Skip to content

Instantly share code, notes, and snippets.

@vp777
Last active November 12, 2020 20:07
Show Gist options
  • Select an option

  • Save vp777/1a8f4e985367f4a05e326eed8cd74466 to your computer and use it in GitHub Desktop.

Select an option

Save vp777/1a8f4e985367f4a05e326eed8cd74466 to your computer and use it in GitHub Desktop.
This bash script outputs the hosts that fall within a list of CIDR blocks
#!/bin/bash
: '
examples:
./ip_range_check.sh <(echo 1.1.1.1) <(echo 1.1.1.2)
#no results
./ip_range_check.sh <(echo -e '127.0/8\n1.1.1.1/31') <(echo -e '7f000001.7f000002.rbndr.us\n1.1.256\n1.1.1.2\n2.2.2.36')
#7f000001.7f000002.rbndr.us 127.0.0.1
#1.1.256 1.1.256
'
scope=${1?Missing the file with the ip ranges}
ips=${2-/dev/stdin}
[[ -z $2 ]] && echo "Reading IPs from stdin"
function preproc {
printf %s $(echo "$1" | cut -d , -f 2) #extract the IP from a csv file
#printf $1
}
function n2ip {
local static_parts dynamic_parts last_part=${1##*.}
dynamic_parts=( $last_part )
while [[ ${dynamic_parts[0]} -ge 256 ]]; do
dynamic_parts=( $((${dynamic_parts[0]}/256)) $((${dynamic_parts[0]}%256)) "${dynamic_parts[@]:1}" )
done
IFS=. read -a static_parts<<<${1%$last_part}0.0.0
echo ${static_parts[@]:0:4-${#dynamic_parts[@]}} ${dynamic_parts[@]}|tr ' ' .
}
function ip2n {
local dots=$(echo "$1" | tr -cd . | wc -c)
local ip=$1
local n
[[ $dots -ne 3 ]] && {
local last_part=${ip##*.}
ip=$(printf %s ${ip%${last_part}} $(printf '0.%.0's $(seq $((3-$dots)))) ${last_part})
}
IFS=. read -a ip_parts <<< "$ip"
n=0
for ip_part in "${ip_parts[@]}"; do
n=$((n*256+$ip_part))
done
printf %s $n
}
ip_ranges=()
while read -r scope_cidr || [[ -n $scope_cidr ]]; do
[[ $scope_cidr != *"/"* ]] && scope_cidr=${scope_cidr}/32
cidr_ip=${scope_cidr%/*}
cidr_mask_bits=${scope_cidr#*/}
first_ip=$(($(ip2n $cidr_ip)&~(2**(32-cidr_mask_bits)-1)))
last_ip=$((first_ip+2**(32-cidr_mask_bits)))
ip_ranges+=($first_ip $last_ip)
done < "$scope"
while read -r line || [[ -n $line ]]; do
while read -r test_ip || [[ ! -z $test_ip ]];do
ntest_ip=$(ip2n $(preproc $test_ip))
for ((i=0;i<${#ip_ranges[@]};i+=2)); do
if (($ntest_ip>=${ip_ranges[$i]} && $ntest_ip<${ip_ranges[$i+1]})); then
echo "$line $test_ip"
break
fi
done
done < <(echo $line|grep -q '[^0-9/.]' && dig @8.8.8.8 +short a $line || echo $line)
done < "$ips"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment