fix(device-intel): Fix BusyBox compatibility and data source mapping
- Replace bash-only $((16#hex)) with printf "%d" 0x for ash - Fix client-guardian collector to use actual UCI fields (name, zone, status, first_seen, last_seen) - Add ARP table collector for IP resolution and online detection - Fix di_get_summary jsonfilter counting (use per-field extraction) - Rename uci_get to di_ctl_get to avoid collision with OpenWrt's /lib/functions.sh which overwrites it - Replace rx_bytes/tx_bytes/risk_score with first_seen/last_seen timeline in show command Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
932c578dad
commit
abc0f66246
@ -65,24 +65,33 @@ di_collect_mac_guardian() {
|
||||
}
|
||||
|
||||
# Collect client-guardian data via UCI
|
||||
# Format: cg|mac|ip|hostname|zone|status|rx_bytes|tx_bytes|risk_score
|
||||
# Format: cg|mac|name|zone|status|first_seen|last_seen
|
||||
di_collect_client_guardian() {
|
||||
local idx=0
|
||||
while uci -q get client-guardian.@client[$idx] >/dev/null 2>&1; do
|
||||
local mac=$(uci -q get client-guardian.@client[$idx].mac)
|
||||
local ip=$(uci -q get client-guardian.@client[$idx].ip)
|
||||
local hostname=$(uci -q get client-guardian.@client[$idx].hostname)
|
||||
local name=$(uci -q get client-guardian.@client[$idx].name)
|
||||
local zone=$(uci -q get client-guardian.@client[$idx].zone)
|
||||
local status=$(uci -q get client-guardian.@client[$idx].status)
|
||||
local rx=$(uci -q get client-guardian.@client[$idx].rx_bytes)
|
||||
local tx=$(uci -q get client-guardian.@client[$idx].tx_bytes)
|
||||
local risk=$(uci -q get client-guardian.@client[$idx].risk_score)
|
||||
local first_seen=$(uci -q get client-guardian.@client[$idx].first_seen)
|
||||
local last_seen=$(uci -q get client-guardian.@client[$idx].last_seen)
|
||||
|
||||
[ -n "$mac" ] && echo "cg|${mac}|${ip}|${hostname}|${zone}|${status}|${rx:-0}|${tx:-0}|${risk:-0}"
|
||||
[ -n "$mac" ] && echo "cg|${mac}|${name}|${zone}|${status}|${first_seen}|${last_seen}"
|
||||
idx=$((idx + 1))
|
||||
done
|
||||
}
|
||||
|
||||
# Collect ARP table for IP-to-MAC resolution and online detection
|
||||
# Format: arp|mac|ip|iface
|
||||
di_collect_arp() {
|
||||
while read -r ip hw flags mac mask iface; do
|
||||
[ "$ip" = "IP" ] && continue # skip header
|
||||
[ "$mac" = "00:00:00:00:00:00" ] && continue
|
||||
[ "$flags" = "0x0" ] && continue # incomplete entry
|
||||
echo "arp|${mac}|${ip}|${iface}"
|
||||
done < /proc/net/arp
|
||||
}
|
||||
|
||||
# Collect DHCP lease data
|
||||
# Format: dhcp|mac|ip|hostname|expires
|
||||
di_collect_dhcp() {
|
||||
@ -120,7 +129,7 @@ di_collect_exposure() {
|
||||
while read -r sl local_addr rem_addr st rest; do
|
||||
[ "$st" != "0A" ] && continue # 0A = LISTEN
|
||||
local hex_port=$(echo "$local_addr" | cut -d: -f2)
|
||||
local port=$((16#$hex_port))
|
||||
local port=$(printf "%d" "0x${hex_port}" 2>/dev/null)
|
||||
local hex_ip=$(echo "$local_addr" | cut -d: -f1)
|
||||
|
||||
# Determine bind address
|
||||
@ -161,6 +170,7 @@ di_aggregate_devices() {
|
||||
di_collect_mac_guardian > "${tmp_dir}/mg.dat" 2>/dev/null
|
||||
di_collect_client_guardian > "${tmp_dir}/cg.dat" 2>/dev/null
|
||||
di_collect_dhcp > "${tmp_dir}/dhcp.dat" 2>/dev/null
|
||||
di_collect_arp > "${tmp_dir}/arp.dat" 2>/dev/null
|
||||
di_collect_p2p_peers > "${tmp_dir}/p2p.dat" 2>/dev/null
|
||||
di_collect_exposure > "${tmp_dir}/exp.dat" 2>/dev/null
|
||||
di_collect_emulators > "${tmp_dir}/emu.dat" 2>/dev/null
|
||||
@ -183,8 +193,8 @@ di_aggregate_devices() {
|
||||
local ip="" hostname="" vendor="" iface="" online="false"
|
||||
local mg_status="" cg_zone="" cg_status="" randomized="false"
|
||||
local first_seen="" last_seen="" label="" device_type=""
|
||||
local device_type_source="" emulator_source="" rx=0 tx=0 risk=0
|
||||
local services="" source_node="local"
|
||||
local device_type_source="" emulator_source=""
|
||||
local source_node="local"
|
||||
|
||||
# Mac-Guardian data
|
||||
local mg=$(grep "^mg|${mac}|" "${tmp_dir}/mg.dat" 2>/dev/null | head -1)
|
||||
@ -199,18 +209,27 @@ di_aggregate_devices() {
|
||||
last_seen=$(echo "$mg" | cut -d'|' -f9)
|
||||
fi
|
||||
|
||||
# Client-Guardian data
|
||||
local cg=$(grep "^cg|${mac}|" "${tmp_dir}/cg.dat" 2>/dev/null | head -1)
|
||||
# Client-Guardian data (format: cg|mac|name|zone|status|first_seen|last_seen)
|
||||
local cg=$(grep -i "^cg|${mac}|" "${tmp_dir}/cg.dat" 2>/dev/null | head -1)
|
||||
if [ -n "$cg" ]; then
|
||||
local cg_ip=$(echo "$cg" | cut -d'|' -f3)
|
||||
[ -n "$cg_ip" ] && ip="$cg_ip"
|
||||
local cg_host=$(echo "$cg" | cut -d'|' -f4)
|
||||
[ -n "$cg_host" ] && [ -z "$hostname" ] && hostname="$cg_host"
|
||||
cg_zone=$(echo "$cg" | cut -d'|' -f5)
|
||||
cg_status=$(echo "$cg" | cut -d'|' -f6)
|
||||
rx=$(echo "$cg" | cut -d'|' -f7)
|
||||
tx=$(echo "$cg" | cut -d'|' -f8)
|
||||
risk=$(echo "$cg" | cut -d'|' -f9)
|
||||
local cg_name=$(echo "$cg" | cut -d'|' -f3)
|
||||
[ -n "$cg_name" ] && [ -z "$hostname" ] && hostname="$cg_name"
|
||||
cg_zone=$(echo "$cg" | cut -d'|' -f4)
|
||||
cg_status=$(echo "$cg" | cut -d'|' -f5)
|
||||
local cg_first=$(echo "$cg" | cut -d'|' -f6)
|
||||
local cg_last=$(echo "$cg" | cut -d'|' -f7)
|
||||
[ -n "$cg_first" ] && [ -z "$first_seen" ] && first_seen="$cg_first"
|
||||
[ -n "$cg_last" ] && [ -z "$last_seen" ] && last_seen="$cg_last"
|
||||
fi
|
||||
|
||||
# ARP data — provides IP and online detection
|
||||
local arp=$(grep -i "|${mac}|" "${tmp_dir}/arp.dat" 2>/dev/null | head -1)
|
||||
if [ -n "$arp" ]; then
|
||||
local arp_ip=$(echo "$arp" | cut -d'|' -f3)
|
||||
[ -n "$arp_ip" ] && [ -z "$ip" ] && ip="$arp_ip"
|
||||
local arp_iface=$(echo "$arp" | cut -d'|' -f4)
|
||||
[ -n "$arp_iface" ] && [ -z "$iface" ] && iface="$arp_iface"
|
||||
online="true" # present in ARP = reachable
|
||||
fi
|
||||
|
||||
# DHCP data
|
||||
@ -272,12 +291,9 @@ di_aggregate_devices() {
|
||||
[ -n "$device_type" ] && printf ',"device_type":"%s"' "$device_type"
|
||||
[ -n "$device_type_source" ] && printf ',"device_type_source":"%s"' "$device_type_source"
|
||||
[ -n "$emulator_source" ] && printf ',"emulator_source":"%s"' "$emulator_source"
|
||||
printf ',"rx_bytes":%s' "${rx:-0}"
|
||||
printf ',"tx_bytes":%s' "${tx:-0}"
|
||||
printf ',"risk_score":%s' "${risk:-0}"
|
||||
printf ',"source_node":"%s"' "$source_node"
|
||||
[ -n "$first_seen" ] && printf ',"first_seen":%s' "$first_seen"
|
||||
[ -n "$last_seen" ] && printf ',"last_seen":%s' "$last_seen"
|
||||
[ -n "$first_seen" ] && printf ',"first_seen":"%s"' "$first_seen"
|
||||
[ -n "$last_seen" ] && printf ',"last_seen":"%s"' "$last_seen"
|
||||
printf '}'
|
||||
done
|
||||
|
||||
@ -339,12 +355,11 @@ di_get_devices() {
|
||||
|
||||
di_get_summary() {
|
||||
local devices=$(di_get_devices)
|
||||
local total=0 online=0 mesh=0 iot=0 storage=0 compute=0
|
||||
local total=0 online=0 mesh=0
|
||||
|
||||
# Count using jsonfilter
|
||||
total=$(echo "$devices" | jsonfilter -e '@[*].mac' 2>/dev/null | wc -l)
|
||||
online=$(echo "$devices" | jsonfilter -e '@[*]' 2>/dev/null | grep '"online":true' | wc -l)
|
||||
mesh=$(echo "$devices" | jsonfilter -e '@[*]' 2>/dev/null | grep '"device_type":"mesh_peer"' | wc -l)
|
||||
online=$(echo "$devices" | jsonfilter -e '@[*].online' 2>/dev/null | grep -c "true")
|
||||
mesh=$(echo "$devices" | jsonfilter -e '@[*].device_type' 2>/dev/null | grep -c "mesh_peer")
|
||||
|
||||
printf '{"total":%d,"online":%d,"mesh_peers":%d}' \
|
||||
"$total" "$online" "$mesh"
|
||||
|
||||
@ -17,7 +17,7 @@ log() { echo -e "${GREEN}[INTEL]${NC} $1"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
uci_get() { uci -q get ${CONFIG}.$1; }
|
||||
di_ctl_get() { uci -q get ${CONFIG}.$1; }
|
||||
|
||||
# Load libraries
|
||||
. "${LIB_DIR}/functions.sh"
|
||||
@ -101,9 +101,8 @@ cmd_show() {
|
||||
local dtype=$(echo "$device" | jsonfilter -e '@.device_type' 2>/dev/null)
|
||||
local dsrc=$(echo "$device" | jsonfilter -e '@.device_type_source' 2>/dev/null)
|
||||
local emu=$(echo "$device" | jsonfilter -e '@.emulator_source' 2>/dev/null)
|
||||
local rx=$(echo "$device" | jsonfilter -e '@.rx_bytes' 2>/dev/null)
|
||||
local tx=$(echo "$device" | jsonfilter -e '@.tx_bytes' 2>/dev/null)
|
||||
local risk=$(echo "$device" | jsonfilter -e '@.risk_score' 2>/dev/null)
|
||||
local first_seen=$(echo "$device" | jsonfilter -e '@.first_seen' 2>/dev/null)
|
||||
local last_seen=$(echo "$device" | jsonfilter -e '@.last_seen' 2>/dev/null)
|
||||
|
||||
echo " IP: ${ip:--}"
|
||||
echo " Hostname: ${hostname:--}"
|
||||
@ -117,16 +116,15 @@ cmd_show() {
|
||||
echo " MAC Status: ${mg_status:--}"
|
||||
echo " NAC Zone: ${cg_zone:--}"
|
||||
echo " NAC Status: ${cg_status:--}"
|
||||
echo " Risk Score: ${risk:-0}"
|
||||
echo ""
|
||||
echo " ── Classification ──"
|
||||
echo " Device Type: ${dtype:--}"
|
||||
echo " Source: ${dsrc:--}"
|
||||
[ -n "$emu" ] && echo " Emulator: $emu"
|
||||
echo ""
|
||||
echo " ── Traffic ──"
|
||||
echo " RX: ${rx:-0} bytes"
|
||||
echo " TX: ${tx:-0} bytes"
|
||||
echo " ── Timeline ──"
|
||||
echo " First Seen: ${first_seen:--}"
|
||||
echo " Last Seen: ${last_seen:--}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
@ -214,7 +212,7 @@ cmd_summary() {
|
||||
# Emulator status
|
||||
echo " ── Emulators ──"
|
||||
for emu in usb mqtt zigbee; do
|
||||
local enabled=$(uci_get "${emu}.enabled")
|
||||
local enabled=$(di_ctl_get "${emu}.enabled")
|
||||
if [ "$enabled" = "1" ]; then
|
||||
echo -e " ${emu}: ${GREEN}enabled${NC}"
|
||||
else
|
||||
@ -246,7 +244,7 @@ cmd_emulators() {
|
||||
echo ""
|
||||
|
||||
for emu in usb mqtt zigbee; do
|
||||
local enabled=$(uci_get "${emu}.enabled")
|
||||
local enabled=$(di_ctl_get "${emu}.enabled")
|
||||
echo -e " ${CYAN}${emu}${NC}:"
|
||||
echo -e " Enabled: $([ "$enabled" = "1" ] && echo "${GREEN}Yes${NC}" || echo "${RED}No${NC}")"
|
||||
|
||||
@ -257,16 +255,16 @@ cmd_emulators() {
|
||||
echo " Devices: $count USB device(s)"
|
||||
;;
|
||||
mqtt)
|
||||
local host=$(uci_get mqtt.broker_host)
|
||||
local port=$(uci_get mqtt.broker_port)
|
||||
local host=$(di_ctl_get mqtt.broker_host)
|
||||
local port=$(di_ctl_get mqtt.broker_port)
|
||||
echo " Broker: ${host:-127.0.0.1}:${port:-1883}"
|
||||
pgrep mosquitto >/dev/null 2>&1 && \
|
||||
echo -e " Status: ${GREEN}broker running${NC}" || \
|
||||
echo -e " Status: ${RED}broker not found${NC}"
|
||||
;;
|
||||
zigbee)
|
||||
local adapter=$(uci_get zigbee.adapter)
|
||||
local coord=$(uci_get zigbee.coordinator)
|
||||
local adapter=$(di_ctl_get zigbee.adapter)
|
||||
local coord=$(di_ctl_get zigbee.coordinator)
|
||||
echo " Adapter: ${adapter:-zigbee2mqtt}"
|
||||
echo " Dongle: ${coord:-/dev/ttyUSB0}"
|
||||
[ -c "${coord:-/dev/ttyUSB0}" ] 2>/dev/null && \
|
||||
|
||||
Loading…
Reference in New Issue
Block a user