Skip to content

Instantly share code, notes, and snippets.

@ernix
Last active September 24, 2020 08:00
Show Gist options
  • Save ernix/928e51f6b6d01cdc1adac5e6ef2fdece to your computer and use it in GitHub Desktop.
Save ernix/928e51f6b6d01cdc1adac5e6ef2fdece to your computer and use it in GitHub Desktop.
#/bin/sh
set -eu
ip2dec () {
local ip="$1"
if test -z "$ip"; then
printf "Argument required" 1>&2
return 1
fi
if test "$(printf '%s' "$ip" | tr -dc "." | wc -c)" -gt 3; then
printf "Invalid IPv4 address syntax: %s" "$ip" 1>&2
return 1
fi
local chunk i=3 dec=0
for chunk in $(printf '%s' "$ip" | sed 's/\./ /g'); do
if ! test "$chunk" -eq "$chunk" 2>/dev/null; then
printf "Each chunks of IPv4 address must be integer: %s" "$ip" 1>&2
return 1
fi
if test "$((chunk >> 8))" -ne 0; then
printf "Each chunks of IPv4 address must be in range (0 .. 255): %s" "$ip" 1>&2
return 1
fi
dec=$(( dec + (chunk << 8 * i) ))
i=$((i - 1))
done
printf '%d\n' "$dec"
}
dec2ip () {
local dec="$1"
if ! test "$dec" -eq "$dec" 2>/dev/null; then
printf "dec2ip requires decimal: %s" "$dec" 1>&2
return 1
fi
if test "$((dec >> 32))" -ne 0; then
printf "dec2ip requires 32 bit integer: %s" "$dec" 1>&2
return 1
fi
local i ip sep
for i in $(seq 4); do
ip=$(printf "%s%s%s" "$((dec & 0xff))" "${sep:-}" "${ip:-}")
dec=$((dec >> 8))
sep=.
done
printf '%s\n' "$ip"
}
cidr_match () {
local ip_dec cidr
ip_dec=$(ip2dec "$1")
cidr="$2"
local cidraddr cidrmask
IFS=/ read -r cidraddr cidrmask <<__CIDR
$cidr
__CIDR
local cidraddr_dec cidrmask_dec
cidraddr_dec=$(ip2dec "$cidraddr")
cidrmask_dec=$(mask2dec "$cidrmask")
if test "$(( cidraddr_dec & cidrmask_dec ))" -ne "$cidraddr_dec"; then
printf "Invalid CIDR address: %s" "$cidr" 1>&2
return 1
fi
local masked_ip_dec=$((ip_dec & cidrmask_dec))
test "$masked_ip_dec" -eq "$cidraddr_dec"
}
mask2dec () {
local mask="$1"
if ! test "$mask" -eq "$mask" 2>/dev/null; then
printf "Integer required for mask: %s" "$mask" 1>&2
return 1
fi
if test "$mask" -lt 0 -o 32 -lt "$mask"; then
printf "Mask must be in range (0 .. 32): %s" "$mask" 1>&2
return 1
fi
local dec=$(( -1 << (32 - mask) ))
printf '%d\n' "$dec"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment