]> git.ozlabs.org Git - ppp.git/blob - pppd/ccp.c
CI: Updated the 'checkout' actions that were using Node.js 16 to Node.js 20. (#489)
[ppp.git] / pppd / ccp.c
1 /*
2  * ccp.c - PPP Compression Control Protocol.
3  *
4  * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. The name(s) of the authors of this software must not be used to
14  *    endorse or promote products derived from this software without
15  *    prior written permission.
16  *
17  * 3. Redistributions of any form whatsoever must retain the following
18  *    acknowledgment:
19  *    "This product includes software developed by Paul Mackerras
20  *     <paulus@samba.org>".
21  *
22  * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
23  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
24  * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
26  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
27  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
28  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29  */
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #define RCSID   "$Id: ccp.c,v 1.50 2005/06/26 19:34:41 carlsonj Exp $"
36
37 #include <stdlib.h>
38 #include <string.h>
39 #if defined(SOL2)
40 #include <net/ppp-comp.h>
41 #else
42 #include <linux/ppp-comp.h>
43 #endif
44
45 #include "pppd.h"
46 #include "fsm.h"
47 #include "ccp.h"
48
49 #include "chap_ms.h"
50 #include "mppe.h"
51 #include "lcp.h"        /* lcp_close(), lcp_fsm */
52
53
54 /*
55  * Unfortunately there is a bug in zlib which means that using a
56  * size of 8 (window size = 256) for Deflate compression will cause
57  * buffer overruns and kernel crashes in the deflate module.
58  * Until this is fixed we only accept sizes in the range 9 .. 15.
59  * Thanks to James Carlson for pointing this out.
60  */
61 #define DEFLATE_MIN_WORKS       9
62
63 /*
64  * Command-line options.
65  */
66 static int setbsdcomp (char **);
67 static int setdeflate (char **);
68 static char bsd_value[8];
69 static char deflate_value[8];
70
71 /*
72  * Option variables.
73  */
74 #ifdef PPP_WITH_MPPE
75 bool refuse_mppe_stateful = 1;          /* Allow stateful mode? */
76 #endif
77
78 static option_t ccp_option_list[] = {
79     { "noccp", o_bool, &ccp_protent.enabled_flag,
80       "Disable CCP negotiation" },
81     { "-ccp", o_bool, &ccp_protent.enabled_flag,
82       "Disable CCP negotiation", OPT_ALIAS },
83
84     { "bsdcomp", o_special, (void *)setbsdcomp,
85       "Request BSD-Compress packet compression",
86       OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, bsd_value },
87     { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress,
88       "don't allow BSD-Compress", OPT_PRIOSUB | OPT_A2CLR,
89       &ccp_allowoptions[0].bsd_compress },
90     { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress,
91       "don't allow BSD-Compress", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
92       &ccp_allowoptions[0].bsd_compress },
93
94     { "deflate", o_special, (void *)setdeflate,
95       "request Deflate compression",
96       OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, deflate_value },
97     { "nodeflate", o_bool, &ccp_wantoptions[0].deflate,
98       "don't allow Deflate compression", OPT_PRIOSUB | OPT_A2CLR,
99       &ccp_allowoptions[0].deflate },
100     { "-deflate", o_bool, &ccp_wantoptions[0].deflate,
101       "don't allow Deflate compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
102       &ccp_allowoptions[0].deflate },
103
104     { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft,
105       "don't use draft deflate #", OPT_A2COPY,
106       &ccp_allowoptions[0].deflate_draft },
107
108     { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1,
109       "request Predictor-1", OPT_PRIO | 1 },
110     { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1,
111       "don't allow Predictor-1", OPT_PRIOSUB | OPT_A2CLR,
112       &ccp_allowoptions[0].predictor_1 },
113     { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1,
114       "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR,
115       &ccp_allowoptions[0].predictor_1 },
116
117 #ifdef PPP_WITH_MPPE
118     /* MPPE options are symmetrical ... we only set wantoptions here */
119     { "require-mppe", o_bool, &ccp_wantoptions[0].mppe,
120       "require MPPE encryption",
121       OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
122     { "+mppe", o_bool, &ccp_wantoptions[0].mppe,
123       "require MPPE encryption",
124       OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 },
125     { "nomppe", o_bool, &ccp_wantoptions[0].mppe,
126       "don't allow MPPE encryption", OPT_PRIO },
127     { "-mppe", o_bool, &ccp_wantoptions[0].mppe,
128       "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO },
129
130     /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */
131     { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
132       "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
133       &ccp_wantoptions[0].mppe },
134     { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe,
135       "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40,
136       &ccp_wantoptions[0].mppe },
137     { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe,
138       "don't allow MPPE 40-bit encryption",
139       OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe },
140     { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe,
141       "don't allow MPPE 40-bit encryption",
142       OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40,
143       &ccp_wantoptions[0].mppe },
144
145     { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
146       "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
147       &ccp_wantoptions[0].mppe },
148     { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe,
149       "require MPPE 128-bit encryption",
150       OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128,
151       &ccp_wantoptions[0].mppe },
152     { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe,
153       "don't allow MPPE 128-bit encryption",
154       OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe },
155     { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe,
156       "don't allow MPPE 128-bit encryption",
157       OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128,
158       &ccp_wantoptions[0].mppe },
159
160     /* strange one; we always request stateless, but will we allow stateful? */
161     { "mppe-stateful", o_bool, &refuse_mppe_stateful,
162       "allow MPPE stateful mode", OPT_PRIO },
163     { "nomppe-stateful", o_bool, &refuse_mppe_stateful,
164       "disallow MPPE stateful mode", OPT_PRIO | 1 },
165 #endif /* MPPE */
166
167     { NULL }
168 };
169
170 /*
171  * Protocol entry points from main code.
172  */
173 static void ccp_init (int unit);
174 static void ccp_open (int unit);
175 static void ccp_close (int unit, char *);
176 static void ccp_lowerup (int unit);
177 static void ccp_lowerdown (int);
178 static void ccp_input (int unit, u_char *pkt, int len);
179 static void ccp_protrej (int unit);
180 static int  ccp_printpkt (u_char *pkt, int len,
181                           void (*printer)(void *, char *, ...),
182                           void *arg);
183 static void ccp_datainput (int unit, u_char *pkt, int len);
184
185 struct protent ccp_protent = {
186     PPP_CCP,
187     ccp_init,
188     ccp_input,
189     ccp_protrej,
190     ccp_lowerup,
191     ccp_lowerdown,
192     ccp_open,
193     ccp_close,
194     ccp_printpkt,
195     ccp_datainput,
196     1,
197     "CCP",
198     "Compressed",
199     ccp_option_list,
200     NULL,
201     NULL,
202     NULL
203 };
204
205 fsm ccp_fsm[NUM_PPP];
206 ccp_options ccp_wantoptions[NUM_PPP];   /* what to request the peer to use */
207 ccp_options ccp_gotoptions[NUM_PPP];    /* what the peer agreed to do */
208 ccp_options ccp_allowoptions[NUM_PPP];  /* what we'll agree to do */
209 ccp_options ccp_hisoptions[NUM_PPP];    /* what we agreed to do */
210
211 /*
212  * Callbacks for fsm code.
213  */
214 static void ccp_resetci (fsm *);
215 static int  ccp_cilen (fsm *);
216 static void ccp_addci (fsm *, u_char *, int *);
217 static int  ccp_ackci (fsm *, u_char *, int);
218 static int  ccp_nakci (fsm *, u_char *, int, int);
219 static int  ccp_rejci (fsm *, u_char *, int);
220 static int  ccp_reqci (fsm *, u_char *, int *, int);
221 static void ccp_up (fsm *);
222 static void ccp_down (fsm *);
223 static int  ccp_extcode (fsm *, int, int, u_char *, int);
224 static void ccp_rack_timeout (void *);
225 static char *method_name (ccp_options *, ccp_options *);
226
227 static fsm_callbacks ccp_callbacks = {
228     ccp_resetci,
229     ccp_cilen,
230     ccp_addci,
231     ccp_ackci,
232     ccp_nakci,
233     ccp_rejci,
234     ccp_reqci,
235     ccp_up,
236     ccp_down,
237     NULL,
238     NULL,
239     NULL,
240     NULL,
241     ccp_extcode,
242     "CCP"
243 };
244
245 /*
246  * Do we want / did we get any compression?
247  */
248 #define ANY_COMPRESS(opt)       ((opt).deflate || (opt).bsd_compress \
249                                  || (opt).predictor_1 || (opt).predictor_2 \
250                                  || (opt).mppe)
251
252 /*
253  * Local state (mainly for handling reset-reqs and reset-acks).
254  */
255 static int ccp_localstate[NUM_PPP];
256 #define RACK_PENDING    1       /* waiting for reset-ack */
257 #define RREQ_REPEAT     2       /* send another reset-req if no reset-ack */
258
259 #define RACKTIMEOUT     1       /* second */
260
261 static int all_rejected[NUM_PPP];       /* we rejected all peer's options */
262
263 /*
264  * Option parsing.
265  */
266 static int
267 setbsdcomp(char **argv)
268 {
269     int rbits, abits;
270     char *str, *endp;
271
272     str = *argv;
273     abits = rbits = strtol(str, &endp, 0);
274     if (endp != str && *endp == ',') {
275         str = endp + 1;
276         abits = strtol(str, &endp, 0);
277     }
278     if (*endp != 0 || endp == str) {
279         option_error("invalid parameter '%s' for bsdcomp option", *argv);
280         return 0;
281     }
282     if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS))
283         || (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) {
284         option_error("bsdcomp option values must be 0 or %d .. %d",
285                      BSD_MIN_BITS, BSD_MAX_BITS);
286         return 0;
287     }
288     if (rbits > 0) {
289         ccp_wantoptions[0].bsd_compress = 1;
290         ccp_wantoptions[0].bsd_bits = rbits;
291     } else
292         ccp_wantoptions[0].bsd_compress = 0;
293     if (abits > 0) {
294         ccp_allowoptions[0].bsd_compress = 1;
295         ccp_allowoptions[0].bsd_bits = abits;
296     } else
297         ccp_allowoptions[0].bsd_compress = 0;
298     slprintf(bsd_value, sizeof(bsd_value),
299              rbits == abits? "%d": "%d,%d", rbits, abits);
300
301     return 1;
302 }
303
304 static int
305 setdeflate(char **argv)
306 {
307     int rbits, abits;
308     char *str, *endp;
309
310     str = *argv;
311     abits = rbits = strtol(str, &endp, 0);
312     if (endp != str && *endp == ',') {
313         str = endp + 1;
314         abits = strtol(str, &endp, 0);
315     }
316     if (*endp != 0 || endp == str) {
317         option_error("invalid parameter '%s' for deflate option", *argv);
318         return 0;
319     }
320     if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE))
321         || (abits != 0 && (abits < DEFLATE_MIN_SIZE
322                           || abits > DEFLATE_MAX_SIZE))) {
323         option_error("deflate option values must be 0 or %d .. %d",
324                      DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE);
325         return 0;
326     }
327     if (rbits == DEFLATE_MIN_SIZE || abits == DEFLATE_MIN_SIZE) {
328         if (rbits == DEFLATE_MIN_SIZE)
329             rbits = DEFLATE_MIN_WORKS;
330         if (abits == DEFLATE_MIN_SIZE)
331             abits = DEFLATE_MIN_WORKS;
332         warn("deflate option value of %d changed to %d to avoid zlib bug",
333              DEFLATE_MIN_SIZE, DEFLATE_MIN_WORKS);
334     }
335     if (rbits > 0) {
336         ccp_wantoptions[0].deflate = 1;
337         ccp_wantoptions[0].deflate_size = rbits;
338     } else
339         ccp_wantoptions[0].deflate = 0;
340     if (abits > 0) {
341         ccp_allowoptions[0].deflate = 1;
342         ccp_allowoptions[0].deflate_size = abits;
343     } else
344         ccp_allowoptions[0].deflate = 0;
345     slprintf(deflate_value, sizeof(deflate_value),
346              rbits == abits? "%d": "%d,%d", rbits, abits);
347
348     return 1;
349 }
350
351 /*
352  * ccp_init - initialize CCP.
353  */
354 static void
355 ccp_init(int unit)
356 {
357     fsm *f = &ccp_fsm[unit];
358
359     f->unit = unit;
360     f->protocol = PPP_CCP;
361     f->callbacks = &ccp_callbacks;
362     fsm_init(f);
363
364     memset(&ccp_wantoptions[unit],  0, sizeof(ccp_options));
365     memset(&ccp_gotoptions[unit],   0, sizeof(ccp_options));
366     memset(&ccp_allowoptions[unit], 0, sizeof(ccp_options));
367     memset(&ccp_hisoptions[unit],   0, sizeof(ccp_options));
368
369     ccp_wantoptions[0].deflate = 1;
370     ccp_wantoptions[0].deflate_size = DEFLATE_MAX_SIZE;
371     ccp_wantoptions[0].deflate_correct = 1;
372     ccp_wantoptions[0].deflate_draft = 1;
373     ccp_allowoptions[0].deflate = 1;
374     ccp_allowoptions[0].deflate_size = DEFLATE_MAX_SIZE;
375     ccp_allowoptions[0].deflate_correct = 1;
376     ccp_allowoptions[0].deflate_draft = 1;
377
378     ccp_wantoptions[0].bsd_compress = 1;
379     ccp_wantoptions[0].bsd_bits = BSD_MAX_BITS;
380     ccp_allowoptions[0].bsd_compress = 1;
381     ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS;
382
383     ccp_allowoptions[0].predictor_1 = 1;
384 }
385
386 /*
387  * ccp_open - CCP is allowed to come up.
388  */
389 static void
390 ccp_open(int unit)
391 {
392     fsm *f = &ccp_fsm[unit];
393
394     if (f->state != OPENED)
395         ccp_flags_set(unit, 1, 0);
396
397     /*
398      * Find out which compressors the kernel supports before
399      * deciding whether to open in silent mode.
400      */
401     ccp_resetci(f);
402     if (!ANY_COMPRESS(ccp_gotoptions[unit]))
403         f->flags |= OPT_SILENT;
404
405     fsm_open(f);
406 }
407
408 /*
409  * ccp_close - Terminate CCP.
410  */
411 static void
412 ccp_close(int unit, char *reason)
413 {
414     ccp_flags_set(unit, 0, 0);
415     fsm_close(&ccp_fsm[unit], reason);
416 }
417
418 /*
419  * ccp_lowerup - we may now transmit CCP packets.
420  */
421 static void
422 ccp_lowerup(int unit)
423 {
424     fsm_lowerup(&ccp_fsm[unit]);
425 }
426
427 /*
428  * ccp_lowerdown - we may not transmit CCP packets.
429  */
430 static void
431 ccp_lowerdown(int unit)
432 {
433     fsm_lowerdown(&ccp_fsm[unit]);
434 }
435
436 /*
437  * ccp_input - process a received CCP packet.
438  */
439 static void
440 ccp_input(int unit, u_char *p, int len)
441 {
442     fsm *f = &ccp_fsm[unit];
443     int oldstate;
444
445     /*
446      * Check for a terminate-request so we can print a message.
447      */
448     oldstate = f->state;
449     fsm_input(f, p, len);
450     if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED) {
451         notice("Compression disabled by peer.");
452 #ifdef PPP_WITH_MPPE
453         if (ccp_gotoptions[unit].mppe) {
454             error("MPPE disabled, closing LCP");
455             lcp_close(unit, "MPPE disabled by peer");
456         }
457 #endif
458     }
459
460     /*
461      * If we get a terminate-ack and we're not asking for compression,
462      * close CCP.
463      */
464     if (oldstate == REQSENT && p[0] == TERMACK
465         && !ANY_COMPRESS(ccp_gotoptions[unit]))
466         ccp_close(unit, "No compression negotiated");
467 }
468
469 /*
470  * Handle a CCP-specific code.
471  */
472 static int
473 ccp_extcode(fsm *f, int code, int id, u_char *p, int len)
474 {
475     switch (code) {
476     case CCP_RESETREQ:
477         if (f->state != OPENED)
478             break;
479         /* send a reset-ack, which the transmitter will see and
480            reset its compression state. */
481         fsm_sdata(f, CCP_RESETACK, id, NULL, 0);
482         break;
483
484     case CCP_RESETACK:
485         if (ccp_localstate[f->unit] & RACK_PENDING && id == f->reqid) {
486             ccp_localstate[f->unit] &= ~(RACK_PENDING | RREQ_REPEAT);
487             UNTIMEOUT(ccp_rack_timeout, f);
488         }
489         break;
490
491     default:
492         return 0;
493     }
494
495     return 1;
496 }
497
498 /*
499  * ccp_protrej - peer doesn't talk CCP.
500  */
501 static void
502 ccp_protrej(int unit)
503 {
504     ccp_flags_set(unit, 0, 0);
505     fsm_lowerdown(&ccp_fsm[unit]);
506
507 #ifdef PPP_WITH_MPPE
508     if (ccp_gotoptions[unit].mppe) {
509         error("MPPE required but peer negotiation failed");
510         lcp_close(unit, "MPPE required but peer negotiation failed");
511     }
512 #endif
513
514 }
515
516 /*
517  * ccp_resetci - initialize at start of negotiation.
518  */
519 static void
520 ccp_resetci(fsm *f)
521 {
522     ccp_options *go = &ccp_gotoptions[f->unit];
523     u_char opt_buf[CCP_MAX_OPTION_LENGTH];
524
525     *go = ccp_wantoptions[f->unit];
526     all_rejected[f->unit] = 0;
527
528 #ifdef PPP_WITH_MPPE
529     if (go->mppe) {
530         ccp_options *ao = &ccp_allowoptions[f->unit];
531         int auth_mschap_bits = auth_done[f->unit];
532 #ifdef PPP_WITH_EAPTLS
533         int auth_eap_bits = auth_done[f->unit];
534 #endif
535         int numbits;
536
537         /*
538          * Start with a basic sanity check: mschap[v2] auth must be in
539          * exactly one direction.  RFC 3079 says that the keys are
540          * 'derived from the credentials of the peer that initiated the call',
541          * however the PPP protocol doesn't have such a concept, and pppd
542          * cannot get this info externally.  Instead we do the best we can.
543          * NB: If MPPE is required, all other compression opts are invalid.
544          *     So, we return right away if we can't do it.
545          */
546
547         /* Leave only the mschap auth bits set */
548         auth_mschap_bits &= (CHAP_MS_WITHPEER  | CHAP_MS_PEER |
549                              CHAP_MS2_WITHPEER | CHAP_MS2_PEER);
550         /* Count the mschap auths */
551         auth_mschap_bits >>= CHAP_MS_SHIFT;
552         numbits = 0;
553         do {
554             numbits += auth_mschap_bits & 1;
555             auth_mschap_bits >>= 1;
556         } while (auth_mschap_bits);
557         if (numbits > 1) {
558             error("MPPE required, but auth done in both directions.");
559             lcp_close(f->unit, "MPPE required but not available");
560             return;
561         }
562
563 #ifdef PPP_WITH_EAPTLS
564     /*
565      * MPPE is also possible in combination with EAP-TLS.
566      * It is not possible to detect if we're doing EAP or EAP-TLS
567      * at this stage, hence we accept all forms of EAP. If TLS is
568      * not used then the MPPE keys will not be derived anyway.
569      */
570         /* Leave only the eap auth bits set */
571         auth_eap_bits &= (EAP_WITHPEER | EAP_PEER );
572
573         if ((numbits == 0) && (auth_eap_bits == 0)) {
574             error("MPPE required, but MS-CHAP[v2] nor EAP-TLS auth are performed.");
575 #else
576         if (!numbits) {
577             error("MPPE required, but MS-CHAP[v2] auth not performed.");
578 #endif
579             lcp_close(f->unit, "MPPE required but not available");
580             return;
581         }
582
583         /* A plugin (eg radius) may not have obtained key material. */
584         if (!mppe_keys_isset()) {
585             error("MPPE required, but keys are not available.  "
586                   "Possible plugin problem?");
587             lcp_close(f->unit, "MPPE required but not available");
588             return;
589         }
590
591         /* LM auth not supported for MPPE */
592         if (auth_done[f->unit] & (CHAP_MS_WITHPEER | CHAP_MS_PEER)) {
593             /* This might be noise */
594             if (go->mppe & MPPE_OPT_40) {
595                 notice("Disabling 40-bit MPPE; MS-CHAP LM not supported");
596                 go->mppe &= ~MPPE_OPT_40;
597                 ccp_wantoptions[f->unit].mppe &= ~MPPE_OPT_40;
598             }
599         }
600
601         /* Last check: can we actually negotiate something? */
602         if (!(go->mppe & (MPPE_OPT_40 | MPPE_OPT_128))) {
603             /* Could be misconfig, could be 40-bit disabled above. */
604             error("MPPE required, but both 40-bit and 128-bit disabled.");
605             lcp_close(f->unit, "MPPE required but not available");
606             return;
607         }
608
609         /* sync options */
610         ao->mppe = go->mppe;
611         /* MPPE is not compatible with other compression types */
612         ao->bsd_compress = go->bsd_compress = 0;
613         ao->predictor_1  = go->predictor_1  = 0;
614         ao->predictor_2  = go->predictor_2  = 0;
615         ao->deflate      = go->deflate      = 0;
616     }
617
618     /*
619      * Check whether the kernel knows about the various
620      * compression methods we might request.
621      */
622     if (go->mppe) {
623         opt_buf[0] = CI_MPPE;
624         opt_buf[1] = CILEN_MPPE;
625         MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
626         /* Key material unimportant here. */
627         if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0) {
628             error("MPPE required, but kernel has no support.");
629             lcp_close(f->unit, "MPPE required but not available");
630         }
631     }
632 #endif /* PPP_WITH_MPPE */
633     if (go->bsd_compress) {
634         opt_buf[0] = CI_BSD_COMPRESS;
635         opt_buf[1] = CILEN_BSD_COMPRESS;
636         opt_buf[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, BSD_MIN_BITS);
637         if (ccp_test(f->unit, opt_buf, CILEN_BSD_COMPRESS, 0) <= 0)
638             go->bsd_compress = 0;
639     }
640     if (go->deflate) {
641         if (go->deflate_correct) {
642             opt_buf[0] = CI_DEFLATE;
643             opt_buf[1] = CILEN_DEFLATE;
644             opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS);
645             opt_buf[3] = DEFLATE_CHK_SEQUENCE;
646             if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0)
647                 go->deflate_correct = 0;
648         }
649         if (go->deflate_draft) {
650             opt_buf[0] = CI_DEFLATE_DRAFT;
651             opt_buf[1] = CILEN_DEFLATE;
652             opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS);
653             opt_buf[3] = DEFLATE_CHK_SEQUENCE;
654             if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0)
655                 go->deflate_draft = 0;
656         }
657         if (!go->deflate_correct && !go->deflate_draft)
658             go->deflate = 0;
659     }
660     if (go->predictor_1) {
661         opt_buf[0] = CI_PREDICTOR_1;
662         opt_buf[1] = CILEN_PREDICTOR_1;
663         if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_1, 0) <= 0)
664             go->predictor_1 = 0;
665     }
666     if (go->predictor_2) {
667         opt_buf[0] = CI_PREDICTOR_2;
668         opt_buf[1] = CILEN_PREDICTOR_2;
669         if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_2, 0) <= 0)
670             go->predictor_2 = 0;
671     }
672 }
673
674 /*
675  * ccp_cilen - Return total length of our configuration info.
676  */
677 static int
678   ccp_cilen(fsm *f)
679 {
680     ccp_options *go = &ccp_gotoptions[f->unit];
681
682     return (go->bsd_compress? CILEN_BSD_COMPRESS: 0)
683         + (go->deflate && go->deflate_correct? CILEN_DEFLATE: 0)
684         + (go->deflate && go->deflate_draft? CILEN_DEFLATE: 0)
685         + (go->predictor_1? CILEN_PREDICTOR_1: 0)
686         + (go->predictor_2? CILEN_PREDICTOR_2: 0)
687         + (go->mppe? CILEN_MPPE: 0);
688 }
689
690 /*
691  * ccp_addci - put our requests in a packet.
692  */
693 static void
694   ccp_addci(fsm *f, u_char *p, int *lenp)
695 {
696     int res;
697     ccp_options *go = &ccp_gotoptions[f->unit];
698     u_char *p0 = p;
699
700     /*
701      * Add the compression types that we can receive, in decreasing
702      * preference order.  Get the kernel to allocate the first one
703      * in case it gets Acked.
704      */
705 #ifdef PPP_WITH_MPPE
706     if (go->mppe) {
707         u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
708
709         p[0] = opt_buf[0] = CI_MPPE;
710         p[1] = opt_buf[1] = CILEN_MPPE;
711         MPPE_OPTS_TO_CI(go->mppe, &p[2]);
712         MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
713         mppe_get_recv_key(&opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN);
714         res = ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0);
715         if (res > 0)
716             p += CILEN_MPPE;
717         else
718             /* This shouldn't happen, we've already tested it! */
719             lcp_close(f->unit, "MPPE required but not available in kernel");
720     }
721 #endif
722     if (go->deflate) {
723         p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT;
724         p[1] = CILEN_DEFLATE;
725         p[2] = DEFLATE_MAKE_OPT(go->deflate_size);
726         p[3] = DEFLATE_CHK_SEQUENCE;
727         if (p != p0) {
728             p += CILEN_DEFLATE;
729         } else {
730             for (;;) {
731                 if (go->deflate_size < DEFLATE_MIN_WORKS) {
732                     go->deflate = 0;
733                     break;
734                 }
735                 res = ccp_test(f->unit, p, CILEN_DEFLATE, 0);
736                 if (res > 0) {
737                     p += CILEN_DEFLATE;
738                     break;
739                 } else if (res < 0) {
740                     go->deflate = 0;
741                     break;
742                 }
743                 --go->deflate_size;
744                 p[2] = DEFLATE_MAKE_OPT(go->deflate_size);
745             }
746         }
747         if (p != p0 && go->deflate_correct && go->deflate_draft) {
748             p[0] = CI_DEFLATE_DRAFT;
749             p[1] = CILEN_DEFLATE;
750             p[2] = p[2 - CILEN_DEFLATE];
751             p[3] = DEFLATE_CHK_SEQUENCE;
752             p += CILEN_DEFLATE;
753         }
754     }
755     if (go->bsd_compress) {
756         p[0] = CI_BSD_COMPRESS;
757         p[1] = CILEN_BSD_COMPRESS;
758         p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits);
759         if (p != p0) {
760             p += CILEN_BSD_COMPRESS;    /* not the first option */
761         } else {
762             for (;;) {
763                 if (go->bsd_bits < BSD_MIN_BITS) {
764                     go->bsd_compress = 0;
765                     break;
766                 }
767                 res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0);
768                 if (res > 0) {
769                     p += CILEN_BSD_COMPRESS;
770                     break;
771                 } else if (res < 0) {
772                     go->bsd_compress = 0;
773                     break;
774                 }
775                 --go->bsd_bits;
776                 p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits);
777             }
778         }
779     }
780     /* XXX Should Predictor 2 be preferable to Predictor 1? */
781     if (go->predictor_1) {
782         p[0] = CI_PREDICTOR_1;
783         p[1] = CILEN_PREDICTOR_1;
784         if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 0) <= 0) {
785             go->predictor_1 = 0;
786         } else {
787             p += CILEN_PREDICTOR_1;
788         }
789     }
790     if (go->predictor_2) {
791         p[0] = CI_PREDICTOR_2;
792         p[1] = CILEN_PREDICTOR_2;
793         if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 0) <= 0) {
794             go->predictor_2 = 0;
795         } else {
796             p += CILEN_PREDICTOR_2;
797         }
798     }
799
800     go->method = (p > p0)? p0[0]: -1;
801
802     *lenp = p - p0;
803 }
804
805 /*
806  * ccp_ackci - process a received configure-ack, and return
807  * 1 iff the packet was OK.
808  */
809 static int
810   ccp_ackci(fsm *f, u_char *p, int len)
811 {
812     ccp_options *go = &ccp_gotoptions[f->unit];
813     u_char *p0 = p;
814
815 #ifdef PPP_WITH_MPPE
816     if (go->mppe) {
817         u_char opt_buf[CILEN_MPPE];
818
819         opt_buf[0] = CI_MPPE;
820         opt_buf[1] = CILEN_MPPE;
821         MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
822         if (len < CILEN_MPPE || memcmp(opt_buf, p, CILEN_MPPE))
823             return 0;
824         p += CILEN_MPPE;
825         len -= CILEN_MPPE;
826         /* XXX Cope with first/fast ack */
827         if (len == 0)
828             return 1;
829     }
830 #endif
831     if (go->deflate) {
832         if (len < CILEN_DEFLATE
833             || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
834             || p[1] != CILEN_DEFLATE
835             || p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
836             || p[3] != DEFLATE_CHK_SEQUENCE)
837             return 0;
838         p += CILEN_DEFLATE;
839         len -= CILEN_DEFLATE;
840         /* XXX Cope with first/fast ack */
841         if (len == 0)
842             return 1;
843         if (go->deflate_correct && go->deflate_draft) {
844             if (len < CILEN_DEFLATE
845                 || p[0] != CI_DEFLATE_DRAFT
846                 || p[1] != CILEN_DEFLATE
847                 || p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
848                 || p[3] != DEFLATE_CHK_SEQUENCE)
849                 return 0;
850             p += CILEN_DEFLATE;
851             len -= CILEN_DEFLATE;
852         }
853     }
854     if (go->bsd_compress) {
855         if (len < CILEN_BSD_COMPRESS
856             || p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS
857             || p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits))
858             return 0;
859         p += CILEN_BSD_COMPRESS;
860         len -= CILEN_BSD_COMPRESS;
861         /* XXX Cope with first/fast ack */
862         if (p == p0 && len == 0)
863             return 1;
864     }
865     if (go->predictor_1) {
866         if (len < CILEN_PREDICTOR_1
867             || p[0] != CI_PREDICTOR_1 || p[1] != CILEN_PREDICTOR_1)
868             return 0;
869         p += CILEN_PREDICTOR_1;
870         len -= CILEN_PREDICTOR_1;
871         /* XXX Cope with first/fast ack */
872         if (p == p0 && len == 0)
873             return 1;
874     }
875     if (go->predictor_2) {
876         if (len < CILEN_PREDICTOR_2
877             || p[0] != CI_PREDICTOR_2 || p[1] != CILEN_PREDICTOR_2)
878             return 0;
879         p += CILEN_PREDICTOR_2;
880         len -= CILEN_PREDICTOR_2;
881         /* XXX Cope with first/fast ack */
882         if (p == p0 && len == 0)
883             return 1;
884     }
885
886     if (len != 0)
887         return 0;
888     return 1;
889 }
890
891 /*
892  * ccp_nakci - process received configure-nak.
893  * Returns 1 iff the nak was OK.
894  */
895 static int
896   ccp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
897 {
898     ccp_options *go = &ccp_gotoptions[f->unit];
899     ccp_options no;             /* options we've seen already */
900     ccp_options try;            /* options to ask for next time */
901
902     memset(&no, 0, sizeof(no));
903     try = *go;
904
905 #ifdef PPP_WITH_MPPE
906     if (go->mppe && len >= CILEN_MPPE
907         && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
908         no.mppe = 1;
909         /*
910          * Peer wants us to use a different strength or other setting.
911          * Fail if we aren't willing to use his suggestion.
912          */
913         MPPE_CI_TO_OPTS(&p[2], try.mppe);
914         if ((try.mppe & MPPE_OPT_STATEFUL) && refuse_mppe_stateful) {
915             error("Refusing MPPE stateful mode offered by peer");
916             try.mppe = 0;
917         } else if (((go->mppe | MPPE_OPT_STATEFUL) & try.mppe) != try.mppe) {
918             /* Peer must have set options we didn't request (suggest) */
919             try.mppe = 0;
920         }
921
922         if (!try.mppe) {
923             error("MPPE required but peer negotiation failed");
924             lcp_close(f->unit, "MPPE required but peer negotiation failed");
925         }
926     }
927 #endif /* PPP_WITH_MPPE */
928     if (go->deflate && len >= CILEN_DEFLATE
929         && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT)
930         && p[1] == CILEN_DEFLATE) {
931         no.deflate = 1;
932         /*
933          * Peer wants us to use a different code size or something.
934          * Stop asking for Deflate if we don't understand his suggestion.
935          */
936         if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL
937             || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_WORKS
938             || p[3] != DEFLATE_CHK_SEQUENCE)
939             try.deflate = 0;
940         else if (DEFLATE_SIZE(p[2]) < go->deflate_size)
941             try.deflate_size = DEFLATE_SIZE(p[2]);
942         p += CILEN_DEFLATE;
943         len -= CILEN_DEFLATE;
944         if (go->deflate_correct && go->deflate_draft
945             && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT
946             && p[1] == CILEN_DEFLATE) {
947             p += CILEN_DEFLATE;
948             len -= CILEN_DEFLATE;
949         }
950     }
951
952     if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
953         && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
954         no.bsd_compress = 1;
955         /*
956          * Peer wants us to use a different number of bits
957          * or a different version.
958          */
959         if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION)
960             try.bsd_compress = 0;
961         else if (BSD_NBITS(p[2]) < go->bsd_bits)
962             try.bsd_bits = BSD_NBITS(p[2]);
963         p += CILEN_BSD_COMPRESS;
964         len -= CILEN_BSD_COMPRESS;
965     }
966
967     /*
968      * Predictor-1 and 2 have no options, so they can't be Naked.
969      *
970      * There may be remaining options but we ignore them.
971      */
972
973     if (f->state != OPENED)
974         *go = try;
975     return 1;
976 }
977
978 /*
979  * ccp_rejci - reject some of our suggested compression methods.
980  */
981 static int
982 ccp_rejci(fsm *f, u_char *p, int len)
983 {
984     ccp_options *go = &ccp_gotoptions[f->unit];
985     ccp_options try;            /* options to request next time */
986
987     try = *go;
988
989     /*
990      * Cope with empty configure-rejects by ceasing to send
991      * configure-requests.
992      */
993     if (len == 0 && all_rejected[f->unit])
994         return -1;
995
996 #ifdef PPP_WITH_MPPE
997     if (go->mppe && len >= CILEN_MPPE
998         && p[0] == CI_MPPE && p[1] == CILEN_MPPE) {
999         error("MPPE required but peer refused");
1000         lcp_close(f->unit, "MPPE required but peer refused");
1001         p += CILEN_MPPE;
1002         len -= CILEN_MPPE;
1003     }
1004 #endif
1005     if (go->deflate_correct && len >= CILEN_DEFLATE
1006         && p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) {
1007         if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
1008             || p[3] != DEFLATE_CHK_SEQUENCE)
1009             return 0;           /* Rej is bad */
1010         try.deflate_correct = 0;
1011         p += CILEN_DEFLATE;
1012         len -= CILEN_DEFLATE;
1013     }
1014     if (go->deflate_draft && len >= CILEN_DEFLATE
1015         && p[0] == CI_DEFLATE_DRAFT && p[1] == CILEN_DEFLATE) {
1016         if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size)
1017             || p[3] != DEFLATE_CHK_SEQUENCE)
1018             return 0;           /* Rej is bad */
1019         try.deflate_draft = 0;
1020         p += CILEN_DEFLATE;
1021         len -= CILEN_DEFLATE;
1022     }
1023     if (!try.deflate_correct && !try.deflate_draft)
1024         try.deflate = 0;
1025     if (go->bsd_compress && len >= CILEN_BSD_COMPRESS
1026         && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) {
1027         if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits))
1028             return 0;
1029         try.bsd_compress = 0;
1030         p += CILEN_BSD_COMPRESS;
1031         len -= CILEN_BSD_COMPRESS;
1032     }
1033     if (go->predictor_1 && len >= CILEN_PREDICTOR_1
1034         && p[0] == CI_PREDICTOR_1 && p[1] == CILEN_PREDICTOR_1) {
1035         try.predictor_1 = 0;
1036         p += CILEN_PREDICTOR_1;
1037         len -= CILEN_PREDICTOR_1;
1038     }
1039     if (go->predictor_2 && len >= CILEN_PREDICTOR_2
1040         && p[0] == CI_PREDICTOR_2 && p[1] == CILEN_PREDICTOR_2) {
1041         try.predictor_2 = 0;
1042         p += CILEN_PREDICTOR_2;
1043         len -= CILEN_PREDICTOR_2;
1044     }
1045
1046     if (len != 0)
1047         return 0;
1048
1049     if (f->state != OPENED)
1050         *go = try;
1051
1052     return 1;
1053 }
1054
1055 /*
1056  * ccp_reqci - processed a received configure-request.
1057  * Returns CONFACK, CONFNAK or CONFREJ and the packet modified
1058  * appropriately.
1059  */
1060 static int
1061 ccp_reqci(fsm *f, u_char *p, int *lenp, int dont_nak)
1062 {
1063     int ret, newret, res;
1064     u_char *p0, *retp;
1065     int len, clen, type, nb;
1066     ccp_options *ho = &ccp_hisoptions[f->unit];
1067     ccp_options *ao = &ccp_allowoptions[f->unit];
1068 #ifdef PPP_WITH_MPPE
1069     bool rej_for_ci_mppe = 1;   /* Are we rejecting based on a bad/missing */
1070                                 /* CI_MPPE, or due to other options?       */
1071 #endif
1072
1073     ret = CONFACK;
1074     retp = p0 = p;
1075     len = *lenp;
1076
1077     memset(ho, 0, sizeof(ccp_options));
1078     ho->method = (len > 0)? p[0]: -1;
1079
1080     while (len > 0) {
1081         newret = CONFACK;
1082         if (len < 2 || p[1] < 2 || p[1] > len) {
1083             /* length is bad */
1084             clen = len;
1085             newret = CONFREJ;
1086
1087         } else {
1088             type = p[0];
1089             clen = p[1];
1090
1091             switch (type) {
1092 #ifdef PPP_WITH_MPPE
1093             case CI_MPPE:
1094                 if (!ao->mppe || clen != CILEN_MPPE) {
1095                     newret = CONFREJ;
1096                     break;
1097                 }
1098                 MPPE_CI_TO_OPTS(&p[2], ho->mppe);
1099
1100                 /* Nak if anything unsupported or unknown are set. */
1101                 if (ho->mppe & MPPE_OPT_UNSUPPORTED) {
1102                     newret = CONFNAK;
1103                     ho->mppe &= ~MPPE_OPT_UNSUPPORTED;
1104                 }
1105                 if (ho->mppe & MPPE_OPT_UNKNOWN) {
1106                     newret = CONFNAK;
1107                     ho->mppe &= ~MPPE_OPT_UNKNOWN;
1108                 }
1109
1110                 /* Check state opt */
1111                 if (ho->mppe & MPPE_OPT_STATEFUL) {
1112                     /*
1113                      * We can Nak and request stateless, but it's a
1114                      * lot easier to just assume the peer will request
1115                      * it if he can do it; stateful mode is bad over
1116                      * the Internet -- which is where we expect MPPE.
1117                      */
1118                    if (refuse_mppe_stateful) {
1119                         error("Refusing MPPE stateful mode offered by peer");
1120                         newret = CONFREJ;
1121                         break;
1122                     }
1123                 }
1124
1125                 /* Find out which of {S,L} are set. */
1126                 if ((ho->mppe & MPPE_OPT_128)
1127                      && (ho->mppe & MPPE_OPT_40)) {
1128                     /* Both are set, negotiate the strongest. */
1129                     newret = CONFNAK;
1130                     if (ao->mppe & MPPE_OPT_128)
1131                         ho->mppe &= ~MPPE_OPT_40;
1132                     else if (ao->mppe & MPPE_OPT_40)
1133                         ho->mppe &= ~MPPE_OPT_128;
1134                     else {
1135                         newret = CONFREJ;
1136                         break;
1137                     }
1138                 } else if (ho->mppe & MPPE_OPT_128) {
1139                     if (!(ao->mppe & MPPE_OPT_128)) {
1140                         newret = CONFREJ;
1141                         break;
1142                     }
1143                 } else if (ho->mppe & MPPE_OPT_40) {
1144                     if (!(ao->mppe & MPPE_OPT_40)) {
1145                         newret = CONFREJ;
1146                         break;
1147                     }
1148                 } else {
1149                     /* Neither are set. */
1150                     /* We cannot accept this.  */
1151                     newret = CONFNAK;
1152                     /* Give the peer our idea of what can be used,
1153                        so it can choose and confirm */
1154                     ho->mppe = ao->mppe;
1155                 }
1156
1157                 /* rebuild the opts */
1158                 MPPE_OPTS_TO_CI(ho->mppe, &p[2]);
1159                 if (newret == CONFACK) {
1160                     u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN];
1161                     int mtu;
1162
1163                     BCOPY(p, opt_buf, CILEN_MPPE);
1164                     mppe_get_send_key(&opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN);
1165                     if (ccp_test(f->unit, opt_buf,
1166                                  CILEN_MPPE + MPPE_MAX_KEY_LEN, 1) <= 0) {
1167                         /* This shouldn't happen, we've already tested it! */
1168                         error("MPPE required, but kernel has no support.");
1169                         lcp_close(f->unit, "MPPE required but not available");
1170                         newret = CONFREJ;
1171                         break;
1172                     }
1173                     /*
1174                      * We need to decrease the interface MTU by MPPE_PAD
1175                      * because MPPE frames **grow**.  The kernel [must]
1176                      * allocate MPPE_PAD extra bytes in xmit buffers.
1177                      */
1178                     mtu = netif_get_mtu(f->unit);
1179                     if (mtu)
1180                         netif_set_mtu(f->unit, mtu - MPPE_PAD);
1181                     else
1182                         newret = CONFREJ;
1183                 }
1184
1185                 /*
1186                  * We have accepted MPPE or are willing to negotiate
1187                  * MPPE parameters.  A CONFREJ is due to subsequent
1188                  * (non-MPPE) processing.
1189                  */
1190                 rej_for_ci_mppe = 0;
1191                 break;
1192 #endif /* PPP_WITH_MPPE */
1193             case CI_DEFLATE:
1194             case CI_DEFLATE_DRAFT:
1195                 if (!ao->deflate || clen != CILEN_DEFLATE
1196                     || (!ao->deflate_correct && type == CI_DEFLATE)
1197                     || (!ao->deflate_draft && type == CI_DEFLATE_DRAFT)) {
1198                     newret = CONFREJ;
1199                     break;
1200                 }
1201
1202                 ho->deflate = 1;
1203                 ho->deflate_size = nb = DEFLATE_SIZE(p[2]);
1204                 if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL
1205                     || p[3] != DEFLATE_CHK_SEQUENCE
1206                     || nb > ao->deflate_size || nb < DEFLATE_MIN_WORKS) {
1207                     newret = CONFNAK;
1208                     if (!dont_nak) {
1209                         p[2] = DEFLATE_MAKE_OPT(ao->deflate_size);
1210                         p[3] = DEFLATE_CHK_SEQUENCE;
1211                         /* fall through to test this #bits below */
1212                     } else
1213                         break;
1214                 }
1215
1216                 /*
1217                  * Check whether we can do Deflate with the window
1218                  * size they want.  If the window is too big, reduce
1219                  * it until the kernel can cope and nak with that.
1220                  * We only check this for the first option.
1221                  */
1222                 if (p == p0) {
1223                     for (;;) {
1224                         res = ccp_test(f->unit, p, CILEN_DEFLATE, 1);
1225                         if (res > 0)
1226                             break;              /* it's OK now */
1227                         if (res < 0 || nb == DEFLATE_MIN_WORKS || dont_nak) {
1228                             newret = CONFREJ;
1229                             p[2] = DEFLATE_MAKE_OPT(ho->deflate_size);
1230                             break;
1231                         }
1232                         newret = CONFNAK;
1233                         --nb;
1234                         p[2] = DEFLATE_MAKE_OPT(nb);
1235                     }
1236                 }
1237                 break;
1238
1239             case CI_BSD_COMPRESS:
1240                 if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) {
1241                     newret = CONFREJ;
1242                     break;
1243                 }
1244
1245                 ho->bsd_compress = 1;
1246                 ho->bsd_bits = nb = BSD_NBITS(p[2]);
1247                 if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION
1248                     || nb > ao->bsd_bits || nb < BSD_MIN_BITS) {
1249                     newret = CONFNAK;
1250                     if (!dont_nak) {
1251                         p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ao->bsd_bits);
1252                         /* fall through to test this #bits below */
1253                     } else
1254                         break;
1255                 }
1256
1257                 /*
1258                  * Check whether we can do BSD-Compress with the code
1259                  * size they want.  If the code size is too big, reduce
1260                  * it until the kernel can cope and nak with that.
1261                  * We only check this for the first option.
1262                  */
1263                 if (p == p0) {
1264                     for (;;) {
1265                         res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 1);
1266                         if (res > 0)
1267                             break;
1268                         if (res < 0 || nb == BSD_MIN_BITS || dont_nak) {
1269                             newret = CONFREJ;
1270                             p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION,
1271                                                 ho->bsd_bits);
1272                             break;
1273                         }
1274                         newret = CONFNAK;
1275                         --nb;
1276                         p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb);
1277                     }
1278                 }
1279                 break;
1280
1281             case CI_PREDICTOR_1:
1282                 if (!ao->predictor_1 || clen != CILEN_PREDICTOR_1) {
1283                     newret = CONFREJ;
1284                     break;
1285                 }
1286
1287                 ho->predictor_1 = 1;
1288                 if (p == p0
1289                     && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 1) <= 0) {
1290                     newret = CONFREJ;
1291                 }
1292                 break;
1293
1294             case CI_PREDICTOR_2:
1295                 if (!ao->predictor_2 || clen != CILEN_PREDICTOR_2) {
1296                     newret = CONFREJ;
1297                     break;
1298                 }
1299
1300                 ho->predictor_2 = 1;
1301                 if (p == p0
1302                     && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 1) <= 0) {
1303                     newret = CONFREJ;
1304                 }
1305                 break;
1306
1307             default:
1308                 newret = CONFREJ;
1309             }
1310         }
1311
1312         if (newret == CONFNAK && dont_nak)
1313             newret = CONFREJ;
1314         if (!(newret == CONFACK || (newret == CONFNAK && ret == CONFREJ))) {
1315             /* we're returning this option */
1316             if (newret == CONFREJ && ret == CONFNAK)
1317                 retp = p0;
1318             ret = newret;
1319             if (p != retp)
1320                 BCOPY(p, retp, clen);
1321             retp += clen;
1322         }
1323
1324         p += clen;
1325         len -= clen;
1326     }
1327
1328     if (ret != CONFACK) {
1329         if (ret == CONFREJ && *lenp == retp - p0)
1330             all_rejected[f->unit] = 1;
1331         else
1332             *lenp = retp - p0;
1333     }
1334 #ifdef PPP_WITH_MPPE
1335     if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) {
1336         error("MPPE required but peer negotiation failed");
1337         lcp_close(f->unit, "MPPE required but peer negotiation failed");
1338     }
1339 #endif
1340     return ret;
1341 }
1342
1343 /*
1344  * Make a string name for a compression method (or 2).
1345  */
1346 static char *
1347 method_name(ccp_options *opt, ccp_options *opt2)
1348 {
1349     static char result[64];
1350
1351     if (!ANY_COMPRESS(*opt))
1352         return "(none)";
1353     switch (opt->method) {
1354 #ifdef PPP_WITH_MPPE
1355     case CI_MPPE:
1356     {
1357         char *p = result;
1358         char *q = result + sizeof(result); /* 1 past result */
1359
1360         slprintf(p, q - p, "MPPE ");
1361         p += 5;
1362         if (opt->mppe & MPPE_OPT_128) {
1363             slprintf(p, q - p, "128-bit ");
1364             p += 8;
1365         }
1366         if (opt->mppe & MPPE_OPT_40) {
1367             slprintf(p, q - p, "40-bit ");
1368             p += 7;
1369         }
1370         if (opt->mppe & MPPE_OPT_STATEFUL)
1371             slprintf(p, q - p, "stateful");
1372         else
1373             slprintf(p, q - p, "stateless");
1374
1375         break;
1376     }
1377 #endif
1378     case CI_DEFLATE:
1379     case CI_DEFLATE_DRAFT:
1380         if (opt2 != NULL && opt2->deflate_size != opt->deflate_size)
1381             slprintf(result, sizeof(result), "Deflate%s (%d/%d)",
1382                      (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
1383                      opt->deflate_size, opt2->deflate_size);
1384         else
1385             slprintf(result, sizeof(result), "Deflate%s (%d)",
1386                      (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""),
1387                      opt->deflate_size);
1388         break;
1389     case CI_BSD_COMPRESS:
1390         if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits)
1391             slprintf(result, sizeof(result), "BSD-Compress (%d/%d)",
1392                      opt->bsd_bits, opt2->bsd_bits);
1393         else
1394             slprintf(result, sizeof(result), "BSD-Compress (%d)",
1395                      opt->bsd_bits);
1396         break;
1397     case CI_PREDICTOR_1:
1398         return "Predictor 1";
1399     case CI_PREDICTOR_2:
1400         return "Predictor 2";
1401     default:
1402         slprintf(result, sizeof(result), "Method %d", opt->method);
1403     }
1404     return result;
1405 }
1406
1407 /*
1408  * CCP has come up - inform the kernel driver and log a message.
1409  */
1410 static void
1411 ccp_up(fsm *f)
1412 {
1413     ccp_options *go = &ccp_gotoptions[f->unit];
1414     ccp_options *ho = &ccp_hisoptions[f->unit];
1415     char method1[64];
1416
1417     ccp_flags_set(f->unit, 1, 1);
1418     if (ANY_COMPRESS(*go)) {
1419         if (ANY_COMPRESS(*ho)) {
1420             if (go->method == ho->method) {
1421                 notice("%s compression enabled", method_name(go, ho));
1422             } else {
1423                 strlcpy(method1, method_name(go, NULL), sizeof(method1));
1424                 notice("%s / %s compression enabled",
1425                        method1, method_name(ho, NULL));
1426             }
1427         } else
1428             notice("%s receive compression enabled", method_name(go, NULL));
1429     } else if (ANY_COMPRESS(*ho))
1430         notice("%s transmit compression enabled", method_name(ho, NULL));
1431 #ifdef PPP_WITH_MPPE
1432     if (go->mppe) {
1433         mppe_clear_keys();
1434         continue_networks(f->unit);             /* Bring up IP et al */
1435     }
1436 #endif
1437 }
1438
1439 /*
1440  * CCP has gone down - inform the kernel driver.
1441  */
1442 static void
1443 ccp_down(fsm *f)
1444 {
1445     if (ccp_localstate[f->unit] & RACK_PENDING)
1446         UNTIMEOUT(ccp_rack_timeout, f);
1447     ccp_localstate[f->unit] = 0;
1448     ccp_flags_set(f->unit, 1, 0);
1449 #ifdef PPP_WITH_MPPE
1450     if (ccp_gotoptions[f->unit].mppe) {
1451         ccp_gotoptions[f->unit].mppe = 0;
1452         if (lcp_fsm[f->unit].state == OPENED) {
1453             /* If LCP is not already going down, make sure it does. */
1454             error("MPPE disabled");
1455             lcp_close(f->unit, "MPPE disabled");
1456         }
1457     }
1458 #endif
1459 }
1460
1461 /*
1462  * Print the contents of a CCP packet.
1463  */
1464 static char *ccp_codenames[] = {
1465     "ConfReq", "ConfAck", "ConfNak", "ConfRej",
1466     "TermReq", "TermAck", "CodeRej",
1467     NULL, NULL, NULL, NULL, NULL, NULL,
1468     "ResetReq", "ResetAck",
1469 };
1470
1471 static int
1472 ccp_printpkt(u_char *p, int plen,
1473              void (*printer) (void *, char *, ...), void *arg)
1474 {
1475     u_char *p0, *optend;
1476     int code, id, len;
1477     int optlen;
1478
1479     p0 = p;
1480     if (plen < HEADERLEN)
1481         return 0;
1482     code = p[0];
1483     id = p[1];
1484     len = (p[2] << 8) + p[3];
1485     if (len < HEADERLEN || len > plen)
1486         return 0;
1487
1488     if (code >= 1 && code <= sizeof(ccp_codenames) / sizeof(char *)
1489         && ccp_codenames[code-1] != NULL)
1490         printer(arg, " %s", ccp_codenames[code-1]);
1491     else
1492         printer(arg, " code=0x%x", code);
1493     printer(arg, " id=0x%x", id);
1494     len -= HEADERLEN;
1495     p += HEADERLEN;
1496
1497     switch (code) {
1498     case CONFREQ:
1499     case CONFACK:
1500     case CONFNAK:
1501     case CONFREJ:
1502         /* print list of possible compression methods */
1503         while (len >= 2) {
1504             code = p[0];
1505             optlen = p[1];
1506             if (optlen < 2 || optlen > len)
1507                 break;
1508             printer(arg, " <");
1509             len -= optlen;
1510             optend = p + optlen;
1511             switch (code) {
1512 #ifdef PPP_WITH_MPPE
1513             case CI_MPPE:
1514                 if (optlen >= CILEN_MPPE) {
1515                     u_char mppe_opts;
1516
1517                     MPPE_CI_TO_OPTS(&p[2], mppe_opts);
1518                     printer(arg, "mppe %s %s %s %s %s %s%s",
1519                             (p[2] & MPPE_H_BIT)? "+H": "-H",
1520                             (p[5] & MPPE_M_BIT)? "+M": "-M",
1521                             (p[5] & MPPE_S_BIT)? "+S": "-S",
1522                             (p[5] & MPPE_L_BIT)? "+L": "-L",
1523                             (p[5] & MPPE_D_BIT)? "+D": "-D",
1524                             (p[5] & MPPE_C_BIT)? "+C": "-C",
1525                             (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": "");
1526                     if (mppe_opts & MPPE_OPT_UNKNOWN)
1527                         printer(arg, " (%.2x %.2x %.2x %.2x)",
1528                                 p[2], p[3], p[4], p[5]);
1529                     p += CILEN_MPPE;
1530                 }
1531                 break;
1532 #endif
1533             case CI_DEFLATE:
1534             case CI_DEFLATE_DRAFT:
1535                 if (optlen >= CILEN_DEFLATE) {
1536                     printer(arg, "deflate%s %d",
1537                             (code == CI_DEFLATE_DRAFT? "(old#)": ""),
1538                             DEFLATE_SIZE(p[2]));
1539                     if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL)
1540                         printer(arg, " method %d", DEFLATE_METHOD(p[2]));
1541                     if (p[3] != DEFLATE_CHK_SEQUENCE)
1542                         printer(arg, " check %d", p[3]);
1543                     p += CILEN_DEFLATE;
1544                 }
1545                 break;
1546             case CI_BSD_COMPRESS:
1547                 if (optlen >= CILEN_BSD_COMPRESS) {
1548                     printer(arg, "bsd v%d %d", BSD_VERSION(p[2]),
1549                             BSD_NBITS(p[2]));
1550                     p += CILEN_BSD_COMPRESS;
1551                 }
1552                 break;
1553             case CI_PREDICTOR_1:
1554                 if (optlen >= CILEN_PREDICTOR_1) {
1555                     printer(arg, "predictor 1");
1556                     p += CILEN_PREDICTOR_1;
1557                 }
1558                 break;
1559             case CI_PREDICTOR_2:
1560                 if (optlen >= CILEN_PREDICTOR_2) {
1561                     printer(arg, "predictor 2");
1562                     p += CILEN_PREDICTOR_2;
1563                 }
1564                 break;
1565             }
1566             while (p < optend)
1567                 printer(arg, " %.2x", *p++);
1568             printer(arg, ">");
1569         }
1570         break;
1571
1572     case TERMACK:
1573     case TERMREQ:
1574         if (len > 0 && *p >= ' ' && *p < 0x7f) {
1575             print_string((char *)p, len, printer, arg);
1576             p += len;
1577             len = 0;
1578         }
1579         break;
1580     }
1581
1582     /* dump out the rest of the packet in hex */
1583     while (--len >= 0)
1584         printer(arg, " %.2x", *p++);
1585
1586     return p - p0;
1587 }
1588
1589 /*
1590  * We have received a packet that the decompressor failed to
1591  * decompress.  Here we would expect to issue a reset-request, but
1592  * Motorola has a patent on resetting the compressor as a result of
1593  * detecting an error in the decompressed data after decompression.
1594  * (See US patent 5,130,993; international patent publication number
1595  * WO 91/10289; Australian patent 73296/91.)
1596  *
1597  * So we ask the kernel whether the error was detected after
1598  * decompression; if it was, we take CCP down, thus disabling
1599  * compression :-(, otherwise we issue the reset-request.
1600  */
1601 static void
1602 ccp_datainput(int unit, u_char *pkt, int len)
1603 {
1604     fsm *f;
1605
1606     f = &ccp_fsm[unit];
1607     if (f->state == OPENED) {
1608         if (ccp_fatal_error(unit)) {
1609             /*
1610              * Disable compression by taking CCP down.
1611              */
1612             error("Lost compression sync: disabling compression");
1613             ccp_close(unit, "Lost compression sync");
1614 #ifdef PPP_WITH_MPPE
1615             /*
1616              * If we were doing MPPE, we must also take the link down.
1617              */
1618             if (ccp_gotoptions[unit].mppe) {
1619                 error("Too many MPPE errors, closing LCP");
1620                 lcp_close(unit, "Too many MPPE errors");
1621             }
1622 #endif
1623         } else {
1624             /*
1625              * Send a reset-request to reset the peer's compressor.
1626              * We don't do that if we are still waiting for an
1627              * acknowledgement to a previous reset-request.
1628              */
1629             if (!(ccp_localstate[f->unit] & RACK_PENDING)) {
1630                 fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0);
1631                 TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT);
1632                 ccp_localstate[f->unit] |= RACK_PENDING;
1633             } else
1634                 ccp_localstate[f->unit] |= RREQ_REPEAT;
1635         }
1636     }
1637 }
1638
1639 /*
1640  * Timeout waiting for reset-ack.
1641  */
1642 static void
1643 ccp_rack_timeout(void *arg)
1644 {
1645     fsm *f = arg;
1646
1647     if (f->state == OPENED && ccp_localstate[f->unit] & RREQ_REPEAT) {
1648         fsm_sdata(f, CCP_RESETREQ, f->reqid, NULL, 0);
1649         TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT);
1650         ccp_localstate[f->unit] &= ~RREQ_REPEAT;
1651     } else
1652         ccp_localstate[f->unit] &= ~RACK_PENDING;
1653 }
1654