149 |
/* remove expired entries from the ARP table */ |
/* remove expired entries from the ARP table */ |
150 |
for(i = 0; i < ARP_TABLE_SIZE; ++i) { |
for(i = 0; i < ARP_TABLE_SIZE; ++i) { |
151 |
arp_table[i].ctime++; |
arp_table[i].ctime++; |
152 |
if((arp_table[i].state == ETHARP_STATE_STABLE) && |
if ((arp_table[i].state == ETHARP_STATE_STABLE) && |
153 |
(arp_table[i].ctime >= ARP_MAXAGE)) { |
(arp_table[i].ctime >= ARP_MAXAGE)) { |
154 |
DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %u.\n", i)); |
DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %u.\n", i)); |
155 |
arp_table[i].state = ETHARP_STATE_EMPTY; |
arp_table[i].state = ETHARP_STATE_EMPTY; |
158 |
pbuf_free(arp_table[i].p); |
pbuf_free(arp_table[i].p); |
159 |
arp_table[i].p = NULL; |
arp_table[i].p = NULL; |
160 |
#endif |
#endif |
161 |
} else if((arp_table[i].state == ETHARP_STATE_PENDING) && |
} else if ((arp_table[i].state == ETHARP_STATE_PENDING) && |
162 |
(arp_table[i].ctime >= ARP_MAXPENDING)) { |
(arp_table[i].ctime >= ARP_MAXPENDING)) { |
163 |
arp_table[i].state = ETHARP_STATE_EMPTY; |
arp_table[i].state = ETHARP_STATE_EMPTY; |
164 |
#if ARP_QUEUEING |
#if ARP_QUEUEING |
187 |
|
|
188 |
/* Try to find an unused entry in the ARP table. */ |
/* Try to find an unused entry in the ARP table. */ |
189 |
for(i = 0; i < ARP_TABLE_SIZE; ++i) { |
for(i = 0; i < ARP_TABLE_SIZE; ++i) { |
190 |
if(arp_table[i].state == ETHARP_STATE_EMPTY) { |
if (arp_table[i].state == ETHARP_STATE_EMPTY) { |
191 |
DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found empty entry %u\n", i)); |
DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found empty entry %u\n", i)); |
192 |
break; |
break; |
193 |
} |
} |
195 |
|
|
196 |
/* If no unused entry is found, we try to find the oldest entry and |
/* If no unused entry is found, we try to find the oldest entry and |
197 |
throw it away. If all entries are new and have 0 ctime drop one */ |
throw it away. If all entries are new and have 0 ctime drop one */ |
198 |
if(i == ARP_TABLE_SIZE) { |
if (i == ARP_TABLE_SIZE) { |
199 |
maxtime = 0; |
maxtime = 0; |
200 |
j = ARP_TABLE_SIZE; |
j = ARP_TABLE_SIZE; |
201 |
for(i = 0; i < ARP_TABLE_SIZE; ++i) { |
for(i = 0; i < ARP_TABLE_SIZE; ++i) { |
202 |
/* remember entry with oldest stable entry in j*/ |
/* remember entry with oldest stable entry in j*/ |
203 |
if((arp_table[i].state == ETHARP_STATE_STABLE) && |
if ((arp_table[i].state == ETHARP_STATE_STABLE) && |
204 |
#if ARP_QUEUEING /* do not want to re-use an entry with queued packets */ |
#if ARP_QUEUEING /* do not want to re-use an entry with queued packets */ |
205 |
(arp_table[i].p == NULL) && |
(arp_table[i].p == NULL) && |
206 |
#endif |
#endif |
252 |
for(i = 0; i < ARP_TABLE_SIZE; ++i) { |
for(i = 0; i < ARP_TABLE_SIZE; ++i) { |
253 |
/* Check if the source IP address of the incoming packet matches |
/* Check if the source IP address of the incoming packet matches |
254 |
the IP address in this ARP table entry. */ |
the IP address in this ARP table entry. */ |
255 |
if(ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { |
if (ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { |
256 |
/* pending entry? */ |
/* pending entry? */ |
257 |
if(arp_table[i].state == ETHARP_STATE_PENDING) { |
if (arp_table[i].state == ETHARP_STATE_PENDING) { |
258 |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: pending entry %u goes stable\n", i)); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: pending entry %u goes stable\n", i)); |
259 |
/* A pending entry was found, mark it stable */ |
/* A pending entry was found, mark it stable */ |
260 |
arp_table[i].state = ETHARP_STATE_STABLE; |
arp_table[i].state = ETHARP_STATE_STABLE; |
261 |
/* fall-through to next if */ |
/* fall-through to next if */ |
262 |
} |
} |
263 |
/* stable entry? (possible just marked to become stable) */ |
/* stable entry? (possible just marked to become stable) */ |
264 |
if(arp_table[i].state == ETHARP_STATE_STABLE) { |
if (arp_table[i].state == ETHARP_STATE_STABLE) { |
265 |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: updating stable entry %u\n", i)); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: updating stable entry %u\n", i)); |
266 |
/* An old entry found, update this and return. */ |
/* An old entry found, update this and return. */ |
267 |
for(k = 0; k < netif->hwaddr_len; ++k) { |
for(k = 0; k < netif->hwaddr_len; ++k) { |
271 |
arp_table[i].ctime = 0; |
arp_table[i].ctime = 0; |
272 |
#if ARP_QUEUEING |
#if ARP_QUEUEING |
273 |
/* queued packet present? */ |
/* queued packet present? */ |
274 |
if((p = arp_table[i].p) != NULL) { |
if ((p = arp_table[i].p) != NULL) { |
275 |
/* Null out attached buffer immediately */ |
/* Null out attached buffer immediately */ |
276 |
arp_table[i].p = NULL; |
arp_table[i].p = NULL; |
277 |
/* fill-in Ethernet header */ |
/* fill-in Ethernet header */ |
302 |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: adding entry to table\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: adding entry to table\n")); |
303 |
/* find an empty or old entry. */ |
/* find an empty or old entry. */ |
304 |
i = find_arp_entry(); |
i = find_arp_entry(); |
305 |
if(i == ARP_TABLE_SIZE) { |
if (i == ARP_TABLE_SIZE) { |
306 |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: no available entry found\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: no available entry found\n")); |
307 |
return NULL; |
return NULL; |
308 |
} |
} |
363 |
incoming IP packet comes from a host on the local network. */ |
incoming IP packet comes from a host on the local network. */ |
364 |
hdr = p->payload; |
hdr = p->payload; |
365 |
/* source is on local network? */ |
/* source is on local network? */ |
366 |
if(!ip_addr_maskcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) { |
if (!ip_addr_maskcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) { |
367 |
/* do nothing */ |
/* do nothing */ |
368 |
return NULL; |
return NULL; |
369 |
} |
} |
396 |
u8_t i; |
u8_t i; |
397 |
|
|
398 |
/* drop short ARP packets */ |
/* drop short ARP packets */ |
399 |
if(p->tot_len < sizeof(struct etharp_hdr)) { |
if (p->tot_len < sizeof(struct etharp_hdr)) { |
400 |
DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet too short (%d/%d)\n", p->tot_len, sizeof(struct etharp_hdr))); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet too short (%d/%d)\n", p->tot_len, sizeof(struct etharp_hdr))); |
401 |
pbuf_free(p); |
pbuf_free(p); |
402 |
return NULL; |
return NULL; |
404 |
|
|
405 |
hdr = p->payload; |
hdr = p->payload; |
406 |
|
|
407 |
switch(htons(hdr->opcode)) { |
switch (htons(hdr->opcode)) { |
408 |
/* ARP request? */ |
/* ARP request? */ |
409 |
case ARP_REQUEST: |
case ARP_REQUEST: |
410 |
/* ARP request. If it asked for our address, we send out a |
/* ARP request. If it asked for our address, we send out a |
413 |
|
|
414 |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request\n")); |
415 |
/* we are not configured? */ |
/* we are not configured? */ |
416 |
if(netif->ip_addr.addr == 0) { |
if (netif->ip_addr.addr == 0) { |
417 |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n")); |
418 |
pbuf_free(p); |
pbuf_free(p); |
419 |
return NULL; |
return NULL; |
421 |
/* update the ARP cache */ |
/* update the ARP cache */ |
422 |
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0); |
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0); |
423 |
/* ARP request for our address? */ |
/* ARP request for our address? */ |
424 |
if(ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) { |
if (ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) { |
425 |
|
|
426 |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n")); |
427 |
/* re-use pbuf to send ARP reply */ |
/* re-use pbuf to send ARP reply */ |
458 |
dhcp_arp_reply(netif, &hdr->sipaddr); |
dhcp_arp_reply(netif, &hdr->sipaddr); |
459 |
#endif |
#endif |
460 |
/* ARP reply directed to us? */ |
/* ARP reply directed to us? */ |
461 |
if(ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) { |
if (ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) { |
462 |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply is for us\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply is for us\n")); |
463 |
/* update_the ARP cache, ask to insert */ |
/* update_the ARP cache, ask to insert */ |
464 |
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), ARP_INSERT_FLAG); |
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), ARP_INSERT_FLAG); |
514 |
u8_t i; |
u8_t i; |
515 |
|
|
516 |
/* Make room for Ethernet header. */ |
/* Make room for Ethernet header. */ |
517 |
if(pbuf_header(q, sizeof(struct eth_hdr)) != 0) { |
if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) { |
518 |
/* The pbuf_header() call shouldn't fail, and we'll just bail |
/* The pbuf_header() call shouldn't fail, and we'll just bail |
519 |
out if it does.. */ |
out if it does.. */ |
520 |
DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n")); |
535 |
ARP table. */ |
ARP table. */ |
536 |
|
|
537 |
/* destination IP address is an IP broadcast address? */ |
/* destination IP address is an IP broadcast address? */ |
538 |
if(ip_addr_isany(ipaddr) || |
if (ip_addr_isany(ipaddr) || |
539 |
ip_addr_isbroadcast(ipaddr, &(netif->netmask))) { |
ip_addr_isbroadcast(ipaddr, &(netif->netmask))) { |
540 |
/* broadcast on Ethernet also */ |
/* broadcast on Ethernet also */ |
541 |
dest = (struct eth_addr *)ðbroadcast; |
dest = (struct eth_addr *)ðbroadcast; |
542 |
} |
} |
543 |
/* destination IP address is an IP multicast address? */ |
/* destination IP address is an IP multicast address? */ |
544 |
else if(ip_addr_ismulticast(ipaddr)) { |
else if (ip_addr_ismulticast(ipaddr)) { |
545 |
/* Hash IP multicast address to MAC address. */ |
/* Hash IP multicast address to MAC address. */ |
546 |
mcastaddr.addr[0] = 0x01; |
mcastaddr.addr[0] = 0x01; |
547 |
mcastaddr.addr[1] = 0x0; |
mcastaddr.addr[1] = 0x0; |
556 |
else { |
else { |
557 |
/* destination IP network address not on local network? */ |
/* destination IP network address not on local network? */ |
558 |
/* this occurs if the packet is routed to the default gateway on this interface */ |
/* this occurs if the packet is routed to the default gateway on this interface */ |
559 |
if(!ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) { |
if (!ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) { |
560 |
/* gateway available? */ |
/* gateway available? */ |
561 |
if (netif->gw.addr != 0) |
if (netif->gw.addr != 0) |
562 |
{ |
{ |
574 |
/* Ethernet address for IP destination address is in ARP cache? */ |
/* Ethernet address for IP destination address is in ARP cache? */ |
575 |
for(i = 0; i < ARP_TABLE_SIZE; ++i) { |
for(i = 0; i < ARP_TABLE_SIZE; ++i) { |
576 |
/* match found? */ |
/* match found? */ |
577 |
if(arp_table[i].state == ETHARP_STATE_STABLE && |
if (arp_table[i].state == ETHARP_STATE_STABLE && |
578 |
ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { |
ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { |
579 |
dest = &arp_table[i].ethaddr; |
dest = &arp_table[i].ethaddr; |
580 |
break; |
break; |
651 |
srcaddr = (struct eth_addr *)netif->hwaddr; |
srcaddr = (struct eth_addr *)netif->hwaddr; |
652 |
/* bail out if this IP address is pending */ |
/* bail out if this IP address is pending */ |
653 |
for(i = 0; i < ARP_TABLE_SIZE; ++i) { |
for(i = 0; i < ARP_TABLE_SIZE; ++i) { |
654 |
if(ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { |
if (ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { |
655 |
if (arp_table[i].state == ETHARP_STATE_PENDING) { |
if (arp_table[i].state == ETHARP_STATE_PENDING) { |
656 |
DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already pending as entry %u\n", i)); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already pending as entry %u\n", i)); |
657 |
/* break out of for-loop, user may wish to queue a packet on a stable entry */ |
/* break out of for-loop, user may wish to queue a packet on a stable entry */ |