xref: /netbsd/external/bsd/ppp/dist/pppd/lcp.c (revision 3dce80e5)
1 /*	$NetBSD: lcp.c,v 1.5 2021/01/09 16:39:28 christos Exp $	*/
2 
3 /*
4  * lcp.c - PPP Link Control Protocol.
5  *
6  * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. The name "Carnegie Mellon University" must not be used to
21  *    endorse or promote products derived from this software without
22  *    prior written permission. For permission or any legal
23  *    details, please contact
24  *      Office of Technology Transfer
25  *      Carnegie Mellon University
26  *      5000 Forbes Avenue
27  *      Pittsburgh, PA  15213-3890
28  *      (412) 268-4387, fax: (412) 268-7395
29  *      tech-transfer@andrew.cmu.edu
30  *
31  * 4. Redistributions of any form whatsoever must retain the following
32  *    acknowledgment:
33  *    "This product includes software developed by Computing Services
34  *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
35  *
36  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
37  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
38  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
39  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
40  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
41  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
42  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
43  */
44 
45 #include <sys/cdefs.h>
46 __RCSID("$NetBSD: lcp.c,v 1.5 2021/01/09 16:39:28 christos Exp $");
47 
48 /*
49  * TODO:
50  */
51 
52 #include <stdio.h>
53 #include <string.h>
54 #include <stdlib.h>
55 
56 #include "pppd.h"
57 #include "fsm.h"
58 #include "lcp.h"
59 #include "chap-new.h"
60 #include "magic.h"
61 
62 
63 /*
64  * When the link comes up we want to be able to wait for a short while,
65  * or until seeing some input from the peer, before starting to send
66  * configure-requests.  We do this by delaying the fsm_lowerup call.
67  */
68 /* steal a bit in fsm flags word */
69 #define DELAYED_UP	0x100
70 
71 static void lcp_delayed_up(void *);
72 
73 /*
74  * LCP-related command-line options.
75  */
76 int	lcp_echo_interval = 0; 	/* Interval between LCP echo-requests */
77 int	lcp_echo_fails = 0;	/* Tolerance to unanswered echo-requests */
78 bool	lcp_echo_adaptive = 0;	/* request echo only if the link was idle */
79 bool	lax_recv = 0;		/* accept control chars in asyncmap */
80 bool	noendpoint = 0;		/* don't send/accept endpoint discriminator */
81 
82 static int noopt(char **);
83 
84 #ifdef HAVE_MULTILINK
85 static int setendpoint(char **);
86 static void printendpoint(option_t *, void (*)(void *, char *, ...), void *);
87 #endif /* HAVE_MULTILINK */
88 
89 static option_t lcp_option_list[] = {
90     /* LCP options */
91     { "-all", o_special_noarg, (void *)noopt,
92       "Don't request/allow any LCP options" },
93 
94     { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression,
95       "Disable address/control compression",
96       OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },
97     { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression,
98       "Disable address/control compression",
99       OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },
100 
101     { "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
102       "Set asyncmap (for received packets)",
103       OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
104     { "-as", o_uint32, &lcp_wantoptions[0].asyncmap,
105       "Set asyncmap (for received packets)",
106       OPT_ALIAS | OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
107     { "default-asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
108       "Disable asyncmap negotiation",
109       OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR,
110       &lcp_allowoptions[0].neg_asyncmap },
111     { "-am", o_uint32, &lcp_wantoptions[0].asyncmap,
112       "Disable asyncmap negotiation",
113       OPT_ALIAS | OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR,
114       &lcp_allowoptions[0].neg_asyncmap },
115 
116     { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber,
117       "Disable magic number negotiation (looped-back line detection)",
118       OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },
119     { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber,
120       "Disable magic number negotiation (looped-back line detection)",
121       OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },
122 
123     { "mru", o_int, &lcp_wantoptions[0].mru,
124       "Set MRU (maximum received packet size) for negotiation",
125       OPT_PRIO, &lcp_wantoptions[0].neg_mru },
126     { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru,
127       "Disable MRU negotiation (use default 1500)",
128       OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },
129     { "-mru", o_bool, &lcp_wantoptions[0].neg_mru,
130       "Disable MRU negotiation (use default 1500)",
131       OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },
132 
133     { "mtu", o_int, &lcp_allowoptions[0].mru,
134       "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU },
135 
136     { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression,
137       "Disable protocol field compression",
138       OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },
139     { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression,
140       "Disable protocol field compression",
141       OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },
142 
143     { "passive", o_bool, &lcp_wantoptions[0].passive,
144       "Set passive mode", 1 },
145     { "-p", o_bool, &lcp_wantoptions[0].passive,
146       "Set passive mode", OPT_ALIAS | 1 },
147 
148     { "silent", o_bool, &lcp_wantoptions[0].silent,
149       "Set silent mode", 1 },
150 
151     { "lcp-echo-failure", o_int, &lcp_echo_fails,
152       "Set number of consecutive echo failures to indicate link failure",
153       OPT_PRIO },
154     { "lcp-echo-interval", o_int, &lcp_echo_interval,
155       "Set time in seconds between LCP echo requests", OPT_PRIO },
156     { "lcp-echo-adaptive", o_bool, &lcp_echo_adaptive,
157       "Suppress LCP echo requests if traffic was received", 1 },
158     { "lcp-restart", o_int, &lcp_fsm[0].timeouttime,
159       "Set time in seconds between LCP retransmissions", OPT_PRIO },
160     { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits,
161       "Set maximum number of LCP terminate-request transmissions", OPT_PRIO },
162     { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits,
163       "Set maximum number of LCP configure-request transmissions", OPT_PRIO },
164     { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops,
165       "Set limit on number of LCP configure-naks", OPT_PRIO },
166 
167     { "receive-all", o_bool, &lax_recv,
168       "Accept all received control characters", 1 },
169 
170 #ifdef HAVE_MULTILINK
171     { "mrru", o_int, &lcp_wantoptions[0].mrru,
172       "Maximum received packet size for multilink bundle",
173       OPT_PRIO, &lcp_wantoptions[0].neg_mrru },
174 
175     { "mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,
176       "Use short sequence numbers in multilink headers",
177       OPT_PRIO | 1, &lcp_allowoptions[0].neg_ssnhf },
178     { "nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,
179       "Don't use short sequence numbers in multilink headers",
180       OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_ssnhf },
181 
182     { "endpoint", o_special, (void *) setendpoint,
183       "Endpoint discriminator for multilink",
184       OPT_PRIO | OPT_A2PRINTER, (void *) printendpoint },
185 #endif /* HAVE_MULTILINK */
186 
187     { "noendpoint", o_bool, &noendpoint,
188       "Don't send or accept multilink endpoint discriminator", 1 },
189 
190     {NULL}
191 };
192 
193 /* global vars */
194 fsm lcp_fsm[NUM_PPP];			/* LCP fsm structure (global)*/
195 lcp_options lcp_wantoptions[NUM_PPP];	/* Options that we want to request */
196 lcp_options lcp_gotoptions[NUM_PPP];	/* Options that peer ack'd */
197 lcp_options lcp_allowoptions[NUM_PPP];	/* Options we allow peer to request */
198 lcp_options lcp_hisoptions[NUM_PPP];	/* Options that we ack'd */
199 
200 static int lcp_echos_pending = 0;	/* Number of outstanding echo msgs */
201 static int lcp_echo_number   = 0;	/* ID number of next echo frame */
202 static int lcp_echo_timer_running = 0;  /* set if a timer is running */
203 
204 static u_char nak_buffer[PPP_MRU];	/* where we construct a nak packet */
205 
206 /*
207  * Callbacks for fsm code.  (CI = Configuration Information)
208  */
209 static void lcp_resetci(fsm *);	/* Reset our CI */
210 static int  lcp_cilen(fsm *);		/* Return length of our CI */
211 static void lcp_addci(fsm *, u_char *, int *); /* Add our CI to pkt */
212 static int  lcp_ackci(fsm *, u_char *, int); /* Peer ack'd our CI */
213 static int  lcp_nakci(fsm *, u_char *, int, int); /* Peer nak'd our CI */
214 static int  lcp_rejci(fsm *, u_char *, int); /* Peer rej'd our CI */
215 static int  lcp_reqci(fsm *, u_char *, int *, int); /* Rcv peer CI */
216 static void lcp_up(fsm *);		/* We're UP */
217 static void lcp_down(fsm *);		/* We're DOWN */
218 static void lcp_starting(fsm *);	/* We need lower layer up */
219 static void lcp_finished(fsm *);	/* We need lower layer down */
220 static int  lcp_extcode(fsm *, int, int, u_char *, int);
221 static void lcp_rprotrej(fsm *, u_char *, int);
222 
223 /*
224  * routines to send LCP echos to peer
225  */
226 
227 static void lcp_echo_lowerup(int);
228 static void lcp_echo_lowerdown(int);
229 static void LcpEchoTimeout(void *);
230 static void lcp_received_echo_reply(fsm *, int, u_char *, int);
231 static void LcpSendEchoRequest(fsm *);
232 static void LcpLinkFailure(fsm *);
233 static void LcpEchoCheck(fsm *);
234 
235 static fsm_callbacks lcp_callbacks = {	/* LCP callback routines */
236     lcp_resetci,		/* Reset our Configuration Information */
237     lcp_cilen,			/* Length of our Configuration Information */
238     lcp_addci,			/* Add our Configuration Information */
239     lcp_ackci,			/* ACK our Configuration Information */
240     lcp_nakci,			/* NAK our Configuration Information */
241     lcp_rejci,			/* Reject our Configuration Information */
242     lcp_reqci,			/* Request peer's Configuration Information */
243     lcp_up,			/* Called when fsm reaches OPENED state */
244     lcp_down,			/* Called when fsm leaves OPENED state */
245     lcp_starting,		/* Called when we want the lower layer up */
246     lcp_finished,		/* Called when we want the lower layer down */
247     NULL,			/* Called when Protocol-Reject received */
248     NULL,			/* Retransmission is necessary */
249     lcp_extcode,		/* Called to handle LCP-specific codes */
250     "LCP"			/* String name of protocol */
251 };
252 
253 /*
254  * Protocol entry points.
255  * Some of these are called directly.
256  */
257 
258 static void lcp_init(int);
259 static void lcp_input(int, u_char *, int);
260 static void lcp_protrej(int);
261 static int  lcp_printpkt(u_char *, int, void (*)(void *, char *, ...), void *);
262 
263 struct protent lcp_protent = {
264     PPP_LCP,
265     lcp_init,
266     lcp_input,
267     lcp_protrej,
268     lcp_lowerup,
269     lcp_lowerdown,
270     lcp_open,
271     lcp_close,
272     lcp_printpkt,
273     NULL,
274     1,
275     "LCP",
276     NULL,
277     lcp_option_list,
278     NULL,
279     NULL,
280     NULL
281 };
282 
283 int lcp_loopbackfail = DEFLOOPBACKFAIL;
284 
285 /*
286  * Length of each type of configuration option (in octets)
287  */
288 #define CILEN_VOID	2
289 #define CILEN_CHAR	3
290 #define CILEN_SHORT	4	/* CILEN_VOID + 2 */
291 #define CILEN_CHAP	5	/* CILEN_VOID + 2 + 1 */
292 #define CILEN_LONG	6	/* CILEN_VOID + 4 */
293 #define CILEN_LQR	8	/* CILEN_VOID + 2 + 4 */
294 #define CILEN_CBCP	3
295 
296 #define CODENAME(x)	((x) == CONFACK ? "ACK" : \
297 			 (x) == CONFNAK ? "NAK" : "REJ")
298 
299 /*
300  * noopt - Disable all options (why?).
301  */
302 static int
noopt(char ** argv)303 noopt(char **argv)
304 {
305     BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options));
306     BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options));
307 
308     return (1);
309 }
310 
311 #ifdef HAVE_MULTILINK
312 static int
setendpoint(char ** argv)313 setendpoint(char **argv)
314 {
315     if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) {
316 	lcp_wantoptions[0].neg_endpoint = 1;
317 	return 1;
318     }
319     option_error("Can't parse '%s' as an endpoint discriminator", *argv);
320     return 0;
321 }
322 
323 static void
printendpoint(option_t * opt,void (* printer)(void *,char *,...),void * arg)324 printendpoint(option_t *opt, void (*printer)(void *, char *, ...), void *arg)
325 {
326 	printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint));
327 }
328 #endif /* HAVE_MULTILINK */
329 
330 /*
331  * lcp_init - Initialize LCP.
332  */
333 static void
lcp_init(int unit)334 lcp_init(int unit)
335 {
336     fsm *f = &lcp_fsm[unit];
337     lcp_options *wo = &lcp_wantoptions[unit];
338     lcp_options *ao = &lcp_allowoptions[unit];
339 
340     f->unit = unit;
341     f->protocol = PPP_LCP;
342     f->callbacks = &lcp_callbacks;
343 
344     fsm_init(f);
345 
346     BZERO(wo, sizeof(*wo));
347     wo->neg_mru = 1;
348     wo->mru = DEFMRU;
349     wo->neg_asyncmap = 1;
350     wo->neg_magicnumber = 1;
351     wo->neg_pcompression = 1;
352     wo->neg_accompression = 1;
353 
354     BZERO(ao, sizeof(*ao));
355     ao->neg_mru = 1;
356     ao->mru = MAXMRU;
357     ao->neg_asyncmap = 1;
358     ao->neg_chap = 1;
359     ao->chap_mdtype = chap_mdtype_all;
360     ao->neg_upap = 1;
361     ao->neg_eap = 1;
362     ao->neg_magicnumber = 1;
363     ao->neg_pcompression = 1;
364     ao->neg_accompression = 1;
365     ao->neg_endpoint = 1;
366 }
367 
368 
369 /*
370  * lcp_open - LCP is allowed to come up.
371  */
372 void
lcp_open(int unit)373 lcp_open(int unit)
374 {
375     fsm *f = &lcp_fsm[unit];
376     lcp_options *wo = &lcp_wantoptions[unit];
377 
378     f->flags &= ~(OPT_PASSIVE | OPT_SILENT);
379     if (wo->passive)
380 	f->flags |= OPT_PASSIVE;
381     if (wo->silent)
382 	f->flags |= OPT_SILENT;
383     fsm_open(f);
384 }
385 
386 
387 /*
388  * lcp_close - Take LCP down.
389  */
390 void
lcp_close(int unit,char * reason)391 lcp_close(int unit, char *reason)
392 {
393     fsm *f = &lcp_fsm[unit];
394     int oldstate;
395 
396     if (phase != PHASE_DEAD && phase != PHASE_MASTER)
397 	new_phase(PHASE_TERMINATE);
398 
399     if (f->flags & DELAYED_UP) {
400 	untimeout(lcp_delayed_up, f);
401 	f->state = STOPPED;
402     }
403     oldstate = f->state;
404 
405     fsm_close(f, reason);
406     if (oldstate == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP)) {
407 	/*
408 	 * This action is not strictly according to the FSM in RFC1548,
409 	 * but it does mean that the program terminates if you do a
410 	 * lcp_close() when a connection hasn't been established
411 	 * because we are in passive/silent mode or because we have
412 	 * delayed the fsm_lowerup() call and it hasn't happened yet.
413 	 */
414 	f->flags &= ~DELAYED_UP;
415 	lcp_finished(f);
416     }
417 }
418 
419 
420 /*
421  * lcp_lowerup - The lower layer is up.
422  */
423 void
lcp_lowerup(int unit)424 lcp_lowerup(int unit)
425 {
426     lcp_options *wo = &lcp_wantoptions[unit];
427     fsm *f = &lcp_fsm[unit];
428 
429     /*
430      * Don't use A/C or protocol compression on transmission,
431      * but accept A/C and protocol compressed packets
432      * if we are going to ask for A/C and protocol compression.
433      */
434     if (ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0) < 0
435 	|| ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff),
436 			   wo->neg_pcompression, wo->neg_accompression) < 0)
437 	    return;
438     peer_mru[unit] = PPP_MRU;
439 
440     if (listen_time != 0) {
441 	f->flags |= DELAYED_UP;
442 	timeout(lcp_delayed_up, f, 0, listen_time * 1000);
443     } else
444 	fsm_lowerup(f);
445 }
446 
447 
448 /*
449  * lcp_lowerdown - The lower layer is down.
450  */
451 void
lcp_lowerdown(int unit)452 lcp_lowerdown(int unit)
453 {
454     fsm *f = &lcp_fsm[unit];
455 
456     if (f->flags & DELAYED_UP) {
457 	f->flags &= ~DELAYED_UP;
458 	untimeout(lcp_delayed_up, f);
459     } else
460 	fsm_lowerdown(&lcp_fsm[unit]);
461 }
462 
463 
464 /*
465  * lcp_delayed_up - Bring the lower layer up now.
466  */
467 static void
lcp_delayed_up(void * arg)468 lcp_delayed_up(void *arg)
469 {
470     fsm *f = arg;
471 
472     if (f->flags & DELAYED_UP) {
473 	f->flags &= ~DELAYED_UP;
474 	fsm_lowerup(f);
475     }
476 }
477 
478 
479 /*
480  * lcp_input - Input LCP packet.
481  */
482 static void
lcp_input(int unit,u_char * p,int len)483 lcp_input(int unit, u_char *p, int len)
484 {
485     fsm *f = &lcp_fsm[unit];
486 
487     if (f->flags & DELAYED_UP) {
488 	f->flags &= ~DELAYED_UP;
489 	untimeout(lcp_delayed_up, f);
490 	fsm_lowerup(f);
491     }
492     fsm_input(f, p, len);
493 }
494 
495 /*
496  * lcp_extcode - Handle a LCP-specific code.
497  */
498 static int
lcp_extcode(fsm * f,int code,int id,u_char * inp,int len)499 lcp_extcode(fsm *f, int code, int id, u_char *inp, int len)
500 {
501     u_char *magp;
502 
503     switch( code ){
504     case PROTREJ:
505 	lcp_rprotrej(f, inp, len);
506 	break;
507 
508     case ECHOREQ:
509 	if (f->state != OPENED)
510 	    break;
511 	magp = inp;
512 	PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
513 	fsm_sdata(f, ECHOREP, id, inp, len);
514 	break;
515 
516     case ECHOREP:
517 	lcp_received_echo_reply(f, id, inp, len);
518 	break;
519 
520     case DISCREQ:
521     case IDENTIF:
522     case TIMEREM:
523 	break;
524 
525     default:
526 	return 0;
527     }
528     return 1;
529 }
530 
531 
532 /*
533  * lcp_rprotrej - Receive an Protocol-Reject.
534  *
535  * Figure out which protocol is rejected and inform it.
536  */
537 static void
lcp_rprotrej(fsm * f,u_char * inp,int len)538 lcp_rprotrej(fsm *f, u_char *inp, int len)
539 {
540     int i;
541     struct protent *protp;
542     u_short prot;
543     const char *pname;
544 
545     if (len < 2) {
546 	LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!"));
547 	return;
548     }
549 
550     GETSHORT(prot, inp);
551 
552     /*
553      * Protocol-Reject packets received in any state other than the LCP
554      * OPENED state SHOULD be silently discarded.
555      */
556     if( f->state != OPENED ){
557 	LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state));
558 	return;
559     }
560 
561     pname = protocol_name(prot);
562 
563     /*
564      * Upcall the proper Protocol-Reject routine.
565      */
566     for (i = 0; (protp = protocols[i]) != NULL; ++i)
567 	if (protp->protocol == prot && protp->enabled_flag) {
568 	    if (pname == NULL)
569 		dbglog("Protocol-Reject for 0x%x received", prot);
570 	    else
571 		dbglog("Protocol-Reject for '%s' (0x%x) received", pname,
572 		       prot);
573 	    (*protp->protrej)(f->unit);
574 	    return;
575 	}
576 
577     if (pname == NULL)
578 	warn("Protocol-Reject for unsupported protocol 0x%x", prot);
579     else
580 	warn("Protocol-Reject for unsupported protocol '%s' (0x%x)", pname,
581 	     prot);
582 }
583 
584 
585 /*
586  * lcp_protrej - A Protocol-Reject was received.
587  */
588 /*ARGSUSED*/
589 static void
lcp_protrej(int unit)590 lcp_protrej(int unit)
591 {
592     /*
593      * Can't reject LCP!
594      */
595     error("Received Protocol-Reject for LCP!");
596     fsm_protreject(&lcp_fsm[unit]);
597 }
598 
599 
600 /*
601  * lcp_sprotrej - Send a Protocol-Reject for some protocol.
602  */
603 void
lcp_sprotrej(int unit,u_char * p,int len)604 lcp_sprotrej(int unit, u_char *p, int len)
605 {
606     /*
607      * Send back the protocol and the information field of the
608      * rejected packet.  We only get here if LCP is in the OPENED state.
609      */
610     p += 2;
611     len -= 2;
612 
613     fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,
614 	      p, len);
615 }
616 
617 
618 /*
619  * lcp_resetci - Reset our CI.
620  */
621 static void
lcp_resetci(fsm * f)622 lcp_resetci(fsm *f)
623 {
624     lcp_options *wo = &lcp_wantoptions[f->unit];
625     lcp_options *go = &lcp_gotoptions[f->unit];
626     lcp_options *ao = &lcp_allowoptions[f->unit];
627 
628     wo->magicnumber = magic();
629     wo->numloops = 0;
630     *go = *wo;
631     if (!multilink) {
632 	go->neg_mrru = 0;
633 	go->neg_ssnhf = 0;
634 	go->neg_endpoint = 0;
635     }
636     if (noendpoint)
637 	ao->neg_endpoint = 0;
638     peer_mru[f->unit] = PPP_MRU;
639     auth_reset(f->unit);
640 }
641 
642 
643 /*
644  * lcp_cilen - Return length of our CI.
645  */
646 static int
lcp_cilen(fsm * f)647 lcp_cilen(fsm *f)
648 {
649     lcp_options *go = &lcp_gotoptions[f->unit];
650 
651 #define LENCIVOID(neg)	((neg) ? CILEN_VOID : 0)
652 #define LENCICHAP(neg)	((neg) ? CILEN_CHAP : 0)
653 #define LENCISHORT(neg)	((neg) ? CILEN_SHORT : 0)
654 #define LENCILONG(neg)	((neg) ? CILEN_LONG : 0)
655 #define LENCILQR(neg)	((neg) ? CILEN_LQR: 0)
656 #define LENCICBCP(neg)	((neg) ? CILEN_CBCP: 0)
657     /*
658      * NB: we only ask for one of CHAP, UPAP, or EAP, even if we will
659      * accept more than one.  We prefer EAP first, then CHAP, then
660      * PAP.
661      */
662     return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) +
663 	    LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) +
664 	    LENCISHORT(go->neg_eap) +
665 	    LENCICHAP(!go->neg_eap && go->neg_chap) +
666 	    LENCISHORT(!go->neg_eap && !go->neg_chap && go->neg_upap) +
667 	    LENCILQR(go->neg_lqr) +
668 	    LENCICBCP(go->neg_cbcp) +
669 	    LENCILONG(go->neg_magicnumber) +
670 	    LENCIVOID(go->neg_pcompression) +
671 	    LENCIVOID(go->neg_accompression) +
672 	    LENCISHORT(go->neg_mrru) +
673 	    LENCIVOID(go->neg_ssnhf) +
674 	    (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0));
675 }
676 
677 
678 /*
679  * lcp_addci - Add our desired CIs to a packet.
680  */
681 static void
lcp_addci(fsm * f,u_char * ucp,int * lenp)682 lcp_addci(fsm *f, u_char *ucp, int *lenp)
683 {
684     lcp_options *go = &lcp_gotoptions[f->unit];
685     u_char *start_ucp = ucp;
686 
687 #define ADDCIVOID(opt, neg) \
688     if (neg) { \
689 	PUTCHAR(opt, ucp); \
690 	PUTCHAR(CILEN_VOID, ucp); \
691     }
692 #define ADDCISHORT(opt, neg, val) \
693     if (neg) { \
694 	PUTCHAR(opt, ucp); \
695 	PUTCHAR(CILEN_SHORT, ucp); \
696 	PUTSHORT(val, ucp); \
697     }
698 #define ADDCICHAP(opt, neg, val) \
699     if (neg) { \
700 	PUTCHAR((opt), ucp); \
701 	PUTCHAR(CILEN_CHAP, ucp); \
702 	PUTSHORT(PPP_CHAP, ucp); \
703 	PUTCHAR((CHAP_DIGEST(val)), ucp); \
704     }
705 #define ADDCILONG(opt, neg, val) \
706     if (neg) { \
707 	PUTCHAR(opt, ucp); \
708 	PUTCHAR(CILEN_LONG, ucp); \
709 	PUTLONG(val, ucp); \
710     }
711 #define ADDCILQR(opt, neg, val) \
712     if (neg) { \
713 	PUTCHAR(opt, ucp); \
714 	PUTCHAR(CILEN_LQR, ucp); \
715 	PUTSHORT(PPP_LQR, ucp); \
716 	PUTLONG(val, ucp); \
717     }
718 #define ADDCICHAR(opt, neg, val) \
719     if (neg) { \
720 	PUTCHAR(opt, ucp); \
721 	PUTCHAR(CILEN_CHAR, ucp); \
722 	PUTCHAR(val, ucp); \
723     }
724 #define ADDCIENDP(opt, neg, class, val, len) \
725     if (neg) { \
726 	int i; \
727 	PUTCHAR(opt, ucp); \
728 	PUTCHAR(CILEN_CHAR + len, ucp); \
729 	PUTCHAR(class, ucp); \
730 	for (i = 0; i < len; ++i) \
731 	    PUTCHAR(val[i], ucp); \
732     }
733 
734     ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
735     ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
736 	      go->asyncmap);
737     ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
738     ADDCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
739     ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap,
740 	       PPP_PAP);
741     ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
742     ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
743     ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
744     ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
745     ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
746     ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru);
747     ADDCIVOID(CI_SSNHF, go->neg_ssnhf);
748     ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class,
749 	      go->endpoint.value, go->endpoint.length);
750 
751     if (ucp - start_ucp != *lenp) {
752 	/* this should never happen, because peer_mtu should be 1500 */
753 	error("Bug in lcp_addci: wrong length");
754     }
755 }
756 
757 
758 /*
759  * lcp_ackci - Ack our CIs.
760  * This should not modify any state if the Ack is bad.
761  *
762  * Returns:
763  *	0 - Ack was bad.
764  *	1 - Ack was good.
765  */
766 static int
lcp_ackci(fsm * f,u_char * p,int len)767 lcp_ackci(fsm *f, u_char *p, int len)
768 {
769     lcp_options *go = &lcp_gotoptions[f->unit];
770     u_char cilen, citype, cichar;
771     u_short cishort;
772     u_int32_t cilong;
773 
774     /*
775      * CIs must be in exactly the same order that we sent.
776      * Check packet length and CI length at each step.
777      * If we find any deviations, then this packet is bad.
778      */
779 #define ACKCIVOID(opt, neg) \
780     if (neg) { \
781 	if ((len -= CILEN_VOID) < 0) \
782 	    goto bad; \
783 	GETCHAR(citype, p); \
784 	GETCHAR(cilen, p); \
785 	if (cilen != CILEN_VOID || \
786 	    citype != opt) \
787 	    goto bad; \
788     }
789 #define ACKCISHORT(opt, neg, val) \
790     if (neg) { \
791 	if ((len -= CILEN_SHORT) < 0) \
792 	    goto bad; \
793 	GETCHAR(citype, p); \
794 	GETCHAR(cilen, p); \
795 	if (cilen != CILEN_SHORT || \
796 	    citype != opt) \
797 	    goto bad; \
798 	GETSHORT(cishort, p); \
799 	if (cishort != val) \
800 	    goto bad; \
801     }
802 #define ACKCICHAR(opt, neg, val) \
803     if (neg) { \
804 	if ((len -= CILEN_CHAR) < 0) \
805 	    goto bad; \
806 	GETCHAR(citype, p); \
807 	GETCHAR(cilen, p); \
808 	if (cilen != CILEN_CHAR || \
809 	    citype != opt) \
810 	    goto bad; \
811 	GETCHAR(cichar, p); \
812 	if (cichar != val) \
813 	    goto bad; \
814     }
815 #define ACKCICHAP(opt, neg, val) \
816     if (neg) { \
817 	if ((len -= CILEN_CHAP) < 0) \
818 	    goto bad; \
819 	GETCHAR(citype, p); \
820 	GETCHAR(cilen, p); \
821 	if (cilen != CILEN_CHAP || \
822 	    citype != (opt)) \
823 	    goto bad; \
824 	GETSHORT(cishort, p); \
825 	if (cishort != PPP_CHAP) \
826 	    goto bad; \
827 	GETCHAR(cichar, p); \
828 	if (cichar != (CHAP_DIGEST(val))) \
829 	  goto bad; \
830     }
831 #define ACKCILONG(opt, neg, val) \
832     if (neg) { \
833 	if ((len -= CILEN_LONG) < 0) \
834 	    goto bad; \
835 	GETCHAR(citype, p); \
836 	GETCHAR(cilen, p); \
837 	if (cilen != CILEN_LONG || \
838 	    citype != opt) \
839 	    goto bad; \
840 	GETLONG(cilong, p); \
841 	if (cilong != val) \
842 	    goto bad; \
843     }
844 #define ACKCILQR(opt, neg, val) \
845     if (neg) { \
846 	if ((len -= CILEN_LQR) < 0) \
847 	    goto bad; \
848 	GETCHAR(citype, p); \
849 	GETCHAR(cilen, p); \
850 	if (cilen != CILEN_LQR || \
851 	    citype != opt) \
852 	    goto bad; \
853 	GETSHORT(cishort, p); \
854 	if (cishort != PPP_LQR) \
855 	    goto bad; \
856 	GETLONG(cilong, p); \
857 	if (cilong != val) \
858 	  goto bad; \
859     }
860 #define ACKCIENDP(opt, neg, class, val, vlen) \
861     if (neg) { \
862 	int i; \
863 	if ((len -= CILEN_CHAR + vlen) < 0) \
864 	    goto bad; \
865 	GETCHAR(citype, p); \
866 	GETCHAR(cilen, p); \
867 	if (cilen != CILEN_CHAR + vlen || \
868 	    citype != opt) \
869 	    goto bad; \
870 	GETCHAR(cichar, p); \
871 	if (cichar != class) \
872 	    goto bad; \
873 	for (i = 0; i < vlen; ++i) { \
874 	    GETCHAR(cichar, p); \
875 	    if (cichar != val[i]) \
876 		goto bad; \
877 	} \
878     }
879 
880     ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
881     ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
882 	      go->asyncmap);
883     ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
884     ACKCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
885     ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap,
886 	       PPP_PAP);
887     ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
888     ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
889     ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
890     ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
891     ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
892     ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru);
893     ACKCIVOID(CI_SSNHF, go->neg_ssnhf);
894     ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class,
895 	      go->endpoint.value, go->endpoint.length);
896 
897     /*
898      * If there are any remaining CIs, then this packet is bad.
899      */
900     if (len != 0)
901 	goto bad;
902     return (1);
903 bad:
904     LCPDEBUG(("lcp_acki: received bad Ack!"));
905     return (0);
906 }
907 
908 
909 /*
910  * lcp_nakci - Peer has sent a NAK for some of our CIs.
911  * This should not modify any state if the Nak is bad
912  * or if LCP is in the OPENED state.
913  *
914  * Returns:
915  *	0 - Nak was bad.
916  *	1 - Nak was good.
917  */
918 static int
lcp_nakci(fsm * f,u_char * p,int len,int treat_as_reject)919 lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
920 {
921     lcp_options *go = &lcp_gotoptions[f->unit];
922     lcp_options *wo = &lcp_wantoptions[f->unit];
923     u_char citype, cichar, *next;
924     u_short cishort;
925     u_int32_t cilong;
926     lcp_options no;		/* options we've seen Naks for */
927     lcp_options try;		/* options to request next time */
928     int looped_back = 0;
929     int cilen;
930 
931     BZERO(&no, sizeof(no));
932     try = *go;
933 
934     /*
935      * Any Nak'd CIs must be in exactly the same order that we sent.
936      * Check packet length and CI length at each step.
937      * If we find any deviations, then this packet is bad.
938      */
939 #define NAKCIVOID(opt, neg) \
940     if (go->neg && \
941 	len >= CILEN_VOID && \
942 	p[1] == CILEN_VOID && \
943 	p[0] == opt) { \
944 	len -= CILEN_VOID; \
945 	INCPTR(CILEN_VOID, p); \
946 	no.neg = 1; \
947 	try.neg = 0; \
948     }
949 #define NAKCICHAP(opt, neg, code) \
950     if (go->neg && \
951 	len >= CILEN_CHAP && \
952 	p[1] == CILEN_CHAP && \
953 	p[0] == opt) { \
954 	len -= CILEN_CHAP; \
955 	INCPTR(2, p); \
956 	GETSHORT(cishort, p); \
957 	GETCHAR(cichar, p); \
958 	no.neg = 1; \
959 	code \
960     }
961 #define NAKCICHAR(opt, neg, code) \
962     if (go->neg && \
963 	len >= CILEN_CHAR && \
964 	p[1] == CILEN_CHAR && \
965 	p[0] == opt) { \
966 	len -= CILEN_CHAR; \
967 	INCPTR(2, p); \
968 	GETCHAR(cichar, p); \
969 	no.neg = 1; \
970 	code \
971     }
972 #define NAKCISHORT(opt, neg, code) \
973     if (go->neg && \
974 	len >= CILEN_SHORT && \
975 	p[1] == CILEN_SHORT && \
976 	p[0] == opt) { \
977 	len -= CILEN_SHORT; \
978 	INCPTR(2, p); \
979 	GETSHORT(cishort, p); \
980 	no.neg = 1; \
981 	code \
982     }
983 #define NAKCILONG(opt, neg, code) \
984     if (go->neg && \
985 	len >= CILEN_LONG && \
986 	p[1] == CILEN_LONG && \
987 	p[0] == opt) { \
988 	len -= CILEN_LONG; \
989 	INCPTR(2, p); \
990 	GETLONG(cilong, p); \
991 	no.neg = 1; \
992 	code \
993     }
994 #define NAKCILQR(opt, neg, code) \
995     if (go->neg && \
996 	len >= CILEN_LQR && \
997 	p[1] == CILEN_LQR && \
998 	p[0] == opt) { \
999 	len -= CILEN_LQR; \
1000 	INCPTR(2, p); \
1001 	GETSHORT(cishort, p); \
1002 	GETLONG(cilong, p); \
1003 	no.neg = 1; \
1004 	code \
1005     }
1006 #define NAKCIENDP(opt, neg) \
1007     if (go->neg && \
1008 	len >= CILEN_CHAR && \
1009 	p[0] == opt && \
1010 	p[1] >= CILEN_CHAR && \
1011 	p[1] <= len) { \
1012 	len -= p[1]; \
1013 	INCPTR(p[1], p); \
1014 	no.neg = 1; \
1015 	try.neg = 0; \
1016     }
1017 
1018     /*
1019      * NOTE!  There must be no assignments to individual fields of *go in
1020      * the code below.  Any such assignment is a BUG!
1021      */
1022     /*
1023      * We don't care if they want to send us smaller packets than
1024      * we want.  Therefore, accept any MRU less than what we asked for,
1025      * but then ignore the new value when setting the MRU in the kernel.
1026      * If they send us a bigger MRU than what we asked, accept it, up to
1027      * the limit of the default MRU we'd get if we didn't negotiate.
1028      */
1029     if (go->neg_mru && go->mru != DEFMRU) {
1030 	NAKCISHORT(CI_MRU, neg_mru,
1031 		   if (cishort <= wo->mru || cishort <= DEFMRU)
1032 		       try.mru = cishort;
1033 		   );
1034     }
1035 
1036     /*
1037      * Add any characters they want to our (receive-side) asyncmap.
1038      */
1039     if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) {
1040 	NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
1041 		  try.asyncmap = go->asyncmap | cilong;
1042 		  );
1043     }
1044 
1045     /*
1046      * If they've nak'd our authentication-protocol, check whether
1047      * they are proposing a different protocol, or a different
1048      * hash algorithm for CHAP.
1049      */
1050     if ((go->neg_chap || go->neg_upap || go->neg_eap)
1051 	&& len >= CILEN_SHORT
1052 	&& p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
1053 	cilen = p[1];
1054 	len -= cilen;
1055 	no.neg_chap = go->neg_chap;
1056 	no.neg_upap = go->neg_upap;
1057 	no.neg_eap = go->neg_eap;
1058 	INCPTR(2, p);
1059 	GETSHORT(cishort, p);
1060 	if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
1061 	    /* If we were asking for EAP, then we need to stop that. */
1062 	    if (go->neg_eap)
1063 		try.neg_eap = 0;
1064 
1065 	    /* If we were asking for CHAP, then we need to stop that. */
1066 	    else if (go->neg_chap)
1067 		try.neg_chap = 0;
1068 	    /*
1069 	     * If we weren't asking for CHAP or EAP, then we were asking for
1070 	     * PAP, in which case this Nak is bad.
1071 	     */
1072 	    else
1073 		goto bad;
1074 
1075 	} else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
1076 	    GETCHAR(cichar, p);
1077 	    /* Stop asking for EAP, if we were. */
1078 	    if (go->neg_eap) {
1079 		try.neg_eap = 0;
1080 		/* Try to set up to use their suggestion, if possible */
1081 		if (CHAP_CANDIGEST(go->chap_mdtype, cichar))
1082 		    try.chap_mdtype = CHAP_MDTYPE_D(cichar);
1083 	    } else if (go->neg_chap) {
1084 		/*
1085 		 * We were asking for our preferred algorithm, they must
1086 		 * want something different.
1087 		 */
1088 		if (cichar != CHAP_DIGEST(go->chap_mdtype)) {
1089 		    if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) {
1090 			/* Use their suggestion if we support it ... */
1091 			try.chap_mdtype = CHAP_MDTYPE_D(cichar);
1092 		    } else {
1093 			/* ... otherwise, try our next-preferred algorithm. */
1094 			try.chap_mdtype &= ~(CHAP_MDTYPE(try.chap_mdtype));
1095 			if (try.chap_mdtype == MDTYPE_NONE) /* out of algos */
1096 			    try.neg_chap = 0;
1097 		    }
1098 		} else {
1099 		    /*
1100 		     * Whoops, they Nak'd our algorithm of choice
1101 		     * but then suggested it back to us.
1102 		     */
1103 		    goto bad;
1104 		}
1105 	    } else {
1106 		/*
1107 		 * Stop asking for PAP if we were asking for it.
1108 		 */
1109 		try.neg_upap = 0;
1110 	    }
1111 
1112 	} else {
1113 
1114 	    /*
1115 	     * If we were asking for EAP, and they're Conf-Naking EAP,
1116 	     * well, that's just strange.  Nobody should do that.
1117 	     */
1118 	    if (cishort == PPP_EAP && cilen == CILEN_SHORT && go->neg_eap)
1119 		dbglog("Unexpected Conf-Nak for EAP");
1120 
1121 	    /*
1122 	     * We don't recognize what they're suggesting.
1123 	     * Stop asking for what we were asking for.
1124 	     */
1125 	    if (go->neg_eap)
1126 		try.neg_eap = 0;
1127 	    else if (go->neg_chap)
1128 		try.neg_chap = 0;
1129 	    else
1130 		try.neg_upap = 0;
1131 	    p += cilen - CILEN_SHORT;
1132 	}
1133     }
1134 
1135     /*
1136      * If they can't cope with our link quality protocol, we'll have
1137      * to stop asking for LQR.  We haven't got any other protocol.
1138      * If they Nak the reporting period, take their value XXX ?
1139      */
1140     NAKCILQR(CI_QUALITY, neg_lqr,
1141 	     if (cishort != PPP_LQR)
1142 		 try.neg_lqr = 0;
1143 	     else
1144 		 try.lqr_period = cilong;
1145 	     );
1146 
1147     /*
1148      * Only implementing CBCP...not the rest of the callback options
1149      */
1150     NAKCICHAR(CI_CALLBACK, neg_cbcp,
1151               try.neg_cbcp = 0;
1152               );
1153 
1154     /*
1155      * Check for a looped-back line.
1156      */
1157     NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
1158 	      try.magicnumber = magic();
1159 	      looped_back = 1;
1160 	      );
1161 
1162     /*
1163      * Peer shouldn't send Nak for protocol compression or
1164      * address/control compression requests; they should send
1165      * a Reject instead.  If they send a Nak, treat it as a Reject.
1166      */
1167     NAKCIVOID(CI_PCOMPRESSION, neg_pcompression);
1168     NAKCIVOID(CI_ACCOMPRESSION, neg_accompression);
1169 
1170     /*
1171      * Nak for MRRU option - accept their value if it is smaller
1172      * than the one we want.
1173      */
1174     if (go->neg_mrru) {
1175 	NAKCISHORT(CI_MRRU, neg_mrru,
1176 		   if (treat_as_reject)
1177 		       try.neg_mrru = 0;
1178 		   else if (cishort <= wo->mrru)
1179 		       try.mrru = cishort;
1180 		   );
1181     }
1182 
1183     /*
1184      * Nak for short sequence numbers shouldn't be sent, treat it
1185      * like a reject.
1186      */
1187     NAKCIVOID(CI_SSNHF, neg_ssnhf);
1188 
1189     /*
1190      * Nak of the endpoint discriminator option is not permitted,
1191      * treat it like a reject.
1192      */
1193     NAKCIENDP(CI_EPDISC, neg_endpoint);
1194 
1195     /*
1196      * There may be remaining CIs, if the peer is requesting negotiation
1197      * on an option that we didn't include in our request packet.
1198      * If we see an option that we requested, or one we've already seen
1199      * in this packet, then this packet is bad.
1200      * If we wanted to respond by starting to negotiate on the requested
1201      * option(s), we could, but we don't, because except for the
1202      * authentication type and quality protocol, if we are not negotiating
1203      * an option, it is because we were told not to.
1204      * For the authentication type, the Nak from the peer means
1205      * `let me authenticate myself with you' which is a bit pointless.
1206      * For the quality protocol, the Nak means `ask me to send you quality
1207      * reports', but if we didn't ask for them, we don't want them.
1208      * An option we don't recognize represents the peer asking to
1209      * negotiate some option we don't support, so ignore it.
1210      */
1211     while (len >= CILEN_VOID) {
1212 	GETCHAR(citype, p);
1213 	GETCHAR(cilen, p);
1214 	if (cilen < CILEN_VOID || (len -= cilen) < 0)
1215 	    goto bad;
1216 	next = p + cilen - 2;
1217 
1218 	switch (citype) {
1219 	case CI_MRU:
1220 	    if ((go->neg_mru && go->mru != DEFMRU)
1221 		|| no.neg_mru || cilen != CILEN_SHORT)
1222 		goto bad;
1223 	    GETSHORT(cishort, p);
1224 	    if (cishort < DEFMRU) {
1225 		try.neg_mru = 1;
1226 		try.mru = cishort;
1227 	    }
1228 	    break;
1229 	case CI_ASYNCMAP:
1230 	    if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF)
1231 		|| no.neg_asyncmap || cilen != CILEN_LONG)
1232 		goto bad;
1233 	    break;
1234 	case CI_AUTHTYPE:
1235 	    if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap ||
1236 		go->neg_eap || no.neg_eap)
1237 		goto bad;
1238 	    break;
1239 	case CI_MAGICNUMBER:
1240 	    if (go->neg_magicnumber || no.neg_magicnumber ||
1241 		cilen != CILEN_LONG)
1242 		goto bad;
1243 	    break;
1244 	case CI_PCOMPRESSION:
1245 	    if (go->neg_pcompression || no.neg_pcompression
1246 		|| cilen != CILEN_VOID)
1247 		goto bad;
1248 	    break;
1249 	case CI_ACCOMPRESSION:
1250 	    if (go->neg_accompression || no.neg_accompression
1251 		|| cilen != CILEN_VOID)
1252 		goto bad;
1253 	    break;
1254 	case CI_QUALITY:
1255 	    if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)
1256 		goto bad;
1257 	    break;
1258 	case CI_MRRU:
1259 	    if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT)
1260 		goto bad;
1261 	    break;
1262 	case CI_SSNHF:
1263 	    if (go->neg_ssnhf || no.neg_ssnhf || cilen != CILEN_VOID)
1264 		goto bad;
1265 	    try.neg_ssnhf = 1;
1266 	    break;
1267 	case CI_EPDISC:
1268 	    if (go->neg_endpoint || no.neg_endpoint || cilen < CILEN_CHAR)
1269 		goto bad;
1270 	    break;
1271 	}
1272 	p = next;
1273     }
1274 
1275     /*
1276      * OK, the Nak is good.  Now we can update state.
1277      * If there are any options left we ignore them.
1278      */
1279     if (f->state != OPENED) {
1280 	if (looped_back) {
1281 	    if (++try.numloops >= lcp_loopbackfail) {
1282 		notice("Serial line is looped back.");
1283 		status = EXIT_LOOPBACK;
1284 		lcp_close(f->unit, "Loopback detected");
1285 	    }
1286 	} else
1287 	    try.numloops = 0;
1288 	*go = try;
1289     }
1290 
1291     return 1;
1292 
1293 bad:
1294     LCPDEBUG(("lcp_nakci: received bad Nak!"));
1295     return 0;
1296 }
1297 
1298 
1299 /*
1300  * lcp_rejci - Peer has Rejected some of our CIs.
1301  * This should not modify any state if the Reject is bad
1302  * or if LCP is in the OPENED state.
1303  *
1304  * Returns:
1305  *	0 - Reject was bad.
1306  *	1 - Reject was good.
1307  */
1308 static int
lcp_rejci(fsm * f,u_char * p,int len)1309 lcp_rejci(fsm *f, u_char *p, int len)
1310 {
1311     lcp_options *go = &lcp_gotoptions[f->unit];
1312     u_char cichar;
1313     u_short cishort;
1314     u_int32_t cilong;
1315     lcp_options try;		/* options to request next time */
1316 
1317     try = *go;
1318 
1319     /*
1320      * Any Rejected CIs must be in exactly the same order that we sent.
1321      * Check packet length and CI length at each step.
1322      * If we find any deviations, then this packet is bad.
1323      */
1324 #define REJCIVOID(opt, neg) \
1325     if (go->neg && \
1326 	len >= CILEN_VOID && \
1327 	p[1] == CILEN_VOID && \
1328 	p[0] == opt) { \
1329 	len -= CILEN_VOID; \
1330 	INCPTR(CILEN_VOID, p); \
1331 	try.neg = 0; \
1332     }
1333 #define REJCISHORT(opt, neg, val) \
1334     if (go->neg && \
1335 	len >= CILEN_SHORT && \
1336 	p[1] == CILEN_SHORT && \
1337 	p[0] == opt) { \
1338 	len -= CILEN_SHORT; \
1339 	INCPTR(2, p); \
1340 	GETSHORT(cishort, p); \
1341 	/* Check rejected value. */ \
1342 	if (cishort != val) \
1343 	    goto bad; \
1344 	try.neg = 0; \
1345     }
1346 #define REJCICHAP(opt, neg, val) \
1347     if (go->neg && \
1348 	len >= CILEN_CHAP && \
1349 	p[1] == CILEN_CHAP && \
1350 	p[0] == opt) { \
1351 	len -= CILEN_CHAP; \
1352 	INCPTR(2, p); \
1353 	GETSHORT(cishort, p); \
1354 	GETCHAR(cichar, p); \
1355 	/* Check rejected value. */ \
1356 	if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \
1357 	    goto bad; \
1358 	try.neg = 0; \
1359 	try.neg_eap = try.neg_upap = 0; \
1360     }
1361 #define REJCILONG(opt, neg, val) \
1362     if (go->neg && \
1363 	len >= CILEN_LONG && \
1364 	p[1] == CILEN_LONG && \
1365 	p[0] == opt) { \
1366 	len -= CILEN_LONG; \
1367 	INCPTR(2, p); \
1368 	GETLONG(cilong, p); \
1369 	/* Check rejected value. */ \
1370 	if (cilong != val) \
1371 	    goto bad; \
1372 	try.neg = 0; \
1373     }
1374 #define REJCILQR(opt, neg, val) \
1375     if (go->neg && \
1376 	len >= CILEN_LQR && \
1377 	p[1] == CILEN_LQR && \
1378 	p[0] == opt) { \
1379 	len -= CILEN_LQR; \
1380 	INCPTR(2, p); \
1381 	GETSHORT(cishort, p); \
1382 	GETLONG(cilong, p); \
1383 	/* Check rejected value. */ \
1384 	if (cishort != PPP_LQR || cilong != val) \
1385 	    goto bad; \
1386 	try.neg = 0; \
1387     }
1388 #define REJCICBCP(opt, neg, val) \
1389     if (go->neg && \
1390 	len >= CILEN_CBCP && \
1391 	p[1] == CILEN_CBCP && \
1392 	p[0] == opt) { \
1393 	len -= CILEN_CBCP; \
1394 	INCPTR(2, p); \
1395 	GETCHAR(cichar, p); \
1396 	/* Check rejected value. */ \
1397 	if (cichar != val) \
1398 	    goto bad; \
1399 	try.neg = 0; \
1400     }
1401 #define REJCIENDP(opt, neg, class, val, vlen) \
1402     if (go->neg && \
1403 	len >= CILEN_CHAR + vlen && \
1404 	p[0] == opt && \
1405 	p[1] == CILEN_CHAR + vlen) { \
1406 	int i; \
1407 	len -= CILEN_CHAR + vlen; \
1408 	INCPTR(2, p); \
1409 	GETCHAR(cichar, p); \
1410 	if (cichar != class) \
1411 	    goto bad; \
1412 	for (i = 0; i < vlen; ++i) { \
1413 	    GETCHAR(cichar, p); \
1414 	    if (cichar != val[i]) \
1415 		goto bad; \
1416 	} \
1417 	try.neg = 0; \
1418     }
1419 
1420     REJCISHORT(CI_MRU, neg_mru, go->mru);
1421     REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
1422     REJCISHORT(CI_AUTHTYPE, neg_eap, PPP_EAP);
1423     if (!go->neg_eap) {
1424 	REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype);
1425 	if (!go->neg_chap) {
1426 	    REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
1427 	}
1428     }
1429     REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
1430     REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
1431     REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
1432     REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
1433     REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
1434     REJCISHORT(CI_MRRU, neg_mrru, go->mrru);
1435     REJCIVOID(CI_SSNHF, neg_ssnhf);
1436     REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class,
1437 	      go->endpoint.value, go->endpoint.length);
1438 
1439     /*
1440      * If there are any remaining CIs, then this packet is bad.
1441      */
1442     if (len != 0)
1443 	goto bad;
1444     /*
1445      * Now we can update state.
1446      */
1447     if (f->state != OPENED)
1448 	*go = try;
1449     return 1;
1450 
1451 bad:
1452     LCPDEBUG(("lcp_rejci: received bad Reject!"));
1453     return 0;
1454 }
1455 
1456 
1457 /*
1458  * lcp_reqci - Check the peer's requested CIs and send appropriate response.
1459  *
1460  * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
1461  * appropriately.  If reject_if_disagree is non-zero, doesn't return
1462  * CONFNAK; returns CONFREJ if it can't return CONFACK.
1463  */
1464 static int
lcp_reqci(fsm * f,u_char * inp,int * lenp,int reject_if_disagree)1465 lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree)
1466 {
1467     lcp_options *go = &lcp_gotoptions[f->unit];
1468     lcp_options *ho = &lcp_hisoptions[f->unit];
1469     lcp_options *ao = &lcp_allowoptions[f->unit];
1470     u_char *cip, *next;		/* Pointer to current and next CIs */
1471     int cilen, citype, cichar;	/* Parsed len, type, char value */
1472     u_short cishort;		/* Parsed short value */
1473     u_int32_t cilong;		/* Parse long value */
1474     int rc = CONFACK;		/* Final packet return code */
1475     int orc;			/* Individual option return code */
1476     u_char *p;			/* Pointer to next char to parse */
1477     u_char *rejp;		/* Pointer to next char in reject frame */
1478     u_char *nakp;		/* Pointer to next char in Nak frame */
1479     int l = *lenp;		/* Length left */
1480 
1481     /*
1482      * Reset all his options.
1483      */
1484     BZERO(ho, sizeof(*ho));
1485 
1486     /*
1487      * Process all his options.
1488      */
1489     next = inp;
1490     nakp = nak_buffer;
1491     rejp = inp;
1492     while (l) {
1493 	orc = CONFACK;			/* Assume success */
1494 	cip = p = next;			/* Remember begining of CI */
1495 	if (l < 2 ||			/* Not enough data for CI header or */
1496 	    p[1] < 2 ||			/*  CI length too small or */
1497 	    p[1] > l) {			/*  CI length too big? */
1498 	    LCPDEBUG(("lcp_reqci: bad CI length!"));
1499 	    orc = CONFREJ;		/* Reject bad CI */
1500 	    cilen = l;			/* Reject till end of packet */
1501 	    l = 0;			/* Don't loop again */
1502 	    citype = 0;
1503 	    goto endswitch;
1504 	}
1505 	GETCHAR(citype, p);		/* Parse CI type */
1506 	GETCHAR(cilen, p);		/* Parse CI length */
1507 	l -= cilen;			/* Adjust remaining length */
1508 	next += cilen;			/* Step to next CI */
1509 
1510 	switch (citype) {		/* Check CI type */
1511 	case CI_MRU:
1512 	    if (!ao->neg_mru ||		/* Allow option? */
1513 		cilen != CILEN_SHORT) {	/* Check CI length */
1514 		orc = CONFREJ;		/* Reject CI */
1515 		break;
1516 	    }
1517 	    GETSHORT(cishort, p);	/* Parse MRU */
1518 
1519 	    /*
1520 	     * He must be able to receive at least our minimum.
1521 	     * No need to check a maximum.  If he sends a large number,
1522 	     * we'll just ignore it.
1523 	     */
1524 	    if (cishort < MINMRU) {
1525 		orc = CONFNAK;		/* Nak CI */
1526 		PUTCHAR(CI_MRU, nakp);
1527 		PUTCHAR(CILEN_SHORT, nakp);
1528 		PUTSHORT(MINMRU, nakp);	/* Give him a hint */
1529 		break;
1530 	    }
1531 	    ho->neg_mru = 1;		/* Remember he sent MRU */
1532 	    ho->mru = cishort;		/* And remember value */
1533 	    break;
1534 
1535 	case CI_ASYNCMAP:
1536 	    if (!ao->neg_asyncmap ||
1537 		cilen != CILEN_LONG) {
1538 		orc = CONFREJ;
1539 		break;
1540 	    }
1541 	    GETLONG(cilong, p);
1542 
1543 	    /*
1544 	     * Asyncmap must have set at least the bits
1545 	     * which are set in lcp_allowoptions[unit].asyncmap.
1546 	     */
1547 	    if ((ao->asyncmap & ~cilong) != 0) {
1548 		orc = CONFNAK;
1549 		PUTCHAR(CI_ASYNCMAP, nakp);
1550 		PUTCHAR(CILEN_LONG, nakp);
1551 		PUTLONG(ao->asyncmap | cilong, nakp);
1552 		break;
1553 	    }
1554 	    ho->neg_asyncmap = 1;
1555 	    ho->asyncmap = cilong;
1556 	    break;
1557 
1558 	case CI_AUTHTYPE:
1559 	    if (cilen < CILEN_SHORT ||
1560 		!(ao->neg_upap || ao->neg_chap || ao->neg_eap)) {
1561 		/*
1562 		 * Reject the option if we're not willing to authenticate.
1563 		 */
1564 		dbglog("No auth is possible");
1565 		orc = CONFREJ;
1566 		break;
1567 	    }
1568 	    GETSHORT(cishort, p);
1569 
1570 	    /*
1571 	     * Authtype must be PAP, CHAP, or EAP.
1572 	     *
1573 	     * Note: if more than one of ao->neg_upap, ao->neg_chap, and
1574 	     * ao->neg_eap are set, and the peer sends a Configure-Request
1575 	     * with two or more authenticate-protocol requests, then we will
1576 	     * reject the second request.
1577 	     * Whether we end up doing CHAP, UPAP, or EAP depends then on
1578 	     * the ordering of the CIs in the peer's Configure-Request.
1579              */
1580 
1581 	    if (cishort == PPP_PAP) {
1582 		/* we've already accepted CHAP or EAP */
1583 		if (ho->neg_chap || ho->neg_eap ||
1584 		    cilen != CILEN_SHORT) {
1585 		    LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));
1586 		    orc = CONFREJ;
1587 		    break;
1588 		}
1589 		if (!ao->neg_upap) {	/* we don't want to do PAP */
1590 		    orc = CONFNAK;	/* NAK it and suggest CHAP or EAP */
1591 		    PUTCHAR(CI_AUTHTYPE, nakp);
1592 		    if (ao->neg_eap) {
1593 			PUTCHAR(CILEN_SHORT, nakp);
1594 			PUTSHORT(PPP_EAP, nakp);
1595 		    } else {
1596 			PUTCHAR(CILEN_CHAP, nakp);
1597 			PUTSHORT(PPP_CHAP, nakp);
1598 			PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
1599 		    }
1600 		    break;
1601 		}
1602 		ho->neg_upap = 1;
1603 		break;
1604 	    }
1605 	    if (cishort == PPP_CHAP) {
1606 		/* we've already accepted PAP or EAP */
1607 		if (ho->neg_upap || ho->neg_eap ||
1608 		    cilen != CILEN_CHAP) {
1609 		    LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));
1610 		    orc = CONFREJ;
1611 		    break;
1612 		}
1613 		if (!ao->neg_chap) {	/* we don't want to do CHAP */
1614 		    orc = CONFNAK;	/* NAK it and suggest EAP or PAP */
1615 		    PUTCHAR(CI_AUTHTYPE, nakp);
1616 		    PUTCHAR(CILEN_SHORT, nakp);
1617 		    if (ao->neg_eap) {
1618 			PUTSHORT(PPP_EAP, nakp);
1619 		    } else {
1620 			PUTSHORT(PPP_PAP, nakp);
1621 		    }
1622 		    break;
1623 		}
1624 		GETCHAR(cichar, p);	/* get digest type */
1625 		if (!(CHAP_CANDIGEST(ao->chap_mdtype, cichar))) {
1626 		    /*
1627 		     * We can't/won't do the requested type,
1628 		     * suggest something else.
1629 		     */
1630 		    orc = CONFNAK;
1631 		    PUTCHAR(CI_AUTHTYPE, nakp);
1632 		    PUTCHAR(CILEN_CHAP, nakp);
1633 		    PUTSHORT(PPP_CHAP, nakp);
1634 		    PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
1635 		    break;
1636 		}
1637 		ho->chap_mdtype = CHAP_MDTYPE_D(cichar); /* save md type */
1638 		ho->neg_chap = 1;
1639 		break;
1640 	    }
1641 	    if (cishort == PPP_EAP) {
1642 		/* we've already accepted CHAP or PAP */
1643 		if (ho->neg_chap || ho->neg_upap || cilen != CILEN_SHORT) {
1644 		    LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE EAP, rejecting..."));
1645 		    orc = CONFREJ;
1646 		    break;
1647 		}
1648 		if (!ao->neg_eap) {	/* we don't want to do EAP */
1649 		    orc = CONFNAK;	/* NAK it and suggest CHAP or PAP */
1650 		    PUTCHAR(CI_AUTHTYPE, nakp);
1651 		    if (ao->neg_chap) {
1652 			PUTCHAR(CILEN_CHAP, nakp);
1653 			PUTSHORT(PPP_CHAP, nakp);
1654 			PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
1655 		    } else {
1656 			PUTCHAR(CILEN_SHORT, nakp);
1657 			PUTSHORT(PPP_PAP, nakp);
1658 		    }
1659 		    break;
1660 		}
1661 		ho->neg_eap = 1;
1662 		break;
1663 	    }
1664 
1665 	    /*
1666 	     * We don't recognize the protocol they're asking for.
1667 	     * Nak it with something we're willing to do.
1668 	     * (At this point we know ao->neg_upap || ao->neg_chap ||
1669 	     * ao->neg_eap.)
1670 	     */
1671 	    orc = CONFNAK;
1672 	    PUTCHAR(CI_AUTHTYPE, nakp);
1673 	    if (ao->neg_eap) {
1674 		PUTCHAR(CILEN_SHORT, nakp);
1675 		PUTSHORT(PPP_EAP, nakp);
1676 	    } else if (ao->neg_chap) {
1677 		PUTCHAR(CILEN_CHAP, nakp);
1678 		PUTSHORT(PPP_CHAP, nakp);
1679 		PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
1680 	    } else {
1681 		PUTCHAR(CILEN_SHORT, nakp);
1682 		PUTSHORT(PPP_PAP, nakp);
1683 	    }
1684 	    break;
1685 
1686 	case CI_QUALITY:
1687 	    if (!ao->neg_lqr ||
1688 		cilen != CILEN_LQR) {
1689 		orc = CONFREJ;
1690 		break;
1691 	    }
1692 
1693 	    GETSHORT(cishort, p);
1694 	    GETLONG(cilong, p);
1695 
1696 	    /*
1697 	     * Check the protocol and the reporting period.
1698 	     * XXX When should we Nak this, and what with?
1699 	     */
1700 	    if (cishort != PPP_LQR) {
1701 		orc = CONFNAK;
1702 		PUTCHAR(CI_QUALITY, nakp);
1703 		PUTCHAR(CILEN_LQR, nakp);
1704 		PUTSHORT(PPP_LQR, nakp);
1705 		PUTLONG(ao->lqr_period, nakp);
1706 		break;
1707 	    }
1708 	    break;
1709 
1710 	case CI_MAGICNUMBER:
1711 	    if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
1712 		cilen != CILEN_LONG) {
1713 		orc = CONFREJ;
1714 		break;
1715 	    }
1716 	    GETLONG(cilong, p);
1717 
1718 	    /*
1719 	     * He must have a different magic number.
1720 	     */
1721 	    if (go->neg_magicnumber &&
1722 		cilong == go->magicnumber) {
1723 		cilong = magic();	/* Don't put magic() inside macro! */
1724 		orc = CONFNAK;
1725 		PUTCHAR(CI_MAGICNUMBER, nakp);
1726 		PUTCHAR(CILEN_LONG, nakp);
1727 		PUTLONG(cilong, nakp);
1728 		break;
1729 	    }
1730 	    ho->neg_magicnumber = 1;
1731 	    ho->magicnumber = cilong;
1732 	    break;
1733 
1734 
1735 	case CI_PCOMPRESSION:
1736 	    if (!ao->neg_pcompression ||
1737 		cilen != CILEN_VOID) {
1738 		orc = CONFREJ;
1739 		break;
1740 	    }
1741 	    ho->neg_pcompression = 1;
1742 	    break;
1743 
1744 	case CI_ACCOMPRESSION:
1745 	    if (!ao->neg_accompression ||
1746 		cilen != CILEN_VOID) {
1747 		orc = CONFREJ;
1748 		break;
1749 	    }
1750 	    ho->neg_accompression = 1;
1751 	    break;
1752 
1753 	case CI_MRRU:
1754 	    if (!ao->neg_mrru || !multilink ||
1755 		cilen != CILEN_SHORT) {
1756 		orc = CONFREJ;
1757 		break;
1758 	    }
1759 
1760 	    GETSHORT(cishort, p);
1761 	    /* possibly should insist on a minimum/maximum MRRU here */
1762 	    ho->neg_mrru = 1;
1763 	    ho->mrru = cishort;
1764 	    break;
1765 
1766 	case CI_SSNHF:
1767 	    if (!ao->neg_ssnhf || !multilink ||
1768 		cilen != CILEN_VOID) {
1769 		orc = CONFREJ;
1770 		break;
1771 	    }
1772 	    ho->neg_ssnhf = 1;
1773 	    break;
1774 
1775 	case CI_EPDISC:
1776 	    if (!ao->neg_endpoint ||
1777 		cilen < CILEN_CHAR ||
1778 		cilen > CILEN_CHAR + MAX_ENDP_LEN) {
1779 		orc = CONFREJ;
1780 		break;
1781 	    }
1782 	    GETCHAR(cichar, p);
1783 	    cilen -= CILEN_CHAR;
1784 	    ho->neg_endpoint = 1;
1785 	    ho->endpoint.class = cichar;
1786 	    ho->endpoint.length = cilen;
1787 	    BCOPY(p, ho->endpoint.value, cilen);
1788 	    INCPTR(cilen, p);
1789 	    break;
1790 
1791 	default:
1792 	    LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype));
1793 	    orc = CONFREJ;
1794 	    break;
1795 	}
1796 
1797 endswitch:
1798 	if (orc == CONFACK &&		/* Good CI */
1799 	    rc != CONFACK)		/*  but prior CI wasnt? */
1800 	    continue;			/* Don't send this one */
1801 
1802 	if (orc == CONFNAK) {		/* Nak this CI? */
1803 	    if (reject_if_disagree	/* Getting fed up with sending NAKs? */
1804 		&& citype != CI_MAGICNUMBER) {
1805 		orc = CONFREJ;		/* Get tough if so */
1806 	    } else {
1807 		if (rc == CONFREJ)	/* Rejecting prior CI? */
1808 		    continue;		/* Don't send this one */
1809 		rc = CONFNAK;
1810 	    }
1811 	}
1812 	if (orc == CONFREJ) {		/* Reject this CI */
1813 	    rc = CONFREJ;
1814 	    if (cip != rejp)		/* Need to move rejected CI? */
1815 		BCOPY(cip, rejp, cilen); /* Move it */
1816 	    INCPTR(cilen, rejp);	/* Update output pointer */
1817 	}
1818     }
1819 
1820     /*
1821      * If we wanted to send additional NAKs (for unsent CIs), the
1822      * code would go here.  The extra NAKs would go at *nakp.
1823      * At present there are no cases where we want to ask the
1824      * peer to negotiate an option.
1825      */
1826 
1827     switch (rc) {
1828     case CONFACK:
1829 	*lenp = next - inp;
1830 	break;
1831     case CONFNAK:
1832 	/*
1833 	 * Copy the Nak'd options from the nak_buffer to the caller's buffer.
1834 	 */
1835 	*lenp = nakp - nak_buffer;
1836 	BCOPY(nak_buffer, inp, *lenp);
1837 	break;
1838     case CONFREJ:
1839 	*lenp = rejp - inp;
1840 	break;
1841     }
1842 
1843     LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc)));
1844     return (rc);			/* Return final code */
1845 }
1846 
1847 
1848 /*
1849  * lcp_up - LCP has come UP.
1850  */
1851 static void
lcp_up(fsm * f)1852 lcp_up(fsm *f)
1853 {
1854     lcp_options *wo = &lcp_wantoptions[f->unit];
1855     lcp_options *ho = &lcp_hisoptions[f->unit];
1856     lcp_options *go = &lcp_gotoptions[f->unit];
1857     lcp_options *ao = &lcp_allowoptions[f->unit];
1858     int mtu, mru;
1859 
1860     if (!go->neg_magicnumber)
1861 	go->magicnumber = 0;
1862     if (!ho->neg_magicnumber)
1863 	ho->magicnumber = 0;
1864 
1865     /*
1866      * Set our MTU to the smaller of the MTU we wanted and
1867      * the MRU our peer wanted.  If we negotiated an MRU,
1868      * set our MRU to the larger of value we wanted and
1869      * the value we got in the negotiation.
1870      * Note on the MTU: the link MTU can be the MRU the peer wanted,
1871      * the interface MTU is set to the lowest of that, the
1872      * MTU we want to use, and our link MRU.
1873      */
1874     mtu = ho->neg_mru? ho->mru: PPP_MRU;
1875     mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU;
1876 #ifdef HAVE_MULTILINK
1877     if (!(multilink && go->neg_mrru && ho->neg_mrru))
1878 #endif /* HAVE_MULTILINK */
1879 	netif_set_mtu(f->unit, MIN(MIN(mtu, mru), ao->mru));
1880     ppp_send_config(f->unit, mtu,
1881 		    (ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
1882 		    ho->neg_pcompression, ho->neg_accompression);
1883     ppp_recv_config(f->unit, mru,
1884 		    (lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff),
1885 		    go->neg_pcompression, go->neg_accompression);
1886 
1887     if (ho->neg_mru)
1888 	peer_mru[f->unit] = ho->mru;
1889 
1890     lcp_echo_lowerup(f->unit);  /* Enable echo messages */
1891 
1892     link_established(f->unit);
1893 }
1894 
1895 
1896 /*
1897  * lcp_down - LCP has gone DOWN.
1898  *
1899  * Alert other protocols.
1900  */
1901 static void
lcp_down(fsm * f)1902 lcp_down(fsm *f)
1903 {
1904     lcp_options *go = &lcp_gotoptions[f->unit];
1905 
1906     lcp_echo_lowerdown(f->unit);
1907 
1908     link_down(f->unit);
1909 
1910     ppp_send_config(f->unit, PPP_MRU, 0xffffffff, 0, 0);
1911     ppp_recv_config(f->unit, PPP_MRU,
1912 		    (go->neg_asyncmap? go->asyncmap: 0xffffffff),
1913 		    go->neg_pcompression, go->neg_accompression);
1914     peer_mru[f->unit] = PPP_MRU;
1915 }
1916 
1917 
1918 /*
1919  * lcp_starting - LCP needs the lower layer up.
1920  */
1921 static void
lcp_starting(fsm * f)1922 lcp_starting(fsm *f)
1923 {
1924     link_required(f->unit);
1925 }
1926 
1927 
1928 /*
1929  * lcp_finished - LCP has finished with the lower layer.
1930  */
1931 static void
lcp_finished(fsm * f)1932 lcp_finished(fsm *f)
1933 {
1934     link_terminated(f->unit);
1935 }
1936 
1937 
1938 /*
1939  * lcp_printpkt - print the contents of an LCP packet.
1940  */
1941 static char *lcp_codenames[] = {
1942     "ConfReq", "ConfAck", "ConfNak", "ConfRej",
1943     "TermReq", "TermAck", "CodeRej", "ProtRej",
1944     "EchoReq", "EchoRep", "DiscReq", "Ident",
1945     "TimeRem"
1946 };
1947 
1948 static int
lcp_printpkt(u_char * p,int plen,void (* printer)(void *,char *,...),void * arg)1949 lcp_printpkt(u_char *p, int plen, void (*printer)(void *, char *, ...), void *arg)
1950 {
1951     int code, id, len, olen, i;
1952     u_char *pstart, *optend;
1953     u_short cishort;
1954     u_int32_t cilong;
1955 
1956     if (plen < HEADERLEN)
1957 	return 0;
1958     pstart = p;
1959     GETCHAR(code, p);
1960     GETCHAR(id, p);
1961     GETSHORT(len, p);
1962     if (len < HEADERLEN || len > plen)
1963 	return 0;
1964 
1965     if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *))
1966 	printer(arg, " %s", lcp_codenames[code-1]);
1967     else
1968 	printer(arg, " code=0x%x", code);
1969     printer(arg, " id=0x%x", id);
1970     len -= HEADERLEN;
1971     switch (code) {
1972     case CONFREQ:
1973     case CONFACK:
1974     case CONFNAK:
1975     case CONFREJ:
1976 	/* print option list */
1977 	while (len >= 2) {
1978 	    GETCHAR(code, p);
1979 	    GETCHAR(olen, p);
1980 	    p -= 2;
1981 	    if (olen < 2 || olen > len) {
1982 		break;
1983 	    }
1984 	    printer(arg, " <");
1985 	    len -= olen;
1986 	    optend = p + olen;
1987 	    switch (code) {
1988 	    case CI_MRU:
1989 		if (olen == CILEN_SHORT) {
1990 		    p += 2;
1991 		    GETSHORT(cishort, p);
1992 		    printer(arg, "mru %d", cishort);
1993 		}
1994 		break;
1995 	    case CI_ASYNCMAP:
1996 		if (olen == CILEN_LONG) {
1997 		    p += 2;
1998 		    GETLONG(cilong, p);
1999 		    printer(arg, "asyncmap 0x%x", cilong);
2000 		}
2001 		break;
2002 	    case CI_AUTHTYPE:
2003 		if (olen >= CILEN_SHORT) {
2004 		    p += 2;
2005 		    printer(arg, "auth ");
2006 		    GETSHORT(cishort, p);
2007 		    switch (cishort) {
2008 		    case PPP_PAP:
2009 			printer(arg, "pap");
2010 			break;
2011 		    case PPP_CHAP:
2012 			printer(arg, "chap");
2013 			if (p < optend) {
2014 			    switch (*p) {
2015 			    case CHAP_MD5:
2016 				printer(arg, " MD5");
2017 				++p;
2018 				break;
2019 			    case CHAP_MICROSOFT:
2020 				printer(arg, " MS");
2021 				++p;
2022 				break;
2023 
2024 			    case CHAP_MICROSOFT_V2:
2025 				printer(arg, " MS-v2");
2026 				++p;
2027 				break;
2028 			    }
2029 			}
2030 			break;
2031 		    case PPP_EAP:
2032 			printer(arg, "eap");
2033 			break;
2034 		    default:
2035 			printer(arg, "0x%x", cishort);
2036 		    }
2037 		}
2038 		break;
2039 	    case CI_QUALITY:
2040 		if (olen >= CILEN_SHORT) {
2041 		    p += 2;
2042 		    printer(arg, "quality ");
2043 		    GETSHORT(cishort, p);
2044 		    switch (cishort) {
2045 		    case PPP_LQR:
2046 			printer(arg, "lqr");
2047 			break;
2048 		    default:
2049 			printer(arg, "0x%x", cishort);
2050 		    }
2051 		}
2052 		break;
2053 	    case CI_CALLBACK:
2054 		if (olen >= CILEN_CHAR) {
2055 		    p += 2;
2056 		    printer(arg, "callback ");
2057 		    GETCHAR(cishort, p);
2058 		    switch (cishort) {
2059 		    case CBCP_OPT:
2060 			printer(arg, "CBCP");
2061 			break;
2062 		    default:
2063 			printer(arg, "0x%x", cishort);
2064 		    }
2065 		}
2066 		break;
2067 	    case CI_MAGICNUMBER:
2068 		if (olen == CILEN_LONG) {
2069 		    p += 2;
2070 		    GETLONG(cilong, p);
2071 		    printer(arg, "magic 0x%x", cilong);
2072 		}
2073 		break;
2074 	    case CI_PCOMPRESSION:
2075 		if (olen == CILEN_VOID) {
2076 		    p += 2;
2077 		    printer(arg, "pcomp");
2078 		}
2079 		break;
2080 	    case CI_ACCOMPRESSION:
2081 		if (olen == CILEN_VOID) {
2082 		    p += 2;
2083 		    printer(arg, "accomp");
2084 		}
2085 		break;
2086 	    case CI_MRRU:
2087 		if (olen == CILEN_SHORT) {
2088 		    p += 2;
2089 		    GETSHORT(cishort, p);
2090 		    printer(arg, "mrru %d", cishort);
2091 		}
2092 		break;
2093 	    case CI_SSNHF:
2094 		if (olen == CILEN_VOID) {
2095 		    p += 2;
2096 		    printer(arg, "ssnhf");
2097 		}
2098 		break;
2099 	    case CI_EPDISC:
2100 #ifdef HAVE_MULTILINK
2101 		if (olen >= CILEN_CHAR) {
2102 		    struct epdisc epd;
2103 		    p += 2;
2104 		    GETCHAR(epd.class, p);
2105 		    epd.length = olen - CILEN_CHAR;
2106 		    if (epd.length > MAX_ENDP_LEN)
2107 			epd.length = MAX_ENDP_LEN;
2108 		    if (epd.length > 0) {
2109 			BCOPY(p, epd.value, epd.length);
2110 			p += epd.length;
2111 		    }
2112 		    printer(arg, "endpoint [%s]", epdisc_to_str(&epd));
2113 		}
2114 #else
2115 		printer(arg, "endpoint");
2116 #endif
2117 		break;
2118 	    }
2119 	    while (p < optend) {
2120 		GETCHAR(code, p);
2121 		printer(arg, " %.2x", code);
2122 	    }
2123 	    printer(arg, ">");
2124 	}
2125 	break;
2126 
2127     case TERMACK:
2128     case TERMREQ:
2129 	if (len > 0 && *p >= ' ' && *p < 0x7f) {
2130 	    printer(arg, " ");
2131 	    print_string((char *)p, len, printer, arg);
2132 	    p += len;
2133 	    len = 0;
2134 	}
2135 	break;
2136 
2137     case ECHOREQ:
2138     case ECHOREP:
2139     case DISCREQ:
2140 	if (len >= 4) {
2141 	    GETLONG(cilong, p);
2142 	    printer(arg, " magic=0x%x", cilong);
2143 	    len -= 4;
2144 	}
2145 	break;
2146 
2147     case IDENTIF:
2148     case TIMEREM:
2149 	if (len >= 4) {
2150 	    GETLONG(cilong, p);
2151 	    printer(arg, " magic=0x%x", cilong);
2152 	    len -= 4;
2153 	}
2154 	if (code == TIMEREM) {
2155 	    if (len < 4)
2156 		break;
2157 	    GETLONG(cilong, p);
2158 	    printer(arg, " seconds=%u", cilong);
2159 	    len -= 4;
2160 	}
2161 	if (len > 0) {
2162 	    printer(arg, " ");
2163 	    print_string((char *)p, len, printer, arg);
2164 	    p += len;
2165 	    len = 0;
2166 	}
2167 	break;
2168     }
2169 
2170     /* print the rest of the bytes in the packet */
2171     for (i = 0; i < len && i < 32; ++i) {
2172 	GETCHAR(code, p);
2173 	printer(arg, " %.2x", code);
2174     }
2175     if (i < len) {
2176 	printer(arg, " ...");
2177 	p += len - i;
2178     }
2179 
2180     return p - pstart;
2181 }
2182 
2183 /*
2184  * Time to shut down the link because there is nothing out there.
2185  */
2186 
2187 static
LcpLinkFailure(fsm * f)2188 void LcpLinkFailure (fsm *f)
2189 {
2190     if (f->state == OPENED) {
2191 	info("No response to %d echo-requests", lcp_echos_pending);
2192         notice("Serial link appears to be disconnected.");
2193 	status = EXIT_PEER_DEAD;
2194 	lcp_close(f->unit, "Peer not responding");
2195     }
2196 }
2197 
2198 /*
2199  * Timer expired for the LCP echo requests from this process.
2200  */
2201 
2202 static void
LcpEchoCheck(fsm * f)2203 LcpEchoCheck (fsm *f)
2204 {
2205     LcpSendEchoRequest (f);
2206     if (f->state != OPENED)
2207 	return;
2208 
2209     /*
2210      * Start the timer for the next interval.
2211      */
2212     if (lcp_echo_timer_running)
2213 	warn("assertion lcp_echo_timer_running==0 failed");
2214     TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);
2215     lcp_echo_timer_running = 1;
2216 }
2217 
2218 /*
2219  * LcpEchoTimeout - Timer expired on the LCP echo
2220  */
2221 
2222 static void
LcpEchoTimeout(void * arg)2223 LcpEchoTimeout (void *arg)
2224 {
2225     if (lcp_echo_timer_running != 0) {
2226         lcp_echo_timer_running = 0;
2227         LcpEchoCheck ((fsm *) arg);
2228     }
2229 }
2230 
2231 /*
2232  * LcpEchoReply - LCP has received a reply to the echo
2233  */
2234 
2235 static void
lcp_received_echo_reply(fsm * f,int id,u_char * inp,int len)2236 lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len)
2237 {
2238     u_int32_t magic;
2239 
2240     /* Check the magic number - don't count replies from ourselves. */
2241     if (len < 4) {
2242 	dbglog("lcp: received short Echo-Reply, length %d", len);
2243 	return;
2244     }
2245     GETLONG(magic, inp);
2246     if (lcp_gotoptions[f->unit].neg_magicnumber
2247 	&& magic == lcp_gotoptions[f->unit].magicnumber) {
2248 	warn("appear to have received our own echo-reply!");
2249 	return;
2250     }
2251 
2252     /* Reset the number of outstanding echo frames */
2253     lcp_echos_pending = 0;
2254 }
2255 
2256 /*
2257  * LcpSendEchoRequest - Send an echo request frame to the peer
2258  */
2259 
2260 static void
LcpSendEchoRequest(fsm * f)2261 LcpSendEchoRequest (fsm *f)
2262 {
2263     u_int32_t lcp_magic;
2264     u_char pkt[4], *pktp;
2265 
2266     /*
2267      * Detect the failure of the peer at this point.
2268      */
2269     if (lcp_echo_fails != 0) {
2270         if (lcp_echos_pending >= lcp_echo_fails) {
2271             LcpLinkFailure(f);
2272 	    lcp_echos_pending = 0;
2273 	}
2274     }
2275 
2276     /*
2277      * If adaptive echos have been enabled, only send the echo request if
2278      * no traffic was received since the last one.
2279      */
2280     if (lcp_echo_adaptive) {
2281 	static unsigned int last_pkts_in = 0;
2282 	struct pppd_stats cur_stats;
2283 
2284 	if (get_ppp_stats(f->unit, &cur_stats) && cur_stats.pkts_in != last_pkts_in) {
2285 	    last_pkts_in = cur_stats.pkts_in;
2286 	    return;
2287 	}
2288     }
2289 
2290     /*
2291      * Make and send the echo request frame.
2292      */
2293     if (f->state == OPENED) {
2294         lcp_magic = lcp_gotoptions[f->unit].magicnumber;
2295 	pktp = pkt;
2296 	PUTLONG(lcp_magic, pktp);
2297         fsm_sdata(f, ECHOREQ, lcp_echo_number++ & 0xFF, pkt, pktp - pkt);
2298 	++lcp_echos_pending;
2299     }
2300 }
2301 
2302 /*
2303  * lcp_echo_lowerup - Start the timer for the LCP frame
2304  */
2305 
2306 static void
lcp_echo_lowerup(int unit)2307 lcp_echo_lowerup (int unit)
2308 {
2309     fsm *f = &lcp_fsm[unit];
2310 
2311     /* Clear the parameters for generating echo frames */
2312     lcp_echos_pending      = 0;
2313     lcp_echo_number        = 0;
2314     lcp_echo_timer_running = 0;
2315 
2316     /* If a timeout interval is specified then start the timer */
2317     if (lcp_echo_interval != 0)
2318         LcpEchoCheck (f);
2319 }
2320 
2321 /*
2322  * lcp_echo_lowerdown - Stop the timer for the LCP frame
2323  */
2324 
2325 static void
lcp_echo_lowerdown(int unit)2326 lcp_echo_lowerdown (int unit)
2327 {
2328     fsm *f = &lcp_fsm[unit];
2329 
2330     if (lcp_echo_timer_running != 0) {
2331         UNTIMEOUT (LcpEchoTimeout, f);
2332         lcp_echo_timer_running = 0;
2333     }
2334 }
2335