Either first or last packet can be queued. Fixed (err_t)NULL return value in etharp_query().

This commit is contained in:
likewise 2003-04-22 15:08:47 +00:00
parent 1204e461c8
commit 042b2a39d9

View File

@ -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;
} }