2013-05-18 64 views
0

捕获数据包从本地路由器移动到目标路由器时所采用的路由需要以下代码。它应该打印所有中间路由器及其IP地址。代码如下。但是输出并没有列出所有的IP地址。它只显示一个路由器的IP。我如何修改代码以显示所有中间IP地址?请帮助我。谢谢!跟踪路由和数据包捕获

输入格式./a.out (destination ip) (port no) (MAX_TTL) (max_probe)

输出我得到的是这样的:

./a.out 68.71.216.176 80 10 2 

追查68.71.216.176同一个Max_ttl 10至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

欢迎来到stackoverflow。只是一个友好的建议,以帮助您正确格式化,您可以使用'反引号'格式化内联代码。 – fontno

回答

0

这种类型的ICMP数据包有2个IP头。你正在寻找的地址不在ip1(这是你正在打印的),它在ip2(你确实加载了,但是你没有打印任何值)。