root/drivers/net/bsd_comp.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bsd_clear
  2. bsd_check
  3. bsd_comp_stats
  4. bsd_reset
  5. bsd_free
  6. bsd_alloc
  7. bsd_comp_alloc
  8. bsd_decomp_alloc
  9. bsd_init
  10. bsd_comp_init
  11. bsd_decomp_init
  12. lens_ptr
  13. dict_ptr
  14. bsd_compress
  15. bsd_incomp
  16. bsd_decompress
  17. init_module
  18. cleanup_module

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

/* [previous][next][first][last][top][bottom][index][help] */