]> git.ozlabs.org Git - ppp.git/blob - pppd/lcp.c
Initial revision
[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.1 1993/11/11 03:54:25 paulus Exp $";
22 #endif
23
24 /*
25  * TODO:
26  * Option tracing.
27  * Test restart.
28  */
29
30 #include <stdio.h>
31 #include <syslog.h>
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <sys/time.h>
36
37 #include <net/if.h>
38 #include <net/if_ppp.h>
39 #include <netinet/in.h>
40
41 #include <string.h>
42
43 #include "pppd.h"
44 #include "ppp.h"
45 #include "fsm.h"
46 #include "lcp.h"
47 #include "magic.h"
48 #include "chap.h"
49 #include "upap.h"
50 #include "ipcp.h"
51
52 /* global vars */
53 fsm lcp_fsm[NPPP];                      /* LCP fsm structure (global)*/
54 lcp_options lcp_wantoptions[NPPP];      /* Options that we want to request */
55 lcp_options lcp_gotoptions[NPPP];       /* Options that peer ack'd */
56 lcp_options lcp_allowoptions[NPPP];     /* Options we allow peer to request */
57 lcp_options lcp_hisoptions[NPPP];       /* Options that we ack'd */
58
59 /*
60  * Callbacks for fsm code.  (CI = Configuration Information)
61  */
62 static void lcp_resetci __ARGS((fsm *));        /* Reset our CI */
63 static int  lcp_cilen __ARGS((fsm *));          /* Return length of our CI */
64 static void lcp_addci __ARGS((fsm *, u_char *, int *)); /* Add our CI to pkt */
65 static int  lcp_ackci __ARGS((fsm *, u_char *, int)); /* Peer ack'd our CI */
66 static int  lcp_nakci __ARGS((fsm *, u_char *, int)); /* Peer nak'd our CI */
67 static int  lcp_rejci __ARGS((fsm *, u_char *, int)); /* Peer rej'd our CI */
68 static int  lcp_reqci __ARGS((fsm *, u_char *, int *, int)); /* Rcv peer CI */
69 static void lcp_up __ARGS((fsm *));             /* We're UP */
70 static void lcp_down __ARGS((fsm *));           /* We're DOWN */
71 static void lcp_starting __ARGS((fsm *));       /* We need lower layer up */
72 static void lcp_finished __ARGS((fsm *));       /* We need lower layer down */
73 static int  lcp_extcode __ARGS((fsm *, int, int, u_char *, int));
74 static void lcp_rprotrej __ARGS((fsm *, u_char *, int));
75
76 static fsm_callbacks lcp_callbacks = {  /* LCP callback routines */
77     lcp_resetci,                /* Reset our Configuration Information */
78     lcp_cilen,                  /* Length of our Configuration Information */
79     lcp_addci,                  /* Add our Configuration Information */
80     lcp_ackci,                  /* ACK our Configuration Information */
81     lcp_nakci,                  /* NAK our Configuration Information */
82     lcp_rejci,                  /* Reject our Configuration Information */
83     lcp_reqci,                  /* Request peer's Configuration Information */
84     lcp_up,                     /* Called when fsm reaches OPENED state */
85     lcp_down,                   /* Called when fsm leaves OPENED state */
86     lcp_starting,               /* Called when we want the lower layer up */
87     lcp_finished,               /* Called when we want the lower layer down */
88     NULL,                       /* Called when Protocol-Reject received */
89     NULL,                       /* Retransmission is necessary */
90     lcp_extcode,                /* Called to handle LCP-specific codes */
91     "LCP"                       /* String name of protocol */
92 };
93
94 int lcp_warnloops = DEFWARNLOOPS; /* Warn about a loopback this often */
95
96 /*
97  * Length of each type of configuration option (in octets)
98  */
99 #define CILEN_VOID      2
100 #define CILEN_SHORT     4       /* CILEN_VOID + sizeof(short) */
101 #define CILEN_CHAP      5       /* CILEN_VOID + sizeof(short) + 1 */
102 #define CILEN_LONG      6       /* CILEN_VOID + sizeof(long) */
103 #define CILEN_LQR       8       /* CILEN_VOID + sizeof(short) + sizeof(long) */
104
105 #define CODENAME(x)     ((x) == CONFACK ? "ACK" : \
106                          (x) == CONFNAK ? "NAK" : "REJ")
107
108
109 /*
110  * lcp_init - Initialize LCP.
111  */
112 void
113 lcp_init(unit)
114     int unit;
115 {
116     fsm *f = &lcp_fsm[unit];
117     lcp_options *wo = &lcp_wantoptions[unit];
118     lcp_options *ao = &lcp_allowoptions[unit];
119
120     f->unit = unit;
121     f->protocol = LCP;
122     f->callbacks = &lcp_callbacks;
123
124     fsm_init(f);
125
126     wo->passive = 0;
127     wo->silent = 0;
128     wo->restart = 0;                    /* Set to 1 in kernels or multi-line
129                                            implementations */
130     wo->neg_mru = 1;
131     wo->mru = DEFMRU;
132     wo->neg_asyncmap = 1;
133     wo->asyncmap = 0;
134     wo->neg_chap = 0;                   /* Set to 1 on server */
135     wo->neg_upap = 0;                   /* Set to 1 on server */
136     wo->chap_mdtype = CHAP_DIGEST_MD5;
137     wo->neg_magicnumber = 1;
138     wo->neg_pcompression = 1;
139     wo->neg_accompression = 1;
140     wo->neg_lqr = 0;                    /* no LQR implementation yet */
141
142     ao->neg_mru = 1;
143     ao->mru = MAXMRU;
144     ao->neg_asyncmap = 1;
145     ao->asyncmap = 0;
146     ao->neg_chap = 1;
147     ao->chap_mdtype = CHAP_DIGEST_MD5;
148     ao->neg_upap = 1;
149     ao->neg_magicnumber = 1;
150     ao->neg_pcompression = 1;
151     ao->neg_accompression = 1;
152     ao->neg_lqr = 0;                    /* no LQR implementation yet */
153
154 }
155
156
157 /*
158  * lcp_open - LCP is allowed to come up.
159  */
160 void
161 lcp_open(unit)
162     int unit;
163 {
164     fsm *f = &lcp_fsm[unit];
165     lcp_options *wo = &lcp_wantoptions[unit];
166
167     f->flags = 0;
168     if (wo->passive)
169         f->flags |= OPT_PASSIVE;
170     if (wo->silent)
171         f->flags |= OPT_SILENT;
172     fsm_open(f);
173 }
174
175
176 /*
177  * lcp_close - Take LCP down.
178  */
179 void
180 lcp_close(unit)
181     int unit;
182 {
183     fsm_close(&lcp_fsm[unit]);
184 }
185
186
187 /*
188  * lcp_lowerup - The lower layer is up.
189  */
190 void
191 lcp_lowerup(unit)
192     int unit;
193 {
194     sifdown(unit);
195     ppp_send_config(unit, MTU, 0xffffffff, 0, 0);
196     ppp_recv_config(unit, MTU, 0, 0, 0);
197     peer_mru[unit] = MTU;
198
199     fsm_lowerup(&lcp_fsm[unit]);
200 }
201
202
203 /*
204  * lcp_lowerdown - The lower layer is down.
205  */
206 void
207 lcp_lowerdown(unit)
208     int unit;
209 {
210     fsm_lowerdown(&lcp_fsm[unit]);
211 }
212
213
214 /*
215  * lcp_input - Input LCP packet.
216  */
217 void
218 lcp_input(unit, p, len)
219     int unit;
220     u_char *p;
221     int len;
222 {
223     fsm_input(&lcp_fsm[unit], p, len);
224 }
225
226
227 /*
228  * lcp_extcode - Handle a LCP-specific code.
229  */
230 static int
231 lcp_extcode(f, code, id, inp, len)
232     fsm *f;
233     int code, id;
234     u_char *inp;
235     int len;
236 {
237     switch( code ){
238     case PROTREJ:
239         lcp_rprotrej(f, inp, len);
240         break;
241     
242     case ECHOREQ:
243         if( f->state != OPENED )
244             break;
245         LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %d", id));
246         fsm_sdata(f, ECHOREP, id, inp, len);
247         break;
248     
249     case ECHOREP:
250     case DISCREQ:
251         break;
252
253     default:
254         return 0;
255     }
256     return 1;
257 }
258
259     
260 /*
261  * lcp_rprotrej - Receive an Protocol-Reject.
262  *
263  * Figure out which protocol is rejected and inform it.
264  */
265 static void
266 lcp_rprotrej(f, inp, len)
267     fsm *f;
268     u_char *inp;
269     int len;
270 {
271     u_short prot;
272
273     LCPDEBUG((LOG_INFO, "lcp_rprotrej."));
274
275     if (len < sizeof (u_short)) {
276         LCPDEBUG((LOG_INFO,
277                   "lcp_rprotrej: Rcvd short Protocol-Reject packet!"));
278         return;
279     }
280
281     GETSHORT(prot, inp);
282
283     LCPDEBUG((LOG_INFO,
284               "lcp_rprotrej: Rcvd Protocol-Reject packet for %x!",
285               prot));
286
287     /*
288      * Protocol-Reject packets received in any state other than the LCP
289      * OPENED state SHOULD be silently discarded.
290      */
291     if( f->state != OPENED ){
292         LCPDEBUG((LOG_INFO, "Protocol-Reject discarded: LCP in state %d",
293                   f->state));
294         return;
295     }
296
297     DEMUXPROTREJ(f->unit, prot);        /* Inform protocol */
298 }
299
300
301 /*
302  * lcp_protrej - A Protocol-Reject was received.
303  */
304 /*ARGSUSED*/
305 void
306 lcp_protrej(unit)
307     int unit;
308 {
309     /*
310      * Can't reject LCP!
311      */
312     LCPDEBUG((LOG_WARNING,
313               "lcp_protrej: Received Protocol-Reject for LCP!"));
314     fsm_protreject(&lcp_fsm[unit]);
315 }
316
317
318 /*
319  * lcp_sprotrej - Send a Protocol-Reject for some protocol.
320  */
321 void
322 lcp_sprotrej(unit, p, len)
323     int unit;
324     u_char *p;
325     int len;
326 {
327     /*
328      * Send back the protocol and the information field of the
329      * rejected packet.  We only get here if LCP is in the OPENED state.
330      */
331     p += 2;
332     len -= 2;
333
334     fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,
335               p, len);
336 }
337
338
339 /*
340  * lcp_resetci - Reset our CI.
341  */
342 static void
343   lcp_resetci(f)
344 fsm *f;
345 {
346     lcp_wantoptions[f->unit].magicnumber = magic();
347     lcp_wantoptions[f->unit].numloops = 0;
348     lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit];
349     peer_mru[f->unit] = MTU;
350 }
351
352
353 /*
354  * lcp_cilen - Return length of our CI.
355  */
356 static int
357 lcp_cilen(f)
358     fsm *f;
359 {
360     lcp_options *go = &lcp_gotoptions[f->unit];
361
362 #define LENCIVOID(neg)  (neg ? CILEN_VOID : 0)
363 #define LENCICHAP(neg)  (neg ? CILEN_CHAP : 0)
364 #define LENCISHORT(neg) (neg ? CILEN_SHORT : 0)
365 #define LENCILONG(neg)  (neg ? CILEN_LONG : 0)
366 #define LENCILQR(neg)   (neg ? CILEN_LQR: 0)
367     /*
368      * NB: we only ask for one of CHAP and UPAP, even if we will
369      * accept either.
370      */
371     return (LENCISHORT(go->neg_mru) +
372             LENCILONG(go->neg_asyncmap) +
373             LENCICHAP(go->neg_chap) +
374             LENCISHORT(!go->neg_chap && go->neg_upap) +
375             LENCILQR(go->neg_lqr) +
376             LENCILONG(go->neg_magicnumber) +
377             LENCIVOID(go->neg_pcompression) +
378             LENCIVOID(go->neg_accompression));
379 }
380
381
382 /*
383  * lcp_addci - Add our desired CIs to a packet.
384  */
385 static void
386 lcp_addci(f, ucp, lenp)
387     fsm *f;
388     u_char *ucp;
389     int *lenp;
390 {
391     lcp_options *go = &lcp_gotoptions[f->unit];
392     u_char *start_ucp = ucp;
393
394 #define ADDCIVOID(opt, neg) \
395     if (neg) { \
396         PUTCHAR(opt, ucp); \
397         PUTCHAR(CILEN_VOID, ucp); \
398     }
399 #define ADDCISHORT(opt, neg, val) \
400     if (neg) { \
401         PUTCHAR(opt, ucp); \
402         PUTCHAR(CILEN_SHORT, ucp); \
403         PUTSHORT(val, ucp); \
404     }
405 #define ADDCICHAP(opt, neg, val, digest) \
406     if (neg) { \
407         PUTCHAR(opt, ucp); \
408         PUTCHAR(CILEN_CHAP, ucp); \
409         PUTSHORT(val, ucp); \
410         PUTCHAR(digest, ucp); \
411     }
412 #define ADDCILONG(opt, neg, val) \
413     if (neg) { \
414         PUTCHAR(opt, ucp); \
415         PUTCHAR(CILEN_LONG, ucp); \
416         PUTLONG(val, ucp); \
417     }
418 #define ADDCILQR(opt, neg, val) \
419     if (neg) { \
420         PUTCHAR(opt, ucp); \
421         PUTCHAR(CILEN_LQR, ucp); \
422         PUTSHORT(LQR, ucp); \
423         PUTLONG(val, ucp); \
424     }
425
426     ADDCISHORT(CI_MRU, go->neg_mru, go->mru);
427     ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap, go->asyncmap);
428     ADDCICHAP(CI_AUTHTYPE, go->neg_chap, CHAP, go->chap_mdtype);
429     ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, UPAP);
430     ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
431     ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
432     ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
433     ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
434
435     if (ucp - start_ucp != *lenp) {
436         /* this should never happen, because peer_mtu should be 1500 */
437         syslog(LOG_ERR, "Bug in lcp_addci: wrong length");
438     }
439 }
440
441
442 /*
443  * lcp_ackci - Ack our CIs.
444  * This should not modify any state if the Ack is bad.
445  *
446  * Returns:
447  *      0 - Ack was bad.
448  *      1 - Ack was good.
449  */
450 static int
451 lcp_ackci(f, p, len)
452     fsm *f;
453     u_char *p;
454     int len;
455 {
456     lcp_options *go = &lcp_gotoptions[f->unit];
457     u_char cilen, citype, cichar;
458     u_short cishort;
459     u_long cilong;
460
461     /*
462      * CIs must be in exactly the same order that we sent.
463      * Check packet length and CI length at each step.
464      * If we find any deviations, then this packet is bad.
465      */
466 #define ACKCIVOID(opt, neg) \
467     if (neg) { \
468         if ((len -= CILEN_VOID) < 0) \
469             goto bad; \
470         GETCHAR(citype, p); \
471         GETCHAR(cilen, p); \
472         if (cilen != CILEN_VOID || \
473             citype != opt) \
474             goto bad; \
475     }
476 #define ACKCISHORT(opt, neg, val) \
477     if (neg) { \
478         if ((len -= CILEN_SHORT) < 0) \
479             goto bad; \
480         GETCHAR(citype, p); \
481         GETCHAR(cilen, p); \
482         if (cilen != CILEN_SHORT || \
483             citype != opt) \
484             goto bad; \
485         GETSHORT(cishort, p); \
486         if (cishort != val) \
487             goto bad; \
488     }
489 #define ACKCICHAP(opt, neg, val, digest) \
490     if (neg) { \
491         if ((len -= CILEN_CHAP) < 0) \
492             goto bad; \
493         GETCHAR(citype, p); \
494         GETCHAR(cilen, p); \
495         if (cilen != CILEN_CHAP || \
496             citype != opt) \
497             goto bad; \
498         GETSHORT(cishort, p); \
499         if (cishort != val) \
500             goto bad; \
501         GETCHAR(cichar, p); \
502         if (cichar != digest) \
503           goto bad; \
504     }
505 #define ACKCILONG(opt, neg, val) \
506     if (neg) { \
507         if ((len -= CILEN_LONG) < 0) \
508             goto bad; \
509         GETCHAR(citype, p); \
510         GETCHAR(cilen, p); \
511         if (cilen != CILEN_LONG || \
512             citype != opt) \
513             goto bad; \
514         GETLONG(cilong, p); \
515         if (cilong != val) \
516             goto bad; \
517     }
518 #define ACKCILQR(opt, neg, val) \
519     if (neg) { \
520         if ((len -= CILEN_LQR) < 0) \
521             goto bad; \
522         GETCHAR(citype, p); \
523         GETCHAR(cilen, p); \
524         if (cilen != CILEN_LQR || \
525             citype != opt) \
526             goto bad; \
527         GETSHORT(cishort, p); \
528         if (cishort != LQR) \
529             goto bad; \
530         GETLONG(cilong, p); \
531         if (cilong != val) \
532           goto bad; \
533     }
534
535     ACKCISHORT(CI_MRU, go->neg_mru, go->mru);
536     ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap, go->asyncmap);
537     ACKCICHAP(CI_AUTHTYPE, go->neg_chap, CHAP, go->chap_mdtype);
538     ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, UPAP);
539     ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
540     ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
541     ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
542     ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
543
544     /*
545      * If there are any remaining CIs, then this packet is bad.
546      */
547     if (len != 0)
548         goto bad;
549     return (1);
550 bad:
551     LCPDEBUG((LOG_WARNING, "lcp_acki: received bad Ack!"));
552     return (0);
553 }
554
555
556 /*
557  * lcp_nakci - Peer has sent a NAK for some of our CIs.
558  * This should not modify any state if the Nak is bad
559  * or if LCP is in the OPENED state.
560  *
561  * Returns:
562  *      0 - Nak was bad.
563  *      1 - Nak was good.
564  */
565 static int
566 lcp_nakci(f, p, len)
567     fsm *f;
568     u_char *p;
569     int len;
570 {
571     lcp_options *go = &lcp_gotoptions[f->unit];
572     lcp_options *wo = &lcp_wantoptions[f->unit];
573     u_char cilen, citype, cichar, *next;
574     u_short cishort;
575     u_long cilong;
576     lcp_options no;             /* options we've seen Naks for */
577     lcp_options try;            /* options to request next time */
578     int looped_back = 0;
579
580     BZERO(&no, sizeof(no));
581     try = *go;
582
583     /*
584      * Any Nak'd CIs must be in exactly the same order that we sent.
585      * Check packet length and CI length at each step.
586      * If we find any deviations, then this packet is bad.
587      */
588 #define NAKCIVOID(opt, neg, code) \
589     if (go->neg && \
590         len >= CILEN_VOID && \
591         p[1] == CILEN_VOID && \
592         p[0] == opt) { \
593         len -= CILEN_VOID; \
594         INCPTR(CILEN_VOID, p); \
595         no.neg = 1; \
596         code \
597     }
598 #define NAKCICHAP(opt, neg, code) \
599     if (go->neg && \
600         len >= CILEN_CHAP && \
601         p[1] == CILEN_CHAP && \
602         p[0] == opt) { \
603         len -= CILEN_CHAP; \
604         INCPTR(2, p); \
605         GETSHORT(cishort, p); \
606         GETCHAR(cichar, p); \
607         no.neg = 1; \
608         code \
609     }
610 #define NAKCISHORT(opt, neg, code) \
611     if (go->neg && \
612         len >= CILEN_SHORT && \
613         p[1] == CILEN_SHORT && \
614         p[0] == opt) { \
615         len -= CILEN_SHORT; \
616         INCPTR(2, p); \
617         GETSHORT(cishort, p); \
618         no.neg = 1; \
619         code \
620     }
621 #define NAKCILONG(opt, neg, code) \
622     if (go->neg && \
623         len >= CILEN_LONG && \
624         p[1] == CILEN_LONG && \
625         p[0] == opt) { \
626         len -= CILEN_LONG; \
627         INCPTR(2, p); \
628         GETLONG(cilong, p); \
629         no.neg = 1; \
630         code \
631     }
632 #define NAKCILQR(opt, neg, code) \
633     if (go->neg && \
634         len >= CILEN_LQR && \
635         p[1] == CILEN_LQR && \
636         p[0] == opt) { \
637         len -= CILEN_LQR; \
638         INCPTR(2, p); \
639         GETSHORT(cishort, p); \
640         GETLONG(cilong, p); \
641         no.neg = 1; \
642         code \
643     }
644
645     /*
646      * We don't care if they want to send us smaller packets than
647      * we want.  Therefore, accept any MRU less than what we asked for,
648      * but then ignore the new value when setting the MRU in the kernel.
649      * If they send us a bigger MRU than what we asked, accept it, up to
650      * the limit of the default MRU we'd get if we didn't negotiate.
651      */
652     NAKCISHORT(CI_MRU, neg_mru,
653                if (cishort <= wo->mru || cishort < DEFMRU)
654                    try.mru = cishort;
655                );
656     /*
657      * Add any characters they want to our (receive-side) asyncmap.
658      */
659     NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
660               try.asyncmap = go->asyncmap | cilong;
661               );
662     /*
663      * If they can't cope with our CHAP hash algorithm, we'll have
664      * to stop asking for CHAP.  We haven't got any other algorithm.
665      */
666     NAKCICHAP(CI_AUTHTYPE, neg_chap,
667               try.neg_chap = 0;
668               );
669     /*
670      * Peer shouldn't send Nak for UPAP, protocol compression or
671      * address/control compression requests; they should send
672      * a Reject instead.  If they send a Nak, treat it as a Reject.
673      */
674     if (!go->neg_chap ){
675         NAKCISHORT(CI_AUTHTYPE, neg_upap,
676                    try.neg_upap = 0;
677                    );
678     }
679     /*
680      * If they can't cope with our link quality protocol, we'll have
681      * to stop asking for LQR.  We haven't got any other protocol.
682      * If they Nak the reporting period, take their value XXX ?
683      */
684     NAKCILONG(CI_QUALITY, neg_lqr,
685               if (cishort != LQR)
686                   try.neg_lqr = 0;
687               else
688                   try.lqr_period = cilong;
689               );
690     /*
691      * Check for a looped-back line.
692      */
693     NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
694               try.magicnumber = magic();
695               ++try.numloops;
696               looped_back = 1;
697               );
698
699     NAKCIVOID(CI_PCOMPRESSION, neg_pcompression,
700               try.neg_pcompression = 0;
701               );
702     NAKCIVOID(CI_ACCOMPRESSION, neg_accompression,
703               try.neg_accompression = 0;
704               );
705
706     /*
707      * There may be remaining CIs, if the peer is requesting negotiation
708      * on an option that we didn't include in our request packet.
709      * If we see an option that we requested, or one we've already seen
710      * in this packet, then this packet is bad.
711      * If we wanted to respond by starting to negotiate on the requested
712      * option(s), we could, but we don't, because except for the
713      * authentication type and quality protocol, if we are not negotiating
714      * an option, it is because we were told not to.
715      * For the authentication type, the Nak from the peer means
716      * `let me authenticate myself with you' which is a bit pointless.
717      * For the quality protocol, the Nak means `ask me to send you quality
718      * reports', but if we didn't ask for them, we don't want them.
719      */
720     while (len > CILEN_VOID) {
721         GETCHAR(citype, p);
722         GETCHAR(cilen, p);
723         if( (len -= cilen) < 0 )
724             goto bad;
725         next = p + cilen - 2;
726
727         switch (citype) {
728         case CI_MRU:
729             if (go->neg_mru || no.neg_mru || cilen != CILEN_SHORT)
730                 goto bad;
731             break;
732         case CI_ASYNCMAP:
733             if (go->neg_asyncmap || no.neg_asyncmap || cilen != CILEN_LONG)
734                 goto bad;
735             break;
736         case CI_AUTHTYPE:
737             if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap)
738                 goto bad;
739             break;
740         case CI_MAGICNUMBER:
741             if (go->neg_magicnumber || no.neg_magicnumber ||
742                 cilen != CILEN_LONG)
743                 goto bad;
744             break;
745         case CI_PCOMPRESSION:
746             if (go->neg_pcompression || no.neg_pcompression
747                 || cilen != CILEN_VOID)
748                 goto bad;
749             break;
750         case CI_ACCOMPRESSION:
751             if (go->neg_accompression || no.neg_accompression
752                 || cilen != CILEN_VOID)
753                 goto bad;
754             break;
755         case CI_QUALITY:
756             if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)
757                 goto bad;
758             break;
759         default:
760             goto bad;
761         }
762         p = next;
763     }
764
765     /* If there is still anything left, this packet is bad. */
766     if (len != 0)
767         goto bad;
768
769     /*
770      * OK, the Nak is good.  Now we can update state.
771      */
772     if (f->state != OPENED) {
773         *go = try;
774         if (looped_back && try.numloops % lcp_warnloops == 0)
775             LCPDEBUG((LOG_INFO, "The line appears to be looped back."));
776     }
777
778     return 1;
779
780 bad:
781     LCPDEBUG((LOG_WARNING, "lcp_nakci: received bad Nak!"));
782     return 0;
783 }
784
785
786 /*
787  * lcp_rejci - Peer has Rejected some of our CIs.
788  * This should not modify any state if the Reject is bad
789  * or if LCP is in the OPENED state.
790  *
791  * Returns:
792  *      0 - Reject was bad.
793  *      1 - Reject was good.
794  */
795 static int
796 lcp_rejci(f, p, len)
797     fsm *f;
798     u_char *p;
799     int len;
800 {
801     lcp_options *go = &lcp_gotoptions[f->unit];
802     u_char cichar;
803     u_short cishort;
804     u_long cilong;
805     u_char *start = p;
806     int plen = len;
807     lcp_options try;            /* options to request next time */
808
809     try = *go;
810
811     /*
812      * Any Rejected CIs must be in exactly the same order that we sent.
813      * Check packet length and CI length at each step.
814      * If we find any deviations, then this packet is bad.
815      */
816 #define REJCIVOID(opt, neg) \
817     if (go->neg && \
818         len >= CILEN_VOID && \
819         p[1] == CILEN_VOID && \
820         p[0] == opt) { \
821         len -= CILEN_VOID; \
822         INCPTR(CILEN_VOID, p); \
823         try.neg = 0; \
824         LCPDEBUG((LOG_INFO, "lcp_rejci rejected void opt %d", opt)); \
825     }
826 #define REJCISHORT(opt, neg, val) \
827     if (go->neg && \
828         len >= CILEN_SHORT && \
829         p[1] == CILEN_SHORT && \
830         p[0] == opt) { \
831         len -= CILEN_SHORT; \
832         INCPTR(2, p); \
833         GETSHORT(cishort, p); \
834         /* Check rejected value. */ \
835         if (cishort != val) \
836             goto bad; \
837         try.neg = 0; \
838         LCPDEBUG((LOG_INFO,"lcp_rejci rejected short opt %d", opt)); \
839     }
840 #define REJCICHAP(opt, neg, val, digest) \
841     if (go->neg && \
842         len >= CILEN_CHAP && \
843         p[1] == CILEN_CHAP && \
844         p[0] == opt) { \
845         len -= CILEN_CHAP; \
846         INCPTR(2, p); \
847         GETSHORT(cishort, p); \
848         GETCHAR(cichar, p); \
849         /* Check rejected value. */ \
850         if (cishort != val || cichar != digest) \
851             goto bad; \
852         try.neg = 0; \
853         LCPDEBUG((LOG_INFO,"lcp_rejci rejected chap opt %d", opt)); \
854     }
855 #define REJCILONG(opt, neg, val) \
856     if (go->neg && \
857         len >= CILEN_LONG && \
858         p[1] == CILEN_LONG && \
859         p[0] == opt) { \
860         len -= CILEN_LONG; \
861         INCPTR(2, p); \
862         GETLONG(cilong, p); \
863         /* Check rejected value. */ \
864         if (cilong != val) \
865             goto bad; \
866         try.neg = 0; \
867         LCPDEBUG((LOG_INFO,"lcp_rejci rejected long opt %d", opt)); \
868     }
869 #define REJCILQR(opt, neg, val) \
870     if (go->neg && \
871         len >= CILEN_LQR && \
872         p[1] == CILEN_LQR && \
873         p[0] == opt) { \
874         len -= CILEN_LQR; \
875         INCPTR(2, p); \
876         GETSHORT(cishort, p); \
877         GETLONG(cilong, p); \
878         /* Check rejected value. */ \
879         if (cishort != LQR || cichar != val) \
880             goto bad; \
881         try.neg = 0; \
882         LCPDEBUG((LOG_INFO,"lcp_rejci rejected LQR opt %d", opt)); \
883     }
884
885     REJCISHORT(CI_MRU, neg_mru, go->mru);
886     REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
887     REJCICHAP(CI_AUTHTYPE, neg_chap, CHAP, go->chap_mdtype);
888     if (!go->neg_chap) {
889         REJCISHORT(CI_AUTHTYPE, neg_upap, UPAP);
890     }
891     REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
892     REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
893     REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
894     REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
895
896     /*
897      * If there are any remaining CIs, then this packet is bad.
898      */
899     if (len != 0)
900         goto bad;
901     /*
902      * Now we can update state.
903      */
904     if (f->state != OPENED)
905         *go = try;
906     return 1;
907
908 bad:
909     LCPDEBUG((LOG_WARNING, "lcp_rejci: received bad Reject!"));
910     LCPDEBUG((LOG_WARNING, "lcp_rejci: plen %d len %d off %d",
911               plen, len, p - start));
912     return 0;
913 }
914
915
916 /*
917  * lcp_reqci - Check the peer's requested CIs and send appropriate response.
918  *
919  * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
920  * appropriately.  If reject_if_disagree is non-zero, doesn't return
921  * CONFNAK; returns CONFREJ if it can't return CONFACK.
922  */
923 static int
924 lcp_reqci(f, inp, lenp, reject_if_disagree)
925     fsm *f;
926     u_char *inp;                /* Requested CIs */
927     int *lenp;                  /* Length of requested CIs */
928     int reject_if_disagree;
929 {
930     lcp_options *go = &lcp_gotoptions[f->unit];
931     lcp_options *ho = &lcp_hisoptions[f->unit];
932     lcp_options *ao = &lcp_allowoptions[f->unit];
933     u_char *cip, *next;         /* Pointer to current and next CIs */
934     u_char cilen, citype, cichar;/* Parsed len, type, char value */
935     u_short cishort;            /* Parsed short value */
936     u_long cilong;              /* Parse long value */
937     int rc = CONFACK;           /* Final packet return code */
938     int orc;                    /* Individual option return code */
939     u_char *p;                  /* Pointer to next char to parse */
940     u_char *ucp = inp;          /* Pointer to current output char */
941     int l = *lenp;              /* Length left */
942
943     /*
944      * Reset all his options.
945      */
946     BZERO(ho, sizeof(*ho));
947
948     /*
949      * Process all his options.
950      */
951     next = inp;
952     while (l) {
953         orc = CONFACK;                  /* Assume success */
954         cip = p = next;                 /* Remember begining of CI */
955         if (l < 2 ||                    /* Not enough data for CI header or */
956             p[1] < 2 ||                 /*  CI length too small or */
957             p[1] > l) {                 /*  CI length too big? */
958             LCPDEBUG((LOG_WARNING, "lcp_reqci: bad CI length!"));
959             orc = CONFREJ;              /* Reject bad CI */
960             cilen = l;                  /* Reject till end of packet */
961             l = 0;                      /* Don't loop again */
962             goto endswitch;
963         }
964         GETCHAR(citype, p);             /* Parse CI type */
965         GETCHAR(cilen, p);              /* Parse CI length */
966         l -= cilen;                     /* Adjust remaining length */
967         next += cilen;                  /* Step to next CI */
968
969         switch (citype) {               /* Check CI type */
970         case CI_MRU:
971             LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd MRU"));
972             if (!ao->neg_mru ||         /* Allow option? */
973                 cilen != CILEN_SHORT) { /* Check CI length */
974                 orc = CONFREJ;          /* Reject CI */
975                 break;
976             }
977             GETSHORT(cishort, p);       /* Parse MRU */
978             LCPDEBUG((LOG_INFO, "(%d)", cishort));
979
980             /*
981              * He must be able to receive at least our minimum.
982              * No need to check a maximum.  If he sends a large number,
983              * we'll just ignore it.
984              */
985             if (cishort < MINMRU) {
986                 orc = CONFNAK;          /* Nak CI */
987                 if( !reject_if_disagree ){
988                     DECPTR(sizeof (short), p);  /* Backup */
989                     PUTSHORT(MINMRU, p);        /* Give him a hint */
990                 }
991                 break;
992             }
993             ho->neg_mru = 1;            /* Remember he sent MRU */
994             ho->mru = cishort;          /* And remember value */
995             break;
996
997         case CI_ASYNCMAP:
998             LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd ASYNCMAP"));
999             if (!ao->neg_asyncmap ||
1000                 cilen != CILEN_LONG) {
1001                 orc = CONFREJ;
1002                 break;
1003             }
1004             GETLONG(cilong, p);
1005             LCPDEBUG((LOG_INFO, "(%lx)", cilong));
1006
1007             /*
1008              * Asyncmap must have set at least the bits
1009              * which are set in lcp_allowoptions[unit].asyncmap.
1010              */
1011             if ((ao->asyncmap & ~cilong) != 0) {
1012                 orc = CONFNAK;
1013                 if( !reject_if_disagree ){
1014                     DECPTR(sizeof (long), p);
1015                     PUTLONG(ao->asyncmap | cilong, p);
1016                 }
1017                 break;
1018             }
1019             ho->neg_asyncmap = 1;
1020             ho->asyncmap = cilong;
1021             break;
1022
1023         case CI_AUTHTYPE:
1024             LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd AUTHTYPE"));
1025             if (cilen < CILEN_SHORT ||
1026                 !(ao->neg_upap || ao->neg_chap)) {
1027                 orc = CONFREJ;
1028                 break;
1029             }
1030             GETSHORT(cishort, p);
1031             LCPDEBUG((LOG_INFO, "(%x)", cishort));
1032
1033             /*
1034              * Authtype must be UPAP or CHAP.
1035              *
1036              * Note: if both ao->neg_upap and ao->neg_chap are set,
1037              * and the peer sends a Configure-Request with two
1038              * authenticate-protocol requests, one for CHAP and one
1039              * for UPAP, then we will reject the second request.
1040              * Whether we end up doing CHAP or UPAP depends then on
1041              * the ordering of the CIs in the peer's Configure-Request.
1042              */
1043
1044             if (cishort == UPAP) {
1045                 if (!ao->neg_upap ||    /* we don't want to do PAP */
1046                     ho->neg_chap ||     /* or we've already accepted CHAP */
1047                     cilen != CILEN_SHORT) {
1048                     LCPDEBUG((LOG_WARNING,
1049                               "lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));
1050                     orc = CONFREJ;
1051                     break;
1052                 }
1053                 ho->neg_upap = 1;
1054                 break;
1055             }
1056             if (cishort == CHAP) {
1057                 if (!ao->neg_chap ||    /* we don't want to do CHAP */
1058                     ho->neg_upap ||     /* or we've already accepted UPAP */
1059                     cilen != CILEN_CHAP) {
1060                     LCPDEBUG((LOG_INFO,
1061                               "lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));
1062                     orc = CONFREJ;
1063                     break;
1064                 }
1065                 GETCHAR(cichar, p);     /* get digest type*/
1066                 if (cichar != ao->chap_mdtype) {
1067                     orc = CONFNAK;
1068                     if( !reject_if_disagree ){
1069                         DECPTR(sizeof (u_char), p);
1070                         PUTCHAR(ao->chap_mdtype, p);
1071                     }
1072                     break;
1073                 }
1074                 ho->chap_mdtype = cichar; /* save md type */
1075                 ho->neg_chap = 1;
1076                 break;
1077             }
1078
1079             /*
1080              * We don't recognize the protocol they're asking for.
1081              * Reject it.
1082              */
1083             orc = CONFREJ;
1084             break;
1085
1086         case CI_QUALITY:
1087             LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd QUALITY"));
1088             if (!ao->neg_lqr ||
1089                 cilen != CILEN_LQR) {
1090                 orc = CONFREJ;
1091                 break;
1092             }
1093
1094             GETSHORT(cishort, p);
1095             GETLONG(cilong, p);
1096             LCPDEBUG((LOG_INFO, "(%x %lx)", cishort, cilong));
1097             if (cishort != LQR) {
1098                 orc = CONFREJ;
1099                 break;
1100             }
1101
1102             /*
1103              * Check the reporting period.
1104              * XXX When should we Nak this, and what with?
1105              */
1106             break;
1107
1108         case CI_MAGICNUMBER:
1109             LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd MAGICNUMBER"));
1110             if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
1111                 cilen != CILEN_LONG) {
1112                 orc = CONFREJ;
1113                 break;
1114             }
1115             GETLONG(cilong, p);
1116             LCPDEBUG((LOG_INFO, "(%lx)", cilong));
1117
1118             /*
1119              * He must have a different magic number.
1120              */
1121             if (go->neg_magicnumber &&
1122                 cilong == go->magicnumber) {
1123                 orc = CONFNAK;
1124                 DECPTR(sizeof (long), p);
1125                 cilong = magic();       /* Don't put magic() inside macro! */
1126                 PUTLONG(cilong, p);
1127                 break;
1128             }
1129             ho->neg_magicnumber = 1;
1130             ho->magicnumber = cilong;
1131             break;
1132
1133
1134         case CI_PCOMPRESSION:
1135             LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd PCOMPRESSION"));
1136             if (!ao->neg_pcompression ||
1137                 cilen != CILEN_VOID) {
1138                 orc = CONFREJ;
1139                 break;
1140             }
1141             ho->neg_pcompression = 1;
1142             break;
1143
1144         case CI_ACCOMPRESSION:
1145             LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd ACCOMPRESSION"));
1146             if (!ao->neg_accompression ||
1147                 cilen != CILEN_VOID) {
1148                 orc = CONFREJ;
1149                 break;
1150             }
1151             ho->neg_accompression = 1;
1152             break;
1153
1154         default:
1155             LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd unknown option %d",
1156                       citype));
1157             orc = CONFREJ;
1158             break;
1159         }
1160
1161 endswitch:
1162         LCPDEBUG((LOG_INFO, " (%s)", CODENAME(orc)));
1163         if (orc == CONFACK &&           /* Good CI */
1164             rc != CONFACK)              /*  but prior CI wasnt? */
1165             continue;                   /* Don't send this one */
1166
1167         if (orc == CONFNAK) {           /* Nak this CI? */
1168             if (reject_if_disagree)     /* Getting fed up with sending NAKs? */
1169                 orc = CONFREJ;          /* Get tough if so */
1170             else {
1171                 if (rc == CONFREJ)      /* Rejecting prior CI? */
1172                     continue;           /* Don't send this one */
1173                 if (rc == CONFACK) {    /* Ack'd all prior CIs? */
1174                     rc = CONFNAK;       /* Not anymore... */
1175                     ucp = inp;          /* Backup */
1176                 }
1177             }
1178         }
1179         if (orc == CONFREJ &&           /* Reject this CI */
1180             rc != CONFREJ) {            /*  but no prior ones? */
1181             rc = CONFREJ;
1182             ucp = inp;                  /* Backup */
1183         }
1184         if (ucp != cip)                 /* Need to move CI? */
1185             BCOPY(cip, ucp, cilen);     /* Move it */
1186         INCPTR(cilen, ucp);             /* Update output pointer */
1187     }
1188
1189     /*
1190      * If we wanted to send additional NAKs (for unsent CIs), the
1191      * code would go here.  This must be done with care since it might
1192      * require a longer packet than we received.  At present there
1193      * are no cases where we want to ask the peer to negotiate an option.
1194      */
1195
1196     *lenp = ucp - inp;                  /* Compute output length */
1197     LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.", CODENAME(rc)));
1198     return (rc);                        /* Return final code */
1199 }
1200
1201
1202 /*
1203  * lcp_up - LCP has come UP.
1204  *
1205  * Start UPAP, IPCP, etc.
1206  */
1207 static void
1208 lcp_up(f)
1209     fsm *f;
1210 {
1211     lcp_options *wo = &lcp_wantoptions[f->unit];
1212     lcp_options *ho = &lcp_hisoptions[f->unit];
1213     lcp_options *go = &lcp_gotoptions[f->unit];
1214     lcp_options *ao = &lcp_allowoptions[f->unit];
1215
1216     /*
1217      * Set our MTU to the smaller of the MTU we wanted and
1218      * the MRU our peer wanted.  If we negotiated an MRU,
1219      * set our MRU to the larger of value we wanted and
1220      * the value we got in the negotiation.
1221      */
1222     ppp_send_config(f->unit, (ho->neg_mru? MIN(ao->mru, ho->mru): MTU),
1223                     (ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
1224                     ho->neg_pcompression, ho->neg_accompression);
1225     ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): MTU),
1226                     (go->neg_asyncmap? go->asyncmap: 0xffffffff),
1227                     go->neg_pcompression, go->neg_accompression);
1228
1229     if (ho->neg_mru)
1230         peer_mru[f->unit] = ho->mru;
1231
1232     ChapLowerUp(f->unit);       /* Enable CHAP */
1233     upap_lowerup(f->unit);      /* Enable UPAP */
1234     ipcp_lowerup(f->unit);      /* Enable IPCP */
1235
1236     link_established(f->unit);
1237 }
1238
1239
1240 /*
1241  * lcp_down - LCP has gone DOWN.
1242  *
1243  * Alert other protocols.
1244  */
1245 static void
1246 lcp_down(f)
1247     fsm *f;
1248 {
1249     ipcp_lowerdown(f->unit);
1250     ChapLowerDown(f->unit);
1251     upap_lowerdown(f->unit);
1252
1253     sifdown(f->unit);
1254     ppp_send_config(f->unit, MTU, 0xffffffff, 0, 0);
1255     ppp_recv_config(f->unit, MTU, 0, 0, 0);
1256     peer_mru[f->unit] = MTU;
1257     syslog(LOG_NOTICE, "Connection terminated.");
1258 }
1259
1260
1261 /*
1262  * lcp_starting - LCP needs the lower layer up.
1263  */
1264 static void
1265 lcp_starting(f)
1266     fsm *f;
1267 {
1268     link_required(f->unit);
1269 }
1270
1271
1272 /*
1273  * lcp_finished - LCP has finished with the lower layer.
1274  */
1275 static void
1276 lcp_finished(f)
1277     fsm *f;
1278 {
1279     link_terminated(f->unit);
1280 }
1281