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