From debf41d707488608213cdf87013610382534c6c4 Mon Sep 17 00:00:00 2001 From: teastep Date: Sun, 22 Jun 2003 16:58:33 +0000 Subject: [PATCH] Allow IP ranges with ADD_SNAT_ALIASES=Yes; Fix add_ip_aliases to match proper subnet to add to git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@605 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb --- Shorewall/changelog.txt | 8 +++ Shorewall/firewall | 99 ++++++++++++++++++++++++++++++-------- Shorewall/masq | 13 +++-- Shorewall/releasenotes.txt | 8 +++ 4 files changed, 104 insertions(+), 24 deletions(-) diff --git a/Shorewall/changelog.txt b/Shorewall/changelog.txt index c5714802c..5c424d2f8 100755 --- a/Shorewall/changelog.txt +++ b/Shorewall/changelog.txt @@ -3,3 +3,11 @@ Changes since 1.4.5 1) Worked around RH7.3 "service" anomaly. 2) Implemented 'newnotsyn' interface option. + +3) Document range in masq ADDRESS column and suppress ADD_SNAT_ALIASES + behavior in that case. + +4) Enable ADD_SNAT_ALIASES=Yes for SNAT ranges. + +5) Allow Shorewall to add aliases to other than the first subnet on an + interface. diff --git a/Shorewall/firewall b/Shorewall/firewall index 4a6dcee11..9c67be0ea 100755 --- a/Shorewall/firewall +++ b/Shorewall/firewall @@ -2826,7 +2826,70 @@ get_routed_subnets() # $1 = interface name fi done } +# +# Convert an IP address to an integer +# +decodeaddr() { + local x + local temp=0 + ifs=$IFS + IFS=. + + for x in $1; do + temp=$(( $temp * 256 + $x )) + done + + echo $temp + + IFS=$ifs +} +# +# convert an integer to an IP address +# +encodeaddr() { + addr=$1 + local x + local y=$(($addr % 256)) + + for (( x=3 ; $x ; x-- )); do + addr=$(($addr >> 8)) + y=$(($addr % 256)).$y + done + + echo $y +} +# +# Enumerate the members of an IP range +# +ip_range() { + first=`decodeaddr ${1%-*}` + last=`decodeaddr ${1#*-}` + + if [ $first -gt $last -o $(($last - $first)) -gt 256 ]; then + fatal_error "Invalid IP address range: $1" + fi + + while [ $first -le $last ]; do + echo `encodeaddr $first` + first=$(($first + 1)) + done +} +# +# Netmask from VLSM +# +ip_netmask() { + echo $(( $(( 0xffffffff << $((32 - $1)) )) & 0xffffffff )) +} +# +# Test for subnet membership +# +in_subnet() # $1 = IP address, $2 = CIDR network +{ + local netmask=`ip_netmask ${2#*/}` + + test $(( `decodeaddr $1` & $netmask)) -eq $(( `decodeaddr ${2%/*}` & $netmask )) +} # # Set up Source NAT (including masquerading) # @@ -2899,8 +2962,10 @@ setup_masq() esac if [ -n "$address" -a -n "$ADD_SNAT_ALIASES" ]; then - list_search $address $aliases_to_add || \ - aliases_to_add="$aliases_to_add $address $fullinterface" + for addr in `ip_range $address` ; do + list_search $addr $aliases_to_add || \ + aliases_to_add="$aliases_to_add $addr $fullinterface" + done fi destination=$destnet @@ -3133,9 +3198,7 @@ verify_os_version() { # add_ip_aliases() { - local external - local interface - local primary + local external interface inet cidr brd bcast rest do_one() { @@ -3148,19 +3211,18 @@ add_ip_aliases() # # Get all of the lines that contain inet addresses with broadcast # - val=`ip addr show $interface | grep 'inet.*brd '` 2> /dev/null + val= - if [ -n "$val" ] ; then - # - # Hack off the leading 'inet ' (actually cut off the - # "/" as well but add it back in). - # - val="/${val#*/}" - # - # Now get the VLSM, "brd" and the broadcast address - # - val=${val%% scope*} - fi + ip addr show $interface 2> /dev/null | grep 'inet.*brd ' | while read inet cidr brd bcast rest ; do + if in_subnet $external $cidr; then + if [ $external = ${cidr%/*} ]; then + return + fi + + val="/${cidr#*/} brd $bcast" + break + fi + done run_ip addr add ${external}${val} dev $interface $label echo "$external $interface" >> ${STATEDIR}/nat @@ -3181,9 +3243,8 @@ add_ip_aliases() label="label $interface:$label" fi - primary=`find_interface_address $interface` shift;shift - [ "x${primary}" = "x${external}" ] || do_one + do_one done } diff --git a/Shorewall/masq b/Shorewall/masq index 27826945c..c127c2ac8 100755 --- a/Shorewall/masq +++ b/Shorewall/masq @@ -42,12 +42,15 @@ # will automatically add this address to the # INTERFACE named in the first column. # -# WARNING: Do NOT specify ADD_SNAT_ALIASES=Yes if -# the address given in this column is the primary -# IP address for the interface in the INTERFACE -# column. +# You may also specify a range of up to 256 +# IP addresses if you want the SNAT address to +# be assigned from that range in a round-robin +# range by connection. The range is specified by +# -. # -# This column may not contain a DNS Name. +# Example: 206.124.146.177-206.124.146.180 +# +# This column may not contain DNS Names. # # Example 1: # diff --git a/Shorewall/releasenotes.txt b/Shorewall/releasenotes.txt index 29ff7bd46..eaf55d286 100755 --- a/Shorewall/releasenotes.txt +++ b/Shorewall/releasenotes.txt @@ -11,3 +11,11 @@ New Features: 1) A 'newnotsyn' interface option has been added. This option may be specified in /etc/shorewall/interfaces and overrides the setting NEWNOTSYN=No for packets arriving on the associated interface. + +2) The means for specifying a range of IP addresses in + /etc/shorewall/masq to use for SNAT is now + documented. ADD_SNAT_ALIASES=Yes is enabled for address ranges. + +3) Shorewall can now add IP addresses to subnets on an interface other + than the first one. +