inetaddress.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * Copyright (c)2013-2020 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: 2024-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. //#include "../../native/GoGlue.h"
  15. import "C"
  16. import (
  17. "bytes"
  18. "encoding/binary"
  19. "encoding/json"
  20. "errors"
  21. "net"
  22. "strconv"
  23. "strings"
  24. "syscall"
  25. "unsafe"
  26. )
  27. func sockaddrStorageToIPNet(ss *C.struct_sockaddr_storage) *net.IPNet {
  28. var a net.IPNet
  29. switch ss.ss_family {
  30. case syscall.AF_INET:
  31. sa4 := (*C.struct_sockaddr_in)(unsafe.Pointer(ss))
  32. var ip4 [4]byte
  33. copy(ip4[:], (*[4]byte)(unsafe.Pointer(&sa4.sin_addr))[:])
  34. a.IP = ip4[:]
  35. a.Mask = net.CIDRMask(int(binary.BigEndian.Uint16(((*[2]byte)(unsafe.Pointer(&sa4.sin_port)))[:])), 32)
  36. return &a
  37. case syscall.AF_INET6:
  38. sa6 := (*C.struct_sockaddr_in6)(unsafe.Pointer(ss))
  39. var ip6 [16]byte
  40. copy(ip6[:], (*[16]byte)(unsafe.Pointer(&sa6.sin6_addr))[:])
  41. a.IP = ip6[:]
  42. a.Mask = net.CIDRMask(int(binary.BigEndian.Uint16(((*[2]byte)(unsafe.Pointer(&sa6.sin6_port)))[:])), 128)
  43. return &a
  44. }
  45. return nil
  46. }
  47. func sockaddrStorageToUDPAddr(ss *C.struct_sockaddr_storage) *net.UDPAddr {
  48. var a net.UDPAddr
  49. switch ss.ss_family {
  50. case syscall.AF_INET:
  51. sa4 := (*C.struct_sockaddr_in)(unsafe.Pointer(ss))
  52. var ip4 [4]byte
  53. copy(ip4[:], (*[4]byte)(unsafe.Pointer(&sa4.sin_addr))[:])
  54. a.IP = ip4[:]
  55. a.Port = int(binary.BigEndian.Uint16(((*[2]byte)(unsafe.Pointer(&sa4.sin_port)))[:]))
  56. return &a
  57. case syscall.AF_INET6:
  58. sa6 := (*C.struct_sockaddr_in6)(unsafe.Pointer(ss))
  59. var ip6 [16]byte
  60. copy(ip6[:], (*[16]byte)(unsafe.Pointer(&sa6.sin6_addr))[:])
  61. a.IP = ip6[:]
  62. a.Port = int(binary.BigEndian.Uint16(((*[2]byte)(unsafe.Pointer(&sa6.sin6_port)))[:]))
  63. return &a
  64. }
  65. return nil
  66. }
  67. func sockaddrStorageToUDPAddr2(ss unsafe.Pointer) *net.UDPAddr {
  68. return sockaddrStorageToUDPAddr((*C.struct_sockaddr_storage)(ss))
  69. }
  70. func zeroSockaddrStorage(ss *C.struct_sockaddr_storage) {
  71. C.memset(unsafe.Pointer(ss), 0, C.sizeof_struct_sockaddr_storage)
  72. }
  73. func makeSockaddrStorage(ip net.IP, port int, ss *C.struct_sockaddr_storage) bool {
  74. zeroSockaddrStorage(ss)
  75. if len(ip) == 4 {
  76. sa4 := (*C.struct_sockaddr_in)(unsafe.Pointer(ss))
  77. sa4.sin_family = syscall.AF_INET
  78. copy(((*[4]byte)(unsafe.Pointer(&sa4.sin_addr)))[:], ip)
  79. binary.BigEndian.PutUint16(((*[2]byte)(unsafe.Pointer(&sa4.sin_port)))[:], uint16(port))
  80. return true
  81. }
  82. if len(ip) == 16 {
  83. sa6 := (*C.struct_sockaddr_in6)(unsafe.Pointer(ss))
  84. sa6.sin6_family = syscall.AF_INET6
  85. copy(((*[16]byte)(unsafe.Pointer(&sa6.sin6_addr)))[:], ip)
  86. binary.BigEndian.PutUint16(((*[2]byte)(unsafe.Pointer(&sa6.sin6_port)))[:], uint16(port))
  87. return true
  88. }
  89. return false
  90. }
  91. var ErrInvalidInetAddress = errors.New("invalid marshaled InetAddress object")
  92. // InetAddress implements net.Addr but has a ZeroTier-like string representation
  93. type InetAddress struct {
  94. IP net.IP
  95. Port int
  96. }
  97. // Nil returns true if this InetAddress is empty.
  98. func (ina *InetAddress) Nil() bool {
  99. return len(ina.IP) == 0
  100. }
  101. // Less returns true if this IP/port is lexicographically less than another
  102. func (ina *InetAddress) Less(i2 *InetAddress) bool {
  103. c := bytes.Compare(ina.IP, i2.IP)
  104. if c < 0 {
  105. return true
  106. }
  107. if c == 0 {
  108. return ina.Port < i2.Port
  109. }
  110. return false
  111. }
  112. // NewInetAddressFromString parses an IP[/port] format address
  113. func NewInetAddressFromString(s string) *InetAddress {
  114. i := new(InetAddress)
  115. ss := strings.Split(strings.TrimSpace(s), "/")
  116. if len(ss) > 0 {
  117. i.IP = net.ParseIP(ss[0])
  118. i4 := i.IP.To4()
  119. if len(i4) == 4 { // down-convert IPv4-in-6 IPs to native IPv4 as this is what all our code expects
  120. i.IP = i4
  121. }
  122. if len(ss) > 1 {
  123. p64, _ := strconv.ParseUint(ss[1], 10, 64)
  124. i.Port = int(p64 & 0xffff)
  125. }
  126. }
  127. return i
  128. }
  129. // NewInetAddressFromSockaddr parses a sockaddr_in or sockaddr_in6 C structure (may crash if given something other than these!)
  130. // This is a convenience wrapper around the CGO functions in node.go.
  131. func NewInetAddressFromSockaddr(sa unsafe.Pointer) *InetAddress {
  132. i := new(InetAddress)
  133. if uintptr(sa) != 0 {
  134. ua := sockaddrStorageToUDPAddr2(sa)
  135. if ua != nil {
  136. i.IP = ua.IP
  137. i.Port = ua.Port
  138. }
  139. }
  140. return i
  141. }
  142. // Network returns "udp" to implement net.Addr
  143. func (ina *InetAddress) Network() string {
  144. return "udp"
  145. }
  146. // String returns this address in ZeroTier-canonical IP/port format
  147. func (ina *InetAddress) String() string {
  148. return ina.IP.String() + "/" + strconv.FormatInt(int64(ina.Port), 10)
  149. }
  150. // Family returns the address family (AFInet etc.) or 0 if none
  151. func (ina *InetAddress) Family() int {
  152. switch len(ina.IP) {
  153. case 4:
  154. return syscall.AF_INET
  155. case 16:
  156. return syscall.AF_INET6
  157. }
  158. return 0
  159. }
  160. // Valid returns true if both the IP and port have valid values
  161. func (ina *InetAddress) Valid() bool {
  162. return (len(ina.IP) == 4 || len(ina.IP) == 16) && (ina.Port > 0 && ina.Port < 65536)
  163. }
  164. // MarshalJSON marshals this MAC as a string
  165. func (ina *InetAddress) MarshalJSON() ([]byte, error) {
  166. s := ina.String()
  167. return json.Marshal(&s)
  168. }
  169. // UnmarshalJSON unmarshals this MAC from a string
  170. func (ina *InetAddress) UnmarshalJSON(j []byte) error {
  171. var s string
  172. err := json.Unmarshal(j, &s)
  173. if err != nil {
  174. return err
  175. }
  176. *ina = *NewInetAddressFromString(s)
  177. return nil
  178. }
  179. func (ina *InetAddress) unmarshalZT(b []byte) (int, error) {
  180. if len(b) <= 0 {
  181. return 0, ErrInvalidInetAddress
  182. }
  183. switch b[0] {
  184. case 0:
  185. ina.IP = nil
  186. ina.Port = 0
  187. return 1, nil
  188. case 4:
  189. if len(b) != 7 {
  190. return 0, ErrInvalidInetAddress
  191. }
  192. ina.IP = []byte{b[1], b[2], b[3], b[4]}
  193. ina.Port = int(binary.BigEndian.Uint16(b[5:7]))
  194. return 7, nil
  195. case 6:
  196. if len(b) != 19 {
  197. return 0, ErrInvalidInetAddress
  198. }
  199. ina.IP = append(make([]byte, 0, 16), b[1:17]...)
  200. ina.Port = int(binary.BigEndian.Uint16(b[17:19]))
  201. return 19, nil
  202. default:
  203. return 0, ErrInvalidInetAddress
  204. }
  205. }
  206. // key returns a short array suitable for use as a map[] key for this IP
  207. func (ina *InetAddress) key() (k [3]uint64) {
  208. copy(((*[16]byte)(unsafe.Pointer(&k[0])))[:], ina.IP)
  209. k[2] = uint64(ina.Port)
  210. return
  211. }