root/net/if_atmsubr.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. atm_output
  2. atm_input
  3. atm_ifattach

    1 /*      $OpenBSD: if_atmsubr.c,v 1.26 2006/03/04 22:40:15 brad Exp $       */
    2 
    3 /*
    4  *
    5  * Copyright (c) 1996 Charles D. Cranor and Washington University.
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by Charles D. Cranor and 
   19  *      Washington University.
   20  * 4. The name of the author may not be used to endorse or promote products
   21  *    derived from this software without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33  */
   34 
   35 /*
   36  *      @(#)COPYRIGHT   1.1 (NRL) January 1995
   37  * 
   38  * NRL grants permission for redistribution and use in source and binary
   39  * forms, with or without modification, of the software and documentation
   40  * created at NRL provided that the following conditions are met:
   41  * 
   42  * 1. Redistributions of source code must retain the above copyright
   43  *    notice, this list of conditions and the following disclaimer.
   44  * 2. Redistributions in binary form must reproduce the above copyright
   45  *    notice, this list of conditions and the following disclaimer in the
   46  *    documentation and/or other materials provided with the distribution.
   47  * 3. All advertising materials mentioning features or use of this software
   48  *    must display the following acknowledgements:
   49  *      This product includes software developed by the University of
   50  *      California, Berkeley and its contributors.
   51  *      This product includes software developed at the Information
   52  *      Technology Division, US Naval Research Laboratory.
   53  * 4. Neither the name of the NRL nor the names of its contributors
   54  *    may be used to endorse or promote products derived from this software
   55  *    without specific prior written permission.
   56  * 
   57  * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
   58  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   59  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   60  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL NRL OR
   61  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   62  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   63  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   64  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   65  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   66  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   67  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   68  * 
   69  * The views and conclusions contained in the software and documentation
   70  * are those of the authors and should not be interpreted as representing
   71  * official policies, either expressed or implied, of the US Naval
   72  * Research Laboratory (NRL).
   73  */
   74 
   75 /*
   76  * if_atmsubr.c
   77  */
   78 
   79 #include <sys/param.h>
   80 #include <sys/systm.h>
   81 #include <sys/kernel.h>
   82 #include <sys/malloc.h>
   83 #include <sys/mbuf.h>
   84 #include <sys/protosw.h>
   85 #include <sys/socket.h>
   86 #include <sys/ioctl.h>
   87 #include <sys/errno.h>
   88 #include <sys/syslog.h>
   89 
   90 #include <machine/cpu.h>
   91 
   92 #include <net/if.h>
   93 #include <net/netisr.h>
   94 #include <net/route.h>
   95 #include <net/if_dl.h>
   96 #include <net/if_types.h>
   97 #include <net/if_atm.h>
   98 
   99 #include <netinet/in.h>
  100 #include <netinet/if_atm.h>
  101 #include <netinet/if_ether.h> /* XXX: for ETHERTYPE_* */
  102 #if defined(INET) || defined(INET6)
  103 #include <netinet/in_var.h>
  104 #endif
  105 #ifdef NATM
  106 #include <netnatm/natm.h>
  107 #endif
  108 
  109 #ifdef INET6
  110 #include <netinet6/in6_var.h>
  111 #endif /* INET6 */
  112 
  113 #define senderr(e) { error = (e); goto bad;}
  114 
  115 /*
  116  * atm_output: ATM output routine
  117  *   inputs:
  118  *     "ifp" = ATM interface to output to
  119  *     "m0" = the packet to output
  120  *     "dst" = the sockaddr to send to (either IP addr, or raw VPI/VCI)
  121  *     "rt0" = the route to use
  122  *   returns: error code   [0 == ok]
  123  *
  124  *   note: special semantic: if (dst == NULL) then we assume "m" already
  125  *              has an atm_pseudohdr on it and just send it directly.
  126  *              [for native mode ATM output]   if dst is null, then
  127  *              rt0 must also be NULL.
  128  */
  129 
  130 int
  131 atm_output(ifp, m0, dst, rt0)
  132         struct ifnet *ifp;
  133         struct mbuf *m0;
  134         struct sockaddr *dst;
  135         struct rtentry *rt0;
  136 {
  137         u_int16_t etype = 0;                    /* if using LLC/SNAP */
  138         int s, error = 0, sz, len;
  139         struct atm_pseudohdr atmdst, *ad;
  140         struct mbuf *m = m0;
  141         struct rtentry *rt;
  142         struct atmllc *atmllc;
  143         u_int32_t atm_flags;
  144 
  145         if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
  146                 senderr(ENETDOWN);
  147 
  148         /*
  149          * check route
  150          */
  151         if ((rt = rt0) != NULL) {
  152 
  153                 if ((rt->rt_flags & RTF_UP) == 0) { /* route went down! */
  154                         if ((rt0 = rt = RTALLOC1(dst, 0)) != NULL)
  155                                 rt->rt_refcnt--;
  156                         else 
  157                                 senderr(EHOSTUNREACH);
  158                 }
  159 
  160                 if (rt->rt_flags & RTF_GATEWAY) {
  161                         if (rt->rt_gwroute == 0)
  162                                 goto lookup;
  163                         if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
  164                                 rtfree(rt); rt = rt0;
  165                         lookup: rt->rt_gwroute = RTALLOC1(rt->rt_gateway, 0);
  166                                 if ((rt = rt->rt_gwroute) == 0)
  167                                         senderr(EHOSTUNREACH);
  168                         }
  169                 }
  170 
  171                 /* XXX: put RTF_REJECT code here if doing ATMARP */
  172 
  173         }
  174 
  175         /*
  176          * check for non-native ATM traffic   (dst != NULL)
  177          */
  178         if (dst) {
  179                 switch (dst->sa_family) {
  180 #ifdef INET
  181                 case AF_INET:
  182 #endif
  183 #ifdef INET6
  184                 case AF_INET6:
  185 #endif
  186 #if defined(INET) || defined(INET6)
  187                         if (dst->sa_family == AF_INET)
  188                                 etype = ETHERTYPE_IP;
  189                         else
  190                                 etype = ETHERTYPE_IPV6;
  191                         if (!atmresolve(rt, m, dst, &atmdst)) {
  192                                 m = NULL; 
  193                                 /* XXX: atmresolve already free'd it */
  194                                 senderr(EHOSTUNREACH);
  195                                 /* XXX: put ATMARP stuff here */
  196                                 /* XXX: watch who frees m on failure */
  197                         }
  198                         break;
  199 #endif
  200 
  201                 default:
  202 #if defined(__NetBSD__) || defined(__OpenBSD__)
  203                         printf("%s: can't handle af%d\n", ifp->if_xname, 
  204                                dst->sa_family);
  205 #elif defined(__FreeBSD__) || defined(__bsdi__)
  206                         printf("%s%d: can't handle af%d\n", ifp->if_name, 
  207                                ifp->if_unit, dst->sa_family);
  208 #endif
  209                         senderr(EAFNOSUPPORT);
  210                 }
  211 
  212                 /*
  213                  * must add atm_pseudohdr to data
  214                  */
  215                 sz = sizeof(atmdst);
  216                 atm_flags = ATM_PH_FLAGS(&atmdst);
  217                 if (atm_flags & ATM_PH_LLCSNAP) sz += 8; /* sizeof snap == 8 */
  218                 M_PREPEND(m, sz, M_DONTWAIT);
  219                 if (m == 0)
  220                         senderr(ENOBUFS);
  221                 ad = mtod(m, struct atm_pseudohdr *);
  222                 *ad = atmdst;
  223                 if (atm_flags & ATM_PH_LLCSNAP) {
  224                         atmllc = (struct atmllc *)(ad + 1);
  225                         bcopy(ATMLLC_HDR, atmllc->llchdr, 
  226                                                 sizeof(atmllc->llchdr));
  227                         ATM_LLC_SETTYPE(atmllc, etype); 
  228                 }
  229         }
  230 
  231         /*
  232          * Queue message on interface, and start output if interface
  233          * not yet active.
  234          */
  235         len = m->m_pkthdr.len;
  236         s = splnet();
  237         IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
  238         if (error) {
  239                 splx(s);
  240                 return (error);
  241         }
  242         ifp->if_obytes += len;
  243         if ((ifp->if_flags & IFF_OACTIVE) == 0)
  244                 (*ifp->if_start)(ifp);
  245         splx(s);
  246         return (error);
  247 
  248 bad:
  249         if (m)
  250                 m_freem(m);
  251         return (error);
  252 }
  253 
  254 /*
  255  * Process a received ATM packet;
  256  * the packet is in the mbuf chain m.
  257  */
  258 void
  259 atm_input(ifp, ah, m, rxhand)
  260         struct ifnet *ifp;
  261         struct atm_pseudohdr *ah;
  262         struct mbuf *m;
  263         void *rxhand;
  264 {
  265         struct ifqueue *inq;
  266         u_int16_t etype = ETHERTYPE_IP; /* default */
  267         int s;
  268 
  269         if ((ifp->if_flags & IFF_UP) == 0) {
  270                 m_freem(m);
  271                 return;
  272         }
  273         ifp->if_ibytes += m->m_pkthdr.len;
  274 
  275         if (rxhand) {
  276 #ifdef NATM
  277           struct natmpcb *npcb = rxhand;
  278           s = splnet();                 /* in case 2 atm cards @ diff lvls */
  279           npcb->npcb_inq++;                     /* count # in queue */
  280           splx(s);
  281           schednetisr(NETISR_NATM);
  282           inq = &natmintrq;
  283           m->m_pkthdr.rcvif = rxhand; /* XXX: overload */
  284 #else
  285           printf("atm_input: NATM detected but not configured in kernel\n");
  286           m_freem(m);
  287           return;
  288 #endif
  289         } else {
  290           /*
  291            * handle LLC/SNAP header, if present
  292            */
  293           if (ATM_PH_FLAGS(ah) & ATM_PH_LLCSNAP) {
  294             struct atmllc *alc;
  295             if (m->m_len < sizeof(*alc) &&
  296                 (m = m_pullup(m, sizeof(*alc))) == NULL)
  297                   return; /* failed */
  298             alc = mtod(m, struct atmllc *);
  299             if (bcmp(alc, ATMLLC_HDR, 6)) {
  300 #if defined(__NetBSD__) || defined(__OpenBSD__)
  301               printf("%s: recv'd invalid LLC/SNAP frame [vp=%d,vc=%d]\n",
  302                   ifp->if_xname, ATM_PH_VPI(ah), ATM_PH_VCI(ah));
  303 #elif defined(__FreeBSD__) || defined(__bsdi__)
  304               printf("%s%d: recv'd invalid LLC/SNAP frame [vp=%d,vc=%d]\n",
  305                   ifp->if_name, ifp->if_unit, ATM_PH_VPI(ah), ATM_PH_VCI(ah));
  306 #endif
  307               m_freem(m);
  308               return;
  309             }
  310             etype = ATM_LLC_TYPE(alc);
  311             m_adj(m, sizeof(*alc));
  312           }
  313 
  314           switch (etype) {
  315 #ifdef INET
  316           case ETHERTYPE_IP:
  317                   schednetisr(NETISR_IP);
  318                   inq = &ipintrq;
  319                   break;
  320 #endif /* INET */
  321 #ifdef INET6
  322           case ETHERTYPE_IPV6:
  323                   schednetisr(NETISR_IPV6);
  324                   inq = &ip6intrq;
  325                   break;
  326 #endif
  327           default:
  328               m_freem(m);
  329               return;
  330           }
  331         }
  332 
  333         s = splnet();
  334         IF_INPUT_ENQUEUE(inq, m);
  335         splx(s);
  336 }
  337 
  338 /*
  339  * Perform common duties while attaching to interface list
  340  */
  341 void
  342 atm_ifattach(ifp)
  343         struct ifnet *ifp;
  344 {
  345 
  346         ifp->if_type = IFT_ATM;
  347         ifp->if_addrlen = 0;
  348         ifp->if_hdrlen = 0;
  349         ifp->if_mtu = ATMMTU;
  350         ifp->if_output = atm_output;
  351 
  352         if_alloc_sadl(ifp);
  353 #ifdef notyet /* if using ATMARP, store hardware address using the next line */
  354         bcopy(ifp->hw_addr, LLADDR(ifp->if_sadl), ifp->if_addrlen);
  355 #endif
  356 }

/* [<][>][^][v][top][bottom][index][help] */