ppp-deflate.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. /* $OpenBSD: ppp-deflate.c,v 1.12 2015/07/15 22:16:42 deraadt Exp $ */
  2. /* $NetBSD: ppp-deflate.c,v 1.1 1996/03/15 02:28:09 paulus Exp $ */
  3. /*
  4. * ppp_deflate.c - interface the zlib procedures for Deflate compression
  5. * and decompression (as used by gzip) to the PPP code.
  6. * This version is for use with mbufs on BSD-derived systems.
  7. *
  8. * Copyright (c) 1989-2002 Paul Mackerras. All rights reserved.
  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. *
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. *
  17. * 2. Redistributions in binary form must reproduce the above copyright
  18. * notice, this list of conditions and the following disclaimer in
  19. * the documentation and/or other materials provided with the
  20. * distribution.
  21. *
  22. * 3. The name(s) of the authors of this software must not be used to
  23. * endorse or promote products derived from this software without
  24. * prior written permission.
  25. *
  26. * 4. Redistributions of any form whatsoever must retain the following
  27. * acknowledgment:
  28. * "This product includes software developed by Paul Mackerras
  29. * <paulus@samba.org>".
  30. *
  31. * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
  32. * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  33. * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
  34. * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  35. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  36. * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  37. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  38. */
  39. #include <sys/param.h>
  40. #include <sys/types.h>
  41. #include <sys/systm.h>
  42. #include <sys/mbuf.h>
  43. #include <net/ppp_defs.h>
  44. #include <lib/libz/zlib.h>
  45. #define PACKETPTR struct mbuf *
  46. #include <net/ppp-comp.h>
  47. #if DO_DEFLATE
  48. /*
  49. * State for a Deflate (de)compressor.
  50. */
  51. struct deflate_state {
  52. int seqno;
  53. int w_size;
  54. int unit;
  55. int hdrlen;
  56. int mru;
  57. int debug;
  58. z_stream strm;
  59. struct compstat stats;
  60. };
  61. #define DEFLATE_OVHD 2 /* Deflate overhead/packet */
  62. static void *zcalloc(void *, u_int items, u_int size);
  63. static void zcfree(void *, void *ptr);
  64. static void *z_comp_alloc(u_char *options, int opt_len);
  65. static void *z_decomp_alloc(u_char *options, int opt_len);
  66. static void z_comp_free(void *state);
  67. static void z_decomp_free(void *state);
  68. static int z_comp_init(void *state, u_char *options, int opt_len,
  69. int unit, int hdrlen, int debug);
  70. static int z_decomp_init(void *state, u_char *options, int opt_len,
  71. int unit, int hdrlen, int mru, int debug);
  72. static int z_compress(void *state, struct mbuf **mret,
  73. struct mbuf *mp, int slen, int maxolen);
  74. static void z_incomp(void *state, struct mbuf *dmsg);
  75. static int z_decompress(void *state, struct mbuf *cmp,
  76. struct mbuf **dmpp);
  77. static void z_comp_reset(void *state);
  78. static void z_decomp_reset(void *state);
  79. static void z_comp_stats(void *state, struct compstat *stats);
  80. /*
  81. * Procedures exported to if_ppp.c.
  82. */
  83. struct compressor ppp_deflate = {
  84. CI_DEFLATE, /* compress_proto */
  85. z_comp_alloc, /* comp_alloc */
  86. z_comp_free, /* comp_free */
  87. z_comp_init, /* comp_init */
  88. z_comp_reset, /* comp_reset */
  89. z_compress, /* compress */
  90. z_comp_stats, /* comp_stat */
  91. z_decomp_alloc, /* decomp_alloc */
  92. z_decomp_free, /* decomp_free */
  93. z_decomp_init, /* decomp_init */
  94. z_decomp_reset, /* decomp_reset */
  95. z_decompress, /* decompress */
  96. z_incomp, /* incomp */
  97. z_comp_stats, /* decomp_stat */
  98. };
  99. struct compressor ppp_deflate_draft = {
  100. CI_DEFLATE_DRAFT, /* compress_proto */
  101. z_comp_alloc, /* comp_alloc */
  102. z_comp_free, /* comp_free */
  103. z_comp_init, /* comp_init */
  104. z_comp_reset, /* comp_reset */
  105. z_compress, /* compress */
  106. z_comp_stats, /* comp_stat */
  107. z_decomp_alloc, /* decomp_alloc */
  108. z_decomp_free, /* decomp_free */
  109. z_decomp_init, /* decomp_init */
  110. z_decomp_reset, /* decomp_reset */
  111. z_decompress, /* decompress */
  112. z_incomp, /* incomp */
  113. z_comp_stats, /* decomp_stat */
  114. };
  115. /*
  116. * Space allocation and freeing routines for use by zlib routines.
  117. */
  118. void *
  119. zcalloc(notused, items, size)
  120. void *notused;
  121. u_int items, size;
  122. {
  123. void *ptr;
  124. ptr = mallocarray(items, size, M_DEVBUF, M_NOWAIT);
  125. return ptr;
  126. }
  127. void
  128. zcfree(notused, ptr)
  129. void *notused;
  130. void *ptr;
  131. {
  132. free(ptr, M_DEVBUF, 0);
  133. }
  134. /*
  135. * Allocate space for a compressor.
  136. */
  137. static void *
  138. z_comp_alloc(options, opt_len)
  139. u_char *options;
  140. int opt_len;
  141. {
  142. struct deflate_state *state;
  143. int w_size;
  144. if (opt_len != CILEN_DEFLATE
  145. || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
  146. || options[1] != CILEN_DEFLATE
  147. || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
  148. || options[3] != DEFLATE_CHK_SEQUENCE)
  149. return NULL;
  150. w_size = DEFLATE_SIZE(options[2]);
  151. if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
  152. return NULL;
  153. state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT);
  154. if (state == NULL)
  155. return NULL;
  156. state->strm.next_in = NULL;
  157. state->strm.zalloc = zcalloc;
  158. state->strm.zfree = zcfree;
  159. if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL,
  160. -w_size, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
  161. free(state, M_DEVBUF, 0);
  162. return NULL;
  163. }
  164. state->w_size = w_size;
  165. bzero(&state->stats, sizeof(state->stats));
  166. return (void *) state;
  167. }
  168. static void
  169. z_comp_free(arg)
  170. void *arg;
  171. {
  172. struct deflate_state *state = (struct deflate_state *) arg;
  173. deflateEnd(&state->strm);
  174. free(state, M_DEVBUF, 0);
  175. }
  176. static int
  177. z_comp_init(arg, options, opt_len, unit, hdrlen, debug)
  178. void *arg;
  179. u_char *options;
  180. int opt_len, unit, hdrlen, debug;
  181. {
  182. struct deflate_state *state = (struct deflate_state *) arg;
  183. if (opt_len < CILEN_DEFLATE
  184. || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
  185. || options[1] != CILEN_DEFLATE
  186. || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
  187. || DEFLATE_SIZE(options[2]) != state->w_size
  188. || options[3] != DEFLATE_CHK_SEQUENCE)
  189. return 0;
  190. state->seqno = 0;
  191. state->unit = unit;
  192. state->hdrlen = hdrlen;
  193. state->debug = debug;
  194. deflateReset(&state->strm);
  195. return 1;
  196. }
  197. static void
  198. z_comp_reset(arg)
  199. void *arg;
  200. {
  201. struct deflate_state *state = (struct deflate_state *) arg;
  202. state->seqno = 0;
  203. deflateReset(&state->strm);
  204. }
  205. int
  206. z_compress(arg, mret, mp, orig_len, maxolen)
  207. void *arg;
  208. struct mbuf **mret; /* compressed packet (out) */
  209. struct mbuf *mp; /* uncompressed packet (in) */
  210. int orig_len, maxolen;
  211. {
  212. struct deflate_state *state = (struct deflate_state *) arg;
  213. u_char *rptr, *wptr;
  214. int proto, olen, wspace, r, flush;
  215. struct mbuf *m;
  216. /*
  217. * Check that the protocol is in the range we handle.
  218. */
  219. rptr = mtod(mp, u_char *);
  220. proto = PPP_PROTOCOL(rptr);
  221. if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) {
  222. *mret = NULL;
  223. return orig_len;
  224. }
  225. /* Allocate one mbuf initially. */
  226. if (maxolen > orig_len)
  227. maxolen = orig_len;
  228. MGET(m, M_DONTWAIT, MT_DATA);
  229. *mret = m;
  230. if (m != NULL) {
  231. m->m_len = 0;
  232. if (maxolen + state->hdrlen > MLEN)
  233. MCLGET(m, M_DONTWAIT);
  234. wspace = M_TRAILINGSPACE(m);
  235. if (state->hdrlen + PPP_HDRLEN + 2 < wspace) {
  236. m->m_data += state->hdrlen;
  237. wspace -= state->hdrlen;
  238. }
  239. wptr = mtod(m, u_char *);
  240. /*
  241. * Copy over the PPP header and store the 2-byte sequence number.
  242. */
  243. wptr[0] = PPP_ADDRESS(rptr);
  244. wptr[1] = PPP_CONTROL(rptr);
  245. wptr[2] = PPP_COMP >> 8;
  246. wptr[3] = PPP_COMP;
  247. wptr += PPP_HDRLEN;
  248. wptr[0] = state->seqno >> 8;
  249. wptr[1] = state->seqno;
  250. wptr += 2;
  251. state->strm.next_out = wptr;
  252. state->strm.avail_out = wspace - (PPP_HDRLEN + 2);
  253. } else {
  254. state->strm.next_out = NULL;
  255. state->strm.avail_out = 1000000;
  256. wptr = NULL;
  257. wspace = 0;
  258. }
  259. ++state->seqno;
  260. rptr += (proto > 0xff)? 2: 3; /* skip 1st proto byte if 0 */
  261. state->strm.next_in = rptr;
  262. state->strm.avail_in = mtod(mp, u_char *) + mp->m_len - rptr;
  263. mp = mp->m_next;
  264. flush = (mp == NULL)? Z_SYNC_FLUSH: Z_NO_FLUSH;
  265. olen = 0;
  266. for (;;) {
  267. r = deflate(&state->strm, flush);
  268. if (r != Z_OK) {
  269. printf("z_compress: deflate returned %d (%s)\n",
  270. r, (state->strm.msg? state->strm.msg: ""));
  271. break;
  272. }
  273. if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
  274. break; /* all done */
  275. if (state->strm.avail_in == 0 && mp != NULL) {
  276. state->strm.next_in = mtod(mp, u_char *);
  277. state->strm.avail_in = mp->m_len;
  278. mp = mp->m_next;
  279. if (mp == NULL)
  280. flush = Z_SYNC_FLUSH;
  281. }
  282. if (state->strm.avail_out == 0) {
  283. if (m != NULL) {
  284. m->m_len = wspace;
  285. olen += wspace;
  286. MGET(m->m_next, M_DONTWAIT, MT_DATA);
  287. m = m->m_next;
  288. if (m != NULL) {
  289. m->m_len = 0;
  290. if (maxolen - olen > MLEN)
  291. MCLGET(m, M_DONTWAIT);
  292. state->strm.next_out = mtod(m, u_char *);
  293. state->strm.avail_out = wspace = M_TRAILINGSPACE(m);
  294. }
  295. }
  296. if (m == NULL) {
  297. state->strm.next_out = NULL;
  298. state->strm.avail_out = 1000000;
  299. }
  300. }
  301. }
  302. if (m != NULL)
  303. olen += (m->m_len = wspace - state->strm.avail_out);
  304. /*
  305. * See if we managed to reduce the size of the packet.
  306. * If the compressor just gave us a single zero byte, it means
  307. * the packet was incompressible.
  308. */
  309. if (m != NULL && olen < orig_len
  310. && !(olen == PPP_HDRLEN + 3 && *wptr == 0)) {
  311. state->stats.comp_bytes += olen;
  312. state->stats.comp_packets++;
  313. } else {
  314. m_freem(*mret);
  315. *mret = NULL;
  316. state->stats.inc_bytes += orig_len;
  317. state->stats.inc_packets++;
  318. olen = orig_len;
  319. }
  320. state->stats.unc_bytes += orig_len;
  321. state->stats.unc_packets++;
  322. return olen;
  323. }
  324. static void
  325. z_comp_stats(arg, stats)
  326. void *arg;
  327. struct compstat *stats;
  328. {
  329. struct deflate_state *state = (struct deflate_state *) arg;
  330. u_int out;
  331. *stats = state->stats;
  332. stats->ratio = stats->unc_bytes;
  333. out = stats->comp_bytes + stats->inc_bytes;
  334. if (stats->ratio <= 0x7ffffff)
  335. stats->ratio <<= 8;
  336. else
  337. out >>= 8;
  338. if (out != 0)
  339. stats->ratio /= out;
  340. }
  341. /*
  342. * Allocate space for a decompressor.
  343. */
  344. static void *
  345. z_decomp_alloc(options, opt_len)
  346. u_char *options;
  347. int opt_len;
  348. {
  349. struct deflate_state *state;
  350. int w_size;
  351. if (opt_len != CILEN_DEFLATE
  352. || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
  353. || options[1] != CILEN_DEFLATE
  354. || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
  355. || options[3] != DEFLATE_CHK_SEQUENCE)
  356. return NULL;
  357. w_size = DEFLATE_SIZE(options[2]);
  358. if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
  359. return NULL;
  360. state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT);
  361. if (state == NULL)
  362. return NULL;
  363. state->strm.next_out = NULL;
  364. state->strm.zalloc = zcalloc;
  365. state->strm.zfree = zcfree;
  366. if (inflateInit2(&state->strm, -w_size) != Z_OK) {
  367. free(state, M_DEVBUF, 0);
  368. return NULL;
  369. }
  370. state->w_size = w_size;
  371. bzero(&state->stats, sizeof(state->stats));
  372. return (void *) state;
  373. }
  374. static void
  375. z_decomp_free(arg)
  376. void *arg;
  377. {
  378. struct deflate_state *state = (struct deflate_state *) arg;
  379. inflateEnd(&state->strm);
  380. free(state, M_DEVBUF, 0);
  381. }
  382. static int
  383. z_decomp_init(arg, options, opt_len, unit, hdrlen, mru, debug)
  384. void *arg;
  385. u_char *options;
  386. int opt_len, unit, hdrlen, mru, debug;
  387. {
  388. struct deflate_state *state = (struct deflate_state *) arg;
  389. if (opt_len < CILEN_DEFLATE
  390. || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
  391. || options[1] != CILEN_DEFLATE
  392. || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
  393. || DEFLATE_SIZE(options[2]) != state->w_size
  394. || options[3] != DEFLATE_CHK_SEQUENCE)
  395. return 0;
  396. state->seqno = 0;
  397. state->unit = unit;
  398. state->hdrlen = hdrlen;
  399. state->debug = debug;
  400. state->mru = mru;
  401. inflateReset(&state->strm);
  402. return 1;
  403. }
  404. static void
  405. z_decomp_reset(arg)
  406. void *arg;
  407. {
  408. struct deflate_state *state = (struct deflate_state *) arg;
  409. state->seqno = 0;
  410. inflateReset(&state->strm);
  411. }
  412. /*
  413. * Decompress a Deflate-compressed packet.
  414. *
  415. * Because of patent problems, we return DECOMP_ERROR for errors
  416. * found by inspecting the input data and for system problems, but
  417. * DECOMP_FATALERROR for any errors which could possibly be said to
  418. * be being detected "after" decompression. For DECOMP_ERROR,
  419. * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
  420. * infringing a patent of Motorola's if we do, so we take CCP down
  421. * instead.
  422. *
  423. * Given that the frame has the correct sequence number and a good FCS,
  424. * errors such as invalid codes in the input most likely indicate a
  425. * bug, so we return DECOMP_FATALERROR for them in order to turn off
  426. * compression, even though they are detected by inspecting the input.
  427. */
  428. int
  429. z_decompress(arg, mi, mop)
  430. void *arg;
  431. struct mbuf *mi, **mop;
  432. {
  433. struct deflate_state *state = (struct deflate_state *) arg;
  434. struct mbuf *mo, *mo_head;
  435. u_char *rptr, *wptr;
  436. int rlen, olen, ospace;
  437. int seq, i, flush, r, decode_proto;
  438. u_char hdr[PPP_HDRLEN + DEFLATE_OVHD];
  439. *mop = NULL;
  440. rptr = mtod(mi, u_char *);
  441. rlen = mi->m_len;
  442. for (i = 0; i < PPP_HDRLEN + DEFLATE_OVHD; ++i) {
  443. while (rlen <= 0) {
  444. mi = mi->m_next;
  445. if (mi == NULL)
  446. return DECOMP_ERROR;
  447. rptr = mtod(mi, u_char *);
  448. rlen = mi->m_len;
  449. }
  450. hdr[i] = *rptr++;
  451. --rlen;
  452. }
  453. /* Check the sequence number. */
  454. seq = (hdr[PPP_HDRLEN] << 8) + hdr[PPP_HDRLEN+1];
  455. if (seq != state->seqno) {
  456. if (state->debug)
  457. printf("z_decompress%d: bad seq # %d, expected %d\n",
  458. state->unit, seq, state->seqno);
  459. return DECOMP_ERROR;
  460. }
  461. ++state->seqno;
  462. /* Allocate an output mbuf. */
  463. MGETHDR(mo, M_DONTWAIT, MT_DATA);
  464. if (mo == NULL)
  465. return DECOMP_ERROR;
  466. mo_head = mo;
  467. mo->m_len = 0;
  468. mo->m_next = NULL;
  469. MCLGET(mo, M_DONTWAIT);
  470. ospace = M_TRAILINGSPACE(mo);
  471. if (state->hdrlen + PPP_HDRLEN < ospace) {
  472. mo->m_data += state->hdrlen;
  473. ospace -= state->hdrlen;
  474. }
  475. /*
  476. * Fill in the first part of the PPP header. The protocol field
  477. * comes from the decompressed data.
  478. */
  479. wptr = mtod(mo, u_char *);
  480. wptr[0] = PPP_ADDRESS(hdr);
  481. wptr[1] = PPP_CONTROL(hdr);
  482. wptr[2] = 0;
  483. /*
  484. * Set up to call inflate. We set avail_out to 1 initially so we can
  485. * look at the first byte of the output and decide whether we have
  486. * a 1-byte or 2-byte protocol field.
  487. */
  488. state->strm.next_in = rptr;
  489. state->strm.avail_in = rlen;
  490. mi = mi->m_next;
  491. flush = (mi == NULL)? Z_SYNC_FLUSH: Z_NO_FLUSH;
  492. rlen += PPP_HDRLEN + DEFLATE_OVHD;
  493. state->strm.next_out = wptr + 3;
  494. state->strm.avail_out = 1;
  495. decode_proto = 1;
  496. olen = PPP_HDRLEN;
  497. /*
  498. * Call inflate, supplying more input or output as needed.
  499. */
  500. for (;;) {
  501. r = inflate(&state->strm, flush);
  502. if (r != Z_OK) {
  503. #ifndef DEFLATE_DEBUG
  504. if (state->debug)
  505. #endif
  506. printf("z_decompress%d: inflate returned %d (%s)\n",
  507. state->unit, r, (state->strm.msg? state->strm.msg: ""));
  508. m_freem(mo_head);
  509. return DECOMP_FATALERROR;
  510. }
  511. if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
  512. break; /* all done */
  513. if (state->strm.avail_in == 0 && mi != NULL) {
  514. state->strm.next_in = mtod(mi, u_char *);
  515. state->strm.avail_in = mi->m_len;
  516. rlen += mi->m_len;
  517. mi = mi->m_next;
  518. if (mi == NULL)
  519. flush = Z_SYNC_FLUSH;
  520. }
  521. if (state->strm.avail_out == 0) {
  522. if (decode_proto) {
  523. state->strm.avail_out = ospace - PPP_HDRLEN;
  524. if ((wptr[3] & 1) == 0) {
  525. /* 2-byte protocol field */
  526. wptr[2] = wptr[3];
  527. --state->strm.next_out;
  528. ++state->strm.avail_out;
  529. --olen;
  530. }
  531. decode_proto = 0;
  532. } else {
  533. mo->m_len = ospace;
  534. olen += ospace;
  535. MGET(mo->m_next, M_DONTWAIT, MT_DATA);
  536. mo = mo->m_next;
  537. if (mo == NULL) {
  538. m_freem(mo_head);
  539. return DECOMP_ERROR;
  540. }
  541. MCLGET(mo, M_DONTWAIT);
  542. state->strm.next_out = mtod(mo, u_char *);
  543. state->strm.avail_out = ospace = M_TRAILINGSPACE(mo);
  544. }
  545. }
  546. }
  547. if (decode_proto) {
  548. m_freem(mo_head);
  549. return DECOMP_ERROR;
  550. }
  551. olen += (mo->m_len = ospace - state->strm.avail_out);
  552. #ifdef DEFLATE_DEBUG
  553. if (olen > state->mru + PPP_HDRLEN)
  554. printf("ppp_deflate%d: exceeded mru (%d > %d)\n",
  555. state->unit, olen, state->mru + PPP_HDRLEN);
  556. #endif
  557. state->stats.unc_bytes += olen;
  558. state->stats.unc_packets++;
  559. state->stats.comp_bytes += rlen;
  560. state->stats.comp_packets++;
  561. *mop = mo_head;
  562. return DECOMP_OK;
  563. }
  564. /*
  565. * Incompressible data has arrived - add it to the history.
  566. */
  567. static void
  568. z_incomp(arg, mi)
  569. void *arg;
  570. struct mbuf *mi;
  571. {
  572. struct deflate_state *state = (struct deflate_state *) arg;
  573. u_char *rptr;
  574. int rlen, proto, r;
  575. /*
  576. * Check that the protocol is one we handle.
  577. */
  578. rptr = mtod(mi, u_char *);
  579. proto = PPP_PROTOCOL(rptr);
  580. if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
  581. return;
  582. ++state->seqno;
  583. /*
  584. * Iterate through the mbufs, adding the characters in them
  585. * to the decompressor's history. For the first mbuf, we start
  586. * at the either the 1st or 2nd byte of the protocol field,
  587. * depending on whether the protocol value is compressible.
  588. */
  589. rlen = mi->m_len;
  590. state->strm.next_in = rptr + 3;
  591. state->strm.avail_in = rlen - 3;
  592. if (proto > 0xff) {
  593. --state->strm.next_in;
  594. ++state->strm.avail_in;
  595. }
  596. for (;;) {
  597. r = inflateInit(&state->strm);
  598. if (r != Z_OK) {
  599. /* gak! */
  600. #ifndef DEFLATE_DEBUG
  601. if (state->debug)
  602. #endif
  603. printf("z_incomp%d: inflateIncomp returned %d (%s)\n",
  604. state->unit, r, (state->strm.msg? state->strm.msg: ""));
  605. return;
  606. }
  607. mi = mi->m_next;
  608. if (mi == NULL)
  609. break;
  610. state->strm.next_in = mtod(mi, u_char *);
  611. state->strm.avail_in = mi->m_len;
  612. rlen += mi->m_len;
  613. }
  614. /*
  615. * Update stats.
  616. */
  617. state->stats.inc_bytes += rlen;
  618. state->stats.inc_packets++;
  619. state->stats.unc_bytes += rlen;
  620. state->stats.unc_packets++;
  621. }
  622. #endif /* DO_DEFLATE */