d2305346393c3f8b392e538468313cd2e1f356ea
[librecmc/librecmc.git] / obsolete-buildroot / sources / openwrt / patches / ppp / z02_ppp-2.4.2-stdopt-mppe-mppc-1.1.patch
1 diff -ruN ppp-2.4.2.orig/include/linux/ppp-comp.h ppp-2.4.2-stdopt/include/linux/ppp-comp.h
2 --- ppp-2.4.2.orig/include/linux/ppp-comp.h     2002-12-06 10:49:15.000000000 +0100
3 +++ ppp-2.4.2-stdopt/include/linux/ppp-comp.h   2004-01-21 06:51:09.000000000 +0100
4 @@ -36,7 +36,7 @@
5   */
6  
7  /*
8 - *  ==FILEVERSION 20020319==
9 + *  ==FILEVERSION 20020715==
10   *
11   *  NOTE TO MAINTAINERS:
12   *     If you modify this file at all, please set the above date.
13 @@ -86,7 +86,7 @@
14  
15         /* Compress a packet */
16         int     (*compress) (void *state, unsigned char *rptr,
17 -                             unsigned char *obuf, int isize, int osize);
18 +                            unsigned char *obuf, int isize, int osize);
19  
20         /* Return compression statistics */
21         void    (*comp_stat) (void *state, struct compstat *stats);
22 @@ -107,7 +107,7 @@
23  
24         /* Decompress a packet. */
25         int     (*decompress) (void *state, unsigned char *ibuf, int isize,
26 -                               unsigned char *obuf, int osize);
27 +                              unsigned char *obuf, int osize);
28  
29         /* Update state for an incompressible packet received */
30         void    (*incomp) (void *state, unsigned char *ibuf, int icnt);
31 @@ -288,6 +288,33 @@
32             opts |= MPPE_OPT_UNKNOWN;           \
33      } while (/* CONSTCOND */ 0)
34  
35 +/* MPPE/MPPC definitions by J.D.*/
36 +#define MPPE_STATELESS          MPPE_H_BIT     /* configuration bit H */
37 +#define MPPE_40BIT              MPPE_L_BIT     /* configuration bit L */
38 +#define MPPE_56BIT              MPPE_M_BIT     /* configuration bit M */
39 +#define MPPE_128BIT             MPPE_S_BIT     /* configuration bit S */
40 +#define MPPE_MPPC               MPPE_C_BIT     /* configuration bit C */
41 +
42 +/*
43 + * Definitions for Stac LZS.
44 + */
45 +
46 +#define CI_LZS                 17      /* config option for Stac LZS */
47 +#define CILEN_LZS              5       /* length of config option */
48 +
49 +#define LZS_OVHD               4       /* max. LZS overhead */
50 +#define LZS_HIST_LEN           2048    /* LZS history size */
51 +#define LZS_MAX_CCOUNT         0x0FFF  /* max. coherency counter value */
52 +
53 +#define LZS_MODE_NONE          0
54 +#define LZS_MODE_LCB           1
55 +#define LZS_MODE_CRC           2
56 +#define LZS_MODE_SEQ           3
57 +#define LZS_MODE_EXT           4
58 +
59 +#define LZS_EXT_BIT_FLUSHED    0x80    /* bit A */
60 +#define LZS_EXT_BIT_COMP       0x20    /* bit C */
61 +
62  /*
63   * Definitions for other, as yet unsupported, compression methods.
64   */
65 diff -ruN ppp-2.4.2.orig/include/net/ppp-comp.h ppp-2.4.2-stdopt/include/net/ppp-comp.h
66 --- ppp-2.4.2.orig/include/net/ppp-comp.h       2002-12-06 10:49:15.000000000 +0100
67 +++ ppp-2.4.2-stdopt/include/net/ppp-comp.h     2004-01-21 06:51:09.000000000 +0100
68 @@ -255,6 +255,33 @@
69             opts |= MPPE_OPT_UNKNOWN;           \
70      } while (/* CONSTCOND */ 0)
71  
72 +/* MPPE/MPPC definitions by J.D.*/
73 +#define MPPE_STATELESS          MPPE_H_BIT     /* configuration bit H */
74 +#define MPPE_40BIT              MPPE_L_BIT     /* configuration bit L */
75 +#define MPPE_56BIT              MPPE_M_BIT     /* configuration bit M */
76 +#define MPPE_128BIT             MPPE_S_BIT     /* configuration bit S */
77 +#define MPPE_MPPC               MPPE_C_BIT     /* configuration bit C */
78 +
79 +/*
80 + * Definitions for Stac LZS.
81 + */
82 +
83 +#define CI_LZS                 17      /* config option for Stac LZS */
84 +#define CILEN_LZS              5       /* length of config option */
85 +
86 +#define LZS_OVHD               4       /* max. LZS overhead */
87 +#define LZS_HIST_LEN           2048    /* LZS history size */
88 +#define LZS_MAX_CCOUNT         0x0FFF  /* max. coherency counter value */
89 +
90 +#define LZS_MODE_NONE          0
91 +#define LZS_MODE_LCB           1
92 +#define LZS_MODE_CRC           2
93 +#define LZS_MODE_SEQ           3
94 +#define LZS_MODE_EXT           4
95 +
96 +#define LZS_EXT_BIT_FLUSHED    0x80    /* bit A */
97 +#define LZS_EXT_BIT_COMP       0x20    /* bit C */
98 +
99  /*
100   * Definitions for other, as yet unsupported, compression methods.
101   */
102 diff -ruN ppp-2.4.2.orig/pppd/ccp.c ppp-2.4.2-stdopt/pppd/ccp.c
103 --- ppp-2.4.2.orig/pppd/ccp.c   2003-05-01 14:30:28.000000000 +0200
104 +++ ppp-2.4.2-stdopt/pppd/ccp.c 2004-05-02 14:10:04.000000000 +0200
105 @@ -67,13 +67,6 @@
106  static char bsd_value[8];
107  static char deflate_value[8];
108  
109 -/*
110 - * Option variables.
111 - */
112 -#ifdef MPPE
113 -bool refuse_mppe_stateful = 1;         /* Allow stateful mode? */
114 -#endif
115 -
116  static option_t ccp_option_list[] = {
117      { "noccp", o_bool, &ccp_protent.enabled_flag,
118        "Disable CCP negotiation" },
119 @@ -113,54 +106,87 @@
120        "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
121        &ccp_allowoptions[0].predictor_1 },
122  
123 +    { "lzs", o_bool, &ccp_wantoptions[0].lzs,
124 +      "request Stac LZS", 1, &ccp_allowoptions[0].lzs, OPT_PRIO },
125 +    { "+lzs", o_bool, &ccp_wantoptions[0].lzs,
126 +      "request Stac LZS", 1, &ccp_allowoptions[0].lzs, OPT_ALIAS | OPT_PRIO },
127 +    { "nolzs", o_bool, &ccp_wantoptions[0].lzs,
128 +      "don't allow Stac LZS", OPT_PRIOSUB | OPT_A2CLR,
129 +      &ccp_allowoptions[0].lzs },
130 +    { "-lzs", o_bool, &ccp_wantoptions[0].lzs,
131 +      "don't allow Stac LZS", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
132 +      &ccp_allowoptions[0].lzs },
133 +
134  #ifdef MPPE
135 -    /* MPPE options are symmetrical ... we only set wantoptions here */
136 +    { "mppc", o_bool, &ccp_wantoptions[0].mppc,
137 +      "request MPPC compression", 1, &ccp_allowoptions[0].mppc, OPT_PRIO },
138 +    { "+mppc", o_bool, &ccp_wantoptions[0].mppc,
139 +      "request MPPC compression", 1, &ccp_allowoptions[0].mppc,
140 +      OPT_ALIAS | OPT_PRIO },
141 +    { "nomppc", o_bool, &ccp_wantoptions[0].mppc,
142 +      "don't allow MPPC compression", OPT_PRIOSUB | OPT_A2CLR,
143 +      &ccp_allowoptions[0].mppc },
144 +    { "-mppc", o_bool, &ccp_wantoptions[0].mppc,
145 +      "don't allow MPPC compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
146 +      &ccp_allowoptions[0].mppc },
147 +
148      { "require-mppe", o_bool, &ccp_wantoptions[0].mppe,
149 -      "require MPPE encryption",
150 -      OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
151 +      "require MPPE encryption", 1, &ccp_allowoptions[0].mppe, OPT_PRIO },
152      { "+mppe", o_bool, &ccp_wantoptions[0].mppe,
153 -      "require MPPE encryption",
154 -      OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
155 +      "require MPPE encryption", 1, &ccp_allowoptions[0].mppe,
156 +      OPT_ALIAS | OPT_PRIO },
157      { "nomppe", o_bool, &ccp_wantoptions[0].mppe,
158 -      "don't allow MPPE encryption", OPT_PRIO },
159 +      "don't allow MPPE encryption", OPT_PRIOSUB | OPT_A2CLR,
160 +      &ccp_allowoptions[0].mppe },
161      { "-mppe", o_bool, &ccp_wantoptions[0].mppe,
162 -      "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO },
163 +      "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
164 +      &ccp_allowoptions[0].mppe },
165  
166 -    /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */
167 -    { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
168 -      "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
169 -      &ccp_wantoptions[0].mppe },
170 -    { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe,
171 -      "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
172 -      &ccp_wantoptions[0].mppe },
173 -    { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe,
174 -      "don't allow MPPE 40-bit encryption",
175 -      OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe },
176 -    { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
177 -      "don't allow MPPE 40-bit encryption",
178 -      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40,
179 -      &ccp_wantoptions[0].mppe },
180 -
181 -    { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
182 -      "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
183 -      &ccp_wantoptions[0].mppe },
184 -    { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe,
185 -      "require MPPE 128-bit encryption",
186 -      OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
187 -      &ccp_wantoptions[0].mppe },
188 -    { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe,
189 -      "don't allow MPPE 128-bit encryption",
190 -      OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe },
191 -    { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
192 -      "don't allow MPPE 128-bit encryption",
193 -      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128,
194 -      &ccp_wantoptions[0].mppe },
195 -
196 -    /* strange one; we always request stateless, but will we allow stateful? */
197 -    { "mppe-stateful", o_bool, &refuse_mppe_stateful,
198 -      "allow MPPE stateful mode", OPT_PRIO },
199 -    { "nomppe-stateful", o_bool, &refuse_mppe_stateful,
200 -      "disallow MPPE stateful mode", OPT_PRIO | 1 },
201 +    { "require-mppe-40", o_bool, &ccp_wantoptions[0].mppe_40,
202 +      "require MPPE 40-bit encryption", 1, &ccp_allowoptions[0].mppe_40,
203 +      OPT_PRIO },
204 +    { "+mppe-40", o_bool, &ccp_wantoptions[0].mppe_40,
205 +      "require MPPE 40-bit encryption", 1, &ccp_allowoptions[0].mppe_40,
206 +      OPT_ALIAS | OPT_PRIO },
207 +    { "nomppe-40", o_bool, &ccp_wantoptions[0].mppe_40,
208 +      "don't allow MPPE 40-bit encryption", OPT_PRIOSUB | OPT_A2CLR,
209 +      &ccp_allowoptions[0].mppe_40 },
210 +    { "-mppe-40", o_bool, &ccp_wantoptions[0].mppe_40,
211 +      "don't allow MPPE 40-bit encryption", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
212 +      &ccp_allowoptions[0].mppe_40 },
213 +
214 +    { "require-mppe-56", o_bool, &ccp_wantoptions[0].mppe_56,
215 +      "require MPPE 56-bit encryption", 1, &ccp_allowoptions[0].mppe_56,
216 +      OPT_PRIO },
217 +    { "+mppe-56", o_bool, &ccp_wantoptions[0].mppe_56,
218 +      "require MPPE 56-bit encryption", 1, &ccp_allowoptions[0].mppe_56,
219 +      OPT_ALIAS | OPT_PRIO },
220 +    { "nomppe-56", o_bool, &ccp_wantoptions[0].mppe_56,
221 +      "don't allow MPPE 56-bit encryption", OPT_PRIOSUB | OPT_A2CLR,
222 +      &ccp_allowoptions[0].mppe_56 },
223 +    { "-mppe-56", o_bool, &ccp_wantoptions[0].mppe_56,
224 +      "don't allow MPPE 56-bit encryption", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
225 +      &ccp_allowoptions[0].mppe_56 },
226 +
227 +    { "require-mppe-128", o_bool, &ccp_wantoptions[0].mppe_128,
228 +      "require MPPE 128-bit encryption", 1, &ccp_allowoptions[0].mppe_128,
229 +      OPT_PRIO },
230 +    { "+mppe-128", o_bool, &ccp_wantoptions[0].mppe_128,
231 +      "require MPPE 128-bit encryption", 1, &ccp_allowoptions[0].mppe_128,
232 +      OPT_ALIAS | OPT_PRIO },
233 +    { "nomppe-128", o_bool, &ccp_wantoptions[0].mppe_40,
234 +      "don't allow MPPE 128-bit encryption", OPT_PRIOSUB | OPT_A2CLR,
235 +      &ccp_allowoptions[0].mppe_128 },
236 +    { "-mppe-128", o_bool, &ccp_wantoptions[0].mppe_128,
237 +      "don't allow MPPE 128-bit encryption", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
238 +      &ccp_allowoptions[0].mppe_128 },
239 +
240 +    { "nomppe-stateful", o_bool, &ccp_wantoptions[0].mppe_stateless,
241 +      "disallow MPPE stateful mode", 1, &ccp_allowoptions[0].mppe_stateless,
242 +      OPT_PRIO },
243 +    { "mppe-stateful", o_bool, &ccp_wantoptions[0].mppe_stateless,
244 +      "allow MPPE stateful mode", OPT_PRIOSUB | OPT_A2CLR,
245 +      &ccp_allowoptions[0].mppe_stateless },
246  #endif /* MPPE */
247  
248      { NULL }
249 @@ -246,7 +272,7 @@
250   */
251  #define ANY_COMPRESS(opt)      ((opt).deflate || (opt).bsd_compress \
252                                  || (opt).predictor_1 || (opt).predictor_2 \
253 -                                || (opt).mppe)
254 +                                || (opt).lzs || (opt).mppc || (opt).mppe)
255  
256  /*
257   * Local state (mainly for handling reset-reqs and reset-acks).
258 @@ -383,6 +409,30 @@
259      ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS;
260  
261      ccp_allowoptions[0].predictor_1 = 1;
262 +
263 +    ccp_wantoptions[0].lzs = 0; /* Stac LZS  - will be enabled in the future */
264 +    ccp_wantoptions[0].lzs_mode = LZS_MODE_SEQ;
265 +    ccp_wantoptions[0].lzs_hists = 1;
266 +    ccp_allowoptions[0].lzs = 0; /* Stac LZS  - will be enabled in the future */
267 +    ccp_allowoptions[0].lzs_mode = LZS_MODE_SEQ;
268 +    ccp_allowoptions[0].lzs_hists = 1;
269 +
270 +#ifdef MPPE
271 +    /* by default allow and request MPPC... */
272 +    ccp_wantoptions[0].mppc = ccp_allowoptions[0].mppc = 1;
273 +
274 +    /* ... and allow but don't request MPPE */
275 +    ccp_allowoptions[0].mppe = 1;
276 +    ccp_allowoptions[0].mppe_40 = 1;
277 +    ccp_allowoptions[0].mppe_56 = 1;
278 +    ccp_allowoptions[0].mppe_128 = 1;
279 +    ccp_allowoptions[0].mppe_stateless = 1;
280 +    ccp_wantoptions[0].mppe = 0;
281 +    ccp_wantoptions[0].mppe_40 = 0;
282 +    ccp_wantoptions[0].mppe_56 = 0;
283 +    ccp_wantoptions[0].mppe_128 = 0;
284 +    ccp_wantoptions[0].mppe_stateless = 0;
285 +#endif /* MPPE */
286  }
287  
288  /*
289 @@ -460,11 +510,11 @@
290      if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED) {
291         notice("Compression disabled by peer.");
292  #ifdef MPPE
293 -       if (ccp_gotoptions[unit].mppe) {
294 +       if (ccp_wantoptions[unit].mppe) {
295             error("MPPE disabled, closing LCP");
296             lcp_close(unit, "MPPE disabled by peer");
297         }
298 -#endif
299 +#endif /* MPPE */
300      }
301  
302      /*
303 @@ -492,6 +542,15 @@
304             break;
305         /* send a reset-ack, which the transmitter will see and
306            reset its compression state. */
307 +
308 +       /* In case of MPPE/MPPC or LZS we shouldn't send CCP_RESETACK,
309 +          but we do it in order to reset compressor; CCP_RESETACK is
310 +          then silently discarded. See functions ppp_send_frame and
311 +          ppp_ccp_peek in ppp_generic.c (Linux only !!!). All the
312 +          confusion is caused by the fact that CCP code is splited
313 +          into two parts - one part is handled by pppd, the other one
314 +          is handled by kernel. */
315 +
316         fsm_sdata(f, CCP_RESETACK, id, NULL, 0);
317         break;
318  
319 @@ -520,12 +579,11 @@
320      fsm_lowerdown(&ccp_fsm[unit]);
321  
322  #ifdef MPPE
323 -    if (ccp_gotoptions[unit].mppe) {
324 +    if (ccp_wantoptions[unit].mppe) {
325         error("MPPE required but peer negotiation failed");
326         lcp_close(unit, "MPPE required but peer negotiation failed");
327      }
328 -#endif
329 -
330 +#endif /* MPPE */
331  }
332  
333  /*
334 @@ -542,7 +600,7 @@
335      all_rejected[f->unit] = 0;
336  
337  #ifdef MPPE
338 -    if (go->mppe) {
339 +    if (go->mppe || go->mppc) {
340         ccp_options *ao = &ccp_allowoptions[f->unit];
341         int auth_mschap_bits = auth_done[f->unit];
342         int numbits;
343 @@ -556,80 +614,109 @@
344          * NB: If MPPE is required, all other compression opts are invalid.
345          *     So, we return right away if we can't do it.
346          */
347 +       if (ccp_wantoptions[f->unit].mppe) {
348 +           /* Leave only the mschap auth bits set */
349 +           auth_mschap_bits &= (CHAP_MS_WITHPEER  | CHAP_MS_PEER |
350 +                                CHAP_MS2_WITHPEER | CHAP_MS2_PEER);
351 +           /* Count the mschap auths */
352 +           auth_mschap_bits >>= CHAP_MS_SHIFT;
353 +           numbits = 0;
354 +           do {
355 +               numbits += auth_mschap_bits & 1;
356 +               auth_mschap_bits >>= 1;
357 +           } while (auth_mschap_bits);
358 +           if (numbits > 1) {
359 +               error("MPPE required, but auth done in both directions.");
360 +               lcp_close(f->unit, "MPPE required but not available");
361 +               return;
362 +           }
363 +           if (!numbits) {
364 +               error("MPPE required, but MS-CHAP[v2] auth not performed.");
365 +               lcp_close(f->unit, "MPPE required but not available");
366 +               return;
367 +           }
368  
369 -       /* Leave only the mschap auth bits set */
370 -       auth_mschap_bits &= (CHAP_MS_WITHPEER  | CHAP_MS_PEER |
371 -                            CHAP_MS2_WITHPEER | CHAP_MS2_PEER);
372 -       /* Count the mschap auths */
373 -       auth_mschap_bits >>= CHAP_MS_SHIFT;
374 -       numbits = 0;
375 -       do {
376 -           numbits += auth_mschap_bits & 1;
377 -           auth_mschap_bits >>= 1;
378 -       } while (auth_mschap_bits);
379 -       if (numbits > 1) {
380 -           error("MPPE required, but auth done in both directions.");
381 -           lcp_close(f->unit, "MPPE required but not available");
382 -           return;
383 -       }
384 -       if (!numbits) {
385 -           error("MPPE required, but MS-CHAP[v2] auth not performed.");
386 -           lcp_close(f->unit, "MPPE required but not available");
387 -           return;
388 -       }
389 -
390 -       /* A plugin (eg radius) may not have obtained key material. */
391 -       if (!mppe_keys_set) {
392 -           error("MPPE required, but keys are not available.  "
393 -                 "Possible plugin problem?");
394 -           lcp_close(f->unit, "MPPE required but not available");
395 -           return;
396 -       }
397 -
398 -       /* LM auth not supported for MPPE */
399 -       if (auth_done[f->unit] & (CHAP_MS_WITHPEER | CHAP_MS_PEER)) {
400 -           /* This might be noise */
401 -           if (go->mppe & MPPE_OPT_40) {
402 -               notice("Disabling 40-bit MPPE; MS-CHAP LM not supported");
403 -               go->mppe &= ~MPPE_OPT_40;
404 -               ccp_wantoptions[f->unit].mppe &= ~MPPE_OPT_40;
405 +           /* A plugin (eg radius) may not have obtained key material. */
406 +           if (!mppe_keys_set) {
407 +               error("MPPE required, but keys are not available.  "
408 +                     "Possible plugin problem?");
409 +               lcp_close(f->unit, "MPPE required but not available");
410 +               return;
411             }
412         }
413  
414 -       /* Last check: can we actually negotiate something? */
415 -       if (!(go->mppe & (MPPE_OPT_40 | MPPE_OPT_128))) {
416 -           /* Could be misconfig, could be 40-bit disabled above. */
417 -           error("MPPE required, but both 40-bit and 128-bit disabled.");
418 -           lcp_close(f->unit, "MPPE required but not available");
419 -           return;
420 +       /*
421 +        * Check whether the kernel knows about the various
422 +        * compression methods we might request. Key material
423 +        * unimportant here.
424 +        */
425 +       if (go->mppc) {
426 +           opt_buf[0] = CI_MPPE;
427 +           opt_buf[1] = CILEN_MPPE;
428 +           opt_buf[2] = 0;
429 +           opt_buf[3] = 0;
430 +           opt_buf[4] = 0;
431 +           opt_buf[5] = MPPE_MPPC;
432 +           if (ccp_test(f->unit, opt_buf, CILEN_MPPE, 0) <= 0)
433 +               go->mppc = 0;
434 +       }
435 +       if (go->mppe_40) {
436 +           opt_buf[0] = CI_MPPE;
437 +           opt_buf[1] = CILEN_MPPE;
438 +           opt_buf[2] = MPPE_STATELESS;
439 +           opt_buf[3] = 0;
440 +           opt_buf[4] = 0;
441 +           opt_buf[5] = MPPE_40BIT;
442 +           if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0)
443 +               go->mppe_40 = 0;
444 +       }
445 +       if (go->mppe_56) {
446 +           opt_buf[0] = CI_MPPE;
447 +           opt_buf[1] = CILEN_MPPE;
448 +           opt_buf[2] = MPPE_STATELESS;
449 +           opt_buf[3] = 0;
450 +           opt_buf[4] = 0;
451 +           opt_buf[5] = MPPE_56BIT;
452 +           if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0)
453 +               go->mppe_56 = 0;
454 +       }
455 +       if (go->mppe_128) {
456 +           opt_buf[0] = CI_MPPE;
457 +           opt_buf[1] = CILEN_MPPE;
458 +           opt_buf[2] = MPPE_STATELESS;
459 +           opt_buf[3] = 0;
460 +           opt_buf[4] = 0;
461 +           opt_buf[5] = MPPE_128BIT;
462 +           if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0)
463 +               go->mppe_128 = 0;
464 +       }
465 +       if (!go->mppe_40 && !go->mppe_56 && !go->mppe_128) {
466 +           if (ccp_wantoptions[f->unit].mppe) {
467 +               error("MPPE required, but kernel has no support.");
468 +               lcp_close(f->unit, "MPPE required but not available");
469 +           }
470 +           go->mppe = go->mppe_stateless = 0;
471 +       } else {
472 +           /* MPPE is not compatible with other compression types */
473 +           if (ccp_wantoptions[f->unit].mppe) {
474 +               ao->bsd_compress = go->bsd_compress = 0;
475 +               ao->predictor_1  = go->predictor_1  = 0;
476 +               ao->predictor_2  = go->predictor_2  = 0;
477 +               ao->deflate      = go->deflate      = 0;
478 +               ao->lzs          = go->lzs          = 0;
479 +           }
480         }
481 -
482 -       /* sync options */
483 -       ao->mppe = go->mppe;
484 -       /* MPPE is not compatible with other compression types */
485 -       ao->bsd_compress = go->bsd_compress = 0;
486 -       ao->predictor_1  = go->predictor_1  = 0;
487 -       ao->predictor_2  = go->predictor_2  = 0;
488 -       ao->deflate      = go->deflate      = 0;
489      }
490  #endif /* MPPE */
491 -
492 -    /*
493 -     * Check whether the kernel knows about the various
494 -     * compression methods we might request.
495 -     */
496 -#ifdef MPPE
497 -    if (go->mppe) {
498 -       opt_buf[0] = CI_MPPE;
499 -       opt_buf[1] = CILEN_MPPE;
500 -       MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
501 -       /* Key material unimportant here. */
502 -       if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0) {
503 -           error("MPPE required, but kernel has no support.");
504 -           lcp_close(f->unit, "MPPE required but not available");
505 -       }
506 +    if (go->lzs) {
507 +       opt_buf[0] = CI_LZS;
508 +       opt_buf[1] = CILEN_LZS;
509 +       opt_buf[2] = go->lzs_hists >> 8;
510 +       opt_buf[3] = go->lzs_hists & 0xff;
511 +       opt_buf[4] = LZS_MODE_SEQ;
512 +       if (ccp_test(f->unit, opt_buf, CILEN_LZS, 0) <= 0)
513 +           go->lzs = 0;
514      }
515 -#endif
516      if (go->bsd_compress) {
517         opt_buf[0] = CI_BSD_COMPRESS;
518         opt_buf[1] = CILEN_BSD_COMPRESS;
519 @@ -684,7 +771,8 @@
520         + (go->deflate? CILEN_DEFLATE: 0)
521         + (go->predictor_1? CILEN_PREDICTOR_1: 0)
522         + (go->predictor_2? CILEN_PREDICTOR_2: 0)
523 -       + (go->mppe? CILEN_MPPE: 0);
524 +       + (go->lzs? CILEN_LZS: 0)
525 +       + ((go->mppe || go->mppc)? CILEN_MPPE: 0);
526  }
527  
528  /*
529 @@ -698,6 +786,8 @@
530  {
531      int res;
532      ccp_options *go = &ccp_gotoptions[f->unit];
533 +    ccp_options *ao = &ccp_allowoptions[f->unit];
534 +    ccp_options *wo = &ccp_wantoptions[f->unit];
535      u_char *p0 = p;
536  
537      /*
538 @@ -706,22 +796,43 @@
539       * in case it gets Acked.
540       */
541  #ifdef MPPE
542 -    if (go->mppe) {
543 +    if (go->mppe || go->mppc || (!wo->mppe && ao->mppe)) {
544         u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
545  
546 -       p[0] = opt_buf[0] = CI_MPPE;
547 -       p[1] = opt_buf[1] = CILEN_MPPE;
548 -       MPPE_OPTS_TO_CI(go->mppe, &p[2]);
549 -       MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
550 +       p[0] = CI_MPPE;
551 +       p[1] = CILEN_MPPE;
552 +       p[2] = (go->mppe_stateless ? MPPE_STATELESS : 0);
553 +       p[3] = 0;
554 +       p[4] = 0;
555 +       p[5] = (go->mppe_40 ? MPPE_40BIT : 0) | (go->mppe_56 ? MPPE_56BIT : 0) |
556 +           (go->mppe_128 ? MPPE_128BIT : 0) | (go->mppc ? MPPE_MPPC : 0);
557 +
558 +       BCOPY(p, opt_buf, CILEN_MPPE);
559         BCOPY(mppe_recv_key, &opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN);
560         res = ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0);
561 -       if (res > 0)
562 +       if (res > 0) {
563             p += CILEN_MPPE;
564 -       else
565 +       } else {
566             /* This shouldn't happen, we've already tested it! */
567 -           lcp_close(f->unit, "MPPE required but not available in kernel");
568 +           go->mppe = go->mppe_40 = go->mppe_56 = go->mppe_128 =
569 +               go->mppe_stateless = go->mppc = 0;
570 +           if (ccp_wantoptions[f->unit].mppe)
571 +               lcp_close(f->unit, "MPPE required but not available in kernel");
572 +       }
573 +    }
574 +#endif /* MPPE */
575 +    if (go->lzs) {
576 +       p[0] = CI_LZS;
577 +       p[1] = CILEN_LZS;
578 +       p[2] = go->lzs_hists >> 8;
579 +       p[3] = go->lzs_hists & 0xff;
580 +       p[4] = LZS_MODE_SEQ;
581 +       res = ccp_test(f->unit, p, CILEN_LZS, 0);
582 +       if (res > 0) {
583 +           p += CILEN_LZS;
584 +       } else
585 +           go->lzs = 0;
586      }
587 -#endif
588      if (go->deflate) {
589         p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT;
590         p[1] = CILEN_DEFLATE;
591 @@ -807,7 +918,7 @@
592  
593  /*
594   * ccp_ackci - process a received configure-ack, and return
595 - * 1 iff the packet was OK.
596 + * 1 if the packet was OK.
597   */
598  static int
599  ccp_ackci(f, p, len)
600 @@ -816,24 +927,44 @@
601      int len;
602  {
603      ccp_options *go = &ccp_gotoptions[f->unit];
604 +    ccp_options *ao = &ccp_allowoptions[f->unit];
605 +    ccp_options *wo = &ccp_wantoptions[f->unit];
606      u_char *p0 = p;
607  
608  #ifdef MPPE
609 -    if (go->mppe) {
610 -       u_char opt_buf[CILEN_MPPE];
611 -
612 -       opt_buf[0] = CI_MPPE;
613 -       opt_buf[1] = CILEN_MPPE;
614 -       MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
615 -       if (len < CILEN_MPPE || memcmp(opt_buf, p, CILEN_MPPE))
616 +    if (go->mppe || go->mppc || (!wo->mppe && ao->mppe)) {
617 +       if (len < CILEN_MPPE
618 +           || p[1] != CILEN_MPPE || p[0] != CI_MPPE
619 +           || p[2] != (go->mppe_stateless ? MPPE_STATELESS : 0)
620 +           || p[3] != 0
621 +           || p[4] != 0
622 +           || (p[5] != ((go->mppe_40 ? MPPE_40BIT : 0) |
623 +                        (go->mppc ? MPPE_MPPC : 0))
624 +               && p[5] != ((go->mppe_56 ? MPPE_56BIT : 0) |
625 +                           (go->mppc ? MPPE_MPPC : 0))
626 +               && p[5] != ((go->mppe_128 ? MPPE_128BIT : 0) |
627 +                           (go->mppc ? MPPE_MPPC : 0))))
628             return 0;
629 +       if (go->mppe_40 || go->mppe_56 || go->mppe_128)
630 +           go->mppe = 1;
631         p += CILEN_MPPE;
632         len -= CILEN_MPPE;
633 +       /* Cope with first/fast ack */
634 +       if (p == p0 && len == 0)
635 +           return 1;
636 +    }
637 +#endif /* MPPE */
638 +    if (go->lzs) {
639 +       if (len < CILEN_LZS || p[0] != CI_LZS || p[1] != CILEN_LZS
640 +           || p[2] != go->lzs_hists>>8 || p[3] != (go->lzs_hists&0xff)
641 +           || p[4] != LZS_MODE_SEQ)
642 +           return 0;
643 +       p += CILEN_LZS;
644 +       len -= CILEN_LZS;
645         /* XXX Cope with first/fast ack */
646 -       if (len == 0)
647 +       if (p == p0 && len == 0)
648             return 1;
649      }
650 -#endif
651      if (go->deflate) {
652         if (len < CILEN_DEFLATE
653             || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
654 @@ -896,7 +1027,7 @@
655  
656  /*
657   * ccp_nakci - process received configure-nak.
658 - * Returns 1 iff the nak was OK.
659 + * Returns 1 if the nak was OK.
660   */
661  static int
662  ccp_nakci(f, p, len)
663 @@ -905,6 +1036,8 @@
664      int len;
665  {
666      ccp_options *go = &ccp_gotoptions[f->unit];
667 +    ccp_options *ao = &ccp_allowoptions[f->unit];
668 +    ccp_options *wo = &ccp_wantoptions[f->unit];
669      ccp_options no;            /* options we've seen already */
670      ccp_options try;           /* options to ask for next time */
671  
672 @@ -912,28 +1045,100 @@
673      try = *go;
674  
675  #ifdef MPPE
676 -    if (go->mppe && len >= CILEN_MPPE
677 -       && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
678 -       no.mppe = 1;
679 -       /*
680 -        * Peer wants us to use a different strength or other setting.
681 -        * Fail if we aren't willing to use his suggestion.
682 -        */
683 -       MPPE_CI_TO_OPTS(&p[2], try.mppe);
684 -       if ((try.mppe & MPPE_OPT_STATEFUL) && refuse_mppe_stateful) {
685 -           error("Refusing MPPE stateful mode offered by peer");
686 -           try.mppe = 0;
687 -       } else if (((go->mppe | MPPE_OPT_STATEFUL) & try.mppe) != try.mppe) {
688 -           /* Peer must have set options we didn't request (suggest) */
689 -           try.mppe = 0;
690 -       }
691 +    if ((go->mppe || go->mppc || (!wo->mppe && ao->mppe)) &&
692 +       len >= CILEN_MPPE && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
693  
694 -       if (!try.mppe) {
695 -           error("MPPE required but peer negotiation failed");
696 -           lcp_close(f->unit, "MPPE required but peer negotiation failed");
697 +       if (go->mppc) {
698 +           no.mppc = 1;
699 +           if (!(p[5] & MPPE_MPPC))
700 +               try.mppc = 0;
701 +       }
702 +
703 +       if (go->mppe)
704 +           no.mppe = 1;
705 +       if (go->mppe_40)
706 +           no.mppe_40 = 1;
707 +       if (go->mppe_56)
708 +           no.mppe_56 = 1;
709 +       if (go->mppe_128)
710 +           no.mppe_128 = 1;
711 +       if (go->mppe_stateless)
712 +           no.mppe_stateless = 1;
713 +
714 +       if (ao->mppe_40) {
715 +           if ((p[5] & MPPE_40BIT))
716 +               try.mppe_40 = 1;
717 +           else
718 +               try.mppe_40 = (p[5] == 0) ? 1 : 0;
719 +       }
720 +       if (ao->mppe_56) {
721 +           if ((p[5] & MPPE_56BIT))
722 +               try.mppe_56 = 1;
723 +           else
724 +               try.mppe_56 = (p[5] == 0) ? 1 : 0;
725 +       }
726 +       if (ao->mppe_128) {
727 +           if ((p[5] & MPPE_128BIT))
728 +               try.mppe_128 = 1;
729 +           else
730 +               try.mppe_128 = (p[5] == 0) ? 1 : 0;
731 +       }
732 +
733 +       if (ao->mppe_stateless) {
734 +           if ((p[2] & MPPE_STATELESS) || wo->mppe_stateless)
735 +               try.mppe_stateless = 1;
736 +           else
737 +               try.mppe_stateless = 0;
738 +       }
739 +
740 +       if (!try.mppe_56 && !try.mppe_40 && !try.mppe_128) {
741 +           try.mppe = try.mppe_stateless = 0;
742 +           if (wo->mppe) {
743 +               /* we require encryption, but peer doesn't support it
744 +                  so we close connection */
745 +               wo->mppc = wo->mppe = wo->mppe_stateless = wo->mppe_40 =
746 +                   wo->mppe_56 = wo->mppe_128 = 0;
747 +               lcp_close(f->unit, "MPPE required but cannot negotiate MPPE "
748 +                         "key length");
749 +           }
750 +        }
751 +       if (wo->mppe && (wo->mppe_40 != try.mppe_40) &&
752 +           (wo->mppe_56 != try.mppe_56) && (wo->mppe_128 != try.mppe_128)) {
753 +           /* cannot negotiate key length */
754 +           wo->mppc = wo->mppe = wo->mppe_stateless = wo->mppe_40 =
755 +               wo->mppe_56 = wo->mppe_128 = 0;
756 +           lcp_close(f->unit, "Cannot negotiate MPPE key length");
757         }
758 +       if (try.mppe_40 && try.mppe_56 && try.mppe_128)
759 +           try.mppe_40 = try.mppe_56 = 0;
760 +       else
761 +           if (try.mppe_56 && try.mppe_128)
762 +               try.mppe_56 = 0;
763 +           else
764 +               if (try.mppe_40 && try.mppe_128)
765 +                   try.mppe_40 = 0;
766 +               else
767 +                   if (try.mppe_40 && try.mppe_56)
768 +                       try.mppe_40 = 0;
769 +
770 +       p += CILEN_MPPE;
771 +       len -= CILEN_MPPE;
772      }
773  #endif /* MPPE */
774 +
775 +    if (go->lzs && len >= CILEN_LZS && p[0] == CI_LZS && p[1] == CILEN_LZS) {
776 +       no.lzs = 1;
777 +       if (((p[2]<<8)|p[3]) > 1 || (p[4] != LZS_MODE_SEQ &&
778 +                                    p[4] != LZS_MODE_EXT))
779 +           try.lzs = 0;
780 +       else {
781 +           try.lzs_mode = p[4];
782 +           try.lzs_hists = (p[2] << 8) | p[3];
783 +       }
784 +       p += CILEN_LZS;
785 +       len -= CILEN_LZS;
786 +    }
787 +
788      if (go->deflate && len >= CILEN_DEFLATE
789         && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
790         && p[1] == CILEN_DEFLATE) {
791 @@ -1006,14 +1211,50 @@
792         return -1;
793  
794  #ifdef MPPE
795 -    if (go->mppe && len >= CILEN_MPPE
796 +    if ((go->mppe || go->mppc) && len >= CILEN_MPPE
797         && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
798 -       error("MPPE required but peer refused");
799 -       lcp_close(f->unit, "MPPE required but peer refused");
800 +       ccp_options *wo = &ccp_wantoptions[f->unit];
801 +       if (p[2] != (go->mppe_stateless ? MPPE_STATELESS : 0) ||
802 +           p[3] != 0 ||
803 +           p[4] != 0 ||
804 +           p[5] != ((go->mppe_40 ? MPPE_40BIT : 0) |
805 +                    (go->mppe_56 ? MPPE_56BIT : 0) |
806 +                    (go->mppe_128 ? MPPE_128BIT : 0) |
807 +                    (go->mppc ? MPPE_MPPC : 0)))
808 +           return 0;
809 +       if (go->mppc)
810 +           try.mppc = 0;
811 +       if (go->mppe) {
812 +           try.mppe = 0;
813 +           if (go->mppe_40)
814 +               try.mppe_40 = 0;
815 +           if (go->mppe_56)
816 +               try.mppe_56 = 0;
817 +           if (go->mppe_128)
818 +               try.mppe_128 = 0;
819 +           if (go->mppe_stateless)
820 +               try.mppe_stateless = 0;
821 +           if (!try.mppe_56 && !try.mppe_40 && !try.mppe_128)
822 +               try.mppe = try.mppe_stateless = 0;
823 +           if (wo->mppe) { /* we want MPPE but cannot negotiate key length */
824 +               wo->mppc = wo->mppe = wo->mppe_stateless = wo->mppe_40 =
825 +                   wo->mppe_56 = wo->mppe_128 = 0;
826 +               lcp_close(f->unit, "MPPE required but cannot negotiate MPPE "
827 +                         "key length");
828 +           }
829 +       }
830         p += CILEN_MPPE;
831         len -= CILEN_MPPE;
832      }
833 -#endif
834 +#endif /* MPPE */
835 +    if (go->lzs && len >= CILEN_LZS && p[0] == CI_LZS && p[1] == CILEN_LZS) {
836 +       if (p[2] != go->lzs_hists>>8 || p[3] != (go->lzs_hists&0xff) 
837 +           || p[4] != go->lzs_mode)
838 +           return 0;
839 +       try.lzs = 0;
840 +       p += CILEN_LZS;
841 +       len -= CILEN_LZS;
842 +    }
843      if (go->deflate_correct && len >= CILEN_DEFLATE
844         && p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) {
845         if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
846 @@ -1077,14 +1318,15 @@
847      int dont_nak;
848  {
849      int ret, newret, res;
850 -    u_char *p0, *retp;
851 +    u_char *p0, *retp, p2, p5;
852      int len, clen, type, nb;
853      ccp_options *ho = &ccp_hisoptions[f->unit];
854      ccp_options *ao = &ccp_allowoptions[f->unit];
855 +    ccp_options *wo = &ccp_wantoptions[f->unit];
856  #ifdef MPPE
857 -    bool rej_for_ci_mppe = 1;  /* Are we rejecting based on a bad/missing */
858 -                               /* CI_MPPE, or due to other options?       */
859 -#endif
860 +    u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
861 +/*     int mtu; */
862 +#endif /* MPPE */
863  
864      ret = CONFACK;
865      retp = p0 = p;
866 @@ -1107,103 +1349,305 @@
867             switch (type) {
868  #ifdef MPPE
869             case CI_MPPE:
870 -               if (!ao->mppe || clen != CILEN_MPPE) {
871 +               if ((!ao->mppc && !ao->mppe) || clen != CILEN_MPPE) {
872                     newret = CONFREJ;
873                     break;
874                 }
875 -               MPPE_CI_TO_OPTS(&p[2], ho->mppe);
876  
877 -               /* Nak if anything unsupported or unknown are set. */
878 -               if (ho->mppe & MPPE_OPT_UNSUPPORTED) {
879 -                   newret = CONFNAK;
880 -                   ho->mppe &= ~MPPE_OPT_UNSUPPORTED;
881 -               }
882 -               if (ho->mppe & MPPE_OPT_UNKNOWN) {
883 +               p2 = p[2];
884 +               p5 = p[5];
885 +               /* not sure what they want, tell 'em what we got */
886 +               if (((p[2] & ~MPPE_STATELESS) != 0 || p[3] != 0 || p[4] != 0 ||
887 +                    (p[5] & ~(MPPE_40BIT | MPPE_56BIT | MPPE_128BIT |
888 +                              MPPE_MPPC)) != 0 || p[5] == 0) ||
889 +                   (p[2] == 0 && p[3] == 0 && p[4] == 0 &&  p[5] == 0)) {
890                     newret = CONFNAK;
891 -                   ho->mppe &= ~MPPE_OPT_UNKNOWN;
892 +                   p[2] = (wo->mppe_stateless ? MPPE_STATELESS : 0);
893 +                   p[3] = 0;
894 +                   p[4] = 0;
895 +                   p[5] = (wo->mppe_40 ? MPPE_40BIT : 0) |
896 +                       (wo->mppe_56 ? MPPE_56BIT : 0) |
897 +                       (wo->mppe_128 ? MPPE_128BIT : 0) |
898 +                       (wo->mppc ? MPPE_MPPC : 0);
899 +                   break;
900                 }
901  
902 -               /* Check state opt */
903 -               if (ho->mppe & MPPE_OPT_STATEFUL) {
904 -                   /*
905 -                    * We can Nak and request stateless, but it's a
906 -                    * lot easier to just assume the peer will request
907 -                    * it if he can do it; stateful mode is bad over
908 -                    * the Internet -- which is where we expect MPPE.
909 -                    */
910 -                  if (refuse_mppe_stateful) {
911 -                       error("Refusing MPPE stateful mode offered by peer");
912 +               if ((p[5] & MPPE_MPPC)) {
913 +                   if (ao->mppc) {
914 +                       ho->mppc = 1;
915 +                       BCOPY(p, opt_buf, CILEN_MPPE);
916 +                       opt_buf[2] = opt_buf[3] = opt_buf[4] = 0;
917 +                       opt_buf[5] = MPPE_MPPC;
918 +                       if (ccp_test(f->unit, opt_buf, CILEN_MPPE, 1) <= 0) {
919 +                           ho->mppc = 0;
920 +                           p[5] &= ~MPPE_MPPC;
921 +                           newret = CONFNAK;
922 +                       }
923 +                   } else {
924                         newret = CONFREJ;
925 -                       break;
926 +                       if (wo->mppe || ao->mppe) {
927 +                           p[5] &= ~MPPE_MPPC;
928 +                           newret = CONFNAK;
929 +                       }
930 +                   }
931 +               }
932 +
933 +               if (ao->mppe)
934 +                   ho->mppe = 1;
935 +
936 +               if ((p[2] & MPPE_STATELESS)) {
937 +                   if (ao->mppe_stateless) {
938 +                       if (wo->mppe_stateless)
939 +                           ho->mppe_stateless = 1;
940 +                       else {
941 +                           newret = CONFNAK;
942 +                           if (!dont_nak)
943 +                               p[2] &= ~MPPE_STATELESS;
944 +                       }
945 +                   } else {
946 +                       newret = CONFNAK;
947 +                       if (!dont_nak)
948 +                           p[2] &= ~MPPE_STATELESS;
949 +                   }
950 +               } else {
951 +                   if (wo->mppe_stateless && !dont_nak) {
952 +                       wo->mppe_stateless = 0;
953 +                       newret = CONFNAK;
954 +                       p[2] |= MPPE_STATELESS;
955                     }
956                 }
957  
958 -               /* Find out which of {S,L} are set. */
959 -               if ((ho->mppe & MPPE_OPT_128)
960 -                    && (ho->mppe & MPPE_OPT_40)) {
961 -                   /* Both are set, negotiate the strongest. */
962 +               if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_56BIT|MPPE_128BIT)) {
963                     newret = CONFNAK;
964 -                   if (ao->mppe & MPPE_OPT_128)
965 -                       ho->mppe &= ~MPPE_OPT_40;
966 -                   else if (ao->mppe & MPPE_OPT_40)
967 -                       ho->mppe &= ~MPPE_OPT_128;
968 -                   else {
969 -                       newret = CONFREJ;
970 -                       break;
971 +                   if (ao->mppe_128) {
972 +                       ho->mppe_128 = 1;
973 +                       p[5] &= ~(MPPE_40BIT|MPPE_56BIT);
974 +                       BCOPY(p, opt_buf, CILEN_MPPE);
975 +                       BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
976 +                             MPPE_MAX_KEY_LEN);
977 +                       if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
978 +                                    MPPE_MAX_KEY_LEN, 1) <= 0) {
979 +                           ho->mppe_128 = 0;
980 +                           p[5] |= (MPPE_40BIT|MPPE_56BIT);
981 +                           p[5] &= ~MPPE_128BIT;
982 +                           goto check_mppe_56_40;
983 +                       }
984 +                       goto check_mppe;
985                     }
986 -               } else if (ho->mppe & MPPE_OPT_128) {
987 -                   if (!(ao->mppe & MPPE_OPT_128)) {
988 -                       newret = CONFREJ;
989 -                       break;
990 +                   p[5] &= ~MPPE_128BIT;
991 +                   goto check_mppe_56_40;
992 +               }
993 +               if ((p[5] & ~MPPE_MPPC) == (MPPE_56BIT|MPPE_128BIT)) {
994 +                   newret = CONFNAK;
995 +                   if (ao->mppe_128) {
996 +                       ho->mppe_128 = 1;
997 +                       p[5] &= ~MPPE_56BIT;
998 +                       BCOPY(p, opt_buf, CILEN_MPPE);
999 +                       BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
1000 +                             MPPE_MAX_KEY_LEN);
1001 +                       if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
1002 +                                    MPPE_MAX_KEY_LEN, 1) <= 0) {
1003 +                           ho->mppe_128 = 0;
1004 +                           p[5] |= MPPE_56BIT;
1005 +                           p[5] &= ~MPPE_128BIT;
1006 +                           goto check_mppe_56;
1007 +                       }
1008 +                       goto check_mppe;
1009                     }
1010 -               } else if (ho->mppe & MPPE_OPT_40) {
1011 -                   if (!(ao->mppe & MPPE_OPT_40)) {
1012 -                       newret = CONFREJ;
1013 -                       break;
1014 +                   p[5] &= ~MPPE_128BIT;
1015 +                   goto check_mppe_56;
1016 +               }
1017 +               if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_128BIT)) {
1018 +                   newret = CONFNAK;
1019 +                   if (ao->mppe_128) {
1020 +                       ho->mppe_128 = 1;
1021 +                       p[5] &= ~MPPE_40BIT;
1022 +                       BCOPY(p, opt_buf, CILEN_MPPE);
1023 +                       BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
1024 +                             MPPE_MAX_KEY_LEN);
1025 +                       if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
1026 +                                    MPPE_MAX_KEY_LEN, 1) <= 0) {
1027 +                           ho->mppe_128 = 0;
1028 +                           p[5] |= MPPE_40BIT;
1029 +                           p[5] &= ~MPPE_128BIT;
1030 +                           goto check_mppe_40;
1031 +                       }
1032 +                       goto check_mppe;
1033 +                   }
1034 +                   p[5] &= ~MPPE_128BIT;
1035 +                   goto check_mppe_40;
1036 +               }
1037 +               if ((p[5] & ~MPPE_MPPC) == MPPE_128BIT) {
1038 +                   if (ao->mppe_128) {
1039 +                       ho->mppe_128 = 1;
1040 +                       BCOPY(p, opt_buf, CILEN_MPPE);
1041 +                       BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
1042 +                             MPPE_MAX_KEY_LEN);
1043 +                       if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
1044 +                                    MPPE_MAX_KEY_LEN, 1) <= 0) {
1045 +                           ho->mppe_128 = 0;
1046 +                           p[5] &= ~MPPE_128BIT;
1047 +                           newret = CONFNAK;
1048 +                       }
1049 +                       goto check_mppe;
1050 +                   }
1051 +                   p[5] &= ~MPPE_128BIT;
1052 +                   newret = CONFNAK;
1053 +                   goto check_mppe;
1054 +               }
1055 +           check_mppe_56_40:
1056 +               if ((p[5] & ~MPPE_MPPC) == (MPPE_40BIT|MPPE_56BIT)) {
1057 +                   newret = CONFNAK;
1058 +                   if (ao->mppe_56) {
1059 +                       ho->mppe_56 = 1;
1060 +                       p[5] &= ~MPPE_40BIT;
1061 +                       BCOPY(p, opt_buf, CILEN_MPPE);
1062 +                       BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
1063 +                             MPPE_MAX_KEY_LEN);
1064 +                       if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
1065 +                                    MPPE_MAX_KEY_LEN, 1) <= 0) {
1066 +                           ho->mppe_56 = 0;
1067 +                           p[5] |= MPPE_40BIT;
1068 +                           p[5] &= ~MPPE_56BIT;
1069 +                           newret = CONFNAK;
1070 +                           goto check_mppe_40;
1071 +                       }
1072 +                       goto check_mppe;
1073 +                   }
1074 +                   p[5] &= ~MPPE_56BIT;
1075 +                   goto check_mppe_40;
1076 +               }
1077 +           check_mppe_56:
1078 +               if ((p[5] & ~MPPE_MPPC) == MPPE_56BIT) {
1079 +                   if (ao->mppe_56) {
1080 +                       ho->mppe_56 = 1;
1081 +                       BCOPY(p, opt_buf, CILEN_MPPE);
1082 +                       BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
1083 +                             MPPE_MAX_KEY_LEN);
1084 +                       if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
1085 +                                    MPPE_MAX_KEY_LEN, 1) <= 0) {
1086 +                           ho->mppe_56 = 0;
1087 +                           p[5] &= ~MPPE_56BIT;
1088 +                           newret = CONFNAK;
1089 +                       }
1090 +                       goto check_mppe;
1091 +                   }
1092 +                   p[5] &= ~MPPE_56BIT;
1093 +                   newret = CONFNAK;
1094 +                   goto check_mppe;
1095 +               }
1096 +           check_mppe_40:
1097 +               if ((p[5] & ~MPPE_MPPC) == MPPE_40BIT) {
1098 +                   if (ao->mppe_40) {
1099 +                       ho->mppe_40 = 1;
1100 +                       BCOPY(p, opt_buf, CILEN_MPPE);
1101 +                       BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
1102 +                             MPPE_MAX_KEY_LEN);
1103 +                       if (ccp_test(f->unit, opt_buf, CILEN_MPPE +
1104 +                                    MPPE_MAX_KEY_LEN, 1) <= 0) {
1105 +                           ho->mppe_40 = 0;
1106 +                           p[5] &= ~MPPE_40BIT;
1107 +                           newret = CONFNAK;
1108 +                       }
1109 +                       goto check_mppe;
1110 +                   }
1111 +                   p[5] &= ~MPPE_40BIT;
1112 +               }
1113 +
1114 +           check_mppe:
1115 +               if (!ho->mppe_40 && !ho->mppe_56 && !ho->mppe_128) {
1116 +                   if (wo->mppe_40 || wo->mppe_56 || wo->mppe_128) {
1117 +                       newret = CONFNAK;
1118 +                       p[2] |= (wo->mppe_stateless ? MPPE_STATELESS : 0);
1119 +                       p[5] |= (wo->mppe_40 ? MPPE_40BIT : 0) |
1120 +                           (wo->mppe_56 ? MPPE_56BIT : 0) |
1121 +                           (wo->mppe_128 ? MPPE_128BIT : 0) |
1122 +                           (wo->mppc ? MPPE_MPPC : 0);
1123 +                   } else {
1124 +                       ho->mppe = ho->mppe_stateless = 0;
1125                     }
1126                 } else {
1127 -                   /* Neither are set. */
1128 +                   /* MPPE is not compatible with other compression types */
1129 +                   if (wo->mppe) {
1130 +                       ao->bsd_compress = 0;
1131 +                       ao->predictor_1 = 0;
1132 +                       ao->predictor_2 = 0;
1133 +                       ao->deflate = 0;
1134 +                       ao->lzs = 0;
1135 +                   }
1136 +               }
1137 +               if ((!ho->mppc || !ao->mppc) && !ho->mppe) {
1138 +                   p[2] = p2;
1139 +                   p[5] = p5;
1140                     newret = CONFREJ;
1141                     break;
1142                 }
1143  
1144 -               /* rebuild the opts */
1145 -               MPPE_OPTS_TO_CI(ho->mppe, &p[2]);
1146 -               if (newret == CONFACK) {
1147 -                   u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
1148 -                   int mtu;
1149 -
1150 -                   BCOPY(p, opt_buf, CILEN_MPPE);
1151 -                   BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
1152 -                         MPPE_MAX_KEY_LEN);
1153 -                   if (ccp_test(f->unit, opt_buf,
1154 -                                CILEN_MPPE + MPPE_MAX_KEY_LEN, 1) <= 0) {
1155 -                       /* This shouldn't happen, we've already tested it! */
1156 -                       error("MPPE required, but kernel has no support.");
1157 -                       lcp_close(f->unit, "MPPE required but not available");
1158 -                       newret = CONFREJ;
1159 -                       break;
1160 -                   }
1161 -                   /*
1162 -                    * We need to decrease the interface MTU by MPPE_PAD
1163 -                    * because MPPE frames **grow**.  The kernel [must]
1164 -                    * allocate MPPE_PAD extra bytes in xmit buffers.
1165 -                    */
1166 -                   mtu = netif_get_mtu(f->unit);
1167 -                   if (mtu)
1168 -                       netif_set_mtu(f->unit, mtu - MPPE_PAD);
1169 -                   else
1170 -                       newret = CONFREJ;
1171 -               }
1172 +               /*
1173 +                * I have commented the code below because according to RFC1547
1174 +                * MTU is only information for higher level protocols about
1175 +                * "the maximum allowable length for a packet (q.v.) transmitted
1176 +                * over a point-to-point link without incurring network layer
1177 +                * fragmentation." Of course a PPP implementation should be able
1178 +                * to handle overhead added by MPPE - in our case apropriate code
1179 +                * is located in drivers/net/ppp_generic.c in the kernel sources.
1180 +                *
1181 +                * According to RFC1661:
1182 +                * - when negotiated MRU is less than 1500 octets, a PPP
1183 +                *   implementation must still be able to receive at least 1500
1184 +                *   octets,
1185 +                * - when PFC is negotiated, a PPP implementation is still
1186 +                *   required to receive frames with uncompressed protocol field.
1187 +                *
1188 +                * So why not to handle MPPE overhead without changing MTU value?
1189 +                * I am sure that RFC3078, unfortunately silently, assumes that.
1190 +                */
1191  
1192                 /*
1193 -                * We have accepted MPPE or are willing to negotiate
1194 -                * MPPE parameters.  A CONFREJ is due to subsequent
1195 -                * (non-MPPE) processing.
1196 +                * We need to decrease the interface MTU by MPPE_PAD
1197 +                * because MPPE frames **grow**.  The kernel [must]
1198 +                * allocate MPPE_PAD extra bytes in xmit buffers.
1199                  */
1200 -               rej_for_ci_mppe = 0;
1201 +/*
1202 +               mtu = netif_get_mtu(f->unit);
1203 +               if (mtu) {
1204 +                   netif_set_mtu(f->unit, mtu - MPPE_PAD);
1205 +               } else {
1206 +                   newret = CONFREJ;
1207 +                   if (ccp_wantoptions[f->unit].mppe) {
1208 +                       error("Cannot adjust MTU needed by MPPE.");
1209 +                       lcp_close(f->unit, "Cannot adjust MTU needed by MPPE.");
1210 +                   }
1211 +               }
1212 +*/
1213                 break;
1214  #endif /* MPPE */
1215 +
1216 +           case CI_LZS:
1217 +               if (!ao->lzs || clen != CILEN_LZS) {
1218 +                   newret = CONFREJ;
1219 +                   break;
1220 +               }
1221 +
1222 +               ho->lzs = 1;
1223 +               ho->lzs_hists = (p[2] << 8) | p[3];
1224 +               ho->lzs_mode = p[4];
1225 +               if ((ho->lzs_hists != ao->lzs_hists) ||
1226 +                   (ho->lzs_mode != ao->lzs_mode)) {
1227 +                   newret = CONFNAK;
1228 +                   if (!dont_nak) {
1229 +                       p[2] = ao->lzs_hists >> 8;
1230 +                       p[3] = ao->lzs_hists & 0xff;
1231 +                       p[4] = ao->lzs_mode;
1232 +                   } else
1233 +                       break;
1234 +               }
1235 +
1236 +               if (p == p0 && ccp_test(f->unit, p, CILEN_LZS, 1) <= 0) {
1237 +                   newret = CONFREJ;
1238 +               }
1239 +               break;
1240 +
1241             case CI_DEFLATE:
1242             case CI_DEFLATE_DRAFT:
1243                 if (!ao->deflate || clen != CILEN_DEFLATE
1244 @@ -1345,12 +1789,6 @@
1245         else
1246             *lenp = retp - p0;
1247      }
1248 -#ifdef MPPE
1249 -    if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) {
1250 -       error("MPPE required but peer negotiation failed");
1251 -       lcp_close(f->unit, "MPPE required but peer negotiation failed");
1252 -    }
1253 -#endif
1254      return ret;
1255  }
1256  
1257 @@ -1372,24 +1810,35 @@
1258         char *p = result;
1259         char *q = result + sizeof(result); /* 1 past result */
1260  
1261 -       slprintf(p, q - p, "MPPE ");
1262 -       p += 5;
1263 -       if (opt->mppe & MPPE_OPT_128) {
1264 -           slprintf(p, q - p, "128-bit ");
1265 -           p += 8;
1266 -       }
1267 -       if (opt->mppe & MPPE_OPT_40) {
1268 -           slprintf(p, q - p, "40-bit ");
1269 -           p += 7;
1270 -       }
1271 -       if (opt->mppe & MPPE_OPT_STATEFUL)
1272 -           slprintf(p, q - p, "stateful");
1273 -       else
1274 -           slprintf(p, q - p, "stateless");
1275 -
1276 +       if (opt->mppe) {
1277 +           if (opt->mppc) {
1278 +               slprintf(p, q - p, "MPPC/MPPE ");
1279 +               p += 10;
1280 +           } else {
1281 +               slprintf(p, q - p, "MPPE ");
1282 +               p += 5;
1283 +           }
1284 +           if (opt->mppe_128) {
1285 +               slprintf(p, q - p, "128-bit ");
1286 +               p += 8;
1287 +           } else if (opt->mppe_56) {
1288 +               slprintf(p, q - p, "56-bit ");
1289 +               p += 7;
1290 +           } else if (opt->mppe_40) {
1291 +               slprintf(p, q - p, "40-bit ");
1292 +               p += 7;
1293 +           }
1294 +           if (opt->mppe_stateless)
1295 +               slprintf(p, q - p, "stateless");
1296 +           else
1297 +               slprintf(p, q - p, "stateful");
1298 +       } else if (opt->mppc)
1299 +           slprintf(p, q - p, "MPPC");
1300         break;
1301      }
1302 -#endif
1303 +#endif /* MPPE */
1304 +    case CI_LZS:
1305 +       return "Stac LZS";
1306      case CI_DEFLATE:
1307      case CI_DEFLATE_DRAFT:
1308         if (opt2 != NULL && opt2->deflate_size != opt->deflate_size)
1309 @@ -1445,12 +1894,12 @@
1310      } else if (ANY_COMPRESS(*ho))
1311         notice("%s transmit compression enabled", method_name(ho, NULL));
1312  #ifdef MPPE
1313 -    if (go->mppe) {
1314 +    if (go->mppe || go->mppc) {
1315         BZERO(mppe_recv_key, MPPE_MAX_KEY_LEN);
1316         BZERO(mppe_send_key, MPPE_MAX_KEY_LEN);
1317         continue_networks(f->unit);             /* Bring up IP et al */
1318      }
1319 -#endif
1320 +#endif /* MPPE */
1321  }
1322  
1323  /*
1324 @@ -1473,7 +1922,7 @@
1325             lcp_close(f->unit, "MPPE disabled");
1326         }
1327      }
1328 -#endif
1329 +#endif /* MPPE */
1330  }
1331  
1332  /*
1333 @@ -1533,24 +1982,28 @@
1334  #ifdef MPPE
1335             case CI_MPPE:
1336                 if (optlen >= CILEN_MPPE) {
1337 -                   u_char mppe_opts;
1338 -
1339 -                   MPPE_CI_TO_OPTS(&p[2], mppe_opts);
1340 -                   printer(arg, "mppe %s %s %s %s %s %s%s",
1341 -                           (p[2] & MPPE_H_BIT)? "+H": "-H",
1342 -                           (p[5] & MPPE_M_BIT)? "+M": "-M",
1343 -                           (p[5] & MPPE_S_BIT)? "+S": "-S",
1344 -                           (p[5] & MPPE_L_BIT)? "+L": "-L",
1345 +                   printer(arg, "mppe %s %s %s %s %s %s",
1346 +                           (p[2] & MPPE_STATELESS)? "+H": "-H",
1347 +                           (p[5] & MPPE_56BIT)? "+M": "-M",
1348 +                           (p[5] & MPPE_128BIT)? "+S": "-S",
1349 +                           (p[5] & MPPE_40BIT)? "+L": "-L",
1350                             (p[5] & MPPE_D_BIT)? "+D": "-D",
1351 -                           (p[5] & MPPE_C_BIT)? "+C": "-C",
1352 -                           (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": "");
1353 -                   if (mppe_opts & MPPE_OPT_UNKNOWN)
1354 +                           (p[5] & MPPE_MPPC)? "+C": "-C");
1355 +                   if ((p[5] & ~(MPPE_56BIT | MPPE_128BIT | MPPE_40BIT |
1356 +                                 MPPE_D_BIT | MPPE_MPPC)) ||
1357 +                       (p[2] & ~MPPE_STATELESS))
1358                         printer(arg, " (%.2x %.2x %.2x %.2x)",
1359                                 p[2], p[3], p[4], p[5]);
1360                     p += CILEN_MPPE;
1361                 }
1362                 break;
1363 -#endif
1364 +#endif /* MPPE */
1365 +           case CI_LZS:
1366 +               if (optlen >= CILEN_LZS) {
1367 +                   printer(arg, "lzs %.2x %.2x %.2x", p[2], p[3], p[4]);
1368 +                   p += CILEN_LZS;
1369 +               }
1370 +               break;
1371             case CI_DEFLATE:
1372             case CI_DEFLATE_DRAFT:
1373                 if (optlen >= CILEN_DEFLATE) {
1374 @@ -1636,6 +2089,7 @@
1375             error("Lost compression sync: disabling compression");
1376             ccp_close(unit, "Lost compression sync");
1377  #ifdef MPPE
1378 +           /* My module dosn't need this. J.D., 2003-07-06 */
1379             /*
1380              * If we were doing MPPE, we must also take the link down.
1381              */
1382 @@ -1643,9 +2097,18 @@
1383                 error("Too many MPPE errors, closing LCP");
1384                 lcp_close(unit, "Too many MPPE errors");
1385             }
1386 -#endif
1387 +#endif /* MPPE */
1388         } else {
1389             /*
1390 +            * When LZS or MPPE/MPPC is negotiated we just send CCP_RESETREQ
1391 +            * and don't wait for CCP_RESETACK
1392 +            */
1393 +           if ((ccp_gotoptions[f->unit].method == CI_LZS) ||
1394 +               (ccp_gotoptions[f->unit].method == CI_MPPE)) {
1395 +               fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0);
1396 +               return;
1397 +           }
1398 +           /*
1399              * Send a reset-request to reset the peer's compressor.
1400              * We don't do that if we are still waiting for an
1401              * acknowledgement to a previous reset-request.
1402 @@ -1676,4 +2139,3 @@
1403      } else
1404         ccp_localstate[f->unit] &= ~RACK_PENDING;
1405  }
1406 -
1407 diff -ruN ppp-2.4.2.orig/pppd/ccp.h ppp-2.4.2-stdopt/pppd/ccp.h
1408 --- ppp-2.4.2.orig/pppd/ccp.h   2002-12-05 00:03:32.000000000 +0100
1409 +++ ppp-2.4.2-stdopt/pppd/ccp.h 2004-01-21 06:51:09.000000000 +0100
1410 @@ -42,9 +42,17 @@
1411      bool predictor_2;          /* do Predictor-2? */
1412      bool deflate_correct;      /* use correct code for deflate? */
1413      bool deflate_draft;                /* use draft RFC code for deflate? */
1414 +    bool lzs;                  /* do Stac LZS? */
1415 +    bool mppc;                 /* do MPPC? */
1416      bool mppe;                 /* do MPPE? */
1417 +    bool mppe_40;              /* allow 40 bit encryption? */
1418 +    bool mppe_56;              /* allow 56 bit encryption? */
1419 +    bool mppe_128;             /* allow 128 bit encryption? */
1420 +    bool mppe_stateless;       /* allow stateless encryption */
1421      u_short bsd_bits;          /* # bits/code for BSD Compress */
1422      u_short deflate_size;      /* lg(window size) for Deflate */
1423 +    u_short lzs_mode;          /* LZS check mode */
1424 +    u_short lzs_hists;         /* number of LZS histories */
1425      short method;              /* code for chosen compression method */
1426  } ccp_options;
1427  
1428 diff -ruN ppp-2.4.2.orig/pppd/chap_ms.c ppp-2.4.2-stdopt/pppd/chap_ms.c
1429 --- ppp-2.4.2.orig/pppd/chap_ms.c       2003-11-18 11:42:56.000000000 +0100
1430 +++ ppp-2.4.2-stdopt/pppd/chap_ms.c     2004-01-21 06:51:09.000000000 +0100
1431 @@ -858,13 +858,17 @@
1432      /*
1433       * Disable undesirable encryption types.  Note that we don't ENABLE
1434       * any encryption types, to avoid overriding manual configuration.
1435 +     *
1436 +     * It seems that 56 bit keys are unsupported in MS-RADIUS (see RFC 2548)
1437       */
1438      switch(types) {
1439         case MPPE_ENC_TYPES_RC4_40:
1440 -           ccp_wantoptions[0].mppe &= ~MPPE_OPT_128;   /* disable 128-bit */
1441 +           ccp_wantoptions[0].mppe_128 = 0;    /* disable 128-bit */
1442 +           ccp_wantoptions[0].mppe_56 = 0;     /* disable 56-bit */
1443             break;
1444         case MPPE_ENC_TYPES_RC4_128:
1445 -           ccp_wantoptions[0].mppe &= ~MPPE_OPT_40;    /* disable 40-bit */
1446 +           ccp_wantoptions[0].mppe_56 = 0;     /* disable 56-bit */
1447 +           ccp_wantoptions[0].mppe_40 = 0;     /* disable 40-bit */
1448             break;
1449         default:
1450             break;
1451 diff -ruN ppp-2.4.2.orig/pppd/pppd.8 ppp-2.4.2-stdopt/pppd/pppd.8
1452 --- ppp-2.4.2.orig/pppd/pppd.8  2004-01-15 06:09:00.000000000 +0100
1453 +++ ppp-2.4.2-stdopt/pppd/pppd.8        2004-01-21 06:51:09.000000000 +0100
1454 @@ -614,6 +614,9 @@
1455  Enables the use of PPP multilink; this is an alias for the `multilink'
1456  option.  This option is currently only available under Linux.
1457  .TP
1458 +.B mppc
1459 +Enables MPPC (Microsoft Point to Point Compression).  This is the default.
1460 +.TP
1461  .B mppe-stateful
1462  Allow MPPE to use stateful mode.  Stateless mode is still attempted first.
1463  The default is to disallow stateful mode.  
1464 @@ -749,12 +752,18 @@
1465  Disables the use of PPP multilink.  This option is currently only
1466  available under Linux.
1467  .TP
1468 +.B nomppc
1469 +Diasables MPPC (Microsoft Point to Point Compression).
1470 +.TP
1471  .B nomppe
1472  Disables MPPE (Microsoft Point to Point Encryption).  This is the default.
1473  .TP
1474  .B nomppe-40
1475  Disable 40\-bit encryption with MPPE.
1476  .TP
1477 +.B nomppe-56
1478 +Disable 56\-bit encryption with MPPE.
1479 +.TP
1480  .B nomppe-128
1481  Disable 128\-bit encryption with MPPE.
1482  .TP
1483 @@ -951,6 +960,9 @@
1484  .B require-mppe-40
1485  Require the use of MPPE, with 40\-bit encryption.
1486  .TP
1487 +.B require-mppe-56
1488 +Require the use of MPPE, with 56\-bit encryption.
1489 +.TP
1490  .B require-mppe-128
1491  Require the use of MPPE, with 128\-bit encryption.
1492  .TP
1493 diff -ruN ppp-2.4.2.orig/pppd/sha1.c ppp-2.4.2-stdopt/pppd/sha1.c
1494 --- ppp-2.4.2.orig/pppd/sha1.c  2002-04-02 15:54:59.000000000 +0200
1495 +++ ppp-2.4.2-stdopt/pppd/sha1.c        2004-08-15 15:00:55.000000000 +0200
1496 @@ -21,7 +21,7 @@
1497  #include "sha1.h"
1498  
1499  static void
1500 -SHA1_Transform(unsigned long[5], const unsigned char[64]);
1501 +SHA1_Transform(u_int32_t state[5], const u_int8_t buffer[64]);
1502  
1503  #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
1504  
1505 @@ -42,17 +42,17 @@
1506  /* Hash a single 512-bit block. This is the core of the algorithm. */
1507  
1508  static void
1509 -SHA1_Transform(unsigned long state[5], const unsigned char buffer[64])
1510 +SHA1_Transform(u_int32_t state[5], const u_int8_t buffer[64])
1511  {
1512 -    unsigned long a, b, c, d, e;
1513 +    u_int32_t a, b, c, d, e;
1514      typedef union {
1515 -       unsigned char c[64];
1516 -       unsigned long l[16];
1517 +       u_int8_t c[64];
1518 +       u_int32_t l[16];
1519      } CHAR64LONG16;
1520      CHAR64LONG16 *block;
1521  
1522  #ifdef SHA1HANDSOFF
1523 -    static unsigned char workspace[64];
1524 +    static u_int8_t workspace[64];
1525      block = (CHAR64LONG16 *) workspace;
1526      memcpy(block, buffer, 64);
1527  #else
1528 @@ -114,9 +114,9 @@
1529  /* Run your data through this. */
1530  
1531  void
1532 -SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len)
1533 +SHA1_Update(SHA1_CTX *context, const u_int8_t *data, u_int32_t len)
1534  {
1535 -    unsigned int i, j;
1536 +    u_int32_t i, j;
1537  
1538      j = (context->count[0] >> 3) & 63;
1539      if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
1540 @@ -139,22 +139,24 @@
1541  /* Add padding and return the message digest. */
1542  
1543  void
1544 -SHA1_Final(unsigned char digest[20], SHA1_CTX *context)
1545 +SHA1_Final(u_int8_t digest[SHA1_SIGNATURE_SIZE], SHA1_CTX *context)
1546  {
1547 -    unsigned long i, j;
1548 -    unsigned char finalcount[8];
1549 +    u_int32_t i, j;
1550 +    u_int8_t finalcount[8];
1551  
1552      for (i = 0; i < 8; i++) {
1553 -        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
1554 +        finalcount[i] = (u_int8_t) ((context->count[(i >= 4 ? 0 : 1)]
1555           >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
1556      }
1557 -    SHA1_Update(context, (unsigned char *) "\200", 1);
1558 +    SHA1_Update(context, (u_int8_t *) "\200", 1);
1559      while ((context->count[0] & 504) != 448) {
1560 -       SHA1_Update(context, (unsigned char *) "\0", 1);
1561 +       SHA1_Update(context, (u_int8_t *) "\0", 1);
1562      }
1563 +       
1564      SHA1_Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
1565 +       
1566      for (i = 0; i < 20; i++) {
1567 -       digest[i] = (unsigned char)
1568 +       digest[i] = (u_int8_t)
1569                      ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
1570      }
1571      /* Wipe variables */
1572 @@ -167,4 +169,3 @@
1573      SHA1Transform(context->state, context->buffer);
1574  #endif
1575  }
1576 -
1577 diff -ruN ppp-2.4.2.orig/pppd/sha1.h ppp-2.4.2-stdopt/pppd/sha1.h
1578 --- ppp-2.4.2.orig/pppd/sha1.h  2002-11-09 12:24:42.000000000 +0100
1579 +++ ppp-2.4.2-stdopt/pppd/sha1.h        2004-08-15 15:00:55.000000000 +0200
1580 @@ -8,6 +8,8 @@
1581  
1582  #ifndef __SHA1_INCLUDE_
1583  
1584 +#include <sys/types.h>
1585 +
1586  #ifndef SHA1_SIGNATURE_SIZE
1587  #ifdef SHA_DIGESTSIZE
1588  #define SHA1_SIGNATURE_SIZE SHA_DIGESTSIZE
1589 @@ -17,14 +19,14 @@
1590  #endif
1591  
1592  typedef struct {
1593 -    unsigned long state[5];
1594 -    unsigned long count[2];
1595 -    unsigned char buffer[64];
1596 +    u_int32_t state[5];
1597 +    u_int32_t count[2];
1598 +    u_int8_t buffer[64];
1599  } SHA1_CTX;
1600  
1601  extern void SHA1_Init(SHA1_CTX *);
1602 -extern void SHA1_Update(SHA1_CTX *, const unsigned char *, unsigned int);
1603 -extern void SHA1_Final(unsigned char[SHA1_SIGNATURE_SIZE], SHA1_CTX *);
1604 +extern void SHA1_Update(SHA1_CTX *, const u_int8_t *, u_int32_t);
1605 +extern void SHA1_Final(u_int8_t[SHA1_SIGNATURE_SIZE], SHA1_CTX *);
1606  
1607  #define __SHA1_INCLUDE_
1608  #endif /* __SHA1_INCLUDE_ */