1 Star 0 Fork 0

fly/tcpip

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
icmptime.cpp 3.26 KB
一键复制 编辑 原始数据 按行查看 历史
fly 提交于 2年前 . icmptime
#include <arpa/inet.h>
#include <errno.h>
#include <iostream>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <stdexcept>
#include <string.h>
#include <string>
#include <strings.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
using namespace std;
#define throw_unix_error(fn) throw runtime_error(string(fn) + ": " + strerror(errno))
uint16_t in_cksum(uint16_t *addr, int len)
{
int nleft = len;
uint32_t sum = 0;
uint16_t *w = addr;
uint16_t answer = 0;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
/* 4mop up an odd byte, if necessary */
if (nleft == 1) {
*(unsigned char *)(&answer) = *(unsigned char *)w;
sum += answer;
}
/* 4add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}
long since_midnight()
{
struct timeval tv;
struct tm *tm;
gettimeofday(&tv, NULL);
tm = gmtime(&tv.tv_sec);
return (tm->tm_hour * 60 * 60 + tm->tm_min * 60 + tm->tm_sec) * 1000 + tv.tv_usec / 1000;
}
void icmptime(const string &host)
{
int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sockfd < 0)
throw_unix_error("socket");
struct icmp icmp;
bzero(&icmp, sizeof(icmp));
icmp.icmp_type = ICMP_TIMESTAMP;
icmp.icmp_code = 0;
icmp.icmp_id = (unsigned short)getpid();
icmp.icmp_seq = 0;
icmp.icmp_otime = htonl(since_midnight());
icmp.icmp_rtime = 0;
icmp.icmp_ttime = 0;
icmp.icmp_cksum = in_cksum((unsigned short *)&icmp, 20);
struct sockaddr_in addr;
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(host.c_str());
if (sendto(sockfd, &icmp, 20, 0, (struct sockaddr *)&addr, sizeof(addr)) < 0)
throw_unix_error();
struct __attribute__((__packed__)) {
struct iphdr iphdr;
struct icmp icmp;
} reply;
for (;;) {
if (recvfrom(sockfd, &reply, sizeof(reply), 0, NULL, NULL) < 0)
throw_unix_error();
if (reply.iphdr.protocol == IPPROTO_ICMP &&
reply.icmp.icmp_type == ICMP_TIMESTAMPREPLY &&
reply.icmp.icmp_id == (unsigned short)getpid())
break;
}
cout << "orig = " << ntohl(reply.icmp.icmp_otime)
<< ", recv = " << ntohl(reply.icmp.icmp_rtime)
<< ", xmit = " << ntohl(reply.icmp.icmp_ttime)
<< ", rtt = " << (since_midnight() - (long)ntohl(reply.icmp.icmp_otime)) << " ms"
<< "\ndifference = " << ((long)ntohl(reply.icmp.icmp_rtime) - (long)ntohl(reply.icmp.icmp_otime)) << " ms"
<< endl;
}
int main(int argc, char *argv[])
{
if (argc != 2) {
cout << "usage: icmptime host" << endl;
return 0;
}
try {
icmptime(argv[1]);
} catch (const runtime_error &e) {
cout << e.what() << endl;
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/q723937936/tcpip.git
git@gitee.com:q723937936/tcpip.git
q723937936
tcpip
tcpip
master

搜索帮助