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