238 |
struct pbuf *p; |
struct pbuf *p; |
239 |
struct eth_hdr *ethhdr; |
struct eth_hdr *ethhdr; |
240 |
#endif |
#endif |
241 |
DEBUGF(ETHARP_DEBUG, ("update_arp_entry()")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("update_arp_entry()\n")); |
242 |
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), |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("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), |
243 |
ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5])); |
ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5])); |
244 |
/* do not update for 0.0.0.0 addresses */ |
/* do not update for 0.0.0.0 addresses */ |
245 |
if (ipaddr->addr == 0) { |
if (ipaddr->addr == 0) { |
246 |
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: will not add 0.0.0.0 to ARP cache\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: will not add 0.0.0.0 to ARP cache\n")); |
247 |
return NULL; |
return NULL; |
248 |
} |
} |
249 |
/* 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 |
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, ("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, ("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 < 6; ++k) { |
for(k = 0; k < netif->hwaddr_len; ++k) { |
268 |
arp_table[i].ethaddr.addr[k] = ethaddr->addr[k]; |
arp_table[i].ethaddr.addr[k] = ethaddr->addr[k]; |
269 |
} |
} |
270 |
/* reset time stamp */ |
/* reset time stamp */ |
276 |
arp_table[i].p = NULL; |
arp_table[i].p = NULL; |
277 |
/* fill-in Ethernet header */ |
/* fill-in Ethernet header */ |
278 |
ethhdr = p->payload; |
ethhdr = p->payload; |
279 |
for(k = 0; k < 6; ++k) { |
for(k = 0; k < netif->hwaddr_len; ++k) { |
280 |
ethhdr->dest.addr[k] = ethaddr->addr[k]; |
ethhdr->dest.addr[k] = ethaddr->addr[k]; |
281 |
} |
} |
282 |
ethhdr->type = htons(ETHTYPE_IP); |
ethhdr->type = htons(ETHTYPE_IP); |
283 |
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: sending queued IP packet.\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: sending queued IP packet.\n")); |
284 |
/* send the queued IP packet */ |
/* send the queued IP packet */ |
285 |
netif->linkoutput(netif, p); |
netif->linkoutput(netif, p); |
286 |
/* free the queued IP packet */ |
/* free the queued IP packet */ |
295 |
/* no matching ARP entry was found */ |
/* no matching ARP entry was found */ |
296 |
LWIP_ASSERT("update_arp_entry: i == ARP_TABLE_SIZE", i == ARP_TABLE_SIZE); |
LWIP_ASSERT("update_arp_entry: i == ARP_TABLE_SIZE", i == ARP_TABLE_SIZE); |
297 |
|
|
298 |
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: IP address not yet in table\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: IP address not yet in table\n")); |
299 |
/* allowed to insert an entry? */ |
/* allowed to insert an entry? */ |
300 |
if ((ETHARP_ALWAYS_INSERT) || (flags & ARP_INSERT_FLAG)) |
if ((ETHARP_ALWAYS_INSERT) || (flags & ARP_INSERT_FLAG)) |
301 |
{ |
{ |
302 |
DEBUGF(ETHARP_DEBUG, ("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, ("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 |
} |
} |
309 |
/* see if find_arp_entry() gave us an old stable, or empty entry to re-use */ |
/* see if find_arp_entry() gave us an old stable, or empty entry to re-use */ |
310 |
if (arp_table[i].state == ETHARP_STATE_STABLE) { |
if (arp_table[i].state == ETHARP_STATE_STABLE) { |
311 |
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: overwriting old stable entry %u\n", i)); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: overwriting old stable entry %u\n", i)); |
312 |
/* stable entries should have no queued packets (TODO: allow later) */ |
/* stable entries should have no queued packets (TODO: allow later) */ |
313 |
#if ARP_QUEUEING |
#if ARP_QUEUEING |
314 |
LWIP_ASSERT("update_arp_entry: arp_table[i].p == NULL", arp_table[i].p == NULL); |
LWIP_ASSERT("update_arp_entry: arp_table[i].p == NULL", arp_table[i].p == NULL); |
315 |
#endif |
#endif |
316 |
} else { |
} else { |
317 |
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: filling empty entry %u with state %u\n", i, arp_table[i].state)); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("update_arp_entry: filling empty entry %u with state %u\n", i, arp_table[i].state)); |
318 |
LWIP_ASSERT("update_arp_entry: arp_table[i].state == ETHARP_STATE_EMPTY", arp_table[i].state == ETHARP_STATE_EMPTY); |
LWIP_ASSERT("update_arp_entry: arp_table[i].state == ETHARP_STATE_EMPTY", arp_table[i].state == ETHARP_STATE_EMPTY); |
319 |
} |
} |
320 |
/* set IP address */ |
/* set IP address */ |
321 |
ip_addr_set(&arp_table[i].ipaddr, ipaddr); |
ip_addr_set(&arp_table[i].ipaddr, ipaddr); |
322 |
/* set Ethernet hardware address */ |
/* set Ethernet hardware address */ |
323 |
for(k = 0; k < 6; ++k) { |
for(k = 0; k < netif->hwaddr_len; ++k) { |
324 |
arp_table[i].ethaddr.addr[k] = ethaddr->addr[k]; |
arp_table[i].ethaddr.addr[k] = ethaddr->addr[k]; |
325 |
} |
} |
326 |
/* reset time-stamp */ |
/* reset time-stamp */ |
334 |
} |
} |
335 |
else |
else |
336 |
{ |
{ |
337 |
DEBUGF(ETHARP_DEBUG, ("update_arp_entry: no matching stable entry to update\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: no matching stable entry to update\n")); |
338 |
} |
} |
339 |
return NULL; |
return NULL; |
340 |
} |
} |
368 |
return NULL; |
return NULL; |
369 |
} |
} |
370 |
|
|
371 |
DEBUGF(ETHARP_DEBUG, ("etharp_ip_input: updating ETHARP table.\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n")); |
372 |
/* update ARP table, ask to insert entry */ |
/* update ARP table, ask to insert entry */ |
373 |
update_arp_entry(netif, &(hdr->ip.src), &(hdr->eth.src), ARP_INSERT_FLAG); |
update_arp_entry(netif, &(hdr->ip.src), &(hdr->eth.src), ARP_INSERT_FLAG); |
374 |
return NULL; |
return NULL; |
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, ("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; |
403 |
} |
} |
411 |
reply. In any case, we time-stamp any existing ARP entry, |
reply. In any case, we time-stamp any existing ARP entry, |
412 |
and possiby send out an IP packet that was queued on it. */ |
and possiby send out an IP packet that was queued on it. */ |
413 |
|
|
414 |
DEBUGF(ETHARP_DEBUG, ("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, ("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; |
420 |
} |
} |
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, ("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 */ |
428 |
hdr->opcode = htons(ARP_REPLY); |
hdr->opcode = htons(ARP_REPLY); |
429 |
|
|
430 |
ip_addr_set(&(hdr->dipaddr), &(hdr->sipaddr)); |
ip_addr_set(&(hdr->dipaddr), &(hdr->sipaddr)); |
431 |
ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr)); |
ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr)); |
432 |
|
|
433 |
for(i = 0; i < 6; ++i) { |
for(i = 0; i < netif->hwaddr_len; ++i) { |
434 |
hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i]; |
hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i]; |
435 |
hdr->shwaddr.addr[i] = ethaddr->addr[i]; |
hdr->shwaddr.addr[i] = ethaddr->addr[i]; |
436 |
hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i]; |
hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i]; |
438 |
} |
} |
439 |
|
|
440 |
hdr->hwtype = htons(HWTYPE_ETHERNET); |
hdr->hwtype = htons(HWTYPE_ETHERNET); |
441 |
ARPH_HWLEN_SET(hdr, 6); |
ARPH_HWLEN_SET(hdr, netif->hwaddr_len); |
442 |
|
|
443 |
hdr->proto = htons(ETHTYPE_IP); |
hdr->proto = htons(ETHTYPE_IP); |
444 |
ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr)); |
ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr)); |
447 |
/* return ARP reply */ |
/* return ARP reply */ |
448 |
netif->linkoutput(netif, p); |
netif->linkoutput(netif, p); |
449 |
} else { |
} else { |
450 |
DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: incoming ARP request was not for us.\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request was not for us.\n")); |
451 |
} |
} |
452 |
break; |
break; |
453 |
case ARP_REPLY: |
case ARP_REPLY: |
454 |
/* ARP reply. We insert or update the ARP table. */ |
/* ARP reply. We insert or update the ARP table. */ |
455 |
DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: incoming ARP reply\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n")); |
456 |
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) |
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) |
457 |
/* DHCP needs to know about ARP replies */ |
/* DHCP needs to know about ARP replies */ |
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, ("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); |
465 |
/* ARP reply not directed to us */ |
/* ARP reply not directed to us */ |
466 |
} else { |
} else { |
467 |
DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: incoming ARP reply is not for us\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply is not for us\n")); |
468 |
/* update the destination address pair */ |
/* update the destination address pair */ |
469 |
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0); |
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0); |
470 |
/* update the destination address pair */ |
/* update the destination address pair */ |
472 |
} |
} |
473 |
break; |
break; |
474 |
default: |
default: |
475 |
DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: ARP unknown opcode type %d\n", htons(hdr->opcode))); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %d\n", htons(hdr->opcode))); |
476 |
break; |
break; |
477 |
} |
} |
478 |
/* free ARP packet */ |
/* free ARP packet */ |
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, ("etharp_output: could not allocate room for header.\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n")); |
521 |
#ifdef LINK_STATS |
#ifdef LINK_STATS |
522 |
++lwip_stats.link.lenerr; |
++lwip_stats.link.lenerr; |
523 |
#endif /* LINK_STATS */ |
#endif /* LINK_STATS */ |
600 |
Ethernet header for the outgoing packet. */ |
Ethernet header for the outgoing packet. */ |
601 |
ethhdr = q->payload; |
ethhdr = q->payload; |
602 |
|
|
603 |
for(i = 0; i < 6; i++) { |
for(i = 0; i < netif->hwaddr_len; i++) { |
604 |
ethhdr->dest.addr[i] = dest->addr[i]; |
ethhdr->dest.addr[i] = dest->addr[i]; |
605 |
ethhdr->src.addr[i] = srcaddr->addr[i]; |
ethhdr->src.addr[i] = srcaddr->addr[i]; |
606 |
} |
} |
672 |
DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available.\n")); |
DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available.\n")); |
673 |
return NULL; |
return NULL; |
674 |
} |
} |
675 |
DEBUGF(ETHARP_DEBUG, ("etharp_query: created ARP table entry %u.\n", i)); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: created ARP table entry %u.\n", i)); |
676 |
/* i is available, create ARP entry */ |
/* i is available, create ARP entry */ |
677 |
ip_addr_set(&arp_table[i].ipaddr, ipaddr); |
ip_addr_set(&arp_table[i].ipaddr, ipaddr); |
678 |
arp_table[i].ctime = 0; |
arp_table[i].ctime = 0; |
690 |
pbuf_ref_chain(q); |
pbuf_ref_chain(q); |
691 |
/* remember pbuf to queue, if any */ |
/* remember pbuf to queue, if any */ |
692 |
arp_table[i].p = q; |
arp_table[i].p = q; |
693 |
DEBUGF(ETHARP_DEBUG, ("etharp_query: queued packet %p on ARP entry %u.\n", (void *)q, i)); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: queued packet %p on ARP entry %u.\n", (void *)q, i)); |
694 |
} |
} |
695 |
#endif |
#endif |
696 |
/* allocate a pbuf for the outgoing ARP request packet */ |
/* allocate a pbuf for the outgoing ARP request packet */ |
698 |
/* could allocate pbuf? */ |
/* could allocate pbuf? */ |
699 |
if (p != NULL) { |
if (p != NULL) { |
700 |
u8_t j; |
u8_t j; |
701 |
DEBUGF(ETHARP_DEBUG, ("etharp_query: sending ARP request.\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: sending ARP request.\n")); |
702 |
hdr = p->payload; |
hdr = p->payload; |
703 |
hdr->opcode = htons(ARP_REQUEST); |
hdr->opcode = htons(ARP_REQUEST); |
704 |
for(j = 0; j < 6; ++j) |
for(j = 0; j < netif->hwaddr_len; ++j) |
705 |
{ |
{ |
706 |
hdr->dhwaddr.addr[j] = 0x00; |
hdr->dhwaddr.addr[j] = 0x00; |
707 |
hdr->shwaddr.addr[j] = srcaddr->addr[j]; |
hdr->shwaddr.addr[j] = srcaddr->addr[j]; |
710 |
ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr)); |
ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr)); |
711 |
|
|
712 |
hdr->hwtype = htons(HWTYPE_ETHERNET); |
hdr->hwtype = htons(HWTYPE_ETHERNET); |
713 |
ARPH_HWLEN_SET(hdr, 6); |
ARPH_HWLEN_SET(hdr, netif->hwaddr_len); |
714 |
|
|
715 |
hdr->proto = htons(ETHTYPE_IP); |
hdr->proto = htons(ETHTYPE_IP); |
716 |
ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr)); |
ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr)); |
717 |
for(j = 0; j < 6; ++j) |
for(j = 0; j < netif->hwaddr_len; ++j) |
718 |
{ |
{ |
719 |
hdr->ethhdr.dest.addr[j] = 0xff; |
hdr->ethhdr.dest.addr[j] = 0xff; |
720 |
hdr->ethhdr.src.addr[j] = srcaddr->addr[j]; |
hdr->ethhdr.src.addr[j] = srcaddr->addr[j]; |
726 |
pbuf_free(p); |
pbuf_free(p); |
727 |
p = NULL; |
p = NULL; |
728 |
} else { |
} else { |
729 |
DEBUGF(ETHARP_DEBUG, ("etharp_query: could not allocate pbuf for ARP request.\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_query: could not allocate pbuf for ARP request.\n")); |
730 |
} |
} |
731 |
return NULL; |
return NULL; |
732 |
} |
} |