Coverage Report

Created: 2024-02-25 06:29

/src/PcapPlusPlus/Packet++/header/NtpLayer.h
Line
Count
Source
1
#pragma once
2
3
#include "Logger.h"
4
#include "Layer.h"
5
#include "IpAddress.h"
6
7
/// @file
8
9
/**
10
 * \namespace pcpp
11
 * \brief The main namespace for the PcapPlusPlus lib
12
 */
13
namespace pcpp
14
{
15
    /**
16
   * @class NtpLayer
17
   * Represents a NTP (Network Time Protocol) layer
18
     *
19
     * @brief The NTP packet consists of an integral number of 32-bit (4 octet) words in network byte order.
20
     * The packet format consists of three components: the header itself, one or more optional extension fields (for v4),
21
     * and an optional message authentication code (MAC). Currently the extension fields are not supported. The NTP header is:
22
     *
23
     * @verbatim
24
       0                   1                   2                   3
25
       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
26
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
27
      |LI | VN  |Mode |    Stratum     |     Poll      |  Precision   |
28
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
29
      |                         Root Delay                            |
30
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31
      |                         Root Dispersion                       |
32
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33
      |                          Reference ID                         |
34
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35
      |                                                               |
36
      +                     Reference Timestamp (64)                  +
37
      |                                                               |
38
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39
      |                                                               |
40
      +                      Origin Timestamp (64)                    +
41
      |                                                               |
42
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43
      |                                                               |
44
      +                      Receive Timestamp (64)                   +
45
      |                                                               |
46
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47
      |                                                               |
48
      +                      Transmit Timestamp (64)                  +
49
      |                                                               |
50
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51
      |                                                               |
52
      .                                                               .
53
      .                Extension Field 1 (variable, only v4)          .
54
      .                                                               .
55
      |                                                               |
56
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
      |                                                               |
58
      .                                                               .
59
      .                Extension Field 1 (variable, only v4)          .
60
      .                                                               .
61
      |                                                               |
62
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63
      |                          Key Identifier                       |
64
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65
      |                                                               |
66
      |                   dgst (128 for v4, 64 for v3)                |
67
      |                                                               |
68
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69
     @endverbatim
70
     *
71
   */
72
    class NtpLayer : public Layer
73
    {
74
    private:
75
#pragma pack(push, 1)
76
        struct ntp_header
77
        {
78
#if (BYTE_ORDER == LITTLE_ENDIAN)
79
            /// 3-bit integer representing the mode
80
            uint8_t mode:3,
81
            /// 3-bit integer representing the NTP version number
82
            version:3,
83
            /// LI Leap Indicator (leap): 2-bit integer warning of an impending leap second to be inserted or deleted in the last minute of the current month
84
            leapIndicator:2;
85
#else
86
            /// LI Leap Indicator (leap): 2-bit integer warning of an impending leap second to be inserted or deleted in the last minute of the current month
87
            uint8_t leapIndicator:2,
88
            /// 3-bit integer representing the NTP version number
89
            version:3,
90
            /// 3-bit integer representing the mode
91
            mode:3;
92
#endif
93
            /// 8-bit integer representing the stratum
94
            uint8_t stratum;
95
            /// Total round-trip delay to the reference clock, in log2 seconds.
96
            int8_t pollInterval,
97
            /// 8-bit signed integer representing the precision of the system clock, in log2 seconds.
98
            precision;
99
            /// Total round-trip delay to the reference clock, in NTP short format.
100
            uint32_t rootDelay,
101
            /// Total dispersion to the reference clock, in NTP short format.
102
            rootDispersion,
103
            /// 32-bit code identifying the particular server or reference clock.  The interpretation depends on the value in the stratum field.
104
            referenceIdentifier;
105
            /// Time when the system clock was last set or corrected, in NTP timestamp format.
106
            uint64_t referenceTimestamp,
107
            /// Time at the client when the request departed for the server, in NTP timestamp format.
108
            originTimestamp,
109
            /// Time at the client when the request departed for the server, in NTP timestamp format.
110
            receiveTimestamp,
111
            /// Time at the server when the response left for the client, in NTP timestamp format.
112
            transmitTimestamp;
113
        };
114
#pragma pack(pop)
115
116
#pragma pack(push, 1)
117
        struct ntp_v3_auth
118
        {
119
            /// An integer identifying the cryptographic key used to generate the message-authentication code
120
            uint32_t keyID;
121
            /// This is an integer identifying the cryptographic key used to generate the message-authentication code.
122
            uint8_t dgst[8]; // 64 bit DES based
123
        };
124
#pragma pack(pop)
125
126
#pragma pack(push, 1)
127
        struct ntp_v4_auth_md5
128
        {
129
            /// 32-bit unsigned integer used by the client and server to designate a secret 128-bit MD5 key.
130
            uint32_t keyID;
131
            /// 128-bit MD5 hash
132
            uint8_t dgst[16];
133
        };
134
#pragma pack(pop)
135
136
#pragma pack(push, 1)
137
        struct ntp_v4_auth_sha1
138
        {
139
            /// 32-bit unsigned integer used by the client and server to designate a secret 160-bit SHA1 key.
140
            uint32_t keyID;
141
            /// 160-bit SHA1 hash
142
            uint8_t dgst[20];
143
        };
144
#pragma pack(pop)
145
146
55.7k
        ntp_header *getNtpHeader() const { return (ntp_header *)m_Data; }
147
148
    public:
149
        /**
150
        * Warning of an impending leap second to be inserted or deleted in the last minute of the current month
151
        */
152
        enum LeapIndicator
153
        {
154
            /// Normal, no leap second
155
            NoWarning = 0,
156
            /// Last minute of the day has 61 seconds
157
            Last61Secs,
158
            /// Last minute of the day has 59 seconds
159
            Last59Secs,
160
            /// Unknown (clock unsynchronized)
161
            Unknown
162
        };
163
164
        /**
165
         * Representing the NTP association modes
166
         */
167
        enum Mode
168
        {
169
            /// Reserved variable
170
            Reserved = 0,
171
            /// Symmetrically active
172
            SymActive,
173
            /// Symmetrically passive
174
            SymPassive,
175
            /// Client mode
176
            Client,
177
            /// Server mode
178
            Server,
179
            /// Broadcasting mode
180
            Broadcast,
181
            /// NTP control messages
182
            Control,
183
            /// Reserved for private use
184
            PrivateUse
185
        };
186
187
        /**
188
         * 32-bit code identifying the particular server or reference clock.
189
         * The interpretation depends on the value in the stratum field.
190
         */
191
        enum class ClockSource : uint32_t
192
        {
193
            // NTPv4
194
195
            /// Geosynchronous Orbit Environment Satellite
196
            GOES = ('G') | ('O' << 8) | ('E' << 16) | ('S' << 24),
197
            /// Global Position System
198
            GPS = ('G') | ('P' << 8) | ('S' << 16),
199
            /// Galileo Positioning System
200
            GAL = ('G') | ('A' << 8) | ('L' << 16),
201
            /// Generic pulse-per-second
202
            PPS = ('P') | ('P' << 8) | ('S' << 16),
203
            /// Inter-Range Instrumentation Group
204
            IRIG = ('I') | ('R' << 8) | ('I' << 16) | ('G' << 24),
205
            /// LF Radio WWVB Ft. Collins, CO 60 kHz
206
            WWVB = ('W') | ('W' << 8) | ('V' << 16) | ('B' << 24),
207
            /// LF Radio DCF77 Mainflingen, DE 77.5 kHz
208
            DCF = ('D') | ('C' << 8) | ('F' << 16),
209
            /// LF Radio HBG Prangins, HB 75 kHz
210
            HBG = ('H') | ('B' << 8) | ('G' << 16),
211
            /// LF Radio MSF Anthorn, UK 60 kHz
212
            MSF = ('M') | ('S' << 8) | ('F' << 16),
213
            /// LF Radio JJY Fukushima, JP 40 kHz, Saga, JP 60 kHz
214
            JJY = ('J') | ('J' << 8) | ('Y' << 16),
215
            /// MF Radio LORAN C station, 100 kHz
216
            LORC = ('L') | ('O' << 8) | ('R' << 16) | ('C' << 24),
217
            /// MF Radio Allouis, FR 162 kHz
218
            TDF = ('T') | ('D' << 8) | ('F' << 16),
219
            /// HF Radio CHU Ottawa, Ontario
220
            CHU = ('C') | ('H' << 8) | ('U' << 16),
221
            /// HF Radio WWV Ft. Collins, CO
222
            WWV = ('W') | ('W' << 8) | ('V' << 16),
223
            /// HF Radio WWVH Kauai, HI
224
            WWVH = ('W') | ('W' << 8) | ('V' << 16) | ('H' << 24),
225
            /// NIST telephone modem
226
            NIST = ('N') | ('I' << 8) | ('S' << 16) | ('T' << 24),
227
            /// NIST telephone modem
228
            ACTS = ('A') | ('C' << 8) | ('T' << 16) | ('S' << 24),
229
            /// USNO telephone modem
230
            USNO = ('U') | ('S' << 8) | ('N' << 16) | ('O' << 24),
231
            /// European telephone modem
232
            PTB = ('P') | ('T' << 8) | ('B' << 16),
233
            /// Multi Reference Sources
234
            MRS = ('M') | ('R' << 8) | ('S' << 16),
235
            /// Inter Face Association Changed
236
            XFAC = ('X') | ('F' << 8) | ('A' << 16) | ('C' << 24),
237
            /// Step time change
238
            STEP = ('S') | ('T' << 8) | ('E' << 16) | ('P' << 24),
239
            /// Google Refid used by Google NTP servers as time4.google.com
240
            GOOG = ('G') | ('O' << 8) | ('O' << 16) | ('G' << 24),
241
            /// Meinberg DCF77 with amplitude modulation (Ref: https://www.meinbergglobal.com/english/info/ntp-refid.htm)
242
            DCFa = ('D') | ('C' << 8) | ('F' << 16) | ('a' << 24),
243
            /// Meinberg DCF77 with phase modulation)/pseudo random phase modulation (Ref: https://www.meinbergglobal.com/english/info/ntp-refid.htm)
244
            DCFp = ('D') | ('C' << 8) | ('F' << 16) | ('p' << 24),
245
            /// Meinberg GPS (with shared memory access) (Ref: https://www.meinbergglobal.com/english/info/ntp-refid.htm)
246
            GPSs = ('G') | ('P' << 8) | ('S' << 16) | ('s' << 24),
247
            /// Meinberg GPS (with interrupt based access) (Ref: https://www.meinbergglobal.com/english/info/ntp-refid.htm)
248
            GPSi = ('G') | ('P' << 8) | ('S' << 16) | ('i' << 24),
249
            /// Meinberg GPS/GLONASS (with shared memory access) (Ref: https://www.meinbergglobal.com/english/info/ntp-refid.htm)
250
            GLNs = ('G') | ('L' << 8) | ('N' << 16) | ('s' << 24),
251
            /// Meinberg GPS/GLONASS (with interrupt based access) (Ref: https://www.meinbergglobal.com/english/info/ntp-refid.htm)
252
            GLNi = ('G') | ('L' << 8) | ('N' << 16) | ('i' << 24),
253
            /// Meinberg Undisciplined local clock (Ref: https://www.meinbergglobal.com/english/info/ntp-refid.htm)
254
            LCL = ('L') | ('C' << 8) | ('L' << 16),
255
            /// Meinberg Undisciplined local clock (Ref: https://www.meinbergglobal.com/english/info/ntp-refid.htm)
256
            LOCL = ('L') | ('O' << 8) | ('C' << 16) | ('L' << 24),
257
258
            // NTPv3
259
260
            /// DCN routing protocol
261
            DCN = ('D') | ('C' << 8) | ('N' << 16),
262
            /// TSP time protocol
263
            TSP = ('T') | ('S' << 8) | ('P' << 16),
264
            /// Digital Time Service
265
            DTS = ('D') | ('T' << 8) | ('S' << 16),
266
            /// Atomic clock (calibrated)
267
            ATOM = ('A') | ('T' << 8) | ('O' << 16) | ('M' << 24),
268
            /// VLF radio (OMEGA, etc.)
269
            VLF = ('V') | ('L' << 8) | ('F' << 16)
270
271
        };
272
273
        /**
274
         * 32-bit Kiss of Death (KoD) codes
275
         */
276
        enum class KissODeath : uint32_t
277
        {
278
            /// The association belongs to a anycast server
279
            ACST = ('A') | ('C' << 8) | ('S' << 16) | ('T' << 24),
280
            /// Server authentication failed
281
            AUTH = ('A') | ('U' << 8) | ('T' << 16) | ('H' << 24),
282
            /// Autokey sequence failed
283
            AUTO = ('A') | ('U' << 8) | ('T' << 16) | ('O' << 24),
284
            /// The association belongs to a broadcast server
285
            BCST = ('B') | ('C' << 8) | ('S' << 16) | ('T' << 24),
286
            /// Cryptographic authentication or identification failed
287
            CRYP = ('C') | ('R' << 8) | ('Y' << 16) | ('P' << 24),
288
            /// Access denied by remote server
289
            DENY = ('D') | ('E' << 8) | ('N' << 16) | ('Y' << 24),
290
            /// Lost peer in symmetric mode
291
            DROP = ('D') | ('R' << 8) | ('O' << 16) | ('P' << 24),
292
            /// Access denied due to local policy
293
            RSTR = ('R') | ('S' << 8) | ('T' << 16) | ('R' << 24),
294
            /// The association has not yet synchronized for the first time
295
            INIT = ('I') | ('N' << 8) | ('I' << 16) | ('T' << 24),
296
            /// The association belongs to a manycast server
297
            MCST = ('M') | ('C' << 8) | ('S' << 16) | ('T' << 24),
298
            /// No key found.  Either the key was never installed or is not trusted
299
            NKEY = ('N') | ('K' << 8) | ('E' << 16) | ('Y' << 24),
300
            /// Rate exceeded.  The server has temporarily denied access because the client exceeded the rate threshold
301
            RATE = ('R') | ('A' << 8) | ('T' << 16) | ('E' << 24),
302
            /// Somebody is tinkering with the association from a remote host running ntpdc.  Not to worry unless some rascal has stolen your keys
303
            RMOT = ('R') | ('M' << 8) | ('O' << 16) | ('T' << 24),
304
            /// A step change in system time has occurred, but the association has not yet resynchronized
305
            STEP = ('S') | ('T' << 8) | ('E' << 16) | ('P' << 24),
306
        };
307
308
        /**
309
     * A constructor that creates the layer from an existing packet raw data
310
     * @param[in] data A pointer to the raw data
311
     * @param[in] dataLen Size of the data in bytes
312
     * @param[in] prevLayer A pointer to the previous layer
313
     * @param[in] packet A pointer to the Packet instance where layer will be stored in
314
     */
315
6.60k
        NtpLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet) : Layer(data, dataLen, prevLayer, packet) { m_Protocol = NTP; }
316
317
        /**
318
         * Empty c'tor
319
         */
320
        NtpLayer();
321
322
        /**
323
         * @return The leap indicator
324
         */
325
        LeapIndicator getLeapIndicator() const;
326
327
        /**
328
         * Set the leap indicator
329
         */
330
        void setLeapIndicator(LeapIndicator val);
331
332
        /**
333
         * @return The version of NTP
334
         */
335
        uint8_t getVersion() const;
336
337
        /**
338
         * Set the version of NTP
339
         */
340
        void setVersion(uint8_t val);
341
342
        /**
343
         * @return The mode value
344
         */
345
        Mode getMode() const;
346
347
        /**
348
         * @return The mode as string
349
         */
350
        std::string getModeString() const;
351
352
        /**
353
         * Set the mode
354
         */
355
        void setMode(Mode val);
356
357
        /**
358
         * @return The value of stratum
359
         */
360
        uint8_t getStratum() const;
361
362
        /**
363
         * Set the value of stratum
364
         */
365
        void setStratum(uint8_t val);
366
367
        /**
368
         * @return The value of poll interval in log2 seconds
369
         */
370
        int8_t getPollInterval() const;
371
372
        /**
373
         * Set the value of poll interval
374
         * @param[in] val Poll interval in log2 seconds
375
         */
376
        void setPollInterval(int8_t val);
377
378
        /**
379
         * @return The value of poll interval in seconds
380
         */
381
        double getPollIntervalInSecs() const;
382
383
        /**
384
         * @return The value of precision in log2 seconds
385
         */
386
        int8_t getPrecision() const;
387
388
        /**
389
         * Set the value of precision
390
         * @param[in] val Precision in log2 seconds
391
         */
392
        void setPrecision(int8_t val);
393
394
        /**
395
         * @return The value of precision in seconds
396
         */
397
        double getPrecisionInSecs() const;
398
399
        /**
400
         * @return The value of root delay in NTP short format
401
         */
402
        uint32_t getRootDelay() const;
403
404
        /**
405
         * Set the value of root delay
406
         * @param[in] val Root delay in NTP short format
407
         */
408
        void setRootDelay(uint32_t val);
409
410
        /**
411
         * @return The value of root delay in seconds
412
         */
413
        double getRootDelayInSecs() const;
414
415
        /**
416
         * Set the value of root delay
417
         * @param[in] val Root delay in seconds
418
         */
419
        void setRootDelayInSecs(double val);
420
421
        /**
422
         * @return The value of root dispersion in NTP short format
423
         */
424
        uint32_t getRootDispersion() const;
425
426
        /**
427
         * Set the value of root delay
428
         * @param[in] val Root dispersion in NTP short format
429
         */
430
        void setRootDispersion(uint32_t val);
431
432
        /**
433
         * @return The value of root dispersion in seconds
434
         */
435
        double getRootDispersionInSecs() const;
436
437
        /**
438
         * Set the value of root dispersion
439
         * @param[in] val Root dispersion in seconds
440
         */
441
        void setRootDispersionInSecs(double val);
442
443
        /**
444
         * @return The value of reference identifier
445
         */
446
        uint32_t getReferenceIdentifier() const;
447
448
        /**
449
         * Set the value of reference identifier
450
         * @param[in] val Value of the reference identifier as IPv4 address
451
         */
452
        void setReferenceIdentifier(IPv4Address val);
453
454
        /**
455
         * Set the value of reference identifier
456
         * @param[in] val Value of the reference identifier as ClockSource
457
         */
458
        void setReferenceIdentifier(ClockSource val);
459
460
        /**
461
         * Set the value of reference identifier
462
         * @param[in] val Value of the reference identifier as Kiss-O-Death code
463
         */
464
        void setReferenceIdentifier(KissODeath val);
465
466
        /**
467
         * @return The value of reference identifier as a string. String representation of NTP clock source if stratum is 1,
468
         * IPv4 address or MD5 hash of first four octets of IPv6
469
         */
470
        std::string getReferenceIdentifierString() const;
471
472
        /**
473
         * @return The value of reference timestamp in NTP timestamp format
474
         */
475
        uint64_t getReferenceTimestamp() const;
476
477
        /**
478
         * Set the value of reference timestamp
479
         * @param[in] val Timestamp in NTP timestamp format
480
         */
481
        void setReferenceTimestamp(uint64_t val);
482
483
        /**
484
         * @return The value of reference timestamp in seconds from Unix Epoch (1 Jan 1970)
485
         */
486
        double getReferenceTimestampInSecs() const;
487
488
        /**
489
         * Set the value of reference timestamp
490
         * @param[in] val Value in seconds from Unix Epoch (1 Jan 1970)
491
         */
492
        void setReferenceTimestampInSecs(double val);
493
494
        /**
495
         * @return The reference timestamp value as readable string in ISO8601 format
496
         */
497
        std::string getReferenceTimestampAsString();
498
499
        /**
500
         * @return The value of origin timestamp in NTP timestamp format
501
         */
502
        uint64_t getOriginTimestamp() const;
503
504
        /**
505
         * Set the value of origin timestamp
506
         * @param[in] val Value in NTP timestamp format
507
         */
508
        void setOriginTimestamp(uint64_t val);
509
510
        /**
511
         * @return The value of origin timestamp in seconds from Unix Epoch (1 Jan 1970)
512
         */
513
        double getOriginTimestampInSecs() const;
514
515
        /**
516
         * Set the value of origin timestamp
517
         * @param[in] val Value in seconds from Unix Epoch (1 Jan 1970)
518
         */
519
        void setOriginTimestampInSecs(double val);
520
521
        /**
522
         * @return the origin timestamp value as readable string in ISO8601 format
523
         */
524
        std::string getOriginTimestampAsString();
525
526
        /**
527
         * @return The value of receive timestamp in NTP timestamp format
528
         */
529
        uint64_t getReceiveTimestamp() const;
530
531
        /**
532
         * Set the value of receive timestamp
533
         * @param[in] val Value in NTP timestamp format
534
         */
535
        void setReceiveTimestamp(uint64_t val);
536
537
        /**
538
         * @return The value of receive timestampin seconds from Unix Epoch (1 Jan 1970)
539
         */
540
        double getReceiveTimestampInSecs() const;
541
542
        /**
543
         * Set the value of receive timestamp
544
         * @param[in] val Value in seconds from Unix Epoch (1 Jan 1970)
545
         */
546
        void setReceiveTimestampInSecs(double val);
547
548
        /**
549
         * @return The receive timestamp value as readable string in ISO8601 format
550
         */
551
        std::string getReceiveTimestampAsString();
552
553
        /**
554
         * @return The value of transmit timestamp in NTP timestamp format
555
         */
556
        uint64_t getTransmitTimestamp() const;
557
558
        /**
559
         * Set the value of transmit timestamp
560
         * @param[in] val Value in NTP timestamp format
561
         */
562
        void setTransmitTimestamp(uint64_t val);
563
564
        /**
565
         * @return The value of transmit timestamp in seconds from Unix Epoch (1 Jan 1970)
566
         */
567
        double getTransmitTimestampInSecs() const;
568
569
        /**
570
         * Set the value of transmit timestamp
571
         * @param[in] val Value in seconds from Unix Epoch (1 Jan 1970)
572
         */
573
        void setTransmitTimestampInSecs(double val);
574
575
        /**
576
         * @return The transmit timestamp value as readable string in ISO8601 format
577
         */
578
        std::string getTransmitTimestampAsString();
579
580
        /**
581
         * @return Returns the key identifier if exists, returns 0 on unsupported NTP version or key identifier not found
582
         */
583
        uint32_t getKeyID() const;
584
585
        /**
586
         * @return Get the digest value as hexadecimal string, empty string on unsupported version
587
         */
588
        std::string getDigest() const;
589
590
        /**
591
         * Convert NTP short format to seconds from the Unix Epoch
592
         *
593
         * @param[in] val Value in NTP short format
594
         * @return Value in seconds from Unix Epoch (1 Jan 1970)
595
         */
596
        static double convertFromShortFormat(const uint32_t val);
597
598
        /**
599
         * Convert NTP timestamp format to seconds from the Unix Epoch
600
         *
601
         * @param[in] val Value in NTP timestamp format
602
         * @return Value in seconds from Unix Epoch (1 Jan 1970)
603
         */
604
        static double convertFromTimestampFormat(const uint64_t val);
605
606
        /**
607
         * Convert seconds from the Unix Epoch to NTP short format
608
         *
609
         * @param[in] val Value in seconds from Unix Epoch (1 Jan 1970)
610
         * @return Value in NTP short format
611
         */
612
        static uint32_t convertToShortFormat(const double val);
613
614
        /**
615
         * Convert seconds from the Unix Epoch to NTP timestamp format
616
         *
617
         * @param[in] val Value in seconds from Unix Epoch (1 Jan 1970)
618
         * @return Value in NTP timestamp format
619
         */
620
        static uint64_t convertToTimestampFormat(const double val);
621
622
        /**
623
         * A static method to convert timestamp value to ISO8601 date time format
624
         * @param[in] timestamp Value in seconds from the Unix Epoch
625
         * @return std::string ISO8601 formatted string
626
         */
627
        static std::string convertToIsoFormat(const double timestamp);
628
629
        /**
630
         * A static method to convert timestamp value to ISO8601 date time format
631
         * @param[in] timestampInNTPformat Value in NTP timestamp format
632
         * @return std::string ISO8601 formatted string
633
         */
634
        static std::string convertToIsoFormat(const uint64_t timestampInNTPformat);
635
636
        /**
637
     * A static method that takes a byte array and detects whether it is a NTP message
638
     * @param[in] data A byte array
639
     * @param[in] dataSize The byte array size (in bytes)
640
     * @return True if the data is identified as NTP message
641
     */
642
        static bool isDataValid(const uint8_t *data, size_t dataSize);
643
644
        /**
645
     * A static method that checks whether the port is considered as NTP
646
     * @param[in] port The port number to be checked
647
     */
648
186k
        static bool isNTPPort(uint16_t port) { return port == 123; }
649
650
        // overridden methods
651
652
        /// Parses the next layer. NTP is the always last so does nothing for this layer
653
6.60k
        void parseNextLayer() {}
654
655
        /**
656
         * @return Get the size of the layer (Including the extension and authentication fields if exists)
657
         */
658
2.68k
        size_t getHeaderLen() const { return m_DataLen; }
659
660
        /// Does nothing for this layer
661
1.34k
        void computeCalculateFields() {}
662
663
        /**
664
         * @return The OSI layer level of NTP (Application Layer).
665
         */
666
1.34k
        OsiModelLayer getOsiModelLayer() const { return OsiModelApplicationLayer; }
667
668
        /**
669
         * @return Returns the protocol info as readable string
670
         */
671
        std::string toString() const;
672
    };
673
674
} // namespace pcpp