1 /*	$OpenBSD: in.c,v 1.40 2005/03/07 10:40:42 claudio 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 <dev/rndvar.h>
71 
72 #include <net/if.h>
73 #include <net/route.h>
74 
75 #include <netinet/in.h>
76 #include <netinet/in_var.h>
77 #include <netinet/igmp_var.h>
78 
79 #ifdef MROUTING
80 #include <netinet/ip_mroute.h>
81 #endif
82 
83 #include "ether.h"
84 
85 #ifdef INET
86 
87 static int in_mask2len(struct in_addr *);
88 static void in_len2mask(struct in_addr *, int);
89 static int in_lifaddr_ioctl(struct socket *, u_long, caddr_t,
90 	struct ifnet *);
91 
92 static int in_addprefix(struct in_ifaddr *, int);
93 static int in_scrubprefix(struct in_ifaddr *);
94 
95 #ifndef SUBNETSARELOCAL
96 #define	SUBNETSARELOCAL	0
97 #endif
98 
99 #ifndef HOSTZEROBROADCAST
100 #define HOSTZEROBROADCAST 1
101 #endif
102 
103 int subnetsarelocal = SUBNETSARELOCAL;
104 int hostzeroisbroadcast = HOSTZEROBROADCAST;
105 
106 /*
107  * Return 1 if an internet address is for a ``local'' host
108  * (one to which we have a connection).  If subnetsarelocal
109  * is true, this includes other subnets of the local net.
110  * Otherwise, it includes only the directly-connected (sub)nets.
111  */
112 int
in_localaddr(in)113 in_localaddr(in)
114 	struct in_addr in;
115 {
116 	struct in_ifaddr *ia;
117 
118 	if (subnetsarelocal) {
119 		for (ia = in_ifaddr.tqh_first; ia != 0; ia = ia->ia_list.tqe_next)
120 			if ((in.s_addr & ia->ia_netmask) == ia->ia_net)
121 				return (1);
122 	} else {
123 		for (ia = in_ifaddr.tqh_first; ia != 0; ia = ia->ia_list.tqe_next)
124 			if ((in.s_addr & ia->ia_subnetmask) == ia->ia_subnet)
125 				return (1);
126 	}
127 	return (0);
128 }
129 
130 /*
131  * Determine whether an IP address is in a reserved set of addresses
132  * that may not be forwarded, or whether datagrams to that destination
133  * may be forwarded.
134  */
135 int
in_canforward(in)136 in_canforward(in)
137 	struct in_addr in;
138 {
139 	u_int32_t net;
140 
141 	if (IN_EXPERIMENTAL(in.s_addr) || IN_MULTICAST(in.s_addr))
142 		return (0);
143 	if (IN_CLASSA(in.s_addr)) {
144 		net = in.s_addr & IN_CLASSA_NET;
145 		if (net == 0 || net == htonl(IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
146 			return (0);
147 	}
148 	return (1);
149 }
150 
151 /*
152  * Trim a mask in a sockaddr
153  */
154 void
in_socktrim(ap)155 in_socktrim(ap)
156 	struct sockaddr_in *ap;
157 {
158 	char *cplim = (char *) &ap->sin_addr;
159 	char *cp = (char *) (&ap->sin_addr + 1);
160 
161 	ap->sin_len = 0;
162 	while (--cp >= cplim)
163 		if (*cp) {
164 			(ap)->sin_len = cp - (char *) (ap) + 1;
165 			break;
166 		}
167 }
168 
169 static int
in_mask2len(mask)170 in_mask2len(mask)
171 	struct in_addr *mask;
172 {
173 	int x, y;
174 	u_char *p;
175 
176 	p = (u_char *)mask;
177 	for (x = 0; x < sizeof(*mask); x++) {
178 		if (p[x] != 0xff)
179 			break;
180 	}
181 	y = 0;
182 	if (x < sizeof(*mask)) {
183 		for (y = 0; y < 8; y++) {
184 			if ((p[x] & (0x80 >> y)) == 0)
185 				break;
186 		}
187 	}
188 	return x * 8 + y;
189 }
190 
191 static void
in_len2mask(mask,len)192 in_len2mask(mask, len)
193 	struct in_addr *mask;
194 	int len;
195 {
196 	int i;
197 	u_char *p;
198 
199 	p = (u_char *)mask;
200 	bzero(mask, sizeof(*mask));
201 	for (i = 0; i < len / 8; i++)
202 		p[i] = 0xff;
203 	if (len % 8)
204 		p[i] = (0xff00 >> (len % 8)) & 0xff;
205 }
206 
207 int	in_interfaces;		/* number of external internet interfaces */
208 
209 /*
210  * Generic internet control operations (ioctl's).
211  * Ifp is 0 if not an interface-specific ioctl.
212  */
213 /* ARGSUSED */
214 int
in_control(so,cmd,data,ifp)215 in_control(so, cmd, data, ifp)
216 	struct socket *so;
217 	u_long cmd;
218 	caddr_t data;
219 	struct ifnet *ifp;
220 {
221 	struct ifreq *ifr = (struct ifreq *)data;
222 	struct in_ifaddr *ia = 0;
223 	struct in_aliasreq *ifra = (struct in_aliasreq *)data;
224 	struct sockaddr_in oldaddr;
225 	int error, hostIsNew, maskIsNew;
226 	int newifaddr;
227 	int s;
228 
229 	switch (cmd) {
230 	case SIOCALIFADDR:
231 	case SIOCDLIFADDR:
232 		if ((so->so_state & SS_PRIV) == 0)
233 			return (EPERM);
234 		/*fall through*/
235 	case SIOCGLIFADDR:
236 		if (!ifp)
237 			return EINVAL;
238 		return in_lifaddr_ioctl(so, cmd, data, ifp);
239 	}
240 
241 	/*
242 	 * Find address for this interface, if it exists.
243 	 */
244 	if (ifp)
245 		for (ia = in_ifaddr.tqh_first; ia; ia = ia->ia_list.tqe_next)
246 			if (ia->ia_ifp == ifp)
247 				break;
248 
249 	switch (cmd) {
250 
251 	case SIOCAIFADDR:
252 	case SIOCDIFADDR:
253 		if (ifra->ifra_addr.sin_family == AF_INET)
254 		    for (; ia != 0; ia = ia->ia_list.tqe_next) {
255 			if (ia->ia_ifp == ifp &&
256 			    ia->ia_addr.sin_addr.s_addr ==
257 				ifra->ifra_addr.sin_addr.s_addr)
258 			    break;
259 		}
260 		if (cmd == SIOCDIFADDR && ia == 0)
261 			return (EADDRNOTAVAIL);
262 		/* FALLTHROUGH */
263 	case SIOCSIFADDR:
264 	case SIOCSIFNETMASK:
265 	case SIOCSIFDSTADDR:
266 		if ((so->so_state & SS_PRIV) == 0)
267 			return (EPERM);
268 
269 		if (ifp == 0)
270 			panic("in_control");
271 		if (ia == (struct in_ifaddr *)0) {
272 			ia = (struct in_ifaddr *)
273 				malloc(sizeof *ia, M_IFADDR, M_WAITOK);
274 			bzero((caddr_t)ia, sizeof *ia);
275 			s = splsoftnet();
276 			TAILQ_INSERT_TAIL(&in_ifaddr, ia, ia_list);
277 			TAILQ_INSERT_TAIL(&ifp->if_addrlist, (struct ifaddr *)ia,
278 			    ifa_list);
279 			ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
280 			ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
281 			ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
282 			ia->ia_sockmask.sin_len = 8;
283 			if (ifp->if_flags & IFF_BROADCAST) {
284 				ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
285 				ia->ia_broadaddr.sin_family = AF_INET;
286 			}
287 			ia->ia_ifp = ifp;
288 			LIST_INIT(&ia->ia_multiaddrs);
289 			if ((ifp->if_flags & IFF_LOOPBACK) == 0)
290 				in_interfaces++;
291 			rnd_lopool_addh(ia, sizeof(*ia));
292 			splx(s);
293 
294 			newifaddr = 1;
295 		} else
296 			newifaddr = 0;
297 		break;
298 
299 	case SIOCSIFBRDADDR:
300 		if ((so->so_state & SS_PRIV) == 0)
301 			return (EPERM);
302 		/* FALLTHROUGH */
303 
304 	case SIOCGIFADDR:
305 	case SIOCGIFNETMASK:
306 	case SIOCGIFDSTADDR:
307 	case SIOCGIFBRDADDR:
308 		if (ia && satosin(&ifr->ifr_addr)->sin_addr.s_addr) {
309 			struct in_ifaddr *ia2;
310 
311 			for (ia2 = ia; ia2; ia2 = ia2->ia_list.tqe_next) {
312 				if (ia2->ia_ifp == ifp &&
313 				    ia2->ia_addr.sin_addr.s_addr ==
314 				    satosin(&ifr->ifr_addr)->sin_addr.s_addr)
315 					break;
316 			}
317 			if (ia2 && ia2->ia_ifp == ifp)
318 				ia = ia2;
319 		}
320 		if (ia == (struct in_ifaddr *)0)
321 			return (EADDRNOTAVAIL);
322 		break;
323 	}
324 	switch (cmd) {
325 
326 	case SIOCGIFADDR:
327 		*satosin(&ifr->ifr_addr) = ia->ia_addr;
328 		break;
329 
330 	case SIOCGIFBRDADDR:
331 		if ((ifp->if_flags & IFF_BROADCAST) == 0)
332 			return (EINVAL);
333 		*satosin(&ifr->ifr_dstaddr) = ia->ia_broadaddr;
334 		break;
335 
336 	case SIOCGIFDSTADDR:
337 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
338 			return (EINVAL);
339 		*satosin(&ifr->ifr_dstaddr) = ia->ia_dstaddr;
340 		break;
341 
342 	case SIOCGIFNETMASK:
343 		*satosin(&ifr->ifr_addr) = ia->ia_sockmask;
344 		break;
345 
346 	case SIOCSIFDSTADDR:
347 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
348 			return (EINVAL);
349 		s = splsoftnet();
350 		oldaddr = ia->ia_dstaddr;
351 		ia->ia_dstaddr = *satosin(&ifr->ifr_dstaddr);
352 		if (ifp->if_ioctl && (error = (*ifp->if_ioctl)
353 					(ifp, SIOCSIFDSTADDR, (caddr_t)ia))) {
354 			ia->ia_dstaddr = oldaddr;
355 			splx(s);
356 			return (error);
357 		}
358 		if (ia->ia_flags & IFA_ROUTE) {
359 			ia->ia_ifa.ifa_dstaddr = sintosa(&oldaddr);
360 			rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
361 			ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
362 			rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
363 		}
364 		splx(s);
365 		break;
366 
367 	case SIOCSIFBRDADDR:
368 		if ((ifp->if_flags & IFF_BROADCAST) == 0)
369 			return (EINVAL);
370 		ia->ia_broadaddr = *satosin(&ifr->ifr_broadaddr);
371 		break;
372 
373 	case SIOCSIFADDR:
374 		s = splsoftnet();
375 		error = in_ifinit(ifp, ia, satosin(&ifr->ifr_addr), 1);
376 		if (!error)
377 			dohooks(ifp->if_addrhooks, 0);
378 		splx(s);
379 		return error;
380 
381 	case SIOCSIFNETMASK:
382 		ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr =
383 		    ifra->ifra_addr.sin_addr.s_addr;
384 		break;
385 
386 	case SIOCAIFADDR:
387 		maskIsNew = 0;
388 		hostIsNew = 1;
389 		error = 0;
390 		s = splsoftnet();
391 		if (ia->ia_addr.sin_family == AF_INET) {
392 			if (ifra->ifra_addr.sin_len == 0) {
393 				ifra->ifra_addr = ia->ia_addr;
394 				hostIsNew = 0;
395 			} else if (ifra->ifra_addr.sin_addr.s_addr ==
396 					       ia->ia_addr.sin_addr.s_addr)
397 				hostIsNew = 0;
398 		}
399 		if (ifra->ifra_mask.sin_len) {
400 			in_ifscrub(ifp, ia);
401 			ia->ia_sockmask = ifra->ifra_mask;
402 			ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr;
403 			maskIsNew = 1;
404 		}
405 		if ((ifp->if_flags & IFF_POINTOPOINT) &&
406 		    (ifra->ifra_dstaddr.sin_family == AF_INET)) {
407 			in_ifscrub(ifp, ia);
408 			ia->ia_dstaddr = ifra->ifra_dstaddr;
409 			maskIsNew  = 1; /* We lie; but the effect's the same */
410 		}
411 		if (ifra->ifra_addr.sin_family == AF_INET &&
412 		    (hostIsNew || maskIsNew)) {
413 			error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
414 		}
415 		if ((ifp->if_flags & IFF_BROADCAST) &&
416 		    (ifra->ifra_broadaddr.sin_family == AF_INET))
417 			ia->ia_broadaddr = ifra->ifra_broadaddr;
418 		if (!error)
419 			dohooks(ifp->if_addrhooks, 0);
420 		splx(s);
421 		return (error);
422 
423 	case SIOCDIFADDR: {
424 		struct in_multi *inm;
425 
426 		/*
427 		 * Even if the individual steps were safe, shouldn't
428 		 * these kinds of changes happen atomically?  What
429 		 * should happen to a packet that was routed after
430 		 * the scrub but before the other steps?
431 		 */
432 		s = splsoftnet();
433 		in_ifscrub(ifp, ia);
434 		TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
435 		TAILQ_REMOVE(&in_ifaddr, ia, ia_list);
436 		while ((inm = LIST_FIRST(&ia->ia_multiaddrs)) != NULL)
437 			in_delmulti(inm);
438 		IFAFREE((&ia->ia_ifa));
439 		dohooks(ifp->if_addrhooks, 0);
440 		splx(s);
441 		break;
442 		}
443 
444 #ifdef MROUTING
445 	case SIOCGETVIFCNT:
446 	case SIOCGETSGCNT:
447 		return (mrt_ioctl(cmd, data));
448 #endif /* MROUTING */
449 
450 	default:
451 		if (ifp == 0 || ifp->if_ioctl == 0)
452 			return (EOPNOTSUPP);
453 		return ((*ifp->if_ioctl)(ifp, cmd, data));
454 	}
455 	return (0);
456 }
457 
458 /*
459  * SIOC[GAD]LIFADDR.
460  *	SIOCGLIFADDR: get first address. (???)
461  *	SIOCGLIFADDR with IFLR_PREFIX:
462  *		get first address that matches the specified prefix.
463  *	SIOCALIFADDR: add the specified address.
464  *	SIOCALIFADDR with IFLR_PREFIX:
465  *		EINVAL since we can't deduce hostid part of the address.
466  *	SIOCDLIFADDR: delete the specified address.
467  *	SIOCDLIFADDR with IFLR_PREFIX:
468  *		delete the first address that matches the specified prefix.
469  * return values:
470  *	EINVAL on invalid parameters
471  *	EADDRNOTAVAIL on prefix match failed/specified address not found
472  *	other values may be returned from in_ioctl()
473  */
474 static int
in_lifaddr_ioctl(so,cmd,data,ifp)475 in_lifaddr_ioctl(so, cmd, data, ifp)
476 	struct socket *so;
477 	u_long cmd;
478 	caddr_t	data;
479 	struct ifnet *ifp;
480 {
481 	struct if_laddrreq *iflr = (struct if_laddrreq *)data;
482 	struct ifaddr *ifa;
483 	struct sockaddr *sa;
484 
485 	/* sanity checks */
486 	if (!data || !ifp) {
487 		panic("invalid argument to in_lifaddr_ioctl");
488 		/*NOTRECHED*/
489 	}
490 
491 	switch (cmd) {
492 	case SIOCGLIFADDR:
493 		/* address must be specified on GET with IFLR_PREFIX */
494 		if ((iflr->flags & IFLR_PREFIX) == 0)
495 			break;
496 		/*FALLTHROUGH*/
497 	case SIOCALIFADDR:
498 	case SIOCDLIFADDR:
499 		/* address must be specified on ADD and DELETE */
500 		sa = (struct sockaddr *)&iflr->addr;
501 		if (sa->sa_family != AF_INET)
502 			return EINVAL;
503 		if (sa->sa_len != sizeof(struct sockaddr_in))
504 			return EINVAL;
505 		/* XXX need improvement */
506 		sa = (struct sockaddr *)&iflr->dstaddr;
507 		if (sa->sa_family
508 		 && sa->sa_family != AF_INET)
509 			return EINVAL;
510 		if (sa->sa_len && sa->sa_len != sizeof(struct sockaddr_in))
511 			return EINVAL;
512 		break;
513 	default: /*shouldn't happen*/
514 #if 0
515 		panic("invalid cmd to in_lifaddr_ioctl");
516 		/*NOTREACHED*/
517 #else
518 		return EOPNOTSUPP;
519 #endif
520 	}
521 	if (sizeof(struct in_addr) * 8 < iflr->prefixlen)
522 		return EINVAL;
523 
524 	switch (cmd) {
525 	case SIOCALIFADDR:
526 	    {
527 		struct in_aliasreq ifra;
528 
529 		if (iflr->flags & IFLR_PREFIX)
530 			return EINVAL;
531 
532 		/* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
533 		bzero(&ifra, sizeof(ifra));
534 		bcopy(iflr->iflr_name, ifra.ifra_name,
535 			sizeof(ifra.ifra_name));
536 
537 		bcopy(&iflr->addr, &ifra.ifra_addr,
538 			((struct sockaddr *)&iflr->addr)->sa_len);
539 
540 		if (((struct sockaddr *)&iflr->dstaddr)->sa_family) {	/*XXX*/
541 			bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
542 				((struct sockaddr *)&iflr->dstaddr)->sa_len);
543 		}
544 
545 		ifra.ifra_mask.sin_family = AF_INET;
546 		ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in);
547 		in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen);
548 
549 		return in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp);
550 	    }
551 	case SIOCGLIFADDR:
552 	case SIOCDLIFADDR:
553 	    {
554 		struct in_ifaddr *ia;
555 		struct in_addr mask, candidate, match;
556 		struct sockaddr_in *sin;
557 		int cmp;
558 
559 		bzero(&mask, sizeof(mask));
560 		if (iflr->flags & IFLR_PREFIX) {
561 			/* lookup a prefix rather than address. */
562 			in_len2mask(&mask, iflr->prefixlen);
563 
564 			sin = (struct sockaddr_in *)&iflr->addr;
565 			match.s_addr = sin->sin_addr.s_addr;
566 			match.s_addr &= mask.s_addr;
567 
568 			/* if you set extra bits, that's wrong */
569 			if (match.s_addr != sin->sin_addr.s_addr)
570 				return EINVAL;
571 
572 			cmp = 1;
573 		} else {
574 			if (cmd == SIOCGLIFADDR) {
575 				/* on getting an address, take the 1st match */
576 				cmp = 0;	/*XXX*/
577 			} else {
578 				/* on deleting an address, do exact match */
579 				in_len2mask(&mask, 32);
580 				sin = (struct sockaddr_in *)&iflr->addr;
581 				match.s_addr = sin->sin_addr.s_addr;
582 
583 				cmp = 1;
584 			}
585 		}
586 
587 		for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = ifa->ifa_list.tqe_next) {
588 			if (ifa->ifa_addr->sa_family != AF_INET6)
589 				continue;
590 			if (!cmp)
591 				break;
592 			candidate.s_addr = ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr;
593 			candidate.s_addr &= mask.s_addr;
594 			if (candidate.s_addr == match.s_addr)
595 				break;
596 		}
597 		if (!ifa)
598 			return EADDRNOTAVAIL;
599 		ia = (struct in_ifaddr *)ifa;
600 
601 		if (cmd == SIOCGLIFADDR) {
602 			/* fill in the if_laddrreq structure */
603 			bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len);
604 
605 			if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
606 				bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
607 					ia->ia_dstaddr.sin_len);
608 			} else
609 				bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
610 
611 			iflr->prefixlen =
612 				in_mask2len(&ia->ia_sockmask.sin_addr);
613 
614 			iflr->flags = 0;	/*XXX*/
615 
616 			return 0;
617 		} else {
618 			struct in_aliasreq ifra;
619 
620 			/* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
621 			bzero(&ifra, sizeof(ifra));
622 			bcopy(iflr->iflr_name, ifra.ifra_name,
623 				sizeof(ifra.ifra_name));
624 
625 			bcopy(&ia->ia_addr, &ifra.ifra_addr,
626 				ia->ia_addr.sin_len);
627 			if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
628 				bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
629 					ia->ia_dstaddr.sin_len);
630 			}
631 			bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr,
632 				ia->ia_sockmask.sin_len);
633 
634 			return in_control(so, SIOCDIFADDR, (caddr_t)&ifra, ifp);
635 		}
636 	    }
637 	}
638 
639 	return EOPNOTSUPP;	/*just for safety*/
640 }
641 
642 /*
643  * Delete any existing route for an interface.
644  */
645 void
in_ifscrub(ifp,ia)646 in_ifscrub(ifp, ia)
647 	struct ifnet *ifp;
648 	struct in_ifaddr *ia;
649 {
650 
651 	in_scrubprefix(ia);
652 }
653 
654 /*
655  * Initialize an interface's internet address
656  * and routing table entry.
657  */
658 int
in_ifinit(ifp,ia,sin,scrub)659 in_ifinit(ifp, ia, sin, scrub)
660 	struct ifnet *ifp;
661 	struct in_ifaddr *ia;
662 	struct sockaddr_in *sin;
663 	int scrub;
664 {
665 	u_int32_t i = sin->sin_addr.s_addr;
666 	struct sockaddr_in oldaddr;
667 	int s = splimp(), flags = RTF_UP, error;
668 
669 	oldaddr = ia->ia_addr;
670 	ia->ia_addr = *sin;
671 	/*
672 	 * Give the interface a chance to initialize
673 	 * if this is its first address,
674 	 * and to validate the address if necessary.
675 	 */
676 	if (ifp->if_ioctl &&
677 	    (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
678 		ia->ia_addr = oldaddr;
679 		splx(s);
680 		return (error);
681 	}
682 	splx(s);
683 
684 	/*
685 	 * How should a packet be routed during
686 	 * an address change--and is it safe?
687 	 * Is the "ifp" even in a consistent state?
688 	 * Be safe for now.
689 	 */
690 	splassert(IPL_SOFTNET);
691 
692 	if (scrub) {
693 		ia->ia_ifa.ifa_addr = sintosa(&oldaddr);
694 		in_ifscrub(ifp, ia);
695 		ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
696 	}
697 	if (IN_CLASSA(i))
698 		ia->ia_netmask = IN_CLASSA_NET;
699 	else if (IN_CLASSB(i))
700 		ia->ia_netmask = IN_CLASSB_NET;
701 	else
702 		ia->ia_netmask = IN_CLASSC_NET;
703 	/*
704 	 * The subnet mask usually includes at least the standard network part,
705 	 * but may may be smaller in the case of supernetting.
706 	 * If it is set, we believe it.
707 	 */
708 	if (ia->ia_subnetmask == 0) {
709 		ia->ia_subnetmask = ia->ia_netmask;
710 		ia->ia_sockmask.sin_addr.s_addr = ia->ia_subnetmask;
711 	} else
712 		ia->ia_netmask &= ia->ia_subnetmask;
713 	ia->ia_net = i & ia->ia_netmask;
714 	ia->ia_subnet = i & ia->ia_subnetmask;
715 	in_socktrim(&ia->ia_sockmask);
716 	/*
717 	 * Add route for the network.
718 	 */
719 	ia->ia_ifa.ifa_metric = ifp->if_metric;
720 	if (ifp->if_flags & IFF_BROADCAST) {
721 		ia->ia_broadaddr.sin_addr.s_addr =
722 			ia->ia_subnet | ~ia->ia_subnetmask;
723 		ia->ia_netbroadcast.s_addr =
724 			ia->ia_net | ~ia->ia_netmask;
725 	} else if (ifp->if_flags & IFF_LOOPBACK) {
726 		ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
727 		flags |= RTF_HOST;
728 	} else if (ifp->if_flags & IFF_POINTOPOINT) {
729 		if (ia->ia_dstaddr.sin_family != AF_INET)
730 			return (0);
731 		flags |= RTF_HOST;
732 	}
733 	error = in_addprefix(ia, flags);
734 	/*
735 	 * If the interface supports multicast, join the "all hosts"
736 	 * multicast group on that interface.
737 	 */
738 	if (ifp->if_flags & IFF_MULTICAST) {
739 		struct in_addr addr;
740 
741 		addr.s_addr = INADDR_ALLHOSTS_GROUP;
742 		in_addmulti(&addr, ifp);
743 	}
744 	return (error);
745 }
746 
747 #define rtinitflags(x) \
748 	((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \
749 	    ? RTF_HOST : 0)
750 
751 /*
752  * add a route to prefix ("connected route" in cisco terminology).
753  * does nothing if there's some interface address with the same prefix already.
754  */
755 static int
in_addprefix(target,flags)756 in_addprefix(target, flags)
757 	struct in_ifaddr *target;
758 	int flags;
759 {
760 	struct in_ifaddr *ia;
761 	struct in_addr prefix, mask, p;
762 	int error;
763 
764 	if ((flags & RTF_HOST) != 0)
765 		prefix = target->ia_dstaddr.sin_addr;
766 	else {
767 		prefix = target->ia_addr.sin_addr;
768 		mask = target->ia_sockmask.sin_addr;
769 		prefix.s_addr &= mask.s_addr;
770 	}
771 
772 	TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
773 		if (rtinitflags(ia)) {
774 			p = ia->ia_dstaddr.sin_addr;
775 			if (prefix.s_addr != p.s_addr)
776 				continue;
777 		} else {
778 			p = ia->ia_addr.sin_addr;
779 			p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
780 			if (prefix.s_addr != p.s_addr ||
781 			    mask.s_addr != ia->ia_sockmask.sin_addr.s_addr)
782 				continue;
783 		}
784 
785 		/*
786 		 * if we got a matching prefix route inserted by other
787 		 * interface adderss, we don't need to bother
788 		 */
789 		if (ia->ia_flags & IFA_ROUTE)
790 			return 0;
791 	}
792 
793 	/*
794 	 * noone seem to have prefix route.  insert it.
795 	 */
796 	error = rtinit(&target->ia_ifa, (int)RTM_ADD, flags);
797 	if (!error)
798 		target->ia_flags |= IFA_ROUTE;
799 	return error;
800 }
801 
802 /*
803  * remove a route to prefix ("connected route" in cisco terminology).
804  * re-installs the route by using another interface address, if there's one
805  * with the same prefix (otherwise we lose the route mistakenly).
806  */
807 static int
in_scrubprefix(target)808 in_scrubprefix(target)
809 	struct in_ifaddr *target;
810 {
811 	struct in_ifaddr *ia;
812 	struct in_addr prefix, mask, p;
813 	int error;
814 
815 	if ((target->ia_flags & IFA_ROUTE) == 0)
816 		return 0;
817 
818 	if (rtinitflags(target))
819 		prefix = target->ia_dstaddr.sin_addr;
820 	else {
821 		prefix = target->ia_addr.sin_addr;
822 		mask = target->ia_sockmask.sin_addr;
823 		prefix.s_addr &= mask.s_addr;
824 	}
825 
826 	for (ia = in_ifaddr.tqh_first; ia; ia = ia->ia_list.tqe_next) {
827 		if (rtinitflags(ia))
828 			p = ia->ia_dstaddr.sin_addr;
829 		else {
830 			p = ia->ia_addr.sin_addr;
831 			p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
832 		}
833 
834 		if (prefix.s_addr != p.s_addr)
835 			continue;
836 
837 		/*
838 		 * if we got a matching prefix route, move IFA_ROUTE to him
839 		 */
840 		if ((ia->ia_flags & IFA_ROUTE) == 0) {
841 			rtinit(&(target->ia_ifa), (int)RTM_DELETE,
842 			    rtinitflags(target));
843 			target->ia_flags &= ~IFA_ROUTE;
844 
845 			error = rtinit(&ia->ia_ifa, (int)RTM_ADD,
846 			    rtinitflags(ia) | RTF_UP);
847 			if (error == 0)
848 				ia->ia_flags |= IFA_ROUTE;
849 			return error;
850 		}
851 	}
852 
853 	/*
854 	 * noone seem to have prefix route.  remove it.
855 	 */
856 	rtinit(&(target->ia_ifa), (int)RTM_DELETE, rtinitflags(target));
857 	target->ia_flags &= ~IFA_ROUTE;
858 	return 0;
859 }
860 
861 #undef rtinitflags
862 
863 /*
864  * Return 1 if the address might be a local broadcast address.
865  */
866 int
in_broadcast(in,ifp)867 in_broadcast(in, ifp)
868 	struct in_addr in;
869 	struct ifnet *ifp;
870 {
871 	struct ifnet *ifn, *if_first, *if_target;
872 	struct ifaddr *ifa;
873 
874 	if (in.s_addr == INADDR_BROADCAST ||
875 	    in.s_addr == INADDR_ANY)
876 		return 1;
877 
878 	if (ifp == NULL) {
879 	  	if_first = ifnet.tqh_first;
880 		if_target = 0;
881 	} else {
882 		if_first = ifp;
883 		if_target = ifp->if_list.tqe_next;
884 	}
885 
886 #define ia (ifatoia(ifa))
887 	/*
888 	 * Look through the list of addresses for a match
889 	 * with a broadcast address.
890 	 * If ifp is NULL, check against all the interfaces.
891 	 */
892         for (ifn = if_first; ifn != if_target; ifn = ifn->if_list.tqe_next) {
893 		if ((ifn->if_flags & IFF_BROADCAST) == 0)
894 			continue;
895 		for (ifa = ifn->if_addrlist.tqh_first; ifa;
896 		    ifa = ifa->ifa_list.tqe_next)
897 			if (ifa->ifa_addr->sa_family == AF_INET &&
898 			    in.s_addr != ia->ia_addr.sin_addr.s_addr &&
899 			    (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
900 			     in.s_addr == ia->ia_netbroadcast.s_addr ||
901 			     (hostzeroisbroadcast &&
902 			      /*
903 			       * Check for old-style (host 0) broadcast.
904 			       */
905 			      (in.s_addr == ia->ia_subnet ||
906 			       in.s_addr == ia->ia_net))))
907 				return 1;
908 	}
909 	return (0);
910 #undef ia
911 }
912 
913 /*
914  * Add an address to the list of IP multicast addresses for a given interface.
915  */
916 struct in_multi *
in_addmulti(ap,ifp)917 in_addmulti(ap, ifp)
918 	struct in_addr *ap;
919 	struct ifnet *ifp;
920 {
921 	struct in_multi *inm;
922 	struct ifreq ifr;
923 	struct in_ifaddr *ia;
924 	int s = splsoftnet();
925 
926 	/*
927 	 * See if address already in list.
928 	 */
929 	IN_LOOKUP_MULTI(*ap, ifp, inm);
930 	if (inm != NULL) {
931 		/*
932 		 * Found it; just increment the reference count.
933 		 */
934 		++inm->inm_refcount;
935 	} else {
936 		/*
937 		 * New address; allocate a new multicast record
938 		 * and link it into the interface's multicast list.
939 		 */
940 		inm = (struct in_multi *)malloc(sizeof(*inm),
941 		    M_IPMADDR, M_NOWAIT);
942 		if (inm == NULL) {
943 			splx(s);
944 			return (NULL);
945 		}
946 		inm->inm_addr = *ap;
947 		inm->inm_ifp = ifp;
948 		inm->inm_refcount = 1;
949 		IFP_TO_IA(ifp, ia);
950 		if (ia == NULL) {
951 			free(inm, M_IPMADDR);
952 			splx(s);
953 			return (NULL);
954 		}
955 		inm->inm_ia = ia;
956 		LIST_INSERT_HEAD(&ia->ia_multiaddrs, inm, inm_list);
957 		/*
958 		 * Ask the network driver to update its multicast reception
959 		 * filter appropriately for the new address.
960 		 */
961 		satosin(&ifr.ifr_addr)->sin_len = sizeof(struct sockaddr_in);
962 		satosin(&ifr.ifr_addr)->sin_family = AF_INET;
963 		satosin(&ifr.ifr_addr)->sin_addr = *ap;
964 		if ((ifp->if_ioctl == NULL) ||
965 		    (*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) {
966 			LIST_REMOVE(inm, inm_list);
967 			free(inm, M_IPMADDR);
968 			splx(s);
969 			return (NULL);
970 		}
971 		/*
972 		 * Let IGMP know that we have joined a new IP multicast group.
973 		 */
974 		igmp_joingroup(inm);
975 	}
976 	splx(s);
977 	return (inm);
978 }
979 
980 /*
981  * Delete a multicast address record.
982  */
983 void
in_delmulti(inm)984 in_delmulti(inm)
985 	struct in_multi *inm;
986 {
987 	struct ifreq ifr;
988 	int s = splsoftnet();
989 
990 	if (--inm->inm_refcount == 0) {
991 		/*
992 		 * No remaining claims to this record; let IGMP know that
993 		 * we are leaving the multicast group.
994 		 */
995 		igmp_leavegroup(inm);
996 		/*
997 		 * Unlink from list.
998 		 */
999 		LIST_REMOVE(inm, inm_list);
1000 		/*
1001 		 * Notify the network driver to update its multicast reception
1002 		 * filter.
1003 		 */
1004 		satosin(&ifr.ifr_addr)->sin_family = AF_INET;
1005 		satosin(&ifr.ifr_addr)->sin_addr = inm->inm_addr;
1006 		(*inm->inm_ifp->if_ioctl)(inm->inm_ifp, SIOCDELMULTI,
1007 							     (caddr_t)&ifr);
1008 		free(inm, M_IPMADDR);
1009 	}
1010 	splx(s);
1011 }
1012 
1013 #endif
1014