]> git.ipfire.org Git - people/stevee/network.git/blobdiff - functions.ipv4
firewall: Add kernel initialization.
[people/stevee/network.git] / functions.ipv4
index d074ca940ab35408876d6be8e446d445b5ec20a3..d7a6b85a71184093b8989de06670613ce0ac7046 100644 (file)
@@ -34,6 +34,17 @@ function ipv4_is_valid() {
        esac
 }
 
+function ipv4_prefix_is_valid() {
+       local prefix=${1}
+
+       isset prefix || return ${EXIT_FALSE}
+
+       [ ${prefix} -le  0 ] && return ${EXIT_FALSE}
+       [ ${prefix} -gt 32 ] && return ${EXIT_FALSE}
+
+       return ${EXIT_TRUE}
+}
+
 function ipv4_detect_duplicate() {
        local device=${1}
        local address=${2}
@@ -42,6 +53,9 @@ function ipv4_detect_duplicate() {
        assert isset device
        assert device_exists ${device}
 
+       # Don't check on PPP devices.
+       device_is_ppp ${device} && return ${EXIT_ERROR}
+
        if ! arping -q -c 2 -w 3 -D -I ${device} ${address}; then
                log DEBUG "Detected duplicate address '${address}' on device '${device}'."
                return ${EXIT_OK}
@@ -54,6 +68,9 @@ function ipv4_update_neighbours() {
        local device=${1}
        local address=${2}
 
+       # Don't do anything on PPP devices.
+       device_is_ppp ${device} && return ${EXIT_OK}
+
        arping -q -A -c 1 -I ${device} ${address}
        ( sleep 2; arping -q -U -c 1 -I ${device} ${address} ) >/dev/null 2>&1 </dev/null &
 }
@@ -63,13 +80,297 @@ function ipv4_get_netaddress() {
        assert isset address
 
        local prefix=$(ip_get_prefix ${address})
-       assert isset prefix
+       isset prefix || prefix="32"
+
+       # Assume host-only address if no prefix has been given.
+       if [ "${prefix}" = "32" ]; then
+               echo "${address}/${prefix}"
+               return ${EXIT_OK}
+       fi
 
        local NETWORK
        eval $(ipcalc --network ${address})
        assert isset NETWORK
 
        echo "${NETWORK}/${prefix}"
+       return ${EXIT_OK}
+}
+
+function ipv4_get_prefix() {
+       local address=${1}
+       local broadcast=${2}
 
+       assert isset address
+       assert isset broadcast
+
+       local PREFIX
+       eval $(ipcalc --prefix ${address} ${broadcast})
+       assert isset PREFIX
+
+       echo "${PREFIX}"
        return ${EXIT_OK}
 }
+
+function ipv4_get_netmask() {
+       local address=${1}
+       assert isset address
+
+       # Add prefix if none given.
+       local prefix=$(ip_get_prefix ${address})
+       isset prefix || address="${address}/32"
+
+       local NETMASK
+       eval $(ipcalc --netmask ${address})
+       assert isset NETMASK
+
+       print "${NETMASK}"
+       return ${EXIT_OK}
+}
+
+function ipv4_flush_device() {
+       #
+       # Flushes all routes, addresses from the device
+       # and clears the ARP cache.
+       #
+
+       local device=${1}
+       assert isset device
+
+       ip -4 addr flush dev ${device} >/dev/null 2>&1
+       ip -4 route flush dev ${device} >/dev/null 2>&1
+       ip -4 neigh flush dev ${device} >/dev/null 2>&1
+
+       return 0
+}
+
+function ipv4_prefix2netmask() {
+       local prefix=${1}
+       shift
+
+       assert isinteger prefix
+
+       # XXX this function is a stub
+
+       case "${prefix}" in
+               24)
+                       echo "255.255.255.0"
+                       ;;
+               *)
+                       assert false NOT IMPLEMENTED
+                       ;;
+       esac
+}
+
+function ipv4_get_network() {
+       local network=$(ipv4_get_network $@)
+
+       ipv4_decode ${network}
+}
+
+function ipv4_get_network_encoded() {
+       local net=${1}
+
+       local prefix=$(ip_get_prefix ${net})
+       isset prefix || prefix=32
+
+       local mask=0
+       if [ ${prefix} -ne 0 ]; then
+               mask=$(( -1 << $(( 32 - ${prefix} )) ))
+       fi
+
+       local addr=$(ip_split_prefix ${net})
+       addr=$(ipv4_encode ${addr})
+
+       print "%d" $(( ${addr} & ${mask} ))
+}
+
+function ipv4_get_broadcast() {
+       local broadcast=$(ipv4_get_broadcast_encoded $@)
+
+       ipv4_decode ${broadcast}
+}
+
+function ipv4_get_broadcast_encoded() {
+       local net=${1}
+
+       local prefix=$(ip_get_prefix ${net})
+       assert isset prefix
+
+       prefix=$(( 32 - ${prefix} ))
+
+       local netmask=0
+       local broadcast=-1
+       if [ ${prefix} -eq 32 ]; then
+               :
+       else
+               netmask=$(( -1 << ${prefix} ))
+               broadcast=$(( $(( 1 << ${prefix} )) - 1))
+       fi
+
+       local addr=$(ip_split_prefix ${net})
+       addr=$(ipv4_encode ${addr})
+
+       print "%d" $(( $(( ${addr} & ${netmask} )) | ${broadcast} ))
+}
+
+function ipv4_encode() {
+       local addr=${1}
+       local int=0
+
+       local field
+       for field in ${addr//./ }; do
+               int=$(( $(( ${int} << 8 )) | ${field} ))
+       done
+
+       print "${int}"
+}
+
+function ipv4_decode() {
+       local int=${1}
+
+       local addr=$(( ${int} & 255 ))
+
+       local i
+       for i in 1 2 3; do
+               int=$(( ${int} >> 8 ))
+               addr="$(( ${int} & 255 )).${addr}"
+       done
+
+       print "${addr}"
+}
+
+function ipv4_addr_eq() {
+       local addr1=${1}
+       assert isset addr1
+
+       local addr2=${2}
+       assert isset addr2
+
+       [[ "${addr1}" = "${addr2}" ]] \
+               && return ${EXIT_TRUE} || return ${EXIT_FALSE}
+}
+
+function ipv4_addr_gt() {
+       local addr1=${1}
+       assert isset addr1
+
+       local addr2=${2}
+       assert isset addr2
+
+       local addr
+       for addr in addr1 addr2; do
+               printf -v ${addr} "%s" "$(ip_encode ${!addr})"
+       done
+
+       [[ ${addr1} -gt ${addr2} ]] \
+               && return ${EXIT_TRUE} || return ${EXIT_FALSE}
+}
+
+function ipv4_range() {
+       local range=${1}
+
+       local first=${1%-*}
+       local last=${1#*-}
+
+       _ipv4_range "$(ipv4_encode ${first})" "$(ipv4_encode ${last})"
+}
+
+function _ipv4_range() {
+       local first=${1}
+       local last=${2}
+
+       if [ ${first} -gt ${last} ]; then
+               local range="$(ipv4_decode ${first})-$(ipv4_decode ${last})"
+
+               error "Invalid IPv4 address range: ${range}"
+               return ${EXIT_ERROR}
+       fi
+
+       last=$(( ${last} + 1 ))
+
+       local prefix
+       local x y z
+       while [ ${last} -gt ${first} ]; do
+               prefix=
+               x=31
+               y=2
+               z=1
+
+               while [ $(( ${first} % ${y} )) -eq 0 ] && [ ${last} -gt $(( ${first} + ${y} )) ]; do
+                       prefix="/${x}"
+                       x=$(( ${x} - 1 ))
+                       z=${y}
+                       y=$(( ${y} * 2 ))
+               done
+
+               print "$(ipv4_decode ${first})${prefix}"
+               first=$(( ${first} + ${z} ))
+       done
+}
+
+function ipv4_range_explicit() {
+       local range=${1}
+
+       local first last
+
+       case "${range}" in
+               *.*.*.*-*.*.*.*)
+                       first=${range%-*}
+                       last=${range#*-}
+                       ;;
+               *.*.*.*/*)
+                       first=$(ipv4_get_network ${range})
+                       last=$(ipv4_get_broadcast ${range})
+                       ;;
+       esac
+
+       _ipv4_range_explicit "$(ipv4_encode ${first})" "$(ipv4_encode ${last})"
+}
+
+function _ipv4_range_explicit() {
+       local first=${1}
+       local last=${2}
+
+       if [ ${first} -gt ${last} ]; then
+               local range="$(ipv4_decode ${first})-$(ipv4_decode ${last})"
+
+               error "Invalid IPv4 address range: ${range}"
+               return ${EXIT_ERROR}
+       fi
+
+       while [ ${first} -le ${last} ]; do
+               ipv4_decode ${first}
+               first=$(( ${first} + 1 ))
+       done
+}
+
+function ipv4_in_subnet() {
+       local addr=${1}
+       assert isset addr
+
+       local subnet=${2}
+       assert isset subnet
+
+       local subnet_first=$(ipv4_get_network_encoded ${subnet})
+       local subnet_last=$(ipv4_get_broadcast_encoded ${subnet})
+
+       addr=$(ipv4_encode ${addr})
+
+       if [[ "${addr}" -ge "${subnet_first}" ]] && [[ "${addr}" -le "${subnet_last}" ]]; then
+               return ${EXIT_TRUE}
+       fi
+
+       return ${EXIT_FALSE}
+}
+
+function ipv4_ttl_valid() {
+       local ttl="${1}"
+
+       isinteger ttl || return ${EXIT_FALSE}
+
+       # Must be between 10 and 255.
+       [ "${ttl}" -lt  10 ] && return ${EXIT_FALSE}
+       [ "${ttl}" -gt 255 ] && return ${EXIT_FALSE}
+
+       return ${EXIT_TRUE}
+}