/[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.87 by likewise, Tue Nov 30 17:22:18 2004 UTC revision 1.88 by likewise, Mon Dec 27 14:44:19 2004 UTC
# Line 390  update_arp_entry(struct netif *netif, st Line 390  update_arp_entry(struct netif *netif, st
390  /* this is where we will send out queued packets! */  /* this is where we will send out queued packets! */
391  #if ARP_QUEUEING  #if ARP_QUEUEING
392    while (arp_table[i].p != NULL) {    while (arp_table[i].p != NULL) {
393      /* get the first packet on the queue (if any) */      /* get the first packet on the queue */
394      struct pbuf *p = arp_table[i].p;      struct pbuf *p = arp_table[i].p;
395      /* Ethernet header */      /* Ethernet header */
396      struct eth_hdr *ethhdr = p->payload;;      struct eth_hdr *ethhdr = p->payload;
397      /* remember (and reference) remainder of queue */      /* remember (and reference) remainder of queue */
398      /* note: this will also terminate the p pbuf chain */      /* note: this will also terminate the p pbuf chain */
399      arp_table[i].p = pbuf_dequeue(p);      arp_table[i].p = pbuf_dequeue(p);
# Line 571  etharp_arp_input(struct netif *netif, st Line 571  etharp_arp_input(struct netif *netif, st
571  /**  /**
572   * Resolve and fill-in Ethernet address header for outgoing packet.   * Resolve and fill-in Ethernet address header for outgoing packet.
573   *   *
574   * If ARP has the Ethernet address in cache, the given packet is   * For IP multicast and broadcast, corresponding Ethernet addresses
575   * returned, ready to be sent.   * are selected and the packet is transmitted on the link.
576   *   *
577   * If ARP does not have the Ethernet address in cache the packet is   * For unicast addresses, the packet is submitted to etharp_query(). In
578   * queued (if enabled and space available) and a ARP request is sent.   * case the IP address is outside the local network, the IP address of
579   * This ARP request is returned as a pbuf, which should be sent by   * the gateway is used.
  * the caller.  
  *  
  * A returned non-NULL packet should be sent by the caller.  
  *  
  * If ARP failed to allocate resources, NULL is returned.  
580   *   *
581   * @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.
582   * @param ipaddr The IP address of the packet destination.   * @param ipaddr The IP address of the packet destination.
583   * @param pbuf The pbuf(s) containing the IP packet to be sent.   * @param pbuf The pbuf(s) containing the IP packet to be sent.
584   *   *
  * @return If non-NULL, a packet ready to be sent by caller.  
  *  
585   * @return   * @return
586   * - ERR_BUF Could not make room for Ethernet header.   * - ERR_RTE No route to destination (no gateway to external networks),
587   * - ERR_MEM Hardware address unknown, and no more ARP entries available   * or the return type of either etharp_query() or netif->linkoutput().
  *   to query for address or queue the packet.  
  * - ERR_RTE No route to destination (no gateway to external networks).  
588   */   */
589  err_t  err_t
590  etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)  etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
591  {  {
592    struct eth_addr *dest, *srcaddr, mcastaddr;    struct eth_addr *dest, *srcaddr, mcastaddr;
593    struct eth_hdr *ethhdr;    struct eth_hdr *ethhdr;
594    err_t result = ERR_OK;    u8_t i;
595    
596    /* make room for Ethernet header - should not fail */    /* make room for Ethernet header - should not fail */
597    if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {    if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
# Line 615  etharp_output(struct netif *netif, struc Line 606  etharp_output(struct netif *netif, struc
606    /* Determine on destination hardware address. Broadcasts and multicasts    /* Determine on destination hardware address. Broadcasts and multicasts
607     * are special, other IP addresses are looked up in the ARP table. */     * are special, other IP addresses are looked up in the ARP table. */
608    
609    /* destination IP address is an IP broadcast address? */    /* broadcast destination IP address? */
610    if (ip_addr_isany(ipaddr) || ip_addr_isbroadcast(ipaddr, netif)) {    if (ip_addr_isbroadcast(ipaddr, netif)) {
611      /* broadcast on Ethernet also */      /* broadcast on Ethernet also */
612      dest = (struct eth_addr *)&ethbroadcast;      dest = (struct eth_addr *)&ethbroadcast;
613    /* destination IP address is an IP multicast address? */    /* multicast destination IP address? */
614    } else if (ip_addr_ismulticast(ipaddr)) {    } else if (ip_addr_ismulticast(ipaddr)) {
615      /* Hash IP multicast address to MAC address. */      /* Hash IP multicast address to MAC address.*/
616      mcastaddr.addr[0] = 0x01;      mcastaddr.addr[0] = 0x01;
617      mcastaddr.addr[1] = 0x00;      mcastaddr.addr[1] = 0x00;
618      mcastaddr.addr[2] = 0x5e;      mcastaddr.addr[2] = 0x5e;
# Line 630  etharp_output(struct netif *netif, struc Line 621  etharp_output(struct netif *netif, struc
621      mcastaddr.addr[5] = ip4_addr4(ipaddr);      mcastaddr.addr[5] = ip4_addr4(ipaddr);
622      /* destination Ethernet address is multicast */      /* destination Ethernet address is multicast */
623      dest = &mcastaddr;      dest = &mcastaddr;
624    /* destination IP address is an IP unicast address */    /* unicast destination IP address? */
625    } else {    } else {
626      /* outside local network? */      /* outside local network? */
627      if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {      if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
# Line 640  etharp_output(struct netif *netif, struc Line 631  etharp_output(struct netif *netif, struc
631          ipaddr = &(netif->gw);          ipaddr = &(netif->gw);
632        /* no default gateway available */        /* no default gateway available */
633        } else {        } else {
634          /* no route to destination error */          /* no route to destination error (default gateway missing) */
635          return ERR_RTE;          return ERR_RTE;
636        }        }
637      }      }
# Line 648  etharp_output(struct netif *netif, struc Line 639  etharp_output(struct netif *netif, struc
639      return etharp_query(netif, ipaddr, q);      return etharp_query(netif, ipaddr, q);
640    }    }
641    
642    /* destination Ethernet address known */    /* continuation for multicast/broadcast destinations */
643    if (dest != NULL) {    /* obtain source Ethernet address of the given interface */
644      u8_t i;    srcaddr = (struct eth_addr *)netif->hwaddr;
645      /* obtain source Ethernet address of the given interface */    ethhdr = q->payload;
646      srcaddr = (struct eth_addr *)netif->hwaddr;    for (i = 0; i < netif->hwaddr_len; i++) {
647      /* A valid IP->MAC address mapping was found, fill in the      ethhdr->dest.addr[i] = dest->addr[i];
648       * Ethernet header for the outgoing packet */      ethhdr->src.addr[i] = srcaddr->addr[i];
649      ethhdr = q->payload;    }
650      for (i = 0; i < netif->hwaddr_len; i++) {    ethhdr->type = htons(ETHTYPE_IP);
651        ethhdr->dest.addr[i] = dest->addr[i];    /* send packet directly on the link */
652        ethhdr->src.addr[i] = srcaddr->addr[i];    return netif->linkoutput(netif, q);
     }  
     ethhdr->type = htons(ETHTYPE_IP);  
     /* send packet */  
     result = netif->linkoutput(netif, q);  
   }  
   return result;  
653  }  }
654    
655  /**  /**
# Line 707  err_t etharp_query(struct netif *netif, Line 692  err_t etharp_query(struct netif *netif,
692    u8_t k; /* Ethernet address octet index */    u8_t k; /* Ethernet address octet index */
693    
694    /* non-unicast address? */    /* non-unicast address? */
695    if (ip_addr_isany(ipaddr) ||    if (ip_addr_isbroadcast(ipaddr, netif) ||
696        ip_addr_isbroadcast(ipaddr, netif) ||        ip_addr_ismulticast(ipaddr) ||
697        ip_addr_ismulticast(ipaddr)) {        ip_addr_isany(ipaddr)) {
698      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n"));      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n"));
699      return ERR_ARG;      return ERR_ARG;
700    }    }
# Line 718  err_t etharp_query(struct netif *netif, Line 703  err_t etharp_query(struct netif *netif,
703    i = find_entry(ipaddr, ETHARP_TRY_HARD);    i = find_entry(ipaddr, ETHARP_TRY_HARD);
704    
705    /* could not find or create entry? */    /* could not find or create entry? */
706    if (i < 0) return (err_t)i;    if (i < 0)
707      {
708        LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: could not create ARP entry\n"));
709        if (q) LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: packet dropped\n"));
710        return (err_t)i;
711      }
712    
713    /* mark a fresh entry as pending (we just sent a request) */    /* mark a fresh entry as pending (we just sent a request) */
714    if (arp_table[i].state == ETHARP_STATE_EMPTY) {    if (arp_table[i].state == ETHARP_STATE_EMPTY) {
# Line 730  err_t etharp_query(struct netif *netif, Line 720  err_t etharp_query(struct netif *netif,
720    ((arp_table[i].state == ETHARP_STATE_PENDING) ||    ((arp_table[i].state == ETHARP_STATE_PENDING) ||
721     (arp_table[i].state == ETHARP_STATE_STABLE)));     (arp_table[i].state == ETHARP_STATE_STABLE)));
722    
723    /* do we have a pending entry? */    /* do we have a pending entry? or an implicit query request? */
724    if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) {    if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) {
725      /* try to resolve it; send out ARP request */      /* try to resolve it; send out ARP request */
726      result = etharp_request(netif, ipaddr);      result = etharp_request(netif, ipaddr);
# Line 765  err_t etharp_query(struct netif *netif, Line 755  err_t etharp_query(struct netif *netif,
755                  /* ... in the empty queue */                  /* ... in the empty queue */
756                  pbuf_ref(p);                  pbuf_ref(p);
757                  arp_table[i].p = p;                  arp_table[i].p = p;
758    #if 0 /* multi-packet-queueing disabled, see bug #11400 */
759          } else {          } else {
760                  /* ... at tail of non-empty queue */                  /* ... at tail of non-empty queue */
761            pbuf_queue(arp_table[i].p, p);            pbuf_queue(arp_table[i].p, p);
762    #endif
763          }          }
764          LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %d\n", (void *)q, i));          LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %d\n", (void *)q, i));
765          result = ERR_OK;          result = ERR_OK;

Legend:
Removed from v.1.87  
changed lines
  Added in v.1.88

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