diff --git a/src/netif/etharp.c b/src/netif/etharp.c index c7e3f98d..bc2e5e0a 100644 --- a/src/netif/etharp.c +++ b/src/netif/etharp.c @@ -372,20 +372,22 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e #if ARP_QUEUEING /* get the first packet on the queue (if any) */ p = arp_table[i].p; - /* queued packet present? */ + /* (another) queued packet present? */ while (p != NULL) { struct pbuf *q, *n; /* search for second packet on queue (n) */ q = p; while (q->tot_len > q->len) { - /* proceed to next pbuf of this packet */ - LWIP_ASSERT("q->next ! NULL", q->next != NULL); - q = q->next; + LWIP_ASSERT("q->next != NULL (while q->tot_len > q->len)", q->next != NULL); + /* proceed to next pbuf of this packet */ + q = q->next; } - /* { q = last pbuf of first packet, q->tot_len = q->len } */ + /* { q = last pbuf of this packet, q->tot_len == q->len } */ + LWIP_ASSERT("q->tot_len == q->len", q->tot_len == q->len); + /* remember next packet on queue */ n = q->next; - /* { n = first pbuf of 2nd packet, or NULL if no 2nd packet } */ - /* terminate the first packet pbuf chain */ + /* { n = first pbuf of next packet, or NULL if no next packet } */ + /* terminate this packet pbuf chain */ q->next = NULL; /* fill-in Ethernet header */ ethhdr = p->payload; @@ -394,7 +396,7 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e ethhdr->src.addr[k] = netif->hwaddr[k]; } ethhdr->type = htons(ETHTYPE_IP); - LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: sending queued IP packet %p.\n",(void *)p)); + LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: sending queued IP packet %p.\n", (void *)p)); /* send the queued IP packet */ netif->linkoutput(netif, p); /* free the queued IP packet */ @@ -405,10 +407,11 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e /* NULL attached buffer*/ arp_table[i].p = NULL; #endif + /* IP addresses should only occur once in the ARP entry, we are done */ return NULL; } - } /* if */ - } /* for */ + } /* if STABLE */ + } /* for all ARP entries */ /* no matching ARP entry was found */ LWIP_ASSERT("update_arp_entry: i == ARP_TABLE_SIZE", i == ARP_TABLE_SIZE); @@ -582,7 +585,7 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) /* ARP reply. We insert or update the ARP table later. */ LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n")); #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) - /* DHCP needs to know about ARP replies to our address */ + /* DHCP wants to know about ARP replies to our wanna-have-address */ if (for_us) dhcp_arp_reply(netif, &hdr->sipaddr); #endif break; @@ -770,9 +773,14 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q) } else if (arp_table[i].state == ETHARP_STATE_STABLE) { LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already stable as entry %u\n", i)); - /* user may wish to queue a packet on a stable entry, so we proceed without ARP requesting */ - /* TODO: even if the ARP entry is stable, we might do an ARP request anyway */ - perform_arp_request = 0; + /* User wishes to queue a packet on a stable entry (or does she want to send + * out the packet immediately, we will not know), so we force an ARP request. + * Upon response we will send out the queued packet in etharp_update(). + * + * Alternatively, we could accept the stable entry, and just send out the packet + * immediately. I chose to implement the former approach. + */ + perform_arp_request = (q?1:0); break; } } @@ -790,12 +798,11 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q) /* i is available, create ARP entry */ arp_table[i].state = ETHARP_STATE_PENDING; ip_addr_set(&arp_table[i].ipaddr, ipaddr); - /* queried address was already in ARP table */ - } else { -#if ARP_QUEUEING - etharp_enqueue(i, q); -#endif } + /* { i is now valid } */ +#if ARP_QUEUEING /* queue packet (even on a stable entry, see above) */ + etharp_enqueue(i, q); +#endif /* ARP request? */ if (perform_arp_request) {