summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbluhm <bluhm@openbsd.org>2017-08-15 04:11:20 +0000
committerbluhm <bluhm@openbsd.org>2017-08-15 04:11:20 +0000
commit068b97e5817f32f7b00f2296ebe1b2bc40bc0465 (patch)
treea58759a7c13fa7c7c707c1d145dc6b14930f6918
parentremove parens that were copied from ndinit's previous life as a macro (diff)
downloadwireguard-openbsd-068b97e5817f32f7b00f2296ebe1b2bc40bc0465.tar.xz
wireguard-openbsd-068b97e5817f32f7b00f2296ebe1b2bc40bc0465.zip
Add tests for pf divert-packet. Currently UDP packets are tested
with in and out rules. A single packet, the initial packet or the response packet are diverted and reinjected.
-rw-r--r--regress/sys/net/pf_divert/Client.pm6
-rw-r--r--regress/sys/net/pf_divert/Makefile18
-rw-r--r--regress/sys/net/pf_divert/Packet.pm79
-rw-r--r--regress/sys/net/pf_divert/Proc.pm8
-rw-r--r--regress/sys/net/pf_divert/Remote.pm3
-rw-r--r--regress/sys/net/pf_divert/Server.pm3
-rw-r--r--regress/sys/net/pf_divert/args-udp-packet-in-init.pl21
-rw-r--r--regress/sys/net/pf_divert/args-udp-packet-in-resp.pl21
-rw-r--r--regress/sys/net/pf_divert/args-udp-packet-in.pl22
-rw-r--r--regress/sys/net/pf_divert/args-udp-packet-out-init.pl21
-rw-r--r--regress/sys/net/pf_divert/args-udp-packet-out-resp.pl21
-rw-r--r--regress/sys/net/pf_divert/args-udp-packet-out.pl22
-rw-r--r--regress/sys/net/pf_divert/args-udp-reply-to.pl18
-rw-r--r--regress/sys/net/pf_divert/funcs.pl60
-rw-r--r--regress/sys/net/pf_divert/remote.pl90
15 files changed, 357 insertions, 56 deletions
diff --git a/regress/sys/net/pf_divert/Client.pm b/regress/sys/net/pf_divert/Client.pm
index 20787d41f2c..e8ce59ff4ee 100644
--- a/regress/sys/net/pf_divert/Client.pm
+++ b/regress/sys/net/pf_divert/Client.pm
@@ -1,4 +1,4 @@
-# $OpenBSD: Client.pm,v 1.3 2013/06/05 04:34:27 bluhm Exp $
+# $OpenBSD: Client.pm,v 1.4 2017/08/15 04:11:20 bluhm Exp $
# Copyright (c) 2010-2013 Alexander Bluhm <bluhm@openbsd.org>
#
@@ -31,8 +31,8 @@ sub new {
my %args = @_;
$args{logfile} ||= "client.log";
$args{up} ||= "Connected";
- $args{down} ||= $args{alarm} ? "Alarm" :
- "Shutdown|Broken pipe|Connection reset by peer";
+ $args{down} ||= $args{alarm} ? "Alarm $class" :
+ "Shutdown $class|Broken pipe|Connection reset by peer";
my $self = Proc::new($class, %args);
$self->{domain}
or croak "$class domain not given";
diff --git a/regress/sys/net/pf_divert/Makefile b/regress/sys/net/pf_divert/Makefile
index c4395eb6f16..3262909db12 100644
--- a/regress/sys/net/pf_divert/Makefile
+++ b/regress/sys/net/pf_divert/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.15 2016/11/16 16:00:41 bluhm Exp $
+# $OpenBSD: Makefile,v 1.16 2017/08/15 04:11:20 bluhm Exp $
# The following ports must be installed for the regression tests:
# p5-IO-Socket-INET6 object interface for AF_INET and AF_INET6 domain sockets
@@ -51,6 +51,8 @@ regress:
# Automatically generate regress targets from test cases in directory.
+PERLS = Client.pm Packet.pm Proc.pm Remote.pm Server.pm \
+ funcs.pl remote.pl
ARGS != cd ${.CURDIR} && ls args-*.pl
TARGETS ?= inet-args-tcp-to inet6-args-tcp-to \
inet-args-tcp-reply inet6-args-tcp-reply \
@@ -84,7 +86,10 @@ TARGETS ?= inet-args-tcp-to inet6-args-tcp-to \
inet-reuse-rip-reply-reply-to inet6-reuse-rip-reply-reply-to \
inet-reuse-rip-reply-to-to inet6-reuse-rip-reply-to-to \
inet-reuse-rip-reply-to-reply inet6-reuse-rip-reply-to-reply \
- inet-reuse-rip-reply-to-reply-to inet6-reuse-rip-reply-to-reply-to
+ inet-reuse-rip-reply-to-reply-to inet6-reuse-rip-reply-to-reply-to \
+ inet-args-udp-packet-in inet-args-udp-packet-out \
+ inet-args-udp-packet-in-init inet-args-udp-packet-in-resp \
+ inet-args-udp-packet-out-init inet-args-udp-packet-out-resp
REGRESS_TARGETS = ${TARGETS:S/^/run-regress-/}
CLEANFILES += *.log *.port ktrace.out stamp-*
@@ -133,7 +138,11 @@ run-regress-${inet}-reuse-rip-to-reply-to:
.for a in ${ARGS}
run-regress-${inet}-${a:R}: ${a}
@echo '\n======== $@ ========'
+.if ${@:M*-packet-*}
+ time ${SUDO} SUDO=${SUDO} perl ${PERLINC} ${PERLPATH}remote.pl -f ${inet} ${LOCAL_${addr}} ${REMOTE_${addr}} ${REMOTE_SSH} ${PERLPATH}${a}
+.else
time ${SUDO} SUDO=${SUDO} perl ${PERLINC} ${PERLPATH}remote.pl -f ${inet} ${LOCAL_${addr}} ${FAKE_${addr}} ${REMOTE_SSH} ${PERLPATH}${a}
+.endif
.endfor
.for proto in tcp udp rip
@@ -176,7 +185,10 @@ run-regress-${inet}-reuse-${proto}-${first}-${second}:
# make perl syntax check for all args files
syntax: stamp-syntax
-stamp-syntax: ${ARGS}
+stamp-syntax: ${PERLS} ${ARGS}
+.for p in ${PERLS}
+ @perl -c ${PERLINC} ${PERLPATH}$p
+.endfor
.for a in ${ARGS}
@perl -c ${PERLPATH}$a
.endfor
diff --git a/regress/sys/net/pf_divert/Packet.pm b/regress/sys/net/pf_divert/Packet.pm
new file mode 100644
index 00000000000..ac7f3e7017a
--- /dev/null
+++ b/regress/sys/net/pf_divert/Packet.pm
@@ -0,0 +1,79 @@
+# $OpenBSD: Packet.pm,v 1.1 2017/08/15 04:11:20 bluhm Exp $
+
+# Copyright (c) 2010-2017 Alexander Bluhm <bluhm@openbsd.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+use strict;
+use warnings;
+
+package Packet;
+use parent 'Proc';
+use Carp;
+use Socket;
+use Socket6;
+use IO::Socket;
+use IO::Socket::INET6;
+
+use constant IPPROTO_DIVERT => 258;
+use constant IP_DIVERTFL => 0x1022;
+use constant IPPROTO_DIVERT_RESP => 0x1;
+use constant IPPROTO_DIVERT_INIT => 0x2;
+
+sub new {
+ my $class = shift;
+ my %args = @_;
+ $args{logfile} ||= "packet.log";
+ $args{up} ||= "Bound";
+ $args{down} ||= "Shutdown $class";
+ my $self = Proc::new($class, %args);
+ $self->{domain}
+ or croak "$class domain not given";
+ my $ds = do { local $> = 0; IO::Socket::INET6->new(
+ Type => Socket::SOCK_RAW,
+ Proto => IPPROTO_DIVERT,
+ Domain => $self->{domain},
+ ) } or die ref($self), " socket failed: $!";
+ my $sa;
+ $sa = pack_sockaddr_in($self->{bindport}, Socket::INADDR_ANY)
+ if $self->{af} eq "inet";
+ $sa = pack_sockaddr_in6($self->{bindport}, Socket::IN6ADDR_ANY)
+ if $self->{af} eq "inet6";
+ $ds->bind($sa)
+ or die ref($self), " bind failed: $!";
+ my $log = $self->{log};
+ print $log "divert sock: ",$ds->sockhost()," ",$ds->sockport(),"\n";
+ $self->{divertaddr} = $ds->sockhost();
+ $self->{divertport} = $ds->sockport();
+ my $divertdir = 0;
+ $divertdir |= IPPROTO_DIVERT_INIT if $self->{divertinit};
+ $divertdir |= IPPROTO_DIVERT_RESP if $self->{divertresp};
+ if ($divertdir) {
+ setsockopt($ds, IPPROTO_IP, IP_DIVERTFL, pack('i', $divertdir))
+ or die ref($self), " set divert flag failed: $!";
+ }
+ $self->{ds} = $ds;
+ return $self;
+}
+
+sub child {
+ my $self = shift;
+ my $ds = $self->{ds};
+
+ open(STDIN, '<&', $ds)
+ or die ref($self), " dup STDIN failed: $!";
+ open(STDOUT, '>&', $ds)
+ or die ref($self), " dup STDOUT failed: $!";
+}
+
+1;
diff --git a/regress/sys/net/pf_divert/Proc.pm b/regress/sys/net/pf_divert/Proc.pm
index 34f09bc92eb..f07dfbaf432 100644
--- a/regress/sys/net/pf_divert/Proc.pm
+++ b/regress/sys/net/pf_divert/Proc.pm
@@ -1,4 +1,4 @@
-# $OpenBSD: Proc.pm,v 1.4 2016/05/03 19:13:04 bluhm Exp $
+# $OpenBSD: Proc.pm,v 1.5 2017/08/15 04:11:20 bluhm Exp $
# Copyright (c) 2010-2014 Alexander Bluhm <bluhm@openbsd.org>
#
@@ -43,7 +43,7 @@ END {
sub new {
my $class = shift;
my $self = { @_ };
- $self->{down} ||= $self->{alarm} ? "Alarm" : "Shutdown";
+ $self->{down} ||= $self->{alarm} ? "Alarm $class" : "Shutdown $class";
$self->{func} && ref($self->{func}) eq 'CODE'
or croak "$class func not given";
$self->{logfile}
@@ -80,7 +80,7 @@ sub run {
print STDERR $self->{up}, "\n";
alarm($self->{alarm}) if $self->{alarm};
$self->{func}->($self);
- print STDERR "Shutdown", "\n";
+ print STDERR "Shutdown ", ref($self), "\n";
IO::Handle::flush(\*STDOUT);
IO::Handle::flush(\*STDERR);
@@ -117,7 +117,7 @@ sub loggrep {
if ($self->{alarm} && $kid > 0 &&
WIFSIGNALED($status) && WTERMSIG($status) == 14 ) {
# child killed by SIGALRM as expected
- print {$self->{log}} "Alarm", "\n";
+ print {$self->{log}} "Alarm ", ref($self), "\n";
} elsif ($kid > 0 && $status != 0) {
# child terminated with failure
die ref($self), " child status: $status $code";
diff --git a/regress/sys/net/pf_divert/Remote.pm b/regress/sys/net/pf_divert/Remote.pm
index 41b2709128a..0983b3eaffb 100644
--- a/regress/sys/net/pf_divert/Remote.pm
+++ b/regress/sys/net/pf_divert/Remote.pm
@@ -1,4 +1,4 @@
-# $OpenBSD: Remote.pm,v 1.7 2016/11/15 16:00:50 bluhm Exp $
+# $OpenBSD: Remote.pm,v 1.8 2017/08/15 04:11:20 bluhm Exp $
# Copyright (c) 2010-2014 Alexander Bluhm <bluhm@openbsd.org>
#
@@ -28,6 +28,7 @@ sub new {
my %args = @_;
$args{logfile} ||= "remote.log";
$args{up} ||= "Started";
+ $args{down} ||= "Shutdown";
$args{func} = sub { Carp::confess "$class func may not be called" };
$args{remotessh}
or croak "$class remote ssh host not given";
diff --git a/regress/sys/net/pf_divert/Server.pm b/regress/sys/net/pf_divert/Server.pm
index 6e737996df1..ea1c06affe9 100644
--- a/regress/sys/net/pf_divert/Server.pm
+++ b/regress/sys/net/pf_divert/Server.pm
@@ -1,4 +1,4 @@
-# $OpenBSD: Server.pm,v 1.3 2013/06/05 04:34:27 bluhm Exp $
+# $OpenBSD: Server.pm,v 1.4 2017/08/15 04:11:20 bluhm Exp $
# Copyright (c) 2010-2013 Alexander Bluhm <bluhm@openbsd.org>
#
@@ -30,6 +30,7 @@ sub new {
my %args = @_;
$args{logfile} ||= "server.log";
$args{up} ||= "Accepted";
+ $args{down} ||= "Shutdown $class";
my $self = Proc::new($class, %args);
$self->{domain}
or croak "$class domain not given";
diff --git a/regress/sys/net/pf_divert/args-udp-packet-in-init.pl b/regress/sys/net/pf_divert/args-udp-packet-in-init.pl
new file mode 100644
index 00000000000..75b61bf476c
--- /dev/null
+++ b/regress/sys/net/pf_divert/args-udp-packet-in-init.pl
@@ -0,0 +1,21 @@
+# test divert-packet input rule with udp initial packet
+
+use strict;
+use warnings;
+
+our %args = (
+ protocol => "udp",
+ client => {
+ func => \&write_read_datagram,
+ },
+ packet => {
+ divertresp => 1, # XXX the directions are broken
+ func => \&read_write_packet,
+ in => "Client",
+ },
+ server => {
+ func => \&read_write_datagram,
+ in => "Packet",
+ },
+ divert => "packet-in-init",
+);
diff --git a/regress/sys/net/pf_divert/args-udp-packet-in-resp.pl b/regress/sys/net/pf_divert/args-udp-packet-in-resp.pl
new file mode 100644
index 00000000000..11500c921ae
--- /dev/null
+++ b/regress/sys/net/pf_divert/args-udp-packet-in-resp.pl
@@ -0,0 +1,21 @@
+# test divert-packet input rule with udp response packet
+
+use strict;
+use warnings;
+
+our %args = (
+ protocol => "udp",
+ client => {
+ func => \&write_read_datagram,
+ in => "Packet",
+ },
+ packet => {
+ divertinit => 1, # XXX the directions are broken
+ func => \&read_write_packet,
+ in => "Server",
+ },
+ server => {
+ func => \&read_write_datagram,
+ },
+ divert => "packet-in-resp",
+);
diff --git a/regress/sys/net/pf_divert/args-udp-packet-in.pl b/regress/sys/net/pf_divert/args-udp-packet-in.pl
new file mode 100644
index 00000000000..f3597c2098d
--- /dev/null
+++ b/regress/sys/net/pf_divert/args-udp-packet-in.pl
@@ -0,0 +1,22 @@
+# test divert-packet input rule with udp
+
+use strict;
+use warnings;
+
+our %args = (
+ protocol => "udp",
+ client => {
+ func => \&write_datagram,
+ noin => 1,
+ },
+ packet => {
+ func => \&read_write_packet,
+ in => "Client",
+ },
+ server => {
+ func => \&read_datagram,
+ in => "Packet",
+ noout => 1,
+ },
+ divert => "packet-in",
+);
diff --git a/regress/sys/net/pf_divert/args-udp-packet-out-init.pl b/regress/sys/net/pf_divert/args-udp-packet-out-init.pl
new file mode 100644
index 00000000000..d747d359f3e
--- /dev/null
+++ b/regress/sys/net/pf_divert/args-udp-packet-out-init.pl
@@ -0,0 +1,21 @@
+# test divert-packet output rule with udp initial packet
+
+use strict;
+use warnings;
+
+our %args = (
+ protocol => "udp",
+ client => {
+ func => \&write_read_datagram,
+ },
+ packet => {
+ divertinit => 1, # XXX the directions are completely broken
+ func => \&read_write_packet,
+ in => "Client",
+ },
+ server => {
+ func => \&read_write_datagram,
+ in => "Packet",
+ },
+ divert => "packet-out-init",
+);
diff --git a/regress/sys/net/pf_divert/args-udp-packet-out-resp.pl b/regress/sys/net/pf_divert/args-udp-packet-out-resp.pl
new file mode 100644
index 00000000000..3d26e8f59ca
--- /dev/null
+++ b/regress/sys/net/pf_divert/args-udp-packet-out-resp.pl
@@ -0,0 +1,21 @@
+# test divert-packet output rule with udp response packet
+
+use strict;
+use warnings;
+
+our %args = (
+ protocol => "udp",
+ client => {
+ func => \&write_read_datagram,
+ in => "Packet",
+ },
+ packet => {
+ divertresp => 1, # XXX the directions are totally broken
+ func => \&read_write_packet,
+ in => "Server",
+ },
+ server => {
+ func => \&read_write_datagram,
+ },
+ divert => "packet-out-resp",
+);
diff --git a/regress/sys/net/pf_divert/args-udp-packet-out.pl b/regress/sys/net/pf_divert/args-udp-packet-out.pl
new file mode 100644
index 00000000000..e5f3dd2f19c
--- /dev/null
+++ b/regress/sys/net/pf_divert/args-udp-packet-out.pl
@@ -0,0 +1,22 @@
+# test divert-packet output rule with udp
+
+use strict;
+use warnings;
+
+our %args = (
+ protocol => "udp",
+ client => {
+ func => \&write_datagram,
+ noin => 1,
+ },
+ packet => {
+ func => \&read_write_packet,
+ in => "Client",
+ },
+ server => {
+ func => \&read_datagram,
+ in => "Packet",
+ noout => 1,
+ },
+ divert => "packet-out",
+);
diff --git a/regress/sys/net/pf_divert/args-udp-reply-to.pl b/regress/sys/net/pf_divert/args-udp-reply-to.pl
index c77088c9557..0886bda24c3 100644
--- a/regress/sys/net/pf_divert/args-udp-reply-to.pl
+++ b/regress/sys/net/pf_divert/args-udp-reply-to.pl
@@ -6,21 +6,7 @@ use Socket;
our %args = (
protocol => "udp",
- client => {
- func => sub {
- my $self = shift;
- write_datagram($self);
- read_datagram($self);
- },
- },
- server => {
- func => sub {
- my $self = shift;
- read_datagram($self);
- $self->{toaddr} = $self->{fromaddr};
- $self->{toport} = $self->{fromport};
- write_datagram($self);
- },
- },
+ client => { func => \&write_read_datagram },
+ server => { func => \&read_write_datagram },
divert => "reply",
);
diff --git a/regress/sys/net/pf_divert/funcs.pl b/regress/sys/net/pf_divert/funcs.pl
index a47b7c4a409..e1d686ae64e 100644
--- a/regress/sys/net/pf_divert/funcs.pl
+++ b/regress/sys/net/pf_divert/funcs.pl
@@ -1,4 +1,4 @@
-# $OpenBSD: funcs.pl,v 1.5 2015/07/28 12:31:29 bluhm Exp $
+# $OpenBSD: funcs.pl,v 1.6 2017/08/15 04:11:20 bluhm Exp $
# Copyright (c) 2010-2015 Alexander Bluhm <bluhm@openbsd.org>
#
@@ -55,10 +55,10 @@ sub write_datagram {
$self->{toport} = $port;
print STDERR "send to: $addr $port\n";
- send(STDIN, $out, 0, $to)
+ send(STDOUT, $out, 0, $to)
or die ref($self), " send to failed: $!";
} else {
- send(STDIN, $out, 0)
+ send(STDOUT, $out, 0)
or die ref($self), " send failed: $!";
}
@@ -98,6 +98,36 @@ sub read_datagram {
}
}
+sub write_read_datagram {
+ my $self = shift;
+ write_datagram($self);
+ read_datagram($self);
+}
+
+sub read_write_datagram {
+ my $self = shift;
+ read_datagram($self);
+ $self->{toaddr} = $self->{fromaddr};
+ $self->{toport} = $self->{fromport};
+ write_datagram($self);
+}
+
+sub read_write_packet {
+ my $self = shift;
+
+ my $packet;
+ read_datagram($self, \$packet);
+ my $hexin = unpack("H*", $packet);
+ print STDERR "<<< $hexin\n";
+
+ $packet =~ s/Client|Server/Packet/;
+ $self->{toaddr} = $self->{fromaddr};
+ $self->{toport} = $self->{fromport};
+ write_datagram($self, $packet);
+ my $hexout = unpack("H*", $packet);
+ print STDERR ">>> $hexout\n";
+}
+
sub in_cksum {
my $data = shift;
my $sum = 0;
@@ -184,15 +214,15 @@ sub read_icmp_echo {
########################################################################
sub check_logs {
- my ($c, $s, %args) = @_;
+ my ($c, $r, $s, %args) = @_;
return if $args{nocheck};
- check_inout($c, $s, %args);
+ check_inout($c, $r, $s, %args);
}
sub check_inout {
- my ($c, $s, %args) = @_;
+ my ($c, $r, $s, %args) = @_;
if ($args{client} && !$args{client}{nocheck}) {
my $out = $args{client}{out} || "Client";
@@ -202,13 +232,25 @@ sub check_inout {
$c->loggrep(qr/^<<< $in/) or die "no client input"
unless $args{client}{noin};
}
+ if ($args{packet} && !$args{packet}{nocheck}) {
+ my $hex;
+ my $in = $args{packet}{in} || $args{packet}{noin}
+ or die "no packet input regex";
+ $hex = unpack("H*", $in);
+ $r->loggrep(qr/Packet: <<< .*$hex/) or die "no packet input"
+ unless $args{packet}{noin};
+ my $out = $args{packet}{out} || "Packet";
+ $hex = unpack("H*", $out);
+ $r->loggrep(qr/Packet: >>> .*$hex/) or die "no packet output"
+ unless $args{packet}{noout};
+ }
if ($args{server} && !$args{server}{nocheck}) {
- my $out = $args{server}{out} || "Server";
- $s->loggrep(qr/^>>> $out/) or die "no server output"
- unless $args{server}{noout};
my $in = $args{server}{in} || "Client";
$s->loggrep(qr/^<<< $in/) or die "no server input"
unless $args{server}{noin};
+ my $out = $args{server}{out} || "Server";
+ $s->loggrep(qr/^>>> $out/) or die "no server output"
+ unless $args{server}{noout};
}
}
diff --git a/regress/sys/net/pf_divert/remote.pl b/regress/sys/net/pf_divert/remote.pl
index 263cefd320b..6257d60c8ef 100644
--- a/regress/sys/net/pf_divert/remote.pl
+++ b/regress/sys/net/pf_divert/remote.pl
@@ -1,5 +1,5 @@
#!/usr/bin/perl
-# $OpenBSD: remote.pl,v 1.7 2016/11/15 16:00:50 bluhm Exp $
+# $OpenBSD: remote.pl,v 1.8 2017/08/15 04:11:20 bluhm Exp $
# Copyright (c) 2010-2015 Alexander Bluhm <bluhm@openbsd.org>
#
@@ -33,6 +33,7 @@ use Socket6;
use Client;
use Server;
use Remote;
+use Packet;
require 'funcs.pl';
sub usage {
@@ -85,21 +86,21 @@ if (@ARGV == 5 && $mode eq "auto") {
usage();
}
-my($c, $l, $r, $s, $logfile);
-my $divert = $args{divert} || "to";
-my $local = $divert eq "to" ? "client" : "server";
-my $remote = $divert eq "to" ? "server" : "client";
+my $divert = $args{divert};
+my ($local, $remote) = ("client", "server");
+($local, $remote) = ($remote, $local) if $mode eq "divert";
+($local, $remote) = ($remote, $local) if $divert =~ /reply|out/;
+my ($srcaddr, $dstaddr) = @ARGV[0,1];
+($srcaddr, $dstaddr) = ($dstaddr, $srcaddr) if $mode eq "divert";
+($srcaddr, $dstaddr) = ($dstaddr, $srcaddr) if $divert =~ /reply|out/;
+
+my ($logfile, $packetlog);
if ($mode eq "divert") {
- $local = $divert eq "to" ? "server" : "client";
- $remote = $divert eq "to" ? "client" : "server";
$logfile = dirname($0)."/remote.log";
-}
-my $srcaddr = $ARGV[0];
-my $dstaddr = $ARGV[1];
-if ($mode eq "divert" xor $divert eq "reply") {
- ($srcaddr, $dstaddr) = ($dstaddr, $srcaddr);
+ $packetlog = dirname($0)."/packet.log";
}
+my ($c, $l, $r, $s);
if ($local eq "server") {
$l = $s = Server->new(
%args,
@@ -108,7 +109,8 @@ if ($local eq "server") {
af => $af,
domain => $domain,
protocol => $protocol,
- listenaddr => $mode ne "divert" ? $ARGV[0] :
+ listenaddr =>
+ $mode ne "divert" || $divert =~ /packet/ ? $ARGV[0] :
$af eq "inet" ? "127.0.0.1" : "::1",
listenport => $serverport || $bindport,
srcaddr => $srcaddr,
@@ -119,6 +121,7 @@ if ($mode eq "auto") {
$r = Remote->new(
%args,
opts => \%opts,
+ down => $args{packet} && "Shutdown Packet",
logfile => "$remote.log",
testfile => $test,
af => $af,
@@ -164,6 +167,33 @@ if ($mode eq "divert") {
};
copy($log, \*STDERR);
+ my ($p, $plog);
+ $p = Packet->new(
+ %args,
+ %{$args{packet}},
+ logfile => $packetlog,
+ af => $af,
+ domain => $domain,
+ bindport => 666,
+ ) if $args{packet};
+
+ if ($p) {
+ open($plog, '<', $p->{logfile})
+ or die "Remote packet log file open failed: $!";
+ $SIG{__DIE__} = sub {
+ die @_ if $^S;
+ copy($log, \*STDERR);
+ copy_prefix(ref $p, $plog, \*STDERR);
+ warn @_;
+ exit 255;
+ };
+ copy_prefix(ref $p, $plog, \*STDERR);
+ $p->run;
+ copy_prefix(ref $p, $plog, \*STDERR);
+ $p->up;
+ copy_prefix(ref $p, $plog, \*STDERR);
+ }
+
my @cmd = qw(pfctl -a regress -f -);
my $pf;
do { local $> = 0; open($pf, '|-', @cmd) }
@@ -172,15 +202,20 @@ if ($mode eq "divert") {
my $port = $protocol =~ /^(tcp|udp)$/ ?
"port $s->{listenport}" : "";
my $divertport = $port || "port 1"; # XXX bad pf syntax
+ my $divertcommand = $divert =~ /packet/ ?
+ "divert-packet port 666" :
+ "divert-to $s->{listenaddr} $divertport";
print $pf "pass in log $af proto $protocol ".
- "from $ARGV[1] to $ARGV[0] $port ".
- "divert-to $s->{listenaddr} $divertport ".
+ "from $ARGV[1] to $ARGV[0] $port $divertcommand ".
"label regress\n";
- } else {
+ }
+ if ($local eq "client") {
my $port = $protocol =~ /^(tcp|udp)$/ ?
"port $ARGV[2]" : "";
+ my $divertcommand = $divert =~ /packet/ ?
+ "divert-packet port 666" : "divert-reply";
print $pf "pass out log $af proto $protocol ".
- "from $c->{bindaddr} to $ARGV[1] $port divert-reply ".
+ "from $c->{bindaddr} to $ARGV[1] $port $divertcommand ".
"label regress\n";
}
close($pf) or die $! ?
@@ -200,6 +235,12 @@ if ($mode eq "divert") {
$l->down;
copy($log, \*STDERR);
+ if ($p) {
+ copy_prefix(ref $p, $plog, \*STDERR);
+ $p->down;
+ copy_prefix(ref $p, $plog, \*STDERR);
+ }
+
exit;
}
@@ -208,7 +249,18 @@ $c->run->up if $c;
$s->up if $s;
$c->down if $c;
-$r->down if $r;
+# remote side has 20 seconds timeout, wait longer than that here
+$r->down(30) if $r;
$s->down if $s;
-check_logs($c || $r, $s || $r, %args);
+check_logs($c || $r, $r, $s || $r, %args);
+
+sub copy_prefix {
+ my ($prefix, $src, $dst) = @_;
+
+ local $_;
+ while (defined($_ = <$src>)) {
+ chomp;
+ print $dst "$prefix: $_\n" if length;
+ }
+}