mirror of
https://github.com/JamesonHuang/OpenWrt_Luci_Lua.git
synced 2025-06-20 01:50:39 +00:00
ntp time polling get system time
This commit is contained in:
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<30><35>ntpʱ<70><CAB1><EFBFBD>У<EFBFBD>ʱ<EFBFBD><CAB1>Ϊ64bit<69><74><EFBFBD><EFBFBD>¼1900<30><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>utc<74><63>ʽ<EFBFBD><CABD>
|
||||
* <20><>32λ<32><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֣<EFBFBD><D6A3><EFBFBD>32λ<32><CEBB>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
//<2F><>ʼ<EFBFBD><CABC><EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
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;
|
||||
}
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
void request(int fd)
|
||||
{
|
||||
unsigned char buf[48] = {0};
|
||||
uint32_t tts[2]; /* Transmit Timestamp */
|
||||
|
||||
/* LI VN MODE = 00 100 011*/
|
||||
/* MODE<44><45>3<EFBFBD><33>ʾ<EFBFBD>ͻ<EFBFBD>ģʽ<C4A3><CABD>4<EFBFBD><34>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ*/
|
||||
buf[0] = 0x23;
|
||||
|
||||
gettime64(tts);
|
||||
//<2F>˴<EFBFBD><CBB4><EFBFBD>Originate Timestamp<6D><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Transmit Timestamp<6D><70>
|
||||
(*(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");
|
||||
}
|
||||
}
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD>NTPӦ<50><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
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,<2C><>NTP<54><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>뿪<EFBFBD><EBBFAA><EFBFBD>Ͷ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>Ͷ˵ı<CBB5><C4B1><EFBFBD>ʱ<EFBFBD><CAB1> */
|
||||
uint32_t t2[2]; /* t2 = Receive Timestamp @ Server,<2C><>NTP<54><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ն<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ն˵ı<CBB5><C4B1><EFBFBD>ʱ<EFBFBD><CAB1> */
|
||||
uint32_t t3[2]; /* t3 = Transmit Timestamp @ Server,<2C><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>뿪Ӧ<EBBFAA><D3A6><EFBFBD><EFBFBD>ʱӦ<CAB1><D3A6><EFBFBD>ߵı<DFB5><C4B1><EFBFBD>ʱ<EFBFBD><CAB1> */
|
||||
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<61><79>NTP<54><50><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||
//offset<65><74>client<6E><74>server<65><72>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
|
||||
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<30><30>1970<37><30><EFBFBD>侭<EFBFBD><E4BEAD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#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);
|
||||
}
|
||||
|
||||
//Ӧ<><D3A6>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;
|
||||
}
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD> LI VN Mode <20><>ֵ
|
||||
LI = 0
|
||||
VN = Version Number ͬ Client
|
||||
Mode = 4
|
||||
*/
|
||||
send_buf[0] = (recv_buf[0] & 0x38) + 4;
|
||||
|
||||
/* Stratum */
|
||||
send_buf[1] = 0x01;
|
||||
/* Reference ID = "LOCL" ,<2C><><EFBFBD>ο<EFBFBD>ʱ<EFBFBD><CAB1>Դ<EFBFBD>ı<EFBFBD>ʶ*/
|
||||
*(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];
|
||||
/* <20><><EFBFBD><EFBFBD>Root Delay = 0, Root Dispersion = 0 */
|
||||
*u32p++ = 0;
|
||||
*u32p++ = 0;
|
||||
|
||||
/* Reference IDǰ<44><C7B0><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
u32p++;
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD> 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]);
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD> 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<54><50><EFBFBD><EFBFBD>UDP<44><50><EFBFBD>Ĵ<EFBFBD><C4B4>䣬ʹ<E4A3AC>õ<EFBFBD>UDP<44>˿ں<CBBF>Ϊ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<30><35>ntpʱ<70><CAB1><EFBFBD>У<EFBFBD>ʱ<EFBFBD><CAB1>Ϊ64bit<69><74><EFBFBD><EFBFBD>¼1900<30><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>utc<74><63>ʽ<EFBFBD><CABD>
|
||||
* <20><>32λ<32><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֣<EFBFBD><D6A3><EFBFBD>32λ<32><CEBB>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
//<2F><>ʼ<EFBFBD><CABC><EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
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;
|
||||
}
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
void request(int fd)
|
||||
{
|
||||
unsigned char buf[48] = {0};
|
||||
uint32_t tts[2]; /* Transmit Timestamp */
|
||||
|
||||
/* LI VN MODE = 00 100 011*/
|
||||
/* MODE<44><45>3<EFBFBD><33>ʾ<EFBFBD>ͻ<EFBFBD>ģʽ<C4A3><CABD>4<EFBFBD><34>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ*/
|
||||
buf[0] = 0x23;
|
||||
|
||||
gettime64(tts);
|
||||
//<2F>˴<EFBFBD><CBB4><EFBFBD>Originate Timestamp<6D><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Transmit Timestamp<6D><70>
|
||||
(*(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");
|
||||
}
|
||||
}
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD>NTPӦ<50><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
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,<2C><>NTP<54><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>뿪<EFBFBD><EBBFAA><EFBFBD>Ͷ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>Ͷ˵ı<CBB5><C4B1><EFBFBD>ʱ<EFBFBD><CAB1> */
|
||||
uint32_t t2[2]; /* t2 = Receive Timestamp @ Server,<2C><>NTP<54><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ն<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ն˵ı<CBB5><C4B1><EFBFBD>ʱ<EFBFBD><CAB1> */
|
||||
uint32_t t3[2]; /* t3 = Transmit Timestamp @ Server,<2C><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>뿪Ӧ<EBBFAA><D3A6><EFBFBD><EFBFBD>ʱӦ<CAB1><D3A6><EFBFBD>ߵı<DFB5><C4B1><EFBFBD>ʱ<EFBFBD><CAB1> */
|
||||
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<61><79>NTP<54><50><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||
//offset<65><74>client<6E><74>server<65><72>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
|
||||
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<30><30>1970<37><30><EFBFBD>侭<EFBFBD><E4BEAD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#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);
|
||||
}
|
||||
|
||||
//Ӧ<><D3A6>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;
|
||||
}
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD> LI VN Mode <20><>ֵ
|
||||
LI = 0
|
||||
VN = Version Number ͬ Client
|
||||
Mode = 4
|
||||
*/
|
||||
send_buf[0] = (recv_buf[0] & 0x38) + 4;
|
||||
|
||||
/* Stratum */
|
||||
send_buf[1] = 0x01;
|
||||
/* Reference ID = "LOCL" ,<2C><><EFBFBD>ο<EFBFBD>ʱ<EFBFBD><CAB1>Դ<EFBFBD>ı<EFBFBD>ʶ*/
|
||||
*(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];
|
||||
/* <20><><EFBFBD><EFBFBD>Root Delay = 0, Root Dispersion = 0 */
|
||||
*u32p++ = 0;
|
||||
*u32p++ = 0;
|
||||
|
||||
/* Reference IDǰ<44><C7B0><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
u32p++;
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD> 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]);
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD> 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<54><50><EFBFBD><EFBFBD>UDP<44><50><EFBFBD>Ĵ<EFBFBD><C4B4>䣬ʹ<E4A3AC>õ<EFBFBD>UDP<44>˿ں<CBBF>Ϊ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
|
Reference in New Issue
Block a user