|
|
1.1 root 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 __P((void *, u_int items, u_int size));
82: static void z_free __P((void *, void *ptr));
83: static void *z_comp_alloc __P((u_char *options, int opt_len));
84: static void *z_decomp_alloc __P((u_char *options, int opt_len));
85: static void z_comp_free __P((void *state));
86: static void z_decomp_free __P((void *state));
87: static int z_comp_init __P((void *state, u_char *options, int opt_len,
88: int unit, int hdrlen, int debug));
89: static int z_decomp_init __P((void *state, u_char *options, int opt_len,
90: int unit, int hdrlen, int mru, int debug));
91: static int z_compress __P((void *state, struct mbuf **mret,
92: struct mbuf *mp, int slen, int maxolen));
93: static void z_incomp __P((void *state, struct mbuf *dmsg));
94: static int z_decompress __P((void *state, struct mbuf *cmp,
95: struct mbuf **dmpp));
96: static void z_comp_reset __P((void *state));
97: static void z_decomp_reset __P((void *state));
98: static void z_comp_stats __P((void *state, struct compstat *stats));
99:
100: /*
101: * Procedures exported to if_ppp.c.
102: */
103: struct compressor ppp_deflate = {
104: CI_DEFLATE, /* compress_proto */
105: z_comp_alloc, /* comp_alloc */
106: z_comp_free, /* comp_free */
107: z_comp_init, /* comp_init */
108: z_comp_reset, /* comp_reset */
109: z_compress, /* compress */
110: z_comp_stats, /* comp_stat */
111: z_decomp_alloc, /* decomp_alloc */
112: z_decomp_free, /* decomp_free */
113: z_decomp_init, /* decomp_init */
114: z_decomp_reset, /* decomp_reset */
115: z_decompress, /* decompress */
116: z_incomp, /* incomp */
117: z_comp_stats, /* decomp_stat */
118: };
119:
120: struct compressor ppp_deflate_draft = {
121: CI_DEFLATE_DRAFT, /* compress_proto */
122: z_comp_alloc, /* comp_alloc */
123: z_comp_free, /* comp_free */
124: z_comp_init, /* comp_init */
125: z_comp_reset, /* comp_reset */
126: z_compress, /* compress */
127: z_comp_stats, /* comp_stat */
128: z_decomp_alloc, /* decomp_alloc */
129: z_decomp_free, /* decomp_free */
130: z_decomp_init, /* decomp_init */
131: z_decomp_reset, /* decomp_reset */
132: z_decompress, /* decompress */
133: z_incomp, /* incomp */
134: z_comp_stats, /* decomp_stat */
135: };
136:
137: /*
138: * Space allocation and freeing routines for use by zlib routines.
139: */
140: void *
141: z_alloc(notused, items, size)
142: void *notused;
143: u_int items, size;
144: {
145: void *ptr;
146:
147: MALLOC(ptr, void *, items * size, M_DEVBUF, M_NOWAIT);
148: return ptr;
149: }
150:
151: void
152: z_free(notused, ptr)
153: void *notused;
154: void *ptr;
155: {
156: FREE(ptr, M_DEVBUF);
157: }
158:
159: /*
160: * Allocate space for a compressor.
161: */
162: static void *
163: z_comp_alloc(options, opt_len)
164: u_char *options;
165: int opt_len;
166: {
167: struct deflate_state *state;
168: int w_size;
169:
170: if (opt_len != CILEN_DEFLATE
171: || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
172: || options[1] != CILEN_DEFLATE
173: || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
174: || options[3] != DEFLATE_CHK_SEQUENCE)
175: return NULL;
176: w_size = DEFLATE_SIZE(options[2]);
177: if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
178: return NULL;
179:
180: MALLOC(state, struct deflate_state *, sizeof(struct deflate_state),
181: M_DEVBUF, M_NOWAIT);
182: if (state == NULL)
183: return NULL;
184:
185: state->strm.next_in = NULL;
186: state->strm.zalloc = z_alloc;
187: state->strm.zfree = z_free;
188: if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION, DEFLATE_METHOD_VAL,
189: -w_size, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
190: FREE(state, M_DEVBUF);
191: return NULL;
192: }
193:
194: state->w_size = w_size;
195: bzero(&state->stats, sizeof(state->stats));
196: return (void *) state;
197: }
198:
199: static void
200: z_comp_free(arg)
201: void *arg;
202: {
203: struct deflate_state *state = (struct deflate_state *) arg;
204:
205: deflateEnd(&state->strm);
206: FREE(state, M_DEVBUF);
207: }
208:
209: static int
210: z_comp_init(arg, options, opt_len, unit, hdrlen, debug)
211: void *arg;
212: u_char *options;
213: int opt_len, unit, hdrlen, debug;
214: {
215: struct deflate_state *state = (struct deflate_state *) arg;
216:
217: if (opt_len < CILEN_DEFLATE
218: || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
219: || options[1] != CILEN_DEFLATE
220: || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
221: || DEFLATE_SIZE(options[2]) != state->w_size
222: || options[3] != DEFLATE_CHK_SEQUENCE)
223: return 0;
224:
225: state->seqno = 0;
226: state->unit = unit;
227: state->hdrlen = hdrlen;
228: state->debug = debug;
229:
230: deflateReset(&state->strm);
231:
232: return 1;
233: }
234:
235: static void
236: z_comp_reset(arg)
237: void *arg;
238: {
239: struct deflate_state *state = (struct deflate_state *) arg;
240:
241: state->seqno = 0;
242: deflateReset(&state->strm);
243: }
244:
245: int
246: z_compress(arg, mret, mp, orig_len, maxolen)
247: void *arg;
248: struct mbuf **mret; /* compressed packet (out) */
249: struct mbuf *mp; /* uncompressed packet (in) */
250: int orig_len, maxolen;
251: {
252: struct deflate_state *state = (struct deflate_state *) arg;
253: u_char *rptr, *wptr;
254: int proto, olen, wspace, r, flush;
255: struct mbuf *m;
256:
257: /*
258: * Check that the protocol is in the range we handle.
259: */
260: rptr = mtod(mp, u_char *);
261: proto = PPP_PROTOCOL(rptr);
262: if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) {
263: *mret = NULL;
264: return orig_len;
265: }
266:
267: /* Allocate one mbuf initially. */
268: if (maxolen > orig_len)
269: maxolen = orig_len;
270: MGET(m, M_DONTWAIT, MT_DATA);
271: *mret = m;
272: if (m != NULL) {
273: m->m_len = 0;
274: if (maxolen + state->hdrlen > MLEN)
275: MCLGET(m, M_DONTWAIT);
276: wspace = M_TRAILINGSPACE(m);
277: if (state->hdrlen + PPP_HDRLEN + 2 < wspace) {
278: m->m_data += state->hdrlen;
279: wspace -= state->hdrlen;
280: }
281: wptr = mtod(m, u_char *);
282:
283: /*
284: * Copy over the PPP header and store the 2-byte sequence number.
285: */
286: wptr[0] = PPP_ADDRESS(rptr);
287: wptr[1] = PPP_CONTROL(rptr);
288: wptr[2] = PPP_COMP >> 8;
289: wptr[3] = PPP_COMP;
290: wptr += PPP_HDRLEN;
291: wptr[0] = state->seqno >> 8;
292: wptr[1] = state->seqno;
293: wptr += 2;
294: state->strm.next_out = wptr;
295: state->strm.avail_out = wspace - (PPP_HDRLEN + 2);
296: } else {
297: state->strm.next_out = NULL;
298: state->strm.avail_out = 1000000;
299: wptr = NULL;
300: wspace = 0;
301: }
302: ++state->seqno;
303:
304: rptr += (proto > 0xff)? 2: 3; /* skip 1st proto byte if 0 */
305: state->strm.next_in = rptr;
306: state->strm.avail_in = mtod(mp, u_char *) + mp->m_len - rptr;
307: mp = mp->m_next;
308: flush = (mp == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH;
309: olen = 0;
310: for (;;) {
311: r = deflate(&state->strm, flush);
312: if (r != Z_OK) {
313: printf("z_compress: deflate returned %d (%s)\n",
314: r, (state->strm.msg? state->strm.msg: ""));
315: break;
316: }
317: if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
318: break; /* all done */
319: if (state->strm.avail_in == 0 && mp != NULL) {
320: state->strm.next_in = mtod(mp, u_char *);
321: state->strm.avail_in = mp->m_len;
322: mp = mp->m_next;
323: if (mp == NULL)
324: flush = Z_PACKET_FLUSH;
325: }
326: if (state->strm.avail_out == 0) {
327: if (m != NULL) {
328: m->m_len = wspace;
329: olen += wspace;
330: MGET(m->m_next, M_DONTWAIT, MT_DATA);
331: m = m->m_next;
332: if (m != NULL) {
333: m->m_len = 0;
334: if (maxolen - olen > MLEN)
335: MCLGET(m, M_DONTWAIT);
336: state->strm.next_out = mtod(m, u_char *);
337: state->strm.avail_out = wspace = M_TRAILINGSPACE(m);
338: }
339: }
340: if (m == NULL) {
341: state->strm.next_out = NULL;
342: state->strm.avail_out = 1000000;
343: }
344: }
345: }
346: if (m != NULL)
347: olen += (m->m_len = wspace - state->strm.avail_out);
348:
349: /*
350: * See if we managed to reduce the size of the packet.
351: */
352: if (m != NULL && olen < orig_len) {
353: state->stats.comp_bytes += olen;
354: state->stats.comp_packets++;
355: } else {
356: if (*mret != NULL) {
357: m_freem(*mret);
358: *mret = NULL;
359: }
360: state->stats.inc_bytes += orig_len;
361: state->stats.inc_packets++;
362: olen = orig_len;
363: }
364: state->stats.unc_bytes += orig_len;
365: state->stats.unc_packets++;
366:
367: return olen;
368: }
369:
370: static void
371: z_comp_stats(arg, stats)
372: void *arg;
373: struct compstat *stats;
374: {
375: struct deflate_state *state = (struct deflate_state *) arg;
376: u_int out;
377:
378: *stats = state->stats;
379: stats->ratio = stats->unc_bytes;
380: out = stats->comp_bytes + stats->inc_bytes;
381: if (stats->ratio <= 0x7ffffff)
382: stats->ratio <<= 8;
383: else
384: out >>= 8;
385: if (out != 0)
386: stats->ratio /= out;
387: }
388:
389: /*
390: * Allocate space for a decompressor.
391: */
392: static void *
393: z_decomp_alloc(options, opt_len)
394: u_char *options;
395: int opt_len;
396: {
397: struct deflate_state *state;
398: int w_size;
399:
400: if (opt_len != CILEN_DEFLATE
401: || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
402: || options[1] != CILEN_DEFLATE
403: || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
404: || options[3] != DEFLATE_CHK_SEQUENCE)
405: return NULL;
406: w_size = DEFLATE_SIZE(options[2]);
407: if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
408: return NULL;
409:
410: MALLOC(state, struct deflate_state *, sizeof(struct deflate_state),
411: M_DEVBUF, M_NOWAIT);
412: if (state == NULL)
413: return NULL;
414:
415: state->strm.next_out = NULL;
416: state->strm.zalloc = z_alloc;
417: state->strm.zfree = z_free;
418: if (inflateInit2(&state->strm, -w_size) != Z_OK) {
419: FREE(state, M_DEVBUF);
420: return NULL;
421: }
422:
423: state->w_size = w_size;
424: bzero(&state->stats, sizeof(state->stats));
425: return (void *) state;
426: }
427:
428: static void
429: z_decomp_free(arg)
430: void *arg;
431: {
432: struct deflate_state *state = (struct deflate_state *) arg;
433:
434: inflateEnd(&state->strm);
435: FREE(state, M_DEVBUF);
436: }
437:
438: static int
439: z_decomp_init(arg, options, opt_len, unit, hdrlen, mru, debug)
440: void *arg;
441: u_char *options;
442: int opt_len, unit, hdrlen, mru, debug;
443: {
444: struct deflate_state *state = (struct deflate_state *) arg;
445:
446: if (opt_len < CILEN_DEFLATE
447: || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
448: || options[1] != CILEN_DEFLATE
449: || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
450: || DEFLATE_SIZE(options[2]) != state->w_size
451: || options[3] != DEFLATE_CHK_SEQUENCE)
452: return 0;
453:
454: state->seqno = 0;
455: state->unit = unit;
456: state->hdrlen = hdrlen;
457: state->debug = debug;
458: state->mru = mru;
459:
460: inflateReset(&state->strm);
461:
462: return 1;
463: }
464:
465: static void
466: z_decomp_reset(arg)
467: void *arg;
468: {
469: struct deflate_state *state = (struct deflate_state *) arg;
470:
471: state->seqno = 0;
472: inflateReset(&state->strm);
473: }
474:
475: /*
476: * Decompress a Deflate-compressed packet.
477: *
478: * Because of patent problems, we return DECOMP_ERROR for errors
479: * found by inspecting the input data and for system problems, but
480: * DECOMP_FATALERROR for any errors which could possibly be said to
481: * be being detected "after" decompression. For DECOMP_ERROR,
482: * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
483: * infringing a patent of Motorola's if we do, so we take CCP down
484: * instead.
485: *
486: * Given that the frame has the correct sequence number and a good FCS,
487: * errors such as invalid codes in the input most likely indicate a
488: * bug, so we return DECOMP_FATALERROR for them in order to turn off
489: * compression, even though they are detected by inspecting the input.
490: */
491: int
492: z_decompress(arg, mi, mop)
493: void *arg;
494: struct mbuf *mi, **mop;
495: {
496: struct deflate_state *state = (struct deflate_state *) arg;
497: struct mbuf *mo, *mo_head;
498: u_char *rptr, *wptr;
499: int rlen, olen, ospace;
500: int seq, i, flush, r, decode_proto;
501: u_char hdr[PPP_HDRLEN + DEFLATE_OVHD];
502:
503: *mop = NULL;
504: rptr = mtod(mi, u_char *);
505: rlen = mi->m_len;
506: for (i = 0; i < PPP_HDRLEN + DEFLATE_OVHD; ++i) {
507: while (rlen <= 0) {
508: mi = mi->m_next;
509: if (mi == NULL)
510: return DECOMP_ERROR;
511: rptr = mtod(mi, u_char *);
512: rlen = mi->m_len;
513: }
514: hdr[i] = *rptr++;
515: --rlen;
516: }
517:
518: /* Check the sequence number. */
519: seq = (hdr[PPP_HDRLEN] << 8) + hdr[PPP_HDRLEN+1];
520: if (seq != state->seqno) {
521: if (state->debug)
522: printf("z_decompress%d: bad seq # %d, expected %d\n",
523: state->unit, seq, state->seqno);
524: return DECOMP_ERROR;
525: }
526: ++state->seqno;
527:
528: /* Allocate an output mbuf. */
529: MGETHDR(mo, M_DONTWAIT, MT_DATA);
530: if (mo == NULL)
531: return DECOMP_ERROR;
532: mo_head = mo;
533: mo->m_len = 0;
534: mo->m_next = NULL;
535: MCLGET(mo, M_DONTWAIT);
536: ospace = M_TRAILINGSPACE(mo);
537: if (state->hdrlen + PPP_HDRLEN < ospace) {
538: mo->m_data += state->hdrlen;
539: ospace -= state->hdrlen;
540: }
541:
542: /*
543: * Fill in the first part of the PPP header. The protocol field
544: * comes from the decompressed data.
545: */
546: wptr = mtod(mo, u_char *);
547: wptr[0] = PPP_ADDRESS(hdr);
548: wptr[1] = PPP_CONTROL(hdr);
549: wptr[2] = 0;
550:
551: /*
552: * Set up to call inflate. We set avail_out to 1 initially so we can
553: * look at the first byte of the output and decide whether we have
554: * a 1-byte or 2-byte protocol field.
555: */
556: state->strm.next_in = rptr;
557: state->strm.avail_in = rlen;
558: mi = mi->m_next;
559: flush = (mi == NULL)? Z_PACKET_FLUSH: Z_NO_FLUSH;
560: rlen += PPP_HDRLEN + DEFLATE_OVHD;
561: state->strm.next_out = wptr + 3;
562: state->strm.avail_out = 1;
563: decode_proto = 1;
564: olen = PPP_HDRLEN;
565:
566: /*
567: * Call inflate, supplying more input or output as needed.
568: */
569: for (;;) {
570: r = inflate(&state->strm, flush);
571: if (r != Z_OK) {
572: #if !DEFLATE_DEBUG
573: if (state->debug)
574: #endif
575: printf("z_decompress%d: inflate returned %d (%s)\n",
576: state->unit, r, (state->strm.msg? state->strm.msg: ""));
577: m_freem(mo_head);
578: return DECOMP_FATALERROR;
579: }
580: if (flush != Z_NO_FLUSH && state->strm.avail_out != 0)
581: break; /* all done */
582: if (state->strm.avail_in == 0 && mi != NULL) {
583: state->strm.next_in = mtod(mi, u_char *);
584: state->strm.avail_in = mi->m_len;
585: rlen += mi->m_len;
586: mi = mi->m_next;
587: if (mi == NULL)
588: flush = Z_PACKET_FLUSH;
589: }
590: if (state->strm.avail_out == 0) {
591: if (decode_proto) {
592: state->strm.avail_out = ospace - PPP_HDRLEN;
593: if ((wptr[3] & 1) == 0) {
594: /* 2-byte protocol field */
595: wptr[2] = wptr[3];
596: --state->strm.next_out;
597: ++state->strm.avail_out;
598: --olen;
599: }
600: decode_proto = 0;
601: } else {
602: mo->m_len = ospace;
603: olen += ospace;
604: MGET(mo->m_next, M_DONTWAIT, MT_DATA);
605: mo = mo->m_next;
606: if (mo == NULL) {
607: m_freem(mo_head);
608: return DECOMP_ERROR;
609: }
610: MCLGET(mo, M_DONTWAIT);
611: state->strm.next_out = mtod(mo, u_char *);
612: state->strm.avail_out = ospace = M_TRAILINGSPACE(mo);
613: }
614: }
615: }
616: if (decode_proto) {
617: m_freem(mo_head);
618: return DECOMP_ERROR;
619: }
620: olen += (mo->m_len = ospace - state->strm.avail_out);
621: #if DEFLATE_DEBUG
622: if (state->debug && olen > state->mru + PPP_HDRLEN)
623: printf("ppp_deflate%d: exceeded mru (%d > %d)\n",
624: state->unit, olen, state->mru + PPP_HDRLEN);
625: #endif
626:
627: state->stats.unc_bytes += olen;
628: state->stats.unc_packets++;
629: state->stats.comp_bytes += rlen;
630: state->stats.comp_packets++;
631:
632: *mop = mo_head;
633: return DECOMP_OK;
634: }
635:
636: /*
637: * Incompressible data has arrived - add it to the history.
638: */
639: static void
640: z_incomp(arg, mi)
641: void *arg;
642: struct mbuf *mi;
643: {
644: struct deflate_state *state = (struct deflate_state *) arg;
645: u_char *rptr;
646: int rlen, proto, r;
647:
648: /*
649: * Check that the protocol is one we handle.
650: */
651: rptr = mtod(mi, u_char *);
652: proto = PPP_PROTOCOL(rptr);
653: if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
654: return;
655:
656: ++state->seqno;
657:
658: /*
659: * Iterate through the mbufs, adding the characters in them
660: * to the decompressor's history. For the first mbuf, we start
661: * at the either the 1st or 2nd byte of the protocol field,
662: * depending on whether the protocol value is compressible.
663: */
664: rlen = mi->m_len;
665: state->strm.next_in = rptr + 3;
666: state->strm.avail_in = rlen - 3;
667: if (proto > 0xff) {
668: --state->strm.next_in;
669: ++state->strm.avail_in;
670: }
671: for (;;) {
672: r = inflateIncomp(&state->strm);
673: if (r != Z_OK) {
674: /* gak! */
675: #if !DEFLATE_DEBUG
676: if (state->debug)
677: #endif
678: printf("z_incomp%d: inflateIncomp returned %d (%s)\n",
679: state->unit, r, (state->strm.msg? state->strm.msg: ""));
680: return;
681: }
682: mi = mi->m_next;
683: if (mi == NULL)
684: break;
685: state->strm.next_in = mtod(mi, u_char *);
686: state->strm.avail_in = mi->m_len;
687: rlen += mi->m_len;
688: }
689:
690: /*
691: * Update stats.
692: */
693: state->stats.inc_bytes += rlen;
694: state->stats.inc_packets++;
695: state->stats.unc_bytes += rlen;
696: state->stats.unc_packets++;
697: }
698:
699: #endif /* DO_DEFLATE */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.