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