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