#!/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"); } #### sudo ./sendPacket.pl -v 4 -t tcp -s 192.168.1.93 -i eth0 -p 25 -d 192.168.1.90 #### sudo ./sendPacket.pl -v 6 -t tcp -s fe80::21c:23ff:fefe:5b7e -i eth0 -p 25 -d fe80::2b0:d0ff:fe7b:bcae