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

Cache object: 729b0abc57a3818060a73d4115ad0eb4


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