bsd-comp.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. /* Because this code is derived from the 4.3BSD compress source:
  2. *
  3. *
  4. * Copyright (c) 1985, 1986 The Regents of the University of California.
  5. * All rights reserved.
  6. *
  7. * This code is derived from software contributed to Berkeley by
  8. * James A. Woods, derived from original work by Spencer Thomas
  9. * and Joseph Orost.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. * 3. All advertising materials mentioning features or use of this software
  20. * must display the following acknowledgement:
  21. * This product includes software developed by the University of
  22. * California, Berkeley and its contributors.
  23. * 4. Neither the name of the University nor the names of its contributors
  24. * may be used to endorse or promote products derived from this software
  25. * without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  28. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  31. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  32. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  33. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  34. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  35. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  36. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  37. * SUCH DAMAGE.
  38. */
  39. /*
  40. * $Id: bsd-comp.c,v 1.4 2004/01/17 05:47:55 carlsonj Exp $
  41. */
  42. #include <sys/types.h>
  43. #include <stdio.h>
  44. #include <stddef.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47. #include "ppp_defs.h"
  48. #include "ppp-comp.h"
  49. #if DO_BSD_COMPRESS
  50. /*
  51. * PPP "BSD compress" compression
  52. * The differences between this compression and the classic BSD LZW
  53. * source are obvious from the requirement that the classic code worked
  54. * with files while this handles arbitrarily long streams that
  55. * are broken into packets. They are:
  56. *
  57. * When the code size expands, a block of junk is not emitted by
  58. * the compressor and not expected by the decompressor.
  59. *
  60. * New codes are not necessarily assigned every time an old
  61. * code is output by the compressor. This is because a packet
  62. * end forces a code to be emitted, but does not imply that a
  63. * new sequence has been seen.
  64. *
  65. * The compression ratio is checked at the first end of a packet
  66. * after the appropriate gap. Besides simplifying and speeding
  67. * things up, this makes it more likely that the transmitter
  68. * and receiver will agree when the dictionary is cleared when
  69. * compression is not going well.
  70. */
  71. /*
  72. * A dictionary for doing BSD compress.
  73. */
  74. struct bsd_db {
  75. int totlen; /* length of this structure */
  76. u_int hsize; /* size of the hash table */
  77. u_char hshift; /* used in hash function */
  78. u_char n_bits; /* current bits/code */
  79. u_char maxbits;
  80. u_char debug;
  81. u_char unit;
  82. u_short seqno; /* sequence number of next packet */
  83. u_int hdrlen; /* header length to preallocate */
  84. u_int mru;
  85. u_int maxmaxcode; /* largest valid code */
  86. u_int max_ent; /* largest code in use */
  87. u_int in_count; /* uncompressed bytes, aged */
  88. u_int bytes_out; /* compressed bytes, aged */
  89. u_int ratio; /* recent compression ratio */
  90. u_int checkpoint; /* when to next check the ratio */
  91. u_int clear_count; /* times dictionary cleared */
  92. u_int incomp_count; /* incompressible packets */
  93. u_int incomp_bytes; /* incompressible bytes */
  94. u_int uncomp_count; /* uncompressed packets */
  95. u_int uncomp_bytes; /* uncompressed bytes */
  96. u_int comp_count; /* compressed packets */
  97. u_int comp_bytes; /* compressed bytes */
  98. u_short *lens; /* array of lengths of codes */
  99. struct bsd_dict {
  100. union { /* hash value */
  101. u_int32_t fcode;
  102. struct {
  103. #ifdef BSD_LITTLE_ENDIAN
  104. u_short prefix; /* preceding code */
  105. u_char suffix; /* last character of new code */
  106. u_char pad;
  107. #else
  108. u_char pad;
  109. u_char suffix; /* last character of new code */
  110. u_short prefix; /* preceding code */
  111. #endif
  112. } hs;
  113. } f;
  114. u_short codem1; /* output of hash table -1 */
  115. u_short cptr; /* map code to hash table entry */
  116. } dict[1];
  117. };
  118. #define BSD_OVHD 2 /* BSD compress overhead/packet */
  119. #define BSD_INIT_BITS BSD_MIN_BITS
  120. static void *bsd_decomp_alloc __P((u_char *options, int opt_len));
  121. static void bsd_free __P((void *state));
  122. static int bsd_decomp_init __P((void *state, u_char *options, int opt_len,
  123. int unit, int hdrlen, int mru, int debug));
  124. static void bsd_incomp __P((void *state, u_char *dmsg, int len));
  125. static int bsd_decompress __P((void *state, u_char *cmp, int inlen,
  126. u_char *dmp, int *outlen));
  127. static void bsd_reset __P((void *state));
  128. static void bsd_comp_stats __P((void *state, struct compstat *stats));
  129. /*
  130. * Exported procedures.
  131. */
  132. struct compressor ppp_bsd_compress = {
  133. CI_BSD_COMPRESS, /* compress_proto */
  134. bsd_decomp_alloc, /* decomp_alloc */
  135. bsd_free, /* decomp_free */
  136. bsd_decomp_init, /* decomp_init */
  137. bsd_reset, /* decomp_reset */
  138. bsd_decompress, /* decompress */
  139. bsd_incomp, /* incomp */
  140. bsd_comp_stats, /* decomp_stat */
  141. };
  142. /*
  143. * the next two codes should not be changed lightly, as they must not
  144. * lie within the contiguous general code space.
  145. */
  146. #define CLEAR 256 /* table clear output code */
  147. #define FIRST 257 /* first free entry */
  148. #define LAST 255
  149. #define MAXCODE(b) ((1 << (b)) - 1)
  150. #define BADCODEM1 MAXCODE(BSD_MAX_BITS)
  151. #define BSD_HASH(prefix,suffix,hshift) ((((u_int32_t)(suffix)) << (hshift)) \
  152. ^ (u_int32_t)(prefix))
  153. #define BSD_KEY(prefix,suffix) ((((u_int32_t)(suffix)) << 16) \
  154. + (u_int32_t)(prefix))
  155. #define CHECK_GAP 10000 /* Ratio check interval */
  156. #define RATIO_SCALE_LOG 8
  157. #define RATIO_SCALE (1<<RATIO_SCALE_LOG)
  158. #define RATIO_MAX (0x7fffffff>>RATIO_SCALE_LOG)
  159. /*
  160. * clear the dictionary
  161. */
  162. static void
  163. bsd_clear(db)
  164. struct bsd_db *db;
  165. {
  166. db->clear_count++;
  167. db->max_ent = FIRST-1;
  168. db->n_bits = BSD_INIT_BITS;
  169. db->ratio = 0;
  170. db->bytes_out = 0;
  171. db->in_count = 0;
  172. db->checkpoint = CHECK_GAP;
  173. }
  174. /*
  175. * If the dictionary is full, then see if it is time to reset it.
  176. *
  177. * Compute the compression ratio using fixed-point arithmetic
  178. * with 8 fractional bits.
  179. *
  180. * Since we have an infinite stream instead of a single file,
  181. * watch only the local compression ratio.
  182. *
  183. * Since both peers must reset the dictionary at the same time even in
  184. * the absence of CLEAR codes (while packets are incompressible), they
  185. * must compute the same ratio.
  186. */
  187. static int /* 1=output CLEAR */
  188. bsd_check(db)
  189. struct bsd_db *db;
  190. {
  191. u_int new_ratio;
  192. if (db->in_count >= db->checkpoint) {
  193. /* age the ratio by limiting the size of the counts */
  194. if (db->in_count >= RATIO_MAX
  195. || db->bytes_out >= RATIO_MAX) {
  196. db->in_count -= db->in_count/4;
  197. db->bytes_out -= db->bytes_out/4;
  198. }
  199. db->checkpoint = db->in_count + CHECK_GAP;
  200. if (db->max_ent >= db->maxmaxcode) {
  201. /* Reset the dictionary only if the ratio is worse,
  202. * or if it looks as if it has been poisoned
  203. * by incompressible data.
  204. *
  205. * This does not overflow, because
  206. * db->in_count <= RATIO_MAX.
  207. */
  208. new_ratio = db->in_count << RATIO_SCALE_LOG;
  209. if (db->bytes_out != 0)
  210. new_ratio /= db->bytes_out;
  211. if (new_ratio < db->ratio || new_ratio < 1 * RATIO_SCALE) {
  212. bsd_clear(db);
  213. return 1;
  214. }
  215. db->ratio = new_ratio;
  216. }
  217. }
  218. return 0;
  219. }
  220. /*
  221. * Return statistics.
  222. */
  223. static void
  224. bsd_comp_stats(state, stats)
  225. void *state;
  226. struct compstat *stats;
  227. {
  228. struct bsd_db *db = (struct bsd_db *) state;
  229. u_int out;
  230. stats->unc_bytes = db->uncomp_bytes;
  231. stats->unc_packets = db->uncomp_count;
  232. stats->comp_bytes = db->comp_bytes;
  233. stats->comp_packets = db->comp_count;
  234. stats->inc_bytes = db->incomp_bytes;
  235. stats->inc_packets = db->incomp_count;
  236. stats->ratio = db->in_count;
  237. out = db->bytes_out;
  238. if (stats->ratio <= 0x7fffff)
  239. stats->ratio <<= 8;
  240. else
  241. out >>= 8;
  242. if (out != 0)
  243. stats->ratio /= out;
  244. }
  245. /*
  246. * Reset state, as on a CCP ResetReq.
  247. */
  248. static void
  249. bsd_reset(state)
  250. void *state;
  251. {
  252. struct bsd_db *db = (struct bsd_db *) state;
  253. db->seqno = 0;
  254. bsd_clear(db);
  255. db->clear_count = 0;
  256. }
  257. /*
  258. * Allocate space for a (de) compressor.
  259. */
  260. static void *
  261. bsd_alloc(options, opt_len, decomp)
  262. u_char *options;
  263. int opt_len, decomp;
  264. {
  265. int bits;
  266. u_int newlen, hsize, hshift, maxmaxcode;
  267. struct bsd_db *db;
  268. if (opt_len != 3 || options[0] != CI_BSD_COMPRESS || options[1] != 3
  269. || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION)
  270. return NULL;
  271. bits = BSD_NBITS(options[2]);
  272. switch (bits) {
  273. case 9: /* needs 82152 for both directions */
  274. case 10: /* needs 84144 */
  275. case 11: /* needs 88240 */
  276. case 12: /* needs 96432 */
  277. hsize = 5003;
  278. hshift = 4;
  279. break;
  280. case 13: /* needs 176784 */
  281. hsize = 9001;
  282. hshift = 5;
  283. break;
  284. case 14: /* needs 353744 */
  285. hsize = 18013;
  286. hshift = 6;
  287. break;
  288. case 15: /* needs 691440 */
  289. hsize = 35023;
  290. hshift = 7;
  291. break;
  292. case 16: /* needs 1366160--far too much, */
  293. /* hsize = 69001; */ /* and 69001 is too big for cptr */
  294. /* hshift = 8; */ /* in struct bsd_db */
  295. /* break; */
  296. default:
  297. return NULL;
  298. }
  299. maxmaxcode = MAXCODE(bits);
  300. newlen = sizeof(*db) + (hsize-1) * (sizeof(db->dict[0]));
  301. db = (struct bsd_db *) malloc(newlen);
  302. if (!db)
  303. return NULL;
  304. memset(db, 0, sizeof(*db) - sizeof(db->dict));
  305. if (!decomp) {
  306. db->lens = NULL;
  307. } else {
  308. db->lens = (u_short *) malloc((maxmaxcode+1) * sizeof(db->lens[0]));
  309. if (!db->lens) {
  310. free(db);
  311. return NULL;
  312. }
  313. }
  314. db->totlen = newlen;
  315. db->hsize = hsize;
  316. db->hshift = hshift;
  317. db->maxmaxcode = maxmaxcode;
  318. db->maxbits = bits;
  319. return (void *) db;
  320. }
  321. static void
  322. bsd_free(state)
  323. void *state;
  324. {
  325. struct bsd_db *db = (struct bsd_db *) state;
  326. if (db->lens)
  327. free(db->lens);
  328. free(db);
  329. }
  330. static void *
  331. bsd_decomp_alloc(options, opt_len)
  332. u_char *options;
  333. int opt_len;
  334. {
  335. return bsd_alloc(options, opt_len, 1);
  336. }
  337. /*
  338. * Initialize the database.
  339. */
  340. static int
  341. bsd_init(db, options, opt_len, unit, hdrlen, mru, debug, decomp)
  342. struct bsd_db *db;
  343. u_char *options;
  344. int opt_len, unit, hdrlen, mru, debug, decomp;
  345. {
  346. int i;
  347. if (opt_len < CILEN_BSD_COMPRESS
  348. || options[0] != CI_BSD_COMPRESS || options[1] != CILEN_BSD_COMPRESS
  349. || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION
  350. || BSD_NBITS(options[2]) != db->maxbits
  351. || (decomp && db->lens == NULL))
  352. return 0;
  353. if (decomp) {
  354. i = LAST+1;
  355. while (i != 0)
  356. db->lens[--i] = 1;
  357. }
  358. i = db->hsize;
  359. while (i != 0) {
  360. db->dict[--i].codem1 = BADCODEM1;
  361. db->dict[i].cptr = 0;
  362. }
  363. db->unit = unit;
  364. db->hdrlen = hdrlen;
  365. db->mru = mru;
  366. if (debug)
  367. db->debug = 1;
  368. bsd_reset(db);
  369. return 1;
  370. }
  371. static int
  372. bsd_decomp_init(state, options, opt_len, unit, hdrlen, mru, debug)
  373. void *state;
  374. u_char *options;
  375. int opt_len, unit, hdrlen, mru, debug;
  376. {
  377. return bsd_init((struct bsd_db *) state, options, opt_len,
  378. unit, hdrlen, mru, debug, 1);
  379. }
  380. /*
  381. * Update the "BSD Compress" dictionary on the receiver for
  382. * incompressible data by pretending to compress the incoming data.
  383. */
  384. static void
  385. bsd_incomp(state, dmsg, mlen)
  386. void *state;
  387. u_char *dmsg;
  388. int mlen;
  389. {
  390. struct bsd_db *db = (struct bsd_db *) state;
  391. u_int hshift = db->hshift;
  392. u_int max_ent = db->max_ent;
  393. u_int n_bits = db->n_bits;
  394. struct bsd_dict *dictp;
  395. u_int32_t fcode;
  396. u_char c;
  397. long hval, disp;
  398. int slen, ilen;
  399. u_int bitno = 7;
  400. u_char *rptr;
  401. u_int ent;
  402. rptr = dmsg;
  403. ent = rptr[0]; /* get the protocol */
  404. if (ent == 0) {
  405. ++rptr;
  406. --mlen;
  407. ent = rptr[0];
  408. }
  409. if ((ent & 1) == 0 || ent < 0x21 || ent > 0xf9)
  410. return;
  411. db->seqno++;
  412. ilen = 1; /* count the protocol as 1 byte */
  413. ++rptr;
  414. slen = dmsg + mlen - rptr;
  415. ilen += slen;
  416. for (; slen > 0; --slen) {
  417. c = *rptr++;
  418. fcode = BSD_KEY(ent, c);
  419. hval = BSD_HASH(ent, c, hshift);
  420. dictp = &db->dict[hval];
  421. /* validate and then check the entry */
  422. if (dictp->codem1 >= max_ent)
  423. goto nomatch;
  424. if (dictp->f.fcode == fcode) {
  425. ent = dictp->codem1+1;
  426. continue; /* found (prefix,suffix) */
  427. }
  428. /* continue probing until a match or invalid entry */
  429. disp = (hval == 0) ? 1 : hval;
  430. do {
  431. hval += disp;
  432. if (hval >= db->hsize)
  433. hval -= db->hsize;
  434. dictp = &db->dict[hval];
  435. if (dictp->codem1 >= max_ent)
  436. goto nomatch;
  437. } while (dictp->f.fcode != fcode);
  438. ent = dictp->codem1+1;
  439. continue; /* finally found (prefix,suffix) */
  440. nomatch: /* output (count) the prefix */
  441. bitno += n_bits;
  442. /* code -> hashtable */
  443. if (max_ent < db->maxmaxcode) {
  444. struct bsd_dict *dictp2;
  445. /* expand code size if needed */
  446. if (max_ent >= MAXCODE(n_bits))
  447. db->n_bits = ++n_bits;
  448. /* Invalidate previous hash table entry
  449. * assigned this code, and then take it over.
  450. */
  451. dictp2 = &db->dict[max_ent+1];
  452. if (db->dict[dictp2->cptr].codem1 == max_ent)
  453. db->dict[dictp2->cptr].codem1 = BADCODEM1;
  454. dictp2->cptr = hval;
  455. dictp->codem1 = max_ent;
  456. dictp->f.fcode = fcode;
  457. db->max_ent = ++max_ent;
  458. db->lens[max_ent] = db->lens[ent]+1;
  459. }
  460. ent = c;
  461. }
  462. bitno += n_bits; /* output (count) the last code */
  463. db->bytes_out += bitno/8;
  464. db->in_count += ilen;
  465. (void)bsd_check(db);
  466. ++db->incomp_count;
  467. db->incomp_bytes += ilen;
  468. ++db->uncomp_count;
  469. db->uncomp_bytes += ilen;
  470. /* Increase code size if we would have without the packet
  471. * boundary and as the decompressor will.
  472. */
  473. if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode)
  474. db->n_bits++;
  475. }
  476. /*
  477. * Decompress "BSD Compress"
  478. *
  479. * Because of patent problems, we return DECOMP_ERROR for errors
  480. * found by inspecting the input data and for system problems, but
  481. * DECOMP_FATALERROR for any errors which could possibly be said to
  482. * be being detected "after" decompression. For DECOMP_ERROR,
  483. * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
  484. * infringing a patent of Motorola's if we do, so we take CCP down
  485. * instead.
  486. *
  487. * Given that the frame has the correct sequence number and a good FCS,
  488. * errors such as invalid codes in the input most likely indicate a
  489. * bug, so we return DECOMP_FATALERROR for them in order to turn off
  490. * compression, even though they are detected by inspecting the input.
  491. */
  492. static int
  493. bsd_decompress(state, cmsg, inlen, dmp, outlenp)
  494. void *state;
  495. u_char *cmsg, *dmp;
  496. int inlen, *outlenp;
  497. {
  498. struct bsd_db *db = (struct bsd_db *) state;
  499. u_int max_ent = db->max_ent;
  500. u_int32_t accm = 0;
  501. u_int bitno = 32; /* 1st valid bit in accm */
  502. u_int n_bits = db->n_bits;
  503. u_int tgtbitno = 32-n_bits; /* bitno when we have a code */
  504. struct bsd_dict *dictp;
  505. int explen, seq, len;
  506. u_int incode, oldcode, finchar;
  507. u_char *p, *rptr, *wptr;
  508. int ilen;
  509. int codelen, extra;
  510. rptr = cmsg;
  511. if (*rptr == 0)
  512. ++rptr;
  513. ++rptr; /* skip protocol (assumed 0xfd) */
  514. seq = (rptr[0] << 8) + rptr[1];
  515. rptr += BSD_OVHD;
  516. ilen = len = cmsg + inlen - rptr;
  517. /*
  518. * Check the sequence number and give up if it is not what we expect.
  519. */
  520. if (seq != db->seqno++) {
  521. if (db->debug)
  522. printf("bsd_decomp%d: bad sequence # %d, expected %d\n",
  523. db->unit, seq, db->seqno - 1);
  524. return DECOMP_ERROR;
  525. }
  526. wptr = dmp + db->hdrlen;
  527. oldcode = CLEAR;
  528. explen = 0;
  529. while (len > 0) {
  530. /*
  531. * Accumulate bytes until we have a complete code.
  532. * Then get the next code, relying on the 32-bit,
  533. * unsigned accm to mask the result.
  534. */
  535. bitno -= 8;
  536. accm |= *rptr++ << bitno;
  537. --len;
  538. if (tgtbitno < bitno)
  539. continue;
  540. incode = accm >> tgtbitno;
  541. accm <<= n_bits;
  542. bitno += n_bits;
  543. if (incode == CLEAR) {
  544. /*
  545. * The dictionary must only be cleared at
  546. * the end of a packet. But there could be an
  547. * empty message block at the end.
  548. */
  549. if (len > 0) {
  550. if (db->debug)
  551. printf("bsd_decomp%d: bad CLEAR\n", db->unit);
  552. return DECOMP_FATALERROR;
  553. }
  554. bsd_clear(db);
  555. explen = ilen = 0;
  556. break;
  557. }
  558. if (incode > max_ent + 2 || incode > db->maxmaxcode
  559. || (incode > max_ent && oldcode == CLEAR)) {
  560. if (db->debug) {
  561. printf("bsd_decomp%d: bad code 0x%x oldcode=0x%x ",
  562. db->unit, incode, oldcode);
  563. printf("max_ent=0x%x seqno=%d\n",
  564. max_ent, db->seqno);
  565. }
  566. return DECOMP_FATALERROR; /* probably a bug */
  567. }
  568. /* Special case for KwKwK string. */
  569. if (incode > max_ent) {
  570. finchar = oldcode;
  571. extra = 1;
  572. } else {
  573. finchar = incode;
  574. extra = 0;
  575. }
  576. codelen = db->lens[finchar];
  577. explen += codelen + extra;
  578. if (explen > db->mru + 1) {
  579. if (db->debug)
  580. printf("bsd_decomp%d: ran out of mru\n", db->unit);
  581. return DECOMP_FATALERROR;
  582. }
  583. /*
  584. * Decode this code and install it in the decompressed buffer.
  585. */
  586. p = (wptr += codelen);
  587. while (finchar > LAST) {
  588. dictp = &db->dict[db->dict[finchar].cptr];
  589. #ifdef DEBUG
  590. --codelen;
  591. if (codelen <= 0) {
  592. printf("bsd_decomp%d: fell off end of chain ", db->unit);
  593. printf("0x%x at 0x%x by 0x%x, max_ent=0x%x\n",
  594. incode, finchar, db->dict[finchar].cptr, max_ent);
  595. return DECOMP_FATALERROR;
  596. }
  597. if (dictp->codem1 != finchar-1) {
  598. printf("bsd_decomp%d: bad code chain 0x%x finchar=0x%x ",
  599. db->unit, incode, finchar);
  600. printf("oldcode=0x%x cptr=0x%x codem1=0x%x\n", oldcode,
  601. db->dict[finchar].cptr, dictp->codem1);
  602. return DECOMP_FATALERROR;
  603. }
  604. #endif
  605. *--p = dictp->f.hs.suffix;
  606. finchar = dictp->f.hs.prefix;
  607. }
  608. *--p = finchar;
  609. #ifdef DEBUG
  610. if (--codelen != 0)
  611. printf("bsd_decomp%d: short by %d after code 0x%x, max_ent=0x%x\n",
  612. db->unit, codelen, incode, max_ent);
  613. #endif
  614. if (extra) /* the KwKwK case again */
  615. *wptr++ = finchar;
  616. /*
  617. * If not first code in a packet, and
  618. * if not out of code space, then allocate a new code.
  619. *
  620. * Keep the hash table correct so it can be used
  621. * with uncompressed packets.
  622. */
  623. if (oldcode != CLEAR && max_ent < db->maxmaxcode) {
  624. struct bsd_dict *dictp2;
  625. u_int32_t fcode;
  626. int hval, disp;
  627. fcode = BSD_KEY(oldcode,finchar);
  628. hval = BSD_HASH(oldcode,finchar,db->hshift);
  629. dictp = &db->dict[hval];
  630. /* look for a free hash table entry */
  631. if (dictp->codem1 < max_ent) {
  632. disp = (hval == 0) ? 1 : hval;
  633. do {
  634. hval += disp;
  635. if (hval >= db->hsize)
  636. hval -= db->hsize;
  637. dictp = &db->dict[hval];
  638. } while (dictp->codem1 < max_ent);
  639. }
  640. /*
  641. * Invalidate previous hash table entry
  642. * assigned this code, and then take it over
  643. */
  644. dictp2 = &db->dict[max_ent+1];
  645. if (db->dict[dictp2->cptr].codem1 == max_ent) {
  646. db->dict[dictp2->cptr].codem1 = BADCODEM1;
  647. }
  648. dictp2->cptr = hval;
  649. dictp->codem1 = max_ent;
  650. dictp->f.fcode = fcode;
  651. db->max_ent = ++max_ent;
  652. db->lens[max_ent] = db->lens[oldcode]+1;
  653. /* Expand code size if needed. */
  654. if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) {
  655. db->n_bits = ++n_bits;
  656. tgtbitno = 32-n_bits;
  657. }
  658. }
  659. oldcode = incode;
  660. }
  661. *outlenp = wptr - (dmp + db->hdrlen);
  662. /*
  663. * Keep the checkpoint right so that incompressible packets
  664. * clear the dictionary at the right times.
  665. */
  666. db->bytes_out += ilen;
  667. db->in_count += explen;
  668. if (bsd_check(db) && db->debug) {
  669. printf("bsd_decomp%d: peer should have cleared dictionary\n",
  670. db->unit);
  671. }
  672. ++db->comp_count;
  673. db->comp_bytes += ilen + BSD_OVHD;
  674. ++db->uncomp_count;
  675. db->uncomp_bytes += explen;
  676. return DECOMP_OK;
  677. }
  678. #endif /* DO_BSD_COMPRESS */