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