/[lwip]/lwip/src/netif/etharp.c
ViewVC logotype

Diff of /lwip/src/netif/etharp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.47.2.5 by jani, Tue Oct 28 11:44:44 2003 UTC revision 1.47.2.6 by likewise, Fri Nov 14 19:23:08 2003 UTC
# Line 113  struct etharp_entry { Line 113  struct etharp_entry {
113    struct eth_addr ethaddr;    struct eth_addr ethaddr;
114    enum etharp_state state;    enum etharp_state state;
115  #if ARP_QUEUEING  #if ARP_QUEUEING
116      /**
117       * Pointer to queue of pending outgoing packets on this ARP entry.
118       * Must be at most a single packet for now. */
119    struct pbuf *p;    struct pbuf *p;
120  #endif  #endif
121    u8_t ctime;    u8_t ctime;
# Line 155  etharp_tmr(void) Line 158  etharp_tmr(void)
158    /* remove expired entries from the ARP table */    /* remove expired entries from the ARP table */
159    for (i = 0; i < ARP_TABLE_SIZE; ++i) {    for (i = 0; i < ARP_TABLE_SIZE; ++i) {
160      arp_table[i].ctime++;      arp_table[i].ctime++;
161        /* a resolved/stable entry? */
162      if ((arp_table[i].state == ETHARP_STATE_STABLE) &&      if ((arp_table[i].state == ETHARP_STATE_STABLE) &&
163             /* entry has become old? */
164          (arp_table[i].ctime >= ARP_MAXAGE)) {          (arp_table[i].ctime >= ARP_MAXAGE)) {
165        LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %u.\n", i));        LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %u.\n", i));
166        goto empty;        goto empty;
167        /* an unresolved/pending entry? */
168      } else if ((arp_table[i].state == ETHARP_STATE_PENDING) &&      } else if ((arp_table[i].state == ETHARP_STATE_PENDING) &&
169             /* entry unresolved/pending for too long? */
170          (arp_table[i].ctime >= ARP_MAXPENDING)) {          (arp_table[i].ctime >= ARP_MAXPENDING)) {
171        LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u.\n", i));        LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u.\n", i));
172    empty:          empty:
173          /* empty old entry */      
174        arp_table[i].state = ETHARP_STATE_EMPTY;        arp_table[i].state = ETHARP_STATE_EMPTY;
175  #if ARP_QUEUEING  #if ARP_QUEUEING
176          /* and empty packet queue */
177        if (arp_table[i].p != NULL) {        if (arp_table[i].p != NULL) {
178          /* remove any queued packet */          /* remove any queued packet */
179          LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: freeing entry %u, packet queue %p.\n", i, (void *)(arp_table[i].p)));          LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: freeing entry %u, packet queue %p.\n", i, (void *)(arp_table[i].p)));
# Line 197  find_arp_entry(void) Line 206  find_arp_entry(void)
206    }    }
207    
208    /* If no unused entry is found, we try to find the oldest entry and    /* If no unused entry is found, we try to find the oldest entry and
209       throw it away. If all entries are new and have 0 ctime drop one  */       throw it away. If all entries are new and ctime drop one */
210    if (i == ARP_TABLE_SIZE) {    if (i == ARP_TABLE_SIZE) {
211      maxtime = 0;      maxtime = 0;
212      j = ARP_TABLE_SIZE;      j = ARP_TABLE_SIZE;
213      for (i = 0; i < ARP_TABLE_SIZE; ++i) {      for (i = 0; i < ARP_TABLE_SIZE; ++i) {
214        /* remember entry with oldest stable entry in j*/        /* remember entry with oldest stable entry in j */
215        if ((arp_table[i].state == ETHARP_STATE_STABLE) &&        if ((arp_table[i].state == ETHARP_STATE_STABLE) &&
216  #if ARP_QUEUEING /* do not want to re-use an entry with queued packets */  #if ARP_QUEUEING /* do not want to re-use an entry with queued packets */
217        (arp_table[i].p == NULL) &&        (arp_table[i].p == NULL) &&
# Line 210  find_arp_entry(void) Line 219  find_arp_entry(void)
219        (arp_table[i].ctime >= maxtime)) {        (arp_table[i].ctime >= maxtime)) {
220          maxtime = arp_table[i].ctime;          maxtime = arp_table[i].ctime;
221          j = i;          j = i;
222            /* { j = oldest stable entry } */
223        }        }
224      }      }
225      if (j != ARP_TABLE_SIZE) {      if (j != ARP_TABLE_SIZE) {
# Line 512  etharp_arp_input(struct netif *netif, st Line 522  etharp_arp_input(struct netif *netif, st
522   * This ARP request is returned as a pbuf, which should be sent by   * This ARP request is returned as a pbuf, which should be sent by
523   * the caller.   * the caller.
524   *   *
  * If ARP failed to allocate resources, NULL is returned.  
  *  
525   * A returned non-NULL packet should be sent by the caller.   * A returned non-NULL packet should be sent by the caller.
526   *   *
527     * If ARP failed to allocate resources, NULL is returned.
528     *
529   * @param netif The lwIP network interface which the IP packet will be sent on.   * @param netif The lwIP network interface which the IP packet will be sent on.
530   * @param ipaddr The IP address of the packet destination.   * @param ipaddr The IP address of the packet destination.
531   * @param pbuf The pbuf(s) containing the IP packet to be sent.   * @param pbuf The pbuf(s) containing the IP packet to be sent.
# Line 530  etharp_output(struct netif *netif, struc Line 540  etharp_output(struct netif *netif, struc
540    struct eth_hdr *ethhdr;    struct eth_hdr *ethhdr;
541    u8_t i;    u8_t i;
542    
543    /* Make room for Ethernet header. */    /* make room for Ethernet header */
544    if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {    if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
545      /* The pbuf_header() call shouldn't fail, and we'll just bail      /* The pbuf_header() call shouldn't fail, and we'll just bail
546      out if it does.. */      out if it does.. */
# Line 539  etharp_output(struct netif *netif, struc Line 549  etharp_output(struct netif *netif, struc
549      return NULL;      return NULL;
550    }    }
551    
   /* obtain source Ethernet address of the given interface */  
   srcaddr = (struct eth_addr *)netif->hwaddr;  
   
552    /* assume unresolved Ethernet address */    /* assume unresolved Ethernet address */
553    dest = NULL;    dest = NULL;
554    /* Construct Ethernet header. Start with looking up deciding which    /* Construct Ethernet header. Start with looking up deciding which
# Line 569  etharp_output(struct netif *netif, struc Line 576  etharp_output(struct netif *netif, struc
576    }    }
577    /* destination IP address is an IP unicast address */    /* destination IP address is an IP unicast address */
578    else {    else {
579      /* destination IP network address not on local network? */      /* destination IP network address not on local network?
580      /* this occurs if the packet is routed to the default gateway on this interface */       * IP layer wants us to forward to the default gateway */
581      if (!ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {      if (!ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
582        /* gateway available? */        /* interface has default gateway? */
583        if (netif->gw.addr != 0)        if (netif->gw.addr != 0)
584        {        {
585          /* use the gateway IP address */          /* route to default gateway IP address */
586          ipaddr = &(netif->gw);          ipaddr = &(netif->gw);
587        }        }
588        /* no gateway available? */        /* no gateway available? */
589        else        else
590        {        {
591          /* IP destination address outside local network, but no gateway available */          /* IP destination address outside local network, but no gateway available */
592            /* { packet is discarded } */
593          return NULL;          return NULL;
594        }        }
595      }      }
# Line 600  etharp_output(struct netif *netif, struc Line 608  etharp_output(struct netif *netif, struc
608        /* ARP query for the IP address, submit this IP packet for queueing */        /* ARP query for the IP address, submit this IP packet for queueing */
609        /* TODO: How do we handle netif->ipaddr == ipaddr? */        /* TODO: How do we handle netif->ipaddr == ipaddr? */
610        etharp_query(netif, ipaddr, q);        etharp_query(netif, ipaddr, q);
611          /* { packet was queued (ERR_OK), or discarded } */
612        /* return nothing */        /* return nothing */
613        return NULL;        return NULL;
614      }      }
# Line 612  etharp_output(struct netif *netif, struc Line 621  etharp_output(struct netif *netif, struc
621    
622    /* destination Ethernet address known */    /* destination Ethernet address known */
623    if (dest != NULL) {    if (dest != NULL) {
624      /* A valid IP->MAC address mapping was found, so we construct the      /* obtain source Ethernet address of the given interface */
625      Ethernet header for the outgoing packet. */      srcaddr = (struct eth_addr *)netif->hwaddr;
626    
627        /* A valid IP->MAC address mapping was found, fill in the
628         * Ethernet header for the outgoing packet */
629      ethhdr = q->payload;      ethhdr = q->payload;
630    
631      for(i = 0; i < netif->hwaddr_len; i++) {      for(i = 0; i < netif->hwaddr_len; i++) {
# Line 654  err_t etharp_query(struct netif *netif, Line 666  err_t etharp_query(struct netif *netif,
666  {  {
667    struct eth_addr *srcaddr;    struct eth_addr *srcaddr;
668    struct etharp_hdr *hdr;    struct etharp_hdr *hdr;
   struct pbuf *p;  
669    err_t result = ERR_OK;    err_t result = ERR_OK;
670    u8_t i;    u8_t i;
671    u8_t perform_arp_request = 1;    u8_t perform_arp_request = 1;
# Line 683  err_t etharp_query(struct netif *netif, Line 694  err_t etharp_query(struct netif *netif,
694    /* queried address not yet in ARP table? */    /* queried address not yet in ARP table? */
695    if (i == ARP_TABLE_SIZE) {    if (i == ARP_TABLE_SIZE) {
696      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: IP address not found in ARP table\n"));      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: IP address not found in ARP table\n"));
697      /* find an available entry */      /* find an available (unused or old) entry */
698      i = find_arp_entry();      i = find_arp_entry();
699      /* bail out if no ARP entries are available */      /* bail out if no ARP entries are available */
700      if (i == ARP_TABLE_SIZE) {      if (i == ARP_TABLE_SIZE) {
701        LWIP_DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available.\n"));        LWIP_DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available. Should seldom occur.\n"));
702        return ERR_MEM;        return ERR_MEM;
703      }      }
704      /* we will now recycle entry i */      /* we will now recycle entry i */
# Line 696  err_t etharp_query(struct netif *netif, Line 707  err_t etharp_query(struct netif *netif,
707      ip_addr_set(&arp_table[i].ipaddr, ipaddr);      ip_addr_set(&arp_table[i].ipaddr, ipaddr);
708      arp_table[i].ctime = 0;      arp_table[i].ctime = 0;
709      arp_table[i].state = ETHARP_STATE_PENDING;      arp_table[i].state = ETHARP_STATE_PENDING;
710  #if ARP_QUEUEING  #if ARP_QUEUEING /* deal with queue of recycled entry */
711      /* free queued packet, as entry is now invalidated */      /* free queued packet, as entry is now invalidated and recycled */
712      if (arp_table[i].p != NULL) {      if (arp_table[i].p != NULL) {
713        pbuf_free(arp_table[i].p);        pbuf_free(arp_table[i].p);
714          LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3,
715            ("etharp_query: dropped packet %p from recycled ARP entry queue. Should not occur.\n", (void *)arp_table[i].p));
716        arp_table[i].p = NULL;        arp_table[i].p = NULL;
       LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("etharp_query: dropped packet on ARP queue. Should not occur.\n"));  
717      }      }
718  #endif  #endif
719    }    }
# Line 713  err_t etharp_query(struct netif *netif, Line 725  err_t etharp_query(struct netif *netif,
725      /* earlier queued packet on this entry? */      /* earlier queued packet on this entry? */
726      if (arp_table[i].p != NULL) {      if (arp_table[i].p != NULL) {
727        pbuf_free(arp_table[i].p);        pbuf_free(arp_table[i].p);
728          LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("etharp_query: dropped packet %p on ARP queue. Should not occur.\n", (void *)arp_table[i].p));
729        arp_table[i].p = NULL;        arp_table[i].p = NULL;
       LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("etharp_query: dropped packet on ARP queue. Should not occur.\n"));  
730        /* fall-through into next if */        /* fall-through into next if */
731      }      }
732  #endif  #endif
# Line 733  err_t etharp_query(struct netif *netif, Line 745  err_t etharp_query(struct netif *netif,
745    /* ARP request? */    /* ARP request? */
746    if (perform_arp_request)    if (perform_arp_request)
747    {    {
748        struct pbuf *p;
749      /* allocate a pbuf for the outgoing ARP request packet */      /* allocate a pbuf for the outgoing ARP request packet */
750      p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);      p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);
751      /* could allocate pbuf? */      /* could allocate pbuf? */

Legend:
Removed from v.1.47.2.5  
changed lines
  Added in v.1.47.2.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26