github.com/gopacket/gopacket@v1.1.0/layers/ntp.go (about)

     1  // 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  
     9  package layers
    10  
    11  import (
    12  	"encoding/binary"
    13  	"errors"
    14  
    15  	"github.com/gopacket/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  const ntpMinimumRecordSizeInBytes int = 48
   213  
   214  //******************************************************************************
   215  
   216  // NTP Type
   217  // --------
   218  // Type NTP implements the DecodingLayer interface. Each NTP object
   219  // represents in a structured form the NTP record present as the UDP
   220  // payload in an NTP UDP packet.
   221  //
   222  
   223  type NTPLeapIndicator uint8
   224  type NTPVersion uint8
   225  type NTPMode uint8
   226  type NTPStratum uint8
   227  type NTPLog2Seconds int8
   228  type NTPFixed16Seconds uint32
   229  type NTPReferenceID uint32
   230  type NTPTimestamp uint64
   231  
   232  type NTP struct {
   233  	BaseLayer // Stores the packet bytes and payload bytes.
   234  
   235  	LeapIndicator      NTPLeapIndicator  // [0,3]. Indicates whether leap second(s) is to be added.
   236  	Version            NTPVersion        // [0,7]. Version of the NTP protocol.
   237  	Mode               NTPMode           // [0,7]. Mode.
   238  	Stratum            NTPStratum        // [0,255]. Stratum of time server in the server tree.
   239  	Poll               NTPLog2Seconds    // [-128,127]. The maximum interval between successive messages, in log2 seconds.
   240  	Precision          NTPLog2Seconds    // [-128,127]. The precision of the system clock, in log2 seconds.
   241  	RootDelay          NTPFixed16Seconds // [0,2^32-1]. Total round trip delay to the reference clock in seconds times 2^16.
   242  	RootDispersion     NTPFixed16Seconds // [0,2^32-1]. Total dispersion to the reference clock, in seconds times 2^16.
   243  	ReferenceID        NTPReferenceID    // ID code of reference clock [0,2^32-1].
   244  	ReferenceTimestamp NTPTimestamp      // Most recent timestamp from the reference clock.
   245  	OriginTimestamp    NTPTimestamp      // Local time when request was sent from local host.
   246  	ReceiveTimestamp   NTPTimestamp      // Local time (on server) that request arrived at server host.
   247  	TransmitTimestamp  NTPTimestamp      // Local time (on server) that request departed server host.
   248  
   249  	// FIX: This package should analyse the extension fields and represent the extension fields too.
   250  	ExtensionBytes []byte // Just put extensions in a byte slice.
   251  }
   252  
   253  //******************************************************************************
   254  
   255  // LayerType returns the layer type of the NTP object, which is LayerTypeNTP.
   256  func (d *NTP) LayerType() gopacket.LayerType {
   257  	return LayerTypeNTP
   258  }
   259  
   260  //******************************************************************************
   261  
   262  // decodeNTP analyses a byte slice and attempts to decode it as an NTP
   263  // record of a UDP packet.
   264  //
   265  // If it succeeds, it loads p with information about the packet and returns nil.
   266  // If it fails, it returns an error (non nil).
   267  //
   268  // This function is employed in layertypes.go to register the NTP layer.
   269  func decodeNTP(data []byte, p gopacket.PacketBuilder) error {
   270  
   271  	// Attempt to decode the byte slice.
   272  	d := &NTP{}
   273  	err := d.DecodeFromBytes(data, p)
   274  	if err != nil {
   275  		return err
   276  	}
   277  
   278  	// If the decoding worked, add the layer to the packet and set it
   279  	// as the application layer too, if there isn't already one.
   280  	p.AddLayer(d)
   281  	p.SetApplicationLayer(d)
   282  
   283  	return nil
   284  }
   285  
   286  //******************************************************************************
   287  
   288  // DecodeFromBytes analyses a byte slice and attempts to decode it as an NTP
   289  // record of a UDP packet.
   290  //
   291  // Upon succeeds, it loads the NTP object with information about the packet
   292  // and returns nil.
   293  // Upon failure, it returns an error (non nil).
   294  func (d *NTP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
   295  
   296  	// If the data block is too short to be a NTP record, then return an error.
   297  	if len(data) < ntpMinimumRecordSizeInBytes {
   298  		df.SetTruncated()
   299  		return errors.New("NTP packet too short")
   300  	}
   301  
   302  	// RFC 5905 does not appear to define a maximum NTP record length.
   303  	// The protocol allows "extension fields" to be included in the record,
   304  	// and states about these fields:"
   305  	//
   306  	//     "While the minimum field length containing required fields is
   307  	//      four words (16 octets), a maximum field length remains to be
   308  	//      established."
   309  	//
   310  	// For this reason, the packet length is not checked here for being too long.
   311  
   312  	// NTP type embeds type BaseLayer which contains two fields:
   313  	//    Contents is supposed to contain the bytes of the data at this level.
   314  	//    Payload is supposed to contain the payload of this level.
   315  	// Here we set the baselayer to be the bytes of the NTP record.
   316  	d.BaseLayer = BaseLayer{Contents: data[:len(data)]}
   317  
   318  	// Extract the fields from the block of bytes.
   319  	// To make sense of this, refer to the packet diagram
   320  	// above and the section on endian conventions.
   321  
   322  	// The first few fields are all packed into the first 32 bits. Unpack them.
   323  	f := data[0]
   324  	d.LeapIndicator = NTPLeapIndicator((f & 0xC0) >> 6)
   325  	d.Version = NTPVersion((f & 0x38) >> 3)
   326  	d.Mode = NTPMode(f & 0x07)
   327  	d.Stratum = NTPStratum(data[1])
   328  	d.Poll = NTPLog2Seconds(data[2])
   329  	d.Precision = NTPLog2Seconds(data[3])
   330  
   331  	// The remaining fields can just be copied in big endian order.
   332  	d.RootDelay = NTPFixed16Seconds(binary.BigEndian.Uint32(data[4:8]))
   333  	d.RootDispersion = NTPFixed16Seconds(binary.BigEndian.Uint32(data[8:12]))
   334  	d.ReferenceID = NTPReferenceID(binary.BigEndian.Uint32(data[12:16]))
   335  	d.ReferenceTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[16:24]))
   336  	d.OriginTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[24:32]))
   337  	d.ReceiveTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[32:40]))
   338  	d.TransmitTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[40:48]))
   339  
   340  	// This layer does not attempt to analyse the extension bytes.
   341  	// But if there are any, we'd like the user to know. So we just
   342  	// place them all in an ExtensionBytes field.
   343  	d.ExtensionBytes = data[48:]
   344  
   345  	// Return no error.
   346  	return nil
   347  }
   348  
   349  // SerializeTo writes the serialized form of this layer into the
   350  // SerializationBuffer, implementing gopacket.SerializableLayer.
   351  // See the docs for gopacket.SerializableLayer for more info.
   352  func (d *NTP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
   353  	data, err := b.PrependBytes(ntpMinimumRecordSizeInBytes)
   354  	if err != nil {
   355  		return err
   356  	}
   357  
   358  	// Pack the first few fields into the first 32 bits.
   359  	h := uint8(0)
   360  	h |= (uint8(d.LeapIndicator) << 6) & 0xC0
   361  	h |= (uint8(d.Version) << 3) & 0x38
   362  	h |= (uint8(d.Mode)) & 0x07
   363  	data[0] = byte(h)
   364  	data[1] = byte(d.Stratum)
   365  	data[2] = byte(d.Poll)
   366  	data[3] = byte(d.Precision)
   367  
   368  	// The remaining fields can just be copied in big endian order.
   369  	binary.BigEndian.PutUint32(data[4:8], uint32(d.RootDelay))
   370  	binary.BigEndian.PutUint32(data[8:12], uint32(d.RootDispersion))
   371  	binary.BigEndian.PutUint32(data[12:16], uint32(d.ReferenceID))
   372  	binary.BigEndian.PutUint64(data[16:24], uint64(d.ReferenceTimestamp))
   373  	binary.BigEndian.PutUint64(data[24:32], uint64(d.OriginTimestamp))
   374  	binary.BigEndian.PutUint64(data[32:40], uint64(d.ReceiveTimestamp))
   375  	binary.BigEndian.PutUint64(data[40:48], uint64(d.TransmitTimestamp))
   376  
   377  	ex, err := b.AppendBytes(len(d.ExtensionBytes))
   378  	if err != nil {
   379  		return err
   380  	}
   381  	copy(ex, d.ExtensionBytes)
   382  
   383  	return nil
   384  }
   385  
   386  //******************************************************************************
   387  
   388  // CanDecode returns a set of layers that NTP objects can decode.
   389  // As NTP objects can only decide the NTP layer, we can return just that layer.
   390  // Apparently a single layer type implements LayerClass.
   391  func (d *NTP) CanDecode() gopacket.LayerClass {
   392  	return LayerTypeNTP
   393  }
   394  
   395  //******************************************************************************
   396  
   397  // NextLayerType specifies the next layer that GoPacket should attempt to
   398  // analyse after this (NTP) layer. As NTP packets do not contain any payload
   399  // bytes, there are no further layers to analyse.
   400  func (d *NTP) NextLayerType() gopacket.LayerType {
   401  	return gopacket.LayerTypeZero
   402  }
   403  
   404  //******************************************************************************
   405  
   406  // NTP packets do not carry any data payload, so the empty byte slice is retured.
   407  // In Go, a nil slice is functionally identical to an empty slice, so we
   408  // return nil to avoid a heap allocation.
   409  func (d *NTP) Payload() []byte {
   410  	return nil
   411  }
   412  
   413  //******************************************************************************
   414  //*                            End Of NTP File                                 *
   415  //******************************************************************************