inet.c revision 1.1 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 * from: Id: inet.c,v 1.4 1993/05/30 01:36:38 deering Exp
11 * $Id: inet.c,v 1.1 1994/01/11 20:15:55 brezak Exp $
12 */
13
14 #ifndef lint
15 static char rcsid[] = "$Id: inet.c,v 1.1 1994/01/11 20:15:55 brezak Exp $";
16 #endif
17
18 #include "defs.h"
19
20
21 /*
22 * Exported variables.
23 */
24 char s1[16]; /* buffers to hold the string representations */
25 char s2[16]; /* of IP addresses, to be passed to inet_fmt() */
26 char s3[16]; /* or inet_fmts(). */
27
28
29 /*
30 * Verify that a given IP address is credible as a host address.
31 * (Without a mask, cannot detect addresses of the form {subnet,0} or
32 * {subnet,-1}.)
33 */
34 int inet_valid_host(naddr)
35 u_long naddr;
36 {
37 register u_long addr;
38
39 addr = ntohl(naddr);
40
41 return (!(IN_MULTICAST(addr) ||
42 IN_BADCLASS (addr) ||
43 (addr & 0xff000000) == 0));
44 }
45
46
47 /*
48 * Verify that a given subnet number and mask pair are credible.
49 */
50 int inet_valid_subnet(nsubnet, nmask)
51 u_long nsubnet, nmask;
52 {
53 register u_long subnet, mask;
54
55 subnet = ntohl(nsubnet);
56 mask = ntohl(nmask);
57
58 if ((subnet & mask) != subnet) return (FALSE);
59
60 if (IN_CLASSA(subnet)) {
61 if (mask < 0xff000000 ||
62 (subnet & 0xff000000) == 0 ||
63 (subnet & 0xff000000) == 0x7f000000) return (FALSE);
64 }
65 else if (IN_CLASSB(subnet)) {
66 if (mask < 0xffff0000) return (FALSE);
67 }
68 else if (IN_CLASSC(subnet)) {
69 if (mask < 0xffffff00) return (FALSE);
70 }
71 else return (FALSE);
72
73 return (TRUE);
74 }
75
76
77 /*
78 * Convert an IP address in u_long (network) format into a printable string.
79 */
80 char *inet_fmt(addr, s)
81 u_long addr;
82 char *s;
83 {
84 register u_char *a;
85
86 a = (u_char *)&addr;
87 sprintf(s, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
88 return (s);
89 }
90
91
92 /*
93 * Convert an IP subnet number in u_long (network) format into a printable
94 * string.
95 */
96 char *inet_fmts(addr, mask, s)
97 u_long addr, mask;
98 char *s;
99 {
100 register u_char *a, *m;
101
102 a = (u_char *)&addr;
103 m = (u_char *)&mask;
104
105 if (m[3] != 0) sprintf(s, "%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
106 else if (m[2] != 0) sprintf(s, "%u.%u.%u", a[0], a[1], a[2]);
107 else if (m[1] != 0) sprintf(s, "%u.%u", a[0], a[1]);
108 else sprintf(s, "%u", a[0]);
109
110 return (s);
111 }
112
113
114 /*
115 * Convert the printable string representation of an IP address into the
116 * u_long (network) format. Return 0xffffffff on error. (To detect the
117 * legal address with that value, you must explicitly compare the string
118 * with "255.255.255.255".)
119 */
120 u_long inet_parse(s)
121 char *s;
122 {
123 u_long a;
124 u_int a0, a1, a2, a3;
125 char c;
126
127 if (sscanf(s, "%u.%u.%u.%u%c", &a0, &a1, &a2, &a3, &c) != 4 ||
128 a0 > 255 || a1 > 255 || a2 > 255 || a3 > 255)
129 return (0xffffffff);
130
131 ((u_char *)&a)[0] = a0;
132 ((u_char *)&a)[1] = a1;
133 ((u_char *)&a)[2] = a2;
134 ((u_char *)&a)[3] = a3;
135
136 return (a);
137 }
138
139
140 /*
141 * inet_cksum extracted from:
142 * P I N G . C
143 *
144 * Author -
145 * Mike Muuss
146 * U. S. Army Ballistic Research Laboratory
147 * December, 1983
148 * Modified at Uc Berkeley
149 *
150 * (ping.c) Status -
151 * Public Domain. Distribution Unlimited.
152 *
153 * I N _ C K S U M
154 *
155 * Checksum routine for Internet Protocol family headers (C Version)
156 *
157 */
158 int inet_cksum(addr, len)
159 u_short *addr;
160 u_int len;
161 {
162 register int nleft = (int)len;
163 register u_short *w = addr;
164 u_short answer = 0;
165 register int sum = 0;
166
167 /*
168 * Our algorithm is simple, using a 32 bit accumulator (sum),
169 * we add sequential 16 bit words to it, and at the end, fold
170 * back all the carry bits from the top 16 bits into the lower
171 * 16 bits.
172 */
173 while( nleft > 1 ) {
174 sum += *w++;
175 nleft -= 2;
176 }
177
178 /* mop up an odd byte, if necessary */
179 if( nleft == 1 ) {
180 *(u_char *) (&answer) = *(u_char *)w ;
181 sum += answer;
182 }
183
184 /*
185 * add back carry outs from top 16 bits to low 16 bits
186 */
187 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
188 sum += (sum >> 16); /* add carry */
189 answer = ~sum; /* truncate to 16 bits */
190 return (answer);
191 }
192