The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net/if_ethersubr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: if_ethersubr.c,v 1.114.2.2 2004/07/14 11:08:01 tron Exp $      */
    2 
    3 /*
    4  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
    5  * All rights reserved.
    6  * 
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. Neither the name of the project nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  * 
   19  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * Copyright (c) 1982, 1989, 1993
   34  *      The Regents of the University of California.  All rights reserved.
   35  *
   36  * Redistribution and use in source and binary forms, with or without
   37  * modification, are permitted provided that the following conditions
   38  * are met:
   39  * 1. Redistributions of source code must retain the above copyright
   40  *    notice, this list of conditions and the following disclaimer.
   41  * 2. Redistributions in binary form must reproduce the above copyright
   42  *    notice, this list of conditions and the following disclaimer in the
   43  *    documentation and/or other materials provided with the distribution.
   44  * 3. Neither the name of the University nor the names of its contributors
   45  *    may be used to endorse or promote products derived from this software
   46  *    without specific prior written permission.
   47  *
   48  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   58  * SUCH DAMAGE.
   59  *
   60  *      @(#)if_ethersubr.c      8.2 (Berkeley) 4/4/96
   61  */
   62 
   63 #include <sys/cdefs.h>
   64 __KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.114.2.2 2004/07/14 11:08:01 tron Exp $");
   65 
   66 #include "opt_inet.h"
   67 #include "opt_atalk.h"
   68 #include "opt_ccitt.h"
   69 #include "opt_llc.h"
   70 #include "opt_iso.h"
   71 #include "opt_ipx.h"
   72 #include "opt_mbuftrace.h"
   73 #include "opt_ns.h"
   74 #include "opt_gateway.h"
   75 #include "opt_pfil_hooks.h"
   76 #include "vlan.h"
   77 #include "pppoe.h"
   78 #include "bridge.h"
   79 #include "bpfilter.h"
   80 #include "arp.h"
   81 
   82 #include <sys/param.h>
   83 #include <sys/systm.h>
   84 #include <sys/kernel.h>
   85 #include <sys/callout.h>
   86 #include <sys/malloc.h>
   87 #include <sys/mbuf.h>
   88 #include <sys/protosw.h>
   89 #include <sys/socket.h>
   90 #include <sys/ioctl.h>
   91 #include <sys/errno.h>
   92 #include <sys/syslog.h>
   93 
   94 #include <machine/cpu.h>
   95 
   96 #include <net/if.h>
   97 #include <net/netisr.h>
   98 #include <net/route.h>
   99 #include <net/if_llc.h>
  100 #include <net/if_dl.h>
  101 #include <net/if_types.h>
  102 
  103 #if NARP == 0
  104 /*
  105  * XXX there should really be a way to issue this warning from within config(8)
  106  */
  107 #error You have included NETATALK or a pseudo-device in your configuration that depends on the presence of ethernet interfaces, but have no such interfaces configured. Check if you really need pseudo-device bridge, pppoe, vlan or options NETATALK.
  108 #endif
  109 
  110 #if NBPFILTER > 0 
  111 #include <net/bpf.h>
  112 #endif
  113 
  114 #include <net/if_ether.h>
  115 #if NVLAN > 0
  116 #include <net/if_vlanvar.h>
  117 #endif
  118 
  119 #if NPPPOE > 0
  120 #include <net/if_pppoe.h>
  121 #endif
  122 
  123 #if NBRIDGE > 0
  124 #include <net/if_bridgevar.h>
  125 #endif
  126 
  127 #include <netinet/in.h>
  128 #ifdef INET
  129 #include <netinet/in_var.h>
  130 #endif
  131 #include <netinet/if_inarp.h>
  132 
  133 #ifdef INET6
  134 #ifndef INET
  135 #include <netinet/in.h>
  136 #endif
  137 #include <netinet6/in6_var.h>
  138 #include <netinet6/nd6.h>
  139 #endif
  140 
  141 #ifdef NS
  142 #include <netns/ns.h>
  143 #include <netns/ns_if.h>
  144 #endif
  145 
  146 #ifdef IPX
  147 #include <netipx/ipx.h>
  148 #include <netipx/ipx_if.h>
  149 #endif
  150 
  151 #ifdef ISO
  152 #include <netiso/argo_debug.h>
  153 #include <netiso/iso.h>
  154 #include <netiso/iso_var.h>
  155 #include <netiso/iso_snpac.h>
  156 #endif
  157 
  158 #ifdef LLC
  159 #include <netccitt/dll.h>
  160 #include <netccitt/llc_var.h>
  161 #endif
  162 
  163 #if defined(LLC) && defined(CCITT)
  164 extern struct ifqueue pkintrq;
  165 #endif
  166 
  167 #ifdef NETATALK
  168 #include <netatalk/at.h>
  169 #include <netatalk/at_var.h>
  170 #include <netatalk/at_extern.h>
  171 
  172 #define llc_snap_org_code llc_un.type_snap.org_code
  173 #define llc_snap_ether_type llc_un.type_snap.ether_type
  174 
  175 extern u_char   at_org_code[3];
  176 extern u_char   aarp_org_code[3];
  177 #endif /* NETATALK */
  178 
  179 u_char  etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  180 #define senderr(e) { error = (e); goto bad;}
  181 
  182 #define SIN(x) ((struct sockaddr_in *)x)
  183 
  184 static  int ether_output __P((struct ifnet *, struct mbuf *,
  185             struct sockaddr *, struct rtentry *));
  186 static  void ether_input __P((struct ifnet *, struct mbuf *));
  187 
  188 /*
  189  * Ethernet output routine.
  190  * Encapsulate a packet of type family for the local net.
  191  * Assumes that ifp is actually pointer to ethercom structure.
  192  */
  193 static int
  194 ether_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst,
  195         struct rtentry *rt0)
  196 {
  197         u_int16_t etype = 0;
  198         int s, len, error = 0, hdrcmplt = 0;
  199         u_char esrc[6], edst[6];
  200         struct mbuf *m = m0;
  201         struct rtentry *rt;
  202         struct mbuf *mcopy = (struct mbuf *)0;
  203         struct ether_header *eh;
  204         ALTQ_DECL(struct altq_pktattr pktattr;)
  205 #ifdef INET
  206         struct arphdr *ah;
  207 #endif /* INET */
  208 #ifdef NETATALK
  209         struct at_ifaddr *aa;
  210 #endif /* NETATALK */
  211         short mflags;
  212 
  213 #ifdef MBUFTRACE
  214         m_claimm(m, ifp->if_mowner);
  215 #endif
  216         if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
  217                 senderr(ENETDOWN);
  218         if ((rt = rt0) != NULL) {
  219                 if ((rt->rt_flags & RTF_UP) == 0) {
  220                         if ((rt0 = rt = rtalloc1(dst, 1)) != NULL) {
  221                                 rt->rt_refcnt--;
  222                                 if (rt->rt_ifp != ifp)
  223                                         return (*rt->rt_ifp->if_output)
  224                                                         (ifp, m0, dst, rt);
  225                         } else 
  226                                 senderr(EHOSTUNREACH);
  227                 }
  228                 if ((rt->rt_flags & RTF_GATEWAY) && dst->sa_family != AF_NS) {
  229                         if (rt->rt_gwroute == 0)
  230                                 goto lookup;
  231                         if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
  232                                 rtfree(rt); rt = rt0;
  233                         lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1);
  234                                 if ((rt = rt->rt_gwroute) == 0)
  235                                         senderr(EHOSTUNREACH);
  236                                 /* the "G" test below also prevents rt == rt0 */
  237                                 if ((rt->rt_flags & RTF_GATEWAY) ||
  238                                     (rt->rt_ifp != ifp)) {
  239                                         rt->rt_refcnt--;
  240                                         rt0->rt_gwroute = 0;
  241                                         senderr(EHOSTUNREACH);
  242                                 }
  243                         }
  244                 }
  245                 if (rt->rt_flags & RTF_REJECT)
  246                         if (rt->rt_rmx.rmx_expire == 0 ||
  247                             (u_long) time.tv_sec < rt->rt_rmx.rmx_expire)
  248                                 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
  249         }
  250 
  251         switch (dst->sa_family) {
  252 
  253 #ifdef INET
  254         case AF_INET:
  255                 if (m->m_flags & M_BCAST)
  256                         bcopy((caddr_t)etherbroadcastaddr, (caddr_t)edst,
  257                                 sizeof(edst));
  258 
  259                 else if (m->m_flags & M_MCAST) {
  260                         ETHER_MAP_IP_MULTICAST(&SIN(dst)->sin_addr,
  261                             (caddr_t)edst)
  262 
  263                 } else if (!arpresolve(ifp, rt, m, dst, edst))
  264                         return (0);     /* if not yet resolved */
  265                 /* If broadcasting on a simplex interface, loopback a copy */
  266                 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
  267                         mcopy = m_copy(m, 0, (int)M_COPYALL);
  268                 etype = htons(ETHERTYPE_IP);
  269                 break;
  270 
  271         case AF_ARP:
  272                 ah = mtod(m, struct arphdr *);
  273                 if (m->m_flags & M_BCAST)
  274                         bcopy((caddr_t)etherbroadcastaddr, (caddr_t)edst,
  275                                 sizeof(edst));
  276                 else
  277                         bcopy((caddr_t)ar_tha(ah),
  278                                 (caddr_t)edst, sizeof(edst));
  279                 
  280                 ah->ar_hrd = htons(ARPHRD_ETHER);
  281 
  282                 switch (ntohs(ah->ar_op)) {
  283                 case ARPOP_REVREQUEST:
  284                 case ARPOP_REVREPLY:
  285                         etype = htons(ETHERTYPE_REVARP);
  286                         break;
  287 
  288                 case ARPOP_REQUEST:
  289                 case ARPOP_REPLY:
  290                 default:
  291                         etype = htons(ETHERTYPE_ARP);
  292                 }
  293 
  294                 break;
  295 #endif
  296 #ifdef INET6
  297         case AF_INET6:
  298                 if (!nd6_storelladdr(ifp, rt, m, dst, (u_char *)edst)){
  299                         /* something bad happened */
  300                         return (0);
  301                 }
  302                 etype = htons(ETHERTYPE_IPV6);
  303                 break;
  304 #endif
  305 #ifdef NETATALK
  306     case AF_APPLETALK:
  307                 if (!aarpresolve(ifp, m, (struct sockaddr_at *)dst, edst)) {
  308 #ifdef NETATALKDEBUG
  309                         printf("aarpresolv failed\n");
  310 #endif /* NETATALKDEBUG */
  311                         return (0);
  312                 }
  313                 /*
  314                  * ifaddr is the first thing in at_ifaddr
  315                  */
  316                 aa = (struct at_ifaddr *) at_ifawithnet(
  317                     (struct sockaddr_at *)dst, ifp);
  318                 if (aa == NULL)
  319                     goto bad;
  320                 
  321                 /*
  322                  * In the phase 2 case, we need to prepend an mbuf for the
  323                  * llc header.  Since we must preserve the value of m,
  324                  * which is passed to us by value, we m_copy() the first
  325                  * mbuf, and use it for our llc header.
  326                  */
  327                 if (aa->aa_flags & AFA_PHASE2) {
  328                         struct llc llc;
  329 
  330                         M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
  331                         llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
  332                         llc.llc_control = LLC_UI;
  333                         bcopy(at_org_code, llc.llc_snap_org_code,
  334                             sizeof(llc.llc_snap_org_code));
  335                         llc.llc_snap_ether_type = htons(ETHERTYPE_ATALK);
  336                         bcopy(&llc, mtod(m, caddr_t), sizeof(struct llc));
  337                 } else {
  338                         etype = htons(ETHERTYPE_ATALK);
  339                 }
  340                 break;
  341 #endif /* NETATALK */
  342 #ifdef NS
  343         case AF_NS:
  344                 etype = htons(ETHERTYPE_NS);
  345                 bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
  346                     (caddr_t)edst, sizeof (edst));
  347                 if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst)))
  348                         return (looutput(ifp, m, dst, rt));
  349                 /* If broadcasting on a simplex interface, loopback a copy */
  350                 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
  351                         mcopy = m_copy(m, 0, (int)M_COPYALL);
  352                 break;
  353 #endif
  354 #ifdef IPX
  355         case AF_IPX:
  356                 etype = htons(ETHERTYPE_IPX);
  357                 bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host),
  358                     (caddr_t)edst, sizeof (edst));
  359                 /* If broadcasting on a simplex interface, loopback a copy */
  360                 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
  361                         mcopy = m_copy(m, 0, (int)M_COPYALL);
  362                 break;
  363 #endif
  364 #ifdef  ISO
  365         case AF_ISO: {
  366                 int     snpalen;
  367                 struct  llc *l;
  368                 struct sockaddr_dl *sdl;
  369 
  370                 if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) &&
  371                     sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) {
  372                         bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst));
  373                 } else {
  374                         error = iso_snparesolve(ifp, (struct sockaddr_iso *)dst,
  375                                                 (char *)edst, &snpalen);
  376                         if (error)
  377                                 goto bad; /* Not Resolved */
  378                 }
  379                 /* If broadcasting on a simplex interface, loopback a copy */
  380                 if (*edst & 1)
  381                         m->m_flags |= (M_BCAST|M_MCAST);
  382                 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
  383                     (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
  384                         M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
  385                         if (mcopy) {
  386                                 eh = mtod(mcopy, struct ether_header *);
  387                                 bcopy((caddr_t)edst,
  388                                       (caddr_t)eh->ether_dhost, sizeof (edst));
  389                                 bcopy(LLADDR(ifp->if_sadl),
  390                                       (caddr_t)eh->ether_shost, sizeof (edst));
  391                         }
  392                 }
  393                 M_PREPEND(m, 3, M_DONTWAIT);
  394                 if (m == NULL)
  395                         return (0);
  396                 l = mtod(m, struct llc *);
  397                 l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
  398                 l->llc_control = LLC_UI;
  399 #ifdef ARGO_DEBUG
  400                 if (argo_debug[D_ETHER]) {
  401                         int i;
  402                         printf("unoutput: sending pkt to: ");
  403                         for (i=0; i<6; i++)
  404                                 printf("%x ", edst[i] & 0xff);
  405                         printf("\n");
  406                 }
  407 #endif
  408                 } break;
  409 #endif /* ISO */
  410 #ifdef  LLC
  411 /*      case AF_NSAP: */
  412         case AF_CCITT: {
  413                 struct sockaddr_dl *sdl = 
  414                         (struct sockaddr_dl *) rt -> rt_gateway;
  415 
  416                 if (sdl && sdl->sdl_family == AF_LINK
  417                     && sdl->sdl_alen > 0) {
  418                         bcopy(LLADDR(sdl), (char *)edst,
  419                                 sizeof(edst));
  420                 } else goto bad; /* Not a link interface ? Funny ... */
  421                 if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&
  422                     (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
  423                         M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
  424                         if (mcopy) {
  425                                 eh = mtod(mcopy, struct ether_header *);
  426                                 bcopy((caddr_t)edst,
  427                                       (caddr_t)eh->ether_dhost, sizeof (edst));
  428                                 bcopy(LLADDR(ifp->if_sadl),
  429                                       (caddr_t)eh->ether_shost, sizeof (edst));
  430                         }
  431                 }
  432 #ifdef LLC_DEBUG
  433                 {
  434                         int i;
  435                         struct llc *l = mtod(m, struct llc *);
  436 
  437                         printf("ether_output: sending LLC2 pkt to: ");
  438                         for (i=0; i<6; i++)
  439                                 printf("%x ", edst[i] & 0xff);
  440                         printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n", 
  441                             m->m_pkthdr.len, l->llc_dsap & 0xff, l->llc_ssap &0xff,
  442                             l->llc_control & 0xff);
  443 
  444                 }
  445 #endif /* LLC_DEBUG */
  446                 } break;
  447 #endif /* LLC */        
  448 
  449         case pseudo_AF_HDRCMPLT:
  450                 hdrcmplt = 1;
  451                 eh = (struct ether_header *)dst->sa_data;
  452                 bcopy((caddr_t)eh->ether_shost, (caddr_t)esrc, sizeof (esrc));
  453                 /* FALLTHROUGH */
  454 
  455         case AF_UNSPEC:
  456                 eh = (struct ether_header *)dst->sa_data;
  457                 bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));
  458                 /* AF_UNSPEC doesn't swap the byte order of the ether_type. */
  459                 etype = eh->ether_type;
  460                 break;
  461 
  462         default:
  463                 printf("%s: can't handle af%d\n", ifp->if_xname,
  464                         dst->sa_family);
  465                 senderr(EAFNOSUPPORT);
  466         }
  467 
  468         if (mcopy)
  469                 (void) looutput(ifp, mcopy, dst, rt);
  470 
  471         /* If no ether type is set, this must be a 802.2 formatted packet.
  472          */
  473         if (etype == 0)
  474                 etype = htons(m->m_pkthdr.len);
  475         /*
  476          * Add local net header.  If no space in first mbuf,
  477          * allocate another.
  478          */
  479         M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
  480         if (m == 0)
  481                 senderr(ENOBUFS);
  482         eh = mtod(m, struct ether_header *);
  483         /* Note: etype is already in network byte order. */
  484 #ifdef __NO_STRICT_ALIGNMENT
  485         eh->ether_type = etype;
  486 #else
  487         {
  488                 uint8_t *dstp = (uint8_t *) &eh->ether_type;
  489 #if BYTE_ORDER == BIG_ENDIAN
  490                 dstp[0] = etype >> 8;
  491                 dstp[1] = etype; 
  492 #else
  493                 dstp[0] = etype;
  494                 dstp[1] = etype >> 8;
  495 #endif /* BYTE_ORDER == BIG_ENDIAN */
  496         }
  497 #endif /* __NO_STRICT_ALIGNMENT */
  498         bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst));
  499         if (hdrcmplt)
  500                 bcopy((caddr_t)esrc, (caddr_t)eh->ether_shost,
  501                     sizeof(eh->ether_shost));
  502         else
  503                 bcopy(LLADDR(ifp->if_sadl), (caddr_t)eh->ether_shost,
  504                     sizeof(eh->ether_shost));
  505 
  506 #ifdef PFIL_HOOKS
  507         if ((error = pfil_run_hooks(&ifp->if_pfil, &m, ifp, PFIL_OUT)) != 0)
  508                 return (error);
  509         if (m == NULL)
  510                 return (0);
  511 #endif
  512 
  513 #if NBRIDGE > 0
  514         /*
  515          * Bridges require special output handling.
  516          */
  517         if (ifp->if_bridge)
  518                 return (bridge_output(ifp, m, NULL, NULL));
  519 #endif
  520 
  521 #ifdef ALTQ
  522         /*
  523          * If ALTQ is enabled on the parent interface, do
  524          * classification; the queueing discipline might not
  525          * require classification, but might require the
  526          * address family/header pointer in the pktattr.
  527          */
  528         if (ALTQ_IS_ENABLED(&ifp->if_snd))
  529                 altq_etherclassify(&ifp->if_snd, m, &pktattr);
  530 #endif
  531 
  532         mflags = m->m_flags;
  533         len = m->m_pkthdr.len;
  534         s = splnet();
  535         /*
  536          * Queue message on interface, and start output if interface
  537          * not yet active.
  538          */
  539         IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error);
  540         if (error) {
  541                 /* mbuf is already freed */
  542                 splx(s);
  543                 return (error);
  544         }
  545         ifp->if_obytes += len;
  546         if (mflags & M_MCAST)
  547                 ifp->if_omcasts++;
  548         if ((ifp->if_flags & IFF_OACTIVE) == 0)
  549                 (*ifp->if_start)(ifp);
  550         splx(s);
  551         return (error);
  552 
  553 bad:
  554         if (m)
  555                 m_freem(m);
  556         return (error);
  557 }
  558 
  559 #ifdef ALTQ
  560 /*
  561  * This routine is a slight hack to allow a packet to be classified
  562  * if the Ethernet headers are present.  It will go away when ALTQ's
  563  * classification engine understands link headers.
  564  */
  565 void
  566 altq_etherclassify(struct ifaltq *ifq, struct mbuf *m,
  567     struct altq_pktattr *pktattr)
  568 {
  569         struct ether_header *eh;
  570         u_int16_t ether_type;
  571         int hlen, af, hdrsize;
  572         caddr_t hdr;
  573 
  574         hlen = ETHER_HDR_LEN;
  575         eh = mtod(m, struct ether_header *);
  576 
  577         ether_type = htons(eh->ether_type);
  578 
  579         if (ether_type < ETHERMTU) {
  580                 /* LLC/SNAP */
  581                 struct llc *llc = (struct llc *)(eh + 1);
  582                 hlen += 8;
  583 
  584                 if (m->m_len < hlen ||
  585                     llc->llc_dsap != LLC_SNAP_LSAP ||
  586                     llc->llc_ssap != LLC_SNAP_LSAP ||
  587                     llc->llc_control != LLC_UI) {
  588                         /* Not SNAP. */
  589                         goto bad;
  590                 }
  591 
  592                 ether_type = htons(llc->llc_un.type_snap.ether_type);
  593         }
  594 
  595         switch (ether_type) {
  596         case ETHERTYPE_IP:
  597                 af = AF_INET;
  598                 hdrsize = 20;           /* sizeof(struct ip) */
  599                 break;
  600 
  601         case ETHERTYPE_IPV6:
  602                 af = AF_INET6;
  603                 hdrsize = 40;           /* sizeof(struct ip6_hdr) */
  604                 break;
  605 
  606         default:
  607                 af = AF_UNSPEC;
  608                 hdrsize = 0;
  609                 break;
  610         }
  611 
  612         while (m->m_len <= hlen) {
  613                 hlen -= m->m_len;
  614                 m = m->m_next;
  615         }
  616         if (m->m_len < (hlen + hdrsize)) {
  617                 /*
  618                  * protocol header not in a single mbuf.
  619                  * We can't cope with this situation right
  620                  * now (but it shouldn't ever happen, really, anyhow).
  621                  */
  622 #ifdef DEBUG
  623                 printf("altq_etherclassify: headers span multiple mbufs: "
  624                     "%d < %d\n", m->m_len, (hlen + hdrsize));
  625 #endif
  626                 goto bad;
  627         }
  628 
  629         m->m_data += hlen;
  630         m->m_len -= hlen;
  631 
  632         hdr = mtod(m, caddr_t);
  633 
  634         if (ALTQ_NEEDS_CLASSIFY(ifq))
  635                 pktattr->pattr_class =
  636                     (*ifq->altq_classify)(ifq->altq_clfier, m, af);
  637         pktattr->pattr_af = af;
  638         pktattr->pattr_hdr = hdr;
  639 
  640         m->m_data -= hlen;
  641         m->m_len += hlen;
  642 
  643         return;
  644 
  645  bad:
  646         pktattr->pattr_class = NULL;
  647         pktattr->pattr_hdr = NULL;
  648         pktattr->pattr_af = AF_UNSPEC;
  649 }
  650 #endif /* ALTQ */
  651 
  652 /*
  653  * Process a received Ethernet packet;
  654  * the packet is in the mbuf chain m with
  655  * the ether header.
  656  */
  657 static void
  658 ether_input(struct ifnet *ifp, struct mbuf *m)
  659 {
  660         struct ethercom *ec = (struct ethercom *) ifp;
  661         struct ifqueue *inq;
  662         u_int16_t etype;
  663         int s;
  664         struct ether_header *eh;
  665 #if defined (ISO) || defined (LLC) || defined(NETATALK)
  666         struct llc *l;
  667 #endif
  668 
  669         if ((ifp->if_flags & IFF_UP) == 0) {
  670                 m_freem(m);
  671                 return;
  672         }
  673 
  674 #ifdef MBUFTRACE
  675         m_claimm(m, &ec->ec_rx_mowner);
  676 #endif
  677         eh = mtod(m, struct ether_header *);
  678         etype = ntohs(eh->ether_type);
  679 
  680         /*
  681          * Determine if the packet is within its size limits.
  682          */
  683         if (m->m_pkthdr.len >
  684             ETHER_MAX_FRAME(ifp, etype, m->m_flags & M_HASFCS)) {
  685                 printf("%s: discarding oversize frame (len=%d)\n",
  686                     ifp->if_xname, m->m_pkthdr.len);
  687                 m_freem(m);
  688                 return;
  689         }
  690 
  691         if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
  692                 /*
  693                  * If this is not a simplex interface, drop the packet
  694                  * if it came from us.
  695                  */
  696                 if ((ifp->if_flags & IFF_SIMPLEX) == 0 &&
  697                     memcmp(LLADDR(ifp->if_sadl), eh->ether_shost,
  698                     ETHER_ADDR_LEN) == 0) {
  699                         m_freem(m);
  700                         return;
  701                 }
  702 
  703                 if (memcmp(etherbroadcastaddr,
  704                     eh->ether_dhost, ETHER_ADDR_LEN) == 0)
  705                         m->m_flags |= M_BCAST;
  706                 else
  707                         m->m_flags |= M_MCAST;
  708                 ifp->if_imcasts++;
  709         }
  710 
  711         /* If the CRC is still on the packet, trim it off. */
  712         if (m->m_flags & M_HASFCS) {
  713                 m_adj(m, -ETHER_CRC_LEN);
  714                 m->m_flags &= ~M_HASFCS;
  715         }
  716 
  717         ifp->if_ibytes += m->m_pkthdr.len;
  718 
  719 #if NBRIDGE > 0
  720         /*
  721          * Tap the packet off here for a bridge.  bridge_input()
  722          * will return NULL if it has consumed the packet, otherwise
  723          * it gets processed as normal.  Note that bridge_input()
  724          * will always return the original packet if we need to
  725          * process it locally.
  726          */
  727         if (ifp->if_bridge) {
  728                 /* clear M_PROMISC, in case the packets comes from a vlan */
  729                 m->m_flags &= ~M_PROMISC;
  730                 m = bridge_input(ifp, m);
  731                 if (m == NULL)
  732                         return;
  733 
  734                 /*
  735                  * Bridge has determined that the packet is for us.
  736                  * Update our interface pointer -- we may have had
  737                  * to "bridge" the packet locally.
  738                  */
  739                 ifp = m->m_pkthdr.rcvif;
  740         } else 
  741 #endif /* NBRIDGE > 0 */
  742         {
  743                 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0 &&
  744                     (ifp->if_flags & IFF_PROMISC) != 0 &&
  745                     memcmp(LLADDR(ifp->if_sadl), eh->ether_dhost,
  746                            ETHER_ADDR_LEN) != 0) {
  747                         m->m_flags |= M_PROMISC;
  748                 }
  749         }
  750 
  751 #ifdef PFIL_HOOKS
  752         if ((m->m_flags & M_PROMISC) == 0) {
  753                 if (pfil_run_hooks(&ifp->if_pfil, &m, ifp, PFIL_IN) != 0)
  754                         return;
  755                 if (m == NULL)
  756                         return;
  757 
  758                 eh = mtod(m, struct ether_header *);
  759                 etype = ntohs(eh->ether_type);
  760         }
  761 #endif
  762 
  763         /*
  764          * If VLANs are configured on the interface, check to
  765          * see if the device performed the decapsulation and
  766          * provided us with the tag.
  767          */
  768         if (ec->ec_nvlans && m_tag_find(m, PACKET_TAG_VLAN, NULL) != NULL) {
  769 #if NVLAN > 0
  770                 /*
  771                  * vlan_input() will either recursively call ether_input()
  772                  * or drop the packet.
  773                  */
  774                 vlan_input(ifp, m);
  775 #else
  776                 m_freem(m);
  777 #endif
  778                 return;
  779         }
  780 
  781         /*
  782          * Handle protocols that expect to have the Ethernet header
  783          * (and possibly FCS) intact.
  784          */
  785         switch (etype) {
  786 #if NVLAN > 0
  787         case ETHERTYPE_VLAN:
  788                 /*
  789                  * vlan_input() will either recursively call ether_input()
  790                  * or drop the packet.
  791                  */
  792                 if (((struct ethercom *)ifp)->ec_nvlans != 0)
  793                         vlan_input(ifp, m);
  794                 else
  795                         m_freem(m);
  796                 return;
  797 #endif /* NVLAN > 0 */
  798 #if NPPPOE > 0
  799         case ETHERTYPE_PPPOEDISC:
  800         case ETHERTYPE_PPPOE:
  801                 if (m->m_flags & M_PROMISC) {
  802                         m_freem(m);
  803                         return;
  804                 }
  805 #ifndef PPPOE_SERVER
  806                 if (m->m_flags & (M_MCAST | M_BCAST)) {
  807                         m_freem(m);
  808                         return;
  809                 }
  810 #endif
  811 
  812                 if (etype == ETHERTYPE_PPPOEDISC) 
  813                         inq = &ppoediscinq;
  814                 else
  815                         inq = &ppoeinq;
  816                 s = splnet();
  817                 if (IF_QFULL(inq)) {
  818                         IF_DROP(inq);
  819                         m_freem(m);
  820                 } else
  821                         IF_ENQUEUE(inq, m);
  822                 splx(s);
  823 #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS
  824                 if (!callout_pending(&pppoe_softintr))
  825                         callout_reset(&pppoe_softintr, 1, pppoe_softintr_handler, NULL);
  826 #else
  827                 softintr_schedule(pppoe_softintr);
  828 #endif
  829                 return;
  830 #endif /* NPPPOE > 0 */
  831         default:
  832                 if (m->m_flags & M_PROMISC) {
  833                         m_freem(m);
  834                         return;
  835                 }
  836         }
  837 
  838         /* Strip off the Ethernet header. */
  839         m_adj(m, sizeof(struct ether_header));
  840 
  841         /* If the CRC is still on the packet, trim it off. */
  842         if (m->m_flags & M_HASFCS) {
  843                 m_adj(m, -ETHER_CRC_LEN);
  844                 m->m_flags &= ~M_HASFCS;
  845         }
  846 
  847         switch (etype) {
  848 #ifdef INET
  849         case ETHERTYPE_IP:
  850 #ifdef GATEWAY
  851                 if (ipflow_fastforward(m))
  852                         return;
  853 #endif
  854                 schednetisr(NETISR_IP);
  855                 inq = &ipintrq;
  856                 break;
  857 
  858         case ETHERTYPE_ARP:
  859                 schednetisr(NETISR_ARP);
  860                 inq = &arpintrq;
  861                 break;
  862 
  863         case ETHERTYPE_REVARP:
  864                 revarpinput(m); /* XXX queue? */
  865                 return;
  866 #endif
  867 #ifdef INET6
  868         case ETHERTYPE_IPV6:
  869                 schednetisr(NETISR_IPV6);
  870                 inq = &ip6intrq;
  871                 break;
  872 #endif
  873 #ifdef NS
  874         case ETHERTYPE_NS:
  875                 schednetisr(NETISR_NS);
  876                 inq = &nsintrq;
  877                 break;
  878 
  879 #endif
  880 #ifdef IPX
  881         case ETHERTYPE_IPX:
  882                 schednetisr(NETISR_IPX);
  883                 inq = &ipxintrq;
  884                 break;
  885 #endif
  886 #ifdef NETATALK
  887         case ETHERTYPE_ATALK:
  888                 schednetisr(NETISR_ATALK);
  889                 inq = &atintrq1;
  890                 break;
  891         case ETHERTYPE_AARP:
  892                 /* probably this should be done with a NETISR as well */
  893                 aarpinput(ifp, m); /* XXX */
  894                 return;
  895 #endif /* NETATALK */
  896         default:
  897 #if defined (ISO) || defined (LLC) || defined (NETATALK)
  898                 if (etype > ETHERMTU)
  899                         goto dropanyway;
  900                 l = mtod(m, struct llc *);
  901                 switch (l->llc_dsap) {
  902 #ifdef NETATALK
  903                 case LLC_SNAP_LSAP:
  904                         switch (l->llc_control) {
  905                         case LLC_UI:
  906                                 if (l->llc_ssap != LLC_SNAP_LSAP) {
  907                                         goto dropanyway;
  908                                 }
  909             
  910                                 if (Bcmp(&(l->llc_snap_org_code)[0],
  911                                     at_org_code, sizeof(at_org_code)) == 0 &&
  912                                     ntohs(l->llc_snap_ether_type) ==
  913                                     ETHERTYPE_ATALK) {
  914                                         inq = &atintrq2;
  915                                         m_adj(m, sizeof(struct llc));
  916                                         schednetisr(NETISR_ATALK);
  917                                         break;
  918                                 }
  919 
  920                                 if (Bcmp(&(l->llc_snap_org_code)[0],
  921                                     aarp_org_code,
  922                                     sizeof(aarp_org_code)) == 0 &&
  923                                     ntohs(l->llc_snap_ether_type) ==
  924                                     ETHERTYPE_AARP) {
  925                                         m_adj( m, sizeof(struct llc));
  926                                         aarpinput(ifp, m); /* XXX */
  927                                     return;
  928                                 }
  929                     
  930                         default:
  931                                 goto dropanyway;
  932                         }
  933                         break;
  934 #endif /* NETATALK */
  935 #ifdef  ISO
  936                 case LLC_ISO_LSAP: 
  937                         switch (l->llc_control) {
  938                         case LLC_UI:
  939                                 /* LLC_UI_P forbidden in class 1 service */
  940                                 if ((l->llc_dsap == LLC_ISO_LSAP) &&
  941                                     (l->llc_ssap == LLC_ISO_LSAP)) {
  942                                         /* LSAP for ISO */
  943                                         if (m->m_pkthdr.len > etype)
  944                                                 m_adj(m, etype - m->m_pkthdr.len);
  945                                         m->m_data += 3;         /* XXX */
  946                                         m->m_len -= 3;          /* XXX */
  947                                         m->m_pkthdr.len -= 3;   /* XXX */
  948                                         M_PREPEND(m, sizeof *eh, M_DONTWAIT);
  949                                         if (m == 0)
  950                                                 return;
  951                                         *mtod(m, struct ether_header *) = *eh;
  952 #ifdef ARGO_DEBUG
  953                                         if (argo_debug[D_ETHER])
  954                                                 printf("clnp packet");
  955 #endif
  956                                         schednetisr(NETISR_ISO);
  957                                         inq = &clnlintrq;
  958                                         break;
  959                                 }
  960                                 goto dropanyway;
  961                                 
  962                         case LLC_XID:
  963                         case LLC_XID_P:
  964                                 if(m->m_len < 6)
  965                                         goto dropanyway;
  966                                 l->llc_window = 0;
  967                                 l->llc_fid = 9;
  968                                 l->llc_class = 1;
  969                                 l->llc_dsap = l->llc_ssap = 0;
  970                                 /* Fall through to */
  971                         case LLC_TEST:
  972                         case LLC_TEST_P:
  973                         {
  974                                 struct sockaddr sa;
  975                                 struct ether_header *eh2;
  976                                 int i;
  977                                 u_char c = l->llc_dsap;
  978 
  979                                 l->llc_dsap = l->llc_ssap;
  980                                 l->llc_ssap = c;
  981                                 if (m->m_flags & (M_BCAST | M_MCAST))
  982                                         bcopy(LLADDR(ifp->if_sadl),
  983                                               (caddr_t)eh->ether_dhost, 6);
  984                                 sa.sa_family = AF_UNSPEC;
  985                                 sa.sa_len = sizeof(sa);
  986                                 eh2 = (struct ether_header *)sa.sa_data;
  987                                 for (i = 0; i < 6; i++) {
  988                                         eh2->ether_shost[i] = c = 
  989                                             eh->ether_dhost[i];
  990                                         eh2->ether_dhost[i] = 
  991                                             eh->ether_dhost[i] =
  992                                             eh->ether_shost[i];
  993                                         eh->ether_shost[i] = c;
  994                                 }
  995                                 ifp->if_output(ifp, m, &sa, NULL);
  996                                 return;
  997                         }
  998                         default:
  999                                 m_freem(m);
 1000                                 return;
 1001                         }
 1002                         break;
 1003 #endif /* ISO */
 1004 #ifdef LLC
 1005                 case LLC_X25_LSAP:
 1006                 {
 1007                         if (m->m_pkthdr.len > etype)
 1008                                 m_adj(m, etype - m->m_pkthdr.len);
 1009                         M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT);
 1010                         if (m == 0)
 1011                                 return;
 1012                         if ( !sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP,
 1013                                             eh->ether_dhost, LLC_X25_LSAP, 6, 
 1014                                             mtod(m, struct sdl_hdr *)))
 1015                                 panic("ETHER cons addr failure");
 1016                         mtod(m, struct sdl_hdr *)->sdlhdr_len = etype;
 1017 #ifdef LLC_DEBUG
 1018                                 printf("llc packet\n");
 1019 #endif /* LLC_DEBUG */
 1020                         schednetisr(NETISR_CCITT);
 1021                         inq = &llcintrq;
 1022                         break;
 1023                 }
 1024 #endif /* LLC */
 1025                 dropanyway:
 1026                 default:
 1027                         m_freem(m);
 1028                         return;
 1029                 }
 1030 #else /* ISO || LLC  || NETATALK*/
 1031             m_freem(m);
 1032             return;
 1033 #endif /* ISO || LLC || NETATALK*/
 1034         }
 1035 
 1036         s = splnet();
 1037         if (IF_QFULL(inq)) {
 1038                 IF_DROP(inq);
 1039                 m_freem(m);
 1040         } else
 1041                 IF_ENQUEUE(inq, m);
 1042         splx(s);
 1043 }
 1044 
 1045 /*
 1046  * Convert Ethernet address to printable (loggable) representation.
 1047  */
 1048 static char digits[] = "0123456789abcdef";
 1049 char *
 1050 ether_sprintf(const u_char *ap)
 1051 {
 1052         static char etherbuf[18];
 1053         char *cp = etherbuf;
 1054         int i;
 1055 
 1056         for (i = 0; i < 6; i++) {
 1057                 *cp++ = digits[*ap >> 4];
 1058                 *cp++ = digits[*ap++ & 0xf];
 1059                 *cp++ = ':';
 1060         }
 1061         *--cp = 0;
 1062         return (etherbuf);
 1063 }
 1064 
 1065 /*
 1066  * Perform common duties while attaching to interface list
 1067  */
 1068 void
 1069 ether_ifattach(struct ifnet *ifp, const u_int8_t *lla)
 1070 {
 1071         struct ethercom *ec = (struct ethercom *)ifp;
 1072 
 1073         ifp->if_type = IFT_ETHER;
 1074         ifp->if_addrlen = ETHER_ADDR_LEN;
 1075         ifp->if_hdrlen = ETHER_HDR_LEN;
 1076         ifp->if_dlt = DLT_EN10MB;
 1077         ifp->if_mtu = ETHERMTU;
 1078         ifp->if_output = ether_output;
 1079         ifp->if_input = ether_input;
 1080         if (ifp->if_baudrate == 0)
 1081                 ifp->if_baudrate = IF_Mbps(10);         /* just a default */
 1082 
 1083         if_alloc_sadl(ifp);
 1084         memcpy(LLADDR(ifp->if_sadl), lla, ifp->if_addrlen);
 1085 
 1086         LIST_INIT(&ec->ec_multiaddrs);
 1087         ifp->if_broadcastaddr = etherbroadcastaddr;
 1088 #if NBPFILTER > 0
 1089         bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
 1090 #endif
 1091 #ifdef MBUFTRACE
 1092         strlcpy(ec->ec_tx_mowner.mo_name, ifp->if_xname,
 1093             sizeof(ec->ec_tx_mowner.mo_name));
 1094         strlcpy(ec->ec_tx_mowner.mo_descr, "tx",
 1095             sizeof(ec->ec_tx_mowner.mo_descr));
 1096         strlcpy(ec->ec_rx_mowner.mo_name, ifp->if_xname,
 1097             sizeof(ec->ec_rx_mowner.mo_name));
 1098         strlcpy(ec->ec_rx_mowner.mo_descr, "rx",
 1099             sizeof(ec->ec_rx_mowner.mo_descr));
 1100         MOWNER_ATTACH(&ec->ec_tx_mowner);
 1101         MOWNER_ATTACH(&ec->ec_rx_mowner);
 1102         ifp->if_mowner = &ec->ec_tx_mowner;
 1103 #endif
 1104 }
 1105 
 1106 void
 1107 ether_ifdetach(struct ifnet *ifp)
 1108 {
 1109         struct ethercom *ec = (void *) ifp;
 1110         struct ether_multi *enm;
 1111         int s;
 1112 
 1113 #if NBRIDGE > 0
 1114         if (ifp->if_bridge)
 1115                 bridge_ifdetach(ifp);
 1116 #endif
 1117 
 1118 #if NBPFILTER > 0
 1119         bpfdetach(ifp);
 1120 #endif
 1121 
 1122 #if NVLAN > 0
 1123         if (ec->ec_nvlans)
 1124                 vlan_ifdetach(ifp);
 1125 #endif
 1126 
 1127         s = splnet();
 1128         while ((enm = LIST_FIRST(&ec->ec_multiaddrs)) != NULL) {
 1129                 LIST_REMOVE(enm, enm_list);
 1130                 free(enm, M_IFMADDR);
 1131                 ec->ec_multicnt--;
 1132         }
 1133         splx(s);
 1134 
 1135 #if 0   /* done in if_detach() */
 1136         if_free_sadl(ifp);
 1137 #endif
 1138 
 1139         MOWNER_DETACH(&ec->ec_rx_mowner);
 1140         MOWNER_DETACH(&ec->ec_tx_mowner);
 1141 }
 1142 
 1143 #if 0
 1144 /*
 1145  * This is for reference.  We have a table-driven version
 1146  * of the little-endian crc32 generator, which is faster
 1147  * than the double-loop.
 1148  */
 1149 u_int32_t
 1150 ether_crc32_le(const u_int8_t *buf, size_t len)
 1151 {
 1152         u_int32_t c, crc, carry;
 1153         size_t i, j;
 1154 
 1155         crc = 0xffffffffU;      /* initial value */
 1156 
 1157         for (i = 0; i < len; i++) {
 1158                 c = buf[i];
 1159                 for (j = 0; j < 8; j++) {
 1160                         carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01);
 1161                         crc >>= 1;
 1162                         c >>= 1;
 1163                         if (carry)
 1164                                 crc = (crc ^ ETHER_CRC_POLY_LE);
 1165                 }
 1166         }
 1167 
 1168         return (crc);
 1169 }
 1170 #else
 1171 u_int32_t
 1172 ether_crc32_le(const u_int8_t *buf, size_t len)
 1173 {
 1174         static const u_int32_t crctab[] = {
 1175                 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
 1176                 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
 1177                 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
 1178                 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
 1179         };
 1180         u_int32_t crc;
 1181         size_t i;
 1182 
 1183         crc = 0xffffffffU;      /* initial value */
 1184 
 1185         for (i = 0; i < len; i++) {
 1186                 crc ^= buf[i];
 1187                 crc = (crc >> 4) ^ crctab[crc & 0xf];
 1188                 crc = (crc >> 4) ^ crctab[crc & 0xf];
 1189         }
 1190 
 1191         return (crc);
 1192 }
 1193 #endif
 1194 
 1195 u_int32_t
 1196 ether_crc32_be(const u_int8_t *buf, size_t len)
 1197 {
 1198         u_int32_t c, crc, carry;
 1199         size_t i, j;
 1200 
 1201         crc = 0xffffffffU;      /* initial value */
 1202 
 1203         for (i = 0; i < len; i++) {
 1204                 c = buf[i];
 1205                 for (j = 0; j < 8; j++) {
 1206                         carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01);
 1207                         crc <<= 1;
 1208                         c >>= 1;
 1209                         if (carry)
 1210                                 crc = (crc ^ ETHER_CRC_POLY_BE) | carry;
 1211                 }
 1212         }
 1213 
 1214         return (crc);
 1215 }
 1216 
 1217 #ifdef INET
 1218 u_char  ether_ipmulticast_min[6] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
 1219 u_char  ether_ipmulticast_max[6] = { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
 1220 #endif
 1221 #ifdef INET6
 1222 u_char  ether_ip6multicast_min[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
 1223 u_char  ether_ip6multicast_max[6] = { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
 1224 #endif
 1225 
 1226 /*
 1227  * Convert a sockaddr into an Ethernet address or range of Ethernet
 1228  * addresses.
 1229  */
 1230 int
 1231 ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN],
 1232     u_int8_t addrhi[ETHER_ADDR_LEN])
 1233 {
 1234 #ifdef INET
 1235         struct sockaddr_in *sin;
 1236 #endif /* INET */
 1237 #ifdef INET6
 1238         struct sockaddr_in6 *sin6;
 1239 #endif /* INET6 */
 1240 
 1241         switch (sa->sa_family) {
 1242 
 1243         case AF_UNSPEC:
 1244                 bcopy(sa->sa_data, addrlo, ETHER_ADDR_LEN);
 1245                 bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
 1246                 break;
 1247 
 1248 #ifdef INET
 1249         case AF_INET:
 1250                 sin = satosin(sa);
 1251                 if (sin->sin_addr.s_addr == INADDR_ANY) {
 1252                         /*
 1253                          * An IP address of INADDR_ANY means listen to
 1254                          * or stop listening to all of the Ethernet
 1255                          * multicast addresses used for IP.
 1256                          * (This is for the sake of IP multicast routers.)
 1257                          */
 1258                         bcopy(ether_ipmulticast_min, addrlo, ETHER_ADDR_LEN);
 1259                         bcopy(ether_ipmulticast_max, addrhi, ETHER_ADDR_LEN);
 1260                 }
 1261                 else {
 1262                         ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
 1263                         bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
 1264                 }
 1265                 break;
 1266 #endif
 1267 #ifdef INET6
 1268         case AF_INET6:
 1269                 sin6 = satosin6(sa);
 1270                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
 1271                         /*
 1272                          * An IP6 address of 0 means listen to or stop
 1273                          * listening to all of the Ethernet multicast
 1274                          * address used for IP6.
 1275                          * (This is used for multicast routers.)
 1276                          */
 1277                         bcopy(ether_ip6multicast_min, addrlo, ETHER_ADDR_LEN);
 1278                         bcopy(ether_ip6multicast_max, addrhi, ETHER_ADDR_LEN);
 1279                 } else {
 1280                         ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
 1281                         bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
 1282                 }
 1283                 break;
 1284 #endif
 1285 
 1286         default:
 1287                 return (EAFNOSUPPORT);
 1288         }
 1289         return (0);
 1290 }
 1291 
 1292 /*
 1293  * Add an Ethernet multicast address or range of addresses to the list for a
 1294  * given interface.
 1295  */
 1296 int
 1297 ether_addmulti(struct ifreq *ifr, struct ethercom *ec)
 1298 {
 1299         struct ether_multi *enm;
 1300         u_char addrlo[ETHER_ADDR_LEN];
 1301         u_char addrhi[ETHER_ADDR_LEN];
 1302         int s = splnet(), error;
 1303 
 1304         error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
 1305         if (error != 0) {
 1306                 splx(s);
 1307                 return (error);
 1308         }
 1309 
 1310         /*
 1311          * Verify that we have valid Ethernet multicast addresses.
 1312          */
 1313         if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
 1314                 splx(s);
 1315                 return (EINVAL);
 1316         }
 1317         /*
 1318          * See if the address range is already in the list.
 1319          */
 1320         ETHER_LOOKUP_MULTI(addrlo, addrhi, ec, enm);
 1321         if (enm != NULL) {
 1322                 /*
 1323                  * Found it; just increment the reference count.
 1324                  */
 1325                 ++enm->enm_refcount;
 1326                 splx(s);
 1327                 return (0);
 1328         }
 1329         /*
 1330          * New address or range; malloc a new multicast record
 1331          * and link it into the interface's multicast list.
 1332          */
 1333         enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
 1334         if (enm == NULL) {
 1335                 splx(s);
 1336                 return (ENOBUFS);
 1337         }
 1338         bcopy(addrlo, enm->enm_addrlo, 6);
 1339         bcopy(addrhi, enm->enm_addrhi, 6);
 1340         enm->enm_ec = ec;
 1341         enm->enm_refcount = 1;
 1342         LIST_INSERT_HEAD(&ec->ec_multiaddrs, enm, enm_list);
 1343         ec->ec_multicnt++;
 1344         splx(s);
 1345         /*
 1346          * Return ENETRESET to inform the driver that the list has changed
 1347          * and its reception filter should be adjusted accordingly.
 1348          */
 1349         return (ENETRESET);
 1350 }
 1351 
 1352 /*
 1353  * Delete a multicast address record.
 1354  */
 1355 int
 1356 ether_delmulti(struct ifreq *ifr, struct ethercom *ec)
 1357 {
 1358         struct ether_multi *enm;
 1359         u_char addrlo[ETHER_ADDR_LEN];
 1360         u_char addrhi[ETHER_ADDR_LEN];
 1361         int s = splnet(), error;
 1362 
 1363         error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
 1364         if (error != 0) {
 1365                 splx(s);
 1366                 return (error);
 1367         }
 1368 
 1369         /*
 1370          * Look ur the address in our list.
 1371          */
 1372         ETHER_LOOKUP_MULTI(addrlo, addrhi, ec, enm);
 1373         if (enm == NULL) {
 1374                 splx(s);
 1375                 return (ENXIO);
 1376         }
 1377         if (--enm->enm_refcount != 0) {
 1378                 /*
 1379                  * Still some claims to this record.
 1380                  */
 1381                 splx(s);
 1382                 return (0);
 1383         }
 1384         /*
 1385          * No remaining claims to this record; unlink and free it.
 1386          */
 1387         LIST_REMOVE(enm, enm_list);
 1388         free(enm, M_IFMADDR);
 1389         ec->ec_multicnt--;
 1390         splx(s);
 1391         /*
 1392          * Return ENETRESET to inform the driver that the list has changed
 1393          * and its reception filter should be adjusted accordingly.
 1394          */
 1395         return (ENETRESET);
 1396 }
 1397 
 1398 /*
 1399  * Common ioctls for Ethernet interfaces.  Note, we must be
 1400  * called at splnet().
 1401  */
 1402 int
 1403 ether_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 1404 {
 1405         struct ethercom *ec = (void *) ifp;
 1406         struct ifreq *ifr = (struct ifreq *)data;
 1407         struct ifaddr *ifa = (struct ifaddr *)data;
 1408         int error = 0;
 1409 
 1410         switch (cmd) {
 1411         case SIOCSIFADDR:
 1412                 ifp->if_flags |= IFF_UP;
 1413                 switch (ifa->ifa_addr->sa_family) {
 1414                 case AF_LINK:
 1415                     {
 1416                         struct sockaddr_dl *sdl =
 1417                             (struct sockaddr_dl *) ifa->ifa_addr;
 1418 
 1419                         if (sdl->sdl_type != IFT_ETHER ||
 1420                             sdl->sdl_alen != ifp->if_addrlen) {
 1421                                 error = EINVAL;
 1422                                 break;
 1423                         }
 1424 
 1425                         memcpy(LLADDR(ifp->if_sadl), LLADDR(sdl),
 1426                             ifp->if_addrlen);
 1427 
 1428                         /* Set new address. */
 1429                         error = (*ifp->if_init)(ifp);
 1430                         break;
 1431                     }
 1432 #ifdef INET
 1433                 case AF_INET:
 1434                         if ((ifp->if_flags & IFF_RUNNING) == 0 &&
 1435                             (error = (*ifp->if_init)(ifp)) != 0)
 1436                                 break;
 1437                         arp_ifinit(ifp, ifa);
 1438                         break;
 1439 #endif /* INET */
 1440 #ifdef NS
 1441                 case AF_NS:
 1442                     {
 1443                         struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
 1444 
 1445                         if (ns_nullhost(*ina))
 1446                                 ina->x_host = *(union ns_host *)
 1447                                     LLADDR(ifp->if_sadl);
 1448                         else
 1449                                 memcpy(LLADDR(ifp->if_sadl),
 1450                                     ina->x_host.c_host, ifp->if_addrlen);
 1451                         /* Set new address. */
 1452                         error = (*ifp->if_init)(ifp);
 1453                         break;
 1454                     }
 1455 #endif /* NS */
 1456                 default:
 1457                         if ((ifp->if_flags & IFF_RUNNING) == 0)
 1458                                 error = (*ifp->if_init)(ifp);
 1459                         break;
 1460                 }
 1461                 break;
 1462 
 1463         case SIOCGIFADDR:
 1464                 memcpy(((struct sockaddr *)&ifr->ifr_data)->sa_data,
 1465                     LLADDR(ifp->if_sadl), ETHER_ADDR_LEN);
 1466                 break;
 1467 
 1468         case SIOCSIFMTU:
 1469             {
 1470                 int maxmtu;
 1471 
 1472                 if (ec->ec_capabilities & ETHERCAP_JUMBO_MTU)
 1473                         maxmtu = ETHERMTU_JUMBO;
 1474                 else
 1475                         maxmtu = ETHERMTU;
 1476 
 1477                 if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > maxmtu)
 1478                         error = EINVAL;
 1479                 else {
 1480                         ifp->if_mtu = ifr->ifr_mtu;
 1481 
 1482                         /* Make sure the device notices the MTU change. */
 1483                         if (ifp->if_flags & IFF_UP)
 1484                                 error = (*ifp->if_init)(ifp);
 1485                 }
 1486                 break;
 1487             }
 1488 
 1489         case SIOCSIFFLAGS:
 1490                 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_RUNNING) {
 1491                         /*
 1492                          * If interface is marked down and it is running,
 1493                          * then stop and disable it.
 1494                          */
 1495                         (*ifp->if_stop)(ifp, 1);
 1496                 } else if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_UP) {
 1497                         /*
 1498                          * If interface is marked up and it is stopped, then
 1499                          * start it.
 1500                          */
 1501                         error = (*ifp->if_init)(ifp);
 1502                 } else if ((ifp->if_flags & IFF_UP) != 0) {
 1503                         /*
 1504                          * Reset the interface to pick up changes in any other
 1505                          * flags that affect the hardware state.
 1506                          */
 1507                         error = (*ifp->if_init)(ifp);
 1508                 }
 1509                 break;
 1510 
 1511         case SIOCADDMULTI:
 1512                 error = ether_addmulti(ifr, ec);
 1513                 break;
 1514 
 1515         case SIOCDELMULTI:
 1516                 error = ether_delmulti(ifr, ec);
 1517                 break;
 1518 
 1519         default:
 1520                 error = ENOTTY;
 1521         }
 1522 
 1523         return (error);
 1524 }

Cache object: 6fe4e6985b92ce52fe728c2cabc716f6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.