1
0
mirror of https://github.com/solemnwarning/ipxwrapper synced 2024-12-30 16:45:37 +01:00
ipxwrapper/tests/15-interfaces.t

423 lines
11 KiB
Perl
Raw Permalink Normal View History

# IPXWrapper test suite
# Copyright (C) 2014 Daniel Collins <solemnwarning@solemnwarning.net>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as published by
# the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
use strict;
use warnings;
use Test::Spec;
use FindBin;
use lib "$FindBin::Bin/lib/";
use IPXWrapper::DOSBoxServer;
use IPXWrapper::Tool::Bind;
use IPXWrapper::Util;
require "$FindBin::Bin/config.pm";
our ($local_ip_a);
our ($remote_mac_a, $remote_ip_a);
our ($remote_mac_b, $remote_ip_b);
our ($dosbox_port);
use constant {
IP_MAX_DATA_SIZE => 8192,
ETHER_MAX_DATA_SIZE => 1470,
LLC_MAX_DATA_SIZE => 1467,
DOSBOX_MAX_DATA_SIZE => 1424,
};
my @expected_addrs;
shared_examples_for "getsockopt" => sub
{
it "returns correct addresses" => sub
{
my @addrs = getsockopt_interfaces($remote_ip_a);
cmp_hashes_partial(\@addrs, \@expected_addrs);
};
it "returns correct IPX_MAX_ADAPTER_NUM" => sub
{
my @addrs = getsockopt_interfaces($remote_ip_a);
my $output = run_remote_cmd($remote_ip_a, "Z:\\tools\\list-interfaces.exe");
my ($got_num) = ($output =~ m/^IPX_MAX_ADAPTER_NUM = (\d+)$/m);
is($got_num, (scalar @addrs));
};
it "returns the configured primary interface first" => sub
{
reg_set_addr($remote_ip_a, "HKCU\\Software\\IPXWrapper", "primary", $remote_mac_a);
my $first_a = get_first_addr_node() // "";
reg_set_addr($remote_ip_a, "HKCU\\Software\\IPXWrapper", "primary", $remote_mac_b);
my $first_b = get_first_addr_node() // "";
is($first_a, $remote_mac_a);
is($first_b, $remote_mac_b);
};
};
describe "IPXWrapper" => sub
{
describe "using IPXWrapper IP encapsulation" => sub
{
before all => sub
{
reg_delete_key($remote_ip_a, "HKCU\\Software\\IPXWrapper");
reg_set_addr( $remote_ip_a, "HKCU\\Software\\IPXWrapper\\00:00:00:00:00:00", "net", "00:00:00:01");
reg_set_addr( $remote_ip_a, "HKCU\\Software\\IPXWrapper\\$remote_mac_a", "net", "00:00:00:01");
reg_set_addr( $remote_ip_a, "HKCU\\Software\\IPXWrapper\\$remote_mac_b", "net", "00:00:00:02");
};
describe "with the wildcard interface disabled" => sub
{
before all => sub
{
reg_set_dword($remote_ip_a, "HKCU\\Software\\IPXWrapper\\00:00:00:00:00:00", "enabled", 0);
@expected_addrs = (
{
net => "00:00:00:01",
node => $remote_mac_a,
maxpkt => IP_MAX_DATA_SIZE,
},
{
net => "00:00:00:02",
node => $remote_mac_b,
maxpkt => IP_MAX_DATA_SIZE,
},
);
};
describe "getsockopt" => sub
{
it_should_behave_like "getsockopt";
};
};
describe "with the wildcard interface enabled" => sub
{
before all => sub
{
reg_set_dword($remote_ip_a, "HKCU\\Software\\IPXWrapper\\00:00:00:00:00:00", "enabled", 1);
@expected_addrs = (
{
net => "00:00:00:01",
maxpkt => IP_MAX_DATA_SIZE,
},
{
net => "00:00:00:01",
node => $remote_mac_a,
maxpkt => IP_MAX_DATA_SIZE,
},
{
net => "00:00:00:02",
node => $remote_mac_b,
maxpkt => IP_MAX_DATA_SIZE,
},
);
};
describe "getsockopt" => sub
{
it_should_behave_like "getsockopt";
it "returns the wildcard interface first by default" => sub
{
my $wildcard_node = wildcard_node();
return unless(defined($wildcard_node));
reg_delete_value($remote_ip_a, "HKCU\\Software\\IPXWrapper", "primary");
is(get_first_addr_node(), $wildcard_node);
};
};
it "remembers the wildcard node number" => sub
{
my $node_a = wildcard_node();
my $node_b = wildcard_node();
is($node_a, $node_b);
};
it "generates a new wildcard node number if the old is deleted" => sub
{
my $old_node = wildcard_node();
return unless(defined($old_node));
reg_delete_value($remote_ip_a, "HKCU\\Software\\IPXWrapper\\00:00:00:00:00:00", "node");
my $new_node = wildcard_node();
isnt($new_node, $old_node);
};
};
};
describe "using Ethernet encapsulation" => sub
{
before all => sub
{
reg_delete_key($remote_ip_a, "HKCU\\Software\\IPXWrapper");
reg_set_dword( $remote_ip_a, "HKCU\\Software\\IPXWrapper", "use_pcap", 1);
reg_set_dword( $remote_ip_a, "HKCU\\Software\\IPXWrapper", "frame_type", 1);
reg_set_addr( $remote_ip_a, "HKCU\\Software\\IPXWrapper\\$remote_mac_a", "net", "00:00:00:01");
reg_set_addr( $remote_ip_a, "HKCU\\Software\\IPXWrapper\\$remote_mac_b", "net", "00:00:00:02");
@expected_addrs = (
{
net => "00:00:00:01",
node => $remote_mac_a,
maxpkt => ETHER_MAX_DATA_SIZE,
},
{
net => "00:00:00:02",
node => $remote_mac_b,
maxpkt => ETHER_MAX_DATA_SIZE,
},
);
};
describe "getsockopt" => sub
{
it_should_behave_like "getsockopt";
};
};
describe "using Novell Ethernet encapsulation" => sub
{
before all => sub
{
reg_delete_key($remote_ip_a, "HKCU\\Software\\IPXWrapper");
reg_set_dword( $remote_ip_a, "HKCU\\Software\\IPXWrapper", "use_pcap", 1);
reg_set_dword( $remote_ip_a, "HKCU\\Software\\IPXWrapper", "frame_type", 2);
reg_set_addr( $remote_ip_a, "HKCU\\Software\\IPXWrapper\\$remote_mac_a", "net", "00:00:00:01");
reg_set_addr( $remote_ip_a, "HKCU\\Software\\IPXWrapper\\$remote_mac_b", "net", "00:00:00:02");
@expected_addrs = (
{
net => "00:00:00:01",
node => $remote_mac_a,
maxpkt => ETHER_MAX_DATA_SIZE,
},
{
net => "00:00:00:02",
node => $remote_mac_b,
maxpkt => ETHER_MAX_DATA_SIZE,
},
);
};
describe "getsockopt" => sub
{
it_should_behave_like "getsockopt";
};
};
describe "using LLC (802.2) Ethernet encapsulation" => sub
{
before all => sub
{
reg_delete_key($remote_ip_a, "HKCU\\Software\\IPXWrapper");
reg_set_dword( $remote_ip_a, "HKCU\\Software\\IPXWrapper", "use_pcap", 1);
reg_set_dword( $remote_ip_a, "HKCU\\Software\\IPXWrapper", "frame_type", 3);
reg_set_addr( $remote_ip_a, "HKCU\\Software\\IPXWrapper\\$remote_mac_a", "net", "00:00:00:01");
reg_set_addr( $remote_ip_a, "HKCU\\Software\\IPXWrapper\\$remote_mac_b", "net", "00:00:00:02");
@expected_addrs = (
{
net => "00:00:00:01",
node => $remote_mac_a,
maxpkt => LLC_MAX_DATA_SIZE,
},
{
net => "00:00:00:02",
node => $remote_mac_b,
maxpkt => LLC_MAX_DATA_SIZE,
},
);
};
describe "getsockopt" => sub
{
it_should_behave_like "getsockopt";
};
};
my $dosbox_server;
describe "using DOSBox UDP encapsulation (via IP address)" => sub
{
before all => sub
{
reg_delete_key($remote_ip_a, "HKCU\\Software\\IPXWrapper");
reg_set_dword( $remote_ip_a, "HKCU\\Software\\IPXWrapper", "use_pcap", ENCAP_TYPE_DOSBOX);
reg_set_string($remote_ip_a, "HKCU\\Software\\IPXWrapper", "dosbox_server_addr", $local_ip_a);
reg_set_dword( $remote_ip_a, "HKCU\\Software\\IPXWrapper", "dosbox_server_port", $dosbox_port);
$dosbox_server = undef;
$dosbox_server = IPXWrapper::DOSBoxServer->new($dosbox_port);
@expected_addrs = (
{
# The node number is randomly selected by the DOSBox server
# when each client connects.
net => "00:00:00:00",
maxpkt => DOSBOX_MAX_DATA_SIZE,
},
);
};
after all => sub
{
$dosbox_server = undef;
};
# Duplicate of common getsockopt block to skip the default interface selection
# logic test (because there is only ever one interface here).
describe "getsockopt" => sub
{
it "returns correct addresses" => sub
{
my @addrs = getsockopt_interfaces($remote_ip_a);
cmp_hashes_partial(\@addrs, \@expected_addrs);
};
it "returns correct IPX_MAX_ADAPTER_NUM" => sub
{
my @addrs = getsockopt_interfaces($remote_ip_a);
my $output = run_remote_cmd($remote_ip_a, "Z:\\tools\\list-interfaces.exe");
my ($got_num) = ($output =~ m/^IPX_MAX_ADAPTER_NUM = (\d+)$/m);
is($got_num, (scalar @addrs));
};
};
};
describe "using DOSBox UDP encapsulation (via DNS name)" => sub
{
before all => sub
{
reg_delete_key($remote_ip_a, "HKCU\\Software\\IPXWrapper");
reg_set_dword( $remote_ip_a, "HKCU\\Software\\IPXWrapper", "use_pcap", ENCAP_TYPE_DOSBOX);
reg_set_string($remote_ip_a, "HKCU\\Software\\IPXWrapper", "dosbox_server_addr", "dosbox-ipv4.com");
reg_set_dword( $remote_ip_a, "HKCU\\Software\\IPXWrapper", "dosbox_server_port", $dosbox_port);
$dosbox_server = undef;
$dosbox_server = IPXWrapper::DOSBoxServer->new($dosbox_port);
@expected_addrs = (
{
# The node number is randomly selected by the DOSBox server
# when each client connects.
net => "00:00:00:00",
maxpkt => DOSBOX_MAX_DATA_SIZE,
},
);
};
after all => sub
{
$dosbox_server = undef;
};
# Duplicate of common getsockopt block to skip the default interface selection
# logic test (because there is only ever one interface here).
describe "getsockopt" => sub
{
it "returns correct addresses" => sub
{
my @addrs = getsockopt_interfaces($remote_ip_a);
cmp_hashes_partial(\@addrs, \@expected_addrs);
};
it "returns correct IPX_MAX_ADAPTER_NUM" => sub
{
my @addrs = getsockopt_interfaces($remote_ip_a);
my $output = run_remote_cmd($remote_ip_a, "Z:\\tools\\list-interfaces.exe");
my ($got_num) = ($output =~ m/^IPX_MAX_ADAPTER_NUM = (\d+)$/m);
is($got_num, (scalar @addrs));
};
};
};
describe "using DOSBox UDP encapsulation (server is down)" => sub
{
before all => sub
{
reg_delete_key($remote_ip_a, "HKCU\\Software\\IPXWrapper");
reg_set_dword( $remote_ip_a, "HKCU\\Software\\IPXWrapper", "use_pcap", ENCAP_TYPE_DOSBOX);
reg_set_string($remote_ip_a, "HKCU\\Software\\IPXWrapper", "dosbox_server_addr", $local_ip_a);
reg_set_dword( $remote_ip_a, "HKCU\\Software\\IPXWrapper", "dosbox_server_port", $dosbox_port);
$dosbox_server = undef;
};
# Duplicate of common getsockopt block to skip the default interface selection
# logic test (because there is only ever one interface here).
describe "getsockopt" => sub
{
it "returns no addresses" => sub
{
my @addrs = getsockopt_interfaces($remote_ip_a);
cmp_deeply(\@addrs, []);
};
it "returns correct IPX_MAX_ADAPTER_NUM" => sub
{
my @addrs = getsockopt_interfaces($remote_ip_a);
my $output = run_remote_cmd($remote_ip_a, "Z:\\tools\\list-interfaces.exe");
my ($got_num) = ($output =~ m/^IPX_MAX_ADAPTER_NUM = (\d+)$/m);
is($got_num, 0);
};
};
};
};
sub get_first_addr_node
{
my ($first) = getsockopt_interfaces($remote_ip_a);
return ($first // {})->{node};
}
sub wildcard_node
{
my ($wildcard) = grep {
$_->{node} ne $remote_mac_a && $_->{node} ne $remote_mac_b
} getsockopt_interfaces($remote_ip_a);
return ($wildcard // {})->{node};
}
runtests unless caller;