#!/usr/bin/perl
# Simple tunnel for userv-ipif tunnels.
#
+# Example test invocation
+#
+# ./udptunnel -e nonce -e timestamp/10/30 -e pkcs5/8 -e blowfish-cbcmac/128 -e blowfish-cbc/128 -m -f ./udptunnel-forwarder davenant,Any anarres,Command 172.30.206.1,172.30.206.2,1000,cslip 15,70 '' '' rsh anarres things/userv-utils/ipif/udptunnel -f things/userv-utils/ipif/udptunnel-forwarder
+#
# usage:
# udptunnel
# [ -l[<local-command/arg>] ... .
# <public-local-addr>,<public-local-port>
# <public-remote-addr>,<public-remote-port>
# <private-local-addr>,<private-remote-addr>,<mtu>,<proto>
-# <keepalive>,<timeout>
-# <extra-local-nets> <extra-remote-nets>
+# <keepalive>,<timeout>[,<reannounce>]
+# <extra-nets-for-local-cmd> <extra-nets-for-remote-cmd>
# [ <remote-command> [<remote-args> ...] ]
#
# proto may be slip or cslip
# <public-remote-addr'>,<public-remote-port'>
# <public-local-addr'>,<public-local-port'>
# <private-remote-addr>,<private-local-addr>,<mtu>,<proto>
-# <keepalive>,<timeout>
-# <extra-remote-nets> <extra-local-nets>
+# <keepalive>,<timeout>[,<reannounce>]
+# <extra-nets-for-remote-cmd> <extra-nets-for-local-cmd>
#
# If it was given Print for <public-remote-foo'>, this command's first
# <public-local-foo> <public-local-foo'> <public-local-foo'>
# (-m not specified) (-m specified)
# actual addr/port that addr/port `Wait'
-# `Wait' the chosen address `Wait'
# `Print' the chosen address `Wait'
+# `Any' `Wait' for addr, `Wait'
+# chosen port for port
#
# udptunnel will userv ipif locally, as
# userv root ipif <private-local-addr>,<private-remote-addr>,<mtu>,<proto>
-# <extra-local-nets>
+# <extra-nets-for-local-cmd>
# or, if -l was given, userv root ipif is replaced with the argument(s)
# following -l option(s) until `.'.
#
return shift @ARGV;
}
-$|=1;
-
@lcmd= ();
@encryption= ();
$masq= 0;
($lva,$rva,$mtu,$proto) = ($1,$2,$3,$4);
$_= shift @ARGV;
-m/^(\d+),(\d+)$/ or quit("keepalive,timeout missing or bad syntax");
-($keepalive,$timeout)= ($1,$2);
+if (m/^(\d+),(\d+)$/) {
+ ($keepalive,$timeout,$reannounce)= ($1+0,$2+0,0);
+ $ka_to_ra= "$keepalive,$timeout";
+} elsif (m/^(\d+),(\d+),(\d+)$/) {
+ ($keepalive,$timeout,$reannounce)= ($1+0,$2+0,$3);
+ "$keepalive,$timeout",
+ $ka_to_ra= "$keepalive,$timeout,$reannounce";
+} else {
+ quit("keepalive,timeout missing or bad syntax");
+}
$keepalive && ($timeout > $keepalive*2) or quit("timeout must be < 2*keepalive")
if $timeout;
@rcmd= (@ARGV,
@remoteopts,
"$rad,$rpd",
- $masq ? 'Wait,Wait' : $lapd,
+ $masq ? 'Wait,Wait' : $las eq 'Any' ? "Wait,$lpd" : $lapd,
"$rva,$lva,$mtu,$proto",
- "$keepalive,$timeout",
+ $ka_to_ra,
$rexn, $lexn);
debug("remote command @rcmd");
if ($rapcmd) {
pipe(RAPREAD,RCMDREADSUB) or fail("pipe");
- select(RCMDREADSUB); $|=1; select(STDOUT);
}
pipe(RCMDWRITESUB,DUMPKEYS) or fail("pipe");
defined($c_rcmd= fork) or fail("fork for remote");
if ($rapcmd) {
close RCMDREADSUB if $rapcmd;
- $!=0; $_= <RAPREAD>; $e="$!";
+ $_= '';
+ while (!m/\n/) {
+ $!=0;
+ defined($nread= sysread(RAPREAD,$_,1,length))
+ or fail("read from remote command");
+ if (!$nread) {
+ close DUMPKEYS;
+ close RAPREAD;
+ waitpid $c_rcmd,0 or fail("wait for remote command");
+ quit($? ? "remote command failed (code $?)" :
+ "no details received from remote");
+ }
+ }
+ chomp;
+ m/^([.0-9]+)\,(\d+)$/ or quit("invalid details from remote end: \`$_'");
+ ($rar,$rpr) = ($1,$2);
+ $ra= conv_host_addr($rar);
+ $rp= conv_port_number($rpr);
defined($c_catremdebug= fork) or fail("fork for cat remote debug");
if (!$c_catremdebug) {
open(STDIN,"<&RAPREAD") or fail("redirect remote debug");
- close RAPREAD;
close DUMPKEYS;
close L;
exec "cat"; fail("execute cat");
}
close RAPREAD;
-
- if (!length) {
- close DUMPKEYS;
- waitpid $c_rcmd,0 or fail("wait for remote command");
- quit($? ? "remote command failed (code $?)" :
- $e ? "read error from remote command: $e" :
- "no details received from remote");
- }
- chomp;
- m/^([.0-9]+)\,(\d+)$/ or quit("invalid details from remote end: \`$_'");
- ($rar,$rpr) = ($1,$2);
- $ra= conv_host_addr($rar);
- $rp= conv_port_number($rpr);
}
} elsif ($dump) {
open DUMPKEYS, ">&STDOUT" or fail("reopen stdout for key material");
@fcmd= ($fcmd, $xfwdopts,
fileno(L), fileno(DW), fileno(UR), fileno(DUMPKEYS),
- $mtu, $keepalive, $timeout,
+ $mtu, $keepalive, $timeout, $reannounce,
@rapf,
@encryption);
debug("forwarding command @fcmd.");