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 }