代码拉取完成,页面将自动刷新
#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;
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。