The ARP table
File: src/topics/arp.j. Path: /ip/arp (ARP_PATH). Reference: cheatsheet.
The ARP table maps IP addresses to MAC addresses on the router's connected networks. It serves two purposes:
- an inventory: every device the router recently exchanged packets with is listed, so it answers "who is on this LAN right now";
- an access control: static (pinned) entries, combined with the interface property
arp=reply-only, let only pinned devices talk.
Dynamic entries are learned and age out; static entries stay until removed. complete == false means the router asked and got no answer, usually an offline device. macForAddress returns "" on a miss instead of throwing, because a miss is normal.
Examples
List one interface's neighbours:
def neighbours as list of mt.ArpEntry init mt.arpTableOn($c, "brlan");
for (def n in $neighbours) {
io.printf("%s -> %s dynamic=%t complete=%t\n",
$n.address, $n.mac, $n.dynamic, $n.complete);
}Look a device up both ways:
def mac as string init mt.macForAddress($c, "192.168.88.50");
if ($mac == "") {
io.printf("the printer has not talked to the router recently\n");
}
def addrs as list of string init mt.addressesForMac($c, "AA:BB:CC:DD:EE:FF");
for (def a in $addrs) {
io.printf("that device holds %s\n", $a);
}Lock a LAN to pinned devices. arp is an interface property, so it is set with the generic verb:
mt.addStaticArp($c, "192.168.88.50", "AA:BB:CC:DD:EE:FF", "brlan");
mt.addStaticArp($c, "192.168.88.51", "11:22:33:44:55:66", "brlan");
mt.set($c, mt.INTERFACE_PATH,
mt.idByName($c, mt.INTERFACE_PATH, "brlan"), {"arp": "reply-only"});After a device changed hardware but kept its IP, remove the stale entry (and re-pin a static one with the new MAC):
mt.removeArpEntry($c, "192.168.88.50");Pitfalls
- Only layer-2 neighbours appear. Devices behind another router are never in the table.
- The table is a cache: absence proves nothing, presence proves recent traffic.
arp=reply-onlycuts off every device not pinned, possibly including your management host. Pin first, switch second.- Static ARP protects the router's view only; it does not stop spoofing between other hosts on the segment.
- The DHCP server can add ARP entries for its leases (
add-arp, set with the generic verbs), which pairs witharp=reply-only.
See also: dhcp.md, interfaces.md, wireless.md (wifiClients lists WiFi clients).