#!/bin/bash # UPnP Device Sniffer avec déduplication # Découverte et analyse des devices UPnP sur le réseau set -e # Couleurs pour l'affichage RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' CYAN='\033[0;36m' NC='\033[0m' # No Color # Configuration INTERFACE="${1:-en0}" TIMEOUT="${2:-5}" TEMP_FILE=$(mktemp) SEEN_FILE=$(mktemp) echo -e "${CYAN}" echo "╔══════════════════════════════════════╗" echo "║ UPnP Device Sniffer PRO ║" echo "║ Avec déduplication des devices ║" echo "╚══════════════════════════════════════╝" echo -e "${NC}" # Nettoyage à la sortie cleanup() { rm -f "$TEMP_FILE" "$SEEN_FILE" echo -e "${YELLOW}🧹 Fichiers temporaires nettoyés.${NC}" } trap cleanup EXIT # Fonction pour extraire les codecs audio extract_audio_codecs() { grep -i "protocolInfo" | grep -i "audio" | \ sed 's/.*\(audio.*\)/\1/' | sort -u | head -8 } # Fonction pour formater l'URL format_url() { echo "$1" | sed 's/.*http/http/' | sed 's/\/$//' } # Fonction pour normaliser le nom du device normalize_name() { echo "$1" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]//g' } # Fonction pour vérifier si un device a déjà été vu is_device_seen() { local key="$1" grep -q "^$key$" "$SEEN_FILE" 2>/dev/null } # Fonction pour marquer un device comme vu mark_device_seen() { local key="$1" echo "$key" >> "$SEEN_FILE" } echo -e "${YELLOW}🔍 Recherche des devices UPnP sur $INTERFACE (${TIMEOUT}s)...${NC}" echo -e "${YELLOW}📡 Filtrage des doublons activé...${NC}" echo # Phase 1: Collecte des devices avec déduplication echo -e "${BLUE}📦 Phase 1: Collecte des devices...${NC}" DEVICE_COUNT=0 gssdp-discover --timeout $TIMEOUT -i $INTERFACE 2>/dev/null | \ while IFS= read -r line; do if [[ $line == *"Location:"* ]]; then url=$(format_url "$(echo "$line" | awk '{print $2}')") # Récupération des infos de base pour la déduplication if curl_output=$(curl -s --connect-timeout 2 "$url" 2>/dev/null); then friendly_name=$(echo "$curl_output" | grep -i "friendlyName" | head -1 | sed 's/.*\(.*\)<\/friendlyName>.*/\1/') model_name=$(echo "$curl_output" | grep -i "modelName" | head -1 | sed 's/.*\(.*\)<\/modelName>.*/\1/') # Création d'une clé unique pour la déduplication device_key=$(normalize_name "${friendly_name}-${model_name}") # Vérifier si on a déjà vu ce device if ! is_device_seen "$device_key"; then mark_device_seen "$device_key" ((DEVICE_COUNT++)) # Stocker les données pour l'affichage echo "===DEVICE_START===" >> "$TEMP_FILE" echo "URL:$url" >> "$TEMP_FILE" echo "FRIENDLY_NAME:$friendly_name" >> "$TEMP_FILE" echo "MODEL:$model_name" >> "$TEMP_FILE" echo "MANUFACTURER:$(echo "$curl_output" | grep -i "manufacturer" | head -1 | sed 's/.*\(.*\)<\/manufacturer>.*/\1/')" >> "$TEMP_FILE" echo "CURL_OUTPUT:$curl_output" >> "$TEMP_FILE" echo "===DEVICE_END===" >> "$TEMP_FILE" else echo -e "${YELLOW} ⚡ Doublon ignoré: $friendly_name${NC}" >&2 fi fi fi done # Phase 2: Affichage organisé des devices uniques echo -e "${BLUE}📊 Phase 2: Analyse des devices uniques...${NC}" echo FINAL_COUNT=0 # Lire le fichier temporaire et afficher les résultats while IFS= read -r line; do case $line in "===DEVICE_START===") unset url friendly_name model_name manufacturer curl_output ;; "===DEVICE_END===") if [[ -n "$url" ]]; then ((FINAL_COUNT++)) echo -e "${GREEN}╔══════════════════════════════════════╗${NC}" echo -e "${GREEN}║ Device #$FINAL_COUNT${NC}" echo -e "${GREEN}║ URL: $url${NC}" echo -e "${GREEN}╚══════════════════════════════════════╗${NC}" echo -e "${BLUE}📝 Informations:${NC}" echo -e " Nom: ${YELLOW}${friendly_name:-Non trouvé}${NC}" echo -e " Modèle: ${YELLOW}${model_name:-Non trouvé}${NC}" echo -e " Fabricant: ${YELLOW}${manufacturer:-Non trouvé}${NC}" # Codecs audio supportés echo -e "${BLUE}🎵 Codecs audio:${NC}" audio_codecs=$(echo "$curl_output" | extract_audio_codecs) if [ -n "$audio_codecs" ]; then echo "$audio_codecs" | while read codec; do echo -e " ✅ ${GREEN}$codec${NC}" done else echo -e " ❌ ${RED}Aucun codec audio détecté${NC}" fi # Services détectés echo -e "${BLUE}🔌 Services principaux:${NC}" services=$(echo "$curl_output" | grep -i "serviceType" | sed 's/.*\(.*\)<\/serviceType>.*/\1/' | head -3) if [ -n "$services" ]; then echo "$services" | while read service; do echo -e " 🔧 ${PURPLE}$service${NC}" done fi echo fi ;; URL:*) url="${line#URL:}" ;; FRIENDLY_NAME:*) friendly_name="${line#FRIENDLY_NAME:}" ;; MODEL:*) model_name="${line#MODEL:}" ;; MANUFACTURER:*) manufacturer="${line#MANUFACTURER:}" ;; CURL_OUTPUT:*) curl_output="${line#CURL_OUTPUT:}" ;; esac done < "$TEMP_FILE" # Résumé final echo -e "${CYAN}" echo "╔══════════════════════════════════════╗" echo "║ SCAN TERMINÉ ║" echo "╠══════════════════════════════════════╣" echo "║ Devices uniques: $FINAL_COUNT ║" echo "╚══════════════════════════════════════╝" echo -e "${NC}"