Search code examples
ship-addresscidrnetmask

Check if an IP falls into an IP range using sh?


Let's suppose I have an IP 173.245.50.16, and I want to check if it falls into the Cloudflare's IP ranges. That basically comes down to:

network_address(173.245.50.16/20) == 173.245.48.0
|| network_address(173.245.50.16/22) == 103.21.244.0
|| ...

Right? Well, I'm not sure about the terminology here, but hopefully you've got the point.

How does that translate into sh code?


Solution

  • What I came up with:

    cf_ip_ranges=`curl -sS https://www.cloudflare.com/ips-v4`
    is_cf_ip() {
        local ip=$1
        local range=$(echo "$cf_ip_ranges" | while IFS= read -r; do
            net=${REPLY%/*}
            n=${REPLY#*/}
            if [ "`ipv4calc --network "$ip/$n"`" = "$net" ]; then
                echo "$REPLY"
                break
            fi
        done)
        if [ "$range" ]; then
            return 0
        else
            return 1
        fi
    }
    if is_cf_ip 8.8.8.8; then
        echo true
    else
        echo false
    fi
    if is_cf_ip 173.245.50.16; then
        echo true
    else
        echo false
    fi
    

    Here I'm using Perl's Net::IPv4Addr module.