107 lines
1.9 KiB
Go
107 lines
1.9 KiB
Go
package host
|
|
|
|
import (
|
|
"lux/proto"
|
|
"net"
|
|
"net/netip"
|
|
)
|
|
|
|
// Option containing all network interfaces of host (excluding loopbacks)
|
|
|
|
// IPv6 GUA
|
|
// IPv6 ULA
|
|
// IPv6 LL
|
|
// IPv4
|
|
|
|
type LuxNetAddrType int
|
|
|
|
const (
|
|
LuxNetAddrType4 = 0
|
|
LuxNetAddrType6LL = 1
|
|
LuxNetAddrType6ULA = 2
|
|
LuxNetAddrType6GUA = 3
|
|
)
|
|
|
|
type LuxNetAddr struct {
|
|
Type LuxNetAddrType
|
|
Addr netip.Addr
|
|
}
|
|
|
|
type LuxNetInterface struct {
|
|
Name string
|
|
Index int
|
|
Addrs []LuxNetAddr
|
|
}
|
|
|
|
func NewLuxNetInterface(netif *net.Interface) (LuxNetInterface, error) {
|
|
luxNet := LuxNetInterface{
|
|
Name: netif.Name,
|
|
Index: netif.Index,
|
|
Addrs: make([]LuxNetAddr, 0),
|
|
}
|
|
|
|
// enumerate interface ips
|
|
addrs, err := netif.Addrs()
|
|
if err != nil {
|
|
return luxNet, err
|
|
}
|
|
|
|
for _, addr := range addrs {
|
|
ip := net.ParseIP(addr.String())
|
|
if ip == nil {
|
|
return luxNet, err
|
|
}
|
|
|
|
luxAddr := LuxNetAddr{}
|
|
if ip.IsLoopback() {
|
|
continue // loopbacks are useless to LUX
|
|
} else if ip.To4() == nil {
|
|
// got IPv6
|
|
if ip.IsLinkLocalUnicast() {
|
|
luxAddr.Type = LuxNetAddrType6LL
|
|
} else if ip[0] == 0xFD || ip[0] == 0xFC {
|
|
// ULA - fc00::/7 with L = 1 -> fd00::/8,
|
|
// tho fc L 0 is not defined we still gonna assume its ULA
|
|
luxAddr.Type = LuxNetAddrType6ULA
|
|
} else {
|
|
// anything else is global unicast
|
|
luxAddr.Type = LuxNetAddrType6GUA
|
|
}
|
|
} else {
|
|
// got IPv4
|
|
luxAddr.Type = LuxNetAddrType4
|
|
}
|
|
|
|
luxAddr.Addr = proto.LuxProtoIPToAddr(ip)
|
|
|
|
luxNet.Addrs = append(luxNet.Addrs, luxAddr)
|
|
}
|
|
|
|
return luxNet, nil
|
|
}
|
|
|
|
type LuxOptionNetIf struct {
|
|
Interfaces map[string]*LuxNetInterface
|
|
}
|
|
|
|
func EnumerateLuxNetInterfaces() (LuxOptionNetIf, error) {
|
|
opt := LuxOptionNetIf{
|
|
make(map[string]*LuxNetInterface),
|
|
}
|
|
|
|
ifaces, err := net.Interfaces()
|
|
if err != nil {
|
|
return opt, err
|
|
}
|
|
|
|
for _, iface := range ifaces {
|
|
netif, err := NewLuxNetInterface(&iface)
|
|
if err != nil {
|
|
return opt, nil
|
|
}
|
|
|
|
opt.Interfaces[netif.Name] = &netif
|
|
}
|
|
|
|
return opt, nil
|
|
}
|