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