1 /* 2 * ipcp.c - PPP IP Control Protocol. 3 * 4 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 5 * Use is subject to license terms. 6 * 7 * Copyright (c) 1989 Carnegie Mellon University. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms are permitted 11 * provided that the above copyright notice and this paragraph are 12 * duplicated in all such forms and that any documentation, 13 * advertising materials, and other materials related to such 14 * distribution and use acknowledge that the software was developed 15 * by Carnegie Mellon University. The name of the 16 * University may not be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 20 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 21 */ 22 23 #define RCSID "$Id: ipcp.c,v 1.54 2000/04/15 01:27:11 masputra Exp $" 24 25 /* 26 * TODO: 27 */ 28 29 #include <stdio.h> 30 #include <string.h> 31 #include <netdb.h> 32 #include <sys/param.h> 33 #include <sys/types.h> 34 #include <sys/socket.h> 35 #if defined(_linux_) || defined(__linux__) 36 #define __FAVOR_BSD 37 #endif 38 #include <netinet/in.h> 39 #include <netinet/tcp.h> 40 #include <arpa/inet.h> 41 42 #include "pppd.h" 43 #include "fsm.h" 44 #include "ipcp.h" 45 #include "pathnames.h" 46 47 #if !defined(lint) && !defined(_lint) 48 static const char rcsid[] = RCSID; 49 #endif 50 51 /* global vars */ 52 ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ 53 ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ 54 ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ 55 ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ 56 57 bool ipcp_from_hostname = 0; /* Local IP address is from hostname lookup */ 58 59 /* Hook for a plugin to know when IP protocol has come up */ 60 void (*ip_up_hook) __P((void)) = NULL; 61 62 /* Hook for a plugin to know when IP protocol has come down */ 63 void (*ip_down_hook) __P((void)) = NULL; 64 65 /* local vars */ 66 static bool default_route_set[NUM_PPP]; /* Have set up a default route */ 67 static bool proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */ 68 static bool ipcp_is_up[NUM_PPP]; /* have called np_up() */ 69 static bool proxy_arp_quiet[NUM_PPP]; /* We should be quiet on error */ 70 static bool disable_defaultip = 0; /* Don't use hostname for IP addr */ 71 72 /* 73 * Callbacks for fsm code. (CI = Configuration Information) 74 */ 75 static void ipcp_resetci __P((fsm *)); /* Reset our CI */ 76 static int ipcp_cilen __P((fsm *)); /* Return length of our CI */ 77 static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ 78 static int ipcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ 79 static int ipcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */ 80 static int ipcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ 81 static int ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ 82 static void ipcp_up __P((fsm *)); /* We're UP */ 83 static void ipcp_down __P((fsm *)); /* We're DOWN */ 84 static void ipcp_finished __P((fsm *)); /* Don't need lower layer */ 85 static int setmsservaddr __P((char *, u_int32_t *)); 86 87 fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */ 88 89 static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ 90 ipcp_resetci, /* Reset our Configuration Information */ 91 ipcp_cilen, /* Length of our Configuration Information */ 92 ipcp_addci, /* Add our Configuration Information */ 93 ipcp_ackci, /* ACK our Configuration Information */ 94 ipcp_nakci, /* NAK our Configuration Information */ 95 ipcp_rejci, /* Reject our Configuration Information */ 96 ipcp_reqci, /* Request peer's Configuration Information */ 97 ipcp_up, /* Called when fsm reaches OPENED state */ 98 ipcp_down, /* Called when fsm leaves OPENED state */ 99 NULL, /* Called when we want the lower layer up */ 100 ipcp_finished, /* Called when we want the lower layer down */ 101 NULL, /* Retransmission is necessary */ 102 NULL, /* Called to handle protocol-specific codes */ 103 "IPCP", /* String name of protocol */ 104 NULL /* Peer rejected a code number */ 105 }; 106 107 /* 108 * Command-line options. 109 */ 110 static int setvjslots __P((char **)); 111 static int setdnsaddr __P((char **)); 112 static int setwinsaddr __P((char **)); 113 static int autoproxyarp __P((char **)); 114 115 static option_t ipcp_option_list[] = { 116 { "noip", o_bool, &ipcp_protent.enabled_flag, 117 "Disable IP and IPCP" }, 118 { "-ip", o_bool, &ipcp_protent.enabled_flag, 119 "Disable IP and IPCP" }, 120 { "novj", o_bool, &ipcp_wantoptions[0].neg_vj, 121 "Disable VJ compression", OPT_A2COPY, &ipcp_allowoptions[0].neg_vj }, 122 { "-vj", o_bool, &ipcp_wantoptions[0].neg_vj, 123 "Disable VJ compression", OPT_A2COPY, &ipcp_allowoptions[0].neg_vj }, 124 { "novjccomp", o_bool, &ipcp_wantoptions[0].cflag, 125 "Disable VJ connection-ID compression", OPT_A2COPY, 126 &ipcp_allowoptions[0].cflag }, 127 { "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag, 128 "Disable VJ connection-ID compression", OPT_A2COPY, 129 &ipcp_allowoptions[0].cflag }, 130 { "vj-max-slots", o_special, (void *)setvjslots, 131 "Set maximum VJ header slots" }, 132 { "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local, 133 "Accept peer's address for us", 1 }, 134 { "ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote, 135 "Accept peer's address for it", 1 }, 136 { "ipparam", o_string, &ipparam, 137 "Set ip script parameter" }, 138 { "noipdefault", o_bool, &disable_defaultip, 139 "Don't use name for default IP adrs", 1 }, 140 { "ms-dns", o_special, (void *)setdnsaddr, 141 "DNS address for the peer's use" }, 142 { "ms-wins", o_special, (void *)setwinsaddr, 143 "Nameserver for SMB over TCP/IP for peer" }, 144 { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime, 145 "Set timeout for IPCP" }, 146 { "ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits, 147 "Set max #xmits for term-reqs" }, 148 { "ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits, 149 "Set max #xmits for conf-reqs" }, 150 { "ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops, 151 "Set max #conf-naks for IPCP" }, 152 { "defaultroute", o_bool, &ipcp_wantoptions[0].default_route, 153 "Add default route", OPT_ENABLE|1, &ipcp_allowoptions[0].default_route }, 154 { "nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route, 155 "disable defaultroute option", OPT_A2COPY, 156 &ipcp_wantoptions[0].default_route }, 157 { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route, 158 "disable defaultroute option", OPT_A2COPY, 159 &ipcp_wantoptions[0].default_route }, 160 { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp, 161 "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp }, 162 { "autoproxyarp", o_special_noarg, (void *)autoproxyarp, 163 "Add proxy ARP entry if needed", OPT_ENABLE, 164 &ipcp_allowoptions[0].proxy_arp }, 165 { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, 166 "disable proxyarp option", OPT_A2COPY, &ipcp_wantoptions[0].proxy_arp }, 167 { "-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, 168 "disable proxyarp option", OPT_A2COPY, &ipcp_wantoptions[0].proxy_arp }, 169 { "usepeerdns", o_bool, &ipcp_wantoptions[0].req_dns1, 170 "Ask peer for DNS address(es)", OPT_A2COPY|1, 171 &ipcp_wantoptions[0].req_dns2 }, 172 { NULL } 173 }; 174 175 /* 176 * Protocol entry points from main code. 177 */ 178 static void ipcp_init __P((int)); 179 static void ipcp_open __P((int)); 180 static void ipcp_close __P((int, char *)); 181 static void ipcp_lowerup __P((int)); 182 static void ipcp_lowerdown __P((int)); 183 static void ipcp_input __P((int, u_char *, int)); 184 static void ipcp_protrej __P((int)); 185 static int ipcp_printpkt __P((u_char *, int, 186 void (*) __P((void *, const char *, ...)), void *)); 187 static void ip_check_options __P((void)); 188 static int ip_demand_conf __P((int)); 189 static int ip_active_pkt __P((u_char *, int)); 190 static void ipcp_print_stat __P((int, FILE *)); 191 192 static void create_resolv __P((u_int32_t, u_int32_t)); 193 194 struct protent ipcp_protent = { 195 PPP_IPCP, 196 ipcp_init, 197 ipcp_input, 198 ipcp_protrej, 199 ipcp_lowerup, 200 ipcp_lowerdown, 201 ipcp_open, 202 ipcp_close, 203 ipcp_printpkt, 204 NULL, 205 1, 206 "IPCP", 207 "IP", 208 ipcp_option_list, 209 ip_check_options, 210 ip_demand_conf, 211 ip_active_pkt, 212 ipcp_print_stat 213 }; 214 215 static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t)); 216 static void ipcp_script __P((char *)); /* Run an up/down script */ 217 static void ipcp_script_done __P((void *, int)); 218 219 /* 220 * Lengths of configuration options. 221 */ 222 #define CILEN_VOID 2 223 #define CILEN_COMPRESS 4 /* min length for compression protocol opt. */ 224 #define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */ 225 #define CILEN_ADDR 6 /* new-style single address option */ 226 #define CILEN_ADDRS 10 /* old-style dual address option */ 227 228 229 /* 230 * This state variable is used to ensure that we don't 231 * run an ipcp-up/down script while one is already running. 232 */ 233 static enum script_state { 234 s_down, 235 s_up 236 } ipcp_script_state; 237 static pid_t ipcp_script_pid; 238 239 /* 240 * Make a string representation of a network IP address. 241 */ 242 char * 243 ip_ntoa(ipaddr) 244 u_int32_t ipaddr; 245 { 246 static char b[64]; 247 248 (void) slprintf(b, sizeof(b), "%I", ipaddr); 249 return b; 250 } 251 252 /* 253 * Option parsing. 254 */ 255 256 /* 257 * setvjslots - set maximum number of connection slots for VJ compression 258 */ 259 static int 260 setvjslots(argv) 261 char **argv; 262 { 263 int value; 264 265 if (!int_option(*argv, &value)) 266 return 0; 267 if (value < 2 || value > 16) { 268 option_error("vj-max-slots value must be between 2 and 16"); 269 return 0; 270 } 271 ipcp_wantoptions [0].maxslotindex = 272 ipcp_allowoptions[0].maxslotindex = value - 1; 273 return 1; 274 } 275 276 /* 277 * setmsservaddr - Set the primary and secondary server addresses in the 278 * array. setdnsaddr() and setwinsaddr() call this function with either 279 * dnsaddr[] or winsaddr[] as the serverarray argument. 280 */ 281 static int 282 setmsservaddr(servname, serverarray) 283 char *servname; 284 u_int32_t *serverarray; 285 { 286 u_int32_t addr; 287 struct hostent *hp = NULL; 288 289 addr = inet_addr(servname); 290 if (addr == (u_int32_t) -1) { 291 if ((hp = gethostbyname(servname)) == NULL) 292 return 0; 293 BCOPY(hp->h_addr, &addr, sizeof (u_int32_t)); 294 } 295 296 /* 297 * If there is no primary then this is the first instance of the 298 * option, we must set the primary. In that case, try to set the 299 * secondary to h_addr_list[1]. If the primary is already set, then 300 * this is the second instance of the option, and we must set 301 * the secondary. 302 */ 303 if (serverarray[0] == 0) { 304 serverarray[0] = addr; 305 if (hp != NULL && hp->h_addr_list[1] != NULL) 306 BCOPY(hp->h_addr_list[1], &serverarray[1], sizeof (u_int32_t)); 307 else 308 serverarray[1] = addr; 309 } else { 310 serverarray[1] = addr; 311 } 312 313 return (1); 314 } 315 316 /* 317 * setdnsaddr - set the dns address(es) 318 */ 319 static int 320 setdnsaddr(argv) 321 char **argv; 322 { 323 if (setmsservaddr(*argv, &(ipcp_allowoptions[0].dnsaddr[0])) == 0) { 324 option_error("invalid address parameter '%s' for ms-dns option", *argv); 325 return (0); 326 } 327 328 return (1); 329 } 330 331 /* 332 * setwinsaddr - set the wins address(es) 333 * This is primrarly used with the Samba package under UNIX or for pointing 334 * the caller to the existing WINS server on a Windows NT platform. 335 */ 336 static int 337 setwinsaddr(argv) 338 char **argv; 339 { 340 if (setmsservaddr(*argv, &(ipcp_allowoptions[0].winsaddr[0])) == 0) { 341 option_error("invalid address parameter '%s' for ms-wins option", 342 *argv); 343 return (0); 344 } 345 346 return (1); 347 } 348 349 /* 350 * autoproxyarp -- enable proxy ARP but don't emit error messages if 351 * it's not actually needed. 352 */ 353 /*ARGSUSED*/ 354 static int 355 autoproxyarp(argv) 356 char **argv; 357 { 358 ipcp_wantoptions[0].proxy_arp = 1; 359 proxy_arp_quiet[0] = 1; 360 361 return (1); 362 } 363 364 365 /* 366 * ipcp_init - Initialize IPCP. 367 */ 368 static void 369 ipcp_init(unit) 370 int unit; 371 { 372 fsm *f = &ipcp_fsm[unit]; 373 ipcp_options *wo = &ipcp_wantoptions[unit]; 374 ipcp_options *ao = &ipcp_allowoptions[unit]; 375 376 f->unit = unit; 377 f->protocol = PPP_IPCP; 378 f->callbacks = &ipcp_callbacks; 379 fsm_init(&ipcp_fsm[unit]); 380 381 BZERO(wo, sizeof(*wo)); 382 BZERO(ao, sizeof(*ao)); 383 384 wo->neg_addr = wo->old_addrs = 1; 385 wo->neg_vj = 1; 386 wo->vj_protocol = IPCP_VJ_COMP; 387 wo->maxslotindex = MAX_STATES - 1; /* really max index */ 388 wo->cflag = 1; 389 390 ao->neg_addr = ao->old_addrs = 1; 391 ao->neg_vj = 1; 392 ao->maxslotindex = MAX_STATES - 1; 393 ao->cflag = 1; 394 395 /* 396 * These aren't actually negotiated. Instead, they control 397 * whether the user may use the proxyarp and defaultroute options. 398 */ 399 ao->proxy_arp = 1; 400 ao->default_route = 1; 401 proxy_arp_quiet[unit] = 0; 402 } 403 404 405 /* 406 * ipcp_open - IPCP is allowed to come up. 407 */ 408 static void 409 ipcp_open(unit) 410 int unit; 411 { 412 fsm_open(&ipcp_fsm[unit]); 413 } 414 415 416 /* 417 * ipcp_close - Take IPCP down. 418 */ 419 static void 420 ipcp_close(unit, reason) 421 int unit; 422 char *reason; 423 { 424 fsm_close(&ipcp_fsm[unit], reason); 425 } 426 427 428 /* 429 * ipcp_lowerup - The lower layer is up. 430 */ 431 static void 432 ipcp_lowerup(unit) 433 int unit; 434 { 435 fsm_lowerup(&ipcp_fsm[unit]); 436 } 437 438 439 /* 440 * ipcp_lowerdown - The lower layer is down. 441 */ 442 static void 443 ipcp_lowerdown(unit) 444 int unit; 445 { 446 fsm_lowerdown(&ipcp_fsm[unit]); 447 } 448 449 450 /* 451 * ipcp_input - Input IPCP packet. 452 */ 453 static void 454 ipcp_input(unit, p, len) 455 int unit; 456 u_char *p; 457 int len; 458 { 459 fsm_input(&ipcp_fsm[unit], p, len); 460 } 461 462 463 /* 464 * ipcp_protrej - A Protocol-Reject was received for IPCP. 465 */ 466 static void 467 ipcp_protrej(unit) 468 int unit; 469 { 470 fsm_protreject(&ipcp_fsm[unit]); 471 } 472 473 474 /* 475 * ipcp_resetci - Reset our CI. 476 * Called by fsm_sconfreq, Send Configure Request. 477 */ 478 static void 479 ipcp_resetci(f) 480 fsm *f; 481 { 482 ipcp_options *wo = &ipcp_wantoptions[f->unit]; 483 ipcp_options *go = &ipcp_gotoptions[f->unit]; 484 ipcp_options *ao = &ipcp_allowoptions[f->unit]; 485 486 wo->req_addr = (wo->neg_addr || wo->old_addrs) && 487 (ao->neg_addr || ao->old_addrs); 488 if (wo->ouraddr == 0 || disable_defaultip) 489 wo->accept_local = 1; 490 if (wo->hisaddr == 0) 491 wo->accept_remote = 1; 492 *go = *wo; 493 if (disable_defaultip) 494 go->ouraddr = 0; 495 } 496 497 498 /* 499 * ipcp_cilen - Return length of our CI. 500 * Called by fsm_sconfreq, Send Configure Request. 501 */ 502 static int 503 ipcp_cilen(f) 504 fsm *f; 505 { 506 ipcp_options *go = &ipcp_gotoptions[f->unit]; 507 ipcp_options *wo = &ipcp_wantoptions[f->unit]; 508 ipcp_options *ho = &ipcp_hisoptions[f->unit]; 509 510 #define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0) 511 #define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) 512 #define LENCIADDR(neg) (neg ? (CILEN_ADDR) : 0) 513 514 /* 515 * First see if we want to change our options to the old 516 * forms because we have received old forms from the peer. 517 */ 518 if (go->neg_addr && go->old_addrs && !ho->neg_addr && ho->old_addrs) 519 /* use the old style of address negotiation */ 520 go->neg_addr = 0; 521 if (wo->neg_vj && !go->neg_vj && !go->old_vj) { 522 /* try an older style of VJ negotiation */ 523 /* use the old style only if the peer did */ 524 if (ho->neg_vj && ho->old_vj) { 525 go->neg_vj = 1; 526 go->old_vj = 1; 527 go->vj_protocol = ho->vj_protocol; 528 } 529 } 530 531 return (LENCIADDRS(!go->neg_addr && go->old_addrs) + 532 LENCIVJ(go->neg_vj, go->old_vj) + 533 LENCIADDR(go->neg_addr) + 534 LENCIADDR(go->req_dns1) + 535 LENCIADDR(go->req_dns2)) ; 536 } 537 538 539 /* 540 * ipcp_addci - Add our desired CIs to a packet. 541 * Called by fsm_sconfreq, Send Configure Request. 542 */ 543 static void 544 ipcp_addci(f, ucp, lenp) 545 fsm *f; 546 u_char *ucp; 547 int *lenp; 548 { 549 ipcp_options *go = &ipcp_gotoptions[f->unit]; 550 int len = *lenp; 551 552 #define ADDCIADDRS(opt, neg, val1, val2) \ 553 if (neg) { \ 554 if (len >= CILEN_ADDRS) { \ 555 PUTCHAR(opt, ucp); \ 556 PUTCHAR(CILEN_ADDRS, ucp); \ 557 PUTNLONG(val1, ucp); \ 558 PUTNLONG(val2, ucp); \ 559 len -= CILEN_ADDRS; \ 560 } else \ 561 go->old_addrs = 0; \ 562 } 563 564 #define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \ 565 if (neg) { \ 566 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ 567 if (len >= vjlen) { \ 568 PUTCHAR(opt, ucp); \ 569 PUTCHAR(vjlen, ucp); \ 570 PUTSHORT(val, ucp); \ 571 if (!old) { \ 572 PUTCHAR(maxslotindex, ucp); \ 573 PUTCHAR(cflag, ucp); \ 574 } \ 575 len -= vjlen; \ 576 } else \ 577 neg = 0; \ 578 } 579 580 #define ADDCIADDR(opt, neg, val) \ 581 if (neg) { \ 582 if (len >= CILEN_ADDR) { \ 583 PUTCHAR(opt, ucp); \ 584 PUTCHAR(CILEN_ADDR, ucp); \ 585 PUTNLONG(val, ucp); \ 586 len -= CILEN_ADDR; \ 587 } else \ 588 neg = 0; \ 589 } 590 591 ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, 592 go->hisaddr); 593 594 ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, 595 go->maxslotindex, go->cflag); 596 597 ADDCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); 598 599 ADDCIADDR(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); 600 601 ADDCIADDR(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); 602 603 *lenp -= len; 604 } 605 606 607 /* 608 * ipcp_ackci - Ack our CIs. 609 * Called by fsm_rconfack, Receive Configure ACK. 610 * 611 * Returns: 612 * 0 - Ack was bad. 613 * 1 - Ack was good. 614 */ 615 static int 616 ipcp_ackci(f, p, len) 617 fsm *f; 618 u_char *p; 619 int len; 620 { 621 ipcp_options *go = &ipcp_gotoptions[f->unit]; 622 u_short cilen, citype, cishort; 623 u_int32_t cilong; 624 u_char cimaxslotindex, cicflag; 625 626 /* 627 * CIs must be in exactly the same order that we sent... 628 * Check packet length and CI length at each step. 629 * If we find any deviations, then this packet is bad. 630 */ 631 632 #define ACKCHECK(opt, olen) \ 633 if ((len -= olen) < 0) \ 634 goto bad; \ 635 GETCHAR(citype, p); \ 636 GETCHAR(cilen, p); \ 637 if (cilen != olen || \ 638 citype != opt) \ 639 goto bad; 640 641 #define ACKCIADDRS(opt, neg, val1, val2) \ 642 if (neg) { \ 643 ACKCHECK(opt, CILEN_ADDRS) \ 644 GETNLONG(cilong, p); \ 645 if (val1 != cilong) \ 646 goto bad; \ 647 GETNLONG(cilong, p); \ 648 if (val2 != cilong) \ 649 goto bad; \ 650 } 651 652 #define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \ 653 if (neg) { \ 654 int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ 655 ACKCHECK(opt, vjlen) \ 656 GETSHORT(cishort, p); \ 657 if (cishort != val) \ 658 goto bad; \ 659 if (!old) { \ 660 GETCHAR(cimaxslotindex, p); \ 661 if (cimaxslotindex != maxslotindex) \ 662 goto bad; \ 663 GETCHAR(cicflag, p); \ 664 if (cicflag != cflag) \ 665 goto bad; \ 666 } \ 667 } 668 669 #define ACKCIADDR(opt, neg, val) \ 670 if (neg) { \ 671 ACKCHECK(opt, CILEN_ADDR) \ 672 GETNLONG(cilong, p); \ 673 if (val != cilong) \ 674 goto bad; \ 675 } 676 677 ACKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, 678 go->hisaddr); 679 680 ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, 681 go->maxslotindex, go->cflag); 682 683 ACKCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); 684 685 ACKCIADDR(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); 686 687 ACKCIADDR(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); 688 689 /* 690 * If there are any remaining CIs, then this packet is bad. 691 */ 692 if (len != 0) 693 goto bad; 694 return (1); 695 696 bad: 697 IPCPDEBUG(("ipcp_ackci: received bad Ack!")); 698 return (0); 699 } 700 701 /* 702 * ipcp_nakci - Peer has sent a NAK for some of our CIs. 703 * This should not modify any state if the Nak is bad 704 * or if IPCP is in the OPENED state. 705 * Calback from fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. 706 * 707 * Returns: 708 * 0 - Nak was bad. 709 * 1 - Nak was good. 710 */ 711 static int 712 ipcp_nakci(f, p, len) 713 fsm *f; 714 u_char *p; 715 int len; 716 { 717 ipcp_options *go = &ipcp_gotoptions[f->unit]; 718 u_char cimaxslotindex, cicflag; 719 u_char citype, cilen, *next; 720 u_short cishort; 721 u_int32_t ciaddr1, ciaddr2; 722 ipcp_options no; /* options we've seen Naks for */ 723 ipcp_options try; /* options to request next time */ 724 725 BZERO(&no, sizeof(no)); 726 try = *go; 727 728 /* 729 * Any Nak'd CIs must be in exactly the same order that we sent. 730 * Check packet length and CI length at each step. 731 * If we find any deviations, then this packet is bad. 732 */ 733 #define NAKCIADDRS(opt, neg, code) \ 734 if ((neg) && \ 735 (cilen = p[1]) == CILEN_ADDRS && \ 736 len >= cilen && \ 737 p[0] == opt) { \ 738 len -= cilen; \ 739 INCPTR(2, p); \ 740 GETNLONG(ciaddr1, p); \ 741 GETNLONG(ciaddr2, p); \ 742 no.old_addrs = 1; \ 743 code \ 744 } 745 746 #define NAKCIVJ(opt, neg, code) \ 747 if (go->neg && \ 748 ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \ 749 len >= cilen && \ 750 p[0] == opt) { \ 751 len -= cilen; \ 752 INCPTR(2, p); \ 753 GETSHORT(cishort, p); \ 754 no.neg = 1; \ 755 code \ 756 } 757 758 #define NAKCIADDR(opt, neg, code) \ 759 if (go->neg && \ 760 (cilen = p[1]) == CILEN_ADDR && \ 761 len >= cilen && \ 762 p[0] == opt) { \ 763 len -= cilen; \ 764 INCPTR(2, p); \ 765 GETNLONG(ciaddr1, p); \ 766 no.neg = 1; \ 767 code \ 768 } 769 770 /* 771 * Accept the peer's idea of {our,his} address, if different 772 * from our idea, only if the accept_{local,remote} flag is set. 773 */ 774 NAKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, 775 if (go->accept_local && ciaddr1) { /* Do we know our address? */ 776 try.ouraddr = ciaddr1; 777 } 778 if (go->accept_remote && ciaddr2) { /* Does he know his? */ 779 try.hisaddr = ciaddr2; 780 } 781 ); 782 783 /* 784 * Accept the peer's value of maxslotindex provided that it 785 * is less than what we asked for. Turn off slot-ID compression 786 * if the peer wants. Send old-style compress-type option if 787 * the peer wants. 788 */ 789 NAKCIVJ(CI_COMPRESSTYPE, neg_vj, 790 if (cilen == CILEN_VJ) { 791 GETCHAR(cimaxslotindex, p); 792 GETCHAR(cicflag, p); 793 if (cishort == IPCP_VJ_COMP) { 794 try.old_vj = 0; 795 if (cimaxslotindex < go->maxslotindex) 796 try.maxslotindex = cimaxslotindex; 797 if (!cicflag) 798 try.cflag = 0; 799 } else { 800 try.neg_vj = 0; 801 } 802 } else { 803 if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) { 804 try.old_vj = 1; 805 try.vj_protocol = cishort; 806 } else { 807 try.neg_vj = 0; 808 } 809 } 810 ); 811 812 NAKCIADDR(CI_ADDR, neg_addr, 813 if (go->accept_local && ciaddr1) { /* Do we know our address? */ 814 try.ouraddr = ciaddr1; 815 } 816 ); 817 818 NAKCIADDR(CI_MS_DNS1, req_dns1, 819 try.dnsaddr[0] = ciaddr1; 820 ); 821 822 NAKCIADDR(CI_MS_DNS2, req_dns2, 823 try.dnsaddr[1] = ciaddr1; 824 ); 825 826 /* 827 * There may be remaining CIs, if the peer is requesting negotiation 828 * on an option that we didn't include in our request packet. 829 * If they want to negotiate about IP addresses, we comply. 830 * If they want us to ask for compression, we refuse. 831 */ 832 while (len > CILEN_VOID) { 833 GETCHAR(citype, p); 834 GETCHAR(cilen, p); 835 if( (len -= cilen) < 0 ) 836 goto bad; 837 next = p + cilen - 2; 838 839 switch (citype) { 840 case CI_COMPRESSTYPE: 841 if (go->neg_vj || no.neg_vj || 842 (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) 843 goto bad; 844 no.neg_vj = 1; 845 break; 846 case CI_ADDRS: 847 if ((!go->neg_addr && go->old_addrs) || no.old_addrs 848 || cilen != CILEN_ADDRS) 849 goto bad; 850 try.neg_addr = 1; 851 try.old_addrs = 1; 852 GETNLONG(ciaddr1, p); 853 if (ciaddr1 && go->accept_local) 854 try.ouraddr = ciaddr1; 855 GETNLONG(ciaddr2, p); 856 if (ciaddr2 && go->accept_remote) 857 try.hisaddr = ciaddr2; 858 no.old_addrs = 1; 859 break; 860 case CI_ADDR: 861 if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) 862 goto bad; 863 try.old_addrs = 0; 864 GETNLONG(ciaddr1, p); 865 if (ciaddr1 && go->accept_local) 866 try.ouraddr = ciaddr1; 867 if (try.ouraddr != 0) 868 try.neg_addr = 1; 869 no.neg_addr = 1; 870 break; 871 } 872 p = next; 873 } 874 875 /* 876 * OK, the Nak is good. Now we can update state. 877 * If there are any remaining options, we ignore them. 878 */ 879 if (f->state != OPENED) 880 *go = try; 881 882 return 1; 883 884 bad: 885 IPCPDEBUG(("ipcp_nakci: received bad Nak!")); 886 return 0; 887 } 888 889 890 /* 891 * ipcp_rejci - Reject some of our CIs. 892 * Callback from fsm_rconfnakrej. 893 */ 894 static int 895 ipcp_rejci(f, p, len) 896 fsm *f; 897 u_char *p; 898 int len; 899 { 900 ipcp_options *go = &ipcp_gotoptions[f->unit]; 901 u_char cimaxslotindex, ciflag, cilen; 902 u_short cishort; 903 u_int32_t cilong; 904 ipcp_options try; /* options to request next time */ 905 906 try = *go; 907 /* 908 * Any Rejected CIs must be in exactly the same order that we sent. 909 * Check packet length and CI length at each step. 910 * If we find any deviations, then this packet is bad. 911 */ 912 #define REJCIADDRS(opt, neg, val1, val2) \ 913 if ((neg) && \ 914 (cilen = p[1]) == CILEN_ADDRS && \ 915 len >= cilen && \ 916 p[0] == opt) { \ 917 len -= cilen; \ 918 INCPTR(2, p); \ 919 GETNLONG(cilong, p); \ 920 /* Check rejected value. */ \ 921 if (cilong != val1) \ 922 goto bad; \ 923 GETNLONG(cilong, p); \ 924 /* Check rejected value. */ \ 925 if (cilong != val2) \ 926 goto bad; \ 927 try.old_addrs = 0; \ 928 } 929 930 #define REJCIVJ(opt, neg, val, old, maxslot, cflag) \ 931 if (go->neg && \ 932 p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \ 933 len >= p[1] && \ 934 p[0] == opt) { \ 935 len -= p[1]; \ 936 INCPTR(2, p); \ 937 GETSHORT(cishort, p); \ 938 /* Check rejected value. */ \ 939 if (cishort != val) \ 940 goto bad; \ 941 if (!old) { \ 942 GETCHAR(cimaxslotindex, p); \ 943 if (cimaxslotindex != maxslot) \ 944 goto bad; \ 945 GETCHAR(ciflag, p); \ 946 if (ciflag != cflag) \ 947 goto bad; \ 948 } \ 949 try.neg = 0; \ 950 } 951 952 #define REJCIADDR(opt, neg, addr) \ 953 if (go->neg && \ 954 ((cilen = p[1]) == CILEN_ADDR) && \ 955 len >= cilen && \ 956 p[0] == opt) { \ 957 len -= cilen; \ 958 INCPTR(2, p); \ 959 GETNLONG(cilong, p); \ 960 /* Check rejected value. */ \ 961 if (cilong != addr) \ 962 goto bad; \ 963 try.neg = 0; \ 964 } 965 966 REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, 967 go->ouraddr, go->hisaddr); 968 969 REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, 970 go->maxslotindex, go->cflag); 971 972 REJCIADDR(CI_ADDR, neg_addr, go->ouraddr); 973 974 REJCIADDR(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); 975 976 REJCIADDR(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); 977 978 /* 979 * If there are any remaining CIs, then this packet is bad. 980 */ 981 if (len != 0) 982 goto bad; 983 /* 984 * Now we can update state. 985 */ 986 if (f->state != OPENED) 987 *go = try; 988 return 1; 989 990 bad: 991 IPCPDEBUG(("ipcp_rejci: received bad Reject!")); 992 return 0; 993 } 994 995 996 /* 997 * ipcp_reqci - Check the peer's requested CIs and send appropriate response. 998 * Callback from fsm_rconfreq, Receive Configure Request 999 * 1000 * Returns: CODE_CONFACK, CODE_CONFNAK or CODE_CONFREJ and input 1001 * packet modified appropriately. If reject_if_disagree is non-zero, 1002 * doesn't return CODE_CONFNAK; returns CODE_CONFREJ if it can't 1003 * return CODE_CONFACK. 1004 */ 1005 static int 1006 ipcp_reqci(f, p, lenp, dont_nak) 1007 fsm *f; 1008 u_char *p; /* Requested CIs */ 1009 int *lenp; /* Length of requested CIs */ 1010 bool dont_nak; 1011 { 1012 ipcp_options *wo = &ipcp_wantoptions[f->unit]; 1013 ipcp_options *ho = &ipcp_hisoptions[f->unit]; 1014 ipcp_options *ao = &ipcp_allowoptions[f->unit]; 1015 ipcp_options *go = &ipcp_gotoptions[f->unit]; 1016 int ret, newret; 1017 u_char *p0, *nakp, *rejp, *prev; 1018 u_short cishort; 1019 int len, cilen, type; 1020 u_int32_t tl, ciaddr1, ciaddr2; /* Parsed address values */ 1021 u_char maxslotindex, cflag; 1022 int d; 1023 1024 ret = CODE_CONFACK; 1025 rejp = p0 = p; 1026 nakp = nak_buffer; 1027 1028 /* 1029 * Reset all his options. 1030 */ 1031 BZERO(ho, sizeof(*ho)); 1032 1033 /* 1034 * Process all his options. 1035 */ 1036 for (len = *lenp; len > 0; len -= cilen, p = prev + cilen) { 1037 if ((len < 2) || p[1] > len) { 1038 /* 1039 * RFC 1661 page 40 -- if the option extends beyond the 1040 * packet, then discard the entire packet. 1041 */ 1042 return (0); 1043 } 1044 1045 newret = CODE_CONFACK; 1046 prev = p; 1047 GETCHAR(type, p); 1048 GETCHAR(cilen, p); 1049 1050 switch (type) { /* Check CI type */ 1051 case CI_ADDRS: 1052 if (!ao->old_addrs || ho->neg_addr) { 1053 newret = CODE_CONFREJ; 1054 break; 1055 } 1056 1057 if (cilen != CILEN_ADDRS) { 1058 /* 1059 * rfc1661, page 40 -- a recongnized option with an 1060 * invalid length should be Nak'ed. 1061 */ 1062 newret = CODE_CONFNAK; 1063 ciaddr1 = wo->hisaddr; 1064 ciaddr2 = wo->ouraddr; 1065 } else { 1066 1067 /* 1068 * If he has no address, or if we both have his 1069 * address but disagree about it, then NAK it with our 1070 * idea. In particular, if we don't know his address, 1071 * but he does, then accept it. 1072 */ 1073 GETNLONG(ciaddr1, p); 1074 if (ciaddr1 != wo->hisaddr && 1075 (ciaddr1 == 0 || !wo->accept_remote)) { 1076 newret = CODE_CONFNAK; 1077 ciaddr1 = wo->hisaddr; 1078 } else if (ciaddr1 == 0 && wo->hisaddr == 0) { 1079 /* 1080 * If neither we nor he knows his address, reject 1081 * the option. 1082 */ 1083 newret = CODE_CONFREJ; 1084 wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ 1085 break; 1086 } else if (ciaddr1 != 0) { 1087 go->hisaddr = ciaddr1; 1088 } 1089 1090 /* 1091 * If he doesn't know our address, or if we both have 1092 * our address * but disagree about it, then NAK it 1093 * with our idea. 1094 */ 1095 GETNLONG(ciaddr2, p); 1096 if (ciaddr2 != wo->ouraddr) { 1097 if (ciaddr2 == 0 || !wo->accept_local) { 1098 newret = CODE_CONFNAK; 1099 ciaddr2 = wo->ouraddr; 1100 } else { 1101 go->ouraddr = ciaddr2; /* accept peer's idea */ 1102 } 1103 } 1104 } 1105 1106 if (newret == CODE_CONFNAK) { 1107 PUTCHAR(type, nakp); 1108 PUTCHAR(CILEN_ADDRS, nakp); 1109 PUTNLONG(ciaddr1, nakp); 1110 PUTNLONG(ciaddr2, nakp); 1111 } 1112 1113 ho->old_addrs = 1; 1114 ho->hisaddr = ciaddr1; 1115 ho->ouraddr = ciaddr2; 1116 break; 1117 1118 case CI_ADDR: 1119 if (!ao->neg_addr || ho->old_addrs) { 1120 newret = CODE_CONFREJ; 1121 break; 1122 } 1123 1124 if (cilen != CILEN_ADDR) { 1125 /* 1126 * rfc1661, page 40 -- a recongnized option with an 1127 * invalid length should be Nak'ed. 1128 */ 1129 newret = CODE_CONFNAK; 1130 ciaddr1 = wo->hisaddr; 1131 } else { 1132 1133 /* 1134 * If he has no address, or if we both have his 1135 * address but disagree about it, then NAK it with our 1136 * idea. In particular, if we don't know his address, 1137 * but he does, then accept it. 1138 */ 1139 GETNLONG(ciaddr1, p); 1140 if (ciaddr1 != wo->hisaddr && 1141 (ciaddr1 == 0 || !wo->accept_remote)) { 1142 newret = CODE_CONFNAK; 1143 ciaddr1 = wo->hisaddr; 1144 } else if (ciaddr1 == 0 && wo->hisaddr == 0 && 1145 wo->default_route != 0) { 1146 newret = CODE_CONFNAK; 1147 /* 1148 * If this is a dialup line (default_route is 1149 * set), and neither side knows about his address, 1150 * suggest an arbitrary rfc1918 address. 1151 */ 1152 ciaddr1 = htonl(0xc0a80101 + ifunit); 1153 dbglog("Peer address unknown; suggesting %I", ciaddr1); 1154 } else if (ciaddr1 == 0 && wo->hisaddr == 0) { 1155 /* 1156 * If this is not a dialup line, don't ACK an 1157 * address of 0.0.0.0 - reject it instead. 1158 */ 1159 newret = CODE_CONFREJ; 1160 wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ 1161 break; 1162 } 1163 } 1164 1165 if (newret == CODE_CONFNAK) { 1166 PUTCHAR(type, nakp); 1167 PUTCHAR(CILEN_ADDR, nakp); 1168 PUTNLONG(ciaddr1, nakp); 1169 } 1170 1171 ho->neg_addr = 1; 1172 ho->hisaddr = ciaddr1; 1173 break; 1174 1175 case CI_MS_DNS1: 1176 case CI_MS_DNS2: 1177 /* Warning -- these options work backwards. */ 1178 /* Microsoft primary or secondary DNS request */ 1179 d = (type == CI_MS_DNS2 ? 1 : 0); 1180 1181 if (ao->dnsaddr[d] == 0) { 1182 newret = CODE_CONFREJ; 1183 break; 1184 } 1185 1186 if (cilen != CILEN_ADDR) { 1187 newret = CODE_CONFNAK; 1188 } else { 1189 GETNLONG(tl, p); 1190 if (tl != ao->dnsaddr[d]) { 1191 newret = CODE_CONFNAK; 1192 } 1193 } 1194 1195 if (newret == CODE_CONFNAK) { 1196 PUTCHAR(type, nakp); 1197 PUTCHAR(CILEN_ADDR, nakp); 1198 PUTNLONG(ao->dnsaddr[d], nakp); 1199 } 1200 break; 1201 1202 case CI_MS_WINS1: 1203 case CI_MS_WINS2: 1204 /* Warning -- these options work backwards. */ 1205 /* Microsoft primary or secondary WINS request */ 1206 d = (type == CI_MS_WINS2 ? 1 : 0); 1207 1208 if (ao->winsaddr[d] == 0) { 1209 newret = CODE_CONFREJ; 1210 break; 1211 } 1212 1213 if (cilen != CILEN_ADDR) { 1214 newret = CODE_CONFNAK; 1215 } else { 1216 GETNLONG(tl, p); 1217 if (tl != ao->winsaddr[d]) { 1218 newret = CODE_CONFNAK; 1219 } 1220 } 1221 1222 if (newret == CODE_CONFNAK) { 1223 PUTCHAR(type, nakp); 1224 PUTCHAR(CILEN_ADDR, nakp); 1225 PUTNLONG(ao->winsaddr[d], nakp); 1226 } 1227 break; 1228 1229 case CI_COMPRESSTYPE: 1230 if (!ao->neg_vj) { 1231 newret = CODE_CONFREJ; 1232 break; 1233 } 1234 1235 maxslotindex = ao->maxslotindex; 1236 cflag = ao->cflag; 1237 if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) { 1238 newret = CODE_CONFNAK; 1239 cishort = IPCP_VJ_COMP; 1240 } else { 1241 GETSHORT(cishort, p); 1242 if (cishort != IPCP_VJ_COMP && 1243 (cishort != IPCP_VJ_COMP_OLD || cilen != CILEN_COMPRESS)) { 1244 newret = CODE_CONFNAK; 1245 cishort = IPCP_VJ_COMP; 1246 } else if (cilen == CILEN_VJ) { 1247 GETCHAR(maxslotindex, p); 1248 if (maxslotindex > ao->maxslotindex) { 1249 newret = CODE_CONFNAK; 1250 maxslotindex = ao->maxslotindex; 1251 } 1252 GETCHAR(cflag, p); 1253 if (cflag != 0 && ao->cflag == 0) { 1254 newret = CODE_CONFNAK; 1255 cflag = 0; 1256 } 1257 } else { 1258 ho->old_vj = 1; 1259 maxslotindex = MAX_STATES - 1; 1260 cflag = 1; 1261 } 1262 } 1263 1264 if (newret == CODE_CONFNAK) { 1265 PUTCHAR(type, nakp); 1266 if (cishort == IPCP_VJ_COMP) { 1267 PUTCHAR(CILEN_VJ, nakp); 1268 PUTSHORT(cishort, nakp); 1269 PUTCHAR(maxslotindex, nakp); 1270 PUTCHAR(cflag, nakp); 1271 } else { 1272 PUTCHAR(CILEN_COMPRESS, nakp); 1273 PUTSHORT(cishort, nakp); 1274 } 1275 } 1276 ho->neg_vj = 1; 1277 ho->vj_protocol = cishort; 1278 ho->maxslotindex = maxslotindex; 1279 ho->cflag = cflag; 1280 break; 1281 1282 default: 1283 newret = CODE_CONFREJ; 1284 break; 1285 } 1286 1287 /* Cope with confused peers. */ 1288 if (cilen < 2) 1289 cilen = 2; 1290 1291 /* 1292 * If this is an Ack'able CI, but we're sending back a Nak, 1293 * don't include this CI. 1294 */ 1295 if (newret == CODE_CONFACK && ret != CODE_CONFACK) 1296 continue; 1297 1298 if (newret == CODE_CONFNAK) { 1299 if (dont_nak) { 1300 newret = CODE_CONFREJ; 1301 } else { 1302 /* Ignore subsequent Nak'able things if rejecting. */ 1303 if (ret == CODE_CONFREJ) 1304 continue; 1305 ret = CODE_CONFNAK; 1306 } 1307 } 1308 1309 if (newret == CODE_CONFREJ) { 1310 ret = CODE_CONFREJ; 1311 if (prev != rejp) 1312 BCOPY(prev, rejp, cilen); 1313 rejp += cilen; 1314 } 1315 } 1316 1317 /* 1318 * If we aren't rejecting this packet, and we want to negotiate 1319 * their address, and they didn't send their address, then we 1320 * send a NAK with a CI_ADDR option appended. We assume the 1321 * input buffer is long enough that we can append the extra 1322 * option safely. 1323 */ 1324 if (ret != CODE_CONFREJ && !ho->neg_addr && !ho->old_addrs && 1325 wo->req_addr && !dont_nak) { 1326 if (ret == CODE_CONFACK) 1327 wo->req_addr = 0; /* don't ask again */ 1328 ret = CODE_CONFNAK; 1329 PUTCHAR(CI_ADDR, nakp); 1330 PUTCHAR(CILEN_ADDR, nakp); 1331 PUTNLONG(wo->hisaddr, nakp); 1332 } 1333 1334 switch (ret) { 1335 case CODE_CONFACK: 1336 *lenp = p - p0; 1337 sys_block_proto(PPP_IP); 1338 break; 1339 case CODE_CONFNAK: 1340 *lenp = nakp - nak_buffer; 1341 BCOPY(nak_buffer, p0, *lenp); 1342 break; 1343 case CODE_CONFREJ: 1344 *lenp = rejp - p0; 1345 break; 1346 } 1347 1348 return (ret); /* Return final code */ 1349 } 1350 1351 1352 /* 1353 * ip_check_options - check that any IP-related options are OK, 1354 * and assign appropriate defaults. 1355 */ 1356 static void 1357 ip_check_options() 1358 { 1359 struct hostent *hp; 1360 u_int32_t local; 1361 ipcp_options *wo = &ipcp_wantoptions[0]; 1362 1363 /* 1364 * Default our local IP address based on our hostname. 1365 * If local IP address already given, don't bother. 1366 */ 1367 if (wo->ouraddr == 0) { 1368 /* 1369 * Look up our hostname (possibly with domain name appended) 1370 * and take the first IP address as our local IP address. 1371 * If there isn't an IP address for our hostname, too bad. 1372 */ 1373 wo->accept_local = 1; /* don't insist on this default value */ 1374 if ((hp = gethostbyname(hostname)) != NULL) { 1375 BCOPY(hp->h_addr, &local, sizeof (hp->h_addr)); 1376 if (local != 0 && !bad_ip_adrs(local)) { 1377 wo->ouraddr = local; 1378 ipcp_from_hostname = 1; 1379 } 1380 } 1381 } 1382 } 1383 1384 1385 /* 1386 * ip_demand_conf - configure the interface as though 1387 * IPCP were up, for use with dial-on-demand. 1388 */ 1389 static int 1390 ip_demand_conf(u) 1391 int u; 1392 { 1393 ipcp_options *wo = &ipcp_wantoptions[u]; 1394 1395 if (wo->hisaddr == 0) { 1396 /* make up an arbitrary address for the peer */ 1397 wo->hisaddr = htonl(0x0a707070 + ifunit); 1398 wo->accept_remote = 1; 1399 } 1400 if (wo->ouraddr == 0) { 1401 /* make up an arbitrary address for us */ 1402 wo->ouraddr = htonl(0x0a404040 + ifunit); 1403 wo->accept_local = 1; 1404 disable_defaultip = 1; /* don't tell the peer this address */ 1405 } 1406 if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr))) 1407 return 0; 1408 if (!sifup(u)) 1409 return 0; 1410 if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE)) 1411 return 0; 1412 if (wo->default_route && sifdefaultroute(u, wo->ouraddr, wo->hisaddr)) 1413 default_route_set[u] = 1; 1414 if (wo->proxy_arp && sifproxyarp(u, wo->hisaddr, proxy_arp_quiet[u])) 1415 proxy_arp_set[u] = 1; 1416 1417 notice("local IP address %I", wo->ouraddr); 1418 notice("remote IP address %I", wo->hisaddr); 1419 1420 return 1; 1421 } 1422 1423 1424 /* 1425 * ipcp_up - IPCP has come UP. 1426 * 1427 * Configure the IP network interface appropriately and bring it up. 1428 */ 1429 static void 1430 ipcp_up(f) 1431 fsm *f; 1432 { 1433 u_int32_t mask; 1434 ipcp_options *ho = &ipcp_hisoptions[f->unit]; 1435 ipcp_options *go = &ipcp_gotoptions[f->unit]; 1436 ipcp_options *wo = &ipcp_wantoptions[f->unit]; 1437 1438 IPCPDEBUG(("ipcp: up")); 1439 1440 /* 1441 * We must have a non-zero IP address for both ends of the link. 1442 */ 1443 if (ho->hisaddr == 0) 1444 ho->hisaddr = wo->hisaddr; 1445 1446 if (ho->hisaddr == 0) { 1447 if (wo->accept_remote) { 1448 /* Pick some rfc1918 address. */ 1449 ho->hisaddr = htonl(0xc0a80101 + ifunit); 1450 dbglog("Peer refused to provide his address; assuming %I", 1451 ho->hisaddr); 1452 } else { 1453 error("Could not determine remote IP address"); 1454 ipcp_close(f->unit, "Could not determine remote IP address"); 1455 return; 1456 } 1457 } 1458 if (go->ouraddr == 0) { 1459 error("Could not determine local IP address"); 1460 ipcp_close(f->unit, "Could not determine local IP address"); 1461 return; 1462 } 1463 script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0); 1464 script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1); 1465 1466 /* 1467 * Check that the peer is allowed to use the IP address it wants. 1468 */ 1469 if (!auth_ip_addr(f->unit, ho->hisaddr)) { 1470 error("Peer is not authorized to use remote address %I", ho->hisaddr); 1471 ipcp_close(f->unit, "Unauthorized remote IP address"); 1472 return; 1473 } 1474 1475 if ((go->req_dns1 && go->dnsaddr[0] != 0) || 1476 (go->req_dns2 && go->dnsaddr[1] != 0)) { 1477 script_setenv("USEPEERDNS", "1", 0); 1478 if (go->dnsaddr[0] != 0) 1479 script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0); 1480 if (go->dnsaddr[1] != 0) 1481 script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0); 1482 create_resolv(go->dnsaddr[0], go->dnsaddr[1]); 1483 } 1484 1485 /* set tcp compression */ 1486 if (sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex) != 1) { 1487 ipcp_close(f->unit, "Could not enable VJ TCP header compression"); 1488 return; 1489 } 1490 1491 /* 1492 * If we are doing dial-on-demand, the interface is already 1493 * configured, so we put out any saved-up packets, then set the 1494 * interface to pass IP packets. 1495 */ 1496 if (demand) { 1497 if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) { 1498 ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr); 1499 if (go->ouraddr != wo->ouraddr) { 1500 warn("Local IP address changed to %I", go->ouraddr); 1501 script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0); 1502 wo->ouraddr = go->ouraddr; 1503 } else 1504 script_unsetenv("OLDIPLOCAL"); 1505 if (ho->hisaddr != wo->hisaddr) { 1506 warn("Remote IP address changed to %I", ho->hisaddr); 1507 script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0); 1508 wo->hisaddr = ho->hisaddr; 1509 } else 1510 script_unsetenv("OLDIPREMOTE"); 1511 1512 /* Set the interface to the new addresses */ 1513 mask = GetMask(go->ouraddr); 1514 if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { 1515 warn("Interface configuration failed"); 1516 ipcp_close(f->unit, "Interface configuration failed"); 1517 return; 1518 } 1519 1520 /* assign a default route through the interface if required */ 1521 if (wo->default_route) 1522 if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) 1523 default_route_set[f->unit] = 1; 1524 1525 /* Make a proxy ARP entry if requested. */ 1526 if (wo->proxy_arp && 1527 sifproxyarp(f->unit, ho->hisaddr, proxy_arp_quiet[f->unit])) 1528 proxy_arp_set[f->unit] = 1; 1529 1530 } 1531 demand_rexmit(PPP_IP); 1532 if (sifnpmode(f->unit, PPP_IP, NPMODE_PASS) != 1) { 1533 ipcp_close(f->unit, "Interface configuration failed."); 1534 return; 1535 } 1536 1537 } else { 1538 /* 1539 * Set IP addresses and (if specified) netmask. 1540 */ 1541 mask = GetMask(go->ouraddr); 1542 1543 #if SIFUPFIRST 1544 /* bring the interface up for IP */ 1545 if (!sifup(f->unit)) { 1546 warn("Interface failed to come up"); 1547 ipcp_close(f->unit, "Interface configuration failed"); 1548 return; 1549 } 1550 #endif 1551 1552 if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) { 1553 warn("Interface configuration failed"); 1554 ipcp_close(f->unit, "Interface configuration failed"); 1555 return; 1556 } 1557 1558 #if !SIFUPFIRST 1559 /* bring the interface up for IP */ 1560 if (!sifup(f->unit)) { 1561 warn("Interface failed to come up"); 1562 ipcp_close(f->unit, "Interface configuration failed"); 1563 return; 1564 } 1565 #endif 1566 1567 if (sifnpmode(f->unit, PPP_IP, NPMODE_PASS) != 1) { 1568 ipcp_close(f->unit, "Interface configuration failed."); 1569 return; 1570 } 1571 1572 /* assign a default route through the interface if required */ 1573 if (wo->default_route) 1574 if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) 1575 default_route_set[f->unit] = 1; 1576 1577 /* Make a proxy ARP entry if requested. */ 1578 if (wo->proxy_arp && 1579 sifproxyarp(f->unit, ho->hisaddr, proxy_arp_quiet[f->unit])) 1580 proxy_arp_set[f->unit] = 1; 1581 1582 wo->ouraddr = go->ouraddr; 1583 1584 notice("local IP address %I", go->ouraddr); 1585 notice("remote IP address %I", ho->hisaddr); 1586 if (go->dnsaddr[0] != 0) 1587 notice("primary DNS address %I", go->dnsaddr[0]); 1588 if (go->dnsaddr[1] != 0) 1589 notice("secondary DNS address %I", go->dnsaddr[1]); 1590 } 1591 1592 np_up(f->unit, PPP_IP); 1593 ipcp_is_up[f->unit] = 1; 1594 1595 if (ip_up_hook != NULL) 1596 (*ip_up_hook)(); 1597 1598 /* 1599 * Execute the ip-up script, like this: 1600 * /etc/ppp/ip-up interface tty speed local-IP remote-IP 1601 */ 1602 if (ipcp_script_state == s_down && ipcp_script_pid == 0) { 1603 ipcp_script_state = s_up; 1604 ipcp_script(_PATH_IPUP); 1605 } 1606 sys_unblock_proto(PPP_IP); 1607 } 1608 1609 1610 /* 1611 * ipcp_down - IPCP has gone DOWN. 1612 * 1613 * Take the IP network interface down, clear its addresses 1614 * and delete routes through it. 1615 */ 1616 static void 1617 ipcp_down(f) 1618 fsm *f; 1619 { 1620 IPCPDEBUG(("ipcp: down")); 1621 /* XXX a bit IPv4-centric here, we only need to get the stats 1622 * before the interface is marked down. */ 1623 update_link_stats(f->unit); 1624 if (ip_down_hook != NULL) 1625 (*ip_down_hook)(); 1626 if (ipcp_is_up[f->unit]) { 1627 ipcp_is_up[f->unit] = 0; 1628 np_down(f->unit, PPP_IP); 1629 } 1630 if (sifvjcomp(f->unit, 0, 0, 0) != 1) { 1631 if (debug) 1632 warn("Failed to disable VJ TCP header compression."); 1633 } 1634 1635 /* 1636 * If we are doing dial-on-demand, set the interface 1637 * to queue up outgoing packets (for now). 1638 */ 1639 if (demand) { 1640 if (sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE) != 1) { 1641 if (debug) 1642 warn("Failed to enable Queueing on outgoing packets."); 1643 } 1644 } else { 1645 if (sifnpmode(f->unit, PPP_IP, NPMODE_ERROR) != 1) { 1646 if (debug) 1647 warn("Could not set interface to drop packets."); 1648 } 1649 if (sifdown(f->unit) != 1) 1650 warn("Could not bring interface down."); 1651 ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr, 1652 ipcp_hisoptions[f->unit].hisaddr); 1653 } 1654 1655 /* Execute the ip-down script */ 1656 if (ipcp_script_state == s_up && ipcp_script_pid == 0) { 1657 ipcp_script_state = s_down; 1658 ipcp_script(_PATH_IPDOWN); 1659 } 1660 } 1661 1662 1663 /* 1664 * ipcp_clear_addrs() - clear the interface addresses, routes, 1665 * proxy arp entries, etc. 1666 */ 1667 static void 1668 ipcp_clear_addrs(unit, ouraddr, hisaddr) 1669 int unit; 1670 u_int32_t ouraddr; /* local address */ 1671 u_int32_t hisaddr; /* remote address */ 1672 { 1673 if (proxy_arp_set[unit]) { 1674 (void) cifproxyarp(unit, hisaddr); 1675 proxy_arp_set[unit] = 0; 1676 } 1677 if (default_route_set[unit]) { 1678 (void) cifdefaultroute(unit, ouraddr, hisaddr); 1679 default_route_set[unit] = 0; 1680 } 1681 if (cifaddr(unit, ouraddr, hisaddr) != 1) 1682 warn("Could not clear addresses"); 1683 } 1684 1685 1686 /* 1687 * ipcp_finished - possibly shut down the lower layers. 1688 */ 1689 static void 1690 ipcp_finished(f) 1691 fsm *f; 1692 { 1693 np_finished(f->unit, PPP_IP); 1694 } 1695 1696 1697 /* 1698 * ipcp_script_done - called when the ip-up or ip-down script 1699 * has finished. 1700 */ 1701 /*ARGSUSED*/ 1702 static void 1703 ipcp_script_done(arg, status) 1704 void *arg; 1705 int status; 1706 { 1707 ipcp_script_pid = 0; 1708 switch (ipcp_script_state) { 1709 case s_up: 1710 if (ipcp_fsm[0].state != OPENED) { 1711 ipcp_script_state = s_down; 1712 ipcp_script(_PATH_IPDOWN); 1713 } 1714 break; 1715 case s_down: 1716 if (ipcp_fsm[0].state == OPENED) { 1717 ipcp_script_state = s_up; 1718 ipcp_script(_PATH_IPUP); 1719 } 1720 break; 1721 } 1722 } 1723 1724 1725 /* 1726 * ipcp_script - Execute a script with arguments 1727 * interface-name tty-name speed local-IP remote-IP. 1728 */ 1729 static void 1730 ipcp_script(script) 1731 char *script; 1732 { 1733 char strspeed[32], strlocal[32], strremote[32]; 1734 char *argv[8]; 1735 1736 (void) slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); 1737 (void) slprintf(strlocal, sizeof(strlocal), "%I", 1738 ipcp_gotoptions[0].ouraddr); 1739 (void) slprintf(strremote, sizeof(strremote), "%I", 1740 ipcp_hisoptions[0].hisaddr); 1741 1742 argv[0] = script; 1743 argv[1] = ifname; 1744 argv[2] = devnam; 1745 argv[3] = strspeed; 1746 argv[4] = strlocal; 1747 argv[5] = strremote; 1748 argv[6] = ipparam; 1749 argv[7] = NULL; 1750 ipcp_script_pid = run_program(script, argv, 0, ipcp_script_done, NULL); 1751 } 1752 1753 /* 1754 * create_resolv - create the replacement resolv.conf file 1755 */ 1756 static void 1757 create_resolv(peerdns1, peerdns2) 1758 u_int32_t peerdns1, peerdns2; 1759 { 1760 FILE *f; 1761 1762 f = fopen(_PATH_RESOLV, "w"); 1763 if (f == NULL) { 1764 error("Failed to create %s: %m", _PATH_RESOLV); 1765 return; 1766 } 1767 1768 if (peerdns1) 1769 if (fprintf(f, "nameserver %s\n", ip_ntoa(peerdns1)) <= 0) 1770 error("Write failed to %s: %m", _PATH_RESOLV); 1771 1772 if (peerdns2) 1773 if (fprintf(f, "nameserver %s\n", ip_ntoa(peerdns2)) <= 0) 1774 error("Write failed to %s: %m", _PATH_RESOLV); 1775 1776 if (fclose(f) != 0) 1777 error("Failed to close %s: %m", _PATH_RESOLV); 1778 } 1779 1780 /* 1781 * ipcp_printpkt - print the contents of an IPCP packet. 1782 */ 1783 static int 1784 ipcp_printpkt(p, plen, printer, arg) 1785 u_char *p; 1786 int plen; 1787 void (*printer) __P((void *, const char *, ...)); 1788 void *arg; 1789 { 1790 int code, id, len, olen; 1791 u_char *pstart, *optend; 1792 u_short cishort; 1793 u_int32_t cilong; 1794 1795 if (plen < HEADERLEN) 1796 return 0; 1797 pstart = p; 1798 GETCHAR(code, p); 1799 GETCHAR(id, p); 1800 GETSHORT(len, p); 1801 if (len < HEADERLEN || len > plen) 1802 return 0; 1803 1804 printer(arg, " %s id=0x%x", code_name(code, 1), id); 1805 len -= HEADERLEN; 1806 switch (code) { 1807 case CODE_CONFREQ: 1808 case CODE_CONFACK: 1809 case CODE_CONFNAK: 1810 case CODE_CONFREJ: 1811 /* print option list */ 1812 while (len >= 2) { 1813 GETCHAR(code, p); 1814 GETCHAR(olen, p); 1815 p -= 2; 1816 if (olen < 2 || olen > len) { 1817 break; 1818 } 1819 printer(arg, " <"); 1820 len -= olen; 1821 optend = p + olen; 1822 switch (code) { 1823 case CI_ADDRS: 1824 if (olen == CILEN_ADDRS) { 1825 p += 2; 1826 GETNLONG(cilong, p); 1827 printer(arg, "addrs %I", cilong); 1828 GETNLONG(cilong, p); 1829 printer(arg, " %I", cilong); 1830 } 1831 break; 1832 case CI_COMPRESSTYPE: 1833 if (olen >= CILEN_COMPRESS) { 1834 p += 2; 1835 GETSHORT(cishort, p); 1836 printer(arg, "compress "); 1837 switch (cishort) { 1838 case IPCP_VJ_COMP: 1839 printer(arg, "VJ"); 1840 break; 1841 case IPCP_VJ_COMP_OLD: 1842 printer(arg, "old-VJ"); 1843 break; 1844 default: 1845 printer(arg, "0x%x", cishort); 1846 } 1847 } 1848 break; 1849 case CI_ADDR: 1850 if (olen == CILEN_ADDR) { 1851 p += 2; 1852 GETNLONG(cilong, p); 1853 printer(arg, "addr %I", cilong); 1854 } 1855 break; 1856 case CI_MS_DNS1: 1857 case CI_MS_DNS2: 1858 p += 2; 1859 GETNLONG(cilong, p); 1860 printer(arg, "ms-dns%d %I", (code == CI_MS_DNS1 ? 1 : 2), 1861 cilong); 1862 break; 1863 case CI_MS_WINS1: 1864 case CI_MS_WINS2: 1865 p += 2; 1866 GETNLONG(cilong, p); 1867 printer(arg, "ms-wins%d %I", (code == CI_MS_WINS1 ? 1 : 2), 1868 cilong); 1869 break; 1870 case CI_SUBNET: 1871 p += 2; 1872 GETNLONG(cilong, p); 1873 printer(arg, "subnet %I", cilong); 1874 break; 1875 } 1876 while (p < optend) { 1877 GETCHAR(code, p); 1878 printer(arg, " %.2x", code); 1879 } 1880 printer(arg, ">"); 1881 } 1882 break; 1883 1884 case CODE_TERMACK: 1885 case CODE_TERMREQ: 1886 if (len > 0 && *p >= ' ' && *p < 0x7f) { 1887 printer(arg, " "); 1888 print_string((char *)p, len, printer, arg); 1889 p += len; 1890 len = 0; 1891 } 1892 break; 1893 } 1894 1895 /* print the rest of the bytes in the packet */ 1896 for (; len > 0; --len) { 1897 GETCHAR(code, p); 1898 printer(arg, " %.2x", code); 1899 } 1900 1901 return p - pstart; 1902 } 1903 1904 char * 1905 tcp_flag_decode(val) 1906 int val; 1907 { 1908 static char buf[32]; 1909 char *cp = buf; 1910 1911 if (val & TH_URG) 1912 *cp++ = 'U'; 1913 if (val & TH_ACK) 1914 *cp++ = 'A'; 1915 if (val & TH_PUSH) 1916 *cp++ = 'P'; 1917 if (val & TH_RST) 1918 *cp++ = 'R'; 1919 if (val & TH_SYN) 1920 *cp++ = 'S'; 1921 if (val & TH_FIN) 1922 *cp++ = 'F'; 1923 if (cp != buf) 1924 *cp++ = ' '; 1925 *cp = '\0'; 1926 return buf; 1927 } 1928 1929 /* 1930 * ip_active_pkt - see if this IP packet is worth bringing the link up for. 1931 * We don't bring the link up for IP fragments or for TCP FIN packets 1932 * with no data. 1933 */ 1934 1935 static int 1936 ip_active_pkt(pkt, len) 1937 u_char *pkt; 1938 int len; 1939 { 1940 u_char *tcp; 1941 struct protoent *pep; 1942 int val; 1943 int hlen; 1944 char buf[32], *cp; 1945 u_int32_t src, dst; 1946 1947 len -= PPP_HDRLEN; 1948 pkt += PPP_HDRLEN; 1949 if (len < IP_HDRLEN) { 1950 dbglog("IP packet of length %d is not activity", len); 1951 return 0; 1952 } 1953 src = get_ipsrc(pkt); 1954 dst = get_ipdst(pkt); 1955 if ((get_ipoff(pkt) & IP_OFFMASK) != 0) { 1956 dbglog("IP fragment from %I->%I is not activity", src, dst); 1957 return 0; 1958 } 1959 val = get_ipproto(pkt); 1960 if (val != IPPROTO_TCP) { 1961 if (debug) { 1962 if ((pep = getprotobynumber(val)) != NULL) { 1963 cp = pep->p_name; 1964 } else { 1965 (void) slprintf(buf, sizeof (buf), "IP proto %d", val); 1966 cp = buf; 1967 } 1968 info("%s from %I->%I is activity", cp, src, dst); 1969 } 1970 return 1; 1971 } 1972 hlen = get_iphl(pkt) * 4; 1973 if (len < hlen + TCP_HDRLEN) { 1974 dbglog("Bad TCP length %d<%d+%d %I->%I is not activity", len, hlen, 1975 TCP_HDRLEN, src, dst); 1976 return 0; 1977 } 1978 tcp = pkt + hlen; 1979 val = get_tcpflags(tcp); 1980 hlen += get_tcpoff(tcp) * 4; 1981 if ((val & TH_FIN) != 0 && len == hlen) { 1982 dbglog("Empty TCP FIN %I->%I is not activity", src, dst); 1983 return 0; 1984 } 1985 info("TCP %d data %s%I->%I is activity", len - hlen, 1986 tcp_flag_decode(get_tcpflags(tcp)), src, dst); 1987 return 1; 1988 } 1989 1990 static void 1991 ipcp_print_stat(unit, strptr) 1992 int unit; 1993 FILE *strptr; 1994 { 1995 ipcp_options *go = &ipcp_gotoptions[unit]; 1996 ipcp_options *ho = &ipcp_hisoptions[unit]; 1997 char *proto_name = ipcp_protent.name; 1998 1999 if (!ipcp_protent.enabled_flag) { 2000 (void) flprintf(strptr, "%s disabled\n", proto_name); 2001 return; 2002 } 2003 2004 (void) flprintf(strptr, "%s state: %s", proto_name, 2005 fsm_state(ipcp_fsm[unit].state)); 2006 (void) flprintf(strptr, "%s local %I remote %I", proto_name, go->ouraddr, 2007 ho->ouraddr); 2008 } 2009