#!/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