]> git.saurik.com Git - apple/xnu.git/blob - bsd/net/ppp_deflate.c
xnu-792.6.76.tar.gz
[apple/xnu.git] / bsd / net / ppp_deflate.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 * ppp_deflate.c - interface the zlib procedures for Deflate compression
24 * and decompression (as used by gzip) to the PPP code.
25 * This version is for use with mbufs on BSD-derived systems.
26 *
27 * Copyright (c) 1994 The Australian National University.
28 * All rights reserved.
29 *
30 * Permission to use, copy, modify, and distribute this software and its
31 * documentation is hereby granted, provided that the above copyright
32 * notice appears in all copies. This software is provided without any
33 * warranty, express or implied. The Australian National University
34 * makes no representations about the suitability of this software for
35 * any purpose.
36 *
37 * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
38 * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
39 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
40 * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY
41 * OF SUCH DAMAGE.
42 *
43 * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
44 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
45 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
46 * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
47 * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
48 * OR MODIFICATIONS.
49 */
50
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/malloc.h>
54 #include <sys/mbuf.h>
55 #include <net/ppp_defs.h>
56 #include <net/zlib.h>
57
58 #define PACKETPTR struct mbuf *
59 #include <net/ppp_comp.h>
60
61 #if DO_DEFLATE
62
63 #define DEFLATE_DEBUG 1
64
65 /*
66 * State for a Deflate (de)compressor.
67 */
68 struct deflate_state {
69 int seqno;
70 int w_size;
71 int unit;
72 int hdrlen;
73 int mru;
74 int debug;
75 z_stream strm;
76 struct compstat stats;
77 };
78
79 #define DEFLATE_OVHD 2 /* Deflate overhead/packet */
80
81 static void *z_alloc(void *, u_int items, u_int size);
82 static void z_free(void *, void *ptr);
83 static void *z_comp_alloc(u_char *options, int opt_len);
84 static void *z_decomp_alloc(u_char *options, int opt_len);
85 static void z_comp_free(void *state);
86 static void z_decomp_free(void *state);
87 static int z_comp_init(void *state, u_char *options, int opt_len,
88 int unit, int hdrlen, int debug);
89 static int z_decomp_init(void *state, u_char *options, int opt_len,
90 int unit, int hdrlen, int mru, int debug);
91 static int z_compress(void *state, struct mbuf **mret,
92 struct mbuf *mp, int slen, int maxolen);
93 static void z_incomp(void *state, struct mbuf *dmsg);
94 static int z_decompress(void *state, struct mbuf *cmp, struct mbuf **dmpp);
95 static void z_comp_reset(void *state);
96 static void z_decomp_reset(void *state);
97 static void z_comp_stats(void *state, struct compstat *stats);
98
99 /*
100 * Procedures exported to if_ppp.c.
101 */
102 struct compressor ppp_deflate = {
103 CI_DEFLATE, /* compress_proto */
104 z_comp_alloc, /* comp_alloc */
105 z_comp_free, /* comp_free */
106 z_comp_init, /* comp_init */
107 z_comp_reset, /* comp_reset */
108 z_compress, /* compress */
109 z_comp_stats, /* comp_stat */
110 z_decomp_alloc, /* decomp_alloc */
111 z_decomp_free, /* decomp_free */
112 z_decomp_init, /* decomp_init */
113 z_decomp_reset, /* decomp_reset */
114 z_decompress, /* decompress */
115 z_incomp, /* incomp */
116 z_comp_stats, /* decomp_stat */
117 };
118
119 struct compressor ppp_deflate_draft = {
120 CI_DEFLATE_DRAFT, /* compress_proto */
121 z_comp_alloc, /* comp_alloc */
122 z_comp_free, /* comp_free */
123 z_comp_init, /* comp_init */
124 z_comp_reset, /* comp_reset */
125 z_compress, /* compress */
126 z_comp_stats, /* comp_stat */
127 z_decomp_alloc, /* decomp_alloc */
128 z_decomp_free, /* decomp_free */
129 z_decomp_init, /* decomp_init */
130 z_decomp_reset, /* decomp_reset */
131 z_decompress, /* decompress */
132 z_incomp, /* incomp */
133 z_comp_stats, /* decomp_stat */
134 };
135
136 /*
137 * Space allocation and freeing routines for use by zlib routines.
138 */
139 void *
140 z_alloc(notused, items, size)
141 void *notused;
142 u_int items, size;
143 {
144 void *ptr;
145
146 MALLOC(ptr, void *, items * size, M_DEVBUF, M_NOWAIT);
147 return ptr;
148 }
149
150 void
151 z_free(notused, ptr)
152 void *notused;
153 void *ptr;
154 {
155 FREE(ptr, M_DEVBUF);
156 }
157
158 /*
159 * Allocate space for a compressor.
160 */
161 static void *
162 z_comp_alloc(options, opt_len)
163 u_char *options;
164 int opt_len;
165 {
166 struct deflate_state *state;
167 int w_size;
168
169 if (opt_len != CILEN_DEFLATE
170 || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
171 || options[1] != CILEN_DEFLATE
172 || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
173 || options[3] != DEFLATE_CHK_SEQUENCE)
174 return NULL;
175 w_size = DEFLATE_SIZE(options[2]);
176 if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
177 return NULL;
178
179 MALLOC(state, struct deflate_state *, sizeof(struct deflate_state),
180 M_DEVBUF, M_NOWAIT);
181 if (state == NULL)
182 return NULL;
183
184 state->strm.next_in = NULL;
185 state->strm.zalloc = z_alloc;
186 state->strm.zfree = z_free;
187 if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL,
188 -w_size, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
189 FREE(state, M_DEVBUF);
190 return NULL;
191 }
192
193 state->w_size = w_size;
194 bzero(&state->stats, sizeof(state->stats));
195 return (void *) state;
196 }
197
198 static void
199 z_comp_free(arg)
200 void *arg;
201 {
202 struct deflate_state *state = (struct deflate_state *) arg;
203
204 deflateEnd(&state->strm);
205 FREE(state, M_DEVBUF);
206 }
207
208 static int
209 z_comp_init(arg, options, opt_len, unit, hdrlen, debug)
210 void *arg;
211 u_char *options;
212 int opt_len, unit, hdrlen, debug;
213 {
214 struct deflate_state *state = (struct deflate_state *) arg;
215
216 if (opt_len < CILEN_DEFLATE
217 || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
218 || options[1] != CILEN_DEFLATE
219 || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
220 || DEFLATE_SIZE(options[2]) != state->w_size
221 || options[3] != DEFLATE_CHK_SEQUENCE)
222 return 0;
223
224 state->seqno = 0;
225 state->unit = unit;
226 state->hdrlen = hdrlen;
227 state->debug = debug;
228
229 deflateReset(&state->strm);
230
231 return 1;
232 }
233
234 static void
235 z_comp_reset(arg)
236 void *arg;
237 {
238 struct deflate_state *state = (struct deflate_state *) arg;
239
240 state->seqno = 0;
241 deflateReset(&state->strm);
242 }
243
244 int
245 z_compress(arg, mret, mp, orig_len, maxolen)
246 void *arg;
247 struct mbuf **mret; /* compressed packet (out) */
248 struct mbuf *mp; /* uncompressed packet (in) */
249 int orig_len, maxolen;
250 {
251 struct deflate_state *state = (struct deflate_state *) arg;
252 u_char *rptr, *wptr;
253 int proto, olen, wspace, r, flush;
254 struct mbuf *m;
255
256 /*
257 * Check that the protocol is in the range we handle.
258 */
259 rptr = mtod(mp, u_char *);
260 proto = PPP_PROTOCOL(rptr);
261 if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) {
262 *mret = NULL;
263 return orig_len;
264 }
265
266 /* Allocate one mbuf initially. */
267 if (maxolen > orig_len)
268 maxolen = orig_len;
269 MGET(m, M_DONTWAIT, MT_DATA);
270 *mret = m;
271 if (m != NULL) {
272 m->m_len = 0;
273 if (maxolen + state->hdrlen > MLEN)
274 MCLGET(m, M_DONTWAIT);
275 wspace = M_TRAILINGSPACE(m);
276 if (state->hdrlen + PPP_HDRLEN + 2 < wspace) {
277 m->m_data += state->hdrlen;
278 wspace -= state->hdrlen;
279 }
280 wptr = mtod(m, u_char *);
281
282 /*
283 * Copy over the PPP header and store the 2-byte sequence number.
284 */
285 wptr[0] = PPP_ADDRESS(rptr);
286 wptr[1] = PPP_CONTROL(rptr);
287 wptr[2] = PPP_COMP >> 8;
288 wptr[3] = PPP_COMP;
289 wptr += PPP_HDRLEN;
290 wptr[0] = state->seqno >> 8;
291 wptr[1] = state->seqno;
292 wptr += 2;
293 state->strm.next_out = wptr;
294 state->strm.avail_out = wspace - (PPP_HDRLEN + 2);
295 } else {
296 state->strm.next_out = NULL;
297 state->strm.avail_out = 1000000;
298 wptr = NULL;
299 wspace = 0;
300 }
301 ++state->seqno;
302
303 rptr += (proto > 0xff)? 2: 3; /* skip 1st proto byte if 0 */
304 state->strm.next_in = rptr;
305 state->strm.avail_in = mtod(mp, u_char *) + mp->m_len - rptr;
306 mp = mp->m_next;
307 flush = (mp == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH;
308 olen = 0;
309 for (;;) {
310 r = deflate(&state->strm, flush);
311 if (r != Z_OK) {
312 printf("z_compress: deflate returned %d (%s)\n",
313 r, (state->strm.msg? state->strm.msg: ""));
314 break;
315 }
316 if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
317 break; /* all done */
318 if (state->strm.avail_in == 0 && mp != NULL) {
319 state->strm.next_in = mtod(mp, u_char *);
320 state->strm.avail_in = mp->m_len;
321 mp = mp->m_next;
322 if (mp == NULL)
323 flush = Z_PACKET_FLUSH;
324 }
325 if (state->strm.avail_out == 0) {
326 if (m != NULL) {
327 m->m_len = wspace;
328 olen += wspace;
329 MGET(m->m_next, M_DONTWAIT, MT_DATA);
330 m = m->m_next;
331 if (m != NULL) {
332 m->m_len = 0;
333 if (maxolen - olen > MLEN)
334 MCLGET(m, M_DONTWAIT);
335 state->strm.next_out = mtod(m, u_char *);
336 state->strm.avail_out = wspace = M_TRAILINGSPACE(m);
337 }
338 }
339 if (m == NULL) {
340 state->strm.next_out = NULL;
341 state->strm.avail_out = 1000000;
342 }
343 }
344 }
345 if (m != NULL)
346 olen += (m->m_len = wspace - state->strm.avail_out);
347
348 /*
349 * See if we managed to reduce the size of the packet.
350 */
351 if (m != NULL && olen < orig_len) {
352 state->stats.comp_bytes += olen;
353 state->stats.comp_packets++;
354 } else {
355 if (*mret != NULL) {
356 m_freem(*mret);
357 *mret = NULL;
358 }
359 state->stats.inc_bytes += orig_len;
360 state->stats.inc_packets++;
361 olen = orig_len;
362 }
363 state->stats.unc_bytes += orig_len;
364 state->stats.unc_packets++;
365
366 return olen;
367 }
368
369 static void
370 z_comp_stats(arg, stats)
371 void *arg;
372 struct compstat *stats;
373 {
374 struct deflate_state *state = (struct deflate_state *) arg;
375 u_int out;
376
377 *stats = state->stats;
378 stats->ratio = stats->unc_bytes;
379 out = stats->comp_bytes + stats->inc_bytes;
380 if (stats->ratio <= 0x7ffffff)
381 stats->ratio <<= 8;
382 else
383 out >>= 8;
384 if (out != 0)
385 stats->ratio /= out;
386 }
387
388 /*
389 * Allocate space for a decompressor.
390 */
391 static void *
392 z_decomp_alloc(options, opt_len)
393 u_char *options;
394 int opt_len;
395 {
396 struct deflate_state *state;
397 int w_size;
398
399 if (opt_len != CILEN_DEFLATE
400 || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
401 || options[1] != CILEN_DEFLATE
402 || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
403 || options[3] != DEFLATE_CHK_SEQUENCE)
404 return NULL;
405 w_size = DEFLATE_SIZE(options[2]);
406 if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
407 return NULL;
408
409 MALLOC(state, struct deflate_state *, sizeof(struct deflate_state),
410 M_DEVBUF, M_NOWAIT);
411 if (state == NULL)
412 return NULL;
413
414 state->strm.next_out = NULL;
415 state->strm.zalloc = z_alloc;
416 state->strm.zfree = z_free;
417 if (inflateInit2(&state->strm, -w_size) != Z_OK) {
418 FREE(state, M_DEVBUF);
419 return NULL;
420 }
421
422 state->w_size = w_size;
423 bzero(&state->stats, sizeof(state->stats));
424 return (void *) state;
425 }
426
427 static void
428 z_decomp_free(arg)
429 void *arg;
430 {
431 struct deflate_state *state = (struct deflate_state *) arg;
432
433 inflateEnd(&state->strm);
434 FREE(state, M_DEVBUF);
435 }
436
437 static int
438 z_decomp_init(arg, options, opt_len, unit, hdrlen, mru, debug)
439 void *arg;
440 u_char *options;
441 int opt_len, unit, hdrlen, mru, debug;
442 {
443 struct deflate_state *state = (struct deflate_state *) arg;
444
445 if (opt_len < CILEN_DEFLATE
446 || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
447 || options[1] != CILEN_DEFLATE
448 || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
449 || DEFLATE_SIZE(options[2]) != state->w_size
450 || options[3] != DEFLATE_CHK_SEQUENCE)
451 return 0;
452
453 state->seqno = 0;
454 state->unit = unit;
455 state->hdrlen = hdrlen;
456 state->debug = debug;
457 state->mru = mru;
458
459 inflateReset(&state->strm);
460
461 return 1;
462 }
463
464 static void
465 z_decomp_reset(arg)
466 void *arg;
467 {
468 struct deflate_state *state = (struct deflate_state *) arg;
469
470 state->seqno = 0;
471 inflateReset(&state->strm);
472 }
473
474 /*
475 * Decompress a Deflate-compressed packet.
476 *
477 * Because of patent problems, we return DECOMP_ERROR for errors
478 * found by inspecting the input data and for system problems, but
479 * DECOMP_FATALERROR for any errors which could possibly be said to
480 * be being detected "after" decompression. For DECOMP_ERROR,
481 * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
482 * infringing a patent of Motorola's if we do, so we take CCP down
483 * instead.
484 *
485 * Given that the frame has the correct sequence number and a good FCS,
486 * errors such as invalid codes in the input most likely indicate a
487 * bug, so we return DECOMP_FATALERROR for them in order to turn off
488 * compression, even though they are detected by inspecting the input.
489 */
490 int
491 z_decompress(arg, mi, mop)
492 void *arg;
493 struct mbuf *mi, **mop;
494 {
495 struct deflate_state *state = (struct deflate_state *) arg;
496 struct mbuf *mo, *mo_head;
497 u_char *rptr, *wptr;
498 int rlen, olen, ospace;
499 int seq, i, flush, r, decode_proto;
500 u_char hdr[PPP_HDRLEN + DEFLATE_OVHD];
501
502 *mop = NULL;
503 rptr = mtod(mi, u_char *);
504 rlen = mi->m_len;
505 for (i = 0; i < PPP_HDRLEN + DEFLATE_OVHD; ++i) {
506 while (rlen <= 0) {
507 mi = mi->m_next;
508 if (mi == NULL)
509 return DECOMP_ERROR;
510 rptr = mtod(mi, u_char *);
511 rlen = mi->m_len;
512 }
513 hdr[i] = *rptr++;
514 --rlen;
515 }
516
517 /* Check the sequence number. */
518 seq = (hdr[PPP_HDRLEN] << 8) + hdr[PPP_HDRLEN+1];
519 if (seq != state->seqno) {
520 if (state->debug)
521 printf("z_decompress%d: bad seq # %d, expected %d\n",
522 state->unit, seq, state->seqno);
523 return DECOMP_ERROR;
524 }
525 ++state->seqno;
526
527 /* Allocate an output mbuf. */
528 MGETHDR(mo, M_DONTWAIT, MT_DATA);
529 if (mo == NULL)
530 return DECOMP_ERROR;
531 mo_head = mo;
532 mo->m_len = 0;
533 mo->m_next = NULL;
534 MCLGET(mo, M_DONTWAIT);
535 ospace = M_TRAILINGSPACE(mo);
536 if (state->hdrlen + PPP_HDRLEN < ospace) {
537 mo->m_data += state->hdrlen;
538 ospace -= state->hdrlen;
539 }
540
541 /*
542 * Fill in the first part of the PPP header. The protocol field
543 * comes from the decompressed data.
544 */
545 wptr = mtod(mo, u_char *);
546 wptr[0] = PPP_ADDRESS(hdr);
547 wptr[1] = PPP_CONTROL(hdr);
548 wptr[2] = 0;
549
550 /*
551 * Set up to call inflate. We set avail_out to 1 initially so we can
552 * look at the first byte of the output and decide whether we have
553 * a 1-byte or 2-byte protocol field.
554 */
555 state->strm.next_in = rptr;
556 state->strm.avail_in = rlen;
557 mi = mi->m_next;
558 flush = (mi == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH;
559 rlen += PPP_HDRLEN + DEFLATE_OVHD;
560 state->strm.next_out = wptr + 3;
561 state->strm.avail_out = 1;
562 decode_proto = 1;
563 olen = PPP_HDRLEN;
564
565 /*
566 * Call inflate, supplying more input or output as needed.
567 */
568 for (;;) {
569 r = inflate(&state->strm, flush);
570 if (r != Z_OK) {
571 #if !DEFLATE_DEBUG
572 if (state->debug)
573 #endif
574 printf("z_decompress%d: inflate returned %d (%s)\n",
575 state->unit, r, (state->strm.msg? state->strm.msg: ""));
576 m_freem(mo_head);
577 return DECOMP_FATALERROR;
578 }
579 if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
580 break; /* all done */
581 if (state->strm.avail_in == 0 && mi != NULL) {
582 state->strm.next_in = mtod(mi, u_char *);
583 state->strm.avail_in = mi->m_len;
584 rlen += mi->m_len;
585 mi = mi->m_next;
586 if (mi == NULL)
587 flush = Z_PACKET_FLUSH;
588 }
589 if (state->strm.avail_out == 0) {
590 if (decode_proto) {
591 state->strm.avail_out = ospace - PPP_HDRLEN;
592 if ((wptr[3] & 1) == 0) {
593 /* 2-byte protocol field */
594 wptr[2] = wptr[3];
595 --state->strm.next_out;
596 ++state->strm.avail_out;
597 --olen;
598 }
599 decode_proto = 0;
600 } else {
601 mo->m_len = ospace;
602 olen += ospace;
603 MGET(mo->m_next, M_DONTWAIT, MT_DATA);
604 mo = mo->m_next;
605 if (mo == NULL) {
606 m_freem(mo_head);
607 return DECOMP_ERROR;
608 }
609 MCLGET(mo, M_DONTWAIT);
610 state->strm.next_out = mtod(mo, u_char *);
611 state->strm.avail_out = ospace = M_TRAILINGSPACE(mo);
612 }
613 }
614 }
615 if (decode_proto) {
616 m_freem(mo_head);
617 return DECOMP_ERROR;
618 }
619 olen += (mo->m_len = ospace - state->strm.avail_out);
620 #if DEFLATE_DEBUG
621 if (state->debug && olen > state->mru + PPP_HDRLEN)
622 printf("ppp_deflate%d: exceeded mru (%d > %d)\n",
623 state->unit, olen, state->mru + PPP_HDRLEN);
624 #endif
625
626 state->stats.unc_bytes += olen;
627 state->stats.unc_packets++;
628 state->stats.comp_bytes += rlen;
629 state->stats.comp_packets++;
630
631 *mop = mo_head;
632 return DECOMP_OK;
633 }
634
635 /*
636 * Incompressible data has arrived - add it to the history.
637 */
638 static void
639 z_incomp(arg, mi)
640 void *arg;
641 struct mbuf *mi;
642 {
643 struct deflate_state *state = (struct deflate_state *) arg;
644 u_char *rptr;
645 int rlen, proto, r;
646
647 /*
648 * Check that the protocol is one we handle.
649 */
650 rptr = mtod(mi, u_char *);
651 proto = PPP_PROTOCOL(rptr);
652 if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
653 return;
654
655 ++state->seqno;
656
657 /*
658 * Iterate through the mbufs, adding the characters in them
659 * to the decompressor's history. For the first mbuf, we start
660 * at the either the 1st or 2nd byte of the protocol field,
661 * depending on whether the protocol value is compressible.
662 */
663 rlen = mi->m_len;
664 state->strm.next_in = rptr + 3;
665 state->strm.avail_in = rlen - 3;
666 if (proto > 0xff) {
667 --state->strm.next_in;
668 ++state->strm.avail_in;
669 }
670 for (;;) {
671 r = inflateIncomp(&state->strm);
672 if (r != Z_OK) {
673 /* gak! */
674 #if !DEFLATE_DEBUG
675 if (state->debug)
676 #endif
677 printf("z_incomp%d: inflateIncomp returned %d (%s)\n",
678 state->unit, r, (state->strm.msg? state->strm.msg: ""));
679 return;
680 }
681 mi = mi->m_next;
682 if (mi == NULL)
683 break;
684 state->strm.next_in = mtod(mi, u_char *);
685 state->strm.avail_in = mi->m_len;
686 rlen += mi->m_len;
687 }
688
689 /*
690 * Update stats.
691 */
692 state->stats.inc_bytes += rlen;
693 state->stats.inc_packets++;
694 state->stats.unc_bytes += rlen;
695 state->stats.unc_packets++;
696 }
697
698 #endif /* DO_DEFLATE */