#!/bin/sh # SecuBox Device Intelligence Controller # Unified device inventory with aggregation, classification, and emulators VERSION="1.0.0" CONFIG="device-intel" LIB_DIR="/usr/lib/secubox/device-intel" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' NC='\033[0m' log() { echo -e "${GREEN}[INTEL]${NC} $1"; } warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } error() { echo -e "${RED}[ERROR]${NC} $1"; } di_ctl_get() { uci -q get ${CONFIG}.$1; } # Load libraries . "${LIB_DIR}/functions.sh" . "${LIB_DIR}/classify.sh" # ============================================================================ # Commands # ============================================================================ cmd_list() { local format="${1:-json}" log "Aggregating device inventory..." di_invalidate_cache local devices=$(di_get_devices) case "$format" in json) echo "$devices" ;; table) echo "" printf "%-19s %-15s %-20s %-12s %-10s %-8s\n" \ "MAC" "IP" "HOSTNAME" "TYPE" "ZONE" "STATUS" echo "────────────────────────────────────────────────────────────────────────────────────" echo "$devices" | jsonfilter -e '@[*].mac' 2>/dev/null | while read -r mac; do [ -z "$mac" ] && continue local ip=$(echo "$devices" | jsonfilter -e "@[@.mac='${mac}'].ip" 2>/dev/null) local host=$(echo "$devices" | jsonfilter -e "@[@.mac='${mac}'].hostname" 2>/dev/null) local dtype=$(echo "$devices" | jsonfilter -e "@[@.mac='${mac}'].device_type" 2>/dev/null) local zone=$(echo "$devices" | jsonfilter -e "@[@.mac='${mac}'].cg_zone" 2>/dev/null) local online=$(echo "$devices" | jsonfilter -e "@[@.mac='${mac}'].online" 2>/dev/null) local status_sym="?" [ "$online" = "true" ] && status_sym="${GREEN}●${NC}" || status_sym="${RED}○${NC}" printf "%-19s %-15s %-20s %-12s %-10s %b\n" \ "$mac" "${ip:--}" "${host:--}" "${dtype:--}" "${zone:--}" "$status_sym" done echo "" ;; esac } cmd_show() { local mac="$1" if [ -z "$mac" ]; then echo "Usage: device-intelctl show " return 1 fi local mac_lower=$(echo "$mac" | tr 'A-F' 'a-f') local devices=$(di_get_devices) local device=$(echo "$devices" | jsonfilter -e "@[@.mac='${mac_lower}']" 2>/dev/null) if [ -z "$device" ]; then error "Device not found: $mac" return 1 fi echo "" echo "==========================================" echo " Device: $mac_lower" echo "==========================================" echo "" local ip=$(echo "$device" | jsonfilter -e '@.ip' 2>/dev/null) local hostname=$(echo "$device" | jsonfilter -e '@.hostname' 2>/dev/null) local label=$(echo "$device" | jsonfilter -e '@.label' 2>/dev/null) local vendor=$(echo "$device" | jsonfilter -e '@.vendor' 2>/dev/null) local online=$(echo "$device" | jsonfilter -e '@.online' 2>/dev/null) local conn=$(echo "$device" | jsonfilter -e '@.connection_type' 2>/dev/null) local iface=$(echo "$device" | jsonfilter -e '@.iface' 2>/dev/null) local randomized=$(echo "$device" | jsonfilter -e '@.randomized' 2>/dev/null) local mg_status=$(echo "$device" | jsonfilter -e '@.mg_status' 2>/dev/null) local cg_zone=$(echo "$device" | jsonfilter -e '@.cg_zone' 2>/dev/null) local cg_status=$(echo "$device" | jsonfilter -e '@.cg_status' 2>/dev/null) 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 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:--}" [ -n "$label" ] && echo " Label: $label" echo " Vendor: ${vendor:--}" echo -e " Online: $([ "$online" = "true" ] && echo "${GREEN}Yes${NC}" || echo "${RED}No${NC}")" echo " Connection: ${conn:--} (${iface:--})" echo -e " Randomized: $([ "$randomized" = "true" ] && echo "${YELLOW}Yes${NC}" || echo "No")" echo "" echo " ── Security ──" echo " MAC Status: ${mg_status:--}" echo " NAC Zone: ${cg_zone:--}" echo " NAC Status: ${cg_status:--}" echo "" echo " ── Classification ──" echo " Device Type: ${dtype:--}" echo " Source: ${dsrc:--}" [ -n "$emu" ] && echo " Emulator: $emu" echo "" echo " ── Timeline ──" echo " First Seen: ${first_seen:--}" echo " Last Seen: ${last_seen:--}" echo "" } cmd_classify() { local mac="$1" if [ -z "$mac" ]; then log "Running batch classification on all devices..." local devices=$(di_get_devices) di_classify_all "$devices" else local mac_lower=$(echo "$mac" | tr 'A-F' 'a-f') local devices=$(di_get_devices) local ip=$(echo "$devices" | jsonfilter -e "@[@.mac='${mac_lower}'].ip" 2>/dev/null) local hostname=$(echo "$devices" | jsonfilter -e "@[@.mac='${mac_lower}'].hostname" 2>/dev/null) local vendor=$(echo "$devices" | jsonfilter -e "@[@.mac='${mac_lower}'].vendor" 2>/dev/null) local emu=$(echo "$devices" | jsonfilter -e "@[@.mac='${mac_lower}'].emulator_source" 2>/dev/null) local result=$(di_classify_device "$mac_lower" "$ip" "$hostname" "$vendor" "$emu") local dtype=$(echo "$result" | cut -d'|' -f1) local dsrc=$(echo "$result" | cut -d'|' -f2) log "Device $mac_lower classified as: $dtype (via $dsrc)" fi } cmd_set_type() { local mac="$1" dtype="$2" if [ -z "$mac" ] || [ -z "$dtype" ]; then echo "Usage: device-intelctl set-type " echo "Types: iot_sensor, storage, relay_gateway, compute, io_device, mqtt_device, zigbee_device, usb_peripheral" return 1 fi local mac_lower=$(echo "$mac" | tr 'A-F' 'a-f') local mac_clean=$(echo "$mac_lower" | tr -d ':') uci set ${CONFIG}.${mac_clean}=device uci set ${CONFIG}.${mac_clean}.mac="$mac_lower" uci set ${CONFIG}.${mac_clean}.type="$dtype" uci commit "$CONFIG" di_invalidate_cache log "Device $mac_lower type set to: $dtype" } cmd_set_label() { local mac="$1" label="$2" if [ -z "$mac" ] || [ -z "$label" ]; then echo "Usage: device-intelctl set-label