isdn_bsdcomp.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:24k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * BSD compression module
  3.  *
  4.  * Patched version for ISDN syncPPP written 1997/1998 by Michael Hipp
  5.  * The whole module is now SKB based.
  6.  *
  7.  */
  8. /*
  9.  * Update: The Berkeley copyright was changed, and the change 
  10.  * is retroactive to all "true" BSD software (ie everything
  11.  * from UCB as opposed to other peoples code that just carried
  12.  * the same license). The new copyright doesn't clash with the
  13.  * GPL, so the module-only restriction has been removed..
  14.  */
  15. /*
  16.  * Original copyright notice:
  17.  *
  18.  * Copyright (c) 1985, 1986 The Regents of the University of California.
  19.  * All rights reserved.
  20.  *
  21.  * This code is derived from software contributed to Berkeley by
  22.  * James A. Woods, derived from original work by Spencer Thomas
  23.  * and Joseph Orost.
  24.  *
  25.  * Redistribution and use in source and binary forms, with or without
  26.  * modification, are permitted provided that the following conditions
  27.  * are met:
  28.  * 1. Redistributions of source code must retain the above copyright
  29.  *    notice, this list of conditions and the following disclaimer.
  30.  * 2. Redistributions in binary form must reproduce the above copyright
  31.  *    notice, this list of conditions and the following disclaimer in the
  32.  *    documentation and/or other materials provided with the distribution.
  33.  * 3. All advertising materials mentioning features or use of this software
  34.  *    must display the following acknowledgement:
  35.  * This product includes software developed by the University of
  36.  * California, Berkeley and its contributors.
  37.  * 4. Neither the name of the University nor the names of its contributors
  38.  *    may be used to endorse or promote products derived from this software
  39.  *    without specific prior written permission.
  40.  *
  41.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  42.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  45.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51.  * SUCH DAMAGE.
  52.  */
  53. #include <linux/module.h>
  54. #include <linux/init.h>
  55. #include <linux/kernel.h>
  56. #include <linux/sched.h>
  57. #include <linux/types.h>
  58. #include <linux/fcntl.h>
  59. #include <linux/interrupt.h>
  60. #include <linux/ptrace.h>
  61. #include <linux/ioport.h>
  62. #include <linux/in.h>
  63. #include <linux/slab.h>
  64. #include <linux/tty.h>
  65. #include <linux/errno.h>
  66. #include <linux/string.h> /* used in new tty drivers */
  67. #include <linux/signal.h> /* used in new tty drivers */
  68. #include <asm/system.h>
  69. #include <asm/bitops.h>
  70. #include <asm/segment.h>
  71. #include <asm/byteorder.h>
  72. #include <asm/types.h>
  73. #include <linux/if.h>
  74. #include <linux/if_ether.h>
  75. #include <linux/netdevice.h>
  76. #include <linux/skbuff.h>
  77. #include <linux/inet.h>
  78. #include <linux/ioctl.h>
  79. #include <linux/vmalloc.h>
  80. #include <linux/ppp_defs.h>
  81. #include <linux/isdn.h>
  82. #include <linux/isdn_ppp.h>
  83. #include <linux/ip.h>
  84. #include <linux/tcp.h>
  85. #include <linux/if_arp.h>
  86. #include <linux/ppp-comp.h>
  87. #include "isdn_ppp.h"
  88. MODULE_DESCRIPTION("ISDN4Linux: BSD Compression for PPP over ISDN");
  89. MODULE_LICENSE("Dual BSD/GPL");
  90. #define BSD_VERSION(x) ((x) >> 5)
  91. #define BSD_NBITS(x) ((x) & 0x1F)
  92. #define BSD_CURRENT_VERSION 1
  93. #define DEBUG 1
  94. /*
  95.  * A dictionary for doing BSD compress.
  96.  */
  97. struct bsd_dict {
  98. u32 fcode;
  99. u16 codem1; /* output of hash table -1 */
  100. u16 cptr; /* map code to hash table entry */
  101. };
  102. struct bsd_db {
  103. int            totlen; /* length of this structure */
  104. unsigned int   hsize; /* size of the hash table */
  105. unsigned char  hshift; /* used in hash function */
  106. unsigned char  n_bits; /* current bits/code */
  107. unsigned char  maxbits; /* maximum bits/code */
  108. unsigned char  debug; /* non-zero if debug desired */
  109. unsigned char  unit; /* ppp unit number */
  110. u16 seqno;           /* sequence # of next packet */
  111. unsigned int   mru; /* size of receive (decompress) bufr */
  112. unsigned int   maxmaxcode; /* largest valid code */
  113. unsigned int   max_ent; /* largest code in use */
  114. unsigned int   in_count; /* uncompressed bytes, aged */
  115. unsigned int   bytes_out; /* compressed bytes, aged */
  116. unsigned int   ratio; /* recent compression ratio */
  117. unsigned int   checkpoint; /* when to next check the ratio */
  118. unsigned int   clear_count; /* times dictionary cleared */
  119. unsigned int   incomp_count; /* incompressible packets */
  120. unsigned int   incomp_bytes; /* incompressible bytes */
  121. unsigned int   uncomp_count; /* uncompressed packets */
  122. unsigned int   uncomp_bytes; /* uncompressed bytes */
  123. unsigned int   comp_count; /* compressed packets */
  124. unsigned int   comp_bytes; /* compressed bytes */
  125. unsigned short  *lens; /* array of lengths of codes */
  126. struct bsd_dict *dict; /* dictionary */
  127. int xmit;
  128. };
  129. #define BSD_OVHD 2 /* BSD compress overhead/packet */
  130. #define MIN_BSD_BITS 9
  131. #define BSD_INIT_BITS MIN_BSD_BITS
  132. #define MAX_BSD_BITS 15
  133. /*
  134.  * the next two codes should not be changed lightly, as they must not
  135.  * lie within the contiguous general code space.
  136.  */
  137. #define CLEAR 256 /* table clear output code */
  138. #define FIRST 257 /* first free entry */
  139. #define LAST 255
  140. #define MAXCODE(b) ((1 << (b)) - 1)
  141. #define BADCODEM1 MAXCODE(MAX_BSD_BITS);
  142. #define BSD_HASH(prefix,suffix,hshift) ((((unsigned long)(suffix))<<(hshift)) 
  143.  ^ (unsigned long)(prefix))
  144. #define BSD_KEY(prefix,suffix) ((((unsigned long)(suffix)) << 16) 
  145.  + (unsigned long)(prefix))
  146. #define CHECK_GAP 10000 /* Ratio check interval */
  147. #define RATIO_SCALE_LOG 8
  148. #define RATIO_SCALE (1<<RATIO_SCALE_LOG)
  149. #define RATIO_MAX (0x7fffffff>>RATIO_SCALE_LOG)
  150. /*
  151.  * clear the dictionary
  152.  */
  153. static void bsd_clear(struct bsd_db *db)
  154. {
  155. db->clear_count++;
  156. db->max_ent      = FIRST-1;
  157. db->n_bits       = BSD_INIT_BITS;
  158. db->bytes_out    = 0;
  159. db->in_count     = 0;
  160. db->incomp_count = 0;
  161. db->ratio      = 0;
  162. db->checkpoint   = CHECK_GAP;
  163. }
  164. /*
  165.  * If the dictionary is full, then see if it is time to reset it.
  166.  *
  167.  * Compute the compression ratio using fixed-point arithmetic
  168.  * with 8 fractional bits.
  169.  *
  170.  * Since we have an infinite stream instead of a single file,
  171.  * watch only the local compression ratio.
  172.  *
  173.  * Since both peers must reset the dictionary at the same time even in
  174.  * the absence of CLEAR codes (while packets are incompressible), they
  175.  * must compute the same ratio.
  176.  */
  177. static int bsd_check (struct bsd_db *db) /* 1=output CLEAR */
  178. {
  179.     unsigned int new_ratio;
  180.     if (db->in_count >= db->checkpoint)
  181.       {
  182. /* age the ratio by limiting the size of the counts */
  183. if (db->in_count >= RATIO_MAX || db->bytes_out >= RATIO_MAX)
  184.   {
  185.     db->in_count  -= (db->in_count  >> 2);
  186.     db->bytes_out -= (db->bytes_out >> 2);
  187.   }
  188. db->checkpoint = db->in_count + CHECK_GAP;
  189. if (db->max_ent >= db->maxmaxcode)
  190.   {
  191.     /* Reset the dictionary only if the ratio is worse,
  192.      * or if it looks as if it has been poisoned
  193.      * by incompressible data.
  194.      *
  195.      * This does not overflow, because
  196.      * db->in_count <= RATIO_MAX.
  197.      */
  198.     new_ratio = db->in_count << RATIO_SCALE_LOG;
  199.     if (db->bytes_out != 0)
  200.       {
  201. new_ratio /= db->bytes_out;
  202.       }
  203.     
  204.     if (new_ratio < db->ratio || new_ratio < 1 * RATIO_SCALE)
  205.       {
  206. bsd_clear (db);
  207. return 1;
  208.       }
  209.     db->ratio = new_ratio;
  210.   }
  211.       }
  212.     return 0;
  213. }
  214. /*
  215.  * Return statistics.
  216.  */
  217. static void bsd_stats (void *state, struct compstat *stats)
  218. {
  219. struct bsd_db *db = (struct bsd_db *) state;
  220.     
  221. stats->unc_bytes    = db->uncomp_bytes;
  222. stats->unc_packets  = db->uncomp_count;
  223. stats->comp_bytes   = db->comp_bytes;
  224. stats->comp_packets = db->comp_count;
  225. stats->inc_bytes    = db->incomp_bytes;
  226. stats->inc_packets  = db->incomp_count;
  227. stats->in_count     = db->in_count;
  228. stats->bytes_out    = db->bytes_out;
  229. }
  230. /*
  231.  * Reset state, as on a CCP ResetReq.
  232.  */
  233. static void bsd_reset (void *state,unsigned char code, unsigned char id,
  234. unsigned char *data, unsigned len,
  235. struct isdn_ppp_resetparams *rsparm)
  236. {
  237. struct bsd_db *db = (struct bsd_db *) state;
  238. bsd_clear(db);
  239. db->seqno       = 0;
  240. db->clear_count = 0;
  241. }
  242. /*
  243.  * Release the compression structure
  244.  */
  245. static void bsd_free (void *state)
  246. {
  247. struct bsd_db *db = (struct bsd_db *) state;
  248. if (db) {
  249. /*
  250.  * Release the dictionary
  251.  */
  252. if (db->dict) {
  253. vfree (db->dict);
  254. db->dict = NULL;
  255. }
  256. /*
  257.  * Release the string buffer
  258.  */
  259. if (db->lens) {
  260. vfree (db->lens);
  261. db->lens = NULL;
  262. }
  263. /*
  264.  * Finally release the structure itself.
  265.  */
  266. kfree (db);
  267. MOD_DEC_USE_COUNT;
  268. }
  269. }
  270. /*
  271.  * Allocate space for a (de) compressor.
  272.  */
  273. static void *bsd_alloc (struct isdn_ppp_comp_data *data)
  274. {
  275. int bits;
  276. unsigned int hsize, hshift, maxmaxcode;
  277. struct bsd_db *db;
  278. int decomp;
  279. static unsigned int htab[][2] = {
  280. { 5003 , 4 } , { 5003 , 4 } , { 5003 , 4 } , { 5003 , 4 } , 
  281. { 9001 , 5 } , { 18013 , 6 } , { 35023 , 7 } , { 69001 , 8 } 
  282. };
  283. if (data->optlen != 1 || data->num != CI_BSD_COMPRESS
  284. || BSD_VERSION(data->options[0]) != BSD_CURRENT_VERSION)
  285. return NULL;
  286. bits = BSD_NBITS(data->options[0]);
  287. if(bits < 9 || bits > 15)
  288. return NULL;
  289. hsize = htab[bits-9][0];
  290. hshift = htab[bits-9][1];
  291. /*
  292.  * Allocate the main control structure for this instance.
  293.  */
  294. maxmaxcode = MAXCODE(bits);
  295. db = (struct bsd_db *) kmalloc (sizeof (struct bsd_db),GFP_KERNEL);
  296. if (!db)
  297. return NULL;
  298. memset (db, 0, sizeof(struct bsd_db));
  299. db->xmit = data->flags & IPPP_COMP_FLAG_XMIT;
  300. decomp = db->xmit ? 0 : 1;
  301. /*
  302.  * Allocate space for the dictionary. This may be more than one page in
  303.  * length.
  304.  */
  305. db->dict = (struct bsd_dict *) vmalloc (hsize * sizeof (struct bsd_dict));
  306. if (!db->dict) {
  307. bsd_free (db);
  308. return NULL;
  309. }
  310. MOD_INC_USE_COUNT;
  311. /*
  312.  * If this is the compression buffer then there is no length data.
  313.  * For decompression, the length information is needed as well.
  314.  */
  315. if (!decomp)
  316. db->lens = NULL;
  317. else {
  318. db->lens = (unsigned short *) vmalloc ((maxmaxcode + 1) *
  319. sizeof (db->lens[0]));
  320. if (!db->lens) {
  321. bsd_free (db); /* calls MOD_DEC_USE_COUNT; */
  322. return (NULL);
  323. }
  324. }
  325. /*
  326.  * Initialize the data information for the compression code
  327.  */
  328. db->totlen     = sizeof (struct bsd_db) + (sizeof (struct bsd_dict) * hsize);
  329. db->hsize      = hsize;
  330. db->hshift     = hshift;
  331. db->maxmaxcode = maxmaxcode;
  332. db->maxbits    = bits;
  333. return (void *) db;
  334. }
  335. /*
  336.  * Initialize the database.
  337.  */
  338. static int bsd_init (void *state, struct isdn_ppp_comp_data *data, int unit, int debug)
  339. {
  340. struct bsd_db *db = state;
  341. int indx;
  342. int decomp;
  343. if(!state || !data) {
  344. printk(KERN_ERR "isdn_bsd_init: [%d] ERR, state %lx data %lxn",unit,(long)state,(long)data);
  345. return 0;
  346. }
  347. decomp = db->xmit ? 0 : 1;
  348.     
  349. if (data->optlen != 1 || data->num != CI_BSD_COMPRESS
  350. || (BSD_VERSION(data->options[0]) != BSD_CURRENT_VERSION)
  351. || (BSD_NBITS(data->options[0]) != db->maxbits)
  352. || (decomp && db->lens == NULL)) {
  353. printk(KERN_ERR "isdn_bsd: %d %d %d %d %lxn",data->optlen,data->num,data->options[0],decomp,(unsigned long)db->lens);
  354. return 0;
  355. }
  356. if (decomp)
  357. for(indx=LAST;indx>=0;indx--)
  358. db->lens[indx] = 1;
  359. indx = db->hsize;
  360. while (indx-- != 0) {
  361. db->dict[indx].codem1 = BADCODEM1;
  362. db->dict[indx].cptr   = 0;
  363. }
  364. db->unit = unit;
  365. db->mru  = 0;
  366. db->debug = 1;
  367.     
  368. bsd_reset(db,0,0,NULL,0,NULL);
  369.     
  370. return 1;
  371. }
  372. /*
  373.  * Obtain pointers to the various structures in the compression tables
  374.  */
  375. #define dict_ptrx(p,idx) &(p->dict[idx])
  376. #define lens_ptrx(p,idx) &(p->lens[idx])
  377. #ifdef DEBUG
  378. static unsigned short *lens_ptr(struct bsd_db *db, int idx)
  379. {
  380. if ((unsigned int) idx > (unsigned int) db->maxmaxcode) {
  381. printk (KERN_DEBUG "<9>ppp: lens_ptr(%d) > maxn", idx);
  382. idx = 0;
  383. }
  384. return lens_ptrx (db, idx);
  385. }
  386. static struct bsd_dict *dict_ptr(struct bsd_db *db, int idx)
  387. {
  388. if ((unsigned int) idx >= (unsigned int) db->hsize) {
  389. printk (KERN_DEBUG "<9>ppp: dict_ptr(%d) > maxn", idx);
  390. idx = 0;
  391. }
  392. return dict_ptrx (db, idx);
  393. }
  394. #else
  395. #define lens_ptr(db,idx) lens_ptrx(db,idx)
  396. #define dict_ptr(db,idx) dict_ptrx(db,idx)
  397. #endif
  398. /*
  399.  * compress a packet
  400.  */
  401. static int bsd_compress (void *state, struct sk_buff *skb_in, struct sk_buff *skb_out,int proto)
  402. {
  403. struct bsd_db *db;
  404. int hshift;
  405. unsigned int max_ent;
  406. unsigned int n_bits;
  407. unsigned int bitno;
  408. unsigned long accm;
  409. int ent;
  410. unsigned long fcode;
  411. struct bsd_dict *dictp;
  412. unsigned char c;
  413. int hval,disp,ilen,mxcode;
  414. unsigned char *rptr = skb_in->data;
  415. int isize = skb_in->len;
  416. #define OUTPUT(ent)
  417.   {
  418.     bitno -= n_bits;
  419.     accm |= ((ent) << bitno);
  420.     do {
  421.         if(skb_out && skb_tailroom(skb_out) > 0) 
  422.        *(skb_put(skb_out,1)) = (unsigned char) (accm>>24); 
  423. accm <<= 8;
  424. bitno += 8;
  425.     } while (bitno <= 24);
  426.   }
  427. /*
  428.  * If the protocol is not in the range we're interested in,
  429.  * just return without compressing the packet.  If it is,
  430.  * the protocol becomes the first byte to compress.
  431.  */
  432. printk(KERN_DEBUG "bsd_compress called with %xn",proto);
  433. ent = proto;
  434. if (proto < 0x21 || proto > 0xf9 || !(proto & 0x1) )
  435. return 0;
  436. db      = (struct bsd_db *) state;
  437. hshift  = db->hshift;
  438. max_ent = db->max_ent;
  439. n_bits  = db->n_bits;
  440. bitno   = 32;
  441. accm    = 0;
  442. mxcode  = MAXCODE (n_bits);
  443. /* This is the PPP header information */
  444. if(skb_out && skb_tailroom(skb_out) >= 2) {
  445. char *v = skb_put(skb_out,2);
  446. /* we only push our own data on the header,
  447.   AC,PC and protos is pushed by caller  */
  448. v[0] = db->seqno >> 8;
  449. v[1] = db->seqno;
  450. }
  451. ilen   = ++isize; /* This is off by one, but that is what is in draft! */
  452. while (--ilen > 0) {
  453. c     = *rptr++;
  454. fcode = BSD_KEY  (ent, c);
  455. hval  = BSD_HASH (ent, c, hshift);
  456. dictp = dict_ptr (db, hval);
  457. /* Validate and then check the entry. */
  458. if (dictp->codem1 >= max_ent)
  459. goto nomatch;
  460. if (dictp->fcode == fcode) {
  461. ent = dictp->codem1 + 1;
  462. continue; /* found (prefix,suffix) */
  463. }
  464. /* continue probing until a match or invalid entry */
  465. disp = (hval == 0) ? 1 : hval;
  466. do {
  467. hval += disp;
  468. if (hval >= db->hsize)
  469. hval -= db->hsize;
  470. dictp = dict_ptr (db, hval);
  471. if (dictp->codem1 >= max_ent)
  472. goto nomatch;
  473. } while (dictp->fcode != fcode);
  474. ent = dictp->codem1 + 1; /* finally found (prefix,suffix) */
  475. continue;
  476. nomatch:
  477. OUTPUT(ent); /* output the prefix */
  478. /* code -> hashtable */
  479. if (max_ent < db->maxmaxcode) {
  480. struct bsd_dict *dictp2;
  481. struct bsd_dict *dictp3;
  482. int indx;
  483. /* expand code size if needed */
  484. if (max_ent >= mxcode) {
  485. db->n_bits = ++n_bits;
  486. mxcode = MAXCODE (n_bits);
  487. }
  488.     
  489. /* 
  490.  * Invalidate old hash table entry using
  491.  * this code, and then take it over.
  492.  */
  493. dictp2 = dict_ptr (db, max_ent + 1);
  494. indx   = dictp2->cptr;
  495. dictp3 = dict_ptr (db, indx);
  496. if (dictp3->codem1 == max_ent)
  497. dictp3->codem1 = BADCODEM1;
  498. dictp2->cptr   = hval;
  499. dictp->codem1  = max_ent;
  500. dictp->fcode = fcode;
  501. db->max_ent    = ++max_ent;
  502. if (db->lens) {
  503. unsigned short *len1 = lens_ptr (db, max_ent);
  504. unsigned short *len2 = lens_ptr (db, ent);
  505. *len1 = *len2 + 1;
  506. }
  507. }
  508. ent = c;
  509. }
  510.     
  511. OUTPUT(ent); /* output the last code */
  512. if(skb_out)
  513. db->bytes_out    += skb_out->len; /* Do not count bytes from here */
  514. db->uncomp_bytes += isize;
  515. db->in_count     += isize;
  516. ++db->uncomp_count;
  517. ++db->seqno;
  518. if (bitno < 32)
  519. ++db->bytes_out; /* must be set before calling bsd_check */
  520. /*
  521.  * Generate the clear command if needed
  522.  */
  523. if (bsd_check(db))
  524. OUTPUT (CLEAR);
  525. /*
  526.  * Pad dribble bits of last code with ones.
  527.  * Do not emit a completely useless byte of ones.
  528.  */
  529. if (bitno < 32 && skb_out && skb_tailroom(skb_out) > 0) 
  530. *(skb_put(skb_out,1)) = (unsigned char) ((accm | (0xff << (bitno-8))) >> 24);
  531.     
  532. /*
  533.  * Increase code size if we would have without the packet
  534.  * boundary because the decompressor will do so.
  535.  */
  536. if (max_ent >= mxcode && max_ent < db->maxmaxcode)
  537. db->n_bits++;
  538. /* If output length is too large then this is an incompressible frame. */
  539. if (!skb_out || (skb_out && skb_out->len >= skb_in->len) ) {
  540. ++db->incomp_count;
  541. db->incomp_bytes += isize;
  542. return 0;
  543. }
  544. /* Count the number of compressed frames */
  545. ++db->comp_count;
  546. db->comp_bytes += skb_out->len;
  547. return skb_out->len;
  548. #undef OUTPUT
  549. }
  550. /*
  551.  * Update the "BSD Compress" dictionary on the receiver for
  552.  * incompressible data by pretending to compress the incoming data.
  553.  */
  554. static void bsd_incomp (void *state, struct sk_buff *skb_in,int proto)
  555. {
  556. bsd_compress (state, skb_in, NULL, proto);
  557. }
  558. /*
  559.  * Decompress "BSD Compress".
  560.  */
  561. static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *skb_out,
  562.    struct isdn_ppp_resetparams *rsparm)
  563. {
  564. struct bsd_db *db;
  565. unsigned int max_ent;
  566. unsigned long accm;
  567. unsigned int bitno; /* 1st valid bit in accm */
  568. unsigned int n_bits;
  569. unsigned int tgtbitno; /* bitno when we have a code */
  570. struct bsd_dict *dictp;
  571. int seq;
  572. unsigned int incode;
  573. unsigned int oldcode;
  574. unsigned int finchar;
  575. unsigned char *p,*ibuf;
  576. int ilen;
  577. int codelen;
  578. int extra;
  579. db       = (struct bsd_db *) state;
  580. max_ent  = db->max_ent;
  581. accm     = 0;
  582. bitno    = 32; /* 1st valid bit in accm */
  583. n_bits   = db->n_bits;
  584. tgtbitno = 32 - n_bits; /* bitno when we have a code */
  585. printk(KERN_DEBUG "bsd_decompress calledn");
  586. if(!skb_in || !skb_out) {
  587. printk(KERN_ERR "bsd_decompress called with NULL parametern");
  588. return DECOMP_ERROR;
  589. }
  590.     
  591. /*
  592.  * Get the sequence number.
  593.  */
  594. if( (p = skb_pull(skb_in,2)) == NULL) {
  595. return DECOMP_ERROR;
  596. }
  597. p-=2;
  598. seq   = (p[0] << 8) + p[1];
  599. ilen  = skb_in->len;
  600. ibuf = skb_in->data;
  601. /*
  602.  * Check the sequence number and give up if it differs from
  603.  * the value we're expecting.
  604.  */
  605. if (seq != db->seqno) {
  606. if (db->debug) {
  607. printk(KERN_DEBUG "bsd_decomp%d: bad sequence # %d, expected %dn",
  608. db->unit, seq, db->seqno - 1);
  609. }
  610. return DECOMP_ERROR;
  611. }
  612. ++db->seqno;
  613. db->bytes_out += ilen;
  614. if(skb_tailroom(skb_out) > 0)
  615. *(skb_put(skb_out,1)) = 0;
  616. else
  617. return DECOMP_ERR_NOMEM;
  618.     
  619. oldcode = CLEAR;
  620. /*
  621.  * Keep the checkpoint correctly so that incompressible packets
  622.  * clear the dictionary at the proper times.
  623.  */
  624. for (;;) {
  625. if (ilen-- <= 0) {
  626. db->in_count += (skb_out->len - 1); /* don't count the header */
  627. break;
  628. }
  629. /*
  630.  * Accumulate bytes until we have a complete code.
  631.  * Then get the next code, relying on the 32-bit,
  632.  * unsigned accm to mask the result.
  633.  */
  634. bitno -= 8;
  635. accm  |= *ibuf++ << bitno;
  636. if (tgtbitno < bitno)
  637. continue;
  638. incode = accm >> tgtbitno;
  639. accm <<= n_bits;
  640. bitno += n_bits;
  641. /*
  642.  * The dictionary must only be cleared at the end of a packet.
  643.  */
  644. if (incode == CLEAR) {
  645. if (ilen > 0) {
  646. if (db->debug)
  647. printk(KERN_DEBUG "bsd_decomp%d: bad CLEARn", db->unit);
  648. return DECOMP_FATALERROR; /* probably a bug */
  649. }
  650. bsd_clear(db);
  651. break;
  652. }
  653. if ((incode > max_ent + 2) || (incode > db->maxmaxcode)
  654. || (incode > max_ent && oldcode == CLEAR)) {
  655. if (db->debug) {
  656. printk(KERN_DEBUG "bsd_decomp%d: bad code 0x%x oldcode=0x%x ",
  657. db->unit, incode, oldcode);
  658. printk(KERN_DEBUG "max_ent=0x%x skb->Len=%d seqno=%dn",
  659. max_ent, skb_out->len, db->seqno);
  660. }
  661. return DECOMP_FATALERROR; /* probably a bug */
  662. }
  663. /* Special case for KwKwK string. */
  664. if (incode > max_ent) {
  665. finchar = oldcode;
  666. extra   = 1;
  667. } else {
  668. finchar = incode;
  669. extra   = 0;
  670. }
  671. codelen = *(lens_ptr (db, finchar));
  672. if( skb_tailroom(skb_out) < codelen + extra) {
  673. if (db->debug) {
  674. printk(KERN_DEBUG "bsd_decomp%d: ran out of mrun", db->unit);
  675. #ifdef DEBUG
  676. printk(KERN_DEBUG "  len=%d, finchar=0x%x, codelen=%d,skblen=%dn",
  677. ilen, finchar, codelen, skb_out->len);
  678. #endif
  679. }
  680. return DECOMP_FATALERROR;
  681. }
  682. /*
  683.  * Decode this code and install it in the decompressed buffer.
  684.  */
  685. p     = skb_put(skb_out,codelen);
  686. p += codelen;
  687. while (finchar > LAST) {
  688. struct bsd_dict *dictp2 = dict_ptr (db, finchar);
  689.     
  690. dictp = dict_ptr (db, dictp2->cptr);
  691. #ifdef DEBUG
  692. if (--codelen <= 0 || dictp->codem1 != finchar-1) {
  693. if (codelen <= 0) {
  694. printk(KERN_ERR "bsd_decomp%d: fell off end of chain ", db->unit);
  695. printk(KERN_ERR "0x%x at 0x%x by 0x%x, max_ent=0x%xn", incode, finchar, dictp2->cptr, max_ent);
  696. } else {
  697. if (dictp->codem1 != finchar-1) {
  698. printk(KERN_ERR "bsd_decomp%d: bad code chain 0x%x finchar=0x%x ",db->unit, incode, finchar);
  699. printk(KERN_ERR "oldcode=0x%x cptr=0x%x codem1=0x%xn", oldcode, dictp2->cptr, dictp->codem1);
  700. }
  701. }
  702. return DECOMP_FATALERROR;
  703. }
  704. #endif
  705. {
  706. u32 fcode = dictp->fcode;
  707. *--p    = (fcode >> 16) & 0xff;
  708. finchar = fcode & 0xffff;
  709. }
  710. }
  711. *--p = finchar;
  712. #ifdef DEBUG
  713. if (--codelen != 0)
  714. printk(KERN_ERR "bsd_decomp%d: short by %d after code 0x%x, max_ent=0x%xn", db->unit, codelen, incode, max_ent);
  715. #endif
  716. if (extra) /* the KwKwK case again */
  717. *(skb_put(skb_out,1)) = finchar;
  718. /*
  719.  * If not first code in a packet, and
  720.  * if not out of code space, then allocate a new code.
  721.  *
  722.  * Keep the hash table correct so it can be used
  723.  * with uncompressed packets.
  724.  */
  725. if (oldcode != CLEAR && max_ent < db->maxmaxcode) {
  726. struct bsd_dict *dictp2, *dictp3;
  727. u16  *lens1,  *lens2;
  728. unsigned long fcode;
  729. int hval, disp, indx;
  730.     
  731. fcode = BSD_KEY(oldcode,finchar);
  732. hval  = BSD_HASH(oldcode,finchar,db->hshift);
  733. dictp = dict_ptr (db, hval);
  734.     
  735. /* look for a free hash table entry */
  736. if (dictp->codem1 < max_ent) {
  737. disp = (hval == 0) ? 1 : hval;
  738. do {
  739. hval += disp;
  740. if (hval >= db->hsize)
  741. hval -= db->hsize;
  742. dictp = dict_ptr (db, hval);
  743. } while (dictp->codem1 < max_ent);
  744. }
  745.     
  746. /*
  747.  * Invalidate previous hash table entry
  748.  * assigned this code, and then take it over
  749.  */
  750. dictp2 = dict_ptr (db, max_ent + 1);
  751. indx   = dictp2->cptr;
  752. dictp3 = dict_ptr (db, indx);
  753. if (dictp3->codem1 == max_ent)
  754. dictp3->codem1 = BADCODEM1;
  755. dictp2->cptr   = hval;
  756. dictp->codem1  = max_ent;
  757. dictp->fcode = fcode;
  758. db->max_ent    = ++max_ent;
  759. /* Update the length of this string. */
  760. lens1  = lens_ptr (db, max_ent);
  761. lens2  = lens_ptr (db, oldcode);
  762. *lens1 = *lens2 + 1;
  763.     
  764. /* Expand code size if needed. */
  765. if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) {
  766. db->n_bits = ++n_bits;
  767. tgtbitno   = 32-n_bits;
  768. }
  769. }
  770. oldcode = incode;
  771. }
  772. ++db->comp_count;
  773. ++db->uncomp_count;
  774. db->comp_bytes   += skb_in->len - BSD_OVHD;
  775. db->uncomp_bytes += skb_out->len;
  776. if (bsd_check(db)) {
  777. if (db->debug)
  778. printk(KERN_DEBUG "bsd_decomp%d: peer should have cleared dictionary on %dn",
  779. db->unit, db->seqno - 1);
  780. }
  781. return skb_out->len;
  782. }
  783. /*************************************************************
  784.  * Table of addresses for the BSD compression module
  785.  *************************************************************/
  786. static struct isdn_ppp_compressor ippp_bsd_compress = {
  787. NULL,NULL, /* prev,next: overwritten by isdn_ppp */
  788. CI_BSD_COMPRESS, /* compress_proto */
  789. bsd_alloc, /* alloc */
  790. bsd_free, /* free */
  791. bsd_init, /* init */
  792. bsd_reset, /* reset */
  793. bsd_compress, /* compress */
  794. bsd_decompress, /* decompress */
  795. bsd_incomp, /* incomp */
  796. bsd_stats /* comp_stat */
  797. };
  798. /*************************************************************
  799.  * Module support routines
  800.  *************************************************************/
  801. static int __init isdn_bsdcomp_init(void)
  802. {
  803. int answer = isdn_ppp_register_compressor (&ippp_bsd_compress);
  804. if (answer == 0)
  805. printk (KERN_INFO "PPP BSD Compression module registeredn");
  806. return answer;
  807. }
  808. static void __exit isdn_bsdcomp_exit(void)
  809. {
  810. isdn_ppp_unregister_compressor (&ippp_bsd_compress);
  811. }
  812. module_init(isdn_bsdcomp_init);
  813. module_exit(isdn_bsdcomp_exit);