跟踪路由和包捕获



需要下面的代码来捕获数据包从本地路由器移动到目的路由器时所采取的路由。它应该打印所有中间路由器及其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 probesn", 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: %sn",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:%sn", "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:%sn", 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("nttSENT 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 ("nt%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 transitn");
else if(icmp->icmp_code==3)
        printf("Destination unreachable: Port unreachablen");
//}
exit(0);
}

这种ICMP报文有2个IP报头。您要查找的地址不是在ip1(这是您正在打印的),而是在ip2(您确实加载了,但随后您没有从中打印任何值)。

最新更新