2013-05-18 3 views
0

패킷이 로컬 라우터에서 대상 라우터로 이동할 때 패킷이 사용하는 경로를 캡처하려면 다음 코드가 필요합니다. 모든 중간 라우터와 해당 IP 주소를 인쇄해야합니다. 코드는 아래와 같습니다. 그러나 출력이 모든 IP 주소를 나열하지는 않습니다. 그것은 단지 하나의 라우터의 IP를 보여줍니다. 모든 중간 IP 주소를 표시하도록 코드를 어떻게 수정할 수 있습니까? 제발 도와주세요. 고맙습니다!Traceroute 및 패킷 캡처

입력 형식는 : ./a.out (destination ip) (port no) (MAX_TTL) (max_probe)

내가 가진 무엇 출력이 같은 것입니다 :

./a.out 68.71.216.176 80 10 2 

2 프로브 포트 80에 대한 Max_ttl 10 68.71.216.176을 추적

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

환영합니다. 제대로 포맷하는 데 도움이되는 친절한 제안으로,'backticks '로 인라인 코드를 포맷 할 수 있습니다. – fontno

답변

0

이 유형의 ICMP 패킷에는 2 개의 IP 헤더가 있습니다. 찾고있는 주소가 ip1 (인쇄중인 주소)이 아니고 ip2 (로드했으나 그 값을 인쇄하지 않은 주소)에 있습니다.