如何在bash中验证IPv6地址?

时间:2015-12-02 17:23:20

标签: regex linux macos bash ipv6

我有一个bash脚本,根据已知发件人的IP地址构建白名单' SPF记录(https://github.com/stevejenkins/postwhite)。在那个剧本中,我有一系列的功能,以及#34;规范化"检索到的IPv4 CIDR:

# Create IPv4 normalize function
ip2int() {
    local a b c d
    { IFS=. read a b c d; } <<< $1
    printf $(((((((a << 8) | b) << 8) | c) << 8) | d))
}

int2ip() {
    local ui32=$1; shift
    local ip n
    for n in 1 2 3 4; do
        ip=$((ui32 & 0xff))${ip:+.}$ip
        ui32=$((ui32 >> 8))
    done
    printf $ip
}

network() {
    local ip netmask;
    { IFS="/" read ip netmask; } <<< $1
    local addr=$(ip2int $ip);
    local mask=$((0xffffffff << (32 -$netmask)));
    printf $(int2ip $((addr & mask)))/$netmask
}

function normalize_ipv4() {
    # split by ":"
    local array=(${ip/:/ });
    if [ "x${array[0]}" = "xip4" ] ; then
        # check if is a CIDR
        if [[ ${array[1]} == *"/"32 ]] ; then
            IP=${array[1]}
        elif [[ ${array[1]} == *"/"* ]] ; then
            IP=$(network ${array[1]});
        else
            IP=${array[1]}
        fi
    else
        IP=${array[1]}
    fi
    printf "$IP"
}

我可以确定规范化的IPv4 CIDR是否与查询中的IPv4 CIDR匹配,然后我可以“修复”&#34; &#34;除去,&#34;或者&#34;保持&#34;白名单中的IPv4 CIDR无效:

# If enabled, fix invalid CIDRs
if [ "$invalidip4" == "fix" ] ; then
    printf "\nFixing invalid IPv4 CIDRs..."
    for ip in $(cat  "${tmp2}") ; do
        ip=$(normalize_ipv4  "$ip");
        if [ -n "$ip" ] ; then
            printf "$ip\tpermit\n"
        fi
    done >> "${tmp3}" &
    show_dots $!

# If enabled, remove invalid CIDRs
elif [ "$invalidip4" == "remove" ] ; then
    printf "\nRemoving invalid IPv4 CIDRs..."
    for ip in $(cat "${tmp2}") ; do
        iptype=$( printf "$ip" | cut -d\: -f1 )
        origip=$( printf "$ip" | cut -d\: -f2 )
        ip=$(normalize_ipv4 "$ip");
        if [ "$origip" == "$ip" ] ; then
            printf "$ip\tpermit\n"
        elif [ "$iptype" == "ip6" ] ; then
            printf "$ip\tpermit\n"
        fi
    done >> "${tmp3}" &
    show_dots $!

# If enabled, keep invalid CIDRs
elif [ "$invalidip4" == "keep" ] ; then
    printf "\nKeeping invalid IPv4 CIDRs...\n"
    printf "%s\n" | grep "^ip" "${tmp2}" | cut -c5- | sed s/$/' permit'/ > "${tmp3}"
fi

我现在正在寻找为IPv6地址和CIDR创建规范化功能,因此我可以进行类似的比较,并允许用户选择如何对待它们。我不知道从哪里开始,我的正则表达式技巧是不存在的。

以下是在规范化之前如何格式化IPv6查询结果的一些示例:

ip6:2620:109:c003:104::/64
ip6:2620:109:c006:104::/64
ip6:2620:109:c00d:104::/64
ip6:2001:4860:4000::/36
ip6:2404:6800:4000::/36
ip6:2607:f8b0:4000::/36
ip6:2800:3f0:4000::/36
ip6:2a00:1450:4000::/36
ip6:2a04:35c0::/29
ip6:2607:f8b0:4001:c13::1b
ip6:2c0f:fb50:4000::/36

脚本需要在Linux,BSD,OSX和尽可能多的系统上运行,因此我尝试尽可能保持脚本通用。

提前致谢!

0 个答案:

没有答案