]> git.ozlabs.org Git - ppp.git/blob - linux/mppe/ppp_mppe_compress.c
Run ntlm_auth as the user that invoked pppd.
[ppp.git] / linux / mppe / ppp_mppe_compress.c
1 /*
2  * ppp_mppe_compress.c - interface MPPE to the PPP code.
3  * This version is for use with Linux kernel 2.2.19+, 2.4.18+ and 2.6.2+.
4  *
5  * By Frank Cusack <frank@google.com>.
6  * Copyright (c) 2002,2003,2004 Google, Inc.
7  * All rights reserved.
8  *
9  * Permission to use, copy, modify, and distribute this software and its
10  * documentation is hereby granted, provided that the above copyright
11  * notice appears in all copies.  This software is provided without any
12  * warranty, express or implied.
13  *
14  * Changelog:
15  *      2/15/04 - TS: added #include <version.h> and testing for Kernel
16  *                    version before using 
17  *                    MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
18  *                    deprecated in 2.6
19  */
20
21 #include <linux/module.h>
22 #include <linux/kernel.h>
23 #include <linux/version.h>
24 #include <linux/init.h>
25 #include <linux/types.h>
26 #include <linux/slab.h>
27 #include <linux/string.h>
28
29 #include <linux/ppp_defs.h>
30 #include <linux/ppp-comp.h>
31
32 #include "arcfour.h"
33 #include "sha1.h"
34
35 /*
36  * State for an MPPE (de)compressor.
37  */
38 typedef struct ppp_mppe_state {
39     unsigned char       master_key[MPPE_MAX_KEY_LEN];
40     unsigned char       session_key[MPPE_MAX_KEY_LEN];
41     arcfour_context     arcfour_context; /* encryption state */
42     unsigned            keylen;         /* key length in bytes             */
43                                         /* NB: 128-bit == 16, 40-bit == 8! */
44                                         /* If we want to support 56-bit,   */
45                                         /* the unit has to change to bits  */
46     unsigned char       bits;           /* MPPE control bits */
47     unsigned            ccount;         /* 12-bit coherency count (seqno)  */
48     unsigned            stateful;       /* stateful mode flag */
49     int                 discard;        /* stateful mode packet loss flag */
50     int                 sanity_errors;  /* take down LCP if too many */
51     int                 unit;
52     int                 debug;
53     struct compstat     stats;
54 } ppp_mppe_state;
55
56 /* ppp_mppe_state.bits definitions */
57 #define MPPE_BIT_A      0x80    /* Encryption table were (re)inititalized */
58 #define MPPE_BIT_B      0x40    /* MPPC only (not implemented) */
59 #define MPPE_BIT_C      0x20    /* MPPC only (not implemented) */
60 #define MPPE_BIT_D      0x10    /* This is an encrypted frame */
61
62 #define MPPE_BIT_FLUSHED        MPPE_BIT_A
63 #define MPPE_BIT_ENCRYPTED      MPPE_BIT_D
64
65 #define MPPE_BITS(p) ((p)[4] & 0xf0)
66 #define MPPE_CCOUNT(p) ((((p)[4] & 0x0f) << 8) + (p)[5])
67 #define MPPE_CCOUNT_SPACE 0x1000        /* The size of the ccount space */
68
69 #define MPPE_OVHD       2               /* MPPE overhead/packet */
70 #define SANITY_MAX      1600            /* Max bogon factor we will tolerate */
71
72 static void     GetNewKeyFromSHA __P((unsigned char *StartKey,
73                                       unsigned char *SessionKey,
74                                       unsigned SessionKeyLength,
75                                       unsigned char *InterimKey));
76 static void     mppe_rekey __P((ppp_mppe_state *state, int));
77 static void     *mppe_alloc __P((unsigned char *options, int optlen));
78 static void     mppe_free __P((void *state));
79 static int      mppe_init __P((void *state, unsigned char *options,
80                                int optlen, int unit, int debug, const char *));
81 static int      mppe_comp_init __P((void *state, unsigned char *options,
82                                     int optlen,
83                                     int unit, int hdrlen, int debug));
84 static int      mppe_decomp_init __P((void *state, unsigned char *options,
85                                       int optlen, int unit,
86                                       int hdrlen, int mru, int debug));
87 static int      mppe_compress __P((void *state, unsigned char *ibuf,
88                                    unsigned char *obuf,
89                                    int isize, int osize));
90 static void     mppe_incomp __P((void *state, unsigned char *ibuf, int icnt));
91 static int      mppe_decompress __P((void *state, unsigned char *ibuf,
92                                      int isize, unsigned char *obuf,int osize));
93 static void     mppe_comp_reset __P((void *state));
94 static void     mppe_decomp_reset __P((void *state));
95 static void     mppe_comp_stats __P((void *state, struct compstat *stats));
96
97
98 /*
99  * Key Derivation, from RFC 3078, RFC 3079.
100  * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
101  */
102 static void
103 GetNewKeyFromSHA(unsigned char *MasterKey, unsigned char *SessionKey,
104                  unsigned SessionKeyLength, unsigned char *InterimKey)
105 {
106     SHA1_CTX Context;
107     unsigned char Digest[SHA1_SIGNATURE_SIZE];
108
109     unsigned char SHApad1[40] =
110     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
114     unsigned char SHApad2[40] =
115     { 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
116       0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
117       0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
118       0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 };
119
120     /* assert(SessionKeyLength <= SHA1_SIGNATURE_SIZE); */
121
122     SHA1_Init(&Context);
123     SHA1_Update(&Context, MasterKey, SessionKeyLength);
124     SHA1_Update(&Context, SHApad1, sizeof(SHApad1));
125     SHA1_Update(&Context, SessionKey, SessionKeyLength);
126     SHA1_Update(&Context, SHApad2, sizeof(SHApad2));
127     SHA1_Final(Digest, &Context);
128
129     memcpy(InterimKey, Digest, SessionKeyLength);
130 }
131
132 /*
133  * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3.
134  * Well, not what's written there, but rather what they meant.
135  */
136 static void
137 mppe_rekey(ppp_mppe_state *state, int initial_key)
138 {
139     unsigned char InterimKey[MPPE_MAX_KEY_LEN];
140
141     GetNewKeyFromSHA(state->master_key, state->session_key,
142                      state->keylen, InterimKey);
143     if (!initial_key) {
144         arcfour_setkey(&state->arcfour_context, InterimKey, state->keylen);
145         arcfour_encrypt(&state->arcfour_context, InterimKey, state->keylen,
146                         state->session_key);
147     } else {
148         memcpy(state->session_key, InterimKey, state->keylen);
149     }
150     if (state->keylen == 8) {
151         /* See RFC 3078 */
152         state->session_key[0] = 0xd1;
153         state->session_key[1] = 0x26;
154         state->session_key[2] = 0x9e;
155     }
156     arcfour_setkey(&state->arcfour_context, state->session_key, state->keylen);
157 }
158
159
160 /*
161  * Allocate space for a (de)compressor.
162  */
163 static void *
164 mppe_alloc(unsigned char *options, int optlen)
165 {
166     ppp_mppe_state *state;
167
168     if (optlen != CILEN_MPPE + sizeof(state->master_key)
169         || options[0] != CI_MPPE
170         || options[1] != CILEN_MPPE)
171         return NULL;
172
173     state = (ppp_mppe_state *) kmalloc(sizeof(*state), GFP_KERNEL);
174     if (state == NULL)
175         return NULL;
176
177 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
178     try_module_get(THIS_MODULE);
179 #else
180     MOD_INC_USE_COUNT;
181 #endif
182     memset(state, 0, sizeof(*state));
183
184     /* Save keys. */
185     memcpy(state->master_key, &options[CILEN_MPPE], sizeof(state->master_key));
186     memcpy(state->session_key, state->master_key, sizeof(state->master_key));
187     /*
188      * We defer initial key generation until mppe_init(), as mppe_alloc()
189      * is called frequently during negotiation.
190      */
191
192     return (void *) state;
193 }
194
195 /*
196  * Deallocate space for a (de)compressor.
197  */
198 static void
199 mppe_free(void *arg)
200 {
201     ppp_mppe_state *state = (ppp_mppe_state *) arg;
202
203     if (state) {
204         kfree(state);
205 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
206         module_put(THIS_MODULE);
207 #else
208         MOD_DEC_USE_COUNT;
209 #endif
210     }
211 }
212
213
214 /* 
215  * Initialize (de)compressor state.
216  */
217 static int
218 mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug,
219           const char *debugstr)
220 {
221     ppp_mppe_state *state = (ppp_mppe_state *) arg;
222     unsigned char mppe_opts;
223
224     if (optlen != CILEN_MPPE
225         || options[0] != CI_MPPE
226         || options[1] != CILEN_MPPE)
227         return 0;
228
229     MPPE_CI_TO_OPTS(&options[2], mppe_opts);
230     if (mppe_opts & MPPE_OPT_128)
231         state->keylen = 16;
232     else if (mppe_opts & MPPE_OPT_40)
233         state->keylen = 8;
234     else {
235         printk(KERN_WARNING "%s[%d]: unknown key length\n", debugstr, unit);
236         return 0;
237     }
238     if (mppe_opts & MPPE_OPT_STATEFUL)
239         state->stateful = 1;
240
241     /* Generate the initial session key. */
242     mppe_rekey(state, 1);
243
244     if (debug) {
245         int i;
246         char mkey[sizeof(state->master_key) * 2 + 1];
247         char skey[sizeof(state->session_key) * 2 + 1];
248
249         printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n", debugstr,
250                unit, (state->keylen == 16)? 128: 40,
251                (state->stateful)? "stateful": "stateless");
252
253         for (i = 0; i < sizeof(state->master_key); i++)
254             sprintf(mkey + i * 2, "%.2x", state->master_key[i]);
255         for (i = 0; i < sizeof(state->session_key); i++)
256             sprintf(skey + i * 2, "%.2x", state->session_key[i]);
257         printk(KERN_DEBUG "%s[%d]: keys: master: %s initial session: %s\n",
258                debugstr, unit, mkey, skey);
259     }
260
261     /*
262      * Initialize the coherency count.  The initial value is not specified
263      * in RFC 3078, but we can make a reasonable assumption that it will
264      * start at 0.  Setting it to the max here makes the comp/decomp code
265      * do the right thing (determined through experiment).
266      */
267     state->ccount = MPPE_CCOUNT_SPACE - 1;
268
269     /*
270      * Note that even though we have initialized the key table, we don't
271      * set the FLUSHED bit.  This is contrary to RFC 3078, sec. 3.1.
272      */
273     state->bits = MPPE_BIT_ENCRYPTED;
274
275     state->unit  = unit;
276     state->debug = debug;
277
278     return 1;
279 }
280
281
282
283 static int
284 mppe_comp_init(void *arg, unsigned char *options, int optlen, int unit,
285                int hdrlen, int debug)
286 {
287     /* ARGSUSED */
288     return mppe_init(arg, options, optlen, unit, debug, "mppe_comp_init");
289 }
290
291 /*
292  * We received a CCP Reset-Request (actually, we are sending a Reset-Ack),
293  * tell the compressor to rekey.  Note that we MUST NOT rekey for
294  * every CCP Reset-Request; we only rekey on the next xmit packet.
295  * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost.
296  * So, rekeying for every CCP Reset-Request is broken as the peer will not
297  * know how many times we've rekeyed.  (If we rekey and THEN get another
298  * CCP Reset-Request, we must rekey again.)
299  */
300 static void
301 mppe_comp_reset(void *arg)
302 {
303     ppp_mppe_state *state = (ppp_mppe_state *) arg;
304
305     state->bits |= MPPE_BIT_FLUSHED;
306 }
307
308 /*
309  * Compress (encrypt) a packet.
310  * It's strange to call this a compressor, since the output is always
311  * MPPE_OVHD + 2 bytes larger than the input.
312  */
313 int
314 mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
315               int isize, int osize)
316 {
317     ppp_mppe_state *state = (ppp_mppe_state *) arg;
318     int proto;
319
320     /*
321      * Check that the protocol is in the range we handle.
322      */
323     proto = PPP_PROTOCOL(ibuf);
324     if (proto < 0x0021 || proto > 0x00fa)
325         return 0;
326
327     /* Make sure we have enough room to generate an encrypted packet. */
328     if (osize < isize + MPPE_OVHD + 2) {
329         /* Drop the packet if we should encrypt it, but can't. */
330         printk(KERN_DEBUG "mppe_compress[%d]: osize too small! "
331                "(have: %d need: %d)\n", state->unit,
332                osize, osize + MPPE_OVHD + 2);
333         return -1;
334     }
335
336     osize = isize + MPPE_OVHD + 2;
337
338     /*
339      * Copy over the PPP header and set control bits.
340      */
341     obuf[0] = PPP_ADDRESS(ibuf);
342     obuf[1] = PPP_CONTROL(ibuf);
343     obuf[2] = PPP_COMP >> 8;            /* isize + MPPE_OVHD + 1 */
344     obuf[3] = PPP_COMP;                 /* isize + MPPE_OVHD + 2 */
345     obuf += PPP_HDRLEN;
346
347     state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
348     if (state->debug >= 7)
349         printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit,
350                state->ccount);
351     obuf[0] = state->ccount >> 8;
352     obuf[1] = state->ccount & 0xff;
353
354     if (!state->stateful ||                     /* stateless mode     */
355         ((state->ccount & 0xff) == 0xff) ||     /* "flag" packet      */
356         (state->bits & MPPE_BIT_FLUSHED)) {     /* CCP Reset-Request  */
357         /* We must rekey */
358         if (state->debug && state->stateful)
359             printk(KERN_DEBUG "mppe_compress[%d]: rekeying\n", state->unit);
360         mppe_rekey(state, 0);
361         state->bits |= MPPE_BIT_FLUSHED;
362     }
363     obuf[0] |= state->bits;
364     state->bits &= ~MPPE_BIT_FLUSHED;   /* reset for next xmit */
365
366     obuf  += MPPE_OVHD;
367     ibuf  += 2; /* skip to proto field */
368     isize -= 2;
369
370     /* Encrypt packet */
371     arcfour_encrypt(&state->arcfour_context, ibuf, isize, obuf);
372
373     state->stats.unc_bytes += isize;
374     state->stats.unc_packets++;
375     state->stats.comp_bytes += osize;
376     state->stats.comp_packets++;
377
378     return osize;
379 }
380
381 /*
382  * Since every frame grows by MPPE_OVHD + 2 bytes, this is always going
383  * to look bad ... and the longer the link is up the worse it will get.
384  */
385 static void
386 mppe_comp_stats(void *arg, struct compstat *stats)
387 {
388     ppp_mppe_state *state = (ppp_mppe_state *) arg;
389
390     *stats = state->stats;
391 }
392
393
394 static int
395 mppe_decomp_init(void *arg, unsigned char *options, int optlen, int unit,
396                  int hdrlen, int mru, int debug)
397 {
398     /* ARGSUSED */
399     return mppe_init(arg, options, optlen, unit, debug, "mppe_decomp_init");
400 }
401
402 /*
403  * We received a CCP Reset-Ack.  Just ignore it.
404  */
405 static void
406 mppe_decomp_reset(void *arg)
407 {
408     /* ARGSUSED */
409     return;
410 }
411
412 /*
413  * Decompress (decrypt) an MPPE packet.
414  */
415 int
416 mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
417                 int osize)
418 {
419     ppp_mppe_state *state = (ppp_mppe_state *) arg;
420     unsigned ccount;
421     int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED;
422     int sanity = 0;
423
424     if (isize <= PPP_HDRLEN + MPPE_OVHD) {
425         if (state->debug)
426             printk(KERN_DEBUG "mppe_decompress[%d]: short pkt (%d)\n",
427                    state->unit, isize);
428         return DECOMP_ERROR;
429     }
430
431     /*
432      * Make sure we have enough room to decrypt the packet.
433      * Note that for our test we only subtract 1 byte whereas in
434      * mppe_compress() we added 2 bytes (+MPPE_OVHD);
435      * this is to account for possible PFC.
436      */
437     if (osize < isize - MPPE_OVHD - 1) {
438         printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
439                "(have: %d need: %d)\n", state->unit,
440                osize, isize - MPPE_OVHD - 1);
441         return DECOMP_ERROR;
442     }
443     osize = isize - MPPE_OVHD - 2;      /* assume no PFC */
444
445     ccount = MPPE_CCOUNT(ibuf);
446     if (state->debug >= 7)
447         printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n", state->unit,
448                ccount);
449
450     /* sanity checks -- terminate with extreme prejudice */
451     if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
452         printk(KERN_DEBUG "mppe_decompress[%d]: ENCRYPTED bit not set!\n",
453                state->unit);
454         state->sanity_errors += 100;
455         sanity = 1;
456     }
457     if (!state->stateful && !flushed) {
458         printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set in "
459                "stateless mode!\n", state->unit);
460         state->sanity_errors += 100;
461         sanity = 1;
462     }
463     if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
464         printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set on "
465                "flag packet!\n", state->unit);
466         state->sanity_errors += 100;
467         sanity = 1;
468     }
469
470     if (sanity) {
471         if (state->sanity_errors < SANITY_MAX)
472             return DECOMP_ERROR;
473         else
474             /*
475              * Take LCP down if the peer is sending too many bogons.
476              * We don't want to do this for a single or just a few
477              * instances since it could just be due to packet corruption.
478              */
479             return DECOMP_FATALERROR;
480     }
481
482     /*
483      * Check the coherency count.
484      */
485
486     if (!state->stateful) {
487         /* RFC 3078, sec 8.1.  Rekey for every packet. */
488         while (state->ccount != ccount) {
489             mppe_rekey(state, 0);
490             state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
491         }
492     } else {
493         /* RFC 3078, sec 8.2. */
494         if (!state->discard) {
495             /* normal state */
496             state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
497             if (ccount != state->ccount) {
498                 /*
499                  * (ccount > state->ccount)
500                  * Packet loss detected, enter the discard state.
501                  * Signal the peer to rekey (by sending a CCP Reset-Request).
502                  */
503                 state->discard = 1;
504                 return DECOMP_ERROR;
505             }
506         } else {
507             /* discard state */
508            if (!flushed) {
509                 /* ccp.c will be silent (no additional CCP Reset-Requests). */
510                 return DECOMP_ERROR;
511             } else {
512                 /* Rekey for every missed "flag" packet. */
513                 while ((ccount & ~0xff) != (state->ccount & ~0xff)) {
514                     mppe_rekey(state, 0);
515                     state->ccount = (state->ccount + 256) % MPPE_CCOUNT_SPACE;
516                 }
517
518                 /* reset */
519                 state->discard = 0;
520                 state->ccount = ccount;
521                 /*
522                  * Another problem with RFC 3078 here.  It implies that the
523                  * peer need not send a Reset-Ack packet.  But RFC 1962
524                  * requires it.  Hopefully, M$ does send a Reset-Ack; even
525                  * though it isn't required for MPPE synchronization, it is
526                  * required to reset CCP state.
527                  */
528             }
529         }
530         if (flushed)
531             mppe_rekey(state, 0);
532     }
533
534     /*
535      * Fill in the first part of the PPP header.  The protocol field
536      * comes from the decrypted data.
537      */
538     obuf[0] = PPP_ADDRESS(ibuf);        /* +1 */
539     obuf[1] = PPP_CONTROL(ibuf);        /* +1 */
540     obuf  += 2;
541     ibuf  += PPP_HDRLEN + MPPE_OVHD;
542     isize -= PPP_HDRLEN + MPPE_OVHD;    /* -6 */
543                                         /* net osize: isize-4 */
544
545     /*
546      * Decrypt the first byte in order to check if it is
547      * a compressed or uncompressed protocol field.
548      */
549     arcfour_decrypt(&state->arcfour_context, ibuf, 1, obuf);
550
551     /*
552      * Do PFC decompression.
553      * This would be nicer if we were given the actual sk_buff
554      * instead of a char *.
555      */
556     if ((obuf[0] & 0x01) != 0) {
557         obuf[1] = obuf[0];
558         obuf[0] = 0;
559         obuf++;
560         osize++;
561     }
562
563     /* And finally, decrypt the rest of the packet. */
564     arcfour_decrypt(&state->arcfour_context, ibuf + 1, isize - 1, obuf + 1);
565
566     state->stats.unc_bytes += osize;
567     state->stats.unc_packets++;
568     state->stats.comp_bytes += isize;
569     state->stats.comp_packets++;
570
571     /* good packet credit */
572     state->sanity_errors >>= 1;
573
574     return osize;
575 }
576
577 /*
578  * Incompressible data has arrived (this should never happen!).
579  * We should probably drop the link if the protocol is in the range
580  * of what should be encrypted.  At the least, we should drop this
581  * packet.  (How to do this?)
582  */
583 static void
584 mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
585 {
586     ppp_mppe_state *state = (ppp_mppe_state *) arg;
587
588     if (state->debug &&
589         (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa))
590         printk(KERN_DEBUG "mppe_incomp[%d]: incompressible (unencrypted) data! "
591                "(proto %04x)\n", state->unit, PPP_PROTOCOL(ibuf));
592
593     state->stats.inc_bytes += icnt;
594     state->stats.inc_packets++;
595     state->stats.unc_bytes += icnt;
596     state->stats.unc_packets++;
597 }
598
599 /*************************************************************
600  * Module interface table
601  *************************************************************/
602
603 /* These are in ppp.c (2.2.x) or ppp_generic.c (2.4.x) */
604 extern int  ppp_register_compressor   (struct compressor *cp);
605 extern void ppp_unregister_compressor (struct compressor *cp);
606
607 /*
608  * Procedures exported to if_ppp.c.
609  */
610 struct compressor ppp_mppe = {
611     CI_MPPE,            /* compress_proto */
612     mppe_alloc,         /* comp_alloc */
613     mppe_free,          /* comp_free */
614     mppe_comp_init,     /* comp_init */
615     mppe_comp_reset,    /* comp_reset */
616     mppe_compress,      /* compress */
617     mppe_comp_stats,    /* comp_stat */
618     mppe_alloc,         /* decomp_alloc */
619     mppe_free,          /* decomp_free */
620     mppe_decomp_init,   /* decomp_init */
621     mppe_decomp_reset,  /* decomp_reset */
622     mppe_decompress,    /* decompress */
623     mppe_incomp,        /* incomp */
624     mppe_comp_stats,    /* decomp_stat */
625 };
626
627 /* 2.2 compatibility defines */
628 #ifndef __init
629 #define __init
630 #endif
631 #ifndef __exit
632 #define __exit
633 #endif
634 #ifndef MODULE_LICENSE
635 #define MODULE_LICENSE(license)
636 #endif
637
638 int __init
639 ppp_mppe_init(void)
640 {  
641     int answer = ppp_register_compressor(&ppp_mppe);
642
643     if (answer == 0)
644         printk(KERN_INFO "PPP MPPE Compression module registered\n");
645     return answer;
646 }
647
648 void __exit
649 ppp_mppe_cleanup(void)
650 {
651     ppp_unregister_compressor(&ppp_mppe);
652 }
653
654 module_init(ppp_mppe_init);
655 module_exit(ppp_mppe_cleanup);
656 MODULE_LICENSE("BSD without advertisement clause");