0

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

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

我得到的输出是这样的:

./a.out 68.71.216.176 80 10 2

使用 2 个探针将 MAX_TTL 10 的 68.71.216.176 跟踪到端口 80

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);
}
4

1 回答 1

0

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

于 2013-05-22T15:51:15.727 回答