Annotation of embedaddon/mrouted/inet.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * The mrouted program is covered by the license in the accompanying file
                      3:  * named "LICENSE".  Use of the mrouted program represents acceptance of
                      4:  * the terms and conditions listed in that file.
                      5:  *
                      6:  * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
                      7:  * Leland Stanford Junior University.
                      8:  */
                      9: 
                     10: #include "defs.h"
                     11: 
                     12: /*
                     13:  * Exported variables.
                     14:  */
                     15: char s1[MAX_INET_BUF_LEN];             /* buffers to hold the string representations  */
                     16: char s2[MAX_INET_BUF_LEN];             /* of IP addresses, to be passed to inet_fmt() */
                     17: char s3[MAX_INET_BUF_LEN];             /* or inet_fmts().                             */
                     18: char s4[MAX_INET_BUF_LEN];
                     19: 
                     20: 
                     21: /*
                     22:  * Verify that a given IP address is credible as a host address.
                     23:  * (Without a mask, cannot detect addresses of the form {subnet,0} or
                     24:  * {subnet,-1}.)
                     25:  */
                     26: int inet_valid_host(u_int32 naddr)
                     27: {
                     28:     u_int32 addr;
                     29: 
                     30:     addr = ntohl(naddr);
                     31: 
                     32:     return (!(IN_MULTICAST(addr) ||
                     33:              IN_BADCLASS (addr) ||
                     34:              (addr & 0xff000000) == 0));
                     35: }
                     36: 
                     37: /*
                     38:  * Verify that a given netmask is plausible;
                     39:  * make sure that it is a series of 1's followed by
                     40:  * a series of 0's with no discontiguous 1's.
                     41:  */
                     42: int inet_valid_mask(u_int32 mask)
                     43: {
                     44:     if (~(((mask & -mask) - 1) | mask) != 0) {
                     45:        /* Mask is not contiguous */
                     46:        return FALSE;
                     47:     }
                     48: 
                     49:     return TRUE;
                     50: }
                     51: 
                     52: /*
                     53:  * Verify that a given subnet number and mask pair are credible.
                     54:  *
                     55:  * With CIDR, almost any subnet and mask are credible.  mrouted still
                     56:  * can't handle aggregated class A's, so we still check that, but
                     57:  * otherwise the only requirements are that the subnet address is
                     58:  * within the [ABC] range and that the host bits of the subnet
                     59:  * are all 0.
                     60:  */
                     61: int inet_valid_subnet(u_int32 nsubnet, u_int32 nmask)
                     62: {
                     63:     u_int32 subnet, mask;
                     64: 
                     65:     subnet = ntohl(nsubnet);
                     66:     mask   = ntohl(nmask);
                     67: 
                     68:     if ((subnet & mask) != subnet) return FALSE;
                     69: 
                     70:     if (subnet == 0)
                     71:        return mask == 0;
                     72: 
                     73:     if (IN_CLASSA(subnet)) {
                     74:        if (mask < 0xff000000 ||
                     75:            (subnet & 0xff000000) == 0x7f000000 ||
                     76:            (subnet & 0xff000000) == 0x00000000) return FALSE;
                     77:     }
                     78:     else if (IN_CLASSD(subnet) || IN_BADCLASS(subnet)) {
                     79:        /* Above Class C address space */
                     80:        return FALSE;
                     81:     }
                     82:     if (subnet & ~mask) {
                     83:        /* Host bits are set in the subnet */
                     84:        return FALSE;
                     85:     }
                     86:     if (!inet_valid_mask(mask)) {
                     87:        /* Netmask is not contiguous */
                     88:        return FALSE;
                     89:     }
                     90: 
                     91:     return TRUE;
                     92: }
                     93: 
                     94: 
                     95: /*
                     96:  * Convert an IP address in u_long (network) format into a printable string.
                     97:  */
                     98: char *inet_fmt(u_int32 addr, char *s, size_t len)
                     99: {
                    100:     u_char *a;
                    101: 
                    102:     a = (u_char *)&addr;
                    103:     snprintf(s, len, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
                    104: 
                    105:     return s;
                    106: }
                    107: 
                    108: 
                    109: /*
                    110:  * Convert an IP subnet number in u_long (network) format into a printable
                    111:  * string including the netmask as a number of bits.
                    112:  */
                    113: char *inet_fmts(u_int32 addr, u_int32 mask, char *s, size_t len)
                    114: {
                    115:     u_char *a, *m;
                    116:     int bits;
                    117: 
                    118:     if ((addr == 0) && (mask == 0)) {
                    119:        snprintf(s, len, "default");
                    120:        return s;
                    121:     }
                    122:     a = (u_char *)&addr;
                    123:     m = (u_char *)&mask;
                    124:     bits = 33 - ffs(ntohl(mask));
                    125: 
                    126:     if      (m[3] != 0) snprintf(s, len, "%u.%u.%u.%u/%d", a[0], a[1], a[2], a[3],
                    127:                                                bits);
                    128:     else if (m[2] != 0) snprintf(s, len, "%u.%u.%u/%d",    a[0], a[1], a[2], bits);
                    129:     else if (m[1] != 0) snprintf(s, len, "%u.%u/%d",       a[0], a[1], bits);
                    130:     else                snprintf(s, len, "%u/%d",          a[0], bits);
                    131: 
                    132:     return s;
                    133: }
                    134: 
                    135: /*
                    136:  * Convert the printable string representation of an IP address into the
                    137:  * u_long (network) format.  Return 0xffffffff on error.  (To detect the
                    138:  * legal address with that value, you must explicitly compare the string
                    139:  * with "255.255.255.255".)
                    140:  */
                    141: u_int32 inet_parse(char *s, int n)
                    142: {
                    143:     u_int32 a = 0;
                    144:     u_int a0 = 0, a1 = 0, a2 = 0, a3 = 0;
                    145:     int i;
                    146:     char c;
                    147: 
                    148:     i = sscanf(s, "%u.%u.%u.%u%c", &a0, &a1, &a2, &a3, &c);
                    149:     if (i < n || i > 4 || a0 > 255 || a1 > 255 || a2 > 255 || a3 > 255)
                    150:        return 0xffffffff;
                    151: 
                    152:     ((u_char *)&a)[0] = a0;
                    153:     ((u_char *)&a)[1] = a1;
                    154:     ((u_char *)&a)[2] = a2;
                    155:     ((u_char *)&a)[3] = a3;
                    156: 
                    157:     return a;
                    158: }
                    159: 
                    160: 
                    161: /*
                    162:  * inet_cksum extracted from:
                    163:  *                     P I N G . C
                    164:  *
                    165:  * Author -
                    166:  *     Mike Muuss
                    167:  *     U. S. Army Ballistic Research Laboratory
                    168:  *     December, 1983
                    169:  * Modified at Uc Berkeley
                    170:  *
                    171:  * (ping.c) Status -
                    172:  *     Public Domain.  Distribution Unlimited.
                    173:  *
                    174:  *                     I N _ C K S U M
                    175:  *
                    176:  * Checksum routine for Internet Protocol family headers (C Version)
                    177:  *
                    178:  */
                    179: int inet_cksum(u_int16_t *addr, u_int len)
                    180: {
                    181:        int nleft = (int)len;
                    182:        u_int16_t *w = addr;
                    183:        u_int16_t answer = 0;
                    184:        int32_t sum = 0;
                    185: 
                    186:        /*
                    187:         *  Our algorithm is simple, using a 32 bit accumulator (sum),
                    188:         *  we add sequential 16 bit words to it, and at the end, fold
                    189:         *  back all the carry bits from the top 16 bits into the lower
                    190:         *  16 bits.
                    191:         */
                    192:        while (nleft > 1)  {
                    193:                sum += *w++;
                    194:                nleft -= 2;
                    195:        }
                    196: 
                    197:        /* mop up an odd byte, if necessary */
                    198:        if (nleft == 1) {
                    199:                *(u_char *) (&answer) = *(u_char *)w ;
                    200:                sum += answer;
                    201:        }
                    202: 
                    203:        /*
                    204:         * add back carry outs from top 16 bits to low 16 bits
                    205:         */
                    206:        sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
                    207:        sum += (sum >> 16);                     /* add carry */
                    208:        answer = ~sum;                          /* truncate to 16 bits */
                    209: 
                    210:        return answer;
                    211: }
                    212: 
                    213: /**
                    214:  * Local Variables:
                    215:  *  version-control: t
                    216:  *  indent-tabs-mode: t
                    217:  *  c-file-style: "ellemtel"
                    218:  *  c-basic-offset: 4
                    219:  * End:
                    220:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>