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