network.go raw

   1  package addrmgr
   2  
   3  import (
   4  	"fmt"
   5  	"net"
   6  	
   7  	"github.com/p9c/p9/pkg/wire"
   8  )
   9  
  10  var (
  11  	// rfc1918Nets specifies the IPv4 private address blocks as defined by by RFC1918 (10.0.0.0/8, 172.16.0.0/12, and
  12  	// 192.168.0.0/16).
  13  	rfc1918Nets = []net.IPNet{
  14  		ipNet("10.0.0.0", 8, 32),
  15  		ipNet("172.16.0.0", 12, 32),
  16  		ipNet("192.168.0.0", 16, 32),
  17  	}
  18  	// rfc2544Net specifies the the IPv4 block as defined by RFC2544 (198.18.0.0/15)
  19  	rfc2544Net = ipNet("198.18.0.0", 15, 32)
  20  	// rfc3849Net specifies the IPv6 documentation address block as defined by RFC3849 (2001:DB8::/32).
  21  	rfc3849Net = ipNet("2001:DB8::", 32, 128)
  22  	// rfc3927Net specifies the IPv4 auto configuration address block as defined by RFC3927 (169.254.0.0/16).
  23  	rfc3927Net = ipNet("169.254.0.0", 16, 32)
  24  	// rfc3964Net specifies the IPv6 to IPv4 encapsulation address block as defined by RFC3964 (2002::/16).
  25  	rfc3964Net = ipNet("2002::", 16, 128)
  26  	// rfc4193Net specifies the IPv6 unique local address block as defined by RFC4193 (FC00::/7).
  27  	rfc4193Net = ipNet("FC00::", 7, 128)
  28  	// rfc4380Net specifies the IPv6 teredo tunneling over UDP address block as defined by RFC4380 (2001::/32).
  29  	rfc4380Net = ipNet("2001::", 32, 128)
  30  	// rfc4843Net specifies the IPv6 ORCHID address block as defined by RFC4843 (2001:10::/28).
  31  	rfc4843Net = ipNet("2001:10::", 28, 128)
  32  	// rfc4862Net specifies the IPv6 stateless address autoconfiguration address block as defined by RFC4862
  33  	// (FE80::/64).
  34  	rfc4862Net = ipNet("FE80::", 64, 128)
  35  	// rfc5737Net specifies the IPv4 documentation address blocks as defined by RFC5737 (192.0.2.0/24, 198.51.100.0/24,
  36  	// 203.0.113.0/24)
  37  	rfc5737Net = []net.IPNet{
  38  		ipNet("192.0.2.0", 24, 32),
  39  		ipNet("198.51.100.0", 24, 32),
  40  		ipNet("203.0.113.0", 24, 32),
  41  	}
  42  	// rfc6052Net specifies the IPv6 well-known prefix address block as defined by RFC6052 (64:FF9B::/96).
  43  	rfc6052Net = ipNet("64:FF9B::", 96, 128)
  44  	// rfc6145Net specifies the IPv6 to IPv4 translated address range as defined by RFC6145 (::FFFF:0:0:0/96).
  45  	rfc6145Net = ipNet("::FFFF:0:0:0", 96, 128)
  46  	// rfc6598Net specifies the IPv4 block as defined by RFC6598 (100.64.0.0/10)
  47  	rfc6598Net = ipNet("100.64.0.0", 10, 32)
  48  	// onionCatNet defines the IPv6 address block used to support Tor. bitcoind encodes a .onion address as a 16 byte
  49  	// number by decoding the address prior to the .onion (i.e. the key hash) base32 into a ten/ byte number. It then
  50  	// stores the first 6 bytes of the address as 0xfd, 0x87, 0xd8, 0x7e, 0xeb, 0x43. This is the same range used by
  51  	// OnionCat, which is part part of the RFC4193 unique local IPv6 range. In summary the format is: { magic 6 bytes,
  52  	// 10 bytes base32 decode of key hash }
  53  	onionCatNet = ipNet("fd87:d87e:eb43::", 48, 128)
  54  	// zero4Net defines the IPv4 address block for address staring with 0 (0.0.0.0/8).
  55  	zero4Net = ipNet("0.0.0.0", 8, 32)
  56  	// heNet defines the Hurricane Electric IPv6 address block.
  57  	heNet = ipNet("2001:470::", 32, 128)
  58  )
  59  
  60  // ipNet returns a net.IPNet struct given the passed IP address string, number of one bits to include at the start of
  61  // the mask, and the total number of bits for the mask.
  62  func ipNet(ip string, ones, bits int) net.IPNet {
  63  	return net.IPNet{IP: net.ParseIP(ip), Mask: net.CIDRMask(ones, bits)}
  64  }
  65  
  66  // IsIPv4 returns whether or not the given address is an IPv4 address.
  67  func IsIPv4(na *wire.NetAddress) bool {
  68  	return na.IP.To4() != nil
  69  }
  70  
  71  // IsLocal returns whether or not the given address is a local address.
  72  func IsLocal(na *wire.NetAddress) bool {
  73  	return na.IP.IsLoopback() || zero4Net.Contains(na.IP)
  74  }
  75  
  76  // IsOnionCatTor returns whether or not the passed address is in the IPv6 range used by bitcoin to support Tor
  77  // (fd87:d87e:eb43::/48). Note that this range is the same range used by OnionCat, which is part of the RFC4193 unique
  78  // local IPv6 range.
  79  func IsOnionCatTor(na *wire.NetAddress) bool {
  80  	return onionCatNet.Contains(na.IP)
  81  }
  82  
  83  // IsRFC1918 returns whether or not the passed address is part of the IPv4 private network address space as defined by
  84  // RFC1918 (10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16).
  85  func IsRFC1918(na *wire.NetAddress) bool {
  86  	for _, rfc := range rfc1918Nets {
  87  		if rfc.Contains(na.IP) {
  88  			return true
  89  		}
  90  	}
  91  	return false
  92  }
  93  
  94  // IsRFC2544 returns whether or not the passed address is part of the IPv4 address space as defined by RFC2544
  95  // (198.18.0.0/15)
  96  func IsRFC2544(na *wire.NetAddress) bool {
  97  	return rfc2544Net.Contains(na.IP)
  98  }
  99  
 100  // IsRFC3849 returns whether or not the passed address is part of the IPv6 documentation range as defined by RFC3849
 101  // (2001:DB8::/32).
 102  func IsRFC3849(na *wire.NetAddress) bool {
 103  	return rfc3849Net.Contains(na.IP)
 104  }
 105  
 106  // IsRFC3927 returns whether or not the passed address is part of the IPv4 autoconfiguration range as defined by RFC3927
 107  // (169.254.0.0/16).
 108  func IsRFC3927(na *wire.NetAddress) bool {
 109  	return rfc3927Net.Contains(na.IP)
 110  }
 111  
 112  // IsRFC3964 returns whether or not the passed address is part of the IPv6 to IPv4 encapsulation range as defined by
 113  // RFC3964 (2002::/16).
 114  func IsRFC3964(na *wire.NetAddress) bool {
 115  	return rfc3964Net.Contains(na.IP)
 116  }
 117  
 118  // IsRFC4193 returns whether or not the passed address is part of the IPv6 unique local range as defined by RFC4193
 119  // (FC00::/7).
 120  func IsRFC4193(na *wire.NetAddress) bool {
 121  	return rfc4193Net.Contains(na.IP)
 122  }
 123  
 124  // IsRFC4380 returns whether or not the passed address is part of the IPv6 teredo tunneling over UDP range as defined by
 125  // RFC4380 (2001::/32).
 126  func IsRFC4380(na *wire.NetAddress) bool {
 127  	return rfc4380Net.Contains(na.IP)
 128  }
 129  
 130  // IsRFC4843 returns whether or not the passed address is part of the IPv6 ORCHID range as defined by RFC4843
 131  // (2001:10::/28).
 132  func IsRFC4843(na *wire.NetAddress) bool {
 133  	return rfc4843Net.Contains(na.IP)
 134  }
 135  
 136  // IsRFC4862 returns whether or not the passed address is part of the IPv6 stateless address autoconfiguration range as
 137  // defined by RFC4862 (FE80::/64).
 138  func IsRFC4862(na *wire.NetAddress) bool {
 139  	return rfc4862Net.Contains(na.IP)
 140  }
 141  
 142  // IsRFC5737 returns whether or not the passed address is part of the IPv4 documentation address space as defined by
 143  // RFC5737 (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24)
 144  func IsRFC5737(na *wire.NetAddress) bool {
 145  	for _, rfc := range rfc5737Net {
 146  		if rfc.Contains(na.IP) {
 147  			return true
 148  		}
 149  	}
 150  	return false
 151  }
 152  
 153  // IsRFC6052 returns whether or not the passed address is part of the IPv6 well-known prefix range as defined by RFC6052
 154  // (64:FF9B::/96).
 155  func IsRFC6052(na *wire.NetAddress) bool {
 156  	return rfc6052Net.Contains(na.IP)
 157  }
 158  
 159  // IsRFC6145 returns whether or not the passed address is part of the IPv6 to IPv4 translated address range as defined
 160  // by RFC6145 (::FFFF:0:0:0/96).
 161  func IsRFC6145(na *wire.NetAddress) bool {
 162  	return rfc6145Net.Contains(na.IP)
 163  }
 164  
 165  // IsRFC6598 returns whether or not the passed address is part of the IPv4 shared address space specified by RFC6598
 166  // (100.64.0.0/10)
 167  func IsRFC6598(na *wire.NetAddress) bool {
 168  	return rfc6598Net.Contains(na.IP)
 169  }
 170  
 171  // IsValid returns whether or not the passed address is valid. The address is considered invalid under the following
 172  // circumstances:
 173  //
 174  // IPv4: It is either a zero or all bits set address. I
 175  //
 176  // Pv6: It is either a zero or RFC3849 documentation address.
 177  func IsValid(na *wire.NetAddress) bool {
 178  	// IsUnspecified returns if address is 0, so only all bits set, and RFC3849 need to be explicitly checked.
 179  	return na.IP != nil && !(na.IP.IsUnspecified() ||
 180  		na.IP.Equal(net.IPv4bcast))
 181  }
 182  
 183  // IsRoutable returns whether or not the passed address is routable over the public internet. This is true as long as
 184  // the address is valid and is not in any reserved ranges.
 185  func IsRoutable(na *wire.NetAddress) bool {
 186  	return IsValid(na) && !(IsRFC1918(na) || IsRFC2544(na) || IsRFC3927(na) || IsRFC4862(na) || IsRFC3849(na) || IsRFC4843(na) || IsRFC5737(na) || IsRFC6598(na) || IsLocal(na) || (IsRFC4193(na) && !IsOnionCatTor(na)))
 187  }
 188  
 189  // GroupKey returns a string representing the network group an address is part of. This is the /16 for IPv4, the /32
 190  // (/36 for he.net) for IPv6, the string "local" for a local address, the string "tor:key" where key is the /4 of the
 191  // onion address for Tor address, and the string "unroutable" for an unroutable address.
 192  func GroupKey(na *wire.NetAddress) string {
 193  	if IsLocal(na) {
 194  		return "local"
 195  	}
 196  	if !IsRoutable(na) {
 197  		return "unroutable"
 198  	}
 199  	if IsIPv4(na) {
 200  		return na.IP.Mask(net.CIDRMask(16, 32)).String()
 201  	}
 202  	if IsRFC6145(na) || IsRFC6052(na) {
 203  		// last four bytes are the ip address
 204  		ip := na.IP[12:16]
 205  		return ip.Mask(net.CIDRMask(16, 32)).String()
 206  	}
 207  	if IsRFC3964(na) {
 208  		ip := na.IP[2:6]
 209  		return ip.Mask(net.CIDRMask(16, 32)).String()
 210  	}
 211  	if IsRFC4380(na) {
 212  		// teredo tunnels have the last 4 bytes as the v4 address XOR 0xff.
 213  		ip := net.IP(make([]byte, 4))
 214  		for i, byt := range na.IP[12:16] {
 215  			ip[i] = byt ^ 0xff
 216  		}
 217  		return ip.Mask(net.CIDRMask(16, 32)).String()
 218  	}
 219  	if IsOnionCatTor(na) {
 220  		// group is keyed off the first 4 bits of the actual onion key.
 221  		return fmt.Sprintf("tor:%d", na.IP[6]&((1<<4)-1))
 222  	}
 223  	// OK, so now we know ourselves to be a IPv6 address. bitcoind uses /32 for everything, except for Hurricane
 224  	// Electric's (he.net) IP range, which it uses /36 for.
 225  	bits := 32
 226  	if heNet.Contains(na.IP) {
 227  		bits = 36
 228  	}
 229  	return na.IP.Mask(net.CIDRMask(bits, 128)).String()
 230  }
 231