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/netgraph/ng_atmllc.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) 2003-2004 Benno Rice <benno@eloquent.com.au>
    3  * All Rights Reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR  ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR  BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * $FreeBSD: releng/9.0/sys/netgraph/ng_atmllc.c 220768 2011-04-18 09:12:27Z glebius $
   27  */
   28 
   29 #include <sys/param.h>
   30 #include <sys/systm.h>
   31 #include <sys/kernel.h>
   32 #include <sys/malloc.h>
   33 #include <sys/mbuf.h>
   34 #include <sys/socket.h>
   35 #include <sys/sockio.h>
   36 
   37 #include <netgraph/ng_message.h>
   38 #include <netgraph/netgraph.h>
   39 #include <netgraph/ng_atmllc.h>
   40 
   41 #include <net/if.h>
   42 #include <net/ethernet.h>       /* for M_HASFCS and ETHER_HDR_LEN */
   43 #include <net/if_atm.h>         /* for struct atmllc */
   44 
   45 #define NG_ATMLLC_HEADER                "\252\252\3\0\200\302"
   46 #define NG_ATMLLC_HEADER_LEN            (sizeof(struct atmllc))
   47 #define NG_ATMLLC_TYPE_ETHERNET_FCS     0x0001
   48 #define NG_ATMLLC_TYPE_FDDI_FCS         0x0004
   49 #define NG_ATMLLC_TYPE_ETHERNET_NOFCS   0x0007
   50 #define NG_ATMLLC_TYPE_FDDI_NOFCS       0x000A
   51 
   52 struct ng_atmllc_priv {
   53         hook_p          atm;
   54         hook_p          ether;
   55         hook_p          fddi;
   56 };
   57 
   58 /* Netgraph methods. */
   59 static ng_constructor_t         ng_atmllc_constructor;
   60 static ng_shutdown_t            ng_atmllc_shutdown;
   61 static ng_rcvmsg_t              ng_atmllc_rcvmsg;
   62 static ng_newhook_t             ng_atmllc_newhook;
   63 static ng_rcvdata_t             ng_atmllc_rcvdata;
   64 static ng_disconnect_t          ng_atmllc_disconnect;
   65 
   66 static struct ng_type ng_atmllc_typestruct = {
   67         .version =      NG_ABI_VERSION, 
   68         .name =         NG_ATMLLC_NODE_TYPE,
   69         .constructor =  ng_atmllc_constructor,
   70         .rcvmsg =       ng_atmllc_rcvmsg,
   71         .shutdown =     ng_atmllc_shutdown,
   72         .newhook =      ng_atmllc_newhook,
   73         .rcvdata =      ng_atmllc_rcvdata,
   74         .disconnect =   ng_atmllc_disconnect,
   75 };
   76 NETGRAPH_INIT(atmllc, &ng_atmllc_typestruct);
   77 
   78 static int
   79 ng_atmllc_constructor(node_p node)
   80 {
   81         struct  ng_atmllc_priv *priv;
   82 
   83         priv = malloc(sizeof(*priv), M_NETGRAPH, M_WAITOK | M_ZERO);
   84         NG_NODE_SET_PRIVATE(node, priv);
   85 
   86         return (0);
   87 }
   88 
   89 static int
   90 ng_atmllc_rcvmsg(node_p node, item_p item, hook_p lasthook)
   91 {
   92         struct  ng_mesg *msg;
   93         int     error;
   94 
   95         error = 0;
   96         NGI_GET_MSG(item, msg);
   97         msg->header.flags |= NGF_RESP;
   98         NG_RESPOND_MSG(error, node, item, msg);
   99         return (error);
  100 }
  101 
  102 static int
  103 ng_atmllc_shutdown(node_p node)
  104 {
  105         struct  ng_atmllc_priv *priv;
  106 
  107         priv = NG_NODE_PRIVATE(node);
  108 
  109         free(priv, M_NETGRAPH);
  110 
  111         NG_NODE_UNREF(node);
  112 
  113         return (0);
  114 }
  115 
  116 static int
  117 ng_atmllc_newhook(node_p node, hook_p hook, const char *name)
  118 {
  119         struct  ng_atmllc_priv *priv;
  120 
  121         priv = NG_NODE_PRIVATE(node);
  122 
  123         if (strcmp(name, NG_ATMLLC_HOOK_ATM) == 0) {
  124                 if (priv->atm != NULL) {
  125                         return (EISCONN);
  126                 }
  127                 priv->atm = hook;
  128         } else if (strcmp(name, NG_ATMLLC_HOOK_ETHER) == 0) {
  129                 if (priv->ether != NULL) {
  130                         return (EISCONN);
  131                 }
  132                 priv->ether = hook;
  133         } else if (strcmp(name, NG_ATMLLC_HOOK_FDDI) == 0) {
  134                 if (priv->fddi != NULL) {
  135                         return (EISCONN);
  136                 }
  137                 priv->fddi = hook;
  138         } else {
  139                 return (EINVAL);
  140         }
  141 
  142         return (0);
  143 }
  144 
  145 static int
  146 ng_atmllc_rcvdata(hook_p hook, item_p item)
  147 {
  148         struct  ng_atmllc_priv *priv;
  149         struct  mbuf *m;
  150         struct  atmllc *hdr;
  151         hook_p  outhook;
  152         u_int   padding;
  153         int     error;
  154 
  155         priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
  156         m = NGI_M(item);
  157         outhook = NULL;
  158         padding = 0;
  159 
  160         if (hook == priv->atm) {
  161                 /* Ditch the psuedoheader. */
  162                 hdr = mtod(m, struct atmllc *);
  163                 /* m_adj(m, sizeof(struct atm_pseudohdr)); */
  164 
  165                 /*
  166                  * Make sure we have the LLC and ethernet headers.
  167                  * The ethernet header size is slightly larger than the FDDI
  168                  * header, which is convenient.
  169                  */
  170                 if (m->m_len < sizeof(struct atmllc) + ETHER_HDR_LEN) {
  171                         m = m_pullup(m, sizeof(struct atmllc) + ETHER_HDR_LEN);
  172                         if (m == NULL) {
  173                                 return (ENOMEM);
  174                         }
  175                 }
  176 
  177                 /* Decode the LLC header. */
  178                 hdr = mtod(m, struct atmllc *);
  179                 if (ATM_LLC_TYPE(hdr) == NG_ATMLLC_TYPE_ETHERNET_NOFCS) {
  180                         m->m_flags &= ~M_HASFCS;
  181                         outhook = priv->ether;
  182                         padding = 2;
  183                 } else if (ATM_LLC_TYPE(hdr) == NG_ATMLLC_TYPE_ETHERNET_FCS) {
  184                         m->m_flags |= M_HASFCS;
  185                         outhook = priv->ether;
  186                         padding = 2;
  187                 } else if (ATM_LLC_TYPE(hdr) == NG_ATMLLC_TYPE_FDDI_NOFCS) {
  188                         m->m_flags &= ~M_HASFCS;
  189                         outhook = priv->fddi;
  190                         padding = 3;
  191                 } else if (ATM_LLC_TYPE(hdr) == NG_ATMLLC_TYPE_FDDI_FCS) {
  192                         m->m_flags |= M_HASFCS;
  193                         outhook = priv->fddi;
  194                         padding = 3;
  195                 } else {
  196                         printf("ng_atmllc: unknown type: %x\n",
  197                             ATM_LLC_TYPE(hdr));
  198                 }
  199 
  200                 /* Remove the LLC header and any padding*/
  201                 m_adj(m, sizeof(struct atmllc) + padding);
  202         } else if (hook == priv->ether) {
  203                 /* Add the LLC header */
  204                 M_PREPEND(m, NG_ATMLLC_HEADER_LEN + 2, M_DONTWAIT);
  205                 if (m == NULL) {
  206                         printf("ng_atmllc: M_PREPEND failed\n");
  207                         NG_FREE_ITEM(item);
  208                         return (ENOMEM);
  209                 }
  210                 hdr = mtod(m, struct atmllc *);
  211                 bzero((void *)hdr, sizeof(struct atmllc) + 2);
  212                 bcopy(NG_ATMLLC_HEADER, hdr->llchdr, 6);
  213                 if ((m->m_flags & M_HASFCS) != 0) {
  214                         ATM_LLC_SETTYPE(hdr, NG_ATMLLC_TYPE_ETHERNET_FCS);
  215                 } else {
  216                         ATM_LLC_SETTYPE(hdr, NG_ATMLLC_TYPE_ETHERNET_NOFCS);
  217                 }
  218                 outhook = priv->atm;
  219         } else if (hook == priv->fddi) {
  220                 /* Add the LLC header */
  221                 M_PREPEND(m, NG_ATMLLC_HEADER_LEN + 3, M_DONTWAIT);
  222                 if (m == NULL) {
  223                         printf("ng_atmllc: M_PREPEND failed\n");
  224                         NG_FREE_ITEM(item);
  225                         return (ENOMEM);
  226                 }
  227                 hdr = mtod(m, struct atmllc *);
  228                 bzero((void *)hdr, sizeof(struct atmllc) + 3);
  229                 bcopy(NG_ATMLLC_HEADER, hdr->llchdr, 6);
  230                 if ((m->m_flags & M_HASFCS) != 0) {
  231                         ATM_LLC_SETTYPE(hdr, NG_ATMLLC_TYPE_FDDI_FCS);
  232                 } else {
  233                         ATM_LLC_SETTYPE(hdr, NG_ATMLLC_TYPE_FDDI_NOFCS);
  234                 }
  235                 outhook = priv->atm;
  236         }
  237 
  238         if (outhook == NULL) {
  239                 NG_FREE_ITEM(item);
  240                 return (0);
  241         }
  242 
  243         NG_FWD_NEW_DATA(error, item, outhook, m);
  244         return (error);
  245 }
  246 
  247 static int
  248 ng_atmllc_disconnect(hook_p hook)
  249 {
  250         node_p  node;
  251         struct  ng_atmllc_priv *priv;
  252 
  253         node = NG_HOOK_NODE(hook);
  254         priv = NG_NODE_PRIVATE(node);
  255 
  256         if (hook == priv->atm) {
  257                 priv->atm = NULL;
  258         } else if (hook == priv->ether) {
  259                 priv->ether = NULL;
  260         } else if (hook == priv->fddi) {
  261                 priv->fddi = NULL;
  262         }
  263 
  264         if (NG_NODE_NUMHOOKS(node) == 0 && NG_NODE_IS_VALID(node)) {
  265                 ng_rmnode_self(node);
  266         }
  267 
  268         return (0);
  269 }

Cache object: 7a3dab7105629608b30d2dcc9b33bf1b


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