Beagleboard-xm NTP程式
1: #include<stdio.h>
2: #include<stdlib.h>
3: #include<string.h>
4: #include<errno.h>
5: #include<unistd.h>
6: #include<sys/types.h>
7: #include<sys/socket.h>
8: #include<sys/time.h>
9: #include<linux/in.h>
10:
11: /*Used to set NTP protocol version*/
12: #define NTP_Version 0x4
13: /*Sets NTP mode to client*/
14: #define Mode_Client 0x3
15: /*NTP counts time from 1-1-1900, we must subtract 70 years to go to epoch*/
16: #define _1_1_1970_ 0x83AA7E80
17:
18: /*Message structure for NTP message according to rfc4330*/
19: typedef struct struct_sntp_msg{
20: unsigned char LI : 2;
21: unsigned char VN : 3;
22: unsigned char Mode : 3;
23: unsigned char Stratum;
24: unsigned char Poll;
25: unsigned char Precision;
26: unsigned int root_delay;
27: unsigned int root_dispersion;
28: unsigned int ref_id;
29: unsigned int ref_timestamp;
30: unsigned int ref_timestamp_nanosecs;
31: unsigned int orig_timestamp;
32: unsigned int orig_timestamp_nanosecs;
33: unsigned int rx_timestamp;
34: unsigned int rx_timestamp_nanosecs;
35: unsigned int tx_timestamp;
36: unsigned int tx_timestamp_nanosecs;
37: unsigned int key_identifier;
38: unsigned char msg_digest[16];
39: } sntp_msg;
40:
41: /*Creates an NTP message, Using empty transmission time, since we will sync
42: with the time of the server, we dont a big precision therefore we will not use
43: the algorithms specified in RFC4330*/
44: int fillReqMessage (sntp_msg *outMsg){
45: if(outMsg==NULL){
46: return -1;
47: }
48: memset(outMsg, 0x0, sizeof(sntp_msg));
49: outMsg->LI = 0x3; //clock not synchronized
50: outMsg->VN = NTP_Version;
51: outMsg->Mode = Mode_Client;
52: return 0;
53: }
54:
55: /*Sets the system time based on the epoch value*/
56: int set_SystemTime(unsigned int epoch){
57: struct timeval tv;
58: struct timezone tz;
59: memset(&tv, 0x0, sizeof(struct timeval));
60: /*Timezone value is considered in the epoch time and we ignore DST*/
61: memset(&tz, 0x0, sizeof(struct timezone));
62: tv.tv_sec = epoch;
63: if( settimeofday(&tv, &tz) == -1){
64: fprintf(stderr,"Failed to gettimeofday %s \n",strerror(errno));
65: return -1;
66: }
67: else
68: return 0;
69: }
70:
71: int main (int argc, char* argv[]){
72:
73: int offset = 0;
74: //Parsing cmdLine
75: if(argc != 2){
76: fprintf(stdout,"\t/******************************************************/\n");
77: fprintf(stdout,"\t/* */\n");
78: fprintf(stdout,"\t/* USAGE */\n");
79: fprintf(stdout,"\t/* */\n");
80: fprintf(stdout,"\t/* ./timesync TIMEZONEOFFSET */\n");
81: fprintf(stdout,"\t/* */\n");
82: fprintf(stdout,"\t/* TIMEZONEOFFSET minutes to add/remove to GMT */\n");
83: fprintf(stdout,"\t/* */\n");
84: fprintf(stdout,"\t/* */\n");
85: fprintf(stdout,"\t/******************************************************/\n");
86: return 0;
87: }
88: else{
89: /*Saving offset in minutes*/
90: offset = atoi(argv[1]);
91: }
92:
93:
94: sntp_msg outMsg;
95: sntp_msg inMsg;
96: int sock = 0;
97: unsigned int epochTime = 0;
98: struct sockaddr_in ntpaddr;
99: memset(&ntpaddr, 0x0, sizeof(struct sockaddr_in));
100: ntpaddr.sin_family = AF_INET;
101: /*Setting IP address of ntp server*/
102: inet_aton("95.130.9.63",&(ntpaddr.sin_addr.s_addr));
103: /*Setting port for NTP protocol*/
104: ntpaddr.sin_port = htons(123);
105:
106: /*Create the message*/
107: if(fillReqMessage(&outMsg)){
108: fprintf(stderr,"Failed to create Message\n");
109: return -1;
110: }
111: /*Creating the socket*/
112: if( ( sock = socket(AF_INET, SOCK_DGRAM, 0 ) ) == -1){
113: fprintf(stderr,"Failed to open socket %s \n",strerror(errno));
114: return -1;
115: }
116: /*Connecting the socket*/
117: if( connect( sock, (struct sockaddr*) &ntpaddr, sizeof(struct sockaddr) ) < 0 ){
118: fprintf(stderr,"Failed to connect socket %s \n",strerror(errno));
119: close(sock);
120: return -1;
121: }
122: /*Sending*/
123: if( send( sock, (void*) &outMsg, sizeof(sntp_msg), 0 ) != sizeof(sntp_msg) ){
124: fprintf(stderr,"Failed to tx %s \n",strerror(errno));
125: close(sock);
126: return -1;
127: }
128: /*Receiving from the socket, we will just wync our clock with the server time
129: we dont anymore precision*/
130: if( recv( sock, (void*) &inMsg, sizeof(sntp_msg), 0 ) ==-1){
131: fprintf(stderr,"Failed to rx %s \n",strerror(errno));
132: close(sock);
133: return -1;
134: }
135: /*Cleaning up*/
136: if( close(sock) == -1){
137: fprintf(stderr,"Failed to close socket %s \n",strerror(errno));
138: return -1;
139: }
140:
141: /*Reinterpreting received info*/
142: //fprintf(stdout,"Updated Time is: 0x%X %u\n",ntohl(inMsg.tx_timestamp),(unsigned int) ntohl(inMsg.tx_timestamp));
143: /*unix time measures time in seconds from 1-1-1970 whereas NTP measures time
144: in seconds from 1-1-1900 (RFC4330), to convert we must remove 70 years in
145: seconds and finally add the offset in seconds from GMT*/
146: epochTime = ntohl(inMsg.tx_timestamp) - _1_1_1970_ + (offset*60);
147:
148: /*Updating System time and date*/
149: if( set_SystemTime(epochTime) == -1 )
150: return -1;
151:
152:
153: fprintf(stdout,"Updated Time is: %u\n",epochTime);
154:
155: return 0;
156: }
157:
158: