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