1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "lwip_test.h"
33 #include <lwip/netif.h>
34 #include <lwip/netifapi.h>
35 #include <lwip/pbuf.h>
36 #include <lwip/ip4_addr.h>
37 #include <lwip/ip4.h>
38 #include <lwip/ip.h>
39 #include <lwip/def.h>
40 #include <lwip/udp.h>
41 #include <lwip/inet_chksum.h>
42 #include "lwip/prot/iana.h"
43
44 #define MSG "Hi, I am testing BT netif."
45 #define STACK_IP_BT "192.168.167.1"
46 #define PEER_IP_BT "100.100.100.100"
47 #define GATEWAY_IP_BT "192.168.167.239"
48 #define NETIF_MAC "121212"
49 #define PEER_MAC "454545"
50 #define NETIF_NAME_BT "bt1000"
51 #define TEST_CASE 210
52 static char g_buf[BUF_SIZE + 1] = { 0 };
53 struct netif *btProxyNf = NULL;
54
55 static void ReplayArpTask();
56 static void ArpPackageProc(struct netif *netif, struct pbuf *p);
57 extern void driverif_input(struct netif *netif, struct pbuf *p);
58 static void ReplayArpEncodeEthernet(struct netif *netif, struct pbuf *p);
59
ReplayUdpEncodeEthernet(struct netif * netif,struct pbuf * p)60 static void ReplayUdpEncodeEthernet(struct netif *netif, struct pbuf *p)
61 {
62 int ret;
63 ret = pbuf_add_header(p, SIZEOF_ETH_HDR);
64 ICUNIT_ASSERT_EQUAL(ret, 0, 1);
65
66 struct eth_hdr *ethhdr;
67 ethhdr = (struct eth_hdr *)p->payload;
68 ethhdr->type = lwip_htons(ETHTYPE_IP);
69 SMEMCPY(ðhdr->dest, NETIF_MAC, ETH_HWADDR_LEN);
70 SMEMCPY(ðhdr->src, PEER_MAC, ETH_HWADDR_LEN);
71
72 driverif_input(netif, p);
73 }
74
ReplayUdpEncodeIp(struct pbuf * p,ip4_addr_t * src,ip4_addr_t * dest)75 static void ReplayUdpEncodeIp(struct pbuf *p, ip4_addr_t *src, ip4_addr_t *dest)
76 {
77 struct ip_hdr *iphdr;
78 int ret;
79 #if CHECKSUM_GEN_IP_INLINE
80 u32_t chk_sum = 0;
81 #endif /* CHECKSUM_GEN_IP_INLINE */
82
83 // ip header
84 ret = pbuf_add_header(p, IP_HLEN);
85 ICUNIT_ASSERT_EQUAL(ret, 0, 2);
86 iphdr = (struct ip_hdr *)p->payload;
87 IPH_TTL_SET(iphdr, UDP_TTL);
88 IPH_PROTO_SET(iphdr, IP_PROTO_UDP);
89
90 #if CHECKSUM_GEN_IP_INLINE
91 chk_sum += PP_NTOHS(IP_PROTO_UDP | (ttl << 8));
92 #endif /* CHECKSUM_GEN_IP_INLINE */
93
94 /* dest cannot be NULL here */
95 ip4_addr_copy(iphdr->dest, *dest);
96 #if CHECKSUM_GEN_IP_INLINE
97 chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF;
98 chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16;
99 #endif /* CHECKSUM_GEN_IP_INLINE */
100
101 u16_t ip_hlen = IP_HLEN;
102 IPH_VHL_SET(iphdr, 4, ip_hlen / 4);
103 IPH_TOS_SET(iphdr, 0);
104 #if CHECKSUM_GEN_IP_INLINE
105 chk_sum += PP_NTOHS(tos | (iphdr->_v_hl << 8));
106 #endif /* CHECKSUM_GEN_IP_INLINE */
107 IPH_LEN_SET(iphdr, lwip_htons(p->tot_len));
108 #if CHECKSUM_GEN_IP_INLINE
109 chk_sum += iphdr->_len;
110 #endif /* CHECKSUM_GEN_IP_INLINE */
111 IPH_OFFSET_SET(iphdr, 0);
112 IPH_ID_SET(iphdr, lwip_htons(0));
113 #if CHECKSUM_GEN_IP_INLINE
114 chk_sum += iphdr->_id;
115 #endif /* CHECKSUM_GEN_IP_INLINE */
116 ip4_addr_copy(iphdr->src, *src);
117
118 #if CHECKSUM_GEN_IP_INLINE
119 chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF;
120 chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16;
121 chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
122 chk_sum = (chk_sum >> 16) + chk_sum;
123 chk_sum = ~chk_sum;
124 IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
125 iphdr->_chksum = (u16_t)chk_sum; /* network order */
126 }
127 #if LWIP_CHECKSUM_CTRL_PER_NETIF
128 else {
129 IPH_CHKSUM_SET(iphdr, 0);
130 }
131 #endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
132 #else /* CHECKSUM_GEN_IP_INLINE */
133 IPH_CHKSUM_SET(iphdr, 0);
134 #if CHECKSUM_GEN_IP
135 IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
136 IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));
137 }
138 #endif /* CHECKSUM_GEN_IP */
139 #endif /* CHECKSUM_GEN_IP_INLINE */
140
141 ReplayUdpEncodeEthernet(btProxyNf, p);
142 }
143
ReplayUdp(void * ptemp)144 static void ReplayUdp(void *ptemp)
145 {
146 struct udp_hdr *udphdr;
147 ip4_addr_t sipaddr, dipaddr;
148 int size = strlen(MSG);
149 int ret;
150 (void)ptemp;
151
152 LogPrintln("encode udp replay packet");
153 inet_pton(AF_INET, PEER_IP_BT, &sipaddr);
154 inet_pton(AF_INET, STACK_IP_BT, &dipaddr);
155
156 struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
157 u16_t chksum = LWIP_CHKSUM_COPY(p->payload, MSG, size);
158
159 // udp header
160 ret = pbuf_add_header(p, UDP_HLEN);
161 ICUNIT_ASSERT_EQUAL(ret, 0, 1);
162 udphdr = (struct udp_hdr *)p->payload;
163 udphdr->src = lwip_htons(STACK_PORT);
164 udphdr->dest = lwip_htons(STACK_PORT);
165 udphdr->len = lwip_htons(p->tot_len);
166 /* in UDP, 0 checksum means 'no checksum' */
167 u16_t udpchksum = ip_chksum_pseudo_partial(p, IP_PROTO_UDP, p->tot_len, UDP_HLEN, &sipaddr, &dipaddr);
168 u32_t acc = udpchksum + (u16_t)~(chksum);
169 udpchksum = FOLD_U32T(acc);
170 if (udpchksum == 0x0000) {
171 udpchksum = 0xffff;
172 }
173 udphdr->chksum = udpchksum;
174 udphdr->chksum = 0;
175
176 ReplayUdpEncodeIp(p, &sipaddr, &dipaddr);
177 }
178
ReplayUdpTask()179 static void ReplayUdpTask()
180 {
181 int ret;
182 ret = sys_thread_new("replay_udp", ReplayUdp, NULL,
183 STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
184 ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 3);
185 }
186
ParsePackageIpUdp(struct netif * netif,struct pbuf * btBuf)187 static void ParsePackageIpUdp(struct netif *netif, struct pbuf *btBuf)
188 {
189 // get scr_addr and dest_addr from ip head
190 const struct ip_hdr *iphdr;
191 iphdr = (const struct ip_hdr *)btBuf->payload;
192 ip4_addr_p_t ip4_addr_scr = iphdr->src;
193 ip4_addr_p_t ip4_addr_dest = iphdr->dest;
194 char buf[32];
195 int dataLen;
196
197 // get scr_port and dest port from tcp head
198 u16_t scr_port, dest_port;
199 void *data;
200 struct udp_hdr *udphdr;
201 udphdr = (struct udp_hdr *)((u8_t *)iphdr + IPH_HL_BYTES(iphdr));
202 scr_port = udphdr->src;
203 dest_port = udphdr->dest;
204 data = (void *)((u8_t *)udphdr + UDP_HLEN);
205
206 LogPrintln("======Bt netif send package======");
207 LogPrintln("netif full name %s", netif->full_name);
208 (void)inet_ntop(AF_INET, &ip4_addr_scr.addr, buf, sizeof(buf));
209 LogPrintln("package src ip %s", buf);
210 (void)inet_ntop(AF_INET, &ip4_addr_dest.addr, buf, sizeof(buf));
211 LogPrintln("package dest ip %s", buf);
212 LogPrintln("package src port %d", lwip_ntohs(scr_port));
213 LogPrintln("package dest port %d", lwip_ntohs(dest_port));
214 LogPrintln("send data %s", (char *)data);
215 dataLen = lwip_ntohs(udphdr->len) - UDP_HLEN;
216 LogPrintln("send data length %d", dataLen);
217 ICUNIT_ASSERT_EQUAL(dataLen, strlen(MSG), 4);
218 LogPrintln("=================================");
219
220 ReplayUdpTask();
221 }
222
ParsePackageEthernet(struct netif * netif,struct pbuf * p)223 static void ParsePackageEthernet(struct netif *netif, struct pbuf *p)
224 {
225 u16_t next_hdr_offset = SIZEOF_ETH_HDR;
226 // get src mac and dest mac
227 struct eth_hdr *ethhdr;
228 ethhdr = (struct eth_hdr *)p->payload;
229 u16_t type = ethhdr->type;
230
231 switch (type) {
232 #if LWIP_IPV4 && LWIP_ARP
233 /* IP packet? */
234 case PP_HTONS(ETHTYPE_IP): // 0x0008
235 if (!(netif->flags & NETIF_FLAG_ETHARP)) {
236 return;
237 }
238 /* skip Ethernet header (min. size checked above) */
239 if (pbuf_remove_header(p, next_hdr_offset)) {
240 return;
241 } else {
242 /* pass to IP layer */
243 ParsePackageIpUdp(netif, p);
244 }
245 break;
246
247 case PP_HTONS(ETHTYPE_ARP): // 0x0608
248 if (!(netif->flags & NETIF_FLAG_ETHARP)) {
249 return;
250 }
251 /* skip Ethernet header (min. size checked above) */
252 if (pbuf_remove_header(p, next_hdr_offset)) {
253 return;
254 } else {
255 /* pass p to ARP module */
256 LogPrintln("recv arp packet");
257 ArpPackageProc(netif, p);
258 }
259 break;
260 #endif /* LWIP_IPV4 && LWIP_ARP */
261
262 default:
263 LogPrintln("type is other %d", type);
264 break;
265 }
266 }
267
BtProxySend(struct netif * netif,struct pbuf * p)268 static void BtProxySend(struct netif *netif, struct pbuf *p)
269 {
270 if (netif == NULL || p == NULL) {
271 LogPrintln("%s : netif = NUll or p = NULL!", __func__);
272 return;
273 }
274 #if ETH_PAD_SIZE
275 (void)pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
276 #endif
277 ParsePackageEthernet(netif, p);
278 }
279
CreateBtNetIf()280 static struct netif *CreateBtNetIf()
281 {
282 struct netif *btNetif = NULL;
283 btNetif = (struct netif *)malloc(sizeof(struct netif));
284 if (btNetif == NULL) {
285 LogPrintln("%s fail : netif malloc fail!", __func__);
286 LWIP_ASSERT("btNetif malloc fail.", 0);
287 return NULL;
288 }
289 (void)memset_s(btNetif, sizeof(struct netif), 0, sizeof(struct netif));
290 btNetif->drv_send = BtProxySend;
291 btNetif->link_layer_type = BT_PROXY_IF;
292 btNetif->hwaddr_len = ETH_HWADDR_LEN;
293 (void)memcpy_s(&btNetif->hwaddr, sizeof(btNetif->hwaddr), NETIF_MAC, ETH_HWADDR_LEN);
294 (void)memcpy_s(&btNetif->full_name, sizeof(btNetif->full_name), NETIF_NAME_BT, sizeof(NETIF_NAME_BT));
295 ip4_addr_t gw, ipaddr, netmask;
296 IP4_ADDR(&gw, 192, 168, 167, 239);
297 IP4_ADDR(&ipaddr, 192, 168, 167, 1);
298 IP4_ADDR(&netmask, 255, 255, 255, 255);
299 int ret = 0;
300 if ((ret = netifapi_netif_add(btNetif, &ipaddr, &netmask, &gw, btNetif, driverif_init, tcpip_input)) != ERR_OK) {
301 LogPrintln("%s : netifapi_netif_add fail!,ret=%d", __func__, ret);
302 LWIP_ASSERT("btNetif add fail.", 0);
303 return NULL;
304 }
305 LogPrintln("netifapi_netif_add success!");
306 netif_set_link_up(btNetif);
307 netifapi_netif_set_up(btNetif);
308 return btNetif;
309 }
310
UdpTestNetifTask(void * p)311 static void UdpTestNetifTask(void *p)
312 {
313 (void)p;
314 LogPrintln("net_socket_test_011.c enter");
315 g_testCase = TEST_CASE;
316 int sfd;
317 struct sockaddr_in srvAddr = { 0 };
318 struct sockaddr_in clnAddr = { 0 };
319 socklen_t clnAddrLen = sizeof(clnAddr);
320 struct ifreq nif;
321 int ret;
322
323 btProxyNf = CreateBtNetIf();
324
325 /* socket creation */
326 sfd = socket(AF_INET, SOCK_DGRAM, 0);
327 LWIP_ASSERT("socket invalid param.", sfd != -1);
328
329 srvAddr.sin_family = AF_INET;
330 srvAddr.sin_addr.s_addr = inet_addr(STACK_IP_BT);
331 srvAddr.sin_port = htons(STACK_PORT);
332 ret = bind(sfd, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
333 LWIP_ASSERT("socket invalid param.", ret == 0);
334
335 char *inface = NETIF_NAME_BT;
336 (void)strcpy_s(nif.ifr_name, sizeof(nif.ifr_name), inface);
337 if (setsockopt(sfd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&nif, sizeof(nif)) < 0) {
338 LogPrintln("set intaface fail");
339 LWIP_ASSERT("set intaface fail.", 0);
340 }
341
342 /* send */
343 clnAddr.sin_family = AF_INET;
344 clnAddr.sin_addr.s_addr = inet_addr(PEER_IP_BT);
345 clnAddr.sin_port = htons(PEER_PORT);
346 (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
347 (void)strcpy_s(g_buf, sizeof(g_buf), MSG);
348 ret = sendto(sfd, g_buf, strlen(MSG), 0, (struct sockaddr*)&clnAddr,
349 (socklen_t)sizeof(clnAddr));
350 LogPrintln("client send success: %d", sfd);
351 LWIP_ASSERT("socket invalid param.", ret != -1);
352
353 /* recv */
354 (void)memset_s(g_buf, sizeof(g_buf), 0, sizeof(g_buf));
355 ret = recvfrom(sfd, g_buf, sizeof(g_buf), 0, (struct sockaddr*)&clnAddr,
356 &clnAddrLen);
357 LWIP_ASSERT("socket invalid param.", ret == strlen(MSG));
358 LogPrintln("cli recv: %s", g_buf);
359
360 /* close socket */
361 ret = closesocket(sfd);
362 LWIP_ASSERT("socket invalid param.", ret != -1);
363 return;
364 }
365
UdpTestNetif()366 int UdpTestNetif()
367 {
368 int ret = sys_thread_new("udp_test_netif", UdpTestNetifTask, NULL,
369 STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
370 ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
371 return ret;
372 }
373
ArpPackageProc(struct netif * netif,struct pbuf * p)374 static void ArpPackageProc(struct netif *netif, struct pbuf *p)
375 {
376 struct etharp_hdr *hdr;
377 ip4_addr_t sipaddr, dipaddr;
378 hdr = (struct etharp_hdr *)p->payload;
379
380 if (hdr->opcode != PP_HTONS(ARP_REQUEST)) {
381 LogPrintln("opcode %d is not arp request", hdr->opcode);
382 return;
383 }
384
385 inet_pton(AF_INET, GATEWAY_IP_BT, &sipaddr);
386 inet_pton(AF_INET, STACK_IP_BT, &dipaddr);
387 if (memcmp(&hdr->dipaddr, &sipaddr, sizeof(ip4_addr_t)) != EOK) {
388 LogPrintln("hdr->dipaddr %u is invalid", hdr->dipaddr);
389 return;
390 }
391
392 ReplayArpTask();
393 }
394
ReplayArpEncodeEthernet(struct netif * netif,struct pbuf * p)395 static void ReplayArpEncodeEthernet(struct netif *netif, struct pbuf *p)
396 {
397 int ret;
398 ret = pbuf_add_header(p, SIZEOF_ETH_HDR);
399 ICUNIT_ASSERT_EQUAL(ret, 0, 1);
400
401 struct eth_hdr *ethhdr;
402 ethhdr = (struct eth_hdr *)p->payload;
403 ethhdr->type = lwip_htons(ETHTYPE_ARP);
404 SMEMCPY(ðhdr->dest, NETIF_MAC, ETH_HWADDR_LEN);
405 SMEMCPY(ðhdr->src, PEER_MAC, ETH_HWADDR_LEN);
406
407 driverif_input(netif, p);
408 }
409
ReplayArp(void * ptemp)410 static void ReplayArp(void *ptemp)
411 {
412 struct etharp_hdr *hdr;
413 ip4_addr_t sipaddr, dipaddr;
414
415 (void)ptemp;
416 LogPrintln("encode arp replay packet");
417 inet_pton(AF_INET, GATEWAY_IP_BT, &sipaddr);
418 inet_pton(AF_INET, STACK_IP_BT, &dipaddr);
419 struct pbuf *p = pbuf_alloc(PBUF_LINK, SIZEOF_ETHARP_HDR, PBUF_RAM);
420 hdr = (struct etharp_hdr *)p->payload;
421 hdr->opcode = PP_HTONS(ARP_REPLY);
422 /* Write the ARP MAC-Addresses */
423 SMEMCPY(&hdr->shwaddr, PEER_MAC, ETH_HWADDR_LEN);
424 SMEMCPY(&hdr->dhwaddr, NETIF_MAC, ETH_HWADDR_LEN);
425 /* Copy struct ip4_addr_wordaligned to aligned ip4_addr, to support compilers without
426 * structure packing. */
427 IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->sipaddr, &sipaddr);
428 IPADDR_WORDALIGNED_COPY_FROM_IP4_ADDR_T(&hdr->dipaddr, &dipaddr);
429 hdr->hwtype = PP_HTONS(LWIP_IANA_HWTYPE_ETHERNET);
430 hdr->proto = PP_HTONS(ETHTYPE_IP);
431 /* set hwlen and protolen */
432 hdr->hwlen = ETH_HWADDR_LEN;
433 hdr->protolen = sizeof(ip4_addr_t);
434
435 ReplayArpEncodeEthernet(btProxyNf, p);
436 }
437
ReplayArpTask()438 static void ReplayArpTask()
439 {
440 int ret;
441 ret = sys_thread_new("replay_arp", ReplayArp, NULL,
442 STACK_TEST_SIZE, TCPIP_THREAD_PRIO);
443 ICUNIT_ASSERT_NOT_EQUAL(ret, -1, 23);
444 }
445