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