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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [ppp/] [current/] [src/] [ppp_deflate.c] - Blame information for rev 786

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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