Skip to content

Instantly share code, notes, and snippets.

@gtrabanco
Last active August 29, 2021 11:31
Show Gist options
  • Save gtrabanco/7726c4da182775b9268298c24bee5b85 to your computer and use it in GitHub Desktop.
Save gtrabanco/7726c4da182775b9268298c24bee5b85 to your computer and use it in GitHub Desktop.
Netmask to bits & bits to netmask
#!/usr/bin/env bash
#shellcheck disable=SC2206,SC2207
ipv4_netmask() {
local IFS='.' netmask=() rest_bits tmp_netmask=0
local -r bits="${1:-0}"
if [[ $bits -lt 0 || $bits -gt 32 ]]; then
echo "Error: IPv4 netmask should be between 0 and 32" 1>&2
return 1
fi
local -r complete=$(( bits / 8 ))
rest_bits=$(( bits % 8 ))
until [[ ${#netmask[@]} -eq $complete ]]; do
netmask+=("255")
done
if [[ $rest -lt 8 ]]; then
while [[ $rest_bits -gt 0 ]]; do
tmp_netmask=$(( ( 2 ** ( 8 - rest_bits ) ) + tmp_netmask ))
rest_bits=$(( rest_bits - 1 ))
done
netmask+=("$tmp_netmask")
fi
while [[ ${#netmask[@]} -lt 4 ]]; do
netmask+=("0")
done
echo "${netmask[*]}"
}
ipv4_wildcard() {
local IFS='.' netmask=() i
local -r bits="${1:-0}"
netmask=(${1:-0})
if [[ ${#netmask[@]} -eq 1 ]]; then
netmask=($(ipv4_netmask "${1:-0}"))
fi
for i in "${!netmask[@]}"; do
if [[ ${netmask[$i]} -lt 0 || ${netmask[$i]} -gt 255 ]]; then
echo "Network mask should not have any octet lower than 0 and greater than 255" 1>&2
return 1
fi
netmask["$i"]=$(( 255 - netmask[i] ))
done
echo "${netmask[*]}"
}
ipv4_bits_to_mask() {
local mask=0 bits="${1:-0}"
if [[ $bits -lt 0 || $bits -gt 8 ]]; then
echo "Invalid number of bits"
return 1
fi
while [[ $bits -gt 0 ]]; do
mask=$(( ( 2 ** ( 8 - bits ) ) + mask ))
bits=$(( bits - 1 ))
if [[ $mask -lt 0 ]]; then
echo "Invalid mask?" 1>&2
return 1
fi
done
echo "$mask"
}
ipv4_mask_to_bits() {
local bits=0 mask="${1:-0}"
if [[ $mask -gt 255 || $mask -lt 0 ]]; then
echo "Octet should be between 0 and 255" 1>&2
return 1
fi
while [[ $mask -gt 0 ]]; do
bits=$(( bits + 1 ))
mask=$(( mask - ( 2 ** ( 8 - bits ) ) ))
if [[ $mask -lt 0 ]]; then
echo "Invalid mask" 1>&2
return 1
fi
done
echo "$bits"
}
ipv4_bits() {
local IFS='.' bits=0 total_bits=0 netmask
netmask=(${1:-0.0.0.0})
if [[ ${#netmask[@]} -eq 1 && ${netmask[0]} -ge 0 && ${netmask[0]} -le 32 ]]; then
echo "${1:-0}"
return
elif [[ ${#netmask[@]} -ne 4 ]]; then
echo "Network mask should have 4 octetts" 1>&2
return 1
fi
for i in "${!netmask[@]}"; do
if [[ ${netmask[$i]} -lt 0 || ${netmask[$i]} -gt 255 ]]; then
echo "Network mask should not have any octet lower than 0 and greater than 255" 1>&2
return 1
fi
bits=0
while [[ ${netmask[$i]} -gt 0 ]]; do
bits=$(( bits + 1))
netmask[$i]=$(( netmask[i] - ( 2 ** ( 8 - bits ) ) ))
if [[ netmask[$i] -lt 0 ]]; then
echo "Invalid mask" 1>&2
return 1
fi
done
total_bits=$(( total_bits + bits ))
done
echo "$total_bits"
}
validate_ip_cidr() {
[[ $1 =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/(3[0-2]|[0-2]?[0-9]{1})$ ]] ||
[[ $1 =~ ^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}\/(12[0-8]|1[0-1][0-9]|[0-9]?[0-9]{1})$ ]]
}
validate_ip() {
[[ "$1" =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ ]] ||
[[ $1 =~ ^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$ ]]
}
ipGetMask() {
local bits
bits="$(echo "$1" | grep -E -o "(\/(3[0-2]|[0-2]?[0-9]{1})?)$" || echo "/-1")"
bits="${bits:1}"
if [[ $bits -ge 0 && $bits -le 32 ]]; then
echo "$bits"
fi
}
ipv4_netmask 24
ipv4_wildcard 24
ipv4_wildcard 255.128.0.0
ipv4_bits 255.255.128.0
ipv4_bits_to_mask 2
ipv4_mask_to_bits 192
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment