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