1 /* $NetBSD: ipcp.c,v 1.2 2013/11/28 22:33:42 christos 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 #include <sys/cdefs.h> 46 #if 0 47 #define RCSID "Id: ipcp.c,v 1.73 2008/05/26 08:33:22 paulus Exp " 48 static const char rcsid[] = RCSID; 49 #else 50 __RCSID("$NetBSD: ipcp.c,v 1.2 2013/11/28 22:33:42 christos Exp $"); 51 #endif 52 53 /* 54 * TODO: 55 */ 56 57 #include <stdio.h> 58 #include <string.h> 59 #include <stdlib.h> 60 #include <netdb.h> 61 #include <sys/param.h> 62 #include <sys/types.h> 63 #include <sys/socket.h> 64 #include <netinet/in.h> 65 #include <arpa/inet.h> 66 67 #include "pppd.h" 68 #include "fsm.h" 69 #include "ipcp.h" 70 #include "pathnames.h" 71 72 73 /* global vars */ 74 ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ 75 ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ 76 ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ 77 ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ 78 79 u_int32_t netmask = 0; /* IP netmask to set on interface */ 80 81 bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */ 82 bool noremoteip = 0; /* Let him have no IP address */ 83 84 /* Hook for a plugin to know when IP protocol has come up */ 85 void (*ip_up_hook) __P((void)) = NULL; 86 87 /* Hook for a plugin to know when IP protocol has come down */ 88 void (*ip_down_hook) __P((void)) = NULL; 89 90 /* Hook for a plugin to choose the remote IP address */ 91 void (*ip_choose_hook) __P((u_int32_t *)) = NULL; 92 93 /* Notifiers for when IPCP goes up and down */ 94 struct notifier *ip_up_notifier = NULL; 95 struct notifier *ip_down_notifier = NULL; 96 97 /* local vars */ 98 static int default_route_set[NUM_PPP]; /* Have set up a default route */ 99 static int proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */ 100 static bool usepeerdns; /* Ask peer for DNS addrs */ 101 static int ipcp_is_up; /* have called np_up() */ 102 static int ipcp_is_open; /* haven't called np_finished() */ 103 static bool ask_for_local; /* request our address from peer */ 104 static char vj_value[8]; /* string form of vj option value */ 105 static char netmask_str[20]; /* string form of netmask value */ 106 107 /* 108 * Callbacks for fsm code. (CI = Configuration Information) 109 */ 110 static void ipcp_resetci __P((fsm *)); /* Reset our CI */ 111 static int ipcp_cilen __P((fsm *)); /* Return length of our CI */ 112 static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ 113 static int ipcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ 114 static int ipcp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */ 115 static int ipcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ 116 static int ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ 117 static void ipcp_up __P((fsm *)); /* We're UP */ 118 static void ipcp_down __P((fsm *)); /* We're DOWN */ 119 static void ipcp_finished __P((fsm *)); /* Don't need lower layer */ 120 121 fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */ 122 123 static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ 124 ipcp_resetci, /* Reset our Configuration Information */ 125 ipcp_cilen, /* Length of our Configuration Information */ 126 ipcp_addci, /* Add our Configuration Information */ 127 ipcp_ackci, /* ACK our Configuration Information */ 128 ipcp_nakci, /* NAK our Configuration Information */ 129 ipcp_rejci, /* Reject our Configuration Information */ 130 ipcp_reqci, /* Request peer's Configuration Information */ 131 ipcp_up, /* Called when fsm reaches OPENED state */ 132 ipcp_down, /* Called when fsm leaves OPENED state */ 133 NULL, /* Called when we want the lower layer up */ 134 ipcp_finished, /* Called when we want the lower layer down */ 135 NULL, /* Called when Protocol-Reject received */ 136 NULL, /* Retransmission is necessary */ 137 NULL, /* Called to handle protocol-specific codes */ 138 "IPCP" /* String name of protocol */ 139 }; 140 141 /* 142 * Command-line options. 143 */ 144 static int setvjslots __P((char **)); 145 static int setdnsaddr __P((char **)); 146 static int setwinsaddr __P((char **)); 147 static int setnetmask __P((char **)); 148 int setipaddr __P((char *, char **, int)); 149 static void printipaddr __P((option_t *, void (*)(void *, char *,...),void *)); 150 151 static option_t ipcp_option_list[] = { 152 { "noip", o_bool, &ipcp_protent.enabled_flag, 153 "Disable IP and IPCP" }, 154 { "-ip", o_bool, &ipcp_protent.enabled_flag, 155 "Disable IP and IPCP", OPT_ALIAS }, 156 157 { "novj", o_bool, &ipcp_wantoptions[0].neg_vj, 158 "Disable VJ compression", OPT_A2CLR, &ipcp_allowoptions[0].neg_vj }, 159 { "-vj", o_bool, &ipcp_wantoptions[0].neg_vj, 160 "Disable VJ compression", OPT_ALIAS | OPT_A2CLR, 161 &ipcp_allowoptions[0].neg_vj }, 162 163 { "novjccomp", o_bool, &ipcp_wantoptions[0].cflag, 164 "Disable VJ connection-ID compression", OPT_A2CLR, 165 &ipcp_allowoptions[0].cflag }, 166 { "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag, 167 "Disable VJ connection-ID compression", OPT_ALIAS | OPT_A2CLR, 168 &ipcp_allowoptions[0].cflag }, 169 170 { "vj-max-slots", o_special, (void *)setvjslots, 171 "Set maximum VJ header slots", 172 OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, vj_value }, 173 174 { "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local, 175 "Accept peer's address for us", 1 }, 176 { "ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote, 177 "Accept peer's address for it", 1 }, 178 179 { "ipparam", o_string, &ipparam, 180 "Set ip script parameter", OPT_PRIO }, 181 182 { "noipdefault", o_bool, &disable_defaultip, 183 "Don't use name for default IP adrs", 1 }, 184 185 { "ms-dns", 1, (void *)setdnsaddr, 186 "DNS address for the peer's use" }, 187 { "ms-wins", 1, (void *)setwinsaddr, 188 "Nameserver for SMB over TCP/IP for peer" }, 189 190 { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime, 191 "Set timeout for IPCP", OPT_PRIO }, 192 { "ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits, 193 "Set max #xmits for term-reqs", OPT_PRIO }, 194 { "ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits, 195 "Set max #xmits for conf-reqs", OPT_PRIO }, 196 { "ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops, 197 "Set max #conf-naks for IPCP", OPT_PRIO }, 198 199 { "defaultroute", o_bool, &ipcp_wantoptions[0].default_route, 200 "Add default route", OPT_ENABLE|1, &ipcp_allowoptions[0].default_route }, 201 { "nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route, 202 "disable defaultroute option", OPT_A2CLR, 203 &ipcp_wantoptions[0].default_route }, 204 { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route, 205 "disable defaultroute option", OPT_ALIAS | OPT_A2CLR, 206 &ipcp_wantoptions[0].default_route }, 207 208 { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp, 209 "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp }, 210 { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, 211 "disable proxyarp option", OPT_A2CLR, 212 &ipcp_wantoptions[0].proxy_arp }, 213 { "-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, 214 "disable proxyarp option", OPT_ALIAS | OPT_A2CLR, 215 &ipcp_wantoptions[0].proxy_arp }, 216 217 { "usepeerdns", o_bool, &usepeerdns, 218 "Ask peer for DNS address(es)", 1 }, 219 220 { "netmask", o_special, (void *)setnetmask, 221 "set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str }, 222 223 { "ipcp-no-addresses", o_bool, &ipcp_wantoptions[0].old_addrs, 224 "Disable old-style IP-Addresses usage", OPT_A2CLR, 225 &ipcp_allowoptions[0].old_addrs }, 226 { "ipcp-no-address", o_bool, &ipcp_wantoptions[0].neg_addr, 227 "Disable IP-Address usage", OPT_A2CLR, 228 &ipcp_allowoptions[0].neg_addr }, 229 #ifdef __linux__ 230 { "noremoteip", o_bool, &noremoteip, 231 "Allow peer to have no IP address", 1 }, 232 #endif 233 { "nosendip", o_bool, &ipcp_wantoptions[0].neg_addr, 234 "Don't send our IP address to peer", OPT_A2CLR, 235 &ipcp_wantoptions[0].old_addrs}, 236 237 { "IP addresses", o_wild, (void *) &setipaddr, 238 "set local and remote IP addresses", 239 OPT_NOARG | OPT_A2PRINTER, (void *) &printipaddr }, 240 241 { NULL } 242 }; 243 244 /* 245 * Protocol entry points from main code. 246 */ 247 static void ipcp_init __P((int)); 248 static void ipcp_open __P((int)); 249 static void ipcp_close __P((int, char *)); 250 static void ipcp_lowerup __P((int)); 251 static void ipcp_lowerdown __P((int)); 252 static void ipcp_input __P((int, u_char *, int)); 253 static void ipcp_protrej __P((int)); 254 static int ipcp_printpkt __P((u_char *, int, 255 void (*) __P((void *, char *, ...)), void *)); 256 static void ip_check_options __P((void)); 257 static int ip_demand_conf __P((int)); 258 static int ip_active_pkt __P((u_char *, int)); 259 static void create_resolv __P((u_int32_t, u_int32_t)); 260 261 struct protent ipcp_protent = { 262 PPP_IPCP, 263 ipcp_init, 264 ipcp_input, 265 ipcp_protrej, 266 ipcp_lowerup, 267 ipcp_lowerdown, 268 ipcp_open, 269 ipcp_close, 270 ipcp_printpkt, 271 NULL, 272 1, 273 "IPCP", 274 "IP", 275 ipcp_option_list, 276 ip_check_options, 277 ip_demand_conf, 278 ip_active_pkt 279 }; 280 281 static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t)); 282 static void ipcp_script __P((char *, int)); /* Run an up/down script */ 283 static void ipcp_script_done __P((void *)); 284 285 /* 286 * Lengths of configuration options. 287 */ 288 #define CILEN_VOID 2 289 #define CILEN_COMPRESS 4 /* min length for compression protocol opt. */ 290 #define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */ 291 #define CILEN_ADDR 6 /* new-style single address option */ 292 #define CILEN_ADDRS 10 /* old-style dual address option */ 293 294 295 #define CODENAME(x) ((x) == CONFACK ? "ACK" : \ 296 (x) == CONFNAK ? "NAK" : "REJ") 297 298 /* 299 * This state variable is used to ensure that we don't 300 * run an ipcp-up/down script while one is already running. 301 */ 302 static enum script_state { 303 s_down, 304 s_up, 305 } ipcp_script_state; 306 static pid_t ipcp_script_pid; 307 308 /* 309 * Make a string representation of a network IP address. 310 */ 311 char * 312 ip_ntoa(ipaddr) 313 u_int32_t ipaddr; 314 { 315 static char b[64]; 316 317 slprintf(b, sizeof(b), "%I", ipaddr); 318 return b; 319 } 320 321 /* 322 * Option parsing. 323 */ 324 325 /* 326 * setvjslots - set maximum number of connection slots for VJ compression 327 */ 328 static int 329 setvjslots(argv) 330 char **argv; 331 { 332 int value; 333 334 if (!int_option(*argv, &value)) 335 return 0; 336 if (value < 2 || value > 16) { 337 option_error("vj-max-slots value must be between 2 and 16"); 338 return 0; 339 } 340 ipcp_wantoptions [0].maxslotindex = 341 ipcp_allowoptions[0].maxslotindex = value - 1; 342 slprintf(vj_value, sizeof(vj_value), "%d", value); 343 return 1; 344 } 345 346 /* 347 * setdnsaddr - set the dns address(es) 348 */ 349 static int 350 setdnsaddr(argv) 351 char **argv; 352 { 353 u_int32_t dns; 354 struct hostent *hp; 355 356 dns = inet_addr(*argv); 357 if (dns == (u_int32_t) -1) { 358 if ((hp = gethostbyname(*argv)) == NULL) { 359 option_error("invalid address parameter '%s' for ms-dns option", 360 *argv); 361 return 0; 362 } 363 dns = *(u_int32_t *)hp->h_addr; 364 } 365 366 /* We take the last 2 values given, the 2nd-last as the primary 367 and the last as the secondary. If only one is given it 368 becomes both primary and secondary. */ 369 if (ipcp_allowoptions[0].dnsaddr[1] == 0) 370 ipcp_allowoptions[0].dnsaddr[0] = dns; 371 else 372 ipcp_allowoptions[0].dnsaddr[0] = ipcp_allowoptions[0].dnsaddr[1]; 373 374 /* always set the secondary address value. */ 375 ipcp_allowoptions[0].dnsaddr[1] = dns; 376 377 return (1); 378 } 379 380 /* 381 * setwinsaddr - set the wins address(es) 382 * This is primrarly used with the Samba package under UNIX or for pointing 383 * the caller to the existing WINS server on a Windows NT platform. 384 */ 385 static int 386 setwinsaddr(argv) 387 char **argv; 388 { 389 u_int32_t wins; 390 struct hostent *hp; 391 392 wins = inet_addr(*argv); 393 if (wins == (u_int32_t) -1) { 394 if ((hp = gethostbyname(*argv)) == NULL) { 395 option_error("invalid address parameter '%s' for ms-wins option", 396 *argv); 397 return 0; 398 } 399 wins = *(u_int32_t *)hp->h_addr; 400 } 401 402 /* We take the last 2 values given, the 2nd-last as the primary 403 and the last as the secondary. If only one is given it 404 becomes both primary and secondary. */ 405 if (ipcp_allowoptions[0].winsaddr[1] == 0) 406 ipcp_allowoptions[0].winsaddr[0] = wins; 407 else 408 ipcp_allowoptions[0].winsaddr[0] = ipcp_allowoptions[0].winsaddr[1]; 409 410 /* always set the secondary address value. */ 411 ipcp_allowoptions[0].winsaddr[1] = wins; 412 413 return (1); 414 } 415 416 /* 417 * setipaddr - Set the IP address 418 * If doit is 0, the call is to check whether this option is 419 * potentially an IP address specification. 420 * Not static so that plugins can call it to set the addresses 421 */ 422 int 423 setipaddr(arg, argv, doit) 424 char *arg; 425 char **argv; 426 int doit; 427 { 428 struct hostent *hp; 429 char *colon; 430 u_int32_t local, remote; 431 ipcp_options *wo = &ipcp_wantoptions[0]; 432 static int prio_local = 0, prio_remote = 0; 433 434 /* 435 * IP address pair separated by ":". 436 */ 437 if ((colon = strchr(arg, ':')) == NULL) 438 return 0; 439 if (!doit) 440 return 1; 441 442 /* 443 * If colon first character, then no local addr. 444 */ 445 if (colon != arg && option_priority >= prio_local) { 446 *colon = '\0'; 447 if ((local = inet_addr(arg)) == (u_int32_t) -1) { 448 if ((hp = gethostbyname(arg)) == NULL) { 449 option_error("unknown host: %s", arg); 450 return 0; 451 } 452 local = *(u_int32_t *)hp->h_addr; 453 } 454 if (bad_ip_adrs(local)) { 455 option_error("bad local IP address %s", ip_ntoa(local)); 456 return 0; 457 } 458 if (local != 0) 459 wo->ouraddr = local; 460 *colon = ':'; 461 prio_local = option_priority; 462 } 463 464 /* 465 * If colon last character, then no remote addr. 466 */ 467 if (*++colon != '\0' && option_priority >= prio_remote) { 468 if ((remote = inet_addr(colon)) == (u_int32_t) -1) { 469 if ((hp = gethostbyname(colon)) == NULL) { 470 option_error("unknown host: %s", colon); 471 return 0; 472 } 473 remote = *(u_int32_t *)hp->h_addr; 474 if (remote_name[0] == 0) 475 strlcpy(remote_name, colon, sizeof(remote_name)); 476 } 477 if (bad_ip_adrs(remote)) { 478 option_error("bad remote IP address %s", ip_ntoa(remote)); 479 return 0; 480 } 481 if (remote != 0) 482 wo->hisaddr = remote; 483 prio_remote = option_priority; 484 } 485 486 return 1; 487 } 488 489 static void 490 printipaddr(opt, printer, arg) 491 option_t *opt; 492 void (*printer) __P((void *, char *, ...)); 493 void *arg; 494 { 495 ipcp_options *wo = &ipcp_wantoptions[0]; 496 497 if (wo->ouraddr != 0) 498 printer(arg, "%I", wo->ouraddr); 499 printer(arg, ":"); 500 if (wo->hisaddr != 0) 501 printer(arg, "%I", wo->hisaddr); 502 } 503 504 /* 505 * setnetmask - set the netmask to be used on the interface. 506 */ 507 static int 508 setnetmask(argv) 509 char **argv; 510 { 511 u_int32_t mask; 512 int n; 513 char *p; 514 515 /* 516 * Unfortunately, if we use inet_addr, we can't tell whether 517 * a result of all 1s is an error or a valid 255.255.255.255. 518 */ 519 p = *argv; 520 n = parse_dotted_ip(p, &mask); 521 522 mask = htonl(mask); 523 524 if (n == 0 || p[n] != 0 || (netmask & ~mask) != 0) { 525 option_error("invalid netmask value '%s'", *argv); 526 return 0; 527 } 528 529 netmask = mask; 530 slprintf(netmask_str, sizeof(netmask_str), "%I", mask); 531 532 return (1); 533 } 534 535 int 536 parse_dotted_ip(p, vp) 537 char *p; 538 u_int32_t *vp; 539 { 540 int n; 541 u_int32_t v, b; 542 char *endp, *p0 = p; 543 544 v = 0; 545 for (n = 3;; --n) { 546 b = strtoul(p, &endp, 0); 547 if (endp == p) 548 return 0; 549 if (b > 255) { 550 if (n < 3) 551 return 0; 552 /* accept e.g. 0xffffff00 */ 553 *vp = b; 554 return endp - p0; 555 } 556 v |= b << (n * 8); 557 p = endp; 558 if (n == 0) 559 break; 560 if (*p != '.') 561 return 0; 562 ++p; 563 } 564 *vp = v; 565 return p - p0; 566 } 567 568 569 /* 570 * ipcp_init - Initialize IPCP. 571 */ 572 static void 573 ipcp_init(unit) 574 int unit; 575 { 576 fsm *f = &ipcp_fsm[unit]; 577 ipcp_options *wo = &ipcp_wantoptions[unit]; 578 ipcp_options *ao = &ipcp_allowoptions[unit]; 579 580 f->unit = unit; 581 f->protocol = PPP_IPCP; 582 f->callbacks = &ipcp_callbacks; 583 fsm_init(&ipcp_fsm[unit]); 584 585 /* 586 * Some 3G modems use repeated IPCP NAKs as a way of stalling 587 * until they can contact a server on the network, so we increase 588 * the default number of NAKs we accept before we start treating 589 * them as rejects. 590 */ 591 f->maxnakloops = 100; 592 593 memset(wo, 0, sizeof(*wo)); 594 memset(ao, 0, sizeof(*ao)); 595 596 wo->neg_addr = wo->old_addrs = 1; 597 wo->neg_vj = 1; 598 wo->vj_protocol = IPCP_VJ_COMP; 599 wo->maxslotindex = MAX_STATES - 1; /* really max index */ 600 wo->cflag = 1; 601 602 603 /* max slots and slot-id compression are currently hardwired in */ 604 /* ppp_if.c to 16 and 1, this needs to be changed (among other */ 605 /* things) gmc */ 606 607 ao->neg_addr = ao->old_addrs = 1; 608 ao->neg_vj = 1; 609 ao->maxslotindex = MAX_STATES - 1; 610 ao->cflag = 1; 611 612 /* 613 * XXX These control whether the user may use the proxyarp 614 * and defaultroute options. 615 */ 616 ao->proxy_arp = 1; 617 ao->default_route = 1; 618 } 619 620 621 /* 622 * ipcp_open - IPCP is allowed to come up. 623 */ 624 static void 625 ipcp_open(unit) 626 int unit; 627 { 628 fsm_open(&ipcp_fsm[unit]); 629 ipcp_is_open = 1; 630 } 631 632 633 /* 634 * ipcp_close - Take IPCP down. 635 */ 636 static void 637 ipcp_close(unit, reason) 638 int unit; 639 char *reason; 640 { 641 fsm_close(&ipcp_fsm[unit], reason); 642 } 643 644 645 /* 646 * ipcp_lowerup - The lower layer is up. 647 */ 648 static void 649 ipcp_lowerup(unit) 650 int unit; 651 { 652 fsm_lowerup(&ipcp_fsm[unit]); 653 } 654 655 656 /* 657 * ipcp_lowerdown - The lower layer is down. 658 */ 659 static void 660 ipcp_lowerdown(unit) 661 int unit; 662 { 663 fsm_lowerdown(&ipcp_fsm[unit]); 664 } 665 666 667 /* 668 * ipcp_input - Input IPCP packet. 669 */ 670 static void 671 ipcp_input(unit, p, len) 672 int unit; 673 u_char *p; 674 int len; 675 { 676 fsm_input(&ipcp_fsm[unit], p, len); 677 } 678 679 680 /* 681 * ipcp_protrej - A Protocol-Reject was received for IPCP. 682 * 683 * Pretend the lower layer went down, so we shut up. 684 */ 685 static void 686 ipcp_protrej(unit) 687 int unit; 688 { 689 fsm_lowerdown(&ipcp_fsm[unit]); 690 } 691 692 693 /* 694 * ipcp_resetci - Reset our CI. 695 * Called by fsm_sconfreq, Send Configure Request. 696 */ 697 static void 698 ipcp_resetci(f) 699 fsm *f; 700 { 701 ipcp_options *wo = &ipcp_wantoptions[f->unit]; 702 ipcp_options *go = &ipcp_gotoptions[f->unit]; 703 ipcp_options *ao = &ipcp_allowoptions[f->unit]; 704 705 wo->req_addr = (wo->neg_addr || wo->old_addrs) && 706 (ao->neg_addr || ao->old_addrs); 707 if (wo->ouraddr == 0) 708 wo->accept_local = 1; 709 if (wo->hisaddr == 0) 710 wo->accept_remote = 1; 711 wo->req_dns1 = usepeerdns; /* Request DNS addresses from the peer */ 712 wo->req_dns2 = usepeerdns; 713 *go = *wo; 714 if (!ask_for_local) 715 go->ouraddr = 0; 716 if (ip_choose_hook) { 717 ip_choose_hook(&wo->hisaddr); 718 if (wo->hisaddr) { 719 wo->accept_remote = 0; 720 } 721 } 722 BZERO(&ipcp_hisoptions[f->unit], sizeof(ipcp_options)); 723 } 724 725 726 /* 727 * ipcp_cilen - Return length of our CI. 728 * Called by fsm_sconfreq, Send Configure Request. 729 */ 730 static int 731 ipcp_cilen(f) 732 fsm *f; 733 { 734 ipcp_options *go = &ipcp_gotoptions[f->unit]; 735 ipcp_options *wo = &ipcp_wantoptions[f->unit]; 736 ipcp_options *ho = &ipcp_hisoptions[f->unit]; 737 738 #define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0) 739 #define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) 740 #define LENCIADDR(neg) (neg ? CILEN_ADDR : 0) 741 #define LENCIDNS(neg) LENCIADDR(neg) 742 #define LENCIWINS(neg) LENCIADDR(neg) 743 744 /* 745 * First see if we want to change our options to the old 746 * forms because we have received old forms from the peer. 747 */ 748 if (go->neg_addr && go->old_addrs && !ho->neg_addr && ho->old_addrs) 749 go->neg_addr = 0; 750 if (wo->neg_vj && !go->neg_vj && !go->old_vj) { 751 /* try an older style of VJ negotiation */ 752 /* use the old style only if the peer did */ 753 if (ho->neg_vj && ho->old_vj) { 754 go->neg_vj = 1; 755 go->old_vj = 1; 756 go->vj_protocol = ho->vj_protocol; 757 } 758 } 759 760 return (LENCIADDRS(!go->neg_addr && go->old_addrs) + 761 LENCIVJ(go->neg_vj, go->old_vj) + 762 LENCIADDR(go->neg_addr) + 763 LENCIDNS(go->req_dns1) + 764 LENCIDNS(go->req_dns2) + 765 LENCIWINS(go->winsaddr[0]) + 766 LENCIWINS(go->winsaddr[1])) ; 767 } 768 769 770 /* 771 * ipcp_addci - Add our desired CIs to a packet. 772 * Called by fsm_sconfreq, Send Configure Request. 773 */ 774 static void 775 ipcp_addci(f, ucp, lenp) 776 fsm *f; 777 u_char *ucp; 778 int *lenp; 779 { 780 ipcp_options *go = &ipcp_gotoptions[f->unit]; 781 int len = *lenp; 782 783 #define ADDCIADDRS(opt, neg, val1, val2) \ 784 if (neg) { \ 785 if (len >= CILEN_ADDRS) { \ 786 u_int32_t l; \ 787 PUTCHAR(opt, ucp); \ 788 PUTCHAR(CILEN_ADDRS, ucp); \ 789 l = ntohl(val1); \ 790 PUTLONG(l, ucp); \ 791 l = ntohl(val2); \ 792 PUTLONG(l, ucp); \ 793 len -= CILEN_ADDRS; \ 794 } else \ 795 go->old_addrs = 0; \ 796 } 797 798 #define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \ 799 if (neg) { \ 800 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ 801 if (len >= vjlen) { \ 802 PUTCHAR(opt, ucp); \ 803 PUTCHAR(vjlen, ucp); \ 804 PUTSHORT(val, ucp); \ 805 if (!old) { \ 806 PUTCHAR(maxslotindex, ucp); \ 807 PUTCHAR(cflag, ucp); \ 808 } \ 809 len -= vjlen; \ 810 } else \ 811 neg = 0; \ 812 } 813 814 #define ADDCIADDR(opt, neg, val) \ 815 if (neg) { \ 816 if (len >= CILEN_ADDR) { \ 817 u_int32_t l; \ 818 PUTCHAR(opt, ucp); \ 819 PUTCHAR(CILEN_ADDR, ucp); \ 820 l = ntohl(val); \ 821 PUTLONG(l, ucp); \ 822 len -= CILEN_ADDR; \ 823 } else \ 824 neg = 0; \ 825 } 826 827 #define ADDCIDNS(opt, neg, addr) \ 828 if (neg) { \ 829 if (len >= CILEN_ADDR) { \ 830 u_int32_t l; \ 831 PUTCHAR(opt, ucp); \ 832 PUTCHAR(CILEN_ADDR, ucp); \ 833 l = ntohl(addr); \ 834 PUTLONG(l, ucp); \ 835 len -= CILEN_ADDR; \ 836 } else \ 837 neg = 0; \ 838 } 839 840 #define ADDCIWINS(opt, addr) \ 841 if (addr) { \ 842 if (len >= CILEN_ADDR) { \ 843 u_int32_t l; \ 844 PUTCHAR(opt, ucp); \ 845 PUTCHAR(CILEN_ADDR, ucp); \ 846 l = ntohl(addr); \ 847 PUTLONG(l, ucp); \ 848 len -= CILEN_ADDR; \ 849 } else \ 850 addr = 0; \ 851 } 852 853 ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, 854 go->hisaddr); 855 856 ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, 857 go->maxslotindex, go->cflag); 858 859 ADDCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); 860 861 ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); 862 863 ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); 864 865 ADDCIWINS(CI_MS_WINS1, go->winsaddr[0]); 866 867 ADDCIWINS(CI_MS_WINS2, go->winsaddr[1]); 868 869 *lenp -= len; 870 } 871 872 873 /* 874 * ipcp_ackci - Ack our CIs. 875 * Called by fsm_rconfack, Receive Configure ACK. 876 * 877 * Returns: 878 * 0 - Ack was bad. 879 * 1 - Ack was good. 880 */ 881 static int 882 ipcp_ackci(f, p, len) 883 fsm *f; 884 u_char *p; 885 int len; 886 { 887 ipcp_options *go = &ipcp_gotoptions[f->unit]; 888 u_short cilen, citype, cishort; 889 u_int32_t cilong; 890 u_char cimaxslotindex, cicflag; 891 892 /* 893 * CIs must be in exactly the same order that we sent... 894 * Check packet length and CI length at each step. 895 * If we find any deviations, then this packet is bad. 896 */ 897 898 #define ACKCIADDRS(opt, neg, val1, val2) \ 899 if (neg) { \ 900 u_int32_t l; \ 901 if ((len -= CILEN_ADDRS) < 0) \ 902 goto bad; \ 903 GETCHAR(citype, p); \ 904 GETCHAR(cilen, p); \ 905 if (cilen != CILEN_ADDRS || \ 906 citype != opt) \ 907 goto bad; \ 908 GETLONG(l, p); \ 909 cilong = htonl(l); \ 910 if (val1 != cilong) \ 911 goto bad; \ 912 GETLONG(l, p); \ 913 cilong = htonl(l); \ 914 if (val2 != cilong) \ 915 goto bad; \ 916 } 917 918 #define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \ 919 if (neg) { \ 920 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ 921 if ((len -= vjlen) < 0) \ 922 goto bad; \ 923 GETCHAR(citype, p); \ 924 GETCHAR(cilen, p); \ 925 if (cilen != vjlen || \ 926 citype != opt) \ 927 goto bad; \ 928 GETSHORT(cishort, p); \ 929 if (cishort != val) \ 930 goto bad; \ 931 if (!old) { \ 932 GETCHAR(cimaxslotindex, p); \ 933 if (cimaxslotindex != maxslotindex) \ 934 goto bad; \ 935 GETCHAR(cicflag, p); \ 936 if (cicflag != cflag) \ 937 goto bad; \ 938 } \ 939 } 940 941 #define ACKCIADDR(opt, neg, val) \ 942 if (neg) { \ 943 u_int32_t l; \ 944 if ((len -= CILEN_ADDR) < 0) \ 945 goto bad; \ 946 GETCHAR(citype, p); \ 947 GETCHAR(cilen, p); \ 948 if (cilen != CILEN_ADDR || \ 949 citype != opt) \ 950 goto bad; \ 951 GETLONG(l, p); \ 952 cilong = htonl(l); \ 953 if (val != cilong) \ 954 goto bad; \ 955 } 956 957 #define ACKCIDNS(opt, neg, addr) \ 958 if (neg) { \ 959 u_int32_t l; \ 960 if ((len -= CILEN_ADDR) < 0) \ 961 goto bad; \ 962 GETCHAR(citype, p); \ 963 GETCHAR(cilen, p); \ 964 if (cilen != CILEN_ADDR || citype != opt) \ 965 goto bad; \ 966 GETLONG(l, p); \ 967 cilong = htonl(l); \ 968 if (addr != cilong) \ 969 goto bad; \ 970 } 971 972 ACKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, 973 go->hisaddr); 974 975 ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, 976 go->maxslotindex, go->cflag); 977 978 ACKCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); 979 980 ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); 981 982 ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); 983 984 /* 985 * If there are any remaining CIs, then this packet is bad. 986 */ 987 if (len != 0) 988 goto bad; 989 return (1); 990 991 bad: 992 IPCPDEBUG(("ipcp_ackci: received bad Ack!")); 993 return (0); 994 } 995 996 /* 997 * ipcp_nakci - Peer has sent a NAK for some of our CIs. 998 * This should not modify any state if the Nak is bad 999 * or if IPCP is in the OPENED state. 1000 * Calback from fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. 1001 * 1002 * Returns: 1003 * 0 - Nak was bad. 1004 * 1 - Nak was good. 1005 */ 1006 static int 1007 ipcp_nakci(f, p, len, treat_as_reject) 1008 fsm *f; 1009 u_char *p; 1010 int len; 1011 int treat_as_reject; 1012 { 1013 ipcp_options *go = &ipcp_gotoptions[f->unit]; 1014 u_char cimaxslotindex, cicflag; 1015 u_char citype, cilen, *next; 1016 u_short cishort; 1017 u_int32_t ciaddr1, ciaddr2, l, cidnsaddr; 1018 ipcp_options no; /* options we've seen Naks for */ 1019 ipcp_options try; /* options to request next time */ 1020 1021 BZERO(&no, sizeof(no)); 1022 try = *go; 1023 1024 /* 1025 * Any Nak'd 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 NAKCIADDRS(opt, neg, code) \ 1030 if ((neg) && \ 1031 (cilen = p[1]) == CILEN_ADDRS && \ 1032 len >= cilen && \ 1033 p[0] == opt) { \ 1034 len -= cilen; \ 1035 INCPTR(2, p); \ 1036 GETLONG(l, p); \ 1037 ciaddr1 = htonl(l); \ 1038 GETLONG(l, p); \ 1039 ciaddr2 = htonl(l); \ 1040 no.old_addrs = 1; \ 1041 code \ 1042 } 1043 1044 #define NAKCIVJ(opt, neg, code) \ 1045 if (go->neg && \ 1046 ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \ 1047 len >= cilen && \ 1048 p[0] == opt) { \ 1049 len -= cilen; \ 1050 INCPTR(2, p); \ 1051 GETSHORT(cishort, p); \ 1052 no.neg = 1; \ 1053 code \ 1054 } 1055 1056 #define NAKCIADDR(opt, neg, code) \ 1057 if (go->neg && \ 1058 (cilen = p[1]) == CILEN_ADDR && \ 1059 len >= cilen && \ 1060 p[0] == opt) { \ 1061 len -= cilen; \ 1062 INCPTR(2, p); \ 1063 GETLONG(l, p); \ 1064 ciaddr1 = htonl(l); \ 1065 no.neg = 1; \ 1066 code \ 1067 } 1068 1069 #define NAKCIDNS(opt, neg, code) \ 1070 if (go->neg && \ 1071 ((cilen = p[1]) == CILEN_ADDR) && \ 1072 len >= cilen && \ 1073 p[0] == opt) { \ 1074 len -= cilen; \ 1075 INCPTR(2, p); \ 1076 GETLONG(l, p); \ 1077 cidnsaddr = htonl(l); \ 1078 no.neg = 1; \ 1079 code \ 1080 } 1081 1082 /* 1083 * Accept the peer's idea of {our,his} address, if different 1084 * from our idea, only if the accept_{local,remote} flag is set. 1085 */ 1086 NAKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, 1087 if (treat_as_reject) { 1088 try.old_addrs = 0; 1089 } else { 1090 if (go->accept_local && ciaddr1) { 1091 /* take his idea of our address */ 1092 try.ouraddr = ciaddr1; 1093 } 1094 if (go->accept_remote && ciaddr2) { 1095 /* take his idea of his address */ 1096 try.hisaddr = ciaddr2; 1097 } 1098 } 1099 ); 1100 1101 /* 1102 * Accept the peer's value of maxslotindex provided that it 1103 * is less than what we asked for. Turn off slot-ID compression 1104 * if the peer wants. Send old-style compress-type option if 1105 * the peer wants. 1106 */ 1107 NAKCIVJ(CI_COMPRESSTYPE, neg_vj, 1108 if (treat_as_reject) { 1109 try.neg_vj = 0; 1110 } else if (cilen == CILEN_VJ) { 1111 GETCHAR(cimaxslotindex, p); 1112 GETCHAR(cicflag, p); 1113 if (cishort == IPCP_VJ_COMP) { 1114 try.old_vj = 0; 1115 if (cimaxslotindex < go->maxslotindex) 1116 try.maxslotindex = cimaxslotindex; 1117 if (!cicflag) 1118 try.cflag = 0; 1119 } else { 1120 try.neg_vj = 0; 1121 } 1122 } else { 1123 if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) { 1124 try.old_vj = 1; 1125 try.vj_protocol = cishort; 1126 } else { 1127 try.neg_vj = 0; 1128 } 1129 } 1130 ); 1131 1132 NAKCIADDR(CI_ADDR, neg_addr, 1133 if (treat_as_reject) { 1134 try.neg_addr = 0; 1135 try.old_addrs = 0; 1136 } else if (go->accept_local && ciaddr1) { 1137 /* take his idea of our address */ 1138 try.ouraddr = ciaddr1; 1139 } 1140 ); 1141 1142 NAKCIDNS(CI_MS_DNS1, req_dns1, 1143 if (treat_as_reject) { 1144 try.req_dns1 = 0; 1145 } else { 1146 try.dnsaddr[0] = cidnsaddr; 1147 } 1148 ); 1149 1150 NAKCIDNS(CI_MS_DNS2, req_dns2, 1151 if (treat_as_reject) { 1152 try.req_dns2 = 0; 1153 } else { 1154 try.dnsaddr[1] = cidnsaddr; 1155 } 1156 ); 1157 1158 /* 1159 * There may be remaining CIs, if the peer is requesting negotiation 1160 * on an option that we didn't include in our request packet. 1161 * If they want to negotiate about IP addresses, we comply. 1162 * If they want us to ask for compression, we refuse. 1163 * If they want us to ask for ms-dns, we do that, since some 1164 * peers get huffy if we don't. 1165 */ 1166 while (len >= CILEN_VOID) { 1167 GETCHAR(citype, p); 1168 GETCHAR(cilen, p); 1169 if ( cilen < CILEN_VOID || (len -= cilen) < 0 ) 1170 goto bad; 1171 next = p + cilen - 2; 1172 1173 switch (citype) { 1174 case CI_COMPRESSTYPE: 1175 if (go->neg_vj || no.neg_vj || 1176 (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) 1177 goto bad; 1178 no.neg_vj = 1; 1179 break; 1180 case CI_ADDRS: 1181 if ((!go->neg_addr && go->old_addrs) || no.old_addrs 1182 || cilen != CILEN_ADDRS) 1183 goto bad; 1184 try.neg_addr = 0; 1185 GETLONG(l, p); 1186 ciaddr1 = htonl(l); 1187 if (ciaddr1 && go->accept_local) 1188 try.ouraddr = ciaddr1; 1189 GETLONG(l, p); 1190 ciaddr2 = htonl(l); 1191 if (ciaddr2 && go->accept_remote) 1192 try.hisaddr = ciaddr2; 1193 no.old_addrs = 1; 1194 break; 1195 case CI_ADDR: 1196 if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) 1197 goto bad; 1198 try.old_addrs = 0; 1199 GETLONG(l, p); 1200 ciaddr1 = htonl(l); 1201 if (ciaddr1 && go->accept_local) 1202 try.ouraddr = ciaddr1; 1203 if (try.ouraddr != 0) 1204 try.neg_addr = 1; 1205 no.neg_addr = 1; 1206 break; 1207 case CI_MS_DNS1: 1208 if (go->req_dns1 || no.req_dns1 || cilen != CILEN_ADDR) 1209 goto bad; 1210 GETLONG(l, p); 1211 try.dnsaddr[0] = htonl(l); 1212 try.req_dns1 = 1; 1213 no.req_dns1 = 1; 1214 break; 1215 case CI_MS_DNS2: 1216 if (go->req_dns2 || no.req_dns2 || cilen != CILEN_ADDR) 1217 goto bad; 1218 GETLONG(l, p); 1219 try.dnsaddr[1] = htonl(l); 1220 try.req_dns2 = 1; 1221 no.req_dns2 = 1; 1222 break; 1223 case CI_MS_WINS1: 1224 case CI_MS_WINS2: 1225 if (cilen != CILEN_ADDR) 1226 goto bad; 1227 GETLONG(l, p); 1228 ciaddr1 = htonl(l); 1229 if (ciaddr1) 1230 try.winsaddr[citype == CI_MS_WINS2] = ciaddr1; 1231 break; 1232 } 1233 p = next; 1234 } 1235 1236 /* 1237 * OK, the Nak is good. Now we can update state. 1238 * If there are any remaining options, we ignore them. 1239 */ 1240 if (f->state != OPENED) 1241 *go = try; 1242 1243 return 1; 1244 1245 bad: 1246 IPCPDEBUG(("ipcp_nakci: received bad Nak!")); 1247 return 0; 1248 } 1249 1250 1251 /* 1252 * ipcp_rejci - Reject some of our CIs. 1253 * Callback from fsm_rconfnakrej. 1254 */ 1255 static int 1256 ipcp_rejci(f, p, len) 1257 fsm *f; 1258 u_char *p; 1259 int len; 1260 { 1261 ipcp_options *go = &ipcp_gotoptions[f->unit]; 1262 u_char cimaxslotindex, ciflag, cilen; 1263 u_short cishort; 1264 u_int32_t cilong; 1265 ipcp_options try; /* options to request next time */ 1266 1267 try = *go; 1268 /* 1269 * Any Rejected CIs must be in exactly the same order that we sent. 1270 * Check packet length and CI length at each step. 1271 * If we find any deviations, then this packet is bad. 1272 */ 1273 #define REJCIADDRS(opt, neg, val1, val2) \ 1274 if ((neg) && \ 1275 (cilen = p[1]) == CILEN_ADDRS && \ 1276 len >= cilen && \ 1277 p[0] == opt) { \ 1278 u_int32_t l; \ 1279 len -= cilen; \ 1280 INCPTR(2, p); \ 1281 GETLONG(l, p); \ 1282 cilong = htonl(l); \ 1283 /* Check rejected value. */ \ 1284 if (cilong != val1) \ 1285 goto bad; \ 1286 GETLONG(l, p); \ 1287 cilong = htonl(l); \ 1288 /* Check rejected value. */ \ 1289 if (cilong != val2) \ 1290 goto bad; \ 1291 try.old_addrs = 0; \ 1292 } 1293 1294 #define REJCIVJ(opt, neg, val, old, maxslot, cflag) \ 1295 if (go->neg && \ 1296 p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \ 1297 len >= p[1] && \ 1298 p[0] == opt) { \ 1299 len -= p[1]; \ 1300 INCPTR(2, p); \ 1301 GETSHORT(cishort, p); \ 1302 /* Check rejected value. */ \ 1303 if (cishort != val) \ 1304 goto bad; \ 1305 if (!old) { \ 1306 GETCHAR(cimaxslotindex, p); \ 1307 if (cimaxslotindex != maxslot) \ 1308 goto bad; \ 1309 GETCHAR(ciflag, p); \ 1310 if (ciflag != cflag) \ 1311 goto bad; \ 1312 } \ 1313 try.neg = 0; \ 1314 } 1315 1316 #define REJCIADDR(opt, neg, val) \ 1317 if (go->neg && \ 1318 (cilen = p[1]) == CILEN_ADDR && \ 1319 len >= cilen && \ 1320 p[0] == opt) { \ 1321 u_int32_t l; \ 1322 len -= cilen; \ 1323 INCPTR(2, p); \ 1324 GETLONG(l, p); \ 1325 cilong = htonl(l); \ 1326 /* Check rejected value. */ \ 1327 if (cilong != val) \ 1328 goto bad; \ 1329 try.neg = 0; \ 1330 } 1331 1332 #define REJCIDNS(opt, neg, dnsaddr) \ 1333 if (go->neg && \ 1334 ((cilen = p[1]) == CILEN_ADDR) && \ 1335 len >= cilen && \ 1336 p[0] == opt) { \ 1337 u_int32_t l; \ 1338 len -= cilen; \ 1339 INCPTR(2, p); \ 1340 GETLONG(l, p); \ 1341 cilong = htonl(l); \ 1342 /* Check rejected value. */ \ 1343 if (cilong != dnsaddr) \ 1344 goto bad; \ 1345 try.neg = 0; \ 1346 } 1347 1348 #define REJCIWINS(opt, addr) \ 1349 if (addr && \ 1350 ((cilen = p[1]) == CILEN_ADDR) && \ 1351 len >= cilen && \ 1352 p[0] == opt) { \ 1353 u_int32_t l; \ 1354 len -= cilen; \ 1355 INCPTR(2, p); \ 1356 GETLONG(l, p); \ 1357 cilong = htonl(l); \ 1358 /* Check rejected value. */ \ 1359 if (cilong != addr) \ 1360 goto bad; \ 1361 try.winsaddr[opt == CI_MS_WINS2] = 0; \ 1362 } 1363 1364 REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, 1365 go->ouraddr, go->hisaddr); 1366 1367 REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, 1368 go->maxslotindex, go->cflag); 1369 1370 REJCIADDR(CI_ADDR, neg_addr, go->ouraddr); 1371 1372 REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); 1373 1374 REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); 1375 1376 REJCIWINS(CI_MS_WINS1, go->winsaddr[0]); 1377 1378 REJCIWINS(CI_MS_WINS2, go->winsaddr[1]); 1379 1380 /* 1381 * If there are any remaining CIs, then this packet is bad. 1382 */ 1383 if (len != 0) 1384 goto bad; 1385 /* 1386 * Now we can update state. 1387 */ 1388 if (f->state != OPENED) 1389 *go = try; 1390 return 1; 1391 1392 bad: 1393 IPCPDEBUG(("ipcp_rejci: received bad Reject!")); 1394 return 0; 1395 } 1396 1397 1398 /* 1399 * ipcp_reqci - Check the peer's requested CIs and send appropriate response. 1400 * Callback from fsm_rconfreq, Receive Configure Request 1401 * 1402 * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified 1403 * appropriately. If reject_if_disagree is non-zero, doesn't return 1404 * CONFNAK; returns CONFREJ if it can't return CONFACK. 1405 */ 1406 static int 1407 ipcp_reqci(f, inp, len, reject_if_disagree) 1408 fsm *f; 1409 u_char *inp; /* Requested CIs */ 1410 int *len; /* Length of requested CIs */ 1411 int reject_if_disagree; 1412 { 1413 ipcp_options *wo = &ipcp_wantoptions[f->unit]; 1414 ipcp_options *ho = &ipcp_hisoptions[f->unit]; 1415 ipcp_options *ao = &ipcp_allowoptions[f->unit]; 1416 u_char *cip, *next; /* Pointer to current and next CIs */ 1417 u_short cilen, citype; /* Parsed len, type */ 1418 u_short cishort; /* Parsed short value */ 1419 u_int32_t tl, ciaddr1, ciaddr2;/* Parsed address values */ 1420 int rc = CONFACK; /* Final packet return code */ 1421 int orc; /* Individual option return code */ 1422 u_char *p; /* Pointer to next char to parse */ 1423 u_char *ucp = inp; /* Pointer to current output char */ 1424 int l = *len; /* Length left */ 1425 u_char maxslotindex, cflag; 1426 int d; 1427 1428 /* 1429 * Reset all his options. 1430 */ 1431 BZERO(ho, sizeof(*ho)); 1432 1433 /* 1434 * Process all his options. 1435 */ 1436 next = inp; 1437 while (l) { 1438 orc = CONFACK; /* Assume success */ 1439 cip = p = next; /* Remember begining of CI */ 1440 if (l < 2 || /* Not enough data for CI header or */ 1441 p[1] < 2 || /* CI length too small or */ 1442 p[1] > l) { /* CI length too big? */ 1443 IPCPDEBUG(("ipcp_reqci: bad CI length!")); 1444 orc = CONFREJ; /* Reject bad CI */ 1445 cilen = l; /* Reject till end of packet */ 1446 l = 0; /* Don't loop again */ 1447 goto endswitch; 1448 } 1449 GETCHAR(citype, p); /* Parse CI type */ 1450 GETCHAR(cilen, p); /* Parse CI length */ 1451 l -= cilen; /* Adjust remaining length */ 1452 next += cilen; /* Step to next CI */ 1453 1454 switch (citype) { /* Check CI type */ 1455 case CI_ADDRS: 1456 if (!ao->old_addrs || ho->neg_addr || 1457 cilen != CILEN_ADDRS) { /* Check CI length */ 1458 orc = CONFREJ; /* Reject CI */ 1459 break; 1460 } 1461 1462 /* 1463 * If he has no address, or if we both have his address but 1464 * disagree about it, then NAK it with our idea. 1465 * In particular, if we don't know his address, but he does, 1466 * then accept it. 1467 */ 1468 GETLONG(tl, p); /* Parse source address (his) */ 1469 ciaddr1 = htonl(tl); 1470 if (ciaddr1 != wo->hisaddr 1471 && (ciaddr1 == 0 || !wo->accept_remote)) { 1472 orc = CONFNAK; 1473 if (!reject_if_disagree) { 1474 DECPTR(sizeof(u_int32_t), p); 1475 tl = ntohl(wo->hisaddr); 1476 PUTLONG(tl, p); 1477 } 1478 } else if (ciaddr1 == 0 && wo->hisaddr == 0) { 1479 /* 1480 * If neither we nor he knows his address, reject the option. 1481 */ 1482 orc = CONFREJ; 1483 wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ 1484 break; 1485 } 1486 1487 /* 1488 * If he doesn't know our address, or if we both have our address 1489 * but disagree about it, then NAK it with our idea. 1490 */ 1491 GETLONG(tl, p); /* Parse desination address (ours) */ 1492 ciaddr2 = htonl(tl); 1493 if (ciaddr2 != wo->ouraddr) { 1494 if (ciaddr2 == 0 || !wo->accept_local) { 1495 orc = CONFNAK; 1496 if (!reject_if_disagree) { 1497 DECPTR(sizeof(u_int32_t), p); 1498 tl = ntohl(wo->ouraddr); 1499 PUTLONG(tl, p); 1500 } 1501 } else { 1502 wo->ouraddr = ciaddr2; /* accept peer's idea */ 1503 } 1504 } 1505 1506 ho->old_addrs = 1; 1507 ho->hisaddr = ciaddr1; 1508 ho->ouraddr = ciaddr2; 1509 break; 1510 1511 case CI_ADDR: 1512 if (!ao->neg_addr || ho->old_addrs || 1513 cilen != CILEN_ADDR) { /* Check CI length */ 1514 orc = CONFREJ; /* Reject CI */ 1515 break; 1516 } 1517 1518 /* 1519 * If he has no address, or if we both have his address but 1520 * disagree about it, then NAK it with our idea. 1521 * In particular, if we don't know his address, but he does, 1522 * then accept it. 1523 */ 1524 GETLONG(tl, p); /* Parse source address (his) */ 1525 ciaddr1 = htonl(tl); 1526 if (ciaddr1 != wo->hisaddr 1527 && (ciaddr1 == 0 || !wo->accept_remote)) { 1528 orc = CONFNAK; 1529 if (!reject_if_disagree) { 1530 DECPTR(sizeof(u_int32_t), p); 1531 tl = ntohl(wo->hisaddr); 1532 PUTLONG(tl, p); 1533 } 1534 } else if (ciaddr1 == 0 && wo->hisaddr == 0) { 1535 /* 1536 * Don't ACK an address of 0.0.0.0 - reject it instead. 1537 */ 1538 orc = CONFREJ; 1539 wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ 1540 break; 1541 } 1542 1543 ho->neg_addr = 1; 1544 ho->hisaddr = ciaddr1; 1545 break; 1546 1547 case CI_MS_DNS1: 1548 case CI_MS_DNS2: 1549 /* Microsoft primary or secondary DNS request */ 1550 d = citype == CI_MS_DNS2; 1551 1552 /* If we do not have a DNS address then we cannot send it */ 1553 if (ao->dnsaddr[d] == 0 || 1554 cilen != CILEN_ADDR) { /* Check CI length */ 1555 orc = CONFREJ; /* Reject CI */ 1556 break; 1557 } 1558 GETLONG(tl, p); 1559 if (htonl(tl) != ao->dnsaddr[d]) { 1560 DECPTR(sizeof(u_int32_t), p); 1561 tl = ntohl(ao->dnsaddr[d]); 1562 PUTLONG(tl, p); 1563 orc = CONFNAK; 1564 } 1565 break; 1566 1567 case CI_MS_WINS1: 1568 case CI_MS_WINS2: 1569 /* Microsoft primary or secondary WINS request */ 1570 d = citype == CI_MS_WINS2; 1571 1572 /* If we do not have a DNS address then we cannot send it */ 1573 if (ao->winsaddr[d] == 0 || 1574 cilen != CILEN_ADDR) { /* Check CI length */ 1575 orc = CONFREJ; /* Reject CI */ 1576 break; 1577 } 1578 GETLONG(tl, p); 1579 if (htonl(tl) != ao->winsaddr[d]) { 1580 DECPTR(sizeof(u_int32_t), p); 1581 tl = ntohl(ao->winsaddr[d]); 1582 PUTLONG(tl, p); 1583 orc = CONFNAK; 1584 } 1585 break; 1586 1587 case CI_COMPRESSTYPE: 1588 if (!ao->neg_vj || 1589 (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) { 1590 orc = CONFREJ; 1591 break; 1592 } 1593 GETSHORT(cishort, p); 1594 1595 if (!(cishort == IPCP_VJ_COMP || 1596 (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) { 1597 orc = CONFREJ; 1598 break; 1599 } 1600 1601 ho->neg_vj = 1; 1602 ho->vj_protocol = cishort; 1603 if (cilen == CILEN_VJ) { 1604 GETCHAR(maxslotindex, p); 1605 if (maxslotindex > ao->maxslotindex) { 1606 orc = CONFNAK; 1607 if (!reject_if_disagree){ 1608 DECPTR(1, p); 1609 PUTCHAR(ao->maxslotindex, p); 1610 } 1611 } 1612 GETCHAR(cflag, p); 1613 if (cflag && !ao->cflag) { 1614 orc = CONFNAK; 1615 if (!reject_if_disagree){ 1616 DECPTR(1, p); 1617 PUTCHAR(wo->cflag, p); 1618 } 1619 } 1620 ho->maxslotindex = maxslotindex; 1621 ho->cflag = cflag; 1622 } else { 1623 ho->old_vj = 1; 1624 ho->maxslotindex = MAX_STATES - 1; 1625 ho->cflag = 1; 1626 } 1627 break; 1628 1629 default: 1630 orc = CONFREJ; 1631 break; 1632 } 1633 endswitch: 1634 if (orc == CONFACK && /* Good CI */ 1635 rc != CONFACK) /* but prior CI wasnt? */ 1636 continue; /* Don't send this one */ 1637 1638 if (orc == CONFNAK) { /* Nak this CI? */ 1639 if (reject_if_disagree) /* Getting fed up with sending NAKs? */ 1640 orc = CONFREJ; /* Get tough if so */ 1641 else { 1642 if (rc == CONFREJ) /* Rejecting prior CI? */ 1643 continue; /* Don't send this one */ 1644 if (rc == CONFACK) { /* Ack'd all prior CIs? */ 1645 rc = CONFNAK; /* Not anymore... */ 1646 ucp = inp; /* Backup */ 1647 } 1648 } 1649 } 1650 1651 if (orc == CONFREJ && /* Reject this CI */ 1652 rc != CONFREJ) { /* but no prior ones? */ 1653 rc = CONFREJ; 1654 ucp = inp; /* Backup */ 1655 } 1656 1657 /* Need to move CI? */ 1658 if (ucp != cip) 1659 BCOPY(cip, ucp, cilen); /* Move it */ 1660 1661 /* Update output pointer */ 1662 INCPTR(cilen, ucp); 1663 } 1664 1665 /* 1666 * If we aren't rejecting this packet, and we want to negotiate 1667 * their address, and they didn't send their address, then we 1668 * send a NAK with a CI_ADDR option appended. We assume the 1669 * input buffer is long enough that we can append the extra 1670 * option safely. 1671 */ 1672 if (rc != CONFREJ && !ho->neg_addr && !ho->old_addrs && 1673 wo->req_addr && !reject_if_disagree && !noremoteip) { 1674 if (rc == CONFACK) { 1675 rc = CONFNAK; 1676 ucp = inp; /* reset pointer */ 1677 wo->req_addr = 0; /* don't ask again */ 1678 } 1679 PUTCHAR(CI_ADDR, ucp); 1680 PUTCHAR(CILEN_ADDR, ucp); 1681 tl = ntohl(wo->hisaddr); 1682 PUTLONG(tl, ucp); 1683 } 1684 1685 *len = ucp - inp; /* Compute output length */ 1686 IPCPDEBUG(("ipcp: returning Configure-%s", CODENAME(rc))); 1687 return (rc); /* Return final code */ 1688 } 1689 1690 1691 /* 1692 * ip_check_options - check that any IP-related options are OK, 1693 * and assign appropriate defaults. 1694 */ 1695 static void 1696 ip_check_options() 1697 { 1698 struct hostent *hp; 1699 u_int32_t local; 1700 ipcp_options *wo = &ipcp_wantoptions[0]; 1701 1702 /* 1703 * Default our local IP address based on our hostname. 1704 * If local IP address already given, don't bother. 1705 */ 1706 if (wo->ouraddr == 0 && !disable_defaultip) { 1707 /* 1708 * Look up our hostname (possibly with domain name appended) 1709 * and take the first IP address as our local IP address. 1710 * If there isn't an IP address for our hostname, too bad. 1711 */ 1712 wo->accept_local = 1; /* don't insist on this default value */ 1713 if ((hp = gethostbyname(hostname)) != NULL) { 1714 local = *(u_int32_t *)hp->h_addr; 1715 if (local != 0 && !bad_ip_adrs(local)) 1716 wo->ouraddr = local; 1717 } 1718 } 1719 ask_for_local = wo->ouraddr != 0 || !disable_defaultip; 1720 } 1721 1722 1723 /* 1724 * ip_demand_conf - configure the interface as though 1725 * IPCP were up, for use with dial-on-demand. 1726 */ 1727 static int 1728 ip_demand_conf(u) 1729 int u; 1730 { 1731 ipcp_options *wo = &ipcp_wantoptions[u]; 1732 1733 if (wo->hisaddr == 0 && !noremoteip) { 1734 /* make up an arbitrary address for the peer */ 1735 wo->hisaddr = htonl(0x0a707070 + ifunit); 1736 wo->accept_remote = 1; 1737 } 1738 if (wo->ouraddr == 0) { 1739 /* make up an arbitrary address for us */ 1740 wo->ouraddr = htonl(0x0a404040 + ifunit); 1741 wo->accept_local = 1; 1742 ask_for_local = 0; /* don't tell the peer this address */ 1743 } 1744 if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr))) 1745 return 0; 1746 ipcp_script(_PATH_IPPREUP, 1); 1747 if (!sifup(u)) 1748 return 0; 1749 if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE)) 1750 return 0; 1751 if (wo->default_route) 1752 if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr)) 1753 default_route_set[u] = 1; 1754 if (wo->proxy_arp) 1755 if (sifproxyarp(u, wo->hisaddr)) 1756 proxy_arp_set[u] = 1; 1757 1758 notice("local IP address %I", wo->ouraddr); 1759 if (wo->hisaddr) 1760 notice("remote IP address %I", wo->hisaddr); 1761 1762 return 1; 1763 } 1764 1765 1766 /* 1767 * ipcp_up - IPCP has come UP. 1768 * 1769 * Configure the IP network interface appropriately and bring it up. 1770 */ 1771 static void 1772 ipcp_up(f) 1773 fsm *f; 1774 { 1775 u_int32_t mask; 1776 ipcp_options *ho = &ipcp_hisoptions[f->unit]; 1777 ipcp_options *go = &ipcp_gotoptions[f->unit]; 1778 ipcp_options *wo = &ipcp_wantoptions[f->unit]; 1779 1780 IPCPDEBUG(("ipcp: up")); 1781 1782 /* 1783 * We must have a non-zero IP address for both ends of the link. 1784 */ 1785 if (!ho->neg_addr && !ho->old_addrs) 1786 ho->hisaddr = wo->hisaddr; 1787 1788 if (!(go->neg_addr || go->old_addrs) && (wo->neg_addr || wo->old_addrs) 1789 && wo->ouraddr != 0) { 1790 error("Peer refused to agree to our IP address"); 1791 ipcp_close(f->unit, "Refused our IP address"); 1792 return; 1793 } 1794 if (go->ouraddr == 0) { 1795 error("Could not determine local IP address"); 1796 ipcp_close(f->unit, "Could not determine local IP address"); 1797 return; 1798 } 1799 if (ho->hisaddr == 0 && !noremoteip) { 1800 ho->hisaddr = htonl(0x0a404040 + ifunit); 1801 warn("Could not determine remote IP address: defaulting to %I", 1802 ho->hisaddr); 1803 } 1804 script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0); 1805 if (ho->hisaddr != 0) 1806 script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1); 1807 1808 if (!go->req_dns1) 1809 go->dnsaddr[0] = 0; 1810 if (!go->req_dns2) 1811 go->dnsaddr[1] = 0; 1812 if (go->dnsaddr[0]) 1813 script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0); 1814 if (go->dnsaddr[1]) 1815 script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0); 1816 if (usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { 1817 script_setenv("USEPEERDNS", "1", 0); 1818 create_resolv(go->dnsaddr[0], go->dnsaddr[1]); 1819 } 1820 1821 /* 1822 * Check that the peer is allowed to use the IP address it wants. 1823 */ 1824 if (ho->hisaddr != 0 && !auth_ip_addr(f->unit, ho->hisaddr)) { 1825 error("Peer is not authorized to use remote address %I", ho->hisaddr); 1826 ipcp_close(f->unit, "Unauthorized remote IP address"); 1827 return; 1828 } 1829 1830 /* set tcp compression */ 1831 sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex); 1832 1833 /* 1834 * If we are doing dial-on-demand, the interface is already 1835 * configured, so we put out any saved-up packets, then set the 1836 * interface to pass IP packets. 1837 */ 1838 if (demand) { 1839 if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) { 1840 ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr); 1841 if (go->ouraddr != wo->ouraddr) { 1842 warn("Local IP address changed to %I", go->ouraddr); 1843 script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0); 1844 wo->ouraddr = go->ouraddr; 1845 } else 1846 script_unsetenv("OLDIPLOCAL"); 1847 if (ho->hisaddr != wo->hisaddr && wo->hisaddr != 0) { 1848 warn("Remote IP address changed to %I", ho->hisaddr); 1849 script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0); 1850 wo->hisaddr = ho->hisaddr; 1851 } else 1852 script_unsetenv("OLDIPREMOTE"); 1853 1854 /* Set the interface to the new addresses */ 1855 mask = GetMask(go->ouraddr); 1856 if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { 1857 if (debug) 1858 warn("Interface configuration failed"); 1859 ipcp_close(f->unit, "Interface configuration failed"); 1860 return; 1861 } 1862 1863 /* assign a default route through the interface if required */ 1864 if (ipcp_wantoptions[f->unit].default_route) 1865 if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) 1866 default_route_set[f->unit] = 1; 1867 1868 /* Make a proxy ARP entry if requested. */ 1869 if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp) 1870 if (sifproxyarp(f->unit, ho->hisaddr)) 1871 proxy_arp_set[f->unit] = 1; 1872 1873 } 1874 demand_rexmit(PPP_IP); 1875 sifnpmode(f->unit, PPP_IP, NPMODE_PASS); 1876 1877 } else { 1878 /* 1879 * Set IP addresses and (if specified) netmask. 1880 */ 1881 mask = GetMask(go->ouraddr); 1882 1883 #if !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) 1884 if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { 1885 if (debug) 1886 warn("Interface configuration failed"); 1887 ipcp_close(f->unit, "Interface configuration failed"); 1888 return; 1889 } 1890 #endif 1891 1892 /* run the pre-up script, if any, and wait for it to finish */ 1893 ipcp_script(_PATH_IPPREUP, 1); 1894 1895 /* bring the interface up for IP */ 1896 if (!sifup(f->unit)) { 1897 if (debug) 1898 warn("Interface failed to come up"); 1899 ipcp_close(f->unit, "Interface configuration failed"); 1900 return; 1901 } 1902 1903 #if (defined(SVR4) && (defined(SNI) || defined(__USLC__))) 1904 if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { 1905 if (debug) 1906 warn("Interface configuration failed"); 1907 ipcp_close(f->unit, "Interface configuration failed"); 1908 return; 1909 } 1910 #endif 1911 sifnpmode(f->unit, PPP_IP, NPMODE_PASS); 1912 1913 /* assign a default route through the interface if required */ 1914 if (ipcp_wantoptions[f->unit].default_route) 1915 if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) 1916 default_route_set[f->unit] = 1; 1917 1918 /* Make a proxy ARP entry if requested. */ 1919 if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp) 1920 if (sifproxyarp(f->unit, ho->hisaddr)) 1921 proxy_arp_set[f->unit] = 1; 1922 1923 ipcp_wantoptions[0].ouraddr = go->ouraddr; 1924 1925 notice("local IP address %I", go->ouraddr); 1926 if (ho->hisaddr != 0) 1927 notice("remote IP address %I", ho->hisaddr); 1928 if (go->dnsaddr[0]) 1929 notice("primary DNS address %I", go->dnsaddr[0]); 1930 if (go->dnsaddr[1]) 1931 notice("secondary DNS address %I", go->dnsaddr[1]); 1932 } 1933 1934 reset_link_stats(f->unit); 1935 1936 np_up(f->unit, PPP_IP); 1937 ipcp_is_up = 1; 1938 1939 notify(ip_up_notifier, 0); 1940 if (ip_up_hook) 1941 ip_up_hook(); 1942 1943 /* 1944 * Execute the ip-up script, like this: 1945 * /etc/ppp/ip-up interface tty speed local-IP remote-IP 1946 */ 1947 if (ipcp_script_state == s_down && ipcp_script_pid == 0) { 1948 ipcp_script_state = s_up; 1949 ipcp_script(_PATH_IPUP, 0); 1950 } 1951 } 1952 1953 1954 /* 1955 * ipcp_down - IPCP has gone DOWN. 1956 * 1957 * Take the IP network interface down, clear its addresses 1958 * and delete routes through it. 1959 */ 1960 static void 1961 ipcp_down(f) 1962 fsm *f; 1963 { 1964 IPCPDEBUG(("ipcp: down")); 1965 /* XXX a bit IPv4-centric here, we only need to get the stats 1966 * before the interface is marked down. */ 1967 /* XXX more correct: we must get the stats before running the notifiers, 1968 * at least for the radius plugin */ 1969 update_link_stats(f->unit); 1970 notify(ip_down_notifier, 0); 1971 if (ip_down_hook) 1972 ip_down_hook(); 1973 if (ipcp_is_up) { 1974 ipcp_is_up = 0; 1975 np_down(f->unit, PPP_IP); 1976 } 1977 sifvjcomp(f->unit, 0, 0, 0); 1978 1979 print_link_stats(); /* _after_ running the notifiers and ip_down_hook(), 1980 * because print_link_stats() sets link_stats_valid 1981 * to 0 (zero) */ 1982 1983 /* 1984 * If we are doing dial-on-demand, set the interface 1985 * to queue up outgoing packets (for now). 1986 */ 1987 if (demand) { 1988 sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE); 1989 } else { 1990 sifnpmode(f->unit, PPP_IP, NPMODE_DROP); 1991 sifdown(f->unit); 1992 ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr, 1993 ipcp_hisoptions[f->unit].hisaddr); 1994 } 1995 1996 /* Execute the ip-down script */ 1997 if (ipcp_script_state == s_up && ipcp_script_pid == 0) { 1998 ipcp_script_state = s_down; 1999 ipcp_script(_PATH_IPDOWN, 0); 2000 } 2001 } 2002 2003 2004 /* 2005 * ipcp_clear_addrs() - clear the interface addresses, routes, 2006 * proxy arp entries, etc. 2007 */ 2008 static void 2009 ipcp_clear_addrs(unit, ouraddr, hisaddr) 2010 int unit; 2011 u_int32_t ouraddr; /* local address */ 2012 u_int32_t hisaddr; /* remote address */ 2013 { 2014 if (proxy_arp_set[unit]) { 2015 cifproxyarp(unit, hisaddr); 2016 proxy_arp_set[unit] = 0; 2017 } 2018 if (default_route_set[unit]) { 2019 cifdefaultroute(unit, ouraddr, hisaddr); 2020 default_route_set[unit] = 0; 2021 } 2022 cifaddr(unit, ouraddr, hisaddr); 2023 } 2024 2025 2026 /* 2027 * ipcp_finished - possibly shut down the lower layers. 2028 */ 2029 static void 2030 ipcp_finished(f) 2031 fsm *f; 2032 { 2033 if (ipcp_is_open) { 2034 ipcp_is_open = 0; 2035 np_finished(f->unit, PPP_IP); 2036 } 2037 } 2038 2039 2040 /* 2041 * ipcp_script_done - called when the ip-up or ip-down script 2042 * has finished. 2043 */ 2044 static void 2045 ipcp_script_done(arg) 2046 void *arg; 2047 { 2048 ipcp_script_pid = 0; 2049 switch (ipcp_script_state) { 2050 case s_up: 2051 if (ipcp_fsm[0].state != OPENED) { 2052 ipcp_script_state = s_down; 2053 ipcp_script(_PATH_IPDOWN, 0); 2054 } 2055 break; 2056 case s_down: 2057 if (ipcp_fsm[0].state == OPENED) { 2058 ipcp_script_state = s_up; 2059 ipcp_script(_PATH_IPUP, 0); 2060 } 2061 break; 2062 } 2063 } 2064 2065 2066 /* 2067 * ipcp_script - Execute a script with arguments 2068 * interface-name tty-name speed local-IP remote-IP. 2069 */ 2070 static void 2071 ipcp_script(script, wait) 2072 char *script; 2073 int wait; 2074 { 2075 char strspeed[32], strlocal[32], strremote[32]; 2076 char *argv[8]; 2077 2078 slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); 2079 slprintf(strlocal, sizeof(strlocal), "%I", ipcp_gotoptions[0].ouraddr); 2080 slprintf(strremote, sizeof(strremote), "%I", ipcp_hisoptions[0].hisaddr); 2081 2082 argv[0] = script; 2083 argv[1] = ifname; 2084 argv[2] = devnam; 2085 argv[3] = strspeed; 2086 argv[4] = strlocal; 2087 argv[5] = strremote; 2088 argv[6] = ipparam; 2089 argv[7] = NULL; 2090 if (wait) 2091 run_program(script, argv, 0, NULL, NULL, 1); 2092 else 2093 ipcp_script_pid = run_program(script, argv, 0, ipcp_script_done, 2094 NULL, 0); 2095 } 2096 2097 /* 2098 * create_resolv - create the replacement resolv.conf file 2099 */ 2100 static void 2101 create_resolv(peerdns1, peerdns2) 2102 u_int32_t peerdns1, peerdns2; 2103 { 2104 FILE *f; 2105 2106 f = fopen(_PATH_RESOLV, "w"); 2107 if (f == NULL) { 2108 error("Failed to create %s: %m", _PATH_RESOLV); 2109 return; 2110 } 2111 2112 if (peerdns1) 2113 fprintf(f, "nameserver %s\n", ip_ntoa(peerdns1)); 2114 2115 if (peerdns2) 2116 fprintf(f, "nameserver %s\n", ip_ntoa(peerdns2)); 2117 2118 if (ferror(f)) 2119 error("Write failed to %s: %m", _PATH_RESOLV); 2120 2121 fclose(f); 2122 } 2123 2124 /* 2125 * ipcp_printpkt - print the contents of an IPCP packet. 2126 */ 2127 static char *ipcp_codenames[] = { 2128 "ConfReq", "ConfAck", "ConfNak", "ConfRej", 2129 "TermReq", "TermAck", "CodeRej" 2130 }; 2131 2132 static int 2133 ipcp_printpkt(p, plen, printer, arg) 2134 u_char *p; 2135 int plen; 2136 void (*printer) __P((void *, char *, ...)); 2137 void *arg; 2138 { 2139 int code, id, len, olen; 2140 u_char *pstart, *optend; 2141 u_short cishort; 2142 u_int32_t cilong; 2143 2144 if (plen < HEADERLEN) 2145 return 0; 2146 pstart = p; 2147 GETCHAR(code, p); 2148 GETCHAR(id, p); 2149 GETSHORT(len, p); 2150 if (len < HEADERLEN || len > plen) 2151 return 0; 2152 2153 if (code >= 1 && code <= sizeof(ipcp_codenames) / sizeof(char *)) 2154 printer(arg, " %s", ipcp_codenames[code-1]); 2155 else 2156 printer(arg, " code=0x%x", code); 2157 printer(arg, " id=0x%x", id); 2158 len -= HEADERLEN; 2159 switch (code) { 2160 case CONFREQ: 2161 case CONFACK: 2162 case CONFNAK: 2163 case CONFREJ: 2164 /* print option list */ 2165 while (len >= 2) { 2166 GETCHAR(code, p); 2167 GETCHAR(olen, p); 2168 p -= 2; 2169 if (olen < 2 || olen > len) { 2170 break; 2171 } 2172 printer(arg, " <"); 2173 len -= olen; 2174 optend = p + olen; 2175 switch (code) { 2176 case CI_ADDRS: 2177 if (olen == CILEN_ADDRS) { 2178 p += 2; 2179 GETLONG(cilong, p); 2180 printer(arg, "addrs %I", htonl(cilong)); 2181 GETLONG(cilong, p); 2182 printer(arg, " %I", htonl(cilong)); 2183 } 2184 break; 2185 case CI_COMPRESSTYPE: 2186 if (olen >= CILEN_COMPRESS) { 2187 p += 2; 2188 GETSHORT(cishort, p); 2189 printer(arg, "compress "); 2190 switch (cishort) { 2191 case IPCP_VJ_COMP: 2192 printer(arg, "VJ"); 2193 break; 2194 case IPCP_VJ_COMP_OLD: 2195 printer(arg, "old-VJ"); 2196 break; 2197 default: 2198 printer(arg, "0x%x", cishort); 2199 } 2200 } 2201 break; 2202 case CI_ADDR: 2203 if (olen == CILEN_ADDR) { 2204 p += 2; 2205 GETLONG(cilong, p); 2206 printer(arg, "addr %I", htonl(cilong)); 2207 } 2208 break; 2209 case CI_MS_DNS1: 2210 case CI_MS_DNS2: 2211 p += 2; 2212 GETLONG(cilong, p); 2213 printer(arg, "ms-dns%d %I", (code == CI_MS_DNS1? 1: 2), 2214 htonl(cilong)); 2215 break; 2216 case CI_MS_WINS1: 2217 case CI_MS_WINS2: 2218 p += 2; 2219 GETLONG(cilong, p); 2220 printer(arg, "ms-wins %I", htonl(cilong)); 2221 break; 2222 } 2223 while (p < optend) { 2224 GETCHAR(code, p); 2225 printer(arg, " %.2x", code); 2226 } 2227 printer(arg, ">"); 2228 } 2229 break; 2230 2231 case TERMACK: 2232 case TERMREQ: 2233 if (len > 0 && *p >= ' ' && *p < 0x7f) { 2234 printer(arg, " "); 2235 print_string((char *)p, len, printer, arg); 2236 p += len; 2237 len = 0; 2238 } 2239 break; 2240 } 2241 2242 /* print the rest of the bytes in the packet */ 2243 for (; len > 0; --len) { 2244 GETCHAR(code, p); 2245 printer(arg, " %.2x", code); 2246 } 2247 2248 return p - pstart; 2249 } 2250 2251 /* 2252 * ip_active_pkt - see if this IP packet is worth bringing the link up for. 2253 * We don't bring the link up for IP fragments or for TCP FIN packets 2254 * with no data. 2255 */ 2256 #define IP_HDRLEN 20 /* bytes */ 2257 #define IP_OFFMASK 0x1fff 2258 #ifndef IPPROTO_TCP 2259 #define IPPROTO_TCP 6 2260 #endif 2261 #define TCP_HDRLEN 20 2262 #define TH_FIN 0x01 2263 2264 /* 2265 * We use these macros because the IP header may be at an odd address, 2266 * and some compilers might use word loads to get th_off or ip_hl. 2267 */ 2268 2269 #define net_short(x) (((x)[0] << 8) + (x)[1]) 2270 #define get_iphl(x) (((unsigned char *)(x))[0] & 0xF) 2271 #define get_ipoff(x) net_short((unsigned char *)(x) + 6) 2272 #define get_ipproto(x) (((unsigned char *)(x))[9]) 2273 #define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) 2274 #define get_tcpflags(x) (((unsigned char *)(x))[13]) 2275 2276 static int 2277 ip_active_pkt(pkt, len) 2278 u_char *pkt; 2279 int len; 2280 { 2281 u_char *tcp; 2282 int hlen; 2283 2284 len -= PPP_HDRLEN; 2285 pkt += PPP_HDRLEN; 2286 if (len < IP_HDRLEN) 2287 return 0; 2288 if ((get_ipoff(pkt) & IP_OFFMASK) != 0) 2289 return 0; 2290 if (get_ipproto(pkt) != IPPROTO_TCP) 2291 return 1; 2292 hlen = get_iphl(pkt) * 4; 2293 if (len < hlen + TCP_HDRLEN) 2294 return 0; 2295 tcp = pkt + hlen; 2296 if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) 2297 return 0; 2298 return 1; 2299 } 2300