#include "sysincl.h"
#include "addressing.h"
-#include "hash.h"
/* This is the default port to use for CANDM, if no alternative is
defined */
#define REQ_MODIFY_MAXDELAYDEVRATIO 47
#define REQ_RESELECT 48
#define REQ_RESELECTDISTANCE 49
-#define N_REQUEST_TYPES 50
-
-/* Special utoken value used to log on with first exchange being the
- password. (This time value has long since gone by) */
-#define SPECIAL_UTOKEN 0x10101010
-
-/* Structure used to exchange timevals independent on size of time_t */
+#define REQ_MODIFY_MAKESTEP 50
+#define REQ_SMOOTHING 51
+#define REQ_SMOOTHTIME 52
+#define REQ_REFRESH 53
+#define REQ_SERVER_STATS 54
+#define REQ_CLIENT_ACCESSES_BY_INDEX2 55
+#define REQ_LOCAL2 56
+#define REQ_NTP_DATA 57
+#define REQ_ADD_SERVER2 58
+#define REQ_ADD_PEER2 59
+#define REQ_ADD_SERVER3 60
+#define REQ_ADD_PEER3 61
+#define REQ_SHUTDOWN 62
+#define REQ_ONOFFLINE 63
+#define REQ_ADD_SOURCE 64
+#define REQ_NTP_SOURCE_NAME 65
+#define REQ_RESET_SOURCES 66
+#define REQ_AUTH_DATA 67
+#define REQ_CLIENT_ACCESSES_BY_INDEX3 68
+#define REQ_SELECT_DATA 69
+#define REQ_RELOAD_SOURCES 70
+#define REQ_DOFFSET2 71
+#define REQ_MODIFY_SELECTOPTS 72
+#define REQ_MODIFY_OFFSET 73
+#define REQ_LOCAL3 74
+#define N_REQUEST_TYPES 75
+
+/* Structure used to exchange timespecs independent of time_t size */
typedef struct {
uint32_t tv_sec_high;
uint32_t tv_sec_low;
uint32_t tv_nsec;
-} Timeval;
+} Timespec;
/* This is used in tv_sec_high for 32-bit timestamps */
#define TV_NOHIGHSEC 0x7fffffff
+/* Structure for 64-bit integers (not requiring 64-bit alignment) */
+typedef struct {
+ uint32_t high;
+ uint32_t low;
+} Integer64;
+
/* 32-bit floating-point format consisting of 7-bit signed exponent
and 25-bit signed coefficient without hidden bit.
The result is calculated as: 2^(exp - 25) * coef */
pktlength.c, to get the number of bytes that ought to be
transmitted for each packet type. */
+typedef struct {
+ int32_t EOR;
+} REQ_Null;
+
typedef struct {
IPAddr mask;
IPAddr address;
} REQ_Modify_Maxupdateskew;
typedef struct {
- Timeval ts;
+ int32_t limit;
+ Float threshold;
+ int32_t EOR;
+} REQ_Modify_Makestep;
+
+typedef struct {
+ Timespec ts;
int32_t EOR;
} REQ_Logon;
typedef struct {
- Timeval ts;
+ Timespec ts;
int32_t EOR;
} REQ_Settime;
typedef struct {
int32_t on_off;
int32_t stratum;
+ Float distance;
+ int32_t orphan;
+ Float activate;
int32_t EOR;
} REQ_Local;
int32_t EOR;
} REQ_Manual;
-typedef struct {
- int32_t EOR;
-} REQ_N_Sources;
-
typedef struct {
int32_t index;
int32_t EOR;
} REQ_Source_Data;
-typedef struct {
- int32_t EOR;
-} REQ_Rekey;
-
typedef struct {
IPAddr ip;
int32_t subnet_bits;
int32_t EOR;
} REQ_Ac_Check;
+/* Source types in NTP source requests */
+#define REQ_ADDSRC_SERVER 1
+#define REQ_ADDSRC_PEER 2
+#define REQ_ADDSRC_POOL 3
+
/* Flags used in NTP source requests */
#define REQ_ADDSRC_ONLINE 0x1
#define REQ_ADDSRC_AUTOOFFLINE 0x2
#define REQ_ADDSRC_IBURST 0x4
#define REQ_ADDSRC_PREFER 0x8
#define REQ_ADDSRC_NOSELECT 0x10
-
-typedef struct {
- IPAddr ip_addr;
+#define REQ_ADDSRC_TRUST 0x20
+#define REQ_ADDSRC_REQUIRE 0x40
+#define REQ_ADDSRC_INTERLEAVED 0x80
+#define REQ_ADDSRC_BURST 0x100
+#define REQ_ADDSRC_NTS 0x200
+#define REQ_ADDSRC_COPY 0x400
+#define REQ_ADDSRC_EF_EXP_MONO_ROOT 0x800
+#define REQ_ADDSRC_EF_EXP_NET_CORRECTION 0x1000
+#define REQ_ADDSRC_IPV4 0x2000
+#define REQ_ADDSRC_IPV6 0x4000
+
+typedef struct {
+ uint32_t type;
+ uint8_t name[256];
uint32_t port;
int32_t minpoll;
int32_t maxpoll;
int32_t presend_minpoll;
+ uint32_t min_stratum;
+ uint32_t poll_target;
+ uint32_t version;
+ uint32_t max_sources;
+ int32_t min_samples;
+ int32_t max_samples;
uint32_t authkey;
+ uint32_t nts_port;
Float max_delay;
Float max_delay_ratio;
+ Float max_delay_dev_ratio;
+ Float min_delay;
+ Float asymmetry;
+ Float offset;
uint32_t flags;
+ int32_t filter_length;
+ uint32_t cert_set;
+ Float max_delay_quant;
+ uint32_t reserved[1];
int32_t EOR;
} REQ_NTP_Source;
int32_t EOR;
} REQ_Del_Source;
-typedef struct {
- int32_t EOR;
-} REQ_WriteRtc;
-
typedef struct {
Float dfreq;
int32_t EOR;
} REQ_Dfreq;
typedef struct {
- int32_t sec;
- int32_t usec;
+ Float doffset;
int32_t EOR;
} REQ_Doffset;
-typedef struct {
- int32_t EOR;
-} REQ_Tracking;
-
typedef struct {
uint32_t index;
int32_t EOR;
} REQ_Sourcestats;
-typedef struct {
- int32_t EOR;
-} REQ_RTCReport;
+/* This is based on the response size rather than the
+ request size */
+#define MAX_CLIENT_ACCESSES 8
typedef struct {
+ uint32_t first_index;
+ uint32_t n_clients;
+ uint32_t min_hits;
+ uint32_t reset;
int32_t EOR;
-} REQ_TrimRTC;
+} REQ_ClientAccessesByIndex;
typedef struct {
+ int32_t index;
int32_t EOR;
-} REQ_CycleLogs;
-
-typedef struct {
- IPAddr ip;
- uint32_t bits_specd;
-} REQ_SubnetsAccessed_Subnet;
-
-#define MAX_SUBNETS_ACCESSED 8
+} REQ_ManualDelete;
typedef struct {
- uint32_t n_subnets;
- REQ_SubnetsAccessed_Subnet subnets[MAX_SUBNETS_ACCESSED];
-} REQ_SubnetsAccessed;
-
-/* This is based on the response size rather than the
- request size */
-#define MAX_CLIENT_ACCESSES 8
+ Float distance;
+ int32_t EOR;
+} REQ_ReselectDistance;
-typedef struct {
- uint32_t n_clients;
- IPAddr client_ips[MAX_CLIENT_ACCESSES];
-} REQ_ClientAccesses;
+#define REQ_SMOOTHTIME_RESET 0
+#define REQ_SMOOTHTIME_ACTIVATE 1
typedef struct {
- uint32_t first_index;
- uint32_t n_indices;
+ int32_t option;
int32_t EOR;
-} REQ_ClientAccessesByIndex;
+} REQ_SmoothTime;
typedef struct {
+ IPAddr ip_addr;
int32_t EOR;
-} REQ_ManualList;
+} REQ_NTPData;
typedef struct {
- int32_t index;
+ IPAddr ip_addr;
int32_t EOR;
-} REQ_ManualDelete;
+} REQ_NTPSourceName;
typedef struct {
+ IPAddr ip_addr;
int32_t EOR;
-} REQ_MakeStep;
+} REQ_AuthData;
typedef struct {
+ uint32_t index;
int32_t EOR;
-} REQ_Activity;
+} REQ_SelectData;
+/* Mask and options reuse the REQ_ADDSRC flags */
typedef struct {
+ IPAddr address;
+ uint32_t ref_id;
+ uint32_t mask;
+ uint32_t options;
int32_t EOR;
-} REQ_Reselect;
+} REQ_Modify_SelectOpts;
typedef struct {
- Float distance;
+ IPAddr address;
+ uint32_t ref_id;
+ Float new_offset;
int32_t EOR;
-} REQ_ReselectDistance;
+} REQ_Modify_Offset;
/* ================================================== */
modify polltarget, modify maxdelaydevratio, reselect, reselectdistance
Version 5 : auth data moved to the end of the packet to allow hashes with
- different sizes, extended sources, tracking and activity reports
+ different sizes, extended sources, tracking and activity reports, dropped
+ subnets accessed and client accesses
+
+ Version 6 : added padding to requests to prevent amplification attack,
+ changed maximum number of samples in manual list to 16, new commands: modify
+ makestep, smoothing, smoothtime
+
+ Support for authentication was removed later in version 6 of the protocol
+ and commands that required authentication are allowed only locally over Unix
+ domain socket.
+
+ Version 6 (no authentication) : changed format of client accesses by index
+ (two times), delta offset, and manual timestamp, added new fields and
+ flags to NTP source request and report, made length of manual list constant,
+ added new commands: authdata, ntpdata, onoffline, refresh, reset,
+ selectdata, serverstats, shutdown, sourcename
*/
-#define PROTO_VERSION_NUMBER 5
+#define PROTO_VERSION_NUMBER 6
+
+/* The oldest protocol versions that are compatible enough with the current
+ version to report a version mismatch for the server and the client */
+#define PROTO_VERSION_MISMATCH_COMPAT_SERVER 5
+#define PROTO_VERSION_MISMATCH_COMPAT_CLIENT 4
-/* The oldest protocol version that is compatible enough with
- the current version to report a version mismatch */
-#define PROTO_VERSION_MISMATCH_COMPAT 4
+/* The first protocol version using padding in requests */
+#define PROTO_VERSION_PADDING 6
+
+/* The maximum length of padding in request packet, currently
+ defined by CLIENT_ACCESSES_BY_INDEX3 */
+#define MAX_PADDING_LENGTH 484
/* ================================================== */
(count up from zero for same sequence
number) */
uint32_t sequence; /* Client's sequence number */
- uint32_t utoken; /* Unique token per incarnation of daemon */
- uint32_t token; /* Command token (to prevent replay attack) */
+ uint32_t pad1;
+ uint32_t pad2;
union {
+ REQ_Null null;
REQ_Online online;
REQ_Offline offline;
REQ_Burst burst;
REQ_Modify_Minstratum modify_minstratum;
REQ_Modify_Polltarget modify_polltarget;
REQ_Modify_Maxupdateskew modify_maxupdateskew;
+ REQ_Modify_Makestep modify_makestep;
REQ_Logon logon;
REQ_Settime settime;
REQ_Local local;
REQ_Manual manual;
- REQ_N_Sources n_sources;
REQ_Source_Data source_data;
- REQ_Rekey rekey;
REQ_Allow_Deny allow_deny;
REQ_Ac_Check ac_check;
REQ_NTP_Source ntp_source;
REQ_Del_Source del_source;
- REQ_WriteRtc writertc;
REQ_Dfreq dfreq;
REQ_Doffset doffset;
- REQ_Tracking tracking;
REQ_Sourcestats sourcestats;
- REQ_RTCReport rtcreport;
- REQ_TrimRTC trimrtc;
- REQ_CycleLogs cyclelogs;
- REQ_SubnetsAccessed subnets_accessed;
- REQ_ClientAccesses client_accesses;
REQ_ClientAccessesByIndex client_accesses_by_index;
- REQ_ManualList manual_list;
REQ_ManualDelete manual_delete;
- REQ_MakeStep make_step;
- REQ_Activity activity;
- REQ_Reselect reselect;
REQ_ReselectDistance reselect_distance;
+ REQ_SmoothTime smoothtime;
+ REQ_NTPData ntp_data;
+ REQ_NTPSourceName ntp_source_name;
+ REQ_AuthData auth_data;
+ REQ_SelectData select_data;
+ REQ_Modify_SelectOpts modify_select_opts;
+ REQ_Modify_Offset modify_offset;
} data; /* Command specific parameters */
- /* authentication of the packet, there is no hole after the actual data
- from the data union, this field only sets the maximum auth size */
- uint8_t auth[MAX_HASH_LENGTH];
+ /* Padding used to prevent traffic amplification. It only defines the
+ maximum size of the packet, there is no hole after the data field. */
+ uint8_t padding[MAX_PADDING_LENGTH];
} CMD_Request;
#define RPY_CLIENT_ACCESSES_BY_INDEX 10
#define RPY_MANUAL_LIST 11
#define RPY_ACTIVITY 12
-#define N_REPLY_TYPES 13
+#define RPY_SMOOTHING 13
+#define RPY_SERVER_STATS 14
+#define RPY_CLIENT_ACCESSES_BY_INDEX2 15
+#define RPY_NTP_DATA 16
+#define RPY_MANUAL_TIMESTAMP2 17
+#define RPY_MANUAL_LIST2 18
+#define RPY_NTP_SOURCE_NAME 19
+#define RPY_AUTH_DATA 20
+#define RPY_CLIENT_ACCESSES_BY_INDEX3 21
+#define RPY_SERVER_STATS2 22
+#define RPY_SELECT_DATA 23
+#define RPY_SERVER_STATS3 24
+#define RPY_SERVER_STATS4 25
+#define RPY_NTP_DATA2 26
+#define N_REPLY_TYPES 27
/* Status codes */
#define STT_SUCCESS 0
#define STT_BADSUBNET 7
#define STT_ACCESSALLOWED 8
#define STT_ACCESSDENIED 9
-#define STT_NOHOSTACCESS 10
+#define STT_NOHOSTACCESS 10 /* Deprecated */
#define STT_SOURCEALREADYKNOWN 11
#define STT_TOOMANYSOURCES 12
#define STT_NORTC 13
#define STT_INVALIDAF 17
#define STT_BADPKTVERSION 18
#define STT_BADPKTLENGTH 19
+#define STT_INVALIDNAME 21
typedef struct {
int32_t EOR;
#define RPY_SD_MD_PEER 1
#define RPY_SD_MD_REF 2
-#define RPY_SD_ST_SYNC 0
-#define RPY_SD_ST_UNREACH 1
+#define RPY_SD_ST_SELECTED 0
+#define RPY_SD_ST_NONSELECTABLE 1
#define RPY_SD_ST_FALSETICKER 2
#define RPY_SD_ST_JITTERY 3
-#define RPY_SD_ST_CANDIDATE 4
-#define RPY_SD_ST_OUTLYER 5
-
-#define RPY_SD_FLAG_NOSELECT 0x1
-#define RPY_SD_FLAG_PREFER 0x2
+#define RPY_SD_ST_UNSELECTED 4
+#define RPY_SD_ST_SELECTABLE 5
typedef struct {
IPAddr ip_addr;
- uint16_t poll;
+ int16_t poll;
uint16_t stratum;
uint16_t state;
uint16_t mode;
IPAddr ip_addr;
uint16_t stratum;
uint16_t leap_status;
- Timeval ref_time;
+ Timespec ref_time;
Float current_correction;
Float last_offset;
Float rms_offset;
} RPY_Sourcestats;
typedef struct {
- Timeval ref_time;
+ Timespec ref_time;
uint16_t n_samples;
uint16_t n_runs;
uint32_t span_seconds;
} RPY_Rtc;
typedef struct {
- uint32_t centiseconds;
+ Float offset;
Float dfreq_ppm;
Float new_afreq_ppm;
int32_t EOR;
typedef struct {
IPAddr ip;
- uint32_t bits_specd;
- uint32_t bitmap[8];
-} RPY_SubnetsAccessed_Subnet;
-
-typedef struct {
- uint32_t n_subnets;
- RPY_SubnetsAccessed_Subnet subnets[MAX_SUBNETS_ACCESSED];
-} RPY_SubnetsAccessed;
-
-typedef struct {
- IPAddr ip;
- uint32_t client_hits;
- uint32_t peer_hits;
- uint32_t cmd_hits_auth;
- uint32_t cmd_hits_normal;
- uint32_t cmd_hits_bad;
+ uint32_t ntp_hits;
+ uint32_t nke_hits;
+ uint32_t cmd_hits;
+ uint32_t ntp_drops;
+ uint32_t nke_drops;
+ uint32_t cmd_drops;
+ int8_t ntp_interval;
+ int8_t nke_interval;
+ int8_t cmd_interval;
+ int8_t ntp_timeout_interval;
uint32_t last_ntp_hit_ago;
+ uint32_t last_nke_hit_ago;
uint32_t last_cmd_hit_ago;
} RPY_ClientAccesses_Client;
-typedef struct {
- uint32_t n_clients;
- RPY_ClientAccesses_Client clients[MAX_CLIENT_ACCESSES];
-} RPY_ClientAccesses;
-
typedef struct {
uint32_t n_indices; /* how many indices there are in the server's table */
uint32_t next_index; /* the index 1 beyond those processed on this call */
uint32_t n_clients; /* the number of valid entries in the following array */
RPY_ClientAccesses_Client clients[MAX_CLIENT_ACCESSES];
+ int32_t EOR;
} RPY_ClientAccessesByIndex;
-#define MAX_MANUAL_LIST_SAMPLES 32
+typedef struct {
+ Integer64 ntp_hits;
+ Integer64 nke_hits;
+ Integer64 cmd_hits;
+ Integer64 ntp_drops;
+ Integer64 nke_drops;
+ Integer64 cmd_drops;
+ Integer64 log_drops;
+ Integer64 ntp_auth_hits;
+ Integer64 ntp_interleaved_hits;
+ Integer64 ntp_timestamps;
+ Integer64 ntp_span_seconds;
+ Integer64 ntp_daemon_rx_timestamps;
+ Integer64 ntp_daemon_tx_timestamps;
+ Integer64 ntp_kernel_rx_timestamps;
+ Integer64 ntp_kernel_tx_timestamps;
+ Integer64 ntp_hw_rx_timestamps;
+ Integer64 ntp_hw_tx_timestamps;
+ Integer64 reserved[4];
+ int32_t EOR;
+} RPY_ServerStats;
+
+#define MAX_MANUAL_LIST_SAMPLES 16
typedef struct {
- Timeval when;
+ Timespec when;
Float slewed_offset;
Float orig_offset;
Float residual;
typedef struct {
uint32_t n_samples;
RPY_ManualListSample samples[MAX_MANUAL_LIST_SAMPLES];
+ int32_t EOR;
} RPY_ManualList;
typedef struct {
int32_t EOR;
} RPY_Activity;
+#define RPY_SMT_FLAG_ACTIVE 0x1
+#define RPY_SMT_FLAG_LEAPONLY 0x2
+
+typedef struct {
+ uint32_t flags;
+ Float offset;
+ Float freq_ppm;
+ Float wander_ppm;
+ Float last_update_ago;
+ Float remaining_time;
+ int32_t EOR;
+} RPY_Smoothing;
+
+#define RPY_NTP_FLAGS_TESTS 0x3ff
+#define RPY_NTP_FLAG_INTERLEAVED 0x4000
+#define RPY_NTP_FLAG_AUTHENTICATED 0x8000
+
+typedef struct {
+ IPAddr remote_addr;
+ IPAddr local_addr;
+ uint16_t remote_port;
+ uint8_t leap;
+ uint8_t version;
+ uint8_t mode;
+ uint8_t stratum;
+ int8_t poll;
+ int8_t precision;
+ Float root_delay;
+ Float root_dispersion;
+ uint32_t ref_id;
+ Timespec ref_time;
+ Float offset;
+ Float peer_delay;
+ Float peer_dispersion;
+ Float response_time;
+ Float jitter_asymmetry;
+ uint16_t flags;
+ uint8_t tx_tss_char;
+ uint8_t rx_tss_char;
+ uint32_t total_tx_count;
+ uint32_t total_rx_count;
+ uint32_t total_valid_count;
+ uint32_t total_good_count;
+ uint32_t total_kernel_tx_ts;
+ uint32_t total_kernel_rx_ts;
+ uint32_t total_hw_tx_ts;
+ uint32_t total_hw_rx_ts;
+ uint32_t reserved[4];
+ int32_t EOR;
+} RPY_NTPData;
+
+typedef struct {
+ uint8_t name[256];
+ int32_t EOR;
+} RPY_NTPSourceName;
+
+#define RPY_AD_MD_NONE 0
+#define RPY_AD_MD_SYMMETRIC 1
+#define RPY_AD_MD_NTS 2
+
+typedef struct {
+ uint16_t mode;
+ uint16_t key_type;
+ uint32_t key_id;
+ uint16_t key_length;
+ uint16_t ke_attempts;
+ uint32_t last_ke_ago;
+ uint16_t cookies;
+ uint16_t cookie_length;
+ uint16_t nak;
+ uint16_t pad;
+ int32_t EOR;
+} RPY_AuthData;
+
+#define RPY_SD_OPTION_NOSELECT 0x1
+#define RPY_SD_OPTION_PREFER 0x2
+#define RPY_SD_OPTION_TRUST 0x4
+#define RPY_SD_OPTION_REQUIRE 0x8
+
+typedef struct {
+ uint32_t ref_id;
+ IPAddr ip_addr;
+ uint8_t state_char;
+ uint8_t authentication;
+ uint8_t leap;
+ uint8_t pad;
+ uint16_t conf_options;
+ uint16_t eff_options;
+ uint32_t last_sample_ago;
+ Float score;
+ Float lo_limit;
+ Float hi_limit;
+ int32_t EOR;
+} RPY_SelectData;
+
typedef struct {
uint8_t version;
uint8_t pkt_type;
uint16_t command; /* Which command is being replied to */
uint16_t reply; /* Which format of reply this is */
uint16_t status; /* Status of command processing */
- uint16_t number; /* Which packet this is in reply sequence */
- uint16_t total; /* Number of replies to expect in this sequence */
- uint16_t pad1; /* Get up to 4 byte alignment */
+ uint16_t pad1; /* Padding for compatibility and 4 byte alignment */
+ uint16_t pad2;
+ uint16_t pad3;
uint32_t sequence; /* Echo of client's sequence number */
- uint32_t utoken; /* Unique token per incarnation of daemon */
- uint32_t token; /* New command token (only if command was successfully
- authenticated) */
+ uint32_t pad4;
+ uint32_t pad5;
+
union {
RPY_Null null;
RPY_N_Sources n_sources;
RPY_Tracking tracking;
RPY_Sourcestats sourcestats;
RPY_Rtc rtc;
- RPY_SubnetsAccessed subnets_accessed;
- RPY_ClientAccesses client_accesses;
RPY_ClientAccessesByIndex client_accesses_by_index;
+ RPY_ServerStats server_stats;
RPY_ManualList manual_list;
RPY_Activity activity;
+ RPY_Smoothing smoothing;
+ RPY_NTPData ntp_data;
+ RPY_NTPSourceName ntp_source_name;
+ RPY_AuthData auth_data;
+ RPY_SelectData select_data;
} data; /* Reply specific parameters */
- /* authentication of the packet, there is no hole after the actual data
- from the data union, this field only sets the maximum auth size */
- uint8_t auth[MAX_HASH_LENGTH];
-
} CMD_Reply;
/* ================================================== */