2 * ccp.c - PPP Compression Control Protocol.
4 * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
17 * 3. Redistributions of any form whatsoever must retain the following
19 * "This product includes software developed by Paul Mackerras
20 * <paulus@samba.org>".
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.
31 #include "netif/ppp/ppp_opts.h"
32 #if PPP_SUPPORT && CCP_SUPPORT /* don't build if not configured for use in lwipopts.h */
37 #include "netif/ppp/ppp_impl.h"
39 #include "netif/ppp/fsm.h"
40 #include "netif/ppp/ccp.h"
43 #include "netif/ppp/lcp.h" /* lcp_close(), lcp_fsm */
44 #include "netif/ppp/mppe.h" /* mppe_init() */
45 #endif /* MPPE_SUPPORT */
48 * Unfortunately there is a bug in zlib which means that using a
49 * size of 8 (window size = 256) for Deflate compression will cause
50 * buffer overruns and kernel crashes in the deflate module.
51 * Until this is fixed we only accept sizes in the range 9 .. 15.
52 * Thanks to James Carlson for pointing this out.
54 #define DEFLATE_MIN_WORKS 9
57 * Command-line options.
60 static int setbsdcomp (char **);
61 static int setdeflate (char **);
62 static char bsd_value
[8];
63 static char deflate_value
[8];
69 bool refuse_mppe_stateful
= 1; /* Allow stateful mode? */
70 #endif /* MPPE_SUPPORT */
72 static 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
},
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
},
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
},
98 { "nodeflatedraft", o_bool
, &ccp_wantoptions
[0].deflate_draft
,
99 "don't use draft deflate #", OPT_A2COPY
,
100 &ccp_allowoptions
[0].deflate_draft
},
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
},
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
},
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
},
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
},
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_SUPPORT */
163 #endif /* PPP_OPTIONS */
166 * Protocol entry points from main code.
168 static void ccp_init(ppp_pcb
*pcb
);
169 static void ccp_open(ppp_pcb
*pcb
);
170 static void ccp_close(ppp_pcb
*pcb
, const char *reason
);
171 static void ccp_lowerup(ppp_pcb
*pcb
);
172 static void ccp_lowerdown(ppp_pcb
*pcb
);
173 static void ccp_input(ppp_pcb
*pcb
, u_char
*pkt
, int len
);
174 static void ccp_protrej(ppp_pcb
*pcb
);
176 static int ccp_printpkt(const u_char
*p
, int plen
, void (*printer
) (void *, const char *, ...), void *arg
);
177 #endif /* PRINTPKT_SUPPORT */
179 static void ccp_datainput(ppp_pcb
*pcb
, u_char
*pkt
, int len
);
180 #endif /* PPP_DATAINPUT */
182 const struct protent ccp_protent
= {
193 #endif /* PRINTPKT_SUPPORT */
196 #endif /* PPP_DATAINPUT */
200 #endif /* PRINTPKT_SUPPORT */
204 #endif /* PPP_OPTIONS */
208 #endif /* DEMAND_SUPPORT */
212 * Callbacks for fsm code.
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 const char *method_name (ccp_options
*, ccp_options
*);
227 static const fsm_callbacks ccp_callbacks
= {
246 * Do we want / did we get any compression?
248 static int ccp_anycompress(ccp_options
*opt
) {
252 #endif /* DEFLATE_SUPPORT */
253 #if BSDCOMPRESS_SUPPORT
254 || (opt
)->bsd_compress
255 #endif /* BSDCOMPRESS_SUPPORT */
256 #if PREDICTOR_SUPPORT
257 || (opt
)->predictor_1
|| (opt
)->predictor_2
258 #endif /* PREDICTOR_SUPPORT */
261 #endif /* MPPE_SUPPORT */
266 * Local state (mainly for handling reset-reqs and reset-acks).
268 #define RACK_PENDING 1 /* waiting for reset-ack */
269 #define RREQ_REPEAT 2 /* send another reset-req if no reset-ack */
271 #define RACKTIMEOUT 1 /* second */
285 abits
= rbits
= strtol(str
, &endp
, 0);
286 if (endp
!= str
&& *endp
== ',') {
288 abits
= strtol(str
, &endp
, 0);
290 if (*endp
!= 0 || endp
== str
) {
291 option_error("invalid parameter '%s' for bsdcomp option", *argv
);
294 if ((rbits
!= 0 && (rbits
< BSD_MIN_BITS
|| rbits
> BSD_MAX_BITS
))
295 || (abits
!= 0 && (abits
< BSD_MIN_BITS
|| abits
> BSD_MAX_BITS
))) {
296 option_error("bsdcomp option values must be 0 or %d .. %d",
297 BSD_MIN_BITS
, BSD_MAX_BITS
);
301 ccp_wantoptions
[0].bsd_compress
= 1;
302 ccp_wantoptions
[0].bsd_bits
= rbits
;
304 ccp_wantoptions
[0].bsd_compress
= 0;
306 ccp_allowoptions
[0].bsd_compress
= 1;
307 ccp_allowoptions
[0].bsd_bits
= abits
;
309 ccp_allowoptions
[0].bsd_compress
= 0;
310 ppp_slprintf(bsd_value
, sizeof(bsd_value
),
311 rbits
== abits
? "%d": "%d,%d", rbits
, abits
);
324 abits
= rbits
= strtol(str
, &endp
, 0);
325 if (endp
!= str
&& *endp
== ',') {
327 abits
= strtol(str
, &endp
, 0);
329 if (*endp
!= 0 || endp
== str
) {
330 option_error("invalid parameter '%s' for deflate option", *argv
);
333 if ((rbits
!= 0 && (rbits
< DEFLATE_MIN_SIZE
|| rbits
> DEFLATE_MAX_SIZE
))
334 || (abits
!= 0 && (abits
< DEFLATE_MIN_SIZE
335 || abits
> DEFLATE_MAX_SIZE
))) {
336 option_error("deflate option values must be 0 or %d .. %d",
337 DEFLATE_MIN_SIZE
, DEFLATE_MAX_SIZE
);
340 if (rbits
== DEFLATE_MIN_SIZE
|| abits
== DEFLATE_MIN_SIZE
) {
341 if (rbits
== DEFLATE_MIN_SIZE
)
342 rbits
= DEFLATE_MIN_WORKS
;
343 if (abits
== DEFLATE_MIN_SIZE
)
344 abits
= DEFLATE_MIN_WORKS
;
345 warn("deflate option value of %d changed to %d to avoid zlib bug",
346 DEFLATE_MIN_SIZE
, DEFLATE_MIN_WORKS
);
349 ccp_wantoptions
[0].deflate
= 1;
350 ccp_wantoptions
[0].deflate_size
= rbits
;
352 ccp_wantoptions
[0].deflate
= 0;
354 ccp_allowoptions
[0].deflate
= 1;
355 ccp_allowoptions
[0].deflate_size
= abits
;
357 ccp_allowoptions
[0].deflate
= 0;
358 ppp_slprintf(deflate_value
, sizeof(deflate_value
),
359 rbits
== abits
? "%d": "%d,%d", rbits
, abits
);
363 #endif /* PPP_OPTIONS */
366 * ccp_init - initialize CCP.
368 static void ccp_init(ppp_pcb
*pcb
) {
369 fsm
*f
= &pcb
->ccp_fsm
;
372 f
->protocol
= PPP_CCP
;
373 f
->callbacks
= &ccp_callbacks
;
376 #if 0 /* Not necessary, everything is cleared in ppp_new() */
377 memset(wo
, 0, sizeof(*wo
));
378 memset(go
, 0, sizeof(*go
));
379 memset(ao
, 0, sizeof(*ao
));
380 memset(ho
, 0, sizeof(*ho
));
385 wo
->deflate_size
= DEFLATE_MAX_SIZE
;
386 wo
->deflate_correct
= 1;
387 wo
->deflate_draft
= 1;
389 ao
->deflate_size
= DEFLATE_MAX_SIZE
;
390 ao
->deflate_correct
= 1;
391 ao
->deflate_draft
= 1;
392 #endif /* DEFLATE_SUPPORT */
394 #if BSDCOMPRESS_SUPPORT
395 wo
->bsd_compress
= 1;
396 wo
->bsd_bits
= BSD_MAX_BITS
;
397 ao
->bsd_compress
= 1;
398 ao
->bsd_bits
= BSD_MAX_BITS
;
399 #endif /* BSDCOMPRESS_SUPPORT */
401 #if PREDICTOR_SUPPORT
403 #endif /* PREDICTOR_SUPPORT */
407 * ccp_open - CCP is allowed to come up.
409 static void ccp_open(ppp_pcb
*pcb
) {
410 fsm
*f
= &pcb
->ccp_fsm
;
411 ccp_options
*go
= &pcb
->ccp_gotoptions
;
413 if (f
->state
!= PPP_FSM_OPENED
)
414 ccp_set(pcb
, 1, 0, 0, 0);
417 * Find out which compressors the kernel supports before
418 * deciding whether to open in silent mode.
421 if (!ccp_anycompress(go
))
422 f
->flags
|= OPT_SILENT
;
428 * ccp_close - Terminate CCP.
430 static void ccp_close(ppp_pcb
*pcb
, const char *reason
) {
431 fsm
*f
= &pcb
->ccp_fsm
;
432 ccp_set(pcb
, 0, 0, 0, 0);
433 fsm_close(f
, reason
);
437 * ccp_lowerup - we may now transmit CCP packets.
439 static void ccp_lowerup(ppp_pcb
*pcb
) {
440 fsm
*f
= &pcb
->ccp_fsm
;
445 * ccp_lowerdown - we may not transmit CCP packets.
447 static void ccp_lowerdown(ppp_pcb
*pcb
) {
448 fsm
*f
= &pcb
->ccp_fsm
;
453 * ccp_input - process a received CCP packet.
455 static void ccp_input(ppp_pcb
*pcb
, u_char
*p
, int len
) {
456 fsm
*f
= &pcb
->ccp_fsm
;
457 ccp_options
*go
= &pcb
->ccp_gotoptions
;
461 * Check for a terminate-request so we can print a message.
464 fsm_input(f
, p
, len
);
465 if (oldstate
== PPP_FSM_OPENED
&& p
[0] == TERMREQ
&& f
->state
!= PPP_FSM_OPENED
) {
466 ppp_notice("Compression disabled by peer.");
469 ppp_error("MPPE disabled, closing LCP");
470 lcp_close(pcb
, "MPPE disabled by peer");
472 #endif /* MPPE_SUPPORT */
476 * If we get a terminate-ack and we're not asking for compression,
479 if (oldstate
== PPP_FSM_REQSENT
&& p
[0] == TERMACK
480 && !ccp_anycompress(go
))
481 ccp_close(pcb
, "No compression negotiated");
485 * Handle a CCP-specific code.
487 static int ccp_extcode(fsm
*f
, int code
, int id
, u_char
*p
, int len
) {
488 ppp_pcb
*pcb
= f
->pcb
;
490 LWIP_UNUSED_ARG(len
);
494 if (f
->state
!= PPP_FSM_OPENED
)
497 /* send a reset-ack, which the transmitter will see and
498 reset its compression state. */
499 fsm_sdata(f
, CCP_RESETACK
, id
, NULL
, 0);
503 if ((pcb
->ccp_localstate
& RACK_PENDING
) && id
== f
->reqid
) {
504 pcb
->ccp_localstate
&= ~(RACK_PENDING
| RREQ_REPEAT
);
505 UNTIMEOUT(ccp_rack_timeout
, f
);
506 ccp_reset_decomp(pcb
);
518 * ccp_protrej - peer doesn't talk CCP.
520 static void ccp_protrej(ppp_pcb
*pcb
) {
521 fsm
*f
= &pcb
->ccp_fsm
;
523 ccp_options
*go
= &pcb
->ccp_gotoptions
;
524 #endif /* MPPE_SUPPORT */
526 ccp_set(pcb
, 0, 0, 0, 0);
531 ppp_error("MPPE required but peer negotiation failed");
532 lcp_close(pcb
, "MPPE required but peer negotiation failed");
534 #endif /* MPPE_SUPPORT */
539 * ccp_resetci - initialize at start of negotiation.
541 static void ccp_resetci(fsm
*f
) {
542 ppp_pcb
*pcb
= f
->pcb
;
543 ccp_options
*go
= &pcb
->ccp_gotoptions
;
544 ccp_options
*wo
= &pcb
->ccp_wantoptions
;
546 ccp_options
*ao
= &pcb
->ccp_allowoptions
;
547 #endif /* MPPE_SUPPORT */
548 #if DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT
549 u_char opt_buf
[CCP_MAX_OPTION_LENGTH
];
550 #endif /* DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT */
551 #if DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT
553 #endif /* DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT */
556 if (pcb
->settings
.require_mppe
) {
557 wo
->mppe
= ao
->mppe
=
558 (pcb
->settings
.refuse_mppe_40
? 0 : MPPE_OPT_40
)
559 | (pcb
->settings
.refuse_mppe_128
? 0 : MPPE_OPT_128
);
561 #endif /* MPPE_SUPPORT */
564 pcb
->ccp_all_rejected
= 0;
568 int auth_mschap_bits
= pcb
->auth_done
;
572 * Start with a basic sanity check: mschap[v2] auth must be in
573 * exactly one direction. RFC 3079 says that the keys are
574 * 'derived from the credentials of the peer that initiated the call',
575 * however the PPP protocol doesn't have such a concept, and pppd
576 * cannot get this info externally. Instead we do the best we can.
577 * NB: If MPPE is required, all other compression opts are invalid.
578 * So, we return right away if we can't do it.
581 /* Leave only the mschap auth bits set */
582 auth_mschap_bits
&= (CHAP_MS_WITHPEER
| CHAP_MS_PEER
|
583 CHAP_MS2_WITHPEER
| CHAP_MS2_PEER
);
584 /* Count the mschap auths */
585 auth_mschap_bits
>>= CHAP_MS_SHIFT
;
588 numbits
+= auth_mschap_bits
& 1;
589 auth_mschap_bits
>>= 1;
590 } while (auth_mschap_bits
);
592 ppp_error("MPPE required, but auth done in both directions.");
593 lcp_close(pcb
, "MPPE required but not available");
597 ppp_error("MPPE required, but MS-CHAP[v2] auth not performed.");
598 lcp_close(pcb
, "MPPE required but not available");
602 /* A plugin (eg radius) may not have obtained key material. */
603 if (!pcb
->mppe_keys_set
) {
604 ppp_error("MPPE required, but keys are not available. "
605 "Possible plugin problem?");
606 lcp_close(pcb
, "MPPE required but not available");
610 /* LM auth not supported for MPPE */
611 if (pcb
->auth_done
& (CHAP_MS_WITHPEER
| CHAP_MS_PEER
)) {
612 /* This might be noise */
613 if (go
->mppe
& MPPE_OPT_40
) {
614 ppp_notice("Disabling 40-bit MPPE; MS-CHAP LM not supported");
615 go
->mppe
&= ~MPPE_OPT_40
;
616 wo
->mppe
&= ~MPPE_OPT_40
;
620 /* Last check: can we actually negotiate something? */
621 if (!(go
->mppe
& (MPPE_OPT_40
| MPPE_OPT_128
))) {
622 /* Could be misconfig, could be 40-bit disabled above. */
623 ppp_error("MPPE required, but both 40-bit and 128-bit disabled.");
624 lcp_close(pcb
, "MPPE required but not available");
630 /* MPPE is not compatible with other compression types */
631 #if BSDCOMPRESS_SUPPORT
632 ao
->bsd_compress
= go
->bsd_compress
= 0;
633 #endif /* BSDCOMPRESS_SUPPORT */
634 #if PREDICTOR_SUPPORT
635 ao
->predictor_1
= go
->predictor_1
= 0;
636 ao
->predictor_2
= go
->predictor_2
= 0;
637 #endif /* PREDICTOR_SUPPORT */
639 ao
->deflate
= go
->deflate
= 0;
640 #endif /* DEFLATE_SUPPORT */
642 #endif /* MPPE_SUPPORT */
645 * Check whether the kernel knows about the various
646 * compression methods we might request.
648 #if BSDCOMPRESS_SUPPORT
649 /* FIXME: we don't need to test if BSD compress is available
650 * if BSDCOMPRESS_SUPPORT is set, it is.
652 if (go
->bsd_compress
) {
653 opt_buf
[0] = CI_BSD_COMPRESS
;
654 opt_buf
[1] = CILEN_BSD_COMPRESS
;
656 if (go
->bsd_bits
< BSD_MIN_BITS
) {
657 go
->bsd_compress
= 0;
660 opt_buf
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
, go
->bsd_bits
);
661 res
= ccp_test(pcb
, opt_buf
, CILEN_BSD_COMPRESS
, 0);
664 } else if (res
< 0) {
665 go
->bsd_compress
= 0;
671 #endif /* BSDCOMPRESS_SUPPORT */
673 /* FIXME: we don't need to test if deflate is available
674 * if DEFLATE_SUPPORT is set, it is.
677 if (go
->deflate_correct
) {
678 opt_buf
[0] = CI_DEFLATE
;
679 opt_buf
[1] = CILEN_DEFLATE
;
680 opt_buf
[3] = DEFLATE_CHK_SEQUENCE
;
682 if (go
->deflate_size
< DEFLATE_MIN_WORKS
) {
683 go
->deflate_correct
= 0;
686 opt_buf
[2] = DEFLATE_MAKE_OPT(go
->deflate_size
);
687 res
= ccp_test(pcb
, opt_buf
, CILEN_DEFLATE
, 0);
690 } else if (res
< 0) {
691 go
->deflate_correct
= 0;
697 if (go
->deflate_draft
) {
698 opt_buf
[0] = CI_DEFLATE_DRAFT
;
699 opt_buf
[1] = CILEN_DEFLATE
;
700 opt_buf
[3] = DEFLATE_CHK_SEQUENCE
;
702 if (go
->deflate_size
< DEFLATE_MIN_WORKS
) {
703 go
->deflate_draft
= 0;
706 opt_buf
[2] = DEFLATE_MAKE_OPT(go
->deflate_size
);
707 res
= ccp_test(pcb
, opt_buf
, CILEN_DEFLATE
, 0);
710 } else if (res
< 0) {
711 go
->deflate_draft
= 0;
717 if (!go
->deflate_correct
&& !go
->deflate_draft
)
720 #endif /* DEFLATE_SUPPORT */
721 #if PREDICTOR_SUPPORT
722 /* FIXME: we don't need to test if predictor is available,
723 * if PREDICTOR_SUPPORT is set, it is.
725 if (go
->predictor_1
) {
726 opt_buf
[0] = CI_PREDICTOR_1
;
727 opt_buf
[1] = CILEN_PREDICTOR_1
;
728 if (ccp_test(pcb
, opt_buf
, CILEN_PREDICTOR_1
, 0) <= 0)
731 if (go
->predictor_2
) {
732 opt_buf
[0] = CI_PREDICTOR_2
;
733 opt_buf
[1] = CILEN_PREDICTOR_2
;
734 if (ccp_test(pcb
, opt_buf
, CILEN_PREDICTOR_2
, 0) <= 0)
737 #endif /* PREDICTOR_SUPPORT */
741 * ccp_cilen - Return total length of our configuration info.
743 static int ccp_cilen(fsm
*f
) {
744 ppp_pcb
*pcb
= f
->pcb
;
745 ccp_options
*go
= &pcb
->ccp_gotoptions
;
748 #if BSDCOMPRESS_SUPPORT
749 + (go
->bsd_compress
? CILEN_BSD_COMPRESS
: 0)
750 #endif /* BSDCOMPRESS_SUPPORT */
752 + (go
->deflate
&& go
->deflate_correct
? CILEN_DEFLATE
: 0)
753 + (go
->deflate
&& go
->deflate_draft
? CILEN_DEFLATE
: 0)
754 #endif /* DEFLATE_SUPPORT */
755 #if PREDICTOR_SUPPORT
756 + (go
->predictor_1
? CILEN_PREDICTOR_1
: 0)
757 + (go
->predictor_2
? CILEN_PREDICTOR_2
: 0)
758 #endif /* PREDICTOR_SUPPORT */
760 + (go
->mppe
? CILEN_MPPE
: 0)
761 #endif /* MPPE_SUPPORT */
766 * ccp_addci - put our requests in a packet.
768 static void ccp_addci(fsm
*f
, u_char
*p
, int *lenp
) {
769 ppp_pcb
*pcb
= f
->pcb
;
770 ccp_options
*go
= &pcb
->ccp_gotoptions
;
774 * Add the compression types that we can receive, in decreasing
781 MPPE_OPTS_TO_CI(go
->mppe
, &p
[2]);
782 mppe_init(pcb
, &pcb
->mppe_decomp
, go
->mppe
);
785 #endif /* MPPE_SUPPORT */
788 if (go
->deflate_correct
) {
790 p
[1] = CILEN_DEFLATE
;
791 p
[2] = DEFLATE_MAKE_OPT(go
->deflate_size
);
792 p
[3] = DEFLATE_CHK_SEQUENCE
;
795 if (go
->deflate_draft
) {
796 p
[0] = CI_DEFLATE_DRAFT
;
797 p
[1] = CILEN_DEFLATE
;
798 p
[2] = p
[2 - CILEN_DEFLATE
];
799 p
[3] = DEFLATE_CHK_SEQUENCE
;
803 #endif /* DEFLATE_SUPPORT */
804 #if BSDCOMPRESS_SUPPORT
805 if (go
->bsd_compress
) {
806 p
[0] = CI_BSD_COMPRESS
;
807 p
[1] = CILEN_BSD_COMPRESS
;
808 p
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
, go
->bsd_bits
);
809 p
+= CILEN_BSD_COMPRESS
;
811 #endif /* BSDCOMPRESS_SUPPORT */
812 #if PREDICTOR_SUPPORT
813 /* XXX Should Predictor 2 be preferable to Predictor 1? */
814 if (go
->predictor_1
) {
815 p
[0] = CI_PREDICTOR_1
;
816 p
[1] = CILEN_PREDICTOR_1
;
817 p
+= CILEN_PREDICTOR_1
;
819 if (go
->predictor_2
) {
820 p
[0] = CI_PREDICTOR_2
;
821 p
[1] = CILEN_PREDICTOR_2
;
822 p
+= CILEN_PREDICTOR_2
;
824 #endif /* PREDICTOR_SUPPORT */
826 go
->method
= (p
> p0
)? p0
[0]: 0;
832 * ccp_ackci - process a received configure-ack, and return
833 * 1 iff the packet was OK.
835 static int ccp_ackci(fsm
*f
, u_char
*p
, int len
) {
836 ppp_pcb
*pcb
= f
->pcb
;
837 ccp_options
*go
= &pcb
->ccp_gotoptions
;
838 #if BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT
840 #endif /* BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT */
844 u_char opt_buf
[CILEN_MPPE
];
846 opt_buf
[0] = CI_MPPE
;
847 opt_buf
[1] = CILEN_MPPE
;
848 MPPE_OPTS_TO_CI(go
->mppe
, &opt_buf
[2]);
849 if (len
< CILEN_MPPE
|| memcmp(opt_buf
, p
, CILEN_MPPE
))
853 /* XXX Cope with first/fast ack */
857 #endif /* MPPE_SUPPORT */
860 if (len
< CILEN_DEFLATE
861 || p
[0] != (go
->deflate_correct
? CI_DEFLATE
: CI_DEFLATE_DRAFT
)
862 || p
[1] != CILEN_DEFLATE
863 || p
[2] != DEFLATE_MAKE_OPT(go
->deflate_size
)
864 || p
[3] != DEFLATE_CHK_SEQUENCE
)
867 len
-= CILEN_DEFLATE
;
868 /* XXX Cope with first/fast ack */
871 if (go
->deflate_correct
&& go
->deflate_draft
) {
872 if (len
< CILEN_DEFLATE
873 || p
[0] != CI_DEFLATE_DRAFT
874 || p
[1] != CILEN_DEFLATE
875 || p
[2] != DEFLATE_MAKE_OPT(go
->deflate_size
)
876 || p
[3] != DEFLATE_CHK_SEQUENCE
)
879 len
-= CILEN_DEFLATE
;
882 #endif /* DEFLATE_SUPPORT */
883 #if BSDCOMPRESS_SUPPORT
884 if (go
->bsd_compress
) {
885 if (len
< CILEN_BSD_COMPRESS
886 || p
[0] != CI_BSD_COMPRESS
|| p
[1] != CILEN_BSD_COMPRESS
887 || p
[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION
, go
->bsd_bits
))
889 p
+= CILEN_BSD_COMPRESS
;
890 len
-= CILEN_BSD_COMPRESS
;
891 /* XXX Cope with first/fast ack */
892 if (p
== p0
&& len
== 0)
895 #endif /* BSDCOMPRESS_SUPPORT */
896 #if PREDICTOR_SUPPORT
897 if (go
->predictor_1
) {
898 if (len
< CILEN_PREDICTOR_1
899 || p
[0] != CI_PREDICTOR_1
|| p
[1] != CILEN_PREDICTOR_1
)
901 p
+= CILEN_PREDICTOR_1
;
902 len
-= CILEN_PREDICTOR_1
;
903 /* XXX Cope with first/fast ack */
904 if (p
== p0
&& len
== 0)
907 if (go
->predictor_2
) {
908 if (len
< CILEN_PREDICTOR_2
909 || p
[0] != CI_PREDICTOR_2
|| p
[1] != CILEN_PREDICTOR_2
)
911 p
+= CILEN_PREDICTOR_2
;
912 len
-= CILEN_PREDICTOR_2
;
913 /* XXX Cope with first/fast ack */
914 if (p
== p0
&& len
== 0)
917 #endif /* PREDICTOR_SUPPORT */
925 * ccp_nakci - process received configure-nak.
926 * Returns 1 iff the nak was OK.
928 static int ccp_nakci(fsm
*f
, u_char
*p
, int len
, int treat_as_reject
) {
929 ppp_pcb
*pcb
= f
->pcb
;
930 ccp_options
*go
= &pcb
->ccp_gotoptions
;
931 ccp_options no
; /* options we've seen already */
932 ccp_options try_
; /* options to ask for next time */
933 LWIP_UNUSED_ARG(treat_as_reject
);
934 #if !MPPE_SUPPORT && !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT
936 LWIP_UNUSED_ARG(len
);
937 #endif /* !MPPE_SUPPORT && !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT */
939 memset(&no
, 0, sizeof(no
));
943 if (go
->mppe
&& len
>= CILEN_MPPE
944 && p
[0] == CI_MPPE
&& p
[1] == CILEN_MPPE
) {
947 * Peer wants us to use a different strength or other setting.
948 * Fail if we aren't willing to use his suggestion.
950 MPPE_CI_TO_OPTS(&p
[2], try_
.mppe
);
951 if ((try_
.mppe
& MPPE_OPT_STATEFUL
) && pcb
->settings
.refuse_mppe_stateful
) {
952 ppp_error("Refusing MPPE stateful mode offered by peer");
954 } else if (((go
->mppe
| MPPE_OPT_STATEFUL
) & try_
.mppe
) != try_
.mppe
) {
955 /* Peer must have set options we didn't request (suggest) */
960 ppp_error("MPPE required but peer negotiation failed");
961 lcp_close(pcb
, "MPPE required but peer negotiation failed");
964 #endif /* MPPE_SUPPORT */
966 if (go
->deflate
&& len
>= CILEN_DEFLATE
967 && p
[0] == (go
->deflate_correct
? CI_DEFLATE
: CI_DEFLATE_DRAFT
)
968 && p
[1] == CILEN_DEFLATE
) {
971 * Peer wants us to use a different code size or something.
972 * Stop asking for Deflate if we don't understand his suggestion.
974 if (DEFLATE_METHOD(p
[2]) != DEFLATE_METHOD_VAL
975 || DEFLATE_SIZE(p
[2]) < DEFLATE_MIN_WORKS
976 || p
[3] != DEFLATE_CHK_SEQUENCE
)
978 else if (DEFLATE_SIZE(p
[2]) < go
->deflate_size
)
979 try_
.deflate_size
= DEFLATE_SIZE(p
[2]);
981 len
-= CILEN_DEFLATE
;
982 if (go
->deflate_correct
&& go
->deflate_draft
983 && len
>= CILEN_DEFLATE
&& p
[0] == CI_DEFLATE_DRAFT
984 && p
[1] == CILEN_DEFLATE
) {
986 len
-= CILEN_DEFLATE
;
989 #endif /* DEFLATE_SUPPORT */
990 #if BSDCOMPRESS_SUPPORT
991 if (go
->bsd_compress
&& len
>= CILEN_BSD_COMPRESS
992 && p
[0] == CI_BSD_COMPRESS
&& p
[1] == CILEN_BSD_COMPRESS
) {
995 * Peer wants us to use a different number of bits
996 * or a different version.
998 if (BSD_VERSION(p
[2]) != BSD_CURRENT_VERSION
)
999 try_
.bsd_compress
= 0;
1000 else if (BSD_NBITS(p
[2]) < go
->bsd_bits
)
1001 try_
.bsd_bits
= BSD_NBITS(p
[2]);
1002 p
+= CILEN_BSD_COMPRESS
;
1003 len
-= CILEN_BSD_COMPRESS
;
1005 #endif /* BSDCOMPRESS_SUPPORT */
1008 * Predictor-1 and 2 have no options, so they can't be Naked.
1010 * There may be remaining options but we ignore them.
1013 if (f
->state
!= PPP_FSM_OPENED
)
1019 * ccp_rejci - reject some of our suggested compression methods.
1021 static int ccp_rejci(fsm
*f
, u_char
*p
, int len
) {
1022 ppp_pcb
*pcb
= f
->pcb
;
1023 ccp_options
*go
= &pcb
->ccp_gotoptions
;
1024 ccp_options try_
; /* options to request next time */
1029 * Cope with empty configure-rejects by ceasing to send
1030 * configure-requests.
1032 if (len
== 0 && pcb
->ccp_all_rejected
)
1036 if (go
->mppe
&& len
>= CILEN_MPPE
1037 && p
[0] == CI_MPPE
&& p
[1] == CILEN_MPPE
) {
1038 ppp_error("MPPE required but peer refused");
1039 lcp_close(pcb
, "MPPE required but peer refused");
1043 #endif /* MPPE_SUPPORT */
1045 if (go
->deflate_correct
&& len
>= CILEN_DEFLATE
1046 && p
[0] == CI_DEFLATE
&& p
[1] == CILEN_DEFLATE
) {
1047 if (p
[2] != DEFLATE_MAKE_OPT(go
->deflate_size
)
1048 || p
[3] != DEFLATE_CHK_SEQUENCE
)
1049 return 0; /* Rej is bad */
1050 try_
.deflate_correct
= 0;
1052 len
-= CILEN_DEFLATE
;
1054 if (go
->deflate_draft
&& len
>= CILEN_DEFLATE
1055 && p
[0] == CI_DEFLATE_DRAFT
&& p
[1] == CILEN_DEFLATE
) {
1056 if (p
[2] != DEFLATE_MAKE_OPT(go
->deflate_size
)
1057 || p
[3] != DEFLATE_CHK_SEQUENCE
)
1058 return 0; /* Rej is bad */
1059 try_
.deflate_draft
= 0;
1061 len
-= CILEN_DEFLATE
;
1063 if (!try_
.deflate_correct
&& !try_
.deflate_draft
)
1065 #endif /* DEFLATE_SUPPORT */
1066 #if BSDCOMPRESS_SUPPORT
1067 if (go
->bsd_compress
&& len
>= CILEN_BSD_COMPRESS
1068 && p
[0] == CI_BSD_COMPRESS
&& p
[1] == CILEN_BSD_COMPRESS
) {
1069 if (p
[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION
, go
->bsd_bits
))
1071 try_
.bsd_compress
= 0;
1072 p
+= CILEN_BSD_COMPRESS
;
1073 len
-= CILEN_BSD_COMPRESS
;
1075 #endif /* BSDCOMPRESS_SUPPORT */
1076 #if PREDICTOR_SUPPORT
1077 if (go
->predictor_1
&& len
>= CILEN_PREDICTOR_1
1078 && p
[0] == CI_PREDICTOR_1
&& p
[1] == CILEN_PREDICTOR_1
) {
1079 try_
.predictor_1
= 0;
1080 p
+= CILEN_PREDICTOR_1
;
1081 len
-= CILEN_PREDICTOR_1
;
1083 if (go
->predictor_2
&& len
>= CILEN_PREDICTOR_2
1084 && p
[0] == CI_PREDICTOR_2
&& p
[1] == CILEN_PREDICTOR_2
) {
1085 try_
.predictor_2
= 0;
1086 p
+= CILEN_PREDICTOR_2
;
1087 len
-= CILEN_PREDICTOR_2
;
1089 #endif /* PREDICTOR_SUPPORT */
1094 if (f
->state
!= PPP_FSM_OPENED
)
1101 * ccp_reqci - processed a received configure-request.
1102 * Returns CONFACK, CONFNAK or CONFREJ and the packet modified
1105 static int ccp_reqci(fsm
*f
, u_char
*p
, int *lenp
, int dont_nak
) {
1106 ppp_pcb
*pcb
= f
->pcb
;
1107 ccp_options
*ho
= &pcb
->ccp_hisoptions
;
1108 ccp_options
*ao
= &pcb
->ccp_allowoptions
;
1110 #if DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT
1113 #endif /* DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT */
1115 int len
, clen
, type
;
1117 u8_t rej_for_ci_mppe
= 1; /* Are we rejecting based on a bad/missing */
1118 /* CI_MPPE, or due to other options? */
1119 #endif /* MPPE_SUPPORT */
1125 memset(ho
, 0, sizeof(ccp_options
));
1126 ho
->method
= (len
> 0)? p
[0]: 0;
1130 if (len
< 2 || p
[1] < 2 || p
[1] > len
) {
1142 if (!ao
->mppe
|| clen
!= CILEN_MPPE
) {
1146 MPPE_CI_TO_OPTS(&p
[2], ho
->mppe
);
1148 /* Nak if anything unsupported or unknown are set. */
1149 if (ho
->mppe
& MPPE_OPT_UNSUPPORTED
) {
1151 ho
->mppe
&= ~MPPE_OPT_UNSUPPORTED
;
1153 if (ho
->mppe
& MPPE_OPT_UNKNOWN
) {
1155 ho
->mppe
&= ~MPPE_OPT_UNKNOWN
;
1158 /* Check state opt */
1159 if (ho
->mppe
& MPPE_OPT_STATEFUL
) {
1161 * We can Nak and request stateless, but it's a
1162 * lot easier to just assume the peer will request
1163 * it if he can do it; stateful mode is bad over
1164 * the Internet -- which is where we expect MPPE.
1166 if (pcb
->settings
.refuse_mppe_stateful
) {
1167 ppp_error("Refusing MPPE stateful mode offered by peer");
1173 /* Find out which of {S,L} are set. */
1174 if ((ho
->mppe
& MPPE_OPT_128
)
1175 && (ho
->mppe
& MPPE_OPT_40
)) {
1176 /* Both are set, negotiate the strongest. */
1178 if (ao
->mppe
& MPPE_OPT_128
)
1179 ho
->mppe
&= ~MPPE_OPT_40
;
1180 else if (ao
->mppe
& MPPE_OPT_40
)
1181 ho
->mppe
&= ~MPPE_OPT_128
;
1186 } else if (ho
->mppe
& MPPE_OPT_128
) {
1187 if (!(ao
->mppe
& MPPE_OPT_128
)) {
1191 } else if (ho
->mppe
& MPPE_OPT_40
) {
1192 if (!(ao
->mppe
& MPPE_OPT_40
)) {
1197 /* Neither are set. */
1198 /* We cannot accept this. */
1200 /* Give the peer our idea of what can be used,
1201 so it can choose and confirm */
1202 ho
->mppe
= ao
->mppe
;
1205 /* rebuild the opts */
1206 MPPE_OPTS_TO_CI(ho
->mppe
, &p
[2]);
1207 if (newret
== CONFACK
) {
1210 mppe_init(pcb
, &pcb
->mppe_comp
, ho
->mppe
);
1212 * We need to decrease the interface MTU by MPPE_PAD
1213 * because MPPE frames **grow**. The kernel [must]
1214 * allocate MPPE_PAD extra bytes in xmit buffers.
1216 mtu
= netif_get_mtu(pcb
);
1218 netif_set_mtu(pcb
, mtu
- MPPE_PAD
);
1224 * We have accepted MPPE or are willing to negotiate
1225 * MPPE parameters. A CONFREJ is due to subsequent
1226 * (non-MPPE) processing.
1228 rej_for_ci_mppe
= 0;
1230 #endif /* MPPE_SUPPORT */
1233 case CI_DEFLATE_DRAFT
:
1234 if (!ao
->deflate
|| clen
!= CILEN_DEFLATE
1235 || (!ao
->deflate_correct
&& type
== CI_DEFLATE
)
1236 || (!ao
->deflate_draft
&& type
== CI_DEFLATE_DRAFT
)) {
1242 ho
->deflate_size
= nb
= DEFLATE_SIZE(p
[2]);
1243 if (DEFLATE_METHOD(p
[2]) != DEFLATE_METHOD_VAL
1244 || p
[3] != DEFLATE_CHK_SEQUENCE
1245 || nb
> ao
->deflate_size
|| nb
< DEFLATE_MIN_WORKS
) {
1248 p
[2] = DEFLATE_MAKE_OPT(ao
->deflate_size
);
1249 p
[3] = DEFLATE_CHK_SEQUENCE
;
1250 /* fall through to test this #bits below */
1256 * Check whether we can do Deflate with the window
1257 * size they want. If the window is too big, reduce
1258 * it until the kernel can cope and nak with that.
1259 * We only check this for the first option.
1263 res
= ccp_test(pcb
, p
, CILEN_DEFLATE
, 1);
1265 break; /* it's OK now */
1266 if (res
< 0 || nb
== DEFLATE_MIN_WORKS
|| dont_nak
) {
1268 p
[2] = DEFLATE_MAKE_OPT(ho
->deflate_size
);
1273 p
[2] = DEFLATE_MAKE_OPT(nb
);
1277 #endif /* DEFLATE_SUPPORT */
1278 #if BSDCOMPRESS_SUPPORT
1279 case CI_BSD_COMPRESS
:
1280 if (!ao
->bsd_compress
|| clen
!= CILEN_BSD_COMPRESS
) {
1285 ho
->bsd_compress
= 1;
1286 ho
->bsd_bits
= nb
= BSD_NBITS(p
[2]);
1287 if (BSD_VERSION(p
[2]) != BSD_CURRENT_VERSION
1288 || nb
> ao
->bsd_bits
|| nb
< BSD_MIN_BITS
) {
1291 p
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
, ao
->bsd_bits
);
1292 /* fall through to test this #bits below */
1298 * Check whether we can do BSD-Compress with the code
1299 * size they want. If the code size is too big, reduce
1300 * it until the kernel can cope and nak with that.
1301 * We only check this for the first option.
1305 res
= ccp_test(pcb
, p
, CILEN_BSD_COMPRESS
, 1);
1308 if (res
< 0 || nb
== BSD_MIN_BITS
|| dont_nak
) {
1310 p
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
,
1316 p
[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION
, nb
);
1320 #endif /* BSDCOMPRESS_SUPPORT */
1321 #if PREDICTOR_SUPPORT
1322 case CI_PREDICTOR_1
:
1323 if (!ao
->predictor_1
|| clen
!= CILEN_PREDICTOR_1
) {
1328 ho
->predictor_1
= 1;
1330 && ccp_test(pcb
, p
, CILEN_PREDICTOR_1
, 1) <= 0) {
1335 case CI_PREDICTOR_2
:
1336 if (!ao
->predictor_2
|| clen
!= CILEN_PREDICTOR_2
) {
1341 ho
->predictor_2
= 1;
1343 && ccp_test(pcb
, p
, CILEN_PREDICTOR_2
, 1) <= 0) {
1347 #endif /* PREDICTOR_SUPPORT */
1354 if (newret
== CONFNAK
&& dont_nak
)
1356 if (!(newret
== CONFACK
|| (newret
== CONFNAK
&& ret
== CONFREJ
))) {
1357 /* we're returning this option */
1358 if (newret
== CONFREJ
&& ret
== CONFNAK
)
1362 MEMCPY(retp
, p
, clen
);
1370 if (ret
!= CONFACK
) {
1371 if (ret
== CONFREJ
&& *lenp
== retp
- p0
)
1372 pcb
->ccp_all_rejected
= 1;
1377 if (ret
== CONFREJ
&& ao
->mppe
&& rej_for_ci_mppe
) {
1378 ppp_error("MPPE required but peer negotiation failed");
1379 lcp_close(pcb
, "MPPE required but peer negotiation failed");
1381 #endif /* MPPE_SUPPORT */
1386 * Make a string name for a compression method (or 2).
1388 static const char *method_name(ccp_options
*opt
, ccp_options
*opt2
) {
1389 static char result
[64];
1390 #if !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT
1391 LWIP_UNUSED_ARG(opt2
);
1392 #endif /* !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT */
1394 if (!ccp_anycompress(opt
))
1396 switch (opt
->method
) {
1401 char *q
= result
+ sizeof(result
); /* 1 past result */
1403 ppp_slprintf(p
, q
- p
, "MPPE ");
1405 if (opt
->mppe
& MPPE_OPT_128
) {
1406 ppp_slprintf(p
, q
- p
, "128-bit ");
1409 if (opt
->mppe
& MPPE_OPT_40
) {
1410 ppp_slprintf(p
, q
- p
, "40-bit ");
1413 if (opt
->mppe
& MPPE_OPT_STATEFUL
)
1414 ppp_slprintf(p
, q
- p
, "stateful");
1416 ppp_slprintf(p
, q
- p
, "stateless");
1420 #endif /* MPPE_SUPPORT */
1423 case CI_DEFLATE_DRAFT
:
1424 if (opt2
!= NULL
&& opt2
->deflate_size
!= opt
->deflate_size
)
1425 ppp_slprintf(result
, sizeof(result
), "Deflate%s (%d/%d)",
1426 (opt
->method
== CI_DEFLATE_DRAFT
? "(old#)": ""),
1427 opt
->deflate_size
, opt2
->deflate_size
);
1429 ppp_slprintf(result
, sizeof(result
), "Deflate%s (%d)",
1430 (opt
->method
== CI_DEFLATE_DRAFT
? "(old#)": ""),
1433 #endif /* DEFLATE_SUPPORT */
1434 #if BSDCOMPRESS_SUPPORT
1435 case CI_BSD_COMPRESS
:
1436 if (opt2
!= NULL
&& opt2
->bsd_bits
!= opt
->bsd_bits
)
1437 ppp_slprintf(result
, sizeof(result
), "BSD-Compress (%d/%d)",
1438 opt
->bsd_bits
, opt2
->bsd_bits
);
1440 ppp_slprintf(result
, sizeof(result
), "BSD-Compress (%d)",
1443 #endif /* BSDCOMPRESS_SUPPORT */
1444 #if PREDICTOR_SUPPORT
1445 case CI_PREDICTOR_1
:
1446 return "Predictor 1";
1447 case CI_PREDICTOR_2
:
1448 return "Predictor 2";
1449 #endif /* PREDICTOR_SUPPORT */
1451 ppp_slprintf(result
, sizeof(result
), "Method %d", opt
->method
);
1457 * CCP has come up - inform the kernel driver and log a message.
1459 static void ccp_up(fsm
*f
) {
1460 ppp_pcb
*pcb
= f
->pcb
;
1461 ccp_options
*go
= &pcb
->ccp_gotoptions
;
1462 ccp_options
*ho
= &pcb
->ccp_hisoptions
;
1465 ccp_set(pcb
, 1, 1, go
->method
, ho
->method
);
1466 if (ccp_anycompress(go
)) {
1467 if (ccp_anycompress(ho
)) {
1468 if (go
->method
== ho
->method
) {
1469 ppp_notice("%s compression enabled", method_name(go
, ho
));
1471 ppp_strlcpy(method1
, method_name(go
, NULL
), sizeof(method1
));
1472 ppp_notice("%s / %s compression enabled",
1473 method1
, method_name(ho
, NULL
));
1476 ppp_notice("%s receive compression enabled", method_name(go
, NULL
));
1477 } else if (ccp_anycompress(ho
))
1478 ppp_notice("%s transmit compression enabled", method_name(ho
, NULL
));
1481 continue_networks(pcb
); /* Bring up IP et al */
1483 #endif /* MPPE_SUPPORT */
1487 * CCP has gone down - inform the kernel driver.
1489 static void ccp_down(fsm
*f
) {
1490 ppp_pcb
*pcb
= f
->pcb
;
1492 ccp_options
*go
= &pcb
->ccp_gotoptions
;
1493 #endif /* MPPE_SUPPORT */
1495 if (pcb
->ccp_localstate
& RACK_PENDING
)
1496 UNTIMEOUT(ccp_rack_timeout
, f
);
1497 pcb
->ccp_localstate
= 0;
1498 ccp_set(pcb
, 1, 0, 0, 0);
1502 if (pcb
->lcp_fsm
.state
== PPP_FSM_OPENED
) {
1503 /* If LCP is not already going down, make sure it does. */
1504 ppp_error("MPPE disabled");
1505 lcp_close(pcb
, "MPPE disabled");
1508 #endif /* MPPE_SUPPORT */
1511 #if PRINTPKT_SUPPORT
1513 * Print the contents of a CCP packet.
1515 static const char* const ccp_codenames
[] = {
1516 "ConfReq", "ConfAck", "ConfNak", "ConfRej",
1517 "TermReq", "TermAck", "CodeRej",
1518 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
1519 "ResetReq", "ResetAck",
1522 static int ccp_printpkt(const u_char
*p
, int plen
, void (*printer
) (void *, const char *, ...), void *arg
) {
1523 const u_char
*p0
, *optend
;
1528 if (plen
< HEADERLEN
)
1532 len
= (p
[2] << 8) + p
[3];
1533 if (len
< HEADERLEN
|| len
> plen
)
1536 if (code
>= 1 && code
<= (int)LWIP_ARRAYSIZE(ccp_codenames
) && ccp_codenames
[code
-1] != NULL
)
1537 printer(arg
, " %s", ccp_codenames
[code
-1]);
1539 printer(arg
, " code=0x%x", code
);
1540 printer(arg
, " id=0x%x", id
);
1549 /* print list of possible compression methods */
1553 if (optlen
< 2 || optlen
> len
)
1557 optend
= p
+ optlen
;
1561 if (optlen
>= CILEN_MPPE
) {
1564 MPPE_CI_TO_OPTS(&p
[2], mppe_opts
);
1565 printer(arg
, "mppe %s %s %s %s %s %s%s",
1566 (p
[2] & MPPE_H_BIT
)? "+H": "-H",
1567 (p
[5] & MPPE_M_BIT
)? "+M": "-M",
1568 (p
[5] & MPPE_S_BIT
)? "+S": "-S",
1569 (p
[5] & MPPE_L_BIT
)? "+L": "-L",
1570 (p
[5] & MPPE_D_BIT
)? "+D": "-D",
1571 (p
[5] & MPPE_C_BIT
)? "+C": "-C",
1572 (mppe_opts
& MPPE_OPT_UNKNOWN
)? " +U": "");
1573 if (mppe_opts
& MPPE_OPT_UNKNOWN
)
1574 printer(arg
, " (%.2x %.2x %.2x %.2x)",
1575 p
[2], p
[3], p
[4], p
[5]);
1579 #endif /* MPPE_SUPPORT */
1582 case CI_DEFLATE_DRAFT
:
1583 if (optlen
>= CILEN_DEFLATE
) {
1584 printer(arg
, "deflate%s %d",
1585 (code
== CI_DEFLATE_DRAFT
? "(old#)": ""),
1586 DEFLATE_SIZE(p
[2]));
1587 if (DEFLATE_METHOD(p
[2]) != DEFLATE_METHOD_VAL
)
1588 printer(arg
, " method %d", DEFLATE_METHOD(p
[2]));
1589 if (p
[3] != DEFLATE_CHK_SEQUENCE
)
1590 printer(arg
, " check %d", p
[3]);
1594 #endif /* DEFLATE_SUPPORT */
1595 #if BSDCOMPRESS_SUPPORT
1596 case CI_BSD_COMPRESS
:
1597 if (optlen
>= CILEN_BSD_COMPRESS
) {
1598 printer(arg
, "bsd v%d %d", BSD_VERSION(p
[2]),
1600 p
+= CILEN_BSD_COMPRESS
;
1603 #endif /* BSDCOMPRESS_SUPPORT */
1604 #if PREDICTOR_SUPPORT
1605 case CI_PREDICTOR_1
:
1606 if (optlen
>= CILEN_PREDICTOR_1
) {
1607 printer(arg
, "predictor 1");
1608 p
+= CILEN_PREDICTOR_1
;
1611 case CI_PREDICTOR_2
:
1612 if (optlen
>= CILEN_PREDICTOR_2
) {
1613 printer(arg
, "predictor 2");
1614 p
+= CILEN_PREDICTOR_2
;
1617 #endif /* PREDICTOR_SUPPORT */
1622 printer(arg
, " %.2x", *p
++);
1629 if (len
> 0 && *p
>= ' ' && *p
< 0x7f) {
1630 ppp_print_string(p
, len
, printer
, arg
);
1639 /* dump out the rest of the packet in hex */
1641 printer(arg
, " %.2x", *p
++);
1645 #endif /* PRINTPKT_SUPPORT */
1649 * We have received a packet that the decompressor failed to
1650 * decompress. Here we would expect to issue a reset-request, but
1651 * Motorola has a patent on resetting the compressor as a result of
1652 * detecting an error in the decompressed data after decompression.
1653 * (See US patent 5,130,993; international patent publication number
1654 * WO 91/10289; Australian patent 73296/91.)
1656 * So we ask the kernel whether the error was detected after
1657 * decompression; if it was, we take CCP down, thus disabling
1658 * compression :-(, otherwise we issue the reset-request.
1660 static void ccp_datainput(ppp_pcb
*pcb
, u_char
*pkt
, int len
) {
1663 ccp_options
*go
= &pcb
->ccp_gotoptions
;
1664 #endif /* MPPE_SUPPORT */
1665 LWIP_UNUSED_ARG(pkt
);
1666 LWIP_UNUSED_ARG(len
);
1669 if (f
->state
== PPP_FSM_OPENED
) {
1670 if (ccp_fatal_error(pcb
)) {
1672 * Disable compression by taking CCP down.
1674 ppp_error("Lost compression sync: disabling compression");
1675 ccp_close(pcb
, "Lost compression sync");
1678 * If we were doing MPPE, we must also take the link down.
1681 ppp_error("Too many MPPE errors, closing LCP");
1682 lcp_close(pcb
, "Too many MPPE errors");
1684 #endif /* MPPE_SUPPORT */
1687 * Send a reset-request to reset the peer's compressor.
1688 * We don't do that if we are still waiting for an
1689 * acknowledgement to a previous reset-request.
1691 if (!(pcb
->ccp_localstate
& RACK_PENDING
)) {
1692 fsm_sdata(f
, CCP_RESETREQ
, f
->reqid
= ++f
->id
, NULL
, 0);
1693 TIMEOUT(ccp_rack_timeout
, f
, RACKTIMEOUT
);
1694 pcb
->ccp_localstate
|= RACK_PENDING
;
1696 pcb
->ccp_localstate
|= RREQ_REPEAT
;
1700 #endif /* PPP_DATAINPUT */
1703 * We have received a packet that the decompressor failed to
1704 * decompress. Issue a reset-request.
1706 void ccp_resetrequest(ppp_pcb
*pcb
) {
1707 fsm
*f
= &pcb
->ccp_fsm
;
1709 if (f
->state
!= PPP_FSM_OPENED
)
1713 * Send a reset-request to reset the peer's compressor.
1714 * We don't do that if we are still waiting for an
1715 * acknowledgement to a previous reset-request.
1717 if (!(pcb
->ccp_localstate
& RACK_PENDING
)) {
1718 fsm_sdata(f
, CCP_RESETREQ
, f
->reqid
= ++f
->id
, NULL
, 0);
1719 TIMEOUT(ccp_rack_timeout
, f
, RACKTIMEOUT
);
1720 pcb
->ccp_localstate
|= RACK_PENDING
;
1722 pcb
->ccp_localstate
|= RREQ_REPEAT
;
1726 * Timeout waiting for reset-ack.
1728 static void ccp_rack_timeout(void *arg
) {
1730 ppp_pcb
*pcb
= f
->pcb
;
1732 if (f
->state
== PPP_FSM_OPENED
&& (pcb
->ccp_localstate
& RREQ_REPEAT
)) {
1733 fsm_sdata(f
, CCP_RESETREQ
, f
->reqid
, NULL
, 0);
1734 TIMEOUT(ccp_rack_timeout
, f
, RACKTIMEOUT
);
1735 pcb
->ccp_localstate
&= ~RREQ_REPEAT
;
1737 pcb
->ccp_localstate
&= ~RACK_PENDING
;
1740 #endif /* PPP_SUPPORT && CCP_SUPPORT */