Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / ntp / dist / ntpd / ntp_request.c
blobd77a85dcfa1278912dc38ea2a63bf870ff5167ad
1 /* $NetBSD: ntp_request.c,v 1.1.1.1 2009/12/13 16:55:40 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"
18 #include "ntp_assert.h"
20 #include <stdio.h>
21 #include <stddef.h>
22 #include <signal.h>
23 #ifdef HAVE_NETINET_IN_H
24 #include <netinet/in.h>
25 #endif
26 #include <arpa/inet.h>
28 #include "recvbuff.h"
30 #ifdef KERNEL_PLL
31 #include "ntp_syscall.h"
32 #endif /* KERNEL_PLL */
35 * Structure to hold request procedure information
37 #define NOAUTH 0
38 #define AUTH 1
40 #define NO_REQUEST (-1)
42 * Because we now have v6 addresses in the messages, we need to compensate
43 * for the larger size. Therefore, we introduce the alternate size to
44 * keep us friendly with older implementations. A little ugly.
46 static int client_v6_capable = 0; /* the client can handle longer messages */
48 #define v6sizeof(type) (client_v6_capable ? sizeof(type) : v4sizeof(type))
50 struct req_proc {
51 short request_code; /* defined request code */
52 short needs_auth; /* true when authentication needed */
53 short sizeofitem; /* size of request data item (older size)*/
54 short v6_sizeofitem; /* size of request data item (new size)*/
55 void (*handler) (sockaddr_u *, struct interface *,
56 struct req_pkt *); /* routine to handle request */
60 * Universal request codes
62 static struct req_proc univ_codes[] = {
63 { NO_REQUEST, NOAUTH, 0, 0 }
66 static void req_ack (sockaddr_u *, struct interface *, struct req_pkt *, int);
67 static char * prepare_pkt (sockaddr_u *, struct interface *,
68 struct req_pkt *, size_t);
69 static char * more_pkt (void);
70 static void flush_pkt (void);
71 static void peer_list (sockaddr_u *, struct interface *, struct req_pkt *);
72 static void peer_list_sum (sockaddr_u *, struct interface *, struct req_pkt *);
73 static void peer_info (sockaddr_u *, struct interface *, struct req_pkt *);
74 static void peer_stats (sockaddr_u *, struct interface *, struct req_pkt *);
75 static void sys_info (sockaddr_u *, struct interface *, struct req_pkt *);
76 static void sys_stats (sockaddr_u *, struct interface *, struct req_pkt *);
77 static void mem_stats (sockaddr_u *, struct interface *, struct req_pkt *);
78 static void io_stats (sockaddr_u *, struct interface *, struct req_pkt *);
79 static void timer_stats (sockaddr_u *, struct interface *, struct req_pkt *);
80 static void loop_info (sockaddr_u *, struct interface *, struct req_pkt *);
81 static void do_conf (sockaddr_u *, struct interface *, struct req_pkt *);
82 static void do_unconf (sockaddr_u *, struct interface *, struct req_pkt *);
83 static void set_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *);
84 static void clr_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *);
85 static void setclr_flags (sockaddr_u *, struct interface *, struct req_pkt *, u_long);
86 static void list_restrict (sockaddr_u *, struct interface *, struct req_pkt *);
87 static void do_resaddflags (sockaddr_u *, struct interface *, struct req_pkt *);
88 static void do_ressubflags (sockaddr_u *, struct interface *, struct req_pkt *);
89 static void do_unrestrict (sockaddr_u *, struct interface *, struct req_pkt *);
90 static void do_restrict (sockaddr_u *, struct interface *, struct req_pkt *, int);
91 static void mon_getlist_0 (sockaddr_u *, struct interface *, struct req_pkt *);
92 static void mon_getlist_1 (sockaddr_u *, struct interface *, struct req_pkt *);
93 static void reset_stats (sockaddr_u *, struct interface *, struct req_pkt *);
94 static void reset_peer (sockaddr_u *, struct interface *, struct req_pkt *);
95 static void do_key_reread (sockaddr_u *, struct interface *, struct req_pkt *);
96 static void trust_key (sockaddr_u *, struct interface *, struct req_pkt *);
97 static void untrust_key (sockaddr_u *, struct interface *, struct req_pkt *);
98 static void do_trustkey (sockaddr_u *, struct interface *, struct req_pkt *, u_long);
99 static void get_auth_info (sockaddr_u *, struct interface *, struct req_pkt *);
100 static void reset_auth_stats (void);
101 static void req_get_traps (sockaddr_u *, struct interface *, struct req_pkt *);
102 static void req_set_trap (sockaddr_u *, struct interface *, struct req_pkt *);
103 static void req_clr_trap (sockaddr_u *, struct interface *, struct req_pkt *);
104 static void do_setclr_trap (sockaddr_u *, struct interface *, struct req_pkt *, int);
105 static void set_request_keyid (sockaddr_u *, struct interface *, struct req_pkt *);
106 static void set_control_keyid (sockaddr_u *, struct interface *, struct req_pkt *);
107 static void get_ctl_stats (sockaddr_u *, struct interface *, struct req_pkt *);
108 static void get_if_stats (sockaddr_u *, struct interface *, struct req_pkt *);
109 static void do_if_reload (sockaddr_u *, struct interface *, struct req_pkt *);
110 #ifdef KERNEL_PLL
111 static void get_kernel_info (sockaddr_u *, struct interface *, struct req_pkt *);
112 #endif /* KERNEL_PLL */
113 #ifdef REFCLOCK
114 static void get_clock_info (sockaddr_u *, struct interface *, struct req_pkt *);
115 static void set_clock_fudge (sockaddr_u *, struct interface *, struct req_pkt *);
116 #endif /* REFCLOCK */
117 #ifdef REFCLOCK
118 static void get_clkbug_info (sockaddr_u *, struct interface *, struct req_pkt *);
119 #endif /* REFCLOCK */
122 * ntpd request codes
124 static struct req_proc ntp_codes[] = {
125 { REQ_PEER_LIST, NOAUTH, 0, 0, peer_list },
126 { REQ_PEER_LIST_SUM, NOAUTH, 0, 0, peer_list_sum },
127 { REQ_PEER_INFO, NOAUTH, v4sizeof(struct info_peer_list),
128 sizeof(struct info_peer_list), peer_info},
129 { REQ_PEER_STATS, NOAUTH, v4sizeof(struct info_peer_list),
130 sizeof(struct info_peer_list), peer_stats},
131 { REQ_SYS_INFO, NOAUTH, 0, 0, sys_info },
132 { REQ_SYS_STATS, NOAUTH, 0, 0, sys_stats },
133 { REQ_IO_STATS, NOAUTH, 0, 0, io_stats },
134 { REQ_MEM_STATS, NOAUTH, 0, 0, mem_stats },
135 { REQ_LOOP_INFO, NOAUTH, 0, 0, loop_info },
136 { REQ_TIMER_STATS, NOAUTH, 0, 0, timer_stats },
137 { REQ_CONFIG, AUTH, v4sizeof(struct conf_peer),
138 sizeof(struct conf_peer), do_conf },
139 { REQ_UNCONFIG, AUTH, v4sizeof(struct conf_unpeer),
140 sizeof(struct conf_unpeer), do_unconf },
141 { REQ_SET_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags),
142 sizeof(struct conf_sys_flags), set_sys_flag },
143 { REQ_CLR_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags),
144 sizeof(struct conf_sys_flags), clr_sys_flag },
145 { REQ_GET_RESTRICT, NOAUTH, 0, 0, list_restrict },
146 { REQ_RESADDFLAGS, AUTH, v4sizeof(struct conf_restrict),
147 sizeof(struct conf_restrict), do_resaddflags },
148 { REQ_RESSUBFLAGS, AUTH, v4sizeof(struct conf_restrict),
149 sizeof(struct conf_restrict), do_ressubflags },
150 { REQ_UNRESTRICT, AUTH, v4sizeof(struct conf_restrict),
151 sizeof(struct conf_restrict), do_unrestrict },
152 { REQ_MON_GETLIST, NOAUTH, 0, 0, mon_getlist_0 },
153 { REQ_MON_GETLIST_1, NOAUTH, 0, 0, mon_getlist_1 },
154 { REQ_RESET_STATS, AUTH, sizeof(struct reset_flags), 0, reset_stats },
155 { REQ_RESET_PEER, AUTH, v4sizeof(struct conf_unpeer),
156 sizeof(struct conf_unpeer), reset_peer },
157 { REQ_REREAD_KEYS, AUTH, 0, 0, do_key_reread },
158 { REQ_TRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), trust_key },
159 { REQ_UNTRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), untrust_key },
160 { REQ_AUTHINFO, NOAUTH, 0, 0, get_auth_info },
161 { REQ_TRAPS, NOAUTH, 0, 0, req_get_traps },
162 { REQ_ADD_TRAP, AUTH, v4sizeof(struct conf_trap),
163 sizeof(struct conf_trap), req_set_trap },
164 { REQ_CLR_TRAP, AUTH, v4sizeof(struct conf_trap),
165 sizeof(struct conf_trap), req_clr_trap },
166 { REQ_REQUEST_KEY, AUTH, sizeof(u_long), sizeof(u_long),
167 set_request_keyid },
168 { REQ_CONTROL_KEY, AUTH, sizeof(u_long), sizeof(u_long),
169 set_control_keyid },
170 { REQ_GET_CTLSTATS, NOAUTH, 0, 0, get_ctl_stats },
171 #ifdef KERNEL_PLL
172 { REQ_GET_KERNEL, NOAUTH, 0, 0, get_kernel_info },
173 #endif
174 #ifdef REFCLOCK
175 { REQ_GET_CLOCKINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32),
176 get_clock_info },
177 { REQ_SET_CLKFUDGE, AUTH, sizeof(struct conf_fudge),
178 sizeof(struct conf_fudge), set_clock_fudge },
179 { REQ_GET_CLKBUGINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32),
180 get_clkbug_info },
181 #endif
182 { REQ_IF_STATS, AUTH, 0, 0, get_if_stats },
183 { REQ_IF_RELOAD, AUTH, 0, 0, do_if_reload },
185 { NO_REQUEST, NOAUTH, 0, 0, 0 }
190 * Authentication keyid used to authenticate requests. Zero means we
191 * don't allow writing anything.
193 keyid_t info_auth_keyid;
196 * Statistic counters to keep track of requests and responses.
198 u_long numrequests; /* number of requests we've received */
199 u_long numresppkts; /* number of resp packets sent with data */
201 u_long errorcounter[INFO_ERR_AUTH+1]; /* lazy way to count errors, indexed */
202 /* by the error code */
205 * A hack. To keep the authentication module clear of ntp-ism's, we
206 * include a time reset variable for its stats here.
208 static u_long auth_timereset;
211 * Response packet used by these routines. Also some state information
212 * so that we can handle packet formatting within a common set of
213 * subroutines. Note we try to enter data in place whenever possible,
214 * but the need to set the more bit correctly means we occasionally
215 * use the extra buffer and copy.
217 static struct resp_pkt rpkt;
218 static int reqver;
219 static int seqno;
220 static int nitems;
221 static int itemsize;
222 static int databytes;
223 static char exbuf[RESP_DATA_SIZE];
224 static int usingexbuf;
225 static sockaddr_u *toaddr;
226 static struct interface *frominter;
229 * init_request - initialize request data
231 void
232 init_request (void)
234 int i;
236 numrequests = 0;
237 numresppkts = 0;
238 auth_timereset = 0;
239 info_auth_keyid = 0; /* by default, can't do this */
241 for (i = 0; i < sizeof(errorcounter)/sizeof(errorcounter[0]); i++)
242 errorcounter[i] = 0;
247 * req_ack - acknowledge request with no data
249 static void
250 req_ack(
251 sockaddr_u *srcadr,
252 struct interface *inter,
253 struct req_pkt *inpkt,
254 int errcode
258 * fill in the fields
260 rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver);
261 rpkt.auth_seq = AUTH_SEQ(0, 0);
262 rpkt.implementation = inpkt->implementation;
263 rpkt.request = inpkt->request;
264 rpkt.err_nitems = ERR_NITEMS(errcode, 0);
265 rpkt.mbz_itemsize = MBZ_ITEMSIZE(0);
268 * send packet and bump counters
270 sendpkt(srcadr, inter, -1, (struct pkt *)&rpkt, RESP_HEADER_SIZE);
271 errorcounter[errcode]++;
276 * prepare_pkt - prepare response packet for transmission, return pointer
277 * to storage for data item.
279 static char *
280 prepare_pkt(
281 sockaddr_u *srcadr,
282 struct interface *inter,
283 struct req_pkt *pkt,
284 size_t structsize
287 DPRINTF(4, ("request: preparing pkt\n"));
290 * Fill in the implementation, request and itemsize fields
291 * since these won't change.
293 rpkt.implementation = pkt->implementation;
294 rpkt.request = pkt->request;
295 rpkt.mbz_itemsize = MBZ_ITEMSIZE(structsize);
298 * Compute the static data needed to carry on.
300 toaddr = srcadr;
301 frominter = inter;
302 seqno = 0;
303 nitems = 0;
304 itemsize = structsize;
305 databytes = 0;
306 usingexbuf = 0;
309 * return the beginning of the packet buffer.
311 return &rpkt.data[0];
316 * more_pkt - return a data pointer for a new item.
318 static char *
319 more_pkt(void)
322 * If we were using the extra buffer, send the packet.
324 if (usingexbuf) {
325 DPRINTF(3, ("request: sending pkt\n"));
326 rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, MORE_BIT, reqver);
327 rpkt.auth_seq = AUTH_SEQ(0, seqno);
328 rpkt.err_nitems = htons((u_short)nitems);
329 sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt,
330 RESP_HEADER_SIZE + databytes);
331 numresppkts++;
334 * Copy data out of exbuf into the packet.
336 memcpy(&rpkt.data[0], exbuf, (unsigned)itemsize);
337 seqno++;
338 databytes = 0;
339 nitems = 0;
340 usingexbuf = 0;
343 databytes += itemsize;
344 nitems++;
345 if (databytes + itemsize <= RESP_DATA_SIZE) {
346 DPRINTF(4, ("request: giving him more data\n"));
348 * More room in packet. Give him the
349 * next address.
351 return &rpkt.data[databytes];
352 } else {
354 * No room in packet. Give him the extra
355 * buffer unless this was the last in the sequence.
357 DPRINTF(4, ("request: into extra buffer\n"));
358 if (seqno == MAXSEQ)
359 return NULL;
360 else {
361 usingexbuf = 1;
362 return exbuf;
369 * flush_pkt - we're done, return remaining information.
371 static void
372 flush_pkt(void)
374 DPRINTF(3, ("request: flushing packet, %d items\n", nitems));
376 * Must send the last packet. If nothing in here and nothing
377 * has been sent, send an error saying no data to be found.
379 if (seqno == 0 && nitems == 0)
380 req_ack(toaddr, frominter, (struct req_pkt *)&rpkt,
381 INFO_ERR_NODATA);
382 else {
383 rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver);
384 rpkt.auth_seq = AUTH_SEQ(0, seqno);
385 rpkt.err_nitems = htons((u_short)nitems);
386 sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt,
387 RESP_HEADER_SIZE+databytes);
388 numresppkts++;
395 * Given a buffer, return the packet mode
398 get_packet_mode(struct recvbuf *rbufp)
400 struct req_pkt *inpkt = (struct req_pkt *)&rbufp->recv_pkt;
401 return (INFO_MODE(inpkt->rm_vn_mode));
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 sockaddr_u *srcadr;
417 struct interface *inter;
418 struct req_proc *proc;
419 int ec;
420 short temp_size;
421 l_fp ftmp;
422 double dtemp;
423 size_t recv_len;
424 size_t noslop_len;
425 size_t mac_len;
428 * Initialize pointers, for convenience
430 recv_len = rbufp->recv_length;
431 inpkt = (struct req_pkt *)&rbufp->recv_pkt;
432 srcadr = &rbufp->recv_srcadr;
433 inter = rbufp->dstadr;
435 DPRINTF(3, ("process_private: impl %d req %d\n",
436 inpkt->implementation, inpkt->request));
439 * Do some sanity checks on the packet. Return a format
440 * error if it fails.
442 ec = 0;
443 if ( (++ec, ISRESPONSE(inpkt->rm_vn_mode))
444 || (++ec, ISMORE(inpkt->rm_vn_mode))
445 || (++ec, INFO_VERSION(inpkt->rm_vn_mode) > NTP_VERSION)
446 || (++ec, INFO_VERSION(inpkt->rm_vn_mode) < NTP_OLDVERSION)
447 || (++ec, INFO_SEQ(inpkt->auth_seq) != 0)
448 || (++ec, INFO_ERR(inpkt->err_nitems) != 0)
449 || (++ec, INFO_MBZ(inpkt->mbz_itemsize) != 0)
450 || (++ec, rbufp->recv_length < REQ_LEN_HDR)
452 msyslog(LOG_ERR, "process_private: INFO_ERR_FMT: test %d failed, pkt from %s", ec, stoa(srcadr));
453 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
454 return;
457 reqver = INFO_VERSION(inpkt->rm_vn_mode);
460 * Get the appropriate procedure list to search.
462 if (inpkt->implementation == IMPL_UNIV)
463 proc = univ_codes;
464 else if ((inpkt->implementation == IMPL_XNTPD) ||
465 (inpkt->implementation == IMPL_XNTPD_OLD))
466 proc = ntp_codes;
467 else {
468 req_ack(srcadr, inter, inpkt, INFO_ERR_IMPL);
469 return;
473 * Search the list for the request codes. If it isn't one
474 * we know, return an error.
476 while (proc->request_code != NO_REQUEST) {
477 if (proc->request_code == (short) inpkt->request)
478 break;
479 proc++;
481 if (proc->request_code == NO_REQUEST) {
482 req_ack(srcadr, inter, inpkt, INFO_ERR_REQ);
483 return;
486 DPRINTF(4, ("found request in tables\n"));
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 DPRINTF(3, ("process_private: wrong item size, received %d, should be %d or %d\n",
506 temp_size, proc->sizeofitem, proc->v6_sizeofitem));
507 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
508 return;
510 if ((proc->sizeofitem != 0) &&
511 ((size_t)(temp_size * INFO_NITEMS(inpkt->err_nitems)) >
512 (recv_len - REQ_LEN_HDR))) {
513 DPRINTF(3, ("process_private: not enough data\n"));
514 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
515 return;
518 switch (inpkt->implementation) {
519 case IMPL_XNTPD:
520 client_v6_capable = 1;
521 break;
522 case IMPL_XNTPD_OLD:
523 client_v6_capable = 0;
524 break;
525 default:
526 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
527 return;
531 * If we need to authenticate, do so. Note that an
532 * authenticatable packet must include a mac field, must
533 * have used key info_auth_keyid and must have included
534 * a time stamp in the appropriate field. The time stamp
535 * must be within INFO_TS_MAXSKEW of the receive
536 * time stamp.
538 if (proc->needs_auth && sys_authenticate) {
540 if (recv_len < (REQ_LEN_HDR +
541 (INFO_ITEMSIZE(inpkt->mbz_itemsize) *
542 INFO_NITEMS(inpkt->err_nitems)) +
543 REQ_TAIL_MIN)) {
544 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
545 return;
549 * For 16-octet digests, regardless of itemsize and
550 * nitems, authenticated requests are a fixed size
551 * with the timestamp, key ID, and digest located
552 * at the end of the packet. Because the key ID
553 * determining the digest size precedes the digest,
554 * for larger digests the fixed size request scheme
555 * is abandoned and the timestamp, key ID, and digest
556 * are located relative to the start of the packet,
557 * with the digest size determined by the packet size.
559 noslop_len = REQ_LEN_HDR
560 + INFO_ITEMSIZE(inpkt->mbz_itemsize) *
561 INFO_NITEMS(inpkt->err_nitems)
562 + sizeof(inpkt->tstamp);
563 /* 32-bit alignment */
564 noslop_len = (noslop_len + 3) & ~3;
565 if (recv_len > (noslop_len + MAX_MAC_LEN))
566 mac_len = 20;
567 else
568 mac_len = recv_len - noslop_len;
570 tailinpkt = (void *)((char *)inpkt + recv_len -
571 (mac_len + sizeof(inpkt->tstamp)));
574 * If this guy is restricted from doing this, don't let
575 * him. If the wrong key was used, or packet doesn't
576 * have mac, return.
578 if (!INFO_IS_AUTH(inpkt->auth_seq) || !info_auth_keyid
579 || ntohl(tailinpkt->keyid) != info_auth_keyid) {
580 DPRINTF(5, ("failed auth %d info_auth_keyid %u pkt keyid %u maclen %u\n",
581 INFO_IS_AUTH(inpkt->auth_seq),
582 info_auth_keyid,
583 ntohl(tailinpkt->keyid), mac_len));
584 #ifdef DEBUG
585 msyslog(LOG_DEBUG,
586 "process_private: failed auth %d info_auth_keyid %u pkt keyid %u maclen %u\n",
587 INFO_IS_AUTH(inpkt->auth_seq),
588 info_auth_keyid,
589 ntohl(tailinpkt->keyid), mac_len);
590 #endif
591 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
592 return;
594 if (recv_len > REQ_LEN_NOMAC + MAX_MAC_LEN) {
595 DPRINTF(5, ("bad pkt length %d\n", recv_len));
596 msyslog(LOG_ERR,
597 "process_private: bad pkt length %d",
598 recv_len);
599 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
600 return;
602 if (!mod_okay || !authhavekey(info_auth_keyid)) {
603 DPRINTF(5, ("failed auth mod_okay %d\n",
604 mod_okay));
605 #ifdef DEBUG
606 msyslog(LOG_DEBUG,
607 "process_private: failed auth mod_okay %d\n",
608 mod_okay);
609 #endif
610 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
611 return;
615 * calculate absolute time difference between xmit time stamp
616 * and receive time stamp. If too large, too bad.
618 NTOHL_FP(&tailinpkt->tstamp, &ftmp);
619 L_SUB(&ftmp, &rbufp->recv_time);
620 LFPTOD(&ftmp, dtemp);
621 if (fabs(dtemp) > INFO_TS_MAXSKEW) {
623 * He's a loser. Tell him.
625 DPRINTF(5, ("xmit/rcv timestamp delta %g > INFO_TS_MAXSKEW %g\n",
626 dtemp, INFO_TS_MAXSKEW));
627 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
628 return;
632 * So far so good. See if decryption works out okay.
634 if (!authdecrypt(info_auth_keyid, (u_int32 *)inpkt,
635 recv_len - mac_len, mac_len)) {
636 DPRINTF(5, ("authdecrypt failed\n"));
637 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
638 return;
642 DPRINTF(3, ("process_private: all okay, into handler\n"));
644 * Packet is okay. Call the handler to send him data.
646 (proc->handler)(srcadr, inter, inpkt);
651 * peer_list - send a list of the peers
653 static void
654 peer_list(
655 sockaddr_u *srcadr,
656 struct interface *inter,
657 struct req_pkt *inpkt
660 register struct info_peer_list *ip;
661 register struct peer *pp;
662 register int i;
663 register int skip = 0;
665 ip = (struct info_peer_list *)prepare_pkt(srcadr, inter, inpkt,
666 v6sizeof(struct info_peer_list));
667 for (i = 0; i < NTP_HASH_SIZE && ip != 0; i++) {
668 pp = peer_hash[i];
669 while (pp != 0 && ip != 0) {
670 if (IS_IPV6(&pp->srcadr)) {
671 if (client_v6_capable) {
672 ip->addr6 = SOCK_ADDR6(&pp->srcadr);
673 ip->v6_flag = 1;
674 skip = 0;
675 } else {
676 skip = 1;
677 break;
679 } else {
680 ip->addr = NSRCADR(&pp->srcadr);
681 if (client_v6_capable)
682 ip->v6_flag = 0;
683 skip = 0;
686 if(!skip) {
687 ip->port = NSRCPORT(&pp->srcadr);
688 ip->hmode = pp->hmode;
689 ip->flags = 0;
690 if (pp->flags & FLAG_CONFIG)
691 ip->flags |= INFO_FLAG_CONFIG;
692 if (pp == sys_peer)
693 ip->flags |= INFO_FLAG_SYSPEER;
694 if (pp->status == CTL_PST_SEL_SYNCCAND)
695 ip->flags |= INFO_FLAG_SEL_CANDIDATE;
696 if (pp->status >= CTL_PST_SEL_SYSPEER)
697 ip->flags |= INFO_FLAG_SHORTLIST;
698 ip = (struct info_peer_list *)more_pkt();
700 pp = pp->next;
703 flush_pkt();
708 * peer_list_sum - return extended peer list
710 static void
711 peer_list_sum(
712 sockaddr_u *srcadr,
713 struct interface *inter,
714 struct req_pkt *inpkt
717 register struct info_peer_summary *ips;
718 register struct peer *pp;
719 register int i;
720 l_fp ltmp;
721 register int skip;
723 #ifdef DEBUG
724 if (debug > 2)
725 printf("wants peer list summary\n");
726 #endif
727 ips = (struct info_peer_summary *)prepare_pkt(srcadr, inter, inpkt,
728 v6sizeof(struct info_peer_summary));
729 for (i = 0; i < NTP_HASH_SIZE && ips != 0; i++) {
730 pp = peer_hash[i];
731 while (pp != 0 && ips != 0) {
732 #ifdef DEBUG
733 if (debug > 3)
734 printf("sum: got one\n");
735 #endif
737 * Be careful here not to return v6 peers when we
738 * want only v4.
740 if (IS_IPV6(&pp->srcadr)) {
741 if (client_v6_capable) {
742 ips->srcadr6 = SOCK_ADDR6(&pp->srcadr);
743 ips->v6_flag = 1;
744 if (pp->dstadr)
745 ips->dstadr6 = SOCK_ADDR6(&pp->dstadr->sin);
746 else
747 memset(&ips->dstadr6, 0, sizeof(ips->dstadr6));
748 skip = 0;
749 } else {
750 skip = 1;
751 break;
753 } else {
754 ips->srcadr = NSRCADR(&pp->srcadr);
755 if (client_v6_capable)
756 ips->v6_flag = 0;
758 if (pp->dstadr) {
759 if (!pp->processed)
760 ips->dstadr = NSRCADR(&pp->dstadr->sin);
761 else {
762 if (MDF_BCAST == pp->cast_flags)
763 ips->dstadr = NSRCADR(&pp->dstadr->bcast);
764 else if (pp->cast_flags) {
765 ips->dstadr = NSRCADR(&pp->dstadr->sin);
766 if (!ips->dstadr)
767 ips->dstadr = NSRCADR(&pp->dstadr->bcast);
770 } else
771 ips->dstadr = 0;
773 skip = 0;
776 if (!skip){
777 ips->srcport = NSRCPORT(&pp->srcadr);
778 ips->stratum = pp->stratum;
779 ips->hpoll = pp->hpoll;
780 ips->ppoll = pp->ppoll;
781 ips->reach = pp->reach;
782 ips->flags = 0;
783 if (pp == sys_peer)
784 ips->flags |= INFO_FLAG_SYSPEER;
785 if (pp->flags & FLAG_CONFIG)
786 ips->flags |= INFO_FLAG_CONFIG;
787 if (pp->flags & FLAG_REFCLOCK)
788 ips->flags |= INFO_FLAG_REFCLOCK;
789 if (pp->flags & FLAG_PREFER)
790 ips->flags |= INFO_FLAG_PREFER;
791 if (pp->flags & FLAG_BURST)
792 ips->flags |= INFO_FLAG_BURST;
793 if (pp->status == CTL_PST_SEL_SYNCCAND)
794 ips->flags |= INFO_FLAG_SEL_CANDIDATE;
795 if (pp->status >= CTL_PST_SEL_SYSPEER)
796 ips->flags |= INFO_FLAG_SHORTLIST;
797 ips->hmode = pp->hmode;
798 ips->delay = HTONS_FP(DTOFP(pp->delay));
799 DTOLFP(pp->offset, &ltmp);
800 HTONL_FP(&ltmp, &ips->offset);
801 ips->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp)));
803 pp = pp->next;
804 ips = (struct info_peer_summary *)more_pkt();
807 flush_pkt();
812 * peer_info - send information for one or more peers
814 static void
815 peer_info (
816 sockaddr_u *srcadr,
817 struct interface *inter,
818 struct req_pkt *inpkt
821 register struct info_peer_list *ipl;
822 register struct peer *pp;
823 register struct info_peer *ip;
824 register int items;
825 register int i, j;
826 sockaddr_u addr;
827 extern struct peer *sys_peer;
828 l_fp ltmp;
830 items = INFO_NITEMS(inpkt->err_nitems);
831 ipl = (struct info_peer_list *) inpkt->data;
833 ip = (struct info_peer *)prepare_pkt(srcadr, inter, inpkt,
834 v6sizeof(struct info_peer));
835 while (items-- > 0 && ip != 0) {
836 ZERO_SOCK(&addr);
837 NSRCPORT(&addr) = ipl->port;
838 if (client_v6_capable && ipl->v6_flag) {
839 AF(&addr) = AF_INET6;
840 SOCK_ADDR6(&addr) = ipl->addr6;
841 } else {
842 AF(&addr) = AF_INET;
843 NSRCADR(&addr) = ipl->addr;
845 #ifdef ISC_PLATFORM_HAVESALEN
846 addr.sas.ss_len = SOCKLEN(&addr);
847 #endif
848 ipl++;
849 if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0)
850 continue;
851 if (IS_IPV6(srcadr)) {
852 if (pp->dstadr)
853 ip->dstadr6 =
854 (MDF_BCAST == pp->cast_flags)
855 ? SOCK_ADDR6(&pp->dstadr->bcast)
856 : SOCK_ADDR6(&pp->dstadr->sin);
857 else
858 memset(&ip->dstadr6, 0, sizeof(ip->dstadr6));
860 ip->srcadr6 = SOCK_ADDR6(&pp->srcadr);
861 ip->v6_flag = 1;
862 } else {
863 if (pp->dstadr) {
864 if (!pp->processed)
865 ip->dstadr = NSRCADR(&pp->dstadr->sin);
866 else {
867 if (MDF_BCAST == pp->cast_flags)
868 ip->dstadr = NSRCADR(&pp->dstadr->bcast);
869 else if (pp->cast_flags) {
870 ip->dstadr = NSRCADR(&pp->dstadr->sin);
871 if (!ip->dstadr)
872 ip->dstadr = NSRCADR(&pp->dstadr->bcast);
875 } else
876 ip->dstadr = 0;
878 ip->srcadr = NSRCADR(&pp->srcadr);
879 if (client_v6_capable)
880 ip->v6_flag = 0;
882 ip->srcport = NSRCPORT(&pp->srcadr);
883 ip->flags = 0;
884 if (pp == sys_peer)
885 ip->flags |= INFO_FLAG_SYSPEER;
886 if (pp->flags & FLAG_CONFIG)
887 ip->flags |= INFO_FLAG_CONFIG;
888 if (pp->flags & FLAG_REFCLOCK)
889 ip->flags |= INFO_FLAG_REFCLOCK;
890 if (pp->flags & FLAG_PREFER)
891 ip->flags |= INFO_FLAG_PREFER;
892 if (pp->flags & FLAG_BURST)
893 ip->flags |= INFO_FLAG_BURST;
894 if (pp->status == CTL_PST_SEL_SYNCCAND)
895 ip->flags |= INFO_FLAG_SEL_CANDIDATE;
896 if (pp->status >= CTL_PST_SEL_SYSPEER)
897 ip->flags |= INFO_FLAG_SHORTLIST;
898 ip->leap = pp->leap;
899 ip->hmode = pp->hmode;
900 ip->keyid = pp->keyid;
901 ip->stratum = pp->stratum;
902 ip->ppoll = pp->ppoll;
903 ip->hpoll = pp->hpoll;
904 ip->precision = pp->precision;
905 ip->version = pp->version;
906 ip->reach = pp->reach;
907 ip->unreach = (u_char) pp->unreach;
908 ip->flash = (u_char)pp->flash;
909 ip->flash2 = (u_short) pp->flash;
910 ip->estbdelay = HTONS_FP(DTOFP(pp->delay));
911 ip->ttl = pp->ttl;
912 ip->associd = htons(pp->associd);
913 ip->rootdelay = HTONS_FP(DTOUFP(pp->rootdelay));
914 ip->rootdispersion = HTONS_FP(DTOUFP(pp->rootdisp));
915 ip->refid = pp->refid;
916 HTONL_FP(&pp->reftime, &ip->reftime);
917 HTONL_FP(&pp->aorg, &ip->org);
918 HTONL_FP(&pp->rec, &ip->rec);
919 HTONL_FP(&pp->xmt, &ip->xmt);
920 j = pp->filter_nextpt - 1;
921 for (i = 0; i < NTP_SHIFT; i++, j--) {
922 if (j < 0)
923 j = NTP_SHIFT-1;
924 ip->filtdelay[i] = HTONS_FP(DTOFP(pp->filter_delay[j]));
925 DTOLFP(pp->filter_offset[j], &ltmp);
926 HTONL_FP(&ltmp, &ip->filtoffset[i]);
927 ip->order[i] = (u_char)((pp->filter_nextpt+NTP_SHIFT-1)
928 - pp->filter_order[i]);
929 if (ip->order[i] >= NTP_SHIFT)
930 ip->order[i] -= NTP_SHIFT;
932 DTOLFP(pp->offset, &ltmp);
933 HTONL_FP(&ltmp, &ip->offset);
934 ip->delay = HTONS_FP(DTOFP(pp->delay));
935 ip->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp)));
936 ip->selectdisp = HTONS_FP(DTOUFP(SQRT(pp->jitter)));
937 ip = (struct info_peer *)more_pkt();
939 flush_pkt();
944 * peer_stats - send statistics for one or more peers
946 static void
947 peer_stats (
948 sockaddr_u *srcadr,
949 struct interface *inter,
950 struct req_pkt *inpkt
953 register struct info_peer_list *ipl;
954 register struct peer *pp;
955 register struct info_peer_stats *ip;
956 register int items;
957 sockaddr_u addr;
958 extern struct peer *sys_peer;
960 #ifdef DEBUG
961 if (debug)
962 printf("peer_stats: called\n");
963 #endif
964 items = INFO_NITEMS(inpkt->err_nitems);
965 ipl = (struct info_peer_list *) inpkt->data;
966 ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt,
967 v6sizeof(struct info_peer_stats));
968 while (items-- > 0 && ip != 0) {
969 memset((char *)&addr, 0, sizeof(addr));
970 NSRCPORT(&addr) = ipl->port;
971 if (client_v6_capable && ipl->v6_flag) {
972 AF(&addr) = AF_INET6;
973 SOCK_ADDR6(&addr) = ipl->addr6;
974 } else {
975 AF(&addr) = AF_INET;
976 NSRCADR(&addr) = ipl->addr;
978 #ifdef ISC_PLATFORM_HAVESALEN
979 addr.sas.ss_len = SOCKLEN(&addr);
980 #endif
981 DPRINTF(1, ("peer_stats: looking for %s, %d, %d\n",
982 stoa(&addr), ipl->port, NSRCPORT(&addr)));
984 ipl = (struct info_peer_list *)((char *)ipl +
985 INFO_ITEMSIZE(inpkt->mbz_itemsize));
987 if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == NULL)
988 continue;
990 DPRINTF(1, ("peer_stats: found %s\n", stoa(&addr)));
992 if (IS_IPV4(&pp->srcadr)) {
993 if (pp->dstadr) {
994 if (!pp->processed)
995 ip->dstadr = NSRCADR(&pp->dstadr->sin);
996 else {
997 if (MDF_BCAST == pp->cast_flags)
998 ip->dstadr = NSRCADR(&pp->dstadr->bcast);
999 else if (pp->cast_flags) {
1000 ip->dstadr = NSRCADR(&pp->dstadr->sin);
1001 if (!ip->dstadr)
1002 ip->dstadr = NSRCADR(&pp->dstadr->bcast);
1005 } else
1006 ip->dstadr = 0;
1008 ip->srcadr = NSRCADR(&pp->srcadr);
1009 if (client_v6_capable)
1010 ip->v6_flag = 0;
1011 } else {
1012 if (pp->dstadr)
1013 ip->dstadr6 =
1014 (MDF_BCAST == pp->cast_flags)
1015 ? SOCK_ADDR6(&pp->dstadr->bcast)
1016 : SOCK_ADDR6(&pp->dstadr->sin);
1017 else
1018 memset(&ip->dstadr6, 0, sizeof(ip->dstadr6));
1020 ip->srcadr6 = SOCK_ADDR6(&pp->srcadr);
1021 ip->v6_flag = 1;
1023 ip->srcport = NSRCPORT(&pp->srcadr);
1024 ip->flags = 0;
1025 if (pp == sys_peer)
1026 ip->flags |= INFO_FLAG_SYSPEER;
1027 if (pp->flags & FLAG_CONFIG)
1028 ip->flags |= INFO_FLAG_CONFIG;
1029 if (pp->flags & FLAG_REFCLOCK)
1030 ip->flags |= INFO_FLAG_REFCLOCK;
1031 if (pp->flags & FLAG_PREFER)
1032 ip->flags |= INFO_FLAG_PREFER;
1033 if (pp->flags & FLAG_BURST)
1034 ip->flags |= INFO_FLAG_BURST;
1035 if (pp->flags & FLAG_IBURST)
1036 ip->flags |= INFO_FLAG_IBURST;
1037 if (pp->status == CTL_PST_SEL_SYNCCAND)
1038 ip->flags |= INFO_FLAG_SEL_CANDIDATE;
1039 if (pp->status >= CTL_PST_SEL_SYSPEER)
1040 ip->flags |= INFO_FLAG_SHORTLIST;
1041 ip->flags = htons(ip->flags);
1042 ip->timereceived = htonl((u_int32)(current_time - pp->timereceived));
1043 ip->timetosend = htonl(pp->nextdate - current_time);
1044 ip->timereachable = htonl((u_int32)(current_time - pp->timereachable));
1045 ip->sent = htonl((u_int32)(pp->sent));
1046 ip->processed = htonl((u_int32)(pp->processed));
1047 ip->badauth = htonl((u_int32)(pp->badauth));
1048 ip->bogusorg = htonl((u_int32)(pp->bogusorg));
1049 ip->oldpkt = htonl((u_int32)(pp->oldpkt));
1050 ip->seldisp = htonl((u_int32)(pp->seldisptoolarge));
1051 ip->selbroken = htonl((u_int32)(pp->selbroken));
1052 ip->candidate = pp->status;
1053 ip = (struct info_peer_stats *)more_pkt();
1055 flush_pkt();
1060 * sys_info - return system info
1062 static void
1063 sys_info(
1064 sockaddr_u *srcadr,
1065 struct interface *inter,
1066 struct req_pkt *inpkt
1069 register struct info_sys *is;
1071 is = (struct info_sys *)prepare_pkt(srcadr, inter, inpkt,
1072 v6sizeof(struct info_sys));
1074 if (sys_peer) {
1075 if (IS_IPV4(&sys_peer->srcadr)) {
1076 is->peer = NSRCADR(&sys_peer->srcadr);
1077 if (client_v6_capable)
1078 is->v6_flag = 0;
1079 } else if (client_v6_capable) {
1080 is->peer6 = SOCK_ADDR6(&sys_peer->srcadr);
1081 is->v6_flag = 1;
1083 is->peer_mode = sys_peer->hmode;
1084 } else {
1085 is->peer = 0;
1086 if (client_v6_capable) {
1087 is->v6_flag = 0;
1089 is->peer_mode = 0;
1092 is->leap = sys_leap;
1093 is->stratum = sys_stratum;
1094 is->precision = sys_precision;
1095 is->rootdelay = htonl(DTOFP(sys_rootdelay));
1096 is->rootdispersion = htonl(DTOUFP(sys_rootdisp));
1097 is->frequency = htonl(DTOFP(sys_jitter));
1098 is->stability = htonl(DTOUFP(clock_stability));
1099 is->refid = sys_refid;
1100 HTONL_FP(&sys_reftime, &is->reftime);
1102 is->poll = sys_poll;
1104 is->flags = 0;
1105 if (sys_authenticate)
1106 is->flags |= INFO_FLAG_AUTHENTICATE;
1107 if (sys_bclient)
1108 is->flags |= INFO_FLAG_BCLIENT;
1109 #ifdef REFCLOCK
1110 if (cal_enable)
1111 is->flags |= INFO_FLAG_CAL;
1112 #endif /* REFCLOCK */
1113 if (kern_enable)
1114 is->flags |= INFO_FLAG_KERNEL;
1115 if (mon_enabled != MON_OFF)
1116 is->flags |= INFO_FLAG_MONITOR;
1117 if (ntp_enable)
1118 is->flags |= INFO_FLAG_NTP;
1119 if (pps_enable)
1120 is->flags |= INFO_FLAG_PPS_SYNC;
1121 if (stats_control)
1122 is->flags |= INFO_FLAG_FILEGEN;
1123 is->bdelay = HTONS_FP(DTOFP(sys_bdelay));
1124 HTONL_UF(sys_authdelay.l_f, &is->authdelay);
1125 (void) more_pkt();
1126 flush_pkt();
1131 * sys_stats - return system statistics
1133 static void
1134 sys_stats(
1135 sockaddr_u *srcadr,
1136 struct interface *inter,
1137 struct req_pkt *inpkt
1140 register struct info_sys_stats *ss;
1143 * Importations from the protocol module
1145 ss = (struct info_sys_stats *)prepare_pkt(srcadr, inter, inpkt,
1146 sizeof(struct info_sys_stats));
1147 ss->timeup = htonl((u_int32)current_time);
1148 ss->timereset = htonl((u_int32)(current_time - sys_stattime));
1149 ss->denied = htonl((u_int32)sys_restricted);
1150 ss->oldversionpkt = htonl((u_int32)sys_oldversion);
1151 ss->newversionpkt = htonl((u_int32)sys_newversion);
1152 ss->unknownversion = htonl((u_int32)sys_declined);
1153 ss->badlength = htonl((u_int32)sys_badlength);
1154 ss->processed = htonl((u_int32)sys_processed);
1155 ss->badauth = htonl((u_int32)sys_badauth);
1156 ss->limitrejected = htonl((u_int32)sys_limitrejected);
1157 ss->received = htonl((u_int32)sys_received);
1158 (void) more_pkt();
1159 flush_pkt();
1164 * mem_stats - return memory statistics
1166 static void
1167 mem_stats(
1168 sockaddr_u *srcadr,
1169 struct interface *inter,
1170 struct req_pkt *inpkt
1173 register struct info_mem_stats *ms;
1174 register int i;
1177 * Importations from the peer module
1179 extern int peer_hash_count[];
1180 extern int peer_free_count;
1181 extern u_long peer_timereset;
1182 extern u_long findpeer_calls;
1183 extern u_long peer_allocations;
1184 extern u_long peer_demobilizations;
1185 extern int total_peer_structs;
1187 ms = (struct info_mem_stats *)prepare_pkt(srcadr, inter, inpkt,
1188 sizeof(struct info_mem_stats));
1190 ms->timereset = htonl((u_int32)(current_time - peer_timereset));
1191 ms->totalpeermem = htons((u_short)total_peer_structs);
1192 ms->freepeermem = htons((u_short)peer_free_count);
1193 ms->findpeer_calls = htonl((u_int32)findpeer_calls);
1194 ms->allocations = htonl((u_int32)peer_allocations);
1195 ms->demobilizations = htonl((u_int32)peer_demobilizations);
1197 for (i = 0; i < NTP_HASH_SIZE; i++) {
1198 if (peer_hash_count[i] > 255)
1199 ms->hashcount[i] = 255;
1200 else
1201 ms->hashcount[i] = (u_char)peer_hash_count[i];
1204 (void) more_pkt();
1205 flush_pkt();
1210 * io_stats - return io statistics
1212 static void
1213 io_stats(
1214 sockaddr_u *srcadr,
1215 struct interface *inter,
1216 struct req_pkt *inpkt
1219 register struct info_io_stats *io;
1222 * Importations from the io module
1224 extern u_long io_timereset;
1226 io = (struct info_io_stats *)prepare_pkt(srcadr, inter, inpkt,
1227 sizeof(struct info_io_stats));
1229 io->timereset = htonl((u_int32)(current_time - io_timereset));
1230 io->totalrecvbufs = htons((u_short) total_recvbuffs());
1231 io->freerecvbufs = htons((u_short) free_recvbuffs());
1232 io->fullrecvbufs = htons((u_short) full_recvbuffs());
1233 io->lowwater = htons((u_short) lowater_additions());
1234 io->dropped = htonl((u_int32)packets_dropped);
1235 io->ignored = htonl((u_int32)packets_ignored);
1236 io->received = htonl((u_int32)packets_received);
1237 io->sent = htonl((u_int32)packets_sent);
1238 io->notsent = htonl((u_int32)packets_notsent);
1239 io->interrupts = htonl((u_int32)handler_calls);
1240 io->int_received = htonl((u_int32)handler_pkts);
1242 (void) more_pkt();
1243 flush_pkt();
1248 * timer_stats - return timer statistics
1250 static void
1251 timer_stats(
1252 sockaddr_u *srcadr,
1253 struct interface *inter,
1254 struct req_pkt *inpkt
1257 register struct info_timer_stats *ts;
1260 * Importations from the timer module
1262 extern u_long timer_timereset;
1263 extern u_long timer_overflows;
1264 extern u_long timer_xmtcalls;
1266 ts = (struct info_timer_stats *)prepare_pkt(srcadr, inter, inpkt,
1267 sizeof(struct info_timer_stats));
1269 ts->timereset = htonl((u_int32)(current_time - timer_timereset));
1270 ts->alarms = htonl((u_int32)alarm_overflow);
1271 ts->overflows = htonl((u_int32)timer_overflows);
1272 ts->xmtcalls = htonl((u_int32)timer_xmtcalls);
1274 (void) more_pkt();
1275 flush_pkt();
1280 * loop_info - return the current state of the loop filter
1282 static void
1283 loop_info(
1284 sockaddr_u *srcadr,
1285 struct interface *inter,
1286 struct req_pkt *inpkt
1289 register struct info_loop *li;
1290 l_fp ltmp;
1293 * Importations from the loop filter module
1295 extern double last_offset;
1296 extern double drift_comp;
1297 extern int tc_counter;
1298 extern u_long sys_epoch;
1300 li = (struct info_loop *)prepare_pkt(srcadr, inter, inpkt,
1301 sizeof(struct info_loop));
1303 DTOLFP(last_offset, &ltmp);
1304 HTONL_FP(&ltmp, &li->last_offset);
1305 DTOLFP(drift_comp * 1e6, &ltmp);
1306 HTONL_FP(&ltmp, &li->drift_comp);
1307 li->compliance = htonl((u_int32)(tc_counter));
1308 li->watchdog_timer = htonl((u_int32)(current_time - sys_epoch));
1310 (void) more_pkt();
1311 flush_pkt();
1316 * do_conf - add a peer to the configuration list
1318 static void
1319 do_conf(
1320 sockaddr_u *srcadr,
1321 struct interface *inter,
1322 struct req_pkt *inpkt
1325 static u_long soonest_ifrescan_time = 0;
1326 int items;
1327 u_int fl;
1328 struct conf_peer *cp;
1329 struct conf_peer temp_cp;
1330 sockaddr_u peeraddr;
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));
1342 #if 0 /* paranoid checking - these are done in newpeer() */
1343 fl = 0;
1344 while (items-- > 0 && !fl) {
1345 if (((temp_cp.version) > NTP_VERSION)
1346 || ((temp_cp.version) < NTP_OLDVERSION))
1347 fl = 1;
1348 if (temp_cp.hmode != MODE_ACTIVE
1349 && temp_cp.hmode != MODE_CLIENT
1350 && temp_cp.hmode != MODE_BROADCAST)
1351 fl = 1;
1352 if (temp_cp.flags & ~(CONF_FLAG_PREFER | CONF_FLAG_BURST |
1353 CONF_FLAG_IBURST | CONF_FLAG_SKEY))
1354 fl = 1;
1355 cp = (struct conf_peer *)
1356 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1359 if (fl) {
1360 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1361 return;
1363 #endif /* end paranoid checking */
1366 * Looks okay, try it out
1368 items = INFO_NITEMS(inpkt->err_nitems);
1369 cp = (struct conf_peer *)inpkt->data;
1371 while (items-- > 0) {
1372 memset(&temp_cp, 0, sizeof(struct conf_peer));
1373 memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1374 ZERO_SOCK(&peeraddr);
1376 fl = 0;
1377 if (temp_cp.flags & CONF_FLAG_PREFER)
1378 fl |= FLAG_PREFER;
1379 if (temp_cp.flags & CONF_FLAG_BURST)
1380 fl |= FLAG_BURST;
1381 if (temp_cp.flags & CONF_FLAG_IBURST)
1382 fl |= FLAG_IBURST;
1383 #ifdef OPENSSL
1384 if (temp_cp.flags & CONF_FLAG_SKEY)
1385 fl |= FLAG_SKEY;
1386 #endif /* OPENSSL */
1387 if (client_v6_capable && temp_cp.v6_flag != 0) {
1388 AF(&peeraddr) = AF_INET6;
1389 SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6;
1390 } else {
1391 AF(&peeraddr) = AF_INET;
1392 NSRCADR(&peeraddr) = temp_cp.peeraddr;
1394 * Make sure the address is valid
1396 if (!ISREFCLOCKADR(&peeraddr) &&
1397 ISBADADR(&peeraddr)) {
1398 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1399 return;
1403 NSRCPORT(&peeraddr) = htons(NTP_PORT);
1404 #ifdef ISC_PLATFORM_HAVESALEN
1405 peeraddr.sas.ss_len = SOCKLEN(&peeraddr);
1406 #endif
1408 /* XXX W2DO? minpoll/maxpoll arguments ??? */
1409 if (peer_config(&peeraddr, (struct interface *)0,
1410 temp_cp.hmode, temp_cp.version, temp_cp.minpoll,
1411 temp_cp.maxpoll, fl, temp_cp.ttl, temp_cp.keyid,
1412 NULL) == 0) {
1413 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1414 return;
1418 * ntp_intres.c uses REQ_CONFIG/doconf() to add each
1419 * server after its name is resolved. If we have been
1420 * disconnected from the network, it may notice the
1421 * network has returned and add the first server while
1422 * the relevant interface is still disabled, awaiting
1423 * the next interface rescan. To get things moving
1424 * more quickly, trigger an interface scan now, except
1425 * if we have done so in the last half minute.
1427 if (soonest_ifrescan_time < current_time) {
1428 soonest_ifrescan_time = current_time + 30;
1429 timer_interfacetimeout(current_time);
1430 DPRINTF(1, ("do_conf triggering interface rescan\n"));
1433 cp = (struct conf_peer *)
1434 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1437 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1440 #if 0
1441 /* XXX */
1443 * dns_a - Snarf DNS info for an association ID
1445 static void
1446 dns_a(
1447 sockaddr_u *srcadr,
1448 struct interface *inter,
1449 struct req_pkt *inpkt
1452 register struct info_dns_assoc *dp;
1453 register int items;
1454 struct sockaddr_in peeraddr;
1457 * Do a check of everything to see that it looks
1458 * okay. If not, complain about it. Note we are
1459 * very picky here.
1461 items = INFO_NITEMS(inpkt->err_nitems);
1462 dp = (struct info_dns_assoc *)inpkt->data;
1465 * Looks okay, try it out
1467 items = INFO_NITEMS(inpkt->err_nitems);
1468 dp = (struct info_dns_assoc *)inpkt->data;
1469 memset((char *)&peeraddr, 0, sizeof(struct sockaddr_in));
1470 peeraddr.sin_family = AF_INET;
1471 peeraddr.sin_port = htons(NTP_PORT);
1474 * Make sure the address is valid
1476 if (!ISREFCLOCKADR(&peeraddr) && ISBADADR(&peeraddr)) {
1477 msyslog(LOG_ERR, "dns_a: !ISREFCLOCKADR && ISBADADR");
1478 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1479 return;
1482 while (items-- > 0) {
1483 associd_t associd;
1484 size_t hnl;
1485 struct peer *peer;
1486 int bogon = 0;
1488 associd = dp->associd;
1489 peer = findpeerbyassoc(associd);
1490 if (peer == 0 || peer->flags & FLAG_REFCLOCK) {
1491 msyslog(LOG_ERR, "dns_a: %s",
1492 (peer == 0)
1493 ? "peer == 0"
1494 : "peer->flags & FLAG_REFCLOCK");
1495 ++bogon;
1497 peeraddr.sin_addr.s_addr = dp->peeraddr;
1498 for (hnl = 0; dp->hostname[hnl] && hnl < sizeof dp->hostname; ++hnl) ;
1499 if (hnl >= sizeof dp->hostname) {
1500 msyslog(LOG_ERR, "dns_a: hnl (%ld) >= %ld",
1501 (long)hnl, (long)sizeof dp->hostname);
1502 ++bogon;
1505 msyslog(LOG_INFO, "dns_a: <%s> for %s, AssocID %d, bogon %d",
1506 dp->hostname,
1507 stoa((sockaddr_u *)&peeraddr), associd,
1508 bogon);
1510 if (bogon) {
1511 /* If it didn't work */
1512 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1513 return;
1514 } else {
1515 #if 0
1516 #ifdef PUBKEY
1517 crypto_public(peer, dp->hostname);
1518 #endif /* PUBKEY */
1519 #endif
1522 dp++;
1525 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1527 #endif /* 0 */
1530 * do_unconf - remove a peer from the configuration list
1532 static void
1533 do_unconf(
1534 sockaddr_u *srcadr,
1535 struct interface *inter,
1536 struct req_pkt *inpkt
1539 register struct conf_unpeer *cp;
1540 struct conf_unpeer temp_cp;
1541 register int items;
1542 register struct peer *peer;
1543 sockaddr_u peeraddr;
1544 int bad, found;
1547 * This is a bit unstructured, but I like to be careful.
1548 * We check to see that every peer exists and is actually
1549 * configured. If so, we remove them. If not, we return
1550 * an error.
1552 items = INFO_NITEMS(inpkt->err_nitems);
1553 cp = (struct conf_unpeer *)inpkt->data;
1555 bad = 0;
1556 while (items-- > 0 && !bad) {
1557 memset(&temp_cp, 0, sizeof(temp_cp));
1558 ZERO_SOCK(&peeraddr);
1559 memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1560 if (client_v6_capable && temp_cp.v6_flag) {
1561 AF(&peeraddr) = AF_INET6;
1562 SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6;
1563 } else {
1564 AF(&peeraddr) = AF_INET;
1565 NSRCADR(&peeraddr) = temp_cp.peeraddr;
1567 SET_PORT(&peeraddr, NTP_PORT);
1568 #ifdef ISC_PLATFORM_HAVESALEN
1569 peeraddr.sas.ss_len = SOCKLEN(&peeraddr);
1570 #endif
1571 found = 0;
1572 peer = NULL;
1574 DPRINTF(1, ("searching for %s\n", stoa(&peeraddr)));
1576 while (!found) {
1577 peer = findexistingpeer(&peeraddr, peer, -1);
1578 if (!peer)
1579 break;
1580 if (peer->flags & FLAG_CONFIG)
1581 found = 1;
1583 if (!found)
1584 bad = 1;
1585 cp = (struct conf_unpeer *)
1586 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1589 if (bad) {
1590 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1591 return;
1595 * Now do it in earnest.
1598 items = INFO_NITEMS(inpkt->err_nitems);
1599 cp = (struct conf_unpeer *)inpkt->data;
1601 while (items-- > 0) {
1602 memset(&temp_cp, 0, sizeof(temp_cp));
1603 memset(&peeraddr, 0, sizeof(peeraddr));
1604 memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1605 if (client_v6_capable && temp_cp.v6_flag) {
1606 AF(&peeraddr) = AF_INET6;
1607 SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6;
1608 } else {
1609 AF(&peeraddr) = AF_INET;
1610 NSRCADR(&peeraddr) = temp_cp.peeraddr;
1612 SET_PORT(&peeraddr, NTP_PORT);
1613 #ifdef ISC_PLATFORM_HAVESALEN
1614 peeraddr.sas.ss_len = SOCKLEN(&peeraddr);
1615 #endif
1616 found = 0;
1617 peer = NULL;
1619 while (!found) {
1620 peer = findexistingpeer(&peeraddr, peer, -1);
1621 if (!peer)
1622 break;
1623 if (peer->flags & FLAG_CONFIG)
1624 found = 1;
1626 NTP_INSIST(found);
1627 NTP_INSIST(peer);
1629 peer_clear(peer, "GONE");
1630 unpeer(peer);
1632 cp = (struct conf_unpeer *)
1633 ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1636 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1641 * set_sys_flag - set system flags
1643 static void
1644 set_sys_flag(
1645 sockaddr_u *srcadr,
1646 struct interface *inter,
1647 struct req_pkt *inpkt
1650 setclr_flags(srcadr, inter, inpkt, 1);
1655 * clr_sys_flag - clear system flags
1657 static void
1658 clr_sys_flag(
1659 sockaddr_u *srcadr,
1660 struct interface *inter,
1661 struct req_pkt *inpkt
1664 setclr_flags(srcadr, inter, inpkt, 0);
1669 * setclr_flags - do the grunge work of flag setting/clearing
1671 static void
1672 setclr_flags(
1673 sockaddr_u *srcadr,
1674 struct interface *inter,
1675 struct req_pkt *inpkt,
1676 u_long set
1679 register u_int flags;
1680 int prev_kern_enable;
1682 prev_kern_enable = kern_enable;
1683 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
1684 msyslog(LOG_ERR, "setclr_flags: err_nitems > 1");
1685 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1686 return;
1689 flags = ((struct conf_sys_flags *)inpkt->data)->flags;
1690 flags = ntohl(flags);
1692 if (flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS |
1693 SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR |
1694 SYS_FLAG_FILEGEN | SYS_FLAG_AUTH | SYS_FLAG_CAL)) {
1695 msyslog(LOG_ERR, "setclr_flags: extra flags: %#x",
1696 flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS |
1697 SYS_FLAG_NTP | SYS_FLAG_KERNEL |
1698 SYS_FLAG_MONITOR | SYS_FLAG_FILEGEN |
1699 SYS_FLAG_AUTH | SYS_FLAG_CAL));
1700 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1701 return;
1704 if (flags & SYS_FLAG_BCLIENT)
1705 proto_config(PROTO_BROADCLIENT, set, 0., NULL);
1706 if (flags & SYS_FLAG_PPS)
1707 proto_config(PROTO_PPS, set, 0., NULL);
1708 if (flags & SYS_FLAG_NTP)
1709 proto_config(PROTO_NTP, set, 0., NULL);
1710 if (flags & SYS_FLAG_KERNEL)
1711 proto_config(PROTO_KERNEL, set, 0., NULL);
1712 if (flags & SYS_FLAG_MONITOR)
1713 proto_config(PROTO_MONITOR, set, 0., NULL);
1714 if (flags & SYS_FLAG_FILEGEN)
1715 proto_config(PROTO_FILEGEN, set, 0., NULL);
1716 if (flags & SYS_FLAG_AUTH)
1717 proto_config(PROTO_AUTHENTICATE, set, 0., NULL);
1718 if (flags & SYS_FLAG_CAL)
1719 proto_config(PROTO_CAL, set, 0., NULL);
1720 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1722 /* Reset the kernel ntp parameters if the kernel flag changed. */
1723 if (prev_kern_enable && !kern_enable)
1724 loop_config(LOOP_KERN_CLEAR, 0.0);
1725 if (!prev_kern_enable && kern_enable)
1726 loop_config(LOOP_DRIFTCOMP, drift_comp);
1731 * list_restrict - return the restrict list
1733 static void
1734 list_restrict(
1735 sockaddr_u *srcadr,
1736 struct interface *inter,
1737 struct req_pkt *inpkt
1740 register struct info_restrict *ir;
1741 register struct restrictlist *rl;
1742 register struct restrictlist6 *rl6;
1744 #ifdef DEBUG
1745 if (debug > 2)
1746 printf("wants restrict list summary\n");
1747 #endif
1749 ir = (struct info_restrict *)prepare_pkt(srcadr, inter, inpkt,
1750 v6sizeof(struct info_restrict));
1752 for (rl = restrictlist; rl != 0 && ir != 0; rl = rl->next) {
1753 ir->addr = htonl(rl->addr);
1754 if (client_v6_capable)
1755 ir->v6_flag = 0;
1756 ir->mask = htonl(rl->mask);
1757 ir->count = htonl((u_int32)rl->count);
1758 ir->flags = htons(rl->flags);
1759 ir->mflags = htons(rl->mflags);
1760 ir = (struct info_restrict *)more_pkt();
1762 if (client_v6_capable)
1763 for (rl6 = restrictlist6; rl6 != 0 && ir != 0; rl6 = rl6->next) {
1764 ir->addr6 = rl6->addr6;
1765 ir->mask6 = rl6->mask6;
1766 ir->v6_flag = 1;
1767 ir->count = htonl((u_int32)rl6->count);
1768 ir->flags = htons(rl6->flags);
1769 ir->mflags = htons(rl6->mflags);
1770 ir = (struct info_restrict *)more_pkt();
1772 flush_pkt();
1778 * do_resaddflags - add flags to a restrict entry (or create one)
1780 static void
1781 do_resaddflags(
1782 sockaddr_u *srcadr,
1783 struct interface *inter,
1784 struct req_pkt *inpkt
1787 do_restrict(srcadr, inter, inpkt, RESTRICT_FLAGS);
1793 * do_ressubflags - remove flags from a restrict entry
1795 static void
1796 do_ressubflags(
1797 sockaddr_u *srcadr,
1798 struct interface *inter,
1799 struct req_pkt *inpkt
1802 do_restrict(srcadr, inter, inpkt, RESTRICT_UNFLAG);
1807 * do_unrestrict - remove a restrict entry from the list
1809 static void
1810 do_unrestrict(
1811 sockaddr_u *srcadr,
1812 struct interface *inter,
1813 struct req_pkt *inpkt
1816 do_restrict(srcadr, inter, inpkt, RESTRICT_REMOVE);
1821 * do_restrict - do the dirty stuff of dealing with restrictions
1823 static void
1824 do_restrict(
1825 sockaddr_u *srcadr,
1826 struct interface *inter,
1827 struct req_pkt *inpkt,
1828 int op
1831 register struct conf_restrict *cr;
1832 register int items;
1833 sockaddr_u matchaddr;
1834 sockaddr_u matchmask;
1835 int bad;
1838 * Do a check of the flags to make sure that only
1839 * the NTPPORT flag is set, if any. If not, complain
1840 * about it. Note we are very picky here.
1842 items = INFO_NITEMS(inpkt->err_nitems);
1843 cr = (struct conf_restrict *)inpkt->data;
1845 bad = 0;
1846 cr->flags = ntohs(cr->flags);
1847 cr->mflags = ntohs(cr->mflags);
1848 while (items-- > 0 && !bad) {
1849 if (cr->mflags & ~(RESM_NTPONLY))
1850 bad |= 1;
1851 if (cr->flags & ~(RES_ALLFLAGS))
1852 bad |= 2;
1853 if (cr->mask != htonl(INADDR_ANY)) {
1854 if (client_v6_capable && cr->v6_flag != 0) {
1855 if (IN6_IS_ADDR_UNSPECIFIED(&cr->addr6))
1856 bad |= 4;
1857 } else
1858 if (cr->addr == htonl(INADDR_ANY))
1859 bad |= 8;
1861 cr = (struct conf_restrict *)((char *)cr +
1862 INFO_ITEMSIZE(inpkt->mbz_itemsize));
1865 if (bad) {
1866 msyslog(LOG_ERR, "do_restrict: bad = %#x", bad);
1867 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1868 return;
1872 * Looks okay, try it out
1874 items = INFO_NITEMS(inpkt->err_nitems);
1875 cr = (struct conf_restrict *)inpkt->data;
1876 ZERO_SOCK(&matchaddr);
1877 ZERO_SOCK(&matchmask);
1879 while (items-- > 0) {
1880 if (client_v6_capable && cr->v6_flag) {
1881 AF(&matchaddr) = AF_INET6;
1882 AF(&matchmask) = AF_INET6;
1883 SOCK_ADDR6(&matchaddr) = cr->addr6;
1884 SOCK_ADDR6(&matchmask) = cr->mask6;
1885 } else {
1886 AF(&matchaddr) = AF_INET;
1887 AF(&matchmask) = AF_INET;
1888 NSRCADR(&matchaddr) = cr->addr;
1889 NSRCADR(&matchmask) = cr->mask;
1891 hack_restrict(op, &matchaddr, &matchmask, cr->mflags,
1892 cr->flags);
1893 cr++;
1896 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1901 * mon_getlist - return monitor data
1903 static void
1904 mon_getlist_0(
1905 sockaddr_u *srcadr,
1906 struct interface *inter,
1907 struct req_pkt *inpkt
1910 register struct info_monitor *im;
1911 register struct mon_data *md;
1912 extern struct mon_data mon_mru_list;
1913 extern int mon_enabled;
1915 #ifdef DEBUG
1916 if (debug > 2)
1917 printf("wants monitor 0 list\n");
1918 #endif
1919 if (!mon_enabled) {
1920 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1921 return;
1923 im = (struct info_monitor *)prepare_pkt(srcadr, inter, inpkt,
1924 v6sizeof(struct info_monitor));
1925 for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
1926 md = md->mru_next) {
1927 im->lasttime = htonl((u_int32)((current_time -
1928 md->firsttime) / md->count));
1929 im->firsttime = htonl((u_int32)(current_time - md->lasttime));
1930 im->restr = htonl((u_int32)md->flags);
1931 im->count = htonl((u_int32)(md->count));
1932 if (IS_IPV6(&md->rmtadr)) {
1933 if (!client_v6_capable)
1934 continue;
1935 im->addr6 = SOCK_ADDR6(&md->rmtadr);
1936 im->v6_flag = 1;
1937 } else {
1938 im->addr = NSRCADR(&md->rmtadr);
1939 if (client_v6_capable)
1940 im->v6_flag = 0;
1942 im->port = md->rmtport;
1943 im->mode = md->mode;
1944 im->version = md->version;
1945 im = (struct info_monitor *)more_pkt();
1947 flush_pkt();
1951 * mon_getlist - return monitor data
1953 static void
1954 mon_getlist_1(
1955 sockaddr_u *srcadr,
1956 struct interface *inter,
1957 struct req_pkt *inpkt
1960 register struct info_monitor_1 *im;
1961 register struct mon_data *md;
1962 extern struct mon_data mon_mru_list;
1963 extern int mon_enabled;
1965 if (!mon_enabled) {
1966 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1967 return;
1969 im = (struct info_monitor_1 *)prepare_pkt(srcadr, inter, inpkt,
1970 v6sizeof(struct info_monitor_1));
1971 for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
1972 md = md->mru_next) {
1973 im->lasttime = htonl((u_int32)((current_time -
1974 md->firsttime) / md->count));
1975 im->firsttime = htonl((u_int32)(current_time - md->lasttime));
1976 im->restr = htonl((u_int32)md->flags);
1977 im->count = htonl((u_int32)md->count);
1978 if (IS_IPV6(&md->rmtadr)) {
1979 if (!client_v6_capable)
1980 continue;
1981 im->addr6 = SOCK_ADDR6(&md->rmtadr);
1982 im->v6_flag = 1;
1983 im->daddr6 = SOCK_ADDR6(&md->interface->sin);
1984 } else {
1985 im->addr = NSRCADR(&md->rmtadr);
1986 if (client_v6_capable)
1987 im->v6_flag = 0;
1988 if (MDF_BCAST == md->cast_flags)
1989 im->daddr = NSRCADR(&md->interface->bcast);
1990 else if (md->cast_flags) {
1991 im->daddr = NSRCADR(&md->interface->sin);
1992 if (!im->daddr)
1993 im->daddr = NSRCADR(&md->interface->bcast);
1994 } else
1995 im->daddr = 4;
1997 im->flags = htonl(md->cast_flags);
1998 im->port = md->rmtport;
1999 im->mode = md->mode;
2000 im->version = md->version;
2001 im = (struct info_monitor_1 *)more_pkt();
2003 flush_pkt();
2007 * Module entry points and the flags they correspond with
2009 struct reset_entry {
2010 int flag; /* flag this corresponds to */
2011 void (*handler) (void); /* routine to handle request */
2014 struct reset_entry reset_entries[] = {
2015 { RESET_FLAG_ALLPEERS, peer_all_reset },
2016 { RESET_FLAG_IO, io_clr_stats },
2017 { RESET_FLAG_SYS, proto_clr_stats },
2018 { RESET_FLAG_MEM, peer_clr_stats },
2019 { RESET_FLAG_TIMER, timer_clr_stats },
2020 { RESET_FLAG_AUTH, reset_auth_stats },
2021 { RESET_FLAG_CTL, ctl_clr_stats },
2022 { 0, 0 }
2026 * reset_stats - reset statistic counters here and there
2028 static void
2029 reset_stats(
2030 sockaddr_u *srcadr,
2031 struct interface *inter,
2032 struct req_pkt *inpkt
2035 u_long flags;
2036 struct reset_entry *rent;
2038 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2039 msyslog(LOG_ERR, "reset_stats: err_nitems > 1");
2040 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2041 return;
2044 flags = ((struct reset_flags *)inpkt->data)->flags;
2045 flags = ntohl(flags);
2047 if (flags & ~RESET_ALLFLAGS) {
2048 msyslog(LOG_ERR, "reset_stats: reset leaves %#lx",
2049 flags & ~RESET_ALLFLAGS);
2050 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2051 return;
2054 for (rent = reset_entries; rent->flag != 0; rent++) {
2055 if (flags & rent->flag)
2056 (rent->handler)();
2058 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2063 * reset_peer - clear a peer's statistics
2065 static void
2066 reset_peer(
2067 sockaddr_u *srcadr,
2068 struct interface *inter,
2069 struct req_pkt *inpkt
2072 struct conf_unpeer *cp;
2073 int items;
2074 struct peer *peer;
2075 sockaddr_u peeraddr;
2076 int bad;
2079 * We check first to see that every peer exists. If not,
2080 * we return an error.
2083 items = INFO_NITEMS(inpkt->err_nitems);
2084 cp = (struct conf_unpeer *)inpkt->data;
2086 bad = 0;
2087 while (items-- > 0 && !bad) {
2088 ZERO_SOCK(&peeraddr);
2089 if (client_v6_capable && cp->v6_flag) {
2090 AF(&peeraddr) = AF_INET6;
2091 SOCK_ADDR6(&peeraddr) = cp->peeraddr6;
2092 } else {
2093 AF(&peeraddr) = AF_INET;
2094 NSRCADR(&peeraddr) = cp->peeraddr;
2097 #ifdef ISC_PLATFORM_HAVESALEN
2098 peeraddr.sas.ss_len = SOCKLEN(&peeraddr);
2099 #endif
2100 peer = findexistingpeer(&peeraddr, NULL, -1);
2101 if (NULL == peer)
2102 bad++;
2103 cp = (struct conf_unpeer *)((char *)cp +
2104 INFO_ITEMSIZE(inpkt->mbz_itemsize));
2107 if (bad) {
2108 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2109 return;
2113 * Now do it in earnest.
2116 items = INFO_NITEMS(inpkt->err_nitems);
2117 cp = (struct conf_unpeer *)inpkt->data;
2118 while (items-- > 0) {
2119 ZERO_SOCK(&peeraddr);
2120 if (client_v6_capable && cp->v6_flag) {
2121 AF(&peeraddr) = AF_INET6;
2122 SOCK_ADDR6(&peeraddr) = cp->peeraddr6;
2123 } else {
2124 AF(&peeraddr) = AF_INET;
2125 NSRCADR(&peeraddr) = cp->peeraddr;
2127 SET_PORT(&peeraddr, 123);
2128 #ifdef ISC_PLATFORM_HAVESALEN
2129 peeraddr.sas.ss_len = SOCKLEN(&peeraddr);
2130 #endif
2131 peer = findexistingpeer(&peeraddr, NULL, -1);
2132 while (peer != NULL) {
2133 peer_reset(peer);
2134 peer = findexistingpeer(&peeraddr, peer, -1);
2136 cp = (struct conf_unpeer *)((char *)cp +
2137 INFO_ITEMSIZE(inpkt->mbz_itemsize));
2140 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2145 * do_key_reread - reread the encryption key file
2147 static void
2148 do_key_reread(
2149 sockaddr_u *srcadr,
2150 struct interface *inter,
2151 struct req_pkt *inpkt
2154 rereadkeys();
2155 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2160 * trust_key - make one or more keys trusted
2162 static void
2163 trust_key(
2164 sockaddr_u *srcadr,
2165 struct interface *inter,
2166 struct req_pkt *inpkt
2169 do_trustkey(srcadr, inter, inpkt, 1);
2174 * untrust_key - make one or more keys untrusted
2176 static void
2177 untrust_key(
2178 sockaddr_u *srcadr,
2179 struct interface *inter,
2180 struct req_pkt *inpkt
2183 do_trustkey(srcadr, inter, inpkt, 0);
2188 * do_trustkey - make keys either trustable or untrustable
2190 static void
2191 do_trustkey(
2192 sockaddr_u *srcadr,
2193 struct interface *inter,
2194 struct req_pkt *inpkt,
2195 u_long trust
2198 register u_long *kp;
2199 register int items;
2201 items = INFO_NITEMS(inpkt->err_nitems);
2202 kp = (u_long *)inpkt->data;
2203 while (items-- > 0) {
2204 authtrust(*kp, trust);
2205 kp++;
2208 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2213 * get_auth_info - return some stats concerning the authentication module
2215 static void
2216 get_auth_info(
2217 sockaddr_u *srcadr,
2218 struct interface *inter,
2219 struct req_pkt *inpkt
2222 register struct info_auth *ia;
2225 * Importations from the authentication module
2227 extern u_long authnumkeys;
2228 extern int authnumfreekeys;
2229 extern u_long authkeylookups;
2230 extern u_long authkeynotfound;
2231 extern u_long authencryptions;
2232 extern u_long authdecryptions;
2233 extern u_long authkeyuncached;
2234 extern u_long authkeyexpired;
2236 ia = (struct info_auth *)prepare_pkt(srcadr, inter, inpkt,
2237 sizeof(struct info_auth));
2239 ia->numkeys = htonl((u_int32)authnumkeys);
2240 ia->numfreekeys = htonl((u_int32)authnumfreekeys);
2241 ia->keylookups = htonl((u_int32)authkeylookups);
2242 ia->keynotfound = htonl((u_int32)authkeynotfound);
2243 ia->encryptions = htonl((u_int32)authencryptions);
2244 ia->decryptions = htonl((u_int32)authdecryptions);
2245 ia->keyuncached = htonl((u_int32)authkeyuncached);
2246 ia->expired = htonl((u_int32)authkeyexpired);
2247 ia->timereset = htonl((u_int32)(current_time - auth_timereset));
2249 (void) more_pkt();
2250 flush_pkt();
2256 * reset_auth_stats - reset the authentication stat counters. Done here
2257 * to keep ntp-isms out of the authentication module
2259 static void
2260 reset_auth_stats(void)
2263 * Importations from the authentication module
2265 extern u_long authkeylookups;
2266 extern u_long authkeynotfound;
2267 extern u_long authencryptions;
2268 extern u_long authdecryptions;
2269 extern u_long authkeyuncached;
2271 authkeylookups = 0;
2272 authkeynotfound = 0;
2273 authencryptions = 0;
2274 authdecryptions = 0;
2275 authkeyuncached = 0;
2276 auth_timereset = current_time;
2281 * req_get_traps - return information about current trap holders
2283 static void
2284 req_get_traps(
2285 sockaddr_u *srcadr,
2286 struct interface *inter,
2287 struct req_pkt *inpkt
2290 register struct info_trap *it;
2291 register struct ctl_trap *tr;
2292 register int i;
2295 * Imported from the control module
2297 extern struct ctl_trap ctl_trap[];
2298 extern int num_ctl_traps;
2300 if (num_ctl_traps == 0) {
2301 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2302 return;
2305 it = (struct info_trap *)prepare_pkt(srcadr, inter, inpkt,
2306 v6sizeof(struct info_trap));
2308 for (i = 0, tr = ctl_trap; i < CTL_MAXTRAPS; i++, tr++) {
2309 if (tr->tr_flags & TRAP_INUSE) {
2310 if (IS_IPV4(&tr->tr_addr)) {
2311 if (tr->tr_localaddr == any_interface)
2312 it->local_address = 0;
2313 else
2314 it->local_address
2315 = NSRCADR(&tr->tr_localaddr->sin);
2316 it->trap_address = NSRCADR(&tr->tr_addr);
2317 if (client_v6_capable)
2318 it->v6_flag = 0;
2319 } else {
2320 if (!client_v6_capable)
2321 continue;
2322 it->local_address6
2323 = SOCK_ADDR6(&tr->tr_localaddr->sin);
2324 it->trap_address6 = SOCK_ADDR6(&tr->tr_addr);
2325 it->v6_flag = 1;
2327 it->trap_port = NSRCPORT(&tr->tr_addr);
2328 it->sequence = htons(tr->tr_sequence);
2329 it->settime = htonl((u_int32)(current_time - tr->tr_settime));
2330 it->origtime = htonl((u_int32)(current_time - tr->tr_origtime));
2331 it->resets = htonl((u_int32)tr->tr_resets);
2332 it->flags = htonl((u_int32)tr->tr_flags);
2333 it = (struct info_trap *)more_pkt();
2336 flush_pkt();
2341 * req_set_trap - configure a trap
2343 static void
2344 req_set_trap(
2345 sockaddr_u *srcadr,
2346 struct interface *inter,
2347 struct req_pkt *inpkt
2350 do_setclr_trap(srcadr, inter, inpkt, 1);
2356 * req_clr_trap - unconfigure a trap
2358 static void
2359 req_clr_trap(
2360 sockaddr_u *srcadr,
2361 struct interface *inter,
2362 struct req_pkt *inpkt
2365 do_setclr_trap(srcadr, inter, inpkt, 0);
2371 * do_setclr_trap - do the grunge work of (un)configuring a trap
2373 static void
2374 do_setclr_trap(
2375 sockaddr_u *srcadr,
2376 struct interface *inter,
2377 struct req_pkt *inpkt,
2378 int set
2381 register struct conf_trap *ct;
2382 register struct interface *linter;
2383 int res;
2384 sockaddr_u laddr;
2387 * Prepare sockaddr
2389 ZERO_SOCK(&laddr);
2390 AF(&laddr) = AF(srcadr);
2391 SET_PORT(&laddr, NTP_PORT);
2394 * Restrict ourselves to one item only. This eliminates
2395 * the error reporting problem.
2397 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2398 msyslog(LOG_ERR, "do_setclr_trap: err_nitems > 1");
2399 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2400 return;
2402 ct = (struct conf_trap *)inpkt->data;
2405 * Look for the local interface. If none, use the default.
2407 if (ct->local_address == 0) {
2408 linter = any_interface;
2409 } else {
2410 if (IS_IPV4(&laddr))
2411 NSRCADR(&laddr) = ct->local_address;
2412 else
2413 SOCK_ADDR6(&laddr) = ct->local_address6;
2414 linter = findinterface(&laddr);
2415 if (NULL == linter) {
2416 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2417 return;
2421 if (IS_IPV4(&laddr))
2422 NSRCADR(&laddr) = ct->trap_address;
2423 else
2424 SOCK_ADDR6(&laddr) = ct->trap_address6;
2425 if (ct->trap_port)
2426 NSRCPORT(&laddr) = ct->trap_port;
2427 else
2428 SET_PORT(&laddr, TRAPPORT);
2430 if (set) {
2431 res = ctlsettrap(&laddr, linter, 0,
2432 INFO_VERSION(inpkt->rm_vn_mode));
2433 } else {
2434 res = ctlclrtrap(&laddr, linter, 0);
2437 if (!res) {
2438 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2439 } else {
2440 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2442 return;
2448 * set_request_keyid - set the keyid used to authenticate requests
2450 static void
2451 set_request_keyid(
2452 sockaddr_u *srcadr,
2453 struct interface *inter,
2454 struct req_pkt *inpkt
2457 keyid_t keyid;
2460 * Restrict ourselves to one item only.
2462 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2463 msyslog(LOG_ERR, "set_request_keyid: err_nitems > 1");
2464 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2465 return;
2468 keyid = ntohl(*((u_int32 *)(inpkt->data)));
2469 info_auth_keyid = keyid;
2470 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2476 * set_control_keyid - set the keyid used to authenticate requests
2478 static void
2479 set_control_keyid(
2480 sockaddr_u *srcadr,
2481 struct interface *inter,
2482 struct req_pkt *inpkt
2485 keyid_t keyid;
2486 extern keyid_t ctl_auth_keyid;
2489 * Restrict ourselves to one item only.
2491 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2492 msyslog(LOG_ERR, "set_control_keyid: err_nitems > 1");
2493 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2494 return;
2497 keyid = ntohl(*((u_int32 *)(inpkt->data)));
2498 ctl_auth_keyid = keyid;
2499 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2505 * get_ctl_stats - return some stats concerning the control message module
2507 static void
2508 get_ctl_stats(
2509 sockaddr_u *srcadr,
2510 struct interface *inter,
2511 struct req_pkt *inpkt
2514 register struct info_control *ic;
2517 * Importations from the control module
2519 extern u_long ctltimereset;
2520 extern u_long numctlreq;
2521 extern u_long numctlbadpkts;
2522 extern u_long numctlresponses;
2523 extern u_long numctlfrags;
2524 extern u_long numctlerrors;
2525 extern u_long numctltooshort;
2526 extern u_long numctlinputresp;
2527 extern u_long numctlinputfrag;
2528 extern u_long numctlinputerr;
2529 extern u_long numctlbadoffset;
2530 extern u_long numctlbadversion;
2531 extern u_long numctldatatooshort;
2532 extern u_long numctlbadop;
2533 extern u_long numasyncmsgs;
2535 ic = (struct info_control *)prepare_pkt(srcadr, inter, inpkt,
2536 sizeof(struct info_control));
2538 ic->ctltimereset = htonl((u_int32)(current_time - ctltimereset));
2539 ic->numctlreq = htonl((u_int32)numctlreq);
2540 ic->numctlbadpkts = htonl((u_int32)numctlbadpkts);
2541 ic->numctlresponses = htonl((u_int32)numctlresponses);
2542 ic->numctlfrags = htonl((u_int32)numctlfrags);
2543 ic->numctlerrors = htonl((u_int32)numctlerrors);
2544 ic->numctltooshort = htonl((u_int32)numctltooshort);
2545 ic->numctlinputresp = htonl((u_int32)numctlinputresp);
2546 ic->numctlinputfrag = htonl((u_int32)numctlinputfrag);
2547 ic->numctlinputerr = htonl((u_int32)numctlinputerr);
2548 ic->numctlbadoffset = htonl((u_int32)numctlbadoffset);
2549 ic->numctlbadversion = htonl((u_int32)numctlbadversion);
2550 ic->numctldatatooshort = htonl((u_int32)numctldatatooshort);
2551 ic->numctlbadop = htonl((u_int32)numctlbadop);
2552 ic->numasyncmsgs = htonl((u_int32)numasyncmsgs);
2554 (void) more_pkt();
2555 flush_pkt();
2559 #ifdef KERNEL_PLL
2561 * get_kernel_info - get kernel pll/pps information
2563 static void
2564 get_kernel_info(
2565 sockaddr_u *srcadr,
2566 struct interface *inter,
2567 struct req_pkt *inpkt
2570 register struct info_kernel *ik;
2571 struct timex ntx;
2573 if (!pll_control) {
2574 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2575 return;
2578 memset((char *)&ntx, 0, sizeof(ntx));
2579 if (ntp_adjtime(&ntx) < 0)
2580 msyslog(LOG_ERR, "get_kernel_info: ntp_adjtime() failed: %m");
2581 ik = (struct info_kernel *)prepare_pkt(srcadr, inter, inpkt,
2582 sizeof(struct info_kernel));
2585 * pll variables
2587 ik->offset = htonl((u_int32)ntx.offset);
2588 ik->freq = htonl((u_int32)ntx.freq);
2589 ik->maxerror = htonl((u_int32)ntx.maxerror);
2590 ik->esterror = htonl((u_int32)ntx.esterror);
2591 ik->status = htons(ntx.status);
2592 ik->constant = htonl((u_int32)ntx.constant);
2593 ik->precision = htonl((u_int32)ntx.precision);
2594 ik->tolerance = htonl((u_int32)ntx.tolerance);
2597 * pps variables
2599 ik->ppsfreq = htonl((u_int32)ntx.ppsfreq);
2600 ik->jitter = htonl((u_int32)ntx.jitter);
2601 ik->shift = htons(ntx.shift);
2602 ik->stabil = htonl((u_int32)ntx.stabil);
2603 ik->jitcnt = htonl((u_int32)ntx.jitcnt);
2604 ik->calcnt = htonl((u_int32)ntx.calcnt);
2605 ik->errcnt = htonl((u_int32)ntx.errcnt);
2606 ik->stbcnt = htonl((u_int32)ntx.stbcnt);
2608 (void) more_pkt();
2609 flush_pkt();
2611 #endif /* KERNEL_PLL */
2614 #ifdef REFCLOCK
2616 * get_clock_info - get info about a clock
2618 static void
2619 get_clock_info(
2620 sockaddr_u *srcadr,
2621 struct interface *inter,
2622 struct req_pkt *inpkt
2625 register struct info_clock *ic;
2626 register u_int32 *clkaddr;
2627 register int items;
2628 struct refclockstat clock_stat;
2629 sockaddr_u addr;
2630 l_fp ltmp;
2632 ZERO_SOCK(&addr);
2633 AF(&addr) = AF_INET;
2634 #ifdef ISC_PLATFORM_HAVESALEN
2635 addr.sas.ss_len = SOCKLEN(&addr);
2636 #endif
2637 SET_PORT(&addr, NTP_PORT);
2638 items = INFO_NITEMS(inpkt->err_nitems);
2639 clkaddr = (u_int32 *) inpkt->data;
2641 ic = (struct info_clock *)prepare_pkt(srcadr, inter, inpkt,
2642 sizeof(struct info_clock));
2644 while (items-- > 0) {
2645 NSRCADR(&addr) = *clkaddr++;
2646 if (!ISREFCLOCKADR(&addr) ||
2647 findexistingpeer(&addr, NULL, -1) == NULL) {
2648 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2649 return;
2652 clock_stat.kv_list = (struct ctl_var *)0;
2654 refclock_control(&addr, NULL, &clock_stat);
2656 ic->clockadr = NSRCADR(&addr);
2657 ic->type = clock_stat.type;
2658 ic->flags = clock_stat.flags;
2659 ic->lastevent = clock_stat.lastevent;
2660 ic->currentstatus = clock_stat.currentstatus;
2661 ic->polls = htonl((u_int32)clock_stat.polls);
2662 ic->noresponse = htonl((u_int32)clock_stat.noresponse);
2663 ic->badformat = htonl((u_int32)clock_stat.badformat);
2664 ic->baddata = htonl((u_int32)clock_stat.baddata);
2665 ic->timestarted = htonl((u_int32)clock_stat.timereset);
2666 DTOLFP(clock_stat.fudgetime1, &ltmp);
2667 HTONL_FP(&ltmp, &ic->fudgetime1);
2668 DTOLFP(clock_stat.fudgetime2, &ltmp);
2669 HTONL_FP(&ltmp, &ic->fudgetime2);
2670 ic->fudgeval1 = htonl((u_int32)clock_stat.fudgeval1);
2671 ic->fudgeval2 = htonl((u_int32)clock_stat.fudgeval2);
2673 free_varlist(clock_stat.kv_list);
2675 ic = (struct info_clock *)more_pkt();
2677 flush_pkt();
2683 * set_clock_fudge - get a clock's fudge factors
2685 static void
2686 set_clock_fudge(
2687 sockaddr_u *srcadr,
2688 struct interface *inter,
2689 struct req_pkt *inpkt
2692 register struct conf_fudge *cf;
2693 register int items;
2694 struct refclockstat clock_stat;
2695 sockaddr_u addr;
2696 l_fp ltmp;
2698 ZERO_SOCK(&addr);
2699 memset((char *)&clock_stat, 0, sizeof clock_stat);
2700 items = INFO_NITEMS(inpkt->err_nitems);
2701 cf = (struct conf_fudge *) inpkt->data;
2703 while (items-- > 0) {
2704 AF(&addr) = AF_INET;
2705 NSRCADR(&addr) = cf->clockadr;
2706 #ifdef ISC_PLATFORM_HAVESALEN
2707 addr.sas.ss_len = SOCKLEN(&addr);
2708 #endif
2709 SET_PORT(&addr, NTP_PORT);
2710 if (!ISREFCLOCKADR(&addr) ||
2711 findexistingpeer(&addr, NULL, -1) == 0) {
2712 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2713 return;
2716 switch(ntohl(cf->which)) {
2717 case FUDGE_TIME1:
2718 NTOHL_FP(&cf->fudgetime, &ltmp);
2719 LFPTOD(&ltmp, clock_stat.fudgetime1);
2720 clock_stat.haveflags = CLK_HAVETIME1;
2721 break;
2722 case FUDGE_TIME2:
2723 NTOHL_FP(&cf->fudgetime, &ltmp);
2724 LFPTOD(&ltmp, clock_stat.fudgetime2);
2725 clock_stat.haveflags = CLK_HAVETIME2;
2726 break;
2727 case FUDGE_VAL1:
2728 clock_stat.fudgeval1 = ntohl(cf->fudgeval_flags);
2729 clock_stat.haveflags = CLK_HAVEVAL1;
2730 break;
2731 case FUDGE_VAL2:
2732 clock_stat.fudgeval2 = ntohl(cf->fudgeval_flags);
2733 clock_stat.haveflags = CLK_HAVEVAL2;
2734 break;
2735 case FUDGE_FLAGS:
2736 clock_stat.flags = (u_char) (ntohl(cf->fudgeval_flags) & 0xf);
2737 clock_stat.haveflags =
2738 (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4);
2739 break;
2740 default:
2741 msyslog(LOG_ERR, "set_clock_fudge: default!");
2742 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2743 return;
2746 refclock_control(&addr, &clock_stat, (struct refclockstat *)0);
2749 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2751 #endif
2753 #ifdef REFCLOCK
2755 * get_clkbug_info - get debugging info about a clock
2757 static void
2758 get_clkbug_info(
2759 sockaddr_u *srcadr,
2760 struct interface *inter,
2761 struct req_pkt *inpkt
2764 register int i;
2765 register struct info_clkbug *ic;
2766 register u_int32 *clkaddr;
2767 register int items;
2768 struct refclockbug bug;
2769 sockaddr_u addr;
2771 ZERO_SOCK(&addr);
2772 AF(&addr) = AF_INET;
2773 #ifdef ISC_PLATFORM_HAVESALEN
2774 addr.sas.ss_len = SOCKLEN(&addr);
2775 #endif
2776 SET_PORT(&addr, 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 NSRCADR(&addr) = *clkaddr++;
2785 if (!ISREFCLOCKADR(&addr) ||
2786 findexistingpeer(&addr, NULL, -1) == 0) {
2787 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2788 return;
2791 memset((char *)&bug, 0, sizeof bug);
2792 refclock_buginfo(&addr, &bug);
2793 if (bug.nvalues == 0 && bug.ntimes == 0) {
2794 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2795 return;
2798 ic->clockadr = NSRCADR(&addr);
2799 i = bug.nvalues;
2800 if (i > NUMCBUGVALUES)
2801 i = NUMCBUGVALUES;
2802 ic->nvalues = (u_char)i;
2803 ic->svalues = htons((u_short) (bug.svalues & ((1<<i)-1)));
2804 while (--i >= 0)
2805 ic->values[i] = htonl(bug.values[i]);
2807 i = bug.ntimes;
2808 if (i > NUMCBUGTIMES)
2809 i = NUMCBUGTIMES;
2810 ic->ntimes = (u_char)i;
2811 ic->stimes = htonl(bug.stimes);
2812 while (--i >= 0) {
2813 HTONL_FP(&bug.times[i], &ic->times[i]);
2816 ic = (struct info_clkbug *)more_pkt();
2818 flush_pkt();
2820 #endif
2823 * receiver of interface structures
2825 static void
2826 fill_info_if_stats(void *data, interface_info_t *interface_info)
2828 struct info_if_stats **ifsp = (struct info_if_stats **)data;
2829 struct info_if_stats *ifs = *ifsp;
2830 struct interface *interface = interface_info->interface;
2832 memset(ifs, 0, sizeof(*ifs));
2834 if (IS_IPV6(&interface->sin)) {
2835 if (!client_v6_capable) {
2836 return;
2838 ifs->v6_flag = 1;
2839 ifs->unaddr.addr6 = SOCK_ADDR6(&interface->sin);
2840 ifs->unbcast.addr6 = SOCK_ADDR6(&interface->bcast);
2841 ifs->unmask.addr6 = SOCK_ADDR6(&interface->mask);
2842 } else {
2843 ifs->v6_flag = 0;
2844 ifs->unaddr.addr = SOCK_ADDR4(&interface->sin);
2845 ifs->unbcast.addr = SOCK_ADDR4(&interface->bcast);
2846 ifs->unmask.addr = SOCK_ADDR4(&interface->mask);
2848 ifs->v6_flag = htonl(ifs->v6_flag);
2849 strncpy(ifs->name, interface->name, sizeof(ifs->name));
2850 ifs->family = htons(interface->family);
2851 ifs->flags = htonl(interface->flags);
2852 ifs->last_ttl = htonl(interface->last_ttl);
2853 ifs->num_mcast = htonl(interface->num_mcast);
2854 ifs->received = htonl(interface->received);
2855 ifs->sent = htonl(interface->sent);
2856 ifs->notsent = htonl(interface->notsent);
2857 ifs->scopeid = htonl(interface->scopeid);
2858 /* ifindex was always zero, now no longer in struct interface */
2859 ifs->ifindex = 0;
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 sockaddr_u *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 sockaddr_u *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();