xref: /freebsd/contrib/ntp/ntpd/ntp_control.c (revision a812392203d7c4c3f0db9d8a0f3391374c49c71f)
1 /*
2  * ntp_control.c - respond to control messages and send async traps
3  */
4 
5 /*
6  * $FreeBSD$
7  */
8 
9 #ifdef HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12 
13 #include "ntpd.h"
14 #include "ntp_io.h"
15 #include "ntp_refclock.h"
16 #include "ntp_control.h"
17 #include "ntp_unixtime.h"
18 #include "ntp_stdlib.h"
19 
20 #include <stdio.h>
21 #include <ctype.h>
22 #include <signal.h>
23 
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
26 
27 #ifndef MIN
28 #define MIN(a, b) (((a) <= (b)) ? (a) : (b))
29 #endif
30 
31 /*
32  * Structure to hold request procedure information
33  */
34 #define NOAUTH	0
35 #define AUTH	1
36 
37 #define NO_REQUEST	(-1)
38 
39 struct ctl_proc {
40 	short control_code;		/* defined request code */
41 	u_short flags;			/* flags word */
42 	void (*handler) P((struct recvbuf *, int)); /* handle request */
43 };
44 
45 /*
46  * Only one flag.  Authentication required or not.
47  */
48 #define NOAUTH	0
49 #define AUTH	1
50 
51 /*
52  * Request processing routines
53  */
54 static	void	ctl_error	P((int));
55 #ifdef REFCLOCK
56 static	u_short ctlclkstatus	P((struct refclockstat *));
57 #endif
58 static	void	ctl_flushpkt	P((int));
59 static	void	ctl_putdata	P((const char *, unsigned int, int));
60 static	void	ctl_putstr	P((const char *, const char *,
61 				    unsigned int));
62 static	void	ctl_putdbl	P((const char *, double));
63 static	void	ctl_putuint	P((const char *, u_long));
64 static	void	ctl_puthex	P((const char *, u_long));
65 static	void	ctl_putint	P((const char *, long));
66 static	void	ctl_putts	P((const char *, l_fp *));
67 static	void	ctl_putadr	P((const char *, u_int32, struct sockaddr_storage*));
68 static	void	ctl_putid	P((const char *, char *));
69 static	void	ctl_putarray	P((const char *, double *, int));
70 static	void	ctl_putsys	P((int));
71 static	void	ctl_putpeer	P((int, struct peer *));
72 #ifdef OPENSSL
73 static	void	ctl_putfs	P((const char *, tstamp_t));
74 #endif
75 #ifdef REFCLOCK
76 static	void	ctl_putclock	P((int, struct refclockstat *, int));
77 #endif	/* REFCLOCK */
78 static	struct ctl_var *ctl_getitem P((struct ctl_var *, char **));
79 static	u_long count_var	P((struct ctl_var *));
80 static	void	control_unspec	P((struct recvbuf *, int));
81 static	void	read_status	P((struct recvbuf *, int));
82 static	void	read_variables	P((struct recvbuf *, int));
83 static	void	write_variables P((struct recvbuf *, int));
84 static	void	read_clock_status P((struct recvbuf *, int));
85 static	void	write_clock_status P((struct recvbuf *, int));
86 static	void	set_trap	P((struct recvbuf *, int));
87 static	void	unset_trap	P((struct recvbuf *, int));
88 static	struct ctl_trap *ctlfindtrap P((struct sockaddr_storage *,
89 				    struct interface *));
90 
91 static	struct ctl_proc control_codes[] = {
92 	{ CTL_OP_UNSPEC,	NOAUTH, control_unspec },
93 	{ CTL_OP_READSTAT,	NOAUTH, read_status },
94 	{ CTL_OP_READVAR,	NOAUTH, read_variables },
95 	{ CTL_OP_WRITEVAR,	AUTH,	write_variables },
96 	{ CTL_OP_READCLOCK,	NOAUTH, read_clock_status },
97 	{ CTL_OP_WRITECLOCK,	NOAUTH, write_clock_status },
98 	{ CTL_OP_SETTRAP,	NOAUTH, set_trap },
99 	{ CTL_OP_UNSETTRAP,	NOAUTH, unset_trap },
100 	{ NO_REQUEST,		0 }
101 };
102 
103 /*
104  * System variable values. The array can be indexed by the variable
105  * index to find the textual name.
106  */
107 static struct ctl_var sys_var[] = {
108 	{ 0,		PADDING, "" },		/* 0 */
109 	{ CS_LEAP,	RW, "leap" },		/* 1 */
110 	{ CS_STRATUM,	RO, "stratum" },	/* 2 */
111 	{ CS_PRECISION, RO, "precision" },	/* 3 */
112 	{ CS_ROOTDELAY, RO, "rootdelay" },	/* 4 */
113 	{ CS_ROOTDISPERSION, RO, "rootdispersion" }, /* 5 */
114 	{ CS_REFID,	RO, "refid" },		/* 6 */
115 	{ CS_REFTIME,	RO, "reftime" },	/* 7 */
116 	{ CS_POLL,	RO, "poll" },		/* 8 */
117 	{ CS_PEERID,	RO, "peer" },		/* 9 */
118 	{ CS_STATE,	RO, "state" },		/* 10 */
119 	{ CS_OFFSET,	RO, "offset" },		/* 11 */
120 	{ CS_DRIFT,	RO, "frequency" },	/* 12 */
121 	{ CS_JITTER,	RO, "jitter" },		/* 13 */
122 	{ CS_ERROR,	RO, "noise" },		/* 14 */
123 	{ CS_CLOCK,	RO, "clock" },		/* 15 */
124 	{ CS_PROCESSOR, RO, "processor" },	/* 16 */
125 	{ CS_SYSTEM,	RO, "system" },		/* 17 */
126 	{ CS_VERSION,	RO, "version" },	/* 18 */
127 	{ CS_STABIL,	RO, "stability" },	/* 19 */
128 	{ CS_VARLIST,	RO, "sys_var_list" },	/* 20 */
129 #ifdef OPENSSL
130 	{ CS_FLAGS,	RO, "flags" },		/* 21 */
131 	{ CS_HOST,	RO, "hostname" },	/* 22 */
132 	{ CS_PUBLIC,	RO, "update" },		/* 23 */
133 	{ CS_CERTIF,	RO, "cert" },		/* 24 */
134 	{ CS_REVTIME,	RO, "expire" },		/* 25 */
135 	{ CS_LEAPTAB,	RO, "leapsec" },	/* 26 */
136 	{ CS_TAI,	RO, "tai" },		/* 27 */
137 	{ CS_DIGEST,	RO, "signature" },	/* 28 */
138 	{ CS_IDENT,	RO, "ident" },		/* 29 */
139 	{ CS_REVOKE,	RO, "expire" },		/* 30 */
140 #endif /* OPENSSL */
141 	{ 0,		EOV, "" }		/* 21/31 */
142 };
143 
144 static struct ctl_var *ext_sys_var = (struct ctl_var *)0;
145 
146 /*
147  * System variables we print by default (in fuzzball order,
148  * more-or-less)
149  */
150 static	u_char def_sys_var[] = {
151 	CS_VERSION,
152 	CS_PROCESSOR,
153 	CS_SYSTEM,
154 	CS_LEAP,
155 	CS_STRATUM,
156 	CS_PRECISION,
157 	CS_ROOTDELAY,
158 	CS_ROOTDISPERSION,
159 	CS_PEERID,
160 	CS_REFID,
161 	CS_REFTIME,
162 	CS_POLL,
163 	CS_CLOCK,
164 	CS_STATE,
165 	CS_OFFSET,
166 	CS_DRIFT,
167 	CS_JITTER,
168 	CS_ERROR,
169 	CS_STABIL,
170 #ifdef OPENSSL
171 	CS_HOST,
172 	CS_DIGEST,
173 	CS_FLAGS,
174 	CS_PUBLIC,
175 	CS_IDENT,
176 	CS_LEAPTAB,
177 	CS_TAI,
178 	CS_CERTIF,
179 #endif /* OPENSSL */
180 	0
181 };
182 
183 
184 /*
185  * Peer variable list
186  */
187 static struct ctl_var peer_var[] = {
188 	{ 0,		PADDING, "" },		/* 0 */
189 	{ CP_CONFIG,	RO, "config" },		/* 1 */
190 	{ CP_AUTHENABLE, RO,	"authenable" },	/* 2 */
191 	{ CP_AUTHENTIC, RO, "authentic" }, 	/* 3 */
192 	{ CP_SRCADR,	RO, "srcadr" },		/* 4 */
193 	{ CP_SRCPORT,	RO, "srcport" },	/* 5 */
194 	{ CP_DSTADR,	RO, "dstadr" },		/* 6 */
195 	{ CP_DSTPORT,	RO, "dstport" },	/* 7 */
196 	{ CP_LEAP,	RO, "leap" },		/* 8 */
197 	{ CP_HMODE,	RO, "hmode" },		/* 9 */
198 	{ CP_STRATUM,	RO, "stratum" },	/* 10 */
199 	{ CP_PPOLL,	RO, "ppoll" },		/* 11 */
200 	{ CP_HPOLL,	RO, "hpoll" },		/* 12 */
201 	{ CP_PRECISION,	RO, "precision" },	/* 13 */
202 	{ CP_ROOTDELAY,	RO, "rootdelay" },	/* 14 */
203 	{ CP_ROOTDISPERSION, RO, "rootdispersion" }, /* 15 */
204 	{ CP_REFID,	RO, "refid" },		/* 16 */
205 	{ CP_REFTIME,	RO, "reftime" },	/* 17 */
206 	{ CP_ORG,	RO, "org" },		/* 18 */
207 	{ CP_REC,	RO, "rec" },		/* 19 */
208 	{ CP_XMT,	RO, "xmt" },		/* 20 */
209 	{ CP_REACH,	RO, "reach" },		/* 21 */
210 	{ CP_UNREACH,	RO, "unreach" },	/* 22 */
211 	{ CP_TIMER,	RO, "timer" },		/* 23 */
212 	{ CP_DELAY,	RO, "delay" },		/* 24 */
213 	{ CP_OFFSET,	RO, "offset" },		/* 25 */
214 	{ CP_JITTER,	RO, "jitter" },		/* 26 */
215 	{ CP_DISPERSION, RO, "dispersion" },	/* 27 */
216 	{ CP_KEYID,	RO, "keyid" },		/* 28 */
217 	{ CP_FILTDELAY,	RO, "filtdelay=" },	/* 29 */
218 	{ CP_FILTOFFSET, RO, "filtoffset=" },	/* 30 */
219 	{ CP_PMODE,	RO, "pmode" },		/* 31 */
220 	{ CP_RECEIVED,	RO, "received"},	/* 32 */
221 	{ CP_SENT,	RO, "sent" },		/* 33 */
222 	{ CP_FILTERROR,	RO, "filtdisp=" },	/* 34 */
223 	{ CP_FLASH,	RO, "flash" },		/* 35 */
224 	{ CP_TTL,	RO, "ttl" },		/* 36 */
225 	{ CP_VARLIST,	RO, "peer_var_list" },	/* 37 */
226 #ifdef OPENSSL
227 	{ CP_FLAGS,	RO, "flags" },		/* 38 */
228 	{ CP_HOST,	RO, "hostname" },	/* 39 */
229 	{ CP_VALID,	RO, "valid" },		/* 40 */
230 	{ CP_INITSEQ,	RO, "initsequence" },   /* 41 */
231 	{ CP_INITKEY,	RO, "initkey" },	/* 42 */
232 	{ CP_INITTSP,	RO, "timestamp" },	/* 43 */
233 	{ CP_DIGEST,	RO, "signature" },	/* 44 */
234 	{ CP_IDENT,	RO, "trust" },		/* 45 */
235 #endif /* OPENSSL */
236 	{ 0,		EOV, "" }		/* 38/46 */
237 };
238 
239 
240 /*
241  * Peer variables we print by default
242  */
243 static u_char def_peer_var[] = {
244 	CP_SRCADR,
245 	CP_SRCPORT,
246 	CP_DSTADR,
247 	CP_DSTPORT,
248 	CP_LEAP,
249 	CP_STRATUM,
250 	CP_PRECISION,
251 	CP_ROOTDELAY,
252 	CP_ROOTDISPERSION,
253 	CP_REFID,
254 	CP_REACH,
255 	CP_UNREACH,
256 	CP_HMODE,
257 	CP_PMODE,
258 	CP_HPOLL,
259 	CP_PPOLL,
260 	CP_FLASH,
261 	CP_KEYID,
262 	CP_TTL,
263 	CP_OFFSET,
264 	CP_DELAY,
265 	CP_DISPERSION,
266 	CP_JITTER,
267 	CP_REFTIME,
268 	CP_ORG,
269 	CP_REC,
270 	CP_XMT,
271 	CP_FILTDELAY,
272 	CP_FILTOFFSET,
273 	CP_FILTERROR,
274 #ifdef OPENSSL
275 	CP_HOST,
276 	CP_DIGEST,
277 	CP_VALID,
278 	CP_FLAGS,
279 	CP_IDENT,
280 	CP_INITSEQ,
281 #endif /* OPENSSL */
282 	0
283 };
284 
285 
286 #ifdef REFCLOCK
287 /*
288  * Clock variable list
289  */
290 static struct ctl_var clock_var[] = {
291 	{ 0,		PADDING, "" },		/* 0 */
292 	{ CC_TYPE,	RO, "type" },		/* 1 */
293 	{ CC_TIMECODE,	RO, "timecode" },	/* 2 */
294 	{ CC_POLL,	RO, "poll" },		/* 3 */
295 	{ CC_NOREPLY,	RO, "noreply" },	/* 4 */
296 	{ CC_BADFORMAT, RO, "badformat" },	/* 5 */
297 	{ CC_BADDATA,	RO, "baddata" },	/* 6 */
298 	{ CC_FUDGETIME1, RO, "fudgetime1" },	/* 7 */
299 	{ CC_FUDGETIME2, RO, "fudgetime2" },	/* 8 */
300 	{ CC_FUDGEVAL1, RO, "stratum" },	/* 9 */
301 	{ CC_FUDGEVAL2, RO, "refid" },		/* 10 */
302 	{ CC_FLAGS,	RO, "flags" },		/* 11 */
303 	{ CC_DEVICE,	RO, "device" },		/* 12 */
304 	{ CC_VARLIST,	RO, "clock_var_list" },	/* 13 */
305 	{ 0,		EOV, ""  }		/* 14 */
306 };
307 
308 
309 /*
310  * Clock variables printed by default
311  */
312 static u_char def_clock_var[] = {
313 	CC_DEVICE,
314 	CC_TYPE,	/* won't be output if device = known */
315 	CC_TIMECODE,
316 	CC_POLL,
317 	CC_NOREPLY,
318 	CC_BADFORMAT,
319 	CC_BADDATA,
320 	CC_FUDGETIME1,
321 	CC_FUDGETIME2,
322 	CC_FUDGEVAL1,
323 	CC_FUDGEVAL2,
324 	CC_FLAGS,
325 	0
326 };
327 #endif
328 
329 
330 /*
331  * System and processor definitions.
332  */
333 #ifndef HAVE_UNAME
334 # ifndef STR_SYSTEM
335 #  define		STR_SYSTEM	"UNIX"
336 # endif
337 # ifndef STR_PROCESSOR
338 #	define		STR_PROCESSOR	"unknown"
339 # endif
340 
341 static char str_system[] = STR_SYSTEM;
342 static char str_processor[] = STR_PROCESSOR;
343 #else
344 # include <sys/utsname.h>
345 static struct utsname utsnamebuf;
346 #endif /* HAVE_UNAME */
347 
348 /*
349  * Trap structures. We only allow a few of these, and send a copy of
350  * each async message to each live one. Traps time out after an hour, it
351  * is up to the trap receipient to keep resetting it to avoid being
352  * timed out.
353  */
354 /* ntp_request.c */
355 struct ctl_trap ctl_trap[CTL_MAXTRAPS];
356 int num_ctl_traps;
357 
358 /*
359  * Type bits, for ctlsettrap() call.
360  */
361 #define TRAP_TYPE_CONFIG	0	/* used by configuration code */
362 #define TRAP_TYPE_PRIO		1	/* priority trap */
363 #define TRAP_TYPE_NONPRIO	2	/* nonpriority trap */
364 
365 
366 /*
367  * List relating reference clock types to control message time sources.
368  * Index by the reference clock type. This list will only be used iff
369  * the reference clock driver doesn't set peer->sstclktype to something
370  * different than CTL_SST_TS_UNSPEC.
371  */
372 static u_char clocktypes[] = {
373 	CTL_SST_TS_NTP, 	/* REFCLK_NONE (0) */
374 	CTL_SST_TS_LOCAL,	/* REFCLK_LOCALCLOCK (1) */
375 	CTL_SST_TS_UHF, 	/* deprecated REFCLK_GPS_TRAK (2) */
376 	CTL_SST_TS_HF,		/* REFCLK_WWV_PST (3) */
377 	CTL_SST_TS_LF,		/* REFCLK_WWVB_SPECTRACOM (4) */
378 	CTL_SST_TS_UHF, 	/* REFCLK_TRUETIME (5) */
379 	CTL_SST_TS_UHF, 	/* REFCLK_GOES_TRAK (6) IRIG_AUDIO? */
380 	CTL_SST_TS_HF,		/* REFCLK_CHU (7) */
381 	CTL_SST_TS_LF,		/* REFCLOCK_PARSE (default) (8) */
382 	CTL_SST_TS_LF,		/* REFCLK_GPS_MX4200 (9) */
383 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_AS2201 (10) */
384 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_ARBITER (11) */
385 	CTL_SST_TS_UHF, 	/* REFCLK_IRIG_TPRO (12) */
386 	CTL_SST_TS_ATOM,	/* REFCLK_ATOM_LEITCH (13) */
387 	CTL_SST_TS_LF,		/* deprecated REFCLK_MSF_EES (14) */
388 	CTL_SST_TS_NTP, 	/* not used (15) */
389 	CTL_SST_TS_UHF, 	/* REFCLK_IRIG_BANCOMM (16) */
390 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_DATU (17) */
391 	CTL_SST_TS_TELEPHONE,	/* REFCLK_NIST_ACTS (18) */
392 	CTL_SST_TS_HF,		/* REFCLK_WWV_HEATH (19) */
393 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_NMEA (20) */
394 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_VME (21) */
395 	CTL_SST_TS_ATOM,	/* REFCLK_ATOM_PPS (22) */
396 	CTL_SST_TS_NTP,		/* not used (23) */
397 	CTL_SST_TS_NTP,		/* not used (24) */
398 	CTL_SST_TS_NTP, 	/* not used (25) */
399 	CTL_SST_TS_UHF, 	/* REFCLK_GPS_HP (26) */
400 	CTL_SST_TS_TELEPHONE,	/* REFCLK_ARCRON_MSF (27) */
401 	CTL_SST_TS_TELEPHONE,	/* REFCLK_SHM (28) */
402 	CTL_SST_TS_UHF, 	/* REFCLK_PALISADE (29) */
403 	CTL_SST_TS_UHF, 	/* REFCLK_ONCORE (30) */
404 	CTL_SST_TS_UHF,		/* REFCLK_JUPITER (31) */
405 	CTL_SST_TS_LF,		/* REFCLK_CHRONOLOG (32) */
406 	CTL_SST_TS_LF,		/* REFCLK_DUMBCLOCK (33) */
407 	CTL_SST_TS_LF,		/* REFCLK_ULINK (34) */
408 	CTL_SST_TS_LF,		/* REFCLK_PCF (35) */
409 	CTL_SST_TS_LF,		/* REFCLK_WWV (36) */
410 	CTL_SST_TS_LF,		/* REFCLK_FG (37) */
411 	CTL_SST_TS_UHF, 	/* REFCLK_HOPF_SERIAL (38) */
412 	CTL_SST_TS_UHF,		/* REFCLK_HOPF_PCI (39) */
413 	CTL_SST_TS_LF,		/* REFCLK_JJY (40) */
414 	CTL_SST_TS_UHF,		/* REFCLK_TT560 (41) */
415 	CTL_SST_TS_UHF,		/* REFCLK_ZYFER (42) */
416 	CTL_SST_TS_UHF,		/* REFCLK_RIPENCC (43) */
417 	CTL_SST_TS_UHF,		/* REFCLK_NEOCLOCK4X (44) */
418 };
419 
420 
421 /*
422  * Keyid used for authenticating write requests.
423  */
424 keyid_t ctl_auth_keyid;
425 
426 /*
427  * We keep track of the last error reported by the system internally
428  */
429 static	u_char ctl_sys_last_event;
430 static	u_char ctl_sys_num_events;
431 
432 
433 /*
434  * Statistic counters to keep track of requests and responses.
435  */
436 u_long ctltimereset;		/* time stats reset */
437 u_long numctlreq;		/* number of requests we've received */
438 u_long numctlbadpkts;		/* number of bad control packets */
439 u_long numctlresponses; 	/* number of resp packets sent with data */
440 u_long numctlfrags; 		/* number of fragments sent */
441 u_long numctlerrors;		/* number of error responses sent */
442 u_long numctltooshort;		/* number of too short input packets */
443 u_long numctlinputresp; 	/* number of responses on input */
444 u_long numctlinputfrag; 	/* number of fragments on input */
445 u_long numctlinputerr;		/* number of input pkts with err bit set */
446 u_long numctlbadoffset; 	/* number of input pkts with nonzero offset */
447 u_long numctlbadversion;	/* number of input pkts with unknown version */
448 u_long numctldatatooshort;	/* data too short for count */
449 u_long numctlbadop; 		/* bad op code found in packet */
450 u_long numasyncmsgs;		/* number of async messages we've sent */
451 
452 /*
453  * Response packet used by these routines. Also some state information
454  * so that we can handle packet formatting within a common set of
455  * subroutines.  Note we try to enter data in place whenever possible,
456  * but the need to set the more bit correctly means we occasionally
457  * use the extra buffer and copy.
458  */
459 static struct ntp_control rpkt;
460 static u_char	res_version;
461 static u_char	res_opcode;
462 static associd_t res_associd;
463 static int	res_offset;
464 static u_char * datapt;
465 static u_char * dataend;
466 static int	datalinelen;
467 static int	datanotbinflag;
468 static struct sockaddr_storage *rmt_addr;
469 static struct interface *lcl_inter;
470 
471 static u_char	res_authenticate;
472 static u_char	res_authokay;
473 static keyid_t	res_keyid;
474 
475 #define MAXDATALINELEN	(72)
476 
477 static u_char	res_async;	/* set to 1 if this is async trap response */
478 
479 /*
480  * Pointers for saving state when decoding request packets
481  */
482 static	char *reqpt;
483 static	char *reqend;
484 
485 /*
486  * init_control - initialize request data
487  */
488 void
489 init_control(void)
490 {
491 	int i;
492 
493 #ifdef HAVE_UNAME
494 	uname(&utsnamebuf);
495 #endif /* HAVE_UNAME */
496 
497 	ctl_clr_stats();
498 
499 	ctl_auth_keyid = 0;
500 	ctl_sys_last_event = EVNT_UNSPEC;
501 	ctl_sys_num_events = 0;
502 
503 	num_ctl_traps = 0;
504 	for (i = 0; i < CTL_MAXTRAPS; i++)
505 		ctl_trap[i].tr_flags = 0;
506 }
507 
508 
509 /*
510  * ctl_error - send an error response for the current request
511  */
512 static void
513 ctl_error(
514 	int errcode
515 	)
516 {
517 #ifdef DEBUG
518 	if (debug >= 4)
519 		printf("sending control error %d\n", errcode);
520 #endif
521 	/*
522 	 * Fill in the fields. We assume rpkt.sequence and rpkt.associd
523 	 * have already been filled in.
524 	 */
525 	rpkt.r_m_e_op = (u_char) (CTL_RESPONSE|CTL_ERROR|(res_opcode &
526 	    CTL_OP_MASK));
527 	rpkt.status = htons((u_short) ((errcode<<8) & 0xff00));
528 	rpkt.count = 0;
529 
530 	/*
531 	 * send packet and bump counters
532 	 */
533 	if (res_authenticate && sys_authenticate) {
534 		int maclen;
535 
536 		*(u_int32 *)((u_char *)&rpkt + CTL_HEADER_LEN) =
537 		    htonl(res_keyid);
538 		maclen = authencrypt(res_keyid, (u_int32 *)&rpkt,
539 		    CTL_HEADER_LEN);
540 		sendpkt(rmt_addr, lcl_inter, -2, (struct pkt *)&rpkt,
541 		    CTL_HEADER_LEN + maclen);
542 	} else {
543 		sendpkt(rmt_addr, lcl_inter, -3, (struct pkt *)&rpkt,
544 		    CTL_HEADER_LEN);
545 	}
546 	numctlerrors++;
547 }
548 
549 
550 /*
551  * process_control - process an incoming control message
552  */
553 void
554 process_control(
555 	struct recvbuf *rbufp,
556 	int restrict_mask
557 	)
558 {
559 	register struct ntp_control *pkt;
560 	register int req_count;
561 	register int req_data;
562 	register struct ctl_proc *cc;
563 	int properlen;
564 	int maclen;
565 
566 #ifdef DEBUG
567 	if (debug > 2)
568 		printf("in process_control()\n");
569 #endif
570 
571 	/*
572 	 * Save the addresses for error responses
573 	 */
574 	numctlreq++;
575 	rmt_addr = &rbufp->recv_srcadr;
576 	lcl_inter = rbufp->dstadr;
577 	pkt = (struct ntp_control *)&rbufp->recv_pkt;
578 
579 	/*
580 	 * If the length is less than required for the header, or
581 	 * it is a response or a fragment, ignore this.
582 	 */
583 	if (rbufp->recv_length < CTL_HEADER_LEN
584 	    || pkt->r_m_e_op & (CTL_RESPONSE|CTL_MORE|CTL_ERROR)
585 	    || pkt->offset != 0) {
586 #ifdef DEBUG
587 		if (debug)
588 			printf("invalid format in control packet\n");
589 #endif
590 		if (rbufp->recv_length < CTL_HEADER_LEN)
591 			numctltooshort++;
592 		if (pkt->r_m_e_op & CTL_RESPONSE)
593 			numctlinputresp++;
594 		if (pkt->r_m_e_op & CTL_MORE)
595 			numctlinputfrag++;
596 		if (pkt->r_m_e_op & CTL_ERROR)
597 			numctlinputerr++;
598 		if (pkt->offset != 0)
599 			numctlbadoffset++;
600 		return;
601 	}
602 	res_version = PKT_VERSION(pkt->li_vn_mode);
603 	if (res_version > NTP_VERSION || res_version < NTP_OLDVERSION) {
604 #ifdef DEBUG
605 		if (debug)
606 			printf("unknown version %d in control packet\n",
607 			   res_version);
608 #endif
609 		numctlbadversion++;
610 		return;
611 	}
612 
613 	/*
614 	 * Pull enough data from the packet to make intelligent
615 	 * responses
616 	 */
617 	rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, res_version,
618 	    MODE_CONTROL);
619 	res_opcode = pkt->r_m_e_op;
620 	rpkt.sequence = pkt->sequence;
621 	rpkt.associd = pkt->associd;
622 	rpkt.status = 0;
623 	res_offset = 0;
624 	res_associd = htons(pkt->associd);
625 	res_async = 0;
626 	res_authenticate = 0;
627 	res_keyid = 0;
628 	res_authokay = 0;
629 	req_count = (int)htons(pkt->count);
630 	datanotbinflag = 0;
631 	datalinelen = 0;
632 	datapt = rpkt.data;
633 	dataend = &(rpkt.data[CTL_MAX_DATA_LEN]);
634 
635 	/*
636 	 * We're set up now. Make sure we've got at least enough
637 	 * incoming data space to match the count.
638 	 */
639 	req_data = rbufp->recv_length - CTL_HEADER_LEN;
640 	if (req_data < req_count || rbufp->recv_length & 0x3) {
641 		ctl_error(CERR_BADFMT);
642 		numctldatatooshort++;
643 		return;
644 	}
645 
646 	properlen = req_count + CTL_HEADER_LEN;
647 #ifdef DEBUG
648 	if (debug > 2 && (rbufp->recv_length & 0x3) != 0)
649 		printf("Packet length %d unrounded\n",
650 		    rbufp->recv_length);
651 #endif
652 	/* round up proper len to a 8 octet boundary */
653 
654 	properlen = (properlen + 7) & ~7;
655 	maclen = rbufp->recv_length - properlen;
656 	if ((rbufp->recv_length & (sizeof(u_long) - 1)) == 0 &&
657 	    maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN &&
658 	    sys_authenticate) {
659 		res_authenticate = 1;
660 		res_keyid = ntohl(*(u_int32 *)((u_char *)pkt +
661 		    properlen));
662 
663 #ifdef DEBUG
664 		if (debug > 2)
665 			printf(
666 			    "recv_len %d, properlen %d, wants auth with keyid %08x, MAC length=%d\n",
667 			    rbufp->recv_length, properlen, res_keyid, maclen);
668 #endif
669 		if (!authistrusted(res_keyid)) {
670 #ifdef DEBUG
671 			if (debug > 2)
672 				printf("invalid keyid %08x\n",
673 				    res_keyid);
674 #endif
675 		} else if (authdecrypt(res_keyid, (u_int32 *)pkt,
676 		    rbufp->recv_length - maclen, maclen)) {
677 #ifdef DEBUG
678 			if (debug > 2)
679 				printf("authenticated okay\n");
680 #endif
681 			res_authokay = 1;
682 		} else {
683 #ifdef DEBUG
684 			if (debug > 2)
685 				printf("authentication failed\n");
686 #endif
687 			res_keyid = 0;
688 		}
689 	}
690 
691 	/*
692 	 * Set up translate pointers
693 	 */
694 	reqpt = (char *)pkt->data;
695 	reqend = reqpt + req_count;
696 
697 	/*
698 	 * Look for the opcode processor
699 	 */
700 	for (cc = control_codes; cc->control_code != NO_REQUEST; cc++) {
701 		if (cc->control_code == res_opcode) {
702 #ifdef DEBUG
703 			if (debug > 2)
704 				printf("opcode %d, found command handler\n",
705 				    res_opcode);
706 #endif
707 			if (cc->flags == AUTH && (!res_authokay ||
708 			    res_keyid != ctl_auth_keyid)) {
709 				ctl_error(CERR_PERMISSION);
710 				return;
711 			}
712 			(cc->handler)(rbufp, restrict_mask);
713 			return;
714 		}
715 	}
716 
717 	/*
718 	 * Can't find this one, return an error.
719 	 */
720 	numctlbadop++;
721 	ctl_error(CERR_BADOP);
722 	return;
723 }
724 
725 
726 /*
727  * ctlpeerstatus - return a status word for this peer
728  */
729 u_short
730 ctlpeerstatus(
731 	register struct peer *peer
732 	)
733 {
734 	register u_short status;
735 
736 	status = peer->status;
737 	if (peer->flags & FLAG_CONFIG)
738 		status |= CTL_PST_CONFIG;
739 	if (peer->flags & FLAG_AUTHENABLE)
740 		status |= CTL_PST_AUTHENABLE;
741 	if (peer->flags & FLAG_AUTHENTIC)
742 		status |= CTL_PST_AUTHENTIC;
743 	if (peer->reach != 0)
744 		status |= CTL_PST_REACH;
745 	return (u_short)CTL_PEER_STATUS(status, peer->num_events,
746 	    peer->last_event);
747 }
748 
749 
750 /*
751  * ctlclkstatus - return a status word for this clock
752  */
753 #ifdef REFCLOCK
754 static u_short
755 ctlclkstatus(
756 	struct refclockstat *this_clock
757 	)
758 {
759 	return ((u_short)(((this_clock->currentstatus) << 8) |
760 	    (this_clock->lastevent)));
761 }
762 #endif
763 
764 
765 /*
766  * ctlsysstatus - return the system status word
767  */
768 u_short
769 ctlsysstatus(void)
770 {
771 	register u_char this_clock;
772 
773 	this_clock = CTL_SST_TS_UNSPEC;
774 #ifdef REFCLOCK
775 	if (sys_peer != 0) {
776 		if (sys_peer->sstclktype != CTL_SST_TS_UNSPEC) {
777 			this_clock = sys_peer->sstclktype;
778 			if (pps_control)
779 				this_clock |= CTL_SST_TS_PPS;
780 		} else {
781 			if (sys_peer->refclktype < sizeof(clocktypes))
782 				this_clock =
783 				    clocktypes[sys_peer->refclktype];
784 			if (pps_control)
785 				this_clock |= CTL_SST_TS_PPS;
786 		}
787 	}
788 #endif /* REFCLOCK */
789 	return (u_short)CTL_SYS_STATUS(sys_leap, this_clock,
790 	    ctl_sys_num_events, ctl_sys_last_event);
791 }
792 
793 
794 /*
795  * ctl_flushpkt - write out the current packet and prepare
796  *		  another if necessary.
797  */
798 static void
799 ctl_flushpkt(
800 	int more
801 	)
802 {
803 	int dlen;
804 	int sendlen;
805 
806 	if (!more && datanotbinflag) {
807 		/*
808 		 * Big hack, output a trailing \r\n
809 		 */
810 		*datapt++ = '\r';
811 		*datapt++ = '\n';
812 	}
813 	dlen = datapt - (u_char *)rpkt.data;
814 	sendlen = dlen + CTL_HEADER_LEN;
815 
816 	/*
817 	 * Pad to a multiple of 32 bits
818 	 */
819 	while (sendlen & 0x3) {
820 		*datapt++ = '\0';
821 		sendlen++;
822 	}
823 
824 	/*
825 	 * Fill in the packet with the current info
826 	 */
827 	rpkt.r_m_e_op = (u_char)(CTL_RESPONSE|more|(res_opcode &
828 	    CTL_OP_MASK));
829 	rpkt.count = htons((u_short) dlen);
830 	rpkt.offset = htons( (u_short) res_offset);
831 	if (res_async) {
832 		register int i;
833 
834 		for (i = 0; i < CTL_MAXTRAPS; i++) {
835 			if (ctl_trap[i].tr_flags & TRAP_INUSE) {
836 				rpkt.li_vn_mode =
837 				    PKT_LI_VN_MODE(sys_leap,
838 				    ctl_trap[i].tr_version,
839 				    MODE_CONTROL);
840 				rpkt.sequence =
841 				    htons(ctl_trap[i].tr_sequence);
842 				sendpkt(&ctl_trap[i].tr_addr,
843 					ctl_trap[i].tr_localaddr, -4,
844 					(struct pkt *)&rpkt, sendlen);
845 				if (!more)
846 					ctl_trap[i].tr_sequence++;
847 				numasyncmsgs++;
848 			}
849 		}
850 	} else {
851 		if (res_authenticate && sys_authenticate) {
852 			int maclen;
853 			int totlen = sendlen;
854 			keyid_t keyid = htonl(res_keyid);
855 
856 			/*
857 			 * If we are going to authenticate, then there
858 			 * is an additional requirement that the MAC
859 			 * begin on a 64 bit boundary.
860 			 */
861 			while (totlen & 7) {
862 				*datapt++ = '\0';
863 				totlen++;
864 			}
865 			memcpy(datapt, &keyid, sizeof keyid);
866 			maclen = authencrypt(res_keyid,
867 			    (u_int32 *)&rpkt, totlen);
868 			sendpkt(rmt_addr, lcl_inter, -5,
869 			    (struct pkt *)&rpkt, totlen + maclen);
870 		} else {
871 			sendpkt(rmt_addr, lcl_inter, -6,
872 			    (struct pkt *)&rpkt, sendlen);
873 		}
874 		if (more)
875 			numctlfrags++;
876 		else
877 			numctlresponses++;
878 	}
879 
880 	/*
881 	 * Set us up for another go around.
882 	 */
883 	res_offset += dlen;
884 	datapt = (u_char *)rpkt.data;
885 }
886 
887 
888 /*
889  * ctl_putdata - write data into the packet, fragmenting and starting
890  * another if this one is full.
891  */
892 static void
893 ctl_putdata(
894 	const char *dp,
895 	unsigned int dlen,
896 	int bin 		/* set to 1 when data is binary */
897 	)
898 {
899 	int overhead;
900 	unsigned int currentlen;
901 
902 	overhead = 0;
903 	if (!bin) {
904 		datanotbinflag = 1;
905 		overhead = 3;
906 		if (datapt != rpkt.data) {
907 			*datapt++ = ',';
908 			datalinelen++;
909 			if ((dlen + datalinelen + 1) >= MAXDATALINELEN)
910 			    {
911 				*datapt++ = '\r';
912 				*datapt++ = '\n';
913 				datalinelen = 0;
914 			} else {
915 				*datapt++ = ' ';
916 				datalinelen++;
917 			}
918 		}
919 	}
920 
921 	/*
922 	 * Save room for trailing junk
923 	 */
924 	while (dlen + overhead + datapt > dataend) {
925 		/*
926 		 * Not enough room in this one, flush it out.
927 		 */
928 		currentlen = MIN(dlen, dataend - datapt);
929 
930 		memcpy(datapt, dp, currentlen);
931 
932 		datapt += currentlen;
933 		dp += currentlen;
934 		dlen -= currentlen;
935 		datalinelen += currentlen;
936 
937 		ctl_flushpkt(CTL_MORE);
938 	}
939 
940 	memmove((char *)datapt, dp, (unsigned)dlen);
941 	datapt += dlen;
942 	datalinelen += dlen;
943 }
944 
945 
946 /*
947  * ctl_putstr - write a tagged string into the response packet
948  */
949 static void
950 ctl_putstr(
951 	const char *tag,
952 	const char *data,
953 	unsigned int len
954 	)
955 {
956 	register char *cp;
957 	register const char *cq;
958 	char buffer[400];
959 
960 	cp = buffer;
961 	cq = tag;
962 	while (*cq != '\0')
963 		*cp++ = *cq++;
964 	if (len > 0) {
965 		*cp++ = '=';
966 		*cp++ = '"';
967 		if (len > (int) (sizeof(buffer) - (cp - buffer) - 1))
968 			len = sizeof(buffer) - (cp - buffer) - 1;
969 		memmove(cp, data, (unsigned)len);
970 		cp += len;
971 		*cp++ = '"';
972 	}
973 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
974 }
975 
976 
977 /*
978  * ctl_putdbl - write a tagged, signed double into the response packet
979  */
980 static void
981 ctl_putdbl(
982 	const char *tag,
983 	double ts
984 	)
985 {
986 	register char *cp;
987 	register const char *cq;
988 	char buffer[200];
989 
990 	cp = buffer;
991 	cq = tag;
992 	while (*cq != '\0')
993 		*cp++ = *cq++;
994 	*cp++ = '=';
995 	(void)sprintf(cp, "%.3f", ts);
996 	while (*cp != '\0')
997 		cp++;
998 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
999 }
1000 
1001 /*
1002  * ctl_putuint - write a tagged unsigned integer into the response
1003  */
1004 static void
1005 ctl_putuint(
1006 	const char *tag,
1007 	u_long uval
1008 	)
1009 {
1010 	register char *cp;
1011 	register const char *cq;
1012 	char buffer[200];
1013 
1014 	cp = buffer;
1015 	cq = tag;
1016 	while (*cq != '\0')
1017 		*cp++ = *cq++;
1018 
1019 	*cp++ = '=';
1020 	(void) sprintf(cp, "%lu", uval);
1021 	while (*cp != '\0')
1022 		cp++;
1023 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
1024 }
1025 
1026 /*
1027  * ctl_putfs - write a decoded filestamp into the response
1028  */
1029 #ifdef OPENSSL
1030 static void
1031 ctl_putfs(
1032 	const char *tag,
1033 	tstamp_t uval
1034 	)
1035 {
1036 	register char *cp;
1037 	register const char *cq;
1038 	char buffer[200];
1039 	struct tm *tm = NULL;
1040 	time_t fstamp;
1041 
1042 	cp = buffer;
1043 	cq = tag;
1044 	while (*cq != '\0')
1045 		*cp++ = *cq++;
1046 
1047 	*cp++ = '=';
1048 	fstamp = uval - JAN_1970;
1049 	tm = gmtime(&fstamp);
1050 	if (tm == NULL)
1051 		return;
1052 
1053 	sprintf(cp, "%04d%02d%02d%02d%02d", tm->tm_year + 1900,
1054 	    tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
1055 	while (*cp != '\0')
1056 		cp++;
1057 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
1058 }
1059 #endif
1060 
1061 
1062 /*
1063  * ctl_puthex - write a tagged unsigned integer, in hex, into the response
1064  */
1065 static void
1066 ctl_puthex(
1067 	const char *tag,
1068 	u_long uval
1069 	)
1070 {
1071 	register char *cp;
1072 	register const char *cq;
1073 	char buffer[200];
1074 
1075 	cp = buffer;
1076 	cq = tag;
1077 	while (*cq != '\0')
1078 		*cp++ = *cq++;
1079 
1080 	*cp++ = '=';
1081 	(void) sprintf(cp, "0x%lx", uval);
1082 	while (*cp != '\0')
1083 		cp++;
1084 	ctl_putdata(buffer,(unsigned)( cp - buffer ), 0);
1085 }
1086 
1087 
1088 /*
1089  * ctl_putint - write a tagged signed integer into the response
1090  */
1091 static void
1092 ctl_putint(
1093 	const char *tag,
1094 	long ival
1095 	)
1096 {
1097 	register char *cp;
1098 	register const char *cq;
1099 	char buffer[200];
1100 
1101 	cp = buffer;
1102 	cq = tag;
1103 	while (*cq != '\0')
1104 		*cp++ = *cq++;
1105 
1106 	*cp++ = '=';
1107 	(void) sprintf(cp, "%ld", ival);
1108 	while (*cp != '\0')
1109 		cp++;
1110 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
1111 }
1112 
1113 
1114 /*
1115  * ctl_putts - write a tagged timestamp, in hex, into the response
1116  */
1117 static void
1118 ctl_putts(
1119 	const char *tag,
1120 	l_fp *ts
1121 	)
1122 {
1123 	register char *cp;
1124 	register const char *cq;
1125 	char buffer[200];
1126 
1127 	cp = buffer;
1128 	cq = tag;
1129 	while (*cq != '\0')
1130 		*cp++ = *cq++;
1131 
1132 	*cp++ = '=';
1133 	(void) sprintf(cp, "0x%08lx.%08lx",
1134 			   ts->l_ui & ULONG_CONST(0xffffffff),
1135 			   ts->l_uf & ULONG_CONST(0xffffffff));
1136 	while (*cp != '\0')
1137 		cp++;
1138 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
1139 }
1140 
1141 
1142 /*
1143  * ctl_putadr - write an IP address into the response
1144  */
1145 static void
1146 ctl_putadr(
1147 	const char *tag,
1148 	u_int32 addr32,
1149 	struct sockaddr_storage* addr
1150 	)
1151 {
1152 	register char *cp;
1153 	register const char *cq;
1154 	char buffer[200];
1155 
1156 	cp = buffer;
1157 	cq = tag;
1158 	while (*cq != '\0')
1159 		*cp++ = *cq++;
1160 
1161 	*cp++ = '=';
1162 	if (addr == NULL)
1163 		cq = numtoa(addr32);
1164 	else
1165 		cq = stoa(addr);
1166 	while (*cq != '\0')
1167 		*cp++ = *cq++;
1168 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
1169 }
1170 
1171 /*
1172  * ctl_putid - write a tagged clock ID into the response
1173  */
1174 static void
1175 ctl_putid(
1176 	const char *tag,
1177 	char *id
1178 	)
1179 {
1180 	register char *cp;
1181 	register const char *cq;
1182 	char buffer[200];
1183 
1184 	cp = buffer;
1185 	cq = tag;
1186 	while (*cq != '\0')
1187 		*cp++ = *cq++;
1188 
1189 	*cp++ = '=';
1190 	cq = id;
1191 	while (*cq != '\0' && (cq - id) < 4)
1192 		*cp++ = *cq++;
1193 	ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
1194 }
1195 
1196 
1197 /*
1198  * ctl_putarray - write a tagged eight element double array into the response
1199  */
1200 static void
1201 ctl_putarray(
1202 	const char *tag,
1203 	double *arr,
1204 	int start
1205 	)
1206 {
1207 	register char *cp;
1208 	register const char *cq;
1209 	char buffer[200];
1210 	int i;
1211 	cp = buffer;
1212 	cq = tag;
1213 	while (*cq != '\0')
1214 		*cp++ = *cq++;
1215 	i = start;
1216 	do {
1217 		if (i == 0)
1218 			i = NTP_SHIFT;
1219 		i--;
1220 		(void)sprintf(cp, " %.2f", arr[i] * 1e3);
1221 		while (*cp != '\0')
1222 			cp++;
1223 	} while(i != start);
1224 	ctl_putdata(buffer, (unsigned)(cp - buffer), 0);
1225 }
1226 
1227 
1228 /*
1229  * ctl_putsys - output a system variable
1230  */
1231 static void
1232 ctl_putsys(
1233 	int varid
1234 	)
1235 {
1236 	l_fp tmp;
1237 	char str[256];
1238 #ifdef OPENSSL
1239 	struct cert_info *cp;
1240 	char cbuf[256];
1241 #endif /* OPENSSL */
1242 
1243 	switch (varid) {
1244 
1245 	case CS_LEAP:
1246 		ctl_putuint(sys_var[CS_LEAP].text, sys_leap);
1247 		break;
1248 
1249 	case CS_STRATUM:
1250 		ctl_putuint(sys_var[CS_STRATUM].text, sys_stratum);
1251 		break;
1252 
1253 	case CS_PRECISION:
1254 		ctl_putint(sys_var[CS_PRECISION].text, sys_precision);
1255 		break;
1256 
1257 	case CS_ROOTDELAY:
1258 		ctl_putdbl(sys_var[CS_ROOTDELAY].text, sys_rootdelay *
1259 		    1e3);
1260 		break;
1261 
1262 	case CS_ROOTDISPERSION:
1263 		ctl_putdbl(sys_var[CS_ROOTDISPERSION].text,
1264 		    sys_rootdispersion * 1e3);
1265 		break;
1266 
1267 	case CS_REFID:
1268 		if (sys_stratum > 1 && sys_stratum < STRATUM_UNSPEC)
1269 			ctl_putadr(sys_var[CS_REFID].text, sys_refid, NULL);
1270 		else
1271 			ctl_putid(sys_var[CS_REFID].text,
1272 			    (char *)&sys_refid);
1273 		break;
1274 
1275 	case CS_REFTIME:
1276 		ctl_putts(sys_var[CS_REFTIME].text, &sys_reftime);
1277 		break;
1278 
1279 	case CS_POLL:
1280 		ctl_putuint(sys_var[CS_POLL].text, sys_poll);
1281 		break;
1282 
1283 	case CS_PEERID:
1284 		if (sys_peer == NULL)
1285 			ctl_putuint(sys_var[CS_PEERID].text, 0);
1286 		else
1287 			ctl_putuint(sys_var[CS_PEERID].text,
1288 				sys_peer->associd);
1289 		break;
1290 
1291 	case CS_STATE:
1292 		ctl_putuint(sys_var[CS_STATE].text, (unsigned)state);
1293 		break;
1294 
1295 	case CS_OFFSET:
1296 		ctl_putdbl(sys_var[CS_OFFSET].text, last_offset * 1e3);
1297 		break;
1298 
1299 	case CS_DRIFT:
1300 		ctl_putdbl(sys_var[CS_DRIFT].text, drift_comp * 1e6);
1301 		break;
1302 
1303 	case CS_JITTER:
1304 		ctl_putdbl(sys_var[CS_JITTER].text, sys_jitter * 1e3);
1305 		break;
1306 
1307 	case CS_ERROR:
1308 		ctl_putdbl(sys_var[CS_ERROR].text, clock_jitter * 1e3);
1309 		break;
1310 
1311 	case CS_CLOCK:
1312 		get_systime(&tmp);
1313 		ctl_putts(sys_var[CS_CLOCK].text, &tmp);
1314 		break;
1315 
1316 	case CS_PROCESSOR:
1317 #ifndef HAVE_UNAME
1318 		ctl_putstr(sys_var[CS_PROCESSOR].text, str_processor,
1319 		    sizeof(str_processor) - 1);
1320 #else
1321 		ctl_putstr(sys_var[CS_PROCESSOR].text,
1322 		    utsnamebuf.machine, strlen(utsnamebuf.machine));
1323 #endif /* HAVE_UNAME */
1324 		break;
1325 
1326 	case CS_SYSTEM:
1327 #ifndef HAVE_UNAME
1328 		ctl_putstr(sys_var[CS_SYSTEM].text, str_system,
1329 		    sizeof(str_system) - 1);
1330 #else
1331 		sprintf(str, "%s/%s", utsnamebuf.sysname, utsnamebuf.release);
1332 		ctl_putstr(sys_var[CS_SYSTEM].text, str, strlen(str));
1333 #endif /* HAVE_UNAME */
1334 		break;
1335 
1336 	case CS_VERSION:
1337 		ctl_putstr(sys_var[CS_VERSION].text, Version,
1338 		    strlen(Version));
1339 		break;
1340 
1341 	case CS_STABIL:
1342 		ctl_putdbl(sys_var[CS_STABIL].text, clock_stability *
1343 		    1e6);
1344 		break;
1345 
1346 	case CS_VARLIST:
1347 		{
1348 			char buf[CTL_MAX_DATA_LEN];
1349 			register char *s, *t, *be;
1350 			register const char *ss;
1351 			register int i;
1352 			register struct ctl_var *k;
1353 
1354 			s = buf;
1355 			be = buf + sizeof(buf) -
1356 			    strlen(sys_var[CS_VARLIST].text) - 4;
1357 			if (s > be)
1358 				break;	/* really long var name */
1359 
1360 			strcpy(s, sys_var[CS_VARLIST].text);
1361 			strcat(s, "=\"");
1362 			s += strlen(s);
1363 			t = s;
1364 			for (k = sys_var; !(k->flags &EOV); k++) {
1365 				if (k->flags & PADDING)
1366 					continue;
1367 				i = strlen(k->text);
1368 				if (s+i+1 >= be)
1369 				break;
1370 
1371 				if (s != t)
1372 				*s++ = ',';
1373 				strcpy(s, k->text);
1374 				s += i;
1375 			}
1376 
1377 			for (k = ext_sys_var; k && !(k->flags &EOV);
1378 			    k++) {
1379 				if (k->flags & PADDING)
1380 					continue;
1381 
1382 				ss = k->text;
1383 				if (!ss)
1384 					continue;
1385 
1386 				while (*ss && *ss != '=')
1387 					ss++;
1388 				i = ss - k->text;
1389 				if (s + i + 1 >= be)
1390 					break;
1391 
1392 				if (s != t)
1393 				*s++ = ',';
1394 				strncpy(s, k->text,
1395 				    (unsigned)i);
1396 				s += i;
1397 			}
1398 			if (s+2 >= be)
1399 				break;
1400 
1401 			*s++ = '"';
1402 			*s = '\0';
1403 
1404 			ctl_putdata(buf, (unsigned)( s - buf ),
1405 			    0);
1406 		}
1407 		break;
1408 
1409 #ifdef OPENSSL
1410 	case CS_FLAGS:
1411 		if (crypto_flags) {
1412 			ctl_puthex(sys_var[CS_FLAGS].text, crypto_flags);
1413 		}
1414 		break;
1415 
1416 	case CS_DIGEST:
1417 		if (crypto_flags) {
1418 			const EVP_MD *dp;
1419 
1420 			dp = EVP_get_digestbynid(crypto_flags >> 16);
1421 			strcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)));
1422 			ctl_putstr(sys_var[CS_DIGEST].text, str,
1423 			    strlen(str));
1424 		}
1425 		break;
1426 
1427 	case CS_HOST:
1428 		if (sys_hostname != NULL)
1429 			ctl_putstr(sys_var[CS_HOST].text, sys_hostname,
1430 			    strlen(sys_hostname));
1431 		break;
1432 
1433 	case CS_CERTIF:
1434 		for (cp = cinfo; cp != NULL; cp = cp->link) {
1435 			sprintf(cbuf, "%s %s 0x%x", cp->subject,
1436 			    cp->issuer, cp->flags);
1437 			ctl_putstr(sys_var[CS_CERTIF].text, cbuf,
1438 			    strlen(cbuf));
1439 			ctl_putfs(sys_var[CS_REVOKE].text, cp->last);
1440 		}
1441 		break;
1442 
1443 	case CS_PUBLIC:
1444 		if (hostval.fstamp != 0)
1445 			ctl_putfs(sys_var[CS_PUBLIC].text,
1446 			    ntohl(hostval.tstamp));
1447 		break;
1448 
1449 	case CS_REVTIME:
1450 		if (hostval.tstamp != 0)
1451 			ctl_putfs(sys_var[CS_REVTIME].text,
1452 			    ntohl(hostval.tstamp));
1453 		break;
1454 
1455 	case CS_IDENT:
1456 		if (iffpar_pkey != NULL)
1457 			ctl_putstr(sys_var[CS_IDENT].text,
1458 			    iffpar_file, strlen(iffpar_file));
1459 		if (gqpar_pkey != NULL)
1460 			ctl_putstr(sys_var[CS_IDENT].text,
1461 			    gqpar_file, strlen(gqpar_file));
1462 		if (mvpar_pkey != NULL)
1463 			ctl_putstr(sys_var[CS_IDENT].text,
1464 			    mvpar_file, strlen(mvpar_file));
1465 		break;
1466 
1467 	case CS_LEAPTAB:
1468 		if (tai_leap.fstamp != 0)
1469 			ctl_putfs(sys_var[CS_LEAPTAB].text,
1470 			    ntohl(tai_leap.fstamp));
1471 		break;
1472 
1473 	case CS_TAI:
1474 		ctl_putuint(sys_var[CS_TAI].text, sys_tai);
1475 		break;
1476 #endif /* OPENSSL */
1477 	}
1478 }
1479 
1480 
1481 /*
1482  * ctl_putpeer - output a peer variable
1483  */
1484 static void
1485 ctl_putpeer(
1486 	int varid,
1487 	struct peer *peer
1488 	)
1489 {
1490 	int temp;
1491 #ifdef OPENSSL
1492 	char str[256];
1493 	struct autokey *ap;
1494 #endif /* OPENSSL */
1495 
1496 	switch (varid) {
1497 
1498 	case CP_CONFIG:
1499 		ctl_putuint(peer_var[CP_CONFIG].text,
1500 		    (unsigned)((peer->flags & FLAG_CONFIG) != 0));
1501 		break;
1502 
1503 	case CP_AUTHENABLE:
1504 		ctl_putuint(peer_var[CP_AUTHENABLE].text,
1505 		    (unsigned)((peer->flags & FLAG_AUTHENABLE) != 0));
1506 		break;
1507 
1508 	case CP_AUTHENTIC:
1509 		ctl_putuint(peer_var[CP_AUTHENTIC].text,
1510 		    (unsigned)((peer->flags & FLAG_AUTHENTIC) != 0));
1511 		break;
1512 
1513 	case CP_SRCADR:
1514 		ctl_putadr(peer_var[CP_SRCADR].text, 0,
1515 		    &peer->srcadr);
1516 		break;
1517 
1518 	case CP_SRCPORT:
1519 		ctl_putuint(peer_var[CP_SRCPORT].text,
1520 		    ntohs(((struct sockaddr_in*)&peer->srcadr)->sin_port));
1521 		break;
1522 
1523 	case CP_DSTADR:
1524 		if (peer->dstadr) {
1525 			ctl_putadr(peer_var[CP_DSTADR].text, 0,
1526 				   &(peer->dstadr->sin));
1527 		} else {
1528 			ctl_putadr(peer_var[CP_DSTADR].text, 0,
1529 				   NULL);
1530 		}
1531 		break;
1532 
1533 	case CP_DSTPORT:
1534 		ctl_putuint(peer_var[CP_DSTPORT].text,
1535 		    (u_long)(peer->dstadr ?
1536 		    ntohs(((struct sockaddr_in*)&peer->dstadr->sin)->sin_port) : 0));
1537 		break;
1538 
1539 	case CP_LEAP:
1540 		ctl_putuint(peer_var[CP_LEAP].text, peer->leap);
1541 		break;
1542 
1543 	case CP_HMODE:
1544 		ctl_putuint(peer_var[CP_HMODE].text, peer->hmode);
1545 		break;
1546 
1547 	case CP_STRATUM:
1548 		ctl_putuint(peer_var[CP_STRATUM].text, peer->stratum);
1549 		break;
1550 
1551 	case CP_PPOLL:
1552 		ctl_putuint(peer_var[CP_PPOLL].text, peer->ppoll);
1553 		break;
1554 
1555 	case CP_HPOLL:
1556 		ctl_putuint(peer_var[CP_HPOLL].text, peer->hpoll);
1557 		break;
1558 
1559 	case CP_PRECISION:
1560 		ctl_putint(peer_var[CP_PRECISION].text,
1561 		    peer->precision);
1562 		break;
1563 
1564 	case CP_ROOTDELAY:
1565 		ctl_putdbl(peer_var[CP_ROOTDELAY].text,
1566 		    peer->rootdelay * 1e3);
1567 		break;
1568 
1569 	case CP_ROOTDISPERSION:
1570 		ctl_putdbl(peer_var[CP_ROOTDISPERSION].text,
1571 		    peer->rootdispersion * 1e3);
1572 		break;
1573 
1574 	case CP_REFID:
1575 		if (peer->flags & FLAG_REFCLOCK) {
1576 			ctl_putid(peer_var[CP_REFID].text,
1577 			   (char *)&peer->refid);
1578 		} else {
1579 			if (peer->stratum > 1 && peer->stratum <
1580 			    STRATUM_UNSPEC)
1581 				ctl_putadr(peer_var[CP_REFID].text,
1582 				    peer->refid, NULL);
1583 			else
1584 				ctl_putid(peer_var[CP_REFID].text,
1585 				    (char *)&peer->refid);
1586 		}
1587 		break;
1588 
1589 	case CP_REFTIME:
1590 		ctl_putts(peer_var[CP_REFTIME].text, &peer->reftime);
1591 		break;
1592 
1593 	case CP_ORG:
1594 		ctl_putts(peer_var[CP_ORG].text, &peer->org);
1595 		break;
1596 
1597 	case CP_REC:
1598 		ctl_putts(peer_var[CP_REC].text, &peer->rec);
1599 		break;
1600 
1601 	case CP_XMT:
1602 		ctl_putts(peer_var[CP_XMT].text, &peer->xmt);
1603 		break;
1604 
1605 	case CP_REACH:
1606 		ctl_puthex(peer_var[CP_REACH].text, peer->reach);
1607 		break;
1608 
1609 	case CP_FLASH:
1610 		temp = peer->flash;
1611 		ctl_puthex(peer_var[CP_FLASH].text, temp);
1612 		break;
1613 
1614 	case CP_TTL:
1615 		ctl_putint(peer_var[CP_TTL].text, sys_ttl[peer->ttl]);
1616 		break;
1617 
1618 	case CP_UNREACH:
1619 		ctl_putuint(peer_var[CP_UNREACH].text, peer->unreach);
1620 		break;
1621 
1622 	case CP_TIMER:
1623 		ctl_putuint(peer_var[CP_TIMER].text,
1624 		    peer->nextdate - current_time);
1625 		break;
1626 
1627 	case CP_DELAY:
1628 		ctl_putdbl(peer_var[CP_DELAY].text, peer->delay * 1e3);
1629 		break;
1630 
1631 	case CP_OFFSET:
1632 		ctl_putdbl(peer_var[CP_OFFSET].text, peer->offset *
1633 		    1e3);
1634 		break;
1635 
1636 	case CP_JITTER:
1637 		ctl_putdbl(peer_var[CP_JITTER].text, peer->jitter * 1e3);
1638 		break;
1639 
1640 	case CP_DISPERSION:
1641 		ctl_putdbl(peer_var[CP_DISPERSION].text, peer->disp *
1642 		    1e3);
1643 		break;
1644 
1645 	case CP_KEYID:
1646 		ctl_putuint(peer_var[CP_KEYID].text, peer->keyid);
1647 		break;
1648 
1649 	case CP_FILTDELAY:
1650 		ctl_putarray(peer_var[CP_FILTDELAY].text,
1651 		    peer->filter_delay, (int)peer->filter_nextpt);
1652 		break;
1653 
1654 	case CP_FILTOFFSET:
1655 		ctl_putarray(peer_var[CP_FILTOFFSET].text,
1656 		    peer->filter_offset, (int)peer->filter_nextpt);
1657 		break;
1658 
1659 	case CP_FILTERROR:
1660 		ctl_putarray(peer_var[CP_FILTERROR].text,
1661 		    peer->filter_disp, (int)peer->filter_nextpt);
1662 		break;
1663 
1664 	case CP_PMODE:
1665 		ctl_putuint(peer_var[CP_PMODE].text, peer->pmode);
1666 		break;
1667 
1668 	case CP_RECEIVED:
1669 		ctl_putuint(peer_var[CP_RECEIVED].text, peer->received);
1670 		break;
1671 
1672 	case CP_SENT:
1673 		ctl_putuint(peer_var[CP_SENT].text, peer->sent);
1674 		break;
1675 
1676 	case CP_VARLIST:
1677 		{
1678 			char buf[CTL_MAX_DATA_LEN];
1679 			register char *s, *t, *be;
1680 			register int i;
1681 			register struct ctl_var *k;
1682 
1683 			s = buf;
1684 			be = buf + sizeof(buf) -
1685 			    strlen(peer_var[CP_VARLIST].text) - 4;
1686 			if (s > be)
1687 				break;	/* really long var name */
1688 
1689 			strcpy(s, peer_var[CP_VARLIST].text);
1690 			strcat(s, "=\"");
1691 			s += strlen(s);
1692 			t = s;
1693 			for (k = peer_var; !(k->flags &EOV); k++) {
1694 				if (k->flags & PADDING)
1695 					continue;
1696 
1697 				i = strlen(k->text);
1698 				if (s + i + 1 >= be)
1699 				break;
1700 
1701 				if (s != t)
1702 					*s++ = ',';
1703 				strcpy(s, k->text);
1704 				s += i;
1705 			}
1706 			if (s+2 >= be)
1707 				break;
1708 
1709 			*s++ = '"';
1710 			*s = '\0';
1711 			ctl_putdata(buf, (unsigned)(s - buf), 0);
1712 		}
1713 		break;
1714 #ifdef OPENSSL
1715 	case CP_FLAGS:
1716 		if (peer->crypto)
1717 			ctl_puthex(peer_var[CP_FLAGS].text, peer->crypto);
1718 		break;
1719 
1720 	case CP_DIGEST:
1721 		if (peer->crypto) {
1722 			const EVP_MD *dp;
1723 
1724 			dp = EVP_get_digestbynid(peer->crypto >> 16);
1725 			strcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)));
1726 			ctl_putstr(peer_var[CP_DIGEST].text, str,
1727        	                     strlen(str));
1728 		}
1729 		break;
1730 
1731 	case CP_HOST:
1732 		if (peer->subject != NULL)
1733 			ctl_putstr(peer_var[CP_HOST].text,
1734 			    peer->subject, strlen(peer->subject));
1735 		break;
1736 
1737 	case CP_VALID:		/* not used */
1738 		break;
1739 
1740 	case CP_IDENT:
1741 		if (peer->issuer != NULL)
1742 			ctl_putstr(peer_var[CP_IDENT].text,
1743 			    peer->issuer, strlen(peer->issuer));
1744 		break;
1745 
1746 	case CP_INITSEQ:
1747 		if ((ap = (struct autokey *)peer->recval.ptr) == NULL)
1748 			break;
1749 		ctl_putint(peer_var[CP_INITSEQ].text, ap->seq);
1750 		ctl_puthex(peer_var[CP_INITKEY].text, ap->key);
1751 		ctl_putfs(peer_var[CP_INITTSP].text,
1752 		    ntohl(peer->recval.tstamp));
1753 		break;
1754 #endif /* OPENSSL */
1755 	}
1756 }
1757 
1758 
1759 #ifdef REFCLOCK
1760 /*
1761  * ctl_putclock - output clock variables
1762  */
1763 static void
1764 ctl_putclock(
1765 	int varid,
1766 	struct refclockstat *clock_stat,
1767 	int mustput
1768 	)
1769 {
1770 	switch(varid) {
1771 
1772 	case CC_TYPE:
1773 		if (mustput || clock_stat->clockdesc == NULL
1774 			|| *(clock_stat->clockdesc) == '\0') {
1775 			ctl_putuint(clock_var[CC_TYPE].text, clock_stat->type);
1776 		}
1777 		break;
1778 	case CC_TIMECODE:
1779 		ctl_putstr(clock_var[CC_TIMECODE].text,
1780 		    clock_stat->p_lastcode,
1781 		    (unsigned)clock_stat->lencode);
1782 		break;
1783 
1784 	case CC_POLL:
1785 		ctl_putuint(clock_var[CC_POLL].text, clock_stat->polls);
1786 		break;
1787 
1788 	case CC_NOREPLY:
1789 		ctl_putuint(clock_var[CC_NOREPLY].text,
1790 		    clock_stat->noresponse);
1791 		break;
1792 
1793 	case CC_BADFORMAT:
1794 		ctl_putuint(clock_var[CC_BADFORMAT].text,
1795 		    clock_stat->badformat);
1796 		break;
1797 
1798 	case CC_BADDATA:
1799 		ctl_putuint(clock_var[CC_BADDATA].text,
1800 		    clock_stat->baddata);
1801 		break;
1802 
1803 	case CC_FUDGETIME1:
1804 		if (mustput || (clock_stat->haveflags & CLK_HAVETIME1))
1805 			ctl_putdbl(clock_var[CC_FUDGETIME1].text,
1806 			    clock_stat->fudgetime1 * 1e3);
1807 		break;
1808 
1809 	case CC_FUDGETIME2:
1810 		if (mustput || (clock_stat->haveflags & CLK_HAVETIME2)) 			ctl_putdbl(clock_var[CC_FUDGETIME2].text,
1811 			    clock_stat->fudgetime2 * 1e3);
1812 		break;
1813 
1814 	case CC_FUDGEVAL1:
1815 		if (mustput || (clock_stat->haveflags & CLK_HAVEVAL1))
1816 			ctl_putint(clock_var[CC_FUDGEVAL1].text,
1817 			    clock_stat->fudgeval1);
1818 		break;
1819 
1820 	case CC_FUDGEVAL2:
1821 		if (mustput || (clock_stat->haveflags & CLK_HAVEVAL2)) {
1822 			if (clock_stat->fudgeval1 > 1)
1823 				ctl_putadr(clock_var[CC_FUDGEVAL2].text,
1824 				    (u_int32)clock_stat->fudgeval2, NULL);
1825 			else
1826 				ctl_putid(clock_var[CC_FUDGEVAL2].text,
1827 				    (char *)&clock_stat->fudgeval2);
1828 		}
1829 		break;
1830 
1831 	case CC_FLAGS:
1832 		if (mustput || (clock_stat->haveflags &	(CLK_HAVEFLAG1 |
1833 		    CLK_HAVEFLAG2 | CLK_HAVEFLAG3 | CLK_HAVEFLAG4)))
1834 			ctl_putuint(clock_var[CC_FLAGS].text,
1835 			    clock_stat->flags);
1836 		break;
1837 
1838 	case CC_DEVICE:
1839 		if (clock_stat->clockdesc == NULL ||
1840 		    *(clock_stat->clockdesc) == '\0') {
1841 			if (mustput)
1842 				ctl_putstr(clock_var[CC_DEVICE].text,
1843 				    "", 0);
1844 		} else {
1845 			ctl_putstr(clock_var[CC_DEVICE].text,
1846 			    clock_stat->clockdesc,
1847 			    strlen(clock_stat->clockdesc));
1848 		}
1849 		break;
1850 
1851 	case CC_VARLIST:
1852 		{
1853 			char buf[CTL_MAX_DATA_LEN];
1854 			register char *s, *t, *be;
1855 			register const char *ss;
1856 			register int i;
1857 			register struct ctl_var *k;
1858 
1859 			s = buf;
1860 			be = buf + sizeof(buf);
1861 			if (s + strlen(clock_var[CC_VARLIST].text) + 4 >
1862 			    be)
1863 				break;	/* really long var name */
1864 
1865 			strcpy(s, clock_var[CC_VARLIST].text);
1866 			strcat(s, "=\"");
1867 			s += strlen(s);
1868 			t = s;
1869 
1870 			for (k = clock_var; !(k->flags &EOV); k++) {
1871 				if (k->flags & PADDING)
1872 					continue;
1873 
1874 				i = strlen(k->text);
1875 				if (s + i + 1 >= be)
1876 					break;
1877 
1878 				if (s != t)
1879 				*s++ = ',';
1880 				strcpy(s, k->text);
1881 				s += i;
1882 			}
1883 
1884 			for (k = clock_stat->kv_list; k && !(k->flags &
1885 			    EOV); k++) {
1886 				if (k->flags & PADDING)
1887 					continue;
1888 
1889 				ss = k->text;
1890 				if (!ss)
1891 					continue;
1892 
1893 				while (*ss && *ss != '=')
1894 					ss++;
1895 				i = ss - k->text;
1896 				if (s+i+1 >= be)
1897 					break;
1898 
1899 				if (s != t)
1900 					*s++ = ',';
1901 				strncpy(s, k->text, (unsigned)i);
1902 				s += i;
1903 				*s = '\0';
1904 			}
1905 			if (s+2 >= be)
1906 				break;
1907 
1908 			*s++ = '"';
1909 			*s = '\0';
1910 			ctl_putdata(buf, (unsigned)( s - buf ), 0);
1911 		}
1912 		break;
1913 	}
1914 }
1915 #endif
1916 
1917 
1918 
1919 /*
1920  * ctl_getitem - get the next data item from the incoming packet
1921  */
1922 static struct ctl_var *
1923 ctl_getitem(
1924 	struct ctl_var *var_list,
1925 	char **data
1926 	)
1927 {
1928 	register struct ctl_var *v;
1929 	register char *cp;
1930 	register char *tp;
1931 	static struct ctl_var eol = { 0, EOV, };
1932 	static char buf[128];
1933 
1934 	/*
1935 	 * Delete leading commas and white space
1936 	 */
1937 	while (reqpt < reqend && (*reqpt == ',' ||
1938 	    isspace((unsigned char)*reqpt)))
1939 		reqpt++;
1940 	if (reqpt >= reqend)
1941 		return (0);
1942 
1943 	if (var_list == (struct ctl_var *)0)
1944 		return (&eol);
1945 
1946 	/*
1947 	 * Look for a first character match on the tag.  If we find
1948 	 * one, see if it is a full match.
1949 	 */
1950 	v = var_list;
1951 	cp = reqpt;
1952 	while (!(v->flags & EOV)) {
1953 		if (!(v->flags & PADDING) && *cp == *(v->text)) {
1954 			tp = v->text;
1955 			while (*tp != '\0' && *tp != '=' && cp <
1956 			    reqend && *cp == *tp) {
1957 				cp++;
1958 				tp++;
1959 			}
1960 			if ((*tp == '\0') || (*tp == '=')) {
1961 				while (cp < reqend && isspace((unsigned char)*cp))
1962 					cp++;
1963 				if (cp == reqend || *cp == ',') {
1964 					buf[0] = '\0';
1965 					*data = buf;
1966 					if (cp < reqend)
1967 						cp++;
1968 					reqpt = cp;
1969 					return v;
1970 				}
1971 				if (*cp == '=') {
1972 					cp++;
1973 					tp = buf;
1974 					while (cp < reqend && isspace((unsigned char)*cp))
1975 						cp++;
1976 					while (cp < reqend && *cp != ',') {
1977 						*tp++ = *cp++;
1978 						if (tp >= buf + sizeof(buf)) {
1979 							ctl_error(CERR_BADFMT);
1980 							numctlbadpkts++;
1981 #if 0	/* Avoid possible DOS attack */
1982 /* If we get a smarter msyslog we can re-enable this */
1983 							msyslog(LOG_WARNING,
1984 		"Possible 'ntpdx' exploit from %s:%d (possibly spoofed)\n",
1985 		stoa(rmt_addr), SRCPORT(rmt_addr)
1986 								);
1987 #endif
1988 							return (0);
1989 						}
1990 					}
1991 					if (cp < reqend)
1992 						cp++;
1993 					*tp-- = '\0';
1994 					while (tp >= buf) {
1995 						if (!isspace((unsigned int)(*tp)))
1996 							break;
1997 						*tp-- = '\0';
1998 					}
1999 					reqpt = cp;
2000 					*data = buf;
2001 					return (v);
2002 				}
2003 			}
2004 			cp = reqpt;
2005 		}
2006 		v++;
2007 	}
2008 	return v;
2009 }
2010 
2011 
2012 /*
2013  * control_unspec - response to an unspecified op-code
2014  */
2015 /*ARGSUSED*/
2016 static void
2017 control_unspec(
2018 	struct recvbuf *rbufp,
2019 	int restrict_mask
2020 	)
2021 {
2022 	struct peer *peer;
2023 
2024 	/*
2025 	 * What is an appropriate response to an unspecified op-code?
2026 	 * I return no errors and no data, unless a specified assocation
2027 	 * doesn't exist.
2028 	 */
2029 	if (res_associd != 0) {
2030 		if ((peer = findpeerbyassoc(res_associd)) == 0) {
2031 			ctl_error(CERR_BADASSOC);
2032 			return;
2033 		}
2034 		rpkt.status = htons(ctlpeerstatus(peer));
2035 	} else {
2036 		rpkt.status = htons(ctlsysstatus());
2037 	}
2038 	ctl_flushpkt(0);
2039 }
2040 
2041 
2042 /*
2043  * read_status - return either a list of associd's, or a particular
2044  * peer's status.
2045  */
2046 /*ARGSUSED*/
2047 static void
2048 read_status(
2049 	struct recvbuf *rbufp,
2050 	int restrict_mask
2051 	)
2052 {
2053 	register int i;
2054 	register struct peer *peer;
2055 	u_short ass_stat[CTL_MAX_DATA_LEN / sizeof(u_short)];
2056 
2057 #ifdef DEBUG
2058 	if (debug > 2)
2059 		printf("read_status: ID %d\n", res_associd);
2060 #endif
2061 	/*
2062 	 * Two choices here. If the specified association ID is
2063 	 * zero we return all known assocation ID's.  Otherwise
2064 	 * we return a bunch of stuff about the particular peer.
2065 	 */
2066 	if (res_associd == 0) {
2067 		register int n;
2068 
2069 		n = 0;
2070 		rpkt.status = htons(ctlsysstatus());
2071 		for (i = 0; i < NTP_HASH_SIZE; i++) {
2072 			for (peer = assoc_hash[i]; peer != 0;
2073 				peer = peer->ass_next) {
2074 				ass_stat[n++] = htons(peer->associd);
2075 				ass_stat[n++] =
2076 				    htons(ctlpeerstatus(peer));
2077 				if (n ==
2078 				    CTL_MAX_DATA_LEN/sizeof(u_short)) {
2079 					ctl_putdata((char *)ass_stat,
2080 					    n * sizeof(u_short), 1);
2081 					n = 0;
2082 				}
2083 			}
2084 		}
2085 
2086 		if (n != 0)
2087 			ctl_putdata((char *)ass_stat, n *
2088 			    sizeof(u_short), 1);
2089 		ctl_flushpkt(0);
2090 	} else {
2091 		peer = findpeerbyassoc(res_associd);
2092 		if (peer == 0) {
2093 			ctl_error(CERR_BADASSOC);
2094 		} else {
2095 			register u_char *cp;
2096 
2097 			rpkt.status = htons(ctlpeerstatus(peer));
2098 			if (res_authokay)
2099 				peer->num_events = 0;
2100 			/*
2101 			 * For now, output everything we know about the
2102 			 * peer. May be more selective later.
2103 			 */
2104 			for (cp = def_peer_var; *cp != 0; cp++)
2105 				ctl_putpeer((int)*cp, peer);
2106 			ctl_flushpkt(0);
2107 		}
2108 	}
2109 }
2110 
2111 
2112 /*
2113  * read_variables - return the variables the caller asks for
2114  */
2115 /*ARGSUSED*/
2116 static void
2117 read_variables(
2118 	struct recvbuf *rbufp,
2119 	int restrict_mask
2120 	)
2121 {
2122 	register struct ctl_var *v;
2123 	register int i;
2124 	char *valuep;
2125 	u_char *wants;
2126 	unsigned int gotvar = (CS_MAXCODE > CP_MAXCODE) ? (CS_MAXCODE +
2127 	    1) : (CP_MAXCODE + 1);
2128 	if (res_associd == 0) {
2129 		/*
2130 		 * Wants system variables. Figure out which he wants
2131 		 * and give them to him.
2132 		 */
2133 		rpkt.status = htons(ctlsysstatus());
2134 		if (res_authokay)
2135 			ctl_sys_num_events = 0;
2136 		gotvar += count_var(ext_sys_var);
2137 		wants = (u_char *)emalloc(gotvar);
2138 		memset((char *)wants, 0, gotvar);
2139 		gotvar = 0;
2140 		while ((v = ctl_getitem(sys_var, &valuep)) != 0) {
2141 			if (v->flags & EOV) {
2142 				if ((v = ctl_getitem(ext_sys_var,
2143 				    &valuep)) != 0) {
2144 					if (v->flags & EOV) {
2145 						ctl_error(CERR_UNKNOWNVAR);
2146 						free((char *)wants);
2147 						return;
2148 					}
2149 					wants[CS_MAXCODE + 1 +
2150 					    v->code] = 1;
2151 					gotvar = 1;
2152 					continue;
2153 				} else {
2154 					break; /* shouldn't happen ! */
2155 				}
2156 			}
2157 			wants[v->code] = 1;
2158 			gotvar = 1;
2159 		}
2160 		if (gotvar) {
2161 			for (i = 1; i <= CS_MAXCODE; i++)
2162 				if (wants[i])
2163 					ctl_putsys(i);
2164 			for (i = 0; ext_sys_var &&
2165 			    !(ext_sys_var[i].flags & EOV); i++)
2166 				if (wants[i + CS_MAXCODE + 1])
2167 					ctl_putdata(ext_sys_var[i].text,
2168 					    strlen(ext_sys_var[i].text),
2169 					    0);
2170 		} else {
2171 			register u_char *cs;
2172 			register struct ctl_var *kv;
2173 
2174 			for (cs = def_sys_var; *cs != 0; cs++)
2175 				ctl_putsys((int)*cs);
2176 			for (kv = ext_sys_var; kv && !(kv->flags & EOV);
2177 			    kv++)
2178 				if (kv->flags & DEF)
2179 					ctl_putdata(kv->text,
2180 					    strlen(kv->text), 0);
2181 		}
2182 		free((char *)wants);
2183 	} else {
2184 		register struct peer *peer;
2185 
2186 		/*
2187 		 * Wants info for a particular peer. See if we know
2188 		 * the guy.
2189 		 */
2190 		peer = findpeerbyassoc(res_associd);
2191 		if (peer == 0) {
2192 			ctl_error(CERR_BADASSOC);
2193 			return;
2194 		}
2195 		rpkt.status = htons(ctlpeerstatus(peer));
2196 		if (res_authokay)
2197 			peer->num_events = 0;
2198 		wants = (u_char *)emalloc(gotvar);
2199 		memset((char*)wants, 0, gotvar);
2200 		gotvar = 0;
2201 		while ((v = ctl_getitem(peer_var, &valuep)) != 0) {
2202 			if (v->flags & EOV) {
2203 				ctl_error(CERR_UNKNOWNVAR);
2204 				free((char *)wants);
2205 				return;
2206 			}
2207 			wants[v->code] = 1;
2208 			gotvar = 1;
2209 		}
2210 		if (gotvar) {
2211 			for (i = 1; i <= CP_MAXCODE; i++)
2212 				if (wants[i])
2213 					ctl_putpeer(i, peer);
2214 		} else {
2215 			register u_char *cp;
2216 
2217 			for (cp = def_peer_var; *cp != 0; cp++)
2218 				ctl_putpeer((int)*cp, peer);
2219 		}
2220 		free((char *)wants);
2221 	}
2222 	ctl_flushpkt(0);
2223 }
2224 
2225 
2226 /*
2227  * write_variables - write into variables. We only allow leap bit
2228  * writing this way.
2229  */
2230 /*ARGSUSED*/
2231 static void
2232 write_variables(
2233 	struct recvbuf *rbufp,
2234 	int restrict_mask
2235 	)
2236 {
2237 	register struct ctl_var *v;
2238 	register int ext_var;
2239 	char *valuep;
2240 	long val = 0;
2241 
2242 	/*
2243 	 * If he's trying to write into a peer tell him no way
2244 	 */
2245 	if (res_associd != 0) {
2246 		ctl_error(CERR_PERMISSION);
2247 		return;
2248 	}
2249 
2250 	/*
2251 	 * Set status
2252 	 */
2253 	rpkt.status = htons(ctlsysstatus());
2254 
2255 	/*
2256 	 * Look through the variables. Dump out at the first sign of
2257 	 * trouble.
2258 	 */
2259 	while ((v = ctl_getitem(sys_var, &valuep)) != 0) {
2260 		ext_var = 0;
2261 		if (v->flags & EOV) {
2262 			if ((v = ctl_getitem(ext_sys_var, &valuep)) !=
2263 			    0) {
2264 				if (v->flags & EOV) {
2265 					ctl_error(CERR_UNKNOWNVAR);
2266 					return;
2267 				}
2268 				ext_var = 1;
2269 			} else {
2270 				break;
2271 			}
2272 		}
2273 		if (!(v->flags & CAN_WRITE)) {
2274 			ctl_error(CERR_PERMISSION);
2275 			return;
2276 		}
2277 		if (!ext_var && (*valuep == '\0' || !atoint(valuep,
2278 		    &val))) {
2279 			ctl_error(CERR_BADFMT);
2280 			return;
2281 		}
2282 		if (!ext_var && (val & ~LEAP_NOTINSYNC) != 0) {
2283 			ctl_error(CERR_BADVALUE);
2284 			return;
2285 		}
2286 
2287 		if (ext_var) {
2288 			char *s = (char *)emalloc(strlen(v->text) +
2289 			    strlen(valuep) + 2);
2290 			const char *t;
2291 			char *tt = s;
2292 
2293 			t = v->text;
2294 			while (*t && *t != '=')
2295 				*tt++ = *t++;
2296 
2297 			*tt++ = '=';
2298 			strcat(tt, valuep);
2299 			set_sys_var(s, strlen(s)+1, v->flags);
2300 			free(s);
2301 		} else {
2302 			/*
2303 			 * This one seems sane. Save it.
2304 			 */
2305 			switch(v->code) {
2306 
2307 			case CS_LEAP:
2308 			default:
2309 				ctl_error(CERR_UNSPEC); /* really */
2310 				return;
2311 			}
2312 		}
2313 	}
2314 
2315 	/*
2316 	 * If we got anything, do it. xxx nothing to do ***
2317 	 */
2318 	/*
2319 	  if (leapind != ~0 || leapwarn != ~0) {
2320 	  	if (!leap_setleap((int)leapind, (int)leapwarn)) {
2321 	  		ctl_error(CERR_PERMISSION);
2322 	  		return;
2323 	  	}
2324 	  }
2325 	*/
2326 	ctl_flushpkt(0);
2327 }
2328 
2329 
2330 /*
2331  * read_clock_status - return clock radio status
2332  */
2333 /*ARGSUSED*/
2334 static void
2335 read_clock_status(
2336 	struct recvbuf *rbufp,
2337 	int restrict_mask
2338 	)
2339 {
2340 #ifndef REFCLOCK
2341 	/*
2342 	 * If no refclock support, no data to return
2343 	 */
2344 	ctl_error(CERR_BADASSOC);
2345 #else
2346 	register struct ctl_var *v;
2347 	register int i;
2348 	register struct peer *peer;
2349 	char *valuep;
2350 	u_char *wants;
2351 	unsigned int gotvar;
2352 	struct refclockstat clock_stat;
2353 
2354 	if (res_associd == 0) {
2355 
2356 		/*
2357 		 * Find a clock for this jerk.	If the system peer
2358 		 * is a clock use it, else search the hash tables
2359 		 * for one.
2360 		 */
2361 		if (sys_peer != 0 && (sys_peer->flags & FLAG_REFCLOCK))
2362 		    {
2363 			peer = sys_peer;
2364 		} else {
2365 			peer = 0;
2366 			for (i = 0; peer == 0 && i < NTP_HASH_SIZE; i++) {
2367 				for (peer = assoc_hash[i]; peer != 0;
2368 					peer = peer->ass_next) {
2369 					if (peer->flags & FLAG_REFCLOCK)
2370 						break;
2371 				}
2372 			}
2373 			if (peer == 0) {
2374 				ctl_error(CERR_BADASSOC);
2375 				return;
2376 			}
2377 		}
2378 	} else {
2379 		peer = findpeerbyassoc(res_associd);
2380 		if (peer == 0 || !(peer->flags & FLAG_REFCLOCK)) {
2381 			ctl_error(CERR_BADASSOC);
2382 			return;
2383 		}
2384 	}
2385 
2386 	/*
2387 	 * If we got here we have a peer which is a clock. Get his
2388 	 * status.
2389 	 */
2390 	clock_stat.kv_list = (struct ctl_var *)0;
2391 	refclock_control(&peer->srcadr, (struct refclockstat *)0,
2392 	    &clock_stat);
2393 
2394 	/*
2395 	 * Look for variables in the packet.
2396 	 */
2397 	rpkt.status = htons(ctlclkstatus(&clock_stat));
2398 	gotvar = CC_MAXCODE + 1 + count_var(clock_stat.kv_list);
2399 	wants = (u_char *)emalloc(gotvar);
2400 	memset((char*)wants, 0, gotvar);
2401 	gotvar = 0;
2402 	while ((v = ctl_getitem(clock_var, &valuep)) != 0) {
2403 		if (v->flags & EOV) {
2404 			if ((v = ctl_getitem(clock_stat.kv_list,
2405 			    &valuep)) != 0) {
2406 				if (v->flags & EOV) {
2407 					ctl_error(CERR_UNKNOWNVAR);
2408 					free((char*)wants);
2409 					free_varlist(clock_stat.kv_list);
2410 					return;
2411 				}
2412 				wants[CC_MAXCODE + 1 + v->code] = 1;
2413 				gotvar = 1;
2414 				continue;
2415 			} else {
2416 				break; /* shouldn't happen ! */
2417 			}
2418 		}
2419 		wants[v->code] = 1;
2420 		gotvar = 1;
2421 	}
2422 
2423 	if (gotvar) {
2424 		for (i = 1; i <= CC_MAXCODE; i++)
2425 			if (wants[i])
2426 			ctl_putclock(i, &clock_stat, 1);
2427 		for (i = 0; clock_stat.kv_list &&
2428 		    !(clock_stat.kv_list[i].flags & EOV); i++)
2429 			if (wants[i + CC_MAXCODE + 1])
2430 				ctl_putdata(clock_stat.kv_list[i].text,
2431 				    strlen(clock_stat.kv_list[i].text),
2432 				    0);
2433 	} else {
2434 		register u_char *cc;
2435 		register struct ctl_var *kv;
2436 
2437 		for (cc = def_clock_var; *cc != 0; cc++)
2438 			ctl_putclock((int)*cc, &clock_stat, 0);
2439 		for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV);
2440 		    kv++)
2441 			if (kv->flags & DEF)
2442 				ctl_putdata(kv->text, strlen(kv->text),
2443 				    0);
2444 	}
2445 
2446 	free((char*)wants);
2447 	free_varlist(clock_stat.kv_list);
2448 
2449 	ctl_flushpkt(0);
2450 #endif
2451 }
2452 
2453 
2454 /*
2455  * write_clock_status - we don't do this
2456  */
2457 /*ARGSUSED*/
2458 static void
2459 write_clock_status(
2460 	struct recvbuf *rbufp,
2461 	int restrict_mask
2462 	)
2463 {
2464 	ctl_error(CERR_PERMISSION);
2465 }
2466 
2467 /*
2468  * Trap support from here on down. We send async trap messages when the
2469  * upper levels report trouble. Traps can by set either by control
2470  * messages or by configuration.
2471  */
2472 /*
2473  * set_trap - set a trap in response to a control message
2474  */
2475 static void
2476 set_trap(
2477 	struct recvbuf *rbufp,
2478 	int restrict_mask
2479 	)
2480 {
2481 	int traptype;
2482 
2483 	/*
2484 	 * See if this guy is allowed
2485 	 */
2486 	if (restrict_mask & RES_NOTRAP) {
2487 		ctl_error(CERR_PERMISSION);
2488 		return;
2489 	}
2490 
2491 	/*
2492 	 * Determine his allowed trap type.
2493 	 */
2494 	traptype = TRAP_TYPE_PRIO;
2495 	if (restrict_mask & RES_LPTRAP)
2496 		traptype = TRAP_TYPE_NONPRIO;
2497 
2498 	/*
2499 	 * Call ctlsettrap() to do the work.  Return
2500 	 * an error if it can't assign the trap.
2501 	 */
2502 	if (!ctlsettrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype,
2503 	    (int)res_version))
2504 		ctl_error(CERR_NORESOURCE);
2505 	ctl_flushpkt(0);
2506 }
2507 
2508 
2509 /*
2510  * unset_trap - unset a trap in response to a control message
2511  */
2512 static void
2513 unset_trap(
2514 	struct recvbuf *rbufp,
2515 	int restrict_mask
2516 	)
2517 {
2518 	int traptype;
2519 
2520 	/*
2521 	 * We don't prevent anyone from removing his own trap unless the
2522 	 * trap is configured. Note we also must be aware of the
2523 	 * possibility that restriction flags were changed since this
2524 	 * guy last set his trap. Set the trap type based on this.
2525 	 */
2526 	traptype = TRAP_TYPE_PRIO;
2527 	if (restrict_mask & RES_LPTRAP)
2528 		traptype = TRAP_TYPE_NONPRIO;
2529 
2530 	/*
2531 	 * Call ctlclrtrap() to clear this out.
2532 	 */
2533 	if (!ctlclrtrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype))
2534 		ctl_error(CERR_BADASSOC);
2535 	ctl_flushpkt(0);
2536 }
2537 
2538 
2539 /*
2540  * ctlsettrap - called to set a trap
2541  */
2542 int
2543 ctlsettrap(
2544 	struct sockaddr_storage *raddr,
2545 	struct interface *linter,
2546 	int traptype,
2547 	int version
2548 	)
2549 {
2550 	register struct ctl_trap *tp;
2551 	register struct ctl_trap *tptouse;
2552 
2553 	/*
2554 	 * See if we can find this trap.  If so, we only need update
2555 	 * the flags and the time.
2556 	 */
2557 	if ((tp = ctlfindtrap(raddr, linter)) != NULL) {
2558 		switch (traptype) {
2559 
2560 		case TRAP_TYPE_CONFIG:
2561 			tp->tr_flags = TRAP_INUSE|TRAP_CONFIGURED;
2562 			break;
2563 
2564 		case TRAP_TYPE_PRIO:
2565 			if (tp->tr_flags & TRAP_CONFIGURED)
2566 				return (1); /* don't change anything */
2567 			tp->tr_flags = TRAP_INUSE;
2568 			break;
2569 
2570 		case TRAP_TYPE_NONPRIO:
2571 			if (tp->tr_flags & TRAP_CONFIGURED)
2572 				return (1); /* don't change anything */
2573 			tp->tr_flags = TRAP_INUSE|TRAP_NONPRIO;
2574 			break;
2575 		}
2576 		tp->tr_settime = current_time;
2577 		tp->tr_resets++;
2578 		return (1);
2579 	}
2580 
2581 	/*
2582 	 * First we heard of this guy.	Try to find a trap structure
2583 	 * for him to use, clearing out lesser priority guys if we
2584 	 * have to. Clear out anyone who's expired while we're at it.
2585 	 */
2586 	tptouse = NULL;
2587 	for (tp = ctl_trap; tp < &ctl_trap[CTL_MAXTRAPS]; tp++) {
2588 		if ((tp->tr_flags & TRAP_INUSE) &&
2589 		    !(tp->tr_flags & TRAP_CONFIGURED) &&
2590 		    ((tp->tr_settime + CTL_TRAPTIME) > current_time)) {
2591 			tp->tr_flags = 0;
2592 			num_ctl_traps--;
2593 		}
2594 		if (!(tp->tr_flags & TRAP_INUSE)) {
2595 			tptouse = tp;
2596 		} else if (!(tp->tr_flags & TRAP_CONFIGURED)) {
2597 			switch (traptype) {
2598 
2599 			case TRAP_TYPE_CONFIG:
2600 				if (tptouse == NULL) {
2601 					tptouse = tp;
2602 					break;
2603 				}
2604 				if (tptouse->tr_flags & TRAP_NONPRIO &&
2605 				    !(tp->tr_flags & TRAP_NONPRIO))
2606 					break;
2607 
2608 				if (!(tptouse->tr_flags & TRAP_NONPRIO)
2609 				    && tp->tr_flags & TRAP_NONPRIO) {
2610 					tptouse = tp;
2611 					break;
2612 				}
2613 				if (tptouse->tr_origtime <
2614 				    tp->tr_origtime)
2615 					tptouse = tp;
2616 				break;
2617 
2618 			case TRAP_TYPE_PRIO:
2619 				if (tp->tr_flags & TRAP_NONPRIO) {
2620 					if (tptouse == NULL ||
2621 					    (tptouse->tr_flags &
2622 					    TRAP_INUSE &&
2623 					    tptouse->tr_origtime <
2624 					    tp->tr_origtime))
2625 						tptouse = tp;
2626 				}
2627 				break;
2628 
2629 			case TRAP_TYPE_NONPRIO:
2630 				break;
2631 			}
2632 		}
2633 	}
2634 
2635 	/*
2636 	 * If we don't have room for him return an error.
2637 	 */
2638 	if (tptouse == NULL)
2639 		return (0);
2640 
2641 	/*
2642 	 * Set up this structure for him.
2643 	 */
2644 	tptouse->tr_settime = tptouse->tr_origtime = current_time;
2645 	tptouse->tr_count = tptouse->tr_resets = 0;
2646 	tptouse->tr_sequence = 1;
2647 	tptouse->tr_addr = *raddr;
2648 	tptouse->tr_localaddr = linter;
2649 	tptouse->tr_version = (u_char) version;
2650 	tptouse->tr_flags = TRAP_INUSE;
2651 	if (traptype == TRAP_TYPE_CONFIG)
2652 		tptouse->tr_flags |= TRAP_CONFIGURED;
2653 	else if (traptype == TRAP_TYPE_NONPRIO)
2654 		tptouse->tr_flags |= TRAP_NONPRIO;
2655 	num_ctl_traps++;
2656 	return (1);
2657 }
2658 
2659 
2660 /*
2661  * ctlclrtrap - called to clear a trap
2662  */
2663 int
2664 ctlclrtrap(
2665 	struct sockaddr_storage *raddr,
2666 	struct interface *linter,
2667 	int traptype
2668 	)
2669 {
2670 	register struct ctl_trap *tp;
2671 
2672 	if ((tp = ctlfindtrap(raddr, linter)) == NULL)
2673 		return (0);
2674 
2675 	if (tp->tr_flags & TRAP_CONFIGURED
2676 		&& traptype != TRAP_TYPE_CONFIG)
2677 		return (0);
2678 
2679 	tp->tr_flags = 0;
2680 	num_ctl_traps--;
2681 	return (1);
2682 }
2683 
2684 
2685 /*
2686  * ctlfindtrap - find a trap given the remote and local addresses
2687  */
2688 static struct ctl_trap *
2689 ctlfindtrap(
2690 	struct sockaddr_storage *raddr,
2691 	struct interface *linter
2692 	)
2693 {
2694 	register struct ctl_trap *tp;
2695 
2696 	for (tp = ctl_trap; tp < &ctl_trap[CTL_MAXTRAPS]; tp++) {
2697 		if ((tp->tr_flags & TRAP_INUSE)
2698 		    && (NSRCPORT(raddr) == NSRCPORT(&tp->tr_addr))
2699 		    && SOCKCMP(raddr, &tp->tr_addr)
2700 	 	    && (linter == tp->tr_localaddr) )
2701 		return (tp);
2702 	}
2703 	return (struct ctl_trap *)NULL;
2704 }
2705 
2706 
2707 /*
2708  * report_event - report an event to the trappers
2709  */
2710 void
2711 report_event(
2712 	int err,
2713 	struct peer *peer
2714 	)
2715 {
2716 	register int i;
2717 
2718 	/*
2719 	 * Record error code in proper spots, but have mercy on the
2720 	 * log file.
2721 	 */
2722 	if (!(err & (PEER_EVENT | CRPT_EVENT))) {
2723 		if (ctl_sys_num_events < CTL_SYS_MAXEVENTS)
2724 			ctl_sys_num_events++;
2725 		if (ctl_sys_last_event != (u_char)err) {
2726 			NLOG(NLOG_SYSEVENT)
2727 			    msyslog(LOG_INFO, "system event '%s' (0x%02x) status '%s' (0x%02x)",
2728 			    eventstr(err), err,
2729 			    sysstatstr(ctlsysstatus()), ctlsysstatus());
2730 #ifdef DEBUG
2731 			if (debug)
2732 				printf("report_event: system event '%s' (0x%02x) status '%s' (0x%02x)\n",
2733 				    eventstr(err), err,
2734 				    sysstatstr(ctlsysstatus()),
2735 				    ctlsysstatus());
2736 #endif
2737 			ctl_sys_last_event = (u_char)err;
2738 		}
2739 	} else if (peer != 0) {
2740 		char *src;
2741 
2742 #ifdef REFCLOCK
2743 		if (ISREFCLOCKADR(&peer->srcadr))
2744 			src = refnumtoa(&peer->srcadr);
2745 		else
2746 #endif
2747 			src = stoa(&peer->srcadr);
2748 
2749 		peer->last_event = (u_char)(err & ~PEER_EVENT);
2750 		if (peer->num_events < CTL_PEER_MAXEVENTS)
2751 			peer->num_events++;
2752 		NLOG(NLOG_PEEREVENT)
2753 		    msyslog(LOG_INFO, "peer %s event '%s' (0x%02x) status '%s' (0x%02x)",
2754 		    src, eventstr(err), err,
2755 		    peerstatstr(ctlpeerstatus(peer)),
2756 		    ctlpeerstatus(peer));
2757 #ifdef DEBUG
2758 		if (debug)
2759 			printf( "peer %s event '%s' (0x%02x) status '%s' (0x%02x)\n",
2760 			    src, eventstr(err), err,
2761 			    peerstatstr(ctlpeerstatus(peer)),
2762 			    ctlpeerstatus(peer));
2763 #endif
2764 	} else {
2765 		msyslog(LOG_ERR,
2766 		    "report_event: err '%s' (0x%02x), no peer",
2767 		    eventstr(err), err);
2768 #ifdef DEBUG
2769 		printf(
2770 		    "report_event: peer event '%s' (0x%02x), no peer\n",
2771 		    eventstr(err), err);
2772 #endif
2773 		return;
2774 	}
2775 
2776 	/*
2777 	 * If no trappers, return.
2778 	 */
2779 	if (num_ctl_traps <= 0)
2780 		return;
2781 
2782 	/*
2783 	 * Set up the outgoing packet variables
2784 	 */
2785 	res_opcode = CTL_OP_ASYNCMSG;
2786 	res_offset = 0;
2787 	res_async = 1;
2788 	res_authenticate = 0;
2789 	datapt = rpkt.data;
2790 	dataend = &(rpkt.data[CTL_MAX_DATA_LEN]);
2791 	if (!(err & PEER_EVENT)) {
2792 		rpkt.associd = 0;
2793 		rpkt.status = htons(ctlsysstatus());
2794 
2795 		/*
2796 		 * For now, put everything we know about system
2797 		 * variables. Don't send crypto strings.
2798 		 */
2799 		for (i = 1; i <= CS_MAXCODE; i++) {
2800 #ifdef OPENSSL
2801 			if (i > CS_VARLIST)
2802 				continue;
2803 #endif /* OPENSSL */
2804 			ctl_putsys(i);
2805 		}
2806 #ifdef REFCLOCK
2807 		/*
2808 		 * for clock exception events: add clock variables to
2809 		 * reflect info on exception
2810 		 */
2811 		if (err == EVNT_CLOCKEXCPT) {
2812 			struct refclockstat clock_stat;
2813 			struct ctl_var *kv;
2814 
2815 			clock_stat.kv_list = (struct ctl_var *)0;
2816 			refclock_control(&peer->srcadr,
2817 			    (struct refclockstat *)0, &clock_stat);
2818 			ctl_puthex("refclockstatus",
2819 			    ctlclkstatus(&clock_stat));
2820 			for (i = 1; i <= CC_MAXCODE; i++)
2821 				ctl_putclock(i, &clock_stat, 0);
2822 			for (kv = clock_stat.kv_list; kv &&
2823 			    !(kv->flags & EOV); kv++)
2824 				if (kv->flags & DEF)
2825 					ctl_putdata(kv->text,
2826 					    strlen(kv->text), 0);
2827 			free_varlist(clock_stat.kv_list);
2828 		}
2829 #endif /* REFCLOCK */
2830 	} else {
2831 		rpkt.associd = htons(peer->associd);
2832 		rpkt.status = htons(ctlpeerstatus(peer));
2833 
2834 		/*
2835 		 * Dump it all. Later, maybe less.
2836 		 */
2837 		for (i = 1; i <= CP_MAXCODE; i++) {
2838 #ifdef OPENSSL
2839 			if (i > CP_VARLIST)
2840 				continue;
2841 #endif /* OPENSSL */
2842 			ctl_putpeer(i, peer);
2843 		}
2844 #ifdef REFCLOCK
2845 		/*
2846 		 * for clock exception events: add clock variables to
2847 		 * reflect info on exception
2848 		 */
2849 		if (err == EVNT_PEERCLOCK) {
2850 			struct refclockstat clock_stat;
2851 			struct ctl_var *kv;
2852 
2853 			clock_stat.kv_list = (struct ctl_var *)0;
2854 			refclock_control(&peer->srcadr,
2855 			    (struct refclockstat *)0, &clock_stat);
2856 
2857 			ctl_puthex("refclockstatus",
2858 			    ctlclkstatus(&clock_stat));
2859 
2860 			for (i = 1; i <= CC_MAXCODE; i++)
2861 				ctl_putclock(i, &clock_stat, 0);
2862 			for (kv = clock_stat.kv_list; kv &&
2863 			    !(kv->flags & EOV); kv++)
2864 				if (kv->flags & DEF)
2865 					ctl_putdata(kv->text,
2866 					    strlen(kv->text), 0);
2867 			free_varlist(clock_stat.kv_list);
2868 		}
2869 #endif /* REFCLOCK */
2870 	}
2871 
2872 	/*
2873 	 * We're done, return.
2874 	 */
2875 	ctl_flushpkt(0);
2876 }
2877 
2878 
2879 /*
2880  * ctl_clr_stats - clear stat counters
2881  */
2882 void
2883 ctl_clr_stats(void)
2884 {
2885 	ctltimereset = current_time;
2886 	numctlreq = 0;
2887 	numctlbadpkts = 0;
2888 	numctlresponses = 0;
2889 	numctlfrags = 0;
2890 	numctlerrors = 0;
2891 	numctlfrags = 0;
2892 	numctltooshort = 0;
2893 	numctlinputresp = 0;
2894 	numctlinputfrag = 0;
2895 	numctlinputerr = 0;
2896 	numctlbadoffset = 0;
2897 	numctlbadversion = 0;
2898 	numctldatatooshort = 0;
2899 	numctlbadop = 0;
2900 	numasyncmsgs = 0;
2901 }
2902 
2903 static u_long
2904 count_var(
2905 	struct ctl_var *k
2906 	)
2907 {
2908 	register u_long c;
2909 
2910 	if (!k)
2911 		return (0);
2912 
2913 	c = 0;
2914 	while (!(k++->flags & EOV))
2915 		c++;
2916 	return (c);
2917 }
2918 
2919 char *
2920 add_var(
2921 	struct ctl_var **kv,
2922 	u_long size,
2923 	u_short def
2924 	)
2925 {
2926 	register u_long c;
2927 	register struct ctl_var *k;
2928 
2929 	c = count_var(*kv);
2930 
2931 	k = *kv;
2932 	*kv  = (struct ctl_var *)emalloc((c+2)*sizeof(struct ctl_var));
2933 	if (k) {
2934 		memmove((char *)*kv, (char *)k,
2935 		    sizeof(struct ctl_var)*c);
2936 		free((char *)k);
2937 	}
2938 	(*kv)[c].code  = (u_short) c;
2939 	(*kv)[c].text  = (char *)emalloc(size);
2940 	(*kv)[c].flags = def;
2941 	(*kv)[c+1].code  = 0;
2942 	(*kv)[c+1].text  = (char *)0;
2943 	(*kv)[c+1].flags = EOV;
2944 	return (char *)(*kv)[c].text;
2945 }
2946 
2947 void
2948 set_var(
2949 	struct ctl_var **kv,
2950 	const char *data,
2951 	u_long size,
2952 	u_short def
2953 	)
2954 {
2955 	register struct ctl_var *k;
2956 	register const char *s;
2957 	register const char *t;
2958 	char *td;
2959 
2960 	if (!data || !size)
2961 		return;
2962 
2963 	k = *kv;
2964 	if (k != NULL) {
2965 		while (!(k->flags & EOV)) {
2966 			s = data;
2967 			t = k->text;
2968 			if (t)	{
2969 				while (*t != '=' && *s - *t == 0) {
2970 					s++;
2971 					t++;
2972 				}
2973 				if (*s == *t && ((*t == '=') || !*t)) {
2974 					free((void *)k->text);
2975 					td = (char *)emalloc(size);
2976 					memmove(td, data, size);
2977 					k->text =td;
2978 					k->flags = def;
2979 					return;
2980 				}
2981 			} else {
2982 				td = (char *)emalloc(size);
2983 				memmove(td, data, size);
2984 				k->text = td;
2985 				k->flags = def;
2986 				return;
2987 			}
2988 			k++;
2989 		}
2990 	}
2991 	td = add_var(kv, size, def);
2992 	memmove(td, data, size);
2993 }
2994 
2995 void
2996 set_sys_var(
2997 	const char *data,
2998 	u_long size,
2999 	u_short def
3000 	)
3001 {
3002 	set_var(&ext_sys_var, data, size, def);
3003 }
3004 
3005 void
3006 free_varlist(
3007 	struct ctl_var *kv
3008 	)
3009 {
3010 	struct ctl_var *k;
3011 	if (kv) {
3012 		for (k = kv; !(k->flags & EOV); k++)
3013 			free((void *)k->text);
3014 		free((void *)kv);
3015 	}
3016 }
3017