638 |
* TODO: use the ctime field to see how long ago an ARP request was sent, |
* TODO: use the ctime field to see how long ago an ARP request was sent, |
639 |
* possibly retry. |
* possibly retry. |
640 |
*/ |
*/ |
641 |
struct pbuf *etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q) |
err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q) |
642 |
{ |
{ |
643 |
struct eth_addr *srcaddr; |
struct eth_addr *srcaddr; |
644 |
struct etharp_hdr *hdr; |
struct etharp_hdr *hdr; |
645 |
struct pbuf *p; |
struct pbuf *p; |
646 |
|
err_t result; |
647 |
u8_t i; |
u8_t i; |
648 |
|
|
649 |
srcaddr = (struct eth_addr *)netif->hwaddr; |
srcaddr = (struct eth_addr *)netif->hwaddr; |
652 |
if(ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { |
if(ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { |
653 |
if (arp_table[i].state == ETHARP_STATE_PENDING) { |
if (arp_table[i].state == ETHARP_STATE_PENDING) { |
654 |
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)); |
655 |
/* break out of for-loop */ |
/* break out of for-loop, user may wish to queue a packet on a stable entry */ |
656 |
break; |
break; |
657 |
} |
} |
658 |
else if (arp_table[i].state == ETHARP_STATE_STABLE) { |
else if (arp_table[i].state == ETHARP_STATE_STABLE) { |
659 |
DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already stable as entry %u\n", i)); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already stable as entry %u\n", i)); |
660 |
|
/* TODO: user may wish to queue a packet on a stable entry. */ |
661 |
return NULL; |
return NULL; |
662 |
} |
} |
663 |
} |
} |
664 |
} |
} |
665 |
/* queried address not yet pending in ARP table? */ |
/* queried address not yet in ARP table? */ |
666 |
if (i == ARP_TABLE_SIZE) |
if (i == ARP_TABLE_SIZE) { |
|
{ |
|
667 |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: IP address not found in ARP table\n")); |
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: IP address not found in ARP table\n")); |
668 |
/* find an available entry */ |
/* find an available entry */ |
669 |
i = find_arp_entry(); |
i = find_arp_entry(); |
670 |
/* bail out if no ARP entries are available */ |
/* bail out if no ARP entries are available */ |
671 |
if(i == ARP_TABLE_SIZE) |
if (i == ARP_TABLE_SIZE) { |
|
{ |
|
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 |
} |
} |
686 |
if ((q != NULL) && (arp_table[i].p == NULL)) { |
if ((q != NULL) && (arp_table[i].p == NULL)) { |
687 |
/* copy PBUF_REF referenced payloads to PBUF_RAM */ |
/* copy PBUF_REF referenced payloads to PBUF_RAM */ |
688 |
q = pbuf_take(q); |
q = pbuf_take(q); |
|
/* pbufs are queued, increase the reference count */ |
|
|
pbuf_ref(q); |
|
689 |
/* remember pbuf to queue, if any */ |
/* remember pbuf to queue, if any */ |
690 |
arp_table[i].p = q; |
arp_table[i].p = q; |
691 |
|
/* pbufs are queued, increase the reference count */ |
692 |
|
pbuf_ref(q); |
693 |
DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("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 |
721 |
} |
} |
722 |
hdr->ethhdr.type = htons(ETHTYPE_ARP); |
hdr->ethhdr.type = htons(ETHTYPE_ARP); |
723 |
/* send ARP query */ |
/* send ARP query */ |
724 |
netif->linkoutput(netif, p); |
result = netif->linkoutput(netif, p); |
725 |
/* free ARP query packet */ |
/* free ARP query packet */ |
726 |
pbuf_free(p); |
pbuf_free(p); |
727 |
p = NULL; |
p = NULL; |
728 |
} else { |
} else { |
729 |
|
result = ERR_MEM; |
730 |
DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("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")); |
731 |
} |
} |
732 |
return NULL; |
return result; |
733 |
} |
} |