Annotation of embedaddon/mrouted/inet.c, revision 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>