-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaddrs.go
160 lines (131 loc) · 3.09 KB
/
addrs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package core
import (
"net"
"net/netip"
)
// GetStringIPAddresses returns a list of text IP addresses bound
// to the given interfaces or all if none are given
func GetStringIPAddresses(ifaces ...string) ([]string, error) {
addrs, err := GetIPAddresses(ifaces...)
out := asStringIPAddresses(addrs...)
return out, err
}
func asStringIPAddresses(addrs ...netip.Addr) []string {
out := make([]string, 0, len(addrs))
for _, addr := range addrs {
if addr.IsValid() {
s := addr.String()
out = append(out, s)
}
}
return out
}
// GetNetIPAddresses returns a list of net.IP addresses bound to
// the given interfaces or all if none are given
func GetNetIPAddresses(ifaces ...string) ([]net.IP, error) {
addrs, err := GetIPAddresses(ifaces...)
out := asNetIPAddresses(addrs...)
return out, err
}
func asNetIPAddresses(addrs ...netip.Addr) []net.IP {
out := make([]net.IP, 0, len(addrs))
for _, addr := range addrs {
if addr.IsValid() {
out = append(out, asNetIP(addr.Unmap()))
}
}
return out
}
func asNetIP(addr netip.Addr) net.IP {
if addr.Is4() {
a4 := addr.As4()
return a4[:]
}
a16 := addr.As16()
return a16[:]
}
// GetIPAddresses returns a list of netip.Addr bound to the given
// interfaces or all if none are given
func GetIPAddresses(ifaces ...string) ([]netip.Addr, error) {
var out []netip.Addr
if len(ifaces) == 0 {
// all addresses
addrs, err := net.InterfaceAddrs()
out = appendNetIPAsIP(out, addrs...)
return out, err
}
// only given
for _, name := range ifaces {
ifi, err := net.InterfaceByName(name)
if err != nil {
return out, err
}
addrs, err := ifi.Addrs()
if err != nil {
return out, err
}
out = appendNetIPAsIP(out, addrs...)
}
return out, nil
}
func appendNetIPAsIP(out []netip.Addr, addrs ...net.Addr) []netip.Addr {
for _, ip := range addrs {
addr, ok := AddrFromNetIP(ip)
if ok && addr.IsValid() {
out = append(out, addr.Unmap())
}
}
return out
}
// AddrFromNetIP attempts to convert a net.Addr into a netip.Addr
func AddrFromNetIP(addr net.Addr) (netip.Addr, bool) {
var s []byte
switch v := addr.(type) {
case *net.IPAddr:
s = v.IP
case *net.IPNet:
s = v.IP
}
return netip.AddrFromSlice(s)
}
// GetInterfacesNames returns the list of interfaces,
// considering an optional exclusion list
func GetInterfacesNames(except ...string) ([]string, error) {
s, err := net.Interfaces()
if err != nil {
return nil, err
}
out := make([]string, 0, len(s))
for _, ifi := range s {
if s := ifi.Name; s != "" {
out = append(out, s)
}
}
if len(except) > 0 {
out = SliceMinus(out, except)
}
return out, nil
}
// ParseAddr turns a string into netip.Addr
func ParseAddr(s string) (addr netip.Addr, err error) {
switch s {
case "0":
addr = netip.IPv4Unspecified()
case "::":
addr = netip.IPv6Unspecified()
default:
addr, err = netip.ParseAddr(s)
if err != nil {
return addr, err
}
}
return addr, nil
}
// ParseNetIP turns a string into a net.IP
func ParseNetIP(s string) (ip net.IP, err error) {
addr, err := ParseAddr(s)
if err != nil {
return nil, err
}
return asNetIP(addr.Unmap()), nil
}