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