#!/usr/bin/env bash
# ░▒▓█ NEO RADAR v1.16 █▓▒░

# ANSI Color Codes
CLR_RESET="\033[0m"
CLR_CYAN="\033[1;36m"
CLR_DARKCYAN="\033[0;36m"
CLR_MAGENTA="\033[1;35m"
CLR_DARKMAGENTA="\033[0;35m"
CLR_YELLOW="\033[1;33m"
CLR_GREEN="\033[1;32m"
CLR_GRAY="\033[0;37m"
CLR_DARKGRAY="\033[1;30m"
CLR_RED="\033[1;31m"

DEFAULT_PREFIX="192.168.0"
COMMON_PORTS=(21 22 23 25 53 80 110 135 139 143 443 445 548 993 995 1433 3306 3389 5900 8080 8443)
KEY_PORTS=(22 23 80 139 443 445 3389 5000 5555 62078)
declare -A OUI_CACHE

# --- Termux detection ---
detect_termux() {
    [ -n "$TERMUX_VERSION" ] || [ -f "/system/build.prop" ]
}

# --- IP validation ---
validate_ip() {
    local ip=$1 octets=() octet
    IFS='.' read -ra octets <<< "$ip"
    [ ${#octets[@]} -ne 4 ] && return 1
    for octet in "${octets[@]}"; do
        [[ "$octet" =~ ^[0-9]+$ ]] || return 1
        [ "$octet" -lt 0 -o "$octet" -gt 255 ] && return 1
    done
    return 0
}

# --- Port check (300ms timeout) ---
check_port() {
    local ip="$1" port="$2"
    if command -v nc >/dev/null 2>&1; then
        nc -z -w 1 "$ip" "$port" >/dev/null 2>&1
        return $?
    fi
    timeout 1 bash -c "</dev/tcp/$ip/$port" >/dev/null 2>&1
    return $?
}

# --- Batch port scan for a single host (all ports per call) ---
scan_host_ports() {
    local ip="$1" port
    shift 1
    for port in "$@"; do
        if check_port "$ip" "$port"; then
            echo "$port"
        fi
    done
}

# --- Hostname resolution (multi-method) ---
resolve_hostname() {
    local ip="$1" name=""

    if command -v nmblookup >/dev/null 2>&1; then
        name=$(nmblookup -A "$ip" 2>/dev/null | grep -E "<00>" | grep -v "<GROUP>" | head -1 | awk '{print $1}')
    fi

    if [ -z "$name" ] && command -v avahi-resolve >/dev/null 2>&1; then
        name=$(avahi-resolve -a "$ip" 2>/dev/null | awk '{print $2}')
    fi

    if [ -z "$name" ]; then
        name=$(getent hosts "$ip" 2>/dev/null | awk '{print $2}')
    fi

    if [ -z "$name" ] && command -v nslookup >/dev/null 2>&1; then
        name=$(nslookup "$ip" 2>/dev/null | grep "name = " | sed 's/.*name = //' | sed 's/\.$//' | head -1)
    fi

    if [ -z "$name" ] && command -v dig >/dev/null 2>&1; then
        name=$(dig -x "$ip" +short 2>/dev/null | head -1)
    fi

    if [ -n "$name" ]; then
        echo "$name"
    else
        echo "No DNS/mDNS/NBT Record"
    fi
}

# --- ARP MAC capture ---
get_mac_address() {
    local ip="$1" mac=""

    mac=$(ip neighbor show "$ip" 2>/dev/null | awk '{print $5}' | grep -E '([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}' | tr 'a-z' 'A-Z' | head -1)

    if [ -z "$mac" ] && [ -f /proc/net/arp ]; then
        mac=$(grep -w "$ip" /proc/net/arp 2>/dev/null | awk '{print $4}' | grep -v "00:00:00:00:00:00" | tr 'a-z' 'A-Z' | head -1)
    fi

    if [ -z "$mac" ] && command -v arp >/dev/null 2>&1; then
        mac=$(arp -n "$ip" 2>/dev/null | grep -w "$ip" | awk '{print $3}' | grep -E '([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}' | tr 'a-z' 'A-Z' | head -1)
    fi

    if [ -n "$mac" ]; then
        echo "$mac"
    else
        echo "Unavailable"
    fi
}

# --- Populate OUI vendor cache ---
load_oui_cache() {
    OUI_CACHE=()
    # Virtualization
    OUI_CACHE[005056]="VMware"; OUI_CACHE[000C29]="VMware"; OUI_CACHE[000569]="VMware"
    OUI_CACHE[080027]="Oracle VirtualBox"; OUI_CACHE[0A0027]="Oracle VirtualBox"
    OUI_CACHE[00155D]="Microsoft Hyper-V"; OUI_CACHE[0003FF]="Microsoft"
    OUI_CACHE[00163E]="Xen / Citrix"; OUI_CACHE[000E0C]="Xen / Citrix"
    OUI_CACHE[525400]="QEMU/KVM (user)"
    # Single Board Computers
    OUI_CACHE[B827EB]="Raspberry Pi"; OUI_CACHE[D43A04]="Raspberry Pi"
    OUI_CACHE[E45F01]="Raspberry Pi"; OUI_CACHE[2CCF67]="Raspberry Pi"
    OUI_CACHE[DCA632]="Raspberry Pi"; OUI_CACHE[0013C3]="Arduino"
    OUI_CACHE[98BA61]="BeagleBoard"; OUI_CACHE[A020A6]="Odroid"
    # Apple
    OUI_CACHE[000393]="Apple"; OUI_CACHE[000502]="Apple"; OUI_CACHE[000A27]="Apple"
    OUI_CACHE[000D93]="Apple"; OUI_CACHE[001124]="Apple"; OUI_CACHE[001451]="Apple"
    OUI_CACHE[0016CB]="Apple"; OUI_CACHE[0017F2]="Apple"; OUI_CACHE[0019E3]="Apple"
    OUI_CACHE[001B63]="Apple"; OUI_CACHE[001D4F]="Apple"; OUI_CACHE[001E52]="Apple"
    OUI_CACHE[001F5B]="Apple"; OUI_CACHE[001FF3]="Apple"; OUI_CACHE[0021E9]="Apple"
    OUI_CACHE[002241]="Apple"; OUI_CACHE[002332]="Apple"; OUI_CACHE[00236C]="Apple"
    OUI_CACHE[002436]="Apple"; OUI_CACHE[002500]="Apple"; OUI_CACHE[0025BC]="Apple"
    OUI_CACHE[002608]="Apple"; OUI_CACHE[0026B0]="Apple"; OUI_CACHE[0050E4]="Apple"
    OUI_CACHE[040CCE]="Apple"; OUI_CACHE[086698]="Apple"; OUI_CACHE[0C3021]="Apple"
    OUI_CACHE[0C74C2]="Apple"; OUI_CACHE[1093E9]="Apple"; OUI_CACHE[109ADD]="Apple"
    OUI_CACHE[147DDA]="Apple"; OUI_CACHE[185AF6]="Apple"; OUI_CACHE[1C5B47]="Apple"
    OUI_CACHE[2CBEEB]="Apple"; OUI_CACHE[34159E]="Apple"; OUI_CACHE[34A395]="Apple"
    OUI_CACHE[3C0754]="Apple"; OUI_CACHE[3CD0F8]="Apple"; OUI_CACHE[40A5EF]="Apple"
    OUI_CACHE[442EE6]="Apple"; OUI_CACHE[444E6A]="Apple"; OUI_CACHE[48605F]="Apple"
    OUI_CACHE[488EEC]="Apple"; OUI_CACHE[4C3275]="Apple"; OUI_CACHE[54E43A]="Apple"
    OUI_CACHE[5855CA]="Apple"; OUI_CACHE[60334B]="Apple"; OUI_CACHE[608C4A]="Apple"
    OUI_CACHE[6476F0]="Apple"; OUI_CACHE[64A2F9]="Apple"; OUI_CACHE[685B36]="Apple"
    OUI_CACHE[68AB7E]="Apple"; OUI_CACHE[6C72E7]="Apple"; OUI_CACHE[703EAC]="Apple"
    OUI_CACHE[784B7F]="Apple"; OUI_CACHE[784F43]="Apple"; OUI_CACHE[7C04D0]="Apple"
    OUI_CACHE[7C11BE]="Apple"; OUI_CACHE[80BE05]="Apple"; OUI_CACHE[843838]="Apple"
    OUI_CACHE[88532C]="Apple"; OUI_CACHE[8C7B9D]="Apple"; OUI_CACHE[8C8590]="Apple"
    OUI_CACHE[90840D]="Apple"; OUI_CACHE[94DB49]="Apple"; OUI_CACHE[9801A7]="Apple"
    OUI_CACHE[98FE94]="Apple"; OUI_CACHE[A0999B]="Apple"; OUI_CACHE[A46B6B]="Apple"
    OUI_CACHE[A483E7]="Apple"; OUI_CACHE[A886DD]="Apple"; OUI_CACHE[AC293A]="Apple"
    OUI_CACHE[B065BD]="Apple"; OUI_CACHE[B4F0AB]="Apple"; OUI_CACHE[B8E856]="Apple"
    OUI_CACHE[BC926B]="Apple"; OUI_CACHE[C0FE45]="Apple"; OUI_CACHE[C42B2C]="Apple"
    OUI_CACHE[C84C75]="Apple"; OUI_CACHE[CC08FB]="Apple"; OUI_CACHE[CC20E8]="Apple"
    OUI_CACHE[D03A05]="Apple"; OUI_CACHE[D4067B]="Apple"; OUI_CACHE[D461FE]="Apple"
    OUI_CACHE[D89A34]="Apple"; OUI_CACHE[DC2B66]="Apple"; OUI_CACHE[E01E34]="Apple"
    OUI_CACHE[E0F847]="Apple"; OUI_CACHE[E4CE8F]="Apple"; OUI_CACHE[E8FDCE]="Apple"
    OUI_CACHE[F01898]="Apple"; OUI_CACHE[F04F7C]="Apple"; OUI_CACHE[F09A51]="Apple"
    OUI_CACHE[F40F24]="Apple"; OUI_CACHE[F4F5DB]="Apple"; OUI_CACHE[FCE998]="Apple"
    OUI_CACHE[F81EDF]="Apple"; OUI_CACHE[FC253F]="Apple"
    # Google
    OUI_CACHE[001A11]="Google"; OUI_CACHE[3C5AB4]="Google"; OUI_CACHE[DAA119]="Google"
    OUI_CACHE[A47733]="Google"; OUI_CACHE[D052A8]="Google"
    OUI_CACHE[385B0B]="Google"; OUI_CACHE[385B0C]="Google"
    OUI_CACHE[8C5C3A]="Google (Chromecast)"; OUI_CACHE[8CB84A]="Google"
    OUI_CACHE[F8DFA8]="Google"; OUI_CACHE[B43A28]="Google"
    OUI_CACHE[9CADEF]="Google"; OUI_CACHE[00180A]="Google"
    # Samsung
    OUI_CACHE[0012FB]="Samsung"; OUI_CACHE[001599]="Samsung"; OUI_CACHE[5001D9]="Samsung"
    OUI_CACHE[B05CDA]="Samsung"; OUI_CACHE[EC1F72]="Samsung"
    OUI_CACHE[F0272B]="Samsung"; OUI_CACHE[945E2B]="Samsung"
    OUI_CACHE[7085C2]="Samsung"; OUI_CACHE[5C514F]="Samsung"
    OUI_CACHE[C89402]="Samsung"; OUI_CACHE[F82C18]="Samsung"
    OUI_CACHE[8CFBA5]="Samsung"; OUI_CACHE[A49005]="Samsung"
    OUI_CACHE[20D906]="Samsung"
    # Amazon
    OUI_CACHE[44650D]="Amazon"; OUI_CACHE[74C246]="Amazon"; OUI_CACHE[A002DC]="Amazon"
    OUI_CACHE[64006A]="Amazon"; OUI_CACHE[4CEFC0]="Amazon"
    OUI_CACHE[40B076]="Amazon"; OUI_CACHE[AC63BE]="Amazon"
    # Dell
    OUI_CACHE[000F53]="Dell"; OUI_CACHE[001422]="Dell"; OUI_CACHE[1866DA]="Dell"
    OUI_CACHE[00123F]="Dell"; OUI_CACHE[001D09]="Dell"; OUI_CACHE[002170]="Dell"
    OUI_CACHE[0024E8]="Dell"; OUI_CACHE[5CF9DD]="Dell"; OUI_CACHE[F8DB7F]="Dell"
    # HP
    OUI_CACHE[0017A4]="HP"; OUI_CACHE[001F29]="HP"; OUI_CACHE[3CD92B]="HP"
    OUI_CACHE[001A4B]="HP"; OUI_CACHE[00237D]="HP"; OUI_CACHE[0025B3]="HP"
    OUI_CACHE[3863BB]="HP"; OUI_CACHE[2C598A]="HP"; OUI_CACHE[9CAED3]="HP"
    # Lenovo / IBM
    OUI_CACHE[001485]="Lenovo / IBM"; OUI_CACHE[001E37]="Lenovo / IBM"
    OUI_CACHE[00216A]="Lenovo / IBM"; OUI_CACHE[002451]="Lenovo / IBM"
    OUI_CACHE[E096FB]="Lenovo / IBM"
    # ASUS
    OUI_CACHE[001E8C]="ASUS"; OUI_CACHE[04D4C4]="ASUS"; OUI_CACHE[10BF48]="ASUS"
    OUI_CACHE[1C872C]="ASUS"; OUI_CACHE[24F094]="ASUS"; OUI_CACHE[3C0630]="ASUS"
    OUI_CACHE[60A44C]="ASUS"; OUI_CACHE[74D02B]="ASUS"; OUI_CACHE[8C10D4]="ASUS"
    OUI_CACHE[94D9B3]="ASUS"; OUI_CACHE[A021B7]="ASUS"; OUI_CACHE[B06EBF]="ASUS"
    OUI_CACHE[C81EE7]="ASUS"; OUI_CACHE[E89F6D]="ASUS"
    # Acer
    OUI_CACHE[001B24]="Acer"; OUI_CACHE[001FC6]="Acer"; OUI_CACHE[1C6F65]="Acer"
    OUI_CACHE[7824AF]="Acer"; OUI_CACHE[984B4A]="Acer"; OUI_CACHE[D4389C]="Acer"
    # Cisco
    OUI_CACHE[00000C]="Cisco"; OUI_CACHE[000143]="Cisco"; OUI_CACHE[000196]="Cisco"
    OUI_CACHE[00070E]="Cisco"; OUI_CACHE[00097B]="Cisco"; OUI_CACHE[001B0C]="Cisco"
    OUI_CACHE[001AA1]="Cisco"; OUI_CACHE[001E7A]="Cisco"; OUI_CACHE[001D46]="Cisco"
    OUI_CACHE[0C2724]="Cisco"; OUI_CACHE[1CDEA7]="Cisco"; OUI_CACHE[24166D]="Cisco"
    OUI_CACHE[3CCE73]="Cisco"; OUI_CACHE[547FEE]="Cisco"; OUI_CACHE[5C5015]="Cisco"
    OUI_CACHE[64167F]="Cisco"; OUI_CACHE[6C8814]="Cisco"; OUI_CACHE[848F69]="Cisco"
    OUI_CACHE[A01D48]="Cisco"; OUI_CACHE[A0528A]="Cisco"; OUI_CACHE[B06CBF]="Cisco"
    OUI_CACHE[C46ACF]="Cisco"; OUI_CACHE[D8F2CA]="Cisco"; OUI_CACHE[E02DE6]="Cisco"
    # TP-Link
    OUI_CACHE[50C7BF]="TP-Link"; OUI_CACHE[E848B8]="TP-Link"; OUI_CACHE[001D0F]="TP-Link"
    OUI_CACHE[98DAC4]="TP-Link"; OUI_CACHE[54A050]="TP-Link"; OUI_CACHE[6466B3]="TP-Link"
    OUI_CACHE[704CA5]="TP-Link"; OUI_CACHE[980D2E]="TP-Link"; OUI_CACHE[B0BE76]="TP-Link"
    OUI_CACHE[F4EC38]="TP-Link"; OUI_CACHE[84D81B]="TP-Link"; OUI_CACHE[1C3BF3]="TP-Link"
    OUI_CACHE[10FEED]="TP-Link"; OUI_CACHE[000E2E]="TP-Link"
    # NETGEAR
    OUI_CACHE[00146C]="NETGEAR"; OUI_CACHE[00184D]="NETGEAR"; OUI_CACHE[288023]="NETGEAR"
    OUI_CACHE[A42B8C]="NETGEAR"; OUI_CACHE[3822D6]="NETGEAR"; OUI_CACHE[8035C1]="NETGEAR"
    OUI_CACHE[20F41B]="NETGEAR"; OUI_CACHE[C03F0E]="NETGEAR"; OUI_CACHE[841B5E]="NETGEAR"
    OUI_CACHE[B03956]="NETGEAR"; OUI_CACHE[A0D3C1]="NETGEAR"
    # Linksys
    OUI_CACHE[001217]="Linksys"; OUI_CACHE[0014BF]="Linksys"; OUI_CACHE[001839]="Linksys"
    OUI_CACHE[001C10]="Linksys"; OUI_CACHE[001A70]="Linksys"; OUI_CACHE[00226B]="Linksys"
    OUI_CACHE[00259C]="Linksys"; OUI_CACHE[002369]="Linksys"; OUI_CACHE[E091F5]="Linksys"
    # D-Link
    OUI_CACHE[00055D]="D-Link"; OUI_CACHE[000D88]="D-Link"; OUI_CACHE[001195]="D-Link"
    OUI_CACHE[0015E9]="D-Link"; OUI_CACHE[001B11]="D-Link"; OUI_CACHE[001CF0]="D-Link"
    OUI_CACHE[28107B]="D-Link"; OUI_CACHE[74DADA]="D-Link"; OUI_CACHE[B0C554]="D-Link"
    OUI_CACHE[CCB255]="D-Link"; OUI_CACHE[1C9180]="D-Link"
    # Ubiquiti
    OUI_CACHE[00156D]="Ubiquiti"; OUI_CACHE[002722]="Ubiquiti"; OUI_CACHE[0418D6]="Ubiquiti"
    OUI_CACHE[24A42C]="Ubiquiti"; OUI_CACHE[44D9E7]="Ubiquiti"; OUI_CACHE[687251]="Ubiquiti"
    OUI_CACHE[7483C2]="Ubiquiti"; OUI_CACHE[788A20]="Ubiquiti"; OUI_CACHE[D0214F]="Ubiquiti"
    OUI_CACHE[E063DA]="Ubiquiti"
    # MikroTik
    OUI_CACHE[000E8F]="MikroTik"; OUI_CACHE[4C5F70]="MikroTik"; OUI_CACHE[64D154]="MikroTik"
    OUI_CACHE[A84041]="MikroTik"; OUI_CACHE[D4CA6D]="MikroTik"; OUI_CACHE[E48D8C]="MikroTik"
    # Huawei
    OUI_CACHE[001882]="Huawei"; OUI_CACHE[00259E]="Huawei"; OUI_CACHE[3C5C1C]="Huawei"
    OUI_CACHE[4C7F62]="Huawei"; OUI_CACHE[5407CC]="Huawei"; OUI_CACHE[70B3D5]="Huawei"
    OUI_CACHE[7439EA]="Huawei"; OUI_CACHE[8C3C4A]="Huawei"; OUI_CACHE[C02506]="Huawei"
    OUI_CACHE[F80D43]="Huawei"
    # Xiaomi
    OUI_CACHE[000F90]="Xiaomi"; OUI_CACHE[182B0A]="Xiaomi"; OUI_CACHE[38BAF8]="Xiaomi"
    OUI_CACHE[48FD8E]="Xiaomi"; OUI_CACHE[549F13]="Xiaomi"; OUI_CACHE[8C34FD]="Xiaomi"
    OUI_CACHE[900DCB]="Xiaomi"; OUI_CACHE[C0EEFB]="Xiaomi"; OUI_CACHE[E0ACCB]="Xiaomi"
    # Synology
    OUI_CACHE[001132]="Synology"; OUI_CACHE[00127B]="Synology"
    # QNAP
    OUI_CACHE[00089B]="QNAP"; OUI_CACHE[001ACE]="QNAP"
    # Western Digital
    OUI_CACHE[001DEC]="Western Digital"; OUI_CACHE[0090A9]="Western Digital"
    OUI_CACHE[1826CB]="Western Digital"
    # Intel
    OUI_CACHE[00166F]="Intel"; OUI_CACHE[001E64]="Intel"; OUI_CACHE[A44E31]="Intel"
    OUI_CACHE[001B21]="Intel"; OUI_CACHE[001CC0]="Intel"; OUI_CACHE[002185]="Intel"
    OUI_CACHE[F46D04]="Intel"; OUI_CACHE[54EE75]="Intel"
    # Realtek & Broadcom
    OUI_CACHE[00E04C]="Realtek"; OUI_CACHE[00E018]="Realtek"
    OUI_CACHE[001018]="Broadcom"; OUI_CACHE[000AF7]="Broadcom"
    OUI_CACHE[20687D]="Broadcom"
    # NVIDIA
    OUI_CACHE[00044B]="NVIDIA"; OUI_CACHE[1002B5]="NVIDIA"
    # Sony
    OUI_CACHE[000B46]="Sony"; OUI_CACHE[001DBA]="Sony"; OUI_CACHE[00215D]="Sony"
    OUI_CACHE[0812CF]="Sony"; OUI_CACHE[D847BB]="Sony"; OUI_CACHE[706655]="Sony"
    # LG
    OUI_CACHE[001E66]="LG"; OUI_CACHE[002244]="LG"; OUI_CACHE[A8B8E0]="LG"
    OUI_CACHE[DC330D]="LG"; OUI_CACHE[E0CB4E]="LG"
    # Nintendo
    OUI_CACHE[0019FD]="Nintendo"; OUI_CACHE[0022AA]="Nintendo"; OUI_CACHE[A4C0E1]="Nintendo"
    OUI_CACHE[B47C9C]="Nintendo"; OUI_CACHE[B8276D]="Nintendo"
    # Microsoft Xbox
    OUI_CACHE[002248]="Microsoft Xbox"; OUI_CACHE[5847CA]="Microsoft Xbox"
    OUI_CACHE[7C1E52]="Microsoft Xbox"; OUI_CACHE[A45E60]="Microsoft Xbox"
    # Sony PlayStation
    OUI_CACHE[000420]="Sony Interactive / Logitech"; OUI_CACHE[001FE1]="Sony PlayStation"
    OUI_CACHE[A89352]="Sony PlayStation"; OUI_CACHE[00265C]="Sony Interactive"
    # Roku
    OUI_CACHE[000D4B]="Roku"; OUI_CACHE[0CA613]="Roku"; OUI_CACHE[28E7CF]="Roku"
    # Brother Printers
    OUI_CACHE[000DD9]="Brother"; OUI_CACHE[001B8C]="Brother"; OUI_CACHE[002305]="Brother"
    OUI_CACHE[002577]="Brother"; OUI_CACHE[04A316]="Brother"; OUI_CACHE[102332]="Brother"
    # Canon Printers
    OUI_CACHE[000A99]="Canon"; OUI_CACHE[001B7A]="Canon"
    # Epson
    OUI_CACHE[000048]="Epson"; OUI_CACHE[000C6E]="Epson"; OUI_CACHE[001BE2]="Epson"
    # Philips Hue
    OUI_CACHE[001788]="Philips Hue"; OUI_CACHE[ECB5FA]="Philips Hue"
    # Sonos
    OUI_CACHE[000E58]="Sonos"; OUI_CACHE[B8E937]="Sonos"; OUI_CACHE[94599C]="Sonos"
    # Ring / Amazon
    OUI_CACHE[000EC2]="Ring / Amazon"; OUI_CACHE[747548]="Ring / Amazon"
    # NetApp
    OUI_CACHE[000A98]="NetApp"
    # Juniper
    OUI_CACHE[001ABD]="Juniper"; OUI_CACHE[00121E]="Juniper"
    # Aruba / HPE
    OUI_CACHE[001A1E]="Aruba / HPE"; OUI_CACHE[B0B98A]="Aruba / HPE"
    OUI_CACHE[D0C7C0]="Aruba / HPE"
    # Fortinet
    OUI_CACHE[00090F]="Fortinet"; OUI_CACHE[906CAC]="Fortinet"
    OUI_CACHE[BC1665]="Fortinet"
    # Zyxel
    OUI_CACHE[001349]="Zyxel"; OUI_CACHE[001ACF]="Zyxel"; OUI_CACHE[1C1D86]="Zyxel"
    # OnePlus
    OUI_CACHE[0A0B0C]="OnePlus"; OUI_CACHE[DAAEC7]="OnePlus"
    # Motorola
    OUI_CACHE[001E0B]="Motorola"; OUI_CACHE[1C2B10]="Motorola"
    OUI_CACHE[2C5B1A]="Motorola"; OUI_CACHE[00150C]="Motorola"
    # Nokia
    OUI_CACHE[00137A]="Nokia"; OUI_CACHE[0022A2]="Nokia"
    OUI_CACHE[4C6B39]="Nokia"; OUI_CACHE[B0A737]="Nokia"
    # HTC
    OUI_CACHE[0012D2]="HTC"; OUI_CACHE[000BFC]="HTC"
    OUI_CACHE[28D0EA]="HTC"; OUI_CACHE[102DB6]="HTC"
    # BlackBerry
    OUI_CACHE[000A28]="BlackBerry"; OUI_CACHE[001FDD]="BlackBerry"
    # Oppo / Vivo / Realme
    OUI_CACHE[7C610E]="Oppo"; OUI_CACHE[8C5085]="Oppo"
    OUI_CACHE[9CFCE8]="Oppo"; OUI_CACHE[447733]="Vivo"
    # Wyze
    OUI_CACHE[24CF21]="Wyze Labs"; OUI_CACHE[2CAA8E]="Wyze Labs"
    # Belkin / WeMo
    OUI_CACHE[001D7D]="Belkin / WeMo"; OUI_CACHE[EC1A59]="Belkin / WeMo"
    # Ecobee
    OUI_CACHE[502FA5]="Ecobee"
    # Arlo
    OUI_CACHE[14EBB6]="Arlo / Netgear"
    # Honeywell
    OUI_CACHE[001AAF]="Honeywell"
    # Vizio
    OUI_CACHE[001EC9]="Vizio"; OUI_CACHE[B0091A]="Vizio"
    # TCL
    OUI_CACHE[6CADEF]="TCL"; OUI_CACHE[9CEFD5]="TCL"
    # Hisense
    OUI_CACHE[00234E]="Hisense"; OUI_CACHE[641A22]="Hisense"
    # Lutron
    OUI_CACHE[00182E]="Lutron"
    # August Home
    OUI_CACHE[34EA34]="August Home"
    # Tuya / Smart Life (IoT)
    OUI_CACHE[10D61B]="Tuya Smart"
    OUI_CACHE[4C11BF]="Tuya Smart"
    OUI_CACHE[84E342]="Tuya Smart"
    # eero
    OUI_CACHE[8C6B8F]="eero"
    # Orbi (Netgear)
    OUI_CACHE[1C61B4]="Orbi / Netgear"
    # Plume
    OUI_CACHE[BC2C2D]="Plume"
}

# --- OUI vendor lookup with cache + API fallback ---
get_vendor() {
    local mac="$1" oui_clean vendor
    [ -z "$mac" ] || [ "$mac" = "Unavailable" ] && { echo "Unknown Vendor"; return; }

    oui_clean=$(echo "$mac" | tr -d ':-' | tr 'a-z' 'A-Z' | cut -c 1-6)

    # Check for randomized/private MAC (mobile privacy feature)
    local first_byte="${oui_clean:0:2}"
    local second_char="${first_byte:1:1}"
    case "$second_char" in
        2|6|A|E) echo "Randomized MAC (Privacy)"; return ;;
    esac

    # Check cache
    [ -n "${OUI_CACHE[$oui_clean]}" ] && { echo "${OUI_CACHE[$oui_clean]}"; return; }

    # Check local OUI file
    if [ -f /usr/share/ieee-data/oui.txt ]; then
        vendor=$(grep -i "^$oui_clean" /usr/share/ieee-data/oui.txt 2>/dev/null | head -1 | cut -d')' -f2 | xargs)
        if [ -n "$vendor" ]; then
            OUI_CACHE[$oui_clean]="$vendor"
            echo "$vendor"
            return
        fi
    fi

    # API fallback
    if command -v curl >/dev/null 2>&1; then
        vendor=$(curl -s --max-time 3 "https://api.maclookup.app/v2/macs/$oui_clean" 2>/dev/null)
        if [ -n "$vendor" ]; then
            vendor=$(echo "$vendor" | grep -o '"company":"[^"]*"' | cut -d'"' -f4)
            if [ -n "$vendor" ]; then
                OUI_CACHE[$oui_clean]="$vendor"
                echo "$vendor"
                return
            fi
        fi
    fi

    echo "Unknown Vendor"
}

# --- Service label for port ---
port_service() {
    case $1 in
        22) echo "SSH" ;; 23) echo "Telnet" ;; 80) echo "HTTP" ;;
        135) echo "RPC" ;; 139) echo "NetBIOS" ;; 443) echo "HTTPS" ;;
        445) echo "SMB" ;; 548) echo "AFP" ;; 1433) echo "MS-SQL" ;;
        3389) echo "RDP" ;; 3689) echo "DAAP" ;;
        5000) echo "AirPlay" ;; 5555) echo "ADB" ;; 5900) echo "VNC" ;;
        62078) echo "iTunes" ;; 8080) echo "Alt-HTTP" ;;
        *) echo "$1" ;;
    esac
}

# --- Multi-signal OS fingerprinting ---
fingerprint_os() {
    local ip="$1" ttl="$2" hname="$3"
    shift 3
    local open_ports=("$@")
    local sw=0 sl=0 sa=0 sn=0 total=0 top=0 pct=0
    local os="Unknown" conf="low" header="" nb="" mac="" oui=""
    local signals=""

    # TTL
    if [ "$ttl" -ge 100 ] && [ "$ttl" -le 128 ]; then sw=$((sw + 3)); signals="TTL:$ttl(Win+3)"
    elif [ "$ttl" -ge 32 ] && [ "$ttl" -le 64 ]; then sl=$((sl + 3)); signals="TTL:$ttl(Lin+3)"
    elif [ "$ttl" -ge 240 ] && [ "$ttl" -le 255 ]; then sn=$((sn + 3)); signals="TTL:$ttl(Net+3)"
    else signals="TTL:$ttl"; fi

    # Hostname clues
    if [ -n "$hname" ] && [ "$hname" != "No DNS/mDNS/NBT Record" ] && [ "$hname" != "Unavailable" ]; then
        local hname_upper
        hname_upper=$(echo "$hname" | tr 'a-z' 'A-Z')
        case "$hname_upper" in
            IPHONE*|IPAD*|IPOD*) sa=$((sa + 5)); signals="$signals, Host:Apple(+5)" ;;
            MACBOOK*|MAC-PRO*|IMAC*|MACMINI*|APPLE*) sa=$((sa + 5)); signals="$signals, Host:Apple(+5)" ;;
            DESKTOP-*|LAPTOP-*|WIN-*|WORKSTATION*) sw=$((sw + 4)); signals="$signals, Host:Win(+4)" ;;
            ANDROID*|SM-*|GT-*|REDMI*|POCO*|MOTO*|ONEPLUS*) sl=$((sl + 4)); signals="$signals, Host:Android(+4)" ;;
            ROUTER*|GATEWAY*|SWITCH*|AP-*|OPENWRT*|DD-WRT*) sn=$((sn + 5)); signals="$signals, Host:Network(+5)" ;;
        esac
    fi

    # Ports
    for p in "${open_ports[@]}"; do
        case $p in
            445) sw=$((sw + 5)); signals="$signals, SMB(+5)" ;;
            135) sw=$((sw + 3)); signals="$signals, RPC(+3)" ;;
            139) sw=$((sw + 3)); signals="$signals, NetBIOS(+3)" ;;
            3389) sw=$((sw + 4)); signals="$signals, RDP(+4)" ;;
            1433) sw=$((sw + 3)); signals="$signals, MSSQL(+3)" ;;
            22) sl=$((sl + 3)); signals="$signals, SSH(+3)" ;;
            5555) sl=$((sl + 4)); signals="$signals, ADB(+4)" ;;
            5900) sl=$((sl + 2)); signals="$signals, VNC(+2)" ;;
            23) sn=$((sn + 3)); signals="$signals, Telnet(+3)" ;;
            8080) sn=$((sn + 1)); signals="$signals, Alt-HTTP(+1)" ;;
            5000|7000) sa=$((sa + 4)); signals="$signals, AirPlay(+4)" ;;
            62078) sa=$((sa + 5)); signals="$signals, iTunes(+5)" ;;
            548) sa=$((sa + 4)); signals="$signals, AFP(+4)" ;;
            3689) sa=$((sa + 3)); signals="$signals, DAAP(+3)" ;;
        esac
    done

    # HTTP Server header
    header=$(echo -e "HEAD / HTTP/1.0\r\n\r\n" | timeout 1 nc "$ip" 80 2>/dev/null | grep -i "^Server:" | head -1)
    if [ -n "$header" ]; then
        echo "$header" | grep -qi "Microsoft-IIS" && { sw=$((sw + 4)); signals="$signals, IIS(+4)"; }
        echo "$header" | grep -qiE "Apache|nginx|lighttpd" && { sl=$((sl + 2)); signals="$signals, Web:Lin(+2)"; }
        echo "$header" | grep -qiE "micro_httpd|GoAhead|RomPager|Boa|httpd" && { sn=$((sn + 4)); signals="$signals, IoT-srv(+4)"; }
        echo "$header" | grep -qiE "AirHttpd|CUPS" && { sa=$((sa + 4)); signals="$signals, Apple-srv(+4)"; }
    fi

    # NetBIOS
    if command -v nmblookup >/dev/null 2>&1; then
        nb=$(nmblookup -A "$ip" 2>/dev/null | grep -E "<00>" | grep -v "<GROUP>" | head -1 | awk '{print $1}')
        [ -n "$nb" ] && { sw=$((sw + 4)); signals="$signals, NetBIOS(+4)"; }
    fi

    # MAC OUI hint (weak, +1 only)
    mac=$(get_mac_address "$ip" 2>/dev/null)
    if [ -n "$mac" ] && [ "$mac" != "Unavailable" ]; then
        oui=$(echo "$mac" | tr -d ':-' | tr 'a-z' 'A-Z' | cut -c 1-6)
        case "$oui" in
            000393|000502|000A27|1093E9|A483E7|F4F5DB|\
            147DDA|185AF6|34A395|3CD0F8|685B36|703EAC|\
            784F43|88532C|90840D|94DB49|9801A7|B8E856|\
            C84C75|D89A34|F01898|F09A51|F40F24|FCE998|\
            FC253F|04D3B0|086698) sa=$((sa + 1)); signals="$signals, OUI:Apple(+1)" ;;
            0012FB|001599|5001D9|B05CDA|EC1F72|7085C2|\
            001A11|3C5AB4|DAA119|A47733|000F90|182B0A|\
            48FD8E|549F13|001882|3C5C1C|5407CC|DAAEC7|\
            001E66|A8B8E0|DC330D|000FB0|447733|7C610E|\
            9CFCE8|8C5085|0012D2|00150C) sl=$((sl + 1)); signals="$signals, OUI:Android(+1)" ;;
        esac
    fi

    # Determine winner
    total=$((sw + sl + sa + sn))
    [ "$total" -eq 0 ] && { echo "Unknown|low|"; return; }

    if [ "$sa" -ge "$sw" ] && [ "$sa" -ge "$sl" ] && [ "$sa" -ge "$sn" ] && [ "$sa" -gt 0 ]; then
        os="Apple (macOS/iOS)"; top=$sa
    elif [ "$sw" -ge "$sl" ] && [ "$sw" -ge "$sn" ] && [ "$sw" -gt 0 ]; then
        os="Windows"; top=$sw
    elif [ "$sl" -ge "$sn" ] && [ "$sl" -gt 0 ]; then
        os="Linux / Android"; top=$sl
    elif [ "$sn" -gt 0 ]; then
        os="Network / IoT Device"; top=$sn
    fi

    pct=$((top * 100 / total))
    [ "$pct" -ge 80 ] && conf="very high"
    [ "$pct" -ge 60 ] && conf="high"
    [ "$pct" -ge 40 ] && conf="medium"

    echo "$os|$conf|$signals"
}

# --- Loop-based end options (no recursion) ---
show_end_options() {
    local suppress_save="$1"
    shift
    local output_data=("$@")
    local action=""

    while true; do
        echo ""
        if [ "$suppress_save" = "true" ]; then
            read -r -p "$(echo -e "${CLR_CYAN}[+] Press Enter or 'B' for Main Menu, or 'E' to Exit:${CLR_RESET} ")" action
        else
            read -r -p "$(echo -e "${CLR_CYAN}[+] Press Enter or 'B' for Main Menu, 'S' to Save Scan, or 'E' to Exit:${CLR_RESET} ")" action
        fi

        case "$action" in
            [eE])
                echo -e "\n${CLR_CYAN}Goodbye.${CLR_RESET}"
                exit 0
                ;;
            [sS])
                if [ "$suppress_save" = "true" ]; then
                    start_neo_radar
                    return
                fi
                if [ "${#output_data[@]}" -eq 0 ]; then
                    echo -e "  ${CLR_YELLOW}[-] No scan results available to save.${CLR_RESET}"
                else
                    local default_file="Scan_Result_$(date +'%Y%m%d_%H%M%S').txt"
                    local file_path=""

                    if command -v zenity >/dev/null 2>&1; then
                        file_path=$(zenity --file-selection --save --confirm-overwrite --filename="$default_file" 2>/dev/null)
                    elif command -v kdialog >/dev/null 2>&1; then
                        file_path=$(kdialog --getsavefilename "$default_file" 2>/dev/null)
                    fi

                    if [ -z "$file_path" ]; then
                        read -r -p "$(echo -e "${CLR_CYAN}Enter save file path (default: $default_file):${CLR_RESET} ")" user_path
                        file_path="${user_path:-$default_file}"
                    fi

                    printf "%s\n" "${output_data[@]}" > "$file_path" 2>/dev/null
                    if [ $? -eq 0 ]; then
                        echo -e "  ${CLR_GREEN}[+] Scan results saved to: $file_path${CLR_RESET}"
                    else
                        echo -e "  ${CLR_RED}[-] Error saving file to $file_path${CLR_RESET}"
                    fi
                fi
                ;;
            [bB]|"")
                start_neo_radar
                return
                ;;
        esac
    done
}

# ====================================================================
# Main Radar
# ====================================================================
start_neo_radar() {
    clear
    echo ""
    echo -e "${CLR_DARKMAGENTA}============================================${CLR_RESET}"
    echo -e "${CLR_CYAN}         ░▒▓█ NEO RADAR v1.16 █▓▒░          ${CLR_RESET}"
    echo -e "${CLR_DARKMAGENTA}============================================${CLR_RESET}"
    echo -e "${CLR_MAGENTA}            Created By ItsNEOx              ${CLR_RESET}"
    echo -e "${CLR_DARKCYAN}      The super simple network radar      ${CLR_RESET}"
    echo -e "${CLR_DARKGRAY}            for legal purposes              ${CLR_RESET}"
    echo -e "${CLR_DARKMAGENTA}--------------------------------------------${CLR_RESET}"
    echo ""

    # Termux check
    if detect_termux; then
        echo -e "${CLR_DARKMAGENTA}--------------------------------------------${CLR_RESET}"
        echo -e "${CLR_YELLOW} [!] ANDROID/TERMUX DETECTED${CLR_RESET}"
        echo -e "${CLR_DARKMAGENTA}--------------------------------------------${CLR_RESET}"
        echo -e "${CLR_GRAY} Android locks ARP table access for security.${CLR_RESET}"
        echo -e "${CLR_YELLOW} Mode 4 (ARP MAC Lookup) will not return results.${CLR_RESET}"
        echo -e "${CLR_GRAY} All other modes work fine on Termux.${CLR_RESET}"
        echo -e "${CLR_DARKMAGENTA}--------------------------------------------${CLR_RESET}"
        echo ""
    fi

    echo -e "${CLR_CYAN}Choose scan mode:${CLR_RESET}"
    echo "1) Network Ping Scan"
    echo "2) Single Host Inspection (Ports + Hostname + OS)"
    echo "3) Ping + TCP port scan"
    echo "4) ARP Device MAC Lookup & Vendor Identification"
    echo "5) Hostname Scan & Fingerprinting (enhanced OS detection)"
    echo "6) Custom Port Scan"
    echo "7) Help / Feature Guide"
    echo "8) Check for Updates"
    echo "9) Nmap Command Reference"
    echo "E) Exit Program"
    echo ""

    while true; do
        read -r -p "Enter option number or 'E' to Exit (default: 1): " mode
        [ -z "$mode" ] && mode=1
        case "$mode" in
            [eE]) echo -e "\n${CLR_CYAN}Goodbye.${CLR_RESET}"; exit 0 ;;
            [1-9]) break ;;
            *) echo -e "  ${CLR_YELLOW}[!] Please enter a number between 1 and 9, or 'E' to exit.${CLR_RESET}" ;;
        esac
    done

    echo ""

    # ---------------------------------------------------------
    # Mode 7 — Help / Feature Guide
    # ---------------------------------------------------------
    if [ "$mode" = "7" ]; then
        echo -e "${CLR_DARKMAGENTA}============================================${CLR_RESET}"
        echo -e "${CLR_CYAN}         NEO RADAR - HELP & GUIDE           ${CLR_RESET}"
        echo -e "${CLR_DARKMAGENTA}============================================${CLR_RESET}"
        echo ""

        echo -e "${CLR_YELLOW}1) Network Ping Scan${CLR_RESET}"
        echo -e "${CLR_GRAY}   Multi-threaded ICMP sweep to find online hosts.${CLR_RESET}\n"

        echo -e "${CLR_YELLOW}2) Single Host Inspection${CLR_RESET}"
        echo -e "${CLR_GRAY}   Ping, TTL OS estimation, DNS/mDNS/NBT hostnames,${CLR_RESET}"
        echo -e "${CLR_GRAY}   and batched port scan on one IP. OS confidence based${CLR_RESET}"
        echo -e "${CLR_GRAY}   on TTL range accuracy (very high when TTL is known).${CLR_RESET}\n"

        echo -e "${CLR_YELLOW}3) Ping + TCP Port Scan${CLR_RESET}"
        echo -e "${CLR_GRAY}   Discover active hosts, then scan all common TCP ports${CLR_RESET}"
        echo -e "${CLR_GRAY}   per host in a single batch (faster).${CLR_RESET}\n"

        echo -e "${CLR_YELLOW}4) ARP Device MAC Lookup & Vendor Identification${CLR_RESET}"
        echo -e "${CLR_GRAY}   Queries kernel ARP tables for MAC addresses and vendors.${CLR_RESET}\n"

        echo -e "${CLR_YELLOW}5) Hostname Scan & Fingerprinting${CLR_RESET}"
        echo -e "${CLR_GRAY}   Multi-signal OS detection: TTL, ports, hostname, HTTP${CLR_RESET}"
        echo -e "${CLR_GRAY}   header, NetBIOS, and MAC OUI. Confidence: ≥80% very high,${CLR_RESET}"
        echo -e "${CLR_GRAY}   ≥60% high, ≥40% medium, <40% low.${CLR_RESET}\n"

        echo -e "${CLR_YELLOW}6) Custom Port Scan${CLR_RESET}"
        echo -e "${CLR_GRAY}   Scan every discovered host against a port list you provide${CLR_RESET}"
        echo -e "${CLR_GRAY}   (e.g. '22, 80, 8080'). Reports which hosts have each open.${CLR_RESET}\n"

        echo -e "${CLR_YELLOW}8) Check for Updates${CLR_RESET}"
        echo -e "${CLR_GRAY}   Checks GitHub for new releases.${CLR_RESET}\n"

        echo -e "${CLR_YELLOW}9) Nmap Command Reference${CLR_RESET}"
        echo -e "${CLR_GRAY}   Shows equivalent Nmap commands for each scan mode.${CLR_RESET}\n"

        echo -e "${CLR_RED}Android/Termux Note:${CLR_RESET}"
        echo -e "${CLR_GRAY}   Works on Termux, but Android locks ARP table access.${CLR_RESET}"
        echo -e "${CLR_YELLOW}   Mode 4 (ARP MAC Lookup) will NOT return results.${CLR_RESET}"
        echo -e "${CLR_GRAY}   All other modes work fine.${CLR_RESET}\n"

        show_end_options "true"
        return
    fi

    # ---------------------------------------------------------
    # Mode 8 — Check for Updates
    # ---------------------------------------------------------
    if [ "$mode" = "8" ]; then
        local_version="1.16"
        local_repo_raw="https://raw.githubusercontent.com/ItsNEOx/Neo-Radar/main/neoradar"
        local_repo_web="https://github.com/ItsNEOx/Neo-Radar"

        echo -e "${CLR_CYAN}[+] Checking GitHub for updates...${CLR_RESET}"

        remote_code=""
        if command -v curl >/dev/null 2>&1; then
            remote_code=$(curl -sSL --connect-timeout 5 "$local_repo_raw" 2>/dev/null)
        elif command -v wget >/dev/null 2>&1; then
            remote_code=$(wget -qO- --timeout=5 "$local_repo_raw" 2>/dev/null)
        fi

        if [ -n "$remote_code" ]; then
            remote_version=$(echo "$remote_code" | grep -oP 'v\d+\.\d+(?:\.\d+)?' | head -1 | tr -d 'v')
            echo -e "  ${CLR_YELLOW}Current Version: v$local_version${CLR_RESET}"
            if [ -n "$remote_version" ]; then
                echo -e "  ${CLR_GREEN}Latest Version : v$remote_version${CLR_RESET}"
                if [ "$remote_version" != "$local_version" ]; then
                    echo -e "\n${CLR_YELLOW}[!] A new update (v$remote_version) is available!${CLR_RESET}"
                    read -r -p "$(echo -e "${CLR_CYAN}[+] Download and install update? (y/N): ${CLR_RESET}")" choice
                    case "$choice" in
                        [yY])
                            tmp_file=$(mktemp)
                            dl_ok=0
                            if command -v curl >/dev/null 2>&1; then
                                curl -sSL --connect-timeout 10 "$local_repo_raw" -o "$tmp_file" 2>/dev/null && dl_ok=1
                            elif command -v wget >/dev/null 2>&1; then
                                wget -q --timeout=10 "$local_repo_raw" -O "$tmp_file" 2>/dev/null && dl_ok=1
                            fi
                            if [ "$dl_ok" = "1" ] && [ -s "$tmp_file" ] && grep -q "NEO RADAR" "$tmp_file"; then
                                if [ -w "$0" ]; then
                                    if cat "$tmp_file" > "$0" && chmod +x "$0"; then
                                        echo -e "  ${CLR_GREEN}[+] Update to v$remote_version complete!${CLR_RESET}"
                                        echo -e "  ${CLR_YELLOW}[!] Update ready! Please restart NEO RADAR to run the new version.${CLR_RESET}"
                                    else
                                        echo -e "  ${CLR_RED}[-] Failed to write update.${CLR_RESET}"
                                    fi
                                else
                                    echo -e "  ${CLR_YELLOW}[-] Cannot write to $0 (permission).${CLR_RESET}"
                                    echo -e "  ${CLR_YELLOW}    Run: sudo $0${CLR_RESET}"
                                fi
                                rm -f "$tmp_file"
                            else
                                echo -e "  ${CLR_RED}[-] Download failed or file corrupted.${CLR_RESET}"
                                echo -e "  ${CLR_YELLOW}    Visit: $local_repo_web${CLR_RESET}"
                                rm -f "$tmp_file"
                            fi
                            ;;
                        *)
                            echo -e "  ${CLR_YELLOW}    Visit: $local_repo_web${CLR_RESET}"
                            ;;
                    esac
                else
                    echo -e "\n${CLR_GREEN}[+] You are running the latest version!${CLR_RESET}"
                fi
            else
                echo -e "  ${CLR_RED}[-] Could not parse version.${CLR_RESET}"
                echo -e "  ${CLR_YELLOW}    Visit: $local_repo_web${CLR_RESET}"
            fi
        else
            echo -e "  ${CLR_RED}[-] Could not reach GitHub.${CLR_RESET}"
            echo -e "  ${CLR_YELLOW}    Visit: $local_repo_web${CLR_RESET}"
        fi

        show_end_options "true"
        return
    fi

    # ---------------------------------------------------------
    # Mode 9 — Nmap Command Reference
    # ---------------------------------------------------------
    if [ "$mode" = "9" ]; then
        clear
        echo -e "${CLR_DARKMAGENTA}============================================${CLR_RESET}"
        echo -e "${CLR_CYAN}       NEO RADAR - Nmap Command Guide       ${CLR_RESET}"
        echo -e "${CLR_DARKMAGENTA}============================================${CLR_RESET}"
        echo -e "${CLR_YELLOW}   How to perform each scan mode with Nmap ${CLR_RESET}"
        echo -e "${CLR_DARKMAGENTA}============================================${CLR_RESET}"
        echo ""

        echo -e "${CLR_YELLOW}1) Network Ping Scan${CLR_RESET}"
        echo -e "${CLR_GRAY}   Neo-Radar: ICMP sweep across a range of IPs.${CLR_RESET}"
        echo -e "   ${CLR_GREEN}Nmap:      nmap -sn 192.168.0.0/24${CLR_RESET}"
        echo -e "   ${CLR_DARKCYAN}Flags:${CLR_RESET}"
        echo -e "     ${CLR_DARKGRAY}-sn  -> Ping sweep only (no port scan)${CLR_RESET}"
        echo -e "     ${CLR_DARKGRAY}/24  -> CIDR notation for 192.168.0.1-254${CLR_RESET}"
        echo -e "   ${CLR_GRAY}Sends ICMP echo, TCP SYN to 443, TCP ACK to 80,${CLR_RESET}"
        echo -e "   ${CLR_GRAY}and ICMP timestamp requests simultaneously.${CLR_RESET}"
        echo ""

        echo -e "${CLR_YELLOW}2) Single Host Inspection${CLR_RESET}"
        echo -e "${CLR_GRAY}   Neo-Radar: Ping + TTL OS guess + DNS + port scan.${CLR_RESET}"
        echo -e "${CLR_GRAY}   OS confidence: very high when TTL matches known range${CLR_RESET}"
        echo -e "${CLR_GRAY}   (Windows 100-128, Linux/Unix 32-64, Network 240-255).${CLR_RESET}"
        echo -e "   ${CLR_GREEN}Nmap:      nmap -A 192.168.0.1${CLR_RESET}"
        echo -e "   ${CLR_DARKCYAN}Flags:${CLR_RESET}"
        echo -e "     ${CLR_DARKGRAY}-A  -> Aggressive (-O -sV -sC --traceroute)${CLR_RESET}"
        echo -e "   ${CLR_GRAY}Use -p- to scan all 65535 ports.${CLR_RESET}"
        echo ""

        echo -e "${CLR_YELLOW}3) Ping + TCP Port Scan${CLR_RESET}"
        echo -e "${CLR_GRAY}   Neo-Radar: Discover hosts, scan common TCP ports.${CLR_RESET}"
        echo -e "   ${CLR_GREEN}Nmap:      nmap -sS 192.168.0.0/24 -p 21,22,23,25,53,80,110,${CLR_RESET}"
        echo -e "     ${CLR_GREEN}135,139,143,443,445,993,995,1433,${CLR_RESET}"
        echo -e "     ${CLR_GREEN}3306,3389,5900,8080,8443${CLR_RESET}"
        echo -e "   ${CLR_DARKCYAN}Flags:${CLR_RESET}"
        echo -e "     ${CLR_DARKGRAY}-sS -> SYN scan (half-open, requires root)${CLR_RESET}"
        echo -e "     ${CLR_DARKGRAY}-sT -> TCP connect scan (no root needed)${CLR_RESET}"
        echo -e "     ${CLR_DARKGRAY}-p  -> Port list or range${CLR_RESET}"
        echo ""

        echo -e "${CLR_YELLOW}4) ARP MAC Lookup & Vendor Identification${CLR_RESET}"
        echo -e "${CLR_GRAY}   Neo-Radar: Queries ARP table for MAC addresses.${CLR_RESET}"
        echo -e "   ${CLR_GREEN}Nmap:      nmap -PR 192.168.0.0/24${CLR_RESET}"
        echo -e "   ${CLR_DARKCYAN}Flags:${CLR_RESET}"
        echo -e "     ${CLR_DARKGRAY}-PR -> ARP ping (local subnet, fastest)${CLR_RESET}"
        echo -e "   ${CLR_GRAY}ARP is Layer-2, local subnet only.${CLR_RESET}"
        echo -e "   ${CLR_GRAY}MACs also appear in standard -sn output.${CLR_RESET}"
        echo ""

        echo -e "${CLR_YELLOW}5) Hostname Scan & Fingerprinting${CLR_RESET}"
        echo -e "${CLR_GRAY}   Neo-Radar: Multi-signal OS detection with confidence rating.${CLR_RESET}"
        echo -e "${CLR_GRAY}   Signals: TTL, open ports, hostname, HTTP header, NetBIOS,${CLR_RESET}"
        echo -e "${CLR_GRAY}   MAC OUI. Points awarded to Windows/Linux/Apple/Network.${CLR_RESET}"
        echo -e "${CLR_GRAY}   Confidence: ≥80% very high, ≥60% high, ≥40% medium, <40% low.${CLR_RESET}"
        echo -e "   ${CLR_GREEN}Nmap:      nmap -sL 192.168.0.0/24  (DNS lookup)${CLR_RESET}"
        echo -e "     ${CLR_GREEN}nmap -O 192.168.0.0/24       (OS detection)${CLR_RESET}"
        echo -e "   ${CLR_DARKCYAN}Flags:${CLR_RESET}"
        echo -e "     ${CLR_DARKGRAY}-sL -> List scan / reverse-DNS${CLR_RESET}"
        echo -e "     ${CLR_DARKGRAY}-O  -> OS fingerprinting (TCP/IP stack)${CLR_RESET}"
        echo ""

        echo -e "${CLR_YELLOW}6) Custom Port Scan${CLR_RESET}"
        echo -e "${CLR_GRAY}   Neo-Radar: Scan a port list you choose across all live hosts.${CLR_RESET}"
        echo -e "   ${CLR_GREEN}Nmap:      nmap -sT 192.168.0.0/24 -p 22,80,8080${CLR_RESET}"
        echo -e "   ${CLR_DARKCYAN}Flags:${CLR_RESET}"
        echo -e "     ${CLR_DARKGRAY}-sT -> TCP connect scan (no root needed)${CLR_RESET}"
        echo -e "     ${CLR_DARKGRAY}-p  -> Comma-separated custom port list${CLR_RESET}"
        echo ""

        echo -e "${CLR_DARKMAGENTA}============================================${CLR_RESET}"
        echo -e "${CLR_CYAN} Quick Reference${CLR_RESET}"
        echo -e "${CLR_DARKMAGENTA}============================================${CLR_RESET}"
        echo -e "  ${CLR_GREEN}-sn${CLR_RESET}       Ping sweep host discovery"
        echo -e "  ${CLR_GREEN}-sS${CLR_RESET}       SYN half-open scan (requires root)"
        echo -e "  ${CLR_GREEN}-sT${CLR_RESET}       TCP connect scan"
        echo -e "  ${CLR_GREEN}-sV${CLR_RESET}       Service/version detection"
        echo -e "  ${CLR_GREEN}-O${CLR_RESET}        OS fingerprinting"
        echo -e "  ${CLR_GREEN}-sC${CLR_RESET}       Default NSE script scan"
        echo -e "  ${CLR_GREEN}-A${CLR_RESET}        Aggressive (-O -sV -sC --traceroute)"
        echo -e "  ${CLR_GREEN}-PR${CLR_RESET}       ARP ping (local subnet)"
        echo -e "  ${CLR_GREEN}-sL${CLR_RESET}       List scan / DNS resolution"
        echo -e "  ${CLR_GREEN}-p <n>${CLR_RESET}    Port range"
        echo -e "  ${CLR_GREEN}-T<0-5>${CLR_RESET}   Timing template (T4 faster)"
        echo -e "  ${CLR_GREEN}-v${CLR_RESET}        Increase verbosity"
        echo -e "  ${CLR_GREEN}--reason${CLR_RESET}  Shows why Nmap concluded a state"
        echo ""

        show_end_options "true"
        return
    fi

    # ---------------------------------------------------------
    # Mode 2 — Single Host Inspection
    # ---------------------------------------------------------
    if [ "$mode" = "2" ]; then
        while true; do
            read -r -p "Enter target IP address (Example : 192.168.0.1): " target_ip
            case "$target_ip" in
                [eE]) echo -e "\n${CLR_CYAN}Goodbye.${CLR_RESET}"; exit 0 ;;
                [bB]) start_neo_radar; return ;;
            esac
            if [ -z "$target_ip" ]; then
                echo -e "  ${CLR_YELLOW}[!] IP address is required.${CLR_RESET}"
                continue
            fi
            if validate_ip "$target_ip"; then break; fi
            echo -e "  ${CLR_YELLOW}[!] Invalid IP format. Use the form 192.168.0.1${CLR_RESET}"
        done

        echo -e "\n${CLR_CYAN}[+] Inspecting single host: $target_ip...${CLR_RESET}"

        ping_out=$(ping -c 1 -W 1 "$target_ip" 2>/dev/null)
        if [ $? -ne 0 ]; then
            echo -e "  ${CLR_YELLOW}[-] Host $target_ip did not respond to ping.${CLR_RESET}"
            show_end_options "false"
            return
        fi

        echo -e "  ${CLR_GREEN}[+] Host Status: ONLINE${CLR_RESET}"

        ttl=$(echo "$ping_out" | grep -i "ttl=" | sed -e 's/.*ttl=//i' | awk '{print $1}')
        [ -z "$ttl" ] && ttl="N/A"

        # Batched port scan (all ports per host in one job)
        echo -e "  ${CLR_CYAN}[+] Scanning ${#COMMON_PORTS[@]} common ports...${CLR_RESET}"
        tmp_dir=$(mktemp -d)
        (
            for port in "${COMMON_PORTS[@]}"; do
                if check_port "$target_ip" "$port"; then
                    echo "$port" >> "$tmp_dir/ports"
                fi
            done
        ) &
        wait
        open_ports=()
        if [ -f "$tmp_dir/ports" ]; then
            while IFS= read -r p; do open_ports+=("$p"); done < "$tmp_dir/ports"
        fi
        rm -rf "$tmp_dir"

        host_name=$(resolve_hostname "$target_ip")

        # OS Detection (TTL-based with Apple hostname hint)
        if [ "$ttl" != "N/A" ]; then
            if [ "$ttl" -ge 100 ] && [ "$ttl" -le 128 ]; then os="Windows"
            elif [ "$ttl" -ge 32 ] && [ "$ttl" -le 64 ]; then os="Linux / Unix / Android / macOS"
            elif [ "$ttl" -ge 240 ]; then os="Network / IoT Device"
            else os="Unknown"; fi
        else
            os="Unknown"
        fi

        # Apple override via hostname
        if [ -n "$host_name" ] && [ "$host_name" != "Unavailable" ]; then
            hname_upper=$(echo "$host_name" | tr 'a-z' 'A-Z')
            case "$hname_upper" in
                IPHONE*|IPAD*|IPOD*) os="Apple iOS" ;;
                MACBOOK*|MAC-PRO*|IMAC*|MACMINI*) os="Apple macOS" ;;
            esac
        fi

        echo -e "\n${CLR_DARKMAGENTA}--------------------------------------------${CLR_RESET}"
        echo -e "${CLR_CYAN} Host Details: $target_ip${CLR_RESET}"
        echo -e "${CLR_DARKMAGENTA}--------------------------------------------${CLR_RESET}"
        echo -e "  ${CLR_GREEN}Hostname : $host_name${CLR_RESET}"
        echo -e "  ${CLR_GREEN}OS Family: $os (TTL: $ttl)${CLR_RESET}"

        if [ "${#open_ports[@]}" -gt 0 ]; then
            ports_text=$(IFS=', '; echo "${open_ports[*]}")
            echo -e "  ${CLR_GREEN}Open Ports: $ports_text${CLR_RESET}"
        else
            ports_text="No open ports found (checked ${#COMMON_PORTS[@]} common ports)"
            echo -e "  ${CLR_DARKGRAY}Open Ports: $ports_text${CLR_RESET}"
        fi

        scan_log=(
            "============================================"
            " NEO RADAR - Single Host Inspection Log"
            " Timestamp : $(date)"
            " Target IP : $target_ip"
            " Hostname  : $host_name"
            " OS Family : $os (TTL: $ttl)"
            " Open Ports: $ports_text"
            "============================================"
        )

        show_end_options "false" "${scan_log[@]}"
        return
    fi

    # ---------------------------------------------------------
    # Mode 6 — Custom Port List Input
    # ---------------------------------------------------------
    custom_ports=()
    if [ "$mode" = "6" ]; then
        while true; do
            echo -e "${CLR_DARKGRAY}Enter 'B' for Main Menu, or 'E' to Exit.${CLR_RESET}"
            read -r -p "Enter port(s) to scan across the network, separated by commas (Example : 22, 80, 8080): " port_input
            case "$port_input" in
                [eE]) echo -e "\n${CLR_CYAN}Goodbye.${CLR_RESET}"; exit 0 ;;
                [bB]) start_neo_radar; return ;;
            esac

            invalid_ports=""
            custom_ports=()
            for token in $(echo "$port_input" | tr ',' ' '); do
                case "$token" in
                    *[!0-9]*)
                        invalid_ports="$invalid_ports $token"
                        ;;
                    *)
                        if [ "$token" -ge 1 ] && [ "$token" -le 65535 ] 2>/dev/null; then
                            is_dup=0
                            for existing_port in "${custom_ports[@]}"; do
                                [ "$existing_port" = "$token" ] && is_dup=1
                            done
                            [ "$is_dup" -eq 0 ] && custom_ports+=("$token")
                        else
                            invalid_ports="$invalid_ports $token"
                        fi
                        ;;
                esac
            done

            if [ "${#custom_ports[@]}" -eq 0 ]; then
                echo -e "  ${CLR_YELLOW}[!] Please enter at least one valid port number (1-65535).${CLR_RESET}"
            elif [ -n "$invalid_ports" ]; then
                echo -e "  ${CLR_YELLOW}[!] Invalid port(s):$invalid_ports. Use numbers between 1 and 65535.${CLR_RESET}"
            else
                IFS=$'\n' sorted_ports=($(sort -n <<<"${custom_ports[*]}")); unset IFS
                custom_ports=("${sorted_ports[@]}")
                break
            fi
        done
        echo ""
    fi

    # ---------------------------------------------------------
    # Subnet Prompt (Modes 1, 3, 4, 5, 6)
    # ---------------------------------------------------------
    echo -e "${CLR_DARKGRAY}Enter 'B' for Main Menu, or 'E' to Exit.${CLR_RESET}"
    read -r -p "Enter target network prefix (default: $DEFAULT_PREFIX): " prefix_input
    case "$prefix_input" in
        [eE]) echo -e "\n${CLR_CYAN}Goodbye.${CLR_RESET}"; exit 0 ;;
        [bB]) start_neo_radar; return ;;
    esac
    prefix="${prefix_input:-$DEFAULT_PREFIX}"
    while [[ "$prefix" == *"." ]]; do
        prefix="${prefix%.}"
    done

    # If user typed 4 octets (e.g. 192.168.0.0 or 172.92.50.1), drop the last to get a 3-octet prefix
    IFS='.' read -ra prefixOctets <<< "$prefix"
    if [ "${#prefixOctets[@]}" -eq 4 ]; then
        prefix="${prefixOctets[0]}.${prefixOctets[1]}.${prefixOctets[2]}"
    fi

    while true; do
        read -r -p "Enter starting host number (1-255, default: 1): " start_input
        case "$start_input" in
            [eE]) echo -e "\n${CLR_CYAN}Goodbye.${CLR_RESET}"; exit 0 ;;
            [bB]) start_neo_radar; return ;;
            "") start_host=1; break ;;
            *[!0-9]*) echo -e "  ${CLR_YELLOW}[!] Numbers only, between 1 and 255.${CLR_RESET}" ;;
            *)
                if [ "$start_input" -ge 1 ] && [ "$start_input" -le 255 ] 2>/dev/null; then
                    start_host=$start_input; break
                else
                    echo -e "  ${CLR_YELLOW}[!] Numbers only, between 1 and 255.${CLR_RESET}"
                fi
                ;;
        esac
    done

    while true; do
        read -r -p "Enter ending host number (1-255, default: 254): " end_input
        case "$end_input" in
            [eE]) echo -e "\n${CLR_CYAN}Goodbye.${CLR_RESET}"; exit 0 ;;
            [bB]) start_neo_radar; return ;;
            "") end_host=254; break ;;
            *[!0-9]*) echo -e "  ${CLR_YELLOW}[!] Numbers only, between 1 and 255.${CLR_RESET}" ;;
            *)
                if [ "$end_input" -ge 1 ] && [ "$end_input" -le 255 ] 2>/dev/null; then
                    end_host=$end_input; break
                else
                    echo -e "  ${CLR_YELLOW}[!] Numbers only, between 1 and 255.${CLR_RESET}"
                fi
                ;;
        esac
    done

    if [ "$start_host" -gt "$end_host" ]; then
        echo -e "  ${CLR_YELLOW}[!] Starting host cannot be greater than ending host.${CLR_RESET}"
        start_neo_radar
        return
    fi

    echo -e "\n${CLR_CYAN}[+] Starting live sweep on $prefix.$start_host through $prefix.$end_host...${CLR_RESET}"
    echo -e "${CLR_DARKMAGENTA}--------------------------------------------${CLR_RESET}"

    # ---------------------------------------------------------
    # Ping Sweep Engine
    # ---------------------------------------------------------
    tmp_ping_dir=$(mktemp -d)
    for (( i=start_host; i<=end_host; i++ )); do
        (
            ip="$prefix.$i"
            ping_res=$(ping -c 1 -W 1 "$ip" 2>/dev/null)
            if [ $? -eq 0 ]; then
                rtt=$(echo "$ping_res" | grep -i "time=" | sed -e 's/.*time=//i' | awk '{print $1}')
                [ -z "$rtt" ] && rtt="<1"
                echo "$rtt" > "$tmp_ping_dir/$i"
                echo -e "  ${CLR_GREEN}[+] Discovered: $ip [RTT: ${rtt}ms]${CLR_RESET}"
            fi
        ) &
        running_jobs=$(jobs -r -p | wc -l)
        [ "$running_jobs" -ge 64 ] && sleep 0.02
    done
    wait

    alive=()
    for (( i=start_host; i<=end_host; i++ )); do
        [ -f "$tmp_ping_dir/$i" ] && alive+=("$prefix.$i")
    done
    rm -rf "$tmp_ping_dir"

    echo -e "${CLR_DARKMAGENTA}--------------------------------------------${CLR_RESET}"
    echo -e "${CLR_CYAN}Sweep Complete. Total Active Hosts: ${#alive[@]}${CLR_RESET}"

    if [ "${#alive[@]}" -eq 0 ]; then
        echo -e "  ${CLR_YELLOW}[-] No hosts responded.${CLR_RESET}"
        show_end_options "false" "No active hosts discovered on $prefix.$start_host-$end_host"
        return
    fi

    # ---------------------------------------------------------
    # Mode 1 — Network Ping Scan
    # ---------------------------------------------------------
    if [ "$mode" = "1" ]; then
        echo -e "\n${CLR_CYAN}Sorted Active Hosts:${CLR_RESET}"
        for h in "${alive[@]}"; do echo -e "  ${CLR_GREEN}[+] $h${CLR_RESET}"; done

        scan_log=(
            "============================================"
            " NEO RADAR - Network Ping Scan Log"
            " Timestamp : $(date)"
            " Target    : $prefix.$start_host-$end_host"
            " Total     : ${#alive[@]} active hosts"
            "--------------------------------------------"
        )
        for h in "${alive[@]}"; do scan_log+=("  [+] $h"); done
        scan_log+=("============================================")

        show_end_options "false" "${scan_log[@]}"
        return
    fi

    # ---------------------------------------------------------
    # Mode 6 — Custom Port Scan (user-defined port list, BATCHED per host)
    # ---------------------------------------------------------
    if [ "$mode" = "6" ]; then
        ports_label=$(IFS=', '; echo "${custom_ports[*]}")
        echo -e "\n${CLR_CYAN}[+] Scanning ${#custom_ports[@]} custom port(s) [$ports_label] across active hosts...${CLR_RESET}"

        tmp_port_dir=$(mktemp -d)
        for target in "${alive[@]}"; do
            (
                for port in "${custom_ports[@]}"; do
                    if check_port "$target" "$port"; then
                        echo "$port" >> "$tmp_port_dir/$target"
                    fi
                done
            ) &
            running_jobs=$(jobs -r -p | wc -l)
            [ "$running_jobs" -ge 64 ] && sleep 0.02
        done
        wait

        # Split hosts into found / not-found groups
        found_hosts=()
        notfound_hosts=()
        for target in "${alive[@]}"; do
            if [ -s "$tmp_port_dir/$target" ]; then
                found_hosts+=("$target")
            else
                notfound_hosts+=("$target")
            fi
        done

        echo -e "\n${CLR_CYAN}Custom Port Scan Results:${CLR_RESET}"

        scan_log=(
            "============================================"
            " NEO RADAR - Custom Port Scan Log"
            " Timestamp : $(date)"
            " Target    : $prefix.$start_host-$end_host"
            " Ports     : $ports_label"
            "--------------------------------------------"
        )

        echo ""
        echo -e "${CLR_GREEN}=== FOUND - Hosts With Open Ports (${#found_hosts[@]}) ===${CLR_RESET}"
        scan_log+=("FOUND - Hosts With Open Ports (${#found_hosts[@]})")
        if [ "${#found_hosts[@]}" -eq 0 ]; then
            echo -e "  ${CLR_DARKGRAY}None${CLR_RESET}"
            scan_log+=("  None")
        fi
        for target in "${found_hosts[@]}"; do
            echo ""
            echo -e "${CLR_YELLOW}Host: $target${CLR_RESET}"
            echo -e "${CLR_DARKMAGENTA}-------------------------${CLR_RESET}"
            scan_log+=("" "Host: $target")
            for port in "${custom_ports[@]}"; do
                if grep -qw "$port" "$tmp_port_dir/$target" 2>/dev/null; then
                    echo -e "  ${CLR_GREEN}  Port $port : OPEN${CLR_RESET}"
                    scan_log+=("    Port $port : OPEN")
                fi
            done
        done

        noopen_list=""
        for target in "${notfound_hosts[@]}"; do
            [ -n "$noopen_list" ] && noopen_list="$noopen_list, "
            noopen_list="$noopen_list$target"
        done

        echo ""
        echo -e "${CLR_YELLOW}=== NOT FOUND - No Open Ports (${#notfound_hosts[@]}) ===${CLR_RESET}"
        if [ "${#notfound_hosts[@]}" -eq 0 ]; then
            echo -e "  ${CLR_DARKGRAY}None${CLR_RESET}"
            scan_log+=("" "NOT FOUND - No Open Ports (0)" "  None")
        else
            echo -e "  ${CLR_DARKGRAY}$noopen_list${CLR_RESET}"
            scan_log+=("" "NOT FOUND - No Open Ports (${#notfound_hosts[@]})" "  $noopen_list")
        fi

        scan_log+=("============================================")
        rm -rf "$tmp_port_dir"

        show_end_options "false" "${scan_log[@]}"
        return
    fi

    # ---------------------------------------------------------
    # Mode 3 — Ping + TCP Port Scan (BATCHED per host)
    # ---------------------------------------------------------
    if [ "$mode" = "3" ]; then
        echo -e "\n${CLR_CYAN}[+] Scanning ${#COMMON_PORTS[@]} common TCP ports across active hosts...${CLR_RESET}"

        tmp_port_dir=$(mktemp -d)
        for target in "${alive[@]}"; do
            (
                for port in "${COMMON_PORTS[@]}"; do
                    if check_port "$target" "$port"; then
                        echo "$port" >> "$tmp_port_dir/$target"
                    fi
                done
            ) &
            running_jobs=$(jobs -r -p | wc -l)
            [ "$running_jobs" -ge 64 ] && sleep 0.02
        done
        wait

        # Split hosts into found / not-found groups
        found_hosts=()
        notfound_hosts=()
        for target in "${alive[@]}"; do
            if [ -s "$tmp_port_dir/$target" ]; then
                found_hosts+=("$target")
            else
                notfound_hosts+=("$target")
            fi
        done

        echo -e "\n${CLR_CYAN}TCP Port Scan Results:${CLR_RESET}"

        scan_log=(
            "============================================"
            " NEO RADAR - Ping + TCP Port Scan Log"
            " Timestamp : $(date)"
            " Target    : $prefix.$start_host-$end_host"
            " Scanned   : ${#COMMON_PORTS[@]} Common Ports"
            "--------------------------------------------"
        )

        echo ""
        echo -e "${CLR_GREEN}=== FOUND - Hosts With Open Ports (${#found_hosts[@]}) ===${CLR_RESET}"
        scan_log+=("FOUND - Hosts With Open Ports (${#found_hosts[@]})")
        if [ "${#found_hosts[@]}" -eq 0 ]; then
            echo -e "  ${CLR_DARKGRAY}None${CLR_RESET}"
            scan_log+=("  None")
        fi
        for target in "${found_hosts[@]}"; do
            echo ""
            echo -e "${CLR_YELLOW}Host: $target${CLR_RESET}"
            echo -e "${CLR_DARKMAGENTA}-------------------------${CLR_RESET}"
            scan_log+=("" "Host: $target")
            for port in "${COMMON_PORTS[@]}"; do
                if grep -qw "$port" "$tmp_port_dir/$target" 2>/dev/null; then
                    echo -e "  ${CLR_GREEN}  Port $port : OPEN${CLR_RESET}"
                    scan_log+=("    Port $port : OPEN")
                fi
            done
        done

        noopen_list=""
        for target in "${notfound_hosts[@]}"; do
            [ -n "$noopen_list" ] && noopen_list="$noopen_list, "
            noopen_list="$noopen_list$target"
        done

        echo ""
        echo -e "${CLR_YELLOW}=== NOT FOUND - No Open Ports (${#notfound_hosts[@]}) ===${CLR_RESET}"
        if [ "${#notfound_hosts[@]}" -eq 0 ]; then
            echo -e "  ${CLR_DARKGRAY}None${CLR_RESET}"
            scan_log+=("" "NOT FOUND - No Open Ports (0)" "  None")
        else
            echo -e "  ${CLR_DARKGRAY}$noopen_list${CLR_RESET}"
            scan_log+=("" "NOT FOUND - No Open Ports (${#notfound_hosts[@]})" "  $noopen_list")
        fi

        scan_log+=("============================================")
        rm -rf "$tmp_port_dir"

        show_end_options "false" "${scan_log[@]}"
        return
    fi

    # ---------------------------------------------------------
    # Mode 4 — Fast ARP Device Identification (single broadcast)
    # ---------------------------------------------------------
    if [ "$mode" = "4" ]; then
        echo -e "\n${CLR_CYAN}[+] Refreshing ARP entries with broadcast ping...${CLR_RESET}"

        ping -c 1 -W 1 -b "$prefix.255" >/dev/null 2>&1
        sleep 0.3

        load_oui_cache

        echo -e "\n${CLR_CYAN}Device MAC Addresses & Manufacturer Identification:${CLR_RESET}"

        scan_log=(
            "============================================"
            " NEO RADAR - MAC Lookup & Vendor ID Log"
            " Timestamp : $(date)"
            " Target    : $prefix.$start_host-$end_host"
            "--------------------------------------------"
        )

        for ip in "${alive[@]}"; do
            mac=$(get_mac_address "$ip")
            vendor=$(get_vendor "$mac")

            if [ "$mac" != "Unavailable" ]; then
                echo -e "  ${CLR_GREEN}$ip  ->  $mac  [$vendor]${CLR_RESET}"
                scan_log+=("  $ip  ->  $mac  [$vendor]")
            else
                echo -e "  ${CLR_DARKGRAY}$ip  ->  MAC Unavailable${CLR_RESET}"
                scan_log+=("  $ip  ->  MAC Unavailable")
            fi
        done
        scan_log+=("============================================")

        show_end_options "false" "${scan_log[@]}"
        return
    fi

    # ---------------------------------------------------------
    # Mode 5 — Hostname Scan & Fingerprinting (multi-signal)
    # ---------------------------------------------------------
    if [ "$mode" = "5" ]; then
        echo -e "\n${CLR_CYAN}[+] Resolving Hostnames & OS Profiling...${CLR_RESET}"

        tmp_host_dir=$(mktemp -d)

        for target in "${alive[@]}"; do
            (
                host_name=$(resolve_hostname "$target")

                ping_out=$(ping -c 1 -W 1 "$target" 2>/dev/null)
                ttl=$(echo "$ping_out" | grep -i "ttl=" | sed -e 's/.*ttl=//i' | awk '{print $1}')
                [ -z "$ttl" ] && ttl=0

                # Probe key ports for OS fingerprinting
                open_ports=()
                for port in "${KEY_PORTS[@]}"; do
                    if check_port "$target" "$port"; then
                        open_ports+=("$port")
                    fi
                done

                os_result=$(fingerprint_os "$target" "$ttl" "$host_name" "${open_ports[@]}")
                IFS='|' read -r os confidence sig_detail <<< "$os_result"

                # Build port hint string
                hint=""
                for p in "${open_ports[@]}"; do
                    [ -n "$hint" ] && hint="$hint, "
                    hint="$hint$(port_service $p)"
                done
                [ -n "$hint" ] && hint=" [$hint]"

                echo "Host: $host_name | OS: $os (confidence: $confidence)$hint $sig_detail" > "$tmp_host_dir/$target"
            ) &
        done
        wait

        echo -e "\n${CLR_CYAN}Hostname & OS Results:${CLR_RESET}"

        scan_log=(
            "============================================"
            " NEO RADAR - Hostname Scan & Fingerprinting Log"
            " Timestamp : $(date)"
            " Target    : $prefix.$start_host-$end_host"
            "--------------------------------------------"
        )

        for target in "${alive[@]}"; do
            if [ -f "$tmp_host_dir/$target" ]; then
                details=$(cat "$tmp_host_dir/$target")
                echo -e "  ${CLR_GREEN}$target -> $details${CLR_RESET}"
                scan_log+=("  $target -> $details")
            fi
        done
        scan_log+=("============================================")
        rm -rf "$tmp_host_dir"

        show_end_options "false" "${scan_log[@]}"
        return
    fi

    show_end_options "false"
}

start_neo_radar
