implement LuxOptionNetIf

This commit is contained in:
mykola2312 2025-01-27 02:14:36 +02:00
parent a31898c41d
commit d5860973bf
3 changed files with 144 additions and 18 deletions

View file

@ -1,9 +1,11 @@
package host
import (
"fmt"
"lux/proto"
"net"
"net/netip"
"strings"
)
// Option containing all network interfaces of host (excluding loopbacks)
@ -27,29 +29,61 @@ type LuxNetAddr struct {
Addr netip.Addr
}
func (addr *LuxNetAddr) Read(rd *proto.LuxBuffer) error {
addrType, err := rd.ReadUint16()
if err != nil {
return err
}
addr.Type = LuxNetAddrType(addrType)
ipAddr, err := rd.ReadIP()
if err != nil {
return err
}
addr.Addr = ipAddr
return nil
}
func (addr *LuxNetAddr) Write(wd *proto.LuxBuffer) {
wd.WriteUint16(uint16(addr.Type))
wd.WriteIP(addr.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,
func NewLuxNetInterface() LuxNetInterface {
return LuxNetInterface{
Addrs: make([]LuxNetAddr, 0),
}
}
func parseNetlinkIp(addr string) string {
if strings.ContainsRune(addr, '/') {
return strings.Split(addr, "/")[0]
}
return addr
}
func (luxNet *LuxNetInterface) FromNetlink(netif *net.Interface) error {
luxNet.Name = netif.Name
luxNet.Index = netif.Index
// enumerate interface ips
addrs, err := netif.Addrs()
if err != nil {
return luxNet, err
return err
}
for _, addr := range addrs {
ip := net.ParseIP(addr.String())
ip := net.ParseIP(parseNetlinkIp(addr.String()))
if ip == nil {
return luxNet, err
return err
}
luxAddr := LuxNetAddr{}
@ -77,31 +111,105 @@ func NewLuxNetInterface(netif *net.Interface) (LuxNetInterface, error) {
luxNet.Addrs = append(luxNet.Addrs, luxAddr)
}
return luxNet, nil
return nil
}
func (netif *LuxNetInterface) Read(rd *proto.LuxBuffer) error {
name, err := rd.ReadString()
if err != nil {
return err
}
netif.Name = name
idx, err := rd.ReadUint16()
if err != nil {
return err
}
netif.Index = int(idx)
addrNum, err := rd.ReadUint16()
if err != nil {
return err
}
for i := 0; i < int(addrNum); i++ {
addr := LuxNetAddr{}
if addr.Read(rd) != nil {
return err
}
netif.Addrs = append(netif.Addrs, addr)
}
return nil
}
func (netif *LuxNetInterface) Write(wd *proto.LuxBuffer) {
wd.WriteString(netif.Name)
wd.WriteUint16(uint16(netif.Index))
wd.WriteUint16(uint16(len(netif.Addrs)))
for _, addr := range netif.Addrs {
addr.Write(wd)
}
}
type LuxOptionNetIf struct {
Interfaces map[string]*LuxNetInterface
}
func EnumerateLuxNetInterfaces() (LuxOptionNetIf, error) {
opt := LuxOptionNetIf{
make(map[string]*LuxNetInterface),
func NewLuxOptionNetIf() LuxOptionNetIf {
return LuxOptionNetIf{
Interfaces: make(map[string]*LuxNetInterface),
}
}
func (opt *LuxOptionNetIf) EnumerateNetlink() error {
ifaces, err := net.Interfaces()
if err != nil {
return opt, err
return err
}
for _, iface := range ifaces {
netif, err := NewLuxNetInterface(&iface)
if err != nil {
return opt, nil
netif := NewLuxNetInterface()
if err := netif.FromNetlink(&iface); err != nil {
return nil
}
opt.Interfaces[netif.Name] = &netif
if len(netif.Addrs) > 0 {
// only add if we got atleast 1 ip, since we might want to skip
// netif loopback that has no IP because we skip one in FromNetlink
fmt.Println(netif)
opt.Interfaces[netif.Name] = &netif
}
}
return opt, nil
return nil
}
func (opt *LuxOptionNetIf) Read(rd *proto.LuxBuffer) error {
ifNum, err := rd.ReadUint16()
if err != nil {
return err
}
for i := 0; i < int(ifNum); i++ {
netif := NewLuxNetInterface()
if err := netif.Read(rd); err != nil {
return err
}
}
return nil
}
func (opt *LuxOptionNetIf) Write(wd *proto.LuxBuffer) {
wd.WriteUint16(uint16(len(opt.Interfaces)))
for _, netif := range opt.Interfaces {
netif.Write(wd)
}
}
func (*LuxOptionNetIf) Type() LuxOptionType {
return LuxOptionTypeNetIf
}

View file

@ -8,7 +8,8 @@ import (
type LuxOptionType uint
const (
LuxOptionTypeWAN = 0
LuxOptionTypeWAN = 0
LuxOptionTypeNetIf = 1
)
type LuxOption interface {
@ -30,6 +31,10 @@ func ReadLuxOption(rd *proto.LuxBuffer) (LuxOption, error) {
opt := &LuxOptionWAN{}
err = opt.Read(rd)
return opt, err
case LuxOptionTypeNetIf:
opt := NewLuxOptionNetIf()
err := opt.Read(rd)
return &opt, err
default:
return nil, fmt.Errorf("unknown option %d", optVal)
}

13
main.go
View file

@ -471,6 +471,17 @@ func (*HostIdentWAN) Provide() (host.LuxOption, error) {
return &wan, nil
}
type HostNetif struct{}
func (*HostNetif) Provide() (host.LuxOption, error) {
netif := host.NewLuxOptionNetIf()
if err := netif.EnumerateNetlink(); err != nil {
return nil, err
}
return &netif, nil
}
func hostMain() {
xmlBytes, err := os.ReadFile(configPath)
if err != nil {
@ -535,6 +546,8 @@ func hostMain() {
} else if wan.Method == "identme" {
host.AddOptionProvider(&HostIdentWAN{})
}
} else if option.Type == "netif" {
host.AddOptionProvider(&HostNetif{})
}
}