summaryrefslogtreecommitdiffstats
path: root/candm.h
blob: 033cdb9e8924697f9912e73b0540c2958890b378 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
/*
  chronyd/chronyc - Programs for keeping computer clocks accurate.

 **********************************************************************
 * Copyright (C) Richard P. Curnow  1997-2003
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 **********************************************************************

  =======================================================================

  Definitions for the network protocol used for command and monitoring
  of the timeserver.

  */

#ifndef GOT_CANDM_H
#define GOT_CANDM_H

#include "sysincl.h"
#include "addressing.h"

/* This is the default port to use for CANDM, if no alternative is
   defined */
#define DEFAULT_CANDM_PORT 323

/* Request codes */
#define REQ_NULL 0
#define REQ_ONLINE 1
#define REQ_OFFLINE 2
#define REQ_BURST 3
#define REQ_MODIFY_MINPOLL 4
#define REQ_MODIFY_MAXPOLL 5
#define REQ_DUMP 6
#define REQ_MODIFY_MAXDELAY 7
#define REQ_MODIFY_MAXDELAYRATIO 8
#define REQ_MODIFY_MAXUPDATESKEW 9
#define REQ_LOGON 10
#define REQ_SETTIME 11
#define REQ_LOCAL 12
#define REQ_MANUAL 13
#define REQ_N_SOURCES 14
#define REQ_SOURCE_DATA 15
#define REQ_REKEY 16
#define REQ_ALLOW 17
#define REQ_ALLOWALL 18
#define REQ_DENY 19
#define REQ_DENYALL 20
#define REQ_CMDALLOW 21
#define REQ_CMDALLOWALL 22
#define REQ_CMDDENY 23
#define REQ_CMDDENYALL 24
#define REQ_ACCHECK 25
#define REQ_CMDACCHECK 26
#define REQ_ADD_SERVER 27
#define REQ_ADD_PEER 28
#define REQ_DEL_SOURCE 29
#define REQ_WRITERTC 30
#define REQ_DFREQ 31
#define REQ_DOFFSET 32
#define REQ_TRACKING 33
#define REQ_SOURCESTATS 34
#define REQ_RTCREPORT 35
#define REQ_TRIMRTC 36
#define REQ_CYCLELOGS 37
#define REQ_SUBNETS_ACCESSED 38
#define REQ_CLIENT_ACCESSES 39
#define REQ_CLIENT_ACCESSES_BY_INDEX 40
#define REQ_MANUAL_LIST 41
#define REQ_MANUAL_DELETE 42
#define REQ_MAKESTEP 43
#define REQ_ACTIVITY 44
#define REQ_MODIFY_MINSTRATUM 45
#define REQ_MODIFY_POLLTARGET 46
#define REQ_MODIFY_MAXDELAYDEVRATIO 47
#define REQ_RESELECT 48
#define REQ_RESELECTDISTANCE 49
#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 N_REQUEST_TYPES 73

/* 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;
} 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 */
typedef struct {
  int32_t f;
} Float;

/* The EOR (end of record) fields are used by the offsetof operator in
   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;
  int32_t EOR;
} REQ_Online;

typedef struct {
  IPAddr mask;
  IPAddr address;
  int32_t EOR;
} REQ_Offline;

typedef struct {
  IPAddr mask;
  IPAddr address;
  int32_t n_good_samples;
  int32_t n_total_samples;
  int32_t EOR;
} REQ_Burst;

typedef struct {
  IPAddr address;
  int32_t new_minpoll;
  int32_t EOR;
} REQ_Modify_Minpoll;

typedef struct {
  IPAddr address;
  int32_t new_maxpoll;
  int32_t EOR;
} REQ_Modify_Maxpoll;

typedef struct {
  int32_t pad;
  int32_t EOR;
} REQ_Dump;

typedef struct {
  IPAddr address;
  Float new_max_delay;
  int32_t EOR;
} REQ_Modify_Maxdelay;

typedef struct {
  IPAddr address;
  Float new_max_delay_ratio;
  int32_t EOR;
} REQ_Modify_Maxdelayratio;

typedef struct {
  IPAddr address;
  Float new_max_delay_dev_ratio;
  int32_t EOR;
} REQ_Modify_Maxdelaydevratio;

typedef struct {
  IPAddr address;
  int32_t new_min_stratum;
  int32_t EOR;
} REQ_Modify_Minstratum;

typedef struct {
  IPAddr address;
  int32_t new_poll_target;
  int32_t EOR;
} REQ_Modify_Polltarget;

typedef struct {
  Float new_max_update_skew;
  int32_t EOR;
} REQ_Modify_Maxupdateskew;

typedef struct {
  int32_t limit;
  Float threshold;
  int32_t EOR;
} REQ_Modify_Makestep;

typedef struct {
  Timespec ts;
  int32_t EOR;
} REQ_Logon;

typedef struct {
  Timespec ts;
  int32_t EOR;
} REQ_Settime;

typedef struct {
  int32_t on_off;
  int32_t stratum;
  Float distance;
  int32_t orphan;
  int32_t EOR;
} REQ_Local;

typedef struct {
  int32_t option;
  int32_t EOR;
} REQ_Manual;

typedef struct {
  int32_t index;
  int32_t EOR;
} REQ_Source_Data;

typedef struct {
  IPAddr ip;
  int32_t subnet_bits;
  int32_t EOR;
} REQ_Allow_Deny;

typedef struct {
  IPAddr ip;
  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
#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

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;

typedef struct {
  IPAddr ip_addr;
  int32_t EOR;
} REQ_Del_Source;

typedef struct {
  Float dfreq;
  int32_t EOR;
} REQ_Dfreq;

typedef struct {
  Float doffset;
  int32_t EOR;
} REQ_Doffset;

typedef struct {
  uint32_t index;
  int32_t EOR;
} REQ_Sourcestats;

/* 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_ClientAccessesByIndex;

typedef struct {
  int32_t index;
  int32_t EOR;
} REQ_ManualDelete;

typedef struct {
  Float distance;
  int32_t EOR;
} REQ_ReselectDistance;

#define REQ_SMOOTHTIME_RESET 0
#define REQ_SMOOTHTIME_ACTIVATE 1

typedef struct {
  int32_t option;
  int32_t EOR;
} REQ_SmoothTime;

typedef struct {
  IPAddr ip_addr;
  int32_t EOR;
} REQ_NTPData;

typedef struct {
  IPAddr ip_addr;
  int32_t EOR;
} REQ_NTPSourceName;

typedef struct {
  IPAddr ip_addr;
  int32_t EOR;
} REQ_AuthData;

typedef struct {
  uint32_t index;
  int32_t EOR;
} 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_Modify_SelectOpts;

/* ================================================== */

#define PKT_TYPE_CMD_REQUEST 1
#define PKT_TYPE_CMD_REPLY 2

/* This version number needs to be incremented whenever the packet
   size and/or the format of any of the existing messages is changed.
   Other changes, e.g. new command types, should be handled cleanly by
   client.c and cmdmon.c anyway, so the version can stay the same.
   
   Version 1 : original version with fixed size packets

   Version 2 : both command and reply packet sizes made capable of
   being variable length.

   Version 3 : NTP_Source message lengthened (auto_offline)

   Version 4 : IPv6 addressing added, 64-bit time values, sourcestats 
   and tracking reports extended, added flags to NTP source request,
   trimmed source report, replaced fixed-point format with floating-point
   and used also instead of integer microseconds, new commands: modify stratum,
   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, 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 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 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

/* ================================================== */

typedef struct {
  uint8_t version; /* Protocol version */
  uint8_t pkt_type; /* What sort of packet this is */
  uint8_t res1;
  uint8_t res2;
  uint16_t command; /* Which command is being issued */
  uint16_t attempt; /* How many resends the client has done
                             (count up from zero for same sequence
                             number) */
  uint32_t sequence; /* Client's sequence number */
  uint32_t pad1;
  uint32_t pad2;

  union {
    REQ_Null null;
    REQ_Online online;
    REQ_Offline offline;
    REQ_Burst burst;
    REQ_Modify_Minpoll modify_minpoll;
    REQ_Modify_Maxpoll modify_maxpoll;
    REQ_Dump dump;
    REQ_Modify_Maxdelay modify_maxdelay;
    REQ_Modify_Maxdelayratio modify_maxdelayratio;
    REQ_Modify_Maxdelaydevratio modify_maxdelaydevratio;
    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_Source_Data source_data;
    REQ_Allow_Deny allow_deny;
    REQ_Ac_Check ac_check;
    REQ_NTP_Source ntp_source;
    REQ_Del_Source del_source;
    REQ_Dfreq dfreq;
    REQ_Doffset doffset;
    REQ_Sourcestats sourcestats;
    REQ_ClientAccessesByIndex client_accesses_by_index;
    REQ_ManualDelete manual_delete;
    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;
  } data; /* Command specific parameters */

  /* 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;

/* ================================================== */
/* Authority codes for command types */

#define PERMIT_OPEN 0
#define PERMIT_LOCAL 1
#define PERMIT_AUTH 2

/* ================================================== */

/* Reply codes */
#define RPY_NULL 1
#define RPY_N_SOURCES 2
#define RPY_SOURCE_DATA 3
#define RPY_MANUAL_TIMESTAMP 4
#define RPY_TRACKING 5
#define RPY_SOURCESTATS 6
#define RPY_RTC 7
#define RPY_SUBNETS_ACCESSED 8
#define RPY_CLIENT_ACCESSES 9
#define RPY_CLIENT_ACCESSES_BY_INDEX 10
#define RPY_MANUAL_LIST 11
#define RPY_ACTIVITY 12
#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 N_REPLY_TYPES 26

/* Status codes */
#define STT_SUCCESS 0
#define STT_FAILED 1
#define STT_UNAUTH 2
#define STT_INVALID 3
#define STT_NOSUCHSOURCE 4
#define STT_INVALIDTS 5
#define STT_NOTENABLED 6
#define STT_BADSUBNET 7
#define STT_ACCESSALLOWED 8
#define STT_ACCESSDENIED 9
#define STT_NOHOSTACCESS 10 /* Deprecated */
#define STT_SOURCEALREADYKNOWN 11
#define STT_TOOMANYSOURCES 12
#define STT_NORTC 13
#define STT_BADRTCFILE 14
#define STT_INACTIVE 15
#define STT_BADSAMPLE 16
#define STT_INVALIDAF 17
#define STT_BADPKTVERSION 18
#define STT_BADPKTLENGTH 19
#define STT_INVALIDNAME 21

typedef struct {
  int32_t EOR;
} RPY_Null;

typedef struct {
  uint32_t n_sources;
  int32_t EOR;
} RPY_N_Sources;

#define RPY_SD_MD_CLIENT 0
#define RPY_SD_MD_PEER   1
#define RPY_SD_MD_REF    2

#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_UNSELECTED 4
#define RPY_SD_ST_SELECTABLE 5

typedef struct {
  IPAddr ip_addr;
  int16_t poll;
  uint16_t stratum;
  uint16_t state;
  uint16_t mode;
  uint16_t flags;
  uint16_t reachability;
  uint32_t  since_sample;
  Float orig_latest_meas;
  Float latest_meas;
  Float latest_meas_err;
  int32_t EOR;
} RPY_Source_Data;

typedef struct {
  uint32_t ref_id;
  IPAddr ip_addr;
  uint16_t stratum;
  uint16_t leap_status;
  Timespec ref_time;
  Float current_correction;
  Float last_offset;
  Float rms_offset;
  Float freq_ppm;
  Float resid_freq_ppm;
  Float skew_ppm;
  Float root_delay;
  Float root_dispersion;
  Float last_update_interval;
  int32_t EOR;
} RPY_Tracking;

typedef struct {
  uint32_t ref_id;
  IPAddr ip_addr;
  uint32_t n_samples;
  uint32_t n_runs;
  uint32_t span_seconds;
  Float sd;
  Float resid_freq_ppm;
  Float skew_ppm;
  Float est_offset;
  Float est_offset_err;
  int32_t EOR;
} RPY_Sourcestats;

typedef struct {
  Timespec ref_time;
  uint16_t n_samples;
  uint16_t n_runs;
  uint32_t span_seconds;
  Float rtc_seconds_fast;
  Float rtc_gain_rate_ppm;
  int32_t EOR;
} RPY_Rtc;

typedef struct {
  Float offset;
  Float dfreq_ppm;
  Float new_afreq_ppm;
  int32_t EOR;
} RPY_ManualTimestamp;

typedef struct {
  IPAddr ip;
  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_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;

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 {
  Timespec when;
  Float slewed_offset;
  Float orig_offset;
  Float residual;
} RPY_ManualListSample;

typedef struct {
  uint32_t n_samples;
  RPY_ManualListSample samples[MAX_MANUAL_LIST_SAMPLES];
  int32_t EOR;
} RPY_ManualList;

typedef struct {
  int32_t online;
  int32_t offline;
  int32_t burst_online;
  int32_t burst_offline;
  int32_t unresolved;
  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 reserved[3];
  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;
  uint8_t res1;
  uint8_t res2;
  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 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 pad4;
  uint32_t pad5;

  union {
    RPY_Null null;
    RPY_N_Sources n_sources;
    RPY_Source_Data source_data;
    RPY_ManualTimestamp manual_timestamp;
    RPY_Tracking tracking;
    RPY_Sourcestats sourcestats;
    RPY_Rtc rtc;
    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 */

} CMD_Reply;

/* ================================================== */

#endif /* GOT_CANDM_H */