#!/usr/bin/perl
use strict;
use warnings;
# This script use IP option called "record route" for emulate traceroute.
# Unfortunately max size of ip options is only 40 bytes and we can see
# just 9 hops, other hops will be ignored ;(
use Net::RawIP;
use Getopt::Long qw(GetOptions);
my %opt;
GetOptions(\%opt, 'interface=s', 'source=s', 'dest=s');
die "Usage $0 --interface <interface> --dest <dest host> --source <your host>"
unless($opt{dest} && $opt{interface} && $opt{source});
my $rawip = Net::RawIP->new({icmp =>{}});
$rawip->set({
ip => {
saddr => $opt{source},
daddr => $opt{dest},
},
icmp => {
type => 8,
id => $$,
}
});
my $data = "\5".("\0" x 37);
$rawip->optset(ip => {
type => [(7)],
data => [($data)],
});
my $filt = "ip proto \\icmp and dst host $opt{source}";
my $size = 1500;
my $tout = 30;
my $pcap = $rawip->pcapinit($opt{interface}, $filt, $size, $tout);
my $i = 0;
my @a;
if (fork) {
loop $pcap,1, \&dmp, \@a;
}
else {
sleep 1;
$rawip->set({icmp => {sequence => $i,data => timem()}});
$rawip->send(1,1);
}
sub dmp {
$rawip->bset(substr($_[2],14));
my $opt = ($rawip->optget(ip => {type => [(7)] } ))[2];
$opt = substr($opt, 2);
my @route = unpack("N9", $opt);
my $j = 0;
for my $site (@route) {
last unless $site;
printf(" -> ") if $j;
printf("\n") if $j == 4;
printf("%u.%u.%u.%u", unpack("C4", pack("N", $site)));
$j++;
}
printf("\n");
}
syntax highlighted by Code2HTML, v. 0.9.1