在文件ntp.h中SNTPv4(RFC2030)协议包定义如下:
struct l_fixedpt {
u_int32_t int_partl;
u_int32_t fractionl;
};
struct s_fixedpt {
u_int16_t int_parts;
u_int16_t fractions;
};
struct ntp_msg {
u_int8_t status;        /* status of local clock and leap info */
u_int8_t stratum;       /* Stratum level */
u_int8_t ppoll;         /* poll value */
int8_t precision;
struct s_fixedpt rootdelay;
struct s_fixedpt dispersion;
u_int32_t refid;
struct l_fixedpt reftime;
struct l_fixedpt orgtime;
struct l_fixedpt rectime;
struct l_fixedpt xmttime;
} __packed;
下面以最常用的SNTPv4工作模式-单播模式,来说明服务器的工作过程:
openNTPD服务器在初始化时,主函数ntp_main()调用函数setup_listeners()在123端口建立UDP服务;函数server_dispatch()将数据包结构体ntp_msg 成员status中LI字段设置为3(表示未与上级服务器同步);VN字段设置为4,表示SNTPv4;Mode 字段设置为4(服务器模式);成员stratum和ppoll设置为0;成员precision设置为0xFA(十进制为-6)。
一旦服务器与外部时钟源取得同步后,进入工作状态,在日志中会记录“clock is now synced”。LI字段设置为0,stratum字段设置为外部时钟源服务器的stratum+1;Reference Identifier字段设置为时钟源的ip地址,如十六进制C0 A8 FE 01表示192.168.254.1,Precision字段和前边设置相同;VN字段设置为客户端请求信息包的VN字段值,Root Delay和Root Dispersion字段通常设置为0,Reference Timestamp字段设置为从外部时钟源最新取得的时间,Originate Timestamp字段设置为客户请求包的Transmit Timestamp字段值,Transmit Timestamp字段设置为服务器发出时间戳给客户的时间。
SNTP服务器在工作过程中,如果与外部时钟源失去同步,Stratum字段设置为0,此时客户收到这个信息时,要丢弃服务器发给它的时间戳信息