Skip to content

Instantly share code, notes, and snippets.

@reidstidolph
Last active December 10, 2018 03:39
Show Gist options
  • Save reidstidolph/5fbe75aa14e68604e0b3408ac892b22d to your computer and use it in GitHub Desktop.
Save reidstidolph/5fbe75aa14e68604e0b3408ac892b22d to your computer and use it in GitHub Desktop.
Grabs arp entries from a 128T host, along with a published device OUI listing. It then records MAC addresses and vendors to a CSV file.
#!/usr/bin/env node
"use strict";
/*
Grabs text file containing registered OUI listing, along with all entries from
ARP caches available to a 128T host. It then records MAC addresses and vendors
to a csv file.
*/
const fs = require('fs')
const https = require('https')
const http = require('http')
const authToken = '<my_token_string>'
const t128HostAddress = '<my_128T_host>'
const ouiUrl = 'http://standards-oui.ieee.org/oui.txt'
const outputFile = 'arp.csv'
var ouiDb = {}
function getArp() {
var graphqlQuery = {
query: `query getArp($filterNodes: [String], $filterRouters: [String]) {
allRouters(names: $filterRouters) {
nodes {
name
nodes(names: $filterNodes) {
nodes {
_id
name
arp {
networkInterface
ipAddress
destinationMac
state
}
}
}
}
}
}`,
variables: null,
operationName: 'getArp'
}
const options = {
host : t128HostAddress,
port : 443,
path : '/api/v1/graphql',
method : 'POST',
rejectUnauthorized : false,
headers : {
'Content-Type' : 'application/json',
'Content-Length' : Buffer.byteLength(JSON.stringify(graphqlQuery), 'utf8'),
'Authorization' : `Bearer ${authToken}`,
'Accept' : 'application/json'
}
}
var req = https.request(options, (res) => {
var responseData = ''
var fileOutputString = ''
res.setEncoding('utf8')
res.on('data', (resDataChunk) => {
responseData += resDataChunk
})
res.on('end', () => {
var arpResultsGraph = JSON.parse(responseData).data.allRouters.nodes
//process.stdout.write(`Router,Node,Interface,IP,MAC,State,Vendor\n`)
fileOutputString += `Router,Node,Interface,IP,MAC,State,Vendor\n`
arpResultsGraph.forEach((router) => {
if (router.nodes.nodes instanceof Array) {
router.nodes.nodes.forEach((t128node) => {
if (t128node.arp instanceof Array) {
t128node.arp.forEach((arpEntry) => {
var ouiKey = arpEntry.destinationMac.slice(0, 8).toUpperCase().replace(/:/g, '')
var vendor = 'Unknown'
if (ouiDb[ouiKey]) {
vendor = ouiDb[ouiKey]
}
//process.stdout.write(`${router.name},${t128node.name},${arpEntry.networkInterface},${arpEntry.ipAddress},${arpEntry.destinationMac},${arpEntry.state},${vendor}\n`)
fileOutputString += `${router.name},${t128node.name},${arpEntry.networkInterface},${arpEntry.ipAddress},${arpEntry.destinationMac},${arpEntry.state},${vendor}\n`
})
}
})
}
})
// write json to disk
fs.writeFile(`./${outputFile}`, fileOutputString, (err) => {
if (err) {
console.error(err)
return
}
console.log(`Results recorded to '${outputFile}'.`);
})
})
})
req.write(JSON.stringify(graphqlQuery))
req.on('error', (error) => {
console.log('debug', 'REST request failed:', error)
});
req.end()
}
function getOuiDb(){
// fetch OUI list
console.log('Fetching OUI database...')
http.get(ouiUrl, (res) => {
const { statusCode } = res
const contentType = res.headers['content-type']
let error
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`)
} else if (!/^text\/plain/.test(contentType)) {
error = new Error('Invalid content-type.\n' +
`Expected test/plain but received ${contentType}`)
}
if (error) {
console.error(error.message)
res.resume()
return;
}
res.setEncoding('utf8')
let rawData = ''
res.on('data', (chunk) => { rawData += chunk; })
res.on('end', () => {
var regexp = /[0-9a-fA-F]{6}\s+\(base 16\)\s+\S+.*[\n\r]/gi
var ouiStringArray = rawData.match(regexp)
ouiStringArray.forEach((ouiString) => {
ouiString = ouiString.trim()
var ouiStringRegex = /(^[0-9a-fA-F]{6})\s+\(base 16\)\s+(\S+.*)$/.exec(ouiString)
var ouiMAC = ouiStringRegex[1]
var ouiVendor = ouiStringRegex[2]
if (!ouiDb[ouiMAC]) {
ouiDb[ouiMAC] = ouiVendor
} else {
// uncomment these if you want to see duplicates in the OUI listing.
//console.log(`WARNING: ${ouiMAC} already processed.`)
//console.log(` Keeping value: ${ouiDb[ouiMAC]}`)
//console.log(` Dropping value: ${ouiVendor}`)
}
})
console.log('OUI database downloaded. Getting ARP entries...')
getArp()
})
}).on('error', (e) => {
console.error(`Got error: ${e.message}`)
})
}
// begin
getOuiDb()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment