1 /* 2 * lcp.c - PPP Link Control Protocol. 3 * 4 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 5 * Use is subject to license terms. 6 * 7 * Copyright (c) 1989 Carnegie Mellon University. 8 * All rights reserved. 9 * 10 * Copyright (c) 2016 by Delphix. All rights reserved. 11 * 12 * Redistribution and use in source and binary forms are permitted 13 * provided that the above copyright notice and this paragraph are 14 * duplicated in all such forms and that any documentation, 15 * advertising materials, and other materials related to such 16 * distribution and use acknowledge that the software was developed 17 * by Carnegie Mellon University. The name of the 18 * University may not be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 22 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 23 */ 24 25 #include <stdio.h> 26 #include <string.h> 27 #include <stdlib.h> 28 #include <ctype.h> 29 #if defined(CHAPMS) || defined(CHAPMSV2) 30 #ifdef HAVE_CRYPT_H 31 #include <crypt.h> 32 #endif 33 #ifndef USE_CRYPT 34 #include <des.h> 35 #endif 36 #ifdef SOL2 37 #include <errno.h> 38 #endif 39 #endif 40 41 #include "pppd.h" 42 #include "fsm.h" 43 #include "lcp.h" 44 #include "chap.h" 45 #include "magic.h" 46 #include "patchlevel.h" 47 48 /* 49 * Special failure codes for logging link failure reasons. 50 */ 51 bool peer_nak_auth; /* Peer sent nak for our auth request */ 52 u_short nak_auth_orig; /* Auth proto peer naked */ 53 u_short nak_auth_proto; /* Auth proto peer suggested instead */ 54 bool unsolicited_nak_auth; /* Peer asked us to authenticate */ 55 u_short unsolicit_auth_proto; /* Auth proto peer wants */ 56 bool peer_reject_auth; /* Peer sent reject for auth */ 57 u_short reject_auth_proto; /* Protocol that peer rejected */ 58 bool rejected_peers_auth; /* We sent a reject to the peer */ 59 u_short rejected_auth_proto; /* Protocol that peer wanted to use */ 60 bool naked_peers_auth; /* We sent a nak to the peer */ 61 u_short naked_auth_orig; /* Protocol that we wanted to use */ 62 u_short naked_auth_proto; /* Protocol that peer wants us to use */ 63 64 /* 65 * LCP-related command-line options. 66 */ 67 int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ 68 int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ 69 bool lax_recv = 0; /* accept control chars in asyncmap */ 70 static int use_accm_test = 2; /* use big echo-requests to check ACCM */ 71 #define ACCM_TEST_FAILS 5 72 73 #define _tostr2(x) #x 74 #define _tostr(x) _tostr2(x) 75 static char identstr[256] = /* Identification string */ 76 "ppp-" VERSION "." _tostr(PATCHLEVEL) IMPLEMENTATION; 77 static int noident = 0; /* 1 to disable; 2 to reject */ 78 static int sentident = 0; /* counts the # of ident codes sent */ 79 80 /* set if we're allowed to send an unsolicited Configure-Nak for MRU. */ 81 static bool unsolicit_mru; 82 83 static int setescape __P((char **, option_t *)); 84 85 static bool do_msft_workaround = 1; 86 static int setasyncmap __P((char **, option_t *)); 87 88 bool noendpoint = 0; /* don't send/accept endpoint discriminator */ 89 static int setendpoint __P((char **, option_t *)); 90 91 static char *callback_strings[] = { 92 "auth", "dialstring", "location", "E.164", "X.500", "", "CBCP", NULL 93 }; 94 95 /* This is used in packet printing even if NEGOTIATE_FCS isn't enabled */ 96 static char *fcsalt_strings[] = { 97 "null", "crc16", "crc32", NULL 98 }; 99 100 #ifdef NEGOTIATE_FCS 101 static int setfcsallow __P((char **, option_t *)); 102 static int setfcswant __P((char **, option_t *)); 103 #endif 104 105 /* Backward compatibility for Linux */ 106 #ifndef PPP_MAXMRU 107 #define PPP_MTU 1500 /* Default MTU (size of Info field) */ 108 #define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) 109 #define PPP_MINMTU 64 110 #define PPP_MAXMRU 65000 /* Largest MRU we allow */ 111 #define PPP_MINMRU 128 112 #endif 113 114 static option_t lcp_option_list[] = { 115 /* LCP options */ 116 { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression, 117 "Disable address/control compression", 118 OPT_A2COPY, &lcp_allowoptions[0].neg_accompression }, 119 { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression, 120 "Disable address/control compression", 121 OPT_A2COPY, &lcp_allowoptions[0].neg_accompression }, 122 { "default-asyncmap", o_bool, &lcp_wantoptions[0].neg_asyncmap, 123 "Disable asyncmap negotiation", 124 OPT_A2COPY, &lcp_allowoptions[0].neg_asyncmap }, 125 { "-am", o_bool, &lcp_wantoptions[0].neg_asyncmap, 126 "Disable asyncmap negotiation", 127 OPT_A2COPY, &lcp_allowoptions[0].neg_asyncmap }, 128 { "asyncmap", o_special, (void *)setasyncmap, 129 "Set asyncmap (for received packets)" }, 130 { "-as", o_special, (void *)setasyncmap, 131 "Set asyncmap (for received packets)" }, 132 { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber, 133 "Disable magic number option (looped-back line detect)", 134 OPT_A2COPY, &lcp_allowoptions[0].neg_magicnumber }, 135 { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber, 136 "Disable magic number option (looped-back line detect)", 137 OPT_A2COPY, &lcp_allowoptions[0].neg_magicnumber }, 138 { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru, 139 "Disable MRU negotiation (use default 1500)", 140 OPT_A2COPY, &lcp_allowoptions[0].neg_mru }, 141 { "-mru", o_bool, &lcp_wantoptions[0].neg_mru, 142 "Disable MRU negotiation (use default 1500)", 143 OPT_A2COPY, &lcp_allowoptions[0].neg_mru }, 144 { "mru", o_int, &lcp_wantoptions[0].mru, 145 "Set MRU (maximum received packet size) for negotiation", 146 OPT_LIMITS, &lcp_wantoptions[0].neg_mru, PPP_MAXMRU, PPP_MINMRU }, 147 { "mtu", o_int, &lcp_allowoptions[0].mru, 148 "Set our MTU", OPT_LIMITS|OPT_A2COPY, &lcp_allowoptions[0].mrru, 149 PPP_MAXMTU, PPP_MINMTU }, 150 { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression, 151 "Disable protocol field compression", 152 OPT_A2COPY, &lcp_allowoptions[0].neg_pcompression }, 153 { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression, 154 "Disable protocol field compression", 155 OPT_A2COPY, &lcp_allowoptions[0].neg_pcompression }, 156 { "-p", o_bool, &lcp_wantoptions[0].passive, 157 "Set passive mode", 1 }, 158 { "passive", o_bool, &lcp_wantoptions[0].passive, 159 "Set passive mode", 1 }, 160 { "silent", o_bool, &lcp_wantoptions[0].silent, 161 "Set silent mode", 1 }, 162 { "escape", o_special, (void *)setescape, 163 "List of character codes to escape on transmission" }, 164 { "lcp-echo-failure", o_int, &lcp_echo_fails, 165 "Number of consecutive echo failures for link failure" }, 166 { "lcp-echo-interval", o_int, &lcp_echo_interval, 167 "Set time in seconds between LCP echo requests" }, 168 { "no-accm-test", o_int, &use_accm_test, 169 "Disable use of LCP Echo-Request asyncmap checking", 170 OPT_NOARG|OPT_VAL(0) }, 171 { "small-accm-test", o_int, &use_accm_test, 172 "Use only small Echo-Requests for asyncmap checking", 173 OPT_NOARG|OPT_VAL(1) }, 174 { "lcp-restart", o_int, &lcp_fsm[0].timeouttime, 175 "Set time in seconds between LCP retransmissions" }, 176 { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits, 177 "Maximum number of LCP terminate-request transmissions" }, 178 { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits, 179 "Maximum number of LCP configure-request transmissions" }, 180 { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops, 181 "Set limit on number of LCP configure-naks" }, 182 { "receive-all", o_bool, &lax_recv, 183 "Accept all received control characters", 1 }, 184 #ifdef HAVE_MULTILINK 185 { "mrru", o_int, &lcp_wantoptions[0].mrru, 186 "Maximum received packet size for multilink bundle", 187 OPT_LIMITS, &lcp_wantoptions[0].neg_mrru, PPP_MAXMRU, PPP_MINMRU }, 188 { "mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, 189 "Use short sequence numbers in multilink headers", 190 OPT_A2COPY | 1, &lcp_allowoptions[0].neg_ssnhf }, 191 { "nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, 192 "Don't use short sequence numbers in multilink headers", 193 OPT_A2COPY, &lcp_allowoptions[0].neg_ssnhf }, 194 #endif /* HAVE_MULTILINK */ 195 { "endpoint", o_special, (void *)setendpoint, 196 "Endpoint discriminator for multilink", }, 197 { "noendpoint", o_bool, &noendpoint, 198 "Don't send or accept multilink endpoint discriminator", 1 }, 199 { "ident", o_string, identstr, 200 "LCP Identification string", OPT_STATIC, NULL, sizeof(identstr) }, 201 { "noident", o_int, &noident, 202 "Disable use of LCP Identification", OPT_INC|OPT_NOARG|1 }, 203 #ifdef NEGOTIATE_FCS 204 { "default-fcs", o_bool, &lcp_wantoptions[0].neg_fcs, 205 "Disable FCS Alternatives option (use default CRC-16)", 206 OPT_A2COPY, &lcp_allowoptions[0].neg_fcs }, 207 { "allow-fcs", o_special, (void *)setfcsallow, 208 "Set allowable FCS types; crc16, crc32, null, or number" }, 209 { "fcs", o_special, (void *)setfcswant, 210 "Set FCS type(s) desired; crc16, crc32, null, or number" }, 211 #endif 212 #ifdef MUX_FRAME 213 /* 214 * if pppmux option is turned on, then the parameter to this 215 * is time value in microseconds 216 */ 217 { "pppmux", o_int, &lcp_wantoptions[0].pppmux, 218 "Set PPP Multiplexing option timer", OPT_LLIMIT | OPT_A2COPY, 219 &lcp_allowoptions[0].pppmux, 0, 0 }, 220 #endif 221 {NULL} 222 }; 223 224 /* global vars */ 225 fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/ 226 lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */ 227 lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ 228 lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ 229 lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ 230 u_int32_t xmit_accm[NUM_PPP][8]; /* extended transmit ACCM */ 231 232 /* 233 * These variables allow a plugin to assert limits on the maximum 234 * MRU/MTU values that can be negotiated. 235 */ 236 int absmax_mru = PPP_MAXMRU; 237 int absmax_mtu = PPP_MAXMTU; 238 239 static int lcp_echos_pending = 0; /* Number of outstanding echo msgs */ 240 static int lcp_echo_number = 0; /* ID number of next echo frame */ 241 static int lcp_echo_timer_running = 0; /* set if a timer is running */ 242 static bool lcp_echo_accm_test = 0; /* flag if still testing ACCM */ 243 static int lcp_echo_badreplies = 0; /* number of bad replies from peer */ 244 /* 245 * The maximum number of bad replies we tolerate before bringing the 246 * link down. 247 */ 248 #define LCP_ECHO_MAX_BADREPLIES 10 249 250 /* 251 * Callbacks for fsm code. (CI = Configuration Information) 252 */ 253 static void lcp_resetci __P((fsm *)); /* Reset our CI */ 254 static int lcp_cilen __P((fsm *)); /* Return length of our CI */ 255 static void lcp_addci __P((fsm *, u_char *, int *)); /* Add our CI to pkt */ 256 static int lcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ 257 static int lcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */ 258 static int lcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ 259 static int lcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv peer CI */ 260 static void lcp_up __P((fsm *)); /* We're UP */ 261 static void lcp_down __P((fsm *)); /* We're DOWN */ 262 static void lcp_starting __P((fsm *)); /* We need lower layer up */ 263 static void lcp_finished __P((fsm *)); /* We need lower layer down */ 264 static int lcp_extcode __P((fsm *, int, int, u_char *, int)); 265 static void lcp_rprotrej __P((fsm *, u_char *, int)); 266 static int lcp_coderej __P((fsm *f, int code, int id, u_char *inp, int len)); 267 268 /* 269 * routines to send LCP echos to peer 270 */ 271 272 static void lcp_echo_lowerup __P((int)); 273 static void lcp_echo_lowerdown __P((int)); 274 static void LcpEchoTimeout __P((void *)); 275 static int lcp_received_echo_reply __P((fsm *, int, u_char *, int)); 276 static void LcpSendEchoRequest __P((fsm *)); 277 static void LcpLinkFailure __P((fsm *)); 278 static void LcpEchoCheck __P((fsm *)); 279 280 /* 281 * routines to send and receive additional LCP packets described in 282 * section 1 of rfc1570. 283 */ 284 static void LcpSendIdentification __P((fsm *)); 285 static void lcp_received_identification __P((fsm *, int, u_char *, int)); 286 static void LcpSendTimeRemaining __P((fsm *, u_int32_t)); 287 static void lcp_timeremaining __P((void *)); 288 static void lcp_received_timeremain __P((fsm *, int, u_char *, int)); 289 290 291 static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ 292 lcp_resetci, /* Reset our Configuration Information */ 293 lcp_cilen, /* Length of our Configuration Information */ 294 lcp_addci, /* Add our Configuration Information */ 295 lcp_ackci, /* ACK our Configuration Information */ 296 lcp_nakci, /* NAK our Configuration Information */ 297 lcp_rejci, /* Reject our Configuration Information */ 298 lcp_reqci, /* Request peer's Configuration Information */ 299 lcp_up, /* Called when fsm reaches OPENED state */ 300 lcp_down, /* Called when fsm leaves OPENED state */ 301 lcp_starting, /* Called when we want the lower layer up */ 302 lcp_finished, /* Called when we want the lower layer down */ 303 NULL, /* Retransmission is necessary */ 304 lcp_extcode, /* Called to handle LCP-specific codes */ 305 "LCP", /* String name of protocol */ 306 lcp_coderej, /* Peer rejected a code number */ 307 }; 308 309 /* 310 * Protocol entry points. 311 * Some of these are called directly. 312 */ 313 314 static void lcp_init __P((int)); 315 static void lcp_input __P((int, u_char *, int)); 316 static void lcp_protrej __P((int)); 317 static int lcp_printpkt __P((u_char *, int, 318 void (*) __P((void *, const char *, ...)), void *)); 319 320 321 struct protent lcp_protent = { 322 PPP_LCP, /* Protocol Number for LCP */ 323 lcp_init, /* Initializes LCP */ 324 lcp_input, /* Processes a received LCP packet */ 325 lcp_protrej, /* Process a received Protocol-reject */ 326 lcp_lowerup, /* Called after the serial device has been set up */ 327 lcp_lowerdown, /* Called when the link is brought down */ 328 lcp_open, /* Called after lcp_lowerup when bringing up the link */ 329 lcp_close, /* Called when the link goes down */ 330 lcp_printpkt, /* Print a packet in human readable form */ 331 NULL, /* Process a received data packet */ 332 1, /* LCP is enabled by default */ 333 "LCP", /* Name of the protocol */ 334 NULL, /* Name of the corresponding data protocol */ 335 lcp_option_list, /* List of LCP command-line options */ 336 NULL, /* Assigns default values for options */ 337 NULL, /* Configures demand-dial */ 338 NULL /* Bring up the link for this packet? */ 339 }; 340 341 int lcp_loopbackfail = DEFLOOPBACKFAIL; 342 343 /* 344 * Length of each type of configuration option (in octets) 345 */ 346 #define CILEN_VOID 2 347 #define CILEN_CHAR 3 348 #define CILEN_SHORT 4 /* CILEN_VOID + 2 */ 349 #define CILEN_CHAP 5 /* CILEN_VOID + 2 + 1 */ 350 #define CILEN_LONG 6 /* CILEN_VOID + 4 */ 351 #define CILEN_LQR 8 /* CILEN_VOID + 2 + 4 */ 352 #define CILEN_CBCP 3 353 354 355 /* 356 * setescape - add chars to the set we escape on transmission. 357 */ 358 /*ARGSUSED*/ 359 static int 360 setescape(argv, opt) 361 char **argv; 362 option_t *opt; 363 { 364 int n, ret; 365 char *p, *endp; 366 367 p = *argv; 368 ret = 1; 369 while (*p != '\0') { 370 n = strtol(p, &endp, 16); 371 if (p == endp) { 372 option_error("escape parameter contains invalid hex number '%s'", 373 p); 374 return 0; 375 } 376 p = endp; 377 if (n < 0 || n == 0x5E || n > 0xFF) { 378 option_error("can't escape character 0x%x", n); 379 ret = 0; 380 } else 381 xmit_accm[0][n >> 5] |= 1 << (n & 0x1F); 382 while (*p == ',' || *p == ' ') 383 ++p; 384 } 385 return ret; 386 } 387 388 /* 389 * setasyncmap - set async map negotiated 390 */ 391 /*ARGSUSED*/ 392 static int 393 setasyncmap(argv, opt) 394 char **argv; 395 option_t *opt; 396 { 397 u_int32_t val; 398 char *endp; 399 400 val = strtoul(*argv, &endp, 16); 401 if (*argv == endp) { 402 option_error("invalid numeric parameter '%s' for 'asyncmap' option", 403 *argv); 404 return 0; 405 } 406 lcp_wantoptions[0].asyncmap |= val; 407 lcp_wantoptions[0].neg_asyncmap = (~lcp_wantoptions[0].asyncmap != 0); 408 do_msft_workaround = 0; 409 return 1; 410 } 411 412 /*ARGSUSED*/ 413 static int 414 setendpoint(argv, opt) 415 char **argv; 416 option_t *opt; 417 { 418 if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) { 419 lcp_wantoptions[0].neg_endpoint = 1; 420 return 1; 421 } 422 option_error("Can't parse '%s' as an endpoint discriminator", *argv); 423 return 0; 424 } 425 426 #ifdef NEGOTIATE_FCS 427 static int 428 str_to_fcstype(opt,arg) 429 lcp_options *opt; 430 char *arg; 431 { 432 char **cpp, *cp; 433 int val, len; 434 435 if (*arg != '\0') { 436 val = 0; 437 while (*arg != '\0') { 438 len = 0; 439 if (isdigit(*arg)) { 440 len = strtol(arg, &cp, 0); 441 if (len < 0 || len > 255 || arg == cp || 442 (*cp != '\0' && *cp != ',')) 443 break; 444 val |= len; 445 len = cp - arg; 446 } else { 447 for (cpp = fcsalt_strings; *cpp != NULL; cpp++) { 448 len = strlen(*cpp); 449 if (strncasecmp(arg, *cpp, len) == 0 && 450 (arg[len] == '\0' || arg[len] == ',')) 451 break; 452 } 453 if (*cpp == NULL) 454 break; 455 val |= 1<<(cpp-fcsalt_strings); 456 } 457 if (arg[len] == '\0') { 458 opt->neg_fcs = 1; 459 opt->fcs_type = val; 460 return (1); 461 } 462 arg += len+1; 463 } 464 } 465 option_error("Can't parse '%s' as an FCS type", arg); 466 return (0); 467 } 468 469 /*ARGSUSED*/ 470 static int 471 setfcsallow(argv, opt) 472 char **argv; 473 option_t *opt; 474 { 475 return str_to_fcstype(&lcp_allowoptions[0], *argv); 476 } 477 478 /*ARGSUSED*/ 479 static int 480 setfcswant(argv, opt) 481 char **argv; 482 option_t *opt; 483 { 484 return str_to_fcstype(&lcp_wantoptions[0], *argv); 485 } 486 #endif 487 488 /* 489 * lcp_init - Initialize LCP. 490 */ 491 static void 492 lcp_init(unit) 493 int unit; 494 { 495 fsm *f = &lcp_fsm[unit]; 496 lcp_options *wo = &lcp_wantoptions[unit]; 497 lcp_options *ao = &lcp_allowoptions[unit]; 498 499 f->unit = unit; 500 f->protocol = PPP_LCP; 501 f->callbacks = &lcp_callbacks; 502 503 fsm_init(f); 504 505 BZERO(wo, sizeof(*wo)); 506 wo->neg_mru = 1; 507 wo->mru = PPP_MRU; 508 wo->neg_asyncmap = 1; 509 wo->chap_mdtype = CHAP_DIGEST_MD5; 510 wo->neg_magicnumber = 1; 511 wo->neg_pcompression = 1; 512 wo->neg_accompression = 1; 513 514 /* 515 * Leave allowed MRU (MTU) at zero; configuration option sets it 516 * non-zero if we should nak for something else. 517 */ 518 BZERO(ao, sizeof(*ao)); 519 ao->neg_mru = 1; 520 ao->neg_asyncmap = 1; 521 ao->neg_chap = 1; 522 #if defined(CHAPMS) || defined(CHAPMSV2) 523 #ifdef SOL2 524 /* Check if DES wasn't exported */ 525 errno = 0; 526 setkey("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 527 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); 528 if (errno == 0) 529 #endif 530 { 531 #ifdef CHAPMS 532 ao->neg_mschap = 1; 533 #endif 534 #ifdef CHAPMSV2 535 ao->neg_mschapv2 = 1; 536 #endif 537 } 538 #endif 539 ao->chap_mdtype = CHAP_DIGEST_MD5; 540 ao->neg_upap = 1; 541 ao->neg_magicnumber = 1; 542 ao->neg_pcompression = 1; 543 ao->neg_accompression = 1; 544 #ifdef CBCP_SUPPORT 545 ao->neg_cbcp = 1; 546 #endif 547 ao->neg_endpoint = 1; 548 #ifdef NEGOTIATE_FCS 549 ao->neg_fcs = 1; 550 ao->fcs_type = FCSALT_NULL|FCSALT_16|FCSALT_32; 551 #endif 552 553 BZERO(xmit_accm[unit], sizeof(xmit_accm[0])); 554 xmit_accm[unit][3] = 0x60000000; 555 } 556 557 558 /* 559 * lcp_open - LCP is allowed to come up. 560 */ 561 void 562 lcp_open(unit) 563 int unit; 564 { 565 fsm *f = &lcp_fsm[unit]; 566 lcp_options *wo = &lcp_wantoptions[unit]; 567 568 f->flags = 0; 569 if (wo->passive) 570 f->flags |= OPT_PASSIVE; 571 if (wo->silent) 572 f->flags |= OPT_SILENT; 573 fsm_open(f); 574 } 575 576 577 /* 578 * lcp_close - Take LCP down. 579 */ 580 void 581 lcp_close(unit, reason) 582 int unit; 583 char *reason; 584 { 585 fsm *f = &lcp_fsm[unit]; 586 587 if (phase != PHASE_DEAD) 588 new_phase(PHASE_TERMINATE); 589 if (f->state == STOPPED && (f->flags & (OPT_PASSIVE|OPT_SILENT))) { 590 /* 591 * This action is not strictly according to the FSM in RFC1548, 592 * but it does mean that the program terminates if you do a 593 * lcp_close() in passive/silent mode when a connection hasn't 594 * been established. 595 */ 596 f->state = CLOSED; 597 lcp_finished(f); 598 599 } else 600 fsm_close(&lcp_fsm[unit], reason); 601 } 602 603 604 /* 605 * lcp_lowerup - The lower layer is up. 606 */ 607 void 608 lcp_lowerup(unit) 609 int unit; 610 { 611 lcp_options *wo = &lcp_wantoptions[unit]; 612 int mru, mtu; 613 614 mru = PPP_MRU > absmax_mru ? absmax_mru : PPP_MRU; 615 mtu = PPP_MTU > absmax_mtu ? absmax_mtu : PPP_MTU; 616 617 /* 618 * Don't use A/C or protocol compression on transmission, 619 * but accept A/C and protocol compressed packets 620 * if we are going to ask for A/C and protocol compression. 621 */ 622 ppp_set_xaccm(unit, xmit_accm[unit]); 623 ppp_send_config(unit, mtu, 0xffffffff, 0, 0); 624 ppp_recv_config(unit, mru, (lax_recv? 0: 0xffffffff), 625 wo->neg_pcompression, wo->neg_accompression); 626 #ifdef NEGOTIATE_FCS 627 ppp_send_fcs(unit, FCSALT_16); 628 ppp_recv_fcs(unit, FCSALT_16); 629 #endif 630 631 fsm_setpeermru(unit, mtu); 632 lcp_allowoptions[unit].asyncmap = xmit_accm[unit][0]; 633 634 fsm_lowerup(&lcp_fsm[unit]); 635 } 636 637 638 /* 639 * lcp_lowerdown - The lower layer is down. 640 */ 641 void 642 lcp_lowerdown(unit) 643 int unit; 644 { 645 fsm_lowerdown(&lcp_fsm[unit]); 646 } 647 648 649 /* 650 * lcp_input - Input LCP packet. 651 */ 652 static void 653 lcp_input(unit, p, len) 654 int unit; 655 u_char *p; 656 int len; 657 { 658 fsm *f = &lcp_fsm[unit]; 659 660 fsm_input(f, p, len); 661 } 662 663 664 /* 665 * lcp_extcode - Handle a LCP-specific code. 666 */ 667 static int 668 lcp_extcode(f, code, id, inp, len) 669 fsm *f; 670 int code, id; 671 u_char *inp; 672 int len; 673 { 674 u_char *magp; 675 676 switch( code ){ 677 case CODE_PROTREJ: 678 lcp_rprotrej(f, inp, len); 679 break; 680 681 case CODE_ECHOREQ: 682 if (f->state != OPENED) 683 break; 684 magp = inp; 685 PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp); 686 fsm_sdata(f, CODE_ECHOREP, id, inp, len); 687 break; 688 689 case CODE_ECHOREP: 690 if (!lcp_received_echo_reply(f, id, inp, len)) { 691 lcp_echo_badreplies++; 692 if (lcp_echo_badreplies > LCP_ECHO_MAX_BADREPLIES) { 693 LcpLinkFailure(f); 694 lcp_echos_pending = 0; 695 lcp_echo_badreplies = 0; 696 } 697 } 698 break; 699 700 case CODE_DISCREQ: 701 break; 702 703 case CODE_IDENT: 704 /* More than one 'noident' tells us to reject the code number. */ 705 if (noident > 1) 706 return 0; 707 lcp_received_identification(f, id, inp, len); 708 break; 709 710 case CODE_TIMEREMAIN: 711 lcp_received_timeremain(f, id, inp, len); 712 break; 713 714 default: 715 return 0; 716 } 717 return 1; 718 } 719 720 /* 721 * lcp_rprotrej - Receive an Protocol-Reject. 722 * 723 * Figure out which protocol is rejected and inform it. 724 */ 725 static void 726 lcp_rprotrej(f, inp, len) 727 fsm *f; 728 u_char *inp; 729 int len; 730 { 731 int i; 732 struct protent *protp; 733 u_short prot; 734 735 if (len < 2) { 736 dbglog("lcp_rprotrej: Rcvd short Protocol-Reject packet!"); 737 return; 738 } 739 740 GETSHORT(prot, inp); 741 742 /* 743 * Protocol-Reject packets received in any state other than the LCP 744 * OPENED state SHOULD be silently discarded. 745 */ 746 if( f->state != OPENED ){ 747 dbglog("Protocol-Reject discarded: LCP in state %s", 748 fsm_state(f->state)); 749 return; 750 } 751 752 /* 753 * Upcall the proper Protocol-Reject routine. 754 */ 755 for (i = 0; (protp = protocols[i]) != NULL; ++i) 756 if (protp->protocol == prot && protp->enabled_flag) { 757 (*protp->protrej)(f->unit); 758 return; 759 } 760 761 warn("Protocol-Reject for unsupported protocol 0x%x", prot); 762 } 763 764 765 /* 766 * lcp_protrej - A Protocol-Reject was received. 767 */ 768 /*ARGSUSED*/ 769 static void 770 lcp_protrej(unit) 771 int unit; 772 { 773 /* 774 * Can't reject LCP! 775 */ 776 error("Received Protocol-Reject for LCP!"); 777 } 778 779 /* 780 * lcp_coderej - A Code-Reject was received. 781 */ 782 /*ARGSUSED*/ 783 static int 784 lcp_coderej(f, code, id, inp, len) 785 fsm *f; 786 int code; 787 int id; 788 u_char *inp; 789 int len; 790 { 791 /* The peer cannot reject these code numbers. */ 792 if (code >= CODE_CONFREQ && code <= CODE_PROTREJ) 793 return 1; 794 switch (code) { 795 case CODE_ECHOREQ: 796 /* 797 * If the peer rejects an Echo-Request, then stop doing that. 798 */ 799 if (lcp_echo_timer_running != 0) { 800 UNTIMEOUT (LcpEchoTimeout, f); 801 lcp_echo_timer_running = 0; 802 lcp_echo_interval = 0; 803 } 804 break; 805 } 806 return 0; 807 } 808 809 /* 810 * lcp_sprotrej - Send a Protocol-Reject for some protocol. 811 */ 812 void 813 lcp_sprotrej(unit, p, len) 814 int unit; 815 u_char *p; 816 int len; 817 { 818 /* 819 * Send back the protocol and the information field of the 820 * rejected packet. We only get here if LCP is in the OPENED state. 821 */ 822 p += 2; 823 len -= 2; 824 825 fsm_sdata(&lcp_fsm[unit], CODE_PROTREJ, ++lcp_fsm[unit].id, 826 p, len); 827 } 828 829 830 /* 831 * lcp_resetci - Reset our CI. 832 */ 833 static void 834 lcp_resetci(f) 835 fsm *f; 836 { 837 lcp_options *wo = &lcp_wantoptions[f->unit]; 838 lcp_options *go = &lcp_gotoptions[f->unit]; 839 lcp_options *ao = &lcp_allowoptions[f->unit]; 840 841 wo->magicnumber = magic(); 842 wo->numloops = 0; 843 sentident = 0; 844 *go = *wo; 845 if (!multilink) { 846 go->neg_mrru = 0; 847 go->neg_ssnhf = 0; 848 } 849 if (noendpoint) 850 ao->neg_endpoint = 0; 851 if (go->mru > absmax_mru) 852 go->mru = absmax_mru; 853 if (ao->mru > absmax_mtu) 854 ao->mru = absmax_mtu; 855 unsolicit_mru = 1; 856 fsm_setpeermru(f->unit, PPP_MTU > absmax_mtu ? absmax_mtu : PPP_MTU); 857 auth_reset(f->unit); 858 } 859 860 861 /* 862 * lcp_cilen - Return length of our CI. 863 */ 864 static int 865 lcp_cilen(f) 866 fsm *f; 867 { 868 lcp_options *go = &lcp_gotoptions[f->unit]; 869 870 #define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0) 871 #define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0) 872 #define LENCICHAR(neg) ((neg) ? CILEN_CHAR : 0) 873 #define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0) 874 #define LENCILONG(neg) ((neg) ? CILEN_LONG : 0) 875 #define LENCILQR(neg) ((neg) ? CILEN_LQR: 0) 876 #define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0) 877 /* 878 * NB: we only ask for one of CHAP and UPAP, even if we will 879 * accept either. 880 */ 881 return (LENCISHORT(go->neg_mru && go->mru != PPP_MRU) + 882 LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) + 883 LENCICHAP(go->neg_chap || go->neg_mschap || go->neg_mschapv2) + 884 LENCISHORT(!go->neg_chap && go->neg_upap && !go->neg_mschap && 885 !go->neg_mschapv2) + 886 LENCILQR(go->neg_lqr) + 887 LENCICBCP(go->neg_cbcp) + 888 LENCILONG(go->neg_magicnumber) + 889 LENCIVOID(go->neg_pcompression) + 890 LENCIVOID(go->neg_accompression) + 891 LENCICHAR(go->neg_fcs) + 892 LENCISHORT(go->neg_mrru) + 893 LENCIVOID(go->neg_ssnhf) + 894 #ifdef MUX_FRAME 895 LENCIVOID(go->pppmux) + 896 #endif 897 (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0)); 898 } 899 900 901 /* 902 * lcp_addci - Add our desired CIs to a packet. 903 */ 904 static void 905 lcp_addci(f, ucp, lenp) 906 fsm *f; 907 u_char *ucp; 908 int *lenp; 909 { 910 lcp_options *go = &lcp_gotoptions[f->unit]; 911 lcp_options *ho = &lcp_hisoptions[f->unit]; 912 u_char *start_ucp = ucp; 913 914 #define ADDCIVOID(opt, neg) \ 915 if (neg) { \ 916 PUTCHAR(opt, ucp); \ 917 PUTCHAR(CILEN_VOID, ucp); \ 918 } 919 #define ADDCISHORT(opt, neg, val) \ 920 if (neg) { \ 921 PUTCHAR(opt, ucp); \ 922 PUTCHAR(CILEN_SHORT, ucp); \ 923 PUTSHORT(val, ucp); \ 924 } 925 #define ADDCICHAP(opt, neg, val, digest) \ 926 if (neg) { \ 927 PUTCHAR(opt, ucp); \ 928 PUTCHAR(CILEN_CHAP, ucp); \ 929 PUTSHORT(val, ucp); \ 930 PUTCHAR(digest, ucp); \ 931 } 932 #define ADDCILONG(opt, neg, val) \ 933 if (neg) { \ 934 PUTCHAR(opt, ucp); \ 935 PUTCHAR(CILEN_LONG, ucp); \ 936 PUTLONG(val, ucp); \ 937 } 938 #define ADDCILQR(opt, neg, val) \ 939 if (neg) { \ 940 PUTCHAR(opt, ucp); \ 941 PUTCHAR(CILEN_LQR, ucp); \ 942 PUTSHORT(PPP_LQR, ucp); \ 943 PUTLONG(val, ucp); \ 944 } 945 #define ADDCICHAR(opt, neg, val) \ 946 if (neg) { \ 947 PUTCHAR(opt, ucp); \ 948 PUTCHAR(CILEN_CHAR, ucp); \ 949 PUTCHAR(val, ucp); \ 950 } 951 #define ADDCIENDP(opt, neg, class, val, len) \ 952 if (neg) { \ 953 int i; \ 954 PUTCHAR(opt, ucp); \ 955 PUTCHAR(CILEN_CHAR + len, ucp); \ 956 PUTCHAR(class, ucp); \ 957 for (i = 0; i < len; ++i) \ 958 PUTCHAR(val[i], ucp); \ 959 } 960 961 ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_MRU, go->mru); 962 ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, 963 go->asyncmap); 964 /* go->chap_mdtype always points to a useful value */ 965 ADDCICHAP(CI_AUTHTYPE, go->neg_chap || go->neg_mschap || go->neg_mschapv2, 966 PPP_CHAP, go->chap_mdtype); 967 ADDCISHORT(CI_AUTHTYPE, !(go->neg_chap || go->neg_mschap || 968 go->neg_mschapv2) && go->neg_upap, PPP_PAP); 969 /* We can't both say zero for LQR period. */ 970 if (f->state == ACKSENT && go->neg_lqr && go->lqr_period == 0 && 971 ho->neg_lqr && ho->lqr_period == 0) 972 go->lqr_period = 500; 973 ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); 974 ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBOP_CBCP); 975 ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); 976 ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); 977 ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); 978 ADDCICHAR(CI_FCSALTERN, (go->neg_fcs && go->fcs_type != 0), go->fcs_type); 979 ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class, 980 go->endpoint.value, go->endpoint.length); 981 #ifdef MUX_FRAME 982 ADDCIVOID(CI_MUXING, go->pppmux); 983 #endif 984 ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru); 985 ADDCIVOID(CI_SSNHF, go->neg_ssnhf); 986 987 if (ucp - start_ucp != *lenp) { 988 /* this should never happen, because peer_mtu should be 1500 */ 989 error("Bug in lcp_addci: wrong length"); 990 } 991 } 992 993 994 /* 995 * lcp_ackci - Ack our CIs. 996 * This should not modify any state if the Ack is bad. 997 * 998 * Returns: 999 * 0 - Ack was bad. 1000 * 1 - Ack was good. 1001 */ 1002 static int 1003 lcp_ackci(f, p, len) 1004 fsm *f; 1005 u_char *p; 1006 int len; 1007 { 1008 lcp_options *go = &lcp_gotoptions[f->unit]; 1009 #ifdef MUX_FRAME 1010 lcp_options *ao = &lcp_allowoptions[f->unit]; 1011 #endif 1012 u_char cilen, citype, cichar; 1013 u_short cishort; 1014 u_int32_t cilong; 1015 1016 /* 1017 * CIs must be in exactly the same order that we sent. 1018 * Check packet length and CI length at each step. 1019 * If we find any deviations, then this packet is bad. 1020 */ 1021 #define ACKCIVOID(opt, neg) \ 1022 if (neg) { \ 1023 if ((len -= CILEN_VOID) < 0) \ 1024 goto bad; \ 1025 GETCHAR(citype, p); \ 1026 GETCHAR(cilen, p); \ 1027 if (cilen != CILEN_VOID || \ 1028 citype != opt) \ 1029 goto bad; \ 1030 } 1031 #define ACKCISHORT(opt, neg, val) \ 1032 if (neg) { \ 1033 if ((len -= CILEN_SHORT) < 0) \ 1034 goto bad; \ 1035 GETCHAR(citype, p); \ 1036 GETCHAR(cilen, p); \ 1037 if (cilen != CILEN_SHORT || \ 1038 citype != opt) \ 1039 goto bad; \ 1040 GETSHORT(cishort, p); \ 1041 if (cishort != val) \ 1042 goto bad; \ 1043 } 1044 #define ACKCIAUTH(opt, neg, val) \ 1045 if (neg) { \ 1046 if ((len -= CILEN_SHORT) < 0) \ 1047 goto bad; \ 1048 GETCHAR(citype, p); \ 1049 GETCHAR(cilen, p); \ 1050 if (cilen != CILEN_SHORT || \ 1051 citype != opt) \ 1052 goto bad; \ 1053 GETSHORT(cishort, p); \ 1054 if (cishort != val) \ 1055 goto bad; \ 1056 peer_nak_auth = 0; \ 1057 peer_reject_auth = 0; \ 1058 } 1059 #define ACKCICHAR(opt, neg, val) \ 1060 if (neg) { \ 1061 if ((len -= CILEN_CHAR) < 0) \ 1062 goto bad; \ 1063 GETCHAR(citype, p); \ 1064 GETCHAR(cilen, p); \ 1065 if (cilen != CILEN_CHAR || \ 1066 citype != opt) \ 1067 goto bad; \ 1068 GETCHAR(cichar, p); \ 1069 if (cichar != val) \ 1070 goto bad; \ 1071 } 1072 #define ACKCICHAP(opt, neg, val, digest) \ 1073 if (neg) { \ 1074 if ((len -= CILEN_CHAP) < 0) \ 1075 goto bad; \ 1076 GETCHAR(citype, p); \ 1077 GETCHAR(cilen, p); \ 1078 if (cilen != CILEN_CHAP || \ 1079 citype != opt) \ 1080 goto bad; \ 1081 GETSHORT(cishort, p); \ 1082 if (cishort != val) \ 1083 goto bad; \ 1084 GETCHAR(cichar, p); \ 1085 if (cichar != digest) \ 1086 goto bad; \ 1087 peer_nak_auth = 0; \ 1088 peer_reject_auth = 0; \ 1089 } 1090 #define ACKCILONG(opt, neg, val) \ 1091 if (neg) { \ 1092 if ((len -= CILEN_LONG) < 0) \ 1093 goto bad; \ 1094 GETCHAR(citype, p); \ 1095 GETCHAR(cilen, p); \ 1096 if (cilen != CILEN_LONG || \ 1097 citype != opt) \ 1098 goto bad; \ 1099 GETLONG(cilong, p); \ 1100 if (cilong != val) \ 1101 goto bad; \ 1102 } 1103 #define ACKCILQR(opt, neg, val) \ 1104 if (neg) { \ 1105 if ((len -= CILEN_LQR) < 0) \ 1106 goto bad; \ 1107 GETCHAR(citype, p); \ 1108 GETCHAR(cilen, p); \ 1109 if (cilen != CILEN_LQR || \ 1110 citype != opt) \ 1111 goto bad; \ 1112 GETSHORT(cishort, p); \ 1113 if (cishort != PPP_LQR) \ 1114 goto bad; \ 1115 GETLONG(cilong, p); \ 1116 if (cilong != val) \ 1117 goto bad; \ 1118 } 1119 #define ACKCIENDP(opt, neg, class, val, vlen) \ 1120 if (neg) { \ 1121 int i; \ 1122 if ((len -= CILEN_CHAR + vlen) < 0) \ 1123 goto bad; \ 1124 GETCHAR(citype, p); \ 1125 GETCHAR(cilen, p); \ 1126 if (cilen != CILEN_CHAR + vlen || \ 1127 citype != opt) \ 1128 goto bad; \ 1129 GETCHAR(cichar, p); \ 1130 if (cichar != class) \ 1131 goto bad; \ 1132 for (i = 0; i < vlen; ++i) { \ 1133 GETCHAR(cichar, p); \ 1134 if (cichar != val[i]) \ 1135 goto bad; \ 1136 } \ 1137 } 1138 1139 ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_MRU, go->mru); 1140 ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, 1141 go->asyncmap); 1142 /* go->chap_mdtype always points to a useful value */ 1143 ACKCICHAP(CI_AUTHTYPE, go->neg_chap || go->neg_mschap || go->neg_mschapv2, 1144 PPP_CHAP, go->chap_mdtype); 1145 ACKCIAUTH(CI_AUTHTYPE, !(go->neg_chap || go->neg_mschap || 1146 go->neg_mschapv2) && go->neg_upap, PPP_PAP); 1147 ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); 1148 ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBOP_CBCP); 1149 ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); 1150 ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); 1151 ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); 1152 ACKCICHAR(CI_FCSALTERN, go->neg_fcs, go->fcs_type); 1153 ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class, 1154 go->endpoint.value, go->endpoint.length); 1155 #ifdef MUX_FRAME 1156 ACKCIVOID(CI_MUXING, go->pppmux); 1157 if (go->pppmux) 1158 go->pppmux = ao->pppmux; 1159 #endif 1160 ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru); 1161 ACKCIVOID(CI_SSNHF, go->neg_ssnhf); 1162 1163 /* 1164 * If there are any remaining CIs, then this packet is bad. 1165 */ 1166 if (len != 0) 1167 goto bad; 1168 return (1); 1169 bad: 1170 dbglog("lcp_acki: received bad Ack!"); 1171 return (0); 1172 } 1173 1174 1175 /* 1176 * lcp_nakci - Peer has sent a NAK for some of our CIs. 1177 * This should not modify any state if the Nak is bad 1178 * or if LCP is in the OPENED state. 1179 * 1180 * Returns: 1181 * 0 - Nak was bad. 1182 * 1 - Nak was good. 1183 */ 1184 static int 1185 lcp_nakci(f, p, len) 1186 fsm *f; 1187 u_char *p; 1188 int len; 1189 { 1190 lcp_options *go = &lcp_gotoptions[f->unit]; 1191 lcp_options *wo = &lcp_wantoptions[f->unit]; 1192 u_char citype, cichar, *next; 1193 u_short cishort; 1194 u_int32_t cilong; 1195 lcp_options no; /* options we've seen Naks for */ 1196 lcp_options try; /* options to request next time */ 1197 int looped_back = 0; 1198 int cilen; 1199 1200 BZERO(&no, sizeof(no)); 1201 try = *go; 1202 1203 /* 1204 * Any Nak'd CIs must be in exactly the same order that we sent. 1205 * Check packet length and CI length at each step. 1206 * If we find any deviations, then this packet is bad. 1207 */ 1208 #define NAKCIVOID(opt, neg) \ 1209 if (go->neg && \ 1210 len >= CILEN_VOID && \ 1211 p[1] == CILEN_VOID && \ 1212 p[0] == opt) { \ 1213 len -= CILEN_VOID; \ 1214 INCPTR(CILEN_VOID, p); \ 1215 no.neg = 1; \ 1216 try.neg = 0; \ 1217 } 1218 #define NAKCICHAR(opt, neg, code) \ 1219 if (go->neg && \ 1220 len >= CILEN_CHAR && \ 1221 p[1] == CILEN_CHAR && \ 1222 p[0] == opt) { \ 1223 len -= CILEN_CHAR; \ 1224 INCPTR(2, p); \ 1225 GETCHAR(cichar, p); \ 1226 no.neg = 1; \ 1227 code \ 1228 } 1229 #define NAKCISHORT(opt, neg, code) \ 1230 if (go->neg && \ 1231 len >= CILEN_SHORT && \ 1232 p[1] == CILEN_SHORT && \ 1233 p[0] == opt) { \ 1234 len -= CILEN_SHORT; \ 1235 INCPTR(2, p); \ 1236 GETSHORT(cishort, p); \ 1237 no.neg = 1; \ 1238 code \ 1239 } 1240 #define NAKCILONG(opt, neg, code) \ 1241 if (go->neg && \ 1242 len >= CILEN_LONG && \ 1243 p[1] == CILEN_LONG && \ 1244 p[0] == opt) { \ 1245 len -= CILEN_LONG; \ 1246 INCPTR(2, p); \ 1247 GETLONG(cilong, p); \ 1248 no.neg = 1; \ 1249 code \ 1250 } 1251 #define NAKCILQR(opt, neg, code) \ 1252 if (go->neg && \ 1253 len >= CILEN_LQR && \ 1254 p[1] == CILEN_LQR && \ 1255 p[0] == opt) { \ 1256 len -= CILEN_LQR; \ 1257 INCPTR(2, p); \ 1258 GETSHORT(cishort, p); \ 1259 GETLONG(cilong, p); \ 1260 no.neg = 1; \ 1261 code \ 1262 } 1263 #define NAKCIENDP(opt, neg) \ 1264 if (go->neg && \ 1265 len >= CILEN_CHAR && \ 1266 p[0] == opt && \ 1267 p[1] >= CILEN_CHAR && \ 1268 p[1] <= len) { \ 1269 len -= p[1]; \ 1270 INCPTR(p[1], p); \ 1271 no.neg = 1; \ 1272 try.neg = 0; \ 1273 } 1274 1275 /* 1276 * We don't care if they want to send us smaller packets than 1277 * we want. Therefore, accept any MRU less than what we asked for, 1278 * but then ignore the new value when setting the MRU in the kernel. 1279 * If they send us a bigger MRU than what we asked, accept it, up to 1280 * the limit of the default MRU we'd get if we didn't negotiate. 1281 */ 1282 if (go->neg_mru && go->mru != PPP_MRU) { 1283 NAKCISHORT(CI_MRU, neg_mru, 1284 if (cishort <= wo->mru || 1285 (cishort <= PPP_MRU && cishort <= absmax_mru)) 1286 try.mru = cishort; 1287 ); 1288 } 1289 1290 /* 1291 * Add any characters they want to our (receive-side) asyncmap. 1292 */ 1293 if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) { 1294 NAKCILONG(CI_ASYNCMAP, neg_asyncmap, 1295 try.asyncmap = go->asyncmap | cilong; 1296 ); 1297 } 1298 1299 /* 1300 * If they've nak'd our authentication-protocol, check whether 1301 * they are proposing a different protocol, or a different 1302 * hash algorithm for CHAP. 1303 */ 1304 if ((go->neg_chap || go->neg_mschap || go->neg_mschapv2 || go->neg_upap) && 1305 len >= CILEN_SHORT && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && 1306 p[1] <= len) { 1307 cilen = p[1]; 1308 len -= cilen; 1309 INCPTR(2, p); 1310 GETSHORT(cishort, p); 1311 peer_nak_auth = 1; 1312 nak_auth_orig = (go->neg_chap || go->neg_mschap || go->neg_mschapv2) ? 1313 PPP_CHAP : PPP_PAP; 1314 nak_auth_proto = cishort; 1315 if (cishort == PPP_PAP && cilen == CILEN_SHORT) { 1316 no.neg_upap = go->neg_upap; 1317 /* 1318 * If we were asking for CHAP, they obviously don't want to do it. 1319 * If we weren't asking for CHAP, then we were asking for PAP, 1320 * in which case this Nak is bad. 1321 */ 1322 if (!go->neg_chap && !go->neg_mschap && !go->neg_mschapv2) 1323 goto bad; 1324 try.neg_chap = 0; 1325 try.neg_mschap = 0; 1326 try.neg_mschapv2 = 0; 1327 1328 } else if (cishort == PPP_CHAP && cilen >= CILEN_CHAP) { 1329 /* stop asking for that type */ 1330 switch (go->chap_mdtype) { 1331 case CHAP_DIGEST_MD5: 1332 no.neg_chap = go->neg_chap; 1333 try.neg_chap = 0; 1334 break; 1335 case CHAP_MICROSOFT: 1336 no.neg_mschap = go->neg_mschap; 1337 try.neg_mschap = 0; 1338 break; 1339 case CHAP_MICROSOFT_V2: 1340 no.neg_mschapv2 = go->neg_mschapv2; 1341 try.neg_mschapv2 = 0; 1342 break; 1343 } 1344 GETCHAR(cichar, p); 1345 /* Allow >= on length here for broken and silly peers. */ 1346 p += cilen - CILEN_CHAP; 1347 try.neg_upap = 0; 1348 if ((cichar == CHAP_DIGEST_MD5 && wo->neg_chap) || 1349 (cichar == CHAP_MICROSOFT && wo->neg_mschap) || 1350 (cichar == CHAP_MICROSOFT_V2 && wo->neg_mschapv2)) { 1351 /* Try its requested algorithm. */ 1352 try.chap_mdtype = cichar; 1353 } else { 1354 goto try_another; 1355 } 1356 1357 } else { 1358 /* 1359 * We don't recognize what they're suggesting. 1360 * Stop asking for what we were asking for. 1361 */ 1362 try_another: 1363 if (go->neg_chap || go->neg_mschap || go->neg_mschapv2) { 1364 switch (go->chap_mdtype) { 1365 case CHAP_DIGEST_MD5: 1366 try.neg_chap = 0; 1367 if (wo->neg_mschap) { 1368 try.chap_mdtype = CHAP_MICROSOFT; 1369 break; 1370 } 1371 /*FALLTHROUGH*/ 1372 case CHAP_MICROSOFT: 1373 try.neg_mschap = 0; 1374 if (wo->neg_mschapv2) { 1375 try.chap_mdtype = CHAP_MICROSOFT_V2; 1376 break; 1377 } 1378 /*FALLTHROUGH*/ 1379 case CHAP_MICROSOFT_V2: 1380 try.neg_mschapv2 = 0; 1381 break; 1382 } 1383 } else 1384 try.neg_upap = 0; 1385 p += cilen - CILEN_SHORT; 1386 } 1387 } 1388 1389 /* 1390 * If they can't cope with our link quality protocol, we'll have 1391 * to stop asking for LQR. We haven't got any other protocol. If 1392 * they Nak the reporting period, then the following logic 1393 * applies: 1394 * If it suggests zero and go->neg_fcs is true and 1395 * ao->lqr_period isn't zero, then take its suggestion. If it 1396 * suggests zero otherwise, ignore it. If it suggests a nonzero 1397 * value and wo->lqr_period is zero, then take its suggestion. If 1398 * it suggests a nonzero value otherwise that's less than 1399 * wo->lqr_period, then ignore it. 1400 */ 1401 NAKCILQR(CI_QUALITY, neg_lqr, 1402 if (cishort != PPP_LQR) 1403 try.neg_lqr = 0; 1404 else if (cilong == 0 && go->neg_fcs && wo->lqr_period != 0) 1405 try.lqr_period = cilong; 1406 else if (cilong != 0 && 1407 (wo->lqr_period == 0 || cilong > wo->lqr_period)) 1408 try.lqr_period = cilong; 1409 ); 1410 1411 /* 1412 * Only implementing CBCP...not the rest of the callback options 1413 */ 1414 NAKCICHAR(CI_CALLBACK, neg_cbcp, 1415 try.neg_cbcp = 0; 1416 ); 1417 1418 /* 1419 * Check for a looped-back line. 1420 */ 1421 NAKCILONG(CI_MAGICNUMBER, neg_magicnumber, 1422 try.magicnumber = magic(); 1423 looped_back = 1; 1424 ); 1425 1426 /* 1427 * Peer shouldn't send Nak for protocol compression or 1428 * address/control compression requests; they should send 1429 * a Reject instead. If they send a Nak, treat it as a Reject. 1430 */ 1431 NAKCIVOID(CI_PCOMPRESSION, neg_pcompression); 1432 NAKCIVOID(CI_ACCOMPRESSION, neg_accompression); 1433 1434 /* 1435 * Remove any FCS types it doesn't like from our (receive-side) 1436 * FCS list. 1437 */ 1438 NAKCICHAR(CI_FCSALTERN, neg_fcs, try.fcs_type = go->fcs_type & cichar;); 1439 1440 #ifdef MUX_FRAME 1441 /* Nacked MUX option */ 1442 NAKCIVOID(CI_MUXING, pppmux); 1443 #endif 1444 1445 /* 1446 * Nak of the endpoint discriminator option is not permitted, 1447 * treat it like a reject. 1448 */ 1449 NAKCIENDP(CI_EPDISC, neg_endpoint); 1450 1451 /* 1452 * Nak for MRRU option - accept their value if it is smaller 1453 * than the one we want. 1454 */ 1455 if (go->neg_mrru) { 1456 NAKCISHORT(CI_MRRU, neg_mrru, 1457 if (cishort <= wo->mrru) 1458 try.mrru = cishort; 1459 ); 1460 } 1461 1462 /* 1463 * Nak for short sequence numbers shouldn't be sent, treat it 1464 * like a reject. 1465 */ 1466 NAKCIVOID(CI_SSNHF, neg_ssnhf); 1467 1468 /* 1469 * There may be remaining CIs, if the peer is requesting negotiation 1470 * on an option that we didn't include in our request packet. 1471 * If we see an option that we requested, or one we've already seen 1472 * in this packet, then this packet is bad. 1473 * If we wanted to respond by starting to negotiate on the requested 1474 * option(s), we could, but we don't, because except for the 1475 * authentication type and quality protocol, if we are not negotiating 1476 * an option, it is because we were told not to. 1477 * For the authentication type, the Nak from the peer means 1478 * `let me authenticate myself with you' which is a bit pointless. 1479 * For the quality protocol, the Nak means `ask me to send you quality 1480 * reports', but if we didn't ask for them, we don't want them. 1481 * An option we don't recognize represents the peer asking to 1482 * negotiate some option we don't support, so ignore it. 1483 */ 1484 while (len > CILEN_VOID) { 1485 GETCHAR(citype, p); 1486 GETCHAR(cilen, p); 1487 if (cilen < CILEN_VOID || (len -= cilen) < 0) 1488 goto bad; 1489 next = p + cilen - 2; 1490 1491 switch (citype) { 1492 case CI_MRU: 1493 if ((go->neg_mru && go->mru != PPP_MRU) 1494 || no.neg_mru || cilen != CILEN_SHORT) 1495 goto bad; 1496 GETSHORT(cishort, p); 1497 if (cishort < PPP_MRU && cishort < absmax_mru) { 1498 try.neg_mru = 1; 1499 try.mru = cishort; 1500 notice("Peer sent unsolicited Nak for MRU less than default."); 1501 } 1502 break; 1503 case CI_ASYNCMAP: 1504 if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) 1505 || no.neg_asyncmap || cilen != CILEN_LONG) 1506 goto bad; 1507 break; 1508 case CI_AUTHTYPE: 1509 unsolicited_nak_auth = 1; 1510 if (cilen >= CILEN_SHORT) { 1511 GETSHORT(unsolicit_auth_proto, p); 1512 } else { 1513 unsolicit_auth_proto = 0; 1514 } 1515 if (go->neg_chap || no.neg_chap || 1516 go->neg_mschap || no.neg_mschap || 1517 go->neg_mschapv2 || no.neg_mschapv2 || 1518 go->neg_upap || no.neg_upap) 1519 goto bad; 1520 break; 1521 case CI_MAGICNUMBER: 1522 if (go->neg_magicnumber || no.neg_magicnumber || 1523 cilen != CILEN_LONG) 1524 goto bad; 1525 break; 1526 case CI_PCOMPRESSION: 1527 if (go->neg_pcompression || no.neg_pcompression 1528 || cilen != CILEN_VOID) 1529 goto bad; 1530 break; 1531 case CI_ACCOMPRESSION: 1532 if (go->neg_accompression || no.neg_accompression 1533 || cilen != CILEN_VOID) 1534 goto bad; 1535 break; 1536 case CI_QUALITY: 1537 if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR) 1538 goto bad; 1539 break; 1540 case CI_MRRU: 1541 if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT) 1542 goto bad; 1543 break; 1544 case CI_SSNHF: 1545 if (go->neg_ssnhf || no.neg_ssnhf || cilen != CILEN_VOID) 1546 goto bad; 1547 try.neg_ssnhf = 1; 1548 break; 1549 case CI_EPDISC: 1550 if (go->neg_endpoint || no.neg_endpoint || cilen < CILEN_CHAR) 1551 goto bad; 1552 break; 1553 case CI_FCSALTERN: 1554 if (go->neg_fcs || no.neg_fcs || cilen < CILEN_CHAR) 1555 goto bad; 1556 break; 1557 #ifdef MUX_FRAME 1558 case CI_MUXING: 1559 if (go->pppmux || no.pppmux || cilen < CILEN_VOID) 1560 goto bad; 1561 break; 1562 #endif 1563 } 1564 p = next; 1565 } 1566 1567 /* 1568 * OK, the Nak is good. Now we can update state. 1569 * If there are any options left we ignore them. 1570 */ 1571 if (f->state != OPENED) { 1572 /* 1573 * Note: the code once reset try.numloops to zero here if 1574 * looped_back wasn't set. This is wrong because a mixture of 1575 * looped-back and peer data (possible if half-duplex is used) 1576 * will allow the link to come up, and it shouldn't. 1577 */ 1578 if (looped_back) { 1579 if (++try.numloops >= lcp_loopbackfail) { 1580 notice("Serial line is looped back."); 1581 lcp_close(f->unit, "Loopback detected"); 1582 status = EXIT_LOOPBACK; 1583 } 1584 } 1585 *go = try; 1586 } 1587 1588 return 1; 1589 1590 bad: 1591 dbglog("lcp_nakci: received bad Nak!"); 1592 return 0; 1593 } 1594 1595 1596 /* 1597 * lcp_rejci - Peer has Rejected some of our CIs. 1598 * This should not modify any state if the Reject is bad 1599 * or if LCP is in the OPENED state. 1600 * 1601 * Returns: 1602 * 0 - Reject was bad. 1603 * 1 - Reject was good. 1604 */ 1605 static int 1606 lcp_rejci(f, p, len) 1607 fsm *f; 1608 u_char *p; 1609 int len; 1610 { 1611 lcp_options *go = &lcp_gotoptions[f->unit]; 1612 u_char cichar; 1613 u_short cishort; 1614 u_int32_t cilong; 1615 lcp_options try; /* options to request next time */ 1616 1617 try = *go; 1618 1619 /* 1620 * Any Rejected CIs must be in exactly the same order that we sent. 1621 * Check packet length and CI length at each step. 1622 * If we find any deviations, then this packet is bad. 1623 */ 1624 #define REJCIVOID(opt, neg) \ 1625 if (go->neg && \ 1626 len >= CILEN_VOID && \ 1627 p[1] == CILEN_VOID && \ 1628 p[0] == opt) { \ 1629 len -= CILEN_VOID; \ 1630 INCPTR(CILEN_VOID, p); \ 1631 try.neg = 0; \ 1632 } 1633 #define REJCICHAR(opt, neg, val) \ 1634 if (go->neg && \ 1635 len >= CILEN_CHAR && \ 1636 p[1] == CILEN_CHAR && \ 1637 p[0] == opt) { \ 1638 len -= CILEN_CHAR; \ 1639 INCPTR(2, p); \ 1640 GETCHAR(cichar, p); \ 1641 /* Check rejected value. */ \ 1642 if (cichar != val) \ 1643 goto bad; \ 1644 try.neg = 0; \ 1645 } 1646 #define REJCISHORT(opt, neg, val) \ 1647 if (go->neg && \ 1648 len >= CILEN_SHORT && \ 1649 p[1] == CILEN_SHORT && \ 1650 p[0] == opt) { \ 1651 len -= CILEN_SHORT; \ 1652 INCPTR(2, p); \ 1653 GETSHORT(cishort, p); \ 1654 /* Check rejected value. */ \ 1655 if (cishort != val) \ 1656 goto bad; \ 1657 try.neg = 0; \ 1658 } 1659 #define REJCIAUTH(opt, neg, val) \ 1660 if (go->neg && \ 1661 len >= CILEN_SHORT && \ 1662 p[1] == CILEN_SHORT && \ 1663 p[0] == opt) { \ 1664 len -= CILEN_SHORT; \ 1665 INCPTR(2, p); \ 1666 GETSHORT(cishort, p); \ 1667 /* Check rejected value. */ \ 1668 peer_reject_auth = 1; \ 1669 reject_auth_proto = cishort; \ 1670 if (cishort != val) \ 1671 goto bad; \ 1672 try.neg = 0; \ 1673 } 1674 #define REJCILONG(opt, neg, val) \ 1675 if (go->neg && \ 1676 len >= CILEN_LONG && \ 1677 p[1] == CILEN_LONG && \ 1678 p[0] == opt) { \ 1679 len -= CILEN_LONG; \ 1680 INCPTR(2, p); \ 1681 GETLONG(cilong, p); \ 1682 /* Check rejected value. */ \ 1683 if (cilong != val) \ 1684 goto bad; \ 1685 try.neg = 0; \ 1686 } 1687 #define REJCILQR(opt, neg, val) \ 1688 if (go->neg && \ 1689 len >= CILEN_LQR && \ 1690 p[1] == CILEN_LQR && \ 1691 p[0] == opt) { \ 1692 len -= CILEN_LQR; \ 1693 INCPTR(2, p); \ 1694 GETSHORT(cishort, p); \ 1695 GETLONG(cilong, p); \ 1696 /* Check rejected value. */ \ 1697 if (cishort != PPP_LQR || cilong != val) \ 1698 goto bad; \ 1699 try.neg = 0; \ 1700 } 1701 #define REJCICBCP(opt, neg, val) \ 1702 if (go->neg && \ 1703 len >= CILEN_CBCP && \ 1704 p[1] == CILEN_CBCP && \ 1705 p[0] == opt) { \ 1706 len -= CILEN_CBCP; \ 1707 INCPTR(2, p); \ 1708 GETCHAR(cichar, p); \ 1709 /* Check rejected value. */ \ 1710 if (cichar != val) \ 1711 goto bad; \ 1712 try.neg = 0; \ 1713 } 1714 #define REJCIENDP(opt, neg, class, val, vlen) \ 1715 if (go->neg && \ 1716 len >= CILEN_CHAR + vlen && \ 1717 p[0] == opt && \ 1718 p[1] == CILEN_CHAR + vlen) { \ 1719 int i; \ 1720 len -= CILEN_CHAR + vlen; \ 1721 INCPTR(2, p); \ 1722 GETCHAR(cichar, p); \ 1723 if (cichar != class) \ 1724 goto bad; \ 1725 for (i = 0; i < vlen; ++i) { \ 1726 GETCHAR(cichar, p); \ 1727 if (cichar != val[i]) \ 1728 goto bad; \ 1729 } \ 1730 try.neg = 0; \ 1731 } 1732 1733 /* Received a Configure-Reject, try to send Identification now. */ 1734 if (!noident && sentident < 3) { 1735 LcpSendIdentification(f); 1736 sentident++; 1737 } 1738 1739 REJCISHORT(CI_MRU, neg_mru, go->mru); 1740 REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); 1741 1742 /* 1743 * There are broken peers (such as unbundled Solaris PPP) that 1744 * send Configure-Reject for authentication when they really 1745 * intend Configure-Nak. This code works around this problem. 1746 */ 1747 if ((go->neg_chap || go->neg_mschap || go->neg_mschapv2) && 1748 len >= CILEN_CHAP && p[1] == CILEN_CHAP && p[0] == CI_AUTHTYPE) { 1749 len -= CILEN_CHAP; 1750 INCPTR(2, p); 1751 GETSHORT(cishort, p); 1752 GETCHAR(cichar, p); 1753 peer_reject_auth = 1; 1754 reject_auth_proto = cishort; 1755 /* Check rejected value. */ 1756 if (cishort != PPP_CHAP || cichar != go->chap_mdtype) 1757 goto bad; 1758 /* Disable the one that it rejected */ 1759 switch (cichar) { 1760 case CHAP_DIGEST_MD5: 1761 try.neg_chap = 0; 1762 break; 1763 case CHAP_MICROSOFT: 1764 try.neg_mschap = 0; 1765 break; 1766 case CHAP_MICROSOFT_V2: 1767 try.neg_mschapv2 = 0; 1768 break; 1769 } 1770 /* Try another, if we can. */ 1771 if (try.neg_chap) 1772 try.chap_mdtype = CHAP_DIGEST_MD5; 1773 else if (try.neg_mschap) 1774 try.chap_mdtype = CHAP_MICROSOFT; 1775 else 1776 try.chap_mdtype = CHAP_MICROSOFT_V2; 1777 } 1778 1779 if (!go->neg_chap && !go->neg_mschap && !go->neg_mschapv2) { 1780 REJCIAUTH(CI_AUTHTYPE, neg_upap, PPP_PAP); 1781 } 1782 REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period); 1783 REJCICBCP(CI_CALLBACK, neg_cbcp, CBOP_CBCP); 1784 REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); 1785 REJCIVOID(CI_PCOMPRESSION, neg_pcompression); 1786 REJCIVOID(CI_ACCOMPRESSION, neg_accompression); 1787 REJCICHAR(CI_FCSALTERN, neg_fcs, go->fcs_type); 1788 #ifdef MUX_FRAME 1789 REJCIVOID(CI_MUXING,pppmux); 1790 #endif 1791 REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class, 1792 go->endpoint.value, go->endpoint.length); 1793 REJCISHORT(CI_MRRU, neg_mrru, go->mrru); 1794 REJCIVOID(CI_SSNHF, neg_ssnhf); 1795 1796 /* 1797 * If there are any remaining CIs, then this packet is bad. 1798 */ 1799 if (len != 0) 1800 goto bad; 1801 /* 1802 * Now we can update state. 1803 */ 1804 if (f->state != OPENED) 1805 *go = try; 1806 return 1; 1807 1808 bad: 1809 dbglog("lcp_rejci: received bad Reject!"); 1810 return 0; 1811 } 1812 1813 1814 /* 1815 * lcp_reqci - Check the peer's requested CIs and send appropriate response. 1816 * 1817 * Returns: CODE_CONFACK, CODE_CONFNAK or CODE_CONFREJ and input 1818 * packet modified appropriately. If reject_if_disagree is non-zero, 1819 * doesn't return CODE_CONFNAK; returns CODE_CONFREJ if it can't 1820 * return CODE_CONFACK. 1821 */ 1822 static int 1823 lcp_reqci(f, p, lenp, dont_nak) 1824 fsm *f; 1825 u_char *p; /* Requested CIs */ 1826 int *lenp; /* Length of requested CIs */ 1827 int dont_nak; 1828 { 1829 lcp_options *wo = &lcp_wantoptions[f->unit]; 1830 lcp_options *go = &lcp_gotoptions[f->unit]; 1831 lcp_options *ho = &lcp_hisoptions[f->unit]; 1832 lcp_options *ao = &lcp_allowoptions[f->unit]; 1833 int cilen, citype, cichar; /* Parsed len, type, char value */ 1834 u_short cishort; /* Parsed short value */ 1835 u_int32_t cilong; /* Parse long value */ 1836 int ret, newret; 1837 u_char *p0, *nakp, *rejp, *prev; 1838 int len; 1839 1840 /* 1841 * Loop through options once to find out if peer is offering 1842 * Multilink, and repair values as needed. 1843 */ 1844 ao->mru = ao->mrru; 1845 p0 = p; 1846 for (len = *lenp; len > 0; len -= cilen, p = prev + cilen) { 1847 if (len < 2 || p[1] > len) { 1848 /* 1849 * RFC 1661 page 40 -- if the option extends beyond the 1850 * packet, then discard the entire packet. 1851 */ 1852 dbglog("discarding LCP Configure-Request due to truncated option"); 1853 return (0); 1854 } 1855 prev = p; 1856 GETCHAR(citype, p); 1857 GETCHAR(cilen, p); 1858 if (citype == CI_MRRU) { 1859 if (ao->mrru != 0) { 1860 if (ao->mrru+6 > PPP_MTU) 1861 ao->mru = PPP_MTU; 1862 else 1863 ao->mru = ao->mrru + 6; 1864 } 1865 } 1866 if (cilen < 2) 1867 cilen = 2; 1868 } 1869 if (ao->mru > absmax_mtu) 1870 ao->mru = absmax_mtu; 1871 1872 ret = CODE_CONFACK; 1873 rejp = p = p0; 1874 nakp = nak_buffer; 1875 1876 /* 1877 * Reset all its options. 1878 */ 1879 BZERO(ho, sizeof(*ho)); 1880 1881 /* 1882 * Process all its options. 1883 */ 1884 for (len = *lenp; len > 0; len -= cilen, p = prev + cilen) { 1885 newret = CODE_CONFACK; /* Assume success */ 1886 1887 prev = p; 1888 GETCHAR(citype, p); 1889 GETCHAR(cilen, p); 1890 1891 switch (citype) { /* Check CI type */ 1892 case CI_MRU: 1893 if (!ao->neg_mru) { 1894 newret = CODE_CONFREJ; 1895 break; 1896 } 1897 1898 if (cilen != CILEN_SHORT) { /* Check CI length */ 1899 newret = CODE_CONFNAK; 1900 cishort = ao->mru; 1901 } else { 1902 /* extract the MRU from the option */ 1903 GETSHORT(cishort, p); 1904 1905 /* 1906 * If the offered MRU is less than our desired MTU, we 1907 * should nak. This is especially helpful if we're 1908 * doing demand-dial, since those queued up packets 1909 * might be discarded otherwise. 1910 */ 1911 if (cishort < ao->mru) { 1912 newret = CODE_CONFNAK; 1913 cishort = ao->mru; 1914 } 1915 } 1916 1917 /* 1918 * If we're going to send a nak with something less than 1919 * or equal to the default PPP MTU, then just reject instead. 1920 */ 1921 if (newret == CODE_CONFNAK && cishort <= PPP_MTU) 1922 newret = CODE_CONFREJ; 1923 1924 if (newret == CODE_CONFNAK) { 1925 PUTCHAR(CI_MRU, nakp); 1926 PUTCHAR(CILEN_SHORT, nakp); 1927 PUTSHORT(cishort, nakp); /* Give it a hint */ 1928 } 1929 1930 ho->neg_mru = 1; /* Remember that it sent MRU */ 1931 ho->mru = cishort; /* And remember value */ 1932 break; 1933 1934 case CI_ASYNCMAP: 1935 if (!ao->neg_asyncmap) { 1936 newret = CODE_CONFREJ; 1937 break; 1938 } 1939 1940 if (cilen != CILEN_LONG) { 1941 newret = CODE_CONFNAK; 1942 cilong = 0; 1943 } else { 1944 GETLONG(cilong, p); 1945 1946 /* 1947 * Asyncmap must have set at least the bits 1948 * which are set in lcp_allowoptions[unit].asyncmap. 1949 */ 1950 if ((ao->asyncmap & ~cilong) != 0) 1951 newret = CODE_CONFNAK; 1952 } 1953 1954 /* 1955 * Workaround for common broken Microsoft software -- if 1956 * the peer is sending us a nonzero ACCM, then it *needs* 1957 * us to send the same to it. Adjust our Configure- 1958 * Request message and restart LCP. 1959 */ 1960 if (do_msft_workaround && (cilong & ~wo->asyncmap)) { 1961 dbglog("adjusted requested asyncmap from %X to %X", 1962 wo->asyncmap, wo->asyncmap | cilong); 1963 do_msft_workaround = 0; 1964 wo->neg_asyncmap = 1; 1965 wo->asyncmap |= cilong; 1966 f->flags &= ~OPT_SILENT; 1967 info("possibly broken peer detected; restarting LCP"); 1968 fsm_lowerdown(f); 1969 fsm_lowerup(f); 1970 return (0); 1971 } 1972 1973 if (newret == CODE_CONFNAK) { 1974 PUTCHAR(CI_ASYNCMAP, nakp); 1975 PUTCHAR(CILEN_LONG, nakp); 1976 PUTLONG(ao->asyncmap | cilong, nakp); 1977 } 1978 ho->neg_asyncmap = 1; 1979 ho->asyncmap = cilong; 1980 break; 1981 1982 case CI_AUTHTYPE: 1983 if (!(ao->neg_upap || ao->neg_chap || ao->neg_mschap || 1984 ao->neg_mschapv2)) { 1985 rejected_peers_auth = 1; 1986 if (cilen >= CILEN_SHORT) { 1987 GETSHORT(rejected_auth_proto, p); 1988 } else { 1989 rejected_auth_proto = 0; 1990 } 1991 /* 1992 * Reject the option if we're not willing to authenticate. 1993 */ 1994 newret = CODE_CONFREJ; 1995 break; 1996 } 1997 rejected_peers_auth = 0; 1998 naked_peers_auth = 0; 1999 2000 if (cilen >= CILEN_SHORT) { 2001 /* Extract the authentication protocol from the option */ 2002 GETSHORT(cishort, p); 2003 2004 if (ho->neg_upap || ho->neg_chap || ho->neg_mschap || 2005 ho->neg_mschapv2) { 2006 dbglog("Rejecting extra authentication protocol option"); 2007 newret = CODE_CONFREJ; 2008 break; 2009 } 2010 2011 /* 2012 * Authtype must be PAP or CHAP. 2013 * 2014 * Note: if both ao->neg_upap and ao->neg_*chap* are 2015 * set, and the peer sends a Configure-Request with 2016 * two authenticate-protocol requests, one for CHAP 2017 * and one for UPAP, then we will reject the second 2018 * request. Whether we end up doing CHAP or UPAP 2019 * depends then on the ordering of the CIs in the 2020 * peer's Configure-Request. 2021 * 2022 * We're supposed to list all of the protocols we can 2023 * possibly use in the returned Configure-Nak. This 2024 * part of RFC 1661 (section 5.3) is in conflict with 2025 * the section that says the options shouldn't be 2026 * reordered, so it's often ignored. 2027 */ 2028 2029 if (cishort == PPP_PAP) { 2030 if (ao->neg_upap) { 2031 if (cilen != CILEN_SHORT) 2032 goto try_pap_anyway; 2033 ho->neg_upap = 1; 2034 break; 2035 } 2036 } else if (cishort == PPP_CHAP) { 2037 /* Test >= here to allow for broken peers. */ 2038 if (cilen >= CILEN_CHAP && 2039 (ao->neg_chap || ao->neg_mschap || ao->neg_mschapv2)) { 2040 GETCHAR(cichar, p); 2041 if (cichar == CHAP_DIGEST_MD5 && ao->neg_chap) 2042 ho->neg_chap = 1; 2043 else if (cichar == CHAP_MICROSOFT && ao->neg_mschap) 2044 ho->neg_mschap = 1; 2045 else if (cichar == CHAP_MICROSOFT_V2 && 2046 ao->neg_mschapv2) 2047 ho->neg_mschap = 1; 2048 if (ho->neg_chap || ho->neg_mschap || 2049 ho->neg_mschapv2) { 2050 ho->chap_mdtype = cichar; /* save md type */ 2051 break; 2052 } 2053 } 2054 } 2055 } 2056 2057 /* 2058 * We don't recognize the protocol they're asking for. 2059 * Nak it with something we're willing to do. 2060 * (At this point we know ao->neg_upap || ao->neg_chap.) 2061 */ 2062 PUTCHAR(CI_AUTHTYPE, nakp); 2063 if (ao->neg_chap || ao->neg_mschap || ao->neg_mschapv2) { 2064 PUTCHAR(CILEN_CHAP, nakp); 2065 PUTSHORT(PPP_CHAP, nakp); 2066 PUTCHAR(ao->chap_mdtype, nakp); 2067 naked_auth_proto = PPP_CHAP; 2068 } else { 2069 try_pap_anyway: 2070 PUTCHAR(CILEN_SHORT, nakp); 2071 PUTSHORT(PPP_PAP, nakp); 2072 naked_auth_proto = PPP_PAP; 2073 } 2074 naked_peers_auth = 1; 2075 naked_auth_orig = cishort; 2076 newret = CODE_CONFNAK; 2077 break; 2078 2079 case CI_QUALITY: 2080 if (!ao->neg_lqr) { 2081 newret = CODE_CONFREJ; 2082 break; 2083 } 2084 2085 if (cilen != CILEN_LQR) { 2086 newret = CODE_CONFNAK; 2087 cilong = ao->lqr_period; 2088 } else { 2089 2090 GETSHORT(cishort, p); 2091 GETLONG(cilong, p); 2092 2093 /* Check the LQM protocol */ 2094 if (cishort != PPP_LQR) { 2095 newret = CODE_CONFNAK; 2096 } 2097 2098 /* Check the reporting period; we can't both send zero */ 2099 if ((cilong == 0 && go->lqr_period == 0) || 2100 cilong < ao->lqr_period) { 2101 newret = CODE_CONFNAK; 2102 if ((cilong = ao->lqr_period) == 0) 2103 cilong = 500; 2104 } 2105 } 2106 2107 if (newret == CODE_CONFNAK) { 2108 PUTCHAR(CI_QUALITY, nakp); 2109 PUTCHAR(CILEN_LQR, nakp); 2110 PUTSHORT(PPP_LQR, nakp); 2111 PUTLONG(cilong, nakp); 2112 } 2113 2114 ho->neg_lqr = 1; 2115 ho->lqr_period = cilong; 2116 break; 2117 2118 case CI_MAGICNUMBER: 2119 if (!(ao->neg_magicnumber || go->neg_magicnumber)) { 2120 newret = CODE_CONFREJ; 2121 break; 2122 } 2123 2124 ho->neg_magicnumber = 1; 2125 if (cilen < CILEN_LONG) { 2126 /* 2127 * If we send Magic-Number, then we must not reject it 2128 * when the peer sends it to us, even if its version 2129 * looks odd to us. Ack if the cilent is wrong in this 2130 * case. If we're not sending Magic-Number, then we don't 2131 * much care what its value is anyway. 2132 */ 2133 break; 2134 } 2135 2136 GETLONG(cilong, p); 2137 ho->magicnumber = cilong; 2138 if (cilen > CILEN_LONG) 2139 break; 2140 2141 /* 2142 * It must have a different magic number. Make sure we 2143 * give it a good one to use. 2144 */ 2145 while (go->neg_magicnumber && cilong == go->magicnumber) { 2146 newret = CODE_CONFNAK; 2147 cilong = magic(); 2148 } 2149 2150 if (newret == CODE_CONFNAK) { 2151 PUTCHAR(CI_MAGICNUMBER, nakp); 2152 PUTCHAR(CILEN_LONG, nakp); 2153 PUTLONG(cilong, nakp); 2154 /* 2155 * We don't need to bump the numloops counter here 2156 * since it's already done upon reception of a nak. 2157 */ 2158 } 2159 break; 2160 2161 case CI_PCOMPRESSION: 2162 if (!ao->neg_pcompression) { 2163 newret = CODE_CONFREJ; 2164 break; 2165 } 2166 if (cilen != CILEN_VOID) { 2167 newret = CODE_CONFNAK; 2168 PUTCHAR(CI_PCOMPRESSION, nakp); 2169 PUTCHAR(CILEN_VOID, nakp); 2170 } 2171 ho->neg_pcompression = 1; 2172 break; 2173 2174 case CI_ACCOMPRESSION: 2175 if (!ao->neg_accompression) { 2176 newret = CODE_CONFREJ; 2177 break; 2178 } 2179 if (cilen != CILEN_VOID) { 2180 newret = CODE_CONFNAK; 2181 PUTCHAR(CI_ACCOMPRESSION, nakp); 2182 PUTCHAR(CILEN_VOID, nakp); 2183 } 2184 ho->neg_accompression = 1; 2185 break; 2186 2187 case CI_FCSALTERN: 2188 if (!ao->neg_fcs) { 2189 newret = CODE_CONFREJ; 2190 break; 2191 } 2192 2193 if (cilen != CILEN_CHAR) { 2194 newret = CODE_CONFNAK; 2195 cichar = ao->fcs_type; 2196 } else { 2197 2198 GETCHAR(cichar, p); 2199 /* If it has bits we don't like, tell it to stop. */ 2200 if (cichar & ~ao->fcs_type) { 2201 if ((cichar &= ao->fcs_type) == 0) { 2202 newret = CODE_CONFREJ; 2203 break; 2204 } 2205 newret = CODE_CONFNAK; 2206 } 2207 } 2208 if (newret == CODE_CONFNAK) { 2209 PUTCHAR(CI_FCSALTERN, nakp); 2210 PUTCHAR(CILEN_CHAR, nakp); 2211 PUTCHAR(cichar, nakp); 2212 } 2213 ho->neg_fcs = 1; 2214 ho->fcs_type = cichar; 2215 break; 2216 2217 case CI_MRRU: 2218 if (!ao->neg_mrru || !multilink) { 2219 newret = CODE_CONFREJ; 2220 break; 2221 } 2222 if (cilen != CILEN_SHORT) { 2223 newret = CODE_CONFNAK; 2224 cishort = ao->mrru; 2225 } else { 2226 GETSHORT(cishort, p); 2227 if (cishort < ao->mrru) { 2228 newret = CODE_CONFNAK; 2229 cishort = ao->mrru; 2230 } 2231 } 2232 2233 if (cishort < PPP_MINMTU) { 2234 newret = CODE_CONFNAK; 2235 cishort = PPP_MINMTU; 2236 } 2237 2238 if (newret == CODE_CONFNAK) { 2239 PUTCHAR(CI_MRRU, nakp); 2240 PUTCHAR(CILEN_SHORT, nakp); 2241 PUTSHORT(cishort, nakp); 2242 } 2243 2244 ho->neg_mrru = 1; 2245 ho->mrru = cishort; 2246 break; 2247 2248 case CI_SSNHF: 2249 if (!ao->neg_ssnhf || !multilink) { 2250 newret = CODE_CONFREJ; 2251 break; 2252 } 2253 if (cilen != CILEN_VOID) { 2254 newret = CODE_CONFNAK; 2255 PUTCHAR(CI_SSNHF, nakp); 2256 PUTCHAR(CILEN_VOID, nakp); 2257 } 2258 ho->neg_ssnhf = 1; 2259 break; 2260 2261 case CI_EPDISC: 2262 if (!ao->neg_endpoint) { 2263 newret = CODE_CONFREJ; 2264 break; 2265 } 2266 if (cilen < CILEN_CHAR || cilen > CILEN_CHAR + MAX_ENDP_LEN) { 2267 int i; 2268 2269 newret = CODE_CONFNAK; 2270 PUTCHAR(CI_EPDISC, nakp); 2271 PUTCHAR(CILEN_CHAR + ao->endpoint.length, nakp); 2272 PUTCHAR(ao->endpoint.class, nakp); 2273 for (i = 0; i < ao->endpoint.length; i++) 2274 PUTCHAR(ao->endpoint.value[i], nakp); 2275 break; 2276 } 2277 GETCHAR(cichar, p); 2278 ho->neg_endpoint = 1; 2279 ho->endpoint.class = cichar; 2280 ho->endpoint.length = cilen - 3; 2281 BCOPY(p, ho->endpoint.value, cilen - 3); 2282 break; 2283 2284 #ifdef MUX_FRAME 2285 case CI_MUXING: 2286 if (ao->pppmux == 0 || cilen != CILEN_VOID) { 2287 newret = CODE_CONFREJ; 2288 break; 2289 } 2290 /* remember its option */ 2291 ho->pppmux = ao->pppmux; 2292 break; 2293 #endif 2294 2295 default: 2296 dbglog("LCP: rejecting unknown option %d", citype); 2297 newret = CODE_CONFREJ; 2298 break; 2299 } 2300 2301 /* Cope with confused peers. */ 2302 if (cilen < 2) 2303 cilen = 2; 2304 2305 /* 2306 * If this is an Ack'able CI, but we're sending back a Nak, 2307 * don't include this CI. 2308 */ 2309 if (newret == CODE_CONFACK && ret != CODE_CONFACK) 2310 continue; 2311 2312 if (newret == CODE_CONFNAK) { 2313 /* 2314 * Continue naking the Magic Number option until the cows come 2315 * home -- rejecting it is wrong. 2316 */ 2317 if (dont_nak && citype != CI_MAGICNUMBER) { 2318 newret = CODE_CONFREJ; 2319 } else { 2320 /* Ignore subsequent Nak'able things if rejecting. */ 2321 if (ret == CODE_CONFREJ) 2322 continue; 2323 ret = CODE_CONFNAK; 2324 } 2325 } 2326 2327 if (newret == CODE_CONFREJ) { 2328 ret = CODE_CONFREJ; 2329 if (prev != rejp) 2330 BCOPY(prev, rejp, cilen); 2331 rejp += cilen; 2332 } 2333 } 2334 2335 /* 2336 * If the peer hasn't negotiated its MRU, and we'd like an MTU 2337 * that's larger than the default, try sending an unsolicited 2338 * Nak for what we want. 2339 */ 2340 if (ret != CODE_CONFREJ && !ho->neg_mru && ao->mru > PPP_MTU && 2341 !dont_nak && unsolicit_mru) { 2342 unsolicit_mru = 0; /* don't ask again */ 2343 ret = CODE_CONFNAK; 2344 PUTCHAR(CI_MRU, nakp); 2345 PUTCHAR(CILEN_SHORT, nakp); 2346 PUTSHORT(ao->mru, nakp); 2347 } 2348 2349 switch (ret) { 2350 case CODE_CONFACK: 2351 *lenp = p - p0; 2352 break; 2353 case CODE_CONFNAK: 2354 /* 2355 * Copy the Nak'd options from the nak_buffer to the caller's buffer. 2356 */ 2357 *lenp = nakp - nak_buffer; 2358 BCOPY(nak_buffer, p0, *lenp); 2359 break; 2360 case CODE_CONFREJ: 2361 *lenp = rejp - p0; 2362 2363 /* We're about to send Configure-Reject; send Identification */ 2364 if (!noident && sentident < 3) { 2365 LcpSendIdentification(f); 2366 sentident++; 2367 } 2368 break; 2369 } 2370 2371 LCPDEBUG(("lcp_reqci: returning %s.", code_name(ret, 1))); 2372 return (ret); /* Return final code */ 2373 } 2374 2375 2376 /* 2377 * lcp_up - LCP has come UP. 2378 */ 2379 static void 2380 lcp_up(f) 2381 fsm *f; 2382 { 2383 lcp_options *wo = &lcp_wantoptions[f->unit]; 2384 lcp_options *ho = &lcp_hisoptions[f->unit]; 2385 lcp_options *go = &lcp_gotoptions[f->unit]; 2386 lcp_options *ao = &lcp_allowoptions[f->unit]; 2387 int mru, mtu; 2388 2389 if (!go->neg_magicnumber) 2390 go->magicnumber = 0; 2391 if (!ho->neg_magicnumber) 2392 ho->magicnumber = 0; 2393 2394 /* 2395 * Set our MTU to the smaller of the MTU we wanted and 2396 * the MRU our peer wanted. If we negotiated an MRU, 2397 * set our MRU to the larger of value we wanted and 2398 * the value we got in the negotiation. 2399 */ 2400 if (ao->mru != 0 && ho->mru > ao->mru) 2401 ho->mru = ao->mru; 2402 mtu = (ho->neg_mru ? ho->mru: PPP_MRU); 2403 if (mtu > absmax_mtu) 2404 mtu = absmax_mtu; 2405 ppp_send_config(f->unit, mtu, 2406 (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), 2407 ho->neg_pcompression, ho->neg_accompression); 2408 fsm_setpeermru(f->unit, mtu); 2409 mru = (go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU); 2410 if (mru > absmax_mru) 2411 mru = absmax_mru; 2412 ppp_recv_config(f->unit, mru, 2413 (lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff), 2414 go->neg_pcompression, go->neg_accompression); 2415 #ifdef NEGOTIATE_FCS 2416 ppp_send_fcs(f->unit, ho->neg_fcs ? ho->fcs_type : FCSALT_16); 2417 ppp_recv_fcs(f->unit, go->neg_fcs ? go->fcs_type : FCSALT_16); 2418 #endif 2419 #ifdef MUX_FRAME 2420 ppp_send_muxoption(f->unit, ho->pppmux); 2421 ppp_recv_muxoption(f->unit, go->pppmux); 2422 #endif 2423 2424 lcp_echo_lowerup(f->unit); /* Enable echo messages */ 2425 2426 /* LCP is Up; send Identification */ 2427 if (!noident) { 2428 LcpSendIdentification(f); 2429 sentident++; 2430 } 2431 2432 link_established(f->unit); 2433 } 2434 2435 2436 /* 2437 * lcp_down - LCP has gone DOWN. 2438 * 2439 * Alert other protocols. 2440 */ 2441 static void 2442 lcp_down(f) 2443 fsm *f; 2444 { 2445 int mtu; 2446 lcp_options *go = &lcp_gotoptions[f->unit]; 2447 2448 lcp_echo_lowerdown(f->unit); 2449 2450 link_down(f->unit); 2451 2452 mtu = PPP_MTU > absmax_mtu ? absmax_mtu : PPP_MTU; 2453 ppp_send_config(f->unit, mtu, 0xffffffff, 0, 0); 2454 ppp_recv_config(f->unit, (PPP_MRU > absmax_mru ? absmax_mru : PPP_MRU), 2455 (go->neg_asyncmap? go->asyncmap: 0xffffffff), 2456 go->neg_pcompression, go->neg_accompression); 2457 #ifdef NEGOTIATE_FCS 2458 ppp_send_fcs(f->unit, FCSALT_16); 2459 ppp_recv_fcs(f->unit, FCSALT_16); 2460 #endif 2461 fsm_setpeermru(f->unit, mtu); 2462 } 2463 2464 2465 /* 2466 * lcp_starting - LCP needs the lower layer up. 2467 */ 2468 static void 2469 lcp_starting(f) 2470 fsm *f; 2471 { 2472 link_required(f->unit); 2473 } 2474 2475 2476 /* 2477 * lcp_finished - LCP has finished with the lower layer. 2478 */ 2479 static void 2480 lcp_finished(f) 2481 fsm *f; 2482 { 2483 link_terminated(f->unit); 2484 } 2485 2486 2487 /* 2488 * lcp_printpkt - print the contents of an LCP packet. 2489 */ 2490 2491 static int 2492 lcp_printpkt(p, plen, printer, arg) 2493 u_char *p; 2494 int plen; 2495 void (*printer) __P((void *, const char *, ...)); 2496 void *arg; 2497 { 2498 int code, id, len, olen, i; 2499 u_char *pstart, *optend, cichar; 2500 u_short cishort; 2501 u_int32_t cilong; 2502 2503 if (plen < HEADERLEN) 2504 return 0; 2505 pstart = p; 2506 GETCHAR(code, p); 2507 GETCHAR(id, p); 2508 GETSHORT(len, p); 2509 if (len < HEADERLEN || len > plen) 2510 return 0; 2511 2512 printer(arg, " %s id=0x%x", code_name(code,1), id); 2513 len -= HEADERLEN; 2514 switch (code) { 2515 case CODE_CONFREQ: 2516 case CODE_CONFACK: 2517 case CODE_CONFNAK: 2518 case CODE_CONFREJ: 2519 /* print option list */ 2520 while (len >= 2) { 2521 GETCHAR(code, p); 2522 GETCHAR(olen, p); 2523 p -= 2; 2524 if (olen < 2 || olen > len) { 2525 break; 2526 } 2527 printer(arg, " <"); 2528 len -= olen; 2529 optend = p + olen; 2530 switch (code) { 2531 case CI_MRU: 2532 if (olen >= CILEN_SHORT) { 2533 p += 2; 2534 GETSHORT(cishort, p); 2535 printer(arg, "mru %d", cishort); 2536 } 2537 break; 2538 case CI_ASYNCMAP: 2539 if (olen >= CILEN_LONG) { 2540 p += 2; 2541 GETLONG(cilong, p); 2542 printer(arg, "asyncmap 0x%x", cilong); 2543 } 2544 break; 2545 case CI_AUTHTYPE: 2546 if (olen >= CILEN_SHORT) { 2547 p += 2; 2548 printer(arg, "auth "); 2549 GETSHORT(cishort, p); 2550 switch (cishort) { 2551 case PPP_PAP: 2552 printer(arg, "pap"); 2553 break; 2554 case PPP_CHAP: 2555 printer(arg, "chap"); 2556 if (p < optend) { 2557 switch (*p) { 2558 case CHAP_DIGEST_MD5: 2559 printer(arg, " MD5"); 2560 ++p; 2561 break; 2562 case CHAP_MICROSOFT: 2563 printer(arg, " m$oft"); 2564 ++p; 2565 break; 2566 case CHAP_MICROSOFT_V2: 2567 printer(arg, " m$oft-v2"); 2568 ++p; 2569 break; 2570 } 2571 } 2572 break; 2573 #ifdef PPP_EAP 2574 case PPP_EAP: 2575 printer(arg, "eap"); 2576 break; 2577 #endif 2578 case 0xC027: 2579 printer(arg, "spap"); 2580 break; 2581 case 0xC123: 2582 printer(arg, "old-spap"); 2583 break; 2584 default: 2585 printer(arg, "0x%x", cishort); 2586 } 2587 } 2588 break; 2589 case CI_QUALITY: 2590 if (olen >= CILEN_SHORT) { 2591 p += 2; 2592 printer(arg, "quality "); 2593 GETSHORT(cishort, p); 2594 switch (cishort) { 2595 case PPP_LQR: 2596 printer(arg, "lqr"); 2597 break; 2598 default: 2599 printer(arg, "0x%x", cishort); 2600 } 2601 } 2602 break; 2603 case CI_CALLBACK: 2604 if (olen >= CILEN_CHAR) { 2605 p += 2; 2606 printer(arg, "callback "); 2607 GETCHAR(cichar, p); 2608 if (cichar <= 6 && 2609 *callback_strings[(int)cichar] != '\0') { 2610 printer(arg, "%s", callback_strings[(int)cichar]); 2611 } else { 2612 printer(arg, "0x%x", cichar); 2613 } 2614 } 2615 break; 2616 case CI_MAGICNUMBER: 2617 if (olen >= CILEN_LONG) { 2618 p += 2; 2619 GETLONG(cilong, p); 2620 printer(arg, "magic 0x%x", cilong); 2621 } 2622 break; 2623 case CI_PCOMPRESSION: 2624 if (olen >= CILEN_VOID) { 2625 p += 2; 2626 printer(arg, "pcomp"); 2627 } 2628 break; 2629 case CI_ACCOMPRESSION: 2630 if (olen >= CILEN_VOID) { 2631 p += 2; 2632 printer(arg, "accomp"); 2633 } 2634 break; 2635 case CI_FCSALTERN: 2636 if (olen >= CILEN_CHAR) { 2637 char **cpp; 2638 int needcomma = 0; 2639 2640 p += 2; 2641 GETCHAR(cichar, p); 2642 for (cpp = fcsalt_strings; *cpp != NULL; cpp++) 2643 if (cichar & 1<<(cpp-fcsalt_strings)) { 2644 cichar &= ~(1<<(cpp-fcsalt_strings)); 2645 printer(arg, (needcomma ? ",%s" : "fcs %s"), *cpp); 2646 needcomma = 1; 2647 } 2648 if (cichar != 0 || !needcomma) 2649 printer(arg, (needcomma ? ",0x%x" : "fcs 0x%x"), 2650 cichar); 2651 } 2652 break; 2653 case CI_NUMBERED: 2654 if (olen >= CILEN_SHORT) { 2655 p += 2; 2656 GETCHAR(cichar, p); 2657 printer(arg, "numb win %d", cichar); 2658 GETCHAR(cichar, p); 2659 printer(arg, " addr %d", cichar); 2660 } 2661 break; 2662 case CI_MRRU: 2663 if (olen >= CILEN_SHORT) { 2664 p += 2; 2665 GETSHORT(cishort, p); 2666 printer(arg, "mrru %d", cishort); 2667 } 2668 break; 2669 case CI_SSNHF: 2670 if (olen >= CILEN_VOID) { 2671 p += 2; 2672 printer(arg, "ssnhf"); 2673 } 2674 break; 2675 case CI_EPDISC: 2676 if (olen >= CILEN_CHAR) { 2677 struct epdisc epd; 2678 p += 2; 2679 GETCHAR(epd.class, p); 2680 epd.length = olen - CILEN_CHAR; 2681 if (epd.length > MAX_ENDP_LEN) 2682 epd.length = MAX_ENDP_LEN; 2683 if (epd.length > 0) { 2684 BCOPY(p, epd.value, epd.length); 2685 p += epd.length; 2686 } 2687 printer(arg, "endpoint [%s]", epdisc_to_str(&epd)); 2688 } 2689 break; 2690 case CI_LINKDISC: 2691 if (olen >= CILEN_SHORT) { 2692 p += 2; 2693 GETSHORT(cishort, p); 2694 printer(arg, "linkdisc %d", cishort); 2695 } 2696 break; 2697 case CI_COBS: 2698 if (olen >= CILEN_CHAR) { 2699 p += 2; 2700 GETCHAR(cichar, p); 2701 printer(arg, "cobs 0x%x", cichar); 2702 } 2703 break; 2704 case CI_PFXELISION: 2705 if (olen >= CILEN_CHAR) { 2706 p += 2; 2707 printer(arg, "pfx"); 2708 } 2709 break; 2710 case CI_MPHDRFMT: 2711 if (olen >= CILEN_SHORT) { 2712 p += 2; 2713 printer(arg, "mphdr "); 2714 GETCHAR(cichar, p); 2715 switch (cichar) { 2716 case 2: 2717 printer(arg, "long"); 2718 break; 2719 case 6: 2720 printer(arg, "short"); 2721 break; 2722 default: 2723 printer(arg, "0x%x", cichar); 2724 break; 2725 } 2726 GETCHAR(cichar, p); 2727 printer(arg, " #cl %d", cichar); 2728 } 2729 break; 2730 case CI_I18N: 2731 if (olen >= CILEN_LONG) { 2732 p += 2; 2733 GETLONG(cilong, p); 2734 printer(arg, "i18n charset 0x%x", cilong); 2735 if (olen > CILEN_LONG) { 2736 printer(arg, " lang "); 2737 print_string((char *)p, olen-CILEN_LONG, printer, arg); 2738 p = optend; 2739 } 2740 } 2741 break; 2742 case CI_SDL: 2743 if (olen >= CILEN_VOID) { 2744 p += 2; 2745 printer(arg, "sdl"); 2746 } 2747 break; 2748 case CI_MUXING: 2749 if (olen >= CILEN_VOID) { 2750 p += 2; 2751 printer(arg, "mux"); 2752 } 2753 break; 2754 } 2755 while (p < optend) { 2756 GETCHAR(code, p); 2757 printer(arg, " %.2x", code); 2758 } 2759 printer(arg, ">"); 2760 } 2761 break; 2762 2763 case CODE_TERMACK: 2764 case CODE_TERMREQ: 2765 if (len > 0 && *p >= ' ' && *p < 0x7f) { 2766 printer(arg, " "); 2767 print_string((char *)p, len, printer, arg); 2768 p += len; 2769 len = 0; 2770 } 2771 break; 2772 2773 case CODE_ECHOREQ: 2774 case CODE_ECHOREP: 2775 case CODE_DISCREQ: 2776 if (len >= 4) { 2777 GETLONG(cilong, p); 2778 printer(arg, " magic=0x%x", cilong); 2779 len -= 4; 2780 } 2781 break; 2782 2783 case CODE_IDENT: 2784 if (len >= 4) { 2785 GETLONG(cilong, p); 2786 printer(arg, " magic=0x%x", cilong); 2787 len -= 4; 2788 } else 2789 break; 2790 if (len > 0 && (len > 1 || *p != '\0')) { 2791 printer(arg, " "); 2792 print_string((char *)p, len, printer, arg); 2793 p += len; 2794 len = 0; 2795 } 2796 break; 2797 2798 case CODE_TIMEREMAIN: 2799 if (len >= 4) { 2800 GETLONG(cilong, p); 2801 printer(arg, " magic=0x%x", cilong); 2802 len -= 4; 2803 } else 2804 break; 2805 if (len >= 4) { 2806 GETLONG(cilong, p); 2807 printer(arg, " seconds=%d", cilong); 2808 len -= 4; 2809 } else 2810 break; 2811 if (len > 0 && (len > 1 || *p != '\0')) { 2812 printer(arg, " "); 2813 print_string((char *)p, len, printer, arg); 2814 p += len; 2815 len = 0; 2816 } 2817 break; 2818 } 2819 2820 /* print the rest of the bytes in the packet */ 2821 for (i = 0; i < len && i < 32; ++i) { 2822 GETCHAR(code, p); 2823 printer(arg, " %.2x", code); 2824 } 2825 if (i < len) { 2826 printer(arg, " ..."); 2827 p += len - i; 2828 } 2829 2830 return p - pstart; 2831 } 2832 2833 /* 2834 * Time to shut down the link because there is nothing out there. 2835 */ 2836 2837 static void 2838 LcpLinkFailure (f) 2839 fsm *f; 2840 { 2841 char *close_message; 2842 2843 if (f->state == OPENED) { 2844 if (lcp_echo_badreplies > LCP_ECHO_MAX_BADREPLIES) { 2845 info("Received %d bad echo-replies", lcp_echo_badreplies); 2846 close_message = "Receiving malformed Echo-Replies"; 2847 } else if (lcp_echo_accm_test) { 2848 /* 2849 * If this is an asynchronous line and we've missed all of 2850 * the initial echo requests, then this is probably due to 2851 * a bad ACCM. 2852 */ 2853 notice("Peer not responding to initial Echo-Requests."); 2854 notice("Negotiated asyncmap may be incorrect for this link."); 2855 close_message = "Peer not responding; perhaps bad asyncmap"; 2856 } else { 2857 info("No response to %d echo-requests", lcp_echos_pending); 2858 notice("Serial link appears to be disconnected."); 2859 close_message = "Peer not responding"; 2860 } 2861 2862 lcp_close(f->unit, close_message); 2863 status = EXIT_PEER_DEAD; 2864 } 2865 } 2866 2867 /* 2868 * Timer expired for the LCP echo requests from this process. 2869 */ 2870 2871 static void 2872 LcpEchoCheck (f) 2873 fsm *f; 2874 { 2875 if (f->state != OPENED || lcp_echo_interval == 0) 2876 return; 2877 2878 LcpSendEchoRequest (f); 2879 2880 /* 2881 * Start the timer for the next interval. 2882 */ 2883 if (lcp_echo_timer_running) 2884 warn("assertion lcp_echo_timer_running==0 failed"); 2885 TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval); 2886 lcp_echo_timer_running = 1; 2887 } 2888 2889 /* 2890 * LcpEchoTimeout - Timer expired on the LCP echo 2891 */ 2892 2893 static void 2894 LcpEchoTimeout (arg) 2895 void *arg; 2896 { 2897 if (lcp_echo_timer_running != 0) { 2898 lcp_echo_timer_running = 0; 2899 LcpEchoCheck ((fsm *) arg); 2900 } 2901 } 2902 2903 /* 2904 * LcpEchoReply - LCP has received a reply to the echo 2905 */ 2906 /*ARGSUSED*/ 2907 static int 2908 lcp_received_echo_reply (f, id, inp, len) 2909 fsm *f; 2910 int id; 2911 u_char *inp; 2912 int len; 2913 { 2914 u_int32_t magic; 2915 2916 /* Check the magic number - don't count replies from ourselves. */ 2917 if (len < 4) { 2918 dbglog("lcp: received short Echo-Reply, length %d", len); 2919 return (0); 2920 } 2921 GETLONG(magic, inp); 2922 if (lcp_gotoptions[f->unit].neg_magicnumber && 2923 magic == lcp_gotoptions[f->unit].magicnumber) { 2924 warn("appear to have received our own echo-reply!"); 2925 return (0); 2926 } 2927 2928 /* Reset the number of outstanding echo frames */ 2929 lcp_echos_pending = 0; 2930 2931 if (lcp_echo_accm_test) { 2932 dbglog("lcp: validated asyncmap setting"); 2933 lcp_echo_accm_test = 0; 2934 if (lcp_echo_fails == 0) 2935 lcp_echo_interval = 0; 2936 } 2937 return (1); 2938 } 2939 2940 /* 2941 * LcpSendEchoRequest - Send an echo request frame to the peer 2942 */ 2943 2944 static void 2945 LcpSendEchoRequest (f) 2946 fsm *f; 2947 { 2948 u_int32_t lcp_magic; 2949 u_char pkt[4+256], *pktp; 2950 int i; 2951 2952 /* 2953 * Detect the failure of the peer at this point. If we're not currently 2954 * performing the ACCM test, then we just check for the user's echo-failure 2955 * point. If we are performing the ACCM test, then use ACCM_TEST_FAILS if 2956 * the user hasn't specified a different failure point. 2957 */ 2958 i = lcp_echo_fails; 2959 if (i == 0) 2960 i = ACCM_TEST_FAILS; 2961 if ((!lcp_echo_accm_test && lcp_echo_fails != 0 && 2962 lcp_echos_pending >= lcp_echo_fails) || 2963 (lcp_echo_accm_test && lcp_echos_pending >= i)) { 2964 LcpLinkFailure(f); 2965 lcp_echos_pending = 0; 2966 lcp_echo_badreplies = 0; 2967 } 2968 2969 /* 2970 * Make and send the echo request frame. 2971 */ 2972 if (f->state == OPENED) { 2973 lcp_magic = lcp_gotoptions[f->unit].magicnumber; 2974 pktp = pkt; 2975 PUTLONG(lcp_magic, pktp); 2976 /* Send some test packets so we can fail the link early. */ 2977 if (lcp_echo_accm_test) { 2978 switch (use_accm_test) { 2979 case 1: 2980 /* Only the characters covered by negotiated ACCM */ 2981 for (i = 0; i < 32; i++) 2982 *pktp++ = i; 2983 break; 2984 case 2: 2985 /* All characters */ 2986 for (i = 0; i < 256; i++) 2987 *pktp++ = i; 2988 break; 2989 } 2990 } 2991 fsm_sdata(f, CODE_ECHOREQ, lcp_echo_number++ & 0xFF, pkt, pktp - pkt); 2992 ++lcp_echos_pending; 2993 } 2994 } 2995 2996 /* 2997 * lcp_echo_lowerup - Start the timer for the LCP frame 2998 */ 2999 3000 static void 3001 lcp_echo_lowerup (unit) 3002 int unit; 3003 { 3004 fsm *f = &lcp_fsm[unit]; 3005 3006 /* Clear the parameters for generating echo frames */ 3007 lcp_echos_pending = 0; 3008 lcp_echo_number = 0; 3009 lcp_echo_timer_running = 0; 3010 lcp_echo_accm_test = !sync_serial && use_accm_test; 3011 3012 /* If a timeout interval is specified then start the timer */ 3013 LcpEchoCheck(f); 3014 } 3015 3016 /* 3017 * lcp_echo_lowerdown - Stop the timer for the LCP frame 3018 */ 3019 3020 static void 3021 lcp_echo_lowerdown (unit) 3022 int unit; 3023 { 3024 fsm *f = &lcp_fsm[unit]; 3025 3026 if (lcp_echo_timer_running != 0) { 3027 UNTIMEOUT (LcpEchoTimeout, f); 3028 lcp_echo_timer_running = 0; 3029 } 3030 } 3031 3032 /* 3033 * LcpSendIdentification - Send LCP Identification string to peer. 3034 */ 3035 3036 static void 3037 LcpSendIdentification (f) 3038 fsm *f; 3039 { 3040 u_int32_t lcp_magic; 3041 u_char pkt[4 + sizeof(identstr)], *pktp; 3042 int idlen; 3043 3044 /* 3045 * Make and send the Identification frame. 3046 */ 3047 if (f->state == OPENED) 3048 lcp_magic = lcp_gotoptions[f->unit].magicnumber; 3049 else 3050 lcp_magic = 0; 3051 3052 pktp = pkt; 3053 PUTLONG(lcp_magic, pktp); 3054 idlen = strlen(identstr); 3055 BCOPY(identstr, pktp, idlen); 3056 INCPTR(idlen, pktp); 3057 fsm_sdata(f, CODE_IDENT, ++f->id, pkt, pktp - pkt); 3058 } 3059 3060 /*ARGSUSED*/ 3061 static void 3062 lcp_received_identification (f, id, inp, len) 3063 fsm *f; 3064 int id; 3065 u_char *inp; 3066 int len; 3067 { 3068 u_int32_t magic; 3069 3070 /* Check the magic number - don't count replies from ourselves. */ 3071 if (len < 4) { 3072 dbglog("%s: received short Identification; %d < 4", len); 3073 return; 3074 } 3075 GETLONG(magic, inp); 3076 len -= 4; 3077 if (lcp_gotoptions[f->unit].neg_magicnumber && f->state == OPENED && 3078 magic == lcp_gotoptions[f->unit].magicnumber) { 3079 warn("appear to have received our own Identification!"); 3080 return; 3081 } 3082 if (len > 0 && (len > 1 || *inp != '\0')) 3083 notice("Peer Identification: %0.*v", len, inp); 3084 } 3085 3086 /* 3087 * Send a Time-Remaining LCP packet. We don't include a message. 3088 */ 3089 static void 3090 LcpSendTimeRemaining(f, time_remaining) 3091 fsm *f; 3092 u_int32_t time_remaining; 3093 { 3094 u_int32_t lcp_magic; 3095 u_char pkt[8]; 3096 u_char *pktp; 3097 3098 if (f->state != OPENED) 3099 return; 3100 3101 lcp_magic = lcp_gotoptions[f->unit].magicnumber; 3102 pktp = pkt; 3103 PUTLONG(lcp_magic, pktp); 3104 PUTLONG(time_remaining, pktp); 3105 fsm_sdata(f, CODE_TIMEREMAIN, ++f->id, pkt, pktp - pkt); 3106 } 3107 3108 /*ARGSUSED*/ 3109 static void 3110 lcp_received_timeremain(f, id, inp, len) 3111 fsm *f; 3112 int id; 3113 u_char *inp; 3114 int len; 3115 { 3116 u_int32_t magic; 3117 u_int32_t time_remaining; 3118 3119 /* Check the magic number - don't count replies from ourselves. */ 3120 if (len < 8) { 3121 dbglog("%s: received short Time-Remain; %d < 8", len); 3122 return; 3123 } 3124 GETLONG(magic, inp); 3125 if (lcp_gotoptions[f->unit].neg_magicnumber && f->state == OPENED && 3126 magic == lcp_gotoptions[f->unit].magicnumber) { 3127 warn("appear to have received our own Time-Remain!"); 3128 return; 3129 } 3130 GETLONG(time_remaining, inp); 3131 if (len > 8) { 3132 notice("%d seconds remain: \"%.*s\"", time_remaining, 3133 len-8, inp); 3134 } else { 3135 notice("Time Remaining: %d seconds", time_remaining); 3136 } 3137 } 3138 3139 /* 3140 * lcp_timeremaining - timeout handler which sends LCP Time-Remaining 3141 * packet. 3142 */ 3143 static void 3144 lcp_timeremaining(arg) 3145 void *arg; 3146 { 3147 struct lcp_timer *lt = (struct lcp_timer *)arg; 3148 u_int32_t time_remaining; 3149 int unit; 3150 3151 unit = lt->unit; 3152 time_remaining = lt->tr; 3153 LcpSendTimeRemaining(&lcp_fsm[unit], time_remaining); 3154 free(lt); 3155 } 3156 3157 /* 3158 * lcp_settimeremaining - set a timeout to send an LCP Time-Remaining 3159 * packet. The first argument, connecttime, is the time remaining 3160 * at the time this function is called. The second argument is the 3161 * desired time remaining when the packet should be sent out. 3162 */ 3163 void 3164 lcp_settimeremaining(unit, connecttime, time_remaining) 3165 int unit; 3166 u_int32_t connecttime; 3167 u_int32_t time_remaining; 3168 { 3169 struct lcp_timer *lt; 3170 3171 if (connecttime == time_remaining) { 3172 LcpSendTimeRemaining(&lcp_fsm[unit], time_remaining); 3173 } else { 3174 lt = (struct lcp_timer *)malloc(sizeof (struct lcp_timer)); 3175 lt->unit = unit; 3176 lt->tr = time_remaining; 3177 TIMEOUT(lcp_timeremaining, (void *)lt, connecttime - time_remaining); 3178 } 3179 } 3180