]> git.ozlabs.org Git - ppp.git/blob - linux/bsd_comp.c
add man page for pppdump and add it to the list of things
[ppp.git] / linux / bsd_comp.c
1 /* Because this code is derived from the 4.3BSD compress source:
2  *
3  * Copyright (c) 1985, 1986 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * James A. Woods, derived from original work by Spencer Thomas
8  * and Joseph Orost.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  */
38
39 /*
40  * This version is for use with contiguous buffers on Linux-derived systems.
41  *
42  *  ==FILEVERSION 970607==
43  *
44  *  NOTE TO MAINTAINERS:
45  *     If you modify this file at all, please set the number above to the
46  *     date of the modification as YYMMDD (year month day).
47  *     bsd_comp.c is shipped with a PPP distribution as well as with
48  *     the kernel; if everyone increases the FILEVERSION number above,
49  *     then scripts can do the right thing when deciding whether to
50  *     install a new bsd_comp.c file. Don't change the format of that
51  *     line otherwise, so the installation script can recognize it.
52  *
53  * From: bsd_comp.c,v 1.3 1994/12/08 01:59:58 paulus Exp
54  */
55
56 #ifndef MODULE
57 #error This file must be compiled as a module.
58 #endif
59
60 #include <linux/version.h>
61 #include <linux/module.h>
62 #include <linux/kernel.h>
63 #include <linux/sched.h>
64 #include <linux/types.h>
65 #include <linux/fcntl.h>
66 #include <linux/interrupt.h>
67 #include <linux/ptrace.h>
68 #include <linux/malloc.h>
69 #include <linux/ioport.h>
70 #include <linux/in.h>
71
72 #undef VERSION
73 /* a nice define to generate linux version numbers */
74 #define VERSION(major,minor,patch) (((((major)<<8)+(minor))<<8)+(patch))
75
76 #if LINUX_VERSION_CODE >= VERSION(2,1,4)
77 #include <linux/vmalloc.h>
78 #endif
79
80 #include <linux/tty.h>
81 #include <linux/errno.h>
82 #include <linux/sched.h>        /* to get the struct task_struct */
83 #include <linux/string.h>       /* used in new tty drivers */
84 #include <linux/signal.h>       /* used in new tty drivers */
85
86 #include <asm/system.h>
87 #include <asm/bitops.h>
88 #include <asm/byteorder.h>
89
90 #include <linux/if.h>
91
92 #include <linux/if_ether.h>
93 #include <linux/netdevice.h>
94 #include <linux/skbuff.h>
95 #include <linux/inet.h>
96 #include <linux/ioctl.h>
97
98 #include <linux/ppp_defs.h>
99
100 #undef   PACKETPTR
101 #define  PACKETPTR 1
102 #include <linux/ppp-comp.h>
103 #undef   PACKETPTR
104
105 /*
106  * PPP "BSD compress" compression
107  *  The differences between this compression and the classic BSD LZW
108  *  source are obvious from the requirement that the classic code worked
109  *  with files while this handles arbitrarily long streams that
110  *  are broken into packets.  They are:
111  *
112  *      When the code size expands, a block of junk is not emitted by
113  *          the compressor and not expected by the decompressor.
114  *
115  *      New codes are not necessarily assigned every time an old
116  *          code is output by the compressor.  This is because a packet
117  *          end forces a code to be emitted, but does not imply that a
118  *          new sequence has been seen.
119  *
120  *      The compression ratio is checked at the first end of a packet
121  *          after the appropriate gap.  Besides simplifying and speeding
122  *          things up, this makes it more likely that the transmitter
123  *          and receiver will agree when the dictionary is cleared when
124  *          compression is not going well.
125  */
126
127 /*
128  * Macros to extract protocol version and number of bits
129  * from the third byte of the BSD Compress CCP configuration option.
130  */
131
132 #define BSD_VERSION(x)  ((x) >> 5)
133 #define BSD_NBITS(x)    ((x) & 0x1F)
134
135 #define BSD_CURRENT_VERSION     1
136
137 /*
138  * A dictionary for doing BSD compress.
139  */
140
141 struct bsd_dict {
142     union {                             /* hash value */
143         unsigned long   fcode;
144         struct {
145 #if defined(__LITTLE_ENDIAN)            /* Little endian order */
146             unsigned short      prefix; /* preceding code */
147             unsigned char       suffix; /* last character of new code */
148             unsigned char       pad;
149 #elif defined(__BIG_ENDIAN)             /* Big endian order */
150             unsigned char       pad;
151             unsigned char       suffix; /* last character of new code */
152             unsigned short      prefix; /* preceding code */
153 #else
154 #error Endianness not defined...
155 #endif
156         } hs;
157     } f;
158     unsigned short codem1;              /* output of hash table -1 */
159     unsigned short cptr;                /* map code to hash table entry */
160 };
161
162 struct bsd_db {
163     int     totlen;                     /* length of this structure */
164     unsigned int   hsize;               /* size of the hash table */
165     unsigned char  hshift;              /* used in hash function */
166     unsigned char  n_bits;              /* current bits/code */
167     unsigned char  maxbits;             /* maximum bits/code */
168     unsigned char  debug;               /* non-zero if debug desired */
169     unsigned char  unit;                /* ppp unit number */
170     unsigned short seqno;               /* sequence # of next packet */
171     unsigned int   mru;                 /* size of receive (decompress) bufr */
172     unsigned int   maxmaxcode;          /* largest valid code */
173     unsigned int   max_ent;             /* largest code in use */
174     unsigned int   in_count;            /* uncompressed bytes, aged */
175     unsigned int   bytes_out;           /* compressed bytes, aged */
176     unsigned int   ratio;               /* recent compression ratio */
177     unsigned int   checkpoint;          /* when to next check the ratio */
178     unsigned int   clear_count;         /* times dictionary cleared */
179     unsigned int   incomp_count;        /* incompressible packets */
180     unsigned int   incomp_bytes;        /* incompressible bytes */
181     unsigned int   uncomp_count;        /* uncompressed packets */
182     unsigned int   uncomp_bytes;        /* uncompressed bytes */
183     unsigned int   comp_count;          /* compressed packets */
184     unsigned int   comp_bytes;          /* compressed bytes */
185     unsigned short  *lens;              /* array of lengths of codes */
186     struct bsd_dict *dict;              /* dictionary */
187 };
188
189 #define BSD_OVHD        2               /* BSD compress overhead/packet */
190 #define MIN_BSD_BITS    9
191 #define BSD_INIT_BITS   MIN_BSD_BITS
192 #define MAX_BSD_BITS    15
193
194 static void     bsd_free (void *state);
195 static void     *bsd_alloc(unsigned char *options, int opt_len, int decomp);
196 static void     *bsd_comp_alloc (unsigned char *options, int opt_len);
197 static void     *bsd_decomp_alloc (unsigned char *options, int opt_len);
198
199 static int      bsd_init        (void *db, unsigned char *options,
200                                  int opt_len, int unit, int debug, int decomp);
201 static int      bsd_comp_init   (void *state, unsigned char *options,
202                                  int opt_len, int unit, int opthdr, int debug);
203 static int      bsd_decomp_init (void *state, unsigned char *options,
204                                  int opt_len, int unit, int opthdr, int mru,
205                                  int debug);
206
207 static void     bsd_reset (void *state);
208 static void     bsd_comp_stats (void *state, struct compstat *stats);
209
210 static int      bsd_compress (void *state, unsigned char *rptr,
211                               unsigned char *obuf, int isize, int osize);
212 static void     bsd_incomp (void *state, unsigned char *ibuf, int icnt);
213
214 static int      bsd_decompress (void *state, unsigned char *ibuf, int isize,
215                                 unsigned char *obuf, int osize);
216
217 /* These are in ppp.c */
218 extern int  ppp_register_compressor   (struct compressor *cp);
219 extern void ppp_unregister_compressor (struct compressor *cp);
220
221 /*
222  * the next two codes should not be changed lightly, as they must not
223  * lie within the contiguous general code space.
224  */
225 #define CLEAR   256                     /* table clear output code */
226 #define FIRST   257                     /* first free entry */
227 #define LAST    255
228
229 #define MAXCODE(b)      ((1 << (b)) - 1)
230 #define BADCODEM1       MAXCODE(MAX_BSD_BITS);
231
232 #define BSD_HASH(prefix,suffix,hshift) ((((unsigned long)(suffix))<<(hshift)) \
233                                          ^ (unsigned long)(prefix))
234 #define BSD_KEY(prefix,suffix)          ((((unsigned long)(suffix)) << 16) \
235                                          + (unsigned long)(prefix))
236
237 #define CHECK_GAP       10000           /* Ratio check interval */
238
239 #define RATIO_SCALE_LOG 8
240 #define RATIO_SCALE     (1<<RATIO_SCALE_LOG)
241 #define RATIO_MAX       (0x7fffffff>>RATIO_SCALE_LOG)
242
243 /*
244  * clear the dictionary
245  */
246
247 static void
248 bsd_clear(struct bsd_db *db)
249 {
250     db->clear_count++;
251     db->max_ent      = FIRST-1;
252     db->n_bits       = BSD_INIT_BITS;
253     db->bytes_out    = 0;
254     db->in_count     = 0;
255     db->ratio        = 0;
256     db->checkpoint   = CHECK_GAP;
257 }
258
259 /*
260  * If the dictionary is full, then see if it is time to reset it.
261  *
262  * Compute the compression ratio using fixed-point arithmetic
263  * with 8 fractional bits.
264  *
265  * Since we have an infinite stream instead of a single file,
266  * watch only the local compression ratio.
267  *
268  * Since both peers must reset the dictionary at the same time even in
269  * the absence of CLEAR codes (while packets are incompressible), they
270  * must compute the same ratio.
271  */
272
273 static int bsd_check (struct bsd_db *db)        /* 1=output CLEAR */
274   {
275     unsigned int new_ratio;
276
277     if (db->in_count >= db->checkpoint)
278       {
279         /* age the ratio by limiting the size of the counts */
280         if (db->in_count >= RATIO_MAX || db->bytes_out >= RATIO_MAX)
281           {
282             db->in_count  -= (db->in_count  >> 2);
283             db->bytes_out -= (db->bytes_out >> 2);
284           }
285         
286         db->checkpoint = db->in_count + CHECK_GAP;
287         
288         if (db->max_ent >= db->maxmaxcode)
289           {
290             /* Reset the dictionary only if the ratio is worse,
291              * or if it looks as if it has been poisoned
292              * by incompressible data.
293              *
294              * This does not overflow, because
295              *  db->in_count <= RATIO_MAX.
296              */
297
298             new_ratio = db->in_count << RATIO_SCALE_LOG;
299             if (db->bytes_out != 0)
300               {
301                 new_ratio /= db->bytes_out;
302               }
303             
304             if (new_ratio < db->ratio || new_ratio < 1 * RATIO_SCALE)
305               {
306                 bsd_clear (db);
307                 return 1;
308               }
309             db->ratio = new_ratio;
310           }
311       }
312     return 0;
313   }
314
315 /*
316  * Return statistics.
317  */
318
319 static void bsd_comp_stats (void *state, struct compstat *stats)
320   {
321     struct bsd_db *db = (struct bsd_db *) state;
322     
323     stats->unc_bytes    = db->uncomp_bytes;
324     stats->unc_packets  = db->uncomp_count;
325     stats->comp_bytes   = db->comp_bytes;
326     stats->comp_packets = db->comp_count;
327     stats->inc_bytes    = db->incomp_bytes;
328     stats->inc_packets  = db->incomp_count;
329     stats->in_count     = db->in_count;
330     stats->bytes_out    = db->bytes_out;
331   }
332
333 /*
334  * Reset state, as on a CCP ResetReq.
335  */
336
337 static void bsd_reset (void *state)
338   {
339     struct bsd_db *db = (struct bsd_db *) state;
340
341     bsd_clear(db);
342
343     db->seqno       = 0;
344     db->clear_count = 0;
345   }
346
347 /*
348  * Release the compression structure
349  */
350
351 static void bsd_free (void *state)
352   {
353     struct bsd_db *db = (struct bsd_db *) state;
354     
355     if (db)
356       {
357 /*
358  * Release the dictionary
359  */
360         if (db->dict)
361           {
362             vfree (db->dict);
363             db->dict = NULL;
364           }
365 /*
366  * Release the string buffer
367  */
368         if (db->lens)
369           {
370             vfree (db->lens);
371             db->lens = NULL;
372           }
373 /*
374  * Finally release the structure itself.
375  */
376         kfree (db);
377         MOD_DEC_USE_COUNT;
378       }
379   }
380
381 /*
382  * Allocate space for a (de) compressor.
383  */
384
385 static void *bsd_alloc (unsigned char *options, int opt_len, int decomp)
386   {
387     int bits;
388     unsigned int hsize, hshift, maxmaxcode;
389     struct bsd_db *db;
390
391     if (opt_len != 3 || options[0] != CI_BSD_COMPRESS || options[1] != 3
392         || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION)
393       {
394         return NULL;
395       }
396
397     bits = BSD_NBITS(options[2]);
398
399     switch (bits)
400       {
401     case 9:                     /* needs 82152 for both directions */
402     case 10:                    /* needs 84144 */
403     case 11:                    /* needs 88240 */
404     case 12:                    /* needs 96432 */
405         hsize = 5003;
406         hshift = 4;
407         break;
408     case 13:                    /* needs 176784 */
409         hsize = 9001;
410         hshift = 5;
411         break;
412     case 14:                    /* needs 353744 */
413         hsize = 18013;
414         hshift = 6;
415         break;
416     case 15:                    /* needs 691440 */
417         hsize = 35023;
418         hshift = 7;
419         break;
420     case 16:                    /* needs 1366160--far too much, */
421         /* hsize = 69001; */    /* and 69001 is too big for cptr */
422         /* hshift = 8; */       /* in struct bsd_db */
423         /* break; */
424     default:
425         return NULL;
426       }
427 /*
428  * Allocate the main control structure for this instance.
429  */
430     maxmaxcode = MAXCODE(bits);
431     db         = (struct bsd_db *) kmalloc (sizeof (struct bsd_db),
432                                             GFP_KERNEL);
433     if (!db)
434       {
435         return NULL;
436       }
437
438     memset (db, 0, sizeof(struct bsd_db));
439 /*
440  * Allocate space for the dictionary. This may be more than one page in
441  * length.
442  */
443     db->dict = (struct bsd_dict *) vmalloc (hsize *
444                                             sizeof (struct bsd_dict));
445     if (!db->dict)
446       {
447         bsd_free (db);
448         return NULL;
449       }
450
451     MOD_INC_USE_COUNT;
452 /*
453  * If this is the compression buffer then there is no length data.
454  */
455     if (!decomp)
456       {
457         db->lens = NULL;
458       }
459 /*
460  * For decompression, the length information is needed as well.
461  */
462     else
463       {
464         db->lens = (unsigned short *) vmalloc ((maxmaxcode + 1) *
465                                                sizeof (db->lens[0]));
466         if (!db->lens)
467           {
468             bsd_free (db);
469             return (NULL);
470           }
471       }
472 /*
473  * Initialize the data information for the compression code
474  */
475     db->totlen     = sizeof (struct bsd_db)   +
476                     (sizeof (struct bsd_dict) * hsize);
477
478     db->hsize      = hsize;
479     db->hshift     = hshift;
480     db->maxmaxcode = maxmaxcode;
481     db->maxbits    = bits;
482
483     return (void *) db;
484   }
485
486 static void *bsd_comp_alloc (unsigned char *options, int opt_len)
487   {
488     return bsd_alloc (options, opt_len, 0);
489   }
490
491 static void *bsd_decomp_alloc (unsigned char *options, int opt_len)
492   {
493     return bsd_alloc (options, opt_len, 1);
494   }
495
496 /*
497  * Initialize the database.
498  */
499
500 static int bsd_init (void *state, unsigned char *options,
501                      int opt_len, int unit, int debug, int decomp)
502   {
503     struct bsd_db *db = state;
504     int indx;
505     
506     if ((opt_len != 3) || (options[0] != CI_BSD_COMPRESS) || (options[1] != 3)
507         || (BSD_VERSION(options[2]) != BSD_CURRENT_VERSION)
508         || (BSD_NBITS(options[2]) != db->maxbits)
509         || (decomp && db->lens == NULL))
510       {
511         return 0;
512       }
513
514     if (decomp)
515       {
516         indx = LAST;
517         do
518           {
519             db->lens[indx] = 1;
520           }
521         while (indx-- > 0);
522       }
523
524     indx = db->hsize;
525     while (indx-- != 0)
526       {
527         db->dict[indx].codem1 = BADCODEM1;
528         db->dict[indx].cptr   = 0;
529       }
530
531     db->unit = unit;
532     db->mru  = 0;
533 #ifndef DEBUG
534     if (debug)
535 #endif
536       db->debug = 1;
537     
538     bsd_reset(db);
539     
540     return 1;
541   }
542
543 static int bsd_comp_init (void *state, unsigned char *options,
544                           int opt_len, int unit, int opthdr, int debug)
545   {
546     return bsd_init (state, options, opt_len, unit, debug, 0);
547   }
548
549 static int bsd_decomp_init (void *state, unsigned char *options,
550                             int opt_len, int unit, int opthdr, int mru,
551                             int debug)
552   {
553     return bsd_init (state, options, opt_len, unit, debug, 1);
554   }
555
556 /*
557  * Obtain pointers to the various structures in the compression tables
558  */
559
560 #define dict_ptrx(p,idx) &(p->dict[idx])
561 #define lens_ptrx(p,idx) &(p->lens[idx])
562
563 #ifdef DEBUG
564 static unsigned short *lens_ptr(struct bsd_db *db, int idx)
565   {
566     if ((unsigned int) idx > (unsigned int) db->maxmaxcode)
567       {
568         printk ("<9>ppp: lens_ptr(%d) > max\n", idx);
569         idx = 0;
570       }
571     return lens_ptrx (db, idx);
572   }
573
574 static struct bsd_dict *dict_ptr(struct bsd_db *db, int idx)
575   {
576     if ((unsigned int) idx >= (unsigned int) db->hsize)
577       {
578         printk ("<9>ppp: dict_ptr(%d) > max\n", idx);
579         idx = 0;
580       }
581     return dict_ptrx (db, idx);
582   }
583
584 #else
585 #define lens_ptr(db,idx) lens_ptrx(db,idx)
586 #define dict_ptr(db,idx) dict_ptrx(db,idx)
587 #endif
588
589 /*
590  * compress a packet
591  *
592  *      The result of this function is the size of the compressed
593  *      packet. A zero is returned if the packet was not compressed
594  *      for some reason, such as the size being larger than uncompressed.
595  *
596  *      One change from the BSD compress command is that when the
597  *      code size expands, we do not output a bunch of padding.
598  */
599
600 static int bsd_compress (void *state, unsigned char *rptr, unsigned char *obuf,
601                          int isize, int osize)
602   {
603     struct bsd_db *db;
604     int hshift;
605     unsigned int max_ent;
606     unsigned int n_bits;
607     unsigned int bitno;
608     unsigned long accm;
609     int ent;
610     unsigned long fcode;
611     struct bsd_dict *dictp;
612     unsigned char c;
613     int hval;
614     int disp;
615     int ilen;
616     int mxcode;
617     unsigned char *wptr;
618     int olen;
619
620 #define PUTBYTE(v)                      \
621   {                                     \
622     ++olen;                             \
623     if (wptr)                           \
624       {                                 \
625         *wptr++ = (unsigned char) (v);  \
626         if (olen >= osize)              \
627           {                             \
628             wptr = NULL;                \
629           }                             \
630       }                                 \
631   }
632
633 #define OUTPUT(ent)                     \
634   {                                     \
635     bitno -= n_bits;                    \
636     accm |= ((ent) << bitno);           \
637     do                                  \
638       {                                 \
639         PUTBYTE(accm >> 24);            \
640         accm <<= 8;                     \
641         bitno += 8;                     \
642       }                                 \
643     while (bitno <= 24);                \
644   }
645
646   /*
647    * If the protocol is not in the range we're interested in,
648    * just return without compressing the packet.  If it is,
649    * the protocol becomes the first byte to compress.
650    */
651
652     ent = PPP_PROTOCOL(rptr);
653     if (ent < 0x21 || ent > 0xf9)
654       {
655         return 0;
656       }
657
658     db      = (struct bsd_db *) state;
659     hshift  = db->hshift;
660     max_ent = db->max_ent;
661     n_bits  = db->n_bits;
662     bitno   = 32;
663     accm    = 0;
664     mxcode  = MAXCODE (n_bits);
665
666     /* Initialize the output pointers */
667     wptr  = obuf;
668     olen  = PPP_HDRLEN + BSD_OVHD;
669
670     if (osize > isize)
671       {
672         osize = isize;
673       }
674
675     /* This is the PPP header information */
676     if (wptr)
677       {
678         *wptr++ = PPP_ADDRESS(rptr);
679         *wptr++ = PPP_CONTROL(rptr);
680         *wptr++ = 0;
681         *wptr++ = PPP_COMP;
682         *wptr++ = db->seqno >> 8;
683         *wptr++ = db->seqno;
684       }
685
686     /* Skip the input header */
687     rptr  += PPP_HDRLEN;
688     isize -= PPP_HDRLEN;
689     ilen   = ++isize;   /* Low byte of protocol is counted as input */
690
691     while (--ilen > 0)
692       {
693         c     = *rptr++;
694         fcode = BSD_KEY  (ent, c);
695         hval  = BSD_HASH (ent, c, hshift);
696         dictp = dict_ptr (db, hval);
697         
698         /* Validate and then check the entry. */
699         if (dictp->codem1 >= max_ent)
700           {
701             goto nomatch;
702           }
703
704         if (dictp->f.fcode == fcode)
705           {
706             ent = dictp->codem1 + 1;
707             continue;   /* found (prefix,suffix) */
708           }
709         
710         /* continue probing until a match or invalid entry */
711         disp = (hval == 0) ? 1 : hval;
712
713         do
714           {
715             hval += disp;
716             if (hval >= db->hsize)
717               {
718                 hval -= db->hsize;
719               }
720             dictp = dict_ptr (db, hval);
721             if (dictp->codem1 >= max_ent)
722               {
723                 goto nomatch;
724               }
725           }
726         while (dictp->f.fcode != fcode);
727
728         ent = dictp->codem1 + 1;        /* finally found (prefix,suffix) */
729         continue;
730         
731 nomatch:
732         OUTPUT(ent);            /* output the prefix */
733         
734         /* code -> hashtable */
735         if (max_ent < db->maxmaxcode)
736           {
737             struct bsd_dict *dictp2;
738             struct bsd_dict *dictp3;
739             int    indx;
740
741             /* expand code size if needed */
742             if (max_ent >= mxcode)
743               {
744                 db->n_bits = ++n_bits;
745                 mxcode     = MAXCODE (n_bits);
746               }
747             
748             /* Invalidate old hash table entry using
749              * this code, and then take it over.
750              */
751
752             dictp2 = dict_ptr (db, max_ent + 1);
753             indx   = dictp2->cptr;
754             dictp3 = dict_ptr (db, indx);
755
756             if (dictp3->codem1 == max_ent)
757               {
758                 dictp3->codem1 = BADCODEM1;
759               }
760
761             dictp2->cptr   = hval;
762             dictp->codem1  = max_ent;
763             dictp->f.fcode = fcode;
764             db->max_ent    = ++max_ent;
765
766             if (db->lens)
767               {
768                 unsigned short *len1 = lens_ptr (db, max_ent);
769                 unsigned short *len2 = lens_ptr (db, ent);
770                 *len1 = *len2 + 1;
771               }
772           }
773         ent = c;
774       }
775     
776     OUTPUT(ent);                /* output the last code */
777
778     db->bytes_out    += olen - PPP_HDRLEN - BSD_OVHD;
779     db->uncomp_bytes += isize;
780     db->in_count     += isize;
781     ++db->uncomp_count;
782     ++db->seqno;
783
784     if (bitno < 32)
785       {
786         ++db->bytes_out; /* must be set before calling bsd_check */
787       }
788
789     /*
790      * Generate the clear command if needed
791      */
792
793     if (bsd_check(db))
794       {
795         OUTPUT (CLEAR);
796       }
797     
798     /*
799      * Pad dribble bits of last code with ones.
800      * Do not emit a completely useless byte of ones.
801      */
802
803     if (bitno != 32)
804       {
805         PUTBYTE((accm | (0xff << (bitno-8))) >> 24);
806       }
807     
808     /*
809      * Increase code size if we would have without the packet
810      * boundary because the decompressor will do so.
811      */
812
813     if (max_ent >= mxcode && max_ent < db->maxmaxcode)
814       {
815         db->n_bits++;
816       }
817
818     /* If output length is too large then this is an incomplete frame. */
819     if (wptr == NULL)
820       {
821         ++db->incomp_count;
822         db->incomp_bytes += isize;
823         olen              = 0;
824       }
825     else /* Count the number of compressed frames */
826       {
827         ++db->comp_count;
828         db->comp_bytes += olen;
829       }
830
831     /* Return the resulting output length */
832     return olen;
833 #undef OUTPUT
834 #undef PUTBYTE
835   }
836
837 /*
838  * Update the "BSD Compress" dictionary on the receiver for
839  * incompressible data by pretending to compress the incoming data.
840  */
841
842 static void bsd_incomp (void *state, unsigned char *ibuf, int icnt)
843   {
844     (void) bsd_compress (state, ibuf, (char *) 0, icnt, 0);
845   }
846
847 /*
848  * Decompress "BSD Compress".
849  *
850  * Because of patent problems, we return DECOMP_ERROR for errors
851  * found by inspecting the input data and for system problems, but
852  * DECOMP_FATALERROR for any errors which could possibly be said to
853  * be being detected "after" decompression.  For DECOMP_ERROR,
854  * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
855  * infringing a patent of Motorola's if we do, so we take CCP down
856  * instead.
857  *
858  * Given that the frame has the correct sequence number and a good FCS,
859  * errors such as invalid codes in the input most likely indicate a
860  * bug, so we return DECOMP_FATALERROR for them in order to turn off
861  * compression, even though they are detected by inspecting the input.
862  */
863
864 static int bsd_decompress (void *state, unsigned char *ibuf, int isize,
865                            unsigned char *obuf, int osize)
866   {
867     struct bsd_db *db;
868     unsigned int max_ent;
869     unsigned long accm;
870     unsigned int bitno;         /* 1st valid bit in accm */
871     unsigned int n_bits;
872     unsigned int tgtbitno;      /* bitno when we have a code */
873     struct bsd_dict *dictp;
874     int explen;
875     int seq;
876     unsigned int incode;
877     unsigned int oldcode;
878     unsigned int finchar;
879     unsigned char *p;
880     unsigned char *wptr;
881     int adrs;
882     int ctrl;
883     int ilen;
884     int codelen;
885     int extra;
886
887     db       = (struct bsd_db *) state;
888     max_ent  = db->max_ent;
889     accm     = 0;
890     bitno    = 32;              /* 1st valid bit in accm */
891     n_bits   = db->n_bits;
892     tgtbitno = 32 - n_bits;     /* bitno when we have a code */
893     
894     /*
895      * Save the address/control from the PPP header
896      * and then get the sequence number.
897      */
898
899     adrs  = PPP_ADDRESS (ibuf);
900     ctrl  = PPP_CONTROL (ibuf);
901
902     seq   = (ibuf[4] << 8) + ibuf[5];
903
904     ibuf += (PPP_HDRLEN + 2);
905     ilen  = isize - (PPP_HDRLEN + 2);
906     
907     /*
908      * Check the sequence number and give up if it differs from
909      * the value we're expecting.
910      */
911
912     if (seq != db->seqno)
913       {
914         if (db->debug)
915           {
916             printk("bsd_decomp%d: bad sequence # %d, expected %d\n",
917                    db->unit, seq, db->seqno - 1);
918           }
919         return DECOMP_ERROR;
920       }
921
922     ++db->seqno;
923     db->bytes_out += ilen;
924
925     /*
926      * Fill in the ppp header, but not the last byte of the protocol
927      * (that comes from the decompressed data).
928      */
929
930     wptr    = obuf;
931     *wptr++ = adrs;
932     *wptr++ = ctrl;
933     *wptr++ = 0;
934     
935     oldcode = CLEAR;
936     explen  = 3;
937
938     /*
939      * Keep the checkpoint correctly so that incompressible packets
940      * clear the dictionary at the proper times.
941      */
942
943     for (;;)
944       {
945         if (ilen-- <= 0)
946           {
947             db->in_count += (explen - 3); /* don't count the header */
948             break;
949           }
950
951         /*
952          * Accumulate bytes until we have a complete code.
953          * Then get the next code, relying on the 32-bit,
954          * unsigned accm to mask the result.
955          */
956
957         bitno -= 8;
958         accm  |= *ibuf++ << bitno;
959         if (tgtbitno < bitno)
960           {
961             continue;
962           }
963
964         incode = accm >> tgtbitno;
965         accm <<= n_bits;
966         bitno += n_bits;
967
968         /*
969          * The dictionary must only be cleared at the end of a packet.
970          */
971         
972         if (incode == CLEAR)
973           {
974             if (ilen > 0)
975               {
976                 if (db->debug)
977                   {
978                     printk("bsd_decomp%d: bad CLEAR\n", db->unit);
979                   }
980                 return DECOMP_FATALERROR;       /* probably a bug */
981               }
982             
983             bsd_clear(db);
984             break;
985           }
986
987         if ((incode > max_ent + 2) || (incode > db->maxmaxcode)
988             || (incode > max_ent && oldcode == CLEAR))
989           {
990             if (db->debug)
991               {
992                 printk("bsd_decomp%d: bad code 0x%x oldcode=0x%x ",
993                        db->unit, incode, oldcode);
994                 printk("max_ent=0x%x explen=%d seqno=%d\n",
995                        max_ent, explen, db->seqno);
996               }
997             return DECOMP_FATALERROR;   /* probably a bug */
998           }
999         
1000         /* Special case for KwKwK string. */
1001         if (incode > max_ent)
1002           {
1003             finchar = oldcode;
1004             extra   = 1;
1005           }
1006         else
1007           {
1008             finchar = incode;
1009             extra   = 0;
1010           }
1011         
1012         codelen = *(lens_ptr (db, finchar));
1013         explen += codelen + extra;
1014         if (explen > osize)
1015           {
1016             if (db->debug)
1017               {
1018                 printk("bsd_decomp%d: ran out of mru\n", db->unit);
1019 #ifdef DEBUG
1020                 printk("  len=%d, finchar=0x%x, codelen=%d, explen=%d\n",
1021                        ilen, finchar, codelen, explen);
1022 #endif
1023               }
1024             return DECOMP_FATALERROR;
1025           }
1026         
1027         /*
1028          * Decode this code and install it in the decompressed buffer.
1029          */
1030
1031         wptr += codelen;
1032         p     = wptr;
1033         while (finchar > LAST)
1034           {
1035             struct bsd_dict *dictp2 = dict_ptr (db, finchar);
1036             
1037             dictp = dict_ptr (db, dictp2->cptr);
1038 #ifdef DEBUG
1039             if (--codelen <= 0 || dictp->codem1 != finchar-1)
1040               {
1041                 if (codelen <= 0)
1042                   {
1043                     printk("bsd_decomp%d: fell off end of chain ", db->unit);
1044                     printk("0x%x at 0x%x by 0x%x, max_ent=0x%x\n",
1045                            incode, finchar, dictp2->cptr, max_ent);
1046                   }
1047                 else
1048                   {
1049                     if (dictp->codem1 != finchar-1)
1050                       {
1051                         printk("bsd_decomp%d: bad code chain 0x%x "
1052                                "finchar=0x%x ",
1053                                db->unit, incode, finchar);
1054
1055                         printk("oldcode=0x%x cptr=0x%x codem1=0x%x\n",
1056                                oldcode, dictp2->cptr, dictp->codem1);
1057                       }
1058                   }
1059                 return DECOMP_FATALERROR;
1060               }
1061 #endif
1062             *--p    = dictp->f.hs.suffix;
1063             finchar = dictp->f.hs.prefix;
1064           }
1065         *--p = finchar;
1066         
1067 #ifdef DEBUG
1068         if (--codelen != 0)
1069           {
1070             printk("bsd_decomp%d: short by %d after code 0x%x, max_ent=0x%x\n",
1071                    db->unit, codelen, incode, max_ent);
1072           }
1073 #endif
1074         
1075         if (extra)              /* the KwKwK case again */
1076           {
1077             *wptr++ = finchar;
1078           }
1079         
1080         /*
1081          * If not first code in a packet, and
1082          * if not out of code space, then allocate a new code.
1083          *
1084          * Keep the hash table correct so it can be used
1085          * with uncompressed packets.
1086          */
1087
1088         if (oldcode != CLEAR && max_ent < db->maxmaxcode)
1089           {
1090             struct bsd_dict *dictp2, *dictp3;
1091             unsigned short  *lens1,  *lens2;
1092             unsigned long fcode;
1093             int hval, disp, indx;
1094             
1095             fcode = BSD_KEY(oldcode,finchar);
1096             hval  = BSD_HASH(oldcode,finchar,db->hshift);
1097             dictp = dict_ptr (db, hval);
1098             
1099             /* look for a free hash table entry */
1100             if (dictp->codem1 < max_ent)
1101               {
1102                 disp = (hval == 0) ? 1 : hval;
1103                 do
1104                   {
1105                     hval += disp;
1106                     if (hval >= db->hsize)
1107                       {
1108                         hval -= db->hsize;
1109                       }
1110                     dictp = dict_ptr (db, hval);
1111                   }
1112                 while (dictp->codem1 < max_ent);
1113               }
1114             
1115             /*
1116              * Invalidate previous hash table entry
1117              * assigned this code, and then take it over
1118              */
1119
1120             dictp2 = dict_ptr (db, max_ent + 1);
1121             indx   = dictp2->cptr;
1122             dictp3 = dict_ptr (db, indx);
1123
1124             if (dictp3->codem1 == max_ent)
1125               {
1126                 dictp3->codem1 = BADCODEM1;
1127               }
1128
1129             dictp2->cptr   = hval;
1130             dictp->codem1  = max_ent;
1131             dictp->f.fcode = fcode;
1132             db->max_ent    = ++max_ent;
1133
1134             /* Update the length of this string. */
1135             lens1  = lens_ptr (db, max_ent);
1136             lens2  = lens_ptr (db, oldcode);
1137             *lens1 = *lens2 + 1;
1138             
1139             /* Expand code size if needed. */
1140             if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode)
1141               {
1142                 db->n_bits = ++n_bits;
1143                 tgtbitno   = 32-n_bits;
1144               }
1145           }
1146         oldcode = incode;
1147       }
1148
1149     ++db->comp_count;
1150     ++db->uncomp_count;
1151     db->comp_bytes   += isize - BSD_OVHD - PPP_HDRLEN;
1152     db->uncomp_bytes += explen;
1153
1154     if (bsd_check(db))
1155       {
1156         if (db->debug)
1157           {
1158             printk("bsd_decomp%d: peer should have cleared dictionary on %d\n",
1159                    db->unit, db->seqno - 1);
1160           }
1161       }
1162     return explen;
1163   }
1164      
1165 /*************************************************************
1166  * Table of addresses for the BSD compression module
1167  *************************************************************/
1168
1169 static struct compressor ppp_bsd_compress = {
1170     CI_BSD_COMPRESS,            /* compress_proto */
1171     bsd_comp_alloc,             /* comp_alloc */
1172     bsd_free,                   /* comp_free */
1173     bsd_comp_init,              /* comp_init */
1174     bsd_reset,                  /* comp_reset */
1175     bsd_compress,               /* compress */
1176     bsd_comp_stats,             /* comp_stat */
1177     bsd_decomp_alloc,           /* decomp_alloc */
1178     bsd_free,                   /* decomp_free */
1179     bsd_decomp_init,            /* decomp_init */
1180     bsd_reset,                  /* decomp_reset */
1181     bsd_decompress,             /* decompress */
1182     bsd_incomp,                 /* incomp */
1183     bsd_comp_stats              /* decomp_stat */
1184 };
1185
1186 /*************************************************************
1187  * Module support routines
1188  *************************************************************/
1189
1190 int
1191 init_module(void)
1192 {
1193         int answer = ppp_register_compressor (&ppp_bsd_compress);
1194         if (answer == 0)
1195                 printk (KERN_INFO "PPP BSD Compression module registered\n");
1196         return answer;
1197 }
1198
1199 void
1200 cleanup_module(void)
1201 {
1202         ppp_unregister_compressor (&ppp_bsd_compress);
1203 }