1 /*
2  *  ==FILEVERSION 980319==
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 Linux kernel 1.3.X.
7  *
8  * Copyright (c) 1994 The Australian National University.
9  * All rights reserved.
10  *
11  * Permission to use, copy, modify, and distribute this software and its
12  * documentation is hereby granted, provided that the above copyright
13  * notice appears in all copies.  This software is provided without any
14  * warranty, express or implied. The Australian National University
15  * makes no representations about the suitability of this software for
16  * any purpose.
17  *
18  * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
19  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
20  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
21  * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY
22  * OF SUCH DAMAGE.
23  *
24  * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
25  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
26  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
27  * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
28  * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
29  * OR MODIFICATIONS.
30  *
31  * From: deflate.c,v 1.1 1996/01/18 03:17:48 paulus Exp
32  */
33 
34 #include <linux/module.h>
35 #include <linux/slab.h>
36 #include <linux/vmalloc.h>
37 #include <linux/init.h>
38 #include <linux/string.h>
39 
40 #include <linux/ppp_defs.h>
41 #include <linux/ppp-comp.h>
42 
43 #include <linux/zlib.h>
44 #include <asm/unaligned.h>
45 
46 /*
47  * State for a Deflate (de)compressor.
48  */
49 struct ppp_deflate_state {
50     int		seqno;
51     int		w_size;
52     int		unit;
53     int		mru;
54     int		debug;
55     z_stream	strm;
56     struct compstat stats;
57 };
58 
59 #define DEFLATE_OVHD	2		/* Deflate overhead/packet */
60 
61 static void	*z_comp_alloc(unsigned char *options, int opt_len);
62 static void	*z_decomp_alloc(unsigned char *options, int opt_len);
63 static void	z_comp_free(void *state);
64 static void	z_decomp_free(void *state);
65 static int	z_comp_init(void *state, unsigned char *options,
66 				 int opt_len,
67 				 int unit, int hdrlen, int debug);
68 static int	z_decomp_init(void *state, unsigned char *options,
69 				   int opt_len,
70 				   int unit, int hdrlen, int mru, int debug);
71 static int	z_compress(void *state, unsigned char *rptr,
72 				unsigned char *obuf,
73 				int isize, int osize);
74 static void	z_incomp(void *state, unsigned char *ibuf, int icnt);
75 static int	z_decompress(void *state, unsigned char *ibuf,
76 				int isize, unsigned char *obuf, int osize);
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 /**
82  *	z_comp_free - free the memory used by a compressor
83  *	@arg:	pointer to the private state for the compressor.
84  */
z_comp_free(void * arg)85 static void z_comp_free(void *arg)
86 {
87 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
88 
89 	if (state) {
90 		zlib_deflateEnd(&state->strm);
91 		vfree(state->strm.workspace);
92 		kfree(state);
93 	}
94 }
95 
96 /**
97  *	z_comp_alloc - allocate space for a compressor.
98  *	@options: pointer to CCP option data
99  *	@opt_len: length of the CCP option at @options.
100  *
101  *	The @options pointer points to the a buffer containing the
102  *	CCP option data for the compression being negotiated.  It is
103  *	formatted according to RFC1979, and describes the window
104  *	size that the peer is requesting that we use in compressing
105  *	data to be sent to it.
106  *
107  *	Returns the pointer to the private state for the compressor,
108  *	or NULL if we could not allocate enough memory.
109  */
z_comp_alloc(unsigned char * options,int opt_len)110 static void *z_comp_alloc(unsigned char *options, int opt_len)
111 {
112 	struct ppp_deflate_state *state;
113 	int w_size;
114 
115 	if (opt_len != CILEN_DEFLATE ||
116 	    (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) ||
117 	    options[1] != CILEN_DEFLATE ||
118 	    DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL ||
119 	    options[3] != DEFLATE_CHK_SEQUENCE)
120 		return NULL;
121 	w_size = DEFLATE_SIZE(options[2]);
122 	if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
123 		return NULL;
124 
125 	state = kzalloc(sizeof(*state),
126 						     GFP_KERNEL);
127 	if (state == NULL)
128 		return NULL;
129 
130 	state->strm.next_in   = NULL;
131 	state->w_size         = w_size;
132 	state->strm.workspace = vmalloc(zlib_deflate_workspacesize(-w_size, 8));
133 	if (state->strm.workspace == NULL)
134 		goto out_free;
135 
136 	if (zlib_deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION,
137 			 DEFLATE_METHOD_VAL, -w_size, 8, Z_DEFAULT_STRATEGY)
138 	    != Z_OK)
139 		goto out_free;
140 	return (void *) state;
141 
142 out_free:
143 	z_comp_free(state);
144 	return NULL;
145 }
146 
147 /**
148  *	z_comp_init - initialize a previously-allocated compressor.
149  *	@arg:	pointer to the private state for the compressor
150  *	@options: pointer to the CCP option data describing the
151  *		compression that was negotiated with the peer
152  *	@opt_len: length of the CCP option data at @options
153  *	@unit:	PPP unit number for diagnostic messages
154  *	@hdrlen: ignored (present for backwards compatibility)
155  *	@debug:	debug flag; if non-zero, debug messages are printed.
156  *
157  *	The CCP options described by @options must match the options
158  *	specified when the compressor was allocated.  The compressor
159  *	history is reset.  Returns 0 for failure (CCP options don't
160  *	match) or 1 for success.
161  */
z_comp_init(void * arg,unsigned char * options,int opt_len,int unit,int hdrlen,int debug)162 static int z_comp_init(void *arg, unsigned char *options, int opt_len,
163 		       int unit, int hdrlen, int debug)
164 {
165 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
166 
167 	if (opt_len < CILEN_DEFLATE ||
168 	    (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) ||
169 	    options[1] != CILEN_DEFLATE ||
170 	    DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL ||
171 	    DEFLATE_SIZE(options[2]) != state->w_size ||
172 	    options[3] != DEFLATE_CHK_SEQUENCE)
173 		return 0;
174 
175 	state->seqno = 0;
176 	state->unit  = unit;
177 	state->debug = debug;
178 
179 	zlib_deflateReset(&state->strm);
180 
181 	return 1;
182 }
183 
184 /**
185  *	z_comp_reset - reset a previously-allocated compressor.
186  *	@arg:	pointer to private state for the compressor.
187  *
188  *	This clears the history for the compressor and makes it
189  *	ready to start emitting a new compressed stream.
190  */
z_comp_reset(void * arg)191 static void z_comp_reset(void *arg)
192 {
193 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
194 
195 	state->seqno = 0;
196 	zlib_deflateReset(&state->strm);
197 }
198 
199 /**
200  *	z_compress - compress a PPP packet with Deflate compression.
201  *	@arg:	pointer to private state for the compressor
202  *	@rptr:	uncompressed packet (input)
203  *	@obuf:	compressed packet (output)
204  *	@isize:	size of uncompressed packet
205  *	@osize:	space available at @obuf
206  *
207  *	Returns the length of the compressed packet, or 0 if the
208  *	packet is incompressible.
209  */
z_compress(void * arg,unsigned char * rptr,unsigned char * obuf,int isize,int osize)210 static int z_compress(void *arg, unsigned char *rptr, unsigned char *obuf,
211 	       int isize, int osize)
212 {
213 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
214 	int r, proto, off, olen, oavail;
215 	unsigned char *wptr;
216 
217 	/*
218 	 * Check that the protocol is in the range we handle.
219 	 */
220 	proto = PPP_PROTOCOL(rptr);
221 	if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
222 		return 0;
223 
224 	/* Don't generate compressed packets which are larger than
225 	   the uncompressed packet. */
226 	if (osize > isize)
227 		osize = isize;
228 
229 	wptr = obuf;
230 
231 	/*
232 	 * Copy over the PPP header and store the 2-byte sequence number.
233 	 */
234 	wptr[0] = PPP_ADDRESS(rptr);
235 	wptr[1] = PPP_CONTROL(rptr);
236 	put_unaligned_be16(PPP_COMP, wptr + 2);
237 	wptr += PPP_HDRLEN;
238 	put_unaligned_be16(state->seqno, wptr);
239 	wptr += DEFLATE_OVHD;
240 	olen = PPP_HDRLEN + DEFLATE_OVHD;
241 	state->strm.next_out = wptr;
242 	state->strm.avail_out = oavail = osize - olen;
243 	++state->seqno;
244 
245 	off = (proto > 0xff) ? 2 : 3;	/* skip 1st proto byte if 0 */
246 	rptr += off;
247 	state->strm.next_in = rptr;
248 	state->strm.avail_in = (isize - off);
249 
250 	for (;;) {
251 		r = zlib_deflate(&state->strm, Z_PACKET_FLUSH);
252 		if (r != Z_OK) {
253 			if (state->debug)
254 				printk(KERN_ERR
255 				       "z_compress: deflate returned %d\n", r);
256 			break;
257 		}
258 		if (state->strm.avail_out == 0) {
259 			olen += oavail;
260 			state->strm.next_out = NULL;
261 			state->strm.avail_out = oavail = 1000000;
262 		} else {
263 			break;		/* all done */
264 		}
265 	}
266 	olen += oavail - state->strm.avail_out;
267 
268 	/*
269 	 * See if we managed to reduce the size of the packet.
270 	 */
271 	if (olen < isize) {
272 		state->stats.comp_bytes += olen;
273 		state->stats.comp_packets++;
274 	} else {
275 		state->stats.inc_bytes += isize;
276 		state->stats.inc_packets++;
277 		olen = 0;
278 	}
279 	state->stats.unc_bytes += isize;
280 	state->stats.unc_packets++;
281 
282 	return olen;
283 }
284 
285 /**
286  *	z_comp_stats - return compression statistics for a compressor
287  *		or decompressor.
288  *	@arg:	pointer to private space for the (de)compressor
289  *	@stats:	pointer to a struct compstat to receive the result.
290  */
z_comp_stats(void * arg,struct compstat * stats)291 static void z_comp_stats(void *arg, struct compstat *stats)
292 {
293 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
294 
295 	*stats = state->stats;
296 }
297 
298 /**
299  *	z_decomp_free - Free the memory used by a decompressor.
300  *	@arg:	pointer to private space for the decompressor.
301  */
z_decomp_free(void * arg)302 static void z_decomp_free(void *arg)
303 {
304 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
305 
306 	if (state) {
307 		zlib_inflateEnd(&state->strm);
308 		vfree(state->strm.workspace);
309 		kfree(state);
310 	}
311 }
312 
313 /**
314  *	z_decomp_alloc - allocate space for a decompressor.
315  *	@options: pointer to CCP option data
316  *	@opt_len: length of the CCP option at @options.
317  *
318  *	The @options pointer points to the a buffer containing the
319  *	CCP option data for the compression being negotiated.  It is
320  *	formatted according to RFC1979, and describes the window
321  *	size that we are requesting the peer to use in compressing
322  *	data to be sent to us.
323  *
324  *	Returns the pointer to the private state for the decompressor,
325  *	or NULL if we could not allocate enough memory.
326  */
z_decomp_alloc(unsigned char * options,int opt_len)327 static void *z_decomp_alloc(unsigned char *options, int opt_len)
328 {
329 	struct ppp_deflate_state *state;
330 	int w_size;
331 
332 	if (opt_len != CILEN_DEFLATE ||
333 	    (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) ||
334 	    options[1] != CILEN_DEFLATE ||
335 	    DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL ||
336 	    options[3] != DEFLATE_CHK_SEQUENCE)
337 		return NULL;
338 	w_size = DEFLATE_SIZE(options[2]);
339 	if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
340 		return NULL;
341 
342 	state = kzalloc(sizeof(*state), GFP_KERNEL);
343 	if (state == NULL)
344 		return NULL;
345 
346 	state->w_size         = w_size;
347 	state->strm.next_out  = NULL;
348 	state->strm.workspace = vmalloc(zlib_inflate_workspacesize());
349 	if (state->strm.workspace == NULL)
350 		goto out_free;
351 
352 	if (zlib_inflateInit2(&state->strm, -w_size) != Z_OK)
353 		goto out_free;
354 	return (void *) state;
355 
356 out_free:
357 	z_decomp_free(state);
358 	return NULL;
359 }
360 
361 /**
362  *	z_decomp_init - initialize a previously-allocated decompressor.
363  *	@arg:	pointer to the private state for the decompressor
364  *	@options: pointer to the CCP option data describing the
365  *		compression that was negotiated with the peer
366  *	@opt_len: length of the CCP option data at @options
367  *	@unit:	PPP unit number for diagnostic messages
368  *	@hdrlen: ignored (present for backwards compatibility)
369  *	@mru:	maximum length of decompressed packets
370  *	@debug:	debug flag; if non-zero, debug messages are printed.
371  *
372  *	The CCP options described by @options must match the options
373  *	specified when the decompressor was allocated.  The decompressor
374  *	history is reset.  Returns 0 for failure (CCP options don't
375  *	match) or 1 for success.
376  */
z_decomp_init(void * arg,unsigned char * options,int opt_len,int unit,int hdrlen,int mru,int debug)377 static int z_decomp_init(void *arg, unsigned char *options, int opt_len,
378 			 int unit, int hdrlen, int mru, int debug)
379 {
380 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
381 
382 	if (opt_len < CILEN_DEFLATE ||
383 	    (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) ||
384 	    options[1] != CILEN_DEFLATE ||
385 	    DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL ||
386 	    DEFLATE_SIZE(options[2]) != state->w_size ||
387 	    options[3] != DEFLATE_CHK_SEQUENCE)
388 		return 0;
389 
390 	state->seqno = 0;
391 	state->unit  = unit;
392 	state->debug = debug;
393 	state->mru   = mru;
394 
395 	zlib_inflateReset(&state->strm);
396 
397 	return 1;
398 }
399 
400 /**
401  *	z_decomp_reset - reset a previously-allocated decompressor.
402  *	@arg:	pointer to private state for the decompressor.
403  *
404  *	This clears the history for the decompressor and makes it
405  *	ready to receive a new compressed stream.
406  */
z_decomp_reset(void * arg)407 static void z_decomp_reset(void *arg)
408 {
409 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
410 
411 	state->seqno = 0;
412 	zlib_inflateReset(&state->strm);
413 }
414 
415 /**
416  *	z_decompress - decompress a Deflate-compressed packet.
417  *	@arg:	pointer to private state for the decompressor
418  *	@ibuf:	pointer to input (compressed) packet data
419  *	@isize:	length of input packet
420  *	@obuf:	pointer to space for output (decompressed) packet
421  *	@osize:	amount of space available at @obuf
422  *
423  * Because of patent problems, we return DECOMP_ERROR for errors
424  * found by inspecting the input data and for system problems, but
425  * DECOMP_FATALERROR for any errors which could possibly be said to
426  * be being detected "after" decompression.  For DECOMP_ERROR,
427  * we can issue a CCP reset-request; for DECOMP_FATALERROR, we may be
428  * infringing a patent of Motorola's if we do, so we take CCP down
429  * instead.
430  *
431  * Given that the frame has the correct sequence number and a good FCS,
432  * errors such as invalid codes in the input most likely indicate a
433  * bug, so we return DECOMP_FATALERROR for them in order to turn off
434  * compression, even though they are detected by inspecting the input.
435  */
z_decompress(void * arg,unsigned char * ibuf,int isize,unsigned char * obuf,int osize)436 static int z_decompress(void *arg, unsigned char *ibuf, int isize,
437 		 unsigned char *obuf, int osize)
438 {
439 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
440 	int olen, seq, r;
441 	int decode_proto, overflow;
442 	unsigned char overflow_buf[1];
443 
444 	if (isize <= PPP_HDRLEN + DEFLATE_OVHD) {
445 		if (state->debug)
446 			printk(KERN_DEBUG "z_decompress%d: short pkt (%d)\n",
447 			       state->unit, isize);
448 		return DECOMP_ERROR;
449 	}
450 
451 	/* Check the sequence number. */
452 	seq = get_unaligned_be16(ibuf + PPP_HDRLEN);
453 	if (seq != (state->seqno & 0xffff)) {
454 		if (state->debug)
455 			printk(KERN_DEBUG "z_decompress%d: bad seq # %d, expected %d\n",
456 			       state->unit, seq, state->seqno & 0xffff);
457 		return DECOMP_ERROR;
458 	}
459 	++state->seqno;
460 
461 	/*
462 	 * Fill in the first part of the PPP header.  The protocol field
463 	 * comes from the decompressed data.
464 	 */
465 	obuf[0] = PPP_ADDRESS(ibuf);
466 	obuf[1] = PPP_CONTROL(ibuf);
467 	obuf[2] = 0;
468 
469 	/*
470 	 * Set up to call inflate.  We set avail_out to 1 initially so we can
471 	 * look at the first byte of the output and decide whether we have
472 	 * a 1-byte or 2-byte protocol field.
473 	 */
474 	state->strm.next_in = ibuf + PPP_HDRLEN + DEFLATE_OVHD;
475 	state->strm.avail_in = isize - (PPP_HDRLEN + DEFLATE_OVHD);
476 	state->strm.next_out = obuf + 3;
477 	state->strm.avail_out = 1;
478 	decode_proto = 1;
479 	overflow = 0;
480 
481 	/*
482 	 * Call inflate, supplying more input or output as needed.
483 	 */
484 	for (;;) {
485 		r = zlib_inflate(&state->strm, Z_PACKET_FLUSH);
486 		if (r != Z_OK) {
487 			if (state->debug)
488 				printk(KERN_DEBUG "z_decompress%d: inflate returned %d (%s)\n",
489 				       state->unit, r, (state->strm.msg? state->strm.msg: ""));
490 			return DECOMP_FATALERROR;
491 		}
492 		if (state->strm.avail_out != 0)
493 			break;		/* all done */
494 		if (decode_proto) {
495 			state->strm.avail_out = osize - PPP_HDRLEN;
496 			if ((obuf[3] & 1) == 0) {
497 				/* 2-byte protocol field */
498 				obuf[2] = obuf[3];
499 				--state->strm.next_out;
500 				++state->strm.avail_out;
501 			}
502 			decode_proto = 0;
503 		} else if (!overflow) {
504 			/*
505 			 * We've filled up the output buffer; the only way to
506 			 * find out whether inflate has any more characters
507 			 * left is to give it another byte of output space.
508 			 */
509 			state->strm.next_out = overflow_buf;
510 			state->strm.avail_out = 1;
511 			overflow = 1;
512 		} else {
513 			if (state->debug)
514 				printk(KERN_DEBUG "z_decompress%d: ran out of mru\n",
515 				       state->unit);
516 			return DECOMP_FATALERROR;
517 		}
518 	}
519 
520 	if (decode_proto) {
521 		if (state->debug)
522 			printk(KERN_DEBUG "z_decompress%d: didn't get proto\n",
523 			       state->unit);
524 		return DECOMP_ERROR;
525 	}
526 
527 	olen = osize + overflow - state->strm.avail_out;
528 	state->stats.unc_bytes += olen;
529 	state->stats.unc_packets++;
530 	state->stats.comp_bytes += isize;
531 	state->stats.comp_packets++;
532 
533 	return olen;
534 }
535 
536 /**
537  *	z_incomp - add incompressible input data to the history.
538  *	@arg:	pointer to private state for the decompressor
539  *	@ibuf:	pointer to input packet data
540  *	@icnt:	length of input data.
541  */
z_incomp(void * arg,unsigned char * ibuf,int icnt)542 static void z_incomp(void *arg, unsigned char *ibuf, int icnt)
543 {
544 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
545 	int proto, r;
546 
547 	/*
548 	 * Check that the protocol is one we handle.
549 	 */
550 	proto = PPP_PROTOCOL(ibuf);
551 	if (proto > 0x3fff || proto == 0xfd || proto == 0xfb)
552 		return;
553 
554 	++state->seqno;
555 
556 	/*
557 	 * We start at the either the 1st or 2nd byte of the protocol field,
558 	 * depending on whether the protocol value is compressible.
559 	 */
560 	state->strm.next_in = ibuf + 3;
561 	state->strm.avail_in = icnt - 3;
562 	if (proto > 0xff) {
563 		--state->strm.next_in;
564 		++state->strm.avail_in;
565 	}
566 
567 	r = zlib_inflateIncomp(&state->strm);
568 	if (r != Z_OK) {
569 		/* gak! */
570 		if (state->debug) {
571 			printk(KERN_DEBUG "z_incomp%d: inflateIncomp returned %d (%s)\n",
572 			       state->unit, r, (state->strm.msg? state->strm.msg: ""));
573 		}
574 		return;
575 	}
576 
577 	/*
578 	 * Update stats.
579 	 */
580 	state->stats.inc_bytes += icnt;
581 	state->stats.inc_packets++;
582 	state->stats.unc_bytes += icnt;
583 	state->stats.unc_packets++;
584 }
585 
586 /*************************************************************
587  * Module interface table
588  *************************************************************/
589 
590 /* These are in ppp_generic.c */
591 extern int  ppp_register_compressor   (struct compressor *cp);
592 extern void ppp_unregister_compressor (struct compressor *cp);
593 
594 /*
595  * Procedures exported to if_ppp.c.
596  */
597 static struct compressor ppp_deflate = {
598 	.compress_proto =	CI_DEFLATE,
599 	.comp_alloc =		z_comp_alloc,
600 	.comp_free =		z_comp_free,
601 	.comp_init =		z_comp_init,
602 	.comp_reset =		z_comp_reset,
603 	.compress =		z_compress,
604 	.comp_stat =		z_comp_stats,
605 	.decomp_alloc =		z_decomp_alloc,
606 	.decomp_free =		z_decomp_free,
607 	.decomp_init =		z_decomp_init,
608 	.decomp_reset =		z_decomp_reset,
609 	.decompress =		z_decompress,
610 	.incomp =		z_incomp,
611 	.decomp_stat =		z_comp_stats,
612 	.owner =		THIS_MODULE
613 };
614 
615 static struct compressor ppp_deflate_draft = {
616 	.compress_proto =	CI_DEFLATE_DRAFT,
617 	.comp_alloc =		z_comp_alloc,
618 	.comp_free =		z_comp_free,
619 	.comp_init =		z_comp_init,
620 	.comp_reset =		z_comp_reset,
621 	.compress =		z_compress,
622 	.comp_stat =		z_comp_stats,
623 	.decomp_alloc =		z_decomp_alloc,
624 	.decomp_free =		z_decomp_free,
625 	.decomp_init =		z_decomp_init,
626 	.decomp_reset =		z_decomp_reset,
627 	.decompress =		z_decompress,
628 	.incomp =		z_incomp,
629 	.decomp_stat =		z_comp_stats,
630 	.owner =		THIS_MODULE
631 };
632 
deflate_init(void)633 static int __init deflate_init(void)
634 {
635         int answer = ppp_register_compressor(&ppp_deflate);
636         if (answer == 0)
637                 printk(KERN_INFO
638 		       "PPP Deflate Compression module registered\n");
639 	ppp_register_compressor(&ppp_deflate_draft);
640         return answer;
641 }
642 
deflate_cleanup(void)643 static void __exit deflate_cleanup(void)
644 {
645 	ppp_unregister_compressor(&ppp_deflate);
646 	ppp_unregister_compressor(&ppp_deflate_draft);
647 }
648 
649 module_init(deflate_init);
650 module_exit(deflate_cleanup);
651 MODULE_LICENSE("Dual BSD/GPL");
652 MODULE_ALIAS("ppp-compress-" __stringify(CI_DEFLATE));
653 MODULE_ALIAS("ppp-compress-" __stringify(CI_DEFLATE_DRAFT));
654