xref: /dflybsd-src/sys/netinet/in.c (revision 52347f71f500fe4113e37cca4ea6edc6150698e7)
1 /*
2  * Copyright (c) 1982, 1986, 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *	@(#)in.c	8.4 (Berkeley) 1/9/95
34  * $FreeBSD: src/sys/netinet/in.c,v 1.44.2.14 2002/11/08 00:45:50 suz Exp $
35  * $DragonFly: src/sys/netinet/in.c,v 1.26 2008/03/07 11:34:20 sephe Exp $
36  */
37 
38 #include "opt_bootp.h"
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/sockio.h>
43 #include <sys/malloc.h>
44 #include <sys/proc.h>
45 #include <sys/msgport.h>
46 #include <sys/socket.h>
47 
48 #include <sys/kernel.h>
49 #include <sys/sysctl.h>
50 #include <sys/thread2.h>
51 
52 #include <net/if.h>
53 #include <net/if_types.h>
54 #include <net/route.h>
55 #include <net/netmsg2.h>
56 
57 #include <netinet/in.h>
58 #include <netinet/in_var.h>
59 #include <netinet/in_pcb.h>
60 
61 #include <netinet/igmp_var.h>
62 
63 MALLOC_DEFINE(M_IPMADDR, "in_multi", "internet multicast address");
64 
65 static int in_mask2len (struct in_addr *);
66 static void in_len2mask (struct in_addr *, int);
67 static int in_lifaddr_ioctl (struct socket *, u_long, caddr_t,
68 	struct ifnet *, struct thread *);
69 
70 static void	in_socktrim (struct sockaddr_in *);
71 static int	in_ifinit (struct ifnet *,
72 	    struct in_ifaddr *, struct sockaddr_in *, int);
73 
74 static void	in_control_dispatch(struct netmsg *);
75 static int	in_control_internal(u_long, caddr_t, struct ifnet *,
76 		    struct thread *);
77 
78 static int subnetsarelocal = 0;
79 SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW,
80 	&subnetsarelocal, 0, "");
81 
82 struct in_multihead in_multihead; /* XXX BSS initialization */
83 
84 extern struct inpcbinfo ripcbinfo;
85 extern struct inpcbinfo udbinfo;
86 
87 /*
88  * Return 1 if an internet address is for a ``local'' host
89  * (one to which we have a connection).  If subnetsarelocal
90  * is true, this includes other subnets of the local net.
91  * Otherwise, it includes only the directly-connected (sub)nets.
92  */
93 int
94 in_localaddr(struct in_addr in)
95 {
96 	u_long i = ntohl(in.s_addr);
97 	struct in_ifaddr *ia;
98 
99 	if (subnetsarelocal) {
100 		TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link)
101 			if ((i & ia->ia_netmask) == ia->ia_net)
102 				return (1);
103 	} else {
104 		TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link)
105 			if ((i & ia->ia_subnetmask) == ia->ia_subnet)
106 				return (1);
107 	}
108 	return (0);
109 }
110 
111 /*
112  * Determine whether an IP address is in a reserved set of addresses
113  * that may not be forwarded, or whether datagrams to that destination
114  * may be forwarded.
115  */
116 int
117 in_canforward(struct in_addr in)
118 {
119 	u_long i = ntohl(in.s_addr);
120 	u_long net;
121 
122 	if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i))
123 		return (0);
124 	if (IN_CLASSA(i)) {
125 		net = i & IN_CLASSA_NET;
126 		if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
127 			return (0);
128 	}
129 	return (1);
130 }
131 
132 /*
133  * Trim a mask in a sockaddr
134  */
135 static void
136 in_socktrim(struct sockaddr_in *ap)
137 {
138     char *cplim = (char *) &ap->sin_addr;
139     char *cp = (char *) (&ap->sin_addr + 1);
140 
141     ap->sin_len = 0;
142     while (--cp >= cplim)
143 	if (*cp) {
144 	    (ap)->sin_len = cp - (char *) (ap) + 1;
145 	    break;
146 	}
147 }
148 
149 static int
150 in_mask2len(struct in_addr *mask)
151 {
152 	int x, y;
153 	u_char *p;
154 
155 	p = (u_char *)mask;
156 	for (x = 0; x < sizeof *mask; x++) {
157 		if (p[x] != 0xff)
158 			break;
159 	}
160 	y = 0;
161 	if (x < sizeof *mask) {
162 		for (y = 0; y < 8; y++) {
163 			if ((p[x] & (0x80 >> y)) == 0)
164 				break;
165 		}
166 	}
167 	return x * 8 + y;
168 }
169 
170 static void
171 in_len2mask(struct in_addr *mask, int len)
172 {
173 	int i;
174 	u_char *p;
175 
176 	p = (u_char *)mask;
177 	bzero(mask, sizeof *mask);
178 	for (i = 0; i < len / 8; i++)
179 		p[i] = 0xff;
180 	if (len % 8)
181 		p[i] = (0xff00 >> (len % 8)) & 0xff;
182 }
183 
184 static int in_interfaces;	/* number of external internet interfaces */
185 
186 struct in_control_arg {
187 	u_long		cmd;
188 	caddr_t		data;
189 	struct ifnet	*ifp;
190 	struct thread	*td;
191 };
192 
193 static void
194 in_control_dispatch(struct netmsg *nmsg)
195 {
196 	struct lwkt_msg *msg = &nmsg->nm_lmsg;
197 	const struct in_control_arg *arg = msg->u.ms_resultp;
198 	int error;
199 
200 	error = in_control_internal(arg->cmd, arg->data, arg->ifp, arg->td);
201 	lwkt_replymsg(msg, error);
202 }
203 
204 /*
205  * Generic internet control operations (ioctl's).
206  * Ifp is 0 if not an interface-specific ioctl.
207  *
208  * NOTE! td might be NULL.
209  */
210 /* ARGSUSED */
211 int
212 in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
213 	   struct thread *td)
214 {
215 	struct netmsg nmsg;
216 	struct in_control_arg arg;
217 	struct lwkt_msg *msg;
218 	int error;
219 
220 	switch (cmd) {
221 	case SIOCALIFADDR:
222 	case SIOCDLIFADDR:
223 		if (td && (error = suser(td)) != 0)
224 			return error;
225 		/*fall through*/
226 	case SIOCGLIFADDR:
227 		if (!ifp)
228 			return EINVAL;
229 		return in_lifaddr_ioctl(so, cmd, data, ifp, td);
230 	}
231 
232 	KASSERT(cmd != SIOCALIFADDR && cmd != SIOCDLIFADDR,
233 		("recursive SIOC%cLIFADDR!\n",
234 		 cmd == SIOCDLIFADDR ? 'D' : 'A'));
235 
236 	switch (cmd) {
237 	case SIOCSIFDSTADDR:
238 	case SIOCSIFBRDADDR:
239 	case SIOCSIFADDR:
240 	case SIOCSIFNETMASK:
241 	case SIOCAIFADDR:
242 	case SIOCDIFADDR:
243 		bzero(&arg, sizeof(arg));
244 		arg.cmd = cmd;
245 		arg.data = data;
246 		arg.ifp = ifp;
247 		arg.td = td;
248 
249 		netmsg_init(&nmsg, &curthread->td_msgport, 0,
250 			    in_control_dispatch);
251 		msg = &nmsg.nm_lmsg;
252 		msg->u.ms_resultp = &arg;
253 
254 		lwkt_domsg(cpu_portfn(0), msg, 0);
255 		return msg->ms_error;
256 	default:
257 		return in_control_internal(cmd, data, ifp, td);
258 	}
259 }
260 
261 static int
262 in_control_internal(u_long cmd, caddr_t data, struct ifnet *ifp,
263 		    struct thread *td)
264 {
265 	struct ifreq *ifr = (struct ifreq *)data;
266 	struct in_ifaddr *ia = 0, *iap;
267 	struct in_addr dst;
268 	struct in_ifaddr *oia;
269 	struct in_aliasreq *ifra = (struct in_aliasreq *)data;
270 	struct sockaddr_in oldaddr;
271 	int hostIsNew, iaIsNew, maskIsNew;
272 	int error = 0;
273 
274 	iaIsNew = 0;
275 
276 	/*
277 	 * Find address for this interface, if it exists.
278 	 *
279 	 * If an alias address was specified, find that one instead of
280 	 * the first one on the interface, if possible
281 	 */
282 	if (ifp) {
283 		dst = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
284 		LIST_FOREACH(iap, INADDR_HASH(dst.s_addr), ia_hash)
285 			if (iap->ia_ifp == ifp &&
286 			    iap->ia_addr.sin_addr.s_addr == dst.s_addr) {
287 				ia = iap;
288 				break;
289 			}
290 		if (ia == NULL) {
291 			struct ifaddr_container *ifac;
292 
293 			TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid],
294 				      ifa_link) {
295 				iap = ifatoia(ifac->ifa);
296 				if (iap->ia_addr.sin_family == AF_INET) {
297 					ia = iap;
298 					break;
299 				}
300 			}
301 		}
302 	}
303 
304 	switch (cmd) {
305 
306 	case SIOCAIFADDR:
307 	case SIOCDIFADDR:
308 		if (ifp == NULL)
309 			return (EADDRNOTAVAIL);
310 		if (ifra->ifra_addr.sin_family == AF_INET) {
311 			for (oia = ia; ia; ia = TAILQ_NEXT(ia, ia_link)) {
312 				if (ia->ia_ifp == ifp  &&
313 				    ia->ia_addr.sin_addr.s_addr ==
314 				    ifra->ifra_addr.sin_addr.s_addr)
315 					break;
316 			}
317 			if ((ifp->if_flags & IFF_POINTOPOINT)
318 			    && (cmd == SIOCAIFADDR)
319 			    && (ifra->ifra_dstaddr.sin_addr.s_addr
320 				== INADDR_ANY)) {
321 				return EDESTADDRREQ;
322 			}
323 		}
324 		if (cmd == SIOCDIFADDR && ia == NULL)
325 			return (EADDRNOTAVAIL);
326 		/* FALLTHROUGH */
327 	case SIOCSIFADDR:
328 	case SIOCSIFNETMASK:
329 	case SIOCSIFDSTADDR:
330 		if (td && (error = suser(td)) != 0)
331 			return error;
332 
333 		if (ifp == NULL)
334 			return (EADDRNOTAVAIL);
335 		if (ia == NULL) {
336 			struct ifaddr *ifa;
337 
338 			ia = ifa_create(sizeof(*ia), M_WAITOK);
339 
340 			/*
341 			 * Protect from NETISR_IP traversing address list
342 			 * while we're modifying it.
343 			 */
344 			crit_enter();
345 
346 			TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_link);
347 			ifa = &ia->ia_ifa;
348 			ifa_iflink(ifa, ifp, 1);
349 
350 			ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;
351 			ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
352 			ifa->ifa_netmask = (struct sockaddr *)&ia->ia_sockmask;
353 			ia->ia_sockmask.sin_len = 8;
354 			ia->ia_sockmask.sin_family = AF_INET;
355 			if (ifp->if_flags & IFF_BROADCAST) {
356 				ia->ia_broadaddr.sin_len = sizeof ia->ia_addr;
357 				ia->ia_broadaddr.sin_family = AF_INET;
358 			}
359 			ia->ia_ifp = ifp;
360 			if (!(ifp->if_flags & IFF_LOOPBACK))
361 				in_interfaces++;
362 			iaIsNew = 1;
363 			crit_exit();
364 		}
365 		break;
366 
367 	case SIOCSIFBRDADDR:
368 		if (td && (error = suser(td)) != 0)
369 			return error;
370 		/* FALLTHROUGH */
371 
372 	case SIOCGIFADDR:
373 	case SIOCGIFNETMASK:
374 	case SIOCGIFDSTADDR:
375 	case SIOCGIFBRDADDR:
376 		if (ia == NULL)
377 			return (EADDRNOTAVAIL);
378 		break;
379 	}
380 	switch (cmd) {
381 
382 	case SIOCGIFADDR:
383 		*((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr;
384 		return (0);
385 
386 	case SIOCGIFBRDADDR:
387 		if ((ifp->if_flags & IFF_BROADCAST) == 0)
388 			return (EINVAL);
389 		*((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_broadaddr;
390 		return (0);
391 
392 	case SIOCGIFDSTADDR:
393 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
394 			return (EINVAL);
395 		*((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr;
396 		return (0);
397 
398 	case SIOCGIFNETMASK:
399 		*((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask;
400 		return (0);
401 
402 	case SIOCSIFDSTADDR:
403 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
404 			return (EINVAL);
405 		oldaddr = ia->ia_dstaddr;
406 		ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr;
407 		lwkt_serialize_enter(ifp->if_serializer);
408 		if (ifp->if_ioctl &&
409 		    (error = ifp->if_ioctl(ifp, SIOCSIFDSTADDR, (caddr_t)ia,
410 					      td->td_proc->p_ucred))) {
411 			ia->ia_dstaddr = oldaddr;
412 			lwkt_serialize_exit(ifp->if_serializer);
413 			return (error);
414 		}
415 		if (ia->ia_flags & IFA_ROUTE) {
416 			ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
417 			rtinit(&ia->ia_ifa, RTM_DELETE, RTF_HOST);
418 			ia->ia_ifa.ifa_dstaddr =
419 					(struct sockaddr *)&ia->ia_dstaddr;
420 			rtinit(&ia->ia_ifa, RTM_ADD, RTF_HOST | RTF_UP);
421 		}
422 		lwkt_serialize_exit(ifp->if_serializer);
423 		return (0);
424 
425 	case SIOCSIFBRDADDR:
426 		if ((ifp->if_flags & IFF_BROADCAST) == 0)
427 			return (EINVAL);
428 		ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr;
429 		return (0);
430 
431 	case SIOCSIFADDR:
432 		error = in_ifinit(ifp, ia,
433 		    (struct sockaddr_in *) &ifr->ifr_addr, 1);
434 		if (error != 0 && iaIsNew)
435 			break;
436 		if (error == 0)
437 			EVENTHANDLER_INVOKE(ifaddr_event, ifp);
438 		return (0);
439 
440 	case SIOCSIFNETMASK:
441 		ia->ia_sockmask.sin_addr = ifra->ifra_addr.sin_addr;
442 		ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr);
443 		return (0);
444 
445 	case SIOCAIFADDR:
446 		maskIsNew = 0;
447 		hostIsNew = 1;
448 		error = 0;
449 		if (ia->ia_addr.sin_family == AF_INET) {
450 			if (ifra->ifra_addr.sin_len == 0) {
451 				ifra->ifra_addr = ia->ia_addr;
452 				hostIsNew = 0;
453 			} else if (ifra->ifra_addr.sin_addr.s_addr ==
454 					       ia->ia_addr.sin_addr.s_addr)
455 				hostIsNew = 0;
456 		}
457 		if (ifra->ifra_mask.sin_len) {
458 			in_ifscrub(ifp, ia);
459 			ia->ia_sockmask = ifra->ifra_mask;
460 			ia->ia_sockmask.sin_family = AF_INET;
461 			ia->ia_subnetmask =
462 			     ntohl(ia->ia_sockmask.sin_addr.s_addr);
463 			maskIsNew = 1;
464 		}
465 		if ((ifp->if_flags & IFF_POINTOPOINT) &&
466 		    (ifra->ifra_dstaddr.sin_family == AF_INET)) {
467 			in_ifscrub(ifp, ia);
468 			ia->ia_dstaddr = ifra->ifra_dstaddr;
469 			maskIsNew  = 1; /* We lie; but the effect's the same */
470 		}
471 		if (ifra->ifra_addr.sin_family == AF_INET &&
472 		    (hostIsNew || maskIsNew))
473 			error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
474 
475 		if (error != 0 && iaIsNew)
476 			break;
477 
478 		if ((ifp->if_flags & IFF_BROADCAST) &&
479 		    (ifra->ifra_broadaddr.sin_family == AF_INET))
480 			ia->ia_broadaddr = ifra->ifra_broadaddr;
481 		if (error == 0)
482 			EVENTHANDLER_INVOKE(ifaddr_event, ifp);
483 		return (error);
484 
485 	case SIOCDIFADDR:
486 		/*
487 		 * in_ifscrub kills the interface route.
488 		 */
489 		in_ifscrub(ifp, ia);
490 		/*
491 		 * in_ifadown gets rid of all the rest of
492 		 * the routes.  This is not quite the right
493 		 * thing to do, but at least if we are running
494 		 * a routing process they will come back.
495 		 */
496 		in_ifadown(&ia->ia_ifa, 1);
497 		EVENTHANDLER_INVOKE(ifaddr_event, ifp);
498 		error = 0;
499 		break;
500 
501 	default:
502 		if (ifp == NULL || ifp->if_ioctl == NULL)
503 			return (EOPNOTSUPP);
504 		lwkt_serialize_enter(ifp->if_serializer);
505 		error = ifp->if_ioctl(ifp, cmd, data, td->td_proc->p_ucred);
506 		lwkt_serialize_exit(ifp->if_serializer);
507 		return (error);
508 	}
509 
510 	ifa_ifunlink(&ia->ia_ifa, ifp);
511 
512 	/*
513 	 * Protect from NETISR_IP traversing address list while we're modifying
514 	 * it.
515 	 */
516 	crit_enter();	/* XXX MP */
517 	TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link);
518 	LIST_REMOVE(ia, ia_hash);
519 	crit_exit();	/* XXX MP */
520 
521 	ifa_destroy(&ia->ia_ifa);
522 
523 	return (error);
524 }
525 
526 /*
527  * SIOC[GAD]LIFADDR.
528  *	SIOCGLIFADDR: get first address. (?!?)
529  *	SIOCGLIFADDR with IFLR_PREFIX:
530  *		get first address that matches the specified prefix.
531  *	SIOCALIFADDR: add the specified address.
532  *	SIOCALIFADDR with IFLR_PREFIX:
533  *		EINVAL since we can't deduce hostid part of the address.
534  *	SIOCDLIFADDR: delete the specified address.
535  *	SIOCDLIFADDR with IFLR_PREFIX:
536  *		delete the first address that matches the specified prefix.
537  * return values:
538  *	EINVAL on invalid parameters
539  *	EADDRNOTAVAIL on prefix match failed/specified address not found
540  *	other values may be returned from in_ioctl()
541  *
542  * NOTE! td might be NULL.
543  */
544 static int
545 in_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
546 		 struct thread *td)
547 {
548 	struct if_laddrreq *iflr = (struct if_laddrreq *)data;
549 
550 	/* sanity checks */
551 	if (!data || !ifp) {
552 		panic("invalid argument to in_lifaddr_ioctl");
553 		/*NOTRECHED*/
554 	}
555 
556 	switch (cmd) {
557 	case SIOCGLIFADDR:
558 		/* address must be specified on GET with IFLR_PREFIX */
559 		if ((iflr->flags & IFLR_PREFIX) == 0)
560 			break;
561 		/*FALLTHROUGH*/
562 	case SIOCALIFADDR:
563 	case SIOCDLIFADDR:
564 		/* address must be specified on ADD and DELETE */
565 		if (iflr->addr.ss_family != AF_INET)
566 			return EINVAL;
567 		if (iflr->addr.ss_len != sizeof(struct sockaddr_in))
568 			return EINVAL;
569 		/* XXX need improvement */
570 		if (iflr->dstaddr.ss_family
571 		 && iflr->dstaddr.ss_family != AF_INET)
572 			return EINVAL;
573 		if (iflr->dstaddr.ss_family
574 		 && iflr->dstaddr.ss_len != sizeof(struct sockaddr_in))
575 			return EINVAL;
576 		break;
577 	default: /*shouldn't happen*/
578 		return EOPNOTSUPP;
579 	}
580 	if (sizeof(struct in_addr) * 8 < iflr->prefixlen)
581 		return EINVAL;
582 
583 	switch (cmd) {
584 	case SIOCALIFADDR:
585 	    {
586 		struct in_aliasreq ifra;
587 
588 		if (iflr->flags & IFLR_PREFIX)
589 			return EINVAL;
590 
591 		/* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
592 		bzero(&ifra, sizeof ifra);
593 		bcopy(iflr->iflr_name, ifra.ifra_name, sizeof ifra.ifra_name);
594 
595 		bcopy(&iflr->addr, &ifra.ifra_addr, iflr->addr.ss_len);
596 
597 		if (iflr->dstaddr.ss_family) {	/*XXX*/
598 			bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
599 				iflr->dstaddr.ss_len);
600 		}
601 
602 		ifra.ifra_mask.sin_family = AF_INET;
603 		ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in);
604 		in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen);
605 
606 		return in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp, td);
607 	    }
608 	case SIOCGLIFADDR:
609 	case SIOCDLIFADDR:
610 	    {
611 		struct ifaddr_container *ifac;
612 		struct in_ifaddr *ia;
613 		struct in_addr mask, candidate, match;
614 		struct sockaddr_in *sin;
615 		int cmp;
616 
617 		bzero(&mask, sizeof mask);
618 		if (iflr->flags & IFLR_PREFIX) {
619 			/* lookup a prefix rather than address. */
620 			in_len2mask(&mask, iflr->prefixlen);
621 
622 			sin = (struct sockaddr_in *)&iflr->addr;
623 			match.s_addr = sin->sin_addr.s_addr;
624 			match.s_addr &= mask.s_addr;
625 
626 			/* if you set extra bits, that's wrong */
627 			if (match.s_addr != sin->sin_addr.s_addr)
628 				return EINVAL;
629 
630 			cmp = 1;
631 		} else {
632 			if (cmd == SIOCGLIFADDR) {
633 				/* on getting an address, take the 1st match */
634 				match.s_addr = 0; /* gcc4 warning */
635 				cmp = 0;	/*XXX*/
636 			} else {
637 				/* on deleting an address, do exact match */
638 				in_len2mask(&mask, 32);
639 				sin = (struct sockaddr_in *)&iflr->addr;
640 				match.s_addr = sin->sin_addr.s_addr;
641 
642 				cmp = 1;
643 			}
644 		}
645 
646 		TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
647 			struct ifaddr *ifa = ifac->ifa;
648 
649 			if (ifa->ifa_addr->sa_family != AF_INET6)
650 				continue;
651 			if (!cmp)
652 				break;
653 			candidate.s_addr =
654 			((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr;
655 			candidate.s_addr &= mask.s_addr;
656 			if (candidate.s_addr == match.s_addr)
657 				break;
658 		}
659 		if (ifac == NULL)
660 			return EADDRNOTAVAIL;
661 		ia = (struct in_ifaddr *)(ifac->ifa);
662 
663 		if (cmd == SIOCGLIFADDR) {
664 			/* fill in the if_laddrreq structure */
665 			bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len);
666 
667 			if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
668 				bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
669 					ia->ia_dstaddr.sin_len);
670 			} else
671 				bzero(&iflr->dstaddr, sizeof iflr->dstaddr);
672 
673 			iflr->prefixlen =
674 				in_mask2len(&ia->ia_sockmask.sin_addr);
675 
676 			iflr->flags = 0;	/*XXX*/
677 
678 			return 0;
679 		} else {
680 			struct in_aliasreq ifra;
681 
682 			/* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
683 			bzero(&ifra, sizeof ifra);
684 			bcopy(iflr->iflr_name, ifra.ifra_name,
685 				sizeof ifra.ifra_name);
686 
687 			bcopy(&ia->ia_addr, &ifra.ifra_addr,
688 				ia->ia_addr.sin_len);
689 			if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
690 				bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
691 					ia->ia_dstaddr.sin_len);
692 			}
693 			bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr,
694 				ia->ia_sockmask.sin_len);
695 
696 			return in_control(so, SIOCDIFADDR, (caddr_t)&ifra,
697 					  ifp, td);
698 		}
699 	    }
700 	}
701 
702 	return EOPNOTSUPP;	/*just for safety*/
703 }
704 
705 /*
706  * Delete any existing route for an interface.
707  */
708 void
709 in_ifscrub(struct ifnet *ifp, struct in_ifaddr *ia)
710 {
711 
712 	if ((ia->ia_flags & IFA_ROUTE) == 0)
713 		return;
714 	if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))
715 		rtinit(&ia->ia_ifa, RTM_DELETE, RTF_HOST);
716 	else
717 		rtinit(&ia->ia_ifa, RTM_DELETE, 0);
718 	ia->ia_flags &= ~IFA_ROUTE;
719 }
720 
721 /*
722  * Initialize an interface's internet address
723  * and routing table entry.
724  */
725 static int
726 in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, int scrub)
727 {
728 	u_long i = ntohl(sin->sin_addr.s_addr);
729 	struct sockaddr_in oldaddr;
730 	int flags = RTF_UP, error = 0;
731 
732 	lwkt_serialize_enter(ifp->if_serializer);
733 
734 	oldaddr = ia->ia_addr;
735 	if (oldaddr.sin_family == AF_INET)
736 		LIST_REMOVE(ia, ia_hash);
737 	ia->ia_addr = *sin;
738 	if (ia->ia_addr.sin_family == AF_INET)
739 		LIST_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr),
740 		    ia, ia_hash);
741 	/*
742 	 * Give the interface a chance to initialize
743 	 * if this is its first address,
744 	 * and to validate the address if necessary.
745 	 */
746 	if (ifp->if_ioctl &&
747 	    (error = ifp->if_ioctl(ifp, SIOCSIFADDR, (caddr_t)ia, NULL))) {
748 		lwkt_serialize_exit(ifp->if_serializer);
749 		/* LIST_REMOVE(ia, ia_hash) is done in in_control */
750 		ia->ia_addr = oldaddr;
751 		if (ia->ia_addr.sin_family == AF_INET)
752 			LIST_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr),
753 			    ia, ia_hash);
754 		return (error);
755 	}
756 	lwkt_serialize_exit(ifp->if_serializer);
757 	if (scrub) {
758 		ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
759 		in_ifscrub(ifp, ia);
760 		ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
761 	}
762 	if (IN_CLASSA(i))
763 		ia->ia_netmask = IN_CLASSA_NET;
764 	else if (IN_CLASSB(i))
765 		ia->ia_netmask = IN_CLASSB_NET;
766 	else
767 		ia->ia_netmask = IN_CLASSC_NET;
768 	/*
769 	 * The subnet mask usually includes at least the standard network part,
770 	 * but may may be smaller in the case of supernetting.
771 	 * If it is set, we believe it.
772 	 */
773 	if (ia->ia_subnetmask == 0) {
774 		ia->ia_subnetmask = ia->ia_netmask;
775 		ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
776 	} else
777 		ia->ia_netmask &= ia->ia_subnetmask;
778 	ia->ia_net = i & ia->ia_netmask;
779 	ia->ia_subnet = i & ia->ia_subnetmask;
780 	in_socktrim(&ia->ia_sockmask);
781 	/*
782 	 * Add route for the network.
783 	 */
784 	ia->ia_ifa.ifa_metric = ifp->if_metric;
785 	if (ifp->if_flags & IFF_BROADCAST) {
786 		ia->ia_broadaddr.sin_addr.s_addr =
787 			htonl(ia->ia_subnet | ~ia->ia_subnetmask);
788 		ia->ia_netbroadcast.s_addr =
789 			htonl(ia->ia_net | ~ ia->ia_netmask);
790 	} else if (ifp->if_flags & IFF_LOOPBACK) {
791 		ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
792 		flags |= RTF_HOST;
793 	} else if (ifp->if_flags & IFF_POINTOPOINT) {
794 		if (ia->ia_dstaddr.sin_family != AF_INET)
795 			return (0);
796 		flags |= RTF_HOST;
797 	}
798 
799 	/*-
800 	 * Don't add host routes for interface addresses of
801 	 * 0.0.0.0 --> 0.255.255.255 netmask 255.0.0.0.  This makes it
802 	 * possible to assign several such address pairs with consistent
803 	 * results (no host route) and is required by BOOTP.
804 	 *
805 	 * XXX: This is ugly !  There should be a way for the caller to
806 	 *      say that they don't want a host route.
807 	 */
808 	if (ia->ia_addr.sin_addr.s_addr != INADDR_ANY ||
809 	    ia->ia_netmask != IN_CLASSA_NET ||
810 	    ia->ia_dstaddr.sin_addr.s_addr != htonl(IN_CLASSA_HOST)) {
811 		if ((error = rtinit(&ia->ia_ifa, (int)RTM_ADD, flags)) != 0) {
812 			ia->ia_addr = oldaddr;
813 			return (error);
814 		}
815 		ia->ia_flags |= IFA_ROUTE;
816 	}
817 
818 	/*
819 	 * If the interface supports multicast, join the "all hosts"
820 	 * multicast group on that interface.
821 	 */
822 	if (ifp->if_flags & IFF_MULTICAST) {
823 		struct in_addr addr;
824 
825 		addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
826 		in_addmulti(&addr, ifp);
827 	}
828 	return (error);
829 }
830 
831 
832 /*
833  * Return 1 if the address might be a local broadcast address.
834  */
835 int
836 in_broadcast(struct in_addr in, struct ifnet *ifp)
837 {
838 	struct ifaddr_container *ifac;
839 	u_long t;
840 
841 	if (in.s_addr == INADDR_BROADCAST ||
842 	    in.s_addr == INADDR_ANY)
843 		return 1;
844 	if ((ifp->if_flags & IFF_BROADCAST) == 0)
845 		return 0;
846 	t = ntohl(in.s_addr);
847 	/*
848 	 * Look through the list of addresses for a match
849 	 * with a broadcast address.
850 	 */
851 #define ia ((struct in_ifaddr *)ifa)
852 	TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
853 		struct ifaddr *ifa = ifac->ifa;
854 
855 		if (ifa->ifa_addr->sa_family == AF_INET &&
856 		    (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
857 		     in.s_addr == ia->ia_netbroadcast.s_addr ||
858 		     /*
859 		      * Check for old-style (host 0) broadcast.
860 		      */
861 		     t == ia->ia_subnet || t == ia->ia_net) &&
862 		     /*
863 		      * Check for an all one subnetmask. These
864 		      * only exist when an interface gets a secondary
865 		      * address.
866 		      */
867 		     ia->ia_subnetmask != (u_long)0xffffffff)
868 			    return 1;
869 	}
870 	return (0);
871 #undef ia
872 }
873 /*
874  * Add an address to the list of IP multicast addresses for a given interface.
875  */
876 struct in_multi *
877 in_addmulti(struct in_addr *ap, struct ifnet *ifp)
878 {
879 	struct in_multi *inm;
880 	int error;
881 	struct sockaddr_in sin;
882 	struct ifmultiaddr *ifma;
883 
884 	/*
885 	 * Call generic routine to add membership or increment
886 	 * refcount.  It wants addresses in the form of a sockaddr,
887 	 * so we build one here (being careful to zero the unused bytes).
888 	 */
889 	bzero(&sin, sizeof sin);
890 	sin.sin_family = AF_INET;
891 	sin.sin_len = sizeof sin;
892 	sin.sin_addr = *ap;
893 	crit_enter();
894 	error = if_addmulti(ifp, (struct sockaddr *)&sin, &ifma);
895 	if (error) {
896 		crit_exit();
897 		return 0;
898 	}
899 
900 	/*
901 	 * If ifma->ifma_protospec is null, then if_addmulti() created
902 	 * a new record.  Otherwise, we are done.
903 	 */
904 	if (ifma->ifma_protospec != 0) {
905 		crit_exit();
906 		return ifma->ifma_protospec;
907 	}
908 
909 	/* XXX - if_addmulti uses M_WAITOK.  Can this really be called
910 	   at interrupt time?  If so, need to fix if_addmulti. XXX */
911 	inm = kmalloc(sizeof *inm, M_IPMADDR, M_WAITOK | M_ZERO);
912 	inm->inm_addr = *ap;
913 	inm->inm_ifp = ifp;
914 	inm->inm_ifma = ifma;
915 	ifma->ifma_protospec = inm;
916 	LIST_INSERT_HEAD(&in_multihead, inm, inm_link);
917 
918 	/*
919 	 * Let IGMP know that we have joined a new IP multicast group.
920 	 */
921 	igmp_joingroup(inm);
922 	crit_exit();
923 	return (inm);
924 }
925 
926 /*
927  * Delete a multicast address record.
928  */
929 void
930 in_delmulti(struct in_multi *inm)
931 {
932 	struct ifmultiaddr *ifma;
933 	struct in_multi my_inm;
934 
935 	crit_enter();
936 	ifma = inm->inm_ifma;
937 	my_inm.inm_ifp = NULL ; /* don't send the leave msg */
938 	if (ifma->ifma_refcount == 1) {
939 		/*
940 		 * No remaining claims to this record; let IGMP know that
941 		 * we are leaving the multicast group.
942 		 * But do it after the if_delmulti() which might reset
943 		 * the interface and nuke the packet.
944 		 */
945 		my_inm = *inm ;
946 		ifma->ifma_protospec = 0;
947 		LIST_REMOVE(inm, inm_link);
948 		kfree(inm, M_IPMADDR);
949 	}
950 	/* XXX - should be separate API for when we have an ifma? */
951 	if_delmulti(ifma->ifma_ifp, ifma->ifma_addr);
952 	if (my_inm.inm_ifp != NULL)
953 		igmp_leavegroup(&my_inm);
954 	crit_exit();
955 }
956 
957 void
958 in_ifdetach(struct ifnet *ifp)
959 {
960 	in_pcbpurgeif0(LIST_FIRST(&ripcbinfo.pcblisthead), ifp);
961 	in_pcbpurgeif0(LIST_FIRST(&udbinfo.pcblisthead), ifp);
962 }
963