1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
#!/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");
}
|