/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 | | /// @namespace pcpp |
10 | | /// @brief The main namespace for the PcapPlusPlus lib |
11 | | namespace pcpp |
12 | | { |
13 | | /// @class NtpLayer |
14 | | /// Represents a NTP (Network Time Protocol) layer |
15 | | /// |
16 | | /// @brief The NTP packet consists of an integral number of 32-bit (4 octet) words in network byte order. |
17 | | /// The packet format consists of three components: the header itself, one or more optional extension fields (for |
18 | | /// v4), and an optional message authentication code (MAC). Currently the extension fields are not supported. The |
19 | | /// NTP header is: |
20 | | /// |
21 | | /// @code{.unparsed} |
22 | | /// 0 1 2 3 |
23 | | /// 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 |
24 | | /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
25 | | /// |LI | VN |Mode | Stratum | Poll | Precision | |
26 | | /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
27 | | /// | Root Delay | |
28 | | /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
29 | | /// | Root Dispersion | |
30 | | /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
31 | | /// | Reference ID | |
32 | | /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
33 | | /// | | |
34 | | /// + Reference Timestamp (64) + |
35 | | /// | | |
36 | | /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
37 | | /// | | |
38 | | /// + Origin Timestamp (64) + |
39 | | /// | | |
40 | | /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
41 | | /// | | |
42 | | /// + Receive Timestamp (64) + |
43 | | /// | | |
44 | | /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
45 | | /// | | |
46 | | /// + Transmit Timestamp (64) + |
47 | | /// | | |
48 | | /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
49 | | /// | | |
50 | | /// . . |
51 | | /// . Extension Field 1 (variable, only v4) . |
52 | | /// . . |
53 | | /// | | |
54 | | /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
55 | | /// | | |
56 | | /// . . |
57 | | /// . Extension Field 1 (variable, only v4) . |
58 | | /// . . |
59 | | /// | | |
60 | | /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
61 | | /// | Key Identifier | |
62 | | /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
63 | | /// | | |
64 | | /// | dgst (128 for v4, 64 for v3) | |
65 | | /// | | |
66 | | /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
67 | | /// @endcode |
68 | | class NtpLayer : public Layer |
69 | | { |
70 | | private: |
71 | | #pragma pack(push, 1) |
72 | | struct ntp_header |
73 | | { |
74 | | #if (BYTE_ORDER == LITTLE_ENDIAN) |
75 | | /// 3-bit integer representing the mode |
76 | | uint8_t mode : 3, |
77 | | /// 3-bit integer representing the NTP version number |
78 | | version : 3, |
79 | | /// LI Leap Indicator (leap): 2-bit integer warning of an impending leap second to be inserted or |
80 | | /// deleted in the last minute of the current month |
81 | | leapIndicator : 2; |
82 | | #else |
83 | | /// LI Leap Indicator (leap): 2-bit integer warning of an impending leap second to be inserted or deleted in |
84 | | /// the last minute of the current month |
85 | | uint8_t leapIndicator : 2, |
86 | | /// 3-bit integer representing the NTP version number |
87 | | version : 3, |
88 | | /// 3-bit integer representing the mode |
89 | | mode : 3; |
90 | | #endif |
91 | | /// 8-bit integer representing the stratum |
92 | | uint8_t stratum; |
93 | | /// Total round-trip delay to the reference clock, in log2 seconds. |
94 | | int8_t pollInterval, |
95 | | /// 8-bit signed integer representing the precision of the system clock, in log2 seconds. |
96 | | precision; |
97 | | /// Total round-trip delay to the reference clock, in NTP short format. |
98 | | uint32_t rootDelay, |
99 | | /// Total dispersion to the reference clock, in NTP short format. |
100 | | rootDispersion, |
101 | | /// 32-bit code identifying the particular server or reference clock. The interpretation depends on the |
102 | | /// value in the stratum field. |
103 | | referenceIdentifier; |
104 | | /// Time when the system clock was last set or corrected, in NTP timestamp format. |
105 | | uint64_t referenceTimestamp, |
106 | | /// Time at the client when the request departed for the server, in NTP timestamp format. |
107 | | originTimestamp, |
108 | | /// Time at the client when the request departed for the server, in NTP timestamp format. |
109 | | receiveTimestamp, |
110 | | /// Time at the server when the response left for the client, in NTP timestamp format. |
111 | | transmitTimestamp; |
112 | | }; |
113 | | #pragma pack(pop) |
114 | | static_assert(sizeof(ntp_header) == 48, "ntp_header size is not 48 bytes"); |
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 | | static_assert(sizeof(ntp_v3_auth) == 12, "ntp_v3_auth size is not 12 bytes"); |
126 | | |
127 | | #pragma pack(push, 1) |
128 | | struct ntp_v4_auth_md5 |
129 | | { |
130 | | /// 32-bit unsigned integer used by the client and server to designate a secret 128-bit MD5 key. |
131 | | uint32_t keyID; |
132 | | /// 128-bit MD5 hash |
133 | | uint8_t dgst[16]; |
134 | | }; |
135 | | #pragma pack(pop) |
136 | | static_assert(sizeof(ntp_v4_auth_md5) == 20, "ntp_v4_auth_md5 size is not 20 bytes"); |
137 | | |
138 | | #pragma pack(push, 1) |
139 | | struct ntp_v4_auth_sha1 |
140 | | { |
141 | | /// 32-bit unsigned integer used by the client and server to designate a secret 160-bit SHA1 key. |
142 | | uint32_t keyID; |
143 | | /// 160-bit SHA1 hash |
144 | | uint8_t dgst[20]; |
145 | | }; |
146 | | #pragma pack(pop) |
147 | | static_assert(sizeof(ntp_v4_auth_sha1) == 24, "ntp_v4_auth_sha1 size is not 24 bytes"); |
148 | | |
149 | | ntp_header* getNtpHeader() const |
150 | 29.6k | { |
151 | 29.6k | return reinterpret_cast<ntp_header*>(m_Data); |
152 | 29.6k | } |
153 | | |
154 | | public: |
155 | | /// Warning of an impending leap second to be inserted or deleted in the last minute of the current month |
156 | | enum LeapIndicator |
157 | | { |
158 | | /// Normal, no leap second |
159 | | NoWarning = 0, |
160 | | /// Last minute of the day has 61 seconds |
161 | | Last61Secs, |
162 | | /// Last minute of the day has 59 seconds |
163 | | Last59Secs, |
164 | | /// Unknown (clock unsynchronized) |
165 | | Unknown |
166 | | }; |
167 | | |
168 | | /// Representing the NTP association modes |
169 | | enum Mode |
170 | | { |
171 | | /// Reserved variable |
172 | | Reserved = 0, |
173 | | /// Symmetrically active |
174 | | SymActive, |
175 | | /// Symmetrically passive |
176 | | SymPassive, |
177 | | /// Client mode |
178 | | Client, |
179 | | /// Server mode |
180 | | Server, |
181 | | /// Broadcasting mode |
182 | | Broadcast, |
183 | | /// NTP control messages |
184 | | Control, |
185 | | /// Reserved for private use |
186 | | PrivateUse |
187 | | }; |
188 | | |
189 | | /// 32-bit code identifying the particular server or reference clock. |
190 | | /// The interpretation depends on the value in the stratum field. |
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: |
242 | | /// https://www.meinbergglobal.com/english/info/ntp-refid.htm) |
243 | | DCFa = ('D') | ('C' << 8) | ('F' << 16) | ('a' << 24), |
244 | | /// Meinberg DCF77 with phase modulation)/pseudo random phase modulation (Ref: |
245 | | /// https://www.meinbergglobal.com/english/info/ntp-refid.htm) |
246 | | DCFp = ('D') | ('C' << 8) | ('F' << 16) | ('p' << 24), |
247 | | /// Meinberg GPS (with shared memory access) (Ref: |
248 | | /// https://www.meinbergglobal.com/english/info/ntp-refid.htm) |
249 | | GPSs = ('G') | ('P' << 8) | ('S' << 16) | ('s' << 24), |
250 | | /// Meinberg GPS (with interrupt based access) (Ref: |
251 | | /// https://www.meinbergglobal.com/english/info/ntp-refid.htm) |
252 | | GPSi = ('G') | ('P' << 8) | ('S' << 16) | ('i' << 24), |
253 | | /// Meinberg GPS/GLONASS (with shared memory access) (Ref: |
254 | | /// https://www.meinbergglobal.com/english/info/ntp-refid.htm) |
255 | | GLNs = ('G') | ('L' << 8) | ('N' << 16) | ('s' << 24), |
256 | | /// Meinberg GPS/GLONASS (with interrupt based access) (Ref: |
257 | | /// https://www.meinbergglobal.com/english/info/ntp-refid.htm) |
258 | | GLNi = ('G') | ('L' << 8) | ('N' << 16) | ('i' << 24), |
259 | | /// Meinberg Undisciplined local clock (Ref: https://www.meinbergglobal.com/english/info/ntp-refid.htm) |
260 | | LCL = ('L') | ('C' << 8) | ('L' << 16), |
261 | | /// Meinberg Undisciplined local clock (Ref: https://www.meinbergglobal.com/english/info/ntp-refid.htm) |
262 | | LOCL = ('L') | ('O' << 8) | ('C' << 16) | ('L' << 24), |
263 | | |
264 | | // NTPv3 |
265 | | |
266 | | /// DCN routing protocol |
267 | | DCN = ('D') | ('C' << 8) | ('N' << 16), |
268 | | /// TSP time protocol |
269 | | TSP = ('T') | ('S' << 8) | ('P' << 16), |
270 | | /// Digital Time Service |
271 | | DTS = ('D') | ('T' << 8) | ('S' << 16), |
272 | | /// Atomic clock (calibrated) |
273 | | ATOM = ('A') | ('T' << 8) | ('O' << 16) | ('M' << 24), |
274 | | /// VLF radio (OMEGA, etc.) |
275 | | VLF = ('V') | ('L' << 8) | ('F' << 16) |
276 | | }; |
277 | | |
278 | | /// 32-bit Kiss of Death (KoD) codes |
279 | | enum class KissODeath : uint32_t |
280 | | { |
281 | | /// The association belongs to a anycast server |
282 | | ACST = ('A') | ('C' << 8) | ('S' << 16) | ('T' << 24), |
283 | | /// Server authentication failed |
284 | | AUTH = ('A') | ('U' << 8) | ('T' << 16) | ('H' << 24), |
285 | | /// Autokey sequence failed |
286 | | AUTO = ('A') | ('U' << 8) | ('T' << 16) | ('O' << 24), |
287 | | /// The association belongs to a broadcast server |
288 | | BCST = ('B') | ('C' << 8) | ('S' << 16) | ('T' << 24), |
289 | | /// Cryptographic authentication or identification failed |
290 | | CRYP = ('C') | ('R' << 8) | ('Y' << 16) | ('P' << 24), |
291 | | /// Access denied by remote server |
292 | | DENY = ('D') | ('E' << 8) | ('N' << 16) | ('Y' << 24), |
293 | | /// Lost peer in symmetric mode |
294 | | DROP = ('D') | ('R' << 8) | ('O' << 16) | ('P' << 24), |
295 | | /// Access denied due to local policy |
296 | | RSTR = ('R') | ('S' << 8) | ('T' << 16) | ('R' << 24), |
297 | | /// The association has not yet synchronized for the first time |
298 | | INIT = ('I') | ('N' << 8) | ('I' << 16) | ('T' << 24), |
299 | | /// The association belongs to a manycast server |
300 | | MCST = ('M') | ('C' << 8) | ('S' << 16) | ('T' << 24), |
301 | | /// No key found. Either the key was never installed or is not trusted |
302 | | NKEY = ('N') | ('K' << 8) | ('E' << 16) | ('Y' << 24), |
303 | | /// Rate exceeded. The server has temporarily denied access because the client exceeded the rate threshold |
304 | | RATE = ('R') | ('A' << 8) | ('T' << 16) | ('E' << 24), |
305 | | /// Somebody is tinkering with the association from a remote host running ntpdc. Not to worry unless some |
306 | | /// rascal has stolen your keys |
307 | | RMOT = ('R') | ('M' << 8) | ('O' << 16) | ('T' << 24), |
308 | | /// A step change in system time has occurred, but the association has not yet resynchronized |
309 | | STEP = ('S') | ('T' << 8) | ('E' << 16) | ('P' << 24), |
310 | | }; |
311 | | |
312 | | /// A constructor that creates the layer from an existing packet raw data |
313 | | /// @param[in] data A pointer to the raw data |
314 | | /// @param[in] dataLen Size of the data in bytes |
315 | | /// @param[in] prevLayer A pointer to the previous layer |
316 | | /// @param[in] packet A pointer to the Packet instance where layer will be stored in |
317 | | NtpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) |
318 | 3.58k | : Layer(data, dataLen, prevLayer, packet, NTP) |
319 | 3.58k | {} |
320 | | |
321 | | /// Empty c'tor |
322 | | NtpLayer(); |
323 | | |
324 | | /// @return The leap indicator |
325 | | LeapIndicator getLeapIndicator() const; |
326 | | |
327 | | /// Set the leap indicator |
328 | | void setLeapIndicator(LeapIndicator val); |
329 | | |
330 | | /// @return The version of NTP |
331 | | uint8_t getVersion() const; |
332 | | |
333 | | /// Set the version of NTP |
334 | | void setVersion(uint8_t val); |
335 | | |
336 | | /// @return The mode value |
337 | | Mode getMode() const; |
338 | | |
339 | | /// @return The mode as string |
340 | | std::string getModeString() const; |
341 | | |
342 | | /// Set the mode |
343 | | void setMode(Mode val); |
344 | | |
345 | | /// @return The value of stratum |
346 | | uint8_t getStratum() const; |
347 | | |
348 | | /// Set the value of stratum |
349 | | void setStratum(uint8_t val); |
350 | | |
351 | | /// @return The value of poll interval in log2 seconds |
352 | | int8_t getPollInterval() const; |
353 | | |
354 | | /// Set the value of poll interval |
355 | | /// @param[in] val Poll interval in log2 seconds |
356 | | void setPollInterval(int8_t val); |
357 | | |
358 | | /// @return The value of poll interval in seconds |
359 | | double getPollIntervalInSecs() const; |
360 | | |
361 | | /// @return The value of precision in log2 seconds |
362 | | int8_t getPrecision() const; |
363 | | |
364 | | /// Set the value of precision |
365 | | /// @param[in] val Precision in log2 seconds |
366 | | void setPrecision(int8_t val); |
367 | | |
368 | | /// @return The value of precision in seconds |
369 | | double getPrecisionInSecs() const; |
370 | | |
371 | | /// @return The value of root delay in NTP short format |
372 | | uint32_t getRootDelay() const; |
373 | | |
374 | | /// Set the value of root delay |
375 | | /// @param[in] val Root delay in NTP short format |
376 | | void setRootDelay(uint32_t val); |
377 | | |
378 | | /// @return The value of root delay in seconds |
379 | | double getRootDelayInSecs() const; |
380 | | |
381 | | /// Set the value of root delay |
382 | | /// @param[in] val Root delay in seconds |
383 | | void setRootDelayInSecs(double val); |
384 | | |
385 | | /// @return The value of root dispersion in NTP short format |
386 | | uint32_t getRootDispersion() const; |
387 | | |
388 | | /// Set the value of root delay |
389 | | /// @param[in] val Root dispersion in NTP short format |
390 | | void setRootDispersion(uint32_t val); |
391 | | |
392 | | /// @return The value of root dispersion in seconds |
393 | | double getRootDispersionInSecs() const; |
394 | | |
395 | | /// Set the value of root dispersion |
396 | | /// @param[in] val Root dispersion in seconds |
397 | | void setRootDispersionInSecs(double val); |
398 | | |
399 | | /// @return The value of reference identifier |
400 | | uint32_t getReferenceIdentifier() const; |
401 | | |
402 | | /// Set the value of reference identifier |
403 | | /// @param[in] val Value of the reference identifier as IPv4 address |
404 | | void setReferenceIdentifier(IPv4Address val); |
405 | | |
406 | | /// Set the value of reference identifier |
407 | | /// @param[in] val Value of the reference identifier as ClockSource |
408 | | void setReferenceIdentifier(ClockSource val); |
409 | | |
410 | | /// Set the value of reference identifier |
411 | | /// @param[in] val Value of the reference identifier as Kiss-O-Death code |
412 | | void setReferenceIdentifier(KissODeath val); |
413 | | |
414 | | /// @return The value of reference identifier as a string. String representation of NTP clock source if |
415 | | /// stratum is 1, IPv4 address or MD5 hash of first four octets of IPv6 |
416 | | std::string getReferenceIdentifierString() const; |
417 | | |
418 | | /// @return The value of reference timestamp in NTP timestamp format |
419 | | uint64_t getReferenceTimestamp() const; |
420 | | |
421 | | /// Set the value of reference timestamp |
422 | | /// @param[in] val Timestamp in NTP timestamp format |
423 | | void setReferenceTimestamp(uint64_t val); |
424 | | |
425 | | /// @return The value of reference timestamp in seconds from Unix Epoch (1 Jan 1970) |
426 | | double getReferenceTimestampInSecs() const; |
427 | | |
428 | | /// Set the value of reference timestamp |
429 | | /// @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) |
430 | | void setReferenceTimestampInSecs(double val); |
431 | | |
432 | | /// @return The reference timestamp value as readable string in ISO8601 format |
433 | | std::string getReferenceTimestampAsString(); |
434 | | |
435 | | /// @return The value of origin timestamp in NTP timestamp format |
436 | | uint64_t getOriginTimestamp() const; |
437 | | |
438 | | /// Set the value of origin timestamp |
439 | | /// @param[in] val Value in NTP timestamp format |
440 | | void setOriginTimestamp(uint64_t val); |
441 | | |
442 | | /// @return The value of origin timestamp in seconds from Unix Epoch (1 Jan 1970) |
443 | | double getOriginTimestampInSecs() const; |
444 | | |
445 | | /// Set the value of origin timestamp |
446 | | /// @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) |
447 | | void setOriginTimestampInSecs(double val); |
448 | | |
449 | | /// @return the origin timestamp value as readable string in ISO8601 format |
450 | | std::string getOriginTimestampAsString(); |
451 | | |
452 | | /// @return The value of receive timestamp in NTP timestamp format |
453 | | uint64_t getReceiveTimestamp() const; |
454 | | |
455 | | /// Set the value of receive timestamp |
456 | | /// @param[in] val Value in NTP timestamp format |
457 | | void setReceiveTimestamp(uint64_t val); |
458 | | |
459 | | /// @return The value of receive timestampin seconds from Unix Epoch (1 Jan 1970) |
460 | | double getReceiveTimestampInSecs() const; |
461 | | |
462 | | /// Set the value of receive timestamp |
463 | | /// @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) |
464 | | void setReceiveTimestampInSecs(double val); |
465 | | |
466 | | /// @return The receive timestamp value as readable string in ISO8601 format |
467 | | std::string getReceiveTimestampAsString(); |
468 | | |
469 | | /// @return The value of transmit timestamp in NTP timestamp format |
470 | | uint64_t getTransmitTimestamp() const; |
471 | | |
472 | | /// Set the value of transmit timestamp |
473 | | /// @param[in] val Value in NTP timestamp format |
474 | | void setTransmitTimestamp(uint64_t val); |
475 | | |
476 | | /// @return The value of transmit timestamp in seconds from Unix Epoch (1 Jan 1970) |
477 | | double getTransmitTimestampInSecs() const; |
478 | | |
479 | | /// Set the value of transmit timestamp |
480 | | /// @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) |
481 | | void setTransmitTimestampInSecs(double val); |
482 | | |
483 | | /// @return The transmit timestamp value as readable string in ISO8601 format |
484 | | std::string getTransmitTimestampAsString(); |
485 | | |
486 | | /// @return Returns the key identifier if exists, returns 0 on unsupported NTP version or key identifier not |
487 | | /// found |
488 | | uint32_t getKeyID() const; |
489 | | |
490 | | /// @return Get the digest value as hexadecimal string, empty string on unsupported version |
491 | | std::string getDigest() const; |
492 | | |
493 | | /// Convert NTP short format to seconds from the Unix Epoch |
494 | | /// @param[in] val Value in NTP short format |
495 | | /// @return Value in seconds from Unix Epoch (1 Jan 1970) |
496 | | static double convertFromShortFormat(const uint32_t val); |
497 | | |
498 | | /// Convert NTP timestamp format to seconds from the Unix Epoch |
499 | | /// @param[in] val Value in NTP timestamp format |
500 | | /// @return Value in seconds from Unix Epoch (1 Jan 1970) |
501 | | static double convertFromTimestampFormat(const uint64_t val); |
502 | | |
503 | | /// Convert seconds from the Unix Epoch to NTP short format |
504 | | /// @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) |
505 | | /// @return Value in NTP short format |
506 | | static uint32_t convertToShortFormat(const double val); |
507 | | |
508 | | /// Convert seconds from the Unix Epoch to NTP timestamp format |
509 | | /// @param[in] val Value in seconds from Unix Epoch (1 Jan 1970) |
510 | | /// @return Value in NTP timestamp format |
511 | | static uint64_t convertToTimestampFormat(const double val); |
512 | | |
513 | | /// A static method to convert timestamp value to ISO8601 date time format |
514 | | /// @param[in] timestamp Value in seconds from the Unix Epoch |
515 | | /// @return std::string ISO8601 formatted string |
516 | | static std::string convertToIsoFormat(const double timestamp); |
517 | | |
518 | | /// A static method to convert timestamp value to ISO8601 date time format |
519 | | /// @param[in] timestampInNTPformat Value in NTP timestamp format |
520 | | /// @return std::string ISO8601 formatted string |
521 | | static std::string convertToIsoFormat(const uint64_t timestampInNTPformat); |
522 | | |
523 | | /// A static method that takes a byte array and detects whether it is a NTP message |
524 | | /// @param[in] data A byte array |
525 | | /// @param[in] dataSize The byte array size (in bytes) |
526 | | /// @return True if the data is identified as NTP message |
527 | | static bool isDataValid(const uint8_t* data, size_t dataSize); |
528 | | |
529 | | /// A static method that checks whether the port is considered as NTP |
530 | | /// @param[in] port The port number to be checked |
531 | | static bool isNTPPort(uint16_t port) |
532 | 55.4k | { |
533 | 55.4k | return port == 123; |
534 | 55.4k | } |
535 | | |
536 | | // overridden methods |
537 | | |
538 | | /// Parses the next layer. NTP is the always last so does nothing for this layer |
539 | | void parseNextLayer() override |
540 | 3.58k | {} |
541 | | |
542 | | /// @return Get the size of the layer (Including the extension and authentication fields if exists) |
543 | | size_t getHeaderLen() const override |
544 | 1.43k | { |
545 | 1.43k | return m_DataLen; |
546 | 1.43k | } |
547 | | |
548 | | /// Does nothing for this layer |
549 | | void computeCalculateFields() override |
550 | 716 | {} |
551 | | |
552 | | /// @return The OSI layer level of NTP (Application Layer). |
553 | | OsiModelLayer getOsiModelLayer() const override |
554 | 716 | { |
555 | 716 | return OsiModelApplicationLayer; |
556 | 716 | } |
557 | | |
558 | | /// @return Returns the protocol info as readable string |
559 | | std::string toString() const override; |
560 | | }; |
561 | | } // namespace pcpp |