Verifique se um IP pertence a um intervalo específico

0

Eu tenho um arquivo de log que lista os intervalos de IP permitidos dessa maneira:

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

Eu também estou trabalhando em um script bash que, entre outras coisas, precisa verificar este arquivo de log e determinar se um IP especificado está na lista de permissões.

No caso do IP 204.12.5.10 , por exemplo, como eu usaria o arquivo de log com os intervalos especificados para determinar se esse IP é parte de um intervalo nesse arquivo?

    
por wbruan 05.10.2015 / 14:11

2 respostas

2

A coisa útil para lembrar com endereços IP é que eles são na verdade apenas representações de um número de 32 bits.

Então você pode convertê-los em um decimal multiplicando os octetos como base 256.

Por exemplo:

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

Então, dado um intervalo como o acima - primeiro converta os dois, de modo que você tenha um começo e um fim. Em seguida, compare os IPs recebidos para ver se eles se encaixam.

Então, algo assim (ilustrando o algoritmo):

#!/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",

Poderia facilmente fazer isso como um 'script de verificação' - lendo um arquivo (em vez de DATA ) e obtendo $ip_to_check de STDIN ).

(note - como perl puro poderia ser transformado em um forro com facilidade, ou um script para chamar. Ou reescrito - eu diria que você poderia fazer isso com expr facilmente).

    
por 05.10.2015 / 14:31
1

Aqui está uma versão do 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

A função canon recebe um endereço IP, divide os campos numéricos, então estende cada um para 3 dígitos e retorna a string. É chamado para os 2 valores em cada linha, e estes são comparado com o endereço IP desejado (definido no início), que também foi "canonificado".

    
por 05.10.2015 / 15:27