程序只實現了獲取時間戳,至於將時間戳轉換成具體日期和時間,暫時沒有好的辦法。socket
1 #define TIME_STAMP_REQUEST 13 2 3 struct iphdr 4 { 5 unsigned char ip_hdr_len : 4; //包頭長度 6 unsigned char ip_version : 4; //版本 7 unsigned char ip_tos; 8 9 unsigned short ip_length; //總長度 10 unsigned short ip_identify;//標識 11 unsigned short ip_offset;//片偏移 12 unsigned char ip_ttl; 13 unsigned char ip_protocol; 14 unsigned short ip_cksum; 15 16 struct in_addr ip_src; //源地址 17 struct in_addr ip_dst; //目的地址 18 }; 19 20 struct icmphdr 21 { 22 unsigned char icmp_type; //8位類型 23 unsigned char icmp_code; //8位代碼 24 unsigned short icmp_cksum; //16位的校驗和 25 26 unsigned short icmp_identify; 27 unsigned short icmp_seq; 28 29 unsigned int icmp_otime; 30 unsigned int icmp_rtime; //接收時間 31 unsigned int icmp_ttime; //應答時間 32 }; 33 34 unsigned short checksum(int count,unsigned short* addr) 35 { 36 long sum = 0; 37 38 while(count > 1) 39 { 40 sum +=*addr++; 41 count -= sizeof(unsigned short); 42 } 43 44 if(count > 0) 45 { 46 sum +=*(unsigned char*)addr; 47 } 48 49 while(sum >> 16) 50 { 51 sum = (sum & 0xFFFF) + (sum >> 16); 52 } 53 54 return (unsigned short)(~sum); 55 } 56 57 bool timestamp_request(char * argv) 58 { 59 WSADATA wsaData; 60 WSAStartup(MAKEWORD(2, 2), &wsaData); 61 62 SOCKET soc = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); 63 if(soc == -1) 64 { 65 printf("create raw socket failed!\n"); 66 return false; 67 } 68 69 struct sockaddr_in addrsrv; 70 71 addrsrv.sin_family = AF_INET; 72 addrsrv.sin_port = htons(0); 73 addrsrv.sin_addr.s_addr = inet_addr("202.112.10.36"); //預設地址 74 75 struct hostent* phostent = gethostbyname(argv); 76 if (phostent) 77 { 78 addrsrv.sin_addr.s_addr = *(u_long *)phostent->h_addr_list[0];; 79 } 80 81 printf("sending timestamp request to host [%s]\n",inet_ntoa(addrsrv.sin_addr)); 82 83 icmphdr ihdr = {0}; 84 85 ihdr.icmp_type = TIME_STAMP_REQUEST; 86 ihdr.icmp_identify = (unsigned short)GetCurrentProcessId(); 87 ihdr.icmp_cksum = checksum(sizeof(icmphdr),(unsigned short *)&ihdr); 88 89 if(sendto(soc,(char *)&ihdr,sizeof(ihdr),0,(sockaddr *)&addrsrv,sizeof(addrsrv)) == -1) 90 { 91 printf("send icmp packet failed!\n"); 92 return false; 93 } 94 95 struct sockaddr_in addrcli; 96 97 int nlength = sizeof(addrcli); 98 char recv[MAXBYTE] = {0}; 99 100 struct timeval timeout; 101 timeout.tv_sec = 3000; 102 timeout.tv_usec = 0; 103 setsockopt(soc, SOL_SOCKET,SO_RCVTIMEO, (char*)&timeout,sizeof(timeout)); 104 105 if(recvfrom(soc,recv,MAXBYTE,0,(sockaddr *)&addrcli,&nlength) == -1) 106 { 107 printf("recv ip packet failed!\n"); 108 return false; 109 } 110 111 iphdr* piphdr = (iphdr *)recv; 112 if(checksum(piphdr->ip_hdr_len << 2,(unsigned short *)piphdr) != 0) 113 { 114 printf("invalid ip packet!\n"); 115 return false; 116 } 117 118 icmphdr* pichdr = (icmphdr *)(piphdr + 1); 119 if(checksum(sizeof(icmphdr),(unsigned short *)pichdr) != 0) 120 { 121 printf("invalid icmp packet!\n"); 122 return false; 123 } 124 125 printf("recv time:[%u] transmit time:[%u]\n",ntohl(pichdr->icmp_rtime),ntohl(pichdr->icmp_ttime)); 126 127 return true; 128 } 129 130 int main(int argc,char * argv[]) 131 { 132 if(argc < 2) 133 { 134 return 0; 135 } 136 137 timestamp_request(argv[1]); 138 }