]> git.ozlabs.org Git - ppp.git/blob - pppd/lcp.c
CI: Updated the 'checkout' actions that were using Node.js 16 to Node.js 20. (#489)
[ppp.git] / pppd / lcp.c
1 /*
2  * lcp.c - PPP Link Control Protocol.
3  *
4  * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * 3. The name "Carnegie Mellon University" must not be used to
19  *    endorse or promote products derived from this software without
20  *    prior written permission. For permission or any legal
21  *    details, please contact
22  *      Office of Technology Transfer
23  *      Carnegie Mellon University
24  *      5000 Forbes Avenue
25  *      Pittsburgh, PA  15213-3890
26  *      (412) 268-4387, fax: (412) 268-7395
27  *      tech-transfer@andrew.cmu.edu
28  *
29  * 4. Redistributions of any form whatsoever must retain the following
30  *    acknowledgment:
31  *    "This product includes software developed by Computing Services
32  *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
33  *
34  * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
35  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36  * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
37  * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
38  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
39  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
40  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41  */
42
43 #ifdef HAVE_CONFIG_H
44 #include "config.h"
45 #endif
46
47 #include <stdio.h>
48 #include <string.h>
49 #include <stdlib.h>
50 #include <fcntl.h>
51 #include <string.h>
52 #include <time.h>
53 #include <arpa/inet.h>
54 #include <sys/mman.h>
55
56 #include "pppd-private.h"
57 #include "options.h"
58 #include "fsm.h"
59 #include "lcp.h"
60 #include "eap.h"
61 #include "chap.h"
62 #include "magic.h"
63 #include "multilink.h"
64
65 /*
66  * When the link comes up we want to be able to wait for a short while,
67  * or until seeing some input from the peer, before starting to send
68  * configure-requests.  We do this by delaying the fsm_lowerup call.
69  */
70 /* steal a bit in fsm flags word */
71 #define DELAYED_UP      0x100
72
73 static void lcp_delayed_up(void *);
74
75 /*
76  * These definitions relate to the measurement and logging of round-trip
77  * time (RTT) of LCP echo-requests implemented in lcp_rtt_update_buffer().
78  */
79 #define LCP_RTT_MAGIC 0x19450425
80 #define LCP_RTT_HEADER_LENGTH 4
81 #define LCP_RTT_FILE_SIZE 8192
82 #define LCP_RTT_ELEMENTS (LCP_RTT_FILE_SIZE / sizeof(u_int32_t) - LCP_RTT_HEADER_LENGTH) / 2
83
84 /*
85  * LCP-related command-line options.
86  */
87 int     lcp_echo_interval = 0;  /* Interval between LCP echo-requests */
88 int     lcp_echo_fails = 0;     /* Tolerance to unanswered echo-requests */
89 bool    lcp_echo_adaptive = 0;  /* request echo only if the link was idle */
90 char    *lcp_rtt_file = NULL;   /* measure the RTT of LCP echo-requests */
91 bool    lax_recv = 0;           /* accept control chars in asyncmap */
92 bool    noendpoint = 0;         /* don't send/accept endpoint discriminator */
93
94 static int noopt(char **);
95
96 #ifdef PPP_WITH_MULTILINK
97 static int setendpoint(char **);
98 static void printendpoint(option_t *, void (*)(void *, char *, ...), void *);
99 #endif /* PPP_WITH_MULTILINK */
100
101 static struct option lcp_option_list[] = {
102     /* LCP options */
103     { "-all", o_special_noarg, (void *)noopt,
104       "Don't request/allow any LCP options" },
105
106     { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression,
107       "Disable address/control compression",
108       OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },
109     { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression,
110       "Disable address/control compression",
111       OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },
112
113     { "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
114       "Set asyncmap (for received packets)",
115       OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
116     { "-as", o_uint32, &lcp_wantoptions[0].asyncmap,
117       "Set asyncmap (for received packets)",
118       OPT_ALIAS | OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
119     { "default-asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
120       "Disable asyncmap negotiation",
121       OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR,
122       &lcp_allowoptions[0].neg_asyncmap },
123     { "-am", o_uint32, &lcp_wantoptions[0].asyncmap,
124       "Disable asyncmap negotiation",
125       OPT_ALIAS | OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR,
126       &lcp_allowoptions[0].neg_asyncmap },
127
128     { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber,
129       "Disable magic number negotiation (looped-back line detection)",
130       OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },
131     { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber,
132       "Disable magic number negotiation (looped-back line detection)",
133       OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },
134
135     { "mru", o_int, &lcp_wantoptions[0].mru,
136       "Set MRU (maximum received packet size) for negotiation",
137       OPT_PRIO, &lcp_wantoptions[0].neg_mru },
138     { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru,
139       "Disable MRU negotiation (use default 1500)",
140       OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },
141     { "-mru", o_bool, &lcp_wantoptions[0].neg_mru,
142       "Disable MRU negotiation (use default 1500)",
143       OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },
144
145     { "mtu", o_int, &lcp_allowoptions[0].mru,
146       "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU },
147
148     { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression,
149       "Disable protocol field compression",
150       OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },
151     { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression,
152       "Disable protocol field compression",
153       OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },
154
155     { "passive", o_bool, &lcp_wantoptions[0].passive,
156       "Set passive mode", 1 },
157     { "-p", o_bool, &lcp_wantoptions[0].passive,
158       "Set passive mode", OPT_ALIAS | 1 },
159
160     { "silent", o_bool, &lcp_wantoptions[0].silent,
161       "Set silent mode", 1 },
162
163     { "lcp-echo-failure", o_int, &lcp_echo_fails,
164       "Set number of consecutive echo failures to indicate link failure",
165       OPT_PRIO },
166     { "lcp-echo-interval", o_int, &lcp_echo_interval,
167       "Set time in seconds between LCP echo requests", OPT_PRIO },
168     { "lcp-echo-adaptive", o_bool, &lcp_echo_adaptive,
169       "Suppress LCP echo requests if traffic was received", 1 },
170     { "lcp-rtt-file", o_string, &lcp_rtt_file,
171       "Filename for logging the round-trip time of LCP echo requests",
172       OPT_PRIO | OPT_PRIV },
173     { "lcp-restart", o_int, &lcp_fsm[0].timeouttime,
174       "Set time in seconds between LCP retransmissions", OPT_PRIO },
175     { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits,
176       "Set maximum number of LCP terminate-request transmissions", OPT_PRIO },
177     { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits,
178       "Set maximum number of LCP configure-request transmissions", OPT_PRIO },
179     { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops,
180       "Set limit on number of LCP configure-naks", OPT_PRIO },
181
182     { "receive-all", o_bool, &lax_recv,
183       "Accept all received control characters", 1 },
184
185 #ifdef PPP_WITH_MULTILINK
186     { "mrru", o_int, &lcp_wantoptions[0].mrru,
187       "Maximum received packet size for multilink bundle",
188       OPT_PRIO, &lcp_wantoptions[0].neg_mrru },
189
190     { "mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,
191       "Use short sequence numbers in multilink headers",
192       OPT_PRIO | 1, &lcp_allowoptions[0].neg_ssnhf },
193     { "nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,
194       "Don't use short sequence numbers in multilink headers",
195       OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_ssnhf },
196
197     { "endpoint", o_special, (void *) setendpoint,
198       "Endpoint discriminator for multilink",
199       OPT_PRIO | OPT_A2PRINTER, (void *) printendpoint },
200 #endif /* PPP_WITH_MULTILINK */
201
202     { "noendpoint", o_bool, &noendpoint,
203       "Don't send or accept multilink endpoint discriminator", 1 },
204
205     {NULL}
206 };
207
208 /* global vars */
209 fsm lcp_fsm[NUM_PPP];                   /* LCP fsm structure (global)*/
210 lcp_options lcp_wantoptions[NUM_PPP];   /* Options that we want to request */
211 lcp_options lcp_gotoptions[NUM_PPP];    /* Options that peer ack'd */
212 lcp_options lcp_allowoptions[NUM_PPP];  /* Options we allow peer to request */
213 lcp_options lcp_hisoptions[NUM_PPP];    /* Options that we ack'd */
214
215 static int lcp_echos_pending = 0;       /* Number of outstanding echo msgs */
216 static int lcp_echo_number   = 0;       /* ID number of next echo frame */
217 static int lcp_echo_timer_running = 0;  /* set if a timer is running */
218 static int lcp_rtt_file_fd = 0;         /* fd for the opened LCP RTT file */
219 static u_int32_t *lcp_rtt_buffer = NULL; /* the mmap'ed LCP RTT file */
220
221 static u_char nak_buffer[PPP_MRU];      /* where we construct a nak packet */
222
223 /*
224  * Callbacks for fsm code.  (CI = Configuration Information)
225  */
226 static void lcp_resetci(fsm *); /* Reset our CI */
227 static int  lcp_cilen(fsm *);           /* Return length of our CI */
228 static void lcp_addci(fsm *, u_char *, int *); /* Add our CI to pkt */
229 static int  lcp_ackci(fsm *, u_char *, int); /* Peer ack'd our CI */
230 static int  lcp_nakci(fsm *, u_char *, int, int); /* Peer nak'd our CI */
231 static int  lcp_rejci(fsm *, u_char *, int); /* Peer rej'd our CI */
232 static int  lcp_reqci(fsm *, u_char *, int *, int); /* Rcv peer CI */
233 static void lcp_up(fsm *);              /* We're UP */
234 static void lcp_down(fsm *);            /* We're DOWN */
235 static void lcp_starting(fsm *);        /* We need lower layer up */
236 static void lcp_finished(fsm *);        /* We need lower layer down */
237 static int  lcp_extcode(fsm *, int, int, u_char *, int);
238 static void lcp_rprotrej(fsm *, u_char *, int);
239
240 /*
241  * routines to send LCP echos to peer
242  */
243
244 static void lcp_echo_lowerup(int);
245 static void lcp_echo_lowerdown(int);
246 static void LcpEchoTimeout(void *);
247 static void lcp_received_echo_reply(fsm *, int, u_char *, int);
248 static void LcpSendEchoRequest(fsm *);
249 static void LcpLinkFailure(fsm *);
250 static void LcpEchoCheck(fsm *);
251
252 static fsm_callbacks lcp_callbacks = {  /* LCP callback routines */
253     lcp_resetci,                /* Reset our Configuration Information */
254     lcp_cilen,                  /* Length of our Configuration Information */
255     lcp_addci,                  /* Add our Configuration Information */
256     lcp_ackci,                  /* ACK our Configuration Information */
257     lcp_nakci,                  /* NAK our Configuration Information */
258     lcp_rejci,                  /* Reject our Configuration Information */
259     lcp_reqci,                  /* Request peer's Configuration Information */
260     lcp_up,                     /* Called when fsm reaches OPENED state */
261     lcp_down,                   /* Called when fsm leaves OPENED state */
262     lcp_starting,               /* Called when we want the lower layer up */
263     lcp_finished,               /* Called when we want the lower layer down */
264     NULL,                       /* Called when Protocol-Reject received */
265     NULL,                       /* Retransmission is necessary */
266     lcp_extcode,                /* Called to handle LCP-specific codes */
267     "LCP"                       /* String name of protocol */
268 };
269
270 /*
271  * Protocol entry points.
272  * Some of these are called directly.
273  */
274
275 static void lcp_init(int);
276 static void lcp_input(int, u_char *, int);
277 static void lcp_protrej(int);
278 static int  lcp_printpkt(u_char *, int, void (*)(void *, char *, ...), void *);
279
280 struct protent lcp_protent = {
281     PPP_LCP,
282     lcp_init,
283     lcp_input,
284     lcp_protrej,
285     lcp_lowerup,
286     lcp_lowerdown,
287     lcp_open,
288     lcp_close,
289     lcp_printpkt,
290     NULL,
291     1,
292     "LCP",
293     NULL,
294     lcp_option_list,
295     NULL,
296     NULL,
297     NULL
298 };
299
300 int lcp_loopbackfail = DEFLOOPBACKFAIL;
301
302 /*
303  * Length of each type of configuration option (in octets)
304  */
305 #define CILEN_VOID      2
306 #define CILEN_CHAR      3
307 #define CILEN_SHORT     4       /* CILEN_VOID + 2 */
308 #define CILEN_CHAP      5       /* CILEN_VOID + 2 + 1 */
309 #define CILEN_LONG      6       /* CILEN_VOID + 4 */
310 #define CILEN_LQR       8       /* CILEN_VOID + 2 + 4 */
311 #define CILEN_CBCP      3
312
313 #define CODENAME(x)     ((x) == CONFACK ? "ACK" : \
314                          (x) == CONFNAK ? "NAK" : "REJ")
315
316 /*
317  * noopt - Disable all options (why?).
318  */
319 static int
320 noopt(char **argv)
321 {
322     BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options));
323     BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options));
324
325     return (1);
326 }
327
328 #ifdef PPP_WITH_MULTILINK
329 static int
330 setendpoint(char **argv)
331 {
332     if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) {
333         lcp_wantoptions[0].neg_endpoint = 1;
334         return 1;
335     }
336     ppp_option_error("Can't parse '%s' as an endpoint discriminator", *argv);
337     return 0;
338 }
339
340 static void
341 printendpoint(option_t *opt, void (*printer)(void *, char *, ...), void *arg)
342 {
343         printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint));
344 }
345 #endif /* PPP_WITH_MULTILINK */
346
347 /*
348  * lcp_init - Initialize LCP.
349  */
350 static void
351 lcp_init(int unit)
352 {
353     fsm *f = &lcp_fsm[unit];
354     lcp_options *wo = &lcp_wantoptions[unit];
355     lcp_options *ao = &lcp_allowoptions[unit];
356
357     f->unit = unit;
358     f->protocol = PPP_LCP;
359     f->callbacks = &lcp_callbacks;
360
361     fsm_init(f);
362
363     BZERO(wo, sizeof(*wo));
364     wo->neg_mru = 1;
365     wo->mru = DEFMRU;
366     wo->neg_asyncmap = 1;
367     wo->neg_magicnumber = 1;
368     wo->neg_pcompression = 1;
369     wo->neg_accompression = 1;
370
371     BZERO(ao, sizeof(*ao));
372     ao->neg_mru = 1;
373     ao->mru = MAXMRU;
374     ao->neg_asyncmap = 1;
375     ao->neg_chap = 1;
376     ao->chap_mdtype = chap_mdtype_all;
377     ao->neg_upap = 1;
378     ao->neg_eap = 1;
379     ao->neg_magicnumber = 1;
380     ao->neg_pcompression = 1;
381     ao->neg_accompression = 1;
382     ao->neg_endpoint = 1;
383 }
384
385
386 /*
387  * lcp_open - LCP is allowed to come up.
388  */
389 void
390 lcp_open(int unit)
391 {
392     fsm *f = &lcp_fsm[unit];
393     lcp_options *wo = &lcp_wantoptions[unit];
394
395     f->flags &= ~(OPT_PASSIVE | OPT_SILENT);
396     if (wo->passive)
397         f->flags |= OPT_PASSIVE;
398     if (wo->silent)
399         f->flags |= OPT_SILENT;
400     fsm_open(f);
401 }
402
403
404 /*
405  * lcp_close - Take LCP down.
406  */
407 void
408 lcp_close(int unit, char *reason)
409 {
410     fsm *f = &lcp_fsm[unit];
411     int oldstate;
412
413     if (!in_phase(PHASE_DEAD) && !in_phase(PHASE_MASTER))
414         new_phase(PHASE_TERMINATE);
415
416     if (f->flags & DELAYED_UP) {
417         UNTIMEOUT(lcp_delayed_up, f);
418         f->state = STOPPED;
419     }
420     oldstate = f->state;
421
422     fsm_close(f, reason);
423     if (oldstate == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP)) {
424         /*
425          * This action is not strictly according to the FSM in RFC1548,
426          * but it does mean that the program terminates if you do a
427          * lcp_close() when a connection hasn't been established
428          * because we are in passive/silent mode or because we have
429          * delayed the fsm_lowerup() call and it hasn't happened yet.
430          */
431         f->flags &= ~DELAYED_UP;
432         lcp_finished(f);
433     }
434 }
435
436
437 /*
438  * lcp_lowerup - The lower layer is up.
439  */
440 void
441 lcp_lowerup(int unit)
442 {
443     lcp_options *wo = &lcp_wantoptions[unit];
444     fsm *f = &lcp_fsm[unit];
445
446     /*
447      * Don't use A/C or protocol compression on transmission,
448      * but accept A/C and protocol compressed packets
449      * if we are going to ask for A/C and protocol compression.
450      */
451     if (ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0) < 0
452         || ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff),
453                            wo->neg_pcompression, wo->neg_accompression) < 0)
454             return;
455     peer_mru[unit] = PPP_MRU;
456
457     if (listen_time != 0) {
458         f->flags |= DELAYED_UP;
459         ppp_timeout(lcp_delayed_up, f, 0, listen_time * 1000);
460     } else
461         fsm_lowerup(f);
462 }
463
464
465 /*
466  * lcp_lowerdown - The lower layer is down.
467  */
468 void
469 lcp_lowerdown(int unit)
470 {
471     fsm *f = &lcp_fsm[unit];
472
473     if (f->flags & DELAYED_UP) {
474         f->flags &= ~DELAYED_UP;
475         UNTIMEOUT(lcp_delayed_up, f);
476     } else
477         fsm_lowerdown(&lcp_fsm[unit]);
478 }
479
480
481 /*
482  * lcp_delayed_up - Bring the lower layer up now.
483  */
484 static void
485 lcp_delayed_up(void *arg)
486 {
487     fsm *f = arg;
488
489     if (f->flags & DELAYED_UP) {
490         f->flags &= ~DELAYED_UP;
491         fsm_lowerup(f);
492     }
493 }
494
495
496 /*
497  * lcp_input - Input LCP packet.
498  */
499 static void
500 lcp_input(int unit, u_char *p, int len)
501 {
502     fsm *f = &lcp_fsm[unit];
503
504     if (f->flags & DELAYED_UP) {
505         f->flags &= ~DELAYED_UP;
506         UNTIMEOUT(lcp_delayed_up, f);
507         fsm_lowerup(f);
508     }
509     fsm_input(f, p, len);
510 }
511
512 /*
513  * lcp_extcode - Handle a LCP-specific code.
514  */
515 static int
516 lcp_extcode(fsm *f, int code, int id, u_char *inp, int len)
517 {
518     u_char *magp;
519
520     switch( code ){
521     case PROTREJ:
522         lcp_rprotrej(f, inp, len);
523         break;
524     
525     case ECHOREQ:
526         if (f->state != OPENED)
527             break;
528         magp = inp;
529         PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
530         fsm_sdata(f, ECHOREP, id, inp, len);
531         break;
532     
533     case ECHOREP:
534         lcp_received_echo_reply(f, id, inp, len);
535         break;
536
537     case DISCREQ:
538     case IDENTIF:
539     case TIMEREM:
540         break;
541
542     default:
543         return 0;
544     }
545     return 1;
546 }
547
548     
549 /*
550  * lcp_rprotrej - Receive an Protocol-Reject.
551  *
552  * Figure out which protocol is rejected and inform it.
553  */
554 static void
555 lcp_rprotrej(fsm *f, u_char *inp, int len)
556 {
557     int i;
558     struct protent *protp;
559     u_short prot;
560     const char *pname;
561
562     if (len < 2) {
563         LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!"));
564         return;
565     }
566
567     GETSHORT(prot, inp);
568
569     /*
570      * Protocol-Reject packets received in any state other than the LCP
571      * OPENED state SHOULD be silently discarded.
572      */
573     if( f->state != OPENED ){
574         LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state));
575         return;
576     }
577
578     pname = protocol_name(prot);
579
580     /*
581      * Upcall the proper Protocol-Reject routine.
582      */
583     for (i = 0; (protp = protocols[i]) != NULL; ++i)
584         if (protp->protocol == prot && protp->enabled_flag) {
585             if (pname == NULL)
586                 dbglog("Protocol-Reject for 0x%x received", prot);
587             else
588                 dbglog("Protocol-Reject for '%s' (0x%x) received", pname,
589                        prot);
590             (*protp->protrej)(f->unit);
591             return;
592         }
593
594     if (pname == NULL)
595         warn("Protocol-Reject for unsupported protocol 0x%x", prot);
596     else
597         warn("Protocol-Reject for unsupported protocol '%s' (0x%x)", pname,
598              prot);
599 }
600
601
602 /*
603  * lcp_protrej - A Protocol-Reject was received.
604  */
605 /*ARGSUSED*/
606 static void
607 lcp_protrej(int unit)
608 {
609     /*
610      * Can't reject LCP!
611      */
612     error("Received Protocol-Reject for LCP!");
613     fsm_protreject(&lcp_fsm[unit]);
614 }
615
616
617 /*
618  * lcp_sprotrej - Send a Protocol-Reject for some protocol.
619  */
620 void
621 lcp_sprotrej(int unit, u_char *p, int len)
622 {
623     /*
624      * Send back the protocol and the information field of the
625      * rejected packet.  We only get here if LCP is in the OPENED state.
626      */
627     p += 2;
628     len -= 2;
629
630     fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id,
631               p, len);
632 }
633
634
635 /*
636  * lcp_resetci - Reset our CI.
637  */
638 static void
639 lcp_resetci(fsm *f)
640 {
641     lcp_options *wo = &lcp_wantoptions[f->unit];
642     lcp_options *go = &lcp_gotoptions[f->unit];
643     lcp_options *ao = &lcp_allowoptions[f->unit];
644
645     wo->magicnumber = magic();
646     wo->numloops = 0;
647     *go = *wo;
648     if (!multilink) {
649         go->neg_mrru = 0;
650         go->neg_ssnhf = 0;
651         go->neg_endpoint = 0;
652     }
653     if (noendpoint)
654         ao->neg_endpoint = 0;
655     peer_mru[f->unit] = PPP_MRU;
656     auth_reset(f->unit);
657 }
658
659
660 /*
661  * lcp_cilen - Return length of our CI.
662  */
663 static int
664 lcp_cilen(fsm *f)
665 {
666     lcp_options *go = &lcp_gotoptions[f->unit];
667
668 #define LENCIVOID(neg)  ((neg) ? CILEN_VOID : 0)
669 #define LENCICHAP(neg)  ((neg) ? CILEN_CHAP : 0)
670 #define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0)
671 #define LENCILONG(neg)  ((neg) ? CILEN_LONG : 0)
672 #define LENCILQR(neg)   ((neg) ? CILEN_LQR: 0)
673 #define LENCICBCP(neg)  ((neg) ? CILEN_CBCP: 0)
674     /*
675      * NB: we only ask for one of CHAP, UPAP, or EAP, even if we will
676      * accept more than one.  We prefer EAP first, then CHAP, then
677      * PAP.
678      */
679     return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) +
680             LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) +
681             LENCISHORT(go->neg_eap) +
682             LENCICHAP(!go->neg_eap && go->neg_chap) +
683             LENCISHORT(!go->neg_eap && !go->neg_chap && go->neg_upap) +
684             LENCILQR(go->neg_lqr) +
685             LENCICBCP(go->neg_cbcp) +
686             LENCILONG(go->neg_magicnumber) +
687             LENCIVOID(go->neg_pcompression) +
688             LENCIVOID(go->neg_accompression) +
689             LENCISHORT(go->neg_mrru) +
690             LENCIVOID(go->neg_ssnhf) +
691             (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0));
692 }
693
694
695 /*
696  * lcp_addci - Add our desired CIs to a packet.
697  */
698 static void
699 lcp_addci(fsm *f, u_char *ucp, int *lenp)
700 {
701     lcp_options *go = &lcp_gotoptions[f->unit];
702     u_char *start_ucp = ucp;
703
704 #define ADDCIVOID(opt, neg) \
705     if (neg) { \
706         PUTCHAR(opt, ucp); \
707         PUTCHAR(CILEN_VOID, ucp); \
708     }
709 #define ADDCISHORT(opt, neg, val) \
710     if (neg) { \
711         PUTCHAR(opt, ucp); \
712         PUTCHAR(CILEN_SHORT, ucp); \
713         PUTSHORT(val, ucp); \
714     }
715 #define ADDCICHAP(opt, neg, val) \
716     if (neg) { \
717         PUTCHAR((opt), ucp); \
718         PUTCHAR(CILEN_CHAP, ucp); \
719         PUTSHORT(PPP_CHAP, ucp); \
720         PUTCHAR((CHAP_DIGEST(val)), ucp); \
721     }
722 #define ADDCILONG(opt, neg, val) \
723     if (neg) { \
724         PUTCHAR(opt, ucp); \
725         PUTCHAR(CILEN_LONG, ucp); \
726         PUTLONG(val, ucp); \
727     }
728 #define ADDCILQR(opt, neg, val) \
729     if (neg) { \
730         PUTCHAR(opt, ucp); \
731         PUTCHAR(CILEN_LQR, ucp); \
732         PUTSHORT(PPP_LQR, ucp); \
733         PUTLONG(val, ucp); \
734     }
735 #define ADDCICHAR(opt, neg, val) \
736     if (neg) { \
737         PUTCHAR(opt, ucp); \
738         PUTCHAR(CILEN_CHAR, ucp); \
739         PUTCHAR(val, ucp); \
740     }
741 #define ADDCIENDP(opt, neg, class, val, len) \
742     if (neg) { \
743         int i; \
744         PUTCHAR(opt, ucp); \
745         PUTCHAR(CILEN_CHAR + len, ucp); \
746         PUTCHAR(class, ucp); \
747         for (i = 0; i < len; ++i) \
748             PUTCHAR(val[i], ucp); \
749     }
750
751     ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
752     ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
753               go->asyncmap);
754     ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
755     ADDCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
756     ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap,
757                PPP_PAP);
758     ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
759     ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
760     ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
761     ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
762     ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
763     ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru);
764     ADDCIVOID(CI_SSNHF, go->neg_ssnhf);
765     ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class,
766               go->endpoint.value, go->endpoint.length);
767
768     if (ucp - start_ucp != *lenp) {
769         /* this should never happen, because peer_mtu should be 1500 */
770         error("Bug in lcp_addci: wrong length");
771     }
772 }
773
774
775 /*
776  * lcp_ackci - Ack our CIs.
777  * This should not modify any state if the Ack is bad.
778  *
779  * Returns:
780  *      0 - Ack was bad.
781  *      1 - Ack was good.
782  */
783 static int
784 lcp_ackci(fsm *f, u_char *p, int len)
785 {
786     lcp_options *go = &lcp_gotoptions[f->unit];
787     u_char cilen, citype, cichar;
788     u_short cishort;
789     u_int32_t cilong;
790
791     /*
792      * CIs must be in exactly the same order that we sent.
793      * Check packet length and CI length at each step.
794      * If we find any deviations, then this packet is bad.
795      */
796 #define ACKCIVOID(opt, neg) \
797     if (neg) { \
798         if ((len -= CILEN_VOID) < 0) \
799             goto bad; \
800         GETCHAR(citype, p); \
801         GETCHAR(cilen, p); \
802         if (cilen != CILEN_VOID || \
803             citype != opt) \
804             goto bad; \
805     }
806 #define ACKCISHORT(opt, neg, val) \
807     if (neg) { \
808         if ((len -= CILEN_SHORT) < 0) \
809             goto bad; \
810         GETCHAR(citype, p); \
811         GETCHAR(cilen, p); \
812         if (cilen != CILEN_SHORT || \
813             citype != opt) \
814             goto bad; \
815         GETSHORT(cishort, p); \
816         if (cishort != val) \
817             goto bad; \
818     }
819 #define ACKCICHAR(opt, neg, val) \
820     if (neg) { \
821         if ((len -= CILEN_CHAR) < 0) \
822             goto bad; \
823         GETCHAR(citype, p); \
824         GETCHAR(cilen, p); \
825         if (cilen != CILEN_CHAR || \
826             citype != opt) \
827             goto bad; \
828         GETCHAR(cichar, p); \
829         if (cichar != val) \
830             goto bad; \
831     }
832 #define ACKCICHAP(opt, neg, val) \
833     if (neg) { \
834         if ((len -= CILEN_CHAP) < 0) \
835             goto bad; \
836         GETCHAR(citype, p); \
837         GETCHAR(cilen, p); \
838         if (cilen != CILEN_CHAP || \
839             citype != (opt)) \
840             goto bad; \
841         GETSHORT(cishort, p); \
842         if (cishort != PPP_CHAP) \
843             goto bad; \
844         GETCHAR(cichar, p); \
845         if (cichar != (CHAP_DIGEST(val))) \
846           goto bad; \
847     }
848 #define ACKCILONG(opt, neg, val) \
849     if (neg) { \
850         if ((len -= CILEN_LONG) < 0) \
851             goto bad; \
852         GETCHAR(citype, p); \
853         GETCHAR(cilen, p); \
854         if (cilen != CILEN_LONG || \
855             citype != opt) \
856             goto bad; \
857         GETLONG(cilong, p); \
858         if (cilong != val) \
859             goto bad; \
860     }
861 #define ACKCILQR(opt, neg, val) \
862     if (neg) { \
863         if ((len -= CILEN_LQR) < 0) \
864             goto bad; \
865         GETCHAR(citype, p); \
866         GETCHAR(cilen, p); \
867         if (cilen != CILEN_LQR || \
868             citype != opt) \
869             goto bad; \
870         GETSHORT(cishort, p); \
871         if (cishort != PPP_LQR) \
872             goto bad; \
873         GETLONG(cilong, p); \
874         if (cilong != val) \
875           goto bad; \
876     }
877 #define ACKCIENDP(opt, neg, class, val, vlen) \
878     if (neg) { \
879         int i; \
880         if ((len -= CILEN_CHAR + vlen) < 0) \
881             goto bad; \
882         GETCHAR(citype, p); \
883         GETCHAR(cilen, p); \
884         if (cilen != CILEN_CHAR + vlen || \
885             citype != opt) \
886             goto bad; \
887         GETCHAR(cichar, p); \
888         if (cichar != class) \
889             goto bad; \
890         for (i = 0; i < vlen; ++i) { \
891             GETCHAR(cichar, p); \
892             if (cichar != val[i]) \
893                 goto bad; \
894         } \
895     }
896
897     ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
898     ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
899               go->asyncmap);
900     ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
901     ACKCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
902     ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap,
903                PPP_PAP);
904     ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
905     ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
906     ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
907     ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression);
908     ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression);
909     ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru);
910     ACKCIVOID(CI_SSNHF, go->neg_ssnhf);
911     ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class,
912               go->endpoint.value, go->endpoint.length);
913
914     /*
915      * If there are any remaining CIs, then this packet is bad.
916      */
917     if (len != 0)
918         goto bad;
919     return (1);
920 bad:
921     LCPDEBUG(("lcp_acki: received bad Ack!"));
922     return (0);
923 }
924
925
926 /*
927  * lcp_nakci - Peer has sent a NAK for some of our CIs.
928  * This should not modify any state if the Nak is bad
929  * or if LCP is in the OPENED state.
930  *
931  * Returns:
932  *      0 - Nak was bad.
933  *      1 - Nak was good.
934  */
935 static int
936 lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
937 {
938     lcp_options *go = &lcp_gotoptions[f->unit];
939     lcp_options *wo = &lcp_wantoptions[f->unit];
940     u_char citype, cichar, *next;
941     u_short cishort;
942     u_int32_t cilong;
943     lcp_options no;             /* options we've seen Naks for */
944     lcp_options try;            /* options to request next time */
945     int looped_back = 0;
946     int cilen;
947
948     BZERO(&no, sizeof(no));
949     try = *go;
950
951     /*
952      * Any Nak'd CIs must be in exactly the same order that we sent.
953      * Check packet length and CI length at each step.
954      * If we find any deviations, then this packet is bad.
955      */
956 #define NAKCIVOID(opt, neg) \
957     if (go->neg && \
958         len >= CILEN_VOID && \
959         p[1] == CILEN_VOID && \
960         p[0] == opt) { \
961         len -= CILEN_VOID; \
962         INCPTR(CILEN_VOID, p); \
963         no.neg = 1; \
964         try.neg = 0; \
965     }
966 #define NAKCICHAP(opt, neg, code) \
967     if (go->neg && \
968         len >= CILEN_CHAP && \
969         p[1] == CILEN_CHAP && \
970         p[0] == opt) { \
971         len -= CILEN_CHAP; \
972         INCPTR(2, p); \
973         GETSHORT(cishort, p); \
974         GETCHAR(cichar, p); \
975         no.neg = 1; \
976         code \
977     }
978 #define NAKCICHAR(opt, neg, code) \
979     if (go->neg && \
980         len >= CILEN_CHAR && \
981         p[1] == CILEN_CHAR && \
982         p[0] == opt) { \
983         len -= CILEN_CHAR; \
984         INCPTR(2, p); \
985         GETCHAR(cichar, p); \
986         no.neg = 1; \
987         code \
988     }
989 #define NAKCISHORT(opt, neg, code) \
990     if (go->neg && \
991         len >= CILEN_SHORT && \
992         p[1] == CILEN_SHORT && \
993         p[0] == opt) { \
994         len -= CILEN_SHORT; \
995         INCPTR(2, p); \
996         GETSHORT(cishort, p); \
997         no.neg = 1; \
998         code \
999     }
1000 #define NAKCILONG(opt, neg, code) \
1001     if (go->neg && \
1002         len >= CILEN_LONG && \
1003         p[1] == CILEN_LONG && \
1004         p[0] == opt) { \
1005         len -= CILEN_LONG; \
1006         INCPTR(2, p); \
1007         GETLONG(cilong, p); \
1008         no.neg = 1; \
1009         code \
1010     }
1011 #define NAKCILQR(opt, neg, code) \
1012     if (go->neg && \
1013         len >= CILEN_LQR && \
1014         p[1] == CILEN_LQR && \
1015         p[0] == opt) { \
1016         len -= CILEN_LQR; \
1017         INCPTR(2, p); \
1018         GETSHORT(cishort, p); \
1019         GETLONG(cilong, p); \
1020         no.neg = 1; \
1021         code \
1022     }
1023 #define NAKCIENDP(opt, neg) \
1024     if (go->neg && \
1025         len >= CILEN_CHAR && \
1026         p[0] == opt && \
1027         p[1] >= CILEN_CHAR && \
1028         p[1] <= len) { \
1029         len -= p[1]; \
1030         INCPTR(p[1], p); \
1031         no.neg = 1; \
1032         try.neg = 0; \
1033     }
1034
1035     /*
1036      * NOTE!  There must be no assignments to individual fields of *go in
1037      * the code below.  Any such assignment is a BUG!
1038      */
1039     /*
1040      * We don't care if they want to send us smaller packets than
1041      * we want.  Therefore, accept any MRU less than what we asked for,
1042      * but then ignore the new value when setting the MRU in the kernel.
1043      * If they send us a bigger MRU than what we asked, accept it, up to
1044      * the limit of the default MRU we'd get if we didn't negotiate.
1045      */
1046     if (go->neg_mru && go->mru != DEFMRU) {
1047         NAKCISHORT(CI_MRU, neg_mru,
1048                    if (cishort <= wo->mru || cishort <= DEFMRU)
1049                        try.mru = cishort;
1050                    );
1051     }
1052
1053     /*
1054      * Add any characters they want to our (receive-side) asyncmap.
1055      */
1056     if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) {
1057         NAKCILONG(CI_ASYNCMAP, neg_asyncmap,
1058                   try.asyncmap = go->asyncmap | cilong;
1059                   );
1060     }
1061
1062     /*
1063      * If they've nak'd our authentication-protocol, check whether
1064      * they are proposing a different protocol, or a different
1065      * hash algorithm for CHAP.
1066      */
1067     if ((go->neg_chap || go->neg_upap || go->neg_eap)
1068         && len >= CILEN_SHORT
1069         && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
1070         cilen = p[1];
1071         len -= cilen;
1072         no.neg_chap = go->neg_chap;
1073         no.neg_upap = go->neg_upap;
1074         no.neg_eap = go->neg_eap;
1075         INCPTR(2, p);
1076         GETSHORT(cishort, p);
1077         if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
1078             /* If we were asking for EAP, then we need to stop that. */
1079             if (go->neg_eap)
1080                 try.neg_eap = 0;
1081
1082             /* If we were asking for CHAP, then we need to stop that. */
1083             else if (go->neg_chap)
1084                 try.neg_chap = 0;
1085             /*
1086              * If we weren't asking for CHAP or EAP, then we were asking for
1087              * PAP, in which case this Nak is bad.
1088              */
1089             else
1090                 goto bad;
1091
1092         } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
1093             GETCHAR(cichar, p);
1094             /* Stop asking for EAP, if we were. */
1095             if (go->neg_eap) {
1096                 try.neg_eap = 0;
1097                 /* Try to set up to use their suggestion, if possible */
1098                 if (CHAP_CANDIGEST(go->chap_mdtype, cichar))
1099                     try.chap_mdtype = CHAP_MDTYPE_D(cichar);
1100             } else if (go->neg_chap) {
1101                 /*
1102                  * We were asking for our preferred algorithm, they must
1103                  * want something different.
1104                  */
1105                 if (cichar != CHAP_DIGEST(go->chap_mdtype)) {
1106                     if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) {
1107                         /* Use their suggestion if we support it ... */
1108                         try.chap_mdtype = CHAP_MDTYPE_D(cichar);
1109                     } else {
1110                         /* ... otherwise, try our next-preferred algorithm. */
1111                         try.chap_mdtype &= ~(CHAP_MDTYPE(try.chap_mdtype));
1112                         if (try.chap_mdtype == MDTYPE_NONE) /* out of algos */
1113                             try.neg_chap = 0;
1114                     }
1115                 } else {
1116                     /*
1117                      * Whoops, they Nak'd our algorithm of choice
1118                      * but then suggested it back to us.
1119                      */
1120                     goto bad;
1121                 }
1122             } else {
1123                 /*
1124                  * Stop asking for PAP if we were asking for it.
1125                  */
1126                 try.neg_upap = 0;
1127             }
1128
1129         } else {
1130
1131             /*
1132              * If we were asking for EAP, and they're Conf-Naking EAP,
1133              * well, that's just strange.  Nobody should do that.
1134              */
1135             if (cishort == PPP_EAP && cilen == CILEN_SHORT && go->neg_eap)
1136                 dbglog("Unexpected Conf-Nak for EAP");
1137
1138             /*
1139              * We don't recognize what they're suggesting.
1140              * Stop asking for what we were asking for.
1141              */
1142             if (go->neg_eap)
1143                 try.neg_eap = 0;
1144             else if (go->neg_chap)
1145                 try.neg_chap = 0;
1146             else
1147                 try.neg_upap = 0;
1148             p += cilen - CILEN_SHORT;
1149         }
1150     }
1151
1152     /*
1153      * If they can't cope with our link quality protocol, we'll have
1154      * to stop asking for LQR.  We haven't got any other protocol.
1155      * If they Nak the reporting period, take their value XXX ?
1156      */
1157     NAKCILQR(CI_QUALITY, neg_lqr,
1158              if (cishort != PPP_LQR)
1159                  try.neg_lqr = 0;
1160              else
1161                  try.lqr_period = cilong;
1162              );
1163
1164     /*
1165      * Only implementing CBCP...not the rest of the callback options
1166      */
1167     NAKCICHAR(CI_CALLBACK, neg_cbcp,
1168               try.neg_cbcp = 0;
1169               );
1170
1171     /*
1172      * Check for a looped-back line.
1173      */
1174     NAKCILONG(CI_MAGICNUMBER, neg_magicnumber,
1175               try.magicnumber = magic();
1176               looped_back = 1;
1177               );
1178
1179     /*
1180      * Peer shouldn't send Nak for protocol compression or
1181      * address/control compression requests; they should send
1182      * a Reject instead.  If they send a Nak, treat it as a Reject.
1183      */
1184     NAKCIVOID(CI_PCOMPRESSION, neg_pcompression);
1185     NAKCIVOID(CI_ACCOMPRESSION, neg_accompression);
1186
1187     /*
1188      * Nak for MRRU option - accept their value if it is smaller
1189      * than the one we want.
1190      */
1191     if (go->neg_mrru) {
1192         NAKCISHORT(CI_MRRU, neg_mrru,
1193                    if (treat_as_reject)
1194                        try.neg_mrru = 0;
1195                    else if (cishort <= wo->mrru)
1196                        try.mrru = cishort;
1197                    );
1198     }
1199
1200     /*
1201      * Nak for short sequence numbers shouldn't be sent, treat it
1202      * like a reject.
1203      */
1204     NAKCIVOID(CI_SSNHF, neg_ssnhf);
1205
1206     /*
1207      * Nak of the endpoint discriminator option is not permitted,
1208      * treat it like a reject.
1209      */
1210     NAKCIENDP(CI_EPDISC, neg_endpoint);
1211
1212     /*
1213      * There may be remaining CIs, if the peer is requesting negotiation
1214      * on an option that we didn't include in our request packet.
1215      * If we see an option that we requested, or one we've already seen
1216      * in this packet, then this packet is bad.
1217      * If we wanted to respond by starting to negotiate on the requested
1218      * option(s), we could, but we don't, because except for the
1219      * authentication type and quality protocol, if we are not negotiating
1220      * an option, it is because we were told not to.
1221      * For the authentication type, the Nak from the peer means
1222      * `let me authenticate myself with you' which is a bit pointless.
1223      * For the quality protocol, the Nak means `ask me to send you quality
1224      * reports', but if we didn't ask for them, we don't want them.
1225      * An option we don't recognize represents the peer asking to
1226      * negotiate some option we don't support, so ignore it.
1227      */
1228     while (len >= CILEN_VOID) {
1229         GETCHAR(citype, p);
1230         GETCHAR(cilen, p);
1231         if (cilen < CILEN_VOID || (len -= cilen) < 0)
1232             goto bad;
1233         next = p + cilen - 2;
1234
1235         switch (citype) {
1236         case CI_MRU:
1237             if ((go->neg_mru && go->mru != DEFMRU)
1238                 || no.neg_mru || cilen != CILEN_SHORT)
1239                 goto bad;
1240             GETSHORT(cishort, p);
1241             if (cishort < DEFMRU) {
1242                 try.neg_mru = 1;
1243                 try.mru = cishort;
1244             }
1245             break;
1246         case CI_ASYNCMAP:
1247             if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF)
1248                 || no.neg_asyncmap || cilen != CILEN_LONG)
1249                 goto bad;
1250             break;
1251         case CI_AUTHTYPE:
1252             if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap ||
1253                 go->neg_eap || no.neg_eap)
1254                 goto bad;
1255             break;
1256         case CI_MAGICNUMBER:
1257             if (go->neg_magicnumber || no.neg_magicnumber ||
1258                 cilen != CILEN_LONG)
1259                 goto bad;
1260             break;
1261         case CI_PCOMPRESSION:
1262             if (go->neg_pcompression || no.neg_pcompression
1263                 || cilen != CILEN_VOID)
1264                 goto bad;
1265             break;
1266         case CI_ACCOMPRESSION:
1267             if (go->neg_accompression || no.neg_accompression
1268                 || cilen != CILEN_VOID)
1269                 goto bad;
1270             break;
1271         case CI_QUALITY:
1272             if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR)
1273                 goto bad;
1274             break;
1275         case CI_MRRU:
1276             if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT)
1277                 goto bad;
1278             break;
1279         case CI_SSNHF:
1280             if (go->neg_ssnhf || no.neg_ssnhf || cilen != CILEN_VOID)
1281                 goto bad;
1282             try.neg_ssnhf = 1;
1283             break;
1284         case CI_EPDISC:
1285             if (go->neg_endpoint || no.neg_endpoint || cilen < CILEN_CHAR)
1286                 goto bad;
1287             break;
1288         }
1289         p = next;
1290     }
1291
1292     /*
1293      * OK, the Nak is good.  Now we can update state.
1294      * If there are any options left we ignore them.
1295      */
1296     if (f->state != OPENED) {
1297         if (looped_back) {
1298             if (++try.numloops >= lcp_loopbackfail) {
1299                 notice("Serial line is looped back.");
1300                 ppp_set_status(EXIT_LOOPBACK);
1301                 lcp_close(f->unit, "Loopback detected");
1302             }
1303         } else
1304             try.numloops = 0;
1305         *go = try;
1306     }
1307
1308     return 1;
1309
1310 bad:
1311     LCPDEBUG(("lcp_nakci: received bad Nak!"));
1312     return 0;
1313 }
1314
1315
1316 /*
1317  * lcp_rejci - Peer has Rejected some of our CIs.
1318  * This should not modify any state if the Reject is bad
1319  * or if LCP is in the OPENED state.
1320  *
1321  * Returns:
1322  *      0 - Reject was bad.
1323  *      1 - Reject was good.
1324  */
1325 static int
1326 lcp_rejci(fsm *f, u_char *p, int len)
1327 {
1328     lcp_options *go = &lcp_gotoptions[f->unit];
1329     u_char cichar;
1330     u_short cishort;
1331     u_int32_t cilong;
1332     lcp_options try;            /* options to request next time */
1333
1334     try = *go;
1335
1336     /*
1337      * Any Rejected CIs must be in exactly the same order that we sent.
1338      * Check packet length and CI length at each step.
1339      * If we find any deviations, then this packet is bad.
1340      */
1341 #define REJCIVOID(opt, neg) \
1342     if (go->neg && \
1343         len >= CILEN_VOID && \
1344         p[1] == CILEN_VOID && \
1345         p[0] == opt) { \
1346         len -= CILEN_VOID; \
1347         INCPTR(CILEN_VOID, p); \
1348         try.neg = 0; \
1349     }
1350 #define REJCISHORT(opt, neg, val) \
1351     if (go->neg && \
1352         len >= CILEN_SHORT && \
1353         p[1] == CILEN_SHORT && \
1354         p[0] == opt) { \
1355         len -= CILEN_SHORT; \
1356         INCPTR(2, p); \
1357         GETSHORT(cishort, p); \
1358         /* Check rejected value. */ \
1359         if (cishort != val) \
1360             goto bad; \
1361         try.neg = 0; \
1362     }
1363 #define REJCICHAP(opt, neg, val) \
1364     if (go->neg && \
1365         len >= CILEN_CHAP && \
1366         p[1] == CILEN_CHAP && \
1367         p[0] == opt) { \
1368         len -= CILEN_CHAP; \
1369         INCPTR(2, p); \
1370         GETSHORT(cishort, p); \
1371         GETCHAR(cichar, p); \
1372         /* Check rejected value. */ \
1373         if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \
1374             goto bad; \
1375         try.neg = 0; \
1376         try.neg_eap = try.neg_upap = 0; \
1377     }
1378 #define REJCILONG(opt, neg, val) \
1379     if (go->neg && \
1380         len >= CILEN_LONG && \
1381         p[1] == CILEN_LONG && \
1382         p[0] == opt) { \
1383         len -= CILEN_LONG; \
1384         INCPTR(2, p); \
1385         GETLONG(cilong, p); \
1386         /* Check rejected value. */ \
1387         if (cilong != val) \
1388             goto bad; \
1389         try.neg = 0; \
1390     }
1391 #define REJCILQR(opt, neg, val) \
1392     if (go->neg && \
1393         len >= CILEN_LQR && \
1394         p[1] == CILEN_LQR && \
1395         p[0] == opt) { \
1396         len -= CILEN_LQR; \
1397         INCPTR(2, p); \
1398         GETSHORT(cishort, p); \
1399         GETLONG(cilong, p); \
1400         /* Check rejected value. */ \
1401         if (cishort != PPP_LQR || cilong != val) \
1402             goto bad; \
1403         try.neg = 0; \
1404     }
1405 #define REJCICBCP(opt, neg, val) \
1406     if (go->neg && \
1407         len >= CILEN_CBCP && \
1408         p[1] == CILEN_CBCP && \
1409         p[0] == opt) { \
1410         len -= CILEN_CBCP; \
1411         INCPTR(2, p); \
1412         GETCHAR(cichar, p); \
1413         /* Check rejected value. */ \
1414         if (cichar != val) \
1415             goto bad; \
1416         try.neg = 0; \
1417     }
1418 #define REJCIENDP(opt, neg, class, val, vlen) \
1419     if (go->neg && \
1420         len >= CILEN_CHAR + vlen && \
1421         p[0] == opt && \
1422         p[1] == CILEN_CHAR + vlen) { \
1423         int i; \
1424         len -= CILEN_CHAR + vlen; \
1425         INCPTR(2, p); \
1426         GETCHAR(cichar, p); \
1427         if (cichar != class) \
1428             goto bad; \
1429         for (i = 0; i < vlen; ++i) { \
1430             GETCHAR(cichar, p); \
1431             if (cichar != val[i]) \
1432                 goto bad; \
1433         } \
1434         try.neg = 0; \
1435     }
1436
1437     REJCISHORT(CI_MRU, neg_mru, go->mru);
1438     REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
1439     REJCISHORT(CI_AUTHTYPE, neg_eap, PPP_EAP);
1440     if (!go->neg_eap) {
1441         REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype);
1442         if (!go->neg_chap) {
1443             REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
1444         }
1445     }
1446     REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
1447     REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
1448     REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber);
1449     REJCIVOID(CI_PCOMPRESSION, neg_pcompression);
1450     REJCIVOID(CI_ACCOMPRESSION, neg_accompression);
1451     REJCISHORT(CI_MRRU, neg_mrru, go->mrru);
1452     REJCIVOID(CI_SSNHF, neg_ssnhf);
1453     REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class,
1454               go->endpoint.value, go->endpoint.length);
1455
1456     /*
1457      * If there are any remaining CIs, then this packet is bad.
1458      */
1459     if (len != 0)
1460         goto bad;
1461     /*
1462      * Now we can update state.
1463      */
1464     if (f->state != OPENED)
1465         *go = try;
1466     return 1;
1467
1468 bad:
1469     LCPDEBUG(("lcp_rejci: received bad Reject!"));
1470     return 0;
1471 }
1472
1473
1474 /*
1475  * lcp_reqci - Check the peer's requested CIs and send appropriate response.
1476  *
1477  * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified
1478  * appropriately.  If reject_if_disagree is non-zero, doesn't return
1479  * CONFNAK; returns CONFREJ if it can't return CONFACK.
1480  */
1481 static int
1482 lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree)
1483 {
1484     lcp_options *go = &lcp_gotoptions[f->unit];
1485     lcp_options *ho = &lcp_hisoptions[f->unit];
1486     lcp_options *ao = &lcp_allowoptions[f->unit];
1487     u_char *cip, *next;         /* Pointer to current and next CIs */
1488     int cilen, citype, cichar;  /* Parsed len, type, char value */
1489     u_short cishort;            /* Parsed short value */
1490     u_int32_t cilong;           /* Parse long value */
1491     int rc = CONFACK;           /* Final packet return code */
1492     int orc;                    /* Individual option return code */
1493     u_char *p;                  /* Pointer to next char to parse */
1494     u_char *rejp;               /* Pointer to next char in reject frame */
1495     u_char *nakp;               /* Pointer to next char in Nak frame */
1496     int l = *lenp;              /* Length left */
1497
1498     /*
1499      * Reset all his options.
1500      */
1501     BZERO(ho, sizeof(*ho));
1502
1503     /*
1504      * Process all his options.
1505      */
1506     next = inp;
1507     nakp = nak_buffer;
1508     rejp = inp;
1509     while (l) {
1510         orc = CONFACK;                  /* Assume success */
1511         cip = p = next;                 /* Remember begining of CI */
1512         if (l < 2 ||                    /* Not enough data for CI header or */
1513             p[1] < 2 ||                 /*  CI length too small or */
1514             p[1] > l) {                 /*  CI length too big? */
1515             LCPDEBUG(("lcp_reqci: bad CI length!"));
1516             orc = CONFREJ;              /* Reject bad CI */
1517             cilen = l;                  /* Reject till end of packet */
1518             l = 0;                      /* Don't loop again */
1519             citype = 0;
1520             goto endswitch;
1521         }
1522         GETCHAR(citype, p);             /* Parse CI type */
1523         GETCHAR(cilen, p);              /* Parse CI length */
1524         l -= cilen;                     /* Adjust remaining length */
1525         next += cilen;                  /* Step to next CI */
1526
1527         switch (citype) {               /* Check CI type */
1528         case CI_MRU:
1529             if (!ao->neg_mru ||         /* Allow option? */
1530                 cilen != CILEN_SHORT) { /* Check CI length */
1531                 orc = CONFREJ;          /* Reject CI */
1532                 break;
1533             }
1534             GETSHORT(cishort, p);       /* Parse MRU */
1535
1536             /*
1537              * He must be able to receive at least our minimum.
1538              * No need to check a maximum.  If he sends a large number,
1539              * we'll just ignore it.
1540              */
1541             if (cishort < MINMRU) {
1542                 orc = CONFNAK;          /* Nak CI */
1543                 PUTCHAR(CI_MRU, nakp);
1544                 PUTCHAR(CILEN_SHORT, nakp);
1545                 PUTSHORT(MINMRU, nakp); /* Give him a hint */
1546                 break;
1547             }
1548             ho->neg_mru = 1;            /* Remember he sent MRU */
1549             ho->mru = cishort;          /* And remember value */
1550             break;
1551
1552         case CI_ASYNCMAP:
1553             if (!ao->neg_asyncmap ||
1554                 cilen != CILEN_LONG) {
1555                 orc = CONFREJ;
1556                 break;
1557             }
1558             GETLONG(cilong, p);
1559
1560             /*
1561              * Asyncmap must have set at least the bits
1562              * which are set in lcp_allowoptions[unit].asyncmap.
1563              */
1564             if ((ao->asyncmap & ~cilong) != 0) {
1565                 orc = CONFNAK;
1566                 PUTCHAR(CI_ASYNCMAP, nakp);
1567                 PUTCHAR(CILEN_LONG, nakp);
1568                 PUTLONG(ao->asyncmap | cilong, nakp);
1569                 break;
1570             }
1571             ho->neg_asyncmap = 1;
1572             ho->asyncmap = cilong;
1573             break;
1574
1575         case CI_AUTHTYPE:
1576             if (cilen < CILEN_SHORT ||
1577                 !(ao->neg_upap || ao->neg_chap || ao->neg_eap)) {
1578                 /*
1579                  * Reject the option if we're not willing to authenticate.
1580                  */
1581                 dbglog("No auth is possible");
1582                 orc = CONFREJ;
1583                 break;
1584             }
1585             GETSHORT(cishort, p);
1586
1587             /*
1588              * Authtype must be PAP, CHAP, or EAP.
1589              *
1590              * Note: if more than one of ao->neg_upap, ao->neg_chap, and
1591              * ao->neg_eap are set, and the peer sends a Configure-Request
1592              * with two or more authenticate-protocol requests, then we will
1593              * reject the second request.
1594              * Whether we end up doing CHAP, UPAP, or EAP depends then on
1595              * the ordering of the CIs in the peer's Configure-Request.
1596              */
1597
1598             if (cishort == PPP_PAP) {
1599                 /* we've already accepted CHAP or EAP */
1600                 if (ho->neg_chap || ho->neg_eap ||
1601                     cilen != CILEN_SHORT) {
1602                     LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));
1603                     orc = CONFREJ;
1604                     break;
1605                 }
1606                 if (!ao->neg_upap) {    /* we don't want to do PAP */
1607                     orc = CONFNAK;      /* NAK it and suggest CHAP or EAP */
1608                     PUTCHAR(CI_AUTHTYPE, nakp);
1609                     if (ao->neg_eap) {
1610                         PUTCHAR(CILEN_SHORT, nakp);
1611                         PUTSHORT(PPP_EAP, nakp);
1612                     } else {
1613                         PUTCHAR(CILEN_CHAP, nakp);
1614                         PUTSHORT(PPP_CHAP, nakp);
1615                         PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
1616                     }
1617                     break;
1618                 }
1619                 ho->neg_upap = 1;
1620                 break;
1621             }
1622             if (cishort == PPP_CHAP) {
1623                 /* we've already accepted PAP or EAP */
1624                 if (ho->neg_upap || ho->neg_eap ||
1625                     cilen != CILEN_CHAP) {
1626                     LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));
1627                     orc = CONFREJ;
1628                     break;
1629                 }
1630                 if (!ao->neg_chap) {    /* we don't want to do CHAP */
1631                     orc = CONFNAK;      /* NAK it and suggest EAP or PAP */
1632                     PUTCHAR(CI_AUTHTYPE, nakp);
1633                     PUTCHAR(CILEN_SHORT, nakp);
1634                     if (ao->neg_eap) {
1635                         PUTSHORT(PPP_EAP, nakp);
1636                     } else {
1637                         PUTSHORT(PPP_PAP, nakp);
1638                     }
1639                     break;
1640                 }
1641                 GETCHAR(cichar, p);     /* get digest type */
1642                 if (!(CHAP_CANDIGEST(ao->chap_mdtype, cichar))) {
1643                     /*
1644                      * We can't/won't do the requested type,
1645                      * suggest something else.
1646                      */
1647                     orc = CONFNAK;
1648                     PUTCHAR(CI_AUTHTYPE, nakp);
1649                     PUTCHAR(CILEN_CHAP, nakp);
1650                     PUTSHORT(PPP_CHAP, nakp);
1651                     PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
1652                     break;
1653                 }
1654                 ho->chap_mdtype = CHAP_MDTYPE_D(cichar); /* save md type */
1655                 ho->neg_chap = 1;
1656                 break;
1657             }
1658             if (cishort == PPP_EAP) {
1659                 /* we've already accepted CHAP or PAP */
1660                 if (ho->neg_chap || ho->neg_upap || cilen != CILEN_SHORT) {
1661                     LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE EAP, rejecting..."));
1662                     orc = CONFREJ;
1663                     break;
1664                 }
1665                 if (!ao->neg_eap) {     /* we don't want to do EAP */
1666                     orc = CONFNAK;      /* NAK it and suggest CHAP or PAP */
1667                     PUTCHAR(CI_AUTHTYPE, nakp);
1668                     if (ao->neg_chap) {
1669                         PUTCHAR(CILEN_CHAP, nakp);
1670                         PUTSHORT(PPP_CHAP, nakp);
1671                         PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
1672                     } else {
1673                         PUTCHAR(CILEN_SHORT, nakp);
1674                         PUTSHORT(PPP_PAP, nakp);
1675                     }
1676                     break;
1677                 }
1678                 ho->neg_eap = 1;
1679                 break;
1680             }
1681
1682             /*
1683              * We don't recognize the protocol they're asking for.
1684              * Nak it with something we're willing to do.
1685              * (At this point we know ao->neg_upap || ao->neg_chap ||
1686              * ao->neg_eap.)
1687              */
1688             orc = CONFNAK;
1689             PUTCHAR(CI_AUTHTYPE, nakp);
1690             if (ao->neg_eap) {
1691                 PUTCHAR(CILEN_SHORT, nakp);
1692                 PUTSHORT(PPP_EAP, nakp);
1693             } else if (ao->neg_chap) {
1694                 PUTCHAR(CILEN_CHAP, nakp);
1695                 PUTSHORT(PPP_CHAP, nakp);
1696                 PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
1697             } else {
1698                 PUTCHAR(CILEN_SHORT, nakp);
1699                 PUTSHORT(PPP_PAP, nakp);
1700             }
1701             break;
1702
1703         case CI_QUALITY:
1704             if (!ao->neg_lqr ||
1705                 cilen != CILEN_LQR) {
1706                 orc = CONFREJ;
1707                 break;
1708             }
1709
1710             GETSHORT(cishort, p);
1711             GETLONG(cilong, p);
1712
1713             /*
1714              * Check the protocol and the reporting period.
1715              * XXX When should we Nak this, and what with?
1716              */
1717             if (cishort != PPP_LQR) {
1718                 orc = CONFNAK;
1719                 PUTCHAR(CI_QUALITY, nakp);
1720                 PUTCHAR(CILEN_LQR, nakp);
1721                 PUTSHORT(PPP_LQR, nakp);
1722                 PUTLONG(ao->lqr_period, nakp);
1723                 break;
1724             }
1725             break;
1726
1727         case CI_MAGICNUMBER:
1728             if (!(ao->neg_magicnumber || go->neg_magicnumber) ||
1729                 cilen != CILEN_LONG) {
1730                 orc = CONFREJ;
1731                 break;
1732             }
1733             GETLONG(cilong, p);
1734
1735             /*
1736              * He must have a different magic number.
1737              */
1738             if (go->neg_magicnumber &&
1739                 cilong == go->magicnumber) {
1740                 cilong = magic();       /* Don't put magic() inside macro! */
1741                 orc = CONFNAK;
1742                 PUTCHAR(CI_MAGICNUMBER, nakp);
1743                 PUTCHAR(CILEN_LONG, nakp);
1744                 PUTLONG(cilong, nakp);
1745                 break;
1746             }
1747             ho->neg_magicnumber = 1;
1748             ho->magicnumber = cilong;
1749             break;
1750
1751
1752         case CI_PCOMPRESSION:
1753             if (!ao->neg_pcompression ||
1754                 cilen != CILEN_VOID) {
1755                 orc = CONFREJ;
1756                 break;
1757             }
1758             ho->neg_pcompression = 1;
1759             break;
1760
1761         case CI_ACCOMPRESSION:
1762             if (!ao->neg_accompression ||
1763                 cilen != CILEN_VOID) {
1764                 orc = CONFREJ;
1765                 break;
1766             }
1767             ho->neg_accompression = 1;
1768             break;
1769
1770         case CI_MRRU:
1771             if (!ao->neg_mrru || !multilink ||
1772                 cilen != CILEN_SHORT) {
1773                 orc = CONFREJ;
1774                 break;
1775             }
1776
1777             GETSHORT(cishort, p);
1778             /* possibly should insist on a minimum/maximum MRRU here */
1779             ho->neg_mrru = 1;
1780             ho->mrru = cishort;
1781             break;
1782
1783         case CI_SSNHF:
1784             if (!ao->neg_ssnhf || !multilink ||
1785                 cilen != CILEN_VOID) {
1786                 orc = CONFREJ;
1787                 break;
1788             }
1789             ho->neg_ssnhf = 1;
1790             break;
1791
1792         case CI_EPDISC:
1793             if (!ao->neg_endpoint ||
1794                 cilen < CILEN_CHAR ||
1795                 cilen > CILEN_CHAR + MAX_ENDP_LEN) {
1796                 orc = CONFREJ;
1797                 break;
1798             }
1799             GETCHAR(cichar, p);
1800             cilen -= CILEN_CHAR;
1801             ho->neg_endpoint = 1;
1802             ho->endpoint.class = cichar;
1803             ho->endpoint.length = cilen;
1804             BCOPY(p, ho->endpoint.value, cilen);
1805             INCPTR(cilen, p);
1806             break;
1807
1808         default:
1809             LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype));
1810             orc = CONFREJ;
1811             break;
1812         }
1813
1814 endswitch:
1815         if (orc == CONFACK &&           /* Good CI */
1816             rc != CONFACK)              /*  but prior CI wasnt? */
1817             continue;                   /* Don't send this one */
1818
1819         if (orc == CONFNAK) {           /* Nak this CI? */
1820             if (reject_if_disagree      /* Getting fed up with sending NAKs? */
1821                 && citype != CI_MAGICNUMBER) {
1822                 orc = CONFREJ;          /* Get tough if so */
1823             } else {
1824                 if (rc == CONFREJ)      /* Rejecting prior CI? */
1825                     continue;           /* Don't send this one */
1826                 rc = CONFNAK;
1827             }
1828         }
1829         if (orc == CONFREJ) {           /* Reject this CI */
1830             rc = CONFREJ;
1831             if (cip != rejp)            /* Need to move rejected CI? */
1832                 BCOPY(cip, rejp, cilen); /* Move it */
1833             INCPTR(cilen, rejp);        /* Update output pointer */
1834         }
1835     }
1836
1837     /*
1838      * If we wanted to send additional NAKs (for unsent CIs), the
1839      * code would go here.  The extra NAKs would go at *nakp.
1840      * At present there are no cases where we want to ask the
1841      * peer to negotiate an option.
1842      */
1843
1844     switch (rc) {
1845     case CONFACK:
1846         *lenp = next - inp;
1847         break;
1848     case CONFNAK:
1849         /*
1850          * Copy the Nak'd options from the nak_buffer to the caller's buffer.
1851          */
1852         *lenp = nakp - nak_buffer;
1853         BCOPY(nak_buffer, inp, *lenp);
1854         break;
1855     case CONFREJ:
1856         *lenp = rejp - inp;
1857         break;
1858     }
1859
1860     LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc)));
1861     return (rc);                        /* Return final code */
1862 }
1863
1864
1865 /*
1866  * lcp_up - LCP has come UP.
1867  */
1868 static void
1869 lcp_up(fsm *f)
1870 {
1871     lcp_options *wo = &lcp_wantoptions[f->unit];
1872     lcp_options *ho = &lcp_hisoptions[f->unit];
1873     lcp_options *go = &lcp_gotoptions[f->unit];
1874     lcp_options *ao = &lcp_allowoptions[f->unit];
1875     int mtu, mru;
1876
1877     if (!go->neg_magicnumber)
1878         go->magicnumber = 0;
1879     if (!ho->neg_magicnumber)
1880         ho->magicnumber = 0;
1881
1882     /*
1883      * Set our MTU to the smaller of the MTU we wanted and
1884      * the MRU our peer wanted.  If we negotiated an MRU,
1885      * set our MRU to the larger of value we wanted and
1886      * the value we got in the negotiation.
1887      * Note on the MTU: the link MTU can be the MRU the peer wanted,
1888      * the interface MTU is set to the lowest of that, the
1889      * MTU we want to use, and our link MRU.
1890      */
1891     mtu = ho->neg_mru? ho->mru: PPP_MRU;
1892     mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU;
1893 #ifdef PPP_WITH_MULTILINK
1894     if (!(multilink && go->neg_mrru && ho->neg_mrru))
1895 #endif /* PPP_WITH_MULTILINK */
1896         ppp_set_mtu(f->unit, MIN(MIN(mtu, mru), ao->mru));
1897     ppp_send_config(f->unit, mtu,
1898                     (ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
1899                     ho->neg_pcompression, ho->neg_accompression);
1900     ppp_recv_config(f->unit, mru,
1901                     (lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff),
1902                     go->neg_pcompression, go->neg_accompression);
1903
1904     if (ho->neg_mru)
1905         peer_mru[f->unit] = ho->mru;
1906
1907     lcp_echo_lowerup(f->unit);  /* Enable echo messages */
1908
1909     link_established(f->unit);
1910 }
1911
1912
1913 /*
1914  * lcp_down - LCP has gone DOWN.
1915  *
1916  * Alert other protocols.
1917  */
1918 static void
1919 lcp_down(fsm *f)
1920 {
1921     lcp_options *go = &lcp_gotoptions[f->unit];
1922
1923     lcp_echo_lowerdown(f->unit);
1924
1925     link_down(f->unit);
1926
1927     ppp_send_config(f->unit, PPP_MRU, 0xffffffff, 0, 0);
1928     ppp_recv_config(f->unit, PPP_MRU,
1929                     (go->neg_asyncmap? go->asyncmap: 0xffffffff),
1930                     go->neg_pcompression, go->neg_accompression);
1931     peer_mru[f->unit] = PPP_MRU;
1932 }
1933
1934
1935 /*
1936  * lcp_starting - LCP needs the lower layer up.
1937  */
1938 static void
1939 lcp_starting(fsm *f)
1940 {
1941     link_required(f->unit);
1942 }
1943
1944
1945 /*
1946  * lcp_finished - LCP has finished with the lower layer.
1947  */
1948 static void
1949 lcp_finished(fsm *f)
1950 {
1951     link_terminated(f->unit);
1952 }
1953
1954
1955 /*
1956  * lcp_printpkt - print the contents of an LCP packet.
1957  */
1958 static char *lcp_codenames[] = {
1959     "ConfReq", "ConfAck", "ConfNak", "ConfRej",
1960     "TermReq", "TermAck", "CodeRej", "ProtRej",
1961     "EchoReq", "EchoRep", "DiscReq", "Ident",
1962     "TimeRem"
1963 };
1964
1965 static int
1966 lcp_printpkt(u_char *p, int plen, void (*printer)(void *, char *, ...), void *arg)
1967 {
1968     int code, id, len, olen, i;
1969     u_char *pstart, *optend;
1970     u_short cishort;
1971     u_int32_t cilong;
1972
1973     if (plen < HEADERLEN)
1974         return 0;
1975     pstart = p;
1976     GETCHAR(code, p);
1977     GETCHAR(id, p);
1978     GETSHORT(len, p);
1979     if (len < HEADERLEN || len > plen)
1980         return 0;
1981
1982     if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *))
1983         printer(arg, " %s", lcp_codenames[code-1]);
1984     else
1985         printer(arg, " code=0x%x", code);
1986     printer(arg, " id=0x%x", id);
1987     len -= HEADERLEN;
1988     switch (code) {
1989     case CONFREQ:
1990     case CONFACK:
1991     case CONFNAK:
1992     case CONFREJ:
1993         /* print option list */
1994         while (len >= 2) {
1995             GETCHAR(code, p);
1996             GETCHAR(olen, p);
1997             p -= 2;
1998             if (olen < 2 || olen > len) {
1999                 break;
2000             }
2001             printer(arg, " <");
2002             len -= olen;
2003             optend = p + olen;
2004             switch (code) {
2005             case CI_MRU:
2006                 if (olen == CILEN_SHORT) {
2007                     p += 2;
2008                     GETSHORT(cishort, p);
2009                     printer(arg, "mru %d", cishort);
2010                 }
2011                 break;
2012             case CI_ASYNCMAP:
2013                 if (olen == CILEN_LONG) {
2014                     p += 2;
2015                     GETLONG(cilong, p);
2016                     printer(arg, "asyncmap 0x%x", cilong);
2017                 }
2018                 break;
2019             case CI_AUTHTYPE:
2020                 if (olen >= CILEN_SHORT) {
2021                     p += 2;
2022                     printer(arg, "auth ");
2023                     GETSHORT(cishort, p);
2024                     switch (cishort) {
2025                     case PPP_PAP:
2026                         printer(arg, "pap");
2027                         break;
2028                     case PPP_CHAP:
2029                         printer(arg, "chap");
2030                         if (p < optend) {
2031                             switch (*p) {
2032                             case CHAP_MD5:
2033                                 printer(arg, " MD5");
2034                                 ++p;
2035                                 break;
2036                             case CHAP_MICROSOFT:
2037                                 printer(arg, " MS");
2038                                 ++p;
2039                                 break;
2040
2041                             case CHAP_MICROSOFT_V2:
2042                                 printer(arg, " MS-v2");
2043                                 ++p;
2044                                 break;
2045                             }
2046                         }
2047                         break;
2048                     case PPP_EAP:
2049                         printer(arg, "eap");
2050                         break;
2051                     default:
2052                         printer(arg, "0x%x", cishort);
2053                     }
2054                 }
2055                 break;
2056             case CI_QUALITY:
2057                 if (olen >= CILEN_SHORT) {
2058                     p += 2;
2059                     printer(arg, "quality ");
2060                     GETSHORT(cishort, p);
2061                     switch (cishort) {
2062                     case PPP_LQR:
2063                         printer(arg, "lqr");
2064                         break;
2065                     default:
2066                         printer(arg, "0x%x", cishort);
2067                     }
2068                 }
2069                 break;
2070             case CI_CALLBACK:
2071                 if (olen >= CILEN_CHAR) {
2072                     p += 2;
2073                     printer(arg, "callback ");
2074                     GETCHAR(cishort, p);
2075                     switch (cishort) {
2076                     case CBCP_OPT:
2077                         printer(arg, "CBCP");
2078                         break;
2079                     default:
2080                         printer(arg, "0x%x", cishort);
2081                     }
2082                 }
2083                 break;
2084             case CI_MAGICNUMBER:
2085                 if (olen == CILEN_LONG) {
2086                     p += 2;
2087                     GETLONG(cilong, p);
2088                     printer(arg, "magic 0x%x", cilong);
2089                 }
2090                 break;
2091             case CI_PCOMPRESSION:
2092                 if (olen == CILEN_VOID) {
2093                     p += 2;
2094                     printer(arg, "pcomp");
2095                 }
2096                 break;
2097             case CI_ACCOMPRESSION:
2098                 if (olen == CILEN_VOID) {
2099                     p += 2;
2100                     printer(arg, "accomp");
2101                 }
2102                 break;
2103             case CI_MRRU:
2104                 if (olen == CILEN_SHORT) {
2105                     p += 2;
2106                     GETSHORT(cishort, p);
2107                     printer(arg, "mrru %d", cishort);
2108                 }
2109                 break;
2110             case CI_SSNHF:
2111                 if (olen == CILEN_VOID) {
2112                     p += 2;
2113                     printer(arg, "ssnhf");
2114                 }
2115                 break;
2116             case CI_EPDISC:
2117 #ifdef PPP_WITH_MULTILINK
2118                 if (olen >= CILEN_CHAR) {
2119                     struct epdisc epd;
2120                     p += 2;
2121                     GETCHAR(epd.class, p);
2122                     epd.length = olen - CILEN_CHAR;
2123                     if (epd.length > MAX_ENDP_LEN)
2124                         epd.length = MAX_ENDP_LEN;
2125                     if (epd.length > 0) {
2126                         BCOPY(p, epd.value, epd.length);
2127                         p += epd.length;
2128                     }
2129                     printer(arg, "endpoint [%s]", epdisc_to_str(&epd));
2130                 }
2131 #else
2132                 printer(arg, "endpoint");
2133 #endif
2134                 break;
2135             }
2136             while (p < optend) {
2137                 GETCHAR(code, p);
2138                 printer(arg, " %.2x", code);
2139             }
2140             printer(arg, ">");
2141         }
2142         break;
2143
2144     case TERMACK:
2145     case TERMREQ:
2146         if (len > 0 && *p >= ' ' && *p < 0x7f) {
2147             printer(arg, " ");
2148             print_string((char *)p, len, printer, arg);
2149             p += len;
2150             len = 0;
2151         }
2152         break;
2153
2154     case ECHOREQ:
2155     case ECHOREP:
2156     case DISCREQ:
2157         if (len >= 4) {
2158             GETLONG(cilong, p);
2159             printer(arg, " magic=0x%x", cilong);
2160             len -= 4;
2161         }
2162         break;
2163
2164     case IDENTIF:
2165     case TIMEREM:
2166         if (len >= 4) {
2167             GETLONG(cilong, p);
2168             printer(arg, " magic=0x%x", cilong);
2169             len -= 4;
2170         }
2171         if (code == TIMEREM) {
2172             if (len < 4)
2173                 break;
2174             GETLONG(cilong, p);
2175             printer(arg, " seconds=%u", cilong);
2176             len -= 4;
2177         }
2178         if (len > 0) {
2179             printer(arg, " ");
2180             print_string((char *)p, len, printer, arg);
2181             p += len;
2182             len = 0;
2183         }
2184         break;
2185     }
2186
2187     /* print the rest of the bytes in the packet */
2188     for (i = 0; i < len && i < 32; ++i) {
2189         GETCHAR(code, p);
2190         printer(arg, " %.2x", code);
2191     }
2192     if (i < len) {
2193         printer(arg, " ...");
2194         p += len - i;
2195     }
2196
2197     return p - pstart;
2198 }
2199
2200 /*
2201  * Time to shut down the link because there is nothing out there.
2202  */
2203
2204 static
2205 void LcpLinkFailure (fsm *f)
2206 {
2207     if (f->state == OPENED) {
2208         info("No response to %d echo-requests", lcp_echos_pending);
2209         notice("Serial link appears to be disconnected.");
2210         ppp_set_status(EXIT_PEER_DEAD);
2211         lcp_close(f->unit, "Peer not responding");
2212     }
2213 }
2214
2215 /*
2216  * Timer expired for the LCP echo requests from this process.
2217  */
2218
2219 static void
2220 LcpEchoCheck (fsm *f)
2221 {
2222     LcpSendEchoRequest (f);
2223     if (f->state != OPENED)
2224         return;
2225
2226     /*
2227      * Start the timer for the next interval.
2228      */
2229     if (lcp_echo_timer_running)
2230         warn("assertion lcp_echo_timer_running==0 failed");
2231     TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval);
2232     lcp_echo_timer_running = 1;
2233 }
2234
2235 /*
2236  * LcpEchoTimeout - Timer expired on the LCP echo
2237  */
2238
2239 static void
2240 LcpEchoTimeout (void *arg)
2241 {
2242     if (lcp_echo_timer_running != 0) {
2243         lcp_echo_timer_running = 0;
2244         LcpEchoCheck ((fsm *) arg);
2245     }
2246 }
2247
2248 /*
2249  * Log the round-trip time (RTT) of the received LCP echo-request.
2250  *
2251  * The header section at the beginning of lcp_rtt_file contains
2252  * LCP_RTT_HEADER_LENGTH fields, each a u_int32_t in network byte order:
2253  * [0] LCP_RTT_MAGIC
2254  * [1] status (1: the file is open and is being written)
2255  * [2] index of the most recently updated element
2256  * [3] the value of the lcp-echo-interval parameter
2257  *
2258  * The header is followed by a ring buffer of LCP_RTT_ELEMENTS elements, each
2259  * containing a pair of u_int32_t in network byte order with this content:
2260  * [0] UNIX timestamp
2261  * [1] bits 24-31: the number of lost LCP echo replies
2262  *     bits 0-23:  the measured RTT in microseconds
2263  *
2264  * The timestamp is unsigned to support storing dates beyond 2038.
2265  *
2266  * Consumers of lcp_rtt_file are expected to:
2267  * - read the complete file of arbitrary length
2268  * - check the magic number
2269  * - process the data elements starting at the index
2270  * - ignore any elements with a timestamp of 0
2271  */
2272 static void
2273 lcp_rtt_update_buffer (unsigned long rtt)
2274 {
2275     volatile u_int32_t *const ring_header = lcp_rtt_buffer;
2276     volatile u_int32_t *const ring_buffer = lcp_rtt_buffer
2277         + LCP_RTT_HEADER_LENGTH;
2278     unsigned int next_entry, lost;
2279
2280     /* choose the next entry where the data will be stored */
2281     if (ntohl(ring_header[2]) >= (LCP_RTT_ELEMENTS - 1) * 2)
2282         next_entry = 0;                         /* go back to the beginning */
2283     else
2284         next_entry = ntohl(ring_header[2]) + 2; /* use the next one */
2285
2286     /* update the data element */
2287     /* storing the timestamp in an *unsigned* long allows dates up to 2106 */
2288     ring_buffer[next_entry] = htonl((u_int32_t) time(NULL));
2289     lost = lcp_echos_pending - 1;
2290     if (lost > 0xFF)
2291         lost = 0xFF;            /* truncate the lost packets count to 256 */
2292     if (rtt > 0xFFFFFF)
2293         rtt = 0xFFFFFF;         /* truncate the RTT to 16777216 */
2294     /* use bits 24-31 for the lost packets count and bits 0-23 for the RTT */
2295     ring_buffer[next_entry + 1] = htonl((u_int32_t) ((lost << 24) + rtt));
2296
2297     /* update the pointer to the (just updated) most current data element */
2298     ring_header[2] = htonl(next_entry);
2299
2300     /* In theory, CPUs implementing a weakly-consistent memory model do not
2301      * guarantee that these three memory store operations to the buffer will
2302      * be seen in the same order by the reader process.
2303      * This means that a process reading the file could see the index
2304      * having been updated before the element that the index points to had
2305      * been written.
2306      * But in practice we expect that the read(2) system call used by
2307      * consumers processes is atomic with respect to the following msync(2)
2308      * call, so we ignore the issue.
2309      */
2310
2311     if (msync(lcp_rtt_buffer, LCP_RTT_FILE_SIZE, MS_ASYNC) < 0)
2312         error("msync() for %s failed: %m", lcp_rtt_file);
2313 }
2314
2315 /*
2316  * LcpEchoReply - LCP has received a reply to the echo
2317  */
2318
2319 static void
2320 lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len)
2321 {
2322     u_int32_t magic;
2323
2324     /* Check the magic number - don't count replies from ourselves. */
2325     if (len < 4) {
2326         dbglog("lcp: received short Echo-Reply, length %d", len);
2327         return;
2328     }
2329     GETLONG(magic, inp);
2330     if (lcp_gotoptions[f->unit].neg_magicnumber
2331         && magic == lcp_gotoptions[f->unit].magicnumber) {
2332         warn("appear to have received our own echo-reply!");
2333         return;
2334     }
2335
2336     if (lcp_rtt_file_fd && len >= 16) {
2337         long lcp_rtt_magic;
2338
2339         /*
2340          * If the magic word is found at the beginning of the data section
2341          * of the frame then read the timestamp which follows and subtract
2342          * it from the current time to compute the round trip time.
2343          */
2344         GETLONG(lcp_rtt_magic, inp);
2345         if (lcp_rtt_magic == LCP_RTT_MAGIC) {
2346             struct timespec ts;
2347             unsigned long req_sec, req_nsec, rtt;
2348
2349             clock_gettime(CLOCK_MONOTONIC, &ts);
2350             GETLONG(req_sec, inp);
2351             GETLONG(req_nsec, inp);
2352             /* compute the RTT in microseconds */
2353             rtt = (ts.tv_sec - req_sec) * 1000000
2354                 + (ts.tv_nsec / 1000 - req_nsec / 1000);
2355             /* log the RTT */
2356             lcp_rtt_update_buffer(rtt);
2357         }
2358     }
2359
2360     /* Reset the number of outstanding echo frames */
2361     lcp_echos_pending = 0;
2362 }
2363
2364 /*
2365  * LcpSendEchoRequest - Send an echo request frame to the peer
2366  */
2367
2368 static void
2369 LcpSendEchoRequest (fsm *f)
2370 {
2371     u_int32_t lcp_magic;
2372     u_char pkt[16], *pktp;
2373
2374     /*
2375      * Detect the failure of the peer at this point.
2376      */
2377     if (lcp_echo_fails != 0) {
2378         if (lcp_echos_pending >= lcp_echo_fails) {
2379             LcpLinkFailure(f);
2380             lcp_echos_pending = 0;
2381         }
2382     }
2383
2384     /*
2385      * If adaptive echos have been enabled, only send the echo request if
2386      * no traffic was received since the last one.
2387      */
2388     if (lcp_echo_adaptive) {
2389         static unsigned int last_pkts_in = 0;
2390         struct pppd_stats cur_stats;
2391
2392         if (get_ppp_stats(f->unit, &cur_stats) && cur_stats.pkts_in != last_pkts_in) {
2393             last_pkts_in = cur_stats.pkts_in;
2394             /* receipt of traffic indicates the link is working... */
2395             lcp_echos_pending = 0;
2396             return;
2397         }
2398     }
2399
2400     /*
2401      * Make and send the echo request frame.
2402      */
2403     if (f->state == OPENED) {
2404         lcp_magic = lcp_gotoptions[f->unit].magicnumber;
2405         pktp = pkt;
2406         PUTLONG(lcp_magic, pktp);
2407
2408         /* Put a timestamp in the data section of the frame */
2409         if (lcp_rtt_file_fd) {
2410             struct timespec ts;
2411
2412             PUTLONG(LCP_RTT_MAGIC, pktp);
2413             clock_gettime(CLOCK_MONOTONIC, &ts);
2414             PUTLONG((u_int32_t)ts.tv_sec, pktp);
2415             PUTLONG((u_int32_t)ts.tv_nsec, pktp);
2416         }
2417
2418         fsm_sdata(f, ECHOREQ, lcp_echo_number++ & 0xFF, pkt, pktp - pkt);
2419         ++lcp_echos_pending;
2420     }
2421 }
2422
2423 static void
2424 lcp_rtt_open_file (void)
2425 {
2426     volatile u_int32_t *ring_header;
2427
2428     if (!lcp_rtt_file)
2429         return;
2430
2431     lcp_rtt_file_fd = open(lcp_rtt_file, O_RDWR | O_CREAT, 0644);
2432     if (lcp_rtt_file_fd < 0) {
2433         error("Can't open the RTT log file %s: %m", lcp_rtt_file);
2434         lcp_rtt_file_fd = 0;
2435         return;
2436     }
2437
2438     if (ftruncate(lcp_rtt_file_fd, LCP_RTT_FILE_SIZE) < 0)
2439         fatal("ftruncate() of %s failed: %m", lcp_rtt_file);
2440     lcp_rtt_buffer = mmap(0, LCP_RTT_FILE_SIZE, PROT_READ | PROT_WRITE,
2441             MAP_SHARED, lcp_rtt_file_fd, 0);
2442     if (lcp_rtt_buffer == MAP_FAILED)
2443         fatal("mmap() of %s failed: %m", lcp_rtt_file);
2444     ring_header = lcp_rtt_buffer;
2445
2446     /* initialize the ring buffer */
2447     if (ring_header[0] != htonl(LCP_RTT_MAGIC)) {
2448         memset(lcp_rtt_buffer, 0, LCP_RTT_FILE_SIZE);
2449         ring_header[0] = htonl(LCP_RTT_MAGIC);
2450     }
2451
2452     ring_header[3] = htonl(lcp_echo_interval);
2453     ring_header[1] = htonl(1); /* status: LCP up, file opened */
2454 }
2455
2456 static void
2457 lcp_rtt_close_file (void)
2458 {
2459     volatile u_int32_t *const ring_header = lcp_rtt_buffer;
2460
2461     if (!lcp_rtt_file_fd)
2462         return;
2463
2464     ring_header[1] = htonl(0); /* status: LCP down, file closed */
2465
2466     if (munmap(lcp_rtt_buffer, LCP_RTT_FILE_SIZE) < 0)
2467         error("munmap() of %s failed: %m", lcp_rtt_file);
2468     if (close(lcp_rtt_file_fd) < 0)
2469         error("close() of %s failed: %m", lcp_rtt_file);
2470     lcp_rtt_buffer = NULL;
2471     lcp_rtt_file_fd = 0;
2472 }
2473
2474 /*
2475  * lcp_echo_lowerup - Start the timer for the LCP frame
2476  */
2477
2478 static void
2479 lcp_echo_lowerup (int unit)
2480 {
2481     fsm *f = &lcp_fsm[unit];
2482
2483     /* Clear the parameters for generating echo frames */
2484     lcp_echos_pending      = 0;
2485     lcp_echo_number        = 0;
2486     lcp_echo_timer_running = 0;
2487
2488     /* Open the file where the LCP RTT data will be logged */
2489     lcp_rtt_open_file();
2490   
2491     /* If a timeout interval is specified then start the timer */
2492     if (lcp_echo_interval != 0)
2493         LcpEchoCheck (f);
2494 }
2495
2496 /*
2497  * lcp_echo_lowerdown - Stop the timer for the LCP frame
2498  */
2499
2500 static void
2501 lcp_echo_lowerdown (int unit)
2502 {
2503     fsm *f = &lcp_fsm[unit];
2504
2505     if (lcp_echo_timer_running != 0) {
2506         UNTIMEOUT (LcpEchoTimeout, f);
2507         lcp_echo_timer_running = 0;
2508     }
2509
2510     /* Close the file containing the LCP RTT data */
2511     lcp_rtt_close_file();
2512 }