//go:build linux package resolve import ( "bufio" "io" "os" "strings" "git.ktf.ninja/tabledevil/gists/projects/go-tools/go/goipgrep/internal/normalize" ) type NeighborTable struct { ByMAC map[string][]string } func LoadNeighborTable() (*NeighborTable, error) { f, err := os.Open("/proc/net/arp") if err != nil { return nil, err } defer f.Close() return parseProcNetARP(f), nil } func ResolveMACs(macs []string) ([]MACResolution, error) { tab, err := LoadNeighborTable() if err != nil { return nil, err } var res []MACResolution for _, mac := range macs { res = append(res, MACResolution{MAC: mac, IPs: append([]string(nil), tab.ByMAC[mac]...)}) } return res, nil } type MACResolution struct { MAC string `json:"mac"` IPs []string `json:"ips,omitempty"` } func parseProcNetARP(r io.Reader) *NeighborTable { nt := &NeighborTable{ByMAC: make(map[string][]string)} sc := bufio.NewScanner(r) first := true for sc.Scan() { line := strings.TrimSpace(sc.Text()) if line == "" { continue } if first { // header first = false continue } fields := strings.Fields(line) if len(fields) < 4 { continue } ip := fields[0] macRaw := fields[3] mac, ok := normalize.NormalizeMAC(macRaw) if !ok { continue } // Skip incomplete/placeholder entries. if mac == "00:00:00:00:00:00" { continue } nt.ByMAC[mac] = append(nt.ByMAC[mac], ip) } return nt }