diff --git a/Shorewall/Perl/prog.header b/Shorewall/Perl/prog.header index 1a611614b..6d1e819c8 100644 --- a/Shorewall/Perl/prog.header +++ b/Shorewall/Perl/prog.header @@ -15,7 +15,7 @@ # Commands are: # # start Starts the firewall -# refresh Refresh the firewall +# refresh Refresh the firewall # restart Restarts the firewall # reload Reload the firewall # clear Removes all firewall rules @@ -24,379 +24,3 @@ # version Displays the version of Shorewall that # generated this program # -################################################################################ -# Functions imported from /usr/share/shorewall/prog.header -################################################################################ -# -# Find the value 'weight' in the passed arguments then echo the next value -# - -find_weight() { - while [ $# -gt 1 ]; do - [ "x$1" = xweight ] && echo $2 && return - shift - done -} - -# -# Find the interfaces that have a route to the passed address - the default -# route is not used. -# - -find_rt_interface() { - $IP -4 route list | while read addr rest; do - case $addr in - */*) - in_network ${1%/*} $addr && echo $(find_device $rest) - ;; - default) - ;; - *) - if [ "$addr" = "$1" -o "$addr/32" = "$1" ]; then - echo $(find_device $rest) - fi - ;; - esac - done -} - -# -# Echo the name of the interface(s) that will be used to send to the -# passed address -# - -find_interface_by_address() { - local dev - dev="$(find_rt_interface $1)" - local first - local rest - - [ -z "$dev" ] && dev=$(find_default_interface) - - [ -n "$dev" ] && echo $dev -} - -# -# echo the list of networks routed out of a given interface -# -get_routed_networks() # $1 = interface name, $2-n = Fatal error message -{ - local address - local rest - - $IP -4 route show dev $1 2> /dev/null | - while read address rest; do - case "$address" in - default) - if [ $# -gt 1 ]; then - shift - fatal_error "$@" - else - echo "WARNING: default route ignored on interface $1" >&2 - fi - ;; - multicast|broadcast|prohibit|nat|throw|nexthop) - ;; - *) - [ "$address" = "${address%/*}" ] && address="${address}/32" - echo $address - ;; - esac - done -} - -# -# Get the broadcast addresses associated with an interface -# -get_interface_bcasts() # $1 = interface -{ - local addresses - addresses= - - $IP -f inet addr show dev $1 2> /dev/null | grep 'inet.*brd' | sed 's/inet.*brd //; s/scope.*//;' | sort -u -} - -# -# Delete IP address -# -del_ip_addr() # $1 = address, $2 = interface -{ - [ $(find_first_interface_address_if_any $2) = $1 ] || qtnoin $IP addr del $1 dev $2 -} - -# Add IP Aliases -# -add_ip_aliases() # $* = List of addresses -{ - local local - local addresses - local external - local interface - local inet - local cidr - local rest - local val - local arping - arping=$(mywhich arping) - - address_details() - { - # - # Folks feel uneasy if they don't see all of the same - # decoration on these IP addresses that they see when their - # distro's net config tool adds them. In an attempt to reduce - # the anxiety level, we have the following code which sets - # the VLSM and BRD from an existing address in the same networks - # - # Get all of the lines that contain inet addresses with broadcast - # - $IP -f inet addr show $interface 2> /dev/null | grep 'inet.*brd' | while read inet cidr rest ; do - case $cidr in - */*) - if in_network $external $cidr; then - echo "/${cidr#*/} brd $(broadcastaddress $cidr)" - break - fi - ;; - esac - done - } - - do_one() - { - val=$(address_details) - - $IP addr add ${external}${val} dev $interface $label - [ -n "$arping" ] && qt $arping -U -c 2 -I $interface $external - echo "$external $interface" >> $VARDIR/nat - [ -n "$label" ] && label="with $label" - progress_message " IP Address $external added to interface $interface $label" - } - - progress_message "Adding IP Addresses..." - - while [ $# -gt 0 ]; do - external=$1 - interface=$2 - label= - - if [ "$interface" != "${interface%:*}" ]; then - label="${interface#*:}" - interface="${interface%:*}" - label="label $interface:$label" - fi - - shift 2 - - list_search $external $(find_interface_addresses $interface) || do_one - done -} - -# -# Detect the gateway through a PPP or DHCP-configured interface -# -detect_dynamic_gateway() { # $1 = interface - local interface - interface=$1 - local GATEWAYS - GATEWAYS= - local gateway - - gateway=$(run_findgw_exit $1); - - if [ -z "$gateway" ]; then - gateway=$( find_peer $($IP addr list $interface ) ) - fi - - if [ -z "$gateway" -a -f /var/lib/dhcpcd/dhcpcd-${1}.info ]; then - eval $(grep ^GATEWAYS= /var/lib/dhcpcd/dhcpcd-${1}.info 2> /dev/null) - [ -n "$GATEWAYS" ] && GATEWAYS=${GATEWAYS%,*} && gateway=$GATEWAYS - fi - - if [ -z "$gateway" -a -f /var/lib/dhcp/dhclient-${1}.lease ]; then - gateway=$(grep 'option routers' /var/lib/dhcp/dhclient-${1}.lease | tail -n 1 | while read j1 j2 gateway; do echo $gateway ; return 0; done) - fi - - [ -n "$gateway" ] && echo $gateway -} - -# -# Detect the gateway through an interface -# -detect_gateway() # $1 = interface -{ - local interface - interface=$1 - local gateway - # - # First assume that this is some sort of dynamic interface - # - gateway=$( detect_dynamic_gateway $interface ) - # - # Maybe there's a default route through this gateway already - # - [ -n "$gateway" ] || gateway=$(find_gateway $($IP -4 route list dev $interface | grep ^default)) - # - # Last hope -- is there a load-balancing route through the interface? - # - [ -n "$gateway" ] || gateway=$(find_nexthop $interface) - # - # Be sure we found one - # - [ -n "$gateway" ] && echo $gateway -} - -# -# Disable IPV6 -# -disable_ipv6() { - local foo - foo="$($IP -f inet6 addr list 2> /dev/null)" - - if [ -n "$foo" ]; then - if [ -x "$IP6TABLES" ]; then - $IP6TABLES -P FORWARD DROP - $IP6TABLES -P INPUT DROP - $IP6TABLES -P OUTPUT DROP - $IP6TABLES -F - $IP6TABLES -X - $IP6TABLES -A OUTPUT -o lo -j ACCEPT - $IP6TABLES -A INPUT -i lo -j ACCEPT - else - error_message "WARNING: DISABLE_IPV6=Yes in shorewall.conf but this system does not appear to have ip6tables" - fi - fi -} - -# -# Add an additional gateway to the default route -# -add_gateway() # $1 = Delta $2 = Table Number -{ - local route - local weight - local delta - local dev - - route=`$IP -4 -o route ls table $2 | grep ^default | sed 's/default //; s/[\]//g'` - - if [ -z "$route" ]; then - run_ip route add default scope global table $2 $1 - else - delta=$1 - - if ! echo $route | fgrep -q ' nexthop '; then - route=`echo $route | sed 's/via/nexthop via/'` - dev=$(find_device $route) - if [ -f ${VARDIR}/${dev}_weight ]; then - weight=`cat ${VARDIR}/${dev}_weight` - route="$route weight $weight" - fi - fi - - run_ip route replace default scope global table $2 $route $delta - fi -} - -# -# Remove a gateway from the default route -# -delete_gateway() # $! = Description of the Gateway $2 = table number $3 = device -{ - local route - local gateway - local dev - - route=`$IP -4 -o route ls table $2 | grep ^default | sed 's/[\]//g'` - gateway=$1 - - if [ -n "$route" ]; then - if echo $route | fgrep -q ' nexthop '; then - gateway="nexthop $gateway" - eval route=\`echo $route \| sed \'s/$gateway/ /\'\` - run_ip route replace table $2 $route - else - dev=$(find_device $route) - [ "$dev" = "$3" ] && run_ip route delete default table $2 - fi - fi -} - -# -# Determine the MAC address of the passed IP through the passed interface -# -find_mac() # $1 = IP address, $2 = interface -{ - if interface_is_usable $2 ; then - qt ping -nc 1 -t 2 -I $2 $1 - - local result - result=$($IP neigh list | awk "/^$1 / {print \$5}") - - case $result in - \<*\>) - ;; - *) - [ -n "$result" ] && echo $result - ;; - esac - fi -} - -# -# Clear Proxy Arp -# -delete_proxyarp() { - if [ -f ${VARDIR}/proxyarp ]; then - while read address interface external haveroute; do - qtnoin $IP -4 neigh del proxy $address dev $external - [ -z "${haveroute}${g_noroutes}" ] && qtnoin $IP -4 route del $address/32 dev $interface - f=/proc/sys/net/ipv4/conf/$interface/proxy_arp - [ -f $f ] && echo 0 > $f - done < ${VARDIR}/proxyarp - - rm -f ${VARDIR}/proxyarp - fi -} - -# -# Remove all Shorewall-added rules -# -clear_firewall() { - stop_firewall - - setpolicy INPUT ACCEPT - setpolicy FORWARD ACCEPT - setpolicy OUTPUT ACCEPT - - run_iptables -F - qt $IPTABLES -t raw -F - - echo 1 > /proc/sys/net/ipv4/ip_forward - - if [ -n "$DISABLE_IPV6" ]; then - if [ -x $IP6TABLES ]; then - $IP6TABLES -P INPUT ACCEPT 2> /dev/null - $IP6TABLES -P OUTPUT ACCEPT 2> /dev/null - $IP6TABLES -P FORWARD ACCEPT 2> /dev/null - fi - fi - - run_clear_exit - - set_state "Cleared" - - logger -p kern.info "$g_product Cleared" -} - -# -# Get a list of all configured broadcast addresses on the system -# -get_all_bcasts() -{ - $IP -f inet addr show 2> /dev/null | grep 'inet.*brd' | grep -v '/32 ' | sed 's/inet.*brd //; s/scope.*//;' | sort -u -} - -################################################################################ -# End of functions in /usr/share/shorewall/prog.header -################################################################################ diff --git a/Shorewall/Perl/prog.header6 b/Shorewall/Perl/prog.header6 index 027d677c5..3dc9a2d32 100644 --- a/Shorewall/Perl/prog.header6 +++ b/Shorewall/Perl/prog.header6 @@ -1,6 +1,6 @@ # This program is under GPL [http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt] # -# (c) 1999-2011- Tom Eastep (teastep@shorewall.net) +# (c) 1999-2012 - Tom Eastep (teastep@shorewall.net) # # Options are: # @@ -24,288 +24,3 @@ # version Displays the version of Shorewall that # generated this program # -################################################################################ -# Functions imported from /usr/share/shorewall/prog.header6 -################################################################################ -# -# Get all interface addresses with VLSMs -# - -find_interface_full_addresses() # $1 = interface -{ - $IP -f inet6 addr show $1 2> /dev/null | grep 'inet6 ' | sed 's/\s*inet6 //;s/ scope.*//;s/ peer.*//' -} - -# -# Normalize an IPv6 Address by compressing out consecutive zero elements -# -normalize_address() # $1 = valid IPv6 Address -{ - local address - address=$1 - local j - - while true; do - case $address in - ::*) - address=0$address - ;; - *::*) - list_count $(split $address) - - j=$? - - if [ $j -eq 7 ]; then - address=${address%::*}:0:${address#*::} - elif [ $j -eq 8 ]; then - $address=${address%::*}:${address#*::} - break 2 - else - address=${address%::*}:0::${address#*::} - fi - ;; - *) - echo $address - break 2 - ;; - esac - done -} - -# -# Reads correctly-formed and fully-qualified host and subnet addresses from STDIN. For each -# that defines a /120 or larger network, it sends to STDOUT: -# -# The corresponding subnet-router anycast address (all host address bits are zero) -# The corresponding anycast addresses defined by RFC 2526 (the last 128 addresses in the subnet) -# -convert_to_anycast() { - local address - local badress - local vlsm - local host - local o - local m - m= - local z - z=65535 - local l - - while read address; do - case $address in - 2*|3*) - vlsm=${address#*/} - vlsm=${vlsm:=128} - - if [ $vlsm -le 120 ]; then - # - # Defines a viable subnet -- first get the subnet-router anycast address - # - host=$((128 - $vlsm)) - - address=$(normalize_address ${address%/*}) - - while [ $host -ge 16 ]; do - address=${address%:*} - host=$(($host - 16)) - done - - if [ $host -gt 0 ]; then - # - # VLSM is not a multiple of 16 - # - host=$((16 - $host)) - o=$((0x${address##*:})) - m=0 - while [ $host -gt 0 ]; do - m=$((($m >> 1) | 0x8000)) - z=$(($z >> 1)) - host=$(($host - 1)) - done - - o=$(($o & $m)) - - badress=${address%:*} - - address=$badress:$(printf %04x $o) - - z=$(($o | $z)) - - if [ $vlsm -gt 112 ]; then - z=$(($z & 0xff80)) - fi - - badress=$badress:$(printf %04x $z) - else - badress=$address - fi - # - # Note: at this point $address and $badress are the same except possibly for - # the contents of the last half-word - # - list_count $(split $address) - - l=$? - # - # Now generate the anycast addresses defined by RFC 2526 - # - if [ $l -lt 8 ]; then - # - # The subnet-router address - # - echo $address:: - - while [ $l -lt 8 ]; do - badress=$badress:ffff - l=$(($l + 1 )) - done - else - # - # The subnet-router address - # - echo $address - fi - # - # And the RFC 2526 addresses - # - echo $badress/121 - fi - ;; - esac - done -} - -# -# Generate a list of anycast addresses for a given interface -# - -get_interface_acasts() # $1 = interface -{ - local addresses - addresses= - - find_interface_full_addresses $1 | convert_to_anycast | sort -u -} - -# -# Get a list of all configured anycast addresses on the system -# -get_all_acasts() -{ - find_interface_full_addresses | convert_to_anycast | sort -u -} - -# -# Detect the gateway through an interface -# -detect_gateway() # $1 = interface -{ - local interface - interface=$1 - # - # First assume that this is some sort of point-to-point interface - # - gateway=$( find_peer $($IP -6 addr list $interface ) ) - # - # Maybe there's a default route through this gateway already - # - [ -n "$gateway" ] || gateway=$(find_gateway $($IP -6 route list dev $interface | grep '^default')) - # - # Last hope -- is there a load-balancing route through the interface? - # - [ -n "$gateway" ] || gateway=$(find_nexthop $interface) - # - # Be sure we found one - # - [ -n "$gateway" ] && echo $gateway -} - -# -# Add an additional gateway to the default route -# -add_gateway() # $1 = Delta $2 = Table Number -{ - local route - local weight - local delta - local dev - - run_ip route add default scope global table $2 $1 -} - -# -# Remove a gateway from the default route -# -delete_gateway() # $! = Description of the Gateway $2 = table number $3 = device -{ - local route - local gateway - local dev - - route=`$IP -6 -o route ls table $2 | grep ^default | sed 's/[\]//g'` - gateway=$1 - - dev=$(find_device $route) - [ "$dev" = "$3" ] && run_ip route delete default table $2 -} - -# -# Determine how to do "echo -e" -# - -find_echo() { - local result - - result=$(echo "a\tb") - [ ${#result} -eq 3 ] && { echo echo; return; } - - result=$(echo -e "a\tb") - [ ${#result} -eq 3 ] && { echo "echo -e"; return; } - - result=$(which echo) - [ -n "$result" ] && { echo "$result -e"; return; } - - echo echo -} - -# -# Clear Proxy NDP -# -delete_proxyndp() { - if [ -f ${VARDIR}/proxyndp ]; then - while read address interface external haveroute; do - qt $IP -6 neigh del proxy $address dev $external - [ -z "${haveroute}${g_noroutes}" ] && qt $IP -6 route del $address/128 dev $interface - f=/proc/sys/net/ipv6/conf/$interface/proxy_ndp - [ -f $f ] && echo 0 > $f - done < ${VARDIR}/proxyndp - - rm -f ${VARDIR}/proxyndp - fi -} - -# -# Remove all Shorewall-added rules -# -clear_firewall() { - stop_firewall - - setpolicy INPUT ACCEPT - setpolicy FORWARD ACCEPT - setpolicy OUTPUT ACCEPT - - run_iptables -F - qt $IP6TABLES -t raw -F - - echo 1 > /proc/sys/net/ipv6/conf/all/forwarding - - run_clear_exit - - set_state "Cleared" - - logger -p kern.info "$g_product Cleared" -} - -################################################################################ -# End of functions imported from /usr/share/shorewall/prog.header6 -################################################################################ diff --git a/Shorewall/lib.core b/Shorewall/lib.core index 6a159388a..aefb37003 100644 --- a/Shorewall/lib.core +++ b/Shorewall/lib.core @@ -25,6 +25,659 @@ # are found in prog.header and prog.header6). # ######################################################################################### + +?IF $__IPV4 +# +# Find the value 'weight' in the passed arguments then echo the next value +# + +find_weight() { + while [ $# -gt 1 ]; do + [ "x$1" = xweight ] && echo $2 && return + shift + done +} + +# +# Find the interfaces that have a route to the passed address - the default +# route is not used. +# + +find_rt_interface() { + $IP -4 route list | while read addr rest; do + case $addr in + */*) + in_network ${1%/*} $addr && echo $(find_device $rest) + ;; + default) + ;; + *) + if [ "$addr" = "$1" -o "$addr/32" = "$1" ]; then + echo $(find_device $rest) + fi + ;; + esac + done +} + +# +# Echo the name of the interface(s) that will be used to send to the +# passed address +# + +find_interface_by_address() { + local dev + dev="$(find_rt_interface $1)" + local first + local rest + + [ -z "$dev" ] && dev=$(find_default_interface) + + [ -n "$dev" ] && echo $dev +} + +# +# echo the list of networks routed out of a given interface +# +get_routed_networks() # $1 = interface name, $2-n = Fatal error message +{ + local address + local rest + + $IP -4 route show dev $1 2> /dev/null | + while read address rest; do + case "$address" in + default) + if [ $# -gt 1 ]; then + shift + fatal_error "$@" + else + echo "WARNING: default route ignored on interface $1" >&2 + fi + ;; + multicast|broadcast|prohibit|nat|throw|nexthop) + ;; + *) + [ "$address" = "${address%/*}" ] && address="${address}/32" + echo $address + ;; + esac + done +} + +# +# Get the broadcast addresses associated with an interface +# +get_interface_bcasts() # $1 = interface +{ + local addresses + addresses= + + $IP -f inet addr show dev $1 2> /dev/null | grep 'inet.*brd' | sed 's/inet.*brd //; s/scope.*//;' | sort -u +} + +# +# Delete IP address +# +del_ip_addr() # $1 = address, $2 = interface +{ + [ $(find_first_interface_address_if_any $2) = $1 ] || qtnoin $IP addr del $1 dev $2 +} + +# Add IP Aliases +# +add_ip_aliases() # $* = List of addresses +{ + local local + local addresses + local external + local interface + local inet + local cidr + local rest + local val + local arping + arping=$(mywhich arping) + + address_details() + { + # + # Folks feel uneasy if they don't see all of the same + # decoration on these IP addresses that they see when their + # distro's net config tool adds them. In an attempt to reduce + # the anxiety level, we have the following code which sets + # the VLSM and BRD from an existing address in the same networks + # + # Get all of the lines that contain inet addresses with broadcast + # + $IP -f inet addr show $interface 2> /dev/null | grep 'inet.*brd' | while read inet cidr rest ; do + case $cidr in + */*) + if in_network $external $cidr; then + echo "/${cidr#*/} brd $(broadcastaddress $cidr)" + break + fi + ;; + esac + done + } + + do_one() + { + val=$(address_details) + + $IP addr add ${external}${val} dev $interface $label + [ -n "$arping" ] && qt $arping -U -c 2 -I $interface $external + echo "$external $interface" >> $VARDIR/nat + [ -n "$label" ] && label="with $label" + progress_message " IP Address $external added to interface $interface $label" + } + + progress_message "Adding IP Addresses..." + + while [ $# -gt 0 ]; do + external=$1 + interface=$2 + label= + + if [ "$interface" != "${interface%:*}" ]; then + label="${interface#*:}" + interface="${interface%:*}" + label="label $interface:$label" + fi + + shift 2 + + list_search $external $(find_interface_addresses $interface) || do_one + done +} + +# +# Detect the gateway through a PPP or DHCP-configured interface +# +detect_dynamic_gateway() { # $1 = interface + local interface + interface=$1 + local GATEWAYS + GATEWAYS= + local gateway + + gateway=$(run_findgw_exit $1); + + if [ -z "$gateway" ]; then + gateway=$( find_peer $($IP addr list $interface ) ) + fi + + if [ -z "$gateway" -a -f /var/lib/dhcpcd/dhcpcd-${1}.info ]; then + eval $(grep ^GATEWAYS= /var/lib/dhcpcd/dhcpcd-${1}.info 2> /dev/null) + [ -n "$GATEWAYS" ] && GATEWAYS=${GATEWAYS%,*} && gateway=$GATEWAYS + fi + + if [ -z "$gateway" -a -f /var/lib/dhcp/dhclient-${1}.lease ]; then + gateway=$(grep 'option routers' /var/lib/dhcp/dhclient-${1}.lease | tail -n 1 | while read j1 j2 gateway; do echo $gateway ; return 0; done) + fi + + [ -n "$gateway" ] && echo $gateway +} + +# +# Detect the gateway through an interface +# +detect_gateway() # $1 = interface +{ + local interface + interface=$1 + local gateway + # + # First assume that this is some sort of dynamic interface + # + gateway=$( detect_dynamic_gateway $interface ) + # + # Maybe there's a default route through this gateway already + # + [ -n "$gateway" ] || gateway=$(find_gateway $($IP -4 route list dev $interface | grep ^default)) + # + # Last hope -- is there a load-balancing route through the interface? + # + [ -n "$gateway" ] || gateway=$(find_nexthop $interface) + # + # Be sure we found one + # + [ -n "$gateway" ] && echo $gateway +} + +# +# Disable IPV6 +# +disable_ipv6() { + local foo + foo="$($IP -f inet6 addr list 2> /dev/null)" + + if [ -n "$foo" ]; then + if [ -x "$IP6TABLES" ]; then + $IP6TABLES -P FORWARD DROP + $IP6TABLES -P INPUT DROP + $IP6TABLES -P OUTPUT DROP + $IP6TABLES -F + $IP6TABLES -X + $IP6TABLES -A OUTPUT -o lo -j ACCEPT + $IP6TABLES -A INPUT -i lo -j ACCEPT + else + error_message "WARNING: DISABLE_IPV6=Yes in shorewall.conf but this system does not appear to have ip6tables" + fi + fi +} + +# +# Add an additional gateway to the default route +# +add_gateway() # $1 = Delta $2 = Table Number +{ + local route + local weight + local delta + local dev + + route=`$IP -4 -o route ls table $2 | grep ^default | sed 's/default //; s/[\]//g'` + + if [ -z "$route" ]; then + run_ip route add default scope global table $2 $1 + else + delta=$1 + + if ! echo $route | fgrep -q ' nexthop '; then + route=`echo $route | sed 's/via/nexthop via/'` + dev=$(find_device $route) + if [ -f ${VARDIR}/${dev}_weight ]; then + weight=`cat ${VARDIR}/${dev}_weight` + route="$route weight $weight" + fi + fi + + run_ip route replace default scope global table $2 $route $delta + fi +} + +# +# Remove a gateway from the default route +# +delete_gateway() # $! = Description of the Gateway $2 = table number $3 = device +{ + local route + local gateway + local dev + + route=`$IP -4 -o route ls table $2 | grep ^default | sed 's/[\]//g'` + gateway=$1 + + if [ -n "$route" ]; then + if echo $route | fgrep -q ' nexthop '; then + gateway="nexthop $gateway" + eval route=\`echo $route \| sed \'s/$gateway/ /\'\` + run_ip route replace table $2 $route + else + dev=$(find_device $route) + [ "$dev" = "$3" ] && run_ip route delete default table $2 + fi + fi +} + +# +# Determine the MAC address of the passed IP through the passed interface +# +find_mac() # $1 = IP address, $2 = interface +{ + if interface_is_usable $2 ; then + qt ping -nc 1 -t 2 -I $2 $1 + + local result + result=$($IP neigh list | awk "/^$1 / {print \$5}") + + case $result in + \<*\>) + ;; + *) + [ -n "$result" ] && echo $result + ;; + esac + fi +} + +# +# Clear Proxy Arp +# +delete_proxyarp() { + if [ -f ${VARDIR}/proxyarp ]; then + while read address interface external haveroute; do + qtnoin $IP -4 neigh del proxy $address dev $external + [ -z "${haveroute}${g_noroutes}" ] && qtnoin $IP -4 route del $address/32 dev $interface + f=/proc/sys/net/ipv4/conf/$interface/proxy_arp + [ -f $f ] && echo 0 > $f + done < ${VARDIR}/proxyarp + + rm -f ${VARDIR}/proxyarp + fi +} + +# +# Remove all Shorewall-added rules +# +clear_firewall() { + stop_firewall + + setpolicy INPUT ACCEPT + setpolicy FORWARD ACCEPT + setpolicy OUTPUT ACCEPT + + run_iptables -F + qt $IPTABLES -t raw -F + + echo 1 > /proc/sys/net/ipv4/ip_forward + + if [ -n "$DISABLE_IPV6" ]; then + if [ -x $IP6TABLES ]; then + $IP6TABLES -P INPUT ACCEPT 2> /dev/null + $IP6TABLES -P OUTPUT ACCEPT 2> /dev/null + $IP6TABLES -P FORWARD ACCEPT 2> /dev/null + fi + fi + + run_clear_exit + + set_state "Cleared" + + logger -p kern.info "$g_product Cleared" +} + +# +# Get a list of all configured broadcast addresses on the system +# +get_all_bcasts() +{ + $IP -f inet addr show 2> /dev/null | grep 'inet.*brd' | grep -v '/32 ' | sed 's/inet.*brd //; s/scope.*//;' | sort -u +} +?ELSE +# +# Get all interface addresses with VLSMs +# + +find_interface_full_addresses() # $1 = interface +{ + $IP -f inet6 addr show $1 2> /dev/null | grep 'inet6 ' | sed 's/\s*inet6 //;s/ scope.*//;s/ peer.*//' +} + +# +# Normalize an IPv6 Address by compressing out consecutive zero elements +# +normalize_address() # $1 = valid IPv6 Address +{ + local address + address=$1 + local j + + while true; do + case $address in + ::*) + address=0$address + ;; + *::*) + list_count $(split $address) + + j=$? + + if [ $j -eq 7 ]; then + address=${address%::*}:0:${address#*::} + elif [ $j -eq 8 ]; then + $address=${address%::*}:${address#*::} + break 2 + else + address=${address%::*}:0::${address#*::} + fi + ;; + *) + echo $address + break 2 + ;; + esac + done +} + +# +# Reads correctly-formed and fully-qualified host and subnet addresses from STDIN. For each +# that defines a /120 or larger network, it sends to STDOUT: +# +# The corresponding subnet-router anycast address (all host address bits are zero) +# The corresponding anycast addresses defined by RFC 2526 (the last 128 addresses in the subnet) +# +convert_to_anycast() { + local address + local badress + local vlsm + local host + local o + local m + m= + local z + z=65535 + local l + + while read address; do + case $address in + 2*|3*) + vlsm=${address#*/} + vlsm=${vlsm:=128} + + if [ $vlsm -le 120 ]; then + # + # Defines a viable subnet -- first get the subnet-router anycast address + # + host=$((128 - $vlsm)) + + address=$(normalize_address ${address%/*}) + + while [ $host -ge 16 ]; do + address=${address%:*} + host=$(($host - 16)) + done + + if [ $host -gt 0 ]; then + # + # VLSM is not a multiple of 16 + # + host=$((16 - $host)) + o=$((0x${address##*:})) + m=0 + while [ $host -gt 0 ]; do + m=$((($m >> 1) | 0x8000)) + z=$(($z >> 1)) + host=$(($host - 1)) + done + + o=$(($o & $m)) + + badress=${address%:*} + + address=$badress:$(printf %04x $o) + + z=$(($o | $z)) + + if [ $vlsm -gt 112 ]; then + z=$(($z & 0xff80)) + fi + + badress=$badress:$(printf %04x $z) + else + badress=$address + fi + # + # Note: at this point $address and $badress are the same except possibly for + # the contents of the last half-word + # + list_count $(split $address) + + l=$? + # + # Now generate the anycast addresses defined by RFC 2526 + # + if [ $l -lt 8 ]; then + # + # The subnet-router address + # + echo $address:: + + while [ $l -lt 8 ]; do + badress=$badress:ffff + l=$(($l + 1 )) + done + else + # + # The subnet-router address + # + echo $address + fi + # + # And the RFC 2526 addresses + # + echo $badress/121 + fi + ;; + esac + done +} + +# +# Generate a list of anycast addresses for a given interface +# + +get_interface_acasts() # $1 = interface +{ + local addresses + addresses= + + find_interface_full_addresses $1 | convert_to_anycast | sort -u +} + +# +# Get a list of all configured anycast addresses on the system +# +get_all_acasts() +{ + find_interface_full_addresses | convert_to_anycast | sort -u +} + +# +# Detect the gateway through an interface +# +detect_gateway() # $1 = interface +{ + local interface + interface=$1 + # + # First assume that this is some sort of point-to-point interface + # + gateway=$( find_peer $($IP -6 addr list $interface ) ) + # + # Maybe there's a default route through this gateway already + # + [ -n "$gateway" ] || gateway=$(find_gateway $($IP -6 route list dev $interface | grep '^default')) + # + # Last hope -- is there a load-balancing route through the interface? + # + [ -n "$gateway" ] || gateway=$(find_nexthop $interface) + # + # Be sure we found one + # + [ -n "$gateway" ] && echo $gateway +} + +# +# Add an additional gateway to the default route +# +add_gateway() # $1 = Delta $2 = Table Number +{ + local route + local weight + local delta + local dev + + run_ip route add default scope global table $2 $1 +} + +# +# Remove a gateway from the default route +# +delete_gateway() # $! = Description of the Gateway $2 = table number $3 = device +{ + local route + local gateway + local dev + + route=`$IP -6 -o route ls table $2 | grep ^default | sed 's/[\]//g'` + gateway=$1 + + dev=$(find_device $route) + [ "$dev" = "$3" ] && run_ip route delete default table $2 +} + +# +# Determine how to do "echo -e" +# + +find_echo() { + local result + + result=$(echo "a\tb") + [ ${#result} -eq 3 ] && { echo echo; return; } + + result=$(echo -e "a\tb") + [ ${#result} -eq 3 ] && { echo "echo -e"; return; } + + result=$(which echo) + [ -n "$result" ] && { echo "$result -e"; return; } + + echo echo +} + +# +# Clear Proxy NDP +# +delete_proxyndp() { + if [ -f ${VARDIR}/proxyndp ]; then + while read address interface external haveroute; do + qt $IP -6 neigh del proxy $address dev $external + [ -z "${haveroute}${g_noroutes}" ] && qt $IP -6 route del $address/128 dev $interface + f=/proc/sys/net/ipv6/conf/$interface/proxy_ndp + [ -f $f ] && echo 0 > $f + done < ${VARDIR}/proxyndp + + rm -f ${VARDIR}/proxyndp + fi +} + +# +# Remove all Shorewall-added rules +# +clear_firewall() { + stop_firewall + + setpolicy INPUT ACCEPT + setpolicy FORWARD ACCEPT + setpolicy OUTPUT ACCEPT + + run_iptables -F + qt $IP6TABLES -t raw -F + + echo 1 > /proc/sys/net/ipv6/conf/all/forwarding + + run_clear_exit + + set_state "Cleared" + + logger -p kern.info "$g_product Cleared" +} + +?ENDIF + # # Conditionally produce message #