#!/bin/sh # # Copyright (c) 2003-2006 Hajimu UMEMOTO # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $Mahoroba: src/dtcpclient/dtcpclient.script,v 1.29 2006/01/10 17:38:56 ume Exp $ # # DON'T EDIT THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING. PUT YOUR # CONFIGURATION INTO /usr/local/etc/dtcpclient_script.conf, INSTEAD. # # Set gif interface name to be used for tunnel. # FreeBSD: If tunif is not set, gif will be created dynamically. # MacOSX: If tunif is not set, interface will be determined # automatically. When you set it explicitly, make sure having # specified gif interface beforehand. # Other: default is gif0 #tunif='gif0' # # Set to static route. (default: default) #static_routes='default' # # Set IPv6 address if you wish to add it to gif interface. (default: '') #tunif_addrs='' # # Set to "YES" if you don't want to destroy cloned interface. # (default: NO) # FreeBSD: If tunif is not defined, this will be treated as "NO". # MacOSX: This is ignored. #cloned_interface_keep="NO" # # Set definition of prefix delegation if you want to do prefix # delegation with network type tunnel. # The format is `interface/slaid/hostid/prefixlen'. # The default of `slaid' is `0'. # When `hostid' is ommitted, EUI-64 address is assumed. # The default of `prefixlen' is `64'. # If `@' is specified as interface, it is substituted with the tunnel # interface. #prefix_delegation='sis0/1' # # If you want to execute more commands at up/down, you can set # `up_command' and `down_command'. logger -t dtcpclient $* state=$1 server=$2 myaddr=$3 tuntype=$4 me=$5 her=$6 case ${tuntype} in host) me6=$7 her6=$8 ;; network) if [ -z "$8" ]; then prefixes=$7 else me6=$7 her6=$8 prefixes=$9 fi ;; esac OIFS="$IFS" IFS=";" set ${myaddr} myaddr=$1 me_port=$2 set ${her} her=$1 her_port=$2 IFS="$OIFS" if [ -n "${me_port}" ]; then udp_tunnel=1 fi if [ -r /usr/local/etc/dtcpclient_script.conf ]; then . /usr/local/etc/dtcpclient_script.conf fi nickname=`echo ${server} | sed -e 's/[\.:\-]/_/g' -e 's/^\([0-9]\)/_\1/'` for _var in tunif static_routes tunif_addrs cloned_interface_keep \ prefix_delegation up_command down_command; do eval _val=\$${nickname}_${_var} if [ -n "${_val}" ]; then eval ${_var}=\${_val} fi done static_routes=${static_routes:-'default'} cloned_interface_keep=${cloned_interface_keep:-'NO'} ifconfig () { # echo ifconfig $* # logger -t dtcpclient ifconfig $* /sbin/ifconfig $* } route () { # echo route $* # logger -t dtcpclient route $* /sbin/route $* } str_split() { OIFS="$IFS" IFS="$1" set $2 IFS="$OIFS" echo $* } construct_addr() { prefix=$1 slaid=$2 hostid=$3 addr=`expr "${prefix}" : '\(.*\)/\(.*\)'` OIFS="$IFS" IFS=":" set ${addr} IFS="$OIFS" slaid=$((`printf "%d" 0x${4:-0}` + `printf "%d" 0x${slaid}`)) echo $1':'$2':'$3':'`printf "%x" ${slaid}`':'${hostid} } getladdr() { ifconfig $1 2>/dev/null | while read proto addr rest; do [ ${proto} != 'inet6' ] && continue case ${addr} in fe80::*) echo ${addr} return ;; esac done } gethostid() { expr "`getladdr $1`" : 'fe80::\(.*\)%\(.*\)' } gif_inuse() { expect_me=$1; expect_her=$2 OIFS="$IFS" IFS= ifconfig -a 2>/dev/null | while read line; do t=`expr "${line}" : '\([a-zA-Z0-9]*\):.*'` if [ -n "${t}" ]; then iface="${t}" continue fi IFS="$OIFS" set ${line} IFS= tunnel=$1; proto=$2; me=$3; arrow=$4; her=$5 [ ${tunnel} = 'tunnel' ] || continue if [ ${me} = ${expect_me} -a ${her} = ${expect_her} ]; then echo ${iface} break fi done IFS="$OIFS" } gif_readytouse() { OIFS="$IFS" IFS= peer='NONE' (ifconfig -a 2>/dev/null; echo '000:') | while read line; do t=`expr "${line}" : '\([a-zA-Z0-9]*\):.*'` if [ -n "${t}" ]; then if [ -z "${peer}" ]; then ifname=`echo ${iface} | cut -c 1-3` if [ ${ifname} = 'gif' -o ${ifname} = '000' ] then echo "${iface}" break; fi fi iface="${t}" peer= continue fi IFS="$OIFS" set ${line} IFS= tunnel=$1; proto=$2; me=$3; arrow=$4; her=$5 [ ${tunnel} = 'tunnel' ] && peer="$me $her" done IFS="$OIFS" } lockfile=${lockfile:-'/var/run/dtcpclient.lock'} do_lock() { until mkdir ${lockfile} > /dev/null 2>&1; do sleep 1 done } do_unlock() { rmdir ${lockfile} } do_prefix_delegation() { is_up=$1 prefix=$2 if [ -n "${prefix_delegation}" ]; then plen=`expr "${prefix}" : '.*/\(.*\)'` if [ ${plen:-64} -lt 64 ]; then case "${is_up}" in up) route delete -inet6 ${prefix} > /dev/null 2>&1 route add -inet6 ${prefix} ::1 -reject ;; down) route delete -inet6 ${prefix} ;; esac fi for pd in `str_split ',' ${prefix_delegation}`; do OIFS="$IFS" IFS="/" set ${pd} IFS="$OIFS" lanif=$1 if [ X${lanif} = X'@' ]; then lanif=${tunif} fi slaid=${2:-0} hostid=$3 ifconfig ${lanif} up if [ $system = 'Darwin' ]; then [ -z "`getladdr ${lanif}`" ] && ip6 -u ${lanif} fi hostid=${hostid:-`gethostid ${lanif}`} hostid=${hostid:-': eui64'} prefixlen=${4:-64} addr=`construct_addr ${prefix} ${slaid} "${hostid}"` case "${is_up}" in up) alias="alias" ;; down) alias="-alias" ;; esac ifconfig ${lanif} inet6 ${addr} prefixlen ${prefixlen} ${alias} done fi } ng_mkpeer() { ngctl -f - 2> /dev/null < /dev/null 2>&1 bogus="" while true; do iface=`ng_iface_create_one` if [ -z "${iface}" ]; then exit 2 fi if [ "${iface}" = "${req_iface}" ]; then echo ${iface} break fi bogus="${bogus} ${iface}" done for iface in ${bogus}; do ngctl shutdown ${iface}: done } if [ -n "${udp_tunnel}" ]; then case ${tunif} in ng[0-9]*) ;; *) tunif='ng0' ;; esac fi system=`uname -s` if [ -z "${tunif}" ]; then if [ $system = 'FreeBSD' -o ${system} = 'Darwin' ]; then tunif='gif' else tunif='gif0' fi fi if [ ${system} = 'Darwin' ]; then cloned_interface_keep='YES' elif [ ${tunif} = 'gif' ]; then cloned_interface_keep='NO' fi case ${state} in up) if [ -n "${udp_tunnel}" ]; then _tunif=`ng_iface_create ${tunif}` [ -n "${_tunif}" ] && tunif=${_tunif} ngctl mkpeer ${tunif}: ksocket inet6 inet/dgram/udp ngctl msg ${tunif}:inet6 bind inet/${myaddr}:${me_port} ngctl msg ${tunif}:inet6 connect inet/${her}:${her_port} else if [ ${system} = 'Darwin' ]; then if [ ${tunif} = 'gif' ]; then do_lock locked='YES' tunif=`gif_readytouse` fi else _tunif=`ifconfig ${tunif} create 2> /dev/null` [ -n "${_tunif}" ] && tunif=${_tunif} fi ifconfig ${tunif} tunnel ${myaddr} ${her} fi if [ -n "${DTCP_MTU}" ]; then ifconfig ${tunif} mtu ${DTCP_MTU} fi ifconfig ${tunif} up if [ -z "${udp_tunnel}" -a ${system} = 'Darwin' ]; then [ -z "`getladdr ${tunif}`" ] && ip6 -u ${tunif} if [ -n "${locked}" ]; then do_unlock locked='' fi fi case ${tuntype} in host) ifconfig ${tunif} inet6 ${me6} ${her6} prefixlen 128 ;; network) if [ -n "${me6}" -a -n "${her6}" ]; then ifconfig ${tunif} inet6 ${me6} ${her6} prefixlen 128 fi for prefix in `str_split ',' ${prefixes}`; do do_prefix_delegation ${state} ${prefix} done ;; esac if [ -n "${tunif_addrs}" ]; then for tunif_addr in `str_split ',' ${tunif_addrs}`; do ifconfig ${tunif} inet6 ${tunif_addr} alias done fi if [ -n "${static_routes}" ]; then for static_route in `str_split ',' ${static_routes}`; do route delete -inet6 ${static_route} > /dev/null 2>&1 route add -inet6 ${static_route} ::1 -ifp ${tunif} done fi if [ -n "${up_command}" ]; then export state server myaddr tuntype me her me6 her6 prefixes eval ${up_command} fi ;; down) if [ -n "${down_command}" ]; then export state server myaddr tuntype me her me6 her6 prefixes eval ${down_command} fi if [ ${tunif} = 'gif' ]; then tunif=`gif_inuse ${myaddr} ${her}` fi if [ -n "${static_routes}" ]; then for static_route in `str_split ',' ${static_routes}`; do route delete -inet6 ${static_route} ::1 -ifp ${tunif} done fi if [ -n "${tunif_addrs}" ]; then for tunif_addr in `str_split ',' ${tunif_addrs}`; do ifconfig ${tunif} inet6 ${tunif_addr} -alias done fi case ${tuntype} in host) ifconfig ${tunif} inet6 ${me6} ${her6} prefixlen 128 -alias ;; network) if [ -n "${me6}" -a -n "${her6}" ]; then ifconfig ${tunif} inet6 ${me6} ${her6} prefixlen 128 \ -alias fi for prefix in `str_split ',' ${prefixes}`; do do_prefix_delegation ${state} ${prefix} done ;; esac if [ -n "${DTCP_MTU}" ]; then ifconfig ${tunif} mtu 1280 fi ifconfig ${tunif} down if [ -n "${udp_tunnel}" ]; then ngctl shutdown ${tunif}: else ifconfig ${tunif} deletetunnel case ${cloned_interface_keep} in [Yy][Ee][Ss]) ;; *) ifconfig ${tunif} destroy ;; esac fi ;; esac