ON Semiconductor / mbed-os

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers test_etharp.c Source File

test_etharp.c

00001 #include "test_etharp.h"
00002 
00003 #include "lwip/udp.h"
00004 #include "netif/etharp.h"
00005 #include "lwip/stats.h"
00006 
00007 #if !LWIP_STATS || !UDP_STATS || !MEMP_STATS || !ETHARP_STATS
00008 #error "This tests needs UDP-, MEMP- and ETHARP-statistics enabled"
00009 #endif
00010 #if !ETHARP_SUPPORT_STATIC_ENTRIES
00011 #error "This test needs ETHARP_SUPPORT_STATIC_ENTRIES enabled"
00012 #endif
00013 
00014 static struct netif test_netif;
00015 static ip4_addr_t test_ipaddr, test_netmask, test_gw;
00016 struct eth_addr test_ethaddr =  {{1,1,1,1,1,1}};
00017 struct eth_addr test_ethaddr2 = {{1,1,1,1,1,2}};
00018 struct eth_addr test_ethaddr3 = {{1,1,1,1,1,3}};
00019 struct eth_addr test_ethaddr4 = {{1,1,1,1,1,4}};
00020 static int linkoutput_ctr;
00021 
00022 /* Helper functions */
00023 static void
00024 etharp_remove_all(void)
00025 {
00026   int i;
00027   /* call etharp_tmr often enough to have all entries cleaned */
00028   for(i = 0; i < 0xff; i++) {
00029     etharp_tmr();
00030   }
00031 }
00032 
00033 static err_t
00034 default_netif_linkoutput(struct netif *netif, struct pbuf *p)
00035 {
00036   fail_unless(netif == &test_netif);
00037   fail_unless(p != NULL);
00038   linkoutput_ctr++;
00039   return ERR_OK;
00040 }
00041 
00042 static err_t
00043 default_netif_init(struct netif *netif)
00044 {
00045   fail_unless(netif != NULL);
00046   netif->linkoutput = default_netif_linkoutput;
00047   netif->output = etharp_output;
00048   netif->mtu = 1500;
00049   netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
00050   netif->hwaddr_len = ETHARP_HWADDR_LEN;
00051   return ERR_OK;
00052 }
00053 
00054 static void
00055 default_netif_add(void)
00056 {
00057   IP4_ADDR(&test_gw, 192,168,0,1);
00058   IP4_ADDR(&test_ipaddr, 192,168,0,1);
00059   IP4_ADDR(&test_netmask, 255,255,0,0);
00060 
00061   fail_unless(netif_default == NULL);
00062   netif_set_default(netif_add(&test_netif, &test_ipaddr, &test_netmask,
00063                               &test_gw, NULL, default_netif_init, NULL));
00064   netif_set_up(&test_netif);
00065 }
00066 
00067 static void
00068 default_netif_remove(void)
00069 {
00070   fail_unless(netif_default == &test_netif);
00071   netif_remove(&test_netif);
00072 }
00073 
00074 static void
00075 create_arp_response(ip4_addr_t *adr)
00076 {
00077   int k;
00078   struct eth_hdr *ethhdr;
00079   struct etharp_hdr *etharphdr;
00080   struct pbuf *p = pbuf_alloc(PBUF_RAW, sizeof(struct eth_hdr) + sizeof(struct etharp_hdr), PBUF_RAM);
00081   if(p == NULL) {
00082     FAIL_RET();
00083   }
00084   ethhdr = (struct eth_hdr*)p->payload;
00085   etharphdr = (struct etharp_hdr*)(ethhdr + 1);
00086 
00087   ethhdr->dest = test_ethaddr;
00088   ethhdr->src = test_ethaddr2;
00089   ethhdr->type = htons(ETHTYPE_ARP);
00090 
00091   etharphdr->hwtype = htons(/*HWTYPE_ETHERNET*/ 1);
00092   etharphdr->proto = htons(ETHTYPE_IP);
00093   etharphdr->hwlen = ETHARP_HWADDR_LEN;
00094   etharphdr->protolen = sizeof(ip4_addr_t);
00095   etharphdr->opcode = htons(ARP_REPLY);
00096 
00097   SMEMCPY(&etharphdr->sipaddr, adr, sizeof(ip4_addr_t));
00098   SMEMCPY(&etharphdr->dipaddr, &test_ipaddr, sizeof(ip4_addr_t));
00099 
00100   k = 6;
00101   while(k > 0) {
00102     k--;
00103     /* Write the ARP MAC-Addresses */
00104     etharphdr->shwaddr.addr[k] = test_ethaddr2.addr[k];
00105     etharphdr->dhwaddr.addr[k] = test_ethaddr.addr[k];
00106     /* Write the Ethernet MAC-Addresses */
00107     ethhdr->dest.addr[k] = test_ethaddr.addr[k];
00108     ethhdr->src.addr[k]  = test_ethaddr2.addr[k];
00109   }
00110 
00111   ethernet_input(p, &test_netif);
00112 }
00113 
00114 /* Setups/teardown functions */
00115 
00116 static void
00117 etharp_setup(void)
00118 {
00119   etharp_remove_all();
00120   default_netif_add();
00121 }
00122 
00123 static void
00124 etharp_teardown(void)
00125 {
00126   etharp_remove_all();
00127   default_netif_remove();
00128 }
00129 
00130 
00131 /* Test functions */
00132 
00133 START_TEST(test_etharp_table)
00134 {
00135 #if ETHARP_SUPPORT_STATIC_ENTRIES
00136   err_t err;
00137 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
00138   s8_t idx;
00139   const ip4_addr_t *unused_ipaddr;
00140   struct eth_addr *unused_ethaddr;
00141   struct udp_pcb* pcb;
00142   LWIP_UNUSED_ARG(_i);
00143 
00144   if (netif_default != &test_netif) {
00145     fail("This test needs a default netif");
00146   }
00147 
00148   linkoutput_ctr = 0;
00149 
00150   pcb = udp_new();
00151   fail_unless(pcb != NULL);
00152   if (pcb != NULL) {
00153     ip4_addr_t adrs[ARP_TABLE_SIZE + 2];
00154     int i;
00155     for(i = 0; i < ARP_TABLE_SIZE + 2; i++) {
00156       IP4_ADDR(&adrs[i], 192,168,0,i+2);
00157     }
00158     /* fill ARP-table with dynamic entries */
00159     for(i = 0; i < ARP_TABLE_SIZE; i++) {
00160       struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 10, PBUF_RAM);
00161       fail_unless(p != NULL);
00162       if (p != NULL) {
00163         err_t err2;
00164         ip_addr_t dst;
00165         ip_addr_copy_from_ip4(dst, adrs[i]);
00166         err2 = udp_sendto(pcb, p, &dst, 123);
00167         fail_unless(err2 == ERR_OK);
00168         /* etharp request sent? */
00169         fail_unless(linkoutput_ctr == (2*i) + 1);
00170         pbuf_free(p);
00171 
00172         /* create an ARP response */
00173         create_arp_response(&adrs[i]);
00174         /* queued UDP packet sent? */
00175         fail_unless(linkoutput_ctr == (2*i) + 2);
00176 
00177         idx = etharp_find_addr(NULL, &adrs[i], &unused_ethaddr, &unused_ipaddr);
00178         fail_unless(idx == i);
00179         etharp_tmr();
00180       }
00181     }
00182     linkoutput_ctr = 0;
00183 #if ETHARP_SUPPORT_STATIC_ENTRIES
00184     /* create one static entry */
00185     err = etharp_add_static_entry(&adrs[ARP_TABLE_SIZE], &test_ethaddr3);
00186     fail_unless(err == ERR_OK);
00187     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
00188     fail_unless(idx == 0);
00189     fail_unless(linkoutput_ctr == 0);
00190 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
00191 
00192     linkoutput_ctr = 0;
00193     /* fill ARP-table with dynamic entries */
00194     for(i = 0; i < ARP_TABLE_SIZE; i++) {
00195       struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 10, PBUF_RAM);
00196       fail_unless(p != NULL);
00197       if (p != NULL) {
00198         err_t err2;
00199         ip_addr_t dst;
00200         ip_addr_copy_from_ip4(dst, adrs[i]);
00201         err2 = udp_sendto(pcb, p, &dst, 123);
00202         fail_unless(err2 == ERR_OK);
00203         /* etharp request sent? */
00204         fail_unless(linkoutput_ctr == (2*i) + 1);
00205         pbuf_free(p);
00206 
00207         /* create an ARP response */
00208         create_arp_response(&adrs[i]);
00209         /* queued UDP packet sent? */
00210         fail_unless(linkoutput_ctr == (2*i) + 2);
00211 
00212         idx = etharp_find_addr(NULL, &adrs[i], &unused_ethaddr, &unused_ipaddr);
00213         if (i < ARP_TABLE_SIZE - 1) {
00214           fail_unless(idx == i+1);
00215         } else {
00216           /* the last entry must not overwrite the static entry! */
00217           fail_unless(idx == 1);
00218         }
00219         etharp_tmr();
00220       }
00221     }
00222 #if ETHARP_SUPPORT_STATIC_ENTRIES
00223     /* create a second static entry */
00224     err = etharp_add_static_entry(&adrs[ARP_TABLE_SIZE+1], &test_ethaddr4);
00225     fail_unless(err == ERR_OK);
00226     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
00227     fail_unless(idx == 0);
00228     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr);
00229     fail_unless(idx == 2);
00230     /* and remove it again */
00231     err = etharp_remove_static_entry(&adrs[ARP_TABLE_SIZE+1]);
00232     fail_unless(err == ERR_OK);
00233     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
00234     fail_unless(idx == 0);
00235     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr);
00236     fail_unless(idx == -1);
00237 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
00238 
00239     /* check that static entries don't time out */
00240     etharp_remove_all();
00241     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
00242     fail_unless(idx == 0);
00243 
00244 #if ETHARP_SUPPORT_STATIC_ENTRIES
00245     /* remove the first static entry */
00246     err = etharp_remove_static_entry(&adrs[ARP_TABLE_SIZE]);
00247     fail_unless(err == ERR_OK);
00248     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
00249     fail_unless(idx == -1);
00250     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr);
00251     fail_unless(idx == -1);
00252 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
00253 
00254     udp_remove(pcb);
00255   }
00256 }
00257 END_TEST
00258 
00259 
00260 /** Create the suite including all tests for this module */
00261 Suite *
00262 etharp_suite(void)
00263 {
00264   testfunc tests[] = {
00265     TESTFUNC(test_etharp_table)
00266   };
00267   return create_suite("ETHARP", tests, sizeof(tests)/sizeof(testfunc), etharp_setup, etharp_teardown);
00268 }