HostAddress.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. package types
  2. // Reference: https://www.ietf.org/rfc/rfc4120.txt
  3. // Section: 5.2.5
  4. import (
  5. "bytes"
  6. "fmt"
  7. "net"
  8. "github.com/jcmturner/gofork/encoding/asn1"
  9. "github.com/jcmturner/gokrb5/v8/iana/addrtype"
  10. )
  11. /*
  12. HostAddress and HostAddresses
  13. HostAddress ::= SEQUENCE {
  14. addr-type [0] Int32,
  15. address [1] OCTET STRING
  16. }
  17. -- NOTE: HostAddresses is always used as an OPTIONAL field and
  18. -- should not be empty.
  19. HostAddresses -- NOTE: subtly different from rfc1510,
  20. -- but has a value mapping and encodes the same
  21. ::= SEQUENCE OF HostAddress
  22. The host address encodings consist of two fields:
  23. addr-type
  24. This field specifies the type of address that follows. Pre-
  25. defined values for this field are specified in Section 7.5.3.
  26. address
  27. This field encodes a single address of type addr-type.
  28. */
  29. // HostAddresses implements RFC 4120 type: https://tools.ietf.org/html/rfc4120#section-5.2.5
  30. type HostAddresses []HostAddress
  31. // HostAddress implements RFC 4120 type: https://tools.ietf.org/html/rfc4120#section-5.2.5
  32. type HostAddress struct {
  33. AddrType int32 `asn1:"explicit,tag:0"`
  34. Address []byte `asn1:"explicit,tag:1"`
  35. }
  36. // GetHostAddress returns a HostAddress struct from a string in the format <hostname>:<port>
  37. func GetHostAddress(s string) (HostAddress, error) {
  38. var h HostAddress
  39. cAddr, _, err := net.SplitHostPort(s)
  40. if err != nil {
  41. return h, fmt.Errorf("invalid format of client address: %v", err)
  42. }
  43. ip := net.ParseIP(cAddr)
  44. var ht int32
  45. if ip.To4() != nil {
  46. ht = addrtype.IPv4
  47. ip = ip.To4()
  48. } else if ip.To16() != nil {
  49. ht = addrtype.IPv6
  50. ip = ip.To16()
  51. } else {
  52. return h, fmt.Errorf("could not determine client's address types: %v", err)
  53. }
  54. h = HostAddress{
  55. AddrType: ht,
  56. Address: ip,
  57. }
  58. return h, nil
  59. }
  60. // GetAddress returns a string representation of the HostAddress.
  61. func (h *HostAddress) GetAddress() (string, error) {
  62. var b []byte
  63. _, err := asn1.Unmarshal(h.Address, &b)
  64. return string(b), err
  65. }
  66. // LocalHostAddresses returns a HostAddresses struct for the local machines interface IP addresses.
  67. func LocalHostAddresses() (ha HostAddresses, err error) {
  68. ifs, err := net.Interfaces()
  69. if err != nil {
  70. return
  71. }
  72. for _, iface := range ifs {
  73. if iface.Flags&net.FlagLoopback != 0 || iface.Flags&net.FlagUp == 0 {
  74. // Interface is either loopback of not up
  75. continue
  76. }
  77. addrs, err := iface.Addrs()
  78. if err != nil {
  79. continue
  80. }
  81. for _, addr := range addrs {
  82. var ip net.IP
  83. switch v := addr.(type) {
  84. case *net.IPNet:
  85. ip = v.IP
  86. case *net.IPAddr:
  87. ip = v.IP
  88. }
  89. var a HostAddress
  90. if ip.To16() == nil {
  91. //neither IPv4 or IPv6
  92. continue
  93. }
  94. if ip.To4() != nil {
  95. //Is IPv4
  96. a.AddrType = addrtype.IPv4
  97. a.Address = ip.To4()
  98. } else {
  99. a.AddrType = addrtype.IPv6
  100. a.Address = ip.To16()
  101. }
  102. ha = append(ha, a)
  103. }
  104. }
  105. return ha, nil
  106. }
  107. // HostAddressesFromNetIPs returns a HostAddresses type from a slice of net.IP
  108. func HostAddressesFromNetIPs(ips []net.IP) (ha HostAddresses) {
  109. for _, ip := range ips {
  110. ha = append(ha, HostAddressFromNetIP(ip))
  111. }
  112. return ha
  113. }
  114. // HostAddressFromNetIP returns a HostAddress type from a net.IP
  115. func HostAddressFromNetIP(ip net.IP) HostAddress {
  116. if ip.To4() != nil {
  117. //Is IPv4
  118. return HostAddress{
  119. AddrType: addrtype.IPv4,
  120. Address: ip.To4(),
  121. }
  122. }
  123. return HostAddress{
  124. AddrType: addrtype.IPv6,
  125. Address: ip.To16(),
  126. }
  127. }
  128. // HostAddressesEqual tests if two HostAddress slices are equal.
  129. func HostAddressesEqual(h, a []HostAddress) bool {
  130. if len(h) != len(a) {
  131. return false
  132. }
  133. for _, e := range a {
  134. var found bool
  135. for _, i := range h {
  136. if e.Equal(i) {
  137. found = true
  138. break
  139. }
  140. }
  141. if !found {
  142. return false
  143. }
  144. }
  145. return true
  146. }
  147. // HostAddressesContains tests if a HostAddress is contained in a HostAddress slice.
  148. func HostAddressesContains(h []HostAddress, a HostAddress) bool {
  149. for _, e := range h {
  150. if e.Equal(a) {
  151. return true
  152. }
  153. }
  154. return false
  155. }
  156. // Equal tests if the HostAddress is equal to another HostAddress provided.
  157. func (h *HostAddress) Equal(a HostAddress) bool {
  158. if h.AddrType != a.AddrType {
  159. return false
  160. }
  161. return bytes.Equal(h.Address, a.Address)
  162. }
  163. // Contains tests if a HostAddress is contained within the HostAddresses struct.
  164. func (h *HostAddresses) Contains(a HostAddress) bool {
  165. for _, e := range *h {
  166. if e.Equal(a) {
  167. return true
  168. }
  169. }
  170. return false
  171. }
  172. // Equal tests if a HostAddress slice is equal to the HostAddresses struct.
  173. func (h *HostAddresses) Equal(a []HostAddress) bool {
  174. if len(*h) != len(a) {
  175. return false
  176. }
  177. for _, e := range a {
  178. if !h.Contains(e) {
  179. return false
  180. }
  181. }
  182. return true
  183. }