[BACK]Return to if_ethersubr.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / net

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/net/if_ethersubr.c between version 1.2 and 1.3

version 1.2, 1993/05/20 03:05:59 version 1.3, 1993/12/06 04:50:19
Line 109  ether_output(ifp, m0, dst, rt)
Line 109  ether_output(ifp, m0, dst, rt)
                 idst = ((struct sockaddr_in *)dst)->sin_addr;                  idst = ((struct sockaddr_in *)dst)->sin_addr;
                 if (!arpresolve(ac, m, &idst, edst, &usetrailers))                  if (!arpresolve(ac, m, &idst, edst, &usetrailers))
                         return (0);     /* if not yet resolved */                          return (0);     /* if not yet resolved */
                 if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1))                  /* If broadcasting on a simplex interface, loopback a copy */
                   if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
                         mcopy = m_copy(m, 0, (int)M_COPYALL);                          mcopy = m_copy(m, 0, (int)M_COPYALL);
                 off = m->m_pkthdr.len - m->m_len;                  off = m->m_pkthdr.len - m->m_len;
                 if (usetrailers && off > 0 && (off & 0x1ff) == 0 &&                  if (usetrailers && off > 0 && (off & 0x1ff) == 0 &&
Line 133  ether_output(ifp, m0, dst, rt)
Line 134  ether_output(ifp, m0, dst, rt)
                     (caddr_t)edst, sizeof (edst));                      (caddr_t)edst, sizeof (edst));
                 if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst)))                  if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst)))
                         return (looutput(ifp, m, dst, rt));                          return (looutput(ifp, m, dst, rt));
                 if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1))                  /* If broadcasting on a simplex interface, loopback a copy */
                   if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
                         mcopy = m_copy(m, 0, (int)M_COPYALL);                          mcopy = m_copy(m, 0, (int)M_COPYALL);
                 goto gottype;                  goto gottype;
 #endif  #endif
Line 164  ether_output(ifp, m0, dst, rt)
Line 166  ether_output(ifp, m0, dst, rt)
                                         (char *)edst, &snpalen)) > 0)                                          (char *)edst, &snpalen)) > 0)
                         goto bad; /* Not Resolved */                          goto bad; /* Not Resolved */
         iso_resolved:          iso_resolved:
                 if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&                  /* If broadcasting on a simplex interface, loopback a copy */
                   if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
                     (mcopy = m_copy(m, 0, (int)M_COPYALL))) {                      (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
                         M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);                          M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
                         if (mcopy) {                          if (mcopy) {
Line 190  ether_output(ifp, m0, dst, rt)
Line 193  ether_output(ifp, m0, dst, rt)
                                 printf("%x ", edst[i] & 0xff);                                  printf("%x ", edst[i] & 0xff);
                         printf("\n");                          printf("\n");
                 ENDDEBUG                  ENDDEBUG
                 } goto gottype;                  }
                   goto gottype;
 #endif  ISO  #endif  ISO
 #ifdef RMP  #ifdef RMP
         case AF_RMP:          case AF_RMP:
Line 262  gottype:
Line 266  gottype:
                 (*ifp->if_start)(ifp);                  (*ifp->if_start)(ifp);
         splx(s);          splx(s);
         ifp->if_obytes += len + sizeof (struct ether_header);          ifp->if_obytes += len + sizeof (struct ether_header);
   #ifdef MULTICAST
           if (m->m_flags & M_MCAST)
   #else
         if (edst[0] & 1)          if (edst[0] & 1)
   #endif
                 ifp->if_omcasts++;                  ifp->if_omcasts++;
         return (error);          return (error);
   
Line 288  ether_input(ifp, eh, m)
Line 296  ether_input(ifp, eh, m)
   
         ifp->if_lastchange = time;          ifp->if_lastchange = time;
         ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);          ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);
   #ifdef MULTICAST
           if (eh->ether_dhost[0] & 1) {
                   if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
                            sizeof(etherbroadcastaddr)) == 0)
                           m->m_flags |= M_BCAST;
                   else
                           m->m_flags |= M_MCAST;
           }
   #else
         if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,          if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
             sizeof(etherbroadcastaddr)) == 0)              sizeof(etherbroadcastaddr)) == 0)
                 m->m_flags |= M_BCAST;                  m->m_flags |= M_BCAST;
         else if (eh->ether_dhost[0] & 1)          else if (eh->ether_dhost[0] & 1)
                 m->m_flags |= M_MCAST;                  m->m_flags |= M_MCAST;
   #endif
         if (m->m_flags & (M_BCAST|M_MCAST))          if (m->m_flags & (M_BCAST|M_MCAST))
                 ifp->if_imcasts++;                  ifp->if_imcasts++;
   
Line 416  ether_sprintf(ap)
Line 434  ether_sprintf(ap)
         *--cp = 0;          *--cp = 0;
         return (etherbuf);          return (etherbuf);
 }  }
   
   #ifdef MULTICAST
   u_char  ether_ipmulticast_min[6] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
   u_char  ether_ipmulticast_max[6] = { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
   
   /* XXX */
   #undef ac
   /*
    * Add an Ethernet multicast address or range of addresses to the list for a
    * given interface.
    */
   int
   ether_addmulti(ifr, ac)
           struct ifreq *ifr;
           register struct arpcom *ac;
   {
           register struct ether_multi *enm;
           struct sockaddr_in *sin;
           u_char addrlo[6];
           u_char addrhi[6];
           int s = splimp();
   
           switch (ifr->ifr_addr.sa_family) {
   
           case AF_UNSPEC:
                   bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
                   bcopy(addrlo, addrhi, 6);
                   break;
   
   #ifdef INET
           case AF_INET:
                   sin = (struct sockaddr_in *)&(ifr->ifr_addr);
                   if (sin->sin_addr.s_addr == INADDR_ANY) {
                           /*
                            * An IP address of INADDR_ANY means listen to all
                            * of the Ethernet multicast addresses used for IP.
                            * (This is for the sake of IP multicast routers.)
                            */
                           bcopy(ether_ipmulticast_min, addrlo, 6);
                           bcopy(ether_ipmulticast_max, addrhi, 6);
                   }
                   else {
                           ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
                           bcopy(addrlo, addrhi, 6);
                   }
                   break;
   #endif
   
           default:
                   splx(s);
                   return (EAFNOSUPPORT);
           }
   
           /*
            * Verify that we have valid Ethernet multicast addresses.
            */
           if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
                   splx(s);
                   return (EINVAL);
           }
           /*
            * See if the address range is already in the list.
            */
           ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
           if (enm != NULL) {
                   /*
                    * Found it; just increment the reference count.
                    */
                   ++enm->enm_refcount;
                   splx(s);
                   return (0);
           }
           /*
            * New address or range; malloc a new multicast record
            * and link it into the interface's multicast list.
            */
           enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
           if (enm == NULL) {
                   splx(s);
                   return (ENOBUFS);
           }
           bcopy(addrlo, enm->enm_addrlo, 6);
           bcopy(addrhi, enm->enm_addrhi, 6);
           enm->enm_ac = ac;
           enm->enm_refcount = 1;
           enm->enm_next = ac->ac_multiaddrs;
           ac->ac_multiaddrs = enm;
           ac->ac_multicnt++;
           splx(s);
           /*
            * Return ENETRESET to inform the driver that the list has changed
            * and its reception filter should be adjusted accordingly.
            */
           return (ENETRESET);
   }
   
   /*
    * Delete a multicast address record.
    */
   int
   ether_delmulti(ifr, ac)
           struct ifreq *ifr;
           register struct arpcom *ac;
   {
           register struct ether_multi *enm;
           register struct ether_multi **p;
           struct sockaddr_in *sin;
           u_char addrlo[6];
           u_char addrhi[6];
           int s = splimp();
   
           switch (ifr->ifr_addr.sa_family) {
   
           case AF_UNSPEC:
                   bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
                   bcopy(addrlo, addrhi, 6);
                   break;
   
   #ifdef INET
           case AF_INET:
                   sin = (struct sockaddr_in *)&(ifr->ifr_addr);
                   if (sin->sin_addr.s_addr == INADDR_ANY) {
                           /*
                            * An IP address of INADDR_ANY means stop listening
                            * to the range of Ethernet multicast addresses used
                            * for IP.
                            */
                           bcopy(ether_ipmulticast_min, addrlo, 6);
                           bcopy(ether_ipmulticast_max, addrhi, 6);
                   }
                   else {
                           ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
                           bcopy(addrlo, addrhi, 6);
                   }
                   break;
   #endif
   
           default:
                   splx(s);
                   return (EAFNOSUPPORT);
           }
   
           /*
            * Look up the address in our list.
            */
           ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
           if (enm == NULL) {
                   splx(s);
                   return (ENXIO);
           }
           if (--enm->enm_refcount != 0) {
                   /*
                    * Still some claims to this record.
                    */
                   splx(s);
                   return (0);
           }
           /*
            * No remaining claims to this record; unlink and free it.
            */
           for (p = &enm->enm_ac->ac_multiaddrs;
                *p != enm;
                p = &(*p)->enm_next)
                   continue;
           *p = (*p)->enm_next;
           free(enm, M_IFMADDR);
           ac->ac_multicnt--;
           splx(s);
           /*
            * Return ENETRESET to inform the driver that the list has changed
            * and its reception filter should be adjusted accordingly.
            */
           return (ENETRESET);
   }
   #endif

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

CVSweb <webmaster@jp.NetBSD.org>