一.大致流程:
将ICMP头和时间数据设置好后,通过创建好的原始套接字socket发出去。目的主机计算效验和后会将数据原样返回,用当前时间和返回的数据结算时间差,计算出rtt。
二.数据结构:
ICMP时间戳请求与应答报文格式:
aaarticlea/png;base64,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" alt="" />
ICMP头部数据结构:
struct icmp //占8字节,在<netinet/ip_icmp.h>头文件中定义
{
u_int8_t icmp_type; //类型
u_int8_t icmp_code; //代码
u_int16_t icmp_cksum; //检验和
u_int16_t icd_id; //标识符
u_int16_t icd_seq; //序列号
}
注:对于icmp时间戳请求与应答是这样的,我将不必要的数据定义省略了。
struct timeval时间结构体:
struct timeval //该结构在<time.h>中定义
{
__time_t tv_sec; // 秒,实际上为long int类型
__suseconds_t tv_usec; // 微秒(百万分之一秒),实际上为long int类型
};
三.说明:
1.我们以ping www.baidu.com为例,但我们并没有计算平均rtt
2.我们并没有手动创建IP头,而是交给了内核去帮我们处理
3.中间设计到的函数需要查相关资料
四.代码实现:
/*
============================================================================
Name : myping.c
Author : huh
Version : 0.01
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/ #include <sys/types.h>
#include <sys/select.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/ip_icmp.h> #define PACKET_SIZE 1024*4 int pid;
int sockfd;
int datalen = ;
int nsent = , nrecv = ;
char sendbuf[PACKET_SIZE];
char recvbuf[PACKET_SIZE];
struct sockaddr_in dest_addr; //socket目的地址
struct sockaddr_in src_addr;
struct timeval tvrecv; void send_packet();
void un_packet(int);
void tv_sub(struct timeval *out, struct timeval *in);
unsigned short in_chksum(unsigned short *addr, int len); int main()
{
pid = getpid();
char str[];
unsigned int inaddr;
struct hostent *host;
int size = * ;
strcpy(str,"www.baidu.com");
//IP地址(域名)到无符号整数的转换
inaddr = inet_addr(str);
if (inaddr == INADDR_NONE)
{
host = gethostbyname(str);
if (host == NULL)
{
printf("参数格式不正确,请重新输入!\n");
return ;
}
memcpy((char*) &inaddr, host->h_addr, sizeof(dest_addr.sin_addr));
}
//设置套接字地址
dest_addr.sin_family = AF_INET;
memcpy((char *)&dest_addr.sin_addr, (char *)&inaddr,sizeof(inaddr));
//创建套接字
sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
//改变socket缓冲区大小
setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); printf("PING %s (%s) %d(84) bytes of data.\n",str, inet_ntoa(dest_addr.sin_addr), datalen);
//不停的发送和接受ICMP数据包
while ()
{
send_packet();
int src_addr_len = sizeof(struct sockaddr_in);
//接收数据包,一直阻塞到有数据包到达为止
int len = recvfrom(sockfd, recvbuf, sizeof(recvbuf), , (struct sockaddr *) &src_addr, (socklen_t *) &src_addr_len);
if(len < )
printf("recvfrom error!\n");
un_packet(len);
sleep(); //间隔一秒,后面会用信号实现每秒发送一个ICMP包。
}
return ;
} //解包
void un_packet(int len)
{
int hlen1;
double rtt;
struct ip *ip;
struct icmp *icmp;
struct timeval *tvsend; ip = (struct ip *) recvbuf;
hlen1 = ip->ip_hl << ;
if (ip->ip_p != IPPROTO_ICMP)
return ; icmp = (struct icmp *) (recvbuf + hlen1);
len -= hlen1; if ((icmp->icmp_type == ICMP_ECHOREPLY))
{
if (icmp->icmp_id != pid)
return;
tvsend = (struct timeval *) icmp->icmp_data; //发送时间
gettimeofday(&tvrecv, NULL); //得到当前时间 tv_sub(&tvrecv, tvsend); //计算接收和发送的时间差
rtt = tvrecv.tv_sec * 1000.0 + tvrecv.tv_usec / 1000.0; //以毫秒单位计算rtt
printf("%d byte from %s: icmp_seq=%u ttl=%d rtt=%.3fms\n", len, inet_ntoa(src_addr.sin_addr), icmp->icmp_seq, ip->ip_ttl, rtt);
nrecv++;
}
} //手动构建数据包,并通过原始套接字发送
void send_packet()
{
int len;
struct icmp *icmp;
icmp = (struct icmp *) (sendbuf);
icmp->icmp_type = ICMP_ECHO; //拼接icmp
icmp->icmp_code = ;
icmp->icmp_id = pid; //2字节
icmp->icmp_seq = nsent++; //2字节
memset(icmp->icmp_data, 0xa5, datalen);
gettimeofday((struct timeval *) icmp->icmp_data, NULL); //将发送时间作为数据传递过去 len = datalen + ;
icmp->icmp_cksum = ; //校验和需要先置0
icmp->icmp_cksum = in_chksum((unsigned short *) icmp, len); //计算效验和 sendto(sockfd, sendbuf, len, , (struct sockaddr *) &dest_addr,
sizeof(dest_addr)); //将包发出去
//printf("package have sent!\n");
} //计算效验和
unsigned short in_chksum(unsigned short *addr, int len)
{
int nleft = len;
int sum = ;
unsigned short *w = addr;
unsigned short answer = ;
//把ICMP报头二进制数据以2字节为单位累加起来
while (nleft > )
{
sum += *w++;
nleft -= ;
}
if (nleft == )
{
*(unsigned char *) (&answer) = *(unsigned char *) w;
sum += answer;
}
sum = (sum >> ) + (sum & 0xffff);
sum += (sum >> );
answer = ~sum;
return answer;
} //计算时间差
void tv_sub(struct timeval *out, struct timeval *in)
{
if ((out->tv_usec -= in->tv_usec) < )
{
--out->tv_sec;
out->tv_usec += ;
}
out->tv_sec -= in->tv_sec;
}
myping