bsd-comp.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116
  1. /* $OpenBSD: bsd-comp.c,v 1.11 2015/07/15 22:16:41 deraadt Exp $ */
  2. /* $NetBSD: bsd-comp.c,v 1.6 1996/10/13 02:10:58 christos Exp $ */
  3. /* Because this code is derived from the 4.3BSD compress source:
  4. *
  5. *
  6. * Copyright (c) 1985, 1986 The Regents of the University of California.
  7. * All rights reserved.
  8. *
  9. * This code is derived from software contributed to Berkeley by
  10. * James A. Woods, derived from original work by Spencer Thomas
  11. * and Joseph Orost.
  12. *
  13. * Redistribution and use in source and binary forms, with or without
  14. * modification, are permitted provided that the following conditions
  15. * are met:
  16. * 1. Redistributions of source code must retain the above copyright
  17. * notice, this list of conditions and the following disclaimer.
  18. * 2. Redistributions in binary form must reproduce the above copyright
  19. * notice, this list of conditions and the following disclaimer in the
  20. * documentation and/or other materials provided with the distribution.
  21. * 3. Neither the name of the University nor the names of its contributors
  22. * may be used to endorse or promote products derived from this software
  23. * without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35. * SUCH DAMAGE.
  36. */
  37. /*
  38. * This version is for use with mbufs on BSD-derived systems.
  39. */
  40. #include <sys/param.h>
  41. #include <sys/types.h>
  42. #include <sys/systm.h>
  43. #include <sys/mbuf.h>
  44. #include <sys/socket.h>
  45. #include <net/if.h>
  46. #include <net/if_var.h>
  47. #include <net/if_types.h>
  48. #include <net/ppp_defs.h>
  49. #include <net/if_ppp.h>
  50. #define PACKETPTR struct mbuf *
  51. #include <net/ppp-comp.h>
  52. #if DO_BSD_COMPRESS
  53. /*
  54. * PPP "BSD compress" compression
  55. * The differences between this compression and the classic BSD LZW
  56. * source are obvious from the requirement that the classic code worked
  57. * with files while this handles arbitrarily long streams that
  58. * are broken into packets. They are:
  59. *
  60. * When the code size expands, a block of junk is not emitted by
  61. * the compressor and not expected by the decompressor.
  62. *
  63. * New codes are not necessarily assigned every time an old
  64. * code is output by the compressor. This is because a packet
  65. * end forces a code to be emitted, but does not imply that a
  66. * new sequence has been seen.
  67. *
  68. * The compression ratio is checked at the first end of a packet
  69. * after the appropriate gap. Besides simplifying and speeding
  70. * things up, this makes it more likely that the transmitter
  71. * and receiver will agree when the dictionary is cleared when
  72. * compression is not going well.
  73. */
  74. /*
  75. * A dictionary for doing BSD compress.
  76. */
  77. struct bsd_db {
  78. int totlen; /* length of this structure */
  79. u_int hsize; /* size of the hash table */
  80. u_char hshift; /* used in hash function */
  81. u_char n_bits; /* current bits/code */
  82. u_char maxbits;
  83. u_char debug;
  84. u_char unit;
  85. u_int16_t seqno; /* sequence # of next packet */
  86. u_int hdrlen; /* header length to preallocate */
  87. u_int mru;
  88. u_int maxmaxcode; /* largest valid code */
  89. u_int max_ent; /* largest code in use */
  90. u_int in_count; /* uncompressed bytes, aged */
  91. u_int bytes_out; /* compressed bytes, aged */
  92. u_int ratio; /* recent compression ratio */
  93. u_int checkpoint; /* when to next check the ratio */
  94. u_int clear_count; /* times dictionary cleared */
  95. u_int incomp_count; /* incompressible packets */
  96. u_int incomp_bytes; /* incompressible bytes */
  97. u_int uncomp_count; /* uncompressed packets */
  98. u_int uncomp_bytes; /* uncompressed bytes */
  99. u_int comp_count; /* compressed packets */
  100. u_int comp_bytes; /* compressed bytes */
  101. u_int16_t *lens; /* array of lengths of codes */
  102. struct bsd_dict {
  103. union { /* hash value */
  104. u_int32_t fcode;
  105. struct {
  106. #if BYTE_ORDER == LITTLE_ENDIAN
  107. u_int16_t prefix; /* preceding code */
  108. u_char suffix; /* last character of new code */
  109. u_char pad;
  110. #else
  111. u_char pad;
  112. u_char suffix; /* last character of new code */
  113. u_int16_t prefix; /* preceding code */
  114. #endif
  115. } hs;
  116. } f;
  117. u_int16_t codem1; /* output of hash table -1 */
  118. u_int16_t cptr; /* map code to hash table entry */
  119. } dict[1];
  120. };
  121. #define BSD_OVHD 2 /* BSD compress overhead/packet */
  122. #define BSD_INIT_BITS BSD_MIN_BITS
  123. static void *bsd_comp_alloc(u_char *options, int opt_len);
  124. static void *bsd_decomp_alloc(u_char *options, int opt_len);
  125. static void bsd_free(void *state);
  126. static int bsd_comp_init(void *state, u_char *options, int opt_len,
  127. int unit, int hdrlen, int debug);
  128. static int bsd_decomp_init(void *state, u_char *options, int opt_len,
  129. int unit, int hdrlen, int mru, int debug);
  130. static int bsd_compress(void *state, struct mbuf **mret,
  131. struct mbuf *mp, int slen, int maxolen);
  132. static void bsd_incomp(void *state, struct mbuf *dmsg);
  133. static int bsd_decompress(void *state, struct mbuf *cmp,
  134. struct mbuf **dmpp);
  135. static void bsd_reset(void *state);
  136. static void bsd_comp_stats(void *state, struct compstat *stats);
  137. /*
  138. * Procedures exported to if_ppp.c.
  139. */
  140. struct compressor ppp_bsd_compress = {
  141. CI_BSD_COMPRESS, /* compress_proto */
  142. bsd_comp_alloc, /* comp_alloc */
  143. bsd_free, /* comp_free */
  144. bsd_comp_init, /* comp_init */
  145. bsd_reset, /* comp_reset */
  146. bsd_compress, /* compress */
  147. bsd_comp_stats, /* comp_stat */
  148. bsd_decomp_alloc, /* decomp_alloc */
  149. bsd_free, /* decomp_free */
  150. bsd_decomp_init, /* decomp_init */
  151. bsd_reset, /* decomp_reset */
  152. bsd_decompress, /* decompress */
  153. bsd_incomp, /* incomp */
  154. bsd_comp_stats, /* decomp_stat */
  155. };
  156. /*
  157. * the next two codes should not be changed lightly, as they must not
  158. * lie within the contiguous general code space.
  159. */
  160. #define CLEAR 256 /* table clear output code */
  161. #define FIRST 257 /* first free entry */
  162. #define LAST 255
  163. #define MAXCODE(b) ((1 << (b)) - 1)
  164. #define BADCODEM1 MAXCODE(BSD_MAX_BITS)
  165. #define BSD_HASH(prefix,suffix,hshift) ((((u_int32_t)(suffix)) << (hshift)) \
  166. ^ (u_int32_t)(prefix))
  167. #define BSD_KEY(prefix,suffix) ((((u_int32_t)(suffix)) << 16) \
  168. + (u_int32_t)(prefix))
  169. #define CHECK_GAP 10000 /* Ratio check interval */
  170. #define RATIO_SCALE_LOG 8
  171. #define RATIO_SCALE (1<<RATIO_SCALE_LOG)
  172. #define RATIO_MAX (0x7fffffff>>RATIO_SCALE_LOG)
  173. static void bsd_clear(struct bsd_db *);
  174. static int bsd_check(struct bsd_db *);
  175. static void *bsd_alloc(u_char *, int, int);
  176. static int bsd_init(struct bsd_db *, u_char *, int, int, int, int,
  177. int, int);
  178. /*
  179. * clear the dictionary
  180. */
  181. static void
  182. bsd_clear(db)
  183. struct bsd_db *db;
  184. {
  185. db->clear_count++;
  186. db->max_ent = FIRST-1;
  187. db->n_bits = BSD_INIT_BITS;
  188. db->ratio = 0;
  189. db->bytes_out = 0;
  190. db->in_count = 0;
  191. db->incomp_count = 0;
  192. db->checkpoint = CHECK_GAP;
  193. }
  194. /*
  195. * If the dictionary is full, then see if it is time to reset it.
  196. *
  197. * Compute the compression ratio using fixed-point arithmetic
  198. * with 8 fractional bits.
  199. *
  200. * Since we have an infinite stream instead of a single file,
  201. * watch only the local compression ratio.
  202. *
  203. * Since both peers must reset the dictionary at the same time even in
  204. * the absence of CLEAR codes (while packets are incompressible), they
  205. * must compute the same ratio.
  206. */
  207. static int /* 1=output CLEAR */
  208. bsd_check(db)
  209. struct bsd_db *db;
  210. {
  211. u_int new_ratio;
  212. if (db->in_count >= db->checkpoint) {
  213. /* age the ratio by limiting the size of the counts */
  214. if (db->in_count >= RATIO_MAX
  215. || db->bytes_out >= RATIO_MAX) {
  216. db->in_count -= db->in_count/4;
  217. db->bytes_out -= db->bytes_out/4;
  218. }
  219. db->checkpoint = db->in_count + CHECK_GAP;
  220. if (db->max_ent >= db->maxmaxcode) {
  221. /* Reset the dictionary only if the ratio is worse,
  222. * or if it looks as if it has been poisoned
  223. * by incompressible data.
  224. *
  225. * This does not overflow, because
  226. * db->in_count <= RATIO_MAX.
  227. */
  228. new_ratio = db->in_count << RATIO_SCALE_LOG;
  229. if (db->bytes_out != 0)
  230. new_ratio /= db->bytes_out;
  231. if (new_ratio < db->ratio || new_ratio < 1 * RATIO_SCALE) {
  232. bsd_clear(db);
  233. return 1;
  234. }
  235. db->ratio = new_ratio;
  236. }
  237. }
  238. return 0;
  239. }
  240. /*
  241. * Return statistics.
  242. */
  243. static void
  244. bsd_comp_stats(state, stats)
  245. void *state;
  246. struct compstat *stats;
  247. {
  248. struct bsd_db *db = (struct bsd_db *) state;
  249. u_int out;
  250. stats->unc_bytes = db->uncomp_bytes;
  251. stats->unc_packets = db->uncomp_count;
  252. stats->comp_bytes = db->comp_bytes;
  253. stats->comp_packets = db->comp_count;
  254. stats->inc_bytes = db->incomp_bytes;
  255. stats->inc_packets = db->incomp_count;
  256. stats->ratio = db->in_count;
  257. out = db->bytes_out;
  258. if (stats->ratio <= 0x7fffff)
  259. stats->ratio <<= 8;
  260. else
  261. out >>= 8;
  262. if (out != 0)
  263. stats->ratio /= out;
  264. }
  265. /*
  266. * Reset state, as on a CCP ResetReq.
  267. */
  268. static void
  269. bsd_reset(state)
  270. void *state;
  271. {
  272. struct bsd_db *db = (struct bsd_db *) state;
  273. db->seqno = 0;
  274. bsd_clear(db);
  275. db->clear_count = 0;
  276. }
  277. /*
  278. * Allocate space for a (de) compressor.
  279. */
  280. static void *
  281. bsd_alloc(options, opt_len, decomp)
  282. u_char *options;
  283. int opt_len, decomp;
  284. {
  285. int bits;
  286. u_int newlen, hsize, hshift, maxmaxcode;
  287. struct bsd_db *db;
  288. if (opt_len < CILEN_BSD_COMPRESS || options[0] != CI_BSD_COMPRESS
  289. || options[1] != CILEN_BSD_COMPRESS
  290. || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION)
  291. return NULL;
  292. bits = BSD_NBITS(options[2]);
  293. switch (bits) {
  294. case 9: /* needs 82152 for both directions */
  295. case 10: /* needs 84144 */
  296. case 11: /* needs 88240 */
  297. case 12: /* needs 96432 */
  298. hsize = 5003;
  299. hshift = 4;
  300. break;
  301. case 13: /* needs 176784 */
  302. hsize = 9001;
  303. hshift = 5;
  304. break;
  305. case 14: /* needs 353744 */
  306. hsize = 18013;
  307. hshift = 6;
  308. break;
  309. case 15: /* needs 691440 */
  310. hsize = 35023;
  311. hshift = 7;
  312. break;
  313. case 16: /* needs 1366160--far too much, */
  314. /* hsize = 69001; */ /* and 69001 is too big for cptr */
  315. /* hshift = 8; */ /* in struct bsd_db */
  316. /* break; */
  317. default:
  318. return NULL;
  319. }
  320. maxmaxcode = MAXCODE(bits);
  321. newlen = sizeof(*db) + (hsize-1) * (sizeof(db->dict[0]));
  322. db = malloc(newlen, M_DEVBUF, M_NOWAIT|M_ZERO);
  323. if (!db)
  324. return NULL;
  325. if (!decomp) {
  326. db->lens = NULL;
  327. } else {
  328. db->lens = mallocarray(maxmaxcode + 1, sizeof(db->lens[0]), M_DEVBUF,
  329. M_NOWAIT);
  330. if (!db->lens) {
  331. free(db, M_DEVBUF, 0);
  332. return NULL;
  333. }
  334. }
  335. db->totlen = newlen;
  336. db->hsize = hsize;
  337. db->hshift = hshift;
  338. db->maxmaxcode = maxmaxcode;
  339. db->maxbits = bits;
  340. return (void *) db;
  341. }
  342. static void
  343. bsd_free(state)
  344. void *state;
  345. {
  346. struct bsd_db *db = (struct bsd_db *) state;
  347. if (db->lens)
  348. free(db->lens, M_DEVBUF, 0);
  349. free(db, M_DEVBUF, 0);
  350. }
  351. static void *
  352. bsd_comp_alloc(options, opt_len)
  353. u_char *options;
  354. int opt_len;
  355. {
  356. return bsd_alloc(options, opt_len, 0);
  357. }
  358. static void *
  359. bsd_decomp_alloc(options, opt_len)
  360. u_char *options;
  361. int opt_len;
  362. {
  363. return bsd_alloc(options, opt_len, 1);
  364. }
  365. /*
  366. * Initialize the database.
  367. */
  368. static int
  369. bsd_init(db, options, opt_len, unit, hdrlen, mru, debug, decomp)
  370. struct bsd_db *db;
  371. u_char *options;
  372. int opt_len, unit, hdrlen, mru, debug, decomp;
  373. {
  374. int i;
  375. if (opt_len < CILEN_BSD_COMPRESS || options[0] != CI_BSD_COMPRESS
  376. || options[1] != CILEN_BSD_COMPRESS
  377. || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION
  378. || BSD_NBITS(options[2]) != db->maxbits
  379. || (decomp && db->lens == NULL))
  380. return 0;
  381. if (decomp) {
  382. i = LAST+1;
  383. while (i != 0)
  384. db->lens[--i] = 1;
  385. }
  386. i = db->hsize;
  387. while (i != 0) {
  388. db->dict[--i].codem1 = BADCODEM1;
  389. db->dict[i].cptr = 0;
  390. }
  391. db->unit = unit;
  392. db->hdrlen = hdrlen;
  393. db->mru = mru;
  394. #ifndef DEBUG
  395. if (debug)
  396. #endif
  397. db->debug = 1;
  398. bsd_reset(db);
  399. return 1;
  400. }
  401. static int
  402. bsd_comp_init(state, options, opt_len, unit, hdrlen, debug)
  403. void *state;
  404. u_char *options;
  405. int opt_len, unit, hdrlen, debug;
  406. {
  407. return bsd_init((struct bsd_db *) state, options, opt_len,
  408. unit, hdrlen, 0, debug, 0);
  409. }
  410. static int
  411. bsd_decomp_init(state, options, opt_len, unit, hdrlen, mru, debug)
  412. void *state;
  413. u_char *options;
  414. int opt_len, unit, hdrlen, mru, debug;
  415. {
  416. return bsd_init((struct bsd_db *) state, options, opt_len,
  417. unit, hdrlen, mru, debug, 1);
  418. }
  419. /*
  420. * compress a packet
  421. * One change from the BSD compress command is that when the
  422. * code size expands, we do not output a bunch of padding.
  423. */
  424. int /* new slen */
  425. bsd_compress(state, mret, mp, slen, maxolen)
  426. void *state;
  427. struct mbuf **mret; /* return compressed mbuf chain here */
  428. struct mbuf *mp; /* from here */
  429. int slen; /* uncompressed length */
  430. int maxolen; /* max compressed length */
  431. {
  432. struct bsd_db *db = (struct bsd_db *) state;
  433. int hshift = db->hshift;
  434. u_int max_ent = db->max_ent;
  435. u_int n_bits = db->n_bits;
  436. u_int bitno = 32;
  437. u_int32_t accm = 0, fcode;
  438. struct bsd_dict *dictp;
  439. u_char c;
  440. int hval, disp, ent, ilen;
  441. u_char *rptr, *wptr;
  442. u_char *cp_end;
  443. int olen;
  444. struct mbuf *m;
  445. #define PUTBYTE(v) { \
  446. ++olen; \
  447. if (wptr) { \
  448. *wptr++ = (v); \
  449. if (wptr >= cp_end) { \
  450. m->m_len = wptr - mtod(m, u_char *); \
  451. MGET(m->m_next, M_DONTWAIT, MT_DATA); \
  452. m = m->m_next; \
  453. if (m) { \
  454. m->m_len = 0; \
  455. if (maxolen - olen > MLEN) \
  456. MCLGET(m, M_DONTWAIT); \
  457. wptr = mtod(m, u_char *); \
  458. cp_end = wptr + M_TRAILINGSPACE(m); \
  459. } else \
  460. wptr = NULL; \
  461. } \
  462. } \
  463. }
  464. #define OUTPUT(ent) { \
  465. bitno -= n_bits; \
  466. accm |= ((ent) << bitno); \
  467. do { \
  468. PUTBYTE(accm >> 24); \
  469. accm <<= 8; \
  470. bitno += 8; \
  471. } while (bitno <= 24); \
  472. }
  473. /*
  474. * If the protocol is not in the range we're interested in,
  475. * just return without compressing the packet. If it is,
  476. * the protocol becomes the first byte to compress.
  477. */
  478. rptr = mtod(mp, u_char *);
  479. ent = PPP_PROTOCOL(rptr);
  480. if (ent < 0x21 || ent > 0xf9) {
  481. *mret = NULL;
  482. return slen;
  483. }
  484. /* Don't generate compressed packets which are larger than
  485. the uncompressed packet. */
  486. if (maxolen > slen)
  487. maxolen = slen;
  488. /* Allocate one mbuf to start with. */
  489. MGET(m, M_DONTWAIT, MT_DATA);
  490. *mret = m;
  491. if (m != NULL) {
  492. m->m_len = 0;
  493. if (maxolen + db->hdrlen > MLEN)
  494. MCLGET(m, M_DONTWAIT);
  495. m->m_data += db->hdrlen;
  496. wptr = mtod(m, u_char *);
  497. cp_end = wptr + M_TRAILINGSPACE(m);
  498. } else
  499. wptr = cp_end = NULL;
  500. /*
  501. * Copy the PPP header over, changing the protocol,
  502. * and install the 2-byte packet sequence number.
  503. */
  504. if (wptr) {
  505. *wptr++ = PPP_ADDRESS(rptr); /* assumes the ppp header is */
  506. *wptr++ = PPP_CONTROL(rptr); /* all in one mbuf */
  507. *wptr++ = 0; /* change the protocol */
  508. *wptr++ = PPP_COMP;
  509. *wptr++ = db->seqno >> 8;
  510. *wptr++ = db->seqno;
  511. }
  512. ++db->seqno;
  513. olen = 0;
  514. rptr += PPP_HDRLEN;
  515. slen = mp->m_len - PPP_HDRLEN;
  516. ilen = slen + 1;
  517. for (;;) {
  518. if (slen <= 0) {
  519. mp = mp->m_next;
  520. if (!mp)
  521. break;
  522. rptr = mtod(mp, u_char *);
  523. slen = mp->m_len;
  524. if (!slen)
  525. continue; /* handle 0-length buffers */
  526. ilen += slen;
  527. }
  528. slen--;
  529. c = *rptr++;
  530. fcode = BSD_KEY(ent, c);
  531. hval = BSD_HASH(ent, c, hshift);
  532. dictp = &db->dict[hval];
  533. /* Validate and then check the entry. */
  534. if (dictp->codem1 >= max_ent)
  535. goto nomatch;
  536. if (dictp->f.fcode == fcode) {
  537. ent = dictp->codem1+1;
  538. continue; /* found (prefix,suffix) */
  539. }
  540. /* continue probing until a match or invalid entry */
  541. disp = (hval == 0) ? 1 : hval;
  542. do {
  543. hval += disp;
  544. if (hval >= db->hsize)
  545. hval -= db->hsize;
  546. dictp = &db->dict[hval];
  547. if (dictp->codem1 >= max_ent)
  548. goto nomatch;
  549. } while (dictp->f.fcode != fcode);
  550. ent = dictp->codem1 + 1; /* finally found (prefix,suffix) */
  551. continue;
  552. nomatch:
  553. OUTPUT(ent); /* output the prefix */
  554. /* code -> hashtable */
  555. if (max_ent < db->maxmaxcode) {
  556. struct bsd_dict *dictp2;
  557. /* expand code size if needed */
  558. if (max_ent >= MAXCODE(n_bits))
  559. db->n_bits = ++n_bits;
  560. /* Invalidate old hash table entry using
  561. * this code, and then take it over.
  562. */
  563. dictp2 = &db->dict[max_ent+1];
  564. if (db->dict[dictp2->cptr].codem1 == max_ent)
  565. db->dict[dictp2->cptr].codem1 = BADCODEM1;
  566. dictp2->cptr = hval;
  567. dictp->codem1 = max_ent;
  568. dictp->f.fcode = fcode;
  569. db->max_ent = ++max_ent;
  570. }
  571. ent = c;
  572. }
  573. OUTPUT(ent); /* output the last code */
  574. db->bytes_out += olen;
  575. db->in_count += ilen;
  576. if (bitno < 32)
  577. ++db->bytes_out; /* count complete bytes */
  578. if (bsd_check(db))
  579. OUTPUT(CLEAR); /* do not count the CLEAR */
  580. /*
  581. * Pad dribble bits of last code with ones.
  582. * Do not emit a completely useless byte of ones.
  583. */
  584. if (bitno != 32)
  585. PUTBYTE((accm | (0xff << (bitno-8))) >> 24);
  586. if (m != NULL) {
  587. m->m_len = wptr - mtod(m, u_char *);
  588. m->m_next = NULL;
  589. }
  590. /*
  591. * Increase code size if we would have without the packet
  592. * boundary and as the decompressor will.
  593. */
  594. if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode)
  595. db->n_bits++;
  596. db->uncomp_bytes += ilen;
  597. ++db->uncomp_count;
  598. if (olen + PPP_HDRLEN + BSD_OVHD > maxolen) {
  599. /* throw away the compressed stuff if it is longer than uncompressed */
  600. m_freem(*mret);
  601. *mret = NULL;
  602. ++db->incomp_count;
  603. db->incomp_bytes += ilen;
  604. } else {
  605. ++db->comp_count;
  606. db->comp_bytes += olen + BSD_OVHD;
  607. }
  608. return olen + PPP_HDRLEN + BSD_OVHD;
  609. #undef OUTPUT
  610. #undef PUTBYTE
  611. }
  612. /*
  613. * Update the "BSD Compress" dictionary on the receiver for
  614. * incompressible data by pretending to compress the incoming data.
  615. */
  616. static void
  617. bsd_incomp(state, dmsg)
  618. void *state;
  619. struct mbuf *dmsg;
  620. {
  621. struct bsd_db *db = (struct bsd_db *) state;
  622. u_int hshift = db->hshift;
  623. u_int max_ent = db->max_ent;
  624. u_int n_bits = db->n_bits;
  625. struct bsd_dict *dictp;
  626. u_int32_t fcode;
  627. u_char c;
  628. u_int32_t hval, disp;
  629. int slen, ilen;
  630. u_int bitno = 7;
  631. u_char *rptr;
  632. u_int ent;
  633. /*
  634. * If the protocol is not in the range we're interested in,
  635. * just return without looking at the packet. If it is,
  636. * the protocol becomes the first byte to "compress".
  637. */
  638. rptr = mtod(dmsg, u_char *);
  639. ent = PPP_PROTOCOL(rptr);
  640. if (ent < 0x21 || ent > 0xf9)
  641. return;
  642. db->incomp_count++;
  643. db->seqno++;
  644. ilen = 1; /* count the protocol as 1 byte */
  645. rptr += PPP_HDRLEN;
  646. slen = dmsg->m_len - PPP_HDRLEN;
  647. for (;;) {
  648. if (slen <= 0) {
  649. dmsg = dmsg->m_next;
  650. if (!dmsg)
  651. break;
  652. rptr = mtod(dmsg, u_char *);
  653. slen = dmsg->m_len;
  654. continue;
  655. }
  656. ilen += slen;
  657. do {
  658. c = *rptr++;
  659. fcode = BSD_KEY(ent, c);
  660. hval = BSD_HASH(ent, c, hshift);
  661. dictp = &db->dict[hval];
  662. /* validate and then check the entry */
  663. if (dictp->codem1 >= max_ent)
  664. goto nomatch;
  665. if (dictp->f.fcode == fcode) {
  666. ent = dictp->codem1+1;
  667. continue; /* found (prefix,suffix) */
  668. }
  669. /* continue probing until a match or invalid entry */
  670. disp = (hval == 0) ? 1 : hval;
  671. do {
  672. hval += disp;
  673. if (hval >= db->hsize)
  674. hval -= db->hsize;
  675. dictp = &db->dict[hval];
  676. if (dictp->codem1 >= max_ent)
  677. goto nomatch;
  678. } while (dictp->f.fcode != fcode);
  679. ent = dictp->codem1+1;
  680. continue; /* finally found (prefix,suffix) */
  681. nomatch: /* output (count) the prefix */
  682. bitno += n_bits;
  683. /* code -> hashtable */
  684. if (max_ent < db->maxmaxcode) {
  685. struct bsd_dict *dictp2;
  686. /* expand code size if needed */
  687. if (max_ent >= MAXCODE(n_bits))
  688. db->n_bits = ++n_bits;
  689. /* Invalidate previous hash table entry
  690. * assigned this code, and then take it over.
  691. */
  692. dictp2 = &db->dict[max_ent+1];
  693. if (db->dict[dictp2->cptr].codem1 == max_ent)
  694. db->dict[dictp2->cptr].codem1 = BADCODEM1;
  695. dictp2->cptr = hval;
  696. dictp->codem1 = max_ent;
  697. dictp->f.fcode = fcode;
  698. db->max_ent = ++max_ent;
  699. db->lens[max_ent] = db->lens[ent]+1;
  700. }
  701. ent = c;
  702. } while (--slen != 0);
  703. }
  704. bitno += n_bits; /* output (count) the last code */
  705. db->bytes_out += bitno/8;
  706. db->in_count += ilen;
  707. (void)bsd_check(db);
  708. ++db->incomp_count;
  709. db->incomp_bytes += ilen;
  710. ++db->uncomp_count;
  711. db->uncomp_bytes += ilen;
  712. /* Increase code size if we would have without the packet
  713. * boundary and as the decompressor will.
  714. */
  715. if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode)
  716. db->n_bits++;
  717. }
  718. /*
  719. * Decompress "BSD Compress".
  720. *
  721. * Because of patent problems, we return DECOMP_ERROR for errors
  722. * found by inspecting the input data and for system problems, but
  723. * DECOMP_FATALERROR for any errors which could possibly be said to
  724. * be being detected "after" decompression. For DECOMP_ERROR,
  725. * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
  726. * infringing a patent of Motorola's if we do, so we take CCP down
  727. * instead.
  728. *
  729. * Given that the frame has the correct sequence number and a good FCS,
  730. * errors such as invalid codes in the input most likely indicate a
  731. * bug, so we return DECOMP_FATALERROR for them in order to turn off
  732. * compression, even though they are detected by inspecting the input.
  733. */
  734. int
  735. bsd_decompress(state, cmp, dmpp)
  736. void *state;
  737. struct mbuf *cmp, **dmpp;
  738. {
  739. struct bsd_db *db = (struct bsd_db *) state;
  740. u_int max_ent = db->max_ent;
  741. u_int32_t accm = 0;
  742. u_int bitno = 32; /* 1st valid bit in accm */
  743. u_int n_bits = db->n_bits;
  744. u_int tgtbitno = 32-n_bits; /* bitno when we have a code */
  745. struct bsd_dict *dictp;
  746. int explen, i, seq, len;
  747. u_int incode, oldcode, finchar;
  748. u_char *p, *rptr, *wptr;
  749. struct mbuf *m, *dmp, *mret;
  750. int adrs, ctrl, ilen;
  751. int space, codelen, extra;
  752. /*
  753. * Save the address/control from the PPP header
  754. * and then get the sequence number.
  755. */
  756. *dmpp = NULL;
  757. rptr = mtod(cmp, u_char *);
  758. adrs = PPP_ADDRESS(rptr);
  759. ctrl = PPP_CONTROL(rptr);
  760. rptr += PPP_HDRLEN;
  761. len = cmp->m_len - PPP_HDRLEN;
  762. seq = 0;
  763. for (i = 0; i < 2; ++i) {
  764. while (len <= 0) {
  765. cmp = cmp->m_next;
  766. if (cmp == NULL)
  767. return DECOMP_ERROR;
  768. rptr = mtod(cmp, u_char *);
  769. len = cmp->m_len;
  770. }
  771. seq = (seq << 8) + *rptr++;
  772. --len;
  773. }
  774. /*
  775. * Check the sequence number and give up if it differs from
  776. * the value we're expecting.
  777. */
  778. if (seq != db->seqno) {
  779. if (db->debug)
  780. printf("bsd_decomp%d: bad sequence # %d, expected %d\n",
  781. db->unit, seq, db->seqno - 1);
  782. return DECOMP_ERROR;
  783. }
  784. ++db->seqno;
  785. /*
  786. * Allocate one mbuf to start with.
  787. */
  788. MGETHDR(dmp, M_DONTWAIT, MT_DATA);
  789. if (dmp == NULL)
  790. return DECOMP_ERROR;
  791. mret = dmp;
  792. dmp->m_len = 0;
  793. dmp->m_next = NULL;
  794. MCLGET(dmp, M_DONTWAIT);
  795. dmp->m_data += db->hdrlen;
  796. wptr = mtod(dmp, u_char *);
  797. space = M_TRAILINGSPACE(dmp) - PPP_HDRLEN + 1;
  798. /*
  799. * Fill in the ppp header, but not the last byte of the protocol
  800. * (that comes from the decompressed data).
  801. */
  802. wptr[0] = adrs;
  803. wptr[1] = ctrl;
  804. wptr[2] = 0;
  805. wptr += PPP_HDRLEN - 1;
  806. ilen = len;
  807. oldcode = CLEAR;
  808. explen = 0;
  809. for (;;) {
  810. if (len == 0) {
  811. cmp = cmp->m_next;
  812. if (!cmp) /* quit at end of message */
  813. break;
  814. rptr = mtod(cmp, u_char *);
  815. len = cmp->m_len;
  816. ilen += len;
  817. continue; /* handle 0-length buffers */
  818. }
  819. /*
  820. * Accumulate bytes until we have a complete code.
  821. * Then get the next code, relying on the 32-bit,
  822. * unsigned accm to mask the result.
  823. */
  824. bitno -= 8;
  825. accm |= *rptr++ << bitno;
  826. --len;
  827. if (tgtbitno < bitno)
  828. continue;
  829. incode = accm >> tgtbitno;
  830. accm <<= n_bits;
  831. bitno += n_bits;
  832. if (incode == CLEAR) {
  833. /*
  834. * The dictionary must only be cleared at
  835. * the end of a packet. But there could be an
  836. * empty mbuf at the end.
  837. */
  838. if (len > 0 || cmp->m_next != NULL) {
  839. while ((cmp = cmp->m_next) != NULL)
  840. len += cmp->m_len;
  841. if (len > 0) {
  842. m_freem(mret);
  843. if (db->debug)
  844. printf("bsd_decomp%d: bad CLEAR\n", db->unit);
  845. return DECOMP_FATALERROR; /* probably a bug */
  846. }
  847. }
  848. bsd_clear(db);
  849. explen = ilen = 0;
  850. break;
  851. }
  852. if (incode > max_ent + 2 || incode > db->maxmaxcode
  853. || (incode > max_ent && oldcode == CLEAR)) {
  854. m_freem(mret);
  855. if (db->debug) {
  856. printf("bsd_decomp%d: bad code 0x%x oldcode=0x%x ",
  857. db->unit, incode, oldcode);
  858. printf("max_ent=0x%x explen=%d seqno=%d\n",
  859. max_ent, explen, db->seqno);
  860. }
  861. return DECOMP_FATALERROR; /* probably a bug */
  862. }
  863. /* Special case for KwKwK string. */
  864. if (incode > max_ent) {
  865. finchar = oldcode;
  866. extra = 1;
  867. } else {
  868. finchar = incode;
  869. extra = 0;
  870. }
  871. codelen = db->lens[finchar];
  872. explen += codelen + extra;
  873. if (explen > db->mru + 1) {
  874. m_freem(mret);
  875. if (db->debug) {
  876. printf("bsd_decomp%d: ran out of mru\n", db->unit);
  877. #ifdef DEBUG
  878. while ((cmp = cmp->m_next) != NULL)
  879. len += cmp->m_len;
  880. printf(" len=%d, finchar=0x%x, codelen=%d, explen=%d\n",
  881. len, finchar, codelen, explen);
  882. #endif
  883. }
  884. return DECOMP_FATALERROR;
  885. }
  886. /*
  887. * For simplicity, the decoded characters go in a single mbuf,
  888. * so we allocate a single extra cluster mbuf if necessary.
  889. */
  890. if ((space -= codelen + extra) < 0) {
  891. dmp->m_len = wptr - mtod(dmp, u_char *);
  892. MGET(m, M_DONTWAIT, MT_DATA);
  893. if (m == NULL) {
  894. m_freem(mret);
  895. return DECOMP_ERROR;
  896. }
  897. m->m_len = 0;
  898. m->m_next = NULL;
  899. dmp->m_next = m;
  900. MCLGET(m, M_DONTWAIT);
  901. space = M_TRAILINGSPACE(m) - (codelen + extra);
  902. if (space < 0) {
  903. /* now that's what I call *compression*. */
  904. m_freem(mret);
  905. return DECOMP_ERROR;
  906. }
  907. dmp = m;
  908. wptr = mtod(dmp, u_char *);
  909. }
  910. /*
  911. * Decode this code and install it in the decompressed buffer.
  912. */
  913. p = (wptr += codelen);
  914. while (finchar > LAST) {
  915. dictp = &db->dict[db->dict[finchar].cptr];
  916. #ifdef DEBUG
  917. if (--codelen <= 0 || dictp->codem1 != finchar-1)
  918. goto bad;
  919. #endif
  920. *--p = dictp->f.hs.suffix;
  921. finchar = dictp->f.hs.prefix;
  922. }
  923. *--p = finchar;
  924. #ifdef DEBUG
  925. if (--codelen != 0)
  926. printf("bsd_decomp%d: short by %d after code 0x%x, max_ent=0x%x\n",
  927. db->unit, codelen, incode, max_ent);
  928. #endif
  929. if (extra) /* the KwKwK case again */
  930. *wptr++ = finchar;
  931. /*
  932. * If not first code in a packet, and
  933. * if not out of code space, then allocate a new code.
  934. *
  935. * Keep the hash table correct so it can be used
  936. * with uncompressed packets.
  937. */
  938. if (oldcode != CLEAR && max_ent < db->maxmaxcode) {
  939. struct bsd_dict *dictp2;
  940. u_int32_t fcode;
  941. u_int32_t hval, disp;
  942. fcode = BSD_KEY(oldcode,finchar);
  943. hval = BSD_HASH(oldcode,finchar,db->hshift);
  944. dictp = &db->dict[hval];
  945. /* look for a free hash table entry */
  946. if (dictp->codem1 < max_ent) {
  947. disp = (hval == 0) ? 1 : hval;
  948. do {
  949. hval += disp;
  950. if (hval >= db->hsize)
  951. hval -= db->hsize;
  952. dictp = &db->dict[hval];
  953. } while (dictp->codem1 < max_ent);
  954. }
  955. /*
  956. * Invalidate previous hash table entry
  957. * assigned this code, and then take it over
  958. */
  959. dictp2 = &db->dict[max_ent+1];
  960. if (db->dict[dictp2->cptr].codem1 == max_ent) {
  961. db->dict[dictp2->cptr].codem1 = BADCODEM1;
  962. }
  963. dictp2->cptr = hval;
  964. dictp->codem1 = max_ent;
  965. dictp->f.fcode = fcode;
  966. db->max_ent = ++max_ent;
  967. db->lens[max_ent] = db->lens[oldcode]+1;
  968. /* Expand code size if needed. */
  969. if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) {
  970. db->n_bits = ++n_bits;
  971. tgtbitno = 32-n_bits;
  972. }
  973. }
  974. oldcode = incode;
  975. }
  976. dmp->m_len = wptr - mtod(dmp, u_char *);
  977. /*
  978. * Keep the checkpoint right so that incompressible packets
  979. * clear the dictionary at the right times.
  980. */
  981. db->bytes_out += ilen;
  982. db->in_count += explen;
  983. if (bsd_check(db) && db->debug) {
  984. printf("bsd_decomp%d: peer should have cleared dictionary\n",
  985. db->unit);
  986. }
  987. ++db->comp_count;
  988. db->comp_bytes += ilen + BSD_OVHD;
  989. ++db->uncomp_count;
  990. db->uncomp_bytes += explen;
  991. *dmpp = mret;
  992. return DECOMP_OK;
  993. #ifdef DEBUG
  994. bad:
  995. if (codelen <= 0) {
  996. printf("bsd_decomp%d: fell off end of chain ", db->unit);
  997. printf("0x%x at 0x%x by 0x%x, max_ent=0x%x\n",
  998. incode, finchar, db->dict[finchar].cptr, max_ent);
  999. } else if (dictp->codem1 != finchar-1) {
  1000. printf("bsd_decomp%d: bad code chain 0x%x finchar=0x%x ",
  1001. db->unit, incode, finchar);
  1002. printf("oldcode=0x%x cptr=0x%x codem1=0x%x\n", oldcode,
  1003. db->dict[finchar].cptr, dictp->codem1);
  1004. }
  1005. m_freem(mret);
  1006. return DECOMP_FATALERROR;
  1007. #endif /* DEBUG */
  1008. }
  1009. #endif /* DO_BSD_COMPRESS */