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