identifica se os endereços IP na lista A existem dentro de uma lista de intervalos de IPs na lista B

1

Eu tenho 2 listas, uma contendo todos os endereços IP de 32 bits, e a outra é uma lista de intervalos de IP e outros endereços IP. Eu preciso encontrar se cada IP dentro da lista A existe em qualquer intervalo de IP ou endereço na lista B. O resultado final seria exibir os endereços da lista A que não existe na lista B. Isso seria fácil usando diff se os intervalos de IP não estivessem envolvidos. A lista em si contém quase 10.000 linhas, portanto, passar por isso manualmente levaria uma eternidade.

    
por Steve 25.05.2017 / 17:50

2 respostas

2

Este script faz o truque no Linux / Bash. Não tenho certeza se está livre de bugs. Comente se você quiser alguma explicação.

#!/bin/bash

# The script prints addresses from one file that are NOT
# in the ranges provided in another file.

# $1 is the file with addresses to check
# $2 is the file that holds the ranges
## in format x.x.x.x-y.y.y.y or as a single IP, one per line.

### Variables ###

inFile="$1"
rangesFile="$2"
typeset -a rangesLow rangesHigh #arrays of int
rangesCount=


### Functions ###

toInt () {
    printf "%d\n" $(($1*256*256*256 + $2*256*256 + $3*256 + $4))
}

readRanges () {
    while IFS=- read -a range
    do
        IFS=. read -a low <<< "${range[0]}"
        [ -z "${range[1]}" ] && range[1]="${range[0]}"
        IFS=. read -a high <<< "${range[1]}"
        rangesLow+=( $(toInt "${low[@]}") )
        rangesHigh+=( $(toInt "${high[@]}") )
    done < "$rangesFile"
    rangesCount=${#rangesLow[@]}
}

singleCheck () {
    # $1 is the address to check.
    # $2 and $3 are the bounds, low and high.
    # Returns 0 if NOT in range.

    [[ $1 -ge $2 ]] && [[ $1 -le $3 ]] && return 1
    # To invert the logic of the script, instead of the line above
    ## use this one:
    # [[ $1 -ge $2 ]] && [[ $1 -le $3 ]] || return 1
    return 0
}

addressCheck () {
    # The function takes in 4 octets of an IP as four positional parameters.
    # Returns 1 if IP is in any range.
    # If not in range, the address is printed to stdout.
    local address
    address=$(toInt "$@")
    for ((i=0; i<rangesCount ; i++)) # Loop for all ranges.
    do
        singleCheck "$address" "${rangesLow[$i]}" "${rangesHigh[$i]}" || return 1 
    done    
    printf "%d.%d.%d.%d\n" "$@"
}

checkAll () {
    while IFS=. read -a toCheck
    do
        addressCheck "${toCheck[@]}"
    done < "$inFile"
}

main () {
    readRanges
    checkAll
}

### Execute ###

main

Baseado no brilhante pensamento de hymie.

    
por 25.05.2017 / 21:43
2

Eu não sei sobre um script de shell, mas um programa deve ser capaz de converter as duas listas de endereços IP com quatro pontos em números inteiros únicos e, em seguida, comparar os números com padrão maior que menor que.

i = (first octet * 256*256*256) + (second octet * 256*256)
  + (third octet * 256) + (fourth octet)
    
por 25.05.2017 / 18:21