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