my_tracerouter

main.c
  1 #include "trace.h"
  2 int main(int argc,char * argv[])
  3 {
  4             
  5     if(argc != 2) {
  6         fprintf(stderr,"Usage: %s hostname\n",argv[0]);
  7         exit(-1);
  8     }
  9         
 10     const int max_ttl = MYMAXTTL;    
 11     const int nprobes = NPROBES;
 12     
 13     struct hostent *phost;          
 14     struct sockaddr_in host_addr;  
 15     struct sockaddr_in locate_addr; 
 16     bzero(&host_addr,sizeof(host_addr)); 
 17     
 18     
 19     host_addr.sin_family = AF_INET;
 20     host_addr.sin_addr.s_addr =  inet_addr(argv[1]);
 21     host_addr.sin_port = htons(DSTPORT);
 22     
 23     
 24     if(host_addr.sin_addr.s_addr == INADDR_NONE){
 25         if(NULL == (phost = gethostbyname(argv[1]))) {
 26             fprintf(stderr,"unknown host %s\n",argv[1]);
 27             exit(-1);
 28         }
 29         
 30         memcpy(&host_addr.sin_addr,phost->h_addr,phost->h_length);
 31     }
 32     
 33     
 34     locate_addr.sin_family=AF_INET;
 35     locate_addr.sin_addr.s_addr=htonl(INADDR_ANY);
 36     locate_addr.sin_port=htons(SRCPORT);
 37     int sendfd,recvfd;
 38     
 39 
 40     if ((sendfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
 41         fprintf(stderr,"sendfd: udp socket\r\n");
 42         exit(-1);
 43     }
 44     
 45     if ((recvfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
 46         fprintf(stderr,"recvfd: raw socket\r\n");
 47         exit(-1);
 48     }
 49     
 50     
 51     if(bind(sendfd,(struct sockaddr*)&locate_addr,sizeof(locate_addr))) {
 52         fprintf(stderr,"bind error\r\n");
 53         exit(-1);
 54     }
 55 
 56     fprintf(stdout, "traceroute to %s (%s)", argv[1],inet_ntoa(host_addr.sin_addr));    
 57     fprintf(stdout, ", %d hops max, %d byte packets\r\n", max_ttl, UDPPACKETSIZE+sizeof(struct ip)+sizeof(struct udphdr));
 58     
 59     char data_buf[MAXPACKET];    
 60     struct sockaddr_in src_addr;    
 61     int ttl = 0;
 62     
 63     for (ttl = 1; ttl <= max_ttl; ++ttl) {
 64         u_long last_addr = 0;    
 65         int got_there = 0;        
 66         printf("%2d ", ttl);
 67         fflush(stdout);
 68         int  probe = 0;;
 69         for (probe = 0; probe < nprobes; ++probe) {
 70             int len_data = 0;
 71             struct timeval t1, t2;    
 72             struct timezone tz;
 73             struct ip *ip;
 74                                     
 75             gettimeofday(&t1, &tz);    
 76             send_probe(sendfd,&host_addr,ttl); 
 77             
 78             while (len_data = wait_reply(recvfd, &src_addr,data_buf,sizeof(data_buf))) {
 79                 gettimeofday(&t2, &tz); 
 80                 
 81                 if (check_packet(data_buf, len_data) != 0) { 
 82                     
 83                     if (src_addr.sin_addr.s_addr != last_addr) { 
 84                         printf("%s  ",inet_ntoa(src_addr.sin_addr));
 85                         last_addr = src_addr.sin_addr.s_addr;
 86                     }
 87                     
 88                     printf("  %g ms  ", tv_sub(&t1, &t2));
 89                     if(src_addr.sin_addr.s_addr == host_addr.sin_addr.s_addr)
 90                         got_there++;
 91                     break;
 92                 }else if(check_packet(data_buf,len_data) == 0){
 93                     printf("check_pakcet wrong\n");
 94                 }
 95             }
 96             if (len_data == 0) 
 97                 printf("   *   ");
 98         }
 99         printf("\n");
100         if (got_there)
101             break;
102     }
103     return 0;
104 }
105 
106  
mylib.c
#include "trace.h"
double tv_sub(struct timeval *tv_one,struct timeval *tv_two)
{
    double ret;
        
    ret = (double)(tv_two->tv_sec - tv_one->tv_sec) * 1000.0 + (double)(tv_two->tv_usec - tv_one->tv_usec) / 1000.0;
    return (ret);
}

 int wait_reply(int recvfd,struct sockaddr_in *src_addr,char *data_buf,int buf_len)
{
    const int wait_time = WAITTIME;    
    int len_data = 0;        
    int src_addrlen = sizeof (*src_addr);
    fd_set fds; 
    FD_ZERO(&fds); 
    FD_SET(recvfd, &fds); 
    struct timeval wait;
    wait.tv_sec = wait_time; 
    wait.tv_usec = 0;
    if (select(recvfd+1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0) {
        len_data = recvfrom(recvfd, data_buf, buf_len, 0,(struct sockaddr *)src_addr, &src_addrlen);
    }
    
    return(len_data);
}

void send_probe(int sendfd,struct sockaddr_in *dest_addr,int ttl)
{
    char data_buf[UDPPACKETSIZE];        
    bzero(data_buf,sizeof(data_buf));
    setsockopt(sendfd,IPPROTO_IP,IP_TTL,(char *)&ttl,sizeof(ttl));
    int n = sendto(sendfd, data_buf, sizeof(data_buf), 0,(struct sockaddr *)dest_addr,sizeof(struct sockaddr));
    if(n != UDPPACKETSIZE) {
        fprintf(stderr,"bad sendto\r\n");
    }
}

int check_packet(u_char *buf,int  len_data)
{
    struct ip *ip= (struct ip *) buf;
    int hlen = ip->ip_hl << 2;
    if (len_data < hlen + ICMP_MINLEN) {
        return 0;
    }
    len_data -= hlen;
    struct icmp *icp= (struct icmp *)(buf + hlen);
    u_char type=icp->icmp_type;    
    u_char code=icp->icmp_code; 
    if(type == ICMP_TIMXCEED || type == ICMP_UNREACH) {
        struct ip *hip=&icp->icmp_ip;
        hlen=hip->ip_hl<<2;
        struct udphdr *udp=(struct udphdr *)((u_char *)hip+hlen);
        if(hip->ip_p==IPPROTO_UDP && udp->dest==htons(DSTPORT) && 
            udp->source==htons(SRCPORT))
                return 1;
    }
    
    return 0;
}
trace.h
 1 #include <sys/time.h>
 2 #include <sys/socket.h>
 3 #include <netinet/in_systm.h>
 4 #include <netinet/in.h>
 5 #include <netinet/ip.h>
 6 #include <netinet/ip_icmp.h>
 7 #include <netinet/udp.h>
 8 #include <netdb.h>
 9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #define MAXPACKET    65535    
13 #define UDPPACKETSIZE    36    
14 #define SRCPORT        55567    
15 #define DSTPORT        55558    
16 #define MYMAXTTL 30
17 #define NPROBES 3
18 #define WAITTIME 4
19 
20 double tv_sub(struct timeval *tv_one,struct timeval *tv_two);
21 int check_packet(u_char *buf,int  len_data); 
22 void send_probe(int sendfd,struct sockaddr_in *dest_addr,int ttl);
23 int wait_reply(int recvfd,struct sockaddr_in *src_addr,char *data_buf,int buf_len); 
makefile
1 mytraceroute: main.c mylib.c trace.h
2           gcc -o mytraceroute main.c mylib.c -I ./ 

转载于:https://www.cnblogs.com/hust2012/archive/2012/11/08/2760754.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值