mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-07-16 09:47:31 +00:00
Either first or last packet can be queued. Fixed (err_t)NULL return value in etharp_query().
This commit is contained in:
parent
1204e461c8
commit
042b2a39d9
|
@ -643,8 +643,9 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||||
struct eth_addr *srcaddr;
|
struct eth_addr *srcaddr;
|
||||||
struct etharp_hdr *hdr;
|
struct etharp_hdr *hdr;
|
||||||
struct pbuf *p;
|
struct pbuf *p;
|
||||||
err_t result;
|
err_t result = ERR_OK;
|
||||||
u8_t i;
|
u8_t i;
|
||||||
|
u8_t perform_arp_request = 1;
|
||||||
/* prevent warning if ARP_QUEUEING == 0 */
|
/* prevent warning if ARP_QUEUEING == 0 */
|
||||||
if (q);
|
if (q);
|
||||||
|
|
||||||
|
@ -659,8 +660,10 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||||
}
|
}
|
||||||
else if (arp_table[i].state == ETHARP_STATE_STABLE) {
|
else if (arp_table[i].state == ETHARP_STATE_STABLE) {
|
||||||
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));
|
||||||
/* TODO: user may wish to queue a packet on a stable entry. */
|
/* user may wish to queue a packet on a stable entry, so we proceed without ARP requesting */
|
||||||
return NULL;
|
/* TODO: even if the ARP entry is stable, we might do an ARP request anyway in some cases? */
|
||||||
|
perform_arp_request = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -672,7 +675,7 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||||
/* bail out if no ARP entries are available */
|
/* bail out if no ARP entries are available */
|
||||||
if (i == ARP_TABLE_SIZE) {
|
if (i == ARP_TABLE_SIZE) {
|
||||||
DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available.\n"));
|
DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available.\n"));
|
||||||
return NULL;
|
return ERR_MEM;
|
||||||
}
|
}
|
||||||
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: created ARP table entry %u.\n", i));
|
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: created ARP table entry %u.\n", i));
|
||||||
/* i is available, create ARP entry */
|
/* i is available, create ARP entry */
|
||||||
|
@ -680,56 +683,77 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||||
arp_table[i].ctime = 0;
|
arp_table[i].ctime = 0;
|
||||||
arp_table[i].state = ETHARP_STATE_PENDING;
|
arp_table[i].state = ETHARP_STATE_PENDING;
|
||||||
#if ARP_QUEUEING
|
#if ARP_QUEUEING
|
||||||
arp_table[i].p = NULL;
|
/* free queued packet, as entry is now invalidated */
|
||||||
|
if (arp_table[i].p != NULL) {
|
||||||
|
pbuf_free(arp_table[i].p);
|
||||||
|
arp_table[i].p = NULL;
|
||||||
|
DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("etharp_query: dropped packet on ARP queue. Should not occur.\n"));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if ARP_QUEUEING
|
#if ARP_QUEUEING
|
||||||
/* any pbuf to queue and queue is empty? */
|
/* any pbuf to queue and queue is empty? */
|
||||||
if ((q != NULL) && (arp_table[i].p == NULL)) {
|
if (q != NULL) {
|
||||||
/* copy PBUF_REF referenced payloads to PBUF_RAM */
|
/* yield later packets over older packets? */
|
||||||
q = pbuf_take(q);
|
#if ARP_QUEUE_FIRST == 0
|
||||||
/* remember pbuf to queue, if any */
|
/* earlier queued packet on this entry? */
|
||||||
arp_table[i].p = q;
|
if (arp_table[i].p != NULL) {
|
||||||
/* pbufs are queued, increase the reference count */
|
pbuf_free(arp_table[i].p);
|
||||||
pbuf_ref(q);
|
arp_table[i].p = NULL;
|
||||||
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 | 3, ("etharp_query: dropped packet on ARP queue. Should not occur.\n"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* packet can be queued? */
|
||||||
|
if (arp_table[i].p == NULL) {
|
||||||
|
/* copy PBUF_REF referenced payloads to PBUF_RAM */
|
||||||
|
q = pbuf_take(q);
|
||||||
|
/* remember pbuf to queue, if any */
|
||||||
|
arp_table[i].p = q;
|
||||||
|
/* pbufs are queued, increase the reference count */
|
||||||
|
pbuf_ref(q);
|
||||||
|
DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: queued packet %p on ARP entry %u.\n", (void *)q, i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* allocate a pbuf for the outgoing ARP request packet */
|
/* ARP request? */
|
||||||
p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);
|
if (perform_arp_request)
|
||||||
/* could allocate pbuf? */
|
{
|
||||||
if (p != NULL) {
|
/* allocate a pbuf for the outgoing ARP request packet */
|
||||||
u8_t j;
|
p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);
|
||||||
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: sending ARP request.\n"));
|
/* could allocate pbuf? */
|
||||||
hdr = p->payload;
|
if (p != NULL) {
|
||||||
hdr->opcode = htons(ARP_REQUEST);
|
u8_t j;
|
||||||
for(j = 0; j < netif->hwaddr_len; ++j)
|
DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: sending ARP request.\n"));
|
||||||
{
|
hdr = p->payload;
|
||||||
hdr->dhwaddr.addr[j] = 0x00;
|
hdr->opcode = htons(ARP_REQUEST);
|
||||||
hdr->shwaddr.addr[j] = srcaddr->addr[j];
|
for(j = 0; j < netif->hwaddr_len; ++j)
|
||||||
}
|
{
|
||||||
ip_addr_set(&(hdr->dipaddr), ipaddr);
|
hdr->dhwaddr.addr[j] = 0x00;
|
||||||
ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));
|
hdr->shwaddr.addr[j] = srcaddr->addr[j];
|
||||||
|
}
|
||||||
|
ip_addr_set(&(hdr->dipaddr), ipaddr);
|
||||||
|
ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));
|
||||||
|
|
||||||
hdr->hwtype = htons(HWTYPE_ETHERNET);
|
hdr->hwtype = htons(HWTYPE_ETHERNET);
|
||||||
ARPH_HWLEN_SET(hdr, netif->hwaddr_len);
|
ARPH_HWLEN_SET(hdr, netif->hwaddr_len);
|
||||||
|
|
||||||
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];
|
||||||
|
}
|
||||||
|
hdr->ethhdr.type = htons(ETHTYPE_ARP);
|
||||||
|
/* send ARP query */
|
||||||
|
result = netif->linkoutput(netif, p);
|
||||||
|
/* free ARP query packet */
|
||||||
|
pbuf_free(p);
|
||||||
|
p = NULL;
|
||||||
|
} else {
|
||||||
|
result = ERR_MEM;
|
||||||
|
DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_query: could not allocate pbuf for ARP request.\n"));
|
||||||
}
|
}
|
||||||
hdr->ethhdr.type = htons(ETHTYPE_ARP);
|
|
||||||
/* send ARP query */
|
|
||||||
result = netif->linkoutput(netif, p);
|
|
||||||
/* free ARP query packet */
|
|
||||||
pbuf_free(p);
|
|
||||||
p = NULL;
|
|
||||||
} else {
|
|
||||||
result = ERR_MEM;
|
|
||||||
DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_query: could not allocate pbuf for ARP request.\n"));
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user