#!/bin/bash

# 脚本名称: count_pjsip_ip_subnets_simple.sh
# 功能描述: 统计sudo asterisk -x 'pjsip list contacts'命令返回的IP的网段分布
#          并统计/etc/asterisk/pjsip.registration.conf中的IP地址
# 作者: Claude
# 日期: $(date +%Y-%m-%d)

# 打印标题
echo "===================================="
echo "   PJSIP 连接 IP 网段统计工具     "
echo "===================================="

# 检查asterisk是否安装
if ! command -v asterisk &> /dev/null; then
    echo "错误: 未找到asterisk命令，请确认已安装Asterisk"
    exit 1
fi

echo "正在获取PJSIP联系人信息..."

# 获取PJSIP联系人信息
pjsip_output=$(sudo asterisk -rx 'pjsip list contacts')

if [ $? -ne 0 ]; then
    echo "错误: 执行'sudo asterisk -rx \"pjsip list contacts\"'命令失败"
    exit 1
fi

# 从输出中提取IP地址
# 使用grep提取IPv4地址，排除127.0.0.1
pjsip_ips=$(echo "$pjsip_output" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v '127\.0\.0\.1')
pjsip_ip_count=$(echo "$pjsip_ips" | grep -v '^$' | wc -l)
echo "从 'pjsip list contacts' 命令中找到 $pjsip_ip_count 个IP地址"

# 初始化最终的IP列表
ip_list="$pjsip_ips"

# 检查pjsip.registration.conf文件
reg_conf_file="/etc/asterisk/pjsip.registration.conf"
echo "正在检查 $reg_conf_file 中的IP地址..."

if [ -f "$reg_conf_file" ]; then
    # 从配置文件中提取IP地址，更精确地匹配配置文件中的IP
    echo "解析 $reg_conf_file 文件..."
    
    # 1. 提取server_uri字段中的IP (典型格式: server_uri=sip:user@10.1.2.3:5060)
    server_uri_ips=$(grep -i "server_uri" "$reg_conf_file" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v '127\.0\.0\.1')
    
    # 2. 提取client_uri字段中的IP
    client_uri_ips=$(grep -i "client_uri" "$reg_conf_file" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v '127\.0\.0\.1')
    
    # 3. 提取contact_uri字段中的IP
    contact_uri_ips=$(grep -i "contact_uri" "$reg_conf_file" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v '127\.0\.0\.1')
    
    # 4. 提取outbound_proxy字段中的IP
    outbound_proxy_ips=$(grep -i "outbound_proxy" "$reg_conf_file" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v '127\.0\.0\.1')
    
    # 5. 其他可能包含IP的字段，如host=
    host_ips=$(grep -i "host=" "$reg_conf_file" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | grep -v '127\.0\.0\.1')
    
    # 合并所有找到的IP
    reg_conf_ips=$(echo -e "$server_uri_ips\n$client_uri_ips\n$contact_uri_ips\n$outbound_proxy_ips\n$host_ips" | grep -v '^$' | sort | uniq)
    reg_conf_ip_count=$(echo "$reg_conf_ips" | grep -v '^$' | wc -l)
    
    if [ $reg_conf_ip_count -gt 0 ]; then
        echo "在 $reg_conf_file 中找到 $reg_conf_ip_count 个IP地址，添加到统计中..."
        
        # 保存来源信息
        for ip in $reg_conf_ips; do
            if grep -i "server_uri.*$ip" "$reg_conf_file" >/dev/null; then
                echo "$ip : server_uri" >> /tmp/pjsip_ip_sources.txt
            fi
            if grep -i "client_uri.*$ip" "$reg_conf_file" >/dev/null; then
                echo "$ip : client_uri" >> /tmp/pjsip_ip_sources.txt
            fi
            if grep -i "contact_uri.*$ip" "$reg_conf_file" >/dev/null; then
                echo "$ip : contact_uri" >> /tmp/pjsip_ip_sources.txt
            fi
            if grep -i "outbound_proxy.*$ip" "$reg_conf_file" >/dev/null; then
                echo "$ip : outbound_proxy" >> /tmp/pjsip_ip_sources.txt
            fi
            if grep -i "host=.*$ip" "$reg_conf_file" >/dev/null; then
                echo "$ip : host" >> /tmp/pjsip_ip_sources.txt
            fi
        done
        
        # 合并两个IP列表
        ip_list=$(echo -e "$ip_list\n$reg_conf_ips" | grep -v '^$' | sort | uniq)
    else
        echo "在 $reg_conf_file 中未找到IP地址"
    fi
else
    echo "警告: $reg_conf_file 文件不存在，跳过此步骤"
fi

if [ -z "$ip_list" ]; then
    echo "未找到任何IP地址"
    exit 0
fi

total_ips=$(echo "$ip_list" | grep -v '^$' | wc -l)
echo "总共找到 $total_ips 个唯一IP地址"
echo "正在统计网段分布..."

# 将IP地址转换为网段（取前三个八位字节）
subnet_list=$(echo "$ip_list" | sed -r 's/([0-9]+\.[0-9]+\.[0-9]+)\.[0-9]+/\1.0\/24/g')

# 统计每个网段的数量
echo "IP网段统计结果(/24):"
echo "$subnet_list" | sort | uniq -c | sort -nr | while read count subnet; do
    printf "%-18s - %3d 个IP\n" "$subnet" "$count"
done

# 更详细的统计（按B类网络统计）
echo -e "\nB类网络统计结果(/16):"
b_class_list=$(echo "$ip_list" | sed -r 's/([0-9]+\.[0-9]+)\.[0-9]+\.[0-9]+/\1.0.0\/16/g')
echo "$b_class_list" | sort | uniq -c | sort -nr | while read count subnet; do
    printf "%-18s - %3d 个IP\n" "$subnet" "$count"
done

# 更详细的统计（按A类网络统计）
echo -e "\nA类网络统计结果(/8):"
a_class_list=$(echo "$ip_list" | sed -r 's/([0-9]+)\.[0-9]+\.[0-9]+\.[0-9]+/\1.0.0.0\/8/g')
echo "$a_class_list" | sort | uniq -c | sort -nr | while read count subnet; do
    printf "%-18s - %3d 个IP\n" "$subnet" "$count"
done

# 分别显示来源统计
echo -e "\n按来源统计IP地址:"
echo "从 'pjsip list contacts' 命令获取的IP地址数量: $pjsip_ip_count"

if [ -f "$reg_conf_file" ] && [ -n "$reg_conf_ips" ]; then
    echo "从 $reg_conf_file 配置文件获取的IP地址数量: $reg_conf_ip_count"
    
    # 查找同时出现在两个来源的IP
    common_ips=$(comm -12 <(echo "$pjsip_ips" | sort | uniq) <(echo "$reg_conf_ips" | sort | uniq) | wc -l)
    echo "同时出现在两个来源的IP地址数量: $common_ips"
    
    # 显示每个IP在配置文件中的位置信息
    if [ -f "/tmp/pjsip_ip_sources.txt" ]; then
        echo -e "\n配置文件中IP地址的位置信息:"
        cat /tmp/pjsip_ip_sources.txt | sort | uniq
        rm -f /tmp/pjsip_ip_sources.txt
    fi
fi

echo -e "\n统计完成"
