1 /* 2 * Copyright (c) 1982, 1986, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)in.c 8.4 (Berkeley) 1/9/95 34 * $FreeBSD$ 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/sockio.h> 40 #include <sys/malloc.h> 41 #include <sys/socket.h> 42 #include <sys/kernel.h> 43 #include <sys/sysctl.h> 44 45 #include <net/if.h> 46 #include <net/if_types.h> 47 #include <net/route.h> 48 49 #include <netinet/in.h> 50 #include <netinet/in_var.h> 51 52 #include <netinet/igmp_var.h> 53 54 #include "gif.h" 55 #if NGIF > 0 56 #include <net/if_gif.h> 57 #endif 58 59 static MALLOC_DEFINE(M_IPMADDR, "in_multi", "internet multicast address"); 60 61 static int in_mask2len __P((struct in_addr *)); 62 static void in_len2mask __P((struct in_addr *, int)); 63 static int in_lifaddr_ioctl __P((struct socket *, u_long, caddr_t, 64 struct ifnet *, struct proc *)); 65 66 static void in_socktrim __P((struct sockaddr_in *)); 67 static int in_ifinit __P((struct ifnet *, 68 struct in_ifaddr *, struct sockaddr_in *, int)); 69 70 static int subnetsarelocal = 0; 71 SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW, 72 &subnetsarelocal, 0, ""); 73 74 struct in_multihead in_multihead; /* XXX BSS initialization */ 75 76 /* 77 * Return 1 if an internet address is for a ``local'' host 78 * (one to which we have a connection). If subnetsarelocal 79 * is true, this includes other subnets of the local net. 80 * Otherwise, it includes only the directly-connected (sub)nets. 81 */ 82 int 83 in_localaddr(in) 84 struct in_addr in; 85 { 86 register u_long i = ntohl(in.s_addr); 87 register struct in_ifaddr *ia; 88 89 if (subnetsarelocal) { 90 for (ia = TAILQ_FIRST(&in_ifaddrhead); ia; 91 ia = TAILQ_NEXT(ia, ia_link)) 92 if ((i & ia->ia_netmask) == ia->ia_net) 93 return (1); 94 } else { 95 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) 96 if ((i & ia->ia_subnetmask) == ia->ia_subnet) 97 return (1); 98 } 99 return (0); 100 } 101 102 /* 103 * Determine whether an IP address is in a reserved set of addresses 104 * that may not be forwarded, or whether datagrams to that destination 105 * may be forwarded. 106 */ 107 int 108 in_canforward(in) 109 struct in_addr in; 110 { 111 register u_long i = ntohl(in.s_addr); 112 register u_long net; 113 114 if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i)) 115 return (0); 116 if (IN_CLASSA(i)) { 117 net = i & IN_CLASSA_NET; 118 if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT)) 119 return (0); 120 } 121 return (1); 122 } 123 124 /* 125 * Trim a mask in a sockaddr 126 */ 127 static void 128 in_socktrim(ap) 129 struct sockaddr_in *ap; 130 { 131 register char *cplim = (char *) &ap->sin_addr; 132 register char *cp = (char *) (&ap->sin_addr + 1); 133 134 ap->sin_len = 0; 135 while (--cp >= cplim) 136 if (*cp) { 137 (ap)->sin_len = cp - (char *) (ap) + 1; 138 break; 139 } 140 } 141 142 static int 143 in_mask2len(mask) 144 struct in_addr *mask; 145 { 146 int x, y; 147 u_char *p; 148 149 p = (u_char *)mask; 150 for (x = 0; x < sizeof(*mask); x++) { 151 if (p[x] != 0xff) 152 break; 153 } 154 y = 0; 155 if (x < sizeof(*mask)) { 156 for (y = 0; y < 8; y++) { 157 if ((p[x] & (0x80 >> y)) == 0) 158 break; 159 } 160 } 161 return x * 8 + y; 162 } 163 164 static void 165 in_len2mask(mask, len) 166 struct in_addr *mask; 167 int len; 168 { 169 int i; 170 u_char *p; 171 172 p = (u_char *)mask; 173 bzero(mask, sizeof(*mask)); 174 for (i = 0; i < len / 8; i++) 175 p[i] = 0xff; 176 if (len % 8) 177 p[i] = (0xff00 >> (len % 8)) & 0xff; 178 } 179 180 static int in_interfaces; /* number of external internet interfaces */ 181 182 /* 183 * Generic internet control operations (ioctl's). 184 * Ifp is 0 if not an interface-specific ioctl. 185 */ 186 /* ARGSUSED */ 187 int 188 in_control(so, cmd, data, ifp, p) 189 struct socket *so; 190 u_long cmd; 191 caddr_t data; 192 register struct ifnet *ifp; 193 struct proc *p; 194 { 195 register struct ifreq *ifr = (struct ifreq *)data; 196 register struct in_ifaddr *ia = 0, *iap; 197 register struct ifaddr *ifa; 198 struct in_ifaddr *oia; 199 struct in_aliasreq *ifra = (struct in_aliasreq *)data; 200 struct sockaddr_in oldaddr; 201 int error, hostIsNew, maskIsNew, s; 202 u_long i; 203 204 #if NGIF > 0 205 if (ifp && ifp->if_type == IFT_GIF) { 206 switch (cmd) { 207 case SIOCSIFPHYADDR: 208 case SIOCDIFPHYADDR: 209 if (p && 210 (error = suser(p)) != 0) 211 return(error); 212 case SIOCGIFPSRCADDR: 213 case SIOCGIFPDSTADDR: 214 return gif_ioctl(ifp, cmd, data); 215 } 216 } 217 #endif 218 219 switch (cmd) { 220 case SIOCALIFADDR: 221 case SIOCDLIFADDR: 222 if (p && (error = suser(p)) != 0) 223 return error; 224 /*fall through*/ 225 case SIOCGLIFADDR: 226 if (!ifp) 227 return EINVAL; 228 return in_lifaddr_ioctl(so, cmd, data, ifp, p); 229 } 230 231 /* 232 * Find address for this interface, if it exists. 233 * 234 * If an alias address was specified, find that one instead of 235 * the first one on the interface. 236 */ 237 if (ifp) 238 for (iap = TAILQ_FIRST(&in_ifaddrhead); iap; 239 iap = TAILQ_NEXT(iap, ia_link)) 240 if (iap->ia_ifp == ifp) { 241 if (((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr == 242 iap->ia_addr.sin_addr.s_addr) { 243 ia = iap; 244 break; 245 } else if (ia == NULL) { 246 ia = iap; 247 if (ifr->ifr_addr.sa_family != AF_INET) 248 break; 249 } 250 } 251 252 switch (cmd) { 253 254 case SIOCAIFADDR: 255 case SIOCDIFADDR: 256 if (ifp == 0) 257 return (EADDRNOTAVAIL); 258 if (ifra->ifra_addr.sin_family == AF_INET) { 259 for (oia = ia; ia; ia = TAILQ_NEXT(ia, ia_link)) { 260 if (ia->ia_ifp == ifp && 261 ia->ia_addr.sin_addr.s_addr == 262 ifra->ifra_addr.sin_addr.s_addr) 263 break; 264 } 265 if ((ifp->if_flags & IFF_POINTOPOINT) 266 && (cmd == SIOCAIFADDR) 267 && (ifra->ifra_dstaddr.sin_addr.s_addr 268 == INADDR_ANY)) { 269 return EDESTADDRREQ; 270 } 271 } 272 if (cmd == SIOCDIFADDR && ia == 0) 273 return (EADDRNOTAVAIL); 274 /* FALLTHROUGH */ 275 case SIOCSIFADDR: 276 case SIOCSIFNETMASK: 277 case SIOCSIFDSTADDR: 278 if (p && (error = suser(p)) != 0) 279 return error; 280 281 if (ifp == 0) 282 return (EADDRNOTAVAIL); 283 if (ia == (struct in_ifaddr *)0) { 284 ia = (struct in_ifaddr *) 285 malloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO); 286 if (ia == (struct in_ifaddr *)NULL) 287 return (ENOBUFS); 288 /* 289 * Protect from ipintr() traversing address list 290 * while we're modifying it. 291 */ 292 s = splnet(); 293 294 TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_link); 295 ifa = &ia->ia_ifa; 296 TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link); 297 298 ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr; 299 ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr; 300 ifa->ifa_netmask = (struct sockaddr *)&ia->ia_sockmask; 301 ia->ia_sockmask.sin_len = 8; 302 if (ifp->if_flags & IFF_BROADCAST) { 303 ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr); 304 ia->ia_broadaddr.sin_family = AF_INET; 305 } 306 ia->ia_ifp = ifp; 307 if (!(ifp->if_flags & IFF_LOOPBACK)) 308 in_interfaces++; 309 splx(s); 310 } 311 break; 312 313 case SIOCSIFBRDADDR: 314 if (p && (error = suser(p)) != 0) 315 return error; 316 /* FALLTHROUGH */ 317 318 case SIOCGIFADDR: 319 case SIOCGIFNETMASK: 320 case SIOCGIFDSTADDR: 321 case SIOCGIFBRDADDR: 322 if (ia == (struct in_ifaddr *)0) 323 return (EADDRNOTAVAIL); 324 break; 325 } 326 switch (cmd) { 327 328 case SIOCGIFADDR: 329 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr; 330 break; 331 332 case SIOCGIFBRDADDR: 333 if ((ifp->if_flags & IFF_BROADCAST) == 0) 334 return (EINVAL); 335 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_broadaddr; 336 break; 337 338 case SIOCGIFDSTADDR: 339 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 340 return (EINVAL); 341 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr; 342 break; 343 344 case SIOCGIFNETMASK: 345 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask; 346 break; 347 348 case SIOCSIFDSTADDR: 349 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 350 return (EINVAL); 351 oldaddr = ia->ia_dstaddr; 352 ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr; 353 if (ifp->if_ioctl && (error = (*ifp->if_ioctl) 354 (ifp, SIOCSIFDSTADDR, (caddr_t)ia))) { 355 ia->ia_dstaddr = oldaddr; 356 return (error); 357 } 358 if (ia->ia_flags & IFA_ROUTE) { 359 ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr; 360 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 361 ia->ia_ifa.ifa_dstaddr = 362 (struct sockaddr *)&ia->ia_dstaddr; 363 rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); 364 } 365 break; 366 367 case SIOCSIFBRDADDR: 368 if ((ifp->if_flags & IFF_BROADCAST) == 0) 369 return (EINVAL); 370 ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr; 371 break; 372 373 case SIOCSIFADDR: 374 return (in_ifinit(ifp, ia, 375 (struct sockaddr_in *) &ifr->ifr_addr, 1)); 376 377 case SIOCSIFNETMASK: 378 i = ifra->ifra_addr.sin_addr.s_addr; 379 ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr = i); 380 break; 381 382 case SIOCAIFADDR: 383 maskIsNew = 0; 384 hostIsNew = 1; 385 error = 0; 386 if (ia->ia_addr.sin_family == AF_INET) { 387 if (ifra->ifra_addr.sin_len == 0) { 388 ifra->ifra_addr = ia->ia_addr; 389 hostIsNew = 0; 390 } else if (ifra->ifra_addr.sin_addr.s_addr == 391 ia->ia_addr.sin_addr.s_addr) 392 hostIsNew = 0; 393 } 394 if (ifra->ifra_mask.sin_len) { 395 in_ifscrub(ifp, ia); 396 ia->ia_sockmask = ifra->ifra_mask; 397 ia->ia_subnetmask = 398 ntohl(ia->ia_sockmask.sin_addr.s_addr); 399 maskIsNew = 1; 400 } 401 if ((ifp->if_flags & IFF_POINTOPOINT) && 402 (ifra->ifra_dstaddr.sin_family == AF_INET)) { 403 in_ifscrub(ifp, ia); 404 ia->ia_dstaddr = ifra->ifra_dstaddr; 405 maskIsNew = 1; /* We lie; but the effect's the same */ 406 } 407 if (ifra->ifra_addr.sin_family == AF_INET && 408 (hostIsNew || maskIsNew)) 409 error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0); 410 if ((ifp->if_flags & IFF_BROADCAST) && 411 (ifra->ifra_broadaddr.sin_family == AF_INET)) 412 ia->ia_broadaddr = ifra->ifra_broadaddr; 413 return (error); 414 415 case SIOCDIFADDR: 416 in_ifscrub(ifp, ia); 417 /* 418 * Protect from ipintr() traversing address list 419 * while we're modifying it. 420 */ 421 s = splnet(); 422 423 ifa = &ia->ia_ifa; 424 TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); 425 oia = ia; 426 TAILQ_REMOVE(&in_ifaddrhead, oia, ia_link); 427 IFAFREE(&oia->ia_ifa); 428 splx(s); 429 break; 430 431 default: 432 if (ifp == 0 || ifp->if_ioctl == 0) 433 return (EOPNOTSUPP); 434 return ((*ifp->if_ioctl)(ifp, cmd, data)); 435 } 436 return (0); 437 } 438 439 /* 440 * SIOC[GAD]LIFADDR. 441 * SIOCGLIFADDR: get first address. (?!?) 442 * SIOCGLIFADDR with IFLR_PREFIX: 443 * get first address that matches the specified prefix. 444 * SIOCALIFADDR: add the specified address. 445 * SIOCALIFADDR with IFLR_PREFIX: 446 * EINVAL since we can't deduce hostid part of the address. 447 * SIOCDLIFADDR: delete the specified address. 448 * SIOCDLIFADDR with IFLR_PREFIX: 449 * delete the first address that matches the specified prefix. 450 * return values: 451 * EINVAL on invalid parameters 452 * EADDRNOTAVAIL on prefix match failed/specified address not found 453 * other values may be returned from in_ioctl() 454 */ 455 static int 456 in_lifaddr_ioctl(so, cmd, data, ifp, p) 457 struct socket *so; 458 u_long cmd; 459 caddr_t data; 460 struct ifnet *ifp; 461 struct proc *p; 462 { 463 struct if_laddrreq *iflr = (struct if_laddrreq *)data; 464 struct ifaddr *ifa; 465 466 /* sanity checks */ 467 if (!data || !ifp) { 468 panic("invalid argument to in_lifaddr_ioctl"); 469 /*NOTRECHED*/ 470 } 471 472 switch (cmd) { 473 case SIOCGLIFADDR: 474 /* address must be specified on GET with IFLR_PREFIX */ 475 if ((iflr->flags & IFLR_PREFIX) == 0) 476 break; 477 /*FALLTHROUGH*/ 478 case SIOCALIFADDR: 479 case SIOCDLIFADDR: 480 /* address must be specified on ADD and DELETE */ 481 if (iflr->addr.ss_family != AF_INET) 482 return EINVAL; 483 if (iflr->addr.ss_len != sizeof(struct sockaddr_in)) 484 return EINVAL; 485 /* XXX need improvement */ 486 if (iflr->dstaddr.ss_family 487 && iflr->dstaddr.ss_family != AF_INET) 488 return EINVAL; 489 if (iflr->dstaddr.ss_family 490 && iflr->dstaddr.ss_len != sizeof(struct sockaddr_in)) 491 return EINVAL; 492 break; 493 default: /*shouldn't happen*/ 494 return EOPNOTSUPP; 495 } 496 if (sizeof(struct in_addr) * 8 < iflr->prefixlen) 497 return EINVAL; 498 499 switch (cmd) { 500 case SIOCALIFADDR: 501 { 502 struct in_aliasreq ifra; 503 504 if (iflr->flags & IFLR_PREFIX) 505 return EINVAL; 506 507 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */ 508 bzero(&ifra, sizeof(ifra)); 509 bcopy(iflr->iflr_name, ifra.ifra_name, 510 sizeof(ifra.ifra_name)); 511 512 bcopy(&iflr->addr, &ifra.ifra_addr, iflr->addr.ss_len); 513 514 if (iflr->dstaddr.ss_family) { /*XXX*/ 515 bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr, 516 iflr->dstaddr.ss_len); 517 } 518 519 ifra.ifra_mask.sin_family = AF_INET; 520 ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in); 521 in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen); 522 523 return in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp, p); 524 } 525 case SIOCGLIFADDR: 526 case SIOCDLIFADDR: 527 { 528 struct in_ifaddr *ia; 529 struct in_addr mask, candidate, match; 530 struct sockaddr_in *sin; 531 int cmp; 532 533 bzero(&mask, sizeof(mask)); 534 if (iflr->flags & IFLR_PREFIX) { 535 /* lookup a prefix rather than address. */ 536 in_len2mask(&mask, iflr->prefixlen); 537 538 sin = (struct sockaddr_in *)&iflr->addr; 539 match.s_addr = sin->sin_addr.s_addr; 540 match.s_addr &= mask.s_addr; 541 542 /* if you set extra bits, that's wrong */ 543 if (match.s_addr != sin->sin_addr.s_addr) 544 return EINVAL; 545 546 cmp = 1; 547 } else { 548 if (cmd == SIOCGLIFADDR) { 549 /* on getting an address, take the 1st match */ 550 cmp = 0; /*XXX*/ 551 } else { 552 /* on deleting an address, do exact match */ 553 in_len2mask(&mask, 32); 554 sin = (struct sockaddr_in *)&iflr->addr; 555 match.s_addr = sin->sin_addr.s_addr; 556 557 cmp = 1; 558 } 559 } 560 561 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 562 if (ifa->ifa_addr->sa_family != AF_INET6) 563 continue; 564 if (!cmp) 565 break; 566 candidate.s_addr = ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr; 567 candidate.s_addr &= mask.s_addr; 568 if (candidate.s_addr == match.s_addr) 569 break; 570 } 571 if (!ifa) 572 return EADDRNOTAVAIL; 573 ia = (struct in_ifaddr *)ifa; 574 575 if (cmd == SIOCGLIFADDR) { 576 /* fill in the if_laddrreq structure */ 577 bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len); 578 579 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { 580 bcopy(&ia->ia_dstaddr, &iflr->dstaddr, 581 ia->ia_dstaddr.sin_len); 582 } else 583 bzero(&iflr->dstaddr, sizeof(iflr->dstaddr)); 584 585 iflr->prefixlen = 586 in_mask2len(&ia->ia_sockmask.sin_addr); 587 588 iflr->flags = 0; /*XXX*/ 589 590 return 0; 591 } else { 592 struct in_aliasreq ifra; 593 594 /* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */ 595 bzero(&ifra, sizeof(ifra)); 596 bcopy(iflr->iflr_name, ifra.ifra_name, 597 sizeof(ifra.ifra_name)); 598 599 bcopy(&ia->ia_addr, &ifra.ifra_addr, 600 ia->ia_addr.sin_len); 601 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { 602 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr, 603 ia->ia_dstaddr.sin_len); 604 } 605 bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr, 606 ia->ia_sockmask.sin_len); 607 608 return in_control(so, SIOCDIFADDR, (caddr_t)&ifra, 609 ifp, p); 610 } 611 } 612 } 613 614 return EOPNOTSUPP; /*just for safety*/ 615 } 616 617 /* 618 * Delete any existing route for an interface. 619 */ 620 void 621 in_ifscrub(ifp, ia) 622 register struct ifnet *ifp; 623 register struct in_ifaddr *ia; 624 { 625 626 if ((ia->ia_flags & IFA_ROUTE) == 0) 627 return; 628 if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) 629 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 630 else 631 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0); 632 ia->ia_flags &= ~IFA_ROUTE; 633 } 634 635 /* 636 * Initialize an interface's internet address 637 * and routing table entry. 638 */ 639 static int 640 in_ifinit(ifp, ia, sin, scrub) 641 register struct ifnet *ifp; 642 register struct in_ifaddr *ia; 643 struct sockaddr_in *sin; 644 int scrub; 645 { 646 register u_long i = ntohl(sin->sin_addr.s_addr); 647 struct sockaddr_in oldaddr; 648 int s = splimp(), flags = RTF_UP, error; 649 650 oldaddr = ia->ia_addr; 651 ia->ia_addr = *sin; 652 /* 653 * Give the interface a chance to initialize 654 * if this is its first address, 655 * and to validate the address if necessary. 656 */ 657 if (ifp->if_ioctl && 658 (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) { 659 splx(s); 660 ia->ia_addr = oldaddr; 661 return (error); 662 } 663 splx(s); 664 if (scrub) { 665 ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr; 666 in_ifscrub(ifp, ia); 667 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 668 } 669 if (IN_CLASSA(i)) 670 ia->ia_netmask = IN_CLASSA_NET; 671 else if (IN_CLASSB(i)) 672 ia->ia_netmask = IN_CLASSB_NET; 673 else 674 ia->ia_netmask = IN_CLASSC_NET; 675 /* 676 * The subnet mask usually includes at least the standard network part, 677 * but may may be smaller in the case of supernetting. 678 * If it is set, we believe it. 679 */ 680 if (ia->ia_subnetmask == 0) { 681 ia->ia_subnetmask = ia->ia_netmask; 682 ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask); 683 } else 684 ia->ia_netmask &= ia->ia_subnetmask; 685 ia->ia_net = i & ia->ia_netmask; 686 ia->ia_subnet = i & ia->ia_subnetmask; 687 in_socktrim(&ia->ia_sockmask); 688 /* 689 * Add route for the network. 690 */ 691 ia->ia_ifa.ifa_metric = ifp->if_metric; 692 if (ifp->if_flags & IFF_BROADCAST) { 693 ia->ia_broadaddr.sin_addr.s_addr = 694 htonl(ia->ia_subnet | ~ia->ia_subnetmask); 695 ia->ia_netbroadcast.s_addr = 696 htonl(ia->ia_net | ~ ia->ia_netmask); 697 } else if (ifp->if_flags & IFF_LOOPBACK) { 698 ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr; 699 flags |= RTF_HOST; 700 } else if (ifp->if_flags & IFF_POINTOPOINT) { 701 if (ia->ia_dstaddr.sin_family != AF_INET) 702 return (0); 703 flags |= RTF_HOST; 704 } 705 if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0) 706 ia->ia_flags |= IFA_ROUTE; 707 708 /* 709 * If the interface supports multicast, join the "all hosts" 710 * multicast group on that interface. 711 */ 712 if (ifp->if_flags & IFF_MULTICAST) { 713 struct in_addr addr; 714 715 addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP); 716 in_addmulti(&addr, ifp); 717 } 718 return (error); 719 } 720 721 722 /* 723 * Return 1 if the address might be a local broadcast address. 724 */ 725 int 726 in_broadcast(in, ifp) 727 struct in_addr in; 728 struct ifnet *ifp; 729 { 730 register struct ifaddr *ifa; 731 u_long t; 732 733 if (in.s_addr == INADDR_BROADCAST || 734 in.s_addr == INADDR_ANY) 735 return 1; 736 if ((ifp->if_flags & IFF_BROADCAST) == 0) 737 return 0; 738 t = ntohl(in.s_addr); 739 /* 740 * Look through the list of addresses for a match 741 * with a broadcast address. 742 */ 743 #define ia ((struct in_ifaddr *)ifa) 744 for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa; 745 ifa = TAILQ_NEXT(ifa, ifa_link)) 746 if (ifa->ifa_addr->sa_family == AF_INET && 747 (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr || 748 in.s_addr == ia->ia_netbroadcast.s_addr || 749 /* 750 * Check for old-style (host 0) broadcast. 751 */ 752 t == ia->ia_subnet || t == ia->ia_net) && 753 /* 754 * Check for an all one subnetmask. These 755 * only exist when an interface gets a secondary 756 * address. 757 */ 758 ia->ia_subnetmask != (u_long)0xffffffff) 759 return 1; 760 return (0); 761 #undef ia 762 } 763 /* 764 * Add an address to the list of IP multicast addresses for a given interface. 765 */ 766 struct in_multi * 767 in_addmulti(ap, ifp) 768 register struct in_addr *ap; 769 register struct ifnet *ifp; 770 { 771 register struct in_multi *inm; 772 int error; 773 struct sockaddr_in sin; 774 struct ifmultiaddr *ifma; 775 int s = splnet(); 776 777 /* 778 * Call generic routine to add membership or increment 779 * refcount. It wants addresses in the form of a sockaddr, 780 * so we build one here (being careful to zero the unused bytes). 781 */ 782 bzero(&sin, sizeof sin); 783 sin.sin_family = AF_INET; 784 sin.sin_len = sizeof sin; 785 sin.sin_addr = *ap; 786 error = if_addmulti(ifp, (struct sockaddr *)&sin, &ifma); 787 if (error) { 788 splx(s); 789 return 0; 790 } 791 792 /* 793 * If ifma->ifma_protospec is null, then if_addmulti() created 794 * a new record. Otherwise, we are done. 795 */ 796 if (ifma->ifma_protospec != 0) { 797 splx(s); 798 return ifma->ifma_protospec; 799 } 800 801 /* XXX - if_addmulti uses M_WAITOK. Can this really be called 802 at interrupt time? If so, need to fix if_addmulti. XXX */ 803 inm = (struct in_multi *)malloc(sizeof(*inm), M_IPMADDR, 804 M_NOWAIT | M_ZERO); 805 if (inm == NULL) { 806 splx(s); 807 return (NULL); 808 } 809 810 inm->inm_addr = *ap; 811 inm->inm_ifp = ifp; 812 inm->inm_ifma = ifma; 813 ifma->ifma_protospec = inm; 814 LIST_INSERT_HEAD(&in_multihead, inm, inm_link); 815 816 /* 817 * Let IGMP know that we have joined a new IP multicast group. 818 */ 819 igmp_joingroup(inm); 820 splx(s); 821 return (inm); 822 } 823 824 /* 825 * Delete a multicast address record. 826 */ 827 void 828 in_delmulti(inm) 829 register struct in_multi *inm; 830 { 831 struct ifmultiaddr *ifma = inm->inm_ifma; 832 struct in_multi my_inm; 833 int s = splnet(); 834 835 my_inm.inm_ifp = NULL ; /* don't send the leave msg */ 836 if (ifma->ifma_refcount == 1) { 837 /* 838 * No remaining claims to this record; let IGMP know that 839 * we are leaving the multicast group. 840 * But do it after the if_delmulti() which might reset 841 * the interface and nuke the packet. 842 */ 843 my_inm = *inm ; 844 ifma->ifma_protospec = 0; 845 LIST_REMOVE(inm, inm_link); 846 free(inm, M_IPMADDR); 847 } 848 /* XXX - should be separate API for when we have an ifma? */ 849 if_delmulti(ifma->ifma_ifp, ifma->ifma_addr); 850 if (my_inm.inm_ifp != NULL) 851 igmp_leavegroup(&my_inm); 852 splx(s); 853 } 854