blob: 33c15b3b39f5a6f72b012969c9e408e6fabc1544 [file] [log] [blame]
Takahiro Suzukid7bf8202020-12-17 20:21:59 +09001// Copyright 2016 Google, Inc. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style license
4// that can be found in the LICENSE file in the root of the source
5// tree.
6//
7//******************************************************************************
8
9package layers
10
11import (
12 "encoding/binary"
13 "errors"
14
15 "github.com/google/gopacket"
16)
17
18//******************************************************************************
19//
20// Network Time Protocol (NTP) Decoding Layer
21// ------------------------------------------
22// This file provides a GoPacket decoding layer for NTP.
23//
24//******************************************************************************
25//
26// About The Network Time Protocol (NTP)
27// -------------------------------------
28// NTP is a protocol that enables computers on the internet to set their
29// clocks to the correct time (or to a time that is acceptably close to the
30// correct time). NTP runs on top of UDP.
31//
32// There have been a series of versions of the NTP protocol. The latest
33// version is V4 and is specified in RFC 5905:
34// http://www.ietf.org/rfc/rfc5905.txt
35//
36//******************************************************************************
37//
38// References
39// ----------
40//
41// Wikipedia's NTP entry:
42// https://en.wikipedia.org/wiki/Network_Time_Protocol
43// This is the best place to get an overview of NTP.
44//
45// Network Time Protocol Home Website:
46// http://www.ntp.org/
47// This appears to be the official website of NTP.
48//
49// List of current NTP Protocol RFCs:
50// http://www.ntp.org/rfc.html
51//
52// RFC 958: "Network Time Protocol (NTP)" (1985)
53// https://tools.ietf.org/html/rfc958
54// This is the original NTP specification.
55//
56// RFC 1305: "Network Time Protocol (Version 3) Specification, Implementation and Analysis" (1992)
57// https://tools.ietf.org/html/rfc1305
58// The protocol was updated in 1992 yielding NTP V3.
59//
60// RFC 5905: "Network Time Protocol Version 4: Protocol and Algorithms Specification" (2010)
61// https://www.ietf.org/rfc/rfc5905.txt
62// The protocol was updated in 2010 yielding NTP V4.
63// V4 is backwards compatible with all previous versions of NTP.
64//
65// RFC 5906: "Network Time Protocol Version 4: Autokey Specification"
66// https://tools.ietf.org/html/rfc5906
67// This document addresses the security of the NTP protocol
68// and is probably not relevant to this package.
69//
70// RFC 5907: "Definitions of Managed Objects for Network Time Protocol Version 4 (NTPv4)"
71// https://tools.ietf.org/html/rfc5907
72// This document addresses the management of NTP servers and
73// is probably not relevant to this package.
74//
75// RFC 5908: "Network Time Protocol (NTP) Server Option for DHCPv6"
76// https://tools.ietf.org/html/rfc5908
77// This document addresses the use of NTP in DHCPv6 and is
78// probably not relevant to this package.
79//
80// "Let's make a NTP Client in C"
81// https://lettier.github.io/posts/2016-04-26-lets-make-a-ntp-client-in-c.html
82// This web page contains useful information about the details of NTP,
83// including an NTP record struture in C, and C code.
84//
85// "NTP Packet Header (NTP Reference Implementation) (Computer Network Time Synchronization)"
86// http://what-when-how.com/computer-network-time-synchronization/
87// ntp-packet-header-ntp-reference-implementation-computer-network-time-synchronization/
88// This web page contains useful information on the details of NTP.
89//
90// "Technical information - NTP Data Packet"
91// https://www.meinbergglobal.com/english/info/ntp-packet.htm
92// This page has a helpful diagram of an NTP V4 packet.
93//
94//******************************************************************************
95//
96// Obsolete References
97// -------------------
98//
99// RFC 1119: "RFC-1119 "Network Time Protocol (Version 2) Specification and Implementation" (1989)
100// https://tools.ietf.org/html/rfc1119
101// Version 2 was drafted in 1989.
102// It is unclear whether V2 was ever implememented or whether the
103// ideas ended up in V3 (which was implemented in 1992).
104//
105// RFC 1361: "Simple Network Time Protocol (SNTP)"
106// https://tools.ietf.org/html/rfc1361
107// This document is obsoleted by RFC 1769 and is included only for completeness.
108//
109// RFC 1769: "Simple Network Time Protocol (SNTP)"
110// https://tools.ietf.org/html/rfc1769
111// This document is obsoleted by RFC 2030 and RFC 4330 and is included only for completeness.
112//
113// RFC 2030: "Simple Network Time Protocol (SNTP) Version 4 for IPv4, IPv6 and OSI"
114// https://tools.ietf.org/html/rfc2030
115// This document is obsoleted by RFC 4330 and is included only for completeness.
116//
117// RFC 4330: "Simple Network Time Protocol (SNTP) Version 4 for IPv4, IPv6 and OSI"
118// https://tools.ietf.org/html/rfc4330
119// This document is obsoleted by RFC 5905 and is included only for completeness.
120//
121//******************************************************************************
122//
123// Endian And Bit Numbering Issues
124// -------------------------------
125//
126// Endian and bit numbering issues can be confusing. Here is some
127// clarification:
128//
129// ENDIAN: Values are sent big endian.
130// https://en.wikipedia.org/wiki/Endianness
131//
132// BIT NUMBERING: Bits are numbered 0 upwards from the most significant
133// bit to the least significant bit. This means that if there is a 32-bit
134// value, the most significant bit is called bit 0 and the least
135// significant bit is called bit 31.
136//
137// See RFC 791 Appendix B for more discussion.
138//
139//******************************************************************************
140//
141// NTP V3 and V4 Packet Format
142// ---------------------------
143// NTP packets are UDP packets whose payload contains an NTP record.
144//
145// The NTP RFC defines the format of the NTP record.
146//
147// There have been four versions of the protocol:
148//
149// V1 in 1985
150// V2 in 1989
151// V3 in 1992
152// V4 in 2010
153//
154// It is clear that V1 and V2 are obsolete, and there is no need to
155// cater for these formats.
156//
157// V3 and V4 essentially use the same format, with V4 adding some optional
158// fields on the end. So this package supports the V3 and V4 formats.
159//
160// The current version of NTP (NTP V4)'s RFC (V4 - RFC 5905) contains
161// the following diagram for the NTP record format:
162
163// 0 1 2 3
164// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
165// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
166// |LI | VN |Mode | Stratum | Poll | Precision |
167// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
168// | Root Delay |
169// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
170// | Root Dispersion |
171// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
172// | Reference ID |
173// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
174// | |
175// + Reference Timestamp (64) +
176// | |
177// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
178// | |
179// + Origin Timestamp (64) +
180// | |
181// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
182// | |
183// + Receive Timestamp (64) +
184// | |
185// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
186// | |
187// + Transmit Timestamp (64) +
188// | |
189// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
190// | |
191// . .
192// . Extension Field 1 (variable) .
193// . .
194// | |
195// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
196// | |
197// . .
198// . Extension Field 2 (variable) .
199// . .
200// | |
201// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
202// | Key Identifier |
203// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
204// | |
205// | dgst (128) |
206// | |
207// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
208// From http://www.ietf.org/rfc/rfc5905.txt
209//
210// The fields "Extension Field 1 (variable)" and later are optional fields,
211// and so we can set a minimum NTP record size of 48 bytes.
212//
213const ntpMinimumRecordSizeInBytes int = 48
214
215//******************************************************************************
216
217// NTP Type
218// --------
219// Type NTP implements the DecodingLayer interface. Each NTP object
220// represents in a structured form the NTP record present as the UDP
221// payload in an NTP UDP packet.
222//
223
224type NTPLeapIndicator uint8
225type NTPVersion uint8
226type NTPMode uint8
227type NTPStratum uint8
228type NTPLog2Seconds int8
229type NTPFixed16Seconds uint32
230type NTPReferenceID uint32
231type NTPTimestamp uint64
232
233type NTP struct {
234 BaseLayer // Stores the packet bytes and payload bytes.
235
236 LeapIndicator NTPLeapIndicator // [0,3]. Indicates whether leap second(s) is to be added.
237 Version NTPVersion // [0,7]. Version of the NTP protocol.
238 Mode NTPMode // [0,7]. Mode.
239 Stratum NTPStratum // [0,255]. Stratum of time server in the server tree.
240 Poll NTPLog2Seconds // [-128,127]. The maximum interval between successive messages, in log2 seconds.
241 Precision NTPLog2Seconds // [-128,127]. The precision of the system clock, in log2 seconds.
242 RootDelay NTPFixed16Seconds // [0,2^32-1]. Total round trip delay to the reference clock in seconds times 2^16.
243 RootDispersion NTPFixed16Seconds // [0,2^32-1]. Total dispersion to the reference clock, in seconds times 2^16.
244 ReferenceID NTPReferenceID // ID code of reference clock [0,2^32-1].
245 ReferenceTimestamp NTPTimestamp // Most recent timestamp from the reference clock.
246 OriginTimestamp NTPTimestamp // Local time when request was sent from local host.
247 ReceiveTimestamp NTPTimestamp // Local time (on server) that request arrived at server host.
248 TransmitTimestamp NTPTimestamp // Local time (on server) that request departed server host.
249
250 // FIX: This package should analyse the extension fields and represent the extension fields too.
251 ExtensionBytes []byte // Just put extensions in a byte slice.
252}
253
254//******************************************************************************
255
256// LayerType returns the layer type of the NTP object, which is LayerTypeNTP.
257func (d *NTP) LayerType() gopacket.LayerType {
258 return LayerTypeNTP
259}
260
261//******************************************************************************
262
263// decodeNTP analyses a byte slice and attempts to decode it as an NTP
264// record of a UDP packet.
265//
266// If it succeeds, it loads p with information about the packet and returns nil.
267// If it fails, it returns an error (non nil).
268//
269// This function is employed in layertypes.go to register the NTP layer.
270func decodeNTP(data []byte, p gopacket.PacketBuilder) error {
271
272 // Attempt to decode the byte slice.
273 d := &NTP{}
274 err := d.DecodeFromBytes(data, p)
275 if err != nil {
276 return err
277 }
278
279 // If the decoding worked, add the layer to the packet and set it
280 // as the application layer too, if there isn't already one.
281 p.AddLayer(d)
282 p.SetApplicationLayer(d)
283
284 return nil
285}
286
287//******************************************************************************
288
289// DecodeFromBytes analyses a byte slice and attempts to decode it as an NTP
290// record of a UDP packet.
291//
292// Upon succeeds, it loads the NTP object with information about the packet
293// and returns nil.
294// Upon failure, it returns an error (non nil).
295func (d *NTP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
296
297 // If the data block is too short to be a NTP record, then return an error.
298 if len(data) < ntpMinimumRecordSizeInBytes {
299 df.SetTruncated()
300 return errors.New("NTP packet too short")
301 }
302
303 // RFC 5905 does not appear to define a maximum NTP record length.
304 // The protocol allows "extension fields" to be included in the record,
305 // and states about these fields:"
306 //
307 // "While the minimum field length containing required fields is
308 // four words (16 octets), a maximum field length remains to be
309 // established."
310 //
311 // For this reason, the packet length is not checked here for being too long.
312
313 // NTP type embeds type BaseLayer which contains two fields:
314 // Contents is supposed to contain the bytes of the data at this level.
315 // Payload is supposed to contain the payload of this level.
316 // Here we set the baselayer to be the bytes of the NTP record.
317 d.BaseLayer = BaseLayer{Contents: data[:len(data)]}
318
319 // Extract the fields from the block of bytes.
320 // To make sense of this, refer to the packet diagram
321 // above and the section on endian conventions.
322
323 // The first few fields are all packed into the first 32 bits. Unpack them.
324 f := data[0]
325 d.LeapIndicator = NTPLeapIndicator((f & 0xC0) >> 6)
326 d.Version = NTPVersion((f & 0x38) >> 3)
327 d.Mode = NTPMode(f & 0x07)
328 d.Stratum = NTPStratum(data[1])
329 d.Poll = NTPLog2Seconds(data[2])
330 d.Precision = NTPLog2Seconds(data[3])
331
332 // The remaining fields can just be copied in big endian order.
333 d.RootDelay = NTPFixed16Seconds(binary.BigEndian.Uint32(data[4:8]))
334 d.RootDispersion = NTPFixed16Seconds(binary.BigEndian.Uint32(data[8:12]))
335 d.ReferenceID = NTPReferenceID(binary.BigEndian.Uint32(data[12:16]))
336 d.ReferenceTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[16:24]))
337 d.OriginTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[24:32]))
338 d.ReceiveTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[32:40]))
339 d.TransmitTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[40:48]))
340
341 // This layer does not attempt to analyse the extension bytes.
342 // But if there are any, we'd like the user to know. So we just
343 // place them all in an ExtensionBytes field.
344 d.ExtensionBytes = data[48:]
345
346 // Return no error.
347 return nil
348}
349
350// SerializeTo writes the serialized form of this layer into the
351// SerializationBuffer, implementing gopacket.SerializableLayer.
352// See the docs for gopacket.SerializableLayer for more info.
353func (d *NTP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
354 data, err := b.PrependBytes(ntpMinimumRecordSizeInBytes)
355 if err != nil {
356 return err
357 }
358
359 // Pack the first few fields into the first 32 bits.
360 h := uint8(0)
361 h |= (uint8(d.LeapIndicator) << 6) & 0xC0
362 h |= (uint8(d.Version) << 3) & 0x38
363 h |= (uint8(d.Mode)) & 0x07
364 data[0] = byte(h)
365 data[1] = byte(d.Stratum)
366 data[2] = byte(d.Poll)
367 data[3] = byte(d.Precision)
368
369 // The remaining fields can just be copied in big endian order.
370 binary.BigEndian.PutUint32(data[4:8], uint32(d.RootDelay))
371 binary.BigEndian.PutUint32(data[8:12], uint32(d.RootDispersion))
372 binary.BigEndian.PutUint32(data[12:16], uint32(d.ReferenceID))
373 binary.BigEndian.PutUint64(data[16:24], uint64(d.ReferenceTimestamp))
374 binary.BigEndian.PutUint64(data[24:32], uint64(d.OriginTimestamp))
375 binary.BigEndian.PutUint64(data[32:40], uint64(d.ReceiveTimestamp))
376 binary.BigEndian.PutUint64(data[40:48], uint64(d.TransmitTimestamp))
377
378 ex, err := b.AppendBytes(len(d.ExtensionBytes))
379 if err != nil {
380 return err
381 }
382 copy(ex, d.ExtensionBytes)
383
384 return nil
385}
386
387//******************************************************************************
388
389// CanDecode returns a set of layers that NTP objects can decode.
390// As NTP objects can only decide the NTP layer, we can return just that layer.
391// Apparently a single layer type implements LayerClass.
392func (d *NTP) CanDecode() gopacket.LayerClass {
393 return LayerTypeNTP
394}
395
396//******************************************************************************
397
398// NextLayerType specifies the next layer that GoPacket should attempt to
399// analyse after this (NTP) layer. As NTP packets do not contain any payload
400// bytes, there are no further layers to analyse.
401func (d *NTP) NextLayerType() gopacket.LayerType {
402 return gopacket.LayerTypeZero
403}
404
405//******************************************************************************
406
407// NTP packets do not carry any data payload, so the empty byte slice is retured.
408// In Go, a nil slice is functionally identical to an empty slice, so we
409// return nil to avoid a heap allocation.
410func (d *NTP) Payload() []byte {
411 return nil
412}
413
414//******************************************************************************
415//* End Of NTP File *
416//******************************************************************************