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