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