summaryrefslogtreecommitdiffstats
path: root/package/base-files/files/lib/functions
diff options
context:
space:
mode:
authorPhilip Prindeville <philipp@redfish-solutions.com>2023-10-22 13:27:50 -0600
committerPhilip Prindeville <philipp@redfish-solutions.com>2023-12-12 12:30:35 -0700
commit854739b32c7f2e56e5b79ee049749e60faece8f5 (patch)
tree920d7db684def8cde7a6ebae1136bc4a303ca09a /package/base-files/files/lib/functions
parent1438bc583c671120ddd38f4eb2dc786ec53e207c (diff)
downloadopenwrt-854739b32c7f2e56e5b79ee049749e60faece8f5.tar.gz
openwrt-854739b32c7f2e56e5b79ee049749e60faece8f5.tar.bz2
openwrt-854739b32c7f2e56e5b79ee049749e60faece8f5.zip
base-files: ipcalc.sh: Rewrite in pure shell
Also add better error checking on input. Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
Diffstat (limited to 'package/base-files/files/lib/functions')
-rw-r--r--package/base-files/files/lib/functions/ipv4.sh140
1 files changed, 140 insertions, 0 deletions
diff --git a/package/base-files/files/lib/functions/ipv4.sh b/package/base-files/files/lib/functions/ipv4.sh
new file mode 100644
index 0000000000..30ae480305
--- /dev/null
+++ b/package/base-files/files/lib/functions/ipv4.sh
@@ -0,0 +1,140 @@
+uint_max=4294967295
+
+assert_uint32() {
+ local __n="$1"
+
+ if [ -z "$__n" -o -n "${__n//[0-9]/}" ]; then
+ printf "Not a decimal integer (%s)\n" "$__n ">&2
+ return 1
+ fi
+
+ if [ "$__n" -gt $uint_max ]; then
+ printf "Out of range (%s)\n" "$__n" >&2
+ return 1
+ fi
+
+ if [ "$((__n + 0))" != "$__n" ]; then
+ printf "Not normalized notation (%s)\n" "$__n" >&2
+ return 1
+ fi
+
+ return 0
+}
+
+bitcount() {
+ local __var="$1" __c="$2"
+ assert_uint32 "$__c" || return 1
+
+ __c=$((((__c >> 1) & 0x55555555) + (__c & 0x55555555)))
+ __c=$((((__c >> 2) & 0x33333333) + (__c & 0x33333333)))
+ __c=$((((__c >> 4) & 0x0f0f0f0f) + (__c & 0x0f0f0f0f)))
+ __c=$((((__c >> 8) & 0x00ff00ff) + (__c & 0x00ff00ff)))
+ __c=$((((__c >> 16) & 0x0000ffff) + (__c & 0x0000ffff)))
+
+ export -- "$__var=$__c"
+}
+
+# tedious but portable with busybox's limited shell
+str2ip() {
+ local __var="$1" __ip="$2" __n __val=0
+
+ case "$__ip" in
+ [0-9].*)
+ __n="${__ip:0:1}"
+ __ip="${__ip:2}"
+ ;;
+ [1-9][0-9].*)
+ __n="${__ip:0:2}"
+ __ip="${__ip:3}"
+ ;;
+ 1[0-9][0-9].*|2[0-4][0-9].*|25[0-5].*)
+ __n="${__ip:0:3}"
+ __ip="${__ip:4}"
+ ;;
+ *)
+ printf "Not a dotted quad (%s)\n" "$2" >&2
+ return 1
+ ;;
+ esac
+
+ __val=$((__n << 24))
+
+ case "$__ip" in
+ [0-9].*)
+ __n="${__ip:0:1}"
+ __ip="${__ip:2}"
+ ;;
+ [1-9][0-9].*)
+ __n="${__ip:0:2}"
+ __ip="${__ip:3}"
+ ;;
+ 1[0-9][0-9].*|2[0-4][0-9].*|25[0-5].*)
+ __n="${__ip:0:3}"
+ __ip="${__ip:4}"
+ ;;
+ *)
+ printf "Not a dotted quad (%s)\n" "$2" >&2
+ return 1
+ ;;
+ esac
+
+ __val=$((__val + (__n << 16)))
+
+ case "$__ip" in
+ [0-9].*)
+ __n="${__ip:0:1}"
+ __ip="${__ip:2}"
+ ;;
+ [1-9][0-9].*)
+ __n="${__ip:0:2}"
+ __ip="${__ip:3}"
+ ;;
+ 1[0-9][0-9].*|2[0-4][0-9].*|25[0-5].*)
+ __n="${__ip:0:3}"
+ __ip="${__ip:4}"
+ ;;
+ *)
+ printf "Not a dotted quad (%s)\n" "$2" >&2
+ return 1
+ ;;
+ esac
+
+ __val=$((__val + (__n << 8)))
+
+ case "$__ip" in
+ [0-9])
+ __n="${__ip:0:1}"
+ __ip="${__ip:1}"
+ ;;
+ [1-9][0-9])
+ __n="${__ip:0:2}"
+ __ip="${__ip:2}"
+ ;;
+ 1[0-9][0-9]|2[0-4][0-9]|25[0-5])
+ __n="${__ip:0:3}"
+ __ip="${__ip:3}"
+ ;;
+ *)
+ printf "Not a dotted quad (%s)\n" "$2" >&2
+ return 1
+ ;;
+ esac
+
+ __val=$((__val + __n))
+
+ if [ -n "$__ip" ]; then
+ printf "Not a dotted quad (%s)\n" "$2" >&2
+ return 1
+ fi
+
+ export -- "$__var=$__val"
+ return 0
+}
+
+ip2str() {
+ local __var="$1" __n="$2"
+ assert_uint32 "$__n" || return 1
+
+ export -- "$__var=$((__n >> 24)).$(((__n >> 16) & 255)).$(((__n >> 8) & 255)).$((__n & 255))"
+}
+