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