SAMV71 Xplained Ultra Software Package 1.0

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 ip_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(ip_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(ip_addr_t);
00095   etharphdr->opcode = htons(ARP_REPLY);
00096 
00097   SMEMCPY(&etharphdr->sipaddr, adr, sizeof(ip_addr_t));
00098   SMEMCPY(&etharphdr->dipaddr, &test_ipaddr, sizeof(ip_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   ip_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     ip_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 err = udp_sendto(pcb, p, &adrs[i], 123);
00164         fail_unless(err == ERR_OK);
00165         /* etharp request sent? */
00166         fail_unless(linkoutput_ctr == (2*i) + 1);
00167         pbuf_free(p);
00168 
00169         /* create an ARP response */
00170         create_arp_response(&adrs[i]);
00171         /* queued UDP packet sent? */
00172         fail_unless(linkoutput_ctr == (2*i) + 2);
00173 
00174         idx = etharp_find_addr(NULL, &adrs[i], &unused_ethaddr, &unused_ipaddr);
00175         fail_unless(idx == i);
00176         etharp_tmr();
00177       }
00178     }
00179     linkoutput_ctr = 0;
00180 #if ETHARP_SUPPORT_STATIC_ENTRIES
00181     /* create one static entry */
00182     err = etharp_add_static_entry(&adrs[ARP_TABLE_SIZE], &test_ethaddr3);
00183     fail_unless(err == ERR_OK);
00184     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
00185     fail_unless(idx == 0);
00186     fail_unless(linkoutput_ctr == 0);
00187 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
00188 
00189     linkoutput_ctr = 0;
00190     /* fill ARP-table with dynamic entries */
00191     for(i = 0; i < ARP_TABLE_SIZE; i++) {
00192       struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 10, PBUF_RAM);
00193       fail_unless(p != NULL);
00194       if (p != NULL) {
00195         err_t err = udp_sendto(pcb, p, &adrs[i], 123);
00196         fail_unless(err == ERR_OK);
00197         /* etharp request sent? */
00198         fail_unless(linkoutput_ctr == (2*i) + 1);
00199         pbuf_free(p);
00200 
00201         /* create an ARP response */
00202         create_arp_response(&adrs[i]);
00203         /* queued UDP packet sent? */
00204         fail_unless(linkoutput_ctr == (2*i) + 2);
00205 
00206         idx = etharp_find_addr(NULL, &adrs[i], &unused_ethaddr, &unused_ipaddr);
00207         if (i < ARP_TABLE_SIZE - 1) {
00208           fail_unless(idx == i+1);
00209         } else {
00210           /* the last entry must not overwrite the static entry! */
00211           fail_unless(idx == 1);
00212         }
00213         etharp_tmr();
00214       }
00215     }
00216 #if ETHARP_SUPPORT_STATIC_ENTRIES
00217     /* create a second static entry */
00218     err = etharp_add_static_entry(&adrs[ARP_TABLE_SIZE+1], &test_ethaddr4);
00219     fail_unless(err == ERR_OK);
00220     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
00221     fail_unless(idx == 0);
00222     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr);
00223     fail_unless(idx == 2);
00224     /* and remove it again */
00225     err = etharp_remove_static_entry(&adrs[ARP_TABLE_SIZE+1]);
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 == -1);
00231 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
00232 
00233     /* check that static entries don't time out */
00234     etharp_remove_all();
00235     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
00236     fail_unless(idx == 0);
00237 
00238 #if ETHARP_SUPPORT_STATIC_ENTRIES
00239     /* remove the first static entry */
00240     err = etharp_remove_static_entry(&adrs[ARP_TABLE_SIZE]);
00241     fail_unless(err == ERR_OK);
00242     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr);
00243     fail_unless(idx == -1);
00244     idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr);
00245     fail_unless(idx == -1);
00246 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
00247 
00248     udp_remove(pcb);
00249   }
00250 }
00251 END_TEST
00252 
00253 
00254 /** Create the suite including all tests for this module */
00255 Suite *
00256 etharp_suite(void)
00257 {
00258   TFun tests[] = {
00259     test_etharp_table
00260   };
00261   return create_suite("ETHARP", tests, sizeof(tests)/sizeof(TFun), etharp_setup, etharp_teardown);
00262 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines