From 03a01c8c19b8c1279dc746a58da7bbc620d544b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Feh=C3=A9r=20Roland=20=C3=81d=C3=A1m?= Date: Thu, 11 Jun 2026 13:18:34 +0200 Subject: [PATCH] Too lazy to check what exactly I did since last commit --- .gitignore | 3 +- arpscan.sh | 60 +++++++++++++----- macvendor.json | 161 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 209 insertions(+), 15 deletions(-) create mode 100644 macvendor.json diff --git a/.gitignore b/.gitignore index b7d3f3e..c42b144 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ arpscan.json -nmaplog.txt +nmaplog.*.txt +devices/ diff --git a/arpscan.sh b/arpscan.sh index d34b265..905d75a 100755 --- a/arpscan.sh +++ b/arpscan.sh @@ -7,9 +7,7 @@ starttime="$(date '+%Y-%m-%d %H:%M:%S')" if [ -f arpscan.json ] then - #tempjson=$(jq '.ips += {} | .ips = ([ .ips | to_entries[] | select(.value.reserved == true) ] | from_entries)' arpscan.json) tempjson=$(jq '.ips += {} | .ips=(.ips|to_entries|map_values(.value.online=false)|from_entries)' arpscan.json) - #tempjson="$(cat arpscan.json)" if [ $? -ne 0 ] then echo "Failed to load network JSON" 1>&2 @@ -24,18 +22,18 @@ jsonescape() { } foundhost() { - tempjson=$(jq "$(jsonescape "${1}") as \$ip|.ips[\$ip].mac=$(jsonescape "${2}")|.ips[\$ip].online=true" <<< "${tempjson}") + tempjson=$(jq "$(jsonescape "${1}") as \$ip|.ips[\$ip].mac=$(jsonescape "${2}")|.ips[\$ip].online=true|.ips[\$ip].lastseen=$(jsonescape "${starttime}")" <<< "${tempjson}") } doscan() { local nmaplog - nmaplog=$(sudo nmap -sn -n 192.168.16.0/24) + nmaplog=$(sudo nmap -sn -n "${1}") if [ $? -ne 0 ] then echo "nmap failed" 1>&2 return 1 fi - cat <<< "${nmaplog}" > nmaplog.txt + cat <<< "${nmaplog}" > "nmaplog.$(sed 's/\//\./' <<< "${1}").txt" local parsestep local ipaddr @@ -97,20 +95,54 @@ doscan() { #done < nmaplog.txt } -doscan -if [ $? -ne 0 ] -then - echo "Scan failed" 1>&2 - exit 1 -fi +localifaces="$(ip -j addr | jq '[.[]|{ifname:.ifname,address:.address,addr_info:.addr_info[]}|select(.ifname!="lo")|select(.addr_info.prefixlen>=20)|select(.addr_info.family=="inet")|{ifname:.ifname,ip:.addr_info.local,prefix:.addr_info.prefixlen,mac:(.address|ascii_upcase)}]|map_values(.ip32=(.ip|split(".")|to_entries|map((.value|tonumber)*pow(256;3-.key))|add))|map_values(.subnet32=(.ip32/pow(2;32-.prefix)|floor)*pow(2;32-.prefix))|map_values(.subnet=([(.subnet32/pow(256;3)|floor%256),(.subnet32/pow(256;2)|floor%256),(.subnet32/256|floor%256),.subnet32%256]|join(".")))|map_values(del(.ip32)|del(.subnet32))')" + +for i in $(seq "$(jq 'length' <<< "${localifaces}")") +do + currentiface="$(jq ".[${i}-1]" <<< "${localifaces}")" + foundhost "$(jq -r '.ip' <<< "${currentiface}")" "$(jq -r '.mac' <<< "${currentiface}")" + subnet="$(jq -r '.subnet' <<< "${currentiface}")/$(jq '.prefix' <<< "${currentiface}")" + echo "Scanning ${subnet}" + doscan "${subnet}" + if [ $? -ne 0 ] + then + echo "Scan failed" 1>&2 + exit 1 + fi +done ## make sure the MAC vendor and device/port fields exist -tempjson="$(jq '.macvendor+={}|.devices+=[]' <<< "${tempjson}")" +#tempjson="$(jq '.macvendor+={}|.devices+=[]' <<< "${tempjson}")" +if [ ! -f macvendor.json ] +then + echo '{}' > macvendor.json +fi +if [ ! -d devices ] +then + mkdir -p devices +fi +if [ ! -f devices/_example.json ] +then + cat < devices/_example.json +{ + "desc": "Description of the device", + "model": "Example Device Model", + "type": "example", + "user": "username", + "ports": [ + { + "name": "port1", + "mac": "00:00:00:00:00:00" + } + ] +} +EOF +fi tempjson="$(jq '.ips=(.ips|to_entries|sort_by(.key|split(".")|to_entries|map((.value|tonumber)*pow(256;3-.key))|add)|from_entries)' <<< "${tempjson}")" -fancyjson="$(jq '. as $root|$root.macvendor|to_entries|map({key:.value[],value:.key})|from_entries as $vendors|($root.devices|map(.*(.ports[]|with_entries(.key|="port_"+.))))|map_values(del(.ports))|map({key:.port_mac,value:.})|from_entries as $ports|$root.ips|map_values(.port=$ports[.mac]|.vendor=$vendors[.mac[0:8]])' <<< "${tempjson}")" +fancyjson="$(jq --slurpfile macvendor macvendor.json --slurpfile devices <(cat devices/*.json) '. as $root|$macvendor[0]|to_entries|map({key:.value[],value:.key})|from_entries as $vendors|($devices|map(.*(.ports[]|with_entries(.key|="port_"+.))))|map_values(del(.ports))|map({key:.port_mac,value:.})|from_entries as $ports|$root.ips|map_values(.port=$ports[.mac]|.vendor=$vendors[.mac[0:8]])' <<< "${tempjson}")" -jq -r '(["[?]","MAC","Vendor","Model","IP","User","Device","Port"],(to_entries|sort_by(.key|split(".")|to_entries|map((.value|tonumber)*pow(256;3-.key))|add)|.[]|[if .value.online then "[#]" else "[ ]" end,.value.mac,.value.vendor,.value.port.model,.key,.value.port.user,.value.port.desc,.value.port.port_name]))|@tsv' <<< "${fancyjson}" | column -ts $'\t' +jq -r '(["[?]","IP","MAC","Vendor","Model","User","Device","Port","Last seen"],(to_entries|sort_by(.key|split(".")|to_entries|map((.value|tonumber)*pow(256;3-.key))|add)|.[]|[if .value.online then "[#]" else "[ ]" end,.key,.value.mac,.value.vendor,.value.port.model,.value.port.user,.value.port.desc,.value.port.port_name,.value.lastseen]))|@tsv' <<< "${fancyjson}" | column -ts $'\t' cat <<< "${tempjson}" > arpscan.json diff --git a/macvendor.json b/macvendor.json new file mode 100644 index 0000000..ab1df37 --- /dev/null +++ b/macvendor.json @@ -0,0 +1,161 @@ +{ + "Project Vabel": [ + "02:50:56" + ], + "Project Vabel: Proxmox VE": [ + "BC:24:11" + ], + "Apple": [ + "68:4A:5F", + "80:04:5F", + "90:B7:90" + ], + "ASRock Incorporation": [ + "70:85:C2" + ], + "ASUSTek Computer": [ + "04:42:1A", + "50:EB:F6", + "7C:10:C9", + "A0:36:BC", + "A8:5E:45", + "BC:FC:E7" + ], + "AzureWave Technology Inc.": [ + "48:E7:DA", + "50:5A:65" + ], + "Cisco-Linksys": [ + "20:AA:4B", + "C8:B3:73" + ], + "Cloud Network Technology Singapore PTE. LTD.": [ + "3C:0A:F3", + "A8:3B:76" + ], + "Compal Information (KUNSHAN) CO., LTD.": [ + "08:8F:C3" + ], + "CyberTAN Technology": [ + "78:45:61" + ], + "Dell": [ + "3C:2C:30", + "60:18:95", + "64:00:6A", + "EC:F4:BB" + ], + "Espressif Inc.": [ + "80:65:99" + ], + "GSD VIET NAM TECHNOLOGY COMPANY LIMITED": [ + "38:9B:73" + ], + "Hewlett Packard": [ + "28:92:4A", + "2C:59:E5" + ], + "Hewlett Packard Enterprise": [ + "9C:DC:71", + "E0:07:1B" + ], + "Hitron Technologies. Inc": [ + "BC:14:01", + "F0:F2:49" + ], + "Huawei Technologies": [ + "78:CF:2F" + ], + "Icann, Iana Department": [ + "00:00:5E" + ], + "Intel Corporate": [ + "00:24:D7", + "2C:0D:A7", + "3C:E9:F7", + "6C:2F:80", + "88:F4:DA", + "94:E2:3C", + "A0:E7:0B", + "C4:75:AB" + ], + "Konica Minolta Holdings": [ + "00:20:6B" + ], + "LCFC(Hefei) Electronics Technology co, ltd": [ + "88:A4:C2", + "90:2E:16", + "9C:2D:CD" + ], + "Micro-Star Intl": [ + "D8:BB:C1" + ], + "Microsoft Corporation": [ + "D8:E2:DF" + ], + "PCS Systemtechnik GmbH (VirtualBox NIC)": [ + "08:00:27" + ], + "Private": [ + "80:6D:97" + ], + "Realtek Semiconductor": [ + "00:E0:4C" + ], + "Routerboard.com": [ + "64:D1:54", + "74:4D:28" + ], + "Samsung Electronics": [ + "5C:DC:49", + "BC:93:07", + "F4:DD:06" + ], + "Seiko Epson Corporation": [ + "F8:25:51", + "F8:D0:27" + ], + "Shenzhen HongRui Optical Technology": [ + "1C:2A:A3" + ], + "Siemens AG": [ + "30:B8:51" + ], + "Siemens AG, Automations & Drives,": [ + "30:13:89" + ], + "SJIT Co., Ltd.": [ + "34:FC:99" + ], + "SMC Networks": [ + "00:13:F7" + ], + "Synology Incoporated": [ + "00:11:32", + "90:09:D0" + ], + "TP-Link Systems": [ + "5C:E9:31", + "E4:FA:C4" + ], + "TPV Display Technology (Xiamen)": [ + "94:BD:BE" + ], + "Vantiva Technologies Belgium": [ + "D4:92:5E" + ], + "VMware": [ + "00:0C:29" + ], + "Wistron Corporation": [ + "00:26:2D" + ], + "Wistron InfoComm(Kunshan)Co.": [ + "F4:A8:0D" + ], + "Xiaomi Communications": [ + "48:87:59", + "50:8E:49", + "E4:84:D3" + ] +} \ No newline at end of file