misc.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * Copyright (c)2019 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2023-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. package zerotier
  14. import (
  15. "encoding/base32"
  16. "encoding/binary"
  17. "net"
  18. "time"
  19. "unsafe"
  20. )
  21. // ZeroTierLogoChar is the unicode character that is ZeroTier's logo
  22. const ZeroTierLogoChar = "⏁"
  23. // Base32StdLowerCase is a base32 encoder/decoder using a lower-case standard alphabet and no padding.
  24. var Base32StdLowerCase = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567").WithPadding(base32.NoPadding)
  25. // TimeMs returns the time in milliseconds since epoch.
  26. func TimeMs() int64 { return int64(time.Now().UnixNano()) / int64(1000000) }
  27. // ipNetToKey creates a key that can be used in a map[] from a net.IPNet
  28. func ipNetToKey(ipn *net.IPNet) (k [3]uint64) {
  29. copy(((*[16]byte)(unsafe.Pointer(&k[0])))[:], ipn.IP)
  30. ones, bits := ipn.Mask.Size()
  31. k[2] = (uint64(ones) << 32) | uint64(bits)
  32. return
  33. }
  34. func allZero(b []byte) bool {
  35. for _, bb := range b {
  36. if bb != 0 {
  37. return false
  38. }
  39. }
  40. return true
  41. }
  42. // checkPort does trial binding to a port using both UDP and TCP and returns false if any bindings fail.
  43. func checkPort(port int) bool {
  44. var ua net.UDPAddr
  45. ua.IP = net.IPv6zero
  46. ua.Port = port
  47. uc, err := net.ListenUDP("udp6", &ua)
  48. if uc != nil {
  49. _ = uc.Close()
  50. }
  51. if err != nil {
  52. return false
  53. }
  54. ua.IP = net.IPv4zero
  55. uc, err = net.ListenUDP("udp4", &ua)
  56. if uc != nil {
  57. _ = uc.Close()
  58. }
  59. if err != nil {
  60. return false
  61. }
  62. var ta net.TCPAddr
  63. ta.IP = net.IPv6zero
  64. ta.Port = port
  65. tc, err := net.ListenTCP("tcp6", &ta)
  66. if tc != nil {
  67. _ = tc.Close()
  68. }
  69. if err != nil {
  70. return false
  71. }
  72. ta.IP = net.IPv4zero
  73. tc, err = net.ListenTCP("tcp4", &ta)
  74. if tc != nil {
  75. _ = tc.Close()
  76. }
  77. if err != nil {
  78. return false
  79. }
  80. return true
  81. }
  82. // The ipClassify code below is based on and should produce identical results to
  83. // InetAddress::ipScope() in the C++ code.
  84. const (
  85. ipClassificationNone = -1
  86. ipClassificationLoopback = 0
  87. ipClassificationPseudoprivate = 1
  88. ipClassificationPrivate = 2
  89. ipClassificationLinkLocal = 3
  90. ipClassificationMulticast = 4
  91. ipClassificationGlobal = 5
  92. )
  93. var ipv4PseudoprivatePrefixes = []byte{
  94. 0x06, // 6.0.0.0/8 (US Army)
  95. 0x0b, // 11.0.0.0/8 (US DoD)
  96. 0x15, // 21.0.0.0/8 (US DDN-RVN)
  97. 0x16, // 22.0.0.0/8 (US DISA)
  98. 0x19, // 25.0.0.0/8 (UK Ministry of Defense)
  99. 0x1a, // 26.0.0.0/8 (US DISA)
  100. 0x1c, // 28.0.0.0/8 (US DSI-North)
  101. 0x1d, // 29.0.0.0/8 (US DISA)
  102. 0x1e, // 30.0.0.0/8 (US DISA)
  103. 0x33, // 51.0.0.0/8 (UK Department of Social Security)
  104. 0x37, // 55.0.0.0/8 (US DoD)
  105. 0x38, // 56.0.0.0/8 (US Postal Service)
  106. }
  107. // ipClassify determines the official or in a few cases unofficial role of an IP address
  108. func ipClassify(ip net.IP) int {
  109. if len(ip) == 16 {
  110. ip4 := ip.To4()
  111. if len(ip4) == 4 {
  112. ip = ip4
  113. }
  114. }
  115. if len(ip) == 4 {
  116. ip4FirstByte := ip[0]
  117. for _, b := range ipv4PseudoprivatePrefixes {
  118. if ip4FirstByte == b {
  119. return ipClassificationPseudoprivate
  120. }
  121. }
  122. ip4 := binary.BigEndian.Uint32(ip)
  123. switch ip4FirstByte {
  124. case 0x0a: // 10.0.0.0/8
  125. return ipClassificationPrivate
  126. case 0x64: // 100.64.0.0/10
  127. if (ip4 & 0xffc00000) == 0x64400000 {
  128. return ipClassificationPrivate
  129. }
  130. case 0x7f: // 127.0.0.1/8
  131. return ipClassificationLoopback
  132. case 0xa9: // 169.254.0.0/16
  133. if (ip4 & 0xffff0000) == 0xa9fe0000 {
  134. return ipClassificationLinkLocal
  135. }
  136. case 0xac: // 172.16.0.0/12
  137. if (ip4 & 0xfff00000) == 0xac100000 {
  138. return ipClassificationPrivate
  139. }
  140. case 0xc0: // 192.168.0.0/16
  141. if (ip4 & 0xffff0000) == 0xc0a80000 {
  142. return ipClassificationPrivate
  143. }
  144. }
  145. switch ip4 >> 28 {
  146. case 0xe: // 224.0.0.0/4
  147. return ipClassificationMulticast
  148. case 0xf: // 240.0.0.0/4 ("reserved," usually unusable)
  149. return ipClassificationNone
  150. }
  151. return ipClassificationGlobal
  152. }
  153. if len(ip) == 16 {
  154. if (ip[0] & 0xf0) == 0xf0 {
  155. if ip[0] == 0xff { // ff00::/8
  156. return ipClassificationMulticast
  157. }
  158. if ip[0] == 0xfe && (ip[1]&0xc0) == 0x80 {
  159. if allZero(ip[2:15]) {
  160. if ip[15] == 0x01 { // fe80::1/128
  161. return ipClassificationLoopback
  162. }
  163. return ipClassificationLinkLocal
  164. }
  165. }
  166. if (ip[0] & 0xfe) == 0xfc { // fc00::/7
  167. return ipClassificationPrivate
  168. }
  169. }
  170. if allZero(ip[0:15]) {
  171. if ip[15] == 0x01 { // ::1/128
  172. return ipClassificationLoopback
  173. }
  174. if ip[15] == 0x00 { // ::/128
  175. return ipClassificationNone
  176. }
  177. }
  178. return ipClassificationGlobal
  179. }
  180. return ipClassificationNone
  181. }