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/bsd/net/ether_if_module.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 /*
    2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_LICENSE_HEADER_START@
    5  * 
    6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
    7  * 
    8  * This file contains Original Code and/or Modifications of Original Code
    9  * as defined in and that are subject to the Apple Public Source License
   10  * Version 2.0 (the 'License'). You may not use this file except in
   11  * compliance with the License. Please obtain a copy of the License at
   12  * http://www.opensource.apple.com/apsl/ and read it before using this
   13  * file.
   14  * 
   15  * The Original Code and all software distributed under the License are
   16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   20  * Please see the License for the specific language governing rights and
   21  * limitations under the License.
   22  * 
   23  * @APPLE_LICENSE_HEADER_END@
   24  */
   25 /*
   26  * Copyright (c) 1982, 1989, 1993
   27  *      The Regents of the University of California.  All rights reserved.
   28  *
   29  * Redistribution and use in source and binary forms, with or without
   30  * modification, are permitted provided that the following conditions
   31  * are met:
   32  * 1. Redistributions of source code must retain the above copyright
   33  *    notice, this list of conditions and the following disclaimer.
   34  * 2. Redistributions in binary form must reproduce the above copyright
   35  *    notice, this list of conditions and the following disclaimer in the
   36  *    documentation and/or other materials provided with the distribution.
   37  * 3. All advertising materials mentioning features or use of this software
   38  *    must display the following acknowledgement:
   39  *      This product includes software developed by the University of
   40  *      California, Berkeley and its contributors.
   41  * 4. Neither the name of the University nor the names of its contributors
   42  *    may be used to endorse or promote products derived from this software
   43  *    without specific prior written permission.
   44  *
   45  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   46  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   47  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   48  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   49  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   50  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   51  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   52  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   53  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   54  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   55  * SUCH DAMAGE.
   56  *
   57  */
   58 
   59 
   60 
   61 #include <sys/param.h>
   62 #include <sys/systm.h>
   63 #include <sys/kernel.h>
   64 #include <sys/malloc.h>
   65 #include <sys/mbuf.h>
   66 #include <sys/socket.h>
   67 #include <sys/sockio.h>
   68 #include <sys/sysctl.h>
   69 
   70 #include <net/if.h>
   71 #include <net/netisr.h>
   72 #include <net/route.h>
   73 #include <net/if_llc.h>
   74 #include <net/if_dl.h>
   75 #include <net/if_types.h>
   76 #include <netinet/if_ether.h>
   77 #include <netinet/in.h> /* For M_LOOP */
   78 
   79 /*
   80 #if INET
   81 #include <netinet/in.h>
   82 #include <netinet/in_var.h>
   83 
   84 #include <netinet/in_systm.h>
   85 #include <netinet/ip.h>
   86 #endif
   87 */
   88 
   89 #include <sys/socketvar.h>
   90 
   91 #include <net/dlil.h>
   92 
   93 
   94 #if LLC && CCITT
   95 extern struct ifqueue pkintrq;
   96 #endif
   97 
   98 /* General stuff from if_ethersubr.c - may not need some of it */
   99 
  100 #include <netat/at_pat.h>
  101 #if NETAT
  102 extern struct ifqueue atalkintrq;
  103 #endif
  104 
  105 
  106 #if BRIDGE
  107 #include <net/bridge.h>
  108 #endif
  109 
  110 /* #include "vlan.h" */
  111 #if NVLAN > 0
  112 #include <net/if_vlan_var.h>
  113 #endif /* NVLAN > 0 */
  114 
  115 static u_long lo_dlt = 0;
  116 
  117 #define IFP2AC(IFP) ((struct arpcom *)IFP)
  118 
  119 struct en_desc {
  120     u_int16_t           type;           /* Type of protocol stored in data */
  121     struct if_proto *proto;             /* Protocol structure */
  122     u_long                      data[2];        /* Protocol data */
  123 };
  124 
  125 #define ETHER_DESC_BLK_SIZE (10)
  126 #define MAX_INTERFACES 50
  127 
  128 /*
  129  * Statics for demux module
  130  */
  131 
  132 struct ether_desc_blk_str {
  133     u_long  n_max_used;
  134     u_long      n_count;
  135     struct en_desc  *block_ptr;
  136 };
  137 
  138 
  139 static struct ether_desc_blk_str ether_desc_blk[MAX_INTERFACES];
  140 
  141 
  142 /* from if_ethersubr.c */
  143 int ether_resolvemulti __P((struct ifnet *, struct sockaddr **,
  144                                     struct sockaddr *));
  145 
  146 /*
  147  * Release all descriptor entries owned by this dl_tag (there may be several).
  148  * Setting the type to 0 releases the entry. Eventually we should compact-out
  149  * the unused entries.
  150  */
  151 static
  152 int  ether_del_proto(struct if_proto *proto, u_long dl_tag)
  153 {
  154     struct en_desc*     ed = ether_desc_blk[proto->ifp->family_cookie].block_ptr;
  155     u_long      current = 0;
  156     int found = 0;
  157     
  158     for (current = ether_desc_blk[proto->ifp->family_cookie].n_max_used;
  159             current > 0; current--) {
  160         if (ed[current - 1].proto == proto) {
  161             found = 1;
  162             ed[current - 1].type = 0;
  163             
  164             if (current == ether_desc_blk[proto->ifp->family_cookie].n_max_used) {
  165                 ether_desc_blk[proto->ifp->family_cookie].n_max_used--;
  166             }
  167         }
  168     }
  169     
  170     return found;
  171  }
  172 
  173 
  174 
  175 static int
  176 ether_add_proto(struct ddesc_head_str *desc_head, struct if_proto *proto, u_long dl_tag)
  177 {
  178    char *current_ptr;
  179    struct dlil_demux_desc  *desc;
  180    struct en_desc          *ed;
  181    struct en_desc *last;
  182    u_long                  *bitmask;
  183    u_long                  *proto_id;
  184    u_long                  i;
  185    short                   total_length;
  186    u_long                  block_count;
  187    u_long                  *tmp;
  188 
  189 
  190     TAILQ_FOREACH(desc, desc_head, next) {
  191         switch (desc->type) {
  192             /* These types are supported */
  193             /* Top three are preferred */
  194             case DLIL_DESC_ETYPE2:
  195                 if (desc->variants.native_type_length != 2)
  196                     return EINVAL;
  197                 break;
  198                 
  199             case DLIL_DESC_SAP:
  200                 if (desc->variants.native_type_length != 3)
  201                     return EINVAL;
  202                 break;
  203                 
  204             case DLIL_DESC_SNAP:
  205                 if (desc->variants.native_type_length != 5)
  206                     return EINVAL;
  207                 break;
  208                 
  209             case DLIL_DESC_802_2:
  210             case DLIL_DESC_802_2_SNAP:
  211                 break;
  212             
  213             case DLIL_DESC_RAW:
  214                 if (desc->variants.bitmask.proto_id_length == 0)
  215                     break;
  216                 /* else fall through, bitmask variant not supported */
  217             
  218             default:
  219                 ether_del_proto(proto, dl_tag);
  220                 return EINVAL;
  221         }
  222     
  223     restart:
  224         ed = ether_desc_blk[proto->ifp->family_cookie].block_ptr;
  225         
  226         /* Find a free entry */
  227         for (i = 0; i < ether_desc_blk[proto->ifp->family_cookie].n_count; i++) {
  228             if (ed[i].type == 0) {
  229                 break;
  230             }
  231         }
  232         
  233         if (i >= ether_desc_blk[proto->ifp->family_cookie].n_count) {
  234             u_long      new_count = ETHER_DESC_BLK_SIZE +
  235                         ether_desc_blk[proto->ifp->family_cookie].n_count;
  236             tmp = _MALLOC((new_count * (sizeof(*ed))), M_IFADDR, M_WAITOK);
  237             if (tmp  == 0) {
  238                 /*
  239                 * Remove any previous descriptors set in the call.
  240                 */
  241                 ether_del_proto(proto, dl_tag);
  242                 return ENOMEM;
  243             }
  244             
  245             bzero(tmp, new_count * sizeof(*ed));
  246             bcopy(ether_desc_blk[proto->ifp->family_cookie].block_ptr, 
  247                 tmp, ether_desc_blk[proto->ifp->family_cookie].n_count * sizeof(*ed));
  248             FREE(ether_desc_blk[proto->ifp->family_cookie].block_ptr, M_IFADDR);
  249             ether_desc_blk[proto->ifp->family_cookie].n_count = new_count;
  250             ether_desc_blk[proto->ifp->family_cookie].block_ptr = (struct en_desc*)tmp;
  251         }
  252         
  253         /* Bump n_max_used if appropriate */
  254         if (i + 1 > ether_desc_blk[proto->ifp->family_cookie].n_max_used) {
  255             ether_desc_blk[proto->ifp->family_cookie].n_max_used = i + 1;
  256         }
  257         
  258         ed[i].proto     = proto;
  259         ed[i].data[0] = 0;
  260         ed[i].data[1] = 0;
  261         
  262         switch (desc->type) {
  263             case DLIL_DESC_RAW:
  264                 /* 2 byte ethernet raw protocol type is at native_type */
  265                 /* protocol is not in network byte order */
  266                 ed[i].type = DLIL_DESC_ETYPE2;
  267                 ed[i].data[0] = htons(*(u_int16_t*)desc->native_type);
  268                 break;
  269                 
  270             case DLIL_DESC_ETYPE2:
  271                 /* 2 byte ethernet raw protocol type is at native_type */
  272                 /* prtocol must be in network byte order */
  273                 ed[i].type = DLIL_DESC_ETYPE2;
  274                 ed[i].data[0] = *(u_int16_t*)desc->native_type;
  275                 break;
  276             
  277             case DLIL_DESC_802_2:
  278                 ed[i].type = DLIL_DESC_SAP;
  279                 ed[i].data[0] = *(u_int32_t*)&desc->variants.desc_802_2;
  280                 ed[i].data[0] &= htonl(0xFFFFFF00);
  281                 break;
  282             
  283             case DLIL_DESC_SAP:
  284                 ed[i].type = DLIL_DESC_SAP;
  285                 bcopy(desc->native_type, &ed[i].data[0], 3);
  286                 break;
  287     
  288             case DLIL_DESC_802_2_SNAP:
  289                 ed[i].type = DLIL_DESC_SNAP;
  290                 desc->variants.desc_802_2_SNAP.protocol_type =
  291                     htons(desc->variants.desc_802_2_SNAP.protocol_type);
  292                 bcopy(&desc->variants.desc_802_2_SNAP, &ed[i].data[0], 8);
  293                 ed[i].data[0] &= htonl(0x000000FF);
  294                 desc->variants.desc_802_2_SNAP.protocol_type =
  295                     ntohs(desc->variants.desc_802_2_SNAP.protocol_type);
  296                 break;
  297             
  298             case DLIL_DESC_SNAP: {
  299                 u_int8_t*       pDest = ((u_int8_t*)&ed[i].data[0]) + 3;
  300                 ed[i].type = DLIL_DESC_SNAP;
  301                 bcopy(desc->native_type, pDest, 5);
  302             }
  303             break;
  304         }
  305     }
  306     
  307     return 0;
  308 } 
  309 
  310 
  311 static
  312 int  ether_shutdown()
  313 {
  314     return 0;
  315 }
  316 
  317 
  318 int ether_demux(ifp, m, frame_header, proto)
  319     struct ifnet *ifp;
  320     struct mbuf  *m;
  321     char         *frame_header;
  322     struct if_proto **proto;
  323 
  324 {
  325     register struct ether_header *eh = (struct ether_header *)frame_header;
  326     u_short                     ether_type = eh->ether_type;
  327     u_int16_t           type;
  328     u_int8_t            *data;
  329     u_long                      i = 0;
  330     u_long                      max = ether_desc_blk[ifp->family_cookie].n_max_used;
  331     struct en_desc      *ed = ether_desc_blk[ifp->family_cookie].block_ptr;
  332     u_int32_t           extProto1 = 0;
  333     u_int32_t           extProto2 = 0;
  334     
  335     if (eh->ether_dhost[0] & 1) {
  336         /* Check for broadcast */
  337         if (*(u_int32_t*)eh->ether_dhost == 0xFFFFFFFF &&
  338             *(u_int16_t*)(eh->ether_dhost + sizeof(u_int32_t)) == 0xFFFF)
  339             m->m_flags |= M_BCAST;
  340         else
  341             m->m_flags |= M_MCAST;
  342     } else {
  343         /*
  344          * When the driver is put into promiscuous mode we may receive unicast
  345          * frames that are not intended for our interfaces.  They are filtered
  346          * here to keep them from traveling further up the stack to code that
  347          * is not expecting them or prepared to deal with them.  In the near
  348          * future, the filtering done here will be moved even further down the
  349          * stack into the IONetworkingFamily, preventing even interface
  350          * filter NKE's from receiving promiscuous packets.  Please use BPF.
  351          */
  352         #define ETHER_CMP(x, y) ( ((u_int16_t *) x)[0] != ((u_int16_t *) y)[0] || \
  353                                   ((u_int16_t *) x)[1] != ((u_int16_t *) y)[1] || \
  354                                   ((u_int16_t *) x)[2] != ((u_int16_t *) y)[2] )
  355     
  356         if (ETHER_CMP(eh->ether_dhost, ((struct arpcom *) ifp)->ac_enaddr)) {
  357             m_freem(m);
  358             return EJUSTRETURN;
  359         }
  360     }
  361     
  362     data = mtod(m, u_int8_t*);
  363     
  364     /*
  365      * Determine the packet's protocol type and stuff the protocol into
  366      * longs for quick compares.
  367      */
  368     
  369     if (ntohs(ether_type) <= 1500) {
  370         extProto1 = *(u_int32_t*)data;
  371         
  372         // SAP or SNAP
  373         if ((extProto1 & htonl(0xFFFFFF00)) == htonl(0xAAAA0300)) {
  374             // SNAP
  375             type = DLIL_DESC_SNAP;
  376             extProto2 = *(u_int32_t*)(data + sizeof(u_int32_t));
  377             extProto1 &= htonl(0x000000FF);
  378         } else {
  379             type = DLIL_DESC_SAP;
  380             extProto1 &= htonl(0xFFFFFF00);
  381         }
  382     } else {
  383         type = DLIL_DESC_ETYPE2;
  384     }
  385     
  386     /* 
  387      * Search through the connected protocols for a match. 
  388      */
  389     
  390     switch (type) {
  391         case DLIL_DESC_ETYPE2:
  392             for (i = 0; i < max; i++) {
  393                 if ((ed[i].type == type) && (ed[i].data[0] == ether_type)) {
  394                     *proto = ed[i].proto;
  395                     return 0;
  396                 }
  397             }
  398             break;
  399         
  400         case DLIL_DESC_SAP:
  401             for (i = 0; i < max; i++) {
  402                 if ((ed[i].type == type) && (ed[i].data[0] == extProto1)) {
  403                     *proto = ed[i].proto;
  404                     return 0;
  405                 }
  406             }
  407             break;
  408         
  409         case DLIL_DESC_SNAP:
  410             for (i = 0; i < max; i++) {
  411                 if ((ed[i].type == type) && (ed[i].data[0] == extProto1) &&
  412                     (ed[i].data[1] == extProto2)) {
  413                     *proto = ed[i].proto;
  414                     return 0;
  415                 }
  416             }
  417             break;
  418     }
  419     
  420     return ENOENT;
  421 }                       
  422 
  423 
  424 
  425 /*
  426  * Ethernet output routine.
  427  * Encapsulate a packet of type family for the local net.
  428  * Use trailer local net encapsulation if enough data in first
  429  * packet leaves a multiple of 512 bytes of data in remainder.
  430  * Assumes that ifp is actually pointer to arpcom structure.
  431  */
  432 int
  433 ether_frameout(ifp, m, ndest, edst, ether_type)
  434         register struct ifnet   *ifp;
  435         struct mbuf             **m;
  436         struct sockaddr         *ndest;
  437         char                    *edst;
  438         char                    *ether_type;
  439 {
  440         register struct ether_header *eh;
  441         int hlen;       /* link layer header lenght */
  442         struct arpcom *ac = IFP2AC(ifp);
  443 
  444 
  445         hlen = ETHER_HDR_LEN;
  446 
  447         /*
  448          * If a simplex interface, and the packet is being sent to our
  449          * Ethernet address or a broadcast address, loopback a copy.
  450          * XXX To make a simplex device behave exactly like a duplex
  451          * device, we should copy in the case of sending to our own
  452          * ethernet address (thus letting the original actually appear
  453          * on the wire). However, we don't do that here for security
  454          * reasons and compatibility with the original behavior.
  455          */
  456         if ((ifp->if_flags & IFF_SIMPLEX) &&
  457             ((*m)->m_flags & M_LOOP)) {
  458             if (lo_dlt == 0) 
  459             dlil_find_dltag(APPLE_IF_FAM_LOOPBACK, 0, PF_INET, &lo_dlt);
  460 
  461             if (lo_dlt) {
  462             if ((*m)->m_flags & M_BCAST) {
  463                 struct mbuf *n = m_copy(*m, 0, (int)M_COPYALL);
  464                 if (n != NULL)
  465                     dlil_output(lo_dlt, n, 0, ndest, 0);
  466             } 
  467             else 
  468             {
  469                 if (bcmp(edst,  ac->ac_enaddr, ETHER_ADDR_LEN) == 0) {
  470                     dlil_output(lo_dlt, *m, 0, ndest, 0);
  471                     return EJUSTRETURN;
  472                 }
  473             }
  474             }
  475         }
  476     
  477     
  478         /*
  479          * Add local net header.  If no space in first mbuf,
  480          * allocate another.
  481          */
  482         M_PREPEND(*m, sizeof (struct ether_header), M_DONTWAIT);
  483         if (*m == 0) {
  484             return (EJUSTRETURN);
  485         }
  486 
  487 
  488         eh = mtod(*m, struct ether_header *);
  489         (void)memcpy(&eh->ether_type, ether_type,
  490                 sizeof(eh->ether_type));
  491         (void)memcpy(eh->ether_dhost, edst, 6);
  492         (void)memcpy(eh->ether_shost, ac->ac_enaddr,
  493             sizeof(eh->ether_shost));
  494 
  495         return 0;
  496 }
  497 
  498 
  499 static
  500 int  ether_add_if(struct ifnet *ifp)
  501 {
  502     u_long  i;
  503 
  504     ifp->if_framer = ether_frameout;
  505     ifp->if_demux  = ether_demux;
  506     ifp->if_event  = 0;
  507     ifp->if_resolvemulti = ether_resolvemulti;
  508 
  509     for (i=0; i < MAX_INTERFACES; i++)
  510         if (ether_desc_blk[i].n_count == 0)
  511             break;
  512 
  513     if (i == MAX_INTERFACES)
  514         return ENOMEM;
  515 
  516     ether_desc_blk[i].block_ptr = _MALLOC(ETHER_DESC_BLK_SIZE * sizeof(struct en_desc),
  517                                             M_IFADDR, M_WAITOK);
  518     if (ether_desc_blk[i].block_ptr == 0)
  519         return ENOMEM;
  520 
  521     ether_desc_blk[i].n_count = ETHER_DESC_BLK_SIZE;
  522     bzero(ether_desc_blk[i].block_ptr, ETHER_DESC_BLK_SIZE * sizeof(struct en_desc));
  523 
  524     ifp->family_cookie = i;
  525     
  526     return 0;
  527 }
  528 
  529 static
  530 int  ether_del_if(struct ifnet *ifp)
  531 {
  532     if ((ifp->family_cookie < MAX_INTERFACES) &&
  533         (ether_desc_blk[ifp->family_cookie].n_count))
  534     {
  535         FREE(ether_desc_blk[ifp->family_cookie].block_ptr, M_IFADDR);
  536         ether_desc_blk[ifp->family_cookie].block_ptr = NULL;
  537         ether_desc_blk[ifp->family_cookie].n_count = 0;
  538         ether_desc_blk[ifp->family_cookie].n_max_used = 0;
  539         return 0;
  540     }
  541     else
  542         return ENOENT;
  543 }
  544 
  545 static
  546 int  ether_init_if(struct ifnet *ifp)
  547 {
  548     register struct ifaddr *ifa;
  549     register struct sockaddr_dl *sdl;
  550 
  551     ifa = ifnet_addrs[ifp->if_index - 1];
  552     if (ifa == 0) {
  553             printf("ether_ifattach: no lladdr!\n");
  554             return;
  555     }
  556     sdl = (struct sockaddr_dl *)ifa->ifa_addr;
  557     sdl->sdl_type = IFT_ETHER;
  558     sdl->sdl_alen = ifp->if_addrlen;
  559     bcopy((IFP2AC(ifp))->ac_enaddr, LLADDR(sdl), ifp->if_addrlen);
  560 
  561     return 0;
  562 }
  563 
  564 
  565 int
  566 ether_ifmod_ioctl(ifp, command, data)
  567     struct ifnet *ifp;
  568     u_long       command;
  569     caddr_t      data;
  570 {
  571     struct rslvmulti_req *rsreq = (struct rslvmulti_req *) data;
  572     int error = 0;
  573     struct sockaddr_dl *sdl;
  574     struct sockaddr_in *sin;
  575     u_char *e_addr;
  576 
  577 
  578     switch (command) {
  579         case SIOCRSLVMULTI: 
  580         switch(rsreq->sa->sa_family) {
  581             case AF_UNSPEC:
  582                 /* AppleTalk uses AF_UNSPEC for multicast registration.
  583                  * No mapping needed. Just check that it's a valid MC address.
  584                  */
  585                 e_addr = &rsreq->sa->sa_data[0];
  586                 if ((e_addr[0] & 1) != 1)
  587                     return EADDRNOTAVAIL;
  588                 *rsreq->llsa = 0;
  589                 return EJUSTRETURN;
  590             
  591             
  592             case AF_LINK:
  593                 /* 
  594                  * No mapping needed. Just check that it's a valid MC address.
  595                  */
  596                 sdl = (struct sockaddr_dl *)rsreq->sa;
  597                 e_addr = LLADDR(sdl);
  598                 if ((e_addr[0] & 1) != 1)
  599                     return EADDRNOTAVAIL;
  600                 *rsreq->llsa = 0;
  601                 return EJUSTRETURN;
  602                 
  603             default:
  604                 return EAFNOSUPPORT;
  605         }
  606         
  607         default:
  608             return EOPNOTSUPP;
  609     }
  610 }
  611 
  612 
  613 extern int ether_attach_inet(struct ifnet *ifp, u_long *dl_tag);
  614 extern int ether_detach_inet(struct ifnet *ifp, u_long dl_tag);
  615 extern int ether_attach_inet6(struct ifnet *ifp, u_long *dl_tag);
  616 extern int ether_detach_inet6(struct ifnet *ifp, u_long dl_tag);
  617 int ether_family_init()
  618 {
  619     int  i, error=0;
  620     struct dlil_ifmod_reg_str  ifmod_reg;
  621     struct dlil_protomod_reg_str enet_protoreg;
  622 
  623     /* ethernet family is built-in, called from bsd_init */
  624     thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
  625 
  626     bzero(&ifmod_reg, sizeof(ifmod_reg));
  627     ifmod_reg.add_if = ether_add_if;
  628     ifmod_reg.del_if = ether_del_if;
  629     ifmod_reg.init_if = ether_init_if;
  630     ifmod_reg.add_proto = ether_add_proto;
  631     ifmod_reg.del_proto = ether_del_proto;
  632     ifmod_reg.ifmod_ioctl = ether_ifmod_ioctl;
  633     ifmod_reg.shutdown    = ether_shutdown;
  634 
  635     if (dlil_reg_if_modules(APPLE_IF_FAM_ETHERNET, &ifmod_reg)) {
  636         printf("WARNING: ether_family_init -- Can't register if family modules\n");
  637         return EIO;
  638     }
  639 
  640     for (i=0; i < MAX_INTERFACES; i++)
  641         ether_desc_blk[i].n_count = 0;
  642 
  643         /* Register protocol registration functions */
  644 
  645         bzero(&enet_protoreg, sizeof(enet_protoreg));
  646         enet_protoreg.attach_proto = ether_attach_inet;
  647         enet_protoreg.detach_proto = ether_detach_inet;
  648         
  649         if ( error = dlil_reg_proto_module(PF_INET, APPLE_IF_FAM_ETHERNET, &enet_protoreg) != 0)
  650                 kprintf("dlil_reg_proto_module failed for AF_INET6 error=%d\n", error);
  651 
  652 
  653         enet_protoreg.attach_proto = ether_attach_inet6;
  654         enet_protoreg.detach_proto = ether_detach_inet6;
  655         
  656         if ( error = dlil_reg_proto_module(PF_INET6, APPLE_IF_FAM_ETHERNET, &enet_protoreg) != 0)
  657                 kprintf("dlil_reg_proto_module failed for AF_INET6 error=%d\n", error);
  658 
  659     thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
  660 
  661     return (error);
  662 }

Cache object: 95e9c510c588f78ca7026fcfe0809a4d


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