Annotation of embedaddon/pimdd/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.mrouted". 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: * inet.c,v 3.8.4.1 1997/01/29 19:49:33 fenner Exp
! 11: */
! 12: #define C(x) ((x) & 0xff)
! 13:
! 14: #include "defs.h"
! 15:
! 16:
! 17: /*
! 18: * Exported variables.
! 19: */
! 20: char s1[19]; /* buffers to hold the string representations */
! 21: char s2[19]; /* of IP addresses, to be passed to inet_fmt() */
! 22: char s3[19];
! 23: char s4[19];
! 24:
! 25:
! 26: /*
! 27: * Verify that a given IP address is credible as a host address.
! 28: * (Without a mask, cannot detect addresses of the form {subnet,0} or
! 29: * {subnet,-1}.)
! 30: */
! 31: int
! 32: inet_valid_host(naddr)
! 33: u_int32 naddr;
! 34: {
! 35: register u_int32 addr;
! 36:
! 37: addr = ntohl(naddr);
! 38:
! 39: return (!(IN_MULTICAST(addr) ||
! 40: IN_BADCLASS (addr) ||
! 41: (addr & 0xff000000) == 0));
! 42: }
! 43:
! 44: /*
! 45: * Verify that a given netmask is plausible;
! 46: * make sure that it is a series of 1's followed by
! 47: * a series of 0's with no discontiguous 1's.
! 48: */
! 49: int
! 50: inet_valid_mask(mask)
! 51: u_int32 mask;
! 52: {
! 53: if (~(((mask & -mask) - 1) | mask) != 0) {
! 54: /* Mask is not contiguous */
! 55: return (FALSE);
! 56: }
! 57:
! 58: return (TRUE);
! 59: }
! 60:
! 61: /*
! 62: * Verify that a given subnet number and mask pair are credible.
! 63: *
! 64: * With CIDR, almost any subnet and mask are credible. mrouted still
! 65: * can't handle aggregated class A's, so we still check that, but
! 66: * otherwise the only requirements are that the subnet address is
! 67: * within the [ABC] range and that the host bits of the subnet
! 68: * are all 0.
! 69: */
! 70: int
! 71: inet_valid_subnet(nsubnet, nmask)
! 72: u_int32 nsubnet, nmask;
! 73: {
! 74: register u_int32 subnet, mask;
! 75:
! 76: subnet = ntohl(nsubnet);
! 77: mask = ntohl(nmask);
! 78:
! 79: if ((subnet & mask) != subnet)
! 80: return (FALSE);
! 81:
! 82: if (subnet == 0)
! 83: return (mask == 0);
! 84:
! 85: if (IN_CLASSA(subnet)) {
! 86: if (mask < 0xff000000 ||
! 87: (subnet & 0xff000000) == 0x7f000000 ||
! 88: (subnet & 0xff000000) == 0x00000000) return (FALSE);
! 89: }
! 90: else if (IN_CLASSD(subnet) || IN_BADCLASS(subnet)) {
! 91: /* Above Class C address space */
! 92: return (FALSE);
! 93: }
! 94: if (subnet & ~mask) {
! 95: /* Host bits are set in the subnet */
! 96: return (FALSE);
! 97: }
! 98: if (!inet_valid_mask(mask)) {
! 99: /* Netmask is not contiguous */
! 100: return (FALSE);
! 101: }
! 102:
! 103: return (TRUE);
! 104: }
! 105:
! 106:
! 107: /*
! 108: * Convert an IP address in u_int32 (network) format into a printable string.
! 109: */
! 110: char *
! 111: inet_fmt(addr, s)
! 112: u_int32 addr;
! 113: char *s;
! 114: {
! 115: register u_char *a;
! 116:
! 117: a = (u_char *)&addr;
! 118: sprintf(s, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
! 119: return (s);
! 120: }
! 121:
! 122:
! 123: /*
! 124: * Convert an IP subnet number in u_int32 (network) format into a printable
! 125: * string including the netmask as a number of bits.
! 126: */
! 127: #ifdef NOSUCHDEF /* replaced by netname() */
! 128: char *
! 129: inet_fmts(addr, mask, s)
! 130: u_int32 addr, mask;
! 131: char *s;
! 132: {
! 133: register u_char *a, *m;
! 134: int bits;
! 135:
! 136: if ((addr == 0) && (mask == 0)) {
! 137: sprintf(s, "default");
! 138: return (s);
! 139: }
! 140: a = (u_char *)&addr;
! 141: m = (u_char *)&mask;
! 142: bits = 33 - ffs(ntohl(mask));
! 143:
! 144: if (m[3] != 0) sprintf(s, "%u.%u.%u.%u/%d", a[0], a[1], a[2], a[3],
! 145: bits);
! 146: else if (m[2] != 0) sprintf(s, "%u.%u.%u/%d", a[0], a[1], a[2], bits);
! 147: else if (m[1] != 0) sprintf(s, "%u.%u/%d", a[0], a[1], bits);
! 148: else sprintf(s, "%u/%d", a[0], bits);
! 149:
! 150: return (s);
! 151: }
! 152: #endif /* NOSUCHDEF */
! 153:
! 154: /*
! 155: * Convert the printable string representation of an IP address into the
! 156: * u_int32 (network) format. Return 0xffffffff on error. (To detect the
! 157: * legal address with that value, you must explicitly compare the string
! 158: * with "255.255.255.255".)
! 159: * The return value is in network order.
! 160: */
! 161: u_int32
! 162: inet_parse(s, n)
! 163: char *s;
! 164: int n;
! 165: {
! 166: u_int32 a = 0;
! 167: u_int a0 = 0, a1 = 0, a2 = 0, a3 = 0;
! 168: int i;
! 169: char c;
! 170:
! 171: i = sscanf(s, "%u.%u.%u.%u%c", &a0, &a1, &a2, &a3, &c);
! 172: if (i < n || i > 4 || a0 > 255 || a1 > 255 || a2 > 255 || a3 > 255)
! 173: return (0xffffffff);
! 174:
! 175: ((u_char *)&a)[0] = a0;
! 176: ((u_char *)&a)[1] = a1;
! 177: ((u_char *)&a)[2] = a2;
! 178: ((u_char *)&a)[3] = a3;
! 179:
! 180: return (a);
! 181: }
! 182:
! 183:
! 184: /*
! 185: * inet_cksum extracted from:
! 186: * P I N G . C
! 187: *
! 188: * Author -
! 189: * Mike Muuss
! 190: * U. S. Army Ballistic Research Laboratory
! 191: * December, 1983
! 192: * Modified at Uc Berkeley
! 193: *
! 194: * (ping.c) Status -
! 195: * Public Domain. Distribution Unlimited.
! 196: *
! 197: * I N _ C K S U M
! 198: *
! 199: * Checksum routine for Internet Protocol family headers (C Version)
! 200: *
! 201: */
! 202: int
! 203: inet_cksum(addr, len)
! 204: u_int16 *addr;
! 205: u_int len;
! 206: {
! 207: register int nleft = (int)len;
! 208: register u_int16 *w = addr;
! 209: u_int16 answer = 0;
! 210: register int sum = 0;
! 211:
! 212: /*
! 213: * Our algorithm is simple, using a 32 bit accumulator (sum),
! 214: * we add sequential 16 bit words to it, and at the end, fold
! 215: * back all the carry bits from the top 16 bits into the lower
! 216: * 16 bits.
! 217: */
! 218: while (nleft > 1) {
! 219: sum += *w++;
! 220: nleft -= 2;
! 221: }
! 222:
! 223: /* mop up an odd byte, if necessary */
! 224: if (nleft == 1) {
! 225: *(u_char *) (&answer) = *(u_char *)w ;
! 226: sum += answer;
! 227: }
! 228:
! 229: /*
! 230: * add back carry outs from top 16 bits to low 16 bits
! 231: */
! 232: sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
! 233: sum += (sum >> 16); /* add carry */
! 234: answer = ~sum; /* truncate to 16 bits */
! 235: return (answer);
! 236: }
! 237:
! 238: /*
! 239: * Called by following netname() to create a mask specified network address.
! 240: */
! 241: void
! 242: trimdomain(cp)
! 243: char *cp;
! 244: {
! 245: static char domain[MAXHOSTNAMELEN + 1];
! 246: static int first = 1;
! 247: char *s;
! 248:
! 249: if (first) {
! 250: first = 0;
! 251: if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
! 252: (s = strchr(domain, '.')))
! 253: (void) strcpy(domain, s + 1);
! 254: else
! 255: domain[0] = 0;
! 256: }
! 257:
! 258: if (domain[0]) {
! 259: while ((cp = strchr(cp, '.'))) {
! 260: if (!strcasecmp(cp + 1, domain)) {
! 261: *cp = 0; /* hit it */
! 262: break;
! 263: } else {
! 264: cp++;
! 265: }
! 266: }
! 267: }
! 268: }
! 269:
! 270: static u_long
! 271: forgemask(a)
! 272: u_long a;
! 273: {
! 274: u_long m;
! 275:
! 276: if (IN_CLASSA(a))
! 277: m = IN_CLASSA_NET;
! 278: else if (IN_CLASSB(a))
! 279: m = IN_CLASSB_NET;
! 280: else
! 281: m = IN_CLASSC_NET;
! 282: return (m);
! 283: }
! 284:
! 285: static void
! 286: domask(dst, addr, mask)
! 287: char *dst;
! 288: u_long addr, mask;
! 289: {
! 290: int b, i;
! 291:
! 292: if (!mask || (forgemask(addr) == mask)) {
! 293: *dst = '\0';
! 294: return;
! 295: }
! 296: i = 0;
! 297: for (b = 0; b < 32; b++)
! 298: if (mask & (1 << b)) {
! 299: int bb;
! 300:
! 301: i = b;
! 302: for (bb = b+1; bb < 32; bb++)
! 303: if (!(mask & (1 << bb))) {
! 304: i = -1; /* noncontig */
! 305: break;
! 306: }
! 307: break;
! 308: }
! 309: if (i == -1)
! 310: sprintf(dst, "&0x%lx", mask);
! 311: else
! 312: sprintf(dst, "/%d", 32 - i);
! 313: }
! 314:
! 315: /*
! 316: * Return the name of the network whose address is given.
! 317: * The address is assumed to be that of a net or subnet, not a host.
! 318: */
! 319: char *
! 320: netname(addr, mask)
! 321: u_int32 addr, mask;
! 322: {
! 323: static char line[MAXHOSTNAMELEN + 4];
! 324: u_int32 omask;
! 325: u_int32 i;
! 326:
! 327: i = ntohl(addr);
! 328: omask = mask = ntohl(mask);
! 329: if ((i & 0xffffff) == 0)
! 330: sprintf(line, "%u", C(i >> 24));
! 331: else if ((i & 0xffff) == 0)
! 332: sprintf(line, "%u.%u", C(i >> 24) , C(i >> 16));
! 333: else if ((i & 0xff) == 0)
! 334: sprintf(line, "%u.%u.%u", C(i >> 24), C(i >> 16), C(i >> 8));
! 335: else
! 336: sprintf(line, "%u.%u.%u.%u", C(i >> 24),
! 337: C(i >> 16), C(i >> 8), C(i));
! 338: domask(line+strlen(line), i, omask);
! 339: return (line);
! 340: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>