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