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_async.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  * ng_async.c
    3  */
    4 
    5 /*-
    6  * Copyright (c) 1996-1999 Whistle Communications, Inc.
    7  * All rights reserved.
    8  * 
    9  * Subject to the following obligations and disclaimer of warranty, use and
   10  * redistribution of this software, in source or object code forms, with or
   11  * without modifications are expressly permitted by Whistle Communications;
   12  * provided, however, that:
   13  * 1. Any and all reproductions of the source or object code must include the
   14  *    copyright notice above and the following disclaimer of warranties; and
   15  * 2. No rights are granted, in any manner or form, to use Whistle
   16  *    Communications, Inc. trademarks, including the mark "WHISTLE
   17  *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
   18  *    such appears in the above copyright notice or in the software.
   19  * 
   20  * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
   21  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
   22  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
   23  * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
   24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
   25  * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
   26  * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
   27  * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
   28  * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
   29  * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
   30  * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
   31  * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
   32  * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
   33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   35  * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
   36  * OF SUCH DAMAGE.
   37  *
   38  * Author: Archie Cobbs <archie@freebsd.org>
   39  *
   40  * $FreeBSD: releng/11.2/sys/netgraph/ng_async.c 227293 2011-11-07 06:44:47Z ed $
   41  * $Whistle: ng_async.c,v 1.17 1999/11/01 09:24:51 julian Exp $
   42  */
   43 
   44 /*
   45  * This node type implements a PPP style sync <-> async converter.
   46  * See RFC 1661 for details of how asynchronous encoding works.
   47  */
   48 
   49 #include <sys/param.h>
   50 #include <sys/systm.h>
   51 #include <sys/kernel.h>
   52 #include <sys/mbuf.h>
   53 #include <sys/malloc.h>
   54 #include <sys/errno.h>
   55 
   56 #include <netgraph/ng_message.h>
   57 #include <netgraph/netgraph.h>
   58 #include <netgraph/ng_async.h>
   59 #include <netgraph/ng_parse.h>
   60 
   61 #include <net/ppp_defs.h>
   62 
   63 #ifdef NG_SEPARATE_MALLOC
   64 static MALLOC_DEFINE(M_NETGRAPH_ASYNC, "netgraph_async", "netgraph async node");
   65 #else
   66 #define M_NETGRAPH_ASYNC M_NETGRAPH
   67 #endif
   68 
   69 
   70 /* Async decode state */
   71 #define MODE_HUNT       0
   72 #define MODE_NORMAL     1
   73 #define MODE_ESC        2
   74 
   75 /* Private data structure */
   76 struct ng_async_private {
   77         node_p          node;           /* Our node */
   78         hook_p          async;          /* Asynchronous side */
   79         hook_p          sync;           /* Synchronous side */
   80         u_char          amode;          /* Async hunt/esape mode */
   81         u_int16_t       fcs;            /* Decoded async FCS (so far) */
   82         u_char         *abuf;           /* Buffer to encode sync into */
   83         u_char         *sbuf;           /* Buffer to decode async into */
   84         u_int           slen;           /* Length of data in sbuf */
   85         long            lasttime;       /* Time of last async packet sent */
   86         struct          ng_async_cfg    cfg;    /* Configuration */
   87         struct          ng_async_stat   stats;  /* Statistics */
   88 };
   89 typedef struct ng_async_private *sc_p;
   90 
   91 /* Useful macros */
   92 #define ASYNC_BUF_SIZE(smru)    (2 * (smru) + 10)
   93 #define SYNC_BUF_SIZE(amru)     ((amru) + 10)
   94 #define ERROUT(x)               do { error = (x); goto done; } while (0)
   95 
   96 /* Netgraph methods */
   97 static ng_constructor_t         nga_constructor;
   98 static ng_rcvdata_t             nga_rcvdata;
   99 static ng_rcvmsg_t              nga_rcvmsg;
  100 static ng_shutdown_t            nga_shutdown;
  101 static ng_newhook_t             nga_newhook;
  102 static ng_disconnect_t          nga_disconnect;
  103 
  104 /* Helper stuff */
  105 static int      nga_rcv_sync(const sc_p sc, item_p item);
  106 static int      nga_rcv_async(const sc_p sc, item_p item);
  107 
  108 /* Parse type for struct ng_async_cfg */
  109 static const struct ng_parse_struct_field nga_config_type_fields[]
  110         = NG_ASYNC_CONFIG_TYPE_INFO;
  111 static const struct ng_parse_type nga_config_type = {
  112         &ng_parse_struct_type,
  113         &nga_config_type_fields
  114 };
  115 
  116 /* Parse type for struct ng_async_stat */
  117 static const struct ng_parse_struct_field nga_stats_type_fields[]
  118         = NG_ASYNC_STATS_TYPE_INFO;
  119 static const struct ng_parse_type nga_stats_type = {
  120         &ng_parse_struct_type,
  121         &nga_stats_type_fields
  122 };
  123 
  124 /* List of commands and how to convert arguments to/from ASCII */
  125 static const struct ng_cmdlist nga_cmdlist[] = {
  126         {
  127           NGM_ASYNC_COOKIE,
  128           NGM_ASYNC_CMD_SET_CONFIG,
  129           "setconfig",
  130           &nga_config_type,
  131           NULL
  132         },
  133         {
  134           NGM_ASYNC_COOKIE,
  135           NGM_ASYNC_CMD_GET_CONFIG,
  136           "getconfig",
  137           NULL,
  138           &nga_config_type
  139         },
  140         {
  141           NGM_ASYNC_COOKIE,
  142           NGM_ASYNC_CMD_GET_STATS,
  143           "getstats",
  144           NULL,
  145           &nga_stats_type
  146         },
  147         {
  148           NGM_ASYNC_COOKIE,
  149           NGM_ASYNC_CMD_CLR_STATS,
  150           "clrstats",
  151           &nga_stats_type,
  152           NULL
  153         },
  154         { 0 }
  155 };
  156 
  157 /* Define the netgraph node type */
  158 static struct ng_type typestruct = {
  159         .version =      NG_ABI_VERSION,
  160         .name =         NG_ASYNC_NODE_TYPE,
  161         .constructor =  nga_constructor,
  162         .rcvmsg =       nga_rcvmsg,
  163         .shutdown =     nga_shutdown,
  164         .newhook =      nga_newhook,
  165         .rcvdata =      nga_rcvdata,
  166         .disconnect =   nga_disconnect,
  167         .cmdlist =      nga_cmdlist
  168 };
  169 NETGRAPH_INIT(async, &typestruct);
  170 
  171 /* CRC table */
  172 static const u_int16_t fcstab[];
  173 
  174 /******************************************************************
  175                     NETGRAPH NODE METHODS
  176 ******************************************************************/
  177 
  178 /*
  179  * Initialize a new node
  180  */
  181 static int
  182 nga_constructor(node_p node)
  183 {
  184         sc_p sc;
  185 
  186         sc = malloc(sizeof(*sc), M_NETGRAPH_ASYNC, M_WAITOK | M_ZERO);
  187         sc->amode = MODE_HUNT;
  188         sc->cfg.accm = ~0;
  189         sc->cfg.amru = NG_ASYNC_DEFAULT_MRU;
  190         sc->cfg.smru = NG_ASYNC_DEFAULT_MRU;
  191         sc->abuf = malloc(ASYNC_BUF_SIZE(sc->cfg.smru),
  192             M_NETGRAPH_ASYNC, M_WAITOK);
  193         sc->sbuf = malloc(SYNC_BUF_SIZE(sc->cfg.amru),
  194             M_NETGRAPH_ASYNC, M_WAITOK);
  195         NG_NODE_SET_PRIVATE(node, sc);
  196         sc->node = node;
  197         return (0);
  198 }
  199 
  200 /*
  201  * Reserve a hook for a pending connection
  202  */
  203 static int
  204 nga_newhook(node_p node, hook_p hook, const char *name)
  205 {
  206         const sc_p sc = NG_NODE_PRIVATE(node);
  207         hook_p *hookp;
  208 
  209         if (!strcmp(name, NG_ASYNC_HOOK_ASYNC)) {
  210                 /*
  211                  * We use a static buffer here so only one packet
  212                  * at a time can be allowed to travel in this direction.
  213                  * Force Writer semantics.
  214                  */
  215                 NG_HOOK_FORCE_WRITER(hook);
  216                 hookp = &sc->async;
  217         } else if (!strcmp(name, NG_ASYNC_HOOK_SYNC)) {
  218                 /*
  219                  * We use a static state here so only one packet
  220                  * at a time can be allowed to travel in this direction.
  221                  * Force Writer semantics.
  222                  * Since we set this for both directions
  223                  * we might as well set it for the whole node
  224                  * bit I haven;t done that (yet).
  225                  */
  226                 NG_HOOK_FORCE_WRITER(hook);
  227                 hookp = &sc->sync;
  228         } else {
  229                 return (EINVAL);
  230         }
  231         if (*hookp) /* actually can't happen I think [JRE] */
  232                 return (EISCONN);
  233         *hookp = hook;
  234         return (0);
  235 }
  236 
  237 /*
  238  * Receive incoming data
  239  */
  240 static int
  241 nga_rcvdata(hook_p hook, item_p item)
  242 {
  243         const sc_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
  244 
  245         if (hook == sc->sync)
  246                 return (nga_rcv_sync(sc, item));
  247         if (hook == sc->async)
  248                 return (nga_rcv_async(sc, item));
  249         panic("%s", __func__);
  250 }
  251 
  252 /*
  253  * Receive incoming control message
  254  */
  255 static int
  256 nga_rcvmsg(node_p node, item_p item, hook_p lasthook)
  257 {
  258         const sc_p sc = NG_NODE_PRIVATE(node);
  259         struct ng_mesg *resp = NULL;
  260         int error = 0;
  261         struct ng_mesg *msg;
  262         
  263         NGI_GET_MSG(item, msg);
  264         switch (msg->header.typecookie) {
  265         case NGM_ASYNC_COOKIE:
  266                 switch (msg->header.cmd) {
  267                 case NGM_ASYNC_CMD_GET_STATS:
  268                         NG_MKRESPONSE(resp, msg, sizeof(sc->stats), M_NOWAIT);
  269                         if (resp == NULL)
  270                                 ERROUT(ENOMEM);
  271                         *((struct ng_async_stat *) resp->data) = sc->stats;
  272                         break;
  273                 case NGM_ASYNC_CMD_CLR_STATS:
  274                         bzero(&sc->stats, sizeof(sc->stats));
  275                         break;
  276                 case NGM_ASYNC_CMD_SET_CONFIG:
  277                     {
  278                         struct ng_async_cfg *const cfg =
  279                                 (struct ng_async_cfg *) msg->data;
  280                         u_char *buf;
  281 
  282                         if (msg->header.arglen != sizeof(*cfg))
  283                                 ERROUT(EINVAL);
  284                         if (cfg->amru < NG_ASYNC_MIN_MRU
  285                             || cfg->amru > NG_ASYNC_MAX_MRU
  286                             || cfg->smru < NG_ASYNC_MIN_MRU
  287                             || cfg->smru > NG_ASYNC_MAX_MRU)
  288                                 ERROUT(EINVAL);
  289                         cfg->enabled = !!cfg->enabled;  /* normalize */
  290                         if (cfg->smru > sc->cfg.smru) { /* reallocate buffer */
  291                                 buf = malloc(ASYNC_BUF_SIZE(cfg->smru),
  292                                     M_NETGRAPH_ASYNC, M_NOWAIT);
  293                                 if (!buf)
  294                                         ERROUT(ENOMEM);
  295                                 free(sc->abuf, M_NETGRAPH_ASYNC);
  296                                 sc->abuf = buf;
  297                         }
  298                         if (cfg->amru > sc->cfg.amru) { /* reallocate buffer */
  299                                 buf = malloc(SYNC_BUF_SIZE(cfg->amru),
  300                                     M_NETGRAPH_ASYNC, M_NOWAIT);
  301                                 if (!buf)
  302                                         ERROUT(ENOMEM);
  303                                 free(sc->sbuf, M_NETGRAPH_ASYNC);
  304                                 sc->sbuf = buf;
  305                                 sc->amode = MODE_HUNT;
  306                                 sc->slen = 0;
  307                         }
  308                         if (!cfg->enabled) {
  309                                 sc->amode = MODE_HUNT;
  310                                 sc->slen = 0;
  311                         }
  312                         sc->cfg = *cfg;
  313                         break;
  314                     }
  315                 case NGM_ASYNC_CMD_GET_CONFIG:
  316                         NG_MKRESPONSE(resp, msg, sizeof(sc->cfg), M_NOWAIT);
  317                         if (!resp)
  318                                 ERROUT(ENOMEM);
  319                         *((struct ng_async_cfg *) resp->data) = sc->cfg;
  320                         break;
  321                 default:
  322                         ERROUT(EINVAL);
  323                 }
  324                 break;
  325         default:
  326                 ERROUT(EINVAL);
  327         }
  328 done:
  329         NG_RESPOND_MSG(error, node, item, resp);
  330         NG_FREE_MSG(msg);
  331         return (error);
  332 }
  333 
  334 /*
  335  * Shutdown this node
  336  */
  337 static int
  338 nga_shutdown(node_p node)
  339 {
  340         const sc_p sc = NG_NODE_PRIVATE(node);
  341 
  342         free(sc->abuf, M_NETGRAPH_ASYNC);
  343         free(sc->sbuf, M_NETGRAPH_ASYNC);
  344         bzero(sc, sizeof(*sc));
  345         free(sc, M_NETGRAPH_ASYNC);
  346         NG_NODE_SET_PRIVATE(node, NULL);
  347         NG_NODE_UNREF(node);
  348         return (0);
  349 }
  350 
  351 /*
  352  * Lose a hook. When both hooks go away, we disappear.
  353  */
  354 static int
  355 nga_disconnect(hook_p hook)
  356 {
  357         const sc_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
  358         hook_p *hookp;
  359 
  360         if (hook == sc->async)
  361                 hookp = &sc->async;
  362         else if (hook == sc->sync)
  363                 hookp = &sc->sync;
  364         else
  365                 panic("%s", __func__);
  366         if (!*hookp)
  367                 panic("%s 2", __func__);
  368         *hookp = NULL;
  369         bzero(&sc->stats, sizeof(sc->stats));
  370         sc->lasttime = 0;
  371         if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
  372         && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook))))
  373                 ng_rmnode_self(NG_HOOK_NODE(hook));
  374         return (0);
  375 }
  376 
  377 /******************************************************************
  378                     INTERNAL HELPER STUFF
  379 ******************************************************************/
  380 
  381 /*
  382  * Encode a byte into the async buffer
  383  */
  384 static __inline void
  385 nga_async_add(const sc_p sc, u_int16_t *fcs, u_int32_t accm, int *len, u_char x)
  386 {
  387         *fcs = PPP_FCS(*fcs, x);
  388         if ((x < 32 && ((1 << x) & accm))
  389             || (x == PPP_ESCAPE)
  390             || (x == PPP_FLAG)) {
  391                 sc->abuf[(*len)++] = PPP_ESCAPE;
  392                 x ^= PPP_TRANS;
  393         }
  394         sc->abuf[(*len)++] = x;
  395 }
  396 
  397 /*
  398  * Receive incoming synchronous data.
  399  */
  400 static int
  401 nga_rcv_sync(const sc_p sc, item_p item)
  402 {
  403         struct ifnet *rcvif;
  404         int alen, error = 0;
  405         struct timeval time;
  406         u_int16_t fcs, fcs0;
  407         u_int32_t accm;
  408         struct mbuf *m;
  409 
  410 
  411 #define ADD_BYTE(x)     nga_async_add(sc, &fcs, accm, &alen, (x))
  412 
  413         /* Check for bypass mode */
  414         if (!sc->cfg.enabled) {
  415                 NG_FWD_ITEM_HOOK(error, item, sc->async );
  416                 return (error);
  417         }
  418         NGI_GET_M(item, m);
  419 
  420         rcvif = m->m_pkthdr.rcvif;
  421 
  422         /* Get ACCM; special case LCP frames, which use full ACCM */
  423         accm = sc->cfg.accm;
  424         if (m->m_pkthdr.len >= 4) {
  425                 static const u_char lcphdr[4] = {
  426                     PPP_ALLSTATIONS,
  427                     PPP_UI,
  428                     (u_char)(PPP_LCP >> 8),
  429                     (u_char)(PPP_LCP & 0xff)
  430                 };
  431                 u_char buf[4];
  432 
  433                 m_copydata(m, 0, 4, (caddr_t)buf);
  434                 if (bcmp(buf, &lcphdr, 4) == 0)
  435                         accm = ~0;
  436         }
  437 
  438         /* Check for overflow */
  439         if (m->m_pkthdr.len > sc->cfg.smru) {
  440                 sc->stats.syncOverflows++;
  441                 NG_FREE_M(m);
  442                 NG_FREE_ITEM(item);
  443                 return (EMSGSIZE);
  444         }
  445 
  446         /* Update stats */
  447         sc->stats.syncFrames++;
  448         sc->stats.syncOctets += m->m_pkthdr.len;
  449 
  450         /* Initialize async encoded version of input mbuf */
  451         alen = 0;
  452         fcs = PPP_INITFCS;
  453 
  454         /* Add beginning sync flag if it's been long enough to need one */
  455         getmicrotime(&time);
  456         if (time.tv_sec >= sc->lasttime + 1) {
  457                 sc->abuf[alen++] = PPP_FLAG;
  458                 sc->lasttime = time.tv_sec;
  459         }
  460 
  461         /* Add packet payload */
  462         while (m != NULL) {
  463                 while (m->m_len > 0) {
  464                         ADD_BYTE(*mtod(m, u_char *));
  465                         m->m_data++;
  466                         m->m_len--;
  467                 }
  468                 m = m_free(m);
  469         }
  470 
  471         /* Add checksum and final sync flag */
  472         fcs0 = fcs;
  473         ADD_BYTE(~fcs0 & 0xff);
  474         ADD_BYTE(~fcs0 >> 8);
  475         sc->abuf[alen++] = PPP_FLAG;
  476 
  477         /* Put frame in an mbuf and ship it off */
  478         if (!(m = m_devget(sc->abuf, alen, 0, rcvif, NULL))) {
  479                 NG_FREE_ITEM(item);
  480                 error = ENOBUFS;
  481         } else {
  482                 NG_FWD_NEW_DATA(error, item, sc->async, m);
  483         }
  484         return (error);
  485 }
  486 
  487 /*
  488  * Receive incoming asynchronous data
  489  * XXX Technically, we should strip out incoming characters
  490  *     that are in our ACCM. Not sure if this is good or not.
  491  */
  492 static int
  493 nga_rcv_async(const sc_p sc, item_p item)
  494 {
  495         struct ifnet *rcvif;
  496         int error;
  497         struct mbuf *m;
  498 
  499         if (!sc->cfg.enabled) {
  500                 NG_FWD_ITEM_HOOK(error, item,  sc->sync);
  501                 return (error);
  502         }
  503         NGI_GET_M(item, m);
  504         rcvif = m->m_pkthdr.rcvif;
  505         while (m) {
  506                 struct mbuf *n;
  507 
  508                 for (; m->m_len > 0; m->m_data++, m->m_len--) {
  509                         u_char  ch = *mtod(m, u_char *);
  510 
  511                         sc->stats.asyncOctets++;
  512                         if (ch == PPP_FLAG) {   /* Flag overrides everything */
  513                                 int     skip = 0;
  514 
  515                                 /* Check for runts */
  516                                 if (sc->slen < 2) {
  517                                         if (sc->slen > 0)
  518                                                 sc->stats.asyncRunts++;
  519                                         goto reset;
  520                                 }
  521 
  522                                 /* Verify CRC */
  523                                 if (sc->fcs != PPP_GOODFCS) {
  524                                         sc->stats.asyncBadCheckSums++;
  525                                         goto reset;
  526                                 }
  527                                 sc->slen -= 2;
  528 
  529                                 /* Strip address and control fields */
  530                                 if (sc->slen >= 2
  531                                     && sc->sbuf[0] == PPP_ALLSTATIONS
  532                                     && sc->sbuf[1] == PPP_UI)
  533                                         skip = 2;
  534 
  535                                 /* Check for frame too big */
  536                                 if (sc->slen - skip > sc->cfg.amru) {
  537                                         sc->stats.asyncOverflows++;
  538                                         goto reset;
  539                                 }
  540 
  541                                 /* OK, ship it out */
  542                                 if ((n = m_devget(sc->sbuf + skip,
  543                                            sc->slen - skip, 0, rcvif, NULL))) {
  544                                         if (item) { /* sets NULL -> item */
  545                                                 NG_FWD_NEW_DATA(error, item,
  546                                                         sc->sync, n);
  547                                         } else {
  548                                                 NG_SEND_DATA_ONLY(error,
  549                                                         sc->sync ,n);
  550                                         }
  551                                 }
  552                                 sc->stats.asyncFrames++;
  553 reset:
  554                                 sc->amode = MODE_NORMAL;
  555                                 sc->fcs = PPP_INITFCS;
  556                                 sc->slen = 0;
  557                                 continue;
  558                         }
  559                         switch (sc->amode) {
  560                         case MODE_NORMAL:
  561                                 if (ch == PPP_ESCAPE) {
  562                                         sc->amode = MODE_ESC;
  563                                         continue;
  564                                 }
  565                                 break;
  566                         case MODE_ESC:
  567                                 ch ^= PPP_TRANS;
  568                                 sc->amode = MODE_NORMAL;
  569                                 break;
  570                         case MODE_HUNT:
  571                         default:
  572                                 continue;
  573                         }
  574 
  575                         /* Add byte to frame */
  576                         if (sc->slen >= SYNC_BUF_SIZE(sc->cfg.amru)) {
  577                                 sc->stats.asyncOverflows++;
  578                                 sc->amode = MODE_HUNT;
  579                                 sc->slen = 0;
  580                         } else {
  581                                 sc->sbuf[sc->slen++] = ch;
  582                                 sc->fcs = PPP_FCS(sc->fcs, ch);
  583                         }
  584                 }
  585                 m = m_free(m);
  586         }
  587         if (item)
  588                 NG_FREE_ITEM(item);
  589         return (0);
  590 }
  591 
  592 /*
  593  * CRC table
  594  *
  595  * Taken from RFC 1171 Appendix B
  596  */
  597 static const u_int16_t fcstab[256] = {
  598          0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
  599          0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
  600          0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
  601          0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
  602          0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
  603          0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
  604          0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
  605          0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
  606          0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
  607          0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
  608          0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
  609          0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
  610          0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
  611          0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
  612          0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
  613          0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
  614          0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
  615          0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
  616          0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
  617          0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
  618          0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
  619          0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
  620          0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
  621          0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
  622          0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
  623          0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
  624          0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
  625          0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
  626          0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
  627          0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
  628          0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
  629          0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
  630 };

Cache object: 5840f14f819d566d1ed618b147c149bf


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