root/net/ppp-deflate.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. zalloc
  2. zfree
  3. z_comp_alloc
  4. z_comp_free
  5. z_comp_init
  6. z_comp_reset
  7. z_compress
  8. z_comp_stats
  9. z_decomp_alloc
  10. z_decomp_free
  11. z_decomp_init
  12. z_decomp_reset
  13. z_decompress
  14. z_incomp

    1 /*      $OpenBSD: ppp-deflate.c,v 1.7 2002/09/13 00:12:07 deraadt 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/types.h>
   43 #include <sys/systm.h>
   44 #include <sys/mbuf.h>
   45 #include <net/ppp_defs.h>
   46 #include <net/zlib.h>
   47 
   48 #define PACKETPTR       struct mbuf *
   49 #include <net/ppp-comp.h>
   50 
   51 #if DO_DEFLATE
   52 
   53 /*
   54  * State for a Deflate (de)compressor.
   55  */
   56 struct deflate_state {
   57     int         seqno;
   58     int         w_size;
   59     int         unit;
   60     int         hdrlen;
   61     int         mru;
   62     int         debug;
   63     z_stream    strm;
   64     struct compstat stats;
   65 };
   66 
   67 #define DEFLATE_OVHD    2               /* Deflate overhead/packet */
   68 
   69 static void     *zalloc(void *, u_int items, u_int size);
   70 static void     zfree(void *, void *ptr, u_int nb);
   71 static void     *z_comp_alloc(u_char *options, int opt_len);
   72 static void     *z_decomp_alloc(u_char *options, int opt_len);
   73 static void     z_comp_free(void *state);
   74 static void     z_decomp_free(void *state);
   75 static int      z_comp_init(void *state, u_char *options, int opt_len,
   76                                  int unit, int hdrlen, int debug);
   77 static int      z_decomp_init(void *state, u_char *options, int opt_len,
   78                                      int unit, int hdrlen, int mru, int debug);
   79 static int      z_compress(void *state, struct mbuf **mret,
   80                                   struct mbuf *mp, int slen, int maxolen);
   81 static void     z_incomp(void *state, struct mbuf *dmsg);
   82 static int      z_decompress(void *state, struct mbuf *cmp,
   83                                     struct mbuf **dmpp);
   84 static void     z_comp_reset(void *state);
   85 static void     z_decomp_reset(void *state);
   86 static void     z_comp_stats(void *state, struct compstat *stats);
   87 
   88 /*
   89  * Procedures exported to if_ppp.c.
   90  */
   91 struct compressor ppp_deflate = {
   92     CI_DEFLATE,                 /* compress_proto */
   93     z_comp_alloc,               /* comp_alloc */
   94     z_comp_free,                /* comp_free */
   95     z_comp_init,                /* comp_init */
   96     z_comp_reset,               /* comp_reset */
   97     z_compress,                 /* compress */
   98     z_comp_stats,               /* comp_stat */
   99     z_decomp_alloc,             /* decomp_alloc */
  100     z_decomp_free,              /* decomp_free */
  101     z_decomp_init,              /* decomp_init */
  102     z_decomp_reset,             /* decomp_reset */
  103     z_decompress,               /* decompress */
  104     z_incomp,                   /* incomp */
  105     z_comp_stats,               /* decomp_stat */
  106 };
  107 
  108 struct compressor ppp_deflate_draft = {
  109     CI_DEFLATE_DRAFT,           /* compress_proto */
  110     z_comp_alloc,               /* comp_alloc */
  111     z_comp_free,                /* comp_free */
  112     z_comp_init,                /* comp_init */
  113     z_comp_reset,               /* comp_reset */
  114     z_compress,                 /* compress */
  115     z_comp_stats,               /* comp_stat */
  116     z_decomp_alloc,             /* decomp_alloc */
  117     z_decomp_free,              /* decomp_free */
  118     z_decomp_init,              /* decomp_init */
  119     z_decomp_reset,             /* decomp_reset */
  120     z_decompress,               /* decompress */
  121     z_incomp,                   /* incomp */
  122     z_comp_stats,               /* decomp_stat */
  123 };
  124 /*
  125  * Space allocation and freeing routines for use by zlib routines.
  126  */
  127 void *
  128 zalloc(notused, items, size)
  129     void *notused;
  130     u_int items, size;
  131 {
  132     void *ptr;
  133 
  134     MALLOC(ptr, void *, items * size, M_DEVBUF, M_NOWAIT);
  135     return ptr;
  136 }
  137 
  138 void
  139 zfree(notused, ptr, nbytes)
  140     void *notused;
  141     void *ptr;
  142     u_int nbytes;
  143 {
  144     FREE(ptr, M_DEVBUF);
  145 }
  146 
  147 /*
  148  * Allocate space for a compressor.
  149  */
  150 static void *
  151 z_comp_alloc(options, opt_len)
  152     u_char *options;
  153     int opt_len;
  154 {
  155     struct deflate_state *state;
  156     int w_size;
  157 
  158     if (opt_len != CILEN_DEFLATE
  159         || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
  160         || options[1] != CILEN_DEFLATE
  161         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
  162         || options[3] != DEFLATE_CHK_SEQUENCE)
  163         return NULL;
  164     w_size = DEFLATE_SIZE(options[2]);
  165     if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
  166         return NULL;
  167 
  168     MALLOC(state, struct deflate_state *, sizeof(struct deflate_state),
  169            M_DEVBUF, M_NOWAIT);
  170     if (state == NULL)
  171         return NULL;
  172 
  173     state->strm.next_in = NULL;
  174     state->strm.zalloc = zalloc;
  175     state->strm.zfree = zfree;
  176     if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL,
  177                      -w_size, 8, Z_DEFAULT_STRATEGY, DEFLATE_OVHD+2) != Z_OK) {
  178         FREE(state, M_DEVBUF);
  179         return NULL;
  180     }
  181 
  182     state->w_size = w_size;
  183     bzero(&state->stats, sizeof(state->stats));
  184     return (void *) state;
  185 }
  186 
  187 static void
  188 z_comp_free(arg)
  189     void *arg;
  190 {
  191     struct deflate_state *state = (struct deflate_state *) arg;
  192 
  193     deflateEnd(&state->strm);
  194     FREE(state, M_DEVBUF);
  195 }
  196 
  197 static int
  198 z_comp_init(arg, options, opt_len, unit, hdrlen, debug)
  199     void *arg;
  200     u_char *options;
  201     int opt_len, unit, hdrlen, debug;
  202 {
  203     struct deflate_state *state = (struct deflate_state *) arg;
  204 
  205     if (opt_len < CILEN_DEFLATE
  206         || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
  207         || options[1] != CILEN_DEFLATE
  208         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
  209         || DEFLATE_SIZE(options[2]) != state->w_size
  210         || options[3] != DEFLATE_CHK_SEQUENCE)
  211         return 0;
  212 
  213     state->seqno = 0;
  214     state->unit = unit;
  215     state->hdrlen = hdrlen;
  216     state->debug = debug;
  217 
  218     deflateReset(&state->strm);
  219 
  220     return 1;
  221 }
  222 
  223 static void
  224 z_comp_reset(arg)
  225     void *arg;
  226 {
  227     struct deflate_state *state = (struct deflate_state *) arg;
  228 
  229     state->seqno = 0;
  230     deflateReset(&state->strm);
  231 }
  232 
  233 int
  234 z_compress(arg, mret, mp, orig_len, maxolen)
  235     void *arg;
  236     struct mbuf **mret;         /* compressed packet (out) */
  237     struct mbuf *mp;            /* uncompressed packet (in) */
  238     int orig_len, maxolen;
  239 {
  240     struct deflate_state *state = (struct deflate_state *) arg;
  241     u_char *rptr, *wptr;
  242     int proto, olen, wspace, r, flush;
  243     struct mbuf *m;
  244 
  245     /*
  246      * Check that the protocol is in the range we handle.
  247      */
  248     rptr = mtod(mp, u_char *);
  249     proto = PPP_PROTOCOL(rptr);
  250     if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) {
  251         *mret = NULL;
  252         return orig_len;
  253     }
  254 
  255     /* Allocate one mbuf initially. */
  256     if (maxolen > orig_len)
  257         maxolen = orig_len;
  258     MGET(m, M_DONTWAIT, MT_DATA);
  259     *mret = m;
  260     if (m != NULL) {
  261         m->m_len = 0;
  262         if (maxolen + state->hdrlen > MLEN)
  263             MCLGET(m, M_DONTWAIT);
  264         wspace = M_TRAILINGSPACE(m);
  265         if (state->hdrlen + PPP_HDRLEN + 2 < wspace) {
  266             m->m_data += state->hdrlen;
  267             wspace -= state->hdrlen;
  268         }
  269         wptr = mtod(m, u_char *);
  270 
  271         /*
  272          * Copy over the PPP header and store the 2-byte sequence number.
  273          */
  274         wptr[0] = PPP_ADDRESS(rptr);
  275         wptr[1] = PPP_CONTROL(rptr);
  276         wptr[2] = PPP_COMP >> 8;
  277         wptr[3] = PPP_COMP;
  278         wptr += PPP_HDRLEN;
  279         wptr[0] = state->seqno >> 8;
  280         wptr[1] = state->seqno;
  281         wptr += 2;
  282         state->strm.next_out = wptr;
  283         state->strm.avail_out = wspace - (PPP_HDRLEN + 2);
  284     } else {
  285         state->strm.next_out = NULL;
  286         state->strm.avail_out = 1000000;
  287         wptr = NULL;
  288         wspace = 0;
  289     }
  290     ++state->seqno;
  291 
  292     rptr += (proto > 0xff)? 2: 3;       /* skip 1st proto byte if 0 */
  293     state->strm.next_in = rptr;
  294     state->strm.avail_in = mtod(mp, u_char *) + mp->m_len - rptr;
  295     mp = mp->m_next;
  296     flush = (mp == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH;
  297     olen = 0;
  298     for (;;) {
  299         r = deflate(&state->strm, flush);
  300         if (r != Z_OK) {
  301             printf("z_compress: deflate returned %d (%s)\n",
  302                    r, (state->strm.msg? state->strm.msg: ""));
  303             break;
  304         }
  305         if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
  306             break;              /* all done */
  307         if (state->strm.avail_in == 0 && mp != NULL) {
  308             state->strm.next_in = mtod(mp, u_char *);
  309             state->strm.avail_in = mp->m_len;
  310             mp = mp->m_next;
  311             if (mp == NULL)
  312                 flush = Z_PACKET_FLUSH;
  313         }
  314         if (state->strm.avail_out == 0) {
  315             if (m != NULL) {
  316                 m->m_len = wspace;
  317                 olen += wspace;
  318                 MGET(m->m_next, M_DONTWAIT, MT_DATA);
  319                 m = m->m_next;
  320                 if (m != NULL) {
  321                     m->m_len = 0;
  322                     if (maxolen - olen > MLEN)
  323                         MCLGET(m, M_DONTWAIT);
  324                     state->strm.next_out = mtod(m, u_char *);
  325                     state->strm.avail_out = wspace = M_TRAILINGSPACE(m);
  326                 }
  327             }
  328             if (m == NULL) {
  329                 state->strm.next_out = NULL;
  330                 state->strm.avail_out = 1000000;
  331             }
  332         }
  333     }
  334     if (m != NULL)
  335         olen += (m->m_len = wspace - state->strm.avail_out);
  336 
  337     /*
  338      * See if we managed to reduce the size of the packet.
  339      * If the compressor just gave us a single zero byte, it means
  340      * the packet was incompressible.
  341      */
  342     if (m != NULL && olen < orig_len
  343         && !(olen == PPP_HDRLEN + 3 && *wptr == 0)) {
  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     bzero(&state->stats, 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 = PPP_HDRLEN;
  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 #ifndef 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 #ifdef 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 #ifndef 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 */

/* [<][>][^][v][top][bottom][index][help] */