GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/mrinfo/../mrouted/inet.c Lines: 0 57 0.0 %
Date: 2017-11-07 Branches: 0 40 0.0 %

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