1 #include "test_udp.h"
2 
3 #include "lwip/udp.h"
4 #include "lwip/stats.h"
5 #include "lwip/inet_chksum.h"
6 
7 #if !LWIP_STATS || !UDP_STATS || !MEMP_STATS
8 #error "This tests needs UDP- and MEMP-statistics enabled"
9 #endif
10 
11 struct test_udp_rxdata {
12   u32_t rx_cnt;
13   u32_t rx_bytes;
14   struct udp_pcb *pcb;
15 };
16 
17 static struct netif test_netif1, test_netif2;
18 static ip4_addr_t test_gw1, test_ipaddr1, test_netmask1;
19 static ip4_addr_t test_gw2, test_ipaddr2, test_netmask2;
20 static int output_ctr, linkoutput_ctr;
21 
22 /* Helper functions */
23 static void
udp_remove_all(void)24 udp_remove_all(void)
25 {
26   struct udp_pcb *pcb = udp_pcbs;
27   struct udp_pcb *pcb2;
28 
29   while(pcb != NULL) {
30     pcb2 = pcb;
31     pcb = pcb->next;
32     udp_remove(pcb2);
33   }
34   fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 0);
35 }
36 
37 static err_t
default_netif_output(struct netif * netif,struct pbuf * p,const ip4_addr_t * ipaddr)38 default_netif_output(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr)
39 {
40   fail_unless((netif == &test_netif1) || (netif == &test_netif2));
41   fail_unless(p != NULL);
42   fail_unless(ipaddr != NULL);
43   output_ctr++;
44   return ERR_OK;
45 }
46 
47 static err_t
default_netif_linkoutput(struct netif * netif,struct pbuf * p)48 default_netif_linkoutput(struct netif *netif, struct pbuf *p)
49 {
50   fail_unless((netif == &test_netif1) || (netif == &test_netif2));
51   fail_unless(p != NULL);
52   linkoutput_ctr++;
53   return ERR_OK;
54 }
55 
56 static err_t
default_netif_init(struct netif * netif)57 default_netif_init(struct netif *netif)
58 {
59   fail_unless(netif != NULL);
60   netif->output = default_netif_output;
61   netif->linkoutput = default_netif_linkoutput;
62   netif->mtu = 1500;
63   netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
64   netif->hwaddr_len = 6;
65   return ERR_OK;
66 }
67 
68 static void
default_netif_add(void)69 default_netif_add(void)
70 {
71   struct netif *n;
72 
73 #if LWIP_HAVE_LOOPIF
74   fail_unless(netif_list != NULL); /* the loopif */
75   fail_unless(netif_list->next == NULL);
76 #else
77   fail_unless(netif_list == NULL);
78 #endif
79   fail_unless(netif_default == NULL);
80 
81   IP4_ADDR(&test_ipaddr1, 192,168,0,1);
82   IP4_ADDR(&test_netmask1, 255,255,255,0);
83   IP4_ADDR(&test_gw1, 192,168,0,254);
84   n = netif_add(&test_netif1, &test_ipaddr1, &test_netmask1,
85                 &test_gw1, NULL, default_netif_init, NULL);
86   fail_unless(n == &test_netif1);
87 
88   IP4_ADDR(&test_ipaddr2, 192,168,1,1);
89   IP4_ADDR(&test_netmask2, 255,255,255,0);
90   IP4_ADDR(&test_gw2, 192,168,1,254);
91   n = netif_add(&test_netif2, &test_ipaddr2, &test_netmask2,
92                 &test_gw2, NULL, default_netif_init, NULL);
93   fail_unless(n == &test_netif2);
94 
95   netif_set_default(&test_netif1);
96   netif_set_up(&test_netif1);
97   netif_set_up(&test_netif2);
98 }
99 
100 static void
default_netif_remove(void)101 default_netif_remove(void)
102 {
103   fail_unless(netif_default == &test_netif1);
104   netif_remove(&test_netif1);
105   netif_remove(&test_netif2);
106   fail_unless(netif_default == NULL);
107 #if LWIP_HAVE_LOOPIF
108   fail_unless(netif_list != NULL); /* the loopif */
109   fail_unless(netif_list->next == NULL);
110 #else
111   fail_unless(netif_list == NULL);
112 #endif
113 }
114 /* Setups/teardown functions */
115 
116 static void
udp_setup(void)117 udp_setup(void)
118 {
119   udp_remove_all();
120   default_netif_add();
121   lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
122 }
123 
124 static void
udp_teardown(void)125 udp_teardown(void)
126 {
127   udp_remove_all();
128   default_netif_remove();
129   lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
130 }
131 
132 
133 /* Test functions */
134 
START_TEST(test_udp_new_remove)135 START_TEST(test_udp_new_remove)
136 {
137   struct udp_pcb* pcb;
138   LWIP_UNUSED_ARG(_i);
139 
140   fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 0);
141 
142   pcb = udp_new();
143   fail_unless(pcb != NULL);
144   if (pcb != NULL) {
145     fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 1);
146     udp_remove(pcb);
147     fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 0);
148   }
149 }
150 END_TEST
151 
test_recv(void * arg,struct udp_pcb * pcb,struct pbuf * p,const ip_addr_t * addr,u16_t port)152 static void test_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p,
153     const ip_addr_t *addr, u16_t port)
154 {
155   struct test_udp_rxdata *ctr = (struct test_udp_rxdata *)arg;
156 
157   LWIP_UNUSED_ARG(addr);
158   LWIP_UNUSED_ARG(port);
159 
160   fail_unless(arg != NULL);
161   fail_unless(ctr->pcb == pcb);
162 
163   ctr->rx_cnt++;
164   ctr->rx_bytes += p->tot_len;
165 
166   if (p != NULL) {
167     pbuf_free(p);
168   }
169 }
170 
171 static struct pbuf *
test_udp_create_test_packet(u16_t length,u16_t port,u32_t dst_addr)172 test_udp_create_test_packet(u16_t length, u16_t port, u32_t dst_addr)
173 {
174   err_t err;
175   u8_t ret;
176   struct udp_hdr *uh;
177   struct ip_hdr *ih;
178   struct pbuf *p;
179   const u8_t test_data[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
180 
181   p = pbuf_alloc(PBUF_TRANSPORT, length, PBUF_POOL);
182   fail_unless(p != NULL);
183   if (p == NULL) {
184     return NULL;
185   }
186   fail_unless(p->next == NULL);
187   err = pbuf_take(p, test_data, length);
188   fail_unless(err == ERR_OK);
189 
190   /* add UDP header */
191   ret = pbuf_add_header(p, sizeof(struct udp_hdr));
192   fail_unless(!ret);
193   uh = (struct udp_hdr *)p->payload;
194   uh->chksum = 0;
195   uh->dest = uh->src = lwip_htons(port);
196   uh->len = lwip_htons(p->tot_len);
197   /* add IPv4 header */
198   ret = pbuf_add_header(p, sizeof(struct ip_hdr));
199   fail_unless(!ret);
200   ih = (struct ip_hdr *)p->payload;
201   memset(ih, 0, sizeof(*ih));
202   ih->dest.addr = dst_addr;
203   ih->_len = lwip_htons(p->tot_len);
204   ih->_ttl = 32;
205   ih->_proto = IP_PROTO_UDP;
206   IPH_VHL_SET(ih, 4, sizeof(struct ip_hdr) / 4);
207   IPH_CHKSUM_SET(ih, inet_chksum(ih, sizeof(struct ip_hdr)));
208   return p;
209 }
210 
211 /* bind 2 pcbs to specific netif IP and test which one gets broadcasts */
START_TEST(test_udp_broadcast_rx_with_2_netifs)212 START_TEST(test_udp_broadcast_rx_with_2_netifs)
213 {
214   err_t err;
215   struct udp_pcb *pcb1, *pcb2;
216   const u16_t port = 12345;
217   struct test_udp_rxdata ctr1, ctr2;
218   struct pbuf *p;
219 #if SO_REUSE
220   struct udp_pcb *pcb_any;
221   struct test_udp_rxdata ctr_any;
222 #endif
223   LWIP_UNUSED_ARG(_i);
224 
225   pcb1 = udp_new();
226   fail_unless(pcb1 != NULL);
227   pcb2 = udp_new();
228   fail_unless(pcb2 != NULL);
229 
230 #if SO_REUSE
231   pcb_any = udp_new();
232   fail_unless(pcb_any != NULL);
233 
234   ip_set_option(pcb1, SOF_REUSEADDR);
235   ip_set_option(pcb2, SOF_REUSEADDR);
236   ip_set_option(pcb_any, SOF_REUSEADDR);
237 
238   err = udp_bind(pcb_any, NULL, port);
239   fail_unless(err == ERR_OK);
240   memset(&ctr_any, 0, sizeof(ctr_any));
241   ctr_any.pcb = pcb_any;
242   udp_recv(pcb_any, test_recv, &ctr_any);
243 #endif
244 
245   err = udp_bind(pcb1, &test_netif1.ip_addr, port);
246   fail_unless(err == ERR_OK);
247   err = udp_bind(pcb2, &test_netif2.ip_addr, port);
248   fail_unless(err == ERR_OK);
249 
250   memset(&ctr1, 0, sizeof(ctr1));
251   ctr1.pcb = pcb1;
252   memset(&ctr2, 0, sizeof(ctr2));
253   ctr2.pcb = pcb2;
254 
255   udp_recv(pcb1, test_recv, &ctr1);
256   udp_recv(pcb2, test_recv, &ctr2);
257 
258   /* unicast to netif1 */
259   p = test_udp_create_test_packet(16, port, test_ipaddr1.addr);
260   EXPECT_RET(p != NULL);
261   err = ip4_input(p, &test_netif1);
262   fail_unless(err == ERR_OK);
263   fail_unless(ctr1.rx_cnt == 1);
264   fail_unless(ctr1.rx_bytes == 16);
265   fail_unless(ctr2.rx_cnt == 0);
266 #if SO_REUSE
267   fail_unless(ctr_any.rx_cnt == 0);
268 #endif
269   ctr1.rx_cnt = ctr1.rx_bytes = 0;
270 
271   /* unicast to netif2 */
272   p = test_udp_create_test_packet(16, port, test_ipaddr2.addr);
273   EXPECT_RET(p != NULL);
274   err = ip4_input(p, &test_netif2);
275   fail_unless(err == ERR_OK);
276   fail_unless(ctr2.rx_cnt == 1);
277   fail_unless(ctr2.rx_bytes == 16);
278   fail_unless(ctr1.rx_cnt == 0);
279 #if SO_REUSE
280   fail_unless(ctr_any.rx_cnt == 0);
281 #endif
282   ctr2.rx_cnt = ctr2.rx_bytes = 0;
283 
284   /* broadcast to netif1-broadcast, input to netif2 */
285   p = test_udp_create_test_packet(16, port, test_ipaddr1.addr | ~test_netmask1.addr);
286   EXPECT_RET(p != NULL);
287   err = ip4_input(p, &test_netif2);
288   fail_unless(err == ERR_OK);
289   fail_unless(ctr1.rx_cnt == 1);
290   fail_unless(ctr1.rx_bytes == 16);
291   fail_unless(ctr2.rx_cnt == 0);
292 #if SO_REUSE
293   fail_unless(ctr_any.rx_cnt == 0);
294 #endif
295   ctr1.rx_cnt = ctr1.rx_bytes = 0;
296 
297   /* broadcast to netif2-broadcast, input to netif1 */
298   p = test_udp_create_test_packet(16, port, test_ipaddr2.addr | ~test_netmask2.addr);
299   EXPECT_RET(p != NULL);
300   err = ip4_input(p, &test_netif1);
301   fail_unless(err == ERR_OK);
302   fail_unless(ctr2.rx_cnt == 1);
303   fail_unless(ctr2.rx_bytes == 16);
304   fail_unless(ctr1.rx_cnt == 0);
305 #if SO_REUSE
306   fail_unless(ctr_any.rx_cnt == 0);
307 #endif
308   ctr2.rx_cnt = ctr2.rx_bytes = 0;
309 
310   /* broadcast to global-broadcast, input to netif1 */
311   p = test_udp_create_test_packet(16, port, 0xffffffff);
312   EXPECT_RET(p != NULL);
313   err = ip4_input(p, &test_netif1);
314   fail_unless(err == ERR_OK);
315   fail_unless(ctr1.rx_cnt == 1);
316   fail_unless(ctr1.rx_bytes == 16);
317   fail_unless(ctr2.rx_cnt == 0);
318 #if SO_REUSE
319   fail_unless(ctr_any.rx_cnt == 0);
320 #endif
321   ctr1.rx_cnt = ctr1.rx_bytes = 0;
322 
323   /* broadcast to global-broadcast, input to netif2 */
324   p = test_udp_create_test_packet(16, port, 0xffffffff);
325   EXPECT_RET(p != NULL);
326   err = ip4_input(p, &test_netif2);
327   fail_unless(err == ERR_OK);
328   fail_unless(ctr2.rx_cnt == 1);
329   fail_unless(ctr2.rx_bytes == 16);
330   fail_unless(ctr1.rx_cnt == 0);
331 #if SO_REUSE
332   fail_unless(ctr_any.rx_cnt == 0);
333 #endif
334   ctr2.rx_cnt = ctr2.rx_bytes = 0;
335 }
336 END_TEST
337 
START_TEST(test_udp_bind)338 START_TEST(test_udp_bind)
339 {
340   struct udp_pcb* pcb1;
341   struct udp_pcb* pcb2;
342   ip_addr_t ip1;
343   ip_addr_t ip2;
344   err_t err1;
345   err_t err2;
346   LWIP_UNUSED_ARG(_i);
347 
348   /* bind on same port using different IP address types */
349   ip_addr_set_any_val(0, ip1);
350   ip_addr_set_any_val(1, ip2);
351 
352   pcb1 = udp_new_ip_type(IPADDR_TYPE_V4);
353   pcb2 = udp_new_ip_type(IPADDR_TYPE_V6);
354 
355   err1 = udp_bind(pcb1, &ip1, 2105);
356   err2 = udp_bind(pcb2, &ip2, 2105);
357 
358   fail_unless(err1 == ERR_OK);
359   fail_unless(err2 == ERR_OK);
360 
361   udp_remove(pcb1);
362   udp_remove(pcb2);
363 
364   /* bind on same port using SAME IPv4 address type */
365   ip_addr_set_any_val(0, ip1);
366   ip_addr_set_any_val(0, ip2);
367 
368   pcb1 = udp_new_ip_type(IPADDR_TYPE_V4);
369   pcb2 = udp_new_ip_type(IPADDR_TYPE_V4);
370 
371   err1 = udp_bind(pcb1, &ip1, 2105);
372   err2 = udp_bind(pcb2, &ip2, 2105);
373 
374   fail_unless(err1 == ERR_OK);
375   fail_unless(err2 == ERR_USE);
376 
377   udp_remove(pcb1);
378   udp_remove(pcb2);
379 
380   /* bind on same port using SAME IPv6 address type */
381   ip_addr_set_any_val(1, ip1);
382   ip_addr_set_any_val(1, ip2);
383 
384   pcb1 = udp_new_ip_type(IPADDR_TYPE_V6);
385   pcb2 = udp_new_ip_type(IPADDR_TYPE_V6);
386 
387   err1 = udp_bind(pcb1, &ip1, 2105);
388   err2 = udp_bind(pcb2, &ip2, 2105);
389 
390   fail_unless(err1 == ERR_OK);
391   fail_unless(err2 == ERR_USE);
392 
393   udp_remove(pcb1);
394   udp_remove(pcb2);
395 
396   /* Bind with different IP address type */
397   ip_addr_set_any_val(0, ip1);
398   ip_addr_set_any_val(1, ip2);
399 
400   pcb1 = udp_new_ip_type(IPADDR_TYPE_V6);
401   pcb2 = udp_new_ip_type(IPADDR_TYPE_V4);
402 
403   err1 = udp_bind(pcb1, &ip1, 2105);
404   err2 = udp_bind(pcb2, &ip2, 2105);
405 
406   fail_unless(err1 == ERR_OK);
407   fail_unless(err2 == ERR_OK);
408 
409   udp_remove(pcb1);
410   udp_remove(pcb2);
411 
412   /* Bind with different IP numbers */
413   IP_ADDR4(&ip1, 1, 2, 3, 4);
414   IP_ADDR4(&ip2, 4, 3, 2, 1);
415 
416   pcb1 = udp_new_ip_type(IPADDR_TYPE_V6);
417   pcb2 = udp_new_ip_type(IPADDR_TYPE_V4);
418 
419   err1 = udp_bind(pcb1, &ip1, 2105);
420   err2 = udp_bind(pcb2, &ip2, 2105);
421 
422   fail_unless(err1 == ERR_OK);
423   fail_unless(err2 == ERR_OK);
424 
425   udp_remove(pcb1);
426   udp_remove(pcb2);
427 
428   /* Bind with same IP numbers */
429   IP_ADDR4(&ip1, 1, 2, 3, 4);
430   IP_ADDR4(&ip2, 1, 2, 3, 4);
431 
432   pcb1 = udp_new_ip_type(IPADDR_TYPE_V6);
433   pcb2 = udp_new_ip_type(IPADDR_TYPE_V4);
434 
435   err1 = udp_bind(pcb1, &ip1, 2105);
436   err2 = udp_bind(pcb2, &ip2, 2105);
437 
438   fail_unless(err1 == ERR_OK);
439   fail_unless(err2 == ERR_USE);
440 
441   udp_remove(pcb1);
442   udp_remove(pcb2);
443 
444   /* bind on same port using ANY + IPv4 */
445   ip1 = *IP_ANY_TYPE;
446   IP_ADDR4(&ip2, 1, 2, 3, 4);
447 
448   pcb1 = udp_new_ip_type(IPADDR_TYPE_ANY);
449   pcb2 = udp_new_ip_type(IPADDR_TYPE_V4);
450 
451   err1 = udp_bind(pcb1, &ip1, 2105);
452   err2 = udp_bind(pcb2, &ip2, 2105);
453 
454   fail_unless(err1 == ERR_OK);
455   fail_unless(err2 == ERR_USE);
456 
457   udp_remove(pcb1);
458   udp_remove(pcb2);
459 }
460 END_TEST
461 
462 /** Create the suite including all tests for this module */
463 Suite *
udp_suite(void)464 udp_suite(void)
465 {
466   testfunc tests[] = {
467     TESTFUNC(test_udp_new_remove),
468     TESTFUNC(test_udp_broadcast_rx_with_2_netifs),
469     TESTFUNC(test_udp_bind)
470   };
471   return create_suite("UDP", tests, sizeof(tests)/sizeof(testfunc), udp_setup, udp_teardown);
472 }
473