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