Structure of theNTP Data packet
NTP Proto
Cryptosum LI VN Mode Strat Poll Prec
LI = leap indicator
VN = version number
Strat = Stratum (0-15)
Poll = poll intervall
Prec = Precision
Root Delay
Root Dispersion
Reference Identifier
Reference Timestamp
Seconds (32),
Fraction (32)
Originate Timestamp
Seconds (32),
Fraction (32)
Receive Timestamp
Seconds (32),
Fraction (32)
Transmit Timestamp
Seconds (32),
Fraction (32)
Ext. Field 1 Key Identifier (optional)
Ext. Field 2 Message Digest (optional)
Authenticator
(Optional)
Key/Algorithm Identifier
Message Hash (64 or 128)
struct ntp_pkt_t {
    u_char        li_vn_mode;   // leap indicator, version and mode
    u_char        stratum;      // peer stratum
    u_char        ppoll;        // peer poll interval
    s_char        precision;    // peer clock precision
    u_fp          rootdelay;    // distance to primary clock
    u_fp          rootdispersion;      // clock dispersion
    u_int32       refid;        // reference clock ID
    l_fp          reftime;      // time peer clock was last updated
    l_fp          org;          // originate time stamp
    l_fp          rec;          // receive time stamp
    l_fp          xmt;          // transmit time stamp
    u_int32       exten[1];     // misused
    u_char        mac[MAX_MAC_LEN]; // mac */
} ntppkt;
Request packet sent by ESP8266 to NTP server (from 192.168.0.242 to 192.168.0.28)
Headers: 1st LL:14 bytes, IP:20 bytes, UDP:8 bytes,  tot: 42 bytes

0000   64 66 b3 b0 f1 20 18 fe 34 9f 38 5e 08 00 45 00  df... ..4.8^..E.
0010   00 4c 00 4e 00 00 ff 11 38 f4 c0 a8 00 f2 c0 a8  .L.N....8.......
0020   00 1c 5b 4b 00 7b 00 38 37 6c e3 00 06 ec 00 00  ..[K.{.87l......
0030   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0040   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0050   00 00 00 00 00 00 00 00 00 00                    ..........

Response sent back by NTP server Headers: 1st LL:14 bytes, IP:20 bytes, UDP:8 bytes, tot: 42 bytes 0000 18 fe 34 9f 38 5e 64 66 b3 b0 f1 20 08 00 45 c0 ..4.8^df... ..E. 0010 00 4c 00 00 40 00 40 11 b7 82 c0 a8 00 1c c0 a8 .L..@.@......... 0020 00 f2 00 7b 5b 4b 00 38 36 2a 24 03 06 f0 00 00 ...{[K.86*$..... 0030 0b 34 00 00 16 67 5b 79 a5 92 d9 08 d2 c7 ee d1 .4...g[y........ 0040 ff 40 00 00 00 00 00 00 00 00 d9 08 d4 b3 94 c4 .@.............. 0050 37 25 d9 08 d4 b3 94 db 47 72 7%......Gr

/*F********************************************************************
* A packet I received from mu Linux Server
**********************************************************************/
I used: tcpdump -i eth0 -a --snapshot-length=200 -nnn -vvv -X  "port 123"
15:13:40.828249 IP (tos 0x0, ttl 47, id 64236, offset 0, flags [DF], proto UDP (17), length 76)
    185.125.190.57.123 > 192.168.0.9.123: [udp sum ok] NTPv4, length 48
    Server, Leap indicator:  (0), Stratum 2 (secondary reference), poll 10 (1024s), precision -25
    Root Delay: 0.001098, Root dispersion: 0.000320, Reference-ID: 48.134.154.62
      Reference Timestamp:  3873816705.556883967 (2022/10/03 15:11:45)
      Originator Timestamp: 3873816820.719755605 (2022/10/03 15:13:40)
      Receive Timestamp:    3873816820.774116279 (2022/10/03 15:13:40)
      Transmit Timestamp:   3873816820.774127132 (2022/10/03 15:13:40)
        Originator - Receive Timestamp:  +0.054360674
        Originator - Transmit Timestamp: +0.054371527
    0x0000:  4500 004c faec 4000 2f11 184c b97d be39  E..L..@./..L.}.9
    0x0010:  c0a8 0009 007b 007b 0038 d1e5 2402 0ae7  .....{.{.8..$...
    0x0020:  0000 0048 0000 0015 3086 9a3e e6e5 c081  ...H....0..>....
    0x0030:  8e8f f29e e6e5 c0f4 b841 e743 e6e5 c0f4  .........A.C....
    0x0040:  c62c 7c09 e6e5 c0f4 c62d 321f            .,|......-2.
                      3873816820   Same Timestamp (secs) as above  



NTPv4 Extension Fields

Field Length Field Type
Extension Field
(padded to 32-bit boundary)
Last field padded to 64-bit boundary
NTP V3 and V4
NTP V4 only
authentication only


NTP Timestamp

NTP timestamp format (64 bits) :
Seconds (32) Fraction (32)
Seconds and Fractions since 01.01.1900



The time synchronization between Client and Server works as follows:


Client Connection Server
Timestamp 1 Client-Server Timestamp 2
Timestamp 4 Server-Client Timestamp 3


From these four timestamps the system can calculate two values:
Offset = (t2 - t1) + (t3 - t4)
-----------------
2
Delay = (t4 - t1) - (t3 - t2)

Here you can see that NTP averages the Delay because it assumes that the trip of the packet is the same in both directions, that means differences influence the Offset as an error.

In local networks the round-trip delay is only a small part of the offset and therefor the offset calculation is already precise.

In bigger networks the offsets and delays are filtered more often, to compensate the delay variations. The offset is calculated from the packet with the smallest delay out of the last eight packets.

Additionally an other value is calculated from the same packets:
The " Dispersion " value, an averaged value of the offset deviation from the eight last data packets to the actual offset. The offsets with a smaller delay are weighted more.