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