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