ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
ntp.h
Go to the documentation of this file.
1// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file ntp.h
6 * @brief The NTP packet on the wire (RFC 5905 sec 7.3, Figure 8), shared by the client and server.
7 *
8 * Layout, field offsets, and the enumerated values either role tests. The client role lives in
9 * ntp_service/, the server role in ntp_server/; both read the format from here and neither states
10 * any of it a second time.
11 *
12 * The header is 48 octets, twelve 32-bit words:
13 *
14 * 0 1 2 3
15 * 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
16 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
17 * |LI | VN |Mode | Stratum | Poll | Precision |
18 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
19 * | Root Delay |
20 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
21 * | Root Dispersion |
22 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23 * | Reference ID |
24 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
25 * | Reference Timestamp (64) |
26 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
27 * | Origin Timestamp (64) |
28 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
29 * | Receive Timestamp (64) |
30 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31 * | Transmit Timestamp (64) |
32 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33 *
34 * A timestamp is 32 bits of seconds since the prime epoch then 32 bits of fraction, so each one
35 * takes two offsets here. Every multi-octet field is big-endian.
36 *
37 * @author Douglas Quigg (dstroy0)
38 * @date 2026
39 */
40
41#ifndef PROTOCORE_NTP_H
42#define PROTOCORE_NTP_H
43
44#include <stdint.h>
45
46#include "protocore_config.h"
47
49
50/** @brief One NTP packet on the wire is exactly 48 octets (no extension or MAC fields). */
51#define PROTOCORE_NTP_PACKET_LEN 48u
52
53/** @brief Seconds between the NTP prime epoch (1900-01-01) and the Unix epoch (1970-01-01). */
54#define PROTOCORE_NTP_UNIX_OFFSET 2208988800u
55
56/** @brief UDP port NTP answers on (RFC 5905 sec 7.2). */
57#define PROTOCORE_NTP_PORT 123u
58
59// --- field offsets, RFC 5905 Figure 8 -----------------------------------------------------------
60
61/** @brief Leap indicator, version and mode, packed into the first octet. */
62#define PROTOCORE_NTP_OFF_LI_VN_MODE 0u
63
64/** @brief Stratum of the sender. */
65#define PROTOCORE_NTP_OFF_STRATUM 1u
66
67/** @brief Poll interval, log2 seconds, signed. */
68#define PROTOCORE_NTP_OFF_POLL 2u
69
70/** @brief Clock precision, log2 seconds, signed. */
71#define PROTOCORE_NTP_OFF_PRECISION 3u
72
73/** @brief Round-trip delay to the reference clock, 16.16 seconds. */
74#define PROTOCORE_NTP_OFF_ROOT_DELAY 4u
75
76/** @brief Dispersion to the reference clock, 16.16 seconds. */
77#define PROTOCORE_NTP_OFF_ROOT_DISP 8u
78
79/** @brief Reference identifier: a kiss code at stratum 0, a source ID at stratum 1. */
80#define PROTOCORE_NTP_OFF_REFID 12u
81
82/** @brief Reference timestamp, when the sender's clock was last set. */
83#define PROTOCORE_NTP_OFF_REF_SEC 16u
84#define PROTOCORE_NTP_OFF_REF_FRAC 20u
85
86/** @brief Origin timestamp: the client's transmit stamp, echoed by the server. */
87#define PROTOCORE_NTP_OFF_ORIGIN_SEC 24u
88#define PROTOCORE_NTP_OFF_ORIGIN_FRAC 28u
89
90/** @brief Receive timestamp: when the request reached the server. */
91#define PROTOCORE_NTP_OFF_RX_SEC 32u
92#define PROTOCORE_NTP_OFF_RX_FRAC 36u
93
94/** @brief Transmit timestamp: when the reply left, and the field a client reads the time from. */
95#define PROTOCORE_NTP_OFF_TX_SEC 40u
96#define PROTOCORE_NTP_OFF_TX_FRAC 44u
97
98// --- first octet --------------------------------------------------------------------------------
99
100/** @brief li (2) | vn (3) | mode (3), packed into the first octet. */
101#define PROTOCORE_NTP_LI_VN_MODE(li, vn, mode) ((uint8_t)(((li) << 6) | ((vn) << 3) | (mode)))
102
103/** @brief The leap indicator carried in the first octet. */
104#define PROTOCORE_NTP_LI_OF(b) ((uint8_t)((b) >> 6))
105
106/** @brief The version carried in the first octet. */
107#define PROTOCORE_NTP_VN_OF(b) ((uint8_t)(((b) >> 3) & 0x07u))
108
109/** @brief The mode carried in the first octet. */
110#define PROTOCORE_NTP_MODE_OF(b) ((uint8_t)((b) & 0x07u))
111
112/** @brief NTP version this speaks (RFC 5905). */
113#define PROTOCORE_NTP_VERSION 4u
114
115// Modes, RFC 5905 sec 7.3. Only client and server are exchanged here; the rest are named so a
116// packet carrying one is recognised rather than silently treated as a reply.
117#define PROTOCORE_NTP_MODE_RESERVED 0u
118#define PROTOCORE_NTP_MODE_SYM_ACTIVE 1u
119#define PROTOCORE_NTP_MODE_SYM_PASSIVE 2u
120#define PROTOCORE_NTP_MODE_CLIENT 3u
121#define PROTOCORE_NTP_MODE_SERVER 4u
122#define PROTOCORE_NTP_MODE_BROADCAST 5u
123#define PROTOCORE_NTP_MODE_CONTROL 6u
124#define PROTOCORE_NTP_MODE_PRIVATE 7u
125
126// Leap indicator, RFC 5905 sec 7.3.
127#define PROTOCORE_NTP_LI_NONE 0u
128#define PROTOCORE_NTP_LI_ADD_SEC 1u
129#define PROTOCORE_NTP_LI_DEL_SEC 2u
130
131/** @brief Leap indicator 3, clock unsynchronized: RFC 4330 sec 5 discards a reply carrying it. */
132#define PROTOCORE_NTP_LI_UNSYNC 3u
133
134// Stratum, RFC 5905 sec 7.3. 0 is unspecified and carries a kiss code in the reference ID; 1 is a
135// primary reference; 2-15 is a secondary server; 16 is unsynchronized and above that is reserved.
136#define PROTOCORE_NTP_STRATUM_KOD 0u
137#define PROTOCORE_NTP_STRATUM_PRIMARY 1u
138#define PROTOCORE_NTP_STRATUM_MAX 15u
139#define PROTOCORE_NTP_STRATUM_UNSYNC 16u
140
141// --- reference identifiers ----------------------------------------------------------------------
142
143/** @brief Reference ID "LOCL" - an undisciplined local clock (RFC 5905 sec 7.3). */
144#define PROTOCORE_NTP_REFID_LOCL 0x4C4F434Cu
145
146/** @brief Reference ID "GPS " - a GPS-disciplined reference clock (use with stratum 1). */
147#define PROTOCORE_NTP_REFID_GPS 0x47505320u
148
150
151#endif // PROTOCORE_NTP_H
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
Definition types.h:96
#define PROTOCORE_END_DECLS
Definition types.h:97