1 /* $OpenBSD: lcp.c,v 1.6 1998/01/17 20:30:24 millert Exp $ */ 2 3 /* 4 * lcp.c - PPP Link Control Protocol. 5 * 6 * Copyright (c) 1989 Carnegie Mellon University. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms are permitted 10 * provided that the above copyright notice and this paragraph are 11 * duplicated in all such forms and that any documentation, 12 * advertising materials, and other materials related to such 13 * distribution and use acknowledge that the software was developed 14 * by Carnegie Mellon University. The name of the 15 * University may not be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 19 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 */ 21 22 #ifndef lint 23 #if 0 24 static char rcsid[] = "Id: lcp.c,v 1.31 1997/11/27 06:08:44 paulus Exp $"; 25 #else 26 static char rcsid[] = "$OpenBSD: lcp.c,v 1.6 1998/01/17 20:30:24 millert Exp $"; 27 #endif 28 #endif 29 30 /* 31 * TODO: 32 */ 33 34 #include <stdio.h> 35 #include <string.h> 36 #include <syslog.h> 37 #include <assert.h> 38 #include <sys/ioctl.h> 39 #include <sys/types.h> 40 #include <sys/socket.h> 41 #include <sys/time.h> 42 #include <netinet/in.h> 43 44 #include "pppd.h" 45 #include "fsm.h" 46 #include "lcp.h" 47 #include "chap.h" 48 #include "magic.h" 49 50 /* global vars */ 51 fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/ 52 lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */ 53 lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ 54 lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ 55 lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ 56 u_int32_t xmit_accm[NUM_PPP][8]; /* extended transmit ACCM */ 57 58 static u_int32_t lcp_echos_pending = 0; /* Number of outstanding echo msgs */ 59 static u_int32_t lcp_echo_number = 0; /* ID number of next echo frame */ 60 static u_int32_t lcp_echo_timer_running = 0; /* TRUE if a timer is running */ 61 62 static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ 63 64 /* 65 * Callbacks for fsm code. (CI = Configuration Information) 66 */ 67 static void lcp_resetci __P((fsm *)); /* Reset our CI */ 68 static int lcp_cilen __P((fsm *)); /* Return length of our CI */ 69 static void lcp_addci __P((fsm *, u_char *, int *)); /* Add our CI to pkt */ 70 static int lcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ 71 static int lcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */ 72 static int lcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ 73 static int lcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv peer CI */ 74 static void lcp_up __P((fsm *)); /* We're UP */ 75 static void lcp_down __P((fsm *)); /* We're DOWN */ 76 static void lcp_starting __P((fsm *)); /* We need lower layer up */ 77 static void lcp_finished __P((fsm *)); /* We need lower layer down */ 78 static int lcp_extcode __P((fsm *, int, int, u_char *, int)); 79 static void lcp_rprotrej __P((fsm *, u_char *, int)); 80 81 /* 82 * routines to send LCP echos to peer 83 */ 84 85 static void lcp_echo_lowerup __P((int)); 86 static void lcp_echo_lowerdown __P((int)); 87 static void LcpEchoTimeout __P((void *)); 88 static void lcp_received_echo_reply __P((fsm *, int, u_char *, int)); 89 static void LcpSendEchoRequest __P((fsm *)); 90 static void LcpLinkFailure __P((fsm *)); 91 static void LcpEchoCheck __P((fsm *)); 92 93 static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ 94 lcp_resetci, /* Reset our Configuration Information */ 95 lcp_cilen, /* Length of our Configuration Information */ 96 lcp_addci, /* Add our Configuration Information */ 97 lcp_ackci, /* ACK our Configuration Information */ 98 lcp_nakci, /* NAK our Configuration Information */ 99 lcp_rejci, /* Reject our Configuration Information */ 100 lcp_reqci, /* Request peer's Configuration Information */ 101 lcp_up, /* Called when fsm reaches OPENED state */ 102 lcp_down, /* Called when fsm leaves OPENED state */ 103 lcp_starting, /* Called when we want the lower layer up */ 104 lcp_finished, /* Called when we want the lower layer down */ 105 NULL, /* Called when Protocol-Reject received */ 106 NULL, /* Retransmission is necessary */ 107 lcp_extcode, /* Called to handle LCP-specific codes */ 108 "LCP" /* String name of protocol */ 109 }; 110 111 /* 112 * Protocol entry points. 113 * Some of these are called directly. 114 */ 115 116 static void lcp_init __P((int)); 117 static void lcp_input __P((int, u_char *, int)); 118 static void lcp_protrej __P((int)); 119 static int lcp_printpkt __P((u_char *, int, 120 void (*) __P((void *, char *, ...)), void *)); 121 122 struct protent lcp_protent = { 123 PPP_LCP, 124 lcp_init, 125 lcp_input, 126 lcp_protrej, 127 lcp_lowerup, 128 lcp_lowerdown, 129 lcp_open, 130 lcp_close, 131 lcp_printpkt, 132 NULL, 133 1, 134 "LCP", 135 NULL, 136 NULL, 137 NULL 138 }; 139 140 int lcp_loopbackfail = DEFLOOPBACKFAIL; 141 142 /* 143 * Length of each type of configuration option (in octets) 144 */ 145 #define CILEN_VOID 2 146 #define CILEN_CHAR 3 147 #define CILEN_SHORT 4 /* CILEN_VOID + sizeof(short) */ 148 #define CILEN_CHAP 5 /* CILEN_VOID + sizeof(short) + 1 */ 149 #define CILEN_LONG 6 /* CILEN_VOID + sizeof(long) */ 150 #define CILEN_LQR 8 /* CILEN_VOID + sizeof(short) + sizeof(long) */ 151 #define CILEN_CBCP 3 152 153 #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ 154 (x) == CONFNAK ? "NAK" : "REJ") 155 156 157 /* 158 * lcp_init - Initialize LCP. 159 */ 160 static void 161 lcp_init(unit) 162 int unit; 163 { 164 fsm *f = &lcp_fsm[unit]; 165 lcp_options *wo = &lcp_wantoptions[unit]; 166 lcp_options *ao = &lcp_allowoptions[unit]; 167 168 f->unit = unit; 169 f->protocol = PPP_LCP; 170 f->callbacks = &lcp_callbacks; 171 172 fsm_init(f); 173 174 wo->passive = 0; 175 wo->silent = 0; 176 wo->restart = 0; /* Set to 1 in kernels or multi-line 177 implementations */ 178 wo->neg_mru = 1; 179 wo->mru = DEFMRU; 180 wo->neg_asyncmap = 0; 181 wo->asyncmap = 0; 182 wo->neg_chap = 0; /* Set to 1 on server */ 183 wo->neg_upap = 0; /* Set to 1 on server */ 184 wo->chap_mdtype = CHAP_DIGEST_MD5; 185 wo->neg_magicnumber = 1; 186 wo->neg_pcompression = 1; 187 wo->neg_accompression = 1; 188 wo->neg_lqr = 0; /* no LQR implementation yet */ 189 wo->neg_cbcp = 0; 190 191 ao->neg_mru = 1; 192 ao->mru = MAXMRU; 193 ao->neg_asyncmap = 1; 194 ao->asyncmap = 0; 195 ao->neg_chap = 1; 196 ao->chap_mdtype = CHAP_DIGEST_MD5; 197 ao->neg_upap = 1; 198 ao->neg_magicnumber = 1; 199 ao->neg_pcompression = 1; 200 ao->neg_accompression = 1; 201 ao->neg_lqr = 0; /* no LQR implementation yet */ 202 #ifdef CBCP_SUPPORT 203 ao->neg_cbcp = 1; 204 #else 205 ao->neg_cbcp = 0; 206 #endif 207 208 memset(xmit_accm[unit], 0, sizeof(xmit_accm[0])); 209 xmit_accm[unit][3] = 0x60000000; 210 } 211 212 213 /* 214 * lcp_open - LCP is allowed to come up. 215 */ 216 void 217 lcp_open(unit) 218 int unit; 219 { 220 fsm *f = &lcp_fsm[unit]; 221 lcp_options *wo = &lcp_wantoptions[unit]; 222 223 f->flags = 0; 224 if (wo->passive) 225 f->flags |= OPT_PASSIVE; 226 if (wo->silent) 227 f->flags |= OPT_SILENT; 228 fsm_open(f); 229 } 230 231 232 /* 233 * lcp_close - Take LCP down. 234 */ 235 void 236 lcp_close(unit, reason) 237 int unit; 238 char *reason; 239 { 240 fsm *f = &lcp_fsm[unit]; 241 242 if (phase != PHASE_DEAD) 243 phase = PHASE_TERMINATE; 244 if (f->state == STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) { 245 /* 246 * This action is not strictly according to the FSM in RFC1548, 247 * but it does mean that the program terminates if you do a 248 * lcp_close() in passive/silent mode when a connection hasn't 249 * been established. 250 */ 251 f->state = CLOSED; 252 lcp_finished(f); 253 254 } else 255 fsm_close(&lcp_fsm[unit], reason); 256 } 257 258 259 /* 260 * lcp_lowerup - The lower layer is up. 261 */ 262 void 263 lcp_lowerup(unit) 264 int unit; 265 { 266 lcp_options *wo = &lcp_wantoptions[unit]; 267 268 /* 269 * Don't use A/C or protocol compression on transmission, 270 * but accept A/C and protocol compressed packets 271 * if we are going to ask for A/C and protocol compression. 272 */ 273 ppp_set_xaccm(unit, xmit_accm[unit]); 274 ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0); 275 ppp_recv_config(unit, PPP_MRU, 0xffffffff, 276 wo->neg_pcompression, wo->neg_accompression); 277 peer_mru[unit] = PPP_MRU; 278 lcp_allowoptions[unit].asyncmap = xmit_accm[unit][0]; 279 280 fsm_lowerup(&lcp_fsm[unit]); 281 } 282 283 284 /* 285 * lcp_lowerdown - The lower layer is down. 286 */ 287 void 288 lcp_lowerdown(unit) 289 int unit; 290 { 291 fsm_lowerdown(&lcp_fsm[unit]); 292 } 293 294 295 /* 296 * lcp_input - Input LCP packet. 297 */ 298 static void 299 lcp_input(unit, p, len) 300 int unit; 301 u_char *p; 302 int len; 303 { 304 fsm *f = &lcp_fsm[unit]; 305 306 fsm_input(f, p, len); 307 } 308 309 310 /* 311 * lcp_extcode - Handle a LCP-specific code. 312 */ 313 static int 314 lcp_extcode(f, code, id, inp, len) 315 fsm *f; 316 int code, id; 317 u_char *inp; 318 int len; 319 { 320 u_char *magp; 321 322 switch( code ){ 323 case PROTREJ: 324 lcp_rprotrej(f, inp, len); 325 break; 326 327 case ECHOREQ: 328 if (f->state != OPENED) 329 break; 330 LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %d", id)); 331 magp = inp; 332 PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp); 333 fsm_sdata(f, ECHOREP, id, inp, len); 334 break; 335 336 case ECHOREP: 337 lcp_received_echo_reply(f, id, inp, len); 338 break; 339 340 case DISCREQ: 341 break; 342 343 default: 344 return 0; 345 } 346 return 1; 347 } 348 349 350 /* 351 * lcp_rprotrej - Receive an Protocol-Reject. 352 * 353 * Figure out which protocol is rejected and inform it. 354 */ 355 static void 356 lcp_rprotrej(f, inp, len) 357 fsm *f; 358 u_char *inp; 359 int len; 360 { 361 int i; 362 struct protent *protp; 363 u_short prot; 364 365 LCPDEBUG((LOG_INFO, "lcp_rprotrej.")); 366 367 if (len < sizeof (u_short)) { 368 LCPDEBUG((LOG_INFO, 369 "lcp_rprotrej: Rcvd short Protocol-Reject packet!")); 370 return; 371 } 372 373 GETSHORT(prot, inp); 374 375 LCPDEBUG((LOG_INFO, 376 "lcp_rprotrej: Rcvd Protocol-Reject packet for %x!", 377 prot)); 378 379 /* 380 * Protocol-Reject packets received in any state other than the LCP 381 * OPENED state SHOULD be silently discarded. 382 */ 383 if( f->state != OPENED ){ 384 LCPDEBUG((LOG_INFO, "Protocol-Reject discarded: LCP in state %d", 385 f->state)); 386 return; 387 } 388 389 /* 390 * Upcall the proper Protocol-Reject routine. 391 */ 392 for (i = 0; (protp = protocols[i]) != NULL; ++i) 393 if (protp->protocol == prot && protp->enabled_flag) { 394 (*protp->protrej)(f->unit); 395 return; 396 } 397 398 syslog(LOG_WARNING, "Protocol-Reject for unsupported protocol 0x%x", 399 prot); 400 } 401 402 403 /* 404 * lcp_protrej - A Protocol-Reject was received. 405 */ 406 /*ARGSUSED*/ 407 static void 408 lcp_protrej(unit) 409 int unit; 410 { 411 /* 412 * Can't reject LCP! 413 */ 414 LCPDEBUG((LOG_WARNING, 415 "lcp_protrej: Received Protocol-Reject for LCP!")); 416 fsm_protreject(&lcp_fsm[unit]); 417 } 418 419 420 /* 421 * lcp_sprotrej - Send a Protocol-Reject for some protocol. 422 */ 423 void 424 lcp_sprotrej(unit, p, len) 425 int unit; 426 u_char *p; 427 int len; 428 { 429 /* 430 * Send back the protocol and the information field of the 431 * rejected packet. We only get here if LCP is in the OPENED state. 432 */ 433 p += 2; 434 len -= 2; 435 436 fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id, 437 p, len); 438 } 439 440 441 /* 442 * lcp_resetci - Reset our CI. 443 */ 444 static void 445 lcp_resetci(f) 446 fsm *f; 447 { 448 lcp_wantoptions[f->unit].magicnumber = magic(); 449 lcp_wantoptions[f->unit].numloops = 0; 450 lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit]; 451 peer_mru[f->unit] = PPP_MRU; 452 auth_reset(f->unit); 453 } 454 455 456 /* 457 * lcp_cilen - Return length of our CI. 458 */ 459 static int 460 lcp_cilen(f) 461 fsm *f; 462 { 463 lcp_options *go = &lcp_gotoptions[f->unit]; 464 465 #define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0) 466 #define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0) 467 #define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0) 468 #define LENCILONG(neg) ((neg) ? CILEN_LONG : 0) 469 #define LENCILQR(neg) ((neg) ? CILEN_LQR: 0) 470 #define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0) 471 /* 472 * NB: we only ask for one of CHAP and UPAP, even if we will 473 * accept either. 474 */ 475 return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) + 476 LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) + 477 LENCICHAP(go->neg_chap) + 478 LENCISHORT(!go->neg_chap && go->neg_upap) + 479 LENCILQR(go->neg_lqr) + 480 LENCICBCP(go->neg_cbcp) + 481 LENCILONG(go->neg_magicnumber) + 482 LENCIVOID(go->neg_pcompression) + 483 LENCIVOID(go->neg_accompression)); 484 } 485 486 487 /* 488 * lcp_addci - Add our desired CIs to a packet. 489 */ 490 static void 491 lcp_addci(f, ucp, lenp) 492 fsm *f; 493 u_char *ucp; 494 int *lenp; 495 { 496 lcp_options *go = &lcp_gotoptions[f->unit]; 497 u_char *start_ucp = ucp; 498 499 #define ADDCIVOID(opt, neg) \ 500 if (neg) { \ 501 PUTCHAR(opt, ucp); \ 502 PUTCHAR(CILEN_VOID, ucp); \ 503 } 504 #define ADDCISHORT(opt, neg, val) \ 505 if (neg) { \ 506 PUTCHAR(opt, ucp); \ 507 PUTCHAR(CILEN_SHORT, ucp); \ 508 PUTSHORT(val, ucp); \ 509 } 510 #define ADDCICHAP(opt, neg, val, digest) \ 511 if (neg) { \ 512 PUTCHAR(opt, ucp); \ 513 PUTCHAR(CILEN_CHAP, ucp); \ 514 PUTSHORT(val, ucp); \ 515 PUTCHAR(digest, ucp); \ 516 } 517 #define ADDCILONG(opt, neg, val) \ 518 if (neg) { \ 519 PUTCHAR(opt, ucp); \ 520 PUTCHAR(CILEN_LONG, ucp); \ 521 PUTLONG(val, ucp); \ 522 } 523 #define ADDCILQR(opt, neg, val) \ 524 if (neg) { \ 525 PUTCHAR(opt, ucp); \ 526 PUTCHAR(CILEN_LQR, ucp); \ 527 PUTSHORT(PPP_LQR, ucp); \ 528 PUTLONG(val, ucp); \ 529 } 530 #define ADDCICHAR(opt, neg, val) \ 531 if (neg) { \ 532 PUTCHAR(opt, ucp); \ 533 PUTCHAR(CILEN_CHAR, ucp); \ 534 PUTCHAR(val, ucp); \ 535 } 536 537 ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); 538 ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, 539 go->asyncmap); 540 ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); 541 ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); 542 ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); 543 ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); 544 ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); 545 ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); 546 ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); 547 548 if (ucp - start_ucp != *lenp) { 549 /* this should never happen, because peer_mtu should be 1500 */ 550 syslog(LOG_ERR, "Bug in lcp_addci: wrong length"); 551 } 552 } 553 554 555 /* 556 * lcp_ackci - Ack our CIs. 557 * This should not modify any state if the Ack is bad. 558 * 559 * Returns: 560 * 0 - Ack was bad. 561 * 1 - Ack was good. 562 */ 563 static int 564 lcp_ackci(f, p, len) 565 fsm *f; 566 u_char *p; 567 int len; 568 { 569 lcp_options *go = &lcp_gotoptions[f->unit]; 570 u_char cilen, citype, cichar; 571 u_short cishort; 572 u_int32_t cilong; 573 574 /* 575 * CIs must be in exactly the same order that we sent. 576 * Check packet length and CI length at each step. 577 * If we find any deviations, then this packet is bad. 578 */ 579 #define ACKCIVOID(opt, neg) \ 580 if (neg) { \ 581 if ((len -= CILEN_VOID) < 0) \ 582 goto bad; \ 583 GETCHAR(citype, p); \ 584 GETCHAR(cilen, p); \ 585 if (cilen != CILEN_VOID || \ 586 citype != opt) \ 587 goto bad; \ 588 } 589 #define ACKCISHORT(opt, neg, val) \ 590 if (neg) { \ 591 if ((len -= CILEN_SHORT) < 0) \ 592 goto bad; \ 593 GETCHAR(citype, p); \ 594 GETCHAR(cilen, p); \ 595 if (cilen != CILEN_SHORT || \ 596 citype != opt) \ 597 goto bad; \ 598 GETSHORT(cishort, p); \ 599 if (cishort != val) \ 600 goto bad; \ 601 } 602 #define ACKCICHAR(opt, neg, val) \ 603 if (neg) { \ 604 if ((len -= CILEN_CHAR) < 0) \ 605 goto bad; \ 606 GETCHAR(citype, p); \ 607 GETCHAR(cilen, p); \ 608 if (cilen != CILEN_CHAR || \ 609 citype != opt) \ 610 goto bad; \ 611 GETCHAR(cichar, p); \ 612 if (cichar != val) \ 613 goto bad; \ 614 } 615 #define ACKCICHAP(opt, neg, val, digest) \ 616 if (neg) { \ 617 if ((len -= CILEN_CHAP) < 0) \ 618 goto bad; \ 619 GETCHAR(citype, p); \ 620 GETCHAR(cilen, p); \ 621 if (cilen != CILEN_CHAP || \ 622 citype != opt) \ 623 goto bad; \ 624 GETSHORT(cishort, p); \ 625 if (cishort != val) \ 626 goto bad; \ 627 GETCHAR(cichar, p); \ 628 if (cichar != digest) \ 629 goto bad; \ 630 } 631 #define ACKCILONG(opt, neg, val) \ 632 if (neg) { \ 633 if ((len -= CILEN_LONG) < 0) \ 634 goto bad; \ 635 GETCHAR(citype, p); \ 636 GETCHAR(cilen, p); \ 637 if (cilen != CILEN_LONG || \ 638 citype != opt) \ 639 goto bad; \ 640 GETLONG(cilong, p); \ 641 if (cilong != val) \ 642 goto bad; \ 643 } 644 #define ACKCILQR(opt, neg, val) \ 645 if (neg) { \ 646 if ((len -= CILEN_LQR) < 0) \ 647 goto bad; \ 648 GETCHAR(citype, p); \ 649 GETCHAR(cilen, p); \ 650 if (cilen != CILEN_LQR || \ 651 citype != opt) \ 652 goto bad; \ 653 GETSHORT(cishort, p); \ 654 if (cishort != PPP_LQR) \ 655 goto bad; \ 656 GETLONG(cilong, p); \ 657 if (cilong != val) \ 658 goto bad; \ 659 } 660 661 ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); 662 ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, 663 go->asyncmap); 664 ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); 665 ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); 666 ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); 667 ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); 668 ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); 669 ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); 670 ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); 671 672 /* 673 * If there are any remaining CIs, then this packet is bad. 674 */ 675 if (len != 0) 676 goto bad; 677 return (1); 678 bad: 679 LCPDEBUG((LOG_WARNING, "lcp_acki: received bad Ack!")); 680 return (0); 681 } 682 683 684 /* 685 * lcp_nakci - Peer has sent a NAK for some of our CIs. 686 * This should not modify any state if the Nak is bad 687 * or if LCP is in the OPENED state. 688 * 689 * Returns: 690 * 0 - Nak was bad. 691 * 1 - Nak was good. 692 */ 693 static int 694 lcp_nakci(f, p, len) 695 fsm *f; 696 u_char *p; 697 int len; 698 { 699 lcp_options *go = &lcp_gotoptions[f->unit]; 700 lcp_options *wo = &lcp_wantoptions[f->unit]; 701 u_char citype, cichar, *next; 702 u_short cishort; 703 u_int32_t cilong; 704 lcp_options no; /* options we've seen Naks for */ 705 lcp_options try; /* options to request next time */ 706 int looped_back = 0; 707 int cilen; 708 709 BZERO(&no, sizeof(no)); 710 try = *go; 711 712 /* 713 * Any Nak'd CIs must be in exactly the same order that we sent. 714 * Check packet length and CI length at each step. 715 * If we find any deviations, then this packet is bad. 716 */ 717 #define NAKCIVOID(opt, neg, code) \ 718 if (go->neg && \ 719 len >= CILEN_VOID && \ 720 p[1] == CILEN_VOID && \ 721 p[0] == opt) { \ 722 len -= CILEN_VOID; \ 723 INCPTR(CILEN_VOID, p); \ 724 no.neg = 1; \ 725 code \ 726 } 727 #define NAKCICHAP(opt, neg, code) \ 728 if (go->neg && \ 729 len >= CILEN_CHAP && \ 730 p[1] == CILEN_CHAP && \ 731 p[0] == opt) { \ 732 len -= CILEN_CHAP; \ 733 INCPTR(2, p); \ 734 GETSHORT(cishort, p); \ 735 GETCHAR(cichar, p); \ 736 no.neg = 1; \ 737 code \ 738 } 739 #define NAKCICHAR(opt, neg, code) \ 740 if (go->neg && \ 741 len >= CILEN_CHAR && \ 742 p[1] == CILEN_CHAR && \ 743 p[0] == opt) { \ 744 len -= CILEN_CHAR; \ 745 INCPTR(2, p); \ 746 GETCHAR(cichar, p); \ 747 no.neg = 1; \ 748 code \ 749 } 750 #define NAKCISHORT(opt, neg, code) \ 751 if (go->neg && \ 752 len >= CILEN_SHORT && \ 753 p[1] == CILEN_SHORT && \ 754 p[0] == opt) { \ 755 len -= CILEN_SHORT; \ 756 INCPTR(2, p); \ 757 GETSHORT(cishort, p); \ 758 no.neg = 1; \ 759 code \ 760 } 761 #define NAKCILONG(opt, neg, code) \ 762 if (go->neg && \ 763 len >= CILEN_LONG && \ 764 p[1] == CILEN_LONG && \ 765 p[0] == opt) { \ 766 len -= CILEN_LONG; \ 767 INCPTR(2, p); \ 768 GETLONG(cilong, p); \ 769 no.neg = 1; \ 770 code \ 771 } 772 #define NAKCILQR(opt, neg, code) \ 773 if (go->neg && \ 774 len >= CILEN_LQR && \ 775 p[1] == CILEN_LQR && \ 776 p[0] == opt) { \ 777 len -= CILEN_LQR; \ 778 INCPTR(2, p); \ 779 GETSHORT(cishort, p); \ 780 GETLONG(cilong, p); \ 781 no.neg = 1; \ 782 code \ 783 } 784 785 /* 786 * We don't care if they want to send us smaller packets than 787 * we want. Therefore, accept any MRU less than what we asked for, 788 * but then ignore the new value when setting the MRU in the kernel. 789 * If they send us a bigger MRU than what we asked, accept it, up to 790 * the limit of the default MRU we'd get if we didn't negotiate. 791 */ 792 if (go->neg_mru && go->mru != DEFMRU) { 793 NAKCISHORT(CI_MRU, neg_mru, 794 if (cishort <= wo->mru || cishort <= DEFMRU) 795 try.mru = cishort; 796 ); 797 } 798 799 /* 800 * Add any characters they want to our (receive-side) asyncmap. 801 */ 802 if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) { 803 NAKCILONG(CI_ASYNCMAP, neg_asyncmap, 804 try.asyncmap = go->asyncmap | cilong; 805 ); 806 } 807 808 /* 809 * If they've nak'd our authentication-protocol, check whether 810 * they are proposing a different protocol, or a different 811 * hash algorithm for CHAP. 812 */ 813 if ((go->neg_chap || go->neg_upap) 814 && len >= CILEN_SHORT 815 && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) { 816 cilen = p[1]; 817 len -= cilen; 818 no.neg_chap = go->neg_chap; 819 no.neg_upap = go->neg_upap; 820 INCPTR(2, p); 821 GETSHORT(cishort, p); 822 if (cishort == PPP_PAP && cilen == CILEN_SHORT) { 823 /* 824 * If we were asking for CHAP, they obviously don't want to do it. 825 * If we weren't asking for CHAP, then we were asking for PAP, 826 * in which case this Nak is bad. 827 */ 828 if (!go->neg_chap) 829 goto bad; 830 try.neg_chap = 0; 831 832 } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { 833 GETCHAR(cichar, p); 834 if (go->neg_chap) { 835 /* 836 * We were asking for CHAP/MD5; they must want a different 837 * algorithm. If they can't do MD5, we'll have to stop 838 * asking for CHAP. 839 */ 840 if (cichar != go->chap_mdtype) 841 try.neg_chap = 0; 842 } else { 843 /* 844 * Stop asking for PAP if we were asking for it. 845 */ 846 try.neg_upap = 0; 847 } 848 849 } else { 850 /* 851 * We don't recognize what they're suggesting. 852 * Stop asking for what we were asking for. 853 */ 854 if (go->neg_chap) 855 try.neg_chap = 0; 856 else 857 try.neg_upap = 0; 858 p += cilen - CILEN_SHORT; 859 } 860 } 861 862 /* 863 * If they can't cope with our link quality protocol, we'll have 864 * to stop asking for LQR. We haven't got any other protocol. 865 * If they Nak the reporting period, take their value XXX ? 866 */ 867 NAKCILQR(CI_QUALITY, neg_lqr, 868 if (cishort != PPP_LQR) 869 try.neg_lqr = 0; 870 else 871 try.lqr_period = cilong; 872 ); 873 874 /* 875 * Only implementing CBCP...not the rest of the callback options 876 */ 877 NAKCICHAR(CI_CALLBACK, neg_cbcp, 878 try.neg_cbcp = 0; 879 ); 880 881 /* 882 * Check for a looped-back line. 883 */ 884 NAKCILONG(CI_MAGICNUMBER, neg_magicnumber, 885 try.magicnumber = magic(); 886 looped_back = 1; 887 ); 888 889 /* 890 * Peer shouldn't send Nak for protocol compression or 891 * address/control compression requests; they should send 892 * a Reject instead. If they send a Nak, treat it as a Reject. 893 */ 894 NAKCIVOID(CI_PCOMPRESSION, neg_pcompression, 895 try.neg_pcompression = 0; 896 ); 897 NAKCIVOID(CI_ACCOMPRESSION, neg_accompression, 898 try.neg_accompression = 0; 899 ); 900 901 /* 902 * There may be remaining CIs, if the peer is requesting negotiation 903 * on an option that we didn't include in our request packet. 904 * If we see an option that we requested, or one we've already seen 905 * in this packet, then this packet is bad. 906 * If we wanted to respond by starting to negotiate on the requested 907 * option(s), we could, but we don't, because except for the 908 * authentication type and quality protocol, if we are not negotiating 909 * an option, it is because we were told not to. 910 * For the authentication type, the Nak from the peer means 911 * `let me authenticate myself with you' which is a bit pointless. 912 * For the quality protocol, the Nak means `ask me to send you quality 913 * reports', but if we didn't ask for them, we don't want them. 914 * An option we don't recognize represents the peer asking to 915 * negotiate some option we don't support, so ignore it. 916 */ 917 while (len > CILEN_VOID) { 918 GETCHAR(citype, p); 919 GETCHAR(cilen, p); 920 if (cilen < CILEN_VOID || (len -= cilen) < 0) 921 goto bad; 922 next = p + cilen - 2; 923 924 switch (citype) { 925 case CI_MRU: 926 if ((go->neg_mru && go->mru != DEFMRU) 927 || no.neg_mru || cilen != CILEN_SHORT) 928 goto bad; 929 GETSHORT(cishort, p); 930 if (cishort < DEFMRU) 931 try.mru = cishort; 932 break; 933 case CI_ASYNCMAP: 934 if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) 935 || no.neg_asyncmap || cilen != CILEN_LONG) 936 goto bad; 937 break; 938 case CI_AUTHTYPE: 939 if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap) 940 goto bad; 941 break; 942 case CI_MAGICNUMBER: 943 if (go->neg_magicnumber || no.neg_magicnumber || 944 cilen != CILEN_LONG) 945 goto bad; 946 break; 947 case CI_PCOMPRESSION: 948 if (go->neg_pcompression || no.neg_pcompression 949 || cilen != CILEN_VOID) 950 goto bad; 951 break; 952 case CI_ACCOMPRESSION: 953 if (go->neg_accompression || no.neg_accompression 954 || cilen != CILEN_VOID) 955 goto bad; 956 break; 957 case CI_QUALITY: 958 if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR) 959 goto bad; 960 break; 961 } 962 p = next; 963 } 964 965 /* If there is still anything left, this packet is bad. */ 966 if (len != 0) 967 goto bad; 968 969 /* 970 * OK, the Nak is good. Now we can update state. 971 */ 972 if (f->state != OPENED) { 973 if (looped_back) { 974 if (++try.numloops >= lcp_loopbackfail) { 975 syslog(LOG_NOTICE, "Serial line is looped back."); 976 lcp_close(f->unit, "Loopback detected"); 977 } 978 } else 979 try.numloops = 0; 980 *go = try; 981 } 982 983 return 1; 984 985 bad: 986 LCPDEBUG((LOG_WARNING, "lcp_nakci: received bad Nak!")); 987 return 0; 988 } 989 990 991 /* 992 * lcp_rejci - Peer has Rejected some of our CIs. 993 * This should not modify any state if the Reject is bad 994 * or if LCP is in the OPENED state. 995 * 996 * Returns: 997 * 0 - Reject was bad. 998 * 1 - Reject was good. 999 */ 1000 static int 1001 lcp_rejci(f, p, len) 1002 fsm *f; 1003 u_char *p; 1004 int len; 1005 { 1006 lcp_options *go = &lcp_gotoptions[f->unit]; 1007 u_char cichar; 1008 u_short cishort; 1009 u_int32_t cilong; 1010 lcp_options try; /* options to request next time */ 1011 1012 try = *go; 1013 1014 /* 1015 * Any Rejected CIs must be in exactly the same order that we sent. 1016 * Check packet length and CI length at each step. 1017 * If we find any deviations, then this packet is bad. 1018 */ 1019 #define REJCIVOID(opt, neg) \ 1020 if (go->neg && \ 1021 len >= CILEN_VOID && \ 1022 p[1] == CILEN_VOID && \ 1023 p[0] == opt) { \ 1024 len -= CILEN_VOID; \ 1025 INCPTR(CILEN_VOID, p); \ 1026 try.neg = 0; \ 1027 LCPDEBUG((LOG_INFO, "lcp_rejci rejected void opt %d", opt)); \ 1028 } 1029 #define REJCISHORT(opt, neg, val) \ 1030 if (go->neg && \ 1031 len >= CILEN_SHORT && \ 1032 p[1] == CILEN_SHORT && \ 1033 p[0] == opt) { \ 1034 len -= CILEN_SHORT; \ 1035 INCPTR(2, p); \ 1036 GETSHORT(cishort, p); \ 1037 /* Check rejected value. */ \ 1038 if (cishort != val) \ 1039 goto bad; \ 1040 try.neg = 0; \ 1041 LCPDEBUG((LOG_INFO,"lcp_rejci rejected short opt %d", opt)); \ 1042 } 1043 #define REJCICHAP(opt, neg, val, digest) \ 1044 if (go->neg && \ 1045 len >= CILEN_CHAP && \ 1046 p[1] == CILEN_CHAP && \ 1047 p[0] == opt) { \ 1048 len -= CILEN_CHAP; \ 1049 INCPTR(2, p); \ 1050 GETSHORT(cishort, p); \ 1051 GETCHAR(cichar, p); \ 1052 /* Check rejected value. */ \ 1053 if (cishort != val || cichar != digest) \ 1054 goto bad; \ 1055 try.neg = 0; \ 1056 try.neg_upap = 0; \ 1057 LCPDEBUG((LOG_INFO,"lcp_rejci rejected chap opt %d", opt)); \ 1058 } 1059 #define REJCILONG(opt, neg, val) \ 1060 if (go->neg && \ 1061 len >= CILEN_LONG && \ 1062 p[1] == CILEN_LONG && \ 1063 p[0] == opt) { \ 1064 len -= CILEN_LONG; \ 1065 INCPTR(2, p); \ 1066 GETLONG(cilong, p); \ 1067 /* Check rejected value. */ \ 1068 if (cilong != val) \ 1069 goto bad; \ 1070 try.neg = 0; \ 1071 LCPDEBUG((LOG_INFO,"lcp_rejci rejected long opt %d", opt)); \ 1072 } 1073 #define REJCILQR(opt, neg, val) \ 1074 if (go->neg && \ 1075 len >= CILEN_LQR && \ 1076 p[1] == CILEN_LQR && \ 1077 p[0] == opt) { \ 1078 len -= CILEN_LQR; \ 1079 INCPTR(2, p); \ 1080 GETSHORT(cishort, p); \ 1081 GETLONG(cilong, p); \ 1082 /* Check rejected value. */ \ 1083 if (cishort != PPP_LQR || cilong != val) \ 1084 goto bad; \ 1085 try.neg = 0; \ 1086 LCPDEBUG((LOG_INFO,"lcp_rejci rejected LQR opt %d", opt)); \ 1087 } 1088 #define REJCICBCP(opt, neg, val) \ 1089 if (go->neg && \ 1090 len >= CILEN_CBCP && \ 1091 p[1] == CILEN_CBCP && \ 1092 p[0] == opt) { \ 1093 len -= CILEN_CBCP; \ 1094 INCPTR(2, p); \ 1095 GETCHAR(cichar, p); \ 1096 /* Check rejected value. */ \ 1097 if (cichar != val) \ 1098 goto bad; \ 1099 try.neg = 0; \ 1100 LCPDEBUG((LOG_INFO,"lcp_rejci rejected Callback opt %d", opt)); \ 1101 } 1102 1103 REJCISHORT(CI_MRU, neg_mru, go->mru); 1104 REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); 1105 REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype); 1106 if (!go->neg_chap) { 1107 REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); 1108 } 1109 REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period); 1110 REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT); 1111 REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); 1112 REJCIVOID(CI_PCOMPRESSION, neg_pcompression); 1113 REJCIVOID(CI_ACCOMPRESSION, neg_accompression); 1114 1115 /* 1116 * If there are any remaining CIs, then this packet is bad. 1117 */ 1118 if (len != 0) 1119 goto bad; 1120 /* 1121 * Now we can update state. 1122 */ 1123 if (f->state != OPENED) 1124 *go = try; 1125 return 1; 1126 1127 bad: 1128 LCPDEBUG((LOG_WARNING, "lcp_rejci: received bad Reject!")); 1129 return 0; 1130 } 1131 1132 1133 /* 1134 * lcp_reqci - Check the peer's requested CIs and send appropriate response. 1135 * 1136 * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified 1137 * appropriately. If reject_if_disagree is non-zero, doesn't return 1138 * CONFNAK; returns CONFREJ if it can't return CONFACK. 1139 */ 1140 static int 1141 lcp_reqci(f, inp, lenp, reject_if_disagree) 1142 fsm *f; 1143 u_char *inp; /* Requested CIs */ 1144 int *lenp; /* Length of requested CIs */ 1145 int reject_if_disagree; 1146 { 1147 lcp_options *go = &lcp_gotoptions[f->unit]; 1148 lcp_options *ho = &lcp_hisoptions[f->unit]; 1149 lcp_options *ao = &lcp_allowoptions[f->unit]; 1150 u_char *cip, *next; /* Pointer to current and next CIs */ 1151 int cilen, citype, cichar; /* Parsed len, type, char value */ 1152 u_short cishort; /* Parsed short value */ 1153 u_int32_t cilong; /* Parse long value */ 1154 int rc = CONFACK; /* Final packet return code */ 1155 int orc; /* Individual option return code */ 1156 u_char *p; /* Pointer to next char to parse */ 1157 u_char *rejp; /* Pointer to next char in reject frame */ 1158 u_char *nakp; /* Pointer to next char in Nak frame */ 1159 int l = *lenp; /* Length left */ 1160 1161 /* 1162 * Reset all his options. 1163 */ 1164 BZERO(ho, sizeof(*ho)); 1165 1166 /* 1167 * Process all his options. 1168 */ 1169 next = inp; 1170 nakp = nak_buffer; 1171 rejp = inp; 1172 while (l) { 1173 orc = CONFACK; /* Assume success */ 1174 cip = p = next; /* Remember begining of CI */ 1175 if (l < 2 || /* Not enough data for CI header or */ 1176 p[1] < 2 || /* CI length too small or */ 1177 p[1] > l) { /* CI length too big? */ 1178 LCPDEBUG((LOG_WARNING, "lcp_reqci: bad CI length!")); 1179 orc = CONFREJ; /* Reject bad CI */ 1180 cilen = l; /* Reject till end of packet */ 1181 l = 0; /* Don't loop again */ 1182 citype = 0; 1183 goto endswitch; 1184 } 1185 GETCHAR(citype, p); /* Parse CI type */ 1186 GETCHAR(cilen, p); /* Parse CI length */ 1187 l -= cilen; /* Adjust remaining length */ 1188 next += cilen; /* Step to next CI */ 1189 1190 switch (citype) { /* Check CI type */ 1191 case CI_MRU: 1192 LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd MRU")); 1193 if (!ao->neg_mru || /* Allow option? */ 1194 cilen != CILEN_SHORT) { /* Check CI length */ 1195 orc = CONFREJ; /* Reject CI */ 1196 break; 1197 } 1198 GETSHORT(cishort, p); /* Parse MRU */ 1199 LCPDEBUG((LOG_INFO, "(%d)", cishort)); 1200 1201 /* 1202 * He must be able to receive at least our minimum. 1203 * No need to check a maximum. If he sends a large number, 1204 * we'll just ignore it. 1205 */ 1206 if (cishort < MINMRU) { 1207 orc = CONFNAK; /* Nak CI */ 1208 PUTCHAR(CI_MRU, nakp); 1209 PUTCHAR(CILEN_SHORT, nakp); 1210 PUTSHORT(MINMRU, nakp); /* Give him a hint */ 1211 break; 1212 } 1213 ho->neg_mru = 1; /* Remember he sent MRU */ 1214 ho->mru = cishort; /* And remember value */ 1215 break; 1216 1217 case CI_ASYNCMAP: 1218 LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd ASYNCMAP")); 1219 if (!ao->neg_asyncmap || 1220 cilen != CILEN_LONG) { 1221 orc = CONFREJ; 1222 break; 1223 } 1224 GETLONG(cilong, p); 1225 LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong)); 1226 1227 /* 1228 * Asyncmap must have set at least the bits 1229 * which are set in lcp_allowoptions[unit].asyncmap. 1230 */ 1231 if ((ao->asyncmap & ~cilong) != 0) { 1232 orc = CONFNAK; 1233 PUTCHAR(CI_ASYNCMAP, nakp); 1234 PUTCHAR(CILEN_LONG, nakp); 1235 PUTLONG(ao->asyncmap | cilong, nakp); 1236 break; 1237 } 1238 ho->neg_asyncmap = 1; 1239 ho->asyncmap = cilong; 1240 break; 1241 1242 case CI_AUTHTYPE: 1243 LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd AUTHTYPE")); 1244 if (cilen < CILEN_SHORT || 1245 !(ao->neg_upap || ao->neg_chap)) { 1246 /* 1247 * Reject the option if we're not willing to authenticate. 1248 */ 1249 orc = CONFREJ; 1250 break; 1251 } 1252 GETSHORT(cishort, p); 1253 LCPDEBUG((LOG_INFO, "(%x)", cishort)); 1254 1255 /* 1256 * Authtype must be UPAP or CHAP. 1257 * 1258 * Note: if both ao->neg_upap and ao->neg_chap are set, 1259 * and the peer sends a Configure-Request with two 1260 * authenticate-protocol requests, one for CHAP and one 1261 * for UPAP, then we will reject the second request. 1262 * Whether we end up doing CHAP or UPAP depends then on 1263 * the ordering of the CIs in the peer's Configure-Request. 1264 */ 1265 1266 if (cishort == PPP_PAP) { 1267 if (ho->neg_chap || /* we've already accepted CHAP */ 1268 cilen != CILEN_SHORT) { 1269 LCPDEBUG((LOG_WARNING, 1270 "lcp_reqci: rcvd AUTHTYPE PAP, rejecting...")); 1271 orc = CONFREJ; 1272 break; 1273 } 1274 if (!ao->neg_upap) { /* we don't want to do PAP */ 1275 orc = CONFNAK; /* NAK it and suggest CHAP */ 1276 PUTCHAR(CI_AUTHTYPE, nakp); 1277 PUTCHAR(CILEN_CHAP, nakp); 1278 PUTSHORT(PPP_CHAP, nakp); 1279 PUTCHAR(ao->chap_mdtype, nakp); 1280 break; 1281 } 1282 ho->neg_upap = 1; 1283 break; 1284 } 1285 if (cishort == PPP_CHAP) { 1286 if (ho->neg_upap || /* we've already accepted PAP */ 1287 cilen != CILEN_CHAP) { 1288 LCPDEBUG((LOG_INFO, 1289 "lcp_reqci: rcvd AUTHTYPE CHAP, rejecting...")); 1290 orc = CONFREJ; 1291 break; 1292 } 1293 if (!ao->neg_chap) { /* we don't want to do CHAP */ 1294 orc = CONFNAK; /* NAK it and suggest PAP */ 1295 PUTCHAR(CI_AUTHTYPE, nakp); 1296 PUTCHAR(CILEN_SHORT, nakp); 1297 PUTSHORT(PPP_PAP, nakp); 1298 break; 1299 } 1300 GETCHAR(cichar, p); /* get digest type*/ 1301 if (cichar != CHAP_DIGEST_MD5 1302 #ifdef CHAPMS 1303 && cichar != CHAP_MICROSOFT 1304 #endif 1305 ) { 1306 orc = CONFNAK; 1307 PUTCHAR(CI_AUTHTYPE, nakp); 1308 PUTCHAR(CILEN_CHAP, nakp); 1309 PUTSHORT(PPP_CHAP, nakp); 1310 PUTCHAR(ao->chap_mdtype, nakp); 1311 break; 1312 } 1313 ho->chap_mdtype = cichar; /* save md type */ 1314 ho->neg_chap = 1; 1315 break; 1316 } 1317 1318 /* 1319 * We don't recognize the protocol they're asking for. 1320 * Nak it with something we're willing to do. 1321 * (At this point we know ao->neg_upap || ao->neg_chap.) 1322 */ 1323 orc = CONFNAK; 1324 PUTCHAR(CI_AUTHTYPE, nakp); 1325 if (ao->neg_chap) { 1326 PUTCHAR(CILEN_CHAP, nakp); 1327 PUTSHORT(PPP_CHAP, nakp); 1328 PUTCHAR(ao->chap_mdtype, nakp); 1329 } else { 1330 PUTCHAR(CILEN_SHORT, nakp); 1331 PUTSHORT(PPP_PAP, nakp); 1332 } 1333 break; 1334 1335 case CI_QUALITY: 1336 LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd QUALITY")); 1337 if (!ao->neg_lqr || 1338 cilen != CILEN_LQR) { 1339 orc = CONFREJ; 1340 break; 1341 } 1342 1343 GETSHORT(cishort, p); 1344 GETLONG(cilong, p); 1345 LCPDEBUG((LOG_INFO, "(%x %x)", cishort, (unsigned int) cilong)); 1346 1347 /* 1348 * Check the protocol and the reporting period. 1349 * XXX When should we Nak this, and what with? 1350 */ 1351 if (cishort != PPP_LQR) { 1352 orc = CONFNAK; 1353 PUTCHAR(CI_QUALITY, nakp); 1354 PUTCHAR(CILEN_LQR, nakp); 1355 PUTSHORT(PPP_LQR, nakp); 1356 PUTLONG(ao->lqr_period, nakp); 1357 break; 1358 } 1359 break; 1360 1361 case CI_MAGICNUMBER: 1362 LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd MAGICNUMBER")); 1363 if (!(ao->neg_magicnumber || go->neg_magicnumber) || 1364 cilen != CILEN_LONG) { 1365 orc = CONFREJ; 1366 break; 1367 } 1368 GETLONG(cilong, p); 1369 LCPDEBUG((LOG_INFO, "(%x)", (unsigned int) cilong)); 1370 1371 /* 1372 * He must have a different magic number. 1373 */ 1374 if (go->neg_magicnumber && 1375 cilong == go->magicnumber) { 1376 cilong = magic(); /* Don't put magic() inside macro! */ 1377 orc = CONFNAK; 1378 PUTCHAR(CI_MAGICNUMBER, nakp); 1379 PUTCHAR(CILEN_LONG, nakp); 1380 PUTLONG(cilong, nakp); 1381 break; 1382 } 1383 ho->neg_magicnumber = 1; 1384 ho->magicnumber = cilong; 1385 break; 1386 1387 1388 case CI_PCOMPRESSION: 1389 LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd PCOMPRESSION")); 1390 if (!ao->neg_pcompression || 1391 cilen != CILEN_VOID) { 1392 orc = CONFREJ; 1393 break; 1394 } 1395 ho->neg_pcompression = 1; 1396 break; 1397 1398 case CI_ACCOMPRESSION: 1399 LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd ACCOMPRESSION")); 1400 if (!ao->neg_accompression || 1401 cilen != CILEN_VOID) { 1402 orc = CONFREJ; 1403 break; 1404 } 1405 ho->neg_accompression = 1; 1406 break; 1407 1408 default: 1409 LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd unknown option %d", 1410 citype)); 1411 orc = CONFREJ; 1412 break; 1413 } 1414 1415 endswitch: 1416 LCPDEBUG((LOG_INFO, " (%s)", CODENAME(orc))); 1417 if (orc == CONFACK && /* Good CI */ 1418 rc != CONFACK) /* but prior CI wasnt? */ 1419 continue; /* Don't send this one */ 1420 1421 if (orc == CONFNAK) { /* Nak this CI? */ 1422 if (reject_if_disagree /* Getting fed up with sending NAKs? */ 1423 && citype != CI_MAGICNUMBER) { 1424 orc = CONFREJ; /* Get tough if so */ 1425 } else { 1426 if (rc == CONFREJ) /* Rejecting prior CI? */ 1427 continue; /* Don't send this one */ 1428 rc = CONFNAK; 1429 } 1430 } 1431 if (orc == CONFREJ) { /* Reject this CI */ 1432 rc = CONFREJ; 1433 if (cip != rejp) /* Need to move rejected CI? */ 1434 BCOPY(cip, rejp, cilen); /* Move it */ 1435 INCPTR(cilen, rejp); /* Update output pointer */ 1436 } 1437 } 1438 1439 /* 1440 * If we wanted to send additional NAKs (for unsent CIs), the 1441 * code would go here. The extra NAKs would go at *nakp. 1442 * At present there are no cases where we want to ask the 1443 * peer to negotiate an option. 1444 */ 1445 1446 switch (rc) { 1447 case CONFACK: 1448 *lenp = next - inp; 1449 break; 1450 case CONFNAK: 1451 /* 1452 * Copy the Nak'd options from the nak_buffer to the caller's buffer. 1453 */ 1454 *lenp = nakp - nak_buffer; 1455 BCOPY(nak_buffer, inp, *lenp); 1456 break; 1457 case CONFREJ: 1458 *lenp = rejp - inp; 1459 break; 1460 } 1461 1462 LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.", CODENAME(rc))); 1463 return (rc); /* Return final code */ 1464 } 1465 1466 1467 /* 1468 * lcp_up - LCP has come UP. 1469 */ 1470 static void 1471 lcp_up(f) 1472 fsm *f; 1473 { 1474 lcp_options *wo = &lcp_wantoptions[f->unit]; 1475 lcp_options *ho = &lcp_hisoptions[f->unit]; 1476 lcp_options *go = &lcp_gotoptions[f->unit]; 1477 lcp_options *ao = &lcp_allowoptions[f->unit]; 1478 1479 if (!go->neg_magicnumber) 1480 go->magicnumber = 0; 1481 if (!ho->neg_magicnumber) 1482 ho->magicnumber = 0; 1483 1484 /* 1485 * Set our MTU to the smaller of the MTU we wanted and 1486 * the MRU our peer wanted. If we negotiated an MRU, 1487 * set our MRU to the larger of value we wanted and 1488 * the value we got in the negotiation. 1489 */ 1490 ppp_send_config(f->unit, MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)), 1491 (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), 1492 ho->neg_pcompression, ho->neg_accompression); 1493 ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU), 1494 (go->neg_asyncmap? go->asyncmap: 0xffffffff), 1495 go->neg_pcompression, go->neg_accompression); 1496 1497 if (ho->neg_mru) 1498 peer_mru[f->unit] = ho->mru; 1499 1500 lcp_echo_lowerup(f->unit); /* Enable echo messages */ 1501 1502 link_established(f->unit); 1503 } 1504 1505 1506 /* 1507 * lcp_down - LCP has gone DOWN. 1508 * 1509 * Alert other protocols. 1510 */ 1511 static void 1512 lcp_down(f) 1513 fsm *f; 1514 { 1515 lcp_options *go = &lcp_gotoptions[f->unit]; 1516 1517 lcp_echo_lowerdown(f->unit); 1518 1519 link_down(f->unit); 1520 1521 ppp_send_config(f->unit, PPP_MRU, 0xffffffff, 0, 0); 1522 ppp_recv_config(f->unit, PPP_MRU, 1523 (go->neg_asyncmap? go->asyncmap: 0xffffffff), 1524 go->neg_pcompression, go->neg_accompression); 1525 peer_mru[f->unit] = PPP_MRU; 1526 } 1527 1528 1529 /* 1530 * lcp_starting - LCP needs the lower layer up. 1531 */ 1532 static void 1533 lcp_starting(f) 1534 fsm *f; 1535 { 1536 link_required(f->unit); 1537 } 1538 1539 1540 /* 1541 * lcp_finished - LCP has finished with the lower layer. 1542 */ 1543 static void 1544 lcp_finished(f) 1545 fsm *f; 1546 { 1547 link_terminated(f->unit); 1548 } 1549 1550 1551 /* 1552 * lcp_printpkt - print the contents of an LCP packet. 1553 */ 1554 static char *lcp_codenames[] = { 1555 "ConfReq", "ConfAck", "ConfNak", "ConfRej", 1556 "TermReq", "TermAck", "CodeRej", "ProtRej", 1557 "EchoReq", "EchoRep", "DiscReq" 1558 }; 1559 1560 static int 1561 lcp_printpkt(p, plen, printer, arg) 1562 u_char *p; 1563 int plen; 1564 void (*printer) __P((void *, char *, ...)); 1565 void *arg; 1566 { 1567 int code, id, len, olen; 1568 u_char *pstart, *optend; 1569 u_short cishort; 1570 u_int32_t cilong; 1571 1572 if (plen < HEADERLEN) 1573 return 0; 1574 pstart = p; 1575 GETCHAR(code, p); 1576 GETCHAR(id, p); 1577 GETSHORT(len, p); 1578 if (len < HEADERLEN || len > plen) 1579 return 0; 1580 1581 if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *)) 1582 printer(arg, " %s", lcp_codenames[code-1]); 1583 else 1584 printer(arg, " code=0x%x", code); 1585 printer(arg, " id=0x%x", id); 1586 len -= HEADERLEN; 1587 switch (code) { 1588 case CONFREQ: 1589 case CONFACK: 1590 case CONFNAK: 1591 case CONFREJ: 1592 /* print option list */ 1593 while (len >= 2) { 1594 GETCHAR(code, p); 1595 GETCHAR(olen, p); 1596 p -= 2; 1597 if (olen < 2 || olen > len) { 1598 break; 1599 } 1600 printer(arg, " <"); 1601 len -= olen; 1602 optend = p + olen; 1603 switch (code) { 1604 case CI_MRU: 1605 if (olen == CILEN_SHORT) { 1606 p += 2; 1607 GETSHORT(cishort, p); 1608 printer(arg, "mru %d", cishort); 1609 } 1610 break; 1611 case CI_ASYNCMAP: 1612 if (olen == CILEN_LONG) { 1613 p += 2; 1614 GETLONG(cilong, p); 1615 printer(arg, "asyncmap 0x%x", cilong); 1616 } 1617 break; 1618 case CI_AUTHTYPE: 1619 if (olen >= CILEN_SHORT) { 1620 p += 2; 1621 printer(arg, "auth "); 1622 GETSHORT(cishort, p); 1623 switch (cishort) { 1624 case PPP_PAP: 1625 printer(arg, "pap"); 1626 break; 1627 case PPP_CHAP: 1628 printer(arg, "chap"); 1629 break; 1630 default: 1631 printer(arg, "0x%x", cishort); 1632 } 1633 } 1634 break; 1635 case CI_QUALITY: 1636 if (olen >= CILEN_SHORT) { 1637 p += 2; 1638 printer(arg, "quality "); 1639 GETSHORT(cishort, p); 1640 switch (cishort) { 1641 case PPP_LQR: 1642 printer(arg, "lqr"); 1643 break; 1644 default: 1645 printer(arg, "0x%x", cishort); 1646 } 1647 } 1648 break; 1649 case CI_CALLBACK: 1650 if (olen >= CILEN_CHAR) { 1651 p += 2; 1652 printer(arg, "callback "); 1653 GETSHORT(cishort, p); 1654 switch (cishort) { 1655 case CBCP_OPT: 1656 printer(arg, "CBCP"); 1657 break; 1658 default: 1659 printer(arg, "0x%x", cishort); 1660 } 1661 } 1662 break; 1663 case CI_MAGICNUMBER: 1664 if (olen == CILEN_LONG) { 1665 p += 2; 1666 GETLONG(cilong, p); 1667 printer(arg, "magic 0x%x", cilong); 1668 } 1669 break; 1670 case CI_PCOMPRESSION: 1671 if (olen == CILEN_VOID) { 1672 p += 2; 1673 printer(arg, "pcomp"); 1674 } 1675 break; 1676 case CI_ACCOMPRESSION: 1677 if (olen == CILEN_VOID) { 1678 p += 2; 1679 printer(arg, "accomp"); 1680 } 1681 break; 1682 } 1683 while (p < optend) { 1684 GETCHAR(code, p); 1685 printer(arg, " %.2x", code); 1686 } 1687 printer(arg, ">"); 1688 } 1689 break; 1690 1691 case TERMACK: 1692 case TERMREQ: 1693 if (len > 0 && *p >= ' ' && *p < 0x7f) { 1694 printer(arg, " "); 1695 print_string(p, len, printer, arg); 1696 p += len; 1697 len = 0; 1698 } 1699 break; 1700 1701 case ECHOREQ: 1702 case ECHOREP: 1703 case DISCREQ: 1704 if (len >= 4) { 1705 GETLONG(cilong, p); 1706 printer(arg, " magic=0x%x", cilong); 1707 p += 4; 1708 len -= 4; 1709 } 1710 break; 1711 } 1712 1713 /* print the rest of the bytes in the packet */ 1714 for (; len > 0; --len) { 1715 GETCHAR(code, p); 1716 printer(arg, " %.2x", code); 1717 } 1718 1719 return p - pstart; 1720 } 1721 1722 /* 1723 * Time to shut down the link because there is nothing out there. 1724 */ 1725 1726 static 1727 void LcpLinkFailure (f) 1728 fsm *f; 1729 { 1730 if (f->state == OPENED) { 1731 syslog(LOG_INFO, "No response to %d echo-requests", lcp_echos_pending); 1732 syslog(LOG_NOTICE, "Serial link appears to be disconnected."); 1733 lcp_close(f->unit, "Peer not responding"); 1734 } 1735 } 1736 1737 /* 1738 * Timer expired for the LCP echo requests from this process. 1739 */ 1740 1741 static void 1742 LcpEchoCheck (f) 1743 fsm *f; 1744 { 1745 LcpSendEchoRequest (f); 1746 1747 /* 1748 * Start the timer for the next interval. 1749 */ 1750 assert (lcp_echo_timer_running==0); 1751 TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval); 1752 lcp_echo_timer_running = 1; 1753 } 1754 1755 /* 1756 * LcpEchoTimeout - Timer expired on the LCP echo 1757 */ 1758 1759 static void 1760 LcpEchoTimeout (arg) 1761 void *arg; 1762 { 1763 if (lcp_echo_timer_running != 0) { 1764 lcp_echo_timer_running = 0; 1765 LcpEchoCheck ((fsm *) arg); 1766 } 1767 } 1768 1769 /* 1770 * LcpEchoReply - LCP has received a reply to the echo 1771 */ 1772 1773 static void 1774 lcp_received_echo_reply (f, id, inp, len) 1775 fsm *f; 1776 int id; u_char *inp; int len; 1777 { 1778 u_int32_t magic; 1779 1780 /* Check the magic number - don't count replies from ourselves. */ 1781 if (len < 4) { 1782 syslog(LOG_DEBUG, "lcp: received short Echo-Reply, length %d", len); 1783 return; 1784 } 1785 GETLONG(magic, inp); 1786 if (lcp_gotoptions[f->unit].neg_magicnumber 1787 && magic == lcp_gotoptions[f->unit].magicnumber) { 1788 syslog(LOG_WARNING, "appear to have received our own echo-reply!"); 1789 return; 1790 } 1791 1792 /* Reset the number of outstanding echo frames */ 1793 lcp_echos_pending = 0; 1794 } 1795 1796 /* 1797 * LcpSendEchoRequest - Send an echo request frame to the peer 1798 */ 1799 1800 static void 1801 LcpSendEchoRequest (f) 1802 fsm *f; 1803 { 1804 u_int32_t lcp_magic; 1805 u_char pkt[4], *pktp; 1806 1807 /* 1808 * Detect the failure of the peer at this point. 1809 */ 1810 if (lcp_echo_fails != 0) { 1811 if (lcp_echos_pending >= lcp_echo_fails) { 1812 LcpLinkFailure(f); 1813 lcp_echos_pending = 0; 1814 } 1815 } 1816 1817 /* 1818 * Make and send the echo request frame. 1819 */ 1820 if (f->state == OPENED) { 1821 lcp_magic = lcp_gotoptions[f->unit].magicnumber; 1822 pktp = pkt; 1823 PUTLONG(lcp_magic, pktp); 1824 fsm_sdata(f, ECHOREQ, lcp_echo_number++ & 0xFF, pkt, pktp - pkt); 1825 ++lcp_echos_pending; 1826 } 1827 } 1828 1829 /* 1830 * lcp_echo_lowerup - Start the timer for the LCP frame 1831 */ 1832 1833 static void 1834 lcp_echo_lowerup (unit) 1835 int unit; 1836 { 1837 fsm *f = &lcp_fsm[unit]; 1838 1839 /* Clear the parameters for generating echo frames */ 1840 lcp_echos_pending = 0; 1841 lcp_echo_number = 0; 1842 lcp_echo_timer_running = 0; 1843 1844 /* If a timeout interval is specified then start the timer */ 1845 if (lcp_echo_interval != 0) 1846 LcpEchoCheck (f); 1847 } 1848 1849 /* 1850 * lcp_echo_lowerdown - Stop the timer for the LCP frame 1851 */ 1852 1853 static void 1854 lcp_echo_lowerdown (unit) 1855 int unit; 1856 { 1857 fsm *f = &lcp_fsm[unit]; 1858 1859 if (lcp_echo_timer_running != 0) { 1860 UNTIMEOUT (LcpEchoTimeout, f); 1861 lcp_echo_timer_running = 0; 1862 } 1863 } 1864