# 2.11BSD#431 - /usr/src/new/nntp/server/subnet.c

##### Functions

    bsr               X
    getifconf         X
    inet_snetof       X

##### struct's

    in_if             X

       1: #ifndef lint
       2: static  char    *sccsid = "@(#)subnet.c	1.5	(Berkeley) 1/4/88";
       3: #endif
       4:
       5: #include "../common/conf.h"
       6:
       7: #ifdef SUBNET
       8:
       9: #include <sys/types.h>
      10: #include <sys/socket.h>
      11: #include <netinet/in.h>
      12: #ifndef NETMASK
      13: #include <net/if.h>
      14: #endif
      15: #include <sys/ioctl.h>
      16:
      17: /*
      18:  * The following routines provide a general interface for
      19:  * subnet support.  Like the library function "inet_netof",
      20:  * which returns the standard (i.e., non-subnet) network
      21:  * portion of an internet address, "inet_snetof" returns
      22:  * the subnetwork portion -- if there is one.  If there
      23:  * isn't, it returns 0.
      24:  *
      25:  * Subnets, under 4.3, are specific to a given set of
      26:  * machines -- right down to the network interfaces.
      27:  * Because of this, the function "getifconf" must be
      28:  * called first.  This routine builds a table listing
      29:  * all the (internet) interfaces present on a machine,
      30:  * along with their subnet masks.  Then when inet_snetof
      31:  * is called, it can quickly scan this table.
      32:  *
      33:  * Unfortunately, there "ain't no graceful way" to handle
      34:  * certain situations.  For example, the kernel permits
      35:  * arbitrary subnet bits -- that is, you could have a
      36:  * 22 bit network field and a 10 bit subnet field.
      37:  * However, due to braindamage at the user level, in
      38:  * such sterling routines as getnetbyaddr, you need to
      39:  * have a subnet mask which is an even multiple of 8.
      40:  * Unless you are running with class C subnets, in which
      41:  * case it should be a multiple of 4.  Because of this rot,
      42:  * if you have non-multiples of 4 bits of subnet, you should
      43:  * define DAMAGED_NETMASK when you compile.  This will round
      44:  * things off to a multiple of 8 bits.
      45:  *
      46:  * Finally, you may want subnet support even if your system doesn't
      47:  * support the ioctls to get subnet mask information.  If you want
      48:  * such a thing, you can define NETMASK to be a constant that is
      49:  * the subnet mask for your network.
      50:  *
      51:  * And don't *even* get me started on how the definitions of the inet_foo()
      52:  * routines changed between 4.2 and 4.3, making internet addresses
      53:  * be unsigned long vs. struct in_addr.  Don't blame me if this
      54:  * won't lint...
      55:  */
      56:
      57: /*
      58:  * One structure for each interface, containing
      59:  * the network number and subnet mask, stored in HBO.
      60:  */
      61: struct in_if {
      62:     u_long  i_net;      /* Network number, shifted right */
      63:     u_long  i_subnetmask;   /* Subnet mask for this if */
      64:     int i_bitshift; /* How many bits right for outside */
      65: };
      66:
      67: /*
      68:  * Table (eventually, once we malloc) of
      69:  * internet interface subnet informaiton.
      70:  */
      71: static  struct in_if    *in_ifsni;
      72:
      73: static  int     if_count;
      74:
      75: /*
      76:  * Get the network interface configuration,
      77:  * and squirrel away the network numbers and
      78:  * subnet masks of each interface.  Return
      79:  * number of interfaces found, or -1 on error.
      80:  * N.B.: don't call this more than once...
      81:  */
      82:
      83: getifconf()
      84: {
      85: #ifndef NETMASK
      86:     register int    i, j;
      87:     int     s;
      88:     struct ifconf   ifc;
      89:     char        buf[1024];
      90:     register struct ifreq   *ifr;
      91:     u_long      inet_netof();
      92:     u_long      addr;
      93:
      94:     /*
      95: 	 * Find out how many interfaces we have, and malloc
      96: 	 * room for information about each one.
      97: 	 */
      98:
      99:     s = socket(AF_INET, SOCK_DGRAM, 0);
     100:     if (s < 0)
     101:         return (-1);
     102:
     103:     ifc.ifc_buf = buf;
     104:     ifc.ifc_len = sizeof (buf);
     105:
     106:     if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
     107:         (void) close(s);
     108:         return (-1);
     109:     }
     110:
     111:     /*
     112: 	 * if_count here is the count of possible
     113: 	 * interfaces we may be interested in... actual
     114: 	 * interfaces may be less (some may not be internet,
     115: 	 * not all are necessarily up, etc.)
     116: 	 */
     117:
     118:     if_count = ifc.ifc_len / sizeof (struct ifreq);
     119:
     120:     in_ifsni = (struct in_if *) malloc(if_count * sizeof (struct in_if));
     121:     if (in_ifsni == 0) {
     122:         (void) close(s);
     123:         return (-1);
     124:     }
     125:
     126:     for (i = j = 0; i < if_count; ++i) {
     127:         ifr = &ifc.ifc_req[i];
     128:         if (ioctl(s, SIOCGIFFLAGS, ifr) < 0)
     129:             continue;
     130:         if ((ifr->ifr_flags & IFF_UP) == 0)
     131:             continue;
     132:         if (ioctl(s, SIOCGIFADDR, ifr) < 0)
     133:             continue;
     134:         if (ifr->ifr_addr.sa_family != AF_INET)
     135:             continue;
     136:         addr = (*(struct sockaddr_in *)&ifr->ifr_addr).sin_addr.s_addr;
     137:         in_ifsni[j].i_net = inet_netof(addr);
     138:         if (ioctl(s, SIOCGIFNETMASK, ifr) < 0)
     139:             continue;
     140:         in_ifsni[j].i_subnetmask =
     141:          ntohl((*(struct sockaddr_in *)&ifr->ifr_addr).sin_addr.s_addr);
     142:         /*
     143: 		 * The following should "never happen".  But under SunOs
     144: 		 * 3.4, along with the rest of their broken networking code,
     145: 		 * SIOCGIFNETMASK can get a netmask which is 0.  There
     146: 		 * really isn't anything that "right" that we can do
     147: 		 * about it, so we'll set their subnet mask to be their
     148: 		 * *net*work mask.  Which may or may not be right.
     149: 		 */
     150:         if (in_ifsni[j].i_subnetmask == 0) {
     151:             addr = ntohl(addr);
     152:             if (IN_CLASSA(addr))
     153:                 in_ifsni[j].i_subnetmask = IN_CLASSA_NET;
     154:             else if (IN_CLASSB(addr))
     155:                 in_ifsni[j].i_subnetmask = IN_CLASSB_NET;
     156:             else if (IN_CLASSC(addr))
     157:                 in_ifsni[j].i_subnetmask = IN_CLASSC_NET;
     158:             else            /* what to do ... */
     159:                 in_ifsni[j].i_subnetmask = IN_CLASSC_NET;
     160:         } else
     161:             in_ifsni[j].i_bitshift = bsr(in_ifsni[j].i_subnetmask);
     162:         j++;
     163:     }
     164:
     165:     if_count = j;
     166:
     167:     (void) close(s);
     168:
     169:     return (if_count);
     170:
     171: #else   /* hard-coded subnets */
     172:
     173:     if_count = 1;
     174:
     175:     in_ifsni = (struct in_if *) malloc(if_count * sizeof (struct in_if));
     176:     if (in_ifsni == 0) {
     177:         return (-1);
     178:     }
     179:     in_ifsni[0].i_net = 0;
     180:     in_ifsni[0].i_subnetmask = NETMASK;
     181:     in_ifsni[0].i_bitshift = bsr(in_ifsni[0].i_subnetmask);
     182:     return (if_count);
     183: #endif
     184: }
     185:
     186:
     187: /*
     188:  * Return the (sub)network number from an internet address.
     189:  * "in" is in NBO, return value in host byte order.
     190:  * If "in" is not a subnet, return 0.
     191:  */
     192:
     193: u_long
     194: inet_snetof(in)
     195:     u_long  in;
     196: {
     197:     register int    j;
     198:     register u_long i = ntohl(in);
     199:     register u_long net;
     200:     u_long      inet_netof(), inet_lnaof();
     201:
     202:     net = inet_netof(in);
     203:
     204:     /*
     205: 	 * Check whether network is a subnet;
     206: 	 * if so, return subnet number.
     207: 	 */
     208:     for (j = 0; j < if_count; ++j)
     209: #ifdef NETMASK
     210:         if (1) {
     211: #else
     212:         if (net == in_ifsni[j].i_net) {
     213: #endif
     214:             net = i & in_ifsni[j].i_subnetmask;
     215:             if (inet_lnaof(htonl(net)) == 0)
     216:                 return (0);
     217:             else
     218:                 return (net >> in_ifsni[j].i_bitshift);
     219:         }
     220:
     221:     return (0);
     222: }
     223:
     224:
     225: /*
     226:  * Return the number of bits required to
     227:  * shift right a mask into a getnetent-able entitity.
     228:  */
     229:
     230: bsr(mask)
     231:     register int    mask;
     232: {
     233:     register int    count = 0;
     234:
     235:     if (mask == 0)      /* "never happen", except with SunOs 3.4 */
     236:         return (0);
     237:
     238:     while ((mask & 1) == 0) {
     239:         ++count;
     240:         mask >>= 1;
     241:     }
     242: #ifdef DAMAGED_NETMASK
     243:     count /= 8;         /* XXX gag retch puke barf */
     244:     count *= 8;
     245: #endif
     246:     return (count);
     247: }
     248:
     249: #endif

#### Defined functions

bsr defined in line 230; used 2 times

- in line 161, 181

getifconf defined in line 83; used 1 times

- in /usr/src/new/nntp/server/access_inet.c line 47

inet_snetof defined in line 193; used 1 times

- in /usr/src/new/nntp/server/access_inet.c line 65

#### Defined variables

if_count defined in line 73; used 9 times

- in line 118-120(2), 126, 165-175(4), 182, 208

in_ifsni defined in line 71; used 20 times

- in line 120-121(2), 137-140(2), 150-161(7), 175-181(6), 212-218(3)

sccsid defined in line 2; never used

#### Defined struct's

in_if defined in line 61; used 10 times

- in line 71(2), 120(4), 175(4)

Last modified: 1988-01-05 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1312 |