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