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