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