ntpclient 是一个网络校时客户端程序。
下载地址:
ntpclient 基于NTP协议,RFC-1305有详细说明。
NTP数据格式:(请求/应答)
Leap Indicator: 跳跃指示器,警告在当月最后一天的最终时刻插入的迫近闺秒(闺秒)。
Version Number: 版本号。
Mode: 工作模式。该字段包括以下值:0-预留;1-对称行为;3-客户机;4-服务器;5-广播;6-NTP控制信息。
NTP协议具有3种工作模式,分别为主/被动对称模式、客户/服务器模式、广播模式。
在主/被动对称模式中,有一对一的连接,双方均可同步对方或被对方同步,先发出申请建立连接的一方工作在主动模式下,另一方工作在被动模式下;
客户/服务器模式与主/被动模式基本相同,惟一区别在于客户方可被服务器同步,但服务器不能被客户同步;
在广播模式中,有一对多的连接,服务器不论客户工作在何种模式下,都会主动发出时间信息,客户根据此信息调整自己的时间。
Stratum: 对本地时钟级别的整体识别。
Poll: 有符号整数表示连续信息间的最大间隔。
Precision: 有符号整数表示本地时钟精确度。
Root Delay: 表示到达主参考源的一次往复的总延迟,它是有15~16位小数部分的符号定点小数。
Root Dispersion: 表示一次到达主参考源的标准误差,它是有15~16位小数部分的无符号定点小数。
Reference Clock ID: 识别特殊参考源。
Reference Timestamp:
Fraction:
Originate Timestamp: 这是向服务器请求分离客户机的时间,采用64位时标格式。(4字节整数部分)
Fraction: (4字节小数部分)
Receive Timestamp: 这是向服务器请求到达客户机的时间,采用64位时标格式。
Fraction:
Transmit Timestamp: 这是向客户机答复分离服务器的时间,采用64位时标格式。
Fraction:
下面是ntpclient程序的大体流程:
main
{
getopt获取参数,设置struct ntp_control ntpc;
setup_receive 绑定本地套接字
setup_transmit 无实际意义
primary_loop
{
send_packet 构造NTP数据格式,发送给NTP server
recvfrom 接收NTP server发送过来的数据
rfc1305print 设置时间
}
}
关键函数为 send_packet 和rfc1305print
static void send_packet(int usd, u32 time_sent[2])
{
u32 data[12];
#define LI 0
#define VN 3
#define MODE 3
#define STRATUM 0
#define POLL 4
#define PREC -6
memset(data,0,sizeof data);
data[0] = htonl (
( LI << 30 ) | ( VN << 27 ) | ( MODE << 24 ) |
( STRATUM << 16) | ( POLL << 8 ) | ( PREC & 0xff ) );
data[1] = htonl(1<<16); /* Root Delay (seconds) */
data[2] = htonl(1<<16); /* Root Dispersion (seconds) */
ntpc_gettime(time_sent, time_sent+1);
data[10] = htonl(time_sent[0]); /* Transmit Timestamp coarse */
data[11] = htonl(time_sent[1]); /* Transmit Timestamp fine */
send(usd,data,48,0);
}
static int rfc1305print(u32 *data, struct ntptime *arrival, struct ntp_control *ntpc, int *error)
{
#define Data(i) ntohl(((u32 *)data)[i])
xmttime.coarse = Data(10);
xmttime.fine = Data(11);
#undef Data
if (ntpc->set_clock) { /* you'd better be root, or ntpclient will exit here! */
set_time(&xmttime);
}
}
从rfc1305print的代码可以看出,仅仅使用了Transmit Timestamp这8个字节重新更新本地系统时间。