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

Cache object: cb70299ffdf11013729075970fb1a9e5


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