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