diff options
| author | Elizabeth Alexander Hunt <me@liz.coffee> | 2026-06-20 09:40:07 -0700 |
|---|---|---|
| committer | Elizabeth Alexander Hunt <me@liz.coffee> | 2026-06-20 09:40:07 -0700 |
| commit | fb653292612eddca5b088ed88466c546d1597107 (patch) | |
| tree | 900ed32e066812688858ed3bb15128c41bb78054 /adapters/arp/arp.go | |
| download | penguins.lan-fb653292612eddca5b088ed88466c546d1597107.tar.gz penguins.lan-fb653292612eddca5b088ed88466c546d1597107.zip | |
Initial commit
Diffstat (limited to 'adapters/arp/arp.go')
| -rw-r--r-- | adapters/arp/arp.go | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/adapters/arp/arp.go b/adapters/arp/arp.go new file mode 100644 index 0000000..19d7632 --- /dev/null +++ b/adapters/arp/arp.go @@ -0,0 +1,63 @@ +package arp + +import ( + "os/exec" + "regexp" + "strings" + + "penguins.lan/utils" +) + +type ArpTable struct { + AddrToMac map[utils.INet4]utils.Mac +} + +// Lookup returns the canonical MAC for an IPv4 string, false if it isn't in the +// table or isn't parseable IPv4 (e.g. an IPv6 peer). +func (t *ArpTable) Lookup(ip string) (string, bool) { + addr, err := utils.ParseINet4(ip) + if err != nil { + return "", false + } + mac, ok := t.AddrToMac[*addr] + if !ok { + return "", false + } + return mac.Format(), true +} + +type TableProvider interface { + Fetch() (*ArpTable, error) +} + +var arpLine = regexp.MustCompile(`\((\d{1,3}(?:\.\d{1,3}){3})\) at ([0-9a-fA-F]{1,2}(?::[0-9a-fA-F]{1,2}){5})`) + +type SystemProvider struct{} + +func (SystemProvider) Fetch() (*ArpTable, error) { + out, err := exec.Command("arp", "-an").Output() + if err != nil { + return nil, err + } + return parseTable(string(out)), nil +} + +func parseTable(out string) *ArpTable { + table := &ArpTable{AddrToMac: make(map[utils.INet4]utils.Mac)} + for _, line := range strings.Split(out, "\n") { + m := arpLine.FindStringSubmatch(line) + if m == nil { + continue + } + addr, err := utils.ParseINet4(m[1]) + if err != nil { + continue + } + mac, err := utils.ParseMac(m[2]) + if err != nil { + continue + } + table.AddrToMac[*addr] = *mac + } + return table +} |
