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_tokensubr.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_tokensubr.c,v 1.54.10.1 2009/11/21 19:43:41 snj Exp $       */
    2 
    3 /*
    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. Neither the name of the University 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 REGENTS 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 REGENTS 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  *      from: NetBSD: if_fddisubr.c,v 1.2 1995/08/19 04:35:29 cgd Exp
   32  */
   33 
   34 /*
   35  * Copyright (c) 1997-1999 The NetBSD Foundation, Inc.
   36  * All rights reserved.
   37  *
   38  * This code is derived from software contributed to The NetBSD Foundation
   39  * by Onno van der Linden.
   40  *
   41  * Redistribution and use in source and binary forms, with or without
   42  * modification, are permitted provided that the following conditions
   43  * are met:
   44  * 1. Redistributions of source code must retain the above copyright
   45  *    notice, this list of conditions and the following disclaimer.
   46  * 2. Redistributions in binary form must reproduce the above copyright
   47  *    notice, this list of conditions and the following disclaimer in the
   48  *    documentation and/or other materials provided with the distribution.
   49  *
   50  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   51  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   52  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   53  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   54  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   55  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   56  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   57  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   58  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   59  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   60  * POSSIBILITY OF SUCH DAMAGE.
   61  */
   62 
   63 /*
   64  * Copyright (c) 1995
   65  *      Matt Thomas.  All rights reserved.
   66  *
   67  * Redistribution and use in source and binary forms, with or without
   68  * modification, are permitted provided that the following conditions
   69  * are met:
   70  * 1. Redistributions of source code must retain the above copyright
   71  *    notice, this list of conditions and the following disclaimer.
   72  * 2. Redistributions in binary form must reproduce the above copyright
   73  *    notice, this list of conditions and the following disclaimer in the
   74  *    documentation and/or other materials provided with the distribution.
   75  * 3. The names of its contributors may not be used to endorse or promote
   76  *    products derived from this software without specific prior written
   77  *    permission.
   78  *
   79  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   80  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   81  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   82  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   83  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   84  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   85  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   86  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   87  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   88  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   89  * SUCH DAMAGE.
   90  *
   91  *      from: NetBSD: if_fddisubr.c,v 1.2 1995/08/19 04:35:29 cgd Exp
   92  */
   93 
   94 #include <sys/cdefs.h>
   95 __KERNEL_RCSID(0, "$NetBSD: if_tokensubr.c,v 1.54.10.1 2009/11/21 19:43:41 snj Exp $");
   96 
   97 #include "opt_inet.h"
   98 #include "opt_atalk.h"
   99 #include "opt_iso.h"
  100 #include "opt_gateway.h"
  101 
  102 #include "bpfilter.h"
  103 
  104 #include <sys/param.h>
  105 #include <sys/systm.h>
  106 #include <sys/kernel.h>
  107 #include <sys/malloc.h>
  108 #include <sys/mbuf.h>
  109 #include <sys/protosw.h>
  110 #include <sys/socket.h>
  111 #include <sys/ioctl.h>
  112 #include <sys/errno.h>
  113 #include <sys/syslog.h>
  114 
  115 #include <sys/cpu.h>
  116 
  117 #include <net/if.h>
  118 #include <net/netisr.h>
  119 #include <net/route.h>
  120 #include <net/if_llc.h>
  121 #include <net/if_dl.h>
  122 #include <net/if_types.h>
  123 
  124 #if NBPFILTER > 0
  125 #include <net/bpf.h>
  126 #endif
  127 
  128 #include <net/if_ether.h>
  129 #include <net/if_token.h>
  130 
  131 #include "carp.h"
  132 #if NCARP > 0
  133 #include <netinet/ip_carp.h>
  134 #endif
  135 
  136 #ifdef INET
  137 #include <netinet/in.h>
  138 #include <netinet/in_var.h>
  139 #include <netinet/if_inarp.h>
  140 #endif
  141 
  142 
  143 #ifdef DECNET
  144 #include <netdnet/dn.h>
  145 #endif
  146 
  147 #ifdef ISO
  148 #include <netiso/argo_debug.h>
  149 #include <netiso/iso.h>
  150 #include <netiso/iso_var.h>
  151 #include <netiso/iso_snpac.h>
  152 #endif
  153 
  154 #include "bpfilter.h"
  155 
  156 #define senderr(e) { error = (e); goto bad;}
  157 
  158 #if defined(__bsdi__) || defined(__NetBSD__)
  159 #define RTALLOC1(a, b)                  rtalloc1(a, b)
  160 #define ARPRESOLVE(a, b, c, d, e, f)    arpresolve(a, b, c, d, e)
  161 #define TYPEHTONS(t)                    (t)
  162 #elif defined(__FreeBSD__)
  163 #define RTALLOC1(a, b)                  rtalloc1(a, b, 0UL)
  164 #define ARPRESOLVE(a, b, c, d, e, f)    arpresolve(a, b, c, d, e, f)
  165 #define TYPEHTONS(t)                    (htons(t))
  166 #endif
  167 
  168 #define RCF_ALLROUTES (2 << 8) | TOKEN_RCF_FRAME2 | TOKEN_RCF_BROADCAST_ALL
  169 #define RCF_SINGLEROUTE (2 << 8) | TOKEN_RCF_FRAME2 | TOKEN_RCF_BROADCAST_SINGLE
  170 
  171 static int      token_output(struct ifnet *, struct mbuf *,
  172                              const struct sockaddr *, struct rtentry *);
  173 static void     token_input(struct ifnet *, struct mbuf *);
  174 
  175 /*
  176  * Token Ring output routine.
  177  * Encapsulate a packet of type family for the local net.
  178  * Assumes that ifp is actually pointer to arphdr structure.
  179  * XXX route info has to go into the same mbuf as the header
  180  */
  181 static int
  182 token_output(struct ifnet *ifp0, struct mbuf *m0, const struct sockaddr *dst,
  183     struct rtentry *rt0)
  184 {
  185         uint16_t etype;
  186         int error = 0;
  187         u_char edst[ISO88025_ADDR_LEN];
  188         struct mbuf *m = m0;
  189         struct rtentry *rt;
  190         struct mbuf *mcopy = NULL;
  191         struct token_header *trh;
  192 #ifdef INET
  193         struct arphdr *ah = (struct arphdr *)ifp0;
  194 #endif /* INET */
  195         struct token_rif *rif = NULL;
  196         struct token_rif bcastrif;
  197         struct ifnet *ifp = ifp0;
  198         size_t riflen = 0;
  199         ALTQ_DECL(struct altq_pktattr pktattr;)
  200 
  201 #if NCARP > 0
  202         if (ifp->if_type == IFT_CARP) {
  203                 struct ifaddr *ifa;
  204 
  205                 /* loop back if this is going to the carp interface */
  206                 if (dst != NULL && ifp0->if_link_state == LINK_STATE_UP &&
  207                     (ifa = ifa_ifwithaddr(dst)) != NULL &&
  208                     ifa->ifa_ifp == ifp0)
  209                         return (looutput(ifp0, m, dst, rt0));
  210 
  211                 ifp = ifp->if_carpdev;
  212                 ah = (struct arphdr *)ifp;
  213 
  214                 if ((ifp0->if_flags & (IFF_UP|IFF_RUNNING)) !=
  215                     (IFF_UP|IFF_RUNNING))
  216                         senderr(ENETDOWN);
  217         }
  218 #endif /* NCARP > 0 */
  219 
  220         if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
  221                 senderr(ENETDOWN);
  222         if ((rt = rt0)) {
  223                 if ((rt->rt_flags & RTF_UP) == 0) {
  224                         if ((rt0 = rt = RTALLOC1(dst, 1)))
  225                                 rt->rt_refcnt--;
  226                         else
  227                                 senderr(EHOSTUNREACH);
  228                 }
  229                 if (rt->rt_flags & RTF_GATEWAY) {
  230                         if (rt->rt_gwroute == 0)
  231                                 goto lookup;
  232                         if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
  233                                 rtfree(rt); rt = rt0;
  234                         lookup: rt->rt_gwroute = RTALLOC1(rt->rt_gateway, 1);
  235                                 if ((rt = rt->rt_gwroute) == 0)
  236                                         senderr(EHOSTUNREACH);
  237                         }
  238                 }
  239                 if (rt->rt_flags & RTF_REJECT)
  240                         if (rt->rt_rmx.rmx_expire == 0 ||
  241                             time_second < rt->rt_rmx.rmx_expire)
  242                                 senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
  243         }
  244 
  245         /*
  246          * If the queueing discipline needs packet classification,
  247          * do it before prepending link headers.
  248          */
  249         IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr);
  250 
  251         switch (dst->sa_family) {
  252 
  253 #ifdef INET
  254         case AF_INET:
  255                 if (m->m_flags & M_BCAST) {
  256                         if (ifp->if_flags & IFF_LINK0) {
  257                                 if (ifp->if_flags & IFF_LINK1)
  258                                         bcastrif.tr_rcf = htons(RCF_ALLROUTES);
  259                                 else
  260                                         bcastrif.tr_rcf = htons(RCF_SINGLEROUTE);
  261                                 rif = &bcastrif;
  262                                 riflen = sizeof(rif->tr_rcf);
  263                         }
  264                         memcpy(edst, tokenbroadcastaddr, sizeof(edst));
  265                 }
  266 /*
  267  * XXX m->m_flags & M_MCAST   IEEE802_MAP_IP_MULTICAST ??
  268  */
  269                 else {
  270                         if (!ARPRESOLVE(ifp, rt, m, dst, edst, rt0))
  271                                 return (0);     /* if not yet resolved */
  272                         rif = TOKEN_RIF((struct llinfo_arp *) rt->rt_llinfo);
  273                         riflen = (ntohs(rif->tr_rcf) & TOKEN_RCF_LEN_MASK) >> 8;
  274                 }
  275                 /* If broadcasting on a simplex interface, loopback a copy. */
  276                 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
  277                         mcopy = m_copy(m, 0, (int)M_COPYALL);
  278                 etype = htons(ETHERTYPE_IP);
  279                 break;
  280         case AF_ARP:
  281 /*
  282  * XXX source routing, assume m->m_data contains the useful stuff
  283  */
  284                 ah = mtod(m, struct arphdr *);
  285                 ah->ar_hrd = htons(ARPHRD_IEEE802);
  286 
  287                 switch (ntohs(ah->ar_op)) {
  288                 case ARPOP_REVREQUEST:
  289                 case ARPOP_REVREPLY:
  290                         etype = htons(ETHERTYPE_REVARP);
  291                         break;
  292 
  293                 case ARPOP_REQUEST:
  294                 case ARPOP_REPLY:
  295                 default:
  296                         etype = htons(ETHERTYPE_ARP);
  297                 }
  298 
  299                 if (m->m_flags & M_BCAST) {
  300                         if (ifp->if_flags & IFF_LINK0) {
  301                                 if (ifp->if_flags & IFF_LINK1)
  302                                         bcastrif.tr_rcf = htons(RCF_ALLROUTES);
  303                                 else
  304                                         bcastrif.tr_rcf = htons(RCF_SINGLEROUTE);
  305                                 rif = &bcastrif;
  306                                 riflen = sizeof(rif->tr_rcf);
  307                         }
  308                         memcpy(edst, tokenbroadcastaddr, sizeof(edst));
  309                 }
  310                 else {
  311                         void *tha = ar_tha(ah);
  312                         if (tha == NULL)
  313                                 return 0;
  314                         bcopy(tha, (void *)edst, sizeof(edst));
  315                         trh = (struct token_header *)M_TRHSTART(m);
  316                         trh->token_ac = TOKEN_AC;
  317                         trh->token_fc = TOKEN_FC;
  318                         if (trh->token_shost[0] & TOKEN_RI_PRESENT) {
  319                                 struct token_rif *trrif;
  320 
  321                                 trrif = TOKEN_RIF(trh);
  322                                 riflen = (ntohs(trrif->tr_rcf) & TOKEN_RCF_LEN_MASK) >> 8;
  323                         }
  324                         bcopy((void *)edst, (void *)trh->token_dhost,
  325                             sizeof (edst));
  326                         bcopy(CLLADDR(ifp->if_sadl), (void *)trh->token_shost,
  327                             sizeof(trh->token_shost));
  328                         if (riflen != 0)
  329                                 trh->token_shost[0] |= TOKEN_RI_PRESENT;
  330 /*
  331  * compare (m->m_data - m->m_pktdat) with (sizeof(struct token_header) + riflen + ...
  332  */
  333                         m->m_len += (sizeof(*trh) + riflen + LLC_SNAPFRAMELEN);
  334                         m->m_data -= (sizeof(*trh) + riflen + LLC_SNAPFRAMELEN);
  335                         m->m_pkthdr.len += (sizeof(*trh) + riflen + LLC_SNAPFRAMELEN);
  336                         goto send;
  337                 }
  338                 break;
  339 #endif
  340 #ifdef  ISO
  341         case AF_ISO: {
  342                 int     snpalen;
  343                 struct  llc *l;
  344                 const struct sockaddr_dl *sdl;
  345 
  346                 if (rt && (sdl = satocsdl(rt->rt_gateway)) &&
  347                     sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) {
  348                         memcpy(edst, CLLADDR(sdl), sizeof(edst));
  349                 }
  350                 else if ((error = iso_snparesolve(ifp,
  351                     (const struct sockaddr_iso *)dst, (char *)edst, &snpalen)))
  352                         goto bad; /* Not resolved */
  353                 /* If broadcasting on a simplex interface, loopback a copy. */
  354                 if (*edst & 1)
  355                         m->m_flags |= (M_BCAST|M_MCAST);
  356                 if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
  357                     (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
  358                         M_PREPEND(mcopy, sizeof (*trh), M_DONTWAIT);
  359                         if (mcopy) {
  360                                 trh = mtod(mcopy, struct token_header *);
  361                                 bcopy((void *)edst,
  362                                     (void *)trh->token_dhost, sizeof (edst));
  363                                 bcopy(CLLADDR(ifp->if_sadl),
  364                                     (void *)trh->token_shost, sizeof (edst));
  365                         }
  366                 }
  367                 M_PREPEND(m, 3, M_DONTWAIT);
  368                 if (m == NULL)
  369                         return (0);
  370                 etype = 0;
  371                 l = mtod(m, struct llc *);
  372                 l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
  373                 l->llc_control = LLC_UI;
  374 #if defined(__FreeBSD__)
  375                 IFDEBUG(D_ETHER)
  376                         int i;
  377                         printf("token_output: sending pkt to: ");
  378                         for (i=0; i < ISO88025_ADDR_LEN; i++)
  379                                 printf("%x ", edst[i] & 0xff);
  380                         printf("\n");
  381                 ENDDEBUG
  382 #endif
  383                 } break;
  384 #endif /* ISO */
  385 
  386         case AF_UNSPEC:
  387         {
  388                 const struct ether_header *eh;
  389                 eh = (const struct ether_header *)dst->sa_data;
  390                 memcpy(edst, eh->ether_dhost, sizeof(edst));
  391                 if (*edst & 1)
  392                         m->m_flags |= (M_BCAST|M_MCAST);
  393                 etype = TYPEHTONS(eh->ether_type);
  394                 if (m->m_flags & M_BCAST) {
  395                         if (ifp->if_flags & IFF_LINK0) {
  396                                 if (ifp->if_flags & IFF_LINK1)
  397                                         bcastrif.tr_rcf = htons(RCF_ALLROUTES);
  398                                 else
  399                                         bcastrif.tr_rcf = htons(RCF_SINGLEROUTE);
  400                                 rif = &bcastrif;
  401                                 riflen = sizeof(bcastrif.tr_rcf);
  402                         }
  403                 }
  404                 break;
  405         }
  406 
  407         default:
  408                 printf("%s: can't handle af%d\n", ifp->if_xname,
  409                     dst->sa_family);
  410                 senderr(EAFNOSUPPORT);
  411         }
  412 
  413 
  414         if (mcopy)
  415                 (void) looutput(ifp, mcopy, dst, rt);
  416         if (etype != 0) {
  417                 struct llc *l;
  418                 M_PREPEND(m, LLC_SNAPFRAMELEN, M_DONTWAIT);
  419                 if (m == 0)
  420                         senderr(ENOBUFS);
  421                 l = mtod(m, struct llc *);
  422                 l->llc_control = LLC_UI;
  423                 l->llc_dsap = l->llc_ssap = LLC_SNAP_LSAP;
  424                 l->llc_snap.org_code[0] = l->llc_snap.org_code[1] =
  425                     l->llc_snap.org_code[2] = 0;
  426                 bcopy((void *) &etype, (void *) &l->llc_snap.ether_type,
  427                     sizeof(uint16_t));
  428         }
  429 
  430         /*
  431          * Add local net header.  If no space in first mbuf,
  432          * allocate another.
  433          */
  434 
  435         M_PREPEND(m, (riflen + sizeof (*trh)), M_DONTWAIT);
  436         if (m == 0)
  437                 senderr(ENOBUFS);
  438         trh = mtod(m, struct token_header *);
  439         trh->token_ac = TOKEN_AC;
  440         trh->token_fc = TOKEN_FC;
  441         bcopy((void *)edst, (void *)trh->token_dhost, sizeof (edst));
  442         bcopy(CLLADDR(ifp->if_sadl), (void *)trh->token_shost,
  443             sizeof(trh->token_shost));
  444 
  445         if (riflen != 0) {
  446                 struct token_rif *trrif;
  447 
  448                 trh->token_shost[0] |= TOKEN_RI_PRESENT;
  449                 trrif = TOKEN_RIF(trh);
  450                 bcopy(rif, trrif, riflen);
  451         }
  452 #ifdef INET
  453 send:
  454 #endif
  455 
  456 #if NCARP > 0
  457         if (ifp0 != ifp && ifp0->if_type == IFT_CARP) {
  458                 bcopy(CLLADDR(ifp0->if_sadl), (void *)trh->token_shost,     
  459                     sizeof(trh->token_shost));
  460         }
  461 #endif /* NCARP > 0 */
  462 
  463         return ifq_enqueue(ifp, m ALTQ_COMMA ALTQ_DECL(&pktattr));
  464 bad:
  465         if (m)
  466                 m_freem(m);
  467         return (error);
  468 }
  469 
  470 /*
  471  * Process a received token ring packet;
  472  * the packet is in the mbuf chain m with
  473  * the token ring header.
  474  */
  475 static void
  476 token_input(struct ifnet *ifp, struct mbuf *m)
  477 {
  478         struct ifqueue *inq;
  479         struct llc *l;
  480         struct token_header *trh;
  481         int s, lan_hdr_len;
  482 
  483         if ((ifp->if_flags & IFF_UP) == 0) {
  484                 m_freem(m);
  485                 return;
  486         }
  487 
  488         trh = mtod(m, struct token_header *);
  489 
  490         ifp->if_ibytes += m->m_pkthdr.len;
  491         if (memcmp(tokenbroadcastaddr, trh->token_dhost,
  492             sizeof(tokenbroadcastaddr)) == 0)
  493                 m->m_flags |= M_BCAST;
  494         else if (trh->token_dhost[0] & 1)
  495                 m->m_flags |= M_MCAST;
  496         if (m->m_flags & (M_BCAST|M_MCAST))
  497                 ifp->if_imcasts++;
  498 
  499         /* Skip past the Token Ring header and RIF. */
  500         lan_hdr_len = sizeof(struct token_header);
  501         if (trh->token_shost[0] & TOKEN_RI_PRESENT) {
  502                 struct token_rif *trrif;
  503 
  504                 trrif = TOKEN_RIF(trh);
  505                 lan_hdr_len += (ntohs(trrif->tr_rcf) & TOKEN_RCF_LEN_MASK) >> 8;
  506         }
  507 
  508         l = (struct llc *)(mtod(m, uint8_t *) + lan_hdr_len);
  509 
  510         switch (l->llc_dsap) {
  511 #if defined(INET) || defined(NS) || defined(DECNET)
  512         case LLC_SNAP_LSAP:
  513         {
  514                 uint16_t etype;
  515                 if (l->llc_control != LLC_UI || l->llc_ssap != LLC_SNAP_LSAP)
  516                         goto dropanyway;
  517                 if (l->llc_snap.org_code[0] != 0 ||
  518                     l->llc_snap.org_code[1] != 0 ||
  519                     l->llc_snap.org_code[2] != 0)
  520                         goto dropanyway;
  521                 etype = ntohs(l->llc_snap.ether_type);
  522                 m_adj(m, lan_hdr_len + LLC_SNAPFRAMELEN);
  523 #if NCARP > 0
  524                 if (ifp->if_carp && ifp->if_type != IFT_CARP &&
  525                     (carp_input(m, (uint8_t *)&trh->token_shost,
  526                     (uint8_t *)&trh->token_dhost, l->llc_snap.ether_type) == 0))
  527                         return;
  528 #endif /* NCARP > 0 */
  529 
  530                 switch (etype) {
  531 #ifdef INET
  532                 case ETHERTYPE_IP:
  533                         schednetisr(NETISR_IP);
  534                         inq = &ipintrq;
  535                         break;
  536 
  537                 case ETHERTYPE_ARP:
  538                         schednetisr(NETISR_ARP);
  539                         inq = &arpintrq;
  540                         break;
  541 #endif
  542 #ifdef DECNET
  543                 case ETHERTYPE_DECNET:
  544                         schednetisr(NETISR_DECNET);
  545                         inq = &decnetintrq;
  546                         break;
  547 #endif
  548                 default:
  549                         /*
  550                         printf("token_input: unknown protocol 0x%x\n", etype);
  551                         */
  552                         ifp->if_noproto++;
  553                         goto dropanyway;
  554                 }
  555                 break;
  556         }
  557 #endif /* INET || NS || DECNET */
  558 #ifdef  ISO
  559         case LLC_ISO_LSAP:
  560                 switch (l->llc_control) {
  561                 case LLC_UI:
  562                         /* LLC_UI_P forbidden in class 1 service */
  563                         if ((l->llc_dsap == LLC_ISO_LSAP) &&
  564                             (l->llc_ssap == LLC_ISO_LSAP)) {
  565 
  566 #if defined(__FreeBSD__)
  567                                 IFDEBUG(D_ETHER)
  568                                         printf("clnp packet");
  569                                 ENDDEBUG
  570 #endif
  571                                 schednetisr(NETISR_ISO);
  572                                 inq = &clnlintrq;
  573                                 break;
  574                         }
  575                         goto dropanyway;
  576 
  577                 case LLC_XID:
  578                 case LLC_XID_P:
  579                         if(m->m_len < LLC_XID_BASIC_MINLEN + lan_hdr_len)
  580                                 goto dropanyway;
  581                         l->llc_window = 0;
  582                         l->llc_fid = LLC_XID_FORMAT_BASIC;
  583                         l->llc_class = LLC_XID_CLASS_I;
  584                         l->llc_dsap = l->llc_ssap = 0;
  585                         /* Fall through to */
  586                 case LLC_TEST:
  587                 case LLC_TEST_P:
  588                 {
  589                         struct sockaddr sa;
  590                         struct ether_header *eh;
  591                         int i;
  592                         u_char c = l->llc_dsap;
  593 
  594                         l->llc_dsap = l->llc_ssap;
  595                         l->llc_ssap = c;
  596                         if (m->m_flags & (M_BCAST | M_MCAST))
  597                                 bcopy(CLLADDR(ifp->if_sadl),
  598                                     (void *)trh->token_dhost,
  599                                     ISO88025_ADDR_LEN);
  600                         sa.sa_family = AF_UNSPEC;
  601                         sa.sa_len = sizeof(sa);
  602                         eh = (struct ether_header *)sa.sa_data;
  603                         for (i = 0; i < ISO88025_ADDR_LEN; i++) {
  604                                 eh->ether_shost[i] = c = trh->token_dhost[i];
  605                                 eh->ether_dhost[i] =
  606                                     eh->ether_dhost[i] = trh->token_shost[i];
  607                                 eh->ether_shost[i] = c;
  608                         }
  609                         eh->ether_type = 0;
  610                         m_adj(m, lan_hdr_len);
  611                         ifp->if_output(ifp, m, &sa, NULL);
  612                         return;
  613                 }
  614                 default:
  615                         m_freem(m);
  616                         return;
  617                 }
  618                 break;
  619 #endif /* ISO */
  620 
  621         default:
  622                 /* printf("token_input: unknown dsap 0x%x\n", l->llc_dsap); */
  623                 ifp->if_noproto++;
  624 #if defined(INET) || defined(NS) || defined(DECNET) || defined(ISO)
  625         dropanyway:
  626 #endif
  627                 m_freem(m);
  628                 return;
  629         }
  630 
  631         s = splnet();
  632         if (IF_QFULL(inq)) {
  633                 IF_DROP(inq);
  634                 m_freem(m);
  635         }
  636         else
  637                 IF_ENQUEUE(inq, m);
  638         splx(s);
  639 }
  640 
  641 /*
  642  * Perform common duties while attaching to interface list
  643  */
  644 void
  645 token_ifattach(struct ifnet *ifp, void *lla)
  646 {
  647 
  648         ifp->if_type = IFT_ISO88025;
  649         ifp->if_hdrlen = 14;
  650         ifp->if_dlt = DLT_IEEE802;
  651         ifp->if_mtu = ISO88025_MTU;
  652         ifp->if_output = token_output;
  653         ifp->if_input = token_input;
  654         ifp->if_broadcastaddr = tokenbroadcastaddr;
  655 #ifdef IFF_NOTRAILERS
  656         ifp->if_flags |= IFF_NOTRAILERS;
  657 #endif
  658 
  659         if_set_sadl(ifp, lla, ISO88025_ADDR_LEN);
  660 
  661 #if NBPFILTER > 0
  662         bpfattach(ifp, DLT_IEEE802, sizeof(struct token_header));
  663 #endif
  664 }
  665 
  666 void
  667 token_ifdetach(struct ifnet *ifp)
  668 {
  669 
  670 #if NBPFILTER > 0
  671         bpfdetach(ifp);
  672 #endif
  673 #if 0   /* done in if_detach() */
  674         if_free_sadl(ifp);
  675 #endif
  676 }

Cache object: bb3065faeb86c23747a2df4ac0a60285


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