xref: /openbsd-src/sys/netinet/in.c (revision 8550894424f8a4aa4aafb6cd57229dd6ed7cd9dd)
1 /*	$OpenBSD: in.c,v 1.179 2022/12/06 22:19:39 mvs 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 
85 void in_socktrim(struct sockaddr_in *);
86 
87 int in_ioctl_set_ifaddr(u_long, caddr_t, struct ifnet *, int);
88 int in_ioctl_change_ifaddr(u_long, caddr_t, struct ifnet *, int);
89 int in_ioctl_get(u_long, caddr_t, struct ifnet *);
90 void in_purgeaddr(struct ifaddr *);
91 int in_addhost(struct in_ifaddr *, struct sockaddr_in *);
92 int in_scrubhost(struct in_ifaddr *, struct sockaddr_in *);
93 int in_insert_prefix(struct in_ifaddr *);
94 void 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  */
101 int
102 in_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  */
120 void
121 in_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 
134 int
135 in_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 
155 void
156 in_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 
169 int
170 in_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 
187 int
188 in_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 
199 int
200 in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
201 {
202 	int privileged;
203 	int error;
204 
205 	privileged = 0;
206 	if ((so->so_state & SS_PRIV) != 0)
207 		privileged++;
208 
209 	switch (cmd) {
210 #ifdef MROUTING
211 	case SIOCGETVIFCNT:
212 	case SIOCGETSGCNT:
213 		KERNEL_LOCK();
214 		error = mrt_ioctl(so, cmd, data);
215 		KERNEL_UNLOCK();
216 		break;
217 #endif /* MROUTING */
218 	default:
219 		KERNEL_LOCK();
220 		error = in_ioctl(cmd, data, ifp, privileged);
221 		KERNEL_UNLOCK();
222 		break;
223 	}
224 
225 	return error;
226 }
227 
228 int
229 in_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
230 {
231 	struct ifreq *ifr = (struct ifreq *)data;
232 	struct ifaddr *ifa;
233 	struct in_ifaddr *ia = NULL;
234 	struct sockaddr_in *sin = NULL, oldaddr;
235 	int error = 0;
236 
237 	if (ifp == NULL)
238 		return (ENXIO);
239 
240 	switch (cmd) {
241 	case SIOCGIFADDR:
242 	case SIOCGIFNETMASK:
243 	case SIOCGIFDSTADDR:
244 	case SIOCGIFBRDADDR:
245 		return in_ioctl_get(cmd, data, ifp);
246 	case SIOCSIFADDR:
247 		return in_ioctl_set_ifaddr(cmd, data, ifp, privileged);
248 	case SIOCAIFADDR:
249 	case SIOCDIFADDR:
250 		return in_ioctl_change_ifaddr(cmd, data, ifp, privileged);
251 	case SIOCSIFNETMASK:
252 	case SIOCSIFDSTADDR:
253 	case SIOCSIFBRDADDR:
254 		break;
255 	default:
256 		return (EOPNOTSUPP);
257 	}
258 
259 	if (ifr->ifr_addr.sa_family == AF_INET) {
260 		error = in_sa2sin(&ifr->ifr_addr, &sin);
261 		if (error)
262 			return (error);
263 	}
264 
265 	NET_LOCK();
266 
267 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
268 		if (ifa->ifa_addr->sa_family != AF_INET)
269 			continue;
270 		/* find first address or exact match */
271 		if (ia == NULL)
272 			ia = ifatoia(ifa);
273 		if (sin == NULL || sin->sin_addr.s_addr == INADDR_ANY)
274 			break;
275 		if (ifatoia(ifa)->ia_addr.sin_addr.s_addr ==
276 		    sin->sin_addr.s_addr) {
277 			ia = ifatoia(ifa);
278 			break;
279 		}
280 	}
281 	if (ia == NULL) {
282 		error = EADDRNOTAVAIL;
283 		goto err;
284 	}
285 
286 	switch (cmd) {
287 	case SIOCSIFDSTADDR:
288 		if (!privileged) {
289 			error = EPERM;
290 			break;
291 		}
292 
293 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
294 			error = EINVAL;
295 			break;
296 		}
297 		error = in_sa2sin(&ifr->ifr_dstaddr, &sin);
298 		if (error)
299 			break;
300 		oldaddr = ia->ia_dstaddr;
301 		ia->ia_dstaddr = *sin;
302 		error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, (caddr_t)ia);
303 		if (error) {
304 			ia->ia_dstaddr = oldaddr;
305 			break;
306 		}
307 		in_scrubhost(ia, &oldaddr);
308 		in_addhost(ia, &ia->ia_dstaddr);
309 		break;
310 
311 	case SIOCSIFBRDADDR:
312 		if (!privileged) {
313 			error = EPERM;
314 			break;
315 		}
316 
317 		if ((ifp->if_flags & IFF_BROADCAST) == 0) {
318 			error = EINVAL;
319 			break;
320 		}
321 		error = in_sa2sin(&ifr->ifr_broadaddr, &sin);
322 		if (error)
323 			break;
324 		ifa_update_broadaddr(ifp, &ia->ia_ifa, sintosa(sin));
325 		break;
326 
327 	case SIOCSIFNETMASK:
328 		if (!privileged) {
329 			error = EPERM;
330 			break;
331 		}
332 
333 		if (ifr->ifr_addr.sa_len < 8) {
334 			error = EINVAL;
335 			break;
336 		}
337 		/* do not check inet family or strict len */
338 		sin = satosin(&ifr->ifr_addr);
339 		if (ntohl(sin->sin_addr.s_addr) &
340 		    (~ntohl(sin->sin_addr.s_addr) >> 1)) {
341 			/* non-contiguous netmask */
342 			error = EINVAL;
343 			break;
344 		}
345 		ia->ia_netmask = ia->ia_sockmask.sin_addr.s_addr =
346 		    sin->sin_addr.s_addr;
347 		break;
348 	}
349 err:
350 	NET_UNLOCK();
351 	return (error);
352 }
353 
354 int
355 in_ioctl_set_ifaddr(u_long cmd, caddr_t data, struct ifnet *ifp,
356     int privileged)
357 {
358 	struct ifreq *ifr = (struct ifreq *)data;
359 	struct ifaddr *ifa;
360 	struct in_ifaddr *ia = NULL;
361 	struct sockaddr_in *sin;
362 	int error = 0;
363 	int newifaddr;
364 
365 	if (cmd != SIOCSIFADDR)
366 		panic("%s: invalid ioctl %lu", __func__, cmd);
367 
368 	if (!privileged)
369 		return (EPERM);
370 
371 	error = in_sa2sin(&ifr->ifr_addr, &sin);
372 	if (error)
373 		return (error);
374 
375 	NET_LOCK();
376 
377 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
378 		if (ifa->ifa_addr->sa_family != AF_INET)
379 			continue;
380 		/* find first address */
381 		ia = ifatoia(ifa);
382 		break;
383 	}
384 	if (ia == NULL) {
385 		ia = malloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO);
386 		refcnt_init_trace(&ia->ia_ifa.ifa_refcnt, DT_REFCNT_IDX_IFADDR);
387 		ia->ia_addr.sin_family = AF_INET;
388 		ia->ia_addr.sin_len = sizeof(ia->ia_addr);
389 		ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
390 		ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
391 		ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
392 		ia->ia_sockmask.sin_len = 8;
393 		if (ifp->if_flags & IFF_BROADCAST) {
394 			ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
395 			ia->ia_broadaddr.sin_family = AF_INET;
396 		}
397 		ia->ia_ifp = ifp;
398 
399 		newifaddr = 1;
400 	} else
401 		newifaddr = 0;
402 
403 	in_ifscrub(ifp, ia);
404 	error = in_ifinit(ifp, ia, sin, newifaddr);
405 	if (!error)
406 		if_addrhooks_run(ifp);
407 
408 	NET_UNLOCK();
409 	return error;
410 }
411 
412 int
413 in_ioctl_change_ifaddr(u_long cmd, caddr_t data, struct ifnet *ifp,
414     int privileged)
415 {
416 	struct ifaddr *ifa;
417 	struct in_ifaddr *ia = NULL;
418 	struct in_aliasreq *ifra = (struct in_aliasreq *)data;
419 	struct sockaddr_in *sin = NULL, *dstsin = NULL, *broadsin = NULL;
420 	struct sockaddr_in *masksin = NULL;
421 	int error = 0;
422 	int newifaddr;
423 
424 	if (ifra->ifra_addr.sin_family == AF_INET) {
425 		error = in_sa2sin(sintosa(&ifra->ifra_addr), &sin);
426 		if (error)
427 			return (error);
428 	}
429 
430 	NET_LOCK();
431 
432 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
433 		if (ifa->ifa_addr->sa_family != AF_INET)
434 			continue;
435 		/* find first address, if no exact match wanted */
436 		if (sin == NULL || sin->sin_addr.s_addr ==
437 		    ifatoia(ifa)->ia_addr.sin_addr.s_addr) {
438 			ia = ifatoia(ifa);
439 			break;
440 		}
441 	}
442 
443 	switch (cmd) {
444 	case SIOCAIFADDR: {
445 		int needinit = 0;
446 
447 		if (!privileged) {
448 			error = EPERM;
449 			break;
450 		}
451 
452 		if (ifra->ifra_mask.sin_len) {
453 			if (ifra->ifra_mask.sin_len < 8) {
454 				error = EINVAL;
455 				break;
456 			}
457 			/* do not check inet family or strict len */
458 			masksin = &ifra->ifra_mask;
459 			if (ntohl(masksin->sin_addr.s_addr) &
460 			    (~ntohl(masksin->sin_addr.s_addr) >> 1)) {
461 				/* non-contiguous netmask */
462 				error = EINVAL;
463 				break;
464 			}
465 		}
466 		if ((ifp->if_flags & IFF_POINTOPOINT) &&
467 		    ifra->ifra_dstaddr.sin_family == AF_INET) {
468 			error = in_sa2sin(sintosa(&ifra->ifra_dstaddr),
469 			    &dstsin);
470 			if (error)
471 				break;
472 		}
473 		if ((ifp->if_flags & IFF_BROADCAST) &&
474 		    ifra->ifra_broadaddr.sin_family == AF_INET) {
475 			error = in_sa2sin(sintosa(&ifra->ifra_broadaddr),
476 			    &broadsin);
477 			if (error)
478 				break;
479 		}
480 
481 		if (ia == NULL) {
482 			ia = malloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO);
483 			refcnt_init_trace(&ia->ia_ifa.ifa_refcnt,
484 			    DT_REFCNT_IDX_IFADDR);
485 			ia->ia_addr.sin_family = AF_INET;
486 			ia->ia_addr.sin_len = sizeof(ia->ia_addr);
487 			ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
488 			ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
489 			ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
490 			ia->ia_sockmask.sin_len = 8;
491 			if (ifp->if_flags & IFF_BROADCAST) {
492 				ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
493 				ia->ia_broadaddr.sin_family = AF_INET;
494 			}
495 			ia->ia_ifp = ifp;
496 
497 			newifaddr = 1;
498 		} else
499 			newifaddr = 0;
500 
501 		if (sin == NULL) {
502 			sin = &ia->ia_addr;
503 		} else if (newifaddr ||
504 		    sin->sin_addr.s_addr != ia->ia_addr.sin_addr.s_addr) {
505 			needinit = 1;
506 		}
507 		if (masksin != NULL) {
508 			in_ifscrub(ifp, ia);
509 			ia->ia_netmask = ia->ia_sockmask.sin_addr.s_addr =
510 			    masksin->sin_addr.s_addr;
511 			needinit = 1;
512 		}
513 		if (dstsin != NULL) {
514 			in_ifscrub(ifp, ia);
515 			ia->ia_dstaddr = *dstsin;
516 			needinit = 1;
517 		}
518 		if (broadsin != NULL) {
519 			if (newifaddr)
520 				ia->ia_broadaddr = *broadsin;
521 			else
522 				ifa_update_broadaddr(ifp, &ia->ia_ifa,
523 				    sintosa(broadsin));
524 		}
525 		if (needinit) {
526 			error = in_ifinit(ifp, ia, sin, newifaddr);
527 			if (error)
528 				break;
529 		}
530 		if_addrhooks_run(ifp);
531 		break;
532 	    }
533 	case SIOCDIFADDR:
534 		if (!privileged) {
535 			error = EPERM;
536 			break;
537 		}
538 
539 		if (ia == NULL) {
540 			error = EADDRNOTAVAIL;
541 			break;
542 		}
543 		/*
544 		 * Even if the individual steps were safe, shouldn't
545 		 * these kinds of changes happen atomically?  What
546 		 * should happen to a packet that was routed after
547 		 * the scrub but before the other steps?
548 		 */
549 		in_purgeaddr(&ia->ia_ifa);
550 		if_addrhooks_run(ifp);
551 		break;
552 
553 	default:
554 		panic("%s: invalid ioctl %lu", __func__, cmd);
555 	}
556 
557 	NET_UNLOCK();
558 	return (error);
559 }
560 
561 int
562 in_ioctl_get(u_long cmd, caddr_t data, struct ifnet *ifp)
563 {
564 	struct ifreq *ifr = (struct ifreq *)data;
565 	struct ifaddr *ifa;
566 	struct in_ifaddr *ia = NULL;
567 	struct sockaddr *sa;
568 	struct sockaddr_in *sin = NULL;
569 	int error = 0;
570 
571 	sa = &ifr->ifr_addr;
572 	if (sa->sa_family == AF_INET) {
573 		sa->sa_len = sizeof(struct sockaddr_in);
574 		error = in_sa2sin(sa, &sin);
575 		if (error)
576 			return (error);
577 	}
578 
579 	NET_LOCK_SHARED();
580 
581 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
582 		if (ifa->ifa_addr->sa_family != AF_INET)
583 			continue;
584 		/* find first address or exact match */
585 		if (ia == NULL)
586 			ia = ifatoia(ifa);
587 		if (sin == NULL || sin->sin_addr.s_addr == INADDR_ANY)
588 			break;
589 		if (ifatoia(ifa)->ia_addr.sin_addr.s_addr ==
590 		    sin->sin_addr.s_addr) {
591 			ia = ifatoia(ifa);
592 			break;
593 		}
594 	}
595 	if (ia == NULL) {
596 		error = EADDRNOTAVAIL;
597 		goto err;
598 	}
599 
600 	switch(cmd) {
601 	case SIOCGIFADDR:
602 		*satosin(&ifr->ifr_addr) = ia->ia_addr;
603 		break;
604 
605 	case SIOCGIFBRDADDR:
606 		if ((ifp->if_flags & IFF_BROADCAST) == 0) {
607 			error = EINVAL;
608 			break;
609 		}
610 		*satosin(&ifr->ifr_dstaddr) = ia->ia_broadaddr;
611 		break;
612 
613 	case SIOCGIFDSTADDR:
614 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
615 			error = EINVAL;
616 			break;
617 		}
618 		*satosin(&ifr->ifr_dstaddr) = ia->ia_dstaddr;
619 		break;
620 
621 	case SIOCGIFNETMASK:
622 		*satosin(&ifr->ifr_addr) = ia->ia_sockmask;
623 		break;
624 
625 	default:
626 		panic("%s: invalid ioctl %lu", __func__, cmd);
627 	}
628 
629 err:
630 	NET_UNLOCK_SHARED();
631 	return (error);
632 }
633 
634 /*
635  * Delete any existing route for an interface.
636  */
637 void
638 in_ifscrub(struct ifnet *ifp, struct in_ifaddr *ia)
639 {
640 	if (ISSET(ifp->if_flags, IFF_POINTOPOINT))
641 		in_scrubhost(ia, &ia->ia_dstaddr);
642 	else if (!ISSET(ifp->if_flags, IFF_LOOPBACK))
643 		in_remove_prefix(ia);
644 }
645 
646 /*
647  * Initialize an interface's internet address
648  * and routing table entry.
649  */
650 int
651 in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
652     int newaddr)
653 {
654 	u_int32_t i = sin->sin_addr.s_addr;
655 	struct sockaddr_in oldaddr;
656 	int error = 0, rterror;
657 
658 	NET_ASSERT_LOCKED();
659 
660 	/*
661 	 * Always remove the address from the tree to make sure its
662 	 * position gets updated in case the key changes.
663 	 */
664 	if (!newaddr) {
665 		rt_ifa_dellocal(&ia->ia_ifa);
666 		ifa_del(ifp, &ia->ia_ifa);
667 	}
668 	oldaddr = ia->ia_addr;
669 	ia->ia_addr = *sin;
670 
671 	if (ia->ia_netmask == 0) {
672 		if (IN_CLASSA(i))
673 			ia->ia_netmask = IN_CLASSA_NET;
674 		else if (IN_CLASSB(i))
675 			ia->ia_netmask = IN_CLASSB_NET;
676 		else
677 			ia->ia_netmask = IN_CLASSC_NET;
678 		ia->ia_sockmask.sin_addr.s_addr = ia->ia_netmask;
679 	}
680 
681 	/*
682 	 * Give the interface a chance to initialize
683 	 * if this is its first address,
684 	 * and to validate the address if necessary.
685 	 */
686 	if ((error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
687 		ia->ia_addr = oldaddr;
688 	}
689 
690 	/*
691 	 * Add the address to the local list and the global tree.  If an
692 	 * error occurred, put back the original address.
693 	 */
694 	ifa_add(ifp, &ia->ia_ifa);
695 	rterror = rt_ifa_addlocal(&ia->ia_ifa);
696 
697 	if (rterror) {
698 		if (!newaddr)
699 			ifa_del(ifp, &ia->ia_ifa);
700 		if (!error)
701 			error = rterror;
702 		goto out;
703 	}
704 	if (error)
705 		goto out;
706 
707 
708 	ia->ia_net = i & ia->ia_netmask;
709 	in_socktrim(&ia->ia_sockmask);
710 	/*
711 	 * Add route for the network.
712 	 */
713 	ia->ia_ifa.ifa_metric = ifp->if_metric;
714 	if (ISSET(ifp->if_flags, IFF_BROADCAST)) {
715 		if (IN_RFC3021_SUBNET(ia->ia_netmask))
716 			ia->ia_broadaddr.sin_addr.s_addr = 0;
717 		else {
718 			ia->ia_broadaddr.sin_addr.s_addr =
719 			    ia->ia_net | ~ia->ia_netmask;
720 		}
721 	}
722 
723 	if (ISSET(ifp->if_flags, IFF_POINTOPOINT)) {
724 		/* XXX We should not even call in_ifinit() in this case. */
725 		if (ia->ia_dstaddr.sin_family != AF_INET)
726 			goto out;
727 		error = in_addhost(ia, &ia->ia_dstaddr);
728 	} else if (!ISSET(ifp->if_flags, IFF_LOOPBACK)) {
729 		error = in_insert_prefix(ia);
730 	}
731 
732 	/*
733 	 * If the interface supports multicast, join the "all hosts"
734 	 * multicast group on that interface.
735 	 */
736 	if ((ifp->if_flags & IFF_MULTICAST) && ia->ia_allhosts == NULL) {
737 		struct in_addr addr;
738 
739 		addr.s_addr = INADDR_ALLHOSTS_GROUP;
740 		ia->ia_allhosts = in_addmulti(&addr, ifp);
741 	}
742 
743 out:
744 	if (error && newaddr)
745 		in_purgeaddr(&ia->ia_ifa);
746 
747 	return (error);
748 }
749 
750 void
751 in_purgeaddr(struct ifaddr *ifa)
752 {
753 	struct ifnet *ifp = ifa->ifa_ifp;
754 	struct in_ifaddr *ia = ifatoia(ifa);
755 
756 	NET_ASSERT_LOCKED();
757 
758 	in_ifscrub(ifp, ia);
759 
760 	rt_ifa_dellocal(&ia->ia_ifa);
761 	rt_ifa_purge(&ia->ia_ifa);
762 	ifa_del(ifp, &ia->ia_ifa);
763 
764 	if (ia->ia_allhosts != NULL) {
765 		in_delmulti(ia->ia_allhosts);
766 		ia->ia_allhosts = NULL;
767 	}
768 
769 	ia->ia_ifp = NULL;
770 	ifafree(&ia->ia_ifa);
771 }
772 
773 int
774 in_addhost(struct in_ifaddr *ia, struct sockaddr_in *dst)
775 {
776 	return rt_ifa_add(&ia->ia_ifa, RTF_HOST | RTF_MPATH,
777 	    sintosa(dst), ia->ia_ifa.ifa_ifp->if_rdomain);
778 }
779 
780 int
781 in_scrubhost(struct in_ifaddr *ia, struct sockaddr_in *dst)
782 {
783 	return rt_ifa_del(&ia->ia_ifa, RTF_HOST,
784 	    sintosa(dst), ia->ia_ifa.ifa_ifp->if_rdomain);
785 }
786 
787 /*
788  * Insert the cloning and broadcast routes for this subnet.
789  */
790 int
791 in_insert_prefix(struct in_ifaddr *ia)
792 {
793 	struct ifaddr *ifa = &ia->ia_ifa;
794 	int error;
795 
796 	error = rt_ifa_add(ifa, RTF_CLONING | RTF_CONNECTED | RTF_MPATH,
797 	    ifa->ifa_addr, ifa->ifa_ifp->if_rdomain);
798 	if (error)
799 		return (error);
800 
801 	if (ia->ia_broadaddr.sin_addr.s_addr != 0) {
802 		error = rt_ifa_add(ifa, RTF_HOST | RTF_BROADCAST | RTF_MPATH,
803 		    ifa->ifa_broadaddr, ifa->ifa_ifp->if_rdomain);
804 	}
805 
806 	return (error);
807 }
808 
809 void
810 in_remove_prefix(struct in_ifaddr *ia)
811 {
812 	struct ifaddr *ifa = &ia->ia_ifa;
813 
814 	rt_ifa_del(ifa, RTF_CLONING | RTF_CONNECTED,
815 	    ifa->ifa_addr, ifa->ifa_ifp->if_rdomain);
816 
817 	if (ia->ia_broadaddr.sin_addr.s_addr != 0) {
818 		rt_ifa_del(ifa, RTF_HOST | RTF_BROADCAST,
819 		    ifa->ifa_broadaddr, ifa->ifa_ifp->if_rdomain);
820 	}
821 }
822 
823 /*
824  * Return 1 if the address is a local broadcast address.
825  */
826 int
827 in_broadcast(struct in_addr in, u_int rtableid)
828 {
829 	struct ifnet *ifn;
830 	struct ifaddr *ifa;
831 	u_int rdomain;
832 
833 	rdomain = rtable_l2(rtableid);
834 
835 #define ia (ifatoia(ifa))
836 	TAILQ_FOREACH(ifn, &ifnetlist, if_list) {
837 		if (ifn->if_rdomain != rdomain)
838 			continue;
839 		if ((ifn->if_flags & IFF_BROADCAST) == 0)
840 			continue;
841 		TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list)
842 			if (ifa->ifa_addr->sa_family == AF_INET &&
843 			    in.s_addr != ia->ia_addr.sin_addr.s_addr &&
844 			    in.s_addr == ia->ia_broadaddr.sin_addr.s_addr)
845 				return 1;
846 	}
847 	return (0);
848 #undef ia
849 }
850 
851 /*
852  * Add an address to the list of IP multicast addresses for a given interface.
853  */
854 struct in_multi *
855 in_addmulti(struct in_addr *ap, struct ifnet *ifp)
856 {
857 	struct in_multi *inm;
858 	struct ifreq ifr;
859 
860 	/*
861 	 * See if address already in list.
862 	 */
863 	IN_LOOKUP_MULTI(*ap, ifp, inm);
864 	if (inm != NULL) {
865 		/*
866 		 * Found it; just increment the reference count.
867 		 */
868 		++inm->inm_refcnt;
869 	} else {
870 		/*
871 		 * New address; allocate a new multicast record
872 		 * and link it into the interface's multicast list.
873 		 */
874 		inm = malloc(sizeof(*inm), M_IPMADDR, M_WAITOK | M_ZERO);
875 		inm->inm_sin.sin_len = sizeof(struct sockaddr_in);
876 		inm->inm_sin.sin_family = AF_INET;
877 		inm->inm_sin.sin_addr = *ap;
878 		inm->inm_refcnt = 1;
879 		inm->inm_ifidx = ifp->if_index;
880 		inm->inm_ifma.ifma_addr = sintosa(&inm->inm_sin);
881 
882 		/*
883 		 * Ask the network driver to update its multicast reception
884 		 * filter appropriately for the new address.
885 		 */
886 		memset(&ifr, 0, sizeof(ifr));
887 		memcpy(&ifr.ifr_addr, &inm->inm_sin, sizeof(inm->inm_sin));
888 		KERNEL_LOCK();
889 		if ((*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) {
890 			KERNEL_UNLOCK();
891 			free(inm, M_IPMADDR, sizeof(*inm));
892 			return (NULL);
893 		}
894 		KERNEL_UNLOCK();
895 
896 		TAILQ_INSERT_HEAD(&ifp->if_maddrlist, &inm->inm_ifma,
897 		    ifma_list);
898 
899 		/*
900 		 * Let IGMP know that we have joined a new IP multicast group.
901 		 */
902 		igmp_joingroup(inm, ifp);
903 	}
904 
905 	return (inm);
906 }
907 
908 /*
909  * Delete a multicast address record.
910  */
911 void
912 in_delmulti(struct in_multi *inm)
913 {
914 	struct ifreq ifr;
915 	struct ifnet *ifp;
916 
917 	NET_ASSERT_LOCKED();
918 
919 	if (--inm->inm_refcnt != 0)
920 		return;
921 
922 	ifp = if_get(inm->inm_ifidx);
923 	if (ifp != NULL) {
924 		/*
925 		 * No remaining claims to this record; let IGMP know that
926 		 * we are leaving the multicast group.
927 		 */
928 		igmp_leavegroup(inm, ifp);
929 
930 		/*
931 		 * Notify the network driver to update its multicast
932 		 * reception filter.
933 		 */
934 		memset(&ifr, 0, sizeof(ifr));
935 		satosin(&ifr.ifr_addr)->sin_len = sizeof(struct sockaddr_in);
936 		satosin(&ifr.ifr_addr)->sin_family = AF_INET;
937 		satosin(&ifr.ifr_addr)->sin_addr = inm->inm_addr;
938 		KERNEL_LOCK();
939 		(*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr);
940 		KERNEL_UNLOCK();
941 
942 		TAILQ_REMOVE(&ifp->if_maddrlist, &inm->inm_ifma, ifma_list);
943 	}
944 	if_put(ifp);
945 
946 	free(inm, M_IPMADDR, sizeof(*inm));
947 }
948 
949 /*
950  * Return 1 if the multicast group represented by ``ap'' has been
951  * joined by interface ``ifp'', 0 otherwise.
952  */
953 int
954 in_hasmulti(struct in_addr *ap, struct ifnet *ifp)
955 {
956 	struct in_multi *inm;
957 	int joined;
958 
959 	IN_LOOKUP_MULTI(*ap, ifp, inm);
960 	joined = (inm != NULL);
961 
962 	return (joined);
963 }
964 
965 void
966 in_ifdetach(struct ifnet *ifp)
967 {
968 	struct ifaddr *ifa, *next;
969 
970 	/* nuke any of IPv4 addresses we have */
971 	TAILQ_FOREACH_SAFE(ifa, &ifp->if_addrlist, ifa_list, next) {
972 		if (ifa->ifa_addr->sa_family != AF_INET)
973 			continue;
974 		in_purgeaddr(ifa);
975 		if_addrhooks_run(ifp);
976 	}
977 
978 	if (ifp->if_xflags & IFXF_AUTOCONF4)
979 		ifp->if_xflags &= ~IFXF_AUTOCONF4;
980 }
981 
982 void
983 in_prefixlen2mask(struct in_addr *maskp, int plen)
984 {
985 	if (plen == 0)
986 		maskp->s_addr = 0;
987 	else
988 		maskp->s_addr = htonl(0xffffffff << (32 - plen));
989 }
990