1 /* $OpenBSD: in.c,v 1.170 2020/05/27 11:19:28 mpi 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/if_var.h> 72 #include <net/route.h> 73 74 #include <netinet/in.h> 75 #include <netinet/in_var.h> 76 #include <netinet/igmp_var.h> 77 78 #ifdef MROUTING 79 #include <netinet/ip_mroute.h> 80 #endif 81 82 #include "ether.h" 83 84 85 void in_socktrim(struct sockaddr_in *); 86 87 int in_ioctl_set_ifaddr(u_long, caddr_t, struct ifnet *, int); 88 int in_ioctl_change_ifaddr(u_long, caddr_t, struct ifnet *, int); 89 int in_ioctl_get(u_long, caddr_t, struct ifnet *); 90 void in_purgeaddr(struct ifaddr *); 91 int in_addhost(struct in_ifaddr *, struct sockaddr_in *); 92 int in_scrubhost(struct in_ifaddr *, struct sockaddr_in *); 93 int in_insert_prefix(struct in_ifaddr *); 94 void in_remove_prefix(struct in_ifaddr *); 95 96 /* 97 * Determine whether an IP address is in a reserved set of addresses 98 * that may not be forwarded, or whether datagrams to that destination 99 * may be forwarded. 100 */ 101 int 102 in_canforward(struct in_addr in) 103 { 104 u_int32_t net; 105 106 if (IN_EXPERIMENTAL(in.s_addr) || IN_MULTICAST(in.s_addr)) 107 return (0); 108 if (IN_CLASSA(in.s_addr)) { 109 net = in.s_addr & IN_CLASSA_NET; 110 if (net == 0 || 111 net == htonl(IN_LOOPBACKNET << IN_CLASSA_NSHIFT)) 112 return (0); 113 } 114 return (1); 115 } 116 117 /* 118 * Trim a mask in a sockaddr 119 */ 120 void 121 in_socktrim(struct sockaddr_in *ap) 122 { 123 char *cplim = (char *) &ap->sin_addr; 124 char *cp = (char *) (&ap->sin_addr + 1); 125 126 ap->sin_len = 0; 127 while (--cp >= cplim) 128 if (*cp) { 129 (ap)->sin_len = cp - (char *) (ap) + 1; 130 break; 131 } 132 } 133 134 int 135 in_mask2len(struct in_addr *mask) 136 { 137 int x, y; 138 u_char *p; 139 140 p = (u_char *)mask; 141 for (x = 0; x < sizeof(*mask); x++) { 142 if (p[x] != 0xff) 143 break; 144 } 145 y = 0; 146 if (x < sizeof(*mask)) { 147 for (y = 0; y < 8; y++) { 148 if ((p[x] & (0x80 >> y)) == 0) 149 break; 150 } 151 } 152 return x * 8 + y; 153 } 154 155 void 156 in_len2mask(struct in_addr *mask, int len) 157 { 158 int i; 159 u_char *p; 160 161 p = (u_char *)mask; 162 bzero(mask, sizeof(*mask)); 163 for (i = 0; i < len / 8; i++) 164 p[i] = 0xff; 165 if (len % 8) 166 p[i] = (0xff00 >> (len % 8)) & 0xff; 167 } 168 169 int 170 in_nam2sin(const struct mbuf *nam, struct sockaddr_in **sin) 171 { 172 struct sockaddr *sa = mtod(nam, struct sockaddr *); 173 174 if (nam->m_len < offsetof(struct sockaddr, sa_data)) 175 return EINVAL; 176 if (sa->sa_family != AF_INET) 177 return EAFNOSUPPORT; 178 if (sa->sa_len != nam->m_len) 179 return EINVAL; 180 if (sa->sa_len != sizeof(struct sockaddr_in)) 181 return EINVAL; 182 *sin = satosin(sa); 183 184 return 0; 185 } 186 187 int 188 in_sa2sin(struct sockaddr *sa, struct sockaddr_in **sin) 189 { 190 if (sa->sa_family != AF_INET) 191 return EAFNOSUPPORT; 192 if (sa->sa_len != sizeof(struct sockaddr_in)) 193 return EINVAL; 194 *sin = satosin(sa); 195 196 return 0; 197 } 198 199 int 200 in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp) 201 { 202 int privileged; 203 int error; 204 205 privileged = 0; 206 if ((so->so_state & SS_PRIV) != 0) 207 privileged++; 208 209 switch (cmd) { 210 #ifdef MROUTING 211 case SIOCGETVIFCNT: 212 case SIOCGETSGCNT: 213 error = mrt_ioctl(so, cmd, data); 214 break; 215 #endif /* MROUTING */ 216 default: 217 error = in_ioctl(cmd, data, ifp, privileged); 218 break; 219 } 220 221 return error; 222 } 223 224 int 225 in_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, int privileged) 226 { 227 struct ifreq *ifr = (struct ifreq *)data; 228 struct ifaddr *ifa; 229 struct in_ifaddr *ia = NULL; 230 struct sockaddr_in *sin = NULL, oldaddr; 231 int error = 0; 232 233 if (ifp == NULL) 234 return (ENXIO); 235 236 switch (cmd) { 237 case SIOCGIFADDR: 238 case SIOCGIFNETMASK: 239 case SIOCGIFDSTADDR: 240 case SIOCGIFBRDADDR: 241 return in_ioctl_get(cmd, data, ifp); 242 case SIOCSIFADDR: 243 return in_ioctl_set_ifaddr(cmd, data, ifp, privileged); 244 case SIOCAIFADDR: 245 case SIOCDIFADDR: 246 return in_ioctl_change_ifaddr(cmd, data, ifp, privileged); 247 case SIOCSIFNETMASK: 248 case SIOCSIFDSTADDR: 249 case SIOCSIFBRDADDR: 250 break; 251 default: 252 return (EOPNOTSUPP); 253 } 254 255 if (ifr->ifr_addr.sa_family == AF_INET) { 256 error = in_sa2sin(&ifr->ifr_addr, &sin); 257 if (error) 258 return (error); 259 } 260 261 NET_LOCK(); 262 263 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 264 if (ifa->ifa_addr->sa_family != AF_INET) 265 continue; 266 /* find first address or exact match */ 267 if (ia == NULL) 268 ia = ifatoia(ifa); 269 if (sin == NULL || sin->sin_addr.s_addr == INADDR_ANY) 270 break; 271 if (ifatoia(ifa)->ia_addr.sin_addr.s_addr == 272 sin->sin_addr.s_addr) { 273 ia = ifatoia(ifa); 274 break; 275 } 276 } 277 if (ia == NULL) { 278 error = EADDRNOTAVAIL; 279 goto err; 280 } 281 282 switch (cmd) { 283 case SIOCSIFDSTADDR: 284 if (!privileged) { 285 error = EPERM; 286 break; 287 } 288 289 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) { 290 error = EINVAL; 291 break; 292 } 293 error = in_sa2sin(&ifr->ifr_dstaddr, &sin); 294 if (error) 295 break; 296 oldaddr = ia->ia_dstaddr; 297 ia->ia_dstaddr = *sin; 298 error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, (caddr_t)ia); 299 if (error) { 300 ia->ia_dstaddr = oldaddr; 301 break; 302 } 303 in_scrubhost(ia, &oldaddr); 304 in_addhost(ia, &ia->ia_dstaddr); 305 break; 306 307 case SIOCSIFBRDADDR: 308 if (!privileged) { 309 error = EPERM; 310 break; 311 } 312 313 if ((ifp->if_flags & IFF_BROADCAST) == 0) { 314 error = EINVAL; 315 break; 316 } 317 error = in_sa2sin(&ifr->ifr_broadaddr, &sin); 318 if (error) 319 break; 320 ifa_update_broadaddr(ifp, &ia->ia_ifa, sintosa(sin)); 321 break; 322 323 case SIOCSIFNETMASK: 324 if (!privileged) { 325 error = EPERM; 326 break; 327 } 328 329 if (ifr->ifr_addr.sa_len < 8) { 330 error = EINVAL; 331 break; 332 } 333 /* do not check inet family or strict len */ 334 sin = satosin(&ifr->ifr_addr); 335 if (ntohl(sin->sin_addr.s_addr) & 336 (~ntohl(sin->sin_addr.s_addr) >> 1)) { 337 /* non-contiguous netmask */ 338 error = EINVAL; 339 break; 340 } 341 ia->ia_netmask = ia->ia_sockmask.sin_addr.s_addr = 342 sin->sin_addr.s_addr; 343 break; 344 } 345 err: 346 NET_UNLOCK(); 347 return (error); 348 } 349 350 int 351 in_ioctl_set_ifaddr(u_long cmd, caddr_t data, struct ifnet *ifp, 352 int privileged) 353 { 354 struct ifreq *ifr = (struct ifreq *)data; 355 struct ifaddr *ifa; 356 struct in_ifaddr *ia = NULL; 357 struct sockaddr_in *sin; 358 int error = 0; 359 int newifaddr; 360 361 if (cmd != SIOCSIFADDR) 362 panic("%s: invalid ioctl %lu", __func__, cmd); 363 364 if (!privileged) 365 return (EPERM); 366 367 error = in_sa2sin(&ifr->ifr_addr, &sin); 368 if (error) 369 return (error); 370 371 NET_LOCK(); 372 373 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 374 if (ifa->ifa_addr->sa_family != AF_INET) 375 continue; 376 /* find first address */ 377 ia = ifatoia(ifa); 378 break; 379 } 380 if (ia == NULL) { 381 ia = malloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO); 382 ia->ia_addr.sin_family = AF_INET; 383 ia->ia_addr.sin_len = sizeof(ia->ia_addr); 384 ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr); 385 ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr); 386 ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask); 387 ia->ia_sockmask.sin_len = 8; 388 if (ifp->if_flags & IFF_BROADCAST) { 389 ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr); 390 ia->ia_broadaddr.sin_family = AF_INET; 391 } 392 ia->ia_ifp = ifp; 393 394 newifaddr = 1; 395 } else 396 newifaddr = 0; 397 398 in_ifscrub(ifp, ia); 399 error = in_ifinit(ifp, ia, sin, newifaddr); 400 if (!error) 401 if_addrhooks_run(ifp); 402 403 NET_UNLOCK(); 404 return error; 405 } 406 407 int 408 in_ioctl_change_ifaddr(u_long cmd, caddr_t data, struct ifnet *ifp, 409 int privileged) 410 { 411 struct ifaddr *ifa; 412 struct in_ifaddr *ia = NULL; 413 struct in_aliasreq *ifra = (struct in_aliasreq *)data; 414 struct sockaddr_in *sin = NULL, *dstsin = NULL, *broadsin = NULL; 415 struct sockaddr_in *masksin = NULL; 416 int error = 0; 417 int newifaddr; 418 419 if (ifra->ifra_addr.sin_family == AF_INET) { 420 error = in_sa2sin(sintosa(&ifra->ifra_addr), &sin); 421 if (error) 422 return (error); 423 } 424 425 NET_LOCK(); 426 427 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 428 if (ifa->ifa_addr->sa_family != AF_INET) 429 continue; 430 /* find first address, if no exact match wanted */ 431 if (sin == NULL || sin->sin_addr.s_addr == 432 ifatoia(ifa)->ia_addr.sin_addr.s_addr) { 433 ia = ifatoia(ifa); 434 break; 435 } 436 } 437 438 switch (cmd) { 439 case SIOCAIFADDR: { 440 int needinit = 0; 441 442 if (!privileged) { 443 error = EPERM; 444 break; 445 } 446 447 if (ifra->ifra_mask.sin_len) { 448 if (ifra->ifra_mask.sin_len < 8) { 449 error = EINVAL; 450 break; 451 } 452 /* do not check inet family or strict len */ 453 masksin = &ifra->ifra_mask; 454 if (ntohl(masksin->sin_addr.s_addr) & 455 (~ntohl(masksin->sin_addr.s_addr) >> 1)) { 456 /* non-contiguous netmask */ 457 error = EINVAL; 458 break; 459 } 460 } 461 if ((ifp->if_flags & IFF_POINTOPOINT) && 462 ifra->ifra_dstaddr.sin_family == AF_INET) { 463 error = in_sa2sin(sintosa(&ifra->ifra_dstaddr), 464 &dstsin); 465 if (error) 466 break; 467 } 468 if ((ifp->if_flags & IFF_BROADCAST) && 469 ifra->ifra_broadaddr.sin_family == AF_INET) { 470 error = in_sa2sin(sintosa(&ifra->ifra_broadaddr), 471 &broadsin); 472 if (error) 473 break; 474 } 475 476 if (ia == NULL) { 477 ia = malloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO); 478 ia->ia_addr.sin_family = AF_INET; 479 ia->ia_addr.sin_len = sizeof(ia->ia_addr); 480 ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr); 481 ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr); 482 ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask); 483 ia->ia_sockmask.sin_len = 8; 484 if (ifp->if_flags & IFF_BROADCAST) { 485 ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr); 486 ia->ia_broadaddr.sin_family = AF_INET; 487 } 488 ia->ia_ifp = ifp; 489 490 newifaddr = 1; 491 } else 492 newifaddr = 0; 493 494 if (sin == NULL) { 495 sin = &ia->ia_addr; 496 } else if (newifaddr || 497 sin->sin_addr.s_addr != ia->ia_addr.sin_addr.s_addr) { 498 needinit = 1; 499 } 500 if (masksin != NULL) { 501 in_ifscrub(ifp, ia); 502 ia->ia_netmask = ia->ia_sockmask.sin_addr.s_addr = 503 masksin->sin_addr.s_addr; 504 needinit = 1; 505 } 506 if (dstsin != NULL) { 507 in_ifscrub(ifp, ia); 508 ia->ia_dstaddr = *dstsin; 509 needinit = 1; 510 } 511 if (broadsin != NULL) { 512 if (newifaddr) 513 ia->ia_broadaddr = *broadsin; 514 else 515 ifa_update_broadaddr(ifp, &ia->ia_ifa, 516 sintosa(broadsin)); 517 } 518 if (needinit) { 519 error = in_ifinit(ifp, ia, sin, newifaddr); 520 if (error) 521 break; 522 } 523 if_addrhooks_run(ifp); 524 break; 525 } 526 case SIOCDIFADDR: 527 if (!privileged) { 528 error = EPERM; 529 break; 530 } 531 532 if (ia == NULL) { 533 error = EADDRNOTAVAIL; 534 break; 535 } 536 /* 537 * Even if the individual steps were safe, shouldn't 538 * these kinds of changes happen atomically? What 539 * should happen to a packet that was routed after 540 * the scrub but before the other steps? 541 */ 542 in_purgeaddr(&ia->ia_ifa); 543 if_addrhooks_run(ifp); 544 break; 545 546 default: 547 panic("%s: invalid ioctl %lu", __func__, cmd); 548 } 549 550 NET_UNLOCK(); 551 return (error); 552 } 553 554 int 555 in_ioctl_get(u_long cmd, caddr_t data, struct ifnet *ifp) 556 { 557 struct ifreq *ifr = (struct ifreq *)data; 558 struct ifaddr *ifa; 559 struct in_ifaddr *ia = NULL; 560 struct sockaddr *sa; 561 struct sockaddr_in *sin = NULL; 562 int error = 0; 563 564 sa = &ifr->ifr_addr; 565 if (sa->sa_family == AF_INET) { 566 sa->sa_len = sizeof(struct sockaddr_in); 567 error = in_sa2sin(sa, &sin); 568 if (error) 569 return (error); 570 } 571 572 NET_RLOCK_IN_IOCTL(); 573 574 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 575 if (ifa->ifa_addr->sa_family != AF_INET) 576 continue; 577 /* find first address or exact match */ 578 if (ia == NULL) 579 ia = ifatoia(ifa); 580 if (sin == NULL || sin->sin_addr.s_addr == INADDR_ANY) 581 break; 582 if (ifatoia(ifa)->ia_addr.sin_addr.s_addr == 583 sin->sin_addr.s_addr) { 584 ia = ifatoia(ifa); 585 break; 586 } 587 } 588 if (ia == NULL) { 589 error = EADDRNOTAVAIL; 590 goto err; 591 } 592 593 switch(cmd) { 594 case SIOCGIFADDR: 595 *satosin(&ifr->ifr_addr) = ia->ia_addr; 596 break; 597 598 case SIOCGIFBRDADDR: 599 if ((ifp->if_flags & IFF_BROADCAST) == 0) { 600 error = EINVAL; 601 break; 602 } 603 *satosin(&ifr->ifr_dstaddr) = ia->ia_broadaddr; 604 break; 605 606 case SIOCGIFDSTADDR: 607 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) { 608 error = EINVAL; 609 break; 610 } 611 *satosin(&ifr->ifr_dstaddr) = ia->ia_dstaddr; 612 break; 613 614 case SIOCGIFNETMASK: 615 *satosin(&ifr->ifr_addr) = ia->ia_sockmask; 616 break; 617 618 default: 619 panic("%s: invalid ioctl %lu", __func__, cmd); 620 } 621 622 err: 623 NET_RUNLOCK_IN_IOCTL(); 624 return (error); 625 } 626 627 /* 628 * Delete any existing route for an interface. 629 */ 630 void 631 in_ifscrub(struct ifnet *ifp, struct in_ifaddr *ia) 632 { 633 if (ISSET(ifp->if_flags, IFF_POINTOPOINT)) 634 in_scrubhost(ia, &ia->ia_dstaddr); 635 else if (!ISSET(ifp->if_flags, IFF_LOOPBACK)) 636 in_remove_prefix(ia); 637 } 638 639 /* 640 * Initialize an interface's internet address 641 * and routing table entry. 642 */ 643 int 644 in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, 645 int newaddr) 646 { 647 u_int32_t i = sin->sin_addr.s_addr; 648 struct sockaddr_in oldaddr; 649 int error = 0, rterror; 650 651 NET_ASSERT_LOCKED(); 652 653 /* 654 * Always remove the address from the tree to make sure its 655 * position gets updated in case the key changes. 656 */ 657 if (!newaddr) { 658 rt_ifa_dellocal(&ia->ia_ifa); 659 ifa_del(ifp, &ia->ia_ifa); 660 } 661 oldaddr = ia->ia_addr; 662 ia->ia_addr = *sin; 663 664 if (ia->ia_netmask == 0) { 665 if (IN_CLASSA(i)) 666 ia->ia_netmask = IN_CLASSA_NET; 667 else if (IN_CLASSB(i)) 668 ia->ia_netmask = IN_CLASSB_NET; 669 else 670 ia->ia_netmask = IN_CLASSC_NET; 671 ia->ia_sockmask.sin_addr.s_addr = ia->ia_netmask; 672 } 673 674 /* 675 * Give the interface a chance to initialize 676 * if this is its first address, 677 * and to validate the address if necessary. 678 */ 679 if ((error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) { 680 ia->ia_addr = oldaddr; 681 } 682 683 /* 684 * Add the address to the local list and the global tree. If an 685 * error occured, put back the original address. 686 */ 687 ifa_add(ifp, &ia->ia_ifa); 688 rterror = rt_ifa_addlocal(&ia->ia_ifa); 689 690 if (rterror) { 691 if (!newaddr) 692 ifa_del(ifp, &ia->ia_ifa); 693 if (!error) 694 error = rterror; 695 goto out; 696 } 697 if (error) 698 goto out; 699 700 701 ia->ia_net = i & ia->ia_netmask; 702 in_socktrim(&ia->ia_sockmask); 703 /* 704 * Add route for the network. 705 */ 706 ia->ia_ifa.ifa_metric = ifp->if_metric; 707 if (ISSET(ifp->if_flags, IFF_BROADCAST)) { 708 if (IN_RFC3021_SUBNET(ia->ia_netmask)) 709 ia->ia_broadaddr.sin_addr.s_addr = 0; 710 else { 711 ia->ia_broadaddr.sin_addr.s_addr = 712 ia->ia_net | ~ia->ia_netmask; 713 } 714 } 715 716 if (ISSET(ifp->if_flags, IFF_POINTOPOINT)) { 717 /* XXX We should not even call in_ifinit() in this case. */ 718 if (ia->ia_dstaddr.sin_family != AF_INET) 719 goto out; 720 error = in_addhost(ia, &ia->ia_dstaddr); 721 } else if (!ISSET(ifp->if_flags, IFF_LOOPBACK)) { 722 error = in_insert_prefix(ia); 723 } 724 725 /* 726 * If the interface supports multicast, join the "all hosts" 727 * multicast group on that interface. 728 */ 729 if ((ifp->if_flags & IFF_MULTICAST) && ia->ia_allhosts == NULL) { 730 struct in_addr addr; 731 732 addr.s_addr = INADDR_ALLHOSTS_GROUP; 733 ia->ia_allhosts = in_addmulti(&addr, ifp); 734 } 735 736 out: 737 if (error && newaddr) 738 in_purgeaddr(&ia->ia_ifa); 739 740 return (error); 741 } 742 743 void 744 in_purgeaddr(struct ifaddr *ifa) 745 { 746 struct ifnet *ifp = ifa->ifa_ifp; 747 struct in_ifaddr *ia = ifatoia(ifa); 748 extern int ifatrash; 749 750 NET_ASSERT_LOCKED(); 751 752 in_ifscrub(ifp, ia); 753 754 rt_ifa_dellocal(&ia->ia_ifa); 755 rt_ifa_purge(&ia->ia_ifa); 756 ifa_del(ifp, &ia->ia_ifa); 757 758 if (ia->ia_allhosts != NULL) { 759 in_delmulti(ia->ia_allhosts); 760 ia->ia_allhosts = NULL; 761 } 762 763 ifatrash++; 764 ia->ia_ifp = NULL; 765 ifafree(&ia->ia_ifa); 766 } 767 768 int 769 in_addhost(struct in_ifaddr *ia, struct sockaddr_in *dst) 770 { 771 return rt_ifa_add(&ia->ia_ifa, RTF_HOST | RTF_MPATH, 772 sintosa(dst), ia->ia_ifa.ifa_ifp->if_rdomain); 773 } 774 775 int 776 in_scrubhost(struct in_ifaddr *ia, struct sockaddr_in *dst) 777 { 778 return rt_ifa_del(&ia->ia_ifa, RTF_HOST, 779 sintosa(dst), ia->ia_ifa.ifa_ifp->if_rdomain); 780 } 781 782 /* 783 * Insert the cloning and broadcast routes for this subnet. 784 */ 785 int 786 in_insert_prefix(struct in_ifaddr *ia) 787 { 788 struct ifaddr *ifa = &ia->ia_ifa; 789 int error; 790 791 error = rt_ifa_add(ifa, RTF_CLONING | RTF_CONNECTED | RTF_MPATH, 792 ifa->ifa_addr, ifa->ifa_ifp->if_rdomain); 793 if (error) 794 return (error); 795 796 if (ia->ia_broadaddr.sin_addr.s_addr != 0) { 797 error = rt_ifa_add(ifa, RTF_HOST | RTF_BROADCAST | RTF_MPATH, 798 ifa->ifa_broadaddr, ifa->ifa_ifp->if_rdomain); 799 } 800 801 return (error); 802 } 803 804 void 805 in_remove_prefix(struct in_ifaddr *ia) 806 { 807 struct ifaddr *ifa = &ia->ia_ifa; 808 809 rt_ifa_del(ifa, RTF_CLONING | RTF_CONNECTED, 810 ifa->ifa_addr, ifa->ifa_ifp->if_rdomain); 811 812 if (ia->ia_broadaddr.sin_addr.s_addr != 0) { 813 rt_ifa_del(ifa, RTF_HOST | RTF_BROADCAST, 814 ifa->ifa_broadaddr, ifa->ifa_ifp->if_rdomain); 815 } 816 } 817 818 /* 819 * Return 1 if the address is a local broadcast address. 820 */ 821 int 822 in_broadcast(struct in_addr in, u_int rtableid) 823 { 824 struct ifnet *ifn; 825 struct ifaddr *ifa; 826 u_int rdomain; 827 828 rdomain = rtable_l2(rtableid); 829 830 #define ia (ifatoia(ifa)) 831 TAILQ_FOREACH(ifn, &ifnet, if_list) { 832 if (ifn->if_rdomain != rdomain) 833 continue; 834 if ((ifn->if_flags & IFF_BROADCAST) == 0) 835 continue; 836 TAILQ_FOREACH(ifa, &ifn->if_addrlist, ifa_list) 837 if (ifa->ifa_addr->sa_family == AF_INET && 838 in.s_addr != ia->ia_addr.sin_addr.s_addr && 839 in.s_addr == ia->ia_broadaddr.sin_addr.s_addr) 840 return 1; 841 } 842 return (0); 843 #undef ia 844 } 845 846 /* 847 * Add an address to the list of IP multicast addresses for a given interface. 848 */ 849 struct in_multi * 850 in_addmulti(struct in_addr *ap, struct ifnet *ifp) 851 { 852 struct in_multi *inm; 853 struct ifreq ifr; 854 855 /* 856 * See if address already in list. 857 */ 858 IN_LOOKUP_MULTI(*ap, ifp, inm); 859 if (inm != NULL) { 860 /* 861 * Found it; just increment the reference count. 862 */ 863 ++inm->inm_refcnt; 864 } else { 865 /* 866 * New address; allocate a new multicast record 867 * and link it into the interface's multicast list. 868 */ 869 inm = malloc(sizeof(*inm), M_IPMADDR, M_NOWAIT | M_ZERO); 870 if (inm == NULL) 871 return (NULL); 872 873 inm->inm_sin.sin_len = sizeof(struct sockaddr_in); 874 inm->inm_sin.sin_family = AF_INET; 875 inm->inm_sin.sin_addr = *ap; 876 inm->inm_refcnt = 1; 877 inm->inm_ifidx = ifp->if_index; 878 inm->inm_ifma.ifma_addr = sintosa(&inm->inm_sin); 879 880 /* 881 * Ask the network driver to update its multicast reception 882 * filter appropriately for the new address. 883 */ 884 memset(&ifr, 0, sizeof(ifr)); 885 memcpy(&ifr.ifr_addr, &inm->inm_sin, sizeof(inm->inm_sin)); 886 if ((*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) { 887 free(inm, M_IPMADDR, sizeof(*inm)); 888 return (NULL); 889 } 890 891 TAILQ_INSERT_HEAD(&ifp->if_maddrlist, &inm->inm_ifma, 892 ifma_list); 893 894 /* 895 * Let IGMP know that we have joined a new IP multicast group. 896 */ 897 igmp_joingroup(inm); 898 } 899 900 return (inm); 901 } 902 903 /* 904 * Delete a multicast address record. 905 */ 906 void 907 in_delmulti(struct in_multi *inm) 908 { 909 struct ifreq ifr; 910 struct ifnet *ifp; 911 912 NET_ASSERT_LOCKED(); 913 914 if (--inm->inm_refcnt == 0) { 915 /* 916 * No remaining claims to this record; let IGMP know that 917 * we are leaving the multicast group. 918 */ 919 igmp_leavegroup(inm); 920 ifp = if_get(inm->inm_ifidx); 921 922 /* 923 * Notify the network driver to update its multicast 924 * reception filter. 925 */ 926 if (ifp != NULL) { 927 memset(&ifr, 0, sizeof(ifr)); 928 satosin(&ifr.ifr_addr)->sin_len = 929 sizeof(struct sockaddr_in); 930 satosin(&ifr.ifr_addr)->sin_family = AF_INET; 931 satosin(&ifr.ifr_addr)->sin_addr = inm->inm_addr; 932 KERNEL_LOCK(); 933 (*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr); 934 KERNEL_UNLOCK(); 935 936 TAILQ_REMOVE(&ifp->if_maddrlist, &inm->inm_ifma, 937 ifma_list); 938 } 939 if_put(ifp); 940 941 free(inm, M_IPMADDR, sizeof(*inm)); 942 } 943 } 944 945 /* 946 * Return 1 if the multicast group represented by ``ap'' has been 947 * joined by interface ``ifp'', 0 otherwise. 948 */ 949 int 950 in_hasmulti(struct in_addr *ap, struct ifnet *ifp) 951 { 952 struct in_multi *inm; 953 int joined; 954 955 IN_LOOKUP_MULTI(*ap, ifp, inm); 956 joined = (inm != NULL); 957 958 return (joined); 959 } 960 961 void 962 in_ifdetach(struct ifnet *ifp) 963 { 964 struct ifaddr *ifa, *next; 965 966 /* nuke any of IPv4 addresses we have */ 967 TAILQ_FOREACH_SAFE(ifa, &ifp->if_addrlist, ifa_list, next) { 968 if (ifa->ifa_addr->sa_family != AF_INET) 969 continue; 970 in_purgeaddr(ifa); 971 if_addrhooks_run(ifp); 972 } 973 974 if (ifp->if_xflags & IFXF_AUTOCONF4) 975 ifp->if_xflags &= ~IFXF_AUTOCONF4; 976 } 977 978 void 979 in_prefixlen2mask(struct in_addr *maskp, int plen) 980 { 981 if (plen == 0) 982 maskp->s_addr = 0; 983 else 984 maskp->s_addr = htonl(0xffffffff << (32 - plen)); 985 } 986