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