/usr/share/doc/libnet-rawip-perl/examples/traceroute is in libnet-rawip-perl 0.25-2build2.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | #!/usr/bin/perl
# Has been created by ShaD0w <mci@gw.al.lg.ua>
# This is free software; you can redistribute it and/or modify it under the
# same terms as Perl itself.
# Look at user configurable section for set defaults
use Net::RawIP qw(:pcap);
use Socket;
require 'getopts.pl';
Getopts('m:q:w:t:h');
$|=1;
$dest = $opt_t;
if ($opt_h || !$opt_t){
print "Usage $0 [ -h ] [-w timeout(sec)] [-q nqueries] [-m max_ttl] -t host\n ";
exit
}
$max_ttl = ($opt_m ? $opt_m : 30);
$n_pakets = ($opt_q ? $opt_q : 3);
$timeout = ($opt_w ? $opt_w: 5);
($name,$ip) = (gethostbyname($dest))[0,4];
die "$dest: host not found" if $?;
#############
# User configurable section
# If rdev and ifaddrlist functions are not implemented
# $dev='eth0'; # set your device
# $ip_addr = 'amk.lan'; # set your ip address
# The rdev and ifaddrlist functions are implemented (auto)
$dev = rdev($dest);
$ip_addr = ${ifaddrlist()}{$dev};
#############
print "traceroute to $name (";
printf ("%u.%u.%u.%u",unpack("C4",$ip));
print ") , $max_ttl hops max, 40 byte packets\n";
srand();
$packet = new Net::RawIP({udp=>{}});
$icmp = new Net::RawIP({icmp=>{}});
$udp = new Net::RawIP({udp=>{}});
$filt="ip proto \\icmp and dst host $ip_addr and (icmp[0]==3 or icmp[0]==11)";
$pcap = $packet->pcapinit($dev,$filt,1500,60);
$offset = linkoffset($pcap);
$packet->set({ip=> {saddr=>$ip_addr, daddr=>$dest, frag_off=>0,
tos=>0, id=>$$},
udp=> {data=>'a'x12}});
for($i=1;$i<=$max_ttl;$i++){
print "$i. ";
$printed = 0;
for($np=0;$np<$n_pakets;$np++){
$gen=10000+int(rand(1000));
$packet->set({ip=>{ttl=>$i},udp=>{source=>$gen, dest=>$gen+1}});
undef($ipacket);
$packet->send();
$stime = timem();
$drop = 1;
do {
$end = 1 if($p_type==3);
$p_addr=$p_type=$p_code=0;
$ipacket = &next($pcap,$temp);
$etime=timem();
if($ipacket) {
$icmp->bset(substr($ipacket,$offset));
($addr,$type,$code,$data) = $icmp->get({ip=>['saddr'],icmp=>['type','code','data']});
$udp->bset($data);
($sign) = $udp->get({udp=>['source']});
if($sign eq $gen){
$drop = 0;
($p_addr, $p_type, $p_code) = ($addr, $type, $code);
}
}
} while((($etime-$stime)<$timeout) && $drop);
unless(($etime-$stime)<$timeout){
print "* ";
next;
}
$dtime = ($etime-$stime);
unless($printed){
print ip2name($p_addr), " (",ip2dot($p_addr), ") ",destun($type,$p_code) ? rtt_ms($dtime):cod2name($dtime,$p_code);
$printed = 1;
} else {
print " ",destun($type,$p_code) ? rtt_ms($dtime):cod2name($dtime,$p_code);
}
}
print "\n";
exit if $end;
}
sub ip2dot {
sprintf("%u.%u.%u.%u",unpack "C4", pack "N1", shift);
}
sub ip2name {
my $addr = shift;
(gethostbyaddr(pack("N",$addr),AF_INET))[0] || ip2dot($addr);
}
sub rtt_ms {
sprintf("%.2f ms", 1000*shift);
}
sub cod2name {
my @str = qw( !N !H !P 0 !F !S);
return rtt_ms($_[0])." ".$str[$_[1]];
}
sub destun {
$_[0]!=3 || ($_[0]==3 && $_[1] == 3)
}
|