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

Cache object: 7d53db131186da7f53ed187d6ce75ccb


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