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