I made the changes as you suggested. My XS file now reads:
int
libnet_init_packet(p_size, buf)
size_t p_size
u_char * & buf
OUTPUT:
buf
I also did the same thing for libnet_destory_packet(). It now compiles as I hoped it would, but I get a memory fault when I run this test script:
# Before `make install' is performed this script should be runnable wi
+th
# `make test'. After `make install' it should work as `perl test.pl'
######################### We start with some black magic to print on f
+ailure.
# Change 1..1 below to 1..last_test_to_print .
# (It may become useful if the test is moved to ./t subdirectory.)
BEGIN { $| = 1; print "1..1\n"; }
END {print "not ok 1\n" unless $loaded;}
use Net::LibnetRaw;
$loaded = 1;
print "ok 1\n";
my $buf;
Net::LibnetRaw::libnet_init_packet(IP_H, $buf);
my $dip = Net::LibnetRaw::libnet_name_resolve("10.0.0.4", 1);
my $sip = Net::LibnetRaw::libnet_name_resolve("10.0.0.1", 1);
#my $sock = Net::LibnetRaw::libnet_open_raw_sock(IPPROTO_RAW);
Net::LibnetRaw::libnet_build_ip(ICMP_ECHO_H, 0, 12345, 0, 127, 0, $sip
+, $dip, undef, 0, $buf);
Net::LibnetRaw::libnet_write_ip($sock, $buf, IP_H + ICMP_ECHO_H);
Net::LibnetRaw::libnet_close_raw_sock($sock);
Net::LibnetRaw::libnet_destroy_packet($buf);
######################### End of black magic.
# Insert your test code below (better if it prints "ok 13"
# (correspondingly "not ok 13") depending on the success of chunk 13
# of the test code):
It appears that the error occurs when I call libnet_build_ip(). It seems pretty clear that there is an issue with the passage and management of buf. Buf is supposed to come back out by reference here. My XSUB for libnet_build_ip() is:
int
libnet_build_ip(len, tos, id, frag, ttl, prot, saddr, daddr, payload,
+payload_s, buf)
u_short len
u_char tos
u_short id
u_short frag
u_char ttl
u_char prot
u_long saddr
u_long daddr
const u_char * payload
int payload_s
u_char & buf
OUTPUT:
buf
It is appropriate for the function prototype. buf is not passed as a C "u_char **" like with libnet_init_packet(). buf should be holding a C pointer to the meory location allocated by libnet_packet_init(), which is basically a wrapper to malloc() which passed the buf back by reference.
My guess is that there is some issue related to storing a pointer to a memory location used in C in a perl reference. If my guess is correction, how do I work around this? If not, then what the hell am I doing wrong? I've considered writing additional C code to simply allow $buf to hold a number which would act sort of like a "buffer descriptor" ala UNIX file I/O and keep the pointers in perl, but I really want to do as much of this in perl as possible.
Your solutions are greatly appreciated.
|