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:
parent
b58ef3eb1e
commit
ba7fa5a77f
@ -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)
|
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
|
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 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OVERHEAD + ipx_payload_len;
|
return sizeof(ethernet_header)
|
||||||
|
+ sizeof(novell_ipx_packet)
|
||||||
|
+ ipx_payload_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void novell_frame_pack(void *frame_buffer,
|
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)
|
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
|
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 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,
|
void llc_frame_pack(void *frame_buffer,
|
||||||
|
@ -44,6 +44,7 @@ my $node_c_net = "00:00:00:00";
|
|||||||
|
|
||||||
my $ipx_eth_capture_class;
|
my $ipx_eth_capture_class;
|
||||||
my $ipx_eth_send_func;
|
my $ipx_eth_send_func;
|
||||||
|
my $max_payload_size;
|
||||||
|
|
||||||
shared_examples_for "ipx over ethernet" => sub
|
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
|
before all => sub
|
||||||
{
|
{
|
||||||
$ptype_capture_class = $ipx_eth_capture_class;
|
$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_capture_class = "IPXWrapper::Capture::IPX";
|
||||||
$ipx_eth_send_func = \&send_ipx_packet_ethernet;
|
$ipx_eth_send_func = \&send_ipx_packet_ethernet;
|
||||||
|
$max_payload_size = 1470;
|
||||||
};
|
};
|
||||||
|
|
||||||
it_should_behave_like "ipx over ethernet";
|
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_capture_class = "IPXWrapper::Capture::IPXNovell";
|
||||||
$ipx_eth_send_func = \&send_ipx_packet_novell;
|
$ipx_eth_send_func = \&send_ipx_packet_novell;
|
||||||
|
$max_payload_size = 1470;
|
||||||
};
|
};
|
||||||
|
|
||||||
it_should_behave_like "ipx over ethernet";
|
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_capture_class = "IPXWrapper::Capture::IPXLLC";
|
||||||
$ipx_eth_send_func = \&send_ipx_packet_llc;
|
$ipx_eth_send_func = \&send_ipx_packet_llc;
|
||||||
|
$max_payload_size = 1467;
|
||||||
};
|
};
|
||||||
|
|
||||||
it_should_behave_like "ipx over ethernet";
|
it_should_behave_like "ipx over ethernet";
|
||||||
|
@ -241,8 +241,8 @@ int main()
|
|||||||
|
|
||||||
CHECK_FRAME_SIZE(novell_frame_size, 0, 44);
|
CHECK_FRAME_SIZE(novell_frame_size, 0, 44);
|
||||||
CHECK_FRAME_SIZE(novell_frame_size, 50, 94);
|
CHECK_FRAME_SIZE(novell_frame_size, 50, 94);
|
||||||
CHECK_FRAME_SIZE(novell_frame_size, 1456, 1500);
|
CHECK_FRAME_SIZE(novell_frame_size, 1470, 1514);
|
||||||
CHECK_FRAME_SIZE(novell_frame_size, 1457, 0);
|
CHECK_FRAME_SIZE(novell_frame_size, 1471, 0);
|
||||||
|
|
||||||
/* +===================+
|
/* +===================+
|
||||||
* | novell_frame_pack |
|
* | novell_frame_pack |
|
||||||
@ -510,8 +510,8 @@ int main()
|
|||||||
|
|
||||||
CHECK_FRAME_SIZE(llc_frame_size, 0, 47);
|
CHECK_FRAME_SIZE(llc_frame_size, 0, 47);
|
||||||
CHECK_FRAME_SIZE(llc_frame_size, 50, 97);
|
CHECK_FRAME_SIZE(llc_frame_size, 50, 97);
|
||||||
CHECK_FRAME_SIZE(llc_frame_size, 1453, 1500);
|
CHECK_FRAME_SIZE(llc_frame_size, 1467, 1514);
|
||||||
CHECK_FRAME_SIZE(llc_frame_size, 1454, 0);
|
CHECK_FRAME_SIZE(llc_frame_size, 1468, 0);
|
||||||
|
|
||||||
/* +================+
|
/* +================+
|
||||||
* | llc_frame_pack |
|
* | llc_frame_pack |
|
||||||
|
@ -28,7 +28,7 @@ sub new
|
|||||||
my ($class, $dev) = @_;
|
my ($class, $dev) = @_;
|
||||||
|
|
||||||
my $err;
|
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");
|
or die("Cannot open device $dev: $err");
|
||||||
|
|
||||||
return bless(\$pcap, $class);
|
return bless(\$pcap, $class);
|
||||||
|
@ -28,7 +28,7 @@ sub new
|
|||||||
my ($class, $dev) = @_;
|
my ($class, $dev) = @_;
|
||||||
|
|
||||||
my $err;
|
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");
|
or die("Cannot open device $dev: $err");
|
||||||
|
|
||||||
return bless(\$pcap, $class);
|
return bless(\$pcap, $class);
|
||||||
|
@ -28,7 +28,7 @@ sub new
|
|||||||
my ($class, $dev) = @_;
|
my ($class, $dev) = @_;
|
||||||
|
|
||||||
my $err;
|
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");
|
or die("Cannot open device $dev: $err");
|
||||||
|
|
||||||
return bless(\$pcap, $class);
|
return bless(\$pcap, $class);
|
||||||
|
@ -55,12 +55,14 @@ sub run_remote_cmd
|
|||||||
note(join(" ", @command));
|
note(join(" ", @command));
|
||||||
|
|
||||||
my $output = "";
|
my $output = "";
|
||||||
IPC::Run::run(\@command, ">&" => \$output)
|
my $ok = IPC::Run::run(\@command, ">&" => \$output);
|
||||||
or die("Failure running $exe_name:\n$output");
|
|
||||||
|
|
||||||
# Oh line endings, how do I hate thee? Let me count the ways.
|
# Oh line endings, how do I hate thee? Let me count the ways.
|
||||||
$output =~ s/\r//g;
|
$output =~ s/\r//g;
|
||||||
|
|
||||||
|
die("Failure running $exe_name:\n$output")
|
||||||
|
unless($ok);
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
const int MAX_SOCKETS = 32;
|
const int MAX_SOCKETS = 32;
|
||||||
const int BUFSIZE = 64;
|
const int BUFSIZE = 2048;
|
||||||
|
|
||||||
static void usage(const char *argv0)
|
static void usage(const char *argv0)
|
||||||
{
|
{
|
||||||
|
@ -43,7 +43,7 @@ int main(int argc, char **argv)
|
|||||||
BOOL reuse = FALSE;
|
BOOL reuse = FALSE;
|
||||||
|
|
||||||
int opt;
|
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')
|
if(opt == 'n')
|
||||||
{
|
{
|
||||||
@ -65,6 +65,13 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
data = optarg;
|
data = optarg;
|
||||||
}
|
}
|
||||||
|
else if(opt == 'l')
|
||||||
|
{
|
||||||
|
int len = atoi(optarg);
|
||||||
|
assert((data = malloc(len)) != NULL);
|
||||||
|
|
||||||
|
memset((char*)(data), 0xAA, len);
|
||||||
|
}
|
||||||
else if(opt == 'b')
|
else if(opt == 'b')
|
||||||
{
|
{
|
||||||
bcast = TRUE;
|
bcast = TRUE;
|
||||||
@ -87,6 +94,7 @@ int main(int argc, char **argv)
|
|||||||
"[-s <local socket number>]\n"
|
"[-s <local socket number>]\n"
|
||||||
"[-t <packet type>]\n"
|
"[-t <packet type>]\n"
|
||||||
"[-d <payload>]\n"
|
"[-d <payload>]\n"
|
||||||
|
"[-l <payload length>]\n"
|
||||||
"[-b (enable SO_BROADCAST)]\n"
|
"[-b (enable SO_BROADCAST)]\n"
|
||||||
"[-r (enable SO_REUSEADDR)]\n"
|
"[-r (enable SO_REUSEADDR)]\n"
|
||||||
"<remote network number>\n"
|
"<remote network number>\n"
|
||||||
@ -132,7 +140,14 @@ int main(int argc, char **argv)
|
|||||||
printf("Bound to local address: %s\n", formatted_addr);
|
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);
|
closesocket(sock);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user