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.2 (Berkeley) 11/15/93 34 * $Id: in.c,v 1.3 1994/08/02 07:48:12 davidg Exp $ 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/ioctl.h> 40 #include <sys/errno.h> 41 #include <sys/malloc.h> 42 #include <sys/socket.h> 43 #include <sys/socketvar.h> 44 45 #include <net/if.h> 46 #include <net/route.h> 47 48 #include <netinet/in_systm.h> 49 #include <netinet/in.h> 50 #include <netinet/in_var.h> 51 #include <netinet/if_ether.h> 52 53 #ifdef INET 54 /* 55 * Return the network number from an internet address. 56 */ 57 u_long 58 in_netof(in) 59 struct in_addr in; 60 { 61 register u_long i = ntohl(in.s_addr); 62 register u_long net; 63 register struct in_ifaddr *ia; 64 65 if (IN_CLASSA(i)) 66 net = i & IN_CLASSA_NET; 67 else if (IN_CLASSB(i)) 68 net = i & IN_CLASSB_NET; 69 else if (IN_CLASSC(i)) 70 net = i & IN_CLASSC_NET; 71 else if (IN_CLASSD(i)) 72 net = i & IN_CLASSD_NET; 73 else 74 return (0); 75 76 /* 77 * Check whether network is a subnet; 78 * if so, return subnet number. 79 */ 80 for (ia = in_ifaddr; ia; ia = ia->ia_next) 81 if (net == ia->ia_net) 82 return (i & ia->ia_subnetmask); 83 return (net); 84 } 85 86 #ifndef SUBNETSARELOCAL 87 #define SUBNETSARELOCAL 1 88 #endif 89 int subnetsarelocal = SUBNETSARELOCAL; 90 /* 91 * Return 1 if an internet address is for a ``local'' host 92 * (one to which we have a connection). If subnetsarelocal 93 * is true, this includes other subnets of the local net. 94 * Otherwise, it includes only the directly-connected (sub)nets. 95 */ 96 int 97 in_localaddr(in) 98 struct in_addr in; 99 { 100 register u_long i = ntohl(in.s_addr); 101 register struct in_ifaddr *ia; 102 103 if (subnetsarelocal) { 104 for (ia = in_ifaddr; ia; ia = ia->ia_next) 105 if ((i & ia->ia_netmask) == ia->ia_net) 106 return (1); 107 } else { 108 for (ia = in_ifaddr; ia; ia = ia->ia_next) 109 if ((i & ia->ia_subnetmask) == ia->ia_subnet) 110 return (1); 111 } 112 return (0); 113 } 114 115 /* 116 * Determine whether an IP address is in a reserved set of addresses 117 * that may not be forwarded, or whether datagrams to that destination 118 * may be forwarded. 119 */ 120 int 121 in_canforward(in) 122 struct in_addr in; 123 { 124 register u_long i = ntohl(in.s_addr); 125 register u_long net; 126 127 if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i)) 128 return (0); 129 if (IN_CLASSA(i)) { 130 net = i & IN_CLASSA_NET; 131 if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT)) 132 return (0); 133 } 134 return (1); 135 } 136 137 /* 138 * Trim a mask in a sockaddr 139 */ 140 void 141 in_socktrim(ap) 142 struct sockaddr_in *ap; 143 { 144 register char *cplim = (char *) &ap->sin_addr; 145 register char *cp = (char *) (&ap->sin_addr + 1); 146 147 ap->sin_len = 0; 148 while (--cp > cplim) 149 if (*cp) { 150 (ap)->sin_len = cp - (char *) (ap) + 1; 151 break; 152 } 153 } 154 155 int in_interfaces; /* number of external internet interfaces */ 156 extern struct ifnet loif; 157 158 /* 159 * Generic internet control operations (ioctl's). 160 * Ifp is 0 if not an interface-specific ioctl. 161 */ 162 /* ARGSUSED */ 163 int 164 in_control(so, cmd, data, ifp) 165 struct socket *so; 166 int cmd; 167 caddr_t data; 168 register struct ifnet *ifp; 169 { 170 register struct ifreq *ifr = (struct ifreq *)data; 171 register struct in_ifaddr *ia = 0; 172 register struct ifaddr *ifa; 173 struct in_ifaddr *oia; 174 struct in_aliasreq *ifra = (struct in_aliasreq *)data; 175 struct sockaddr_in oldaddr; 176 int error, hostIsNew, maskIsNew; 177 u_long i; 178 179 /* 180 * Find address for this interface, if it exists. 181 */ 182 if (ifp) 183 for (ia = in_ifaddr; ia; ia = ia->ia_next) 184 if (ia->ia_ifp == ifp) 185 break; 186 187 switch (cmd) { 188 189 case SIOCAIFADDR: 190 case SIOCDIFADDR: 191 if (ifra->ifra_addr.sin_family == AF_INET) 192 for (oia = ia; ia; ia = ia->ia_next) { 193 if (ia->ia_ifp == ifp && 194 ia->ia_addr.sin_addr.s_addr == 195 ifra->ifra_addr.sin_addr.s_addr) 196 break; 197 } 198 if (cmd == SIOCDIFADDR && ia == 0) 199 return (EADDRNOTAVAIL); 200 /* FALLTHROUGH */ 201 case SIOCSIFADDR: 202 case SIOCSIFNETMASK: 203 case SIOCSIFDSTADDR: 204 if ((so->so_state & SS_PRIV) == 0) 205 return (EPERM); 206 207 if (ifp == 0) 208 panic("in_control"); 209 if (ia == (struct in_ifaddr *)0) { 210 oia = (struct in_ifaddr *) 211 malloc(sizeof *oia, M_IFADDR, M_WAITOK); 212 if (oia == (struct in_ifaddr *)NULL) 213 return (ENOBUFS); 214 bzero((caddr_t)oia, sizeof *oia); 215 if (ia = in_ifaddr) { 216 for ( ; ia->ia_next; ia = ia->ia_next) 217 continue; 218 ia->ia_next = oia; 219 } else 220 in_ifaddr = oia; 221 ia = oia; 222 if (ifa = ifp->if_addrlist) { 223 for ( ; ifa->ifa_next; ifa = ifa->ifa_next) 224 continue; 225 ifa->ifa_next = (struct ifaddr *) ia; 226 } else 227 ifp->if_addrlist = (struct ifaddr *) ia; 228 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 229 ia->ia_ifa.ifa_dstaddr 230 = (struct sockaddr *)&ia->ia_dstaddr; 231 ia->ia_ifa.ifa_netmask 232 = (struct sockaddr *)&ia->ia_sockmask; 233 ia->ia_sockmask.sin_len = 8; 234 if (ifp->if_flags & IFF_BROADCAST) { 235 ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr); 236 ia->ia_broadaddr.sin_family = AF_INET; 237 } 238 ia->ia_ifp = ifp; 239 if (ifp != &loif) 240 in_interfaces++; 241 } 242 break; 243 244 case SIOCSIFBRDADDR: 245 if ((so->so_state & SS_PRIV) == 0) 246 return (EPERM); 247 /* FALLTHROUGH */ 248 249 case SIOCGIFADDR: 250 case SIOCGIFNETMASK: 251 case SIOCGIFDSTADDR: 252 case SIOCGIFBRDADDR: 253 if (ia == (struct in_ifaddr *)0) 254 return (EADDRNOTAVAIL); 255 break; 256 } 257 switch (cmd) { 258 259 case SIOCGIFADDR: 260 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr; 261 break; 262 263 case SIOCGIFBRDADDR: 264 if ((ifp->if_flags & IFF_BROADCAST) == 0) 265 return (EINVAL); 266 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_broadaddr; 267 break; 268 269 case SIOCGIFDSTADDR: 270 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 271 return (EINVAL); 272 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr; 273 break; 274 275 case SIOCGIFNETMASK: 276 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask; 277 break; 278 279 case SIOCSIFDSTADDR: 280 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 281 return (EINVAL); 282 oldaddr = ia->ia_dstaddr; 283 ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr; 284 if (ifp->if_ioctl && (error = (*ifp->if_ioctl) 285 (ifp, SIOCSIFDSTADDR, (caddr_t)ia))) { 286 ia->ia_dstaddr = oldaddr; 287 return (error); 288 } 289 if (ia->ia_flags & IFA_ROUTE) { 290 ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr; 291 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 292 ia->ia_ifa.ifa_dstaddr = 293 (struct sockaddr *)&ia->ia_dstaddr; 294 rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); 295 } 296 break; 297 298 case SIOCSIFBRDADDR: 299 if ((ifp->if_flags & IFF_BROADCAST) == 0) 300 return (EINVAL); 301 ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr; 302 break; 303 304 case SIOCSIFADDR: 305 return (in_ifinit(ifp, ia, 306 (struct sockaddr_in *) &ifr->ifr_addr, 1)); 307 308 case SIOCSIFNETMASK: 309 i = ifra->ifra_addr.sin_addr.s_addr; 310 ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr = i); 311 break; 312 313 case SIOCAIFADDR: 314 maskIsNew = 0; 315 hostIsNew = 1; 316 error = 0; 317 if (ia->ia_addr.sin_family == AF_INET) { 318 if (ifra->ifra_addr.sin_len == 0) { 319 ifra->ifra_addr = ia->ia_addr; 320 hostIsNew = 0; 321 } else if (ifra->ifra_addr.sin_addr.s_addr == 322 ia->ia_addr.sin_addr.s_addr) 323 hostIsNew = 0; 324 } 325 if (ifra->ifra_mask.sin_len) { 326 in_ifscrub(ifp, ia); 327 ia->ia_sockmask = ifra->ifra_mask; 328 ia->ia_subnetmask = 329 ntohl(ia->ia_sockmask.sin_addr.s_addr); 330 maskIsNew = 1; 331 } 332 if ((ifp->if_flags & IFF_POINTOPOINT) && 333 (ifra->ifra_dstaddr.sin_family == AF_INET)) { 334 in_ifscrub(ifp, ia); 335 ia->ia_dstaddr = ifra->ifra_dstaddr; 336 maskIsNew = 1; /* We lie; but the effect's the same */ 337 } 338 if (ifra->ifra_addr.sin_family == AF_INET && 339 (hostIsNew || maskIsNew)) 340 error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0); 341 if ((ifp->if_flags & IFF_BROADCAST) && 342 (ifra->ifra_broadaddr.sin_family == AF_INET)) 343 ia->ia_broadaddr = ifra->ifra_broadaddr; 344 return (error); 345 346 case SIOCDIFADDR: 347 in_ifscrub(ifp, ia); 348 if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia) 349 ifp->if_addrlist = ifa->ifa_next; 350 else { 351 while (ifa->ifa_next && 352 (ifa->ifa_next != (struct ifaddr *)ia)) 353 ifa = ifa->ifa_next; 354 if (ifa->ifa_next) 355 ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next; 356 else 357 printf("Couldn't unlink inifaddr from ifp\n"); 358 } 359 oia = ia; 360 if (oia == (ia = in_ifaddr)) 361 in_ifaddr = ia->ia_next; 362 else { 363 while (ia->ia_next && (ia->ia_next != oia)) 364 ia = ia->ia_next; 365 if (ia->ia_next) 366 ia->ia_next = oia->ia_next; 367 else 368 printf("Didn't unlink inifadr from list\n"); 369 } 370 IFAFREE((&oia->ia_ifa)); 371 break; 372 373 default: 374 if (ifp == 0 || ifp->if_ioctl == 0) 375 return (EOPNOTSUPP); 376 return ((*ifp->if_ioctl)(ifp, cmd, data)); 377 } 378 return (0); 379 } 380 381 /* 382 * Delete any existing route for an interface. 383 */ 384 void 385 in_ifscrub(ifp, ia) 386 register struct ifnet *ifp; 387 register struct in_ifaddr *ia; 388 { 389 390 if ((ia->ia_flags & IFA_ROUTE) == 0) 391 return; 392 if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) 393 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 394 else 395 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0); 396 ia->ia_flags &= ~IFA_ROUTE; 397 } 398 399 /* 400 * Initialize an interface's internet address 401 * and routing table entry. 402 */ 403 int 404 in_ifinit(ifp, ia, sin, scrub) 405 register struct ifnet *ifp; 406 register struct in_ifaddr *ia; 407 struct sockaddr_in *sin; 408 int scrub; 409 { 410 register u_long i = ntohl(sin->sin_addr.s_addr); 411 struct sockaddr_in oldaddr; 412 int s = splimp(), flags = RTF_UP, error; 413 414 oldaddr = ia->ia_addr; 415 ia->ia_addr = *sin; 416 /* 417 * Give the interface a chance to initialize 418 * if this is its first address, 419 * and to validate the address if necessary. 420 */ 421 if (ifp->if_ioctl && 422 (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) { 423 splx(s); 424 ia->ia_addr = oldaddr; 425 return (error); 426 } 427 if (ifp->if_output == ether_output) { /* XXX: Another Kludge */ 428 ia->ia_ifa.ifa_rtrequest = arp_rtrequest; 429 ia->ia_ifa.ifa_flags |= RTF_CLONING; 430 } 431 splx(s); 432 if (scrub) { 433 ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr; 434 in_ifscrub(ifp, ia); 435 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 436 } 437 if (IN_CLASSA(i)) 438 ia->ia_netmask = IN_CLASSA_NET; 439 else if (IN_CLASSB(i)) 440 ia->ia_netmask = IN_CLASSB_NET; 441 else 442 ia->ia_netmask = IN_CLASSC_NET; 443 /* 444 * The subnet mask usually includes at least the standard network part, 445 * but may may be smaller in the case of supernetting. 446 * If it is set, we believe it. 447 */ 448 if (ia->ia_subnetmask == 0) { 449 ia->ia_subnetmask = ia->ia_netmask; 450 ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask); 451 } else 452 ia->ia_netmask &= ia->ia_subnetmask; 453 ia->ia_net = i & ia->ia_netmask; 454 ia->ia_subnet = i & ia->ia_subnetmask; 455 in_socktrim(&ia->ia_sockmask); 456 /* 457 * Add route for the network. 458 */ 459 ia->ia_ifa.ifa_metric = ifp->if_metric; 460 if (ifp->if_flags & IFF_BROADCAST) { 461 ia->ia_broadaddr.sin_addr.s_addr = 462 htonl(ia->ia_subnet | ~ia->ia_subnetmask); 463 ia->ia_netbroadcast.s_addr = 464 htonl(ia->ia_net | ~ ia->ia_netmask); 465 } else if (ifp->if_flags & IFF_LOOPBACK) { 466 ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr; 467 flags |= RTF_HOST; 468 } else if (ifp->if_flags & IFF_POINTOPOINT) { 469 if (ia->ia_dstaddr.sin_family != AF_INET) 470 return (0); 471 flags |= RTF_HOST; 472 } 473 if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0) 474 ia->ia_flags |= IFA_ROUTE; 475 /* 476 * If the interface supports multicast, join the "all hosts" 477 * multicast group on that interface. 478 */ 479 if (ifp->if_flags & IFF_MULTICAST) { 480 struct in_addr addr; 481 482 addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP); 483 in_addmulti(&addr, ifp); 484 } 485 return (error); 486 } 487 488 489 /* 490 * Return 1 if the address might be a local broadcast address. 491 */ 492 int 493 in_broadcast(in, ifp) 494 struct in_addr in; 495 struct ifnet *ifp; 496 { 497 register struct ifaddr *ifa; 498 u_long t; 499 500 if (in.s_addr == INADDR_BROADCAST || 501 in.s_addr == INADDR_ANY) 502 return 1; 503 if ((ifp->if_flags & IFF_BROADCAST) == 0) 504 return 0; 505 t = ntohl(in.s_addr); 506 /* 507 * Look through the list of addresses for a match 508 * with a broadcast address. 509 */ 510 #define ia ((struct in_ifaddr *)ifa) 511 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) 512 if (ifa->ifa_addr->sa_family == AF_INET && 513 (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr || 514 in.s_addr == ia->ia_netbroadcast.s_addr || 515 /* 516 * Check for old-style (host 0) broadcast. 517 */ 518 t == ia->ia_subnet || t == ia->ia_net)) 519 return 1; 520 return (0); 521 #undef ia 522 } 523 /* 524 * Add an address to the list of IP multicast addresses for a given interface. 525 */ 526 struct in_multi * 527 in_addmulti(ap, ifp) 528 register struct in_addr *ap; 529 register struct ifnet *ifp; 530 { 531 register struct in_multi *inm; 532 struct ifreq ifr; 533 struct in_ifaddr *ia; 534 int s = splnet(); 535 536 /* 537 * See if address already in list. 538 */ 539 IN_LOOKUP_MULTI(*ap, ifp, inm); 540 if (inm != NULL) { 541 /* 542 * Found it; just increment the reference count. 543 */ 544 ++inm->inm_refcount; 545 } 546 else { 547 /* 548 * New address; allocate a new multicast record 549 * and link it into the interface's multicast list. 550 */ 551 inm = (struct in_multi *)malloc(sizeof(*inm), 552 M_IPMADDR, M_NOWAIT); 553 if (inm == NULL) { 554 splx(s); 555 return (NULL); 556 } 557 inm->inm_addr = *ap; 558 inm->inm_ifp = ifp; 559 inm->inm_refcount = 1; 560 IFP_TO_IA(ifp, ia); 561 if (ia == NULL) { 562 free(inm, M_IPMADDR); 563 splx(s); 564 return (NULL); 565 } 566 inm->inm_ia = ia; 567 inm->inm_next = ia->ia_multiaddrs; 568 ia->ia_multiaddrs = inm; 569 /* 570 * Ask the network driver to update its multicast reception 571 * filter appropriately for the new address. 572 */ 573 ((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET; 574 ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr = *ap; 575 if ((ifp->if_ioctl == NULL) || 576 (*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) { 577 ia->ia_multiaddrs = inm->inm_next; 578 free(inm, M_IPMADDR); 579 splx(s); 580 return (NULL); 581 } 582 /* 583 * Let IGMP know that we have joined a new IP multicast group. 584 */ 585 igmp_joingroup(inm); 586 } 587 splx(s); 588 return (inm); 589 } 590 591 /* 592 * Delete a multicast address record. 593 */ 594 void 595 in_delmulti(inm) 596 register struct in_multi *inm; 597 { 598 register struct in_multi **p; 599 struct ifreq ifr; 600 int s = splnet(); 601 602 if (--inm->inm_refcount == 0) { 603 /* 604 * No remaining claims to this record; let IGMP know that 605 * we are leaving the multicast group. 606 */ 607 igmp_leavegroup(inm); 608 /* 609 * Unlink from list. 610 */ 611 for (p = &inm->inm_ia->ia_multiaddrs; 612 *p != inm; 613 p = &(*p)->inm_next) 614 continue; 615 *p = (*p)->inm_next; 616 /* 617 * Notify the network driver to update its multicast reception 618 * filter. 619 */ 620 ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET; 621 ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr = 622 inm->inm_addr; 623 (*inm->inm_ifp->if_ioctl)(inm->inm_ifp, SIOCDELMULTI, 624 (caddr_t)&ifr); 625 free(inm, M_IPMADDR); 626 } 627 splx(s); 628 } 629 #endif 630