From 193dbc3a62c8729c09e7ddabc3d101946a16f9d8 Mon Sep 17 00:00:00 2001 From: Giacomo Sanchietti Date: Wed, 25 Feb 2026 13:01:17 +0100 Subject: [PATCH] fix: replace upstream ipcalc Get ipcalc: from https://raw.githubusercontent.com/openwrt/openwrt/32ed3db1a0c36aeecd027ee585669ab0a390ac22/package/base-files/files/bin/ipcalc.sh Make sure dnsmsq does not fail if the firewall IP is indside the DHCP range. --- files/bin/ipcalc.sh | 142 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 files/bin/ipcalc.sh diff --git a/files/bin/ipcalc.sh b/files/bin/ipcalc.sh new file mode 100644 index 000000000..e8c7a07df --- /dev/null +++ b/files/bin/ipcalc.sh @@ -0,0 +1,142 @@ +#!/bin/sh + +. /lib/functions/ipv4.sh + +PROG="$(basename "$0")" + +# wrapper to convert an integer to an address, unless we're using +# decimal output format. +# hook for library function +_ip2str() { + local var="$1" n="$2" + assert_uint32 "$n" || exit 1 + + if [ "$decimal" -ne 0 ]; then + export -- "$var=$n" + elif [ "$hexadecimal" -ne 0 ]; then + export -- "$var=$(printf "%x" "$n")" + else + ip2str "$@" + fi +} + +usage() { + echo "Usage: $PROG [ -d | -x ] address/prefix [ start limit ]" >&2 + exit 1 +} + +decimal=0 +hexadecimal=0 +if [ "$1" = "-d" ]; then + decimal=1 + shift +elif [ "$1" = "-x" ]; then + hexadecimal=1 + shift +fi + +if [ $# -eq 0 ]; then + usage +fi + +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 + ;; +*/*) + # more modern prefix notation of n.n.n.n/p + str2ip ipaddr "${1%/*}" || exit 1 + prefix="${1#*/}" + assert_uint32 "$prefix" || exit 1 + if [ "$prefix" -gt 32 ]; then + printf "Prefix out of range (%s)\n" "$prefix" >&2 + exit 1 + fi + prefix2netmask netmask "$prefix" || exit 1 + shift + ;; +*) + # 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 + +# we either have no arguments left, or we have a range start and length +if [ $# -ne 0 ] && [ $# -ne 2 ]; then + usage +fi + +# complement of the netmask, i.e. the hostmask +hostmask=$((netmask ^ 0xffffffff)) +network=$((ipaddr & netmask)) +broadcast=$((network | hostmask)) +count=$((hostmask + 1)) + +_ip2str IP "$ipaddr" +_ip2str NETMASK "$netmask" +_ip2str NETWORK "$network" + +echo "IP=$IP" +echo "NETMASK=$NETMASK" +# don't include this-network or broadcast addresses +if [ "$prefix" -le 30 ]; then + _ip2str BROADCAST "$broadcast" + echo "BROADCAST=$BROADCAST" +fi +echo "NETWORK=$NETWORK" +echo "PREFIX=$prefix" +echo "COUNT=$count" + +# if there's no range, we're done +[ $# -eq 0 ] && exit 0 +[ -z "$1$2" ] && exit 0 + +if [ "$prefix" -le 30 ]; then + lower=$((network + 1)) +else + lower="$network" +fi + +start="$1" +assert_uint32 "$start" || exit 1 +start=$((network | (start & hostmask))) +[ "$start" -lt "$lower" ] && start="$lower" +[ "$start" -eq "$ipaddr" ] && start=$((start + 1)) + +if [ "$prefix" -le 30 ]; then + upper=$(((network | hostmask) - 1)) +elif [ "$prefix" -eq 31 ]; then + upper=$((network | hostmask)) +else + upper="$network" +fi + +range="$2" +assert_uint32 "$range" || exit 1 +end=$((start + range - 1)) +[ "$end" -gt "$upper" ] && end="$upper" +[ "$end" -eq "$ipaddr" ] && end=$((end - 1)) + +if [ "$start" -gt "$end" ]; then + echo "network ($NETWORK/$prefix) too small" >&2 + exit 1 +fi + +_ip2str START "$start" +_ip2str END "$end" + +if [ "$start" -le "$ipaddr" ] && [ "$ipaddr" -le "$end" ]; then + echo "warning: address $IP inside range $START..$END" >&2 +fi + +echo "START=$START" +echo "END=$END" + +exit 0