Skip to content

See what changed on the network in a window

  • “What showed up on the network over the long weekend?”
  • “A device went missing from a closet. When did we last see it, and where?”
  • “Security wants every IP that changed hands this week, especially the suspicious ones.”

Where trace-diff answers “did this one path change,” Changes answers “what changed anywhere.” Both draw on the same bitemporal log; see What the bitemporal log makes discoverable for the concept.

Open Changes in the web UI and pick a window (24 hours, 7 days, or 30 days). Four sections fill in:

  • Moved — a MAC now on a different (switch, port) than before, with its old and new location and the time of the move.
  • New devices — MACs seen for the first time, named by OUI vendor, with their IP and access port.
  • Removed — MACs that aged out and did not come back, with their last location and time.
  • IP rebindings — an IP that bound to a different MAC. Rows where the vendor changed are flagged and sorted to the top: a DHCP renewal keeps the same MAC and vendor, so a different-vendor MAC on an IP is the takeover/spoof signal worth a second look.

Empty sections say so rather than showing a blank table.

From the API (for automation and alerting)

Section titled “From the API (for automation and alerting)”

The same data is one request, so a cron or a SIEM feed can pull it without the UI:

Terminal window
curl -s "https://l2trace.example.net/api/changes?since=now-7d&until=now&limit=1000"

since and until take ISO-8601 or a relative window (now-7d, now-24h). The response has four arrays:

{
"moves": [{ "mac", "vlan", "moved_at", "was_at",
"from_switch", "from_port", "to_switch", "to_port", "oui_vendor" }],
"appeared": [{ "mac", "first_seen", "vlan", "switch", "port", "ip", "oui_vendor" }],
"disappeared": [{ "mac", "last_seen", "vlan", "switch", "port", "oui_vendor" }],
"ip_rebindings":[{ "ip", "mac", "prev_mac", "rebound_at", "prev_bound_at",
"gap_seconds", "new_vendor", "prev_vendor", "vendor_changed" }]
}

The takeover-review feed is just the rebindings with vendor_changed: true:

Terminal window
curl -s ".../api/changes?since=now-7d&until=now" \
| jq '.ip_rebindings[] | select(.vendor_changed)'

The change counts reflect observations, not ground truth about devices. If collection was paused during the window (a maintenance window, a poller outage), MACs age out and then re-learn, which inflates the appeared and removed counts for that period. This is the bitemporal log behaving correctly: it records that the observations stopped and restarted, not that the devices left and returned. When a window overlaps a known collection gap, weigh the totals accordingly.