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