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