#!/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 --dest --source " 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"); }