Coverage Report

Created: 2026-02-26 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ntp-dev/ntpd/ntp_control.c
Line
Count
Source
1
/*
2
 * ntp_control.c - respond to mode 6 control messages and send async
3
 *       traps.  Provides service to ntpq and others.
4
 */
5
6
#ifdef HAVE_CONFIG_H
7
# include <config.h>
8
#endif
9
10
#include <stdio.h>
11
#include <ctype.h>
12
#include <signal.h>
13
#include <sys/stat.h>
14
#ifdef HAVE_NETINET_IN_H
15
# include <netinet/in.h>
16
#endif
17
#include <arpa/inet.h>
18
19
#include "ntpd.h"
20
#include "ntp_io.h"
21
#include "ntp_refclock.h"
22
#include "ntp_control.h"
23
#include "ntp_unixtime.h"
24
#include "ntp_stdlib.h"
25
#include "ntp_config.h"
26
#include "ntp_crypto.h"
27
#include "ntp_assert.h"
28
#include "ntp_leapsec.h"
29
#include "timexsup.h"
30
31
#include <rc_cmdlength.h>
32
#ifdef KERNEL_PLL
33
# include "ntp_syscall.h"
34
#endif
35
36
/*
37
 * Structure to hold request procedure information
38
 */
39
40
struct ctl_proc {
41
  short control_code;   /* defined request code */
42
0
#define NO_REQUEST  (-1)
43
  u_short flags;      /* flags word */
44
  /* Only one flag.  Authentication required or not. */
45
#define NOAUTH  0
46
0
#define AUTH  1
47
  void (*handler) (struct recvbuf *, int); /* handle request */
48
};
49
50
51
/*
52
 * Request processing routines
53
 */
54
static  void  ctl_error (u_char);
55
#ifdef REFCLOCK
56
static  u_short ctlclkstatus  (struct refclockstat *);
57
#endif
58
static  void  ctl_flushpkt  (u_char);
59
static  void  ctl_putdata (const char *, unsigned int, int);
60
static  void  ctl_putstr  (const char *, const char *, size_t);
61
static  void  ctl_putdblf (const char *, int, int, double);
62
0
#define ctl_putdbl(tag, d)  ctl_putdblf(tag, 1, 3, d)
63
0
#define ctl_putdbl6(tag, d) ctl_putdblf(tag, 1, 6, d)
64
0
#define ctl_putsfp(tag, sfp)  ctl_putdblf(tag, 0, -1, \
65
0
              FPTOD(sfp))
66
static  void  ctl_putuint (const char *, u_long);
67
static  void  ctl_puthex  (const char *, u_long);
68
static  void  ctl_putint  (const char *, long);
69
static  void  ctl_putts (const char *, l_fp *);
70
static  void  ctl_putadr  (const char *, u_int32,
71
         sockaddr_u *);
72
static  void  ctl_putrefid  (const char *, u_int32);
73
static  void  ctl_putarray  (const char *, double *, int);
74
static  void  ctl_putsys  (int);
75
static  void  ctl_putpeer (int, struct peer *);
76
static  void  ctl_putfs (const char *, tstamp_t);
77
static  void  ctl_printf  (const char *, ...) NTP_PRINTF(1, 2);
78
#ifdef REFCLOCK
79
static  void  ctl_putclock  (int, struct refclockstat *, int);
80
#endif  /* REFCLOCK */
81
static  const struct ctl_var *ctl_getitem(const struct ctl_var *,
82
            char **);
83
static  u_short count_var (const struct ctl_var *);
84
static  void  control_unspec  (struct recvbuf *, int);
85
static  void  read_status (struct recvbuf *, int);
86
static  void  read_sysvars  (void);
87
static  void  read_peervars (void);
88
static  void  read_variables  (struct recvbuf *, int);
89
static  void  write_variables (struct recvbuf *, int);
90
static  void  read_clockstatus(struct recvbuf *, int);
91
static  void  write_clockstatus(struct recvbuf *, int);
92
static  void  set_trap  (struct recvbuf *, int);
93
static  void  save_config (struct recvbuf *, int);
94
static  void  configure (struct recvbuf *, int);
95
static  void  send_mru_entry  (mon_entry *, int);
96
static  void  send_random_tag_value(int);
97
static  void  read_mru_list (struct recvbuf *, int);
98
static  void  send_ifstats_entry(endpt *, u_int);
99
static  void  read_ifstats  (struct recvbuf *);
100
static  void  sockaddrs_from_restrict_u(sockaddr_u *, sockaddr_u *,
101
            restrict_u *, int);
102
static  void  send_restrict_entry(restrict_u *, int, u_int);
103
static  void  send_restrict_list(restrict_u *, int, u_int *);
104
static  void  read_addr_restrictions(struct recvbuf *);
105
static  void  read_ordlist  (struct recvbuf *, int);
106
static  u_int32 derive_nonce  (sockaddr_u *, u_int32, u_int32);
107
static  void  generate_nonce  (struct recvbuf *, char *, size_t);
108
static  int validate_nonce  (const char *, struct recvbuf *);
109
static  void  req_nonce (struct recvbuf *, int);
110
static  void  unset_trap  (struct recvbuf *, int);
111
static  struct ctl_trap *ctlfindtrap(sockaddr_u *,
112
             endpt *);
113
114
int/*BOOL*/ is_safe_filename(const char * name);
115
116
static const struct ctl_proc control_codes[] = {
117
  { CTL_OP_UNSPEC,    NOAUTH, control_unspec },
118
  { CTL_OP_READSTAT,    NOAUTH, read_status },
119
  { CTL_OP_READVAR,   NOAUTH, read_variables },
120
  { CTL_OP_WRITEVAR,    AUTH, write_variables },
121
  { CTL_OP_READCLOCK,   NOAUTH, read_clockstatus },
122
  { CTL_OP_WRITECLOCK,    AUTH, write_clockstatus },
123
  { CTL_OP_SETTRAP,   AUTH, set_trap },
124
  { CTL_OP_CONFIGURE,   AUTH, configure },
125
  { CTL_OP_SAVECONFIG,    AUTH, save_config },
126
  { CTL_OP_READ_MRU,    NOAUTH, read_mru_list },
127
  { CTL_OP_READ_ORDLIST_A,  AUTH, read_ordlist },
128
  { CTL_OP_REQ_NONCE,   NOAUTH, req_nonce },
129
  { CTL_OP_UNSETTRAP,   AUTH, unset_trap },
130
  { NO_REQUEST,     0,  NULL }
131
};
132
133
/*
134
 * System variables we understand
135
 */
136
0
#define CS_LEAP     1
137
0
#define CS_STRATUM    2
138
0
#define CS_PRECISION    3
139
0
#define CS_ROOTDELAY    4
140
0
#define CS_ROOTDISPERSION 5
141
0
#define CS_REFID    6
142
0
#define CS_REFTIME    7
143
0
#define CS_POLL     8
144
0
#define CS_PEERID   9
145
0
#define CS_OFFSET   10
146
0
#define CS_DRIFT    11
147
0
#define CS_JITTER   12
148
0
#define CS_ERROR    13
149
0
#define CS_CLOCK    14
150
0
#define CS_PROCESSOR    15
151
0
#define CS_SYSTEM   16
152
0
#define CS_VERSION    17
153
0
#define CS_STABIL   18
154
0
#define CS_VARLIST    19
155
0
#define CS_TAI      20
156
0
#define CS_LEAPTAB    21
157
0
#define CS_LEAPEND    22
158
0
#define CS_RATE     23
159
0
#define CS_MRU_ENABLED    24
160
0
#define CS_MRU_DEPTH    25
161
0
#define CS_MRU_DEEPEST    26
162
0
#define CS_MRU_MINDEPTH   27
163
0
#define CS_MRU_MAXAGE   28
164
0
#define CS_MRU_MAXDEPTH   29
165
0
#define CS_MRU_MEM    30
166
0
#define CS_MRU_MAXMEM   31
167
0
#define CS_SS_UPTIME    32
168
0
#define CS_SS_RESET   33
169
0
#define CS_SS_RECEIVED    34
170
0
#define CS_SS_THISVER   35
171
0
#define CS_SS_OLDVER    36
172
0
#define CS_SS_BADFORMAT   37
173
0
#define CS_SS_BADAUTH   38
174
0
#define CS_SS_DECLINED    39
175
0
#define CS_SS_RESTRICTED  40
176
0
#define CS_SS_LIMITED   41
177
0
#define CS_SS_KODSENT   42
178
0
#define CS_SS_PROCESSED   43
179
0
#define CS_SS_LAMPORT   44
180
0
#define CS_SS_TSROUNDING  45
181
0
#define CS_PEERADR    46
182
0
#define CS_PEERMODE   47
183
0
#define CS_BCASTDELAY   48
184
0
#define CS_AUTHDELAY    49
185
0
#define CS_AUTHKEYS   50
186
0
#define CS_AUTHFREEK    51
187
0
#define CS_AUTHKLOOKUPS   52
188
0
#define CS_AUTHKNOTFOUND  53
189
0
#define CS_AUTHKUNCACHED  54
190
0
#define CS_AUTHKEXPIRED   55
191
0
#define CS_AUTHENCRYPTS   56
192
0
#define CS_AUTHDECRYPTS   57
193
0
#define CS_AUTHRESET    58
194
0
#define CS_K_OFFSET   59
195
0
#define CS_K_FREQ   60
196
0
#define CS_K_MAXERR   61
197
0
#define CS_K_ESTERR   62
198
0
#define CS_K_STFLAGS    63
199
0
#define CS_K_TIMECONST    64
200
0
#define CS_K_PRECISION    65
201
0
#define CS_K_FREQTOL    66
202
0
#define CS_K_PPS_FREQ   67
203
0
#define CS_K_PPS_STABIL   68
204
0
#define CS_K_PPS_JITTER   69
205
0
#define CS_K_PPS_CALIBDUR 70
206
0
#define CS_K_PPS_CALIBS   71
207
0
#define CS_K_PPS_CALIBERRS  72
208
0
#define CS_K_PPS_JITEXC   73
209
0
#define CS_K_PPS_STBEXC   74
210
0
#define CS_KERN_FIRST   CS_K_OFFSET
211
0
#define CS_KERN_LAST    CS_K_PPS_STBEXC
212
0
#define CS_IOSTATS_RESET  75
213
0
#define CS_TOTAL_RBUF   76
214
0
#define CS_FREE_RBUF    77
215
0
#define CS_USED_RBUF    78
216
0
#define CS_RBUF_LOWATER   79
217
0
#define CS_IO_DROPPED   80
218
0
#define CS_IO_IGNORED   81
219
0
#define CS_IO_RECEIVED    82
220
0
#define CS_IO_SENT    83
221
0
#define CS_IO_SENDFAILED  84
222
0
#define CS_IO_WAKEUPS   85
223
0
#define CS_IO_GOODWAKEUPS 86
224
0
#define CS_TIMERSTATS_RESET 87
225
0
#define CS_TIMER_OVERRUNS 88
226
0
#define CS_TIMER_XMTS   89
227
0
#define CS_FUZZ     90
228
0
#define CS_WANDER_THRESH  91
229
#define CS_LEAPSMEARINTV  92
230
0
#define CS_LEAPSMEAROFFS  93
231
0
#define CS_MAX_NOAUTOKEY  CS_LEAPSMEAROFFS
232
#ifdef AUTOKEY
233
0
#define CS_FLAGS    (1 + CS_MAX_NOAUTOKEY)
234
0
#define CS_HOST     (2 + CS_MAX_NOAUTOKEY)
235
0
#define CS_PUBLIC   (3 + CS_MAX_NOAUTOKEY)
236
0
#define CS_CERTIF   (4 + CS_MAX_NOAUTOKEY)
237
0
#define CS_SIGNATURE    (5 + CS_MAX_NOAUTOKEY)
238
0
#define CS_REVTIME    (6 + CS_MAX_NOAUTOKEY)
239
0
#define CS_IDENT    (7 + CS_MAX_NOAUTOKEY)
240
0
#define CS_DIGEST   (8 + CS_MAX_NOAUTOKEY)
241
0
#define CS_MAXCODE    CS_DIGEST
242
#else /* !AUTOKEY follows */
243
#define CS_MAXCODE    CS_MAX_NOAUTOKEY
244
#endif  /* !AUTOKEY */
245
246
/*
247
 * Peer variables we understand
248
 */
249
0
#define CP_CONFIG   1
250
0
#define CP_AUTHENABLE   2
251
0
#define CP_AUTHENTIC    3
252
0
#define CP_SRCADR   4
253
0
#define CP_SRCPORT    5
254
0
#define CP_DSTADR   6
255
0
#define CP_DSTPORT    7
256
0
#define CP_LEAP     8
257
0
#define CP_HMODE    9
258
0
#define CP_STRATUM    10
259
0
#define CP_PPOLL    11
260
0
#define CP_HPOLL    12
261
0
#define CP_PRECISION    13
262
0
#define CP_ROOTDELAY    14
263
0
#define CP_ROOTDISPERSION 15
264
0
#define CP_REFID    16
265
0
#define CP_REFTIME    17
266
0
#define CP_ORG      18
267
0
#define CP_REC      19
268
0
#define CP_XMT      20
269
0
#define CP_REACH    21
270
0
#define CP_UNREACH    22
271
0
#define CP_TIMER    23
272
0
#define CP_DELAY    24
273
0
#define CP_OFFSET   25
274
0
#define CP_JITTER   26
275
0
#define CP_DISPERSION   27
276
0
#define CP_KEYID    28
277
0
#define CP_FILTDELAY    29
278
0
#define CP_FILTOFFSET   30
279
0
#define CP_PMODE    31
280
0
#define CP_RECEIVED   32
281
0
#define CP_SENT     33
282
0
#define CP_FILTERROR    34
283
0
#define CP_FLASH    35
284
0
#define CP_TTL      36
285
0
#define CP_VARLIST    37
286
0
#define CP_IN     38
287
0
#define CP_OUT      39
288
0
#define CP_RATE     40
289
0
#define CP_BIAS     41
290
0
#define CP_SRCHOST    42
291
0
#define CP_TIMEREC    43
292
0
#define CP_TIMEREACH    44
293
0
#define CP_BADAUTH    45
294
0
#define CP_BOGUSORG   46
295
0
#define CP_OLDPKT   47
296
0
#define CP_SELDISP    48
297
0
#define CP_SELBROKEN    49
298
0
#define CP_CANDIDATE    50
299
0
#define CP_MAX_NOAUTOKEY  CP_CANDIDATE
300
#ifdef AUTOKEY
301
0
#define CP_FLAGS    (1 + CP_MAX_NOAUTOKEY)
302
0
#define CP_HOST     (2 + CP_MAX_NOAUTOKEY)
303
0
#define CP_VALID    (3 + CP_MAX_NOAUTOKEY)
304
0
#define CP_INITSEQ    (4 + CP_MAX_NOAUTOKEY)
305
0
#define CP_INITKEY    (5 + CP_MAX_NOAUTOKEY)
306
0
#define CP_INITTSP    (6 + CP_MAX_NOAUTOKEY)
307
0
#define CP_SIGNATURE    (7 + CP_MAX_NOAUTOKEY)
308
0
#define CP_IDENT    (8 + CP_MAX_NOAUTOKEY)
309
#define CP_MAXCODE    CP_IDENT
310
#else /* !AUTOKEY follows */
311
#define CP_MAXCODE    CP_MAX_NOAUTOKEY
312
#endif  /* !AUTOKEY */
313
314
/*
315
 * Clock variables we understand
316
 */
317
0
#define CC_TYPE   1
318
0
#define CC_TIMECODE 2
319
0
#define CC_POLL   3
320
0
#define CC_NOREPLY  4
321
0
#define CC_BADFORMAT  5
322
0
#define CC_BADDATA  6
323
0
#define CC_FUDGETIME1 7
324
0
#define CC_FUDGETIME2 8
325
0
#define CC_FUDGEVAL1  9
326
0
#define CC_FUDGEVAL2  10
327
0
#define CC_FLAGS  11
328
0
#define CC_DEVICE 12
329
0
#define CC_VARLIST  13
330
0
#define CC_FUDGEMINJIT  14
331
0
#define CC_MAXCODE  CC_FUDGEMINJIT
332
333
/*
334
 * System variable values. The array can be indexed by the variable
335
 * index to find the textual name.
336
 */
337
static const struct ctl_var sys_var[] = {
338
  { 0,    PADDING, "" },    /* 0 */
339
  { CS_LEAP,  RW, "leap" },   /* 1 */
340
  { CS_STRATUM, RO, "stratum" },  /* 2 */
341
  { CS_PRECISION, RO, "precision" },  /* 3 */
342
  { CS_ROOTDELAY, RO, "rootdelay" },  /* 4 */
343
  { CS_ROOTDISPERSION, RO, "rootdisp" },  /* 5 */
344
  { CS_REFID, RO, "refid" },    /* 6 */
345
  { CS_REFTIME, RO, "reftime" },  /* 7 */
346
  { CS_POLL,  RO, "tc" },   /* 8 */
347
  { CS_PEERID,  RO, "peer" },   /* 9 */
348
  { CS_OFFSET,  RO, "offset" },   /* 10 */
349
  { CS_DRIFT, RO, "frequency" },  /* 11 */
350
  { CS_JITTER,  RO, "sys_jitter" }, /* 12 */
351
  { CS_ERROR, RO, "clk_jitter" }, /* 13 */
352
  { CS_CLOCK, RO, "clock" },    /* 14 */
353
  { CS_PROCESSOR, RO, "processor" },  /* 15 */
354
  { CS_SYSTEM,  RO, "system" },   /* 16 */
355
  { CS_VERSION, RO, "version" },  /* 17 */
356
  { CS_STABIL,  RO, "clk_wander" }, /* 18 */
357
  { CS_VARLIST, RO, "sys_var_list" }, /* 19 */
358
  { CS_TAI, RO, "tai" },    /* 20 */
359
  { CS_LEAPTAB, RO, "leapsec" },  /* 21 */
360
  { CS_LEAPEND, RO, "expire" },   /* 22 */
361
  { CS_RATE,  RO, "mintc" },    /* 23 */
362
  { CS_MRU_ENABLED, RO, "mru_enabled" },  /* 24 */
363
  { CS_MRU_DEPTH,   RO, "mru_depth" },  /* 25 */
364
  { CS_MRU_DEEPEST, RO, "mru_deepest" },  /* 26 */
365
  { CS_MRU_MINDEPTH,  RO, "mru_mindepth" }, /* 27 */
366
  { CS_MRU_MAXAGE,  RO, "mru_maxage" }, /* 28 */
367
  { CS_MRU_MAXDEPTH,  RO, "mru_maxdepth" }, /* 29 */
368
  { CS_MRU_MEM,   RO, "mru_mem" },  /* 30 */
369
  { CS_MRU_MAXMEM,  RO, "mru_maxmem" }, /* 31 */
370
  { CS_SS_UPTIME,   RO, "ss_uptime" },  /* 32 */
371
  { CS_SS_RESET,    RO, "ss_reset" }, /* 33 */
372
  { CS_SS_RECEIVED, RO, "ss_received" },  /* 34 */
373
  { CS_SS_THISVER,  RO, "ss_thisver" }, /* 35 */
374
  { CS_SS_OLDVER,   RO, "ss_oldver" },  /* 36 */
375
  { CS_SS_BADFORMAT,  RO, "ss_badformat" }, /* 37 */
376
  { CS_SS_BADAUTH,  RO, "ss_badauth" }, /* 38 */
377
  { CS_SS_DECLINED, RO, "ss_declined" },  /* 39 */
378
  { CS_SS_RESTRICTED, RO, "ss_restricted" },  /* 40 */
379
  { CS_SS_LIMITED,  RO, "ss_limited" }, /* 41 */
380
  { CS_SS_KODSENT,  RO, "ss_kodsent" }, /* 42 */
381
  { CS_SS_PROCESSED,  RO, "ss_processed" }, /* 43 */
382
  { CS_SS_LAMPORT,  RO, "ss_lamport" }, /* 44 */
383
  { CS_SS_TSROUNDING, RO, "ss_tsrounding" },  /* 45 */
384
  { CS_PEERADR,   RO, "peeradr" },  /* 46 */
385
  { CS_PEERMODE,    RO, "peermode" }, /* 47 */
386
  { CS_BCASTDELAY,  RO, "bcastdelay" }, /* 48 */
387
  { CS_AUTHDELAY,   RO, "authdelay" },  /* 49 */
388
  { CS_AUTHKEYS,    RO, "authkeys" }, /* 50 */
389
  { CS_AUTHFREEK,   RO, "authfreek" },  /* 51 */
390
  { CS_AUTHKLOOKUPS,  RO, "authklookups" }, /* 52 */
391
  { CS_AUTHKNOTFOUND, RO, "authknotfound" },  /* 53 */
392
  { CS_AUTHKUNCACHED, RO, "authkuncached" },  /* 54 */
393
  { CS_AUTHKEXPIRED,  RO, "authkexpired" }, /* 55 */
394
  { CS_AUTHENCRYPTS,  RO, "authencrypts" }, /* 56 */
395
  { CS_AUTHDECRYPTS,  RO, "authdecrypts" }, /* 57 */
396
  { CS_AUTHRESET,   RO, "authreset" },  /* 58 */
397
  { CS_K_OFFSET,    RO, "koffset" },  /* 59 */
398
  { CS_K_FREQ,    RO, "kfreq" },    /* 60 */
399
  { CS_K_MAXERR,    RO, "kmaxerr" },  /* 61 */
400
  { CS_K_ESTERR,    RO, "kesterr" },  /* 62 */
401
  { CS_K_STFLAGS,   RO, "kstflags" }, /* 63 */
402
  { CS_K_TIMECONST, RO, "ktimeconst" }, /* 64 */
403
  { CS_K_PRECISION, RO, "kprecis" },  /* 65 */
404
  { CS_K_FREQTOL,   RO, "kfreqtol" }, /* 66 */
405
  { CS_K_PPS_FREQ,  RO, "kppsfreq" }, /* 67 */
406
  { CS_K_PPS_STABIL,  RO, "kppsstab" }, /* 68 */
407
  { CS_K_PPS_JITTER,  RO, "kppsjitter" }, /* 69 */
408
  { CS_K_PPS_CALIBDUR,  RO, "kppscalibdur" }, /* 70 */
409
  { CS_K_PPS_CALIBS,  RO, "kppscalibs" }, /* 71 */
410
  { CS_K_PPS_CALIBERRS, RO, "kppscaliberrs" },  /* 72 */
411
  { CS_K_PPS_JITEXC,  RO, "kppsjitexc" }, /* 73 */
412
  { CS_K_PPS_STBEXC,  RO, "kppsstbexc" }, /* 74 */
413
  { CS_IOSTATS_RESET, RO, "iostats_reset" },  /* 75 */
414
  { CS_TOTAL_RBUF,  RO, "total_rbuf" }, /* 76 */
415
  { CS_FREE_RBUF,   RO, "free_rbuf" },  /* 77 */
416
  { CS_USED_RBUF,   RO, "used_rbuf" },  /* 78 */
417
  { CS_RBUF_LOWATER,  RO, "rbuf_lowater" }, /* 79 */
418
  { CS_IO_DROPPED,  RO, "io_dropped" }, /* 80 */
419
  { CS_IO_IGNORED,  RO, "io_ignored" }, /* 81 */
420
  { CS_IO_RECEIVED, RO, "io_received" },  /* 82 */
421
  { CS_IO_SENT,   RO, "io_sent" },  /* 83 */
422
  { CS_IO_SENDFAILED, RO, "io_sendfailed" },  /* 84 */
423
  { CS_IO_WAKEUPS,  RO, "io_wakeups" }, /* 85 */
424
  { CS_IO_GOODWAKEUPS,  RO, "io_goodwakeups" }, /* 86 */
425
  { CS_TIMERSTATS_RESET,  RO, "timerstats_reset" },/* 87 */
426
  { CS_TIMER_OVERRUNS,  RO, "timer_overruns" }, /* 88 */
427
  { CS_TIMER_XMTS,  RO, "timer_xmts" }, /* 89 */
428
  { CS_FUZZ,    RO, "fuzz" },   /* 90 */
429
  { CS_WANDER_THRESH, RO, "clk_wander_threshold" }, /* 91 */
430
431
  { CS_LEAPSMEARINTV, RO, "leapsmearinterval" },    /* 92 */
432
  { CS_LEAPSMEAROFFS, RO, "leapsmearoffset" },      /* 93 */
433
434
#ifdef AUTOKEY
435
  { CS_FLAGS, RO, "flags" },    /* 1 + CS_MAX_NOAUTOKEY */
436
  { CS_HOST,  RO, "host" },   /* 2 + CS_MAX_NOAUTOKEY */
437
  { CS_PUBLIC,  RO, "update" },   /* 3 + CS_MAX_NOAUTOKEY */
438
  { CS_CERTIF,  RO, "cert" },   /* 4 + CS_MAX_NOAUTOKEY */
439
  { CS_SIGNATURE, RO, "signature" },  /* 5 + CS_MAX_NOAUTOKEY */
440
  { CS_REVTIME, RO, "until" },    /* 6 + CS_MAX_NOAUTOKEY */
441
  { CS_IDENT, RO, "ident" },    /* 7 + CS_MAX_NOAUTOKEY */
442
  { CS_DIGEST,  RO, "digest" },   /* 8 + CS_MAX_NOAUTOKEY */
443
#endif  /* AUTOKEY */
444
  { 0,    EOV, "" }   /* 94/102 */
445
};
446
447
static struct ctl_var *ext_sys_var = NULL;
448
449
/*
450
 * System variables we print by default (in fuzzball order,
451
 * more-or-less)
452
 */
453
static const u_char def_sys_var[] = {
454
  CS_VERSION,
455
  CS_PROCESSOR,
456
  CS_SYSTEM,
457
  CS_LEAP,
458
  CS_STRATUM,
459
  CS_PRECISION,
460
  CS_ROOTDELAY,
461
  CS_ROOTDISPERSION,
462
  CS_REFID,
463
  CS_REFTIME,
464
  CS_CLOCK,
465
  CS_PEERID,
466
  CS_POLL,
467
  CS_RATE,
468
  CS_OFFSET,
469
  CS_DRIFT,
470
  CS_JITTER,
471
  CS_ERROR,
472
  CS_STABIL,
473
  CS_TAI,
474
  CS_LEAPTAB,
475
  CS_LEAPEND,
476
  CS_LEAPSMEARINTV,
477
  CS_LEAPSMEAROFFS,
478
#ifdef AUTOKEY
479
  CS_HOST,
480
  CS_IDENT,
481
  CS_FLAGS,
482
  CS_DIGEST,
483
  CS_SIGNATURE,
484
  CS_PUBLIC,
485
  CS_CERTIF,
486
#endif  /* AUTOKEY */
487
  0
488
};
489
490
491
/*
492
 * Peer variable list
493
 */
494
static const struct ctl_var peer_var[] = {
495
  { 0,    PADDING, "" },    /* 0 */
496
  { CP_CONFIG,  RO, "config" },   /* 1 */
497
  { CP_AUTHENABLE, RO,  "authenable" }, /* 2 */
498
  { CP_AUTHENTIC, RO, "authentic" },  /* 3 */
499
  { CP_SRCADR,  RO, "srcadr" },   /* 4 */
500
  { CP_SRCPORT, RO, "srcport" },  /* 5 */
501
  { CP_DSTADR,  RO, "dstadr" },   /* 6 */
502
  { CP_DSTPORT, RO, "dstport" },  /* 7 */
503
  { CP_LEAP,  RO, "leap" },   /* 8 */
504
  { CP_HMODE, RO, "hmode" },    /* 9 */
505
  { CP_STRATUM, RO, "stratum" },  /* 10 */
506
  { CP_PPOLL, RO, "ppoll" },    /* 11 */
507
  { CP_HPOLL, RO, "hpoll" },    /* 12 */
508
  { CP_PRECISION, RO, "precision" },  /* 13 */
509
  { CP_ROOTDELAY, RO, "rootdelay" },  /* 14 */
510
  { CP_ROOTDISPERSION, RO, "rootdisp" },  /* 15 */
511
  { CP_REFID, RO, "refid" },    /* 16 */
512
  { CP_REFTIME, RO, "reftime" },  /* 17 */
513
  { CP_ORG, RO, "org" },    /* 18 */
514
  { CP_REC, RO, "rec" },    /* 19 */
515
  { CP_XMT, RO, "xleave" },   /* 20 */
516
  { CP_REACH, RO, "reach" },    /* 21 */
517
  { CP_UNREACH, RO, "unreach" },  /* 22 */
518
  { CP_TIMER, RO, "timer" },    /* 23 */
519
  { CP_DELAY, RO, "delay" },    /* 24 */
520
  { CP_OFFSET,  RO, "offset" },   /* 25 */
521
  { CP_JITTER,  RO, "jitter" },   /* 26 */
522
  { CP_DISPERSION, RO, "dispersion" },  /* 27 */
523
  { CP_KEYID, RO, "keyid" },    /* 28 */
524
  { CP_FILTDELAY, RO, "filtdelay" },  /* 29 */
525
  { CP_FILTOFFSET, RO, "filtoffset" },  /* 30 */
526
  { CP_PMODE, RO, "pmode" },    /* 31 */
527
  { CP_RECEIVED,  RO, "received"},  /* 32 */
528
  { CP_SENT,  RO, "sent" },   /* 33 */
529
  { CP_FILTERROR, RO, "filtdisp" }, /* 34 */
530
  { CP_FLASH, RO, "flash" },    /* 35 */
531
  { CP_TTL, RO, "ttl" },    /* 36 */
532
  { CP_VARLIST, RO, "peer_var_list" },  /* 37 */
533
  { CP_IN,  RO, "in" },   /* 38 */
534
  { CP_OUT, RO, "out" },    /* 39 */
535
  { CP_RATE,  RO, "headway" },  /* 40 */
536
  { CP_BIAS,  RO, "bias" },   /* 41 */
537
  { CP_SRCHOST, RO, "srchost" },  /* 42 */
538
  { CP_TIMEREC, RO, "timerec" },  /* 43 */
539
  { CP_TIMEREACH, RO, "timereach" },  /* 44 */
540
  { CP_BADAUTH, RO, "badauth" },  /* 45 */
541
  { CP_BOGUSORG,  RO, "bogusorg" }, /* 46 */
542
  { CP_OLDPKT,  RO, "oldpkt" },   /* 47 */
543
  { CP_SELDISP, RO, "seldisp" },  /* 48 */
544
  { CP_SELBROKEN, RO, "selbroken" },  /* 49 */
545
  { CP_CANDIDATE, RO, "candidate" },  /* 50 */
546
#ifdef AUTOKEY
547
  { CP_FLAGS, RO, "flags" },    /* 1 + CP_MAX_NOAUTOKEY */
548
  { CP_HOST,  RO, "host" },   /* 2 + CP_MAX_NOAUTOKEY */
549
  { CP_VALID, RO, "valid" },    /* 3 + CP_MAX_NOAUTOKEY */
550
  { CP_INITSEQ, RO, "initsequence" }, /* 4 + CP_MAX_NOAUTOKEY */
551
  { CP_INITKEY, RO, "initkey" },  /* 5 + CP_MAX_NOAUTOKEY */
552
  { CP_INITTSP, RO, "timestamp" },  /* 6 + CP_MAX_NOAUTOKEY */
553
  { CP_SIGNATURE, RO, "signature" },  /* 7 + CP_MAX_NOAUTOKEY */
554
  { CP_IDENT, RO, "ident" },    /* 8 + CP_MAX_NOAUTOKEY */
555
#endif  /* AUTOKEY */
556
  { 0,    EOV, "" }   /* 50/58 */
557
};
558
559
560
/*
561
 * Peer variables we print by default
562
 */
563
static const u_char def_peer_var[] = {
564
  CP_SRCADR,
565
  CP_SRCPORT,
566
  CP_SRCHOST,
567
  CP_DSTADR,
568
  CP_DSTPORT,
569
  CP_OUT,
570
  CP_IN,
571
  CP_LEAP,
572
  CP_STRATUM,
573
  CP_PRECISION,
574
  CP_ROOTDELAY,
575
  CP_ROOTDISPERSION,
576
  CP_REFID,
577
  CP_REFTIME,
578
  CP_REC,
579
  CP_REACH,
580
  CP_UNREACH,
581
  CP_HMODE,
582
  CP_PMODE,
583
  CP_HPOLL,
584
  CP_PPOLL,
585
  CP_RATE,
586
  CP_FLASH,
587
  CP_KEYID,
588
  CP_TTL,
589
  CP_OFFSET,
590
  CP_DELAY,
591
  CP_DISPERSION,
592
  CP_JITTER,
593
  CP_XMT,
594
  CP_BIAS,
595
  CP_FILTDELAY,
596
  CP_FILTOFFSET,
597
  CP_FILTERROR,
598
#ifdef AUTOKEY
599
  CP_HOST,
600
  CP_FLAGS,
601
  CP_SIGNATURE,
602
  CP_VALID,
603
  CP_INITSEQ,
604
  CP_IDENT,
605
#endif  /* AUTOKEY */
606
  0
607
};
608
609
610
#ifdef REFCLOCK
611
/*
612
 * Clock variable list
613
 */
614
static const struct ctl_var clock_var[] = {
615
  { 0,    PADDING, "" },    /* 0 */
616
  { CC_TYPE,  RO, "type" },   /* 1 */
617
  { CC_TIMECODE,  RO, "timecode" }, /* 2 */
618
  { CC_POLL,  RO, "poll" },   /* 3 */
619
  { CC_NOREPLY, RO, "noreply" },  /* 4 */
620
  { CC_BADFORMAT, RO, "badformat" },  /* 5 */
621
  { CC_BADDATA, RO, "baddata" },  /* 6 */
622
  { CC_FUDGETIME1, RO, "fudgetime1" },  /* 7 */
623
  { CC_FUDGETIME2, RO, "fudgetime2" },  /* 8 */
624
  { CC_FUDGEVAL1, RO, "stratum" },  /* 9 */
625
  { CC_FUDGEVAL2, RO, "refid" },    /* 10 */
626
  { CC_FLAGS, RO, "flags" },    /* 11 */
627
  { CC_DEVICE,  RO, "device" },   /* 12 */
628
  { CC_VARLIST, RO, "clock_var_list" }, /* 13 */
629
  { CC_FUDGEMINJIT, RO, "minjitter" },  /* 14 */
630
  { 0,    EOV, ""  }    /* 15 */
631
};
632
633
634
/*
635
 * Clock variables printed by default
636
 */
637
static const u_char def_clock_var[] = {
638
  CC_DEVICE,
639
  CC_TYPE,  /* won't be output if device = known */
640
  CC_TIMECODE,
641
  CC_POLL,
642
  CC_NOREPLY,
643
  CC_BADFORMAT,
644
  CC_BADDATA,
645
  CC_FUDGEMINJIT,
646
  CC_FUDGETIME1,
647
  CC_FUDGETIME2,
648
  CC_FUDGEVAL1,
649
  CC_FUDGEVAL2,
650
  CC_FLAGS,
651
  0
652
};
653
#endif
654
655
/*
656
 * MRU string constants shared by send_mru_entry() and read_mru_list().
657
 */
658
static const char addr_fmt[] =    "addr.%d";
659
static const char last_fmt[] =    "last.%d";
660
661
/*
662
 * System and processor definitions.
663
 */
664
#ifndef HAVE_UNAME
665
# ifndef STR_SYSTEM
666
#  define   STR_SYSTEM  "UNIX"
667
# endif
668
# ifndef STR_PROCESSOR
669
#  define   STR_PROCESSOR "unknown"
670
# endif
671
672
static const char str_system[] = STR_SYSTEM;
673
static const char str_processor[] = STR_PROCESSOR;
674
#else
675
# include <sys/utsname.h>
676
static struct utsname utsnamebuf;
677
#endif /* HAVE_UNAME */
678
679
/*
680
 * Trap structures. We only allow a few of these, and send a copy of
681
 * each async message to each live one. Traps time out after an hour, it
682
 * is up to the trap receipient to keep resetting it to avoid being
683
 * timed out.
684
 */
685
/* ntp_request.c */
686
struct ctl_trap ctl_traps[CTL_MAXTRAPS];
687
int num_ctl_traps;
688
689
/*
690
 * Type bits, for ctlsettrap() call.
691
 */
692
0
#define TRAP_TYPE_CONFIG  0  /* used by configuration code */
693
0
#define TRAP_TYPE_PRIO    1  /* priority trap */
694
0
#define TRAP_TYPE_NONPRIO 2  /* nonpriority trap */
695
696
697
/*
698
 * List relating reference clock types to control message time sources.
699
 * Index by the reference clock type. This list will only be used iff
700
 * the reference clock driver doesn't set peer->sstclktype to something
701
 * different than CTL_SST_TS_UNSPEC.
702
 */
703
#ifdef REFCLOCK
704
static const u_char clocktypes[] = {
705
  CTL_SST_TS_NTP,   /* REFCLK_NONE (0) */
706
  CTL_SST_TS_LOCAL, /* REFCLK_LOCALCLOCK (1) */
707
  CTL_SST_TS_UHF,   /* deprecated REFCLK_GPS_TRAK (2) */
708
  CTL_SST_TS_HF,    /* REFCLK_WWV_PST (3) */
709
  CTL_SST_TS_LF,    /* REFCLK_WWVB_SPECTRACOM (4) */
710
  CTL_SST_TS_UHF,   /* REFCLK_TRUETIME (5) */
711
  CTL_SST_TS_UHF,   /* REFCLK_IRIG_AUDIO (6) */
712
  CTL_SST_TS_HF,    /* REFCLK_CHU (7) */
713
  CTL_SST_TS_LF,    /* REFCLOCK_PARSE (default) (8) */
714
  CTL_SST_TS_LF,    /* REFCLK_GPS_MX4200 (9) */
715
  CTL_SST_TS_UHF,   /* REFCLK_GPS_AS2201 (10) */
716
  CTL_SST_TS_UHF,   /* REFCLK_GPS_ARBITER (11) */
717
  CTL_SST_TS_UHF,   /* REFCLK_IRIG_TPRO (12) */
718
  CTL_SST_TS_ATOM,  /* REFCLK_ATOM_LEITCH (13) */
719
  CTL_SST_TS_LF,    /* deprecated REFCLK_MSF_EES (14) */
720
  CTL_SST_TS_NTP,   /* not used (15) */
721
  CTL_SST_TS_UHF,   /* REFCLK_IRIG_BANCOMM (16) */
722
  CTL_SST_TS_UHF,   /* REFCLK_GPS_DATU (17) */
723
  CTL_SST_TS_TELEPHONE, /* REFCLK_NIST_ACTS (18) */
724
  CTL_SST_TS_HF,    /* REFCLK_WWV_HEATH (19) */
725
  CTL_SST_TS_UHF,   /* REFCLK_GPS_NMEA (20) */
726
  CTL_SST_TS_UHF,   /* REFCLK_GPS_VME (21) */
727
  CTL_SST_TS_ATOM,  /* REFCLK_ATOM_PPS (22) */
728
  CTL_SST_TS_NTP,   /* not used (23) */
729
  CTL_SST_TS_NTP,   /* not used (24) */
730
  CTL_SST_TS_NTP,   /* not used (25) */
731
  CTL_SST_TS_UHF,   /* REFCLK_GPS_HP (26) */
732
  CTL_SST_TS_LF,    /* REFCLK_ARCRON_MSF (27) */
733
  CTL_SST_TS_UHF,   /* REFCLK_SHM (28) */
734
  CTL_SST_TS_UHF,   /* REFCLK_PALISADE (29) */
735
  CTL_SST_TS_UHF,   /* REFCLK_ONCORE (30) */
736
  CTL_SST_TS_UHF,   /* REFCLK_JUPITER (31) */
737
  CTL_SST_TS_LF,    /* REFCLK_CHRONOLOG (32) */
738
  CTL_SST_TS_LF,    /* REFCLK_DUMBCLOCK (33) */
739
  CTL_SST_TS_LF,    /* REFCLK_ULINK (34) */
740
  CTL_SST_TS_LF,    /* REFCLK_PCF (35) */
741
  CTL_SST_TS_HF,    /* REFCLK_WWV (36) */
742
  CTL_SST_TS_LF,    /* REFCLK_FG (37) */
743
  CTL_SST_TS_UHF,   /* REFCLK_HOPF_SERIAL (38) */
744
  CTL_SST_TS_UHF,   /* REFCLK_HOPF_PCI (39) */
745
  CTL_SST_TS_LF,    /* REFCLK_JJY (40) */
746
  CTL_SST_TS_UHF,   /* REFCLK_TT560 (41) */
747
  CTL_SST_TS_UHF,   /* REFCLK_ZYFER (42) */
748
  CTL_SST_TS_UHF,   /* REFCLK_RIPENCC (43) */
749
  CTL_SST_TS_UHF,   /* REFCLK_NEOCLOCK4X (44) */
750
  CTL_SST_TS_UHF,   /* REFCLK_TSYNCPCI (45) */
751
  CTL_SST_TS_UHF    /* REFCLK_GPSDJSON (46) */
752
};
753
#endif  /* REFCLOCK */
754
755
756
/*
757
 * Keyid used for authenticating write requests.
758
 */
759
keyid_t ctl_auth_keyid;
760
761
/*
762
 * We keep track of the last error reported by the system internally
763
 */
764
static  u_char ctl_sys_last_event;
765
static  u_char ctl_sys_num_events;
766
767
768
/*
769
 * Statistic counters to keep track of requests and responses.
770
 */
771
u_long ctltimereset;    /* time stats reset */
772
u_long numctlreq;   /* number of requests we've received */
773
u_long numctlbadpkts;   /* number of bad control packets */
774
u_long numctlresponses;   /* number of resp packets sent with data */
775
u_long numctlfrags;   /* number of fragments sent */
776
u_long numctlerrors;    /* number of error responses sent */
777
u_long numctltooshort;    /* number of too short input packets */
778
u_long numctlinputresp;   /* number of responses on input */
779
u_long numctlinputfrag;   /* number of fragments on input */
780
u_long numctlinputerr;    /* number of input pkts with err bit set */
781
u_long numctlbadoffset;   /* number of input pkts with nonzero offset */
782
u_long numctlbadversion;  /* number of input pkts with unknown version */
783
u_long numctldatatooshort;  /* data too short for count */
784
u_long numctlbadop;   /* bad op code found in packet */
785
u_long numasyncmsgs;    /* number of async messages we've sent */
786
787
/*
788
 * Response packet used by these routines. Also some state information
789
 * so that we can handle packet formatting within a common set of
790
 * subroutines.  Note we try to enter data in place whenever possible,
791
 * but the need to set the more bit correctly means we occasionally
792
 * use the extra buffer and copy.
793
 */
794
static struct ntp_control rpkt;
795
static u_char res_version;
796
static u_char res_opcode;
797
static associd_t res_associd;
798
static u_short  res_frags;  /* datagrams in this response */
799
static int  res_offset; /* offset of payload in response */
800
static u_char * datapt;
801
static u_char * dataend;
802
static int  datalinelen;
803
static int  datasent; /* flag to avoid initial ", " */
804
static int  datanotbinflag;
805
static sockaddr_u *rmt_addr;
806
static endpt *lcl_inter;
807
808
static u_char res_authenticate;
809
static u_char res_authokay;
810
static keyid_t  res_keyid;
811
812
0
#define MAXDATALINELEN  (72)
813
814
static u_char res_async;  /* sending async trap response? */
815
816
/*
817
 * Pointers for saving state when decoding request packets
818
 */
819
static  char *reqpt;
820
static  char *reqend;
821
822
/*
823
 * init_control - initialize request data
824
 */
825
void
826
init_control(void)
827
1
{
828
1
  size_t i;
829
830
1
#ifdef HAVE_UNAME
831
1
  uname(&utsnamebuf);
832
1
#endif /* HAVE_UNAME */
833
834
1
  ctl_clr_stats();
835
836
1
  ctl_auth_keyid = 0;
837
1
  ctl_sys_last_event = EVNT_UNSPEC;
838
1
  ctl_sys_num_events = 0;
839
840
1
  num_ctl_traps = 0;
841
4
  for (i = 0; i < COUNTOF(ctl_traps); i++)
842
3
    ctl_traps[i].tr_flags = 0;
843
1
}
844
845
846
/*
847
 * ctl_error - send an error response for the current request
848
 */
849
static void
850
ctl_error(
851
  u_char errcode
852
  )
853
0
{
854
0
  size_t    maclen;
855
856
0
  numctlerrors++;
857
0
  DPRINTF(3, ("sending control error %u\n", errcode));
858
859
  /*
860
   * Fill in the fields. We assume rpkt.sequence and rpkt.associd
861
   * have already been filled in.
862
   */
863
0
  rpkt.r_m_e_op = (u_char)CTL_RESPONSE | CTL_ERROR |
864
0
      (res_opcode & CTL_OP_MASK);
865
0
  rpkt.status = htons((u_short)(errcode << 8) & 0xff00);
866
0
  rpkt.count = 0;
867
868
  /*
869
   * send packet and bump counters
870
   */
871
0
  if (res_authenticate && sys_authenticate) {
872
0
    maclen = authencrypt(res_keyid, (u_int32 *)&rpkt,
873
0
             CTL_HEADER_LEN);
874
0
    sendpkt(rmt_addr, lcl_inter, -2, (void *)&rpkt,
875
0
      CTL_HEADER_LEN + maclen);
876
0
  } else
877
0
    sendpkt(rmt_addr, lcl_inter, -3, (void *)&rpkt,
878
0
      CTL_HEADER_LEN);
879
0
}
880
881
int/*BOOL*/
882
is_safe_filename(const char * name)
883
0
{
884
  /* We need a strict validation of filenames we should write: The
885
   * daemon might run with special permissions and is remote
886
   * controllable, so we better take care what we allow as file
887
   * name!
888
   *
889
   * The first character must be digit or a letter from the ASCII
890
   * base plane or a '_' ([_A-Za-z0-9]), the following characters
891
   * must be from [-._+A-Za-z0-9].
892
   *
893
   * We do not trust the character classification much here: Since
894
   * the NTP protocol makes no provisions for UTF-8 or local code
895
   * pages, we strictly require the 7bit ASCII code page.
896
   *
897
   * The following table is a packed bit field of 128 two-bit
898
   * groups. The LSB in each group tells us if a character is
899
   * acceptable at the first position, the MSB if the character is
900
   * accepted at any other position.
901
   *
902
   * This does not ensure that the file name is syntactically
903
   * correct (multiple dots will not work with VMS...) but it will
904
   * exclude potential globbing bombs and directory traversal. It
905
   * also rules out drive selection. (For systems that have this
906
   * notion, like Windows or VMS.)
907
   */
908
0
  static const uint32_t chclass[8] = {
909
0
    0x00000000, 0x00000000,
910
0
    0x28800000, 0x000FFFFF,
911
0
    0xFFFFFFFC, 0xC03FFFFF,
912
0
    0xFFFFFFFC, 0x003FFFFF
913
0
  };
914
915
0
  u_int widx, bidx, mask;
916
0
  if ( ! (name && *name))
917
0
    return FALSE;
918
919
0
  mask = 1u;
920
0
  while (0 != (widx = (u_char)*name++)) {
921
0
    bidx = (widx & 15) << 1;
922
0
    widx = widx >> 4;
923
0
    if (widx >= sizeof(chclass)/sizeof(chclass[0]))
924
0
      return FALSE;
925
0
    if (0 == ((chclass[widx] >> bidx) & mask))
926
0
      return FALSE;
927
0
    mask = 2u;
928
0
  }
929
0
  return TRUE;
930
0
}
931
932
933
/*
934
 * save_config - Implements ntpq -c "saveconfig <filename>"
935
 *     Writes current configuration including any runtime
936
 *     changes by ntpq's :config or config-from-file
937
 *
938
 * Note: There should be no buffer overflow or truncation in the
939
 * processing of file names -- both cause security problems. This is bit
940
 * painful to code but essential here.
941
 */
942
void
943
save_config(
944
  struct recvbuf *rbufp,
945
  int restrict_mask
946
  )
947
0
{
948
  /* block directory traversal by searching for characters that
949
   * indicate directory components in a file path.
950
   *
951
   * Conceptually we should be searching for DIRSEP in filename,
952
   * however Windows actually recognizes both forward and
953
   * backslashes as equivalent directory separators at the API
954
   * level.  On POSIX systems we could allow '\\' but such
955
   * filenames are tricky to manipulate from a shell, so just
956
   * reject both types of slashes on all platforms.
957
   */
958
  /* TALOS-CAN-0062: block directory traversal for VMS, too */
959
0
  static const char * illegal_in_filename =
960
#if defined(VMS)
961
      ":[]" /* do not allow drive and path components here */
962
#elif defined(SYS_WINNT)
963
      ":\\/"  /* path and drive separators */
964
#else
965
0
      "\\/" /* separator and critical char for POSIX */
966
0
#endif
967
0
      ;
968
0
  char reply[128];
969
0
#ifdef SAVECONFIG
970
0
  static const char savedconfig_eq[] = "savedconfig=";
971
972
  /* Build a safe open mode from the available mode flags. We want
973
   * to create a new file and write it in text mode (when
974
   * applicable -- only Windows does this...)
975
   */
976
0
  static const int openmode = O_CREAT | O_TRUNC | O_WRONLY
977
0
#  if defined(O_EXCL)   /* posix, vms */
978
0
      | O_EXCL
979
#  elif defined(_O_EXCL)  /* windows is alway very special... */
980
      | _O_EXCL
981
#  endif
982
#  if defined(_O_TEXT)    /* windows, again */
983
      | _O_TEXT
984
#endif
985
0
      ;
986
987
0
  char filespec[128];
988
0
  char filename[128];
989
0
  char fullpath[512];
990
0
  char savedconfig[sizeof(savedconfig_eq) + sizeof(filename)];
991
0
  time_t now;
992
0
  int fd;
993
0
  FILE *fptr;
994
0
  int prc;
995
0
  size_t reqlen;
996
0
#endif
997
998
0
  if (RES_NOMODIFY & restrict_mask) {
999
0
    ctl_printf("%s", "saveconfig prohibited by restrict ... nomodify");
1000
0
    ctl_flushpkt(0);
1001
0
    NLOG(NLOG_SYSINFO)
1002
0
      msyslog(LOG_NOTICE,
1003
0
        "saveconfig from %s rejected due to nomodify restriction",
1004
0
        stoa(&rbufp->recv_srcadr));
1005
0
    sys_restricted++;
1006
0
    return;
1007
0
  }
1008
1009
0
#ifdef SAVECONFIG
1010
0
  if (NULL == saveconfigdir) {
1011
0
    ctl_printf("%s", "saveconfig prohibited, no saveconfigdir configured");
1012
0
    ctl_flushpkt(0);
1013
0
    NLOG(NLOG_SYSINFO)
1014
0
      msyslog(LOG_NOTICE,
1015
0
        "saveconfig from %s rejected, no saveconfigdir",
1016
0
        stoa(&rbufp->recv_srcadr));
1017
0
    return;
1018
0
  }
1019
1020
  /* The length checking stuff gets serious. Do not assume a NUL
1021
   * byte can be found, but if so, use it to calculate the needed
1022
   * buffer size. If the available buffer is too short, bail out;
1023
   * likewise if there is no file spec. (The latter will not
1024
   * happen when using NTPQ, but there are other ways to craft a
1025
   * network packet!)
1026
   */
1027
0
  reqlen = (size_t)(reqend - reqpt);
1028
0
  if (0 != reqlen) {
1029
0
    char * nulpos = (char*)memchr(reqpt, 0, reqlen);
1030
0
    if (NULL != nulpos)
1031
0
      reqlen = (size_t)(nulpos - reqpt);
1032
0
  }
1033
0
  if (0 == reqlen)
1034
0
    return;
1035
0
  if (reqlen >= sizeof(filespec)) {
1036
0
    ctl_printf("saveconfig exceeded maximum raw name length (%u)",
1037
0
         (u_int)sizeof(filespec));
1038
0
    ctl_flushpkt(0);
1039
0
    msyslog(LOG_NOTICE,
1040
0
      "saveconfig exceeded maximum raw name length from %s",
1041
0
      stoa(&rbufp->recv_srcadr));
1042
0
    return;
1043
0
  }
1044
1045
  /* copy data directly as we exactly know the size */
1046
0
  memcpy(filespec, reqpt, reqlen);
1047
0
  filespec[reqlen] = '\0';
1048
1049
  /*
1050
   * allow timestamping of the saved config filename with
1051
   * strftime() format such as:
1052
   *   ntpq -c "saveconfig ntp-%Y%m%d-%H%M%S.conf"
1053
   * XXX: Nice feature, but not too safe.
1054
   * YYY: The check for permitted characters in file names should
1055
   *      weed out the worst. Let's hope 'strftime()' does not
1056
   *      develop pathological problems.
1057
   */
1058
0
  time(&now);
1059
0
  if (0 == strftime(filename, sizeof(filename), filespec,
1060
0
        localtime(&now)))
1061
0
  {
1062
    /*
1063
     * If we arrive here, 'strftime()' balked; most likely
1064
     * the buffer was too short. (Or it encounterd an empty
1065
     * format, or just a format that expands to an empty
1066
     * string.) We try to use the original name, though this
1067
     * is very likely to fail later if there are format
1068
     * specs in the string. Note that truncation cannot
1069
     * happen here as long as both buffers have the same
1070
     * size!
1071
     */
1072
0
    strlcpy(filename, filespec, sizeof(filename));
1073
0
  }
1074
1075
  /*
1076
   * Check the file name for sanity. This might/will rule out file
1077
   * names that would be legal but problematic, and it blocks
1078
   * directory traversal.
1079
   */
1080
0
  if (!is_safe_filename(filename)) {
1081
0
    ctl_printf("saveconfig rejects unsafe file name '%s'",
1082
0
         filename);
1083
0
    ctl_flushpkt(0);
1084
0
    msyslog(LOG_NOTICE,
1085
0
      "saveconfig rejects unsafe file name from %s",
1086
0
      stoa(&rbufp->recv_srcadr));
1087
0
    return;
1088
0
  }
1089
1090
  /*
1091
   * XXX: This next test may not be needed with is_safe_filename()
1092
   */
1093
1094
  /* block directory/drive traversal */
1095
  /* TALOS-CAN-0062: block directory traversal for VMS, too */
1096
0
  if (NULL != strpbrk(filename, illegal_in_filename)) {
1097
0
    snprintf(reply, sizeof(reply),
1098
0
       "saveconfig does not allow directory in filename");
1099
0
    ctl_putdata(reply, strlen(reply), 0);
1100
0
    ctl_flushpkt(0);
1101
0
    msyslog(LOG_NOTICE,
1102
0
      "saveconfig rejects unsafe file name from %s",
1103
0
      stoa(&rbufp->recv_srcadr));
1104
0
    return;
1105
0
  }
1106
1107
  /* concatenation of directory and path can cause another
1108
   * truncation...
1109
   */
1110
0
  prc = snprintf(fullpath, sizeof(fullpath), "%s%s",
1111
0
           saveconfigdir, filename);
1112
0
  if (prc < 0 || (size_t)prc >= sizeof(fullpath)) {
1113
0
    ctl_printf("saveconfig exceeded maximum path length (%u)",
1114
0
         (u_int)sizeof(fullpath));
1115
0
    ctl_flushpkt(0);
1116
0
    msyslog(LOG_NOTICE,
1117
0
      "saveconfig exceeded maximum path length from %s",
1118
0
      stoa(&rbufp->recv_srcadr));
1119
0
    return;
1120
0
  }
1121
1122
0
  fd = open(fullpath, openmode, S_IRUSR | S_IWUSR);
1123
0
  if (-1 == fd)
1124
0
    fptr = NULL;
1125
0
  else
1126
0
    fptr = fdopen(fd, "w");
1127
1128
0
  if (NULL == fptr || -1 == dump_all_config_trees(fptr, 1)) {
1129
0
    ctl_printf("Unable to save configuration to file '%s': %s",
1130
0
         filename, strerror(errno));
1131
0
    msyslog(LOG_ERR,
1132
0
      "saveconfig %s from %s failed", filename,
1133
0
      stoa(&rbufp->recv_srcadr));
1134
0
  } else {
1135
0
    ctl_printf("Configuration saved to '%s'", filename);
1136
0
    msyslog(LOG_NOTICE,
1137
0
      "Configuration saved to '%s' (requested by %s)",
1138
0
      fullpath, stoa(&rbufp->recv_srcadr));
1139
    /*
1140
     * save the output filename in system variable
1141
     * savedconfig, retrieved with:
1142
     *   ntpq -c "rv 0 savedconfig"
1143
     * Note: the way 'savedconfig' is defined makes overflow
1144
     * checks unnecessary here.
1145
     */
1146
0
    snprintf(savedconfig, sizeof(savedconfig), "%s%s",
1147
0
       savedconfig_eq, filename);
1148
0
    set_sys_var(savedconfig, strlen(savedconfig) + 1, RO);
1149
0
  }
1150
1151
0
  if (NULL != fptr)
1152
0
    fclose(fptr);
1153
#else /* !SAVECONFIG follows */
1154
  ctl_printf("%s",
1155
       "saveconfig unavailable, configured with --disable-saveconfig");
1156
#endif
1157
0
  ctl_flushpkt(0);
1158
0
}
1159
1160
1161
/*
1162
 * process_control - process an incoming control message
1163
 */
1164
void
1165
process_control(
1166
  struct recvbuf *rbufp,
1167
  int restrict_mask
1168
  )
1169
0
{
1170
0
  struct ntp_control *pkt;
1171
0
  int req_count;
1172
0
  int req_data;
1173
0
  const struct ctl_proc *cc;
1174
0
  keyid_t *pkid;
1175
0
  int properlen;
1176
0
  size_t maclen;
1177
1178
0
  DPRINTF(3, ("in process_control()\n"));
1179
1180
  /*
1181
   * Save the addresses for error responses
1182
   */
1183
0
  numctlreq++;
1184
0
  rmt_addr = &rbufp->recv_srcadr;
1185
0
  lcl_inter = rbufp->dstadr;
1186
0
  pkt = (struct ntp_control *)&rbufp->recv_pkt;
1187
1188
  /*
1189
   * If the length is less than required for the header,
1190
   * ignore it.
1191
   */
1192
0
  if (rbufp->recv_length < (int)CTL_HEADER_LEN) {
1193
0
    DPRINTF(1, ("Short control packet\n"));
1194
0
    numctltooshort++;
1195
0
    return;
1196
0
  }
1197
1198
  /*
1199
   * If this packet is a response or a fragment, ignore it.
1200
   */
1201
0
  if (   (CTL_RESPONSE | CTL_MORE | CTL_ERROR) & pkt->r_m_e_op
1202
0
      || pkt->offset != 0) {
1203
0
    DPRINTF(1, ("invalid format in control packet\n"));
1204
0
    if (CTL_RESPONSE & pkt->r_m_e_op)
1205
0
      numctlinputresp++;
1206
0
    if (CTL_MORE & pkt->r_m_e_op)
1207
0
      numctlinputfrag++;
1208
0
    if (CTL_ERROR & pkt->r_m_e_op)
1209
0
      numctlinputerr++;
1210
0
    if (pkt->offset != 0)
1211
0
      numctlbadoffset++;
1212
0
    return;
1213
0
  }
1214
1215
0
  res_version = PKT_VERSION(pkt->li_vn_mode);
1216
0
  if (res_version > NTP_VERSION || res_version < NTP_OLDVERSION) {
1217
0
    DPRINTF(1, ("unknown version %d in control packet\n",
1218
0
          res_version));
1219
0
    numctlbadversion++;
1220
0
    return;
1221
0
  }
1222
1223
  /*
1224
   * Pull enough data from the packet to make intelligent
1225
   * responses
1226
   */
1227
0
  rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, res_version,
1228
0
           MODE_CONTROL);
1229
0
  res_opcode = pkt->r_m_e_op;
1230
0
  rpkt.sequence = pkt->sequence;
1231
0
  rpkt.associd = pkt->associd;
1232
0
  rpkt.status = 0;
1233
0
  res_frags = 1;
1234
0
  res_offset = 0;
1235
0
  res_associd = htons(pkt->associd);
1236
0
  res_async = FALSE;
1237
0
  res_authenticate = FALSE;
1238
0
  res_keyid = 0;
1239
0
  res_authokay = FALSE;
1240
0
  req_count = (int)ntohs(pkt->count);
1241
0
  datanotbinflag = FALSE;
1242
0
  datalinelen = 0;
1243
0
  datasent = 0;
1244
0
  datapt = rpkt.u.data;
1245
0
  dataend = &rpkt.u.data[CTL_MAX_DATA_LEN];
1246
1247
0
  if ((rbufp->recv_length & 0x3) != 0)
1248
0
    DPRINTF(3, ("Control packet length %d unrounded\n",
1249
0
          rbufp->recv_length));
1250
1251
  /*
1252
   * We're set up now. Make sure we've got at least enough
1253
   * incoming data space to match the count.
1254
   */
1255
0
  req_data = rbufp->recv_length - CTL_HEADER_LEN;
1256
0
  if (req_data < req_count || rbufp->recv_length & 0x3) {
1257
0
    ctl_error(CERR_BADFMT);
1258
0
    numctldatatooshort++;
1259
0
    return;
1260
0
  }
1261
1262
0
  properlen = req_count + CTL_HEADER_LEN;
1263
  /* round up proper len to a 8 octet boundary */
1264
1265
0
  properlen = (properlen + 7) & ~7;
1266
0
  maclen = rbufp->recv_length - properlen;
1267
0
  if ((rbufp->recv_length & 3) == 0 &&
1268
0
      maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN &&
1269
0
      sys_authenticate) {
1270
0
    res_authenticate = TRUE;
1271
0
    pkid = (void *)((char *)pkt + properlen);
1272
0
    res_keyid = ntohl(*pkid);
1273
0
    DPRINTF(3, ("recv_len %d, properlen %d, wants auth with keyid %08x, MAC length=%zu\n",
1274
0
          rbufp->recv_length, properlen, res_keyid,
1275
0
          maclen));
1276
1277
0
    if (!authistrustedip(res_keyid, &rbufp->recv_srcadr))
1278
0
      DPRINTF(3, ("invalid keyid %08x\n", res_keyid));
1279
0
    else if (authdecrypt(res_keyid, (u_int32 *)pkt,
1280
0
             rbufp->recv_length - maclen,
1281
0
             maclen)) {
1282
0
      res_authokay = TRUE;
1283
0
      DPRINTF(3, ("authenticated okay\n"));
1284
0
    } else {
1285
0
      res_keyid = 0;
1286
0
      DPRINTF(3, ("authentication failed\n"));
1287
0
    }
1288
0
  }
1289
1290
  /*
1291
   * Set up translate pointers
1292
   */
1293
0
  reqpt = (char *)pkt->u.data;
1294
0
  reqend = reqpt + req_count;
1295
1296
  /*
1297
   * Look for the opcode processor
1298
   */
1299
0
  for (cc = control_codes; cc->control_code != NO_REQUEST; cc++) {
1300
0
    if (cc->control_code == res_opcode) {
1301
0
      DPRINTF(3, ("opcode %d, found command handler\n",
1302
0
            res_opcode));
1303
0
      if (cc->flags == AUTH
1304
0
          && (!res_authokay
1305
0
        || res_keyid != ctl_auth_keyid)) {
1306
0
        ctl_error(CERR_PERMISSION);
1307
0
        return;
1308
0
      }
1309
0
      (cc->handler)(rbufp, restrict_mask);
1310
0
      return;
1311
0
    }
1312
0
  }
1313
1314
  /*
1315
   * Can't find this one, return an error.
1316
   */
1317
0
  numctlbadop++;
1318
0
  ctl_error(CERR_BADOP);
1319
0
  return;
1320
0
}
1321
1322
1323
/*
1324
 * ctlpeerstatus - return a status word for this peer
1325
 */
1326
u_short
1327
ctlpeerstatus(
1328
  register struct peer *p
1329
  )
1330
0
{
1331
0
  u_short status;
1332
1333
0
  status = p->status;
1334
0
  if (FLAG_CONFIG & p->flags)
1335
0
    status |= CTL_PST_CONFIG;
1336
0
  if (p->keyid)
1337
0
    status |= CTL_PST_AUTHENABLE;
1338
0
  if (FLAG_AUTHENTIC & p->flags)
1339
0
    status |= CTL_PST_AUTHENTIC;
1340
0
  if (p->reach)
1341
0
    status |= CTL_PST_REACH;
1342
0
  if (MDF_TXONLY_MASK & p->cast_flags)
1343
0
    status |= CTL_PST_BCAST;
1344
1345
0
  return CTL_PEER_STATUS(status, p->num_events, p->last_event);
1346
0
}
1347
1348
1349
/*
1350
 * ctlclkstatus - return a status word for this clock
1351
 */
1352
#ifdef REFCLOCK
1353
static u_short
1354
ctlclkstatus(
1355
  struct refclockstat *pcs
1356
  )
1357
0
{
1358
0
  return CTL_PEER_STATUS(0, pcs->lastevent, pcs->currentstatus);
1359
0
}
1360
#endif
1361
1362
1363
/*
1364
 * ctlsysstatus - return the system status word
1365
 */
1366
u_short
1367
ctlsysstatus(void)
1368
0
{
1369
0
  register u_char this_clock;
1370
1371
0
  this_clock = CTL_SST_TS_UNSPEC;
1372
0
#ifdef REFCLOCK
1373
0
  if (sys_peer != NULL) {
1374
0
    if (CTL_SST_TS_UNSPEC != sys_peer->sstclktype)
1375
0
      this_clock = sys_peer->sstclktype;
1376
0
    else if (sys_peer->refclktype < COUNTOF(clocktypes))
1377
0
      this_clock = clocktypes[sys_peer->refclktype];
1378
0
  }
1379
#else /* REFCLOCK */
1380
  if (sys_peer != 0)
1381
    this_clock = CTL_SST_TS_NTP;
1382
#endif /* REFCLOCK */
1383
0
  return CTL_SYS_STATUS(sys_leap, this_clock, ctl_sys_num_events,
1384
0
            ctl_sys_last_event);
1385
0
}
1386
1387
1388
/*
1389
 * ctl_flushpkt - write out the current packet and prepare
1390
 *      another if necessary.
1391
 */
1392
static void
1393
ctl_flushpkt(
1394
  u_char more
1395
  )
1396
0
{
1397
0
  size_t i;
1398
0
  size_t dlen;
1399
0
  size_t sendlen;
1400
0
  size_t maclen;
1401
0
  size_t totlen;
1402
0
  keyid_t keyid;
1403
1404
0
  dlen = datapt - rpkt.u.data;
1405
0
  if (!more && datanotbinflag && dlen + 2 < CTL_MAX_DATA_LEN) {
1406
    /*
1407
     * Big hack, output a trailing \r\n
1408
     */
1409
0
    *datapt++ = '\r';
1410
0
    *datapt++ = '\n';
1411
0
    dlen += 2;
1412
0
  }
1413
0
  sendlen = dlen + CTL_HEADER_LEN;
1414
1415
  /*
1416
   * Pad to a multiple of 32 bits
1417
   */
1418
0
  while (sendlen & 0x3) {
1419
0
    *datapt++ = '\0';
1420
0
    sendlen++;
1421
0
  }
1422
1423
  /*
1424
   * Fill in the packet with the current info
1425
   */
1426
0
  rpkt.r_m_e_op = CTL_RESPONSE | more |
1427
0
      (res_opcode & CTL_OP_MASK);
1428
0
  rpkt.count = htons((u_short)dlen);
1429
0
  rpkt.offset = htons((u_short)res_offset);
1430
0
  if (res_async) {
1431
0
    for (i = 0; i < COUNTOF(ctl_traps); i++) {
1432
0
      if (TRAP_INUSE & ctl_traps[i].tr_flags) {
1433
0
        rpkt.li_vn_mode =
1434
0
            PKT_LI_VN_MODE(
1435
0
          sys_leap,
1436
0
          ctl_traps[i].tr_version,
1437
0
          MODE_CONTROL);
1438
0
        rpkt.sequence =
1439
0
            htons(ctl_traps[i].tr_sequence);
1440
0
        sendpkt(&ctl_traps[i].tr_addr,
1441
0
          ctl_traps[i].tr_localaddr, -4,
1442
0
          (struct pkt *)&rpkt, sendlen);
1443
0
        if (!more)
1444
0
          ctl_traps[i].tr_sequence++;
1445
0
        numasyncmsgs++;
1446
0
      }
1447
0
    }
1448
0
  } else {
1449
0
    if (res_authenticate && sys_authenticate) {
1450
0
      totlen = sendlen;
1451
      /*
1452
       * If we are going to authenticate, then there
1453
       * is an additional requirement that the MAC
1454
       * begin on a 64 bit boundary.
1455
       */
1456
0
      while (totlen & 7) {
1457
0
        *datapt++ = '\0';
1458
0
        totlen++;
1459
0
      }
1460
0
      keyid = htonl(res_keyid);
1461
0
      memcpy(datapt, &keyid, sizeof(keyid));
1462
0
      maclen = authencrypt(res_keyid,
1463
0
               (u_int32 *)&rpkt, totlen);
1464
0
      sendpkt(rmt_addr, lcl_inter, -5,
1465
0
        (struct pkt *)&rpkt, totlen + maclen);
1466
0
    } else {
1467
0
      sendpkt(rmt_addr, lcl_inter, -6,
1468
0
        (struct pkt *)&rpkt, sendlen);
1469
0
    }
1470
0
    if (more)
1471
0
      numctlfrags++;
1472
0
    else
1473
0
      numctlresponses++;
1474
0
  }
1475
1476
  /*
1477
   * Set us up for another go around.
1478
   */
1479
0
  res_frags++;
1480
0
  res_offset += dlen;
1481
0
  datapt = rpkt.u.data;
1482
0
}
1483
1484
1485
/* --------------------------------------------------------------------
1486
 * block transfer API -- stream string/data fragments into xmit buffer
1487
 * without additional copying
1488
 */
1489
1490
/* buffer descriptor: address & size of fragment
1491
 * 'buf' may only be NULL when 'len' is zero!
1492
 */
1493
typedef struct {
1494
  const void  *buf;
1495
  size_t       len;
1496
} CtlMemBufT;
1497
1498
/* put ctl data in a gather-style operation */
1499
static void
1500
ctl_putdata_ex(
1501
  const CtlMemBufT * argv,
1502
  size_t             argc,
1503
  int/*BOOL*/        bin    /* set to 1 when data is binary */
1504
  )
1505
0
{
1506
0
  const char * src_ptr;
1507
0
  size_t       src_len, cur_len, add_len, argi;
1508
1509
  /* text / binary preprocessing, possibly create new linefeed */
1510
0
  if (bin) {
1511
0
    add_len = 0;
1512
0
  } else {
1513
0
    datanotbinflag = TRUE;
1514
0
    add_len = 3;
1515
1516
0
    if (datasent) {
1517
0
      *datapt++ = ',';
1518
0
      datalinelen++;
1519
1520
      /* sum up total length */
1521
0
      for (argi = 0, src_len = 0; argi < argc; ++argi)
1522
0
        src_len += argv[argi].len;
1523
      /* possibly start a new line, assume no size_t overflow */
1524
0
      if ((src_len + datalinelen + 1) >= MAXDATALINELEN) {
1525
0
        *datapt++ = '\r';
1526
0
        *datapt++ = '\n';
1527
0
        datalinelen = 0;
1528
0
      } else {
1529
0
        *datapt++ = ' ';
1530
0
        datalinelen++;
1531
0
      }
1532
0
    }
1533
0
  }
1534
1535
  /* now stream out all buffers */
1536
0
  for (argi = 0; argi < argc; ++argi) {
1537
0
    src_ptr = argv[argi].buf;
1538
0
    src_len = argv[argi].len;
1539
1540
0
    if ( ! (src_ptr && src_len))
1541
0
      continue;
1542
1543
0
    cur_len = (size_t)(dataend - datapt);
1544
0
    while ((src_len + add_len) > cur_len) {
1545
      /* Not enough room in this one, flush it out. */
1546
0
      if (src_len < cur_len)
1547
0
        cur_len = src_len;
1548
1549
0
      memcpy(datapt, src_ptr, cur_len);
1550
0
      datapt      += cur_len;
1551
0
      datalinelen += cur_len;
1552
1553
0
      src_ptr     += cur_len;
1554
0
      src_len     -= cur_len;
1555
1556
0
      ctl_flushpkt(CTL_MORE);
1557
0
      cur_len = (size_t)(dataend - datapt);
1558
0
    }
1559
1560
0
    memcpy(datapt, src_ptr, src_len);
1561
0
    datapt      += src_len;
1562
0
    datalinelen += src_len;
1563
1564
0
    datasent = TRUE;
1565
0
  }
1566
0
}
1567
1568
/*
1569
 * ctl_putdata - write data into the packet, fragmenting and starting
1570
 * another if this one is full.
1571
 */
1572
static void
1573
ctl_putdata(
1574
  const char *dp,
1575
  unsigned int dlen,
1576
  int bin     /* set to 1 when data is binary */
1577
  )
1578
0
{
1579
0
  CtlMemBufT args[1];
1580
1581
0
  args[0].buf = dp;
1582
0
  args[0].len = dlen;
1583
0
  ctl_putdata_ex(args, 1, bin);
1584
0
}
1585
1586
/*
1587
 * ctl_putstr - write a tagged string into the response packet
1588
 *    in the form:
1589
 *
1590
 *    tag="data"
1591
 *
1592
 *    len is the data length excluding the NUL terminator,
1593
 *    as in ctl_putstr("var", "value", strlen("value"));
1594
 */
1595
static void
1596
ctl_putstr(
1597
  const char *  tag,
1598
  const char *  data,
1599
  size_t    len
1600
  )
1601
0
{
1602
0
  CtlMemBufT args[4];
1603
1604
0
  args[0].buf = tag;
1605
0
  args[0].len = strlen(tag);
1606
0
  if (data && len) {
1607
0
      args[1].buf = "=\"";
1608
0
      args[1].len = 2;
1609
0
      args[2].buf = data;
1610
0
      args[2].len = len;
1611
0
      args[3].buf = "\"";
1612
0
      args[3].len = 1;
1613
0
      ctl_putdata_ex(args, 4, FALSE);
1614
0
  } else {
1615
0
      args[1].buf = "=\"\"";
1616
0
      args[1].len = 3;
1617
0
      ctl_putdata_ex(args, 2, FALSE);
1618
0
  }
1619
0
}
1620
1621
1622
/*
1623
 * ctl_putunqstr - write a tagged string into the response packet
1624
 *       in the form:
1625
 *
1626
 *       tag=data
1627
 *
1628
 *  len is the data length excluding the NUL terminator.
1629
 *  data must not contain a comma or whitespace.
1630
 */
1631
static void
1632
ctl_putunqstr(
1633
  const char *  tag,
1634
  const char *  data,
1635
  size_t    len
1636
  )
1637
0
{
1638
0
  CtlMemBufT args[3];
1639
1640
0
  args[0].buf = tag;
1641
0
  args[0].len = strlen(tag);
1642
0
  args[1].buf = "=";
1643
0
  args[1].len = 1;
1644
0
  if (data && len) {
1645
0
    args[2].buf = data;
1646
0
    args[2].len = len;
1647
0
    ctl_putdata_ex(args, 3, FALSE);
1648
0
  } else {
1649
0
    ctl_putdata_ex(args, 2, FALSE);
1650
0
  }
1651
0
}
1652
1653
1654
/*
1655
 * ctl_putdblf - write a tagged, signed double into the response packet
1656
 */
1657
static void
1658
ctl_putdblf(
1659
  const char *  tag,
1660
  int   use_f,
1661
  int   precision,
1662
  double    d
1663
  )
1664
0
{
1665
0
  char buffer[40];
1666
0
  int  rc;
1667
1668
0
  rc = snprintf(buffer, sizeof(buffer),
1669
0
          (use_f ? "%.*f" : "%.*g"),
1670
0
          precision, d);
1671
0
  INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
1672
0
  ctl_putunqstr(tag, buffer, rc);
1673
0
}
1674
1675
/*
1676
 * ctl_putuint - write a tagged unsigned integer into the response
1677
 */
1678
static void
1679
ctl_putuint(
1680
  const char *tag,
1681
  u_long uval
1682
  )
1683
0
{
1684
0
  char buffer[24]; /* needs to fit for 64 bits! */
1685
0
  int  rc;
1686
1687
0
  rc = snprintf(buffer, sizeof(buffer), "%lu", uval);
1688
0
  INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
1689
0
  ctl_putunqstr(tag, buffer, rc);
1690
0
}
1691
1692
/*
1693
 * ctl_putcal - write a decoded calendar data into the response.
1694
 * only used with AUTOKEY currently, so compiled conditional
1695
 */
1696
#ifdef AUTOKEY
1697
static void
1698
ctl_putcal(
1699
  const char *tag,
1700
  const struct calendar *pcal
1701
  )
1702
0
{
1703
0
  char buffer[16];
1704
0
  int  rc;
1705
1706
0
  rc = snprintf(buffer, sizeof(buffer),
1707
0
          "%04d%02d%02d%02d%02d",
1708
0
          pcal->year, pcal->month, pcal->monthday,
1709
0
          pcal->hour, pcal->minute
1710
0
    );
1711
0
  INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
1712
0
  ctl_putunqstr(tag, buffer, rc);
1713
0
}
1714
#endif
1715
1716
/*
1717
 * ctl_putfs - write a decoded filestamp into the response
1718
 */
1719
static void
1720
ctl_putfs(
1721
  const char *tag,
1722
  tstamp_t uval
1723
  )
1724
0
{
1725
0
  char buffer[16];
1726
0
  int  rc;
1727
1728
0
  time_t fstamp = (time_t)uval - JAN_1970;
1729
0
  struct tm *tm = gmtime(&fstamp);
1730
1731
0
  if (NULL == tm)
1732
0
    return;
1733
1734
0
  rc = snprintf(buffer, sizeof(buffer),
1735
0
          "%04d%02d%02d%02d%02d",
1736
0
          tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
1737
0
          tm->tm_hour, tm->tm_min);
1738
0
  INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
1739
0
  ctl_putunqstr(tag, buffer, rc);
1740
0
}
1741
1742
1743
/*
1744
 * ctl_puthex - write a tagged unsigned integer, in hex, into the
1745
 * response
1746
 */
1747
static void
1748
ctl_puthex(
1749
  const char *tag,
1750
  u_long uval
1751
  )
1752
0
{
1753
0
  char buffer[24];  /* must fit 64bit int! */
1754
0
  int  rc;
1755
1756
0
  rc = snprintf(buffer, sizeof(buffer), "0x%lx", uval);
1757
0
  INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
1758
0
  ctl_putunqstr(tag, buffer, rc);
1759
0
}
1760
1761
1762
/*
1763
 * ctl_putint - write a tagged signed integer into the response
1764
 */
1765
static void
1766
ctl_putint(
1767
  const char *tag,
1768
  long ival
1769
  )
1770
0
{
1771
0
  char buffer[24];  /*must fit 64bit int */
1772
0
  int  rc;
1773
1774
0
  rc = snprintf(buffer, sizeof(buffer), "%ld", ival);
1775
0
  INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
1776
0
  ctl_putunqstr(tag, buffer, rc);
1777
0
}
1778
1779
1780
/*
1781
 * ctl_putts - write a tagged timestamp, in hex, into the response
1782
 */
1783
static void
1784
ctl_putts(
1785
  const char *tag,
1786
  l_fp *ts
1787
  )
1788
0
{
1789
0
  char buffer[24];
1790
0
  int  rc;
1791
1792
0
  rc = snprintf(buffer, sizeof(buffer),
1793
0
          "0x%08lx.%08lx",
1794
0
          (u_long)ts->l_ui, (u_long)ts->l_uf);
1795
0
  INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
1796
0
  ctl_putunqstr(tag, buffer, rc);
1797
0
}
1798
1799
1800
/*
1801
 * ctl_putadr - write an IP address into the response
1802
 */
1803
static void
1804
ctl_putadr(
1805
  const char *tag,
1806
  u_int32 addr32,
1807
  sockaddr_u *addr
1808
  )
1809
0
{
1810
0
  const char *cq;
1811
1812
0
  if (NULL == addr)
1813
0
    cq = numtoa(addr32);
1814
0
  else
1815
0
    cq = stoa(addr);
1816
0
  ctl_putunqstr(tag, cq, strlen(cq));
1817
0
}
1818
1819
1820
/*
1821
 * ctl_putrefid - send a u_int32 refid as printable text
1822
 */
1823
static void
1824
ctl_putrefid(
1825
  const char *  tag,
1826
  u_int32   refid
1827
  )
1828
0
{
1829
0
  size_t nc;
1830
1831
0
  union {
1832
0
    uint32_t w;
1833
0
    uint8_t  b[sizeof(uint32_t)];
1834
0
  } bytes;
1835
1836
0
  bytes.w = refid;
1837
0
  for (nc = 0; nc < sizeof(bytes.b) && bytes.b[nc]; ++nc)
1838
0
    if (  !isprint(bytes.b[nc])
1839
0
        || isspace(bytes.b[nc])
1840
0
        || bytes.b[nc] == ','  )
1841
0
      bytes.b[nc] = '.';
1842
0
  ctl_putunqstr(tag, (const char*)bytes.b, nc);
1843
0
}
1844
1845
1846
/*
1847
 * ctl_putarray - write a tagged eight element double array into the response
1848
 */
1849
static void
1850
ctl_putarray(
1851
  const char *tag,
1852
  double *arr,
1853
  int start
1854
  )
1855
0
{
1856
0
  char *cp, *ep;
1857
0
  char buffer[200];
1858
0
  int  i, rc;
1859
1860
0
  cp = buffer;
1861
0
  ep = buffer + sizeof(buffer);
1862
0
  i  = start;
1863
0
  do {
1864
0
    if (i == 0)
1865
0
      i = NTP_SHIFT;
1866
0
    i--;
1867
0
    rc = snprintf(cp, (size_t)(ep - cp), " %.2f", arr[i] * 1e3);
1868
0
    INSIST(rc >= 0 && (size_t)rc < (size_t)(ep - cp));
1869
0
    cp += rc;
1870
0
  } while (i != start);
1871
0
  ctl_putunqstr(tag, buffer, (size_t)(cp - buffer));
1872
0
}
1873
1874
/*
1875
 * ctl_printf - put a formatted string into the data buffer
1876
 */
1877
static void
1878
ctl_printf(
1879
  const char * fmt,
1880
  ...
1881
  )
1882
0
{
1883
0
  static const char * ellipsis = "[...]";
1884
0
  va_list va;
1885
0
  char    fmtbuf[128];
1886
0
  int     rc;
1887
1888
0
  va_start(va, fmt);
1889
0
  rc = vsnprintf(fmtbuf, sizeof(fmtbuf), fmt, va);
1890
0
  va_end(va);
1891
0
  if (rc < 0 || (size_t)rc >= sizeof(fmtbuf))
1892
0
    strcpy(fmtbuf + sizeof(fmtbuf) - strlen(ellipsis) - 1,
1893
0
           ellipsis);
1894
0
  ctl_putdata(fmtbuf, strlen(fmtbuf), 0);
1895
0
}
1896
1897
1898
/*
1899
 * ctl_putsys - output a system variable
1900
 */
1901
static void
1902
ctl_putsys(
1903
  int varid
1904
  )
1905
0
{
1906
0
  l_fp tmp;
1907
0
  char str[256];
1908
0
  u_int u;
1909
0
  double kb;
1910
0
  double dtemp;
1911
0
  const char *ss;
1912
0
#ifdef AUTOKEY
1913
0
  struct cert_info *cp;
1914
0
#endif  /* AUTOKEY */
1915
0
#ifdef KERNEL_PLL
1916
0
  static struct timex ntx;
1917
0
  static u_long ntp_adjtime_time;
1918
1919
  /*
1920
   * CS_K_* variables depend on up-to-date output of ntp_adjtime()
1921
   */
1922
0
  if (CS_KERN_FIRST <= varid && varid <= CS_KERN_LAST &&
1923
0
      current_time != ntp_adjtime_time) {
1924
0
    ZERO(ntx);
1925
0
    if (ntp_adjtime(&ntx) < 0)
1926
0
      msyslog(LOG_ERR, "ntp_adjtime() for mode 6 query failed: %m");
1927
0
    else
1928
0
      ntp_adjtime_time = current_time;
1929
0
  }
1930
0
#endif  /* KERNEL_PLL */
1931
1932
0
  switch (varid) {
1933
1934
0
  case CS_LEAP:
1935
0
    ctl_putuint(sys_var[CS_LEAP].text, sys_leap);
1936
0
    break;
1937
1938
0
  case CS_STRATUM:
1939
0
    ctl_putuint(sys_var[CS_STRATUM].text, sys_stratum);
1940
0
    break;
1941
1942
0
  case CS_PRECISION:
1943
0
    ctl_putint(sys_var[CS_PRECISION].text, sys_precision);
1944
0
    break;
1945
1946
0
  case CS_ROOTDELAY:
1947
0
    ctl_putdbl(sys_var[CS_ROOTDELAY].text, sys_rootdelay *
1948
0
         1e3);
1949
0
    break;
1950
1951
0
  case CS_ROOTDISPERSION:
1952
0
    ctl_putdbl(sys_var[CS_ROOTDISPERSION].text,
1953
0
         sys_rootdisp * 1e3);
1954
0
    break;
1955
1956
0
  case CS_REFID:
1957
0
    if (REFID_ISTEXT(sys_stratum))
1958
0
      ctl_putrefid(sys_var[varid].text, sys_refid);
1959
0
    else
1960
0
      ctl_putadr(sys_var[varid].text, sys_refid, NULL);
1961
0
    break;
1962
1963
0
  case CS_REFTIME:
1964
0
    ctl_putts(sys_var[CS_REFTIME].text, &sys_reftime);
1965
0
    break;
1966
1967
0
  case CS_POLL:
1968
0
    ctl_putuint(sys_var[CS_POLL].text, sys_poll);
1969
0
    break;
1970
1971
0
  case CS_PEERID:
1972
0
    if (sys_peer == NULL)
1973
0
      ctl_putuint(sys_var[CS_PEERID].text, 0);
1974
0
    else
1975
0
      ctl_putuint(sys_var[CS_PEERID].text,
1976
0
            sys_peer->associd);
1977
0
    break;
1978
1979
0
  case CS_PEERADR:
1980
0
    if (sys_peer != NULL && sys_peer->dstadr != NULL)
1981
0
      ss = sptoa(&sys_peer->srcadr);
1982
0
    else
1983
0
      ss = "0.0.0.0:0";
1984
0
    ctl_putunqstr(sys_var[CS_PEERADR].text, ss, strlen(ss));
1985
0
    break;
1986
1987
0
  case CS_PEERMODE:
1988
0
    u = (sys_peer != NULL)
1989
0
      ? sys_peer->hmode
1990
0
      : MODE_UNSPEC;
1991
0
    ctl_putuint(sys_var[CS_PEERMODE].text, u);
1992
0
    break;
1993
1994
0
  case CS_OFFSET:
1995
0
    ctl_putdbl6(sys_var[CS_OFFSET].text, last_offset * 1e3);
1996
0
    break;
1997
1998
0
  case CS_DRIFT:
1999
0
    ctl_putdbl(sys_var[CS_DRIFT].text, drift_comp * 1e6);
2000
0
    break;
2001
2002
0
  case CS_JITTER:
2003
0
    ctl_putdbl6(sys_var[CS_JITTER].text, sys_jitter * 1e3);
2004
0
    break;
2005
2006
0
  case CS_ERROR:
2007
0
    ctl_putdbl(sys_var[CS_ERROR].text, clock_jitter * 1e3);
2008
0
    break;
2009
2010
0
  case CS_CLOCK:
2011
0
    get_systime(&tmp);
2012
0
    ctl_putts(sys_var[CS_CLOCK].text, &tmp);
2013
0
    break;
2014
2015
0
  case CS_PROCESSOR:
2016
#ifndef HAVE_UNAME
2017
    ctl_putstr(sys_var[CS_PROCESSOR].text, str_processor,
2018
         sizeof(str_processor) - 1);
2019
#else
2020
0
    ctl_putstr(sys_var[CS_PROCESSOR].text,
2021
0
         utsnamebuf.machine, strlen(utsnamebuf.machine));
2022
0
#endif /* HAVE_UNAME */
2023
0
    break;
2024
2025
0
  case CS_SYSTEM:
2026
#ifndef HAVE_UNAME
2027
    ctl_putstr(sys_var[CS_SYSTEM].text, str_system,
2028
         sizeof(str_system) - 1);
2029
#else
2030
0
    snprintf(str, sizeof(str), "%s/%s", utsnamebuf.sysname,
2031
0
       utsnamebuf.release);
2032
0
    ctl_putstr(sys_var[CS_SYSTEM].text, str, strlen(str));
2033
0
#endif /* HAVE_UNAME */
2034
0
    break;
2035
2036
0
  case CS_VERSION:
2037
0
    ctl_putstr(sys_var[CS_VERSION].text, Version,
2038
0
         strlen(Version));
2039
0
    break;
2040
2041
0
  case CS_STABIL:
2042
0
    ctl_putdbl(sys_var[CS_STABIL].text, clock_stability *
2043
0
         1e6);
2044
0
    break;
2045
2046
0
  case CS_VARLIST:
2047
0
  {
2048
0
    char buf[CTL_MAX_DATA_LEN];
2049
    //buffPointer, firstElementPointer, buffEndPointer
2050
0
    char *buffp, *buffend;
2051
0
    int firstVarName;
2052
0
    const char *ss1;
2053
0
    int len;
2054
0
    const struct ctl_var *k;
2055
2056
0
    buffp = buf;
2057
0
    buffend = buf + sizeof(buf);
2058
0
    if (strlen(sys_var[CS_VARLIST].text) > (sizeof(buf) - 4))
2059
0
      break; /* really long var name */
2060
2061
0
    snprintf(buffp, sizeof(buf), "%s=\"",sys_var[CS_VARLIST].text);
2062
0
    buffp += strlen(buffp);
2063
0
    firstVarName = TRUE;
2064
0
    for (k = sys_var; !(k->flags & EOV); k++) {
2065
0
      if (k->flags & PADDING)
2066
0
        continue;
2067
0
      len = strlen(k->text);
2068
0
      if (len + 1 >= buffend - buffp)
2069
0
        break;
2070
0
      if (!firstVarName)
2071
0
        *buffp++ = ',';
2072
0
      else
2073
0
        firstVarName = FALSE;
2074
0
      memcpy(buffp, k->text, len);
2075
0
      buffp += len;
2076
0
    }
2077
2078
0
    for (k = ext_sys_var; k && !(k->flags & EOV); k++) {
2079
0
      if (k->flags & PADDING)
2080
0
        continue;
2081
0
      if (NULL == k->text)
2082
0
        continue;
2083
0
      ss1 = strchr(k->text, '=');
2084
0
      if (NULL == ss1)
2085
0
        len = strlen(k->text);
2086
0
      else
2087
0
        len = ss1 - k->text;
2088
0
      if (len + 1 >= buffend - buffp)
2089
0
        break;
2090
0
      if (firstVarName) {
2091
0
        *buffp++ = ',';
2092
0
        firstVarName = FALSE;
2093
0
      }
2094
0
      memcpy(buffp, k->text,(unsigned)len);
2095
0
      buffp += len;
2096
0
    }
2097
0
    if (2 >= buffend - buffp)
2098
0
      break;
2099
2100
0
    *buffp++ = '"';
2101
0
    *buffp = '\0';
2102
2103
0
    ctl_putdata(buf, (unsigned)( buffp - buf ), 0);
2104
0
    break;
2105
0
  }
2106
2107
0
  case CS_TAI:
2108
0
    if (sys_tai > 0)
2109
0
      ctl_putuint(sys_var[CS_TAI].text, sys_tai);
2110
0
    break;
2111
2112
0
  case CS_LEAPTAB:
2113
0
  {
2114
0
    leap_signature_t lsig;
2115
0
    leapsec_getsig(&lsig);
2116
0
    if (lsig.ttime > 0)
2117
0
      ctl_putfs(sys_var[CS_LEAPTAB].text, lsig.ttime);
2118
0
    break;
2119
0
  }
2120
2121
0
  case CS_LEAPEND:
2122
0
  {
2123
0
    leap_signature_t lsig;
2124
0
    leapsec_getsig(&lsig);
2125
0
    if (lsig.etime > 0)
2126
0
      ctl_putfs(sys_var[CS_LEAPEND].text, lsig.etime);
2127
0
    break;
2128
0
  }
2129
2130
#ifdef LEAP_SMEAR
2131
  case CS_LEAPSMEARINTV:
2132
    if (leap_smear_intv > 0)
2133
      ctl_putuint(sys_var[CS_LEAPSMEARINTV].text, leap_smear_intv);
2134
    break;
2135
2136
  case CS_LEAPSMEAROFFS:
2137
    if (leap_smear_intv > 0)
2138
      ctl_putdbl(sys_var[CS_LEAPSMEAROFFS].text,
2139
           leap_smear.doffset * 1e3);
2140
    break;
2141
#endif  /* LEAP_SMEAR */
2142
2143
0
  case CS_RATE:
2144
0
    ctl_putuint(sys_var[CS_RATE].text, ntp_minpoll);
2145
0
    break;
2146
2147
0
  case CS_MRU_ENABLED:
2148
0
    ctl_puthex(sys_var[varid].text, mon_enabled);
2149
0
    break;
2150
2151
0
  case CS_MRU_DEPTH:
2152
0
    ctl_putuint(sys_var[varid].text, mru_entries);
2153
0
    break;
2154
2155
0
  case CS_MRU_MEM:
2156
0
    kb = mru_entries * (sizeof(mon_entry) / 1024.);
2157
0
    u = (u_int)kb;
2158
0
    if (kb - u >= 0.5)
2159
0
      u++;
2160
0
    ctl_putuint(sys_var[varid].text, u);
2161
0
    break;
2162
2163
0
  case CS_MRU_DEEPEST:
2164
0
    ctl_putuint(sys_var[varid].text, mru_peakentries);
2165
0
    break;
2166
2167
0
  case CS_MRU_MINDEPTH:
2168
0
    ctl_putuint(sys_var[varid].text, mru_mindepth);
2169
0
    break;
2170
2171
0
  case CS_MRU_MAXAGE:
2172
0
    ctl_putint(sys_var[varid].text, mru_maxage);
2173
0
    break;
2174
2175
0
  case CS_MRU_MAXDEPTH:
2176
0
    ctl_putuint(sys_var[varid].text, mru_maxdepth);
2177
0
    break;
2178
2179
0
  case CS_MRU_MAXMEM:
2180
0
    kb = mru_maxdepth * (sizeof(mon_entry) / 1024.);
2181
0
    u = (u_int)kb;
2182
0
    if (kb - u >= 0.5)
2183
0
      u++;
2184
0
    ctl_putuint(sys_var[varid].text, u);
2185
0
    break;
2186
2187
0
  case CS_SS_UPTIME:
2188
0
    ctl_putuint(sys_var[varid].text, current_time);
2189
0
    break;
2190
2191
0
  case CS_SS_RESET:
2192
0
    ctl_putuint(sys_var[varid].text,
2193
0
          current_time - sys_stattime);
2194
0
    break;
2195
2196
0
  case CS_SS_RECEIVED:
2197
0
    ctl_putuint(sys_var[varid].text, sys_received);
2198
0
    break;
2199
2200
0
  case CS_SS_THISVER:
2201
0
    ctl_putuint(sys_var[varid].text, sys_newversion);
2202
0
    break;
2203
2204
0
  case CS_SS_OLDVER:
2205
0
    ctl_putuint(sys_var[varid].text, sys_oldversion);
2206
0
    break;
2207
2208
0
  case CS_SS_BADFORMAT:
2209
0
    ctl_putuint(sys_var[varid].text, sys_badlength);
2210
0
    break;
2211
2212
0
  case CS_SS_BADAUTH:
2213
0
    ctl_putuint(sys_var[varid].text, sys_badauth);
2214
0
    break;
2215
2216
0
  case CS_SS_DECLINED:
2217
0
    ctl_putuint(sys_var[varid].text, sys_declined);
2218
0
    break;
2219
2220
0
  case CS_SS_RESTRICTED:
2221
0
    ctl_putuint(sys_var[varid].text, sys_restricted);
2222
0
    break;
2223
2224
0
  case CS_SS_LIMITED:
2225
0
    ctl_putuint(sys_var[varid].text, sys_limitrejected);
2226
0
    break;
2227
2228
0
  case CS_SS_LAMPORT:
2229
0
    ctl_putuint(sys_var[varid].text, sys_lamport);
2230
0
    break;
2231
2232
0
  case CS_SS_TSROUNDING:
2233
0
    ctl_putuint(sys_var[varid].text, sys_tsrounding);
2234
0
    break;
2235
2236
0
  case CS_SS_KODSENT:
2237
0
    ctl_putuint(sys_var[varid].text, sys_kodsent);
2238
0
    break;
2239
2240
0
  case CS_SS_PROCESSED:
2241
0
    ctl_putuint(sys_var[varid].text, sys_processed);
2242
0
    break;
2243
2244
0
  case CS_BCASTDELAY:
2245
0
    ctl_putdbl(sys_var[varid].text, sys_bdelay * 1e3);
2246
0
    break;
2247
2248
0
  case CS_AUTHDELAY:
2249
0
    LFPTOD(&sys_authdelay, dtemp);
2250
0
    ctl_putdbl(sys_var[varid].text, dtemp * 1e3);
2251
0
    break;
2252
2253
0
  case CS_AUTHKEYS:
2254
0
    ctl_putuint(sys_var[varid].text, authnumkeys);
2255
0
    break;
2256
2257
0
  case CS_AUTHFREEK:
2258
0
    ctl_putuint(sys_var[varid].text, authnumfreekeys);
2259
0
    break;
2260
2261
0
  case CS_AUTHKLOOKUPS:
2262
0
    ctl_putuint(sys_var[varid].text, authkeylookups);
2263
0
    break;
2264
2265
0
  case CS_AUTHKNOTFOUND:
2266
0
    ctl_putuint(sys_var[varid].text, authkeynotfound);
2267
0
    break;
2268
2269
0
  case CS_AUTHKUNCACHED:
2270
0
    ctl_putuint(sys_var[varid].text, authkeyuncached);
2271
0
    break;
2272
2273
0
  case CS_AUTHKEXPIRED:
2274
0
    ctl_putuint(sys_var[varid].text, authkeyexpired);
2275
0
    break;
2276
2277
0
  case CS_AUTHENCRYPTS:
2278
0
    ctl_putuint(sys_var[varid].text, authencryptions);
2279
0
    break;
2280
2281
0
  case CS_AUTHDECRYPTS:
2282
0
    ctl_putuint(sys_var[varid].text, authdecryptions);
2283
0
    break;
2284
2285
0
  case CS_AUTHRESET:
2286
0
    ctl_putuint(sys_var[varid].text,
2287
0
          current_time - auth_timereset);
2288
0
    break;
2289
2290
    /*
2291
     * CTL_IF_KERNLOOP() puts a zero if the kernel loop is
2292
     * unavailable, otherwise calls putfunc with args.
2293
     */
2294
#ifndef KERNEL_PLL
2295
# define  CTL_IF_KERNLOOP(putfunc, args)  \
2296
    ctl_putint(sys_var[varid].text, 0)
2297
#else
2298
0
# define  CTL_IF_KERNLOOP(putfunc, args)  \
2299
0
    putfunc args
2300
0
#endif
2301
2302
    /*
2303
     * CTL_IF_KERNPPS() puts a zero if either the kernel
2304
     * loop is unavailable, or kernel hard PPS is not
2305
     * active, otherwise calls putfunc with args.
2306
     */
2307
#ifndef KERNEL_PLL
2308
# define  CTL_IF_KERNPPS(putfunc, args) \
2309
    ctl_putint(sys_var[varid].text, 0)
2310
#else
2311
0
# define  CTL_IF_KERNPPS(putfunc, args)     \
2312
0
    if (0 == ntx.shift)       \
2313
0
      ctl_putint(sys_var[varid].text, 0); \
2314
0
    else            \
2315
0
      putfunc args /* no trailing ; */
2316
0
#endif
2317
2318
0
  case CS_K_OFFSET:
2319
0
    CTL_IF_KERNLOOP(
2320
0
      ctl_putdblf,
2321
0
      (sys_var[varid].text, 0, -1,
2322
0
       1000 * dbl_from_var_long(ntx.offset, ntx.status))
2323
0
    );
2324
0
    break;
2325
2326
0
  case CS_K_FREQ:
2327
0
    CTL_IF_KERNLOOP(
2328
0
      ctl_putsfp,
2329
0
      (sys_var[varid].text, ntx.freq)
2330
0
    );
2331
0
    break;
2332
2333
0
  case CS_K_MAXERR:
2334
0
    CTL_IF_KERNLOOP(
2335
0
      ctl_putdblf,
2336
0
      (sys_var[varid].text, 0, 6,
2337
0
       1000 * dbl_from_usec_long(ntx.maxerror))
2338
0
    );
2339
0
    break;
2340
2341
0
  case CS_K_ESTERR:
2342
0
    CTL_IF_KERNLOOP(
2343
0
      ctl_putdblf,
2344
0
      (sys_var[varid].text, 0, 6,
2345
0
       1000 * dbl_from_usec_long(ntx.esterror))
2346
0
    );
2347
0
    break;
2348
2349
0
  case CS_K_STFLAGS:
2350
#ifndef KERNEL_PLL
2351
    ss = "";
2352
#else
2353
0
    ss = k_st_flags(ntx.status);
2354
0
#endif
2355
0
    ctl_putstr(sys_var[varid].text, ss, strlen(ss));
2356
0
    break;
2357
2358
0
  case CS_K_TIMECONST:
2359
0
    CTL_IF_KERNLOOP(
2360
0
      ctl_putint,
2361
0
      (sys_var[varid].text, ntx.constant)
2362
0
    );
2363
0
    break;
2364
2365
0
  case CS_K_PRECISION:
2366
0
    CTL_IF_KERNLOOP(
2367
0
      ctl_putdblf,
2368
0
      (sys_var[varid].text, 0, 6,
2369
0
       1000 * dbl_from_var_long(ntx.precision, ntx.status))
2370
0
    );
2371
0
    break;
2372
2373
0
  case CS_K_FREQTOL:
2374
0
    CTL_IF_KERNLOOP(
2375
0
      ctl_putsfp,
2376
0
      (sys_var[varid].text, ntx.tolerance)
2377
0
    );
2378
0
    break;
2379
2380
0
  case CS_K_PPS_FREQ:
2381
0
    CTL_IF_KERNPPS(
2382
0
      ctl_putsfp,
2383
0
      (sys_var[varid].text, ntx.ppsfreq)
2384
0
    );
2385
0
    break;
2386
2387
0
  case CS_K_PPS_STABIL:
2388
0
    CTL_IF_KERNPPS(
2389
0
      ctl_putsfp,
2390
0
      (sys_var[varid].text, ntx.stabil)
2391
0
    );
2392
0
    break;
2393
2394
0
  case CS_K_PPS_JITTER:
2395
0
    CTL_IF_KERNPPS(
2396
0
      ctl_putdbl,
2397
0
      (sys_var[varid].text,
2398
0
       1000 * dbl_from_var_long(ntx.jitter, ntx.status))
2399
0
    );
2400
0
    break;
2401
2402
0
  case CS_K_PPS_CALIBDUR:
2403
0
    CTL_IF_KERNPPS(
2404
0
      ctl_putint,
2405
0
      (sys_var[varid].text, 1 << ntx.shift)
2406
0
    );
2407
0
    break;
2408
2409
0
  case CS_K_PPS_CALIBS:
2410
0
    CTL_IF_KERNPPS(
2411
0
      ctl_putint,
2412
0
      (sys_var[varid].text, ntx.calcnt)
2413
0
    );
2414
0
    break;
2415
2416
0
  case CS_K_PPS_CALIBERRS:
2417
0
    CTL_IF_KERNPPS(
2418
0
      ctl_putint,
2419
0
      (sys_var[varid].text, ntx.errcnt)
2420
0
    );
2421
0
    break;
2422
2423
0
  case CS_K_PPS_JITEXC:
2424
0
    CTL_IF_KERNPPS(
2425
0
      ctl_putint,
2426
0
      (sys_var[varid].text, ntx.jitcnt)
2427
0
    );
2428
0
    break;
2429
2430
0
  case CS_K_PPS_STBEXC:
2431
0
    CTL_IF_KERNPPS(
2432
0
      ctl_putint,
2433
0
      (sys_var[varid].text, ntx.stbcnt)
2434
0
    );
2435
0
    break;
2436
2437
0
  case CS_IOSTATS_RESET:
2438
0
    ctl_putuint(sys_var[varid].text,
2439
0
          current_time - io_timereset);
2440
0
    break;
2441
2442
0
  case CS_TOTAL_RBUF:
2443
0
    ctl_putuint(sys_var[varid].text, total_recvbuffs());
2444
0
    break;
2445
2446
0
  case CS_FREE_RBUF:
2447
0
    ctl_putuint(sys_var[varid].text, free_recvbuffs());
2448
0
    break;
2449
2450
0
  case CS_USED_RBUF:
2451
0
    ctl_putuint(sys_var[varid].text, full_recvbuffs());
2452
0
    break;
2453
2454
0
  case CS_RBUF_LOWATER:
2455
0
    ctl_putuint(sys_var[varid].text, lowater_additions());
2456
0
    break;
2457
2458
0
  case CS_IO_DROPPED:
2459
0
    ctl_putuint(sys_var[varid].text, packets_dropped);
2460
0
    break;
2461
2462
0
  case CS_IO_IGNORED:
2463
0
    ctl_putuint(sys_var[varid].text, packets_ignored);
2464
0
    break;
2465
2466
0
  case CS_IO_RECEIVED:
2467
0
    ctl_putuint(sys_var[varid].text, packets_received);
2468
0
    break;
2469
2470
0
  case CS_IO_SENT:
2471
0
    ctl_putuint(sys_var[varid].text, packets_sent);
2472
0
    break;
2473
2474
0
  case CS_IO_SENDFAILED:
2475
0
    ctl_putuint(sys_var[varid].text, packets_notsent);
2476
0
    break;
2477
2478
0
  case CS_IO_WAKEUPS:
2479
0
    ctl_putuint(sys_var[varid].text, handler_calls);
2480
0
    break;
2481
2482
0
  case CS_IO_GOODWAKEUPS:
2483
0
    ctl_putuint(sys_var[varid].text, handler_pkts);
2484
0
    break;
2485
2486
0
  case CS_TIMERSTATS_RESET:
2487
0
    ctl_putuint(sys_var[varid].text,
2488
0
          current_time - timer_timereset);
2489
0
    break;
2490
2491
0
  case CS_TIMER_OVERRUNS:
2492
0
    ctl_putuint(sys_var[varid].text, alarm_overflow);
2493
0
    break;
2494
2495
0
  case CS_TIMER_XMTS:
2496
0
    ctl_putuint(sys_var[varid].text, timer_xmtcalls);
2497
0
    break;
2498
2499
0
  case CS_FUZZ:
2500
0
    ctl_putdbl(sys_var[varid].text, sys_fuzz * 1e3);
2501
0
    break;
2502
0
  case CS_WANDER_THRESH:
2503
0
    ctl_putdbl(sys_var[varid].text, wander_threshold * 1e6);
2504
0
    break;
2505
0
#ifdef AUTOKEY
2506
0
  case CS_FLAGS:
2507
0
    if (crypto_flags)
2508
0
      ctl_puthex(sys_var[CS_FLAGS].text,
2509
0
          crypto_flags);
2510
0
    break;
2511
2512
0
  case CS_DIGEST:
2513
0
    if (crypto_flags) {
2514
0
      strlcpy(str, OBJ_nid2ln(crypto_nid),
2515
0
          COUNTOF(str));
2516
0
      ctl_putstr(sys_var[CS_DIGEST].text, str,
2517
0
          strlen(str));
2518
0
    }
2519
0
    break;
2520
2521
0
  case CS_SIGNATURE:
2522
0
    if (crypto_flags) {
2523
0
      const EVP_MD *dp;
2524
2525
0
      dp = EVP_get_digestbynid(crypto_flags >> 16);
2526
0
      strlcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)),
2527
0
          COUNTOF(str));
2528
0
      ctl_putstr(sys_var[CS_SIGNATURE].text, str,
2529
0
          strlen(str));
2530
0
    }
2531
0
    break;
2532
2533
0
  case CS_HOST:
2534
0
    if (hostval.ptr != NULL)
2535
0
      ctl_putstr(sys_var[CS_HOST].text, hostval.ptr,
2536
0
          strlen(hostval.ptr));
2537
0
    break;
2538
2539
0
  case CS_IDENT:
2540
0
    if (sys_ident != NULL)
2541
0
      ctl_putstr(sys_var[CS_IDENT].text, sys_ident,
2542
0
          strlen(sys_ident));
2543
0
    break;
2544
2545
0
  case CS_CERTIF:
2546
0
    for (cp = cinfo; cp != NULL; cp = cp->link) {
2547
0
      snprintf(str, sizeof(str), "%s %s 0x%x",
2548
0
          cp->subject, cp->issuer, cp->flags);
2549
0
      ctl_putstr(sys_var[CS_CERTIF].text, str,
2550
0
          strlen(str));
2551
0
      ctl_putcal(sys_var[CS_REVTIME].text, &(cp->last));
2552
0
    }
2553
0
    break;
2554
2555
0
  case CS_PUBLIC:
2556
0
    if (hostval.tstamp != 0)
2557
0
      ctl_putfs(sys_var[CS_PUBLIC].text,
2558
0
          ntohl(hostval.tstamp));
2559
0
    break;
2560
0
#endif  /* AUTOKEY */
2561
2562
0
  default:
2563
0
    break;
2564
0
  }
2565
0
}
2566
2567
2568
/*
2569
 * ctl_putpeer - output a peer variable
2570
 */
2571
static void
2572
ctl_putpeer(
2573
  int id,
2574
  struct peer *p
2575
  )
2576
0
{
2577
0
  char buf[CTL_MAX_DATA_LEN];
2578
0
  char *s;
2579
0
  char *t;
2580
0
  char *be;
2581
0
  int i;
2582
0
  const struct ctl_var *k;
2583
0
#ifdef AUTOKEY
2584
0
  struct autokey *ap;
2585
0
  const EVP_MD *dp;
2586
0
  const char *str;
2587
0
#endif  /* AUTOKEY */
2588
2589
0
  switch (id) {
2590
2591
0
  case CP_CONFIG:
2592
0
    ctl_putuint(peer_var[id].text,
2593
0
          !(FLAG_PREEMPT & p->flags));
2594
0
    break;
2595
2596
0
  case CP_AUTHENABLE:
2597
0
    ctl_putuint(peer_var[id].text, !(p->keyid));
2598
0
    break;
2599
2600
0
  case CP_AUTHENTIC:
2601
0
    ctl_putuint(peer_var[id].text,
2602
0
          !!(FLAG_AUTHENTIC & p->flags));
2603
0
    break;
2604
2605
0
  case CP_SRCADR:
2606
0
    ctl_putadr(peer_var[id].text, 0, &p->srcadr);
2607
0
    break;
2608
2609
0
  case CP_SRCPORT:
2610
0
    ctl_putuint(peer_var[id].text, SRCPORT(&p->srcadr));
2611
0
    break;
2612
2613
0
  case CP_SRCHOST:
2614
0
    if (p->hostname != NULL)
2615
0
      ctl_putstr(peer_var[id].text, p->hostname,
2616
0
           strlen(p->hostname));
2617
0
    break;
2618
2619
0
  case CP_DSTADR:
2620
0
    ctl_putadr(peer_var[id].text, 0,
2621
0
         (p->dstadr != NULL)
2622
0
        ? &p->dstadr->sin
2623
0
        : NULL);
2624
0
    break;
2625
2626
0
  case CP_DSTPORT:
2627
0
    ctl_putuint(peer_var[id].text,
2628
0
          (p->dstadr != NULL)
2629
0
        ? SRCPORT(&p->dstadr->sin)
2630
0
        : 0);
2631
0
    break;
2632
2633
0
  case CP_IN:
2634
0
    if (p->r21 > 0.)
2635
0
      ctl_putdbl(peer_var[id].text, p->r21 / 1e3);
2636
0
    break;
2637
2638
0
  case CP_OUT:
2639
0
    if (p->r34 > 0.)
2640
0
      ctl_putdbl(peer_var[id].text, p->r34 / 1e3);
2641
0
    break;
2642
2643
0
  case CP_RATE:
2644
0
    ctl_putuint(peer_var[id].text, p->throttle);
2645
0
    break;
2646
2647
0
  case CP_LEAP:
2648
0
    ctl_putuint(peer_var[id].text, p->leap);
2649
0
    break;
2650
2651
0
  case CP_HMODE:
2652
0
    ctl_putuint(peer_var[id].text, p->hmode);
2653
0
    break;
2654
2655
0
  case CP_STRATUM:
2656
0
    ctl_putuint(peer_var[id].text, p->stratum);
2657
0
    break;
2658
2659
0
  case CP_PPOLL:
2660
0
    ctl_putuint(peer_var[id].text, p->ppoll);
2661
0
    break;
2662
2663
0
  case CP_HPOLL:
2664
0
    ctl_putuint(peer_var[id].text, p->hpoll);
2665
0
    break;
2666
2667
0
  case CP_PRECISION:
2668
0
    ctl_putint(peer_var[id].text, p->precision);
2669
0
    break;
2670
2671
0
  case CP_ROOTDELAY:
2672
0
    ctl_putdbl(peer_var[id].text, p->rootdelay * 1e3);
2673
0
    break;
2674
2675
0
  case CP_ROOTDISPERSION:
2676
0
    ctl_putdbl(peer_var[id].text, p->rootdisp * 1e3);
2677
0
    break;
2678
2679
0
  case CP_REFID:
2680
0
#ifdef REFCLOCK
2681
0
    if (p->flags & FLAG_REFCLOCK) {
2682
0
      ctl_putrefid(peer_var[id].text, p->refid);
2683
0
      break;
2684
0
    }
2685
0
#endif
2686
0
    if (REFID_ISTEXT(p->stratum))
2687
0
      ctl_putrefid(peer_var[id].text, p->refid);
2688
0
    else
2689
0
      ctl_putadr(peer_var[id].text, p->refid, NULL);
2690
0
    break;
2691
2692
0
  case CP_REFTIME:
2693
0
    ctl_putts(peer_var[id].text, &p->reftime);
2694
0
    break;
2695
2696
0
  case CP_ORG:
2697
0
    ctl_putts(peer_var[id].text, &p->aorg);
2698
0
    break;
2699
2700
0
  case CP_REC:
2701
0
    ctl_putts(peer_var[id].text, &p->dst);
2702
0
    break;
2703
2704
0
  case CP_XMT:
2705
0
    if (p->xleave)
2706
0
      ctl_putdbl(peer_var[id].text, p->xleave * 1e3);
2707
0
    break;
2708
2709
0
  case CP_BIAS:
2710
0
    if (p->bias != 0.)
2711
0
      ctl_putdbl(peer_var[id].text, p->bias * 1e3);
2712
0
    break;
2713
2714
0
  case CP_REACH:
2715
0
    ctl_puthex(peer_var[id].text, p->reach);
2716
0
    break;
2717
2718
0
  case CP_FLASH:
2719
0
    ctl_puthex(peer_var[id].text, p->flash);
2720
0
    break;
2721
2722
0
  case CP_TTL:
2723
0
#ifdef REFCLOCK
2724
0
    if (p->flags & FLAG_REFCLOCK) {
2725
0
      ctl_putuint(peer_var[id].text, p->ttl);
2726
0
      break;
2727
0
    }
2728
0
#endif
2729
0
    if (p->ttl > 0 && p->ttl < COUNTOF(sys_ttl))
2730
0
      ctl_putint(peer_var[id].text,
2731
0
           sys_ttl[p->ttl]);
2732
0
    break;
2733
2734
0
  case CP_UNREACH:
2735
0
    ctl_putuint(peer_var[id].text, p->unreach);
2736
0
    break;
2737
2738
0
  case CP_TIMER:
2739
0
    ctl_putuint(peer_var[id].text,
2740
0
          p->nextdate - current_time);
2741
0
    break;
2742
2743
0
  case CP_DELAY:
2744
0
    ctl_putdbl(peer_var[id].text, p->delay * 1e3);
2745
0
    break;
2746
2747
0
  case CP_OFFSET:
2748
0
    ctl_putdbl(peer_var[id].text, p->offset * 1e3);
2749
0
    break;
2750
2751
0
  case CP_JITTER:
2752
0
    ctl_putdbl(peer_var[id].text, p->jitter * 1e3);
2753
0
    break;
2754
2755
0
  case CP_DISPERSION:
2756
0
    ctl_putdbl(peer_var[id].text, p->disp * 1e3);
2757
0
    break;
2758
2759
0
  case CP_KEYID:
2760
0
    if (p->keyid > NTP_MAXKEY)
2761
0
      ctl_puthex(peer_var[id].text, p->keyid);
2762
0
    else
2763
0
      ctl_putuint(peer_var[id].text, p->keyid);
2764
0
    break;
2765
2766
0
  case CP_FILTDELAY:
2767
0
    ctl_putarray(peer_var[id].text, p->filter_delay,
2768
0
           p->filter_nextpt);
2769
0
    break;
2770
2771
0
  case CP_FILTOFFSET:
2772
0
    ctl_putarray(peer_var[id].text, p->filter_offset,
2773
0
           p->filter_nextpt);
2774
0
    break;
2775
2776
0
  case CP_FILTERROR:
2777
0
    ctl_putarray(peer_var[id].text, p->filter_disp,
2778
0
           p->filter_nextpt);
2779
0
    break;
2780
2781
0
  case CP_PMODE:
2782
0
    ctl_putuint(peer_var[id].text, p->pmode);
2783
0
    break;
2784
2785
0
  case CP_RECEIVED:
2786
0
    ctl_putuint(peer_var[id].text, p->received);
2787
0
    break;
2788
2789
0
  case CP_SENT:
2790
0
    ctl_putuint(peer_var[id].text, p->sent);
2791
0
    break;
2792
2793
0
  case CP_VARLIST:
2794
0
    s = buf;
2795
0
    be = buf + sizeof(buf);
2796
0
    if (strlen(peer_var[id].text) + 4 > sizeof(buf))
2797
0
      break; /* really long var name */
2798
2799
0
    snprintf(s, sizeof(buf), "%s=\"", peer_var[id].text);
2800
0
    s += strlen(s);
2801
0
    t = s;
2802
0
    for (k = peer_var; !(EOV & k->flags); k++) {
2803
0
      if (PADDING & k->flags)
2804
0
        continue;
2805
0
      i = strlen(k->text);
2806
0
      if (s + i + 1 >= be)
2807
0
        break;
2808
0
      if (s != t)
2809
0
        *s++ = ',';
2810
0
      memcpy(s, k->text, i);
2811
0
      s += i;
2812
0
    }
2813
0
    if (s + 2 < be) {
2814
0
      *s++ = '"';
2815
0
      *s = '\0';
2816
0
      ctl_putdata(buf, (u_int)(s - buf), 0);
2817
0
    }
2818
0
    break;
2819
2820
0
  case CP_TIMEREC:
2821
0
    ctl_putuint(peer_var[id].text,
2822
0
          current_time - p->timereceived);
2823
0
    break;
2824
2825
0
  case CP_TIMEREACH:
2826
0
    ctl_putuint(peer_var[id].text,
2827
0
          current_time - p->timereachable);
2828
0
    break;
2829
2830
0
  case CP_BADAUTH:
2831
0
    ctl_putuint(peer_var[id].text, p->badauth);
2832
0
    break;
2833
2834
0
  case CP_BOGUSORG:
2835
0
    ctl_putuint(peer_var[id].text, p->bogusorg);
2836
0
    break;
2837
2838
0
  case CP_OLDPKT:
2839
0
    ctl_putuint(peer_var[id].text, p->oldpkt);
2840
0
    break;
2841
2842
0
  case CP_SELDISP:
2843
0
    ctl_putuint(peer_var[id].text, p->seldisptoolarge);
2844
0
    break;
2845
2846
0
  case CP_SELBROKEN:
2847
0
    ctl_putuint(peer_var[id].text, p->selbroken);
2848
0
    break;
2849
2850
0
  case CP_CANDIDATE:
2851
0
    ctl_putuint(peer_var[id].text, p->status);
2852
0
    break;
2853
0
#ifdef AUTOKEY
2854
0
  case CP_FLAGS:
2855
0
    if (p->crypto)
2856
0
      ctl_puthex(peer_var[id].text, p->crypto);
2857
0
    break;
2858
2859
0
  case CP_SIGNATURE:
2860
0
    if (p->crypto) {
2861
0
      dp = EVP_get_digestbynid(p->crypto >> 16);
2862
0
      str = OBJ_nid2ln(EVP_MD_pkey_type(dp));
2863
0
      ctl_putstr(peer_var[id].text, str, strlen(str));
2864
0
    }
2865
0
    break;
2866
2867
0
  case CP_HOST:
2868
0
    if (p->subject != NULL)
2869
0
      ctl_putstr(peer_var[id].text, p->subject,
2870
0
          strlen(p->subject));
2871
0
    break;
2872
2873
0
  case CP_VALID:   /* not used */
2874
0
    break;
2875
2876
0
  case CP_INITSEQ:
2877
0
    if (NULL == (ap = p->recval.ptr))
2878
0
      break;
2879
2880
0
    ctl_putint(peer_var[CP_INITSEQ].text, ap->seq);
2881
0
    ctl_puthex(peer_var[CP_INITKEY].text, ap->key);
2882
0
    ctl_putfs(peer_var[CP_INITTSP].text,
2883
0
        ntohl(p->recval.tstamp));
2884
0
    break;
2885
2886
0
  case CP_IDENT:
2887
0
    if (p->ident != NULL)
2888
0
      ctl_putstr(peer_var[id].text, p->ident,
2889
0
          strlen(p->ident));
2890
0
    break;
2891
2892
2893
0
#endif  /* AUTOKEY */
2894
0
  }
2895
0
}
2896
2897
2898
#ifdef REFCLOCK
2899
/*
2900
 * ctl_putclock - output clock variables
2901
 */
2902
static void
2903
ctl_putclock(
2904
  int id,
2905
  struct refclockstat *pcs,
2906
  int mustput
2907
  )
2908
0
{
2909
0
  char buf[CTL_MAX_DATA_LEN];
2910
0
  char *s, *t, *be;
2911
0
  const char *ss;
2912
0
  int i;
2913
0
  const struct ctl_var *k;
2914
2915
0
  switch (id) {
2916
2917
0
  case CC_TYPE:
2918
0
    if (mustput || pcs->clockdesc == NULL
2919
0
        || *(pcs->clockdesc) == '\0') {
2920
0
      ctl_putuint(clock_var[id].text, pcs->type);
2921
0
    }
2922
0
    break;
2923
0
  case CC_TIMECODE:
2924
0
    ctl_putstr(clock_var[id].text,
2925
0
         pcs->p_lastcode,
2926
0
         (unsigned)pcs->lencode);
2927
0
    break;
2928
2929
0
  case CC_POLL:
2930
0
    ctl_putuint(clock_var[id].text, pcs->polls);
2931
0
    break;
2932
2933
0
  case CC_NOREPLY:
2934
0
    ctl_putuint(clock_var[id].text,
2935
0
          pcs->noresponse);
2936
0
    break;
2937
2938
0
  case CC_BADFORMAT:
2939
0
    ctl_putuint(clock_var[id].text,
2940
0
          pcs->badformat);
2941
0
    break;
2942
2943
0
  case CC_BADDATA:
2944
0
    ctl_putuint(clock_var[id].text,
2945
0
          pcs->baddata);
2946
0
    break;
2947
2948
0
  case CC_FUDGETIME1:
2949
0
    if (mustput || (pcs->haveflags & CLK_HAVETIME1))
2950
0
      ctl_putdbl(clock_var[id].text,
2951
0
           pcs->fudgetime1 * 1e3);
2952
0
    break;
2953
2954
0
  case CC_FUDGETIME2:
2955
0
    if (mustput || (pcs->haveflags & CLK_HAVETIME2))
2956
0
      ctl_putdbl(clock_var[id].text,
2957
0
           pcs->fudgetime2 * 1e3);
2958
0
    break;
2959
2960
0
  case CC_FUDGEVAL1:
2961
0
    if (mustput || (pcs->haveflags & CLK_HAVEVAL1))
2962
0
      ctl_putint(clock_var[id].text,
2963
0
           pcs->fudgeval1);
2964
0
    break;
2965
2966
0
  case CC_FUDGEVAL2:
2967
    /* RefID of clocks are always text even if stratum is fudged */
2968
0
    if (mustput || (pcs->haveflags & CLK_HAVEVAL2))
2969
0
      ctl_putrefid(clock_var[id].text, pcs->fudgeval2);
2970
0
    break;
2971
2972
0
  case CC_FLAGS:
2973
0
    ctl_putuint(clock_var[id].text, pcs->flags);
2974
0
    break;
2975
2976
0
  case CC_DEVICE:
2977
0
    if (pcs->clockdesc == NULL ||
2978
0
        *(pcs->clockdesc) == '\0') {
2979
0
      if (mustput)
2980
0
        ctl_putstr(clock_var[id].text,
2981
0
             "", 0);
2982
0
    } else {
2983
0
      ctl_putstr(clock_var[id].text,
2984
0
           pcs->clockdesc,
2985
0
           strlen(pcs->clockdesc));
2986
0
    }
2987
0
    break;
2988
2989
0
  case CC_VARLIST:
2990
0
    s = buf;
2991
0
    be = buf + sizeof(buf);
2992
0
    if (strlen(clock_var[CC_VARLIST].text) + 4 >
2993
0
        sizeof(buf))
2994
0
      break; /* really long var name */
2995
2996
0
    snprintf(s, sizeof(buf), "%s=\"",
2997
0
       clock_var[CC_VARLIST].text);
2998
0
    s += strlen(s);
2999
0
    t = s;
3000
3001
0
    for (k = clock_var; !(EOV & k->flags); k++) {
3002
0
      if (PADDING & k->flags)
3003
0
        continue;
3004
3005
0
      i = strlen(k->text);
3006
0
      if (s + i + 1 >= be)
3007
0
        break;
3008
3009
0
      if (s != t)
3010
0
        *s++ = ',';
3011
0
      memcpy(s, k->text, i);
3012
0
      s += i;
3013
0
    }
3014
3015
0
    for (k = pcs->kv_list; k && !(EOV & k->flags); k++) {
3016
0
      if (PADDING & k->flags)
3017
0
        continue;
3018
3019
0
      ss = k->text;
3020
0
      if (NULL == ss)
3021
0
        continue;
3022
3023
0
      while (*ss && *ss != '=')
3024
0
        ss++;
3025
0
      i = ss - k->text;
3026
0
      if (s + i + 1 >= be)
3027
0
        break;
3028
3029
0
      if (s != t)
3030
0
        *s++ = ',';
3031
0
      memcpy(s, k->text, (unsigned)i);
3032
0
      s += i;
3033
0
      *s = '\0';
3034
0
    }
3035
0
    if (s + 2 >= be)
3036
0
      break;
3037
3038
0
    *s++ = '"';
3039
0
    *s = '\0';
3040
0
    ctl_putdata(buf, (unsigned)(s - buf), 0);
3041
0
    break;
3042
    
3043
0
  case CC_FUDGEMINJIT:
3044
0
    if (mustput || (pcs->haveflags & CLK_HAVEMINJIT))
3045
0
      ctl_putdbl(clock_var[id].text,
3046
0
           pcs->fudgeminjitter * 1e3);
3047
0
    break;
3048
3049
0
  default:
3050
0
    break;
3051
3052
0
  }
3053
0
}
3054
#endif
3055
3056
3057
3058
/*
3059
 * ctl_getitem - get the next data item from the incoming packet
3060
 */
3061
static const struct ctl_var *
3062
ctl_getitem(
3063
  const struct ctl_var *var_list,
3064
  char **data
3065
  )
3066
0
{
3067
  /* [Bug 3008] First check the packet data sanity, then search
3068
   * the key. This improves the consistency of result values: If
3069
   * the result is NULL once, it will never be EOV again for this
3070
   * packet; If it's EOV, it will never be NULL again until the
3071
   * variable is found and processed in a given 'var_list'. (That
3072
   * is, a result is returned that is neither NULL nor EOV).
3073
   */
3074
0
  static const struct ctl_var eol = { 0, EOV, NULL };
3075
0
  static char buf[128];
3076
0
  static u_long quiet_until;
3077
0
  const struct ctl_var *v;
3078
0
  char *cp;
3079
0
  char *tp;
3080
3081
  /*
3082
   * Part One: Validate the packet state
3083
   */
3084
3085
  /* Delete leading commas and white space */
3086
0
  while (reqpt < reqend && (*reqpt == ',' ||
3087
0
          isspace((unsigned char)*reqpt)))
3088
0
    reqpt++;
3089
0
  if (reqpt >= reqend)
3090
0
    return NULL;
3091
3092
  /* Scan the string in the packet until we hit comma or
3093
   * EoB. Register position of first '=' on the fly. */
3094
0
  for (tp = NULL, cp = reqpt; cp != reqend; ++cp) {
3095
0
    if (*cp == '=' && tp == NULL)
3096
0
      tp = cp;
3097
0
    if (*cp == ',')
3098
0
      break;
3099
0
  }
3100
3101
  /* Process payload, if any. */
3102
0
  *data = NULL;
3103
0
  if (NULL != tp) {
3104
    /* eventually strip white space from argument. */
3105
0
    const char *plhead = tp + 1; /* skip the '=' */
3106
0
    const char *pltail = cp;
3107
0
    size_t      plsize;
3108
3109
0
    while (plhead != pltail && isspace((u_char)plhead[0]))
3110
0
      ++plhead;
3111
0
    while (plhead != pltail && isspace((u_char)pltail[-1]))
3112
0
      --pltail;
3113
3114
    /* check payload size, terminate packet on overflow */
3115
0
    plsize = (size_t)(pltail - plhead);
3116
0
    if (plsize >= sizeof(buf))
3117
0
      goto badpacket;
3118
3119
    /* copy data, NUL terminate, and set result data ptr */
3120
0
    memcpy(buf, plhead, plsize);
3121
0
    buf[plsize] = '\0';
3122
0
    *data = buf;
3123
0
  } else {
3124
    /* no payload, current end --> current name termination */
3125
0
    tp = cp;
3126
0
  }
3127
3128
  /* Part Two
3129
   *
3130
   * Now we're sure that the packet data itself is sane. Scan the
3131
   * list now. Make sure a NULL list is properly treated by
3132
   * returning a synthetic End-Of-Values record. We must not
3133
   * return NULL pointers after this point, or the behaviour would
3134
   * become inconsistent if called several times with different
3135
   * variable lists after an EoV was returned.  (Such a behavior
3136
   * actually caused Bug 3008.)
3137
   */
3138
3139
0
  if (NULL == var_list)
3140
0
    return &eol;
3141
3142
0
  for (v = var_list; !(EOV & v->flags); ++v)
3143
0
    if (!(PADDING & v->flags)) {
3144
      /* Check if the var name matches the buffer. The
3145
       * name is bracketed by [reqpt..tp] and not NUL
3146
       * terminated, and it contains no '=' char. The
3147
       * lookup value IS NUL-terminated but might
3148
       * include a '='... We have to look out for
3149
       * that!
3150
       */
3151
0
      const char *sp1 = reqpt;
3152
0
      const char *sp2 = v->text;
3153
3154
      /* [Bug 3412] do not compare past NUL byte in name */
3155
0
      while (   (sp1 != tp)
3156
0
             && ('\0' != *sp2) && (*sp1 == *sp2)) {
3157
0
        ++sp1;
3158
0
        ++sp2;
3159
0
      }
3160
0
      if (sp1 == tp && (*sp2 == '\0' || *sp2 == '='))
3161
0
        break;
3162
0
    }
3163
3164
  /* See if we have found a valid entry or not. If found, advance
3165
   * the request pointer for the next round; if not, clear the
3166
   * data pointer so we have no dangling garbage here.
3167
   */
3168
0
  if (EOV & v->flags)
3169
0
    *data = NULL;
3170
0
  else
3171
0
    reqpt = cp + (cp != reqend);
3172
0
  return v;
3173
3174
0
  badpacket:
3175
  /*TODO? somehow indicate this packet was bad, apart from syslog? */
3176
0
  numctlbadpkts++;
3177
0
  NLOG(NLOG_SYSEVENT)
3178
0
      if (quiet_until <= current_time) {
3179
0
        quiet_until = current_time + 300;
3180
0
        msyslog(LOG_WARNING,
3181
0
          "Possible 'ntpdx' exploit from %s (possibly spoofed)",
3182
0
          sptoa(rmt_addr));
3183
0
      }
3184
0
  reqpt = reqend; /* never again for this packet! */
3185
0
  return NULL;
3186
0
}
3187
3188
3189
/*
3190
 * control_unspec - response to an unspecified op-code
3191
 */
3192
/*ARGSUSED*/
3193
static void
3194
control_unspec(
3195
  struct recvbuf *rbufp,
3196
  int restrict_mask
3197
  )
3198
0
{
3199
0
  struct peer *peer;
3200
3201
  /*
3202
   * What is an appropriate response to an unspecified op-code?
3203
   * I return no errors and no data, unless a specified assocation
3204
   * doesn't exist.
3205
   */
3206
0
  if (res_associd) {
3207
0
    peer = findpeerbyassoc(res_associd);
3208
0
    if (NULL == peer) {
3209
0
      ctl_error(CERR_BADASSOC);
3210
0
      return;
3211
0
    }
3212
0
    rpkt.status = htons(ctlpeerstatus(peer));
3213
0
  } else
3214
0
    rpkt.status = htons(ctlsysstatus());
3215
0
  ctl_flushpkt(0);
3216
0
}
3217
3218
3219
/*
3220
 * read_status - return either a list of associd's, or a particular
3221
 * peer's status.
3222
 */
3223
/*ARGSUSED*/
3224
static void
3225
read_status(
3226
  struct recvbuf *rbufp,
3227
  int restrict_mask
3228
  )
3229
0
{
3230
0
  struct peer *peer;
3231
0
  const u_char *cp;
3232
0
  size_t n;
3233
  /* a_st holds association ID, status pairs alternating */
3234
0
  u_short a_st[CTL_MAX_DATA_LEN / sizeof(u_short)];
3235
3236
0
#ifdef DEBUG
3237
0
  if (debug > 2)
3238
0
    printf("read_status: ID %d\n", res_associd);
3239
0
#endif
3240
  /*
3241
   * Two choices here. If the specified association ID is
3242
   * zero we return all known assocation ID's.  Otherwise
3243
   * we return a bunch of stuff about the particular peer.
3244
   */
3245
0
  if (res_associd) {
3246
0
    peer = findpeerbyassoc(res_associd);
3247
0
    if (NULL == peer) {
3248
0
      ctl_error(CERR_BADASSOC);
3249
0
      return;
3250
0
    }
3251
0
    rpkt.status = htons(ctlpeerstatus(peer));
3252
0
    if (res_authokay)
3253
0
      peer->num_events = 0;
3254
    /*
3255
     * For now, output everything we know about the
3256
     * peer. May be more selective later.
3257
     */
3258
0
    for (cp = def_peer_var; *cp != 0; cp++)
3259
0
      ctl_putpeer((int)*cp, peer);
3260
0
    ctl_flushpkt(0);
3261
0
    return;
3262
0
  }
3263
0
  n = 0;
3264
0
  rpkt.status = htons(ctlsysstatus());
3265
0
  for (peer = peer_list; peer != NULL; peer = peer->p_link) {
3266
0
    a_st[n++] = htons(peer->associd);
3267
0
    a_st[n++] = htons(ctlpeerstatus(peer));
3268
    /* two entries each loop iteration, so n + 1 */
3269
0
    if (n + 1 >= COUNTOF(a_st)) {
3270
0
      ctl_putdata((void *)a_st, n * sizeof(a_st[0]),
3271
0
            1);
3272
0
      n = 0;
3273
0
    }
3274
0
  }
3275
0
  if (n)
3276
0
    ctl_putdata((void *)a_st, n * sizeof(a_st[0]), 1);
3277
0
  ctl_flushpkt(0);
3278
0
}
3279
3280
3281
/*
3282
 * read_peervars - half of read_variables() implementation
3283
 */
3284
static void
3285
read_peervars(void)
3286
0
{
3287
0
  const struct ctl_var *v;
3288
0
  struct peer *peer;
3289
0
  const u_char *cp;
3290
0
  size_t i;
3291
0
  char *  valuep;
3292
0
  u_char  wants[CP_MAXCODE + 1];
3293
0
  u_int gotvar;
3294
3295
  /*
3296
   * Wants info for a particular peer. See if we know
3297
   * the guy.
3298
   */
3299
0
  peer = findpeerbyassoc(res_associd);
3300
0
  if (NULL == peer) {
3301
0
    ctl_error(CERR_BADASSOC);
3302
0
    return;
3303
0
  }
3304
0
  rpkt.status = htons(ctlpeerstatus(peer));
3305
0
  if (res_authokay)
3306
0
    peer->num_events = 0;
3307
0
  ZERO(wants);
3308
0
  gotvar = 0;
3309
0
  while (NULL != (v = ctl_getitem(peer_var, &valuep))) {
3310
0
    if (v->flags & EOV) {
3311
0
      ctl_error(CERR_UNKNOWNVAR);
3312
0
      return;
3313
0
    }
3314
0
    INSIST(v->code < COUNTOF(wants));
3315
0
    wants[v->code] = 1;
3316
0
    gotvar = 1;
3317
0
  }
3318
0
  if (gotvar) {
3319
0
    for (i = 1; i < COUNTOF(wants); i++)
3320
0
      if (wants[i])
3321
0
        ctl_putpeer(i, peer);
3322
0
  } else
3323
0
    for (cp = def_peer_var; *cp != 0; cp++)
3324
0
      ctl_putpeer((int)*cp, peer);
3325
0
  ctl_flushpkt(0);
3326
0
}
3327
3328
3329
/*
3330
 * read_sysvars - half of read_variables() implementation
3331
 */
3332
static void
3333
read_sysvars(void)
3334
0
{
3335
0
  const struct ctl_var *v;
3336
0
  struct ctl_var *kv;
3337
0
  u_int n;
3338
0
  u_int gotvar;
3339
0
  const u_char *cs;
3340
0
  char *  valuep;
3341
0
  const char * pch;
3342
0
  u_char *wants;
3343
0
  size_t  wants_count;
3344
3345
  /*
3346
   * Wants system variables. Figure out which he wants
3347
   * and give them to him.
3348
   */
3349
0
  rpkt.status = htons(ctlsysstatus());
3350
0
  if (res_authokay)
3351
0
    ctl_sys_num_events = 0;
3352
0
  wants_count = CS_MAXCODE + 1 + count_var(ext_sys_var);
3353
0
  wants = emalloc_zero(wants_count);
3354
0
  gotvar = 0;
3355
0
  while (NULL != (v = ctl_getitem(sys_var, &valuep))) {
3356
0
    if (!(EOV & v->flags)) {
3357
0
      INSIST(v->code < wants_count);
3358
0
      wants[v->code] = 1;
3359
0
      gotvar = 1;
3360
0
    } else {
3361
0
      v = ctl_getitem(ext_sys_var, &valuep);
3362
0
      if (NULL == v) {
3363
0
        ctl_error(CERR_BADVALUE);
3364
0
        free(wants);
3365
0
        return;
3366
0
      }
3367
0
      if (EOV & v->flags) {
3368
0
        ctl_error(CERR_UNKNOWNVAR);
3369
0
        free(wants);
3370
0
        return;
3371
0
      }
3372
0
      n = v->code + CS_MAXCODE + 1;
3373
0
      INSIST(n < wants_count);
3374
0
      wants[n] = 1;
3375
0
      gotvar = 1;
3376
0
    }
3377
0
  }
3378
0
  if (gotvar) {
3379
0
    for (n = 1; n <= CS_MAXCODE; n++)
3380
0
      if (wants[n])
3381
0
        ctl_putsys(n);
3382
0
    for (n = 0; n + CS_MAXCODE + 1 < wants_count; n++)
3383
0
      if (wants[n + CS_MAXCODE + 1]) {
3384
0
        pch = ext_sys_var[n].text;
3385
0
        ctl_putdata(pch, strlen(pch), 0);
3386
0
      }
3387
0
  } else {
3388
0
    for (cs = def_sys_var; *cs != 0; cs++)
3389
0
      ctl_putsys((int)*cs);
3390
0
    for (kv = ext_sys_var; kv && !(EOV & kv->flags); kv++)
3391
0
      if (DEF & kv->flags)
3392
0
        ctl_putdata(kv->text, strlen(kv->text),
3393
0
              0);
3394
0
  }
3395
0
  free(wants);
3396
0
  ctl_flushpkt(0);
3397
0
}
3398
3399
3400
/*
3401
 * read_variables - return the variables the caller asks for
3402
 */
3403
/*ARGSUSED*/
3404
static void
3405
read_variables(
3406
  struct recvbuf *rbufp,
3407
  int restrict_mask
3408
  )
3409
0
{
3410
0
  if (res_associd)
3411
0
    read_peervars();
3412
0
  else
3413
0
    read_sysvars();
3414
0
}
3415
3416
3417
/*
3418
 * write_variables - write into variables. We only allow leap bit
3419
 * writing this way.
3420
 */
3421
/*ARGSUSED*/
3422
static void
3423
write_variables(
3424
  struct recvbuf *rbufp,
3425
  int restrict_mask
3426
  )
3427
0
{
3428
0
  const struct ctl_var *v;
3429
0
  int ext_var;
3430
0
  char *valuep;
3431
0
  long val;
3432
0
  size_t octets;
3433
0
  char *vareqv;
3434
0
  const char *t;
3435
0
  char *tt;
3436
3437
0
  val = 0;
3438
  /*
3439
   * If he's trying to write into a peer tell him no way
3440
   */
3441
0
  if (res_associd != 0) {
3442
0
    ctl_error(CERR_PERMISSION);
3443
0
    return;
3444
0
  }
3445
3446
  /*
3447
   * Set status
3448
   */
3449
0
  rpkt.status = htons(ctlsysstatus());
3450
3451
  /*
3452
   * Look through the variables. Dump out at the first sign of
3453
   * trouble.
3454
   */
3455
0
  while ((v = ctl_getitem(sys_var, &valuep)) != NULL) {
3456
0
    ext_var = 0;
3457
0
    if (v->flags & EOV) {
3458
0
      v = ctl_getitem(ext_sys_var, &valuep);
3459
0
      if (v != NULL) {
3460
0
        if (v->flags & EOV) {
3461
0
          ctl_error(CERR_UNKNOWNVAR);
3462
0
          return;
3463
0
        }
3464
0
        ext_var = 1;
3465
0
      } else {
3466
0
        break;
3467
0
      }
3468
0
    }
3469
0
    if (!(v->flags & CAN_WRITE)) {
3470
0
      ctl_error(CERR_PERMISSION);
3471
0
      return;
3472
0
    }
3473
    /* [bug 3565] writing makes sense only if we *have* a
3474
     * value in the packet!
3475
     */
3476
0
    if (valuep == NULL) {
3477
0
      ctl_error(CERR_BADFMT);
3478
0
      return;
3479
0
    }
3480
0
    if (!ext_var) {
3481
0
      if ( !(*valuep && atoint(valuep, &val))) {
3482
0
        ctl_error(CERR_BADFMT);
3483
0
        return;
3484
0
      }
3485
0
      if ((val & ~LEAP_NOTINSYNC) != 0) {
3486
0
        ctl_error(CERR_BADVALUE);
3487
0
        return;
3488
0
      }
3489
0
    }
3490
    
3491
0
    if (ext_var) {
3492
0
      octets = strlen(v->text) + strlen(valuep) + 2;
3493
0
      vareqv = emalloc(octets);
3494
0
      tt = vareqv;
3495
0
      t = v->text;
3496
0
      while (*t && *t != '=')
3497
0
        *tt++ = *t++;
3498
0
      *tt++ = '=';
3499
0
      memcpy(tt, valuep, 1 + strlen(valuep));
3500
0
      set_sys_var(vareqv, 1 + strlen(vareqv), v->flags);
3501
0
      free(vareqv);
3502
0
    } else {
3503
0
      ctl_error(CERR_UNSPEC); /* really */
3504
0
      return;
3505
0
    }
3506
0
  }
3507
3508
  /*
3509
   * If we got anything, do it. xxx nothing to do ***
3510
   */
3511
  /*
3512
    if (leapind != ~0 || leapwarn != ~0) {
3513
    if (!leap_setleap((int)leapind, (int)leapwarn)) {
3514
    ctl_error(CERR_PERMISSION);
3515
    return;
3516
    }
3517
    }
3518
  */
3519
0
  ctl_flushpkt(0);
3520
0
}
3521
3522
3523
/*
3524
 * configure() processes ntpq :config/config-from-file, allowing
3525
 *    generic runtime reconfiguration.
3526
 */
3527
static void configure(
3528
  struct recvbuf *rbufp,
3529
  int restrict_mask
3530
  )
3531
0
{
3532
0
  size_t data_count;
3533
0
  int retval;
3534
3535
  /* I haven't yet implemented changes to an existing association.
3536
   * Hence check if the association id is 0
3537
   */
3538
0
  if (res_associd != 0) {
3539
0
    ctl_error(CERR_BADVALUE);
3540
0
    return;
3541
0
  }
3542
3543
0
  if (RES_NOMODIFY & restrict_mask) {
3544
0
    snprintf(remote_config.err_msg,
3545
0
       sizeof(remote_config.err_msg),
3546
0
       "runtime configuration prohibited by restrict ... nomodify");
3547
0
    ctl_putdata(remote_config.err_msg,
3548
0
          strlen(remote_config.err_msg), 0);
3549
0
    ctl_flushpkt(0);
3550
0
    NLOG(NLOG_SYSINFO)
3551
0
      msyslog(LOG_NOTICE,
3552
0
        "runtime config from %s rejected due to nomodify restriction",
3553
0
        stoa(&rbufp->recv_srcadr));
3554
0
    sys_restricted++;
3555
0
    return;
3556
0
  }
3557
3558
  /* Initialize the remote config buffer */
3559
0
  data_count = remoteconfig_cmdlength(reqpt, reqend);
3560
3561
0
  if (data_count > sizeof(remote_config.buffer) - 2) {
3562
0
    snprintf(remote_config.err_msg,
3563
0
       sizeof(remote_config.err_msg),
3564
0
       "runtime configuration failed: request too long");
3565
0
    ctl_putdata(remote_config.err_msg,
3566
0
          strlen(remote_config.err_msg), 0);
3567
0
    ctl_flushpkt(0);
3568
0
    msyslog(LOG_NOTICE,
3569
0
      "runtime config from %s rejected: request too long",
3570
0
      stoa(&rbufp->recv_srcadr));
3571
0
    return;
3572
0
  }
3573
  /* Bug 2853 -- check if all characters were acceptable */
3574
0
  if (data_count != (size_t)(reqend - reqpt)) {
3575
0
    snprintf(remote_config.err_msg,
3576
0
       sizeof(remote_config.err_msg),
3577
0
       "runtime configuration failed: request contains an unprintable character");
3578
0
    ctl_putdata(remote_config.err_msg,
3579
0
          strlen(remote_config.err_msg), 0);
3580
0
    ctl_flushpkt(0);
3581
0
    msyslog(LOG_NOTICE,
3582
0
      "runtime config from %s rejected: request contains an unprintable character: %0x",
3583
0
      stoa(&rbufp->recv_srcadr),
3584
0
      reqpt[data_count]);
3585
0
    return;
3586
0
  }
3587
3588
0
  memcpy(remote_config.buffer, reqpt, data_count);
3589
  /* The buffer has no trailing linefeed or NUL right now. For
3590
   * logging, we do not want a newline, so we do that first after
3591
   * adding the necessary NUL byte.
3592
   */
3593
0
  remote_config.buffer[data_count] = '\0';
3594
0
  DPRINTF(1, ("Got Remote Configuration Command: %s\n",
3595
0
    remote_config.buffer));
3596
0
  msyslog(LOG_NOTICE, "%s config: %s",
3597
0
    stoa(&rbufp->recv_srcadr),
3598
0
    remote_config.buffer);
3599
3600
  /* Now we have to make sure there is a NL/NUL sequence at the
3601
   * end of the buffer before we parse it.
3602
   */
3603
0
  remote_config.buffer[data_count++] = '\n';
3604
0
  remote_config.buffer[data_count] = '\0';
3605
0
  remote_config.pos = 0;
3606
0
  remote_config.err_pos = 0;
3607
0
  remote_config.no_errors = 0;
3608
0
  config_remotely(&rbufp->recv_srcadr);
3609
3610
  /*
3611
   * Check if errors were reported. If not, output 'Config
3612
   * Succeeded'.  Else output the error count.  It would be nice
3613
   * to output any parser error messages.
3614
   */
3615
0
  if (0 == remote_config.no_errors) {
3616
0
    retval = snprintf(remote_config.err_msg,
3617
0
          sizeof(remote_config.err_msg),
3618
0
          "Config Succeeded");
3619
0
    if (retval > 0)
3620
0
      remote_config.err_pos += retval;
3621
0
  }
3622
3623
0
  ctl_putdata(remote_config.err_msg, remote_config.err_pos, 0);
3624
0
  ctl_flushpkt(0);
3625
3626
0
  DPRINTF(1, ("Reply: %s\n", remote_config.err_msg));
3627
3628
0
  if (remote_config.no_errors > 0)
3629
0
    msyslog(LOG_NOTICE, "%d error in %s config",
3630
0
      remote_config.no_errors,
3631
0
      stoa(&rbufp->recv_srcadr));
3632
0
}
3633
3634
3635
/*
3636
 * derive_nonce - generate 32-bit nonce value derived from the client
3637
 *      address and a request-specific timestamp.
3638
 *
3639
 * This uses MD5 for a non-authentication purpose -- the nonce is used
3640
 * analogous to the TCP 3-way handshake to confirm the UDP client can
3641
 * receive traffic from which it claims to originate, that is, to
3642
 * prevent spoofed requests leading to reflected amplification.
3643
 */
3644
static u_int32 derive_nonce(
3645
  sockaddr_u *  addr,
3646
  u_int32   ts_i,
3647
  u_int32   ts_f
3648
  )
3649
0
{
3650
0
  static u_int32  salt[4];
3651
0
  static u_long last_salt_update;
3652
0
  MD5_CTX   ctx;
3653
0
  union d_tag {
3654
0
    u_char  digest[MD5_DIGEST_LENGTH];
3655
0
    u_int32 extract;
3656
0
  }   d;
3657
3658
0
  while (!salt[0] || current_time - last_salt_update >= 3600) {
3659
0
    salt[0] = ntp_random();
3660
0
    salt[1] = ntp_random();
3661
0
    salt[2] = ntp_random();
3662
0
    salt[3] = ntp_random();
3663
0
    last_salt_update = current_time;
3664
0
  }
3665
3666
0
  MD5Init(&ctx);
3667
0
  MD5Update(&ctx, salt, sizeof(salt));
3668
0
  MD5Update(&ctx, &ts_i, sizeof(ts_i));
3669
0
  MD5Update(&ctx, &ts_f, sizeof(ts_f));
3670
0
  if (IS_IPV4(addr)) {
3671
0
    MD5Update(&ctx, &SOCK_ADDR4(addr), sizeof(SOCK_ADDR4(addr)));
3672
0
  } else {
3673
0
    MD5Update(&ctx, &SOCK_ADDR6(addr), sizeof(SOCK_ADDR6(addr)));
3674
0
  }
3675
0
  MD5Update(&ctx, &NSRCPORT(addr), sizeof(NSRCPORT(addr)));
3676
0
  MD5Update(&ctx, salt, sizeof(salt));
3677
0
  MD5Final(d.digest, &ctx);
3678
3679
0
  return d.extract;
3680
0
}
3681
3682
3683
/*
3684
 * generate_nonce - generate client-address-specific nonce string.
3685
 */
3686
static void generate_nonce(
3687
  struct recvbuf *  rbufp,
3688
  char *      nonce,
3689
  size_t      nonce_octets
3690
  )
3691
0
{
3692
0
  u_int32 derived;
3693
3694
0
  derived = derive_nonce(&rbufp->recv_srcadr,
3695
0
             rbufp->recv_time.l_ui,
3696
0
             rbufp->recv_time.l_uf);
3697
0
  snprintf(nonce, nonce_octets, "%08x%08x%08x",
3698
0
     rbufp->recv_time.l_ui, rbufp->recv_time.l_uf, derived);
3699
0
}
3700
3701
3702
/*
3703
 * validate_nonce - validate client-address-specific nonce string.
3704
 *
3705
 * Returns TRUE if the local calculation of the nonce matches the
3706
 * client-provided value and the timestamp is recent enough.
3707
 */
3708
static int validate_nonce(
3709
  const char *    pnonce,
3710
  struct recvbuf *  rbufp
3711
  )
3712
0
{
3713
0
  u_int ts_i;
3714
0
  u_int ts_f;
3715
0
  l_fp  ts;
3716
0
  l_fp  now_delta;
3717
0
  u_int supposed;
3718
0
  u_int derived;
3719
3720
0
  if (3 != sscanf(pnonce, "%08x%08x%08x", &ts_i, &ts_f, &supposed))
3721
0
    return FALSE;
3722
3723
0
  ts.l_ui = (u_int32)ts_i;
3724
0
  ts.l_uf = (u_int32)ts_f;
3725
0
  derived = derive_nonce(&rbufp->recv_srcadr, ts.l_ui, ts.l_uf);
3726
0
  get_systime(&now_delta);
3727
0
  L_SUB(&now_delta, &ts);
3728
3729
0
  return (supposed == derived && now_delta.l_ui < 16);
3730
0
}
3731
3732
3733
/*
3734
 * send_random_tag_value - send a randomly-generated three character
3735
 *         tag prefix, a '.', an index, a '=' and a
3736
 *         random integer value.
3737
 *
3738
 * To try to force clients to ignore unrecognized tags in mrulist,
3739
 * reslist, and ifstats responses, the first and last rows are spiced
3740
 * with randomly-generated tag names with correct .# index.  Make it
3741
 * three characters knowing that none of the currently-used subscripted
3742
 * tags have that length, avoiding the need to test for
3743
 * tag collision.
3744
 */
3745
static void
3746
send_random_tag_value(
3747
  int indx
3748
  )
3749
0
{
3750
0
  int noise;
3751
0
  char  buf[32];
3752
3753
0
  noise = rand() ^ (rand() << 16);
3754
0
  buf[0] = 'a' + noise % 26;
3755
0
  noise >>= 5;
3756
0
  buf[1] = 'a' + noise % 26;
3757
0
  noise >>= 5;
3758
0
  buf[2] = 'a' + noise % 26;
3759
0
  noise >>= 5;
3760
0
  buf[3] = '.';
3761
0
  snprintf(&buf[4], sizeof(buf) - 4, "%d", indx);
3762
0
  ctl_putuint(buf, noise);
3763
0
}
3764
3765
3766
/*
3767
 * Send a MRU list entry in response to a "ntpq -c mrulist" operation.
3768
 *
3769
 * To keep clients honest about not depending on the order of values,
3770
 * and thereby avoid being locked into ugly workarounds to maintain
3771
 * backward compatibility later as new fields are added to the response,
3772
 * the order is random.
3773
 */
3774
static void
3775
send_mru_entry(
3776
  mon_entry * mon,
3777
  int   count
3778
  )
3779
0
{
3780
0
  const char first_fmt[] =  "first.%d";
3781
0
  const char ct_fmt[] =   "ct.%d";
3782
0
  const char mv_fmt[] =   "mv.%d";
3783
0
  const char rs_fmt[] =   "rs.%d";
3784
0
  char  tag[32];
3785
0
  u_char  sent[6]; /* 6 tag=value pairs */
3786
0
  u_int32 noise;
3787
0
  u_int which;
3788
0
  u_int remaining;
3789
0
  const char * pch;
3790
3791
0
  remaining = COUNTOF(sent);
3792
0
  ZERO(sent);
3793
0
  noise = (u_int32)(rand() ^ (rand() << 16));
3794
0
  while (remaining > 0) {
3795
0
    which = (noise & 7) % COUNTOF(sent);
3796
0
    noise >>= 3;
3797
0
    while (sent[which])
3798
0
      which = (which + 1) % COUNTOF(sent);
3799
3800
0
    switch (which) {
3801
3802
0
    case 0:
3803
0
      snprintf(tag, sizeof(tag), addr_fmt, count);
3804
0
      pch = sptoa(&mon->rmtadr);
3805
0
      ctl_putunqstr(tag, pch, strlen(pch));
3806
0
      break;
3807
3808
0
    case 1:
3809
0
      snprintf(tag, sizeof(tag), last_fmt, count);
3810
0
      ctl_putts(tag, &mon->last);
3811
0
      break;
3812
3813
0
    case 2:
3814
0
      snprintf(tag, sizeof(tag), first_fmt, count);
3815
0
      ctl_putts(tag, &mon->first);
3816
0
      break;
3817
3818
0
    case 3:
3819
0
      snprintf(tag, sizeof(tag), ct_fmt, count);
3820
0
      ctl_putint(tag, mon->count);
3821
0
      break;
3822
3823
0
    case 4:
3824
0
      snprintf(tag, sizeof(tag), mv_fmt, count);
3825
0
      ctl_putuint(tag, mon->vn_mode);
3826
0
      break;
3827
3828
0
    case 5:
3829
0
      snprintf(tag, sizeof(tag), rs_fmt, count);
3830
0
      ctl_puthex(tag, mon->flags);
3831
0
      break;
3832
0
    }
3833
0
    sent[which] = TRUE;
3834
0
    remaining--;
3835
0
  }
3836
0
}
3837
3838
3839
/*
3840
 * read_mru_list - supports ntpq's mrulist command.
3841
 *
3842
 * The challenge here is to match ntpdc's monlist functionality without
3843
 * being limited to hundreds of entries returned total, and without
3844
 * requiring state on the server.  If state were required, ntpq's
3845
 * mrulist command would require authentication.
3846
 *
3847
 * The approach was suggested by Ry Jones.  A finite and variable number
3848
 * of entries are retrieved per request, to avoid having responses with
3849
 * such large numbers of packets that socket buffers are overflowed and
3850
 * packets lost.  The entries are retrieved oldest-first, taking into
3851
 * account that the MRU list will be changing between each request.  We
3852
 * can expect to see duplicate entries for addresses updated in the MRU
3853
 * list during the fetch operation.  In the end, the client can assemble
3854
 * a close approximation of the MRU list at the point in time the last
3855
 * response was sent by ntpd.  The only difference is it may be longer,
3856
 * containing some number of oldest entries which have since been
3857
 * reclaimed.  If necessary, the protocol could be extended to zap those
3858
 * from the client snapshot at the end, but so far that doesn't seem
3859
 * useful.
3860
 *
3861
 * To accomodate the changing MRU list, the starting point for requests
3862
 * after the first request is supplied as a series of last seen
3863
 * timestamps and associated addresses, the newest ones the client has
3864
 * received.  As long as at least one of those entries hasn't been
3865
 * bumped to the head of the MRU list, ntpd can pick up at that point.
3866
 * Otherwise, the request is failed and it is up to ntpq to back up and
3867
 * provide the next newest entry's timestamps and addresses, conceivably
3868
 * backing up all the way to the starting point.
3869
 *
3870
 * input parameters:
3871
 *  nonce=    Regurgitated nonce retrieved by the client
3872
 *      previously using CTL_OP_REQ_NONCE, demonstrating
3873
 *      ability to receive traffic sent to its address.
3874
 *  frags=    Limit on datagrams (fragments) in response.  Used
3875
 *      by newer ntpq versions instead of limit= when
3876
 *      retrieving multiple entries.
3877
 *  limit=    Limit on MRU entries returned.  One of frags= or
3878
 *      limit= must be provided.
3879
 *      limit=1 is a special case:  Instead of fetching
3880
 *      beginning with the supplied starting point's
3881
 *      newer neighbor, fetch the supplied entry, and
3882
 *      in that case the #.last timestamp can be zero.
3883
 *      This enables fetching a single entry by IP
3884
 *      address.  When limit is not one and frags= is
3885
 *      provided, the fragment limit controls.
3886
 *  mincount= (decimal) Return entries with count >= mincount.
3887
 *  laddr=    Return entries associated with the server's IP
3888
 *      address given.  No port specification is needed,
3889
 *      and any supplied is ignored.
3890
 *  resall=   0x-prefixed hex restrict bits which must all be
3891
 *      lit for an MRU entry to be included.
3892
 *      Has precedence over any resany=.
3893
 *  resany=   0x-prefixed hex restrict bits, at least one of
3894
 *      which must be list for an MRU entry to be
3895
 *      included.
3896
 *  last.0=   0x-prefixed hex l_fp timestamp of newest entry
3897
 *      which client previously received.
3898
 *  addr.0=   text of newest entry's IP address and port,
3899
 *      IPv6 addresses in bracketed form: [::]:123
3900
 *  last.1=   timestamp of 2nd newest entry client has.
3901
 *  addr.1=   address of 2nd newest entry.
3902
 *  [...]
3903
 *
3904
 * ntpq provides as many last/addr pairs as will fit in a single request
3905
 * packet, except for the first request in a MRU fetch operation.
3906
 *
3907
 * The response begins with a new nonce value to be used for any
3908
 * followup request.  Following the nonce is the next newer entry than
3909
 * referred to by last.0 and addr.0, if the "0" entry has not been
3910
 * bumped to the front.  If it has, the first entry returned will be the
3911
 * next entry newer than referred to by last.1 and addr.1, and so on.
3912
 * If none of the referenced entries remain unchanged, the request fails
3913
 * and ntpq backs up to the next earlier set of entries to resync.
3914
 *
3915
 * Except for the first response, the response begins with confirmation
3916
 * of the entry that precedes the first additional entry provided:
3917
 *
3918
 *  last.older= hex l_fp timestamp matching one of the input
3919
 *      .last timestamps, which entry now precedes the
3920
 *      response 0. entry in the MRU list.
3921
 *  addr.older= text of address corresponding to older.last.
3922
 *
3923
 * And in any case, a successful response contains sets of values
3924
 * comprising entries, with the oldest numbered 0 and incrementing from
3925
 * there:
3926
 *
3927
 *  addr.#    text of IPv4 or IPv6 address and port
3928
 *  last.#    hex l_fp timestamp of last receipt
3929
 *  first.#   hex l_fp timestamp of first receipt
3930
 *  ct.#    count of packets received
3931
 *  mv.#    mode and version
3932
 *  rs.#    restriction mask (RES_* bits)
3933
 *
3934
 * Note the code currently assumes there are no valid three letter
3935
 * tags sent with each row, and needs to be adjusted if that changes.
3936
 *
3937
 * The client should accept the values in any order, and ignore .#
3938
 * values which it does not understand, to allow a smooth path to
3939
 * future changes without requiring a new opcode.  Clients can rely
3940
 * on all *.0 values preceding any *.1 values, that is all values for
3941
 * a given index number are together in the response.
3942
 *
3943
 * The end of the response list is noted with one or two tag=value
3944
 * pairs.  Unconditionally:
3945
 *
3946
 *  now=    0x-prefixed l_fp timestamp at the server marking
3947
 *      the end of the operation.
3948
 *
3949
 * If any entries were returned, now= is followed by:
3950
 *
3951
 *  last.newest=  hex l_fp identical to last.# of the prior
3952
 *      entry.
3953
 */
3954
static void read_mru_list(
3955
  struct recvbuf *rbufp,
3956
  int restrict_mask
3957
  )
3958
0
{
3959
0
  static const char nulltxt[1] =    { '\0' };
3960
0
  static const char nonce_text[] =    "nonce";
3961
0
  static const char frags_text[] =    "frags";
3962
0
  static const char limit_text[] =    "limit";
3963
0
  static const char mincount_text[] = "mincount";
3964
0
  static const char resall_text[] =   "resall";
3965
0
  static const char resany_text[] =   "resany";
3966
0
  static const char maxlstint_text[] =  "maxlstint";
3967
0
  static const char laddr_text[] =    "laddr";
3968
0
  static const char resaxx_fmt[] =    "0x%hx";
3969
3970
0
  u_int     limit;
3971
0
  u_short     frags;
3972
0
  u_short     resall;
3973
0
  u_short     resany;
3974
0
  int     mincount;
3975
0
  u_int     maxlstint;
3976
0
  sockaddr_u    laddr;
3977
0
  endpt *     lcladr;
3978
0
  u_int     count;
3979
0
  u_int     ui;
3980
0
  u_int     uf;
3981
0
  l_fp      last[16];
3982
0
  sockaddr_u    addr[COUNTOF(last)];
3983
0
  char      buf[128];
3984
0
  struct ctl_var *  in_parms;
3985
0
  const struct ctl_var *  v;
3986
0
  const char *    val;
3987
0
  const char *    pch;
3988
0
  char *      pnonce;
3989
0
  int     nonce_valid;
3990
0
  size_t      i;
3991
0
  int     priors;
3992
0
  u_short     hash;
3993
0
  mon_entry *   mon;
3994
0
  mon_entry *   prior_mon;
3995
0
  l_fp      now;
3996
3997
0
  if (RES_NOMRULIST & restrict_mask) {
3998
0
    ctl_error(CERR_PERMISSION);
3999
0
    NLOG(NLOG_SYSINFO)
4000
0
      msyslog(LOG_NOTICE,
4001
0
        "mrulist from %s rejected due to nomrulist restriction",
4002
0
        stoa(&rbufp->recv_srcadr));
4003
0
    sys_restricted++;
4004
0
    return;
4005
0
  }
4006
  /*
4007
   * fill in_parms var list with all possible input parameters.
4008
   */
4009
0
  in_parms = NULL;
4010
0
  set_var(&in_parms, nonce_text, sizeof(nonce_text), 0);
4011
0
  set_var(&in_parms, frags_text, sizeof(frags_text), 0);
4012
0
  set_var(&in_parms, limit_text, sizeof(limit_text), 0);
4013
0
  set_var(&in_parms, mincount_text, sizeof(mincount_text), 0);
4014
0
  set_var(&in_parms, resall_text, sizeof(resall_text), 0);
4015
0
  set_var(&in_parms, resany_text, sizeof(resany_text), 0);
4016
0
  set_var(&in_parms, maxlstint_text, sizeof(maxlstint_text), 0);
4017
0
  set_var(&in_parms, laddr_text, sizeof(laddr_text), 0);
4018
0
  for (i = 0; i < COUNTOF(last); i++) {
4019
0
    snprintf(buf, sizeof(buf), last_fmt, (int)i);
4020
0
    set_var(&in_parms, buf, strlen(buf) + 1, 0);
4021
0
    snprintf(buf, sizeof(buf), addr_fmt, (int)i);
4022
0
    set_var(&in_parms, buf, strlen(buf) + 1, 0);
4023
0
  }
4024
4025
  /* decode input parms */
4026
0
  pnonce = NULL;
4027
0
  frags = 0;
4028
0
  limit = 0;
4029
0
  mincount = 0;
4030
0
  resall = 0;
4031
0
  resany = 0;
4032
0
  maxlstint = 0;
4033
0
  lcladr = NULL;
4034
0
  priors = 0;
4035
0
  ZERO(last);
4036
0
  ZERO(addr);
4037
4038
  /* have to go through '(void*)' to drop 'const' property from pointer.
4039
   * ctl_getitem()' needs some cleanup, too.... perlinger@ntp.org
4040
   */
4041
0
  while (NULL != (v = ctl_getitem(in_parms, (void*)&val)) &&
4042
0
         !(EOV & v->flags)) {
4043
0
    int si;
4044
4045
0
    if (NULL == val)
4046
0
      val = nulltxt;
4047
4048
0
    if (!strcmp(nonce_text, v->text)) {
4049
0
      free(pnonce);
4050
0
      pnonce = (*val) ? estrdup(val) : NULL;
4051
0
    } else if (!strcmp(frags_text, v->text)) {
4052
0
      if (1 != sscanf(val, "%hu", &frags))
4053
0
        goto blooper;
4054
0
    } else if (!strcmp(limit_text, v->text)) {
4055
0
      if (1 != sscanf(val, "%u", &limit))
4056
0
        goto blooper;
4057
0
    } else if (!strcmp(mincount_text, v->text)) {
4058
0
      if (1 != sscanf(val, "%d", &mincount))
4059
0
        goto blooper;
4060
0
      if (mincount < 0)
4061
0
        mincount = 0;
4062
0
    } else if (!strcmp(resall_text, v->text)) {
4063
0
      if (1 != sscanf(val, resaxx_fmt, &resall))
4064
0
        goto blooper;
4065
0
    } else if (!strcmp(resany_text, v->text)) {
4066
0
      if (1 != sscanf(val, resaxx_fmt, &resany))
4067
0
        goto blooper;
4068
0
    } else if (!strcmp(maxlstint_text, v->text)) {
4069
0
      if (1 != sscanf(val, "%u", &maxlstint))
4070
0
        goto blooper;
4071
0
    } else if (!strcmp(laddr_text, v->text)) {
4072
0
      if (!decodenetnum(val, &laddr))
4073
0
        goto blooper;
4074
0
      lcladr = getinterface(&laddr, 0);
4075
0
    } else if (1 == sscanf(v->text, last_fmt, &si) &&
4076
0
         (size_t)si < COUNTOF(last)) {
4077
0
      if (2 != sscanf(val, "0x%08x.%08x", &ui, &uf))
4078
0
        goto blooper;
4079
0
      last[si].l_ui = ui;
4080
0
      last[si].l_uf = uf;
4081
0
      if (!SOCK_UNSPEC(&addr[si]) && si == priors)
4082
0
        priors++;
4083
0
    } else if (1 == sscanf(v->text, addr_fmt, &si) &&
4084
0
         (size_t)si < COUNTOF(addr)) {
4085
0
      if (!decodenetnum(val, &addr[si]))
4086
0
        goto blooper;
4087
0
      if (last[si].l_ui && last[si].l_uf && si == priors)
4088
0
        priors++;
4089
0
    } else {
4090
0
      DPRINTF(1, ("read_mru_list: invalid key item: '%s' (ignored)\n",
4091
0
            v->text));
4092
0
      continue;
4093
4094
0
    blooper:
4095
0
      DPRINTF(1, ("read_mru_list: invalid param for '%s': '%s' (bailing)\n",
4096
0
            v->text, val));
4097
0
      free(pnonce);
4098
0
      pnonce = NULL;
4099
0
      break;
4100
0
    }
4101
0
  }
4102
0
  free_varlist(in_parms);
4103
0
  in_parms = NULL;
4104
4105
  /* return no responses until the nonce is validated */
4106
0
  if (NULL == pnonce)
4107
0
    return;
4108
4109
0
  nonce_valid = validate_nonce(pnonce, rbufp);
4110
0
  free(pnonce);
4111
0
  if (!nonce_valid)
4112
0
    return;
4113
4114
0
  if ((0 == frags && !(0 < limit && limit <= MRU_ROW_LIMIT)) ||
4115
0
      frags > MRU_FRAGS_LIMIT) {
4116
0
    ctl_error(CERR_BADVALUE);
4117
0
    return;
4118
0
  }
4119
4120
  /*
4121
   * If either frags or limit is not given, use the max.
4122
   */
4123
0
  if (0 != frags && 0 == limit)
4124
0
    limit = UINT_MAX;
4125
0
  else if (0 != limit && 0 == frags)
4126
0
    frags = MRU_FRAGS_LIMIT;
4127
4128
  /*
4129
   * Find the starting point if one was provided.
4130
   */
4131
0
  mon = NULL;
4132
0
  for (i = 0; i < (size_t)priors; i++) {
4133
0
    hash = MON_HASH(&addr[i]);
4134
0
    for (mon = mon_hash[hash];
4135
0
         mon != NULL;
4136
0
         mon = mon->hash_next)
4137
0
      if (ADDR_PORT_EQ(&mon->rmtadr, &addr[i]))
4138
0
        break;
4139
0
    if (mon != NULL) {
4140
0
      if (L_ISEQU(&mon->last, &last[i]))
4141
0
        break;
4142
0
      mon = NULL;
4143
0
    }
4144
0
  }
4145
4146
  /* If a starting point was provided... */
4147
0
  if (priors) {
4148
    /* and none could be found unmodified... */
4149
0
    if (NULL == mon) {
4150
      /* tell ntpq to try again with older entries */
4151
0
      ctl_error(CERR_UNKNOWNVAR);
4152
0
      return;
4153
0
    }
4154
    /* confirm the prior entry used as starting point */
4155
0
    ctl_putts("last.older", &mon->last);
4156
0
    pch = sptoa(&mon->rmtadr);
4157
0
    ctl_putunqstr("addr.older", pch, strlen(pch));
4158
4159
    /*
4160
     * Move on to the first entry the client doesn't have,
4161
     * except in the special case of a limit of one.  In
4162
     * that case return the starting point entry.
4163
     */
4164
0
    if (limit > 1)
4165
0
      mon = PREV_DLIST(mon_mru_list, mon, mru);
4166
0
  } else { /* start with the oldest */
4167
0
    mon = TAIL_DLIST(mon_mru_list, mru);
4168
0
  }
4169
4170
  /*
4171
   * send up to limit= entries in up to frags= datagrams
4172
   */
4173
0
  get_systime(&now);
4174
0
  generate_nonce(rbufp, buf, sizeof(buf));
4175
0
  ctl_putunqstr("nonce", buf, strlen(buf));
4176
0
  prior_mon = NULL;
4177
0
  for (count = 0;
4178
0
       mon != NULL && res_frags < frags && count < limit;
4179
0
       mon = PREV_DLIST(mon_mru_list, mon, mru)) {
4180
4181
0
    if (mon->count < mincount)
4182
0
      continue;
4183
0
    if (resall && resall != (resall & mon->flags))
4184
0
      continue;
4185
0
    if (resany && !(resany & mon->flags))
4186
0
      continue;
4187
0
    if (maxlstint > 0 && now.l_ui - mon->last.l_ui >
4188
0
        maxlstint)
4189
0
      continue;
4190
0
    if (lcladr != NULL && mon->lcladr != lcladr)
4191
0
      continue;
4192
4193
0
    send_mru_entry(mon, count);
4194
0
    if (!count)
4195
0
      send_random_tag_value(0);
4196
0
    count++;
4197
0
    prior_mon = mon;
4198
0
  }
4199
4200
  /*
4201
   * If this batch completes the MRU list, say so explicitly with
4202
   * a now= l_fp timestamp.
4203
   */
4204
0
  if (NULL == mon) {
4205
0
    if (count > 1)
4206
0
      send_random_tag_value(count - 1);
4207
0
    ctl_putts("now", &now);
4208
    /* if any entries were returned confirm the last */
4209
0
    if (prior_mon != NULL)
4210
0
      ctl_putts("last.newest", &prior_mon->last);
4211
0
  }
4212
0
  ctl_flushpkt(0);
4213
0
}
4214
4215
4216
/*
4217
 * Send a ifstats entry in response to a "ntpq -c ifstats" request.
4218
 *
4219
 * To keep clients honest about not depending on the order of values,
4220
 * and thereby avoid being locked into ugly workarounds to maintain
4221
 * backward compatibility later as new fields are added to the response,
4222
 * the order is random.
4223
 */
4224
static void
4225
send_ifstats_entry(
4226
  endpt * la,
4227
  u_int ifnum
4228
  )
4229
0
{
4230
0
  const char addr_fmtu[] =  "addr.%u";
4231
0
  const char bcast_fmt[] =  "bcast.%u";
4232
0
  const char en_fmt[] =   "en.%u";  /* enabled */
4233
0
  const char name_fmt[] =   "name.%u";
4234
0
  const char flags_fmt[] =  "flags.%u";
4235
0
  const char tl_fmt[] =   "tl.%u";  /* ttl */
4236
0
  const char mc_fmt[] =   "mc.%u";  /* mcast count */
4237
0
  const char rx_fmt[] =   "rx.%u";
4238
0
  const char tx_fmt[] =   "tx.%u";
4239
0
  const char txerr_fmt[] =  "txerr.%u";
4240
0
  const char pc_fmt[] =   "pc.%u";  /* peer count */
4241
0
  const char up_fmt[] =   "up.%u";  /* uptime */
4242
0
  char  tag[32];
4243
0
  u_char  sent[IFSTATS_FIELDS]; /* 12 tag=value pairs */
4244
0
  int noisebits;
4245
0
  u_int32 noise;
4246
0
  u_int which;
4247
0
  u_int remaining;
4248
0
  const char *pch;
4249
4250
0
  remaining = COUNTOF(sent);
4251
0
  ZERO(sent);
4252
0
  noise = 0;
4253
0
  noisebits = 0;
4254
0
  while (remaining > 0) {
4255
0
    if (noisebits < 4) {
4256
0
      noise = rand() ^ (rand() << 16);
4257
0
      noisebits = 31;
4258
0
    }
4259
0
    which = (noise & 0xf) % COUNTOF(sent);
4260
0
    noise >>= 4;
4261
0
    noisebits -= 4;
4262
4263
0
    while (sent[which])
4264
0
      which = (which + 1) % COUNTOF(sent);
4265
4266
0
    switch (which) {
4267
4268
0
    case 0:
4269
0
      snprintf(tag, sizeof(tag), addr_fmtu, ifnum);
4270
0
      pch = sptoa(&la->sin);
4271
0
      ctl_putunqstr(tag, pch, strlen(pch));
4272
0
      break;
4273
4274
0
    case 1:
4275
0
      snprintf(tag, sizeof(tag), bcast_fmt, ifnum);
4276
0
      if (INT_BCASTOPEN & la->flags)
4277
0
        pch = sptoa(&la->bcast);
4278
0
      else
4279
0
        pch = "";
4280
0
      ctl_putunqstr(tag, pch, strlen(pch));
4281
0
      break;
4282
4283
0
    case 2:
4284
0
      snprintf(tag, sizeof(tag), en_fmt, ifnum);
4285
0
      ctl_putint(tag, !la->ignore_packets);
4286
0
      break;
4287
4288
0
    case 3:
4289
0
      snprintf(tag, sizeof(tag), name_fmt, ifnum);
4290
0
      ctl_putstr(tag, la->name, strlen(la->name));
4291
0
      break;
4292
4293
0
    case 4:
4294
0
      snprintf(tag, sizeof(tag), flags_fmt, ifnum);
4295
0
      ctl_puthex(tag, (u_int)la->flags);
4296
0
      break;
4297
4298
0
    case 5:
4299
0
      snprintf(tag, sizeof(tag), tl_fmt, ifnum);
4300
0
      ctl_putint(tag, la->last_ttl);
4301
0
      break;
4302
4303
0
    case 6:
4304
0
      snprintf(tag, sizeof(tag), mc_fmt, ifnum);
4305
0
      ctl_putint(tag, la->num_mcast);
4306
0
      break;
4307
4308
0
    case 7:
4309
0
      snprintf(tag, sizeof(tag), rx_fmt, ifnum);
4310
0
      ctl_putint(tag, la->received);
4311
0
      break;
4312
4313
0
    case 8:
4314
0
      snprintf(tag, sizeof(tag), tx_fmt, ifnum);
4315
0
      ctl_putint(tag, la->sent);
4316
0
      break;
4317
4318
0
    case 9:
4319
0
      snprintf(tag, sizeof(tag), txerr_fmt, ifnum);
4320
0
      ctl_putint(tag, la->notsent);
4321
0
      break;
4322
4323
0
    case 10:
4324
0
      snprintf(tag, sizeof(tag), pc_fmt, ifnum);
4325
0
      ctl_putuint(tag, la->peercnt);
4326
0
      break;
4327
4328
0
    case 11:
4329
0
      snprintf(tag, sizeof(tag), up_fmt, ifnum);
4330
0
      ctl_putuint(tag, current_time - la->starttime);
4331
0
      break;
4332
0
    }
4333
0
    sent[which] = TRUE;
4334
0
    remaining--;
4335
0
  }
4336
0
  send_random_tag_value((int)ifnum);
4337
0
}
4338
4339
4340
/*
4341
 * read_ifstats - send statistics for each local address, exposed by
4342
 *      ntpq -c ifstats
4343
 */
4344
static void
4345
read_ifstats(
4346
  struct recvbuf *  rbufp
4347
  )
4348
0
{
4349
0
  u_int ifidx;
4350
0
  endpt * la;
4351
4352
  /*
4353
   * loop over [0..sys_ifnum] searching ep_list for each
4354
   * ifnum in turn.
4355
   */
4356
0
  for (ifidx = 0; ifidx < sys_ifnum; ifidx++) {
4357
0
    for (la = ep_list; la != NULL; la = la->elink)
4358
0
      if (ifidx == la->ifnum)
4359
0
        break;
4360
0
    if (NULL == la)
4361
0
      continue;
4362
    /* return stats for one local address */
4363
0
    send_ifstats_entry(la, ifidx);
4364
0
  }
4365
0
  ctl_flushpkt(0);
4366
0
}
4367
4368
static void
4369
sockaddrs_from_restrict_u(
4370
  sockaddr_u *  psaA,
4371
  sockaddr_u *  psaM,
4372
  restrict_u *  pres,
4373
  int   ipv6
4374
  )
4375
0
{
4376
0
  ZERO(*psaA);
4377
0
  ZERO(*psaM);
4378
0
  if (!ipv6) {
4379
0
    psaA->sa.sa_family = AF_INET;
4380
0
    psaA->sa4.sin_addr.s_addr = htonl(pres->u.v4.addr);
4381
0
    psaM->sa.sa_family = AF_INET;
4382
0
    psaM->sa4.sin_addr.s_addr = htonl(pres->u.v4.mask);
4383
0
  } else {
4384
0
    psaA->sa.sa_family = AF_INET6;
4385
0
    memcpy(&psaA->sa6.sin6_addr, &pres->u.v6.addr,
4386
0
           sizeof(psaA->sa6.sin6_addr));
4387
0
    psaM->sa.sa_family = AF_INET6;
4388
0
    memcpy(&psaM->sa6.sin6_addr, &pres->u.v6.mask,
4389
0
           sizeof(psaA->sa6.sin6_addr));
4390
0
  }
4391
0
}
4392
4393
4394
/*
4395
 * Send a restrict entry in response to a "ntpq -c reslist" request.
4396
 *
4397
 * To keep clients honest about not depending on the order of values,
4398
 * and thereby avoid being locked into ugly workarounds to maintain
4399
 * backward compatibility later as new fields are added to the response,
4400
 * the order is random.
4401
 */
4402
static void
4403
send_restrict_entry(
4404
  restrict_u *  pres,
4405
  int   ipv6,
4406
  u_int   idx
4407
  )
4408
0
{
4409
0
  const char addr_fmtu[] =  "addr.%u";
4410
0
  const char mask_fmtu[] =  "mask.%u";
4411
0
  const char hits_fmt[] =   "hits.%u";
4412
0
  const char flags_fmt[] =  "flags.%u";
4413
0
  char    tag[32];
4414
0
  u_char    sent[RESLIST_FIELDS]; /* 4 tag=value pairs */
4415
0
  int   noisebits;
4416
0
  u_int32   noise;
4417
0
  u_int   which;
4418
0
  u_int   remaining;
4419
0
  sockaddr_u  addr;
4420
0
  sockaddr_u  mask;
4421
0
  const char *  pch;
4422
0
  char *    buf;
4423
0
  const char *  match_str;
4424
0
  const char *  access_str;
4425
4426
0
  sockaddrs_from_restrict_u(&addr, &mask, pres, ipv6);
4427
0
  remaining = COUNTOF(sent);
4428
0
  ZERO(sent);
4429
0
  noise = 0;
4430
0
  noisebits = 0;
4431
0
  while (remaining > 0) {
4432
0
    if (noisebits < 2) {
4433
0
      noise = rand() ^ (rand() << 16);
4434
0
      noisebits = 31;
4435
0
    }
4436
0
    which = (noise & 0x3) % COUNTOF(sent);
4437
0
    noise >>= 2;
4438
0
    noisebits -= 2;
4439
4440
0
    while (sent[which])
4441
0
      which = (which + 1) % COUNTOF(sent);
4442
4443
    /* XXX: Numbers?  Really? */
4444
0
    switch (which) {
4445
4446
0
    case 0:
4447
0
      snprintf(tag, sizeof(tag), addr_fmtu, idx);
4448
0
      pch = stoa(&addr);
4449
0
      ctl_putunqstr(tag, pch, strlen(pch));
4450
0
      break;
4451
4452
0
    case 1:
4453
0
      snprintf(tag, sizeof(tag), mask_fmtu, idx);
4454
0
      pch = stoa(&mask);
4455
0
      ctl_putunqstr(tag, pch, strlen(pch));
4456
0
      break;
4457
4458
0
    case 2:
4459
0
      snprintf(tag, sizeof(tag), hits_fmt, idx);
4460
0
      ctl_putuint(tag, pres->count);
4461
0
      break;
4462
4463
0
    case 3:
4464
0
      snprintf(tag, sizeof(tag), flags_fmt, idx);
4465
0
      match_str = res_match_flags(pres->mflags);
4466
0
      access_str = res_access_flags(pres->rflags);
4467
0
      if ('\0' == match_str[0]) {
4468
0
        pch = access_str;
4469
0
      } else {
4470
0
        LIB_GETBUF(buf);
4471
0
        snprintf(buf, LIB_BUFLENGTH, "%s %s",
4472
0
           match_str, access_str);
4473
0
        pch = buf;
4474
0
      }
4475
0
      ctl_putunqstr(tag, pch, strlen(pch));
4476
0
      break;
4477
0
    }
4478
0
    sent[which] = TRUE;
4479
0
    remaining--;
4480
0
  }
4481
0
  send_random_tag_value((int)idx);
4482
0
}
4483
4484
4485
static void
4486
send_restrict_list(
4487
  restrict_u *  pres,
4488
  int   ipv6,
4489
  u_int *   pidx
4490
  )
4491
0
{
4492
0
  for ( ; pres != NULL; pres = pres->link) {
4493
0
    send_restrict_entry(pres, ipv6, *pidx);
4494
0
    (*pidx)++;
4495
0
  }
4496
0
}
4497
4498
4499
/*
4500
 * read_addr_restrictions - returns IPv4 and IPv6 access control lists
4501
 */
4502
static void
4503
read_addr_restrictions(
4504
  struct recvbuf *  rbufp
4505
)
4506
0
{
4507
0
  u_int idx;
4508
4509
0
  idx = 0;
4510
0
  send_restrict_list(restrictlist4, FALSE, &idx);
4511
0
  send_restrict_list(restrictlist6, TRUE, &idx);
4512
0
  ctl_flushpkt(0);
4513
0
}
4514
4515
4516
/*
4517
 * read_ordlist - CTL_OP_READ_ORDLIST_A for ntpq -c ifstats & reslist
4518
 */
4519
static void
4520
read_ordlist(
4521
  struct recvbuf *  rbufp,
4522
  int     restrict_mask
4523
  )
4524
0
{
4525
0
  const char ifstats_s[] = "ifstats";
4526
0
  const size_t ifstats_chars = COUNTOF(ifstats_s) - 1;
4527
0
  const char addr_rst_s[] = "addr_restrictions";
4528
0
  const size_t a_r_chars = COUNTOF(addr_rst_s) - 1;
4529
0
  struct ntp_control *  cpkt;
4530
0
  u_short     qdata_octets;
4531
4532
  /*
4533
   * CTL_OP_READ_ORDLIST_A was first named CTL_OP_READ_IFSTATS and
4534
   * used only for ntpq -c ifstats.  With the addition of reslist
4535
   * the same opcode was generalized to retrieve ordered lists
4536
   * which require authentication.  The request data is empty or
4537
   * contains "ifstats" (not null terminated) to retrieve local
4538
   * addresses and associated stats.  It is "addr_restrictions"
4539
   * to retrieve the IPv4 then IPv6 remote address restrictions,
4540
   * which are access control lists.  Other request data return
4541
   * CERR_UNKNOWNVAR.
4542
   */
4543
0
  cpkt = (struct ntp_control *)&rbufp->recv_pkt;
4544
0
  qdata_octets = ntohs(cpkt->count);
4545
0
  if (0 == qdata_octets || (ifstats_chars == qdata_octets &&
4546
0
      !memcmp(ifstats_s, cpkt->u.data, ifstats_chars))) {
4547
0
    read_ifstats(rbufp);
4548
0
    return;
4549
0
  }
4550
0
  if (a_r_chars == qdata_octets &&
4551
0
      !memcmp(addr_rst_s, cpkt->u.data, a_r_chars)) {
4552
0
    read_addr_restrictions(rbufp);
4553
0
    return;
4554
0
  }
4555
0
  ctl_error(CERR_UNKNOWNVAR);
4556
0
}
4557
4558
4559
/*
4560
 * req_nonce - CTL_OP_REQ_NONCE for ntpq -c mrulist prerequisite.
4561
 */
4562
static void req_nonce(
4563
  struct recvbuf *  rbufp,
4564
  int     restrict_mask
4565
  )
4566
0
{
4567
0
  char  buf[64];
4568
4569
0
  generate_nonce(rbufp, buf, sizeof(buf));
4570
0
  ctl_putunqstr("nonce", buf, strlen(buf));
4571
0
  ctl_flushpkt(0);
4572
0
}
4573
4574
4575
/*
4576
 * read_clockstatus - return clock radio status
4577
 */
4578
/*ARGSUSED*/
4579
static void
4580
read_clockstatus(
4581
  struct recvbuf *rbufp,
4582
  int restrict_mask
4583
  )
4584
0
{
4585
#ifndef REFCLOCK
4586
  /*
4587
   * If no refclock support, no data to return
4588
   */
4589
  ctl_error(CERR_BADASSOC);
4590
#else
4591
0
  const struct ctl_var *  v;
4592
0
  int     i;
4593
0
  struct peer *   peer;
4594
0
  char *      valuep;
4595
0
  u_char *    wants;
4596
0
  size_t      wants_alloc;
4597
0
  int     gotvar;
4598
0
  const u_char *    cc;
4599
0
  struct ctl_var *  kv;
4600
0
  struct refclockstat cs;
4601
4602
0
  if (res_associd != 0) {
4603
0
    peer = findpeerbyassoc(res_associd);
4604
0
  } else {
4605
    /*
4606
     * Find a clock for this jerk.  If the system peer
4607
     * is a clock use it, else search peer_list for one.
4608
     */
4609
0
    if (sys_peer != NULL && (FLAG_REFCLOCK &
4610
0
        sys_peer->flags))
4611
0
      peer = sys_peer;
4612
0
    else
4613
0
      for (peer = peer_list;
4614
0
           peer != NULL;
4615
0
           peer = peer->p_link)
4616
0
        if (FLAG_REFCLOCK & peer->flags)
4617
0
          break;
4618
0
  }
4619
0
  if (NULL == peer || !(FLAG_REFCLOCK & peer->flags)) {
4620
0
    ctl_error(CERR_BADASSOC);
4621
0
    return;
4622
0
  }
4623
  /*
4624
   * If we got here we have a peer which is a clock. Get his
4625
   * status.
4626
   */
4627
0
  cs.kv_list = NULL;
4628
0
  refclock_control(&peer->srcadr, NULL, &cs);
4629
0
  kv = cs.kv_list;
4630
  /*
4631
   * Look for variables in the packet.
4632
   */
4633
0
  rpkt.status = htons(ctlclkstatus(&cs));
4634
0
  wants_alloc = CC_MAXCODE + 1 + count_var(kv);
4635
0
  wants = emalloc_zero(wants_alloc);
4636
0
  gotvar = FALSE;
4637
0
  while (NULL != (v = ctl_getitem(clock_var, &valuep))) {
4638
0
    if (!(EOV & v->flags)) {
4639
0
      wants[v->code] = TRUE;
4640
0
      gotvar = TRUE;
4641
0
    } else {
4642
0
      v = ctl_getitem(kv, &valuep);
4643
0
      if (NULL == v) {
4644
0
        ctl_error(CERR_BADVALUE);
4645
0
        free(wants);
4646
0
        free_varlist(cs.kv_list);
4647
0
        return;
4648
0
      }
4649
0
      if (EOV & v->flags) {
4650
0
        ctl_error(CERR_UNKNOWNVAR);
4651
0
        free(wants);
4652
0
        free_varlist(cs.kv_list);
4653
0
        return;
4654
0
      }
4655
0
      wants[CC_MAXCODE + 1 + v->code] = TRUE;
4656
0
      gotvar = TRUE;
4657
0
    }
4658
0
  }
4659
4660
0
  if (gotvar) {
4661
0
    for (i = 1; i <= CC_MAXCODE; i++)
4662
0
      if (wants[i])
4663
0
        ctl_putclock(i, &cs, TRUE);
4664
0
    if (kv != NULL)
4665
0
      for (i = 0; !(EOV & kv[i].flags); i++)
4666
0
        if (wants[i + CC_MAXCODE + 1])
4667
0
          ctl_putdata(kv[i].text,
4668
0
                strlen(kv[i].text),
4669
0
                FALSE);
4670
0
  } else {
4671
0
    for (cc = def_clock_var; *cc != 0; cc++)
4672
0
      ctl_putclock((int)*cc, &cs, FALSE);
4673
0
    for ( ; kv != NULL && !(EOV & kv->flags); kv++)
4674
0
      if (DEF & kv->flags)
4675
0
        ctl_putdata(kv->text, strlen(kv->text),
4676
0
              FALSE);
4677
0
  }
4678
4679
0
  free(wants);
4680
0
  free_varlist(cs.kv_list);
4681
4682
0
  ctl_flushpkt(0);
4683
0
#endif
4684
0
}
4685
4686
4687
/*
4688
 * write_clockstatus - we don't do this
4689
 */
4690
/*ARGSUSED*/
4691
static void
4692
write_clockstatus(
4693
  struct recvbuf *rbufp,
4694
  int restrict_mask
4695
  )
4696
0
{
4697
0
  ctl_error(CERR_PERMISSION);
4698
0
}
4699
4700
/*
4701
 * Trap support from here on down. We send async trap messages when the
4702
 * upper levels report trouble. Traps can by set either by control
4703
 * messages or by configuration.
4704
 */
4705
/*
4706
 * set_trap - set a trap in response to a control message
4707
 */
4708
static void
4709
set_trap(
4710
  struct recvbuf *rbufp,
4711
  int restrict_mask
4712
  )
4713
0
{
4714
0
  int traptype;
4715
4716
  /*
4717
   * See if this guy is allowed
4718
   */
4719
0
  if (restrict_mask & RES_NOTRAP) {
4720
0
    ctl_error(CERR_PERMISSION);
4721
0
    return;
4722
0
  }
4723
4724
  /*
4725
   * Determine his allowed trap type.
4726
   */
4727
0
  traptype = TRAP_TYPE_PRIO;
4728
0
  if (restrict_mask & RES_LPTRAP)
4729
0
    traptype = TRAP_TYPE_NONPRIO;
4730
4731
  /*
4732
   * Call ctlsettrap() to do the work.  Return
4733
   * an error if it can't assign the trap.
4734
   */
4735
0
  if (!ctlsettrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype,
4736
0
      (int)res_version))
4737
0
    ctl_error(CERR_NORESOURCE);
4738
0
  ctl_flushpkt(0);
4739
0
}
4740
4741
4742
/*
4743
 * unset_trap - unset a trap in response to a control message
4744
 */
4745
static void
4746
unset_trap(
4747
  struct recvbuf *rbufp,
4748
  int restrict_mask
4749
  )
4750
0
{
4751
0
  int traptype;
4752
4753
  /*
4754
   * We don't prevent anyone from removing his own trap unless the
4755
   * trap is configured. Note we also must be aware of the
4756
   * possibility that restriction flags were changed since this
4757
   * guy last set his trap. Set the trap type based on this.
4758
   */
4759
0
  traptype = TRAP_TYPE_PRIO;
4760
0
  if (restrict_mask & RES_LPTRAP)
4761
0
    traptype = TRAP_TYPE_NONPRIO;
4762
4763
  /*
4764
   * Call ctlclrtrap() to clear this out.
4765
   */
4766
0
  if (!ctlclrtrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype))
4767
0
    ctl_error(CERR_BADASSOC);
4768
0
  ctl_flushpkt(0);
4769
0
}
4770
4771
4772
/*
4773
 * ctlsettrap - called to set a trap
4774
 */
4775
int
4776
ctlsettrap(
4777
  sockaddr_u *raddr,
4778
  endpt *linter,
4779
  int traptype,
4780
  int version
4781
  )
4782
0
{
4783
0
  size_t n;
4784
0
  struct ctl_trap *tp;
4785
0
  struct ctl_trap *tptouse;
4786
4787
  /*
4788
   * See if we can find this trap.  If so, we only need update
4789
   * the flags and the time.
4790
   */
4791
0
  if ((tp = ctlfindtrap(raddr, linter)) != NULL) {
4792
0
    switch (traptype) {
4793
4794
0
    case TRAP_TYPE_CONFIG:
4795
0
      tp->tr_flags = TRAP_INUSE|TRAP_CONFIGURED;
4796
0
      break;
4797
4798
0
    case TRAP_TYPE_PRIO:
4799
0
      if (tp->tr_flags & TRAP_CONFIGURED)
4800
0
        return (1); /* don't change anything */
4801
0
      tp->tr_flags = TRAP_INUSE;
4802
0
      break;
4803
4804
0
    case TRAP_TYPE_NONPRIO:
4805
0
      if (tp->tr_flags & TRAP_CONFIGURED)
4806
0
        return (1); /* don't change anything */
4807
0
      tp->tr_flags = TRAP_INUSE|TRAP_NONPRIO;
4808
0
      break;
4809
0
    }
4810
0
    tp->tr_settime = current_time;
4811
0
    tp->tr_resets++;
4812
0
    return (1);
4813
0
  }
4814
4815
  /*
4816
   * First we heard of this guy.  Try to find a trap structure
4817
   * for him to use, clearing out lesser priority guys if we
4818
   * have to. Clear out anyone who's expired while we're at it.
4819
   */
4820
0
  tptouse = NULL;
4821
0
  for (n = 0; n < COUNTOF(ctl_traps); n++) {
4822
0
    tp = &ctl_traps[n];
4823
0
    if ((TRAP_INUSE & tp->tr_flags) &&
4824
0
        !(TRAP_CONFIGURED & tp->tr_flags) &&
4825
0
        ((tp->tr_settime + CTL_TRAPTIME) > current_time)) {
4826
0
      tp->tr_flags = 0;
4827
0
      num_ctl_traps--;
4828
0
    }
4829
0
    if (!(TRAP_INUSE & tp->tr_flags)) {
4830
0
      tptouse = tp;
4831
0
    } else if (!(TRAP_CONFIGURED & tp->tr_flags)) {
4832
0
      switch (traptype) {
4833
4834
0
      case TRAP_TYPE_CONFIG:
4835
0
        if (tptouse == NULL) {
4836
0
          tptouse = tp;
4837
0
          break;
4838
0
        }
4839
0
        if ((TRAP_NONPRIO & tptouse->tr_flags) &&
4840
0
            !(TRAP_NONPRIO & tp->tr_flags))
4841
0
          break;
4842
4843
0
        if (!(TRAP_NONPRIO & tptouse->tr_flags)
4844
0
            && (TRAP_NONPRIO & tp->tr_flags)) {
4845
0
          tptouse = tp;
4846
0
          break;
4847
0
        }
4848
0
        if (tptouse->tr_origtime <
4849
0
            tp->tr_origtime)
4850
0
          tptouse = tp;
4851
0
        break;
4852
4853
0
      case TRAP_TYPE_PRIO:
4854
0
        if ( TRAP_NONPRIO & tp->tr_flags) {
4855
0
          if (tptouse == NULL ||
4856
0
              ((TRAP_INUSE &
4857
0
                tptouse->tr_flags) &&
4858
0
               tptouse->tr_origtime <
4859
0
               tp->tr_origtime))
4860
0
            tptouse = tp;
4861
0
        }
4862
0
        break;
4863
4864
0
      case TRAP_TYPE_NONPRIO:
4865
0
        break;
4866
0
      }
4867
0
    }
4868
0
  }
4869
4870
  /*
4871
   * If we don't have room for him return an error.
4872
   */
4873
0
  if (tptouse == NULL)
4874
0
    return (0);
4875
4876
  /*
4877
   * Set up this structure for him.
4878
   */
4879
0
  tptouse->tr_settime = tptouse->tr_origtime = current_time;
4880
0
  tptouse->tr_count = tptouse->tr_resets = 0;
4881
0
  tptouse->tr_sequence = 1;
4882
0
  tptouse->tr_addr = *raddr;
4883
0
  tptouse->tr_localaddr = linter;
4884
0
  tptouse->tr_version = (u_char) version;
4885
0
  tptouse->tr_flags = TRAP_INUSE;
4886
0
  if (traptype == TRAP_TYPE_CONFIG)
4887
0
    tptouse->tr_flags |= TRAP_CONFIGURED;
4888
0
  else if (traptype == TRAP_TYPE_NONPRIO)
4889
0
    tptouse->tr_flags |= TRAP_NONPRIO;
4890
0
  num_ctl_traps++;
4891
0
  return (1);
4892
0
}
4893
4894
4895
/*
4896
 * ctlclrtrap - called to clear a trap
4897
 */
4898
int
4899
ctlclrtrap(
4900
  sockaddr_u *raddr,
4901
  endpt *linter,
4902
  int traptype
4903
  )
4904
0
{
4905
0
  register struct ctl_trap *tp;
4906
4907
0
  if ((tp = ctlfindtrap(raddr, linter)) == NULL)
4908
0
    return (0);
4909
4910
0
  if (tp->tr_flags & TRAP_CONFIGURED
4911
0
      && traptype != TRAP_TYPE_CONFIG)
4912
0
    return (0);
4913
4914
0
  tp->tr_flags = 0;
4915
0
  num_ctl_traps--;
4916
0
  return (1);
4917
0
}
4918
4919
4920
/*
4921
 * ctlfindtrap - find a trap given the remote and local addresses
4922
 */
4923
static struct ctl_trap *
4924
ctlfindtrap(
4925
  sockaddr_u *raddr,
4926
  endpt *linter
4927
  )
4928
0
{
4929
0
  size_t  n;
4930
4931
0
  for (n = 0; n < COUNTOF(ctl_traps); n++)
4932
0
    if ((ctl_traps[n].tr_flags & TRAP_INUSE)
4933
0
        && ADDR_PORT_EQ(raddr, &ctl_traps[n].tr_addr)
4934
0
        && (linter == ctl_traps[n].tr_localaddr))
4935
0
      return &ctl_traps[n];
4936
4937
0
  return NULL;
4938
0
}
4939
4940
4941
/*
4942
 * report_event - report an event to the trappers
4943
 */
4944
void
4945
report_event(
4946
  int err,    /* error code */
4947
  struct peer *peer,  /* peer structure pointer */
4948
  const char *str   /* protostats string */
4949
  )
4950
0
{
4951
0
  char  statstr[NTP_MAXSTRLEN];
4952
0
  int i;
4953
0
  size_t  len;
4954
4955
  /*
4956
   * Report the error to the protostats file, system log and
4957
   * trappers.
4958
   */
4959
0
  if (peer == NULL) {
4960
4961
    /*
4962
     * Discard a system report if the number of reports of
4963
     * the same type exceeds the maximum.
4964
     */
4965
0
    if (ctl_sys_last_event != (u_char)err)
4966
0
      ctl_sys_num_events= 0;
4967
0
    if (ctl_sys_num_events >= CTL_SYS_MAXEVENTS)
4968
0
      return;
4969
4970
0
    ctl_sys_last_event = (u_char)err;
4971
0
    ctl_sys_num_events++;
4972
0
    snprintf(statstr, sizeof(statstr),
4973
0
        "0.0.0.0 %04x %02x %s",
4974
0
        ctlsysstatus(), err, eventstr(err));
4975
0
    if (str != NULL) {
4976
0
      len = strlen(statstr);
4977
0
      snprintf(statstr + len, sizeof(statstr) - len,
4978
0
          " %s", str);
4979
0
    }
4980
0
    NLOG(NLOG_SYSEVENT)
4981
0
      msyslog(LOG_INFO, "%s", statstr);
4982
0
  } else {
4983
4984
    /*
4985
     * Discard a peer report if the number of reports of
4986
     * the same type exceeds the maximum for that peer.
4987
     */
4988
0
    const char *  src;
4989
0
    u_char    errlast;
4990
4991
0
    errlast = (u_char)err & ~PEER_EVENT;
4992
0
    if (peer->last_event != errlast)
4993
0
      peer->num_events = 0;
4994
0
    if (peer->num_events >= CTL_PEER_MAXEVENTS)
4995
0
      return;
4996
4997
0
    peer->last_event = errlast;
4998
0
    peer->num_events++;
4999
0
    if (ISREFCLOCKADR(&peer->srcadr))
5000
0
      src = refnumtoa(&peer->srcadr);
5001
0
    else
5002
0
      src = stoa(&peer->srcadr);
5003
5004
0
    snprintf(statstr, sizeof(statstr),
5005
0
        "%s %04x %02x %s", src,
5006
0
        ctlpeerstatus(peer), err, eventstr(err));
5007
0
    if (str != NULL) {
5008
0
      len = strlen(statstr);
5009
0
      snprintf(statstr + len, sizeof(statstr) - len,
5010
0
          " %s", str);
5011
0
    }
5012
0
    NLOG(NLOG_PEEREVENT)
5013
0
      msyslog(LOG_INFO, "%s", statstr);
5014
0
  }
5015
0
  record_proto_stats(statstr);
5016
0
#if DEBUG
5017
0
  if (debug)
5018
0
    printf("event at %lu %s\n", current_time, statstr);
5019
0
#endif
5020
5021
  /*
5022
   * If no trappers, return.
5023
   */
5024
0
  if (num_ctl_traps <= 0)
5025
0
    return;
5026
5027
  /* [Bug 3119]
5028
   * Peer Events should be associated with a peer -- hence the
5029
   * name. But there are instances where this function is called
5030
   * *without* a valid peer. This happens e.g. with an unsolicited
5031
   * CryptoNAK, or when a leap second alarm is going off while
5032
   * currently without a system peer.
5033
   *
5034
   * The most sensible approach to this seems to bail out here if
5035
   * this happens. Avoiding to call this function would also
5036
   * bypass the log reporting in the first part of this function,
5037
   * and this is probably not the best of all options.
5038
   *   -*-perlinger@ntp.org-*-
5039
   */
5040
0
  if ((err & PEER_EVENT) && !peer)
5041
0
    return;
5042
5043
  /*
5044
   * Set up the outgoing packet variables
5045
   */
5046
0
  res_opcode = CTL_OP_ASYNCMSG;
5047
0
  res_offset = 0;
5048
0
  res_async = TRUE;
5049
0
  res_authenticate = FALSE;
5050
0
  datapt = rpkt.u.data;
5051
0
  dataend = &rpkt.u.data[CTL_MAX_DATA_LEN];
5052
0
  if (!(err & PEER_EVENT)) {
5053
0
    rpkt.associd = 0;
5054
0
    rpkt.status = htons(ctlsysstatus());
5055
5056
    /* Include the core system variables and the list. */
5057
0
    for (i = 1; i <= CS_VARLIST; i++)
5058
0
      ctl_putsys(i);
5059
0
  } else if (NULL != peer) { /* paranoia -- skip output */
5060
0
    rpkt.associd = htons(peer->associd);
5061
0
    rpkt.status = htons(ctlpeerstatus(peer));
5062
5063
    /* Dump it all. Later, maybe less. */
5064
0
    for (i = 1; i <= CP_MAX_NOAUTOKEY; i++)
5065
0
      ctl_putpeer(i, peer);
5066
0
#     ifdef REFCLOCK
5067
    /*
5068
     * for clock exception events: add clock variables to
5069
     * reflect info on exception
5070
     */
5071
0
    if (err == PEVNT_CLOCK) {
5072
0
      struct refclockstat cs;
5073
0
      struct ctl_var *kv;
5074
5075
0
      cs.kv_list = NULL;
5076
0
      refclock_control(&peer->srcadr, NULL, &cs);
5077
5078
0
      ctl_puthex("refclockstatus",
5079
0
           ctlclkstatus(&cs));
5080
5081
0
      for (i = 1; i <= CC_MAXCODE; i++)
5082
0
        ctl_putclock(i, &cs, FALSE);
5083
0
      for (kv = cs.kv_list;
5084
0
           kv != NULL && !(EOV & kv->flags);
5085
0
           kv++)
5086
0
        if (DEF & kv->flags)
5087
0
          ctl_putdata(kv->text,
5088
0
                strlen(kv->text),
5089
0
                FALSE);
5090
0
      free_varlist(cs.kv_list);
5091
0
    }
5092
0
#     endif /* REFCLOCK */
5093
0
  }
5094
5095
  /*
5096
   * We're done, return.
5097
   */
5098
0
  ctl_flushpkt(0);
5099
0
}
5100
5101
5102
/*
5103
 * mprintf_event - printf-style varargs variant of report_event()
5104
 */
5105
int
5106
mprintf_event(
5107
  int   evcode,   /* event code */
5108
  struct peer * p,    /* may be NULL */
5109
  const char *  fmt,    /* msnprintf format */
5110
  ...
5111
  )
5112
0
{
5113
0
  va_list ap;
5114
0
  int rc;
5115
0
  char  msg[512];
5116
5117
0
  va_start(ap, fmt);
5118
0
  rc = mvsnprintf(msg, sizeof(msg), fmt, ap);
5119
0
  va_end(ap);
5120
0
  report_event(evcode, p, msg);
5121
5122
0
  return rc;
5123
0
}
5124
5125
5126
/*
5127
 * ctl_clr_stats - clear stat counters
5128
 */
5129
void
5130
ctl_clr_stats(void)
5131
1
{
5132
1
  ctltimereset = current_time;
5133
1
  numctlreq = 0;
5134
1
  numctlbadpkts = 0;
5135
1
  numctlresponses = 0;
5136
1
  numctlfrags = 0;
5137
1
  numctlerrors = 0;
5138
1
  numctlfrags = 0;
5139
1
  numctltooshort = 0;
5140
1
  numctlinputresp = 0;
5141
1
  numctlinputfrag = 0;
5142
1
  numctlinputerr = 0;
5143
1
  numctlbadoffset = 0;
5144
1
  numctlbadversion = 0;
5145
1
  numctldatatooshort = 0;
5146
1
  numctlbadop = 0;
5147
1
  numasyncmsgs = 0;
5148
1
}
5149
5150
static u_short
5151
count_var(
5152
  const struct ctl_var *k
5153
  )
5154
0
{
5155
0
  u_int c;
5156
5157
0
  if (NULL == k)
5158
0
    return 0;
5159
5160
0
  c = 0;
5161
0
  while (!(EOV & (k++)->flags))
5162
0
    c++;
5163
5164
0
  ENSURE(c <= USHRT_MAX);
5165
0
  return (u_short)c;
5166
0
}
5167
5168
5169
char *
5170
add_var(
5171
  struct ctl_var **kv,
5172
  u_long size,
5173
  u_short def
5174
  )
5175
0
{
5176
0
  u_short   c;
5177
0
  struct ctl_var *k;
5178
0
  char *    buf;
5179
5180
0
  c = count_var(*kv);
5181
0
  *kv  = erealloc(*kv, (c + 2) * sizeof(**kv));
5182
0
  k = *kv;
5183
0
  buf = emalloc(size);
5184
0
  k[c].code  = c;
5185
0
  k[c].text  = buf;
5186
0
  k[c].flags = def;
5187
0
  k[c + 1].code  = 0;
5188
0
  k[c + 1].text  = NULL;
5189
0
  k[c + 1].flags = EOV;
5190
5191
0
  return buf;
5192
0
}
5193
5194
5195
void
5196
set_var(
5197
  struct ctl_var **kv,
5198
  const char *data,
5199
  u_long size,
5200
  u_short def
5201
  )
5202
0
{
5203
0
  struct ctl_var *k;
5204
0
  const char *s;
5205
0
  const char *t;
5206
0
  char *td;
5207
5208
0
  if (NULL == data || !size)
5209
0
    return;
5210
5211
0
  k = *kv;
5212
0
  if (k != NULL) {
5213
0
    while (!(EOV & k->flags)) {
5214
0
      if (NULL == k->text) {
5215
0
        td = emalloc(size);
5216
0
        memcpy(td, data, size);
5217
0
        k->text = td;
5218
0
        k->flags = def;
5219
0
        return;
5220
0
      } else {
5221
0
        s = data;
5222
0
        t = k->text;
5223
0
        while (*t != '=' && *s == *t) {
5224
0
          s++;
5225
0
          t++;
5226
0
        }
5227
0
        if (*s == *t && ((*t == '=') || !*t)) {
5228
0
          td = erealloc((void *)(intptr_t)k->text, size);
5229
0
          memcpy(td, data, size);
5230
0
          k->text = td;
5231
0
          k->flags = def;
5232
0
          return;
5233
0
        }
5234
0
      }
5235
0
      k++;
5236
0
    }
5237
0
  }
5238
0
  td = add_var(kv, size, def);
5239
0
  memcpy(td, data, size);
5240
0
}
5241
5242
5243
void
5244
set_sys_var(
5245
  const char *data,
5246
  u_long size,
5247
  u_short def
5248
  )
5249
0
{
5250
0
  set_var(&ext_sys_var, data, size, def);
5251
0
}
5252
5253
5254
/*
5255
 * get_ext_sys_var() retrieves the value of a user-defined variable or
5256
 * NULL if the variable has not been setvar'd.
5257
 */
5258
const char *
5259
get_ext_sys_var(const char *tag)
5260
0
{
5261
0
  struct ctl_var *  v;
5262
0
  size_t      c;
5263
0
  const char *    val;
5264
5265
0
  val = NULL;
5266
0
  c = strlen(tag);
5267
0
  for (v = ext_sys_var; !(EOV & v->flags); v++) {
5268
0
    if (NULL != v->text && !memcmp(tag, v->text, c)) {
5269
0
      if ('=' == v->text[c]) {
5270
0
        val = v->text + c + 1;
5271
0
        break;
5272
0
      } else if ('\0' == v->text[c]) {
5273
0
        val = "";
5274
0
        break;
5275
0
      }
5276
0
    }
5277
0
  }
5278
5279
0
  return val;
5280
0
}
5281
5282
5283
void
5284
free_varlist(
5285
  struct ctl_var *kv
5286
  )
5287
0
{
5288
0
  struct ctl_var *k;
5289
0
  if (kv) {
5290
0
    for (k = kv; !(k->flags & EOV); k++)
5291
0
      free((void *)(intptr_t)k->text);
5292
0
    free((void *)kv);
5293
0
  }
5294
0
}