mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2025-12-10 08:46:40 +08:00
Update and insert on ARP requests as well. Made etharp_arp_input() RFC826 compliant, and efficient.
This commit is contained in:
parent
5df9545dcc
commit
9a83833e30
@ -386,7 +386,8 @@ etharp_ip_input(struct netif *netif, struct pbuf *p)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Responds to ARP requests, updates ARP entries and sends queued IP packets.
|
* Responds to ARP requests to us. Upon ARP replies to us, add entry to cache
|
||||||
|
* send out queued IP packets. Updates cache with snooped address pairs.
|
||||||
*
|
*
|
||||||
* Should be called for incoming ARP packets. The pbuf in the argument
|
* Should be called for incoming ARP packets. The pbuf in the argument
|
||||||
* is freed by this function.
|
* is freed by this function.
|
||||||
@ -404,16 +405,25 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
|
|||||||
{
|
{
|
||||||
struct etharp_hdr *hdr;
|
struct etharp_hdr *hdr;
|
||||||
u8_t i;
|
u8_t i;
|
||||||
|
u8_t for_us;
|
||||||
|
|
||||||
/* drop short ARP packets */
|
/* drop short ARP packets */
|
||||||
if (p->tot_len < sizeof(struct etharp_hdr)) {
|
if (p->tot_len < sizeof(struct etharp_hdr)) {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet too short (%d/%d)\n", p->tot_len, sizeof(struct etharp_hdr)));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet dropped, too short (%d/%d)\n", p->tot_len, sizeof(struct etharp_hdr)));
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr = p->payload;
|
hdr = p->payload;
|
||||||
|
|
||||||
|
/* this interface is not configured? */
|
||||||
|
if (netif->ip_addr.addr == 0) {
|
||||||
|
for_us = 0;
|
||||||
|
} else {
|
||||||
|
/* ARP packet directed to us? */
|
||||||
|
for_us = ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr));
|
||||||
|
}
|
||||||
|
|
||||||
switch (htons(hdr->opcode)) {
|
switch (htons(hdr->opcode)) {
|
||||||
/* ARP request? */
|
/* ARP request? */
|
||||||
case ARP_REQUEST:
|
case ARP_REQUEST:
|
||||||
@ -428,10 +438,8 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
|
|||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* update the ARP cache */
|
|
||||||
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0);
|
|
||||||
/* ARP request for our address? */
|
/* ARP request for our address? */
|
||||||
if (ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) {
|
if (for_us) {
|
||||||
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));
|
||||||
/* re-use pbuf to send ARP reply */
|
/* re-use pbuf to send ARP reply */
|
||||||
@ -456,35 +464,36 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
|
|||||||
hdr->ethhdr.type = htons(ETHTYPE_ARP);
|
hdr->ethhdr.type = htons(ETHTYPE_ARP);
|
||||||
/* return ARP reply */
|
/* return ARP reply */
|
||||||
netif->linkoutput(netif, p);
|
netif->linkoutput(netif, p);
|
||||||
|
|
||||||
|
/* request was not directed to us */
|
||||||
} else {
|
} else {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request was not for us.\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request was not for us.\n"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARP_REPLY:
|
case ARP_REPLY:
|
||||||
/* ARP reply. We insert or update the ARP table. */
|
/* ARP reply. We insert or update the ARP table later. */
|
||||||
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"));
|
||||||
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
|
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
|
||||||
/* DHCP needs to know about ARP replies */
|
/* DHCP needs to know about ARP replies to our address */
|
||||||
dhcp_arp_reply(netif, &hdr->sipaddr);
|
if (for_us) dhcp_arp_reply(netif, &hdr->sipaddr);
|
||||||
#endif
|
#endif
|
||||||
/* ARP reply directed to us? */
|
|
||||||
if (ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) {
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply is for us\n"));
|
|
||||||
/* update_the ARP cache, ask to insert */
|
|
||||||
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), ARP_INSERT_FLAG);
|
|
||||||
/* ARP reply not directed to us */
|
|
||||||
} else {
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply is not for us\n"));
|
|
||||||
/* update the destination address pair */
|
|
||||||
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0);
|
|
||||||
/* update the destination address pair */
|
|
||||||
update_arp_entry(netif, &(hdr->dipaddr), &(hdr->dhwaddr), 0);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %d\n", htons(hdr->opcode)));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %d\n", htons(hdr->opcode)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* add or update entries in the ARP cache */
|
||||||
|
if (for_us) {
|
||||||
|
/* insert IP address in ARP cache (assume requester wants to talk to us)
|
||||||
|
* we might even send out a queued packet to this host */
|
||||||
|
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), ARP_INSERT_FLAG);
|
||||||
|
/* request was not directed to us, but snoop anyway */
|
||||||
|
} else {
|
||||||
|
/* update or insert the source IP address in the cache */
|
||||||
|
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0);
|
||||||
|
/* update or insert the destination IP address pair in the cache */
|
||||||
|
update_arp_entry(netif, &(hdr->dipaddr), &(hdr->dhwaddr), 0);
|
||||||
|
}
|
||||||
/* free ARP packet */
|
/* free ARP packet */
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
p = NULL;
|
p = NULL;
|
||||||
@ -734,10 +743,12 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
|||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: sending ARP request.\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: sending ARP request.\n"));
|
||||||
hdr = p->payload;
|
hdr = p->payload;
|
||||||
hdr->opcode = htons(ARP_REQUEST);
|
hdr->opcode = htons(ARP_REQUEST);
|
||||||
for(j = 0; j < netif->hwaddr_len; ++j)
|
for (j = 0; j < netif->hwaddr_len; ++j)
|
||||||
{
|
{
|
||||||
hdr->dhwaddr.addr[j] = 0x00;
|
|
||||||
hdr->shwaddr.addr[j] = srcaddr->addr[j];
|
hdr->shwaddr.addr[j] = srcaddr->addr[j];
|
||||||
|
/* the hardware address is what we ask for, in
|
||||||
|
* a request it is a don't-care, we use 0's */
|
||||||
|
hdr->dhwaddr.addr[j] = 0x00;
|
||||||
}
|
}
|
||||||
ip_addr_set(&(hdr->dipaddr), ipaddr);
|
ip_addr_set(&(hdr->dipaddr), ipaddr);
|
||||||
ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));
|
ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));
|
||||||
@ -747,7 +758,7 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
|||||||
|
|
||||||
hdr->proto = htons(ETHTYPE_IP);
|
hdr->proto = htons(ETHTYPE_IP);
|
||||||
ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
|
ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
|
||||||
for(j = 0; j < netif->hwaddr_len; ++j)
|
for (j = 0; j < netif->hwaddr_len; ++j)
|
||||||
{
|
{
|
||||||
hdr->ethhdr.dest.addr[j] = 0xff;
|
hdr->ethhdr.dest.addr[j] = 0xff;
|
||||||
hdr->ethhdr.src.addr[j] = srcaddr->addr[j];
|
hdr->ethhdr.src.addr[j] = srcaddr->addr[j];
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user