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 //******************************************************************************