chiark / gitweb /
contrib/: New directory for random occasionally-useful stuff.
[tripe] / contrib / tripe-ipif
CommitLineData
a4f886c3
MW
1#! /bin/sh
2###
3### TRIPE_SLIPIF dynamic allocation script for use with `userv-ipif'
4###
5### (c) 2012 Mark Wooding
6###
7
8###----- Licensing notice ---------------------------------------------------
9###
10### This file is part of Trivial IP Encryption (TrIPE).
11###
12### TrIPE is free software; you can redistribute it and/or modify
13### it under the terms of the GNU General Public License as published by
14### the Free Software Foundation; either version 2 of the License, or
15### (at your option) any later version.
16###
17### TrIPE is distributed in the hope that it will be useful,
18### but WITHOUT ANY WARRANTY; without even the implied warranty of
19### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20### GNU General Public License for more details.
21###
22### You should have received a copy of the GNU General Public License
23### along with TrIPE; if not, write to the Free Software Foundation,
24### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26###--------------------------------------------------------------------------
27### Instructions.
28###
29### This script is an adaptor for attaching tripe's `slip' tunnel driver to
30### `userv-ipif'. The latter is a service for GNU Userv which allows
31### otherwise unprivileged users to implement network devices, subject to
32### administrative limitations on which addresses can be configured and which
33### prefixes routed through them. The software is available as part of the
34### `userv-utils' package.
35###
36### To use this script, you'll need to set up a configuration file
37### `$TRIPEDIR/ipif.tab'. This file may contain comments (begining `#') and
38### blank lines, both of which are ignored, and entries of the form
39###
40### PEER REMOTE-EXT LOCAL-INT REMOTE-INT ROUTE,...
41###
42### The PEER names a peer, as given to tripe's ADD command. REMOTE-EXT is
43### the external IP address of the peer, i.e., the one which tripe will send
44### its packets to. LOCAL-INT and REMOTE-INT are the local and remote
45### addresses to be associated with the point-to-point interface. Finally,
46### the ROUTEs are a comma-separated list of PREFIX/LEN pairs declaring
47### which prefixes should be routed over this interface. The *-INT and
48### ROUTEs fields are passed on to the `userv-ipif' service. The REMOTE-EXT
49### field is used (a) by the accompanying `ipif-peers' script to set up the
50### peer association, and (b) to determine the correct MTU to set; it
51### should have the form ADDRESS[:PORT], where the PORT defaults to 4070 if
52### it's not given explicitly.
53###
54### Having done all of that, and having configured userv-ipif correctly,
55### you should set TRIPE_SLIPIF=.../tripe-ipif and everything should just
56### work. If you drop the script `ipif-peers' into the $TRIPEDIR/peers
57### directory, then the init script will run it and all of the configured
58### peers with known remote addresses will be added on startup.
59
60set -e
61quis=${0##*/}
62
63## Parse the command line.
64case $# in 1) ;; *) echo >&2 "Usage: $quis PEER"; exit 1 ;; esac
65case ${TRIPEDIR+t} in
66 t) ;;
67 *) echo >&2 "$quis: \`TRIPEDIR' unset"; exit 1 ;;
68esac
69peer=$1
70
71## Arrange for errors to go somewhere.
72case "${TRIPE_IPIF_LOG+t}" in t) exec 2>>"$TRIPE_IPIF_LOG" ;; esac
73now=$(date +"%Y-%m-%d %H:%M:%S")
74echo >&2 "$now $quis[$$] running for peer \`$peer'"
75
76## Find the record in the peer table.
77foundp=nil
78while read name remote_ext local_int remote_int routes; do
79 case $name in "$peer") foundp=t; break ;; esac
80done <$TRIPEDIR/ipif.tab
81case $foundp in
82 nil) echo >&2 "$quis[$$]: unknown peer \`$peer'"; exit 1 ;;
83esac
84
85## Announce the interface name. We actually have no way to determine this,
86## so lie and hope that nobody cares.
87echo "userv-$peer"
88
89## Now we can interrogate the server without deadlocking it.
90algs=$(tripectl algs) tagsz=nil blksz=nil
91while read line; do
92 for i in $line; do
93 case $i in
94 cipher-blksz=*) blksz=${i#*=} ;;
95 mac-tagsz=*) tagsz=${i#*=} ;;
96 esac
97 done
98done <<EOF
99$algs
100EOF
101case ,$tagsz,$blksz, in
102 *,nil,*) echo >&2 "$quis[$$]: failed to discover cipher suite"; exit 1 ;;
103esac
104
105## Determine the remote address if none is specified; strip off a port number
106## if there is one.
107case "$remote_ext" in
108 -)
109 addr=$(tripectl addr $peer)
110 set -- $addr
111 case $1 in
112 INET) remote_ext=$2 ;;
113 *) echo >&2 "$quis: unexpected address family \`$1'"; exit 1 ;;
114 esac
115 ;;
116 *:*)
117 remote_ext=${remote_ext%:*}
118 ;;
119esac
120
121## Determine the MTU based on the path.
122pmtu=$(pathmtu $remote_ext)
123mtu=$(( $pmtu - 33 - $tagsz - $blksz ))
124
125## Obtain the tunnel and run it.
126now=$(date +"%Y-%m-%d %H:%M:%S")
127info="invoking \`userv ipif' for \`$peer'; mtu = $mtu"
128info="$info; $local_int -> $remote_int${routes+ $routes}"
129echo >&2 "$now $quis[$$] $info"
130exec userv root ipif $local_int,$remote_int,$mtu,slip $routes
131
132###----- That's all, folks --------------------------------------------------