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