// Effect: Send NTP packet and get the NTP packet, make the time OK
// 2014.7.31 is OK
//
# Include <sys/types. h>
# Include <sys/socket. h>
# Include <strings. h>
# Include <sys/types. h>
# Include <sys/socket. h>
# Include <netinet/in. h>
# Include <ARPA/inet. h>
# Include <unistd. h>
# Include <string. h>
# Include <sys/IOCTL. h>
# Include <stdio. h>
# Include <netinet/udp. h>
# Include <Linux/if_ether.h>
# Include <pthread. h>
# Include <netdb. h>
# Include <stddef. h>
///////////////// Something for the NTP control; do by ZHB ///////////////////////////////////// /////////
# Define int8 char
# Define uint8 unsigned char
# Define uint32 unsigned int
# Define ulong32 unsigned long
# Define long32 long
# Define int32 int
# Define long64 long
# Define u_int32 unsigned long
# Define ntp_port 123/* NTP dedicated port number string */
# Define time_port 37/* time/udp port number */
# Define ntp_port_str "123"/* NTP dedicated port number string */
# Define ntp_server_ip "192.168.1.21"/* NTP service IP */
// 3600 S * 24 h * (365days * 70 years + 17 days)
# Define jan_1970 0x83aa7e80u // * 1900 ~ The time in seconds between January 1, 1970 */
//////////////////////////////////////// ///////////////////
# Define pkt_mode (li_vn_mode) (u_char) (li_vn_mode) & 0x7 ))
# Define pkt_version (li_vn_mode) (u_char) (li_vn_mode)> 3) & 0x7 ))
# Define pkt_leap (li_vn_mode) (u_char) (li_vn_mode)> 6) & 0x3 ))
// # Define debug 1
Struct ntp_packet
{
Uint8 li_vn_mode;
Uint8 stratum;
Uint8 poll;
Uint8 precision;
Ulong32 root_delay;
Ulong32 root_dispersion;
// Int8 ref_id [4];
Ulong32 ref_id;
Ulong32 reftimestamphigh;
Ulong32 reftimestamplow;
Ulong32 oritimestamphigh;
Ulong32 oritimestamplow;
Ulong32 recvtimestamphigh;
Ulong32 recvtimestamplow;
Ulong32 trantimestamphigh;
Ulong32 trantimestamplow;
};
Long64 firsttimestamp, finaltimestamp;
Int sendpkt (INT sockfd, struct addrinfo * res)
{
Struct ntp_packet ntppack, newpack;
// Put the date into the ntppack
Ntppack. li_vn_mode = 0x23;
Ntppack. stratum = 0x02;
Ntppack. Poll = 0x04;
Ntppack. Precision = 0xec;
Ntppack. root_delay = htonl (1 <16); // root_delay = 1.0sec
Ntppack. root_dispersion = htonl (1 <8); // root_dispersion = 0.0039sec
Ntppack. ref_id = inet_addr (ntp_server_ip );
// Obtain the initial timestamp T1
Firsttimestamp = jan_1970 + time (null); //-8*3600
// Printf ("% lx, % lx \ n", jan_1970, firsttimestamp );
Ntppack. reftimestamphigh = htonl (firsttimestamp );
Ntppack. oritimestamphigh = htonl (firsttimestamp );
Ntppack. recvtimestamphigh = htonl (firsttimestamp );
Ntppack. trantimestamphigh = htonl (firsttimestamp );
Int I;
For (I = 0; I <1; I ++)
{
Int ret = sendto (sockfd, & ntppack, sizeof (ntppack), 0, res-> ai_addr, res-> ai_addrlen );
If (Ret <0 ){
Perror ("sendto ");
Return 1;
}
}
}
Int getresponse (INT sockfd, struct addrinfo * res, struct ntp_packet rpkt)
{
// Struct ntp_packet rpkt, newpack;
Fd_set pending_data;
Struct timeval block_time;
Char * refID;
/* Call the select () function and set the timeout value to 1 S */
Fd_zero (& pending_data );
Fd_set (sockfd, & pending_data );
Block_time. TV _sec = 10; // how time to ask
Block_time. TV _usec = 0;
If (select (sockfd + 1, & pending_data, null, null, & block_time)> 0)
{
Int num;
/* Receive server information */
If (num = recvfrom (sockfd, & rpkt,
Sizeof (rpkt), 0, res-> ai_addr, & res-> ai_addrlen) <0)
{
Perror ("recvfrom ");
Return 0;
}
/* Set the data structure for receiving NTP packets */
Int mode = pkt_mode (rpkt. li_vn_mode );
Int version = pkt_version (rpkt. li_vn_mode );
Int leap = pkt_leap (rpkt. li_vn_mode );
Int stratum = rpkt. stratum;
Int poll = rpkt. poll;
Int precision = rpkt. Precision;
// Arrives at the client timestamp T4
Finaltimestamp = Time (null) + jan_1970; //-8*3600;
/// Change the big-end data transmitted over the network to a small-end data format.
Rpkt. root_dispersion = ntohl (rpkt. root_dispersion );
Rpkt. reftimestamphigh = ntohl (rpkt. reftimestamphigh );
Rpkt. reftimestamplow = ntohl (rpkt. reftimestamplow );
Rpkt. oritimestamphigh = ntohl (rpkt. oritimestamphigh );
Rpkt. oritimestamplow = ntohl (rpkt. oritimestamplow );
Rpkt. recvtimestamphigh = ntohl (rpkt. recvtimestamphigh );
Rpkt. recvtimestamplow = ntohl (rpkt. recvtimestamplow );
Rpkt. trantimestamphigh = ntohl (rpkt. trantimestamphigh );
Rpkt. trantimestamplow = ntohl (rpkt. trantimestamplow );
# Ifdef debug
Printf ("Li = % d, version = % d, mode = % d \ n", leap, version, mode );
Printf ("stratum = % d, Poll = % d, precision = % d \ n", stratum, poll, precision );
Printf ("################ data #################### \ n ");
Printf ("root_delay = % LD \ n", rpkt. root_delay );
Printf ("dispersion = % LD \ n", rpkt. root_dispersion );
// Printf ("ID = % s \ n", (* (int *) & rpkt. ref_id ));
Printf ("refh = % lx \ n", rpkt. reftimestamphigh );
Printf ("relw = % lx \ n", rpkt. reftimestamplow );
Printf ("orih = % lx \ n", rpkt. oritimestamphigh );
Printf ("oril = % lx \ n", rpkt. oritimestamplow );
Printf ("rech = % lx \ n", rpkt. recvtimestamphigh );
Printf ("recl = % lx \ n", rpkt. recvtimestamplow );
Printf ("trah = % lx \ n", rpkt. trantimestamphigh );
Printf ("Tral = % lx \ n", rpkt. trantimestamplow );
# Endif
Long64 diftime, delaytime;
// Obtain the time difference between the client and the server = (T2-T1) + (T3-T4)/2
Diftime = (rpkt. recvtimestamphigh-firsttimestamp) + (rpkt. trantimestamphigh-finaltimestamp)> 1;
// Obtain the latency
Delaytime = (rpkt. recvtimestamphigh-firsttimestamp)-(rpkt. trantimestamphigh-finaltimestamp)> 1;
// Diftime = (5-9)> 1;
// Obtain the real time Timestamp
Struct timeval TV1;
Tv1. TV _ sec = Time (null) + diftime + delaytime;
Tv1. TV _ USEC = 0;
Settimeofday (& TV1, null );
# Ifdef debug
Printf ("\ n \ ndebug information... \ n ");
Printf ("Time (null) is % LD \ n", time (null ));
Printf ("different time is % LD \ n", diftime );
Printf ("delaytime is % LD \ n", delaytime );
Printf ("Time (null) + diftime + delaytime = % LD \ n", time (null) + diftime + delaytime );
Printf ("tv1. TV _ sec is % LD \ n", tv1. TV _ Sec );
# Endif
}
Return 1;
}
Int main ()
{
Struct addrinfo * res = NULL, hints;
Memset (& hints, 0, sizeof (hints ));
Hints. ai_family = af_unspec;
Hints. ai_socktype = sock_dgram;
Hints. ai_protocol = ipproto_udp;
/* Call the getaddrinfo () function to obtain the address information */
Int rc = getaddrinfo (ntp_server_ip, ntp_port_str, & hints, & res );
If (RC! = 0)
{
Perror ("getaddrinfo ");
Return 1;
}
Int FD = socket (res-> ai_family, res-> ai_socktype, res-> ai_protocol );
If (FD <0 ){
Perror ("socket ");
Return 0;
}
Sendpkt (FD, Res );
Int I;
Struct ntp_packet rpkt;
I = getresponse (FD, res, rpkt );
Printf ("time is OK \ n ");
Close (FD );
}
Http://www.gpstime.com.cn/chanpin/pinlv/227.html