1#!/usr/bin/perl 2# $OpenBSD: remote.pl,v 1.4 2017/10/27 16:59:14 bluhm Exp $ 3 4# Copyright (c) 2010-2014 Alexander Bluhm <bluhm@openbsd.org> 5# 6# Permission to use, copy, modify, and distribute this software for any 7# purpose with or without fee is hereby granted, provided that the above 8# copyright notice and this permission notice appear in all copies. 9# 10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 18use strict; 19use warnings; 20use File::Basename; 21use File::Copy; 22use Socket; 23use Socket6; 24 25use Client; 26use Relay; 27use Server; 28use Remote; 29require 'funcs.pl'; 30 31sub usage { 32 die <<"EOF"; 33usage: 34 remote.pl localport remoteaddr remoteport [args-test.pl] 35 Run test with local client and server. Remote relay 36 forwarding from remoteaddr remoteport to server localport 37 has to be started manually. 38 remote.pl copy|splice listenaddr connectaddr connectport [args-test.pl] 39 Only start remote relay. 40 remote.pl copy|splice localaddr remoteaddr remotessh [args-test.pl] 41 Run test with local client and server. Remote relay is 42 started automatically with ssh on remotessh. 43EOF 44} 45 46my $testfile; 47our %args; 48if (@ARGV and -f $ARGV[-1]) { 49 $testfile = pop; 50 do $testfile 51 or die "Do test file $testfile failed: ", $@ || $!; 52} 53my $mode = 54 @ARGV == 3 && $ARGV[0] =~ /^\d+$/ && $ARGV[2] =~ /^\d+$/ ? "manual" : 55 @ARGV == 4 && $ARGV[1] !~ /^\d+$/ && $ARGV[3] =~ /^\d+$/ ? "relay" : 56 @ARGV == 4 && $ARGV[1] !~ /^\d+$/ && $ARGV[3] !~ /^\d+$/ ? "auto" : 57 usage(); 58 59my $r; 60if ($mode eq "relay") { 61 $r = Relay->new( 62 forward => $ARGV[0], 63 logfile => dirname($0)."/remote.log", 64 idle => 3, 65 func => \&relay, 66 %{$args{relay}}, 67 protocol => "udp", 68 listendomain => AF_INET, 69 listenaddr => $ARGV[1], 70 connectdomain => AF_INET, 71 connectaddr => $ARGV[2], 72 connectport => $ARGV[3], 73 ); 74 open(my $log, '<', $r->{logfile}) 75 or die "Remote log file open failed: $!"; 76 $SIG{__DIE__} = sub { 77 die @_ if $^S; 78 copy($log, \*STDERR); 79 warn @_; 80 exit 255; 81 }; 82 copy($log, \*STDERR); 83 $r->run; 84 copy($log, \*STDERR); 85 $r->up; 86 copy($log, \*STDERR); 87 $r->down; 88 copy($log, \*STDERR); 89 90 exit; 91} 92 93my $s = Server->new( 94 idle => 4, 95 func => \&read_datagram, 96 %{$args{server}}, 97 protocol => "udp", 98 listendomain => AF_INET, 99 listenaddr => ($mode eq "auto" ? $ARGV[1] : undef), 100 listenport => ($mode eq "manual" ? $ARGV[0] : undef), 101); 102if ($mode eq "auto") { 103 $r = Remote->new( 104 forward => $ARGV[0], 105 logfile => "relay.log", 106 testfile => $testfile, 107 %{$args{relay}}, 108 remotessh => $ARGV[3], 109 protocol => "udp", 110 listenaddr => $ARGV[2], 111 connectaddr => $ARGV[1], 112 connectport => $s->{listenport}, 113 ); 114 $r->run->up; 115} 116my $c = Client->new( 117 func => \&write_datagram, 118 %{$args{client}}, 119 protocol => "udp", 120 connectdomain => AF_INET, 121 connectaddr => ($mode eq "manual" ? $ARGV[1] : $r->{listenaddr}), 122 connectport => ($mode eq "manual" ? $ARGV[2] : $r->{listenport}), 123); 124 125$s->run; 126$c->run->up; 127$s->up; 128 129$c->down; 130$r->down if $r; 131$s->down; 132 133check_logs($c, $r, $s, %args); 134