diff --git a/functions b/functions index 3a3e28bcdb..ba3ce652ed 100644 --- a/functions +++ b/functions @@ -18,15 +18,38 @@ XTRACE=$(set +o | grep xtrace) set +o xtrace -# Exit 0 if address is in network or 1 if address is not in -# network or netaddr library is not installed. +# Convert CIDR notation to a IPv4 netmask +# cidr2netmask cidr-bits +function cidr2netmask() { + local maskpat="255 255 255 255" + local maskdgt="254 252 248 240 224 192 128" + set -- ${maskpat:0:$(( ($1 / 8) * 4 ))}${maskdgt:$(( (7 - ($1 % 8)) * 4 )):3} + echo ${1-0}.${2-0}.${3-0}.${4-0} +} + + +# Return the network portion of the given IP address using netmask +# netmask is in the traditional dotted-quad format +# maskip ip-address netmask +function maskip() { + local ip=$1 + local mask=$2 + local l="${ip%.*}"; local r="${ip#*.}"; local n="${mask%.*}"; local m="${mask#*.}" + local subnet=$((${ip%%.*}&${mask%%.*})).$((${r%%.*}&${m%%.*})).$((${l##*.}&${n##*.})).$((${ip##*.}&${mask##*.})) + echo $subnet +} + + +# Exit 0 if address is in network or 1 if address is not in network +# ip-range is in CIDR notation: 1.2.3.4/20 # address_in_net ip-address ip-range function address_in_net() { - python -c " -import netaddr -import sys -sys.exit(netaddr.IPAddress('$1') not in netaddr.IPNetwork('$2')) -" + local ip=$1 + local range=$2 + local masklen=${range#*/} + local network=$(maskip ${range%/*} $(cidr2netmask $masklen)) + local subnet=$(maskip $ip $(cidr2netmask $masklen)) + [[ $network == $subnet ]] } diff --git a/tests/test_ip.sh b/tests/test_ip.sh new file mode 100755 index 0000000000..e9cbcca4a4 --- /dev/null +++ b/tests/test_ip.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash + +# Tests for DevStack functions +# address_in_net() + +TOP=$(cd $(dirname "$0")/.. && pwd) + +# Import common functions +source $TOP/functions + +# Import configuration +source $TOP/openrc + + +echo "Testing IP addr functions" + +if [[ $(cidr2netmask 4) == 240.0.0.0 ]]; then + echo "cidr2netmask(): /4...OK" +else + echo "cidr2netmask(): /4...failed" +fi +if [[ $(cidr2netmask 8) == 255.0.0.0 ]]; then + echo "cidr2netmask(): /8...OK" +else + echo "cidr2netmask(): /8...failed" +fi +if [[ $(cidr2netmask 12) == 255.240.0.0 ]]; then + echo "cidr2netmask(): /12...OK" +else + echo "cidr2netmask(): /12...failed" +fi +if [[ $(cidr2netmask 16) == 255.255.0.0 ]]; then + echo "cidr2netmask(): /16...OK" +else + echo "cidr2netmask(): /16...failed" +fi +if [[ $(cidr2netmask 20) == 255.255.240.0 ]]; then + echo "cidr2netmask(): /20...OK" +else + echo "cidr2netmask(): /20...failed" +fi +if [[ $(cidr2netmask 24) == 255.255.255.0 ]]; then + echo "cidr2netmask(): /24...OK" +else + echo "cidr2netmask(): /24...failed" +fi +if [[ $(cidr2netmask 28) == 255.255.255.240 ]]; then + echo "cidr2netmask(): /28...OK" +else + echo "cidr2netmask(): /28...failed" +fi +if [[ $(cidr2netmask 30) == 255.255.255.252 ]]; then + echo "cidr2netmask(): /30...OK" +else + echo "cidr2netmask(): /30...failed" +fi +if [[ $(cidr2netmask 32) == 255.255.255.255 ]]; then + echo "cidr2netmask(): /32...OK" +else + echo "cidr2netmask(): /32...failed" +fi + +if [[ $(maskip 169.254.169.254 240.0.0.0) == 160.0.0.0 ]]; then + echo "maskip(): /4...OK" +else + echo "maskip(): /4...failed" +fi +if [[ $(maskip 169.254.169.254 255.0.0.0) == 169.0.0.0 ]]; then + echo "maskip(): /8...OK" +else + echo "maskip(): /8...failed" +fi +if [[ $(maskip 169.254.169.254 255.240.0.0) == 169.240.0.0 ]]; then + echo "maskip(): /12...OK" +else + echo "maskip(): /12...failed" +fi +if [[ $(maskip 169.254.169.254 255.255.0.0) == 169.254.0.0 ]]; then + echo "maskip(): /16...OK" +else + echo "maskip(): /16...failed" +fi +if [[ $(maskip 169.254.169.254 255.255.240.0) == 169.254.160.0 ]]; then + echo "maskip(): /20...OK" +else + echo "maskip(): /20...failed" +fi +if [[ $(maskip 169.254.169.254 255.255.255.0) == 169.254.169.0 ]]; then + echo "maskip(): /24...OK" +else + echo "maskip(): /24...failed" +fi +if [[ $(maskip 169.254.169.254 255.255.255.240) == 169.254.169.240 ]]; then + echo "maskip(): /28...OK" +else + echo "maskip(): /28...failed" +fi +if [[ $(maskip 169.254.169.254 255.255.255.255) == 169.254.169.254 ]]; then + echo "maskip(): /32...OK" +else + echo "maskip(): /32...failed" +fi + +for mask in 8 12 16 20 24 26 28; do + echo -n "address_in_net(): in /$mask..." + if address_in_net 10.10.10.1 10.10.10.0/$mask; then + echo "OK" + else + echo "address_in_net() failed on /$mask" + fi + + echo -n "address_in_net(): not in /$mask..." + if ! address_in_net 10.10.10.1 11.11.11.0/$mask; then + echo "OK" + else + echo "address_in_net() failed on /$mask" + fi +done