home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / netinet / in.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-08  |  15.1 KB  |  598 lines

  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
  598.