-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbogons.go
124 lines (111 loc) · 2.76 KB
/
bogons.go
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package bogons
import "net"
// ValidPublicASN checks whether an ASN is valid.
// No private or reserved ASNs are valid.
func ValidPublicASN(asn uint32) bool {
switch {
case asn == 0: // RFC6483, RFC7607
return false
case asn == 23456: // RFC6793
return false
case asn >= 64496 && asn <= 64511: // RFC5398
return false
case asn >= 64512 && asn <= 65534: // RFC1930, RFC6996
return false
case asn == 65535: // RFC7300
return false
case asn >= 65536 && asn <= 65551: //RFC4893, RFC5398
return false
case asn >= 65552 && asn <= 131071:
return false
case asn >= 4200000000 && asn <= 4294967294: //RFC6996
return false
case asn == 4294967295: // RFC7300
return false
}
return true
}
// ValidPublicIP just checks whether the strings parses into
// either an IPv4 or IPv6 address. It must also be public.
func ValidPublicIP(ip string) bool {
parsed := net.ParseIP(ip)
if parsed == nil {
return false
}
// Private IPs are not valid
return IsPublicIP(parsed)
}
// IsPublicIP checks to ensure that the provided ip is public. Either IPv4 or IPv6 can be used as input.
func IsPublicIP(ip net.IP) bool {
if ip4 := ip.To4(); ip4 != nil {
return IsPublicIPv4(ip4)
}
return IsPublicIPv6(ip)
}
// IsPublicIPv4 checks if the IPv4 address is a valid public address.
func IsPublicIPv4(ip net.IP) bool {
if !ip.IsGlobalUnicast() {
return false
}
switch {
// 0.x.x.x/8
case ip[0] == 0:
return false
// loopbacks
case ip[0] == 127:
return false
// rfc1918
case ip[0] == 10:
return false
// rfc1918
case ip[0] == 172 && ip[1] >= 16 && ip[1] <= 31:
return false
// rfc1918
case ip[0] == 192 && ip[1] == 168:
return false
// rfc6598
case ip[0] == 100 && ip[1] >= 64 && ip[1] <= 127:
return false
// rfc3927
case ip[0] == 169 && ip[1] == 254:
return false
// rfc5737
case ip[0] == 192 && ip[1] == 0 && (ip[2] == 0 || ip[2] == 2):
return false
// rfc5737
case ip[0] == 198 && ip[1] == 51 && ip[2] == 100:
return false
// rfc5737
case ip[0] == 198 && (ip[1] == 18 || ip[1] == 19):
return false
// rfc5737
case ip[0] == 203 && ip[1] == 0 && ip[2] == 113:
return false
// class D,E
case ip[0] >= 224:
return false
}
return true
}
// IsPublicIPv6 checks if the IPv6 address is a valid public address.
func IsPublicIPv6(ip net.IP) bool {
if !ip.IsGlobalUnicast() {
return false
}
switch {
// Teredo tunnels 2001::/32
case ip[0] == 32 && ip[1] == 1 && ip[2] == 0:
return false
// 6bone 3ffe::/16
case ip[0] == 63 && ip[1] == 254:
return false
// documentation 2001:db8::/32
case ip[0] == 32 && ip[1] == 1 && ip[2] == 13 && ip[3] == 184:
return false
// 6to4 2002::/16
case ip[0] == 32 && ip[1] == 2:
return false
}
// Besides the above, as long as the prefix sits inside 2000::/3 it's public
return ip[0] >= 32 && ip[0] <= 63
}