1 /* Copyright (c) 2021-2021 Huawei Device Co., Ltd. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without modification,
4 * are permitted provided that the following conditions are met:
5 *
6 * 1. Redistributions of source code must retain the above copyright notice, this list of
7 * conditions and the following disclaimer.
8 *
9 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
10 * of conditions and the following disclaimer in the documentation and/or other materials
11 * provided with the distribution.
12 *
13 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
14 * to endorse or promote products derived from this software without specific prior written
15 * permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "lwip/sockets.h"
31 #include "lwip/priv/tcpip_priv.h"
32 #include "lwip/priv/sockets_priv.h"
33 #include "lwip/prot/dhcp.h"
34 #include "lwip/dhcp.h"
35 #include "lwip/if_api.h"
36
37 #if LWIP_ENABLE_DISTRIBUTED_NET && LWIP_USE_GET_HOST_BY_NAME_EXTERNAL
38
39 #include "lwip/distributed_net/udp_transmit.h"
40
get_msg_data_len(const struct msghdr * hdr)41 static s32_t get_msg_data_len(const struct msghdr *hdr)
42 {
43 if (hdr->msg_iovlen > MAX_IOV_NUM) {
44 return -1;
45 }
46
47 s32_t data_len = 0;
48 for (int i = 0; i < hdr->msg_iovlen; ++i) {
49 if (hdr->msg_iov[i].iov_len > MAX_UDP_PAYLOAD_LEN) {
50 set_errno(EMSGSIZE);
51 return -1;
52 }
53 data_len += (s32_t)hdr->msg_iov[i].iov_len;
54 if (data_len > MAX_UDP_PAYLOAD_LEN) {
55 set_errno(EMSGSIZE);
56 return -1;
57 }
58 }
59
60 return data_len;
61 }
62
udp_transmit_sendto(int sock,const void * buf,size_t buf_len,const struct sockaddr_in * dest_addr)63 ssize_t udp_transmit_sendto(int sock, const void *buf, size_t buf_len, const struct sockaddr_in *dest_addr)
64 {
65 if (buf_len > MAX_UDP_PAYLOAD_LEN) {
66 set_errno(EMSGSIZE);
67 return -1;
68 }
69
70 udp_data data = {0};
71 (void)memset_s(&data, sizeof(data), 0, sizeof(data));
72 (void)strcpy_s(data.dest_addr, sizeof(data.dest_addr), inet_ntoa(dest_addr->sin_addr));
73 data.dest_port = ntohs(dest_addr->sin_port);
74
75 struct iovec iov[2] = {0};
76 (void)memset_s(iov, sizeof(iov), 0, sizeof(iov));
77 iov[0].iov_base = (void *)&data;
78 iov[0].iov_len = sizeof(data);
79 iov[1].iov_base = (void *)buf;
80 iov[1].iov_len = buf_len;
81
82 struct sockaddr_in transmit_addr = {0};
83 (void)memset_s(&transmit_addr, sizeof(transmit_addr), 0, sizeof(transmit_addr));
84 INIT_SOCK_ADDR(&transmit_addr, LOCAL_SERVER_IP, get_local_udp_server_port());
85
86 struct msghdr send_hdr = {0};
87 (void)memset_s(&send_hdr, sizeof(send_hdr), 0, sizeof(send_hdr));
88 SET_MSG_ADDR(&send_hdr, &transmit_addr, sizeof(transmit_addr));
89 send_hdr.msg_iov = iov;
90 send_hdr.msg_iovlen = 2;
91
92 #if LWIP_DISTRIBUTED_NET_ENABLE_SENDMSG
93 return lwip_sendmsg_internal(sock, &send_hdr, 0);
94 #else
95 return lwip_sendmsg(sock, &send_hdr, 0);
96 #endif
97 }
98
udp_transmit_sendmsg(int sock,const struct msghdr * hdr)99 ssize_t udp_transmit_sendmsg(int sock, const struct msghdr *hdr)
100 {
101 if (get_msg_data_len(hdr) < 0) {
102 return -1;
103 }
104
105 struct sockaddr_in temp_addr_in = {0};
106 (void)memset_s(&temp_addr_in, sizeof(temp_addr_in), 0, sizeof(temp_addr_in));
107 (void)memcpy_s(&temp_addr_in, sizeof(temp_addr_in), hdr->msg_name, MIN(sizeof(temp_addr_in), hdr->msg_namelen));
108
109 udp_data data = {0};
110 (void)memset_s(&data, sizeof(data), 0, sizeof(data));
111 (void)strcpy_s(data.dest_addr, sizeof(data.dest_addr), inet_ntoa(temp_addr_in.sin_addr));
112 data.dest_port = ntohs(temp_addr_in.sin_port);
113
114 u32_t size = sizeof(struct iovec) * (hdr->msg_iovlen + 1);
115 struct iovec *iov = mem_malloc(size);
116 if (iov == NULL) {
117 set_errno(ENOMEM);
118 return -1;
119 }
120 (void)memset_s(iov, size, 0, size);
121 iov[0].iov_base = (void *)&data;
122 iov[0].iov_len = sizeof(data);
123 for (int i = 0; i < hdr->msg_iovlen; ++i) {
124 iov[i + 1].iov_base = hdr->msg_iov[i].iov_base;
125 iov[i + 1].iov_len = hdr->msg_iov[i].iov_len;
126 }
127
128 struct sockaddr_in transmit_addr = {0};
129 (void)memset_s(&transmit_addr, sizeof(transmit_addr), 0, sizeof(transmit_addr));
130 INIT_SOCK_ADDR(&transmit_addr, LOCAL_SERVER_IP, get_local_udp_server_port());
131
132 struct msghdr send_hdr = {0};
133 (void)memset_s(&send_hdr, sizeof(send_hdr), 0, sizeof(send_hdr));
134 SET_MSG_ADDR(&send_hdr, &transmit_addr, sizeof(transmit_addr));
135 send_hdr.msg_iov = iov;
136 send_hdr.msg_iovlen = hdr->msg_iovlen + 1;
137
138 #if LWIP_DISTRIBUTED_NET_ENABLE_SENDMSG
139 ssize_t ret = lwip_sendmsg_internal(sock, &send_hdr, 0);
140 #else
141 ssize_t ret = lwip_sendmsg(sock, &send_hdr, 0);
142 #endif
143 mem_free(iov);
144 return ret;
145 }
146
147 #endif /* LWIP_ENABLE_DISTRIBUTED_NET && LWIP_USE_GET_HOST_BY_NAME_EXTERNAL */
148