当数据包从本地路由器移动到目标路由器时,需要以下代码来捕获数据包所采用的路由。它应该打印所有中间路由器及其IP地址。代码如下。但输出未列出所有IP地址。它只显示一个路由器的IP。如何修改代码以便显示所有中间IP地址?请帮帮我。谢谢!
输入格式:./a.out (destination ip) (port no) (MAX_TTL) (max_probe)
输出我得到的是这样的:
./a.out 68.71.216.176 80 10 2
使用MAX_TTL 10跟踪68.71.216.176到端口80,带有2个探头
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);
}
答案 0 :(得分:0)
此类ICMP数据包有2个IP标头。您要查找的地址不在ip1
(这是您正在打印的地址),它位于ip2
(您加载了,但之后您没有打印任何值)。