misc.go 4.6 KB

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