创建一个响应服务器系统时间的简单NTP服务器时出现问题

问题描述 投票:0回答:1

我正在尝试构建一个非常简单的NTP(v3)服务器,该服务器从LAN上的IP摄像机接收NTP请求以进行时间同步。摄像机与互联网断开连接,因此我们的想法是将本地PC服务器用作摄像机的NTP服务器。

我尝试了两种不同的方法。

  1. 将简单的UDP转发写入已知的NTP服务器(例如time.windows.com)。这很好用。
  2. 编写一个简单的UDP服务器,在端口123上侦听传入的NTP请求,这些请求只返回服务器的系统时间。这对于简单的要求不高的NTP客户端(例如物理网络路由器)也很有效,但是对于本地HIKVISION摄像机而言它仍然失败。

方法:接收48字节缓冲区。确保偏移0处的字节为0x1B。将偏移0处的字节转换为0x1C,并将当前UTC时间写入最后8个字节作为NTP时间戳。这对大多数NTP客户端而言非常有用,但不适用于HIKVISION。

相机发送此请求:

1B-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
00-00-00-00-00-00-00-00-61-8C-DE-CA-C3-73-89-DC

最后8个字节非零。如果我尝试修改我的UDP转发解决方案[1],以便在转发之前将最后8个字节清零,则摄像机会报告错误。事实证明这些位很重要,可能具有一些加密意义。

我正在挖掘RFC以试图理解这一点,但我找不到解释。我能找到的任何示例代码都完全忽略了这一点,并沿着简单的路线前进。

所以问题是......如何解释NTP请求的尾随字节以及如何返回正确的NTP响应?我们欢迎一些示例代码或指向资源的指针。

ntp
1个回答
1
投票

有关NTP数据包格式的说明,请参阅https://www.ietf.org/rfc/rfc1305.pdf第50页开始的附录A.最后8个字节应该带有服务器的响应时间戳 - 这正是您在构建最小响应数据包时将时间戳放入这些字节的原因。

但是,基于此客户端将值放入最后8个字节的事实,看起来它想要使用SNTP(简单NTP)协议第5节中描述的机制,每个https://www.ietf.org/rfc/rfc2030.txt SNTP使用与NTP相同的数据包格式但是以稍微不同的方式使用字段。在SNTP中,客户端放入字节40到47的值是客户端当前的时间概念。 (在这种情况下,AFAICT关闭时间戳是在1951年左右的某个时间。)

如果这是客户端尝试做的事情,那么它希望服务器将这8个字节复制到字节24-31(Originate Timestamp字段),然后将服务器的当前时间写入字节32-39(接收时间戳)并进入字节40-47(传输时间戳),并将其作为响应发送。当然,还会继续将响应中的第一个字节更改为0x1C,以指示此数据包来自服务器。您还应该将字节1中的Stratum值设置为合理的非零值,例如3或4。

鉴于客户端的时钟已经很长时间,它可能需要几轮请求/响应才能实现同步。所以不要指望它的时钟立即跳转到匹配服务器的时钟。 (它可能会这样做,但我不会指望它。)

我认为你不需要通过特别对待这个客户来使你的逻辑复杂化。您可以将相同的逻辑应用于来自将零填充到最后8个字节的客户端的数据包。它只是意味着当您构建对这些客户端的响应时,您将在原始时间戳字段中复制零。

© www.soinside.com 2019 - 2024. All rights reserved.