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-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
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/11.1/sys/netgraph/ng_atmllc.c 243882 2012-12-05 08:04:20Z 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         NGI_GET_M(item, m);
  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                                 NG_FREE_ITEM(item);
  174                                 return (ENOMEM);
  175                         }
  176                 }
  177 
  178                 /* Decode the LLC header. */
  179                 hdr = mtod(m, struct atmllc *);
  180                 if (ATM_LLC_TYPE(hdr) == NG_ATMLLC_TYPE_ETHERNET_NOFCS) {
  181                         m->m_flags &= ~M_HASFCS;
  182                         outhook = priv->ether;
  183                         padding = 2;
  184                 } else if (ATM_LLC_TYPE(hdr) == NG_ATMLLC_TYPE_ETHERNET_FCS) {
  185                         m->m_flags |= M_HASFCS;
  186                         outhook = priv->ether;
  187                         padding = 2;
  188                 } else if (ATM_LLC_TYPE(hdr) == NG_ATMLLC_TYPE_FDDI_NOFCS) {
  189                         m->m_flags &= ~M_HASFCS;
  190                         outhook = priv->fddi;
  191                         padding = 3;
  192                 } else if (ATM_LLC_TYPE(hdr) == NG_ATMLLC_TYPE_FDDI_FCS) {
  193                         m->m_flags |= M_HASFCS;
  194                         outhook = priv->fddi;
  195                         padding = 3;
  196                 } else {
  197                         printf("ng_atmllc: unknown type: %x\n",
  198                             ATM_LLC_TYPE(hdr));
  199                 }
  200 
  201                 /* Remove the LLC header and any padding*/
  202                 m_adj(m, sizeof(struct atmllc) + padding);
  203         } else if (hook == priv->ether) {
  204                 /* Add the LLC header */
  205                 M_PREPEND(m, NG_ATMLLC_HEADER_LEN + 2, M_NOWAIT);
  206                 if (m == NULL) {
  207                         printf("ng_atmllc: M_PREPEND failed\n");
  208                         NG_FREE_ITEM(item);
  209                         return (ENOMEM);
  210                 }
  211                 hdr = mtod(m, struct atmllc *);
  212                 bzero((void *)hdr, sizeof(struct atmllc) + 2);
  213                 bcopy(NG_ATMLLC_HEADER, hdr->llchdr, 6);
  214                 if ((m->m_flags & M_HASFCS) != 0) {
  215                         ATM_LLC_SETTYPE(hdr, NG_ATMLLC_TYPE_ETHERNET_FCS);
  216                 } else {
  217                         ATM_LLC_SETTYPE(hdr, NG_ATMLLC_TYPE_ETHERNET_NOFCS);
  218                 }
  219                 outhook = priv->atm;
  220         } else if (hook == priv->fddi) {
  221                 /* Add the LLC header */
  222                 M_PREPEND(m, NG_ATMLLC_HEADER_LEN + 3, M_NOWAIT);
  223                 if (m == NULL) {
  224                         printf("ng_atmllc: M_PREPEND failed\n");
  225                         NG_FREE_ITEM(item);
  226                         return (ENOMEM);
  227                 }
  228                 hdr = mtod(m, struct atmllc *);
  229                 bzero((void *)hdr, sizeof(struct atmllc) + 3);
  230                 bcopy(NG_ATMLLC_HEADER, hdr->llchdr, 6);
  231                 if ((m->m_flags & M_HASFCS) != 0) {
  232                         ATM_LLC_SETTYPE(hdr, NG_ATMLLC_TYPE_FDDI_FCS);
  233                 } else {
  234                         ATM_LLC_SETTYPE(hdr, NG_ATMLLC_TYPE_FDDI_NOFCS);
  235                 }
  236                 outhook = priv->atm;
  237         }
  238 
  239         if (outhook == NULL) {
  240                 NG_FREE_M(m);
  241                 NG_FREE_ITEM(item);
  242                 return (0);
  243         }
  244 
  245         NG_FWD_NEW_DATA(error, item, outhook, m);
  246         return (error);
  247 }
  248 
  249 static int
  250 ng_atmllc_disconnect(hook_p hook)
  251 {
  252         node_p  node;
  253         struct  ng_atmllc_priv *priv;
  254 
  255         node = NG_HOOK_NODE(hook);
  256         priv = NG_NODE_PRIVATE(node);
  257 
  258         if (hook == priv->atm) {
  259                 priv->atm = NULL;
  260         } else if (hook == priv->ether) {
  261                 priv->ether = NULL;
  262         } else if (hook == priv->fddi) {
  263                 priv->fddi = NULL;
  264         }
  265 
  266         if (NG_NODE_NUMHOOKS(node) == 0 && NG_NODE_IS_VALID(node)) {
  267                 ng_rmnode_self(node);
  268         }
  269 
  270         return (0);
  271 }

Cache object: fae6099df3b66e4442309e3e5300a4b6


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