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