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