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