From: Michael Tremer Date: Sat, 15 Sep 2012 18:38:44 +0000 (+0000) Subject: ipv{6,4}: Simplify some functions and introduce new ones. X-Git-Tag: 005~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ab70371d170f28276a262ec7fe82a86f22145cc8;p=network.git ipv{6,4}: Simplify some functions and introduce new ones. Too much stuff to break down... --- diff --git a/functions.ipv4 b/functions.ipv4 index a48839db..ba97aaa1 100644 --- a/functions.ipv4 +++ b/functions.ipv4 @@ -36,7 +36,8 @@ function ipv4_is_valid() { function ipv4_prefix_is_valid() { local prefix=${1} - assert isset prefix + + isset prefix || return ${EXIT_FALSE} [ ${prefix} -le 0 ] && return ${EXIT_FALSE} [ ${prefix} -gt 32 ] && return ${EXIT_FALSE} @@ -110,6 +111,22 @@ function ipv4_get_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 @@ -145,6 +162,12 @@ function ipv4_prefix2netmask() { } 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}) @@ -158,10 +181,16 @@ function ipv4_get_network() { local addr=$(ip_split_prefix ${net}) addr=$(ipv4_encode ${addr}) - ipv4_decode $(( ${addr} & ${mask} )) + 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}) @@ -181,7 +210,7 @@ function ipv4_get_broadcast() { local addr=$(ip_split_prefix ${net}) addr=$(ipv4_encode ${addr}) - ipv4_decode $(( $(( ${addr} & ${netmask} )) | ${broadcast} )) + print "%d" $(( $(( ${addr} & ${netmask} )) | ${broadcast} )) } function ipv4_encode() { @@ -210,6 +239,33 @@ function ipv4_decode() { 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} @@ -287,3 +343,22 @@ function _ipv4_range_explicit() { 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} +} diff --git a/functions.ipv6 b/functions.ipv6 index d1a43e4d..38a74170 100644 --- a/functions.ipv6 +++ b/functions.ipv6 @@ -162,178 +162,69 @@ function ipv6_prefix_is_valid() { function ipv6_implode() { local address=${1} - assert isset address - if ! ipv6_is_valid ${address}; then - error "IPv6 address is invalid: ${address}" - return ${EXIT_ERROR} - fi - - # Save prefix - local prefix=$(ip_get_prefix ${address}) - address=$(ip_split_prefix ${address}) - - # Make proper address in exploded format - address=$(ipv6_explode ${address}) - - local block - local char - local i - - local address_new - local block_new - - for block in ${address//:/\ }; do - block_new= - for i in $(seq 0 ${#block}); do - char="${block:${i}:1}" - - [ -z "${char}" ] && continue - - if [ -z "${block_new}" ] && [ "${char}" = "0" ]; then - continue - fi - - block_new="${block_new}${char}" - done - - [ -z "${block_new}" ] && block_new="0" - - address_new="${address_new}:${block_new}" - done - - # Cut first colon (:) - address="${address_new:1:${#address_new}}" - - local match - local matches=() - local pattern - local pos_start - local pos_next - for pos_start in $(seq 0 ${#address}); do - matches["${pos_start}"]=0 - - for pos_next in $(seq ${pos_start} 2 ${#address}); do - case "${pos_start}" in - 0) - match="${address:${pos_next}:2}" - pattern="0:" - ;; - *) - match="${address:${pos_next}:2}" - pattern=":0" - ;; - esac - - [ -z "${match}" ] && continue - - if [ "${match}" = "${pattern}" ]; then - matches[${pos_start}]=$(( matches[${pos_start}] + 1)) - else - break - fi - done - done - - local pos_best - local pos_best_val=0 - for i in $(seq 0 ${#matches[@]}); do - [ -z "${matches[${i}]}" ] && continue - - if [ ${matches[${i}]} -gt ${pos_best_val} ]; then - pos_best=${i} - pos_best_val=${matches[${i}]} - fi - done - - if [ -n "${pos_best}" ]; then - address_new="${address:0:${pos_best}}::" - - local pos_end=$(( ${pos_best_val} * 2 + ${pos_best} + 1)) - - if [ "${pos_best}" = "0" ]; then - pos_end=$(( ${pos_end} - 1 )) - fi + local ADDRESS6_IMPL + eval $(ipcalc -6 -i ${address} 2>/dev/null) + assert isset ADDRESS6_IMPL - address="${address_new}${address:${pos_end}:${#address}}" - fi - - # If a prefix was provided we append it in the end - [ -n "${prefix}" ] && address="${address}/${prefix}" - - assert ipv6_is_valid ${address} - - echo "${address}" + print "${ADDRESS6_IMPL}" } function ipv6_explode() { local address=${1} - assert isset address - local prefix=$(ip_get_prefix ${address}) - address=$(ip_split_prefix ${address}) - + # Nothing to do if the length of the address is 39. if [ ${#address} -eq 39 ]; then - echo "${address}$([ -n "${prefix}" ] && echo "/${prefix}")" - return ${EXIT_OK} + print "${address}" + return ${EXIT_OK} fi - address=${address//::/:X:} + local ADDRESS6_EXPL + eval $(ipcalc -6 -e ${address} 2>/dev/null) + assert isset ADDRESS6_EXPL - local block - local block_count=0 - local block_id - local block_max=8 - local blocks=() - - for block in ${address//:/\ }; do - blocks[${block_count}]=${block} - - block_count=$(( ${block_count} + 1 )) - done - - if [ ${#blocks[@]} -lt ${block_max} ]; then - for block_id in $(seq ${#blocks[@]} -1 0); do - block=${blocks[${block_id}]} + print "${ADDRESS6_EXPL}" +} - [ -z "${block}" ] && continue +function ipv6_addr_eq() { + local addr1=${1} + assert isset addr1 - if [ "${block}" = "X" ]; then - blocks[${block_id}]="0000" - break - fi + local addr2=${2} + assert isset addr2 - blocks[$(( ${block_max} - ${block_count} + ${block_id} ))]=${block} - blocks[${block_id}]="0000" - done - fi + local addr + for addr in addr1 addr2; do + printf -v ${addr} "%s" $(ipv6_explode ${!addr}) + done - for block_id in $(seq 0 ${#blocks[@]}); do - block=${blocks[${block_id}]} + [[ "${addr1}" = "${addr2}" ]] \ + && return ${EXIT_TRUE} || return ${EXIT_FALSE} +} - [ -z "${block}" ] && block="0000" +function ipv6_addr_gt() { + local addr1=${1} + assert isset addr1 - while [ "${#block}" -lt 4 ]; do - block="0${block}" - done + local addr2=${2} + assert isset addr2 - blocks[${block_id}]=${block} + local addr + for addr in addr1 addr2; do + printf -v ${addr} "%s" $(ipv6_explode ${!addr}) done - address= - for block in ${blocks[@]}; do - address="${address}:${block}" - done - address=${address:1:39} + local i addr1_oct addr2_oct + for i in 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30; do + addr1_oct="0x${addr1:${i}:2}" + addr2_oct="0x${addr2:${i}:2}" - # If a prefix was provided we append it in the end again - [ -n "${prefix}" ] && address="${address}/${prefix}" - - assert ipv6_is_valid ${address} + [[ ${addr1_oct} -gt ${addr2_oct} ]] && return ${EXIT_TRUE} + done - echo "${address}" + return ${EXIT_FALSE} } function ipv6_hash() { @@ -346,3 +237,18 @@ function ipv6_hash() { echo "${address//:/}" } + +function ipv6_get_network() { + local addr=${1} + assert isset addr + + # Check if a prefix (e.g. /64) is provided. + local prefix=$(ip_get_prefix ${addr}) + assert ipv6_prefix_is_valid ${prefix} + + local PREFIX6 + eval $(ipcalc --ipv6 -p ${addr}) + assert isset PREFIX6 + + print "${PREFIX6}/${prefix}" +}