1/*	$OpenBSD: in.c,v 1.186 2024/01/06 10:58:45 bluhm Exp $	*/
2/*	$NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $	*/
3
4/*
5 * Copyright (C) 2001 WIDE Project.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * Copyright (c) 1982, 1986, 1991, 1993
34 *	The Regents of the University of California.  All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 *    notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 *    notice, this list of conditions and the following disclaimer in the
43 *    documentation and/or other materials provided with the distribution.
44 * 3. 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.2 (Berkeley) 11/15/93
61 */
62
63#include <sys/param.h>
64#include <sys/systm.h>
65#include <sys/ioctl.h>
66#include <sys/malloc.h>
67#include <sys/socket.h>
68#include <sys/socketvar.h>
69
70#include <net/if.h>
71#include <net/if_var.h>
72#include <net/route.h>
73
74#include <netinet/in.h>
75#include <netinet/in_var.h>
76#include <netinet/igmp_var.h>
77
78#ifdef MROUTING
79#include <netinet/ip_mroute.h>
80#endif
81
82#include "ether.h"
83
84
85void in_socktrim(struct sockaddr_in *);
86
87int in_ioctl_set_ifaddr(u_long, caddr_t, struct ifnet *);
88int in_ioctl_change_ifaddr(u_long, caddr_t, struct ifnet *);
89int in_ioctl_get(u_long, caddr_t, struct ifnet *);
90void in_purgeaddr(struct ifaddr *);
91int in_addhost(struct in_ifaddr *, struct sockaddr_in *);
92int in_scrubhost(struct in_ifaddr *, struct sockaddr_in *);
93int in_insert_prefix(struct in_ifaddr *);
94void in_remove_prefix(struct in_ifaddr *);
95
96/*
97 * Determine whether an IP address is in a reserved set of addresses
98 * that may not be forwarded, or whether datagrams to that destination
99 * may be forwarded.
100 */
101int
102in_canforward(struct in_addr in)
103{
104	u_int32_t net;
105
106	if (IN_MULTICAST(in.s_addr))
107		return (0);
108	if (IN_CLASSA(in.s_addr)) {
109		net = in.s_addr & IN_CLASSA_NET;
110		if (net == 0 ||
111		    net == htonl(IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
112			return (0);
113	}
114	return (1);
115}
116
117/*
118 * Trim a mask in a sockaddr
119 */
120void
121in_socktrim(struct sockaddr_in *ap)
122{
123	char *cplim = (char *) &ap->sin_addr;
124	char *cp = (char *) (&ap->sin_addr + 1);
125
126	ap->sin_len = 0;
127	while (--cp >= cplim)
128		if (*cp) {
129			(ap)->sin_len = cp - (char *) (ap) + 1;
130			break;
131		}
132}
133
134int
135in_mask2len(struct in_addr *mask)
136{
137	int x, y;
138	u_char *p;
139
140	p = (u_char *)mask;
141	for (x = 0; x < sizeof(*mask); x++) {
142		if (p[x] != 0xff)
143			break;
144	}
145	y = 0;
146	if (x < sizeof(*mask)) {
147		for (y = 0; y < 8; y++) {
148			if ((p[x] & (0x80 >> y)) == 0)
149				break;
150		}
151	}
152	return x * 8 + y;
153}
154
155void
156in_len2mask(struct in_addr *mask, int len)
157{
158	int i;
159	u_char *p;
160
161	p = (u_char *)mask;
162	bzero(mask, sizeof(*mask));
163	for (i = 0; i < len / 8; i++)
164		p[i] = 0xff;
165	if (len % 8)
166		p[i] = (0xff00 >> (len % 8)) & 0xff;
167}
168
169int
170in_nam2sin(const struct mbuf *nam, struct sockaddr_in **sin)
171{
172	struct sockaddr *sa = mtod(nam, struct sockaddr *);
173
174	if (nam->m_len < offsetof(struct sockaddr, sa_data))
175		return EINVAL;
176	if (sa->sa_family != AF_INET)
177		return EAFNOSUPPORT;
178	if (sa->sa_len != nam->m_len)
179		return EINVAL;
180	if (sa->sa_len != sizeof(struct sockaddr_in))
181		return EINVAL;
182	*sin = satosin(sa);
183
184	return 0;
185}
186
187int
188in_sa2sin(struct sockaddr *sa, struct sockaddr_in **sin)
189{
190	if (sa->sa_family != AF_INET)
191		return EAFNOSUPPORT;
192	if (sa->sa_len != sizeof(struct sockaddr_in))
193		return EINVAL;
194	*sin = satosin(sa);
195
196	return 0;
197}
198
199int
200in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
201{
202	int privileged;
203
204	privileged = 0;
205	if ((so->so_state & SS_PRIV) != 0)
206		privileged++;
207
208	switch (cmd) {
209#ifdef MROUTING
210	case SIOCGETVIFCNT:
211	case SIOCGETSGCNT:
212		return mrt_ioctl(so, cmd, data);
213#endif /* MROUTING */
214	default:
215		return in_ioctl(cmd, data, ifp, privileged);
216	}
217}
218
219int
220in_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
221{
222	struct ifreq *ifr = (struct ifreq *)data;
223	struct ifaddr *ifa;
224	struct in_ifaddr *ia = NULL;
225	struct sockaddr_in *sin = NULL, oldaddr;
226	int error = 0;
227
228	if (ifp == NULL)
229		return (ENXIO);
230
231	switch (cmd) {
232	case SIOCGIFADDR:
233	case SIOCGIFNETMASK:
234	case SIOCGIFDSTADDR:
235	case SIOCGIFBRDADDR:
236		return in_ioctl_get(cmd, data, ifp);
237	case SIOCSIFADDR:
238		if (!privileged)
239			return (EPERM);
240		return in_ioctl_set_ifaddr(cmd, data, ifp);
241	case SIOCAIFADDR:
242	case SIOCDIFADDR:
243		if (!privileged)
244			return (EPERM);
245		return in_ioctl_change_ifaddr(cmd, data, ifp);
246	case SIOCSIFNETMASK:
247	case SIOCSIFDSTADDR:
248	case SIOCSIFBRDADDR:
249		break;
250	default:
251		return (EOPNOTSUPP);
252	}
253
254	if (!privileged)
255		return (EPERM);
256
257	if (ifr->ifr_addr.sa_family == AF_INET) {
258		error = in_sa2sin(&ifr->ifr_addr, &sin);
259		if (error)
260			return (error);
261	}
262
263	NET_LOCK();
264	KERNEL_LOCK();
265
266	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
267		if (ifa->ifa_addr->sa_family != AF_INET)
268			continue;
269		/* find first address or exact match */
270		if (ia == NULL)
271			ia = ifatoia(ifa);
272		if (sin == NULL || sin->sin_addr.s_addr == INADDR_ANY)
273			break;
274		if (ifatoia(ifa)->ia_addr.sin_addr.s_addr ==
275		    sin->sin_addr.s_addr) {
276			ia = ifatoia(ifa);
277			break;
278		}
279	}
280	if (ia == NULL) {
281		error = EADDRNOTAVAIL;
282		goto err;
283	}
284
285	switch (cmd) {
286	case SIOCSIFDSTADDR:
287		if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
288			error = EINVAL;
289			break;
290		}
291		error = in_sa2sin(&ifr->ifr_dstaddr, &sin);
292		if (error)
293			break;
294		oldaddr = ia->ia_dstaddr;
295		ia->ia_dstaddr = *sin;
296		error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, (caddr_t)ia);
297		if (error) {
298			ia->ia_dstaddr = oldaddr;
299			break;
300		}
301		in_scrubhost(ia, &oldaddr);
302		in_addhost(ia, &ia->ia_dstaddr);
303		break;
304
305	case SIOCSIFBRDADDR:
306		if ((ifp->if_flags & IFF_BROADCAST) == 0) {
307			error = EINVAL;
308			break;
309		}
310		error = in_sa2sin(&ifr->ifr_broadaddr, &sin);
311		if (error)
312			break;
313		ifa_update_broadaddr(ifp, &ia->ia_ifa, sintosa(sin));
314		break;
315
316	case SIOCSIFNETMASK:
317		if (ifr->ifr_addr.sa_len < 8) {
318			error = EINVAL;
319			break;
320		}
321		/* do not check inet family or strict len */
322		sin = satosin(&ifr->ifr_addr);
323		if (ntohl(sin->sin_addr.s_addr) &
324		    (~ntohl(sin->sin_addr.s_addr) >> 1)) {
325			/* non-contiguous netmask */
326			error = EINVAL;
327			break;
328		}
329		ia->ia_netmask = ia->ia_sockmask.sin_addr.s_addr =
330		    sin->sin_addr.s_addr;
331		break;
332	}
333err:
334	KERNEL_UNLOCK();
335	NET_UNLOCK();
336	return (error);
337}
338
339int
340in_ioctl_set_ifaddr(u_long cmd, caddr_t data, struct ifnet *ifp)
341{
342	struct ifreq *ifr = (struct ifreq *)data;
343	struct ifaddr *ifa;
344	struct in_ifaddr *ia = NULL;
345	struct sockaddr_in *sin;
346	int error = 0;
347	int newifaddr;
348
349	if (cmd != SIOCSIFADDR)
350		panic("%s: invalid ioctl %lu", __func__, cmd);
351
352	error = in_sa2sin(&ifr->ifr_addr, &sin);
353	if (error)
354		return (error);
355
356	NET_LOCK();
357	KERNEL_LOCK();
358
359	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
360		if (ifa->ifa_addr->sa_family != AF_INET)
361			continue;
362		/* find first address */
363		ia = ifatoia(ifa);
364		break;
365	}
366	if (ia == NULL) {
367		ia = malloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO);
368		refcnt_init_trace(&ia->ia_ifa.ifa_refcnt, DT_REFCNT_IDX_IFADDR);
369		ia->ia_addr.sin_family = AF_INET;
370		ia->ia_addr.sin_len = sizeof(ia->ia_addr);
371		ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
372		ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
373		ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
374		ia->ia_sockmask.sin_len = 8;
375		if (ifp->if_flags & IFF_BROADCAST) {
376			ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
377			ia->ia_broadaddr.sin_family = AF_INET;
378		}
379		ia->ia_ifp = ifp;
380
381		newifaddr = 1;
382	} else
383		newifaddr = 0;
384
385	in_ifscrub(ifp, ia);
386	error = in_ifinit(ifp, ia, sin, newifaddr);
387	if (!error)
388		if_addrhooks_run(ifp);
389
390	KERNEL_UNLOCK();
391	NET_UNLOCK();
392	return error;
393}
394
395int
396in_ioctl_change_ifaddr(u_long cmd, caddr_t data, struct ifnet *ifp)
397{
398	struct ifaddr *ifa;
399	struct in_ifaddr *ia = NULL;
400	struct in_aliasreq *ifra = (struct in_aliasreq *)data;
401	struct sockaddr_in *sin = NULL, *dstsin = NULL, *broadsin = NULL;
402	struct sockaddr_in *masksin = NULL;
403	int error = 0;
404	int newifaddr;
405
406	if (ifra->ifra_addr.sin_family == AF_INET) {
407		error = in_sa2sin(sintosa(&ifra->ifra_addr), &sin);
408		if (error)
409			return (error);
410	}
411
412	NET_LOCK();
413	KERNEL_LOCK();
414
415	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
416		if (ifa->ifa_addr->sa_family != AF_INET)
417			continue;
418		/* find first address, if no exact match wanted */
419		if (sin == NULL || sin->sin_addr.s_addr ==
420		    ifatoia(ifa)->ia_addr.sin_addr.s_addr) {
421			ia = ifatoia(ifa);
422			break;
423		}
424	}
425
426	switch (cmd) {
427	case SIOCAIFADDR: {
428		int needinit = 0;
429
430		if (ifra->ifra_mask.sin_len) {
431			if (ifra->ifra_mask.sin_len < 8) {
432				error = EINVAL;
433				break;
434			}
435			/* do not check inet family or strict len */
436			masksin = &ifra->ifra_mask;
437			if (ntohl(masksin->sin_addr.s_addr) &
438			    (~ntohl(masksin->sin_addr.s_addr) >> 1)) {
439				/* non-contiguous netmask */
440				error = EINVAL;
441				break;
442			}
443		}
444		if ((ifp->if_flags & IFF_POINTOPOINT) &&
445		    ifra->ifra_dstaddr.sin_family == AF_INET) {
446			error = in_sa2sin(sintosa(&ifra->ifra_dstaddr),
447			    &dstsin);
448			if (error)
449				break;
450		}
451		if ((ifp->if_flags & IFF_BROADCAST) &&
452		    ifra->ifra_broadaddr.sin_family == AF_INET) {
453			error = in_sa2sin(sintosa(&ifra->ifra_broadaddr),
454			    &broadsin);
455			if (error)
456				break;
457		}
458
459		if (ia == NULL) {
460			ia = malloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO);
461			refcnt_init_trace(&ia->ia_ifa.ifa_refcnt,
462			    DT_REFCNT_IDX_IFADDR);
463			ia->ia_addr.sin_family = AF_INET;
464			ia->ia_addr.sin_len = sizeof(ia->ia_addr);
465			ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
466			ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
467			ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
468			ia->ia_sockmask.sin_len = 8;
469			if (ifp->if_flags & IFF_BROADCAST) {
470				ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
471				ia->ia_broadaddr.sin_family = AF_INET;
472			}
473			ia->ia_ifp = ifp;
474
475			newifaddr = 1;
476		} else
477			newifaddr = 0;
478
479		if (sin == NULL) {
480			sin = &ia->ia_addr;
481		} else if (newifaddr ||
482		    sin->sin_addr.s_addr != ia->ia_addr.sin_addr.s_addr) {
483			needinit = 1;
484		}
485		if (masksin != NULL) {
486			in_ifscrub(ifp, ia);
487			ia->ia_netmask = ia->ia_sockmask.sin_addr.s_addr =
488			    masksin->sin_addr.s_addr;
489			needinit = 1;
490		}
491		if (dstsin != NULL) {
492			in_ifscrub(ifp, ia);
493			ia->ia_dstaddr = *dstsin;
494			needinit = 1;
495		}
496		if (broadsin != NULL) {
497			if (newifaddr)
498				ia->ia_broadaddr = *broadsin;
499			else
500				ifa_update_broadaddr(ifp, &ia->ia_ifa,
501				    sintosa(broadsin));
502		}
503		if (needinit) {
504			error = in_ifinit(ifp, ia, sin, newifaddr);
505			if (error)
506				break;
507		}
508		if_addrhooks_run(ifp);
509		break;
510	    }
511	case SIOCDIFADDR:
512		if (ia == NULL) {
513			error = EADDRNOTAVAIL;
514			break;
515		}
516		/*
517		 * Even if the individual steps were safe, shouldn't
518		 * these kinds of changes happen atomically?  What
519		 * should happen to a packet that was routed after
520		 * the scrub but before the other steps?
521		 */
522		in_purgeaddr(&ia->ia_ifa);
523		if_addrhooks_run(ifp);
524		break;
525
526	default:
527		panic("%s: invalid ioctl %lu", __func__, cmd);
528	}
529
530	KERNEL_UNLOCK();
531	NET_UNLOCK();
532	return (error);
533}
534
535int
536in_ioctl_get(u_long cmd, caddr_t data, struct ifnet *ifp)
537{
538	struct ifreq *ifr = (struct ifreq *)data;
539	struct ifaddr *ifa;
540	struct in_ifaddr *ia = NULL;
541	struct sockaddr *sa;
542	struct sockaddr_in *sin = NULL;
543	int error = 0;
544
545	sa = &ifr->ifr_addr;
546	if (sa->sa_family == AF_INET) {
547		sa->sa_len = sizeof(struct sockaddr_in);
548		error = in_sa2sin(sa, &sin);
549		if (error)
550			return (error);
551	}
552
553	NET_LOCK_SHARED();
554
555	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
556		if (ifa->ifa_addr->sa_family != AF_INET)
557			continue;
558		/* find first address or exact match */
559		if (ia == NULL)
560			ia = ifatoia(ifa);
561		if (sin == NULL || sin->sin_addr.s_addr == INADDR_ANY)
562			break;
563		if (ifatoia(ifa)->ia_addr.sin_addr.s_addr ==
564		    sin->sin_addr.s_addr) {
565			ia = ifatoia(ifa);
566			break;
567		}
568	}
569	if (ia == NULL) {
570		error = EADDRNOTAVAIL;
571		goto err;
572	}
573
574	switch(cmd) {
575	case SIOCGIFADDR:
576		*satosin(&ifr->ifr_addr) = ia->ia_addr;
577		break;
578
579	case SIOCGIFBRDADDR:
580		if ((ifp->if_flags & IFF_BROADCAST) == 0) {
581			error = EINVAL;
582			break;
583		}
584		*satosin(&ifr->ifr_dstaddr) = ia->ia_broadaddr;
585		break;
586
587	case SIOCGIFDSTADDR:
588		if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
589			error = EINVAL;
590			break;
591		}
592		*satosin(&ifr->ifr_dstaddr) = ia->ia_dstaddr;
593		break;
594
595	case SIOCGIFNETMASK:
596		*satosin(&ifr->ifr_addr) = ia->ia_sockmask;
597		break;
598
599	default:
600		panic("%s: invalid ioctl %lu", __func__, cmd);
601	}
602
603err:
604	NET_UNLOCK_SHARED();
605	return (error);
606}
607
608/*
609 * Delete any existing route for an interface.
610 */
611void
612in_ifscrub(struct ifnet *ifp, struct in_ifaddr *ia)
613{
614	if (ISSET(ifp->if_flags, IFF_POINTOPOINT))
615		in_scrubhost(ia, &ia->ia_dstaddr);
616	else if (!ISSET(ifp->if_flags, IFF_LOOPBACK))
617		in_remove_prefix(ia);
618}
619
620/*
621 * Initialize an interface's internet address
622 * and routing table entry.
623 */
624int
625in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
626    int newaddr)
627{
628	u_int32_t i = sin->sin_addr.s_addr;
629	struct sockaddr_in oldaddr;
630	int error = 0, rterror;
631
632	NET_ASSERT_LOCKED();
633
634	/*
635	 * Always remove the address from the tree to make sure its
636	 * position gets updated in case the key changes.
637	 */
638	if (!newaddr) {
639		rt_ifa_dellocal(&ia->ia_ifa);
640		ifa_del(ifp, &ia->ia_ifa);
641	}
642	oldaddr = ia->ia_addr;
643	ia->ia_addr = *sin;
644
645	if (ia->ia_netmask == 0) {
646		if (IN_CLASSA(i))
647			ia->ia_netmask = IN_CLASSA_NET;
648		else if (IN_CLASSB(i))
649			ia->ia_netmask = IN_CLASSB_NET;
650		else
651			ia->ia_netmask = IN_CLASSC_NET;
652		ia->ia_sockmask.sin_addr.s_addr = ia->ia_netmask;
653	}
654
655	/*
656	 * Give the interface a chance to initialize
657	 * if this is its first address,
658	 * and to validate the address if necessary.
659	 */
660	if ((error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
661		ia->ia_addr = oldaddr;
662	}
663
664	/*
665	 * Add the address to the local list and the global tree.  If an
666	 * error occurred, put back the original address.
667	 */
668	ifa_add(ifp, &ia->ia_ifa);
669	rterror = rt_ifa_addlocal(&ia->ia_ifa);
670
671	if (rterror) {
672		if (!newaddr)
673			ifa_del(ifp, &ia->ia_ifa);
674		if (!error)
675			error = rterror;
676		goto out;
677	}
678	if (error)
679		goto out;
680
681
682	ia->ia_net = i & ia->ia_netmask;
683	in_socktrim(&ia->ia_sockmask);
684	/*
685	 * Add route for the network.
686	 */
687	ia->ia_ifa.ifa_metric = ifp->if_metric;
688	if (ISSET(ifp->if_flags, IFF_BROADCAST)) {
689		if (IN_RFC3021_SUBNET(ia->ia_netmask))
690			ia->ia_broadaddr.sin_addr.s_addr = 0;
691		else {
692			ia->ia_broadaddr.sin_addr.s_addr =
693			    ia->ia_net | ~ia->ia_netmask;
694		}
695	}
696
697	if (ISSET(ifp->if_flags, IFF_POINTOPOINT)) {
698		/* XXX We should not even call in_ifinit() in this case. */
699		if (ia->ia_dstaddr.sin_family != AF_INET)
700			goto out;
701		error = in_addhost(ia, &ia->ia_dstaddr);
702	} else if (!ISSET(ifp->if_flags, IFF_LOOPBACK)) {
703		error = in_insert_prefix(ia);
704	}
705
706	/*
707	 * If the interface supports multicast, join the "all hosts"
708	 * multicast group on that interface.
709	 */
710	if ((ifp->if_flags & IFF_MULTICAST) && ia->ia_allhosts == NULL) {
711		struct in_addr addr;
712
713		addr.s_addr = INADDR_ALLHOSTS_GROUP;
714		ia->ia_allhosts = in_addmulti(&addr, ifp);
715	}
716
717out:
718	if (error && newaddr)
719		in_purgeaddr(&ia->ia_ifa);
720
721	return (error);
722}
723
724void
725in_purgeaddr(struct ifaddr *ifa)
726{
727	struct ifnet *ifp = ifa->ifa_ifp;
728	struct in_ifaddr *ia = ifatoia(ifa);
729
730	NET_ASSERT_LOCKED();
731
732	in_ifscrub(ifp, ia);
733
734	rt_ifa_dellocal(&ia->ia_ifa);
735	rt_ifa_purge(&ia->ia_ifa);
736	ifa_del(ifp, &ia->ia_ifa);
737
738	if (ia->ia_allhosts != NULL) {
739		in_delmulti(ia->ia_allhosts);
740		ia->ia_allhosts = NULL;
741	}
742
743	ia->ia_ifp = NULL;
744	ifafree(&ia->ia_ifa);
745}
746
747int
748in_addhost(struct in_ifaddr *ia, struct sockaddr_in *dst)
749{
750	return rt_ifa_add(&ia->ia_ifa, RTF_HOST | RTF_MPATH,
751	    sintosa(dst), ia->ia_ifa.ifa_ifp->if_rdomain);
752}
753
754int
755in_scrubhost(struct in_ifaddr *ia, struct sockaddr_in *dst)
756{
757	return rt_ifa_del(&ia->ia_ifa, RTF_HOST,
758	    sintosa(dst), ia->ia_ifa.ifa_ifp->if_rdomain);
759}
760
761/*
762 * Insert the cloning and broadcast routes for this subnet.
763 */
764int
765in_insert_prefix(struct in_ifaddr *ia)
766{
767	struct ifaddr *ifa = &ia->ia_ifa;
768	int error;
769
770	error = rt_ifa_add(ifa, RTF_CLONING | RTF_CONNECTED | RTF_MPATH,
771	    ifa->ifa_addr, ifa->ifa_ifp->if_rdomain);
772	if (error)
773		return (error);
774
775	if (ia->ia_broadaddr.sin_addr.s_addr != 0) {
776		error = rt_ifa_add(ifa, RTF_HOST | RTF_BROADCAST | RTF_MPATH,
777		    ifa->ifa_broadaddr, ifa->ifa_ifp->if_rdomain);
778	}
779
780	return (error);
781}
782
783void
784in_remove_prefix(struct in_ifaddr *ia)
785{
786	struct ifaddr *ifa = &ia->ia_ifa;
787
788	rt_ifa_del(ifa, RTF_CLONING | RTF_CONNECTED,
789	    ifa->ifa_addr, ifa->ifa_ifp->if_rdomain);
790
791	if (ia->ia_broadaddr.sin_addr.s_addr != 0) {
792		rt_ifa_del(ifa, RTF_HOST | RTF_BROADCAST,
793		    ifa->ifa_broadaddr, ifa->ifa_ifp->if_rdomain);
794	}
795}
796
797/*
798 * Return 1 if the address is a local broadcast address.
799 */
800int
801in_broadcast(struct in_addr in, u_int rtableid)
802{
803	struct ifnet *ifn;
804	struct ifaddr *ifa;
805	u_int rdomain;
806
807	rdomain = rtable_l2(rtableid);
808
809#define ia (ifatoia(ifa))
810	TAILQ_FOREACH(ifn, &ifnetlist, if_list) {
811		if (ifn->if_rdomain != rdomain)
812			continue;
813		if ((ifn->if_flags & IFF_BROADCAST) == 0)
814			continue;
815		TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list)
816			if (ifa->ifa_addr->sa_family == AF_INET &&
817			    in.s_addr != ia->ia_addr.sin_addr.s_addr &&
818			    in.s_addr == ia->ia_broadaddr.sin_addr.s_addr)
819				return 1;
820	}
821	return (0);
822#undef ia
823}
824
825/*
826 * Add an address to the list of IP multicast addresses for a given interface.
827 */
828struct in_multi *
829in_addmulti(struct in_addr *ap, struct ifnet *ifp)
830{
831	struct in_multi *inm;
832	struct ifreq ifr;
833
834	/*
835	 * See if address already in list.
836	 */
837	IN_LOOKUP_MULTI(*ap, ifp, inm);
838	if (inm != NULL) {
839		/*
840		 * Found it; just increment the reference count.
841		 */
842		refcnt_take(&inm->inm_refcnt);
843	} else {
844		/*
845		 * New address; allocate a new multicast record
846		 * and link it into the interface's multicast list.
847		 */
848		inm = malloc(sizeof(*inm), M_IPMADDR, M_WAITOK | M_ZERO);
849		inm->inm_sin.sin_len = sizeof(struct sockaddr_in);
850		inm->inm_sin.sin_family = AF_INET;
851		inm->inm_sin.sin_addr = *ap;
852		refcnt_init_trace(&inm->inm_refcnt, DT_REFCNT_IDX_IFMADDR);
853		inm->inm_ifidx = ifp->if_index;
854		inm->inm_ifma.ifma_addr = sintosa(&inm->inm_sin);
855
856		/*
857		 * Ask the network driver to update its multicast reception
858		 * filter appropriately for the new address.
859		 */
860		memset(&ifr, 0, sizeof(ifr));
861		memcpy(&ifr.ifr_addr, &inm->inm_sin, sizeof(inm->inm_sin));
862		KERNEL_LOCK();
863		if ((*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) {
864			KERNEL_UNLOCK();
865			free(inm, M_IPMADDR, sizeof(*inm));
866			return (NULL);
867		}
868		KERNEL_UNLOCK();
869
870		TAILQ_INSERT_HEAD(&ifp->if_maddrlist, &inm->inm_ifma,
871		    ifma_list);
872
873		/*
874		 * Let IGMP know that we have joined a new IP multicast group.
875		 */
876		igmp_joingroup(inm, ifp);
877	}
878
879	return (inm);
880}
881
882/*
883 * Delete a multicast address record.
884 */
885void
886in_delmulti(struct in_multi *inm)
887{
888	struct ifreq ifr;
889	struct ifnet *ifp;
890
891	NET_ASSERT_LOCKED();
892
893	if (refcnt_rele(&inm->inm_refcnt) == 0)
894		return;
895
896	ifp = if_get(inm->inm_ifidx);
897	if (ifp != NULL) {
898		/*
899		 * No remaining claims to this record; let IGMP know that
900		 * we are leaving the multicast group.
901		 */
902		igmp_leavegroup(inm, ifp);
903
904		/*
905		 * Notify the network driver to update its multicast
906		 * reception filter.
907		 */
908		memset(&ifr, 0, sizeof(ifr));
909		satosin(&ifr.ifr_addr)->sin_len = sizeof(struct sockaddr_in);
910		satosin(&ifr.ifr_addr)->sin_family = AF_INET;
911		satosin(&ifr.ifr_addr)->sin_addr = inm->inm_addr;
912		KERNEL_LOCK();
913		(*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr);
914		KERNEL_UNLOCK();
915
916		TAILQ_REMOVE(&ifp->if_maddrlist, &inm->inm_ifma, ifma_list);
917	}
918	if_put(ifp);
919
920	free(inm, M_IPMADDR, sizeof(*inm));
921}
922
923/*
924 * Return 1 if the multicast group represented by ``ap'' has been
925 * joined by interface ``ifp'', 0 otherwise.
926 */
927int
928in_hasmulti(struct in_addr *ap, struct ifnet *ifp)
929{
930	struct in_multi *inm;
931	int joined;
932
933	IN_LOOKUP_MULTI(*ap, ifp, inm);
934	joined = (inm != NULL);
935
936	return (joined);
937}
938
939void
940in_ifdetach(struct ifnet *ifp)
941{
942	struct ifaddr *ifa, *next;
943
944	/* nuke any of IPv4 addresses we have */
945	TAILQ_FOREACH_SAFE(ifa, &ifp->if_addrlist, ifa_list, next) {
946		if (ifa->ifa_addr->sa_family != AF_INET)
947			continue;
948		in_purgeaddr(ifa);
949		if_addrhooks_run(ifp);
950	}
951
952	if (ifp->if_xflags & IFXF_AUTOCONF4)
953		ifp->if_xflags &= ~IFXF_AUTOCONF4;
954}
955
956void
957in_prefixlen2mask(struct in_addr *maskp, int plen)
958{
959	if (plen == 0)
960		maskp->s_addr = 0;
961	else
962		maskp->s_addr = htonl(0xffffffff << (32 - plen));
963}
964