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

Cache object: 663acbcb810826d93f9dfb755637bd01


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