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