#! /bin/sh ### ### TRIPE_SLIPIF dynamic allocation script for use with `userv-ipif' ### ### (c) 2012 Mark Wooding ### ###----- Licensing notice --------------------------------------------------- ### ### This file is part of Trivial IP Encryption (TrIPE). ### ### TrIPE is free software: you can redistribute it and/or modify it under ### the terms of the GNU General Public License as published by the Free ### Software Foundation; either version 3 of the License, or (at your ### option) any later version. ### ### TrIPE is distributed in the hope that it will be useful, but WITHOUT ### ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ### FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ### for more details. ### ### You should have received a copy of the GNU General Public License ### along with TrIPE. If not, see . ###-------------------------------------------------------------------------- ### Instructions. ### ### This script is an adaptor for attaching tripe's `slip' tunnel driver to ### `userv-ipif'. The latter is a service for GNU Userv which allows ### otherwise unprivileged users to implement network devices, subject to ### administrative limitations on which addresses can be configured and which ### prefixes routed through them. The software is available as part of the ### `userv-utils' package. ### ### To use this script, you'll need to set up a configuration file ### `$TRIPEDIR/ipif.tab'. This file may contain comments (begining `#') and ### blank lines, both of which are ignored, and entries of the form ### ### PEER REMOTE-EXT LOCAL-INT REMOTE-INT ROUTE,... ### ### The PEER names a peer, as given to tripe's ADD command. REMOTE-EXT is ### the external IP address of the peer, i.e., the one which tripe will send ### its packets to. LOCAL-INT and REMOTE-INT are the local and remote ### addresses to be associated with the point-to-point interface. Finally, ### the ROUTEs are a comma-separated list of PREFIX/LEN pairs declaring ### which prefixes should be routed over this interface. The *-INT and ### ROUTEs fields are passed on to the `userv-ipif' service. The REMOTE-EXT ### field is used (a) by the accompanying `ipif-peers' script to set up the ### peer association, and (b) to determine the correct MTU to set; it ### should have the form ADDRESS[:PORT], where the PORT defaults to 4070 if ### it's not given explicitly, and an IPv6 ADDRESS is enclosed in square ### brackets (because of the stupid syntax decision to use colons in IPv6 ### address literals). ### ### Having done all of that, and having configured userv-ipif correctly, ### you should set TRIPE_SLIPIF=.../tripe-ipif and everything should just ### work. If you drop the script `ipif-peers' into the $TRIPEDIR/peers ### directory, then the init script will run it and all of the configured ### peers with known remote addresses will be added on startup. set -e quis=${0##*/} : ${TRIPEDIR=@configdir@} : ${logfile=@logfile@} : ${TRIPE_IPIF_LOG=${logfile%/*}/tripe-ipif.log} ## Parse the command line. case $# in 1) ;; *) echo >&2 "Usage: $quis PEER"; exit 1 ;; esac case ${TRIPEDIR+t} in t) ;; *) echo >&2 "$quis: \`TRIPEDIR' unset"; exit 1 ;; esac peer=$1 ## Arrange for errors to go somewhere. exec 2>>"$TRIPE_IPIF_LOG" now=$(date +"%Y-%m-%d %H:%M:%S") echo >&2 "$now $quis[$$] running for peer \`$peer'" ## Find the record in the peer table. foundp=nil while read name remote_ext local_int remote_int routes; do case $name in "$peer") foundp=t; break ;; esac done <$TRIPEDIR/ipif.tab case $foundp in nil) echo >&2 "$quis[$$]: unknown peer \`$peer'"; exit 1 ;; esac ## Announce the interface name. We actually have no way to determine this, ## so lie and hope that nobody cares. echo "userv-$peer" ## Now we can interrogate the server without deadlocking it. algs=$(tripectl algs) overhead=nil while read line; do for i in $line; do case $i in bulk-overhead=*) overhead=${i#*=} ;; esac done done <&2 "$quis[$$]: failed to discover overhead"; exit 1 ;; esac ## Determine the remote address if none is specified; strip off a port number ## if there is one. case "$remote_ext" in -) addr=$(tripectl addr $peer) set -- $addr case $1 in INET | INET6) remote_af=$1 remote_ext=$2 ;; *) echo >&2 "$quis: unexpected address family \`$1'"; exit 1 ;; esac ;; \[*\]:*) remote_af=INET6 remote_ext=${remote_ext#\[} remote_ext=${remote_ext%\]:*} ;; *:*) remote_af=INET remote_ext=${remote_ext%:*} ;; esac ## Determine the MTU based on the path. pmtu=$(pathmtu $remote_ext) case $remote_af in INET) iphdrsz=20 ;; INET6) iphdrsz=40 ;; esac mtu=$(( $pmtu - $iphdrsz - 8 - $overhead - 1 )) ## Obtain the tunnel and run it. now=$(date +"%Y-%m-%d %H:%M:%S") info="invoking \`userv ipif' for \`$peer'; mtu = $mtu" info="$info; $local_int -> $remote_int${routes+ $routes}" echo >&2 "$now $quis[$$] $info" exec userv root ipif $local_int,$remote_int,$mtu,slip $routes ###----- That's all, folks --------------------------------------------------