• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&ethhdr->dest, NETIF_MAC, ETH_HWADDR_LEN);
70     SMEMCPY(&ethhdr->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(&ethhdr->dest, NETIF_MAC, ETH_HWADDR_LEN);
405     SMEMCPY(&ethhdr->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