Skip to content

Instantly share code, notes, and snippets.

@smockle
Created February 5, 2019 06:40
Show Gist options
  • Save smockle/b3b38700aa67340a8b101a8a702452fe to your computer and use it in GitHub Desktop.
Save smockle/b3b38700aa67340a8b101a8a702452fe to your computer and use it in GitHub Desktop.
Merge the results of `arp -a` with known device information for improved output
#!/usr/bin/env node
// @ts-check
const fs = require("fs");
const { spawn } = require("child_process");
const ipAddressRegExp = /\((?<ipAddress>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\)/;
const macAddressRegExp = /(?<macAddress>[a-fA-F\d]{1,2}:[a-fA-F\d]{1,2}:[a-fA-F\d]{1,2}:[a-fA-F\d]{1,2}:[a-fA-F\d]{1,2}:[a-fA-F\d]{1,2})/;
function normalizeMACAddress(macAddress) {
return macAddress
.split(":")
.reduce((macAddress, p) => {
const pair = p.length === 2 ? p : `0${p}`;
return macAddress.concat(pair.toUpperCase());
}, [])
.join(":");
}
function deviceFromCSV(str) {
const arr = str.trim().split(",");
return {
device: arr[0],
location: arr[1],
connection: arr[2].toLowerCase(),
macAddress: normalizeMACAddress(arr[3]),
ipAddress: arr[4]
};
}
const knownDevices = fs
.readFileSync("./internet.csv", "utf8")
.split("\n")
.map(deviceFromCSV);
function deviceFromARP(str) {
const arr = str.trim().split(" ");
const macAddress = macAddressRegExp.exec(arr[3]);
const ipAddress = ipAddressRegExp.exec(arr[1]);
return {
...(arr[0] !== "?" ? { hostname: arr[0] } : {}),
macAddress:
macAddress && macAddress.groups
? normalizeMACAddress(macAddress.groups.macAddress)
: null,
ipAddress: ipAddress && ipAddress.groups ? ipAddress.groups.ipAddress : null
};
}
const arp = spawn("arp", ["-a"]);
arp.stdout.on("data", data => {
const arpDevices = data
.toString()
.split("\n")
.map(deviceFromARP)
.filter(({ ipAddress, macAddress }) => ipAddress && macAddress)
.filter(
({ ipAddress, macAddress }) =>
ipAddress.startsWith("192.168") && macAddress !== "FF:FF:FF:FF:FF:FF"
);
const mergedDevices = arpDevices.map(arpDevice => {
const knownDevice = knownDevices.find(
({ macAddress }) => macAddress === arpDevice.macAddress
);
return {
...knownDevice,
...arpDevice
};
});
console.log(mergedDevices);
});
arp.stderr.on("data", data => console.error(data.toString()));
arp.on("close", code => code !== 0 && process.exit(code));
Clay’s iPhone Portable Wireless FF:FF:FF:FF:FF:FF DHCP
Apple TV Media Center Wired FF:FF:FF:FF:FF:FF 192.168.1.10
Xbox One Media Center Wired FF:FF:FF:FF:FF:FF DHCP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment