package hostmode import ( "bufio" "errors" "fmt" "os" "os/exec" "strings" ) // primaryMAC resolves the MAC of the iface that carries the default // IPv4 route. Mirrors quick.sh.tmpl's primary_iface so the agent // reports the same MAC that was registered (important on Proxmox // where vmbr0 inherits its physical NIC's MAC). func primaryMAC() (string, error) { iface, err := defaultRouteIface() if err != nil { return "", err } raw, err := os.ReadFile(fmt.Sprintf("/sys/class/net/%s/address", iface)) if err != nil { return "", fmt.Errorf("read mac for %s: %w", iface, err) } return strings.ToLower(strings.TrimSpace(string(raw))), nil } // defaultRouteIface shells out to `ip` because reading /proc/net/route // requires hex-swap logic and still misses the IPv4-only "dev" // qualification. The service runs as root on a Linux box; `ip` is // always present. func defaultRouteIface() (string, error) { out, err := exec.Command("ip", "-o", "-4", "route", "show", "default").Output() if err != nil { return "", fmt.Errorf("ip route: %w", err) } scan := bufio.NewScanner(strings.NewReader(string(out))) for scan.Scan() { fields := strings.Fields(scan.Text()) for i, f := range fields { if f == "dev" && i+1 < len(fields) { return fields[i+1], nil } } } return "", errors.New("no default IPv4 route") }