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