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_fddisubr.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) 1995, 1996
    3  *      Matt Thomas <matt@3am-software.com>.  All rights reserved.
    4  * Copyright (c) 1982, 1989, 1993
    5  *      The Regents of the University of California.  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. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by the University of
   18  *      California, Berkeley and its contributors.
   19  * 4. Neither the name of the University nor the names of its contributors
   20  *    may be used to endorse or promote products derived from this software
   21  *    without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  *
   35  *      from: if_ethersubr.c,v 1.5 1994/12/13 22:31:45 wollman Exp
   36  * $FreeBSD$
   37  */
   38 
   39 #include "opt_atalk.h"
   40 #include "opt_inet.h"
   41 #include "opt_ipx.h"
   42 
   43 #include <sys/param.h>
   44 #include <sys/systm.h>
   45 #include <sys/mbuf.h>
   46 #include <sys/socket.h>
   47 
   48 #include <net/if.h>
   49 #include <net/netisr.h>
   50 #include <net/route.h>
   51 #include <net/if_llc.h>
   52 #include <net/if_dl.h>
   53 #include <net/if_types.h>
   54 
   55 #ifdef INET
   56 #include <netinet/in.h>
   57 #include <netinet/in_var.h>
   58 #include <netinet/if_ether.h>
   59 #endif
   60 #if defined(__FreeBSD__)
   61 #include <netinet/if_fddi.h>
   62 #else
   63 #include <net/if_fddi.h>
   64 #endif
   65 
   66 #ifdef IPX
   67 #include <netipx/ipx.h> 
   68 #include <netipx/ipx_if.h>
   69 #endif
   70 
   71 #ifdef NS
   72 #include <netns/ns.h>
   73 #include <netns/ns_if.h>
   74 #endif
   75 
   76 #ifdef DECNET
   77 #include <netdnet/dn.h>
   78 #endif
   79 
   80 #ifdef ISO
   81 #include <netiso/argo_debug.h>
   82 #include <netiso/iso.h>
   83 #include <netiso/iso_var.h>
   84 #include <netiso/iso_snpac.h>
   85 #endif
   86 
   87 #ifdef LLC
   88 #include <netccitt/dll.h>
   89 #include <netccitt/llc_var.h>
   90 #endif
   91 
   92 #ifdef NETATALK
   93 #include <netatalk/at.h>
   94 #include <netatalk/at_var.h>
   95 #include <netatalk/at_extern.h>
   96 
   97 #define llc_snap_org_code llc_un.type_snap.org_code
   98 #define llc_snap_ether_type llc_un.type_snap.ether_type
   99 
  100 extern u_char   at_org_code[ 3 ];
  101 extern u_char   aarp_org_code[ 3 ];
  102 #endif /* NETATALK */
  103 
  104 #if defined(LLC) && defined(CCITT)
  105 extern struct ifqueue pkintrq;
  106 #endif
  107 
  108 #include "bpfilter.h"
  109 
  110 #define senderr(e) { error = (e); goto bad;}
  111 
  112 /*
  113  * This really should be defined in if_llc.h but in case it isn't.
  114  */
  115 #ifndef llc_snap
  116 #define llc_snap        llc_un.type_snap
  117 #endif
  118 
  119 #if defined(__bsdi__) || defined(__NetBSD__)
  120 #define RTALLOC1(a, b)                  rtalloc1(a, b)
  121 #define ARPRESOLVE(a, b, c, d, e, f)    arpresolve(a, b, c, d, e)
  122 #elif defined(__FreeBSD__)
  123 #define RTALLOC1(a, b)                  rtalloc1(a, b, 0UL)
  124 #define ARPRESOLVE(a, b, c, d, e, f)    arpresolve(a, b, c, d, e, f)
  125 #endif
  126 /*
  127  * FDDI output routine.
  128  * Encapsulate a packet of type family for the local net.
  129  * Use trailer local net encapsulation if enough data in first
  130  * packet leaves a multiple of 512 bytes of data in remainder.
  131  * Assumes that ifp is actually pointer to arpcom structure.
  132  */
  133 int
  134 fddi_output(ifp, m0, dst, rt0)
  135         register struct ifnet *ifp;
  136         struct mbuf *m0;
  137         struct sockaddr *dst;
  138         struct rtentry *rt0;
  139 {
  140         u_int16_t type;
  141         int s, loop_copy = 0, error = 0;
  142         u_char edst[6];
  143         register struct mbuf *m = m0;
  144         register struct rtentry *rt;
  145         register struct fddi_header *fh;
  146         struct arpcom *ac = (struct arpcom *)ifp;
  147 
  148         if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
  149                 senderr(ENETDOWN);
  150         getmicrotime(&ifp->if_lastchange);
  151 #if !defined(__bsdi__) || _BSDI_VERSION >= 199401
  152         if (rt = rt0) {
  153                 if ((rt->rt_flags & RTF_UP) == 0) {
  154                         if (rt0 = rt = RTALLOC1(dst, 1))
  155                                 rt->rt_refcnt--;
  156                         else 
  157                                 senderr(EHOSTUNREACH);
  158                 }
  159                 if (rt->rt_flags & RTF_GATEWAY) {
  160                         if (rt->rt_gwroute == 0)
  161                                 goto lookup;
  162                         if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
  163                                 rtfree(rt); rt = rt0;
  164                         lookup: rt->rt_gwroute = RTALLOC1(rt->rt_gateway, 1);
  165                                 if ((rt = rt->rt_gwroute) == 0)
  166                                         senderr(EHOSTUNREACH);
  167                         }
  168                 }
  169                 if (rt->rt_flags & RTF_REJECT)
  170                         if (rt->rt_rmx.rmx_expire == 0 ||
  171                             time_second < rt->rt_rmx.rmx_expire)
  172                                 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
  173         }
  174 #endif
  175         switch (dst->sa_family) {
  176 
  177 #ifdef INET
  178         case AF_INET: {
  179 #if !defined(__bsdi__) || _BSDI_VERSION >= 199401
  180                 if (!ARPRESOLVE(ac, rt, m, dst, edst, rt0))
  181                         return (0);     /* if not yet resolved */
  182 #else
  183                 int usetrailers;
  184                 if (!arpresolve(ac, m, &((struct sockaddr_in *)dst)->sin_addr, edst, &usetrailers))
  185                         return (0);     /* if not yet resolved */
  186 #endif
  187                 type = htons(ETHERTYPE_IP);
  188                 break;
  189         }
  190 #endif
  191 #ifdef IPX
  192         case AF_IPX:
  193                 type = htons(ETHERTYPE_IPX);
  194                 bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host),
  195                     (caddr_t)edst, sizeof (edst));
  196                 break;
  197 #endif
  198 #ifdef NETATALK
  199         case AF_APPLETALK: {
  200             struct at_ifaddr *aa;
  201             if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst))
  202                 return (0);
  203             /*
  204              * ifaddr is the first thing in at_ifaddr
  205              */
  206             if ((aa = at_ifawithnet( (struct sockaddr_at *)dst)) == 0)
  207                 goto bad;
  208             
  209             /*
  210              * In the phase 2 case, we need to prepend an mbuf for the llc header.
  211              * Since we must preserve the value of m, which is passed to us by
  212              * value, we m_copy() the first mbuf, and use it for our llc header.
  213              */
  214             if (aa->aa_flags & AFA_PHASE2) {
  215                 struct llc llc;
  216 
  217                 M_PREPEND(m, sizeof(struct llc), M_WAIT);
  218                 if (m == 0)
  219                         senderr(ENOBUFS);
  220                 llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
  221                 llc.llc_control = LLC_UI;
  222                 bcopy(at_org_code, llc.llc_snap_org_code, sizeof(at_org_code));
  223                 llc.llc_snap_ether_type = htons(ETHERTYPE_AT);
  224                 bcopy(&llc, mtod(m, caddr_t), sizeof(struct llc));
  225                 type = 0;
  226             } else {
  227                 type = htons(ETHERTYPE_AT);
  228             }
  229             break;
  230         }
  231 #endif /* NETATALK */
  232 #ifdef NS
  233         case AF_NS:
  234                 type = htons(ETHERTYPE_NS);
  235                 bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
  236                     (caddr_t)edst, sizeof (edst));
  237                 break;
  238 #endif
  239 #ifdef  ISO
  240         case AF_ISO: {
  241                 int     snpalen;
  242                 struct  llc *l;
  243                 register struct sockaddr_dl *sdl;
  244 
  245                 if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) &&
  246                     sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) {
  247                         bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst));
  248                 } else if (error =
  249                             iso_snparesolve(ifp, (struct sockaddr_iso *)dst,
  250                                             (char *)edst, &snpalen))
  251                         goto bad; /* Not Resolved */
  252                 /* If broadcasting on a simplex interface, loopback a copy */
  253                 if (*edst & 1)
  254                         m->m_flags |= (M_BCAST|M_MCAST);
  255                 M_PREPEND(m, 3, M_DONTWAIT);
  256                 if (m == NULL)
  257                         return (0);
  258                 type = 0;
  259                 l = mtod(m, struct llc *);
  260                 l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
  261                 l->llc_control = LLC_UI;
  262                 IFDEBUG(D_ETHER)
  263                         int i;
  264                         printf("unoutput: sending pkt to: ");
  265                         for (i=0; i<6; i++)
  266                                 printf("%x ", edst[i] & 0xff);
  267                         printf("\n");
  268                 ENDDEBUG
  269                 } break;
  270 #endif /* ISO */
  271 #ifdef  LLC
  272 /*      case AF_NSAP: */
  273         case AF_CCITT: {
  274                 register struct sockaddr_dl *sdl = 
  275                         (struct sockaddr_dl *) rt -> rt_gateway;
  276 
  277                 if (sdl && sdl->sdl_family != AF_LINK && sdl->sdl_alen <= 0)
  278                         goto bad; /* Not a link interface ? Funny ... */
  279                 bcopy(LLADDR(sdl), (char *)edst, sizeof(edst));
  280                 if (*edst & 1)
  281                         loop_copy = 1;
  282                 type = 0;
  283 #ifdef LLC_DEBUG
  284                 {
  285                         int i;
  286                         register struct llc *l = mtod(m, struct llc *);
  287 
  288                         printf("fddi_output: sending LLC2 pkt to: ");
  289                         for (i=0; i<6; i++)
  290                                 printf("%x ", edst[i] & 0xff);
  291                         printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n", 
  292                                type & 0xff, l->llc_dsap & 0xff, l->llc_ssap &0xff,
  293                                l->llc_control & 0xff);
  294 
  295                 }
  296 #endif /* LLC_DEBUG */
  297                 } break;
  298 #endif /* LLC */        
  299 
  300         case AF_UNSPEC:
  301         {
  302                 struct ether_header *eh;
  303                 loop_copy = -1;
  304                 eh = (struct ether_header *)dst->sa_data;
  305                 (void)memcpy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst));
  306                 if (*edst & 1)
  307                         m->m_flags |= (M_BCAST|M_MCAST);
  308                 type = eh->ether_type;
  309                 break;
  310         }
  311 
  312 #if NBPFILTER > 0
  313         case AF_IMPLINK:
  314         {
  315                 fh = mtod(m, struct fddi_header *);
  316                 error = EPROTONOSUPPORT;
  317                 switch (fh->fddi_fc & (FDDIFC_C|FDDIFC_L|FDDIFC_F)) {
  318                         case FDDIFC_LLC_ASYNC: {
  319                                 /* legal priorities are 0 through 7 */
  320                                 if ((fh->fddi_fc & FDDIFC_Z) > 7)
  321                                         goto bad;
  322                                 break;
  323                         }
  324                         case FDDIFC_LLC_SYNC: {
  325                                 /* FDDIFC_Z bits reserved, must be zero */
  326                                 if (fh->fddi_fc & FDDIFC_Z)
  327                                         goto bad;
  328                                 break;
  329                         }
  330                         case FDDIFC_SMT: {
  331                                 /* FDDIFC_Z bits must be non zero */
  332                                 if ((fh->fddi_fc & FDDIFC_Z) == 0)
  333                                         goto bad;
  334                                 break;
  335                         }
  336                         default: {
  337                                 /* anything else is too dangerous */
  338                                 goto bad;
  339                         }
  340                 }
  341                 error = 0;
  342                 if (fh->fddi_dhost[0] & 1)
  343                         m->m_flags |= (M_BCAST|M_MCAST);
  344                 goto queue_it;
  345         }
  346 #endif
  347         default:
  348                 printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
  349                         dst->sa_family);
  350                 senderr(EAFNOSUPPORT);
  351         }
  352 
  353         if (type != 0) {
  354                 register struct llc *l;
  355                 M_PREPEND(m, sizeof (struct llc), M_DONTWAIT);
  356                 if (m == 0)
  357                         senderr(ENOBUFS);
  358                 l = mtod(m, struct llc *);
  359                 l->llc_control = LLC_UI;
  360                 l->llc_dsap = l->llc_ssap = LLC_SNAP_LSAP;
  361                 l->llc_snap.org_code[0] = l->llc_snap.org_code[1] = l->llc_snap.org_code[2] = 0;
  362                 (void)memcpy((caddr_t) &l->llc_snap.ether_type, (caddr_t) &type,
  363                         sizeof(u_int16_t));
  364         }
  365 
  366         /*
  367          * Add local net header.  If no space in first mbuf,
  368          * allocate another.
  369          */
  370         M_PREPEND(m, sizeof (struct fddi_header), M_DONTWAIT);
  371         if (m == 0)
  372                 senderr(ENOBUFS);
  373         fh = mtod(m, struct fddi_header *);
  374         fh->fddi_fc = FDDIFC_LLC_ASYNC|FDDIFC_LLC_PRIO4;
  375         (void)memcpy((caddr_t)fh->fddi_dhost, (caddr_t)edst, sizeof (edst));
  376   queue_it:
  377         (void)memcpy((caddr_t)fh->fddi_shost, (caddr_t)ac->ac_enaddr,
  378             sizeof(fh->fddi_shost));
  379 
  380         /*
  381          * If a simplex interface, and the packet is being sent to our
  382          * Ethernet address or a broadcast address, loopback a copy.
  383          * XXX To make a simplex device behave exactly like a duplex
  384          * device, we should copy in the case of sending to our own
  385          * ethernet address (thus letting the original actually appear
  386          * on the wire). However, we don't do that here for security
  387          * reasons and compatibility with the original behavior.
  388          */
  389         if ((ifp->if_flags & IFF_SIMPLEX) &&
  390            (loop_copy != -1)) {
  391                 if ((m->m_flags & M_BCAST) || loop_copy) {
  392                         struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
  393 
  394                         (void) if_simloop(ifp,
  395                                 n, dst, sizeof(struct fddi_header));
  396                 } else if (bcmp(fh->fddi_dhost,
  397                     fh->fddi_shost, sizeof(fh->fddi_shost)) == 0) {
  398                         (void) if_simloop(ifp,
  399                                 m, dst, sizeof(struct fddi_header));
  400                         return(0);      /* XXX */
  401                 }
  402         }
  403 
  404         s = splimp();
  405         /*
  406          * Queue message on interface, and start output if interface
  407          * not yet active.
  408          */
  409         if (IF_QFULL(&ifp->if_snd)) {
  410                 IF_DROP(&ifp->if_snd);
  411                 splx(s);
  412                 senderr(ENOBUFS);
  413         }
  414         ifp->if_obytes += m->m_pkthdr.len;
  415         IF_ENQUEUE(&ifp->if_snd, m);
  416         if ((ifp->if_flags & IFF_OACTIVE) == 0)
  417                 (*ifp->if_start)(ifp);
  418         splx(s);
  419         if (m->m_flags & M_MCAST)
  420                 ifp->if_omcasts++;
  421         return (error);
  422 
  423 bad:
  424         if (m)
  425                 m_freem(m);
  426         return (error);
  427 }
  428 
  429 /*
  430  * Process a received FDDI packet;
  431  * the packet is in the mbuf chain m without
  432  * the fddi header, which is provided separately.
  433  */
  434 void
  435 fddi_input(ifp, fh, m)
  436         struct ifnet *ifp;
  437         register struct fddi_header *fh;
  438         struct mbuf *m;
  439 {
  440         register struct ifqueue *inq;
  441         register struct llc *l;
  442         int s;
  443 
  444         if ((ifp->if_flags & IFF_UP) == 0) {
  445                 m_freem(m);
  446                 return;
  447         }
  448         getmicrotime(&ifp->if_lastchange);
  449         ifp->if_ibytes += m->m_pkthdr.len + sizeof (*fh);
  450         if (fh->fddi_dhost[0] & 1) {
  451                 if (bcmp((caddr_t)fddibroadcastaddr, (caddr_t)fh->fddi_dhost,
  452                     sizeof(fddibroadcastaddr)) == 0)
  453                         m->m_flags |= M_BCAST;
  454                 else
  455                         m->m_flags |= M_MCAST;
  456                 ifp->if_imcasts++;
  457         } else if ((ifp->if_flags & IFF_PROMISC)
  458             && bcmp(((struct arpcom *)ifp)->ac_enaddr, (caddr_t)fh->fddi_dhost,
  459                     sizeof(fh->fddi_dhost)) != 0) {
  460                 m_freem(m);
  461                 return;
  462         }
  463 
  464 #ifdef M_LINK0
  465         /*
  466          * If this has a LLC priority of 0, then mark it so upper
  467          * layers have a hint that it really came via a FDDI/Ethernet
  468          * bridge.
  469          */
  470         if ((fh->fddi_fc & FDDIFC_LLC_PRIO7) == FDDIFC_LLC_PRIO0)
  471                 m->m_flags |= M_LINK0;
  472 #endif
  473 
  474         l = mtod(m, struct llc *);
  475         switch (l->llc_dsap) {
  476 #if defined(INET) || defined(NS) || defined(DECNET) || defined(IPX) || defined(NETATALK)
  477         case LLC_SNAP_LSAP:
  478         {
  479                 u_int16_t type;
  480                 if (l->llc_control != LLC_UI || l->llc_ssap != LLC_SNAP_LSAP)
  481                         goto dropanyway;
  482 #ifdef NETATALK
  483                 if (Bcmp(&(l->llc_snap_org_code)[0], at_org_code,
  484                          sizeof(at_org_code)) == 0 &&
  485                         ntohs(l->llc_snap_ether_type) == ETHERTYPE_AT) {
  486                     inq = &atintrq2;
  487                     m_adj( m, sizeof( struct llc ));
  488                     schednetisr(NETISR_ATALK);
  489                     break;
  490                 }
  491 
  492                 if (Bcmp(&(l->llc_snap_org_code)[0], aarp_org_code,
  493                          sizeof(aarp_org_code)) == 0 &&
  494                         ntohs(l->llc_snap_ether_type) == ETHERTYPE_AARP) {
  495                     m_adj( m, sizeof( struct llc ));
  496                     aarpinput((struct arpcom *)ifp, m); /* XXX */
  497                     return;
  498                 }
  499 #endif /* NETATALK */
  500                 if (l->llc_snap.org_code[0] != 0 || l->llc_snap.org_code[1] != 0|| l->llc_snap.org_code[2] != 0)
  501                         goto dropanyway;
  502                 type = ntohs(l->llc_snap.ether_type);
  503                 m_adj(m, 8);
  504                 switch (type) {
  505 #ifdef INET
  506                 case ETHERTYPE_IP:
  507                         if (ipflow_fastforward(m))
  508                                 return;
  509                         schednetisr(NETISR_IP);
  510                         inq = &ipintrq;
  511                         break;
  512 
  513                 case ETHERTYPE_ARP:
  514 #if !defined(__bsdi__) || _BSDI_VERSION >= 199401
  515                         schednetisr(NETISR_ARP);
  516                         inq = &arpintrq;
  517                         break;
  518 #else
  519                         arpinput((struct arpcom *)ifp, m);
  520                         return;
  521 #endif
  522 #endif
  523 #ifdef IPX      
  524                 case ETHERTYPE_IPX: 
  525                         schednetisr(NETISR_IPX);
  526                         inq = &ipxintrq;
  527                         break;  
  528 #endif   
  529 #ifdef NS
  530                 case ETHERTYPE_NS:
  531                         schednetisr(NETISR_NS);
  532                         inq = &nsintrq;
  533                         break;
  534 #endif
  535 #ifdef DECNET
  536                 case ETHERTYPE_DECNET:
  537                         schednetisr(NETISR_DECNET);
  538                         inq = &decnetintrq;
  539                         break;
  540 #endif
  541 #ifdef NETATALK 
  542                 case ETHERTYPE_AT:
  543                         schednetisr(NETISR_ATALK);
  544                         inq = &atintrq1;
  545                         break;
  546                 case ETHERTYPE_AARP:
  547                         /* probably this should be done with a NETISR as well */
  548                         aarpinput((struct arpcom *)ifp, m); /* XXX */
  549                         return;
  550 #endif /* NETATALK */
  551                 default:
  552                         /* printf("fddi_input: unknown protocol 0x%x\n", type); */
  553                         ifp->if_noproto++;
  554                         goto dropanyway;
  555                 }
  556                 break;
  557         }
  558 #endif /* INET || NS */
  559 #ifdef  ISO
  560         case LLC_ISO_LSAP: 
  561                 switch (l->llc_control) {
  562                 case LLC_UI:
  563                         /* LLC_UI_P forbidden in class 1 service */
  564                         if ((l->llc_dsap == LLC_ISO_LSAP) &&
  565                             (l->llc_ssap == LLC_ISO_LSAP)) {
  566                                 /* LSAP for ISO */
  567                                 m->m_data += 3;         /* XXX */
  568                                 m->m_len -= 3;          /* XXX */
  569                                 m->m_pkthdr.len -= 3;   /* XXX */
  570                                 M_PREPEND(m, sizeof *fh, M_DONTWAIT);
  571                                 if (m == 0)
  572                                         return;
  573                                 *mtod(m, struct fddi_header *) = *fh;
  574                                 IFDEBUG(D_ETHER)
  575                                         printf("clnp packet");
  576                                 ENDDEBUG
  577                                 schednetisr(NETISR_ISO);
  578                                 inq = &clnlintrq;
  579                                 break;
  580                         }
  581                         goto dropanyway;
  582                         
  583                 case LLC_XID:
  584                 case LLC_XID_P:
  585                         if(m->m_len < 6)
  586                                 goto dropanyway;
  587                         l->llc_window = 0;
  588                         l->llc_fid = 9;
  589                         l->llc_class = 1;
  590                         l->llc_dsap = l->llc_ssap = 0;
  591                         /* Fall through to */
  592                 case LLC_TEST:
  593                 case LLC_TEST_P:
  594                 {
  595                         struct sockaddr sa;
  596                         register struct ether_header *eh;
  597                         struct arpcom *ac = (struct arpcom *) ifp;
  598                         int i;
  599                         u_char c = l->llc_dsap;
  600 
  601                         l->llc_dsap = l->llc_ssap;
  602                         l->llc_ssap = c;
  603                         if (m->m_flags & (M_BCAST | M_MCAST))
  604                                 bcopy((caddr_t)ac->ac_enaddr,
  605                                       (caddr_t)eh->ether_dhost, 6);
  606                         sa.sa_family = AF_UNSPEC;
  607                         sa.sa_len = sizeof(sa);
  608                         eh = (struct ether_header *)sa.sa_data;
  609                         for (i = 0; i < 6; i++) {
  610                                 eh->ether_shost[i] = fh->fddi_dhost[i];
  611                                 eh->ether_dhost[i] = fh->fddi_shost[i];
  612                         }
  613                         eh->ether_type = 0;
  614                         ifp->if_output(ifp, m, &sa, NULL);
  615                         return;
  616                 }
  617                 default:
  618                         m_freem(m);
  619                         return;
  620                 }
  621                 break;
  622 #endif /* ISO */
  623 #ifdef LLC
  624         case LLC_X25_LSAP:
  625         {
  626                 M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT);
  627                 if (m == 0)
  628                         return;
  629                 if ( !sdl_sethdrif(ifp, fh->fddi_shost, LLC_X25_LSAP,
  630                                     fh->fddi_dhost, LLC_X25_LSAP, 6, 
  631                                     mtod(m, struct sdl_hdr *)))
  632                         panic("ETHER cons addr failure");
  633                 mtod(m, struct sdl_hdr *)->sdlhdr_len = m->m_pkthdr.len - sizeof(struct sdl_hdr);
  634 #ifdef LLC_DEBUG
  635                 printf("llc packet\n");
  636 #endif /* LLC_DEBUG */
  637                 schednetisr(NETISR_CCITT);
  638                 inq = &llcintrq;
  639                 break;
  640         }
  641 #endif /* LLC */
  642                 
  643         default:
  644                 /* printf("fddi_input: unknown dsap 0x%x\n", l->llc_dsap); */
  645                 ifp->if_noproto++;
  646         dropanyway:
  647                 m_freem(m);
  648                 return;
  649         }
  650 
  651         s = splimp();
  652         if (IF_QFULL(inq)) {
  653                 IF_DROP(inq);
  654                 m_freem(m);
  655         } else
  656                 IF_ENQUEUE(inq, m);
  657         splx(s);
  658 }
  659 /*
  660  * Perform common duties while attaching to interface list
  661  */
  662 #ifdef __NetBSD__
  663 #define ifa_next        ifa_list.tqe_next
  664 #endif
  665 
  666 void
  667 fddi_ifattach(ifp)
  668         register struct ifnet *ifp;
  669 {
  670         register struct ifaddr *ifa;
  671         register struct sockaddr_dl *sdl;
  672 
  673         ifp->if_type = IFT_FDDI;
  674         ifp->if_addrlen = 6;
  675         ifp->if_hdrlen = 21;
  676         ifp->if_mtu = FDDIMTU;
  677         ifp->if_baudrate = 100000000;
  678 #ifdef IFF_NOTRAILERS
  679         ifp->if_flags |= IFF_NOTRAILERS;
  680 #endif
  681 #if defined(__FreeBSD__)
  682         ifa = ifnet_addrs[ifp->if_index - 1];
  683         sdl = (struct sockaddr_dl *)ifa->ifa_addr;
  684         sdl->sdl_type = IFT_FDDI;
  685         sdl->sdl_alen = ifp->if_addrlen;
  686         bcopy(((struct arpcom *)ifp)->ac_enaddr, LLADDR(sdl), ifp->if_addrlen);
  687 #elif defined(__NetBSD__)
  688         LIST_INIT(&((struct arpcom *)ifp)->ac_multiaddrs);
  689         for (ifa = ifp->if_addrlist.tqh_first; ifa != NULL; ifa = ifa->ifa_list.tqe_next)
  690 #else
  691         for (ifa = ifp->if_addrlist; ifa != NULL; ifa = ifa->ifa_next)
  692 #endif
  693 #if !defined(__FreeBSD__)
  694                 if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
  695                     sdl->sdl_family == AF_LINK) {
  696                         sdl->sdl_type = IFT_FDDI;
  697                         sdl->sdl_alen = ifp->if_addrlen;
  698                         bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
  699                               LLADDR(sdl), ifp->if_addrlen);
  700                         break;
  701                 }
  702 #endif
  703 }

Cache object: 9bb894dc3f680a3d4b8ae8f36c8a963a


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