Annotation of embedaddon/pimdd/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.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>