xref: /freebsd/sys/netinet6/in6.c (revision 5129159789cc9d7bc514e4546b88e3427695002d)
1 /*
2  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3  * 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. Neither the name of the project nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
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. All advertising materials mentioning features or use of this software
45  *    must display the following acknowledgement:
46  *	This product includes software developed by the University of
47  *	California, Berkeley and its contributors.
48  * 4. Neither the name of the University nor the names of its contributors
49  *    may be used to endorse or promote products derived from this software
50  *    without specific prior written permission.
51  *
52  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62  * SUCH DAMAGE.
63  *
64  *	@(#)in.c	8.2 (Berkeley) 11/15/93
65  */
66 
67 #include <sys/param.h>
68 #include <sys/errno.h>
69 #include <sys/malloc.h>
70 #include <sys/socket.h>
71 #include <sys/socketvar.h>
72 #include <sys/sockio.h>
73 #include <sys/systm.h>
74 #include <sys/proc.h>
75 #include <sys/time.h>
76 #include <sys/kernel.h>
77 #include <sys/syslog.h>
78 
79 #include <net/if.h>
80 #include <net/if_types.h>
81 #include <net/route.h>
82 #include "gif.h"
83 
84 #include <net/if_dl.h>
85 
86 #include <netinet/in.h>
87 #include <netinet/in_var.h>
88 #include <netinet/if_ether.h>
89 
90 #include <netinet6/nd6.h>
91 #include <netinet6/ip6.h>
92 #include <netinet6/ip6_var.h>
93 #include <netinet6/mld6_var.h>
94 #include <netinet6/in6_ifattach.h>
95 #if NGIF > 0
96 #include <net/if_gif.h>
97 #endif
98 
99 #include <net/net_osdep.h>
100 
101 MALLOC_DEFINE(M_IPMADDR, "in6_multi", "internet multicast address");
102 
103 /*
104  * Definitions of some costant IP6 addresses.
105  */
106 const struct	in6_addr in6addr_any = IN6ADDR_ANY_INIT;
107 const struct	in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
108 const struct	in6_addr in6addr_nodelocal_allnodes =
109 	IN6ADDR_NODELOCAL_ALLNODES_INIT;
110 const struct	in6_addr in6addr_linklocal_allnodes =
111 	IN6ADDR_LINKLOCAL_ALLNODES_INIT;
112 const struct	in6_addr in6addr_linklocal_allrouters =
113 	IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
114 
115 const struct	in6_addr in6mask0 = IN6MASK0;
116 const struct	in6_addr in6mask32 = IN6MASK32;
117 const struct	in6_addr in6mask64 = IN6MASK64;
118 const struct	in6_addr in6mask96 = IN6MASK96;
119 const struct	in6_addr in6mask128 = IN6MASK128;
120 
121 static int	in6_lifaddr_ioctl __P((struct socket *, u_long, caddr_t,
122 	struct ifnet *, struct proc *));
123 struct	in6_multihead in6_multihead;	/* XXX BSS initialization */
124 
125 /*
126  * Determine whether an IP6 address is in a reserved set of addresses
127  * that may not be forwarded, or whether datagrams to that destination
128  * may be forwarded.
129  */
130 int
131 in6_canforward(src, dst)
132 	struct	in6_addr *src, *dst;
133 {
134 	if (IN6_IS_ADDR_LINKLOCAL(src) ||
135 	   IN6_IS_ADDR_LINKLOCAL(dst) ||
136 	   IN6_IS_ADDR_MULTICAST(dst))
137 		return(0);
138 	return(1);
139 }
140 
141 /*
142  * Check if the loopback entry will be automatically generated.
143  *   if 0 returned, will not be automatically generated.
144  *   if 1 returned, will be automatically generated.
145  */
146 static int
147 in6_is_ifloop_auto(struct ifaddr *ifa)
148 {
149 #define SIN6(s) ((struct sockaddr_in6 *)s)
150 	/*
151 	 * If RTF_CLONING is unset, or (IFF_LOOPBACK | IFF_POINTOPOINT),
152 	 * or netmask is all0 or all1, then cloning will not happen,
153 	 * then we can't rely on its loopback entry generation.
154 	 */
155 	if ((ifa->ifa_flags & RTF_CLONING) == 0 ||
156 	    (ifa->ifa_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) ||
157 	    (SIN6(ifa->ifa_netmask)->sin6_len == sizeof(struct sockaddr_in6)
158 	     &&
159 	     IN6_ARE_ADDR_EQUAL(&SIN6(ifa->ifa_netmask)->sin6_addr,
160 				&in6mask128)) ||
161 	    ((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_len == 0)
162 		return 0;
163 	else
164 		return 1;
165 #undef SIN6
166 }
167 
168 /*
169  * Subroutine for in6_ifaddloop() and in6_ifremloop().
170  * This routine does actual work.
171  */
172 static void
173 in6_ifloop_request(int cmd, struct ifaddr *ifa)
174 {
175 	struct sockaddr_in6 lo_sa;
176 	struct sockaddr_in6 all1_sa;
177 	struct rtentry *nrt = NULL;
178 
179 	bzero(&lo_sa, sizeof(lo_sa));
180 	bzero(&all1_sa, sizeof(all1_sa));
181 	lo_sa.sin6_family = AF_INET6;
182 	lo_sa.sin6_len = sizeof(struct sockaddr_in6);
183 	all1_sa = lo_sa;
184 	lo_sa.sin6_addr = in6addr_loopback;
185 	all1_sa.sin6_addr = in6mask128;
186 
187 	/* So we add or remove static loopback entry, here. */
188 	rtrequest(cmd, ifa->ifa_addr,
189 		  (struct sockaddr *)&lo_sa,
190 		  (struct sockaddr *)&all1_sa,
191 		  RTF_UP|RTF_HOST, &nrt);
192 
193 	/*
194 	 * Make sure rt_ifa be equal to IFA, the second argument of the
195 	 * function.
196 	 * We need this because when we refer rt_ifa->ia6_flags in ip6_input,
197 	 * we assume that the rt_ifa points to the address instead of the
198 	 * loopback address.
199 	 */
200 	if (cmd == RTM_ADD && nrt && ifa != nrt->rt_ifa) {
201 		nrt->rt_ifa->ifa_refcnt--;
202 		ifa->ifa_refcnt++;
203 		nrt->rt_ifa = ifa;
204 	}
205 	if (nrt)
206 		nrt->rt_refcnt--;
207 }
208 
209 /*
210  * Add ownaddr as loopback rtentry, if necessary(ex. on p2p link).
211  * Because, KAME needs loopback rtentry for ownaddr check in
212  * ip6_input().
213  */
214 static void
215 in6_ifaddloop(struct ifaddr *ifa)
216 {
217 	if (!in6_is_ifloop_auto(ifa)) {
218 		struct rtentry *rt;
219 
220 		/* If there is no loopback entry, allocate one. */
221 		rt = rtalloc1(ifa->ifa_addr, 0, 0);
222 		if (rt == 0 || (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0)
223 			in6_ifloop_request(RTM_ADD, ifa);
224 		if (rt)
225 			rt->rt_refcnt--;
226 	}
227 }
228 
229 /*
230  * Remove loopback rtentry of ownaddr generated by in6_ifaddloop(),
231  * if it exists.
232  */
233 static void
234 in6_ifremloop(struct ifaddr *ifa)
235 {
236 	if (!in6_is_ifloop_auto(ifa)) {
237 		struct in6_ifaddr *ia;
238 		int ia_count = 0;
239 
240 		/* If only one ifa for the loopback entry, delete it. */
241 		for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
242 			if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa),
243 					       &ia->ia_addr.sin6_addr)) {
244 				ia_count++;
245 				if (ia_count > 1)
246 					break;
247 			}
248 		}
249 		if (ia_count == 1)
250 			in6_ifloop_request(RTM_DELETE, ifa);
251 	}
252 }
253 
254 /*
255  * Subroutine for in6_ifaddproxy() and in6_ifremproxy().
256  * This routine does actual work.
257  * call in6_addmulti() when cmd == 1.
258  * call in6_delmulti() when cmd == 2.
259  */
260 static int
261 in6_ifproxy_request(int cmd, struct in6_ifaddr *ia)
262 {
263 	int error = 0;
264 
265 	/*
266 	 * If we have an IPv6 dstaddr on adding p2p interface,
267 	 * join dstaddr's solicited multicast on necessary interface.
268 	 */
269 	if ((ia->ia_ifp->if_flags & IFF_POINTOPOINT) &&
270 	    ia->ia_dstaddr.sin6_family == AF_INET6 &&
271 	    !IN6_IS_ADDR_LINKLOCAL(&ia->ia_dstaddr.sin6_addr)) {
272 		struct in6_ifaddr *ia_lan;
273 
274 		/*
275 		 * TODO: Join only on some specified interfaces by some
276 		 * configuration.
277 		 * Unsolicited Neighbor Advertisements will be also necessary.
278 		 *
279 		 * Now, join on interfaces which meets following.
280 		 *   -IFF_BROADCAST and IFF_MULTICAST
281 		 *    (NBMA is out of scope)
282 		 *   -the prefix value is same as p2p dstaddr
283 		 */
284 		for (ia_lan = in6_ifaddr; ia_lan; ia_lan = ia_lan->ia_next) {
285 			struct in6_addr llsol;
286 
287 			if ((ia_lan->ia_ifp->if_flags &
288 			     (IFF_BROADCAST|IFF_MULTICAST)) !=
289 			    (IFF_BROADCAST|IFF_MULTICAST))
290 				continue;
291 			if (!IN6_ARE_MASKED_ADDR_EQUAL(IA6_IN6(ia),
292 						       IA6_IN6(ia_lan),
293 						       IA6_MASKIN6(ia_lan)))
294 				continue;
295 			if (ia_lan->ia_ifp == ia->ia_ifp)
296 				continue;
297 
298 			/* init llsol */
299 			bzero(&llsol, sizeof(struct in6_addr));
300 			llsol.s6_addr16[0] = htons(0xff02);
301 			llsol.s6_addr16[1] = htons(ia_lan->ia_ifp->if_index);
302 			llsol.s6_addr32[1] = 0;
303 			llsol.s6_addr32[2] = htonl(1);
304 			llsol.s6_addr32[3] =
305 				ia->ia_dstaddr.sin6_addr.s6_addr32[3];
306 			llsol.s6_addr8[12] = 0xff;
307 
308 			if (cmd == 1)
309 				(void)in6_addmulti(&llsol,
310 						   ia_lan->ia_ifp,
311 						   &error);
312 			else if (cmd == 2) {
313 				struct in6_multi *in6m;
314 
315 				IN6_LOOKUP_MULTI(llsol,
316 						 ia_lan->ia_ifp,
317 						 in6m);
318 				if (in6m)
319 					in6_delmulti(in6m);
320 			}
321 		}
322 	}
323 	return error;
324 }
325 
326 static int
327 in6_ifaddproxy(struct in6_ifaddr *ia)
328 {
329 	return(in6_ifproxy_request(1, ia));
330 }
331 
332 static void
333 in6_ifremproxy(struct in6_ifaddr *ia)
334 {
335 	in6_ifproxy_request(2, ia);
336 }
337 
338 int
339 in6_ifindex2scopeid(idx)
340 	int idx;
341 {
342 	struct ifnet *ifp;
343 	struct ifaddr *ifa;
344 	struct sockaddr_in6 *sin6;
345 
346 	if (idx < 0 || if_index < idx)
347 		return -1;
348 	ifp = ifindex2ifnet[idx];
349 
350 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
351 	{
352 		if (ifa->ifa_addr->sa_family != AF_INET6)
353 			continue;
354 		sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
355 		if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
356 			return sin6->sin6_scope_id & 0xffff;
357 	}
358 
359 	return -1;
360 }
361 
362 int
363 in6_mask2len(mask)
364 	struct in6_addr *mask;
365 {
366 	int x, y;
367 
368 	for (x = 0; x < sizeof(*mask); x++) {
369 		if (mask->s6_addr8[x] != 0xff)
370 			break;
371 	}
372 	y = 0;
373 	if (x < sizeof(*mask)) {
374 		for (y = 0; y < 8; y++) {
375 			if ((mask->s6_addr8[x] & (0x80 >> y)) == 0)
376 				break;
377 		}
378 	}
379 	return x * 8 + y;
380 }
381 
382 void
383 in6_len2mask(mask, len)
384 	struct in6_addr *mask;
385 	int len;
386 {
387 	int i;
388 
389 	bzero(mask, sizeof(*mask));
390 	for (i = 0; i < len / 8; i++)
391 		mask->s6_addr8[i] = 0xff;
392 	if (len % 8)
393 		mask->s6_addr8[i] = (0xff00 >> (len % 8)) & 0xff;
394 }
395 
396 int	in6_interfaces;		/* number of external internet interfaces */
397 
398 #define ifa2ia6(ifa)	((struct in6_ifaddr *)(ifa))
399 #define ia62ifa(ia6)	((struct ifaddr *)(ia6))
400 
401 int
402 in6_control(so, cmd, data, ifp, p)
403 	struct	socket *so;
404 	u_long cmd;
405 	caddr_t	data;
406 	struct ifnet *ifp;
407 	struct proc *p;
408 {
409 	struct	in6_ifreq *ifr = (struct in6_ifreq *)data;
410 	struct	in6_ifaddr *ia, *oia;
411 	struct	in6_aliasreq *ifra = (struct in6_aliasreq *)data;
412 	struct	sockaddr_in6 oldaddr, net;
413 	int	error = 0, hostIsNew, prefixIsNew;
414 	int privileged;
415 
416 	privileged = 0;
417 	if (p && !suser(p))
418 		privileged++;
419 
420 	/*
421 	 * xxx should prevent processes for link-local addresses?
422 	 */
423 #if NGIF > 0
424 	if (ifp && ifp->if_type == IFT_GIF) {
425 		switch (cmd) {
426 		case SIOCSIFPHYADDR_IN6:
427 			if (!privileged)
428 				return(EPERM);
429 			/*fall through*/
430 		case SIOCGIFPSRCADDR_IN6:
431 		case SIOCGIFPDSTADDR_IN6:
432 			return gif_ioctl(ifp, cmd, data);
433 		}
434 	}
435 #endif
436 
437 	if (ifp == 0)
438 		return(EOPNOTSUPP);
439 
440 	switch (cmd) {
441 	case SIOCSNDFLUSH_IN6:
442 	case SIOCSPFXFLUSH_IN6:
443 	case SIOCSRTRFLUSH_IN6:
444 		if (!privileged)
445 			return(EPERM);
446 		/*fall through*/
447 	case SIOCGIFINFO_IN6:
448 	case SIOCGDRLST_IN6:
449 	case SIOCGPRLST_IN6:
450 	case SIOCGNBRINFO_IN6:
451 		return(nd6_ioctl(cmd, data, ifp));
452 	}
453 
454 	switch (cmd) {
455 	case SIOCSIFPREFIX_IN6:
456 	case SIOCDIFPREFIX_IN6:
457 	case SIOCAIFPREFIX_IN6:
458 	case SIOCCIFPREFIX_IN6:
459 	case SIOCSGIFPREFIX_IN6:
460 		if (!privileged)
461 			return(EPERM);
462 		/*fall through*/
463 	case SIOCGIFPREFIX_IN6:
464 		return(in6_prefix_ioctl(so, cmd, data, ifp));
465 	}
466 
467 	switch (cmd) {
468 	case SIOCALIFADDR:
469 	case SIOCDLIFADDR:
470 		if (!privileged)
471 			return(EPERM);
472 		/*fall through*/
473 	case SIOCGLIFADDR:
474 		return in6_lifaddr_ioctl(so, cmd, data, ifp, p);
475 	}
476 
477 	/*
478 	 * Find address for this interface, if it exists.
479 	 */
480 	{
481 
482 		struct sockaddr_in6 *sa6 =
483 			(struct sockaddr_in6 *)&ifra->ifra_addr;
484 
485 		if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
486 			if (sa6->sin6_addr.s6_addr16[1] == 0) {
487 				/* interface ID is not embedded by the user */
488 				sa6->sin6_addr.s6_addr16[1] =
489 					htons(ifp->if_index);
490 			} else
491 				if (sa6->sin6_addr.s6_addr16[1] !=
492 				    htons(ifp->if_index))
493 					return(EINVAL);	/* ifid is contradict */
494 			if (sa6->sin6_scope_id) {
495 				if (sa6->sin6_scope_id !=
496 				    (u_int32_t)ifp->if_index)
497 					return(EINVAL);
498 				sa6->sin6_scope_id = 0; /* XXX: good way? */
499 			}
500 		}
501 	}
502  	ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr);
503 
504 	switch (cmd) {
505 
506 	case SIOCDIFADDR_IN6:
507 		if (ia == 0)
508 			return(EADDRNOTAVAIL);
509 		/* FALLTHROUGH */
510 	case SIOCAIFADDR_IN6:
511 	case SIOCSIFADDR_IN6:
512 	case SIOCSIFNETMASK_IN6:
513 	case SIOCSIFDSTADDR_IN6:
514 		if (!privileged)
515 			return(EPERM);
516 		if (ia == 0) {
517 			ia = (struct in6_ifaddr *)
518 				malloc(sizeof(*ia), M_IFADDR, M_WAITOK);
519 			if (ia == NULL)
520 				return (ENOBUFS);
521 			bzero((caddr_t)ia, sizeof(*ia));
522 			ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
523 			ia->ia_ifa.ifa_dstaddr
524 				= (struct sockaddr *)&ia->ia_dstaddr;
525 			ia->ia_ifa.ifa_netmask
526 				= (struct sockaddr *)&ia->ia_prefixmask;
527 
528 			ia->ia_ifp = ifp;
529 			if ((oia = in6_ifaddr) != NULL) {
530 				for ( ; oia->ia_next; oia = oia->ia_next)
531 					continue;
532 				oia->ia_next = ia;
533 			} else
534 				in6_ifaddr = ia;
535 			TAILQ_INSERT_TAIL(&ifp->if_addrlist,
536 				(struct ifaddr *)ia, ifa_list);
537 			if ((ifp->if_flags & IFF_LOOPBACK) == 0)
538 				in6_interfaces++;	/*XXX*/
539 		}
540 
541 		if (cmd == SIOCAIFADDR_IN6) {
542 			/* sanity for overflow - beware unsigned */
543 			struct in6_addrlifetime *lt;
544 			lt = &ifra->ifra_lifetime;
545 			if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME
546 			 && lt->ia6t_vltime + time_second < time_second) {
547 				return EINVAL;
548 			}
549 			if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME
550 			 && lt->ia6t_pltime + time_second < time_second) {
551 				return EINVAL;
552 			}
553 		}
554 		break;
555 
556 	case SIOCGIFADDR_IN6:
557 		/* This interface is basically deprecated. use SIOCGIFCONF. */
558 		/* fall through */
559 	case SIOCGIFAFLAG_IN6:
560 	case SIOCGIFNETMASK_IN6:
561 	case SIOCGIFDSTADDR_IN6:
562 	case SIOCGIFALIFETIME_IN6:
563 		/* must think again about its semantics */
564 		if (ia == 0)
565 			return(EADDRNOTAVAIL);
566 		break;
567 	case SIOCSIFALIFETIME_IN6:
568 	    {
569 		struct in6_addrlifetime *lt;
570 
571 		if (!privileged)
572 			return(EPERM);
573 		if (ia == 0)
574 			return(EADDRNOTAVAIL);
575 		/* sanity for overflow - beware unsigned */
576 		lt = &ifr->ifr_ifru.ifru_lifetime;
577 		if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME
578 		 && lt->ia6t_vltime + time_second < time_second) {
579 			return EINVAL;
580 		}
581 		if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME
582 		 && lt->ia6t_pltime + time_second < time_second) {
583 			return EINVAL;
584 		}
585 		break;
586 	    }
587 	}
588 
589 	switch (cmd) {
590 
591 	case SIOCGIFADDR_IN6:
592 		ifr->ifr_addr = ia->ia_addr;
593 		break;
594 
595 	case SIOCGIFDSTADDR_IN6:
596 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
597 			return(EINVAL);
598 		ifr->ifr_dstaddr = ia->ia_dstaddr;
599 		break;
600 
601 	case SIOCGIFNETMASK_IN6:
602 		ifr->ifr_addr = ia->ia_prefixmask;
603 		break;
604 
605 	case SIOCGIFAFLAG_IN6:
606 		ifr->ifr_ifru.ifru_flags6 = ia->ia6_flags;
607 		break;
608 
609 	case SIOCGIFSTAT_IN6:
610 		if (ifp == NULL)
611 			return EINVAL;
612 		if (in6_ifstat == NULL || ifp->if_index >= in6_ifstatmax
613 		 || in6_ifstat[ifp->if_index] == NULL) {
614 			/* return EAFNOSUPPORT? */
615 			bzero(&ifr->ifr_ifru.ifru_stat,
616 				sizeof(ifr->ifr_ifru.ifru_stat));
617 		} else
618 			ifr->ifr_ifru.ifru_stat = *in6_ifstat[ifp->if_index];
619 		break;
620 
621 	case SIOCGIFSTAT_ICMP6:
622 		if (ifp == NULL)
623 			return EINVAL;
624 		if (icmp6_ifstat == NULL || ifp->if_index >= icmp6_ifstatmax ||
625 		    icmp6_ifstat[ifp->if_index] == NULL) {
626 			/* return EAFNOSUPPORT? */
627 			bzero(&ifr->ifr_ifru.ifru_stat,
628 				sizeof(ifr->ifr_ifru.ifru_icmp6stat));
629 		} else
630 			ifr->ifr_ifru.ifru_icmp6stat =
631 				*icmp6_ifstat[ifp->if_index];
632 		break;
633 
634 	case SIOCSIFDSTADDR_IN6:
635 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
636 			return(EINVAL);
637 		oldaddr = ia->ia_dstaddr;
638 		ia->ia_dstaddr = ifr->ifr_dstaddr;
639 
640 		/* link-local index check */
641 		if (IN6_IS_ADDR_LINKLOCAL(&ia->ia_dstaddr.sin6_addr)) {
642 			if (ia->ia_dstaddr.sin6_addr.s6_addr16[1] == 0) {
643 				/* interface ID is not embedded by the user */
644 				ia->ia_dstaddr.sin6_addr.s6_addr16[1]
645 					= htons(ifp->if_index);
646 			} else
647 				if (ia->ia_dstaddr.sin6_addr.s6_addr16[1] !=
648 				    htons(ifp->if_index)) {
649 					ia->ia_dstaddr = oldaddr;
650 					return(EINVAL);	/* ifid is contradict */
651 				}
652 		}
653 
654 		if (ifp->if_ioctl && (error = (ifp->if_ioctl)
655 				      (ifp, SIOCSIFDSTADDR, (caddr_t)ia))) {
656 			ia->ia_dstaddr = oldaddr;
657 			return(error);
658 		}
659 		if (ia->ia_flags & IFA_ROUTE) {
660 			ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
661 			rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
662 			ia->ia_ifa.ifa_dstaddr =
663 				(struct sockaddr *)&ia->ia_dstaddr;
664 			rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
665 		}
666 		break;
667 
668 	case SIOCGIFALIFETIME_IN6:
669 		ifr->ifr_ifru.ifru_lifetime = ia->ia6_lifetime;
670 		break;
671 
672 	case SIOCSIFALIFETIME_IN6:
673 		ia->ia6_lifetime = ifr->ifr_ifru.ifru_lifetime;
674 		/* for sanity */
675 		if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
676 			ia->ia6_lifetime.ia6t_expire =
677 				time_second + ia->ia6_lifetime.ia6t_vltime;
678 		} else
679 			ia->ia6_lifetime.ia6t_expire = 0;
680 		if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
681 			ia->ia6_lifetime.ia6t_preferred =
682 				time_second + ia->ia6_lifetime.ia6t_pltime;
683 		} else
684 			ia->ia6_lifetime.ia6t_preferred = 0;
685 		break;
686 
687 	case SIOCSIFADDR_IN6:
688 		return(in6_ifinit(ifp, ia, &ifr->ifr_addr, 1));
689 
690 	case SIOCSIFNETMASK_IN6:
691 		ia->ia_prefixmask = ifr->ifr_addr;
692 		bzero(&net, sizeof(net));
693 		net.sin6_len = sizeof(struct sockaddr_in6);
694 		net.sin6_family = AF_INET6;
695 		net.sin6_port = htons(0);
696 		net.sin6_flowinfo = htonl(0);
697 		net.sin6_addr.s6_addr32[0]
698 			= ia->ia_addr.sin6_addr.s6_addr32[0] &
699 				ia->ia_prefixmask.sin6_addr.s6_addr32[0];
700 		net.sin6_addr.s6_addr32[1]
701 			= ia->ia_addr.sin6_addr.s6_addr32[1] &
702 				ia->ia_prefixmask.sin6_addr.s6_addr32[1];
703 		net.sin6_addr.s6_addr32[2]
704 			= ia->ia_addr.sin6_addr.s6_addr32[2] &
705 				ia->ia_prefixmask.sin6_addr.s6_addr32[2];
706 		net.sin6_addr.s6_addr32[3]
707 			= ia->ia_addr.sin6_addr.s6_addr32[3] &
708 				ia->ia_prefixmask.sin6_addr.s6_addr32[3];
709 		ia->ia_net = net;
710 		break;
711 
712 	case SIOCAIFADDR_IN6:
713 		prefixIsNew = 0;
714 		hostIsNew = 1;
715 
716 		if (ifra->ifra_addr.sin6_len == 0) {
717 			ifra->ifra_addr = ia->ia_addr;
718 			hostIsNew = 0;
719 		} else if (IN6_ARE_ADDR_EQUAL(&ifra->ifra_addr.sin6_addr,
720 					      &ia->ia_addr.sin6_addr))
721 			hostIsNew = 0;
722 
723 		if (ifra->ifra_prefixmask.sin6_len) {
724 			in6_ifscrub(ifp, ia);
725 			ia->ia_prefixmask = ifra->ifra_prefixmask;
726 			prefixIsNew = 1;
727 		}
728 		if ((ifp->if_flags & IFF_POINTOPOINT) &&
729 		    (ifra->ifra_dstaddr.sin6_family == AF_INET6)) {
730 			in6_ifscrub(ifp, ia);
731 			ia->ia_dstaddr = ifra->ifra_dstaddr;
732 			/* link-local index check: should be a separate function? */
733 			if (IN6_IS_ADDR_LINKLOCAL(&ia->ia_dstaddr.sin6_addr)) {
734 				if (ia->ia_dstaddr.sin6_addr.s6_addr16[1] == 0) {
735 					/*
736 					 * interface ID is not embedded by
737 					 * the user
738 					 */
739 					ia->ia_dstaddr.sin6_addr.s6_addr16[1]
740 						= htons(ifp->if_index);
741 				} else
742 					if (ia->ia_dstaddr.sin6_addr.s6_addr16[1] !=
743 					    htons(ifp->if_index)) {
744 						ia->ia_dstaddr = oldaddr;
745 						return(EINVAL);	/* ifid is contradict */
746 					}
747 			}
748 			prefixIsNew = 1; /* We lie; but effect's the same */
749 		}
750 		if (ifra->ifra_addr.sin6_family == AF_INET6 &&
751 		    (hostIsNew || prefixIsNew))
752 			error = in6_ifinit(ifp, ia, &ifra->ifra_addr, 0);
753 		if (ifra->ifra_addr.sin6_family == AF_INET6
754 		    && hostIsNew && (ifp->if_flags & IFF_MULTICAST)) {
755 			int error_local = 0;
756 
757 			/*
758 			 * join solicited multicast addr for new host id
759 			 */
760 			struct in6_addr llsol;
761 			bzero(&llsol, sizeof(struct in6_addr));
762 			llsol.s6_addr16[0] = htons(0xff02);
763 			llsol.s6_addr16[1] = htons(ifp->if_index);
764 			llsol.s6_addr32[1] = 0;
765 			llsol.s6_addr32[2] = htonl(1);
766 			llsol.s6_addr32[3] =
767 				ifra->ifra_addr.sin6_addr.s6_addr32[3];
768 			llsol.s6_addr8[12] = 0xff;
769 			(void)in6_addmulti(&llsol, ifp, &error_local);
770 			if (error == 0)
771 				error = error_local;
772 		}
773 		/* Join dstaddr's solicited multicast if necessary. */
774 		if (nd6_proxyall && hostIsNew) {
775 			int error_local;
776 
777 			error_local = in6_ifaddproxy(ia);
778 			if (error == 0)
779 				error = error_local;
780 		}
781 
782 		ia->ia6_flags = ifra->ifra_flags;
783 		ia->ia6_flags &= ~IN6_IFF_DUPLICATED;	/*safety*/
784 
785 		ia->ia6_lifetime = ifra->ifra_lifetime;
786 		/* for sanity */
787 		if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
788 			ia->ia6_lifetime.ia6t_expire =
789 				time_second + ia->ia6_lifetime.ia6t_vltime;
790 		} else
791 			ia->ia6_lifetime.ia6t_expire = 0;
792 		if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
793 			ia->ia6_lifetime.ia6t_preferred =
794 				time_second + ia->ia6_lifetime.ia6t_pltime;
795 		} else
796 			ia->ia6_lifetime.ia6t_preferred = 0;
797 
798 		/*
799 		 * Perform DAD, if needed.
800 		 * XXX It may be of use, if we can administratively
801 		 * disable DAD.
802 		 */
803 		switch (ifp->if_type) {
804 		case IFT_ARCNET:
805 		case IFT_ETHER:
806 		case IFT_FDDI:
807 			ia->ia6_flags |= IN6_IFF_TENTATIVE;
808 			nd6_dad_start((struct ifaddr *)ia, NULL);
809 			break;
810 #ifdef IFT_DUMMY
811 		case IFT_DUMMY:
812 #endif
813 		case IFT_FAITH:
814 		case IFT_GIF:
815 		case IFT_LOOP:
816 		default:
817 			break;
818 		}
819 
820 		if (hostIsNew) {
821 			int iilen;
822 			int error_local = 0;
823 
824 			iilen = (sizeof(ia->ia_prefixmask.sin6_addr) << 3) -
825 				in6_mask2len(&ia->ia_prefixmask.sin6_addr);
826 			error_local = in6_prefix_add_ifid(iilen, ia);
827 			if (error == 0)
828 				error = error_local;
829 		}
830 
831 		return(error);
832 
833 	case SIOCDIFADDR_IN6:
834 		in6_ifscrub(ifp, ia);
835 
836 		if (ifp->if_flags & IFF_MULTICAST) {
837 			/*
838 			 * delete solicited multicast addr for deleting host id
839 			 */
840 			struct in6_multi *in6m;
841 			struct in6_addr llsol;
842 			bzero(&llsol, sizeof(struct in6_addr));
843 			llsol.s6_addr16[0] = htons(0xff02);
844 			llsol.s6_addr16[1] = htons(ifp->if_index);
845 			llsol.s6_addr32[1] = 0;
846 			llsol.s6_addr32[2] = htonl(1);
847 			llsol.s6_addr32[3] =
848 				ia->ia_addr.sin6_addr.s6_addr32[3];
849 			llsol.s6_addr8[12] = 0xff;
850 
851 			IN6_LOOKUP_MULTI(llsol, ifp, in6m);
852 			if (in6m)
853 				in6_delmulti(in6m);
854 		}
855 		/* Leave dstaddr's solicited multicast if necessary. */
856 		if (nd6_proxyall)
857 			in6_ifremproxy(ia);
858 
859 		TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
860 		oia = ia;
861 		if (oia == (ia = in6_ifaddr))
862 			in6_ifaddr = ia->ia_next;
863 		else {
864 			while (ia->ia_next && (ia->ia_next != oia))
865 				ia = ia->ia_next;
866 			if (ia->ia_next)
867 				ia->ia_next = oia->ia_next;
868 			else
869 				printf("Didn't unlink in6_ifaddr from list\n");
870 		}
871 		{
872 			int iilen;
873 
874 			iilen = (sizeof(oia->ia_prefixmask.sin6_addr) << 3) -
875 				in6_mask2len(&oia->ia_prefixmask.sin6_addr);
876 			in6_prefix_remove_ifid(iilen, oia);
877 		}
878 		IFAFREE((&oia->ia_ifa));
879 		break;
880 
881 	default:
882 		if (ifp == 0 || ifp->if_ioctl == 0)
883 			return(EOPNOTSUPP);
884 		return((*ifp->if_ioctl)(ifp, cmd, data));
885 	}
886 	return(0);
887 }
888 
889 /*
890  * SIOC[GAD]LIFADDR.
891  *	SIOCGLIFADDR: get first address. (?!?)
892  *	SIOCGLIFADDR with IFLR_PREFIX:
893  *		get first address that matches the specified prefix.
894  *	SIOCALIFADDR: add the specified address.
895  *	SIOCALIFADDR with IFLR_PREFIX:
896  *		add the specified prefix, filling hostid part from
897  *		the first link-local address.  prefixlen must be <= 64.
898  *	SIOCDLIFADDR: delete the specified address.
899  *	SIOCDLIFADDR with IFLR_PREFIX:
900  *		delete the first address that matches the specified prefix.
901  * return values:
902  *	EINVAL on invalid parameters
903  *	EADDRNOTAVAIL on prefix match failed/specified address not found
904  *	other values may be returned from in6_ioctl()
905  *
906  * NOTE: SIOCALIFADDR(with IFLR_PREFIX set) allows prefixlen less than 64.
907  * this is to accomodate address naming scheme other than RFC2374,
908  * in the future.
909  * RFC2373 defines interface id to be 64bit, but it allows non-RFC2374
910  * address encoding scheme. (see figure on page 8)
911  */
912 static int
913 in6_lifaddr_ioctl(so, cmd, data, ifp, p)
914 	struct socket *so;
915 	u_long cmd;
916 	caddr_t	data;
917 	struct ifnet *ifp;
918 	struct proc *p;
919 {
920 	struct if_laddrreq *iflr = (struct if_laddrreq *)data;
921 	struct ifaddr *ifa;
922 
923 	/* sanity checks */
924 	if (!data || !ifp) {
925 		panic("invalid argument to in6_lifaddr_ioctl");
926 		/*NOTRECHED*/
927 	}
928 
929 	switch (cmd) {
930 	case SIOCGLIFADDR:
931 		/* address must be specified on GET with IFLR_PREFIX */
932 		if ((iflr->flags & IFLR_PREFIX) == 0)
933 			break;
934 		/*FALLTHROUGH*/
935 	case SIOCALIFADDR:
936 	case SIOCDLIFADDR:
937 		/* address must be specified on ADD and DELETE */
938 		if (iflr->addr.__ss_family != AF_INET6)
939 			return EINVAL;
940 		if (iflr->addr.__ss_len != sizeof(struct sockaddr_in6))
941 			return EINVAL;
942 		/* XXX need improvement */
943 		if (iflr->dstaddr.__ss_family
944 		 && iflr->dstaddr.__ss_family != AF_INET6)
945 			return EINVAL;
946 		if (iflr->dstaddr.__ss_family
947 		 && iflr->dstaddr.__ss_len != sizeof(struct sockaddr_in6))
948 			return EINVAL;
949 		break;
950 	default: /*shouldn't happen*/
951 		return EOPNOTSUPP;
952 	}
953 	if (sizeof(struct in6_addr) * 8 < iflr->prefixlen)
954 		return EINVAL;
955 
956 	switch (cmd) {
957 	case SIOCALIFADDR:
958 	    {
959 		struct in6_aliasreq ifra;
960 		struct in6_addr *hostid = NULL;
961 		int prefixlen;
962 
963 		if ((iflr->flags & IFLR_PREFIX) != 0) {
964 			struct sockaddr_in6 *sin6;
965 
966 			/*
967 			 * hostid is to fill in the hostid part of the
968 			 * address.  hostid points to the first link-local
969 			 * address attached to the interface.
970 			 */
971 			ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp);
972 			if (!ifa)
973 				return EADDRNOTAVAIL;
974 			hostid = IFA_IN6(ifa);
975 
976 		 	/* prefixlen must be <= 64. */
977 			if (64 < iflr->prefixlen)
978 				return EINVAL;
979 			prefixlen = iflr->prefixlen;
980 
981 			/* hostid part must be zero. */
982 			sin6 = (struct sockaddr_in6 *)&iflr->addr;
983 			if (sin6->sin6_addr.s6_addr32[2] != 0
984 			 || sin6->sin6_addr.s6_addr32[3] != 0) {
985 				return EINVAL;
986 			}
987 		} else
988 			prefixlen = iflr->prefixlen;
989 
990 		/* copy args to in6_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
991 		bzero(&ifra, sizeof(ifra));
992 		bcopy(iflr->iflr_name, ifra.ifra_name,
993 			sizeof(ifra.ifra_name));
994 
995 		bcopy(&iflr->addr, &ifra.ifra_addr, iflr->addr.__ss_len);
996 		if (hostid) {
997 			/* fill in hostid part */
998 			ifra.ifra_addr.sin6_addr.s6_addr32[2] =
999 				hostid->s6_addr32[2];
1000 			ifra.ifra_addr.sin6_addr.s6_addr32[3] =
1001 				hostid->s6_addr32[3];
1002 		}
1003 
1004 		if (iflr->dstaddr.__ss_family) {	/*XXX*/
1005 			bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
1006 				iflr->dstaddr.__ss_len);
1007 			if (hostid) {
1008 				ifra.ifra_dstaddr.sin6_addr.s6_addr32[2] =
1009 					hostid->s6_addr32[2];
1010 				ifra.ifra_dstaddr.sin6_addr.s6_addr32[3] =
1011 					hostid->s6_addr32[3];
1012 			}
1013 		}
1014 
1015 		ifra.ifra_prefixmask.sin6_family = AF_INET6;
1016 		ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
1017 		in6_len2mask(&ifra.ifra_prefixmask.sin6_addr, prefixlen);
1018 
1019 		ifra.ifra_flags = iflr->flags & ~IFLR_PREFIX;
1020 		return in6_control(so, SIOCAIFADDR_IN6, (caddr_t)&ifra, ifp, p);
1021 	    }
1022 	case SIOCGLIFADDR:
1023 	case SIOCDLIFADDR:
1024 	    {
1025 		struct in6_ifaddr *ia;
1026 		struct in6_addr mask, candidate, match;
1027 		struct sockaddr_in6 *sin6;
1028 		int cmp;
1029 
1030 		bzero(&mask, sizeof(mask));
1031 		if (iflr->flags & IFLR_PREFIX) {
1032 			/* lookup a prefix rather than address. */
1033 			in6_len2mask(&mask, iflr->prefixlen);
1034 
1035 			sin6 = (struct sockaddr_in6 *)&iflr->addr;
1036 			bcopy(&sin6->sin6_addr, &match, sizeof(match));
1037 			match.s6_addr32[0] &= mask.s6_addr32[0];
1038 			match.s6_addr32[1] &= mask.s6_addr32[1];
1039 			match.s6_addr32[2] &= mask.s6_addr32[2];
1040 			match.s6_addr32[3] &= mask.s6_addr32[3];
1041 
1042 			/* if you set extra bits, that's wrong */
1043 			if (bcmp(&match, &sin6->sin6_addr, sizeof(match)))
1044 				return EINVAL;
1045 
1046 			cmp = 1;
1047 		} else {
1048 			if (cmd == SIOCGLIFADDR) {
1049 				/* on getting an address, take the 1st match */
1050 				cmp = 0;	/*XXX*/
1051 			} else {
1052 				/* on deleting an address, do exact match */
1053 				in6_len2mask(&mask, 128);
1054 				sin6 = (struct sockaddr_in6 *)&iflr->addr;
1055 				bcopy(&sin6->sin6_addr, &match, sizeof(match));
1056 
1057 				cmp = 1;
1058 			}
1059 		}
1060 
1061 		TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1062 		{
1063 			if (ifa->ifa_addr->sa_family != AF_INET6)
1064 				continue;
1065 			if (!cmp)
1066 				break;
1067 			bcopy(IFA_IN6(ifa), &candidate, sizeof(candidate));
1068 			candidate.s6_addr32[0] &= mask.s6_addr32[0];
1069 			candidate.s6_addr32[1] &= mask.s6_addr32[1];
1070 			candidate.s6_addr32[2] &= mask.s6_addr32[2];
1071 			candidate.s6_addr32[3] &= mask.s6_addr32[3];
1072 			if (IN6_ARE_ADDR_EQUAL(&candidate, &match))
1073 				break;
1074 		}
1075 		if (!ifa)
1076 			return EADDRNOTAVAIL;
1077 		ia = ifa2ia6(ifa);
1078 
1079 		if (cmd == SIOCGLIFADDR) {
1080 			/* fill in the if_laddrreq structure */
1081 			bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin6_len);
1082 
1083 			if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
1084 				bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
1085 					ia->ia_dstaddr.sin6_len);
1086 			} else
1087 				bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
1088 
1089 			iflr->prefixlen =
1090 				in6_mask2len(&ia->ia_prefixmask.sin6_addr);
1091 
1092 			iflr->flags = ia->ia6_flags;	/*XXX*/
1093 
1094 			return 0;
1095 		} else {
1096 			struct in6_aliasreq ifra;
1097 
1098 			/* fill in6_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
1099 			bzero(&ifra, sizeof(ifra));
1100 			bcopy(iflr->iflr_name, ifra.ifra_name,
1101 				sizeof(ifra.ifra_name));
1102 
1103 			bcopy(&ia->ia_addr, &ifra.ifra_addr,
1104 				ia->ia_addr.sin6_len);
1105 			if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
1106 				bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
1107 					ia->ia_dstaddr.sin6_len);
1108 			}
1109 			bcopy(&ia->ia_prefixmask, &ifra.ifra_dstaddr,
1110 				ia->ia_prefixmask.sin6_len);
1111 
1112 			ifra.ifra_flags = ia->ia6_flags;
1113 			return in6_control(so, SIOCDIFADDR_IN6, (caddr_t)&ifra,
1114 				ifp, p);
1115 		}
1116 	    }
1117 	}
1118 
1119 	return EOPNOTSUPP;	/*just for safety*/
1120 }
1121 
1122 /*
1123  * Delete any existing route for an interface.
1124  */
1125 void
1126 in6_ifscrub(ifp, ia)
1127 	register struct ifnet *ifp;
1128 	register struct in6_ifaddr *ia;
1129 {
1130 	if ((ia->ia_flags & IFA_ROUTE) == 0)
1131 		return;
1132 	if (ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
1133 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
1134 	else
1135 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
1136 	ia->ia_flags &= ~IFA_ROUTE;
1137 
1138 	/* Remove ownaddr's loopback rtentry, if it exists. */
1139 	in6_ifremloop(&(ia->ia_ifa));
1140 }
1141 
1142 /*
1143  * Initialize an interface's intetnet6 address
1144  * and routing table entry.
1145  */
1146 int
1147 in6_ifinit(ifp, ia, sin6, scrub)
1148 	struct ifnet *ifp;
1149 	struct in6_ifaddr *ia;
1150 	struct sockaddr_in6 *sin6;
1151 	int scrub;
1152 {
1153 	struct	sockaddr_in6 oldaddr;
1154 	int	error, flags = RTF_UP;
1155 	int	s = splimp();
1156 
1157 	oldaddr = ia->ia_addr;
1158 	ia->ia_addr = *sin6;
1159 	/*
1160 	 * Give the interface a chance to initialize
1161 	 * if this is its first address,
1162 	 * and to validate the address if necessary.
1163 	 */
1164 	if (ifp->if_ioctl &&
1165 	   (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
1166 		splx(s);
1167 		ia->ia_addr = oldaddr;
1168 		return(error);
1169 	}
1170 
1171 	switch (ifp->if_type) {
1172 	case IFT_ARCNET:
1173 	case IFT_ETHER:
1174 	case IFT_FDDI:
1175 		ia->ia_ifa.ifa_rtrequest = nd6_rtrequest;
1176 		ia->ia_ifa.ifa_flags |= RTF_CLONING;
1177 		break;
1178 	case IFT_PPP:
1179 		ia->ia_ifa.ifa_rtrequest = nd6_p2p_rtrequest;
1180 		ia->ia_ifa.ifa_flags |= RTF_CLONING;
1181 		break;
1182 	}
1183 
1184 	splx(s);
1185 	if (scrub) {
1186 		ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
1187 		in6_ifscrub(ifp, ia);
1188 		ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
1189 	}
1190 	/* xxx
1191 	 * in_socktrim
1192 	 */
1193 	/*
1194 	 * Add route for the network.
1195 	 */
1196 	ia->ia_ifa.ifa_metric = ifp->if_metric;
1197 	if (ifp->if_flags & IFF_LOOPBACK) {
1198 		ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
1199 		flags |= RTF_HOST;
1200 	} else if (ifp->if_flags & IFF_POINTOPOINT) {
1201 		if (ia->ia_dstaddr.sin6_family != AF_INET6)
1202 			return(0);
1203 		flags |= RTF_HOST;
1204 	}
1205 	if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0)
1206 		ia->ia_flags |= IFA_ROUTE;
1207 
1208 	/* Add ownaddr as loopback rtentry, if necessary(ex. on p2p link). */
1209 	in6_ifaddloop(&(ia->ia_ifa));
1210 
1211 	return(error);
1212 }
1213 
1214 /*
1215  * Add an address to the list of IP6 multicast addresses for a
1216  * given interface.
1217  */
1218 struct	in6_multi *
1219 in6_addmulti(maddr6, ifp, errorp)
1220 	register struct in6_addr *maddr6;
1221 	register struct ifnet *ifp;
1222 	int *errorp;
1223 {
1224 	struct	in6_multi *in6m;
1225 	struct sockaddr_in6 sin6;
1226 	struct ifmultiaddr *ifma;
1227 	int	s = splnet();
1228 
1229 	*errorp = 0;
1230 
1231 	/*
1232 	 * Call generic routine to add membership or increment
1233 	 * refcount.  It wants addresses in the form of a sockaddr,
1234 	 * so we build one here (being careful to zero the unused bytes).
1235 	 */
1236 	bzero(&sin6, sizeof sin6);
1237 	sin6.sin6_family = AF_INET6;
1238 	sin6.sin6_len = sizeof sin6;
1239 	sin6.sin6_addr = *maddr6;
1240 	*errorp = if_addmulti(ifp, (struct sockaddr *)&sin6, &ifma);
1241 	if (*errorp) {
1242 		splx(s);
1243 		return 0;
1244 	}
1245 
1246 	/*
1247 	 * If ifma->ifma_protospec is null, then if_addmulti() created
1248 	 * a new record.  Otherwise, we are done.
1249 	 */
1250 	if (ifma->ifma_protospec != 0)
1251 		return ifma->ifma_protospec;
1252 
1253 	/* XXX - if_addmulti uses M_WAITOK.  Can this really be called
1254 	   at interrupt time?  If so, need to fix if_addmulti. XXX */
1255 	in6m = (struct in6_multi *)malloc(sizeof(*in6m), M_IPMADDR, M_NOWAIT);
1256 	if (in6m == NULL) {
1257 		splx(s);
1258 		return (NULL);
1259 	}
1260 
1261 	bzero(in6m, sizeof *in6m);
1262 	in6m->in6m_addr = *maddr6;
1263 	in6m->in6m_ifp = ifp;
1264 	in6m->in6m_ifma = ifma;
1265 	ifma->ifma_protospec = in6m;
1266 	LIST_INSERT_HEAD(&in6_multihead, in6m, in6m_entry);
1267 
1268 	/*
1269 	 * Let MLD6 know that we have joined a new IP6 multicast
1270 	 * group.
1271 	 */
1272 	mld6_start_listening(in6m);
1273 	splx(s);
1274 	return(in6m);
1275 }
1276 
1277 /*
1278  * Delete a multicast address record.
1279  */
1280 void
1281 in6_delmulti(in6m)
1282 	struct in6_multi *in6m;
1283 {
1284 	struct ifmultiaddr *ifma = in6m->in6m_ifma;
1285 	int	s = splnet();
1286 
1287 	if (ifma->ifma_refcount == 1) {
1288 		/*
1289 		 * No remaining claims to this record; let MLD6 know
1290 		 * that we are leaving the multicast group.
1291 		 */
1292 		mld6_stop_listening(in6m);
1293 		ifma->ifma_protospec = 0;
1294 		LIST_REMOVE(in6m, in6m_entry);
1295 		free(in6m, M_IPMADDR);
1296 	}
1297 	/* XXX - should be separate API for when we have an ifma? */
1298 	if_delmulti(ifma->ifma_ifp, ifma->ifma_addr);
1299 	splx(s);
1300 }
1301 
1302 /*
1303  * Find an IPv6 interface link-local address specific to an interface.
1304  */
1305 struct in6_ifaddr *
1306 in6ifa_ifpforlinklocal(ifp)
1307 	struct ifnet *ifp;
1308 {
1309 	register struct ifaddr *ifa;
1310 
1311 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1312 	{
1313 		if (ifa->ifa_addr == NULL)
1314 			continue;	/* just for safety */
1315 		if (ifa->ifa_addr->sa_family != AF_INET6)
1316 			continue;
1317 		if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa)))
1318 			break;
1319 	}
1320 
1321 	return((struct in6_ifaddr *)ifa);
1322 }
1323 
1324 
1325 /*
1326  * find the internet address corresponding to a given interface and address.
1327  */
1328 struct in6_ifaddr *
1329 in6ifa_ifpwithaddr(ifp, addr)
1330 	struct ifnet *ifp;
1331 	struct in6_addr *addr;
1332 {
1333 	register struct ifaddr *ifa;
1334 
1335 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1336 	{
1337 		if (ifa->ifa_addr == NULL)
1338 			continue;	/* just for safety */
1339 		if (ifa->ifa_addr->sa_family != AF_INET6)
1340 			continue;
1341 		if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)))
1342 			break;
1343 	}
1344 
1345 	return((struct in6_ifaddr *)ifa);
1346 }
1347 
1348 /*
1349  * Convert IP6 address to printable (loggable) representation.
1350  */
1351 static char digits[] = "0123456789abcdef";
1352 static int ip6round = 0;
1353 char *
1354 ip6_sprintf(addr)
1355 register struct in6_addr *addr;
1356 {
1357 	static char ip6buf[8][48];
1358 	register int i;
1359 	register char *cp;
1360 	register u_short *a = (u_short *)addr;
1361 	register u_char *d;
1362 	int dcolon = 0;
1363 
1364 	ip6round = (ip6round + 1) & 7;
1365 	cp = ip6buf[ip6round];
1366 
1367 	for (i = 0; i < 8; i++) {
1368 		if (dcolon == 1) {
1369 			if (*a == 0) {
1370 				if (i == 7)
1371 					*cp++ = ':';
1372 				a++;
1373 				continue;
1374 			} else
1375 				dcolon = 2;
1376 		}
1377 		if (*a == 0) {
1378 			if (dcolon == 0 && *(a + 1) == 0) {
1379 				if (i == 0)
1380 					*cp++ = ':';
1381 				*cp++ = ':';
1382 				dcolon = 1;
1383 			} else {
1384 				*cp++ = '0';
1385 				*cp++ = ':';
1386 			}
1387 			a++;
1388 			continue;
1389 		}
1390 		d = (u_char *)a;
1391 		*cp++ = digits[*d >> 4];
1392 		*cp++ = digits[*d++ & 0xf];
1393 		*cp++ = digits[*d >> 4];
1394 		*cp++ = digits[*d & 0xf];
1395 		*cp++ = ':';
1396 		a++;
1397 	}
1398 	*--cp = 0;
1399 	return(ip6buf[ip6round]);
1400 }
1401 
1402 int
1403 in6_localaddr(in6)
1404 	struct in6_addr *in6;
1405 {
1406 	struct in6_ifaddr *ia;
1407 
1408 	if (IN6_IS_ADDR_LOOPBACK(in6) || IN6_IS_ADDR_LINKLOCAL(in6))
1409 		return 1;
1410 
1411 	for (ia = in6_ifaddr; ia; ia = ia->ia_next)
1412 		if (IN6_ARE_MASKED_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr,
1413 					      &ia->ia_prefixmask.sin6_addr))
1414 			return 1;
1415 
1416 	return (0);
1417 }
1418 
1419 /*
1420  * Get a scope of the address. Node-local, link-local, site-local or global.
1421  */
1422 int
1423 in6_addrscope (addr)
1424 struct in6_addr *addr;
1425 {
1426 	int scope;
1427 
1428 	if (addr->s6_addr8[0] == 0xfe) {
1429 		scope = addr->s6_addr8[1] & 0xc0;
1430 
1431 		switch (scope) {
1432 		case 0x80:
1433 			return IPV6_ADDR_SCOPE_LINKLOCAL;
1434 			break;
1435 		case 0xc0:
1436 			return IPV6_ADDR_SCOPE_SITELOCAL;
1437 			break;
1438 		default:
1439 			return IPV6_ADDR_SCOPE_GLOBAL; /* just in case */
1440 			break;
1441 		}
1442 	}
1443 
1444 
1445 	if (addr->s6_addr8[0] == 0xff) {
1446 		scope = addr->s6_addr8[1] & 0x0f;
1447 
1448 		/*
1449 		 * due to other scope such as reserved,
1450 		 * return scope doesn't work.
1451 		 */
1452 		switch (scope) {
1453 		case IPV6_ADDR_SCOPE_NODELOCAL:
1454 			return IPV6_ADDR_SCOPE_NODELOCAL;
1455 			break;
1456 		case IPV6_ADDR_SCOPE_LINKLOCAL:
1457 			return IPV6_ADDR_SCOPE_LINKLOCAL;
1458 			break;
1459 		case IPV6_ADDR_SCOPE_SITELOCAL:
1460 			return IPV6_ADDR_SCOPE_SITELOCAL;
1461 			break;
1462 		default:
1463 			return IPV6_ADDR_SCOPE_GLOBAL;
1464 			break;
1465 		}
1466 	}
1467 
1468 	if (bcmp(&in6addr_loopback, addr, sizeof(addr) - 1) == 0) {
1469 		if (addr->s6_addr8[15] == 1) /* loopback */
1470 			return IPV6_ADDR_SCOPE_NODELOCAL;
1471 		if (addr->s6_addr8[15] == 0) /* unspecified */
1472 			return IPV6_ADDR_SCOPE_LINKLOCAL;
1473 	}
1474 
1475 	return IPV6_ADDR_SCOPE_GLOBAL;
1476 }
1477 
1478 /*
1479  * return length of part which dst and src are equal
1480  * hard coding...
1481  */
1482 
1483 int
1484 in6_matchlen(src, dst)
1485 struct in6_addr *src, *dst;
1486 {
1487 	int match = 0;
1488 	u_char *s = (u_char *)src, *d = (u_char *)dst;
1489 	u_char *lim = s + 16, r;
1490 
1491 	while (s < lim)
1492 		if ((r = (*d++ ^ *s++)) != 0) {
1493 			while (r < 128) {
1494 				match++;
1495 				r <<= 1;
1496 			}
1497 			break;
1498 		} else
1499 			match += 8;
1500 	return match;
1501 }
1502 
1503 int
1504 in6_are_prefix_equal(p1, p2, len)
1505 	struct in6_addr *p1, *p2;
1506 	int len;
1507 {
1508 	int bytelen, bitlen;
1509 
1510 	/* sanity check */
1511 	if (0 > len || len > 128) {
1512 		log(LOG_ERR, "in6_are_prefix_equal: invalid prefix length(%d)\n",
1513 		    len);
1514 		return(0);
1515 	}
1516 
1517 	bytelen = len / 8;
1518 	bitlen = len % 8;
1519 
1520 	if (bcmp(&p1->s6_addr, &p2->s6_addr, bytelen))
1521 		return(0);
1522 	if (p1->s6_addr[bytelen] >> (8 - bitlen) !=
1523 	    p2->s6_addr[bytelen] >> (8 - bitlen))
1524 		return(0);
1525 
1526 	return(1);
1527 }
1528 
1529 void
1530 in6_prefixlen2mask(maskp, len)
1531 	struct in6_addr *maskp;
1532 	int len;
1533 {
1534 	u_char maskarray[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
1535 	int bytelen, bitlen, i;
1536 
1537 	/* sanity check */
1538 	if (0 > len || len > 128) {
1539 		log(LOG_ERR, "in6_prefixlen2mask: invalid prefix length(%d)\n",
1540 		    len);
1541 		return;
1542 	}
1543 
1544 	bzero(maskp, sizeof(*maskp));
1545 	bytelen = len / 8;
1546 	bitlen = len % 8;
1547 	for (i = 0; i < bytelen; i++)
1548 		maskp->s6_addr[i] = 0xff;
1549 	if (bitlen)
1550 		maskp->s6_addr[bytelen] = maskarray[bitlen - 1];
1551 }
1552 
1553 /*
1554  * return the best address out of the same scope
1555  */
1556 
1557 struct in6_ifaddr *
1558 in6_ifawithscope(ifp, dst)
1559 	register struct ifnet *ifp;
1560 	register struct in6_addr *dst;
1561 {
1562 	int dst_scope =	in6_addrscope(dst), blen = -1, tlen;
1563 	struct ifaddr *ifa;
1564 	struct in6_ifaddr *besta = NULL, *ia;
1565 	struct in6_ifaddr *dep[2];	/*last-resort: deprecated*/
1566 
1567 	dep[0] = dep[1] = NULL;
1568 
1569 	/*
1570 	 * We first look for addresses in the same scope.
1571 	 * If there is one, return it.
1572 	 * If two or more, return one which matches the dst longest.
1573 	 * If none, return one of global addresses assigned other ifs.
1574 	 */
1575 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1576 	{
1577 		if (ifa->ifa_addr->sa_family != AF_INET6)
1578 			continue;
1579 		if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
1580 			continue; /* XXX: is there any case to allow anycast? */
1581 		if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
1582 			continue; /* don't use this interface */
1583 		if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
1584 			continue;
1585 		if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
1586 			if (ip6_use_deprecated)
1587 				dep[0] = (struct in6_ifaddr *)ifa;
1588 			continue;
1589 		}
1590 
1591 		if (dst_scope == in6_addrscope(IFA_IN6(ifa))) {
1592 			/*
1593 			 * call in6_matchlen() as few as possible
1594 			 */
1595 			if (besta) {
1596 				if (blen == -1)
1597 					blen = in6_matchlen(&besta->ia_addr.sin6_addr, dst);
1598 				tlen = in6_matchlen(IFA_IN6(ifa), dst);
1599 				if (tlen > blen) {
1600 					blen = tlen;
1601 					besta = (struct in6_ifaddr *)ifa;
1602 				}
1603 			} else
1604 				besta = (struct in6_ifaddr *)ifa;
1605 		}
1606 	}
1607 	if (besta)
1608 		return besta;
1609 
1610 	for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
1611 		if (IPV6_ADDR_SCOPE_GLOBAL !=
1612 		    in6_addrscope(&(ia->ia_addr.sin6_addr)))
1613 			continue;
1614 		/* XXX: is there any case to allow anycast? */
1615 		if ((ia->ia6_flags & IN6_IFF_ANYCAST) != 0)
1616 			continue;
1617 		if ((ia->ia6_flags & IN6_IFF_NOTREADY) != 0)
1618 			continue;
1619 		if ((ia->ia6_flags & IN6_IFF_DETACHED) != 0)
1620 			continue;
1621 		if ((ia->ia6_flags & IN6_IFF_DEPRECATED) != 0) {
1622 			if (ip6_use_deprecated)
1623 				dep[1] = (struct in6_ifaddr *)ifa;
1624 			continue;
1625 		}
1626 		return ia;
1627 	}
1628 
1629 	/* use the last-resort values, that are, deprecated addresses */
1630 	if (dep[0])
1631 		return dep[0];
1632 	if (dep[1])
1633 		return dep[1];
1634 
1635 	return NULL;
1636 }
1637 
1638 /*
1639  * return the best address out of the same scope. if no address was
1640  * found, return the first valid address from designated IF.
1641  */
1642 
1643 struct in6_ifaddr *
1644 in6_ifawithifp(ifp, dst)
1645 	register struct ifnet *ifp;
1646 	register struct in6_addr *dst;
1647 {
1648 	int dst_scope =	in6_addrscope(dst), blen = -1, tlen;
1649 	struct ifaddr *ifa;
1650 	struct in6_ifaddr *besta = 0;
1651 	struct in6_ifaddr *dep[2];	/*last-resort: deprecated*/
1652 
1653 	dep[0] = dep[1] = NULL;
1654 
1655 	/*
1656 	 * We first look for addresses in the same scope.
1657 	 * If there is one, return it.
1658 	 * If two or more, return one which matches the dst longest.
1659 	 * If none, return one of global addresses assigned other ifs.
1660 	 */
1661 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1662 	{
1663 		if (ifa->ifa_addr->sa_family != AF_INET6)
1664 			continue;
1665 		if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
1666 			continue; /* XXX: is there any case to allow anycast? */
1667 		if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
1668 			continue; /* don't use this interface */
1669 		if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
1670 			continue;
1671 		if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
1672 			if (ip6_use_deprecated)
1673 				dep[0] = (struct in6_ifaddr *)ifa;
1674 			continue;
1675 		}
1676 
1677 		if (dst_scope == in6_addrscope(IFA_IN6(ifa))) {
1678 			/*
1679 			 * call in6_matchlen() as few as possible
1680 			 */
1681 			if (besta) {
1682 				if (blen == -1)
1683 					blen = in6_matchlen(&besta->ia_addr.sin6_addr, dst);
1684 				tlen = in6_matchlen(IFA_IN6(ifa), dst);
1685 				if (tlen > blen) {
1686 					blen = tlen;
1687 					besta = (struct in6_ifaddr *)ifa;
1688 				}
1689 			} else
1690 				besta = (struct in6_ifaddr *)ifa;
1691 		}
1692 	}
1693 	if (besta)
1694 		return(besta);
1695 
1696 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1697 	{
1698 		if (ifa->ifa_addr->sa_family != AF_INET6)
1699 			continue;
1700 		if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST)
1701 			continue; /* XXX: is there any case to allow anycast? */
1702 		if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY)
1703 			continue; /* don't use this interface */
1704 		if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED)
1705 			continue;
1706 		if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) {
1707 			if (ip6_use_deprecated)
1708 				dep[1] = (struct in6_ifaddr *)ifa;
1709 			continue;
1710 		}
1711 
1712 		return (struct in6_ifaddr *)ifa;
1713 	}
1714 
1715 	/* use the last-resort values, that are, deprecated addresses */
1716 	if (dep[0])
1717 		return dep[0];
1718 	if (dep[1])
1719 		return dep[1];
1720 
1721 	return NULL;
1722 }
1723 
1724 /*
1725  * perform DAD when interface becomes IFF_UP.
1726  */
1727 void
1728 in6_if_up(ifp)
1729 	struct ifnet *ifp;
1730 {
1731 	struct ifaddr *ifa;
1732 	struct in6_ifaddr *ia;
1733 	struct sockaddr_dl *sdl;
1734 	int type;
1735 	struct ether_addr ea;
1736 	int off;
1737 	int dad_delay;		/* delay ticks before DAD output */
1738 
1739 	bzero(&ea, sizeof(ea));
1740 	sdl = NULL;
1741 
1742 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1743 	{
1744 		if (ifa->ifa_addr->sa_family == AF_INET6
1745 		 && IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) {
1746 			goto dad;
1747 		}
1748 		if (ifa->ifa_addr->sa_family != AF_LINK)
1749 			continue;
1750 		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
1751 		break;
1752 	}
1753 
1754 	switch (ifp->if_type) {
1755 	case IFT_SLIP:
1756 	case IFT_PPP:
1757 #ifdef IFT_DUMMY
1758 	case IFT_DUMMY:
1759 #endif
1760 	case IFT_GIF:
1761 	case IFT_FAITH:
1762 		type = IN6_IFT_P2P;
1763 		in6_ifattach(ifp, type, 0, 1);
1764 		break;
1765 	case IFT_ETHER:
1766 	case IFT_FDDI:
1767 	case IFT_ATM:
1768 		type = IN6_IFT_802;
1769 		if (sdl == NULL)
1770 			break;
1771 		off = sdl->sdl_nlen;
1772 		if (bcmp(&sdl->sdl_data[off], &ea, sizeof(ea)) != 0)
1773 			in6_ifattach(ifp, type, LLADDR(sdl), 0);
1774 		break;
1775 	case IFT_ARCNET:
1776 		type = IN6_IFT_ARCNET;
1777 		if (sdl == NULL)
1778 			break;
1779 		off = sdl->sdl_nlen;
1780 		if (sdl->sdl_data[off] != 0)	/* XXX ?: */
1781 			in6_ifattach(ifp, type, LLADDR(sdl), 0);
1782 		break;
1783 	default:
1784 		break;
1785 	}
1786 
1787 dad:
1788 	dad_delay = 0;
1789 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)
1790 	{
1791 		if (ifa->ifa_addr->sa_family != AF_INET6)
1792 			continue;
1793 		ia = (struct in6_ifaddr *)ifa;
1794 		if (ia->ia6_flags & IN6_IFF_TENTATIVE)
1795 			nd6_dad_start(ifa, &dad_delay);
1796 	}
1797 }
1798 
1799 /*
1800  * Calculate max IPv6 MTU through all the interfaces and store it
1801  * to in6_maxmtu.
1802  */
1803 void
1804 in6_setmaxmtu()
1805 {
1806 	unsigned long maxmtu = 0;
1807 	struct ifnet *ifp;
1808 
1809 	for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
1810 	{
1811 		if ((ifp->if_flags & IFF_LOOPBACK) == 0 &&
1812 		    nd_ifinfo[ifp->if_index].linkmtu > maxmtu)
1813 			maxmtu =  nd_ifinfo[ifp->if_index].linkmtu;
1814 	}
1815 	if (maxmtu)	/* update only when maxmtu is positive */
1816 		in6_maxmtu = maxmtu;
1817 }
1818 
1819 /*
1820  * Convert sockaddr_in6 to sockaddr_in. Original sockaddr_in6 must be
1821  * v4 mapped addr or v4 compat addr
1822  */
1823 void
1824 in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
1825 {
1826 	bzero(sin, sizeof(*sin));
1827 	sin->sin_len = sizeof(struct sockaddr_in);
1828 	sin->sin_family = AF_INET;
1829 	sin->sin_port = sin6->sin6_port;
1830 	sin->sin_addr.s_addr = sin6->sin6_addr.s6_addr32[3];
1831 }
1832 
1833 /* Convert sockaddr_in to sockaddr_in6 in v4 mapped addr format. */
1834 void
1835 in6_sin_2_v4mapsin6(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
1836 {
1837 	bzero(sin6, sizeof(*sin6));
1838 	sin6->sin6_len = sizeof(struct sockaddr_in6);
1839 	sin6->sin6_family = AF_INET6;
1840 	sin6->sin6_port = sin->sin_port;
1841 	sin6->sin6_addr.s6_addr32[0] = 0;
1842 	sin6->sin6_addr.s6_addr32[1] = 0;
1843 	sin6->sin6_addr.s6_addr32[2] = IPV6_ADDR_INT32_SMP;
1844 	sin6->sin6_addr.s6_addr32[3] = sin->sin_addr.s_addr;
1845 }
1846 
1847 /* Convert sockaddr_in6 into sockaddr_in. */
1848 void
1849 in6_sin6_2_sin_in_sock(struct sockaddr *nam)
1850 {
1851 	struct sockaddr_in *sin_p;
1852 	struct sockaddr_in6 sin6;
1853 
1854 	/*
1855 	 * Save original sockaddr_in6 addr and convert it
1856 	 * to sockaddr_in.
1857 	 */
1858 	sin6 = *(struct sockaddr_in6 *)nam;
1859 	sin_p = (struct sockaddr_in *)nam;
1860 	in6_sin6_2_sin(sin_p, &sin6);
1861 }
1862 
1863 /* Convert sockaddr_in into sockaddr_in6 in v4 mapped addr format. */
1864 void
1865 in6_sin_2_v4mapsin6_in_sock(struct sockaddr **nam)
1866 {
1867 	struct sockaddr_in *sin_p;
1868 	struct sockaddr_in6 *sin6_p;
1869 
1870 	MALLOC(sin6_p, struct sockaddr_in6 *, sizeof *sin6_p, M_SONAME,
1871 	       M_WAITOK);
1872 	sin_p = (struct sockaddr_in *)*nam;
1873 	in6_sin_2_v4mapsin6(sin_p, sin6_p);
1874 	FREE(*nam, M_SONAME);
1875 	*nam = (struct sockaddr *)sin6_p;
1876 }
1877