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