0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 #include <linux/module.h>
0065 #include <linux/init.h>
0066 #include <linux/slab.h>
0067 #include <linux/vmalloc.h>
0068 #include <linux/string.h>
0069
0070 #include <linux/ppp_defs.h>
0071
0072 #undef PACKETPTR
0073 #define PACKETPTR 1
0074 #include <linux/ppp-comp.h>
0075 #undef PACKETPTR
0076
0077 #include <asm/byteorder.h>
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 #define BSD_VERSION(x) ((x) >> 5)
0107 #define BSD_NBITS(x) ((x) & 0x1F)
0108
0109 #define BSD_CURRENT_VERSION 1
0110
0111
0112
0113
0114
0115 struct bsd_dict {
0116 union {
0117 unsigned long fcode;
0118 struct {
0119 #if defined(__LITTLE_ENDIAN)
0120 unsigned short prefix;
0121 unsigned char suffix;
0122 unsigned char pad;
0123 #elif defined(__BIG_ENDIAN)
0124 unsigned char pad;
0125 unsigned char suffix;
0126 unsigned short prefix;
0127 #else
0128 #error Endianness not defined...
0129 #endif
0130 } hs;
0131 } f;
0132 unsigned short codem1;
0133 unsigned short cptr;
0134 };
0135
0136 struct bsd_db {
0137 int totlen;
0138 unsigned int hsize;
0139 unsigned char hshift;
0140 unsigned char n_bits;
0141 unsigned char maxbits;
0142 unsigned char debug;
0143 unsigned char unit;
0144 unsigned short seqno;
0145 unsigned int mru;
0146 unsigned int maxmaxcode;
0147 unsigned int max_ent;
0148 unsigned int in_count;
0149 unsigned int bytes_out;
0150 unsigned int ratio;
0151 unsigned int checkpoint;
0152 unsigned int clear_count;
0153 unsigned int incomp_count;
0154 unsigned int incomp_bytes;
0155 unsigned int uncomp_count;
0156 unsigned int uncomp_bytes;
0157 unsigned int comp_count;
0158 unsigned int comp_bytes;
0159 unsigned short *lens;
0160 struct bsd_dict *dict;
0161 };
0162
0163 #define BSD_OVHD 2
0164 #define MIN_BSD_BITS 9
0165 #define BSD_INIT_BITS MIN_BSD_BITS
0166 #define MAX_BSD_BITS 15
0167
0168 static void bsd_free (void *state);
0169 static void *bsd_alloc(unsigned char *options, int opt_len, int decomp);
0170 static void *bsd_comp_alloc (unsigned char *options, int opt_len);
0171 static void *bsd_decomp_alloc (unsigned char *options, int opt_len);
0172
0173 static int bsd_init (void *db, unsigned char *options,
0174 int opt_len, int unit, int debug, int decomp);
0175 static int bsd_comp_init (void *state, unsigned char *options,
0176 int opt_len, int unit, int opthdr, int debug);
0177 static int bsd_decomp_init (void *state, unsigned char *options,
0178 int opt_len, int unit, int opthdr, int mru,
0179 int debug);
0180
0181 static void bsd_reset (void *state);
0182 static void bsd_comp_stats (void *state, struct compstat *stats);
0183
0184 static int bsd_compress (void *state, unsigned char *rptr,
0185 unsigned char *obuf, int isize, int osize);
0186 static void bsd_incomp (void *state, unsigned char *ibuf, int icnt);
0187
0188 static int bsd_decompress (void *state, unsigned char *ibuf, int isize,
0189 unsigned char *obuf, int osize);
0190
0191
0192 extern int ppp_register_compressor (struct compressor *cp);
0193 extern void ppp_unregister_compressor (struct compressor *cp);
0194
0195
0196
0197
0198
0199 #define CLEAR 256
0200 #define FIRST 257
0201 #define LAST 255
0202
0203 #define MAXCODE(b) ((1 << (b)) - 1)
0204 #define BADCODEM1 MAXCODE(MAX_BSD_BITS)
0205
0206 #define BSD_HASH(prefix,suffix,hshift) ((((unsigned long)(suffix))<<(hshift)) \
0207 ^ (unsigned long)(prefix))
0208 #define BSD_KEY(prefix,suffix) ((((unsigned long)(suffix)) << 16) \
0209 + (unsigned long)(prefix))
0210
0211 #define CHECK_GAP 10000
0212
0213 #define RATIO_SCALE_LOG 8
0214 #define RATIO_SCALE (1<<RATIO_SCALE_LOG)
0215 #define RATIO_MAX (0x7fffffff>>RATIO_SCALE_LOG)
0216
0217
0218
0219
0220
0221 static void
0222 bsd_clear(struct bsd_db *db)
0223 {
0224 db->clear_count++;
0225 db->max_ent = FIRST-1;
0226 db->n_bits = BSD_INIT_BITS;
0227 db->bytes_out = 0;
0228 db->in_count = 0;
0229 db->ratio = 0;
0230 db->checkpoint = CHECK_GAP;
0231 }
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 static int bsd_check (struct bsd_db *db)
0248 {
0249 unsigned int new_ratio;
0250
0251 if (db->in_count >= db->checkpoint)
0252 {
0253
0254 if (db->in_count >= RATIO_MAX || db->bytes_out >= RATIO_MAX)
0255 {
0256 db->in_count -= (db->in_count >> 2);
0257 db->bytes_out -= (db->bytes_out >> 2);
0258 }
0259
0260 db->checkpoint = db->in_count + CHECK_GAP;
0261
0262 if (db->max_ent >= db->maxmaxcode)
0263 {
0264
0265
0266
0267
0268
0269
0270
0271
0272 new_ratio = db->in_count << RATIO_SCALE_LOG;
0273 if (db->bytes_out != 0)
0274 {
0275 new_ratio /= db->bytes_out;
0276 }
0277
0278 if (new_ratio < db->ratio || new_ratio < 1 * RATIO_SCALE)
0279 {
0280 bsd_clear (db);
0281 return 1;
0282 }
0283 db->ratio = new_ratio;
0284 }
0285 }
0286 return 0;
0287 }
0288
0289
0290
0291
0292
0293 static void bsd_comp_stats (void *state, struct compstat *stats)
0294 {
0295 struct bsd_db *db = (struct bsd_db *) state;
0296
0297 stats->unc_bytes = db->uncomp_bytes;
0298 stats->unc_packets = db->uncomp_count;
0299 stats->comp_bytes = db->comp_bytes;
0300 stats->comp_packets = db->comp_count;
0301 stats->inc_bytes = db->incomp_bytes;
0302 stats->inc_packets = db->incomp_count;
0303 stats->in_count = db->in_count;
0304 stats->bytes_out = db->bytes_out;
0305 }
0306
0307
0308
0309
0310
0311 static void bsd_reset (void *state)
0312 {
0313 struct bsd_db *db = (struct bsd_db *) state;
0314
0315 bsd_clear(db);
0316
0317 db->seqno = 0;
0318 db->clear_count = 0;
0319 }
0320
0321
0322
0323
0324
0325 static void bsd_free (void *state)
0326 {
0327 struct bsd_db *db = state;
0328
0329 if (!db)
0330 return;
0331
0332
0333
0334
0335 vfree(db->dict);
0336 db->dict = NULL;
0337
0338
0339
0340 vfree(db->lens);
0341 db->lens = NULL;
0342
0343
0344
0345 kfree(db);
0346 }
0347
0348
0349
0350
0351
0352 static void *bsd_alloc (unsigned char *options, int opt_len, int decomp)
0353 {
0354 int bits;
0355 unsigned int hsize, hshift, maxmaxcode;
0356 struct bsd_db *db;
0357
0358 if (opt_len != 3 || options[0] != CI_BSD_COMPRESS || options[1] != 3
0359 || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION)
0360 {
0361 return NULL;
0362 }
0363
0364 bits = BSD_NBITS(options[2]);
0365
0366 switch (bits)
0367 {
0368 case 9:
0369 case 10:
0370 case 11:
0371 case 12:
0372 hsize = 5003;
0373 hshift = 4;
0374 break;
0375 case 13:
0376 hsize = 9001;
0377 hshift = 5;
0378 break;
0379 case 14:
0380 hsize = 18013;
0381 hshift = 6;
0382 break;
0383 case 15:
0384 hsize = 35023;
0385 hshift = 7;
0386 break;
0387 case 16:
0388
0389
0390
0391 default:
0392 return NULL;
0393 }
0394
0395
0396
0397 maxmaxcode = MAXCODE(bits);
0398 db = kzalloc(sizeof (struct bsd_db),
0399 GFP_KERNEL);
0400 if (!db)
0401 {
0402 return NULL;
0403 }
0404
0405
0406
0407
0408
0409 db->dict = vmalloc(array_size(hsize, sizeof(struct bsd_dict)));
0410 if (!db->dict)
0411 {
0412 bsd_free (db);
0413 return NULL;
0414 }
0415
0416
0417
0418
0419 if (!decomp)
0420 {
0421 db->lens = NULL;
0422 }
0423
0424
0425
0426 else
0427 {
0428 db->lens = vmalloc(array_size(sizeof(db->lens[0]), (maxmaxcode + 1)));
0429 if (!db->lens)
0430 {
0431 bsd_free (db);
0432 return NULL;
0433 }
0434 }
0435
0436
0437
0438 db->totlen = sizeof (struct bsd_db) +
0439 (sizeof (struct bsd_dict) * hsize);
0440
0441 db->hsize = hsize;
0442 db->hshift = hshift;
0443 db->maxmaxcode = maxmaxcode;
0444 db->maxbits = bits;
0445
0446 return (void *) db;
0447 }
0448
0449 static void *bsd_comp_alloc (unsigned char *options, int opt_len)
0450 {
0451 return bsd_alloc (options, opt_len, 0);
0452 }
0453
0454 static void *bsd_decomp_alloc (unsigned char *options, int opt_len)
0455 {
0456 return bsd_alloc (options, opt_len, 1);
0457 }
0458
0459
0460
0461
0462
0463 static int bsd_init (void *state, unsigned char *options,
0464 int opt_len, int unit, int debug, int decomp)
0465 {
0466 struct bsd_db *db = state;
0467 int indx;
0468
0469 if ((opt_len != 3) || (options[0] != CI_BSD_COMPRESS) || (options[1] != 3)
0470 || (BSD_VERSION(options[2]) != BSD_CURRENT_VERSION)
0471 || (BSD_NBITS(options[2]) != db->maxbits)
0472 || (decomp && db->lens == NULL))
0473 {
0474 return 0;
0475 }
0476
0477 if (decomp)
0478 {
0479 indx = LAST;
0480 do
0481 {
0482 db->lens[indx] = 1;
0483 }
0484 while (indx-- > 0);
0485 }
0486
0487 indx = db->hsize;
0488 while (indx-- != 0)
0489 {
0490 db->dict[indx].codem1 = BADCODEM1;
0491 db->dict[indx].cptr = 0;
0492 }
0493
0494 db->unit = unit;
0495 db->mru = 0;
0496 #ifndef DEBUG
0497 if (debug)
0498 #endif
0499 db->debug = 1;
0500
0501 bsd_reset(db);
0502
0503 return 1;
0504 }
0505
0506 static int bsd_comp_init (void *state, unsigned char *options,
0507 int opt_len, int unit, int opthdr, int debug)
0508 {
0509 return bsd_init (state, options, opt_len, unit, debug, 0);
0510 }
0511
0512 static int bsd_decomp_init (void *state, unsigned char *options,
0513 int opt_len, int unit, int opthdr, int mru,
0514 int debug)
0515 {
0516 return bsd_init (state, options, opt_len, unit, debug, 1);
0517 }
0518
0519
0520
0521
0522
0523 #define dict_ptrx(p,idx) &(p->dict[idx])
0524 #define lens_ptrx(p,idx) &(p->lens[idx])
0525
0526 #ifdef DEBUG
0527 static unsigned short *lens_ptr(struct bsd_db *db, int idx)
0528 {
0529 if ((unsigned int) idx > (unsigned int) db->maxmaxcode)
0530 {
0531 printk ("<9>ppp: lens_ptr(%d) > max\n", idx);
0532 idx = 0;
0533 }
0534 return lens_ptrx (db, idx);
0535 }
0536
0537 static struct bsd_dict *dict_ptr(struct bsd_db *db, int idx)
0538 {
0539 if ((unsigned int) idx >= (unsigned int) db->hsize)
0540 {
0541 printk ("<9>ppp: dict_ptr(%d) > max\n", idx);
0542 idx = 0;
0543 }
0544 return dict_ptrx (db, idx);
0545 }
0546
0547 #else
0548 #define lens_ptr(db,idx) lens_ptrx(db,idx)
0549 #define dict_ptr(db,idx) dict_ptrx(db,idx)
0550 #endif
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563 static int bsd_compress (void *state, unsigned char *rptr, unsigned char *obuf,
0564 int isize, int osize)
0565 {
0566 struct bsd_db *db;
0567 int hshift;
0568 unsigned int max_ent;
0569 unsigned int n_bits;
0570 unsigned int bitno;
0571 unsigned long accm;
0572 int ent;
0573 unsigned long fcode;
0574 struct bsd_dict *dictp;
0575 unsigned char c;
0576 int hval;
0577 int disp;
0578 int ilen;
0579 int mxcode;
0580 unsigned char *wptr;
0581 int olen;
0582
0583 #define PUTBYTE(v) \
0584 { \
0585 ++olen; \
0586 if (wptr) \
0587 { \
0588 *wptr++ = (unsigned char) (v); \
0589 if (olen >= osize) \
0590 { \
0591 wptr = NULL; \
0592 } \
0593 } \
0594 }
0595
0596 #define OUTPUT(ent) \
0597 { \
0598 bitno -= n_bits; \
0599 accm |= ((ent) << bitno); \
0600 do \
0601 { \
0602 PUTBYTE(accm >> 24); \
0603 accm <<= 8; \
0604 bitno += 8; \
0605 } \
0606 while (bitno <= 24); \
0607 }
0608
0609
0610
0611
0612
0613
0614
0615 ent = PPP_PROTOCOL(rptr);
0616 if (ent < 0x21 || ent > 0xf9)
0617 {
0618 return 0;
0619 }
0620
0621 db = (struct bsd_db *) state;
0622 hshift = db->hshift;
0623 max_ent = db->max_ent;
0624 n_bits = db->n_bits;
0625 bitno = 32;
0626 accm = 0;
0627 mxcode = MAXCODE (n_bits);
0628
0629
0630 wptr = obuf;
0631 olen = PPP_HDRLEN + BSD_OVHD;
0632
0633 if (osize > isize)
0634 {
0635 osize = isize;
0636 }
0637
0638
0639 if (wptr)
0640 {
0641 *wptr++ = PPP_ADDRESS(rptr);
0642 *wptr++ = PPP_CONTROL(rptr);
0643 *wptr++ = 0;
0644 *wptr++ = PPP_COMP;
0645 *wptr++ = db->seqno >> 8;
0646 *wptr++ = db->seqno;
0647 }
0648
0649
0650 rptr += PPP_HDRLEN;
0651 isize -= PPP_HDRLEN;
0652 ilen = ++isize;
0653
0654 while (--ilen > 0)
0655 {
0656 c = *rptr++;
0657 fcode = BSD_KEY (ent, c);
0658 hval = BSD_HASH (ent, c, hshift);
0659 dictp = dict_ptr (db, hval);
0660
0661
0662 if (dictp->codem1 >= max_ent)
0663 {
0664 goto nomatch;
0665 }
0666
0667 if (dictp->f.fcode == fcode)
0668 {
0669 ent = dictp->codem1 + 1;
0670 continue;
0671 }
0672
0673
0674 disp = (hval == 0) ? 1 : hval;
0675
0676 do
0677 {
0678 hval += disp;
0679 if (hval >= db->hsize)
0680 {
0681 hval -= db->hsize;
0682 }
0683 dictp = dict_ptr (db, hval);
0684 if (dictp->codem1 >= max_ent)
0685 {
0686 goto nomatch;
0687 }
0688 }
0689 while (dictp->f.fcode != fcode);
0690
0691 ent = dictp->codem1 + 1;
0692 continue;
0693
0694 nomatch:
0695 OUTPUT(ent);
0696
0697
0698 if (max_ent < db->maxmaxcode)
0699 {
0700 struct bsd_dict *dictp2;
0701 struct bsd_dict *dictp3;
0702 int indx;
0703
0704
0705 if (max_ent >= mxcode)
0706 {
0707 db->n_bits = ++n_bits;
0708 mxcode = MAXCODE (n_bits);
0709 }
0710
0711
0712
0713
0714
0715 dictp2 = dict_ptr (db, max_ent + 1);
0716 indx = dictp2->cptr;
0717 dictp3 = dict_ptr (db, indx);
0718
0719 if (dictp3->codem1 == max_ent)
0720 {
0721 dictp3->codem1 = BADCODEM1;
0722 }
0723
0724 dictp2->cptr = hval;
0725 dictp->codem1 = max_ent;
0726 dictp->f.fcode = fcode;
0727 db->max_ent = ++max_ent;
0728
0729 if (db->lens)
0730 {
0731 unsigned short *len1 = lens_ptr (db, max_ent);
0732 unsigned short *len2 = lens_ptr (db, ent);
0733 *len1 = *len2 + 1;
0734 }
0735 }
0736 ent = c;
0737 }
0738
0739 OUTPUT(ent);
0740
0741 db->bytes_out += olen - PPP_HDRLEN - BSD_OVHD;
0742 db->uncomp_bytes += isize;
0743 db->in_count += isize;
0744 ++db->uncomp_count;
0745 ++db->seqno;
0746
0747 if (bitno < 32)
0748 {
0749 ++db->bytes_out;
0750 }
0751
0752
0753
0754
0755
0756 if (bsd_check(db))
0757 {
0758 OUTPUT (CLEAR);
0759 }
0760
0761
0762
0763
0764
0765
0766 if (bitno != 32)
0767 {
0768 PUTBYTE((accm | (0xff << (bitno-8))) >> 24);
0769 }
0770
0771
0772
0773
0774
0775
0776 if (max_ent >= mxcode && max_ent < db->maxmaxcode)
0777 {
0778 db->n_bits++;
0779 }
0780
0781
0782 if (wptr == NULL)
0783 {
0784 ++db->incomp_count;
0785 db->incomp_bytes += isize;
0786 olen = 0;
0787 }
0788 else
0789 {
0790 ++db->comp_count;
0791 db->comp_bytes += olen;
0792 }
0793
0794
0795 return olen;
0796 #undef OUTPUT
0797 #undef PUTBYTE
0798 }
0799
0800
0801
0802
0803
0804
0805 static void bsd_incomp (void *state, unsigned char *ibuf, int icnt)
0806 {
0807 (void) bsd_compress (state, ibuf, (char *) 0, icnt, 0);
0808 }
0809
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827 static int bsd_decompress (void *state, unsigned char *ibuf, int isize,
0828 unsigned char *obuf, int osize)
0829 {
0830 struct bsd_db *db;
0831 unsigned int max_ent;
0832 unsigned long accm;
0833 unsigned int bitno;
0834 unsigned int n_bits;
0835 unsigned int tgtbitno;
0836 struct bsd_dict *dictp;
0837 int explen;
0838 int seq;
0839 unsigned int incode;
0840 unsigned int oldcode;
0841 unsigned int finchar;
0842 unsigned char *p;
0843 unsigned char *wptr;
0844 int adrs;
0845 int ctrl;
0846 int ilen;
0847 int codelen;
0848 int extra;
0849
0850 db = (struct bsd_db *) state;
0851 max_ent = db->max_ent;
0852 accm = 0;
0853 bitno = 32;
0854 n_bits = db->n_bits;
0855 tgtbitno = 32 - n_bits;
0856
0857
0858
0859
0860
0861
0862 adrs = PPP_ADDRESS (ibuf);
0863 ctrl = PPP_CONTROL (ibuf);
0864
0865 seq = (ibuf[4] << 8) + ibuf[5];
0866
0867 ibuf += (PPP_HDRLEN + 2);
0868 ilen = isize - (PPP_HDRLEN + 2);
0869
0870
0871
0872
0873
0874
0875 if (seq != db->seqno)
0876 {
0877 if (db->debug)
0878 {
0879 printk("bsd_decomp%d: bad sequence # %d, expected %d\n",
0880 db->unit, seq, db->seqno - 1);
0881 }
0882 return DECOMP_ERROR;
0883 }
0884
0885 ++db->seqno;
0886 db->bytes_out += ilen;
0887
0888
0889
0890
0891
0892
0893 wptr = obuf;
0894 *wptr++ = adrs;
0895 *wptr++ = ctrl;
0896 *wptr++ = 0;
0897
0898 oldcode = CLEAR;
0899 explen = 3;
0900
0901
0902
0903
0904
0905
0906 for (;;)
0907 {
0908 if (ilen-- <= 0)
0909 {
0910 db->in_count += (explen - 3);
0911 break;
0912 }
0913
0914
0915
0916
0917
0918
0919
0920 bitno -= 8;
0921 accm |= *ibuf++ << bitno;
0922 if (tgtbitno < bitno)
0923 {
0924 continue;
0925 }
0926
0927 incode = accm >> tgtbitno;
0928 accm <<= n_bits;
0929 bitno += n_bits;
0930
0931
0932
0933
0934
0935 if (incode == CLEAR)
0936 {
0937 if (ilen > 0)
0938 {
0939 if (db->debug)
0940 {
0941 printk("bsd_decomp%d: bad CLEAR\n", db->unit);
0942 }
0943 return DECOMP_FATALERROR;
0944 }
0945
0946 bsd_clear(db);
0947 break;
0948 }
0949
0950 if ((incode > max_ent + 2) || (incode > db->maxmaxcode)
0951 || (incode > max_ent && oldcode == CLEAR))
0952 {
0953 if (db->debug)
0954 {
0955 printk("bsd_decomp%d: bad code 0x%x oldcode=0x%x ",
0956 db->unit, incode, oldcode);
0957 printk("max_ent=0x%x explen=%d seqno=%d\n",
0958 max_ent, explen, db->seqno);
0959 }
0960 return DECOMP_FATALERROR;
0961 }
0962
0963
0964 if (incode > max_ent)
0965 {
0966 finchar = oldcode;
0967 extra = 1;
0968 }
0969 else
0970 {
0971 finchar = incode;
0972 extra = 0;
0973 }
0974
0975 codelen = *(lens_ptr (db, finchar));
0976 explen += codelen + extra;
0977 if (explen > osize)
0978 {
0979 if (db->debug)
0980 {
0981 printk("bsd_decomp%d: ran out of mru\n", db->unit);
0982 #ifdef DEBUG
0983 printk(" len=%d, finchar=0x%x, codelen=%d, explen=%d\n",
0984 ilen, finchar, codelen, explen);
0985 #endif
0986 }
0987 return DECOMP_FATALERROR;
0988 }
0989
0990
0991
0992
0993
0994 wptr += codelen;
0995 p = wptr;
0996 while (finchar > LAST)
0997 {
0998 struct bsd_dict *dictp2 = dict_ptr (db, finchar);
0999
1000 dictp = dict_ptr (db, dictp2->cptr);
1001 #ifdef DEBUG
1002 if (--codelen <= 0 || dictp->codem1 != finchar-1)
1003 {
1004 if (codelen <= 0)
1005 {
1006 printk("bsd_decomp%d: fell off end of chain ", db->unit);
1007 printk("0x%x at 0x%x by 0x%x, max_ent=0x%x\n",
1008 incode, finchar, dictp2->cptr, max_ent);
1009 }
1010 else
1011 {
1012 if (dictp->codem1 != finchar-1)
1013 {
1014 printk("bsd_decomp%d: bad code chain 0x%x "
1015 "finchar=0x%x ",
1016 db->unit, incode, finchar);
1017
1018 printk("oldcode=0x%x cptr=0x%x codem1=0x%x\n",
1019 oldcode, dictp2->cptr, dictp->codem1);
1020 }
1021 }
1022 return DECOMP_FATALERROR;
1023 }
1024 #endif
1025 *--p = dictp->f.hs.suffix;
1026 finchar = dictp->f.hs.prefix;
1027 }
1028 *--p = finchar;
1029
1030 #ifdef DEBUG
1031 if (--codelen != 0)
1032 {
1033 printk("bsd_decomp%d: short by %d after code 0x%x, max_ent=0x%x\n",
1034 db->unit, codelen, incode, max_ent);
1035 }
1036 #endif
1037
1038 if (extra)
1039 {
1040 *wptr++ = finchar;
1041 }
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051 if (oldcode != CLEAR && max_ent < db->maxmaxcode)
1052 {
1053 struct bsd_dict *dictp2, *dictp3;
1054 unsigned short *lens1, *lens2;
1055 unsigned long fcode;
1056 int hval, disp, indx;
1057
1058 fcode = BSD_KEY(oldcode,finchar);
1059 hval = BSD_HASH(oldcode,finchar,db->hshift);
1060 dictp = dict_ptr (db, hval);
1061
1062
1063 if (dictp->codem1 < max_ent)
1064 {
1065 disp = (hval == 0) ? 1 : hval;
1066 do
1067 {
1068 hval += disp;
1069 if (hval >= db->hsize)
1070 {
1071 hval -= db->hsize;
1072 }
1073 dictp = dict_ptr (db, hval);
1074 }
1075 while (dictp->codem1 < max_ent);
1076 }
1077
1078
1079
1080
1081
1082
1083 dictp2 = dict_ptr (db, max_ent + 1);
1084 indx = dictp2->cptr;
1085 dictp3 = dict_ptr (db, indx);
1086
1087 if (dictp3->codem1 == max_ent)
1088 {
1089 dictp3->codem1 = BADCODEM1;
1090 }
1091
1092 dictp2->cptr = hval;
1093 dictp->codem1 = max_ent;
1094 dictp->f.fcode = fcode;
1095 db->max_ent = ++max_ent;
1096
1097
1098 lens1 = lens_ptr (db, max_ent);
1099 lens2 = lens_ptr (db, oldcode);
1100 *lens1 = *lens2 + 1;
1101
1102
1103 if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode)
1104 {
1105 db->n_bits = ++n_bits;
1106 tgtbitno = 32-n_bits;
1107 }
1108 }
1109 oldcode = incode;
1110 }
1111
1112 ++db->comp_count;
1113 ++db->uncomp_count;
1114 db->comp_bytes += isize - BSD_OVHD - PPP_HDRLEN;
1115 db->uncomp_bytes += explen;
1116
1117 if (bsd_check(db))
1118 {
1119 if (db->debug)
1120 {
1121 printk("bsd_decomp%d: peer should have cleared dictionary on %d\n",
1122 db->unit, db->seqno - 1);
1123 }
1124 }
1125 return explen;
1126 }
1127
1128
1129
1130
1131
1132 static struct compressor ppp_bsd_compress = {
1133 .compress_proto = CI_BSD_COMPRESS,
1134 .comp_alloc = bsd_comp_alloc,
1135 .comp_free = bsd_free,
1136 .comp_init = bsd_comp_init,
1137 .comp_reset = bsd_reset,
1138 .compress = bsd_compress,
1139 .comp_stat = bsd_comp_stats,
1140 .decomp_alloc = bsd_decomp_alloc,
1141 .decomp_free = bsd_free,
1142 .decomp_init = bsd_decomp_init,
1143 .decomp_reset = bsd_reset,
1144 .decompress = bsd_decompress,
1145 .incomp = bsd_incomp,
1146 .decomp_stat = bsd_comp_stats,
1147 .owner = THIS_MODULE
1148 };
1149
1150
1151
1152
1153
1154 static int __init bsdcomp_init(void)
1155 {
1156 int answer = ppp_register_compressor(&ppp_bsd_compress);
1157 if (answer == 0)
1158 printk(KERN_INFO "PPP BSD Compression module registered\n");
1159 return answer;
1160 }
1161
1162 static void __exit bsdcomp_cleanup(void)
1163 {
1164 ppp_unregister_compressor(&ppp_bsd_compress);
1165 }
1166
1167 module_init(bsdcomp_init);
1168 module_exit(bsdcomp_cleanup);
1169 MODULE_LICENSE("Dual BSD/GPL");
1170 MODULE_ALIAS("ppp-compress-" __stringify(CI_BSD_COMPRESS));