Master the fundamental concepts of protocol implementation through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksNTP synchronizes clocks over UDP port 123. The packet is exactly 48 bytes. Byte 0 packs leap indicator (2 bits), version 4 (3 bits), and mode (3 bits). For example, a client request sets mode 3; the server reply sets mode 4.
1-15 for valid servers, 16 = unsynchronized)129.6.15.28)NTP timestamps count seconds since 1900-01-01 with a 32-bit fraction for sub-second precision. Convert to Unix time by subtracting 2208988800 (the 1900-to-1970 offset). The fractional part gives roughly 233 picoseconds per unit. Clients compute clock offset by comparing transmit and receive timestamps, accounting for network delay. Pool servers like pool.ntp.org and stratum-1 sources such as 129.6.15.28 answer thousands of these 48-byte queries per second.
This task requires you to build an NTP client query and parse the response timestamps. chrony and ntpd on every Linux machine parse this exact format defined in RFC 5905 to keep clocks synchronized across the internet. The 2014 NTP amplification DDoS wave exploited deprecated commands on this same protocol, turning small spoofed queries to port 123 into massive reflected floods.
Write a C program that implements the NTP on-wire arithmetic from RFC 5905: given the four exchange timestamps of a client/server poll, compute the clock offset and round-trip delay, and convert the server's timestamp to Unix time.
Input: four decimal integers on one line, T1 T2 T3 T4, all in NTP seconds (seconds since 1900-01-01):
Output:
offset=N: clock offset of the server relative to the client: offset = ((T2 - T1) + (T3 - T4)) / 2, truncated toward negative infinitydelay=N: round-trip delay: delay = (T4 - T1) - (T3 - T2), truncated toward negative infinityserver_time=N. T3 converted to Unix seconds (since 1970-01-01) by subtracting the 2208988800-second NTP/Unix epoch offsetExample: 1000000000 1000000002 1000000001 1000000001 gives offset=1, delay=2. A positive offset means the server clock is ahead of the client; a negative offset means it is behind. No sockets needed: the timestamps arrive on stdin.