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