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