#!/usr/bin/perl

# 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;
require 'getopts.pl';

Getopts('i:s:d:');
die "Usage $0 -i <interface> -d <dest host> -s <your host>"
unless ($opt_d && $opt_d && $opt_s);

$a = new Net::RawIP ({icmp =>{}});
$a->set({ip => {saddr => $opt_s, 
                daddr => $opt_d},
	 icmp => {type => 8, id => $$}
	 });  

$data = "\5".("\0" x 37);
$a->optset(ip => {type => [(7)],data =>[($data)] });

$device = $opt_i; 
$filt = "ip proto \\icmp and dst host $opt_s";
$size = 1500;
$tout = 30;
$pcap = $a->pcapinit($device,$filt,$size,$tout);
$i =0;

if(fork){
        loop $pcap,1,\&dmp,\@a; 
}
else{
     sleep 1;
     $a->set({icmp => {sequence => $i,data => timem()}});
     $a->send(1,1);
}

sub dmp{
  $a->bset(substr($_[2],14));
  $opt = ($a->optget(ip => {type => [(7)] } ))[2];
  $opt = substr($opt,2);
  @route = unpack("N9",$opt);
  $j = 0;
  for $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");
}
