#!/bin/bash
# /root/pppoe/setup-ppp-routes.sh

# 检查root权限
if [ "$EUID" -ne 0 ]; then
    echo "请使用root权限运行此脚本"
    exit 1
fi

echo "=== PPP接口自动配置脚本 ==="

# 等待PPP接口就绪
wait_for_ppp() {
    local max_attempts=30
    local attempt=1
    
    while [ $attempt -le $max_attempts ]; do
        if ip link show | grep -q "^[0-9]\+: ppp"; then
            echo "PPP接口已就绪"
            return 0
        fi
        echo "等待PPP接口... ($attempt/$max_attempts)"
        sleep 1
        ((attempt++))
    done
    echo "等待PPP接口超时"
    return 1
}

# 获取所有PPP接口
get_ppp_interfaces() {
    ip link show | grep -o "ppp[0-9]\+" | sort -u
}

# 自动在/etc/iproute2/rt_tables中添加PPP接口对应的路由表
add_ppp_tables_to_rt_tables() {
    local rt_tables_file="/etc/iproute2/rt_tables"
    local base_table_id=100
    local ppp_interfaces=$(get_ppp_interfaces)
    
    if [ -z "$ppp_interfaces" ]; then
        echo "未检测到PPP接口，跳过路由表配置"
        return 1
    fi
    
    echo "检测到PPP接口: $(echo $ppp_interfaces | tr '\n' ' ')"
    echo "正在更新/etc/iproute2/rt_tables文件..."
    
    # 备份原文件
    cp "$rt_tables_file" "${rt_tables_file}.backup.$(date +%Y%m%d_%H%M%S)" 2>/dev/null
    
    # 为每个PPP接口添加路由表条目
    for iface in $ppp_interfaces; do
        # 提取PPP接口编号
        local ppp_num=$(echo "$iface" | grep -o "[0-9]\+")
        
        if [ -n "$ppp_num" ]; then
            # 计算路由表ID
            local table_id=$((base_table_id + ppp_num))
            local table_name="${iface}_table"
            
            # 检查是否已存在相同的表ID或表名
            if ! grep -q "^${table_id}[[:space:]]" "$rt_tables_file" && \
               ! grep -q "[[:space:]]${table_name}$" "$rt_tables_file"; then
                # 添加新的路由表条目
                echo "${table_id} ${table_name}" | tee -a "$rt_tables_file" > /dev/null
                echo "已添加路由表: ${table_id} ${table_name}"
            else
                echo "路由表 ${table_id} ${table_name} 已存在，跳过"
            fi
        fi
    done
    
    echo "路由表配置更新完成"
}

# 为每个ppp接口设置策略路由
setup_ppp_route() {
    local iface=$1
    local table_id=$2
    
    # 获取接口的IP地址
    local src_ip=$(ip -4 addr show dev $iface 2>/dev/null | grep inet | awk '{print $2}' | cut -d/ -f1)
    local peer_ip=$(ip route show dev $iface 2>/dev/null | awk '/proto kernel/ {print $1}' | head -1)
    
    if [ -z "$src_ip" ]; then
        echo "无法获取 $iface 的IP地址"
        return 1
    fi
    
    # 清空对应路由表
    ip route flush table $table_id 2>/dev/null
    
    # 添加默认路由到ppp接口的网关
    if [ -n "$peer_ip" ]; then
        ip route add default via $peer_ip dev $iface table $table_id 2>/dev/null
        if [ $? -eq 0 ]; then
            echo "已添加默认路由: via $peer_ip dev $iface table $table_id"
        else
            ip route add default dev $iface table $table_id 2>/dev/null
            echo "已添加默认路由: dev $iface table $table_id"
        fi
    else
        # 如果没有获取到网关，直接使用接口
        ip route add default dev $iface table $table_id 2>/dev/null
        echo "已添加默认路由: dev $iface table $table_id"
    fi
    
    # 添加本地路由
    ip route add $src_ip dev $iface scope link table $table_id 2>/dev/null
    
    # 添加策略路由规则
    ip rule del from $src_ip table $table_id 2>/dev/null
    ip rule add from $src_ip table $table_id
    
    echo "已配置 $iface (IP: $src_ip) 使用路由表 $table_id"
    return 0
}

# 配置所有ppp接口（自动识别）
setup_all_ppp_routes() {
    local base_table_id=100
    local ppp_interfaces=$(get_ppp_interfaces)
    local ppp_count=0
    
    if [ -z "$ppp_interfaces" ]; then
        echo "未检测到任何PPP接口"
        return 1
    fi
    
    echo "开始配置PPP接口策略路由..."
    
    for iface in $ppp_interfaces; do
        # 检查接口是否已启用
        if ip link show $iface 2>/dev/null | grep -q "state UP"; then
            # 提取PPP接口编号
            local ppp_num=$(echo "$iface" | grep -o "[0-9]\+")
            local table_id=$((base_table_id + ppp_num))
            
            setup_ppp_route "$iface" "$table_id"
            if [ $? -eq 0 ]; then
                ((ppp_count++))
            fi
        else
            echo "接口 $iface 未启用，跳过配置"
        fi
    done
    
    echo "成功配置了 $ppp_count 个PPP接口"
}

# 显示当前配置状态
show_status() {
    echo -e "\n=== 当前PPP接口状态 ==="
    ip link show | grep -A 1 "ppp" | grep -E "ppp[0-9]+:|state"
    
    echo -e "\n=== 当前PPP路由表规则 ==="
    ip rule list | grep -E "ppp|from|table"
    
    echo -e "\n=== 当前路由表配置 ==="
    grep "ppp.*_table" /etc/iproute2/rt_tables 2>/dev/null || echo "未找到PPP路由表配置"
}

# 主执行函数
main() {
    # 步骤1: 等待PPP接口就绪
    wait_for_ppp || {
        echo "未检测到PPP接口，退出"
        exit 1
    }
    
    # 步骤2: 自动添加PPP路由表到/etc/iproute2/rt_tables
    add_ppp_tables_to_rt_tables
    
    # 步骤3: 自动配置所有PPP接口的路由
    setup_all_ppp_routes
    
    # 步骤4: 启用IP转发
    echo 1 > /proc/sys/net/ipv4/ip_forward
    echo "已启用IP转发"
    
    # 步骤5: 设置连接跟踪
    modprobe nf_conntrack 2>/dev/null
    modprobe nf_conntrack_pptp 2>/dev/null
    echo "已设置连接跟踪"
    
    # 步骤6: 显示配置状态
    show_status
    
    # 步骤7: 配置MASQUERADE（如果需要的话，请取消注释并修改网卡名称）
    # echo "配置MASQUERADE..."
    # iptables -t nat -A POSTROUTING -o enp2s0f0 -j MASQUERADE
    
    echo -e "\n=== 配置完成 ==="
    echo "所有PPP接口已自动配置完成"
    echo "路由表配置已更新到 /etc/iproute2/rt_tables"
}

# 运行主函数
main
