NTPのパケットフォーマット
NTP(バージョン4)のパケットフォーマットを以下に示します。
NTPは基本はUDPを使うことになっていますが、実はTCPでもUDPでもどっちでも良いのです。TCPの実装もたまに見かけます。送信元ポートおよび宛先ポートはともに123番となります。
各フィールドについて
LI (Leap Indicator)
2bit。その日の最後の1分が1秒追加(うるう秒=Leap Second)されるか、もしくは1秒削除されるかを事前に予告するフィールド。
1. その日の最後の1分が61秒となることを予告
2. その日の最後の1分が59秒となることを予告
3. 不明(時刻同期無し)
VN (Version Number)
3bit。現在のNTPバージョンは4(RFC5905で規定)。
NTPバージョン4は、NTPバージョン3(RFC1305)およびSNTP(Simple Network Time Protocol)バージョン4(RFC4330)の機能を統合し、それ以外にもさらに機能を追加したものになります。また、NTPバージョン4はNTPバージョン1~3と下位互換があります。
Mode
3bit。アソシエーションのモードを示します。
アソシエーションとは、NTPの時刻情報を提供する形態を示したものです。アソシエーションモードには以下の値が入ります。
1. Symmetric Active
2. Symmetric Passive
3. Client
4. Server
5. Broadcast
6. NTP control message(制御クエリ)
7. プライベート利用に予約
NTPパケットのModeは、RFC上は相手のアソシエーションモードを想定してセットするとあるのですが、Windows, Linux, Cisco どの実装を見ても、自分のアソシエーションモードをパケットに含めて送信しています。つまり、自分が Symmetric Active であれば Mode=1 , Symmetric Passive であれば Mode=2 , Client であれば Mode=3 , ...となっています。
各アソシエーションモードの具体的な動作については、『NTPプロトコルの概要・仕組み』を参照して下さい。
なお、NTP control messageは主にネットワークシステム監視装置が使うモードです。NTPサーバから応答があるかどうかを確認しますが、時刻同期は一切行いません。
Stratum
8bit。0は原子時計やGPSの時刻を意味しますが、NTPパケット上は取り扱いません。
1は原子時計やGPSに物理的に直結したNTPサーバを意味します。
2以降は、それより1つ上のStratumのNTPサーバから時刻同期したことを意味します。
16は時刻同期していないことを意味します。
17以降は予約とされ、使われていません。
Poll
8bit。次のNTPパケット送出までの最大時間間隔(秒)に対してlog2の対数を取った数値が入ります。例えば10(RFCで推奨されているデフォルト値)の場合は2の10乗の1024秒となります。
この値はNTPで定義されている「discipline algorithm」の中で決定されます。このアルゴリズムは自身とリモートNTPアソシエーションから『時刻およびクロック周波数』の誤差を予測するもので、この誤差が小さければPollは大きめ(つまり間隔が長め)に取るし、誤差が大きければ小さめ(間隔が短め)に取ります。
Precision
8bit。NTPを扱う機器のシステムクロックが扱える精度を相手に示します。Pollと同じく、log2の対数を取った数値が入ります。例えば-18という数値の場合は約1マイクロ秒になります。
Root Delay
Primaryサーバ(Stratum 1 のNTPサーバ)とのラウンドトリップ遅延(Round-Trip Delay)を表しています。NTPサーバは上位NTPサーバからこの値を受け取ると、自身のRTTを加え、下位NTPクライアントへ伝搬します。
この値が大きいほど、ネットワークの距離が遠い=精度が低くなる、ということを意味します。この辺りの詳細も『NTPプロトコルの概要・仕組み』を参照して下さい。
Root Dispersion
Primaryサーバ(Stratum 1 のNTPサーバ)との通信における揺らぎ(Jitter)を表しています。NTPサーバは上位NTPサーバからこの値を受け取ると、自身の揺らぎ(Jitter)を加え、下位NTPクライアントへ伝搬します。
この値が大きいほど、ネットワーク遅延の予測が荒い=精度が低くなる、ということを意味します。この辺りの詳細も『NTPプロトコルの概要・仕組み』を参照して下さい。
Reference ID
32bit。Reference Clock(相手先)がどのNTPサーバを参照しているかを表しています。
Stratum2~14のNTPサーバは、上位のNTPサーバのIPアドレスをセットします。
Stratum1のNTPサーバは、参照先を暗示する任意の1~4文字のASCII文字列をセットします。(GPS、WWVB等)
Reference Timestamp
自分が最後に同期した時刻を示します。このタイムスタンプは、複数のNTPサーバから情報を取得し平均した結果なので、時刻同期の計算には使われません。単に相手へのフィードバックとして送っているだけです。
Origin Timestamp
前回相手がNTPパケットを送信した時刻(前回受信したNTPパケットのTransmit Timestamp)を示します。時刻同期の計算に使われます。この辺りの詳細も『NTPプロトコルの概要・仕組み』を参照して下さい。
Receive Timestamp
自身が前回相手からNTPパケットを受信した時刻を示します。時刻同期の計算に使われます。この辺りの詳細も『NTPプロトコルの概要・仕組み』を参照して下さい。
Transmit Timestamp
自身が、今回相手へNTPパケットを送信した時刻を示します。時刻同期の計算に使われます。この辺りの詳細も『NTPプロトコルの概要・仕組み』を参照して下さい。
Extension Field [1~n]
1つ以上の拡張フィールドを任意に使うことが可能です。ただし、RFCにもどのような利用シーンを想定しているかは記載されていません。
Key Identifier
32bit。キー番号を示します。
dgst
128bit。Key Identifierに紐づくMD5ハッシュ値です。このハッシュを元に、相手が正しいNTP同期先かを認証します。
NTPのタイムスタンプについて
NTPのタイムスタンプは UTC (Coordinated Universal Time:順番が違うように思うかもしれませんが合っています)を前提として、1900/1/1 0:00:00 を起点(=0)としています。この計算だと2036/2/7 6:28:15 までしか表現できませんが、RFC4330では1周回ったところで2036/2/7 6:28:16と解釈することで回避する方法が書かれています。