2 * ==FILEVERSION 980319==
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.
8 * Copyright (c) 1994 The Australian National University.
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
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
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,
31 * From: deflate.c,v 1.1 1996/01/18 03:17:48 paulus Exp
34 #include <linux/module.h>
35 #include <linux/kernel.h>
36 #include <linux/sched.h>
37 #include <linux/types.h>
38 #include <linux/fcntl.h>
39 #include <linux/interrupt.h>
40 #include <linux/ptrace.h>
41 #include <linux/ioport.h>
43 #include <linux/malloc.h>
44 #include <linux/vmalloc.h>
45 #include <linux/errno.h>
46 #include <linux/string.h> /* used in new tty drivers */
47 #include <linux/signal.h> /* used in new tty drivers */
49 #include <asm/system.h>
51 #include <linux/netdevice.h>
52 #include <linux/skbuff.h>
53 #include <linux/inet.h>
54 #include <linux/ioctl.h>
56 #include <linux/ppp_defs.h>
57 #include <linux/ppp-comp.h>
62 * State for a Deflate (de)compressor.
64 struct ppp_deflate_state
{
71 struct compstat stats
;
74 #define DEFLATE_OVHD 2 /* Deflate overhead/packet */
76 static void *zalloc
__P((void *, unsigned int items
, unsigned int size
));
77 static void *zalloc_init
__P((void *, unsigned int items
,
79 static void zfree
__P((void *, void *ptr
));
80 static void *z_comp_alloc
__P((unsigned char *options
, int opt_len
));
81 static void *z_decomp_alloc
__P((unsigned char *options
, int opt_len
));
82 static void z_comp_free
__P((void *state
));
83 static void z_decomp_free
__P((void *state
));
84 static int z_comp_init
__P((void *state
, unsigned char *options
,
86 int unit
, int hdrlen
, int debug
));
87 static int z_decomp_init
__P((void *state
, unsigned char *options
,
89 int unit
, int hdrlen
, int mru
, int debug
));
90 static int z_compress
__P((void *state
, unsigned char *rptr
,
92 int isize
, int osize
));
93 static void z_incomp
__P((void *state
, unsigned char *ibuf
, int icnt
));
94 static int z_decompress
__P((void *state
, unsigned char *ibuf
,
95 int isize
, unsigned char *obuf
, int osize
));
96 static void z_comp_reset
__P((void *state
));
97 static void z_decomp_reset
__P((void *state
));
98 static void z_comp_stats
__P((void *state
, struct compstat
*stats
));
100 struct chunk_header
{
101 int valloced
; /* allocated with valloc, not kmalloc */
102 int guard
; /* check for overwritten header */
105 #define GUARD_MAGIC 0x77a8011a
106 #define MIN_VMALLOC 2048 /* use kmalloc for blocks < this */
109 * Space allocation and freeing routines for use by zlib routines.
116 struct chunk_header
*hdr
= ((struct chunk_header
*)ptr
) - 1;
118 if (hdr
->guard
!= GUARD_MAGIC
) {
119 printk(KERN_WARNING
"zfree: header corrupted (%x %x) at %p\n",
120 hdr
->valloced
, hdr
->guard
, hdr
);
130 zalloc(arg
, items
, size
)
132 unsigned int items
, size
;
134 struct chunk_header
*hdr
;
137 nbytes
= items
* size
+ sizeof(*hdr
);
138 hdr
= kmalloc(nbytes
, GFP_ATOMIC
);
142 hdr
->guard
= GUARD_MAGIC
;
143 return (void *) (hdr
+ 1);
147 zalloc_init(arg
, items
, size
)
149 unsigned int items
, size
;
151 struct chunk_header
*hdr
;
154 nbytes
= items
* size
+ sizeof(*hdr
);
155 if (nbytes
>= MIN_VMALLOC
)
156 hdr
= vmalloc(nbytes
);
158 hdr
= kmalloc(nbytes
, GFP_KERNEL
);
161 hdr
->valloced
= nbytes
>= MIN_VMALLOC
;
162 hdr
->guard
= GUARD_MAGIC
;
163 return (void *) (hdr
+ 1);
170 struct ppp_deflate_state
*state
= (struct ppp_deflate_state
*) arg
;
173 deflateEnd(&state
->strm
);
180 * Allocate space for a compressor.
183 z_comp_alloc(options
, opt_len
)
184 unsigned char *options
;
187 struct ppp_deflate_state
*state
;
190 if (opt_len
!= CILEN_DEFLATE
191 || (options
[0] != CI_DEFLATE
&& options
[0] != CI_DEFLATE_DRAFT
)
192 || options
[1] != CILEN_DEFLATE
193 || DEFLATE_METHOD(options
[2]) != DEFLATE_METHOD_VAL
194 || options
[3] != DEFLATE_CHK_SEQUENCE
)
196 w_size
= DEFLATE_SIZE(options
[2]);
197 if (w_size
< DEFLATE_MIN_SIZE
|| w_size
> DEFLATE_MAX_SIZE
)
200 state
= (struct ppp_deflate_state
*) kmalloc(sizeof(*state
), GFP_KERNEL
);
205 memset (state
, 0, sizeof (struct ppp_deflate_state
));
206 state
->strm
.next_in
= NULL
;
207 state
->strm
.zalloc
= zalloc_init
;
208 state
->strm
.zfree
= zfree
;
209 state
->w_size
= w_size
;
211 if (deflateInit2(&state
->strm
, Z_DEFAULT_COMPRESSION
,
212 DEFLATE_METHOD_VAL
, -w_size
, 8, Z_DEFAULT_STRATEGY
)
215 state
->strm
.zalloc
= zalloc
;
216 return (void *) state
;
225 z_comp_init(arg
, options
, opt_len
, unit
, hdrlen
, debug
)
227 unsigned char *options
;
228 int opt_len
, unit
, hdrlen
, debug
;
230 struct ppp_deflate_state
*state
= (struct ppp_deflate_state
*) arg
;
232 if (opt_len
< CILEN_DEFLATE
233 || (options
[0] != CI_DEFLATE
&& options
[0] != CI_DEFLATE_DRAFT
)
234 || options
[1] != CILEN_DEFLATE
235 || DEFLATE_METHOD(options
[2]) != DEFLATE_METHOD_VAL
236 || DEFLATE_SIZE(options
[2]) != state
->w_size
237 || options
[3] != DEFLATE_CHK_SEQUENCE
)
242 state
->debug
= debug
;
244 deflateReset(&state
->strm
);
253 struct ppp_deflate_state
*state
= (struct ppp_deflate_state
*) arg
;
256 deflateReset(&state
->strm
);
260 z_compress(arg
, rptr
, obuf
, isize
, osize
)
262 unsigned char *rptr
; /* uncompressed packet (in) */
263 unsigned char *obuf
; /* compressed packet (out) */
266 struct ppp_deflate_state
*state
= (struct ppp_deflate_state
*) arg
;
267 int r
, proto
, off
, olen
, oavail
;
271 * Check that the protocol is in the range we handle.
273 proto
= PPP_PROTOCOL(rptr
);
274 if (proto
> 0x3fff || proto
== 0xfd || proto
== 0xfb)
277 /* Don't generate compressed packets which are larger than
278 the uncompressed packet. */
285 * Copy over the PPP header and store the 2-byte sequence number.
287 wptr
[0] = PPP_ADDRESS(rptr
);
288 wptr
[1] = PPP_CONTROL(rptr
);
289 wptr
[2] = PPP_COMP
>> 8;
292 wptr
[0] = state
->seqno
>> 8;
293 wptr
[1] = state
->seqno
;
294 wptr
+= DEFLATE_OVHD
;
295 olen
= PPP_HDRLEN
+ DEFLATE_OVHD
;
296 state
->strm
.next_out
= wptr
;
297 state
->strm
.avail_out
= oavail
= osize
- olen
;
300 off
= (proto
> 0xff) ? 2 : 3; /* skip 1st proto byte if 0 */
302 state
->strm
.next_in
= rptr
;
303 state
->strm
.avail_in
= (isize
- off
);
306 r
= deflate(&state
->strm
, Z_PACKET_FLUSH
);
310 "z_compress: deflate returned %d\n", r
);
313 if (state
->strm
.avail_out
== 0) {
315 state
->strm
.next_out
= NULL
;
316 state
->strm
.avail_out
= oavail
= 1000000;
318 break; /* all done */
321 olen
+= oavail
- state
->strm
.avail_out
;
324 * See if we managed to reduce the size of the packet.
327 state
->stats
.comp_bytes
+= olen
;
328 state
->stats
.comp_packets
++;
330 state
->stats
.inc_bytes
+= isize
;
331 state
->stats
.inc_packets
++;
334 state
->stats
.unc_bytes
+= isize
;
335 state
->stats
.unc_packets
++;
341 z_comp_stats(arg
, stats
)
343 struct compstat
*stats
;
345 struct ppp_deflate_state
*state
= (struct ppp_deflate_state
*) arg
;
347 *stats
= state
->stats
;
354 struct ppp_deflate_state
*state
= (struct ppp_deflate_state
*) arg
;
357 inflateEnd(&state
->strm
);
364 * Allocate space for a decompressor.
367 z_decomp_alloc(options
, opt_len
)
368 unsigned char *options
;
371 struct ppp_deflate_state
*state
;
374 if (opt_len
!= CILEN_DEFLATE
375 || (options
[0] != CI_DEFLATE
&& options
[0] != CI_DEFLATE_DRAFT
)
376 || options
[1] != CILEN_DEFLATE
377 || DEFLATE_METHOD(options
[2]) != DEFLATE_METHOD_VAL
378 || options
[3] != DEFLATE_CHK_SEQUENCE
)
380 w_size
= DEFLATE_SIZE(options
[2]);
381 if (w_size
< DEFLATE_MIN_SIZE
|| w_size
> DEFLATE_MAX_SIZE
)
384 state
= (struct ppp_deflate_state
*) kmalloc(sizeof(*state
), GFP_KERNEL
);
389 memset (state
, 0, sizeof (struct ppp_deflate_state
));
390 state
->w_size
= w_size
;
391 state
->strm
.next_out
= NULL
;
392 state
->strm
.zalloc
= zalloc_init
;
393 state
->strm
.zfree
= zfree
;
395 if (inflateInit2(&state
->strm
, -w_size
) != Z_OK
)
397 state
->strm
.zalloc
= zalloc
;
398 return (void *) state
;
401 z_decomp_free(state
);
407 z_decomp_init(arg
, options
, opt_len
, unit
, hdrlen
, mru
, debug
)
409 unsigned char *options
;
410 int opt_len
, unit
, hdrlen
, mru
, debug
;
412 struct ppp_deflate_state
*state
= (struct ppp_deflate_state
*) arg
;
414 if (opt_len
< CILEN_DEFLATE
415 || (options
[0] != CI_DEFLATE
&& options
[0] != CI_DEFLATE_DRAFT
)
416 || options
[1] != CILEN_DEFLATE
417 || DEFLATE_METHOD(options
[2]) != DEFLATE_METHOD_VAL
418 || DEFLATE_SIZE(options
[2]) != state
->w_size
419 || options
[3] != DEFLATE_CHK_SEQUENCE
)
424 state
->debug
= debug
;
427 inflateReset(&state
->strm
);
436 struct ppp_deflate_state
*state
= (struct ppp_deflate_state
*) arg
;
439 inflateReset(&state
->strm
);
443 * Decompress a Deflate-compressed packet.
445 * Because of patent problems, we return DECOMP_ERROR for errors
446 * found by inspecting the input data and for system problems, but
447 * DECOMP_FATALERROR for any errors which could possibly be said to
448 * be being detected "after" decompression. For DECOMP_ERROR,
449 * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
450 * infringing a patent of Motorola's if we do, so we take CCP down
453 * Given that the frame has the correct sequence number and a good FCS,
454 * errors such as invalid codes in the input most likely indicate a
455 * bug, so we return DECOMP_FATALERROR for them in order to turn off
456 * compression, even though they are detected by inspecting the input.
459 z_decompress(arg
, ibuf
, isize
, obuf
, osize
)
466 struct ppp_deflate_state
*state
= (struct ppp_deflate_state
*) arg
;
468 int decode_proto
, overflow
;
469 unsigned char overflow_buf
[1];
471 if (isize
<= PPP_HDRLEN
+ DEFLATE_OVHD
) {
473 printk(KERN_DEBUG
"z_decompress%d: short pkt (%d)\n",
478 /* Check the sequence number. */
479 seq
= (ibuf
[PPP_HDRLEN
] << 8) + ibuf
[PPP_HDRLEN
+1];
480 if (seq
!= state
->seqno
) {
482 printk(KERN_DEBUG
"z_decompress%d: bad seq # %d, expected %d\n",
483 state
->unit
, seq
, state
->seqno
);
489 * Fill in the first part of the PPP header. The protocol field
490 * comes from the decompressed data.
492 obuf
[0] = PPP_ADDRESS(ibuf
);
493 obuf
[1] = PPP_CONTROL(ibuf
);
497 * Set up to call inflate. We set avail_out to 1 initially so we can
498 * look at the first byte of the output and decide whether we have
499 * a 1-byte or 2-byte protocol field.
501 state
->strm
.next_in
= ibuf
+ PPP_HDRLEN
+ DEFLATE_OVHD
;
502 state
->strm
.avail_in
= isize
- (PPP_HDRLEN
+ DEFLATE_OVHD
);
503 state
->strm
.next_out
= obuf
+ 3;
504 state
->strm
.avail_out
= 1;
509 * Call inflate, supplying more input or output as needed.
512 r
= inflate(&state
->strm
, Z_PACKET_FLUSH
);
515 printk(KERN_DEBUG
"z_decompress%d: inflate returned %d (%s)\n",
516 state
->unit
, r
, (state
->strm
.msg
? state
->strm
.msg
: ""));
517 return DECOMP_FATALERROR
;
519 if (state
->strm
.avail_out
!= 0)
520 break; /* all done */
522 state
->strm
.avail_out
= osize
- PPP_HDRLEN
;
523 if ((obuf
[3] & 1) == 0) {
524 /* 2-byte protocol field */
526 --state
->strm
.next_out
;
527 ++state
->strm
.avail_out
;
530 } else if (!overflow
) {
532 * We've filled up the output buffer; the only way to
533 * find out whether inflate has any more characters
534 * left is to give it another byte of output space.
536 state
->strm
.next_out
= overflow_buf
;
537 state
->strm
.avail_out
= 1;
541 printk(KERN_DEBUG
"z_decompress%d: ran out of mru\n",
543 return DECOMP_FATALERROR
;
549 printk(KERN_DEBUG
"z_decompress%d: didn't get proto\n",
554 olen
= osize
+ overflow
- state
->strm
.avail_out
;
555 state
->stats
.unc_bytes
+= olen
;
556 state
->stats
.unc_packets
++;
557 state
->stats
.comp_bytes
+= isize
;
558 state
->stats
.comp_packets
++;
564 * Incompressible data has arrived - add it to the history.
567 z_incomp(arg
, ibuf
, icnt
)
572 struct ppp_deflate_state
*state
= (struct ppp_deflate_state
*) arg
;
576 * Check that the protocol is one we handle.
578 proto
= PPP_PROTOCOL(ibuf
);
579 if (proto
> 0x3fff || proto
== 0xfd || proto
== 0xfb)
585 * We start at the either the 1st or 2nd byte of the protocol field,
586 * depending on whether the protocol value is compressible.
588 state
->strm
.next_in
= ibuf
+ 3;
589 state
->strm
.avail_in
= icnt
- 3;
591 --state
->strm
.next_in
;
592 ++state
->strm
.avail_in
;
595 r
= inflateIncomp(&state
->strm
);
599 printk(KERN_DEBUG
"z_incomp%d: inflateIncomp returned %d (%s)\n",
600 state
->unit
, r
, (state
->strm
.msg
? state
->strm
.msg
: ""));
608 state
->stats
.inc_bytes
+= icnt
;
609 state
->stats
.inc_packets
++;
610 state
->stats
.unc_bytes
+= icnt
;
611 state
->stats
.unc_packets
++;
614 /*************************************************************
615 * Module interface table
616 *************************************************************/
618 /* These are in ppp.c */
619 extern int ppp_register_compressor (struct compressor
*cp
);
620 extern void ppp_unregister_compressor (struct compressor
*cp
);
623 * Procedures exported to if_ppp.c.
625 struct compressor ppp_deflate
= {
626 CI_DEFLATE
, /* compress_proto */
627 z_comp_alloc
, /* comp_alloc */
628 z_comp_free
, /* comp_free */
629 z_comp_init
, /* comp_init */
630 z_comp_reset
, /* comp_reset */
631 z_compress
, /* compress */
632 z_comp_stats
, /* comp_stat */
633 z_decomp_alloc
, /* decomp_alloc */
634 z_decomp_free
, /* decomp_free */
635 z_decomp_init
, /* decomp_init */
636 z_decomp_reset
, /* decomp_reset */
637 z_decompress
, /* decompress */
638 z_incomp
, /* incomp */
639 z_comp_stats
, /* decomp_stat */
642 struct compressor ppp_deflate_draft
= {
643 CI_DEFLATE_DRAFT
, /* compress_proto */
644 z_comp_alloc
, /* comp_alloc */
645 z_comp_free
, /* comp_free */
646 z_comp_init
, /* comp_init */
647 z_comp_reset
, /* comp_reset */
648 z_compress
, /* compress */
649 z_comp_stats
, /* comp_stat */
650 z_decomp_alloc
, /* decomp_alloc */
651 z_decomp_free
, /* decomp_free */
652 z_decomp_init
, /* decomp_init */
653 z_decomp_reset
, /* decomp_reset */
654 z_decompress
, /* decompress */
655 z_incomp
, /* incomp */
656 z_comp_stats
, /* decomp_stat */
660 /*************************************************************
661 * Module support routines
662 *************************************************************/
667 int answer
= ppp_register_compressor (&ppp_deflate
);
670 "PPP Deflate Compression module registered\n");
671 ppp_register_compressor(&ppp_deflate_draft
);
680 "Deflate Compression module busy, remove delayed\n");
682 ppp_unregister_compressor (&ppp_deflate
);
683 ppp_unregister_compressor (&ppp_deflate_draft
);