xref: /nrf52832-nimble/rt-thread/components/net/lwip-2.1.0/test/unit/udp/test_udp.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero #include "test_udp.h"
2*10465441SEvalZero 
3*10465441SEvalZero #include "lwip/udp.h"
4*10465441SEvalZero #include "lwip/stats.h"
5*10465441SEvalZero #include "lwip/inet_chksum.h"
6*10465441SEvalZero 
7*10465441SEvalZero #if !LWIP_STATS || !UDP_STATS || !MEMP_STATS
8*10465441SEvalZero #error "This tests needs UDP- and MEMP-statistics enabled"
9*10465441SEvalZero #endif
10*10465441SEvalZero 
11*10465441SEvalZero struct test_udp_rxdata {
12*10465441SEvalZero   u32_t rx_cnt;
13*10465441SEvalZero   u32_t rx_bytes;
14*10465441SEvalZero   struct udp_pcb *pcb;
15*10465441SEvalZero };
16*10465441SEvalZero 
17*10465441SEvalZero static struct netif test_netif1, test_netif2;
18*10465441SEvalZero static ip4_addr_t test_gw1, test_ipaddr1, test_netmask1;
19*10465441SEvalZero static ip4_addr_t test_gw2, test_ipaddr2, test_netmask2;
20*10465441SEvalZero static int output_ctr, linkoutput_ctr;
21*10465441SEvalZero 
22*10465441SEvalZero /* Helper functions */
23*10465441SEvalZero static void
udp_remove_all(void)24*10465441SEvalZero udp_remove_all(void)
25*10465441SEvalZero {
26*10465441SEvalZero   struct udp_pcb *pcb = udp_pcbs;
27*10465441SEvalZero   struct udp_pcb *pcb2;
28*10465441SEvalZero 
29*10465441SEvalZero   while(pcb != NULL) {
30*10465441SEvalZero     pcb2 = pcb;
31*10465441SEvalZero     pcb = pcb->next;
32*10465441SEvalZero     udp_remove(pcb2);
33*10465441SEvalZero   }
34*10465441SEvalZero   fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 0);
35*10465441SEvalZero }
36*10465441SEvalZero 
37*10465441SEvalZero static err_t
default_netif_output(struct netif * netif,struct pbuf * p,const ip4_addr_t * ipaddr)38*10465441SEvalZero default_netif_output(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr)
39*10465441SEvalZero {
40*10465441SEvalZero   fail_unless((netif == &test_netif1) || (netif == &test_netif2));
41*10465441SEvalZero   fail_unless(p != NULL);
42*10465441SEvalZero   fail_unless(ipaddr != NULL);
43*10465441SEvalZero   output_ctr++;
44*10465441SEvalZero   return ERR_OK;
45*10465441SEvalZero }
46*10465441SEvalZero 
47*10465441SEvalZero static err_t
default_netif_linkoutput(struct netif * netif,struct pbuf * p)48*10465441SEvalZero default_netif_linkoutput(struct netif *netif, struct pbuf *p)
49*10465441SEvalZero {
50*10465441SEvalZero   fail_unless((netif == &test_netif1) || (netif == &test_netif2));
51*10465441SEvalZero   fail_unless(p != NULL);
52*10465441SEvalZero   linkoutput_ctr++;
53*10465441SEvalZero   return ERR_OK;
54*10465441SEvalZero }
55*10465441SEvalZero 
56*10465441SEvalZero static err_t
default_netif_init(struct netif * netif)57*10465441SEvalZero default_netif_init(struct netif *netif)
58*10465441SEvalZero {
59*10465441SEvalZero   fail_unless(netif != NULL);
60*10465441SEvalZero   netif->output = default_netif_output;
61*10465441SEvalZero   netif->linkoutput = default_netif_linkoutput;
62*10465441SEvalZero   netif->mtu = 1500;
63*10465441SEvalZero   netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
64*10465441SEvalZero   netif->hwaddr_len = 6;
65*10465441SEvalZero   return ERR_OK;
66*10465441SEvalZero }
67*10465441SEvalZero 
68*10465441SEvalZero static void
default_netif_add(void)69*10465441SEvalZero default_netif_add(void)
70*10465441SEvalZero {
71*10465441SEvalZero   struct netif *n;
72*10465441SEvalZero 
73*10465441SEvalZero #if LWIP_HAVE_LOOPIF
74*10465441SEvalZero   fail_unless(netif_list != NULL); /* the loopif */
75*10465441SEvalZero   fail_unless(netif_list->next == NULL);
76*10465441SEvalZero #else
77*10465441SEvalZero   fail_unless(netif_list == NULL);
78*10465441SEvalZero #endif
79*10465441SEvalZero   fail_unless(netif_default == NULL);
80*10465441SEvalZero 
81*10465441SEvalZero   IP4_ADDR(&test_ipaddr1, 192,168,0,1);
82*10465441SEvalZero   IP4_ADDR(&test_netmask1, 255,255,255,0);
83*10465441SEvalZero   IP4_ADDR(&test_gw1, 192,168,0,254);
84*10465441SEvalZero   n = netif_add(&test_netif1, &test_ipaddr1, &test_netmask1,
85*10465441SEvalZero                 &test_gw1, NULL, default_netif_init, NULL);
86*10465441SEvalZero   fail_unless(n == &test_netif1);
87*10465441SEvalZero 
88*10465441SEvalZero   IP4_ADDR(&test_ipaddr2, 192,168,1,1);
89*10465441SEvalZero   IP4_ADDR(&test_netmask2, 255,255,255,0);
90*10465441SEvalZero   IP4_ADDR(&test_gw2, 192,168,1,254);
91*10465441SEvalZero   n = netif_add(&test_netif2, &test_ipaddr2, &test_netmask2,
92*10465441SEvalZero                 &test_gw2, NULL, default_netif_init, NULL);
93*10465441SEvalZero   fail_unless(n == &test_netif2);
94*10465441SEvalZero 
95*10465441SEvalZero   netif_set_default(&test_netif1);
96*10465441SEvalZero   netif_set_up(&test_netif1);
97*10465441SEvalZero   netif_set_up(&test_netif2);
98*10465441SEvalZero }
99*10465441SEvalZero 
100*10465441SEvalZero static void
default_netif_remove(void)101*10465441SEvalZero default_netif_remove(void)
102*10465441SEvalZero {
103*10465441SEvalZero   fail_unless(netif_default == &test_netif1);
104*10465441SEvalZero   netif_remove(&test_netif1);
105*10465441SEvalZero   netif_remove(&test_netif2);
106*10465441SEvalZero   fail_unless(netif_default == NULL);
107*10465441SEvalZero #if LWIP_HAVE_LOOPIF
108*10465441SEvalZero   fail_unless(netif_list != NULL); /* the loopif */
109*10465441SEvalZero   fail_unless(netif_list->next == NULL);
110*10465441SEvalZero #else
111*10465441SEvalZero   fail_unless(netif_list == NULL);
112*10465441SEvalZero #endif
113*10465441SEvalZero }
114*10465441SEvalZero /* Setups/teardown functions */
115*10465441SEvalZero 
116*10465441SEvalZero static void
udp_setup(void)117*10465441SEvalZero udp_setup(void)
118*10465441SEvalZero {
119*10465441SEvalZero   udp_remove_all();
120*10465441SEvalZero   default_netif_add();
121*10465441SEvalZero   lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
122*10465441SEvalZero }
123*10465441SEvalZero 
124*10465441SEvalZero static void
udp_teardown(void)125*10465441SEvalZero udp_teardown(void)
126*10465441SEvalZero {
127*10465441SEvalZero   udp_remove_all();
128*10465441SEvalZero   default_netif_remove();
129*10465441SEvalZero   lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
130*10465441SEvalZero }
131*10465441SEvalZero 
132*10465441SEvalZero 
133*10465441SEvalZero /* Test functions */
134*10465441SEvalZero 
START_TEST(test_udp_new_remove)135*10465441SEvalZero START_TEST(test_udp_new_remove)
136*10465441SEvalZero {
137*10465441SEvalZero   struct udp_pcb* pcb;
138*10465441SEvalZero   LWIP_UNUSED_ARG(_i);
139*10465441SEvalZero 
140*10465441SEvalZero   fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 0);
141*10465441SEvalZero 
142*10465441SEvalZero   pcb = udp_new();
143*10465441SEvalZero   fail_unless(pcb != NULL);
144*10465441SEvalZero   if (pcb != NULL) {
145*10465441SEvalZero     fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 1);
146*10465441SEvalZero     udp_remove(pcb);
147*10465441SEvalZero     fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 0);
148*10465441SEvalZero   }
149*10465441SEvalZero }
150*10465441SEvalZero END_TEST
151*10465441SEvalZero 
test_recv(void * arg,struct udp_pcb * pcb,struct pbuf * p,const ip_addr_t * addr,u16_t port)152*10465441SEvalZero static void test_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p,
153*10465441SEvalZero     const ip_addr_t *addr, u16_t port)
154*10465441SEvalZero {
155*10465441SEvalZero   struct test_udp_rxdata *ctr = (struct test_udp_rxdata *)arg;
156*10465441SEvalZero 
157*10465441SEvalZero   LWIP_UNUSED_ARG(addr);
158*10465441SEvalZero   LWIP_UNUSED_ARG(port);
159*10465441SEvalZero 
160*10465441SEvalZero   fail_unless(arg != NULL);
161*10465441SEvalZero   fail_unless(ctr->pcb == pcb);
162*10465441SEvalZero 
163*10465441SEvalZero   ctr->rx_cnt++;
164*10465441SEvalZero   ctr->rx_bytes += p->tot_len;
165*10465441SEvalZero 
166*10465441SEvalZero   if (p != NULL) {
167*10465441SEvalZero     pbuf_free(p);
168*10465441SEvalZero   }
169*10465441SEvalZero }
170*10465441SEvalZero 
171*10465441SEvalZero static struct pbuf *
test_udp_create_test_packet(u16_t length,u16_t port,u32_t dst_addr)172*10465441SEvalZero test_udp_create_test_packet(u16_t length, u16_t port, u32_t dst_addr)
173*10465441SEvalZero {
174*10465441SEvalZero   err_t err;
175*10465441SEvalZero   u8_t ret;
176*10465441SEvalZero   struct udp_hdr *uh;
177*10465441SEvalZero   struct ip_hdr *ih;
178*10465441SEvalZero   struct pbuf *p;
179*10465441SEvalZero   const u8_t test_data[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
180*10465441SEvalZero 
181*10465441SEvalZero   p = pbuf_alloc(PBUF_TRANSPORT, length, PBUF_POOL);
182*10465441SEvalZero   fail_unless(p != NULL);
183*10465441SEvalZero   if (p == NULL) {
184*10465441SEvalZero     return NULL;
185*10465441SEvalZero   }
186*10465441SEvalZero   fail_unless(p->next == NULL);
187*10465441SEvalZero   err = pbuf_take(p, test_data, length);
188*10465441SEvalZero   fail_unless(err == ERR_OK);
189*10465441SEvalZero 
190*10465441SEvalZero   /* add UDP header */
191*10465441SEvalZero   ret = pbuf_add_header(p, sizeof(struct udp_hdr));
192*10465441SEvalZero   fail_unless(!ret);
193*10465441SEvalZero   uh = (struct udp_hdr *)p->payload;
194*10465441SEvalZero   uh->chksum = 0;
195*10465441SEvalZero   uh->dest = uh->src = lwip_htons(port);
196*10465441SEvalZero   uh->len = lwip_htons(p->tot_len);
197*10465441SEvalZero   /* add IPv4 header */
198*10465441SEvalZero   ret = pbuf_add_header(p, sizeof(struct ip_hdr));
199*10465441SEvalZero   fail_unless(!ret);
200*10465441SEvalZero   ih = (struct ip_hdr *)p->payload;
201*10465441SEvalZero   memset(ih, 0, sizeof(*ih));
202*10465441SEvalZero   ih->dest.addr = dst_addr;
203*10465441SEvalZero   ih->_len = lwip_htons(p->tot_len);
204*10465441SEvalZero   ih->_ttl = 32;
205*10465441SEvalZero   ih->_proto = IP_PROTO_UDP;
206*10465441SEvalZero   IPH_VHL_SET(ih, 4, sizeof(struct ip_hdr) / 4);
207*10465441SEvalZero   IPH_CHKSUM_SET(ih, inet_chksum(ih, sizeof(struct ip_hdr)));
208*10465441SEvalZero   return p;
209*10465441SEvalZero }
210*10465441SEvalZero 
211*10465441SEvalZero /* bind 2 pcbs to specific netif IP and test which one gets broadcasts */
START_TEST(test_udp_broadcast_rx_with_2_netifs)212*10465441SEvalZero START_TEST(test_udp_broadcast_rx_with_2_netifs)
213*10465441SEvalZero {
214*10465441SEvalZero   err_t err;
215*10465441SEvalZero   struct udp_pcb *pcb1, *pcb2;
216*10465441SEvalZero   const u16_t port = 12345;
217*10465441SEvalZero   struct test_udp_rxdata ctr1, ctr2;
218*10465441SEvalZero   struct pbuf *p;
219*10465441SEvalZero #if SO_REUSE
220*10465441SEvalZero   struct udp_pcb *pcb_any;
221*10465441SEvalZero   struct test_udp_rxdata ctr_any;
222*10465441SEvalZero #endif
223*10465441SEvalZero   LWIP_UNUSED_ARG(_i);
224*10465441SEvalZero 
225*10465441SEvalZero   pcb1 = udp_new();
226*10465441SEvalZero   fail_unless(pcb1 != NULL);
227*10465441SEvalZero   pcb2 = udp_new();
228*10465441SEvalZero   fail_unless(pcb2 != NULL);
229*10465441SEvalZero 
230*10465441SEvalZero #if SO_REUSE
231*10465441SEvalZero   pcb_any = udp_new();
232*10465441SEvalZero   fail_unless(pcb_any != NULL);
233*10465441SEvalZero 
234*10465441SEvalZero   ip_set_option(pcb1, SOF_REUSEADDR);
235*10465441SEvalZero   ip_set_option(pcb2, SOF_REUSEADDR);
236*10465441SEvalZero   ip_set_option(pcb_any, SOF_REUSEADDR);
237*10465441SEvalZero 
238*10465441SEvalZero   err = udp_bind(pcb_any, NULL, port);
239*10465441SEvalZero   fail_unless(err == ERR_OK);
240*10465441SEvalZero   memset(&ctr_any, 0, sizeof(ctr_any));
241*10465441SEvalZero   ctr_any.pcb = pcb_any;
242*10465441SEvalZero   udp_recv(pcb_any, test_recv, &ctr_any);
243*10465441SEvalZero #endif
244*10465441SEvalZero 
245*10465441SEvalZero   err = udp_bind(pcb1, &test_netif1.ip_addr, port);
246*10465441SEvalZero   fail_unless(err == ERR_OK);
247*10465441SEvalZero   err = udp_bind(pcb2, &test_netif2.ip_addr, port);
248*10465441SEvalZero   fail_unless(err == ERR_OK);
249*10465441SEvalZero 
250*10465441SEvalZero   memset(&ctr1, 0, sizeof(ctr1));
251*10465441SEvalZero   ctr1.pcb = pcb1;
252*10465441SEvalZero   memset(&ctr2, 0, sizeof(ctr2));
253*10465441SEvalZero   ctr2.pcb = pcb2;
254*10465441SEvalZero 
255*10465441SEvalZero   udp_recv(pcb1, test_recv, &ctr1);
256*10465441SEvalZero   udp_recv(pcb2, test_recv, &ctr2);
257*10465441SEvalZero 
258*10465441SEvalZero   /* unicast to netif1 */
259*10465441SEvalZero   p = test_udp_create_test_packet(16, port, test_ipaddr1.addr);
260*10465441SEvalZero   EXPECT_RET(p != NULL);
261*10465441SEvalZero   err = ip4_input(p, &test_netif1);
262*10465441SEvalZero   fail_unless(err == ERR_OK);
263*10465441SEvalZero   fail_unless(ctr1.rx_cnt == 1);
264*10465441SEvalZero   fail_unless(ctr1.rx_bytes == 16);
265*10465441SEvalZero   fail_unless(ctr2.rx_cnt == 0);
266*10465441SEvalZero #if SO_REUSE
267*10465441SEvalZero   fail_unless(ctr_any.rx_cnt == 0);
268*10465441SEvalZero #endif
269*10465441SEvalZero   ctr1.rx_cnt = ctr1.rx_bytes = 0;
270*10465441SEvalZero 
271*10465441SEvalZero   /* unicast to netif2 */
272*10465441SEvalZero   p = test_udp_create_test_packet(16, port, test_ipaddr2.addr);
273*10465441SEvalZero   EXPECT_RET(p != NULL);
274*10465441SEvalZero   err = ip4_input(p, &test_netif2);
275*10465441SEvalZero   fail_unless(err == ERR_OK);
276*10465441SEvalZero   fail_unless(ctr2.rx_cnt == 1);
277*10465441SEvalZero   fail_unless(ctr2.rx_bytes == 16);
278*10465441SEvalZero   fail_unless(ctr1.rx_cnt == 0);
279*10465441SEvalZero #if SO_REUSE
280*10465441SEvalZero   fail_unless(ctr_any.rx_cnt == 0);
281*10465441SEvalZero #endif
282*10465441SEvalZero   ctr2.rx_cnt = ctr2.rx_bytes = 0;
283*10465441SEvalZero 
284*10465441SEvalZero   /* broadcast to netif1-broadcast, input to netif2 */
285*10465441SEvalZero   p = test_udp_create_test_packet(16, port, test_ipaddr1.addr | ~test_netmask1.addr);
286*10465441SEvalZero   EXPECT_RET(p != NULL);
287*10465441SEvalZero   err = ip4_input(p, &test_netif2);
288*10465441SEvalZero   fail_unless(err == ERR_OK);
289*10465441SEvalZero   fail_unless(ctr1.rx_cnt == 1);
290*10465441SEvalZero   fail_unless(ctr1.rx_bytes == 16);
291*10465441SEvalZero   fail_unless(ctr2.rx_cnt == 0);
292*10465441SEvalZero #if SO_REUSE
293*10465441SEvalZero   fail_unless(ctr_any.rx_cnt == 0);
294*10465441SEvalZero #endif
295*10465441SEvalZero   ctr1.rx_cnt = ctr1.rx_bytes = 0;
296*10465441SEvalZero 
297*10465441SEvalZero   /* broadcast to netif2-broadcast, input to netif1 */
298*10465441SEvalZero   p = test_udp_create_test_packet(16, port, test_ipaddr2.addr | ~test_netmask2.addr);
299*10465441SEvalZero   EXPECT_RET(p != NULL);
300*10465441SEvalZero   err = ip4_input(p, &test_netif1);
301*10465441SEvalZero   fail_unless(err == ERR_OK);
302*10465441SEvalZero   fail_unless(ctr2.rx_cnt == 1);
303*10465441SEvalZero   fail_unless(ctr2.rx_bytes == 16);
304*10465441SEvalZero   fail_unless(ctr1.rx_cnt == 0);
305*10465441SEvalZero #if SO_REUSE
306*10465441SEvalZero   fail_unless(ctr_any.rx_cnt == 0);
307*10465441SEvalZero #endif
308*10465441SEvalZero   ctr2.rx_cnt = ctr2.rx_bytes = 0;
309*10465441SEvalZero 
310*10465441SEvalZero   /* broadcast to global-broadcast, input to netif1 */
311*10465441SEvalZero   p = test_udp_create_test_packet(16, port, 0xffffffff);
312*10465441SEvalZero   EXPECT_RET(p != NULL);
313*10465441SEvalZero   err = ip4_input(p, &test_netif1);
314*10465441SEvalZero   fail_unless(err == ERR_OK);
315*10465441SEvalZero   fail_unless(ctr1.rx_cnt == 1);
316*10465441SEvalZero   fail_unless(ctr1.rx_bytes == 16);
317*10465441SEvalZero   fail_unless(ctr2.rx_cnt == 0);
318*10465441SEvalZero #if SO_REUSE
319*10465441SEvalZero   fail_unless(ctr_any.rx_cnt == 0);
320*10465441SEvalZero #endif
321*10465441SEvalZero   ctr1.rx_cnt = ctr1.rx_bytes = 0;
322*10465441SEvalZero 
323*10465441SEvalZero   /* broadcast to global-broadcast, input to netif2 */
324*10465441SEvalZero   p = test_udp_create_test_packet(16, port, 0xffffffff);
325*10465441SEvalZero   EXPECT_RET(p != NULL);
326*10465441SEvalZero   err = ip4_input(p, &test_netif2);
327*10465441SEvalZero   fail_unless(err == ERR_OK);
328*10465441SEvalZero   fail_unless(ctr2.rx_cnt == 1);
329*10465441SEvalZero   fail_unless(ctr2.rx_bytes == 16);
330*10465441SEvalZero   fail_unless(ctr1.rx_cnt == 0);
331*10465441SEvalZero #if SO_REUSE
332*10465441SEvalZero   fail_unless(ctr_any.rx_cnt == 0);
333*10465441SEvalZero #endif
334*10465441SEvalZero   ctr2.rx_cnt = ctr2.rx_bytes = 0;
335*10465441SEvalZero }
336*10465441SEvalZero END_TEST
337*10465441SEvalZero 
338*10465441SEvalZero /** Create the suite including all tests for this module */
339*10465441SEvalZero Suite *
udp_suite(void)340*10465441SEvalZero udp_suite(void)
341*10465441SEvalZero {
342*10465441SEvalZero   testfunc tests[] = {
343*10465441SEvalZero     TESTFUNC(test_udp_new_remove),
344*10465441SEvalZero     TESTFUNC(test_udp_broadcast_rx_with_2_netifs)
345*10465441SEvalZero   };
346*10465441SEvalZero   return create_suite("UDP", tests, sizeof(tests)/sizeof(testfunc), udp_setup, udp_teardown);
347*10465441SEvalZero }
348