1 /* $NetBSD: deflate.c,v 1.1.1.1 2005/02/20 10:28:54 cube Exp $ */
4 * ppp_deflate.c - interface the zlib procedures for Deflate compression
5 * and decompression (as used by gzip) to the PPP code.
7 * Copyright (c) 1994 Paul Mackerras. All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
21 * 3. The name(s) of the authors of this software must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission.
25 * 4. Redistributions of any form whatsoever must retain the following
27 * "This product includes software developed by Paul Mackerras
28 * <paulus@samba.org>".
30 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
31 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
32 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
33 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
35 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
36 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
38 * Id: deflate.c,v 1.5 2004/01/17 05:47:55 carlsonj Exp
41 #include <sys/types.h>
47 #include <net/ppp_defs.h>
48 #include <net/ppp-comp.h>
53 #define DEFLATE_DEBUG 1
56 * State for a Deflate (de)compressor.
58 struct deflate_state
{
66 struct compstat stats
;
69 #define DEFLATE_OVHD 2 /* Deflate overhead/packet */
71 static void *z_alloc
__P((void *, u_int items
, u_int size
));
72 static void z_free
__P((void *, void *ptr
, u_int nb
));
73 static void *z_decomp_alloc
__P((u_char
*options
, int opt_len
));
74 static void z_decomp_free
__P((void *state
));
75 static int z_decomp_init
__P((void *state
, u_char
*options
, int opt_len
,
76 int unit
, int hdrlen
, int mru
, int debug
));
77 static void z_incomp
__P((void *state
, PACKETPTR mi
));
78 static int z_decompress
__P((void *state
, PACKETPTR mi
, PACKETPTR
*mo
));
79 static void z_decomp_reset
__P((void *state
));
80 static void z_comp_stats
__P((void *state
, struct compstat
*stats
));
83 * Procedures exported to if_ppp.c.
85 struct compressor ppp_deflate
= {
86 CI_DEFLATE
, /* compress_proto */
87 NULL
, /* comp_alloc */
90 NULL
, /* comp_reset */
91 NULL
, /* comp_compress */
93 z_decomp_alloc
, /* decomp_alloc */
94 z_decomp_free
, /* decomp_free */
95 z_decomp_init
, /* decomp_init */
96 z_decomp_reset
, /* decomp_reset */
97 z_decompress
, /* decompress */
98 z_incomp
, /* incomp */
99 z_comp_stats
, /* decomp_stat */
103 * Space allocation and freeing routines for use by zlib routines.
106 z_alloc(notused
, items
, size
)
110 return malloc(items
* size
);
114 z_free(notused
, ptr
, nbytes
)
123 z_comp_stats(arg
, stats
)
125 struct compstat
*stats
;
127 struct deflate_state
*state
= (struct deflate_state
*) arg
;
130 *stats
= state
->stats
;
131 stats
->ratio
= stats
->unc_bytes
;
132 out
= stats
->comp_bytes
+ stats
->unc_bytes
;
133 if (stats
->ratio
<= 0x7ffffff)
142 * Allocate space for a decompressor.
145 z_decomp_alloc(options
, opt_len
)
149 struct deflate_state
*state
;
152 if (opt_len
!= CILEN_DEFLATE
|| options
[0] != CI_DEFLATE
153 || options
[1] != CILEN_DEFLATE
154 || DEFLATE_METHOD(options
[2]) != DEFLATE_METHOD_VAL
155 || options
[3] != DEFLATE_CHK_SEQUENCE
)
157 w_size
= DEFLATE_SIZE(options
[2]);
158 if (w_size
< DEFLATE_MIN_SIZE
|| w_size
> DEFLATE_MAX_SIZE
)
161 state
= (struct deflate_state
*) malloc(sizeof(*state
));
165 state
->strm
.next_out
= NULL
;
166 state
->strm
.zalloc
= (alloc_func
) z_alloc
;
167 state
->strm
.zfree
= (free_func
) z_free
;
168 if (inflateInit2(&state
->strm
, -w_size
) != Z_OK
) {
173 state
->w_size
= w_size
;
174 memset(&state
->stats
, 0, sizeof(state
->stats
));
175 return (void *) state
;
182 struct deflate_state
*state
= (struct deflate_state
*) arg
;
184 inflateEnd(&state
->strm
);
189 z_decomp_init(arg
, options
, opt_len
, unit
, hdrlen
, mru
, debug
)
192 int opt_len
, unit
, hdrlen
, mru
, debug
;
194 struct deflate_state
*state
= (struct deflate_state
*) arg
;
196 if (opt_len
< CILEN_DEFLATE
|| options
[0] != CI_DEFLATE
197 || options
[1] != CILEN_DEFLATE
198 || DEFLATE_METHOD(options
[2]) != DEFLATE_METHOD_VAL
199 || DEFLATE_SIZE(options
[2]) != state
->w_size
200 || options
[3] != DEFLATE_CHK_SEQUENCE
)
205 state
->hdrlen
= hdrlen
;
206 state
->debug
= debug
;
209 inflateReset(&state
->strm
);
218 struct deflate_state
*state
= (struct deflate_state
*) arg
;
221 inflateReset(&state
->strm
);
225 * Decompress a Deflate-compressed packet.
227 * Because of patent problems, we return DECOMP_ERROR for errors
228 * found by inspecting the input data and for system problems, but
229 * DECOMP_FATALERROR for any errors which could possibly be said to
230 * be being detected "after" decompression. For DECOMP_ERROR,
231 * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
232 * infringing a patent of Motorola's if we do, so we take CCP down
235 * Given that the frame has the correct sequence number and a good FCS,
236 * errors such as invalid codes in the input most likely indicate a
237 * bug, so we return DECOMP_FATALERROR for them in order to turn off
238 * compression, even though they are detected by inspecting the input.
241 z_decompress(arg
, mi
, mo
)
246 struct deflate_state
*state
= (struct deflate_state
*) arg
;
256 /* Check the sequence number. */
257 seq
= (rptr
[0] << 8) + rptr
[1];
259 if (seq
!= state
->seqno
) {
263 printf("z_decompress%d: bad seq # %d, expected %d\n",
264 state
->unit
, seq
, state
->seqno
);
270 * Set up to call inflate.
273 state
->strm
.next_in
= rptr
;
274 state
->strm
.avail_in
= mi
->buf
+ mi
->len
- rptr
;
275 rlen
= state
->strm
.avail_in
+ PPP_HDRLEN
+ DEFLATE_OVHD
;
276 state
->strm
.next_out
= wptr
;
277 state
->strm
.avail_out
= state
->mru
+ 2;
279 r
= inflate(&state
->strm
, Z_PACKET_FLUSH
);
284 printf("z_decompress%d: inflate returned %d (%s)\n",
285 state
->unit
, r
, (state
->strm
.msg
? state
->strm
.msg
: ""));
286 return DECOMP_FATALERROR
;
288 olen
= state
->mru
+ 2 - state
->strm
.avail_out
;
291 if ((wptr
[0] & 1) != 0)
292 ++olen
; /* for suppressed protocol high byte */
293 olen
+= 2; /* for address, control */
296 if (olen
> state
->mru
+ PPP_HDRLEN
)
297 printf("ppp_deflate%d: exceeded mru (%d > %d)\n",
298 state
->unit
, olen
, state
->mru
+ PPP_HDRLEN
);
301 state
->stats
.unc_bytes
+= olen
;
302 state
->stats
.unc_packets
++;
303 state
->stats
.comp_bytes
+= rlen
;
304 state
->stats
.comp_packets
++;
310 * Incompressible data has arrived - add it to the history.
317 struct deflate_state
*state
= (struct deflate_state
*) arg
;
322 * Check that the protocol is one we handle.
326 if ((proto
& 1) == 0)
327 proto
= (proto
<< 8) + rptr
[1];
328 if (proto
> 0x3fff || proto
== 0xfd || proto
== 0xfb)
335 rlen
= mi
->buf
+ mi
->len
- rptr
;
336 state
->strm
.next_in
= rptr
;
337 state
->strm
.avail_in
= rlen
;
338 r
= inflateIncomp(&state
->strm
);
344 printf("z_incomp%d: inflateIncomp returned %d (%s)\n",
345 state
->unit
, r
, (state
->strm
.msg
? state
->strm
.msg
: ""));
355 state
->stats
.inc_bytes
+= rlen
;
356 state
->stats
.inc_packets
++;
357 state
->stats
.unc_bytes
+= rlen
;
358 state
->stats
.unc_packets
++;
361 #endif /* DO_DEFLATE */