diff -ur vpnc-0.5.3/vpnc-script.in vpnc-0.5.3.new/vpnc-script.in --- vpnc-0.5.3/vpnc-script.in 2008-11-19 23:55:51 +0300 +++ vpnc-0.5.3.new/vpnc-script.in 2010-01-17 01:16:12 +0300 @@ -50,8 +50,7 @@ DEFAULT_ROUTE_FILE=/var/run/vpnc/defaultroute RESOLV_CONF_BACKUP=/var/run/vpnc/resolv.conf-backup -FULL_SCRIPTNAME=@PREFIX@/sbin/vpnc -SCRIPTNAME=`basename $FULL_SCRIPTNAME` +SCRIPTNAME=`basename $0` # some systems, eg. Darwin & FreeBSD, prune /var/run on boot if [ ! -d "/var/run/vpnc" ]; then @@ -72,6 +71,13 @@ route_syntax_del="delete" route_syntax_netmask="-netmask" fi +if [ "$OS" = "SunOS" ]; then + route_syntax_interface="-interface" + route_syntax_plumb="plumb" +else + route_syntax_interface="" + route_syntax_plumb="" +fi if [ -x /sbin/resolvconf ]; then # Optional tool on Debian, Ubuntu, Gentoo MODIFYRESOLVCONF=modify_resolvconf_manager @@ -90,8 +96,7 @@ if [ -n "$INTERNAL_IP4_MTU" ]; then MTU=$INTERNAL_IP4_MTU elif [ -n "$IPROUTE" ]; then - DEV=$($IPROUTE route | grep ^default | sed 's/^.* dev \([[:alnum:]-]\+\).*$/\1/') - MTU=$(($($IPROUTE link show "$DEV" | grep mtu | sed 's/^.* mtu \([[:digit:]]\+\).*$/\1/') - 88)) + MTU=$(($($IPROUTE route get "$VPNGATEWAY" | sed -ne 's/^.*mtu \([[:digit:]]\+\).*$/\1/p') - 88)) else MTU=1412 fi @@ -102,13 +107,31 @@ if [ -n "$INTERNAL_IP4_NETMASK" ]; then set_network_route $INTERNAL_IP4_NETADDR $INTERNAL_IP4_NETMASK $INTERNAL_IP4_NETMASKLEN fi + + # If the netmask is provided, it contains the address _and_ netmask + if [ -n "$IPROUTE" ]; then + if [ -n "$INTERNAL_IP6_NETMASK" ]; then + $IPROUTE -6 addr add $INTERNAL_IP6_NETMASK dev $TUNDEV + elif [ -n "$INTERNAL_IP6_ADDRESS" ]; then + $IPROUTE -6 addr add $INTERNAL_IP6_ADDRESS/128 dev $TUNDEV + fi + else + if [ -n "$INTERNAL_IP6_ADDRESS" ]; then + ifconfig "$TUNDEV" inet6 $route_syntax_plumb $INTERNAL_IP6_ADDRESS/128 $ifconfig_syntax_ptp $INTERNAL_IP6_ADDRESS mtu $MTU up + fi + fi } destroy_tun_device() { case "$OS" in - NetBSD) # and probably others... + NetBSD|FreeBSD) # and probably others... ifconfig "$TUNDEV" destroy ;; + SunOS) + if [ -n "$INTERNAL_IP6_ADDRESS" ]; then + ifconfig "$TUNDEV" inet6 unplumb + fi + ;; esac } @@ -123,18 +146,18 @@ $IPROUTE route add `$IPROUTE route get "$VPNGATEWAY" | fix_ip_get_output` $IPROUTE route flush cache } - + del_vpngateway_route() { $IPROUTE route $route_syntax_del "$VPNGATEWAY" $IPROUTE route flush cache } - + set_default_route() { $IPROUTE route | grep '^default' | fix_ip_get_output > "$DEFAULT_ROUTE_FILE" $IPROUTE route replace default dev "$TUNDEV" $IPROUTE route flush cache } - + set_network_route() { NETWORK="$1" NETMASK="$2" @@ -142,7 +165,7 @@ $IPROUTE route replace "$NETWORK/$NETMASKLEN" dev "$TUNDEV" $IPROUTE route flush cache } - + reset_default_route() { if [ -s "$DEFAULT_ROUTE_FILE" ]; then $IPROUTE route replace `cat "$DEFAULT_ROUTE_FILE"` @@ -150,14 +173,39 @@ rm -f -- "$DEFAULT_ROUTE_FILE" fi } - + del_network_route() { NETWORK="$1" NETMASK="$2" NETMASKLEN="$3" - $IPROUTE route $route_syntax_del "$NETWORK/$NETMASKLEN" dev "$TUNDEV" + $IPROUTE route $route_syntax_del "$NETWORK/$NETMASKLEN" dev "$TUNDEV" + $IPROUTE route flush cache + } + + set_ipv6_default_route() { + # We don't save/restore IPv6 default route; just add a higher-priority one. + $IPROUTE -6 route add default dev "$TUNDEV" metric 1 + $IPROUTE -6 route flush cache + } + + set_ipv6_network_route() { + NETWORK="$1" + NETMASKLEN="$2" + $IPROUTE -6 route replace "$NETWORK/$NETMASKLEN" dev "$TUNDEV" $IPROUTE route flush cache } + + reset_ipv6_default_route() { + $IPROUTE -6 route del default dev "$TUNDEV" + $IPROUTE route flush cache + } + + del_ipv6_network_route() { + NETWORK="$1" + NETMASKLEN="$2" + $IPROUTE -6 route del "$NETWORK/$NETMASKLEN" dev "$TUNDEV" + $IPROUTE -6 route flush cache + } else # use route command get_default_gw() { # isn't -n supposed to give --numeric output? @@ -165,41 +213,42 @@ # Get rid of lines containing IPv6 addresses (':') netstat -r -n | awk '/:/ { next; } /^(default|0\.0\.0\.0)/ { print $2; }' } - + set_vpngateway_route() { route add -host "$VPNGATEWAY" $route_syntax_gw "`get_default_gw`" } del_vpngateway_route() { - route $route_syntax_del -host "$VPNGATEWAY" + vpngw_route=`netstat -r -n | awk '/:/ { next; } /^(default|0\.0\.0\.0)/ { print $2; }'` + route $route_syntax_del -host "$VPNGATEWAY" $route_syntax_gw "$vpngw_route" } - + set_default_route() { DEFAULTGW="`get_default_gw`" echo "$DEFAULTGW" > "$DEFAULT_ROUTE_FILE" - route $route_syntax_del default - route add default $route_syntax_gw "$INTERNAL_IP4_ADDRESS" + route $route_syntax_del default $route_syntax_gw "`get_default_gw`" + route add default $route_syntax_gw "$INTERNAL_IP4_ADDRESS" $route_syntax_interface } - + set_network_route() { NETWORK="$1" NETMASK="$2" NETMASKLEN="$3" del_network_route "$NETWORK" "$NETMASK" "$NETMASKLEN" - route add -net "$NETWORK" $route_syntax_netmask "$NETMASK" $route_syntax_gw "$INTERNAL_IP4_ADDRESS" + route add -net "$NETWORK" $route_syntax_netmask "$NETMASK" $route_syntax_gw "$INTERNAL_IP4_ADDRESS" $route_syntax_interface } - + reset_default_route() { if [ -s "$DEFAULT_ROUTE_FILE" ]; then - route $route_syntax_del default + route $route_syntax_del default $route_syntax_gw "`get_default_gw`" $route_syntax_interface route add default $route_syntax_gw `cat "$DEFAULT_ROUTE_FILE"` rm -f -- "$DEFAULT_ROUTE_FILE" fi } - + del_network_route() { case "$OS" in - Linux|NetBSD|Darwin) # and probably others... + Linux|NetBSD|Darwin|SunOS) # and probably others... # routes are deleted automatically on device shutdown return ;; @@ -209,6 +258,30 @@ NETMASKLEN="$3" route $route_syntax_del -net "$NETWORK" $route_syntax_netmask "$NETMASK" $route_syntax_gw "$INTERNAL_IP4_ADDRESS" } + + set_ipv6_default_route() { + route add -inet6 default "$INTERNAL_IP6_ADDRESS" $route_syntax_interface + } + + set_ipv6_network_route() { + NETWORK="$1" + NETMASK="$2" + route add -inet6 -net "$NETWORK/$NETMASK" "$INTERNAL_IP6_ADDRESS" $route_syntax_interface + : + } + + reset_ipv6_default_route() { + route $route_syntax_del -inet6 default "$INTERNAL_IP6_ADDRESS" + : + } + + del_ipv6_network_route() { + NETWORK="$1" + NETMASK="$2" + route $route_syntax_del -inet6 "$NETWORK/$NETMASK" "$INTERNAL_IP6_ADDRESS" + : + } + fi # =========== resolv.conf handling ==================================== @@ -255,7 +328,7 @@ $LINE" done exec 6<&- - + for i in $INTERNAL_IP4_DNS_TEMP ; do NEW_RESOLVCONF="$NEW_RESOLVCONF nameserver $i" @@ -351,6 +424,7 @@ modify_resolvconf_suse() { + FULL_SCRIPTNAME=`readlink -f $0` RESOLV_OPTS='' test -n "$INTERNAL_IP4_DNS" && RESOLV_OPTS="-n \"$INTERNAL_IP4_DNS\"" test -n "$CISCO_DEF_DOMAIN" && RESOLV_OPTS="$RESOLV_OPTS -d $CISCO_DEF_DOMAIN" @@ -360,6 +434,7 @@ # Restore resolv.conf to old contents on Suse restore_resolvconf_suse() { + FULL_SCRIPTNAME=`readlink -f $0` /sbin/modify_resolvconf restore -s vpnc -p $SCRIPTNAME -f $FULL_SCRIPTNAME -e $TUNDEV } @@ -444,7 +519,7 @@ echo "$CISCO_BANNER" | while read LINE ; do echo "|" "$LINE" ; done echo fi - + do_ifconfig set_vpngateway_route if [ -n "$CISCO_SPLIT_INC" ]; then @@ -461,12 +536,34 @@ i=`expr $i + 1` done for i in $INTERNAL_IP4_DNS ; do - set_network_route "$i" "255.255.255.255" "32" + if ! echo "$i" | grep : >/dev/null; then + set_network_route "$i" "255.255.255.255" "32" + fi done - else + elif [ -n "$INTERNAL_IP4_ADDRESS" ]; then set_default_route fi - + if [ -n "$CISCO_IPV6_SPLIT_INC" ]; then + i=0 + while [ $i -lt $CISCO_IPV6_SPLIT_INC ] ; do + eval NETWORK="\${CISCO_IPV6_SPLIT_INC_${i}_ADDR}" + eval NETMASKLEN="\${CISCO_IPV6_SPLIT_INC_${i}_MASKLEN}" + if [ $NETMASKLEN -lt 128 ]; then + set_ipv6_network_route "$NETWORK" "$NETMASKLEN" + else + set_ipv6_default_route + fi + i=`expr $i + 1` + done + for i in $INTERNAL_IP4_DNS ; do + if echo "$i" | grep : >/dev/null; then + set_ipv6_network_route "$i" "128" + fi + done + elif [ -n "$INTERNAL_IP6_NETMASK" -o -n "$INTERNAL_IP6_ADDRESS" ]; then + set_ipv6_default_route + fi + if [ -n "$INTERNAL_IP4_DNS" ]; then $MODIFYRESOLVCONF fi @@ -494,9 +591,27 @@ else reset_default_route fi - + if [ -n "$CISCO_IPV6_SPLIT_INC" ]; then + i=0 + while [ $i -lt $CISCO_IPV6_SPLIT_INC ] ; do + eval NETWORK="\${CISCO_IPV6_SPLIT_INC_${i}_ADDR}" + eval NETMASKLEN="\${CISCO_IPV6_SPLIT_INC_${i}_MASKLEN}" + if [ $NETMASKLEN -eq 0 ]; then + reset_ipv6_default_route + else + del_ipv6_network_route "$NETWORK" "$NETMASKLEN" + fi + i=`expr $i + 1` + done + for i in $INTERNAL_IP6_DNS ; do + del_ipv6_network_route "$i" "128" + done + else + reset_ipv6_default_route + fi + del_vpngateway_route - + if [ -n "$INTERNAL_IP4_DNS" ]; then $RESTORERESOLVCONF fi