Skip to content

feat(devices): MAC addresses and makers on the local network, and devices that moved - #104

Merged
Wasabules merged 1 commit into
mainfrom
feat-device-mac
Oct 27, 2026
Merged

Wasabules merged 1 commit into
mainfrom
feat-device-mac

Conversation

@Wasabules

Copy link
Copy Markdown
Owner

Stacked on #103 because they share generated files. It will be retargeted to main once #103 is merged.

A syslog message carries no MAC address. This adds the MAC wherever it helps, and says plainly that it is only known on the local network.

Where the MAC comes from

The new package internal/neighbors reads the system's neighbor table (ARP for IPv4, NDP for IPv6) every 30 seconds:

System How
Windows GetIpNetTable2 (iphlpapi), which x/sys/windows does not wrap. Checked on this machine against Get-NetNeighbor: same 9 IPv4 neighbors, same MACs.
Linux netlink RTM_GETNEIGH, IPv4 and IPv6
macOS the routing socket (RTF_LLINFO), via x/net/route
  • Local network only: the table only knows this machine's own networks. An address on none of them is routed, and gets no MAC rather than the router's, which is all the table would hold for it. This machine and loopback are reported as such.
  • No network traffic, no storage: nothing is sent to learn a MAC, and nothing is written to the database.
  • Makers: the IEEE's MA-L registry is embedded, reduced and gzipped (40,404 entries, 390 KB). tools/oui rebuilds it from oui.csv. A locally administered MAC (a phone's private address, a VM) is shown as private, with no maker.

In the application

  • Settings › Devices:
    • Under each address: its MAC and maker, or routed — no MAC, or this computer.
    • A note above the table says MACs are only known on the local network, and why.
    • The filter accepts a MAC or a maker.
  • Devices that moved: the inventory remembers the MACs each address had since the start.
    • MAC changed: the address's device changed (replaced, or two devices claiming one address).
    • also at …: the same MAC was heard at another address (DHCP).
    • When a rule names a device's old address and no rule names its new one, the line says so.
  • Suggested template: a new rule opened from the tab suggests the template the maker fits (a camera maker → Camera; Cisco or MikroTik → Sends no hostname). It is only a suggestion, applied with a click.
  • Message detail panel: the source's MAC and maker, or why there is none.
  • Anonymous mode replaces MACs (redactMAC).
  • LookupAddress on Backend: the inventory and the lookups are those of the engine that receives, so the service's when the window drives it.
  • The 8 languages, the user guide (Devices, MAC addresses — on the local network only), the README and the documentation page are updated. The message-detail screenshots are regenerated.

Tests

  • internal/neighbors:
    • MAC parsing in its usual spellings, and makers (a Freebox, Cisco, a private MAC);
    • which table entries are kept;
    • the lookup on and off the local network, and for this machine;
    • the table read on the machine running the tests.
  • Netlink decoding, on Linux.
  • internal/sources: the inventory's MAC history (a device that moved, an address that changed hands).
  • UI checked through the screenshot bridge, in both themes. The table first overflowed, so long maker names are cut and the button labels shortened.

Checked: go vet (Windows, Linux; macOS for internal/neighbors), staticcheck, go test -race ./..., svelte-check --fail-on-warnings, npm test, npm run build, the docs' links.

…ices that moved

A syslog message carries no MAC. The new internal/neighbors reads the
system's neighbor table - ARP and NDP - every 30 seconds: GetIpNetTable2
on Windows (checked against Get-NetNeighbor), netlink on Linux, the
routing socket on macOS. That table only knows this machine's own
networks: an address on none of them is routed, and is given no MAC
rather than the router's. This machine and loopback are said so.
Nothing is sent on the network, nothing is stored.

- Makers come from the IEEE's MA-L registry, embedded reduced and
  gzipped (40,404 entries, 390 KB; tools/oui rebuilds it from oui.csv).
  A locally administered MAC (a phone's private address, a VM) is said
  to be private, with no maker.
- Settings > Devices shows each device's MAC and maker under its
  address, or "routed - no MAC", and a note saying plainly that MACs are
  only known on the local network. Its filter takes a MAC or a maker.
- The inventory remembers the MACs each address had since the start:
  "MAC changed" for an address whose device changed (replaced, or two
  claiming it), "also at ..." for a MAC heard at another address (DHCP),
  and the rule that names a device's old address when none names its
  new one.
- A new rule from the tab suggests the template the maker fits (a camera
  maker: Camera; Cisco, MikroTik: Sends no hostname), never applied
  without a click.
- The detail panel of a message gives its source's MAC and maker, or
  why there is none. Anonymous mode replaces MACs (redactMAC).
- LookupAddress on Backend; the inventory and the lookups are those of
  the engine that receives, the service's when the window drives it.

Tests: MAC parsing in its usual spellings, makers, what the table
keeps, the lookup on and off the local network and for this machine,
the netlink parsing (Linux), the table read here, and the inventory's
MAC history.
@Wasabules
Wasabules changed the base branch from fix-encryption-left-clear to main October 27, 2026 12:20
@Wasabules Wasabules closed this Oct 27, 2026
@Wasabules Wasabules reopened this Oct 27, 2026
@Wasabules
Wasabules merged commit feb385c into main Oct 27, 2026
14 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant