The following code is required to capture the route taken by a packet as it moves from the local router to destination router. It should print all the intermediate routers and its ip addresses. The code is given below. But the output doesn't list all the IP addresses. It shows only one router's IP. How can i modify the code so that it shows all the intermediate ip addresses? Please help me out. Thank you!
Input format: ./a.out (destination ip) (port no) (MAX_TTL) (max_probe)
The output what i got is something like this:
./a.out 68.71.216.176 80 10 2
tracing 68.71.216.176 with MAX_TTL 10 on to port 80 with 2 probes
1>192.168.1.1:80.....192.168.1.3:35410------------------->Time-to-live exceeded: Time-to-live exceeded on transit
1>192.168.1.1:80.....192.168.1.3:35410------------------->Time-to-live exceeded: Time-to-live exceeded on transit
2>192.168.1.1:80.....192.168.1.3:35410------------------->Time-to-live exceeded: Time-to-live exceeded on transit
2>192.168.1.1:80.....192.168.1.3:35410------------------->Time-to-live exceeded: Time-to-live exceeded on transit
3>192.168.1.1:80.....192.168.1.3:35410------------------->Time-to-live exceeded: Time-to-live exceeded on transit
3>192.168.1.1:80.....192.168.1.3:35410------------------->Time-to-live exceeded: Time-to-live exceeded on transit
4>192.168.1.1:80.....192.168.1.3:35410------------------->Time-to-live exceeded: Time-to-live exceeded on transit
4>192.168.1.1:80.....192.168.1.3:35410------------------->Time-to-live exceeded: Time-to-live exceeded on transit
5>192.168.1.1:80.....192.168.1.3:35410------------------->Time-to-live exceeded: Time-to-live exceeded on transit
5>192.168.1.1:80.....192.168.1.3:35410------------------->Time-to-live exceeded: Time-to-live exceeded on transit
6>192.168.1.1:80.....192.168.1.3:35410------------------->Time-to-live exceeded: Time-to-live exceeded on transit
6>192.168.1.1:80.....192.168.1.3:35410------------------->Time-to-live exceeded: Time-to-live exceeded on transit
7>192.168.1.1:80.....192.168.1.3:35410------------------->Time-to-live exceeded: Time-to-live exceeded on transit
7>192.168.1.1:80.....192.168.1.3:35410------------------->Time-to-live exceeded: Time-to-live exceeded on transit
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<errno.h>
#include<netinet/ip.h>
#include<pcap.h>
#include<signal.h>
#include<arpa/inet.h>
/*IP HEADER*/
struct ip_hdr
{
unsigned char ip_v:4, ip_hl:4;
unsigned char ip_tos;
unsigned short int ip_len;
unsigned short int ip_id;
unsigned short int ip_off;
unsigned char ip_ttl;
unsigned char ip_p;
unsigned short int ip_sum;
struct in_addr ip_src, ip_dst;
};
/*ICMP HEADER*/
struct icmp_hdr
{
unsigned char icmp_type;
unsigned char icmp_code;
unsigned short int icmp_chksum;
int icmo_nouse;
};
struct udp_hdr
{
unsigned short int udp_srcport;
unsigned short int udp_destport;
unsigned short int udp_len;
unsigned short int udp_chksum;
};
int sockfd1;
char *buf = "s",dst[INET_ADDRSTRLEN],src[INET_ADDRSTRLEN];
int ttl,max_ttl,max_probe,pac;
struct sockaddr_in servaddr;
pcap_t *handle;
unsigned short int port_now;
int Initiate_pcapsession();
void send_packets(int);
void parse(u_char *,const struct pcap_pkthdr *,const u_char *);
int main (int argc, char **argv)
{
int state;
unsigned short int port;
if (argc < 5)
{
printf ("\n USAGE ./a.out <d-IP> <port> <maxttl> <maxprobe>\n");
return 0;
}
port = atoi (argv[2]);
max_ttl = atoi (argv[3]);
max_probe = atoi (argv[4]);
printf ("tracing %s with MAX_TTL %d on to port %u with %d probes\n", argv[1], max_ttl, port, max_probe);
servaddr.sin_family = AF_INET;
if (inet_pton (AF_INET, argv[1], &servaddr.sin_addr) < 0)
{
perror ("\tspecified address is invalid:progrm terminates:inet_pton");
return 0;
}
if ((sockfd1 = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
perror ("Error creating Socket:socket");
return 0;
}
if((state=Initiate_pcapsession())==-1)
{
printf("\nCoudnt create a Packet capture session:TERMINATING");
return 0;
}
for (ttl = 1; ttl <= max_ttl; ttl++)
{
port_now=htons(port + ttl -1);
//printf("\n%d>",ttl);
servaddr.sin_port = port_now;
send_packets (ttl);
}
pcap_close(handle);
close (sockfd1);
return 0;
}
int Initiate_pcapsession()
{
int state;
char *dev;
char errbuf[PCAP_ERRBUF_SIZE];
struct bpf_program fp;
char filter_exp[]="icmp and (icmp[0] = 11 and icmp[1] = 0) or (icmp[0] = 3 and icmp[1] = 3)";
bpf_u_int32 mask,net;
if((dev=pcap_lookupdev(errbuf))==NULL)
{
printf("\nCoudnt find default device: %s\n",errbuf);
return -1;
}
// else
// printf("\nFound default device %s ",dev);
if (pcap_lookupnet ("wlan0", &net, &mask, errbuf) == -1)
{
printf ("\nCoudn't get the netmask for device %s:%s\n", "wlan0", errbuf);
return -1;
}
if ((handle = pcap_open_live ("wlan0", BUFSIZ, 1, 270000, errbuf)) == NULL)
{
printf ("\nCoudn't open device %s:%s","wlan0", errbuf);
return -1;
}
if((state=pcap_setnonblock(handle, 1, errbuf))==-1)
{
printf("\nCoudn't set capture descriptor to non-blocking mode :%s",errbuf);
return -1;
}
if (pcap_compile (handle, &fp, filter_exp, 0, net) == -1)
{
printf ("\nCoudn't parse filter %s:%s", filter_exp, pcap_geterr (handle));
return -1;
}
if (pcap_setfilter (handle, &fp) == -1)
{
printf ("\nCoudn't install filter %s:%s\n", filter_exp, pcap_geterr (handle));
return -1;
}
return 1;
}
void send_packets( int ttl_now)
{
pid_t pid;
int p,num,status;
setsockopt (sockfd1, IPPROTO_IP, IP_TTL, &ttl_now, sizeof (ttl_now));
for(p=1;p<=max_probe;p++)
{
if ((sendto(sockfd1, buf, sizeof (buf), 0, (struct sockaddr *) &servaddr,sizeof (servaddr))) == -1)
{
perror ("sendto");
}
else
{
pac+=1;
//printf("\n\t\tSENT PACKET %d",pac);
if((pid=fork())<0)
{
perror("fork");
exit(0);
}
if(pid==0)
{
num=pcap_loop(handle,-1,parse,NULL);
if(num)
printf("\npcap_dispatch:%d packets captured",num);
else
printf("\npcap_dispatch:No pcakets captured");
}
else
{
sleep(1);
//wait(&status);
kill(pid,SIGSTOP);
}
}
}
}
void parse(u_char *args,const struct pcap_pkthdr *header,const u_char *packet)
{
struct ip_hdr *ip1 = (struct ip_hdr *) (packet + 14); /*initialising ip pointer beyond the sll protocol header 16 bytes */
struct icmp_hdr *icmp = (struct icmp_hdr *) (packet + 14 + sizeof (struct ip_hdr));
struct ip_hdr *ip2 = (struct ip_hdr *) (packet + 14 + sizeof (struct ip_hdr) + sizeof (struct icmp_hdr));
struct udp_hdr *udp = (struct udp_hdr *) (packet + 14 + sizeof (struct ip_hdr) + sizeof (struct icmp_hdr) + sizeof (struct ip_hdr));
//if (ntohs (udp->udp_destport) == ntohs (port_now))
//{
inet_ntop (AF_INET, &ip1->ip_dst, dst, 16);
inet_ntop (AF_INET, &ip1->ip_src, src, 16);
printf ("\n\t%d>%s:%u.....%s:%u------------------->",ttl, src,ntohs (udp->udp_destport), dst,ntohs (udp->udp_srcport));
if(icmp->icmp_code==0)
printf("Time-to-live exceeded: Time-to-live exceeded on transit\n");
else if(icmp->icmp_code==3)
printf("Destination unreachable: Port unreachable\n");
//}
exit(0);
}