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/net/ppp-deflate.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 /*      $OpenBSD: ppp-deflate.c,v 1.17 2021/07/22 16:40:19 tb Exp $     */
    2 /*      $NetBSD: ppp-deflate.c,v 1.1 1996/03/15 02:28:09 paulus Exp $   */
    3 
    4 /*
    5  * ppp_deflate.c - interface the zlib procedures for Deflate compression
    6  * and decompression (as used by gzip) to the PPP code.
    7  * This version is for use with mbufs on BSD-derived systems.
    8  *
    9  * Copyright (c) 1989-2002 Paul Mackerras. All rights reserved.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  *
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  *
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in
   20  *    the documentation and/or other materials provided with the
   21  *    distribution.
   22  *
   23  * 3. The name(s) of the authors of this software must not be used to
   24  *    endorse or promote products derived from this software without
   25  *    prior written permission.
   26  *
   27  * 4. Redistributions of any form whatsoever must retain the following
   28  *    acknowledgment:
   29  *    "This product includes software developed by Paul Mackerras
   30  *     <paulus@samba.org>".
   31  *
   32  * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
   33  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
   34  * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
   35  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   36  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
   37  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
   38  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   39  */
   40 
   41 #include <sys/param.h>
   42 #include <sys/systm.h>
   43 #include <sys/mbuf.h>
   44 #include <net/ppp_defs.h>
   45 #include <lib/libz/zlib.h>
   46 
   47 #define PACKETPTR       struct mbuf *
   48 #include <net/ppp-comp.h>
   49 
   50 #if DO_DEFLATE
   51 
   52 /*
   53  * State for a Deflate (de)compressor.
   54  */
   55 struct deflate_state {
   56     int         seqno;
   57     int         w_size;
   58     int         unit;
   59     int         hdrlen;
   60     int         mru;
   61     int         debug;
   62     z_stream    strm;
   63     struct compstat stats;
   64 };
   65 
   66 #define DEFLATE_OVHD    2               /* Deflate overhead/packet */
   67 
   68 static void     *zcalloc(void *, u_int items, u_int size);
   69 static void     zcfree(void *, void *ptr, u_int size);
   70 static void     *z_comp_alloc(u_char *options, int opt_len);
   71 static void     *z_decomp_alloc(u_char *options, int opt_len);
   72 static void     z_comp_free(void *state);
   73 static void     z_decomp_free(void *state);
   74 static int      z_comp_init(void *state, u_char *options, int opt_len,
   75                                  int unit, int hdrlen, int debug);
   76 static int      z_decomp_init(void *state, u_char *options, int opt_len,
   77                                      int unit, int hdrlen, int mru, int debug);
   78 static int      z_compress(void *state, struct mbuf **mret,
   79                                   struct mbuf *mp, int slen, int maxolen);
   80 static void     z_incomp(void *state, struct mbuf *dmsg);
   81 static int      z_decompress(void *state, struct mbuf *cmp,
   82                                     struct mbuf **dmpp);
   83 static void     z_comp_reset(void *state);
   84 static void     z_decomp_reset(void *state);
   85 static void     z_comp_stats(void *state, struct compstat *stats);
   86 
   87 /*
   88  * Procedures exported to if_ppp.c.
   89  */
   90 struct compressor ppp_deflate = {
   91     CI_DEFLATE,                 /* compress_proto */
   92     z_comp_alloc,               /* comp_alloc */
   93     z_comp_free,                /* comp_free */
   94     z_comp_init,                /* comp_init */
   95     z_comp_reset,               /* comp_reset */
   96     z_compress,                 /* compress */
   97     z_comp_stats,               /* comp_stat */
   98     z_decomp_alloc,             /* decomp_alloc */
   99     z_decomp_free,              /* decomp_free */
  100     z_decomp_init,              /* decomp_init */
  101     z_decomp_reset,             /* decomp_reset */
  102     z_decompress,               /* decompress */
  103     z_incomp,                   /* incomp */
  104     z_comp_stats,               /* decomp_stat */
  105 };
  106 
  107 struct compressor ppp_deflate_draft = {
  108     CI_DEFLATE_DRAFT,           /* compress_proto */
  109     z_comp_alloc,               /* comp_alloc */
  110     z_comp_free,                /* comp_free */
  111     z_comp_init,                /* comp_init */
  112     z_comp_reset,               /* comp_reset */
  113     z_compress,                 /* compress */
  114     z_comp_stats,               /* comp_stat */
  115     z_decomp_alloc,             /* decomp_alloc */
  116     z_decomp_free,              /* decomp_free */
  117     z_decomp_init,              /* decomp_init */
  118     z_decomp_reset,             /* decomp_reset */
  119     z_decompress,               /* decompress */
  120     z_incomp,                   /* incomp */
  121     z_comp_stats,               /* decomp_stat */
  122 };
  123 /*
  124  * Space allocation and freeing routines for use by zlib routines.
  125  */
  126 void *
  127 zcalloc(void *notused, u_int items, u_int size)
  128 {
  129     void *ptr;
  130 
  131     ptr = mallocarray(items, size, M_DEVBUF, M_NOWAIT);
  132     return ptr;
  133 }
  134 
  135 void
  136 zcfree(void *notused, void *ptr, u_int size)
  137 {
  138     free(ptr, M_DEVBUF, size);
  139 }
  140 
  141 /*
  142  * Allocate space for a compressor.
  143  */
  144 static void *
  145 z_comp_alloc(u_char *options, int opt_len)
  146 {
  147     struct deflate_state *state;
  148     int w_size;
  149 
  150     if (opt_len != CILEN_DEFLATE
  151         || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
  152         || options[1] != CILEN_DEFLATE
  153         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
  154         || options[3] != DEFLATE_CHK_SEQUENCE)
  155         return NULL;
  156     w_size = DEFLATE_SIZE(options[2]);
  157     if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
  158         return NULL;
  159 
  160     state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT);
  161     if (state == NULL)
  162         return NULL;
  163 
  164     state->strm.next_in = NULL;
  165     state->strm.zalloc = zcalloc;
  166     state->strm.zfree = zcfree;
  167     if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL,
  168                      -w_size, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
  169         free(state, M_DEVBUF, 0);
  170         return NULL;
  171     }
  172 
  173     state->w_size = w_size;
  174     bzero(&state->stats, sizeof(state->stats));
  175     return (void *) state;
  176 }
  177 
  178 static void
  179 z_comp_free(void *arg)
  180 {
  181     struct deflate_state *state = (struct deflate_state *) arg;
  182 
  183     deflateEnd(&state->strm);
  184     free(state, M_DEVBUF, 0);
  185 }
  186 
  187 static int
  188 z_comp_init(void *arg, u_char *options, int opt_len, int unit, int hdrlen,
  189     int debug)
  190 {
  191     struct deflate_state *state = (struct deflate_state *) arg;
  192 
  193     if (opt_len < CILEN_DEFLATE
  194         || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
  195         || options[1] != CILEN_DEFLATE
  196         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
  197         || DEFLATE_SIZE(options[2]) != state->w_size
  198         || options[3] != DEFLATE_CHK_SEQUENCE)
  199         return 0;
  200 
  201     state->seqno = 0;
  202     state->unit = unit;
  203     state->hdrlen = hdrlen;
  204     state->debug = debug;
  205 
  206     deflateReset(&state->strm);
  207 
  208     return 1;
  209 }
  210 
  211 static void
  212 z_comp_reset(void *arg)
  213 {
  214     struct deflate_state *state = (struct deflate_state *) arg;
  215 
  216     state->seqno = 0;
  217     deflateReset(&state->strm);
  218 }
  219 
  220 int
  221 z_compress(void *arg,
  222     struct mbuf **mret,         /* compressed packet (out) */
  223     struct mbuf *mp,            /* uncompressed packet (in) */
  224     int orig_len, int maxolen)
  225 {
  226     struct deflate_state *state = (struct deflate_state *) arg;
  227     u_char *rptr, *wptr;
  228     int proto, olen, wspace, r, flush;
  229     struct mbuf *m;
  230 
  231     /*
  232      * Check that the protocol is in the range we handle.
  233      */
  234     rptr = mtod(mp, u_char *);
  235     proto = PPP_PROTOCOL(rptr);
  236     if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) {
  237         *mret = NULL;
  238         return orig_len;
  239     }
  240 
  241     /* Allocate one mbuf initially. */
  242     if (maxolen > orig_len)
  243         maxolen = orig_len;
  244     MGET(m, M_DONTWAIT, MT_DATA);
  245     *mret = m;
  246     if (m != NULL) {
  247         m->m_len = 0;
  248         if (maxolen + state->hdrlen > MLEN)
  249             MCLGET(m, M_DONTWAIT);
  250         wspace = m_trailingspace(m);
  251         if (state->hdrlen + PPP_HDRLEN + 2 < wspace) {
  252             m->m_data += state->hdrlen;
  253             wspace -= state->hdrlen;
  254         }
  255         wptr = mtod(m, u_char *);
  256 
  257         /*
  258          * Copy over the PPP header and store the 2-byte sequence number.
  259          */
  260         wptr[0] = PPP_ADDRESS(rptr);
  261         wptr[1] = PPP_CONTROL(rptr);
  262         wptr[2] = PPP_COMP >> 8;
  263         wptr[3] = PPP_COMP;
  264         wptr += PPP_HDRLEN;
  265         wptr[0] = state->seqno >> 8;
  266         wptr[1] = state->seqno;
  267         wptr += 2;
  268         state->strm.next_out = wptr;
  269         state->strm.avail_out = wspace - (PPP_HDRLEN + 2);
  270     } else {
  271         state->strm.next_out = NULL;
  272         state->strm.avail_out = 1000000;
  273         wptr = NULL;
  274         wspace = 0;
  275     }
  276     ++state->seqno;
  277 
  278     rptr += (proto > 0xff)? 2: 3;       /* skip 1st proto byte if 0 */
  279     state->strm.next_in = rptr;
  280     state->strm.avail_in = mtod(mp, u_char *) + mp->m_len - rptr;
  281     mp = mp->m_next;
  282     flush = (mp == NULL)? Z_SYNC_FLUSH: Z_NO_FLUSH;
  283     olen = 0;
  284     for (;;) {
  285         r = deflate(&state->strm, flush);
  286         if (r != Z_OK) {
  287             printf("z_compress: deflate returned %d (%s)\n",
  288                    r, (state->strm.msg? state->strm.msg: ""));
  289             break;
  290         }
  291         if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
  292             break;              /* all done */
  293         if (state->strm.avail_in == 0 && mp != NULL) {
  294             state->strm.next_in = mtod(mp, u_char *);
  295             state->strm.avail_in = mp->m_len;
  296             mp = mp->m_next;
  297             if (mp == NULL)
  298                 flush = Z_SYNC_FLUSH;
  299         }
  300         if (state->strm.avail_out == 0) {
  301             if (m != NULL) {
  302                 m->m_len = wspace;
  303                 olen += wspace;
  304                 MGET(m->m_next, M_DONTWAIT, MT_DATA);
  305                 m = m->m_next;
  306                 if (m != NULL) {
  307                     m->m_len = 0;
  308                     if (maxolen - olen > MLEN)
  309                         MCLGET(m, M_DONTWAIT);
  310                     state->strm.next_out = mtod(m, u_char *);
  311                     state->strm.avail_out = wspace = m_trailingspace(m);
  312                 }
  313             }
  314             if (m == NULL) {
  315                 state->strm.next_out = NULL;
  316                 state->strm.avail_out = 1000000;
  317             }
  318         }
  319     }
  320     if (m != NULL)
  321         olen += (m->m_len = wspace - state->strm.avail_out);
  322 
  323     /*
  324      * See if we managed to reduce the size of the packet.
  325      * If the compressor just gave us a single zero byte, it means
  326      * the packet was incompressible.
  327      */
  328     if (m != NULL && olen < orig_len
  329         && !(olen == PPP_HDRLEN + 3 && *wptr == 0)) {
  330         state->stats.comp_bytes += olen;
  331         state->stats.comp_packets++;
  332     } else {
  333         m_freemp(mret);
  334 
  335         state->stats.inc_bytes += orig_len;
  336         state->stats.inc_packets++;
  337         olen = orig_len;
  338     }
  339     state->stats.unc_bytes += orig_len;
  340     state->stats.unc_packets++;
  341 
  342     return olen;
  343 }
  344 
  345 static void
  346 z_comp_stats(void *arg, struct compstat *stats)
  347 {
  348     struct deflate_state *state = (struct deflate_state *) arg;
  349     u_int out;
  350 
  351     *stats = state->stats;
  352     stats->ratio = stats->unc_bytes;
  353     out = stats->comp_bytes + stats->inc_bytes;
  354     if (stats->ratio <= 0x7ffffff)
  355         stats->ratio <<= 8;
  356     else
  357         out >>= 8;
  358     if (out != 0)
  359         stats->ratio /= out;
  360 }
  361 
  362 /*
  363  * Allocate space for a decompressor.
  364  */
  365 static void *
  366 z_decomp_alloc(u_char *options, int opt_len)
  367 {
  368     struct deflate_state *state;
  369     int w_size;
  370 
  371     if (opt_len != CILEN_DEFLATE
  372         || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
  373         || options[1] != CILEN_DEFLATE
  374         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
  375         || options[3] != DEFLATE_CHK_SEQUENCE)
  376         return NULL;
  377     w_size = DEFLATE_SIZE(options[2]);
  378     if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
  379         return NULL;
  380 
  381     state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT);
  382     if (state == NULL)
  383         return NULL;
  384 
  385     state->strm.next_out = NULL;
  386     state->strm.zalloc = zcalloc;
  387     state->strm.zfree = zcfree;
  388     if (inflateInit2(&state->strm, -w_size) != Z_OK) {
  389         free(state, M_DEVBUF, 0);
  390         return NULL;
  391     }
  392 
  393     state->w_size = w_size;
  394     bzero(&state->stats, sizeof(state->stats));
  395     return (void *) state;
  396 }
  397 
  398 static void
  399 z_decomp_free(void *arg)
  400 {
  401     struct deflate_state *state = (struct deflate_state *) arg;
  402 
  403     inflateEnd(&state->strm);
  404     free(state, M_DEVBUF, 0);
  405 }
  406 
  407 static int
  408 z_decomp_init(void *arg, u_char *options, int opt_len, int unit, int hdrlen,
  409     int mru, int debug)
  410 {
  411     struct deflate_state *state = (struct deflate_state *) arg;
  412 
  413     if (opt_len < CILEN_DEFLATE
  414         || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
  415         || options[1] != CILEN_DEFLATE
  416         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
  417         || DEFLATE_SIZE(options[2]) != state->w_size
  418         || options[3] != DEFLATE_CHK_SEQUENCE)
  419         return 0;
  420 
  421     state->seqno = 0;
  422     state->unit = unit;
  423     state->hdrlen = hdrlen;
  424     state->debug = debug;
  425     state->mru = mru;
  426 
  427     inflateReset(&state->strm);
  428 
  429     return 1;
  430 }
  431 
  432 static void
  433 z_decomp_reset(void *arg)
  434 {
  435     struct deflate_state *state = (struct deflate_state *) arg;
  436 
  437     state->seqno = 0;
  438     inflateReset(&state->strm);
  439 }
  440 
  441 /*
  442  * Decompress a Deflate-compressed packet.
  443  *
  444  * Because of patent problems, we return DECOMP_ERROR for errors
  445  * found by inspecting the input data and for system problems, but
  446  * DECOMP_FATALERROR for any errors which could possibly be said to
  447  * be being detected "after" decompression.  For DECOMP_ERROR,
  448  * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
  449  * infringing a patent of Motorola's if we do, so we take CCP down
  450  * instead.
  451  *
  452  * Given that the frame has the correct sequence number and a good FCS,
  453  * errors such as invalid codes in the input most likely indicate a
  454  * bug, so we return DECOMP_FATALERROR for them in order to turn off
  455  * compression, even though they are detected by inspecting the input.
  456  */
  457 int
  458 z_decompress(void *arg, struct mbuf *mi, struct mbuf **mop)
  459 {
  460     struct deflate_state *state = (struct deflate_state *) arg;
  461     struct mbuf *mo, *mo_head;
  462     u_char *rptr, *wptr;
  463     int rlen, olen, ospace;
  464     int seq, i, flush, r, decode_proto;
  465     u_char hdr[PPP_HDRLEN + DEFLATE_OVHD];
  466 
  467     *mop = NULL;
  468     rptr = mtod(mi, u_char *);
  469     rlen = mi->m_len;
  470     for (i = 0; i < PPP_HDRLEN + DEFLATE_OVHD; ++i) {
  471         while (rlen <= 0) {
  472             mi = mi->m_next;
  473             if (mi == NULL)
  474                 return DECOMP_ERROR;
  475             rptr = mtod(mi, u_char *);
  476             rlen = mi->m_len;
  477         }
  478         hdr[i] = *rptr++;
  479         --rlen;
  480     }
  481 
  482     /* Check the sequence number. */
  483     seq = (hdr[PPP_HDRLEN] << 8) + hdr[PPP_HDRLEN+1];
  484     if (seq != state->seqno) {
  485         if (state->debug)
  486             printf("z_decompress%d: bad seq # %d, expected %d\n",
  487                    state->unit, seq, state->seqno);
  488         return DECOMP_ERROR;
  489     }
  490     ++state->seqno;
  491 
  492     /* Allocate an output mbuf. */
  493     MGETHDR(mo, M_DONTWAIT, MT_DATA);
  494     if (mo == NULL)
  495         return DECOMP_ERROR;
  496     mo_head = mo;
  497     mo->m_len = 0;
  498     mo->m_next = NULL;
  499     MCLGET(mo, M_DONTWAIT);
  500     ospace = m_trailingspace(mo);
  501     if (state->hdrlen + PPP_HDRLEN < ospace) {
  502         mo->m_data += state->hdrlen;
  503         ospace -= state->hdrlen;
  504     }
  505 
  506     /*
  507      * Fill in the first part of the PPP header.  The protocol field
  508      * comes from the decompressed data.
  509      */
  510     wptr = mtod(mo, u_char *);
  511     wptr[0] = PPP_ADDRESS(hdr);
  512     wptr[1] = PPP_CONTROL(hdr);
  513     wptr[2] = 0;
  514 
  515     /*
  516      * Set up to call inflate.  We set avail_out to 1 initially so we can
  517      * look at the first byte of the output and decide whether we have
  518      * a 1-byte or 2-byte protocol field.
  519      */
  520     state->strm.next_in = rptr;
  521     state->strm.avail_in = rlen;
  522     mi = mi->m_next;
  523     flush = (mi == NULL)? Z_SYNC_FLUSH: Z_NO_FLUSH;
  524     rlen += PPP_HDRLEN + DEFLATE_OVHD;
  525     state->strm.next_out = wptr + 3;
  526     state->strm.avail_out = 1;
  527     decode_proto = 1;
  528     olen = PPP_HDRLEN;
  529 
  530     /*
  531      * Call inflate, supplying more input or output as needed.
  532      */
  533     for (;;) {
  534         r = inflate(&state->strm, flush);
  535         if (r != Z_OK) {
  536 #ifndef DEFLATE_DEBUG
  537             if (state->debug)
  538 #endif
  539                 printf("z_decompress%d: inflate returned %d (%s)\n",
  540                        state->unit, r, (state->strm.msg? state->strm.msg: ""));
  541             m_freem(mo_head);
  542             return DECOMP_FATALERROR;
  543         }
  544         if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
  545             break;              /* all done */
  546         if (state->strm.avail_in == 0 && mi != NULL) {
  547             state->strm.next_in = mtod(mi, u_char *);
  548             state->strm.avail_in = mi->m_len;
  549             rlen += mi->m_len;
  550             mi = mi->m_next;
  551             if (mi == NULL)
  552                 flush = Z_SYNC_FLUSH;
  553         }
  554         if (state->strm.avail_out == 0) {
  555             if (decode_proto) {
  556                 state->strm.avail_out = ospace - PPP_HDRLEN;
  557                 if ((wptr[3] & 1) == 0) {
  558                     /* 2-byte protocol field */
  559                     wptr[2] = wptr[3];
  560                     --state->strm.next_out;
  561                     ++state->strm.avail_out;
  562                     --olen;
  563                 }
  564                 decode_proto = 0;
  565             } else {
  566                 mo->m_len = ospace;
  567                 olen += ospace;
  568                 MGET(mo->m_next, M_DONTWAIT, MT_DATA);
  569                 mo = mo->m_next;
  570                 if (mo == NULL) {
  571                     m_freem(mo_head);
  572                     return DECOMP_ERROR;
  573                 }
  574                 MCLGET(mo, M_DONTWAIT);
  575                 state->strm.next_out = mtod(mo, u_char *);
  576                 state->strm.avail_out = ospace = m_trailingspace(mo);
  577             }
  578         }
  579     }
  580     if (decode_proto) {
  581         m_freem(mo_head);
  582         return DECOMP_ERROR;
  583     }
  584     olen += (mo->m_len = ospace - state->strm.avail_out);
  585 #ifdef DEFLATE_DEBUG
  586     if (olen > state->mru + PPP_HDRLEN)
  587         printf("ppp_deflate%d: exceeded mru (%d > %d)\n",
  588                state->unit, olen, state->mru + PPP_HDRLEN);
  589 #endif
  590 
  591     state->stats.unc_bytes += olen;
  592     state->stats.unc_packets++;
  593     state->stats.comp_bytes += rlen;
  594     state->stats.comp_packets++;
  595 
  596     *mop = mo_head;
  597     return DECOMP_OK;
  598 }
  599 
  600 /*
  601  * Incompressible data has arrived - add it to the history.
  602  */
  603 static void
  604 z_incomp(void *arg, struct mbuf *mi)
  605 {
  606     struct deflate_state *state = (struct deflate_state *) arg;
  607     u_char *rptr;
  608     int rlen, proto, r;
  609 
  610     /*
  611      * Check that the protocol is one we handle.
  612      */
  613     rptr = mtod(mi, u_char *);
  614     proto = PPP_PROTOCOL(rptr);
  615     if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
  616         return;
  617 
  618     ++state->seqno;
  619 
  620     /*
  621      * Iterate through the mbufs, adding the characters in them
  622      * to the decompressor's history.  For the first mbuf, we start
  623      * at the either the 1st or 2nd byte of the protocol field,
  624      * depending on whether the protocol value is compressible.
  625      */
  626     rlen = mi->m_len;
  627     state->strm.next_in = rptr + 3;
  628     state->strm.avail_in = rlen - 3;
  629     if (proto > 0xff) {
  630         --state->strm.next_in;
  631         ++state->strm.avail_in;
  632     }
  633     for (;;) {
  634         r = inflateInit(&state->strm);
  635         if (r != Z_OK) {
  636             /* gak! */
  637 #ifndef DEFLATE_DEBUG
  638             if (state->debug)
  639 #endif
  640                 printf("z_incomp%d: inflateIncomp returned %d (%s)\n",
  641                        state->unit, r, (state->strm.msg? state->strm.msg: ""));
  642             return;
  643         }
  644         mi = mi->m_next;
  645         if (mi == NULL)
  646             break;
  647         state->strm.next_in = mtod(mi, u_char *);
  648         state->strm.avail_in = mi->m_len;
  649         rlen += mi->m_len;
  650     }
  651 
  652     /*
  653      * Update stats.
  654      */
  655     state->stats.inc_bytes += rlen;
  656     state->stats.inc_packets++;
  657     state->stats.unc_bytes += rlen;
  658     state->stats.unc_packets++;
  659 }
  660 
  661 #endif /* DO_DEFLATE */

Cache object: ef6e444a507711392452772c6c9d0415


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