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