mirror of
https://github.com/JamesonHuang/OpenWrt_Luci_Lua.git
synced 2024-11-23 22:00:11 +00:00
ntp time polling get system time
This commit is contained in:
parent
a7aa28eb38
commit
4611b5aca5
1
1_6.h12_dev/ntp/timesync/.svn/entries
Normal file
1
1_6.h12_dev/ntp/timesync/.svn/entries
Normal file
@ -0,0 +1 @@
|
||||
12
|
1
1_6.h12_dev/ntp/timesync/.svn/format
Normal file
1
1_6.h12_dev/ntp/timesync/.svn/format
Normal file
@ -0,0 +1 @@
|
||||
12
|
Binary file not shown.
@ -0,0 +1,2 @@
|
||||
sudo ./server
|
||||
./client <server ip address>
|
@ -0,0 +1,20 @@
|
||||
.PHONY: all clean tags
|
||||
|
||||
CFLAGS:=-Wall -O2
|
||||
|
||||
all: client server
|
||||
|
||||
server: server.c
|
||||
$(CC) $(CFLAGS) $^ -o $@
|
||||
strip -s $@
|
||||
|
||||
client: client.c
|
||||
$(CC) $(CFLAGS) $^ -o $@
|
||||
strip -s $@
|
||||
|
||||
tags:
|
||||
ctags -R .
|
||||
|
||||
clean:
|
||||
-rm *.o client server
|
||||
|
Binary file not shown.
@ -0,0 +1,159 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h> /* gettimeofday() */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <time.h> /* for time() and ctime() */
|
||||
|
||||
/*
|
||||
* rfc1305的ntp时间中,时间为64bit,记录1900年后的秒数(utc格式)
|
||||
* 高32位是整数部分,低32位是小数部分*/
|
||||
#define UTC_NTP 2208988800U /* 1970 - 1900 */
|
||||
|
||||
/* get Timestamp for NTP in LOCAL ENDIAN */
|
||||
void gettime64(uint32_t ts[])
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
ts[0] = tv.tv_sec + UTC_NTP;
|
||||
ts[1] = (4294*(tv.tv_usec)) + ((1981*(tv.tv_usec))>>11);
|
||||
}
|
||||
|
||||
int die(const char *msg)
|
||||
{
|
||||
fputs(msg, stderr);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int useage(const char *path)
|
||||
{
|
||||
printf("Useage:\n\t%s <server address>\n", path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//开始连接服务器
|
||||
int open_connect(const char* server)
|
||||
{
|
||||
int s;
|
||||
struct addrinfo *saddr;
|
||||
|
||||
/* printf("Connecting to server: %s\n", server); */
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s == -1) {
|
||||
die("Can not create socket.\n");
|
||||
}
|
||||
|
||||
if (0 != getaddrinfo(server, "123", NULL, &saddr)) {
|
||||
die("Server address not correct.\n");
|
||||
}
|
||||
|
||||
if (connect(s, saddr->ai_addr, saddr->ai_addrlen) != 0) {
|
||||
die("Connect error\n");
|
||||
}
|
||||
|
||||
freeaddrinfo(saddr);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//发送请求报文
|
||||
void request(int fd)
|
||||
{
|
||||
unsigned char buf[48] = {0};
|
||||
uint32_t tts[2]; /* Transmit Timestamp */
|
||||
|
||||
/* LI VN MODE = 00 100 011*/
|
||||
/* MODE:3表示客户模式,4表示服务器模式*/
|
||||
buf[0] = 0x23;
|
||||
|
||||
gettime64(tts);
|
||||
//此处将Originate Timestamp设置在Transmit Timestamp处
|
||||
(*(uint32_t *)&buf[40]) = htonl(tts[0]);
|
||||
(*(uint32_t *)&buf[44])= htonl(tts[1]);
|
||||
if (send(fd, buf, 48, 0) !=48 ) {
|
||||
die("Send error\n");
|
||||
}
|
||||
}
|
||||
|
||||
//获得NTP应答报文
|
||||
void get_reply(int fd)
|
||||
{
|
||||
unsigned char buf[48];
|
||||
uint32_t *pt;
|
||||
// uint32_t t_last_update[2]; /* Reference Timestamp @ Server */
|
||||
uint32_t t1[2]; /* t1 = Originate Timestamp,即NTP请求报文离开发送端时发送端的本地时间 */
|
||||
uint32_t t2[2]; /* t2 = Receive Timestamp @ Server,即NTP请求报文到达接收端时接收端的本地时间 */
|
||||
uint32_t t3[2]; /* t3 = Transmit Timestamp @ Server,即应答报文离开应答者时应答者的本地时间 */
|
||||
uint32_t t4[2]; /* t4 = Receive Timestamp @ Client */
|
||||
double T1, T2, T3, T4;
|
||||
double tfrac = 4294967296.0;
|
||||
time_t curr_time;
|
||||
time_t diff_sec;
|
||||
|
||||
if (recv(fd, buf, 48, 0) < 48) {
|
||||
die("Receive error\n");
|
||||
}
|
||||
gettime64(t4);
|
||||
pt = (uint32_t *)&buf[24];
|
||||
|
||||
t1[0] = htonl(*pt++);
|
||||
t1[1] = htonl(*pt++);
|
||||
|
||||
t2[0] = htonl(*pt++);
|
||||
t2[1] = htonl(*pt++);
|
||||
|
||||
t3[0] = htonl(*pt++);
|
||||
t3[1] = htonl(*pt++);
|
||||
|
||||
/* t1 = Transmit Timestamp @ Client */
|
||||
/*
|
||||
* (Version=4, Mode=Server,
|
||||
* Stratum = 0-15, etc.)*/
|
||||
|
||||
T1 = t1[0] + t1[1]/tfrac;
|
||||
T2 = t2[0] + t2[1]/tfrac;
|
||||
T3 = t3[0] + t3[1]/tfrac;
|
||||
T4 = t4[0] + t4[1]/tfrac;
|
||||
|
||||
//delay:NTP报文的往返时延
|
||||
//offset:client与server的时间差
|
||||
printf( "\ndelay = %lf\n"
|
||||
"offset = %lf\n\n",
|
||||
(T4-T1) - (T3-T2),
|
||||
((T2 - T1) + (T3 - T4)) /2
|
||||
);
|
||||
|
||||
diff_sec = ((int32_t)(t2[0] - t1[0]) + (int32_t)(t3[0] - t4[0])) /2;
|
||||
curr_time = time(NULL) - diff_sec;
|
||||
printf("Current Time at Server: %s\n", ctime(&curr_time));
|
||||
}
|
||||
|
||||
int client(const char* server)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open_connect(server);
|
||||
request(fd);
|
||||
get_reply(fd);
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[], char **env)
|
||||
{
|
||||
if (argc < 2) {
|
||||
return useage(argv[0]);
|
||||
}
|
||||
|
||||
return client(argv[1]);
|
||||
}
|
@ -0,0 +1,213 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h> /* gettimeofday() */
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <time.h> /* for time() and ctime() */
|
||||
|
||||
//1900至1970年间经过的总秒数
|
||||
#define UTC_NTP 2208988800U /* 1970 - 1900 */
|
||||
|
||||
/* get Timestamp for NTP in LOCAL ENDIAN */
|
||||
void gettime64(uint32_t ts[])
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
ts[0] = tv.tv_sec + UTC_NTP;
|
||||
ts[1] = (4294*(tv.tv_usec)) + ((1981*(tv.tv_usec))>>11);
|
||||
}
|
||||
|
||||
|
||||
int die(const char *msg)
|
||||
{
|
||||
if (msg) {
|
||||
fputs(msg, stderr);
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
void log_request_arrive(uint32_t *ntp_time)
|
||||
{
|
||||
time_t t;
|
||||
|
||||
if (ntp_time) {
|
||||
t = *ntp_time - UTC_NTP;
|
||||
} else {
|
||||
t = time(NULL);
|
||||
}
|
||||
printf("A request comes at: %s", ctime(&t));
|
||||
}
|
||||
|
||||
|
||||
void log_ntp_event(char *msg)
|
||||
{
|
||||
puts(msg);
|
||||
}
|
||||
|
||||
//应答client
|
||||
int ntp_reply(
|
||||
int socket_fd,
|
||||
struct sockaddr *saddr_p,
|
||||
socklen_t saddrlen,
|
||||
unsigned char recv_buf[],
|
||||
uint32_t recv_time[])
|
||||
{
|
||||
/* Assume that recv_time is in local endian ! */
|
||||
unsigned char send_buf[48];
|
||||
uint32_t *u32p;
|
||||
|
||||
/* do not use 0xC7 because the LI=11 can be `unsynchronized` */
|
||||
if ((recv_buf[0] & 0x07/*0xC7*/) != 0x3) {
|
||||
/* LI VN Mode stimmt nicht */
|
||||
log_ntp_event("Invalid request: found error at the first byte");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 设置 LI VN Mode 的值
|
||||
LI = 0
|
||||
VN = Version Number 同 Client
|
||||
Mode = 4
|
||||
*/
|
||||
send_buf[0] = (recv_buf[0] & 0x38) + 4;
|
||||
|
||||
/* Stratum */
|
||||
send_buf[1] = 0x01;
|
||||
/* Reference ID = "LOCL" ,即参考时钟源的标识*/
|
||||
*(uint32_t*)&send_buf[12] = htonl(0x4C4F434C);
|
||||
|
||||
/* Copy Poll */
|
||||
send_buf[2] = recv_buf[2];
|
||||
|
||||
/* Precision in Microsecond ( from API gettimeofday() ) */
|
||||
send_buf[3] = (signed char)(-6); /* 2^(-6) sec */
|
||||
|
||||
u32p = (uint32_t *)&send_buf[4];
|
||||
/* 设置Root Delay = 0, Root Dispersion = 0 */
|
||||
*u32p++ = 0;
|
||||
*u32p++ = 0;
|
||||
|
||||
/* Reference ID前面已经设置*/
|
||||
u32p++;
|
||||
|
||||
/* 设置 Reference TimeStamp */
|
||||
gettime64(u32p);
|
||||
*u32p = htonl(*u32p - 60); /* -1 Min.*/
|
||||
u32p++;
|
||||
*u32p = htonl(*u32p); /* -1 Min.*/
|
||||
u32p++;
|
||||
|
||||
/* Originate Time = Transmit Time @ Client */
|
||||
*u32p++ = *(uint32_t *)&recv_buf[40];
|
||||
*u32p++ = *(uint32_t *)&recv_buf[44];
|
||||
|
||||
/* Receive Time @ Server */
|
||||
*u32p++ = htonl(recv_time[0]);
|
||||
*u32p++ = htonl(recv_time[1]);
|
||||
|
||||
/* 设置 Transmit Time*/
|
||||
gettime64(u32p);
|
||||
*u32p = htonl(*u32p); /* -1 Min.*/
|
||||
u32p++;
|
||||
*u32p = htonl(*u32p); /* -1 Min.*/
|
||||
|
||||
if ( sendto( socket_fd,
|
||||
send_buf,
|
||||
sizeof(send_buf), 0,
|
||||
saddr_p, saddrlen)
|
||||
< 48) {
|
||||
perror("sendto error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void request_process_loop(int fd)
|
||||
{
|
||||
struct sockaddr src_addr;
|
||||
socklen_t src_addrlen = sizeof(src_addr);
|
||||
unsigned char buf[48];
|
||||
uint32_t recv_time[2];
|
||||
pid_t pid;
|
||||
|
||||
while (1) {
|
||||
while (recvfrom(fd, buf,
|
||||
48, 0,
|
||||
&src_addr,
|
||||
&src_addrlen)
|
||||
< 48 ); /* invalid request */
|
||||
|
||||
gettime64(recv_time);
|
||||
/* recv_time in local endian */
|
||||
log_request_arrive(recv_time);
|
||||
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
/* Child */
|
||||
ntp_reply(fd, &src_addr , src_addrlen, buf, recv_time);
|
||||
exit(0);
|
||||
} else if (pid == -1) {
|
||||
perror("fork() error");
|
||||
die(NULL);
|
||||
}
|
||||
/* return to parent */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ntp_server()
|
||||
{
|
||||
int s;
|
||||
struct sockaddr_in sinaddr;
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s == -1) {
|
||||
perror("Can not create socket.");
|
||||
die(NULL);
|
||||
}
|
||||
|
||||
memset(&sinaddr, 0, sizeof(sinaddr));
|
||||
sinaddr.sin_family = AF_INET;
|
||||
//NTP基于UDP报文传输,使用的UDP端口号为123
|
||||
sinaddr.sin_port = htons(123);
|
||||
sinaddr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if (0 != bind(s, (struct sockaddr *)&sinaddr, sizeof(sinaddr))) {
|
||||
perror("Bind error");
|
||||
die(NULL);
|
||||
}
|
||||
|
||||
log_ntp_event( "\n========================================\n"
|
||||
"= Server started, waiting for requests =\n"
|
||||
"========================================\n");
|
||||
|
||||
request_process_loop(s);
|
||||
close(s);
|
||||
}
|
||||
|
||||
|
||||
void wait_wrapper()
|
||||
{
|
||||
int s;
|
||||
wait(&s);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[], char **env)
|
||||
{
|
||||
signal(SIGCHLD,wait_wrapper);
|
||||
ntp_server();
|
||||
return 0;
|
||||
}
|
BIN
1_6.h12_dev/ntp/timesync/.svn/wc.db
Normal file
BIN
1_6.h12_dev/ntp/timesync/.svn/wc.db
Normal file
Binary file not shown.
20
1_6.h12_dev/ntp/timesync/Makefile
Normal file
20
1_6.h12_dev/ntp/timesync/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
.PHONY: all clean tags
|
||||
|
||||
CFLAGS:=-Wall -O2
|
||||
|
||||
all: client server
|
||||
|
||||
server: server.c
|
||||
$(CC) $(CFLAGS) $^ -o $@
|
||||
strip -s $@
|
||||
|
||||
client: client.c
|
||||
$(CC) $(CFLAGS) $^ -o $@
|
||||
strip -s $@
|
||||
|
||||
tags:
|
||||
ctags -R .
|
||||
|
||||
clean:
|
||||
-rm *.o client server
|
||||
|
2
1_6.h12_dev/ntp/timesync/README
Normal file
2
1_6.h12_dev/ntp/timesync/README
Normal file
@ -0,0 +1,2 @@
|
||||
sudo ./server
|
||||
./client <server ip address>
|
BIN
1_6.h12_dev/ntp/timesync/client
Executable file
BIN
1_6.h12_dev/ntp/timesync/client
Executable file
Binary file not shown.
165
1_6.h12_dev/ntp/timesync/client.c
Normal file
165
1_6.h12_dev/ntp/timesync/client.c
Normal file
@ -0,0 +1,165 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h> /* gettimeofday() */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <time.h> /* for time() and ctime() */
|
||||
|
||||
/*
|
||||
* rfc1305的ntp时间中,时间为64bit,记录1900年后的秒数(utc格式)
|
||||
* 高32位是整数部分,低32位是小数部分*/
|
||||
#define UTC_NTP 2208988800U /* 1970 - 1900 */
|
||||
|
||||
/* get Timestamp for NTP in LOCAL ENDIAN */
|
||||
void gettime64(uint32_t ts[])
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
ts[0] = tv.tv_sec + UTC_NTP;
|
||||
ts[1] = (4294*(tv.tv_usec)) + ((1981*(tv.tv_usec))>>11);
|
||||
}
|
||||
|
||||
int die(const char *msg)
|
||||
{
|
||||
fputs(msg, stderr);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int useage(const char *path)
|
||||
{
|
||||
printf("Useage:\n\t%s <server address>\n", path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//开始连接服务器
|
||||
int open_connect(const char* server)
|
||||
{
|
||||
int s;
|
||||
struct addrinfo *saddr;
|
||||
|
||||
/* printf("Connecting to server: %s\n", server); */
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s == -1) {
|
||||
die("Can not create socket.\n");
|
||||
}
|
||||
|
||||
if (0 != getaddrinfo(server, "123", NULL, &saddr)) {
|
||||
die("Server address not correct.\n");
|
||||
}
|
||||
|
||||
if (connect(s, saddr->ai_addr, saddr->ai_addrlen) != 0) {
|
||||
die("Connect error\n");
|
||||
}
|
||||
|
||||
freeaddrinfo(saddr);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//发送请求报文
|
||||
void request(int fd)
|
||||
{
|
||||
unsigned char buf[48] = {0};
|
||||
uint32_t tts[2]; /* Transmit Timestamp */
|
||||
|
||||
/* LI VN MODE = 00 100 011*/
|
||||
/* MODE:3表示客户模式,4表示服务器模式*/
|
||||
buf[0] = 0x23;
|
||||
|
||||
gettime64(tts);
|
||||
//此处将Originate Timestamp设置在Transmit Timestamp处
|
||||
(*(uint32_t *)&buf[40]) = htonl(tts[0]);
|
||||
(*(uint32_t *)&buf[44])= htonl(tts[1]);
|
||||
if (send(fd, buf, 48, 0) !=48 ) {
|
||||
die("Send error\n");
|
||||
}
|
||||
}
|
||||
|
||||
//获得NTP应答报文
|
||||
void get_reply(int fd)
|
||||
{
|
||||
unsigned char buf[48];
|
||||
uint32_t *pt;
|
||||
// uint32_t t_last_update[2]; /* Reference Timestamp @ Server */
|
||||
uint32_t t1[2]; /* t1 = Originate Timestamp,即NTP请求报文离开发送端时发送端的本地时间 */
|
||||
uint32_t t2[2]; /* t2 = Receive Timestamp @ Server,即NTP请求报文到达接收端时接收端的本地时间 */
|
||||
uint32_t t3[2]; /* t3 = Transmit Timestamp @ Server,即应答报文离开应答者时应答者的本地时间 */
|
||||
uint32_t t4[2]; /* t4 = Receive Timestamp @ Client */
|
||||
double T1, T2, T3, T4;
|
||||
double tfrac = 4294967296.0;
|
||||
time_t curr_time;
|
||||
time_t diff_sec;
|
||||
|
||||
if (recv(fd, buf, 48, 0) < 48) {
|
||||
die("Receive error\n");
|
||||
}
|
||||
gettime64(t4);
|
||||
pt = (uint32_t *)&buf[24];
|
||||
|
||||
t1[0] = htonl(*pt++);
|
||||
t1[1] = htonl(*pt++);
|
||||
|
||||
t2[0] = htonl(*pt++);
|
||||
t2[1] = htonl(*pt++);
|
||||
|
||||
t3[0] = htonl(*pt++);
|
||||
t3[1] = htonl(*pt++);
|
||||
|
||||
/* t1 = Transmit Timestamp @ Client */
|
||||
/*
|
||||
* (Version=4, Mode=Server,
|
||||
* Stratum = 0-15, etc.)*/
|
||||
|
||||
T1 = t1[0] + t1[1]/tfrac;
|
||||
T2 = t2[0] + t2[1]/tfrac;
|
||||
T3 = t3[0] + t3[1]/tfrac;
|
||||
T4 = t4[0] + t4[1]/tfrac;
|
||||
|
||||
//delay:NTP报文的往返时延
|
||||
//offset:client与server的时间差
|
||||
printf( "\ndelay = %lf\n"
|
||||
"offset = %lf\n\n",
|
||||
(T4-T1) - (T3-T2),
|
||||
((T2 - T1) + (T3 - T4)) /2
|
||||
);
|
||||
|
||||
diff_sec = ((int32_t)(t2[0] - t1[0]) + (int32_t)(t3[0] - t4[0])) /2;
|
||||
curr_time = time(NULL) - diff_sec;
|
||||
printf("Current Time at Server: %s\n", ctime(&curr_time));
|
||||
printf("Current TimeStamp at Server: %d\n", (int)curr_time);
|
||||
}
|
||||
|
||||
int client(const char* server)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open_connect(server);
|
||||
request(fd);
|
||||
get_reply(fd);
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[], char **env)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
return useage(argv[0]);
|
||||
}
|
||||
//return client(argv[1]);
|
||||
client(argv[1]);
|
||||
sleep(3);
|
||||
}
|
||||
}
|
BIN
1_6.h12_dev/ntp/timesync/server
Executable file
BIN
1_6.h12_dev/ntp/timesync/server
Executable file
Binary file not shown.
213
1_6.h12_dev/ntp/timesync/server.c
Normal file
213
1_6.h12_dev/ntp/timesync/server.c
Normal file
@ -0,0 +1,213 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h> /* gettimeofday() */
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <time.h> /* for time() and ctime() */
|
||||
|
||||
//1900至1970年间经过的总秒数
|
||||
#define UTC_NTP 2208988800U /* 1970 - 1900 */
|
||||
|
||||
/* get Timestamp for NTP in LOCAL ENDIAN */
|
||||
void gettime64(uint32_t ts[])
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
ts[0] = tv.tv_sec + UTC_NTP;
|
||||
ts[1] = (4294*(tv.tv_usec)) + ((1981*(tv.tv_usec))>>11);
|
||||
}
|
||||
|
||||
|
||||
int die(const char *msg)
|
||||
{
|
||||
if (msg) {
|
||||
fputs(msg, stderr);
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
void log_request_arrive(uint32_t *ntp_time)
|
||||
{
|
||||
time_t t;
|
||||
|
||||
if (ntp_time) {
|
||||
t = *ntp_time - UTC_NTP;
|
||||
} else {
|
||||
t = time(NULL);
|
||||
}
|
||||
printf("A request comes at: %s", ctime(&t));
|
||||
}
|
||||
|
||||
|
||||
void log_ntp_event(char *msg)
|
||||
{
|
||||
puts(msg);
|
||||
}
|
||||
|
||||
//应答client
|
||||
int ntp_reply(
|
||||
int socket_fd,
|
||||
struct sockaddr *saddr_p,
|
||||
socklen_t saddrlen,
|
||||
unsigned char recv_buf[],
|
||||
uint32_t recv_time[])
|
||||
{
|
||||
/* Assume that recv_time is in local endian ! */
|
||||
unsigned char send_buf[48];
|
||||
uint32_t *u32p;
|
||||
|
||||
/* do not use 0xC7 because the LI=11 can be `unsynchronized` */
|
||||
if ((recv_buf[0] & 0x07/*0xC7*/) != 0x3) {
|
||||
/* LI VN Mode stimmt nicht */
|
||||
log_ntp_event("Invalid request: found error at the first byte");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 设置 LI VN Mode 的值
|
||||
LI = 0
|
||||
VN = Version Number 同 Client
|
||||
Mode = 4
|
||||
*/
|
||||
send_buf[0] = (recv_buf[0] & 0x38) + 4;
|
||||
|
||||
/* Stratum */
|
||||
send_buf[1] = 0x01;
|
||||
/* Reference ID = "LOCL" ,即参考时钟源的标识*/
|
||||
*(uint32_t*)&send_buf[12] = htonl(0x4C4F434C);
|
||||
|
||||
/* Copy Poll */
|
||||
send_buf[2] = recv_buf[2];
|
||||
|
||||
/* Precision in Microsecond ( from API gettimeofday() ) */
|
||||
send_buf[3] = (signed char)(-6); /* 2^(-6) sec */
|
||||
|
||||
u32p = (uint32_t *)&send_buf[4];
|
||||
/* 设置Root Delay = 0, Root Dispersion = 0 */
|
||||
*u32p++ = 0;
|
||||
*u32p++ = 0;
|
||||
|
||||
/* Reference ID前面已经设置*/
|
||||
u32p++;
|
||||
|
||||
/* 设置 Reference TimeStamp */
|
||||
gettime64(u32p);
|
||||
*u32p = htonl(*u32p - 60); /* -1 Min.*/
|
||||
u32p++;
|
||||
*u32p = htonl(*u32p); /* -1 Min.*/
|
||||
u32p++;
|
||||
|
||||
/* Originate Time = Transmit Time @ Client */
|
||||
*u32p++ = *(uint32_t *)&recv_buf[40];
|
||||
*u32p++ = *(uint32_t *)&recv_buf[44];
|
||||
|
||||
/* Receive Time @ Server */
|
||||
*u32p++ = htonl(recv_time[0]);
|
||||
*u32p++ = htonl(recv_time[1]);
|
||||
|
||||
/* 设置 Transmit Time*/
|
||||
gettime64(u32p);
|
||||
*u32p = htonl(*u32p); /* -1 Min.*/
|
||||
u32p++;
|
||||
*u32p = htonl(*u32p); /* -1 Min.*/
|
||||
|
||||
if ( sendto( socket_fd,
|
||||
send_buf,
|
||||
sizeof(send_buf), 0,
|
||||
saddr_p, saddrlen)
|
||||
< 48) {
|
||||
perror("sendto error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void request_process_loop(int fd)
|
||||
{
|
||||
struct sockaddr src_addr;
|
||||
socklen_t src_addrlen = sizeof(src_addr);
|
||||
unsigned char buf[48];
|
||||
uint32_t recv_time[2];
|
||||
pid_t pid;
|
||||
|
||||
while (1) {
|
||||
while (recvfrom(fd, buf,
|
||||
48, 0,
|
||||
&src_addr,
|
||||
&src_addrlen)
|
||||
< 48 ); /* invalid request */
|
||||
|
||||
gettime64(recv_time);
|
||||
/* recv_time in local endian */
|
||||
log_request_arrive(recv_time);
|
||||
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
/* Child */
|
||||
ntp_reply(fd, &src_addr , src_addrlen, buf, recv_time);
|
||||
exit(0);
|
||||
} else if (pid == -1) {
|
||||
perror("fork() error");
|
||||
die(NULL);
|
||||
}
|
||||
/* return to parent */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ntp_server()
|
||||
{
|
||||
int s;
|
||||
struct sockaddr_in sinaddr;
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s == -1) {
|
||||
perror("Can not create socket.");
|
||||
die(NULL);
|
||||
}
|
||||
|
||||
memset(&sinaddr, 0, sizeof(sinaddr));
|
||||
sinaddr.sin_family = AF_INET;
|
||||
//NTP基于UDP报文传输,使用的UDP端口号为123
|
||||
sinaddr.sin_port = htons(123);
|
||||
sinaddr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if (0 != bind(s, (struct sockaddr *)&sinaddr, sizeof(sinaddr))) {
|
||||
perror("Bind error");
|
||||
die(NULL);
|
||||
}
|
||||
|
||||
log_ntp_event( "\n========================================\n"
|
||||
"= Server started, waiting for requests =\n"
|
||||
"========================================\n");
|
||||
|
||||
request_process_loop(s);
|
||||
close(s);
|
||||
}
|
||||
|
||||
|
||||
void wait_wrapper()
|
||||
{
|
||||
int s;
|
||||
wait(&s);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[], char **env)
|
||||
{
|
||||
signal(SIGCHLD,wait_wrapper);
|
||||
ntp_server();
|
||||
return 0;
|
||||
}
|
26
1_6.h12_dev/ntp/timesync/tags
Normal file
26
1_6.h12_dev/ntp/timesync/tags
Normal file
@ -0,0 +1,26 @@
|
||||
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
|
||||
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
|
||||
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
|
||||
!_TAG_PROGRAM_NAME Exuberant Ctags //
|
||||
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
|
||||
!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
|
||||
CFLAGS Makefile /^CFLAGS:=-Wall -O2$/;" m
|
||||
UTC_NTP client.c 17;" d file:
|
||||
UTC_NTP server.c 18;" d file:
|
||||
client client.c /^int client(const char* server)$/;" f
|
||||
die client.c /^int die(const char *msg)$/;" f
|
||||
die server.c /^int die(const char *msg)$/;" f
|
||||
get_reply client.c /^void get_reply(int fd)$/;" f
|
||||
gettime64 client.c /^void gettime64(uint32_t ts[])$/;" f
|
||||
gettime64 server.c /^void gettime64(uint32_t ts[])$/;" f
|
||||
log_ntp_event server.c /^void log_ntp_event(char *msg)$/;" f
|
||||
log_request_arrive server.c /^void log_request_arrive(uint32_t *ntp_time)$/;" f
|
||||
main client.c /^int main(int argc, char *argv[], char **env)$/;" f
|
||||
main server.c /^int main(int argc, char *argv[], char **env)$/;" f
|
||||
ntp_reply server.c /^int ntp_reply($/;" f
|
||||
ntp_server server.c /^void ntp_server()$/;" f
|
||||
open_connect client.c /^int open_connect(const char* server)$/;" f
|
||||
request client.c /^void request(int fd)$/;" f
|
||||
request_process_loop server.c /^void request_process_loop(int fd)$/;" f
|
||||
useage client.c /^int useage(const char *path)$/;" f
|
||||
wait_wrapper server.c /^void wait_wrapper()$/;" f
|
Loading…
Reference in New Issue
Block a user