/[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.39.2.4 by likewise, Wed Jun 4 10:18:38 2003 UTC revision 1.39.2.5 by likewise, Wed Jun 4 10:30:01 2003 UTC
# Line 151  etharp_tmr(void) Line 151  etharp_tmr(void)
151        
152    DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));    DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
153    /* remove expired entries from the ARP table */    /* remove expired entries from the ARP table */
154    for(i = 0; i < ARP_TABLE_SIZE; ++i) {    for (i = 0; i < ARP_TABLE_SIZE; ++i) {
155      arp_table[i].ctime++;              arp_table[i].ctime++;
156      if ((arp_table[i].state == ETHARP_STATE_STABLE) &&      if ((arp_table[i].state == ETHARP_STATE_STABLE) &&      
157         (arp_table[i].ctime >= ARP_MAXAGE)) {          (arp_table[i].ctime >= ARP_MAXAGE)) {
158        DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %u.\n", i));        DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %u.\n", i));
159        arp_table[i].state = ETHARP_STATE_EMPTY;        arp_table[i].state = ETHARP_STATE_EMPTY;
160  #if ARP_QUEUEING  #if ARP_QUEUEING
161        /* remove any queued packet */        /* remove any queued packet */
162        pbuf_free(arp_table[i].p);        pbuf_free(arp_table[i].p);      
163        arp_table[i].p = NULL;        arp_table[i].p = NULL;
164  #endif  #endif
165      } else if ((arp_table[i].state == ETHARP_STATE_PENDING) &&      } else if ((arp_table[i].state == ETHARP_STATE_PENDING) &&
# Line 168  etharp_tmr(void) Line 168  etharp_tmr(void)
168  #if ARP_QUEUEING  #if ARP_QUEUEING
169        DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u - dequeueing %p.\n", i, (void *)(arp_table[i].p)));        DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u - dequeueing %p.\n", i, (void *)(arp_table[i].p)));
170        /* remove any queued packet */        /* remove any queued packet */
171        pbuf_free(arp_table[i].p);        pbuf_free(arp_table[i].p);      
172        arp_table[i].p = NULL;        arp_table[i].p = NULL;
173  #else  #else
174        DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u.\n", i));        DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u.\n", i));
# Line 190  find_arp_entry(void) Line 190  find_arp_entry(void)
190    u8_t i, j, maxtime;    u8_t i, j, maxtime;
191        
192    /* Try to find an unused entry in the ARP table. */    /* Try to find an unused entry in the ARP table. */
193    for(i = 0; i < ARP_TABLE_SIZE; ++i) {    for (i = 0; i < ARP_TABLE_SIZE; ++i) {
194      if (arp_table[i].state == ETHARP_STATE_EMPTY) {      if (arp_table[i].state == ETHARP_STATE_EMPTY) {
195        DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found empty entry %u\n", i));        DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found empty entry %u\n", i));
196        break;        break;
# Line 202  find_arp_entry(void) Line 202  find_arp_entry(void)
202    if (i == ARP_TABLE_SIZE) {    if (i == ARP_TABLE_SIZE) {
203      maxtime = 0;      maxtime = 0;
204      j = ARP_TABLE_SIZE;      j = ARP_TABLE_SIZE;
205      for(i = 0; i < ARP_TABLE_SIZE; ++i) {      for (i = 0; i < ARP_TABLE_SIZE; ++i) {
206        /* remember entry with oldest stable entry in j*/        /* remember entry with oldest stable entry in j*/
207        if ((arp_table[i].state == ETHARP_STATE_STABLE) &&        if ((arp_table[i].state == ETHARP_STATE_STABLE) &&
208  #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 */
# Line 214  find_arp_entry(void) Line 214  find_arp_entry(void)
214        }        }
215      }      }
216      if (j != ARP_TABLE_SIZE) {      if (j != ARP_TABLE_SIZE) {
217      DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found oldest stable entry %u\n", j));        DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found oldest stable entry %u\n", j));
218      } else {      } else {
219        DEBUGF(ETHARP_DEBUG, ("find_arp_entry: no replacable entry could be found\n"));        DEBUGF(ETHARP_DEBUG, ("find_arp_entry: no replacable entry could be found\n"));
220      }      }
# Line 242  static struct pbuf * Line 242  static struct pbuf *
242  update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags)  update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags)
243  {  {
244    u8_t i, k;    u8_t i, k;
 #if ARP_QUEUEING  
   struct pbuf *p;  
   struct eth_hdr *ethhdr;  
 #endif  
245    DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("update_arp_entry()\n"));    DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("update_arp_entry()\n"));
246      LWIP_ASSERT("netif->hwaddr_len != 0", netif->hwaddr_len != 0);
247    DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: %u.%u.%u.%u - %02x:%02x:%02x:%02x:%02x:%02x\n", ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr),    DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: %u.%u.%u.%u - %02x:%02x:%02x:%02x:%02x:%02x\n", ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr),
248    ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));    ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
249    /* do not update for 0.0.0.0 addresses */    /* do not update for 0.0.0.0 addresses */
# Line 257  update_arp_entry(struct netif *netif, st Line 254  update_arp_entry(struct netif *netif, st
254    /* Walk through the ARP mapping table and try to find an entry to    /* Walk through the ARP mapping table and try to find an entry to
255    update. If none is found, the IP -> MAC address mapping is    update. If none is found, the IP -> MAC address mapping is
256    inserted in the ARP table. */    inserted in the ARP table. */
257    for(i = 0; i < ARP_TABLE_SIZE; ++i) {    for (i = 0; i < ARP_TABLE_SIZE; ++i) {
258      /* Check if the source IP address of the incoming packet matches      /* Check if the source IP address of the incoming packet matches
259      the IP address in this ARP table entry. */      the IP address in this ARP table entry. */
260      if (ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {      if (ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
# Line 270  update_arp_entry(struct netif *netif, st Line 267  update_arp_entry(struct netif *netif, st
267        }        }
268        /* stable entry? (possible just marked to become stable) */        /* stable entry? (possible just marked to become stable) */
269        if (arp_table[i].state == ETHARP_STATE_STABLE) {        if (arp_table[i].state == ETHARP_STATE_STABLE) {
270    #if ARP_QUEUEING
271            struct pbuf *p;
272            struct eth_hdr *ethhdr;
273    #endif
274          DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: updating stable entry %u\n", i));          DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: updating stable entry %u\n", i));
275          /* An old entry found, update this and return. */          /* An old entry found, update this and return. */
276          for(k = 0; k < netif->hwaddr_len; ++k) {          for (k = 0; k < netif->hwaddr_len; ++k) {
277            arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];            arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
278          }          }
279          /* reset time stamp */          /* reset time stamp */
280          arp_table[i].ctime = 0;          arp_table[i].ctime = 0;
281  #if ARP_QUEUEING  #if ARP_QUEUEING
282            p = arp_table[i].p;
283          /* queued packet present? */          /* queued packet present? */
284          if ((p = arp_table[i].p) != NULL) {          if (p != NULL) {
285            /* Null out attached buffer immediately */            /* NULL attached buffer immediately */
286            arp_table[i].p = NULL;            arp_table[i].p = NULL;
287            /* fill-in Ethernet header */            /* fill-in Ethernet header */
288            ethhdr = p->payload;            ethhdr = p->payload;
289            for(k = 0; k < netif->hwaddr_len; ++k) {            for (k = 0; k < netif->hwaddr_len; ++k) {
290              ethhdr->dest.addr[k] = ethaddr->addr[k];              ethhdr->dest.addr[k] = ethaddr->addr[k];
291            }            }
292            ethhdr->type = htons(ETHTYPE_IP);                                  ethhdr->type = htons(ETHTYPE_IP);                      
# Line 328  update_arp_entry(struct netif *netif, st Line 330  update_arp_entry(struct netif *netif, st
330      /* set IP address */        /* set IP address */  
331      ip_addr_set(&arp_table[i].ipaddr, ipaddr);      ip_addr_set(&arp_table[i].ipaddr, ipaddr);
332      /* set Ethernet hardware address */        /* set Ethernet hardware address */  
333      for(k = 0; k < netif->hwaddr_len; ++k) {      for (k = 0; k < netif->hwaddr_len; ++k) {
334        arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];        arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
335      }      }
336      /* reset time-stamp */        /* reset time-stamp */  
# Line 419  etharp_arp_input(struct netif *netif, st Line 421  etharp_arp_input(struct netif *netif, st
421      reply. In any case, we time-stamp any existing ARP entry,      reply. In any case, we time-stamp any existing ARP entry,
422      and possiby send out an IP packet that was queued on it. */      and possiby send out an IP packet that was queued on it. */
423    
424      DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));      DEBUGF (ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
425      /* we are not configured? */      /* we are not configured? */
426      if (netif->ip_addr.addr == 0) {      if (netif->ip_addr.addr == 0) {
427        DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));        DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
# Line 646  err_t etharp_query(struct netif *netif, Line 648  err_t etharp_query(struct netif *netif,
648    struct pbuf *p;    struct pbuf *p;
649    err_t result = ERR_OK;    err_t result = ERR_OK;
650    u8_t i;    u8_t i;
651    /* prevent warning if ARP_QUEUEING == 0 */    u8_t perform_arp_request = 1;
652    if (q);    /* prevent 'unused argument' warning if ARP_QUEUEING == 0 */
653      (void)q;
654    srcaddr = (struct eth_addr *)netif->hwaddr;    srcaddr = (struct eth_addr *)netif->hwaddr;
655    /* bail out if this IP address is pending */    /* bail out if this IP address is pending */
656    for(i = 0; i < ARP_TABLE_SIZE; ++i) {    for (i = 0; i < ARP_TABLE_SIZE; ++i) {
657      if (ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {      if (ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
658        if (arp_table[i].state == ETHARP_STATE_PENDING) {        if (arp_table[i].state == ETHARP_STATE_PENDING) {
659          DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already pending as entry %u\n", i));          DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already pending as entry %u\n", i));
660          /* break out of for-loop, user may wish to queue a packet on a stable entry */          /* break out of for-loop, user may wish to queue a packet on a stable entry */
661            /* TODO: we will issue a new ARP request, which should not occur too often */
662            /* we might want to run a faster timer on ARP to limit this */
663          break;          break;
664        }        }
665        else if (arp_table[i].state == ETHARP_STATE_STABLE) {        else if (arp_table[i].state == ETHARP_STATE_STABLE) {
666          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));
667          /* 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 */
668          return NULL;          /* TODO: even if the ARP entry is stable, we might do an ARP request anyway */
669            perform_arp_request = 0;
670            break;
671        }        }
672      }      }
673    }    }
# Line 673  err_t etharp_query(struct netif *netif, Line 679  err_t etharp_query(struct netif *netif,
679      /* bail out if no ARP entries are available */      /* bail out if no ARP entries are available */
680      if (i == ARP_TABLE_SIZE) {      if (i == ARP_TABLE_SIZE) {
681        DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available.\n"));        DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available.\n"));
682        return NULL;        return ERR_MEM;
683      }      }
684        /* we will now recycle entry i */
685      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));
686      /* i is available, create ARP entry */      /* i is available, create ARP entry */
687      ip_addr_set(&arp_table[i].ipaddr, ipaddr);      ip_addr_set(&arp_table[i].ipaddr, ipaddr);
688      arp_table[i].ctime = 0;      arp_table[i].ctime = 0;
689      arp_table[i].state = ETHARP_STATE_PENDING;      arp_table[i].state = ETHARP_STATE_PENDING;
690  #if ARP_QUEUEING  #if ARP_QUEUEING
691      arp_table[i].p = NULL;      /* free queued packet, as entry is now invalidated */
692        if (arp_table[i].p != NULL) {
693          pbuf_free(arp_table[i].p);
694          arp_table[i].p = NULL;
695          DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("etharp_query: dropped packet on ARP queue. Should not occur.\n"));
696        }
697  #endif  #endif
698    }    }
699  #if ARP_QUEUEING  #if ARP_QUEUEING
700    /* any pbuf to queue and queue is empty? */    /* any pbuf to queue and queue is empty? */
701    if ((q != NULL) && (arp_table[i].p == NULL)) {    if (q != NULL) {
702      /* copy PBUF_REF referenced payloads to PBUF_RAM */  /* yield later packets over older packets? */
703      q = pbuf_take(q);  #if ARP_QUEUE_FIRST == 0
704      /* remember pbuf to queue, if any */      /* earlier queued packet on this entry? */
705      arp_table[i].p = q;      if (arp_table[i].p != NULL) {
706      /* pbufs are queued, increase the reference count */        pbuf_free(arp_table[i].p);
707      pbuf_ref(q);        arp_table[i].p = NULL;
708      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"));
709    }        /* fall-through into next if */
710  #endif      }
711    /* allocate a pbuf for the outgoing ARP request packet */  #endif
712    p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);      /* packet can be queued? */
713    /* could allocate pbuf? */      if (arp_table[i].p == NULL) {
714    if (p != NULL) {        /* copy PBUF_REF referenced payloads into PBUF_RAM */
715      u8_t j;        q = pbuf_take(q);
716      DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: sending ARP request.\n"));        /* remember pbuf to queue, if any */
717      hdr = p->payload;        arp_table[i].p = q;
718      hdr->opcode = htons(ARP_REQUEST);        /* pbufs are queued, increase the reference count */
719      for(j = 0; j < netif->hwaddr_len; ++j)        pbuf_ref(q);
720      {        DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: queued packet %p on ARP entry %u.\n", (void *)q, i));
       hdr->dhwaddr.addr[j] = 0x00;  
       hdr->shwaddr.addr[j] = srcaddr->addr[j];  
721      }      }
722      ip_addr_set(&(hdr->dipaddr), ipaddr);    }
723      ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));  #endif
724      /* ARP request? */
725      if (perform_arp_request)
726      {
727        /* allocate a pbuf for the outgoing ARP request packet */
728        p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);
729        /* could allocate pbuf? */
730        if (p != NULL) {
731          u8_t j;
732          DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: sending ARP request.\n"));
733          hdr = p->payload;
734          hdr->opcode = htons(ARP_REQUEST);
735          for(j = 0; j < netif->hwaddr_len; ++j)
736          {
737            hdr->dhwaddr.addr[j] = 0x00;
738            hdr->shwaddr.addr[j] = srcaddr->addr[j];
739          }
740          ip_addr_set(&(hdr->dipaddr), ipaddr);
741          ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));
742    
743      hdr->hwtype = htons(HWTYPE_ETHERNET);        hdr->hwtype = htons(HWTYPE_ETHERNET);
744      ARPH_HWLEN_SET(hdr, netif->hwaddr_len);        ARPH_HWLEN_SET(hdr, netif->hwaddr_len);
745    
746      hdr->proto = htons(ETHTYPE_IP);        hdr->proto = htons(ETHTYPE_IP);
747      ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));        ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
748      for(j = 0; j < netif->hwaddr_len; ++j)        for(j = 0; j < netif->hwaddr_len; ++j)
749      {        {
750        hdr->ethhdr.dest.addr[j] = 0xff;          hdr->ethhdr.dest.addr[j] = 0xff;
751        hdr->ethhdr.src.addr[j] = srcaddr->addr[j];          hdr->ethhdr.src.addr[j] = srcaddr->addr[j];
752          }
753          hdr->ethhdr.type = htons(ETHTYPE_ARP);      
754          /* send ARP query */
755          result = netif->linkoutput(netif, p);
756          /* free ARP query packet */
757          pbuf_free(p);
758          p = NULL;
759        } else {
760          result = ERR_MEM;
761          DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_query: could not allocate pbuf for ARP request.\n"));
762      }      }
     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"));  
763    }    }
764    return result;    return result;
765  }  }

Legend:
Removed from v.1.39.2.4  
changed lines
  Added in v.1.39.2.5

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