From 9d76f3ef00a8d563225047543eca609492bdd73f Mon Sep 17 00:00:00 2001 From: Daniel Collins Date: Wed, 29 Mar 2017 22:19:31 +0100 Subject: [PATCH] Extended end-to-end test suite to cover LLC encapsulation. --- manifest.src.txt | 2 + tests/30-eth-ipx.t | 18 ++++++ tests/lib/IPXWrapper/Capture/IPXLLC.pm | 81 ++++++++++++++++++++++++++ tests/lib/IPXWrapper/Util.pm | 16 +++++ 4 files changed, 117 insertions(+) create mode 100644 tests/lib/IPXWrapper/Capture/IPXLLC.pm diff --git a/manifest.src.txt b/manifest.src.txt index 4e41654..fae5d1d 100644 --- a/manifest.src.txt +++ b/manifest.src.txt @@ -73,6 +73,8 @@ tests/ethernet.c tests/ptype.pm tests/lib/IPXWrapper/Capture/IPX.pm +tests/lib/IPXWrapper/Capture/IPXLLC.pm +tests/lib/IPXWrapper/Capture/IPXNovell.pm tests/lib/IPXWrapper/Capture/IPXOverUDP.pm tests/lib/IPXWrapper/SPX.pm tests/lib/IPXWrapper/Tool/Bind.pm diff --git a/tests/30-eth-ipx.t b/tests/30-eth-ipx.t index c3e6cf4..24a0da0 100644 --- a/tests/30-eth-ipx.t +++ b/tests/30-eth-ipx.t @@ -23,6 +23,7 @@ use FindBin; use lib "$FindBin::Bin/lib/"; use IPXWrapper::Capture::IPX; +use IPXWrapper::Capture::IPXLLC; use IPXWrapper::Capture::IPXNovell; use IPXWrapper::Tool::IPXRecv; use IPXWrapper::Util; @@ -563,4 +564,21 @@ describe "IPXWrapper using Novell Ethernet encapsulation" => sub it_should_behave_like "ipx over ethernet"; }; +describe "IPXWrapper 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:00"); + + $ipx_eth_capture_class = "IPXWrapper::Capture::IPXLLC"; + $ipx_eth_send_func = \&send_ipx_packet_llc; + }; + + it_should_behave_like "ipx over ethernet"; +}; + runtests unless caller; diff --git a/tests/lib/IPXWrapper/Capture/IPXLLC.pm b/tests/lib/IPXWrapper/Capture/IPXLLC.pm new file mode 100644 index 0000000..a7f2607 --- /dev/null +++ b/tests/lib/IPXWrapper/Capture/IPXLLC.pm @@ -0,0 +1,81 @@ +# IPXWrapper test suite +# Copyright (C) 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 +# 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::IPXLLC; + +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, 5) eq "\x{E0}\x{E0}\x{03}\x{FF}\x{FF}") + { + my $ipx = NetPacket::IPX->decode(substr($ether->{data}, 3)); + + 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} - 33) != 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 ba4a2b6..cfd8f3e 100644 --- a/tests/lib/IPXWrapper/Util.pm +++ b/tests/lib/IPXWrapper/Util.pm @@ -32,6 +32,7 @@ our @EXPORT = qw( send_ipx_over_udp send_ipx_packet_ethernet send_ipx_packet_novell + send_ipx_packet_llc cmp_hashes_partial @@ -158,6 +159,21 @@ sub send_ipx_packet_novell $enc_packet); } +sub send_ipx_packet_llc +{ + my ($dev, %options) = @_; + + my $packet = NetPacket::IPX->new(%options); + my $enc_packet = $packet->encode(); + + # Prefix IPX packet with LLC header + $enc_packet = pack("C3", 0xE0, 0xE0, 0x03).$enc_packet; + + _send_ethernet_frame($dev, + $packet->{dest_node}, $packet->{src_node}, length($enc_packet), + $enc_packet); +} + sub cmp_hashes_partial { my ($got, $expect) = @_;