1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
#include "check_ucast_static.h"
static void usage(void)
{
fprintf(stderr, "Usage: check-prefix-boundary [-4|-6] address/prefix\n");
exit(1);
}
static void get_prefix_1(inet_prefix *dst, char *arg, int family)
{
char *slash, *endp;
memset(dst, 0, sizeof(*dst));
slash = strchr(arg, '/');
if (!slash || slash[1] == '\0')
err("Missing prefix length\n");
*slash = 0;
get_addr_1(dst, arg, family);
dst->plen = strtoul(slash+1, &endp, 0);
if (*endp != '\0')
err("Invalid character in prefix length\n");
if (dst->plen > 8 * dst->bytelen)
err("Prefix length is too large\n");
*slash = '/';
}
static void get_netmask(inet_prefix *msk, const inet_prefix *dst)
{
int i, plen = dst->plen;
memset(msk, 0, sizeof(*msk));
msk->family = dst->family;
msk->bytelen = dst->bytelen;
for (i = 0; plen > 0 && i < dst->bytelen / sizeof(uint32_t); i++) {
uint32_t m = (plen > 32) ? ~0 : htonl(~0 << (32 - plen));
msk->data[i] = dst->data[i] & m;
plen -= 32;
}
}
int main(int argc, char **argv)
{
int family = AF_UNSPEC;
while (--argc) {
char *arg = *++argv;
inet_prefix dst, msk;
if (arg[0] == '-') {
switch(arg[1]) {
case '4':
family = AF_INET;
break;
case '6':
family = AF_INET6;
break;
default:
usage();
}
continue;
}
get_prefix_1(&dst, arg, family);
get_netmask(&msk, &dst);
if (memcmp(msk.data, dst.data, dst.bytelen) != 0) {
char buf[INET_ADDRSTRLEN];
err("Prefix not on a natural network boundary."
"Did you mean %s?\n",
inet_ntop(msk.family, msk.data, buf, sizeof buf));
}
/*
* Macros to check for Mcast are based on:
*
* Addr dst.data
* 224.1.2.2 ==> 0x030201e0
* ff01:0203:: ==> 0x030201ff
*
*/
if (family == AF_INET) {
if (IS_MULTICAST(dst.data[0])) {
err("Invalid Prefix...Route cannot be Multicast\n");
}
if (IS_BROADCAST(dst.data[0])) {
err("Invalid Prefix...Route cannot be Broadcast\n");
}
} else if (family == AF_INET6) {
if (IS_IPV6_MULTICAST(dst.data[0])) {
err("Invalid Prefix...Route cannot be IPv6 Multicast\n");
}
}
}
return 0;
}
|