1 // Copyright 2016 Google, Inc. All rights reserved.
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
7 //******************************************************************************
15 "github.com/google/gopacket"
18 //******************************************************************************
20 // Network Time Protocol (NTP) Decoding Layer
21 // ------------------------------------------
22 // This file provides a GoPacket decoding layer for NTP.
24 //******************************************************************************
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.
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
36 //******************************************************************************
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.
45 // Network Time Protocol Home Website:
46 // http://www.ntp.org/
47 // This appears to be the official website of NTP.
49 // List of current NTP Protocol RFCs:
50 // http://www.ntp.org/rfc.html
52 // RFC 958: "Network Time Protocol (NTP)" (1985)
53 // https://tools.ietf.org/html/rfc958
54 // This is the original NTP specification.
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.
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.
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.
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.
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.
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.
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.
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.
94 //******************************************************************************
96 // Obsolete References
97 // -------------------
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).
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.
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.
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.
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.
121 //******************************************************************************
123 // Endian And Bit Numbering Issues
124 // -------------------------------
126 // Endian and bit numbering issues can be confusing. Here is some
129 // ENDIAN: Values are sent big endian.
130 // https://en.wikipedia.org/wiki/Endianness
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.
137 // See RFC 791 Appendix B for more discussion.
139 //******************************************************************************
141 // NTP V3 and V4 Packet Format
142 // ---------------------------
143 // NTP packets are UDP packets whose payload contains an NTP record.
145 // The NTP RFC defines the format of the NTP record.
147 // There have been four versions of the protocol:
154 // It is clear that V1 and V2 are obsolete, and there is no need to
155 // cater for these formats.
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.
160 // The current version of NTP (NTP V4)'s RFC (V4 - RFC 5905) contains
161 // the following diagram for the NTP record format:
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 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
169 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
170 // | Root Dispersion |
171 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
173 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
175 // + Reference Timestamp (64) +
177 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
179 // + Origin Timestamp (64) +
181 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
183 // + Receive Timestamp (64) +
185 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
187 // + Transmit Timestamp (64) +
189 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
192 // . Extension Field 1 (variable) .
195 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
198 // . Extension Field 2 (variable) .
201 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
202 // | Key Identifier |
203 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
207 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
208 // From http://www.ietf.org/rfc/rfc5905.txt
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.
213 const ntpMinimumRecordSizeInBytes int = 48
215 //******************************************************************************
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.
224 type NTPLeapIndicator uint8
225 type NTPVersion uint8
227 type NTPStratum uint8
228 type NTPLog2Seconds int8
229 type NTPFixed16Seconds uint32
230 type NTPReferenceID uint32
231 type NTPTimestamp uint64
234 BaseLayer // Stores the packet bytes and payload bytes.
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.
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.
254 //******************************************************************************
256 // LayerType returns the layer type of the NTP object, which is LayerTypeNTP.
257 func (d *NTP) LayerType() gopacket.LayerType {
261 //******************************************************************************
263 // decodeNTP analyses a byte slice and attempts to decode it as an NTP
264 // record of a UDP packet.
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).
269 // This function is employed in layertypes.go to register the NTP layer.
270 func decodeNTP(data []byte, p gopacket.PacketBuilder) error {
272 // Attempt to decode the byte slice.
274 err := d.DecodeFromBytes(data, p)
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.
282 p.SetApplicationLayer(d)
287 //******************************************************************************
289 // DecodeFromBytes analyses a byte slice and attempts to decode it as an NTP
290 // record of a UDP packet.
292 // Upon succeeds, it loads the NTP object with information about the packet
294 // Upon failure, it returns an error (non nil).
295 func (d *NTP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
297 // If the data block is too short to be a NTP record, then return an error.
298 if len(data) < ntpMinimumRecordSizeInBytes {
300 return errors.New("NTP packet too short")
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:"
307 // "While the minimum field length containing required fields is
308 // four words (16 octets), a maximum field length remains to be
311 // For this reason, the packet length is not checked here for being too long.
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)]}
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.
323 // The first few fields are all packed into the first 32 bits. Unpack them.
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])
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]))
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:]
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.
353 func (d *NTP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
354 data, err := b.PrependBytes(ntpMinimumRecordSizeInBytes)
359 // Pack the first few fields into the first 32 bits.
361 h |= (uint8(d.LeapIndicator) << 6) & 0xC0
362 h |= (uint8(d.Version) << 3) & 0x38
363 h |= (uint8(d.Mode)) & 0x07
365 data[1] = byte(d.Stratum)
366 data[2] = byte(d.Poll)
367 data[3] = byte(d.Precision)
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))
378 ex, err := b.AppendBytes(len(d.ExtensionBytes))
382 copy(ex, d.ExtensionBytes)
387 //******************************************************************************
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.
392 func (d *NTP) CanDecode() gopacket.LayerClass {
396 //******************************************************************************
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.
401 func (d *NTP) NextLayerType() gopacket.LayerType {
402 return gopacket.LayerTypeZero
405 //******************************************************************************
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.
410 func (d *NTP) Payload() []byte {
414 //******************************************************************************
415 //* End Of NTP File *
416 //******************************************************************************