HostAddress.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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. "gopkg.in/jcmturner/gokrb5.v6/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. hb, err := ip.MarshalText()
  45. if err != nil {
  46. return h, fmt.Errorf("could not marshal client's address into bytes: %v", err)
  47. }
  48. var ht int32
  49. if ip.To4() != nil {
  50. ht = addrtype.IPv4
  51. } else if ip.To16() != nil {
  52. ht = addrtype.IPv6
  53. } else {
  54. return h, fmt.Errorf("could not determine client's address types: %v", err)
  55. }
  56. h = HostAddress{
  57. AddrType: ht,
  58. Address: hb,
  59. }
  60. return h, nil
  61. }
  62. // GetAddress returns a string representation of the HostAddress.
  63. func (h *HostAddress) GetAddress() (string, error) {
  64. var b []byte
  65. _, err := asn1.Unmarshal(h.Address, &b)
  66. return string(b), err
  67. }
  68. // LocalHostAddresses returns a HostAddresses struct for the local machines interface IP addresses.
  69. func LocalHostAddresses() (ha HostAddresses, err error) {
  70. ifs, err := net.Interfaces()
  71. if err != nil {
  72. return
  73. }
  74. for _, iface := range ifs {
  75. if iface.Flags&net.FlagLoopback != 0 || iface.Flags&net.FlagUp == 0 {
  76. // Interface is either loopback of not up
  77. continue
  78. }
  79. addrs, err := iface.Addrs()
  80. if err != nil {
  81. continue
  82. }
  83. for _, addr := range addrs {
  84. var ip net.IP
  85. switch v := addr.(type) {
  86. case *net.IPNet:
  87. ip = v.IP
  88. case *net.IPAddr:
  89. ip = v.IP
  90. }
  91. var a HostAddress
  92. if ip.To16() == nil {
  93. //neither IPv4 or IPv6
  94. continue
  95. }
  96. if ip.To4() != nil {
  97. //Is IPv4
  98. a.AddrType = addrtype.IPv4
  99. a.Address = ip.To4()
  100. } else {
  101. a.AddrType = addrtype.IPv6
  102. a.Address = ip.To16()
  103. }
  104. ha = append(ha, a)
  105. }
  106. }
  107. return ha, nil
  108. }
  109. // HostAddressesFromNetIPs returns a HostAddresses type from a slice of net.IP
  110. func HostAddressesFromNetIPs(ips []net.IP) (ha HostAddresses) {
  111. for _, ip := range ips {
  112. ha = append(ha, HostAddressFromNetIP(ip))
  113. }
  114. return ha
  115. }
  116. // HostAddressFromNetIP returns a HostAddress type from a net.IP
  117. func HostAddressFromNetIP(ip net.IP) HostAddress {
  118. if ip.To4() != nil {
  119. //Is IPv4
  120. return HostAddress{
  121. AddrType: addrtype.IPv4,
  122. Address: ip.To4(),
  123. }
  124. }
  125. return HostAddress{
  126. AddrType: addrtype.IPv6,
  127. Address: ip.To16(),
  128. }
  129. }
  130. // HostAddressesEqual tests if two HostAddress slices are equal.
  131. func HostAddressesEqual(h, a []HostAddress) bool {
  132. if len(h) != len(a) {
  133. return false
  134. }
  135. for _, e := range a {
  136. var found bool
  137. for _, i := range h {
  138. if e.Equal(i) {
  139. found = true
  140. break
  141. }
  142. }
  143. if !found {
  144. return false
  145. }
  146. }
  147. return true
  148. }
  149. // HostAddressesContains tests if a HostAddress is contained in a HostAddress slice.
  150. func HostAddressesContains(h []HostAddress, a HostAddress) bool {
  151. for _, e := range h {
  152. if e.Equal(a) {
  153. return true
  154. }
  155. }
  156. return false
  157. }
  158. // Equal tests if the HostAddress is equal to another HostAddress provided.
  159. func (h *HostAddress) Equal(a HostAddress) bool {
  160. if h.AddrType != a.AddrType {
  161. return false
  162. }
  163. return bytes.Equal(h.Address, a.Address)
  164. }
  165. // Contains tests if a HostAddress is contained within the HostAddresses struct.
  166. func (h *HostAddresses) Contains(a HostAddress) bool {
  167. for _, e := range *h {
  168. if e.Equal(a) {
  169. return true
  170. }
  171. }
  172. return false
  173. }
  174. // Equal tests if a HostAddress slice is equal to the HostAddresses struct.
  175. func (h *HostAddresses) Equal(a []HostAddress) bool {
  176. if len(*h) != len(a) {
  177. return false
  178. }
  179. for _, e := range a {
  180. if !h.Contains(e) {
  181. return false
  182. }
  183. }
  184. return true
  185. }