bpa has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

I recently posted with some issues getting the Net::Packet module and some of its dependencies installed on my Ubuntu 8.04 box. The monks were very helpful and with their help, I quickly resoved my installation issues. I am hoping someone can help me with this as well. I am using Net::Packet-3.26 on kernel 2.6.24-20.

The reason I tried the install on Ubuntu was because I was having problems sending out IPv6 packets on Slackware, but Ubuntu is giving me the exact error which is:

UPDATE: Sorry, I uncommented the initialization of $env and reposted the output.
addr_net: undef input env->ip6: ::1 Env->ip6: ::1 NP_IPv6_PROTOCOL_TCP: 6 Use of uninitialized value in socket at /usr/local/share/perl/5.8.8/Ne +t/Write/Layer.pm line 171. Net::Write::Layer::open: socket: Address family not supported by proto +col at /usr/local/share/perl/5.8.8/Net/Packet/DescL3.pm line 86


Here is my code:

#!/usr/bin/perl # Author: Barret Miller # Date: 07/14/08 (date of E3 gaming conference!) # This program will send either a UDP or TCP packet with a faked # source address to a destination address for IPv4 or IPv6 use Switch; use Net::Packet::Env qw($Env); use Net::Packet::Consts qw(:ipv6); require Net::Packet::Frame; require Net::Packet::DescL3; require Net::Packet::Dump; require Net::Packet::IPv4; require Net::Packet::IPv6; require Net::Packet::UDP; require Net::Packet::TCP; my $transport; my $port; my $version; my $ip; my $l4; my $srcAddr; my $dstAddr; my $if; handleArgs(@ARGV); my $env = Net::Packet::Env->new(dev => $if); print("env->ip6: " . $Env->ip6 . "\n"); print("Env->ip6: " . $Env->ip6 . "\n"); print("NP_IPv6_PROTOCOL_TCP: " . NP_IPv6_PROTOCOL_TCP . "\n"); #my $desc = Net::Packet::DescL3->new( # target => '192.168.1.99', #); my $dump = Net::Packet::Dump->new( keepTimestamp => 1, env => $env, ); $dump->start; my $d3 = Net::Packet::DescL3->new( dev => 'wlan0', target => '::1', ); # Build network layer header (ip4 or ip6) # defualts to ip4 if($version eq '6') { $ip = Net::Packet::IPv6->new( src => '::1', dst => '::1', nextHeader => NP_IPv6_PROTOCOL_TCP, ); } else { $ip = Net::Packet::IPv4->new( src => $srcAddr, dst => $dstAddr, ); } # Build a transport layer header # defaults to tcp if($transport eq 'udp') { $l4 = Net::Packet::UDP->new( dst => $port, ); } else { $l4 = Net::Packet::TCP->new( dst => $port, ); } # Assemble a frame my $frame = Net::Packet::Frame->new( l3 => $ip, l4 => $l4, ); $frame->send; # Note: if you have faked your address, don't expect a # reply! if($transport eq 'tcp') { until($dump->timeout) { if($frame->recv) { print $frame->reply->l3, "\n"; print $frame->reply->l4, "\n"; last; } } } # clean up crap files $dump->stop; $dump->clean; # Handle command line args sub handleArgs { my @args = @_; my $argsLength = @args; if($argsLength < 6) { printUsage(); die "Incorrect arguments\n"; } else { for(my $i = 0; $i < $argsLength; $i++) { my $arg = $args[$i]; switch($arg) { # Port to send to case "-p" { $port = $args[$i + 1]; $i++; } # IP version number case "-v" { $version = $args[$i + 1]; $i++; } # transport layer protocol case "-t" { $l4 = $args[$i + 1]; $i++; } case "-s" { $srcAddr = $args[$i + 1]; $i++; } case "-d" { $dstAddr = $args[$i + 1]; $i++; } case "-i" { $if = $args[$i + 1]; $i++; } else { printUsage(); } } } } } sub printUsage { print("USAGE: \n" . "sendPacket [-v 4|6] [-t tcp|udp] [-s srcAddr]\n" . "-i iface -p dstPort -d dstAddr\n"); }


I have no problem sending out an IPv4 packet, and when sniffing the network, this module has no problem disecting IPv6 packets, but I am begining to wonder if it is possible to inject IPv6 packets to the network.

Any help is greatly appreciated.

Barret

Replies are listed 'Best First'.
Re: Problem Sending an IPv6 Packet with Net::Packet Module
by Anonymous Monk on Jul 24, 2008 at 03:58 UTC
    Did you run the test suite ? What did you get?
      Hi, sorry for the long time it has taken me to respond since you posted, but thank you. I'm not sure what you mean by the test suite. I did attempt to run the ip6-syn-send.pl example program that came with the Net::Packet module, and it executes without error as my script does now, but I can't pick up anything when sniffing the interface. With my program I can send IPv4 packets just fine and I can sniff them on the source and receiving host, but no such luck with an IPv6 packet.

      I do thank you for your suggestion because when I looked into the ip6-syn-send.pl sample script to see why it was not getting any error message, I saw that it was creating a layer 2 eth object explicitly and giving it a destination mac address. Once I created this object in my code, and included it when creating the frame object, that got rid of my error. However, like I said I still cannot see any IPv6 frames traversing the wire despite the lack of error messages. Here is my updated code:
      #!/usr/bin/perl # This program will send either a UDP or TCP packet with a faked # source address to a destination address for IPv4 or IPv6 use strict; use warnings; use Switch; use Net::Packet::Env qw($Env); use Net::Packet::Consts qw(:ipv6 :eth); require Net::Packet::Frame; require Net::Packet::DescL3; require Net::Packet::Dump; require Net::Packet::IPv4; require Net::Packet::IPv6; require Net::Packet::UDP; require Net::Packet::TCP; require Net::Packet::ETH; my $transport; my $port; my $version; my $eth; my $ip; my $l4; my $frame; my $srcAddr; my $dstAddr; my $if; handleArgs(@ARGV); printEnv(); my $env = Net::Packet::Env->new(dev => $if); my $dump = Net::Packet::Dump->new( keepTimestamp => 1, env => $env, ); $dump->start; # Build network layer header (ip4 or ip6) # defualts to ip4 if($version eq '6') { $eth = Net::Packet::ETH->new( type => NP_ETH_TYPE_IPv6, dst => '00:B0:D0:7B:BC:AE', ); $ip = Net::Packet::IPv6->new( src => $srcAddr, dst => $dstAddr, ); } else { $ip = Net::Packet::IPv4->new( src => $srcAddr, dst => $dstAddr, ); } # Build a transport layer header # defaults to tcp if($transport eq 'udp') { $l4 = Net::Packet::UDP->new( dst => $port, ); } else { $l4 = Net::Packet::TCP->new( dst => $port, ); } # Assemble a frame if($version eq '6') { $frame = Net::Packet::Frame->new( l2 => $eth, l3 => $ip, l4 => $l4, ); } else { $frame = Net::Packet::Frame->new( l3 => $ip, l4 => $l4, ); } $frame->send; # Note: if you have faked your address, don't expect a # reply! if($transport eq 'tcp') { until($dump->timeout) { if($frame->recv) { print $frame->reply->l3, "\n"; print $frame->reply->l4, "\n"; last; } } } # clean up crap files $dump->stop; $dump->clean; # Handle command line args sub handleArgs { my @args = @_; my $argsLength = @args; if($argsLength < 6) { printUsage(); die "Incorrect arguments\n"; } else { for(my $i = 0; $i < $argsLength; $i++) { my $arg = $args[$i]; switch($arg) { # Port to send to case "-p" { $port = $args[$i + 1]; $i++; } # IP version number case "-v" { $version = $args[$i + 1]; $i++; } # transport layer protocol case "-t" { $transport = $args[$i + 1]; $i++; } case "-s" { $srcAddr = $args[$i + 1]; $i++; } case "-d" { $dstAddr = $args[$i + 1]; $i++; } case "-i" { $if = $args[$i + 1]; $i++; } else { printUsage(); } } } } } sub printUsage { print("USAGE: \n" . "sendPacket [-v 4|6] [-t tcp|udp] [-s srcAddr]\n" . "-i iface -p dstPort -d dstAddr\n"); } sub printEnv { print("transport: $transport\n"); print("port: $port\n"); print("version: $version\n"); print("srcAddr: $srcAddr\n"); print("dstAddr: $dstAddr\n"); print("if: $if\n"); }


      To send an IPv4 tcp packet:
      sudo ./sendPacket.pl -v 4 -t tcp -s 192.168.1.93 -i eth0 -p 25 -d 192. +168.1.90


      To send an IPv6 tcp packet:
      sudo ./sendPacket.pl -v 6 -t tcp -s fe80::21c:23ff:fefe:5b7e -i eth0 - +p 25 -d fe80::2b0:d0ff:fe7b:bcae


      Obviously change the source and destination addresses to something relevant to your setup and only have to use sudo on Ubuntu. Thanks for any help.