CPU実験室

誰も見向きもしない古いCPUをいじって動かしてみようというプロジェクトです

NTP実装(2)

イメージ 1

このパケットモニタは優れものでNTPのデータグラムを解析して表示までしてしまいます。
実際に返送される時刻情報は整数部32ビット、小数部32ビットの計64ビットで表現されています。

[パケット情報] (Request 210.173.160.57 -> 192.168.0.10)
[MAC層] (EtherII(DIX))
[IPヘッダ]
[UDPヘッダ]
送信元ポート番号 : 0x007B (123) ntp Network Time Protocol
送信先ポート番号 : 0x007B (123) ntp Network Time Protocol
データ長 : 0x0038 (56 オクテット)
チェックサム : 0xDA1C
[NTPパケット]
フラグ : 0x1A
閏秒指示子 : 0 (警告無し)
バージョン : 3 (IPv4のみ)
モード : 2 (対象受動 passive)
階級 : 2 (従属的な基準)
ポーリング間隔 : 10
精度 : 0xEE (0.000004 sec)
ルート遅延 : 0x19000000 (0.000381 sec)
ルート分散 : 0x75030000 (0.013504 sec)
基準ID : 0x38A0ADD2 (210.173.160.56)
基準タイムスタンプ : 2006-12-28 07:57:34.2200 UTC
基点タイムスタンプ : 1970-01-01 00:00:00.0000 UTC
受信タイムスタンプ : 2006-12-28 08:01:16.8137 UTC
送信タイムスタンプ : 2006-12-28 08:01:16.8138 UTC


小数部32ビットということはナノ秒以下の分解能があるわけで本当かいな?
そのほかに上位の時間標準との遅れなどの情報も含んでおり、さらに厳密に言えば
クライアント~サーバ間の応答時間を測定してそれらも加味して時刻を決定する必要があるのですが
そういうのはバッサリ切って送信時刻情報の整数部だけを取り出しました。

たとえば上のようなレスポンス内で送信タイムスタンプの32ビット整数部は「C93DF84C」
で、3376281676秒となります。
これは協定世界時1900年1月1日午前0時からの経過時間を示しているので
9時間を足して通常の日付時刻表示に変換すれば日本時間表示ができます。
変換するためのにはCの標準関数でlocaltime()というのがあるのですが、
ところがこれは1970年1月1日午前0時からの経過時間を引数にするので使えません。
これは手作りする必要がありそうです。時分秒だけであれば86400のモジュロをとれば算出できるので
これを液晶表示器に送ればNTP時計になりそうです。

ただし、常時NTPサーバにリクエストして時刻を取得するのはサーバに負担がかかるのでいけません。
実際にはリアルタイムクロックか、ソフト/ハードのタイマで計時しておいて1時間に1回とか
正時に補正を掛けるのが正しいようです。

ところでNTPの実験をしていて自分のパソコンが標準時より10分も進んでいるのに
初めて気づきました.....