source: rtems/cpukit/libnetworking/net/ppp-deflate.c @ 0286b9f

4.104.114.84.9
Last change on this file since 0286b9f was 0286b9f, checked in by Joel Sherrill <joel.sherrill@…>, on Jan 31, 2002 at 9:42:11 PM

2001-01-31 Mike Siers <mikes@…>

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