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