130 |
/** |
/** |
131 |
* Clears expired entries in the ARP table. |
* Clears expired entries in the ARP table. |
132 |
* |
* |
133 |
* This function should be called every ETHARP_TMR_INTERVAL microseconds (10 seconds), |
* This function should be called every ETHARP_TMR_INTERVAL microseconds (5 seconds), |
134 |
* in order to expire entries in the ARP table. |
* in order to expire entries in the ARP table. |
135 |
*/ |
*/ |
136 |
void |
void |
201 |
*/ |
*/ |
202 |
static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags) |
static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags) |
203 |
{ |
{ |
204 |
s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE, empty = ARP_TABLE_SIZE, i; |
s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE; |
205 |
u8_t age_pending = 0, age_stable = 0; |
s8_t empty = ARP_TABLE_SIZE; |
206 |
|
u8_t i = 0, age_pending = 0, age_stable = 0; |
207 |
#if ARP_QUEUEING |
#if ARP_QUEUEING |
208 |
/* oldest entry with packets on queue */ |
/* oldest entry with packets on queue */ |
209 |
s8_t old_queue = ARP_TABLE_SIZE; |
s8_t old_queue = ARP_TABLE_SIZE; |
273 |
/* { we have no match } => try to create a new entry */ |
/* { we have no match } => try to create a new entry */ |
274 |
|
|
275 |
/* no empty entry found and not allowed to recycle? */ |
/* no empty entry found and not allowed to recycle? */ |
276 |
if ((i == ARP_TABLE_SIZE) && ((flags & ETHARP_TRY_HARD) == 0)) |
if ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_TRY_HARD) == 0)) |
277 |
{ |
{ |
278 |
return (s8_t)ERR_MEM; |
return (s8_t)ERR_MEM; |
279 |
} |
} |
312 |
/* recycle oldest pending */ |
/* recycle oldest pending */ |
313 |
i = old_queue; |
i = old_queue; |
314 |
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: selecting oldest pending entry %d, freeing packet queue %p\n", i, (void *)(arp_table[i].p))); |
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: selecting oldest pending entry %d, freeing packet queue %p\n", i, (void *)(arp_table[i].p))); |
315 |
/* no empty or recyclable entries found */ |
pbuf_free(arp_table[i].p); |
316 |
|
arp_table[i].p = NULL; |
317 |
#endif |
#endif |
318 |
|
/* no empty or recyclable entries found */ |
319 |
} else { |
} else { |
320 |
return (s8_t)ERR_MEM; |
return (s8_t)ERR_MEM; |
321 |
} |
} |
326 |
|
|
327 |
/* recycle entry (no-op for an already empty entry) */ |
/* recycle entry (no-op for an already empty entry) */ |
328 |
arp_table[i].state = ETHARP_STATE_EMPTY; |
arp_table[i].state = ETHARP_STATE_EMPTY; |
329 |
|
|
330 |
/* IP address given? */ |
/* IP address given? */ |
331 |
if (ipaddr != NULL) { |
if (ipaddr != NULL) { |
332 |
/* set IP address */ |
/* set IP address */ |
333 |
ip_addr_set(&arp_table[i].ipaddr, ipaddr); |
ip_addr_set(&arp_table[i].ipaddr, ipaddr); |
334 |
} |
} |
335 |
arp_table[i].ctime = 0; |
arp_table[i].ctime = 0; |
|
#if ARP_QUEUEING |
|
|
/* remove any queued packets */ |
|
|
if (arp_table[i].p != NULL) pbuf_free(arp_table[i].p); |
|
|
arp_table[i].p = NULL; |
|
|
#endif |
|
336 |
return (err_t)i; |
return (err_t)i; |
337 |
} |
} |
338 |
|
|
555 |
/* ARP reply. We already updated the ARP cache earlier. */ |
/* ARP reply. We already updated the ARP cache earlier. */ |
556 |
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n")); |
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n")); |
557 |
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) |
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) |
558 |
/* DHCP wants to know about ARP replies to our wanna-have-address */ |
/* When unconfigured, DHCP wants to know about ARP replies from the |
559 |
if (for_us) dhcp_arp_reply(netif, &sipaddr); |
* address offered to us, as that means someone else uses it already! */ |
560 |
|
if (netif->ip_addr.addr == 0) dhcp_arp_reply(netif, &sipaddr); |
561 |
#endif |
#endif |
562 |
break; |
break; |
563 |
default: |
default: |