2 * lcp.c - PPP Link Control Protocol.
4 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5 * Use is subject to license terms.
7 * Copyright (c) 1989 Carnegie Mellon University.
10 * Copyright (c) 2016 by Delphix. All rights reserved.
12 * Redistribution and use in source and binary forms are permitted
13 * provided that the above copyright notice and this paragraph are
14 * duplicated in all such forms and that any documentation,
15 * advertising materials, and other materials related to such
16 * distribution and use acknowledge that the software was developed
17 * by Carnegie Mellon University. The name of the
18 * University may not be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
22 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 #if defined(CHAPMS) || defined(CHAPMSV2)
46 #include "patchlevel.h"
49 * Special failure codes for logging link failure reasons.
51 bool peer_nak_auth
; /* Peer sent nak for our auth request */
52 u_short nak_auth_orig
; /* Auth proto peer naked */
53 u_short nak_auth_proto
; /* Auth proto peer suggested instead */
54 bool unsolicited_nak_auth
; /* Peer asked us to authenticate */
55 u_short unsolicit_auth_proto
; /* Auth proto peer wants */
56 bool peer_reject_auth
; /* Peer sent reject for auth */
57 u_short reject_auth_proto
; /* Protocol that peer rejected */
58 bool rejected_peers_auth
; /* We sent a reject to the peer */
59 u_short rejected_auth_proto
; /* Protocol that peer wanted to use */
60 bool naked_peers_auth
; /* We sent a nak to the peer */
61 u_short naked_auth_orig
; /* Protocol that we wanted to use */
62 u_short naked_auth_proto
; /* Protocol that peer wants us to use */
65 * LCP-related command-line options.
67 int lcp_echo_interval
= 0; /* Interval between LCP echo-requests */
68 int lcp_echo_fails
= 0; /* Tolerance to unanswered echo-requests */
69 bool lax_recv
= 0; /* accept control chars in asyncmap */
70 static int use_accm_test
= 2; /* use big echo-requests to check ACCM */
71 #define ACCM_TEST_FAILS 5
74 #define _tostr(x) _tostr2(x)
75 static char identstr
[256] = /* Identification string */
76 "ppp-" VERSION
"." _tostr(PATCHLEVEL
) IMPLEMENTATION
;
77 static int noident
= 0; /* 1 to disable; 2 to reject */
78 static int sentident
= 0; /* counts the # of ident codes sent */
80 /* set if we're allowed to send an unsolicited Configure-Nak for MRU. */
81 static bool unsolicit_mru
;
83 static int setescape
__P((char **, option_t
*));
85 static bool do_msft_workaround
= 1;
86 static int setasyncmap
__P((char **, option_t
*));
88 bool noendpoint
= 0; /* don't send/accept endpoint discriminator */
89 static int setendpoint
__P((char **, option_t
*));
91 static char *callback_strings
[] = {
92 "auth", "dialstring", "location", "E.164", "X.500", "", "CBCP", NULL
95 /* This is used in packet printing even if NEGOTIATE_FCS isn't enabled */
96 static char *fcsalt_strings
[] = {
97 "null", "crc16", "crc32", NULL
101 static int setfcsallow
__P((char **, option_t
*));
102 static int setfcswant
__P((char **, option_t
*));
105 /* Backward compatibility for Linux */
107 #define PPP_MTU 1500 /* Default MTU (size of Info field) */
108 #define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN)
109 #define PPP_MINMTU 64
110 #define PPP_MAXMRU 65000 /* Largest MRU we allow */
111 #define PPP_MINMRU 128
114 static option_t lcp_option_list
[] = {
116 { "noaccomp", o_bool
, &lcp_wantoptions
[0].neg_accompression
,
117 "Disable address/control compression",
118 OPT_A2COPY
, &lcp_allowoptions
[0].neg_accompression
},
119 { "-ac", o_bool
, &lcp_wantoptions
[0].neg_accompression
,
120 "Disable address/control compression",
121 OPT_A2COPY
, &lcp_allowoptions
[0].neg_accompression
},
122 { "default-asyncmap", o_bool
, &lcp_wantoptions
[0].neg_asyncmap
,
123 "Disable asyncmap negotiation",
124 OPT_A2COPY
, &lcp_allowoptions
[0].neg_asyncmap
},
125 { "-am", o_bool
, &lcp_wantoptions
[0].neg_asyncmap
,
126 "Disable asyncmap negotiation",
127 OPT_A2COPY
, &lcp_allowoptions
[0].neg_asyncmap
},
128 { "asyncmap", o_special
, (void *)setasyncmap
,
129 "Set asyncmap (for received packets)" },
130 { "-as", o_special
, (void *)setasyncmap
,
131 "Set asyncmap (for received packets)" },
132 { "nomagic", o_bool
, &lcp_wantoptions
[0].neg_magicnumber
,
133 "Disable magic number option (looped-back line detect)",
134 OPT_A2COPY
, &lcp_allowoptions
[0].neg_magicnumber
},
135 { "-mn", o_bool
, &lcp_wantoptions
[0].neg_magicnumber
,
136 "Disable magic number option (looped-back line detect)",
137 OPT_A2COPY
, &lcp_allowoptions
[0].neg_magicnumber
},
138 { "default-mru", o_bool
, &lcp_wantoptions
[0].neg_mru
,
139 "Disable MRU negotiation (use default 1500)",
140 OPT_A2COPY
, &lcp_allowoptions
[0].neg_mru
},
141 { "-mru", o_bool
, &lcp_wantoptions
[0].neg_mru
,
142 "Disable MRU negotiation (use default 1500)",
143 OPT_A2COPY
, &lcp_allowoptions
[0].neg_mru
},
144 { "mru", o_int
, &lcp_wantoptions
[0].mru
,
145 "Set MRU (maximum received packet size) for negotiation",
146 OPT_LIMITS
, &lcp_wantoptions
[0].neg_mru
, PPP_MAXMRU
, PPP_MINMRU
},
147 { "mtu", o_int
, &lcp_allowoptions
[0].mru
,
148 "Set our MTU", OPT_LIMITS
|OPT_A2COPY
, &lcp_allowoptions
[0].mrru
,
149 PPP_MAXMTU
, PPP_MINMTU
},
150 { "nopcomp", o_bool
, &lcp_wantoptions
[0].neg_pcompression
,
151 "Disable protocol field compression",
152 OPT_A2COPY
, &lcp_allowoptions
[0].neg_pcompression
},
153 { "-pc", o_bool
, &lcp_wantoptions
[0].neg_pcompression
,
154 "Disable protocol field compression",
155 OPT_A2COPY
, &lcp_allowoptions
[0].neg_pcompression
},
156 { "-p", o_bool
, &lcp_wantoptions
[0].passive
,
157 "Set passive mode", 1 },
158 { "passive", o_bool
, &lcp_wantoptions
[0].passive
,
159 "Set passive mode", 1 },
160 { "silent", o_bool
, &lcp_wantoptions
[0].silent
,
161 "Set silent mode", 1 },
162 { "escape", o_special
, (void *)setescape
,
163 "List of character codes to escape on transmission" },
164 { "lcp-echo-failure", o_int
, &lcp_echo_fails
,
165 "Number of consecutive echo failures for link failure" },
166 { "lcp-echo-interval", o_int
, &lcp_echo_interval
,
167 "Set time in seconds between LCP echo requests" },
168 { "no-accm-test", o_int
, &use_accm_test
,
169 "Disable use of LCP Echo-Request asyncmap checking",
170 OPT_NOARG
|OPT_VAL(0) },
171 { "small-accm-test", o_int
, &use_accm_test
,
172 "Use only small Echo-Requests for asyncmap checking",
173 OPT_NOARG
|OPT_VAL(1) },
174 { "lcp-restart", o_int
, &lcp_fsm
[0].timeouttime
,
175 "Set time in seconds between LCP retransmissions" },
176 { "lcp-max-terminate", o_int
, &lcp_fsm
[0].maxtermtransmits
,
177 "Maximum number of LCP terminate-request transmissions" },
178 { "lcp-max-configure", o_int
, &lcp_fsm
[0].maxconfreqtransmits
,
179 "Maximum number of LCP configure-request transmissions" },
180 { "lcp-max-failure", o_int
, &lcp_fsm
[0].maxnakloops
,
181 "Set limit on number of LCP configure-naks" },
182 { "receive-all", o_bool
, &lax_recv
,
183 "Accept all received control characters", 1 },
184 #ifdef HAVE_MULTILINK
185 { "mrru", o_int
, &lcp_wantoptions
[0].mrru
,
186 "Maximum received packet size for multilink bundle",
187 OPT_LIMITS
, &lcp_wantoptions
[0].neg_mrru
, PPP_MAXMRU
, PPP_MINMRU
},
188 { "mpshortseq", o_bool
, &lcp_wantoptions
[0].neg_ssnhf
,
189 "Use short sequence numbers in multilink headers",
190 OPT_A2COPY
| 1, &lcp_allowoptions
[0].neg_ssnhf
},
191 { "nompshortseq", o_bool
, &lcp_wantoptions
[0].neg_ssnhf
,
192 "Don't use short sequence numbers in multilink headers",
193 OPT_A2COPY
, &lcp_allowoptions
[0].neg_ssnhf
},
194 #endif /* HAVE_MULTILINK */
195 { "endpoint", o_special
, (void *)setendpoint
,
196 "Endpoint discriminator for multilink", },
197 { "noendpoint", o_bool
, &noendpoint
,
198 "Don't send or accept multilink endpoint discriminator", 1 },
199 { "ident", o_string
, identstr
,
200 "LCP Identification string", OPT_STATIC
, NULL
, sizeof(identstr
) },
201 { "noident", o_int
, &noident
,
202 "Disable use of LCP Identification", OPT_INC
|OPT_NOARG
|1 },
204 { "default-fcs", o_bool
, &lcp_wantoptions
[0].neg_fcs
,
205 "Disable FCS Alternatives option (use default CRC-16)",
206 OPT_A2COPY
, &lcp_allowoptions
[0].neg_fcs
},
207 { "allow-fcs", o_special
, (void *)setfcsallow
,
208 "Set allowable FCS types; crc16, crc32, null, or number" },
209 { "fcs", o_special
, (void *)setfcswant
,
210 "Set FCS type(s) desired; crc16, crc32, null, or number" },
214 * if pppmux option is turned on, then the parameter to this
215 * is time value in microseconds
217 { "pppmux", o_int
, &lcp_wantoptions
[0].pppmux
,
218 "Set PPP Multiplexing option timer", OPT_LLIMIT
| OPT_A2COPY
,
219 &lcp_allowoptions
[0].pppmux
, 0, 0 },
225 fsm lcp_fsm
[NUM_PPP
]; /* LCP fsm structure (global)*/
226 lcp_options lcp_wantoptions
[NUM_PPP
]; /* Options that we want to request */
227 lcp_options lcp_gotoptions
[NUM_PPP
]; /* Options that peer ack'd */
228 lcp_options lcp_allowoptions
[NUM_PPP
]; /* Options we allow peer to request */
229 lcp_options lcp_hisoptions
[NUM_PPP
]; /* Options that we ack'd */
230 u_int32_t xmit_accm
[NUM_PPP
][8]; /* extended transmit ACCM */
233 * These variables allow a plugin to assert limits on the maximum
234 * MRU/MTU values that can be negotiated.
236 int absmax_mru
= PPP_MAXMRU
;
237 int absmax_mtu
= PPP_MAXMTU
;
239 static int lcp_echos_pending
= 0; /* Number of outstanding echo msgs */
240 static int lcp_echo_number
= 0; /* ID number of next echo frame */
241 static int lcp_echo_timer_running
= 0; /* set if a timer is running */
242 static bool lcp_echo_accm_test
= 0; /* flag if still testing ACCM */
243 static int lcp_echo_badreplies
= 0; /* number of bad replies from peer */
245 * The maximum number of bad replies we tolerate before bringing the
248 #define LCP_ECHO_MAX_BADREPLIES 10
251 * Callbacks for fsm code. (CI = Configuration Information)
253 static void lcp_resetci
__P((fsm
*)); /* Reset our CI */
254 static int lcp_cilen
__P((fsm
*)); /* Return length of our CI */
255 static void lcp_addci
__P((fsm
*, u_char
*, int *)); /* Add our CI to pkt */
256 static int lcp_ackci
__P((fsm
*, u_char
*, int)); /* Peer ack'd our CI */
257 static int lcp_nakci
__P((fsm
*, u_char
*, int)); /* Peer nak'd our CI */
258 static int lcp_rejci
__P((fsm
*, u_char
*, int)); /* Peer rej'd our CI */
259 static int lcp_reqci
__P((fsm
*, u_char
*, int *, int)); /* Rcv peer CI */
260 static void lcp_up
__P((fsm
*)); /* We're UP */
261 static void lcp_down
__P((fsm
*)); /* We're DOWN */
262 static void lcp_starting
__P((fsm
*)); /* We need lower layer up */
263 static void lcp_finished
__P((fsm
*)); /* We need lower layer down */
264 static int lcp_extcode
__P((fsm
*, int, int, u_char
*, int));
265 static void lcp_rprotrej
__P((fsm
*, u_char
*, int));
266 static int lcp_coderej
__P((fsm
*f
, int code
, int id
, u_char
*inp
, int len
));
269 * routines to send LCP echos to peer
272 static void lcp_echo_lowerup
__P((int));
273 static void lcp_echo_lowerdown
__P((int));
274 static void LcpEchoTimeout
__P((void *));
275 static int lcp_received_echo_reply
__P((fsm
*, int, u_char
*, int));
276 static void LcpSendEchoRequest
__P((fsm
*));
277 static void LcpLinkFailure
__P((fsm
*));
278 static void LcpEchoCheck
__P((fsm
*));
281 * routines to send and receive additional LCP packets described in
282 * section 1 of rfc1570.
284 static void LcpSendIdentification
__P((fsm
*));
285 static void lcp_received_identification
__P((fsm
*, int, u_char
*, int));
286 static void LcpSendTimeRemaining
__P((fsm
*, u_int32_t
));
287 static void lcp_timeremaining
__P((void *));
288 static void lcp_received_timeremain
__P((fsm
*, int, u_char
*, int));
291 static fsm_callbacks lcp_callbacks
= { /* LCP callback routines */
292 lcp_resetci
, /* Reset our Configuration Information */
293 lcp_cilen
, /* Length of our Configuration Information */
294 lcp_addci
, /* Add our Configuration Information */
295 lcp_ackci
, /* ACK our Configuration Information */
296 lcp_nakci
, /* NAK our Configuration Information */
297 lcp_rejci
, /* Reject our Configuration Information */
298 lcp_reqci
, /* Request peer's Configuration Information */
299 lcp_up
, /* Called when fsm reaches OPENED state */
300 lcp_down
, /* Called when fsm leaves OPENED state */
301 lcp_starting
, /* Called when we want the lower layer up */
302 lcp_finished
, /* Called when we want the lower layer down */
303 NULL
, /* Retransmission is necessary */
304 lcp_extcode
, /* Called to handle LCP-specific codes */
305 "LCP", /* String name of protocol */
306 lcp_coderej
, /* Peer rejected a code number */
310 * Protocol entry points.
311 * Some of these are called directly.
314 static void lcp_init
__P((int));
315 static void lcp_input
__P((int, u_char
*, int));
316 static void lcp_protrej
__P((int));
317 static int lcp_printpkt
__P((u_char
*, int,
318 void (*) __P((void *, const char *, ...)), void *));
321 struct protent lcp_protent
= {
322 PPP_LCP
, /* Protocol Number for LCP */
323 lcp_init
, /* Initializes LCP */
324 lcp_input
, /* Processes a received LCP packet */
325 lcp_protrej
, /* Process a received Protocol-reject */
326 lcp_lowerup
, /* Called after the serial device has been set up */
327 lcp_lowerdown
, /* Called when the link is brought down */
328 lcp_open
, /* Called after lcp_lowerup when bringing up the link */
329 lcp_close
, /* Called when the link goes down */
330 lcp_printpkt
, /* Print a packet in human readable form */
331 NULL
, /* Process a received data packet */
332 1, /* LCP is enabled by default */
333 "LCP", /* Name of the protocol */
334 NULL
, /* Name of the corresponding data protocol */
335 lcp_option_list
, /* List of LCP command-line options */
336 NULL
, /* Assigns default values for options */
337 NULL
, /* Configures demand-dial */
338 NULL
/* Bring up the link for this packet? */
341 int lcp_loopbackfail
= DEFLOOPBACKFAIL
;
344 * Length of each type of configuration option (in octets)
348 #define CILEN_SHORT 4 /* CILEN_VOID + 2 */
349 #define CILEN_CHAP 5 /* CILEN_VOID + 2 + 1 */
350 #define CILEN_LONG 6 /* CILEN_VOID + 4 */
351 #define CILEN_LQR 8 /* CILEN_VOID + 2 + 4 */
356 * setescape - add chars to the set we escape on transmission.
370 n
= strtol(p
, &endp
, 16);
372 option_error("escape parameter contains invalid hex number '%s'",
377 if (n
< 0 || n
== 0x5E || n
> 0xFF) {
378 option_error("can't escape character 0x%x", n
);
381 xmit_accm
[0][n
>> 5] |= 1 << (n
& 0x1F);
382 while (*p
== ',' || *p
== ' ')
389 * setasyncmap - set async map negotiated
393 setasyncmap(argv
, opt
)
400 val
= strtoul(*argv
, &endp
, 16);
402 option_error("invalid numeric parameter '%s' for 'asyncmap' option",
406 lcp_wantoptions
[0].asyncmap
|= val
;
407 lcp_wantoptions
[0].neg_asyncmap
= (~lcp_wantoptions
[0].asyncmap
!= 0);
408 do_msft_workaround
= 0;
414 setendpoint(argv
, opt
)
418 if (str_to_epdisc(&lcp_wantoptions
[0].endpoint
, *argv
)) {
419 lcp_wantoptions
[0].neg_endpoint
= 1;
422 option_error("Can't parse '%s' as an endpoint discriminator", *argv
);
428 str_to_fcstype(opt
,arg
)
437 while (*arg
!= '\0') {
440 len
= strtol(arg
, &cp
, 0);
441 if (len
< 0 || len
> 255 || arg
== cp
||
442 (*cp
!= '\0' && *cp
!= ','))
447 for (cpp
= fcsalt_strings
; *cpp
!= NULL
; cpp
++) {
449 if (strncasecmp(arg
, *cpp
, len
) == 0 &&
450 (arg
[len
] == '\0' || arg
[len
] == ','))
455 val
|= 1<<(cpp
-fcsalt_strings
);
457 if (arg
[len
] == '\0') {
465 option_error("Can't parse '%s' as an FCS type", arg
);
471 setfcsallow(argv
, opt
)
475 return str_to_fcstype(&lcp_allowoptions
[0], *argv
);
480 setfcswant(argv
, opt
)
484 return str_to_fcstype(&lcp_wantoptions
[0], *argv
);
489 * lcp_init - Initialize LCP.
495 fsm
*f
= &lcp_fsm
[unit
];
496 lcp_options
*wo
= &lcp_wantoptions
[unit
];
497 lcp_options
*ao
= &lcp_allowoptions
[unit
];
500 f
->protocol
= PPP_LCP
;
501 f
->callbacks
= &lcp_callbacks
;
505 BZERO(wo
, sizeof(*wo
));
508 wo
->neg_asyncmap
= 1;
509 wo
->chap_mdtype
= CHAP_DIGEST_MD5
;
510 wo
->neg_magicnumber
= 1;
511 wo
->neg_pcompression
= 1;
512 wo
->neg_accompression
= 1;
515 * Leave allowed MRU (MTU) at zero; configuration option sets it
516 * non-zero if we should nak for something else.
518 BZERO(ao
, sizeof(*ao
));
520 ao
->neg_asyncmap
= 1;
522 #if defined(CHAPMS) || defined(CHAPMSV2)
524 /* Check if DES wasn't exported */
526 setkey("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
527 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
535 ao
->neg_mschapv2
= 1;
539 ao
->chap_mdtype
= CHAP_DIGEST_MD5
;
541 ao
->neg_magicnumber
= 1;
542 ao
->neg_pcompression
= 1;
543 ao
->neg_accompression
= 1;
547 ao
->neg_endpoint
= 1;
550 ao
->fcs_type
= FCSALT_NULL
|FCSALT_16
|FCSALT_32
;
553 BZERO(xmit_accm
[unit
], sizeof(xmit_accm
[0]));
554 xmit_accm
[unit
][3] = 0x60000000;
559 * lcp_open - LCP is allowed to come up.
565 fsm
*f
= &lcp_fsm
[unit
];
566 lcp_options
*wo
= &lcp_wantoptions
[unit
];
570 f
->flags
|= OPT_PASSIVE
;
572 f
->flags
|= OPT_SILENT
;
578 * lcp_close - Take LCP down.
581 lcp_close(unit
, reason
)
585 fsm
*f
= &lcp_fsm
[unit
];
587 if (phase
!= PHASE_DEAD
)
588 new_phase(PHASE_TERMINATE
);
589 if (f
->state
== STOPPED
&& (f
->flags
& (OPT_PASSIVE
|OPT_SILENT
))) {
591 * This action is not strictly according to the FSM in RFC1548,
592 * but it does mean that the program terminates if you do a
593 * lcp_close() in passive/silent mode when a connection hasn't
600 fsm_close(&lcp_fsm
[unit
], reason
);
605 * lcp_lowerup - The lower layer is up.
611 lcp_options
*wo
= &lcp_wantoptions
[unit
];
614 mru
= PPP_MRU
> absmax_mru
? absmax_mru
: PPP_MRU
;
615 mtu
= PPP_MTU
> absmax_mtu
? absmax_mtu
: PPP_MTU
;
618 * Don't use A/C or protocol compression on transmission,
619 * but accept A/C and protocol compressed packets
620 * if we are going to ask for A/C and protocol compression.
622 ppp_set_xaccm(unit
, xmit_accm
[unit
]);
623 ppp_send_config(unit
, mtu
, 0xffffffff, 0, 0);
624 ppp_recv_config(unit
, mru
, (lax_recv
? 0: 0xffffffff),
625 wo
->neg_pcompression
, wo
->neg_accompression
);
627 ppp_send_fcs(unit
, FCSALT_16
);
628 ppp_recv_fcs(unit
, FCSALT_16
);
631 fsm_setpeermru(unit
, mtu
);
632 lcp_allowoptions
[unit
].asyncmap
= xmit_accm
[unit
][0];
634 fsm_lowerup(&lcp_fsm
[unit
]);
639 * lcp_lowerdown - The lower layer is down.
645 fsm_lowerdown(&lcp_fsm
[unit
]);
650 * lcp_input - Input LCP packet.
653 lcp_input(unit
, p
, len
)
658 fsm
*f
= &lcp_fsm
[unit
];
660 fsm_input(f
, p
, len
);
665 * lcp_extcode - Handle a LCP-specific code.
668 lcp_extcode(f
, code
, id
, inp
, len
)
678 lcp_rprotrej(f
, inp
, len
);
682 if (f
->state
!= OPENED
)
685 PUTLONG(lcp_gotoptions
[f
->unit
].magicnumber
, magp
);
686 fsm_sdata(f
, CODE_ECHOREP
, id
, inp
, len
);
690 if (!lcp_received_echo_reply(f
, id
, inp
, len
)) {
691 lcp_echo_badreplies
++;
692 if (lcp_echo_badreplies
> LCP_ECHO_MAX_BADREPLIES
) {
694 lcp_echos_pending
= 0;
695 lcp_echo_badreplies
= 0;
704 /* More than one 'noident' tells us to reject the code number. */
707 lcp_received_identification(f
, id
, inp
, len
);
710 case CODE_TIMEREMAIN
:
711 lcp_received_timeremain(f
, id
, inp
, len
);
721 * lcp_rprotrej - Receive an Protocol-Reject.
723 * Figure out which protocol is rejected and inform it.
726 lcp_rprotrej(f
, inp
, len
)
732 struct protent
*protp
;
736 dbglog("lcp_rprotrej: Rcvd short Protocol-Reject packet!");
743 * Protocol-Reject packets received in any state other than the LCP
744 * OPENED state SHOULD be silently discarded.
746 if( f
->state
!= OPENED
){
747 dbglog("Protocol-Reject discarded: LCP in state %s",
748 fsm_state(f
->state
));
753 * Upcall the proper Protocol-Reject routine.
755 for (i
= 0; (protp
= protocols
[i
]) != NULL
; ++i
)
756 if (protp
->protocol
== prot
&& protp
->enabled_flag
) {
757 (*protp
->protrej
)(f
->unit
);
761 warn("Protocol-Reject for unsupported protocol 0x%x", prot
);
766 * lcp_protrej - A Protocol-Reject was received.
776 error("Received Protocol-Reject for LCP!");
780 * lcp_coderej - A Code-Reject was received.
784 lcp_coderej(f
, code
, id
, inp
, len
)
791 /* The peer cannot reject these code numbers. */
792 if (code
>= CODE_CONFREQ
&& code
<= CODE_PROTREJ
)
797 * If the peer rejects an Echo-Request, then stop doing that.
799 if (lcp_echo_timer_running
!= 0) {
800 UNTIMEOUT (LcpEchoTimeout
, f
);
801 lcp_echo_timer_running
= 0;
802 lcp_echo_interval
= 0;
810 * lcp_sprotrej - Send a Protocol-Reject for some protocol.
813 lcp_sprotrej(unit
, p
, len
)
819 * Send back the protocol and the information field of the
820 * rejected packet. We only get here if LCP is in the OPENED state.
825 fsm_sdata(&lcp_fsm
[unit
], CODE_PROTREJ
, ++lcp_fsm
[unit
].id
,
831 * lcp_resetci - Reset our CI.
837 lcp_options
*wo
= &lcp_wantoptions
[f
->unit
];
838 lcp_options
*go
= &lcp_gotoptions
[f
->unit
];
839 lcp_options
*ao
= &lcp_allowoptions
[f
->unit
];
841 wo
->magicnumber
= magic();
850 ao
->neg_endpoint
= 0;
851 if (go
->mru
> absmax_mru
)
852 go
->mru
= absmax_mru
;
853 if (ao
->mru
> absmax_mtu
)
854 ao
->mru
= absmax_mtu
;
856 fsm_setpeermru(f
->unit
, PPP_MTU
> absmax_mtu
? absmax_mtu
: PPP_MTU
);
862 * lcp_cilen - Return length of our CI.
868 lcp_options
*go
= &lcp_gotoptions
[f
->unit
];
870 #define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0)
871 #define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0)
872 #define LENCICHAR(neg) ((neg) ? CILEN_CHAR : 0)
873 #define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0)
874 #define LENCILONG(neg) ((neg) ? CILEN_LONG : 0)
875 #define LENCILQR(neg) ((neg) ? CILEN_LQR: 0)
876 #define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0)
878 * NB: we only ask for one of CHAP and UPAP, even if we will
881 return (LENCISHORT(go
->neg_mru
&& go
->mru
!= PPP_MRU
) +
882 LENCILONG(go
->neg_asyncmap
&& go
->asyncmap
!= 0xFFFFFFFF) +
883 LENCICHAP(go
->neg_chap
|| go
->neg_mschap
|| go
->neg_mschapv2
) +
884 LENCISHORT(!go
->neg_chap
&& go
->neg_upap
&& !go
->neg_mschap
&&
886 LENCILQR(go
->neg_lqr
) +
887 LENCICBCP(go
->neg_cbcp
) +
888 LENCILONG(go
->neg_magicnumber
) +
889 LENCIVOID(go
->neg_pcompression
) +
890 LENCIVOID(go
->neg_accompression
) +
891 LENCICHAR(go
->neg_fcs
) +
892 LENCISHORT(go
->neg_mrru
) +
893 LENCIVOID(go
->neg_ssnhf
) +
895 LENCIVOID(go
->pppmux
) +
897 (go
->neg_endpoint
? CILEN_CHAR
+ go
->endpoint
.length
: 0));
902 * lcp_addci - Add our desired CIs to a packet.
905 lcp_addci(f
, ucp
, lenp
)
910 lcp_options
*go
= &lcp_gotoptions
[f
->unit
];
911 lcp_options
*ho
= &lcp_hisoptions
[f
->unit
];
912 u_char
*start_ucp
= ucp
;
914 #define ADDCIVOID(opt, neg) \
917 PUTCHAR(CILEN_VOID, ucp); \
919 #define ADDCISHORT(opt, neg, val) \
922 PUTCHAR(CILEN_SHORT, ucp); \
923 PUTSHORT(val, ucp); \
925 #define ADDCICHAP(opt, neg, val, digest) \
928 PUTCHAR(CILEN_CHAP, ucp); \
929 PUTSHORT(val, ucp); \
930 PUTCHAR(digest, ucp); \
932 #define ADDCILONG(opt, neg, val) \
935 PUTCHAR(CILEN_LONG, ucp); \
938 #define ADDCILQR(opt, neg, val) \
941 PUTCHAR(CILEN_LQR, ucp); \
942 PUTSHORT(PPP_LQR, ucp); \
945 #define ADDCICHAR(opt, neg, val) \
948 PUTCHAR(CILEN_CHAR, ucp); \
951 #define ADDCIENDP(opt, neg, class, val, len) \
955 PUTCHAR(CILEN_CHAR + len, ucp); \
956 PUTCHAR(class, ucp); \
957 for (i = 0; i < len; ++i) \
958 PUTCHAR(val[i], ucp); \
961 ADDCISHORT(CI_MRU
, go
->neg_mru
&& go
->mru
!= PPP_MRU
, go
->mru
);
962 ADDCILONG(CI_ASYNCMAP
, go
->neg_asyncmap
&& go
->asyncmap
!= 0xFFFFFFFF,
964 /* go->chap_mdtype always points to a useful value */
965 ADDCICHAP(CI_AUTHTYPE
, go
->neg_chap
|| go
->neg_mschap
|| go
->neg_mschapv2
,
966 PPP_CHAP
, go
->chap_mdtype
);
967 ADDCISHORT(CI_AUTHTYPE
, !(go
->neg_chap
|| go
->neg_mschap
||
968 go
->neg_mschapv2
) && go
->neg_upap
, PPP_PAP
);
969 /* We can't both say zero for LQR period. */
970 if (f
->state
== ACKSENT
&& go
->neg_lqr
&& go
->lqr_period
== 0 &&
971 ho
->neg_lqr
&& ho
->lqr_period
== 0)
972 go
->lqr_period
= 500;
973 ADDCILQR(CI_QUALITY
, go
->neg_lqr
, go
->lqr_period
);
974 ADDCICHAR(CI_CALLBACK
, go
->neg_cbcp
, CBOP_CBCP
);
975 ADDCILONG(CI_MAGICNUMBER
, go
->neg_magicnumber
, go
->magicnumber
);
976 ADDCIVOID(CI_PCOMPRESSION
, go
->neg_pcompression
);
977 ADDCIVOID(CI_ACCOMPRESSION
, go
->neg_accompression
);
978 ADDCICHAR(CI_FCSALTERN
, (go
->neg_fcs
&& go
->fcs_type
!= 0), go
->fcs_type
);
979 ADDCIENDP(CI_EPDISC
, go
->neg_endpoint
, go
->endpoint
.class,
980 go
->endpoint
.value
, go
->endpoint
.length
);
982 ADDCIVOID(CI_MUXING
, go
->pppmux
);
984 ADDCISHORT(CI_MRRU
, go
->neg_mrru
, go
->mrru
);
985 ADDCIVOID(CI_SSNHF
, go
->neg_ssnhf
);
987 if (ucp
- start_ucp
!= *lenp
) {
988 /* this should never happen, because peer_mtu should be 1500 */
989 error("Bug in lcp_addci: wrong length");
995 * lcp_ackci - Ack our CIs.
996 * This should not modify any state if the Ack is bad.
1003 lcp_ackci(f
, p
, len
)
1008 lcp_options
*go
= &lcp_gotoptions
[f
->unit
];
1010 lcp_options
*ao
= &lcp_allowoptions
[f
->unit
];
1012 u_char cilen
, citype
, cichar
;
1017 * CIs must be in exactly the same order that we sent.
1018 * Check packet length and CI length at each step.
1019 * If we find any deviations, then this packet is bad.
1021 #define ACKCIVOID(opt, neg) \
1023 if ((len -= CILEN_VOID) < 0) \
1025 GETCHAR(citype, p); \
1026 GETCHAR(cilen, p); \
1027 if (cilen != CILEN_VOID || \
1031 #define ACKCISHORT(opt, neg, val) \
1033 if ((len -= CILEN_SHORT) < 0) \
1035 GETCHAR(citype, p); \
1036 GETCHAR(cilen, p); \
1037 if (cilen != CILEN_SHORT || \
1040 GETSHORT(cishort, p); \
1041 if (cishort != val) \
1044 #define ACKCIAUTH(opt, neg, val) \
1046 if ((len -= CILEN_SHORT) < 0) \
1048 GETCHAR(citype, p); \
1049 GETCHAR(cilen, p); \
1050 if (cilen != CILEN_SHORT || \
1053 GETSHORT(cishort, p); \
1054 if (cishort != val) \
1056 peer_nak_auth = 0; \
1057 peer_reject_auth = 0; \
1059 #define ACKCICHAR(opt, neg, val) \
1061 if ((len -= CILEN_CHAR) < 0) \
1063 GETCHAR(citype, p); \
1064 GETCHAR(cilen, p); \
1065 if (cilen != CILEN_CHAR || \
1068 GETCHAR(cichar, p); \
1069 if (cichar != val) \
1072 #define ACKCICHAP(opt, neg, val, digest) \
1074 if ((len -= CILEN_CHAP) < 0) \
1076 GETCHAR(citype, p); \
1077 GETCHAR(cilen, p); \
1078 if (cilen != CILEN_CHAP || \
1081 GETSHORT(cishort, p); \
1082 if (cishort != val) \
1084 GETCHAR(cichar, p); \
1085 if (cichar != digest) \
1087 peer_nak_auth = 0; \
1088 peer_reject_auth = 0; \
1090 #define ACKCILONG(opt, neg, val) \
1092 if ((len -= CILEN_LONG) < 0) \
1094 GETCHAR(citype, p); \
1095 GETCHAR(cilen, p); \
1096 if (cilen != CILEN_LONG || \
1099 GETLONG(cilong, p); \
1100 if (cilong != val) \
1103 #define ACKCILQR(opt, neg, val) \
1105 if ((len -= CILEN_LQR) < 0) \
1107 GETCHAR(citype, p); \
1108 GETCHAR(cilen, p); \
1109 if (cilen != CILEN_LQR || \
1112 GETSHORT(cishort, p); \
1113 if (cishort != PPP_LQR) \
1115 GETLONG(cilong, p); \
1116 if (cilong != val) \
1119 #define ACKCIENDP(opt, neg, class, val, vlen) \
1122 if ((len -= CILEN_CHAR + vlen) < 0) \
1124 GETCHAR(citype, p); \
1125 GETCHAR(cilen, p); \
1126 if (cilen != CILEN_CHAR + vlen || \
1129 GETCHAR(cichar, p); \
1130 if (cichar != class) \
1132 for (i = 0; i < vlen; ++i) { \
1133 GETCHAR(cichar, p); \
1134 if (cichar != val[i]) \
1139 ACKCISHORT(CI_MRU
, go
->neg_mru
&& go
->mru
!= PPP_MRU
, go
->mru
);
1140 ACKCILONG(CI_ASYNCMAP
, go
->neg_asyncmap
&& go
->asyncmap
!= 0xFFFFFFFF,
1142 /* go->chap_mdtype always points to a useful value */
1143 ACKCICHAP(CI_AUTHTYPE
, go
->neg_chap
|| go
->neg_mschap
|| go
->neg_mschapv2
,
1144 PPP_CHAP
, go
->chap_mdtype
);
1145 ACKCIAUTH(CI_AUTHTYPE
, !(go
->neg_chap
|| go
->neg_mschap
||
1146 go
->neg_mschapv2
) && go
->neg_upap
, PPP_PAP
);
1147 ACKCILQR(CI_QUALITY
, go
->neg_lqr
, go
->lqr_period
);
1148 ACKCICHAR(CI_CALLBACK
, go
->neg_cbcp
, CBOP_CBCP
);
1149 ACKCILONG(CI_MAGICNUMBER
, go
->neg_magicnumber
, go
->magicnumber
);
1150 ACKCIVOID(CI_PCOMPRESSION
, go
->neg_pcompression
);
1151 ACKCIVOID(CI_ACCOMPRESSION
, go
->neg_accompression
);
1152 ACKCICHAR(CI_FCSALTERN
, go
->neg_fcs
, go
->fcs_type
);
1153 ACKCIENDP(CI_EPDISC
, go
->neg_endpoint
, go
->endpoint
.class,
1154 go
->endpoint
.value
, go
->endpoint
.length
);
1156 ACKCIVOID(CI_MUXING
, go
->pppmux
);
1158 go
->pppmux
= ao
->pppmux
;
1160 ACKCISHORT(CI_MRRU
, go
->neg_mrru
, go
->mrru
);
1161 ACKCIVOID(CI_SSNHF
, go
->neg_ssnhf
);
1164 * If there are any remaining CIs, then this packet is bad.
1170 dbglog("lcp_acki: received bad Ack!");
1176 * lcp_nakci - Peer has sent a NAK for some of our CIs.
1177 * This should not modify any state if the Nak is bad
1178 * or if LCP is in the OPENED state.
1185 lcp_nakci(f
, p
, len
)
1190 lcp_options
*go
= &lcp_gotoptions
[f
->unit
];
1191 lcp_options
*wo
= &lcp_wantoptions
[f
->unit
];
1192 u_char citype
, cichar
, *next
;
1195 lcp_options no
; /* options we've seen Naks for */
1196 lcp_options
try; /* options to request next time */
1197 int looped_back
= 0;
1200 BZERO(&no
, sizeof(no
));
1204 * Any Nak'd CIs must be in exactly the same order that we sent.
1205 * Check packet length and CI length at each step.
1206 * If we find any deviations, then this packet is bad.
1208 #define NAKCIVOID(opt, neg) \
1210 len >= CILEN_VOID && \
1211 p[1] == CILEN_VOID && \
1213 len -= CILEN_VOID; \
1214 INCPTR(CILEN_VOID, p); \
1218 #define NAKCICHAR(opt, neg, code) \
1220 len >= CILEN_CHAR && \
1221 p[1] == CILEN_CHAR && \
1223 len -= CILEN_CHAR; \
1225 GETCHAR(cichar, p); \
1229 #define NAKCISHORT(opt, neg, code) \
1231 len >= CILEN_SHORT && \
1232 p[1] == CILEN_SHORT && \
1234 len -= CILEN_SHORT; \
1236 GETSHORT(cishort, p); \
1240 #define NAKCILONG(opt, neg, code) \
1242 len >= CILEN_LONG && \
1243 p[1] == CILEN_LONG && \
1245 len -= CILEN_LONG; \
1247 GETLONG(cilong, p); \
1251 #define NAKCILQR(opt, neg, code) \
1253 len >= CILEN_LQR && \
1254 p[1] == CILEN_LQR && \
1258 GETSHORT(cishort, p); \
1259 GETLONG(cilong, p); \
1263 #define NAKCIENDP(opt, neg) \
1265 len >= CILEN_CHAR && \
1267 p[1] >= CILEN_CHAR && \
1276 * We don't care if they want to send us smaller packets than
1277 * we want. Therefore, accept any MRU less than what we asked for,
1278 * but then ignore the new value when setting the MRU in the kernel.
1279 * If they send us a bigger MRU than what we asked, accept it, up to
1280 * the limit of the default MRU we'd get if we didn't negotiate.
1282 if (go
->neg_mru
&& go
->mru
!= PPP_MRU
) {
1283 NAKCISHORT(CI_MRU
, neg_mru
,
1284 if (cishort
<= wo
->mru
||
1285 (cishort
<= PPP_MRU
&& cishort
<= absmax_mru
))
1291 * Add any characters they want to our (receive-side) asyncmap.
1293 if (go
->neg_asyncmap
&& go
->asyncmap
!= 0xFFFFFFFF) {
1294 NAKCILONG(CI_ASYNCMAP
, neg_asyncmap
,
1295 try.asyncmap
= go
->asyncmap
| cilong
;
1300 * If they've nak'd our authentication-protocol, check whether
1301 * they are proposing a different protocol, or a different
1302 * hash algorithm for CHAP.
1304 if ((go
->neg_chap
|| go
->neg_mschap
|| go
->neg_mschapv2
|| go
->neg_upap
) &&
1305 len
>= CILEN_SHORT
&& p
[0] == CI_AUTHTYPE
&& p
[1] >= CILEN_SHORT
&&
1310 GETSHORT(cishort
, p
);
1312 nak_auth_orig
= (go
->neg_chap
|| go
->neg_mschap
|| go
->neg_mschapv2
) ?
1314 nak_auth_proto
= cishort
;
1315 if (cishort
== PPP_PAP
&& cilen
== CILEN_SHORT
) {
1316 no
.neg_upap
= go
->neg_upap
;
1318 * If we were asking for CHAP, they obviously don't want to do it.
1319 * If we weren't asking for CHAP, then we were asking for PAP,
1320 * in which case this Nak is bad.
1322 if (!go
->neg_chap
&& !go
->neg_mschap
&& !go
->neg_mschapv2
)
1326 try.neg_mschapv2
= 0;
1328 } else if (cishort
== PPP_CHAP
&& cilen
>= CILEN_CHAP
) {
1329 /* stop asking for that type */
1330 switch (go
->chap_mdtype
) {
1331 case CHAP_DIGEST_MD5
:
1332 no
.neg_chap
= go
->neg_chap
;
1335 case CHAP_MICROSOFT
:
1336 no
.neg_mschap
= go
->neg_mschap
;
1339 case CHAP_MICROSOFT_V2
:
1340 no
.neg_mschapv2
= go
->neg_mschapv2
;
1341 try.neg_mschapv2
= 0;
1345 /* Allow >= on length here for broken and silly peers. */
1346 p
+= cilen
- CILEN_CHAP
;
1348 if ((cichar
== CHAP_DIGEST_MD5
&& wo
->neg_chap
) ||
1349 (cichar
== CHAP_MICROSOFT
&& wo
->neg_mschap
) ||
1350 (cichar
== CHAP_MICROSOFT_V2
&& wo
->neg_mschapv2
)) {
1351 /* Try its requested algorithm. */
1352 try.chap_mdtype
= cichar
;
1359 * We don't recognize what they're suggesting.
1360 * Stop asking for what we were asking for.
1363 if (go
->neg_chap
|| go
->neg_mschap
|| go
->neg_mschapv2
) {
1364 switch (go
->chap_mdtype
) {
1365 case CHAP_DIGEST_MD5
:
1367 if (wo
->neg_mschap
) {
1368 try.chap_mdtype
= CHAP_MICROSOFT
;
1372 case CHAP_MICROSOFT
:
1374 if (wo
->neg_mschapv2
) {
1375 try.chap_mdtype
= CHAP_MICROSOFT_V2
;
1379 case CHAP_MICROSOFT_V2
:
1380 try.neg_mschapv2
= 0;
1385 p
+= cilen
- CILEN_SHORT
;
1390 * If they can't cope with our link quality protocol, we'll have
1391 * to stop asking for LQR. We haven't got any other protocol. If
1392 * they Nak the reporting period, then the following logic
1394 * If it suggests zero and go->neg_fcs is true and
1395 * ao->lqr_period isn't zero, then take its suggestion. If it
1396 * suggests zero otherwise, ignore it. If it suggests a nonzero
1397 * value and wo->lqr_period is zero, then take its suggestion. If
1398 * it suggests a nonzero value otherwise that's less than
1399 * wo->lqr_period, then ignore it.
1401 NAKCILQR(CI_QUALITY
, neg_lqr
,
1402 if (cishort
!= PPP_LQR
)
1404 else if (cilong
== 0 && go
->neg_fcs
&& wo
->lqr_period
!= 0)
1405 try.lqr_period
= cilong
;
1406 else if (cilong
!= 0 &&
1407 (wo
->lqr_period
== 0 || cilong
> wo
->lqr_period
))
1408 try.lqr_period
= cilong
;
1412 * Only implementing CBCP...not the rest of the callback options
1414 NAKCICHAR(CI_CALLBACK
, neg_cbcp
,
1419 * Check for a looped-back line.
1421 NAKCILONG(CI_MAGICNUMBER
, neg_magicnumber
,
1422 try.magicnumber
= magic();
1427 * Peer shouldn't send Nak for protocol compression or
1428 * address/control compression requests; they should send
1429 * a Reject instead. If they send a Nak, treat it as a Reject.
1431 NAKCIVOID(CI_PCOMPRESSION
, neg_pcompression
);
1432 NAKCIVOID(CI_ACCOMPRESSION
, neg_accompression
);
1435 * Remove any FCS types it doesn't like from our (receive-side)
1438 NAKCICHAR(CI_FCSALTERN
, neg_fcs
, try.fcs_type
= go
->fcs_type
& cichar
;);
1441 /* Nacked MUX option */
1442 NAKCIVOID(CI_MUXING
, pppmux
);
1446 * Nak of the endpoint discriminator option is not permitted,
1447 * treat it like a reject.
1449 NAKCIENDP(CI_EPDISC
, neg_endpoint
);
1452 * Nak for MRRU option - accept their value if it is smaller
1453 * than the one we want.
1456 NAKCISHORT(CI_MRRU
, neg_mrru
,
1457 if (cishort
<= wo
->mrru
)
1463 * Nak for short sequence numbers shouldn't be sent, treat it
1466 NAKCIVOID(CI_SSNHF
, neg_ssnhf
);
1469 * There may be remaining CIs, if the peer is requesting negotiation
1470 * on an option that we didn't include in our request packet.
1471 * If we see an option that we requested, or one we've already seen
1472 * in this packet, then this packet is bad.
1473 * If we wanted to respond by starting to negotiate on the requested
1474 * option(s), we could, but we don't, because except for the
1475 * authentication type and quality protocol, if we are not negotiating
1476 * an option, it is because we were told not to.
1477 * For the authentication type, the Nak from the peer means
1478 * `let me authenticate myself with you' which is a bit pointless.
1479 * For the quality protocol, the Nak means `ask me to send you quality
1480 * reports', but if we didn't ask for them, we don't want them.
1481 * An option we don't recognize represents the peer asking to
1482 * negotiate some option we don't support, so ignore it.
1484 while (len
> CILEN_VOID
) {
1487 if (cilen
< CILEN_VOID
|| (len
-= cilen
) < 0)
1489 next
= p
+ cilen
- 2;
1493 if ((go
->neg_mru
&& go
->mru
!= PPP_MRU
)
1494 || no
.neg_mru
|| cilen
!= CILEN_SHORT
)
1496 GETSHORT(cishort
, p
);
1497 if (cishort
< PPP_MRU
&& cishort
< absmax_mru
) {
1500 notice("Peer sent unsolicited Nak for MRU less than default.");
1504 if ((go
->neg_asyncmap
&& go
->asyncmap
!= 0xFFFFFFFF)
1505 || no
.neg_asyncmap
|| cilen
!= CILEN_LONG
)
1509 unsolicited_nak_auth
= 1;
1510 if (cilen
>= CILEN_SHORT
) {
1511 GETSHORT(unsolicit_auth_proto
, p
);
1513 unsolicit_auth_proto
= 0;
1515 if (go
->neg_chap
|| no
.neg_chap
||
1516 go
->neg_mschap
|| no
.neg_mschap
||
1517 go
->neg_mschapv2
|| no
.neg_mschapv2
||
1518 go
->neg_upap
|| no
.neg_upap
)
1521 case CI_MAGICNUMBER
:
1522 if (go
->neg_magicnumber
|| no
.neg_magicnumber
||
1523 cilen
!= CILEN_LONG
)
1526 case CI_PCOMPRESSION
:
1527 if (go
->neg_pcompression
|| no
.neg_pcompression
1528 || cilen
!= CILEN_VOID
)
1531 case CI_ACCOMPRESSION
:
1532 if (go
->neg_accompression
|| no
.neg_accompression
1533 || cilen
!= CILEN_VOID
)
1537 if (go
->neg_lqr
|| no
.neg_lqr
|| cilen
!= CILEN_LQR
)
1541 if (go
->neg_mrru
|| no
.neg_mrru
|| cilen
!= CILEN_SHORT
)
1545 if (go
->neg_ssnhf
|| no
.neg_ssnhf
|| cilen
!= CILEN_VOID
)
1550 if (go
->neg_endpoint
|| no
.neg_endpoint
|| cilen
< CILEN_CHAR
)
1554 if (go
->neg_fcs
|| no
.neg_fcs
|| cilen
< CILEN_CHAR
)
1559 if (go
->pppmux
|| no
.pppmux
|| cilen
< CILEN_VOID
)
1568 * OK, the Nak is good. Now we can update state.
1569 * If there are any options left we ignore them.
1571 if (f
->state
!= OPENED
) {
1573 * Note: the code once reset try.numloops to zero here if
1574 * looped_back wasn't set. This is wrong because a mixture of
1575 * looped-back and peer data (possible if half-duplex is used)
1576 * will allow the link to come up, and it shouldn't.
1579 if (++try.numloops
>= lcp_loopbackfail
) {
1580 notice("Serial line is looped back.");
1581 lcp_close(f
->unit
, "Loopback detected");
1582 status
= EXIT_LOOPBACK
;
1591 dbglog("lcp_nakci: received bad Nak!");
1597 * lcp_rejci - Peer has Rejected some of our CIs.
1598 * This should not modify any state if the Reject is bad
1599 * or if LCP is in the OPENED state.
1602 * 0 - Reject was bad.
1603 * 1 - Reject was good.
1606 lcp_rejci(f
, p
, len
)
1611 lcp_options
*go
= &lcp_gotoptions
[f
->unit
];
1615 lcp_options
try; /* options to request next time */
1620 * Any Rejected CIs must be in exactly the same order that we sent.
1621 * Check packet length and CI length at each step.
1622 * If we find any deviations, then this packet is bad.
1624 #define REJCIVOID(opt, neg) \
1626 len >= CILEN_VOID && \
1627 p[1] == CILEN_VOID && \
1629 len -= CILEN_VOID; \
1630 INCPTR(CILEN_VOID, p); \
1633 #define REJCICHAR(opt, neg, val) \
1635 len >= CILEN_CHAR && \
1636 p[1] == CILEN_CHAR && \
1638 len -= CILEN_CHAR; \
1640 GETCHAR(cichar, p); \
1641 /* Check rejected value. */ \
1642 if (cichar != val) \
1646 #define REJCISHORT(opt, neg, val) \
1648 len >= CILEN_SHORT && \
1649 p[1] == CILEN_SHORT && \
1651 len -= CILEN_SHORT; \
1653 GETSHORT(cishort, p); \
1654 /* Check rejected value. */ \
1655 if (cishort != val) \
1659 #define REJCIAUTH(opt, neg, val) \
1661 len >= CILEN_SHORT && \
1662 p[1] == CILEN_SHORT && \
1664 len -= CILEN_SHORT; \
1666 GETSHORT(cishort, p); \
1667 /* Check rejected value. */ \
1668 peer_reject_auth = 1; \
1669 reject_auth_proto = cishort; \
1670 if (cishort != val) \
1674 #define REJCILONG(opt, neg, val) \
1676 len >= CILEN_LONG && \
1677 p[1] == CILEN_LONG && \
1679 len -= CILEN_LONG; \
1681 GETLONG(cilong, p); \
1682 /* Check rejected value. */ \
1683 if (cilong != val) \
1687 #define REJCILQR(opt, neg, val) \
1689 len >= CILEN_LQR && \
1690 p[1] == CILEN_LQR && \
1694 GETSHORT(cishort, p); \
1695 GETLONG(cilong, p); \
1696 /* Check rejected value. */ \
1697 if (cishort != PPP_LQR || cilong != val) \
1701 #define REJCICBCP(opt, neg, val) \
1703 len >= CILEN_CBCP && \
1704 p[1] == CILEN_CBCP && \
1706 len -= CILEN_CBCP; \
1708 GETCHAR(cichar, p); \
1709 /* Check rejected value. */ \
1710 if (cichar != val) \
1714 #define REJCIENDP(opt, neg, class, val, vlen) \
1716 len >= CILEN_CHAR + vlen && \
1718 p[1] == CILEN_CHAR + vlen) { \
1720 len -= CILEN_CHAR + vlen; \
1722 GETCHAR(cichar, p); \
1723 if (cichar != class) \
1725 for (i = 0; i < vlen; ++i) { \
1726 GETCHAR(cichar, p); \
1727 if (cichar != val[i]) \
1733 /* Received a Configure-Reject, try to send Identification now. */
1734 if (!noident
&& sentident
< 3) {
1735 LcpSendIdentification(f
);
1739 REJCISHORT(CI_MRU
, neg_mru
, go
->mru
);
1740 REJCILONG(CI_ASYNCMAP
, neg_asyncmap
, go
->asyncmap
);
1743 * There are broken peers (such as unbundled Solaris PPP) that
1744 * send Configure-Reject for authentication when they really
1745 * intend Configure-Nak. This code works around this problem.
1747 if ((go
->neg_chap
|| go
->neg_mschap
|| go
->neg_mschapv2
) &&
1748 len
>= CILEN_CHAP
&& p
[1] == CILEN_CHAP
&& p
[0] == CI_AUTHTYPE
) {
1751 GETSHORT(cishort
, p
);
1753 peer_reject_auth
= 1;
1754 reject_auth_proto
= cishort
;
1755 /* Check rejected value. */
1756 if (cishort
!= PPP_CHAP
|| cichar
!= go
->chap_mdtype
)
1758 /* Disable the one that it rejected */
1760 case CHAP_DIGEST_MD5
:
1763 case CHAP_MICROSOFT
:
1766 case CHAP_MICROSOFT_V2
:
1767 try.neg_mschapv2
= 0;
1770 /* Try another, if we can. */
1772 try.chap_mdtype
= CHAP_DIGEST_MD5
;
1773 else if (try.neg_mschap
)
1774 try.chap_mdtype
= CHAP_MICROSOFT
;
1776 try.chap_mdtype
= CHAP_MICROSOFT_V2
;
1779 if (!go
->neg_chap
&& !go
->neg_mschap
&& !go
->neg_mschapv2
) {
1780 REJCIAUTH(CI_AUTHTYPE
, neg_upap
, PPP_PAP
);
1782 REJCILQR(CI_QUALITY
, neg_lqr
, go
->lqr_period
);
1783 REJCICBCP(CI_CALLBACK
, neg_cbcp
, CBOP_CBCP
);
1784 REJCILONG(CI_MAGICNUMBER
, neg_magicnumber
, go
->magicnumber
);
1785 REJCIVOID(CI_PCOMPRESSION
, neg_pcompression
);
1786 REJCIVOID(CI_ACCOMPRESSION
, neg_accompression
);
1787 REJCICHAR(CI_FCSALTERN
, neg_fcs
, go
->fcs_type
);
1789 REJCIVOID(CI_MUXING
,pppmux
);
1791 REJCIENDP(CI_EPDISC
, neg_endpoint
, go
->endpoint
.class,
1792 go
->endpoint
.value
, go
->endpoint
.length
);
1793 REJCISHORT(CI_MRRU
, neg_mrru
, go
->mrru
);
1794 REJCIVOID(CI_SSNHF
, neg_ssnhf
);
1797 * If there are any remaining CIs, then this packet is bad.
1802 * Now we can update state.
1804 if (f
->state
!= OPENED
)
1809 dbglog("lcp_rejci: received bad Reject!");
1815 * lcp_reqci - Check the peer's requested CIs and send appropriate response.
1817 * Returns: CODE_CONFACK, CODE_CONFNAK or CODE_CONFREJ and input
1818 * packet modified appropriately. If reject_if_disagree is non-zero,
1819 * doesn't return CODE_CONFNAK; returns CODE_CONFREJ if it can't
1820 * return CODE_CONFACK.
1823 lcp_reqci(f
, p
, lenp
, dont_nak
)
1825 u_char
*p
; /* Requested CIs */
1826 int *lenp
; /* Length of requested CIs */
1829 lcp_options
*wo
= &lcp_wantoptions
[f
->unit
];
1830 lcp_options
*go
= &lcp_gotoptions
[f
->unit
];
1831 lcp_options
*ho
= &lcp_hisoptions
[f
->unit
];
1832 lcp_options
*ao
= &lcp_allowoptions
[f
->unit
];
1833 int cilen
, citype
, cichar
; /* Parsed len, type, char value */
1834 u_short cishort
; /* Parsed short value */
1835 u_int32_t cilong
; /* Parse long value */
1837 u_char
*p0
, *nakp
, *rejp
, *prev
;
1841 * Loop through options once to find out if peer is offering
1842 * Multilink, and repair values as needed.
1846 for (len
= *lenp
; len
> 0; len
-= cilen
, p
= prev
+ cilen
) {
1847 if (len
< 2 || p
[1] > len
) {
1849 * RFC 1661 page 40 -- if the option extends beyond the
1850 * packet, then discard the entire packet.
1852 dbglog("discarding LCP Configure-Request due to truncated option");
1858 if (citype
== CI_MRRU
) {
1859 if (ao
->mrru
!= 0) {
1860 if (ao
->mrru
+6 > PPP_MTU
)
1863 ao
->mru
= ao
->mrru
+ 6;
1869 if (ao
->mru
> absmax_mtu
)
1870 ao
->mru
= absmax_mtu
;
1877 * Reset all its options.
1879 BZERO(ho
, sizeof(*ho
));
1882 * Process all its options.
1884 for (len
= *lenp
; len
> 0; len
-= cilen
, p
= prev
+ cilen
) {
1885 newret
= CODE_CONFACK
; /* Assume success */
1891 switch (citype
) { /* Check CI type */
1894 newret
= CODE_CONFREJ
;
1898 if (cilen
!= CILEN_SHORT
) { /* Check CI length */
1899 newret
= CODE_CONFNAK
;
1902 /* extract the MRU from the option */
1903 GETSHORT(cishort
, p
);
1906 * If the offered MRU is less than our desired MTU, we
1907 * should nak. This is especially helpful if we're
1908 * doing demand-dial, since those queued up packets
1909 * might be discarded otherwise.
1911 if (cishort
< ao
->mru
) {
1912 newret
= CODE_CONFNAK
;
1918 * If we're going to send a nak with something less than
1919 * or equal to the default PPP MTU, then just reject instead.
1921 if (newret
== CODE_CONFNAK
&& cishort
<= PPP_MTU
)
1922 newret
= CODE_CONFREJ
;
1924 if (newret
== CODE_CONFNAK
) {
1925 PUTCHAR(CI_MRU
, nakp
);
1926 PUTCHAR(CILEN_SHORT
, nakp
);
1927 PUTSHORT(cishort
, nakp
); /* Give it a hint */
1930 ho
->neg_mru
= 1; /* Remember that it sent MRU */
1931 ho
->mru
= cishort
; /* And remember value */
1935 if (!ao
->neg_asyncmap
) {
1936 newret
= CODE_CONFREJ
;
1940 if (cilen
!= CILEN_LONG
) {
1941 newret
= CODE_CONFNAK
;
1947 * Asyncmap must have set at least the bits
1948 * which are set in lcp_allowoptions[unit].asyncmap.
1950 if ((ao
->asyncmap
& ~cilong
) != 0)
1951 newret
= CODE_CONFNAK
;
1955 * Workaround for common broken Microsoft software -- if
1956 * the peer is sending us a nonzero ACCM, then it *needs*
1957 * us to send the same to it. Adjust our Configure-
1958 * Request message and restart LCP.
1960 if (do_msft_workaround
&& (cilong
& ~wo
->asyncmap
)) {
1961 dbglog("adjusted requested asyncmap from %X to %X",
1962 wo
->asyncmap
, wo
->asyncmap
| cilong
);
1963 do_msft_workaround
= 0;
1964 wo
->neg_asyncmap
= 1;
1965 wo
->asyncmap
|= cilong
;
1966 f
->flags
&= ~OPT_SILENT
;
1967 info("possibly broken peer detected; restarting LCP");
1973 if (newret
== CODE_CONFNAK
) {
1974 PUTCHAR(CI_ASYNCMAP
, nakp
);
1975 PUTCHAR(CILEN_LONG
, nakp
);
1976 PUTLONG(ao
->asyncmap
| cilong
, nakp
);
1978 ho
->neg_asyncmap
= 1;
1979 ho
->asyncmap
= cilong
;
1983 if (!(ao
->neg_upap
|| ao
->neg_chap
|| ao
->neg_mschap
||
1984 ao
->neg_mschapv2
)) {
1985 rejected_peers_auth
= 1;
1986 if (cilen
>= CILEN_SHORT
) {
1987 GETSHORT(rejected_auth_proto
, p
);
1989 rejected_auth_proto
= 0;
1992 * Reject the option if we're not willing to authenticate.
1994 newret
= CODE_CONFREJ
;
1997 rejected_peers_auth
= 0;
1998 naked_peers_auth
= 0;
2000 if (cilen
>= CILEN_SHORT
) {
2001 /* Extract the authentication protocol from the option */
2002 GETSHORT(cishort
, p
);
2004 if (ho
->neg_upap
|| ho
->neg_chap
|| ho
->neg_mschap
||
2006 dbglog("Rejecting extra authentication protocol option");
2007 newret
= CODE_CONFREJ
;
2012 * Authtype must be PAP or CHAP.
2014 * Note: if both ao->neg_upap and ao->neg_*chap* are
2015 * set, and the peer sends a Configure-Request with
2016 * two authenticate-protocol requests, one for CHAP
2017 * and one for UPAP, then we will reject the second
2018 * request. Whether we end up doing CHAP or UPAP
2019 * depends then on the ordering of the CIs in the
2020 * peer's Configure-Request.
2022 * We're supposed to list all of the protocols we can
2023 * possibly use in the returned Configure-Nak. This
2024 * part of RFC 1661 (section 5.3) is in conflict with
2025 * the section that says the options shouldn't be
2026 * reordered, so it's often ignored.
2029 if (cishort
== PPP_PAP
) {
2031 if (cilen
!= CILEN_SHORT
)
2032 goto try_pap_anyway
;
2036 } else if (cishort
== PPP_CHAP
) {
2037 /* Test >= here to allow for broken peers. */
2038 if (cilen
>= CILEN_CHAP
&&
2039 (ao
->neg_chap
|| ao
->neg_mschap
|| ao
->neg_mschapv2
)) {
2041 if (cichar
== CHAP_DIGEST_MD5
&& ao
->neg_chap
)
2043 else if (cichar
== CHAP_MICROSOFT
&& ao
->neg_mschap
)
2045 else if (cichar
== CHAP_MICROSOFT_V2
&&
2048 if (ho
->neg_chap
|| ho
->neg_mschap
||
2050 ho
->chap_mdtype
= cichar
; /* save md type */
2058 * We don't recognize the protocol they're asking for.
2059 * Nak it with something we're willing to do.
2060 * (At this point we know ao->neg_upap || ao->neg_chap.)
2062 PUTCHAR(CI_AUTHTYPE
, nakp
);
2063 if (ao
->neg_chap
|| ao
->neg_mschap
|| ao
->neg_mschapv2
) {
2064 PUTCHAR(CILEN_CHAP
, nakp
);
2065 PUTSHORT(PPP_CHAP
, nakp
);
2066 PUTCHAR(ao
->chap_mdtype
, nakp
);
2067 naked_auth_proto
= PPP_CHAP
;
2070 PUTCHAR(CILEN_SHORT
, nakp
);
2071 PUTSHORT(PPP_PAP
, nakp
);
2072 naked_auth_proto
= PPP_PAP
;
2074 naked_peers_auth
= 1;
2075 naked_auth_orig
= cishort
;
2076 newret
= CODE_CONFNAK
;
2081 newret
= CODE_CONFREJ
;
2085 if (cilen
!= CILEN_LQR
) {
2086 newret
= CODE_CONFNAK
;
2087 cilong
= ao
->lqr_period
;
2090 GETSHORT(cishort
, p
);
2093 /* Check the LQM protocol */
2094 if (cishort
!= PPP_LQR
) {
2095 newret
= CODE_CONFNAK
;
2098 /* Check the reporting period; we can't both send zero */
2099 if ((cilong
== 0 && go
->lqr_period
== 0) ||
2100 cilong
< ao
->lqr_period
) {
2101 newret
= CODE_CONFNAK
;
2102 if ((cilong
= ao
->lqr_period
) == 0)
2107 if (newret
== CODE_CONFNAK
) {
2108 PUTCHAR(CI_QUALITY
, nakp
);
2109 PUTCHAR(CILEN_LQR
, nakp
);
2110 PUTSHORT(PPP_LQR
, nakp
);
2111 PUTLONG(cilong
, nakp
);
2115 ho
->lqr_period
= cilong
;
2118 case CI_MAGICNUMBER
:
2119 if (!(ao
->neg_magicnumber
|| go
->neg_magicnumber
)) {
2120 newret
= CODE_CONFREJ
;
2124 ho
->neg_magicnumber
= 1;
2125 if (cilen
< CILEN_LONG
) {
2127 * If we send Magic-Number, then we must not reject it
2128 * when the peer sends it to us, even if its version
2129 * looks odd to us. Ack if the cilent is wrong in this
2130 * case. If we're not sending Magic-Number, then we don't
2131 * much care what its value is anyway.
2137 ho
->magicnumber
= cilong
;
2138 if (cilen
> CILEN_LONG
)
2142 * It must have a different magic number. Make sure we
2143 * give it a good one to use.
2145 while (go
->neg_magicnumber
&& cilong
== go
->magicnumber
) {
2146 newret
= CODE_CONFNAK
;
2150 if (newret
== CODE_CONFNAK
) {
2151 PUTCHAR(CI_MAGICNUMBER
, nakp
);
2152 PUTCHAR(CILEN_LONG
, nakp
);
2153 PUTLONG(cilong
, nakp
);
2155 * We don't need to bump the numloops counter here
2156 * since it's already done upon reception of a nak.
2161 case CI_PCOMPRESSION
:
2162 if (!ao
->neg_pcompression
) {
2163 newret
= CODE_CONFREJ
;
2166 if (cilen
!= CILEN_VOID
) {
2167 newret
= CODE_CONFNAK
;
2168 PUTCHAR(CI_PCOMPRESSION
, nakp
);
2169 PUTCHAR(CILEN_VOID
, nakp
);
2171 ho
->neg_pcompression
= 1;
2174 case CI_ACCOMPRESSION
:
2175 if (!ao
->neg_accompression
) {
2176 newret
= CODE_CONFREJ
;
2179 if (cilen
!= CILEN_VOID
) {
2180 newret
= CODE_CONFNAK
;
2181 PUTCHAR(CI_ACCOMPRESSION
, nakp
);
2182 PUTCHAR(CILEN_VOID
, nakp
);
2184 ho
->neg_accompression
= 1;
2189 newret
= CODE_CONFREJ
;
2193 if (cilen
!= CILEN_CHAR
) {
2194 newret
= CODE_CONFNAK
;
2195 cichar
= ao
->fcs_type
;
2199 /* If it has bits we don't like, tell it to stop. */
2200 if (cichar
& ~ao
->fcs_type
) {
2201 if ((cichar
&= ao
->fcs_type
) == 0) {
2202 newret
= CODE_CONFREJ
;
2205 newret
= CODE_CONFNAK
;
2208 if (newret
== CODE_CONFNAK
) {
2209 PUTCHAR(CI_FCSALTERN
, nakp
);
2210 PUTCHAR(CILEN_CHAR
, nakp
);
2211 PUTCHAR(cichar
, nakp
);
2214 ho
->fcs_type
= cichar
;
2218 if (!ao
->neg_mrru
|| !multilink
) {
2219 newret
= CODE_CONFREJ
;
2222 if (cilen
!= CILEN_SHORT
) {
2223 newret
= CODE_CONFNAK
;
2226 GETSHORT(cishort
, p
);
2227 if (cishort
< ao
->mrru
) {
2228 newret
= CODE_CONFNAK
;
2233 if (cishort
< PPP_MINMTU
) {
2234 newret
= CODE_CONFNAK
;
2235 cishort
= PPP_MINMTU
;
2238 if (newret
== CODE_CONFNAK
) {
2239 PUTCHAR(CI_MRRU
, nakp
);
2240 PUTCHAR(CILEN_SHORT
, nakp
);
2241 PUTSHORT(cishort
, nakp
);
2249 if (!ao
->neg_ssnhf
|| !multilink
) {
2250 newret
= CODE_CONFREJ
;
2253 if (cilen
!= CILEN_VOID
) {
2254 newret
= CODE_CONFNAK
;
2255 PUTCHAR(CI_SSNHF
, nakp
);
2256 PUTCHAR(CILEN_VOID
, nakp
);
2262 if (!ao
->neg_endpoint
) {
2263 newret
= CODE_CONFREJ
;
2266 if (cilen
< CILEN_CHAR
|| cilen
> CILEN_CHAR
+ MAX_ENDP_LEN
) {
2269 newret
= CODE_CONFNAK
;
2270 PUTCHAR(CI_EPDISC
, nakp
);
2271 PUTCHAR(CILEN_CHAR
+ ao
->endpoint
.length
, nakp
);
2272 PUTCHAR(ao
->endpoint
.class, nakp
);
2273 for (i
= 0; i
< ao
->endpoint
.length
; i
++)
2274 PUTCHAR(ao
->endpoint
.value
[i
], nakp
);
2278 ho
->neg_endpoint
= 1;
2279 ho
->endpoint
.class = cichar
;
2280 ho
->endpoint
.length
= cilen
- 3;
2281 BCOPY(p
, ho
->endpoint
.value
, cilen
- 3);
2286 if (ao
->pppmux
== 0 || cilen
!= CILEN_VOID
) {
2287 newret
= CODE_CONFREJ
;
2290 /* remember its option */
2291 ho
->pppmux
= ao
->pppmux
;
2296 dbglog("LCP: rejecting unknown option %d", citype
);
2297 newret
= CODE_CONFREJ
;
2301 /* Cope with confused peers. */
2306 * If this is an Ack'able CI, but we're sending back a Nak,
2307 * don't include this CI.
2309 if (newret
== CODE_CONFACK
&& ret
!= CODE_CONFACK
)
2312 if (newret
== CODE_CONFNAK
) {
2314 * Continue naking the Magic Number option until the cows come
2315 * home -- rejecting it is wrong.
2317 if (dont_nak
&& citype
!= CI_MAGICNUMBER
) {
2318 newret
= CODE_CONFREJ
;
2320 /* Ignore subsequent Nak'able things if rejecting. */
2321 if (ret
== CODE_CONFREJ
)
2327 if (newret
== CODE_CONFREJ
) {
2330 BCOPY(prev
, rejp
, cilen
);
2336 * If the peer hasn't negotiated its MRU, and we'd like an MTU
2337 * that's larger than the default, try sending an unsolicited
2338 * Nak for what we want.
2340 if (ret
!= CODE_CONFREJ
&& !ho
->neg_mru
&& ao
->mru
> PPP_MTU
&&
2341 !dont_nak
&& unsolicit_mru
) {
2342 unsolicit_mru
= 0; /* don't ask again */
2344 PUTCHAR(CI_MRU
, nakp
);
2345 PUTCHAR(CILEN_SHORT
, nakp
);
2346 PUTSHORT(ao
->mru
, nakp
);
2355 * Copy the Nak'd options from the nak_buffer to the caller's buffer.
2357 *lenp
= nakp
- nak_buffer
;
2358 BCOPY(nak_buffer
, p0
, *lenp
);
2363 /* We're about to send Configure-Reject; send Identification */
2364 if (!noident
&& sentident
< 3) {
2365 LcpSendIdentification(f
);
2371 LCPDEBUG(("lcp_reqci: returning %s.", code_name(ret
, 1)));
2372 return (ret
); /* Return final code */
2377 * lcp_up - LCP has come UP.
2383 lcp_options
*wo
= &lcp_wantoptions
[f
->unit
];
2384 lcp_options
*ho
= &lcp_hisoptions
[f
->unit
];
2385 lcp_options
*go
= &lcp_gotoptions
[f
->unit
];
2386 lcp_options
*ao
= &lcp_allowoptions
[f
->unit
];
2389 if (!go
->neg_magicnumber
)
2390 go
->magicnumber
= 0;
2391 if (!ho
->neg_magicnumber
)
2392 ho
->magicnumber
= 0;
2395 * Set our MTU to the smaller of the MTU we wanted and
2396 * the MRU our peer wanted. If we negotiated an MRU,
2397 * set our MRU to the larger of value we wanted and
2398 * the value we got in the negotiation.
2400 if (ao
->mru
!= 0 && ho
->mru
> ao
->mru
)
2402 mtu
= (ho
->neg_mru
? ho
->mru
: PPP_MRU
);
2403 if (mtu
> absmax_mtu
)
2405 ppp_send_config(f
->unit
, mtu
,
2406 (ho
->neg_asyncmap
? ho
->asyncmap
: 0xffffffff),
2407 ho
->neg_pcompression
, ho
->neg_accompression
);
2408 fsm_setpeermru(f
->unit
, mtu
);
2409 mru
= (go
->neg_mru
? MAX(wo
->mru
, go
->mru
): PPP_MRU
);
2410 if (mru
> absmax_mru
)
2412 ppp_recv_config(f
->unit
, mru
,
2413 (lax_recv
? 0: go
->neg_asyncmap
? go
->asyncmap
: 0xffffffff),
2414 go
->neg_pcompression
, go
->neg_accompression
);
2415 #ifdef NEGOTIATE_FCS
2416 ppp_send_fcs(f
->unit
, ho
->neg_fcs
? ho
->fcs_type
: FCSALT_16
);
2417 ppp_recv_fcs(f
->unit
, go
->neg_fcs
? go
->fcs_type
: FCSALT_16
);
2420 ppp_send_muxoption(f
->unit
, ho
->pppmux
);
2421 ppp_recv_muxoption(f
->unit
, go
->pppmux
);
2424 lcp_echo_lowerup(f
->unit
); /* Enable echo messages */
2426 /* LCP is Up; send Identification */
2428 LcpSendIdentification(f
);
2432 link_established(f
->unit
);
2437 * lcp_down - LCP has gone DOWN.
2439 * Alert other protocols.
2446 lcp_options
*go
= &lcp_gotoptions
[f
->unit
];
2448 lcp_echo_lowerdown(f
->unit
);
2452 mtu
= PPP_MTU
> absmax_mtu
? absmax_mtu
: PPP_MTU
;
2453 ppp_send_config(f
->unit
, mtu
, 0xffffffff, 0, 0);
2454 ppp_recv_config(f
->unit
, (PPP_MRU
> absmax_mru
? absmax_mru
: PPP_MRU
),
2455 (go
->neg_asyncmap
? go
->asyncmap
: 0xffffffff),
2456 go
->neg_pcompression
, go
->neg_accompression
);
2457 #ifdef NEGOTIATE_FCS
2458 ppp_send_fcs(f
->unit
, FCSALT_16
);
2459 ppp_recv_fcs(f
->unit
, FCSALT_16
);
2461 fsm_setpeermru(f
->unit
, mtu
);
2466 * lcp_starting - LCP needs the lower layer up.
2472 link_required(f
->unit
);
2477 * lcp_finished - LCP has finished with the lower layer.
2483 link_terminated(f
->unit
);
2488 * lcp_printpkt - print the contents of an LCP packet.
2492 lcp_printpkt(p
, plen
, printer
, arg
)
2495 void (*printer
) __P((void *, const char *, ...));
2498 int code
, id
, len
, olen
, i
;
2499 u_char
*pstart
, *optend
, cichar
;
2503 if (plen
< HEADERLEN
)
2509 if (len
< HEADERLEN
|| len
> plen
)
2512 printer(arg
, " %s id=0x%x", code_name(code
,1), id
);
2519 /* print option list */
2524 if (olen
< 2 || olen
> len
) {
2532 if (olen
>= CILEN_SHORT
) {
2534 GETSHORT(cishort
, p
);
2535 printer(arg
, "mru %d", cishort
);
2539 if (olen
>= CILEN_LONG
) {
2542 printer(arg
, "asyncmap 0x%x", cilong
);
2546 if (olen
>= CILEN_SHORT
) {
2548 printer(arg
, "auth ");
2549 GETSHORT(cishort
, p
);
2552 printer(arg
, "pap");
2555 printer(arg
, "chap");
2558 case CHAP_DIGEST_MD5
:
2559 printer(arg
, " MD5");
2562 case CHAP_MICROSOFT
:
2563 printer(arg
, " m$oft");
2566 case CHAP_MICROSOFT_V2
:
2567 printer(arg
, " m$oft-v2");
2575 printer(arg
, "eap");
2579 printer(arg
, "spap");
2582 printer(arg
, "old-spap");
2585 printer(arg
, "0x%x", cishort
);
2590 if (olen
>= CILEN_SHORT
) {
2592 printer(arg
, "quality ");
2593 GETSHORT(cishort
, p
);
2596 printer(arg
, "lqr");
2599 printer(arg
, "0x%x", cishort
);
2604 if (olen
>= CILEN_CHAR
) {
2606 printer(arg
, "callback ");
2609 *callback_strings
[(int)cichar
] != '\0') {
2610 printer(arg
, "%s", callback_strings
[(int)cichar
]);
2612 printer(arg
, "0x%x", cichar
);
2616 case CI_MAGICNUMBER
:
2617 if (olen
>= CILEN_LONG
) {
2620 printer(arg
, "magic 0x%x", cilong
);
2623 case CI_PCOMPRESSION
:
2624 if (olen
>= CILEN_VOID
) {
2626 printer(arg
, "pcomp");
2629 case CI_ACCOMPRESSION
:
2630 if (olen
>= CILEN_VOID
) {
2632 printer(arg
, "accomp");
2636 if (olen
>= CILEN_CHAR
) {
2642 for (cpp
= fcsalt_strings
; *cpp
!= NULL
; cpp
++)
2643 if (cichar
& 1<<(cpp
-fcsalt_strings
)) {
2644 cichar
&= ~(1<<(cpp
-fcsalt_strings
));
2645 printer(arg
, (needcomma
? ",%s" : "fcs %s"), *cpp
);
2648 if (cichar
!= 0 || !needcomma
)
2649 printer(arg
, (needcomma
? ",0x%x" : "fcs 0x%x"),
2654 if (olen
>= CILEN_SHORT
) {
2657 printer(arg
, "numb win %d", cichar
);
2659 printer(arg
, " addr %d", cichar
);
2663 if (olen
>= CILEN_SHORT
) {
2665 GETSHORT(cishort
, p
);
2666 printer(arg
, "mrru %d", cishort
);
2670 if (olen
>= CILEN_VOID
) {
2672 printer(arg
, "ssnhf");
2676 if (olen
>= CILEN_CHAR
) {
2679 GETCHAR(epd
.class, p
);
2680 epd
.length
= olen
- CILEN_CHAR
;
2681 if (epd
.length
> MAX_ENDP_LEN
)
2682 epd
.length
= MAX_ENDP_LEN
;
2683 if (epd
.length
> 0) {
2684 BCOPY(p
, epd
.value
, epd
.length
);
2687 printer(arg
, "endpoint [%s]", epdisc_to_str(&epd
));
2691 if (olen
>= CILEN_SHORT
) {
2693 GETSHORT(cishort
, p
);
2694 printer(arg
, "linkdisc %d", cishort
);
2698 if (olen
>= CILEN_CHAR
) {
2701 printer(arg
, "cobs 0x%x", cichar
);
2705 if (olen
>= CILEN_CHAR
) {
2707 printer(arg
, "pfx");
2711 if (olen
>= CILEN_SHORT
) {
2713 printer(arg
, "mphdr ");
2717 printer(arg
, "long");
2720 printer(arg
, "short");
2723 printer(arg
, "0x%x", cichar
);
2727 printer(arg
, " #cl %d", cichar
);
2731 if (olen
>= CILEN_LONG
) {
2734 printer(arg
, "i18n charset 0x%x", cilong
);
2735 if (olen
> CILEN_LONG
) {
2736 printer(arg
, " lang ");
2737 print_string((char *)p
, olen
-CILEN_LONG
, printer
, arg
);
2743 if (olen
>= CILEN_VOID
) {
2745 printer(arg
, "sdl");
2749 if (olen
>= CILEN_VOID
) {
2751 printer(arg
, "mux");
2755 while (p
< optend
) {
2757 printer(arg
, " %.2x", code
);
2765 if (len
> 0 && *p
>= ' ' && *p
< 0x7f) {
2767 print_string((char *)p
, len
, printer
, arg
);
2778 printer(arg
, " magic=0x%x", cilong
);
2786 printer(arg
, " magic=0x%x", cilong
);
2790 if (len
> 0 && (len
> 1 || *p
!= '\0')) {
2792 print_string((char *)p
, len
, printer
, arg
);
2798 case CODE_TIMEREMAIN
:
2801 printer(arg
, " magic=0x%x", cilong
);
2807 printer(arg
, " seconds=%d", cilong
);
2811 if (len
> 0 && (len
> 1 || *p
!= '\0')) {
2813 print_string((char *)p
, len
, printer
, arg
);
2820 /* print the rest of the bytes in the packet */
2821 for (i
= 0; i
< len
&& i
< 32; ++i
) {
2823 printer(arg
, " %.2x", code
);
2826 printer(arg
, " ...");
2834 * Time to shut down the link because there is nothing out there.
2841 char *close_message
;
2843 if (f
->state
== OPENED
) {
2844 if (lcp_echo_badreplies
> LCP_ECHO_MAX_BADREPLIES
) {
2845 info("Received %d bad echo-replies", lcp_echo_badreplies
);
2846 close_message
= "Receiving malformed Echo-Replies";
2847 } else if (lcp_echo_accm_test
) {
2849 * If this is an asynchronous line and we've missed all of
2850 * the initial echo requests, then this is probably due to
2853 notice("Peer not responding to initial Echo-Requests.");
2854 notice("Negotiated asyncmap may be incorrect for this link.");
2855 close_message
= "Peer not responding; perhaps bad asyncmap";
2857 info("No response to %d echo-requests", lcp_echos_pending
);
2858 notice("Serial link appears to be disconnected.");
2859 close_message
= "Peer not responding";
2862 lcp_close(f
->unit
, close_message
);
2863 status
= EXIT_PEER_DEAD
;
2868 * Timer expired for the LCP echo requests from this process.
2875 if (f
->state
!= OPENED
|| lcp_echo_interval
== 0)
2878 LcpSendEchoRequest (f
);
2881 * Start the timer for the next interval.
2883 if (lcp_echo_timer_running
)
2884 warn("assertion lcp_echo_timer_running==0 failed");
2885 TIMEOUT (LcpEchoTimeout
, f
, lcp_echo_interval
);
2886 lcp_echo_timer_running
= 1;
2890 * LcpEchoTimeout - Timer expired on the LCP echo
2894 LcpEchoTimeout (arg
)
2897 if (lcp_echo_timer_running
!= 0) {
2898 lcp_echo_timer_running
= 0;
2899 LcpEchoCheck ((fsm
*) arg
);
2904 * LcpEchoReply - LCP has received a reply to the echo
2908 lcp_received_echo_reply (f
, id
, inp
, len
)
2916 /* Check the magic number - don't count replies from ourselves. */
2918 dbglog("lcp: received short Echo-Reply, length %d", len
);
2921 GETLONG(magic
, inp
);
2922 if (lcp_gotoptions
[f
->unit
].neg_magicnumber
&&
2923 magic
== lcp_gotoptions
[f
->unit
].magicnumber
) {
2924 warn("appear to have received our own echo-reply!");
2928 /* Reset the number of outstanding echo frames */
2929 lcp_echos_pending
= 0;
2931 if (lcp_echo_accm_test
) {
2932 dbglog("lcp: validated asyncmap setting");
2933 lcp_echo_accm_test
= 0;
2934 if (lcp_echo_fails
== 0)
2935 lcp_echo_interval
= 0;
2941 * LcpSendEchoRequest - Send an echo request frame to the peer
2945 LcpSendEchoRequest (f
)
2948 u_int32_t lcp_magic
;
2949 u_char pkt
[4+256], *pktp
;
2953 * Detect the failure of the peer at this point. If we're not currently
2954 * performing the ACCM test, then we just check for the user's echo-failure
2955 * point. If we are performing the ACCM test, then use ACCM_TEST_FAILS if
2956 * the user hasn't specified a different failure point.
2960 i
= ACCM_TEST_FAILS
;
2961 if ((!lcp_echo_accm_test
&& lcp_echo_fails
!= 0 &&
2962 lcp_echos_pending
>= lcp_echo_fails
) ||
2963 (lcp_echo_accm_test
&& lcp_echos_pending
>= i
)) {
2965 lcp_echos_pending
= 0;
2966 lcp_echo_badreplies
= 0;
2970 * Make and send the echo request frame.
2972 if (f
->state
== OPENED
) {
2973 lcp_magic
= lcp_gotoptions
[f
->unit
].magicnumber
;
2975 PUTLONG(lcp_magic
, pktp
);
2976 /* Send some test packets so we can fail the link early. */
2977 if (lcp_echo_accm_test
) {
2978 switch (use_accm_test
) {
2980 /* Only the characters covered by negotiated ACCM */
2981 for (i
= 0; i
< 32; i
++)
2985 /* All characters */
2986 for (i
= 0; i
< 256; i
++)
2991 fsm_sdata(f
, CODE_ECHOREQ
, lcp_echo_number
++ & 0xFF, pkt
, pktp
- pkt
);
2992 ++lcp_echos_pending
;
2997 * lcp_echo_lowerup - Start the timer for the LCP frame
3001 lcp_echo_lowerup (unit
)
3004 fsm
*f
= &lcp_fsm
[unit
];
3006 /* Clear the parameters for generating echo frames */
3007 lcp_echos_pending
= 0;
3008 lcp_echo_number
= 0;
3009 lcp_echo_timer_running
= 0;
3010 lcp_echo_accm_test
= !sync_serial
&& use_accm_test
;
3012 /* If a timeout interval is specified then start the timer */
3017 * lcp_echo_lowerdown - Stop the timer for the LCP frame
3021 lcp_echo_lowerdown (unit
)
3024 fsm
*f
= &lcp_fsm
[unit
];
3026 if (lcp_echo_timer_running
!= 0) {
3027 UNTIMEOUT (LcpEchoTimeout
, f
);
3028 lcp_echo_timer_running
= 0;
3033 * LcpSendIdentification - Send LCP Identification string to peer.
3037 LcpSendIdentification (f
)
3040 u_int32_t lcp_magic
;
3041 u_char pkt
[4 + sizeof(identstr
)], *pktp
;
3045 * Make and send the Identification frame.
3047 if (f
->state
== OPENED
)
3048 lcp_magic
= lcp_gotoptions
[f
->unit
].magicnumber
;
3053 PUTLONG(lcp_magic
, pktp
);
3054 idlen
= strlen(identstr
);
3055 BCOPY(identstr
, pktp
, idlen
);
3056 INCPTR(idlen
, pktp
);
3057 fsm_sdata(f
, CODE_IDENT
, ++f
->id
, pkt
, pktp
- pkt
);
3062 lcp_received_identification (f
, id
, inp
, len
)
3070 /* Check the magic number - don't count replies from ourselves. */
3072 dbglog("%s: received short Identification; %d < 4", len
);
3075 GETLONG(magic
, inp
);
3077 if (lcp_gotoptions
[f
->unit
].neg_magicnumber
&& f
->state
== OPENED
&&
3078 magic
== lcp_gotoptions
[f
->unit
].magicnumber
) {
3079 warn("appear to have received our own Identification!");
3082 if (len
> 0 && (len
> 1 || *inp
!= '\0'))
3083 notice("Peer Identification: %0.*v", len
, inp
);
3087 * Send a Time-Remaining LCP packet. We don't include a message.
3090 LcpSendTimeRemaining(f
, time_remaining
)
3092 u_int32_t time_remaining
;
3094 u_int32_t lcp_magic
;
3098 if (f
->state
!= OPENED
)
3101 lcp_magic
= lcp_gotoptions
[f
->unit
].magicnumber
;
3103 PUTLONG(lcp_magic
, pktp
);
3104 PUTLONG(time_remaining
, pktp
);
3105 fsm_sdata(f
, CODE_TIMEREMAIN
, ++f
->id
, pkt
, pktp
- pkt
);
3110 lcp_received_timeremain(f
, id
, inp
, len
)
3117 u_int32_t time_remaining
;
3119 /* Check the magic number - don't count replies from ourselves. */
3121 dbglog("%s: received short Time-Remain; %d < 8", len
);
3124 GETLONG(magic
, inp
);
3125 if (lcp_gotoptions
[f
->unit
].neg_magicnumber
&& f
->state
== OPENED
&&
3126 magic
== lcp_gotoptions
[f
->unit
].magicnumber
) {
3127 warn("appear to have received our own Time-Remain!");
3130 GETLONG(time_remaining
, inp
);
3132 notice("%d seconds remain: \"%.*s\"", time_remaining
,
3135 notice("Time Remaining: %d seconds", time_remaining
);
3140 * lcp_timeremaining - timeout handler which sends LCP Time-Remaining
3144 lcp_timeremaining(arg
)
3147 struct lcp_timer
*lt
= (struct lcp_timer
*)arg
;
3148 u_int32_t time_remaining
;
3152 time_remaining
= lt
->tr
;
3153 LcpSendTimeRemaining(&lcp_fsm
[unit
], time_remaining
);
3158 * lcp_settimeremaining - set a timeout to send an LCP Time-Remaining
3159 * packet. The first argument, connecttime, is the time remaining
3160 * at the time this function is called. The second argument is the
3161 * desired time remaining when the packet should be sent out.
3164 lcp_settimeremaining(unit
, connecttime
, time_remaining
)
3166 u_int32_t connecttime
;
3167 u_int32_t time_remaining
;
3169 struct lcp_timer
*lt
;
3171 if (connecttime
== time_remaining
) {
3172 LcpSendTimeRemaining(&lcp_fsm
[unit
], time_remaining
);
3174 lt
= (struct lcp_timer
*)malloc(sizeof (struct lcp_timer
));
3176 lt
->tr
= time_remaining
;
3177 TIMEOUT(lcp_timeremaining
, (void *)lt
, connecttime
- time_remaining
);