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