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