BASH - Check IP is in range of ip pools

BASH - Check IP is in range of ip pools

I have a list of IPs in MAXCDN_ARRAY to be used as whitelist. I want to check if a specific IP address is in range in this array. How can I structure the code so that it can compare all IPs in the array and say the specific IP in in range of this list or not?

GrepCIDR

You can use grepcidr to check if an IP address is in a list of CIDR networks.

You have to install grepcidr package:

~] apt-get install grepcidr

Bash script to find ip address in range of ip addresses using grepcidr:

#! /bin/bash

MAXCDN_ARRAY="192.168.0.0/24 192.168.0.0/16 192.168.1.0/24 172.16.32.0/16"

IP=192.168.0.5


echo "we use a grepcdir for ip in ip range"
for subnet in $MAXCDN_ARRAY
do
    # grepcidr 192.168.1.0/24 <(echo "192.168.1.1")
    output_grepcidr=$( grepcidr ${subnet} <(echo ${IP}) )
    if [[ ${output_grepcidr} = ${IP} ]]
        then
            echo "${IP} is in ${subnet}"
        else
            echo "${IP} is not in ${subnet}"
    fi
done
./ip_in_subnet-grepcidr.sh 
we use a grepcdir for ip in ip range
192.168.0.5 is in 192.168.0.0/24
192.168.0.5 is in 192.168.0.0/16
192.168.0.5 is not in 192.168.1.0/24
192.168.0.5 is not in 172.16.32.0/16

own bash function

I realize that this is older and already has an accepted answer, but this solution utilizes a function I wrote for portability across multiple servers in an environment where grepcidr wasn't a standard package across all servers.

The comments should clarify just what it's doing.

#! /bin/bash

# Set DEBUG=1, in order to see it iterate through the calculations.
# DEBUG=1

MAXCDN_ARRAY="192.168.0.0/24 192.168.0.0/16 192.168.1.0/24 172.16.32.0/16"

IP=192.168.0.5

function in_subnet {
    # Determine whether IP address is in the specified subnet.
    #
    # Args:
    #   sub: Subnet, in CIDR notation.
    #   ip: IP address to check.
    #
    # Returns:
    #   1|0
    #
    local ip ip_a mask netmask sub sub_ip rval start end

    # Define bitmask.
    local readonly BITMASK=0xFFFFFFFF

    # Set DEBUG status if not already defined in the script.
    [[ "${DEBUG}" == "" ]] && DEBUG=0

    # Read arguments.
    IFS=/ read sub mask <<< "${1}"
    IFS=. read -a sub_ip <<< "${sub}"
    IFS=. read -a ip_a <<< "${2}"

    # Calculate netmask.
    netmask=$(($BITMASK<<$((32-$mask)) & $BITMASK))

    # Determine address range.
    start=0
    for o in "${sub_ip[@]}"
    do
        start=$(($start<<8 | $o))
    done

    start=$(($start & $netmask))
    end=$(($start | ~$netmask & $BITMASK))

    # Convert IP address to 32-bit number.
    ip=0
    for o in "${ip_a[@]}"
    do
        ip=$(($ip<<8 | $o))
    done

    # Determine if IP in range.
"ip_in_subnet-bash-function.sh" 87 lines, 1981 bytes
echo "we use a grepcdir for ip in ip range"
for subnet in $MAXCDN_ARRAY
do
    # grepcidr 192.168.1.0/24 <(echo "192.168.1.1")
    output_grepcidr=$( grepcidr ${subnet} <(echo ${IP}) )
    if [[ ${output_grepcidr} = ${IP} ]]
        then
            echo "${IP} is in ${subnet}"
        else
            echo "${IP} is not in ${subnet}"
    fi
done

    # Determine if IP in range.
    (( $ip >= $start )) && (( $ip <= $end )) && rval=1 || rval=0

    (( $DEBUG )) &&
        printf "ip=0x%08X; start=0x%08X; end=0x%08X; in_subnet=%u\n" $ip $start $end $rval 1>&2

    echo "${rval}"
}


echo "We use own function for ip in ip range"
for subnet in $MAXCDN_ARRAY
do
    if [[ $(in_subnet $subnet $IP) -eq 1 ]]
        then
            echo "${IP} is in ${subnet}"
        else
            echo "${IP} is not in ${subnet}"
    fi
done
~] ./ip_in_subnet-bash-function.sh 
We use own function for ip in ip range
192.168.0.5 is in 192.168.0.0/24
192.168.0.5 is in 192.168.0.0/16
192.168.0.5 is not in 192.168.1.0/24
192.168.0.5 is not in 172.16.32.0/16

SUBSCRIBE FOR NEW ARTICLES

@
comments powered by Disqus