Chinaunix首页 | 论坛 | 博客
  • 博客访问: 84461
  • 博文数量: 29
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 90
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-07 19:35
文章分类
文章存档

2015年(11)

2014年(18)

我的朋友

分类: LINUX

2014-11-04 14:30:05

ntpclient源码分析  

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个字节重新更新本地系统时间。

阅读(3829) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~