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