lux/host/lux_netif.go
2025-01-27 00:52:41 +02:00

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
}