检查重叠子网

检查重叠子网

我想知道是否有办法检查某些子网是否与 IP 列表重叠例如,我们有这个列表:

197.26.9.128/25
193.36.81.128/25
194.33.24.0/22
188.115.195.80/28
188.115.195.64/28
185.59.69.96/28
185.59.69.32/27
41.202.219.32/27
41.202.219.128/29
154.70.120.16/28
154.70.120.32/28
154.70.120.0/28
41.202.219.208/28
41.202.219.136/29
197.157.209.0/24

我想检查以下 IP 是否与之前的列表重叠。

197.26.9.0/26
194.33.26.0/26      (IP overlapped with 194.33.24.0/22)
188.115.195.88/29   (IP overlapped with 188.115.195.80/28)
41.202.219.0/24
197.157.209.128/28  (IP overlapped with 197.157.209.0/24)

输出如下:

197.26.9.0/26
41.202.219.0/24

答案1

尝试用IP冲突, pip install ipconflict.

将您的子网放入/tmp/subnets.txt

ipconflict -f /tmp/subnets.txt

输出:

conflict found: 194.33.24.0/22 <-> 194.33.26.0/26
conflict found: 188.115.195.80/28 <-> 188.115.195.88/29
conflict found: 41.202.219.32/27 <-> 41.202.219.0/24
conflict found: 41.202.219.128/29 <-> 41.202.219.0/24
conflict found: 41.202.219.208/28 <-> 41.202.219.0/24
conflict found: 41.202.219.136/29 <-> 41.202.219.0/24
conflict found: 197.157.209.0/24 <-> 197.157.209.128/28

答案2

这里有一些内容供您参考。首先,是 Bash 中的脚本,所以效率不高。它并不完全符合您的要求,因为它只检查一对子网并报告重叠情况。脚本下面是一些粗略的 shell 命令,但结果并未以您想要的形式呈现。因此,您需要根据您的需求集成和调整整个集合,或者将它们视为说明逻辑的草图。

#!/usr/bin/env bash

subnet1="$1"
subnet2="$2"

# calculate min and max of subnet1
# calculate min and max of subnet2
# find the common range (check_overlap)
# print it if there is one

read_range () {
    IFS=/ read ip mask <<<"$1"
    IFS=. read -a octets <<< "$ip";
    set -- "${octets[@]}";
    min_ip=$(($1*256*256*256 + $2*256*256 + $3*256 + $4));
    host=$((32-mask))
    max_ip=$(($min_ip+(2**host)-1))
    printf "%d-%d\n" "$min_ip" "$max_ip"
}

check_overlap () {
    IFS=- read min1 max1 <<<"$1";
    IFS=- read min2 max2 <<<"$2";
    if [ "$max1" -lt "$min2" ] || [ "$max2" -lt "$min1" ]; then return; fi
    [ "$max1" -ge "$max2" ] && max="$max2" ||   max="$max1"
    [ "$min1" -le "$min2" ] && min="$min2" || min="$min1"
    printf "%s-%s\n" "$(to_octets $min)" "$(to_octets $max)"
}

to_octets () {
    first=$(($1>>24))
    second=$((($1&(256*256*255))>>16))
    third=$((($1&(256*255))>>8))
    fourth=$(($1&255))
    printf "%d.%d.%d.%d\n" "$first" "$second" "$third" "$fourth" 
}

range1="$(read_range $subnet1)"
range2="$(read_range $subnet2)"
overlap="$(check_overlap $range1 $range2)"
[ -n "$overlap" ] && echo "Overlap $overlap of $subnet1 and $subnet2"

用法和结果如下:

$ ./overlap.bash 194.33.26.0/26 194.33.24.0/22
Overlap 194.33.26.0-194.33.26.63 of 194.33.26.0/26 and 194.33.24.0/22

现在,假设您的第一个子网列表位于文件中,list并且要检查的子网位于文件中to_check,您可以使用脚本来查找所有重叠。

$ while read l; do list+=("$l"); done < list
$ while read t; do to_check+=("$t"); done < to_check
$ for i in "${list[@]}"; do for j in "${to_check[@]}"; do \
./overlap.bash "$i" "$j"; done; done

这是结果:

Overlap 194.33.26.0-194.33.26.63 of 194.33.24.0/22 and 194.33.26.0/26
Overlap 188.115.195.88-188.115.195.95 of 188.115.195.80/28 and 188.115.195.88/29
Overlap 41.202.219.32-41.202.219.63 of 41.202.219.32/27 and 41.202.219.0/24
Overlap 41.202.219.128-41.202.219.135 of 41.202.219.128/29 and 41.202.219.0/24
Overlap 41.202.219.208-41.202.219.223 of 41.202.219.208/28 and 41.202.219.0/24
Overlap 41.202.219.136-41.202.219.143 of 41.202.219.136/29 and 41.202.219.0/24
Overlap 197.157.209.128-197.157.209.143 of 197.157.209.0/24 and 197.157.209.128/28

正如您所看到的,41.202.219.0/24有四个重叠,这与您在问题中的预期相反。

为了仅获取与第一个列表不重叠的子网,脚本会短得多。您不需要该to_octets函数,并且该check_overlap函数已经可以在这一行给出结果:

if [ "$max1" -lt "$min2" ] || [ "$max2" -lt "$min1" ]; then return; fi

最后两行也可以更改(最后一行完全删除)。

至于集成逻辑,可以对第一个列表进行短路检查,因为并非所有组合都必须检查。一个负数就足够了。

相关内容