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