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