diff --git a/tests/30-eth-ipx.t b/tests/30-eth-ipx.t index a16aa2f..c3e6cf4 100644 --- a/tests/30-eth-ipx.t +++ b/tests/30-eth-ipx.t @@ -1,5 +1,5 @@ # IPXWrapper test suite -# Copyright (C) 2014 Daniel Collins +# Copyright (C) 2014-2017 Daniel Collins # # 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 @@ -23,6 +23,7 @@ use FindBin; use lib "$FindBin::Bin/lib/"; use IPXWrapper::Capture::IPX; +use IPXWrapper::Capture::IPXNovell; use IPXWrapper::Tool::IPXRecv; use IPXWrapper::Util; @@ -40,16 +41,11 @@ our $ptype_capture_class; my $node_c_net = "00:00:00:00"; -describe "IPXWrapper using Ethernet encapsulation" => sub +my $ipx_eth_capture_class; +my $ipx_eth_send_func; + +shared_examples_for "ipx over ethernet" => 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_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:00"); - }; - describe "unicast packets" => sub { they "are received" => sub @@ -59,7 +55,7 @@ describe "IPXWrapper using Ethernet encapsulation" => sub "00:00:00:00", $remote_mac_a, "4444", ); - send_ipx_packet($local_dev_a, + $ipx_eth_send_func->($local_dev_a, tc => 0, type => 0, @@ -94,7 +90,7 @@ describe "IPXWrapper using Ethernet encapsulation" => sub they "are transmitted" => sub { - my $capture = IPXWrapper::Capture::IPX->new($local_dev_a); + my $capture = $ipx_eth_capture_class->new($local_dev_a); run_remote_cmd( $remote_ip_a, "Z:\\tools\\ipx-send.exe", @@ -127,7 +123,7 @@ describe "IPXWrapper using Ethernet encapsulation" => sub { they "are transmitted by sockets with SO_BROADCAST" => sub { - my $capture = IPXWrapper::Capture::IPX->new($local_dev_a); + my $capture = $ipx_eth_capture_class->new($local_dev_a); run_remote_cmd( $remote_ip_a, "Z:\\tools\\ipx-send.exe", @@ -160,8 +156,8 @@ describe "IPXWrapper using Ethernet encapsulation" => sub they "are only transmitted on the bound interface (Network A)" => sub { - my $capture_a = IPXWrapper::Capture::IPX->new($local_dev_a); - my $capture_b = IPXWrapper::Capture::IPX->new($local_dev_b); + my $capture_a = $ipx_eth_capture_class->new($local_dev_a); + my $capture_b = $ipx_eth_capture_class->new($local_dev_b); run_remote_cmd( $remote_ip_a, "Z:\\tools\\ipx-send.exe", @@ -197,8 +193,8 @@ describe "IPXWrapper using Ethernet encapsulation" => sub they "are only transmitted on the bound interface (Network B)" => sub { - my $capture_a = IPXWrapper::Capture::IPX->new($local_dev_a); - my $capture_b = IPXWrapper::Capture::IPX->new($local_dev_b); + my $capture_a = $ipx_eth_capture_class->new($local_dev_a); + my $capture_b = $ipx_eth_capture_class->new($local_dev_b); run_remote_cmd( $remote_ip_a, "Z:\\tools\\ipx-send.exe", @@ -239,7 +235,7 @@ describe "IPXWrapper using Ethernet encapsulation" => sub "-b", "00:00:00:00", $remote_mac_a, "4444", ); - send_ipx_packet($local_dev_a, + $ipx_eth_send_func->($local_dev_a, tc => 0, type => 0, @@ -276,7 +272,7 @@ describe "IPXWrapper using Ethernet encapsulation" => sub "-b", "00:00:00:00", $remote_mac_b, "4444", ); - send_ipx_packet($local_dev_a, + $ipx_eth_send_func->($local_dev_a, tc => 0, type => 0, @@ -313,7 +309,7 @@ describe "IPXWrapper using Ethernet encapsulation" => sub "-b", "00:00:00:00", $remote_mac_a, "4444", ); - send_ipx_packet($local_dev_a, + $ipx_eth_send_func->($local_dev_a, tc => 0, type => 0, @@ -344,7 +340,7 @@ describe "IPXWrapper using Ethernet encapsulation" => sub "00:00:00:00", $remote_mac_a, "4444", ); - send_ipx_packet($local_dev_a, + $ipx_eth_send_func->($local_dev_a, tc => 0, type => 0, @@ -375,7 +371,7 @@ describe "IPXWrapper using Ethernet encapsulation" => sub "00:00:00:00", $remote_mac_a, "4444", ); - send_ipx_packet($local_dev_a, + $ipx_eth_send_func->($local_dev_a, tc => 0, type => 0, @@ -413,7 +409,7 @@ describe "IPXWrapper using Ethernet encapsulation" => sub "-r", "-b", "00:00:00:00", $remote_mac_a, "4444", ); - send_ipx_packet($local_dev_a, + $ipx_eth_send_func->($local_dev_a, tc => 0, type => 0, @@ -463,7 +459,7 @@ describe "IPXWrapper using Ethernet encapsulation" => sub "-r", "-b", "00:00:00:00", $remote_mac_a, "4444", ); - send_ipx_packet($local_dev_a, + $ipx_eth_send_func->($local_dev_a, tc => 0, type => 0, @@ -507,13 +503,13 @@ describe "IPXWrapper using Ethernet encapsulation" => sub before all => sub { - $ptype_capture_class = "IPXWrapper::Capture::IPX"; + $ptype_capture_class = $ipx_eth_capture_class; $ptype_send_func = sub { my ($type, $data) = @_; - send_ipx_packet($local_dev_a, + $ipx_eth_send_func->($local_dev_a, tc => 0, type => $type, @@ -533,4 +529,38 @@ describe "IPXWrapper using Ethernet encapsulation" => sub it_should_behave_like "ipx packet type handling"; }; +describe "IPXWrapper 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:00"); + + $ipx_eth_capture_class = "IPXWrapper::Capture::IPX"; + $ipx_eth_send_func = \&send_ipx_packet_ethernet; + }; + + it_should_behave_like "ipx over ethernet"; +}; + +describe "IPXWrapper 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:00"); + + $ipx_eth_capture_class = "IPXWrapper::Capture::IPXNovell"; + $ipx_eth_send_func = \&send_ipx_packet_novell; + }; + + it_should_behave_like "ipx over ethernet"; +}; + runtests unless caller; diff --git a/tests/lib/IPXWrapper/Capture/IPXNovell.pm b/tests/lib/IPXWrapper/Capture/IPXNovell.pm new file mode 100644 index 0000000..bd5cbf6 --- /dev/null +++ b/tests/lib/IPXWrapper/Capture/IPXNovell.pm @@ -0,0 +1,81 @@ +# IPXWrapper test suite +# Copyright (C) 2016 Daniel Collins +# +# 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; + +package IPXWrapper::Capture::IPXNovell; + +use Net::Pcap; +use NetPacket::Ethernet; +use NetPacket::IPX; + +sub new +{ + my ($class, $dev) = @_; + + my $err; + my $pcap = Net::Pcap::pcap_open_live($dev, 1500, 0, 1, \$err) + or die("Cannot open device $dev: $err"); + + return bless(\$pcap, $class); +} + +sub read_available +{ + my ($self) = @_; + + my @packets = (); + + Net::Pcap::pcap_dispatch($$self, -1, sub + { + my ($user_data, $header, $packet) = @_; + + my $ether = NetPacket::Ethernet->decode($packet); + + if($ether->{type} <= 1500 && substr($ether->{data}, 0, 2) eq "\x{FF}\x{FF}") + { + my $ipx = NetPacket::IPX->decode($ether->{data}); + + my %packet = ( + src_mac => $ether->{src_mac}, + dst_mac => $ether->{dest_mac}, + + tc => $ipx->{tc}, + type => $ipx->{type}, + + src_network => $ipx->{src_network}, + src_node => $ipx->{src_node}, + src_socket => $ipx->{src_socket}, + + dst_network => $ipx->{dest_network}, + dst_node => $ipx->{dest_node}, + dst_socket => $ipx->{dest_socket}, + + data => $ipx->{data}, + ); + + # Skip if the frame length is wrong. + return if(($ether->{type} - 30) != length($packet{data})); + + push(@packets, \%packet); + } + }, undef); + + return @packets; +} + +1; diff --git a/tests/lib/IPXWrapper/Util.pm b/tests/lib/IPXWrapper/Util.pm index 6f26c36..ba4a2b6 100644 --- a/tests/lib/IPXWrapper/Util.pm +++ b/tests/lib/IPXWrapper/Util.pm @@ -1,5 +1,5 @@ # IPXWrapper test suite -# Copyright (C) 2014 Daniel Collins +# Copyright (C) 2014-2017 Daniel Collins # # 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 @@ -30,7 +30,8 @@ our @EXPORT = qw( reg_delete_value send_ipx_over_udp - send_ipx_packet + send_ipx_packet_ethernet + send_ipx_packet_novell cmp_hashes_partial @@ -134,7 +135,7 @@ sub _send_ethernet_frame or die("Couldn't transmit frame on device $dev"); } -sub send_ipx_packet +sub send_ipx_packet_ethernet { my ($dev, %options) = @_; @@ -145,6 +146,18 @@ sub send_ipx_packet $packet->encode()); } +sub send_ipx_packet_novell +{ + my ($dev, %options) = @_; + + my $packet = NetPacket::IPX->new(%options); + my $enc_packet = $packet->encode(); + + _send_ethernet_frame($dev, + $packet->{dest_node}, $packet->{src_node}, length($enc_packet), + $enc_packet); +} + sub cmp_hashes_partial { my ($got, $expect) = @_;