3 |
* Address Resolution Protocol module for IP over Ethernet |
* Address Resolution Protocol module for IP over Ethernet |
4 |
* |
* |
5 |
* $Log$ |
* $Log$ |
6 |
|
* Revision 1.14 2002/12/02 16:08:09 likewise |
7 |
|
* Fixed wrong assertion condition. |
8 |
|
* |
9 |
* Revision 1.13 2002/11/29 16:02:11 likewise |
* Revision 1.13 2002/11/29 16:02:11 likewise |
10 |
* More complete ARP protocol implementation. |
* More complete ARP protocol implementation. |
11 |
* |
* |
152 |
}; |
}; |
153 |
|
|
154 |
static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}}; |
static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}}; |
155 |
static struct etharp_entry arp_table[ARP_TABLE_SIZE]; |
static struct etharp_entry arp_table[ARP_TABLE_SIZE] = { 0 } ; |
156 |
static u8_t ctime; |
static u8_t ctime; |
157 |
|
|
158 |
static struct pbuf *update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags); |
static struct pbuf *update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags); |
168 |
/* clear ARP entries */ |
/* clear ARP entries */ |
169 |
for(i = 0; i < ARP_TABLE_SIZE; ++i) { |
for(i = 0; i < ARP_TABLE_SIZE; ++i) { |
170 |
arp_table[i].state = ETHARP_STATE_EMPTY; |
arp_table[i].state = ETHARP_STATE_EMPTY; |
171 |
|
arp_table[i].p = NULL; |
172 |
} |
} |
173 |
/* reset ARP current time */ |
/* reset ARP current time */ |
174 |
ctime = 0; |
ctime = 0; |
200 |
#endif |
#endif |
201 |
} else if((arp_table[i].state == ETHARP_STATE_PENDING) && |
} else if((arp_table[i].state == ETHARP_STATE_PENDING) && |
202 |
(ctime - arp_table[i].ctime >= ARP_MAXPENDING)) { |
(ctime - arp_table[i].ctime >= ARP_MAXPENDING)) { |
|
DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u - dequeueing %p.\n", i, arp_table[i].p)); |
|
203 |
arp_table[i].state = ETHARP_STATE_EMPTY; |
arp_table[i].state = ETHARP_STATE_EMPTY; |
204 |
#if ARP_QUEUEING |
#if ARP_QUEUEING |
205 |
|
DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u - dequeueing %p.\n", i, arp_table[i].p)); |
206 |
/* remove any queued packet */ |
/* remove any queued packet */ |
207 |
pbuf_free(arp_table[i].p); |
pbuf_free(arp_table[i].p); |
208 |
arp_table[i].p = NULL; |
arp_table[i].p = NULL; |
209 |
|
#else |
210 |
|
DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u.\n", i); |
211 |
#endif |
#endif |
212 |
} |
} |
213 |
} |
} |
249 |
DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found oldest stable entry %u\n", j)); |
DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found oldest stable entry %u\n", j)); |
250 |
i = j; |
i = j; |
251 |
} |
} |
252 |
|
DEBUGF(ETHARP_DEBUG, ("find_arp_entry: returning %u, state %u\n", i, arp_table[i].state)); |
253 |
return i; |
return i; |
254 |
} |
} |
255 |
|
|
272 |
{ |
{ |
273 |
u8_t i, k; |
u8_t i, k; |
274 |
struct eth_hdr *ethhdr; |
struct eth_hdr *ethhdr; |
275 |
|
DEBUGF(ETHARP_DEBUG, ("update_arp_entry()")); |
276 |
|
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: %u.%u.%u.%u - %02x:%02x:%02x:%02x:%02x:%02x\n", ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr), |
277 |
|
ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5], ethaddr->addr[6])); |
278 |
/* do not update for 0.0.0.0 addresses */ |
/* do not update for 0.0.0.0 addresses */ |
279 |
if (ipaddr->addr == 0) return NULL; |
if (ipaddr->addr == 0) { |
280 |
|
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: will not add 0.0.0.0 to ARP cache\n")); |
281 |
|
return NULL; |
282 |
|
} |
283 |
/* Walk through the ARP mapping table and try to find an entry to |
/* Walk through the ARP mapping table and try to find an entry to |
284 |
update. If none is found, the IP -> MAC address mapping is |
update. If none is found, the IP -> MAC address mapping is |
285 |
inserted in the ARP table. */ |
inserted in the ARP table. */ |
330 |
/* no matching ARP entry was found */ |
/* no matching ARP entry was found */ |
331 |
ASSERT("update_arp_entry: i == ARP_TABLE_SIZE", i == ARP_TABLE_SIZE); |
ASSERT("update_arp_entry: i == ARP_TABLE_SIZE", i == ARP_TABLE_SIZE); |
332 |
|
|
333 |
|
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: IP address not yet in table\n")); |
334 |
/* allowed to insert an entry? */ |
/* allowed to insert an entry? */ |
335 |
if ((ETHARP_ALWAYS_INSERT) || (flags & ARP_INSERT_FLAG)) |
if ((ETHARP_ALWAYS_INSERT) || (flags & ARP_INSERT_FLAG)) |
336 |
{ |
{ |
337 |
|
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: adding entry to table\n")); |
338 |
/* find an empty or old entry. */ |
/* find an empty or old entry. */ |
339 |
i = find_arp_entry(); |
i = find_arp_entry(); |
340 |
if(i == ARP_TABLE_SIZE) { |
if(i == ARP_TABLE_SIZE) { |
345 |
if (arp_table[i].state == ETHARP_STATE_STABLE) { |
if (arp_table[i].state == ETHARP_STATE_STABLE) { |
346 |
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: overwriting old stable entry %u\n", i)); |
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: overwriting old stable entry %u\n", i)); |
347 |
/* stable entries should have no queued packets (TODO: allow later) */ |
/* stable entries should have no queued packets (TODO: allow later) */ |
348 |
ASSERT("update_arp_entry: arp_table[i].p != NULL", arp_table[i].p != NULL); |
ASSERT("update_arp_entry: arp_table[i].p == NULL", arp_table[i].p == NULL); |
349 |
} else { |
} else { |
350 |
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: filling empty entry %u with state %u\n", i, arp_table[i].stat)); |
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: filling empty entry %u with state %u\n", i, arp_table[i].state)); |
351 |
ASSERT("update_arp_entry: arp_table[i].state == ETHARP_STATE_EMPTY", arp_table[i].state == ETHARP_STATE_EMPTY); |
ASSERT("update_arp_entry: arp_table[i].state == ETHARP_STATE_EMPTY", arp_table[i].state == ETHARP_STATE_EMPTY); |
352 |
} |
} |
353 |
/* set IP address */ |
/* set IP address */ |
478 |
/* return ARP reply */ |
/* return ARP reply */ |
479 |
netif->linkoutput(netif, p); |
netif->linkoutput(netif, p); |
480 |
} else { |
} else { |
481 |
DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: ARP request, but not for us.\n")); |
DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: incoming ARP request was not for us.\n")); |
482 |
} |
} |
483 |
break; |
break; |
484 |
case ARP_REPLY: |
case ARP_REPLY: |
485 |
/* ARP reply. We insert or update the ARP table. */ |
/* ARP reply. We insert or update the ARP table. */ |
486 |
DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: ARP reply\n")); |
DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: incoming ARP reply\n")); |
487 |
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) |
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) |
488 |
/* DHCP needs to know about ARP replies */ |
/* DHCP needs to know about ARP replies */ |
489 |
dhcp_arp_reply(&hdr->sipaddr); |
dhcp_arp_reply(&hdr->sipaddr); |
490 |
#endif |
#endif |
491 |
/* ARP reply directed to us? */ |
/* ARP reply directed to us? */ |
492 |
if(ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) { |
if(ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) { |
493 |
DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: ARP reply for us\n")); |
DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: incoming ARP reply is for us\n")); |
494 |
/* update_the ARP cache, ask to insert */ |
/* update_the ARP cache, ask to insert */ |
495 |
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), ARP_INSERT_FLAG); |
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), ARP_INSERT_FLAG); |
496 |
/* ARP reply not directed to us */ |
/* ARP reply not directed to us */ |
497 |
} else { |
} else { |
498 |
DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: ARP reply, but NOT for us\n")); |
DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: incoming ARP reply is not for us\n")); |
499 |
/* update the destination address pair */ |
/* update the destination address pair */ |
500 |
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0); |
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0); |
501 |
/* update the destination address pair */ |
/* update the destination address pair */ |
503 |
} |
} |
504 |
break; |
break; |
505 |
default: |
default: |
506 |
DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: unknown type %d\n", htons(hdr->opcode))); |
DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: ARP unknown opcode type %d\n", htons(hdr->opcode))); |
507 |
break; |
break; |
508 |
} |
} |
509 |
/* free ARP packet */ |
/* free ARP packet */ |