mbed-os for GR-LYCHEE

Dependents:   mbed-os-example-blinky-gr-lychee GR-Boads_Camera_sample GR-Boards_Audio_Recoder GR-Boads_Camera_DisplayApp ... more

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