initscripts: sync networking functions from IPFire

following commit made changes to networking functions

commit 76ea485d9edb781328e307c68b1f878d933408e5
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Fri Sep 27 17:39:22 2024 +0200

    wireguard: Select the correct source IP address for N2N peers

    This is so that the firewall chooses the correct IP address when trying
    to establish connections to the remote networks.

    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit d99826dc71
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Sep 24 10:33:22 2024 +0200

    suricata: Enable scanning IPsec packets

    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit db151ad716
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sun Sep 22 17:08:03 2024 +0200

    suricata: Add support for zones having multiple interfaces

    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 1b7d1abdf0
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Sep 10 10:50:15 2024 +0200

    suricata: Add option to scan WireGuard

    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 79cce701a9
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Tue Sep 10 10:40:28 2024 +0200

    suricata: Restore the interface selection

    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit 3f863ee70d
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Sat Mar 23 14:32:30 2024 +0100

    initscripts: Add some basic functions for IP address maths

    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

commit e340d393d3
Author: Michael Tremer <michael.tremer@ipfire.org>
Date:   Fri Mar 22 17:40:15 2024 +0100

    network: Don't include initscript headers twice

    Everywhere we import the functions, we have already imported the
    standard includes.

    Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>

Signed-off-by: Vincent Li <vincent.mc.li@gmail.com>
This commit is contained in:
Vincent Li
2025-07-02 16:55:13 +00:00
parent dd9a60e720
commit d854559daf

View File

@@ -19,12 +19,273 @@
# #
###############################################################################
. /etc/sysconfig/rc
. $rc_functions
eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
eval $(/usr/local/bin/readhash /var/ipfire/dns/settings)
ip2bin() {
local address="${1}"
local IFS='.'
local octet
local n=0
for octet in ${address}; do
# Shift n
(( n <<= 8 ))
# Apply the octet
(( n |= octet ))
done
echo "${n}"
}
bin2ip() {
local n="${1}"
local IFS='.'
local address=()
for i in {3..0}; do
address+=( $(( n >> (8 * i) & 0xff )) )
done
echo "${address[*]}"
}
network_get_intfs() {
local zone="${1}"
case "${zone^^}" in
RED)
# For PPPoE, the RED interface is called ppp0 (unless we use QMI)
if [ "${RED_TYPE}" = "PPPOE" ] && [ "${RED_DRIVER}" != "qmi_wwan" ]; then
echo "ppp0"
return 0
# Otherwise we return RED_DEV
elif [ -n "${RED_DEV}" ]; then
echo "${RED_DEV}"
return 0
fi
;;
GREEN)
if [ -n "${GREEN_DEV}" ]; then
echo "${GREEN_DEV}"
return 0
fi
;;
ORANGE)
if [ -n "${ORANGE_DEV}" ]; then
echo "${ORANGE_DEV}"
return 0
fi
;;
BLUE)
if [ -n "${BLUE_DEV}" ]; then
echo "${BLUE_DEV}"
return 0
fi
;;
IPSEC)
local VARS=(
id status x1 x2 type x3 x4 x5 x6 x7 x8 x9 x10
x11 x12 x13 x14 x15 x16 x17 x18 x19 x20
x21 x22 x23 x24 x25 x26 x27 x28 x29 x30
x31 x32 x33 x34 interface_mode rest
)
while IFS="," read -r "${VARS[@]}"; do
# Check if the connection is enabled
[ "${status}" = "on" ] || continue
# Check if this a net-to-net connection
[ "${type}" = "net" ] || continue
# Determine the interface name
case "${interface_mode}" in
gre|vti)
echo "${interface_mode}${id}"
;;
esac
done < /var/ipfire/vpn/config
return 0
;;
WIREGUARD|WG)
echo "wg+"
return 0
;;
OPENVPN|OVPN)
# OpenVPN is using all tun devices
echo "tun+"
return 0
;;
esac
# Not found
return 1
}
network_get_address() {
local network="${1}"
# Return everything before the slash
echo "${network%%/*}"
}
network_get_prefix() {
local network="${1}"
# Consider everything after the / the prefix
local prefix="${network##*/}"
# If the prefix is valid, return it
if network_prefix_is_valid "${prefix}"; then
echo "${prefix}"
# Otherwise it might be a subnet mask
else
network_netmask_to_prefix "${prefix}"
fi
}
network_get_netmask() {
local network="${1}"
# Consider everything after the / the netmask
local netmask="${network##*/}"
# If we have a prefix, we need to convert
if network_prefix_is_valid "${netmask}"; then
network_prefix_to_netmask "${netmask}"
# Otherwise return what we got
else
echo "${netmask}"
fi
}
network_prefix_is_valid() {
local prefix="${1}"
# The prefix must be numbers only
if ! [[ "${prefix}" =~ ^[0-9]+$ ]]; then
return 1
fi
# Must be a number between 0 and 32 (inclusive)
[ "${prefix}" -ge 0 -a "${prefix}" -le 32 ]
}
network_prefix_to_netmask() {
local prefix="${1}"
# Set n with all bits set
local n=0xffffffff
# Shift
(( n <<= (32 - prefix) ))
# Convert back
bin2ip "${n}"
}
network_netmask_to_prefix() {
local netmask="${1}"
local prefix=0
# Convert to binary
local n="$(ip2bin "${netmask}")"
while [ "${n}" -gt 0 ]; do
# If the highest bit is not set, we are done
[ "$(( n & (1 << 31) ))" -eq 0 ] && break
# Increment prefix & shift n
(( prefix++ ))
(( n <<= 1 ))
done
echo "${prefix}"
}
network_address_in_network() {
local address="${1}"
local network="${2}"
# Split the network into its address & mask
local netaddr="$(network_get_address "${network}")"
local netmask="$(network_get_netmask "${network}")"
# Abort if we could not parse the network
if [ -z "${netaddr}" -o -z "${netmask}" ]; then
return 1
fi
# Convert everything to binary
address="$(ip2bin "${address}")"
netaddr="$(ip2bin "${netaddr}")"
netmask="$(ip2bin "${netmask}")"
# Ensure the network address is the first address
(( netaddr &= netmask ))
# Compute broadcast
local broadcast=$(( netaddr | (~netmask & 0xffffffff) ))
# Return true if address is in the network
[ "${address}" -ge "${netaddr}" -a "${address}" -le "${broadcast}" ]
}
# Takes a network and list of IP addresses and will return the first IP address
# that is in the given network.
first_address_in_network() {
local network="${1}"
shift
local addr
for addr in $@; do
if network_address_in_network "${addr}" "${network}"; then
echo "${addr}"
return 0
fi
done
return 1
}
# Returns the first of IPFire's own IP addresses that is in any of the given networks
ipfire_address_in_networks() {
local addresses=()
local var
for var in GREEN_ADDRESS BLUE_ADDRESS ORANGE_ADDRESS; do
if [ -n "${!var}" ]; then
addresses+=( "${!var}" )
fi
done
local network
for network in $@; do
# Find and end after the first match
if first_address_in_network "${network}" "${addresses[@]}"; then
return 0
fi
done
# Nothing found
return 1
}
dhcpcd_get_pid() {
# This function returns the pid of a dhcpcd by a given
# network device, if a pidfile exists.