OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [libnetworking/] [net/] [ppp-deflate.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*      ppp-deflate.c,v 1.1 2002/01/31 21:40:47 joel Exp        */
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
 */
49
struct 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
 
62
static void     *zalloc __P((void *, u_int items, u_int size));
63
static void     zfree __P((void *, void *ptr));
64
static void     *z_comp_alloc __P((u_char *options, int opt_len));
65
static void     *z_decomp_alloc __P((u_char *options, int opt_len));
66
static void     z_comp_free __P((void *state));
67
static void     z_decomp_free __P((void *state));
68
static int      z_comp_init __P((void *state, u_char *options, int opt_len,
69
                                 int unit, int hdrlen, int debug));
70
static int      z_decomp_init __P((void *state, u_char *options, int opt_len,
71
                                     int unit, int hdrlen, int mru, int debug));
72
static int      z_compress __P((void *state, struct mbuf **mret,
73
                                  struct mbuf *mp, int slen, int maxolen));
74
static void     z_incomp __P((void *state, struct mbuf *dmsg));
75
static int      z_decompress __P((void *state, struct mbuf *cmp,
76
                                    struct mbuf **dmpp));
77
static void     z_comp_reset __P((void *state));
78
static void     z_decomp_reset __P((void *state));
79
static void     z_comp_stats __P((void *state, struct compstat *stats));
80
 
81
/*
82
 * Procedures exported to if_ppp.c.
83
 */
84
struct 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
 
101
struct 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
 */
121
void *
122
zalloc(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
 
132
void
133
zfree(notused, ptr)
134
    void *notused;
135
    void *ptr;
136
{
137
    FREE(ptr, M_DEVBUF);
138
}
139
 
140
/*
141
 * Allocate space for a compressor.
142
 */
143
static void *
144
z_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
 
180
static void
181
z_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
 
190
static int
191
z_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
 
216
static void
217
z_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
 
226
int
227
z_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
 
354
static void
355
z_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
 */
376
static void *
377
z_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
 
412
static void
413
z_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
 
422
static int
423
z_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
 
449
static void
450
z_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
 */
475
int
476
z_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
 */
623
static void
624
z_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 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.