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

Allow sending Novell/LLC frames up to the maximum size.

This commit is contained in:
Daniel Collins 2017-08-20 22:59:49 +01:00
parent b58ef3eb1e
commit ba7fa5a77f
9 changed files with 132 additions and 25 deletions

View File

@ -154,17 +154,15 @@ bool ethII_frame_unpack(const novell_ipx_packet **packet, size_t *packet_len, co
size_t novell_frame_size(size_t ipx_payload_len)
{
static const size_t OVERHEAD
= sizeof(ethernet_header)
+ sizeof(novell_ipx_packet);
if(ipx_payload_len > NOVELL_IPX_PACKET_MAX_PAYLOAD
|| ipx_payload_len > (1500 - OVERHEAD))
|| ipx_payload_len > (1500 - sizeof(novell_ipx_packet)))
{
return 0;
}
return OVERHEAD + ipx_payload_len;
return sizeof(ethernet_header)
+ sizeof(novell_ipx_packet)
+ ipx_payload_len;
}
void novell_frame_pack(void *frame_buffer,
@ -224,18 +222,16 @@ bool novell_frame_unpack(const novell_ipx_packet **packet, size_t *packet_len, c
size_t llc_frame_size(size_t ipx_payload_len)
{
static const size_t OVERHEAD
= sizeof(ethernet_header)
+ sizeof(llc_header)
+ sizeof(novell_ipx_packet);
if(ipx_payload_len > NOVELL_IPX_PACKET_MAX_PAYLOAD
|| ipx_payload_len > (1500 - OVERHEAD))
|| ipx_payload_len > (1500 - (sizeof(llc_header) + sizeof(novell_ipx_packet))))
{
return 0;
}
return OVERHEAD + ipx_payload_len;
return sizeof(ethernet_header)
+ sizeof(llc_header)
+ sizeof(novell_ipx_packet)
+ ipx_payload_len;
}
void llc_frame_pack(void *frame_buffer,

View File

@ -44,6 +44,7 @@ my $node_c_net = "00:00:00:00";
my $ipx_eth_capture_class;
my $ipx_eth_send_func;
my $max_payload_size;
shared_examples_for "ipx over ethernet" => sub
{
@ -502,6 +503,96 @@ shared_examples_for "ipx over ethernet" => sub
};
};
it "can transmit the largest possible packet" => sub
{
my $capture = $ipx_eth_capture_class->new($local_dev_a);
run_remote_cmd(
$remote_ip_a, "Z:\\tools\\ipx-send.exe",
"-l" => $max_payload_size,
"-s" => "4324", "-h" => $remote_mac_a,
"00:00:00:01", $local_mac_a, "6789",
);
sleep(1);
my @packets = $capture->read_available();
cmp_hashes_partial(\@packets, [
{
src_network => "00:00:00:01",
src_node => $remote_mac_a,
src_socket => 4324,
dst_network => "00:00:00:01",
dst_node => $local_mac_a,
dst_socket => 6789,
data => (chr(0xAA) x $max_payload_size),
},
]);
};
it "refuses to transmit larger than the largest possible packet" => sub
{
my $capture = $ipx_eth_capture_class->new($local_dev_a);
trap {
run_remote_cmd(
$remote_ip_a, "Z:\\tools\\ipx-send.exe",
"-l" => $max_payload_size + 1,
"-s" => "1111", "-h" => $remote_mac_a,
"00:00:00:01", $local_mac_a, "2222",
);
};
sleep(1);
# Ensure sendto() failed with WSAEMSGSIZE
like($trap->die(), qr/^sendto: 10040$/m);
# Ensure no packets were transmitted.
my @packets = $capture->read_available();
cmp_hashes_partial(\@packets, []);
};
it "can receive the largest possible packet" => sub
{
my $capture = IPXWrapper::Tool::IPXRecv->new(
$remote_ip_a,
"00:00:00:00", $remote_mac_a, "3456",
);
$ipx_eth_send_func->($local_dev_a,
tc => 0,
type => 0,
dest_network => "00:00:00:01",
dest_node => $remote_mac_a,
dest_socket => 3456,
src_network => "00:00:00:01",
src_node => $local_mac_a,
src_socket => 4567,
data => ("x" x $max_payload_size),
);
sleep(1);
my @packets = $capture->kill_and_read();
cmp_hashes_partial(\@packets, [
{
src_network => "00:00:00:01",
src_node => $local_mac_a,
src_socket => 4567,
data => ("x" x $max_payload_size),
},
]);
};
before all => sub
{
$ptype_capture_class = $ipx_eth_capture_class;
@ -542,6 +633,7 @@ describe "IPXWrapper using Ethernet encapsulation" => sub
$ipx_eth_capture_class = "IPXWrapper::Capture::IPX";
$ipx_eth_send_func = \&send_ipx_packet_ethernet;
$max_payload_size = 1470;
};
it_should_behave_like "ipx over ethernet";
@ -559,6 +651,7 @@ describe "IPXWrapper using Novell Ethernet encapsulation" => sub
$ipx_eth_capture_class = "IPXWrapper::Capture::IPXNovell";
$ipx_eth_send_func = \&send_ipx_packet_novell;
$max_payload_size = 1470;
};
it_should_behave_like "ipx over ethernet";
@ -576,6 +669,7 @@ describe "IPXWrapper using LLC (802.2) Ethernet encapsulation" => sub
$ipx_eth_capture_class = "IPXWrapper::Capture::IPXLLC";
$ipx_eth_send_func = \&send_ipx_packet_llc;
$max_payload_size = 1467;
};
it_should_behave_like "ipx over ethernet";

View File

@ -241,8 +241,8 @@ int main()
CHECK_FRAME_SIZE(novell_frame_size, 0, 44);
CHECK_FRAME_SIZE(novell_frame_size, 50, 94);
CHECK_FRAME_SIZE(novell_frame_size, 1456, 1500);
CHECK_FRAME_SIZE(novell_frame_size, 1457, 0);
CHECK_FRAME_SIZE(novell_frame_size, 1470, 1514);
CHECK_FRAME_SIZE(novell_frame_size, 1471, 0);
/* +===================+
* | novell_frame_pack |
@ -510,8 +510,8 @@ int main()
CHECK_FRAME_SIZE(llc_frame_size, 0, 47);
CHECK_FRAME_SIZE(llc_frame_size, 50, 97);
CHECK_FRAME_SIZE(llc_frame_size, 1453, 1500);
CHECK_FRAME_SIZE(llc_frame_size, 1454, 0);
CHECK_FRAME_SIZE(llc_frame_size, 1467, 1514);
CHECK_FRAME_SIZE(llc_frame_size, 1468, 0);
/* +================+
* | llc_frame_pack |

View File

@ -28,7 +28,7 @@ sub new
my ($class, $dev) = @_;
my $err;
my $pcap = Net::Pcap::pcap_open_live($dev, 1500, 0, 1, \$err)
my $pcap = Net::Pcap::pcap_open_live($dev, 2000, 0, 1, \$err)
or die("Cannot open device $dev: $err");
return bless(\$pcap, $class);

View File

@ -28,7 +28,7 @@ sub new
my ($class, $dev) = @_;
my $err;
my $pcap = Net::Pcap::pcap_open_live($dev, 1500, 0, 1, \$err)
my $pcap = Net::Pcap::pcap_open_live($dev, 2000, 0, 1, \$err)
or die("Cannot open device $dev: $err");
return bless(\$pcap, $class);

View File

@ -28,7 +28,7 @@ sub new
my ($class, $dev) = @_;
my $err;
my $pcap = Net::Pcap::pcap_open_live($dev, 1500, 0, 1, \$err)
my $pcap = Net::Pcap::pcap_open_live($dev, 2000, 0, 1, \$err)
or die("Cannot open device $dev: $err");
return bless(\$pcap, $class);

View File

@ -55,12 +55,14 @@ sub run_remote_cmd
note(join(" ", @command));
my $output = "";
IPC::Run::run(\@command, ">&" => \$output)
or die("Failure running $exe_name:\n$output");
my $ok = IPC::Run::run(\@command, ">&" => \$output);
# Oh line endings, how do I hate thee? Let me count the ways.
$output =~ s/\r//g;
die("Failure running $exe_name:\n$output")
unless($ok);
return $output;
}

View File

@ -28,7 +28,7 @@
#include "tools.h"
const int MAX_SOCKETS = 32;
const int BUFSIZE = 64;
const int BUFSIZE = 2048;
static void usage(const char *argv0)
{

View File

@ -43,7 +43,7 @@ int main(int argc, char **argv)
BOOL reuse = FALSE;
int opt;
while((opt = getopt(argc, argv, "n:h:s:t:d:br")) != -1)
while((opt = getopt(argc, argv, "n:h:s:t:d:l:br")) != -1)
{
if(opt == 'n')
{
@ -65,6 +65,13 @@ int main(int argc, char **argv)
{
data = optarg;
}
else if(opt == 'l')
{
int len = atoi(optarg);
assert((data = malloc(len)) != NULL);
memset((char*)(data), 0xAA, len);
}
else if(opt == 'b')
{
bcast = TRUE;
@ -87,6 +94,7 @@ int main(int argc, char **argv)
"[-s <local socket number>]\n"
"[-t <packet type>]\n"
"[-d <payload>]\n"
"[-l <payload length>]\n"
"[-b (enable SO_BROADCAST)]\n"
"[-r (enable SO_REUSEADDR)]\n"
"<remote network number>\n"
@ -132,7 +140,14 @@ int main(int argc, char **argv)
printf("Bound to local address: %s\n", formatted_addr);
}
assert(sendto(sock, data, strlen(data), 0, (struct sockaddr*)(&remote_addr), sizeof(remote_addr)) == strlen(data));
int sr = sendto(sock, data, strlen(data), 0, (struct sockaddr*)(&remote_addr), sizeof(remote_addr));
if(sr == -1)
{
fprintf(stderr, "sendto: %u\n", (unsigned int)(WSAGetLastError()));
return 1;
}
assert(sr == strlen(data));
closesocket(sock);