]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet/in.c
xnu-2050.48.11.tar.gz
[apple/xnu.git] / bsd / netinet / in.c
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
104 static int in_mask2len(struct in_addr *);
105 static void in_len2mask(struct in_addr *, int);
106 static int in_lifaddr_ioctl(struct socket *, u_long, struct if_laddrreq *,
107 struct ifnet *, struct proc *);
108 static int in_setrouter(struct ifnet *, int);
109
110 static void in_socktrim(struct sockaddr_in *);
111 static 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
123 static void in_iahash_remove(struct in_ifaddr *);
124 static void in_iahash_insert(struct in_ifaddr *);
125 static void in_iahash_insert_ptp(struct in_ifaddr *);
126 static struct in_ifaddr *in_ifaddr_alloc(int);
127 static void in_ifaddr_attached(struct ifaddr *);
128 static void in_ifaddr_detached(struct ifaddr *);
129 static void in_ifaddr_free(struct ifaddr *);
130 static void in_ifaddr_trace(struct ifaddr *, int);
131
132 static int subnetsarelocal = 0;
133 SYSCTL_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
144 struct 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 */
166 static TAILQ_HEAD(, in_ifaddr_dbg) inifa_trash_head;
167 static decl_lck_mtx_data(, inifa_trash_lock);
168
169 #if DEBUG
170 static unsigned int inifa_debug = 1; /* debugging (enabled) */
171 #else
172 static unsigned int inifa_debug; /* debugging (disabled) */
173 #endif /* !DEBUG */
174 static unsigned int inifa_size; /* size of zone element */
175 static 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 */
187 int
188 inaddr_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 */
225 int
226 in_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 */
266 int
267 in_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 */
285 static void
286 in_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
299 static int
300 in_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
320 static void
321 in_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
334 static int in_interfaces; /* number of external internet interfaces */
335
336 static int
337 in_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 */
369 int
370 in_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 */
1244 static int
1245 in_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 */
1421 static int
1422 in_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 */
1445 void
1446 in_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 */
1470 static void
1471 in_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 */
1492 static void
1493 in_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 */
1519 static void
1520 in_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 */
1564 static int
1565 in_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 */
1753 int
1754 in_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
1796 void
1797 in_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
1855 int inet_aton(char *cp, struct in_addr *pin);
1856 int
1857 inet_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
1876 int inet_ntoa2(struct in_addr * pin, char * cp, const int len);
1877 int 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 */
1892 void
1893 in_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
1915 static struct in_ifaddr *
1916 in_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
1940 static void
1941 in_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
1973 static void
1974 in_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
1994 static void
1995 in_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
2016 static void
2017 in_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 }