2 * ntp_request.c - respond to information requests
15 #include "ntp_request.h"
16 #include "ntp_control.h"
17 #include "ntp_refclock.h"
19 #include "ntp_stdlib.h"
23 #include "ntp_syscall.h"
24 #endif /* KERNEL_PLL */
27 * Structure to hold request procedure information
32 #define NO_REQUEST (-1)
35 short request_code; /* defined request code */
36 short needs_auth; /* true when authentication needed */
37 short sizeofitem; /* size of request data item */
38 void (*handler) P((struct sockaddr_in *, struct interface *,
39 struct req_pkt *)); /* routine to handle request */
43 * Universal request codes
45 static struct req_proc univ_codes[] = {
46 { NO_REQUEST, NOAUTH, 0, 0 }
49 static void req_ack P((struct sockaddr_in *, struct interface *, struct req_pkt *, int));
50 static char * prepare_pkt P((struct sockaddr_in *, struct interface *, struct req_pkt *, u_int));
51 static char * more_pkt P((void));
52 static void flush_pkt P((void));
53 static void peer_list P((struct sockaddr_in *, struct interface *, struct req_pkt *));
54 static void peer_list_sum P((struct sockaddr_in *, struct interface *, struct req_pkt *));
55 static void peer_info P((struct sockaddr_in *, struct interface *, struct req_pkt *));
56 static void peer_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *));
57 static void sys_info P((struct sockaddr_in *, struct interface *, struct req_pkt *));
58 static void sys_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *));
59 static void mem_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *));
60 static void io_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *));
61 static void timer_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *));
62 static void loop_info P((struct sockaddr_in *, struct interface *, struct req_pkt *));
63 static void do_conf P((struct sockaddr_in *, struct interface *, struct req_pkt *));
64 static void do_unconf P((struct sockaddr_in *, struct interface *, struct req_pkt *));
65 static void set_sys_flag P((struct sockaddr_in *, struct interface *, struct req_pkt *));
66 static void clr_sys_flag P((struct sockaddr_in *, struct interface *, struct req_pkt *));
67 static void setclr_flags P((struct sockaddr_in *, struct interface *, struct req_pkt *, u_long));
68 static void list_restrict P((struct sockaddr_in *, struct interface *, struct req_pkt *));
69 static void do_resaddflags P((struct sockaddr_in *, struct interface *, struct req_pkt *));
70 static void do_ressubflags P((struct sockaddr_in *, struct interface *, struct req_pkt *));
71 static void do_unrestrict P((struct sockaddr_in *, struct interface *, struct req_pkt *));
72 static void do_restrict P((struct sockaddr_in *, struct interface *, struct req_pkt *, int));
73 static void mon_getlist_0 P((struct sockaddr_in *, struct interface *, struct req_pkt *));
74 static void mon_getlist_1 P((struct sockaddr_in *, struct interface *, struct req_pkt *));
75 static void reset_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *));
76 static void reset_peer P((struct sockaddr_in *, struct interface *, struct req_pkt *));
77 static void do_key_reread P((struct sockaddr_in *, struct interface *, struct req_pkt *));
78 static void trust_key P((struct sockaddr_in *, struct interface *, struct req_pkt *));
79 static void untrust_key P((struct sockaddr_in *, struct interface *, struct req_pkt *));
80 static void do_trustkey P((struct sockaddr_in *, struct interface *, struct req_pkt *, int));
81 static void get_auth_info P((struct sockaddr_in *, struct interface *, struct req_pkt *));
82 static void reset_auth_stats P((void));
83 static void req_get_traps P((struct sockaddr_in *, struct interface *, struct req_pkt *));
84 static void req_set_trap P((struct sockaddr_in *, struct interface *, struct req_pkt *));
85 static void req_clr_trap P((struct sockaddr_in *, struct interface *, struct req_pkt *));
86 static void do_setclr_trap P((struct sockaddr_in *, struct interface *, struct req_pkt *, int));
87 static void set_request_keyid P((struct sockaddr_in *, struct interface *, struct req_pkt *));
88 static void set_control_keyid P((struct sockaddr_in *, struct interface *, struct req_pkt *));
89 static void get_ctl_stats P((struct sockaddr_in *, struct interface *, struct req_pkt *));
91 static void get_kernel_info P((struct sockaddr_in *, struct interface *, struct req_pkt *));
92 #endif /* KERNEL_PLL */
94 static void get_clock_info P((struct sockaddr_in *, struct interface *, struct req_pkt *));
95 static void set_clock_fudge P((struct sockaddr_in *, struct interface *, struct req_pkt *));
98 static void get_clkbug_info P((struct sockaddr_in *, struct interface *, struct req_pkt *));
104 static struct req_proc ntp_codes[] = {
105 { REQ_PEER_LIST, NOAUTH, 0, peer_list },
106 { REQ_PEER_LIST_SUM, NOAUTH, 0, peer_list_sum },
107 { REQ_PEER_INFO, NOAUTH, sizeof(struct info_peer_list), peer_info },
108 { REQ_PEER_STATS, NOAUTH, sizeof(struct info_peer_list), peer_stats },
109 { REQ_SYS_INFO, NOAUTH, 0, sys_info },
110 { REQ_SYS_STATS, NOAUTH, 0, sys_stats },
111 { REQ_IO_STATS, NOAUTH, 0, io_stats },
112 { REQ_MEM_STATS, NOAUTH, 0, mem_stats },
113 { REQ_LOOP_INFO, NOAUTH, 0, loop_info },
114 { REQ_TIMER_STATS, NOAUTH, 0, timer_stats },
115 { REQ_CONFIG, AUTH, sizeof(struct conf_peer), do_conf },
116 { REQ_UNCONFIG, AUTH, sizeof(struct conf_unpeer), do_unconf },
117 { REQ_SET_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags), set_sys_flag },
118 { REQ_CLR_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags), clr_sys_flag },
119 { REQ_GET_RESTRICT, NOAUTH, 0, list_restrict },
120 { REQ_RESADDFLAGS, AUTH, sizeof(struct conf_restrict), do_resaddflags },
121 { REQ_RESSUBFLAGS, AUTH, sizeof(struct conf_restrict), do_ressubflags },
122 { REQ_UNRESTRICT, AUTH, sizeof(struct conf_restrict), do_unrestrict },
123 { REQ_MON_GETLIST, NOAUTH, 0, mon_getlist_0 },
124 { REQ_MON_GETLIST_1, NOAUTH, 0, mon_getlist_1 },
125 { REQ_RESET_STATS, AUTH, sizeof(struct reset_flags), reset_stats },
126 { REQ_RESET_PEER, AUTH, sizeof(struct conf_unpeer), reset_peer },
127 { REQ_REREAD_KEYS, AUTH, 0, do_key_reread },
128 { REQ_TRUSTKEY, AUTH, sizeof(u_long), trust_key },
129 { REQ_UNTRUSTKEY, AUTH, sizeof(u_long), untrust_key },
130 { REQ_AUTHINFO, NOAUTH, 0, get_auth_info },
131 { REQ_TRAPS, NOAUTH, 0, req_get_traps },
132 { REQ_ADD_TRAP, AUTH, sizeof(struct conf_trap), req_set_trap },
133 { REQ_CLR_TRAP, AUTH, sizeof(struct conf_trap), req_clr_trap },
134 { REQ_REQUEST_KEY, AUTH, sizeof(u_long), set_request_keyid },
135 { REQ_CONTROL_KEY, AUTH, sizeof(u_long), set_control_keyid },
136 { REQ_GET_CTLSTATS, NOAUTH, 0, get_ctl_stats },
138 { REQ_GET_KERNEL, NOAUTH, 0, get_kernel_info },
141 { REQ_GET_CLOCKINFO, NOAUTH, sizeof(u_int32), get_clock_info },
142 { REQ_SET_CLKFUDGE, AUTH, sizeof(struct conf_fudge), set_clock_fudge },
143 { REQ_GET_CLKBUGINFO, NOAUTH, sizeof(u_int32), get_clkbug_info },
145 { NO_REQUEST, NOAUTH, 0, 0 }
150 * Authentication keyid used to authenticate requests. Zero means we
151 * don't allow writing anything.
153 u_long info_auth_keyid;
156 * Statistic counters to keep track of requests and responses.
158 u_long numrequests; /* number of requests we've received */
159 u_long numresppkts; /* number of resp packets sent with data */
161 u_long errorcounter[INFO_ERR_AUTH+1]; /* lazy way to count errors, indexed */
162 /* by the error code */
165 * A hack. To keep the authentication module clear of ntp-ism's, we
166 * include a time reset variable for its stats here.
168 static u_long auth_timereset;
171 * Response packet used by these routines. Also some state information
172 * so that we can handle packet formatting within a common set of
173 * subroutines. Note we try to enter data in place whenever possible,
174 * but the need to set the more bit correctly means we occasionally
175 * use the extra buffer and copy.
177 static struct resp_pkt rpkt;
182 static int databytes;
183 static char exbuf[RESP_DATA_SIZE];
184 static int usingexbuf;
185 static struct sockaddr_in *toaddr;
186 static struct interface *frominter;
189 * init_request - initialize request data
199 info_auth_keyid = 0; /* by default, can't do this */
201 for (i = 0; i < sizeof(errorcounter)/sizeof(errorcounter[0]); i++)
207 * req_ack - acknowledge request with no data
211 struct sockaddr_in *srcadr,
212 struct interface *inter,
213 struct req_pkt *inpkt,
220 rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver);
221 rpkt.auth_seq = AUTH_SEQ(0, 0);
222 rpkt.implementation = inpkt->implementation;
223 rpkt.request = inpkt->request;
224 rpkt.err_nitems = ERR_NITEMS(errcode, 0);
225 rpkt.mbz_itemsize = MBZ_ITEMSIZE(0);
228 * send packet and bump counters
230 sendpkt(srcadr, inter, -1, (struct pkt *)&rpkt, RESP_HEADER_SIZE);
231 errorcounter[errcode]++;
236 * prepare_pkt - prepare response packet for transmission, return pointer
237 * to storage for data item.
241 struct sockaddr_in *srcadr,
242 struct interface *inter,
249 printf("request: preparing pkt\n");
253 * Fill in the implementation, reqest and itemsize fields
254 * since these won't change.
256 rpkt.implementation = pkt->implementation;
257 rpkt.request = pkt->request;
258 rpkt.mbz_itemsize = MBZ_ITEMSIZE(structsize);
261 * Compute the static data needed to carry on.
267 itemsize = structsize;
272 * return the beginning of the packet buffer.
274 return &rpkt.data[0];
279 * more_pkt - return a data pointer for a new item.
285 * If we were using the extra buffer, send the packet.
290 printf("request: sending pkt\n");
292 rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, MORE_BIT, reqver);
293 rpkt.auth_seq = AUTH_SEQ(0, seqno);
294 rpkt.err_nitems = htons((u_short)nitems);
295 sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt,
296 RESP_HEADER_SIZE+databytes);
300 * Copy data out of exbuf into the packet.
302 memmove(&rpkt.data[0], exbuf, (unsigned)itemsize);
309 databytes += itemsize;
311 if (databytes + itemsize <= RESP_DATA_SIZE) {
314 printf("request: giving him more data\n");
317 * More room in packet. Give him the
320 return &rpkt.data[databytes];
323 * No room in packet. Give him the extra
324 * buffer unless this was the last in the sequence.
328 printf("request: into extra buffer\n");
341 * flush_pkt - we're done, return remaining information.
348 printf("request: flushing packet, %d items\n", nitems);
351 * Must send the last packet. If nothing in here and nothing
352 * has been sent, send an error saying no data to be found.
354 if (seqno == 0 && nitems == 0)
355 req_ack(toaddr, frominter, (struct req_pkt *)&rpkt,
358 rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver);
359 rpkt.auth_seq = AUTH_SEQ(0, seqno);
360 rpkt.err_nitems = htons((u_short)nitems);
361 sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt,
362 RESP_HEADER_SIZE+databytes);
370 * process_private - process private mode (7) packets
374 struct recvbuf *rbufp,
378 struct req_pkt *inpkt;
379 struct sockaddr_in *srcadr;
380 struct interface *inter;
381 struct req_proc *proc;
384 * Initialize pointers, for convenience
386 inpkt = (struct req_pkt *)&rbufp->recv_pkt;
387 srcadr = &rbufp->recv_srcadr;
388 inter = rbufp->dstadr;
392 printf("prepare_pkt: impl %d req %d\n",
393 inpkt->implementation, inpkt->request);
397 * Do some sanity checks on the packet. Return a format
400 if (ISRESPONSE(inpkt->rm_vn_mode)
401 || ISMORE(inpkt->rm_vn_mode)
402 || INFO_VERSION(inpkt->rm_vn_mode) > NTP_VERSION
403 || INFO_VERSION(inpkt->rm_vn_mode) < NTP_OLDVERSION
404 || INFO_SEQ(inpkt->auth_seq) != 0
405 || INFO_ERR(inpkt->err_nitems) != 0
406 || INFO_MBZ(inpkt->mbz_itemsize) != 0
407 || rbufp->recv_length > REQ_LEN_MAC
408 || rbufp->recv_length < REQ_LEN_NOMAC) {
409 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
413 reqver = INFO_VERSION(inpkt->rm_vn_mode);
416 * Get the appropriate procedure list to search.
418 if (inpkt->implementation == IMPL_UNIV)
420 else if (inpkt->implementation == IMPL_XNTPD)
423 req_ack(srcadr, inter, inpkt, INFO_ERR_IMPL);
429 * Search the list for the request codes. If it isn't one
430 * we know, return an error.
432 while (proc->request_code != NO_REQUEST) {
433 if (proc->request_code == (short) inpkt->request)
437 if (proc->request_code == NO_REQUEST) {
438 req_ack(srcadr, inter, inpkt, INFO_ERR_REQ);
444 printf("found request in tables\n");
448 * If we need to authenticate, do so. Note that an
449 * authenticatable packet must include a mac field, must
450 * have used key info_auth_keyid and must have included
451 * a time stamp in the appropriate field. The time stamp
452 * must be within INFO_TS_MAXSKEW of the receive
455 if (proc->needs_auth && sys_authenticate) {
460 * If this guy is restricted from doing this, don't let him
461 * If wrong key was used, or packet doesn't have mac, return.
463 if (!INFO_IS_AUTH(inpkt->auth_seq) || info_auth_keyid == 0
464 || ntohl(inpkt->keyid) != info_auth_keyid) {
467 printf("failed auth %d info_auth_keyid %lu pkt keyid %lu\n",
468 INFO_IS_AUTH(inpkt->auth_seq),
469 (u_long)info_auth_keyid,
470 (u_long)ntohl(inpkt->keyid));
472 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
475 if (rbufp->recv_length > REQ_LEN_MAC) {
478 printf("bad pkt length %d\n",
481 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
484 if (!mod_okay || !authhavekey(info_auth_keyid)) {
487 printf("failed auth mod_okay %d\n", mod_okay);
489 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
494 * calculate absolute time difference between xmit time stamp
495 * and receive time stamp. If too large, too bad.
497 NTOHL_FP(&inpkt->tstamp, &ftmp);
498 L_SUB(&ftmp, &rbufp->recv_time);
499 LFPTOD(&ftmp, dtemp);
500 if (fabs(dtemp) >= INFO_TS_MAXSKEW) {
502 * He's a loser. Tell him.
504 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
509 * So far so good. See if decryption works out okay.
511 if (!authdecrypt(info_auth_keyid, (u_int32 *)inpkt,
512 REQ_LEN_NOMAC, (int)(rbufp->recv_length - REQ_LEN_NOMAC))) {
513 req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
519 * If we need data, check to see if we have some. If we
520 * don't, check to see that there is none (picky, picky).
522 if (INFO_ITEMSIZE(inpkt->mbz_itemsize) != proc->sizeofitem) {
523 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
526 if (proc->sizeofitem != 0)
527 if (proc->sizeofitem*INFO_NITEMS(inpkt->err_nitems)
528 > sizeof(inpkt->data)) {
529 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
535 printf("process_private: all okay, into handler\n");
539 * Packet is okay. Call the handler to send him data.
541 (proc->handler)(srcadr, inter, inpkt);
546 * peer_list - send a list of the peers
550 struct sockaddr_in *srcadr,
551 struct interface *inter,
552 struct req_pkt *inpkt
555 register struct info_peer_list *ip;
556 register struct peer *pp;
559 ip = (struct info_peer_list *)prepare_pkt(srcadr, inter, inpkt,
560 sizeof(struct info_peer_list));
561 for (i = 0; i < HASH_SIZE && ip != 0; i++) {
563 while (pp != 0 && ip != 0) {
564 ip->address = pp->srcadr.sin_addr.s_addr;
565 ip->port = pp->srcadr.sin_port;
566 ip->hmode = pp->hmode;
568 if (pp->flags & FLAG_CONFIG)
569 ip->flags |= INFO_FLAG_CONFIG;
571 ip->flags |= INFO_FLAG_SYSPEER;
572 if (pp->status == CTL_PST_SEL_SYNCCAND)
573 ip->flags |= INFO_FLAG_SEL_CANDIDATE;
574 if (pp->status >= CTL_PST_SEL_SYSPEER)
575 ip->flags |= INFO_FLAG_SHORTLIST;
576 ip = (struct info_peer_list *)more_pkt();
585 * peer_list_sum - return extended peer list
589 struct sockaddr_in *srcadr,
590 struct interface *inter,
591 struct req_pkt *inpkt
594 register struct info_peer_summary *ips;
595 register struct peer *pp;
601 printf("wants peer list summary\n");
604 ips = (struct info_peer_summary *)prepare_pkt(srcadr, inter, inpkt,
605 sizeof(struct info_peer_summary));
606 for (i = 0; i < HASH_SIZE && ips != 0; i++) {
608 while (pp != 0 && ips != 0) {
611 printf("sum: got one\n");
613 ips->dstadr = (pp->processed) ?
614 pp->cast_flags == MDF_BCAST ?
615 pp->dstadr->bcast.sin_addr.s_addr:
617 pp->dstadr->sin.sin_addr.s_addr ?
618 pp->dstadr->sin.sin_addr.s_addr:
619 pp->dstadr->bcast.sin_addr.s_addr:
621 ips->srcadr = pp->srcadr.sin_addr.s_addr;
622 ips->srcport = pp->srcadr.sin_port;
623 ips->stratum = pp->stratum;
624 ips->hpoll = pp->hpoll;
625 ips->ppoll = pp->ppoll;
626 ips->reach = pp->reach;
629 ips->flags |= INFO_FLAG_SYSPEER;
630 if (pp->flags & FLAG_CONFIG)
631 ips->flags |= INFO_FLAG_CONFIG;
632 if (pp->flags & FLAG_REFCLOCK)
633 ips->flags |= INFO_FLAG_REFCLOCK;
634 if (pp->flags & FLAG_AUTHENABLE)
635 ips->flags |= INFO_FLAG_AUTHENABLE;
636 if (pp->flags & FLAG_PREFER)
637 ips->flags |= INFO_FLAG_PREFER;
638 if (pp->flags & FLAG_BURST)
639 ips->flags |= INFO_FLAG_BURST;
640 if (pp->status == CTL_PST_SEL_SYNCCAND)
641 ips->flags |= INFO_FLAG_SEL_CANDIDATE;
642 if (pp->status >= CTL_PST_SEL_SYSPEER)
643 ips->flags |= INFO_FLAG_SHORTLIST;
644 ips->hmode = pp->hmode;
645 ips->delay = HTONS_FP(DTOFP(pp->delay));
646 DTOLFP(pp->offset, <mp);
647 HTONL_FP(<mp, &ips->offset);
648 ips->dispersion = HTONS_FP(DTOUFP(pp->disp));
651 ips = (struct info_peer_summary *)more_pkt();
659 * peer_info - send information for one or more peers
663 struct sockaddr_in *srcadr,
664 struct interface *inter,
665 struct req_pkt *inpkt
668 register struct info_peer_list *ipl;
669 register struct peer *pp;
670 register struct info_peer *ip;
673 struct sockaddr_in addr;
674 extern struct peer *sys_peer;
677 memset((char *)&addr, 0, sizeof addr);
678 addr.sin_family = AF_INET;
679 items = INFO_NITEMS(inpkt->err_nitems);
680 ipl = (struct info_peer_list *) inpkt->data;
681 ip = (struct info_peer *)prepare_pkt(srcadr, inter, inpkt,
682 sizeof(struct info_peer));
683 while (items-- > 0 && ip != 0) {
684 addr.sin_port = ipl->port;
685 addr.sin_addr.s_addr = ipl->address;
687 if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0)
689 ip->dstadr = (pp->processed) ?
690 pp->cast_flags == MDF_BCAST ?
691 pp->dstadr->bcast.sin_addr.s_addr:
693 pp->dstadr->sin.sin_addr.s_addr ?
694 pp->dstadr->sin.sin_addr.s_addr:
695 pp->dstadr->bcast.sin_addr.s_addr:
697 ip->srcadr = NSRCADR(&pp->srcadr);
698 ip->srcport = NSRCPORT(&pp->srcadr);
701 ip->flags |= INFO_FLAG_SYSPEER;
702 if (pp->flags & FLAG_CONFIG)
703 ip->flags |= INFO_FLAG_CONFIG;
704 if (pp->flags & FLAG_REFCLOCK)
705 ip->flags |= INFO_FLAG_REFCLOCK;
706 if (pp->flags & FLAG_AUTHENABLE)
707 ip->flags |= INFO_FLAG_AUTHENABLE;
708 if (pp->flags & FLAG_PREFER)
709 ip->flags |= INFO_FLAG_PREFER;
710 if (pp->flags & FLAG_BURST)
711 ip->flags |= INFO_FLAG_BURST;
712 if (pp->status == CTL_PST_SEL_SYNCCAND)
713 ip->flags |= INFO_FLAG_SEL_CANDIDATE;
714 if (pp->status >= CTL_PST_SEL_SYSPEER)
715 ip->flags |= INFO_FLAG_SHORTLIST;
717 ip->hmode = pp->hmode;
718 ip->keyid = pp->keyid;
719 ip->stratum = pp->stratum;
720 ip->ppoll = pp->ppoll;
721 ip->hpoll = pp->hpoll;
722 ip->precision = pp->precision;
723 ip->version = pp->version;
724 ip->valid = pp->valid;
725 ip->reach = pp->reach;
726 ip->unreach = pp->unreach;
727 ip->flash = (u_char)pp->flash;
728 ip->flash2 = pp->flash;
729 ip->estbdelay = HTONS_FP(DTOFP(pp->estbdelay));
731 ip->associd = htons(pp->associd);
732 ip->rootdelay = HTONS_FP(DTOUFP(pp->rootdelay));
733 ip->rootdispersion = HTONS_FP(DTOUFP(pp->rootdispersion));
734 ip->refid = pp->refid;
735 HTONL_FP(&pp->reftime, &ip->reftime);
736 HTONL_FP(&pp->org, &ip->org);
737 HTONL_FP(&pp->rec, &ip->rec);
738 HTONL_FP(&pp->xmt, &ip->xmt);
739 j = pp->filter_nextpt - 1;
740 for (i = 0; i < NTP_SHIFT; i++, j--) {
743 ip->filtdelay[i] = HTONS_FP(DTOFP(pp->filter_delay[j]));
744 DTOLFP(pp->filter_offset[j], <mp);
745 HTONL_FP(<mp, &ip->filtoffset[i]);
746 ip->order[i] = (pp->filter_nextpt+NTP_SHIFT-1)
747 - pp->filter_order[i];
748 if (ip->order[i] >= NTP_SHIFT)
749 ip->order[i] -= NTP_SHIFT;
751 DTOLFP(pp->offset, <mp);
752 HTONL_FP(<mp, &ip->offset);
753 ip->delay = HTONS_FP(DTOFP(pp->delay));
754 ip->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp)));
755 ip->selectdisp = HTONS_FP(DTOUFP(SQRT(pp->variance)));
756 ip = (struct info_peer *)more_pkt();
763 * peer_stats - send statistics for one or more peers
767 struct sockaddr_in *srcadr,
768 struct interface *inter,
769 struct req_pkt *inpkt
772 register struct info_peer_list *ipl;
773 register struct peer *pp;
774 register struct info_peer_stats *ip;
776 struct sockaddr_in addr;
777 extern struct peer *sys_peer;
779 memset((char *)&addr, 0, sizeof addr);
780 addr.sin_family = AF_INET;
781 items = INFO_NITEMS(inpkt->err_nitems);
782 ipl = (struct info_peer_list *) inpkt->data;
783 ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt,
784 sizeof(struct info_peer_stats));
785 while (items-- > 0 && ip != 0) {
786 addr.sin_port = ipl->port;
787 addr.sin_addr.s_addr = ipl->address;
789 if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0)
791 ip->dstadr = (pp->processed) ?
792 pp->cast_flags == MDF_BCAST ?
793 pp->dstadr->bcast.sin_addr.s_addr:
795 pp->dstadr->sin.sin_addr.s_addr ?
796 pp->dstadr->sin.sin_addr.s_addr:
797 pp->dstadr->bcast.sin_addr.s_addr:
799 ip->srcadr = NSRCADR(&pp->srcadr);
800 ip->srcport = NSRCPORT(&pp->srcadr);
803 ip->flags |= INFO_FLAG_SYSPEER;
804 if (pp->flags & FLAG_CONFIG)
805 ip->flags |= INFO_FLAG_CONFIG;
806 if (pp->flags & FLAG_REFCLOCK)
807 ip->flags |= INFO_FLAG_REFCLOCK;
808 if (pp->flags & FLAG_AUTHENABLE)
809 ip->flags |= INFO_FLAG_AUTHENABLE;
810 if (pp->flags & FLAG_PREFER)
811 ip->flags |= INFO_FLAG_PREFER;
812 if (pp->flags & FLAG_BURST)
813 ip->flags |= INFO_FLAG_BURST;
814 if (pp->status == CTL_PST_SEL_SYNCCAND)
815 ip->flags |= INFO_FLAG_SEL_CANDIDATE;
816 if (pp->status >= CTL_PST_SEL_SYSPEER)
817 ip->flags |= INFO_FLAG_SHORTLIST;
818 ip->timereceived = htonl((u_int32)(current_time - pp->timereceived));
819 ip->timetosend = htonl(pp->nextdate - current_time);
820 ip->timereachable = htonl((u_int32)(current_time - pp->timereachable));
821 ip->sent = htonl((u_int32)(pp->sent));
822 ip->processed = htonl((u_int32)(pp->processed));
823 ip->badauth = htonl((u_int32)(pp->badauth));
824 ip->bogusorg = htonl((u_int32)(pp->bogusorg));
825 ip->oldpkt = htonl((u_int32)(pp->oldpkt));
826 ip->seldisp = htonl((u_int32)(pp->seldisptoolarge));
827 ip->selbroken = htonl((u_int32)(pp->selbroken));
828 ip->candidate = pp->status;
829 ip = (struct info_peer_stats *)more_pkt();
836 * sys_info - return system info
840 struct sockaddr_in *srcadr,
841 struct interface *inter,
842 struct req_pkt *inpkt
845 register struct info_sys *is;
848 * Importations from the protocol module
850 extern u_char sys_leap;
851 extern u_char sys_stratum;
852 extern s_char sys_precision;
853 extern double sys_rootdelay;
854 extern double sys_rootdispersion;
855 extern u_int32 sys_refid;
856 extern l_fp sys_reftime;
857 extern u_char sys_poll;
858 extern struct peer *sys_peer;
859 extern int sys_bclient;
860 extern double sys_bdelay;
861 extern l_fp sys_authdelay;
862 extern double clock_stability;
863 extern double sys_error;
865 is = (struct info_sys *)prepare_pkt(srcadr, inter, inpkt,
866 sizeof(struct info_sys));
869 is->peer = NSRCADR(&sys_peer->srcadr);
870 is->peer_mode = sys_peer->hmode;
876 is->stratum = sys_stratum;
877 is->precision = sys_precision;
878 is->rootdelay = htonl(DTOFP(sys_rootdelay));
879 is->rootdispersion = htonl(DTOUFP(sys_rootdispersion));
880 is->frequency = htonl(DTOFP(sys_error));
881 is->stability = htonl(DTOUFP(clock_stability * 1e6));
882 is->refid = sys_refid;
883 HTONL_FP(&sys_reftime, &is->reftime);
889 is->flags |= INFO_FLAG_BCLIENT;
890 if (sys_authenticate)
891 is->flags |= INFO_FLAG_AUTHENTICATE;
893 is->flags |= INFO_FLAG_KERNEL;
895 is->flags |= INFO_FLAG_NTP;
897 is->flags |= INFO_FLAG_PLL_SYNC;
899 is->flags |= INFO_FLAG_PPS_SYNC;
900 if (mon_enabled != MON_OFF)
901 is->flags |= INFO_FLAG_MONITOR;
903 is->flags |= INFO_FLAG_FILEGEN;
904 is->bdelay = HTONS_FP(DTOFP(sys_bdelay));
905 HTONL_UF(sys_authdelay.l_f, &is->authdelay);
913 * sys_stats - return system statistics
917 struct sockaddr_in *srcadr,
918 struct interface *inter,
919 struct req_pkt *inpkt
922 register struct info_sys_stats *ss;
925 * Importations from the protocol module
927 extern u_long sys_stattime;
928 extern u_long sys_badstratum;
929 extern u_long sys_oldversionpkt;
930 extern u_long sys_newversionpkt;
931 extern u_long sys_unknownversion;
932 extern u_long sys_badlength;
933 extern u_long sys_processed;
934 extern u_long sys_badauth;
935 extern u_long sys_limitrejected;
937 ss = (struct info_sys_stats *)prepare_pkt(srcadr, inter, inpkt,
938 sizeof(struct info_sys_stats));
940 ss->timeup = htonl((u_int32)current_time);
941 ss->timereset = htonl((u_int32)(current_time - sys_stattime));
942 ss->badstratum = htonl((u_int32)sys_badstratum);
943 ss->oldversionpkt = htonl((u_int32)sys_oldversionpkt);
944 ss->newversionpkt = htonl((u_int32)sys_newversionpkt);
945 ss->unknownversion = htonl((u_int32)sys_unknownversion);
946 ss->badlength = htonl((u_int32)sys_badlength);
947 ss->processed = htonl((u_int32)sys_processed);
948 ss->badauth = htonl((u_int32)sys_badauth);
949 ss->limitrejected = htonl((u_int32)sys_limitrejected);
956 * mem_stats - return memory statistics
960 struct sockaddr_in *srcadr,
961 struct interface *inter,
962 struct req_pkt *inpkt
965 register struct info_mem_stats *ms;
969 * Importations from the peer module
971 extern int peer_hash_count[HASH_SIZE];
972 extern int peer_free_count;
973 extern u_long peer_timereset;
974 extern u_long findpeer_calls;
975 extern u_long peer_allocations;
976 extern u_long peer_demobilizations;
977 extern int total_peer_structs;
979 ms = (struct info_mem_stats *)prepare_pkt(srcadr, inter, inpkt,
980 sizeof(struct info_mem_stats));
982 ms->timereset = htonl((u_int32)(current_time - peer_timereset));
983 ms->totalpeermem = htons((u_short)total_peer_structs);
984 ms->freepeermem = htons((u_short)peer_free_count);
985 ms->findpeer_calls = htonl((u_int32)findpeer_calls);
986 ms->allocations = htonl((u_int32)peer_allocations);
987 ms->demobilizations = htonl((u_int32)peer_demobilizations);
989 for (i = 0; i < HASH_SIZE; i++) {
990 if (peer_hash_count[i] > 255)
991 ms->hashcount[i] = 255;
993 ms->hashcount[i] = (u_char)peer_hash_count[i];
1002 * io_stats - return io statistics
1006 struct sockaddr_in *srcadr,
1007 struct interface *inter,
1008 struct req_pkt *inpkt
1011 register struct info_io_stats *io;
1014 * Importations from the io module
1016 extern u_long io_timereset;
1018 io = (struct info_io_stats *)prepare_pkt(srcadr, inter, inpkt,
1019 sizeof(struct info_io_stats));
1021 io->timereset = htonl((u_int32)(current_time - io_timereset));
1022 io->totalrecvbufs = htons((u_short) total_recvbuffs());
1023 io->freerecvbufs = htons((u_short) free_recvbuffs());
1024 io->fullrecvbufs = htons((u_short) full_recvbuffs());
1025 io->lowwater = htons((u_short) lowater_additions());
1026 io->dropped = htonl((u_int32)packets_dropped);
1027 io->ignored = htonl((u_int32)packets_ignored);
1028 io->received = htonl((u_int32)packets_received);
1029 io->sent = htonl((u_int32)packets_sent);
1030 io->notsent = htonl((u_int32)packets_notsent);
1031 io->interrupts = htonl((u_int32)handler_calls);
1032 io->int_received = htonl((u_int32)handler_pkts);
1040 * timer_stats - return timer statistics
1044 struct sockaddr_in *srcadr,
1045 struct interface *inter,
1046 struct req_pkt *inpkt
1049 register struct info_timer_stats *ts;
1052 * Importations from the timer module
1054 extern u_long timer_timereset;
1055 extern u_long timer_overflows;
1056 extern u_long timer_xmtcalls;
1058 ts = (struct info_timer_stats *)prepare_pkt(srcadr, inter, inpkt,
1059 sizeof(struct info_timer_stats));
1061 ts->timereset = htonl((u_int32)(current_time - timer_timereset));
1062 ts->alarms = htonl((u_int32)alarm_overflow);
1063 ts->overflows = htonl((u_int32)timer_overflows);
1064 ts->xmtcalls = htonl((u_int32)timer_xmtcalls);
1072 * loop_info - return the current state of the loop filter
1076 struct sockaddr_in *srcadr,
1077 struct interface *inter,
1078 struct req_pkt *inpkt
1081 register struct info_loop *li;
1085 * Importations from the loop filter module
1087 extern double last_offset;
1088 extern double drift_comp;
1089 extern int tc_counter;
1090 extern u_long last_time;
1092 li = (struct info_loop *)prepare_pkt(srcadr, inter, inpkt,
1093 sizeof(struct info_loop));
1095 DTOLFP(last_offset, <mp);
1096 HTONL_FP(<mp, &li->last_offset);
1097 DTOLFP(drift_comp * 1e6, <mp);
1098 HTONL_FP(<mp, &li->drift_comp);
1099 li->compliance = htonl((u_int32)(tc_counter));
1100 li->watchdog_timer = htonl((u_int32)(current_time - last_time));
1108 * do_conf - add a peer to the configuration list
1112 struct sockaddr_in *srcadr,
1113 struct interface *inter,
1114 struct req_pkt *inpkt
1117 register struct conf_peer *cp;
1119 struct sockaddr_in peeraddr;
1123 * Do a check of everything to see that it looks
1124 * okay. If not, complain about it. Note we are
1127 items = INFO_NITEMS(inpkt->err_nitems);
1128 cp = (struct conf_peer *)inpkt->data;
1131 while (items-- > 0 && !fl) {
1132 if (((cp->version) > NTP_VERSION)
1133 || ((cp->version) < NTP_OLDVERSION))
1135 if (cp->hmode != MODE_ACTIVE
1136 && cp->hmode != MODE_CLIENT
1137 && cp->hmode != MODE_BROADCAST)
1139 if (cp->flags & ~(CONF_FLAG_AUTHENABLE | CONF_FLAG_PREFER
1140 | CONF_FLAG_NOSELECT | CONF_FLAG_BURST | CONF_FLAG_SKEY))
1146 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1151 * Looks okay, try it out
1153 items = INFO_NITEMS(inpkt->err_nitems);
1154 cp = (struct conf_peer *)inpkt->data;
1155 memset((char *)&peeraddr, 0, sizeof(struct sockaddr_in));
1156 peeraddr.sin_family = AF_INET;
1157 peeraddr.sin_port = htons(NTP_PORT);
1160 * Make sure the address is valid
1164 !ISREFCLOCKADR(&peeraddr) &&
1166 ISBADADR(&peeraddr)) {
1167 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1171 while (items-- > 0) {
1173 if (cp->flags & CONF_FLAG_AUTHENABLE)
1174 fl |= FLAG_AUTHENABLE;
1175 if (cp->flags & CONF_FLAG_PREFER)
1177 if (cp->flags & CONF_FLAG_NOSELECT)
1178 fl |= FLAG_NOSELECT;
1179 if (cp->flags & CONF_FLAG_BURST)
1181 if (cp->flags & CONF_FLAG_SKEY)
1183 peeraddr.sin_addr.s_addr = cp->peeraddr;
1184 /* XXX W2DO? minpoll/maxpoll arguments ??? */
1185 if (peer_config(&peeraddr, (struct interface *)0,
1186 cp->hmode, cp->version, cp->minpoll, cp->maxpoll,
1187 fl, cp->ttl, cp->keyid) == 0) {
1188 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1194 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1199 * do_unconf - remove a peer from the configuration list
1203 struct sockaddr_in *srcadr,
1204 struct interface *inter,
1205 struct req_pkt *inpkt
1208 register struct conf_unpeer *cp;
1210 register struct peer *peer;
1211 struct sockaddr_in peeraddr;
1215 * This is a bit unstructured, but I like to be careful.
1216 * We check to see that every peer exists and is actually
1217 * configured. If so, we remove them. If not, we return
1220 peeraddr.sin_family = AF_INET;
1221 peeraddr.sin_port = htons(NTP_PORT);
1223 items = INFO_NITEMS(inpkt->err_nitems);
1224 cp = (struct conf_unpeer *)inpkt->data;
1227 while (items-- > 0 && !bad) {
1228 peeraddr.sin_addr.s_addr = cp->peeraddr;
1230 peer = (struct peer *)0;
1232 peer = findexistingpeer(&peeraddr, peer, -1);
1233 if (peer == (struct peer *)0)
1235 if (peer->flags & FLAG_CONFIG)
1244 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1249 * Now do it in earnest.
1252 items = INFO_NITEMS(inpkt->err_nitems);
1253 cp = (struct conf_unpeer *)inpkt->data;
1254 while (items-- > 0) {
1255 peeraddr.sin_addr.s_addr = cp->peeraddr;
1256 peer_unconfig(&peeraddr, (struct interface *)0, -1);
1260 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1265 * set_sys_flag - set system flags
1269 struct sockaddr_in *srcadr,
1270 struct interface *inter,
1271 struct req_pkt *inpkt
1274 setclr_flags(srcadr, inter, inpkt, 1);
1279 * clr_sys_flag - clear system flags
1283 struct sockaddr_in *srcadr,
1284 struct interface *inter,
1285 struct req_pkt *inpkt
1288 setclr_flags(srcadr, inter, inpkt, 0);
1293 * setclr_flags - do the grunge work of flag setting/clearing
1297 struct sockaddr_in *srcadr,
1298 struct interface *inter,
1299 struct req_pkt *inpkt,
1303 register u_long flags;
1305 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
1306 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1310 flags = ((struct conf_sys_flags *)inpkt->data)->flags;
1312 if (flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_AUTHENTICATE |
1313 SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR |
1314 SYS_FLAG_FILEGEN)) {
1315 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1319 if (flags & SYS_FLAG_BCLIENT)
1320 proto_config(PROTO_BROADCLIENT, set, 0.);
1321 if (flags & SYS_FLAG_AUTHENTICATE)
1322 proto_config(PROTO_AUTHENTICATE, set, 0.);
1323 if (flags & SYS_FLAG_NTP)
1324 proto_config(PROTO_NTP, set, 0.);
1325 if (flags & SYS_FLAG_KERNEL)
1326 proto_config(PROTO_KERNEL, set, 0.);
1327 if (flags & SYS_FLAG_MONITOR)
1328 proto_config(PROTO_MONITOR, set, 0.);
1329 if (flags & SYS_FLAG_FILEGEN)
1330 proto_config(PROTO_FILEGEN, set, 0.);
1331 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1336 * list_restrict - return the restrict list
1340 struct sockaddr_in *srcadr,
1341 struct interface *inter,
1342 struct req_pkt *inpkt
1345 register struct info_restrict *ir;
1346 register struct restrictlist *rl;
1347 extern struct restrictlist *restrictlist;
1351 printf("wants peer list summary\n");
1354 ir = (struct info_restrict *)prepare_pkt(srcadr, inter, inpkt,
1355 sizeof(struct info_restrict));
1356 for (rl = restrictlist; rl != 0 && ir != 0; rl = rl->next) {
1357 ir->addr = htonl(rl->addr);
1358 ir->mask = htonl(rl->mask);
1359 ir->count = htonl((u_int32)rl->count);
1360 ir->flags = htons(rl->flags);
1361 ir->mflags = htons(rl->mflags);
1362 ir = (struct info_restrict *)more_pkt();
1370 * do_resaddflags - add flags to a restrict entry (or create one)
1374 struct sockaddr_in *srcadr,
1375 struct interface *inter,
1376 struct req_pkt *inpkt
1379 do_restrict(srcadr, inter, inpkt, RESTRICT_FLAGS);
1385 * do_ressubflags - remove flags from a restrict entry
1389 struct sockaddr_in *srcadr,
1390 struct interface *inter,
1391 struct req_pkt *inpkt
1394 do_restrict(srcadr, inter, inpkt, RESTRICT_UNFLAG);
1399 * do_unrestrict - remove a restrict entry from the list
1403 struct sockaddr_in *srcadr,
1404 struct interface *inter,
1405 struct req_pkt *inpkt
1408 do_restrict(srcadr, inter, inpkt, RESTRICT_REMOVE);
1416 * do_restrict - do the dirty stuff of dealing with restrictions
1420 struct sockaddr_in *srcadr,
1421 struct interface *inter,
1422 struct req_pkt *inpkt,
1426 register struct conf_restrict *cr;
1428 struct sockaddr_in matchaddr;
1429 struct sockaddr_in matchmask;
1433 * Do a check of the flags to make sure that only
1434 * the NTPPORT flag is set, if any. If not, complain
1435 * about it. Note we are very picky here.
1437 items = INFO_NITEMS(inpkt->err_nitems);
1438 cr = (struct conf_restrict *)inpkt->data;
1441 while (items-- > 0 && !bad) {
1442 if (cr->mflags & ~(RESM_NTPONLY))
1444 if (cr->flags & ~(RES_ALLFLAGS))
1446 if (cr->addr == htonl(INADDR_ANY) && cr->mask != htonl(INADDR_ANY))
1452 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1457 * Looks okay, try it out
1459 items = INFO_NITEMS(inpkt->err_nitems);
1460 cr = (struct conf_restrict *)inpkt->data;
1461 memset((char *)&matchaddr, 0, sizeof(struct sockaddr_in));
1462 memset((char *)&matchmask, 0, sizeof(struct sockaddr_in));
1463 matchaddr.sin_family = AF_INET;
1464 matchmask.sin_family = AF_INET;
1466 while (items-- > 0) {
1467 matchaddr.sin_addr.s_addr = cr->addr;
1468 matchmask.sin_addr.s_addr = cr->mask;
1469 hack_restrict(op, &matchaddr, &matchmask, cr->mflags,
1474 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1479 * mon_getlist - return monitor data
1483 struct sockaddr_in *srcadr,
1484 struct interface *inter,
1485 struct req_pkt *inpkt
1488 register struct info_monitor *im;
1489 register struct mon_data *md;
1490 extern struct mon_data mon_mru_list;
1491 extern int mon_enabled;
1495 printf("wants monitor 0 list\n");
1498 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1502 im = (struct info_monitor *)prepare_pkt(srcadr, inter, inpkt,
1503 sizeof(struct info_monitor));
1504 for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
1505 md = md->mru_next) {
1506 im->lasttime = htonl((u_int32)(current_time - md->lasttime));
1507 im->firsttime = htonl((u_int32)(current_time - md->firsttime));
1509 im->lastdrop = htonl((u_int32)(current_time - md->lastdrop));
1512 im->count = htonl((u_int32)(md->count));
1513 im->addr = md->rmtadr;
1514 im->port = md->rmtport;
1515 im->mode = md->mode;
1516 im->version = md->version;
1517 im = (struct info_monitor *)more_pkt();
1523 * mon_getlist - return monitor data
1527 struct sockaddr_in *srcadr,
1528 struct interface *inter,
1529 struct req_pkt *inpkt
1532 register struct info_monitor_1 *im;
1533 register struct mon_data *md;
1534 extern struct mon_data mon_mru_list;
1535 extern int mon_enabled;
1539 printf("wants monitor 1 list\n");
1542 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1546 im = (struct info_monitor_1 *)prepare_pkt(srcadr, inter, inpkt,
1547 sizeof(struct info_monitor_1));
1548 for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
1549 md = md->mru_next) {
1550 im->lasttime = htonl((u_int32)(current_time - md->lasttime));
1551 im->firsttime = htonl((u_int32)(current_time - md->firsttime));
1553 im->lastdrop = htonl((u_int32)(current_time - md->lastdrop));
1556 im->count = htonl((u_int32)md->count);
1557 im->addr = md->rmtadr;
1559 (md->cast_flags == MDF_BCAST)
1560 ? md->interface->bcast.sin_addr.s_addr
1562 ? (md->interface->sin.sin_addr.s_addr
1563 ? md->interface->sin.sin_addr.s_addr
1564 : md->interface->bcast.sin_addr.s_addr
1567 im->flags = md->cast_flags;
1568 im->port = md->rmtport;
1569 im->mode = md->mode;
1570 im->version = md->version;
1571 im = (struct info_monitor_1 *)more_pkt();
1577 * Module entry points and the flags they correspond with
1579 struct reset_entry {
1580 int flag; /* flag this corresponds to */
1581 void (*handler) P((void)); /* routine to handle request */
1584 struct reset_entry reset_entries[] = {
1585 { RESET_FLAG_ALLPEERS, peer_all_reset },
1586 { RESET_FLAG_IO, io_clr_stats },
1587 { RESET_FLAG_SYS, proto_clr_stats },
1588 { RESET_FLAG_MEM, peer_clr_stats },
1589 { RESET_FLAG_TIMER, timer_clr_stats },
1590 { RESET_FLAG_AUTH, reset_auth_stats },
1591 { RESET_FLAG_CTL, ctl_clr_stats },
1596 * reset_stats - reset statistic counters here and there
1600 struct sockaddr_in *srcadr,
1601 struct interface *inter,
1602 struct req_pkt *inpkt
1606 struct reset_entry *rent;
1608 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
1609 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1613 flags = ((struct reset_flags *)inpkt->data)->flags;
1615 if (flags & ~RESET_ALLFLAGS) {
1616 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1620 for (rent = reset_entries; rent->flag != 0; rent++) {
1621 if (flags & rent->flag)
1624 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1629 * reset_peer - clear a peer's statistics
1633 struct sockaddr_in *srcadr,
1634 struct interface *inter,
1635 struct req_pkt *inpkt
1638 register struct conf_unpeer *cp;
1640 register struct peer *peer;
1641 struct sockaddr_in peeraddr;
1645 * We check first to see that every peer exists. If not,
1646 * we return an error.
1648 peeraddr.sin_family = AF_INET;
1649 peeraddr.sin_port = htons(NTP_PORT);
1651 items = INFO_NITEMS(inpkt->err_nitems);
1652 cp = (struct conf_unpeer *)inpkt->data;
1655 while (items-- > 0 && !bad) {
1656 peeraddr.sin_addr.s_addr = cp->peeraddr;
1657 peer = findexistingpeer(&peeraddr, (struct peer *)0, -1);
1658 if (peer == (struct peer *)0)
1664 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1669 * Now do it in earnest.
1672 items = INFO_NITEMS(inpkt->err_nitems);
1673 cp = (struct conf_unpeer *)inpkt->data;
1674 while (items-- > 0) {
1675 peeraddr.sin_addr.s_addr = cp->peeraddr;
1676 peer = findexistingpeer(&peeraddr, (struct peer *)0, -1);
1679 peer = findexistingpeer(&peeraddr, (struct peer *)peer, -1);
1684 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1689 * do_key_reread - reread the encryption key file
1693 struct sockaddr_in *srcadr,
1694 struct interface *inter,
1695 struct req_pkt *inpkt
1699 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1704 * trust_key - make one or more keys trusted
1708 struct sockaddr_in *srcadr,
1709 struct interface *inter,
1710 struct req_pkt *inpkt
1713 do_trustkey(srcadr, inter, inpkt, 1);
1718 * untrust_key - make one or more keys untrusted
1722 struct sockaddr_in *srcadr,
1723 struct interface *inter,
1724 struct req_pkt *inpkt
1727 do_trustkey(srcadr, inter, inpkt, 0);
1732 * do_trustkey - make keys either trustable or untrustable
1736 struct sockaddr_in *srcadr,
1737 struct interface *inter,
1738 struct req_pkt *inpkt,
1742 register u_long *kp;
1745 items = INFO_NITEMS(inpkt->err_nitems);
1746 kp = (u_long *)inpkt->data;
1747 while (items-- > 0) {
1748 authtrust(*kp, trust);
1752 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1757 * get_auth_info - return some stats concerning the authentication module
1761 struct sockaddr_in *srcadr,
1762 struct interface *inter,
1763 struct req_pkt *inpkt
1766 register struct info_auth *ia;
1769 * Importations from the authentication module
1771 extern u_long authnumkeys;
1772 extern int authnumfreekeys;
1773 extern u_long authkeylookups;
1774 extern u_long authkeynotfound;
1775 extern u_long authencryptions;
1776 extern u_long authdecryptions;
1777 extern u_long authkeyuncached;
1778 extern u_long authkeyexpired;
1780 ia = (struct info_auth *)prepare_pkt(srcadr, inter, inpkt,
1781 sizeof(struct info_auth));
1783 ia->numkeys = htonl((u_int32)authnumkeys);
1784 ia->numfreekeys = htonl((u_int32)authnumfreekeys);
1785 ia->keylookups = htonl((u_int32)authkeylookups);
1786 ia->keynotfound = htonl((u_int32)authkeynotfound);
1787 ia->encryptions = htonl((u_int32)authencryptions);
1788 ia->decryptions = htonl((u_int32)authdecryptions);
1789 ia->keyuncached = htonl((u_int32)authkeyuncached);
1790 ia->expired = htonl((u_int32)authkeyexpired);
1791 ia->timereset = htonl((u_int32)(current_time - auth_timereset));
1800 * reset_auth_stats - reset the authentication stat counters. Done here
1801 * to keep ntp-isms out of the authentication module
1804 reset_auth_stats(void)
1807 * Importations from the authentication module
1809 extern u_long authkeylookups;
1810 extern u_long authkeynotfound;
1811 extern u_long authencryptions;
1812 extern u_long authdecryptions;
1813 extern u_long authkeyuncached;
1816 authkeynotfound = 0;
1817 authencryptions = 0;
1818 authdecryptions = 0;
1819 authkeyuncached = 0;
1820 auth_timereset = current_time;
1825 * req_get_traps - return information about current trap holders
1829 struct sockaddr_in *srcadr,
1830 struct interface *inter,
1831 struct req_pkt *inpkt
1834 register struct info_trap *it;
1835 register struct ctl_trap *tr;
1839 * Imported from the control module
1841 extern struct ctl_trap ctl_trap[];
1842 extern int num_ctl_traps;
1844 if (num_ctl_traps == 0) {
1845 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1849 it = (struct info_trap *)prepare_pkt(srcadr, inter, inpkt,
1850 sizeof(struct info_trap));
1852 for (i = 0, tr = ctl_trap; i < CTL_MAXTRAPS; i++, tr++) {
1853 if (tr->tr_flags & TRAP_INUSE) {
1854 if (tr->tr_localaddr == any_interface)
1855 it->local_address = 0;
1858 = NSRCADR(&tr->tr_localaddr->sin);
1859 it->trap_address = NSRCADR(&tr->tr_addr);
1860 it->trap_port = NSRCPORT(&tr->tr_addr);
1861 it->sequence = htons(tr->tr_sequence);
1862 it->settime = htonl((u_int32)(current_time - tr->tr_settime));
1863 it->origtime = htonl((u_int32)(current_time - tr->tr_origtime));
1864 it->resets = htonl((u_int32)tr->tr_resets);
1865 it->flags = htonl((u_int32)tr->tr_flags);
1866 it = (struct info_trap *)more_pkt();
1874 * req_set_trap - configure a trap
1878 struct sockaddr_in *srcadr,
1879 struct interface *inter,
1880 struct req_pkt *inpkt
1883 do_setclr_trap(srcadr, inter, inpkt, 1);
1889 * req_clr_trap - unconfigure a trap
1893 struct sockaddr_in *srcadr,
1894 struct interface *inter,
1895 struct req_pkt *inpkt
1898 do_setclr_trap(srcadr, inter, inpkt, 0);
1904 * do_setclr_trap - do the grunge work of (un)configuring a trap
1908 struct sockaddr_in *srcadr,
1909 struct interface *inter,
1910 struct req_pkt *inpkt,
1914 register struct conf_trap *ct;
1915 register struct interface *linter;
1917 struct sockaddr_in laddr;
1920 * Prepare sockaddr_in structure
1922 memset((char *)&laddr, 0, sizeof laddr);
1923 laddr.sin_family = AF_INET;
1924 laddr.sin_port = ntohs(NTP_PORT);
1927 * Restrict ourselves to one item only. This eliminates
1928 * the error reporting problem.
1930 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
1931 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1934 ct = (struct conf_trap *)inpkt->data;
1937 * Look for the local interface. If none, use the default.
1939 if (ct->local_address == 0) {
1940 linter = any_interface;
1942 laddr.sin_addr.s_addr = ct->local_address;
1943 linter = findinterface(&laddr);
1944 if (linter == NULL) {
1945 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1950 laddr.sin_addr.s_addr = ct->trap_address;
1951 if (ct->trap_port != 0)
1952 laddr.sin_port = ct->trap_port;
1954 laddr.sin_port = htons(TRAPPORT);
1957 res = ctlsettrap(&laddr, linter, 0,
1958 INFO_VERSION(inpkt->rm_vn_mode));
1960 res = ctlclrtrap(&laddr, linter, 0);
1964 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1966 req_ack(srcadr, inter, inpkt, INFO_OKAY);
1974 * set_request_keyid - set the keyid used to authenticate requests
1978 struct sockaddr_in *srcadr,
1979 struct interface *inter,
1980 struct req_pkt *inpkt
1986 * Restrict ourselves to one item only.
1988 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
1989 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1993 keyid = ntohl(*((u_int32 *)(inpkt->data)));
1994 info_auth_keyid = keyid;
1995 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2001 * set_control_keyid - set the keyid used to authenticate requests
2005 struct sockaddr_in *srcadr,
2006 struct interface *inter,
2007 struct req_pkt *inpkt
2011 extern u_long ctl_auth_keyid;
2014 * Restrict ourselves to one item only.
2016 if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2017 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2021 keyid = ntohl(*((u_int32 *)(inpkt->data)));
2022 ctl_auth_keyid = keyid;
2023 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2029 * get_ctl_stats - return some stats concerning the control message module
2033 struct sockaddr_in *srcadr,
2034 struct interface *inter,
2035 struct req_pkt *inpkt
2038 register struct info_control *ic;
2041 * Importations from the control module
2043 extern u_long ctltimereset;
2044 extern u_long numctlreq;
2045 extern u_long numctlbadpkts;
2046 extern u_long numctlresponses;
2047 extern u_long numctlfrags;
2048 extern u_long numctlerrors;
2049 extern u_long numctltooshort;
2050 extern u_long numctlinputresp;
2051 extern u_long numctlinputfrag;
2052 extern u_long numctlinputerr;
2053 extern u_long numctlbadoffset;
2054 extern u_long numctlbadversion;
2055 extern u_long numctldatatooshort;
2056 extern u_long numctlbadop;
2057 extern u_long numasyncmsgs;
2059 ic = (struct info_control *)prepare_pkt(srcadr, inter, inpkt,
2060 sizeof(struct info_control));
2062 ic->ctltimereset = htonl((u_int32)(current_time - ctltimereset));
2063 ic->numctlreq = htonl((u_int32)numctlreq);
2064 ic->numctlbadpkts = htonl((u_int32)numctlbadpkts);
2065 ic->numctlresponses = htonl((u_int32)numctlresponses);
2066 ic->numctlfrags = htonl((u_int32)numctlfrags);
2067 ic->numctlerrors = htonl((u_int32)numctlerrors);
2068 ic->numctltooshort = htonl((u_int32)numctltooshort);
2069 ic->numctlinputresp = htonl((u_int32)numctlinputresp);
2070 ic->numctlinputfrag = htonl((u_int32)numctlinputfrag);
2071 ic->numctlinputerr = htonl((u_int32)numctlinputerr);
2072 ic->numctlbadoffset = htonl((u_int32)numctlbadoffset);
2073 ic->numctlbadversion = htonl((u_int32)numctlbadversion);
2074 ic->numctldatatooshort = htonl((u_int32)numctldatatooshort);
2075 ic->numctlbadop = htonl((u_int32)numctlbadop);
2076 ic->numasyncmsgs = htonl((u_int32)numasyncmsgs);
2085 * get_kernel_info - get kernel pll/pps information
2089 struct sockaddr_in *srcadr,
2090 struct interface *inter,
2091 struct req_pkt *inpkt
2094 register struct info_kernel *ik;
2098 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2102 memset((char *)&ntx, 0, sizeof(ntx));
2103 if (ntp_adjtime(&ntx) < 0)
2104 msyslog(LOG_ERR, "get_kernel_info: ntp_adjtime() failed: %m");
2105 ik = (struct info_kernel *)prepare_pkt(srcadr, inter, inpkt,
2106 sizeof(struct info_kernel));
2111 ik->offset = htonl((u_int32)ntx.offset);
2112 ik->freq = htonl((u_int32)ntx.freq);
2113 ik->maxerror = htonl((u_int32)ntx.maxerror);
2114 ik->esterror = htonl((u_int32)ntx.esterror);
2115 ik->status = htons(ntx.status);
2116 ik->constant = htonl((u_int32)ntx.constant);
2117 ik->precision = htonl((u_int32)ntx.precision);
2118 ik->tolerance = htonl((u_int32)ntx.tolerance);
2123 ik->ppsfreq = htonl((u_int32)ntx.ppsfreq);
2124 ik->jitter = htonl((u_int32)ntx.jitter);
2125 ik->shift = htons(ntx.shift);
2126 ik->stabil = htonl((u_int32)ntx.stabil);
2127 ik->jitcnt = htonl((u_int32)ntx.jitcnt);
2128 ik->calcnt = htonl((u_int32)ntx.calcnt);
2129 ik->errcnt = htonl((u_int32)ntx.errcnt);
2130 ik->stbcnt = htonl((u_int32)ntx.stbcnt);
2135 #endif /* KERNEL_PLL */
2140 * get_clock_info - get info about a clock
2144 struct sockaddr_in *srcadr,
2145 struct interface *inter,
2146 struct req_pkt *inpkt
2149 register struct info_clock *ic;
2150 register u_int32 *clkaddr;
2152 struct refclockstat clock_stat;
2153 struct sockaddr_in addr;
2156 memset((char *)&addr, 0, sizeof addr);
2157 addr.sin_family = AF_INET;
2158 addr.sin_port = htons(NTP_PORT);
2159 items = INFO_NITEMS(inpkt->err_nitems);
2160 clkaddr = (u_int32 *) inpkt->data;
2162 ic = (struct info_clock *)prepare_pkt(srcadr, inter, inpkt,
2163 sizeof(struct info_clock));
2165 while (items-- > 0) {
2166 addr.sin_addr.s_addr = *clkaddr++;
2167 if (!ISREFCLOCKADR(&addr) ||
2168 findexistingpeer(&addr, (struct peer *)0, -1) == 0) {
2169 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2173 clock_stat.kv_list = (struct ctl_var *)0;
2175 refclock_control(&addr, (struct refclockstat *)0, &clock_stat);
2177 ic->clockadr = addr.sin_addr.s_addr;
2178 ic->type = clock_stat.type;
2179 ic->flags = clock_stat.flags;
2180 ic->lastevent = clock_stat.lastevent;
2181 ic->currentstatus = clock_stat.currentstatus;
2182 ic->polls = htonl((u_int32)clock_stat.polls);
2183 ic->noresponse = htonl((u_int32)clock_stat.noresponse);
2184 ic->badformat = htonl((u_int32)clock_stat.badformat);
2185 ic->baddata = htonl((u_int32)clock_stat.baddata);
2186 ic->timestarted = htonl((u_int32)clock_stat.timereset);
2187 DTOLFP(clock_stat.fudgetime1, <mp);
2188 HTONL_FP(<mp, &ic->fudgetime1);
2189 DTOLFP(clock_stat.fudgetime1, <mp);
2190 HTONL_FP(<mp, &ic->fudgetime2);
2191 ic->fudgeval1 = htonl((u_int32)clock_stat.fudgeval1);
2192 ic->fudgeval2 = htonl((u_int32)clock_stat.fudgeval2);
2194 free_varlist(clock_stat.kv_list);
2196 ic = (struct info_clock *)more_pkt();
2204 * set_clock_fudge - get a clock's fudge factors
2208 struct sockaddr_in *srcadr,
2209 struct interface *inter,
2210 struct req_pkt *inpkt
2213 register struct conf_fudge *cf;
2215 struct refclockstat clock_stat;
2216 struct sockaddr_in addr;
2219 memset((char *)&addr, 0, sizeof addr);
2220 memset((char *)&clock_stat, 0, sizeof clock_stat);
2221 addr.sin_family = AF_INET;
2222 addr.sin_port = htons(NTP_PORT);
2223 items = INFO_NITEMS(inpkt->err_nitems);
2224 cf = (struct conf_fudge *) inpkt->data;
2226 while (items-- > 0) {
2227 addr.sin_addr.s_addr = cf->clockadr;
2228 if (!ISREFCLOCKADR(&addr) ||
2229 findexistingpeer(&addr, (struct peer *)0, -1) == 0) {
2230 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2234 switch(ntohl(cf->which)) {
2236 NTOHL_FP(&cf->fudgetime, <mp);
2237 LFPTOD(<mp, clock_stat.fudgetime1);
2238 clock_stat.haveflags = CLK_HAVETIME1;
2241 NTOHL_FP(&cf->fudgetime, <mp);
2242 LFPTOD(<mp, clock_stat.fudgetime2);
2243 clock_stat.haveflags = CLK_HAVETIME2;
2246 clock_stat.fudgeval1 = ntohl(cf->fudgeval_flags);
2247 clock_stat.haveflags = CLK_HAVEVAL1;
2250 clock_stat.fudgeval2 = ntohl(cf->fudgeval_flags);
2251 clock_stat.haveflags = CLK_HAVEVAL2;
2254 clock_stat.flags = (u_char) ntohl(cf->fudgeval_flags) & 0xf;
2255 clock_stat.haveflags =
2256 (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4);
2259 req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2263 refclock_control(&addr, &clock_stat, (struct refclockstat *)0);
2266 req_ack(srcadr, inter, inpkt, INFO_OKAY);
2272 * get_clkbug_info - get debugging info about a clock
2276 struct sockaddr_in *srcadr,
2277 struct interface *inter,
2278 struct req_pkt *inpkt
2282 register struct info_clkbug *ic;
2283 register u_int32 *clkaddr;
2285 struct refclockbug bug;
2286 struct sockaddr_in addr;
2288 memset((char *)&addr, 0, sizeof addr);
2289 addr.sin_family = AF_INET;
2290 addr.sin_port = htons(NTP_PORT);
2291 items = INFO_NITEMS(inpkt->err_nitems);
2292 clkaddr = (u_int32 *) inpkt->data;
2294 ic = (struct info_clkbug *)prepare_pkt(srcadr, inter, inpkt,
2295 sizeof(struct info_clkbug));
2297 while (items-- > 0) {
2298 addr.sin_addr.s_addr = *clkaddr++;
2299 if (!ISREFCLOCKADR(&addr) ||
2300 findexistingpeer(&addr, (struct peer *)0, -1) == 0) {
2301 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2305 memset((char *)&bug, 0, sizeof bug);
2306 refclock_buginfo(&addr, &bug);
2307 if (bug.nvalues == 0 && bug.ntimes == 0) {
2308 req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2312 ic->clockadr = addr.sin_addr.s_addr;
2314 if (i > NUMCBUGVALUES)
2316 ic->nvalues = (u_char)i;
2317 ic->svalues = htons((u_short) (bug.svalues & ((1<<i)-1)));
2319 ic->values[i] = htonl(bug.values[i]);
2322 if (i > NUMCBUGTIMES)
2324 ic->ntimes = (u_char)i;
2325 ic->stimes = htonl(bug.stimes);
2327 HTONL_FP(&bug.times[i], &ic->times[i]);
2330 ic = (struct info_clkbug *)more_pkt();