aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Prindeville <philipp@redfish-solutions.com>2023-11-11 12:37:20 -0700
committerPhilip Prindeville <philipp@redfish-solutions.com>2023-12-12 12:30:35 -0700
commitdd256099c3fbf48e108381dea8588c38e89cf14a (patch)
tree9cda6d3f772b93c24629ac73470b475174513d47
parent6cdc429a484392afb4ca7c8a32355987d9e0cc73 (diff)
downloadupstream-dd256099c3fbf48e108381dea8588c38e89cf14a.tar.gz
upstream-dd256099c3fbf48e108381dea8588c38e89cf14a.tar.bz2
upstream-dd256099c3fbf48e108381dea8588c38e89cf14a.zip
base-files: ipcalc.sh: Add netmask2prefix function
Also add is_contiguous to check if it's a valid netmask. Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
-rwxr-xr-xpackage/base-files/files/bin/ipcalc.sh7
-rw-r--r--package/base-files/files/lib/functions/ipv4.sh39
2 files changed, 41 insertions, 5 deletions
diff --git a/package/base-files/files/bin/ipcalc.sh b/package/base-files/files/bin/ipcalc.sh
index 4f48e0a7927..9e2702c60d2 100755
--- a/package/base-files/files/bin/ipcalc.sh
+++ b/package/base-files/files/bin/ipcalc.sh
@@ -44,6 +44,7 @@ case "$1" in
# data is n.n.n.n/m.m.m.m format, like on a Cisco router
str2ip ipaddr "${1%/*}" || exit 1
str2ip netmask "${1#*/}" || exit 1
+ netmask2prefix prefix "$netmask" || exit 1
shift
;;
*/*)
@@ -62,6 +63,7 @@ case "$1" in
# address and netmask as two separate arguments
str2ip ipaddr "$1" || exit 1
str2ip netmask "$2" || exit 1
+ netmask2prefix prefix "$netmask" || exit 1
shift 2
;;
esac
@@ -71,11 +73,6 @@ if [ $# -ne 0 ] && [ $# -ne 2 ]; then
usage
fi
-if ! bitcount prefix "$netmask"; then
- printf "Invalid netmask (%s)\n" "$netmask" >&2
- exit 1
-fi
-
# complement of the netmask, i.e. the hostmask
hostmask=$((netmask ^ 0xffffffff))
network=$((ipaddr & netmask))
diff --git a/package/base-files/files/lib/functions/ipv4.sh b/package/base-files/files/lib/functions/ipv4.sh
index 9405a635525..c6fcd2af2e5 100644
--- a/package/base-files/files/lib/functions/ipv4.sh
+++ b/package/base-files/files/lib/functions/ipv4.sh
@@ -157,3 +157,42 @@ prefix2netmask() {
export -- "$__var=$(((~(uint_max >> __n)) & uint_max))"
}
+_is_contiguous() {
+ local __x="$1" # no checking done
+ local __y=$((~__x & uint_max))
+ local __z=$(((__y + 1) & uint_max))
+
+ [ $((__z & __y)) -eq 0 ]
+}
+
+# check argument as being contiguous upper bits (and yes,
+# 0 doesn't have any discontiguous bits).
+is_contiguous() {
+ local __var="$1" __x="$2" __val=0
+ assert_uint32 "$__x" || return 1
+
+ local __y=$((~__x & uint_max))
+ local __z=$(((__y + 1) & uint_max))
+
+ [ $((__z & __y)) -eq 0 ] && __val=1
+
+ export -- "$__var=$__val"
+}
+
+# convert mask to prefix, validating that it's a conventional
+# (contiguous) netmask.
+netmask2prefix() {
+ local __var="$1" __n="$2" __cont __bits
+ assert_uint32 "$__n" || return 1
+
+ is_contiguous __cont "$__n" || return 1
+ if [ $__cont -eq 0 ]; then
+ printf "Not a contiguous netmask (%08x)\n" "$__n" >&2
+ return 1
+ fi
+
+ bitcount __bits "$__n" # already checked
+
+ export -- "$__var=$__bits"
+}
+