#!/bin/bash

#==============================================================================
# Proxmox IP Scanner
# Описание: Сканира всички LXC контейнери и VM за IP адреси, проверява за
#           дублирани IP и показва отворени портове
#
# Употреба:
#   ./check-ips.sh                    - Основна проверка на IP адресите
#   ./check-ips.sh -p                 - Показва и отворените портове
#   ./check-ips.sh -o report.txt      - Записва резултата във файл
#   ./check-ips.sh -p -o report.txt   - Показва портове И записва във файл
#   ./check-ips.sh -h                 - Показва помощта
#
# Параметри:
#   -p, --ports    Показва отворените портове на работещите контейнери
#   -o, --output   Записва резултата във файл (презаписва файла ако съществува)
#   -h, --help     Показва помощната информация
#
# Примери:
#   ./check-ips.sh -p                          # Проверка с портове
#   ./check-ips.sh -o /root/ip-report.txt      # Запис в /root/
#   ./check-ips.sh --ports --output scan.txt   # Пълен скан със запис
#==============================================================================

# Цветове за терминала
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

OUTPUT_FILE=""
SHOW_PORTS=false

# Обработка на параметри
while [[ $# -gt 0 ]]; do
    case $1 in
        -o|--output)
            OUTPUT_FILE="$2"
            shift 2
            ;;
        -p|--ports)
            SHOW_PORTS=true
            shift
            ;;
        -h|--help)
            echo "Употреба: $0 [-o файл] [-p]"
            echo "  -o, --output FILE    Записва резултата във файл"
            echo "  -p, --ports          Показва отворените портове"
            echo "  -h, --help           Показва тази помощ"
            exit 0
            ;;
        *)
            echo "Непознат параметър: $1"
            exit 1
            ;;
    esac
done

# Функция за запис и показване
log() {
    echo -e "$1"
    if [ -n "$OUTPUT_FILE" ]; then
        echo -e "$1" | sed 's/\x1b\[[0-9;]*m//g' >> "$OUTPUT_FILE"
    fi
}

# Изчистване на файла ако съществува
if [ -n "$OUTPUT_FILE" ]; then
    > "$OUTPUT_FILE"
fi

log "${BLUE}=== Proxmox IP Проверка ===${NC}"
log "Дата: $(date '+%Y-%m-%d %H:%M:%S')\n"

# Масив за съхранение на IP адреси
declare -A ip_list
declare -A ip_owners

# Обхождане на всички LXC контейнери
log "${GREEN}Сканиране на LXC контейнери...${NC}\n"

for ctid in $(pct list | awk 'NR>1 {print $1}'); do
    name=$(pct list | grep "^$ctid" | awk '{print $3}')
    status=$(pct status $ctid | awk '{print $2}')
    
    log "${YELLOW}CT $ctid${NC} - $name [$status]"
    
    # Четене на конфигурацията
    config_file="/etc/pve/lxc/${ctid}.conf"
    
    if [ -f "$config_file" ]; then
        # Извличане на IP адреси от конфигурацията
        ips=$(grep -E "^net[0-9]+:" "$config_file" | grep -oP 'ip=\K[^/,]+' | sort -u)
        
        if [ -n "$ips" ]; then
            while IFS= read -r ip; do
                if [ "$ip" != "dhcp" ]; then
                    log "  IP: ${GREEN}$ip${NC}"
                    
                    # Проверка за дублиране
                    if [ -n "${ip_list[$ip]}" ]; then
                        ip_list[$ip]="${ip_list[$ip]}, CT$ctid($name)"
                    else
                        ip_list[$ip]="CT$ctid($name)"
                    fi
                    
                    ip_owners[$ip]+="CT$ctid($name) "
                    
                    # Проверка на портове ако контейнера работи
                    if [ "$status" = "running" ] && [ "$SHOW_PORTS" = true ]; then
                        ports=$(pct exec $ctid -- ss -tlnp 2>/dev/null | awk 'NR>1 {print $4}' | grep -oP ':\K[0-9]+$' | sort -u | tr '\n' ' ')
                        if [ -n "$ports" ]; then
                            log "  Портове: ${BLUE}$ports${NC}"
                        fi
                    fi
                fi
            done <<< "$ips"
        else
            log "  ${YELLOW}Няма намерени IP адреси${NC}"
        fi
    fi
    log ""
done

# Проверка за VM (опционално)
log "${GREEN}Сканиране на VM...${NC}\n"

for vmid in $(qm list | awk 'NR>1 {print $1}'); do
    name=$(qm list | grep "^$vmid" | awk '{print $2}')
    status=$(qm status $vmid | awk '{print $2}')
    
    log "${YELLOW}VM $vmid${NC} - $name [$status]"
    
    config_file="/etc/pve/qemu-server/${vmid}.conf"
    
    if [ -f "$config_file" ]; then
        # Извличане на IP от конфигурацията (ако е зададен статично)
        ips=$(grep -oP 'ip=\K[^/,]+' "$config_file" 2>/dev/null | sort -u)
        
        if [ -n "$ips" ]; then
            while IFS= read -r ip; do
                log "  IP: ${GREEN}$ip${NC}"
                
                if [ -n "${ip_list[$ip]}" ]; then
                    ip_list[$ip]="${ip_list[$ip]}, VM$vmid($name)"
                else
                    ip_list[$ip]="VM$vmid($name)"
                fi
                
                ip_owners[$ip]+="VM$vmid($name) "
            done <<< "$ips"
        else
            log "  ${YELLOW}Няма статични IP (DHCP или config празен)${NC}"
        fi
    fi
    log ""
done

# Проверка за дублирани IP
log "\n${BLUE}=== Анализ на IP адреси ===${NC}\n"

duplicate_found=false
for ip in "${!ip_list[@]}"; do
    count=$(echo "${ip_owners[$ip]}" | wc -w)
    if [ $count -gt 1 ]; then
        duplicate_found=true
        log "${RED}⚠ ДУБЛИРАН IP: $ip${NC}"
        log "  Използва се от: ${ip_owners[$ip]}"
        log ""
    fi
done

if [ "$duplicate_found" = false ]; then
    log "${GREEN}✓ Няма дублирани IP адреси${NC}\n"
fi

# Обобщена таблица
log "${BLUE}=== Всички IP адреси ===${NC}"
log "$(printf '%-18s | %s' 'IP Адрес' 'Собственик')"
log "$(printf '%s' '-------------------+----------------------------------------')"

for ip in $(echo "${!ip_list[@]}" | tr ' ' '\n' | sort -V); do
    count=$(echo "${ip_owners[$ip]}" | wc -w)
    if [ $count -gt 1 ]; then
        color=$RED
    else
        color=$NC
    fi
    log "${color}$(printf '%-18s | %s' "$ip" "${ip_list[$ip]}")${NC}"
done

if [ -n "$OUTPUT_FILE" ]; then
    log "\n${GREEN}Резултатът е записан във: $OUTPUT_FILE${NC}"
fi