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 == NULL || !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 if (ip6_forwarding == 0) 465 return(EPERM); 466 return(in6_prefix_ioctl(so, cmd, data, ifp)); 467 } 468 469 switch (cmd) { 470 case SIOCALIFADDR: 471 case SIOCDLIFADDR: 472 if (!privileged) 473 return(EPERM); 474 /*fall through*/ 475 case SIOCGLIFADDR: 476 return in6_lifaddr_ioctl(so, cmd, data, ifp, p); 477 } 478 479 /* 480 * Find address for this interface, if it exists. 481 */ 482 { 483 484 struct sockaddr_in6 *sa6 = 485 (struct sockaddr_in6 *)&ifra->ifra_addr; 486 487 if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) { 488 if (sa6->sin6_addr.s6_addr16[1] == 0) { 489 /* interface ID is not embedded by the user */ 490 sa6->sin6_addr.s6_addr16[1] = 491 htons(ifp->if_index); 492 } else 493 if (sa6->sin6_addr.s6_addr16[1] != 494 htons(ifp->if_index)) 495 return(EINVAL); /* ifid is contradict */ 496 if (sa6->sin6_scope_id) { 497 if (sa6->sin6_scope_id != 498 (u_int32_t)ifp->if_index) 499 return(EINVAL); 500 sa6->sin6_scope_id = 0; /* XXX: good way? */ 501 } 502 } 503 } 504 ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr); 505 506 switch (cmd) { 507 508 case SIOCDIFADDR_IN6: 509 if (ia == 0) 510 return(EADDRNOTAVAIL); 511 /* FALLTHROUGH */ 512 case SIOCAIFADDR_IN6: 513 case SIOCSIFADDR_IN6: 514 case SIOCSIFNETMASK_IN6: 515 case SIOCSIFDSTADDR_IN6: 516 if (!privileged) 517 return(EPERM); 518 if (ia == 0) { 519 ia = (struct in6_ifaddr *) 520 malloc(sizeof(*ia), M_IFADDR, M_WAITOK); 521 if (ia == NULL) 522 return (ENOBUFS); 523 bzero((caddr_t)ia, sizeof(*ia)); 524 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 525 ia->ia_ifa.ifa_dstaddr 526 = (struct sockaddr *)&ia->ia_dstaddr; 527 ia->ia_ifa.ifa_netmask 528 = (struct sockaddr *)&ia->ia_prefixmask; 529 530 ia->ia_ifp = ifp; 531 if ((oia = in6_ifaddr) != NULL) { 532 for ( ; oia->ia_next; oia = oia->ia_next) 533 continue; 534 oia->ia_next = ia; 535 } else 536 in6_ifaddr = ia; 537 TAILQ_INSERT_TAIL(&ifp->if_addrlist, 538 (struct ifaddr *)ia, ifa_list); 539 if ((ifp->if_flags & IFF_LOOPBACK) == 0) 540 in6_interfaces++; /*XXX*/ 541 } 542 543 if (cmd == SIOCAIFADDR_IN6) { 544 /* sanity for overflow - beware unsigned */ 545 struct in6_addrlifetime *lt; 546 lt = &ifra->ifra_lifetime; 547 if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME 548 && lt->ia6t_vltime + time_second < time_second) { 549 return EINVAL; 550 } 551 if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME 552 && lt->ia6t_pltime + time_second < time_second) { 553 return EINVAL; 554 } 555 } 556 break; 557 558 case SIOCGIFADDR_IN6: 559 /* This interface is basically deprecated. use SIOCGIFCONF. */ 560 /* fall through */ 561 case SIOCGIFAFLAG_IN6: 562 case SIOCGIFNETMASK_IN6: 563 case SIOCGIFDSTADDR_IN6: 564 case SIOCGIFALIFETIME_IN6: 565 /* must think again about its semantics */ 566 if (ia == 0) 567 return(EADDRNOTAVAIL); 568 break; 569 case SIOCSIFALIFETIME_IN6: 570 { 571 struct in6_addrlifetime *lt; 572 573 if (!privileged) 574 return(EPERM); 575 if (ia == 0) 576 return(EADDRNOTAVAIL); 577 /* sanity for overflow - beware unsigned */ 578 lt = &ifr->ifr_ifru.ifru_lifetime; 579 if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME 580 && lt->ia6t_vltime + time_second < time_second) { 581 return EINVAL; 582 } 583 if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME 584 && lt->ia6t_pltime + time_second < time_second) { 585 return EINVAL; 586 } 587 break; 588 } 589 } 590 591 switch (cmd) { 592 593 case SIOCGIFADDR_IN6: 594 ifr->ifr_addr = ia->ia_addr; 595 break; 596 597 case SIOCGIFDSTADDR_IN6: 598 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 599 return(EINVAL); 600 ifr->ifr_dstaddr = ia->ia_dstaddr; 601 break; 602 603 case SIOCGIFNETMASK_IN6: 604 ifr->ifr_addr = ia->ia_prefixmask; 605 break; 606 607 case SIOCGIFAFLAG_IN6: 608 ifr->ifr_ifru.ifru_flags6 = ia->ia6_flags; 609 break; 610 611 case SIOCGIFSTAT_IN6: 612 if (ifp == NULL) 613 return EINVAL; 614 if (in6_ifstat == NULL || ifp->if_index >= in6_ifstatmax 615 || in6_ifstat[ifp->if_index] == NULL) { 616 /* return EAFNOSUPPORT? */ 617 bzero(&ifr->ifr_ifru.ifru_stat, 618 sizeof(ifr->ifr_ifru.ifru_stat)); 619 } else 620 ifr->ifr_ifru.ifru_stat = *in6_ifstat[ifp->if_index]; 621 break; 622 623 case SIOCGIFSTAT_ICMP6: 624 if (ifp == NULL) 625 return EINVAL; 626 if (icmp6_ifstat == NULL || ifp->if_index >= icmp6_ifstatmax || 627 icmp6_ifstat[ifp->if_index] == NULL) { 628 /* return EAFNOSUPPORT? */ 629 bzero(&ifr->ifr_ifru.ifru_stat, 630 sizeof(ifr->ifr_ifru.ifru_icmp6stat)); 631 } else 632 ifr->ifr_ifru.ifru_icmp6stat = 633 *icmp6_ifstat[ifp->if_index]; 634 break; 635 636 case SIOCSIFDSTADDR_IN6: 637 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 638 return(EINVAL); 639 oldaddr = ia->ia_dstaddr; 640 ia->ia_dstaddr = ifr->ifr_dstaddr; 641 642 /* link-local index check */ 643 if (IN6_IS_ADDR_LINKLOCAL(&ia->ia_dstaddr.sin6_addr)) { 644 if (ia->ia_dstaddr.sin6_addr.s6_addr16[1] == 0) { 645 /* interface ID is not embedded by the user */ 646 ia->ia_dstaddr.sin6_addr.s6_addr16[1] 647 = htons(ifp->if_index); 648 } else 649 if (ia->ia_dstaddr.sin6_addr.s6_addr16[1] != 650 htons(ifp->if_index)) { 651 ia->ia_dstaddr = oldaddr; 652 return(EINVAL); /* ifid is contradict */ 653 } 654 } 655 656 if (ifp->if_ioctl && (error = (ifp->if_ioctl) 657 (ifp, SIOCSIFDSTADDR, (caddr_t)ia))) { 658 ia->ia_dstaddr = oldaddr; 659 return(error); 660 } 661 if (ia->ia_flags & IFA_ROUTE) { 662 ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr; 663 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 664 ia->ia_ifa.ifa_dstaddr = 665 (struct sockaddr *)&ia->ia_dstaddr; 666 rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); 667 } 668 break; 669 670 case SIOCGIFALIFETIME_IN6: 671 ifr->ifr_ifru.ifru_lifetime = ia->ia6_lifetime; 672 break; 673 674 case SIOCSIFALIFETIME_IN6: 675 ia->ia6_lifetime = ifr->ifr_ifru.ifru_lifetime; 676 /* for sanity */ 677 if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) { 678 ia->ia6_lifetime.ia6t_expire = 679 time_second + ia->ia6_lifetime.ia6t_vltime; 680 } else 681 ia->ia6_lifetime.ia6t_expire = 0; 682 if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) { 683 ia->ia6_lifetime.ia6t_preferred = 684 time_second + ia->ia6_lifetime.ia6t_pltime; 685 } else 686 ia->ia6_lifetime.ia6t_preferred = 0; 687 break; 688 689 case SIOCSIFADDR_IN6: 690 return(in6_ifinit(ifp, ia, &ifr->ifr_addr, 1)); 691 692 case SIOCSIFNETMASK_IN6: 693 ia->ia_prefixmask = ifr->ifr_addr; 694 bzero(&net, sizeof(net)); 695 net.sin6_len = sizeof(struct sockaddr_in6); 696 net.sin6_family = AF_INET6; 697 net.sin6_port = htons(0); 698 net.sin6_flowinfo = htonl(0); 699 net.sin6_addr.s6_addr32[0] 700 = ia->ia_addr.sin6_addr.s6_addr32[0] & 701 ia->ia_prefixmask.sin6_addr.s6_addr32[0]; 702 net.sin6_addr.s6_addr32[1] 703 = ia->ia_addr.sin6_addr.s6_addr32[1] & 704 ia->ia_prefixmask.sin6_addr.s6_addr32[1]; 705 net.sin6_addr.s6_addr32[2] 706 = ia->ia_addr.sin6_addr.s6_addr32[2] & 707 ia->ia_prefixmask.sin6_addr.s6_addr32[2]; 708 net.sin6_addr.s6_addr32[3] 709 = ia->ia_addr.sin6_addr.s6_addr32[3] & 710 ia->ia_prefixmask.sin6_addr.s6_addr32[3]; 711 ia->ia_net = net; 712 break; 713 714 case SIOCAIFADDR_IN6: 715 prefixIsNew = 0; 716 hostIsNew = 1; 717 718 if (ifra->ifra_addr.sin6_len == 0) { 719 ifra->ifra_addr = ia->ia_addr; 720 hostIsNew = 0; 721 } else if (IN6_ARE_ADDR_EQUAL(&ifra->ifra_addr.sin6_addr, 722 &ia->ia_addr.sin6_addr)) 723 hostIsNew = 0; 724 725 if (ifra->ifra_prefixmask.sin6_len) { 726 in6_ifscrub(ifp, ia); 727 ia->ia_prefixmask = ifra->ifra_prefixmask; 728 prefixIsNew = 1; 729 } 730 if ((ifp->if_flags & IFF_POINTOPOINT) && 731 (ifra->ifra_dstaddr.sin6_family == AF_INET6)) { 732 in6_ifscrub(ifp, ia); 733 ia->ia_dstaddr = ifra->ifra_dstaddr; 734 /* link-local index check: should be a separate function? */ 735 if (IN6_IS_ADDR_LINKLOCAL(&ia->ia_dstaddr.sin6_addr)) { 736 if (ia->ia_dstaddr.sin6_addr.s6_addr16[1] == 0) { 737 /* 738 * interface ID is not embedded by 739 * the user 740 */ 741 ia->ia_dstaddr.sin6_addr.s6_addr16[1] 742 = htons(ifp->if_index); 743 } else 744 if (ia->ia_dstaddr.sin6_addr.s6_addr16[1] != 745 htons(ifp->if_index)) { 746 ia->ia_dstaddr = oldaddr; 747 return(EINVAL); /* ifid is contradict */ 748 } 749 } 750 prefixIsNew = 1; /* We lie; but effect's the same */ 751 } 752 if (ifra->ifra_addr.sin6_family == AF_INET6 && 753 (hostIsNew || prefixIsNew)) 754 error = in6_ifinit(ifp, ia, &ifra->ifra_addr, 0); 755 if (ifra->ifra_addr.sin6_family == AF_INET6 756 && hostIsNew && (ifp->if_flags & IFF_MULTICAST)) { 757 int error_local = 0; 758 759 /* 760 * join solicited multicast addr for new host id 761 */ 762 struct in6_addr llsol; 763 bzero(&llsol, sizeof(struct in6_addr)); 764 llsol.s6_addr16[0] = htons(0xff02); 765 llsol.s6_addr16[1] = htons(ifp->if_index); 766 llsol.s6_addr32[1] = 0; 767 llsol.s6_addr32[2] = htonl(1); 768 llsol.s6_addr32[3] = 769 ifra->ifra_addr.sin6_addr.s6_addr32[3]; 770 llsol.s6_addr8[12] = 0xff; 771 (void)in6_addmulti(&llsol, ifp, &error_local); 772 if (error == 0) 773 error = error_local; 774 } 775 /* Join dstaddr's solicited multicast if necessary. */ 776 if (nd6_proxyall && hostIsNew) { 777 int error_local; 778 779 error_local = in6_ifaddproxy(ia); 780 if (error == 0) 781 error = error_local; 782 } 783 784 ia->ia6_flags = ifra->ifra_flags; 785 ia->ia6_flags &= ~IN6_IFF_DUPLICATED; /*safety*/ 786 787 ia->ia6_lifetime = ifra->ifra_lifetime; 788 /* for sanity */ 789 if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) { 790 ia->ia6_lifetime.ia6t_expire = 791 time_second + ia->ia6_lifetime.ia6t_vltime; 792 } else 793 ia->ia6_lifetime.ia6t_expire = 0; 794 if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) { 795 ia->ia6_lifetime.ia6t_preferred = 796 time_second + ia->ia6_lifetime.ia6t_pltime; 797 } else 798 ia->ia6_lifetime.ia6t_preferred = 0; 799 800 /* 801 * Perform DAD, if needed. 802 * XXX It may be of use, if we can administratively 803 * disable DAD. 804 */ 805 switch (ifp->if_type) { 806 case IFT_ARCNET: 807 case IFT_ETHER: 808 case IFT_FDDI: 809 ia->ia6_flags |= IN6_IFF_TENTATIVE; 810 nd6_dad_start((struct ifaddr *)ia, NULL); 811 break; 812 #ifdef IFT_DUMMY 813 case IFT_DUMMY: 814 #endif 815 case IFT_FAITH: 816 case IFT_GIF: 817 case IFT_LOOP: 818 default: 819 break; 820 } 821 822 if (hostIsNew) { 823 int iilen; 824 int error_local = 0; 825 826 iilen = (sizeof(ia->ia_prefixmask.sin6_addr) << 3) - 827 in6_mask2len(&ia->ia_prefixmask.sin6_addr); 828 error_local = in6_prefix_add_ifid(iilen, ia); 829 if (error == 0) 830 error = error_local; 831 } 832 833 return(error); 834 835 case SIOCDIFADDR_IN6: 836 in6_ifscrub(ifp, ia); 837 838 if (ifp->if_flags & IFF_MULTICAST) { 839 /* 840 * delete solicited multicast addr for deleting host id 841 */ 842 struct in6_multi *in6m; 843 struct in6_addr llsol; 844 bzero(&llsol, sizeof(struct in6_addr)); 845 llsol.s6_addr16[0] = htons(0xff02); 846 llsol.s6_addr16[1] = htons(ifp->if_index); 847 llsol.s6_addr32[1] = 0; 848 llsol.s6_addr32[2] = htonl(1); 849 llsol.s6_addr32[3] = 850 ia->ia_addr.sin6_addr.s6_addr32[3]; 851 llsol.s6_addr8[12] = 0xff; 852 853 IN6_LOOKUP_MULTI(llsol, ifp, in6m); 854 if (in6m) 855 in6_delmulti(in6m); 856 } 857 /* Leave dstaddr's solicited multicast if necessary. */ 858 if (nd6_proxyall) 859 in6_ifremproxy(ia); 860 861 TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list); 862 oia = ia; 863 if (oia == (ia = in6_ifaddr)) 864 in6_ifaddr = ia->ia_next; 865 else { 866 while (ia->ia_next && (ia->ia_next != oia)) 867 ia = ia->ia_next; 868 if (ia->ia_next) 869 ia->ia_next = oia->ia_next; 870 else 871 printf("Didn't unlink in6_ifaddr from list\n"); 872 } 873 { 874 int iilen; 875 876 iilen = (sizeof(oia->ia_prefixmask.sin6_addr) << 3) - 877 in6_mask2len(&oia->ia_prefixmask.sin6_addr); 878 in6_prefix_remove_ifid(iilen, oia); 879 } 880 IFAFREE((&oia->ia_ifa)); 881 break; 882 883 default: 884 if (ifp == 0 || ifp->if_ioctl == 0) 885 return(EOPNOTSUPP); 886 return((*ifp->if_ioctl)(ifp, cmd, data)); 887 } 888 return(0); 889 } 890 891 /* 892 * SIOC[GAD]LIFADDR. 893 * SIOCGLIFADDR: get first address. (?!?) 894 * SIOCGLIFADDR with IFLR_PREFIX: 895 * get first address that matches the specified prefix. 896 * SIOCALIFADDR: add the specified address. 897 * SIOCALIFADDR with IFLR_PREFIX: 898 * add the specified prefix, filling hostid part from 899 * the first link-local address. prefixlen must be <= 64. 900 * SIOCDLIFADDR: delete the specified address. 901 * SIOCDLIFADDR with IFLR_PREFIX: 902 * delete the first address that matches the specified prefix. 903 * return values: 904 * EINVAL on invalid parameters 905 * EADDRNOTAVAIL on prefix match failed/specified address not found 906 * other values may be returned from in6_ioctl() 907 * 908 * NOTE: SIOCALIFADDR(with IFLR_PREFIX set) allows prefixlen less than 64. 909 * this is to accomodate address naming scheme other than RFC2374, 910 * in the future. 911 * RFC2373 defines interface id to be 64bit, but it allows non-RFC2374 912 * address encoding scheme. (see figure on page 8) 913 */ 914 static int 915 in6_lifaddr_ioctl(so, cmd, data, ifp, p) 916 struct socket *so; 917 u_long cmd; 918 caddr_t data; 919 struct ifnet *ifp; 920 struct proc *p; 921 { 922 struct if_laddrreq *iflr = (struct if_laddrreq *)data; 923 struct ifaddr *ifa; 924 925 /* sanity checks */ 926 if (!data || !ifp) { 927 panic("invalid argument to in6_lifaddr_ioctl"); 928 /*NOTRECHED*/ 929 } 930 931 switch (cmd) { 932 case SIOCGLIFADDR: 933 /* address must be specified on GET with IFLR_PREFIX */ 934 if ((iflr->flags & IFLR_PREFIX) == 0) 935 break; 936 /*FALLTHROUGH*/ 937 case SIOCALIFADDR: 938 case SIOCDLIFADDR: 939 /* address must be specified on ADD and DELETE */ 940 if (iflr->addr.ss_family != AF_INET6) 941 return EINVAL; 942 if (iflr->addr.ss_len != sizeof(struct sockaddr_in6)) 943 return EINVAL; 944 /* XXX need improvement */ 945 if (iflr->dstaddr.ss_family 946 && iflr->dstaddr.ss_family != AF_INET6) 947 return EINVAL; 948 if (iflr->dstaddr.ss_family 949 && iflr->dstaddr.ss_len != sizeof(struct sockaddr_in6)) 950 return EINVAL; 951 break; 952 default: /*shouldn't happen*/ 953 return EOPNOTSUPP; 954 } 955 if (sizeof(struct in6_addr) * 8 < iflr->prefixlen) 956 return EINVAL; 957 958 switch (cmd) { 959 case SIOCALIFADDR: 960 { 961 struct in6_aliasreq ifra; 962 struct in6_addr *hostid = NULL; 963 int prefixlen; 964 965 if ((iflr->flags & IFLR_PREFIX) != 0) { 966 struct sockaddr_in6 *sin6; 967 968 /* 969 * hostid is to fill in the hostid part of the 970 * address. hostid points to the first link-local 971 * address attached to the interface. 972 */ 973 ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp); 974 if (!ifa) 975 return EADDRNOTAVAIL; 976 hostid = IFA_IN6(ifa); 977 978 /* prefixlen must be <= 64. */ 979 if (64 < iflr->prefixlen) 980 return EINVAL; 981 prefixlen = iflr->prefixlen; 982 983 /* hostid part must be zero. */ 984 sin6 = (struct sockaddr_in6 *)&iflr->addr; 985 if (sin6->sin6_addr.s6_addr32[2] != 0 986 || sin6->sin6_addr.s6_addr32[3] != 0) { 987 return EINVAL; 988 } 989 } else 990 prefixlen = iflr->prefixlen; 991 992 /* copy args to in6_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */ 993 bzero(&ifra, sizeof(ifra)); 994 bcopy(iflr->iflr_name, ifra.ifra_name, 995 sizeof(ifra.ifra_name)); 996 997 bcopy(&iflr->addr, &ifra.ifra_addr, iflr->addr.ss_len); 998 if (hostid) { 999 /* fill in hostid part */ 1000 ifra.ifra_addr.sin6_addr.s6_addr32[2] = 1001 hostid->s6_addr32[2]; 1002 ifra.ifra_addr.sin6_addr.s6_addr32[3] = 1003 hostid->s6_addr32[3]; 1004 } 1005 1006 if (iflr->dstaddr.ss_family) { /*XXX*/ 1007 bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr, 1008 iflr->dstaddr.ss_len); 1009 if (hostid) { 1010 ifra.ifra_dstaddr.sin6_addr.s6_addr32[2] = 1011 hostid->s6_addr32[2]; 1012 ifra.ifra_dstaddr.sin6_addr.s6_addr32[3] = 1013 hostid->s6_addr32[3]; 1014 } 1015 } 1016 1017 ifra.ifra_prefixmask.sin6_family = AF_INET6; 1018 ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6); 1019 in6_len2mask(&ifra.ifra_prefixmask.sin6_addr, prefixlen); 1020 1021 ifra.ifra_flags = iflr->flags & ~IFLR_PREFIX; 1022 return in6_control(so, SIOCAIFADDR_IN6, (caddr_t)&ifra, ifp, p); 1023 } 1024 case SIOCGLIFADDR: 1025 case SIOCDLIFADDR: 1026 { 1027 struct in6_ifaddr *ia; 1028 struct in6_addr mask, candidate, match; 1029 struct sockaddr_in6 *sin6; 1030 int cmp; 1031 1032 bzero(&mask, sizeof(mask)); 1033 if (iflr->flags & IFLR_PREFIX) { 1034 /* lookup a prefix rather than address. */ 1035 in6_len2mask(&mask, iflr->prefixlen); 1036 1037 sin6 = (struct sockaddr_in6 *)&iflr->addr; 1038 bcopy(&sin6->sin6_addr, &match, sizeof(match)); 1039 match.s6_addr32[0] &= mask.s6_addr32[0]; 1040 match.s6_addr32[1] &= mask.s6_addr32[1]; 1041 match.s6_addr32[2] &= mask.s6_addr32[2]; 1042 match.s6_addr32[3] &= mask.s6_addr32[3]; 1043 1044 /* if you set extra bits, that's wrong */ 1045 if (bcmp(&match, &sin6->sin6_addr, sizeof(match))) 1046 return EINVAL; 1047 1048 cmp = 1; 1049 } else { 1050 if (cmd == SIOCGLIFADDR) { 1051 /* on getting an address, take the 1st match */ 1052 cmp = 0; /*XXX*/ 1053 } else { 1054 /* on deleting an address, do exact match */ 1055 in6_len2mask(&mask, 128); 1056 sin6 = (struct sockaddr_in6 *)&iflr->addr; 1057 bcopy(&sin6->sin6_addr, &match, sizeof(match)); 1058 1059 cmp = 1; 1060 } 1061 } 1062 1063 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) 1064 { 1065 if (ifa->ifa_addr->sa_family != AF_INET6) 1066 continue; 1067 if (!cmp) 1068 break; 1069 bcopy(IFA_IN6(ifa), &candidate, sizeof(candidate)); 1070 candidate.s6_addr32[0] &= mask.s6_addr32[0]; 1071 candidate.s6_addr32[1] &= mask.s6_addr32[1]; 1072 candidate.s6_addr32[2] &= mask.s6_addr32[2]; 1073 candidate.s6_addr32[3] &= mask.s6_addr32[3]; 1074 if (IN6_ARE_ADDR_EQUAL(&candidate, &match)) 1075 break; 1076 } 1077 if (!ifa) 1078 return EADDRNOTAVAIL; 1079 ia = ifa2ia6(ifa); 1080 1081 if (cmd == SIOCGLIFADDR) { 1082 /* fill in the if_laddrreq structure */ 1083 bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin6_len); 1084 1085 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { 1086 bcopy(&ia->ia_dstaddr, &iflr->dstaddr, 1087 ia->ia_dstaddr.sin6_len); 1088 } else 1089 bzero(&iflr->dstaddr, sizeof(iflr->dstaddr)); 1090 1091 iflr->prefixlen = 1092 in6_mask2len(&ia->ia_prefixmask.sin6_addr); 1093 1094 iflr->flags = ia->ia6_flags; /*XXX*/ 1095 1096 return 0; 1097 } else { 1098 struct in6_aliasreq ifra; 1099 1100 /* fill in6_aliasreq and do ioctl(SIOCDIFADDR_IN6) */ 1101 bzero(&ifra, sizeof(ifra)); 1102 bcopy(iflr->iflr_name, ifra.ifra_name, 1103 sizeof(ifra.ifra_name)); 1104 1105 bcopy(&ia->ia_addr, &ifra.ifra_addr, 1106 ia->ia_addr.sin6_len); 1107 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { 1108 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr, 1109 ia->ia_dstaddr.sin6_len); 1110 } 1111 bcopy(&ia->ia_prefixmask, &ifra.ifra_dstaddr, 1112 ia->ia_prefixmask.sin6_len); 1113 1114 ifra.ifra_flags = ia->ia6_flags; 1115 return in6_control(so, SIOCDIFADDR_IN6, (caddr_t)&ifra, 1116 ifp, p); 1117 } 1118 } 1119 } 1120 1121 return EOPNOTSUPP; /*just for safety*/ 1122 } 1123 1124 /* 1125 * Delete any existing route for an interface. 1126 */ 1127 void 1128 in6_ifscrub(ifp, ia) 1129 register struct ifnet *ifp; 1130 register struct in6_ifaddr *ia; 1131 { 1132 if ((ia->ia_flags & IFA_ROUTE) == 0) 1133 return; 1134 if (ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) 1135 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 1136 else 1137 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0); 1138 ia->ia_flags &= ~IFA_ROUTE; 1139 1140 /* Remove ownaddr's loopback rtentry, if it exists. */ 1141 in6_ifremloop(&(ia->ia_ifa)); 1142 } 1143 1144 /* 1145 * Initialize an interface's intetnet6 address 1146 * and routing table entry. 1147 */ 1148 int 1149 in6_ifinit(ifp, ia, sin6, scrub) 1150 struct ifnet *ifp; 1151 struct in6_ifaddr *ia; 1152 struct sockaddr_in6 *sin6; 1153 int scrub; 1154 { 1155 struct sockaddr_in6 oldaddr; 1156 int error, flags = RTF_UP; 1157 int s = splimp(); 1158 1159 oldaddr = ia->ia_addr; 1160 ia->ia_addr = *sin6; 1161 /* 1162 * Give the interface a chance to initialize 1163 * if this is its first address, 1164 * and to validate the address if necessary. 1165 */ 1166 if (ifp->if_ioctl && 1167 (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) { 1168 splx(s); 1169 ia->ia_addr = oldaddr; 1170 return(error); 1171 } 1172 1173 switch (ifp->if_type) { 1174 case IFT_ARCNET: 1175 case IFT_ETHER: 1176 case IFT_FDDI: 1177 ia->ia_ifa.ifa_rtrequest = nd6_rtrequest; 1178 ia->ia_ifa.ifa_flags |= RTF_CLONING; 1179 break; 1180 case IFT_PPP: 1181 ia->ia_ifa.ifa_rtrequest = nd6_p2p_rtrequest; 1182 ia->ia_ifa.ifa_flags |= RTF_CLONING; 1183 break; 1184 } 1185 1186 splx(s); 1187 if (scrub) { 1188 ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr; 1189 in6_ifscrub(ifp, ia); 1190 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 1191 } 1192 /* xxx 1193 * in_socktrim 1194 */ 1195 /* 1196 * Add route for the network. 1197 */ 1198 ia->ia_ifa.ifa_metric = ifp->if_metric; 1199 if (ifp->if_flags & IFF_LOOPBACK) { 1200 ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr; 1201 flags |= RTF_HOST; 1202 } else if (ifp->if_flags & IFF_POINTOPOINT) { 1203 if (ia->ia_dstaddr.sin6_family != AF_INET6) 1204 return(0); 1205 flags |= RTF_HOST; 1206 } 1207 if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0) 1208 ia->ia_flags |= IFA_ROUTE; 1209 1210 /* Add ownaddr as loopback rtentry, if necessary(ex. on p2p link). */ 1211 in6_ifaddloop(&(ia->ia_ifa)); 1212 1213 return(error); 1214 } 1215 1216 /* 1217 * Add an address to the list of IP6 multicast addresses for a 1218 * given interface. 1219 */ 1220 struct in6_multi * 1221 in6_addmulti(maddr6, ifp, errorp) 1222 register struct in6_addr *maddr6; 1223 register struct ifnet *ifp; 1224 int *errorp; 1225 { 1226 struct in6_multi *in6m; 1227 struct sockaddr_in6 sin6; 1228 struct ifmultiaddr *ifma; 1229 int s = splnet(); 1230 1231 *errorp = 0; 1232 1233 /* 1234 * Call generic routine to add membership or increment 1235 * refcount. It wants addresses in the form of a sockaddr, 1236 * so we build one here (being careful to zero the unused bytes). 1237 */ 1238 bzero(&sin6, sizeof sin6); 1239 sin6.sin6_family = AF_INET6; 1240 sin6.sin6_len = sizeof sin6; 1241 sin6.sin6_addr = *maddr6; 1242 *errorp = if_addmulti(ifp, (struct sockaddr *)&sin6, &ifma); 1243 if (*errorp) { 1244 splx(s); 1245 return 0; 1246 } 1247 1248 /* 1249 * If ifma->ifma_protospec is null, then if_addmulti() created 1250 * a new record. Otherwise, we are done. 1251 */ 1252 if (ifma->ifma_protospec != 0) 1253 return ifma->ifma_protospec; 1254 1255 /* XXX - if_addmulti uses M_WAITOK. Can this really be called 1256 at interrupt time? If so, need to fix if_addmulti. XXX */ 1257 in6m = (struct in6_multi *)malloc(sizeof(*in6m), M_IPMADDR, M_NOWAIT); 1258 if (in6m == NULL) { 1259 splx(s); 1260 return (NULL); 1261 } 1262 1263 bzero(in6m, sizeof *in6m); 1264 in6m->in6m_addr = *maddr6; 1265 in6m->in6m_ifp = ifp; 1266 in6m->in6m_ifma = ifma; 1267 ifma->ifma_protospec = in6m; 1268 LIST_INSERT_HEAD(&in6_multihead, in6m, in6m_entry); 1269 1270 /* 1271 * Let MLD6 know that we have joined a new IP6 multicast 1272 * group. 1273 */ 1274 mld6_start_listening(in6m); 1275 splx(s); 1276 return(in6m); 1277 } 1278 1279 /* 1280 * Delete a multicast address record. 1281 */ 1282 void 1283 in6_delmulti(in6m) 1284 struct in6_multi *in6m; 1285 { 1286 struct ifmultiaddr *ifma = in6m->in6m_ifma; 1287 int s = splnet(); 1288 1289 if (ifma->ifma_refcount == 1) { 1290 /* 1291 * No remaining claims to this record; let MLD6 know 1292 * that we are leaving the multicast group. 1293 */ 1294 mld6_stop_listening(in6m); 1295 ifma->ifma_protospec = 0; 1296 LIST_REMOVE(in6m, in6m_entry); 1297 free(in6m, M_IPMADDR); 1298 } 1299 /* XXX - should be separate API for when we have an ifma? */ 1300 if_delmulti(ifma->ifma_ifp, ifma->ifma_addr); 1301 splx(s); 1302 } 1303 1304 /* 1305 * Find an IPv6 interface link-local address specific to an interface. 1306 */ 1307 struct in6_ifaddr * 1308 in6ifa_ifpforlinklocal(ifp) 1309 struct ifnet *ifp; 1310 { 1311 register struct ifaddr *ifa; 1312 1313 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) 1314 { 1315 if (ifa->ifa_addr == NULL) 1316 continue; /* just for safety */ 1317 if (ifa->ifa_addr->sa_family != AF_INET6) 1318 continue; 1319 if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa))) 1320 break; 1321 } 1322 1323 return((struct in6_ifaddr *)ifa); 1324 } 1325 1326 1327 /* 1328 * find the internet address corresponding to a given interface and address. 1329 */ 1330 struct in6_ifaddr * 1331 in6ifa_ifpwithaddr(ifp, addr) 1332 struct ifnet *ifp; 1333 struct in6_addr *addr; 1334 { 1335 register struct ifaddr *ifa; 1336 1337 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) 1338 { 1339 if (ifa->ifa_addr == NULL) 1340 continue; /* just for safety */ 1341 if (ifa->ifa_addr->sa_family != AF_INET6) 1342 continue; 1343 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa))) 1344 break; 1345 } 1346 1347 return((struct in6_ifaddr *)ifa); 1348 } 1349 1350 /* 1351 * Convert IP6 address to printable (loggable) representation. 1352 */ 1353 static char digits[] = "0123456789abcdef"; 1354 static int ip6round = 0; 1355 char * 1356 ip6_sprintf(addr) 1357 register struct in6_addr *addr; 1358 { 1359 static char ip6buf[8][48]; 1360 register int i; 1361 register char *cp; 1362 register u_short *a = (u_short *)addr; 1363 register u_char *d; 1364 int dcolon = 0; 1365 1366 ip6round = (ip6round + 1) & 7; 1367 cp = ip6buf[ip6round]; 1368 1369 for (i = 0; i < 8; i++) { 1370 if (dcolon == 1) { 1371 if (*a == 0) { 1372 if (i == 7) 1373 *cp++ = ':'; 1374 a++; 1375 continue; 1376 } else 1377 dcolon = 2; 1378 } 1379 if (*a == 0) { 1380 if (dcolon == 0 && *(a + 1) == 0) { 1381 if (i == 0) 1382 *cp++ = ':'; 1383 *cp++ = ':'; 1384 dcolon = 1; 1385 } else { 1386 *cp++ = '0'; 1387 *cp++ = ':'; 1388 } 1389 a++; 1390 continue; 1391 } 1392 d = (u_char *)a; 1393 *cp++ = digits[*d >> 4]; 1394 *cp++ = digits[*d++ & 0xf]; 1395 *cp++ = digits[*d >> 4]; 1396 *cp++ = digits[*d & 0xf]; 1397 *cp++ = ':'; 1398 a++; 1399 } 1400 *--cp = 0; 1401 return(ip6buf[ip6round]); 1402 } 1403 1404 int 1405 in6_localaddr(in6) 1406 struct in6_addr *in6; 1407 { 1408 struct in6_ifaddr *ia; 1409 1410 if (IN6_IS_ADDR_LOOPBACK(in6) || IN6_IS_ADDR_LINKLOCAL(in6)) 1411 return 1; 1412 1413 for (ia = in6_ifaddr; ia; ia = ia->ia_next) 1414 if (IN6_ARE_MASKED_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr, 1415 &ia->ia_prefixmask.sin6_addr)) 1416 return 1; 1417 1418 return (0); 1419 } 1420 1421 /* 1422 * Get a scope of the address. Node-local, link-local, site-local or global. 1423 */ 1424 int 1425 in6_addrscope (addr) 1426 struct in6_addr *addr; 1427 { 1428 int scope; 1429 1430 if (addr->s6_addr8[0] == 0xfe) { 1431 scope = addr->s6_addr8[1] & 0xc0; 1432 1433 switch (scope) { 1434 case 0x80: 1435 return IPV6_ADDR_SCOPE_LINKLOCAL; 1436 break; 1437 case 0xc0: 1438 return IPV6_ADDR_SCOPE_SITELOCAL; 1439 break; 1440 default: 1441 return IPV6_ADDR_SCOPE_GLOBAL; /* just in case */ 1442 break; 1443 } 1444 } 1445 1446 1447 if (addr->s6_addr8[0] == 0xff) { 1448 scope = addr->s6_addr8[1] & 0x0f; 1449 1450 /* 1451 * due to other scope such as reserved, 1452 * return scope doesn't work. 1453 */ 1454 switch (scope) { 1455 case IPV6_ADDR_SCOPE_NODELOCAL: 1456 return IPV6_ADDR_SCOPE_NODELOCAL; 1457 break; 1458 case IPV6_ADDR_SCOPE_LINKLOCAL: 1459 return IPV6_ADDR_SCOPE_LINKLOCAL; 1460 break; 1461 case IPV6_ADDR_SCOPE_SITELOCAL: 1462 return IPV6_ADDR_SCOPE_SITELOCAL; 1463 break; 1464 default: 1465 return IPV6_ADDR_SCOPE_GLOBAL; 1466 break; 1467 } 1468 } 1469 1470 if (bcmp(&in6addr_loopback, addr, sizeof(addr) - 1) == 0) { 1471 if (addr->s6_addr8[15] == 1) /* loopback */ 1472 return IPV6_ADDR_SCOPE_NODELOCAL; 1473 if (addr->s6_addr8[15] == 0) /* unspecified */ 1474 return IPV6_ADDR_SCOPE_LINKLOCAL; 1475 } 1476 1477 return IPV6_ADDR_SCOPE_GLOBAL; 1478 } 1479 1480 /* 1481 * return length of part which dst and src are equal 1482 * hard coding... 1483 */ 1484 1485 int 1486 in6_matchlen(src, dst) 1487 struct in6_addr *src, *dst; 1488 { 1489 int match = 0; 1490 u_char *s = (u_char *)src, *d = (u_char *)dst; 1491 u_char *lim = s + 16, r; 1492 1493 while (s < lim) 1494 if ((r = (*d++ ^ *s++)) != 0) { 1495 while (r < 128) { 1496 match++; 1497 r <<= 1; 1498 } 1499 break; 1500 } else 1501 match += 8; 1502 return match; 1503 } 1504 1505 int 1506 in6_are_prefix_equal(p1, p2, len) 1507 struct in6_addr *p1, *p2; 1508 int len; 1509 { 1510 int bytelen, bitlen; 1511 1512 /* sanity check */ 1513 if (0 > len || len > 128) { 1514 log(LOG_ERR, "in6_are_prefix_equal: invalid prefix length(%d)\n", 1515 len); 1516 return(0); 1517 } 1518 1519 bytelen = len / 8; 1520 bitlen = len % 8; 1521 1522 if (bcmp(&p1->s6_addr, &p2->s6_addr, bytelen)) 1523 return(0); 1524 if (p1->s6_addr[bytelen] >> (8 - bitlen) != 1525 p2->s6_addr[bytelen] >> (8 - bitlen)) 1526 return(0); 1527 1528 return(1); 1529 } 1530 1531 void 1532 in6_prefixlen2mask(maskp, len) 1533 struct in6_addr *maskp; 1534 int len; 1535 { 1536 u_char maskarray[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; 1537 int bytelen, bitlen, i; 1538 1539 /* sanity check */ 1540 if (0 > len || len > 128) { 1541 log(LOG_ERR, "in6_prefixlen2mask: invalid prefix length(%d)\n", 1542 len); 1543 return; 1544 } 1545 1546 bzero(maskp, sizeof(*maskp)); 1547 bytelen = len / 8; 1548 bitlen = len % 8; 1549 for (i = 0; i < bytelen; i++) 1550 maskp->s6_addr[i] = 0xff; 1551 if (bitlen) 1552 maskp->s6_addr[bytelen] = maskarray[bitlen - 1]; 1553 } 1554 1555 /* 1556 * return the best address out of the same scope 1557 */ 1558 1559 struct in6_ifaddr * 1560 in6_ifawithscope(ifp, dst) 1561 register struct ifnet *ifp; 1562 register struct in6_addr *dst; 1563 { 1564 int dst_scope = in6_addrscope(dst), blen = -1, tlen; 1565 struct ifaddr *ifa; 1566 struct in6_ifaddr *besta = NULL, *ia; 1567 struct in6_ifaddr *dep[3]; /*last-resort: deprecated*/ 1568 1569 dep[0] = dep[1] = dep[2] = NULL; 1570 1571 /* 1572 * We first look for addresses in the same scope. 1573 * If there is one, return it. 1574 * If two or more, return one which matches the dst longest. 1575 * If none, return one of global addresses assigned other ifs. 1576 */ 1577 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) 1578 { 1579 if (ifa->ifa_addr->sa_family != AF_INET6) 1580 continue; 1581 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST) 1582 continue; /* XXX: is there any case to allow anycast? */ 1583 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY) 1584 continue; /* don't use this interface */ 1585 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED) 1586 continue; 1587 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) { 1588 if (ip6_use_deprecated) 1589 dep[0] = (struct in6_ifaddr *)ifa; 1590 continue; 1591 } 1592 1593 if (dst_scope == in6_addrscope(IFA_IN6(ifa))) { 1594 /* 1595 * call in6_matchlen() as few as possible 1596 */ 1597 if (besta) { 1598 if (blen == -1) 1599 blen = in6_matchlen(&besta->ia_addr.sin6_addr, dst); 1600 tlen = in6_matchlen(IFA_IN6(ifa), dst); 1601 if (tlen > blen) { 1602 blen = tlen; 1603 besta = (struct in6_ifaddr *)ifa; 1604 } 1605 } else 1606 besta = (struct in6_ifaddr *)ifa; 1607 } 1608 } 1609 if (besta) 1610 return besta; 1611 1612 for (ia = in6_ifaddr; ia; ia = ia->ia_next) { 1613 if (IPV6_ADDR_SCOPE_GLOBAL != 1614 in6_addrscope(&(ia->ia_addr.sin6_addr))) 1615 continue; 1616 /* XXX: is there any case to allow anycast? */ 1617 if ((ia->ia6_flags & IN6_IFF_ANYCAST) != 0) 1618 continue; 1619 if ((ia->ia6_flags & IN6_IFF_NOTREADY) != 0) 1620 continue; 1621 if ((ia->ia6_flags & IN6_IFF_DETACHED) != 0) 1622 continue; 1623 if ((ia->ia6_flags & IN6_IFF_DEPRECATED) != 0) { 1624 if (ip6_use_deprecated) 1625 dep[1] = (struct in6_ifaddr *)ifa; 1626 continue; 1627 } 1628 return ia; 1629 } 1630 1631 for (ia = in6_ifaddr; ia; ia = ia->ia_next) { 1632 if (IPV6_ADDR_SCOPE_SITELOCAL != 1633 in6_addrscope(&(ia->ia_addr.sin6_addr))) 1634 continue; 1635 /* XXX: is there any case to allow anycast? */ 1636 if ((ia->ia6_flags & IN6_IFF_ANYCAST) != 0) 1637 continue; 1638 if ((ia->ia6_flags & IN6_IFF_NOTREADY) != 0) 1639 continue; 1640 if ((ia->ia6_flags & IN6_IFF_DETACHED) != 0) 1641 continue; 1642 if ((ia->ia6_flags & IN6_IFF_DEPRECATED) != 0) { 1643 if (ip6_use_deprecated) 1644 dep[2] = (struct in6_ifaddr *)ifa; 1645 continue; 1646 } 1647 return ia; 1648 } 1649 1650 /* use the last-resort values, that are, deprecated addresses */ 1651 if (dep[0]) 1652 return dep[0]; 1653 if (dep[1]) 1654 return dep[1]; 1655 if (dep[2]) 1656 return dep[2]; 1657 1658 return NULL; 1659 } 1660 1661 /* 1662 * return the best address out of the same scope. if no address was 1663 * found, return the first valid address from designated IF. 1664 */ 1665 1666 struct in6_ifaddr * 1667 in6_ifawithifp(ifp, dst) 1668 register struct ifnet *ifp; 1669 register struct in6_addr *dst; 1670 { 1671 int dst_scope = in6_addrscope(dst), blen = -1, tlen; 1672 struct ifaddr *ifa; 1673 struct in6_ifaddr *besta = 0; 1674 struct in6_ifaddr *dep[2]; /*last-resort: deprecated*/ 1675 1676 dep[0] = dep[1] = NULL; 1677 1678 /* 1679 * We first look for addresses in the same scope. 1680 * If there is one, return it. 1681 * If two or more, return one which matches the dst longest. 1682 * If none, return one of global addresses assigned other ifs. 1683 */ 1684 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) 1685 { 1686 if (ifa->ifa_addr->sa_family != AF_INET6) 1687 continue; 1688 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST) 1689 continue; /* XXX: is there any case to allow anycast? */ 1690 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY) 1691 continue; /* don't use this interface */ 1692 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED) 1693 continue; 1694 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) { 1695 if (ip6_use_deprecated) 1696 dep[0] = (struct in6_ifaddr *)ifa; 1697 continue; 1698 } 1699 1700 if (dst_scope == in6_addrscope(IFA_IN6(ifa))) { 1701 /* 1702 * call in6_matchlen() as few as possible 1703 */ 1704 if (besta) { 1705 if (blen == -1) 1706 blen = in6_matchlen(&besta->ia_addr.sin6_addr, dst); 1707 tlen = in6_matchlen(IFA_IN6(ifa), dst); 1708 if (tlen > blen) { 1709 blen = tlen; 1710 besta = (struct in6_ifaddr *)ifa; 1711 } 1712 } else 1713 besta = (struct in6_ifaddr *)ifa; 1714 } 1715 } 1716 if (besta) 1717 return(besta); 1718 1719 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) 1720 { 1721 if (ifa->ifa_addr->sa_family != AF_INET6) 1722 continue; 1723 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST) 1724 continue; /* XXX: is there any case to allow anycast? */ 1725 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY) 1726 continue; /* don't use this interface */ 1727 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED) 1728 continue; 1729 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) { 1730 if (ip6_use_deprecated) 1731 dep[1] = (struct in6_ifaddr *)ifa; 1732 continue; 1733 } 1734 1735 return (struct in6_ifaddr *)ifa; 1736 } 1737 1738 /* use the last-resort values, that are, deprecated addresses */ 1739 if (dep[0]) 1740 return dep[0]; 1741 if (dep[1]) 1742 return dep[1]; 1743 1744 return NULL; 1745 } 1746 1747 /* 1748 * perform DAD when interface becomes IFF_UP. 1749 */ 1750 void 1751 in6_if_up(ifp) 1752 struct ifnet *ifp; 1753 { 1754 struct ifaddr *ifa; 1755 struct in6_ifaddr *ia; 1756 struct sockaddr_dl *sdl; 1757 int type; 1758 struct ether_addr ea; 1759 int off; 1760 int dad_delay; /* delay ticks before DAD output */ 1761 1762 bzero(&ea, sizeof(ea)); 1763 sdl = NULL; 1764 1765 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) 1766 { 1767 if (ifa->ifa_addr->sa_family == AF_INET6 1768 && IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr)) { 1769 goto dad; 1770 } 1771 if (ifa->ifa_addr->sa_family != AF_LINK) 1772 continue; 1773 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 1774 break; 1775 } 1776 1777 switch (ifp->if_type) { 1778 case IFT_SLIP: 1779 case IFT_PPP: 1780 #ifdef IFT_DUMMY 1781 case IFT_DUMMY: 1782 #endif 1783 case IFT_GIF: 1784 case IFT_FAITH: 1785 type = IN6_IFT_P2P; 1786 in6_ifattach(ifp, type, 0, 1); 1787 break; 1788 case IFT_ETHER: 1789 case IFT_FDDI: 1790 case IFT_ATM: 1791 type = IN6_IFT_802; 1792 if (sdl == NULL) 1793 break; 1794 off = sdl->sdl_nlen; 1795 if (bcmp(&sdl->sdl_data[off], &ea, sizeof(ea)) != 0) 1796 in6_ifattach(ifp, type, LLADDR(sdl), 0); 1797 break; 1798 case IFT_ARCNET: 1799 type = IN6_IFT_ARCNET; 1800 if (sdl == NULL) 1801 break; 1802 off = sdl->sdl_nlen; 1803 if (sdl->sdl_data[off] != 0) /* XXX ?: */ 1804 in6_ifattach(ifp, type, LLADDR(sdl), 0); 1805 break; 1806 default: 1807 break; 1808 } 1809 1810 dad: 1811 dad_delay = 0; 1812 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) 1813 { 1814 if (ifa->ifa_addr->sa_family != AF_INET6) 1815 continue; 1816 ia = (struct in6_ifaddr *)ifa; 1817 if (ia->ia6_flags & IN6_IFF_TENTATIVE) 1818 nd6_dad_start(ifa, &dad_delay); 1819 } 1820 } 1821 1822 /* 1823 * Calculate max IPv6 MTU through all the interfaces and store it 1824 * to in6_maxmtu. 1825 */ 1826 void 1827 in6_setmaxmtu() 1828 { 1829 unsigned long maxmtu = 0; 1830 struct ifnet *ifp; 1831 1832 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) 1833 { 1834 if ((ifp->if_flags & IFF_LOOPBACK) == 0 && 1835 nd_ifinfo[ifp->if_index].linkmtu > maxmtu) 1836 maxmtu = nd_ifinfo[ifp->if_index].linkmtu; 1837 } 1838 if (maxmtu) /* update only when maxmtu is positive */ 1839 in6_maxmtu = maxmtu; 1840 } 1841 1842 /* 1843 * Convert sockaddr_in6 to sockaddr_in. Original sockaddr_in6 must be 1844 * v4 mapped addr or v4 compat addr 1845 */ 1846 void 1847 in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6) 1848 { 1849 bzero(sin, sizeof(*sin)); 1850 sin->sin_len = sizeof(struct sockaddr_in); 1851 sin->sin_family = AF_INET; 1852 sin->sin_port = sin6->sin6_port; 1853 sin->sin_addr.s_addr = sin6->sin6_addr.s6_addr32[3]; 1854 } 1855 1856 /* Convert sockaddr_in to sockaddr_in6 in v4 mapped addr format. */ 1857 void 1858 in6_sin_2_v4mapsin6(struct sockaddr_in *sin, struct sockaddr_in6 *sin6) 1859 { 1860 bzero(sin6, sizeof(*sin6)); 1861 sin6->sin6_len = sizeof(struct sockaddr_in6); 1862 sin6->sin6_family = AF_INET6; 1863 sin6->sin6_port = sin->sin_port; 1864 sin6->sin6_addr.s6_addr32[0] = 0; 1865 sin6->sin6_addr.s6_addr32[1] = 0; 1866 sin6->sin6_addr.s6_addr32[2] = IPV6_ADDR_INT32_SMP; 1867 sin6->sin6_addr.s6_addr32[3] = sin->sin_addr.s_addr; 1868 } 1869 1870 /* Convert sockaddr_in6 into sockaddr_in. */ 1871 void 1872 in6_sin6_2_sin_in_sock(struct sockaddr *nam) 1873 { 1874 struct sockaddr_in *sin_p; 1875 struct sockaddr_in6 sin6; 1876 1877 /* 1878 * Save original sockaddr_in6 addr and convert it 1879 * to sockaddr_in. 1880 */ 1881 sin6 = *(struct sockaddr_in6 *)nam; 1882 sin_p = (struct sockaddr_in *)nam; 1883 in6_sin6_2_sin(sin_p, &sin6); 1884 } 1885 1886 /* Convert sockaddr_in into sockaddr_in6 in v4 mapped addr format. */ 1887 void 1888 in6_sin_2_v4mapsin6_in_sock(struct sockaddr **nam) 1889 { 1890 struct sockaddr_in *sin_p; 1891 struct sockaddr_in6 *sin6_p; 1892 1893 MALLOC(sin6_p, struct sockaddr_in6 *, sizeof *sin6_p, M_SONAME, 1894 M_WAITOK); 1895 sin_p = (struct sockaddr_in *)*nam; 1896 in6_sin_2_v4mapsin6(sin_p, sin6_p); 1897 FREE(*nam, M_SONAME); 1898 *nam = (struct sockaddr *)sin6_p; 1899 } 1900