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