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