1 /* $OpenBSD: ipcp.c,v 1.15 2015/12/14 03:25:59 mmcc Exp $ */ 2 3 /* 4 * ipcp.c - PPP IP Control Protocol. 5 * 6 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. The name "Carnegie Mellon University" must not be used to 21 * endorse or promote products derived from this software without 22 * prior written permission. For permission or any legal 23 * details, please contact 24 * Office of Technology Transfer 25 * Carnegie Mellon University 26 * 5000 Forbes Avenue 27 * Pittsburgh, PA 15213-3890 28 * (412) 268-4387, fax: (412) 268-7395 29 * tech-transfer@andrew.cmu.edu 30 * 31 * 4. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by Computing Services 34 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 35 * 36 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 37 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 38 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 39 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 40 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 41 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 42 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 43 */ 44 45 /* 46 * TODO: 47 */ 48 49 #include <sys/types.h> 50 #include <sys/socket.h> 51 #include <netinet/in.h> 52 #include <stdio.h> 53 #include <stdlib.h> 54 #include <string.h> 55 #include <syslog.h> 56 #include <netdb.h> 57 58 #include "pppd.h" 59 #include "fsm.h" 60 #include "ipcp.h" 61 #include "pathnames.h" 62 63 /* global vars */ 64 ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ 65 ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ 66 ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ 67 ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ 68 69 /* local vars */ 70 static int cis_received[NUM_PPP]; /* # Conf-Reqs received */ 71 static int default_route_set[NUM_PPP]; /* Have set up a default route */ 72 static int proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */ 73 74 /* 75 * Callbacks for fsm code. (CI = Configuration Information) 76 */ 77 static void ipcp_resetci(fsm *); /* Reset our CI */ 78 static int ipcp_cilen(fsm *); /* Return length of our CI */ 79 static void ipcp_addci(fsm *, u_char *, int *); /* Add our CI */ 80 static int ipcp_ackci(fsm *, u_char *, int); /* Peer ack'd our CI */ 81 static int ipcp_nakci(fsm *, u_char *, int); /* Peer nak'd our CI */ 82 static int ipcp_rejci(fsm *, u_char *, int); /* Peer rej'd our CI */ 83 static int ipcp_reqci(fsm *, u_char *, int *, int); /* Rcv CI */ 84 static void ipcp_up(fsm *); /* We're UP */ 85 static void ipcp_down(fsm *); /* We're DOWN */ 86 static void ipcp_script(fsm *, char *); /* Run an up/down script */ 87 static void ipcp_finished(fsm *); /* Don't need lower layer */ 88 89 fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */ 90 91 static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ 92 ipcp_resetci, /* Reset our Configuration Information */ 93 ipcp_cilen, /* Length of our Configuration Information */ 94 ipcp_addci, /* Add our Configuration Information */ 95 ipcp_ackci, /* ACK our Configuration Information */ 96 ipcp_nakci, /* NAK our Configuration Information */ 97 ipcp_rejci, /* Reject our Configuration Information */ 98 ipcp_reqci, /* Request peer's Configuration Information */ 99 ipcp_up, /* Called when fsm reaches OPENED state */ 100 ipcp_down, /* Called when fsm leaves OPENED state */ 101 NULL, /* Called when we want the lower layer up */ 102 ipcp_finished, /* Called when we want the lower layer down */ 103 NULL, /* Called when Protocol-Reject received */ 104 NULL, /* Retransmission is necessary */ 105 NULL, /* Called to handle protocol-specific codes */ 106 "IPCP" /* String name of protocol */ 107 }; 108 109 /* 110 * Protocol entry points from main code. 111 */ 112 static void ipcp_init(int); 113 static void ipcp_open(int); 114 static void ipcp_close(int, char *); 115 static void ipcp_lowerup(int); 116 static void ipcp_lowerdown(int); 117 static void ipcp_input(int, u_char *, int); 118 static void ipcp_protrej(int); 119 static int ipcp_printpkt(u_char *, int, void (*)(void *, char *, ...), void *); 120 static void ip_check_options(void); 121 static int ip_demand_conf(int); 122 static int ip_active_pkt(u_char *, int); 123 124 struct protent ipcp_protent = { 125 PPP_IPCP, 126 ipcp_init, 127 ipcp_input, 128 ipcp_protrej, 129 ipcp_lowerup, 130 ipcp_lowerdown, 131 ipcp_open, 132 ipcp_close, 133 ipcp_printpkt, 134 NULL, 135 1, 136 "IPCP", 137 ip_check_options, 138 ip_demand_conf, 139 ip_active_pkt 140 }; 141 142 static void ipcp_clear_addrs(int); 143 144 /* 145 * Lengths of configuration options. 146 */ 147 #define CILEN_VOID 2 148 #define CILEN_COMPRESS 4 /* min length for compression protocol opt. */ 149 #define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */ 150 #define CILEN_ADDR 6 /* new-style single address option */ 151 #define CILEN_ADDRS 10 /* old-style dual address option */ 152 153 154 #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ 155 (x) == CONFNAK ? "NAK" : "REJ") 156 157 158 /* 159 * Make a string representation of a network IP address. 160 */ 161 char * 162 ip_ntoa(ipaddr) 163 u_int32_t ipaddr; 164 { 165 static char b[64]; 166 167 ipaddr = ntohl(ipaddr); 168 169 snprintf(b, sizeof b, "%d.%d.%d.%d", 170 (u_char)(ipaddr >> 24), 171 (u_char)(ipaddr >> 16), 172 (u_char)(ipaddr >> 8), 173 (u_char)(ipaddr)); 174 return b; 175 } 176 177 178 /* 179 * ipcp_init - Initialize IPCP. 180 */ 181 static void 182 ipcp_init(unit) 183 int unit; 184 { 185 fsm *f = &ipcp_fsm[unit]; 186 ipcp_options *wo = &ipcp_wantoptions[unit]; 187 ipcp_options *ao = &ipcp_allowoptions[unit]; 188 189 f->unit = unit; 190 f->protocol = PPP_IPCP; 191 f->callbacks = &ipcp_callbacks; 192 fsm_init(&ipcp_fsm[unit]); 193 194 memset(wo, 0, sizeof(*wo)); 195 memset(ao, 0, sizeof(*ao)); 196 197 wo->neg_addr = 1; 198 wo->neg_vj = 1; 199 wo->vj_protocol = IPCP_VJ_COMP; 200 wo->maxslotindex = MAX_STATES - 1; /* really max index */ 201 wo->cflag = 1; 202 203 /* max slots and slot-id compression are currently hardwired in */ 204 /* ppp_if.c to 16 and 1, this needs to be changed (among other */ 205 /* things) gmc */ 206 207 ao->neg_addr = 1; 208 ao->neg_vj = 1; 209 ao->maxslotindex = MAX_STATES - 1; 210 ao->cflag = 1; 211 212 /* 213 * XXX These control whether the user may use the proxyarp 214 * and defaultroute options. 215 */ 216 ao->proxy_arp = 1; 217 ao->default_route = 1; 218 } 219 220 221 /* 222 * ipcp_open - IPCP is allowed to come up. 223 */ 224 static void 225 ipcp_open(unit) 226 int unit; 227 { 228 fsm_open(&ipcp_fsm[unit]); 229 } 230 231 232 /* 233 * ipcp_close - Take IPCP down. 234 */ 235 static void 236 ipcp_close(unit, reason) 237 int unit; 238 char *reason; 239 { 240 fsm_close(&ipcp_fsm[unit], reason); 241 } 242 243 244 /* 245 * ipcp_lowerup - The lower layer is up. 246 */ 247 static void 248 ipcp_lowerup(unit) 249 int unit; 250 { 251 fsm_lowerup(&ipcp_fsm[unit]); 252 } 253 254 255 /* 256 * ipcp_lowerdown - The lower layer is down. 257 */ 258 static void 259 ipcp_lowerdown(unit) 260 int unit; 261 { 262 fsm_lowerdown(&ipcp_fsm[unit]); 263 } 264 265 266 /* 267 * ipcp_input - Input IPCP packet. 268 */ 269 static void 270 ipcp_input(unit, p, len) 271 int unit; 272 u_char *p; 273 int len; 274 { 275 fsm_input(&ipcp_fsm[unit], p, len); 276 } 277 278 279 /* 280 * ipcp_protrej - A Protocol-Reject was received for IPCP. 281 * 282 * Pretend the lower layer went down, so we shut up. 283 */ 284 static void 285 ipcp_protrej(unit) 286 int unit; 287 { 288 fsm_lowerdown(&ipcp_fsm[unit]); 289 } 290 291 292 /* 293 * ipcp_resetci - Reset our CI. 294 */ 295 static void 296 ipcp_resetci(f) 297 fsm *f; 298 { 299 ipcp_options *wo = &ipcp_wantoptions[f->unit]; 300 301 wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr; 302 if (wo->ouraddr == 0) 303 wo->accept_local = 1; 304 if (wo->hisaddr == 0) 305 wo->accept_remote = 1; 306 ipcp_gotoptions[f->unit] = *wo; 307 cis_received[f->unit] = 0; 308 } 309 310 311 /* 312 * ipcp_cilen - Return length of our CI. 313 */ 314 static int 315 ipcp_cilen(f) 316 fsm *f; 317 { 318 ipcp_options *go = &ipcp_gotoptions[f->unit]; 319 ipcp_options *wo = &ipcp_wantoptions[f->unit]; 320 ipcp_options *ho = &ipcp_hisoptions[f->unit]; 321 322 #define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) 323 #define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0) 324 325 /* 326 * First see if we want to change our options to the old 327 * forms because we have received old forms from the peer. 328 */ 329 if (wo->neg_addr && !go->neg_addr && !go->old_addrs) { 330 /* use the old style of address negotiation */ 331 go->neg_addr = 1; 332 go->old_addrs = 1; 333 } 334 if (wo->neg_vj && !go->neg_vj && !go->old_vj) { 335 /* try an older style of VJ negotiation */ 336 if (cis_received[f->unit] == 0) { 337 /* keep trying the new style until we see some CI from the peer */ 338 go->neg_vj = 1; 339 } else { 340 /* use the old style only if the peer did */ 341 if (ho->neg_vj && ho->old_vj) { 342 go->neg_vj = 1; 343 go->old_vj = 1; 344 go->vj_protocol = ho->vj_protocol; 345 } 346 } 347 } 348 349 return (LENCIADDR(go->neg_addr, go->old_addrs) + 350 LENCIVJ(go->neg_vj, go->old_vj)); 351 } 352 353 354 /* 355 * ipcp_addci - Add our desired CIs to a packet. 356 */ 357 static void 358 ipcp_addci(f, ucp, lenp) 359 fsm *f; 360 u_char *ucp; 361 int *lenp; 362 { 363 ipcp_options *go = &ipcp_gotoptions[f->unit]; 364 int len = *lenp; 365 366 #define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \ 367 if (neg) { \ 368 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ 369 if (len >= vjlen) { \ 370 PUTCHAR(opt, ucp); \ 371 PUTCHAR(vjlen, ucp); \ 372 PUTSHORT(val, ucp); \ 373 if (!old) { \ 374 PUTCHAR(maxslotindex, ucp); \ 375 PUTCHAR(cflag, ucp); \ 376 } \ 377 len -= vjlen; \ 378 } else \ 379 neg = 0; \ 380 } 381 382 #define ADDCIADDR(opt, neg, old, val1, val2) \ 383 if (neg) { \ 384 int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ 385 if (len >= addrlen) { \ 386 u_int32_t l; \ 387 PUTCHAR(opt, ucp); \ 388 PUTCHAR(addrlen, ucp); \ 389 l = ntohl(val1); \ 390 PUTLONG(l, ucp); \ 391 if (old) { \ 392 l = ntohl(val2); \ 393 PUTLONG(l, ucp); \ 394 } \ 395 len -= addrlen; \ 396 } else \ 397 neg = 0; \ 398 } 399 400 ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr, 401 go->old_addrs, go->ouraddr, go->hisaddr); 402 403 ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, 404 go->maxslotindex, go->cflag); 405 406 *lenp -= len; 407 } 408 409 410 /* 411 * ipcp_ackci - Ack our CIs. 412 * 413 * Returns: 414 * 0 - Ack was bad. 415 * 1 - Ack was good. 416 */ 417 static int 418 ipcp_ackci(f, p, len) 419 fsm *f; 420 u_char *p; 421 int len; 422 { 423 ipcp_options *go = &ipcp_gotoptions[f->unit]; 424 u_short cilen, citype, cishort; 425 u_int32_t cilong; 426 u_char cimaxslotindex, cicflag; 427 428 /* 429 * CIs must be in exactly the same order that we sent... 430 * Check packet length and CI length at each step. 431 * If we find any deviations, then this packet is bad. 432 */ 433 434 #define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \ 435 if (neg) { \ 436 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ 437 if ((len -= vjlen) < 0) \ 438 goto bad; \ 439 GETCHAR(citype, p); \ 440 GETCHAR(cilen, p); \ 441 if (cilen != vjlen || \ 442 citype != opt) \ 443 goto bad; \ 444 GETSHORT(cishort, p); \ 445 if (cishort != val) \ 446 goto bad; \ 447 if (!old) { \ 448 GETCHAR(cimaxslotindex, p); \ 449 if (cimaxslotindex != maxslotindex) \ 450 goto bad; \ 451 GETCHAR(cicflag, p); \ 452 if (cicflag != cflag) \ 453 goto bad; \ 454 } \ 455 } 456 457 #define ACKCIADDR(opt, neg, old, val1, val2) \ 458 if (neg) { \ 459 int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ 460 u_int32_t l; \ 461 if ((len -= addrlen) < 0) \ 462 goto bad; \ 463 GETCHAR(citype, p); \ 464 GETCHAR(cilen, p); \ 465 if (cilen != addrlen || \ 466 citype != opt) \ 467 goto bad; \ 468 GETLONG(l, p); \ 469 cilong = htonl(l); \ 470 if (val1 != cilong) \ 471 goto bad; \ 472 if (old) { \ 473 GETLONG(l, p); \ 474 cilong = htonl(l); \ 475 if (val2 != cilong) \ 476 goto bad; \ 477 } \ 478 } 479 480 ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr, 481 go->old_addrs, go->ouraddr, go->hisaddr); 482 483 ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, 484 go->maxslotindex, go->cflag); 485 486 /* 487 * If there are any remaining CIs, then this packet is bad. 488 */ 489 if (len != 0) 490 goto bad; 491 return (1); 492 493 bad: 494 IPCPDEBUG((LOG_INFO, "ipcp_ackci: received bad Ack!")); 495 return (0); 496 } 497 498 /* 499 * ipcp_nakci - Peer has sent a NAK for some of our CIs. 500 * This should not modify any state if the Nak is bad 501 * or if IPCP is in the OPENED state. 502 * 503 * Returns: 504 * 0 - Nak was bad. 505 * 1 - Nak was good. 506 */ 507 static int 508 ipcp_nakci(f, p, len) 509 fsm *f; 510 u_char *p; 511 int len; 512 { 513 ipcp_options *go = &ipcp_gotoptions[f->unit]; 514 u_char cimaxslotindex, cicflag; 515 u_char citype, cilen, *next; 516 u_short cishort; 517 u_int32_t ciaddr1, ciaddr2, l; 518 ipcp_options no; /* options we've seen Naks for */ 519 ipcp_options try; /* options to request next time */ 520 521 BZERO(&no, sizeof(no)); 522 try = *go; 523 524 /* 525 * Any Nak'd CIs must be in exactly the same order that we sent. 526 * Check packet length and CI length at each step. 527 * If we find any deviations, then this packet is bad. 528 */ 529 #define NAKCIADDR(opt, neg, old, code) \ 530 if (go->neg && \ 531 len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \ 532 p[1] == cilen && \ 533 p[0] == opt) { \ 534 len -= cilen; \ 535 INCPTR(2, p); \ 536 GETLONG(l, p); \ 537 ciaddr1 = htonl(l); \ 538 if (old) { \ 539 GETLONG(l, p); \ 540 ciaddr2 = htonl(l); \ 541 no.old_addrs = 1; \ 542 } else \ 543 ciaddr2 = 0; \ 544 no.neg = 1; \ 545 code \ 546 } 547 548 #define NAKCIVJ(opt, neg, code) \ 549 if (go->neg && \ 550 ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \ 551 len >= cilen && \ 552 p[0] == opt) { \ 553 len -= cilen; \ 554 INCPTR(2, p); \ 555 GETSHORT(cishort, p); \ 556 no.neg = 1; \ 557 code \ 558 } 559 560 /* 561 * Accept the peer's idea of {our,his} address, if different 562 * from our idea, only if the accept_{local,remote} flag is set. 563 */ 564 NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs, 565 if (go->accept_local && ciaddr1) { /* Do we know our address? */ 566 try.ouraddr = ciaddr1; 567 IPCPDEBUG((LOG_INFO, "local IP address %s", 568 ip_ntoa(ciaddr1))); 569 } 570 if (go->accept_remote && ciaddr2) { /* Does he know his? */ 571 try.hisaddr = ciaddr2; 572 IPCPDEBUG((LOG_INFO, "remote IP address %s", 573 ip_ntoa(ciaddr2))); 574 } 575 ); 576 577 /* 578 * Accept the peer's value of maxslotindex provided that it 579 * is less than what we asked for. Turn off slot-ID compression 580 * if the peer wants. Send old-style compress-type option if 581 * the peer wants. 582 */ 583 NAKCIVJ(CI_COMPRESSTYPE, neg_vj, 584 if (cilen == CILEN_VJ) { 585 GETCHAR(cimaxslotindex, p); 586 GETCHAR(cicflag, p); 587 if (cishort == IPCP_VJ_COMP) { 588 try.old_vj = 0; 589 if (cimaxslotindex < go->maxslotindex) 590 try.maxslotindex = cimaxslotindex; 591 if (!cicflag) 592 try.cflag = 0; 593 } else { 594 try.neg_vj = 0; 595 } 596 } else { 597 if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) { 598 try.old_vj = 1; 599 try.vj_protocol = cishort; 600 } else { 601 try.neg_vj = 0; 602 } 603 } 604 ); 605 606 /* 607 * There may be remaining CIs, if the peer is requesting negotiation 608 * on an option that we didn't include in our request packet. 609 * If they want to negotiate about IP addresses, we comply. 610 * If they want us to ask for compression, we refuse. 611 */ 612 while (len > CILEN_VOID) { 613 GETCHAR(citype, p); 614 GETCHAR(cilen, p); 615 if( (len -= cilen) < 0 ) 616 goto bad; 617 next = p + cilen - 2; 618 619 switch (citype) { 620 case CI_COMPRESSTYPE: 621 if (go->neg_vj || no.neg_vj || 622 (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) 623 goto bad; 624 no.neg_vj = 1; 625 break; 626 case CI_ADDRS: 627 if ((go->neg_addr && go->old_addrs) || no.old_addrs 628 || cilen != CILEN_ADDRS) 629 goto bad; 630 try.neg_addr = 1; 631 try.old_addrs = 1; 632 GETLONG(l, p); 633 ciaddr1 = htonl(l); 634 if (ciaddr1 && go->accept_local) 635 try.ouraddr = ciaddr1; 636 GETLONG(l, p); 637 ciaddr2 = htonl(l); 638 if (ciaddr2 && go->accept_remote) 639 try.hisaddr = ciaddr2; 640 no.old_addrs = 1; 641 break; 642 case CI_ADDR: 643 if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) 644 goto bad; 645 try.old_addrs = 0; 646 GETLONG(l, p); 647 ciaddr1 = htonl(l); 648 if (ciaddr1 && go->accept_local) 649 try.ouraddr = ciaddr1; 650 if (try.ouraddr != 0) 651 try.neg_addr = 1; 652 no.neg_addr = 1; 653 break; 654 } 655 p = next; 656 } 657 658 /* If there is still anything left, this packet is bad. */ 659 if (len != 0) 660 goto bad; 661 662 /* 663 * OK, the Nak is good. Now we can update state. 664 */ 665 if (f->state != OPENED) 666 *go = try; 667 668 return 1; 669 670 bad: 671 IPCPDEBUG((LOG_INFO, "ipcp_nakci: received bad Nak!")); 672 return 0; 673 } 674 675 676 /* 677 * ipcp_rejci - Reject some of our CIs. 678 */ 679 static int 680 ipcp_rejci(f, p, len) 681 fsm *f; 682 u_char *p; 683 int len; 684 { 685 ipcp_options *go = &ipcp_gotoptions[f->unit]; 686 u_char cimaxslotindex, ciflag, cilen; 687 u_short cishort; 688 u_int32_t cilong; 689 ipcp_options try; /* options to request next time */ 690 691 try = *go; 692 /* 693 * Any Rejected CIs must be in exactly the same order that we sent. 694 * Check packet length and CI length at each step. 695 * If we find any deviations, then this packet is bad. 696 */ 697 #define REJCIADDR(opt, neg, old, val1, val2) \ 698 if (go->neg && \ 699 len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \ 700 p[1] == cilen && \ 701 p[0] == opt) { \ 702 u_int32_t l; \ 703 len -= cilen; \ 704 INCPTR(2, p); \ 705 GETLONG(l, p); \ 706 cilong = htonl(l); \ 707 /* Check rejected value. */ \ 708 if (cilong != val1) \ 709 goto bad; \ 710 if (old) { \ 711 GETLONG(l, p); \ 712 cilong = htonl(l); \ 713 /* Check rejected value. */ \ 714 if (cilong != val2) \ 715 goto bad; \ 716 } \ 717 try.neg = 0; \ 718 } 719 720 #define REJCIVJ(opt, neg, val, old, maxslot, cflag) \ 721 if (go->neg && \ 722 p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \ 723 len >= p[1] && \ 724 p[0] == opt) { \ 725 len -= p[1]; \ 726 INCPTR(2, p); \ 727 GETSHORT(cishort, p); \ 728 /* Check rejected value. */ \ 729 if (cishort != val) \ 730 goto bad; \ 731 if (!old) { \ 732 GETCHAR(cimaxslotindex, p); \ 733 if (cimaxslotindex != maxslot) \ 734 goto bad; \ 735 GETCHAR(ciflag, p); \ 736 if (ciflag != cflag) \ 737 goto bad; \ 738 } \ 739 try.neg = 0; \ 740 } 741 742 REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, 743 go->old_addrs, go->ouraddr, go->hisaddr); 744 745 REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, 746 go->maxslotindex, go->cflag); 747 748 /* 749 * If there are any remaining CIs, then this packet is bad. 750 */ 751 if (len != 0) 752 goto bad; 753 /* 754 * Now we can update state. 755 */ 756 if (f->state != OPENED) 757 *go = try; 758 return 1; 759 760 bad: 761 IPCPDEBUG((LOG_INFO, "ipcp_rejci: received bad Reject!")); 762 return 0; 763 } 764 765 766 /* 767 * ipcp_reqci - Check the peer's requested CIs and send appropriate response. 768 * 769 * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified 770 * appropriately. If reject_if_disagree is non-zero, doesn't return 771 * CONFNAK; returns CONFREJ if it can't return CONFACK. 772 */ 773 static int 774 ipcp_reqci(f, inp, len, reject_if_disagree) 775 fsm *f; 776 u_char *inp; /* Requested CIs */ 777 int *len; /* Length of requested CIs */ 778 int reject_if_disagree; 779 { 780 ipcp_options *wo = &ipcp_wantoptions[f->unit]; 781 ipcp_options *ho = &ipcp_hisoptions[f->unit]; 782 ipcp_options *ao = &ipcp_allowoptions[f->unit]; 783 ipcp_options *go = &ipcp_gotoptions[f->unit]; 784 u_char *cip, *next; /* Pointer to current and next CIs */ 785 u_short cilen, citype; /* Parsed len, type */ 786 u_short cishort; /* Parsed short value */ 787 u_int32_t tl, ciaddr1, ciaddr2;/* Parsed address values */ 788 int rc = CONFACK; /* Final packet return code */ 789 int orc; /* Individual option return code */ 790 u_char *p; /* Pointer to next char to parse */ 791 u_char *ucp = inp; /* Pointer to current output char */ 792 int l = *len; /* Length left */ 793 u_char maxslotindex, cflag; 794 int d; 795 796 cis_received[f->unit] = 1; 797 798 /* 799 * Reset all his options. 800 */ 801 BZERO(ho, sizeof(*ho)); 802 803 /* 804 * Process all his options. 805 */ 806 next = inp; 807 while (l) { 808 orc = CONFACK; /* Assume success */ 809 cip = p = next; /* Remember beginning of CI */ 810 if (l < 2 || /* Not enough data for CI header or */ 811 p[1] < 2 || /* CI length too small or */ 812 p[1] > l) { /* CI length too big? */ 813 IPCPDEBUG((LOG_INFO, "ipcp_reqci: bad CI length!")); 814 orc = CONFREJ; /* Reject bad CI */ 815 cilen = l; /* Reject till end of packet */ 816 l = 0; /* Don't loop again */ 817 goto endswitch; 818 } 819 GETCHAR(citype, p); /* Parse CI type */ 820 GETCHAR(cilen, p); /* Parse CI length */ 821 l -= cilen; /* Adjust remaining length */ 822 next += cilen; /* Step to next CI */ 823 824 switch (citype) { /* Check CI type */ 825 case CI_ADDRS: 826 IPCPDEBUG((LOG_INFO, "ipcp: received ADDRS ")); 827 if (!ao->neg_addr || 828 cilen != CILEN_ADDRS) { /* Check CI length */ 829 orc = CONFREJ; /* Reject CI */ 830 break; 831 } 832 833 /* 834 * If he has no address, or if we both have his address but 835 * disagree about it, then NAK it with our idea. 836 * In particular, if we don't know his address, but he does, 837 * then accept it. 838 */ 839 GETLONG(tl, p); /* Parse source address (his) */ 840 ciaddr1 = htonl(tl); 841 IPCPDEBUG((LOG_INFO, "(%s:", ip_ntoa(ciaddr1))); 842 if (ciaddr1 != wo->hisaddr 843 && (ciaddr1 == 0 || !wo->accept_remote)) { 844 orc = CONFNAK; 845 if (!reject_if_disagree) { 846 DECPTR(sizeof(u_int32_t), p); 847 tl = ntohl(wo->hisaddr); 848 PUTLONG(tl, p); 849 } 850 } else if (ciaddr1 == 0 && wo->hisaddr == 0) { 851 /* 852 * If neither we nor he knows his address, reject the option. 853 */ 854 orc = CONFREJ; 855 wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ 856 break; 857 } 858 859 /* 860 * If he doesn't know our address, or if we both have our address 861 * but disagree about it, then NAK it with our idea. 862 */ 863 GETLONG(tl, p); /* Parse destination address (ours) */ 864 ciaddr2 = htonl(tl); 865 IPCPDEBUG((LOG_INFO, "%s)", ip_ntoa(ciaddr2))); 866 if (ciaddr2 != wo->ouraddr) { 867 if (ciaddr2 == 0 || !wo->accept_local) { 868 orc = CONFNAK; 869 if (!reject_if_disagree) { 870 DECPTR(sizeof(u_int32_t), p); 871 tl = ntohl(wo->ouraddr); 872 PUTLONG(tl, p); 873 } 874 } else { 875 go->ouraddr = ciaddr2; /* accept peer's idea */ 876 } 877 } 878 879 ho->neg_addr = 1; 880 ho->old_addrs = 1; 881 ho->hisaddr = ciaddr1; 882 ho->ouraddr = ciaddr2; 883 break; 884 885 case CI_ADDR: 886 IPCPDEBUG((LOG_INFO, "ipcp: received ADDR ")); 887 888 if (!ao->neg_addr || 889 cilen != CILEN_ADDR) { /* Check CI length */ 890 orc = CONFREJ; /* Reject CI */ 891 break; 892 } 893 894 /* 895 * If he has no address, or if we both have his address but 896 * disagree about it, then NAK it with our idea. 897 * In particular, if we don't know his address, but he does, 898 * then accept it. 899 */ 900 GETLONG(tl, p); /* Parse source address (his) */ 901 ciaddr1 = htonl(tl); 902 IPCPDEBUG((LOG_INFO, "(%s)", ip_ntoa(ciaddr1))); 903 if (ciaddr1 != wo->hisaddr 904 && (ciaddr1 == 0 || !wo->accept_remote)) { 905 orc = CONFNAK; 906 if (!reject_if_disagree) { 907 DECPTR(sizeof(u_int32_t), p); 908 tl = ntohl(wo->hisaddr); 909 PUTLONG(tl, p); 910 } 911 } else if (ciaddr1 == 0 && wo->hisaddr == 0) { 912 /* 913 * Don't ACK an address of 0.0.0.0 - reject it instead. 914 */ 915 orc = CONFREJ; 916 wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ 917 break; 918 } 919 920 ho->neg_addr = 1; 921 ho->hisaddr = ciaddr1; 922 break; 923 924 case CI_MS_DNS1: 925 case CI_MS_DNS2: 926 /* Microsoft primary or secondary DNS request */ 927 d = citype == CI_MS_DNS2; 928 IPCPDEBUG((LOG_INFO, "ipcp: received DNS%d Request ", d+1)); 929 930 /* If we do not have a DNS address then we cannot send it */ 931 if (ao->dnsaddr[d] == 0 || 932 cilen != CILEN_ADDR) { /* Check CI length */ 933 orc = CONFREJ; /* Reject CI */ 934 break; 935 } 936 GETLONG(tl, p); 937 if (htonl(tl) != ao->dnsaddr[d]) { 938 DECPTR(sizeof(u_int32_t), p); 939 tl = ntohl(ao->dnsaddr[d]); 940 PUTLONG(tl, p); 941 orc = CONFNAK; 942 } 943 break; 944 945 case CI_MS_WINS1: 946 case CI_MS_WINS2: 947 /* Microsoft primary or secondary WINS request */ 948 d = citype == CI_MS_WINS2; 949 IPCPDEBUG((LOG_INFO, "ipcp: received WINS%d Request ", d+1)); 950 951 /* If we do not have a DNS address then we cannot send it */ 952 if (ao->winsaddr[d] == 0 || 953 cilen != CILEN_ADDR) { /* Check CI length */ 954 orc = CONFREJ; /* Reject CI */ 955 break; 956 } 957 GETLONG(tl, p); 958 if (htonl(tl) != ao->winsaddr[d]) { 959 DECPTR(sizeof(u_int32_t), p); 960 tl = ntohl(ao->winsaddr[d]); 961 PUTLONG(tl, p); 962 orc = CONFNAK; 963 } 964 break; 965 966 case CI_COMPRESSTYPE: 967 IPCPDEBUG((LOG_INFO, "ipcp: received COMPRESSTYPE ")); 968 if (!ao->neg_vj || 969 (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) { 970 orc = CONFREJ; 971 break; 972 } 973 GETSHORT(cishort, p); 974 IPCPDEBUG((LOG_INFO, "(%d)", cishort)); 975 976 if (!(cishort == IPCP_VJ_COMP || 977 (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) { 978 orc = CONFREJ; 979 break; 980 } 981 982 ho->neg_vj = 1; 983 ho->vj_protocol = cishort; 984 if (cilen == CILEN_VJ) { 985 GETCHAR(maxslotindex, p); 986 if (maxslotindex > ao->maxslotindex) { 987 orc = CONFNAK; 988 if (!reject_if_disagree){ 989 DECPTR(1, p); 990 PUTCHAR(ao->maxslotindex, p); 991 } 992 } 993 GETCHAR(cflag, p); 994 if (cflag && !ao->cflag) { 995 orc = CONFNAK; 996 if (!reject_if_disagree){ 997 DECPTR(1, p); 998 PUTCHAR(wo->cflag, p); 999 } 1000 } 1001 ho->maxslotindex = maxslotindex; 1002 ho->cflag = cflag; 1003 } else { 1004 ho->old_vj = 1; 1005 ho->maxslotindex = MAX_STATES - 1; 1006 ho->cflag = 1; 1007 } 1008 break; 1009 1010 default: 1011 orc = CONFREJ; 1012 break; 1013 } 1014 1015 endswitch: 1016 IPCPDEBUG((LOG_INFO, " (%s)\n", CODENAME(orc))); 1017 1018 if (orc == CONFACK && /* Good CI */ 1019 rc != CONFACK) /* but prior CI wasnt? */ 1020 continue; /* Don't send this one */ 1021 1022 if (orc == CONFNAK) { /* Nak this CI? */ 1023 if (reject_if_disagree) /* Getting fed up with sending NAKs? */ 1024 orc = CONFREJ; /* Get tough if so */ 1025 else { 1026 if (rc == CONFREJ) /* Rejecting prior CI? */ 1027 continue; /* Don't send this one */ 1028 if (rc == CONFACK) { /* Ack'd all prior CIs? */ 1029 rc = CONFNAK; /* Not anymore... */ 1030 ucp = inp; /* Backup */ 1031 } 1032 } 1033 } 1034 1035 if (orc == CONFREJ && /* Reject this CI */ 1036 rc != CONFREJ) { /* but no prior ones? */ 1037 rc = CONFREJ; 1038 ucp = inp; /* Backup */ 1039 } 1040 1041 /* Need to move CI? */ 1042 if (ucp != cip) 1043 BCOPY(cip, ucp, cilen); /* Move it */ 1044 1045 /* Update output pointer */ 1046 INCPTR(cilen, ucp); 1047 } 1048 1049 /* 1050 * If we aren't rejecting this packet, and we want to negotiate 1051 * their address, and they didn't send their address, then we 1052 * send a NAK with a CI_ADDR option appended. We assume the 1053 * input buffer is long enough that we can append the extra 1054 * option safely. 1055 */ 1056 if (rc != CONFREJ && !ho->neg_addr && 1057 wo->req_addr && !reject_if_disagree) { 1058 if (rc == CONFACK) { 1059 rc = CONFNAK; 1060 ucp = inp; /* reset pointer */ 1061 wo->req_addr = 0; /* don't ask again */ 1062 } 1063 PUTCHAR(CI_ADDR, ucp); 1064 PUTCHAR(CILEN_ADDR, ucp); 1065 tl = ntohl(wo->hisaddr); 1066 PUTLONG(tl, ucp); 1067 } 1068 1069 *len = ucp - inp; /* Compute output length */ 1070 IPCPDEBUG((LOG_INFO, "ipcp: returning Configure-%s", CODENAME(rc))); 1071 return (rc); /* Return final code */ 1072 } 1073 1074 1075 /* 1076 * ip_check_options - check that any IP-related options are OK, 1077 * and assign appropriate defaults. 1078 */ 1079 static void 1080 ip_check_options() 1081 { 1082 struct hostent *hp; 1083 u_int32_t local; 1084 ipcp_options *wo = &ipcp_wantoptions[0]; 1085 1086 /* 1087 * Default our local IP address based on our hostname. 1088 * If local IP address already given, don't bother. 1089 */ 1090 if (wo->ouraddr == 0 && !disable_defaultip) { 1091 /* 1092 * Look up our hostname (possibly with domain name appended) 1093 * and take the first IP address as our local IP address. 1094 * If there isn't an IP address for our hostname, too bad. 1095 */ 1096 wo->accept_local = 1; /* don't insist on this default value */ 1097 if ((hp = gethostbyname(hostname)) != NULL) { 1098 local = *(u_int32_t *)hp->h_addr; 1099 if (local != 0 && !bad_ip_adrs(local)) 1100 wo->ouraddr = local; 1101 } 1102 } 1103 1104 if (demand && wo->hisaddr == 0) { 1105 option_error("remote IP address required for demand-dialling\n"); 1106 exit(1); 1107 } 1108 #if 0 1109 if (demand && wo->accept_remote) { 1110 option_error("ipcp-accept-remote is incompatible with demand\n"); 1111 exit(1); 1112 } 1113 #endif 1114 } 1115 1116 1117 /* 1118 * ip_demand_conf - configure the interface as though 1119 * IPCP were up, for use with dial-on-demand. 1120 */ 1121 static int 1122 ip_demand_conf(u) 1123 int u; 1124 { 1125 ipcp_options *wo = &ipcp_wantoptions[u]; 1126 1127 if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr))) 1128 return 0; 1129 if (!sifup(u)) 1130 return 0; 1131 if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE)) 1132 return 0; 1133 if (wo->default_route) 1134 if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr)) 1135 default_route_set[u] = 1; 1136 if (wo->proxy_arp) 1137 if (sifproxyarp(u, wo->hisaddr)) 1138 proxy_arp_set[u] = 1; 1139 1140 syslog(LOG_NOTICE, "local IP address %s", ip_ntoa(wo->ouraddr)); 1141 syslog(LOG_NOTICE, "remote IP address %s", ip_ntoa(wo->hisaddr)); 1142 1143 return 1; 1144 } 1145 1146 1147 /* 1148 * ipcp_up - IPCP has come UP. 1149 * 1150 * Configure the IP network interface appropriately and bring it up. 1151 */ 1152 static void 1153 ipcp_up(f) 1154 fsm *f; 1155 { 1156 u_int32_t mask; 1157 ipcp_options *ho = &ipcp_hisoptions[f->unit]; 1158 ipcp_options *go = &ipcp_gotoptions[f->unit]; 1159 ipcp_options *wo = &ipcp_wantoptions[f->unit]; 1160 1161 np_up(f->unit, PPP_IP); 1162 IPCPDEBUG((LOG_INFO, "ipcp: up")); 1163 1164 /* 1165 * We must have a non-zero IP address for both ends of the link. 1166 */ 1167 if (!ho->neg_addr) 1168 ho->hisaddr = wo->hisaddr; 1169 1170 if (ho->hisaddr == 0) { 1171 syslog(LOG_ERR, "Could not determine remote IP address"); 1172 ipcp_close(f->unit, "Could not determine remote IP address"); 1173 return; 1174 } 1175 if (go->ouraddr == 0) { 1176 syslog(LOG_ERR, "Could not determine local IP address"); 1177 ipcp_close(f->unit, "Could not determine local IP address"); 1178 return; 1179 } 1180 script_setenv("IPLOCAL", ip_ntoa(go->ouraddr)); 1181 script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr)); 1182 1183 /* 1184 * Check that the peer is allowed to use the IP address it wants. 1185 */ 1186 if (!auth_ip_addr(f->unit, ho->hisaddr)) { 1187 syslog(LOG_ERR, "Peer is not authorized to use remote address %s", 1188 ip_ntoa(ho->hisaddr)); 1189 ipcp_close(f->unit, "Unauthorized remote IP address"); 1190 return; 1191 } 1192 1193 /* set tcp compression */ 1194 sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex); 1195 1196 /* 1197 * If we are doing dial-on-demand, the interface is already 1198 * configured, so we put out any saved-up packets, then set the 1199 * interface to pass IP packets. 1200 */ 1201 if (demand) { 1202 if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) { 1203 if (go->ouraddr != wo->ouraddr) 1204 syslog(LOG_WARNING, "Local IP address changed to %s", 1205 ip_ntoa(go->ouraddr)); 1206 if (ho->hisaddr != wo->hisaddr) 1207 syslog(LOG_WARNING, "Remote IP address changed to %s", 1208 ip_ntoa(ho->hisaddr)); 1209 ipcp_clear_addrs(f->unit); 1210 1211 /* Set the interface to the new addresses */ 1212 mask = GetMask(go->ouraddr); 1213 if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { 1214 IPCPDEBUG((LOG_WARNING, "sifaddr failed")); 1215 ipcp_close(f->unit, "Interface configuration failed"); 1216 return; 1217 } 1218 1219 /* assign a default route through the interface if required */ 1220 if (ipcp_wantoptions[f->unit].default_route) 1221 if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) 1222 default_route_set[f->unit] = 1; 1223 1224 /* Make a proxy ARP entry if requested. */ 1225 if (ipcp_wantoptions[f->unit].proxy_arp) 1226 if (sifproxyarp(f->unit, ho->hisaddr)) 1227 proxy_arp_set[f->unit] = 1; 1228 1229 } 1230 demand_rexmit(PPP_IP); 1231 sifnpmode(f->unit, PPP_IP, NPMODE_PASS); 1232 1233 } else { 1234 /* 1235 * Set IP addresses and (if specified) netmask. 1236 */ 1237 mask = GetMask(go->ouraddr); 1238 1239 #if !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) 1240 if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { 1241 IPCPDEBUG((LOG_WARNING, "sifaddr failed")); 1242 ipcp_close(f->unit, "Interface configuration failed"); 1243 return; 1244 } 1245 #endif 1246 1247 /* bring the interface up for IP */ 1248 if (!sifup(f->unit)) { 1249 IPCPDEBUG((LOG_WARNING, "sifup failed")); 1250 ipcp_close(f->unit, "Interface configuration failed"); 1251 return; 1252 } 1253 1254 #if (defined(SVR4) && (defined(SNI) || defined(__USLC__))) 1255 if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { 1256 IPCPDEBUG((LOG_WARNING, "sifaddr failed")); 1257 ipcp_close(f->unit, "Interface configuration failed"); 1258 return; 1259 } 1260 #endif 1261 sifnpmode(f->unit, PPP_IP, NPMODE_PASS); 1262 1263 /* assign a default route through the interface if required */ 1264 if (ipcp_wantoptions[f->unit].default_route) 1265 if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) 1266 default_route_set[f->unit] = 1; 1267 1268 /* Make a proxy ARP entry if requested. */ 1269 if (ipcp_wantoptions[f->unit].proxy_arp) 1270 if (sifproxyarp(f->unit, ho->hisaddr)) 1271 proxy_arp_set[f->unit] = 1; 1272 1273 syslog(LOG_NOTICE, "local IP address %s", ip_ntoa(go->ouraddr)); 1274 syslog(LOG_NOTICE, "remote IP address %s", ip_ntoa(ho->hisaddr)); 1275 } 1276 1277 /* 1278 * Execute the ip-up script, like this: 1279 * /etc/ppp/ip-up interface tty speed local-IP remote-IP 1280 */ 1281 ipcp_script(f, _PATH_IPUP); 1282 1283 } 1284 1285 1286 /* 1287 * ipcp_down - IPCP has gone DOWN. 1288 * 1289 * Take the IP network interface down, clear its addresses 1290 * and delete routes through it. 1291 */ 1292 static void 1293 ipcp_down(f) 1294 fsm *f; 1295 { 1296 IPCPDEBUG((LOG_INFO, "ipcp: down")); 1297 np_down(f->unit, PPP_IP); 1298 sifvjcomp(f->unit, 0, 0, 0); 1299 1300 /* 1301 * If we are doing dial-on-demand, set the interface 1302 * to queue up outgoing packets (for now). 1303 */ 1304 if (demand) { 1305 sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE); 1306 } else { 1307 sifdown(f->unit); 1308 ipcp_clear_addrs(f->unit); 1309 } 1310 1311 /* Execute the ip-down script */ 1312 ipcp_script(f, _PATH_IPDOWN); 1313 } 1314 1315 1316 /* 1317 * ipcp_clear_addrs() - clear the interface addresses, routes, 1318 * proxy arp entries, etc. 1319 */ 1320 static void 1321 ipcp_clear_addrs(unit) 1322 int unit; 1323 { 1324 u_int32_t ouraddr, hisaddr; 1325 1326 ouraddr = ipcp_gotoptions[unit].ouraddr; 1327 hisaddr = ipcp_hisoptions[unit].hisaddr; 1328 if (proxy_arp_set[unit]) { 1329 cifproxyarp(unit, hisaddr); 1330 proxy_arp_set[unit] = 0; 1331 } 1332 if (default_route_set[unit]) { 1333 cifdefaultroute(unit, ouraddr, hisaddr); 1334 default_route_set[unit] = 0; 1335 } 1336 cifaddr(unit, ouraddr, hisaddr); 1337 } 1338 1339 1340 /* 1341 * ipcp_finished - possibly shut down the lower layers. 1342 */ 1343 static void 1344 ipcp_finished(f) 1345 fsm *f; 1346 { 1347 np_finished(f->unit, PPP_IP); 1348 } 1349 1350 1351 /* 1352 * ipcp_script - Execute a script with arguments 1353 * interface-name tty-name speed local-IP remote-IP. 1354 */ 1355 static void 1356 ipcp_script(f, script) 1357 fsm *f; 1358 char *script; 1359 { 1360 char strspeed[32], strlocal[32], strremote[32]; 1361 char *argv[8]; 1362 1363 snprintf(strspeed, sizeof strspeed, "%d", baud_rate); 1364 strlcpy(strlocal, ip_ntoa(ipcp_gotoptions[f->unit].ouraddr), 1365 sizeof strlocal); 1366 strlcpy(strremote, ip_ntoa(ipcp_hisoptions[f->unit].hisaddr), 1367 sizeof strremote); 1368 1369 argv[0] = script; 1370 argv[1] = ifname; 1371 argv[2] = devnam; 1372 argv[3] = strspeed; 1373 argv[4] = strlocal; 1374 argv[5] = strremote; 1375 argv[6] = ipparam; 1376 argv[7] = NULL; 1377 run_program(script, argv, 0); 1378 } 1379 1380 /* 1381 * ipcp_printpkt - print the contents of an IPCP packet. 1382 */ 1383 static char *ipcp_codenames[] = { 1384 "ConfReq", "ConfAck", "ConfNak", "ConfRej", 1385 "TermReq", "TermAck", "CodeRej" 1386 }; 1387 1388 static int 1389 ipcp_printpkt(p, plen, printer, arg) 1390 u_char *p; 1391 int plen; 1392 void (*printer)(void *, char *, ...); 1393 void *arg; 1394 { 1395 int code, id, len, olen; 1396 u_char *pstart, *optend; 1397 u_short cishort; 1398 u_int32_t cilong; 1399 1400 if (plen < HEADERLEN) 1401 return 0; 1402 pstart = p; 1403 GETCHAR(code, p); 1404 GETCHAR(id, p); 1405 GETSHORT(len, p); 1406 if (len < HEADERLEN || len > plen) 1407 return 0; 1408 1409 if (code >= 1 && code <= sizeof(ipcp_codenames) / sizeof(char *)) 1410 printer(arg, " %s", ipcp_codenames[code-1]); 1411 else 1412 printer(arg, " code=0x%x", code); 1413 printer(arg, " id=0x%x", id); 1414 len -= HEADERLEN; 1415 switch (code) { 1416 case CONFREQ: 1417 case CONFACK: 1418 case CONFNAK: 1419 case CONFREJ: 1420 /* print option list */ 1421 while (len >= 2) { 1422 GETCHAR(code, p); 1423 GETCHAR(olen, p); 1424 p -= 2; 1425 if (olen < 2 || olen > len) { 1426 break; 1427 } 1428 printer(arg, " <"); 1429 len -= olen; 1430 optend = p + olen; 1431 switch (code) { 1432 case CI_ADDRS: 1433 if (olen == CILEN_ADDRS) { 1434 p += 2; 1435 GETLONG(cilong, p); 1436 printer(arg, "addrs %I", htonl(cilong)); 1437 GETLONG(cilong, p); 1438 printer(arg, " %I", htonl(cilong)); 1439 } 1440 break; 1441 case CI_COMPRESSTYPE: 1442 if (olen >= CILEN_COMPRESS) { 1443 p += 2; 1444 GETSHORT(cishort, p); 1445 printer(arg, "compress "); 1446 switch (cishort) { 1447 case IPCP_VJ_COMP: 1448 printer(arg, "VJ"); 1449 break; 1450 case IPCP_VJ_COMP_OLD: 1451 printer(arg, "old-VJ"); 1452 break; 1453 default: 1454 printer(arg, "0x%x", cishort); 1455 } 1456 } 1457 break; 1458 case CI_ADDR: 1459 if (olen == CILEN_ADDR) { 1460 p += 2; 1461 GETLONG(cilong, p); 1462 printer(arg, "addr %I", htonl(cilong)); 1463 } 1464 break; 1465 case CI_MS_DNS1: 1466 case CI_MS_DNS2: 1467 p += 2; 1468 GETLONG(cilong, p); 1469 printer(arg, "ms-dns %I", htonl(cilong)); 1470 break; 1471 case CI_MS_WINS1: 1472 case CI_MS_WINS2: 1473 p += 2; 1474 GETLONG(cilong, p); 1475 printer(arg, "ms-wins %I", htonl(cilong)); 1476 break; 1477 } 1478 while (p < optend) { 1479 GETCHAR(code, p); 1480 printer(arg, " %.2x", code); 1481 } 1482 printer(arg, ">"); 1483 } 1484 break; 1485 1486 case TERMACK: 1487 case TERMREQ: 1488 if (len > 0 && *p >= ' ' && *p < 0x7f) { 1489 printer(arg, " "); 1490 print_string(p, len, printer, arg); 1491 p += len; 1492 len = 0; 1493 } 1494 break; 1495 } 1496 1497 /* print the rest of the bytes in the packet */ 1498 for (; len > 0; --len) { 1499 GETCHAR(code, p); 1500 printer(arg, " %.2x", code); 1501 } 1502 1503 return p - pstart; 1504 } 1505 1506 /* 1507 * ip_active_pkt - see if this IP packet is worth bringing the link up for. 1508 * We don't bring the link up for IP fragments or for TCP FIN packets 1509 * with no data. 1510 */ 1511 #define IP_HDRLEN 20 /* bytes */ 1512 #define IP_OFFMASK 0x1fff 1513 #define IPPROTO_TCP 6 1514 #define TCP_HDRLEN 20 1515 #define TH_FIN 0x01 1516 1517 /* 1518 * We use these macros because the IP header may be at an odd address, 1519 * and some compilers might use word loads to get th_off or ip_hl. 1520 */ 1521 1522 #define net_short(x) (((x)[0] << 8) + (x)[1]) 1523 #define get_iphl(x) (((unsigned char *)(x))[0] & 0xF) 1524 #define get_ipoff(x) net_short((unsigned char *)(x) + 6) 1525 #define get_ipproto(x) (((unsigned char *)(x))[9]) 1526 #define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) 1527 #define get_tcpflags(x) (((unsigned char *)(x))[13]) 1528 1529 static int 1530 ip_active_pkt(pkt, len) 1531 u_char *pkt; 1532 int len; 1533 { 1534 u_char *tcp; 1535 int hlen; 1536 1537 len -= PPP_HDRLEN; 1538 pkt += PPP_HDRLEN; 1539 if (len < IP_HDRLEN) 1540 return 0; 1541 if ((get_ipoff(pkt) & IP_OFFMASK) != 0) 1542 return 0; 1543 if (get_ipproto(pkt) != IPPROTO_TCP) 1544 return 1; 1545 hlen = get_iphl(pkt) * 4; 1546 if (len < hlen + TCP_HDRLEN) 1547 return 0; 1548 tcp = pkt + hlen; 1549 if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) 1550 return 0; 1551 return 1; 1552 } 1553