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