xref: /openbsd/usr.sbin/pppd/lcp.c (revision db3296cf)
1 /*	$OpenBSD: lcp.c,v 1.9 2002/07/01 19:31:37 deraadt 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 #ifndef lint
46 #if 0
47 static char rcsid[] = "Id: lcp.c,v 1.31 1997/11/27 06:08:44 paulus Exp $";
48 #else
49 static char rcsid[] = "$OpenBSD: lcp.c,v 1.9 2002/07/01 19:31:37 deraadt Exp $";
50 #endif
51 #endif
52 
53 /*
54  * TODO:
55  */
56 
57 #include <stdio.h>
58 #include <string.h>
59 #include <syslog.h>
60 #include <assert.h>
61 #include <sys/ioctl.h>
62 #include <sys/types.h>
63 #include <sys/socket.h>
64 #include <sys/time.h>
65 #include <netinet/in.h>
66 
67 #include "pppd.h"
68 #include "fsm.h"
69 #include "lcp.h"
70 #include "chap.h"
71 #include "magic.h"
72 
73 /* global vars */
74 fsm lcp_fsm[NUM_PPP];			/* LCP fsm structure (global)*/
75 lcp_options lcp_wantoptions[NUM_PPP];	/* Options that we want to request */
76 lcp_options lcp_gotoptions[NUM_PPP];	/* Options that peer ack'd */
77 lcp_options lcp_allowoptions[NUM_PPP];	/* Options we allow peer to request */
78 lcp_options lcp_hisoptions[NUM_PPP];	/* Options that we ack'd */
79 u_int32_t xmit_accm[NUM_PPP][8];		/* extended transmit ACCM */
80 
81 static u_int32_t lcp_echos_pending = 0;	/* Number of outstanding echo msgs */
82 static u_int32_t lcp_echo_number   = 0;	/* ID number of next echo frame */
83 static u_int32_t lcp_echo_timer_running = 0;  /* TRUE if a timer is running */
84 
85 static u_char nak_buffer[PPP_MRU];	/* where we construct a nak packet */
86 
87 /*
88  * Callbacks for fsm code.  (CI = Configuration Information)
89  */
90 static void lcp_resetci(fsm *);		/* Reset our CI */
91 static int  lcp_cilen(fsm *);		/* Return length of our CI */
92 static void lcp_addci(fsm *, u_char *, int *); /* Add our CI to pkt */
93 static int  lcp_ackci(fsm *, u_char *, int); /* Peer ack'd our CI */
94 static int  lcp_nakci(fsm *, u_char *, int); /* Peer nak'd our CI */
95 static int  lcp_rejci(fsm *, u_char *, int); /* Peer rej'd our CI */
96 static int  lcp_reqci(fsm *, u_char *, int *, int); /* Rcv peer CI */
97 static void lcp_up(fsm *);		/* We're UP */
98 static void lcp_down(fsm *);		/* We're DOWN */
99 static void lcp_starting(fsm *);	/* We need lower layer up */
100 static void lcp_finished(fsm *);	/* We need lower layer down */
101 static int  lcp_extcode(fsm *, int, int, u_char *, int);
102 static void lcp_rprotrej(fsm *, u_char *, int);
103 
104 /*
105  * routines to send LCP echos to peer
106  */
107 
108 static void lcp_echo_lowerup(int);
109 static void lcp_echo_lowerdown(int);
110 static void LcpEchoTimeout(void *);
111 static void lcp_received_echo_reply(fsm *, int, u_char *, int);
112 static void LcpSendEchoRequest(fsm *);
113 static void LcpLinkFailure(fsm *);
114 static void LcpEchoCheck(fsm *);
115 
116 static fsm_callbacks lcp_callbacks = {	/* LCP callback routines */
117     lcp_resetci,		/* Reset our Configuration Information */
118     lcp_cilen,			/* Length of our Configuration Information */
119     lcp_addci,			/* Add our Configuration Information */
120     lcp_ackci,			/* ACK our Configuration Information */
121     lcp_nakci,			/* NAK our Configuration Information */
122     lcp_rejci,			/* Reject our Configuration Information */
123     lcp_reqci,			/* Request peer's Configuration Information */
124     lcp_up,			/* Called when fsm reaches OPENED state */
125     lcp_down,			/* Called when fsm leaves OPENED state */
126     lcp_starting,		/* Called when we want the lower layer up */
127     lcp_finished,		/* Called when we want the lower layer down */
128     NULL,			/* Called when Protocol-Reject received */
129     NULL,			/* Retransmission is necessary */
130     lcp_extcode,		/* Called to handle LCP-specific codes */
131     "LCP"			/* String name of protocol */
132 };
133 
134 /*
135  * Protocol entry points.
136  * Some of these are called directly.
137  */
138 
139 static void lcp_init(int);
140 static void lcp_input(int, u_char *, int);
141 static void lcp_protrej(int);
142 static int  lcp_printpkt(u_char *, int, void (*)(void *, char *, ...), void *);
143 
144 struct protent lcp_protent = {
145     PPP_LCP,
146     lcp_init,
147     lcp_input,
148     lcp_protrej,
149     lcp_lowerup,
150     lcp_lowerdown,
151     lcp_open,
152     lcp_close,
153     lcp_printpkt,
154     NULL,
155     1,
156     "LCP",
157     NULL,
158     NULL,
159     NULL
160 };
161 
162 int lcp_loopbackfail = DEFLOOPBACKFAIL;
163 
164 /*
165  * Length of each type of configuration option (in octets)
166  */
167 #define CILEN_VOID	2
168 #define CILEN_CHAR	3
169 #define CILEN_SHORT	4	/* CILEN_VOID + sizeof(short) */
170 #define CILEN_CHAP	5	/* CILEN_VOID + sizeof(short) + 1 */
171 #define CILEN_LONG	6	/* CILEN_VOID + sizeof(long) */
172 #define CILEN_LQR	8	/* CILEN_VOID + sizeof(short) + sizeof(long) */
173 #define CILEN_CBCP	3
174 
175 #define CODENAME(x)	((x) == CONFACK ? "ACK" : \
176 			 (x) == CONFNAK ? "NAK" : "REJ")
177 
178 
179 /*
180  * lcp_init - Initialize LCP.
181  */
182 static void
183 lcp_init(unit)
184     int unit;
185 {
186     fsm *f = &lcp_fsm[unit];
187     lcp_options *wo = &lcp_wantoptions[unit];
188     lcp_options *ao = &lcp_allowoptions[unit];
189 
190     f->unit = unit;
191     f->protocol = PPP_LCP;
192     f->callbacks = &lcp_callbacks;
193 
194     fsm_init(f);
195 
196     wo->passive = 0;
197     wo->silent = 0;
198     wo->restart = 0;			/* Set to 1 in kernels or multi-line
199 					   implementations */
200     wo->neg_mru = 1;
201     wo->mru = DEFMRU;
202     wo->neg_asyncmap = 0;
203     wo->asyncmap = 0;
204     wo->neg_chap = 0;			/* Set to 1 on server */
205     wo->neg_upap = 0;			/* Set to 1 on server */
206     wo->chap_mdtype = CHAP_DIGEST_MD5;
207     wo->neg_magicnumber = 1;
208     wo->neg_pcompression = 1;
209     wo->neg_accompression = 1;
210     wo->neg_lqr = 0;			/* no LQR implementation yet */
211     wo->neg_cbcp = 0;
212 
213     ao->neg_mru = 1;
214     ao->mru = MAXMRU;
215     ao->neg_asyncmap = 1;
216     ao->asyncmap = 0;
217     ao->neg_chap = 1;
218     ao->chap_mdtype = CHAP_DIGEST_MD5;
219     ao->neg_upap = 1;
220     ao->neg_magicnumber = 1;
221     ao->neg_pcompression = 1;
222     ao->neg_accompression = 1;
223     ao->neg_lqr = 0;			/* no LQR implementation yet */
224 #ifdef CBCP_SUPPORT
225     ao->neg_cbcp = 1;
226 #else
227     ao->neg_cbcp = 0;
228 #endif
229 
230     memset(xmit_accm[unit], 0, sizeof(xmit_accm[0]));
231     xmit_accm[unit][3] = 0x60000000;
232 }
233 
234 
235 /*
236  * lcp_open - LCP is allowed to come up.
237  */
238 void
239 lcp_open(unit)
240     int unit;
241 {
242     fsm *f = &lcp_fsm[unit];
243     lcp_options *wo = &lcp_wantoptions[unit];
244 
245     f->flags = 0;
246     if (wo->passive)
247 	f->flags |= OPT_PASSIVE;
248     if (wo->silent)
249 	f->flags |= OPT_SILENT;
250     fsm_open(f);
251 }
252 
253 
254 /*
255  * lcp_close - Take LCP down.
256  */
257 void
258 lcp_close(unit, reason)
259     int unit;
260     char *reason;
261 {
262     fsm *f = &lcp_fsm[unit];
263 
264     if (phase != PHASE_DEAD)
265 	phase = PHASE_TERMINATE;
266     if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) {
267 	/*
268 	 * This action is not strictly according to the FSM in RFC1548,
269 	 * but it does mean that the program terminates if you do a
270 	 * lcp_close() in passive/silent mode when a connection hasn't
271 	 * been established.
272 	 */
273 	f->state = CLOSED;
274 	lcp_finished(f);
275 
276     } else
277 	fsm_close(&lcp_fsm[unit], reason);
278 }
279 
280 
281 /*
282  * lcp_lowerup - The lower layer is up.
283  */
284 void
285 lcp_lowerup(unit)
286     int unit;
287 {
288     lcp_options *wo = &lcp_wantoptions[unit];
289 
290     /*
291      * Don't use A/C or protocol compression on transmission,
292      * but accept A/C and protocol compressed packets
293      * if we are going to ask for A/C and protocol compression.
294      */
295     ppp_set_xaccm(unit, xmit_accm[unit]);
296     ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0);
297     ppp_recv_config(unit, PPP_MRU, 0xffffffff,
298 		    wo->neg_pcompression, wo->neg_accompression);
299     peer_mru[unit] = PPP_MRU;
300     lcp_allowoptions[unit].asyncmap = xmit_accm[unit][0];
301 
302     fsm_lowerup(&lcp_fsm[unit]);
303 }
304 
305 
306 /*
307  * lcp_lowerdown - The lower layer is down.
308  */
309 void
310 lcp_lowerdown(unit)
311     int unit;
312 {
313     fsm_lowerdown(&lcp_fsm[unit]);
314 }
315 
316 
317 /*
318  * lcp_input - Input LCP packet.
319  */
320 static void
321 lcp_input(unit, p, len)
322     int unit;
323     u_char *p;
324     int len;
325 {
326     fsm *f = &lcp_fsm[unit];
327 
328     fsm_input(f, p, len);
329 }
330 
331 
332 /*
333  * lcp_extcode - Handle a LCP-specific code.
334  */
335 static int
336 lcp_extcode(f, code, id, inp, len)
337     fsm *f;
338     int code, id;
339     u_char *inp;
340     int len;
341 {
342     u_char *magp;
343 
344     switch( code ){
345     case PROTREJ:
346 	lcp_rprotrej(f, inp, len);
347 	break;
348 
349     case ECHOREQ:
350 	if (f->state != OPENED)
351 	    break;
352 	LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %d", id));
353 	magp = inp;
354 	PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
355 	fsm_sdata(f, ECHOREP, id, inp, len);
356 	break;
357 
358     case ECHOREP:
359 	lcp_received_echo_reply(f, id, inp, len);
360 	break;
361 
362     case DISCREQ:
363 	break;
364 
365     default:
366 	return 0;
367     }
368     return 1;
369 }
370 
371 
372 /*
373  * lcp_rprotrej - Receive an Protocol-Reject.
374  *
375  * Figure out which protocol is rejected and inform it.
376  */
377 static void
378 lcp_rprotrej(f, inp, len)
379     fsm *f;
380     u_char *inp;
381     int len;
382 {
383     int i;
384     struct protent *protp;
385     u_short prot;
386 
387     LCPDEBUG((LOG_INFO, "lcp_rprotrej."));
388 
389     if (len < sizeof (u_short)) {
390 	LCPDEBUG((LOG_INFO,
391 		  "lcp_rprotrej: Rcvd short Protocol-Reject packet!"));
392 	return;
393     }
394 
395     GETSHORT(prot, inp);
396 
397     LCPDEBUG((LOG_INFO,
398 	      "lcp_rprotrej: Rcvd Protocol-Reject packet for %x!",
399 	      prot));
400 
401     /*
402      * Protocol-Reject packets received in any state other than the LCP
403      * OPENED state SHOULD be silently discarded.
404      */
405     if( f->state != OPENED ){
406 	LCPDEBUG((LOG_INFO, "Protocol-Reject discarded: LCP in state %d",
407 		  f->state));
408 	return;
409     }
410 
411     /*
412      * Upcall the proper Protocol-Reject routine.
413      */
414     for (i = 0; (protp = protocols[i]) != NULL; ++i)
415 	if (protp->protocol == prot && protp->enabled_flag) {
416 	    (*protp->protrej)(f->unit);
417 	    return;
418 	}
419 
420     syslog(LOG_WARNING, "Protocol-Reject for unsupported protocol 0x%x",
421 	   prot);
422 }
423 
424 
425 /*
426  * lcp_protrej - A Protocol-Reject was received.
427  */
428 /*ARGSUSED*/
429 static void
430 lcp_protrej(unit)
431     int unit;
432 {
433     /*
434      * Can't reject LCP!
435      */
436     LCPDEBUG((LOG_WARNING,
437 	      "lcp_protrej: Received Protocol-Reject for LCP!"));
438     fsm_protreject(&lcp_fsm[unit]);
439 }
440 
441 
442 /*
443  * lcp_sprotrej - Send a Protocol-Reject for some protocol.
444  */
445 void
446 lcp_sprotrej(unit, p, len)
447     int unit;
448     u_char *p;
449     int len;
450 {
451     /*
452      * Send back the protocol and the information field of the
453      * rejected packet.  We only get here if LCP is in the OPENED state.
454      */
455     p += 2;
456     len -= 2;
457 
458     fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,
459 	      p, len);
460 }
461 
462 
463 /*
464  * lcp_resetci - Reset our CI.
465  */
466 static void
467 lcp_resetci(f)
468     fsm *f;
469 {
470     lcp_wantoptions[f->unit].magicnumber = magic();
471     lcp_wantoptions[f->unit].numloops = 0;
472     lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit];
473     peer_mru[f->unit] = PPP_MRU;
474     auth_reset(f->unit);
475 }
476 
477 
478 /*
479  * lcp_cilen - Return length of our CI.
480  */
481 static int
482 lcp_cilen(f)
483     fsm *f;
484 {
485     lcp_options *go = &lcp_gotoptions[f->unit];
486 
487 #define LENCIVOID(neg)	((neg) ? CILEN_VOID : 0)
488 #define LENCICHAP(neg)	((neg) ? CILEN_CHAP : 0)
489 #define LENCISHORT(neg)	((neg) ? CILEN_SHORT : 0)
490 #define LENCILONG(neg)	((neg) ? CILEN_LONG : 0)
491 #define LENCILQR(neg)	((neg) ? CILEN_LQR: 0)
492 #define LENCICBCP(neg)	((neg) ? CILEN_CBCP: 0)
493     /*
494      * NB: we only ask for one of CHAP and UPAP, even if we will
495      * accept either.
496      */
497     return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) +
498 	    LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) +
499 	    LENCICHAP(go->neg_chap) +
500 	    LENCISHORT(!go->neg_chap && go->neg_upap) +
501 	    LENCILQR(go->neg_lqr) +
502 	    LENCICBCP(go->neg_cbcp) +
503 	    LENCILONG(go->neg_magicnumber) +
504 	    LENCIVOID(go->neg_pcompression) +
505 	    LENCIVOID(go->neg_accompression));
506 }
507 
508 
509 /*
510  * lcp_addci - Add our desired CIs to a packet.
511  */
512 static void
513 lcp_addci(f, ucp, lenp)
514     fsm *f;
515     u_char *ucp;
516     int *lenp;
517 {
518     lcp_options *go = &lcp_gotoptions[f->unit];
519     u_char *start_ucp = ucp;
520 
521 #define ADDCIVOID(opt, neg) \
522     if (neg) { \
523 	PUTCHAR(opt, ucp); \
524 	PUTCHAR(CILEN_VOID, ucp); \
525     }
526 #define ADDCISHORT(opt, neg, val) \
527     if (neg) { \
528 	PUTCHAR(opt, ucp); \
529 	PUTCHAR(CILEN_SHORT, ucp); \
530 	PUTSHORT(val, ucp); \
531     }
532 #define ADDCICHAP(opt, neg, val, digest) \
533     if (neg) { \
534 	PUTCHAR(opt, ucp); \
535 	PUTCHAR(CILEN_CHAP, ucp); \
536 	PUTSHORT(val, ucp); \
537 	PUTCHAR(digest, ucp); \
538     }
539 #define ADDCILONG(opt, neg, val) \
540     if (neg) { \
541 	PUTCHAR(opt, ucp); \
542 	PUTCHAR(CILEN_LONG, ucp); \
543 	PUTLONG(val, ucp); \
544     }
545 #define ADDCILQR(opt, neg, val) \
546     if (neg) { \
547 	PUTCHAR(opt, ucp); \
548 	PUTCHAR(CILEN_LQR, ucp); \
549 	PUTSHORT(PPP_LQR, ucp); \
550 	PUTLONG(val, ucp); \
551     }
552 #define ADDCICHAR(opt, neg, val) \
553     if (neg) { \
554 	PUTCHAR(opt, ucp); \
555 	PUTCHAR(CILEN_CHAR, ucp); \
556 	PUTCHAR(val, ucp); \
557     }
558 
559     ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
560     ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
561 	      go->asyncmap);
562     ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
563     ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
564     ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
565     ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
566     ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
567     ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
568     ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
569 
570     if (ucp - start_ucp != *lenp) {
571 	/* this should never happen, because peer_mtu should be 1500 */
572 	syslog(LOG_ERR, "Bug in lcp_addci: wrong length");
573     }
574 }
575 
576 
577 /*
578  * lcp_ackci - Ack our CIs.
579  * This should not modify any state if the Ack is bad.
580  *
581  * Returns:
582  *	0 - Ack was bad.
583  *	1 - Ack was good.
584  */
585 static int
586 lcp_ackci(f, p, len)
587     fsm *f;
588     u_char *p;
589     int len;
590 {
591     lcp_options *go = &lcp_gotoptions[f->unit];
592     u_char cilen, citype, cichar;
593     u_short cishort;
594     u_int32_t cilong;
595 
596     /*
597      * CIs must be in exactly the same order that we sent.
598      * Check packet length and CI length at each step.
599      * If we find any deviations, then this packet is bad.
600      */
601 #define ACKCIVOID(opt, neg) \
602     if (neg) { \
603 	if ((len -= CILEN_VOID) < 0) \
604 	    goto bad; \
605 	GETCHAR(citype, p); \
606 	GETCHAR(cilen, p); \
607 	if (cilen != CILEN_VOID || \
608 	    citype != opt) \
609 	    goto bad; \
610     }
611 #define ACKCISHORT(opt, neg, val) \
612     if (neg) { \
613 	if ((len -= CILEN_SHORT) < 0) \
614 	    goto bad; \
615 	GETCHAR(citype, p); \
616 	GETCHAR(cilen, p); \
617 	if (cilen != CILEN_SHORT || \
618 	    citype != opt) \
619 	    goto bad; \
620 	GETSHORT(cishort, p); \
621 	if (cishort != val) \
622 	    goto bad; \
623     }
624 #define ACKCICHAR(opt, neg, val) \
625     if (neg) { \
626 	if ((len -= CILEN_CHAR) < 0) \
627 	    goto bad; \
628 	GETCHAR(citype, p); \
629 	GETCHAR(cilen, p); \
630 	if (cilen != CILEN_CHAR || \
631 	    citype != opt) \
632 	    goto bad; \
633 	GETCHAR(cichar, p); \
634 	if (cichar != val) \
635 	    goto bad; \
636     }
637 #define ACKCICHAP(opt, neg, val, digest) \
638     if (neg) { \
639 	if ((len -= CILEN_CHAP) < 0) \
640 	    goto bad; \
641 	GETCHAR(citype, p); \
642 	GETCHAR(cilen, p); \
643 	if (cilen != CILEN_CHAP || \
644 	    citype != opt) \
645 	    goto bad; \
646 	GETSHORT(cishort, p); \
647 	if (cishort != val) \
648 	    goto bad; \
649 	GETCHAR(cichar, p); \
650 	if (cichar != digest) \
651 	  goto bad; \
652     }
653 #define ACKCILONG(opt, neg, val) \
654     if (neg) { \
655 	if ((len -= CILEN_LONG) < 0) \
656 	    goto bad; \
657 	GETCHAR(citype, p); \
658 	GETCHAR(cilen, p); \
659 	if (cilen != CILEN_LONG || \
660 	    citype != opt) \
661 	    goto bad; \
662 	GETLONG(cilong, p); \
663 	if (cilong != val) \
664 	    goto bad; \
665     }
666 #define ACKCILQR(opt, neg, val) \
667     if (neg) { \
668 	if ((len -= CILEN_LQR) < 0) \
669 	    goto bad; \
670 	GETCHAR(citype, p); \
671 	GETCHAR(cilen, p); \
672 	if (cilen != CILEN_LQR || \
673 	    citype != opt) \
674 	    goto bad; \
675 	GETSHORT(cishort, p); \
676 	if (cishort != PPP_LQR) \
677 	    goto bad; \
678 	GETLONG(cilong, p); \
679 	if (cilong != val) \
680 	  goto bad; \
681     }
682 
683     ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
684     ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
685 	      go->asyncmap);
686     ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype);
687     ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
688     ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
689     ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
690     ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
691     ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
692     ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
693 
694     /*
695      * If there are any remaining CIs, then this packet is bad.
696      */
697     if (len != 0)
698 	goto bad;
699     return (1);
700 bad:
701     LCPDEBUG((LOG_WARNING, "lcp_acki: received bad Ack!"));
702     return (0);
703 }
704 
705 
706 /*
707  * lcp_nakci - Peer has sent a NAK for some of our CIs.
708  * This should not modify any state if the Nak is bad
709  * or if LCP is in the OPENED state.
710  *
711  * Returns:
712  *	0 - Nak was bad.
713  *	1 - Nak was good.
714  */
715 static int
716 lcp_nakci(f, p, len)
717     fsm *f;
718     u_char *p;
719     int len;
720 {
721     lcp_options *go = &lcp_gotoptions[f->unit];
722     lcp_options *wo = &lcp_wantoptions[f->unit];
723     u_char citype, cichar, *next;
724     u_short cishort;
725     u_int32_t cilong;
726     lcp_options no;		/* options we've seen Naks for */
727     lcp_options try;		/* options to request next time */
728     int looped_back = 0;
729     int cilen;
730 
731     BZERO(&no, sizeof(no));
732     try = *go;
733 
734     /*
735      * Any Nak'd CIs must be in exactly the same order that we sent.
736      * Check packet length and CI length at each step.
737      * If we find any deviations, then this packet is bad.
738      */
739 #define NAKCIVOID(opt, neg, code) \
740     if (go->neg && \
741 	len >= CILEN_VOID && \
742 	p[1] == CILEN_VOID && \
743 	p[0] == opt) { \
744 	len -= CILEN_VOID; \
745 	INCPTR(CILEN_VOID, p); \
746 	no.neg = 1; \
747 	code \
748     }
749 #define NAKCICHAP(opt, neg, code) \
750     if (go->neg && \
751 	len >= CILEN_CHAP && \
752 	p[1] == CILEN_CHAP && \
753 	p[0] == opt) { \
754 	len -= CILEN_CHAP; \
755 	INCPTR(2, p); \
756 	GETSHORT(cishort, p); \
757 	GETCHAR(cichar, p); \
758 	no.neg = 1; \
759 	code \
760     }
761 #define NAKCICHAR(opt, neg, code) \
762     if (go->neg && \
763 	len >= CILEN_CHAR && \
764 	p[1] == CILEN_CHAR && \
765 	p[0] == opt) { \
766 	len -= CILEN_CHAR; \
767 	INCPTR(2, p); \
768 	GETCHAR(cichar, p); \
769 	no.neg = 1; \
770 	code \
771     }
772 #define NAKCISHORT(opt, neg, code) \
773     if (go->neg && \
774 	len >= CILEN_SHORT && \
775 	p[1] == CILEN_SHORT && \
776 	p[0] == opt) { \
777 	len -= CILEN_SHORT; \
778 	INCPTR(2, p); \
779 	GETSHORT(cishort, p); \
780 	no.neg = 1; \
781 	code \
782     }
783 #define NAKCILONG(opt, neg, code) \
784     if (go->neg && \
785 	len >= CILEN_LONG && \
786 	p[1] == CILEN_LONG && \
787 	p[0] == opt) { \
788 	len -= CILEN_LONG; \
789 	INCPTR(2, p); \
790 	GETLONG(cilong, p); \
791 	no.neg = 1; \
792 	code \
793     }
794 #define NAKCILQR(opt, neg, code) \
795     if (go->neg && \
796 	len >= CILEN_LQR && \
797 	p[1] == CILEN_LQR && \
798 	p[0] == opt) { \
799 	len -= CILEN_LQR; \
800 	INCPTR(2, p); \
801 	GETSHORT(cishort, p); \
802 	GETLONG(cilong, p); \
803 	no.neg = 1; \
804 	code \
805     }
806 
807     /*
808      * We don't care if they want to send us smaller packets than
809      * we want.  Therefore, accept any MRU less than what we asked for,
810      * but then ignore the new value when setting the MRU in the kernel.
811      * If they send us a bigger MRU than what we asked, accept it, up to
812      * the limit of the default MRU we'd get if we didn't negotiate.
813      */
814     if (go->neg_mru && go->mru != DEFMRU) {
815 	NAKCISHORT(CI_MRU, neg_mru,
816 		   if (cishort <= wo->mru || cishort <= DEFMRU)
817 		       try.mru = cishort;
818 		   );
819     }
820 
821     /*
822      * Add any characters they want to our (receive-side) asyncmap.
823      */
824     if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) {
825 	NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
826 		  try.asyncmap = go->asyncmap | cilong;
827 		  );
828     }
829 
830     /*
831      * If they've nak'd our authentication-protocol, check whether
832      * they are proposing a different protocol, or a different
833      * hash algorithm for CHAP.
834      */
835     if ((go->neg_chap || go->neg_upap)
836 	&& len >= CILEN_SHORT
837 	&& p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
838 	cilen = p[1];
839 	len -= cilen;
840 	no.neg_chap = go->neg_chap;
841 	no.neg_upap = go->neg_upap;
842 	INCPTR(2, p);
843         GETSHORT(cishort, p);
844 	if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
845 	    /*
846 	     * If we were asking for CHAP, they obviously don't want to do it.
847 	     * If we weren't asking for CHAP, then we were asking for PAP,
848 	     * in which case this Nak is bad.
849 	     */
850 	    if (!go->neg_chap)
851 		goto bad;
852 	    try.neg_chap = 0;
853 
854 	} else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
855 	    GETCHAR(cichar, p);
856 	    if (go->neg_chap) {
857 		/*
858 		 * We were asking for CHAP/MD5; they must want a different
859 		 * algorithm.  If they can't do MD5, we'll have to stop
860 		 * asking for CHAP.
861 		 */
862 		if (cichar != go->chap_mdtype)
863 		    try.neg_chap = 0;
864 	    } else {
865 		/*
866 		 * Stop asking for PAP if we were asking for it.
867 		 */
868 		try.neg_upap = 0;
869 	    }
870 
871 	} else {
872 	    /*
873 	     * We don't recognize what they're suggesting.
874 	     * Stop asking for what we were asking for.
875 	     */
876 	    if (go->neg_chap)
877 		try.neg_chap = 0;
878 	    else
879 		try.neg_upap = 0;
880 	    p += cilen - CILEN_SHORT;
881 	}
882     }
883 
884     /*
885      * If they can't cope with our link quality protocol, we'll have
886      * to stop asking for LQR.  We haven't got any other protocol.
887      * If they Nak the reporting period, take their value XXX ?
888      */
889     NAKCILQR(CI_QUALITY, neg_lqr,
890 	     if (cishort != PPP_LQR)
891 		 try.neg_lqr = 0;
892 	     else
893 		 try.lqr_period = cilong;
894 	     );
895 
896     /*
897      * Only implementing CBCP...not the rest of the callback options
898      */
899     NAKCICHAR(CI_CALLBACK, neg_cbcp,
900               try.neg_cbcp = 0;
901               );
902 
903     /*
904      * Check for a looped-back line.
905      */
906     NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
907 	      try.magicnumber = magic();
908 	      looped_back = 1;
909 	      );
910 
911     /*
912      * Peer shouldn't send Nak for protocol compression or
913      * address/control compression requests; they should send
914      * a Reject instead.  If they send a Nak, treat it as a Reject.
915      */
916     NAKCIVOID(CI_PCOMPRESSION, neg_pcompression,
917 	      try.neg_pcompression = 0;
918 	      );
919     NAKCIVOID(CI_ACCOMPRESSION, neg_accompression,
920 	      try.neg_accompression = 0;
921 	      );
922 
923     /*
924      * There may be remaining CIs, if the peer is requesting negotiation
925      * on an option that we didn't include in our request packet.
926      * If we see an option that we requested, or one we've already seen
927      * in this packet, then this packet is bad.
928      * If we wanted to respond by starting to negotiate on the requested
929      * option(s), we could, but we don't, because except for the
930      * authentication type and quality protocol, if we are not negotiating
931      * an option, it is because we were told not to.
932      * For the authentication type, the Nak from the peer means
933      * `let me authenticate myself with you' which is a bit pointless.
934      * For the quality protocol, the Nak means `ask me to send you quality
935      * reports', but if we didn't ask for them, we don't want them.
936      * An option we don't recognize represents the peer asking to
937      * negotiate some option we don't support, so ignore it.
938      */
939     while (len > CILEN_VOID) {
940 	GETCHAR(citype, p);
941 	GETCHAR(cilen, p);
942 	if (cilen < CILEN_VOID || (len -= cilen) < 0)
943 	    goto bad;
944 	next = p + cilen - 2;
945 
946 	switch (citype) {
947 	case CI_MRU:
948 	    if ((go->neg_mru && go->mru != DEFMRU)
949 		|| no.neg_mru || cilen != CILEN_SHORT)
950 		goto bad;
951 	    GETSHORT(cishort, p);
952 	    if (cishort < DEFMRU)
953 		try.mru = cishort;
954 	    break;
955 	case CI_ASYNCMAP:
956 	    if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF)
957 		|| no.neg_asyncmap || cilen != CILEN_LONG)
958 		goto bad;
959 	    break;
960 	case CI_AUTHTYPE:
961 	    if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap)
962 		goto bad;
963 	    break;
964 	case CI_MAGICNUMBER:
965 	    if (go->neg_magicnumber || no.neg_magicnumber ||
966 		cilen != CILEN_LONG)
967 		goto bad;
968 	    break;
969 	case CI_PCOMPRESSION:
970 	    if (go->neg_pcompression || no.neg_pcompression
971 		|| cilen != CILEN_VOID)
972 		goto bad;
973 	    break;
974 	case CI_ACCOMPRESSION:
975 	    if (go->neg_accompression || no.neg_accompression
976 		|| cilen != CILEN_VOID)
977 		goto bad;
978 	    break;
979 	case CI_QUALITY:
980 	    if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)
981 		goto bad;
982 	    break;
983 	}
984 	p = next;
985     }
986 
987     /* If there is still anything left, this packet is bad. */
988     if (len != 0)
989 	goto bad;
990 
991     /*
992      * OK, the Nak is good.  Now we can update state.
993      */
994     if (f->state != OPENED) {
995 	if (looped_back) {
996 	    if (++try.numloops >= lcp_loopbackfail) {
997 		syslog(LOG_NOTICE, "Serial line is looped back.");
998 		lcp_close(f->unit, "Loopback detected");
999 	    }
1000 	} else
1001 	    try.numloops = 0;
1002 	*go = try;
1003     }
1004 
1005     return 1;
1006 
1007 bad:
1008     LCPDEBUG((LOG_WARNING, "lcp_nakci: received bad Nak!"));
1009     return 0;
1010 }
1011 
1012 
1013 /*
1014  * lcp_rejci - Peer has Rejected some of our CIs.
1015  * This should not modify any state if the Reject is bad
1016  * or if LCP is in the OPENED state.
1017  *
1018  * Returns:
1019  *	0 - Reject was bad.
1020  *	1 - Reject was good.
1021  */
1022 static int
1023 lcp_rejci(f, p, len)
1024     fsm *f;
1025     u_char *p;
1026     int len;
1027 {
1028     lcp_options *go = &lcp_gotoptions[f->unit];
1029     u_char cichar;
1030     u_short cishort;
1031     u_int32_t cilong;
1032     lcp_options try;		/* options to request next time */
1033 
1034     try = *go;
1035 
1036     /*
1037      * Any Rejected CIs must be in exactly the same order that we sent.
1038      * Check packet length and CI length at each step.
1039      * If we find any deviations, then this packet is bad.
1040      */
1041 #define REJCIVOID(opt, neg) \
1042     if (go->neg && \
1043 	len >= CILEN_VOID && \
1044 	p[1] == CILEN_VOID && \
1045 	p[0] == opt) { \
1046 	len -= CILEN_VOID; \
1047 	INCPTR(CILEN_VOID, p); \
1048 	try.neg = 0; \
1049 	LCPDEBUG((LOG_INFO, "lcp_rejci rejected void opt %d", opt)); \
1050     }
1051 #define REJCISHORT(opt, neg, val) \
1052     if (go->neg && \
1053 	len >= CILEN_SHORT && \
1054 	p[1] == CILEN_SHORT && \
1055 	p[0] == opt) { \
1056 	len -= CILEN_SHORT; \
1057 	INCPTR(2, p); \
1058 	GETSHORT(cishort, p); \
1059 	/* Check rejected value. */ \
1060 	if (cishort != val) \
1061 	    goto bad; \
1062 	try.neg = 0; \
1063 	LCPDEBUG((LOG_INFO,"lcp_rejci rejected short opt %d", opt)); \
1064     }
1065 #define REJCICHAP(opt, neg, val, digest) \
1066     if (go->neg && \
1067 	len >= CILEN_CHAP && \
1068 	p[1] == CILEN_CHAP && \
1069 	p[0] == opt) { \
1070 	len -= CILEN_CHAP; \
1071 	INCPTR(2, p); \
1072 	GETSHORT(cishort, p); \
1073 	GETCHAR(cichar, p); \
1074 	/* Check rejected value. */ \
1075 	if (cishort != val || cichar != digest) \
1076 	    goto bad; \
1077 	try.neg = 0; \
1078 	try.neg_upap = 0; \
1079 	LCPDEBUG((LOG_INFO,"lcp_rejci rejected chap opt %d", opt)); \
1080     }
1081 #define REJCILONG(opt, neg, val) \
1082     if (go->neg && \
1083 	len >= CILEN_LONG && \
1084 	p[1] == CILEN_LONG && \
1085 	p[0] == opt) { \
1086 	len -= CILEN_LONG; \
1087 	INCPTR(2, p); \
1088 	GETLONG(cilong, p); \
1089 	/* Check rejected value. */ \
1090 	if (cilong != val) \
1091 	    goto bad; \
1092 	try.neg = 0; \
1093 	LCPDEBUG((LOG_INFO,"lcp_rejci rejected long opt %d", opt)); \
1094     }
1095 #define REJCILQR(opt, neg, val) \
1096     if (go->neg && \
1097 	len >= CILEN_LQR && \
1098 	p[1] == CILEN_LQR && \
1099 	p[0] == opt) { \
1100 	len -= CILEN_LQR; \
1101 	INCPTR(2, p); \
1102 	GETSHORT(cishort, p); \
1103 	GETLONG(cilong, p); \
1104 	/* Check rejected value. */ \
1105 	if (cishort != PPP_LQR || cilong != val) \
1106 	    goto bad; \
1107 	try.neg = 0; \
1108 	LCPDEBUG((LOG_INFO,"lcp_rejci rejected LQR opt %d", opt)); \
1109     }
1110 #define REJCICBCP(opt, neg, val) \
1111     if (go->neg && \
1112 	len >= CILEN_CBCP && \
1113 	p[1] == CILEN_CBCP && \
1114 	p[0] == opt) { \
1115 	len -= CILEN_CBCP; \
1116 	INCPTR(2, p); \
1117 	GETCHAR(cichar, p); \
1118 	/* Check rejected value. */ \
1119 	if (cichar != val) \
1120 	    goto bad; \
1121 	try.neg = 0; \
1122 	LCPDEBUG((LOG_INFO,"lcp_rejci rejected Callback opt %d", opt)); \
1123     }
1124 
1125     REJCISHORT(CI_MRU, neg_mru, go->mru);
1126     REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
1127     REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype);
1128     if (!go->neg_chap) {
1129 	REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
1130     }
1131     REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
1132     REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
1133     REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
1134     REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
1135     REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
1136 
1137     /*
1138      * If there are any remaining CIs, then this packet is bad.
1139      */
1140     if (len != 0)
1141 	goto bad;
1142     /*
1143      * Now we can update state.
1144      */
1145     if (f->state != OPENED)
1146 	*go = try;
1147     return 1;
1148 
1149 bad:
1150     LCPDEBUG((LOG_WARNING, "lcp_rejci: received bad Reject!"));
1151     return 0;
1152 }
1153 
1154 
1155 /*
1156  * lcp_reqci - Check the peer's requested CIs and send appropriate response.
1157  *
1158  * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
1159  * appropriately.  If reject_if_disagree is non-zero, doesn't return
1160  * CONFNAK; returns CONFREJ if it can't return CONFACK.
1161  */
1162 static int
1163 lcp_reqci(f, inp, lenp, reject_if_disagree)
1164     fsm *f;
1165     u_char *inp;		/* Requested CIs */
1166     int *lenp;			/* Length of requested CIs */
1167     int reject_if_disagree;
1168 {
1169     lcp_options *go = &lcp_gotoptions[f->unit];
1170     lcp_options *ho = &lcp_hisoptions[f->unit];
1171     lcp_options *ao = &lcp_allowoptions[f->unit];
1172     u_char *cip, *next;		/* Pointer to current and next CIs */
1173     int cilen, citype, cichar;	/* Parsed len, type, char value */
1174     u_short cishort;		/* Parsed short value */
1175     u_int32_t cilong;		/* Parse long value */
1176     int rc = CONFACK;		/* Final packet return code */
1177     int orc;			/* Individual option return code */
1178     u_char *p;			/* Pointer to next char to parse */
1179     u_char *rejp;		/* Pointer to next char in reject frame */
1180     u_char *nakp;		/* Pointer to next char in Nak frame */
1181     int l = *lenp;		/* Length left */
1182 
1183     /*
1184      * Reset all his options.
1185      */
1186     BZERO(ho, sizeof(*ho));
1187 
1188     /*
1189      * Process all his options.
1190      */
1191     next = inp;
1192     nakp = nak_buffer;
1193     rejp = inp;
1194     while (l) {
1195 	orc = CONFACK;			/* Assume success */
1196 	cip = p = next;			/* Remember begining of CI */
1197 	if (l < 2 ||			/* Not enough data for CI header or */
1198 	    p[1] < 2 ||			/*  CI length too small or */
1199 	    p[1] > l) {			/*  CI length too big? */
1200 	    LCPDEBUG((LOG_WARNING, "lcp_reqci: bad CI length!"));
1201 	    orc = CONFREJ;		/* Reject bad CI */
1202 	    cilen = l;			/* Reject till end of packet */
1203 	    l = 0;			/* Don't loop again */
1204 	    citype = 0;
1205 	    goto endswitch;
1206 	}
1207 	GETCHAR(citype, p);		/* Parse CI type */
1208 	GETCHAR(cilen, p);		/* Parse CI length */
1209 	l -= cilen;			/* Adjust remaining length */
1210 	next += cilen;			/* Step to next CI */
1211 
1212 	switch (citype) {		/* Check CI type */
1213 	case CI_MRU:
1214 	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd MRU"));
1215 	    if (!ao->neg_mru ||		/* Allow option? */
1216 		cilen != CILEN_SHORT) {	/* Check CI length */
1217 		orc = CONFREJ;		/* Reject CI */
1218 		break;
1219 	    }
1220 	    GETSHORT(cishort, p);	/* Parse MRU */
1221 	    LCPDEBUG((LOG_INFO, "(%d)", cishort));
1222 
1223 	    /*
1224 	     * He must be able to receive at least our minimum.
1225 	     * No need to check a maximum.  If he sends a large number,
1226 	     * we'll just ignore it.
1227 	     */
1228 	    if (cishort < MINMRU) {
1229 		orc = CONFNAK;		/* Nak CI */
1230 		PUTCHAR(CI_MRU, nakp);
1231 		PUTCHAR(CILEN_SHORT, nakp);
1232 		PUTSHORT(MINMRU, nakp);	/* Give him a hint */
1233 		break;
1234 	    }
1235 	    ho->neg_mru = 1;		/* Remember he sent MRU */
1236 	    ho->mru = cishort;		/* And remember value */
1237 	    break;
1238 
1239 	case CI_ASYNCMAP:
1240 	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd ASYNCMAP"));
1241 	    if (!ao->neg_asyncmap ||
1242 		cilen != CILEN_LONG) {
1243 		orc = CONFREJ;
1244 		break;
1245 	    }
1246 	    GETLONG(cilong, p);
1247 	    LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong));
1248 
1249 	    /*
1250 	     * Asyncmap must have set at least the bits
1251 	     * which are set in lcp_allowoptions[unit].asyncmap.
1252 	     */
1253 	    if ((ao->asyncmap & ~cilong) != 0) {
1254 		orc = CONFNAK;
1255 		PUTCHAR(CI_ASYNCMAP, nakp);
1256 		PUTCHAR(CILEN_LONG, nakp);
1257 		PUTLONG(ao->asyncmap | cilong, nakp);
1258 		break;
1259 	    }
1260 	    ho->neg_asyncmap = 1;
1261 	    ho->asyncmap = cilong;
1262 	    break;
1263 
1264 	case CI_AUTHTYPE:
1265 	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd AUTHTYPE"));
1266 	    if (cilen < CILEN_SHORT ||
1267 		!(ao->neg_upap || ao->neg_chap)) {
1268 		/*
1269 		 * Reject the option if we're not willing to authenticate.
1270 		 */
1271 		orc = CONFREJ;
1272 		break;
1273 	    }
1274 	    GETSHORT(cishort, p);
1275 	    LCPDEBUG((LOG_INFO, "(%x)", cishort));
1276 
1277 	    /*
1278 	     * Authtype must be UPAP or CHAP.
1279 	     *
1280 	     * Note: if both ao->neg_upap and ao->neg_chap are set,
1281 	     * and the peer sends a Configure-Request with two
1282 	     * authenticate-protocol requests, one for CHAP and one
1283 	     * for UPAP, then we will reject the second request.
1284 	     * Whether we end up doing CHAP or UPAP depends then on
1285 	     * the ordering of the CIs in the peer's Configure-Request.
1286 	     */
1287 
1288 	    if (cishort == PPP_PAP) {
1289 		if (ho->neg_chap ||	/* we've already accepted CHAP */
1290 		    cilen != CILEN_SHORT) {
1291 		    LCPDEBUG((LOG_WARNING,
1292 			      "lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));
1293 		    orc = CONFREJ;
1294 		    break;
1295 		}
1296 		if (!ao->neg_upap) {	/* we don't want to do PAP */
1297 		    orc = CONFNAK;	/* NAK it and suggest CHAP */
1298 		    PUTCHAR(CI_AUTHTYPE, nakp);
1299 		    PUTCHAR(CILEN_CHAP, nakp);
1300 		    PUTSHORT(PPP_CHAP, nakp);
1301 		    PUTCHAR(ao->chap_mdtype, nakp);
1302 		    break;
1303 		}
1304 		ho->neg_upap = 1;
1305 		break;
1306 	    }
1307 	    if (cishort == PPP_CHAP) {
1308 		if (ho->neg_upap ||	/* we've already accepted PAP */
1309 		    cilen != CILEN_CHAP) {
1310 		    LCPDEBUG((LOG_INFO,
1311 			      "lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));
1312 		    orc = CONFREJ;
1313 		    break;
1314 		}
1315 		if (!ao->neg_chap) {	/* we don't want to do CHAP */
1316 		    orc = CONFNAK;	/* NAK it and suggest PAP */
1317 		    PUTCHAR(CI_AUTHTYPE, nakp);
1318 		    PUTCHAR(CILEN_SHORT, nakp);
1319 		    PUTSHORT(PPP_PAP, nakp);
1320 		    break;
1321 		}
1322 		GETCHAR(cichar, p);	/* get digest type*/
1323 		if (cichar != CHAP_DIGEST_MD5
1324 #ifdef CHAPMS
1325 		    && cichar != CHAP_MICROSOFT
1326 #endif
1327 		    ) {
1328 		    orc = CONFNAK;
1329 		    PUTCHAR(CI_AUTHTYPE, nakp);
1330 		    PUTCHAR(CILEN_CHAP, nakp);
1331 		    PUTSHORT(PPP_CHAP, nakp);
1332 		    PUTCHAR(ao->chap_mdtype, nakp);
1333 		    break;
1334 		}
1335 		ho->chap_mdtype = cichar; /* save md type */
1336 		ho->neg_chap = 1;
1337 		break;
1338 	    }
1339 
1340 	    /*
1341 	     * We don't recognize the protocol they're asking for.
1342 	     * Nak it with something we're willing to do.
1343 	     * (At this point we know ao->neg_upap || ao->neg_chap.)
1344 	     */
1345 	    orc = CONFNAK;
1346 	    PUTCHAR(CI_AUTHTYPE, nakp);
1347 	    if (ao->neg_chap) {
1348 		PUTCHAR(CILEN_CHAP, nakp);
1349 		PUTSHORT(PPP_CHAP, nakp);
1350 		PUTCHAR(ao->chap_mdtype, nakp);
1351 	    } else {
1352 		PUTCHAR(CILEN_SHORT, nakp);
1353 		PUTSHORT(PPP_PAP, nakp);
1354 	    }
1355 	    break;
1356 
1357 	case CI_QUALITY:
1358 	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd QUALITY"));
1359 	    if (!ao->neg_lqr ||
1360 		cilen != CILEN_LQR) {
1361 		orc = CONFREJ;
1362 		break;
1363 	    }
1364 
1365 	    GETSHORT(cishort, p);
1366 	    GETLONG(cilong, p);
1367 	    LCPDEBUG((LOG_INFO, "(%x %x)", cishort, (unsigned int) cilong));
1368 
1369 	    /*
1370 	     * Check the protocol and the reporting period.
1371 	     * XXX When should we Nak this, and what with?
1372 	     */
1373 	    if (cishort != PPP_LQR) {
1374 		orc = CONFNAK;
1375 		PUTCHAR(CI_QUALITY, nakp);
1376 		PUTCHAR(CILEN_LQR, nakp);
1377 		PUTSHORT(PPP_LQR, nakp);
1378 		PUTLONG(ao->lqr_period, nakp);
1379 		break;
1380 	    }
1381 	    break;
1382 
1383 	case CI_MAGICNUMBER:
1384 	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd MAGICNUMBER"));
1385 	    if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
1386 		cilen != CILEN_LONG) {
1387 		orc = CONFREJ;
1388 		break;
1389 	    }
1390 	    GETLONG(cilong, p);
1391 	    LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong));
1392 
1393 	    /*
1394 	     * He must have a different magic number.
1395 	     */
1396 	    if (go->neg_magicnumber &&
1397 		cilong == go->magicnumber) {
1398 		cilong = magic();	/* Don't put magic() inside macro! */
1399 		orc = CONFNAK;
1400 		PUTCHAR(CI_MAGICNUMBER, nakp);
1401 		PUTCHAR(CILEN_LONG, nakp);
1402 		PUTLONG(cilong, nakp);
1403 		break;
1404 	    }
1405 	    ho->neg_magicnumber = 1;
1406 	    ho->magicnumber = cilong;
1407 	    break;
1408 
1409 
1410 	case CI_PCOMPRESSION:
1411 	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd PCOMPRESSION"));
1412 	    if (!ao->neg_pcompression ||
1413 		cilen != CILEN_VOID) {
1414 		orc = CONFREJ;
1415 		break;
1416 	    }
1417 	    ho->neg_pcompression = 1;
1418 	    break;
1419 
1420 	case CI_ACCOMPRESSION:
1421 	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd ACCOMPRESSION"));
1422 	    if (!ao->neg_accompression ||
1423 		cilen != CILEN_VOID) {
1424 		orc = CONFREJ;
1425 		break;
1426 	    }
1427 	    ho->neg_accompression = 1;
1428 	    break;
1429 
1430 	default:
1431 	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd unknown option %d",
1432 		      citype));
1433 	    orc = CONFREJ;
1434 	    break;
1435 	}
1436 
1437 endswitch:
1438 	LCPDEBUG((LOG_INFO, " (%s)", CODENAME(orc)));
1439 	if (orc == CONFACK &&		/* Good CI */
1440 	    rc != CONFACK)		/*  but prior CI wasnt? */
1441 	    continue;			/* Don't send this one */
1442 
1443 	if (orc == CONFNAK) {		/* Nak this CI? */
1444 	    if (reject_if_disagree	/* Getting fed up with sending NAKs? */
1445 		&& citype != CI_MAGICNUMBER) {
1446 		orc = CONFREJ;		/* Get tough if so */
1447 	    } else {
1448 		if (rc == CONFREJ)	/* Rejecting prior CI? */
1449 		    continue;		/* Don't send this one */
1450 		rc = CONFNAK;
1451 	    }
1452 	}
1453 	if (orc == CONFREJ) {		/* Reject this CI */
1454 	    rc = CONFREJ;
1455 	    if (cip != rejp)		/* Need to move rejected CI? */
1456 		BCOPY(cip, rejp, cilen); /* Move it */
1457 	    INCPTR(cilen, rejp);	/* Update output pointer */
1458 	}
1459     }
1460 
1461     /*
1462      * If we wanted to send additional NAKs (for unsent CIs), the
1463      * code would go here.  The extra NAKs would go at *nakp.
1464      * At present there are no cases where we want to ask the
1465      * peer to negotiate an option.
1466      */
1467 
1468     switch (rc) {
1469     case CONFACK:
1470 	*lenp = next - inp;
1471 	break;
1472     case CONFNAK:
1473 	/*
1474 	 * Copy the Nak'd options from the nak_buffer to the caller's buffer.
1475 	 */
1476 	*lenp = nakp - nak_buffer;
1477 	BCOPY(nak_buffer, inp, *lenp);
1478 	break;
1479     case CONFREJ:
1480 	*lenp = rejp - inp;
1481 	break;
1482     }
1483 
1484     LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.", CODENAME(rc)));
1485     return (rc);			/* Return final code */
1486 }
1487 
1488 
1489 /*
1490  * lcp_up - LCP has come UP.
1491  */
1492 static void
1493 lcp_up(f)
1494     fsm *f;
1495 {
1496     lcp_options *wo = &lcp_wantoptions[f->unit];
1497     lcp_options *ho = &lcp_hisoptions[f->unit];
1498     lcp_options *go = &lcp_gotoptions[f->unit];
1499     lcp_options *ao = &lcp_allowoptions[f->unit];
1500 
1501     if (!go->neg_magicnumber)
1502 	go->magicnumber = 0;
1503     if (!ho->neg_magicnumber)
1504 	ho->magicnumber = 0;
1505 
1506     /*
1507      * Set our MTU to the smaller of the MTU we wanted and
1508      * the MRU our peer wanted.  If we negotiated an MRU,
1509      * set our MRU to the larger of value we wanted and
1510      * the value we got in the negotiation.
1511      */
1512     ppp_send_config(f->unit, MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)),
1513 		    (ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
1514 		    ho->neg_pcompression, ho->neg_accompression);
1515     ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU),
1516 		    (go->neg_asyncmap? go->asyncmap: 0xffffffff),
1517 		    go->neg_pcompression, go->neg_accompression);
1518 
1519     if (ho->neg_mru)
1520 	peer_mru[f->unit] = ho->mru;
1521 
1522     lcp_echo_lowerup(f->unit);  /* Enable echo messages */
1523 
1524     link_established(f->unit);
1525 }
1526 
1527 
1528 /*
1529  * lcp_down - LCP has gone DOWN.
1530  *
1531  * Alert other protocols.
1532  */
1533 static void
1534 lcp_down(f)
1535     fsm *f;
1536 {
1537     lcp_options *go = &lcp_gotoptions[f->unit];
1538 
1539     lcp_echo_lowerdown(f->unit);
1540 
1541     link_down(f->unit);
1542 
1543     ppp_send_config(f->unit, PPP_MRU, 0xffffffff, 0, 0);
1544     ppp_recv_config(f->unit, PPP_MRU,
1545 		    (go->neg_asyncmap? go->asyncmap: 0xffffffff),
1546 		    go->neg_pcompression, go->neg_accompression);
1547     peer_mru[f->unit] = PPP_MRU;
1548 }
1549 
1550 
1551 /*
1552  * lcp_starting - LCP needs the lower layer up.
1553  */
1554 static void
1555 lcp_starting(f)
1556     fsm *f;
1557 {
1558     link_required(f->unit);
1559 }
1560 
1561 
1562 /*
1563  * lcp_finished - LCP has finished with the lower layer.
1564  */
1565 static void
1566 lcp_finished(f)
1567     fsm *f;
1568 {
1569     link_terminated(f->unit);
1570 }
1571 
1572 
1573 /*
1574  * lcp_printpkt - print the contents of an LCP packet.
1575  */
1576 static char *lcp_codenames[] = {
1577     "ConfReq", "ConfAck", "ConfNak", "ConfRej",
1578     "TermReq", "TermAck", "CodeRej", "ProtRej",
1579     "EchoReq", "EchoRep", "DiscReq"
1580 };
1581 
1582 static int
1583 lcp_printpkt(p, plen, printer, arg)
1584     u_char *p;
1585     int plen;
1586     void (*printer)(void *, char *, ...);
1587     void *arg;
1588 {
1589     int code, id, len, olen;
1590     u_char *pstart, *optend;
1591     u_short cishort;
1592     u_int32_t cilong;
1593 
1594     if (plen < HEADERLEN)
1595 	return 0;
1596     pstart = p;
1597     GETCHAR(code, p);
1598     GETCHAR(id, p);
1599     GETSHORT(len, p);
1600     if (len < HEADERLEN || len > plen)
1601 	return 0;
1602 
1603     if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *))
1604 	printer(arg, " %s", lcp_codenames[code-1]);
1605     else
1606 	printer(arg, " code=0x%x", code);
1607     printer(arg, " id=0x%x", id);
1608     len -= HEADERLEN;
1609     switch (code) {
1610     case CONFREQ:
1611     case CONFACK:
1612     case CONFNAK:
1613     case CONFREJ:
1614 	/* print option list */
1615 	while (len >= 2) {
1616 	    GETCHAR(code, p);
1617 	    GETCHAR(olen, p);
1618 	    p -= 2;
1619 	    if (olen < 2 || olen > len) {
1620 		break;
1621 	    }
1622 	    printer(arg, " <");
1623 	    len -= olen;
1624 	    optend = p + olen;
1625 	    switch (code) {
1626 	    case CI_MRU:
1627 		if (olen == CILEN_SHORT) {
1628 		    p += 2;
1629 		    GETSHORT(cishort, p);
1630 		    printer(arg, "mru %d", cishort);
1631 		}
1632 		break;
1633 	    case CI_ASYNCMAP:
1634 		if (olen == CILEN_LONG) {
1635 		    p += 2;
1636 		    GETLONG(cilong, p);
1637 		    printer(arg, "asyncmap 0x%x", cilong);
1638 		}
1639 		break;
1640 	    case CI_AUTHTYPE:
1641 		if (olen >= CILEN_SHORT) {
1642 		    p += 2;
1643 		    printer(arg, "auth ");
1644 		    GETSHORT(cishort, p);
1645 		    switch (cishort) {
1646 		    case PPP_PAP:
1647 			printer(arg, "pap");
1648 			break;
1649 		    case PPP_CHAP:
1650 			printer(arg, "chap");
1651 			break;
1652 		    default:
1653 			printer(arg, "0x%x", cishort);
1654 		    }
1655 		}
1656 		break;
1657 	    case CI_QUALITY:
1658 		if (olen >= CILEN_SHORT) {
1659 		    p += 2;
1660 		    printer(arg, "quality ");
1661 		    GETSHORT(cishort, p);
1662 		    switch (cishort) {
1663 		    case PPP_LQR:
1664 			printer(arg, "lqr");
1665 			break;
1666 		    default:
1667 			printer(arg, "0x%x", cishort);
1668 		    }
1669 		}
1670 		break;
1671 	    case CI_CALLBACK:
1672 		if (olen >= CILEN_CHAR) {
1673 		    p += 2;
1674 		    printer(arg, "callback ");
1675 		    GETSHORT(cishort, p);
1676 		    switch (cishort) {
1677 		    case CBCP_OPT:
1678 			printer(arg, "CBCP");
1679 			break;
1680 		    default:
1681 			printer(arg, "0x%x", cishort);
1682 		    }
1683 		}
1684 		break;
1685 	    case CI_MAGICNUMBER:
1686 		if (olen == CILEN_LONG) {
1687 		    p += 2;
1688 		    GETLONG(cilong, p);
1689 		    printer(arg, "magic 0x%x", cilong);
1690 		}
1691 		break;
1692 	    case CI_PCOMPRESSION:
1693 		if (olen == CILEN_VOID) {
1694 		    p += 2;
1695 		    printer(arg, "pcomp");
1696 		}
1697 		break;
1698 	    case CI_ACCOMPRESSION:
1699 		if (olen == CILEN_VOID) {
1700 		    p += 2;
1701 		    printer(arg, "accomp");
1702 		}
1703 		break;
1704 	    }
1705 	    while (p < optend) {
1706 		GETCHAR(code, p);
1707 		printer(arg, " %.2x", code);
1708 	    }
1709 	    printer(arg, ">");
1710 	}
1711 	break;
1712 
1713     case TERMACK:
1714     case TERMREQ:
1715 	if (len > 0 && *p >= ' ' && *p < 0x7f) {
1716 	    printer(arg, " ");
1717 	    print_string(p, len, printer, arg);
1718 	    p += len;
1719 	    len = 0;
1720 	}
1721 	break;
1722 
1723     case ECHOREQ:
1724     case ECHOREP:
1725     case DISCREQ:
1726 	if (len >= 4) {
1727 	    GETLONG(cilong, p);
1728 	    printer(arg, " magic=0x%x", cilong);
1729 	    p += 4;
1730 	    len -= 4;
1731 	}
1732 	break;
1733     }
1734 
1735     /* print the rest of the bytes in the packet */
1736     for (; len > 0; --len) {
1737 	GETCHAR(code, p);
1738 	printer(arg, " %.2x", code);
1739     }
1740 
1741     return p - pstart;
1742 }
1743 
1744 /*
1745  * Time to shut down the link because there is nothing out there.
1746  */
1747 
1748 static
1749 void LcpLinkFailure (f)
1750     fsm *f;
1751 {
1752     if (f->state == OPENED) {
1753 	syslog(LOG_INFO, "No response to %d echo-requests", lcp_echos_pending);
1754         syslog(LOG_NOTICE, "Serial link appears to be disconnected.");
1755         lcp_close(f->unit, "Peer not responding");
1756     }
1757 }
1758 
1759 /*
1760  * Timer expired for the LCP echo requests from this process.
1761  */
1762 
1763 static void
1764 LcpEchoCheck (f)
1765     fsm *f;
1766 {
1767     LcpSendEchoRequest (f);
1768 
1769     /*
1770      * Start the timer for the next interval.
1771      */
1772     assert (lcp_echo_timer_running==0);
1773     TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);
1774     lcp_echo_timer_running = 1;
1775 }
1776 
1777 /*
1778  * LcpEchoTimeout - Timer expired on the LCP echo
1779  */
1780 
1781 static void
1782 LcpEchoTimeout (arg)
1783     void *arg;
1784 {
1785     if (lcp_echo_timer_running != 0) {
1786         lcp_echo_timer_running = 0;
1787         LcpEchoCheck ((fsm *) arg);
1788     }
1789 }
1790 
1791 /*
1792  * LcpEchoReply - LCP has received a reply to the echo
1793  */
1794 
1795 static void
1796 lcp_received_echo_reply (f, id, inp, len)
1797     fsm *f;
1798     int id; u_char *inp; int len;
1799 {
1800     u_int32_t magic;
1801 
1802     /* Check the magic number - don't count replies from ourselves. */
1803     if (len < 4) {
1804 	syslog(LOG_DEBUG, "lcp: received short Echo-Reply, length %d", len);
1805 	return;
1806     }
1807     GETLONG(magic, inp);
1808     if (lcp_gotoptions[f->unit].neg_magicnumber
1809 	&& magic == lcp_gotoptions[f->unit].magicnumber) {
1810 	syslog(LOG_WARNING, "appear to have received our own echo-reply!");
1811 	return;
1812     }
1813 
1814     /* Reset the number of outstanding echo frames */
1815     lcp_echos_pending = 0;
1816 }
1817 
1818 /*
1819  * LcpSendEchoRequest - Send an echo request frame to the peer
1820  */
1821 
1822 static void
1823 LcpSendEchoRequest (f)
1824     fsm *f;
1825 {
1826     u_int32_t lcp_magic;
1827     u_char pkt[4], *pktp;
1828 
1829     /*
1830      * Detect the failure of the peer at this point.
1831      */
1832     if (lcp_echo_fails != 0) {
1833         if (lcp_echos_pending >= lcp_echo_fails) {
1834             LcpLinkFailure(f);
1835 	    lcp_echos_pending = 0;
1836 	}
1837     }
1838 
1839     /*
1840      * Make and send the echo request frame.
1841      */
1842     if (f->state == OPENED) {
1843         lcp_magic = lcp_gotoptions[f->unit].magicnumber;
1844 	pktp = pkt;
1845 	PUTLONG(lcp_magic, pktp);
1846         fsm_sdata(f, ECHOREQ, lcp_echo_number++ & 0xFF, pkt, pktp - pkt);
1847 	++lcp_echos_pending;
1848     }
1849 }
1850 
1851 /*
1852  * lcp_echo_lowerup - Start the timer for the LCP frame
1853  */
1854 
1855 static void
1856 lcp_echo_lowerup (unit)
1857     int unit;
1858 {
1859     fsm *f = &lcp_fsm[unit];
1860 
1861     /* Clear the parameters for generating echo frames */
1862     lcp_echos_pending      = 0;
1863     lcp_echo_number        = 0;
1864     lcp_echo_timer_running = 0;
1865 
1866     /* If a timeout interval is specified then start the timer */
1867     if (lcp_echo_interval != 0)
1868         LcpEchoCheck (f);
1869 }
1870 
1871 /*
1872  * lcp_echo_lowerdown - Stop the timer for the LCP frame
1873  */
1874 
1875 static void
1876 lcp_echo_lowerdown (unit)
1877     int unit;
1878 {
1879     fsm *f = &lcp_fsm[unit];
1880 
1881     if (lcp_echo_timer_running != 0) {
1882         UNTIMEOUT (LcpEchoTimeout, f);
1883         lcp_echo_timer_running = 0;
1884     }
1885 }
1886