mirror of
https://github.com/logos-messaging/go-multiaddr.git
synced 2026-01-07 15:33:08 +00:00
Merge pull request #46 from multiformats/feat/private-net
private networks and utility functions
This commit is contained in:
commit
3ce601caf3
116
private.go
Normal file
116
private.go
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
package manet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
|
||||||
|
ma "github.com/multiformats/go-multiaddr"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Private4 and Private6 are well-known private networks
|
||||||
|
var Private4, Private6 []*net.IPNet
|
||||||
|
var privateCIDR4 = []string{
|
||||||
|
// localhost
|
||||||
|
"127.0.0.0/8",
|
||||||
|
// private networks
|
||||||
|
"10.0.0.0/8",
|
||||||
|
"100.64.0.0/10",
|
||||||
|
"172.16.0.0/12",
|
||||||
|
"192.168.0.0/16",
|
||||||
|
// link local
|
||||||
|
"169.254.0.0/16",
|
||||||
|
}
|
||||||
|
var privateCIDR6 = []string{
|
||||||
|
// localhost
|
||||||
|
"::1/128",
|
||||||
|
// ULA reserved
|
||||||
|
"fc00::/7",
|
||||||
|
// link local
|
||||||
|
"fe80::/10",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unroutable4 and Unroutable6 are well known unroutable address ranges
|
||||||
|
var Unroutable4, Unroutable6 []*net.IPNet
|
||||||
|
var unroutableCIDR4 = []string{
|
||||||
|
"0.0.0.0/8",
|
||||||
|
"192.0.0.0/26",
|
||||||
|
"192.0.2.0/24",
|
||||||
|
"192.88.99.0/24",
|
||||||
|
"198.18.0.0/15",
|
||||||
|
"198.51.100.0/24",
|
||||||
|
"203.0.113.0/24",
|
||||||
|
"224.0.0.0/4",
|
||||||
|
"240.0.0.0/4",
|
||||||
|
"255.255.255.255/32",
|
||||||
|
}
|
||||||
|
var unroutableCIDR6 = []string{
|
||||||
|
"ff00::/8",
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Private4 = parseCIDR(privateCIDR4)
|
||||||
|
Private6 = parseCIDR(privateCIDR6)
|
||||||
|
Unroutable4 = parseCIDR(unroutableCIDR4)
|
||||||
|
Unroutable6 = parseCIDR(unroutableCIDR6)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseCIDR(cidrs []string) []*net.IPNet {
|
||||||
|
ipnets := make([]*net.IPNet, len(cidrs))
|
||||||
|
for i, cidr := range cidrs {
|
||||||
|
_, ipnet, err := net.ParseCIDR(cidr)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
ipnets[i] = ipnet
|
||||||
|
}
|
||||||
|
return ipnets
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsPublicAddr retruns true if the IP part of the multiaddr is a publicly routable address
|
||||||
|
func IsPublicAddr(a ma.Multiaddr) bool {
|
||||||
|
isPublic := false
|
||||||
|
ma.ForEach(a, func(c ma.Component) bool {
|
||||||
|
switch c.Protocol().Code {
|
||||||
|
case ma.P_IP6ZONE:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
case ma.P_IP4:
|
||||||
|
ip := net.IP(c.RawValue())
|
||||||
|
isPublic = !inAddrRange(ip, Private4) && !inAddrRange(ip, Unroutable4)
|
||||||
|
case ma.P_IP6:
|
||||||
|
ip := net.IP(c.RawValue())
|
||||||
|
isPublic = !inAddrRange(ip, Private6) && !inAddrRange(ip, Unroutable6)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
return isPublic
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsPrivateAddr returns true if the IP part of the mutiaddr is in a private network
|
||||||
|
func IsPrivateAddr(a ma.Multiaddr) bool {
|
||||||
|
isPrivate := false
|
||||||
|
ma.ForEach(a, func(c ma.Component) bool {
|
||||||
|
switch c.Protocol().Code {
|
||||||
|
case ma.P_IP6ZONE:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
case ma.P_IP4:
|
||||||
|
isPrivate = inAddrRange(net.IP(c.RawValue()), Private4)
|
||||||
|
case ma.P_IP6:
|
||||||
|
isPrivate = inAddrRange(net.IP(c.RawValue()), Private6)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
return isPrivate
|
||||||
|
}
|
||||||
|
|
||||||
|
func inAddrRange(ip net.IP, ipnets []*net.IPNet) bool {
|
||||||
|
for _, ipnet := range ipnets {
|
||||||
|
if ipnet.Contains(ip) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
48
private_test.go
Normal file
48
private_test.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package manet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
ma "github.com/multiformats/go-multiaddr"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIsPublicAddr(t *testing.T) {
|
||||||
|
a, err := ma.NewMultiaddr("/ip4/192.168.1.1/tcp/80")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if IsPublicAddr(a) {
|
||||||
|
t.Fatal("192.168.1.1 is not a public address!")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !IsPrivateAddr(a) {
|
||||||
|
t.Fatal("192.168.1.1 is a private address!")
|
||||||
|
}
|
||||||
|
|
||||||
|
a, err = ma.NewMultiaddr("/ip4/1.1.1.1/tcp/80")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !IsPublicAddr(a) {
|
||||||
|
t.Fatal("1.1.1.1 is a public address!")
|
||||||
|
}
|
||||||
|
|
||||||
|
if IsPrivateAddr(a) {
|
||||||
|
t.Fatal("1.1.1.1 is not a private address!")
|
||||||
|
}
|
||||||
|
|
||||||
|
a, err = ma.NewMultiaddr("/tcp/80/ip4/1.1.1.1")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if IsPublicAddr(a) {
|
||||||
|
t.Fatal("shouldn't consider an address that starts with /tcp/ as *public*")
|
||||||
|
}
|
||||||
|
|
||||||
|
if IsPrivateAddr(a) {
|
||||||
|
t.Fatal("shouldn't consider an address that starts with /tcp/ as *private*")
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user