#!/bin/bash

function usage() {
<<EoF cat
Script to:
 -- set up a 6to4 xunnel; and
 -- give it a public, globally valid, unique IPv6 address; and
 -- set up the anycast route to the nearest "relay" xunnel.

Usage:
   $0 [options]

Options include:
  -n            # No-op (don't actually change anything)
  -v		# Print verbose information about what we think we are doing.
                # Hint:  -v -n is harmless and possibly informative.
  -r		# Remove the existing 6to4 xunnel, if any, then exit.
  -W 1.2.3.4	# Specify the WAN IPv4 address to use.
		# Maybe (?) useful if you are offline and know the IP.
		# Default is to determine the address empirically.
  -h		# Print this message and exit.

Hint:  After setting up the xunnel, you may want to
  update-ns -6 -4

Terminology:  A xunnel is the endpoint of a tunnel.  A working 
tunnel needs two or more xunnels.  Typically each xunnel is on
a different host.  Beware that the "ip" command uses the word
"tunnel" to refer to a device that is actually just a xunnel.

EoF
}

# Load some functions that do most of the work:
bindir=$( dirname $0 )
if test -z "$have_ip_conf_utils" ; then
  . $bindir/ip-conf-utils
fi

hostlist=""
mode_i=""
mode_r=""

while test -n "$*" ; do
  opt=$1 ; shift
  case $opt in
    -help|-h)
      usage
      exit 0
      ;;
    -W) 
      arg=$1 ; shift
      WANip4=$arg
      ;;
    -n)
      mode_n=yes
      ;;
    -v)
      mode_v=yes
      ;;
    -r)
      mode_r=yes
      ;;
    *)
      1>&2 echo "Extraneous verbiage '$opt'"
      exit 1
  esac
done

# ascertain IP addresses 
< <(fancy_get_WAN_addr $WANip4)  MapFile WANip4 ip6addr  

if test -z "$WANip4" ; then
  1>&2 echo "Could not ascertain WAN IPv4 address."
  exit 1
fi

# The following snippet handles the case where we are behind
# some sort of NAT box.
# In that case, WANip4 is the NAT box's address.
# We need that, but we also need to ascertain LANip4, 
# which is the address of the relevant interface on _this_ box:
#
# Note that the NAT box(es) must be set to forward 
# IP-protocol-41 to us.
LANip4=$WANip4			## tentatively assume no NAT
rslt=$(ip route get to $LANip4)
set -- $rslt
if test ! "_$1" = "_local" ; then
  while test -n "$*" ; do
    foo=$1; shift
    if test "_$foo" = "_src" ; then
      LANip4=$1 ; shift
    fi
  done
fi

if test -n "$mode_v" ; then
  echo "WANip4:    $WANip4"
  echo "LANip4:    $LANip4"
  echo "ip6addr:   $ip6addr"
fi

if test -n "$mode_n" ; then
  exit 0
fi

cmd=ip		## change to 'echo' for testing

# First, get rid of old xunnel, if any:
$cmd tunnel del 6to4 2>/dev/null || true

if test -n "$mode_r" ; then 
  # Note that routes involving the old xunnel went away 
  # automagically when the old xunnel was destroyed.
  exit
fi

# Bring up the new xunnel:
$cmd  tunnel add 6to4 mode sit ttl 64 remote any local $LANip4
$cmd  link set dev 6to4 up
$cmd  addr add $ip6addr/16 dev 6to4

# Add the anycast route for finding a relay to the 6bone:
$cmd  -6 route add 2000::/3 via ::192.88.99.1 dev 6to4 metric 1026
