检查IP是否属于特定范围

检查IP是否属于特定范围

我有一个日志文件,以这种方式列出了列入白名单的 IP 范围:

"217.29.0.0-217.29.255.255",
"204.12.0.0-204.12.255.255",
"198.54.223.0-198.54.223.255",

我还在编写一个 bash 脚本,除其他外,它需要检查此日志文件并确定指定的 IP 是否已列入白名单。

例如,对于 IP 204.12.5.10,我如何使用具有指定范围的日志文件来确定该 IP 是否属于该文件中的某个范围?

答案1

对于 IP 地址,需要记住的一点是,它们实际上只是 32 位数字的表示。

因此,您可以通过将八位字节乘以基数 256 将它们转换为十进制。

例如:

217.29.0.0 == 216 * 256 ^ 3 + 29 * 256 ^2 + 0 * 256 ^1 + 0 * 256 ^ 0
           == 3640655872

因此,给定一个像上面这样的范围 - 首先将它们都转换,这样你就有了开始和结束。然后比较所有传入的 IP,看看它们是否“适合”。

所以像这样(说明算法):

#!/usr/bin/env perl
use strict;
use warnings;

my $ip_to_check = "204.12.5.10";
my $dword       = 0;
for ( split( '\.', $ip_to_check ) ) { $dword *= 256; $dword += $_ }
print "Checking $dword\n";

while (<DATA>) {
    my ( $start, $finish ) = m/([\d\.]+)/g;
    my $start_dword = 0;
    for ( split '\.', $start ) { $start_dword *= 256; $start_dword += $_ }
    my $end_dword = 0;
    for ( split '\.', $finish ) { $end_dword *= 256; $end_dword += $_ }
    print "Range:\n";
    print "\t$start \t=> $start_dword\n";
    print "\t$finish \t=> $end_dword\n";

    print "$ip_to_check is in $_\n" if $dword >= $start_dword and $dword <= $end_dword;
}

__DATA__
"217.29.0.0-217.29.255.255",
"204.12.0.0-204.12.255.255",
"198.54.223.0-198.54.223.255",

可以很容易地将其作为“检查脚本”来执行 - 通过读取文件(而不是DATA)并$ip_to_check从中获取STDIN)。

(注意 - 因为纯粹perl可以很容易地变成一个衬垫,或者一个要调用的脚本。或者重写 - 我敢说你可以expr很容易地做到这一点)。

答案2

这是一个awk版本:

want=204.12.77.5
awk -v want=$want  -F- '
function canon(ip){
    split(" "ip,x,/[^0-9]+/)
    return sprintf("%03d%03d%03d%03d",x[2],x[3],x[4],x[5])
}
BEGIN { val = canon(want) }
{ low = canon($1); high = canon($2);
  if(val>=low && val<=high)print "in range " $0
}' mylogfile

该函数canon采用 IP 地址,拆分数字字段,然后将每个字段扩展为 3 位数字并返回字符串。它调用每行上的 2 个值,并将这些值与所需的 IP 地址(在开始时设置)进行比较,该地址也已被“规范化”。

答案3

我为 bash 脚本编写了这个函数:

function int_ip() {
    OIFS=$IFS
    IFS='.'
    ip=($1)
    IFS=$OIFS
    echo "${ip[0]} * 256 ^ 3 + ${ip[1]} * 256 ^2 + ${ip[2]} * 256 ^1 + ${ip[3]} * 256 ^ 0" | bc
}

我这样使用它:

HOSTMIN=$(int_ip ${HOSTMIN})
HOSTMAX=$(int_ip ${HOSTMAX})
IPINT=$(int_ip ${NEWIP})

if ! [[ ${IPINT} -le ${HOSTMAX} && ${IPINT} -ge ${HOSTMIN} ]]; then
    echo "IP Out of Range"
    return 1
fi

我用来ipcalc获取 hostmin 和 hostmax

相关内容