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