1 /* $OpenBSD: sys-bsd.c,v 1.30 2020/12/29 19:45:28 benno Exp $ */ 2 3 /* 4 * sys-bsd.c - System-dependent procedures for setting up 5 * PPP interfaces on bsd-4.4-ish systems (including 386BSD, NetBSD, etc.) 6 * 7 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The name "Carnegie Mellon University" must not be used to 22 * endorse or promote products derived from this software without 23 * prior written permission. For permission or any legal 24 * details, please contact 25 * Office of Technology Transfer 26 * Carnegie Mellon University 27 * 5000 Forbes Avenue 28 * Pittsburgh, PA 15213-3890 29 * (412) 268-4387, fax: (412) 268-7395 30 * tech-transfer@andrew.cmu.edu 31 * 32 * 4. Redistributions of any form whatsoever must retain the following 33 * acknowledgment: 34 * "This product includes software developed by Computing Services 35 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 36 * 37 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 38 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 39 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 40 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 41 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 42 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 43 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 44 * 45 * Copyright (c) 1989-2002 Paul Mackerras. All rights reserved. 46 * 47 * Redistribution and use in source and binary forms, with or without 48 * modification, are permitted provided that the following conditions 49 * are met: 50 * 51 * 1. Redistributions of source code must retain the above copyright 52 * notice, this list of conditions and the following disclaimer. 53 * 54 * 2. Redistributions in binary form must reproduce the above copyright 55 * notice, this list of conditions and the following disclaimer in 56 * the documentation and/or other materials provided with the 57 * distribution. 58 * 59 * 3. The name(s) of the authors of this software must not be used to 60 * endorse or promote products derived from this software without 61 * prior written permission. 62 * 63 * 4. Redistributions of any form whatsoever must retain the following 64 * acknowledgment: 65 * "This product includes software developed by Paul Mackerras 66 * <paulus@samba.org>". 67 * 68 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 69 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 70 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 71 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 72 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 73 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 74 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 75 */ 76 77 /* 78 * TODO: 79 */ 80 81 #include <stdio.h> 82 #include <syslog.h> 83 #include <string.h> 84 #include <stdlib.h> 85 #include <unistd.h> 86 #include <err.h> 87 #include <errno.h> 88 #include <fcntl.h> 89 #include <termios.h> 90 #include <signal.h> 91 #include <util.h> 92 #include <sys/ioctl.h> 93 #include <sys/types.h> 94 #include <sys/socket.h> 95 #include <sys/time.h> 96 #include <sys/stat.h> 97 #include <ifaddrs.h> 98 99 #ifdef PPP_FILTER 100 #include <net/bpf.h> 101 #endif 102 #include <net/if.h> 103 #include <net/ppp_defs.h> 104 #include <net/if_ppp.h> 105 #include <net/route.h> 106 #include <net/if_dl.h> 107 #include <netinet/in.h> 108 109 #if RTM_VERSION >= 3 110 #include <sys/param.h> 111 #if defined(NetBSD) && (NetBSD >= 199703) 112 #include <netinet/if_inarp.h> 113 #else /* NetBSD 1.2D or later */ 114 #if defined(__FreeBSD__) || defined(__OpenBSD__) 115 #include <netinet/if_ether.h> 116 #else 117 #include <net/if_ether.h> 118 #endif 119 #endif 120 #endif 121 122 #include "pppd.h" 123 #include "fsm.h" 124 #include "ipcp.h" 125 126 #define ok_error(num) ((num)==EIO) 127 128 static int initdisc = -1; /* Initial TTY discipline for ppp_fd */ 129 static int initfdflags = -1; /* Initial file descriptor flags for ppp_fd */ 130 static int ppp_fd = -1; /* fd which is set to PPP discipline */ 131 static int rtm_seq; 132 133 static int restore_term; /* 1 => we've munged the terminal */ 134 static struct termios inittermios; /* Initial TTY termios */ 135 static struct winsize wsinfo; /* Initial window size info */ 136 137 static char *lock_file; /* name of lock file created */ 138 139 static int loop_slave = -1; 140 static int loop_master; 141 static char loop_name[20]; 142 143 static unsigned char inbuf[512]; /* buffer for chars read from loopback */ 144 145 static int sockfd; /* socket for doing interface ioctls */ 146 147 static int if_is_up; /* the interface is currently up */ 148 static u_int32_t ifaddrs[2]; /* local and remote addresses we set */ 149 static u_int32_t default_route_gateway; /* gateway addr for default route */ 150 static u_int32_t proxy_arp_addr; /* remote addr for proxy arp */ 151 152 /* Prototypes for procedures local to this file. */ 153 static int dodefaultroute(u_int32_t, int); 154 static int get_ether_addr(u_int32_t, struct sockaddr_dl *); 155 156 157 /* 158 * sys_init - System-dependent initialization. 159 */ 160 void 161 sys_init() 162 { 163 /* Get an internet socket for doing socket ioctl's on. */ 164 if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { 165 syslog(LOG_ERR, "Couldn't create IP socket: %m"); 166 die(1); 167 } 168 } 169 170 /* 171 * sys_cleanup - restore any system state we modified before exiting: 172 * mark the interface down, delete default route and/or proxy arp entry. 173 * This should call die() because it's called from die(). 174 */ 175 void 176 sys_cleanup() 177 { 178 struct ifreq ifr; 179 180 if (if_is_up) { 181 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 182 if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) == 0 183 && ((ifr.ifr_flags & IFF_UP) != 0)) { 184 ifr.ifr_flags &= ~IFF_UP; 185 ioctl(sockfd, SIOCSIFFLAGS, &ifr); 186 } 187 } 188 if (ifaddrs[0] != 0) 189 cifaddr(0, ifaddrs[0], ifaddrs[1]); 190 if (default_route_gateway) 191 cifdefaultroute(0, 0, default_route_gateway); 192 if (proxy_arp_addr) 193 cifproxyarp(0, proxy_arp_addr); 194 } 195 196 /* 197 * sys_close - Clean up in a child process before execing. 198 */ 199 void 200 sys_close() 201 { 202 close(sockfd); 203 if (loop_slave >= 0) { 204 close(loop_slave); 205 close(loop_master); 206 } 207 } 208 209 /* 210 * sys_check_options - check the options that the user specified 211 */ 212 void 213 sys_check_options() 214 { 215 } 216 217 /* 218 * ppp_available - check whether the system has any ppp interfaces 219 * (in fact we check whether we can do an ioctl on ppp0). 220 */ 221 int 222 ppp_available() 223 { 224 int s, ok; 225 struct ifreq ifr; 226 extern char *no_ppp_msg; 227 228 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 229 return 1; /* can't tell */ 230 231 strlcpy(ifr.ifr_name, "ppp0", sizeof(ifr.ifr_name)); 232 ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) == 0; 233 close(s); 234 235 no_ppp_msg = "\ 236 PPP device not available. Make sure the device is created with\n\ 237 ifconfig and that the kernel supports PPP. See ifconfig(8) and ppp(4)."; 238 return ok; 239 } 240 241 /* 242 * establish_ppp - Turn the serial port into a ppp interface. 243 */ 244 void 245 establish_ppp(fd) 246 int fd; 247 { 248 int pppdisc = PPPDISC; 249 int x; 250 251 if (demand) { 252 /* 253 * Demand mode - prime the old ppp device to relinquish the unit. 254 */ 255 if (ioctl(ppp_fd, PPPIOCXFERUNIT, 0) == -1) { 256 syslog(LOG_ERR, "ioctl(transfer ppp unit): %m"); 257 die(1); 258 } 259 } 260 261 /* 262 * Save the old line discipline of fd, and set it to PPP. 263 */ 264 if (ioctl(fd, TIOCGETD, &initdisc) == -1) { 265 syslog(LOG_ERR, "ioctl(TIOCGETD): %m"); 266 die(1); 267 } 268 if (ioctl(fd, TIOCSETD, &pppdisc) == -1) { 269 syslog(LOG_ERR, "ioctl(TIOCSETD): %m"); 270 die(1); 271 } 272 273 if (!demand) { 274 /* 275 * Find out which interface we were given. 276 */ 277 if (ioctl(fd, PPPIOCGUNIT, &ifunit) == -1) { 278 syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m"); 279 die(1); 280 } 281 } else { 282 /* 283 * Check that we got the same unit again. 284 */ 285 if (ioctl(fd, PPPIOCGUNIT, &x) == -1) { 286 syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m"); 287 die(1); 288 } 289 if (x != ifunit) { 290 syslog(LOG_ERR, "transfer_ppp failed: wanted unit %d, got %d", 291 ifunit, x); 292 die(1); 293 } 294 x = TTYDISC; 295 ioctl(loop_slave, TIOCSETD, &x); 296 } 297 298 ppp_fd = fd; 299 300 /* 301 * Enable debug in the driver if requested. 302 */ 303 if (kdebugflag) { 304 if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &x) == -1) { 305 syslog(LOG_WARNING, "ioctl (PPPIOCGFLAGS): %m"); 306 } else { 307 x |= (kdebugflag & 0xFF) * SC_DEBUG; 308 if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &x) == -1) 309 syslog(LOG_WARNING, "ioctl(PPPIOCSFLAGS): %m"); 310 } 311 } 312 313 /* 314 * Set device for non-blocking reads. 315 */ 316 if ((initfdflags = fcntl(fd, F_GETFL)) == -1 317 || fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) { 318 syslog(LOG_WARNING, "Couldn't set device to non-blocking mode: %m"); 319 } 320 } 321 322 /* 323 * restore_loop - reattach the ppp unit to the loopback. 324 */ 325 void 326 restore_loop() 327 { 328 int x; 329 330 /* 331 * Transfer the ppp interface back to the loopback. 332 */ 333 if (ioctl(ppp_fd, PPPIOCXFERUNIT, 0) == -1) { 334 syslog(LOG_ERR, "ioctl(transfer ppp unit): %m"); 335 die(1); 336 } 337 x = PPPDISC; 338 if (ioctl(loop_slave, TIOCSETD, &x) == -1) { 339 syslog(LOG_ERR, "ioctl(TIOCSETD): %m"); 340 die(1); 341 } 342 343 /* 344 * Check that we got the same unit again. 345 */ 346 if (ioctl(loop_slave, PPPIOCGUNIT, &x) == -1) { 347 syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m"); 348 die(1); 349 } 350 if (x != ifunit) { 351 syslog(LOG_ERR, "transfer_ppp failed: wanted unit %d, got %d", 352 ifunit, x); 353 die(1); 354 } 355 ppp_fd = loop_slave; 356 } 357 358 /* 359 * disestablish_ppp - Restore the serial port to normal operation. 360 * This shouldn't call die() because it's called from die(). 361 */ 362 void 363 disestablish_ppp(fd) 364 int fd; 365 { 366 /* Reset non-blocking mode on fd. */ 367 if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) == -1) 368 syslog(LOG_WARNING, "Couldn't restore device fd flags: %m"); 369 initfdflags = -1; 370 371 /* Restore old line discipline. */ 372 if (initdisc >= 0 && ioctl(fd, TIOCSETD, &initdisc) == -1) 373 syslog(LOG_ERR, "ioctl(TIOCSETD): %m"); 374 initdisc = -1; 375 376 if (fd == ppp_fd) 377 ppp_fd = -1; 378 } 379 380 /* 381 * Check whether the link seems not to be 8-bit clean. 382 */ 383 void 384 clean_check() 385 { 386 int x; 387 char *s; 388 389 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) { 390 s = NULL; 391 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) { 392 case SC_RCV_B7_0: 393 s = "bit 7 set to 1"; 394 break; 395 case SC_RCV_B7_1: 396 s = "bit 7 set to 0"; 397 break; 398 case SC_RCV_EVNP: 399 s = "odd parity"; 400 break; 401 case SC_RCV_ODDP: 402 s = "even parity"; 403 break; 404 } 405 if (s != NULL) { 406 syslog(LOG_WARNING, "Serial link is not 8-bit clean:"); 407 syslog(LOG_WARNING, "All received characters had %s", s); 408 } 409 } 410 } 411 412 /* 413 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity, 414 * at the requested speed, etc. If `local' is true, set CLOCAL 415 * regardless of whether the modem option was specified. 416 * 417 * For *BSD, we assume that speed_t values numerically equal bits/second. 418 */ 419 void 420 set_up_tty(fd, local) 421 int fd, local; 422 { 423 struct termios tios; 424 425 if (tcgetattr(fd, &tios) == -1) { 426 syslog(LOG_ERR, "tcgetattr: %m"); 427 die(1); 428 } 429 430 if (!restore_term) { 431 inittermios = tios; 432 ioctl(fd, TIOCGWINSZ, &wsinfo); 433 } 434 435 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); 436 if (crtscts > 0 && modem) 437 tios.c_cflag |= CRTSCTS; 438 else if (crtscts < 0) 439 tios.c_cflag &= ~CRTSCTS; 440 441 tios.c_cflag |= CS8 | CREAD | HUPCL; 442 if (local || !modem) 443 tios.c_cflag |= CLOCAL; 444 tios.c_iflag = IGNBRK | IGNPAR; 445 tios.c_oflag = 0; 446 tios.c_lflag = 0; 447 tios.c_cc[VMIN] = 1; 448 tios.c_cc[VTIME] = 0; 449 450 if (crtscts == -2) { 451 tios.c_iflag |= IXON | IXOFF; 452 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ 453 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ 454 } 455 456 if (inspeed) { 457 cfsetospeed(&tios, inspeed); 458 cfsetispeed(&tios, inspeed); 459 } else { 460 inspeed = cfgetospeed(&tios); 461 /* 462 * We can't proceed if the serial port speed is 0, 463 * since that implies that the serial port is disabled. 464 */ 465 if (inspeed == 0) { 466 syslog(LOG_ERR, "Baud rate for %s is 0; need explicit baud rate", 467 devnam); 468 die(1); 469 } 470 } 471 baud_rate = inspeed; 472 473 if (tcsetattr(fd, TCSAFLUSH, &tios) == -1) { 474 syslog(LOG_ERR, "tcsetattr: %m"); 475 die(1); 476 } 477 478 restore_term = 1; 479 } 480 481 /* 482 * restore_tty - restore the terminal to the saved settings. 483 */ 484 void 485 restore_tty(fd) 486 int fd; 487 { 488 if (restore_term) { 489 if (!default_device) { 490 /* 491 * Turn off echoing, because otherwise we can get into 492 * a loop with the tty and the modem echoing to each other. 493 * We presume we are the sole user of this tty device, so 494 * when we close it, it will revert to its defaults anyway. 495 */ 496 inittermios.c_lflag &= ~(ECHO | ECHONL); 497 } 498 if (tcsetattr(fd, TCSAFLUSH, &inittermios) == -1) 499 if (errno != ENXIO) 500 syslog(LOG_WARNING, "tcsetattr: %m"); 501 ioctl(fd, TIOCSWINSZ, &wsinfo); 502 restore_term = 0; 503 } 504 } 505 506 /* 507 * setdtr - control the DTR line on the serial port. 508 * This is called from die(), so it shouldn't call die(). 509 */ 510 void 511 setdtr(fd, on) 512 int fd, on; 513 { 514 int modembits = TIOCM_DTR; 515 516 ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits); 517 } 518 519 520 /* 521 * open_ppp_loopback - open the device we use for getting 522 * packets in demand mode, and connect it to a ppp interface. 523 * Here we use a pty. 524 */ 525 void 526 open_ppp_loopback() 527 { 528 int flags; 529 struct termios tios; 530 int pppdisc = PPPDISC; 531 532 if (openpty(&loop_master, &loop_slave, loop_name, NULL, NULL) == -1) { 533 syslog(LOG_ERR, "No free pty for loopback"); 534 die(1); 535 } 536 SYSDEBUG((LOG_DEBUG, "using %s for loopback", loop_name)); 537 538 if (tcgetattr(loop_slave, &tios) == 0) { 539 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); 540 tios.c_cflag |= CS8 | CREAD; 541 tios.c_iflag = IGNPAR; 542 tios.c_oflag = 0; 543 tios.c_lflag = 0; 544 if (tcsetattr(loop_slave, TCSAFLUSH, &tios) == -1) 545 syslog(LOG_WARNING, "couldn't set attributes on loopback: %m"); 546 } 547 548 if ((flags = fcntl(loop_master, F_GETFL)) != -1) 549 if (fcntl(loop_master, F_SETFL, flags | O_NONBLOCK) == -1) 550 syslog(LOG_WARNING, "couldn't set loopback to nonblock: %m"); 551 552 ppp_fd = loop_slave; 553 if (ioctl(ppp_fd, TIOCSETD, &pppdisc) == -1) { 554 syslog(LOG_ERR, "ioctl(TIOCSETD): %m"); 555 die(1); 556 } 557 558 /* 559 * Find out which interface we were given. 560 */ 561 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) == -1) { 562 syslog(LOG_ERR, "ioctl(PPPIOCGUNIT): %m"); 563 die(1); 564 } 565 566 /* 567 * Enable debug in the driver if requested. 568 */ 569 if (kdebugflag) { 570 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &flags) == -1) { 571 syslog(LOG_WARNING, "ioctl (PPPIOCGFLAGS): %m"); 572 } else { 573 flags |= (kdebugflag & 0xFF) * SC_DEBUG; 574 if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &flags) == -1) 575 syslog(LOG_WARNING, "ioctl(PPPIOCSFLAGS): %m"); 576 } 577 } 578 579 } 580 581 582 /* 583 * output - Output PPP packet. 584 */ 585 void 586 output(unit, p, len) 587 int unit; 588 u_char *p; 589 int len; 590 { 591 if (debug) 592 log_packet(p, len, "sent ", LOG_DEBUG); 593 594 if (write(ttyfd, p, len) == -1) { 595 if (errno != EIO) 596 syslog(LOG_ERR, "write: %m"); 597 } 598 } 599 600 601 /* 602 * wait_input - wait until there is data available on ttyfd, 603 * for the length of time specified by *timo (indefinite 604 * if timo is NULL). 605 */ 606 void 607 wait_input(timo) 608 struct timeval *timo; 609 { 610 fd_set *fdsp = NULL; 611 int fdsn; 612 int n; 613 614 fdsn = howmany(ttyfd+1, NFDBITS) * sizeof(fd_mask); 615 if ((fdsp = (fd_set *)malloc(fdsn)) == NULL) 616 err(1, "malloc"); 617 memset(fdsp, 0, fdsn); 618 FD_SET(ttyfd, fdsp); 619 620 n = select(ttyfd+1, fdsp, NULL, fdsp, timo); 621 if (n == -1 && errno != EINTR) { 622 syslog(LOG_ERR, "select: %m"); 623 free(fdsp); 624 die(1); 625 } 626 free(fdsp); 627 } 628 629 630 /* 631 * wait_loop_output - wait until there is data available on the 632 * loopback, for the length of time specified by *timo (indefinite 633 * if timo is NULL). 634 */ 635 void 636 wait_loop_output(timo) 637 struct timeval *timo; 638 { 639 fd_set *fdsp = NULL; 640 int fdsn; 641 int n; 642 643 fdsn = howmany(loop_master+1, NFDBITS) * sizeof(fd_mask); 644 if ((fdsp = (fd_set *)malloc(fdsn)) == NULL) 645 err(1, "malloc"); 646 memset(fdsp, 0, fdsn); 647 FD_SET(loop_master, fdsp); 648 649 n = select(loop_master + 1, fdsp, NULL, fdsp, timo); 650 if (n == -1 && errno != EINTR) { 651 syslog(LOG_ERR, "select: %m"); 652 free(fdsp); 653 die(1); 654 } 655 free(fdsp); 656 } 657 658 659 /* 660 * wait_time - wait for a given length of time or until a 661 * signal is received. 662 */ 663 void 664 wait_time(timo) 665 struct timeval *timo; 666 { 667 int n; 668 669 n = select(0, NULL, NULL, NULL, timo); 670 if (n == -1 && errno != EINTR) { 671 syslog(LOG_ERR, "select: %m"); 672 die(1); 673 } 674 } 675 676 677 /* 678 * read_packet - get a PPP packet from the serial device. 679 */ 680 int 681 read_packet(buf) 682 u_char *buf; 683 { 684 int len; 685 686 if ((len = read(ttyfd, buf, PPP_MTU + PPP_HDRLEN)) == -1) { 687 if (errno == EWOULDBLOCK || errno == EINTR) 688 return -1; 689 syslog(LOG_ERR, "read: %m"); 690 die(1); 691 } 692 return len; 693 } 694 695 696 /* 697 * get_loop_output - read characters from the loopback, form them 698 * into frames, and detect when we want to bring the real link up. 699 * Return value is 1 if we need to bring up the link, 0 otherwise. 700 */ 701 int 702 get_loop_output() 703 { 704 int rv = 0; 705 int n; 706 707 while ((n = read(loop_master, inbuf, sizeof(inbuf))) >= 0) { 708 if (loop_chars(inbuf, n)) 709 rv = 1; 710 } 711 712 if (n == 0) { 713 syslog(LOG_ERR, "eof on loopback"); 714 die(1); 715 } else if (errno != EWOULDBLOCK){ 716 syslog(LOG_ERR, "read from loopback: %m"); 717 die(1); 718 } 719 720 return rv; 721 } 722 723 724 /* 725 * ppp_send_config - configure the transmit characteristics of 726 * the ppp interface. 727 */ 728 void 729 ppp_send_config(unit, mtu, asyncmap, pcomp, accomp) 730 int unit, mtu; 731 u_int32_t asyncmap; 732 int pcomp, accomp; 733 { 734 u_int x; 735 struct ifreq ifr; 736 737 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 738 ifr.ifr_mtu = mtu; 739 if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) == -1) { 740 syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m"); 741 quit(); 742 } 743 744 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) == -1) { 745 syslog(LOG_ERR, "ioctl(PPPIOCSASYNCMAP): %m"); 746 quit(); 747 } 748 749 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == -1) { 750 syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); 751 quit(); 752 } 753 x = pcomp? x | SC_COMP_PROT: x &~ SC_COMP_PROT; 754 x = accomp? x | SC_COMP_AC: x &~ SC_COMP_AC; 755 if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) == -1) { 756 syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); 757 quit(); 758 } 759 } 760 761 762 /* 763 * ppp_set_xaccm - set the extended transmit ACCM for the interface. 764 */ 765 void 766 ppp_set_xaccm(unit, accm) 767 int unit; 768 ext_accm accm; 769 { 770 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) == -1 && errno != ENOTTY) 771 syslog(LOG_WARNING, "ioctl(set extended ACCM): %m"); 772 } 773 774 775 /* 776 * ppp_recv_config - configure the receive-side characteristics of 777 * the ppp interface. 778 */ 779 void 780 ppp_recv_config(unit, mru, asyncmap, pcomp, accomp) 781 int unit, mru; 782 u_int32_t asyncmap; 783 int pcomp, accomp; 784 { 785 int x; 786 787 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) == -1) { 788 syslog(LOG_ERR, "ioctl(PPPIOCSMRU): %m"); 789 quit(); 790 } 791 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) == -1) { 792 syslog(LOG_ERR, "ioctl(PPPIOCSRASYNCMAP): %m"); 793 quit(); 794 } 795 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == -1) { 796 syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); 797 quit(); 798 } 799 x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC; 800 if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) == -1) { 801 syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); 802 quit(); 803 } 804 } 805 806 /* 807 * ccp_test - ask kernel whether a given compression method 808 * is acceptable for use. Returns 1 if the method and parameters 809 * are OK, 0 if the method is known but the parameters are not OK 810 * (e.g. code size should be reduced), or -1 if the method is unknown. 811 */ 812 int 813 ccp_test(unit, opt_ptr, opt_len, for_transmit) 814 int unit, opt_len, for_transmit; 815 u_char *opt_ptr; 816 { 817 struct ppp_option_data data; 818 819 data.ptr = opt_ptr; 820 data.length = opt_len; 821 data.transmit = for_transmit; 822 if (ioctl(ttyfd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0) 823 return 1; 824 return (errno == ENOBUFS)? 0: -1; 825 } 826 827 /* 828 * ccp_flags_set - inform kernel about the current state of CCP. 829 */ 830 void 831 ccp_flags_set(unit, isopen, isup) 832 int unit, isopen, isup; 833 { 834 int x; 835 836 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == -1) { 837 syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); 838 return; 839 } 840 x = isopen? x | SC_CCP_OPEN: x &~ SC_CCP_OPEN; 841 x = isup? x | SC_CCP_UP: x &~ SC_CCP_UP; 842 if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) == -1) 843 syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); 844 } 845 846 /* 847 * ccp_fatal_error - returns 1 if decompression was disabled as a 848 * result of an error detected after decompression of a packet, 849 * 0 otherwise. This is necessary because of patent nonsense. 850 */ 851 int 852 ccp_fatal_error(unit) 853 int unit; 854 { 855 int x; 856 857 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == -1) { 858 syslog(LOG_ERR, "ioctl(PPPIOCGFLAGS): %m"); 859 return 0; 860 } 861 return x & SC_DC_FERROR; 862 } 863 864 /* 865 * get_idle_time - return how long the link has been idle. 866 */ 867 int 868 get_idle_time(u, ip) 869 int u; 870 struct ppp_idle *ip; 871 { 872 return ioctl(ppp_fd, PPPIOCGIDLE, ip) >= 0; 873 } 874 875 876 #ifdef PPP_FILTER 877 /* 878 * set_filters - transfer the pass and active filters to the kernel. 879 */ 880 int 881 set_filters(pass, active) 882 struct bpf_program *pass, *active; 883 { 884 int ret = 1; 885 886 if (pass->bf_len > 0) { 887 if (ioctl(ppp_fd, PPPIOCSPASS, pass) == -1) { 888 syslog(LOG_ERR, "Couldn't set pass-filter in kernel: %m"); 889 ret = 0; 890 } 891 } 892 if (active->bf_len > 0) { 893 if (ioctl(ppp_fd, PPPIOCSACTIVE, active) == -1) { 894 syslog(LOG_ERR, "Couldn't set active-filter in kernel: %m"); 895 ret = 0; 896 } 897 } 898 return ret; 899 } 900 #endif 901 902 /* 903 * sifvjcomp - config tcp header compression 904 */ 905 int 906 sifvjcomp(u, vjcomp, cidcomp, maxcid) 907 int u, vjcomp, cidcomp, maxcid; 908 { 909 u_int x; 910 911 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == -1) { 912 syslog(LOG_ERR, "ioctl (PPPIOCGFLAGS): %m"); 913 return 0; 914 } 915 x = vjcomp ? x | SC_COMP_TCP: x &~ SC_COMP_TCP; 916 x = cidcomp? x & ~SC_NO_TCP_CCID: x | SC_NO_TCP_CCID; 917 if (ioctl(ppp_fd, PPPIOCSFLAGS, (caddr_t) &x) == -1) { 918 syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); 919 return 0; 920 } 921 if (vjcomp && ioctl(ppp_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) == -1) { 922 syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS): %m"); 923 return 0; 924 } 925 return 1; 926 } 927 928 /* 929 * sifup - Config the interface up and enable IP packets to pass. 930 */ 931 int 932 sifup(u) 933 int u; 934 { 935 struct ifreq ifr; 936 937 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 938 if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) == -1) { 939 syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); 940 return 0; 941 } 942 ifr.ifr_flags |= IFF_UP; 943 if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) == -1) { 944 syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m"); 945 return 0; 946 } 947 if_is_up = 1; 948 return 1; 949 } 950 951 /* 952 * sifnpmode - Set the mode for handling packets for a given NP. 953 */ 954 int 955 sifnpmode(u, proto, mode) 956 int u; 957 int proto; 958 enum NPmode mode; 959 { 960 struct npioctl npi; 961 962 npi.protocol = proto; 963 npi.mode = mode; 964 if (ioctl(ppp_fd, PPPIOCSNPMODE, &npi) == -1) { 965 syslog(LOG_ERR, "ioctl(set NP %d mode to %d): %m", proto, mode); 966 return 0; 967 } 968 return 1; 969 } 970 971 /* 972 * sifdown - Config the interface down and disable IP. 973 */ 974 int 975 sifdown(u) 976 int u; 977 { 978 struct ifreq ifr; 979 int rv; 980 struct npioctl npi; 981 982 rv = 1; 983 npi.protocol = PPP_IP; 984 npi.mode = NPMODE_ERROR; 985 ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi); 986 /* ignore errors, because ppp_fd might have been closed by now. */ 987 988 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 989 if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) == -1) { 990 syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); 991 rv = 0; 992 } else { 993 ifr.ifr_flags &= ~IFF_UP; 994 if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) == -1) { 995 syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m"); 996 rv = 0; 997 } else 998 if_is_up = 0; 999 } 1000 return rv; 1001 } 1002 1003 /* 1004 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, 1005 * if it exists. 1006 */ 1007 #define SET_SA_FAMILY(addr, family) \ 1008 BZERO((char *) &(addr), sizeof(addr)); \ 1009 addr.sa_family = (family); \ 1010 addr.sa_len = sizeof(addr); 1011 1012 /* 1013 * sifaddr - Config the interface IP addresses and netmask. 1014 */ 1015 int 1016 sifaddr(u, o, h, m) 1017 int u; 1018 u_int32_t o, h, m; 1019 { 1020 struct ifaliasreq ifra; 1021 struct ifreq ifr; 1022 char s1[64], s2[64]; 1023 1024 strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name)); 1025 SET_SA_FAMILY(ifra.ifra_addr, AF_INET); 1026 ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o; 1027 SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET); 1028 ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h; 1029 if (m != 0) { 1030 SET_SA_FAMILY(ifra.ifra_mask, AF_INET); 1031 ((struct sockaddr_in *) &ifra.ifra_mask)->sin_addr.s_addr = m; 1032 } else 1033 BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask)); 1034 BZERO(&ifr, sizeof(ifr)); 1035 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 1036 if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifr) == -1) { 1037 if (errno != EADDRNOTAVAIL) 1038 syslog(LOG_WARNING, "Couldn't remove interface address: %m"); 1039 } 1040 if (ioctl(sockfd, SIOCAIFADDR, (caddr_t) &ifra) == -1) { 1041 if (errno != EEXIST) { 1042 syslog(LOG_ERR, "Couldn't set interface address: %m"); 1043 return 0; 1044 } 1045 strlcpy(s1, ip_ntoa(o), sizeof(s1)); 1046 strlcpy(s2, ip_ntoa(h), sizeof(s2)); 1047 syslog(LOG_WARNING, 1048 "Couldn't set interface address: " 1049 "Address %s or destination %s already exists", s1, s2); 1050 } 1051 ifaddrs[0] = o; 1052 ifaddrs[1] = h; 1053 return 1; 1054 } 1055 1056 /* 1057 * cifaddr - Clear the interface IP addresses, and delete routes 1058 * through the interface if possible. 1059 */ 1060 int 1061 cifaddr(u, o, h) 1062 int u; 1063 u_int32_t o, h; 1064 { 1065 struct ifaliasreq ifra; 1066 1067 ifaddrs[0] = 0; 1068 strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name)); 1069 SET_SA_FAMILY(ifra.ifra_addr, AF_INET); 1070 ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o; 1071 SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET); 1072 ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h; 1073 BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask)); 1074 if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifra) == -1) { 1075 if (errno != EADDRNOTAVAIL) 1076 syslog(LOG_WARNING, "Couldn't delete interface address: %m"); 1077 return 0; 1078 } 1079 return 1; 1080 } 1081 1082 /* 1083 * sifdefaultroute - assign a default route through the address given. 1084 */ 1085 int 1086 sifdefaultroute(u, l, g) 1087 int u; 1088 u_int32_t l, g; 1089 { 1090 return dodefaultroute(g, 's'); 1091 } 1092 1093 /* 1094 * cifdefaultroute - delete a default route through the address given. 1095 */ 1096 int 1097 cifdefaultroute(u, l, g) 1098 int u; 1099 u_int32_t l, g; 1100 { 1101 return dodefaultroute(g, 'c'); 1102 } 1103 1104 /* 1105 * dodefaultroute - talk to a routing socket to add/delete a default route. 1106 */ 1107 static int 1108 dodefaultroute(g, cmd) 1109 u_int32_t g; 1110 int cmd; 1111 { 1112 int routes; 1113 struct { 1114 struct rt_msghdr hdr; 1115 struct sockaddr_in dst; 1116 struct sockaddr_in gway; 1117 struct sockaddr_in mask; 1118 } rtmsg; 1119 1120 if ((routes = socket(AF_ROUTE, SOCK_RAW, AF_INET)) == -1) { 1121 syslog(LOG_ERR, "Couldn't %s default route: socket: %m", 1122 cmd=='s'? "add": "delete"); 1123 return 0; 1124 } 1125 1126 memset(&rtmsg, 0, sizeof(rtmsg)); 1127 rtmsg.hdr.rtm_type = cmd == 's'? RTM_ADD: RTM_DELETE; 1128 rtmsg.hdr.rtm_flags = RTF_UP | RTF_GATEWAY; 1129 rtmsg.hdr.rtm_version = RTM_VERSION; 1130 rtmsg.hdr.rtm_seq = ++rtm_seq; 1131 rtmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; 1132 rtmsg.dst.sin_len = sizeof(rtmsg.dst); 1133 rtmsg.dst.sin_family = AF_INET; 1134 rtmsg.gway.sin_len = sizeof(rtmsg.gway); 1135 rtmsg.gway.sin_family = AF_INET; 1136 rtmsg.gway.sin_addr.s_addr = g; 1137 rtmsg.mask.sin_len = sizeof(rtmsg.dst); 1138 rtmsg.mask.sin_family = AF_INET; 1139 1140 rtmsg.hdr.rtm_msglen = sizeof(rtmsg); 1141 if (write(routes, &rtmsg, sizeof(rtmsg)) == -1) { 1142 syslog(LOG_ERR, "Couldn't %s default route: %m", 1143 cmd=='s'? "add": "delete"); 1144 close(routes); 1145 return 0; 1146 } 1147 1148 close(routes); 1149 default_route_gateway = (cmd == 's')? g: 0; 1150 return 1; 1151 } 1152 1153 #if RTM_VERSION >= 3 1154 1155 /* 1156 * sifproxyarp - Make a proxy ARP entry for the peer. 1157 */ 1158 static struct { 1159 struct rt_msghdr hdr; 1160 struct sockaddr_inarp dst; 1161 struct sockaddr_dl hwa; 1162 char extra[128]; 1163 } arpmsg; 1164 1165 static int arpmsg_valid; 1166 1167 int 1168 sifproxyarp(unit, hisaddr) 1169 int unit; 1170 u_int32_t hisaddr; 1171 { 1172 int routes; 1173 1174 /* 1175 * Get the hardware address of an interface on the same subnet 1176 * as our local address. 1177 */ 1178 memset(&arpmsg, 0, sizeof(arpmsg)); 1179 if (!get_ether_addr(hisaddr, &arpmsg.hwa)) { 1180 syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP"); 1181 return 0; 1182 } 1183 1184 if ((routes = socket(AF_ROUTE, SOCK_RAW, AF_INET)) == -1) { 1185 syslog(LOG_ERR, "Couldn't add proxy arp entry: socket: %m"); 1186 return 0; 1187 } 1188 1189 arpmsg.hdr.rtm_type = RTM_ADD; 1190 arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC; 1191 arpmsg.hdr.rtm_version = RTM_VERSION; 1192 arpmsg.hdr.rtm_seq = ++rtm_seq; 1193 arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY; 1194 arpmsg.hdr.rtm_inits = RTV_EXPIRE; 1195 arpmsg.dst.sin_len = sizeof(struct sockaddr_inarp); 1196 arpmsg.dst.sin_family = AF_INET; 1197 arpmsg.dst.sin_addr.s_addr = hisaddr; 1198 arpmsg.dst.sin_other = SIN_PROXY; 1199 1200 arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg 1201 + arpmsg.hwa.sdl_len; 1202 if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) == -1) { 1203 syslog(LOG_ERR, "Couldn't add proxy arp entry: %m"); 1204 close(routes); 1205 return 0; 1206 } 1207 1208 close(routes); 1209 arpmsg_valid = 1; 1210 proxy_arp_addr = hisaddr; 1211 return 1; 1212 } 1213 1214 /* 1215 * cifproxyarp - Delete the proxy ARP entry for the peer. 1216 */ 1217 int 1218 cifproxyarp(unit, hisaddr) 1219 int unit; 1220 u_int32_t hisaddr; 1221 { 1222 int routes; 1223 1224 if (!arpmsg_valid) 1225 return 0; 1226 arpmsg_valid = 0; 1227 1228 arpmsg.hdr.rtm_type = RTM_DELETE; 1229 arpmsg.hdr.rtm_seq = ++rtm_seq; 1230 1231 if ((routes = socket(AF_ROUTE, SOCK_RAW, AF_INET)) == -1) { 1232 syslog(LOG_ERR, "Couldn't delete proxy arp entry: socket: %m"); 1233 return 0; 1234 } 1235 1236 if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) == -1) { 1237 syslog(LOG_ERR, "Couldn't delete proxy arp entry: %m"); 1238 close(routes); 1239 return 0; 1240 } 1241 1242 close(routes); 1243 proxy_arp_addr = 0; 1244 return 1; 1245 } 1246 1247 #else /* RTM_VERSION */ 1248 1249 /* 1250 * sifproxyarp - Make a proxy ARP entry for the peer. 1251 */ 1252 int 1253 sifproxyarp(unit, hisaddr) 1254 int unit; 1255 u_int32_t hisaddr; 1256 { 1257 struct arpreq arpreq; 1258 struct { 1259 struct sockaddr_dl sdl; 1260 char space[128]; 1261 } dls; 1262 1263 BZERO(&arpreq, sizeof(arpreq)); 1264 1265 /* 1266 * Get the hardware address of an interface on the same subnet 1267 * as our local address. 1268 */ 1269 if (!get_ether_addr(hisaddr, &dls.sdl)) { 1270 syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP"); 1271 return 0; 1272 } 1273 1274 arpreq.arp_ha.sa_len = sizeof(struct sockaddr); 1275 arpreq.arp_ha.sa_family = AF_UNSPEC; 1276 BCOPY(LLADDR(&dls.sdl), arpreq.arp_ha.sa_data, dls.sdl.sdl_alen); 1277 SET_SA_FAMILY(arpreq.arp_pa, AF_INET); 1278 ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; 1279 arpreq.arp_flags = ATF_PERM | ATF_PUBL; 1280 if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) == -1) { 1281 syslog(LOG_ERR, "Couldn't add proxy arp entry: %m"); 1282 return 0; 1283 } 1284 1285 proxy_arp_addr = hisaddr; 1286 return 1; 1287 } 1288 1289 /* 1290 * cifproxyarp - Delete the proxy ARP entry for the peer. 1291 */ 1292 int 1293 cifproxyarp(unit, hisaddr) 1294 int unit; 1295 u_int32_t hisaddr; 1296 { 1297 struct arpreq arpreq; 1298 1299 BZERO(&arpreq, sizeof(arpreq)); 1300 SET_SA_FAMILY(arpreq.arp_pa, AF_INET); 1301 ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; 1302 if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) == -1) { 1303 syslog(LOG_WARNING, "Couldn't delete proxy arp entry: %m"); 1304 return 0; 1305 } 1306 proxy_arp_addr = 0; 1307 return 1; 1308 } 1309 #endif /* RTM_VERSION */ 1310 1311 1312 /* 1313 * get_ether_addr - get the hardware address of an interface on the 1314 * the same subnet as ipaddr. 1315 */ 1316 #define MAX_IFS 32 1317 1318 static int 1319 get_ether_addr(ipaddr, hwaddr) 1320 u_int32_t ipaddr; 1321 struct sockaddr_dl *hwaddr; 1322 { 1323 u_int32_t ina, mask; 1324 struct sockaddr_dl *dla; 1325 struct ifaddrs *ifap, *ifa, *ifp; 1326 1327 if (getifaddrs(&ifap) != 0) { 1328 syslog(LOG_ERR, "getifaddrs: %m"); 1329 return 0; 1330 } 1331 1332 /* 1333 * Scan through looking for an interface with an Internet 1334 * address on the same subnet as `ipaddr'. 1335 */ 1336 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 1337 if (ifa->ifa_addr == NULL) 1338 continue; 1339 if (ifa->ifa_addr->sa_family == AF_INET) { 1340 ina = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; 1341 /* 1342 * Check that the interface is up, and not point-to-point 1343 * or loopback. 1344 */ 1345 if ((ifa->ifa_flags & 1346 (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP)) 1347 != (IFF_UP|IFF_BROADCAST)) 1348 continue; 1349 /* 1350 * Get its netmask and check that it's on the right subnet. 1351 */ 1352 mask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr.s_addr; 1353 if ((ipaddr & mask) != (ina & mask)) 1354 continue; 1355 1356 break; 1357 } 1358 } 1359 1360 if (ifa == NULL) { 1361 freeifaddrs(ifap); 1362 return 0; 1363 } 1364 syslog(LOG_INFO, "found interface %s for proxy arp", ifa->ifa_name); 1365 1366 /* 1367 * Now scan through again looking for a link-level address 1368 * for this interface. 1369 */ 1370 ifp = ifa; 1371 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 1372 if (ifa->ifa_addr == NULL) 1373 continue; 1374 if (strcmp(ifp->ifa_name, ifa->ifa_name) == 0 1375 && ifa->ifa_addr->sa_family == AF_LINK) { 1376 /* 1377 * Found the link-level address - copy it out 1378 */ 1379 dla = (struct sockaddr_dl *)ifa->ifa_addr; 1380 BCOPY(dla, hwaddr, dla->sdl_len); 1381 return 1; 1382 } 1383 } 1384 1385 freeifaddrs(ifap); 1386 return 0; 1387 } 1388 1389 /* 1390 * Return user specified netmask, modified by any mask we might determine 1391 * for address `addr' (in network byte order). 1392 * Here we scan through the system's list of interfaces, looking for 1393 * any non-point-to-point interfaces which might appear to be on the same 1394 * network as `addr'. If we find any, we OR in their netmask to the 1395 * user-specified netmask. 1396 */ 1397 u_int32_t 1398 GetMask(addr) 1399 u_int32_t addr; 1400 { 1401 u_int32_t mask, nmask, ina; 1402 struct ifaddrs *ifap, *ifa; 1403 1404 addr = ntohl(addr); 1405 if (IN_CLASSA(addr)) /* determine network mask for address class */ 1406 nmask = IN_CLASSA_NET; 1407 else if (IN_CLASSB(addr)) 1408 nmask = IN_CLASSB_NET; 1409 else 1410 nmask = IN_CLASSC_NET; 1411 /* class D nets are disallowed by bad_ip_adrs */ 1412 mask = netmask | htonl(nmask); 1413 1414 /* 1415 * Scan through the system's network interfaces. 1416 */ 1417 if (getifaddrs(&ifap) != 0) { 1418 syslog(LOG_WARNING, "getifaddrs: %m"); 1419 return mask; 1420 } 1421 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 1422 /* 1423 * Check the interface's internet address. 1424 */ 1425 if (ifa->ifa_addr == NULL || 1426 ifa->ifa_addr->sa_family != AF_INET) 1427 continue; 1428 ina = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; 1429 if ((ntohl(ina) & nmask) != (addr & nmask)) 1430 continue; 1431 /* 1432 * Check that the interface is up, and not point-to-point or loopback. 1433 */ 1434 if ((ifa->ifa_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) 1435 != IFF_UP) 1436 continue; 1437 /* 1438 * Get its netmask and OR it into our mask. 1439 */ 1440 mask |= ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr.s_addr; 1441 } 1442 1443 freeifaddrs(ifap); 1444 return mask; 1445 } 1446 1447 /* 1448 * lock - create a lock file for the named lock device 1449 */ 1450 #define LOCK_PREFIX "/var/spool/lock/LCK.." 1451 1452 int 1453 lock(dev) 1454 char *dev; 1455 { 1456 char hdb_lock_buffer[12]; 1457 int fd, n; 1458 pid_t pid; 1459 char *p; 1460 1461 if ((p = strrchr(dev, '/')) != NULL) 1462 dev = p + 1; 1463 if (asprintf(&lock_file, "%s%s", LOCK_PREFIX, dev) == -1) 1464 novm("lock file name"); 1465 1466 while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) == -1) { 1467 if (errno == EEXIST 1468 && (fd = open(lock_file, O_RDONLY, 0)) >= 0) { 1469 /* Read the lock file to find out who has the device locked */ 1470 n = read(fd, hdb_lock_buffer, 11); 1471 if (n <= 0) { 1472 syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file); 1473 close(fd); 1474 } else { 1475 hdb_lock_buffer[n] = 0; 1476 pid = atoi(hdb_lock_buffer); 1477 if (kill(pid, 0) == -1 && errno == ESRCH) { 1478 /* pid no longer exists - remove the lock file */ 1479 if (unlink(lock_file) == 0) { 1480 close(fd); 1481 syslog(LOG_NOTICE, "Removed stale lock on %s (pid %ld)", 1482 dev, (long)pid); 1483 continue; 1484 } else 1485 syslog(LOG_WARNING, "Couldn't remove stale lock on %s", 1486 dev); 1487 } else 1488 syslog(LOG_NOTICE, "Device %s is locked by pid %ld", 1489 dev, (long)pid); 1490 } 1491 close(fd); 1492 } else 1493 syslog(LOG_ERR, "Can't create lock file %s: %m", lock_file); 1494 free(lock_file); 1495 lock_file = NULL; 1496 return -1; 1497 } 1498 1499 snprintf(hdb_lock_buffer, sizeof hdb_lock_buffer, "%10ld\n", (long)getpid()); 1500 write(fd, hdb_lock_buffer, 11); 1501 1502 close(fd); 1503 return 0; 1504 } 1505 1506 /* 1507 * unlock - remove our lockfile 1508 */ 1509 void 1510 unlock() 1511 { 1512 if (lock_file) { 1513 unlink(lock_file); 1514 free(lock_file); 1515 lock_file = NULL; 1516 } 1517 } 1518