Obfuscate RCS ID matching so that CVS doesn't expand it.
[netbsd-mini2440.git] / dist / ntp / ntpd / ntp_request.c
blob30e0b8296cb9f1fc19cb50044a36a87db669c0e9
1 /* $NetBSD: ntp_request.c,v 1.8 2008/08/23 09:10:31 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 struct req_pkt *inpkt;
415 struct req_pkt_tail *tailinpkt;
416 struct sockaddr_storage *srcadr;
417 struct interface *inter;
418 struct req_proc *proc;
419 int ec;
420 short temp_size;
423 * Initialize pointers, for convenience
425 inpkt = (struct req_pkt *)&rbufp->recv_pkt;
426 srcadr = &rbufp->recv_srcadr;
427 inter = rbufp->dstadr;
429 #ifdef DEBUG
430 if (debug > 2)
431 printf("process_private: impl %d req %d\n",
432 inpkt->implementation, inpkt->request);
433 #endif
436 * Do some sanity checks on the packet. Return a format
437 * error if it fails.
439 ec = 0;
440 if ( (++ec, ISRESPONSE(inpkt->rm_vn_mode))
441 || (++ec, ISMORE(inpkt->rm_vn_mode))
442 || (++ec, INFO_VERSION(inpkt->rm_vn_mode) > NTP_VERSION)
443 || (++ec, INFO_VERSION(inpkt->rm_vn_mode) < NTP_OLDVERSION)
444 || (++ec, INFO_SEQ(inpkt->auth_seq) != 0)
445 || (++ec, INFO_ERR(inpkt->err_nitems) != 0)
446 || (++ec, INFO_MBZ(inpkt->mbz_itemsize) != 0)
447 || (++ec, rbufp->recv_length < REQ_LEN_HDR)
449 msyslog(LOG_ERR, "process_private: INFO_ERR_FMT: test %d failed, pkt from %s", ec, stoa(srcadr));
450 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
451 return;
454 reqver = INFO_VERSION(inpkt->rm_vn_mode);
457 * Get the appropriate procedure list to search.
459 if (inpkt->implementation == IMPL_UNIV)
460 proc = univ_codes;
461 else if ((inpkt->implementation == IMPL_XNTPD) ||
462 (inpkt->implementation == IMPL_XNTPD_OLD))
463 proc = ntp_codes;
464 else {
465 req_ack(srcadr, inter, inpkt, INFO_ERR_IMPL);
466 return;
470 * Search the list for the request codes. If it isn't one
471 * we know, return an error.
473 while (proc->request_code != NO_REQUEST) {
474 if (proc->request_code == (short) inpkt->request)
475 break;
476 proc++;
478 if (proc->request_code == NO_REQUEST) {
479 req_ack(srcadr, inter, inpkt, INFO_ERR_REQ);
480 return;
483 #ifdef DEBUG
484 if (debug > 3)
485 printf("found request in tables\n");
486 #endif
489 * If we need data, check to see if we have some. If we
490 * don't, check to see that there is none (picky, picky).
493 /* This part is a bit tricky, we want to be sure that the size
494 * returned is either the old or the new size. We also can find
495 * out if the client can accept both types of messages this way.
497 * Handle the exception of REQ_CONFIG. It can have two data sizes.
499 temp_size = INFO_ITEMSIZE(inpkt->mbz_itemsize);
500 if ((temp_size != proc->sizeofitem &&
501 temp_size != proc->v6_sizeofitem) &&
502 !(inpkt->implementation == IMPL_XNTPD &&
503 inpkt->request == REQ_CONFIG &&
504 temp_size == sizeof(struct old_conf_peer))) {
505 #ifdef DEBUG
506 if (debug > 2)
507 printf("process_private: wrong item size, received %d, should be %d or %d\n",
508 temp_size, proc->sizeofitem, proc->v6_sizeofitem);
509 #endif
510 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
511 return;
513 if ((proc->sizeofitem != 0) &&
514 ((temp_size * INFO_NITEMS(inpkt->err_nitems)) >
515 (rbufp->recv_length - REQ_LEN_HDR))) {
516 #ifdef DEBUG
517 if (debug > 2)
518 printf("process_private: not enough data\n");
519 #endif
520 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
521 return;
524 switch (inpkt->implementation) {
525 case IMPL_XNTPD:
526 client_v6_capable = 1;
527 break;
528 case IMPL_XNTPD_OLD:
529 client_v6_capable = 0;
530 break;
531 default:
532 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
533 return;
537 * If we need to authenticate, do so. Note that an
538 * authenticatable packet must include a mac field, must
539 * have used key info_auth_keyid and must have included
540 * a time stamp in the appropriate field. The time stamp
541 * must be within INFO_TS_MAXSKEW of the receive
542 * time stamp.
544 if (proc->needs_auth && sys_authenticate) {
545 l_fp ftmp;
546 double dtemp;
548 if (rbufp->recv_length < (int)((REQ_LEN_HDR +
549 (INFO_ITEMSIZE(inpkt->mbz_itemsize) *
550 INFO_NITEMS(inpkt->err_nitems))
551 + sizeof(struct req_pkt_tail)))) {
552 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
554 tailinpkt = (struct req_pkt_tail *)((char *)&rbufp->recv_pkt +
555 rbufp->recv_length - sizeof(struct req_pkt_tail));
558 * If this guy is restricted from doing this, don't let him
559 * If wrong key was used, or packet doesn't have mac, return.
561 if (!INFO_IS_AUTH(inpkt->auth_seq) || info_auth_keyid == 0
562 || ntohl(tailinpkt->keyid) != info_auth_keyid) {
563 #ifdef DEBUG
564 if (debug > 4)
565 printf("failed auth %d info_auth_keyid %lu pkt keyid %lu\n",
566 INFO_IS_AUTH(inpkt->auth_seq),
567 (u_long)info_auth_keyid,
568 (u_long)ntohl(tailinpkt->keyid));
569 msyslog(LOG_DEBUG,
570 "process_private: failed auth %d info_auth_keyid %lu pkt keyid %lu\n",
571 INFO_IS_AUTH(inpkt->auth_seq),
572 (u_long)info_auth_keyid,
573 (u_long)ntohl(tailinpkt->keyid));
574 #endif
575 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
576 return;
578 if (rbufp->recv_length > REQ_LEN_MAC) {
579 #ifdef DEBUG
580 if (debug > 4)
581 printf("bad pkt length %d\n",
582 rbufp->recv_length);
583 #endif
584 msyslog(LOG_ERR, "process_private: bad pkt length %d",
585 rbufp->recv_length);
586 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
587 return;
589 if (!mod_okay || !authhavekey(info_auth_keyid)) {
590 #ifdef DEBUG
591 if (debug > 4)
592 printf("failed auth mod_okay %d\n", mod_okay);
593 msyslog(LOG_DEBUG,
594 "process_private: failed auth mod_okay %d\n",
595 mod_okay);
596 #endif
597 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
598 return;
602 * calculate absolute time difference between xmit time stamp
603 * and receive time stamp. If too large, too bad.
605 NTOHL_FP(&tailinpkt->tstamp, &ftmp);
606 L_SUB(&ftmp, &rbufp->recv_time);
607 LFPTOD(&ftmp, dtemp);
608 if (fabs(dtemp) >= INFO_TS_MAXSKEW) {
610 * He's a loser. Tell him.
612 #ifdef DEBUG
613 if (debug > 4)
614 printf("xmit/rcv timestamp delta > INFO_TS_MAXSKEW\n");
615 #endif
616 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
617 return;
621 * So far so good. See if decryption works out okay.
623 if (!authdecrypt(info_auth_keyid, (u_int32 *)inpkt,
624 rbufp->recv_length - sizeof(struct req_pkt_tail) +
625 REQ_LEN_HDR, sizeof(struct req_pkt_tail) - REQ_LEN_HDR)) {
626 #ifdef DEBUG
627 if (debug > 4)
628 printf("authdecrypt failed\n");
629 #endif
630 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
631 return;
635 #ifdef DEBUG
636 if (debug > 3)
637 printf("process_private: all okay, into handler\n");
638 #endif
641 * Packet is okay. Call the handler to send him data.
643 (proc->handler)(srcadr, inter, inpkt);
648 * peer_list - send a list of the peers
650 static void
651 peer_list(
652 struct sockaddr_storage *srcadr,
653 struct interface *inter,
654 struct req_pkt *inpkt
657 register struct info_peer_list *ip;
658 register struct peer *pp;
659 register int i;
660 register int skip = 0;
662 ip = (struct info_peer_list *)prepare_pkt(srcadr, inter, inpkt,
663 v6sizeof(struct info_peer_list));
664 for (i = 0; i < NTP_HASH_SIZE && ip != 0; i++) {
665 pp = peer_hash[i];
666 while (pp != 0 && ip != 0) {
667 if (pp->srcadr.ss_family == AF_INET6) {
668 if (client_v6_capable) {
669 ip->addr6 = GET_INADDR6(pp->srcadr);
670 ip->v6_flag = 1;
671 skip = 0;
672 } else {
673 skip = 1;
674 break;
676 } else {
677 ip->addr = GET_INADDR(pp->srcadr);
678 if (client_v6_capable)
679 ip->v6_flag = 0;
680 skip = 0;
683 if(!skip) {
684 ip->port = NSRCPORT(&pp->srcadr);
685 ip->hmode = pp->hmode;
686 ip->flags = 0;
687 if (pp->flags & FLAG_CONFIG)
688 ip->flags |= INFO_FLAG_CONFIG;
689 if (pp == sys_peer)
690 ip->flags |= INFO_FLAG_SYSPEER;
691 if (pp->status == CTL_PST_SEL_SYNCCAND)
692 ip->flags |= INFO_FLAG_SEL_CANDIDATE;
693 if (pp->status >= CTL_PST_SEL_SYSPEER)
694 ip->flags |= INFO_FLAG_SHORTLIST;
695 ip = (struct info_peer_list *)more_pkt();
697 pp = pp->next;
700 flush_pkt();
705 * peer_list_sum - return extended peer list
707 static void
708 peer_list_sum(
709 struct sockaddr_storage *srcadr,
710 struct interface *inter,
711 struct req_pkt *inpkt
714 register struct info_peer_summary *ips;
715 register struct peer *pp;
716 register int i;
717 l_fp ltmp;
718 register int skip;
720 #ifdef DEBUG
721 if (debug > 2)
722 printf("wants peer list summary\n");
723 #endif
724 ips = (struct info_peer_summary *)prepare_pkt(srcadr, inter, inpkt,
725 v6sizeof(struct info_peer_summary));
726 for (i = 0; i < NTP_HASH_SIZE && ips != 0; i++) {
727 pp = peer_hash[i];
728 while (pp != 0 && ips != 0) {
729 #ifdef DEBUG
730 if (debug > 3)
731 printf("sum: got one\n");
732 #endif
734 * Be careful here not to return v6 peers when we
735 * want only v4.
737 if (pp->srcadr.ss_family == AF_INET6) {
738 if (client_v6_capable) {
739 ips->srcadr6 = GET_INADDR6(pp->srcadr);
740 ips->v6_flag = 1;
741 if (pp->dstadr)
742 ips->dstadr6 = GET_INADDR6(pp->dstadr->sin);
743 else
744 memset(&ips->dstadr6, 0, sizeof(ips->dstadr6));
745 skip = 0;
746 } else {
747 skip = 1;
748 break;
750 } else {
751 ips->srcadr = GET_INADDR(pp->srcadr);
752 if (client_v6_capable)
753 ips->v6_flag = 0;
754 /* XXX PDM This code is buggy. Need to replace with a straightforward assignment */
756 if (pp->dstadr)
757 ips->dstadr = (pp->processed) ?
758 pp->cast_flags == MDF_BCAST ?
759 GET_INADDR(pp->dstadr->bcast):
760 pp->cast_flags ?
761 GET_INADDR(pp->dstadr->sin) ?
762 GET_INADDR(pp->dstadr->sin):
763 GET_INADDR(pp->dstadr->bcast):
764 1 : GET_INADDR(pp->dstadr->sin);
765 else
766 memset(&ips->dstadr, 0, sizeof(ips->dstadr));
768 skip = 0;
771 if (!skip){
772 ips->srcport = NSRCPORT(&pp->srcadr);
773 ips->stratum = pp->stratum;
774 ips->hpoll = pp->hpoll;
775 ips->ppoll = pp->ppoll;
776 ips->reach = pp->reach;
777 ips->flags = 0;
778 if (pp == sys_peer)
779 ips->flags |= INFO_FLAG_SYSPEER;
780 if (pp->flags & FLAG_CONFIG)
781 ips->flags |= INFO_FLAG_CONFIG;
782 if (pp->flags & FLAG_REFCLOCK)
783 ips->flags |= INFO_FLAG_REFCLOCK;
784 if (pp->flags & FLAG_AUTHENABLE)
785 ips->flags |= INFO_FLAG_AUTHENABLE;
786 if (pp->flags & FLAG_PREFER)
787 ips->flags |= INFO_FLAG_PREFER;
788 if (pp->flags & FLAG_BURST)
789 ips->flags |= INFO_FLAG_BURST;
790 if (pp->status == CTL_PST_SEL_SYNCCAND)
791 ips->flags |= INFO_FLAG_SEL_CANDIDATE;
792 if (pp->status >= CTL_PST_SEL_SYSPEER)
793 ips->flags |= INFO_FLAG_SHORTLIST;
794 ips->hmode = pp->hmode;
795 ips->delay = HTONS_FP(DTOFP(pp->delay));
796 DTOLFP(pp->offset, &ltmp);
797 HTONL_FP(&ltmp, &ips->offset);
798 ips->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp)));
800 pp = pp->next;
801 ips = (struct info_peer_summary *)more_pkt();
804 flush_pkt();
809 * peer_info - send information for one or more peers
811 static void
812 peer_info (
813 struct sockaddr_storage *srcadr,
814 struct interface *inter,
815 struct req_pkt *inpkt
818 register struct info_peer_list *ipl;
819 register struct peer *pp;
820 register struct info_peer *ip;
821 register int items;
822 register int i, j;
823 struct sockaddr_storage addr;
824 extern struct peer *sys_peer;
825 l_fp ltmp;
827 memset((char *)&addr, 0, sizeof addr);
828 items = INFO_NITEMS(inpkt->err_nitems);
829 ipl = (struct info_peer_list *) inpkt->data;
831 ip = (struct info_peer *)prepare_pkt(srcadr, inter, inpkt,
832 v6sizeof(struct info_peer));
833 while (items-- > 0 && ip != 0) {
834 memset((char *)&addr, 0, sizeof(addr));
835 NSRCPORT(&addr) = ipl->port;
836 if (client_v6_capable && ipl->v6_flag != 0) {
837 addr.ss_family = AF_INET6;
838 GET_INADDR6(addr) = ipl->addr6;
839 } else {
840 addr.ss_family = AF_INET;
841 GET_INADDR(addr) = ipl->addr;
843 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
844 addr.ss_len = SOCKLEN(&addr);
845 #endif
846 ipl++;
847 if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0)
848 continue;
849 if (pp->srcadr.ss_family == AF_INET6) {
850 if (pp->dstadr)
851 ip->dstadr6 = pp->cast_flags == MDF_BCAST ?
852 GET_INADDR6(pp->dstadr->bcast) :
853 GET_INADDR6(pp->dstadr->sin);
854 else
855 memset(&ip->dstadr6, 0, sizeof(ip->dstadr6));
857 ip->srcadr6 = GET_INADDR6(pp->srcadr);
858 ip->v6_flag = 1;
859 } else {
860 /* XXX PDM This code is buggy. Need to replace with a straightforward assignment */
861 if (pp->dstadr)
862 ip->dstadr = (pp->processed) ?
863 pp->cast_flags == MDF_BCAST ?
864 GET_INADDR(pp->dstadr->bcast):
865 pp->cast_flags ?
866 GET_INADDR(pp->dstadr->sin) ?
867 GET_INADDR(pp->dstadr->sin):
868 GET_INADDR(pp->dstadr->bcast):
869 2 : GET_INADDR(pp->dstadr->sin);
870 else
871 memset(&ip->dstadr, 0, sizeof(ip->dstadr));
873 ip->srcadr = GET_INADDR(pp->srcadr);
874 if (client_v6_capable)
875 ip->v6_flag = 0;
877 ip->srcport = NSRCPORT(&pp->srcadr);
878 ip->flags = 0;
879 if (pp == sys_peer)
880 ip->flags |= INFO_FLAG_SYSPEER;
881 if (pp->flags & FLAG_CONFIG)
882 ip->flags |= INFO_FLAG_CONFIG;
883 if (pp->flags & FLAG_REFCLOCK)
884 ip->flags |= INFO_FLAG_REFCLOCK;
885 if (pp->flags & FLAG_AUTHENABLE)
886 ip->flags |= INFO_FLAG_AUTHENABLE;
887 if (pp->flags & FLAG_PREFER)
888 ip->flags |= INFO_FLAG_PREFER;
889 if (pp->flags & FLAG_BURST)
890 ip->flags |= INFO_FLAG_BURST;
891 if (pp->status == CTL_PST_SEL_SYNCCAND)
892 ip->flags |= INFO_FLAG_SEL_CANDIDATE;
893 if (pp->status >= CTL_PST_SEL_SYSPEER)
894 ip->flags |= INFO_FLAG_SHORTLIST;
895 ip->leap = pp->leap;
896 ip->hmode = pp->hmode;
897 ip->keyid = pp->keyid;
898 ip->stratum = pp->stratum;
899 ip->ppoll = pp->ppoll;
900 ip->hpoll = pp->hpoll;
901 ip->precision = pp->precision;
902 ip->version = pp->version;
903 ip->reach = pp->reach;
904 ip->unreach = (u_char) pp->unreach;
905 ip->flash = (u_char)pp->flash;
906 ip->flash2 = (u_short) pp->flash;
907 ip->estbdelay = HTONS_FP(DTOFP(pp->estbdelay));
908 ip->ttl = pp->ttl;
909 ip->associd = htons(pp->associd);
910 ip->rootdelay = HTONS_FP(DTOUFP(pp->rootdelay));
911 ip->rootdispersion = HTONS_FP(DTOUFP(pp->rootdispersion));
912 ip->refid = pp->refid;
913 HTONL_FP(&pp->reftime, &ip->reftime);
914 HTONL_FP(&pp->org, &ip->org);
915 HTONL_FP(&pp->rec, &ip->rec);
916 HTONL_FP(&pp->xmt, &ip->xmt);
917 j = pp->filter_nextpt - 1;
918 for (i = 0; i < NTP_SHIFT; i++, j--) {
919 if (j < 0)
920 j = NTP_SHIFT-1;
921 ip->filtdelay[i] = HTONS_FP(DTOFP(pp->filter_delay[j]));
922 DTOLFP(pp->filter_offset[j], &ltmp);
923 HTONL_FP(&ltmp, &ip->filtoffset[i]);
924 ip->order[i] = (u_char)((pp->filter_nextpt+NTP_SHIFT-1)
925 - pp->filter_order[i]);
926 if (ip->order[i] >= NTP_SHIFT)
927 ip->order[i] -= NTP_SHIFT;
929 DTOLFP(pp->offset, &ltmp);
930 HTONL_FP(&ltmp, &ip->offset);
931 ip->delay = HTONS_FP(DTOFP(pp->delay));
932 ip->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp)));
933 ip->selectdisp = HTONS_FP(DTOUFP(SQRT(pp->jitter)));
934 ip = (struct info_peer *)more_pkt();
936 flush_pkt();
941 * peer_stats - send statistics for one or more peers
943 static void
944 peer_stats (
945 struct sockaddr_storage *srcadr,
946 struct interface *inter,
947 struct req_pkt *inpkt
950 register struct info_peer_list *ipl;
951 register struct peer *pp;
952 register struct info_peer_stats *ip;
953 register int items;
954 struct sockaddr_storage addr;
955 extern struct peer *sys_peer;
957 #ifdef DEBUG
958 if (debug)
959 printf("peer_stats: called\n");
960 #endif
961 items = INFO_NITEMS(inpkt->err_nitems);
962 ipl = (struct info_peer_list *) inpkt->data;
963 ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt,
964 v6sizeof(struct info_peer_stats));
965 while (items-- > 0 && ip != 0) {
966 memset((char *)&addr, 0, sizeof(addr));
967 NSRCPORT(&addr) = ipl->port;
968 if (client_v6_capable && ipl->v6_flag) {
969 addr.ss_family = AF_INET6;
970 GET_INADDR6(addr) = ipl->addr6;
971 } else {
972 addr.ss_family = AF_INET;
973 GET_INADDR(addr) = ipl->addr;
975 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
976 addr.ss_len = SOCKLEN(&addr);
977 #endif
978 #ifdef DEBUG
979 if (debug)
980 printf("peer_stats: looking for %s, %d, %d\n", stoa(&addr),
981 ipl->port, ((struct sockaddr_in6 *)&addr)->sin6_port);
982 #endif
983 ipl = (struct info_peer_list *)((char *)ipl +
984 INFO_ITEMSIZE(inpkt->mbz_itemsize));
986 if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0)
987 continue;
988 #ifdef DEBUG
989 if (debug)
990 printf("peer_stats: found %s\n", stoa(&addr));
991 #endif
992 if (pp->srcadr.ss_family == AF_INET) {
993 if (pp->dstadr)
994 ip->dstadr = (pp->processed) ?
995 pp->cast_flags == MDF_BCAST ?
996 GET_INADDR(pp->dstadr->bcast):
997 pp->cast_flags ?
998 GET_INADDR(pp->dstadr->sin) ?
999 GET_INADDR(pp->dstadr->sin):
1000 GET_INADDR(pp->dstadr->bcast):
1001 3 : 7;
1002 else
1003 memset(&ip->dstadr, 0, sizeof(ip->dstadr));
1005 ip->srcadr = GET_INADDR(pp->srcadr);
1006 if (client_v6_capable)
1007 ip->v6_flag = 0;
1008 } else {
1009 if (pp->dstadr)
1010 ip->dstadr6 = pp->cast_flags == MDF_BCAST ?
1011 GET_INADDR6(pp->dstadr->bcast):
1012 GET_INADDR6(pp->dstadr->sin);
1013 else
1014 memset(&ip->dstadr6, 0, sizeof(ip->dstadr6));
1016 ip->srcadr6 = GET_INADDR6(pp->srcadr);
1017 ip->v6_flag = 1;
1019 ip->srcport = NSRCPORT(&pp->srcadr);
1020 ip->flags = 0;
1021 if (pp == sys_peer)
1022 ip->flags |= INFO_FLAG_SYSPEER;
1023 if (pp->flags & FLAG_CONFIG)
1024 ip->flags |= INFO_FLAG_CONFIG;
1025 if (pp->flags & FLAG_REFCLOCK)
1026 ip->flags |= INFO_FLAG_REFCLOCK;
1027 if (pp->flags & FLAG_AUTHENABLE)
1028 ip->flags |= INFO_FLAG_AUTHENABLE;
1029 if (pp->flags & FLAG_PREFER)
1030 ip->flags |= INFO_FLAG_PREFER;
1031 if (pp->flags & FLAG_BURST)
1032 ip->flags |= INFO_FLAG_BURST;
1033 if (pp->flags & FLAG_IBURST)
1034 ip->flags |= INFO_FLAG_IBURST;
1035 if (pp->status == CTL_PST_SEL_SYNCCAND)
1036 ip->flags |= INFO_FLAG_SEL_CANDIDATE;
1037 if (pp->status >= CTL_PST_SEL_SYSPEER)
1038 ip->flags |= INFO_FLAG_SHORTLIST;
1039 ip->flags = htons(ip->flags);
1040 ip->timereceived = htonl((u_int32)(current_time - pp->timereceived));
1041 ip->timetosend = htonl(pp->nextdate - current_time);
1042 ip->timereachable = htonl((u_int32)(current_time - pp->timereachable));
1043 ip->sent = htonl((u_int32)(pp->sent));
1044 ip->processed = htonl((u_int32)(pp->processed));
1045 ip->badauth = htonl((u_int32)(pp->badauth));
1046 ip->bogusorg = htonl((u_int32)(pp->bogusorg));
1047 ip->oldpkt = htonl((u_int32)(pp->oldpkt));
1048 ip->seldisp = htonl((u_int32)(pp->seldisptoolarge));
1049 ip->selbroken = htonl((u_int32)(pp->selbroken));
1050 ip->candidate = pp->status;
1051 ip = (struct info_peer_stats *)more_pkt();
1053 flush_pkt();
1058 * sys_info - return system info
1060 static void
1061 sys_info(
1062 struct sockaddr_storage *srcadr,
1063 struct interface *inter,
1064 struct req_pkt *inpkt
1067 register struct info_sys *is;
1069 is = (struct info_sys *)prepare_pkt(srcadr, inter, inpkt,
1070 v6sizeof(struct info_sys));
1072 if (sys_peer != 0) {
1073 if (sys_peer->srcadr.ss_family == AF_INET) {
1074 is->peer = GET_INADDR(sys_peer->srcadr);
1075 if (client_v6_capable)
1076 is->v6_flag = 0;
1077 } else if (client_v6_capable) {
1078 is->peer6 = GET_INADDR6(sys_peer->srcadr);
1079 is->v6_flag = 1;
1081 is->peer_mode = sys_peer->hmode;
1082 } else {
1083 is->peer = 0;
1084 if (client_v6_capable) {
1085 is->v6_flag = 0;
1087 is->peer_mode = 0;
1090 is->leap = sys_leap;
1091 is->stratum = sys_stratum;
1092 is->precision = sys_precision;
1093 is->rootdelay = htonl(DTOFP(sys_rootdelay));
1094 is->rootdispersion = htonl(DTOUFP(sys_rootdispersion));
1095 is->frequency = htonl(DTOFP(sys_jitter));
1096 is->stability = htonl(DTOUFP(clock_stability));
1097 is->refid = sys_refid;
1098 HTONL_FP(&sys_reftime, &is->reftime);
1100 is->poll = sys_poll;
1102 is->flags = 0;
1103 if (sys_authenticate)
1104 is->flags |= INFO_FLAG_AUTHENTICATE;
1105 if (sys_bclient)
1106 is->flags |= INFO_FLAG_BCLIENT;
1107 #ifdef REFCLOCK
1108 if (cal_enable)
1109 is->flags |= INFO_FLAG_CAL;
1110 #endif /* REFCLOCK */
1111 if (kern_enable)
1112 is->flags |= INFO_FLAG_KERNEL;
1113 if (mon_enabled != MON_OFF)
1114 is->flags |= INFO_FLAG_MONITOR;
1115 if (ntp_enable)
1116 is->flags |= INFO_FLAG_NTP;
1117 if (pps_enable)
1118 is->flags |= INFO_FLAG_PPS_SYNC;
1119 if (stats_control)
1120 is->flags |= INFO_FLAG_FILEGEN;
1121 is->bdelay = HTONS_FP(DTOFP(sys_bdelay));
1122 HTONL_UF(sys_authdelay.l_f, &is->authdelay);
1124 (void) more_pkt();
1125 flush_pkt();
1130 * sys_stats - return system statistics
1132 static void
1133 sys_stats(
1134 struct sockaddr_storage *srcadr,
1135 struct interface *inter,
1136 struct req_pkt *inpkt
1139 register struct info_sys_stats *ss;
1142 * Importations from the protocol module
1144 ss = (struct info_sys_stats *)prepare_pkt(srcadr, inter, inpkt,
1145 sizeof(struct info_sys_stats));
1146 ss->timeup = htonl((u_int32)current_time);
1147 ss->timereset = htonl((u_int32)(current_time - sys_stattime));
1148 ss->denied = htonl((u_int32)sys_restricted);
1149 ss->oldversionpkt = htonl((u_int32)sys_oldversionpkt);
1150 ss->newversionpkt = htonl((u_int32)sys_newversionpkt);
1151 ss->unknownversion = htonl((u_int32)sys_unknownversion);
1152 ss->badlength = htonl((u_int32)sys_badlength);
1153 ss->processed = htonl((u_int32)sys_processed);
1154 ss->badauth = htonl((u_int32)sys_badauth);
1155 ss->limitrejected = htonl((u_int32)sys_limitrejected);
1156 ss->received = htonl((u_int32)sys_received);
1157 (void) more_pkt();
1158 flush_pkt();
1163 * mem_stats - return memory statistics
1165 static void
1166 mem_stats(
1167 struct sockaddr_storage *srcadr,
1168 struct interface *inter,
1169 struct req_pkt *inpkt
1172 register struct info_mem_stats *ms;
1173 register int i;
1176 * Importations from the peer module
1178 extern int peer_hash_count[];
1179 extern int peer_free_count;
1180 extern u_long peer_timereset;
1181 extern u_long findpeer_calls;
1182 extern u_long peer_allocations;
1183 extern u_long peer_demobilizations;
1184 extern int total_peer_structs;
1186 ms = (struct info_mem_stats *)prepare_pkt(srcadr, inter, inpkt,
1187 sizeof(struct info_mem_stats));
1189 ms->timereset = htonl((u_int32)(current_time - peer_timereset));
1190 ms->totalpeermem = htons((u_short)total_peer_structs);
1191 ms->freepeermem = htons((u_short)peer_free_count);
1192 ms->findpeer_calls = htonl((u_int32)findpeer_calls);
1193 ms->allocations = htonl((u_int32)peer_allocations);
1194 ms->demobilizations = htonl((u_int32)peer_demobilizations);
1196 for (i = 0; i < NTP_HASH_SIZE; i++) {
1197 if (peer_hash_count[i] > 255)
1198 ms->hashcount[i] = 255;
1199 else
1200 ms->hashcount[i] = (u_char)peer_hash_count[i];
1203 (void) more_pkt();
1204 flush_pkt();
1209 * io_stats - return io statistics
1211 static void
1212 io_stats(
1213 struct sockaddr_storage *srcadr,
1214 struct interface *inter,
1215 struct req_pkt *inpkt
1218 register struct info_io_stats *io;
1221 * Importations from the io module
1223 extern u_long io_timereset;
1225 io = (struct info_io_stats *)prepare_pkt(srcadr, inter, inpkt,
1226 sizeof(struct info_io_stats));
1228 io->timereset = htonl((u_int32)(current_time - io_timereset));
1229 io->totalrecvbufs = htons((u_short) total_recvbuffs());
1230 io->freerecvbufs = htons((u_short) free_recvbuffs());
1231 io->fullrecvbufs = htons((u_short) full_recvbuffs());
1232 io->lowwater = htons((u_short) lowater_additions());
1233 io->dropped = htonl((u_int32)packets_dropped);
1234 io->ignored = htonl((u_int32)packets_ignored);
1235 io->received = htonl((u_int32)packets_received);
1236 io->sent = htonl((u_int32)packets_sent);
1237 io->notsent = htonl((u_int32)packets_notsent);
1238 io->interrupts = htonl((u_int32)handler_calls);
1239 io->int_received = htonl((u_int32)handler_pkts);
1241 (void) more_pkt();
1242 flush_pkt();
1247 * timer_stats - return timer statistics
1249 static void
1250 timer_stats(
1251 struct sockaddr_storage *srcadr,
1252 struct interface *inter,
1253 struct req_pkt *inpkt
1256 register struct info_timer_stats *ts;
1259 * Importations from the timer module
1261 extern u_long timer_timereset;
1262 extern u_long timer_overflows;
1263 extern u_long timer_xmtcalls;
1265 ts = (struct info_timer_stats *)prepare_pkt(srcadr, inter, inpkt,
1266 sizeof(struct info_timer_stats));
1268 ts->timereset = htonl((u_int32)(current_time - timer_timereset));
1269 ts->alarms = htonl((u_int32)alarm_overflow);
1270 ts->overflows = htonl((u_int32)timer_overflows);
1271 ts->xmtcalls = htonl((u_int32)timer_xmtcalls);
1273 (void) more_pkt();
1274 flush_pkt();
1279 * loop_info - return the current state of the loop filter
1281 static void
1282 loop_info(
1283 struct sockaddr_storage *srcadr,
1284 struct interface *inter,
1285 struct req_pkt *inpkt
1288 register struct info_loop *li;
1289 l_fp ltmp;
1292 * Importations from the loop filter module
1294 extern double last_offset;
1295 extern double drift_comp;
1296 extern int tc_counter;
1297 extern u_long sys_clocktime;
1299 li = (struct info_loop *)prepare_pkt(srcadr, inter, inpkt,
1300 sizeof(struct info_loop));
1302 DTOLFP(last_offset, &ltmp);
1303 HTONL_FP(&ltmp, &li->last_offset);
1304 DTOLFP(drift_comp * 1e6, &ltmp);
1305 HTONL_FP(&ltmp, &li->drift_comp);
1306 li->compliance = htonl((u_int32)(tc_counter));
1307 li->watchdog_timer = htonl((u_int32)(current_time - sys_clocktime));
1309 (void) more_pkt();
1310 flush_pkt();
1315 * do_conf - add a peer to the configuration list
1317 static void
1318 do_conf(
1319 struct sockaddr_storage *srcadr,
1320 struct interface *inter,
1321 struct req_pkt *inpkt
1324 static u_long soonest_ifrescan_time = 0;
1325 int items;
1326 u_int fl;
1327 struct conf_peer *cp;
1328 struct conf_peer temp_cp;
1329 struct sockaddr_storage peeraddr;
1330 struct sockaddr_in tmp_clock;
1333 * Do a check of everything to see that it looks
1334 * okay. If not, complain about it. Note we are
1335 * very picky here.
1337 items = INFO_NITEMS(inpkt->err_nitems);
1338 cp = (struct conf_peer *)inpkt->data;
1339 memset(&temp_cp, 0, sizeof(struct conf_peer));
1340 memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1341 fl = 0;
1342 while (items-- > 0 && !fl) {
1343 if (((temp_cp.version) > NTP_VERSION)
1344 || ((temp_cp.version) < NTP_OLDVERSION))
1345 fl = 1;
1346 if (temp_cp.hmode != MODE_ACTIVE
1347 && temp_cp.hmode != MODE_CLIENT
1348 && temp_cp.hmode != MODE_BROADCAST)
1349 fl = 1;
1350 if (temp_cp.flags & ~(CONF_FLAG_AUTHENABLE | CONF_FLAG_PREFER
1351 | CONF_FLAG_BURST | CONF_FLAG_IBURST | CONF_FLAG_SKEY))
1352 fl = 1;
1353 cp = (struct conf_peer *)
1354 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1357 if (fl) {
1358 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1359 return;
1363 * Looks okay, try it out
1365 items = INFO_NITEMS(inpkt->err_nitems);
1366 cp = (struct conf_peer *)inpkt->data;
1368 while (items-- > 0) {
1369 memset(&temp_cp, 0, sizeof(struct conf_peer));
1370 memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1371 memset((char *)&peeraddr, 0, sizeof(struct sockaddr_storage));
1373 fl = 0;
1374 if (temp_cp.flags & CONF_FLAG_AUTHENABLE)
1375 fl |= FLAG_AUTHENABLE;
1376 if (temp_cp.flags & CONF_FLAG_PREFER)
1377 fl |= FLAG_PREFER;
1378 if (temp_cp.flags & CONF_FLAG_BURST)
1379 fl |= FLAG_BURST;
1380 if (temp_cp.flags & CONF_FLAG_IBURST)
1381 fl |= FLAG_IBURST;
1382 if (temp_cp.flags & CONF_FLAG_SKEY)
1383 fl |= FLAG_SKEY;
1385 if (client_v6_capable && temp_cp.v6_flag != 0) {
1386 peeraddr.ss_family = AF_INET6;
1387 GET_INADDR6(peeraddr) = temp_cp.peeraddr6;
1388 } else {
1389 peeraddr.ss_family = AF_INET;
1390 GET_INADDR(peeraddr) = temp_cp.peeraddr;
1392 * Make sure the address is valid
1394 tmp_clock = *CAST_V4(peeraddr);
1395 if (
1396 #ifdef REFCLOCK
1397 !ISREFCLOCKADR(&tmp_clock) &&
1398 #endif
1399 ISBADADR(&tmp_clock)) {
1400 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1401 return;
1405 NSRCPORT(&peeraddr) = htons(NTP_PORT);
1406 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
1407 peeraddr.ss_len = SOCKLEN(&peeraddr);
1408 #endif
1410 /* XXX W2DO? minpoll/maxpoll arguments ??? */
1411 if (peer_config(&peeraddr, (struct interface *)0,
1412 temp_cp.hmode, temp_cp.version, temp_cp.minpoll,
1413 temp_cp.maxpoll, fl, temp_cp.ttl, temp_cp.keyid,
1414 NULL) == 0) {
1415 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1416 return;
1420 * ntp_intres.c uses REQ_CONFIG/doconf() to add each
1421 * server after its name is resolved. If we have been
1422 * disconnected from the network, it may notice the
1423 * network has returned and add the first server while
1424 * the relevant interface is still disabled, awaiting
1425 * the next interface rescan. To get things moving
1426 * more quickly, trigger an interface scan now, except
1427 * if we have done so in the last half minute.
1429 if (soonest_ifrescan_time < current_time) {
1430 soonest_ifrescan_time = current_time + 30;
1431 timer_interfacetimeout(current_time);
1432 DPRINTF(1, ("do_conf triggering interface rescan\n"));
1435 cp = (struct conf_peer *)
1436 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1439 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1442 #if 0
1443 /* XXX */
1445 * dns_a - Snarf DNS info for an association ID
1447 static void
1448 dns_a(
1449 struct sockaddr_storage *srcadr,
1450 struct interface *inter,
1451 struct req_pkt *inpkt
1454 register struct info_dns_assoc *dp;
1455 register int items;
1456 struct sockaddr_in peeraddr;
1459 * Do a check of everything to see that it looks
1460 * okay. If not, complain about it. Note we are
1461 * very picky here.
1463 items = INFO_NITEMS(inpkt->err_nitems);
1464 dp = (struct info_dns_assoc *)inpkt->data;
1467 * Looks okay, try it out
1469 items = INFO_NITEMS(inpkt->err_nitems);
1470 dp = (struct info_dns_assoc *)inpkt->data;
1471 memset((char *)&peeraddr, 0, sizeof(struct sockaddr_in));
1472 peeraddr.sin_family = AF_INET;
1473 peeraddr.sin_port = htons(NTP_PORT);
1476 * Make sure the address is valid
1478 if (
1479 #ifdef REFCLOCK
1480 !ISREFCLOCKADR(&peeraddr) &&
1481 #endif
1482 ISBADADR(&peeraddr)) {
1483 #ifdef REFCLOCK
1484 msyslog(LOG_ERR, "dns_a: !ISREFCLOCK && ISBADADR");
1485 #else
1486 msyslog(LOG_ERR, "dns_a: ISBADADR");
1487 #endif
1488 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1489 return;
1492 while (items-- > 0) {
1493 associd_t associd;
1494 size_t hnl;
1495 struct peer *peer;
1496 int bogon = 0;
1498 associd = dp->associd;
1499 peer = findpeerbyassoc(associd);
1500 if (peer == 0 || peer->flags & FLAG_REFCLOCK) {
1501 msyslog(LOG_ERR, "dns_a: %s",
1502 (peer == 0)
1503 ? "peer == 0"
1504 : "peer->flags & FLAG_REFCLOCK");
1505 ++bogon;
1507 peeraddr.sin_addr.s_addr = dp->peeraddr;
1508 for (hnl = 0; dp->hostname[hnl] && hnl < sizeof dp->hostname; ++hnl) ;
1509 if (hnl >= sizeof dp->hostname) {
1510 msyslog(LOG_ERR, "dns_a: hnl (%ld) >= %ld",
1511 (long)hnl, (long)sizeof dp->hostname);
1512 ++bogon;
1515 msyslog(LOG_INFO, "dns_a: <%s> for %s, AssocID %d, bogon %d",
1516 dp->hostname,
1517 stoa((struct sockaddr_storage *)&peeraddr), associd,
1518 bogon);
1520 if (bogon) {
1521 /* If it didn't work */
1522 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1523 return;
1524 } else {
1525 #if 0
1526 #ifdef PUBKEY
1527 crypto_public(peer, dp->hostname);
1528 #endif /* PUBKEY */
1529 #endif
1532 dp++;
1535 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1537 #endif /* 0 */
1540 * do_unconf - remove a peer from the configuration list
1542 static void
1543 do_unconf(
1544 struct sockaddr_storage *srcadr,
1545 struct interface *inter,
1546 struct req_pkt *inpkt
1549 register struct conf_unpeer *cp;
1550 struct conf_unpeer temp_cp;
1551 register int items;
1552 register struct peer *peer;
1553 struct sockaddr_storage peeraddr;
1554 int bad, found;
1557 * This is a bit unstructured, but I like to be careful.
1558 * We check to see that every peer exists and is actually
1559 * configured. If so, we remove them. If not, we return
1560 * an error.
1562 items = INFO_NITEMS(inpkt->err_nitems);
1563 cp = (struct conf_unpeer *)inpkt->data;
1565 bad = 0;
1566 while (items-- > 0 && !bad) {
1567 memset(&temp_cp, 0, sizeof(temp_cp));
1568 memset(&peeraddr, 0, sizeof(peeraddr));
1569 memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1570 if (client_v6_capable && temp_cp.v6_flag != 0) {
1571 peeraddr.ss_family = AF_INET6;
1572 GET_INADDR6(peeraddr) = temp_cp.peeraddr6;
1573 } else {
1574 peeraddr.ss_family = AF_INET;
1575 GET_INADDR(peeraddr) = temp_cp.peeraddr;
1577 NSRCPORT(&peeraddr) = htons(NTP_PORT);
1578 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
1579 peeraddr.ss_len = SOCKLEN(&peeraddr);
1580 #endif
1581 found = 0;
1582 peer = (struct peer *)0;
1583 #ifdef DEBUG
1584 if (debug)
1585 printf("searching for %s\n", stoa(&peeraddr));
1586 #endif
1587 while (!found) {
1588 peer = findexistingpeer(&peeraddr, peer, -1);
1589 if (peer == (struct peer *)0)
1590 break;
1591 if (peer->flags & FLAG_CONFIG)
1592 found = 1;
1594 if (!found)
1595 bad = 1;
1596 cp = (struct conf_unpeer *)
1597 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1600 if (bad) {
1601 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1602 return;
1606 * Now do it in earnest.
1609 items = INFO_NITEMS(inpkt->err_nitems);
1610 cp = (struct conf_unpeer *)inpkt->data;
1611 while (items-- > 0) {
1612 memset(&temp_cp, 0, sizeof(temp_cp));
1613 memset(&peeraddr, 0, sizeof(peeraddr));
1614 memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1615 if (client_v6_capable && temp_cp.v6_flag != 0) {
1616 peeraddr.ss_family = AF_INET6;
1617 GET_INADDR6(peeraddr) = temp_cp.peeraddr6;
1618 } else {
1619 peeraddr.ss_family = AF_INET;
1620 GET_INADDR(peeraddr) = temp_cp.peeraddr;
1622 NSRCPORT(&peeraddr) = htons(NTP_PORT);
1623 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
1624 peeraddr.ss_len = SOCKLEN(&peeraddr);
1625 #endif
1626 peer_unconfig(&peeraddr, (struct interface *)0, -1);
1627 cp = (struct conf_unpeer *)
1628 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1631 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1636 * set_sys_flag - set system flags
1638 static void
1639 set_sys_flag(
1640 struct sockaddr_storage *srcadr,
1641 struct interface *inter,
1642 struct req_pkt *inpkt
1645 setclr_flags(srcadr, inter, inpkt, 1);
1650 * clr_sys_flag - clear system flags
1652 static void
1653 clr_sys_flag(
1654 struct sockaddr_storage *srcadr,
1655 struct interface *inter,
1656 struct req_pkt *inpkt
1659 setclr_flags(srcadr, inter, inpkt, 0);
1664 * setclr_flags - do the grunge work of flag setting/clearing
1666 static void
1667 setclr_flags(
1668 struct sockaddr_storage *srcadr,
1669 struct interface *inter,
1670 struct req_pkt *inpkt,
1671 u_long set
1674 register u_int flags;
1675 int prev_kern_enable;
1677 prev_kern_enable = kern_enable;
1678 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
1679 msyslog(LOG_ERR, "setclr_flags: err_nitems > 1");
1680 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1681 return;
1684 flags = ((struct conf_sys_flags *)inpkt->data)->flags;
1685 flags = ntohl(flags);
1687 if (flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS |
1688 SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR |
1689 SYS_FLAG_FILEGEN | SYS_FLAG_AUTH | SYS_FLAG_CAL)) {
1690 msyslog(LOG_ERR, "setclr_flags: extra flags: %#x",
1691 flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS |
1692 SYS_FLAG_NTP | SYS_FLAG_KERNEL |
1693 SYS_FLAG_MONITOR | SYS_FLAG_FILEGEN |
1694 SYS_FLAG_AUTH | SYS_FLAG_CAL));
1695 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1696 return;
1699 if (flags & SYS_FLAG_BCLIENT)
1700 proto_config(PROTO_BROADCLIENT, set, 0., NULL);
1701 if (flags & SYS_FLAG_PPS)
1702 proto_config(PROTO_PPS, set, 0., NULL);
1703 if (flags & SYS_FLAG_NTP)
1704 proto_config(PROTO_NTP, set, 0., NULL);
1705 if (flags & SYS_FLAG_KERNEL)
1706 proto_config(PROTO_KERNEL, set, 0., NULL);
1707 if (flags & SYS_FLAG_MONITOR)
1708 proto_config(PROTO_MONITOR, set, 0., NULL);
1709 if (flags & SYS_FLAG_FILEGEN)
1710 proto_config(PROTO_FILEGEN, set, 0., NULL);
1711 if (flags & SYS_FLAG_AUTH)
1712 proto_config(PROTO_AUTHENTICATE, set, 0., NULL);
1713 if (flags & SYS_FLAG_CAL)
1714 proto_config(PROTO_CAL, set, 0., NULL);
1715 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1717 /* Reset the kernel ntp parameters if the kernel flag changed. */
1718 if (prev_kern_enable && !kern_enable)
1719 loop_config(LOOP_KERN_CLEAR, 0.0);
1720 if (!prev_kern_enable && kern_enable)
1721 loop_config(LOOP_DRIFTCOMP, drift_comp);
1726 * list_restrict - return the restrict list
1728 static void
1729 list_restrict(
1730 struct sockaddr_storage *srcadr,
1731 struct interface *inter,
1732 struct req_pkt *inpkt
1735 register struct info_restrict *ir;
1736 register struct restrictlist *rl;
1737 register struct restrictlist6 *rl6;
1739 #ifdef DEBUG
1740 if (debug > 2)
1741 printf("wants restrict list summary\n");
1742 #endif
1744 ir = (struct info_restrict *)prepare_pkt(srcadr, inter, inpkt,
1745 v6sizeof(struct info_restrict));
1747 for (rl = restrictlist; rl != 0 && ir != 0; rl = rl->next) {
1748 ir->addr = htonl(rl->addr);
1749 if (client_v6_capable)
1750 ir->v6_flag = 0;
1751 ir->mask = htonl(rl->mask);
1752 ir->count = htonl((u_int32)rl->count);
1753 ir->flags = htons(rl->flags);
1754 ir->mflags = htons(rl->mflags);
1755 ir = (struct info_restrict *)more_pkt();
1757 if (client_v6_capable)
1758 for (rl6 = restrictlist6; rl6 != 0 && ir != 0; rl6 = rl6->next) {
1759 ir->addr6 = rl6->addr6;
1760 ir->mask6 = rl6->mask6;
1761 ir->v6_flag = 1;
1762 ir->count = htonl((u_int32)rl6->count);
1763 ir->flags = htons(rl6->flags);
1764 ir->mflags = htons(rl6->mflags);
1765 ir = (struct info_restrict *)more_pkt();
1767 flush_pkt();
1773 * do_resaddflags - add flags to a restrict entry (or create one)
1775 static void
1776 do_resaddflags(
1777 struct sockaddr_storage *srcadr,
1778 struct interface *inter,
1779 struct req_pkt *inpkt
1782 do_restrict(srcadr, inter, inpkt, RESTRICT_FLAGS);
1788 * do_ressubflags - remove flags from a restrict entry
1790 static void
1791 do_ressubflags(
1792 struct sockaddr_storage *srcadr,
1793 struct interface *inter,
1794 struct req_pkt *inpkt
1797 do_restrict(srcadr, inter, inpkt, RESTRICT_UNFLAG);
1802 * do_unrestrict - remove a restrict entry from the list
1804 static void
1805 do_unrestrict(
1806 struct sockaddr_storage *srcadr,
1807 struct interface *inter,
1808 struct req_pkt *inpkt
1811 do_restrict(srcadr, inter, inpkt, RESTRICT_REMOVE);
1819 * do_restrict - do the dirty stuff of dealing with restrictions
1821 static void
1822 do_restrict(
1823 struct sockaddr_storage *srcadr,
1824 struct interface *inter,
1825 struct req_pkt *inpkt,
1826 int op
1829 register struct conf_restrict *cr;
1830 register int items;
1831 struct sockaddr_storage matchaddr;
1832 struct sockaddr_storage matchmask;
1833 int bad;
1836 * Do a check of the flags to make sure that only
1837 * the NTPPORT flag is set, if any. If not, complain
1838 * about it. Note we are very picky here.
1840 items = INFO_NITEMS(inpkt->err_nitems);
1841 cr = (struct conf_restrict *)inpkt->data;
1843 bad = 0;
1844 cr->flags = ntohs(cr->flags);
1845 cr->mflags = ntohs(cr->mflags);
1846 while (items-- > 0 && !bad) {
1847 if (cr->mflags & ~(RESM_NTPONLY))
1848 bad |= 1;
1849 if (cr->flags & ~(RES_ALLFLAGS))
1850 bad |= 2;
1851 if (cr->mask != htonl(INADDR_ANY)) {
1852 if (client_v6_capable && cr->v6_flag != 0) {
1853 if (IN6_IS_ADDR_UNSPECIFIED(&cr->addr6))
1854 bad |= 4;
1855 } else
1856 if (cr->addr == htonl(INADDR_ANY))
1857 bad |= 8;
1859 cr = (struct conf_restrict *)((char *)cr +
1860 INFO_ITEMSIZE(inpkt->mbz_itemsize));
1863 if (bad) {
1864 msyslog(LOG_ERR, "do_restrict: bad = %#x", bad);
1865 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1866 return;
1870 * Looks okay, try it out
1872 items = INFO_NITEMS(inpkt->err_nitems);
1873 cr = (struct conf_restrict *)inpkt->data;
1874 memset((char *)&matchaddr, 0, sizeof(struct sockaddr_storage));
1875 memset((char *)&matchmask, 0, sizeof(struct sockaddr_storage));
1877 while (items-- > 0) {
1878 if (client_v6_capable && cr->v6_flag != 0) {
1879 GET_INADDR6(matchaddr) = cr->addr6;
1880 GET_INADDR6(matchmask) = cr->mask6;
1881 matchaddr.ss_family = AF_INET6;
1882 matchmask.ss_family = AF_INET6;
1883 } else {
1884 GET_INADDR(matchaddr) = cr->addr;
1885 GET_INADDR(matchmask) = cr->mask;
1886 matchaddr.ss_family = AF_INET;
1887 matchmask.ss_family = AF_INET;
1889 hack_restrict(op, &matchaddr, &matchmask, cr->mflags,
1890 cr->flags);
1891 cr++;
1894 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1899 * mon_getlist - return monitor data
1901 static void
1902 mon_getlist_0(
1903 struct sockaddr_storage *srcadr,
1904 struct interface *inter,
1905 struct req_pkt *inpkt
1908 register struct info_monitor *im;
1909 register struct mon_data *md;
1910 extern struct mon_data mon_mru_list;
1911 extern int mon_enabled;
1913 #ifdef DEBUG
1914 if (debug > 2)
1915 printf("wants monitor 0 list\n");
1916 #endif
1917 if (!mon_enabled) {
1918 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1919 return;
1921 im = (struct info_monitor *)prepare_pkt(srcadr, inter, inpkt,
1922 v6sizeof(struct info_monitor));
1923 for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
1924 md = md->mru_next) {
1925 im->lasttime = htonl((u_int32)md->avg_interval);
1926 im->firsttime = htonl((u_int32)(current_time - md->lasttime));
1927 im->lastdrop = htonl((u_int32)md->drop_count);
1928 im->count = htonl((u_int32)(md->count));
1929 if (md->rmtadr.ss_family == AF_INET6) {
1930 if (!client_v6_capable)
1931 continue;
1932 im->addr6 = GET_INADDR6(md->rmtadr);
1933 im->v6_flag = 1;
1934 } else {
1935 im->addr = GET_INADDR(md->rmtadr);
1936 if (client_v6_capable)
1937 im->v6_flag = 0;
1939 im->port = md->rmtport;
1940 im->mode = md->mode;
1941 im->version = md->version;
1942 im = (struct info_monitor *)more_pkt();
1944 flush_pkt();
1948 * mon_getlist - return monitor data
1950 static void
1951 mon_getlist_1(
1952 struct sockaddr_storage *srcadr,
1953 struct interface *inter,
1954 struct req_pkt *inpkt
1957 register struct info_monitor_1 *im;
1958 register struct mon_data *md;
1959 extern struct mon_data mon_mru_list;
1960 extern int mon_enabled;
1962 if (!mon_enabled) {
1963 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1964 return;
1966 im = (struct info_monitor_1 *)prepare_pkt(srcadr, inter, inpkt,
1967 v6sizeof(struct info_monitor_1));
1968 for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
1969 md = md->mru_next) {
1970 im->lasttime = htonl((u_int32)md->avg_interval);
1971 im->firsttime = htonl((u_int32)(current_time - md->lasttime));
1972 im->lastdrop = htonl((u_int32)md->drop_count);
1973 im->count = htonl((u_int32)md->count);
1974 if (md->rmtadr.ss_family == AF_INET6) {
1975 if (!client_v6_capable)
1976 continue;
1977 im->addr6 = GET_INADDR6(md->rmtadr);
1978 im->v6_flag = 1;
1979 im->daddr6 = GET_INADDR6(md->interface->sin);
1980 } else {
1981 im->addr = GET_INADDR(md->rmtadr);
1982 if (client_v6_capable)
1983 im->v6_flag = 0;
1984 im->daddr = (md->cast_flags == MDF_BCAST)
1985 ? GET_INADDR(md->interface->bcast)
1986 : (md->cast_flags
1987 ? (GET_INADDR(md->interface->sin)
1988 ? GET_INADDR(md->interface->sin)
1989 : GET_INADDR(md->interface->bcast))
1990 : 4);
1992 im->flags = htonl(md->cast_flags);
1993 im->port = md->rmtport;
1994 im->mode = md->mode;
1995 im->version = md->version;
1996 im = (struct info_monitor_1 *)more_pkt();
1998 flush_pkt();
2002 * Module entry points and the flags they correspond with
2004 struct reset_entry {
2005 int flag; /* flag this corresponds to */
2006 void (*handler) P((void)); /* routine to handle request */
2009 struct reset_entry reset_entries[] = {
2010 { RESET_FLAG_ALLPEERS, peer_all_reset },
2011 { RESET_FLAG_IO, io_clr_stats },
2012 { RESET_FLAG_SYS, proto_clr_stats },
2013 { RESET_FLAG_MEM, peer_clr_stats },
2014 { RESET_FLAG_TIMER, timer_clr_stats },
2015 { RESET_FLAG_AUTH, reset_auth_stats },
2016 { RESET_FLAG_CTL, ctl_clr_stats },
2017 { 0, 0 }
2021 * reset_stats - reset statistic counters here and there
2023 static void
2024 reset_stats(
2025 struct sockaddr_storage *srcadr,
2026 struct interface *inter,
2027 struct req_pkt *inpkt
2030 u_long flags;
2031 struct reset_entry *rent;
2033 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2034 msyslog(LOG_ERR, "reset_stats: err_nitems > 1");
2035 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2036 return;
2039 flags = ((struct reset_flags *)inpkt->data)->flags;
2040 flags = ntohl(flags);
2042 if (flags & ~RESET_ALLFLAGS) {
2043 msyslog(LOG_ERR, "reset_stats: reset leaves %#lx",
2044 flags & ~RESET_ALLFLAGS);
2045 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2046 return;
2049 for (rent = reset_entries; rent->flag != 0; rent++) {
2050 if (flags & rent->flag)
2051 (rent->handler)();
2053 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2058 * reset_peer - clear a peer's statistics
2060 static void
2061 reset_peer(
2062 struct sockaddr_storage *srcadr,
2063 struct interface *inter,
2064 struct req_pkt *inpkt
2067 register struct conf_unpeer *cp;
2068 register int items;
2069 register struct peer *peer;
2070 struct sockaddr_storage peeraddr;
2071 int bad;
2074 * We check first to see that every peer exists. If not,
2075 * we return an error.
2078 items = INFO_NITEMS(inpkt->err_nitems);
2079 cp = (struct conf_unpeer *)inpkt->data;
2081 bad = 0;
2082 while (items-- > 0 && !bad) {
2083 memset((char *)&peeraddr, 0, sizeof(peeraddr));
2084 if (client_v6_capable && cp->v6_flag != 0) {
2085 GET_INADDR6(peeraddr) = cp->peeraddr6;
2086 peeraddr.ss_family = AF_INET6;
2087 } else {
2088 GET_INADDR(peeraddr) = cp->peeraddr;
2089 peeraddr.ss_family = AF_INET;
2091 NSRCPORT(&peeraddr) = htons(NTP_PORT);
2092 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2093 peeraddr.ss_len = SOCKLEN(&peeraddr);
2094 #endif
2095 peer = findexistingpeer(&peeraddr, (struct peer *)0, -1);
2096 if (peer == (struct peer *)0)
2097 bad++;
2098 cp = (struct conf_unpeer *)((char *)cp +
2099 INFO_ITEMSIZE(inpkt->mbz_itemsize));
2102 if (bad) {
2103 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2104 return;
2108 * Now do it in earnest.
2111 items = INFO_NITEMS(inpkt->err_nitems);
2112 cp = (struct conf_unpeer *)inpkt->data;
2113 while (items-- > 0) {
2114 memset((char *)&peeraddr, 0, sizeof(peeraddr));
2115 if (client_v6_capable && cp->v6_flag != 0) {
2116 GET_INADDR6(peeraddr) = cp->peeraddr6;
2117 peeraddr.ss_family = AF_INET6;
2118 } else {
2119 GET_INADDR(peeraddr) = cp->peeraddr;
2120 peeraddr.ss_family = AF_INET;
2122 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2123 peeraddr.ss_len = SOCKLEN(&peeraddr);
2124 #endif
2125 peer = findexistingpeer(&peeraddr, (struct peer *)0, -1);
2126 while (peer != 0) {
2127 peer_reset(peer);
2128 peer = findexistingpeer(&peeraddr, (struct peer *)peer, -1);
2130 cp = (struct conf_unpeer *)((char *)cp +
2131 INFO_ITEMSIZE(inpkt->mbz_itemsize));
2134 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2139 * do_key_reread - reread the encryption key file
2141 static void
2142 do_key_reread(
2143 struct sockaddr_storage *srcadr,
2144 struct interface *inter,
2145 struct req_pkt *inpkt
2148 rereadkeys();
2149 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2154 * trust_key - make one or more keys trusted
2156 static void
2157 trust_key(
2158 struct sockaddr_storage *srcadr,
2159 struct interface *inter,
2160 struct req_pkt *inpkt
2163 do_trustkey(srcadr, inter, inpkt, 1);
2168 * untrust_key - make one or more keys untrusted
2170 static void
2171 untrust_key(
2172 struct sockaddr_storage *srcadr,
2173 struct interface *inter,
2174 struct req_pkt *inpkt
2177 do_trustkey(srcadr, inter, inpkt, 0);
2182 * do_trustkey - make keys either trustable or untrustable
2184 static void
2185 do_trustkey(
2186 struct sockaddr_storage *srcadr,
2187 struct interface *inter,
2188 struct req_pkt *inpkt,
2189 u_long trust
2192 register u_long *kp;
2193 register int items;
2195 items = INFO_NITEMS(inpkt->err_nitems);
2196 kp = (u_long *)inpkt->data;
2197 while (items-- > 0) {
2198 authtrust(*kp, trust);
2199 kp++;
2202 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2207 * get_auth_info - return some stats concerning the authentication module
2209 static void
2210 get_auth_info(
2211 struct sockaddr_storage *srcadr,
2212 struct interface *inter,
2213 struct req_pkt *inpkt
2216 register struct info_auth *ia;
2219 * Importations from the authentication module
2221 extern u_long authnumkeys;
2222 extern int authnumfreekeys;
2223 extern u_long authkeylookups;
2224 extern u_long authkeynotfound;
2225 extern u_long authencryptions;
2226 extern u_long authdecryptions;
2227 extern u_long authkeyuncached;
2228 extern u_long authkeyexpired;
2230 ia = (struct info_auth *)prepare_pkt(srcadr, inter, inpkt,
2231 sizeof(struct info_auth));
2233 ia->numkeys = htonl((u_int32)authnumkeys);
2234 ia->numfreekeys = htonl((u_int32)authnumfreekeys);
2235 ia->keylookups = htonl((u_int32)authkeylookups);
2236 ia->keynotfound = htonl((u_int32)authkeynotfound);
2237 ia->encryptions = htonl((u_int32)authencryptions);
2238 ia->decryptions = htonl((u_int32)authdecryptions);
2239 ia->keyuncached = htonl((u_int32)authkeyuncached);
2240 ia->expired = htonl((u_int32)authkeyexpired);
2241 ia->timereset = htonl((u_int32)(current_time - auth_timereset));
2243 (void) more_pkt();
2244 flush_pkt();
2250 * reset_auth_stats - reset the authentication stat counters. Done here
2251 * to keep ntp-isms out of the authentication module
2253 static void
2254 reset_auth_stats(void)
2257 * Importations from the authentication module
2259 extern u_long authkeylookups;
2260 extern u_long authkeynotfound;
2261 extern u_long authencryptions;
2262 extern u_long authdecryptions;
2263 extern u_long authkeyuncached;
2265 authkeylookups = 0;
2266 authkeynotfound = 0;
2267 authencryptions = 0;
2268 authdecryptions = 0;
2269 authkeyuncached = 0;
2270 auth_timereset = current_time;
2275 * req_get_traps - return information about current trap holders
2277 static void
2278 req_get_traps(
2279 struct sockaddr_storage *srcadr,
2280 struct interface *inter,
2281 struct req_pkt *inpkt
2284 register struct info_trap *it;
2285 register struct ctl_trap *tr;
2286 register int i;
2289 * Imported from the control module
2291 extern struct ctl_trap ctl_trap[];
2292 extern int num_ctl_traps;
2294 if (num_ctl_traps == 0) {
2295 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2296 return;
2299 it = (struct info_trap *)prepare_pkt(srcadr, inter, inpkt,
2300 v6sizeof(struct info_trap));
2302 for (i = 0, tr = ctl_trap; i < CTL_MAXTRAPS; i++, tr++) {
2303 if (tr->tr_flags & TRAP_INUSE) {
2304 if (tr->tr_addr.ss_family == AF_INET) {
2305 if (tr->tr_localaddr == any_interface)
2306 it->local_address = 0;
2307 else
2308 it->local_address
2309 = GET_INADDR(tr->tr_localaddr->sin);
2310 it->trap_address = GET_INADDR(tr->tr_addr);
2311 if (client_v6_capable)
2312 it->v6_flag = 0;
2313 } else {
2314 if (!client_v6_capable)
2315 continue;
2316 it->local_address6
2317 = GET_INADDR6(tr->tr_localaddr->sin);
2318 it->trap_address6 = GET_INADDR6(tr->tr_addr);
2319 it->v6_flag = 1;
2321 it->trap_port = NSRCPORT(&tr->tr_addr);
2322 it->sequence = htons(tr->tr_sequence);
2323 it->settime = htonl((u_int32)(current_time - tr->tr_settime));
2324 it->origtime = htonl((u_int32)(current_time - tr->tr_origtime));
2325 it->resets = htonl((u_int32)tr->tr_resets);
2326 it->flags = htonl((u_int32)tr->tr_flags);
2327 it = (struct info_trap *)more_pkt();
2330 flush_pkt();
2335 * req_set_trap - configure a trap
2337 static void
2338 req_set_trap(
2339 struct sockaddr_storage *srcadr,
2340 struct interface *inter,
2341 struct req_pkt *inpkt
2344 do_setclr_trap(srcadr, inter, inpkt, 1);
2350 * req_clr_trap - unconfigure a trap
2352 static void
2353 req_clr_trap(
2354 struct sockaddr_storage *srcadr,
2355 struct interface *inter,
2356 struct req_pkt *inpkt
2359 do_setclr_trap(srcadr, inter, inpkt, 0);
2365 * do_setclr_trap - do the grunge work of (un)configuring a trap
2367 static void
2368 do_setclr_trap(
2369 struct sockaddr_storage *srcadr,
2370 struct interface *inter,
2371 struct req_pkt *inpkt,
2372 int set
2375 register struct conf_trap *ct;
2376 register struct interface *linter;
2377 int res;
2378 struct sockaddr_storage laddr;
2381 * Prepare sockaddr_storage structure
2383 memset((char *)&laddr, 0, sizeof laddr);
2384 laddr.ss_family = srcadr->ss_family;
2385 NSRCPORT(&laddr) = ntohs(NTP_PORT);
2388 * Restrict ourselves to one item only. This eliminates
2389 * the error reporting problem.
2391 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2392 msyslog(LOG_ERR, "do_setclr_trap: err_nitems > 1");
2393 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2394 return;
2396 ct = (struct conf_trap *)inpkt->data;
2399 * Look for the local interface. If none, use the default.
2401 if (ct->local_address == 0) {
2402 linter = any_interface;
2403 } else {
2404 if (laddr.ss_family == AF_INET)
2405 GET_INADDR(laddr) = ct->local_address;
2406 else
2407 GET_INADDR6(laddr) = ct->local_address6;
2408 linter = findinterface(&laddr);
2409 if (linter == NULL) {
2410 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2411 return;
2415 if (laddr.ss_family == AF_INET)
2416 GET_INADDR(laddr) = ct->trap_address;
2417 else
2418 GET_INADDR6(laddr) = ct->trap_address6;
2419 if (ct->trap_port != 0)
2420 NSRCPORT(&laddr) = ct->trap_port;
2421 else
2422 NSRCPORT(&laddr) = htons(TRAPPORT);
2424 if (set) {
2425 res = ctlsettrap(&laddr, linter, 0,
2426 INFO_VERSION(inpkt->rm_vn_mode));
2427 } else {
2428 res = ctlclrtrap(&laddr, linter, 0);
2431 if (!res) {
2432 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2433 } else {
2434 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2436 return;
2442 * set_request_keyid - set the keyid used to authenticate requests
2444 static void
2445 set_request_keyid(
2446 struct sockaddr_storage *srcadr,
2447 struct interface *inter,
2448 struct req_pkt *inpkt
2451 keyid_t keyid;
2454 * Restrict ourselves to one item only.
2456 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2457 msyslog(LOG_ERR, "set_request_keyid: err_nitems > 1");
2458 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2459 return;
2462 keyid = ntohl(*((u_int32 *)(inpkt->data)));
2463 info_auth_keyid = keyid;
2464 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2470 * set_control_keyid - set the keyid used to authenticate requests
2472 static void
2473 set_control_keyid(
2474 struct sockaddr_storage *srcadr,
2475 struct interface *inter,
2476 struct req_pkt *inpkt
2479 keyid_t keyid;
2480 extern keyid_t ctl_auth_keyid;
2483 * Restrict ourselves to one item only.
2485 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2486 msyslog(LOG_ERR, "set_control_keyid: err_nitems > 1");
2487 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2488 return;
2491 keyid = ntohl(*((u_int32 *)(inpkt->data)));
2492 ctl_auth_keyid = keyid;
2493 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2499 * get_ctl_stats - return some stats concerning the control message module
2501 static void
2502 get_ctl_stats(
2503 struct sockaddr_storage *srcadr,
2504 struct interface *inter,
2505 struct req_pkt *inpkt
2508 register struct info_control *ic;
2511 * Importations from the control module
2513 extern u_long ctltimereset;
2514 extern u_long numctlreq;
2515 extern u_long numctlbadpkts;
2516 extern u_long numctlresponses;
2517 extern u_long numctlfrags;
2518 extern u_long numctlerrors;
2519 extern u_long numctltooshort;
2520 extern u_long numctlinputresp;
2521 extern u_long numctlinputfrag;
2522 extern u_long numctlinputerr;
2523 extern u_long numctlbadoffset;
2524 extern u_long numctlbadversion;
2525 extern u_long numctldatatooshort;
2526 extern u_long numctlbadop;
2527 extern u_long numasyncmsgs;
2529 ic = (struct info_control *)prepare_pkt(srcadr, inter, inpkt,
2530 sizeof(struct info_control));
2532 ic->ctltimereset = htonl((u_int32)(current_time - ctltimereset));
2533 ic->numctlreq = htonl((u_int32)numctlreq);
2534 ic->numctlbadpkts = htonl((u_int32)numctlbadpkts);
2535 ic->numctlresponses = htonl((u_int32)numctlresponses);
2536 ic->numctlfrags = htonl((u_int32)numctlfrags);
2537 ic->numctlerrors = htonl((u_int32)numctlerrors);
2538 ic->numctltooshort = htonl((u_int32)numctltooshort);
2539 ic->numctlinputresp = htonl((u_int32)numctlinputresp);
2540 ic->numctlinputfrag = htonl((u_int32)numctlinputfrag);
2541 ic->numctlinputerr = htonl((u_int32)numctlinputerr);
2542 ic->numctlbadoffset = htonl((u_int32)numctlbadoffset);
2543 ic->numctlbadversion = htonl((u_int32)numctlbadversion);
2544 ic->numctldatatooshort = htonl((u_int32)numctldatatooshort);
2545 ic->numctlbadop = htonl((u_int32)numctlbadop);
2546 ic->numasyncmsgs = htonl((u_int32)numasyncmsgs);
2548 (void) more_pkt();
2549 flush_pkt();
2553 #ifdef KERNEL_PLL
2555 * get_kernel_info - get kernel pll/pps information
2557 static void
2558 get_kernel_info(
2559 struct sockaddr_storage *srcadr,
2560 struct interface *inter,
2561 struct req_pkt *inpkt
2564 register struct info_kernel *ik;
2565 struct timex ntx;
2567 if (!pll_control) {
2568 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2569 return;
2572 memset((char *)&ntx, 0, sizeof(ntx));
2573 if (ntp_adjtime(&ntx) < 0)
2574 msyslog(LOG_ERR, "get_kernel_info: ntp_adjtime() failed: %m");
2575 ik = (struct info_kernel *)prepare_pkt(srcadr, inter, inpkt,
2576 sizeof(struct info_kernel));
2579 * pll variables
2581 ik->offset = htonl((u_int32)ntx.offset);
2582 ik->freq = htonl((u_int32)ntx.freq);
2583 ik->maxerror = htonl((u_int32)ntx.maxerror);
2584 ik->esterror = htonl((u_int32)ntx.esterror);
2585 ik->status = htons(ntx.status);
2586 ik->constant = htonl((u_int32)ntx.constant);
2587 ik->precision = htonl((u_int32)ntx.precision);
2588 ik->tolerance = htonl((u_int32)ntx.tolerance);
2591 * pps variables
2593 ik->ppsfreq = htonl((u_int32)ntx.ppsfreq);
2594 ik->jitter = htonl((u_int32)ntx.jitter);
2595 ik->shift = htons(ntx.shift);
2596 ik->stabil = htonl((u_int32)ntx.stabil);
2597 ik->jitcnt = htonl((u_int32)ntx.jitcnt);
2598 ik->calcnt = htonl((u_int32)ntx.calcnt);
2599 ik->errcnt = htonl((u_int32)ntx.errcnt);
2600 ik->stbcnt = htonl((u_int32)ntx.stbcnt);
2602 (void) more_pkt();
2603 flush_pkt();
2605 #endif /* KERNEL_PLL */
2608 #ifdef REFCLOCK
2610 * get_clock_info - get info about a clock
2612 static void
2613 get_clock_info(
2614 struct sockaddr_storage *srcadr,
2615 struct interface *inter,
2616 struct req_pkt *inpkt
2619 register struct info_clock *ic;
2620 register u_int32 *clkaddr;
2621 register int items;
2622 struct refclockstat clock_stat;
2623 struct sockaddr_storage addr;
2624 struct sockaddr_in tmp_clock;
2625 l_fp ltmp;
2627 memset((char *)&addr, 0, sizeof addr);
2628 addr.ss_family = AF_INET;
2629 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2630 addr.ss_len = SOCKLEN(&addr);
2631 #endif
2632 NSRCPORT(&addr) = htons(NTP_PORT);
2633 items = INFO_NITEMS(inpkt->err_nitems);
2634 clkaddr = (u_int32 *) inpkt->data;
2636 ic = (struct info_clock *)prepare_pkt(srcadr, inter, inpkt,
2637 sizeof(struct info_clock));
2639 while (items-- > 0) {
2640 tmp_clock.sin_addr.s_addr = *clkaddr++;
2641 CAST_V4(addr)->sin_addr = tmp_clock.sin_addr;
2642 if (!ISREFCLOCKADR(&tmp_clock) ||
2643 findexistingpeer(&addr, (struct peer *)0, -1) == 0) {
2644 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2645 return;
2648 clock_stat.kv_list = (struct ctl_var *)0;
2650 refclock_control(&addr, (struct refclockstat *)0, &clock_stat);
2652 ic->clockadr = tmp_clock.sin_addr.s_addr;
2653 ic->type = clock_stat.type;
2654 ic->flags = clock_stat.flags;
2655 ic->lastevent = clock_stat.lastevent;
2656 ic->currentstatus = clock_stat.currentstatus;
2657 ic->polls = htonl((u_int32)clock_stat.polls);
2658 ic->noresponse = htonl((u_int32)clock_stat.noresponse);
2659 ic->badformat = htonl((u_int32)clock_stat.badformat);
2660 ic->baddata = htonl((u_int32)clock_stat.baddata);
2661 ic->timestarted = htonl((u_int32)clock_stat.timereset);
2662 DTOLFP(clock_stat.fudgetime1, &ltmp);
2663 HTONL_FP(&ltmp, &ic->fudgetime1);
2664 DTOLFP(clock_stat.fudgetime2, &ltmp);
2665 HTONL_FP(&ltmp, &ic->fudgetime2);
2666 ic->fudgeval1 = htonl((u_int32)clock_stat.fudgeval1);
2667 ic->fudgeval2 = htonl((u_int32)clock_stat.fudgeval2);
2669 free_varlist(clock_stat.kv_list);
2671 ic = (struct info_clock *)more_pkt();
2673 flush_pkt();
2679 * set_clock_fudge - get a clock's fudge factors
2681 static void
2682 set_clock_fudge(
2683 struct sockaddr_storage *srcadr,
2684 struct interface *inter,
2685 struct req_pkt *inpkt
2688 register struct conf_fudge *cf;
2689 register int items;
2690 struct refclockstat clock_stat;
2691 struct sockaddr_storage addr;
2692 struct sockaddr_in tmp_clock;
2693 l_fp ltmp;
2695 memset((char *)&addr, 0, sizeof addr);
2696 memset((char *)&clock_stat, 0, sizeof clock_stat);
2697 memset((char *)&tmp_clock, 0, sizeof tmp_clock);
2698 items = INFO_NITEMS(inpkt->err_nitems);
2699 cf = (struct conf_fudge *) inpkt->data;
2701 while (items-- > 0) {
2702 tmp_clock.sin_addr.s_addr = cf->clockadr;
2703 *CAST_V4(addr) = tmp_clock;
2704 addr.ss_family = AF_INET;
2705 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2706 addr.ss_len = SOCKLEN(&addr);
2707 #endif
2708 NSRCPORT(&addr) = htons(NTP_PORT);
2709 if (!ISREFCLOCKADR(&tmp_clock) ||
2710 findexistingpeer(&addr, (struct peer *)0, -1) == 0) {
2711 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2712 return;
2715 switch(ntohl(cf->which)) {
2716 case FUDGE_TIME1:
2717 NTOHL_FP(&cf->fudgetime, &ltmp);
2718 LFPTOD(&ltmp, clock_stat.fudgetime1);
2719 clock_stat.haveflags = CLK_HAVETIME1;
2720 break;
2721 case FUDGE_TIME2:
2722 NTOHL_FP(&cf->fudgetime, &ltmp);
2723 LFPTOD(&ltmp, clock_stat.fudgetime2);
2724 clock_stat.haveflags = CLK_HAVETIME2;
2725 break;
2726 case FUDGE_VAL1:
2727 clock_stat.fudgeval1 = ntohl(cf->fudgeval_flags);
2728 clock_stat.haveflags = CLK_HAVEVAL1;
2729 break;
2730 case FUDGE_VAL2:
2731 clock_stat.fudgeval2 = ntohl(cf->fudgeval_flags);
2732 clock_stat.haveflags = CLK_HAVEVAL2;
2733 break;
2734 case FUDGE_FLAGS:
2735 clock_stat.flags = (u_char) (ntohl(cf->fudgeval_flags) & 0xf);
2736 clock_stat.haveflags =
2737 (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4);
2738 break;
2739 default:
2740 msyslog(LOG_ERR, "set_clock_fudge: default!");
2741 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2742 return;
2745 refclock_control(&addr, &clock_stat, (struct refclockstat *)0);
2748 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2750 #endif
2752 #ifdef REFCLOCK
2754 * get_clkbug_info - get debugging info about a clock
2756 static void
2757 get_clkbug_info(
2758 struct sockaddr_storage *srcadr,
2759 struct interface *inter,
2760 struct req_pkt *inpkt
2763 register int i;
2764 register struct info_clkbug *ic;
2765 register u_int32 *clkaddr;
2766 register int items;
2767 struct refclockbug bug;
2768 struct sockaddr_storage addr;
2769 struct sockaddr_in tmp_clock;
2771 memset((char *)&addr, 0, sizeof addr);
2772 addr.ss_family = AF_INET;
2773 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2774 addr.ss_len = SOCKLEN(&addr);
2775 #endif
2776 NSRCPORT(&addr) = htons(NTP_PORT);
2777 items = INFO_NITEMS(inpkt->err_nitems);
2778 clkaddr = (u_int32 *) inpkt->data;
2780 ic = (struct info_clkbug *)prepare_pkt(srcadr, inter, inpkt,
2781 sizeof(struct info_clkbug));
2783 while (items-- > 0) {
2784 tmp_clock.sin_addr.s_addr = *clkaddr++;
2785 GET_INADDR(addr) = tmp_clock.sin_addr.s_addr;
2786 if (!ISREFCLOCKADR(&tmp_clock) ||
2787 findexistingpeer(&addr, (struct peer *)0, -1) == 0) {
2788 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2789 return;
2792 memset((char *)&bug, 0, sizeof bug);
2793 refclock_buginfo(&addr, &bug);
2794 if (bug.nvalues == 0 && bug.ntimes == 0) {
2795 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2796 return;
2799 ic->clockadr = tmp_clock.sin_addr.s_addr;
2800 i = bug.nvalues;
2801 if (i > NUMCBUGVALUES)
2802 i = NUMCBUGVALUES;
2803 ic->nvalues = (u_char)i;
2804 ic->svalues = htons((u_short) (bug.svalues & ((1<<i)-1)));
2805 while (--i >= 0)
2806 ic->values[i] = htonl(bug.values[i]);
2808 i = bug.ntimes;
2809 if (i > NUMCBUGTIMES)
2810 i = NUMCBUGTIMES;
2811 ic->ntimes = (u_char)i;
2812 ic->stimes = htonl(bug.stimes);
2813 while (--i >= 0) {
2814 HTONL_FP(&bug.times[i], &ic->times[i]);
2817 ic = (struct info_clkbug *)more_pkt();
2819 flush_pkt();
2821 #endif
2824 * receiver of interface structures
2826 static void
2827 fill_info_if_stats(void *data, interface_info_t *interface_info)
2829 struct info_if_stats **ifsp = (struct info_if_stats **)data;
2830 struct info_if_stats *ifs = *ifsp;
2831 struct interface *interface = interface_info->interface;
2833 memset((char*)ifs, 0, sizeof(*ifs));
2835 if (interface->sin.ss_family == AF_INET6) {
2836 if (!client_v6_capable) {
2837 return;
2839 ifs->v6_flag = 1;
2840 memcpy((char *)&ifs->unaddr.addr6, (char *)&CAST_V6(interface->sin)->sin6_addr, sizeof(struct in6_addr));
2841 memcpy((char *)&ifs->unbcast.addr6, (char *)&CAST_V6(interface->bcast)->sin6_addr, sizeof(struct in6_addr));
2842 memcpy((char *)&ifs->unmask.addr6, (char *)&CAST_V6(interface->mask)->sin6_addr, sizeof(struct in6_addr));
2843 } else {
2844 ifs->v6_flag = 0;
2845 memcpy((char *)&ifs->unaddr.addr, (char *)&CAST_V4(interface->sin)->sin_addr, sizeof(struct in_addr));
2846 memcpy((char *)&ifs->unbcast.addr, (char *)&CAST_V4(interface->bcast)->sin_addr, sizeof(struct in_addr));
2847 memcpy((char *)&ifs->unmask.addr, (char *)&CAST_V4(interface->mask)->sin_addr, sizeof(struct in_addr));
2849 ifs->v6_flag = htonl(ifs->v6_flag);
2850 strcpy(ifs->name, interface->name);
2851 ifs->family = htons(interface->family);
2852 ifs->flags = htonl(interface->flags);
2853 ifs->last_ttl = htonl(interface->last_ttl);
2854 ifs->num_mcast = htonl(interface->num_mcast);
2855 ifs->received = htonl(interface->received);
2856 ifs->sent = htonl(interface->sent);
2857 ifs->notsent = htonl(interface->notsent);
2858 ifs->scopeid = htonl(interface->scopeid);
2859 ifs->ifindex = htonl(interface->ifindex);
2860 ifs->ifnum = htonl(interface->ifnum);
2861 ifs->uptime = htonl(current_time - interface->starttime);
2862 ifs->ignore_packets = interface->ignore_packets;
2863 ifs->peercnt = htonl(interface->peercnt);
2864 ifs->action = interface_info->action;
2866 *ifsp = (struct info_if_stats *)more_pkt();
2870 * get_if_stats - get interface statistics
2872 static void
2873 get_if_stats(
2874 struct sockaddr_storage *srcadr,
2875 struct interface *inter,
2876 struct req_pkt *inpkt
2879 struct info_if_stats *ifs;
2881 DPRINTF(3, ("wants interface statistics\n"));
2883 ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt,
2884 v6sizeof(struct info_if_stats));
2886 interface_enumerate(fill_info_if_stats, &ifs);
2888 flush_pkt();
2891 static void
2892 do_if_reload(
2893 struct sockaddr_storage *srcadr,
2894 struct interface *inter,
2895 struct req_pkt *inpkt
2898 struct info_if_stats *ifs;
2900 DPRINTF(3, ("wants interface reload\n"));
2902 ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt,
2903 v6sizeof(struct info_if_stats));
2905 interface_update(fill_info_if_stats, &ifs);
2907 flush_pkt();