chiark / gitweb /
contrib: Do proper substitutions on contrib files.
[tripe] / contrib / tripe-ipif.in
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
60 set -e
61 quis=${0##*/}
62 : ${TRIPEDIR=@configdir@}
63 : ${logfile=@logfile@}
64 : ${TRIPE_IPIF_LOG=${logfile%/*}/tripe-ipif.log}
65
66 ## Parse the command line.
67 case $# in 1) ;; *) echo >&2 "Usage: $quis PEER"; exit 1 ;; esac
68 case ${TRIPEDIR+t} in
69   t) ;;
70   *) echo >&2 "$quis: \`TRIPEDIR' unset"; exit 1 ;;
71 esac
72 peer=$1
73
74 ## Arrange for errors to go somewhere.
75 exec 2>>"$TRIPE_IPIF_LOG"
76 now=$(date +"%Y-%m-%d %H:%M:%S")
77 echo >&2 "$now $quis[$$] running for peer \`$peer'"
78
79 ## Find the record in the peer table.
80 foundp=nil
81 while read name remote_ext local_int remote_int routes; do
82   case $name in "$peer") foundp=t; break ;; esac
83 done <$TRIPEDIR/ipif.tab
84 case $foundp in
85   nil) echo >&2 "$quis[$$]: unknown peer \`$peer'"; exit 1 ;;
86 esac
87
88 ## Announce the interface name.  We actually have no way to determine this,
89 ## so lie and hope that nobody cares.
90 echo "userv-$peer"
91
92 ## Now we can interrogate the server without deadlocking it.
93 algs=$(tripectl algs) tagsz=nil blksz=nil
94 while read line; do
95   for i in $line; do
96     case $i in
97       cipher-blksz=*) blksz=${i#*=} ;;
98       mac-tagsz=*) tagsz=${i#*=} ;;
99     esac
100   done
101 done <<EOF
102 $algs
103 EOF
104 case ,$tagsz,$blksz, in
105   *,nil,*) echo >&2 "$quis[$$]: failed to discover cipher suite"; exit 1 ;;
106 esac
107
108 ## Determine the remote address if none is specified; strip off a port number
109 ## if there is one.
110 case "$remote_ext" in
111   -)
112     addr=$(tripectl addr $peer)
113     set -- $addr
114     case $1 in
115       INET) remote_ext=$2 ;;
116       *) echo >&2 "$quis: unexpected address family \`$1'"; exit 1 ;;
117     esac
118     ;;
119   *:*)
120     remote_ext=${remote_ext%:*}
121     ;;
122 esac
123
124 ## Determine the MTU based on the path.
125 pmtu=$(pathmtu $remote_ext)
126 mtu=$(( $pmtu - 33 - $tagsz - $blksz ))
127
128 ## Obtain the tunnel and run it.
129 now=$(date +"%Y-%m-%d %H:%M:%S")
130 info="invoking \`userv ipif' for \`$peer'; mtu = $mtu"
131 info="$info; $local_int -> $remote_int${routes+ $routes}"
132 echo >&2 "$now $quis[$$] $info"
133 exec userv root ipif $local_int,$remote_int,$mtu,slip $routes
134
135 ###----- That's all, folks --------------------------------------------------