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

Cache object: acaecfad6132b904bc73772997cafa97


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