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