1/*
2 * Copyright (c) 2000-2008 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
76#include <pexpert/pexpert.h>
77
78#include <net/if.h>
79#include <net/if_types.h>
80#include <net/route.h>
81#include <net/kpi_protocol.h>
82
83#include <netinet/in.h>
84#include <netinet/in_var.h>
85#include <netinet/in_pcb.h>
86
87#include <netinet/igmp_var.h>
88#include <net/dlil.h>
89
90#include <netinet/ip_var.h>
91
92#include <netinet/tcp.h>
93#include <netinet/tcp_timer.h>
94#include <netinet/tcp_var.h>
95
96#include <sys/file.h>
97
98
99static int in_mask2len(struct in_addr *);
100static void in_len2mask(struct in_addr *, int);
101static int in_lifaddr_ioctl(struct socket *, u_long, caddr_t,
102	struct ifnet *, struct proc *);
103
104static void	in_socktrim(struct sockaddr_in *);
105static int	in_ifinit(struct ifnet *,
106	    struct in_ifaddr *, struct sockaddr_in *, int);
107
108static int subnetsarelocal = 0;
109SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW,
110	&subnetsarelocal, 0, "");
111
112struct in_multihead in_multihead; /* XXX BSS initialization */
113
114/* Track whether or not the SIOCARPIPLL ioctl has been called */
115__private_extern__	u_int32_t	ipv4_ll_arp_aware = 0;
116
117int
118inaddr_local(struct in_addr in)
119{
120	struct rtentry *rt;
121	struct sockaddr_in sin;
122	int local = 0;
123
124	sin.sin_family = AF_INET;
125	sin.sin_len = sizeof (sin);
126	sin.sin_addr = in;
127	rt = rtalloc1((struct sockaddr *)&sin, 0, 0UL);
128
129	if (rt != NULL) {
130		if (rt->rt_gateway->sa_family == AF_LINK ||
131		    (rt->rt_ifp->if_flags & IFF_LOOPBACK))
132			local = 1;
133		rtfree(rt);
134	} else {
135		local = in_localaddr(in);
136	}
137	return (local);
138}
139
140/*
141 * Return 1 if an internet address is for a ``local'' host
142 * (one to which we have a connection).  If subnetsarelocal
143 * is true, this includes other subnets of the local net.
144 * Otherwise, it includes only the directly-connected (sub)nets.
145 */
146int
147in_localaddr(struct in_addr in)
148{
149	u_long i = ntohl(in.s_addr);
150	struct in_ifaddr *ia;
151
152	if (subnetsarelocal) {
153		lck_mtx_lock(rt_mtx);
154		for (ia = in_ifaddrhead.tqh_first; ia;
155		     ia = ia->ia_link.tqe_next)
156			if ((i & ia->ia_netmask) == ia->ia_net) {
157				lck_mtx_unlock(rt_mtx);
158				return (1);
159			}
160		lck_mtx_unlock(rt_mtx);
161	} else {
162		lck_mtx_lock(rt_mtx);
163		for (ia = in_ifaddrhead.tqh_first; ia;
164		     ia = ia->ia_link.tqe_next)
165			if ((i & ia->ia_subnetmask) == ia->ia_subnet) {
166				lck_mtx_unlock(rt_mtx);
167				return (1);
168			}
169		lck_mtx_unlock(rt_mtx);
170	}
171	return (0);
172}
173
174/*
175 * Determine whether an IP address is in a reserved set of addresses
176 * that may not be forwarded, or whether datagrams to that destination
177 * may be forwarded.
178 */
179int
180in_canforward(struct in_addr in)
181{
182	u_long i = ntohl(in.s_addr);
183	u_long net;
184
185	if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i))
186		return (0);
187	if (IN_CLASSA(i)) {
188		net = i & IN_CLASSA_NET;
189		if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
190			return (0);
191	}
192	return (1);
193}
194
195/*
196 * Trim a mask in a sockaddr
197 */
198static void
199in_socktrim(struct sockaddr_in *ap)
200{
201    char *cplim = (char *) &ap->sin_addr;
202    char *cp = (char *) (&ap->sin_addr + 1);
203
204    ap->sin_len = 0;
205    while (--cp >= cplim)
206        if (*cp) {
207	    (ap)->sin_len = cp - (char *) (ap) + 1;
208	    break;
209	}
210}
211
212static int
213in_mask2len(struct in_addr *mask)
214{
215	size_t x, y;
216	u_char *p;
217
218	p = (u_char *)mask;
219	for (x = 0; x < sizeof(*mask); x++) {
220		if (p[x] != 0xff)
221			break;
222	}
223	y = 0;
224	if (x < sizeof(*mask)) {
225		for (y = 0; y < 8; y++) {
226			if ((p[x] & (0x80 >> y)) == 0)
227				break;
228		}
229	}
230	return x * 8 + y;
231}
232
233static void
234in_len2mask(struct in_addr *mask, int len)
235{
236	int i;
237	u_char *p;
238
239	p = (u_char *)mask;
240	bzero(mask, sizeof(*mask));
241	for (i = 0; i < len / 8; i++)
242		p[i] = 0xff;
243	if (len % 8)
244		p[i] = (0xff00 >> (len % 8)) & 0xff;
245}
246
247static int in_interfaces;	/* number of external internet interfaces */
248
249/*
250 * Generic internet control operations (ioctl's).
251 * Ifp is 0 if not an interface-specific ioctl.
252 *
253 * Returns:	0			Success
254 *		EINVAL
255 *		EADDRNOTAVAIL
256 *		EDESTADDRREQ
257 *		EPERM
258 *		ENOBUFS
259 *		EBUSY
260 *		EOPNOTSUPP
261 *	proc_suser:EPERM
262 *	suser:EPERM
263 *	in_lifaddr_ioctl:???
264 *	dlil_ioctl:???
265 *	in_ifinit:???
266 *	dlil_plumb_protocol:???
267 *	dlil_unplumb_protocol:???
268 */
269/* ARGSUSED */
270int
271in_control(
272	struct socket *so,
273	u_long cmd,
274	caddr_t data,
275	struct ifnet *ifp,
276	struct proc *p)
277{
278	struct ifreq *ifr = (struct ifreq *)data;
279	struct in_ifaddr *ia = NULL, *iap;
280	struct ifaddr *ifa;
281	struct in_aliasreq *ifra = (struct in_aliasreq *)data;
282	struct sockaddr_in oldaddr;
283	int error = 0;
284	int hostIsNew, maskIsNew;
285	struct kev_msg        ev_msg;
286	struct kev_in_data    in_event_data;
287
288
289	switch (cmd) {
290	case SIOCALIFADDR:
291	case SIOCDLIFADDR:
292		if (p && (error = proc_suser(p)) != 0)
293			return error;
294		/*fall through*/
295	case SIOCGLIFADDR:
296		if (!ifp)
297			return EINVAL;
298		return in_lifaddr_ioctl(so, cmd, data, ifp, p);
299	}
300
301	/*
302	 * Find address for this interface, if it exists.
303	 *
304	 * If an alias address was specified, find that one instead of
305	 * the first one on the interface.
306	 */
307	if (ifp) {
308		lck_mtx_lock(rt_mtx);
309		for (iap = in_ifaddrhead.tqh_first; iap;
310		     iap = iap->ia_link.tqe_next)
311			if (iap->ia_ifp == ifp) {
312				if (((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr ==
313				    iap->ia_addr.sin_addr.s_addr) {
314					ia = iap;
315					break;
316				} else if (ia == NULL) {
317					ia = iap;
318					if (ifr->ifr_addr.sa_family != AF_INET)
319						break;
320				}
321			}
322		/* take a reference on ia before releasing mutex */
323		if (ia != NULL) {
324			ifaref(&ia->ia_ifa);
325		}
326		lck_mtx_unlock(rt_mtx);
327	}
328	switch (cmd) {
329	case SIOCAUTOADDR:
330	case SIOCARPIPLL:
331		if (p && (error = proc_suser(p)) != 0) {
332			goto done;
333		}
334		if (ifp == 0) {
335			error = EADDRNOTAVAIL;
336			goto done;
337		}
338		break;
339
340	case SIOCAIFADDR:
341	case SIOCDIFADDR:
342		if (ifp == 0) {
343			error = EADDRNOTAVAIL;
344			goto done;
345		}
346		if (ifra->ifra_addr.sin_family == AF_INET) {
347			struct in_ifaddr *oia;
348
349			lck_mtx_lock(rt_mtx);
350			for (oia = ia; ia; ia = ia->ia_link.tqe_next) {
351				if (ia->ia_ifp == ifp  &&
352				    ia->ia_addr.sin_addr.s_addr ==
353				    ifra->ifra_addr.sin_addr.s_addr)
354					break;
355			}
356			/* take a reference on ia before releasing mutex */
357			if (ia != NULL && ia != oia) {
358				ifaref(&ia->ia_ifa);
359			}
360			lck_mtx_unlock(rt_mtx);
361			if (oia != NULL && oia != ia) {
362				ifafree(&oia->ia_ifa);
363			}
364			if ((ifp->if_flags & IFF_POINTOPOINT)
365			    && (cmd == SIOCAIFADDR)
366			    && (ifra->ifra_dstaddr.sin_addr.s_addr
367				== INADDR_ANY)) {
368				error = EDESTADDRREQ;
369				goto done;
370			}
371		}
372		else if (cmd == SIOCAIFADDR) {
373			error = EINVAL;
374			goto done;
375		}
376		if (cmd == SIOCDIFADDR && ia == 0) {
377			error = EADDRNOTAVAIL;
378			goto done;
379		}
380		/* FALLTHROUGH */
381	case SIOCSIFADDR:
382	case SIOCSIFNETMASK:
383	case SIOCSIFDSTADDR:
384		if ((so->so_state & SS_PRIV) == 0) {
385			error = EPERM;
386			goto done;
387		}
388		if (ifp == 0) {
389			error = EADDRNOTAVAIL;
390			goto done;
391		}
392		if (ifra->ifra_addr.sin_family != AF_INET
393		    && cmd == SIOCSIFADDR) {
394			error = EINVAL;
395			goto done;
396		}
397		if (ia == (struct in_ifaddr *)0) {
398			ia = (struct in_ifaddr *)
399				_MALLOC(sizeof *ia, M_IFADDR, M_WAITOK);
400			if (ia == (struct in_ifaddr *)NULL) {
401				error = ENOBUFS;
402				goto done;
403			}
404			bzero((caddr_t)ia, sizeof *ia);
405			/*
406			 * Protect from ipintr() traversing address list
407			 * while we're modifying it.
408			 */
409
410			ifa = &ia->ia_ifa;
411
412			ia->ia_addr.sin_family = AF_INET;
413			ia->ia_addr.sin_len = sizeof (ia->ia_addr);
414			ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;
415			ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
416			ifa->ifa_netmask = (struct sockaddr *)&ia->ia_sockmask;
417			ia->ia_sockmask.sin_len = 8;
418			ifnet_lock_exclusive(ifp);
419			if (ifp->if_flags & IFF_BROADCAST) {
420				ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
421				ia->ia_broadaddr.sin_family = AF_INET;
422			}
423			ia->ia_ifp = ifp;
424			if (!(ifp->if_flags & IFF_LOOPBACK))
425				in_interfaces++;
426			if_attach_ifa(ifp, ifa);
427			ifnet_lock_done(ifp);
428
429			lck_mtx_lock(rt_mtx);
430			ifaref(&ia->ia_ifa);
431			TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_link);
432			lck_mtx_unlock(rt_mtx);
433
434			/* Generic protocol plumbing */
435
436			if ((error = proto_plumb(PF_INET, ifp))) {
437				if (error != EEXIST) {
438					kprintf("in.c: warning can't plumb proto if=%s%d type %d error=%d\n",
439						ifp->if_name, ifp->if_unit, ifp->if_type, error);
440				}
441				error = 0; /*discard error, can be cold with unsupported interfaces */
442			}
443
444		}
445		break;
446
447	case SIOCPROTOATTACH:
448	case SIOCPROTODETACH:
449		if (p && (error = proc_suser(p)) != 0) {
450			goto done;
451		}
452		if (ifp == 0) {
453			error = EADDRNOTAVAIL;
454			goto done;
455		}
456		break;
457
458	case SIOCSIFBRDADDR:
459#ifdef __APPLE__
460		if ((so->so_state & SS_PRIV) == 0) {
461			error = EPERM;
462			goto done;
463		}
464#else
465		if (p && (error = suser(p)) != 0) {
466			goto done;
467		}
468#endif
469		/* FALLTHROUGH */
470
471	case SIOCGIFADDR:
472	case SIOCGIFNETMASK:
473	case SIOCGIFDSTADDR:
474	case SIOCGIFBRDADDR:
475		if (ia == (struct in_ifaddr *)0) {
476			error = EADDRNOTAVAIL;
477			goto done;
478		}
479		break;
480	}
481	switch (cmd) {
482	case SIOCAUTOADDR:
483		ifnet_lock_exclusive(ifp);
484		if (ifr->ifr_intval)
485			ifp->if_eflags |= IFEF_AUTOCONFIGURING;
486		else
487			ifp->if_eflags &= ~IFEF_AUTOCONFIGURING;
488		ifnet_lock_done(ifp);
489		break;
490
491	case SIOCARPIPLL:
492		ipv4_ll_arp_aware = 1;
493		ifnet_lock_exclusive(ifp);
494		if (ifr->ifr_data)
495			ifp->if_eflags |= IFEF_ARPLL;
496		else
497			ifp->if_eflags &= ~IFEF_ARPLL;
498		ifnet_lock_done(ifp);
499		break;
500
501	case SIOCGIFADDR:
502		*((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr;
503		break;
504
505	case SIOCGIFBRDADDR:
506		if ((ifp->if_flags & IFF_BROADCAST) == 0) {
507			error = EINVAL;
508			break;
509		}
510		*((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_broadaddr;
511		break;
512
513	case SIOCGIFDSTADDR:
514		if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
515			error = EINVAL;
516			break;
517		}
518		*((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr;
519		break;
520
521	case SIOCGIFNETMASK:
522		*((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask;
523		break;
524
525	case SIOCSIFDSTADDR:
526		if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
527			error = EINVAL;
528			break;
529		}
530		oldaddr = ia->ia_dstaddr;
531		ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr;
532		error = ifnet_ioctl(ifp, PF_INET, SIOCSIFDSTADDR, ia);
533		if (error == EOPNOTSUPP) {
534			error = 0;
535		}
536		if (error) {
537			ia->ia_dstaddr = oldaddr;
538			break;
539		}
540
541		ev_msg.vendor_code    = KEV_VENDOR_APPLE;
542		ev_msg.kev_class      = KEV_NETWORK_CLASS;
543		ev_msg.kev_subclass   = KEV_INET_SUBCLASS;
544
545		ev_msg.event_code = KEV_INET_SIFDSTADDR;
546
547		if (ia->ia_ifa.ifa_dstaddr)
548		     in_event_data.ia_dstaddr =
549			  ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
550		else
551		     in_event_data.ia_dstaddr.s_addr  = 0;
552
553		in_event_data.ia_addr         = ia->ia_addr.sin_addr;
554		in_event_data.ia_net          = ia->ia_net;
555		in_event_data.ia_netmask      = ia->ia_netmask;
556		in_event_data.ia_subnet       = ia->ia_subnet;
557		in_event_data.ia_subnetmask   = ia->ia_subnetmask;
558		in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
559		strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
560		in_event_data.link_data.if_family = ifp->if_family;
561		in_event_data.link_data.if_unit  = (unsigned long) ifp->if_unit;
562
563		ev_msg.dv[0].data_ptr    = &in_event_data;
564		ev_msg.dv[0].data_length      = sizeof(struct kev_in_data);
565		ev_msg.dv[1].data_length = 0;
566
567		kev_post_msg(&ev_msg);
568
569
570		if (ia->ia_flags & IFA_ROUTE) {
571			ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
572			rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
573			ia->ia_ifa.ifa_dstaddr =
574					(struct sockaddr *)&ia->ia_dstaddr;
575			rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
576		}
577		break;
578
579	case SIOCSIFBRDADDR:
580		if ((ifp->if_flags & IFF_BROADCAST) == 0) {
581			error = EINVAL;
582			break;
583		}
584		ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr;
585
586		ev_msg.vendor_code    = KEV_VENDOR_APPLE;
587		ev_msg.kev_class      = KEV_NETWORK_CLASS;
588		ev_msg.kev_subclass   = KEV_INET_SUBCLASS;
589
590		ev_msg.event_code = KEV_INET_SIFBRDADDR;
591
592		if (ia->ia_ifa.ifa_dstaddr)
593		     in_event_data.ia_dstaddr =
594			  ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
595		else
596		     in_event_data.ia_dstaddr.s_addr  = 0;
597
598		in_event_data.ia_addr         = ia->ia_addr.sin_addr;
599		in_event_data.ia_net          = ia->ia_net;
600		in_event_data.ia_netmask      = ia->ia_netmask;
601		in_event_data.ia_subnet       = ia->ia_subnet;
602		in_event_data.ia_subnetmask   = ia->ia_subnetmask;
603		in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
604		strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
605		in_event_data.link_data.if_family = ifp->if_family;
606		in_event_data.link_data.if_unit  = (unsigned long) ifp->if_unit;
607
608		ev_msg.dv[0].data_ptr    = &in_event_data;
609		ev_msg.dv[0].data_length      = sizeof(struct kev_in_data);
610		ev_msg.dv[1].data_length = 0;
611
612		kev_post_msg(&ev_msg);
613
614		break;
615
616	case SIOCSIFADDR:
617		error = in_ifinit(ifp, ia, (struct sockaddr_in *) &ifr->ifr_addr, 1);
618		break;
619
620	case SIOCPROTOATTACH:
621		error = proto_plumb(PF_INET, ifp);
622		break;
623
624	case SIOCPROTODETACH:
625                // if an ip address is still present, refuse to detach
626		ifnet_lock_shared(ifp);
627		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
628			if (ifa->ifa_addr->sa_family == AF_INET)
629				break;
630		ifnet_lock_done(ifp);
631		if (ifa != 0) {
632			error =  EBUSY;
633			break;
634		}
635
636		error = proto_unplumb(PF_INET, ifp);
637		break;
638
639
640	case SIOCSIFNETMASK: {
641		u_long i;
642
643		i = ifra->ifra_addr.sin_addr.s_addr;
644		ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr = i);
645		ev_msg.vendor_code    = KEV_VENDOR_APPLE;
646		ev_msg.kev_class      = KEV_NETWORK_CLASS;
647		ev_msg.kev_subclass   = KEV_INET_SUBCLASS;
648
649		ev_msg.event_code = KEV_INET_SIFNETMASK;
650
651		if (ia->ia_ifa.ifa_dstaddr)
652		     in_event_data.ia_dstaddr =
653			  ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
654		else
655		     in_event_data.ia_dstaddr.s_addr  = 0;
656
657		in_event_data.ia_addr         = ia->ia_addr.sin_addr;
658		in_event_data.ia_net          = ia->ia_net;
659		in_event_data.ia_netmask      = ia->ia_netmask;
660		in_event_data.ia_subnet       = ia->ia_subnet;
661		in_event_data.ia_subnetmask   = ia->ia_subnetmask;
662		in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
663		strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
664		in_event_data.link_data.if_family = ifp->if_family;
665		in_event_data.link_data.if_unit  = (unsigned long) ifp->if_unit;
666
667		ev_msg.dv[0].data_ptr    = &in_event_data;
668		ev_msg.dv[0].data_length      = sizeof(struct kev_in_data);
669		ev_msg.dv[1].data_length = 0;
670
671		kev_post_msg(&ev_msg);
672
673		break;
674	}
675	case SIOCAIFADDR:
676		maskIsNew = 0;
677		hostIsNew = 1;
678		error = 0;
679		if (ia->ia_addr.sin_family == AF_INET) {
680			if (ifra->ifra_addr.sin_len == 0) {
681				ifra->ifra_addr = ia->ia_addr;
682				hostIsNew = 0;
683			} else if (ifra->ifra_addr.sin_addr.s_addr ==
684					       ia->ia_addr.sin_addr.s_addr)
685				hostIsNew = 0;
686		}
687		if (ifra->ifra_mask.sin_len) {
688			in_ifscrub(ifp, ia, 0);
689			ia->ia_sockmask = ifra->ifra_mask;
690			ia->ia_subnetmask =
691			     ntohl(ia->ia_sockmask.sin_addr.s_addr);
692			maskIsNew = 1;
693		}
694		if ((ifp->if_flags & IFF_POINTOPOINT) &&
695		    (ifra->ifra_dstaddr.sin_family == AF_INET)) {
696			in_ifscrub(ifp, ia, 0);
697			ia->ia_dstaddr = ifra->ifra_dstaddr;
698			maskIsNew  = 1; /* We lie; but the effect's the same */
699		}
700		if (ifra->ifra_addr.sin_family == AF_INET &&
701		    (hostIsNew || maskIsNew)) {
702			error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
703		}
704		if ((ifp->if_flags & IFF_BROADCAST) &&
705		    (ifra->ifra_broadaddr.sin_family == AF_INET))
706			ia->ia_broadaddr = ifra->ifra_broadaddr;
707
708		/*
709		 * Report event.
710		 */
711
712		if ((error == 0) || (error == EEXIST)) {
713		     ev_msg.vendor_code    = KEV_VENDOR_APPLE;
714		     ev_msg.kev_class      = KEV_NETWORK_CLASS;
715		     ev_msg.kev_subclass   = KEV_INET_SUBCLASS;
716
717		     if (hostIsNew)
718			  ev_msg.event_code = KEV_INET_NEW_ADDR;
719		     else
720			  ev_msg.event_code = KEV_INET_CHANGED_ADDR;
721
722		     if (ia->ia_ifa.ifa_dstaddr)
723			  in_event_data.ia_dstaddr =
724			       ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
725		     else
726			  in_event_data.ia_dstaddr.s_addr  = 0;
727
728		     in_event_data.ia_addr         = ia->ia_addr.sin_addr;
729		     in_event_data.ia_net          = ia->ia_net;
730		     in_event_data.ia_netmask      = ia->ia_netmask;
731		     in_event_data.ia_subnet       = ia->ia_subnet;
732		     in_event_data.ia_subnetmask   = ia->ia_subnetmask;
733		     in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
734		     strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
735		     in_event_data.link_data.if_family = ifp->if_family;
736		     in_event_data.link_data.if_unit  = (unsigned long) ifp->if_unit;
737
738		     ev_msg.dv[0].data_ptr    = &in_event_data;
739		     ev_msg.dv[0].data_length      = sizeof(struct kev_in_data);
740		     ev_msg.dv[1].data_length = 0;
741
742		     kev_post_msg(&ev_msg);
743		}
744		break;
745
746	case SIOCDIFADDR:
747		error = ifnet_ioctl(ifp, PF_INET, SIOCDIFADDR, ia);
748		if (error == EOPNOTSUPP)
749			error = 0;
750		if (error != 0) {
751			break;
752		}
753
754		/* Fill out the kernel event information */
755		ev_msg.vendor_code    = KEV_VENDOR_APPLE;
756		ev_msg.kev_class      = KEV_NETWORK_CLASS;
757		ev_msg.kev_subclass   = KEV_INET_SUBCLASS;
758
759		ev_msg.event_code = KEV_INET_ADDR_DELETED;
760
761		if (ia->ia_ifa.ifa_dstaddr)
762		     in_event_data.ia_dstaddr =
763			  ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
764		else
765		     in_event_data.ia_dstaddr.s_addr  = 0;
766
767		in_event_data.ia_addr         = ia->ia_addr.sin_addr;
768		in_event_data.ia_net          = ia->ia_net;
769		in_event_data.ia_netmask      = ia->ia_netmask;
770		in_event_data.ia_subnet       = ia->ia_subnet;
771		in_event_data.ia_subnetmask   = ia->ia_subnetmask;
772		in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
773		strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ);
774		in_event_data.link_data.if_family = ifp->if_family;
775		in_event_data.link_data.if_unit  = (unsigned long) 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		lck_mtx_lock(rt_mtx);
782		TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link);
783		/*
784		 * in_ifscrub kills the interface route.
785		 */
786		in_ifscrub(ifp, ia, 1);
787		ifa = &ia->ia_ifa;
788		lck_mtx_unlock(rt_mtx);
789		ifnet_lock_exclusive(ifp);
790		if_detach_ifa(ifp, ifa);
791
792#ifdef __APPLE__
793       /*
794        * If the interface supports multicast, and no address is left,
795        * remove the "all hosts" multicast group from that interface.
796        */
797		if (ifp->if_flags & IFF_MULTICAST) {
798			struct in_addr addr;
799			struct in_multi *inm = NULL;
800
801			TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
802				if (ifa->ifa_addr->sa_family == AF_INET)
803					break;
804
805			if (ifa == 0) {
806				addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
807				IN_LOOKUP_MULTI(addr, ifp, inm);
808			}
809			ifnet_lock_done(ifp);
810			if (inm)
811		  	  	in_delmulti(&inm);
812		} else
813			ifnet_lock_done(ifp);
814#endif
815
816		/* Post the kernel event */
817		kev_post_msg(&ev_msg);
818
819		/*
820		 * See if there is any IPV4 address left and if so,
821		 * reconfigure KDP to use current primary address.
822		 */
823		ifa = ifa_ifpgetprimary(ifp, AF_INET);
824		if (ifa != NULL) {
825			error = ifnet_ioctl(ifp, PF_INET, SIOCSIFADDR, ifa);
826			if (error == EOPNOTSUPP)
827				error = 0;
828
829			/* Release reference from ifa_ifpgetprimary() */
830			ifafree(ifa);
831		}
832		break;
833
834#ifdef __APPLE__
835    case SIOCSETOT: {
836        /*
837         * Inspiration from tcp_ctloutput() and ip_ctloutput()
838         * Special ioctl for OpenTransport sockets
839         */
840        struct	inpcb	*inp, *cloned_inp;
841        int 			error2 = 0;
842        int 			cloned_fd = *(int *)data;
843
844        inp = sotoinpcb(so);
845        if (inp == NULL) {
846            break;
847        }
848
849        /* let's make sure it's either -1 or a valid file descriptor */
850        if (cloned_fd != -1) {
851            struct socket	*cloned_so;
852            error2 = file_socket(cloned_fd, &cloned_so);
853            if (error2){
854                break;
855            }
856            cloned_inp = sotoinpcb(cloned_so);
857			file_drop(cloned_fd);
858        } else {
859            cloned_inp = NULL;
860        }
861
862        if (cloned_inp == NULL) {
863            /* OT always uses IP_PORTRANGE_HIGH */
864            inp->inp_flags &= ~(INP_LOWPORT);
865            inp->inp_flags |= INP_HIGHPORT;
866            /* For UDP, OT allows broadcast by default */
867            if (so->so_type == SOCK_DGRAM)
868                so->so_options |= SO_BROADCAST;
869            /* For TCP we want to see MSG_OOB when receive urgent data */
870            else if (so->so_type == SOCK_STREAM)
871                so->so_options |= SO_WANTOOBFLAG;
872        } else {
873            inp->inp_ip_tos = cloned_inp->inp_ip_tos;
874            inp->inp_ip_ttl = cloned_inp->inp_ip_ttl;
875            inp->inp_flags = cloned_inp->inp_flags;
876
877            /* Multicast options */
878            if (cloned_inp->inp_moptions != NULL) {
879                int			i;
880                struct ip_moptions	*cloned_imo = cloned_inp->inp_moptions;
881                struct ip_moptions	*imo = inp->inp_moptions;
882
883                if (imo == NULL) {
884                    /*
885                     * No multicast option buffer attached to the pcb;
886                     * allocate one.
887                     */
888                    imo = (struct ip_moptions*)
889                        _MALLOC(sizeof(*imo), M_IPMOPTS, M_WAITOK);
890                    if (imo == NULL) {
891                        error2 = ENOBUFS;
892                        break;
893                    }
894                    inp->inp_moptions = imo;
895                }
896                imo->imo_multicast_ifp = cloned_imo->imo_multicast_ifp;
897                imo->imo_multicast_vif = cloned_imo->imo_multicast_vif;
898                imo->imo_multicast_ttl = cloned_imo->imo_multicast_ttl;
899                imo->imo_multicast_loop = cloned_imo->imo_multicast_loop;
900                imo->imo_num_memberships = cloned_imo->imo_num_memberships;
901                for (i = 0; i < cloned_imo->imo_num_memberships; i++) {
902                    imo->imo_membership[i] =
903                    in_addmulti(&cloned_imo->imo_membership[i]->inm_addr,
904                                cloned_imo->imo_membership[i]->inm_ifp);
905					if (imo->imo_membership[i] == NULL) {
906						error2 = ENOBUFS;
907						break;
908					}
909                }
910                if (i < cloned_imo->imo_num_memberships) {
911                	/* Failed, perform cleanup */
912                	for (i--; i >= 0; i--)
913                		in_delmulti(&imo->imo_membership[i]);
914                	imo->imo_num_memberships = 0;
915                	break;
916                }
917            }
918        }
919        break;
920    }
921#endif /* __APPLE__ */
922
923	default:
924		error = EOPNOTSUPP;
925	}
926 done:
927	if (ia != NULL) {
928		ifafree(&ia->ia_ifa);
929	}
930	return (error);
931}
932
933/*
934 * SIOC[GAD]LIFADDR.
935 *	SIOCGLIFADDR: get first address. (?!?)
936 *	SIOCGLIFADDR with IFLR_PREFIX:
937 *		get first address that matches the specified prefix.
938 *	SIOCALIFADDR: add the specified address.
939 *	SIOCALIFADDR with IFLR_PREFIX:
940 *		EINVAL since we can't deduce hostid part of the address.
941 *	SIOCDLIFADDR: delete the specified address.
942 *	SIOCDLIFADDR with IFLR_PREFIX:
943 *		delete the first address that matches the specified prefix.
944 * return values:
945 *	EINVAL on invalid parameters
946 *	EADDRNOTAVAIL on prefix match failed/specified address not found
947 *	other values may be returned from in_ioctl()
948 */
949static int
950in_lifaddr_ioctl(
951	struct socket *so,
952	u_long cmd,
953	caddr_t	data,
954	struct ifnet *ifp,
955	struct proc *p)
956{
957	struct if_laddrreq *iflr = (struct if_laddrreq *)data;
958	struct ifaddr *ifa;
959
960	/* sanity checks */
961	if (!data || !ifp) {
962		panic("invalid argument to in_lifaddr_ioctl");
963		/*NOTRECHED*/
964	}
965
966	switch (cmd) {
967	case SIOCGLIFADDR:
968		/* address must be specified on GET with IFLR_PREFIX */
969		if ((iflr->flags & IFLR_PREFIX) == 0)
970			break;
971		/*FALLTHROUGH*/
972	case SIOCALIFADDR:
973	case SIOCDLIFADDR:
974		/* address must be specified on ADD and DELETE */
975		if (iflr->addr.ss_family != AF_INET)
976			return EINVAL;
977		if (iflr->addr.ss_len != sizeof(struct sockaddr_in))
978			return EINVAL;
979		/* XXX need improvement */
980		if (iflr->dstaddr.ss_family
981		 && iflr->dstaddr.ss_family != AF_INET)
982			return EINVAL;
983		if (iflr->dstaddr.ss_family
984		 && iflr->dstaddr.ss_len != sizeof(struct sockaddr_in))
985			return EINVAL;
986		break;
987	default: /*shouldn't happen*/
988		return EOPNOTSUPP;
989	}
990	if (sizeof(struct in_addr) * 8 < iflr->prefixlen)
991		return EINVAL;
992
993	switch (cmd) {
994	case SIOCALIFADDR:
995	    {
996		struct in_aliasreq ifra;
997
998		if (iflr->flags & IFLR_PREFIX)
999			return EINVAL;
1000
1001		/* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
1002		bzero(&ifra, sizeof(ifra));
1003		bcopy(iflr->iflr_name, ifra.ifra_name,
1004			sizeof(ifra.ifra_name));
1005
1006		bcopy(&iflr->addr, &ifra.ifra_addr, iflr->addr.ss_len);
1007
1008		if (iflr->dstaddr.ss_family) {	/*XXX*/
1009			bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
1010				iflr->dstaddr.ss_len);
1011		}
1012
1013		ifra.ifra_mask.sin_family = AF_INET;
1014		ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in);
1015		in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen);
1016
1017		return in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp, p);
1018	    }
1019	case SIOCGLIFADDR:
1020	case SIOCDLIFADDR:
1021	    {
1022		struct in_ifaddr *ia;
1023		struct in_addr mask, candidate;
1024		struct in_addr match = { 0 };
1025		struct sockaddr_in *sin;
1026		int cmp;
1027
1028		bzero(&mask, sizeof(mask));
1029		if (iflr->flags & IFLR_PREFIX) {
1030			/* lookup a prefix rather than address. */
1031			in_len2mask(&mask, iflr->prefixlen);
1032
1033			sin = (struct sockaddr_in *)&iflr->addr;
1034			match.s_addr = sin->sin_addr.s_addr;
1035			match.s_addr &= mask.s_addr;
1036
1037			/* if you set extra bits, that's wrong */
1038			if (match.s_addr != sin->sin_addr.s_addr)
1039				return EINVAL;
1040
1041			cmp = 1;
1042		} else {
1043			if (cmd == SIOCGLIFADDR) {
1044				/* on getting an address, take the 1st match */
1045				cmp = 0;	/*XXX*/
1046			} else {
1047				/* on deleting an address, do exact match */
1048				in_len2mask(&mask, 32);
1049				sin = (struct sockaddr_in *)&iflr->addr;
1050				match.s_addr = sin->sin_addr.s_addr;
1051
1052				cmp = 1;
1053			}
1054		}
1055
1056		ifnet_lock_shared(ifp);
1057		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)	{
1058			if (ifa->ifa_addr->sa_family != AF_INET6)
1059				continue;
1060			if (!cmp)
1061				break;
1062			candidate.s_addr = ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr;
1063			candidate.s_addr &= mask.s_addr;
1064			if (candidate.s_addr == match.s_addr)
1065				break;
1066		}
1067		ifnet_lock_done(ifp);
1068		if (!ifa)
1069			return EADDRNOTAVAIL;
1070		ia = (struct in_ifaddr *)ifa;
1071
1072		if (cmd == SIOCGLIFADDR) {
1073			/* fill in the if_laddrreq structure */
1074			bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len);
1075
1076			if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
1077				bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
1078					ia->ia_dstaddr.sin_len);
1079			} else
1080				bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
1081
1082			iflr->prefixlen =
1083				in_mask2len(&ia->ia_sockmask.sin_addr);
1084
1085			iflr->flags = 0;	/*XXX*/
1086
1087			return 0;
1088		} else {
1089			struct in_aliasreq ifra;
1090
1091			/* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
1092			bzero(&ifra, sizeof(ifra));
1093			bcopy(iflr->iflr_name, ifra.ifra_name,
1094				sizeof(ifra.ifra_name));
1095
1096			bcopy(&ia->ia_addr, &ifra.ifra_addr,
1097				ia->ia_addr.sin_len);
1098			if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
1099				bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
1100					ia->ia_dstaddr.sin_len);
1101			}
1102			bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr,
1103				ia->ia_sockmask.sin_len);
1104
1105			return in_control(so, SIOCDIFADDR, (caddr_t)&ifra,
1106					  ifp, p);
1107		}
1108	    }
1109	}
1110
1111	return EOPNOTSUPP;	/*just for safety*/
1112}
1113
1114/*
1115 * Delete any existing route for an interface.
1116 */
1117void
1118in_ifscrub(
1119	struct ifnet *ifp,
1120	struct in_ifaddr *ia,
1121	int locked)
1122{
1123
1124	if ((ia->ia_flags & IFA_ROUTE) == 0)
1125		return;
1126	if (!locked)
1127		lck_mtx_lock(rt_mtx);
1128	if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))
1129		rtinit_locked(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
1130	else
1131		rtinit_locked(&(ia->ia_ifa), (int)RTM_DELETE, 0);
1132	ia->ia_flags &= ~IFA_ROUTE;
1133	if (!locked)
1134		lck_mtx_unlock(rt_mtx);
1135}
1136
1137/*
1138 * Initialize an interface's internet address
1139 * and routing table entry.
1140 */
1141static int
1142in_ifinit(
1143	struct ifnet *ifp,
1144	struct in_ifaddr *ia,
1145	struct sockaddr_in *sin,
1146	int scrub)
1147{
1148	u_long i = ntohl(sin->sin_addr.s_addr);
1149	struct sockaddr_in oldaddr;
1150	int flags = RTF_UP, error;
1151	struct ifaddr *ifa0;
1152	unsigned int cmd;
1153
1154	oldaddr = ia->ia_addr;
1155	ia->ia_addr = *sin;
1156
1157	/*
1158	 * Give the interface a chance to initialize if this is its first
1159	 * address, and to validate the address if necessary.  Send down
1160	 * SIOCSIFADDR for first address, and SIOCAIFADDR for alias(es).
1161	 * We find the first IPV4 address assigned to it and check if this
1162	 * is the same as the one passed into this routine.
1163	 */
1164	ifa0 = ifa_ifpgetprimary(ifp, AF_INET);
1165	cmd = (&ia->ia_ifa == ifa0) ? SIOCSIFADDR : SIOCAIFADDR;
1166	error = ifnet_ioctl(ifp, PF_INET, cmd, ia);
1167	if (error == EOPNOTSUPP)
1168		error = 0;
1169	/*
1170	 * If we've just sent down SIOCAIFADDR, send another ioctl down
1171	 * for SIOCSIFADDR for the first IPV4 address of the interface,
1172	 * because an address change on one of the addresses will result
1173	 * in the removal of the previous first IPV4 address.  KDP needs
1174	 * be reconfigured with the current primary IPV4 address.
1175	 */
1176	if (error == 0 && cmd == SIOCAIFADDR) {
1177		error = ifnet_ioctl(ifp, PF_INET, SIOCSIFADDR, ifa0);
1178		if (error == EOPNOTSUPP)
1179			error = 0;
1180	}
1181
1182	/* Release reference from ifa_ifpgetprimary() */
1183	ifafree(ifa0);
1184
1185	if (error) {
1186		ia->ia_addr = oldaddr;
1187		return (error);
1188	}
1189	if (scrub) {
1190		ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
1191		in_ifscrub(ifp, ia, 0);
1192		ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
1193	}
1194	if (IN_CLASSA(i))
1195		ia->ia_netmask = IN_CLASSA_NET;
1196	else if (IN_CLASSB(i))
1197		ia->ia_netmask = IN_CLASSB_NET;
1198	else
1199		ia->ia_netmask = IN_CLASSC_NET;
1200	/*
1201	 * The subnet mask usually includes at least the standard network part,
1202	 * but may may be smaller in the case of supernetting.
1203	 * If it is set, we believe it.
1204	 */
1205	if (ia->ia_subnetmask == 0) {
1206		ia->ia_subnetmask = ia->ia_netmask;
1207		ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
1208	} else
1209		ia->ia_netmask &= ia->ia_subnetmask;
1210	ia->ia_net = i & ia->ia_netmask;
1211	ia->ia_subnet = i & ia->ia_subnetmask;
1212	in_socktrim(&ia->ia_sockmask);
1213	/*
1214	 * Add route for the network.
1215	 */
1216	ia->ia_ifa.ifa_metric = ifp->if_metric;
1217	if (ifp->if_flags & IFF_BROADCAST) {
1218		ia->ia_broadaddr.sin_addr.s_addr =
1219			htonl(ia->ia_subnet | ~ia->ia_subnetmask);
1220		ia->ia_netbroadcast.s_addr =
1221			htonl(ia->ia_net | ~ ia->ia_netmask);
1222	} else if (ifp->if_flags & IFF_LOOPBACK) {
1223		ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
1224		flags |= RTF_HOST;
1225	} else if (ifp->if_flags & IFF_POINTOPOINT) {
1226		if (ia->ia_dstaddr.sin_family != AF_INET)
1227			return (0);
1228		flags |= RTF_HOST;
1229	}
1230	if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0)
1231		ia->ia_flags |= IFA_ROUTE;
1232	/* XXX check if the subnet route points to the same interface */
1233	if (error == EEXIST)
1234		error = 0;
1235
1236	/*
1237	 * If the interface supports multicast, join the "all hosts"
1238	 * multicast group on that interface.
1239	 */
1240	if (ifp->if_flags & IFF_MULTICAST) {
1241		struct in_multi *inm;
1242		struct in_addr addr;
1243
1244		addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
1245		ifnet_lock_shared(ifp);
1246		IN_LOOKUP_MULTI(addr, ifp, inm);
1247		ifnet_lock_done(ifp);
1248		if (inm == 0)
1249			in_addmulti(&addr, ifp);
1250	}
1251	return (error);
1252}
1253
1254
1255/*
1256 * Return 1 if the address might be a local broadcast address.
1257 */
1258int
1259in_broadcast(
1260	struct in_addr in,
1261	struct ifnet *ifp)
1262{
1263	struct ifaddr *ifa;
1264	u_long t;
1265
1266	if (in.s_addr == INADDR_BROADCAST ||
1267	    in.s_addr == INADDR_ANY)
1268		return 1;
1269	if ((ifp->if_flags & IFF_BROADCAST) == 0)
1270		return 0;
1271	t = ntohl(in.s_addr);
1272	/*
1273	 * Look through the list of addresses for a match
1274	 * with a broadcast address.
1275	 */
1276#define ia ((struct in_ifaddr *)ifa)
1277	ifnet_lock_shared(ifp);
1278	TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1279		if (ifa->ifa_addr == NULL) {
1280			ifnet_lock_done(ifp);
1281			return (0);
1282		}
1283		if (ifa->ifa_addr->sa_family == AF_INET &&
1284		    (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
1285		     in.s_addr == ia->ia_netbroadcast.s_addr ||
1286		     /*
1287		      * Check for old-style (host 0) broadcast.
1288		      */
1289		     t == ia->ia_subnet || t == ia->ia_net) &&
1290		     /*
1291		      * Check for an all one subnetmask. These
1292		      * only exist when an interface gets a secondary
1293		      * address.
1294		      */
1295		     ia->ia_subnetmask != (u_long)0xffffffff) {
1296			ifnet_lock_done(ifp);
1297			return 1;
1298		}
1299	}
1300	ifnet_lock_done(ifp);
1301	return (0);
1302#undef ia
1303}
1304
1305static void
1306in_free_inm(
1307	void*	ifma_protospec)
1308{
1309	struct in_multi *inm = ifma_protospec;
1310
1311	/*
1312	 * No remaining claims to this record; let IGMP know that
1313	 * we are leaving the multicast group.
1314	 */
1315	igmp_leavegroup(inm);
1316	lck_mtx_lock(rt_mtx);
1317	LIST_REMOVE(inm, inm_link);
1318	lck_mtx_unlock(rt_mtx);
1319	FREE(inm, M_IPMADDR);
1320}
1321
1322/*
1323 * Add an address to the list of IP multicast addresses for a given interface.
1324 */
1325struct in_multi *
1326in_addmulti(
1327	struct in_addr *ap,
1328	struct ifnet *ifp)
1329{
1330	struct in_multi *inm;
1331	int error;
1332	struct sockaddr_in sin;
1333	struct ifmultiaddr *ifma;
1334
1335	/*
1336	 * Call generic routine to add membership or increment
1337	 * refcount.  It wants addresses in the form of a sockaddr,
1338	 * so we build one here (being careful to zero the unused bytes).
1339	 */
1340	bzero(&sin, sizeof sin);
1341	sin.sin_family = AF_INET;
1342	sin.sin_len = sizeof sin;
1343	sin.sin_addr = *ap;
1344	error = if_addmulti(ifp, (struct sockaddr *)&sin, &ifma);
1345	if (error) {
1346		return 0;
1347	}
1348
1349	/*
1350	 * If ifma->ifma_protospec is null, then if_addmulti() created
1351	 * a new record.  Otherwise, we are done.
1352	 */
1353	if (ifma->ifma_protospec != 0) {
1354		return ifma->ifma_protospec;
1355	}
1356
1357	inm = (struct in_multi *) _MALLOC(sizeof(*inm), M_IPMADDR, M_WAITOK);
1358	if (inm == NULL) {
1359		return (NULL);
1360	}
1361
1362	bzero(inm, sizeof *inm);
1363	inm->inm_addr = *ap;
1364	inm->inm_ifp = ifp;
1365	inm->inm_ifma = ifma;
1366	lck_mtx_lock(rt_mtx);
1367	if (ifma->ifma_protospec == NULL) {
1368		ifma->ifma_protospec = inm;
1369		ifma->ifma_free = in_free_inm;
1370		LIST_INSERT_HEAD(&in_multihead, inm, inm_link);
1371	}
1372	lck_mtx_unlock(rt_mtx);
1373
1374	if (ifma->ifma_protospec != inm) {
1375		_FREE(inm, M_IPMADDR);
1376		return ifma->ifma_protospec;
1377	}
1378
1379	/*
1380	 * Let IGMP know that we have joined a new IP multicast group.
1381	 */
1382	error = igmp_joingroup(inm);
1383	if (error) {
1384		char addrbuf[16];
1385
1386		/*
1387		 * We can't free the inm because someone else may already be
1388		 * using it. Once we put it in to ifma->ifma_protospec, it
1389		 * must exist as long as the ifma does. Might be nice to flag
1390		 * the error so we can try igmp_joingroup the next time through.
1391		 */
1392		log(LOG_ERR, "igmp_joingroup error %d joining multicast %s on %s%d\n",
1393			error, inet_ntop(AF_INET, &sin.sin_addr, addrbuf, sizeof(addrbuf)),
1394			ifp->if_name, ifp->if_unit);
1395	}
1396
1397	return (inm);
1398}
1399
1400/*
1401 * Delete a multicast address record.
1402 */
1403void
1404in_delmulti(
1405	struct in_multi **inm)
1406{
1407	struct in_multi	*inm2;
1408
1409	lck_mtx_lock(rt_mtx);
1410	LIST_FOREACH(inm2, &in_multihead, inm_link) {
1411		if (inm2 == *inm)
1412			break;
1413	}
1414	if (inm2 != *inm) {
1415		lck_mtx_unlock(rt_mtx);
1416		printf("in_delmulti - ignoring invalid inm (%p)\n", *inm);
1417		return;
1418	}
1419	lck_mtx_unlock(rt_mtx);
1420
1421	/* We intentionally do this a bit differently than BSD */
1422	if ((*inm)->inm_ifma) {
1423		if_delmultiaddr((*inm)->inm_ifma, 0);
1424		ifma_release((*inm)->inm_ifma);
1425	}
1426	*inm = NULL;
1427}
1428
1429#if !NFSCLIENT
1430int inet_aton(char *cp, struct in_addr *pin);
1431int
1432inet_aton(char * cp, struct in_addr * pin)
1433{
1434    u_char * b = (unsigned char *)pin;
1435    int	   i;
1436    char * p;
1437
1438    for (p = cp, i = 0; i < 4; i++) {
1439	u_long l = strtoul(p, 0, 0);
1440	if (l > 255)
1441	    return (FALSE);
1442	b[i] = l;
1443	p = strchr(p, '.');
1444	if (i < 3 && p == NULL)
1445	    return (FALSE);
1446	p++;
1447    }
1448    return (TRUE);
1449}
1450#endif
1451