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