1 /* $NetBSD: in.c,v 1.145 2014/05/22 22:01:12 rmind Exp $ */ 2 3 /* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the project nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 /*- 33 * Copyright (c) 1998 The NetBSD Foundation, Inc. 34 * All rights reserved. 35 * 36 * This code is derived from software contributed to The NetBSD Foundation 37 * by Public Access Networks Corporation ("Panix"). It was developed under 38 * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 50 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 51 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 52 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 53 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 54 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 55 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 56 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 57 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 58 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 59 * POSSIBILITY OF SUCH DAMAGE. 60 */ 61 62 /* 63 * Copyright (c) 1982, 1986, 1991, 1993 64 * The Regents of the University of California. All rights reserved. 65 * 66 * Redistribution and use in source and binary forms, with or without 67 * modification, are permitted provided that the following conditions 68 * are met: 69 * 1. Redistributions of source code must retain the above copyright 70 * notice, this list of conditions and the following disclaimer. 71 * 2. Redistributions in binary form must reproduce the above copyright 72 * notice, this list of conditions and the following disclaimer in the 73 * documentation and/or other materials provided with the distribution. 74 * 3. Neither the name of the University nor the names of its contributors 75 * may be used to endorse or promote products derived from this software 76 * without specific prior written permission. 77 * 78 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 79 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 80 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 81 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 82 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 83 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 84 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 85 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 86 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 87 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 88 * SUCH DAMAGE. 89 * 90 * @(#)in.c 8.4 (Berkeley) 1/9/95 91 */ 92 93 #include <sys/cdefs.h> 94 __KERNEL_RCSID(0, "$NetBSD: in.c,v 1.145 2014/05/22 22:01:12 rmind Exp $"); 95 96 #include "opt_inet.h" 97 #include "opt_inet_conf.h" 98 #include "opt_mrouting.h" 99 100 #include <sys/param.h> 101 #include <sys/ioctl.h> 102 #include <sys/errno.h> 103 #include <sys/malloc.h> 104 #include <sys/socket.h> 105 #include <sys/socketvar.h> 106 #include <sys/sysctl.h> 107 #include <sys/systm.h> 108 #include <sys/proc.h> 109 #include <sys/syslog.h> 110 #include <sys/kauth.h> 111 112 #include <sys/cprng.h> 113 114 #include <net/if.h> 115 #include <net/route.h> 116 #include <net/pfil.h> 117 118 #include <net/if_ether.h> 119 120 #include <netinet/in_systm.h> 121 #include <netinet/in.h> 122 #include <netinet/in_var.h> 123 #include <netinet/ip.h> 124 #include <netinet/ip_var.h> 125 #include <netinet/in_ifattach.h> 126 #include <netinet/in_pcb.h> 127 #include <netinet/if_inarp.h> 128 #include <netinet/ip_mroute.h> 129 #include <netinet/igmp_var.h> 130 131 #ifdef IPSELSRC 132 #include <netinet/in_selsrc.h> 133 #endif 134 135 static u_int in_mask2len(struct in_addr *); 136 static void in_len2mask(struct in_addr *, u_int); 137 static int in_lifaddr_ioctl(struct socket *, u_long, void *, 138 struct ifnet *, struct lwp *); 139 140 static int in_addprefix(struct in_ifaddr *, int); 141 static int in_scrubprefix(struct in_ifaddr *); 142 static void in_sysctl_init(struct sysctllog **); 143 144 #ifndef SUBNETSARELOCAL 145 #define SUBNETSARELOCAL 1 146 #endif 147 148 #ifndef HOSTZEROBROADCAST 149 #define HOSTZEROBROADCAST 1 150 #endif 151 152 static int subnetsarelocal = SUBNETSARELOCAL; 153 static int hostzeroisbroadcast = HOSTZEROBROADCAST; 154 155 /* 156 * This list is used to keep track of in_multi chains which belong to 157 * deleted interface addresses. We use in_ifaddr so that a chain head 158 * won't be deallocated until all multicast address record are deleted. 159 */ 160 static TAILQ_HEAD(, in_ifaddr) in_mk = TAILQ_HEAD_INITIALIZER(in_mk); 161 162 static struct pool inmulti_pool; 163 static u_int in_multientries; 164 struct in_multihashhead * in_multihashtbl; 165 166 u_long in_multihash; 167 struct in_ifaddrhashhead * in_ifaddrhashtbl; 168 u_long in_ifaddrhash; 169 struct in_ifaddrhead in_ifaddrhead; 170 171 void 172 in_init(void) 173 { 174 pool_init(&inmulti_pool, sizeof(struct in_multi), 0, 0, 0, "inmltpl", 175 NULL, IPL_SOFTNET); 176 TAILQ_INIT(&in_ifaddrhead); 177 178 in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, true, 179 &in_ifaddrhash); 180 in_multihashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, true, 181 &in_multihash); 182 183 in_sysctl_init(NULL); 184 } 185 186 /* 187 * Return 1 if an internet address is for a ``local'' host 188 * (one to which we have a connection). If subnetsarelocal 189 * is true, this includes other subnets of the local net. 190 * Otherwise, it includes only the directly-connected (sub)nets. 191 */ 192 int 193 in_localaddr(struct in_addr in) 194 { 195 struct in_ifaddr *ia; 196 197 if (subnetsarelocal) { 198 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) 199 if ((in.s_addr & ia->ia_netmask) == ia->ia_net) 200 return (1); 201 } else { 202 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) 203 if ((in.s_addr & ia->ia_subnetmask) == ia->ia_subnet) 204 return (1); 205 } 206 return (0); 207 } 208 209 /* 210 * Determine whether an IP address is in a reserved set of addresses 211 * that may not be forwarded, or whether datagrams to that destination 212 * may be forwarded. 213 */ 214 int 215 in_canforward(struct in_addr in) 216 { 217 u_int32_t net; 218 219 if (IN_EXPERIMENTAL(in.s_addr) || IN_MULTICAST(in.s_addr)) 220 return (0); 221 if (IN_CLASSA(in.s_addr)) { 222 net = in.s_addr & IN_CLASSA_NET; 223 if (net == 0 || net == htonl(IN_LOOPBACKNET << IN_CLASSA_NSHIFT)) 224 return (0); 225 } 226 return (1); 227 } 228 229 /* 230 * Trim a mask in a sockaddr 231 */ 232 void 233 in_socktrim(struct sockaddr_in *ap) 234 { 235 char *cplim = (char *) &ap->sin_addr; 236 char *cp = (char *) (&ap->sin_addr + 1); 237 238 ap->sin_len = 0; 239 while (--cp >= cplim) 240 if (*cp) { 241 (ap)->sin_len = cp - (char *) (ap) + 1; 242 break; 243 } 244 } 245 246 /* 247 * Routine to take an Internet address and convert into a 248 * "dotted quad" representation for printing. 249 */ 250 const char * 251 in_fmtaddr(struct in_addr addr) 252 { 253 static char buf[sizeof("123.456.789.123")]; 254 255 addr.s_addr = ntohl(addr.s_addr); 256 257 snprintf(buf, sizeof(buf), "%d.%d.%d.%d", 258 (addr.s_addr >> 24) & 0xFF, 259 (addr.s_addr >> 16) & 0xFF, 260 (addr.s_addr >> 8) & 0xFF, 261 (addr.s_addr >> 0) & 0xFF); 262 return buf; 263 } 264 265 /* 266 * Maintain the "in_maxmtu" variable, which is the largest 267 * mtu for non-local interfaces with AF_INET addresses assigned 268 * to them that are up. 269 */ 270 unsigned long in_maxmtu; 271 272 void 273 in_setmaxmtu(void) 274 { 275 struct in_ifaddr *ia; 276 struct ifnet *ifp; 277 unsigned long maxmtu = 0; 278 279 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) { 280 if ((ifp = ia->ia_ifp) == 0) 281 continue; 282 if ((ifp->if_flags & (IFF_UP|IFF_LOOPBACK)) != IFF_UP) 283 continue; 284 if (ifp->if_mtu > maxmtu) 285 maxmtu = ifp->if_mtu; 286 } 287 if (maxmtu) 288 in_maxmtu = maxmtu; 289 } 290 291 static u_int 292 in_mask2len(struct in_addr *mask) 293 { 294 u_int x, y; 295 u_char *p; 296 297 p = (u_char *)mask; 298 for (x = 0; x < sizeof(*mask); x++) { 299 if (p[x] != 0xff) 300 break; 301 } 302 y = 0; 303 if (x < sizeof(*mask)) { 304 for (y = 0; y < NBBY; y++) { 305 if ((p[x] & (0x80 >> y)) == 0) 306 break; 307 } 308 } 309 return x * NBBY + y; 310 } 311 312 static void 313 in_len2mask(struct in_addr *mask, u_int len) 314 { 315 u_int i; 316 u_char *p; 317 318 p = (u_char *)mask; 319 memset(mask, 0, sizeof(*mask)); 320 for (i = 0; i < len / NBBY; i++) 321 p[i] = 0xff; 322 if (len % NBBY) 323 p[i] = (0xff00 >> (len % NBBY)) & 0xff; 324 } 325 326 /* 327 * Generic internet control operations (ioctl's). 328 * Ifp is 0 if not an interface-specific ioctl. 329 */ 330 /* ARGSUSED */ 331 int 332 in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp, 333 struct lwp *l) 334 { 335 struct ifreq *ifr = (struct ifreq *)data; 336 struct in_ifaddr *ia = NULL; 337 struct in_aliasreq *ifra = (struct in_aliasreq *)data; 338 struct sockaddr_in oldaddr; 339 int error, hostIsNew, maskIsNew; 340 int newifaddr = 0; 341 342 switch (cmd) { 343 case SIOCALIFADDR: 344 case SIOCDLIFADDR: 345 case SIOCGLIFADDR: 346 if (ifp == NULL) 347 return EINVAL; 348 return in_lifaddr_ioctl(so, cmd, data, ifp, l); 349 case SIOCGIFADDRPREF: 350 case SIOCSIFADDRPREF: 351 if (ifp == NULL) 352 return EINVAL; 353 return ifaddrpref_ioctl(so, cmd, data, ifp, l); 354 } 355 356 /* 357 * Find address for this interface, if it exists. 358 */ 359 if (ifp != NULL) 360 IFP_TO_IA(ifp, ia); 361 362 switch (cmd) { 363 case SIOCAIFADDR: 364 case SIOCDIFADDR: 365 case SIOCGIFALIAS: 366 if (ifra->ifra_addr.sin_family == AF_INET) 367 LIST_FOREACH(ia, 368 &IN_IFADDR_HASH(ifra->ifra_addr.sin_addr.s_addr), 369 ia_hash) { 370 if (ia->ia_ifp == ifp && 371 in_hosteq(ia->ia_addr.sin_addr, 372 ifra->ifra_addr.sin_addr)) 373 break; 374 } 375 if ((cmd == SIOCDIFADDR || cmd == SIOCGIFALIAS) && ia == NULL) 376 return (EADDRNOTAVAIL); 377 378 if (cmd == SIOCDIFADDR && 379 ifra->ifra_addr.sin_family == AF_UNSPEC) { 380 ifra->ifra_addr.sin_family = AF_INET; 381 } 382 /* FALLTHROUGH */ 383 case SIOCSIFADDR: 384 case SIOCSIFDSTADDR: 385 if (ifra->ifra_addr.sin_family != AF_INET) 386 return (EAFNOSUPPORT); 387 /* FALLTHROUGH */ 388 case SIOCSIFNETMASK: 389 if (ifp == NULL) 390 panic("in_control"); 391 392 if (cmd == SIOCGIFALIAS) 393 break; 394 395 if (ia == NULL && 396 (cmd == SIOCSIFNETMASK || cmd == SIOCSIFDSTADDR)) 397 return (EADDRNOTAVAIL); 398 399 if (l == NULL) 400 return (EPERM); 401 if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE, 402 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, 403 NULL) != 0) 404 return (EPERM); 405 406 if (ia == NULL) { 407 ia = malloc(sizeof(*ia), M_IFADDR, M_WAITOK|M_ZERO); 408 if (ia == NULL) 409 return (ENOBUFS); 410 TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_list); 411 IFAREF(&ia->ia_ifa); 412 ifa_insert(ifp, &ia->ia_ifa); 413 ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr); 414 ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr); 415 ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask); 416 #ifdef IPSELSRC 417 ia->ia_ifa.ifa_getifa = in_getifa; 418 #else /* IPSELSRC */ 419 ia->ia_ifa.ifa_getifa = NULL; 420 #endif /* IPSELSRC */ 421 ia->ia_sockmask.sin_len = 8; 422 if (ifp->if_flags & IFF_BROADCAST) { 423 ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr); 424 ia->ia_broadaddr.sin_family = AF_INET; 425 } 426 ia->ia_ifp = ifp; 427 ia->ia_idsalt = cprng_fast32() % 65535; 428 LIST_INIT(&ia->ia_multiaddrs); 429 newifaddr = 1; 430 } 431 break; 432 433 case SIOCSIFBRDADDR: 434 if (l == NULL) 435 return (EPERM); 436 if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE, 437 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, 438 NULL) != 0) 439 return (EPERM); 440 /* FALLTHROUGH */ 441 442 case SIOCGIFADDR: 443 case SIOCGIFNETMASK: 444 case SIOCGIFDSTADDR: 445 case SIOCGIFBRDADDR: 446 if (ia == NULL) 447 return (EADDRNOTAVAIL); 448 break; 449 } 450 error = 0; 451 switch (cmd) { 452 453 case SIOCGIFADDR: 454 ifreq_setaddr(cmd, ifr, sintocsa(&ia->ia_addr)); 455 break; 456 457 case SIOCGIFBRDADDR: 458 if ((ifp->if_flags & IFF_BROADCAST) == 0) 459 return (EINVAL); 460 ifreq_setdstaddr(cmd, ifr, sintocsa(&ia->ia_broadaddr)); 461 break; 462 463 case SIOCGIFDSTADDR: 464 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 465 return (EINVAL); 466 ifreq_setdstaddr(cmd, ifr, sintocsa(&ia->ia_dstaddr)); 467 break; 468 469 case SIOCGIFNETMASK: 470 ifreq_setaddr(cmd, ifr, sintocsa(&ia->ia_sockmask)); 471 break; 472 473 case SIOCSIFDSTADDR: 474 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 475 return (EINVAL); 476 oldaddr = ia->ia_dstaddr; 477 ia->ia_dstaddr = *satocsin(ifreq_getdstaddr(cmd, ifr)); 478 if ((error = if_addr_init(ifp, &ia->ia_ifa, false)) != 0) { 479 ia->ia_dstaddr = oldaddr; 480 return error; 481 } 482 if (ia->ia_flags & IFA_ROUTE) { 483 ia->ia_ifa.ifa_dstaddr = sintosa(&oldaddr); 484 rtinit(&ia->ia_ifa, RTM_DELETE, RTF_HOST); 485 ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr); 486 rtinit(&ia->ia_ifa, RTM_ADD, RTF_HOST|RTF_UP); 487 } 488 break; 489 490 case SIOCSIFBRDADDR: 491 if ((ifp->if_flags & IFF_BROADCAST) == 0) 492 return EINVAL; 493 ia->ia_broadaddr = *satocsin(ifreq_getbroadaddr(cmd, ifr)); 494 break; 495 496 case SIOCSIFADDR: 497 error = in_ifinit(ifp, ia, satocsin(ifreq_getaddr(cmd, ifr)), 498 1); 499 if (error == 0) { 500 (void)pfil_run_hooks(if_pfil, 501 (struct mbuf **)SIOCSIFADDR, ifp, PFIL_IFADDR); 502 } 503 break; 504 505 case SIOCSIFNETMASK: 506 in_ifscrub(ifp, ia); 507 ia->ia_sockmask = *satocsin(ifreq_getaddr(cmd, ifr)); 508 ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr; 509 error = in_ifinit(ifp, ia, NULL, 0); 510 break; 511 512 case SIOCAIFADDR: 513 maskIsNew = 0; 514 hostIsNew = 1; 515 if (ia->ia_addr.sin_family != AF_INET) 516 ; 517 else if (ifra->ifra_addr.sin_len == 0) { 518 ifra->ifra_addr = ia->ia_addr; 519 hostIsNew = 0; 520 } else if (in_hosteq(ia->ia_addr.sin_addr, 521 ifra->ifra_addr.sin_addr)) 522 hostIsNew = 0; 523 if (ifra->ifra_mask.sin_len) { 524 /* Only scrub if we control the prefix route, 525 * otherwise userland gets a bogus message */ 526 if ((ia->ia_flags & IFA_ROUTE)) 527 in_ifscrub(ifp, ia); 528 ia->ia_sockmask = ifra->ifra_mask; 529 ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr; 530 maskIsNew = 1; 531 } 532 if ((ifp->if_flags & IFF_POINTOPOINT) && 533 (ifra->ifra_dstaddr.sin_family == AF_INET)) { 534 /* Only scrub if we control the prefix route, 535 * otherwise userland gets a bogus message */ 536 if ((ia->ia_flags & IFA_ROUTE)) 537 in_ifscrub(ifp, ia); 538 ia->ia_dstaddr = ifra->ifra_dstaddr; 539 maskIsNew = 1; /* We lie; but the effect's the same */ 540 } 541 if (ifra->ifra_addr.sin_family == AF_INET && 542 (hostIsNew || maskIsNew)) { 543 error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0); 544 } 545 if ((ifp->if_flags & IFF_BROADCAST) && 546 (ifra->ifra_broadaddr.sin_family == AF_INET)) 547 ia->ia_broadaddr = ifra->ifra_broadaddr; 548 if (error == 0) 549 (void)pfil_run_hooks(if_pfil, 550 (struct mbuf **)SIOCAIFADDR, ifp, PFIL_IFADDR); 551 break; 552 553 case SIOCGIFALIAS: 554 ifra->ifra_mask = ia->ia_sockmask; 555 if ((ifp->if_flags & IFF_POINTOPOINT) && 556 (ia->ia_dstaddr.sin_family == AF_INET)) 557 ifra->ifra_dstaddr = ia->ia_dstaddr; 558 else if ((ifp->if_flags & IFF_BROADCAST) && 559 (ia->ia_broadaddr.sin_family == AF_INET)) 560 ifra->ifra_broadaddr = ia->ia_broadaddr; 561 else 562 memset(&ifra->ifra_broadaddr, 0, 563 sizeof(ifra->ifra_broadaddr)); 564 break; 565 566 case SIOCDIFADDR: 567 in_purgeaddr(&ia->ia_ifa); 568 (void)pfil_run_hooks(if_pfil, (struct mbuf **)SIOCDIFADDR, 569 ifp, PFIL_IFADDR); 570 break; 571 572 #ifdef MROUTING 573 case SIOCGETVIFCNT: 574 case SIOCGETSGCNT: 575 error = mrt_ioctl(so, cmd, data); 576 break; 577 #endif /* MROUTING */ 578 579 default: 580 return ENOTTY; 581 } 582 583 if (error != 0 && newifaddr) { 584 KASSERT(ia != NULL); 585 in_purgeaddr(&ia->ia_ifa); 586 } 587 588 return error; 589 } 590 591 void 592 in_purgeaddr(struct ifaddr *ifa) 593 { 594 struct ifnet *ifp = ifa->ifa_ifp; 595 struct in_ifaddr *ia = (void *) ifa; 596 597 in_ifscrub(ifp, ia); 598 LIST_REMOVE(ia, ia_hash); 599 ifa_remove(ifp, &ia->ia_ifa); 600 TAILQ_REMOVE(&in_ifaddrhead, ia, ia_list); 601 if (ia->ia_allhosts != NULL) 602 in_delmulti(ia->ia_allhosts); 603 IFAFREE(&ia->ia_ifa); 604 in_setmaxmtu(); 605 } 606 607 void 608 in_purgeif(struct ifnet *ifp) /* MUST be called at splsoftnet() */ 609 { 610 if_purgeaddrs(ifp, AF_INET, in_purgeaddr); 611 igmp_purgeif(ifp); /* manipulates pools */ 612 #ifdef MROUTING 613 ip_mrouter_detach(ifp); 614 #endif 615 } 616 617 /* 618 * SIOC[GAD]LIFADDR. 619 * SIOCGLIFADDR: get first address. (???) 620 * SIOCGLIFADDR with IFLR_PREFIX: 621 * get first address that matches the specified prefix. 622 * SIOCALIFADDR: add the specified address. 623 * SIOCALIFADDR with IFLR_PREFIX: 624 * EINVAL since we can't deduce hostid part of the address. 625 * SIOCDLIFADDR: delete the specified address. 626 * SIOCDLIFADDR with IFLR_PREFIX: 627 * delete the first address that matches the specified prefix. 628 * return values: 629 * EINVAL on invalid parameters 630 * EADDRNOTAVAIL on prefix match failed/specified address not found 631 * other values may be returned from in_ioctl() 632 */ 633 static int 634 in_lifaddr_ioctl(struct socket *so, u_long cmd, void *data, 635 struct ifnet *ifp, struct lwp *l) 636 { 637 struct if_laddrreq *iflr = (struct if_laddrreq *)data; 638 struct ifaddr *ifa; 639 struct sockaddr *sa; 640 641 /* sanity checks */ 642 if (data == NULL || ifp == NULL) { 643 panic("invalid argument to in_lifaddr_ioctl"); 644 /*NOTRECHED*/ 645 } 646 647 switch (cmd) { 648 case SIOCGLIFADDR: 649 /* address must be specified on GET with IFLR_PREFIX */ 650 if ((iflr->flags & IFLR_PREFIX) == 0) 651 break; 652 /*FALLTHROUGH*/ 653 case SIOCALIFADDR: 654 case SIOCDLIFADDR: 655 /* address must be specified on ADD and DELETE */ 656 sa = (struct sockaddr *)&iflr->addr; 657 if (sa->sa_family != AF_INET) 658 return EINVAL; 659 if (sa->sa_len != sizeof(struct sockaddr_in)) 660 return EINVAL; 661 /* XXX need improvement */ 662 sa = (struct sockaddr *)&iflr->dstaddr; 663 if (sa->sa_family != AF_UNSPEC && sa->sa_family != AF_INET) 664 return EINVAL; 665 if (sa->sa_len != 0 && sa->sa_len != sizeof(struct sockaddr_in)) 666 return EINVAL; 667 break; 668 default: /*shouldn't happen*/ 669 #if 0 670 panic("invalid cmd to in_lifaddr_ioctl"); 671 /*NOTREACHED*/ 672 #else 673 return EOPNOTSUPP; 674 #endif 675 } 676 if (sizeof(struct in_addr) * NBBY < iflr->prefixlen) 677 return EINVAL; 678 679 switch (cmd) { 680 case SIOCALIFADDR: 681 { 682 struct in_aliasreq ifra; 683 684 if (iflr->flags & IFLR_PREFIX) 685 return EINVAL; 686 687 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR). */ 688 memset(&ifra, 0, sizeof(ifra)); 689 memcpy(ifra.ifra_name, iflr->iflr_name, 690 sizeof(ifra.ifra_name)); 691 692 memcpy(&ifra.ifra_addr, &iflr->addr, 693 ((struct sockaddr *)&iflr->addr)->sa_len); 694 695 if (((struct sockaddr *)&iflr->dstaddr)->sa_family) { /*XXX*/ 696 memcpy(&ifra.ifra_dstaddr, &iflr->dstaddr, 697 ((struct sockaddr *)&iflr->dstaddr)->sa_len); 698 } 699 700 ifra.ifra_mask.sin_family = AF_INET; 701 ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in); 702 in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen); 703 704 return in_control(so, SIOCAIFADDR, (void *)&ifra, ifp, l); 705 } 706 case SIOCGLIFADDR: 707 case SIOCDLIFADDR: 708 { 709 struct in_ifaddr *ia; 710 struct in_addr mask, candidate, match; 711 struct sockaddr_in *sin; 712 int cmp; 713 714 memset(&mask, 0, sizeof(mask)); 715 memset(&match, 0, sizeof(match)); /* XXX gcc */ 716 if (iflr->flags & IFLR_PREFIX) { 717 /* lookup a prefix rather than address. */ 718 in_len2mask(&mask, iflr->prefixlen); 719 720 sin = (struct sockaddr_in *)&iflr->addr; 721 match.s_addr = sin->sin_addr.s_addr; 722 match.s_addr &= mask.s_addr; 723 724 /* if you set extra bits, that's wrong */ 725 if (match.s_addr != sin->sin_addr.s_addr) 726 return EINVAL; 727 728 cmp = 1; 729 } else { 730 if (cmd == SIOCGLIFADDR) { 731 /* on getting an address, take the 1st match */ 732 cmp = 0; /*XXX*/ 733 } else { 734 /* on deleting an address, do exact match */ 735 in_len2mask(&mask, 32); 736 sin = (struct sockaddr_in *)&iflr->addr; 737 match.s_addr = sin->sin_addr.s_addr; 738 739 cmp = 1; 740 } 741 } 742 743 IFADDR_FOREACH(ifa, ifp) { 744 if (ifa->ifa_addr->sa_family != AF_INET) 745 continue; 746 if (cmp == 0) 747 break; 748 candidate.s_addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; 749 candidate.s_addr &= mask.s_addr; 750 if (candidate.s_addr == match.s_addr) 751 break; 752 } 753 if (ifa == NULL) 754 return EADDRNOTAVAIL; 755 ia = (struct in_ifaddr *)ifa; 756 757 if (cmd == SIOCGLIFADDR) { 758 /* fill in the if_laddrreq structure */ 759 memcpy(&iflr->addr, &ia->ia_addr, ia->ia_addr.sin_len); 760 761 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { 762 memcpy(&iflr->dstaddr, &ia->ia_dstaddr, 763 ia->ia_dstaddr.sin_len); 764 } else 765 memset(&iflr->dstaddr, 0, sizeof(iflr->dstaddr)); 766 767 iflr->prefixlen = 768 in_mask2len(&ia->ia_sockmask.sin_addr); 769 770 iflr->flags = 0; /*XXX*/ 771 772 return 0; 773 } else { 774 struct in_aliasreq ifra; 775 776 /* fill in_aliasreq and do ioctl(SIOCDIFADDR) */ 777 memset(&ifra, 0, sizeof(ifra)); 778 memcpy(ifra.ifra_name, iflr->iflr_name, 779 sizeof(ifra.ifra_name)); 780 781 memcpy(&ifra.ifra_addr, &ia->ia_addr, 782 ia->ia_addr.sin_len); 783 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { 784 memcpy(&ifra.ifra_dstaddr, &ia->ia_dstaddr, 785 ia->ia_dstaddr.sin_len); 786 } 787 memcpy(&ifra.ifra_dstaddr, &ia->ia_sockmask, 788 ia->ia_sockmask.sin_len); 789 790 return in_control(so, SIOCDIFADDR, (void *)&ifra, 791 ifp, l); 792 } 793 } 794 } 795 796 return EOPNOTSUPP; /*just for safety*/ 797 } 798 799 /* 800 * Delete any existing route for an interface. 801 */ 802 void 803 in_ifscrub(struct ifnet *ifp, struct in_ifaddr *ia) 804 { 805 806 in_scrubprefix(ia); 807 } 808 809 /* 810 * Initialize an interface's internet address 811 * and routing table entry. 812 */ 813 int 814 in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, 815 const struct sockaddr_in *sin, int scrub) 816 { 817 u_int32_t i; 818 struct sockaddr_in oldaddr; 819 int s = splnet(), flags = RTF_UP, error; 820 821 if (sin == NULL) 822 sin = &ia->ia_addr; 823 824 /* 825 * Set up new addresses. 826 */ 827 oldaddr = ia->ia_addr; 828 if (ia->ia_addr.sin_family == AF_INET) 829 LIST_REMOVE(ia, ia_hash); 830 ia->ia_addr = *sin; 831 LIST_INSERT_HEAD(&IN_IFADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash); 832 833 /* 834 * Give the interface a chance to initialize 835 * if this is its first address, 836 * and to validate the address if necessary. 837 */ 838 if ((error = if_addr_init(ifp, &ia->ia_ifa, true)) != 0) 839 goto bad; 840 splx(s); 841 if (scrub) { 842 ia->ia_ifa.ifa_addr = sintosa(&oldaddr); 843 in_ifscrub(ifp, ia); 844 ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr); 845 } 846 847 i = ia->ia_addr.sin_addr.s_addr; 848 if (IN_CLASSA(i)) 849 ia->ia_netmask = IN_CLASSA_NET; 850 else if (IN_CLASSB(i)) 851 ia->ia_netmask = IN_CLASSB_NET; 852 else 853 ia->ia_netmask = IN_CLASSC_NET; 854 /* 855 * The subnet mask usually includes at least the standard network part, 856 * but may may be smaller in the case of supernetting. 857 * If it is set, we believe it. 858 */ 859 if (ia->ia_subnetmask == 0) { 860 ia->ia_subnetmask = ia->ia_netmask; 861 ia->ia_sockmask.sin_addr.s_addr = ia->ia_subnetmask; 862 } else 863 ia->ia_netmask &= ia->ia_subnetmask; 864 865 ia->ia_net = i & ia->ia_netmask; 866 ia->ia_subnet = i & ia->ia_subnetmask; 867 in_socktrim(&ia->ia_sockmask); 868 /* re-calculate the "in_maxmtu" value */ 869 in_setmaxmtu(); 870 /* 871 * Add route for the network. 872 */ 873 ia->ia_ifa.ifa_metric = ifp->if_metric; 874 if (ifp->if_flags & IFF_BROADCAST) { 875 ia->ia_broadaddr.sin_addr.s_addr = 876 ia->ia_subnet | ~ia->ia_subnetmask; 877 ia->ia_netbroadcast.s_addr = 878 ia->ia_net | ~ia->ia_netmask; 879 } else if (ifp->if_flags & IFF_LOOPBACK) { 880 ia->ia_dstaddr = ia->ia_addr; 881 flags |= RTF_HOST; 882 } else if (ifp->if_flags & IFF_POINTOPOINT) { 883 if (ia->ia_dstaddr.sin_family != AF_INET) 884 return (0); 885 flags |= RTF_HOST; 886 } 887 error = in_addprefix(ia, flags); 888 /* 889 * If the interface supports multicast, join the "all hosts" 890 * multicast group on that interface. 891 */ 892 if ((ifp->if_flags & IFF_MULTICAST) != 0 && ia->ia_allhosts == NULL) { 893 struct in_addr addr; 894 895 addr.s_addr = INADDR_ALLHOSTS_GROUP; 896 ia->ia_allhosts = in_addmulti(&addr, ifp); 897 } 898 return (error); 899 bad: 900 splx(s); 901 LIST_REMOVE(ia, ia_hash); 902 ia->ia_addr = oldaddr; 903 if (ia->ia_addr.sin_family == AF_INET) 904 LIST_INSERT_HEAD(&IN_IFADDR_HASH(ia->ia_addr.sin_addr.s_addr), 905 ia, ia_hash); 906 return (error); 907 } 908 909 #define rtinitflags(x) \ 910 ((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \ 911 ? RTF_HOST : 0) 912 913 /* 914 * add a route to prefix ("connected route" in cisco terminology). 915 * does nothing if there's some interface address with the same prefix already. 916 */ 917 static int 918 in_addprefix(struct in_ifaddr *target, int flags) 919 { 920 struct in_ifaddr *ia; 921 struct in_addr prefix, mask, p; 922 int error; 923 924 if ((flags & RTF_HOST) != 0) 925 prefix = target->ia_dstaddr.sin_addr; 926 else { 927 prefix = target->ia_addr.sin_addr; 928 mask = target->ia_sockmask.sin_addr; 929 prefix.s_addr &= mask.s_addr; 930 } 931 932 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) { 933 if (rtinitflags(ia)) 934 p = ia->ia_dstaddr.sin_addr; 935 else { 936 p = ia->ia_addr.sin_addr; 937 p.s_addr &= ia->ia_sockmask.sin_addr.s_addr; 938 } 939 940 if (prefix.s_addr != p.s_addr) 941 continue; 942 943 /* 944 * if we got a matching prefix route inserted by other 945 * interface address, we don't need to bother 946 * 947 * XXX RADIX_MPATH implications here? -dyoung 948 * 949 * But we should still notify userland of the new address 950 */ 951 if (ia->ia_flags & IFA_ROUTE) { 952 rt_newaddrmsg(RTM_NEWADDR, &target->ia_ifa, 0, NULL); 953 return 0; 954 } 955 } 956 957 /* 958 * noone seem to have prefix route. insert it. 959 */ 960 error = rtinit(&target->ia_ifa, RTM_ADD, flags); 961 if (error == 0) 962 target->ia_flags |= IFA_ROUTE; 963 else if (error == EEXIST) { 964 /* 965 * the fact the route already exists is not an error. 966 */ 967 error = 0; 968 } 969 return error; 970 } 971 972 /* 973 * remove a route to prefix ("connected route" in cisco terminology). 974 * re-installs the route by using another interface address, if there's one 975 * with the same prefix (otherwise we lose the route mistakenly). 976 */ 977 static int 978 in_scrubprefix(struct in_ifaddr *target) 979 { 980 struct in_ifaddr *ia; 981 struct in_addr prefix, mask, p; 982 int error; 983 984 /* If we don't have IFA_ROUTE we should still inform userland */ 985 if ((target->ia_flags & IFA_ROUTE) == 0) { 986 rt_newaddrmsg(RTM_DELADDR, &target->ia_ifa, 0, NULL); 987 return 0; 988 } 989 990 if (rtinitflags(target)) 991 prefix = target->ia_dstaddr.sin_addr; 992 else { 993 prefix = target->ia_addr.sin_addr; 994 mask = target->ia_sockmask.sin_addr; 995 prefix.s_addr &= mask.s_addr; 996 } 997 998 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) { 999 if (rtinitflags(ia)) 1000 p = ia->ia_dstaddr.sin_addr; 1001 else { 1002 p = ia->ia_addr.sin_addr; 1003 p.s_addr &= ia->ia_sockmask.sin_addr.s_addr; 1004 } 1005 1006 if (prefix.s_addr != p.s_addr) 1007 continue; 1008 1009 /* 1010 * if we got a matching prefix route, move IFA_ROUTE to him 1011 */ 1012 if ((ia->ia_flags & IFA_ROUTE) == 0) { 1013 rtinit(&target->ia_ifa, RTM_DELETE, 1014 rtinitflags(target)); 1015 target->ia_flags &= ~IFA_ROUTE; 1016 1017 error = rtinit(&ia->ia_ifa, RTM_ADD, 1018 rtinitflags(ia) | RTF_UP); 1019 if (error == 0) 1020 ia->ia_flags |= IFA_ROUTE; 1021 return error; 1022 } 1023 } 1024 1025 /* 1026 * noone seem to have prefix route. remove it. 1027 */ 1028 rtinit(&target->ia_ifa, RTM_DELETE, rtinitflags(target)); 1029 target->ia_flags &= ~IFA_ROUTE; 1030 return 0; 1031 } 1032 1033 #undef rtinitflags 1034 1035 /* 1036 * Return 1 if the address might be a local broadcast address. 1037 */ 1038 int 1039 in_broadcast(struct in_addr in, struct ifnet *ifp) 1040 { 1041 struct ifaddr *ifa; 1042 1043 if (in.s_addr == INADDR_BROADCAST || 1044 in_nullhost(in)) 1045 return 1; 1046 if ((ifp->if_flags & IFF_BROADCAST) == 0) 1047 return 0; 1048 /* 1049 * Look through the list of addresses for a match 1050 * with a broadcast address. 1051 */ 1052 #define ia (ifatoia(ifa)) 1053 IFADDR_FOREACH(ifa, ifp) 1054 if (ifa->ifa_addr->sa_family == AF_INET && 1055 !in_hosteq(in, ia->ia_addr.sin_addr) && 1056 (in_hosteq(in, ia->ia_broadaddr.sin_addr) || 1057 in_hosteq(in, ia->ia_netbroadcast) || 1058 (hostzeroisbroadcast && 1059 /* 1060 * Check for old-style (host 0) broadcast. 1061 */ 1062 (in.s_addr == ia->ia_subnet || 1063 in.s_addr == ia->ia_net)))) 1064 return 1; 1065 return (0); 1066 #undef ia 1067 } 1068 1069 /* 1070 * Add an address to the list of IP multicast addresses for a given interface. 1071 */ 1072 struct in_multi * 1073 in_addmulti(struct in_addr *ap, struct ifnet *ifp) 1074 { 1075 struct sockaddr_in sin; 1076 struct in_multi *inm; 1077 int s = splsoftnet(); 1078 1079 /* 1080 * See if address already in list. 1081 */ 1082 IN_LOOKUP_MULTI(*ap, ifp, inm); 1083 if (inm != NULL) { 1084 /* 1085 * Found it; just increment the reference count. 1086 */ 1087 ++inm->inm_refcount; 1088 } else { 1089 /* 1090 * New address; allocate a new multicast record 1091 * and link it into the interface's multicast list. 1092 */ 1093 inm = pool_get(&inmulti_pool, PR_NOWAIT); 1094 if (inm == NULL) { 1095 splx(s); 1096 return (NULL); 1097 } 1098 inm->inm_addr = *ap; 1099 inm->inm_ifp = ifp; 1100 inm->inm_refcount = 1; 1101 LIST_INSERT_HEAD( 1102 &IN_MULTI_HASH(inm->inm_addr.s_addr, ifp), 1103 inm, inm_list); 1104 /* 1105 * Ask the network driver to update its multicast reception 1106 * filter appropriately for the new address. 1107 */ 1108 sockaddr_in_init(&sin, ap, 0); 1109 if (if_mcast_op(ifp, SIOCADDMULTI, sintosa(&sin)) != 0) { 1110 LIST_REMOVE(inm, inm_list); 1111 pool_put(&inmulti_pool, inm); 1112 splx(s); 1113 return (NULL); 1114 } 1115 /* 1116 * Let IGMP know that we have joined a new IP multicast group. 1117 */ 1118 if (igmp_joingroup(inm) != 0) { 1119 LIST_REMOVE(inm, inm_list); 1120 pool_put(&inmulti_pool, inm); 1121 splx(s); 1122 return (NULL); 1123 } 1124 in_multientries++; 1125 } 1126 splx(s); 1127 return (inm); 1128 } 1129 1130 /* 1131 * Delete a multicast address record. 1132 */ 1133 void 1134 in_delmulti(struct in_multi *inm) 1135 { 1136 struct sockaddr_in sin; 1137 int s = splsoftnet(); 1138 1139 if (--inm->inm_refcount == 0) { 1140 /* 1141 * No remaining claims to this record; let IGMP know that 1142 * we are leaving the multicast group. 1143 */ 1144 igmp_leavegroup(inm); 1145 /* 1146 * Unlink from list. 1147 */ 1148 LIST_REMOVE(inm, inm_list); 1149 in_multientries--; 1150 /* 1151 * Notify the network driver to update its multicast reception 1152 * filter. 1153 */ 1154 sockaddr_in_init(&sin, &inm->inm_addr, 0); 1155 if_mcast_op(inm->inm_ifp, SIOCDELMULTI, sintosa(&sin)); 1156 pool_put(&inmulti_pool, inm); 1157 } 1158 splx(s); 1159 } 1160 1161 struct sockaddr_in * 1162 in_selectsrc(struct sockaddr_in *sin, struct route *ro, 1163 int soopts, struct ip_moptions *mopts, int *errorp) 1164 { 1165 struct rtentry *rt = NULL; 1166 struct in_ifaddr *ia = NULL; 1167 1168 /* 1169 * If route is known or can be allocated now, take the 1170 * source address from the interface. Otherwise, punt. 1171 */ 1172 if ((soopts & SO_DONTROUTE) != 0) 1173 rtcache_free(ro); 1174 else { 1175 union { 1176 struct sockaddr dst; 1177 struct sockaddr_in dst4; 1178 } u; 1179 1180 sockaddr_in_init(&u.dst4, &sin->sin_addr, 0); 1181 rt = rtcache_lookup(ro, &u.dst); 1182 } 1183 /* 1184 * If we found a route, use the address 1185 * corresponding to the outgoing interface 1186 * unless it is the loopback (in case a route 1187 * to our address on another net goes to loopback). 1188 * 1189 * XXX Is this still true? Do we care? 1190 */ 1191 if (rt != NULL && (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0) 1192 ia = ifatoia(rt->rt_ifa); 1193 if (ia == NULL) { 1194 u_int16_t fport = sin->sin_port; 1195 1196 sin->sin_port = 0; 1197 ia = ifatoia(ifa_ifwithladdr(sintosa(sin))); 1198 sin->sin_port = fport; 1199 if (ia == NULL) { 1200 /* Find 1st non-loopback AF_INET address */ 1201 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) { 1202 if (!(ia->ia_ifp->if_flags & IFF_LOOPBACK)) 1203 break; 1204 } 1205 } 1206 if (ia == NULL) { 1207 *errorp = EADDRNOTAVAIL; 1208 return NULL; 1209 } 1210 } 1211 /* 1212 * If the destination address is multicast and an outgoing 1213 * interface has been set as a multicast option, use the 1214 * address of that interface as our source address. 1215 */ 1216 if (IN_MULTICAST(sin->sin_addr.s_addr) && mopts != NULL) { 1217 struct ip_moptions *imo; 1218 struct ifnet *ifp; 1219 1220 imo = mopts; 1221 if (imo->imo_multicast_ifp != NULL) { 1222 ifp = imo->imo_multicast_ifp; 1223 IFP_TO_IA(ifp, ia); /* XXX */ 1224 if (ia == 0) { 1225 *errorp = EADDRNOTAVAIL; 1226 return NULL; 1227 } 1228 } 1229 } 1230 if (ia->ia_ifa.ifa_getifa != NULL) { 1231 ia = ifatoia((*ia->ia_ifa.ifa_getifa)(&ia->ia_ifa, 1232 sintosa(sin))); 1233 } 1234 #ifdef GETIFA_DEBUG 1235 else 1236 printf("%s: missing ifa_getifa\n", __func__); 1237 #endif 1238 return satosin(&ia->ia_addr); 1239 } 1240 1241 static void 1242 in_sysctl_init(struct sysctllog **clog) 1243 { 1244 sysctl_createv(clog, 0, NULL, NULL, 1245 CTLFLAG_PERMANENT, 1246 CTLTYPE_NODE, "inet", 1247 SYSCTL_DESCR("PF_INET related settings"), 1248 NULL, 0, NULL, 0, 1249 CTL_NET, PF_INET, CTL_EOL); 1250 sysctl_createv(clog, 0, NULL, NULL, 1251 CTLFLAG_PERMANENT, 1252 CTLTYPE_NODE, "ip", 1253 SYSCTL_DESCR("IPv4 related settings"), 1254 NULL, 0, NULL, 0, 1255 CTL_NET, PF_INET, IPPROTO_IP, CTL_EOL); 1256 1257 sysctl_createv(clog, 0, NULL, NULL, 1258 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1259 CTLTYPE_INT, "subnetsarelocal", 1260 SYSCTL_DESCR("Whether logical subnets are considered " 1261 "local"), 1262 NULL, 0, &subnetsarelocal, 0, 1263 CTL_NET, PF_INET, IPPROTO_IP, 1264 IPCTL_SUBNETSARELOCAL, CTL_EOL); 1265 sysctl_createv(clog, 0, NULL, NULL, 1266 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1267 CTLTYPE_INT, "hostzerobroadcast", 1268 SYSCTL_DESCR("All zeroes address is broadcast address"), 1269 NULL, 0, &hostzeroisbroadcast, 0, 1270 CTL_NET, PF_INET, IPPROTO_IP, 1271 IPCTL_HOSTZEROBROADCAST, CTL_EOL); 1272 } 1273