ntp_request.c revision 1.7
1/*	$NetBSD: ntp_request.c,v 1.7 2012/02/01 22:48:15 kardel Exp $	*/
2
3/*
4 * ntp_request.c - respond to information requests
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_request.h"
14#include "ntp_control.h"
15#include "ntp_refclock.h"
16#include "ntp_if.h"
17#include "ntp_stdlib.h"
18#include "ntp_assert.h"
19
20#include <stdio.h>
21#include <stddef.h>
22#include <signal.h>
23#ifdef HAVE_NETINET_IN_H
24#include <netinet/in.h>
25#endif
26#include <arpa/inet.h>
27
28#include "recvbuff.h"
29
30#ifdef KERNEL_PLL
31#include "ntp_syscall.h"
32#endif /* KERNEL_PLL */
33
34/*
35 * Structure to hold request procedure information
36 */
37#define	NOAUTH	0
38#define	AUTH	1
39
40#define	NO_REQUEST	(-1)
41/*
42 * Because we now have v6 addresses in the messages, we need to compensate
43 * for the larger size.  Therefore, we introduce the alternate size to
44 * keep us friendly with older implementations.  A little ugly.
45 */
46static int client_v6_capable = 0;   /* the client can handle longer messages */
47
48#define v6sizeof(type)	(client_v6_capable ? sizeof(type) : v4sizeof(type))
49
50struct req_proc {
51	short request_code;	/* defined request code */
52	short needs_auth;	/* true when authentication needed */
53	short sizeofitem;	/* size of request data item (older size)*/
54	short v6_sizeofitem;	/* size of request data item (new size)*/
55	void (*handler) (sockaddr_u *, struct interface *,
56			   struct req_pkt *);	/* routine to handle request */
57};
58
59/*
60 * Universal request codes
61 */
62static	struct req_proc univ_codes[] = {
63	{ NO_REQUEST,		NOAUTH,	 0,	0, NULL }
64};
65
66static	void	req_ack	(sockaddr_u *, struct interface *, struct req_pkt *, int);
67static	char *	prepare_pkt	(sockaddr_u *, struct interface *,
68				 struct req_pkt *, size_t);
69static	char *	more_pkt	(void);
70static	void	flush_pkt	(void);
71static	void	peer_list	(sockaddr_u *, struct interface *, struct req_pkt *);
72static	void	peer_list_sum	(sockaddr_u *, struct interface *, struct req_pkt *);
73static	void	peer_info	(sockaddr_u *, struct interface *, struct req_pkt *);
74static	void	peer_stats	(sockaddr_u *, struct interface *, struct req_pkt *);
75static	void	sys_info	(sockaddr_u *, struct interface *, struct req_pkt *);
76static	void	sys_stats	(sockaddr_u *, struct interface *, struct req_pkt *);
77static	void	mem_stats	(sockaddr_u *, struct interface *, struct req_pkt *);
78static	void	io_stats	(sockaddr_u *, struct interface *, struct req_pkt *);
79static	void	timer_stats	(sockaddr_u *, struct interface *, struct req_pkt *);
80static	void	loop_info	(sockaddr_u *, struct interface *, struct req_pkt *);
81static	void	do_conf		(sockaddr_u *, struct interface *, struct req_pkt *);
82static	void	do_unconf	(sockaddr_u *, struct interface *, struct req_pkt *);
83static	void	set_sys_flag	(sockaddr_u *, struct interface *, struct req_pkt *);
84static	void	clr_sys_flag	(sockaddr_u *, struct interface *, struct req_pkt *);
85static	void	setclr_flags	(sockaddr_u *, struct interface *, struct req_pkt *, u_long);
86static	void	list_restrict	(sockaddr_u *, struct interface *, struct req_pkt *);
87static	void	do_resaddflags	(sockaddr_u *, struct interface *, struct req_pkt *);
88static	void	do_ressubflags	(sockaddr_u *, struct interface *, struct req_pkt *);
89static	void	do_unrestrict	(sockaddr_u *, struct interface *, struct req_pkt *);
90static	void	do_restrict	(sockaddr_u *, struct interface *, struct req_pkt *, int);
91static	void	mon_getlist_0	(sockaddr_u *, struct interface *, struct req_pkt *);
92static	void	mon_getlist_1	(sockaddr_u *, struct interface *, struct req_pkt *);
93static	void	reset_stats	(sockaddr_u *, struct interface *, struct req_pkt *);
94static	void	reset_peer	(sockaddr_u *, struct interface *, struct req_pkt *);
95static	void	do_key_reread	(sockaddr_u *, struct interface *, struct req_pkt *);
96static	void	trust_key	(sockaddr_u *, struct interface *, struct req_pkt *);
97static	void	untrust_key	(sockaddr_u *, struct interface *, struct req_pkt *);
98static	void	do_trustkey	(sockaddr_u *, struct interface *, struct req_pkt *, u_long);
99static	void	get_auth_info	(sockaddr_u *, struct interface *, struct req_pkt *);
100static	void	reset_auth_stats (void);
101static	void	req_get_traps	(sockaddr_u *, struct interface *, struct req_pkt *);
102static	void	req_set_trap	(sockaddr_u *, struct interface *, struct req_pkt *);
103static	void	req_clr_trap	(sockaddr_u *, struct interface *, struct req_pkt *);
104static	void	do_setclr_trap	(sockaddr_u *, struct interface *, struct req_pkt *, int);
105static	void	set_request_keyid (sockaddr_u *, struct interface *, struct req_pkt *);
106static	void	set_control_keyid (sockaddr_u *, struct interface *, struct req_pkt *);
107static	void	get_ctl_stats   (sockaddr_u *, struct interface *, struct req_pkt *);
108static	void	get_if_stats    (sockaddr_u *, struct interface *, struct req_pkt *);
109static	void	do_if_reload    (sockaddr_u *, struct interface *, struct req_pkt *);
110#ifdef KERNEL_PLL
111static	void	get_kernel_info (sockaddr_u *, struct interface *, struct req_pkt *);
112#endif /* KERNEL_PLL */
113#ifdef REFCLOCK
114static	void	get_clock_info (sockaddr_u *, struct interface *, struct req_pkt *);
115static	void	set_clock_fudge (sockaddr_u *, struct interface *, struct req_pkt *);
116#endif	/* REFCLOCK */
117#ifdef REFCLOCK
118static	void	get_clkbug_info (sockaddr_u *, struct interface *, struct req_pkt *);
119#endif	/* REFCLOCK */
120
121/*
122 * ntpd request codes
123 */
124static	struct req_proc ntp_codes[] = {
125	{ REQ_PEER_LIST,	NOAUTH,	0, 0,	peer_list },
126	{ REQ_PEER_LIST_SUM,	NOAUTH,	0, 0,	peer_list_sum },
127	{ REQ_PEER_INFO,    NOAUTH, v4sizeof(struct info_peer_list),
128				sizeof(struct info_peer_list), peer_info},
129	{ REQ_PEER_STATS,   NOAUTH, v4sizeof(struct info_peer_list),
130				sizeof(struct info_peer_list), peer_stats},
131	{ REQ_SYS_INFO,		NOAUTH,	0, 0,	sys_info },
132	{ REQ_SYS_STATS,	NOAUTH,	0, 0,	sys_stats },
133	{ REQ_IO_STATS,		NOAUTH,	0, 0,	io_stats },
134	{ REQ_MEM_STATS,	NOAUTH,	0, 0,	mem_stats },
135	{ REQ_LOOP_INFO,	NOAUTH,	0, 0,	loop_info },
136	{ REQ_TIMER_STATS,	NOAUTH,	0, 0,	timer_stats },
137	{ REQ_CONFIG,	    AUTH, v4sizeof(struct conf_peer),
138				sizeof(struct conf_peer), do_conf },
139	{ REQ_UNCONFIG,	    AUTH, v4sizeof(struct conf_unpeer),
140				sizeof(struct conf_unpeer), do_unconf },
141	{ REQ_SET_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags),
142				sizeof(struct conf_sys_flags), set_sys_flag },
143	{ REQ_CLR_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags),
144				sizeof(struct conf_sys_flags),  clr_sys_flag },
145	{ REQ_GET_RESTRICT,	NOAUTH,	0, 0,	list_restrict },
146	{ REQ_RESADDFLAGS, AUTH, v4sizeof(struct conf_restrict),
147				sizeof(struct conf_restrict), do_resaddflags },
148	{ REQ_RESSUBFLAGS, AUTH, v4sizeof(struct conf_restrict),
149				sizeof(struct conf_restrict), do_ressubflags },
150	{ REQ_UNRESTRICT, AUTH, v4sizeof(struct conf_restrict),
151				sizeof(struct conf_restrict), do_unrestrict },
152	{ REQ_MON_GETLIST,	NOAUTH,	0, 0,	mon_getlist_0 },
153	{ REQ_MON_GETLIST_1,	NOAUTH,	0, 0,	mon_getlist_1 },
154	{ REQ_RESET_STATS, AUTH, sizeof(struct reset_flags), 0, reset_stats },
155	{ REQ_RESET_PEER,  AUTH, v4sizeof(struct conf_unpeer),
156				sizeof(struct conf_unpeer), reset_peer },
157	{ REQ_REREAD_KEYS,	AUTH,	0, 0,	do_key_reread },
158	{ REQ_TRUSTKEY,   AUTH, sizeof(u_long), sizeof(u_long), trust_key },
159	{ REQ_UNTRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), untrust_key },
160	{ REQ_AUTHINFO,		NOAUTH,	0, 0,	get_auth_info },
161	{ REQ_TRAPS,		NOAUTH, 0, 0,	req_get_traps },
162	{ REQ_ADD_TRAP,	AUTH, v4sizeof(struct conf_trap),
163				sizeof(struct conf_trap), req_set_trap },
164	{ REQ_CLR_TRAP,	AUTH, v4sizeof(struct conf_trap),
165				sizeof(struct conf_trap), req_clr_trap },
166	{ REQ_REQUEST_KEY, AUTH, sizeof(u_long), sizeof(u_long),
167				set_request_keyid },
168	{ REQ_CONTROL_KEY, AUTH, sizeof(u_long), sizeof(u_long),
169				set_control_keyid },
170	{ REQ_GET_CTLSTATS,	NOAUTH,	0, 0,	get_ctl_stats },
171#ifdef KERNEL_PLL
172	{ REQ_GET_KERNEL,	NOAUTH,	0, 0,	get_kernel_info },
173#endif
174#ifdef REFCLOCK
175	{ REQ_GET_CLOCKINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32),
176				get_clock_info },
177	{ REQ_SET_CLKFUDGE, AUTH, sizeof(struct conf_fudge),
178				sizeof(struct conf_fudge), set_clock_fudge },
179	{ REQ_GET_CLKBUGINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32),
180				get_clkbug_info },
181#endif
182	{ REQ_IF_STATS,		AUTH, 0, 0,	get_if_stats },
183	{ REQ_IF_RELOAD,        AUTH, 0, 0,	do_if_reload },
184
185	{ NO_REQUEST,		NOAUTH,	0, 0,	0 }
186};
187
188
189/*
190 * Authentication keyid used to authenticate requests.  Zero means we
191 * don't allow writing anything.
192 */
193keyid_t info_auth_keyid;
194
195/*
196 * Statistic counters to keep track of requests and responses.
197 */
198u_long numrequests;		/* number of requests we've received */
199u_long numresppkts;		/* number of resp packets sent with data */
200
201u_long errorcounter[INFO_ERR_AUTH+1];	/* lazy way to count errors, indexed */
202/* by the error code */
203
204/*
205 * A hack.  To keep the authentication module clear of ntp-ism's, we
206 * include a time reset variable for its stats here.
207 */
208static u_long auth_timereset;
209
210/*
211 * Response packet used by these routines.  Also some state information
212 * so that we can handle packet formatting within a common set of
213 * subroutines.  Note we try to enter data in place whenever possible,
214 * but the need to set the more bit correctly means we occasionally
215 * use the extra buffer and copy.
216 */
217static struct resp_pkt rpkt;
218static int reqver;
219static int seqno;
220static int nitems;
221static int itemsize;
222static int databytes;
223static char exbuf[RESP_DATA_SIZE];
224static int usingexbuf;
225static sockaddr_u *toaddr;
226static struct interface *frominter;
227
228/*
229 * init_request - initialize request data
230 */
231void
232init_request (void)
233{
234	size_t i;
235
236	numrequests = 0;
237	numresppkts = 0;
238	auth_timereset = 0;
239	info_auth_keyid = 0;	/* by default, can't do this */
240
241	for (i = 0; i < sizeof(errorcounter)/sizeof(errorcounter[0]); i++)
242	    errorcounter[i] = 0;
243}
244
245
246/*
247 * req_ack - acknowledge request with no data
248 */
249static void
250req_ack(
251	sockaddr_u *srcadr,
252	struct interface *inter,
253	struct req_pkt *inpkt,
254	int errcode
255	)
256{
257	/*
258	 * fill in the fields
259	 */
260	rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver);
261	rpkt.auth_seq = AUTH_SEQ(0, 0);
262	rpkt.implementation = inpkt->implementation;
263	rpkt.request = inpkt->request;
264	rpkt.err_nitems = ERR_NITEMS(errcode, 0);
265	rpkt.mbz_itemsize = MBZ_ITEMSIZE(0);
266
267	/*
268	 * send packet and bump counters
269	 */
270	sendpkt(srcadr, inter, -1, (struct pkt *)&rpkt, RESP_HEADER_SIZE);
271	errorcounter[errcode]++;
272}
273
274
275/*
276 * prepare_pkt - prepare response packet for transmission, return pointer
277 *		 to storage for data item.
278 */
279static char *
280prepare_pkt(
281	sockaddr_u *srcadr,
282	struct interface *inter,
283	struct req_pkt *pkt,
284	size_t structsize
285	)
286{
287	DPRINTF(4, ("request: preparing pkt\n"));
288
289	/*
290	 * Fill in the implementation, request and itemsize fields
291	 * since these won't change.
292	 */
293	rpkt.implementation = pkt->implementation;
294	rpkt.request = pkt->request;
295	rpkt.mbz_itemsize = MBZ_ITEMSIZE(structsize);
296
297	/*
298	 * Compute the static data needed to carry on.
299	 */
300	toaddr = srcadr;
301	frominter = inter;
302	seqno = 0;
303	nitems = 0;
304	itemsize = structsize;
305	databytes = 0;
306	usingexbuf = 0;
307
308	/*
309	 * return the beginning of the packet buffer.
310	 */
311	return &rpkt.data[0];
312}
313
314
315/*
316 * more_pkt - return a data pointer for a new item.
317 */
318static char *
319more_pkt(void)
320{
321	/*
322	 * If we were using the extra buffer, send the packet.
323	 */
324	if (usingexbuf) {
325		DPRINTF(3, ("request: sending pkt\n"));
326		rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, MORE_BIT, reqver);
327		rpkt.auth_seq = AUTH_SEQ(0, seqno);
328		rpkt.err_nitems = htons((u_short)nitems);
329		sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt,
330			RESP_HEADER_SIZE + databytes);
331		numresppkts++;
332
333		/*
334		 * Copy data out of exbuf into the packet.
335		 */
336		memcpy(&rpkt.data[0], exbuf, (unsigned)itemsize);
337		seqno++;
338		databytes = 0;
339		nitems = 0;
340		usingexbuf = 0;
341	}
342
343	databytes += itemsize;
344	nitems++;
345	if (databytes + itemsize <= RESP_DATA_SIZE) {
346		DPRINTF(4, ("request: giving him more data\n"));
347		/*
348		 * More room in packet.  Give him the
349		 * next address.
350		 */
351		return &rpkt.data[databytes];
352	} else {
353		/*
354		 * No room in packet.  Give him the extra
355		 * buffer unless this was the last in the sequence.
356		 */
357		DPRINTF(4, ("request: into extra buffer\n"));
358		if (seqno == MAXSEQ)
359			return NULL;
360		else {
361			usingexbuf = 1;
362			return exbuf;
363		}
364	}
365}
366
367
368/*
369 * flush_pkt - we're done, return remaining information.
370 */
371static void
372flush_pkt(void)
373{
374	DPRINTF(3, ("request: flushing packet, %d items\n", nitems));
375	/*
376	 * Must send the last packet.  If nothing in here and nothing
377	 * has been sent, send an error saying no data to be found.
378	 */
379	if (seqno == 0 && nitems == 0)
380		req_ack(toaddr, frominter, (struct req_pkt *)&rpkt,
381			INFO_ERR_NODATA);
382	else {
383		rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver);
384		rpkt.auth_seq = AUTH_SEQ(0, seqno);
385		rpkt.err_nitems = htons((u_short)nitems);
386		sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt,
387			RESP_HEADER_SIZE+databytes);
388		numresppkts++;
389	}
390}
391
392
393
394/*
395 * Given a buffer, return the packet mode
396 */
397int
398get_packet_mode(struct recvbuf *rbufp)
399{
400	struct req_pkt *inpkt = (struct req_pkt *)&rbufp->recv_pkt;
401	return (INFO_MODE(inpkt->rm_vn_mode));
402}
403
404
405/*
406 * process_private - process private mode (7) packets
407 */
408void
409process_private(
410	struct recvbuf *rbufp,
411	int mod_okay
412	)
413{
414	static u_long quiet_until;
415	struct req_pkt *inpkt;
416	struct req_pkt_tail *tailinpkt;
417	sockaddr_u *srcadr;
418	struct interface *inter;
419	struct req_proc *proc;
420	int ec;
421	short temp_size;
422	l_fp ftmp;
423	double dtemp;
424	size_t recv_len;
425	size_t noslop_len;
426	size_t mac_len;
427
428	/*
429	 * Initialize pointers, for convenience
430	 */
431	recv_len = rbufp->recv_length;
432	inpkt = (struct req_pkt *)&rbufp->recv_pkt;
433	srcadr = &rbufp->recv_srcadr;
434	inter = rbufp->dstadr;
435
436	DPRINTF(3, ("process_private: impl %d req %d\n",
437		    inpkt->implementation, inpkt->request));
438
439	/*
440	 * Do some sanity checks on the packet.  Return a format
441	 * error if it fails.
442	 */
443	ec = 0;
444	if (   (++ec, ISRESPONSE(inpkt->rm_vn_mode))
445	    || (++ec, ISMORE(inpkt->rm_vn_mode))
446	    || (++ec, INFO_VERSION(inpkt->rm_vn_mode) > NTP_VERSION)
447	    || (++ec, INFO_VERSION(inpkt->rm_vn_mode) < NTP_OLDVERSION)
448	    || (++ec, INFO_SEQ(inpkt->auth_seq) != 0)
449	    || (++ec, INFO_ERR(inpkt->err_nitems) != 0)
450	    || (++ec, INFO_MBZ(inpkt->mbz_itemsize) != 0)
451	    || (++ec, rbufp->recv_length < (int)REQ_LEN_HDR)
452		) {
453		NLOG(NLOG_SYSEVENT)
454			if (current_time >= quiet_until) {
455				msyslog(LOG_ERR,
456					"process_private: drop test %d"
457					" failed, pkt from %s",
458					ec, stoa(srcadr));
459				quiet_until = current_time + 60;
460			}
461		return;
462	}
463
464	reqver = INFO_VERSION(inpkt->rm_vn_mode);
465
466	/*
467	 * Get the appropriate procedure list to search.
468	 */
469	if (inpkt->implementation == IMPL_UNIV)
470		proc = univ_codes;
471	else if ((inpkt->implementation == IMPL_XNTPD) ||
472		 (inpkt->implementation == IMPL_XNTPD_OLD))
473		proc = ntp_codes;
474	else {
475		req_ack(srcadr, inter, inpkt, INFO_ERR_IMPL);
476		return;
477	}
478
479	/*
480	 * Search the list for the request codes.  If it isn't one
481	 * we know, return an error.
482	 */
483	while (proc->request_code != NO_REQUEST) {
484		if (proc->request_code == (short) inpkt->request)
485			break;
486		proc++;
487	}
488	if (proc->request_code == NO_REQUEST) {
489		req_ack(srcadr, inter, inpkt, INFO_ERR_REQ);
490		return;
491	}
492
493	DPRINTF(4, ("found request in tables\n"));
494
495	/*
496	 * If we need data, check to see if we have some.  If we
497	 * don't, check to see that there is none (picky, picky).
498	 */
499
500	/* This part is a bit tricky, we want to be sure that the size
501	 * returned is either the old or the new size.  We also can find
502	 * out if the client can accept both types of messages this way.
503	 *
504	 * Handle the exception of REQ_CONFIG. It can have two data sizes.
505	 */
506	temp_size = INFO_ITEMSIZE(inpkt->mbz_itemsize);
507	if ((temp_size != proc->sizeofitem &&
508	     temp_size != proc->v6_sizeofitem) &&
509	    !(inpkt->implementation == IMPL_XNTPD &&
510	      inpkt->request == REQ_CONFIG &&
511	      temp_size == sizeof(struct old_conf_peer))) {
512		DPRINTF(3, ("process_private: wrong item size, received %d, should be %d or %d\n",
513			    temp_size, proc->sizeofitem, proc->v6_sizeofitem));
514		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
515		return;
516	}
517	if ((proc->sizeofitem != 0) &&
518	    ((size_t)(temp_size * INFO_NITEMS(inpkt->err_nitems)) >
519	     (recv_len - REQ_LEN_HDR))) {
520		DPRINTF(3, ("process_private: not enough data\n"));
521		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
522		return;
523	}
524
525	switch (inpkt->implementation) {
526	case IMPL_XNTPD:
527		client_v6_capable = 1;
528		break;
529	case IMPL_XNTPD_OLD:
530		client_v6_capable = 0;
531		break;
532	default:
533		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
534		return;
535	}
536
537	/*
538	 * If we need to authenticate, do so.  Note that an
539	 * authenticatable packet must include a mac field, must
540	 * have used key info_auth_keyid and must have included
541	 * a time stamp in the appropriate field.  The time stamp
542	 * must be within INFO_TS_MAXSKEW of the receive
543	 * time stamp.
544	 */
545	if (proc->needs_auth && sys_authenticate) {
546
547		if (recv_len < (REQ_LEN_HDR +
548		    (INFO_ITEMSIZE(inpkt->mbz_itemsize) *
549		    INFO_NITEMS(inpkt->err_nitems)) +
550		    REQ_TAIL_MIN)) {
551			req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
552			return;
553		}
554
555		/*
556		 * For 16-octet digests, regardless of itemsize and
557		 * nitems, authenticated requests are a fixed size
558		 * with the timestamp, key ID, and digest located
559		 * at the end of the packet.  Because the key ID
560		 * determining the digest size precedes the digest,
561		 * for larger digests the fixed size request scheme
562		 * is abandoned and the timestamp, key ID, and digest
563		 * are located relative to the start of the packet,
564		 * with the digest size determined by the packet size.
565		 */
566		noslop_len = REQ_LEN_HDR
567			     + INFO_ITEMSIZE(inpkt->mbz_itemsize) *
568			       INFO_NITEMS(inpkt->err_nitems)
569			     + sizeof(inpkt->tstamp);
570		/* 32-bit alignment */
571		noslop_len = (noslop_len + 3) & ~3;
572		if (recv_len > (noslop_len + MAX_MAC_LEN))
573			mac_len = 20;
574		else
575			mac_len = recv_len - noslop_len;
576
577		tailinpkt = (void *)((char *)inpkt + recv_len -
578			    (mac_len + sizeof(inpkt->tstamp)));
579
580		/*
581		 * If this guy is restricted from doing this, don't let
582		 * him.  If the wrong key was used, or packet doesn't
583		 * have mac, return.
584		 */
585		if (!INFO_IS_AUTH(inpkt->auth_seq) || !info_auth_keyid
586		    || ntohl(tailinpkt->keyid) != info_auth_keyid) {
587			DPRINTF(5, ("failed auth %d info_auth_keyid %u pkt keyid %u maclen %lu\n",
588				    INFO_IS_AUTH(inpkt->auth_seq),
589				    info_auth_keyid,
590				    ntohl(tailinpkt->keyid), (u_long)mac_len));
591#ifdef DEBUG
592			msyslog(LOG_DEBUG,
593				"process_private: failed auth %d info_auth_keyid %u pkt keyid %u maclen %lu\n",
594				INFO_IS_AUTH(inpkt->auth_seq),
595				info_auth_keyid,
596				ntohl(tailinpkt->keyid), (u_long)mac_len);
597#endif
598			req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
599			return;
600		}
601		if (recv_len > REQ_LEN_NOMAC + MAX_MAC_LEN) {
602			DPRINTF(5, ("bad pkt length %zu\n", recv_len));
603			msyslog(LOG_ERR,
604				"process_private: bad pkt length %zu",
605				recv_len);
606			req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
607			return;
608		}
609		if (!mod_okay || !authhavekey(info_auth_keyid)) {
610			DPRINTF(5, ("failed auth mod_okay %d\n",
611				    mod_okay));
612#ifdef DEBUG
613			msyslog(LOG_DEBUG,
614				"process_private: failed auth mod_okay %d\n",
615				mod_okay);
616#endif
617			req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
618			return;
619		}
620
621		/*
622		 * calculate absolute time difference between xmit time stamp
623		 * and receive time stamp.  If too large, too bad.
624		 */
625		NTOHL_FP(&tailinpkt->tstamp, &ftmp);
626		L_SUB(&ftmp, &rbufp->recv_time);
627		LFPTOD(&ftmp, dtemp);
628		if (fabs(dtemp) > INFO_TS_MAXSKEW) {
629			/*
630			 * He's a loser.  Tell him.
631			 */
632			DPRINTF(5, ("xmit/rcv timestamp delta %g > INFO_TS_MAXSKEW %g\n",
633				    dtemp, INFO_TS_MAXSKEW));
634			req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
635			return;
636		}
637
638		/*
639		 * So far so good.  See if decryption works out okay.
640		 */
641		if (!authdecrypt(info_auth_keyid, (u_int32 *)inpkt,
642				 recv_len - mac_len, mac_len)) {
643			DPRINTF(5, ("authdecrypt failed\n"));
644			req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
645			return;
646		}
647	}
648
649	DPRINTF(3, ("process_private: all okay, into handler\n"));
650	/*
651	 * Packet is okay.  Call the handler to send him data.
652	 */
653	(proc->handler)(srcadr, inter, inpkt);
654}
655
656
657/*
658 * peer_list - send a list of the peers
659 */
660static void
661peer_list(
662	sockaddr_u *srcadr,
663	struct interface *inter,
664	struct req_pkt *inpkt
665	)
666{
667	register struct info_peer_list *ip;
668	register struct peer *pp;
669	register int i;
670	register int skip = 0;
671
672	ip = (struct info_peer_list *)prepare_pkt(srcadr, inter, inpkt,
673	    v6sizeof(struct info_peer_list));
674	for (i = 0; i < NTP_HASH_SIZE && ip != 0; i++) {
675		pp = peer_hash[i];
676		while (pp != 0 && ip != 0) {
677			if (IS_IPV6(&pp->srcadr)) {
678				if (client_v6_capable) {
679					ip->addr6 = SOCK_ADDR6(&pp->srcadr);
680					ip->v6_flag = 1;
681					skip = 0;
682				} else {
683					skip = 1;
684					break;
685				}
686			} else {
687				ip->addr = NSRCADR(&pp->srcadr);
688				if (client_v6_capable)
689					ip->v6_flag = 0;
690				skip = 0;
691			}
692
693			if(!skip) {
694				ip->port = NSRCPORT(&pp->srcadr);
695				ip->hmode = pp->hmode;
696				ip->flags = 0;
697				if (pp->flags & FLAG_CONFIG)
698				    ip->flags |= INFO_FLAG_CONFIG;
699				if (pp == sys_peer)
700				    ip->flags |= INFO_FLAG_SYSPEER;
701				if (pp->status == CTL_PST_SEL_SYNCCAND)
702				    ip->flags |= INFO_FLAG_SEL_CANDIDATE;
703				if (pp->status >= CTL_PST_SEL_SYSPEER)
704				    ip->flags |= INFO_FLAG_SHORTLIST;
705				ip = (struct info_peer_list *)more_pkt();
706			}
707			pp = pp->next;
708		}
709	}
710	flush_pkt();
711}
712
713
714/*
715 * peer_list_sum - return extended peer list
716 */
717static void
718peer_list_sum(
719	sockaddr_u *srcadr,
720	struct interface *inter,
721	struct req_pkt *inpkt
722	)
723{
724	register struct info_peer_summary *ips;
725	register struct peer *pp;
726	register int i;
727	l_fp ltmp;
728	register int skip;
729
730#ifdef DEBUG
731	if (debug > 2)
732	    printf("wants peer list summary\n");
733#endif
734	ips = (struct info_peer_summary *)prepare_pkt(srcadr, inter, inpkt,
735	    v6sizeof(struct info_peer_summary));
736	for (i = 0; i < NTP_HASH_SIZE && ips != 0; i++) {
737		pp = peer_hash[i];
738		while (pp != 0 && ips != 0) {
739#ifdef DEBUG
740			if (debug > 3)
741			    printf("sum: got one\n");
742#endif
743			/*
744			 * Be careful here not to return v6 peers when we
745			 * want only v4.
746			 */
747			if (IS_IPV6(&pp->srcadr)) {
748				if (client_v6_capable) {
749					ips->srcadr6 = SOCK_ADDR6(&pp->srcadr);
750					ips->v6_flag = 1;
751					if (pp->dstadr)
752						ips->dstadr6 = SOCK_ADDR6(&pp->dstadr->sin);
753					else
754						memset(&ips->dstadr6, 0, sizeof(ips->dstadr6));
755					skip = 0;
756				} else {
757					skip = 1;
758					break;
759				}
760			} else {
761				ips->srcadr = NSRCADR(&pp->srcadr);
762				if (client_v6_capable)
763					ips->v6_flag = 0;
764
765				if (pp->dstadr) {
766					if (!pp->processed)
767						ips->dstadr = NSRCADR(&pp->dstadr->sin);
768					else {
769						if (MDF_BCAST == pp->cast_flags)
770							ips->dstadr = NSRCADR(&pp->dstadr->bcast);
771						else if (pp->cast_flags) {
772							ips->dstadr = NSRCADR(&pp->dstadr->sin);
773							if (!ips->dstadr)
774								ips->dstadr = NSRCADR(&pp->dstadr->bcast);
775						}
776					}
777				} else
778					ips->dstadr = 0;
779
780				skip = 0;
781			}
782
783			if (!skip){
784				ips->srcport = NSRCPORT(&pp->srcadr);
785				ips->stratum = pp->stratum;
786				ips->hpoll = pp->hpoll;
787				ips->ppoll = pp->ppoll;
788				ips->reach = pp->reach;
789				ips->flags = 0;
790				if (pp == sys_peer)
791				    ips->flags |= INFO_FLAG_SYSPEER;
792				if (pp->flags & FLAG_CONFIG)
793				    ips->flags |= INFO_FLAG_CONFIG;
794				if (pp->flags & FLAG_REFCLOCK)
795				    ips->flags |= INFO_FLAG_REFCLOCK;
796				if (pp->flags & FLAG_PREFER)
797				    ips->flags |= INFO_FLAG_PREFER;
798				if (pp->flags & FLAG_BURST)
799				    ips->flags |= INFO_FLAG_BURST;
800				if (pp->status == CTL_PST_SEL_SYNCCAND)
801				    ips->flags |= INFO_FLAG_SEL_CANDIDATE;
802				if (pp->status >= CTL_PST_SEL_SYSPEER)
803				    ips->flags |= INFO_FLAG_SHORTLIST;
804				ips->hmode = pp->hmode;
805				ips->delay = HTONS_FP(DTOFP(pp->delay));
806				DTOLFP(pp->offset, &ltmp);
807				HTONL_FP(&ltmp, &ips->offset);
808				ips->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp)));
809			}
810			pp = pp->next;
811			ips = (struct info_peer_summary *)more_pkt();
812		}
813	}
814	flush_pkt();
815}
816
817
818/*
819 * peer_info - send information for one or more peers
820 */
821static void
822peer_info (
823	sockaddr_u *srcadr,
824	struct interface *inter,
825	struct req_pkt *inpkt
826	)
827{
828	register struct info_peer_list *ipl;
829	register struct peer *pp;
830	register struct info_peer *ip;
831	register int items;
832	register int i, j;
833	sockaddr_u addr;
834	extern struct peer *sys_peer;
835	l_fp ltmp;
836
837	items = INFO_NITEMS(inpkt->err_nitems);
838	ipl = (struct info_peer_list *) inpkt->data;
839
840	ip = (struct info_peer *)prepare_pkt(srcadr, inter, inpkt,
841	    v6sizeof(struct info_peer));
842	while (items-- > 0 && ip != 0) {
843		ZERO_SOCK(&addr);
844		NSRCPORT(&addr) = ipl->port;
845		if (client_v6_capable && ipl->v6_flag) {
846			AF(&addr) = AF_INET6;
847			SOCK_ADDR6(&addr) = ipl->addr6;
848		} else {
849			AF(&addr) = AF_INET;
850			NSRCADR(&addr) = ipl->addr;
851		}
852#ifdef ISC_PLATFORM_HAVESALEN
853		addr.sa.sa_len = SOCKLEN(&addr);
854#endif
855		ipl++;
856		pp = findexistingpeer(&addr, NULL, -1, 0);
857		if (NULL == pp)
858			continue;
859		if (IS_IPV6(srcadr)) {
860			if (pp->dstadr)
861				ip->dstadr6 =
862				    (MDF_BCAST == pp->cast_flags)
863					? SOCK_ADDR6(&pp->dstadr->bcast)
864					: SOCK_ADDR6(&pp->dstadr->sin);
865			else
866				memset(&ip->dstadr6, 0, sizeof(ip->dstadr6));
867
868			ip->srcadr6 = SOCK_ADDR6(&pp->srcadr);
869			ip->v6_flag = 1;
870		} else {
871			if (pp->dstadr) {
872				if (!pp->processed)
873					ip->dstadr = NSRCADR(&pp->dstadr->sin);
874				else {
875					if (MDF_BCAST == pp->cast_flags)
876						ip->dstadr = NSRCADR(&pp->dstadr->bcast);
877					else if (pp->cast_flags) {
878						ip->dstadr = NSRCADR(&pp->dstadr->sin);
879						if (!ip->dstadr)
880							ip->dstadr = NSRCADR(&pp->dstadr->bcast);
881					}
882				}
883			} else
884				ip->dstadr = 0;
885
886			ip->srcadr = NSRCADR(&pp->srcadr);
887			if (client_v6_capable)
888				ip->v6_flag = 0;
889		}
890		ip->srcport = NSRCPORT(&pp->srcadr);
891		ip->flags = 0;
892		if (pp == sys_peer)
893		    ip->flags |= INFO_FLAG_SYSPEER;
894		if (pp->flags & FLAG_CONFIG)
895		    ip->flags |= INFO_FLAG_CONFIG;
896		if (pp->flags & FLAG_REFCLOCK)
897		    ip->flags |= INFO_FLAG_REFCLOCK;
898		if (pp->flags & FLAG_PREFER)
899		    ip->flags |= INFO_FLAG_PREFER;
900		if (pp->flags & FLAG_BURST)
901		    ip->flags |= INFO_FLAG_BURST;
902		if (pp->status == CTL_PST_SEL_SYNCCAND)
903		    ip->flags |= INFO_FLAG_SEL_CANDIDATE;
904		if (pp->status >= CTL_PST_SEL_SYSPEER)
905		    ip->flags |= INFO_FLAG_SHORTLIST;
906		ip->leap = pp->leap;
907		ip->hmode = pp->hmode;
908		ip->keyid = pp->keyid;
909		ip->stratum = pp->stratum;
910		ip->ppoll = pp->ppoll;
911		ip->hpoll = pp->hpoll;
912		ip->precision = pp->precision;
913		ip->version = pp->version;
914		ip->reach = pp->reach;
915		ip->unreach = (u_char) pp->unreach;
916		ip->flash = (u_char)pp->flash;
917		ip->flash2 = (u_short) pp->flash;
918		ip->estbdelay = HTONS_FP(DTOFP(pp->delay));
919		ip->ttl = pp->ttl;
920		ip->associd = htons(pp->associd);
921		ip->rootdelay = HTONS_FP(DTOUFP(pp->rootdelay));
922		ip->rootdispersion = HTONS_FP(DTOUFP(pp->rootdisp));
923		ip->refid = pp->refid;
924		HTONL_FP(&pp->reftime, &ip->reftime);
925		HTONL_FP(&pp->aorg, &ip->org);
926		HTONL_FP(&pp->rec, &ip->rec);
927		HTONL_FP(&pp->xmt, &ip->xmt);
928		j = pp->filter_nextpt - 1;
929		for (i = 0; i < NTP_SHIFT; i++, j--) {
930			if (j < 0)
931			    j = NTP_SHIFT-1;
932			ip->filtdelay[i] = HTONS_FP(DTOFP(pp->filter_delay[j]));
933			DTOLFP(pp->filter_offset[j], &ltmp);
934			HTONL_FP(&ltmp, &ip->filtoffset[i]);
935			ip->order[i] = (u_char)((pp->filter_nextpt+NTP_SHIFT-1)
936				- pp->filter_order[i]);
937			if (ip->order[i] >= NTP_SHIFT)
938			    ip->order[i] -= NTP_SHIFT;
939		}
940		DTOLFP(pp->offset, &ltmp);
941		HTONL_FP(&ltmp, &ip->offset);
942		ip->delay = HTONS_FP(DTOFP(pp->delay));
943		ip->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp)));
944		ip->selectdisp = HTONS_FP(DTOUFP(SQRT(pp->jitter)));
945		ip = (struct info_peer *)more_pkt();
946	}
947	flush_pkt();
948}
949
950
951/*
952 * peer_stats - send statistics for one or more peers
953 */
954static void
955peer_stats (
956	sockaddr_u *srcadr,
957	struct interface *inter,
958	struct req_pkt *inpkt
959	)
960{
961	register struct info_peer_list *ipl;
962	register struct peer *pp;
963	register struct info_peer_stats *ip;
964	register int items;
965	sockaddr_u addr;
966	extern struct peer *sys_peer;
967
968#ifdef DEBUG
969	if (debug)
970	     printf("peer_stats: called\n");
971#endif
972	items = INFO_NITEMS(inpkt->err_nitems);
973	ipl = (struct info_peer_list *) inpkt->data;
974	ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt,
975	    v6sizeof(struct info_peer_stats));
976	while (items-- > 0 && ip != 0) {
977		memset((char *)&addr, 0, sizeof(addr));
978		NSRCPORT(&addr) = ipl->port;
979		if (client_v6_capable && ipl->v6_flag) {
980			AF(&addr) = AF_INET6;
981			SOCK_ADDR6(&addr) = ipl->addr6;
982		} else {
983			AF(&addr) = AF_INET;
984			NSRCADR(&addr) = ipl->addr;
985		}
986#ifdef ISC_PLATFORM_HAVESALEN
987		addr.sa.sa_len = SOCKLEN(&addr);
988#endif
989		DPRINTF(1, ("peer_stats: looking for %s, %d, %d\n",
990			    stoa(&addr), ipl->port, NSRCPORT(&addr)));
991
992		ipl = (struct info_peer_list *)((char *)ipl +
993		    INFO_ITEMSIZE(inpkt->mbz_itemsize));
994
995		pp = findexistingpeer(&addr, NULL, -1, 0);
996		if (NULL == pp)
997			continue;
998
999		DPRINTF(1, ("peer_stats: found %s\n", stoa(&addr)));
1000
1001		if (IS_IPV4(&pp->srcadr)) {
1002			if (pp->dstadr) {
1003				if (!pp->processed)
1004					ip->dstadr = NSRCADR(&pp->dstadr->sin);
1005				else {
1006					if (MDF_BCAST == pp->cast_flags)
1007						ip->dstadr = NSRCADR(&pp->dstadr->bcast);
1008					else if (pp->cast_flags) {
1009						ip->dstadr = NSRCADR(&pp->dstadr->sin);
1010						if (!ip->dstadr)
1011							ip->dstadr = NSRCADR(&pp->dstadr->bcast);
1012					}
1013				}
1014			} else
1015				ip->dstadr = 0;
1016
1017			ip->srcadr = NSRCADR(&pp->srcadr);
1018			if (client_v6_capable)
1019				ip->v6_flag = 0;
1020		} else {
1021			if (pp->dstadr)
1022				ip->dstadr6 =
1023				    (MDF_BCAST == pp->cast_flags)
1024					? SOCK_ADDR6(&pp->dstadr->bcast)
1025					: SOCK_ADDR6(&pp->dstadr->sin);
1026			else
1027				memset(&ip->dstadr6, 0, sizeof(ip->dstadr6));
1028
1029			ip->srcadr6 = SOCK_ADDR6(&pp->srcadr);
1030			ip->v6_flag = 1;
1031		}
1032		ip->srcport = NSRCPORT(&pp->srcadr);
1033		ip->flags = 0;
1034		if (pp == sys_peer)
1035		    ip->flags |= INFO_FLAG_SYSPEER;
1036		if (pp->flags & FLAG_CONFIG)
1037		    ip->flags |= INFO_FLAG_CONFIG;
1038		if (pp->flags & FLAG_REFCLOCK)
1039		    ip->flags |= INFO_FLAG_REFCLOCK;
1040		if (pp->flags & FLAG_PREFER)
1041		    ip->flags |= INFO_FLAG_PREFER;
1042		if (pp->flags & FLAG_BURST)
1043		    ip->flags |= INFO_FLAG_BURST;
1044		if (pp->flags & FLAG_IBURST)
1045		    ip->flags |= INFO_FLAG_IBURST;
1046		if (pp->status == CTL_PST_SEL_SYNCCAND)
1047		    ip->flags |= INFO_FLAG_SEL_CANDIDATE;
1048		if (pp->status >= CTL_PST_SEL_SYSPEER)
1049		    ip->flags |= INFO_FLAG_SHORTLIST;
1050		ip->flags = htons(ip->flags);
1051		ip->timereceived = htonl((u_int32)(current_time - pp->timereceived));
1052		ip->timetosend = htonl(pp->nextdate - current_time);
1053		ip->timereachable = htonl((u_int32)(current_time - pp->timereachable));
1054		ip->sent = htonl((u_int32)(pp->sent));
1055		ip->processed = htonl((u_int32)(pp->processed));
1056		ip->badauth = htonl((u_int32)(pp->badauth));
1057		ip->bogusorg = htonl((u_int32)(pp->bogusorg));
1058		ip->oldpkt = htonl((u_int32)(pp->oldpkt));
1059		ip->seldisp = htonl((u_int32)(pp->seldisptoolarge));
1060		ip->selbroken = htonl((u_int32)(pp->selbroken));
1061		ip->candidate = pp->status;
1062		ip = (struct info_peer_stats *)more_pkt();
1063	}
1064	flush_pkt();
1065}
1066
1067
1068/*
1069 * sys_info - return system info
1070 */
1071static void
1072sys_info(
1073	sockaddr_u *srcadr,
1074	struct interface *inter,
1075	struct req_pkt *inpkt
1076	)
1077{
1078	register struct info_sys *is;
1079
1080	is = (struct info_sys *)prepare_pkt(srcadr, inter, inpkt,
1081	    v6sizeof(struct info_sys));
1082
1083	if (sys_peer) {
1084		if (IS_IPV4(&sys_peer->srcadr)) {
1085			is->peer = NSRCADR(&sys_peer->srcadr);
1086			if (client_v6_capable)
1087				is->v6_flag = 0;
1088		} else if (client_v6_capable) {
1089			is->peer6 = SOCK_ADDR6(&sys_peer->srcadr);
1090			is->v6_flag = 1;
1091		}
1092		is->peer_mode = sys_peer->hmode;
1093	} else {
1094		is->peer = 0;
1095		if (client_v6_capable) {
1096			is->v6_flag = 0;
1097		}
1098		is->peer_mode = 0;
1099	}
1100
1101	is->leap = sys_leap;
1102	is->stratum = sys_stratum;
1103	is->precision = sys_precision;
1104	is->rootdelay = htonl(DTOFP(sys_rootdelay));
1105	is->rootdispersion = htonl(DTOUFP(sys_rootdisp));
1106	is->frequency = htonl(DTOFP(sys_jitter));
1107	is->stability = htonl(DTOUFP(clock_stability));
1108	is->refid = sys_refid;
1109	HTONL_FP(&sys_reftime, &is->reftime);
1110
1111	is->poll = sys_poll;
1112
1113	is->flags = 0;
1114	if (sys_authenticate)
1115		is->flags |= INFO_FLAG_AUTHENTICATE;
1116	if (sys_bclient)
1117		is->flags |= INFO_FLAG_BCLIENT;
1118#ifdef REFCLOCK
1119	if (cal_enable)
1120		is->flags |= INFO_FLAG_CAL;
1121#endif /* REFCLOCK */
1122	if (kern_enable)
1123		is->flags |= INFO_FLAG_KERNEL;
1124	if (mon_enabled != MON_OFF)
1125		is->flags |= INFO_FLAG_MONITOR;
1126	if (ntp_enable)
1127		is->flags |= INFO_FLAG_NTP;
1128	if (pps_enable)
1129		is->flags |= INFO_FLAG_PPS_SYNC;
1130	if (stats_control)
1131		is->flags |= INFO_FLAG_FILEGEN;
1132	is->bdelay = HTONS_FP(DTOFP(sys_bdelay));
1133	HTONL_UF(sys_authdelay.l_f, &is->authdelay);
1134	(void) more_pkt();
1135	flush_pkt();
1136}
1137
1138
1139/*
1140 * sys_stats - return system statistics
1141 */
1142static void
1143sys_stats(
1144	sockaddr_u *srcadr,
1145	struct interface *inter,
1146	struct req_pkt *inpkt
1147	)
1148{
1149	register struct info_sys_stats *ss;
1150
1151	/*
1152	 * Importations from the protocol module
1153	 */
1154	ss = (struct info_sys_stats *)prepare_pkt(srcadr, inter, inpkt,
1155		sizeof(struct info_sys_stats));
1156	ss->timeup = htonl((u_int32)current_time);
1157	ss->timereset = htonl((u_int32)(current_time - sys_stattime));
1158	ss->denied = htonl((u_int32)sys_restricted);
1159	ss->oldversionpkt = htonl((u_int32)sys_oldversion);
1160	ss->newversionpkt = htonl((u_int32)sys_newversion);
1161	ss->unknownversion = htonl((u_int32)sys_declined);
1162	ss->badlength = htonl((u_int32)sys_badlength);
1163	ss->processed = htonl((u_int32)sys_processed);
1164	ss->badauth = htonl((u_int32)sys_badauth);
1165	ss->limitrejected = htonl((u_int32)sys_limitrejected);
1166	ss->received = htonl((u_int32)sys_received);
1167	(void) more_pkt();
1168	flush_pkt();
1169}
1170
1171
1172/*
1173 * mem_stats - return memory statistics
1174 */
1175static void
1176mem_stats(
1177	sockaddr_u *srcadr,
1178	struct interface *inter,
1179	struct req_pkt *inpkt
1180	)
1181{
1182	register struct info_mem_stats *ms;
1183	register int i;
1184
1185	/*
1186	 * Importations from the peer module
1187	 */
1188	extern int peer_hash_count[];
1189	extern int peer_free_count;
1190	extern u_long peer_timereset;
1191	extern u_long findpeer_calls;
1192	extern u_long peer_allocations;
1193	extern u_long peer_demobilizations;
1194	extern int total_peer_structs;
1195
1196	ms = (struct info_mem_stats *)prepare_pkt(srcadr, inter, inpkt,
1197						  sizeof(struct info_mem_stats));
1198
1199	ms->timereset = htonl((u_int32)(current_time - peer_timereset));
1200	ms->totalpeermem = htons((u_short)total_peer_structs);
1201	ms->freepeermem = htons((u_short)peer_free_count);
1202	ms->findpeer_calls = htonl((u_int32)findpeer_calls);
1203	ms->allocations = htonl((u_int32)peer_allocations);
1204	ms->demobilizations = htonl((u_int32)peer_demobilizations);
1205
1206	for (i = 0; i < NTP_HASH_SIZE; i++) {
1207		if (peer_hash_count[i] > 255)
1208		    ms->hashcount[i] = 255;
1209		else
1210		    ms->hashcount[i] = (u_char)peer_hash_count[i];
1211	}
1212
1213	(void) more_pkt();
1214	flush_pkt();
1215}
1216
1217
1218/*
1219 * io_stats - return io statistics
1220 */
1221static void
1222io_stats(
1223	sockaddr_u *srcadr,
1224	struct interface *inter,
1225	struct req_pkt *inpkt
1226	)
1227{
1228	register struct info_io_stats *io;
1229
1230	/*
1231	 * Importations from the io module
1232	 */
1233	extern u_long io_timereset;
1234
1235	io = (struct info_io_stats *)prepare_pkt(srcadr, inter, inpkt,
1236						 sizeof(struct info_io_stats));
1237
1238	io->timereset = htonl((u_int32)(current_time - io_timereset));
1239	io->totalrecvbufs = htons((u_short) total_recvbuffs());
1240	io->freerecvbufs = htons((u_short) free_recvbuffs());
1241	io->fullrecvbufs = htons((u_short) full_recvbuffs());
1242	io->lowwater = htons((u_short) lowater_additions());
1243	io->dropped = htonl((u_int32)packets_dropped);
1244	io->ignored = htonl((u_int32)packets_ignored);
1245	io->received = htonl((u_int32)packets_received);
1246	io->sent = htonl((u_int32)packets_sent);
1247	io->notsent = htonl((u_int32)packets_notsent);
1248	io->interrupts = htonl((u_int32)handler_calls);
1249	io->int_received = htonl((u_int32)handler_pkts);
1250
1251	(void) more_pkt();
1252	flush_pkt();
1253}
1254
1255
1256/*
1257 * timer_stats - return timer statistics
1258 */
1259static void
1260timer_stats(
1261	sockaddr_u *		srcadr,
1262	struct interface *	inter,
1263	struct req_pkt *	inpkt
1264	)
1265{
1266	struct info_timer_stats *	ts;
1267	u_long				sincereset;
1268
1269	ts = (struct info_timer_stats *)prepare_pkt(srcadr, inter,
1270						    inpkt, sizeof(*ts));
1271
1272	sincereset = current_time - timer_timereset;
1273	ts->timereset = htonl((u_int32)sincereset);
1274	ts->alarms = ts->timereset;
1275	ts->overflows = htonl((u_int32)alarm_overflow);
1276	ts->xmtcalls = htonl((u_int32)timer_xmtcalls);
1277
1278	(void) more_pkt();
1279	flush_pkt();
1280}
1281
1282
1283/*
1284 * loop_info - return the current state of the loop filter
1285 */
1286static void
1287loop_info(
1288	sockaddr_u *srcadr,
1289	struct interface *inter,
1290	struct req_pkt *inpkt
1291	)
1292{
1293	register struct info_loop *li;
1294	l_fp ltmp;
1295
1296	/*
1297	 * Importations from the loop filter module
1298	 */
1299	extern double last_offset;
1300	extern double drift_comp;
1301	extern int tc_counter;
1302	extern u_long sys_epoch;
1303
1304	li = (struct info_loop *)prepare_pkt(srcadr, inter, inpkt,
1305	    sizeof(struct info_loop));
1306
1307	DTOLFP(last_offset, &ltmp);
1308	HTONL_FP(&ltmp, &li->last_offset);
1309	DTOLFP(drift_comp * 1e6, &ltmp);
1310	HTONL_FP(&ltmp, &li->drift_comp);
1311	li->compliance = htonl((u_int32)(tc_counter));
1312	li->watchdog_timer = htonl((u_int32)(current_time - sys_epoch));
1313
1314	(void) more_pkt();
1315	flush_pkt();
1316}
1317
1318
1319/*
1320 * do_conf - add a peer to the configuration list
1321 */
1322static void
1323do_conf(
1324	sockaddr_u *srcadr,
1325	struct interface *inter,
1326	struct req_pkt *inpkt
1327	)
1328{
1329	static u_long soonest_ifrescan_time = 0;
1330	int items;
1331	u_int fl;
1332	struct conf_peer *cp;
1333	struct conf_peer temp_cp;
1334	sockaddr_u peeraddr;
1335
1336	/*
1337	 * Do a check of everything to see that it looks
1338	 * okay.  If not, complain about it.  Note we are
1339	 * very picky here.
1340	 */
1341	items = INFO_NITEMS(inpkt->err_nitems);
1342	cp = (struct conf_peer *)inpkt->data;
1343	memset(&temp_cp, 0, sizeof(struct conf_peer));
1344	memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1345
1346#if 0 /* paranoid checking - these are done in newpeer() */
1347	fl = 0;
1348	while (items-- > 0 && !fl) {
1349		if (((temp_cp.version) > NTP_VERSION)
1350		    || ((temp_cp.version) < NTP_OLDVERSION))
1351		    fl = 1;
1352		if (temp_cp.hmode != MODE_ACTIVE
1353		    && temp_cp.hmode != MODE_CLIENT
1354		    && temp_cp.hmode != MODE_BROADCAST)
1355		    fl = 1;
1356		if (temp_cp.flags & ~(CONF_FLAG_PREFER | CONF_FLAG_BURST |
1357		    CONF_FLAG_IBURST | CONF_FLAG_SKEY))
1358			fl = 1;
1359		cp = (struct conf_peer *)
1360		    ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1361	}
1362
1363	if (fl) {
1364		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1365		return;
1366	}
1367#endif /* end paranoid checking */
1368
1369	/*
1370	 * Looks okay, try it out
1371	 */
1372	items = INFO_NITEMS(inpkt->err_nitems);
1373	cp = (struct conf_peer *)inpkt->data;
1374
1375	while (items-- > 0) {
1376		memset(&temp_cp, 0, sizeof(struct conf_peer));
1377		memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1378		ZERO_SOCK(&peeraddr);
1379
1380		fl = 0;
1381		if (temp_cp.flags & CONF_FLAG_PREFER)
1382			fl |= FLAG_PREFER;
1383		if (temp_cp.flags & CONF_FLAG_BURST)
1384		    fl |= FLAG_BURST;
1385		if (temp_cp.flags & CONF_FLAG_IBURST)
1386		    fl |= FLAG_IBURST;
1387#ifdef OPENSSL
1388		if (temp_cp.flags & CONF_FLAG_SKEY)
1389			fl |= FLAG_SKEY;
1390#endif /* OPENSSL */
1391		if (client_v6_capable && temp_cp.v6_flag != 0) {
1392			AF(&peeraddr) = AF_INET6;
1393			SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6;
1394		} else {
1395			AF(&peeraddr) = AF_INET;
1396			NSRCADR(&peeraddr) = temp_cp.peeraddr;
1397			/*
1398			 * Make sure the address is valid
1399			 */
1400			if (!ISREFCLOCKADR(&peeraddr) &&
1401			    ISBADADR(&peeraddr)) {
1402				req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1403				return;
1404			}
1405
1406		}
1407		NSRCPORT(&peeraddr) = htons(NTP_PORT);
1408#ifdef ISC_PLATFORM_HAVESALEN
1409		peeraddr.sa.sa_len = SOCKLEN(&peeraddr);
1410#endif
1411
1412		/* XXX W2DO? minpoll/maxpoll arguments ??? */
1413		if (peer_config(&peeraddr, (struct interface *)0,
1414		    temp_cp.hmode, temp_cp.version, temp_cp.minpoll,
1415		    temp_cp.maxpoll, fl, temp_cp.ttl, temp_cp.keyid,
1416		    NULL) == 0) {
1417			req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1418			return;
1419		}
1420
1421		/*
1422		 * ntp_intres.c uses REQ_CONFIG/doconf() to add each
1423		 * server after its name is resolved.  If we have been
1424		 * disconnected from the network, it may notice the
1425		 * network has returned and add the first server while
1426		 * the relevant interface is still disabled, awaiting
1427		 * the next interface rescan.  To get things moving
1428		 * more quickly, trigger an interface scan now, except
1429		 * if we have done so in the last half minute.
1430		 */
1431		if (soonest_ifrescan_time < current_time) {
1432			soonest_ifrescan_time = current_time + 30;
1433			timer_interfacetimeout(current_time);
1434			DPRINTF(1, ("do_conf triggering interface rescan\n"));
1435		}
1436
1437		cp = (struct conf_peer *)
1438		    ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1439	}
1440
1441	req_ack(srcadr, inter, inpkt, INFO_OKAY);
1442}
1443
1444#if 0
1445/* XXX */
1446/*
1447 * dns_a - Snarf DNS info for an association ID
1448 */
1449static void
1450dns_a(
1451	sockaddr_u *srcadr,
1452	struct interface *inter,
1453	struct req_pkt *inpkt
1454	)
1455{
1456	register struct info_dns_assoc *dp;
1457	register int items;
1458	struct sockaddr_in peeraddr;
1459
1460	/*
1461	 * Do a check of everything to see that it looks
1462	 * okay.  If not, complain about it.  Note we are
1463	 * very picky here.
1464	 */
1465	items = INFO_NITEMS(inpkt->err_nitems);
1466	dp = (struct info_dns_assoc *)inpkt->data;
1467
1468	/*
1469	 * Looks okay, try it out
1470	 */
1471	items = INFO_NITEMS(inpkt->err_nitems);
1472	dp = (struct info_dns_assoc *)inpkt->data;
1473	memset((char *)&peeraddr, 0, sizeof(struct sockaddr_in));
1474	peeraddr.sin_family = AF_INET;
1475	peeraddr.sin_port = htons(NTP_PORT);
1476
1477	/*
1478	 * Make sure the address is valid
1479	 */
1480	if (!ISREFCLOCKADR(&peeraddr) && ISBADADR(&peeraddr)) {
1481		msyslog(LOG_ERR, "dns_a: !ISREFCLOCKADR && ISBADADR");
1482		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1483		return;
1484	}
1485
1486	while (items-- > 0) {
1487		associd_t associd;
1488		size_t hnl;
1489		struct peer *peer;
1490		int bogon = 0;
1491
1492		associd = dp->associd;
1493		peer = findpeerbyassoc(associd);
1494		if (peer == 0 || peer->flags & FLAG_REFCLOCK) {
1495			msyslog(LOG_ERR, "dns_a: %s",
1496				(peer == 0)
1497				? "peer == 0"
1498				: "peer->flags & FLAG_REFCLOCK");
1499			++bogon;
1500		}
1501		peeraddr.sin_addr.s_addr = dp->peeraddr;
1502		for (hnl = 0; dp->hostname[hnl] && hnl < sizeof dp->hostname; ++hnl) ;
1503		if (hnl >= sizeof dp->hostname) {
1504			msyslog(LOG_ERR, "dns_a: hnl (%ld) >= %ld",
1505				(long)hnl, (long)sizeof dp->hostname);
1506			++bogon;
1507		}
1508
1509		msyslog(LOG_INFO, "dns_a: <%s> for %s, AssocID %d, bogon %d",
1510			dp->hostname,
1511			stoa((sockaddr_u *)&peeraddr), associd,
1512			bogon);
1513
1514		if (bogon) {
1515			/* If it didn't work */
1516			req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1517			return;
1518		} else {
1519#if 0
1520#ifdef PUBKEY
1521			crypto_public(peer, dp->hostname);
1522#endif /* PUBKEY */
1523#endif
1524		}
1525
1526		dp++;
1527	}
1528
1529	req_ack(srcadr, inter, inpkt, INFO_OKAY);
1530}
1531#endif /* 0 */
1532
1533/*
1534 * do_unconf - remove a peer from the configuration list
1535 */
1536static void
1537do_unconf(
1538	sockaddr_u *srcadr,
1539	struct interface *inter,
1540	struct req_pkt *inpkt
1541	)
1542{
1543	register struct conf_unpeer *cp;
1544	struct conf_unpeer temp_cp;
1545	register int items;
1546	register struct peer *peer;
1547	sockaddr_u peeraddr;
1548	int bad, found;
1549
1550	/*
1551	 * This is a bit unstructured, but I like to be careful.
1552	 * We check to see that every peer exists and is actually
1553	 * configured.  If so, we remove them.  If not, we return
1554	 * an error.
1555	 */
1556	items = INFO_NITEMS(inpkt->err_nitems);
1557	cp = (struct conf_unpeer *)inpkt->data;
1558
1559	bad = 0;
1560	while (items-- > 0 && !bad) {
1561		memset(&temp_cp, 0, sizeof(temp_cp));
1562		ZERO_SOCK(&peeraddr);
1563		memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1564		if (client_v6_capable && temp_cp.v6_flag) {
1565			AF(&peeraddr) = AF_INET6;
1566			SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6;
1567		} else {
1568			AF(&peeraddr) = AF_INET;
1569			NSRCADR(&peeraddr) = temp_cp.peeraddr;
1570		}
1571		SET_PORT(&peeraddr, NTP_PORT);
1572#ifdef ISC_PLATFORM_HAVESALEN
1573		peeraddr.sa.sa_len = SOCKLEN(&peeraddr);
1574#endif
1575		found = 0;
1576		peer = NULL;
1577
1578		DPRINTF(1, ("searching for %s\n", stoa(&peeraddr)));
1579
1580		while (!found) {
1581			peer = findexistingpeer(&peeraddr, peer, -1, 0);
1582			if (!peer)
1583				break;
1584			if (peer->flags & FLAG_CONFIG)
1585				found = 1;
1586		}
1587		if (!found)
1588			bad = 1;
1589		cp = (struct conf_unpeer *)
1590			((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1591	}
1592
1593	if (bad) {
1594		req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1595		return;
1596	}
1597
1598	/*
1599	 * Now do it in earnest.
1600	 */
1601
1602	items = INFO_NITEMS(inpkt->err_nitems);
1603	cp = (struct conf_unpeer *)inpkt->data;
1604
1605	while (items-- > 0) {
1606		memset(&temp_cp, 0, sizeof(temp_cp));
1607		memset(&peeraddr, 0, sizeof(peeraddr));
1608		memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1609		if (client_v6_capable && temp_cp.v6_flag) {
1610			AF(&peeraddr) = AF_INET6;
1611			SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6;
1612		} else {
1613			AF(&peeraddr) = AF_INET;
1614			NSRCADR(&peeraddr) = temp_cp.peeraddr;
1615		}
1616		SET_PORT(&peeraddr, NTP_PORT);
1617#ifdef ISC_PLATFORM_HAVESALEN
1618		peeraddr.sa.sa_len = SOCKLEN(&peeraddr);
1619#endif
1620		found = 0;
1621		peer = NULL;
1622
1623		while (!found) {
1624			peer = findexistingpeer(&peeraddr, peer, -1, 0);
1625			if (!peer)
1626				break;
1627			if (peer->flags & FLAG_CONFIG)
1628				found = 1;
1629		}
1630		NTP_INSIST(found);
1631		NTP_INSIST(peer);
1632
1633		peer_clear(peer, "GONE");
1634		unpeer(peer);
1635
1636		cp = (struct conf_unpeer *)
1637			((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1638	}
1639
1640	req_ack(srcadr, inter, inpkt, INFO_OKAY);
1641}
1642
1643
1644/*
1645 * set_sys_flag - set system flags
1646 */
1647static void
1648set_sys_flag(
1649	sockaddr_u *srcadr,
1650	struct interface *inter,
1651	struct req_pkt *inpkt
1652	)
1653{
1654	setclr_flags(srcadr, inter, inpkt, 1);
1655}
1656
1657
1658/*
1659 * clr_sys_flag - clear system flags
1660 */
1661static void
1662clr_sys_flag(
1663	sockaddr_u *srcadr,
1664	struct interface *inter,
1665	struct req_pkt *inpkt
1666	)
1667{
1668	setclr_flags(srcadr, inter, inpkt, 0);
1669}
1670
1671
1672/*
1673 * setclr_flags - do the grunge work of flag setting/clearing
1674 */
1675static void
1676setclr_flags(
1677	sockaddr_u *srcadr,
1678	struct interface *inter,
1679	struct req_pkt *inpkt,
1680	u_long set
1681	)
1682{
1683	struct conf_sys_flags *sf;
1684	u_int32 flags;
1685	int prev_kern_enable;
1686
1687	prev_kern_enable = kern_enable;
1688	if (INFO_NITEMS(inpkt->err_nitems) > 1) {
1689		msyslog(LOG_ERR, "setclr_flags: err_nitems > 1");
1690		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1691		return;
1692	}
1693
1694	sf = (struct conf_sys_flags *)inpkt->data;
1695	flags = ntohl(sf->flags);
1696
1697	if (flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS |
1698		      SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR |
1699		      SYS_FLAG_FILEGEN | SYS_FLAG_AUTH | SYS_FLAG_CAL)) {
1700		msyslog(LOG_ERR, "setclr_flags: extra flags: %#x",
1701			flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS |
1702				  SYS_FLAG_NTP | SYS_FLAG_KERNEL |
1703				  SYS_FLAG_MONITOR | SYS_FLAG_FILEGEN |
1704				  SYS_FLAG_AUTH | SYS_FLAG_CAL));
1705		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1706		return;
1707	}
1708
1709	if (flags & SYS_FLAG_BCLIENT)
1710		proto_config(PROTO_BROADCLIENT, set, 0., NULL);
1711	if (flags & SYS_FLAG_PPS)
1712		proto_config(PROTO_PPS, set, 0., NULL);
1713	if (flags & SYS_FLAG_NTP)
1714		proto_config(PROTO_NTP, set, 0., NULL);
1715	if (flags & SYS_FLAG_KERNEL)
1716		proto_config(PROTO_KERNEL, set, 0., NULL);
1717	if (flags & SYS_FLAG_MONITOR)
1718		proto_config(PROTO_MONITOR, set, 0., NULL);
1719	if (flags & SYS_FLAG_FILEGEN)
1720		proto_config(PROTO_FILEGEN, set, 0., NULL);
1721	if (flags & SYS_FLAG_AUTH)
1722		proto_config(PROTO_AUTHENTICATE, set, 0., NULL);
1723	if (flags & SYS_FLAG_CAL)
1724		proto_config(PROTO_CAL, set, 0., NULL);
1725	req_ack(srcadr, inter, inpkt, INFO_OKAY);
1726
1727	/* Reset the kernel ntp parameters if the kernel flag changed. */
1728	if (prev_kern_enable && !kern_enable)
1729	     	loop_config(LOOP_KERN_CLEAR, 0.0);
1730	if (!prev_kern_enable && kern_enable)
1731	     	loop_config(LOOP_DRIFTCOMP, drift_comp);
1732}
1733
1734/*
1735 * list_restrict4 - recursive helper for list_restrict dumps IPv4
1736 *		    restriction list in reverse order.
1737 */
1738static void
1739list_restrict4(
1740	restrict_u *		res,
1741	struct info_restrict **	ppir
1742	)
1743{
1744	struct info_restrict *	pir;
1745
1746	if (res->link != NULL)
1747		list_restrict4(res->link, ppir);
1748
1749	pir = *ppir;
1750	pir->addr = htonl(res->u.v4.addr);
1751	if (client_v6_capable)
1752		pir->v6_flag = 0;
1753	pir->mask = htonl(res->u.v4.mask);
1754	pir->count = htonl(res->count);
1755	pir->flags = htons(res->flags);
1756	pir->mflags = htons(res->mflags);
1757	*ppir = (struct info_restrict *)more_pkt();
1758}
1759
1760
1761/*
1762 * list_restrict6 - recursive helper for list_restrict dumps IPv6
1763 *		    restriction list in reverse order.
1764 */
1765static void
1766list_restrict6(
1767	restrict_u *		res,
1768	struct info_restrict **	ppir
1769	)
1770{
1771	struct info_restrict *	pir;
1772
1773	if (res->link != NULL)
1774		list_restrict6(res->link, ppir);
1775
1776	pir = *ppir;
1777	pir->addr6 = res->u.v6.addr;
1778	pir->mask6 = res->u.v6.mask;
1779	pir->v6_flag = 1;
1780	pir->count = htonl(res->count);
1781	pir->flags = htons(res->flags);
1782	pir->mflags = htons(res->mflags);
1783	*ppir = (struct info_restrict *)more_pkt();
1784}
1785
1786
1787/*
1788 * list_restrict - return the restrict list
1789 */
1790static void
1791list_restrict(
1792	sockaddr_u *srcadr,
1793	struct interface *inter,
1794	struct req_pkt *inpkt
1795	)
1796{
1797	struct info_restrict *ir;
1798
1799	DPRINTF(3, ("wants restrict list summary\n"));
1800
1801	ir = (struct info_restrict *)prepare_pkt(srcadr, inter, inpkt,
1802	    v6sizeof(struct info_restrict));
1803
1804	/*
1805	 * The restriction lists are kept sorted in the reverse order
1806	 * than they were originally.  To preserve the output semantics,
1807	 * dump each list in reverse order.  A recursive helper function
1808	 * achieves that.
1809	 */
1810	list_restrict4(restrictlist4, &ir);
1811	if (client_v6_capable)
1812		list_restrict6(restrictlist6, &ir);
1813	flush_pkt();
1814}
1815
1816
1817/*
1818 * do_resaddflags - add flags to a restrict entry (or create one)
1819 */
1820static void
1821do_resaddflags(
1822	sockaddr_u *srcadr,
1823	struct interface *inter,
1824	struct req_pkt *inpkt
1825	)
1826{
1827	do_restrict(srcadr, inter, inpkt, RESTRICT_FLAGS);
1828}
1829
1830
1831
1832/*
1833 * do_ressubflags - remove flags from a restrict entry
1834 */
1835static void
1836do_ressubflags(
1837	sockaddr_u *srcadr,
1838	struct interface *inter,
1839	struct req_pkt *inpkt
1840	)
1841{
1842	do_restrict(srcadr, inter, inpkt, RESTRICT_UNFLAG);
1843}
1844
1845
1846/*
1847 * do_unrestrict - remove a restrict entry from the list
1848 */
1849static void
1850do_unrestrict(
1851	sockaddr_u *srcadr,
1852	struct interface *inter,
1853	struct req_pkt *inpkt
1854	)
1855{
1856	do_restrict(srcadr, inter, inpkt, RESTRICT_REMOVE);
1857}
1858
1859
1860/*
1861 * do_restrict - do the dirty stuff of dealing with restrictions
1862 */
1863static void
1864do_restrict(
1865	sockaddr_u *srcadr,
1866	struct interface *inter,
1867	struct req_pkt *inpkt,
1868	int op
1869	)
1870{
1871	register struct conf_restrict *cr;
1872	register int items;
1873	sockaddr_u matchaddr;
1874	sockaddr_u matchmask;
1875	int bad;
1876
1877	/*
1878	 * Do a check of the flags to make sure that only
1879	 * the NTPPORT flag is set, if any.  If not, complain
1880	 * about it.  Note we are very picky here.
1881	 */
1882	items = INFO_NITEMS(inpkt->err_nitems);
1883	cr = (struct conf_restrict *)inpkt->data;
1884
1885	bad = 0;
1886	cr->flags = ntohs(cr->flags);
1887	cr->mflags = ntohs(cr->mflags);
1888	while (items-- > 0 && !bad) {
1889		if (cr->mflags & ~(RESM_NTPONLY))
1890		    bad |= 1;
1891		if (cr->flags & ~(RES_ALLFLAGS))
1892		    bad |= 2;
1893		if (cr->mask != htonl(INADDR_ANY)) {
1894			if (client_v6_capable && cr->v6_flag != 0) {
1895				if (IN6_IS_ADDR_UNSPECIFIED(&cr->addr6))
1896					bad |= 4;
1897			} else
1898				if (cr->addr == htonl(INADDR_ANY))
1899					bad |= 8;
1900		}
1901		cr = (struct conf_restrict *)((char *)cr +
1902		    INFO_ITEMSIZE(inpkt->mbz_itemsize));
1903	}
1904
1905	if (bad) {
1906		msyslog(LOG_ERR, "do_restrict: bad = %#x", bad);
1907		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1908		return;
1909	}
1910
1911	/*
1912	 * Looks okay, try it out
1913	 */
1914	items = INFO_NITEMS(inpkt->err_nitems);
1915	cr = (struct conf_restrict *)inpkt->data;
1916	ZERO_SOCK(&matchaddr);
1917	ZERO_SOCK(&matchmask);
1918
1919	while (items-- > 0) {
1920		if (client_v6_capable && cr->v6_flag) {
1921			AF(&matchaddr) = AF_INET6;
1922			AF(&matchmask) = AF_INET6;
1923			SOCK_ADDR6(&matchaddr) = cr->addr6;
1924			SOCK_ADDR6(&matchmask) = cr->mask6;
1925		} else {
1926			AF(&matchaddr) = AF_INET;
1927			AF(&matchmask) = AF_INET;
1928			NSRCADR(&matchaddr) = cr->addr;
1929			NSRCADR(&matchmask) = cr->mask;
1930		}
1931		hack_restrict(op, &matchaddr, &matchmask, cr->mflags,
1932			 cr->flags);
1933		cr++;
1934	}
1935
1936	req_ack(srcadr, inter, inpkt, INFO_OKAY);
1937}
1938
1939
1940/*
1941 * mon_getlist - return monitor data
1942 */
1943static void
1944mon_getlist_0(
1945	sockaddr_u *srcadr,
1946	struct interface *inter,
1947	struct req_pkt *inpkt
1948	)
1949{
1950	register struct info_monitor *im;
1951	register struct mon_data *md;
1952	extern struct mon_data mon_mru_list;
1953	extern int mon_enabled;
1954
1955#ifdef DEBUG
1956	if (debug > 2)
1957	    printf("wants monitor 0 list\n");
1958#endif
1959	if (!mon_enabled) {
1960		req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1961		return;
1962	}
1963	im = (struct info_monitor *)prepare_pkt(srcadr, inter, inpkt,
1964	    v6sizeof(struct info_monitor));
1965	for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
1966	     md = md->mru_next) {
1967		im->lasttime = htonl((u_int32)((current_time -
1968		    md->firsttime) / md->count));
1969		im->firsttime = htonl((u_int32)(current_time - md->lasttime));
1970		im->restr = htonl((u_int32)md->flags);
1971		im->count = htonl((u_int32)(md->count));
1972		if (IS_IPV6(&md->rmtadr)) {
1973			if (!client_v6_capable)
1974				continue;
1975			im->addr6 = SOCK_ADDR6(&md->rmtadr);
1976			im->v6_flag = 1;
1977		} else {
1978			im->addr = NSRCADR(&md->rmtadr);
1979			if (client_v6_capable)
1980				im->v6_flag = 0;
1981		}
1982		im->port = md->rmtport;
1983		im->mode = md->mode;
1984		im->version = md->version;
1985		im = (struct info_monitor *)more_pkt();
1986	}
1987	flush_pkt();
1988}
1989
1990/*
1991 * mon_getlist - return monitor data
1992 */
1993static void
1994mon_getlist_1(
1995	sockaddr_u *srcadr,
1996	struct interface *inter,
1997	struct req_pkt *inpkt
1998	)
1999{
2000	register struct info_monitor_1 *im;
2001	register struct mon_data *md;
2002	extern struct mon_data mon_mru_list;
2003	extern int mon_enabled;
2004
2005	if (!mon_enabled) {
2006		req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2007		return;
2008	}
2009	im = (struct info_monitor_1 *)prepare_pkt(srcadr, inter, inpkt,
2010	    v6sizeof(struct info_monitor_1));
2011	for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
2012	     md = md->mru_next) {
2013		im->lasttime = htonl((u_int32)((current_time -
2014		    md->firsttime) / md->count));
2015		im->firsttime = htonl((u_int32)(current_time - md->lasttime));
2016		im->restr = htonl((u_int32)md->flags);
2017		im->count = htonl((u_int32)md->count);
2018		if (IS_IPV6(&md->rmtadr)) {
2019			if (!client_v6_capable)
2020				continue;
2021			im->addr6 = SOCK_ADDR6(&md->rmtadr);
2022			im->v6_flag = 1;
2023			im->daddr6 = SOCK_ADDR6(&md->interface->sin);
2024		} else {
2025			im->addr = NSRCADR(&md->rmtadr);
2026			if (client_v6_capable)
2027				im->v6_flag = 0;
2028			if (MDF_BCAST == md->cast_flags)
2029				im->daddr = NSRCADR(&md->interface->bcast);
2030			else if (md->cast_flags) {
2031				im->daddr = NSRCADR(&md->interface->sin);
2032				if (!im->daddr)
2033					im->daddr = NSRCADR(&md->interface->bcast);
2034			} else
2035				im->daddr = 4;
2036		}
2037		im->flags = htonl(md->cast_flags);
2038		im->port = md->rmtport;
2039		im->mode = md->mode;
2040		im->version = md->version;
2041		im = (struct info_monitor_1 *)more_pkt();
2042	}
2043	flush_pkt();
2044}
2045
2046/*
2047 * Module entry points and the flags they correspond with
2048 */
2049struct reset_entry {
2050	int flag;		/* flag this corresponds to */
2051	void (*handler) (void); /* routine to handle request */
2052};
2053
2054struct reset_entry reset_entries[] = {
2055	{ RESET_FLAG_ALLPEERS,	peer_all_reset },
2056	{ RESET_FLAG_IO,	io_clr_stats },
2057	{ RESET_FLAG_SYS,	proto_clr_stats },
2058	{ RESET_FLAG_MEM,	peer_clr_stats },
2059	{ RESET_FLAG_TIMER,	timer_clr_stats },
2060	{ RESET_FLAG_AUTH,	reset_auth_stats },
2061	{ RESET_FLAG_CTL,	ctl_clr_stats },
2062	{ 0,			0 }
2063};
2064
2065/*
2066 * reset_stats - reset statistic counters here and there
2067 */
2068static void
2069reset_stats(
2070	sockaddr_u *srcadr,
2071	struct interface *inter,
2072	struct req_pkt *inpkt
2073	)
2074{
2075	struct reset_flags *rflags;
2076	u_long flags;
2077	struct reset_entry *rent;
2078
2079	if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2080		msyslog(LOG_ERR, "reset_stats: err_nitems > 1");
2081		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2082		return;
2083	}
2084
2085	rflags = (struct reset_flags *)inpkt->data;
2086	flags = ntohl(rflags->flags);
2087
2088	if (flags & ~RESET_ALLFLAGS) {
2089		msyslog(LOG_ERR, "reset_stats: reset leaves %#lx",
2090			flags & ~RESET_ALLFLAGS);
2091		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2092		return;
2093	}
2094
2095	for (rent = reset_entries; rent->flag != 0; rent++) {
2096		if (flags & rent->flag)
2097			(*rent->handler)();
2098	}
2099	req_ack(srcadr, inter, inpkt, INFO_OKAY);
2100}
2101
2102
2103/*
2104 * reset_peer - clear a peer's statistics
2105 */
2106static void
2107reset_peer(
2108	sockaddr_u *srcadr,
2109	struct interface *inter,
2110	struct req_pkt *inpkt
2111	)
2112{
2113	struct conf_unpeer *cp;
2114	int items;
2115	struct peer *peer;
2116	sockaddr_u peeraddr;
2117	int bad;
2118
2119	/*
2120	 * We check first to see that every peer exists.  If not,
2121	 * we return an error.
2122	 */
2123
2124	items = INFO_NITEMS(inpkt->err_nitems);
2125	cp = (struct conf_unpeer *)inpkt->data;
2126
2127	bad = 0;
2128	while (items-- > 0 && !bad) {
2129		ZERO_SOCK(&peeraddr);
2130		if (client_v6_capable && cp->v6_flag) {
2131			AF(&peeraddr) = AF_INET6;
2132			SOCK_ADDR6(&peeraddr) = cp->peeraddr6;
2133		} else {
2134			AF(&peeraddr) = AF_INET;
2135			NSRCADR(&peeraddr) = cp->peeraddr;
2136		}
2137
2138#ifdef ISC_PLATFORM_HAVESALEN
2139		peeraddr.sa.sa_len = SOCKLEN(&peeraddr);
2140#endif
2141		peer = findexistingpeer(&peeraddr, NULL, -1, 0);
2142		if (NULL == peer)
2143			bad++;
2144		cp = (struct conf_unpeer *)((char *)cp +
2145		    INFO_ITEMSIZE(inpkt->mbz_itemsize));
2146	}
2147
2148	if (bad) {
2149		req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2150		return;
2151	}
2152
2153	/*
2154	 * Now do it in earnest.
2155	 */
2156
2157	items = INFO_NITEMS(inpkt->err_nitems);
2158	cp = (struct conf_unpeer *)inpkt->data;
2159	while (items-- > 0) {
2160		ZERO_SOCK(&peeraddr);
2161		if (client_v6_capable && cp->v6_flag) {
2162			AF(&peeraddr) = AF_INET6;
2163			SOCK_ADDR6(&peeraddr) = cp->peeraddr6;
2164		} else {
2165			AF(&peeraddr) = AF_INET;
2166			NSRCADR(&peeraddr) = cp->peeraddr;
2167		}
2168		SET_PORT(&peeraddr, 123);
2169#ifdef ISC_PLATFORM_HAVESALEN
2170		peeraddr.sa.sa_len = SOCKLEN(&peeraddr);
2171#endif
2172		peer = findexistingpeer(&peeraddr, NULL, -1, 0);
2173		while (peer != NULL) {
2174			peer_reset(peer);
2175			peer = findexistingpeer(&peeraddr, peer, -1, 0);
2176		}
2177		cp = (struct conf_unpeer *)((char *)cp +
2178		    INFO_ITEMSIZE(inpkt->mbz_itemsize));
2179	}
2180
2181	req_ack(srcadr, inter, inpkt, INFO_OKAY);
2182}
2183
2184
2185/*
2186 * do_key_reread - reread the encryption key file
2187 */
2188static void
2189do_key_reread(
2190	sockaddr_u *srcadr,
2191	struct interface *inter,
2192	struct req_pkt *inpkt
2193	)
2194{
2195	rereadkeys();
2196	req_ack(srcadr, inter, inpkt, INFO_OKAY);
2197}
2198
2199
2200/*
2201 * trust_key - make one or more keys trusted
2202 */
2203static void
2204trust_key(
2205	sockaddr_u *srcadr,
2206	struct interface *inter,
2207	struct req_pkt *inpkt
2208	)
2209{
2210	do_trustkey(srcadr, inter, inpkt, 1);
2211}
2212
2213
2214/*
2215 * untrust_key - make one or more keys untrusted
2216 */
2217static void
2218untrust_key(
2219	sockaddr_u *srcadr,
2220	struct interface *inter,
2221	struct req_pkt *inpkt
2222	)
2223{
2224	do_trustkey(srcadr, inter, inpkt, 0);
2225}
2226
2227
2228/*
2229 * do_trustkey - make keys either trustable or untrustable
2230 */
2231static void
2232do_trustkey(
2233	sockaddr_u *srcadr,
2234	struct interface *inter,
2235	struct req_pkt *inpkt,
2236	u_long trust
2237	)
2238{
2239	register u_long *kp;
2240	register int items;
2241
2242	items = INFO_NITEMS(inpkt->err_nitems);
2243	kp = (u_long *)inpkt->data;
2244	while (items-- > 0) {
2245		authtrust(*kp, trust);
2246		kp++;
2247	}
2248
2249	req_ack(srcadr, inter, inpkt, INFO_OKAY);
2250}
2251
2252
2253/*
2254 * get_auth_info - return some stats concerning the authentication module
2255 */
2256static void
2257get_auth_info(
2258	sockaddr_u *srcadr,
2259	struct interface *inter,
2260	struct req_pkt *inpkt
2261	)
2262{
2263	register struct info_auth *ia;
2264
2265	/*
2266	 * Importations from the authentication module
2267	 */
2268	extern u_long authnumkeys;
2269	extern int authnumfreekeys;
2270	extern u_long authkeylookups;
2271	extern u_long authkeynotfound;
2272	extern u_long authencryptions;
2273	extern u_long authdecryptions;
2274	extern u_long authkeyuncached;
2275	extern u_long authkeyexpired;
2276
2277	ia = (struct info_auth *)prepare_pkt(srcadr, inter, inpkt,
2278					     sizeof(struct info_auth));
2279
2280	ia->numkeys = htonl((u_int32)authnumkeys);
2281	ia->numfreekeys = htonl((u_int32)authnumfreekeys);
2282	ia->keylookups = htonl((u_int32)authkeylookups);
2283	ia->keynotfound = htonl((u_int32)authkeynotfound);
2284	ia->encryptions = htonl((u_int32)authencryptions);
2285	ia->decryptions = htonl((u_int32)authdecryptions);
2286	ia->keyuncached = htonl((u_int32)authkeyuncached);
2287	ia->expired = htonl((u_int32)authkeyexpired);
2288	ia->timereset = htonl((u_int32)(current_time - auth_timereset));
2289
2290	(void) more_pkt();
2291	flush_pkt();
2292}
2293
2294
2295
2296/*
2297 * reset_auth_stats - reset the authentication stat counters.  Done here
2298 *		      to keep ntp-isms out of the authentication module
2299 */
2300static void
2301reset_auth_stats(void)
2302{
2303	/*
2304	 * Importations from the authentication module
2305	 */
2306	extern u_long authkeylookups;
2307	extern u_long authkeynotfound;
2308	extern u_long authencryptions;
2309	extern u_long authdecryptions;
2310	extern u_long authkeyuncached;
2311
2312	authkeylookups = 0;
2313	authkeynotfound = 0;
2314	authencryptions = 0;
2315	authdecryptions = 0;
2316	authkeyuncached = 0;
2317	auth_timereset = current_time;
2318}
2319
2320
2321/*
2322 * req_get_traps - return information about current trap holders
2323 */
2324static void
2325req_get_traps(
2326	sockaddr_u *srcadr,
2327	struct interface *inter,
2328	struct req_pkt *inpkt
2329	)
2330{
2331	register struct info_trap *it;
2332	register struct ctl_trap *tr;
2333	register int i;
2334
2335	/*
2336	 * Imported from the control module
2337	 */
2338	extern struct ctl_trap ctl_trap[];
2339	extern int num_ctl_traps;
2340
2341	if (num_ctl_traps == 0) {
2342		req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2343		return;
2344	}
2345
2346	it = (struct info_trap *)prepare_pkt(srcadr, inter, inpkt,
2347	    v6sizeof(struct info_trap));
2348
2349	for (i = 0, tr = ctl_trap; i < CTL_MAXTRAPS; i++, tr++) {
2350		if (tr->tr_flags & TRAP_INUSE) {
2351			if (IS_IPV4(&tr->tr_addr)) {
2352				if (tr->tr_localaddr == any_interface)
2353					it->local_address = 0;
2354				else
2355					it->local_address
2356					    = NSRCADR(&tr->tr_localaddr->sin);
2357				it->trap_address = NSRCADR(&tr->tr_addr);
2358				if (client_v6_capable)
2359					it->v6_flag = 0;
2360			} else {
2361				if (!client_v6_capable)
2362					continue;
2363				it->local_address6
2364				    = SOCK_ADDR6(&tr->tr_localaddr->sin);
2365				it->trap_address6 = SOCK_ADDR6(&tr->tr_addr);
2366				it->v6_flag = 1;
2367			}
2368			it->trap_port = NSRCPORT(&tr->tr_addr);
2369			it->sequence = htons(tr->tr_sequence);
2370			it->settime = htonl((u_int32)(current_time - tr->tr_settime));
2371			it->origtime = htonl((u_int32)(current_time - tr->tr_origtime));
2372			it->resets = htonl((u_int32)tr->tr_resets);
2373			it->flags = htonl((u_int32)tr->tr_flags);
2374			it = (struct info_trap *)more_pkt();
2375		}
2376	}
2377	flush_pkt();
2378}
2379
2380
2381/*
2382 * req_set_trap - configure a trap
2383 */
2384static void
2385req_set_trap(
2386	sockaddr_u *srcadr,
2387	struct interface *inter,
2388	struct req_pkt *inpkt
2389	)
2390{
2391	do_setclr_trap(srcadr, inter, inpkt, 1);
2392}
2393
2394
2395
2396/*
2397 * req_clr_trap - unconfigure a trap
2398 */
2399static void
2400req_clr_trap(
2401	sockaddr_u *srcadr,
2402	struct interface *inter,
2403	struct req_pkt *inpkt
2404	)
2405{
2406	do_setclr_trap(srcadr, inter, inpkt, 0);
2407}
2408
2409
2410
2411/*
2412 * do_setclr_trap - do the grunge work of (un)configuring a trap
2413 */
2414static void
2415do_setclr_trap(
2416	sockaddr_u *srcadr,
2417	struct interface *inter,
2418	struct req_pkt *inpkt,
2419	int set
2420	)
2421{
2422	register struct conf_trap *ct;
2423	register struct interface *linter;
2424	int res;
2425	sockaddr_u laddr;
2426
2427	/*
2428	 * Prepare sockaddr
2429	 */
2430	ZERO_SOCK(&laddr);
2431	AF(&laddr) = AF(srcadr);
2432	SET_PORT(&laddr, NTP_PORT);
2433
2434	/*
2435	 * Restrict ourselves to one item only.  This eliminates
2436	 * the error reporting problem.
2437	 */
2438	if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2439		msyslog(LOG_ERR, "do_setclr_trap: err_nitems > 1");
2440		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2441		return;
2442	}
2443	ct = (struct conf_trap *)inpkt->data;
2444
2445	/*
2446	 * Look for the local interface.  If none, use the default.
2447	 */
2448	if (ct->local_address == 0) {
2449		linter = any_interface;
2450	} else {
2451		if (IS_IPV4(&laddr))
2452			NSRCADR(&laddr) = ct->local_address;
2453		else
2454			SOCK_ADDR6(&laddr) = ct->local_address6;
2455		linter = findinterface(&laddr);
2456		if (NULL == linter) {
2457			req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2458			return;
2459		}
2460	}
2461
2462	if (IS_IPV4(&laddr))
2463		NSRCADR(&laddr) = ct->trap_address;
2464	else
2465		SOCK_ADDR6(&laddr) = ct->trap_address6;
2466	if (ct->trap_port)
2467		NSRCPORT(&laddr) = ct->trap_port;
2468	else
2469		SET_PORT(&laddr, TRAPPORT);
2470
2471	if (set) {
2472		res = ctlsettrap(&laddr, linter, 0,
2473				 INFO_VERSION(inpkt->rm_vn_mode));
2474	} else {
2475		res = ctlclrtrap(&laddr, linter, 0);
2476	}
2477
2478	if (!res) {
2479		req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2480	} else {
2481		req_ack(srcadr, inter, inpkt, INFO_OKAY);
2482	}
2483	return;
2484}
2485
2486
2487
2488/*
2489 * set_request_keyid - set the keyid used to authenticate requests
2490 */
2491static void
2492set_request_keyid(
2493	sockaddr_u *srcadr,
2494	struct interface *inter,
2495	struct req_pkt *inpkt
2496	)
2497{
2498	keyid_t *pkeyid;
2499
2500	/*
2501	 * Restrict ourselves to one item only.
2502	 */
2503	if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2504		msyslog(LOG_ERR, "set_request_keyid: err_nitems > 1");
2505		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2506		return;
2507	}
2508
2509	pkeyid = (keyid_t *)inpkt->data;
2510	info_auth_keyid = ntohl(*pkeyid);
2511	req_ack(srcadr, inter, inpkt, INFO_OKAY);
2512}
2513
2514
2515
2516/*
2517 * set_control_keyid - set the keyid used to authenticate requests
2518 */
2519static void
2520set_control_keyid(
2521	sockaddr_u *srcadr,
2522	struct interface *inter,
2523	struct req_pkt *inpkt
2524	)
2525{
2526	keyid_t *pkeyid;
2527	extern keyid_t ctl_auth_keyid;
2528
2529	/*
2530	 * Restrict ourselves to one item only.
2531	 */
2532	if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2533		msyslog(LOG_ERR, "set_control_keyid: err_nitems > 1");
2534		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2535		return;
2536	}
2537
2538	pkeyid = (keyid_t *)inpkt->data;
2539	ctl_auth_keyid = ntohl(*pkeyid);
2540	req_ack(srcadr, inter, inpkt, INFO_OKAY);
2541}
2542
2543
2544
2545/*
2546 * get_ctl_stats - return some stats concerning the control message module
2547 */
2548static void
2549get_ctl_stats(
2550	sockaddr_u *srcadr,
2551	struct interface *inter,
2552	struct req_pkt *inpkt
2553	)
2554{
2555	register struct info_control *ic;
2556
2557	/*
2558	 * Importations from the control module
2559	 */
2560	extern u_long ctltimereset;
2561	extern u_long numctlreq;
2562	extern u_long numctlbadpkts;
2563	extern u_long numctlresponses;
2564	extern u_long numctlfrags;
2565	extern u_long numctlerrors;
2566	extern u_long numctltooshort;
2567	extern u_long numctlinputresp;
2568	extern u_long numctlinputfrag;
2569	extern u_long numctlinputerr;
2570	extern u_long numctlbadoffset;
2571	extern u_long numctlbadversion;
2572	extern u_long numctldatatooshort;
2573	extern u_long numctlbadop;
2574	extern u_long numasyncmsgs;
2575
2576	ic = (struct info_control *)prepare_pkt(srcadr, inter, inpkt,
2577						sizeof(struct info_control));
2578
2579	ic->ctltimereset = htonl((u_int32)(current_time - ctltimereset));
2580	ic->numctlreq = htonl((u_int32)numctlreq);
2581	ic->numctlbadpkts = htonl((u_int32)numctlbadpkts);
2582	ic->numctlresponses = htonl((u_int32)numctlresponses);
2583	ic->numctlfrags = htonl((u_int32)numctlfrags);
2584	ic->numctlerrors = htonl((u_int32)numctlerrors);
2585	ic->numctltooshort = htonl((u_int32)numctltooshort);
2586	ic->numctlinputresp = htonl((u_int32)numctlinputresp);
2587	ic->numctlinputfrag = htonl((u_int32)numctlinputfrag);
2588	ic->numctlinputerr = htonl((u_int32)numctlinputerr);
2589	ic->numctlbadoffset = htonl((u_int32)numctlbadoffset);
2590	ic->numctlbadversion = htonl((u_int32)numctlbadversion);
2591	ic->numctldatatooshort = htonl((u_int32)numctldatatooshort);
2592	ic->numctlbadop = htonl((u_int32)numctlbadop);
2593	ic->numasyncmsgs = htonl((u_int32)numasyncmsgs);
2594
2595	(void) more_pkt();
2596	flush_pkt();
2597}
2598
2599
2600#ifdef KERNEL_PLL
2601/*
2602 * get_kernel_info - get kernel pll/pps information
2603 */
2604static void
2605get_kernel_info(
2606	sockaddr_u *srcadr,
2607	struct interface *inter,
2608	struct req_pkt *inpkt
2609	)
2610{
2611	register struct info_kernel *ik;
2612	struct timex ntx;
2613
2614	if (!pll_control) {
2615		req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2616		return;
2617	}
2618
2619	memset((char *)&ntx, 0, sizeof(ntx));
2620	if (ntp_adjtime(&ntx) < 0)
2621		msyslog(LOG_ERR, "get_kernel_info: ntp_adjtime() failed: %m");
2622	ik = (struct info_kernel *)prepare_pkt(srcadr, inter, inpkt,
2623	    sizeof(struct info_kernel));
2624
2625	/*
2626	 * pll variables
2627	 */
2628	ik->offset = htonl((u_int32)ntx.offset);
2629	ik->freq = htonl((u_int32)ntx.freq);
2630	ik->maxerror = htonl((u_int32)ntx.maxerror);
2631	ik->esterror = htonl((u_int32)ntx.esterror);
2632	ik->status = htons(ntx.status);
2633	ik->constant = htonl((u_int32)ntx.constant);
2634	ik->precision = htonl((u_int32)ntx.precision);
2635	ik->tolerance = htonl((u_int32)ntx.tolerance);
2636
2637	/*
2638	 * pps variables
2639	 */
2640	ik->ppsfreq = htonl((u_int32)ntx.ppsfreq);
2641	ik->jitter = htonl((u_int32)ntx.jitter);
2642	ik->shift = htons(ntx.shift);
2643	ik->stabil = htonl((u_int32)ntx.stabil);
2644	ik->jitcnt = htonl((u_int32)ntx.jitcnt);
2645	ik->calcnt = htonl((u_int32)ntx.calcnt);
2646	ik->errcnt = htonl((u_int32)ntx.errcnt);
2647	ik->stbcnt = htonl((u_int32)ntx.stbcnt);
2648
2649	(void) more_pkt();
2650	flush_pkt();
2651}
2652#endif /* KERNEL_PLL */
2653
2654
2655#ifdef REFCLOCK
2656/*
2657 * get_clock_info - get info about a clock
2658 */
2659static void
2660get_clock_info(
2661	sockaddr_u *srcadr,
2662	struct interface *inter,
2663	struct req_pkt *inpkt
2664	)
2665{
2666	register struct info_clock *ic;
2667	register u_int32 *clkaddr;
2668	register int items;
2669	struct refclockstat clock_stat;
2670	sockaddr_u addr;
2671	l_fp ltmp;
2672
2673	ZERO_SOCK(&addr);
2674	AF(&addr) = AF_INET;
2675#ifdef ISC_PLATFORM_HAVESALEN
2676	addr.sa.sa_len = SOCKLEN(&addr);
2677#endif
2678	SET_PORT(&addr, NTP_PORT);
2679	items = INFO_NITEMS(inpkt->err_nitems);
2680	clkaddr = (u_int32 *) inpkt->data;
2681
2682	ic = (struct info_clock *)prepare_pkt(srcadr, inter, inpkt,
2683					      sizeof(struct info_clock));
2684
2685	while (items-- > 0) {
2686		NSRCADR(&addr) = *clkaddr++;
2687		if (!ISREFCLOCKADR(&addr) ||
2688		    findexistingpeer(&addr, NULL, -1, 0) == NULL) {
2689			req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2690			return;
2691		}
2692
2693		clock_stat.kv_list = (struct ctl_var *)0;
2694
2695		refclock_control(&addr, NULL, &clock_stat);
2696
2697		ic->clockadr = NSRCADR(&addr);
2698		ic->type = clock_stat.type;
2699		ic->flags = clock_stat.flags;
2700		ic->lastevent = clock_stat.lastevent;
2701		ic->currentstatus = clock_stat.currentstatus;
2702		ic->polls = htonl((u_int32)clock_stat.polls);
2703		ic->noresponse = htonl((u_int32)clock_stat.noresponse);
2704		ic->badformat = htonl((u_int32)clock_stat.badformat);
2705		ic->baddata = htonl((u_int32)clock_stat.baddata);
2706		ic->timestarted = htonl((u_int32)clock_stat.timereset);
2707		DTOLFP(clock_stat.fudgetime1, &ltmp);
2708		HTONL_FP(&ltmp, &ic->fudgetime1);
2709		DTOLFP(clock_stat.fudgetime2, &ltmp);
2710		HTONL_FP(&ltmp, &ic->fudgetime2);
2711		ic->fudgeval1 = htonl((u_int32)clock_stat.fudgeval1);
2712		ic->fudgeval2 = htonl(clock_stat.fudgeval2);
2713
2714		free_varlist(clock_stat.kv_list);
2715
2716		ic = (struct info_clock *)more_pkt();
2717	}
2718	flush_pkt();
2719}
2720
2721
2722
2723/*
2724 * set_clock_fudge - get a clock's fudge factors
2725 */
2726static void
2727set_clock_fudge(
2728	sockaddr_u *srcadr,
2729	struct interface *inter,
2730	struct req_pkt *inpkt
2731	)
2732{
2733	register struct conf_fudge *cf;
2734	register int items;
2735	struct refclockstat clock_stat;
2736	sockaddr_u addr;
2737	l_fp ltmp;
2738
2739	ZERO_SOCK(&addr);
2740	memset((char *)&clock_stat, 0, sizeof clock_stat);
2741	items = INFO_NITEMS(inpkt->err_nitems);
2742	cf = (struct conf_fudge *) inpkt->data;
2743
2744	while (items-- > 0) {
2745		AF(&addr) = AF_INET;
2746		NSRCADR(&addr) = cf->clockadr;
2747#ifdef ISC_PLATFORM_HAVESALEN
2748		addr.sa.sa_len = SOCKLEN(&addr);
2749#endif
2750		SET_PORT(&addr, NTP_PORT);
2751		if (!ISREFCLOCKADR(&addr) ||
2752		    findexistingpeer(&addr, NULL, -1, 0) == 0) {
2753			req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2754			return;
2755		}
2756
2757		switch(ntohl(cf->which)) {
2758		    case FUDGE_TIME1:
2759			NTOHL_FP(&cf->fudgetime, &ltmp);
2760			LFPTOD(&ltmp, clock_stat.fudgetime1);
2761			clock_stat.haveflags = CLK_HAVETIME1;
2762			break;
2763		    case FUDGE_TIME2:
2764			NTOHL_FP(&cf->fudgetime, &ltmp);
2765			LFPTOD(&ltmp, clock_stat.fudgetime2);
2766			clock_stat.haveflags = CLK_HAVETIME2;
2767			break;
2768		    case FUDGE_VAL1:
2769			clock_stat.fudgeval1 = ntohl(cf->fudgeval_flags);
2770			clock_stat.haveflags = CLK_HAVEVAL1;
2771			break;
2772		    case FUDGE_VAL2:
2773			clock_stat.fudgeval2 = ntohl(cf->fudgeval_flags);
2774			clock_stat.haveflags = CLK_HAVEVAL2;
2775			break;
2776		    case FUDGE_FLAGS:
2777			clock_stat.flags = (u_char) (ntohl(cf->fudgeval_flags) & 0xf);
2778			clock_stat.haveflags =
2779				(CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4);
2780			break;
2781		    default:
2782			msyslog(LOG_ERR, "set_clock_fudge: default!");
2783			req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2784			return;
2785		}
2786
2787		refclock_control(&addr, &clock_stat, (struct refclockstat *)0);
2788	}
2789
2790	req_ack(srcadr, inter, inpkt, INFO_OKAY);
2791}
2792#endif
2793
2794#ifdef REFCLOCK
2795/*
2796 * get_clkbug_info - get debugging info about a clock
2797 */
2798static void
2799get_clkbug_info(
2800	sockaddr_u *srcadr,
2801	struct interface *inter,
2802	struct req_pkt *inpkt
2803	)
2804{
2805	register int i;
2806	register struct info_clkbug *ic;
2807	register u_int32 *clkaddr;
2808	register int items;
2809	struct refclockbug bug;
2810	sockaddr_u addr;
2811
2812	ZERO_SOCK(&addr);
2813	AF(&addr) = AF_INET;
2814#ifdef ISC_PLATFORM_HAVESALEN
2815	addr.sa.sa_len = SOCKLEN(&addr);
2816#endif
2817	SET_PORT(&addr, NTP_PORT);
2818	items = INFO_NITEMS(inpkt->err_nitems);
2819	clkaddr = (u_int32 *) inpkt->data;
2820
2821	ic = (struct info_clkbug *)prepare_pkt(srcadr, inter, inpkt,
2822					       sizeof(struct info_clkbug));
2823
2824	while (items-- > 0) {
2825		NSRCADR(&addr) = *clkaddr++;
2826		if (!ISREFCLOCKADR(&addr) ||
2827		    findexistingpeer(&addr, NULL, -1, 0) == 0) {
2828			req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2829			return;
2830		}
2831
2832		memset((char *)&bug, 0, sizeof bug);
2833		refclock_buginfo(&addr, &bug);
2834		if (bug.nvalues == 0 && bug.ntimes == 0) {
2835			req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2836			return;
2837		}
2838
2839		ic->clockadr = NSRCADR(&addr);
2840		i = bug.nvalues;
2841		if (i > NUMCBUGVALUES)
2842		    i = NUMCBUGVALUES;
2843		ic->nvalues = (u_char)i;
2844		ic->svalues = htons((u_short) (bug.svalues & ((1<<i)-1)));
2845		while (--i >= 0)
2846		    ic->values[i] = htonl(bug.values[i]);
2847
2848		i = bug.ntimes;
2849		if (i > NUMCBUGTIMES)
2850		    i = NUMCBUGTIMES;
2851		ic->ntimes = (u_char)i;
2852		ic->stimes = htonl(bug.stimes);
2853		while (--i >= 0) {
2854			HTONL_FP(&bug.times[i], &ic->times[i]);
2855		}
2856
2857		ic = (struct info_clkbug *)more_pkt();
2858	}
2859	flush_pkt();
2860}
2861#endif
2862
2863/*
2864 * receiver of interface structures
2865 */
2866static void
2867fill_info_if_stats(void *data, interface_info_t *interface_info)
2868{
2869	struct info_if_stats **ifsp = (struct info_if_stats **)data;
2870	struct info_if_stats *ifs = *ifsp;
2871	endpt *ep = interface_info->ep;
2872
2873	memset(ifs, 0, sizeof(*ifs));
2874
2875	if (IS_IPV6(&ep->sin)) {
2876		if (!client_v6_capable) {
2877			return;
2878		}
2879		ifs->v6_flag = 1;
2880		ifs->unaddr.addr6 = SOCK_ADDR6(&ep->sin);
2881		ifs->unbcast.addr6 = SOCK_ADDR6(&ep->bcast);
2882		ifs->unmask.addr6 = SOCK_ADDR6(&ep->mask);
2883	} else {
2884		ifs->v6_flag = 0;
2885		ifs->unaddr.addr = SOCK_ADDR4(&ep->sin);
2886		ifs->unbcast.addr = SOCK_ADDR4(&ep->bcast);
2887		ifs->unmask.addr = SOCK_ADDR4(&ep->mask);
2888	}
2889	ifs->v6_flag = htonl(ifs->v6_flag);
2890	strncpy(ifs->name, ep->name, sizeof(ifs->name));
2891	ifs->family = htons(ep->family);
2892	ifs->flags = htonl(ep->flags);
2893	ifs->last_ttl = htonl(ep->last_ttl);
2894	ifs->num_mcast = htonl(ep->num_mcast);
2895	ifs->received = htonl(ep->received);
2896	ifs->sent = htonl(ep->sent);
2897	ifs->notsent = htonl(ep->notsent);
2898	ifs->ifindex = htonl(ep->ifindex);
2899	/* scope no longer in struct interface, in in6_addr typically */
2900	ifs->scopeid = ifs->ifindex;
2901	ifs->ifnum = htonl(ep->ifnum);
2902	ifs->uptime = htonl(current_time - ep->starttime);
2903	ifs->ignore_packets = ep->ignore_packets;
2904	ifs->peercnt = htonl(ep->peercnt);
2905	ifs->action = interface_info->action;
2906
2907	*ifsp = (struct info_if_stats *)more_pkt();
2908}
2909
2910/*
2911 * get_if_stats - get interface statistics
2912 */
2913static void
2914get_if_stats(
2915	sockaddr_u *srcadr,
2916	struct interface *inter,
2917	struct req_pkt *inpkt
2918	)
2919{
2920	struct info_if_stats *ifs;
2921
2922	DPRINTF(3, ("wants interface statistics\n"));
2923
2924	ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt,
2925	    v6sizeof(struct info_if_stats));
2926
2927	interface_enumerate(fill_info_if_stats, &ifs);
2928
2929	flush_pkt();
2930}
2931
2932static void
2933do_if_reload(
2934	sockaddr_u *srcadr,
2935	struct interface *inter,
2936	struct req_pkt *inpkt
2937	)
2938{
2939	struct info_if_stats *ifs;
2940
2941	DPRINTF(3, ("wants interface reload\n"));
2942
2943	ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt,
2944	    v6sizeof(struct info_if_stats));
2945
2946	interface_update(fill_info_if_stats, &ifs);
2947
2948	flush_pkt();
2949}
2950
2951