1/* 2 * Copyright (c) 2000-2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * Copyright (c) 1982, 1986, 1991, 1993 30 * The Regents of the University of California. All rights reserved. 31 * 32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions 34 * are met: 35 * 1. Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in the 39 * documentation and/or other materials provided with the distribution. 40 * 3. All advertising materials mentioning features or use of this software 41 * must display the following acknowledgement: 42 * This product includes software developed by the University of 43 * California, Berkeley and its contributors. 44 * 4. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 * 60 * @(#)in.c 8.4 (Berkeley) 1/9/95 61 * $FreeBSD: src/sys/netinet/in.c,v 1.44.2.5 2001/08/13 16:26:17 ume Exp $ 62 */ 63 64#include <sys/param.h> 65#include <sys/systm.h> 66#include <sys/sockio.h> 67#include <sys/socketvar.h> 68#include <sys/malloc.h> 69#include <sys/proc.h> 70#include <sys/socket.h> 71#include <sys/kernel.h> 72#include <sys/sysctl.h> 73#include <sys/kern_event.h> 74#include <sys/syslog.h> 75#include <sys/mcache.h> 76#include <kern/zalloc.h> 77 78#include <pexpert/pexpert.h> 79 80#include <net/if.h> 81#include <net/if_types.h> 82#include <net/route.h> 83#include <net/kpi_protocol.h> 84 85#include <netinet/in.h> 86#include <netinet/in_var.h> 87#include <netinet/in_pcb.h> 88 89#include <netinet/igmp_var.h> 90#include <net/dlil.h> 91 92#include <netinet/ip_var.h> 93 94#include <netinet/tcp.h> 95#include <netinet/tcp_timer.h> 96#include <netinet/tcp_var.h> 97 98#include <sys/file.h> 99 100#if PF 101#include <net/pfvar.h> 102#endif /* PF */ 103 104static int in_mask2len(struct in_addr *); 105static void in_len2mask(struct in_addr *, int); 106static int in_lifaddr_ioctl(struct socket *, u_long, struct if_laddrreq *, 107 struct ifnet *, struct proc *); 108static int in_setrouter(struct ifnet *, int); 109 110static void in_socktrim(struct sockaddr_in *); 111static int in_ifinit(struct ifnet *, 112 struct in_ifaddr *, struct sockaddr_in *, int); 113 114#define IA_HASH_INIT(ia) { \ 115 (ia)->ia_hash.tqe_next = (void *)(uintptr_t)-1; \ 116 (ia)->ia_hash.tqe_prev = (void *)(uintptr_t)-1; \ 117} 118 119#define IA_IS_HASHED(ia) \ 120 (!((ia)->ia_hash.tqe_next == (void *)(uintptr_t)-1 || \ 121 (ia)->ia_hash.tqe_prev == (void *)(uintptr_t)-1)) 122 123static void in_iahash_remove(struct in_ifaddr *); 124static void in_iahash_insert(struct in_ifaddr *); 125static void in_iahash_insert_ptp(struct in_ifaddr *); 126static struct in_ifaddr *in_ifaddr_alloc(int); 127static void in_ifaddr_attached(struct ifaddr *); 128static void in_ifaddr_detached(struct ifaddr *); 129static void in_ifaddr_free(struct ifaddr *); 130static void in_ifaddr_trace(struct ifaddr *, int); 131 132static int subnetsarelocal = 0; 133SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW | CTLFLAG_LOCKED, 134 &subnetsarelocal, 0, ""); 135 136/* Track whether or not the SIOCARPIPLL ioctl has been called */ 137__private_extern__ u_int32_t ipv4_ll_arp_aware = 0; 138 139#define INIFA_TRACE_HIST_SIZE 32 /* size of trace history */ 140 141/* For gdb */ 142__private_extern__ unsigned int inifa_trace_hist_size = INIFA_TRACE_HIST_SIZE; 143 144struct in_ifaddr_dbg { 145 struct in_ifaddr inifa; /* in_ifaddr */ 146 struct in_ifaddr inifa_old; /* saved in_ifaddr */ 147 u_int16_t inifa_refhold_cnt; /* # of IFA_ADDREF */ 148 u_int16_t inifa_refrele_cnt; /* # of IFA_REMREF */ 149 /* 150 * Alloc and free callers. 151 */ 152 ctrace_t inifa_alloc; 153 ctrace_t inifa_free; 154 /* 155 * Circular lists of IFA_ADDREF and IFA_REMREF callers. 156 */ 157 ctrace_t inifa_refhold[INIFA_TRACE_HIST_SIZE]; 158 ctrace_t inifa_refrele[INIFA_TRACE_HIST_SIZE]; 159 /* 160 * Trash list linkage 161 */ 162 TAILQ_ENTRY(in_ifaddr_dbg) inifa_trash_link; 163}; 164 165/* List of trash in_ifaddr entries protected by inifa_trash_lock */ 166static TAILQ_HEAD(, in_ifaddr_dbg) inifa_trash_head; 167static decl_lck_mtx_data(, inifa_trash_lock); 168 169#if DEBUG 170static unsigned int inifa_debug = 1; /* debugging (enabled) */ 171#else 172static unsigned int inifa_debug; /* debugging (disabled) */ 173#endif /* !DEBUG */ 174static unsigned int inifa_size; /* size of zone element */ 175static struct zone *inifa_zone; /* zone for in_ifaddr */ 176 177#define INIFA_ZONE_MAX 64 /* maximum elements in zone */ 178#define INIFA_ZONE_NAME "in_ifaddr" /* zone name */ 179 180/* 181 * Return 1 if the address is 182 * - loopback 183 * - unicast or multicast link local 184 * - routed via a link level gateway 185 * - belongs to a directly connected (sub)net 186 */ 187int 188inaddr_local(struct in_addr in) 189{ 190 struct rtentry *rt; 191 struct sockaddr_in sin; 192 int local = 0; 193 194 if (ntohl(in.s_addr) == INADDR_LOOPBACK || IN_LINKLOCAL(ntohl(in.s_addr))) { 195 local = 1; 196 } else if (ntohl(in.s_addr) >= INADDR_UNSPEC_GROUP && 197 ntohl(in.s_addr) <= INADDR_MAX_LOCAL_GROUP) { 198 local = 1; 199 } else { 200 sin.sin_family = AF_INET; 201 sin.sin_len = sizeof (sin); 202 sin.sin_addr = in; 203 rt = rtalloc1((struct sockaddr *)&sin, 0, 0); 204 205 if (rt != NULL) { 206 RT_LOCK_SPIN(rt); 207 if (rt->rt_gateway->sa_family == AF_LINK || 208 (rt->rt_ifp->if_flags & IFF_LOOPBACK)) 209 local = 1; 210 RT_UNLOCK(rt); 211 rtfree(rt); 212 } else { 213 local = in_localaddr(in); 214 } 215 } 216 return (local); 217} 218 219/* 220 * Return 1 if an internet address is for a ``local'' host 221 * (one to which we have a connection). If subnetsarelocal 222 * is true, this includes other subnets of the local net. 223 * Otherwise, it includes only the directly-connected (sub)nets. 224 */ 225int 226in_localaddr(struct in_addr in) 227{ 228 u_int32_t i = ntohl(in.s_addr); 229 struct in_ifaddr *ia; 230 231 if (subnetsarelocal) { 232 lck_rw_lock_shared(in_ifaddr_rwlock); 233 for (ia = in_ifaddrhead.tqh_first; ia; 234 ia = ia->ia_link.tqe_next) { 235 IFA_LOCK(&ia->ia_ifa); 236 if ((i & ia->ia_netmask) == ia->ia_net) { 237 IFA_UNLOCK(&ia->ia_ifa); 238 lck_rw_done(in_ifaddr_rwlock); 239 return (1); 240 } 241 IFA_UNLOCK(&ia->ia_ifa); 242 } 243 lck_rw_done(in_ifaddr_rwlock); 244 } else { 245 lck_rw_lock_shared(in_ifaddr_rwlock); 246 for (ia = in_ifaddrhead.tqh_first; ia; 247 ia = ia->ia_link.tqe_next) { 248 IFA_LOCK(&ia->ia_ifa); 249 if ((i & ia->ia_subnetmask) == ia->ia_subnet) { 250 IFA_UNLOCK(&ia->ia_ifa); 251 lck_rw_done(in_ifaddr_rwlock); 252 return (1); 253 } 254 IFA_UNLOCK(&ia->ia_ifa); 255 } 256 lck_rw_done(in_ifaddr_rwlock); 257 } 258 return (0); 259} 260 261/* 262 * Determine whether an IP address is in a reserved set of addresses 263 * that may not be forwarded, or whether datagrams to that destination 264 * may be forwarded. 265 */ 266int 267in_canforward(struct in_addr in) 268{ 269 u_int32_t i = ntohl(in.s_addr); 270 u_int32_t net; 271 272 if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i)) 273 return (0); 274 if (IN_CLASSA(i)) { 275 net = i & IN_CLASSA_NET; 276 if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT)) 277 return (0); 278 } 279 return (1); 280} 281 282/* 283 * Trim a mask in a sockaddr 284 */ 285static void 286in_socktrim(struct sockaddr_in *ap) 287{ 288 char *cplim = (char *) &ap->sin_addr; 289 char *cp = (char *) (&ap->sin_addr + 1); 290 291 ap->sin_len = 0; 292 while (--cp >= cplim) 293 if (*cp) { 294 (ap)->sin_len = cp - (char *) (ap) + 1; 295 break; 296 } 297} 298 299static int 300in_mask2len(struct in_addr *mask) 301{ 302 size_t x, y; 303 u_char *p; 304 305 p = (u_char *)mask; 306 for (x = 0; x < sizeof(*mask); x++) { 307 if (p[x] != 0xff) 308 break; 309 } 310 y = 0; 311 if (x < sizeof(*mask)) { 312 for (y = 0; y < 8; y++) { 313 if ((p[x] & (0x80 >> y)) == 0) 314 break; 315 } 316 } 317 return x * 8 + y; 318} 319 320static void 321in_len2mask(struct in_addr *mask, int len) 322{ 323 int i; 324 u_char *p; 325 326 p = (u_char *)mask; 327 bzero(mask, sizeof(*mask)); 328 for (i = 0; i < len / 8; i++) 329 p[i] = 0xff; 330 if (len % 8) 331 p[i] = (0xff00 >> (len % 8)) & 0xff; 332} 333 334static int in_interfaces; /* number of external internet interfaces */ 335 336static int 337in_domifattach(struct ifnet *ifp) 338{ 339 int error; 340 341 if ((error = proto_plumb(PF_INET, ifp)) && error != EEXIST) 342 log(LOG_ERR, "%s: proto_plumb returned %d if=%s%d\n", 343 __func__, error, ifp->if_name, ifp->if_unit); 344 345 return (error); 346} 347 348/* 349 * Generic internet control operations (ioctl's). 350 * Ifp is 0 if not an interface-specific ioctl. 351 * 352 * Returns: 0 Success 353 * EINVAL 354 * EADDRNOTAVAIL 355 * EDESTADDRREQ 356 * EPERM 357 * ENOBUFS 358 * EBUSY 359 * EOPNOTSUPP 360 * proc_suser:EPERM 361 * suser:EPERM 362 * in_lifaddr_ioctl:??? 363 * dlil_ioctl:??? 364 * in_ifinit:??? 365 * dlil_plumb_protocol:??? 366 * dlil_unplumb_protocol:??? 367 */ 368/* ARGSUSED */ 369int 370in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, 371 struct proc *p) 372{ 373 struct in_ifaddr *ia = NULL; 374 struct ifaddr *ifa; 375 struct sockaddr_in oldaddr; 376 int error = 0; 377 int hostIsNew, maskIsNew; 378 struct kev_msg ev_msg; 379 struct kev_in_data in_event_data; 380 381 bzero(&in_event_data, sizeof (struct kev_in_data)); 382 bzero(&ev_msg, sizeof (struct kev_msg)); 383 384 switch (cmd) { 385 case SIOCALIFADDR: /* struct if_laddrreq */ 386 case SIOCDLIFADDR: /* struct if_laddrreq */ 387 if ((error = proc_suser(p)) != 0) 388 return (error); 389 /* FALLTHRU */ 390 case SIOCGLIFADDR: { /* struct if_laddrreq */ 391 struct if_laddrreq iflr; 392 393 if (ifp == NULL) 394 return (EINVAL); 395 396 bcopy(data, &iflr, sizeof (iflr)); 397 error = in_lifaddr_ioctl(so, cmd, &iflr, ifp, p); 398 bcopy(&iflr, data, sizeof (iflr)); 399 return (error); 400 } 401 } 402 403 /* 404 * Find address for this interface, if it exists. 405 * 406 * If an alias address was specified, find that one instead of 407 * the first one on the interface. 408 */ 409 if (ifp != NULL) { 410 struct in_ifaddr *iap; 411 struct sockaddr_in sin; 412 413 bcopy(&((struct ifreq *)(void *)data)->ifr_addr, 414 &sin, sizeof (sin)); 415 416 lck_rw_lock_shared(in_ifaddr_rwlock); 417 for (iap = in_ifaddrhead.tqh_first; iap != NULL; 418 iap = iap->ia_link.tqe_next) { 419 if (iap->ia_ifp != ifp) 420 continue; 421 422 IFA_LOCK(&iap->ia_ifa); 423 if (sin.sin_addr.s_addr == 424 iap->ia_addr.sin_addr.s_addr) { 425 ia = iap; 426 IFA_UNLOCK(&iap->ia_ifa); 427 break; 428 } else if (ia == NULL) { 429 ia = iap; 430 if (sin.sin_family != AF_INET) { 431 IFA_UNLOCK(&iap->ia_ifa); 432 break; 433 } 434 } 435 IFA_UNLOCK(&iap->ia_ifa); 436 } 437 /* take a reference on ia before releasing lock */ 438 if (ia != NULL) 439 IFA_ADDREF(&ia->ia_ifa); 440 lck_rw_done(in_ifaddr_rwlock); 441 } 442 443 switch (cmd) { 444 case SIOCAUTOADDR: /* struct ifreq */ 445 case SIOCARPIPLL: /* struct ifreq */ 446 case SIOCSETROUTERMODE: /* struct ifreq */ 447 if ((error = proc_suser(p)) != 0) { 448 goto done; 449 } 450 if (ifp == NULL) { 451 error = EADDRNOTAVAIL; 452 goto done; 453 } 454 break; 455 456 case SIOCAIFADDR: /* struct ifaliasreq */ 457 case SIOCDIFADDR: { /* struct ifreq */ 458 struct sockaddr_in addr, dstaddr; 459 460 if (ifp == NULL) { 461 error = EADDRNOTAVAIL; 462 goto done; 463 } 464 465 if (cmd == SIOCAIFADDR) { 466 bcopy(&((struct in_aliasreq *)(void *)data)-> 467 ifra_addr, &addr, sizeof (addr)); 468 bcopy(&((struct in_aliasreq *)(void *)data)-> 469 ifra_dstaddr, &dstaddr, sizeof (dstaddr)); 470 } else { 471 VERIFY(cmd == SIOCDIFADDR); 472 bcopy(&((struct ifreq *)(void *)data)->ifr_addr, 473 &addr, sizeof (addr)); 474 bzero(&dstaddr, sizeof (dstaddr)); 475 } 476 477 if (addr.sin_family == AF_INET) { 478 struct in_ifaddr *oia; 479 480 lck_rw_lock_shared(in_ifaddr_rwlock); 481 for (oia = ia; ia; ia = ia->ia_link.tqe_next) { 482 IFA_LOCK(&ia->ia_ifa); 483 if (ia->ia_ifp == ifp && 484 ia->ia_addr.sin_addr.s_addr == 485 addr.sin_addr.s_addr) { 486 IFA_ADDREF_LOCKED(&ia->ia_ifa); 487 IFA_UNLOCK(&ia->ia_ifa); 488 break; 489 } 490 IFA_UNLOCK(&ia->ia_ifa); 491 } 492 lck_rw_done(in_ifaddr_rwlock); 493 if (oia != NULL) 494 IFA_REMREF(&oia->ia_ifa); 495 if ((ifp->if_flags & IFF_POINTOPOINT) && 496 (cmd == SIOCAIFADDR) && 497 (dstaddr.sin_addr.s_addr == INADDR_ANY)) { 498 error = EDESTADDRREQ; 499 goto done; 500 } 501 } else if (cmd == SIOCAIFADDR) { 502 error = EINVAL; 503 goto done; 504 } 505 if (cmd == SIOCDIFADDR && ia == NULL) { 506 error = EADDRNOTAVAIL; 507 goto done; 508 } 509 /* FALLTHROUGH */ 510 } 511 case SIOCSIFADDR: /* struct ifreq */ 512 case SIOCSIFNETMASK: /* struct ifreq */ 513 case SIOCSIFDSTADDR: { /* struct ifreq */ 514 struct sockaddr_in addr; 515 516 if (cmd == SIOCAIFADDR) { 517 /* fell thru from above; just repeat it */ 518 bcopy(&((struct in_aliasreq *)(void *)data)-> 519 ifra_addr, &addr, sizeof (addr)); 520 } else { 521 VERIFY(cmd == SIOCDIFADDR || cmd == SIOCSIFADDR || 522 cmd == SIOCSIFNETMASK || cmd == SIOCSIFDSTADDR); 523 bcopy(&((struct ifreq *)(void *)data)->ifr_addr, 524 &addr, sizeof (addr)); 525 } 526 527 /* socket is NULL if called from in_purgeaddrs() */ 528 if (so != NULL && (so->so_state & SS_PRIV) == 0) { 529 error = EPERM; 530 goto done; 531 } 532 /* in case it's NULL, make sure it came from the kernel */ 533 if (so == NULL && p != kernproc) { 534 error = EPERM; 535 goto done; 536 } 537 if (ifp == NULL) { 538 error = EADDRNOTAVAIL; 539 goto done; 540 } 541 if (addr.sin_family != AF_INET && cmd == SIOCSIFADDR) { 542 error = EINVAL; 543 goto done; 544 } 545 if (ia == NULL) { 546 ia = in_ifaddr_alloc(M_WAITOK); 547 if (ia == NULL) { 548 error = ENOBUFS; 549 goto done; 550 } 551 ifnet_lock_exclusive(ifp); 552 ifa = &ia->ia_ifa; 553 IFA_LOCK(ifa); 554 /* Hold a reference for this routine */ 555 IFA_ADDREF_LOCKED(ifa); 556 IA_HASH_INIT(ia); 557 ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr; 558 ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr; 559 ifa->ifa_netmask = (struct sockaddr *)&ia->ia_sockmask; 560 ia->ia_sockmask.sin_len = 8; 561 if (ifp->if_flags & IFF_BROADCAST) { 562 ia->ia_broadaddr.sin_len = sizeof (ia->ia_addr); 563 ia->ia_broadaddr.sin_family = AF_INET; 564 } 565 ia->ia_ifp = ifp; 566 if (!(ifp->if_flags & IFF_LOOPBACK)) 567 in_interfaces++; 568 /* if_attach_ifa() holds a reference for ifa_link */ 569 if_attach_ifa(ifp, ifa); 570 /* 571 * If we have to go through in_ifinit(), make sure 572 * to avoid installing route(s) based on this address 573 * via PFC_IFUP event, before the link resolver (ARP) 574 * initializes it. 575 */ 576 if (cmd == SIOCAIFADDR || cmd == SIOCSIFADDR) 577 ifa->ifa_debug |= IFD_NOTREADY; 578 IFA_UNLOCK(ifa); 579 ifnet_lock_done(ifp); 580 lck_rw_lock_exclusive(in_ifaddr_rwlock); 581 /* Hold a reference for ia_link */ 582 IFA_ADDREF(ifa); 583 TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_link); 584 lck_rw_done(in_ifaddr_rwlock); 585 /* discard error */ 586 (void) in_domifattach(ifp); 587 error = 0; 588 } 589 break; 590 } 591 592 case SIOCPROTOATTACH: /* struct ifreq */ 593 case SIOCPROTODETACH: /* struct ifreq */ 594 if ((error = proc_suser(p)) != 0) { 595 goto done; 596 } 597 if (ifp == NULL) { 598 error = EADDRNOTAVAIL; 599 goto done; 600 } 601 break; 602 603 case SIOCSIFBRDADDR: /* struct ifreq */ 604 if ((so->so_state & SS_PRIV) == 0) { 605 error = EPERM; 606 goto done; 607 } 608 /* FALLTHROUGH */ 609 case SIOCGIFADDR: /* struct ifreq */ 610 case SIOCGIFNETMASK: /* struct ifreq */ 611 case SIOCGIFDSTADDR: /* struct ifreq */ 612 case SIOCGIFBRDADDR: /* struct ifreq */ 613 if (ia == NULL) { 614 error = EADDRNOTAVAIL; 615 goto done; 616 } 617 break; 618 } 619 620 switch (cmd) { 621 case SIOCAUTOADDR: { /* struct ifreq */ 622 int intval; 623 624 VERIFY(ifp != NULL); 625 bcopy(&((struct ifreq *)(void *)data)->ifr_intval, 626 &intval, sizeof (intval)); 627 628 ifnet_lock_exclusive(ifp); 629 if (intval) { 630 /* 631 * An interface in IPv4 router mode implies that it 632 * is configured with a static IP address and should 633 * not act as a DHCP client; prevent SIOCAUTOADDR from 634 * being set in that mode. 635 */ 636 if (ifp->if_eflags & IFEF_IPV4_ROUTER) { 637 intval = 0; /* be safe; clear flag if set */ 638 error = EBUSY; 639 } else { 640 ifp->if_eflags |= IFEF_AUTOCONFIGURING; 641 } 642 } 643 if (!intval) 644 ifp->if_eflags &= ~IFEF_AUTOCONFIGURING; 645 ifnet_lock_done(ifp); 646 break; 647 } 648 649 case SIOCARPIPLL: { /* struct ifreq */ 650 int intval; 651 652 VERIFY(ifp != NULL); 653 bcopy(&((struct ifreq *)(void *)data)->ifr_intval, 654 &intval, sizeof (intval)); 655 ipv4_ll_arp_aware = 1; 656 657 ifnet_lock_exclusive(ifp); 658 if (intval) { 659 /* 660 * An interface in IPv4 router mode implies that it 661 * is configured with a static IP address and should 662 * not have to deal with IPv4 Link-Local Address; 663 * prevent SIOCARPIPLL from being set in that mode. 664 */ 665 if (ifp->if_eflags & IFEF_IPV4_ROUTER) { 666 intval = 0; /* be safe; clear flag if set */ 667 error = EBUSY; 668 } else { 669 ifp->if_eflags |= IFEF_ARPLL; 670 } 671 } 672 if (!intval) 673 ifp->if_eflags &= ~IFEF_ARPLL; 674 ifnet_lock_done(ifp); 675 break; 676 } 677 678 case SIOCGIFADDR: /* struct ifreq */ 679 VERIFY(ia != NULL); 680 IFA_LOCK(&ia->ia_ifa); 681 bcopy(&ia->ia_addr, &((struct ifreq *)(void *)data)->ifr_addr, 682 sizeof (struct sockaddr_in)); 683 IFA_UNLOCK(&ia->ia_ifa); 684 break; 685 686 case SIOCGIFBRDADDR: /* struct ifreq */ 687 VERIFY(ia != NULL); 688 if ((ifp->if_flags & IFF_BROADCAST) == 0) { 689 error = EINVAL; 690 break; 691 } 692 IFA_LOCK(&ia->ia_ifa); 693 bcopy(&ia->ia_broadaddr, 694 &((struct ifreq *)(void *)data)->ifr_broadaddr, 695 sizeof (struct sockaddr_in)); 696 IFA_UNLOCK(&ia->ia_ifa); 697 break; 698 699 case SIOCGIFDSTADDR: /* struct ifreq */ 700 VERIFY(ia != NULL); 701 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) { 702 error = EINVAL; 703 break; 704 } 705 IFA_LOCK(&ia->ia_ifa); 706 bcopy(&ia->ia_dstaddr, 707 &((struct ifreq *)(void *)data)->ifr_dstaddr, 708 sizeof (struct sockaddr_in)); 709 IFA_UNLOCK(&ia->ia_ifa); 710 break; 711 712 case SIOCGIFNETMASK: /* struct ifreq */ 713 VERIFY(ia != NULL); 714 IFA_LOCK(&ia->ia_ifa); 715 bcopy(&ia->ia_sockmask, 716 &((struct ifreq *)(void *)data)->ifr_addr, 717 sizeof (struct sockaddr_in)); 718 IFA_UNLOCK(&ia->ia_ifa); 719 break; 720 721 case SIOCSIFDSTADDR: /* struct ifreq */ 722 VERIFY(ifp != NULL && ia != NULL); 723 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) { 724 error = EINVAL; 725 break; 726 } 727 IFA_LOCK(&ia->ia_ifa); 728 oldaddr = ia->ia_dstaddr; 729 bcopy(&((struct ifreq *)(void *)data)->ifr_dstaddr, 730 &ia->ia_dstaddr, sizeof (struct sockaddr_in)); 731 if (ia->ia_dstaddr.sin_family == AF_INET) 732 ia->ia_dstaddr.sin_len = sizeof (struct sockaddr_in); 733 IFA_UNLOCK(&ia->ia_ifa); 734 /* 735 * NOTE: SIOCSIFDSTADDR is defined with struct ifreq 736 * as parameter, but here we are sending it down 737 * to the interface with a pointer to struct ifaddr, 738 * for legacy reasons. 739 */ 740 error = ifnet_ioctl(ifp, PF_INET, SIOCSIFDSTADDR, ia); 741 IFA_LOCK(&ia->ia_ifa); 742 if (error == EOPNOTSUPP) { 743 error = 0; 744 } 745 if (error) { 746 ia->ia_dstaddr = oldaddr; 747 IFA_UNLOCK(&ia->ia_ifa); 748 break; 749 } 750 IFA_LOCK_ASSERT_HELD(&ia->ia_ifa); 751 752 ev_msg.vendor_code = KEV_VENDOR_APPLE; 753 ev_msg.kev_class = KEV_NETWORK_CLASS; 754 ev_msg.kev_subclass = KEV_INET_SUBCLASS; 755 756 ev_msg.event_code = KEV_INET_SIFDSTADDR; 757 758 if (ia->ia_ifa.ifa_dstaddr) { 759 in_event_data.ia_dstaddr = ((struct sockaddr_in *) 760 (void *)ia->ia_ifa.ifa_dstaddr)->sin_addr; 761 } else { 762 in_event_data.ia_dstaddr.s_addr = INADDR_ANY; 763 } 764 765 in_event_data.ia_addr = ia->ia_addr.sin_addr; 766 in_event_data.ia_net = ia->ia_net; 767 in_event_data.ia_netmask = ia->ia_netmask; 768 in_event_data.ia_subnet = ia->ia_subnet; 769 in_event_data.ia_subnetmask = ia->ia_subnetmask; 770 in_event_data.ia_netbroadcast = ia->ia_netbroadcast; 771 IFA_UNLOCK(&ia->ia_ifa); 772 (void) strncpy(&in_event_data.link_data.if_name[0], 773 ifp->if_name, IFNAMSIZ); 774 in_event_data.link_data.if_family = ifp->if_family; 775 in_event_data.link_data.if_unit = (u_int32_t) ifp->if_unit; 776 777 ev_msg.dv[0].data_ptr = &in_event_data; 778 ev_msg.dv[0].data_length = sizeof (struct kev_in_data); 779 ev_msg.dv[1].data_length = 0; 780 781 kev_post_msg(&ev_msg); 782 783 lck_mtx_lock(rnh_lock); 784 IFA_LOCK(&ia->ia_ifa); 785 if (ia->ia_flags & IFA_ROUTE) { 786 ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr; 787 IFA_UNLOCK(&ia->ia_ifa); 788 rtinit_locked(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 789 IFA_LOCK(&ia->ia_ifa); 790 ia->ia_ifa.ifa_dstaddr = 791 (struct sockaddr *)&ia->ia_dstaddr; 792 IFA_UNLOCK(&ia->ia_ifa); 793 rtinit_locked(&(ia->ia_ifa), (int)RTM_ADD, 794 RTF_HOST|RTF_UP); 795 } else { 796 IFA_UNLOCK(&ia->ia_ifa); 797 } 798 lck_mtx_unlock(rnh_lock); 799 break; 800 801 case SIOCSIFBRDADDR: /* struct ifreq */ 802 VERIFY(ia != NULL); 803 if ((ifp->if_flags & IFF_BROADCAST) == 0) { 804 error = EINVAL; 805 break; 806 } 807 IFA_LOCK(&ia->ia_ifa); 808 bcopy(&((struct ifreq *)(void *)data)->ifr_broadaddr, 809 &ia->ia_broadaddr, sizeof (struct sockaddr_in)); 810 811 ev_msg.vendor_code = KEV_VENDOR_APPLE; 812 ev_msg.kev_class = KEV_NETWORK_CLASS; 813 ev_msg.kev_subclass = KEV_INET_SUBCLASS; 814 815 ev_msg.event_code = KEV_INET_SIFBRDADDR; 816 817 if (ia->ia_ifa.ifa_dstaddr) { 818 in_event_data.ia_dstaddr = ((struct sockaddr_in *) 819 (void *)ia->ia_ifa.ifa_dstaddr)->sin_addr; 820 } else { 821 in_event_data.ia_dstaddr.s_addr = INADDR_ANY; 822 } 823 in_event_data.ia_addr = ia->ia_addr.sin_addr; 824 in_event_data.ia_net = ia->ia_net; 825 in_event_data.ia_netmask = ia->ia_netmask; 826 in_event_data.ia_subnet = ia->ia_subnet; 827 in_event_data.ia_subnetmask = ia->ia_subnetmask; 828 in_event_data.ia_netbroadcast = ia->ia_netbroadcast; 829 IFA_UNLOCK(&ia->ia_ifa); 830 (void) strncpy(&in_event_data.link_data.if_name[0], 831 ifp->if_name, IFNAMSIZ); 832 in_event_data.link_data.if_family = ifp->if_family; 833 in_event_data.link_data.if_unit = (u_int32_t) ifp->if_unit; 834 835 ev_msg.dv[0].data_ptr = &in_event_data; 836 ev_msg.dv[0].data_length = sizeof (struct kev_in_data); 837 ev_msg.dv[1].data_length = 0; 838 839 kev_post_msg(&ev_msg); 840 break; 841 842 case SIOCSIFADDR: { /* struct ifreq */ 843 struct sockaddr_in addr; 844 845 VERIFY(ifp != NULL && ia != NULL); 846 bcopy(&((struct ifreq *)(void *)data)->ifr_addr, 847 &addr, sizeof (addr)); 848 /* 849 * If this is a new address, the reference count for the 850 * hash table has been taken at creation time above. 851 */ 852 error = in_ifinit(ifp, ia, &addr, 1); 853#if PF 854 if (!error) 855 (void) pf_ifaddr_hook(ifp, cmd); 856#endif /* PF */ 857 break; 858 } 859 860 case SIOCPROTOATTACH: /* struct ifreq */ 861 VERIFY(ifp != NULL); 862 error = in_domifattach(ifp); 863 break; 864 865 case SIOCPROTODETACH: /* struct ifreq */ 866 VERIFY(ifp != NULL); 867 /* 868 * If an IPv4 address is still present, refuse to detach. 869 */ 870 ifnet_lock_shared(ifp); 871 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 872 IFA_LOCK(ifa); 873 if (ifa->ifa_addr->sa_family == AF_INET) { 874 IFA_UNLOCK(ifa); 875 break; 876 } 877 IFA_UNLOCK(ifa); 878 } 879 ifnet_lock_done(ifp); 880 if (ifa != NULL) { 881 error = EBUSY; 882 break; 883 } 884 885 error = proto_unplumb(PF_INET, ifp); 886 break; 887 888 case SIOCSETROUTERMODE: { /* struct ifreq */ 889 int intval; 890 891 VERIFY(ifp != NULL); 892 bcopy(&((struct ifreq *)(void *)data)->ifr_intval, 893 &intval, sizeof (intval)); 894 895 error = in_setrouter(ifp, intval); 896 break; 897 } 898 899 case SIOCSIFNETMASK: { /* struct ifreq */ 900 struct sockaddr_in addr; 901 in_addr_t i; 902 903 VERIFY(ifp != NULL && ia != NULL); 904 bcopy(&((struct ifreq *)(void *)data)->ifr_addr, 905 &addr, sizeof (addr)); 906 i = addr.sin_addr.s_addr; 907 908 IFA_LOCK(&ia->ia_ifa); 909 ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr = i); 910 ev_msg.vendor_code = KEV_VENDOR_APPLE; 911 ev_msg.kev_class = KEV_NETWORK_CLASS; 912 ev_msg.kev_subclass = KEV_INET_SUBCLASS; 913 914 ev_msg.event_code = KEV_INET_SIFNETMASK; 915 916 if (ia->ia_ifa.ifa_dstaddr) { 917 in_event_data.ia_dstaddr = ((struct sockaddr_in *) 918 (void *)ia->ia_ifa.ifa_dstaddr)->sin_addr; 919 } else { 920 in_event_data.ia_dstaddr.s_addr = INADDR_ANY; 921 } 922 in_event_data.ia_addr = ia->ia_addr.sin_addr; 923 in_event_data.ia_net = ia->ia_net; 924 in_event_data.ia_netmask = ia->ia_netmask; 925 in_event_data.ia_subnet = ia->ia_subnet; 926 in_event_data.ia_subnetmask = ia->ia_subnetmask; 927 in_event_data.ia_netbroadcast = ia->ia_netbroadcast; 928 IFA_UNLOCK(&ia->ia_ifa); 929 (void) strncpy(&in_event_data.link_data.if_name[0], 930 ifp->if_name, IFNAMSIZ); 931 in_event_data.link_data.if_family = ifp->if_family; 932 in_event_data.link_data.if_unit = (u_int32_t) ifp->if_unit; 933 934 ev_msg.dv[0].data_ptr = &in_event_data; 935 ev_msg.dv[0].data_length = sizeof (struct kev_in_data); 936 ev_msg.dv[1].data_length = 0; 937 938 kev_post_msg(&ev_msg); 939 break; 940 } 941 942 case SIOCAIFADDR: { /* struct ifaliasreq */ 943 struct sockaddr_in addr, broadaddr, mask; 944 945 VERIFY(ifp != NULL && ia != NULL); 946 bcopy(&((struct ifaliasreq *)(void *)data)->ifra_addr, 947 &addr, sizeof (addr)); 948 bcopy(&((struct ifaliasreq *)(void *)data)->ifra_broadaddr, 949 &broadaddr, sizeof (broadaddr)); 950 bcopy(&((struct ifaliasreq *)(void *)data)->ifra_mask, 951 &mask, sizeof (mask)); 952 953 maskIsNew = 0; 954 hostIsNew = 1; 955 error = 0; 956 957 IFA_LOCK(&ia->ia_ifa); 958 if (ia->ia_addr.sin_family == AF_INET) { 959 if (addr.sin_len == 0) { 960 addr = ia->ia_addr; 961 hostIsNew = 0; 962 } else if (addr.sin_addr.s_addr == 963 ia->ia_addr.sin_addr.s_addr) { 964 hostIsNew = 0; 965 } 966 } 967 if (mask.sin_len) { 968 IFA_UNLOCK(&ia->ia_ifa); 969 in_ifscrub(ifp, ia, 0); 970 IFA_LOCK(&ia->ia_ifa); 971 ia->ia_sockmask = mask; 972 ia->ia_subnetmask = 973 ntohl(ia->ia_sockmask.sin_addr.s_addr); 974 maskIsNew = 1; 975 } 976 if ((ifp->if_flags & IFF_POINTOPOINT) && 977 (broadaddr.sin_family == AF_INET)) { 978 IFA_UNLOCK(&ia->ia_ifa); 979 in_ifscrub(ifp, ia, 0); 980 IFA_LOCK(&ia->ia_ifa); 981 ia->ia_dstaddr = broadaddr; 982 ia->ia_dstaddr.sin_len = sizeof (struct sockaddr_in); 983 maskIsNew = 1; /* We lie; but the effect's the same */ 984 } 985 if (addr.sin_family == AF_INET && (hostIsNew || maskIsNew)) { 986 IFA_UNLOCK(&ia->ia_ifa); 987 error = in_ifinit(ifp, ia, &addr, 0); 988 } else { 989 IFA_UNLOCK(&ia->ia_ifa); 990 } 991#if PF 992 if (!error) 993 (void) pf_ifaddr_hook(ifp, cmd); 994#endif /* PF */ 995 IFA_LOCK(&ia->ia_ifa); 996 if ((ifp->if_flags & IFF_BROADCAST) && 997 (broadaddr.sin_family == AF_INET)) 998 ia->ia_broadaddr = broadaddr; 999 1000 /* 1001 * Report event. 1002 */ 1003 if ((error == 0) || (error == EEXIST)) { 1004 ev_msg.vendor_code = KEV_VENDOR_APPLE; 1005 ev_msg.kev_class = KEV_NETWORK_CLASS; 1006 ev_msg.kev_subclass = KEV_INET_SUBCLASS; 1007 1008 if (hostIsNew) 1009 ev_msg.event_code = KEV_INET_NEW_ADDR; 1010 else 1011 ev_msg.event_code = KEV_INET_CHANGED_ADDR; 1012 1013 if (ia->ia_ifa.ifa_dstaddr) { 1014 in_event_data.ia_dstaddr = 1015 ((struct sockaddr_in *)(void *)ia-> 1016 ia_ifa.ifa_dstaddr)->sin_addr; 1017 } else { 1018 in_event_data.ia_dstaddr.s_addr = INADDR_ANY; 1019 } 1020 in_event_data.ia_addr = ia->ia_addr.sin_addr; 1021 in_event_data.ia_net = ia->ia_net; 1022 in_event_data.ia_netmask = ia->ia_netmask; 1023 in_event_data.ia_subnet = ia->ia_subnet; 1024 in_event_data.ia_subnetmask = ia->ia_subnetmask; 1025 in_event_data.ia_netbroadcast = ia->ia_netbroadcast; 1026 IFA_UNLOCK(&ia->ia_ifa); 1027 (void) strncpy(&in_event_data.link_data.if_name[0], 1028 ifp->if_name, IFNAMSIZ); 1029 in_event_data.link_data.if_family = ifp->if_family; 1030 in_event_data.link_data.if_unit = ifp->if_unit; 1031 1032 ev_msg.dv[0].data_ptr = &in_event_data; 1033 ev_msg.dv[0].data_length = sizeof (struct kev_in_data); 1034 ev_msg.dv[1].data_length = 0; 1035 1036 kev_post_msg(&ev_msg); 1037 } else { 1038 IFA_UNLOCK(&ia->ia_ifa); 1039 } 1040 break; 1041 } 1042 1043 case SIOCDIFADDR: /* struct ifreq */ 1044 VERIFY(ifp != NULL && ia != NULL); 1045 error = ifnet_ioctl(ifp, PF_INET, SIOCDIFADDR, ia); 1046 if (error == EOPNOTSUPP) 1047 error = 0; 1048 if (error != 0) { 1049 break; 1050 } 1051 1052 /* Fill out the kernel event information */ 1053 ev_msg.vendor_code = KEV_VENDOR_APPLE; 1054 ev_msg.kev_class = KEV_NETWORK_CLASS; 1055 ev_msg.kev_subclass = KEV_INET_SUBCLASS; 1056 1057 ev_msg.event_code = KEV_INET_ADDR_DELETED; 1058 1059 IFA_LOCK(&ia->ia_ifa); 1060 if (ia->ia_ifa.ifa_dstaddr) { 1061 in_event_data.ia_dstaddr = ((struct sockaddr_in *) 1062 (void *)ia->ia_ifa.ifa_dstaddr)->sin_addr; 1063 } else { 1064 in_event_data.ia_dstaddr.s_addr = INADDR_ANY; 1065 } 1066 in_event_data.ia_addr = ia->ia_addr.sin_addr; 1067 in_event_data.ia_net = ia->ia_net; 1068 in_event_data.ia_netmask = ia->ia_netmask; 1069 in_event_data.ia_subnet = ia->ia_subnet; 1070 in_event_data.ia_subnetmask = ia->ia_subnetmask; 1071 in_event_data.ia_netbroadcast = ia->ia_netbroadcast; 1072 IFA_UNLOCK(&ia->ia_ifa); 1073 (void) strncpy(&in_event_data.link_data.if_name[0], 1074 ifp->if_name, IFNAMSIZ); 1075 in_event_data.link_data.if_family = ifp->if_family; 1076 in_event_data.link_data.if_unit = (u_int32_t) ifp->if_unit; 1077 1078 ev_msg.dv[0].data_ptr = &in_event_data; 1079 ev_msg.dv[0].data_length = sizeof(struct kev_in_data); 1080 ev_msg.dv[1].data_length = 0; 1081 1082 ifa = &ia->ia_ifa; 1083 lck_rw_lock_exclusive(in_ifaddr_rwlock); 1084 /* Release ia_link reference */ 1085 IFA_REMREF(ifa); 1086 TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link); 1087 IFA_LOCK(ifa); 1088 if (IA_IS_HASHED(ia)) 1089 in_iahash_remove(ia); 1090 IFA_UNLOCK(ifa); 1091 lck_rw_done(in_ifaddr_rwlock); 1092 1093 /* 1094 * in_ifscrub kills the interface route. 1095 */ 1096 in_ifscrub(ifp, ia, 0); 1097 ifnet_lock_exclusive(ifp); 1098 IFA_LOCK(ifa); 1099 /* if_detach_ifa() releases ifa_link reference */ 1100 if_detach_ifa(ifp, ifa); 1101 /* Our reference to this address is dropped at the bottom */ 1102 IFA_UNLOCK(ifa); 1103 1104 /* 1105 * If the interface supports multicast, and no address is left, 1106 * remove the "all hosts" multicast group from that interface. 1107 */ 1108 if ((ifp->if_flags & IFF_MULTICAST) != 0 || 1109 ifp->if_allhostsinm != NULL ) { 1110 1111 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 1112 IFA_LOCK(ifa); 1113 if (ifa->ifa_addr->sa_family == AF_INET) { 1114 IFA_UNLOCK(ifa); 1115 break; 1116 } 1117 IFA_UNLOCK(ifa); 1118 } 1119 ifnet_lock_done(ifp); 1120 1121 lck_mtx_lock(&ifp->if_addrconfig_lock); 1122 if (ifa == NULL && ifp->if_allhostsinm != NULL) { 1123 struct in_multi *inm = ifp->if_allhostsinm; 1124 ifp->if_allhostsinm = NULL; 1125 1126 in_delmulti(inm); 1127 /* release the reference for allhostsinm */ 1128 INM_REMREF(inm); 1129 } 1130 lck_mtx_unlock(&ifp->if_addrconfig_lock); 1131 } else { 1132 ifnet_lock_done(ifp); 1133 } 1134 1135 /* Post the kernel event */ 1136 kev_post_msg(&ev_msg); 1137 1138 /* 1139 * See if there is any IPV4 address left and if so, 1140 * reconfigure KDP to use current primary address. 1141 */ 1142 ifa = ifa_ifpgetprimary(ifp, AF_INET); 1143 if (ifa != NULL) { 1144 /* 1145 * NOTE: SIOCSIFADDR is defined with struct ifreq 1146 * as parameter, but here we are sending it down 1147 * to the interface with a pointer to struct ifaddr, 1148 * for legacy reasons. 1149 */ 1150 error = ifnet_ioctl(ifp, PF_INET, SIOCSIFADDR, ifa); 1151 if (error == EOPNOTSUPP) 1152 error = 0; 1153 1154 /* Release reference from ifa_ifpgetprimary() */ 1155 IFA_REMREF(ifa); 1156 } 1157#if PF 1158 (void) pf_ifaddr_hook(ifp, cmd); 1159#endif /* PF */ 1160 break; 1161 1162#ifdef __APPLE__ 1163 case SIOCSETOT: { /* int */ 1164 /* 1165 * Inspiration from tcp_ctloutput() and ip_ctloutput() 1166 * Special ioctl for OpenTransport sockets 1167 */ 1168 struct inpcb *inp, *cloned_inp; 1169 int error2 = 0; 1170 int cloned_fd; 1171 1172 bcopy(data, &cloned_fd, sizeof (cloned_fd)); 1173 1174 inp = sotoinpcb(so); 1175 if (inp == NULL) { 1176 break; 1177 } 1178 1179 /* let's make sure it's either -1 or a valid file descriptor */ 1180 if (cloned_fd != -1) { 1181 struct socket *cloned_so; 1182 error2 = file_socket(cloned_fd, &cloned_so); 1183 if (error2) { 1184 break; 1185 } 1186 cloned_inp = sotoinpcb(cloned_so); 1187 file_drop(cloned_fd); 1188 } else { 1189 cloned_inp = NULL; 1190 } 1191 1192 if (cloned_inp == NULL) { 1193 /* OT always uses IP_PORTRANGE_HIGH */ 1194 inp->inp_flags &= ~(INP_LOWPORT); 1195 inp->inp_flags |= INP_HIGHPORT; 1196 /* 1197 * For UDP, OT allows broadcast by default; 1198 * for TCP we want to see MSG_OOB when we 1199 * receive urgent data. 1200 */ 1201 if (so->so_type == SOCK_DGRAM) 1202 so->so_options |= SO_BROADCAST; 1203 else if (so->so_type == SOCK_STREAM) 1204 so->so_options |= SO_WANTOOBFLAG; 1205 } else { 1206 inp->inp_ip_tos = cloned_inp->inp_ip_tos; 1207 inp->inp_ip_ttl = cloned_inp->inp_ip_ttl; 1208 inp->inp_flags = cloned_inp->inp_flags; 1209 1210 /* Multicast options */ 1211 if (cloned_inp->inp_moptions != NULL) 1212 error2 = imo_clone(cloned_inp, inp); 1213 } 1214 break; 1215 } 1216#endif /* __APPLE__ */ 1217 1218 default: 1219 error = EOPNOTSUPP; 1220 } 1221 done: 1222 if (ia != NULL) { 1223 IFA_REMREF(&ia->ia_ifa); 1224 } 1225 return (error); 1226} 1227 1228/* 1229 * SIOC[GAD]LIFADDR. 1230 * SIOCGLIFADDR: get first address. (?!?) 1231 * SIOCGLIFADDR with IFLR_PREFIX: 1232 * get first address that matches the specified prefix. 1233 * SIOCALIFADDR: add the specified address. 1234 * SIOCALIFADDR with IFLR_PREFIX: 1235 * EINVAL since we can't deduce hostid part of the address. 1236 * SIOCDLIFADDR: delete the specified address. 1237 * SIOCDLIFADDR with IFLR_PREFIX: 1238 * delete the first address that matches the specified prefix. 1239 * return values: 1240 * EINVAL on invalid parameters 1241 * EADDRNOTAVAIL on prefix match failed/specified address not found 1242 * other values may be returned from in_ioctl() 1243 */ 1244static int 1245in_lifaddr_ioctl(struct socket *so, u_long cmd, struct if_laddrreq *iflr, 1246 struct ifnet *ifp, struct proc *p) 1247{ 1248 struct ifaddr *ifa; 1249 1250 VERIFY(ifp != NULL); 1251 1252 switch (cmd) { 1253 case SIOCGLIFADDR: 1254 /* address must be specified on GET with IFLR_PREFIX */ 1255 if ((iflr->flags & IFLR_PREFIX) == 0) 1256 break; 1257 /*FALLTHROUGH*/ 1258 case SIOCALIFADDR: 1259 case SIOCDLIFADDR: 1260 /* address must be specified on ADD and DELETE */ 1261 if (iflr->addr.ss_family != AF_INET) 1262 return EINVAL; 1263 if (iflr->addr.ss_len != sizeof(struct sockaddr_in)) 1264 return EINVAL; 1265 /* XXX need improvement */ 1266 if (iflr->dstaddr.ss_family 1267 && iflr->dstaddr.ss_family != AF_INET) 1268 return EINVAL; 1269 if (iflr->dstaddr.ss_family 1270 && iflr->dstaddr.ss_len != sizeof(struct sockaddr_in)) 1271 return EINVAL; 1272 break; 1273 default: /*shouldn't happen*/ 1274 return EOPNOTSUPP; 1275 } 1276 if (sizeof(struct in_addr) * 8 < iflr->prefixlen) 1277 return EINVAL; 1278 1279 switch (cmd) { 1280 case SIOCALIFADDR: 1281 { 1282 struct in_aliasreq ifra; 1283 1284 if (iflr->flags & IFLR_PREFIX) 1285 return EINVAL; 1286 1287 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */ 1288 bzero(&ifra, sizeof(ifra)); 1289 bcopy(iflr->iflr_name, ifra.ifra_name, 1290 sizeof(ifra.ifra_name)); 1291 1292 bcopy(&iflr->addr, &ifra.ifra_addr, iflr->addr.ss_len); 1293 1294 if (iflr->dstaddr.ss_family) { /*XXX*/ 1295 bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr, 1296 iflr->dstaddr.ss_len); 1297 } 1298 1299 ifra.ifra_mask.sin_family = AF_INET; 1300 ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in); 1301 in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen); 1302 1303 return in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp, p); 1304 } 1305 case SIOCGLIFADDR: 1306 case SIOCDLIFADDR: 1307 { 1308 struct in_ifaddr *ia; 1309 struct in_addr mask, candidate; 1310 struct in_addr match = { 0 }; 1311 struct sockaddr_in *sin; 1312 int cmp; 1313 1314 bzero(&mask, sizeof(mask)); 1315 if (iflr->flags & IFLR_PREFIX) { 1316 /* lookup a prefix rather than address. */ 1317 in_len2mask(&mask, iflr->prefixlen); 1318 1319 sin = (struct sockaddr_in *)&iflr->addr; 1320 match.s_addr = sin->sin_addr.s_addr; 1321 match.s_addr &= mask.s_addr; 1322 1323 /* if you set extra bits, that's wrong */ 1324 if (match.s_addr != sin->sin_addr.s_addr) 1325 return EINVAL; 1326 1327 cmp = 1; 1328 } else { 1329 if (cmd == SIOCGLIFADDR) { 1330 /* on getting an address, take the 1st match */ 1331 cmp = 0; /*XXX*/ 1332 } else { 1333 /* on deleting an address, do exact match */ 1334 in_len2mask(&mask, 32); 1335 sin = (struct sockaddr_in *)&iflr->addr; 1336 match.s_addr = sin->sin_addr.s_addr; 1337 1338 cmp = 1; 1339 } 1340 } 1341 1342 ifnet_lock_shared(ifp); 1343 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 1344 IFA_LOCK(ifa); 1345 if (ifa->ifa_addr->sa_family != AF_INET6) { 1346 IFA_UNLOCK(ifa); 1347 continue; 1348 } 1349 if (!cmp) { 1350 IFA_UNLOCK(ifa); 1351 break; 1352 } 1353 candidate.s_addr = ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr; 1354 candidate.s_addr &= mask.s_addr; 1355 IFA_UNLOCK(ifa); 1356 if (candidate.s_addr == match.s_addr) 1357 break; 1358 } 1359 if (ifa != NULL) 1360 IFA_ADDREF(ifa); 1361 ifnet_lock_done(ifp); 1362 if (!ifa) 1363 return EADDRNOTAVAIL; 1364 ia = (struct in_ifaddr *)ifa; 1365 1366 if (cmd == SIOCGLIFADDR) { 1367 IFA_LOCK(ifa); 1368 /* fill in the if_laddrreq structure */ 1369 bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len); 1370 1371 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { 1372 bcopy(&ia->ia_dstaddr, &iflr->dstaddr, 1373 ia->ia_dstaddr.sin_len); 1374 } else 1375 bzero(&iflr->dstaddr, sizeof(iflr->dstaddr)); 1376 1377 iflr->prefixlen = 1378 in_mask2len(&ia->ia_sockmask.sin_addr); 1379 1380 iflr->flags = 0; /*XXX*/ 1381 1382 IFA_UNLOCK(ifa); 1383 IFA_REMREF(ifa); 1384 return 0; 1385 } else { 1386 struct in_aliasreq ifra; 1387 1388 /* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */ 1389 bzero(&ifra, sizeof(ifra)); 1390 bcopy(iflr->iflr_name, ifra.ifra_name, 1391 sizeof(ifra.ifra_name)); 1392 1393 IFA_LOCK(ifa); 1394 bcopy(&ia->ia_addr, &ifra.ifra_addr, 1395 ia->ia_addr.sin_len); 1396 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { 1397 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr, 1398 ia->ia_dstaddr.sin_len); 1399 } 1400 bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr, 1401 ia->ia_sockmask.sin_len); 1402 IFA_UNLOCK(ifa); 1403 IFA_REMREF(ifa); 1404 return in_control(so, SIOCDIFADDR, (caddr_t)&ifra, 1405 ifp, p); 1406 } 1407 } 1408 } 1409 1410 return EOPNOTSUPP; /*just for safety*/ 1411} 1412 1413/* 1414 * Handle SIOCSETROUTERMODE to set or clear the IPv4 router mode flag on 1415 * the interface. When in this mode, IPv4 Link-Local Address support is 1416 * disabled in ARP, and DHCP client support is disabled in IP input; turning 1417 * any of them on would cause an error to be returned. Entering or exiting 1418 * this mode will result in the removal of IPv4 addresses currently configured 1419 * on the interface. 1420 */ 1421static int 1422in_setrouter(struct ifnet *ifp, int enable) 1423{ 1424 if (ifp->if_flags & IFF_LOOPBACK) 1425 return (ENODEV); 1426 1427 ifnet_lock_exclusive(ifp); 1428 if (enable) { 1429 ifp->if_eflags |= IFEF_IPV4_ROUTER; 1430 ifp->if_eflags &= ~(IFEF_ARPLL | IFEF_AUTOCONFIGURING); 1431 } else { 1432 ifp->if_eflags &= ~IFEF_IPV4_ROUTER; 1433 } 1434 ifnet_lock_done(ifp); 1435 1436 /* purge all IPv4 addresses configured on this interface */ 1437 in_purgeaddrs(ifp); 1438 1439 return (0); 1440} 1441 1442/* 1443 * Delete any existing route for an interface. 1444 */ 1445void 1446in_ifscrub(struct ifnet *ifp, struct in_ifaddr *ia, int locked) 1447{ 1448 IFA_LOCK(&ia->ia_ifa); 1449 if ((ia->ia_flags & IFA_ROUTE) == 0) { 1450 IFA_UNLOCK(&ia->ia_ifa); 1451 return; 1452 } 1453 IFA_UNLOCK(&ia->ia_ifa); 1454 if (!locked) 1455 lck_mtx_lock(rnh_lock); 1456 if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) 1457 rtinit_locked(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 1458 else 1459 rtinit_locked(&(ia->ia_ifa), (int)RTM_DELETE, 0); 1460 IFA_LOCK(&ia->ia_ifa); 1461 ia->ia_flags &= ~IFA_ROUTE; 1462 IFA_UNLOCK(&ia->ia_ifa); 1463 if (!locked) 1464 lck_mtx_unlock(rnh_lock); 1465} 1466 1467/* 1468 * Caller must hold in_ifaddr_rwlock as writer. 1469 */ 1470static void 1471in_iahash_remove(struct in_ifaddr *ia) 1472{ 1473 lck_rw_assert(in_ifaddr_rwlock, LCK_RW_ASSERT_EXCLUSIVE); 1474 IFA_LOCK_ASSERT_HELD(&ia->ia_ifa); 1475 1476 if (!IA_IS_HASHED(ia)) { 1477 panic("attempt to remove wrong ia %p from hash table\n", ia); 1478 /* NOTREACHED */ 1479 } 1480 TAILQ_REMOVE(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash); 1481 IA_HASH_INIT(ia); 1482 if (IFA_REMREF_LOCKED(&ia->ia_ifa) == NULL) { 1483 panic("%s: unexpected (missing) refcnt ifa=%p", __func__, 1484 &ia->ia_ifa); 1485 /* NOTREACHED */ 1486 } 1487} 1488 1489/* 1490 * Caller must hold in_ifaddr_rwlock as writer. 1491 */ 1492static void 1493in_iahash_insert(struct in_ifaddr *ia) 1494{ 1495 lck_rw_assert(in_ifaddr_rwlock, LCK_RW_ASSERT_EXCLUSIVE); 1496 IFA_LOCK_ASSERT_HELD(&ia->ia_ifa); 1497 1498 if (ia->ia_addr.sin_family != AF_INET) { 1499 panic("attempt to insert wrong ia %p into hash table\n", ia); 1500 /* NOTREACHED */ 1501 } else if (IA_IS_HASHED(ia)) { 1502 panic("attempt to double-insert ia %p into hash table\n", ia); 1503 /* NOTREACHED */ 1504 } 1505 TAILQ_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash); 1506 IFA_ADDREF_LOCKED(&ia->ia_ifa); 1507} 1508 1509/* 1510 * Some point to point interfaces that are tunnels 1511 * borrow the address from an underlying interface (e.g. 1512 * VPN server). In order for source address selection logic to 1513 * find the underlying interface first, we add the address 1514 * of borrowing point to point interfaces at the end of the list. 1515 * (see rdar://6733789) 1516 * 1517 * Caller must hold in_ifaddr_rwlock as writer. 1518 */ 1519static void 1520in_iahash_insert_ptp(struct in_ifaddr *ia) 1521{ 1522 struct in_ifaddr *tmp_ifa; 1523 struct ifnet *tmp_ifp; 1524 1525 lck_rw_assert(in_ifaddr_rwlock, LCK_RW_ASSERT_EXCLUSIVE); 1526 IFA_LOCK_ASSERT_HELD(&ia->ia_ifa); 1527 1528 if (ia->ia_addr.sin_family != AF_INET) { 1529 panic("attempt to insert wrong ia %p into hash table\n", ia); 1530 /* NOTREACHED */ 1531 } else if (IA_IS_HASHED(ia)) { 1532 panic("attempt to double-insert ia %p into hash table\n", ia); 1533 /* NOTREACHED */ 1534 } 1535 IFA_UNLOCK(&ia->ia_ifa); 1536 TAILQ_FOREACH(tmp_ifa, INADDR_HASH(ia->ia_addr.sin_addr.s_addr), 1537 ia_hash) { 1538 IFA_LOCK(&tmp_ifa->ia_ifa); 1539 /* ia->ia_addr won't change, so check without lock */ 1540 if (IA_SIN(tmp_ifa)->sin_addr.s_addr == 1541 ia->ia_addr.sin_addr.s_addr) { 1542 IFA_UNLOCK(&tmp_ifa->ia_ifa); 1543 break; 1544 } 1545 IFA_UNLOCK(&tmp_ifa->ia_ifa); 1546 } 1547 tmp_ifp = (tmp_ifa == NULL) ? NULL : tmp_ifa->ia_ifp; 1548 1549 IFA_LOCK(&ia->ia_ifa); 1550 if (tmp_ifp == NULL) { 1551 TAILQ_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), 1552 ia, ia_hash); 1553 } else { 1554 TAILQ_INSERT_TAIL(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), 1555 ia, ia_hash); 1556 } 1557 IFA_ADDREF_LOCKED(&ia->ia_ifa); 1558} 1559 1560/* 1561 * Initialize an interface's internet address 1562 * and routing table entry. 1563 */ 1564static int 1565in_ifinit( 1566 struct ifnet *ifp, 1567 struct in_ifaddr *ia, 1568 struct sockaddr_in *sin, 1569 int scrub) 1570{ 1571 u_int32_t i = ntohl(sin->sin_addr.s_addr); 1572 struct sockaddr_in oldaddr; 1573 int flags = RTF_UP, error; 1574 struct ifaddr *ifa0; 1575 unsigned int cmd; 1576 int oldremoved = 0; 1577 1578 /* Take an extra reference for this routine */ 1579 IFA_ADDREF(&ia->ia_ifa); 1580 1581 lck_rw_lock_exclusive(in_ifaddr_rwlock); 1582 IFA_LOCK(&ia->ia_ifa); 1583 oldaddr = ia->ia_addr; 1584 if (IA_IS_HASHED(ia)) { 1585 oldremoved = 1; 1586 in_iahash_remove(ia); 1587 } 1588 ia->ia_addr = *sin; 1589 ia->ia_addr.sin_len = sizeof (*sin); 1590 if ((ifp->if_flags & IFF_POINTOPOINT)) 1591 in_iahash_insert_ptp(ia); 1592 else 1593 in_iahash_insert(ia); 1594 IFA_UNLOCK(&ia->ia_ifa); 1595 lck_rw_done(in_ifaddr_rwlock); 1596 1597 /* 1598 * Give the interface a chance to initialize if this is its first 1599 * address, and to validate the address if necessary. Send down 1600 * SIOCSIFADDR for first address, and SIOCAIFADDR for alias(es). 1601 * We find the first IPV4 address assigned to it and check if this 1602 * is the same as the one passed into this routine. 1603 */ 1604 ifa0 = ifa_ifpgetprimary(ifp, AF_INET); 1605 cmd = (&ia->ia_ifa == ifa0) ? SIOCSIFADDR : SIOCAIFADDR; 1606 error = ifnet_ioctl(ifp, PF_INET, cmd, ia); 1607 if (error == EOPNOTSUPP) 1608 error = 0; 1609 /* 1610 * If we've just sent down SIOCAIFADDR, send another ioctl down 1611 * for SIOCSIFADDR for the first IPV4 address of the interface, 1612 * because an address change on one of the addresses will result 1613 * in the removal of the previous first IPV4 address. KDP needs 1614 * be reconfigured with the current primary IPV4 address. 1615 */ 1616 if (error == 0 && cmd == SIOCAIFADDR) { 1617 /* 1618 * NOTE: SIOCSIFADDR is defined with struct ifreq 1619 * as parameter, but here we are sending it down 1620 * to the interface with a pointer to struct ifaddr, 1621 * for legacy reasons. 1622 */ 1623 error = ifnet_ioctl(ifp, PF_INET, SIOCSIFADDR, ifa0); 1624 if (error == EOPNOTSUPP) 1625 error = 0; 1626 } 1627 1628 /* Release reference from ifa_ifpgetprimary() */ 1629 IFA_REMREF(ifa0); 1630 1631 if (error) { 1632 lck_rw_lock_exclusive(in_ifaddr_rwlock); 1633 IFA_LOCK(&ia->ia_ifa); 1634 if (IA_IS_HASHED(ia)) 1635 in_iahash_remove(ia); 1636 ia->ia_addr = oldaddr; 1637 if (oldremoved) { 1638 if ((ifp->if_flags & IFF_POINTOPOINT)) 1639 in_iahash_insert_ptp(ia); 1640 else 1641 in_iahash_insert(ia); 1642 } 1643 IFA_UNLOCK(&ia->ia_ifa); 1644 lck_rw_done(in_ifaddr_rwlock); 1645 /* Release extra reference taken above */ 1646 IFA_REMREF(&ia->ia_ifa); 1647 return (error); 1648 } 1649 lck_mtx_lock(rnh_lock); 1650 IFA_LOCK(&ia->ia_ifa); 1651 /* 1652 * Address has been initialized by the link resolver (ARP) 1653 * via ifnet_ioctl() above; it may now generate route(s). 1654 */ 1655 ia->ia_ifa.ifa_debug &= ~IFD_NOTREADY; 1656 if (scrub) { 1657 ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr; 1658 IFA_UNLOCK(&ia->ia_ifa); 1659 in_ifscrub(ifp, ia, 1); 1660 IFA_LOCK(&ia->ia_ifa); 1661 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 1662 } 1663 IFA_LOCK_ASSERT_HELD(&ia->ia_ifa); 1664 if (IN_CLASSA(i)) 1665 ia->ia_netmask = IN_CLASSA_NET; 1666 else if (IN_CLASSB(i)) 1667 ia->ia_netmask = IN_CLASSB_NET; 1668 else 1669 ia->ia_netmask = IN_CLASSC_NET; 1670 /* 1671 * The subnet mask usually includes at least the standard network part, 1672 * but may may be smaller in the case of supernetting. 1673 * If it is set, we believe it. 1674 */ 1675 if (ia->ia_subnetmask == 0) { 1676 ia->ia_subnetmask = ia->ia_netmask; 1677 ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask); 1678 } else 1679 ia->ia_netmask &= ia->ia_subnetmask; 1680 ia->ia_net = i & ia->ia_netmask; 1681 ia->ia_subnet = i & ia->ia_subnetmask; 1682 in_socktrim(&ia->ia_sockmask); 1683 /* 1684 * Add route for the network. 1685 */ 1686 ia->ia_ifa.ifa_metric = ifp->if_metric; 1687 if (ifp->if_flags & IFF_BROADCAST) { 1688 ia->ia_broadaddr.sin_addr.s_addr = 1689 htonl(ia->ia_subnet | ~ia->ia_subnetmask); 1690 ia->ia_netbroadcast.s_addr = 1691 htonl(ia->ia_net | ~ ia->ia_netmask); 1692 } else if (ifp->if_flags & IFF_LOOPBACK) { 1693 ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr; 1694 flags |= RTF_HOST; 1695 } else if (ifp->if_flags & IFF_POINTOPOINT) { 1696 if (ia->ia_dstaddr.sin_family != AF_INET) { 1697 IFA_UNLOCK(&ia->ia_ifa); 1698 lck_mtx_unlock(rnh_lock); 1699 /* Release extra reference taken above */ 1700 IFA_REMREF(&ia->ia_ifa); 1701 return (0); 1702 } 1703 ia->ia_dstaddr.sin_len = sizeof (*sin); 1704 flags |= RTF_HOST; 1705 } 1706 IFA_UNLOCK(&ia->ia_ifa); 1707 if ((error = rtinit_locked(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0) { 1708 IFA_LOCK(&ia->ia_ifa); 1709 ia->ia_flags |= IFA_ROUTE; 1710 IFA_UNLOCK(&ia->ia_ifa); 1711 } 1712 lck_mtx_unlock(rnh_lock); 1713 1714 /* XXX check if the subnet route points to the same interface */ 1715 if (error == EEXIST) 1716 error = 0; 1717 1718 /* 1719 * If the interface supports multicast, join the "all hosts" 1720 * multicast group on that interface. 1721 */ 1722 if (ifp->if_flags & IFF_MULTICAST) { 1723 struct in_addr addr; 1724 1725 lck_mtx_lock(&ifp->if_addrconfig_lock); 1726 addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP); 1727 if (ifp->if_allhostsinm == NULL) { 1728 struct in_multi *inm; 1729 inm = in_addmulti(&addr, ifp); 1730 1731 if (inm != NULL) { 1732 /* keep the reference on inm added by 1733 * in_addmulti above for storing the 1734 * pointer in allhostsinm 1735 */ 1736 ifp->if_allhostsinm = inm; 1737 } else { 1738 printf("Failed to add membership to all-hosts multicast address on interface %s%d\n", ifp->if_name, ifp->if_unit); 1739 } 1740 } 1741 lck_mtx_unlock(&ifp->if_addrconfig_lock); 1742 } 1743 1744 /* Release extra reference taken above */ 1745 IFA_REMREF(&ia->ia_ifa); 1746 return (error); 1747} 1748 1749 1750/* 1751 * Return 1 if the address might be a local broadcast address. 1752 */ 1753int 1754in_broadcast(struct in_addr in, struct ifnet *ifp) 1755{ 1756 struct ifaddr *ifa; 1757 u_int32_t t; 1758 1759 if (in.s_addr == INADDR_BROADCAST || in.s_addr == INADDR_ANY) 1760 return (1); 1761 if ((ifp->if_flags & IFF_BROADCAST) == 0) 1762 return (0); 1763 t = ntohl(in.s_addr); 1764 /* 1765 * Look through the list of addresses for a match 1766 * with a broadcast address. 1767 */ 1768#define ia ((struct in_ifaddr *)ifa) 1769 ifnet_lock_shared(ifp); 1770 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 1771 IFA_LOCK(ifa); 1772 if (ifa->ifa_addr->sa_family == AF_INET && 1773 (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr || 1774 in.s_addr == ia->ia_netbroadcast.s_addr || 1775 /* 1776 * Check for old-style (host 0) broadcast. 1777 */ 1778 t == ia->ia_subnet || t == ia->ia_net) && 1779 /* 1780 * Check for an all one subnetmask. These 1781 * only exist when an interface gets a secondary 1782 * address. 1783 */ 1784 ia->ia_subnetmask != (u_int32_t)0xffffffff) { 1785 IFA_UNLOCK(ifa); 1786 ifnet_lock_done(ifp); 1787 return (1); 1788 } 1789 IFA_UNLOCK(ifa); 1790 } 1791 ifnet_lock_done(ifp); 1792 return (0); 1793#undef ia 1794} 1795 1796void 1797in_purgeaddrs(struct ifnet *ifp) 1798{ 1799 struct ifaddr **ifap; 1800 int err, i; 1801 1802 /* 1803 * Be nice, and try the civilized way first. If we can't get 1804 * rid of them this way, then do it the rough way. We must 1805 * only get here during detach time, after the ifnet has been 1806 * removed from the global list and arrays. 1807 */ 1808 err = ifnet_get_address_list_family_internal(ifp, &ifap, AF_INET, 1, 1809 M_WAITOK); 1810 if (err == 0 && ifap != NULL) { 1811 for (i = 0; ifap[i] != NULL; i++) { 1812 struct ifaliasreq ifr; 1813 struct ifaddr *ifa; 1814 1815 ifa = ifap[i]; 1816 bzero(&ifr, sizeof (ifr)); 1817 IFA_LOCK(ifa); 1818 ifr.ifra_addr = *ifa->ifa_addr; 1819 if (ifa->ifa_dstaddr != NULL) 1820 ifr.ifra_broadaddr = *ifa->ifa_dstaddr; 1821 IFA_UNLOCK(ifa); 1822 err = in_control(NULL, SIOCDIFADDR, (caddr_t)&ifr, ifp, 1823 kernproc); 1824 /* if we lost the race, ignore it */ 1825 if (err == EADDRNOTAVAIL) 1826 err = 0; 1827 if (err != 0) { 1828 char s_addr[MAX_IPv4_STR_LEN]; 1829 char s_dstaddr[MAX_IPv4_STR_LEN]; 1830 struct in_addr *s, *d; 1831 1832 IFA_LOCK(ifa); 1833 s = &((struct sockaddr_in *) 1834 (void *)ifa->ifa_addr)->sin_addr; 1835 d = &((struct sockaddr_in *) 1836 (void *)ifa->ifa_dstaddr)->sin_addr; 1837 (void) inet_ntop(AF_INET, &s->s_addr, s_addr, 1838 sizeof (s_addr)); 1839 (void) inet_ntop(AF_INET, &d->s_addr, s_dstaddr, 1840 sizeof (s_dstaddr)); 1841 IFA_UNLOCK(ifa); 1842 1843 printf("%s: SIOCDIFADDR ifp=%p ifa_addr=%s " 1844 "ifa_dstaddr=%s (err=%d)\n", __func__, ifp, 1845 s_addr, s_dstaddr, err); 1846 } 1847 } 1848 ifnet_free_address_list(ifap); 1849 } else if (err != 0 && err != ENXIO) { 1850 printf("%s: error retrieving list of AF_INET addresses for " 1851 "ifp=%p (err=%d)\n", __func__, ifp, err); 1852 } 1853} 1854 1855int inet_aton(char *cp, struct in_addr *pin); 1856int 1857inet_aton(char * cp, struct in_addr * pin) 1858{ 1859 u_char * b = (unsigned char *)pin; 1860 int i; 1861 char * p; 1862 1863 for (p = cp, i = 0; i < 4; i++) { 1864 u_int32_t l = strtoul(p, 0, 0); 1865 if (l > 255) 1866 return (FALSE); 1867 b[i] = l; 1868 p = strchr(p, '.'); 1869 if (i < 3 && p == NULL) 1870 return (FALSE); 1871 p++; 1872 } 1873 return (TRUE); 1874} 1875 1876int inet_ntoa2(struct in_addr * pin, char * cp, const int len); 1877int inet_ntoa2(struct in_addr * pin, char * cp, const int len) 1878{ 1879 int ret; 1880 1881 /* address is in network byte order */ 1882 ret = snprintf(cp, len, "%u.%u.%u.%u", pin->s_addr & 0xFF, 1883 (pin->s_addr >> 8) & 0xFF, (pin->s_addr >> 16) & 0xFF, 1884 (pin->s_addr >> 24) & 0xFF); 1885 1886 return ret < len ? TRUE : FALSE; 1887} 1888 1889/* 1890 * Called as part of ip_init 1891 */ 1892void 1893in_ifaddr_init(void) 1894{ 1895 in_multi_init(); 1896 1897 PE_parse_boot_argn("ifa_debug", &inifa_debug, sizeof (inifa_debug)); 1898 1899 inifa_size = (inifa_debug == 0) ? sizeof (struct in_ifaddr) : 1900 sizeof (struct in_ifaddr_dbg); 1901 1902 inifa_zone = zinit(inifa_size, INIFA_ZONE_MAX * inifa_size, 1903 0, INIFA_ZONE_NAME); 1904 if (inifa_zone == NULL) { 1905 panic("%s: failed allocating %s", __func__, INIFA_ZONE_NAME); 1906 /* NOTREACHED */ 1907 } 1908 zone_change(inifa_zone, Z_EXPAND, TRUE); 1909 zone_change(inifa_zone, Z_CALLERACCT, FALSE); 1910 1911 lck_mtx_init(&inifa_trash_lock, ifa_mtx_grp, ifa_mtx_attr); 1912 TAILQ_INIT(&inifa_trash_head); 1913} 1914 1915static struct in_ifaddr * 1916in_ifaddr_alloc(int how) 1917{ 1918 struct in_ifaddr *inifa; 1919 1920 inifa = (how == M_WAITOK) ? zalloc(inifa_zone) : 1921 zalloc_noblock(inifa_zone); 1922 if (inifa != NULL) { 1923 bzero(inifa, inifa_size); 1924 inifa->ia_ifa.ifa_free = in_ifaddr_free; 1925 inifa->ia_ifa.ifa_debug |= IFD_ALLOC; 1926 ifa_lock_init(&inifa->ia_ifa); 1927 if (inifa_debug != 0) { 1928 struct in_ifaddr_dbg *inifa_dbg = 1929 (struct in_ifaddr_dbg *)inifa; 1930 inifa->ia_ifa.ifa_debug |= IFD_DEBUG; 1931 inifa->ia_ifa.ifa_trace = in_ifaddr_trace; 1932 inifa->ia_ifa.ifa_attached = in_ifaddr_attached; 1933 inifa->ia_ifa.ifa_detached = in_ifaddr_detached; 1934 ctrace_record(&inifa_dbg->inifa_alloc); 1935 } 1936 } 1937 return (inifa); 1938} 1939 1940static void 1941in_ifaddr_free(struct ifaddr *ifa) 1942{ 1943 IFA_LOCK_ASSERT_HELD(ifa); 1944 1945 if (ifa->ifa_refcnt != 0) { 1946 panic("%s: ifa %p bad ref cnt", __func__, ifa); 1947 /* NOTREACHED */ 1948 } if (!(ifa->ifa_debug & IFD_ALLOC)) { 1949 panic("%s: ifa %p cannot be freed", __func__, ifa); 1950 /* NOTREACHED */ 1951 } 1952 if (ifa->ifa_debug & IFD_DEBUG) { 1953 struct in_ifaddr_dbg *inifa_dbg = (struct in_ifaddr_dbg *)ifa; 1954 ctrace_record(&inifa_dbg->inifa_free); 1955 bcopy(&inifa_dbg->inifa, &inifa_dbg->inifa_old, 1956 sizeof (struct in_ifaddr)); 1957 if (ifa->ifa_debug & IFD_TRASHED) { 1958 /* Become a regular mutex, just in case */ 1959 IFA_CONVERT_LOCK(ifa); 1960 lck_mtx_lock(&inifa_trash_lock); 1961 TAILQ_REMOVE(&inifa_trash_head, inifa_dbg, 1962 inifa_trash_link); 1963 lck_mtx_unlock(&inifa_trash_lock); 1964 ifa->ifa_debug &= ~IFD_TRASHED; 1965 } 1966 } 1967 IFA_UNLOCK(ifa); 1968 ifa_lock_destroy(ifa); 1969 bzero(ifa, sizeof (struct in_ifaddr)); 1970 zfree(inifa_zone, ifa); 1971} 1972 1973static void 1974in_ifaddr_attached(struct ifaddr *ifa) 1975{ 1976 struct in_ifaddr_dbg *inifa_dbg = (struct in_ifaddr_dbg *)ifa; 1977 1978 IFA_LOCK_ASSERT_HELD(ifa); 1979 1980 if (!(ifa->ifa_debug & IFD_DEBUG)) { 1981 panic("%s: ifa %p has no debug structure", __func__, ifa); 1982 /* NOTREACHED */ 1983 } 1984 if (ifa->ifa_debug & IFD_TRASHED) { 1985 /* Become a regular mutex, just in case */ 1986 IFA_CONVERT_LOCK(ifa); 1987 lck_mtx_lock(&inifa_trash_lock); 1988 TAILQ_REMOVE(&inifa_trash_head, inifa_dbg, inifa_trash_link); 1989 lck_mtx_unlock(&inifa_trash_lock); 1990 ifa->ifa_debug &= ~IFD_TRASHED; 1991 } 1992} 1993 1994static void 1995in_ifaddr_detached(struct ifaddr *ifa) 1996{ 1997 struct in_ifaddr_dbg *inifa_dbg = (struct in_ifaddr_dbg *)ifa; 1998 1999 IFA_LOCK_ASSERT_HELD(ifa); 2000 2001 if (!(ifa->ifa_debug & IFD_DEBUG)) { 2002 panic("%s: ifa %p has no debug structure", __func__, ifa); 2003 /* NOTREACHED */ 2004 } else if (ifa->ifa_debug & IFD_TRASHED) { 2005 panic("%s: ifa %p is already in trash list", __func__, ifa); 2006 /* NOTREACHED */ 2007 } 2008 ifa->ifa_debug |= IFD_TRASHED; 2009 /* Become a regular mutex, just in case */ 2010 IFA_CONVERT_LOCK(ifa); 2011 lck_mtx_lock(&inifa_trash_lock); 2012 TAILQ_INSERT_TAIL(&inifa_trash_head, inifa_dbg, inifa_trash_link); 2013 lck_mtx_unlock(&inifa_trash_lock); 2014} 2015 2016static void 2017in_ifaddr_trace(struct ifaddr *ifa, int refhold) 2018{ 2019 struct in_ifaddr_dbg *inifa_dbg = (struct in_ifaddr_dbg *)ifa; 2020 ctrace_t *tr; 2021 u_int32_t idx; 2022 u_int16_t *cnt; 2023 2024 if (!(ifa->ifa_debug & IFD_DEBUG)) { 2025 panic("%s: ifa %p has no debug structure", __func__, ifa); 2026 /* NOTREACHED */ 2027 } 2028 if (refhold) { 2029 cnt = &inifa_dbg->inifa_refhold_cnt; 2030 tr = inifa_dbg->inifa_refhold; 2031 } else { 2032 cnt = &inifa_dbg->inifa_refrele_cnt; 2033 tr = inifa_dbg->inifa_refrele; 2034 } 2035 2036 idx = atomic_add_16_ov(cnt, 1) % INIFA_TRACE_HIST_SIZE; 2037 ctrace_record(&tr[idx]); 2038} 2039