Sync usage with man page.
[netbsd-mini2440.git] / dist / ntp / ntpd / ntp_request.c
blob1a1684edbaaa81e7d199184d992ba9ba2858ca88
1 /* $NetBSD: ntp_request.c,v 1.1.1.8 2009/12/08 20:43:48 kardel Exp $ */
3 /*
4 * ntp_request.c - respond to information requests
5 */
7 #ifdef HAVE_CONFIG_H
8 # include <config.h>
9 #endif
11 #include "ntpd.h"
12 #include "ntp_io.h"
13 #include "ntp_request.h"
14 #include "ntp_control.h"
15 #include "ntp_refclock.h"
16 #include "ntp_if.h"
17 #include "ntp_stdlib.h"
19 #include <stdio.h>
20 #include <stddef.h>
21 #include <signal.h>
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
25 #include "recvbuff.h"
27 #ifdef KERNEL_PLL
28 #include "ntp_syscall.h"
29 #endif /* KERNEL_PLL */
32 * Structure to hold request procedure information
34 #define NOAUTH 0
35 #define AUTH 1
37 #define NO_REQUEST (-1)
39 * Because we now have v6 addresses in the messages, we need to compensate
40 * for the larger size. Therefore, we introduce the alternate size to
41 * keep us friendly with older implementations. A little ugly.
43 static int client_v6_capable = 0; /* the client can handle longer messages */
45 #define v6sizeof(type) (client_v6_capable ? sizeof(type) : v4sizeof(type))
47 struct req_proc {
48 short request_code; /* defined request code */
49 short needs_auth; /* true when authentication needed */
50 short sizeofitem; /* size of request data item (older size)*/
51 short v6_sizeofitem; /* size of request data item (new size)*/
52 void (*handler) P((struct sockaddr_storage *, struct interface *,
53 struct req_pkt *)); /* routine to handle request */
57 * Universal request codes
59 static struct req_proc univ_codes[] = {
60 { NO_REQUEST, NOAUTH, 0, 0 }
63 static void req_ack P((struct sockaddr_storage *, struct interface *, struct req_pkt *, int));
64 static char * prepare_pkt P((struct sockaddr_storage *, struct interface *, struct req_pkt *, u_int));
65 static char * more_pkt P((void));
66 static void flush_pkt P((void));
67 static void peer_list P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
68 static void peer_list_sum P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
69 static void peer_info P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
70 static void peer_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
71 static void sys_info P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
72 static void sys_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
73 static void mem_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
74 static void io_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
75 static void timer_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
76 static void loop_info P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
77 static void do_conf P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
78 static void do_unconf P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
79 static void set_sys_flag P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
80 static void clr_sys_flag P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
81 static void setclr_flags P((struct sockaddr_storage *, struct interface *, struct req_pkt *, u_long));
82 static void list_restrict P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
83 static void do_resaddflags P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
84 static void do_ressubflags P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
85 static void do_unrestrict P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
86 static void do_restrict P((struct sockaddr_storage *, struct interface *, struct req_pkt *, int));
87 static void mon_getlist_0 P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
88 static void mon_getlist_1 P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
89 static void reset_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
90 static void reset_peer P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
91 static void do_key_reread P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
92 static void trust_key P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
93 static void untrust_key P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
94 static void do_trustkey P((struct sockaddr_storage *, struct interface *, struct req_pkt *, u_long));
95 static void get_auth_info P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
96 static void reset_auth_stats P((void));
97 static void req_get_traps P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
98 static void req_set_trap P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
99 static void req_clr_trap P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
100 static void do_setclr_trap P((struct sockaddr_storage *, struct interface *, struct req_pkt *, int));
101 static void set_request_keyid P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
102 static void set_control_keyid P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
103 static void get_ctl_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
104 static void get_if_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
105 static void do_if_reload P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
106 #ifdef KERNEL_PLL
107 static void get_kernel_info P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
108 #endif /* KERNEL_PLL */
109 #ifdef REFCLOCK
110 static void get_clock_info P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
111 static void set_clock_fudge P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
112 #endif /* REFCLOCK */
113 #ifdef REFCLOCK
114 static void get_clkbug_info P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
115 #endif /* REFCLOCK */
118 * ntpd request codes
120 static struct req_proc ntp_codes[] = {
121 { REQ_PEER_LIST, NOAUTH, 0, 0, peer_list },
122 { REQ_PEER_LIST_SUM, NOAUTH, 0, 0, peer_list_sum },
123 { REQ_PEER_INFO, NOAUTH, v4sizeof(struct info_peer_list),
124 sizeof(struct info_peer_list), peer_info},
125 { REQ_PEER_STATS, NOAUTH, v4sizeof(struct info_peer_list),
126 sizeof(struct info_peer_list), peer_stats},
127 { REQ_SYS_INFO, NOAUTH, 0, 0, sys_info },
128 { REQ_SYS_STATS, NOAUTH, 0, 0, sys_stats },
129 { REQ_IO_STATS, NOAUTH, 0, 0, io_stats },
130 { REQ_MEM_STATS, NOAUTH, 0, 0, mem_stats },
131 { REQ_LOOP_INFO, NOAUTH, 0, 0, loop_info },
132 { REQ_TIMER_STATS, NOAUTH, 0, 0, timer_stats },
133 { REQ_CONFIG, AUTH, v4sizeof(struct conf_peer),
134 sizeof(struct conf_peer), do_conf },
135 { REQ_UNCONFIG, AUTH, v4sizeof(struct conf_unpeer),
136 sizeof(struct conf_unpeer), do_unconf },
137 { REQ_SET_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags),
138 sizeof(struct conf_sys_flags), set_sys_flag },
139 { REQ_CLR_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags),
140 sizeof(struct conf_sys_flags), clr_sys_flag },
141 { REQ_GET_RESTRICT, NOAUTH, 0, 0, list_restrict },
142 { REQ_RESADDFLAGS, AUTH, v4sizeof(struct conf_restrict),
143 sizeof(struct conf_restrict), do_resaddflags },
144 { REQ_RESSUBFLAGS, AUTH, v4sizeof(struct conf_restrict),
145 sizeof(struct conf_restrict), do_ressubflags },
146 { REQ_UNRESTRICT, AUTH, v4sizeof(struct conf_restrict),
147 sizeof(struct conf_restrict), do_unrestrict },
148 { REQ_MON_GETLIST, NOAUTH, 0, 0, mon_getlist_0 },
149 { REQ_MON_GETLIST_1, NOAUTH, 0, 0, mon_getlist_1 },
150 { REQ_RESET_STATS, AUTH, sizeof(struct reset_flags), 0, reset_stats },
151 { REQ_RESET_PEER, AUTH, v4sizeof(struct conf_unpeer),
152 sizeof(struct conf_unpeer), reset_peer },
153 { REQ_REREAD_KEYS, AUTH, 0, 0, do_key_reread },
154 { REQ_TRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), trust_key },
155 { REQ_UNTRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), untrust_key },
156 { REQ_AUTHINFO, NOAUTH, 0, 0, get_auth_info },
157 { REQ_TRAPS, NOAUTH, 0, 0, req_get_traps },
158 { REQ_ADD_TRAP, AUTH, v4sizeof(struct conf_trap),
159 sizeof(struct conf_trap), req_set_trap },
160 { REQ_CLR_TRAP, AUTH, v4sizeof(struct conf_trap),
161 sizeof(struct conf_trap), req_clr_trap },
162 { REQ_REQUEST_KEY, AUTH, sizeof(u_long), sizeof(u_long),
163 set_request_keyid },
164 { REQ_CONTROL_KEY, AUTH, sizeof(u_long), sizeof(u_long),
165 set_control_keyid },
166 { REQ_GET_CTLSTATS, NOAUTH, 0, 0, get_ctl_stats },
167 #ifdef KERNEL_PLL
168 { REQ_GET_KERNEL, NOAUTH, 0, 0, get_kernel_info },
169 #endif
170 #ifdef REFCLOCK
171 { REQ_GET_CLOCKINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32),
172 get_clock_info },
173 { REQ_SET_CLKFUDGE, AUTH, sizeof(struct conf_fudge),
174 sizeof(struct conf_fudge), set_clock_fudge },
175 { REQ_GET_CLKBUGINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32),
176 get_clkbug_info },
177 #endif
178 { REQ_IF_STATS, AUTH, 0, 0, get_if_stats },
179 { REQ_IF_RELOAD, AUTH, 0, 0, do_if_reload },
181 { NO_REQUEST, NOAUTH, 0, 0, 0 }
186 * Authentication keyid used to authenticate requests. Zero means we
187 * don't allow writing anything.
189 keyid_t info_auth_keyid;
192 * Statistic counters to keep track of requests and responses.
194 u_long numrequests; /* number of requests we've received */
195 u_long numresppkts; /* number of resp packets sent with data */
197 u_long errorcounter[INFO_ERR_AUTH+1]; /* lazy way to count errors, indexed */
198 /* by the error code */
201 * A hack. To keep the authentication module clear of ntp-ism's, we
202 * include a time reset variable for its stats here.
204 static u_long auth_timereset;
207 * Response packet used by these routines. Also some state information
208 * so that we can handle packet formatting within a common set of
209 * subroutines. Note we try to enter data in place whenever possible,
210 * but the need to set the more bit correctly means we occasionally
211 * use the extra buffer and copy.
213 static struct resp_pkt rpkt;
214 static int reqver;
215 static int seqno;
216 static int nitems;
217 static int itemsize;
218 static int databytes;
219 static char exbuf[RESP_DATA_SIZE];
220 static int usingexbuf;
221 static struct sockaddr_storage *toaddr;
222 static struct interface *frominter;
225 * init_request - initialize request data
227 void
228 init_request (void)
230 int i;
232 numrequests = 0;
233 numresppkts = 0;
234 auth_timereset = 0;
235 info_auth_keyid = 0; /* by default, can't do this */
237 for (i = 0; i < sizeof(errorcounter)/sizeof(errorcounter[0]); i++)
238 errorcounter[i] = 0;
243 * req_ack - acknowledge request with no data
245 static void
246 req_ack(
247 struct sockaddr_storage *srcadr,
248 struct interface *inter,
249 struct req_pkt *inpkt,
250 int errcode
254 * fill in the fields
256 rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver);
257 rpkt.auth_seq = AUTH_SEQ(0, 0);
258 rpkt.implementation = inpkt->implementation;
259 rpkt.request = inpkt->request;
260 rpkt.err_nitems = ERR_NITEMS(errcode, 0);
261 rpkt.mbz_itemsize = MBZ_ITEMSIZE(0);
264 * send packet and bump counters
266 sendpkt(srcadr, inter, -1, (struct pkt *)&rpkt, RESP_HEADER_SIZE);
267 errorcounter[errcode]++;
272 * prepare_pkt - prepare response packet for transmission, return pointer
273 * to storage for data item.
275 static char *
276 prepare_pkt(
277 struct sockaddr_storage *srcadr,
278 struct interface *inter,
279 struct req_pkt *pkt,
280 u_int structsize
283 #ifdef DEBUG
284 if (debug > 3)
285 printf("request: preparing pkt\n");
286 #endif
289 * Fill in the implementation, request and itemsize fields
290 * since these won't change.
292 rpkt.implementation = pkt->implementation;
293 rpkt.request = pkt->request;
294 rpkt.mbz_itemsize = MBZ_ITEMSIZE(structsize);
297 * Compute the static data needed to carry on.
299 toaddr = srcadr;
300 frominter = inter;
301 seqno = 0;
302 nitems = 0;
303 itemsize = structsize;
304 databytes = 0;
305 usingexbuf = 0;
308 * return the beginning of the packet buffer.
310 return &rpkt.data[0];
315 * more_pkt - return a data pointer for a new item.
317 static char *
318 more_pkt(void)
321 * If we were using the extra buffer, send the packet.
323 if (usingexbuf) {
324 #ifdef DEBUG
325 if (debug > 2)
326 printf("request: sending pkt\n");
327 #endif
328 rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, MORE_BIT, reqver);
329 rpkt.auth_seq = AUTH_SEQ(0, seqno);
330 rpkt.err_nitems = htons((u_short)nitems);
331 sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt,
332 RESP_HEADER_SIZE+databytes);
333 numresppkts++;
336 * Copy data out of exbuf into the packet.
338 memmove(&rpkt.data[0], exbuf, (unsigned)itemsize);
339 seqno++;
340 databytes = 0;
341 nitems = 0;
342 usingexbuf = 0;
345 databytes += itemsize;
346 nitems++;
347 if (databytes + itemsize <= RESP_DATA_SIZE) {
348 #ifdef DEBUG
349 if (debug > 3)
350 printf("request: giving him more data\n");
351 #endif
353 * More room in packet. Give him the
354 * next address.
356 return &rpkt.data[databytes];
357 } else {
359 * No room in packet. Give him the extra
360 * buffer unless this was the last in the sequence.
362 #ifdef DEBUG
363 if (debug > 3)
364 printf("request: into extra buffer\n");
365 #endif
366 if (seqno == MAXSEQ)
367 return (char *)0;
368 else {
369 usingexbuf = 1;
370 return exbuf;
377 * flush_pkt - we're done, return remaining information.
379 static void
380 flush_pkt(void)
382 #ifdef DEBUG
383 if (debug > 2)
384 printf("request: flushing packet, %d items\n", nitems);
385 #endif
387 * Must send the last packet. If nothing in here and nothing
388 * has been sent, send an error saying no data to be found.
390 if (seqno == 0 && nitems == 0)
391 req_ack(toaddr, frominter, (struct req_pkt *)&rpkt,
392 INFO_ERR_NODATA);
393 else {
394 rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver);
395 rpkt.auth_seq = AUTH_SEQ(0, seqno);
396 rpkt.err_nitems = htons((u_short)nitems);
397 sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt,
398 RESP_HEADER_SIZE+databytes);
399 numresppkts++;
406 * process_private - process private mode (7) packets
408 void
409 process_private(
410 struct recvbuf *rbufp,
411 int mod_okay
414 static u_long quiet_until;
415 struct req_pkt *inpkt;
416 struct req_pkt_tail *tailinpkt;
417 struct sockaddr_storage *srcadr;
418 struct interface *inter;
419 struct req_proc *proc;
420 int ec;
421 short temp_size;
424 * Initialize pointers, for convenience
426 inpkt = (struct req_pkt *)&rbufp->recv_pkt;
427 srcadr = &rbufp->recv_srcadr;
428 inter = rbufp->dstadr;
430 #ifdef DEBUG
431 if (debug > 2)
432 printf("process_private: impl %d req %d\n",
433 inpkt->implementation, inpkt->request);
434 #endif
437 * Do some sanity checks on the packet. Return a format
438 * error if it fails.
440 ec = 0;
441 if ( (++ec, ISRESPONSE(inpkt->rm_vn_mode))
442 || (++ec, ISMORE(inpkt->rm_vn_mode))
443 || (++ec, INFO_VERSION(inpkt->rm_vn_mode) > NTP_VERSION)
444 || (++ec, INFO_VERSION(inpkt->rm_vn_mode) < NTP_OLDVERSION)
445 || (++ec, INFO_SEQ(inpkt->auth_seq) != 0)
446 || (++ec, INFO_ERR(inpkt->err_nitems) != 0)
447 || (++ec, INFO_MBZ(inpkt->mbz_itemsize) != 0)
448 || (++ec, rbufp->recv_length < REQ_LEN_HDR)
450 NLOG(NLOG_SYSEVENT)
451 if (current_time >= quiet_until) {
452 msyslog(LOG_ERR,
453 "process_private: drop test %d"
454 " failed, pkt from %s",
455 ec, stoa(srcadr));
456 quiet_until = current_time + 60;
458 return;
461 reqver = INFO_VERSION(inpkt->rm_vn_mode);
464 * Get the appropriate procedure list to search.
466 if (inpkt->implementation == IMPL_UNIV)
467 proc = univ_codes;
468 else if ((inpkt->implementation == IMPL_XNTPD) ||
469 (inpkt->implementation == IMPL_XNTPD_OLD))
470 proc = ntp_codes;
471 else {
472 req_ack(srcadr, inter, inpkt, INFO_ERR_IMPL);
473 return;
477 * Search the list for the request codes. If it isn't one
478 * we know, return an error.
480 while (proc->request_code != NO_REQUEST) {
481 if (proc->request_code == (short) inpkt->request)
482 break;
483 proc++;
485 if (proc->request_code == NO_REQUEST) {
486 req_ack(srcadr, inter, inpkt, INFO_ERR_REQ);
487 return;
490 #ifdef DEBUG
491 if (debug > 3)
492 printf("found request in tables\n");
493 #endif
496 * If we need data, check to see if we have some. If we
497 * don't, check to see that there is none (picky, picky).
500 /* This part is a bit tricky, we want to be sure that the size
501 * returned is either the old or the new size. We also can find
502 * out if the client can accept both types of messages this way.
504 * Handle the exception of REQ_CONFIG. It can have two data sizes.
506 temp_size = INFO_ITEMSIZE(inpkt->mbz_itemsize);
507 if ((temp_size != proc->sizeofitem &&
508 temp_size != proc->v6_sizeofitem) &&
509 !(inpkt->implementation == IMPL_XNTPD &&
510 inpkt->request == REQ_CONFIG &&
511 temp_size == sizeof(struct old_conf_peer))) {
512 #ifdef DEBUG
513 if (debug > 2)
514 printf("process_private: wrong item size, received %d, should be %d or %d\n",
515 temp_size, proc->sizeofitem, proc->v6_sizeofitem);
516 #endif
517 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
518 return;
520 if ((proc->sizeofitem != 0) &&
521 ((temp_size * INFO_NITEMS(inpkt->err_nitems)) >
522 (rbufp->recv_length - REQ_LEN_HDR))) {
523 #ifdef DEBUG
524 if (debug > 2)
525 printf("process_private: not enough data\n");
526 #endif
527 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
528 return;
531 switch (inpkt->implementation) {
532 case IMPL_XNTPD:
533 client_v6_capable = 1;
534 break;
535 case IMPL_XNTPD_OLD:
536 client_v6_capable = 0;
537 break;
538 default:
539 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
540 return;
544 * If we need to authenticate, do so. Note that an
545 * authenticatable packet must include a mac field, must
546 * have used key info_auth_keyid and must have included
547 * a time stamp in the appropriate field. The time stamp
548 * must be within INFO_TS_MAXSKEW of the receive
549 * time stamp.
551 if (proc->needs_auth && sys_authenticate) {
552 l_fp ftmp;
553 double dtemp;
555 if (rbufp->recv_length < (int)((REQ_LEN_HDR +
556 (INFO_ITEMSIZE(inpkt->mbz_itemsize) *
557 INFO_NITEMS(inpkt->err_nitems))
558 + sizeof(struct req_pkt_tail)))) {
559 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
561 tailinpkt = (struct req_pkt_tail *)((char *)&rbufp->recv_pkt +
562 rbufp->recv_length - sizeof(struct req_pkt_tail));
565 * If this guy is restricted from doing this, don't let him
566 * If wrong key was used, or packet doesn't have mac, return.
568 if (!INFO_IS_AUTH(inpkt->auth_seq) || info_auth_keyid == 0
569 || ntohl(tailinpkt->keyid) != info_auth_keyid) {
570 #ifdef DEBUG
571 if (debug > 4)
572 printf("failed auth %d info_auth_keyid %lu pkt keyid %lu\n",
573 INFO_IS_AUTH(inpkt->auth_seq),
574 (u_long)info_auth_keyid,
575 (u_long)ntohl(tailinpkt->keyid));
576 msyslog(LOG_DEBUG,
577 "process_private: failed auth %d info_auth_keyid %lu pkt keyid %lu\n",
578 INFO_IS_AUTH(inpkt->auth_seq),
579 (u_long)info_auth_keyid,
580 (u_long)ntohl(tailinpkt->keyid));
581 #endif
582 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
583 return;
585 if (rbufp->recv_length > REQ_LEN_MAC) {
586 #ifdef DEBUG
587 if (debug > 4)
588 printf("bad pkt length %d\n",
589 rbufp->recv_length);
590 #endif
591 msyslog(LOG_ERR, "process_private: bad pkt length %d",
592 rbufp->recv_length);
593 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
594 return;
596 if (!mod_okay || !authhavekey(info_auth_keyid)) {
597 #ifdef DEBUG
598 if (debug > 4)
599 printf("failed auth mod_okay %d\n", mod_okay);
600 msyslog(LOG_DEBUG,
601 "process_private: failed auth mod_okay %d\n",
602 mod_okay);
603 #endif
604 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
605 return;
609 * calculate absolute time difference between xmit time stamp
610 * and receive time stamp. If too large, too bad.
612 NTOHL_FP(&tailinpkt->tstamp, &ftmp);
613 L_SUB(&ftmp, &rbufp->recv_time);
614 LFPTOD(&ftmp, dtemp);
615 if (fabs(dtemp) >= INFO_TS_MAXSKEW) {
617 * He's a loser. Tell him.
619 #ifdef DEBUG
620 if (debug > 4)
621 printf("xmit/rcv timestamp delta > INFO_TS_MAXSKEW\n");
622 #endif
623 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
624 return;
628 * So far so good. See if decryption works out okay.
630 if (!authdecrypt(info_auth_keyid, (u_int32 *)inpkt,
631 rbufp->recv_length - sizeof(struct req_pkt_tail) +
632 REQ_LEN_HDR, sizeof(struct req_pkt_tail) - REQ_LEN_HDR)) {
633 #ifdef DEBUG
634 if (debug > 4)
635 printf("authdecrypt failed\n");
636 #endif
637 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
638 return;
642 #ifdef DEBUG
643 if (debug > 3)
644 printf("process_private: all okay, into handler\n");
645 #endif
648 * Packet is okay. Call the handler to send him data.
650 (proc->handler)(srcadr, inter, inpkt);
655 * peer_list - send a list of the peers
657 static void
658 peer_list(
659 struct sockaddr_storage *srcadr,
660 struct interface *inter,
661 struct req_pkt *inpkt
664 register struct info_peer_list *ip;
665 register struct peer *pp;
666 register int i;
667 register int skip = 0;
669 ip = (struct info_peer_list *)prepare_pkt(srcadr, inter, inpkt,
670 v6sizeof(struct info_peer_list));
671 for (i = 0; i < NTP_HASH_SIZE && ip != 0; i++) {
672 pp = peer_hash[i];
673 while (pp != 0 && ip != 0) {
674 if (pp->srcadr.ss_family == AF_INET6) {
675 if (client_v6_capable) {
676 ip->addr6 = GET_INADDR6(pp->srcadr);
677 ip->v6_flag = 1;
678 skip = 0;
679 } else {
680 skip = 1;
681 break;
683 } else {
684 ip->addr = GET_INADDR(pp->srcadr);
685 if (client_v6_capable)
686 ip->v6_flag = 0;
687 skip = 0;
690 if(!skip) {
691 ip->port = NSRCPORT(&pp->srcadr);
692 ip->hmode = pp->hmode;
693 ip->flags = 0;
694 if (pp->flags & FLAG_CONFIG)
695 ip->flags |= INFO_FLAG_CONFIG;
696 if (pp == sys_peer)
697 ip->flags |= INFO_FLAG_SYSPEER;
698 if (pp->status == CTL_PST_SEL_SYNCCAND)
699 ip->flags |= INFO_FLAG_SEL_CANDIDATE;
700 if (pp->status >= CTL_PST_SEL_SYSPEER)
701 ip->flags |= INFO_FLAG_SHORTLIST;
702 ip = (struct info_peer_list *)more_pkt();
704 pp = pp->next;
707 flush_pkt();
712 * peer_list_sum - return extended peer list
714 static void
715 peer_list_sum(
716 struct sockaddr_storage *srcadr,
717 struct interface *inter,
718 struct req_pkt *inpkt
721 register struct info_peer_summary *ips;
722 register struct peer *pp;
723 register int i;
724 l_fp ltmp;
725 register int skip;
727 #ifdef DEBUG
728 if (debug > 2)
729 printf("wants peer list summary\n");
730 #endif
731 ips = (struct info_peer_summary *)prepare_pkt(srcadr, inter, inpkt,
732 v6sizeof(struct info_peer_summary));
733 for (i = 0; i < NTP_HASH_SIZE && ips != 0; i++) {
734 pp = peer_hash[i];
735 while (pp != 0 && ips != 0) {
736 #ifdef DEBUG
737 if (debug > 3)
738 printf("sum: got one\n");
739 #endif
741 * Be careful here not to return v6 peers when we
742 * want only v4.
744 if (pp->srcadr.ss_family == AF_INET6) {
745 if (client_v6_capable) {
746 ips->srcadr6 = GET_INADDR6(pp->srcadr);
747 ips->v6_flag = 1;
748 if (pp->dstadr)
749 ips->dstadr6 = GET_INADDR6(pp->dstadr->sin);
750 else
751 memset(&ips->dstadr6, 0, sizeof(ips->dstadr6));
752 skip = 0;
753 } else {
754 skip = 1;
755 break;
757 } else {
758 ips->srcadr = GET_INADDR(pp->srcadr);
759 if (client_v6_capable)
760 ips->v6_flag = 0;
761 /* XXX PDM This code is buggy. Need to replace with a straightforward assignment */
763 if (pp->dstadr)
764 ips->dstadr = (pp->processed) ?
765 pp->cast_flags == MDF_BCAST ?
766 GET_INADDR(pp->dstadr->bcast):
767 pp->cast_flags ?
768 GET_INADDR(pp->dstadr->sin) ?
769 GET_INADDR(pp->dstadr->sin):
770 GET_INADDR(pp->dstadr->bcast):
771 1 : GET_INADDR(pp->dstadr->sin);
772 else
773 memset(&ips->dstadr, 0, sizeof(ips->dstadr));
775 skip = 0;
778 if (!skip){
779 ips->srcport = NSRCPORT(&pp->srcadr);
780 ips->stratum = pp->stratum;
781 ips->hpoll = pp->hpoll;
782 ips->ppoll = pp->ppoll;
783 ips->reach = pp->reach;
784 ips->flags = 0;
785 if (pp == sys_peer)
786 ips->flags |= INFO_FLAG_SYSPEER;
787 if (pp->flags & FLAG_CONFIG)
788 ips->flags |= INFO_FLAG_CONFIG;
789 if (pp->flags & FLAG_REFCLOCK)
790 ips->flags |= INFO_FLAG_REFCLOCK;
791 if (pp->flags & FLAG_AUTHENABLE)
792 ips->flags |= INFO_FLAG_AUTHENABLE;
793 if (pp->flags & FLAG_PREFER)
794 ips->flags |= INFO_FLAG_PREFER;
795 if (pp->flags & FLAG_BURST)
796 ips->flags |= INFO_FLAG_BURST;
797 if (pp->status == CTL_PST_SEL_SYNCCAND)
798 ips->flags |= INFO_FLAG_SEL_CANDIDATE;
799 if (pp->status >= CTL_PST_SEL_SYSPEER)
800 ips->flags |= INFO_FLAG_SHORTLIST;
801 ips->hmode = pp->hmode;
802 ips->delay = HTONS_FP(DTOFP(pp->delay));
803 DTOLFP(pp->offset, &ltmp);
804 HTONL_FP(&ltmp, &ips->offset);
805 ips->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp)));
807 pp = pp->next;
808 ips = (struct info_peer_summary *)more_pkt();
811 flush_pkt();
816 * peer_info - send information for one or more peers
818 static void
819 peer_info (
820 struct sockaddr_storage *srcadr,
821 struct interface *inter,
822 struct req_pkt *inpkt
825 register struct info_peer_list *ipl;
826 register struct peer *pp;
827 register struct info_peer *ip;
828 register int items;
829 register int i, j;
830 struct sockaddr_storage addr;
831 extern struct peer *sys_peer;
832 l_fp ltmp;
834 memset((char *)&addr, 0, sizeof addr);
835 items = INFO_NITEMS(inpkt->err_nitems);
836 ipl = (struct info_peer_list *) inpkt->data;
838 ip = (struct info_peer *)prepare_pkt(srcadr, inter, inpkt,
839 v6sizeof(struct info_peer));
840 while (items-- > 0 && ip != 0) {
841 memset((char *)&addr, 0, sizeof(addr));
842 NSRCPORT(&addr) = ipl->port;
843 if (client_v6_capable && ipl->v6_flag != 0) {
844 addr.ss_family = AF_INET6;
845 GET_INADDR6(addr) = ipl->addr6;
846 } else {
847 addr.ss_family = AF_INET;
848 GET_INADDR(addr) = ipl->addr;
850 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
851 addr.ss_len = SOCKLEN(&addr);
852 #endif
853 ipl++;
854 if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0)
855 continue;
856 if (pp->srcadr.ss_family == AF_INET6) {
857 if (pp->dstadr)
858 ip->dstadr6 = pp->cast_flags == MDF_BCAST ?
859 GET_INADDR6(pp->dstadr->bcast) :
860 GET_INADDR6(pp->dstadr->sin);
861 else
862 memset(&ip->dstadr6, 0, sizeof(ip->dstadr6));
864 ip->srcadr6 = GET_INADDR6(pp->srcadr);
865 ip->v6_flag = 1;
866 } else {
867 /* XXX PDM This code is buggy. Need to replace with a straightforward assignment */
868 if (pp->dstadr)
869 ip->dstadr = (pp->processed) ?
870 pp->cast_flags == MDF_BCAST ?
871 GET_INADDR(pp->dstadr->bcast):
872 pp->cast_flags ?
873 GET_INADDR(pp->dstadr->sin) ?
874 GET_INADDR(pp->dstadr->sin):
875 GET_INADDR(pp->dstadr->bcast):
876 2 : GET_INADDR(pp->dstadr->sin);
877 else
878 memset(&ip->dstadr, 0, sizeof(ip->dstadr));
880 ip->srcadr = GET_INADDR(pp->srcadr);
881 if (client_v6_capable)
882 ip->v6_flag = 0;
884 ip->srcport = NSRCPORT(&pp->srcadr);
885 ip->flags = 0;
886 if (pp == sys_peer)
887 ip->flags |= INFO_FLAG_SYSPEER;
888 if (pp->flags & FLAG_CONFIG)
889 ip->flags |= INFO_FLAG_CONFIG;
890 if (pp->flags & FLAG_REFCLOCK)
891 ip->flags |= INFO_FLAG_REFCLOCK;
892 if (pp->flags & FLAG_AUTHENABLE)
893 ip->flags |= INFO_FLAG_AUTHENABLE;
894 if (pp->flags & FLAG_PREFER)
895 ip->flags |= INFO_FLAG_PREFER;
896 if (pp->flags & FLAG_BURST)
897 ip->flags |= INFO_FLAG_BURST;
898 if (pp->status == CTL_PST_SEL_SYNCCAND)
899 ip->flags |= INFO_FLAG_SEL_CANDIDATE;
900 if (pp->status >= CTL_PST_SEL_SYSPEER)
901 ip->flags |= INFO_FLAG_SHORTLIST;
902 ip->leap = pp->leap;
903 ip->hmode = pp->hmode;
904 ip->keyid = pp->keyid;
905 ip->stratum = pp->stratum;
906 ip->ppoll = pp->ppoll;
907 ip->hpoll = pp->hpoll;
908 ip->precision = pp->precision;
909 ip->version = pp->version;
910 ip->reach = pp->reach;
911 ip->unreach = (u_char) pp->unreach;
912 ip->flash = (u_char)pp->flash;
913 ip->flash2 = (u_short) pp->flash;
914 ip->estbdelay = HTONS_FP(DTOFP(pp->estbdelay));
915 ip->ttl = pp->ttl;
916 ip->associd = htons(pp->associd);
917 ip->rootdelay = HTONS_FP(DTOUFP(pp->rootdelay));
918 ip->rootdispersion = HTONS_FP(DTOUFP(pp->rootdispersion));
919 ip->refid = pp->refid;
920 HTONL_FP(&pp->reftime, &ip->reftime);
921 HTONL_FP(&pp->org, &ip->org);
922 HTONL_FP(&pp->rec, &ip->rec);
923 HTONL_FP(&pp->xmt, &ip->xmt);
924 j = pp->filter_nextpt - 1;
925 for (i = 0; i < NTP_SHIFT; i++, j--) {
926 if (j < 0)
927 j = NTP_SHIFT-1;
928 ip->filtdelay[i] = HTONS_FP(DTOFP(pp->filter_delay[j]));
929 DTOLFP(pp->filter_offset[j], &ltmp);
930 HTONL_FP(&ltmp, &ip->filtoffset[i]);
931 ip->order[i] = (u_char)((pp->filter_nextpt+NTP_SHIFT-1)
932 - pp->filter_order[i]);
933 if (ip->order[i] >= NTP_SHIFT)
934 ip->order[i] -= NTP_SHIFT;
936 DTOLFP(pp->offset, &ltmp);
937 HTONL_FP(&ltmp, &ip->offset);
938 ip->delay = HTONS_FP(DTOFP(pp->delay));
939 ip->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp)));
940 ip->selectdisp = HTONS_FP(DTOUFP(SQRT(pp->jitter)));
941 ip = (struct info_peer *)more_pkt();
943 flush_pkt();
948 * peer_stats - send statistics for one or more peers
950 static void
951 peer_stats (
952 struct sockaddr_storage *srcadr,
953 struct interface *inter,
954 struct req_pkt *inpkt
957 register struct info_peer_list *ipl;
958 register struct peer *pp;
959 register struct info_peer_stats *ip;
960 register int items;
961 struct sockaddr_storage addr;
962 extern struct peer *sys_peer;
964 #ifdef DEBUG
965 if (debug)
966 printf("peer_stats: called\n");
967 #endif
968 items = INFO_NITEMS(inpkt->err_nitems);
969 ipl = (struct info_peer_list *) inpkt->data;
970 ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt,
971 v6sizeof(struct info_peer_stats));
972 while (items-- > 0 && ip != 0) {
973 memset((char *)&addr, 0, sizeof(addr));
974 NSRCPORT(&addr) = ipl->port;
975 if (client_v6_capable && ipl->v6_flag) {
976 addr.ss_family = AF_INET6;
977 GET_INADDR6(addr) = ipl->addr6;
978 } else {
979 addr.ss_family = AF_INET;
980 GET_INADDR(addr) = ipl->addr;
982 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
983 addr.ss_len = SOCKLEN(&addr);
984 #endif
985 #ifdef DEBUG
986 if (debug)
987 printf("peer_stats: looking for %s, %d, %d\n", stoa(&addr),
988 ipl->port, ((struct sockaddr_in6 *)&addr)->sin6_port);
989 #endif
990 ipl = (struct info_peer_list *)((char *)ipl +
991 INFO_ITEMSIZE(inpkt->mbz_itemsize));
993 if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0)
994 continue;
995 #ifdef DEBUG
996 if (debug)
997 printf("peer_stats: found %s\n", stoa(&addr));
998 #endif
999 if (pp->srcadr.ss_family == AF_INET) {
1000 if (pp->dstadr)
1001 ip->dstadr = (pp->processed) ?
1002 pp->cast_flags == MDF_BCAST ?
1003 GET_INADDR(pp->dstadr->bcast):
1004 pp->cast_flags ?
1005 GET_INADDR(pp->dstadr->sin) ?
1006 GET_INADDR(pp->dstadr->sin):
1007 GET_INADDR(pp->dstadr->bcast):
1008 3 : 7;
1009 else
1010 memset(&ip->dstadr, 0, sizeof(ip->dstadr));
1012 ip->srcadr = GET_INADDR(pp->srcadr);
1013 if (client_v6_capable)
1014 ip->v6_flag = 0;
1015 } else {
1016 if (pp->dstadr)
1017 ip->dstadr6 = pp->cast_flags == MDF_BCAST ?
1018 GET_INADDR6(pp->dstadr->bcast):
1019 GET_INADDR6(pp->dstadr->sin);
1020 else
1021 memset(&ip->dstadr6, 0, sizeof(ip->dstadr6));
1023 ip->srcadr6 = GET_INADDR6(pp->srcadr);
1024 ip->v6_flag = 1;
1026 ip->srcport = NSRCPORT(&pp->srcadr);
1027 ip->flags = 0;
1028 if (pp == sys_peer)
1029 ip->flags |= INFO_FLAG_SYSPEER;
1030 if (pp->flags & FLAG_CONFIG)
1031 ip->flags |= INFO_FLAG_CONFIG;
1032 if (pp->flags & FLAG_REFCLOCK)
1033 ip->flags |= INFO_FLAG_REFCLOCK;
1034 if (pp->flags & FLAG_AUTHENABLE)
1035 ip->flags |= INFO_FLAG_AUTHENABLE;
1036 if (pp->flags & FLAG_PREFER)
1037 ip->flags |= INFO_FLAG_PREFER;
1038 if (pp->flags & FLAG_BURST)
1039 ip->flags |= INFO_FLAG_BURST;
1040 if (pp->flags & FLAG_IBURST)
1041 ip->flags |= INFO_FLAG_IBURST;
1042 if (pp->status == CTL_PST_SEL_SYNCCAND)
1043 ip->flags |= INFO_FLAG_SEL_CANDIDATE;
1044 if (pp->status >= CTL_PST_SEL_SYSPEER)
1045 ip->flags |= INFO_FLAG_SHORTLIST;
1046 ip->flags = htons(ip->flags);
1047 ip->timereceived = htonl((u_int32)(current_time - pp->timereceived));
1048 ip->timetosend = htonl(pp->nextdate - current_time);
1049 ip->timereachable = htonl((u_int32)(current_time - pp->timereachable));
1050 ip->sent = htonl((u_int32)(pp->sent));
1051 ip->processed = htonl((u_int32)(pp->processed));
1052 ip->badauth = htonl((u_int32)(pp->badauth));
1053 ip->bogusorg = htonl((u_int32)(pp->bogusorg));
1054 ip->oldpkt = htonl((u_int32)(pp->oldpkt));
1055 ip->seldisp = htonl((u_int32)(pp->seldisptoolarge));
1056 ip->selbroken = htonl((u_int32)(pp->selbroken));
1057 ip->candidate = pp->status;
1058 ip = (struct info_peer_stats *)more_pkt();
1060 flush_pkt();
1065 * sys_info - return system info
1067 static void
1068 sys_info(
1069 struct sockaddr_storage *srcadr,
1070 struct interface *inter,
1071 struct req_pkt *inpkt
1074 register struct info_sys *is;
1076 is = (struct info_sys *)prepare_pkt(srcadr, inter, inpkt,
1077 v6sizeof(struct info_sys));
1079 if (sys_peer != 0) {
1080 if (sys_peer->srcadr.ss_family == AF_INET) {
1081 is->peer = GET_INADDR(sys_peer->srcadr);
1082 if (client_v6_capable)
1083 is->v6_flag = 0;
1084 } else if (client_v6_capable) {
1085 is->peer6 = GET_INADDR6(sys_peer->srcadr);
1086 is->v6_flag = 1;
1088 is->peer_mode = sys_peer->hmode;
1089 } else {
1090 is->peer = 0;
1091 if (client_v6_capable) {
1092 is->v6_flag = 0;
1094 is->peer_mode = 0;
1097 is->leap = sys_leap;
1098 is->stratum = sys_stratum;
1099 is->precision = sys_precision;
1100 is->rootdelay = htonl(DTOFP(sys_rootdelay));
1101 is->rootdispersion = htonl(DTOUFP(sys_rootdispersion));
1102 is->frequency = htonl(DTOFP(sys_jitter));
1103 is->stability = htonl(DTOUFP(clock_stability));
1104 is->refid = sys_refid;
1105 HTONL_FP(&sys_reftime, &is->reftime);
1107 is->poll = sys_poll;
1109 is->flags = 0;
1110 if (sys_authenticate)
1111 is->flags |= INFO_FLAG_AUTHENTICATE;
1112 if (sys_bclient)
1113 is->flags |= INFO_FLAG_BCLIENT;
1114 #ifdef REFCLOCK
1115 if (cal_enable)
1116 is->flags |= INFO_FLAG_CAL;
1117 #endif /* REFCLOCK */
1118 if (kern_enable)
1119 is->flags |= INFO_FLAG_KERNEL;
1120 if (mon_enabled != MON_OFF)
1121 is->flags |= INFO_FLAG_MONITOR;
1122 if (ntp_enable)
1123 is->flags |= INFO_FLAG_NTP;
1124 if (pps_enable)
1125 is->flags |= INFO_FLAG_PPS_SYNC;
1126 if (stats_control)
1127 is->flags |= INFO_FLAG_FILEGEN;
1128 is->bdelay = HTONS_FP(DTOFP(sys_bdelay));
1129 HTONL_UF(sys_authdelay.l_f, &is->authdelay);
1131 (void) more_pkt();
1132 flush_pkt();
1137 * sys_stats - return system statistics
1139 static void
1140 sys_stats(
1141 struct sockaddr_storage *srcadr,
1142 struct interface *inter,
1143 struct req_pkt *inpkt
1146 register struct info_sys_stats *ss;
1149 * Importations from the protocol module
1151 ss = (struct info_sys_stats *)prepare_pkt(srcadr, inter, inpkt,
1152 sizeof(struct info_sys_stats));
1153 ss->timeup = htonl((u_int32)current_time);
1154 ss->timereset = htonl((u_int32)(current_time - sys_stattime));
1155 ss->denied = htonl((u_int32)sys_restricted);
1156 ss->oldversionpkt = htonl((u_int32)sys_oldversionpkt);
1157 ss->newversionpkt = htonl((u_int32)sys_newversionpkt);
1158 ss->unknownversion = htonl((u_int32)sys_unknownversion);
1159 ss->badlength = htonl((u_int32)sys_badlength);
1160 ss->processed = htonl((u_int32)sys_processed);
1161 ss->badauth = htonl((u_int32)sys_badauth);
1162 ss->limitrejected = htonl((u_int32)sys_limitrejected);
1163 ss->received = htonl((u_int32)sys_received);
1164 (void) more_pkt();
1165 flush_pkt();
1170 * mem_stats - return memory statistics
1172 static void
1173 mem_stats(
1174 struct sockaddr_storage *srcadr,
1175 struct interface *inter,
1176 struct req_pkt *inpkt
1179 register struct info_mem_stats *ms;
1180 register int i;
1183 * Importations from the peer module
1185 extern int peer_hash_count[];
1186 extern int peer_free_count;
1187 extern u_long peer_timereset;
1188 extern u_long findpeer_calls;
1189 extern u_long peer_allocations;
1190 extern u_long peer_demobilizations;
1191 extern int total_peer_structs;
1193 ms = (struct info_mem_stats *)prepare_pkt(srcadr, inter, inpkt,
1194 sizeof(struct info_mem_stats));
1196 ms->timereset = htonl((u_int32)(current_time - peer_timereset));
1197 ms->totalpeermem = htons((u_short)total_peer_structs);
1198 ms->freepeermem = htons((u_short)peer_free_count);
1199 ms->findpeer_calls = htonl((u_int32)findpeer_calls);
1200 ms->allocations = htonl((u_int32)peer_allocations);
1201 ms->demobilizations = htonl((u_int32)peer_demobilizations);
1203 for (i = 0; i < NTP_HASH_SIZE; i++) {
1204 if (peer_hash_count[i] > 255)
1205 ms->hashcount[i] = 255;
1206 else
1207 ms->hashcount[i] = (u_char)peer_hash_count[i];
1210 (void) more_pkt();
1211 flush_pkt();
1216 * io_stats - return io statistics
1218 static void
1219 io_stats(
1220 struct sockaddr_storage *srcadr,
1221 struct interface *inter,
1222 struct req_pkt *inpkt
1225 register struct info_io_stats *io;
1228 * Importations from the io module
1230 extern u_long io_timereset;
1232 io = (struct info_io_stats *)prepare_pkt(srcadr, inter, inpkt,
1233 sizeof(struct info_io_stats));
1235 io->timereset = htonl((u_int32)(current_time - io_timereset));
1236 io->totalrecvbufs = htons((u_short) total_recvbuffs());
1237 io->freerecvbufs = htons((u_short) free_recvbuffs());
1238 io->fullrecvbufs = htons((u_short) full_recvbuffs());
1239 io->lowwater = htons((u_short) lowater_additions());
1240 io->dropped = htonl((u_int32)packets_dropped);
1241 io->ignored = htonl((u_int32)packets_ignored);
1242 io->received = htonl((u_int32)packets_received);
1243 io->sent = htonl((u_int32)packets_sent);
1244 io->notsent = htonl((u_int32)packets_notsent);
1245 io->interrupts = htonl((u_int32)handler_calls);
1246 io->int_received = htonl((u_int32)handler_pkts);
1248 (void) more_pkt();
1249 flush_pkt();
1254 * timer_stats - return timer statistics
1256 static void
1257 timer_stats(
1258 struct sockaddr_storage *srcadr,
1259 struct interface *inter,
1260 struct req_pkt *inpkt
1263 register struct info_timer_stats *ts;
1266 * Importations from the timer module
1268 extern u_long timer_timereset;
1269 extern u_long timer_overflows;
1270 extern u_long timer_xmtcalls;
1272 ts = (struct info_timer_stats *)prepare_pkt(srcadr, inter, inpkt,
1273 sizeof(struct info_timer_stats));
1275 ts->timereset = htonl((u_int32)(current_time - timer_timereset));
1276 ts->alarms = htonl((u_int32)alarm_overflow);
1277 ts->overflows = htonl((u_int32)timer_overflows);
1278 ts->xmtcalls = htonl((u_int32)timer_xmtcalls);
1280 (void) more_pkt();
1281 flush_pkt();
1286 * loop_info - return the current state of the loop filter
1288 static void
1289 loop_info(
1290 struct sockaddr_storage *srcadr,
1291 struct interface *inter,
1292 struct req_pkt *inpkt
1295 register struct info_loop *li;
1296 l_fp ltmp;
1299 * Importations from the loop filter module
1301 extern double last_offset;
1302 extern double drift_comp;
1303 extern int tc_counter;
1304 extern u_long sys_clocktime;
1306 li = (struct info_loop *)prepare_pkt(srcadr, inter, inpkt,
1307 sizeof(struct info_loop));
1309 DTOLFP(last_offset, &ltmp);
1310 HTONL_FP(&ltmp, &li->last_offset);
1311 DTOLFP(drift_comp * 1e6, &ltmp);
1312 HTONL_FP(&ltmp, &li->drift_comp);
1313 li->compliance = htonl((u_int32)(tc_counter));
1314 li->watchdog_timer = htonl((u_int32)(current_time - sys_clocktime));
1316 (void) more_pkt();
1317 flush_pkt();
1322 * do_conf - add a peer to the configuration list
1324 static void
1325 do_conf(
1326 struct sockaddr_storage *srcadr,
1327 struct interface *inter,
1328 struct req_pkt *inpkt
1331 static u_long soonest_ifrescan_time = 0;
1332 int items;
1333 u_int fl;
1334 struct conf_peer *cp;
1335 struct conf_peer temp_cp;
1336 struct sockaddr_storage peeraddr;
1337 struct sockaddr_in tmp_clock;
1340 * Do a check of everything to see that it looks
1341 * okay. If not, complain about it. Note we are
1342 * very picky here.
1344 items = INFO_NITEMS(inpkt->err_nitems);
1345 cp = (struct conf_peer *)inpkt->data;
1346 memset(&temp_cp, 0, sizeof(struct conf_peer));
1347 memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1348 fl = 0;
1349 while (items-- > 0 && !fl) {
1350 if (((temp_cp.version) > NTP_VERSION)
1351 || ((temp_cp.version) < NTP_OLDVERSION))
1352 fl = 1;
1353 if (temp_cp.hmode != MODE_ACTIVE
1354 && temp_cp.hmode != MODE_CLIENT
1355 && temp_cp.hmode != MODE_BROADCAST)
1356 fl = 1;
1357 if (temp_cp.flags & ~(CONF_FLAG_AUTHENABLE | CONF_FLAG_PREFER
1358 | CONF_FLAG_BURST | CONF_FLAG_IBURST | CONF_FLAG_SKEY))
1359 fl = 1;
1360 cp = (struct conf_peer *)
1361 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1364 if (fl) {
1365 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1366 return;
1370 * Looks okay, try it out
1372 items = INFO_NITEMS(inpkt->err_nitems);
1373 cp = (struct conf_peer *)inpkt->data;
1375 while (items-- > 0) {
1376 memset(&temp_cp, 0, sizeof(struct conf_peer));
1377 memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1378 memset((char *)&peeraddr, 0, sizeof(struct sockaddr_storage));
1380 fl = 0;
1381 if (temp_cp.flags & CONF_FLAG_AUTHENABLE)
1382 fl |= FLAG_AUTHENABLE;
1383 if (temp_cp.flags & CONF_FLAG_PREFER)
1384 fl |= FLAG_PREFER;
1385 if (temp_cp.flags & CONF_FLAG_BURST)
1386 fl |= FLAG_BURST;
1387 if (temp_cp.flags & CONF_FLAG_IBURST)
1388 fl |= FLAG_IBURST;
1389 if (temp_cp.flags & CONF_FLAG_SKEY)
1390 fl |= FLAG_SKEY;
1392 if (client_v6_capable && temp_cp.v6_flag != 0) {
1393 peeraddr.ss_family = AF_INET6;
1394 GET_INADDR6(peeraddr) = temp_cp.peeraddr6;
1395 } else {
1396 peeraddr.ss_family = AF_INET;
1397 GET_INADDR(peeraddr) = temp_cp.peeraddr;
1399 * Make sure the address is valid
1401 tmp_clock = *CAST_V4(peeraddr);
1402 if (
1403 #ifdef REFCLOCK
1404 !ISREFCLOCKADR(&tmp_clock) &&
1405 #endif
1406 ISBADADR(&tmp_clock)) {
1407 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1408 return;
1412 NSRCPORT(&peeraddr) = htons(NTP_PORT);
1413 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
1414 peeraddr.ss_len = SOCKLEN(&peeraddr);
1415 #endif
1417 /* XXX W2DO? minpoll/maxpoll arguments ??? */
1418 if (peer_config(&peeraddr, (struct interface *)0,
1419 temp_cp.hmode, temp_cp.version, temp_cp.minpoll,
1420 temp_cp.maxpoll, fl, temp_cp.ttl, temp_cp.keyid,
1421 NULL) == 0) {
1422 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1423 return;
1427 * ntp_intres.c uses REQ_CONFIG/doconf() to add each
1428 * server after its name is resolved. If we have been
1429 * disconnected from the network, it may notice the
1430 * network has returned and add the first server while
1431 * the relevant interface is still disabled, awaiting
1432 * the next interface rescan. To get things moving
1433 * more quickly, trigger an interface scan now, except
1434 * if we have done so in the last half minute.
1436 if (soonest_ifrescan_time < current_time) {
1437 soonest_ifrescan_time = current_time + 30;
1438 timer_interfacetimeout(current_time);
1439 DPRINTF(1, ("do_conf triggering interface rescan\n"));
1442 cp = (struct conf_peer *)
1443 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1446 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1449 #if 0
1450 /* XXX */
1452 * dns_a - Snarf DNS info for an association ID
1454 static void
1455 dns_a(
1456 struct sockaddr_storage *srcadr,
1457 struct interface *inter,
1458 struct req_pkt *inpkt
1461 register struct info_dns_assoc *dp;
1462 register int items;
1463 struct sockaddr_in peeraddr;
1466 * Do a check of everything to see that it looks
1467 * okay. If not, complain about it. Note we are
1468 * very picky here.
1470 items = INFO_NITEMS(inpkt->err_nitems);
1471 dp = (struct info_dns_assoc *)inpkt->data;
1474 * Looks okay, try it out
1476 items = INFO_NITEMS(inpkt->err_nitems);
1477 dp = (struct info_dns_assoc *)inpkt->data;
1478 memset((char *)&peeraddr, 0, sizeof(struct sockaddr_in));
1479 peeraddr.sin_family = AF_INET;
1480 peeraddr.sin_port = htons(NTP_PORT);
1483 * Make sure the address is valid
1485 if (
1486 #ifdef REFCLOCK
1487 !ISREFCLOCKADR(&peeraddr) &&
1488 #endif
1489 ISBADADR(&peeraddr)) {
1490 #ifdef REFCLOCK
1491 msyslog(LOG_ERR, "dns_a: !ISREFCLOCK && ISBADADR");
1492 #else
1493 msyslog(LOG_ERR, "dns_a: ISBADADR");
1494 #endif
1495 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1496 return;
1499 while (items-- > 0) {
1500 associd_t associd;
1501 size_t hnl;
1502 struct peer *peer;
1503 int bogon = 0;
1505 associd = dp->associd;
1506 peer = findpeerbyassoc(associd);
1507 if (peer == 0 || peer->flags & FLAG_REFCLOCK) {
1508 msyslog(LOG_ERR, "dns_a: %s",
1509 (peer == 0)
1510 ? "peer == 0"
1511 : "peer->flags & FLAG_REFCLOCK");
1512 ++bogon;
1514 peeraddr.sin_addr.s_addr = dp->peeraddr;
1515 for (hnl = 0; dp->hostname[hnl] && hnl < sizeof dp->hostname; ++hnl) ;
1516 if (hnl >= sizeof dp->hostname) {
1517 msyslog(LOG_ERR, "dns_a: hnl (%ld) >= %ld",
1518 (long)hnl, (long)sizeof dp->hostname);
1519 ++bogon;
1522 msyslog(LOG_INFO, "dns_a: <%s> for %s, AssocID %d, bogon %d",
1523 dp->hostname,
1524 stoa((struct sockaddr_storage *)&peeraddr), associd,
1525 bogon);
1527 if (bogon) {
1528 /* If it didn't work */
1529 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1530 return;
1531 } else {
1532 #if 0
1533 #ifdef PUBKEY
1534 crypto_public(peer, dp->hostname);
1535 #endif /* PUBKEY */
1536 #endif
1539 dp++;
1542 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1544 #endif /* 0 */
1547 * do_unconf - remove a peer from the configuration list
1549 static void
1550 do_unconf(
1551 struct sockaddr_storage *srcadr,
1552 struct interface *inter,
1553 struct req_pkt *inpkt
1556 register struct conf_unpeer *cp;
1557 struct conf_unpeer temp_cp;
1558 register int items;
1559 register struct peer *peer;
1560 struct sockaddr_storage peeraddr;
1561 int bad, found;
1564 * This is a bit unstructured, but I like to be careful.
1565 * We check to see that every peer exists and is actually
1566 * configured. If so, we remove them. If not, we return
1567 * an error.
1569 items = INFO_NITEMS(inpkt->err_nitems);
1570 cp = (struct conf_unpeer *)inpkt->data;
1572 bad = 0;
1573 while (items-- > 0 && !bad) {
1574 memset(&temp_cp, 0, sizeof(temp_cp));
1575 memset(&peeraddr, 0, sizeof(peeraddr));
1576 memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1577 if (client_v6_capable && temp_cp.v6_flag != 0) {
1578 peeraddr.ss_family = AF_INET6;
1579 GET_INADDR6(peeraddr) = temp_cp.peeraddr6;
1580 } else {
1581 peeraddr.ss_family = AF_INET;
1582 GET_INADDR(peeraddr) = temp_cp.peeraddr;
1584 NSRCPORT(&peeraddr) = htons(NTP_PORT);
1585 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
1586 peeraddr.ss_len = SOCKLEN(&peeraddr);
1587 #endif
1588 found = 0;
1589 peer = (struct peer *)0;
1590 #ifdef DEBUG
1591 if (debug)
1592 printf("searching for %s\n", stoa(&peeraddr));
1593 #endif
1594 while (!found) {
1595 peer = findexistingpeer(&peeraddr, peer, -1);
1596 if (peer == (struct peer *)0)
1597 break;
1598 if (peer->flags & FLAG_CONFIG)
1599 found = 1;
1601 if (!found)
1602 bad = 1;
1603 cp = (struct conf_unpeer *)
1604 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1607 if (bad) {
1608 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1609 return;
1613 * Now do it in earnest.
1616 items = INFO_NITEMS(inpkt->err_nitems);
1617 cp = (struct conf_unpeer *)inpkt->data;
1618 while (items-- > 0) {
1619 memset(&temp_cp, 0, sizeof(temp_cp));
1620 memset(&peeraddr, 0, sizeof(peeraddr));
1621 memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1622 if (client_v6_capable && temp_cp.v6_flag != 0) {
1623 peeraddr.ss_family = AF_INET6;
1624 GET_INADDR6(peeraddr) = temp_cp.peeraddr6;
1625 } else {
1626 peeraddr.ss_family = AF_INET;
1627 GET_INADDR(peeraddr) = temp_cp.peeraddr;
1629 NSRCPORT(&peeraddr) = htons(NTP_PORT);
1630 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
1631 peeraddr.ss_len = SOCKLEN(&peeraddr);
1632 #endif
1633 peer_unconfig(&peeraddr, (struct interface *)0, -1);
1634 cp = (struct conf_unpeer *)
1635 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1638 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1643 * set_sys_flag - set system flags
1645 static void
1646 set_sys_flag(
1647 struct sockaddr_storage *srcadr,
1648 struct interface *inter,
1649 struct req_pkt *inpkt
1652 setclr_flags(srcadr, inter, inpkt, 1);
1657 * clr_sys_flag - clear system flags
1659 static void
1660 clr_sys_flag(
1661 struct sockaddr_storage *srcadr,
1662 struct interface *inter,
1663 struct req_pkt *inpkt
1666 setclr_flags(srcadr, inter, inpkt, 0);
1671 * setclr_flags - do the grunge work of flag setting/clearing
1673 static void
1674 setclr_flags(
1675 struct sockaddr_storage *srcadr,
1676 struct interface *inter,
1677 struct req_pkt *inpkt,
1678 u_long set
1681 register u_int flags;
1682 int prev_kern_enable;
1684 prev_kern_enable = kern_enable;
1685 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
1686 msyslog(LOG_ERR, "setclr_flags: err_nitems > 1");
1687 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1688 return;
1691 flags = ((struct conf_sys_flags *)inpkt->data)->flags;
1692 flags = ntohl(flags);
1694 if (flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS |
1695 SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR |
1696 SYS_FLAG_FILEGEN | SYS_FLAG_AUTH | SYS_FLAG_CAL)) {
1697 msyslog(LOG_ERR, "setclr_flags: extra flags: %#x",
1698 flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS |
1699 SYS_FLAG_NTP | SYS_FLAG_KERNEL |
1700 SYS_FLAG_MONITOR | SYS_FLAG_FILEGEN |
1701 SYS_FLAG_AUTH | SYS_FLAG_CAL));
1702 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1703 return;
1706 if (flags & SYS_FLAG_BCLIENT)
1707 proto_config(PROTO_BROADCLIENT, set, 0., NULL);
1708 if (flags & SYS_FLAG_PPS)
1709 proto_config(PROTO_PPS, set, 0., NULL);
1710 if (flags & SYS_FLAG_NTP)
1711 proto_config(PROTO_NTP, set, 0., NULL);
1712 if (flags & SYS_FLAG_KERNEL)
1713 proto_config(PROTO_KERNEL, set, 0., NULL);
1714 if (flags & SYS_FLAG_MONITOR)
1715 proto_config(PROTO_MONITOR, set, 0., NULL);
1716 if (flags & SYS_FLAG_FILEGEN)
1717 proto_config(PROTO_FILEGEN, set, 0., NULL);
1718 if (flags & SYS_FLAG_AUTH)
1719 proto_config(PROTO_AUTHENTICATE, set, 0., NULL);
1720 if (flags & SYS_FLAG_CAL)
1721 proto_config(PROTO_CAL, set, 0., NULL);
1722 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1724 /* Reset the kernel ntp parameters if the kernel flag changed. */
1725 if (prev_kern_enable && !kern_enable)
1726 loop_config(LOOP_KERN_CLEAR, 0.0);
1727 if (!prev_kern_enable && kern_enable)
1728 loop_config(LOOP_DRIFTCOMP, drift_comp);
1733 * list_restrict - return the restrict list
1735 static void
1736 list_restrict(
1737 struct sockaddr_storage *srcadr,
1738 struct interface *inter,
1739 struct req_pkt *inpkt
1742 register struct info_restrict *ir;
1743 register struct restrictlist *rl;
1744 register struct restrictlist6 *rl6;
1746 #ifdef DEBUG
1747 if (debug > 2)
1748 printf("wants restrict list summary\n");
1749 #endif
1751 ir = (struct info_restrict *)prepare_pkt(srcadr, inter, inpkt,
1752 v6sizeof(struct info_restrict));
1754 for (rl = restrictlist; rl != 0 && ir != 0; rl = rl->next) {
1755 ir->addr = htonl(rl->addr);
1756 if (client_v6_capable)
1757 ir->v6_flag = 0;
1758 ir->mask = htonl(rl->mask);
1759 ir->count = htonl((u_int32)rl->count);
1760 ir->flags = htons(rl->flags);
1761 ir->mflags = htons(rl->mflags);
1762 ir = (struct info_restrict *)more_pkt();
1764 if (client_v6_capable)
1765 for (rl6 = restrictlist6; rl6 != 0 && ir != 0; rl6 = rl6->next) {
1766 ir->addr6 = rl6->addr6;
1767 ir->mask6 = rl6->mask6;
1768 ir->v6_flag = 1;
1769 ir->count = htonl((u_int32)rl6->count);
1770 ir->flags = htons(rl6->flags);
1771 ir->mflags = htons(rl6->mflags);
1772 ir = (struct info_restrict *)more_pkt();
1774 flush_pkt();
1780 * do_resaddflags - add flags to a restrict entry (or create one)
1782 static void
1783 do_resaddflags(
1784 struct sockaddr_storage *srcadr,
1785 struct interface *inter,
1786 struct req_pkt *inpkt
1789 do_restrict(srcadr, inter, inpkt, RESTRICT_FLAGS);
1795 * do_ressubflags - remove flags from a restrict entry
1797 static void
1798 do_ressubflags(
1799 struct sockaddr_storage *srcadr,
1800 struct interface *inter,
1801 struct req_pkt *inpkt
1804 do_restrict(srcadr, inter, inpkt, RESTRICT_UNFLAG);
1809 * do_unrestrict - remove a restrict entry from the list
1811 static void
1812 do_unrestrict(
1813 struct sockaddr_storage *srcadr,
1814 struct interface *inter,
1815 struct req_pkt *inpkt
1818 do_restrict(srcadr, inter, inpkt, RESTRICT_REMOVE);
1826 * do_restrict - do the dirty stuff of dealing with restrictions
1828 static void
1829 do_restrict(
1830 struct sockaddr_storage *srcadr,
1831 struct interface *inter,
1832 struct req_pkt *inpkt,
1833 int op
1836 register struct conf_restrict *cr;
1837 register int items;
1838 struct sockaddr_storage matchaddr;
1839 struct sockaddr_storage matchmask;
1840 int bad;
1843 * Do a check of the flags to make sure that only
1844 * the NTPPORT flag is set, if any. If not, complain
1845 * about it. Note we are very picky here.
1847 items = INFO_NITEMS(inpkt->err_nitems);
1848 cr = (struct conf_restrict *)inpkt->data;
1850 bad = 0;
1851 cr->flags = ntohs(cr->flags);
1852 cr->mflags = ntohs(cr->mflags);
1853 while (items-- > 0 && !bad) {
1854 if (cr->mflags & ~(RESM_NTPONLY))
1855 bad |= 1;
1856 if (cr->flags & ~(RES_ALLFLAGS))
1857 bad |= 2;
1858 if (cr->mask != htonl(INADDR_ANY)) {
1859 if (client_v6_capable && cr->v6_flag != 0) {
1860 if (IN6_IS_ADDR_UNSPECIFIED(&cr->addr6))
1861 bad |= 4;
1862 } else
1863 if (cr->addr == htonl(INADDR_ANY))
1864 bad |= 8;
1866 cr = (struct conf_restrict *)((char *)cr +
1867 INFO_ITEMSIZE(inpkt->mbz_itemsize));
1870 if (bad) {
1871 msyslog(LOG_ERR, "do_restrict: bad = %#x", bad);
1872 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1873 return;
1877 * Looks okay, try it out
1879 items = INFO_NITEMS(inpkt->err_nitems);
1880 cr = (struct conf_restrict *)inpkt->data;
1881 memset((char *)&matchaddr, 0, sizeof(struct sockaddr_storage));
1882 memset((char *)&matchmask, 0, sizeof(struct sockaddr_storage));
1884 while (items-- > 0) {
1885 if (client_v6_capable && cr->v6_flag != 0) {
1886 GET_INADDR6(matchaddr) = cr->addr6;
1887 GET_INADDR6(matchmask) = cr->mask6;
1888 matchaddr.ss_family = AF_INET6;
1889 matchmask.ss_family = AF_INET6;
1890 } else {
1891 GET_INADDR(matchaddr) = cr->addr;
1892 GET_INADDR(matchmask) = cr->mask;
1893 matchaddr.ss_family = AF_INET;
1894 matchmask.ss_family = AF_INET;
1896 hack_restrict(op, &matchaddr, &matchmask, cr->mflags,
1897 cr->flags);
1898 cr++;
1901 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1906 * mon_getlist - return monitor data
1908 static void
1909 mon_getlist_0(
1910 struct sockaddr_storage *srcadr,
1911 struct interface *inter,
1912 struct req_pkt *inpkt
1915 register struct info_monitor *im;
1916 register struct mon_data *md;
1917 extern struct mon_data mon_mru_list;
1918 extern int mon_enabled;
1920 #ifdef DEBUG
1921 if (debug > 2)
1922 printf("wants monitor 0 list\n");
1923 #endif
1924 if (!mon_enabled) {
1925 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1926 return;
1928 im = (struct info_monitor *)prepare_pkt(srcadr, inter, inpkt,
1929 v6sizeof(struct info_monitor));
1930 for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
1931 md = md->mru_next) {
1932 im->lasttime = htonl((u_int32)md->avg_interval);
1933 im->firsttime = htonl((u_int32)(current_time - md->lasttime));
1934 im->lastdrop = htonl((u_int32)md->drop_count);
1935 im->count = htonl((u_int32)(md->count));
1936 if (md->rmtadr.ss_family == AF_INET6) {
1937 if (!client_v6_capable)
1938 continue;
1939 im->addr6 = GET_INADDR6(md->rmtadr);
1940 im->v6_flag = 1;
1941 } else {
1942 im->addr = GET_INADDR(md->rmtadr);
1943 if (client_v6_capable)
1944 im->v6_flag = 0;
1946 im->port = md->rmtport;
1947 im->mode = md->mode;
1948 im->version = md->version;
1949 im = (struct info_monitor *)more_pkt();
1951 flush_pkt();
1955 * mon_getlist - return monitor data
1957 static void
1958 mon_getlist_1(
1959 struct sockaddr_storage *srcadr,
1960 struct interface *inter,
1961 struct req_pkt *inpkt
1964 register struct info_monitor_1 *im;
1965 register struct mon_data *md;
1966 extern struct mon_data mon_mru_list;
1967 extern int mon_enabled;
1969 if (!mon_enabled) {
1970 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1971 return;
1973 im = (struct info_monitor_1 *)prepare_pkt(srcadr, inter, inpkt,
1974 v6sizeof(struct info_monitor_1));
1975 for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
1976 md = md->mru_next) {
1977 im->lasttime = htonl((u_int32)md->avg_interval);
1978 im->firsttime = htonl((u_int32)(current_time - md->lasttime));
1979 im->lastdrop = htonl((u_int32)md->drop_count);
1980 im->count = htonl((u_int32)md->count);
1981 if (md->rmtadr.ss_family == AF_INET6) {
1982 if (!client_v6_capable)
1983 continue;
1984 im->addr6 = GET_INADDR6(md->rmtadr);
1985 im->v6_flag = 1;
1986 im->daddr6 = GET_INADDR6(md->interface->sin);
1987 } else {
1988 im->addr = GET_INADDR(md->rmtadr);
1989 if (client_v6_capable)
1990 im->v6_flag = 0;
1991 im->daddr = (md->cast_flags == MDF_BCAST)
1992 ? GET_INADDR(md->interface->bcast)
1993 : (md->cast_flags
1994 ? (GET_INADDR(md->interface->sin)
1995 ? GET_INADDR(md->interface->sin)
1996 : GET_INADDR(md->interface->bcast))
1997 : 4);
1999 im->flags = htonl(md->cast_flags);
2000 im->port = md->rmtport;
2001 im->mode = md->mode;
2002 im->version = md->version;
2003 im = (struct info_monitor_1 *)more_pkt();
2005 flush_pkt();
2009 * Module entry points and the flags they correspond with
2011 struct reset_entry {
2012 int flag; /* flag this corresponds to */
2013 void (*handler) P((void)); /* routine to handle request */
2016 struct reset_entry reset_entries[] = {
2017 { RESET_FLAG_ALLPEERS, peer_all_reset },
2018 { RESET_FLAG_IO, io_clr_stats },
2019 { RESET_FLAG_SYS, proto_clr_stats },
2020 { RESET_FLAG_MEM, peer_clr_stats },
2021 { RESET_FLAG_TIMER, timer_clr_stats },
2022 { RESET_FLAG_AUTH, reset_auth_stats },
2023 { RESET_FLAG_CTL, ctl_clr_stats },
2024 { 0, 0 }
2028 * reset_stats - reset statistic counters here and there
2030 static void
2031 reset_stats(
2032 struct sockaddr_storage *srcadr,
2033 struct interface *inter,
2034 struct req_pkt *inpkt
2037 u_long flags;
2038 struct reset_entry *rent;
2040 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2041 msyslog(LOG_ERR, "reset_stats: err_nitems > 1");
2042 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2043 return;
2046 flags = ((struct reset_flags *)inpkt->data)->flags;
2047 flags = ntohl(flags);
2049 if (flags & ~RESET_ALLFLAGS) {
2050 msyslog(LOG_ERR, "reset_stats: reset leaves %#lx",
2051 flags & ~RESET_ALLFLAGS);
2052 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2053 return;
2056 for (rent = reset_entries; rent->flag != 0; rent++) {
2057 if (flags & rent->flag)
2058 (rent->handler)();
2060 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2065 * reset_peer - clear a peer's statistics
2067 static void
2068 reset_peer(
2069 struct sockaddr_storage *srcadr,
2070 struct interface *inter,
2071 struct req_pkt *inpkt
2074 register struct conf_unpeer *cp;
2075 register int items;
2076 register struct peer *peer;
2077 struct sockaddr_storage peeraddr;
2078 int bad;
2081 * We check first to see that every peer exists. If not,
2082 * we return an error.
2085 items = INFO_NITEMS(inpkt->err_nitems);
2086 cp = (struct conf_unpeer *)inpkt->data;
2088 bad = 0;
2089 while (items-- > 0 && !bad) {
2090 memset((char *)&peeraddr, 0, sizeof(peeraddr));
2091 if (client_v6_capable && cp->v6_flag != 0) {
2092 GET_INADDR6(peeraddr) = cp->peeraddr6;
2093 peeraddr.ss_family = AF_INET6;
2094 } else {
2095 GET_INADDR(peeraddr) = cp->peeraddr;
2096 peeraddr.ss_family = AF_INET;
2098 NSRCPORT(&peeraddr) = htons(NTP_PORT);
2099 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2100 peeraddr.ss_len = SOCKLEN(&peeraddr);
2101 #endif
2102 peer = findexistingpeer(&peeraddr, (struct peer *)0, -1);
2103 if (peer == (struct peer *)0)
2104 bad++;
2105 cp = (struct conf_unpeer *)((char *)cp +
2106 INFO_ITEMSIZE(inpkt->mbz_itemsize));
2109 if (bad) {
2110 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2111 return;
2115 * Now do it in earnest.
2118 items = INFO_NITEMS(inpkt->err_nitems);
2119 cp = (struct conf_unpeer *)inpkt->data;
2120 while (items-- > 0) {
2121 memset((char *)&peeraddr, 0, sizeof(peeraddr));
2122 if (client_v6_capable && cp->v6_flag != 0) {
2123 GET_INADDR6(peeraddr) = cp->peeraddr6;
2124 peeraddr.ss_family = AF_INET6;
2125 } else {
2126 GET_INADDR(peeraddr) = cp->peeraddr;
2127 peeraddr.ss_family = AF_INET;
2129 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2130 peeraddr.ss_len = SOCKLEN(&peeraddr);
2131 #endif
2132 peer = findexistingpeer(&peeraddr, (struct peer *)0, -1);
2133 while (peer != 0) {
2134 peer_reset(peer);
2135 peer = findexistingpeer(&peeraddr, (struct peer *)peer, -1);
2137 cp = (struct conf_unpeer *)((char *)cp +
2138 INFO_ITEMSIZE(inpkt->mbz_itemsize));
2141 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2146 * do_key_reread - reread the encryption key file
2148 static void
2149 do_key_reread(
2150 struct sockaddr_storage *srcadr,
2151 struct interface *inter,
2152 struct req_pkt *inpkt
2155 rereadkeys();
2156 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2161 * trust_key - make one or more keys trusted
2163 static void
2164 trust_key(
2165 struct sockaddr_storage *srcadr,
2166 struct interface *inter,
2167 struct req_pkt *inpkt
2170 do_trustkey(srcadr, inter, inpkt, 1);
2175 * untrust_key - make one or more keys untrusted
2177 static void
2178 untrust_key(
2179 struct sockaddr_storage *srcadr,
2180 struct interface *inter,
2181 struct req_pkt *inpkt
2184 do_trustkey(srcadr, inter, inpkt, 0);
2189 * do_trustkey - make keys either trustable or untrustable
2191 static void
2192 do_trustkey(
2193 struct sockaddr_storage *srcadr,
2194 struct interface *inter,
2195 struct req_pkt *inpkt,
2196 u_long trust
2199 register u_long *kp;
2200 register int items;
2202 items = INFO_NITEMS(inpkt->err_nitems);
2203 kp = (u_long *)inpkt->data;
2204 while (items-- > 0) {
2205 authtrust(*kp, trust);
2206 kp++;
2209 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2214 * get_auth_info - return some stats concerning the authentication module
2216 static void
2217 get_auth_info(
2218 struct sockaddr_storage *srcadr,
2219 struct interface *inter,
2220 struct req_pkt *inpkt
2223 register struct info_auth *ia;
2226 * Importations from the authentication module
2228 extern u_long authnumkeys;
2229 extern int authnumfreekeys;
2230 extern u_long authkeylookups;
2231 extern u_long authkeynotfound;
2232 extern u_long authencryptions;
2233 extern u_long authdecryptions;
2234 extern u_long authkeyuncached;
2235 extern u_long authkeyexpired;
2237 ia = (struct info_auth *)prepare_pkt(srcadr, inter, inpkt,
2238 sizeof(struct info_auth));
2240 ia->numkeys = htonl((u_int32)authnumkeys);
2241 ia->numfreekeys = htonl((u_int32)authnumfreekeys);
2242 ia->keylookups = htonl((u_int32)authkeylookups);
2243 ia->keynotfound = htonl((u_int32)authkeynotfound);
2244 ia->encryptions = htonl((u_int32)authencryptions);
2245 ia->decryptions = htonl((u_int32)authdecryptions);
2246 ia->keyuncached = htonl((u_int32)authkeyuncached);
2247 ia->expired = htonl((u_int32)authkeyexpired);
2248 ia->timereset = htonl((u_int32)(current_time - auth_timereset));
2250 (void) more_pkt();
2251 flush_pkt();
2257 * reset_auth_stats - reset the authentication stat counters. Done here
2258 * to keep ntp-isms out of the authentication module
2260 static void
2261 reset_auth_stats(void)
2264 * Importations from the authentication module
2266 extern u_long authkeylookups;
2267 extern u_long authkeynotfound;
2268 extern u_long authencryptions;
2269 extern u_long authdecryptions;
2270 extern u_long authkeyuncached;
2272 authkeylookups = 0;
2273 authkeynotfound = 0;
2274 authencryptions = 0;
2275 authdecryptions = 0;
2276 authkeyuncached = 0;
2277 auth_timereset = current_time;
2282 * req_get_traps - return information about current trap holders
2284 static void
2285 req_get_traps(
2286 struct sockaddr_storage *srcadr,
2287 struct interface *inter,
2288 struct req_pkt *inpkt
2291 register struct info_trap *it;
2292 register struct ctl_trap *tr;
2293 register int i;
2296 * Imported from the control module
2298 extern struct ctl_trap ctl_trap[];
2299 extern int num_ctl_traps;
2301 if (num_ctl_traps == 0) {
2302 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2303 return;
2306 it = (struct info_trap *)prepare_pkt(srcadr, inter, inpkt,
2307 v6sizeof(struct info_trap));
2309 for (i = 0, tr = ctl_trap; i < CTL_MAXTRAPS; i++, tr++) {
2310 if (tr->tr_flags & TRAP_INUSE) {
2311 if (tr->tr_addr.ss_family == AF_INET) {
2312 if (tr->tr_localaddr == any_interface)
2313 it->local_address = 0;
2314 else
2315 it->local_address
2316 = GET_INADDR(tr->tr_localaddr->sin);
2317 it->trap_address = GET_INADDR(tr->tr_addr);
2318 if (client_v6_capable)
2319 it->v6_flag = 0;
2320 } else {
2321 if (!client_v6_capable)
2322 continue;
2323 it->local_address6
2324 = GET_INADDR6(tr->tr_localaddr->sin);
2325 it->trap_address6 = GET_INADDR6(tr->tr_addr);
2326 it->v6_flag = 1;
2328 it->trap_port = NSRCPORT(&tr->tr_addr);
2329 it->sequence = htons(tr->tr_sequence);
2330 it->settime = htonl((u_int32)(current_time - tr->tr_settime));
2331 it->origtime = htonl((u_int32)(current_time - tr->tr_origtime));
2332 it->resets = htonl((u_int32)tr->tr_resets);
2333 it->flags = htonl((u_int32)tr->tr_flags);
2334 it = (struct info_trap *)more_pkt();
2337 flush_pkt();
2342 * req_set_trap - configure a trap
2344 static void
2345 req_set_trap(
2346 struct sockaddr_storage *srcadr,
2347 struct interface *inter,
2348 struct req_pkt *inpkt
2351 do_setclr_trap(srcadr, inter, inpkt, 1);
2357 * req_clr_trap - unconfigure a trap
2359 static void
2360 req_clr_trap(
2361 struct sockaddr_storage *srcadr,
2362 struct interface *inter,
2363 struct req_pkt *inpkt
2366 do_setclr_trap(srcadr, inter, inpkt, 0);
2372 * do_setclr_trap - do the grunge work of (un)configuring a trap
2374 static void
2375 do_setclr_trap(
2376 struct sockaddr_storage *srcadr,
2377 struct interface *inter,
2378 struct req_pkt *inpkt,
2379 int set
2382 register struct conf_trap *ct;
2383 register struct interface *linter;
2384 int res;
2385 struct sockaddr_storage laddr;
2388 * Prepare sockaddr_storage structure
2390 memset((char *)&laddr, 0, sizeof laddr);
2391 laddr.ss_family = srcadr->ss_family;
2392 NSRCPORT(&laddr) = ntohs(NTP_PORT);
2395 * Restrict ourselves to one item only. This eliminates
2396 * the error reporting problem.
2398 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2399 msyslog(LOG_ERR, "do_setclr_trap: err_nitems > 1");
2400 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2401 return;
2403 ct = (struct conf_trap *)inpkt->data;
2406 * Look for the local interface. If none, use the default.
2408 if (ct->local_address == 0) {
2409 linter = any_interface;
2410 } else {
2411 if (laddr.ss_family == AF_INET)
2412 GET_INADDR(laddr) = ct->local_address;
2413 else
2414 GET_INADDR6(laddr) = ct->local_address6;
2415 linter = findinterface(&laddr);
2416 if (linter == NULL) {
2417 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2418 return;
2422 if (laddr.ss_family == AF_INET)
2423 GET_INADDR(laddr) = ct->trap_address;
2424 else
2425 GET_INADDR6(laddr) = ct->trap_address6;
2426 if (ct->trap_port != 0)
2427 NSRCPORT(&laddr) = ct->trap_port;
2428 else
2429 NSRCPORT(&laddr) = htons(TRAPPORT);
2431 if (set) {
2432 res = ctlsettrap(&laddr, linter, 0,
2433 INFO_VERSION(inpkt->rm_vn_mode));
2434 } else {
2435 res = ctlclrtrap(&laddr, linter, 0);
2438 if (!res) {
2439 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2440 } else {
2441 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2443 return;
2449 * set_request_keyid - set the keyid used to authenticate requests
2451 static void
2452 set_request_keyid(
2453 struct sockaddr_storage *srcadr,
2454 struct interface *inter,
2455 struct req_pkt *inpkt
2458 keyid_t keyid;
2461 * Restrict ourselves to one item only.
2463 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2464 msyslog(LOG_ERR, "set_request_keyid: err_nitems > 1");
2465 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2466 return;
2469 keyid = ntohl(*((u_int32 *)(inpkt->data)));
2470 info_auth_keyid = keyid;
2471 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2477 * set_control_keyid - set the keyid used to authenticate requests
2479 static void
2480 set_control_keyid(
2481 struct sockaddr_storage *srcadr,
2482 struct interface *inter,
2483 struct req_pkt *inpkt
2486 keyid_t keyid;
2487 extern keyid_t ctl_auth_keyid;
2490 * Restrict ourselves to one item only.
2492 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2493 msyslog(LOG_ERR, "set_control_keyid: err_nitems > 1");
2494 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2495 return;
2498 keyid = ntohl(*((u_int32 *)(inpkt->data)));
2499 ctl_auth_keyid = keyid;
2500 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2506 * get_ctl_stats - return some stats concerning the control message module
2508 static void
2509 get_ctl_stats(
2510 struct sockaddr_storage *srcadr,
2511 struct interface *inter,
2512 struct req_pkt *inpkt
2515 register struct info_control *ic;
2518 * Importations from the control module
2520 extern u_long ctltimereset;
2521 extern u_long numctlreq;
2522 extern u_long numctlbadpkts;
2523 extern u_long numctlresponses;
2524 extern u_long numctlfrags;
2525 extern u_long numctlerrors;
2526 extern u_long numctltooshort;
2527 extern u_long numctlinputresp;
2528 extern u_long numctlinputfrag;
2529 extern u_long numctlinputerr;
2530 extern u_long numctlbadoffset;
2531 extern u_long numctlbadversion;
2532 extern u_long numctldatatooshort;
2533 extern u_long numctlbadop;
2534 extern u_long numasyncmsgs;
2536 ic = (struct info_control *)prepare_pkt(srcadr, inter, inpkt,
2537 sizeof(struct info_control));
2539 ic->ctltimereset = htonl((u_int32)(current_time - ctltimereset));
2540 ic->numctlreq = htonl((u_int32)numctlreq);
2541 ic->numctlbadpkts = htonl((u_int32)numctlbadpkts);
2542 ic->numctlresponses = htonl((u_int32)numctlresponses);
2543 ic->numctlfrags = htonl((u_int32)numctlfrags);
2544 ic->numctlerrors = htonl((u_int32)numctlerrors);
2545 ic->numctltooshort = htonl((u_int32)numctltooshort);
2546 ic->numctlinputresp = htonl((u_int32)numctlinputresp);
2547 ic->numctlinputfrag = htonl((u_int32)numctlinputfrag);
2548 ic->numctlinputerr = htonl((u_int32)numctlinputerr);
2549 ic->numctlbadoffset = htonl((u_int32)numctlbadoffset);
2550 ic->numctlbadversion = htonl((u_int32)numctlbadversion);
2551 ic->numctldatatooshort = htonl((u_int32)numctldatatooshort);
2552 ic->numctlbadop = htonl((u_int32)numctlbadop);
2553 ic->numasyncmsgs = htonl((u_int32)numasyncmsgs);
2555 (void) more_pkt();
2556 flush_pkt();
2560 #ifdef KERNEL_PLL
2562 * get_kernel_info - get kernel pll/pps information
2564 static void
2565 get_kernel_info(
2566 struct sockaddr_storage *srcadr,
2567 struct interface *inter,
2568 struct req_pkt *inpkt
2571 register struct info_kernel *ik;
2572 struct timex ntx;
2574 if (!pll_control) {
2575 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2576 return;
2579 memset((char *)&ntx, 0, sizeof(ntx));
2580 if (ntp_adjtime(&ntx) < 0)
2581 msyslog(LOG_ERR, "get_kernel_info: ntp_adjtime() failed: %m");
2582 ik = (struct info_kernel *)prepare_pkt(srcadr, inter, inpkt,
2583 sizeof(struct info_kernel));
2586 * pll variables
2588 ik->offset = htonl((u_int32)ntx.offset);
2589 ik->freq = htonl((u_int32)ntx.freq);
2590 ik->maxerror = htonl((u_int32)ntx.maxerror);
2591 ik->esterror = htonl((u_int32)ntx.esterror);
2592 ik->status = htons(ntx.status);
2593 ik->constant = htonl((u_int32)ntx.constant);
2594 ik->precision = htonl((u_int32)ntx.precision);
2595 ik->tolerance = htonl((u_int32)ntx.tolerance);
2598 * pps variables
2600 ik->ppsfreq = htonl((u_int32)ntx.ppsfreq);
2601 ik->jitter = htonl((u_int32)ntx.jitter);
2602 ik->shift = htons(ntx.shift);
2603 ik->stabil = htonl((u_int32)ntx.stabil);
2604 ik->jitcnt = htonl((u_int32)ntx.jitcnt);
2605 ik->calcnt = htonl((u_int32)ntx.calcnt);
2606 ik->errcnt = htonl((u_int32)ntx.errcnt);
2607 ik->stbcnt = htonl((u_int32)ntx.stbcnt);
2609 (void) more_pkt();
2610 flush_pkt();
2612 #endif /* KERNEL_PLL */
2615 #ifdef REFCLOCK
2617 * get_clock_info - get info about a clock
2619 static void
2620 get_clock_info(
2621 struct sockaddr_storage *srcadr,
2622 struct interface *inter,
2623 struct req_pkt *inpkt
2626 register struct info_clock *ic;
2627 register u_int32 *clkaddr;
2628 register int items;
2629 struct refclockstat clock_stat;
2630 struct sockaddr_storage addr;
2631 struct sockaddr_in tmp_clock;
2632 l_fp ltmp;
2634 memset((char *)&addr, 0, sizeof addr);
2635 addr.ss_family = AF_INET;
2636 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2637 addr.ss_len = SOCKLEN(&addr);
2638 #endif
2639 NSRCPORT(&addr) = htons(NTP_PORT);
2640 items = INFO_NITEMS(inpkt->err_nitems);
2641 clkaddr = (u_int32 *) inpkt->data;
2643 ic = (struct info_clock *)prepare_pkt(srcadr, inter, inpkt,
2644 sizeof(struct info_clock));
2646 while (items-- > 0) {
2647 tmp_clock.sin_addr.s_addr = *clkaddr++;
2648 CAST_V4(addr)->sin_addr = tmp_clock.sin_addr;
2649 if (!ISREFCLOCKADR(&tmp_clock) ||
2650 findexistingpeer(&addr, (struct peer *)0, -1) == 0) {
2651 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2652 return;
2655 clock_stat.kv_list = (struct ctl_var *)0;
2657 refclock_control(&addr, (struct refclockstat *)0, &clock_stat);
2659 ic->clockadr = tmp_clock.sin_addr.s_addr;
2660 ic->type = clock_stat.type;
2661 ic->flags = clock_stat.flags;
2662 ic->lastevent = clock_stat.lastevent;
2663 ic->currentstatus = clock_stat.currentstatus;
2664 ic->polls = htonl((u_int32)clock_stat.polls);
2665 ic->noresponse = htonl((u_int32)clock_stat.noresponse);
2666 ic->badformat = htonl((u_int32)clock_stat.badformat);
2667 ic->baddata = htonl((u_int32)clock_stat.baddata);
2668 ic->timestarted = htonl((u_int32)clock_stat.timereset);
2669 DTOLFP(clock_stat.fudgetime1, &ltmp);
2670 HTONL_FP(&ltmp, &ic->fudgetime1);
2671 DTOLFP(clock_stat.fudgetime2, &ltmp);
2672 HTONL_FP(&ltmp, &ic->fudgetime2);
2673 ic->fudgeval1 = htonl((u_int32)clock_stat.fudgeval1);
2674 ic->fudgeval2 = htonl((u_int32)clock_stat.fudgeval2);
2676 free_varlist(clock_stat.kv_list);
2678 ic = (struct info_clock *)more_pkt();
2680 flush_pkt();
2686 * set_clock_fudge - get a clock's fudge factors
2688 static void
2689 set_clock_fudge(
2690 struct sockaddr_storage *srcadr,
2691 struct interface *inter,
2692 struct req_pkt *inpkt
2695 register struct conf_fudge *cf;
2696 register int items;
2697 struct refclockstat clock_stat;
2698 struct sockaddr_storage addr;
2699 struct sockaddr_in tmp_clock;
2700 l_fp ltmp;
2702 memset((char *)&addr, 0, sizeof addr);
2703 memset((char *)&clock_stat, 0, sizeof clock_stat);
2704 memset((char *)&tmp_clock, 0, sizeof tmp_clock);
2705 items = INFO_NITEMS(inpkt->err_nitems);
2706 cf = (struct conf_fudge *) inpkt->data;
2708 while (items-- > 0) {
2709 tmp_clock.sin_addr.s_addr = cf->clockadr;
2710 *CAST_V4(addr) = tmp_clock;
2711 addr.ss_family = AF_INET;
2712 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2713 addr.ss_len = SOCKLEN(&addr);
2714 #endif
2715 NSRCPORT(&addr) = htons(NTP_PORT);
2716 if (!ISREFCLOCKADR(&tmp_clock) ||
2717 findexistingpeer(&addr, (struct peer *)0, -1) == 0) {
2718 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2719 return;
2722 switch(ntohl(cf->which)) {
2723 case FUDGE_TIME1:
2724 NTOHL_FP(&cf->fudgetime, &ltmp);
2725 LFPTOD(&ltmp, clock_stat.fudgetime1);
2726 clock_stat.haveflags = CLK_HAVETIME1;
2727 break;
2728 case FUDGE_TIME2:
2729 NTOHL_FP(&cf->fudgetime, &ltmp);
2730 LFPTOD(&ltmp, clock_stat.fudgetime2);
2731 clock_stat.haveflags = CLK_HAVETIME2;
2732 break;
2733 case FUDGE_VAL1:
2734 clock_stat.fudgeval1 = ntohl(cf->fudgeval_flags);
2735 clock_stat.haveflags = CLK_HAVEVAL1;
2736 break;
2737 case FUDGE_VAL2:
2738 clock_stat.fudgeval2 = ntohl(cf->fudgeval_flags);
2739 clock_stat.haveflags = CLK_HAVEVAL2;
2740 break;
2741 case FUDGE_FLAGS:
2742 clock_stat.flags = (u_char) (ntohl(cf->fudgeval_flags) & 0xf);
2743 clock_stat.haveflags =
2744 (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4);
2745 break;
2746 default:
2747 msyslog(LOG_ERR, "set_clock_fudge: default!");
2748 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2749 return;
2752 refclock_control(&addr, &clock_stat, (struct refclockstat *)0);
2755 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2757 #endif
2759 #ifdef REFCLOCK
2761 * get_clkbug_info - get debugging info about a clock
2763 static void
2764 get_clkbug_info(
2765 struct sockaddr_storage *srcadr,
2766 struct interface *inter,
2767 struct req_pkt *inpkt
2770 register int i;
2771 register struct info_clkbug *ic;
2772 register u_int32 *clkaddr;
2773 register int items;
2774 struct refclockbug bug;
2775 struct sockaddr_storage addr;
2776 struct sockaddr_in tmp_clock;
2778 memset((char *)&addr, 0, sizeof addr);
2779 addr.ss_family = AF_INET;
2780 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2781 addr.ss_len = SOCKLEN(&addr);
2782 #endif
2783 NSRCPORT(&addr) = htons(NTP_PORT);
2784 items = INFO_NITEMS(inpkt->err_nitems);
2785 clkaddr = (u_int32 *) inpkt->data;
2787 ic = (struct info_clkbug *)prepare_pkt(srcadr, inter, inpkt,
2788 sizeof(struct info_clkbug));
2790 while (items-- > 0) {
2791 tmp_clock.sin_addr.s_addr = *clkaddr++;
2792 GET_INADDR(addr) = tmp_clock.sin_addr.s_addr;
2793 if (!ISREFCLOCKADR(&tmp_clock) ||
2794 findexistingpeer(&addr, (struct peer *)0, -1) == 0) {
2795 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2796 return;
2799 memset((char *)&bug, 0, sizeof bug);
2800 refclock_buginfo(&addr, &bug);
2801 if (bug.nvalues == 0 && bug.ntimes == 0) {
2802 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2803 return;
2806 ic->clockadr = tmp_clock.sin_addr.s_addr;
2807 i = bug.nvalues;
2808 if (i > NUMCBUGVALUES)
2809 i = NUMCBUGVALUES;
2810 ic->nvalues = (u_char)i;
2811 ic->svalues = htons((u_short) (bug.svalues & ((1<<i)-1)));
2812 while (--i >= 0)
2813 ic->values[i] = htonl(bug.values[i]);
2815 i = bug.ntimes;
2816 if (i > NUMCBUGTIMES)
2817 i = NUMCBUGTIMES;
2818 ic->ntimes = (u_char)i;
2819 ic->stimes = htonl(bug.stimes);
2820 while (--i >= 0) {
2821 HTONL_FP(&bug.times[i], &ic->times[i]);
2824 ic = (struct info_clkbug *)more_pkt();
2826 flush_pkt();
2828 #endif
2831 * receiver of interface structures
2833 static void
2834 fill_info_if_stats(void *data, interface_info_t *interface_info)
2836 struct info_if_stats **ifsp = (struct info_if_stats **)data;
2837 struct info_if_stats *ifs = *ifsp;
2838 struct interface *interface = interface_info->interface;
2840 memset((char*)ifs, 0, sizeof(*ifs));
2842 if (interface->sin.ss_family == AF_INET6) {
2843 if (!client_v6_capable) {
2844 return;
2846 ifs->v6_flag = 1;
2847 memcpy((char *)&ifs->unaddr.addr6, (char *)&CAST_V6(interface->sin)->sin6_addr, sizeof(struct in6_addr));
2848 memcpy((char *)&ifs->unbcast.addr6, (char *)&CAST_V6(interface->bcast)->sin6_addr, sizeof(struct in6_addr));
2849 memcpy((char *)&ifs->unmask.addr6, (char *)&CAST_V6(interface->mask)->sin6_addr, sizeof(struct in6_addr));
2850 } else {
2851 ifs->v6_flag = 0;
2852 memcpy((char *)&ifs->unaddr.addr, (char *)&CAST_V4(interface->sin)->sin_addr, sizeof(struct in_addr));
2853 memcpy((char *)&ifs->unbcast.addr, (char *)&CAST_V4(interface->bcast)->sin_addr, sizeof(struct in_addr));
2854 memcpy((char *)&ifs->unmask.addr, (char *)&CAST_V4(interface->mask)->sin_addr, sizeof(struct in_addr));
2856 ifs->v6_flag = htonl(ifs->v6_flag);
2857 strcpy(ifs->name, interface->name);
2858 ifs->family = htons(interface->family);
2859 ifs->flags = htonl(interface->flags);
2860 ifs->last_ttl = htonl(interface->last_ttl);
2861 ifs->num_mcast = htonl(interface->num_mcast);
2862 ifs->received = htonl(interface->received);
2863 ifs->sent = htonl(interface->sent);
2864 ifs->notsent = htonl(interface->notsent);
2865 ifs->scopeid = htonl(interface->scopeid);
2866 ifs->ifindex = htonl(interface->ifindex);
2867 ifs->ifnum = htonl(interface->ifnum);
2868 ifs->uptime = htonl(current_time - interface->starttime);
2869 ifs->ignore_packets = interface->ignore_packets;
2870 ifs->peercnt = htonl(interface->peercnt);
2871 ifs->action = interface_info->action;
2873 *ifsp = (struct info_if_stats *)more_pkt();
2877 * get_if_stats - get interface statistics
2879 static void
2880 get_if_stats(
2881 struct sockaddr_storage *srcadr,
2882 struct interface *inter,
2883 struct req_pkt *inpkt
2886 struct info_if_stats *ifs;
2888 DPRINTF(3, ("wants interface statistics\n"));
2890 ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt,
2891 v6sizeof(struct info_if_stats));
2893 interface_enumerate(fill_info_if_stats, &ifs);
2895 flush_pkt();
2898 static void
2899 do_if_reload(
2900 struct sockaddr_storage *srcadr,
2901 struct interface *inter,
2902 struct req_pkt *inpkt
2905 struct info_if_stats *ifs;
2907 DPRINTF(3, ("wants interface reload\n"));
2909 ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt,
2910 v6sizeof(struct info_if_stats));
2912 interface_update(fill_info_if_stats, &ifs);
2914 flush_pkt();