1 /* NetBSD: sys-bsd.c,v 1.68 2013/06/24 20:43:48 christos 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 #include <sys/cdefs.h> 78 #ifndef lint 79 #if 0 80 #define RCSID "Id: sys-bsd.c,v 1.47 2000/04/13 12:04:23 paulus Exp " 81 #else 82 __RCSID("NetBSD: sys-bsd.c,v 1.68 2013/06/24 20:43:48 christos Exp "); 83 #endif 84 #endif 85 86 /* 87 * TODO: 88 */ 89 90 #include <stdio.h> 91 #include <string.h> 92 #include <stdlib.h> 93 #include <unistd.h> 94 #include <errno.h> 95 #include <fcntl.h> 96 #include <termios.h> 97 #include <signal.h> 98 #include <vis.h> 99 #include <sys/ioctl.h> 100 #include <sys/types.h> 101 #include <sys/socket.h> 102 #include <sys/time.h> 103 #include <sys/stat.h> 104 #include <sys/param.h> 105 #if defined(NetBSD1_2) || defined(__NetBSD_Version__) 106 #include <util.h> 107 #endif 108 #ifdef PPP_FILTER 109 #include <net/bpf.h> 110 #endif 111 112 #include <net/if.h> 113 #include <net/ppp_defs.h> 114 #include <net/if_ppp.h> 115 #include <net/route.h> 116 #include <net/if_dl.h> 117 #include <netinet/in.h> 118 #ifdef __KAME__ 119 #include <netinet6/in6_var.h> 120 #include <netinet6/nd6.h> 121 #endif 122 #include <ifaddrs.h> 123 124 #ifndef IN6_LLADDR_FROM_EUI64 125 #ifdef __KAME__ 126 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \ 127 sin6.sin6_family = AF_INET6; \ 128 sin6.sin6_len = sizeof(struct sockaddr_in6); \ 129 sin6.sin6_addr.s6_addr[0] = 0xfe; \ 130 sin6.sin6_addr.s6_addr[1] = 0x80; \ 131 eui64_copy(eui64, sin6.sin6_addr.s6_addr[8]); \ 132 } while (/*CONSTCOND*/0) 133 #define IN6_IFINDEX(sin6, ifindex) \ 134 /* KAME ifindex hack */ \ 135 *(u_int16_t *)&sin6.sin6_addr.s6_addr[2] = htons(ifindex) 136 #else 137 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do { \ 138 memset(&sin6.s6_addr, 0, sizeof(struct in6_addr)); \ 139 sin6.s6_addr16[0] = htons(0xfe80); \ 140 eui64_copy(eui64, sin6.s6_addr32[2]); \ 141 } while (/*CONSTCOND*/0) 142 #endif 143 #endif 144 145 #if RTM_VERSION >= 3 146 #include <sys/param.h> 147 #if defined(NetBSD) && (NetBSD >= 199703) 148 #include <netinet/if_inarp.h> 149 #else /* NetBSD 1.2D or later */ 150 #ifdef __FreeBSD__ 151 #include <netinet/if_ether.h> 152 #else 153 #include <net/if_ether.h> 154 #endif 155 #endif 156 #endif 157 158 #include "pppd.h" 159 #include "fsm.h" 160 #include "ipcp.h" 161 162 #ifdef RCSID 163 static const char rcsid[] = RCSID; 164 #endif 165 166 static int initdisc = -1; /* Initial TTY discipline for ppp_fd */ 167 static int initfdflags = -1; /* Initial file descriptor flags for ppp_fd */ 168 static int ppp_fd = -1; /* fd which is set to PPP discipline */ 169 static int rtm_seq; 170 171 static int restore_term; /* 1 => we've munged the terminal */ 172 static struct termios inittermios; /* Initial TTY termios */ 173 static struct winsize wsinfo; /* Initial window size info */ 174 175 static int loop_slave = -1; 176 static int loop_master = -1; 177 static int doing_cleanup = 0; 178 static char loop_name[20]; 179 180 static unsigned char inbuf[512]; /* buffer for chars read from loopback */ 181 182 static int sock_fd; /* socket for doing interface ioctls */ 183 #ifdef INET6 184 static int sock6_fd = -1; /* socket for doing ipv6 interface ioctls */ 185 #endif /* INET6 */ 186 static int ttyfd = -1; /* the file descriptor of the tty */ 187 188 static fd_set in_fds; /* set of fds that wait_input waits for */ 189 static int max_in_fd; /* highest fd set in in_fds */ 190 191 static int if_is_up; /* the interface is currently up */ 192 static u_int32_t ifaddrs[2]; /* local and remote addresses we set */ 193 static u_int32_t default_route_gateway; /* gateway addr for default route */ 194 static u_int32_t proxy_arp_addr; /* remote addr for proxy arp */ 195 196 /* Prototypes for procedures local to this file. */ 197 static int get_flags(int); 198 static void set_flags(int, int); 199 static int dodefaultroute(u_int32_t, int); 200 static int get_ether_addr(u_int32_t, struct sockaddr_dl *); 201 static void restore_loop(void); /* Transfer ppp unit back to loopback */ 202 203 204 static void 205 set_queue_size(const char *fmt, int fd) { 206 #ifdef TIOCSQSIZE 207 int oqsize, qsize = 32768; 208 209 /* Only for ptys */ 210 if (ioctl(fd, TIOCGQSIZE, &oqsize) == -1) 211 return; 212 213 if (oqsize >= qsize) 214 return; 215 216 if (ioctl(fd, TIOCSQSIZE, &qsize) == -1) 217 warn("%s: Cannot set tty queue size for %d from %d to %d", fmt, fd, 218 oqsize, qsize); 219 else 220 notice("%s: Changed queue size of %d from %d to %d", fmt, fd, oqsize, 221 qsize); 222 #endif 223 } 224 225 /******************************************************************** 226 * 227 * Functions to read and set the flags value in the device driver 228 */ 229 230 static int 231 get_flags(int fd) 232 { 233 int flags; 234 235 if (ioctl(fd, PPPIOCGFLAGS, (caddr_t) &flags) == -1) 236 fatal("%s: ioctl(PPPIOCGFLAGS): %m", __func__); 237 238 SYSDEBUG((LOG_DEBUG, "get flags = %x\n", flags)); 239 return flags; 240 } 241 242 /********************************************************************/ 243 244 static void 245 set_flags(int fd, int flags) 246 { 247 SYSDEBUG((LOG_DEBUG, "set flags = %x\n", flags)); 248 249 if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &flags) == -1) 250 fatal("%s: ioctl(PPPIOCSFLAGS, %x): %m", __func__, flags, errno); 251 } 252 253 /* 254 * sys_init - System-dependent initialization. 255 */ 256 void 257 sys_init(void) 258 { 259 /* Get an internet socket for doing socket ioctl's on. */ 260 if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 261 fatal("%s: Couldn't create IP socket: %m", __func__); 262 263 #ifdef INET6 264 if ((sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 265 /* check it at runtime */ 266 sock6_fd = -1; 267 } 268 #endif 269 270 FD_ZERO(&in_fds); 271 max_in_fd = 0; 272 } 273 274 /* 275 * sys_cleanup - restore any system state we modified before exiting: 276 * mark the interface down, delete default route and/or proxy arp entry. 277 * This should call die() because it's called from die(). 278 */ 279 void 280 sys_cleanup(void) 281 { 282 struct ifreq ifr; 283 284 doing_cleanup = 1; 285 if (if_is_up) { 286 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 287 if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) >= 0 288 && ((ifr.ifr_flags & IFF_UP) != 0)) { 289 ifr.ifr_flags &= ~IFF_UP; 290 ioctl(sock_fd, SIOCSIFFLAGS, &ifr); 291 } 292 } 293 if (ifaddrs[0] != 0) 294 cifaddr(0, ifaddrs[0], ifaddrs[1]); 295 if (default_route_gateway) 296 cifdefaultroute(0, 0, default_route_gateway); 297 if (proxy_arp_addr) 298 cifproxyarp(0, proxy_arp_addr); 299 doing_cleanup = 0; 300 } 301 302 /* 303 * sys_close - Clean up in a child process before execing. 304 */ 305 void 306 sys_close() 307 { 308 if (sock_fd >= 0) 309 close(sock_fd); 310 #ifdef INET6 311 if (sock6_fd >= 0) 312 close(sock6_fd); 313 #endif 314 if (loop_slave >= 0) 315 close(loop_slave); 316 if (loop_master >= 0) 317 close(loop_master); 318 } 319 320 /* 321 * sys_check_options - check the options that the user specified 322 */ 323 int 324 sys_check_options(void) 325 { 326 #ifndef CDTRCTS 327 if (crtscts == 2) { 328 warn("%s: DTR/CTS flow control is not supported on this system", 329 __func__); 330 return 0; 331 } 332 #endif 333 return 1; 334 } 335 336 /* 337 * ppp_available - check whether the system has any ppp interfaces 338 * (in fact we check whether we can do an ioctl on ppp0). 339 */ 340 int 341 ppp_available(void) 342 { 343 struct if_clonereq ifcr; 344 char *cp, *buf; 345 int idx, s; 346 extern char *no_ppp_msg; 347 348 (void)memset(&ifcr, 0, sizeof(ifcr)); 349 350 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 351 fatal("%s: socket: %m", __func__); 352 353 if (ioctl(s, SIOCIFGCLONERS, &ifcr) == -1) 354 fatal("%s: ioctl(get cloners): %m", __func__); 355 356 buf = malloc(ifcr.ifcr_total * IFNAMSIZ); 357 if (buf == NULL) 358 fatal("%s: Unable to allocate cloner name buffer: %m", __func__); 359 360 ifcr.ifcr_count = ifcr.ifcr_total; 361 ifcr.ifcr_buffer = buf; 362 363 if (ioctl(s, SIOCIFGCLONERS, &ifcr) == -1) 364 fatal("%s: ioctl(get cloners): %m", __func__); 365 (void)close(s); 366 367 /* 368 * In case some disappeared in the mean time, clamp it down. 369 */ 370 if (ifcr.ifcr_count > ifcr.ifcr_total) 371 ifcr.ifcr_count = ifcr.ifcr_total; 372 373 for (cp = buf, idx = 0; idx < ifcr.ifcr_count; idx++, cp += IFNAMSIZ) { 374 if (strcmp(cp, "ppp") == 0) 375 break; 376 } 377 free(buf); 378 379 #ifdef __NetBSD__ 380 no_ppp_msg = "\ 381 This system lacks kernel support for PPP. To include PPP support\n\ 382 in the kernel, please read the ppp(4) manual page.\n"; 383 #else 384 no_ppp_msg = "\ 385 This system lacks kernel support for PPP. To include PPP support\n\ 386 in the kernel, please follow the steps detailed in the README.bsd\n\ 387 file in the ppp-2.2 distribution.\n"; 388 #endif 389 return idx != ifcr.ifcr_count; 390 } 391 392 /* 393 * tty_establish_ppp - Turn the serial port into a ppp interface. 394 */ 395 int 396 tty_establish_ppp(int fd) 397 { 398 int pppdisc = PPPDISC; 399 int x; 400 ttyfd = fd; 401 402 if (demand) { 403 /* 404 * Demand mode - prime the old ppp device to relinquish the unit. 405 */ 406 if (ioctl(ppp_fd, PPPIOCXFERUNIT, 0) < 0) 407 fatal("%s: ioctl(transfer ppp unit): %m", __func__); 408 } 409 410 set_queue_size(__func__, fd); 411 /* 412 * Save the old line discipline of fd, and set it to PPP. 413 */ 414 if (ioctl(fd, TIOCGETD, &initdisc) < 0) 415 fatal("%s: ioctl(TIOCGETD): %m", __func__); 416 if (ioctl(fd, TIOCSETD, &pppdisc) < 0) 417 fatal("%s: ioctl(TIOCSETD): %m", __func__); 418 419 if (ioctl(fd, PPPIOCGUNIT, &x) < 0) 420 fatal("%s: ioctl(PPPIOCGUNIT): %m", __func__); 421 if (!demand) { 422 /* 423 * Find out which interface we were given. 424 */ 425 ifunit = x; 426 } else { 427 /* 428 * Check that we got the same unit again. 429 */ 430 if (x != ifunit) 431 fatal("%s: transfer_ppp failed: wanted unit %d, got %d", 432 __func__, ifunit, x); 433 x = TTYDISC; 434 if (ioctl(loop_slave, TIOCSETD, &x) == -1) 435 fatal("%s: ioctl(TIOCGETD): %m", __func__); 436 } 437 438 ppp_fd = fd; 439 440 /* 441 * Enable debug in the driver if requested. 442 */ 443 if (kdebugflag) { 444 x = get_flags(fd); 445 x |= (kdebugflag & 0xFF) * SC_DEBUG; 446 set_flags(fd, x); 447 } 448 449 /* 450 * Set device for non-blocking reads. 451 */ 452 if ((initfdflags = fcntl(fd, F_GETFL)) == -1 453 || fcntl(fd, F_SETFL, initfdflags | O_NONBLOCK) == -1) { 454 warn("%s: Couldn't set device to non-blocking mode: %m", __func__); 455 } 456 457 return fd; 458 } 459 460 /* 461 * restore_loop - reattach the ppp unit to the loopback. 462 */ 463 static void 464 restore_loop(void) 465 { 466 int x; 467 468 set_queue_size(__func__, loop_slave); 469 /* 470 * Transfer the ppp interface back to the loopback. 471 */ 472 if (ioctl(ppp_fd, PPPIOCXFERUNIT, 0) < 0) 473 fatal("%s: ioctl(transfer ppp unit): %m", __func__); 474 x = PPPDISC; 475 if (ioctl(loop_slave, TIOCSETD, &x) < 0) 476 fatal("%s: ioctl(TIOCSETD): %m", __func__); 477 478 /* 479 * Check that we got the same unit again. 480 */ 481 if (ioctl(loop_slave, PPPIOCGUNIT, &x) < 0) 482 fatal("%s: ioctl(PPPIOCGUNIT): %m", __func__); 483 if (x != ifunit) 484 fatal("%s: transfer_ppp failed: wanted unit %d, got %d", __func__, 485 ifunit, x); 486 ppp_fd = loop_slave; 487 } 488 489 490 /* 491 * Determine if the PPP connection should still be present. 492 */ 493 extern int hungup; 494 495 /* 496 * tty_disestablish_ppp - Restore the serial port to normal operation. 497 * and reconnect the ppp unit to the loopback if in demand mode. 498 * This shouldn't call die() because it's called from die(). 499 */ 500 void 501 tty_disestablish_ppp(fd) 502 int fd; 503 { 504 if (!doing_cleanup && demand) 505 restore_loop(); 506 507 if (!hungup || demand) { 508 509 /* Flush the tty output buffer so that the TIOCSETD doesn't hang. */ 510 if (tcflush(fd, TCIOFLUSH) < 0) 511 if (!doing_cleanup) 512 warn("%s: tcflush failed: %m", __func__); 513 514 /* Restore old line discipline. */ 515 if (initdisc >= 0 && ioctl(fd, TIOCSETD, &initdisc) < 0) 516 if (!doing_cleanup) 517 error("%s: ioctl(TIOCSETD): %m", __func__); 518 initdisc = -1; 519 520 /* Reset non-blocking mode on fd. */ 521 if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) < 0) 522 if (!doing_cleanup) 523 warn("%s: Couldn't restore device fd flags: %m", __func__); 524 } 525 initfdflags = -1; 526 527 if (fd == ppp_fd) 528 ppp_fd = -1; 529 } 530 531 /* 532 * cfg_bundle - configure the existing bundle. 533 * Used in demand mode. 534 */ 535 void 536 cfg_bundle(int mrru, int mtru, int rssn, int tssn) 537 { 538 abort(); 539 #ifdef notyet 540 int flags; 541 struct ifreq ifr; 542 543 if (!new_style_driver) 544 return; 545 546 /* set the mrru, mtu and flags */ 547 if (ioctl(ppp_dev_fd, PPPIOCSMRRU, &mrru) < 0) 548 error("%s: Couldn't set MRRU: %m", __func__); 549 flags = get_flags(ppp_dev_fd); 550 flags &= ~(SC_MP_SHORTSEQ | SC_MP_XSHORTSEQ); 551 flags |= (rssn? SC_MP_SHORTSEQ: 0) | (tssn? SC_MP_XSHORTSEQ: 0) 552 | (mrru? SC_MULTILINK: 0); 553 554 set_flags(ppp_dev_fd, flags); 555 556 /* connect up the channel */ 557 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifunit) < 0) 558 fatal("%s: Couldn't attach to PPP unit %d: %m", __func__, ifunit); 559 add_fd(ppp_dev_fd); 560 #endif 561 } 562 563 /* 564 * make_new_bundle - create a new PPP unit (i.e. a bundle) 565 * and connect our channel to it. This should only get called 566 * if `multilink' was set at the time establish_ppp was called. 567 * In demand mode this uses our existing bundle instead of making 568 * a new one. 569 */ 570 void 571 make_new_bundle(int mrru, int mtru, int rssn, int tssn) 572 { 573 abort(); 574 #ifdef notyet 575 if (!new_style_driver) 576 return; 577 578 /* make us a ppp unit */ 579 if (make_ppp_unit() < 0) 580 die(1); 581 582 /* set the mrru, mtu and flags */ 583 cfg_bundle(mrru, mtru, rssn, tssn); 584 #endif 585 } 586 587 /* 588 * bundle_attach - attach our link to a given PPP unit. 589 * We assume the unit is controlled by another pppd. 590 */ 591 int 592 bundle_attach(int ifnum) 593 { 594 abort(); 595 #ifdef notyet 596 if (!new_style_driver) 597 return -1; 598 599 if (ioctl(ppp_dev_fd, PPPIOCATTACH, &ifnum) < 0) { 600 if (errno == ENXIO) 601 return 0; /* doesn't still exist */ 602 fatal("%s: Couldn't attach to interface unit %d: %m", __func__, ifnum); 603 } 604 if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0) 605 fatal("%s: Couldn't connect to interface unit %d: %m", __func__, ifnum); 606 set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_MULTILINK); 607 608 ifunit = ifnum; 609 #endif 610 return 1; 611 } 612 613 /* 614 * destroy_bundle - tell the driver to destroy our bundle. 615 */ 616 void destroy_bundle(void) 617 { 618 #if notyet 619 if (ppp_dev_fd >= 0) { 620 close(ppp_dev_fd); 621 remove_fd(ppp_dev_fd); 622 ppp_dev_fd = -1; 623 } 624 #endif 625 } 626 627 /* 628 * Check whether the link seems not to be 8-bit clean. 629 */ 630 void 631 clean_check(void) 632 { 633 int x; 634 char *s; 635 636 if (ioctl(ppp_fd, PPPIOCGFLAGS, (caddr_t) &x) == 0) { 637 s = NULL; 638 switch (~x & (SC_RCV_B7_0|SC_RCV_B7_1|SC_RCV_EVNP|SC_RCV_ODDP)) { 639 case SC_RCV_B7_0: 640 s = "bit 7 set to 1"; 641 break; 642 case SC_RCV_B7_1: 643 s = "bit 7 set to 0"; 644 break; 645 case SC_RCV_EVNP: 646 s = "odd parity"; 647 break; 648 case SC_RCV_ODDP: 649 s = "even parity"; 650 break; 651 } 652 if (s != NULL) { 653 struct ppp_rawin win; 654 char buf[4 * sizeof(win.buf) + 1]; 655 int i; 656 warn("%s: Serial link is not 8-bit clean:", __func__); 657 warn("%s: All received characters had %s", __func__, s); 658 if (ioctl(ppp_fd, PPPIOCGRAWIN, &win) == -1) { 659 warn("%s: ioctl(PPPIOCGRAWIN): %s", __func__, strerror(errno)); 660 return; 661 } 662 for (i = 0; i < sizeof(win.buf); i++) 663 win.buf[i] = win.buf[i] & 0x7f; 664 strvisx(buf, (char *)win.buf, win.count, VIS_CSTYLE); 665 warn("%s: Last %d characters were: %s", __func__, (int)win.count, 666 buf); 667 } 668 } 669 } 670 671 672 /* 673 * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity, 674 * at the requested speed, etc. If `local' is true, set CLOCAL 675 * regardless of whether the modem option was specified. 676 * 677 * For *BSD, we assume that speed_t values numerically equal bits/second. 678 */ 679 void 680 set_up_tty(int fd, int local) 681 { 682 struct termios tios; 683 684 if (tcgetattr(fd, &tios) < 0) 685 fatal("%s: tcgetattr: %m", __func__); 686 687 if (!restore_term) { 688 inittermios = tios; 689 ioctl(fd, TIOCGWINSZ, &wsinfo); 690 } 691 692 set_queue_size(__func__, fd); 693 694 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL); 695 if (crtscts > 0 && !local) { 696 if (crtscts == 2) { 697 #ifdef CDTRCTS 698 tios.c_cflag |= CDTRCTS; 699 #endif 700 } else 701 tios.c_cflag |= CRTSCTS; 702 } else if (crtscts < 0) { 703 tios.c_cflag &= ~CRTSCTS; 704 #ifdef CDTRCTS 705 tios.c_cflag &= ~CDTRCTS; 706 #endif 707 } 708 709 tios.c_cflag |= CS8 | CREAD | HUPCL; 710 if (local || !modem) 711 tios.c_cflag |= CLOCAL; 712 tios.c_iflag = IGNBRK | IGNPAR; 713 tios.c_oflag = 0; 714 tios.c_lflag = 0; 715 tios.c_cc[VMIN] = 1; 716 tios.c_cc[VTIME] = 0; 717 718 if (crtscts == -2) { 719 tios.c_iflag |= IXON | IXOFF; 720 tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */ 721 tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */ 722 } 723 724 if (inspeed) { 725 cfsetospeed(&tios, inspeed); 726 cfsetispeed(&tios, inspeed); 727 } else { 728 inspeed = cfgetospeed(&tios); 729 /* 730 * We can't proceed if the serial port speed is 0, 731 * since that implies that the serial port is disabled. 732 */ 733 if (inspeed == 0) 734 fatal("%s: Baud rate for %s is 0; need explicit baud rate", 735 __func__, devnam); 736 } 737 baud_rate = inspeed; 738 739 if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) 740 fatal("%s: tcsetattr: %m", __func__); 741 742 restore_term = 1; 743 } 744 745 /* 746 * restore_tty - restore the terminal to the saved settings. 747 */ 748 void 749 restore_tty(int fd) 750 { 751 if (restore_term) { 752 if (!default_device) { 753 /* 754 * Turn off echoing, because otherwise we can get into 755 * a loop with the tty and the modem echoing to each other. 756 * We presume we are the sole user of this tty device, so 757 * when we close it, it will revert to its defaults anyway. 758 */ 759 inittermios.c_lflag &= ~(ECHO | ECHONL); 760 } 761 if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0) 762 if (errno != ENXIO) 763 warn("%s: tcsetattr: %m", __func__); 764 ioctl(fd, TIOCSWINSZ, &wsinfo); 765 restore_term = 0; 766 } 767 } 768 769 /* 770 * setdtr - control the DTR line on the serial port. 771 * This is called from die(), so it shouldn't call die(). 772 */ 773 void 774 setdtr(int fd, int on) 775 { 776 int modembits = TIOCM_DTR; 777 778 ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits); 779 } 780 781 #ifdef INET6 782 /* 783 * sif6addr - Config the interface with an IPv6 link-local address 784 */ 785 int 786 sif6addr(int unit, eui64_t our_eui64, eui64_t his_eui64) 787 { 788 #ifdef __KAME__ 789 int ifindex; 790 struct in6_aliasreq addreq6; 791 792 if (sock6_fd < 0) { 793 fatal("%s: No IPv6 socket available", __func__); 794 /*NOTREACHED*/ 795 } 796 797 /* actually, this part is not kame local - RFC2553 conformant */ 798 ifindex = if_nametoindex(ifname); 799 if (ifindex == 0) { 800 error("%s: sifaddr6: no interface %s", __func__, ifname); 801 return 0; 802 } 803 804 memset(&addreq6, 0, sizeof(addreq6)); 805 strlcpy(addreq6.ifra_name, ifname, sizeof(addreq6.ifra_name)); 806 807 /* my addr */ 808 IN6_LLADDR_FROM_EUI64(addreq6.ifra_addr, our_eui64); 809 IN6_IFINDEX(addreq6.ifra_addr, ifindex); 810 811 #ifdef notdef 812 /* his addr */ 813 IN6_LLADDR_FROM_EUI64(addreq6.ifra_dstaddr, his_eui64); 814 IN6_IFINDEX(addreq6.ifra_dstaddr, ifindex); 815 #endif 816 817 /* prefix mask: 72bit */ 818 addreq6.ifra_prefixmask.sin6_family = AF_INET6; 819 addreq6.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6); 820 memset(&addreq6.ifra_prefixmask.sin6_addr, 0xff, 821 sizeof(addreq6.ifra_prefixmask.sin6_addr) - sizeof(our_eui64)); 822 memset((char *)&addreq6.ifra_prefixmask.sin6_addr + 823 sizeof(addreq6.ifra_prefixmask.sin6_addr) - sizeof(our_eui64), 0x00, 824 sizeof(our_eui64)); 825 826 /* address lifetime (infty) */ 827 addreq6.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; 828 addreq6.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; 829 830 if (ioctl(sock6_fd, SIOCAIFADDR_IN6, &addreq6) < 0) { 831 error("%s: sif6addr: ioctl(SIOCAIFADDR_IN6): %m", __func__); 832 return 0; 833 } 834 835 return 1; 836 #else 837 struct in6_ifreq ifr6; 838 struct ifreq ifr; 839 struct in6_rtmsg rt6; 840 841 if (sock6_fd < 0) { 842 fatal("%s: No IPv6 socket available", __func__); 843 /*NOTREACHED*/ 844 } 845 846 memset(&ifr, 0, sizeof (ifr)); 847 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 848 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { 849 error("%s: sif6addr: ioctl(SIOCGIFINDEX): %m", __func__); 850 return 0; 851 } 852 853 /* Local interface */ 854 memset(&ifr6, 0, sizeof(ifr6)); 855 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); 856 ifr6.ifr6_ifindex = ifindex; 857 ifr6.ifr6_prefixlen = 10; 858 859 if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) { 860 error("%s: sif6addr: ioctl(SIOCSIFADDR): %m", __func__); 861 return 0; 862 } 863 864 /* Route to remote host */ 865 memset(&rt6, 0, sizeof(rt6)); 866 IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64); 867 rt6.rtmsg_flags = RTF_UP; 868 rt6.rtmsg_dst_len = 10; 869 rt6.rtmsg_ifindex = ifr.ifr_ifindex; 870 rt6.rtmsg_metric = 1; 871 872 if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) { 873 error("%s: sif6addr: ioctl(SIOCADDRT): %m", __func__); 874 return 0; 875 } 876 877 return 1; 878 #endif 879 } 880 881 882 /* 883 * cif6addr - Remove IPv6 address from interface 884 */ 885 int 886 cif6addr(int unit, eui64_t our_eui64, eui64_t his_eui64) 887 { 888 #ifdef __KAME__ 889 int ifindex; 890 struct in6_ifreq delreq6; 891 892 if (sock6_fd < 0) { 893 fatal("%s: No IPv6 socket available", __func__); 894 /*NOTREACHED*/ 895 } 896 897 /* actually, this part is not kame local - RFC2553 conformant */ 898 ifindex = if_nametoindex(ifname); 899 if (ifindex == 0) { 900 error("%s: cifaddr6: no interface %s", __func__, ifname); 901 return 0; 902 } 903 904 memset(&delreq6, 0, sizeof(delreq6)); 905 strlcpy(delreq6.ifr_name, ifname, sizeof(delreq6.ifr_name)); 906 907 /* my addr */ 908 IN6_LLADDR_FROM_EUI64(delreq6.ifr_ifru.ifru_addr, our_eui64); 909 IN6_IFINDEX(delreq6.ifr_ifru.ifru_addr, ifindex); 910 911 if (ioctl(sock6_fd, SIOCDIFADDR_IN6, &delreq6) < 0) { 912 error("%s: cif6addr: ioctl(SIOCDIFADDR_IN6): %m", __func__); 913 return 0; 914 } 915 916 return 1; 917 #else 918 struct ifreq ifr; 919 struct in6_ifreq ifr6; 920 921 if (sock6_fd < 0) { 922 fatal("%s: No IPv6 socket available", __func__); 923 /*NOTREACHED*/ 924 } 925 926 memset(&ifr, 0, sizeof(ifr)); 927 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 928 if (ioctl(sock6_fd, SIOCGIFINDEX, (caddr_t) &ifr) < 0) { 929 error("%s: cif6addr: ioctl(SIOCGIFINDEX): %m", __func__); 930 return 0; 931 } 932 933 memset(&ifr6, 0, sizeof(ifr6)); 934 IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); 935 ifr6.ifr6_ifindex = ifr.ifr_ifindex; 936 ifr6.ifr6_prefixlen = 10; 937 938 if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) { 939 if (errno != EADDRNOTAVAIL) { 940 if (! ok_error (errno)) 941 error("%s: cif6addr: ioctl(SIOCDIFADDR): %m", __func__); 942 } 943 else { 944 warn("%s: cif6addr: ioctl(SIOCDIFADDR): No such address", __func__); 945 } 946 return (0); 947 } 948 return 1; 949 #endif 950 } 951 #endif /* INET6 */ 952 953 /* 954 * get_pty - get a pty master/slave pair and chown the slave side 955 * to the uid given. Assumes slave_name points to >= 12 bytes of space. 956 */ 957 int 958 get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid) 959 { 960 struct termios tios; 961 962 if (openpty(master_fdp, slave_fdp, slave_name, NULL, NULL) < 0) 963 return 0; 964 965 set_queue_size(__func__, *master_fdp); 966 set_queue_size(__func__, *slave_fdp); 967 fchown(*slave_fdp, uid, -1); 968 fchmod(*slave_fdp, S_IRUSR | S_IWUSR); 969 if (tcgetattr(*slave_fdp, &tios) == 0) { 970 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); 971 tios.c_cflag |= CS8 | CREAD | CLOCAL; 972 tios.c_iflag = IGNPAR; 973 tios.c_oflag = 0; 974 tios.c_lflag = 0; 975 if (tcsetattr(*slave_fdp, TCSAFLUSH, &tios) < 0) 976 warn("%s: couldn't set attributes on pty: %m", __func__); 977 } else 978 warn("%s: couldn't get attributes on pty: %m", __func__); 979 980 return 1; 981 } 982 983 984 /* 985 * open_ppp_loopback - open the device we use for getting 986 * packets in demand mode, and connect it to a ppp interface. 987 * Here we use a pty. 988 */ 989 int 990 open_ppp_loopback(void) 991 { 992 int flags; 993 struct termios tios; 994 int pppdisc = PPPDISC; 995 996 if (openpty(&loop_master, &loop_slave, loop_name, NULL, NULL) < 0) 997 fatal("%s: No free pty for loopback", __func__); 998 SYSDEBUG(("using %s for loopback", loop_name)); 999 1000 if (tcgetattr(loop_slave, &tios) == 0) { 1001 tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB); 1002 tios.c_cflag |= CS8 | CREAD | CLOCAL; 1003 tios.c_iflag = IGNPAR; 1004 tios.c_oflag = 0; 1005 tios.c_lflag = 0; 1006 if (tcsetattr(loop_slave, TCSAFLUSH, &tios) < 0) 1007 warn("%s: couldn't set attributes on loopback: %m", __func__); 1008 } 1009 1010 flags = fcntl(loop_master, F_GETFL); 1011 if (flags == -1 || fcntl(loop_master, F_SETFL, flags | O_NONBLOCK) == -1) 1012 warn("%s: couldn't set master loopback to nonblock: %m", __func__); 1013 1014 flags = fcntl(loop_slave, F_GETFL); 1015 if (flags == -1 || fcntl(loop_slave, F_SETFL, flags | O_NONBLOCK) == -1) 1016 warn("%s: couldn't set slave loopback to nonblock: %m", __func__); 1017 1018 ppp_fd = loop_slave; 1019 if (ioctl(ppp_fd, TIOCSETD, &pppdisc) < 0) 1020 fatal("%s: ioctl(TIOCSETD): %m", __func__); 1021 1022 /* 1023 * Find out which interface we were given. 1024 */ 1025 if (ioctl(ppp_fd, PPPIOCGUNIT, &ifunit) < 0) 1026 fatal("%s: ioctl(PPPIOCGUNIT): %m", __func__); 1027 1028 /* 1029 * Enable debug in the driver if requested. 1030 */ 1031 if (kdebugflag) { 1032 flags = get_flags(ppp_fd); 1033 flags |= (kdebugflag & 0xFF) * SC_DEBUG; 1034 set_flags(ppp_fd, flags); 1035 } 1036 1037 return loop_master; 1038 } 1039 1040 1041 /* 1042 * output - Output PPP packet. 1043 */ 1044 void 1045 output(int unit, u_char *p, int len) 1046 { 1047 if (debug) 1048 dbglog("sent %P", p, len); 1049 1050 if (write(ttyfd, p, len) < 0) { 1051 if (errno != EIO) 1052 error("%s: write: %m", __func__); 1053 } 1054 } 1055 1056 1057 /* 1058 * wait_input - wait until there is data available, 1059 * for the length of time specified by *timo (indefinite 1060 * if timo is NULL). 1061 */ 1062 void 1063 wait_input(struct timeval *timo) 1064 { 1065 fd_set ready; 1066 int n; 1067 1068 ready = in_fds; 1069 n = select(max_in_fd + 1, &ready, NULL, &ready, timo); 1070 if (n < 0 && errno != EINTR) 1071 fatal("%s: select: %m", __func__); 1072 } 1073 1074 1075 /* 1076 * add_fd - add an fd to the set that wait_input waits for. 1077 */ 1078 void add_fd(int fd) 1079 { 1080 if (fd >= FD_SETSIZE) 1081 fatal("%s: descriptor too big", __func__); 1082 FD_SET(fd, &in_fds); 1083 if (fd > max_in_fd) 1084 max_in_fd = fd; 1085 } 1086 1087 /* 1088 * remove_fd - remove an fd from the set that wait_input waits for. 1089 */ 1090 void remove_fd(int fd) 1091 { 1092 FD_CLR(fd, &in_fds); 1093 } 1094 1095 #if 0 1096 /* 1097 * wait_loop_output - wait until there is data available on the 1098 * loopback, for the length of time specified by *timo (indefinite 1099 * if timo is NULL). 1100 */ 1101 void 1102 wait_loop_output(struct timeval *timo) 1103 { 1104 fd_set ready; 1105 int n; 1106 1107 FD_ZERO(&ready); 1108 if (loop_master >= FD_SETSIZE) 1109 fatal("%s: descriptor too big", __func__); 1110 FD_SET(loop_master, &ready); 1111 n = select(loop_master + 1, &ready, NULL, &ready, timo); 1112 if (n < 0 && errno != EINTR) 1113 fatal("%s: select: %m", __func__); 1114 } 1115 1116 1117 /* 1118 * wait_time - wait for a given length of time or until a 1119 * signal is received. 1120 */ 1121 void 1122 wait_time(struct timeval *timo) 1123 { 1124 int n; 1125 1126 n = select(0, NULL, NULL, NULL, timo); 1127 if (n < 0 && errno != EINTR) 1128 fatal("%s: select: %m", __func__); 1129 } 1130 #endif 1131 1132 1133 /* 1134 * read_packet - get a PPP packet from the serial device. 1135 */ 1136 int 1137 read_packet(u_char *buf) 1138 { 1139 int len; 1140 1141 if ((len = read(ttyfd, buf, PPP_MTU + PPP_HDRLEN)) < 0) { 1142 if (errno == EWOULDBLOCK || errno == EINTR) 1143 return -1; 1144 fatal("%s: read: %m", __func__); 1145 } 1146 return len; 1147 } 1148 1149 1150 /* 1151 * get_loop_output - read characters from the loopback, form them 1152 * into frames, and detect when we want to bring the real link up. 1153 * Return value is 1 if we need to bring up the link, 0 otherwise. 1154 */ 1155 int 1156 get_loop_output(void) 1157 { 1158 int rv = 0; 1159 int n; 1160 1161 while ((n = read(loop_master, inbuf, sizeof(inbuf))) >= 0) { 1162 if (loop_chars(inbuf, n)) 1163 rv = 1; 1164 } 1165 1166 if (n == 0) 1167 fatal("%s: eof on loopback", __func__); 1168 if (n == -1 && errno != EWOULDBLOCK) 1169 fatal("%s: read from loopback: %m", __func__); 1170 1171 return rv; 1172 } 1173 1174 1175 /* 1176 * netif_set_mtu - set the MTU on the PPP network interface. 1177 */ 1178 void 1179 netif_set_mtu(int unit, int mtu) 1180 { 1181 struct ifreq ifr; 1182 1183 SYSDEBUG((LOG_DEBUG, "netif_set_mtu: mtu = %d\n", mtu)); 1184 1185 memset(&ifr, '\0', sizeof (ifr)); 1186 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); 1187 ifr.ifr_mtu = mtu; 1188 1189 if (ifunit >= 0 && ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0) 1190 fatal("%s: ioctl(SIOCSIFMTU): %m", __func__); 1191 } 1192 1193 /* 1194 * netif_get_mtu - get the MTU on the PPP network interface. 1195 */ 1196 int 1197 netif_get_mtu(int unit) 1198 { 1199 struct ifreq ifr; 1200 1201 memset (&ifr, '\0', sizeof (ifr)); 1202 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); 1203 1204 if (ifunit >= 0 && ioctl(sock_fd, SIOCGIFMTU, (caddr_t) &ifr) < 0) { 1205 error("%s: ioctl(SIOCGIFMTU): %m", __func__); 1206 return 0; 1207 } 1208 return ifr.ifr_mtu; 1209 } 1210 1211 /* 1212 * tty_send_config - configure the transmit characteristics of 1213 * the ppp interface. 1214 */ 1215 void 1216 tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp) 1217 { 1218 u_int x; 1219 #if 0 1220 /* Linux code does not do anything with the mtu here */ 1221 ifnet_set_mtu(-1, mtu); 1222 #endif 1223 1224 if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) 1225 fatal("%s: ioctl(PPPIOCSASYNCMAP): %m", __func__); 1226 1227 x = get_flags(ppp_fd); 1228 x = pcomp? x | SC_COMP_PROT: x &~ SC_COMP_PROT; 1229 x = accomp? x | SC_COMP_AC: x &~ SC_COMP_AC; 1230 x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC; 1231 set_flags(ppp_fd, x); 1232 } 1233 1234 1235 /* 1236 * ppp_set_xaccm - set the extended transmit ACCM for the interface. 1237 */ 1238 void 1239 tty_set_xaccm(ext_accm accm) 1240 { 1241 if (ioctl(ppp_fd, PPPIOCSXASYNCMAP, accm) < 0 && errno != ENOTTY) 1242 warn("%s: ioctl(set extended ACCM): %m", __func__); 1243 } 1244 1245 1246 /* 1247 * ppp_recv_config - configure the receive-side characteristics of 1248 * the ppp interface. 1249 */ 1250 void 1251 tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp) 1252 { 1253 int x; 1254 1255 if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) 1256 fatal("%s: ioctl(PPPIOCSMRU): %m", __func__); 1257 if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) 1258 fatal("%s: ioctl(PPPIOCSRASYNCMAP): %m", __func__); 1259 x = get_flags(ppp_fd); 1260 x = !accomp? x | SC_REJ_COMP_AC: x &~ SC_REJ_COMP_AC; 1261 set_flags(ppp_fd, x); 1262 } 1263 1264 /* 1265 * ccp_test - ask kernel whether a given compression method 1266 * is acceptable for use. Returns 1 if the method and parameters 1267 * are OK, 0 if the method is known but the parameters are not OK 1268 * (e.g. code size should be reduced), or -1 if the method is unknown. 1269 */ 1270 int 1271 ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit) 1272 { 1273 struct ppp_option_data data; 1274 1275 data.ptr = opt_ptr; 1276 data.length = opt_len; 1277 data.transmit = for_transmit; 1278 if (ioctl(ttyfd, PPPIOCSCOMPRESS, (caddr_t) &data) >= 0) 1279 return 1; 1280 return (errno == ENOBUFS)? 0: -1; 1281 } 1282 1283 /* 1284 * ccp_flags_set - inform kernel about the current state of CCP. 1285 */ 1286 void 1287 ccp_flags_set(int unit, int isopen, int isup) 1288 { 1289 int x; 1290 1291 x = get_flags(ppp_fd); 1292 x = isopen? x | SC_CCP_OPEN: x &~ SC_CCP_OPEN; 1293 x = isup? x | SC_CCP_UP: x &~ SC_CCP_UP; 1294 set_flags(ppp_fd, x); 1295 } 1296 1297 /* 1298 * ccp_fatal_error - returns 1 if decompression was disabled as a 1299 * result of an error detected after decompression of a packet, 1300 * 0 otherwise. This is necessary because of patent nonsense. 1301 */ 1302 int 1303 ccp_fatal_error(int unit) 1304 { 1305 int x; 1306 1307 x = get_flags(ppp_fd); 1308 return x & SC_DC_FERROR; 1309 } 1310 1311 /* 1312 * get_idle_time - return how long the link has been idle. 1313 */ 1314 int 1315 get_idle_time(int u, struct ppp_idle *ip) 1316 { 1317 return ioctl(ppp_fd, PPPIOCGIDLE, ip) >= 0; 1318 } 1319 1320 /* 1321 * get_ppp_stats - return statistics for the link. 1322 */ 1323 int 1324 get_ppp_stats(int u, struct pppd_stats *stats) 1325 { 1326 struct ifpppstatsreq req; 1327 1328 memset (&req, 0, sizeof (req)); 1329 strlcpy(req.ifr_name, ifname, sizeof(req.ifr_name)); 1330 if (ioctl(sock_fd, SIOCGPPPSTATS, &req) < 0) { 1331 error("%s: Couldn't get PPP statistics: %m", __func__); 1332 return 0; 1333 } 1334 stats->bytes_in = req.stats.p.ppp_ibytes; 1335 stats->bytes_out = req.stats.p.ppp_obytes; 1336 stats->pkts_in = req.stats.p.ppp_ipackets; 1337 stats->pkts_out = req.stats.p.ppp_opackets; 1338 return 1; 1339 } 1340 1341 1342 #ifdef PPP_FILTER 1343 /* 1344 * set_filters - transfer the pass and active filters to the kernel. 1345 */ 1346 int 1347 set_filters(struct bpf_program *pass_in, struct bpf_program *pass_out, 1348 struct bpf_program *active_in, struct bpf_program *active_out) 1349 { 1350 int ret = 1; 1351 1352 if (pass_in->bf_len > 0) { 1353 if (ioctl(ppp_fd, PPPIOCSIPASS, pass_in) < 0) { 1354 error("%s: Couldn't set pass-filter-in in kernel: %m", __func__); 1355 ret = 0; 1356 } 1357 } 1358 1359 if (pass_out->bf_len > 0) { 1360 if (ioctl(ppp_fd, PPPIOCSOPASS, pass_out) < 0) { 1361 error("%s: Couldn't set pass-filter-out in kernel: %m", __func__); 1362 ret = 0; 1363 } 1364 } 1365 1366 if (active_in->bf_len > 0) { 1367 if (ioctl(ppp_fd, PPPIOCSIACTIVE, active_in) < 0) { 1368 error("%s: Couldn't set active-filter-in in kernel: %m", __func__); 1369 ret = 0; 1370 } 1371 } 1372 1373 if (active_out->bf_len > 0) { 1374 if (ioctl(ppp_fd, PPPIOCSOACTIVE, active_out) < 0) { 1375 error("%s: Couldn't set active-filter-out in kernel: %m", __func__); 1376 ret = 0; 1377 } 1378 } 1379 1380 return ret; 1381 } 1382 #endif 1383 1384 /* 1385 * sifvjcomp - config tcp header compression 1386 */ 1387 int 1388 sifvjcomp(int u, int vjcomp, int cidcomp, int maxcid) 1389 { 1390 u_int x; 1391 1392 x = get_flags(ppp_fd); 1393 x = vjcomp ? x | SC_COMP_TCP: x &~ SC_COMP_TCP; 1394 x = cidcomp? x & ~SC_NO_TCP_CCID: x | SC_NO_TCP_CCID; 1395 set_flags(ppp_fd, x); 1396 if (vjcomp && ioctl(ppp_fd, PPPIOCSMAXCID, (caddr_t) &maxcid) < 0) { 1397 error("%s: ioctl(PPPIOCSMAXCID): %m", __func__); 1398 return 0; 1399 } 1400 return 1; 1401 } 1402 1403 /* 1404 * sifup - Config the interface up and enable IP packets to pass. 1405 */ 1406 int 1407 sifup(int u) 1408 { 1409 struct ifreq ifr; 1410 1411 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); 1412 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { 1413 error("%s: ioctl (SIOCGIFFLAGS): %m", __func__); 1414 return 0; 1415 } 1416 ifr.ifr_flags |= IFF_UP; 1417 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { 1418 error("%s: ioctl(SIOCSIFFLAGS): %m", __func__); 1419 return 0; 1420 } 1421 if_is_up = 1; 1422 return 1; 1423 } 1424 1425 /* 1426 * sifnpmode - Set the mode for handling packets for a given NP. 1427 */ 1428 int 1429 sifnpmode(int u, int proto, enum NPmode mode) 1430 { 1431 struct npioctl npi; 1432 1433 npi.protocol = proto; 1434 npi.mode = mode; 1435 if (ioctl(ppp_fd, PPPIOCSNPMODE, &npi) < 0) { 1436 error("%s: ioctl(set NP %d mode to %d): %m", __func__, proto, mode); 1437 return 0; 1438 } 1439 return 1; 1440 } 1441 1442 /* 1443 * sifdown - Config the interface down and disable IP. 1444 */ 1445 int 1446 sifdown(int u) 1447 { 1448 struct ifreq ifr; 1449 int rv; 1450 struct npioctl npi; 1451 1452 rv = 1; 1453 npi.protocol = PPP_IP; 1454 npi.mode = NPMODE_ERROR; 1455 ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi); 1456 /* ignore errors, because ppp_fd might have been closed by now. */ 1457 1458 strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); 1459 if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { 1460 error("%s: ioctl (SIOCGIFFLAGS): %m", __func__); 1461 rv = 0; 1462 } else { 1463 ifr.ifr_flags &= ~IFF_UP; 1464 if (ioctl(sock_fd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { 1465 error("%s: ioctl(SIOCSIFFLAGS): %m", __func__); 1466 rv = 0; 1467 } else 1468 if_is_up = 0; 1469 } 1470 return rv; 1471 } 1472 1473 /* 1474 * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, 1475 * if it exists. 1476 */ 1477 #define SET_SA_FAMILY(addr, family) \ 1478 BZERO((char *) &(addr), sizeof(addr)); \ 1479 addr.sa_family = (family); \ 1480 addr.sa_len = sizeof(addr); 1481 1482 /* 1483 * sifaddr - Config the interface IP addresses and netmask. 1484 */ 1485 int 1486 sifaddr(int u, u_int32_t o, u_int32_t h, u_int32_t m) 1487 { 1488 struct ifaliasreq ifra; 1489 struct ifreq ifr; 1490 1491 strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name)); 1492 SET_SA_FAMILY(ifra.ifra_addr, AF_INET); 1493 ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o; 1494 SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET); 1495 ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h; 1496 if (m != 0) { 1497 SET_SA_FAMILY(ifra.ifra_mask, AF_INET); 1498 ((struct sockaddr_in *) &ifra.ifra_mask)->sin_addr.s_addr = m; 1499 } else 1500 BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask)); 1501 BZERO(&ifr, sizeof(ifr)); 1502 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 1503 if (ioctl(sock_fd, SIOCDIFADDR, (caddr_t) &ifr) < 0) { 1504 if (errno != EADDRNOTAVAIL) 1505 warn("%s: Couldn't remove interface address: %m", __func__); 1506 } 1507 if (ioctl(sock_fd, SIOCAIFADDR, (caddr_t) &ifra) < 0) { 1508 if (errno != EEXIST) { 1509 error("%s: Couldn't set interface address: %m", __func__); 1510 return 0; 1511 } 1512 warn("%s: Couldn't set interface address: Address %I already exists", 1513 __func__, o); 1514 } 1515 ifaddrs[0] = o; 1516 ifaddrs[1] = h; 1517 return 1; 1518 } 1519 1520 /* 1521 * cifaddr - Clear the interface IP addresses, and delete routes 1522 * through the interface if possible. 1523 */ 1524 int 1525 cifaddr(int u, u_int32_t o, u_int32_t h) 1526 { 1527 struct ifaliasreq ifra; 1528 1529 ifaddrs[0] = 0; 1530 strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name)); 1531 SET_SA_FAMILY(ifra.ifra_addr, AF_INET); 1532 ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o; 1533 SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET); 1534 ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h; 1535 BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask)); 1536 if (ioctl(sock_fd, SIOCDIFADDR, (caddr_t) &ifra) < 0) { 1537 if (!doing_cleanup && errno != EADDRNOTAVAIL) 1538 warn("%s: Couldn't delete interface address: %m", __func__); 1539 return 0; 1540 } 1541 return 1; 1542 } 1543 1544 /* 1545 * sifdefaultroute - assign a default route through the address given. 1546 */ 1547 int 1548 sifdefaultroute(int u, u_int32_t l, u_int32_t g) 1549 { 1550 return dodefaultroute(g, 's'); 1551 } 1552 1553 /* 1554 * cifdefaultroute - delete a default route through the address given. 1555 */ 1556 int 1557 cifdefaultroute(int u, u_int32_t l, u_int32_t g) 1558 { 1559 return dodefaultroute(g, 'c'); 1560 } 1561 1562 /* 1563 * dodefaultroute - talk to a routing socket to add/delete a default route. 1564 */ 1565 static int 1566 dodefaultroute(u_int32_t g, int cmd) 1567 { 1568 int routes; 1569 struct { 1570 struct rt_msghdr hdr; 1571 struct sockaddr_in dst; 1572 struct sockaddr_in gway; 1573 struct sockaddr_in netmask; 1574 struct sockaddr_dl ifp; 1575 } rtmsg; 1576 1577 if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) { 1578 if (!doing_cleanup) 1579 error("%s: Couldn't %s default route: socket: %m", __func__, 1580 cmd == 's' ? "add" : "delete"); 1581 return 0; 1582 } 1583 1584 memset(&rtmsg, 0, sizeof(rtmsg)); 1585 1586 rtmsg.hdr.rtm_type = cmd == 's' ? RTM_ADD : RTM_DELETE; 1587 rtmsg.hdr.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; 1588 rtmsg.hdr.rtm_version = RTM_VERSION; 1589 rtmsg.hdr.rtm_seq = ++rtm_seq; 1590 rtmsg.hdr.rtm_addrs = 1591 RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_IFP; 1592 1593 rtmsg.dst.sin_len = sizeof(rtmsg.dst); 1594 rtmsg.dst.sin_family = AF_INET; 1595 rtmsg.dst.sin_addr.s_addr = 0; 1596 1597 rtmsg.gway.sin_len = sizeof(rtmsg.gway); 1598 rtmsg.gway.sin_family = AF_INET; 1599 rtmsg.gway.sin_addr.s_addr = g; 1600 1601 rtmsg.netmask.sin_len = sizeof(rtmsg.netmask); 1602 rtmsg.netmask.sin_family = AF_INET; 1603 rtmsg.netmask.sin_addr.s_addr = 0; 1604 1605 rtmsg.ifp.sdl_family = AF_LINK; 1606 rtmsg.ifp.sdl_len = sizeof(rtmsg.ifp); 1607 link_addr(ifname, &rtmsg.ifp); 1608 1609 rtmsg.hdr.rtm_msglen = sizeof(rtmsg); 1610 1611 if (write(routes, &rtmsg, sizeof(rtmsg)) < 0) { 1612 if (!doing_cleanup) 1613 error("%s: Couldn't %s default route: %m", __func__, 1614 cmd == 's' ? "add" : "delete"); 1615 close(routes); 1616 return 0; 1617 } 1618 1619 close(routes); 1620 default_route_gateway = (cmd == 's') ? g : 0; 1621 return 1; 1622 } 1623 1624 #if RTM_VERSION >= 3 1625 1626 /* 1627 * sifproxyarp - Make a proxy ARP entry for the peer. 1628 */ 1629 static struct { 1630 struct rt_msghdr hdr; 1631 struct sockaddr_inarp dst; 1632 struct sockaddr_dl hwa; 1633 char extra[128]; 1634 } arpmsg; 1635 1636 static int arpmsg_valid; 1637 1638 int 1639 sifproxyarp(int unit, u_int32_t hisaddr) 1640 { 1641 int routes; 1642 1643 /* 1644 * Get the hardware address of an interface on the same subnet 1645 * as our local address. 1646 */ 1647 memset(&arpmsg, 0, sizeof(arpmsg)); 1648 if (!get_ether_addr(hisaddr, &arpmsg.hwa)) { 1649 error("%s: Cannot determine ethernet address for proxy ARP", __func__); 1650 return 0; 1651 } 1652 1653 if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) { 1654 error("%s: Couldn't add proxy arp entry: socket: %m", __func__); 1655 return 0; 1656 } 1657 1658 arpmsg.hdr.rtm_type = RTM_ADD; 1659 arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC; 1660 arpmsg.hdr.rtm_version = RTM_VERSION; 1661 arpmsg.hdr.rtm_seq = ++rtm_seq; 1662 arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY; 1663 arpmsg.hdr.rtm_inits = RTV_EXPIRE; 1664 arpmsg.dst.sin_len = sizeof(struct sockaddr_inarp); 1665 arpmsg.dst.sin_family = AF_INET; 1666 arpmsg.dst.sin_addr.s_addr = hisaddr; 1667 arpmsg.dst.sin_other = SIN_PROXY; 1668 1669 arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg 1670 + RT_ROUNDUP(arpmsg.hwa.sdl_len); 1671 if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) { 1672 error("%s: Couldn't add proxy arp entry: %m", __func__); 1673 close(routes); 1674 return 0; 1675 } 1676 1677 close(routes); 1678 arpmsg_valid = 1; 1679 proxy_arp_addr = hisaddr; 1680 return 1; 1681 } 1682 1683 /* 1684 * cifproxyarp - Delete the proxy ARP entry for the peer. 1685 */ 1686 int 1687 cifproxyarp(int unit, u_int32_t hisaddr) 1688 { 1689 int routes; 1690 1691 if (!arpmsg_valid) 1692 return 0; 1693 arpmsg_valid = 0; 1694 1695 arpmsg.hdr.rtm_type = RTM_DELETE; 1696 arpmsg.hdr.rtm_seq = ++rtm_seq; 1697 1698 if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) { 1699 if (!doing_cleanup) 1700 error("%s: Couldn't delete proxy arp entry: socket: %m", __func__); 1701 return 0; 1702 } 1703 1704 if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) { 1705 if (!doing_cleanup) 1706 error("%s: Couldn't delete proxy arp entry: %m", __func__); 1707 close(routes); 1708 return 0; 1709 } 1710 1711 close(routes); 1712 proxy_arp_addr = 0; 1713 return 1; 1714 } 1715 1716 #else /* RTM_VERSION */ 1717 1718 /* 1719 * sifproxyarp - Make a proxy ARP entry for the peer. 1720 */ 1721 int 1722 sifproxyarp(int unit, u_int32_t hisaddr) 1723 { 1724 struct arpreq arpreq; 1725 struct { 1726 struct sockaddr_dl sdl; 1727 char space[128]; 1728 } dls; 1729 1730 BZERO(&arpreq, sizeof(arpreq)); 1731 1732 /* 1733 * Get the hardware address of an interface on the same subnet 1734 * as our local address. 1735 */ 1736 if (!get_ether_addr(hisaddr, &dls.sdl)) { 1737 error("%s: Cannot determine ethernet address for proxy ARP", __func__); 1738 return 0; 1739 } 1740 1741 arpreq.arp_ha.sa_len = sizeof(struct sockaddr); 1742 arpreq.arp_ha.sa_family = AF_UNSPEC; 1743 BCOPY(LLADDR(&dls.sdl), arpreq.arp_ha.sa_data, dls.sdl.sdl_alen); 1744 SET_SA_FAMILY(arpreq.arp_pa, AF_INET); 1745 ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; 1746 arpreq.arp_flags = ATF_PERM | ATF_PUBL; 1747 if (ioctl(sock_fd, SIOCSARP, (caddr_t)&arpreq) < 0) { 1748 error("%s: Couldn't add proxy arp entry: %m", __func__); 1749 return 0; 1750 } 1751 1752 proxy_arp_addr = hisaddr; 1753 return 1; 1754 } 1755 1756 /* 1757 * cifproxyarp - Delete the proxy ARP entry for the peer. 1758 */ 1759 int 1760 cifproxyarp(int unit, u_int32_t hisaddr) 1761 { 1762 struct arpreq arpreq; 1763 1764 BZERO(&arpreq, sizeof(arpreq)); 1765 SET_SA_FAMILY(arpreq.arp_pa, AF_INET); 1766 ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; 1767 if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) { 1768 warn("%s: Couldn't delete proxy arp entry: %m", __func__); 1769 return 0; 1770 } 1771 proxy_arp_addr = 0; 1772 return 1; 1773 } 1774 #endif /* RTM_VERSION */ 1775 1776 1777 /* 1778 * get_ether_addr - get the hardware address of an interface on the 1779 * the same subnet as ipaddr. 1780 */ 1781 static int 1782 get_ether_addr(u_int32_t ipaddr, struct sockaddr_dl *hwaddr) 1783 { 1784 u_int32_t ina, mask; 1785 struct sockaddr_dl *dla; 1786 struct ifaddrs *ifap, *ifa, *ifp; 1787 1788 /* 1789 * Scan through looking for an interface with an Internet 1790 * address on the same subnet as `ipaddr'. 1791 */ 1792 if (getifaddrs(&ifap) != 0) { 1793 error("%s: getifaddrs: %m", __func__); 1794 return 0; 1795 } 1796 1797 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 1798 if (ifa->ifa_addr->sa_family != AF_INET) 1799 continue; 1800 ina = ((struct sockaddr_in *) ifa->ifa_addr)->sin_addr.s_addr; 1801 /* 1802 * Check that the interface is up, and not point-to-point 1803 * or loopback. 1804 */ 1805 if ((ifa->ifa_flags & 1806 (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP)) 1807 != (IFF_UP|IFF_BROADCAST)) 1808 continue; 1809 /* 1810 * Get its netmask and check that it's on the right subnet. 1811 */ 1812 mask = ((struct sockaddr_in *) ifa->ifa_netmask)->sin_addr.s_addr; 1813 if ((ipaddr & mask) != (ina & mask)) 1814 continue; 1815 break; 1816 } 1817 1818 if (!ifa) { 1819 freeifaddrs(ifap); 1820 return 0; 1821 } 1822 info("found interface %s for proxy arp", ifa->ifa_name); 1823 1824 ifp = ifa; 1825 1826 /* 1827 * Now scan through again looking for a link-level address 1828 * for this interface. 1829 */ 1830 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 1831 if (strcmp(ifp->ifa_name, ifa->ifa_name) != 0) 1832 continue; 1833 if (ifa->ifa_addr->sa_family != AF_LINK) 1834 continue; 1835 /* 1836 * Found the link-level address - copy it out 1837 */ 1838 dla = (struct sockaddr_dl *) ifa->ifa_addr; 1839 BCOPY(dla, hwaddr, dla->sdl_len); 1840 freeifaddrs(ifap); 1841 return 1; 1842 } 1843 1844 freeifaddrs(ifap); 1845 return 0; 1846 } 1847 1848 /* 1849 * get_if_hwaddr - get the hardware address for the specified 1850 * network interface device. 1851 */ 1852 int 1853 get_if_hwaddr(u_char *addr, char *name) 1854 { 1855 1856 #define IFREQ_SAFE (sizeof(struct ifreq) + sizeof(struct sockaddr_dl)) 1857 /* XXX sockaddr_dl is larger than the sockaddr in struct ifreq! */ 1858 union { /* XXX */ 1859 struct ifreq _ifreq; /* XXX */ 1860 char _X[IFREQ_SAFE]; /* XXX */ 1861 } _ifreq_dontsmashstack; /* XXX */ 1862 #define ifreq_xxx _ifreq_dontsmashstack._ifreq /* XXX */ 1863 1864 struct sockaddr_dl *sdl = (struct sockaddr_dl *) &ifreq_xxx.ifr_addr; 1865 int fd; 1866 1867 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 1868 return 0; 1869 (void)memset(sdl, 0, sizeof(*sdl)); 1870 sdl->sdl_family = AF_LINK; 1871 (void)strlcpy(ifreq_xxx.ifr_name, name, sizeof(ifreq_xxx.ifr_name)); 1872 if (ioctl(fd, SIOCGIFADDR, &ifreq_xxx) == -1) { 1873 (void)close(fd); 1874 return 0; 1875 } 1876 (void)close(fd); 1877 (void)memcpy(addr, LLADDR(sdl), sdl->sdl_alen); 1878 return sdl->sdl_nlen; 1879 } 1880 1881 /* 1882 * get_first_ethernet - return the name of the first ethernet-style 1883 * interface on this system. 1884 */ 1885 char * 1886 get_first_ethernet(void) 1887 { 1888 static char ifname[IFNAMSIZ]; 1889 struct ifaddrs *ifap, *ifa; 1890 1891 /* 1892 * Scan through the system's network interfaces. 1893 */ 1894 if (getifaddrs(&ifap) != 0) { 1895 warn("%s: getifaddrs: %m", __func__); 1896 return NULL; 1897 } 1898 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 1899 /* 1900 * Check the interface's internet address. 1901 */ 1902 if (ifa->ifa_addr->sa_family != AF_INET) 1903 continue; 1904 /* 1905 * Check that the interface is up, and not point-to-point or loopback. 1906 */ 1907 if ((ifa->ifa_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) 1908 != IFF_UP) { 1909 strlcpy(ifname, ifa->ifa_name, sizeof(ifname)); 1910 freeifaddrs(ifap); 1911 return ifname; 1912 } 1913 } 1914 freeifaddrs(ifap); 1915 return NULL; 1916 } 1917 1918 /* 1919 * Return user specified netmask, modified by any mask we might determine 1920 * for address `addr' (in network byte order). 1921 * Here we scan through the system's list of interfaces, looking for 1922 * any non-point-to-point interfaces which might appear to be on the same 1923 * network as `addr'. If we find any, we OR in their netmask to the 1924 * user-specified netmask. 1925 */ 1926 u_int32_t 1927 GetMask(u_int32_t addr) 1928 { 1929 u_int32_t mask, nmask, ina; 1930 struct ifaddrs *ifap, *ifa; 1931 1932 addr = ntohl(addr); 1933 if (IN_CLASSA(addr)) /* determine network mask for address class */ 1934 nmask = IN_CLASSA_NET; 1935 else if (IN_CLASSB(addr)) 1936 nmask = IN_CLASSB_NET; 1937 else 1938 nmask = IN_CLASSC_NET; 1939 /* class D nets are disallowed by bad_ip_adrs */ 1940 mask = netmask | htonl(nmask); 1941 1942 /* 1943 * Scan through the system's network interfaces. 1944 */ 1945 if (getifaddrs(&ifap) != 0) { 1946 warn("%s: getifaddrs: %m", __func__); 1947 return 0; 1948 } 1949 1950 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 1951 /* 1952 * Check the interface's internet address. 1953 */ 1954 if (ifa->ifa_addr->sa_family != AF_INET) 1955 continue; 1956 ina = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; 1957 if ((ntohl(ina) & nmask) != (addr & nmask)) 1958 continue; 1959 /* 1960 * Check that the interface is up, and not point-to-point or loopback. 1961 */ 1962 if ((ifa->ifa_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) != IFF_UP) 1963 continue; 1964 /* 1965 * Get its netmask and OR it into our mask. 1966 */ 1967 mask |= ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr.s_addr; 1968 } 1969 1970 freeifaddrs(ifap); 1971 return mask; 1972 } 1973 1974 /* 1975 * have_route_to - determine if the system has any route to 1976 * a given IP address. 1977 * For demand mode to work properly, we have to ignore routes 1978 * through our own interface. 1979 */ 1980 int have_route_to(u_int32_t addr) 1981 { 1982 return -1; 1983 } 1984 1985 /* 1986 * Use the hostid as part of the random number seed. 1987 */ 1988 int 1989 get_host_seed(void) 1990 { 1991 return gethostid(); 1992 } 1993 1994 #if 0 1995 /* 1996 * lock - create a lock file for the named lock device 1997 */ 1998 #define LOCK_PREFIX "/var/spool/lock/LCK.." 1999 2000 static char *lock_file; /* name of lock file created */ 2001 2002 int 2003 lock(char *dev) 2004 { 2005 char hdb_lock_buffer[12]; 2006 int fd, pid, n; 2007 char *p; 2008 size_t l; 2009 2010 if ((p = strrchr(dev, '/')) != NULL) 2011 dev = p + 1; 2012 l = strlen(LOCK_PREFIX) + strlen(dev) + 1; 2013 lock_file = malloc(l); 2014 if (lock_file == NULL) 2015 novm("lock file name"); 2016 slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev); 2017 2018 while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { 2019 if (errno == EEXIST 2020 && (fd = open(lock_file, O_RDONLY, 0)) >= 0) { 2021 /* Read the lock file to find out who has the device locked */ 2022 n = read(fd, hdb_lock_buffer, 11); 2023 if (n <= 0) { 2024 error("%s: Can't read pid from lock file %s", __func__, 2025 lock_file); 2026 close(fd); 2027 } else { 2028 hdb_lock_buffer[n] = 0; 2029 pid = atoi(hdb_lock_buffer); 2030 if (kill(pid, 0) == -1 && errno == ESRCH) { 2031 /* pid no longer exists - remove the lock file */ 2032 if (unlink(lock_file) == 0) { 2033 close(fd); 2034 notice("%s: Removed stale lock on %s (pid %d)", 2035 __func__, dev, pid); 2036 continue; 2037 } else 2038 warn("%s: Couldn't remove stale lock on %s", __func__, 2039 dev); 2040 } else 2041 notice("%s: Device %s is locked by pid %d", __func__, 2042 dev, pid); 2043 } 2044 close(fd); 2045 } else 2046 error("%s: Can't create lock file %s: %m", __func__, lock_file); 2047 free(lock_file); 2048 lock_file = NULL; 2049 return -1; 2050 } 2051 2052 slprintf(hdb_lock_buffer, sizeof(hdb_lock_buffer), "%10d\n", getpid()); 2053 write(fd, hdb_lock_buffer, 11); 2054 2055 close(fd); 2056 return 0; 2057 } 2058 2059 /* 2060 * unlock - remove our lockfile 2061 */ 2062 void 2063 unlock(void) 2064 { 2065 if (lock_file) { 2066 unlink(lock_file); 2067 free(lock_file); 2068 lock_file = NULL; 2069 } 2070 } 2071 #endif 2072