1 #include "test_etharp.h" 2 3 #include "lwip/udp.h" 4 #include "lwip/etharp.h" 5 #include "netif/ethernet.h" 6 #include "lwip/stats.h" 7 8 #if !LWIP_STATS || !UDP_STATS || !MEMP_STATS || !ETHARP_STATS 9 #error "This tests needs UDP-, MEMP- and ETHARP-statistics enabled" 10 #endif 11 #if !ETHARP_SUPPORT_STATIC_ENTRIES 12 #error "This test needs ETHARP_SUPPORT_STATIC_ENTRIES enabled" 13 #endif 14 15 static struct netif test_netif; 16 static ip4_addr_t test_ipaddr, test_netmask, test_gw; 17 struct eth_addr test_ethaddr = {{1,1,1,1,1,1}}; 18 struct eth_addr test_ethaddr2 = {{1,1,1,1,1,2}}; 19 struct eth_addr test_ethaddr3 = {{1,1,1,1,1,3}}; 20 struct eth_addr test_ethaddr4 = {{1,1,1,1,1,4}}; 21 static int linkoutput_ctr; 22 23 /* Helper functions */ 24 static void 25 etharp_remove_all(void) 26 { 27 int i; 28 /* call etharp_tmr often enough to have all entries cleaned */ 29 for(i = 0; i < 0xff; i++) { 30 etharp_tmr(); 31 } 32 } 33 34 static err_t 35 default_netif_linkoutput(struct netif *netif, struct pbuf *p) 36 { 37 fail_unless(netif == &test_netif); 38 fail_unless(p != NULL); 39 linkoutput_ctr++; 40 return ERR_OK; 41 } 42 43 static err_t 44 default_netif_init(struct netif *netif) 45 { 46 fail_unless(netif != NULL); 47 netif->linkoutput = default_netif_linkoutput; 48 netif->output = etharp_output; 49 netif->mtu = 1500; 50 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; 51 netif->hwaddr_len = ETHARP_HWADDR_LEN; 52 return ERR_OK; 53 } 54 55 static void 56 default_netif_add(void) 57 { 58 IP4_ADDR(&test_gw, 192,168,0,1); 59 IP4_ADDR(&test_ipaddr, 192,168,0,1); 60 IP4_ADDR(&test_netmask, 255,255,0,0); 61 62 fail_unless(netif_default == NULL); 63 netif_set_default(netif_add(&test_netif, &test_ipaddr, &test_netmask, 64 &test_gw, NULL, default_netif_init, NULL)); 65 netif_set_up(&test_netif); 66 } 67 68 static void 69 default_netif_remove(void) 70 { 71 fail_unless(netif_default == &test_netif); 72 netif_remove(&test_netif); 73 } 74 75 static void 76 create_arp_response(ip4_addr_t *adr) 77 { 78 int k; 79 struct eth_hdr *ethhdr; 80 struct etharp_hdr *etharphdr; 81 struct pbuf *p = pbuf_alloc(PBUF_RAW, sizeof(struct eth_hdr) + sizeof(struct etharp_hdr), PBUF_RAM); 82 if(p == NULL) { 83 FAIL_RET(); 84 } 85 ethhdr = (struct eth_hdr*)p->payload; 86 etharphdr = (struct etharp_hdr*)(ethhdr + 1); 87 88 ethhdr->dest = test_ethaddr; 89 ethhdr->src = test_ethaddr2; 90 ethhdr->type = htons(ETHTYPE_ARP); 91 92 etharphdr->hwtype = htons(/*HWTYPE_ETHERNET*/ 1); 93 etharphdr->proto = htons(ETHTYPE_IP); 94 etharphdr->hwlen = ETHARP_HWADDR_LEN; 95 etharphdr->protolen = sizeof(ip4_addr_t); 96 etharphdr->opcode = htons(ARP_REPLY); 97 98 SMEMCPY(ðarphdr->sipaddr, adr, sizeof(ip4_addr_t)); 99 SMEMCPY(ðarphdr->dipaddr, &test_ipaddr, sizeof(ip4_addr_t)); 100 101 k = 6; 102 while(k > 0) { 103 k--; 104 /* Write the ARP MAC-Addresses */ 105 etharphdr->shwaddr.addr[k] = test_ethaddr2.addr[k]; 106 etharphdr->dhwaddr.addr[k] = test_ethaddr.addr[k]; 107 /* Write the Ethernet MAC-Addresses */ 108 ethhdr->dest.addr[k] = test_ethaddr.addr[k]; 109 ethhdr->src.addr[k] = test_ethaddr2.addr[k]; 110 } 111 112 ethernet_input(p, &test_netif); 113 } 114 115 /* Setups/teardown functions */ 116 117 static void 118 etharp_setup(void) 119 { 120 etharp_remove_all(); 121 default_netif_add(); 122 } 123 124 static void 125 etharp_teardown(void) 126 { 127 etharp_remove_all(); 128 default_netif_remove(); 129 } 130 131 132 /* Test functions */ 133 134 START_TEST(test_etharp_table) 135 { 136 #if ETHARP_SUPPORT_STATIC_ENTRIES 137 err_t err; 138 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ 139 s8_t idx; 140 const ip4_addr_t *unused_ipaddr; 141 struct eth_addr *unused_ethaddr; 142 struct udp_pcb* pcb; 143 LWIP_UNUSED_ARG(_i); 144 145 if (netif_default != &test_netif) { 146 fail("This test needs a default netif"); 147 } 148 149 linkoutput_ctr = 0; 150 151 pcb = udp_new(); 152 fail_unless(pcb != NULL); 153 if (pcb != NULL) { 154 ip4_addr_t adrs[ARP_TABLE_SIZE + 2]; 155 int i; 156 for(i = 0; i < ARP_TABLE_SIZE + 2; i++) { 157 IP4_ADDR(&adrs[i], 192,168,0,i+2); 158 } 159 /* fill ARP-table with dynamic entries */ 160 for(i = 0; i < ARP_TABLE_SIZE; i++) { 161 struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 10, PBUF_RAM); 162 fail_unless(p != NULL); 163 if (p != NULL) { 164 err_t err2; 165 ip_addr_t dst; 166 ip_addr_copy_from_ip4(dst, adrs[i]); 167 err2 = udp_sendto(pcb, p, &dst, 123); 168 fail_unless(err2 == ERR_OK); 169 /* etharp request sent? */ 170 fail_unless(linkoutput_ctr == (2*i) + 1); 171 pbuf_free(p); 172 173 /* create an ARP response */ 174 create_arp_response(&adrs[i]); 175 /* queued UDP packet sent? */ 176 fail_unless(linkoutput_ctr == (2*i) + 2); 177 178 idx = etharp_find_addr(NULL, &adrs[i], &unused_ethaddr, &unused_ipaddr); 179 fail_unless(idx == i); 180 etharp_tmr(); 181 } 182 } 183 linkoutput_ctr = 0; 184 #if ETHARP_SUPPORT_STATIC_ENTRIES 185 /* create one static entry */ 186 err = etharp_add_static_entry(&adrs[ARP_TABLE_SIZE], &test_ethaddr3); 187 fail_unless(err == ERR_OK); 188 idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr); 189 fail_unless(idx == 0); 190 fail_unless(linkoutput_ctr == 0); 191 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ 192 193 linkoutput_ctr = 0; 194 /* fill ARP-table with dynamic entries */ 195 for(i = 0; i < ARP_TABLE_SIZE; i++) { 196 struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 10, PBUF_RAM); 197 fail_unless(p != NULL); 198 if (p != NULL) { 199 err_t err2; 200 ip_addr_t dst; 201 ip_addr_copy_from_ip4(dst, adrs[i]); 202 err2 = udp_sendto(pcb, p, &dst, 123); 203 fail_unless(err2 == ERR_OK); 204 /* etharp request sent? */ 205 fail_unless(linkoutput_ctr == (2*i) + 1); 206 pbuf_free(p); 207 208 /* create an ARP response */ 209 create_arp_response(&adrs[i]); 210 /* queued UDP packet sent? */ 211 fail_unless(linkoutput_ctr == (2*i) + 2); 212 213 idx = etharp_find_addr(NULL, &adrs[i], &unused_ethaddr, &unused_ipaddr); 214 if (i < ARP_TABLE_SIZE - 1) { 215 fail_unless(idx == i+1); 216 } else { 217 /* the last entry must not overwrite the static entry! */ 218 fail_unless(idx == 1); 219 } 220 etharp_tmr(); 221 } 222 } 223 #if ETHARP_SUPPORT_STATIC_ENTRIES 224 /* create a second static entry */ 225 err = etharp_add_static_entry(&adrs[ARP_TABLE_SIZE+1], &test_ethaddr4); 226 fail_unless(err == ERR_OK); 227 idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr); 228 fail_unless(idx == 0); 229 idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr); 230 fail_unless(idx == 2); 231 /* and remove it again */ 232 err = etharp_remove_static_entry(&adrs[ARP_TABLE_SIZE+1]); 233 fail_unless(err == ERR_OK); 234 idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr); 235 fail_unless(idx == 0); 236 idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr); 237 fail_unless(idx == -1); 238 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ 239 240 /* check that static entries don't time out */ 241 etharp_remove_all(); 242 idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr); 243 fail_unless(idx == 0); 244 245 #if ETHARP_SUPPORT_STATIC_ENTRIES 246 /* remove the first static entry */ 247 err = etharp_remove_static_entry(&adrs[ARP_TABLE_SIZE]); 248 fail_unless(err == ERR_OK); 249 idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr); 250 fail_unless(idx == -1); 251 idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr); 252 fail_unless(idx == -1); 253 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ 254 255 udp_remove(pcb); 256 } 257 } 258 END_TEST 259 260 261 /** Create the suite including all tests for this module */ 262 Suite * 263 etharp_suite(void) 264 { 265 testfunc tests[] = { 266 TESTFUNC(test_etharp_table) 267 }; 268 return create_suite("ETHARP", tests, sizeof(tests)/sizeof(testfunc), etharp_setup, etharp_teardown); 269 } 270