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