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