chiark / gitweb /
Add example invocation.
[userv-utils.git] / ipif / udptunnel
index c2da428f9a2a5d020cc4875fa66383650b574103..5b64b2b631be1115dec6efd9fb150caf7f426c35 100755 (executable)
@@ -1,6 +1,10 @@
 #!/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>] ... .
@@ -8,6 +12,7 @@
 #        | -m   (`masquerade support': subcommand gets `Wait' instead of our addr/port)
 #        | -d   (`dump keys': when no subcmd, spew keys rather than reading them;
 #                we always send keys to our subcmd if there is one)
+#        | -Dcrypto  (debug crypto - use with care, prints keys, packets &c on screen!)
 #        | -f<path-to-udptunnel-forwarder>
 #          ...
 #        ]
@@ -158,7 +163,7 @@ sub show_addr_port ($) {
     return show_addr($s).','.show_port($s);
 }
 sub arg_value ($$) {
-    my ($val,$opt);
+    my ($val,$opt) = @_;
     $_= '-';
     return $val if length $val;
     @ARGV or quit("$opt needs value");
@@ -172,6 +177,7 @@ $|=1;
 $masq= 0;
 $dump= 0;
 $fcmd= 'udptunnel-forwarder';
+$xfwdopts= '';
 
 while ($ARGV[0] =~ m/^-/) {
     $_= shift @ARGV;
@@ -185,12 +191,17 @@ while ($ARGV[0] =~ m/^-/) {
            $fcmd= arg_value($_,'-f');
        } elsif (s/^-e//) {
            $encrarg= arg_value($_,'-e');
-           push @encrargs, "-e$encrarg";
-           push @encryption, split m#/#, $encrarg;
+           push @remoteopts, "-e$encrarg";
+           @thisencryption= split m#/#, $encrarg;
+           $thisencryption[0] =~ s/^/\|/;
+           push @encryption, @thisencryption;
        } elsif (s/^-m/-/) {
            $masq= 1;
        } elsif (s/^-d/-/) {
            $dump= 1;
+       } elsif (s/^-Dcrypto$/-/) {
+           $xfwdopts.= 'K';
+           push @remoteopts, '-Dcrypto';
        } else {
            quit("unknown option \`$_'");
        }
@@ -255,7 +266,7 @@ if (@ARGV) {
     $rad= xform_remote(show_addr($rs),$ras);
     $rpd= xform_remote(show_port($rs),$rps);
     @rcmd= (@ARGV,
-           @encrargs,
+           @remoteopts,
            "$rad,$rpd",
            $masq ? 'Wait,Wait' : $lapd,
            "$rva,$lva,$mtu,$proto",
@@ -267,10 +278,10 @@ if (@ARGV) {
        pipe(RAPREAD,RCMDREADSUB) or fail("pipe");
        select(RCMDREADSUB); $|=1; select(STDOUT);
     }
-    pipe(DUMPKEYS,RCMDWRITESUB) or fail("pipe");
+    pipe(RCMDWRITESUB,DUMPKEYS) or fail("pipe");
     defined($c_rcmd= fork) or fail("fork for remote");
     if (!$c_rcmd) {
-       open STDIN, ">&RCMDWRITESUB" or fail("reopen stdin for remote command");
+       open STDIN, "<&RCMDWRITESUB" or fail("reopen stdin for remote command");
        open STDOUT, ">&RCMDREADSUB" or fail("reopen stdout for remote command")
            if $rapcmd;
        close RAPREAD if $rapcmd;
@@ -345,17 +356,18 @@ if (!$c_lcmd) {
 close UW;
 close DR;
 
-@fcmd= ($fcmd,
-       fileno(L), fileno(DW), fileno(UR),
+$xfwdopts.= 'w' if $dump;
+
+@fcmd= ($fcmd, $xfwdopts,
+       fileno(L), fileno(DW), fileno(UR), fileno(DUMPKEYS),
        $mtu, $keepalive, $timeout,
        @rapf,
-       fileno(DUMPKEYS), $dump ? 'y' : '',
        @encryption);
 debug("forwarding command @fcmd.");
 
 defined($c_fwd= fork) or fail("fork for udptunnel-forwarder");
 if (!$c_fwd) {
-    foreach $fd (qw(L DW UR)) {
+    foreach $fd (qw(L DW UR DUMPKEYS)) {
        fcntl($fd, F_SETFD, 0) or fail("set no-close-on-exec $fd");
     }
     exec @fcmd; fail("cannot execute $fcmd[0]");
@@ -376,11 +388,12 @@ $estatus= 0;
 while (keys %procs) {
     ($c= wait) >0 or
        fail("wait failed (expecting ". join('; ',keys %procs). ")");
-    warning("unexpected child reaped: pid $c, code $?"), next
+    $status= $?;
+    warning("unexpected child reaped: pid $c, code $status"), next
        unless exists $procs{$c};
     $str= $procs{$c};
     delete $procs{$c};
-    $? ? warning("subprocess $str failed with code $?")
+    $status ? warning("subprocess $str failed with code $status")
        : debug("subprocess $str finished");
     if ($c==$c_lcmd || $c==$c_fwd || $c==$c_rcmd) {
        kill 15, grep (exists $procs{$_}, $c_fwd, $c_rcmd);