2014-04-23 22:45:23 +01:00
|
|
|
# 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/";
|
|
|
|
|
2023-09-05 18:17:47 +01:00
|
|
|
use IPXWrapper::DOSBoxServer;
|
2014-04-23 22:45:23 +01:00
|
|
|
use IPXWrapper::Tool::Bind;
|
2024-11-03 11:25:30 +00:00
|
|
|
use IPXWrapper::Tool::OSVersion;
|
2014-04-23 22:45:23 +01:00
|
|
|
use IPXWrapper::Util;
|
|
|
|
|
|
|
|
require "$FindBin::Bin/config.pm";
|
|
|
|
|
2023-09-05 18:17:47 +01:00
|
|
|
our ($local_ip_a);
|
2014-04-23 22:45:23 +01:00
|
|
|
our ($remote_mac_a, $remote_ip_a);
|
|
|
|
our ($remote_mac_b, $remote_ip_b);
|
2023-09-05 18:17:47 +01:00
|
|
|
our ($dosbox_port);
|
2014-04-23 22:45:23 +01:00
|
|
|
|
|
|
|
use constant {
|
2023-09-05 18:17:47 +01:00
|
|
|
IP_MAX_DATA_SIZE => 8192,
|
|
|
|
ETHER_MAX_DATA_SIZE => 1470,
|
|
|
|
LLC_MAX_DATA_SIZE => 1467,
|
|
|
|
DOSBOX_MAX_DATA_SIZE => 1424,
|
2014-04-23 22:45:23 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
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() // "";
|
|
|
|
|
2023-09-05 18:17:47 +01:00
|
|
|
is($first_a, $remote_mac_a);
|
|
|
|
is($first_b, $remote_mac_b);
|
2014-04-23 22:45:23 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
describe "IPXWrapper" => sub
|
|
|
|
{
|
2023-09-05 18:17:47 +01:00
|
|
|
describe "using IPXWrapper IP encapsulation" => sub
|
2014-04-23 22:45:23 +01:00
|
|
|
{
|
|
|
|
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
|
|
|
|
{
|
2024-11-03 11:25:30 +00:00
|
|
|
if(!IPXWrapper::Tool::OSVersion->get($remote_ip_a)->platform_is_winnt())
|
|
|
|
{
|
|
|
|
# Skip these tests under Windows 98
|
|
|
|
it "(not implemented)";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-04-23 22:45:23 +01:00
|
|
|
before all => sub
|
|
|
|
{
|
|
|
|
reg_delete_key($remote_ip_a, "HKCU\\Software\\IPXWrapper");
|
|
|
|
reg_set_dword( $remote_ip_a, "HKCU\\Software\\IPXWrapper", "use_pcap", 1);
|
2017-08-20 16:44:49 +01:00
|
|
|
reg_set_dword( $remote_ip_a, "HKCU\\Software\\IPXWrapper", "frame_type", 1);
|
2014-04-23 22:45:23 +01:00
|
|
|
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";
|
|
|
|
};
|
|
|
|
};
|
2017-08-20 16:44:49 +01:00
|
|
|
|
|
|
|
describe "using Novell Ethernet encapsulation" => sub
|
|
|
|
{
|
2024-11-03 11:25:30 +00:00
|
|
|
if(!IPXWrapper::Tool::OSVersion->get($remote_ip_a)->platform_is_winnt())
|
|
|
|
{
|
|
|
|
# Skip these tests under Windows 98
|
|
|
|
it "(not implemented)";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-08-20 16:44:49 +01:00
|
|
|
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
|
|
|
|
{
|
2024-11-03 11:25:30 +00:00
|
|
|
if(!IPXWrapper::Tool::OSVersion->get($remote_ip_a)->platform_is_winnt())
|
|
|
|
{
|
|
|
|
# Skip these tests under Windows 98
|
|
|
|
it "(not implemented)";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-08-20 16:44:49 +01:00
|
|
|
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";
|
|
|
|
};
|
|
|
|
};
|
2023-09-05 18:17:47 +01:00
|
|
|
|
2023-09-13 00:24:08 +01:00
|
|
|
my $dosbox_server;
|
|
|
|
|
|
|
|
describe "using DOSBox UDP encapsulation (via IP address)" => sub
|
2023-09-05 18:17:47 +01:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
2023-09-13 00:24:08 +01:00
|
|
|
$dosbox_server = undef;
|
2023-09-05 18:17:47 +01:00
|
|
|
$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));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
2023-09-13 00:24:08 +01:00
|
|
|
|
|
|
|
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);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
2014-04-23 22:45:23 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
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;
|