#!/bin/bash

# ============================================
#  UDP 联通性对照测试工具 (udping)
#  用法: udping <IP地址> <端口>
# ============================================

# 颜色定义
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'

# 显示使用帮助
show_usage() {
    echo -e "${CYAN}用法:${NC}"
    echo -e "  $(basename $0) <IP地址> <端口>"
    echo -e "\n${CYAN}示例:${NC}"
    echo -e "  $(basename $0) 8.8.8.8 53"
    echo -e "  $(basename $0) 192.168.1.1 123"
    echo -e "\n${CYAN}说明:${NC}"
    echo -e "  IP地址  - 目标服务器的 IPv4 地址"
    echo -e "  端口    - UDP 端口号 (1-65535)"
    exit 1
}

# 验证 IP 地址格式
validate_ip() {
    local ip=$1
    # 正则表达式匹配 IPv4 格式
    if [[ $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
        # 检查每个八位组是否在 0-255 范围内
        IFS='.' read -ra ADDR <<< "$ip"
        for i in "${ADDR[@]}"; do
            if [ $i -gt 255 ]; then
                return 1
            fi
        done
        return 0
    else
        return 1
    fi
}

# 验证端口号
validate_port() {
    local port=$1
    if [[ $port =~ ^[0-9]+$ ]] && [ $port -ge 1 ] && [ $port -le 65535 ]; then
        return 0
    else
        return 1
    fi
}

# 检查必要工具
check_dependencies() {
    if ! command -v nc &> /dev/null; then
        echo -e "${RED}错误: 未找到 'nc' (netcat) 工具！${NC}"
        echo -e "${YELLOW}请安装: sudo apt install netcat 或 yum install nc${NC}"
        exit 1
    fi
}

# UDP 连通性测试函数
test_udp() {
    local ip=$1
    local port=$2
    local label=$3
    
    echo -e "\n${YELLOW}► 测试 $label [$ip:$port]${NC}"
    
    start_ms=$(date +%s%3N)
    # -u: UDP, -z: 扫描模式, -v: 详细, -w: 超时3秒
    output=$(timeout 3 nc -vuz -w 3 "$ip" "$port" 2>&1)
    exit_code=$?
    end_ms=$(date +%s%3N)
    
    duration=$((end_ms - start_ms))
    
    # 解析结果
    if [ $exit_code -eq 0 ]; then
        echo -e "  ${GREEN}✓ 成功${NC} - 端口可达 (Open/Filtered)"
        echo -e "  ${CYAN}⏱ 耗时:${NC} ${duration}ms"
    else
        if [[ "$output" == *"refused"* ]]; then
            echo -e "  ${RED}✗ 拒绝${NC} - Connection Refused"
            echo -e "  ${CYAN}💡 提示:${NC} 目标在线但端口未开放"
        elif [[ "$output" == *"timed out"* ]] || [ $exit_code -eq 124 ]; then
            echo -e "  ${RED}⊗ 超时${NC} - No Response"
            echo -e "  ${CYAN}💡 提示:${NC} 网络不通或防火墙拦截"
        else
            echo -e "  ${RED}⊗ 失败${NC} - 无响应"
            echo -e "  ${CYAN}💡 提示:${NC} 检查网络连接或防火墙设置"
        fi
        echo -e "  ${CYAN}⏱ 耗时:${NC} ${duration}ms"
    fi
    
    return $exit_code
}

# ============================================
# 主程序
# ============================================

# 检查参数数量
if [ $# -eq 0 ]; then
    echo -e "${BLUE}=======================================${NC}"
    echo -e "${BLUE}    UDP 联通性对照测试工具 (udping)    ${NC}"
    echo -e "${BLUE}=======================================${NC}\n"
    show_usage
fi

# 处理帮助参数
if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
    show_usage
fi

# 检查参数数量
if [ $# -lt 2 ]; then
    echo -e "${RED}错误: 缺少参数！${NC}\n"
    show_usage
fi

DEST_IP=$1
DEST_PORT=$2

# 验证 IP 地址
if ! validate_ip "$DEST_IP"; then
    echo -e "${RED}错误: IP 地址格式无效！${NC}"
    echo -e "${YELLOW}示例: 192.168.1.1 或 8.8.8.8${NC}"
    exit 1
fi

# 验证端口号
if ! validate_port "$DEST_PORT"; then
    echo -e "${RED}错误: 端口号无效！${NC}"
    echo -e "${YELLOW}端口范围: 1-65535${NC}"
    exit 1
fi

# 检查依赖工具
check_dependencies

# 显示标题
echo -e "${BLUE}=======================================${NC}"
echo -e "${BLUE}    UDP 联通性对照测试工具 (udping)    ${NC}"
echo -e "${BLUE}=======================================${NC}"

# 执行对比测试
echo -e "\n${CYAN}[1/2] 基准参照测试${NC}"
test_udp "1.1.1.1" "53" "Cloudflare DNS"
BASE_RESULT=$?

echo -e "\n${CYAN}[2/2] 目标服务器测试${NC}"
test_udp "$DEST_IP" "$DEST_PORT" "目标服务器"
TARGET_RESULT=$?

# 分析报告
echo -e "\n${BLUE}=========================================${NC}"
echo -e "${BLUE}              📊 分析报告              ${NC}"
echo -e "${BLUE}=========================================${NC}\n"

if [ $BASE_RESULT -ne 0 ] && [ $TARGET_RESULT -ne 0 ]; then
    echo -e "${RED}[诊断结论]${NC} 本地网络异常"
    echo -e "${CYAN}[问题分析]${NC} 连 1.1.1.1:53 都无法连通"
    echo -e "${CYAN}[建议操作]${NC}"
    echo -e "  • 检查本地网络连接（Wi-Fi/网线）"
    echo -e "  • 检查运营商是否封锁 UDP 流量"
    echo -e "  • 尝试切换网络环境测试"
    
elif [ $BASE_RESULT -eq 0 ] && [ $TARGET_RESULT -ne 0 ]; then
    echo -e "${YELLOW}[诊断结论]${NC} 目标服务器无法连接"
    echo -e "${CYAN}[问题分析]${NC} 本地网络正常，但 $DEST_IP:$DEST_PORT 不可达"
    echo -e "${CYAN}[建议操作]${NC}"
    echo -e "  • 确认目标服务是否已启动"
    echo -e "  • 检查目标服务器防火墙规则"
    echo -e "  • 检查云服务商安全组设置"
    echo -e "  • 验证端口号是否正确"
    
elif [ $BASE_RESULT -eq 0 ] && [ $TARGET_RESULT -eq 0 ]; then
    echo -e "${GREEN}[诊断结论]${NC} UDP 连通性正常 ✓"
    echo -e "${CYAN}[测试结果]${NC} 基准和目标均响应正常"
    echo -e "${CYAN}[状态评估]${NC} 网络链路畅通，服务可达"
    
else
    echo -e "${BLUE}[诊断结论]${NC} 结果异常"
    echo -e "${CYAN}[问题分析]${NC} 基准测试失败但目标成功（罕见情况）"
    echo -e "${CYAN}[建议操作]${NC} 稍后重试或更换基准测试地址"
fi

echo -e "\n${BLUE}=========================================${NC}"
echo -e "${CYAN}提示: 使用 'udping -h' 查看帮助信息${NC}\n"
