xref: /openbsd-src/sys/netinet/in.c (revision f763167468dba5339ed4b14b7ecaca2a397ab0f6)
1 /*	$OpenBSD: in.c,v 1.140 2017/08/11 19:53:02 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 
85 void in_socktrim(struct sockaddr_in *);
86 int in_lifaddr_ioctl(u_long, caddr_t, struct ifnet *, int);
87 
88 void in_purgeaddr(struct ifaddr *);
89 int in_addhost(struct in_ifaddr *, struct sockaddr_in *);
90 int in_scrubhost(struct in_ifaddr *, struct sockaddr_in *);
91 int in_insert_prefix(struct in_ifaddr *);
92 void in_remove_prefix(struct in_ifaddr *);
93 
94 /*
95  * Determine whether an IP address is in a reserved set of addresses
96  * that may not be forwarded, or whether datagrams to that destination
97  * may be forwarded.
98  */
99 int
100 in_canforward(struct in_addr in)
101 {
102 	u_int32_t net;
103 
104 	if (IN_EXPERIMENTAL(in.s_addr) || IN_MULTICAST(in.s_addr))
105 		return (0);
106 	if (IN_CLASSA(in.s_addr)) {
107 		net = in.s_addr & IN_CLASSA_NET;
108 		if (net == 0 ||
109 		    net == htonl(IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
110 			return (0);
111 	}
112 	return (1);
113 }
114 
115 /*
116  * Trim a mask in a sockaddr
117  */
118 void
119 in_socktrim(struct sockaddr_in *ap)
120 {
121 	char *cplim = (char *) &ap->sin_addr;
122 	char *cp = (char *) (&ap->sin_addr + 1);
123 
124 	ap->sin_len = 0;
125 	while (--cp >= cplim)
126 		if (*cp) {
127 			(ap)->sin_len = cp - (char *) (ap) + 1;
128 			break;
129 		}
130 }
131 
132 int
133 in_mask2len(struct in_addr *mask)
134 {
135 	int x, y;
136 	u_char *p;
137 
138 	p = (u_char *)mask;
139 	for (x = 0; x < sizeof(*mask); x++) {
140 		if (p[x] != 0xff)
141 			break;
142 	}
143 	y = 0;
144 	if (x < sizeof(*mask)) {
145 		for (y = 0; y < 8; y++) {
146 			if ((p[x] & (0x80 >> y)) == 0)
147 				break;
148 		}
149 	}
150 	return x * 8 + y;
151 }
152 
153 void
154 in_len2mask(struct in_addr *mask, int len)
155 {
156 	int i;
157 	u_char *p;
158 
159 	p = (u_char *)mask;
160 	bzero(mask, sizeof(*mask));
161 	for (i = 0; i < len / 8; i++)
162 		p[i] = 0xff;
163 	if (len % 8)
164 		p[i] = (0xff00 >> (len % 8)) & 0xff;
165 }
166 
167 int
168 in_nam2sin(const struct mbuf *nam, struct sockaddr_in **sin)
169 {
170 	struct sockaddr *sa = mtod(nam, struct sockaddr *);
171 
172 	if (nam->m_len < offsetof(struct sockaddr, sa_data))
173 		return EINVAL;
174 	if (sa->sa_family != AF_INET)
175 		return EAFNOSUPPORT;
176 	if (sa->sa_len != nam->m_len)
177 		return EINVAL;
178 	if (sa->sa_len != sizeof(struct sockaddr_in))
179 		return EINVAL;
180 	*sin = satosin(sa);
181 
182 	return 0;
183 }
184 
185 /*
186  * Generic internet control operations (ioctl's).
187  */
188 int
189 in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp)
190 {
191 	int privileged;
192 
193 	privileged = 0;
194 	if ((so->so_state & SS_PRIV) != 0)
195 		privileged++;
196 
197 	switch (cmd) {
198 #ifdef MROUTING
199 	case SIOCGETVIFCNT:
200 	case SIOCGETSGCNT:
201 		return (mrt_ioctl(so, cmd, data));
202 #endif /* MROUTING */
203 	case SIOCALIFADDR:
204 	case SIOCDLIFADDR:
205 		if (!privileged)
206 			return (EPERM);
207 		/* FALLTHROUGH */
208 	case SIOCGLIFADDR:
209 		if (ifp == NULL)
210 			return (EINVAL);
211 		return in_lifaddr_ioctl(cmd, data, ifp, privileged);
212 	default:
213 		if (ifp == NULL)
214 			return (EOPNOTSUPP);
215 	}
216 
217 	return (in_ioctl(cmd, data, ifp, privileged));
218 }
219 
220 int
221 in_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
222 {
223 	struct ifreq *ifr = (struct ifreq *)data;
224 	struct ifaddr *ifa;
225 	struct in_ifaddr *ia = NULL;
226 	struct in_aliasreq *ifra = (struct in_aliasreq *)data;
227 	struct sockaddr_in oldaddr;
228 	int error;
229 	int newifaddr;
230 
231 	NET_ASSERT_LOCKED();
232 
233 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
234 		if (ifa->ifa_addr->sa_family == AF_INET) {
235 			ia = ifatoia(ifa);
236 			break;
237 		}
238 	}
239 
240 	switch (cmd) {
241 
242 	case SIOCAIFADDR:
243 	case SIOCDIFADDR:
244 		if (ifra->ifra_addr.sin_family == AF_INET) {
245 			for (; ifa != NULL; ifa = TAILQ_NEXT(ifa, ifa_list)) {
246 				if ((ifa->ifa_addr->sa_family == AF_INET) &&
247 				    ifatoia(ifa)->ia_addr.sin_addr.s_addr ==
248 				    ifra->ifra_addr.sin_addr.s_addr)
249 					break;
250 			}
251 			ia = ifatoia(ifa);
252 		}
253 		if (cmd == SIOCDIFADDR && ia == NULL)
254 			return (EADDRNOTAVAIL);
255 		/* FALLTHROUGH */
256 	case SIOCSIFADDR:
257 		if (!privileged)
258 			return (EPERM);
259 
260 		if (ia == NULL) {
261 			ia = malloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO);
262 			ia->ia_addr.sin_family = AF_INET;
263 			ia->ia_addr.sin_len = sizeof(ia->ia_addr);
264 			ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
265 			ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
266 			ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
267 			ia->ia_sockmask.sin_len = 8;
268 			if (ifp->if_flags & IFF_BROADCAST) {
269 				ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
270 				ia->ia_broadaddr.sin_family = AF_INET;
271 			}
272 			ia->ia_ifp = ifp;
273 
274 			newifaddr = 1;
275 		} else
276 			newifaddr = 0;
277 		break;
278 
279 	case SIOCSIFNETMASK:
280 	case SIOCSIFDSTADDR:
281 	case SIOCSIFBRDADDR:
282 		if (!privileged)
283 			return (EPERM);
284 		/* FALLTHROUGH */
285 
286 	case SIOCGIFADDR:
287 	case SIOCGIFNETMASK:
288 	case SIOCGIFDSTADDR:
289 	case SIOCGIFBRDADDR:
290 		if (ia && satosin(&ifr->ifr_addr)->sin_addr.s_addr) {
291 			for (; ifa != NULL; ifa = TAILQ_NEXT(ifa, ifa_list)) {
292 				if ((ifa->ifa_addr->sa_family == AF_INET) &&
293 				    ifatoia(ifa)->ia_addr.sin_addr.s_addr ==
294 				    satosin(&ifr->ifr_addr)->sin_addr.s_addr) {
295 					ia = ifatoia(ifa);
296 					break;
297 				}
298 			}
299 		}
300 		if (ia == NULL)
301 			return (EADDRNOTAVAIL);
302 		break;
303 	}
304 	switch (cmd) {
305 
306 	case SIOCGIFADDR:
307 		*satosin(&ifr->ifr_addr) = ia->ia_addr;
308 		break;
309 
310 	case SIOCGIFBRDADDR:
311 		if ((ifp->if_flags & IFF_BROADCAST) == 0)
312 			return (EINVAL);
313 		*satosin(&ifr->ifr_dstaddr) = ia->ia_broadaddr;
314 		break;
315 
316 	case SIOCGIFDSTADDR:
317 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
318 			return (EINVAL);
319 		*satosin(&ifr->ifr_dstaddr) = ia->ia_dstaddr;
320 		break;
321 
322 	case SIOCGIFNETMASK:
323 		*satosin(&ifr->ifr_addr) = ia->ia_sockmask;
324 		break;
325 
326 	case SIOCSIFDSTADDR:
327 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
328 			return (EINVAL);
329 		oldaddr = ia->ia_dstaddr;
330 		ia->ia_dstaddr = *satosin(&ifr->ifr_dstaddr);
331 		if (ifp->if_ioctl && (error = (*ifp->if_ioctl)
332 					(ifp, SIOCSIFDSTADDR, (caddr_t)ia))) {
333 			ia->ia_dstaddr = oldaddr;
334 			return (error);
335 		}
336 		in_scrubhost(ia, &oldaddr);
337 		in_addhost(ia, &ia->ia_dstaddr);
338 		break;
339 
340 	case SIOCSIFBRDADDR:
341 		if ((ifp->if_flags & IFF_BROADCAST) == 0)
342 			return (EINVAL);
343 		ifa_update_broadaddr(ifp, &ia->ia_ifa, &ifr->ifr_broadaddr);
344 		break;
345 
346 	case SIOCSIFADDR:
347 		in_ifscrub(ifp, ia);
348 		error = in_ifinit(ifp, ia, satosin(&ifr->ifr_addr), newifaddr);
349 		if (!error)
350 			dohooks(ifp->if_addrhooks, 0);
351 		return (error);
352 
353 	case SIOCSIFNETMASK:
354 		ia->ia_netmask = ia->ia_sockmask.sin_addr.s_addr =
355 		    ifra->ifra_addr.sin_addr.s_addr;
356 		break;
357 
358 	case SIOCAIFADDR: {
359 		int needinit = 0;
360 
361 		error = 0;
362 
363 		if (ia->ia_addr.sin_family == AF_INET) {
364 			if (ifra->ifra_addr.sin_len == 0)
365 				ifra->ifra_addr = ia->ia_addr;
366 			else if (ifra->ifra_addr.sin_addr.s_addr !=
367 			    ia->ia_addr.sin_addr.s_addr || newifaddr)
368 				needinit = 1;
369 		}
370 		if (ifra->ifra_mask.sin_len) {
371 			in_ifscrub(ifp, ia);
372 			ia->ia_sockmask = ifra->ifra_mask;
373 			ia->ia_netmask = ia->ia_sockmask.sin_addr.s_addr;
374 			needinit = 1;
375 		}
376 		if ((ifp->if_flags & IFF_POINTOPOINT) &&
377 		    (ifra->ifra_dstaddr.sin_family == AF_INET)) {
378 			in_ifscrub(ifp, ia);
379 			ia->ia_dstaddr = ifra->ifra_dstaddr;
380 			needinit  = 1;
381 		}
382 		if ((ifp->if_flags & IFF_BROADCAST) &&
383 		    (ifra->ifra_broadaddr.sin_family == AF_INET)) {
384 			if (newifaddr)
385 				ia->ia_broadaddr = ifra->ifra_broadaddr;
386 			else
387 				ifa_update_broadaddr(ifp, &ia->ia_ifa,
388 				    sintosa(&ifra->ifra_broadaddr));
389 		}
390 		if (ifra->ifra_addr.sin_family == AF_INET && needinit) {
391 			error = in_ifinit(ifp, ia, &ifra->ifra_addr, newifaddr);
392 		}
393 		if (!error)
394 			dohooks(ifp->if_addrhooks, 0);
395 		return (error);
396 		}
397 	case SIOCDIFADDR:
398 		/*
399 		 * Even if the individual steps were safe, shouldn't
400 		 * these kinds of changes happen atomically?  What
401 		 * should happen to a packet that was routed after
402 		 * the scrub but before the other steps?
403 		 */
404 		in_purgeaddr(&ia->ia_ifa);
405 		dohooks(ifp->if_addrhooks, 0);
406 		break;
407 
408 	default:
409 		if (ifp->if_ioctl == NULL)
410 			return (EOPNOTSUPP);
411 		error = ((*ifp->if_ioctl)(ifp, cmd, data));
412 		return (error);
413 	}
414 	return (0);
415 }
416 
417 /*
418  * SIOC[GAD]LIFADDR.
419  *	SIOCGLIFADDR: get first address. (???)
420  *	SIOCGLIFADDR with IFLR_PREFIX:
421  *		get first address that matches the specified prefix.
422  *	SIOCALIFADDR: add the specified address.
423  *	SIOCALIFADDR with IFLR_PREFIX:
424  *		EINVAL since we can't deduce hostid part of the address.
425  *	SIOCDLIFADDR: delete the specified address.
426  *	SIOCDLIFADDR with IFLR_PREFIX:
427  *		delete the first address that matches the specified prefix.
428  * return values:
429  *	EINVAL on invalid parameters
430  *	EADDRNOTAVAIL on prefix match failed/specified address not found
431  *	other values may be returned from in_ioctl()
432  */
433 int
434 in_lifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged)
435 {
436 	struct if_laddrreq *iflr = (struct if_laddrreq *)data;
437 	struct ifaddr *ifa;
438 	struct sockaddr *sa;
439 
440 	/* sanity checks */
441 	if (!data || !ifp) {
442 		panic("invalid argument to in_lifaddr_ioctl");
443 		/*NOTRECHED*/
444 	}
445 
446 	switch (cmd) {
447 	case SIOCGLIFADDR:
448 		/* address must be specified on GET with IFLR_PREFIX */
449 		if ((iflr->flags & IFLR_PREFIX) == 0)
450 			break;
451 		/*FALLTHROUGH*/
452 	case SIOCALIFADDR:
453 	case SIOCDLIFADDR:
454 		/* address must be specified on ADD and DELETE */
455 		sa = sstosa(&iflr->addr);
456 		if (sa->sa_family != AF_INET)
457 			return EINVAL;
458 		if (sa->sa_len != sizeof(struct sockaddr_in))
459 			return EINVAL;
460 		/* XXX need improvement */
461 		sa = sstosa(&iflr->dstaddr);
462 		if (sa->sa_family
463 		 && sa->sa_family != AF_INET)
464 			return EINVAL;
465 		if (sa->sa_len && sa->sa_len != sizeof(struct sockaddr_in))
466 			return EINVAL;
467 		break;
468 	default: /*shouldn't happen*/
469 #if 0
470 		panic("invalid cmd to in_lifaddr_ioctl");
471 		/*NOTREACHED*/
472 #else
473 		return EOPNOTSUPP;
474 #endif
475 	}
476 	if (sizeof(struct in_addr) * 8 < iflr->prefixlen)
477 		return EINVAL;
478 
479 	switch (cmd) {
480 	case SIOCALIFADDR:
481 	    {
482 		struct in_aliasreq ifra;
483 
484 		if (iflr->flags & IFLR_PREFIX)
485 			return EINVAL;
486 
487 		/* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR). */
488 		bzero(&ifra, sizeof(ifra));
489 		memcpy(ifra.ifra_name, iflr->iflr_name,
490 		    sizeof(ifra.ifra_name));
491 
492 		memcpy(&ifra.ifra_addr, &iflr->addr, iflr->addr.ss_len);
493 
494 		if (iflr->dstaddr.ss_family) {	/*XXX*/
495 			memcpy(&ifra.ifra_dstaddr, &iflr->dstaddr,
496 			    iflr->dstaddr.ss_len);
497 		}
498 
499 		ifra.ifra_mask.sin_family = AF_INET;
500 		ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in);
501 		in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen);
502 
503 		return in_ioctl(SIOCAIFADDR, (caddr_t)&ifra, ifp, privileged);
504 	    }
505 	case SIOCGLIFADDR:
506 	case SIOCDLIFADDR:
507 	    {
508 		struct in_ifaddr *ia;
509 		struct in_addr mask, candidate, match;
510 		struct sockaddr_in *sin;
511 		int cmp;
512 
513 		bzero(&mask, sizeof(mask));
514 		if (iflr->flags & IFLR_PREFIX) {
515 			/* lookup a prefix rather than address. */
516 			in_len2mask(&mask, iflr->prefixlen);
517 
518 			sin = (struct sockaddr_in *)&iflr->addr;
519 			match.s_addr = sin->sin_addr.s_addr;
520 			match.s_addr &= mask.s_addr;
521 
522 			/* if you set extra bits, that's wrong */
523 			if (match.s_addr != sin->sin_addr.s_addr)
524 				return EINVAL;
525 
526 			cmp = 1;
527 		} else {
528 			if (cmd == SIOCGLIFADDR) {
529 				/* on getting an address, take the 1st match */
530 				cmp = 0;	/*XXX*/
531 			} else {
532 				/* on deleting an address, do exact match */
533 				in_len2mask(&mask, 32);
534 				sin = (struct sockaddr_in *)&iflr->addr;
535 				match.s_addr = sin->sin_addr.s_addr;
536 
537 				cmp = 1;
538 			}
539 		}
540 
541 		TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
542 			if (ifa->ifa_addr->sa_family != AF_INET)
543 				continue;
544 			if (!cmp)
545 				break;
546 			candidate.s_addr = ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr;
547 			candidate.s_addr &= mask.s_addr;
548 			if (candidate.s_addr == match.s_addr)
549 				break;
550 		}
551 		if (!ifa)
552 			return EADDRNOTAVAIL;
553 		ia = ifatoia(ifa);
554 
555 		if (cmd == SIOCGLIFADDR) {
556 			/* fill in the if_laddrreq structure */
557 			memcpy(&iflr->addr, &ia->ia_addr, ia->ia_addr.sin_len);
558 
559 			if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
560 				memcpy(&iflr->dstaddr, &ia->ia_dstaddr,
561 				    ia->ia_dstaddr.sin_len);
562 			} else
563 				bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
564 
565 			iflr->prefixlen =
566 				in_mask2len(&ia->ia_sockmask.sin_addr);
567 
568 			iflr->flags = 0;	/*XXX*/
569 
570 			return 0;
571 		} else {
572 			struct in_aliasreq ifra;
573 
574 			/* fill in_aliasreq and do ioctl(SIOCDIFADDR) */
575 			bzero(&ifra, sizeof(ifra));
576 			memcpy(ifra.ifra_name, iflr->iflr_name,
577 			    sizeof(ifra.ifra_name));
578 
579 			memcpy(&ifra.ifra_addr, &ia->ia_addr,
580 			    ia->ia_addr.sin_len);
581 			if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
582 				memcpy(&ifra.ifra_dstaddr, &ia->ia_dstaddr,
583 				    ia->ia_dstaddr.sin_len);
584 			}
585 			memcpy(&ifra.ifra_dstaddr, &ia->ia_sockmask,
586 			    ia->ia_sockmask.sin_len);
587 
588 			return in_ioctl(SIOCDIFADDR, (caddr_t)&ifra, ifp,
589 			    privileged);
590 		}
591 	    }
592 	}
593 
594 	return EOPNOTSUPP;	/*just for safety*/
595 }
596 
597 /*
598  * Delete any existing route for an interface.
599  */
600 void
601 in_ifscrub(struct ifnet *ifp, struct in_ifaddr *ia)
602 {
603 	if (ISSET(ifp->if_flags, IFF_POINTOPOINT))
604 		in_scrubhost(ia, &ia->ia_dstaddr);
605 	else if (!ISSET(ifp->if_flags, IFF_LOOPBACK))
606 		in_remove_prefix(ia);
607 }
608 
609 /*
610  * Initialize an interface's internet address
611  * and routing table entry.
612  */
613 int
614 in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
615     int newaddr)
616 {
617 	u_int32_t i = sin->sin_addr.s_addr;
618 	struct sockaddr_in oldaddr;
619 	int error = 0, rterror;
620 
621 	NET_ASSERT_LOCKED();
622 
623 	/*
624 	 * Always remove the address from the tree to make sure its
625 	 * position gets updated in case the key changes.
626 	 */
627 	if (!newaddr) {
628 		rt_ifa_dellocal(&ia->ia_ifa);
629 		ifa_del(ifp, &ia->ia_ifa);
630 	}
631 	oldaddr = ia->ia_addr;
632 	ia->ia_addr = *sin;
633 
634 	if (ia->ia_netmask == 0) {
635 		if (IN_CLASSA(i))
636 			ia->ia_netmask = IN_CLASSA_NET;
637 		else if (IN_CLASSB(i))
638 			ia->ia_netmask = IN_CLASSB_NET;
639 		else
640 			ia->ia_netmask = IN_CLASSC_NET;
641 		ia->ia_sockmask.sin_addr.s_addr = ia->ia_netmask;
642 	}
643 
644 	/*
645 	 * Give the interface a chance to initialize
646 	 * if this is its first address,
647 	 * and to validate the address if necessary.
648 	 */
649 	if (ifp->if_ioctl &&
650 	    (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
651 		ia->ia_addr = oldaddr;
652 	}
653 
654 	/*
655 	 * Add the address to the local list and the global tree.  If an
656 	 * error occured, put back the original address.
657 	 */
658 	ifa_add(ifp, &ia->ia_ifa);
659 	rterror = rt_ifa_addlocal(&ia->ia_ifa);
660 
661 	if (rterror) {
662 		if (!newaddr)
663 			ifa_del(ifp, &ia->ia_ifa);
664 		if (!error)
665 			error = rterror;
666 		goto out;
667 	}
668 	if (error)
669 		goto out;
670 
671 
672 	ia->ia_net = i & ia->ia_netmask;
673 	in_socktrim(&ia->ia_sockmask);
674 	/*
675 	 * Add route for the network.
676 	 */
677 	ia->ia_ifa.ifa_metric = ifp->if_metric;
678 	if (ISSET(ifp->if_flags, IFF_BROADCAST)) {
679 		if (IN_RFC3021_SUBNET(ia->ia_netmask))
680 			ia->ia_broadaddr.sin_addr.s_addr = 0;
681 		else {
682 			ia->ia_broadaddr.sin_addr.s_addr =
683 			    ia->ia_net | ~ia->ia_netmask;
684 		}
685 	}
686 
687 	if (ISSET(ifp->if_flags, IFF_POINTOPOINT)) {
688 		/* XXX We should not even call in_ifinit() in this case. */
689 		if (ia->ia_dstaddr.sin_family != AF_INET)
690 			goto out;
691 		error = in_addhost(ia, &ia->ia_dstaddr);
692 	} else if (!ISSET(ifp->if_flags, IFF_LOOPBACK)) {
693 		error = in_insert_prefix(ia);
694 	}
695 
696 	/*
697 	 * If the interface supports multicast, join the "all hosts"
698 	 * multicast group on that interface.
699 	 */
700 	if ((ifp->if_flags & IFF_MULTICAST) && ia->ia_allhosts == NULL) {
701 		struct in_addr addr;
702 
703 		addr.s_addr = INADDR_ALLHOSTS_GROUP;
704 		ia->ia_allhosts = in_addmulti(&addr, ifp);
705 	}
706 
707 out:
708 	if (error && newaddr)
709 		in_purgeaddr(&ia->ia_ifa);
710 
711 	return (error);
712 }
713 
714 void
715 in_purgeaddr(struct ifaddr *ifa)
716 {
717 	struct ifnet *ifp = ifa->ifa_ifp;
718 	struct in_ifaddr *ia = ifatoia(ifa);
719 	extern int ifatrash;
720 
721 	NET_ASSERT_LOCKED();
722 
723 	in_ifscrub(ifp, ia);
724 
725 	rt_ifa_dellocal(&ia->ia_ifa);
726 	rt_ifa_purge(&ia->ia_ifa);
727 	ifa_del(ifp, &ia->ia_ifa);
728 
729 	if (ia->ia_allhosts != NULL) {
730 		in_delmulti(ia->ia_allhosts);
731 		ia->ia_allhosts = NULL;
732 	}
733 
734 	ifatrash++;
735 	ia->ia_ifp = NULL;
736 	ifafree(&ia->ia_ifa);
737 }
738 
739 int
740 in_addhost(struct in_ifaddr *ia, struct sockaddr_in *dst)
741 {
742 	return rt_ifa_add(&ia->ia_ifa, RTF_HOST, sintosa(dst));
743 }
744 
745 int
746 in_scrubhost(struct in_ifaddr *ia, struct sockaddr_in *dst)
747 {
748 	return rt_ifa_del(&ia->ia_ifa, RTF_HOST, sintosa(dst));
749 }
750 
751 /*
752  * Insert the cloning and broadcast routes for this subnet.
753  */
754 int
755 in_insert_prefix(struct in_ifaddr *ia)
756 {
757 	struct ifaddr *ifa = &ia->ia_ifa;
758 	int error;
759 
760 	error = rt_ifa_add(ifa, RTF_CLONING | RTF_CONNECTED, ifa->ifa_addr);
761 	if (error)
762 		return (error);
763 
764 	if (ia->ia_broadaddr.sin_addr.s_addr != 0)
765 		error = rt_ifa_add(ifa, RTF_HOST | RTF_BROADCAST,
766 		    ifa->ifa_broadaddr);
767 
768 	return (error);
769 }
770 
771 void
772 in_remove_prefix(struct in_ifaddr *ia)
773 {
774 	struct ifaddr *ifa = &ia->ia_ifa;
775 
776 	rt_ifa_del(ifa, RTF_CLONING | RTF_CONNECTED, ifa->ifa_addr);
777 
778 	if (ia->ia_broadaddr.sin_addr.s_addr != 0)
779 		rt_ifa_del(ifa, RTF_HOST | RTF_BROADCAST, ifa->ifa_broadaddr);
780 }
781 
782 /*
783  * Return 1 if the address is a local broadcast address.
784  */
785 int
786 in_broadcast(struct in_addr in, u_int rtableid)
787 {
788 	struct ifnet *ifn;
789 	struct ifaddr *ifa;
790 	u_int rdomain;
791 
792 	rdomain = rtable_l2(rtableid);
793 
794 #define ia (ifatoia(ifa))
795 	TAILQ_FOREACH(ifn, &ifnet, if_list) {
796 		if (ifn->if_rdomain != rdomain)
797 			continue;
798 		if ((ifn->if_flags & IFF_BROADCAST) == 0)
799 			continue;
800 		TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list)
801 			if (ifa->ifa_addr->sa_family == AF_INET &&
802 			    in.s_addr != ia->ia_addr.sin_addr.s_addr &&
803 			    in.s_addr == ia->ia_broadaddr.sin_addr.s_addr)
804 				return 1;
805 	}
806 	return (0);
807 #undef ia
808 }
809 
810 /*
811  * Add an address to the list of IP multicast addresses for a given interface.
812  */
813 struct in_multi *
814 in_addmulti(struct in_addr *ap, struct ifnet *ifp)
815 {
816 	struct in_multi *inm;
817 	struct ifreq ifr;
818 
819 	/*
820 	 * See if address already in list.
821 	 */
822 	IN_LOOKUP_MULTI(*ap, ifp, inm);
823 	if (inm != NULL) {
824 		/*
825 		 * Found it; just increment the reference count.
826 		 */
827 		++inm->inm_refcnt;
828 	} else {
829 		if (ifp->if_ioctl == NULL)
830 			return (NULL);
831 
832 		/*
833 		 * New address; allocate a new multicast record
834 		 * and link it into the interface's multicast list.
835 		 */
836 		inm = malloc(sizeof(*inm), M_IPMADDR, M_NOWAIT | M_ZERO);
837 		if (inm == NULL)
838 			return (NULL);
839 
840 		inm->inm_sin.sin_len = sizeof(struct sockaddr_in);
841 		inm->inm_sin.sin_family = AF_INET;
842 		inm->inm_sin.sin_addr = *ap;
843 		inm->inm_refcnt = 1;
844 		inm->inm_ifidx = ifp->if_index;
845 		inm->inm_ifma.ifma_addr = sintosa(&inm->inm_sin);
846 
847 		/*
848 		 * Ask the network driver to update its multicast reception
849 		 * filter appropriately for the new address.
850 		 */
851 		memset(&ifr, 0, sizeof(ifr));
852 		memcpy(&ifr.ifr_addr, &inm->inm_sin, sizeof(inm->inm_sin));
853 		if ((*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) {
854 			free(inm, M_IPMADDR, sizeof(*inm));
855 			return (NULL);
856 		}
857 
858 		TAILQ_INSERT_HEAD(&ifp->if_maddrlist, &inm->inm_ifma,
859 		    ifma_list);
860 
861 		/*
862 		 * Let IGMP know that we have joined a new IP multicast group.
863 		 */
864 		igmp_joingroup(inm);
865 	}
866 
867 	return (inm);
868 }
869 
870 /*
871  * Delete a multicast address record.
872  */
873 void
874 in_delmulti(struct in_multi *inm)
875 {
876 	struct ifreq ifr;
877 	struct ifnet *ifp;
878 
879 	NET_ASSERT_LOCKED();
880 
881 	if (--inm->inm_refcnt == 0) {
882 		/*
883 		 * No remaining claims to this record; let IGMP know that
884 		 * we are leaving the multicast group.
885 		 */
886 		igmp_leavegroup(inm);
887 		ifp = if_get(inm->inm_ifidx);
888 
889 		/*
890 		 * Notify the network driver to update its multicast
891 		 * reception filter.
892 		 */
893 		if (ifp != NULL) {
894 			memset(&ifr, 0, sizeof(ifr));
895 			satosin(&ifr.ifr_addr)->sin_len =
896 			    sizeof(struct sockaddr_in);
897 			satosin(&ifr.ifr_addr)->sin_family = AF_INET;
898 			satosin(&ifr.ifr_addr)->sin_addr = inm->inm_addr;
899 			(*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr);
900 
901 			TAILQ_REMOVE(&ifp->if_maddrlist, &inm->inm_ifma,
902 			    ifma_list);
903 		}
904 		if_put(ifp);
905 
906 		free(inm, M_IPMADDR, sizeof(*inm));
907 	}
908 }
909 
910 /*
911  * Return 1 if the multicast group represented by ``ap'' has been
912  * joined by interface ``ifp'', 0 otherwise.
913  */
914 int
915 in_hasmulti(struct in_addr *ap, struct ifnet *ifp)
916 {
917 	struct in_multi *inm;
918 	int joined;
919 
920 	IN_LOOKUP_MULTI(*ap, ifp, inm);
921 	joined = (inm != NULL);
922 
923 	return (joined);
924 }
925 
926 void
927 in_ifdetach(struct ifnet *ifp)
928 {
929 	struct ifaddr *ifa, *next;
930 
931 	/* nuke any of IPv4 addresses we have */
932 	TAILQ_FOREACH_SAFE(ifa, &ifp->if_addrlist, ifa_list, next) {
933 		if (ifa->ifa_addr->sa_family != AF_INET)
934 			continue;
935 		in_purgeaddr(ifa);
936 		dohooks(ifp->if_addrhooks, 0);
937 	}
938 }
939 
940 void
941 in_prefixlen2mask(struct in_addr *maskp, int plen)
942 {
943 	if (plen == 0)
944 		maskp->s_addr = 0;
945 	else
946 		maskp->s_addr = htonl(0xffffffff << (32 - plen));
947 }
948