Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers test_udp.c Source File

test_udp.c

00001 #include "test_udp.h"
00002 
00003 #include "lwip/udp.h"
00004 #include "lwip/stats.h"
00005 #include "lwip/inet_chksum.h"
00006 
00007 #if !LWIP_STATS || !UDP_STATS || !MEMP_STATS
00008 #error "This tests needs UDP- and MEMP-statistics enabled"
00009 #endif
00010 
00011 struct test_udp_rxdata {
00012   u32_t rx_cnt;
00013   u32_t rx_bytes;
00014   struct udp_pcb *pcb;
00015 };
00016 
00017 static struct netif test_netif1, test_netif2;
00018 static ip4_addr_t test_gw1, test_ipaddr1, test_netmask1;
00019 static ip4_addr_t test_gw2, test_ipaddr2, test_netmask2;
00020 static int output_ctr, linkoutput_ctr;
00021 
00022 /* Helper functions */
00023 static void
00024 udp_remove_all(void)
00025 {
00026   struct udp_pcb *pcb = udp_pcbs;
00027   struct udp_pcb *pcb2;
00028 
00029   while(pcb != NULL) {
00030     pcb2 = pcb;
00031     pcb = pcb->next;
00032     udp_remove(pcb2);
00033   }
00034   fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 0);
00035 }
00036 
00037 static err_t
00038 default_netif_output(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr)
00039 {
00040   fail_unless((netif == &test_netif1) || (netif == &test_netif2));
00041   fail_unless(p != NULL);
00042   fail_unless(ipaddr != NULL);
00043   output_ctr++;
00044   return ERR_OK;
00045 }
00046 
00047 static err_t
00048 default_netif_linkoutput(struct netif *netif, struct pbuf *p)
00049 {
00050   fail_unless((netif == &test_netif1) || (netif == &test_netif2));
00051   fail_unless(p != NULL);
00052   linkoutput_ctr++;
00053   return ERR_OK;
00054 }
00055 
00056 static err_t
00057 default_netif_init(struct netif *netif)
00058 {
00059   fail_unless(netif != NULL);
00060   netif->output = default_netif_output;
00061   netif->linkoutput = default_netif_linkoutput;
00062   netif->mtu = 1500;
00063   netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
00064   netif->hwaddr_len = 6;
00065   return ERR_OK;
00066 }
00067 
00068 static void
00069 default_netif_add(void)
00070 {
00071   struct netif *n;
00072 
00073 #if LWIP_HAVE_LOOPIF
00074   fail_unless(netif_list != NULL); /* the loopif */
00075   fail_unless(netif_list->next == NULL);
00076 #else
00077   fail_unless(netif_list == NULL);
00078 #endif
00079   fail_unless(netif_default == NULL);
00080 
00081   IP4_ADDR(&test_ipaddr1, 192,168,0,1);
00082   IP4_ADDR(&test_netmask1, 255,255,255,0);
00083   IP4_ADDR(&test_gw1, 192,168,0,254);
00084   n = netif_add(&test_netif1, &test_ipaddr1, &test_netmask1,
00085                 &test_gw1, NULL, default_netif_init, NULL);
00086   fail_unless(n == &test_netif1);
00087 
00088   IP4_ADDR(&test_ipaddr2, 192,168,1,1);
00089   IP4_ADDR(&test_netmask2, 255,255,255,0);
00090   IP4_ADDR(&test_gw2, 192,168,1,254);
00091   n = netif_add(&test_netif2, &test_ipaddr2, &test_netmask2,
00092                 &test_gw2, NULL, default_netif_init, NULL);
00093   fail_unless(n == &test_netif2);
00094 
00095   netif_set_default(&test_netif1);
00096   netif_set_up(&test_netif1);
00097   netif_set_up(&test_netif2);
00098 }
00099 
00100 static void
00101 default_netif_remove(void)
00102 {
00103   fail_unless(netif_default == &test_netif1);
00104   netif_remove(&test_netif1);
00105   netif_remove(&test_netif2);
00106   fail_unless(netif_default == NULL);
00107 #if LWIP_HAVE_LOOPIF
00108   fail_unless(netif_list != NULL); /* the loopif */
00109   fail_unless(netif_list->next == NULL);
00110 #else
00111   fail_unless(netif_list == NULL);
00112 #endif
00113 }
00114 /* Setups/teardown functions */
00115 
00116 static void
00117 udp_setup(void)
00118 {
00119   udp_remove_all();
00120   default_netif_add();
00121   lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
00122 }
00123 
00124 static void
00125 udp_teardown(void)
00126 {
00127   udp_remove_all();
00128   default_netif_remove();
00129   lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
00130 }
00131 
00132 
00133 /* Test functions */
00134 
00135 START_TEST(test_udp_new_remove)
00136 {
00137   struct udp_pcb* pcb;
00138   LWIP_UNUSED_ARG(_i);
00139 
00140   fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 0);
00141 
00142   pcb = udp_new();
00143   fail_unless(pcb != NULL);
00144   if (pcb != NULL) {
00145     fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 1);
00146     udp_remove(pcb);
00147     fail_unless(MEMP_STATS_GET(used, MEMP_UDP_PCB) == 0);
00148   }
00149 }
00150 END_TEST
00151 
00152 static void test_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p,
00153     const ip_addr_t *addr, u16_t port)
00154 {
00155   struct test_udp_rxdata *ctr = (struct test_udp_rxdata *)arg;
00156 
00157   LWIP_UNUSED_ARG(addr);
00158   LWIP_UNUSED_ARG(port);
00159 
00160   fail_unless(arg != NULL);
00161   fail_unless(ctr->pcb == pcb);
00162 
00163   ctr->rx_cnt++;
00164   ctr->rx_bytes += p->tot_len;
00165 
00166   if (p != NULL) {
00167     pbuf_free(p);
00168   }
00169 }
00170 
00171 static struct pbuf *
00172 test_udp_create_test_packet(u16_t length, u16_t port, u32_t dst_addr)
00173 {
00174   err_t err;
00175   u8_t ret;
00176   struct udp_hdr *uh;
00177   struct ip_hdr *ih;
00178   struct pbuf *p;
00179   const u8_t test_data[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
00180 
00181   p = pbuf_alloc(PBUF_TRANSPORT, length, PBUF_POOL);
00182   fail_unless(p != NULL);
00183   if (p == NULL) {
00184     return NULL;
00185   }
00186   fail_unless(p->next == NULL);
00187   err = pbuf_take(p, test_data, length);
00188   fail_unless(err == ERR_OK);
00189 
00190   /* add UDP header */
00191   ret = pbuf_add_header(p, sizeof(struct udp_hdr));
00192   fail_unless(!ret);
00193   uh = (struct udp_hdr *)p->payload;
00194   uh->chksum = 0;
00195   uh->dest = uh->src = lwip_htons(port);
00196   uh->len = lwip_htons(p->tot_len);
00197   /* add IPv4 header */
00198   ret = pbuf_add_header(p, sizeof(struct ip_hdr));
00199   fail_unless(!ret);
00200   ih = (struct ip_hdr *)p->payload;
00201   memset(ih, 0, sizeof(*ih));
00202   ih->dest.addr = dst_addr;
00203   ih->_len = lwip_htons(p->tot_len);
00204   ih->_ttl = 32;
00205   ih->_proto = IP_PROTO_UDP;
00206   IPH_VHL_SET(ih, 4, sizeof(struct ip_hdr) / 4);
00207   IPH_CHKSUM_SET(ih, inet_chksum(ih, sizeof(struct ip_hdr)));
00208   return p;
00209 }
00210 
00211 /* bind 2 pcbs to specific netif IP and test which one gets broadcasts */
00212 START_TEST(test_udp_broadcast_rx_with_2_netifs)
00213 {
00214   err_t err;
00215   struct udp_pcb *pcb1, *pcb2;
00216   const u16_t port = 12345;
00217   struct test_udp_rxdata ctr1, ctr2;
00218   struct pbuf *p;
00219 #if SO_REUSE
00220   struct udp_pcb *pcb_any;
00221   struct test_udp_rxdata ctr_any;
00222 #endif
00223   LWIP_UNUSED_ARG(_i);
00224 
00225   pcb1 = udp_new();
00226   fail_unless(pcb1 != NULL);
00227   pcb2 = udp_new();
00228   fail_unless(pcb2 != NULL);
00229 
00230 #if SO_REUSE
00231   pcb_any = udp_new();
00232   fail_unless(pcb_any != NULL);
00233 
00234   ip_set_option(pcb1, SOF_REUSEADDR);
00235   ip_set_option(pcb2, SOF_REUSEADDR);
00236   ip_set_option(pcb_any, SOF_REUSEADDR);
00237 
00238   err = udp_bind(pcb_any, NULL, port);
00239   fail_unless(err == ERR_OK);
00240   memset(&ctr_any, 0, sizeof(ctr_any));
00241   ctr_any.pcb = pcb_any;
00242   udp_recv(pcb_any, test_recv, &ctr_any);
00243 #endif
00244 
00245   err = udp_bind(pcb1, &test_netif1.ip_addr, port);
00246   fail_unless(err == ERR_OK);
00247   err = udp_bind(pcb2, &test_netif2.ip_addr, port);
00248   fail_unless(err == ERR_OK);
00249 
00250   memset(&ctr1, 0, sizeof(ctr1));
00251   ctr1.pcb = pcb1;
00252   memset(&ctr2, 0, sizeof(ctr2));
00253   ctr2.pcb = pcb2;
00254 
00255   udp_recv(pcb1, test_recv, &ctr1);
00256   udp_recv(pcb2, test_recv, &ctr2);
00257 
00258   /* unicast to netif1 */
00259   p = test_udp_create_test_packet(16, port, test_ipaddr1.addr);
00260   EXPECT_RET(p != NULL);
00261   err = ip4_input(p, &test_netif1);
00262   fail_unless(err == ERR_OK);
00263   fail_unless(ctr1.rx_cnt == 1);
00264   fail_unless(ctr1.rx_bytes == 16);
00265   fail_unless(ctr2.rx_cnt == 0);
00266 #if SO_REUSE
00267   fail_unless(ctr_any.rx_cnt == 0);
00268 #endif
00269   ctr1.rx_cnt = ctr1.rx_bytes = 0;
00270 
00271   /* unicast to netif2 */
00272   p = test_udp_create_test_packet(16, port, test_ipaddr2.addr);
00273   EXPECT_RET(p != NULL);
00274   err = ip4_input(p, &test_netif2);
00275   fail_unless(err == ERR_OK);
00276   fail_unless(ctr2.rx_cnt == 1);
00277   fail_unless(ctr2.rx_bytes == 16);
00278   fail_unless(ctr1.rx_cnt == 0);
00279 #if SO_REUSE
00280   fail_unless(ctr_any.rx_cnt == 0);
00281 #endif
00282   ctr2.rx_cnt = ctr2.rx_bytes = 0;
00283 
00284   /* broadcast to netif1-broadcast, input to netif2 */
00285   p = test_udp_create_test_packet(16, port, test_ipaddr1.addr | ~test_netmask1.addr);
00286   EXPECT_RET(p != NULL);
00287   err = ip4_input(p, &test_netif2);
00288   fail_unless(err == ERR_OK);
00289   fail_unless(ctr1.rx_cnt == 1);
00290   fail_unless(ctr1.rx_bytes == 16);
00291   fail_unless(ctr2.rx_cnt == 0);
00292 #if SO_REUSE
00293   fail_unless(ctr_any.rx_cnt == 0);
00294 #endif
00295   ctr1.rx_cnt = ctr1.rx_bytes = 0;
00296 
00297   /* broadcast to netif2-broadcast, input to netif1 */
00298   p = test_udp_create_test_packet(16, port, test_ipaddr2.addr | ~test_netmask2.addr);
00299   EXPECT_RET(p != NULL);
00300   err = ip4_input(p, &test_netif1);
00301   fail_unless(err == ERR_OK);
00302   fail_unless(ctr2.rx_cnt == 1);
00303   fail_unless(ctr2.rx_bytes == 16);
00304   fail_unless(ctr1.rx_cnt == 0);
00305 #if SO_REUSE
00306   fail_unless(ctr_any.rx_cnt == 0);
00307 #endif
00308   ctr2.rx_cnt = ctr2.rx_bytes = 0;
00309 
00310   /* broadcast to global-broadcast, input to netif1 */
00311   p = test_udp_create_test_packet(16, port, 0xffffffff);
00312   EXPECT_RET(p != NULL);
00313   err = ip4_input(p, &test_netif1);
00314   fail_unless(err == ERR_OK);
00315   fail_unless(ctr1.rx_cnt == 1);
00316   fail_unless(ctr1.rx_bytes == 16);
00317   fail_unless(ctr2.rx_cnt == 0);
00318 #if SO_REUSE
00319   fail_unless(ctr_any.rx_cnt == 0);
00320 #endif
00321   ctr1.rx_cnt = ctr1.rx_bytes = 0;
00322 
00323   /* broadcast to global-broadcast, input to netif2 */
00324   p = test_udp_create_test_packet(16, port, 0xffffffff);
00325   EXPECT_RET(p != NULL);
00326   err = ip4_input(p, &test_netif2);
00327   fail_unless(err == ERR_OK);
00328   fail_unless(ctr2.rx_cnt == 1);
00329   fail_unless(ctr2.rx_bytes == 16);
00330   fail_unless(ctr1.rx_cnt == 0);
00331 #if SO_REUSE
00332   fail_unless(ctr_any.rx_cnt == 0);
00333 #endif
00334   ctr2.rx_cnt = ctr2.rx_bytes = 0;
00335 }
00336 END_TEST
00337 
00338 /** Create the suite including all tests for this module */
00339 Suite *
00340 udp_suite(void)
00341 {
00342   testfunc tests[] = {
00343     TESTFUNC(test_udp_new_remove),
00344     TESTFUNC(test_udp_broadcast_rx_with_2_netifs)
00345   };
00346   return create_suite("UDP", tests, sizeof(tests)/sizeof(testfunc), udp_setup, udp_teardown);
00347 }