//go:build windows package deploy import ( "net" "os/exec" "strings" ) // arpHosts returns the list of IPv4 hosts currently in the OS ARP cache // that share a subnet with one of our local interfaces. These are machines // that have recently communicated on the LAN — a far smaller and more // targeted set than a blind /24 sweep. // // Falls back to nil (caller will do a full scan) on any error. func arpHosts() []string { out, err := exec.Command("arp", "-a").Output() if err != nil { return nil } local := getLocalIPs() subnets := make(map[string]bool) for _, ip := range local { subnets[getSubnet(ip)] = true } var hosts []string seen := make(map[string]bool) for _, line := range strings.Split(string(out), "\n") { line = strings.TrimSpace(line) // arp -a lines look like: // 192.168.1.1 00-11-22-33-44-55 dynamic fields := strings.Fields(line) if len(fields) < 2 { continue } ip := net.ParseIP(fields[0]) if ip == nil || ip.To4() == nil || ip.IsLoopback() || ip.IsMulticast() { continue } ipStr := ip.To4().String() sub := getSubnet(ipStr) if !subnets[sub] || seen[ipStr] { continue } seen[ipStr] = true hosts = append(hosts, ipStr) } return hosts }