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

Cache object: b099819854d3aa3f8fc65ae2e8dfdd0f


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