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