]> git.ozlabs.org Git - ppp.git/blob - linux/ppp_deflate.c
use vmalloc for large chunks,
[ppp.git] / linux / ppp_deflate.c
1 /*
2  *  ==FILEVERSION 961207==
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 Linux kernel 1.3.X.
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  * From: deflate.c,v 1.1 1996/01/18 03:17:48 paulus Exp
32  */
33
34 #include <linux/module.h>
35 #include <linux/version.h>
36
37 #include <endian.h>
38 #include <linux/kernel.h>
39 #include <linux/sched.h>
40 #include <linux/types.h>
41 #include <linux/fcntl.h>
42 #include <linux/interrupt.h>
43 #include <linux/ptrace.h>
44 #include <linux/ioport.h>
45 #include <linux/in.h>
46 #include <linux/malloc.h>
47 #include <linux/tty.h>
48 #include <linux/errno.h>
49 #include <linux/sched.h>        /* to get the struct task_struct */
50 #include <linux/string.h>       /* used in new tty drivers */
51 #include <linux/signal.h>       /* used in new tty drivers */
52
53 #include <asm/system.h>
54 #include <asm/bitops.h>
55 #include <asm/segment.h>
56
57 #include <linux/if.h>
58
59 #include <linux/if_ether.h>
60 #include <linux/netdevice.h>
61 #include <linux/skbuff.h>
62 #include <linux/inet.h>
63 #include <linux/ioctl.h>
64
65 #include <linux/ppp_defs.h>
66
67 #if LINUX_VERSION_CODE < 0x02010E
68 #include <linux/netprotocol.h>
69 #endif
70
71 #include <netinet/ip.h>
72 #include <netinet/tcp.h>
73 #include <linux/if_arp.h>
74 #include <linux/ppp-comp.h>
75
76 #include "zlib.c"
77
78 #define USEMEMPOOL      0       /* use kmalloc, not memPool routines */
79
80 /*
81  * State for a Deflate (de)compressor.
82  */
83 struct ppp_deflate_state {
84     int         seqno;
85     int         w_size;
86     int         unit;
87     int         mru;
88     int         debug;
89     int         in_alloc;       /* set when we're in [de]comp_alloc */
90     z_stream    strm;
91     struct compstat stats;
92 };
93
94 #define DEFLATE_OVHD    2               /* Deflate overhead/packet */
95
96 static void     *zalloc __P((void *, unsigned int items, unsigned int size));
97 static void     zfree __P((void *, void *ptr, unsigned int nb));
98 static void     *z_comp_alloc __P((unsigned char *options, int opt_len));
99 static void     *z_decomp_alloc __P((unsigned char *options, int opt_len));
100 static void     z_comp_free __P((void *state));
101 static void     z_decomp_free __P((void *state));
102 static int      z_comp_init __P((void *state, unsigned char *options,
103                                  int opt_len,
104                                  int unit, int hdrlen, int debug));
105 static int      z_decomp_init __P((void *state, unsigned char *options,
106                                    int opt_len,
107                                    int unit, int hdrlen, int mru, int debug));
108 static int      z_compress __P((void *state, unsigned char *rptr,
109                                 unsigned char *obuf,
110                                 int isize, int osize));
111 static void     z_incomp __P((void *state, unsigned char *ibuf, int icnt));
112 static int      z_decompress __P((void *state, unsigned char *ibuf,
113                                 int isize, unsigned char *obuf, int osize));
114 static void     z_comp_reset __P((void *state));
115 static void     z_decomp_reset __P((void *state));
116 static void     z_comp_stats __P((void *state, struct compstat *stats));
117
118 #if USEMEMPOOL
119 /*
120  * This is a small set of memory allocation routines.  I created them so
121  * that all memory allocation from the kernel takes place at the
122  * z_(de)comp_alloc and z_(de)comp_free routines.  This eliminates worry
123  * about calling valloc() from within an interrupt.
124  *
125  * The free list is a single linked list sorted by memory address.
126  * The zfree() function re-combines any segments it can.
127  */
128 typedef struct memchunk {
129     unsigned int m_size;
130     struct memchunk *m_next;
131 } MemChunk;
132
133 typedef struct {
134     void *memHead;
135     MemChunk *freePool;
136 } MemPool;
137
138 static int     memPoolAlloc __P((void *arg, unsigned int size));
139 static void    memPoolFree __P((void *arg));
140
141 static int
142 memPoolAlloc(arg, size)
143 void *arg;
144 unsigned int size;
145 {
146     MemPool **memPool = arg;
147     MemChunk *freePool;
148
149     if ((*memPool = kmalloc(sizeof(MemPool), GFP_KERNEL)) == NULL) {
150         printk(KERN_DEBUG "Unable to allocate Memory Head\n");
151         return 0;
152     }
153
154     if (((*memPool)->memHead = (void *)vmalloc(size)) == NULL) {
155         printk(KERN_DEBUG "Unable to allocate Memory Pool\n");
156         kfree(*memPool);
157         return 0;
158     }
159     freePool = (*memPool)->freePool = (*memPool)->memHead;
160     freePool->m_size = size;
161     freePool->m_next = 0;
162
163     return 1;
164 }
165
166 static void
167 memPoolFree(arg)
168 void *arg;
169 {
170     MemPool **memPool = arg;
171
172     if (*memPool) {
173         vfree((*memPool)->memHead);
174         kfree(*memPool);
175         *memPool = NULL;
176     }
177 }
178
179 #ifdef POOLDGB
180 static void    showFreeList __P((MemChunk *));
181
182 static void
183 showFreeList(freePool)
184 MemChunk *freePool;
185 {
186     MemChunk *node;
187     
188     for (node = freePool; node; node = node->m_next)
189         printk(KERN_DEBUG "{%x,%d}->", node, node->m_size);
190     printk(KERN_DEBUG "\n");
191 }
192 #endif
193 #endif /* USEMEMPOOL */
194
195 struct chunk_header {
196     unsigned size;              /* amount of space following header */
197     int valloced;               /* allocated with valloc, not kmalloc */
198 };
199
200 #define MIN_VMALLOC     2048    /* use kmalloc for blocks < this */
201
202 /*
203  * Space allocation and freeing routines for use by zlib routines.
204  */
205 void
206 zfree(arg, ptr, nbytes)
207     void *arg;
208     void *ptr;
209     unsigned int nbytes;
210 {
211 #if !USEMEMPOOL
212     struct chunk_header *hdr = ((struct chunk_header *)ptr) - 1;
213
214     if (hdr->valloced)
215         vfree(hdr);
216     else
217         kfree(hdr);
218 #else
219     MemPool *memPool = (MemPool *)arg;
220     MemChunk *mprev = 0, *node;
221     MemChunk *new = (void *)(((unsigned char *)ptr) - sizeof(MemChunk));
222
223     if (!memPool->freePool) {
224         new->m_next = 0;
225         memPool->freePool = new;
226     } else {
227         /*
228          * Find where this new chunk fits in the free list.
229          */
230         for (node = memPool->freePool; node && new > node; node = node->m_next)
231             mprev = node;
232         /*
233          * Re-combine with the following free chunk if possible.
234          */
235         if ((((unsigned char *)new) + new->m_size) == (unsigned char *)node) {
236             new->m_size += node->m_size;
237             new->m_next = node->m_next;
238             if (mprev) {
239                 if ((((unsigned char *)mprev) + mprev->m_size) == (unsigned char *)new) {
240                     mprev->m_size += new->m_size;
241                     mprev->m_next = new->m_next;
242                 } else
243                     mprev->m_next = new;
244             } else
245                 memPool->freePool = new;
246         /*
247          * Re-combine with the previous free chunk if possible.
248          */
249         } else if (mprev && (((unsigned char *)mprev) + mprev->m_size) ==
250           (unsigned char *)new) {
251             mprev->m_size += new->m_size;
252             if ((((unsigned char *)mprev) + mprev->m_size) == (unsigned char *)node) {
253                 mprev->m_size += node->m_size;
254                 mprev->m_next = node->m_next;
255             } else
256                 mprev->m_next = node;
257         /*
258          * No luck re-combining, just insert the new chunk into the list.
259          */
260         } else {
261             if (mprev)
262                 mprev->m_next = new;
263             else
264                 memPool->freePool = new;
265             new->m_next = node;
266         }
267     }
268 #endif /* USEMEMPOOL */
269 }
270
271 void *
272 zalloc(arg, items, size)
273     void *arg;
274     unsigned int items, size;
275 {
276 #if !USEMEMPOOL
277     struct ppp_deflate_state *state = arg;
278     struct chunk_header *hdr;
279     unsigned nbytes;
280
281     nbytes = items * size + sizeof(*hdr);
282     if (state->in_alloc)
283         if (nbytes >= MIN_VMALLOC)
284             hdr = vmalloc(nbytes);
285         else
286             hdr = kmalloc(nbytes, GFP_KERNEL);
287     else
288         hdr = kmalloc(nbytes, GFP_ATOMIC);
289     if (hdr == 0)
290         return 0;
291     hdr->size = nbytes;
292     hdr->valloced = state->in_alloc && nbytes >= MIN_VMALLOC;
293     return (void *) (hdr + 1);
294 #else
295     MemPool *memPool = (MemPool *)arg;
296     MemChunk *mprev = 0, *node;
297
298     size *= items;
299     size += sizeof(MemChunk);
300     if (size & 0x3)
301         size = (size + 7) & ~3; 
302     for (node = memPool->freePool; node; node = node->m_next) {
303         if (size == node->m_size) {
304             if (mprev)
305                 mprev->m_next = node->m_next;
306             else
307                 memPool->freePool = node->m_next;
308             return (void *)(((unsigned char *)node)+sizeof(MemChunk));
309         } else if (node->m_size > (size + sizeof(MemChunk) + 7)) {
310             MemChunk *new;
311
312             new = (void *)(((unsigned char *)node) + size);
313             new->m_size = node->m_size - size;
314             new->m_next = node->m_next;
315             if (mprev)
316                 mprev->m_next = new;
317             else
318                 memPool->freePool = new;
319
320             node->m_size = size;
321
322             return (void *)(((unsigned char *)node)+sizeof(MemChunk));
323             break;
324         }
325         mprev = node;
326     }
327     printk(KERN_DEBUG
328            "zalloc(%d)... Out of memory in Pool!\n", size - sizeof(MemChunk)); 
329     return NULL;
330 #endif /* USEMEMPOOL */
331 }
332
333 static void
334 z_comp_free(arg)
335     void *arg;
336 {
337     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
338
339     if (state) {
340             deflateEnd(&state->strm);
341 #if USEMEMPOOL
342             memPoolFree(&state->strm.opaque);
343 #endif
344             kfree(state);
345             MOD_DEC_USE_COUNT;
346     }
347 }
348
349 /*
350  * Allocate space for a compressor.
351  */
352 static void *
353 z_comp_alloc(options, opt_len)
354     unsigned char *options;
355     int opt_len;
356 {
357     struct ppp_deflate_state *state;
358     int w_size;
359
360     if (opt_len != CILEN_DEFLATE || options[0] != CI_DEFLATE
361         || options[1] != CILEN_DEFLATE
362         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
363         || options[3] != DEFLATE_CHK_SEQUENCE)
364         return NULL;
365     w_size = DEFLATE_SIZE(options[2]);
366     if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
367         return NULL;
368
369     state = (struct ppp_deflate_state *) kmalloc(sizeof(*state), GFP_KERNEL);
370     if (state == NULL)
371         return NULL;
372
373     MOD_INC_USE_COUNT;
374     memset (state, 0, sizeof (struct ppp_deflate_state));
375     state->strm.next_in = NULL;
376     state->strm.zalloc  = zalloc;
377     state->strm.zfree   = zfree;
378     state->w_size       = w_size;
379     state->in_alloc = 1;
380
381 #if USEMEMPOOL
382     if (!memPoolAlloc(&state->strm.opaque, 0x50000)) {
383         z_comp_free(state);
384         return NULL;
385     }
386 #else
387     state->strm.opaque = state;
388 #endif
389
390     if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL,
391                      -w_size, 8, Z_DEFAULT_STRATEGY, DEFLATE_OVHD+2) != Z_OK) {
392         z_comp_free(state);
393         return NULL;
394     }
395     state->in_alloc = 0;
396     return (void *) state;
397 }
398
399 static int
400 z_comp_init(arg, options, opt_len, unit, hdrlen, debug)
401     void *arg;
402     unsigned char *options;
403     int opt_len, unit, hdrlen, debug;
404 {
405     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
406
407     if (opt_len < CILEN_DEFLATE || options[0] != CI_DEFLATE
408         || options[1] != CILEN_DEFLATE
409         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
410         || DEFLATE_SIZE(options[2]) != state->w_size
411         || options[3] != DEFLATE_CHK_SEQUENCE)
412         return 0;
413
414     state->seqno = 0;
415     state->unit  = unit;
416     state->debug = debug;
417
418     deflateReset(&state->strm);
419
420     return 1;
421 }
422
423 static void
424 z_comp_reset(arg)
425     void *arg;
426 {
427     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
428
429     state->seqno = 0;
430     deflateReset(&state->strm);
431 }
432
433 int
434 z_compress(arg, rptr, obuf, isize, osize)
435     void *arg;
436     unsigned char *rptr;        /* uncompressed packet (in) */
437     unsigned char *obuf;        /* compressed packet (out) */
438     int isize, osize;
439 {
440     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
441     int r, proto, off, olen;
442     unsigned char *wptr;
443
444     /*
445      * Check that the protocol is in the range we handle.
446      */
447     proto = PPP_PROTOCOL(rptr);
448     if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
449         return 0;
450
451     /* Don't generate compressed packets which are larger than
452        the uncompressed packet. */
453     if (osize > isize)
454         osize = isize;
455
456     wptr = obuf;
457
458     /*
459      * Copy over the PPP header and store the 2-byte sequence number.
460      */
461     wptr[0] = PPP_ADDRESS(rptr);
462     wptr[1] = PPP_CONTROL(rptr);
463     wptr[2] = PPP_COMP >> 8;
464     wptr[3] = PPP_COMP;
465     wptr += PPP_HDRLEN;
466     wptr[0] = state->seqno >> 8;
467     wptr[1] = state->seqno;
468     wptr += 2;
469     state->strm.next_out = wptr;
470     state->strm.avail_out = osize - (PPP_HDRLEN + 2);
471     ++state->seqno;
472
473     off = (proto > 0xff) ? 2 : 3;       /* skip 1st proto byte if 0 */
474     rptr += off;
475     state->strm.next_in = rptr;
476     state->strm.avail_in = (isize - off);
477
478     olen = 0;
479     for (;;) {
480         r = deflate(&state->strm, Z_PACKET_FLUSH);
481         if (r != Z_OK) {
482             if (state->debug)
483                 printk(KERN_DEBUG "z_compress: deflate returned %d (%s)\n",
484                        r, (state->strm.msg? state->strm.msg: ""));
485             break;
486         }
487         if (state->strm.avail_out == 0) {
488             olen += osize;
489             state->strm.next_out = NULL;
490             state->strm.avail_out = 1000000;
491         } else {
492             break;              /* all done */
493         }
494     }
495     if (olen < osize)
496         olen += osize - state->strm.avail_out;
497
498     /*
499      * See if we managed to reduce the size of the packet.
500      * If the compressor just gave us a single zero byte, it means
501      * the packet was incompressible.
502      */
503     if (olen < isize && !(olen == PPP_HDRLEN + 3 && *wptr == 0)) {
504         state->stats.comp_bytes += olen;
505         state->stats.comp_packets++;
506     } else {
507         state->stats.inc_bytes += isize;
508         state->stats.inc_packets++;
509         olen = 0;
510     }
511     state->stats.unc_bytes += isize;
512     state->stats.unc_packets++;
513
514     return olen;
515 }
516
517 static void
518 z_comp_stats(arg, stats)
519     void *arg;
520     struct compstat *stats;
521 {
522     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
523
524     *stats = state->stats;
525 }
526
527 static void
528 z_decomp_free(arg)
529     void *arg;
530 {
531     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
532
533     if (state) {
534             inflateEnd(&state->strm);
535 #if USEMEMPOOL
536             memPoolFree(&state->strm.opaque);
537 #endif
538             kfree(state);
539             MOD_DEC_USE_COUNT;
540     }
541 }
542
543 /*
544  * Allocate space for a decompressor.
545  */
546 static void *
547 z_decomp_alloc(options, opt_len)
548     unsigned char *options;
549     int opt_len;
550 {
551     struct ppp_deflate_state *state;
552     int w_size;
553
554     if (opt_len != CILEN_DEFLATE || options[0] != CI_DEFLATE
555         || options[1] != CILEN_DEFLATE
556         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
557         || options[3] != DEFLATE_CHK_SEQUENCE)
558         return NULL;
559     w_size = DEFLATE_SIZE(options[2]);
560     if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
561         return NULL;
562
563     state = (struct ppp_deflate_state *) kmalloc(sizeof(*state), GFP_KERNEL);
564     if (state == NULL)
565         return NULL;
566
567     MOD_INC_USE_COUNT;
568     memset (state, 0, sizeof (struct ppp_deflate_state));
569     state->w_size        = w_size;
570     state->strm.next_out = NULL;
571     state->strm.zalloc   = zalloc;
572     state->strm.zfree    = zfree;
573     state->in_alloc = 1;
574
575 #if USEMEMPOOL
576     if (!memPoolAlloc(&state->strm.opaque, 0x10000)) {
577         z_decomp_free(state);
578         return NULL;
579     }
580 #else
581     state->strm.opaque = state;
582 #endif
583
584     if (inflateInit2(&state->strm, -w_size) != Z_OK) {
585         z_decomp_free(state);
586         return NULL;
587     }
588     state->in_alloc = 0;
589     return (void *) state;
590 }
591
592 static int
593 z_decomp_init(arg, options, opt_len, unit, hdrlen, mru, debug)
594     void *arg;
595     unsigned char *options;
596     int opt_len, unit, hdrlen, mru, debug;
597 {
598     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
599
600     if (opt_len < CILEN_DEFLATE || options[0] != CI_DEFLATE
601         || options[1] != CILEN_DEFLATE
602         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
603         || DEFLATE_SIZE(options[2]) != state->w_size
604         || options[3] != DEFLATE_CHK_SEQUENCE)
605         return 0;
606
607     state->seqno = 0;
608     state->unit  = unit;
609     state->debug = debug;
610     state->mru   = mru;
611
612     inflateReset(&state->strm);
613
614     return 1;
615 }
616
617 static void
618 z_decomp_reset(arg)
619     void *arg;
620 {
621     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
622
623     state->seqno = 0;
624     inflateReset(&state->strm);
625 }
626
627 /*
628  * Decompress a Deflate-compressed packet.
629  *
630  * Because of patent problems, we return DECOMP_ERROR for errors
631  * found by inspecting the input data and for system problems, but
632  * DECOMP_FATALERROR for any errors which could possibly be said to
633  * be being detected "after" decompression.  For DECOMP_ERROR,
634  * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
635  * infringing a patent of Motorola's if we do, so we take CCP down
636  * instead.
637  *
638  * Given that the frame has the correct sequence number and a good FCS,
639  * errors such as invalid codes in the input most likely indicate a
640  * bug, so we return DECOMP_FATALERROR for them in order to turn off
641  * compression, even though they are detected by inspecting the input.
642  */
643 int
644 z_decompress(arg, ibuf, isize, obuf, osize)
645     void *arg;
646     unsigned char *ibuf;
647     int isize;
648     unsigned char *obuf;
649     int osize;
650 {
651     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
652     int olen, seq, r;
653     int decode_proto, overflow;
654     unsigned char overflow_buf[1];
655
656     if (isize <= PPP_HDRLEN + DEFLATE_OVHD) {
657         if (state->debug)
658             printk(KERN_DEBUG "z_decompress%d: short packet (len=%d)\n",
659                    state->unit, isize);
660         return DECOMP_ERROR;
661     }
662
663     /* Check the sequence number. */
664     seq = (ibuf[PPP_HDRLEN] << 8) + ibuf[PPP_HDRLEN+1];
665     if (seq != state->seqno) {
666         if (state->debug)
667             printk(KERN_DEBUG "z_decompress%d: bad seq # %d, expected %d\n",
668                    state->unit, seq, state->seqno);
669         return DECOMP_ERROR;
670     }
671     ++state->seqno;
672
673     /*
674      * Fill in the first part of the PPP header.  The protocol field
675      * comes from the decompressed data.
676      */
677     obuf[0] = PPP_ADDRESS(ibuf);
678     obuf[1] = PPP_CONTROL(ibuf);
679     obuf[2] = 0;
680
681     /*
682      * Set up to call inflate.  We set avail_out to 1 initially so we can
683      * look at the first byte of the output and decide whether we have
684      * a 1-byte or 2-byte protocol field.
685      */
686     state->strm.next_in = ibuf + PPP_HDRLEN + DEFLATE_OVHD;
687     state->strm.avail_in = isize - (PPP_HDRLEN + DEFLATE_OVHD);
688     state->strm.next_out = obuf + 3;
689     state->strm.avail_out = 1;
690     decode_proto = 1;
691     overflow = 0;
692
693     /*
694      * Call inflate, supplying more input or output as needed.
695      */
696     for (;;) {
697         r = inflate(&state->strm, Z_PACKET_FLUSH);
698         if (r != Z_OK) {
699             if (state->debug)
700                 printk(KERN_DEBUG "z_decompress%d: inflate returned %d (%s)\n",
701                        state->unit, r, (state->strm.msg? state->strm.msg: ""));
702             return DECOMP_FATALERROR;
703         }
704         if (state->strm.avail_out != 0)
705             break;              /* all done */
706         if (decode_proto) {
707             state->strm.avail_out = osize - PPP_HDRLEN;
708             if ((obuf[3] & 1) == 0) {
709                 /* 2-byte protocol field */
710                 obuf[2] = obuf[3];
711                 --state->strm.next_out;
712                 ++state->strm.avail_out;
713             }
714             decode_proto = 0;
715         } else if (!overflow) {
716             /*
717              * We've filled up the output buffer; the only way to
718              * find out whether inflate has any more characters left
719              * is to give it another byte of output space.
720              */
721             state->strm.next_out = overflow_buf;
722             state->strm.avail_out = 1;
723             overflow = 1;
724         } else {
725             if (state->debug)
726                 printk(KERN_DEBUG "z_decompress%d: ran out of mru\n",
727                        state->unit);
728             return DECOMP_FATALERROR;
729         }
730     }
731
732     if (decode_proto)
733         return DECOMP_ERROR;
734
735     olen = osize + overflow - state->strm.avail_out;
736     state->stats.unc_bytes += olen;
737     state->stats.unc_packets++;
738     state->stats.comp_bytes += isize;
739     state->stats.comp_packets++;
740
741     return olen;
742 }
743
744 /*
745  * Incompressible data has arrived - add it to the history.
746  */
747 static void
748 z_incomp(arg, ibuf, icnt)
749     void *arg;
750     unsigned char *ibuf;
751     int icnt;
752 {
753     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
754     int proto, r;
755
756     /*
757      * Check that the protocol is one we handle.
758      */
759     proto = PPP_PROTOCOL(ibuf);
760     if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
761         return;
762
763     ++state->seqno;
764
765     /*
766      * Iterate through the message blocks, adding the characters in them
767      * to the decompressor's history.  For the first block, we start
768      * at the either the 1st or 2nd byte of the protocol field,
769      * depending on whether the protocol value is compressible.
770      */
771     state->strm.next_in = ibuf + 3;
772     state->strm.avail_in = icnt - 3;
773     if (proto > 0xff) {
774         --state->strm.next_in;
775         ++state->strm.avail_in;
776     }
777
778     r = inflateIncomp(&state->strm);
779     if (r != Z_OK) {
780         /* gak! */
781         if (state->debug) {
782             printk(KERN_DEBUG "z_incomp%d: inflateIncomp returned %d (%s)\n",
783                    state->unit, r, (state->strm.msg? state->strm.msg: ""));
784         }
785         return;
786     }
787
788     /*
789      * Update stats.
790      */
791     state->stats.inc_bytes += icnt;
792     state->stats.inc_packets++;
793     state->stats.unc_bytes += icnt;
794     state->stats.unc_packets++;
795 }
796
797 /*************************************************************
798  * Module interface table
799  *************************************************************/
800
801 /* These are in ppp.c */
802 extern int  ppp_register_compressor   (struct compressor *cp);
803 extern void ppp_unregister_compressor (struct compressor *cp);
804
805 /*
806  * Procedures exported to if_ppp.c.
807  */
808 struct compressor ppp_deflate = {
809     CI_DEFLATE,                 /* compress_proto */
810     z_comp_alloc,               /* comp_alloc */
811     z_comp_free,                /* comp_free */
812     z_comp_init,                /* comp_init */
813     z_comp_reset,               /* comp_reset */
814     z_compress,                 /* compress */
815     z_comp_stats,               /* comp_stat */
816     z_decomp_alloc,             /* decomp_alloc */
817     z_decomp_free,              /* decomp_free */
818     z_decomp_init,              /* decomp_init */
819     z_decomp_reset,             /* decomp_reset */
820     z_decompress,               /* decompress */
821     z_incomp,                   /* incomp */
822     z_comp_stats,               /* decomp_stat */
823 };
824
825 #ifdef MODULE
826 /*************************************************************
827  * Module support routines
828  *************************************************************/
829
830 int
831 init_module(void)
832 {  
833         int answer = ppp_register_compressor (&ppp_deflate);
834         if (answer == 0)
835                 printk (KERN_INFO
836                         "PPP Deflate Compression module registered\n");
837         return answer;
838 }
839      
840 void
841 cleanup_module(void)
842 {
843         if (MOD_IN_USE)
844                 printk (KERN_INFO
845                         "Deflate Compression module busy, remove delayed\n");
846         else
847                 ppp_unregister_compressor (&ppp_deflate);
848 }
849 #endif