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-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  * 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/8.0/sys/netgraph/ng_async.c 184214 2008-10-23 20:26:15Z des $
   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 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_NOWAIT | M_ZERO);
  187         if (sc == NULL)
  188                 return (ENOMEM);
  189         sc->amode = MODE_HUNT;
  190         sc->cfg.accm = ~0;
  191         sc->cfg.amru = NG_ASYNC_DEFAULT_MRU;
  192         sc->cfg.smru = NG_ASYNC_DEFAULT_MRU;
  193         sc->abuf = malloc(ASYNC_BUF_SIZE(sc->cfg.smru),
  194             M_NETGRAPH_ASYNC, M_NOWAIT);
  195         if (sc->abuf == NULL)
  196                 goto fail;
  197         sc->sbuf = malloc(SYNC_BUF_SIZE(sc->cfg.amru),
  198             M_NETGRAPH_ASYNC, M_NOWAIT);
  199         if (sc->sbuf == NULL) {
  200                 free(sc->abuf, M_NETGRAPH_ASYNC);
  201 fail:
  202                 free(sc, M_NETGRAPH_ASYNC);
  203                 return (ENOMEM);
  204         }
  205         NG_NODE_SET_PRIVATE(node, sc);
  206         sc->node = node;
  207         return (0);
  208 }
  209 
  210 /*
  211  * Reserve a hook for a pending connection
  212  */
  213 static int
  214 nga_newhook(node_p node, hook_p hook, const char *name)
  215 {
  216         const sc_p sc = NG_NODE_PRIVATE(node);
  217         hook_p *hookp;
  218 
  219         if (!strcmp(name, NG_ASYNC_HOOK_ASYNC)) {
  220                 /*
  221                  * We use a static buffer here so only one packet
  222                  * at a time can be allowed to travel in this direction.
  223                  * Force Writer semantics.
  224                  */
  225                 NG_HOOK_FORCE_WRITER(hook);
  226                 hookp = &sc->async;
  227         } else if (!strcmp(name, NG_ASYNC_HOOK_SYNC)) {
  228                 /*
  229                  * We use a static state here so only one packet
  230                  * at a time can be allowed to travel in this direction.
  231                  * Force Writer semantics.
  232                  * Since we set this for both directions
  233                  * we might as well set it for the whole node
  234                  * bit I haven;t done that (yet).
  235                  */
  236                 NG_HOOK_FORCE_WRITER(hook);
  237                 hookp = &sc->sync;
  238         } else {
  239                 return (EINVAL);
  240         }
  241         if (*hookp) /* actually can't happen I think [JRE] */
  242                 return (EISCONN);
  243         *hookp = hook;
  244         return (0);
  245 }
  246 
  247 /*
  248  * Receive incoming data
  249  */
  250 static int
  251 nga_rcvdata(hook_p hook, item_p item)
  252 {
  253         const sc_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
  254 
  255         if (hook == sc->sync)
  256                 return (nga_rcv_sync(sc, item));
  257         if (hook == sc->async)
  258                 return (nga_rcv_async(sc, item));
  259         panic(__func__);
  260 }
  261 
  262 /*
  263  * Receive incoming control message
  264  */
  265 static int
  266 nga_rcvmsg(node_p node, item_p item, hook_p lasthook)
  267 {
  268         const sc_p sc = NG_NODE_PRIVATE(node);
  269         struct ng_mesg *resp = NULL;
  270         int error = 0;
  271         struct ng_mesg *msg;
  272         
  273         NGI_GET_MSG(item, msg);
  274         switch (msg->header.typecookie) {
  275         case NGM_ASYNC_COOKIE:
  276                 switch (msg->header.cmd) {
  277                 case NGM_ASYNC_CMD_GET_STATS:
  278                         NG_MKRESPONSE(resp, msg, sizeof(sc->stats), M_NOWAIT);
  279                         if (resp == NULL)
  280                                 ERROUT(ENOMEM);
  281                         *((struct ng_async_stat *) resp->data) = sc->stats;
  282                         break;
  283                 case NGM_ASYNC_CMD_CLR_STATS:
  284                         bzero(&sc->stats, sizeof(sc->stats));
  285                         break;
  286                 case NGM_ASYNC_CMD_SET_CONFIG:
  287                     {
  288                         struct ng_async_cfg *const cfg =
  289                                 (struct ng_async_cfg *) msg->data;
  290                         u_char *buf;
  291 
  292                         if (msg->header.arglen != sizeof(*cfg))
  293                                 ERROUT(EINVAL);
  294                         if (cfg->amru < NG_ASYNC_MIN_MRU
  295                             || cfg->amru > NG_ASYNC_MAX_MRU
  296                             || cfg->smru < NG_ASYNC_MIN_MRU
  297                             || cfg->smru > NG_ASYNC_MAX_MRU)
  298                                 ERROUT(EINVAL);
  299                         cfg->enabled = !!cfg->enabled;  /* normalize */
  300                         if (cfg->smru > sc->cfg.smru) { /* reallocate buffer */
  301                                 buf = malloc(ASYNC_BUF_SIZE(cfg->smru),
  302                                     M_NETGRAPH_ASYNC, M_NOWAIT);
  303                                 if (!buf)
  304                                         ERROUT(ENOMEM);
  305                                 free(sc->abuf, M_NETGRAPH_ASYNC);
  306                                 sc->abuf = buf;
  307                         }
  308                         if (cfg->amru > sc->cfg.amru) { /* reallocate buffer */
  309                                 buf = malloc(SYNC_BUF_SIZE(cfg->amru),
  310                                     M_NETGRAPH_ASYNC, M_NOWAIT);
  311                                 if (!buf)
  312                                         ERROUT(ENOMEM);
  313                                 free(sc->sbuf, M_NETGRAPH_ASYNC);
  314                                 sc->sbuf = buf;
  315                                 sc->amode = MODE_HUNT;
  316                                 sc->slen = 0;
  317                         }
  318                         if (!cfg->enabled) {
  319                                 sc->amode = MODE_HUNT;
  320                                 sc->slen = 0;
  321                         }
  322                         sc->cfg = *cfg;
  323                         break;
  324                     }
  325                 case NGM_ASYNC_CMD_GET_CONFIG:
  326                         NG_MKRESPONSE(resp, msg, sizeof(sc->cfg), M_NOWAIT);
  327                         if (!resp)
  328                                 ERROUT(ENOMEM);
  329                         *((struct ng_async_cfg *) resp->data) = sc->cfg;
  330                         break;
  331                 default:
  332                         ERROUT(EINVAL);
  333                 }
  334                 break;
  335         default:
  336                 ERROUT(EINVAL);
  337         }
  338 done:
  339         NG_RESPOND_MSG(error, node, item, resp);
  340         NG_FREE_MSG(msg);
  341         return (error);
  342 }
  343 
  344 /*
  345  * Shutdown this node
  346  */
  347 static int
  348 nga_shutdown(node_p node)
  349 {
  350         const sc_p sc = NG_NODE_PRIVATE(node);
  351 
  352         free(sc->abuf, M_NETGRAPH_ASYNC);
  353         free(sc->sbuf, M_NETGRAPH_ASYNC);
  354         bzero(sc, sizeof(*sc));
  355         free(sc, M_NETGRAPH_ASYNC);
  356         NG_NODE_SET_PRIVATE(node, NULL);
  357         NG_NODE_UNREF(node);
  358         return (0);
  359 }
  360 
  361 /*
  362  * Lose a hook. When both hooks go away, we disappear.
  363  */
  364 static int
  365 nga_disconnect(hook_p hook)
  366 {
  367         const sc_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
  368         hook_p *hookp;
  369 
  370         if (hook == sc->async)
  371                 hookp = &sc->async;
  372         else if (hook == sc->sync)
  373                 hookp = &sc->sync;
  374         else
  375                 panic(__func__);
  376         if (!*hookp)
  377                 panic("%s 2", __func__);
  378         *hookp = NULL;
  379         bzero(&sc->stats, sizeof(sc->stats));
  380         sc->lasttime = 0;
  381         if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
  382         && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook))))
  383                 ng_rmnode_self(NG_HOOK_NODE(hook));
  384         return (0);
  385 }
  386 
  387 /******************************************************************
  388                     INTERNAL HELPER STUFF
  389 ******************************************************************/
  390 
  391 /*
  392  * Encode a byte into the async buffer
  393  */
  394 static __inline void
  395 nga_async_add(const sc_p sc, u_int16_t *fcs, u_int32_t accm, int *len, u_char x)
  396 {
  397         *fcs = PPP_FCS(*fcs, x);
  398         if ((x < 32 && ((1 << x) & accm))
  399             || (x == PPP_ESCAPE)
  400             || (x == PPP_FLAG)) {
  401                 sc->abuf[(*len)++] = PPP_ESCAPE;
  402                 x ^= PPP_TRANS;
  403         }
  404         sc->abuf[(*len)++] = x;
  405 }
  406 
  407 /*
  408  * Receive incoming synchronous data.
  409  */
  410 static int
  411 nga_rcv_sync(const sc_p sc, item_p item)
  412 {
  413         struct ifnet *rcvif;
  414         int alen, error = 0;
  415         struct timeval time;
  416         u_int16_t fcs, fcs0;
  417         u_int32_t accm;
  418         struct mbuf *m;
  419 
  420 
  421 #define ADD_BYTE(x)     nga_async_add(sc, &fcs, accm, &alen, (x))
  422 
  423         /* Check for bypass mode */
  424         if (!sc->cfg.enabled) {
  425                 NG_FWD_ITEM_HOOK(error, item, sc->async );
  426                 return (error);
  427         }
  428         NGI_GET_M(item, m);
  429 
  430         rcvif = m->m_pkthdr.rcvif;
  431 
  432         /* Get ACCM; special case LCP frames, which use full ACCM */
  433         accm = sc->cfg.accm;
  434         if (m->m_pkthdr.len >= 4) {
  435                 static const u_char lcphdr[4] = {
  436                     PPP_ALLSTATIONS,
  437                     PPP_UI,
  438                     (u_char)(PPP_LCP >> 8),
  439                     (u_char)(PPP_LCP & 0xff)
  440                 };
  441                 u_char buf[4];
  442 
  443                 m_copydata(m, 0, 4, (caddr_t)buf);
  444                 if (bcmp(buf, &lcphdr, 4) == 0)
  445                         accm = ~0;
  446         }
  447 
  448         /* Check for overflow */
  449         if (m->m_pkthdr.len > sc->cfg.smru) {
  450                 sc->stats.syncOverflows++;
  451                 NG_FREE_M(m);
  452                 NG_FREE_ITEM(item);
  453                 return (EMSGSIZE);
  454         }
  455 
  456         /* Update stats */
  457         sc->stats.syncFrames++;
  458         sc->stats.syncOctets += m->m_pkthdr.len;
  459 
  460         /* Initialize async encoded version of input mbuf */
  461         alen = 0;
  462         fcs = PPP_INITFCS;
  463 
  464         /* Add beginning sync flag if it's been long enough to need one */
  465         getmicrotime(&time);
  466         if (time.tv_sec >= sc->lasttime + 1) {
  467                 sc->abuf[alen++] = PPP_FLAG;
  468                 sc->lasttime = time.tv_sec;
  469         }
  470 
  471         /* Add packet payload */
  472         while (m != NULL) {
  473                 while (m->m_len > 0) {
  474                         ADD_BYTE(*mtod(m, u_char *));
  475                         m->m_data++;
  476                         m->m_len--;
  477                 }
  478                 m = m_free(m);
  479         }
  480 
  481         /* Add checksum and final sync flag */
  482         fcs0 = fcs;
  483         ADD_BYTE(~fcs0 & 0xff);
  484         ADD_BYTE(~fcs0 >> 8);
  485         sc->abuf[alen++] = PPP_FLAG;
  486 
  487         /* Put frame in an mbuf and ship it off */
  488         if (!(m = m_devget(sc->abuf, alen, 0, rcvif, NULL))) {
  489                 NG_FREE_ITEM(item);
  490                 error = ENOBUFS;
  491         } else {
  492                 NG_FWD_NEW_DATA(error, item, sc->async, m);
  493         }
  494         return (error);
  495 }
  496 
  497 /*
  498  * Receive incoming asynchronous data
  499  * XXX Technically, we should strip out incoming characters
  500  *     that are in our ACCM. Not sure if this is good or not.
  501  */
  502 static int
  503 nga_rcv_async(const sc_p sc, item_p item)
  504 {
  505         struct ifnet *rcvif;
  506         int error;
  507         struct mbuf *m;
  508 
  509         if (!sc->cfg.enabled) {
  510                 NG_FWD_ITEM_HOOK(error, item,  sc->sync);
  511                 return (error);
  512         }
  513         NGI_GET_M(item, m);
  514         rcvif = m->m_pkthdr.rcvif;
  515         while (m) {
  516                 struct mbuf *n;
  517 
  518                 for (; m->m_len > 0; m->m_data++, m->m_len--) {
  519                         u_char  ch = *mtod(m, u_char *);
  520 
  521                         sc->stats.asyncOctets++;
  522                         if (ch == PPP_FLAG) {   /* Flag overrides everything */
  523                                 int     skip = 0;
  524 
  525                                 /* Check for runts */
  526                                 if (sc->slen < 2) {
  527                                         if (sc->slen > 0)
  528                                                 sc->stats.asyncRunts++;
  529                                         goto reset;
  530                                 }
  531 
  532                                 /* Verify CRC */
  533                                 if (sc->fcs != PPP_GOODFCS) {
  534                                         sc->stats.asyncBadCheckSums++;
  535                                         goto reset;
  536                                 }
  537                                 sc->slen -= 2;
  538 
  539                                 /* Strip address and control fields */
  540                                 if (sc->slen >= 2
  541                                     && sc->sbuf[0] == PPP_ALLSTATIONS
  542                                     && sc->sbuf[1] == PPP_UI)
  543                                         skip = 2;
  544 
  545                                 /* Check for frame too big */
  546                                 if (sc->slen - skip > sc->cfg.amru) {
  547                                         sc->stats.asyncOverflows++;
  548                                         goto reset;
  549                                 }
  550 
  551                                 /* OK, ship it out */
  552                                 if ((n = m_devget(sc->sbuf + skip,
  553                                            sc->slen - skip, 0, rcvif, NULL))) {
  554                                         if (item) { /* sets NULL -> item */
  555                                                 NG_FWD_NEW_DATA(error, item,
  556                                                         sc->sync, n);
  557                                         } else {
  558                                                 NG_SEND_DATA_ONLY(error,
  559                                                         sc->sync ,n);
  560                                         }
  561                                 }
  562                                 sc->stats.asyncFrames++;
  563 reset:
  564                                 sc->amode = MODE_NORMAL;
  565                                 sc->fcs = PPP_INITFCS;
  566                                 sc->slen = 0;
  567                                 continue;
  568                         }
  569                         switch (sc->amode) {
  570                         case MODE_NORMAL:
  571                                 if (ch == PPP_ESCAPE) {
  572                                         sc->amode = MODE_ESC;
  573                                         continue;
  574                                 }
  575                                 break;
  576                         case MODE_ESC:
  577                                 ch ^= PPP_TRANS;
  578                                 sc->amode = MODE_NORMAL;
  579                                 break;
  580                         case MODE_HUNT:
  581                         default:
  582                                 continue;
  583                         }
  584 
  585                         /* Add byte to frame */
  586                         if (sc->slen >= SYNC_BUF_SIZE(sc->cfg.amru)) {
  587                                 sc->stats.asyncOverflows++;
  588                                 sc->amode = MODE_HUNT;
  589                                 sc->slen = 0;
  590                         } else {
  591                                 sc->sbuf[sc->slen++] = ch;
  592                                 sc->fcs = PPP_FCS(sc->fcs, ch);
  593                         }
  594                 }
  595                 m = m_free(m);
  596         }
  597         if (item)
  598                 NG_FREE_ITEM(item);
  599         return (0);
  600 }
  601 
  602 /*
  603  * CRC table
  604  *
  605  * Taken from RFC 1171 Appendix B
  606  */
  607 static const u_int16_t fcstab[256] = {
  608          0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
  609          0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
  610          0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
  611          0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
  612          0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
  613          0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
  614          0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
  615          0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
  616          0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
  617          0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
  618          0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
  619          0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
  620          0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
  621          0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
  622          0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
  623          0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
  624          0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
  625          0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
  626          0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
  627          0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
  628          0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
  629          0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
  630          0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
  631          0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
  632          0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
  633          0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
  634          0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
  635          0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
  636          0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
  637          0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
  638          0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
  639          0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
  640 };

Cache object: b26e6a11d40841c23fa9f77f19597bda


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