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

Cache object: 43915d11257af98e11b28f873fb20110


[ 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.