]> git.ozlabs.org Git - ppp.git/blob - linux/ppp_deflate.c
minor fixes
[ppp.git] / linux / ppp_deflate.c
1 /*
2  *  ==FILEVERSION 970428==
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
36 #include <linux/kernel.h>
37 #include <linux/sched.h>
38 #include <linux/types.h>
39 #include <linux/fcntl.h>
40 #include <linux/interrupt.h>
41 #include <linux/ptrace.h>
42 #include <linux/ioport.h>
43 #include <linux/in.h>
44 #include <linux/malloc.h>
45 #include <linux/vmalloc.h>
46 #include <linux/errno.h>
47 #include <linux/sched.h>        /* to get the struct task_struct */
48 #include <linux/string.h>       /* used in new tty drivers */
49 #include <linux/signal.h>       /* used in new tty drivers */
50
51 #include <asm/system.h>
52
53 #include <linux/netdevice.h>
54 #include <linux/skbuff.h>
55 #include <linux/inet.h>
56 #include <linux/ioctl.h>
57
58 #include <linux/ppp_defs.h>
59 #include <linux/ppp-comp.h>
60
61 #include "zlib.c"
62
63 /*
64  * State for a Deflate (de)compressor.
65  */
66 struct ppp_deflate_state {
67     int         seqno;
68     int         w_size;
69     int         unit;
70     int         mru;
71     int         debug;
72     z_stream    strm;
73     struct compstat stats;
74 };
75
76 #define DEFLATE_OVHD    2               /* Deflate overhead/packet */
77
78 static void     *zalloc __P((void *, unsigned int items, unsigned int size));
79 static void     *zalloc_init __P((void *, unsigned int items,
80                                   unsigned int size));
81 static void     zfree __P((void *, void *ptr, unsigned int nb));
82 static void     *z_comp_alloc __P((unsigned char *options, int opt_len));
83 static void     *z_decomp_alloc __P((unsigned char *options, int opt_len));
84 static void     z_comp_free __P((void *state));
85 static void     z_decomp_free __P((void *state));
86 static int      z_comp_init __P((void *state, unsigned char *options,
87                                  int opt_len,
88                                  int unit, int hdrlen, int debug));
89 static int      z_decomp_init __P((void *state, unsigned char *options,
90                                    int opt_len,
91                                    int unit, int hdrlen, int mru, int debug));
92 static int      z_compress __P((void *state, unsigned char *rptr,
93                                 unsigned char *obuf,
94                                 int isize, int osize));
95 static void     z_incomp __P((void *state, unsigned char *ibuf, int icnt));
96 static int      z_decompress __P((void *state, unsigned char *ibuf,
97                                 int isize, unsigned char *obuf, int osize));
98 static void     z_comp_reset __P((void *state));
99 static void     z_decomp_reset __P((void *state));
100 static void     z_comp_stats __P((void *state, struct compstat *stats));
101
102 struct chunk_header {
103     unsigned size;              /* amount of space following header */
104     int valloced;               /* allocated with valloc, not kmalloc */
105 };
106
107 #define MIN_VMALLOC     2048    /* use kmalloc for blocks < this */
108
109 /*
110  * Space allocation and freeing routines for use by zlib routines.
111  */
112 void
113 zfree(arg, ptr, nbytes)
114     void *arg;
115     void *ptr;
116     unsigned int nbytes;
117 {
118     struct chunk_header *hdr = ((struct chunk_header *)ptr) - 1;
119
120     if (hdr->valloced)
121         vfree(hdr);
122     else
123         kfree(hdr);
124 }
125
126 void *
127 zalloc(arg, items, size)
128     void *arg;
129     unsigned int items, size;
130 {
131     struct chunk_header *hdr;
132     unsigned nbytes;
133
134     nbytes = items * size + sizeof(*hdr);
135     hdr = kmalloc(nbytes, GFP_ATOMIC);
136     if (hdr == 0)
137         return 0;
138     hdr->size = nbytes;
139     hdr->valloced = 0;
140     return (void *) (hdr + 1);
141 }
142
143 void *
144 zalloc_init(arg, items, size)
145     void *arg;
146     unsigned int items, size;
147 {
148     struct chunk_header *hdr;
149     unsigned nbytes;
150
151     nbytes = items * size + sizeof(*hdr);
152     if (nbytes >= MIN_VMALLOC)
153         hdr = vmalloc(nbytes);
154     else
155         hdr = kmalloc(nbytes, GFP_KERNEL);
156     if (hdr == 0)
157         return 0;
158     hdr->size = nbytes;
159     hdr->valloced = nbytes >= MIN_VMALLOC;
160     return (void *) (hdr + 1);
161 }
162
163 static void
164 z_comp_free(arg)
165     void *arg;
166 {
167     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
168
169     if (state) {
170             deflateEnd(&state->strm);
171             kfree(state);
172             MOD_DEC_USE_COUNT;
173     }
174 }
175
176 /*
177  * Allocate space for a compressor.
178  */
179 static void *
180 z_comp_alloc(options, opt_len)
181     unsigned char *options;
182     int opt_len;
183 {
184     struct ppp_deflate_state *state;
185     int w_size;
186
187     if (opt_len != CILEN_DEFLATE || options[0] != CI_DEFLATE
188         || options[1] != CILEN_DEFLATE
189         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
190         || options[3] != DEFLATE_CHK_SEQUENCE)
191         return NULL;
192     w_size = DEFLATE_SIZE(options[2]);
193     if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
194         return NULL;
195
196     state = (struct ppp_deflate_state *) kmalloc(sizeof(*state), GFP_KERNEL);
197     if (state == NULL)
198         return NULL;
199
200     MOD_INC_USE_COUNT;
201     memset (state, 0, sizeof (struct ppp_deflate_state));
202     state->strm.next_in = NULL;
203     state->strm.zalloc  = zalloc;
204     state->strm.zalloc_init = zalloc;
205     state->strm.zfree   = zfree;
206     state->w_size       = w_size;
207
208     if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL,
209                      -w_size, 8, Z_DEFAULT_STRATEGY, DEFLATE_OVHD+2) != Z_OK) {
210         z_comp_free(state);
211         return NULL;
212     }
213     return (void *) state;
214 }
215
216 static int
217 z_comp_init(arg, options, opt_len, unit, hdrlen, debug)
218     void *arg;
219     unsigned char *options;
220     int opt_len, unit, hdrlen, debug;
221 {
222     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
223
224     if (opt_len < CILEN_DEFLATE || options[0] != CI_DEFLATE
225         || options[1] != CILEN_DEFLATE
226         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
227         || DEFLATE_SIZE(options[2]) != state->w_size
228         || options[3] != DEFLATE_CHK_SEQUENCE)
229         return 0;
230
231     state->seqno = 0;
232     state->unit  = unit;
233     state->debug = debug;
234
235     deflateReset(&state->strm);
236
237     return 1;
238 }
239
240 static void
241 z_comp_reset(arg)
242     void *arg;
243 {
244     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
245
246     state->seqno = 0;
247     deflateReset(&state->strm);
248 }
249
250 int
251 z_compress(arg, rptr, obuf, isize, osize)
252     void *arg;
253     unsigned char *rptr;        /* uncompressed packet (in) */
254     unsigned char *obuf;        /* compressed packet (out) */
255     int isize, osize;
256 {
257     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
258     int r, proto, off, olen;
259     unsigned char *wptr;
260
261     /*
262      * Check that the protocol is in the range we handle.
263      */
264     proto = PPP_PROTOCOL(rptr);
265     if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
266         return 0;
267
268     /* Don't generate compressed packets which are larger than
269        the uncompressed packet. */
270     if (osize > isize)
271         osize = isize;
272
273     wptr = obuf;
274
275     /*
276      * Copy over the PPP header and store the 2-byte sequence number.
277      */
278     wptr[0] = PPP_ADDRESS(rptr);
279     wptr[1] = PPP_CONTROL(rptr);
280     wptr[2] = PPP_COMP >> 8;
281     wptr[3] = PPP_COMP;
282     wptr += PPP_HDRLEN;
283     wptr[0] = state->seqno >> 8;
284     wptr[1] = state->seqno;
285     wptr += 2;
286     state->strm.next_out = wptr;
287     state->strm.avail_out = osize - (PPP_HDRLEN + 2);
288     ++state->seqno;
289
290     off = (proto > 0xff) ? 2 : 3;       /* skip 1st proto byte if 0 */
291     rptr += off;
292     state->strm.next_in = rptr;
293     state->strm.avail_in = (isize - off);
294
295     olen = 0;
296     for (;;) {
297         r = deflate(&state->strm, Z_PACKET_FLUSH);
298         if (r != Z_OK) {
299             if (state->debug)
300                 printk(KERN_DEBUG "z_compress: deflate returned %d (%s)\n",
301                        r, (state->strm.msg? state->strm.msg: ""));
302             break;
303         }
304         if (state->strm.avail_out == 0) {
305             olen += osize;
306             state->strm.next_out = NULL;
307             state->strm.avail_out = 1000000;
308         } else {
309             break;              /* all done */
310         }
311     }
312     if (olen < osize)
313         olen += osize - state->strm.avail_out;
314
315     /*
316      * See if we managed to reduce the size of the packet.
317      * If the compressor just gave us a single zero byte, it means
318      * the packet was incompressible.
319      */
320     if (olen < isize && !(olen == PPP_HDRLEN + 3 && *wptr == 0)) {
321         state->stats.comp_bytes += olen;
322         state->stats.comp_packets++;
323     } else {
324         state->stats.inc_bytes += isize;
325         state->stats.inc_packets++;
326         olen = 0;
327     }
328     state->stats.unc_bytes += isize;
329     state->stats.unc_packets++;
330
331     return olen;
332 }
333
334 static void
335 z_comp_stats(arg, stats)
336     void *arg;
337     struct compstat *stats;
338 {
339     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
340
341     *stats = state->stats;
342 }
343
344 static void
345 z_decomp_free(arg)
346     void *arg;
347 {
348     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
349
350     if (state) {
351             inflateEnd(&state->strm);
352 #if USEMEMPOOL
353             memPoolFree(&state->strm.opaque);
354 #endif
355             kfree(state);
356             MOD_DEC_USE_COUNT;
357     }
358 }
359
360 /*
361  * Allocate space for a decompressor.
362  */
363 static void *
364 z_decomp_alloc(options, opt_len)
365     unsigned char *options;
366     int opt_len;
367 {
368     struct ppp_deflate_state *state;
369     int w_size;
370
371     if (opt_len != CILEN_DEFLATE || options[0] != CI_DEFLATE
372         || options[1] != CILEN_DEFLATE
373         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
374         || options[3] != DEFLATE_CHK_SEQUENCE)
375         return NULL;
376     w_size = DEFLATE_SIZE(options[2]);
377     if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
378         return NULL;
379
380     state = (struct ppp_deflate_state *) kmalloc(sizeof(*state), GFP_KERNEL);
381     if (state == NULL)
382         return NULL;
383
384     MOD_INC_USE_COUNT;
385     memset (state, 0, sizeof (struct ppp_deflate_state));
386     state->w_size        = w_size;
387     state->strm.next_out = NULL;
388     state->strm.zalloc   = zalloc;
389     state->strm.zfree    = zfree;
390
391     if (inflateInit2(&state->strm, -w_size) != Z_OK) {
392         z_decomp_free(state);
393         return NULL;
394     }
395     return (void *) state;
396 }
397
398 static int
399 z_decomp_init(arg, options, opt_len, unit, hdrlen, mru, debug)
400     void *arg;
401     unsigned char *options;
402     int opt_len, unit, hdrlen, mru, debug;
403 {
404     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
405
406     if (opt_len < CILEN_DEFLATE || options[0] != CI_DEFLATE
407         || options[1] != CILEN_DEFLATE
408         || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
409         || DEFLATE_SIZE(options[2]) != state->w_size
410         || options[3] != DEFLATE_CHK_SEQUENCE)
411         return 0;
412
413     state->seqno = 0;
414     state->unit  = unit;
415     state->debug = debug;
416     state->mru   = mru;
417
418     inflateReset(&state->strm);
419
420     return 1;
421 }
422
423 static void
424 z_decomp_reset(arg)
425     void *arg;
426 {
427     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
428
429     state->seqno = 0;
430     inflateReset(&state->strm);
431 }
432
433 /*
434  * Decompress a Deflate-compressed packet.
435  *
436  * Because of patent problems, we return DECOMP_ERROR for errors
437  * found by inspecting the input data and for system problems, but
438  * DECOMP_FATALERROR for any errors which could possibly be said to
439  * be being detected "after" decompression.  For DECOMP_ERROR,
440  * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
441  * infringing a patent of Motorola's if we do, so we take CCP down
442  * instead.
443  *
444  * Given that the frame has the correct sequence number and a good FCS,
445  * errors such as invalid codes in the input most likely indicate a
446  * bug, so we return DECOMP_FATALERROR for them in order to turn off
447  * compression, even though they are detected by inspecting the input.
448  */
449 int
450 z_decompress(arg, ibuf, isize, obuf, osize)
451     void *arg;
452     unsigned char *ibuf;
453     int isize;
454     unsigned char *obuf;
455     int osize;
456 {
457     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
458     int olen, seq, r;
459     int decode_proto, overflow;
460     unsigned char overflow_buf[1];
461
462     if (isize <= PPP_HDRLEN + DEFLATE_OVHD) {
463         if (state->debug)
464             printk(KERN_DEBUG "z_decompress%d: short packet (len=%d)\n",
465                    state->unit, isize);
466         return DECOMP_ERROR;
467     }
468
469     /* Check the sequence number. */
470     seq = (ibuf[PPP_HDRLEN] << 8) + ibuf[PPP_HDRLEN+1];
471     if (seq != state->seqno) {
472         if (state->debug)
473             printk(KERN_DEBUG "z_decompress%d: bad seq # %d, expected %d\n",
474                    state->unit, seq, state->seqno);
475         return DECOMP_ERROR;
476     }
477     ++state->seqno;
478
479     /*
480      * Fill in the first part of the PPP header.  The protocol field
481      * comes from the decompressed data.
482      */
483     obuf[0] = PPP_ADDRESS(ibuf);
484     obuf[1] = PPP_CONTROL(ibuf);
485     obuf[2] = 0;
486
487     /*
488      * Set up to call inflate.  We set avail_out to 1 initially so we can
489      * look at the first byte of the output and decide whether we have
490      * a 1-byte or 2-byte protocol field.
491      */
492     state->strm.next_in = ibuf + PPP_HDRLEN + DEFLATE_OVHD;
493     state->strm.avail_in = isize - (PPP_HDRLEN + DEFLATE_OVHD);
494     state->strm.next_out = obuf + 3;
495     state->strm.avail_out = 1;
496     decode_proto = 1;
497     overflow = 0;
498
499     /*
500      * Call inflate, supplying more input or output as needed.
501      */
502     for (;;) {
503         r = inflate(&state->strm, Z_PACKET_FLUSH);
504         if (r != Z_OK) {
505             if (state->debug)
506                 printk(KERN_DEBUG "z_decompress%d: inflate returned %d (%s)\n",
507                        state->unit, r, (state->strm.msg? state->strm.msg: ""));
508             return DECOMP_FATALERROR;
509         }
510         if (state->strm.avail_out != 0)
511             break;              /* all done */
512         if (decode_proto) {
513             state->strm.avail_out = osize - PPP_HDRLEN;
514             if ((obuf[3] & 1) == 0) {
515                 /* 2-byte protocol field */
516                 obuf[2] = obuf[3];
517                 --state->strm.next_out;
518                 ++state->strm.avail_out;
519             }
520             decode_proto = 0;
521         } else if (!overflow) {
522             /*
523              * We've filled up the output buffer; the only way to
524              * find out whether inflate has any more characters left
525              * is to give it another byte of output space.
526              */
527             state->strm.next_out = overflow_buf;
528             state->strm.avail_out = 1;
529             overflow = 1;
530         } else {
531             if (state->debug)
532                 printk(KERN_DEBUG "z_decompress%d: ran out of mru\n",
533                        state->unit);
534             return DECOMP_FATALERROR;
535         }
536     }
537
538     if (decode_proto)
539         return DECOMP_ERROR;
540
541     olen = osize + overflow - state->strm.avail_out;
542     state->stats.unc_bytes += olen;
543     state->stats.unc_packets++;
544     state->stats.comp_bytes += isize;
545     state->stats.comp_packets++;
546
547     return olen;
548 }
549
550 /*
551  * Incompressible data has arrived - add it to the history.
552  */
553 static void
554 z_incomp(arg, ibuf, icnt)
555     void *arg;
556     unsigned char *ibuf;
557     int icnt;
558 {
559     struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
560     int proto, r;
561
562     /*
563      * Check that the protocol is one we handle.
564      */
565     proto = PPP_PROTOCOL(ibuf);
566     if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
567         return;
568
569     ++state->seqno;
570
571     /*
572      * Iterate through the message blocks, adding the characters in them
573      * to the decompressor's history.  For the first block, we start
574      * at the either the 1st or 2nd byte of the protocol field,
575      * depending on whether the protocol value is compressible.
576      */
577     state->strm.next_in = ibuf + 3;
578     state->strm.avail_in = icnt - 3;
579     if (proto > 0xff) {
580         --state->strm.next_in;
581         ++state->strm.avail_in;
582     }
583
584     r = inflateIncomp(&state->strm);
585     if (r != Z_OK) {
586         /* gak! */
587         if (state->debug) {
588             printk(KERN_DEBUG "z_incomp%d: inflateIncomp returned %d (%s)\n",
589                    state->unit, r, (state->strm.msg? state->strm.msg: ""));
590         }
591         return;
592     }
593
594     /*
595      * Update stats.
596      */
597     state->stats.inc_bytes += icnt;
598     state->stats.inc_packets++;
599     state->stats.unc_bytes += icnt;
600     state->stats.unc_packets++;
601 }
602
603 /*************************************************************
604  * Module interface table
605  *************************************************************/
606
607 /* These are in ppp.c */
608 extern int  ppp_register_compressor   (struct compressor *cp);
609 extern void ppp_unregister_compressor (struct compressor *cp);
610
611 /*
612  * Procedures exported to if_ppp.c.
613  */
614 struct compressor ppp_deflate = {
615     CI_DEFLATE,                 /* compress_proto */
616     z_comp_alloc,               /* comp_alloc */
617     z_comp_free,                /* comp_free */
618     z_comp_init,                /* comp_init */
619     z_comp_reset,               /* comp_reset */
620     z_compress,                 /* compress */
621     z_comp_stats,               /* comp_stat */
622     z_decomp_alloc,             /* decomp_alloc */
623     z_decomp_free,              /* decomp_free */
624     z_decomp_init,              /* decomp_init */
625     z_decomp_reset,             /* decomp_reset */
626     z_decompress,               /* decompress */
627     z_incomp,                   /* incomp */
628     z_comp_stats,               /* decomp_stat */
629 };
630
631 #ifdef MODULE
632 /*************************************************************
633  * Module support routines
634  *************************************************************/
635
636 int
637 init_module(void)
638 {  
639         int answer = ppp_register_compressor (&ppp_deflate);
640         if (answer == 0)
641                 printk (KERN_INFO
642                         "PPP Deflate Compression module registered\n");
643         return answer;
644 }
645      
646 void
647 cleanup_module(void)
648 {
649         if (MOD_IN_USE)
650                 printk (KERN_INFO
651                         "Deflate Compression module busy, remove delayed\n");
652         else
653                 ppp_unregister_compressor (&ppp_deflate);
654 }
655 #endif