程序只实现了获取时间戳,至于将时间戳转换成具体日期和时间,暂时没有好的办法。

  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 }  

 

  

posted on 2016-11-10 14:32  gtxvs  阅读(4067)  评论(0编辑  收藏  举报