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