1 /* $NetBSD: ntp_request.c,v 1.8 2008/08/23 09:10:31 kardel Exp $ */
4 * ntp_request.c - respond to information requests
13 #include "ntp_request.h"
14 #include "ntp_control.h"
15 #include "ntp_refclock.h"
17 #include "ntp_stdlib.h"
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
28 #include "ntp_syscall.h"
29 #endif /* KERNEL_PLL */
32 * Structure to hold request procedure information
37 #define NO_REQUEST (-1)
39 * Because we now have v6 addresses in the messages, we need to compensate
40 * for the larger size. Therefore, we introduce the alternate size to
41 * keep us friendly with older implementations. A little ugly.
43 static int client_v6_capable
= 0; /* the client can handle longer messages */
45 #define v6sizeof(type) (client_v6_capable ? sizeof(type) : v4sizeof(type))
48 short request_code
; /* defined request code */
49 short needs_auth
; /* true when authentication needed */
50 short sizeofitem
; /* size of request data item (older size)*/
51 short v6_sizeofitem
; /* size of request data item (new size)*/
52 void (*handler
) P((struct sockaddr_storage
*, struct interface
*,
53 struct req_pkt
*)); /* routine to handle request */
57 * Universal request codes
59 static struct req_proc univ_codes
[] = {
60 { NO_REQUEST
, NOAUTH
, 0, 0 }
63 static void req_ack
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*, int));
64 static char * prepare_pkt
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*, u_int
));
65 static char * more_pkt
P((void));
66 static void flush_pkt
P((void));
67 static void peer_list
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
68 static void peer_list_sum
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
69 static void peer_info
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
70 static void peer_stats
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
71 static void sys_info
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
72 static void sys_stats
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
73 static void mem_stats
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
74 static void io_stats
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
75 static void timer_stats
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
76 static void loop_info
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
77 static void do_conf
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
78 static void do_unconf
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
79 static void set_sys_flag
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
80 static void clr_sys_flag
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
81 static void setclr_flags
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*, u_long
));
82 static void list_restrict
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
83 static void do_resaddflags
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
84 static void do_ressubflags
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
85 static void do_unrestrict
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
86 static void do_restrict
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*, int));
87 static void mon_getlist_0
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
88 static void mon_getlist_1
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
89 static void reset_stats
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
90 static void reset_peer
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
91 static void do_key_reread
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
92 static void trust_key
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
93 static void untrust_key
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
94 static void do_trustkey
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*, u_long
));
95 static void get_auth_info
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
96 static void reset_auth_stats
P((void));
97 static void req_get_traps
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
98 static void req_set_trap
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
99 static void req_clr_trap
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
100 static void do_setclr_trap
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*, int));
101 static void set_request_keyid
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
102 static void set_control_keyid
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
103 static void get_ctl_stats
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
104 static void get_if_stats
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
105 static void do_if_reload
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
107 static void get_kernel_info
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
108 #endif /* KERNEL_PLL */
110 static void get_clock_info
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
111 static void set_clock_fudge
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
112 #endif /* REFCLOCK */
114 static void get_clkbug_info
P((struct sockaddr_storage
*, struct interface
*, struct req_pkt
*));
115 #endif /* REFCLOCK */
120 static struct req_proc ntp_codes
[] = {
121 { REQ_PEER_LIST
, NOAUTH
, 0, 0, peer_list
},
122 { REQ_PEER_LIST_SUM
, NOAUTH
, 0, 0, peer_list_sum
},
123 { REQ_PEER_INFO
, NOAUTH
, v4sizeof(struct info_peer_list
),
124 sizeof(struct info_peer_list
), peer_info
},
125 { REQ_PEER_STATS
, NOAUTH
, v4sizeof(struct info_peer_list
),
126 sizeof(struct info_peer_list
), peer_stats
},
127 { REQ_SYS_INFO
, NOAUTH
, 0, 0, sys_info
},
128 { REQ_SYS_STATS
, NOAUTH
, 0, 0, sys_stats
},
129 { REQ_IO_STATS
, NOAUTH
, 0, 0, io_stats
},
130 { REQ_MEM_STATS
, NOAUTH
, 0, 0, mem_stats
},
131 { REQ_LOOP_INFO
, NOAUTH
, 0, 0, loop_info
},
132 { REQ_TIMER_STATS
, NOAUTH
, 0, 0, timer_stats
},
133 { REQ_CONFIG
, AUTH
, v4sizeof(struct conf_peer
),
134 sizeof(struct conf_peer
), do_conf
},
135 { REQ_UNCONFIG
, AUTH
, v4sizeof(struct conf_unpeer
),
136 sizeof(struct conf_unpeer
), do_unconf
},
137 { REQ_SET_SYS_FLAG
, AUTH
, sizeof(struct conf_sys_flags
),
138 sizeof(struct conf_sys_flags
), set_sys_flag
},
139 { REQ_CLR_SYS_FLAG
, AUTH
, sizeof(struct conf_sys_flags
),
140 sizeof(struct conf_sys_flags
), clr_sys_flag
},
141 { REQ_GET_RESTRICT
, NOAUTH
, 0, 0, list_restrict
},
142 { REQ_RESADDFLAGS
, AUTH
, v4sizeof(struct conf_restrict
),
143 sizeof(struct conf_restrict
), do_resaddflags
},
144 { REQ_RESSUBFLAGS
, AUTH
, v4sizeof(struct conf_restrict
),
145 sizeof(struct conf_restrict
), do_ressubflags
},
146 { REQ_UNRESTRICT
, AUTH
, v4sizeof(struct conf_restrict
),
147 sizeof(struct conf_restrict
), do_unrestrict
},
148 { REQ_MON_GETLIST
, NOAUTH
, 0, 0, mon_getlist_0
},
149 { REQ_MON_GETLIST_1
, NOAUTH
, 0, 0, mon_getlist_1
},
150 { REQ_RESET_STATS
, AUTH
, sizeof(struct reset_flags
), 0, reset_stats
},
151 { REQ_RESET_PEER
, AUTH
, v4sizeof(struct conf_unpeer
),
152 sizeof(struct conf_unpeer
), reset_peer
},
153 { REQ_REREAD_KEYS
, AUTH
, 0, 0, do_key_reread
},
154 { REQ_TRUSTKEY
, AUTH
, sizeof(u_long
), sizeof(u_long
), trust_key
},
155 { REQ_UNTRUSTKEY
, AUTH
, sizeof(u_long
), sizeof(u_long
), untrust_key
},
156 { REQ_AUTHINFO
, NOAUTH
, 0, 0, get_auth_info
},
157 { REQ_TRAPS
, NOAUTH
, 0, 0, req_get_traps
},
158 { REQ_ADD_TRAP
, AUTH
, v4sizeof(struct conf_trap
),
159 sizeof(struct conf_trap
), req_set_trap
},
160 { REQ_CLR_TRAP
, AUTH
, v4sizeof(struct conf_trap
),
161 sizeof(struct conf_trap
), req_clr_trap
},
162 { REQ_REQUEST_KEY
, AUTH
, sizeof(u_long
), sizeof(u_long
),
164 { REQ_CONTROL_KEY
, AUTH
, sizeof(u_long
), sizeof(u_long
),
166 { REQ_GET_CTLSTATS
, NOAUTH
, 0, 0, get_ctl_stats
},
168 { REQ_GET_KERNEL
, NOAUTH
, 0, 0, get_kernel_info
},
171 { REQ_GET_CLOCKINFO
, NOAUTH
, sizeof(u_int32
), sizeof(u_int32
),
173 { REQ_SET_CLKFUDGE
, AUTH
, sizeof(struct conf_fudge
),
174 sizeof(struct conf_fudge
), set_clock_fudge
},
175 { REQ_GET_CLKBUGINFO
, NOAUTH
, sizeof(u_int32
), sizeof(u_int32
),
178 { REQ_IF_STATS
, AUTH
, 0, 0, get_if_stats
},
179 { REQ_IF_RELOAD
, AUTH
, 0, 0, do_if_reload
},
181 { NO_REQUEST
, NOAUTH
, 0, 0, 0 }
186 * Authentication keyid used to authenticate requests. Zero means we
187 * don't allow writing anything.
189 keyid_t info_auth_keyid
;
192 * Statistic counters to keep track of requests and responses.
194 u_long numrequests
; /* number of requests we've received */
195 u_long numresppkts
; /* number of resp packets sent with data */
197 u_long errorcounter
[INFO_ERR_AUTH
+1]; /* lazy way to count errors, indexed */
198 /* by the error code */
201 * A hack. To keep the authentication module clear of ntp-ism's, we
202 * include a time reset variable for its stats here.
204 static u_long auth_timereset
;
207 * Response packet used by these routines. Also some state information
208 * so that we can handle packet formatting within a common set of
209 * subroutines. Note we try to enter data in place whenever possible,
210 * but the need to set the more bit correctly means we occasionally
211 * use the extra buffer and copy.
213 static struct resp_pkt rpkt
;
218 static int databytes
;
219 static char exbuf
[RESP_DATA_SIZE
];
220 static int usingexbuf
;
221 static struct sockaddr_storage
*toaddr
;
222 static struct interface
*frominter
;
225 * init_request - initialize request data
235 info_auth_keyid
= 0; /* by default, can't do this */
237 for (i
= 0; i
< sizeof(errorcounter
)/sizeof(errorcounter
[0]); i
++)
243 * req_ack - acknowledge request with no data
247 struct sockaddr_storage
*srcadr
,
248 struct interface
*inter
,
249 struct req_pkt
*inpkt
,
256 rpkt
.rm_vn_mode
= RM_VN_MODE(RESP_BIT
, 0, reqver
);
257 rpkt
.auth_seq
= AUTH_SEQ(0, 0);
258 rpkt
.implementation
= inpkt
->implementation
;
259 rpkt
.request
= inpkt
->request
;
260 rpkt
.err_nitems
= ERR_NITEMS(errcode
, 0);
261 rpkt
.mbz_itemsize
= MBZ_ITEMSIZE(0);
264 * send packet and bump counters
266 sendpkt(srcadr
, inter
, -1, (struct pkt
*)&rpkt
, RESP_HEADER_SIZE
);
267 errorcounter
[errcode
]++;
272 * prepare_pkt - prepare response packet for transmission, return pointer
273 * to storage for data item.
277 struct sockaddr_storage
*srcadr
,
278 struct interface
*inter
,
285 printf("request: preparing pkt\n");
289 * Fill in the implementation, request and itemsize fields
290 * since these won't change.
292 rpkt
.implementation
= pkt
->implementation
;
293 rpkt
.request
= pkt
->request
;
294 rpkt
.mbz_itemsize
= MBZ_ITEMSIZE(structsize
);
297 * Compute the static data needed to carry on.
303 itemsize
= structsize
;
308 * return the beginning of the packet buffer.
310 return &rpkt
.data
[0];
315 * more_pkt - return a data pointer for a new item.
321 * If we were using the extra buffer, send the packet.
326 printf("request: sending pkt\n");
328 rpkt
.rm_vn_mode
= RM_VN_MODE(RESP_BIT
, MORE_BIT
, reqver
);
329 rpkt
.auth_seq
= AUTH_SEQ(0, seqno
);
330 rpkt
.err_nitems
= htons((u_short
)nitems
);
331 sendpkt(toaddr
, frominter
, -1, (struct pkt
*)&rpkt
,
332 RESP_HEADER_SIZE
+databytes
);
336 * Copy data out of exbuf into the packet.
338 memmove(&rpkt
.data
[0], exbuf
, (unsigned)itemsize
);
345 databytes
+= itemsize
;
347 if (databytes
+ itemsize
<= RESP_DATA_SIZE
) {
350 printf("request: giving him more data\n");
353 * More room in packet. Give him the
356 return &rpkt
.data
[databytes
];
359 * No room in packet. Give him the extra
360 * buffer unless this was the last in the sequence.
364 printf("request: into extra buffer\n");
377 * flush_pkt - we're done, return remaining information.
384 printf("request: flushing packet, %d items\n", nitems
);
387 * Must send the last packet. If nothing in here and nothing
388 * has been sent, send an error saying no data to be found.
390 if (seqno
== 0 && nitems
== 0)
391 req_ack(toaddr
, frominter
, (struct req_pkt
*)&rpkt
,
394 rpkt
.rm_vn_mode
= RM_VN_MODE(RESP_BIT
, 0, reqver
);
395 rpkt
.auth_seq
= AUTH_SEQ(0, seqno
);
396 rpkt
.err_nitems
= htons((u_short
)nitems
);
397 sendpkt(toaddr
, frominter
, -1, (struct pkt
*)&rpkt
,
398 RESP_HEADER_SIZE
+databytes
);
406 * process_private - process private mode (7) packets
410 struct recvbuf
*rbufp
,
414 struct req_pkt
*inpkt
;
415 struct req_pkt_tail
*tailinpkt
;
416 struct sockaddr_storage
*srcadr
;
417 struct interface
*inter
;
418 struct req_proc
*proc
;
423 * Initialize pointers, for convenience
425 inpkt
= (struct req_pkt
*)&rbufp
->recv_pkt
;
426 srcadr
= &rbufp
->recv_srcadr
;
427 inter
= rbufp
->dstadr
;
431 printf("process_private: impl %d req %d\n",
432 inpkt
->implementation
, inpkt
->request
);
436 * Do some sanity checks on the packet. Return a format
440 if ( (++ec
, ISRESPONSE(inpkt
->rm_vn_mode
))
441 || (++ec
, ISMORE(inpkt
->rm_vn_mode
))
442 || (++ec
, INFO_VERSION(inpkt
->rm_vn_mode
) > NTP_VERSION
)
443 || (++ec
, INFO_VERSION(inpkt
->rm_vn_mode
) < NTP_OLDVERSION
)
444 || (++ec
, INFO_SEQ(inpkt
->auth_seq
) != 0)
445 || (++ec
, INFO_ERR(inpkt
->err_nitems
) != 0)
446 || (++ec
, INFO_MBZ(inpkt
->mbz_itemsize
) != 0)
447 || (++ec
, rbufp
->recv_length
< REQ_LEN_HDR
)
449 msyslog(LOG_ERR
, "process_private: INFO_ERR_FMT: test %d failed, pkt from %s", ec
, stoa(srcadr
));
450 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
454 reqver
= INFO_VERSION(inpkt
->rm_vn_mode
);
457 * Get the appropriate procedure list to search.
459 if (inpkt
->implementation
== IMPL_UNIV
)
461 else if ((inpkt
->implementation
== IMPL_XNTPD
) ||
462 (inpkt
->implementation
== IMPL_XNTPD_OLD
))
465 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_IMPL
);
470 * Search the list for the request codes. If it isn't one
471 * we know, return an error.
473 while (proc
->request_code
!= NO_REQUEST
) {
474 if (proc
->request_code
== (short) inpkt
->request
)
478 if (proc
->request_code
== NO_REQUEST
) {
479 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_REQ
);
485 printf("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
))) {
507 printf("process_private: wrong item size, received %d, should be %d or %d\n",
508 temp_size
, proc
->sizeofitem
, proc
->v6_sizeofitem
);
510 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
513 if ((proc
->sizeofitem
!= 0) &&
514 ((temp_size
* INFO_NITEMS(inpkt
->err_nitems
)) >
515 (rbufp
->recv_length
- REQ_LEN_HDR
))) {
518 printf("process_private: not enough data\n");
520 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
524 switch (inpkt
->implementation
) {
526 client_v6_capable
= 1;
529 client_v6_capable
= 0;
532 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
537 * If we need to authenticate, do so. Note that an
538 * authenticatable packet must include a mac field, must
539 * have used key info_auth_keyid and must have included
540 * a time stamp in the appropriate field. The time stamp
541 * must be within INFO_TS_MAXSKEW of the receive
544 if (proc
->needs_auth
&& sys_authenticate
) {
548 if (rbufp
->recv_length
< (int)((REQ_LEN_HDR
+
549 (INFO_ITEMSIZE(inpkt
->mbz_itemsize
) *
550 INFO_NITEMS(inpkt
->err_nitems
))
551 + sizeof(struct req_pkt_tail
)))) {
552 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
554 tailinpkt
= (struct req_pkt_tail
*)((char *)&rbufp
->recv_pkt
+
555 rbufp
->recv_length
- sizeof(struct req_pkt_tail
));
558 * If this guy is restricted from doing this, don't let him
559 * If wrong key was used, or packet doesn't have mac, return.
561 if (!INFO_IS_AUTH(inpkt
->auth_seq
) || info_auth_keyid
== 0
562 || ntohl(tailinpkt
->keyid
) != info_auth_keyid
) {
565 printf("failed auth %d info_auth_keyid %lu pkt keyid %lu\n",
566 INFO_IS_AUTH(inpkt
->auth_seq
),
567 (u_long
)info_auth_keyid
,
568 (u_long
)ntohl(tailinpkt
->keyid
));
570 "process_private: failed auth %d info_auth_keyid %lu pkt keyid %lu\n",
571 INFO_IS_AUTH(inpkt
->auth_seq
),
572 (u_long
)info_auth_keyid
,
573 (u_long
)ntohl(tailinpkt
->keyid
));
575 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_AUTH
);
578 if (rbufp
->recv_length
> REQ_LEN_MAC
) {
581 printf("bad pkt length %d\n",
584 msyslog(LOG_ERR
, "process_private: bad pkt length %d",
586 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
589 if (!mod_okay
|| !authhavekey(info_auth_keyid
)) {
592 printf("failed auth mod_okay %d\n", mod_okay
);
594 "process_private: failed auth mod_okay %d\n",
597 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_AUTH
);
602 * calculate absolute time difference between xmit time stamp
603 * and receive time stamp. If too large, too bad.
605 NTOHL_FP(&tailinpkt
->tstamp
, &ftmp
);
606 L_SUB(&ftmp
, &rbufp
->recv_time
);
607 LFPTOD(&ftmp
, dtemp
);
608 if (fabs(dtemp
) >= INFO_TS_MAXSKEW
) {
610 * He's a loser. Tell him.
614 printf("xmit/rcv timestamp delta > INFO_TS_MAXSKEW\n");
616 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_AUTH
);
621 * So far so good. See if decryption works out okay.
623 if (!authdecrypt(info_auth_keyid
, (u_int32
*)inpkt
,
624 rbufp
->recv_length
- sizeof(struct req_pkt_tail
) +
625 REQ_LEN_HDR
, sizeof(struct req_pkt_tail
) - REQ_LEN_HDR
)) {
628 printf("authdecrypt failed\n");
630 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_AUTH
);
637 printf("process_private: all okay, into handler\n");
641 * Packet is okay. Call the handler to send him data.
643 (proc
->handler
)(srcadr
, inter
, inpkt
);
648 * peer_list - send a list of the peers
652 struct sockaddr_storage
*srcadr
,
653 struct interface
*inter
,
654 struct req_pkt
*inpkt
657 register struct info_peer_list
*ip
;
658 register struct peer
*pp
;
660 register int skip
= 0;
662 ip
= (struct info_peer_list
*)prepare_pkt(srcadr
, inter
, inpkt
,
663 v6sizeof(struct info_peer_list
));
664 for (i
= 0; i
< NTP_HASH_SIZE
&& ip
!= 0; i
++) {
666 while (pp
!= 0 && ip
!= 0) {
667 if (pp
->srcadr
.ss_family
== AF_INET6
) {
668 if (client_v6_capable
) {
669 ip
->addr6
= GET_INADDR6(pp
->srcadr
);
677 ip
->addr
= GET_INADDR(pp
->srcadr
);
678 if (client_v6_capable
)
684 ip
->port
= NSRCPORT(&pp
->srcadr
);
685 ip
->hmode
= pp
->hmode
;
687 if (pp
->flags
& FLAG_CONFIG
)
688 ip
->flags
|= INFO_FLAG_CONFIG
;
690 ip
->flags
|= INFO_FLAG_SYSPEER
;
691 if (pp
->status
== CTL_PST_SEL_SYNCCAND
)
692 ip
->flags
|= INFO_FLAG_SEL_CANDIDATE
;
693 if (pp
->status
>= CTL_PST_SEL_SYSPEER
)
694 ip
->flags
|= INFO_FLAG_SHORTLIST
;
695 ip
= (struct info_peer_list
*)more_pkt();
705 * peer_list_sum - return extended peer list
709 struct sockaddr_storage
*srcadr
,
710 struct interface
*inter
,
711 struct req_pkt
*inpkt
714 register struct info_peer_summary
*ips
;
715 register struct peer
*pp
;
722 printf("wants peer list summary\n");
724 ips
= (struct info_peer_summary
*)prepare_pkt(srcadr
, inter
, inpkt
,
725 v6sizeof(struct info_peer_summary
));
726 for (i
= 0; i
< NTP_HASH_SIZE
&& ips
!= 0; i
++) {
728 while (pp
!= 0 && ips
!= 0) {
731 printf("sum: got one\n");
734 * Be careful here not to return v6 peers when we
737 if (pp
->srcadr
.ss_family
== AF_INET6
) {
738 if (client_v6_capable
) {
739 ips
->srcadr6
= GET_INADDR6(pp
->srcadr
);
742 ips
->dstadr6
= GET_INADDR6(pp
->dstadr
->sin
);
744 memset(&ips
->dstadr6
, 0, sizeof(ips
->dstadr6
));
751 ips
->srcadr
= GET_INADDR(pp
->srcadr
);
752 if (client_v6_capable
)
754 /* XXX PDM This code is buggy. Need to replace with a straightforward assignment */
757 ips
->dstadr
= (pp
->processed
) ?
758 pp
->cast_flags
== MDF_BCAST
?
759 GET_INADDR(pp
->dstadr
->bcast
):
761 GET_INADDR(pp
->dstadr
->sin
) ?
762 GET_INADDR(pp
->dstadr
->sin
):
763 GET_INADDR(pp
->dstadr
->bcast
):
764 1 : GET_INADDR(pp
->dstadr
->sin
);
766 memset(&ips
->dstadr
, 0, sizeof(ips
->dstadr
));
772 ips
->srcport
= NSRCPORT(&pp
->srcadr
);
773 ips
->stratum
= pp
->stratum
;
774 ips
->hpoll
= pp
->hpoll
;
775 ips
->ppoll
= pp
->ppoll
;
776 ips
->reach
= pp
->reach
;
779 ips
->flags
|= INFO_FLAG_SYSPEER
;
780 if (pp
->flags
& FLAG_CONFIG
)
781 ips
->flags
|= INFO_FLAG_CONFIG
;
782 if (pp
->flags
& FLAG_REFCLOCK
)
783 ips
->flags
|= INFO_FLAG_REFCLOCK
;
784 if (pp
->flags
& FLAG_AUTHENABLE
)
785 ips
->flags
|= INFO_FLAG_AUTHENABLE
;
786 if (pp
->flags
& FLAG_PREFER
)
787 ips
->flags
|= INFO_FLAG_PREFER
;
788 if (pp
->flags
& FLAG_BURST
)
789 ips
->flags
|= INFO_FLAG_BURST
;
790 if (pp
->status
== CTL_PST_SEL_SYNCCAND
)
791 ips
->flags
|= INFO_FLAG_SEL_CANDIDATE
;
792 if (pp
->status
>= CTL_PST_SEL_SYSPEER
)
793 ips
->flags
|= INFO_FLAG_SHORTLIST
;
794 ips
->hmode
= pp
->hmode
;
795 ips
->delay
= HTONS_FP(DTOFP(pp
->delay
));
796 DTOLFP(pp
->offset
, <mp
);
797 HTONL_FP(<mp
, &ips
->offset
);
798 ips
->dispersion
= HTONS_FP(DTOUFP(SQRT(pp
->disp
)));
801 ips
= (struct info_peer_summary
*)more_pkt();
809 * peer_info - send information for one or more peers
813 struct sockaddr_storage
*srcadr
,
814 struct interface
*inter
,
815 struct req_pkt
*inpkt
818 register struct info_peer_list
*ipl
;
819 register struct peer
*pp
;
820 register struct info_peer
*ip
;
823 struct sockaddr_storage addr
;
824 extern struct peer
*sys_peer
;
827 memset((char *)&addr
, 0, sizeof addr
);
828 items
= INFO_NITEMS(inpkt
->err_nitems
);
829 ipl
= (struct info_peer_list
*) inpkt
->data
;
831 ip
= (struct info_peer
*)prepare_pkt(srcadr
, inter
, inpkt
,
832 v6sizeof(struct info_peer
));
833 while (items
-- > 0 && ip
!= 0) {
834 memset((char *)&addr
, 0, sizeof(addr
));
835 NSRCPORT(&addr
) = ipl
->port
;
836 if (client_v6_capable
&& ipl
->v6_flag
!= 0) {
837 addr
.ss_family
= AF_INET6
;
838 GET_INADDR6(addr
) = ipl
->addr6
;
840 addr
.ss_family
= AF_INET
;
841 GET_INADDR(addr
) = ipl
->addr
;
843 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
844 addr
.ss_len
= SOCKLEN(&addr
);
847 if ((pp
= findexistingpeer(&addr
, (struct peer
*)0, -1)) == 0)
849 if (pp
->srcadr
.ss_family
== AF_INET6
) {
851 ip
->dstadr6
= pp
->cast_flags
== MDF_BCAST
?
852 GET_INADDR6(pp
->dstadr
->bcast
) :
853 GET_INADDR6(pp
->dstadr
->sin
);
855 memset(&ip
->dstadr6
, 0, sizeof(ip
->dstadr6
));
857 ip
->srcadr6
= GET_INADDR6(pp
->srcadr
);
860 /* XXX PDM This code is buggy. Need to replace with a straightforward assignment */
862 ip
->dstadr
= (pp
->processed
) ?
863 pp
->cast_flags
== MDF_BCAST
?
864 GET_INADDR(pp
->dstadr
->bcast
):
866 GET_INADDR(pp
->dstadr
->sin
) ?
867 GET_INADDR(pp
->dstadr
->sin
):
868 GET_INADDR(pp
->dstadr
->bcast
):
869 2 : GET_INADDR(pp
->dstadr
->sin
);
871 memset(&ip
->dstadr
, 0, sizeof(ip
->dstadr
));
873 ip
->srcadr
= GET_INADDR(pp
->srcadr
);
874 if (client_v6_capable
)
877 ip
->srcport
= NSRCPORT(&pp
->srcadr
);
880 ip
->flags
|= INFO_FLAG_SYSPEER
;
881 if (pp
->flags
& FLAG_CONFIG
)
882 ip
->flags
|= INFO_FLAG_CONFIG
;
883 if (pp
->flags
& FLAG_REFCLOCK
)
884 ip
->flags
|= INFO_FLAG_REFCLOCK
;
885 if (pp
->flags
& FLAG_AUTHENABLE
)
886 ip
->flags
|= INFO_FLAG_AUTHENABLE
;
887 if (pp
->flags
& FLAG_PREFER
)
888 ip
->flags
|= INFO_FLAG_PREFER
;
889 if (pp
->flags
& FLAG_BURST
)
890 ip
->flags
|= INFO_FLAG_BURST
;
891 if (pp
->status
== CTL_PST_SEL_SYNCCAND
)
892 ip
->flags
|= INFO_FLAG_SEL_CANDIDATE
;
893 if (pp
->status
>= CTL_PST_SEL_SYSPEER
)
894 ip
->flags
|= INFO_FLAG_SHORTLIST
;
896 ip
->hmode
= pp
->hmode
;
897 ip
->keyid
= pp
->keyid
;
898 ip
->stratum
= pp
->stratum
;
899 ip
->ppoll
= pp
->ppoll
;
900 ip
->hpoll
= pp
->hpoll
;
901 ip
->precision
= pp
->precision
;
902 ip
->version
= pp
->version
;
903 ip
->reach
= pp
->reach
;
904 ip
->unreach
= (u_char
) pp
->unreach
;
905 ip
->flash
= (u_char
)pp
->flash
;
906 ip
->flash2
= (u_short
) pp
->flash
;
907 ip
->estbdelay
= HTONS_FP(DTOFP(pp
->estbdelay
));
909 ip
->associd
= htons(pp
->associd
);
910 ip
->rootdelay
= HTONS_FP(DTOUFP(pp
->rootdelay
));
911 ip
->rootdispersion
= HTONS_FP(DTOUFP(pp
->rootdispersion
));
912 ip
->refid
= pp
->refid
;
913 HTONL_FP(&pp
->reftime
, &ip
->reftime
);
914 HTONL_FP(&pp
->org
, &ip
->org
);
915 HTONL_FP(&pp
->rec
, &ip
->rec
);
916 HTONL_FP(&pp
->xmt
, &ip
->xmt
);
917 j
= pp
->filter_nextpt
- 1;
918 for (i
= 0; i
< NTP_SHIFT
; i
++, j
--) {
921 ip
->filtdelay
[i
] = HTONS_FP(DTOFP(pp
->filter_delay
[j
]));
922 DTOLFP(pp
->filter_offset
[j
], <mp
);
923 HTONL_FP(<mp
, &ip
->filtoffset
[i
]);
924 ip
->order
[i
] = (u_char
)((pp
->filter_nextpt
+NTP_SHIFT
-1)
925 - pp
->filter_order
[i
]);
926 if (ip
->order
[i
] >= NTP_SHIFT
)
927 ip
->order
[i
] -= NTP_SHIFT
;
929 DTOLFP(pp
->offset
, <mp
);
930 HTONL_FP(<mp
, &ip
->offset
);
931 ip
->delay
= HTONS_FP(DTOFP(pp
->delay
));
932 ip
->dispersion
= HTONS_FP(DTOUFP(SQRT(pp
->disp
)));
933 ip
->selectdisp
= HTONS_FP(DTOUFP(SQRT(pp
->jitter
)));
934 ip
= (struct info_peer
*)more_pkt();
941 * peer_stats - send statistics for one or more peers
945 struct sockaddr_storage
*srcadr
,
946 struct interface
*inter
,
947 struct req_pkt
*inpkt
950 register struct info_peer_list
*ipl
;
951 register struct peer
*pp
;
952 register struct info_peer_stats
*ip
;
954 struct sockaddr_storage addr
;
955 extern struct peer
*sys_peer
;
959 printf("peer_stats: called\n");
961 items
= INFO_NITEMS(inpkt
->err_nitems
);
962 ipl
= (struct info_peer_list
*) inpkt
->data
;
963 ip
= (struct info_peer_stats
*)prepare_pkt(srcadr
, inter
, inpkt
,
964 v6sizeof(struct info_peer_stats
));
965 while (items
-- > 0 && ip
!= 0) {
966 memset((char *)&addr
, 0, sizeof(addr
));
967 NSRCPORT(&addr
) = ipl
->port
;
968 if (client_v6_capable
&& ipl
->v6_flag
) {
969 addr
.ss_family
= AF_INET6
;
970 GET_INADDR6(addr
) = ipl
->addr6
;
972 addr
.ss_family
= AF_INET
;
973 GET_INADDR(addr
) = ipl
->addr
;
975 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
976 addr
.ss_len
= SOCKLEN(&addr
);
980 printf("peer_stats: looking for %s, %d, %d\n", stoa(&addr
),
981 ipl
->port
, ((struct sockaddr_in6
*)&addr
)->sin6_port
);
983 ipl
= (struct info_peer_list
*)((char *)ipl
+
984 INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
986 if ((pp
= findexistingpeer(&addr
, (struct peer
*)0, -1)) == 0)
990 printf("peer_stats: found %s\n", stoa(&addr
));
992 if (pp
->srcadr
.ss_family
== AF_INET
) {
994 ip
->dstadr
= (pp
->processed
) ?
995 pp
->cast_flags
== MDF_BCAST
?
996 GET_INADDR(pp
->dstadr
->bcast
):
998 GET_INADDR(pp
->dstadr
->sin
) ?
999 GET_INADDR(pp
->dstadr
->sin
):
1000 GET_INADDR(pp
->dstadr
->bcast
):
1003 memset(&ip
->dstadr
, 0, sizeof(ip
->dstadr
));
1005 ip
->srcadr
= GET_INADDR(pp
->srcadr
);
1006 if (client_v6_capable
)
1010 ip
->dstadr6
= pp
->cast_flags
== MDF_BCAST
?
1011 GET_INADDR6(pp
->dstadr
->bcast
):
1012 GET_INADDR6(pp
->dstadr
->sin
);
1014 memset(&ip
->dstadr6
, 0, sizeof(ip
->dstadr6
));
1016 ip
->srcadr6
= GET_INADDR6(pp
->srcadr
);
1019 ip
->srcport
= NSRCPORT(&pp
->srcadr
);
1022 ip
->flags
|= INFO_FLAG_SYSPEER
;
1023 if (pp
->flags
& FLAG_CONFIG
)
1024 ip
->flags
|= INFO_FLAG_CONFIG
;
1025 if (pp
->flags
& FLAG_REFCLOCK
)
1026 ip
->flags
|= INFO_FLAG_REFCLOCK
;
1027 if (pp
->flags
& FLAG_AUTHENABLE
)
1028 ip
->flags
|= INFO_FLAG_AUTHENABLE
;
1029 if (pp
->flags
& FLAG_PREFER
)
1030 ip
->flags
|= INFO_FLAG_PREFER
;
1031 if (pp
->flags
& FLAG_BURST
)
1032 ip
->flags
|= INFO_FLAG_BURST
;
1033 if (pp
->flags
& FLAG_IBURST
)
1034 ip
->flags
|= INFO_FLAG_IBURST
;
1035 if (pp
->status
== CTL_PST_SEL_SYNCCAND
)
1036 ip
->flags
|= INFO_FLAG_SEL_CANDIDATE
;
1037 if (pp
->status
>= CTL_PST_SEL_SYSPEER
)
1038 ip
->flags
|= INFO_FLAG_SHORTLIST
;
1039 ip
->flags
= htons(ip
->flags
);
1040 ip
->timereceived
= htonl((u_int32
)(current_time
- pp
->timereceived
));
1041 ip
->timetosend
= htonl(pp
->nextdate
- current_time
);
1042 ip
->timereachable
= htonl((u_int32
)(current_time
- pp
->timereachable
));
1043 ip
->sent
= htonl((u_int32
)(pp
->sent
));
1044 ip
->processed
= htonl((u_int32
)(pp
->processed
));
1045 ip
->badauth
= htonl((u_int32
)(pp
->badauth
));
1046 ip
->bogusorg
= htonl((u_int32
)(pp
->bogusorg
));
1047 ip
->oldpkt
= htonl((u_int32
)(pp
->oldpkt
));
1048 ip
->seldisp
= htonl((u_int32
)(pp
->seldisptoolarge
));
1049 ip
->selbroken
= htonl((u_int32
)(pp
->selbroken
));
1050 ip
->candidate
= pp
->status
;
1051 ip
= (struct info_peer_stats
*)more_pkt();
1058 * sys_info - return system info
1062 struct sockaddr_storage
*srcadr
,
1063 struct interface
*inter
,
1064 struct req_pkt
*inpkt
1067 register struct info_sys
*is
;
1069 is
= (struct info_sys
*)prepare_pkt(srcadr
, inter
, inpkt
,
1070 v6sizeof(struct info_sys
));
1072 if (sys_peer
!= 0) {
1073 if (sys_peer
->srcadr
.ss_family
== AF_INET
) {
1074 is
->peer
= GET_INADDR(sys_peer
->srcadr
);
1075 if (client_v6_capable
)
1077 } else if (client_v6_capable
) {
1078 is
->peer6
= GET_INADDR6(sys_peer
->srcadr
);
1081 is
->peer_mode
= sys_peer
->hmode
;
1084 if (client_v6_capable
) {
1090 is
->leap
= sys_leap
;
1091 is
->stratum
= sys_stratum
;
1092 is
->precision
= sys_precision
;
1093 is
->rootdelay
= htonl(DTOFP(sys_rootdelay
));
1094 is
->rootdispersion
= htonl(DTOUFP(sys_rootdispersion
));
1095 is
->frequency
= htonl(DTOFP(sys_jitter
));
1096 is
->stability
= htonl(DTOUFP(clock_stability
));
1097 is
->refid
= sys_refid
;
1098 HTONL_FP(&sys_reftime
, &is
->reftime
);
1100 is
->poll
= sys_poll
;
1103 if (sys_authenticate
)
1104 is
->flags
|= INFO_FLAG_AUTHENTICATE
;
1106 is
->flags
|= INFO_FLAG_BCLIENT
;
1109 is
->flags
|= INFO_FLAG_CAL
;
1110 #endif /* REFCLOCK */
1112 is
->flags
|= INFO_FLAG_KERNEL
;
1113 if (mon_enabled
!= MON_OFF
)
1114 is
->flags
|= INFO_FLAG_MONITOR
;
1116 is
->flags
|= INFO_FLAG_NTP
;
1118 is
->flags
|= INFO_FLAG_PPS_SYNC
;
1120 is
->flags
|= INFO_FLAG_FILEGEN
;
1121 is
->bdelay
= HTONS_FP(DTOFP(sys_bdelay
));
1122 HTONL_UF(sys_authdelay
.l_f
, &is
->authdelay
);
1130 * sys_stats - return system statistics
1134 struct sockaddr_storage
*srcadr
,
1135 struct interface
*inter
,
1136 struct req_pkt
*inpkt
1139 register struct info_sys_stats
*ss
;
1142 * Importations from the protocol module
1144 ss
= (struct info_sys_stats
*)prepare_pkt(srcadr
, inter
, inpkt
,
1145 sizeof(struct info_sys_stats
));
1146 ss
->timeup
= htonl((u_int32
)current_time
);
1147 ss
->timereset
= htonl((u_int32
)(current_time
- sys_stattime
));
1148 ss
->denied
= htonl((u_int32
)sys_restricted
);
1149 ss
->oldversionpkt
= htonl((u_int32
)sys_oldversionpkt
);
1150 ss
->newversionpkt
= htonl((u_int32
)sys_newversionpkt
);
1151 ss
->unknownversion
= htonl((u_int32
)sys_unknownversion
);
1152 ss
->badlength
= htonl((u_int32
)sys_badlength
);
1153 ss
->processed
= htonl((u_int32
)sys_processed
);
1154 ss
->badauth
= htonl((u_int32
)sys_badauth
);
1155 ss
->limitrejected
= htonl((u_int32
)sys_limitrejected
);
1156 ss
->received
= htonl((u_int32
)sys_received
);
1163 * mem_stats - return memory statistics
1167 struct sockaddr_storage
*srcadr
,
1168 struct interface
*inter
,
1169 struct req_pkt
*inpkt
1172 register struct info_mem_stats
*ms
;
1176 * Importations from the peer module
1178 extern int peer_hash_count
[];
1179 extern int peer_free_count
;
1180 extern u_long peer_timereset
;
1181 extern u_long findpeer_calls
;
1182 extern u_long peer_allocations
;
1183 extern u_long peer_demobilizations
;
1184 extern int total_peer_structs
;
1186 ms
= (struct info_mem_stats
*)prepare_pkt(srcadr
, inter
, inpkt
,
1187 sizeof(struct info_mem_stats
));
1189 ms
->timereset
= htonl((u_int32
)(current_time
- peer_timereset
));
1190 ms
->totalpeermem
= htons((u_short
)total_peer_structs
);
1191 ms
->freepeermem
= htons((u_short
)peer_free_count
);
1192 ms
->findpeer_calls
= htonl((u_int32
)findpeer_calls
);
1193 ms
->allocations
= htonl((u_int32
)peer_allocations
);
1194 ms
->demobilizations
= htonl((u_int32
)peer_demobilizations
);
1196 for (i
= 0; i
< NTP_HASH_SIZE
; i
++) {
1197 if (peer_hash_count
[i
] > 255)
1198 ms
->hashcount
[i
] = 255;
1200 ms
->hashcount
[i
] = (u_char
)peer_hash_count
[i
];
1209 * io_stats - return io statistics
1213 struct sockaddr_storage
*srcadr
,
1214 struct interface
*inter
,
1215 struct req_pkt
*inpkt
1218 register struct info_io_stats
*io
;
1221 * Importations from the io module
1223 extern u_long io_timereset
;
1225 io
= (struct info_io_stats
*)prepare_pkt(srcadr
, inter
, inpkt
,
1226 sizeof(struct info_io_stats
));
1228 io
->timereset
= htonl((u_int32
)(current_time
- io_timereset
));
1229 io
->totalrecvbufs
= htons((u_short
) total_recvbuffs());
1230 io
->freerecvbufs
= htons((u_short
) free_recvbuffs());
1231 io
->fullrecvbufs
= htons((u_short
) full_recvbuffs());
1232 io
->lowwater
= htons((u_short
) lowater_additions());
1233 io
->dropped
= htonl((u_int32
)packets_dropped
);
1234 io
->ignored
= htonl((u_int32
)packets_ignored
);
1235 io
->received
= htonl((u_int32
)packets_received
);
1236 io
->sent
= htonl((u_int32
)packets_sent
);
1237 io
->notsent
= htonl((u_int32
)packets_notsent
);
1238 io
->interrupts
= htonl((u_int32
)handler_calls
);
1239 io
->int_received
= htonl((u_int32
)handler_pkts
);
1247 * timer_stats - return timer statistics
1251 struct sockaddr_storage
*srcadr
,
1252 struct interface
*inter
,
1253 struct req_pkt
*inpkt
1256 register struct info_timer_stats
*ts
;
1259 * Importations from the timer module
1261 extern u_long timer_timereset
;
1262 extern u_long timer_overflows
;
1263 extern u_long timer_xmtcalls
;
1265 ts
= (struct info_timer_stats
*)prepare_pkt(srcadr
, inter
, inpkt
,
1266 sizeof(struct info_timer_stats
));
1268 ts
->timereset
= htonl((u_int32
)(current_time
- timer_timereset
));
1269 ts
->alarms
= htonl((u_int32
)alarm_overflow
);
1270 ts
->overflows
= htonl((u_int32
)timer_overflows
);
1271 ts
->xmtcalls
= htonl((u_int32
)timer_xmtcalls
);
1279 * loop_info - return the current state of the loop filter
1283 struct sockaddr_storage
*srcadr
,
1284 struct interface
*inter
,
1285 struct req_pkt
*inpkt
1288 register struct info_loop
*li
;
1292 * Importations from the loop filter module
1294 extern double last_offset
;
1295 extern double drift_comp
;
1296 extern int tc_counter
;
1297 extern u_long sys_clocktime
;
1299 li
= (struct info_loop
*)prepare_pkt(srcadr
, inter
, inpkt
,
1300 sizeof(struct info_loop
));
1302 DTOLFP(last_offset
, <mp
);
1303 HTONL_FP(<mp
, &li
->last_offset
);
1304 DTOLFP(drift_comp
* 1e6
, <mp
);
1305 HTONL_FP(<mp
, &li
->drift_comp
);
1306 li
->compliance
= htonl((u_int32
)(tc_counter
));
1307 li
->watchdog_timer
= htonl((u_int32
)(current_time
- sys_clocktime
));
1315 * do_conf - add a peer to the configuration list
1319 struct sockaddr_storage
*srcadr
,
1320 struct interface
*inter
,
1321 struct req_pkt
*inpkt
1324 static u_long soonest_ifrescan_time
= 0;
1327 struct conf_peer
*cp
;
1328 struct conf_peer temp_cp
;
1329 struct sockaddr_storage peeraddr
;
1330 struct sockaddr_in tmp_clock
;
1333 * Do a check of everything to see that it looks
1334 * okay. If not, complain about it. Note we are
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 while (items
-- > 0 && !fl
) {
1343 if (((temp_cp
.version
) > NTP_VERSION
)
1344 || ((temp_cp
.version
) < NTP_OLDVERSION
))
1346 if (temp_cp
.hmode
!= MODE_ACTIVE
1347 && temp_cp
.hmode
!= MODE_CLIENT
1348 && temp_cp
.hmode
!= MODE_BROADCAST
)
1350 if (temp_cp
.flags
& ~(CONF_FLAG_AUTHENABLE
| CONF_FLAG_PREFER
1351 | CONF_FLAG_BURST
| CONF_FLAG_IBURST
| CONF_FLAG_SKEY
))
1353 cp
= (struct conf_peer
*)
1354 ((char *)cp
+ INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1358 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
1363 * Looks okay, try it out
1365 items
= INFO_NITEMS(inpkt
->err_nitems
);
1366 cp
= (struct conf_peer
*)inpkt
->data
;
1368 while (items
-- > 0) {
1369 memset(&temp_cp
, 0, sizeof(struct conf_peer
));
1370 memcpy(&temp_cp
, (char *)cp
, INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1371 memset((char *)&peeraddr
, 0, sizeof(struct sockaddr_storage
));
1374 if (temp_cp
.flags
& CONF_FLAG_AUTHENABLE
)
1375 fl
|= FLAG_AUTHENABLE
;
1376 if (temp_cp
.flags
& CONF_FLAG_PREFER
)
1378 if (temp_cp
.flags
& CONF_FLAG_BURST
)
1380 if (temp_cp
.flags
& CONF_FLAG_IBURST
)
1382 if (temp_cp
.flags
& CONF_FLAG_SKEY
)
1385 if (client_v6_capable
&& temp_cp
.v6_flag
!= 0) {
1386 peeraddr
.ss_family
= AF_INET6
;
1387 GET_INADDR6(peeraddr
) = temp_cp
.peeraddr6
;
1389 peeraddr
.ss_family
= AF_INET
;
1390 GET_INADDR(peeraddr
) = temp_cp
.peeraddr
;
1392 * Make sure the address is valid
1394 tmp_clock
= *CAST_V4(peeraddr
);
1397 !ISREFCLOCKADR(&tmp_clock
) &&
1399 ISBADADR(&tmp_clock
)) {
1400 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
1405 NSRCPORT(&peeraddr
) = htons(NTP_PORT
);
1406 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
1407 peeraddr
.ss_len
= SOCKLEN(&peeraddr
);
1410 /* XXX W2DO? minpoll/maxpoll arguments ??? */
1411 if (peer_config(&peeraddr
, (struct interface
*)0,
1412 temp_cp
.hmode
, temp_cp
.version
, temp_cp
.minpoll
,
1413 temp_cp
.maxpoll
, fl
, temp_cp
.ttl
, temp_cp
.keyid
,
1415 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
1420 * ntp_intres.c uses REQ_CONFIG/doconf() to add each
1421 * server after its name is resolved. If we have been
1422 * disconnected from the network, it may notice the
1423 * network has returned and add the first server while
1424 * the relevant interface is still disabled, awaiting
1425 * the next interface rescan. To get things moving
1426 * more quickly, trigger an interface scan now, except
1427 * if we have done so in the last half minute.
1429 if (soonest_ifrescan_time
< current_time
) {
1430 soonest_ifrescan_time
= current_time
+ 30;
1431 timer_interfacetimeout(current_time
);
1432 DPRINTF(1, ("do_conf triggering interface rescan\n"));
1435 cp
= (struct conf_peer
*)
1436 ((char *)cp
+ INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1439 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
1445 * dns_a - Snarf DNS info for an association ID
1449 struct sockaddr_storage
*srcadr
,
1450 struct interface
*inter
,
1451 struct req_pkt
*inpkt
1454 register struct info_dns_assoc
*dp
;
1456 struct sockaddr_in peeraddr
;
1459 * Do a check of everything to see that it looks
1460 * okay. If not, complain about it. Note we are
1463 items
= INFO_NITEMS(inpkt
->err_nitems
);
1464 dp
= (struct info_dns_assoc
*)inpkt
->data
;
1467 * Looks okay, try it out
1469 items
= INFO_NITEMS(inpkt
->err_nitems
);
1470 dp
= (struct info_dns_assoc
*)inpkt
->data
;
1471 memset((char *)&peeraddr
, 0, sizeof(struct sockaddr_in
));
1472 peeraddr
.sin_family
= AF_INET
;
1473 peeraddr
.sin_port
= htons(NTP_PORT
);
1476 * Make sure the address is valid
1480 !ISREFCLOCKADR(&peeraddr
) &&
1482 ISBADADR(&peeraddr
)) {
1484 msyslog(LOG_ERR
, "dns_a: !ISREFCLOCK && ISBADADR");
1486 msyslog(LOG_ERR
, "dns_a: ISBADADR");
1488 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
1492 while (items
-- > 0) {
1498 associd
= dp
->associd
;
1499 peer
= findpeerbyassoc(associd
);
1500 if (peer
== 0 || peer
->flags
& FLAG_REFCLOCK
) {
1501 msyslog(LOG_ERR
, "dns_a: %s",
1504 : "peer->flags & FLAG_REFCLOCK");
1507 peeraddr
.sin_addr
.s_addr
= dp
->peeraddr
;
1508 for (hnl
= 0; dp
->hostname
[hnl
] && hnl
< sizeof dp
->hostname
; ++hnl
) ;
1509 if (hnl
>= sizeof dp
->hostname
) {
1510 msyslog(LOG_ERR
, "dns_a: hnl (%ld) >= %ld",
1511 (long)hnl
, (long)sizeof dp
->hostname
);
1515 msyslog(LOG_INFO
, "dns_a: <%s> for %s, AssocID %d, bogon %d",
1517 stoa((struct sockaddr_storage
*)&peeraddr
), associd
,
1521 /* If it didn't work */
1522 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
1527 crypto_public(peer
, dp
->hostname
);
1535 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
1540 * do_unconf - remove a peer from the configuration list
1544 struct sockaddr_storage
*srcadr
,
1545 struct interface
*inter
,
1546 struct req_pkt
*inpkt
1549 register struct conf_unpeer
*cp
;
1550 struct conf_unpeer temp_cp
;
1552 register struct peer
*peer
;
1553 struct sockaddr_storage peeraddr
;
1557 * This is a bit unstructured, but I like to be careful.
1558 * We check to see that every peer exists and is actually
1559 * configured. If so, we remove them. If not, we return
1562 items
= INFO_NITEMS(inpkt
->err_nitems
);
1563 cp
= (struct conf_unpeer
*)inpkt
->data
;
1566 while (items
-- > 0 && !bad
) {
1567 memset(&temp_cp
, 0, sizeof(temp_cp
));
1568 memset(&peeraddr
, 0, sizeof(peeraddr
));
1569 memcpy(&temp_cp
, cp
, INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1570 if (client_v6_capable
&& temp_cp
.v6_flag
!= 0) {
1571 peeraddr
.ss_family
= AF_INET6
;
1572 GET_INADDR6(peeraddr
) = temp_cp
.peeraddr6
;
1574 peeraddr
.ss_family
= AF_INET
;
1575 GET_INADDR(peeraddr
) = temp_cp
.peeraddr
;
1577 NSRCPORT(&peeraddr
) = htons(NTP_PORT
);
1578 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
1579 peeraddr
.ss_len
= SOCKLEN(&peeraddr
);
1582 peer
= (struct peer
*)0;
1585 printf("searching for %s\n", stoa(&peeraddr
));
1588 peer
= findexistingpeer(&peeraddr
, peer
, -1);
1589 if (peer
== (struct peer
*)0)
1591 if (peer
->flags
& FLAG_CONFIG
)
1596 cp
= (struct conf_unpeer
*)
1597 ((char *)cp
+ INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1601 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
1606 * Now do it in earnest.
1609 items
= INFO_NITEMS(inpkt
->err_nitems
);
1610 cp
= (struct conf_unpeer
*)inpkt
->data
;
1611 while (items
-- > 0) {
1612 memset(&temp_cp
, 0, sizeof(temp_cp
));
1613 memset(&peeraddr
, 0, sizeof(peeraddr
));
1614 memcpy(&temp_cp
, cp
, INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1615 if (client_v6_capable
&& temp_cp
.v6_flag
!= 0) {
1616 peeraddr
.ss_family
= AF_INET6
;
1617 GET_INADDR6(peeraddr
) = temp_cp
.peeraddr6
;
1619 peeraddr
.ss_family
= AF_INET
;
1620 GET_INADDR(peeraddr
) = temp_cp
.peeraddr
;
1622 NSRCPORT(&peeraddr
) = htons(NTP_PORT
);
1623 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
1624 peeraddr
.ss_len
= SOCKLEN(&peeraddr
);
1626 peer_unconfig(&peeraddr
, (struct interface
*)0, -1);
1627 cp
= (struct conf_unpeer
*)
1628 ((char *)cp
+ INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1631 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
1636 * set_sys_flag - set system flags
1640 struct sockaddr_storage
*srcadr
,
1641 struct interface
*inter
,
1642 struct req_pkt
*inpkt
1645 setclr_flags(srcadr
, inter
, inpkt
, 1);
1650 * clr_sys_flag - clear system flags
1654 struct sockaddr_storage
*srcadr
,
1655 struct interface
*inter
,
1656 struct req_pkt
*inpkt
1659 setclr_flags(srcadr
, inter
, inpkt
, 0);
1664 * setclr_flags - do the grunge work of flag setting/clearing
1668 struct sockaddr_storage
*srcadr
,
1669 struct interface
*inter
,
1670 struct req_pkt
*inpkt
,
1674 register u_int flags
;
1675 int prev_kern_enable
;
1677 prev_kern_enable
= kern_enable
;
1678 if (INFO_NITEMS(inpkt
->err_nitems
) > 1) {
1679 msyslog(LOG_ERR
, "setclr_flags: err_nitems > 1");
1680 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
1684 flags
= ((struct conf_sys_flags
*)inpkt
->data
)->flags
;
1685 flags
= ntohl(flags
);
1687 if (flags
& ~(SYS_FLAG_BCLIENT
| SYS_FLAG_PPS
|
1688 SYS_FLAG_NTP
| SYS_FLAG_KERNEL
| SYS_FLAG_MONITOR
|
1689 SYS_FLAG_FILEGEN
| SYS_FLAG_AUTH
| SYS_FLAG_CAL
)) {
1690 msyslog(LOG_ERR
, "setclr_flags: extra flags: %#x",
1691 flags
& ~(SYS_FLAG_BCLIENT
| SYS_FLAG_PPS
|
1692 SYS_FLAG_NTP
| SYS_FLAG_KERNEL
|
1693 SYS_FLAG_MONITOR
| SYS_FLAG_FILEGEN
|
1694 SYS_FLAG_AUTH
| SYS_FLAG_CAL
));
1695 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
1699 if (flags
& SYS_FLAG_BCLIENT
)
1700 proto_config(PROTO_BROADCLIENT
, set
, 0., NULL
);
1701 if (flags
& SYS_FLAG_PPS
)
1702 proto_config(PROTO_PPS
, set
, 0., NULL
);
1703 if (flags
& SYS_FLAG_NTP
)
1704 proto_config(PROTO_NTP
, set
, 0., NULL
);
1705 if (flags
& SYS_FLAG_KERNEL
)
1706 proto_config(PROTO_KERNEL
, set
, 0., NULL
);
1707 if (flags
& SYS_FLAG_MONITOR
)
1708 proto_config(PROTO_MONITOR
, set
, 0., NULL
);
1709 if (flags
& SYS_FLAG_FILEGEN
)
1710 proto_config(PROTO_FILEGEN
, set
, 0., NULL
);
1711 if (flags
& SYS_FLAG_AUTH
)
1712 proto_config(PROTO_AUTHENTICATE
, set
, 0., NULL
);
1713 if (flags
& SYS_FLAG_CAL
)
1714 proto_config(PROTO_CAL
, set
, 0., NULL
);
1715 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
1717 /* Reset the kernel ntp parameters if the kernel flag changed. */
1718 if (prev_kern_enable
&& !kern_enable
)
1719 loop_config(LOOP_KERN_CLEAR
, 0.0);
1720 if (!prev_kern_enable
&& kern_enable
)
1721 loop_config(LOOP_DRIFTCOMP
, drift_comp
);
1726 * list_restrict - return the restrict list
1730 struct sockaddr_storage
*srcadr
,
1731 struct interface
*inter
,
1732 struct req_pkt
*inpkt
1735 register struct info_restrict
*ir
;
1736 register struct restrictlist
*rl
;
1737 register struct restrictlist6
*rl6
;
1741 printf("wants restrict list summary\n");
1744 ir
= (struct info_restrict
*)prepare_pkt(srcadr
, inter
, inpkt
,
1745 v6sizeof(struct info_restrict
));
1747 for (rl
= restrictlist
; rl
!= 0 && ir
!= 0; rl
= rl
->next
) {
1748 ir
->addr
= htonl(rl
->addr
);
1749 if (client_v6_capable
)
1751 ir
->mask
= htonl(rl
->mask
);
1752 ir
->count
= htonl((u_int32
)rl
->count
);
1753 ir
->flags
= htons(rl
->flags
);
1754 ir
->mflags
= htons(rl
->mflags
);
1755 ir
= (struct info_restrict
*)more_pkt();
1757 if (client_v6_capable
)
1758 for (rl6
= restrictlist6
; rl6
!= 0 && ir
!= 0; rl6
= rl6
->next
) {
1759 ir
->addr6
= rl6
->addr6
;
1760 ir
->mask6
= rl6
->mask6
;
1762 ir
->count
= htonl((u_int32
)rl6
->count
);
1763 ir
->flags
= htons(rl6
->flags
);
1764 ir
->mflags
= htons(rl6
->mflags
);
1765 ir
= (struct info_restrict
*)more_pkt();
1773 * do_resaddflags - add flags to a restrict entry (or create one)
1777 struct sockaddr_storage
*srcadr
,
1778 struct interface
*inter
,
1779 struct req_pkt
*inpkt
1782 do_restrict(srcadr
, inter
, inpkt
, RESTRICT_FLAGS
);
1788 * do_ressubflags - remove flags from a restrict entry
1792 struct sockaddr_storage
*srcadr
,
1793 struct interface
*inter
,
1794 struct req_pkt
*inpkt
1797 do_restrict(srcadr
, inter
, inpkt
, RESTRICT_UNFLAG
);
1802 * do_unrestrict - remove a restrict entry from the list
1806 struct sockaddr_storage
*srcadr
,
1807 struct interface
*inter
,
1808 struct req_pkt
*inpkt
1811 do_restrict(srcadr
, inter
, inpkt
, RESTRICT_REMOVE
);
1819 * do_restrict - do the dirty stuff of dealing with restrictions
1823 struct sockaddr_storage
*srcadr
,
1824 struct interface
*inter
,
1825 struct req_pkt
*inpkt
,
1829 register struct conf_restrict
*cr
;
1831 struct sockaddr_storage matchaddr
;
1832 struct sockaddr_storage matchmask
;
1836 * Do a check of the flags to make sure that only
1837 * the NTPPORT flag is set, if any. If not, complain
1838 * about it. Note we are very picky here.
1840 items
= INFO_NITEMS(inpkt
->err_nitems
);
1841 cr
= (struct conf_restrict
*)inpkt
->data
;
1844 cr
->flags
= ntohs(cr
->flags
);
1845 cr
->mflags
= ntohs(cr
->mflags
);
1846 while (items
-- > 0 && !bad
) {
1847 if (cr
->mflags
& ~(RESM_NTPONLY
))
1849 if (cr
->flags
& ~(RES_ALLFLAGS
))
1851 if (cr
->mask
!= htonl(INADDR_ANY
)) {
1852 if (client_v6_capable
&& cr
->v6_flag
!= 0) {
1853 if (IN6_IS_ADDR_UNSPECIFIED(&cr
->addr6
))
1856 if (cr
->addr
== htonl(INADDR_ANY
))
1859 cr
= (struct conf_restrict
*)((char *)cr
+
1860 INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1864 msyslog(LOG_ERR
, "do_restrict: bad = %#x", bad
);
1865 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
1870 * Looks okay, try it out
1872 items
= INFO_NITEMS(inpkt
->err_nitems
);
1873 cr
= (struct conf_restrict
*)inpkt
->data
;
1874 memset((char *)&matchaddr
, 0, sizeof(struct sockaddr_storage
));
1875 memset((char *)&matchmask
, 0, sizeof(struct sockaddr_storage
));
1877 while (items
-- > 0) {
1878 if (client_v6_capable
&& cr
->v6_flag
!= 0) {
1879 GET_INADDR6(matchaddr
) = cr
->addr6
;
1880 GET_INADDR6(matchmask
) = cr
->mask6
;
1881 matchaddr
.ss_family
= AF_INET6
;
1882 matchmask
.ss_family
= AF_INET6
;
1884 GET_INADDR(matchaddr
) = cr
->addr
;
1885 GET_INADDR(matchmask
) = cr
->mask
;
1886 matchaddr
.ss_family
= AF_INET
;
1887 matchmask
.ss_family
= AF_INET
;
1889 hack_restrict(op
, &matchaddr
, &matchmask
, cr
->mflags
,
1894 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
1899 * mon_getlist - return monitor data
1903 struct sockaddr_storage
*srcadr
,
1904 struct interface
*inter
,
1905 struct req_pkt
*inpkt
1908 register struct info_monitor
*im
;
1909 register struct mon_data
*md
;
1910 extern struct mon_data mon_mru_list
;
1911 extern int mon_enabled
;
1915 printf("wants monitor 0 list\n");
1918 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
1921 im
= (struct info_monitor
*)prepare_pkt(srcadr
, inter
, inpkt
,
1922 v6sizeof(struct info_monitor
));
1923 for (md
= mon_mru_list
.mru_next
; md
!= &mon_mru_list
&& im
!= 0;
1924 md
= md
->mru_next
) {
1925 im
->lasttime
= htonl((u_int32
)md
->avg_interval
);
1926 im
->firsttime
= htonl((u_int32
)(current_time
- md
->lasttime
));
1927 im
->lastdrop
= htonl((u_int32
)md
->drop_count
);
1928 im
->count
= htonl((u_int32
)(md
->count
));
1929 if (md
->rmtadr
.ss_family
== AF_INET6
) {
1930 if (!client_v6_capable
)
1932 im
->addr6
= GET_INADDR6(md
->rmtadr
);
1935 im
->addr
= GET_INADDR(md
->rmtadr
);
1936 if (client_v6_capable
)
1939 im
->port
= md
->rmtport
;
1940 im
->mode
= md
->mode
;
1941 im
->version
= md
->version
;
1942 im
= (struct info_monitor
*)more_pkt();
1948 * mon_getlist - return monitor data
1952 struct sockaddr_storage
*srcadr
,
1953 struct interface
*inter
,
1954 struct req_pkt
*inpkt
1957 register struct info_monitor_1
*im
;
1958 register struct mon_data
*md
;
1959 extern struct mon_data mon_mru_list
;
1960 extern int mon_enabled
;
1963 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
1966 im
= (struct info_monitor_1
*)prepare_pkt(srcadr
, inter
, inpkt
,
1967 v6sizeof(struct info_monitor_1
));
1968 for (md
= mon_mru_list
.mru_next
; md
!= &mon_mru_list
&& im
!= 0;
1969 md
= md
->mru_next
) {
1970 im
->lasttime
= htonl((u_int32
)md
->avg_interval
);
1971 im
->firsttime
= htonl((u_int32
)(current_time
- md
->lasttime
));
1972 im
->lastdrop
= htonl((u_int32
)md
->drop_count
);
1973 im
->count
= htonl((u_int32
)md
->count
);
1974 if (md
->rmtadr
.ss_family
== AF_INET6
) {
1975 if (!client_v6_capable
)
1977 im
->addr6
= GET_INADDR6(md
->rmtadr
);
1979 im
->daddr6
= GET_INADDR6(md
->interface
->sin
);
1981 im
->addr
= GET_INADDR(md
->rmtadr
);
1982 if (client_v6_capable
)
1984 im
->daddr
= (md
->cast_flags
== MDF_BCAST
)
1985 ? GET_INADDR(md
->interface
->bcast
)
1987 ? (GET_INADDR(md
->interface
->sin
)
1988 ? GET_INADDR(md
->interface
->sin
)
1989 : GET_INADDR(md
->interface
->bcast
))
1992 im
->flags
= htonl(md
->cast_flags
);
1993 im
->port
= md
->rmtport
;
1994 im
->mode
= md
->mode
;
1995 im
->version
= md
->version
;
1996 im
= (struct info_monitor_1
*)more_pkt();
2002 * Module entry points and the flags they correspond with
2004 struct reset_entry
{
2005 int flag
; /* flag this corresponds to */
2006 void (*handler
) P((void)); /* routine to handle request */
2009 struct reset_entry reset_entries
[] = {
2010 { RESET_FLAG_ALLPEERS
, peer_all_reset
},
2011 { RESET_FLAG_IO
, io_clr_stats
},
2012 { RESET_FLAG_SYS
, proto_clr_stats
},
2013 { RESET_FLAG_MEM
, peer_clr_stats
},
2014 { RESET_FLAG_TIMER
, timer_clr_stats
},
2015 { RESET_FLAG_AUTH
, reset_auth_stats
},
2016 { RESET_FLAG_CTL
, ctl_clr_stats
},
2021 * reset_stats - reset statistic counters here and there
2025 struct sockaddr_storage
*srcadr
,
2026 struct interface
*inter
,
2027 struct req_pkt
*inpkt
2031 struct reset_entry
*rent
;
2033 if (INFO_NITEMS(inpkt
->err_nitems
) > 1) {
2034 msyslog(LOG_ERR
, "reset_stats: err_nitems > 1");
2035 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
2039 flags
= ((struct reset_flags
*)inpkt
->data
)->flags
;
2040 flags
= ntohl(flags
);
2042 if (flags
& ~RESET_ALLFLAGS
) {
2043 msyslog(LOG_ERR
, "reset_stats: reset leaves %#lx",
2044 flags
& ~RESET_ALLFLAGS
);
2045 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
2049 for (rent
= reset_entries
; rent
->flag
!= 0; rent
++) {
2050 if (flags
& rent
->flag
)
2053 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2058 * reset_peer - clear a peer's statistics
2062 struct sockaddr_storage
*srcadr
,
2063 struct interface
*inter
,
2064 struct req_pkt
*inpkt
2067 register struct conf_unpeer
*cp
;
2069 register struct peer
*peer
;
2070 struct sockaddr_storage peeraddr
;
2074 * We check first to see that every peer exists. If not,
2075 * we return an error.
2078 items
= INFO_NITEMS(inpkt
->err_nitems
);
2079 cp
= (struct conf_unpeer
*)inpkt
->data
;
2082 while (items
-- > 0 && !bad
) {
2083 memset((char *)&peeraddr
, 0, sizeof(peeraddr
));
2084 if (client_v6_capable
&& cp
->v6_flag
!= 0) {
2085 GET_INADDR6(peeraddr
) = cp
->peeraddr6
;
2086 peeraddr
.ss_family
= AF_INET6
;
2088 GET_INADDR(peeraddr
) = cp
->peeraddr
;
2089 peeraddr
.ss_family
= AF_INET
;
2091 NSRCPORT(&peeraddr
) = htons(NTP_PORT
);
2092 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2093 peeraddr
.ss_len
= SOCKLEN(&peeraddr
);
2095 peer
= findexistingpeer(&peeraddr
, (struct peer
*)0, -1);
2096 if (peer
== (struct peer
*)0)
2098 cp
= (struct conf_unpeer
*)((char *)cp
+
2099 INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
2103 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2108 * Now do it in earnest.
2111 items
= INFO_NITEMS(inpkt
->err_nitems
);
2112 cp
= (struct conf_unpeer
*)inpkt
->data
;
2113 while (items
-- > 0) {
2114 memset((char *)&peeraddr
, 0, sizeof(peeraddr
));
2115 if (client_v6_capable
&& cp
->v6_flag
!= 0) {
2116 GET_INADDR6(peeraddr
) = cp
->peeraddr6
;
2117 peeraddr
.ss_family
= AF_INET6
;
2119 GET_INADDR(peeraddr
) = cp
->peeraddr
;
2120 peeraddr
.ss_family
= AF_INET
;
2122 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2123 peeraddr
.ss_len
= SOCKLEN(&peeraddr
);
2125 peer
= findexistingpeer(&peeraddr
, (struct peer
*)0, -1);
2128 peer
= findexistingpeer(&peeraddr
, (struct peer
*)peer
, -1);
2130 cp
= (struct conf_unpeer
*)((char *)cp
+
2131 INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
2134 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2139 * do_key_reread - reread the encryption key file
2143 struct sockaddr_storage
*srcadr
,
2144 struct interface
*inter
,
2145 struct req_pkt
*inpkt
2149 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2154 * trust_key - make one or more keys trusted
2158 struct sockaddr_storage
*srcadr
,
2159 struct interface
*inter
,
2160 struct req_pkt
*inpkt
2163 do_trustkey(srcadr
, inter
, inpkt
, 1);
2168 * untrust_key - make one or more keys untrusted
2172 struct sockaddr_storage
*srcadr
,
2173 struct interface
*inter
,
2174 struct req_pkt
*inpkt
2177 do_trustkey(srcadr
, inter
, inpkt
, 0);
2182 * do_trustkey - make keys either trustable or untrustable
2186 struct sockaddr_storage
*srcadr
,
2187 struct interface
*inter
,
2188 struct req_pkt
*inpkt
,
2192 register u_long
*kp
;
2195 items
= INFO_NITEMS(inpkt
->err_nitems
);
2196 kp
= (u_long
*)inpkt
->data
;
2197 while (items
-- > 0) {
2198 authtrust(*kp
, trust
);
2202 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2207 * get_auth_info - return some stats concerning the authentication module
2211 struct sockaddr_storage
*srcadr
,
2212 struct interface
*inter
,
2213 struct req_pkt
*inpkt
2216 register struct info_auth
*ia
;
2219 * Importations from the authentication module
2221 extern u_long authnumkeys
;
2222 extern int authnumfreekeys
;
2223 extern u_long authkeylookups
;
2224 extern u_long authkeynotfound
;
2225 extern u_long authencryptions
;
2226 extern u_long authdecryptions
;
2227 extern u_long authkeyuncached
;
2228 extern u_long authkeyexpired
;
2230 ia
= (struct info_auth
*)prepare_pkt(srcadr
, inter
, inpkt
,
2231 sizeof(struct info_auth
));
2233 ia
->numkeys
= htonl((u_int32
)authnumkeys
);
2234 ia
->numfreekeys
= htonl((u_int32
)authnumfreekeys
);
2235 ia
->keylookups
= htonl((u_int32
)authkeylookups
);
2236 ia
->keynotfound
= htonl((u_int32
)authkeynotfound
);
2237 ia
->encryptions
= htonl((u_int32
)authencryptions
);
2238 ia
->decryptions
= htonl((u_int32
)authdecryptions
);
2239 ia
->keyuncached
= htonl((u_int32
)authkeyuncached
);
2240 ia
->expired
= htonl((u_int32
)authkeyexpired
);
2241 ia
->timereset
= htonl((u_int32
)(current_time
- auth_timereset
));
2250 * reset_auth_stats - reset the authentication stat counters. Done here
2251 * to keep ntp-isms out of the authentication module
2254 reset_auth_stats(void)
2257 * Importations from the authentication module
2259 extern u_long authkeylookups
;
2260 extern u_long authkeynotfound
;
2261 extern u_long authencryptions
;
2262 extern u_long authdecryptions
;
2263 extern u_long authkeyuncached
;
2266 authkeynotfound
= 0;
2267 authencryptions
= 0;
2268 authdecryptions
= 0;
2269 authkeyuncached
= 0;
2270 auth_timereset
= current_time
;
2275 * req_get_traps - return information about current trap holders
2279 struct sockaddr_storage
*srcadr
,
2280 struct interface
*inter
,
2281 struct req_pkt
*inpkt
2284 register struct info_trap
*it
;
2285 register struct ctl_trap
*tr
;
2289 * Imported from the control module
2291 extern struct ctl_trap ctl_trap
[];
2292 extern int num_ctl_traps
;
2294 if (num_ctl_traps
== 0) {
2295 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2299 it
= (struct info_trap
*)prepare_pkt(srcadr
, inter
, inpkt
,
2300 v6sizeof(struct info_trap
));
2302 for (i
= 0, tr
= ctl_trap
; i
< CTL_MAXTRAPS
; i
++, tr
++) {
2303 if (tr
->tr_flags
& TRAP_INUSE
) {
2304 if (tr
->tr_addr
.ss_family
== AF_INET
) {
2305 if (tr
->tr_localaddr
== any_interface
)
2306 it
->local_address
= 0;
2309 = GET_INADDR(tr
->tr_localaddr
->sin
);
2310 it
->trap_address
= GET_INADDR(tr
->tr_addr
);
2311 if (client_v6_capable
)
2314 if (!client_v6_capable
)
2317 = GET_INADDR6(tr
->tr_localaddr
->sin
);
2318 it
->trap_address6
= GET_INADDR6(tr
->tr_addr
);
2321 it
->trap_port
= NSRCPORT(&tr
->tr_addr
);
2322 it
->sequence
= htons(tr
->tr_sequence
);
2323 it
->settime
= htonl((u_int32
)(current_time
- tr
->tr_settime
));
2324 it
->origtime
= htonl((u_int32
)(current_time
- tr
->tr_origtime
));
2325 it
->resets
= htonl((u_int32
)tr
->tr_resets
);
2326 it
->flags
= htonl((u_int32
)tr
->tr_flags
);
2327 it
= (struct info_trap
*)more_pkt();
2335 * req_set_trap - configure a trap
2339 struct sockaddr_storage
*srcadr
,
2340 struct interface
*inter
,
2341 struct req_pkt
*inpkt
2344 do_setclr_trap(srcadr
, inter
, inpkt
, 1);
2350 * req_clr_trap - unconfigure a trap
2354 struct sockaddr_storage
*srcadr
,
2355 struct interface
*inter
,
2356 struct req_pkt
*inpkt
2359 do_setclr_trap(srcadr
, inter
, inpkt
, 0);
2365 * do_setclr_trap - do the grunge work of (un)configuring a trap
2369 struct sockaddr_storage
*srcadr
,
2370 struct interface
*inter
,
2371 struct req_pkt
*inpkt
,
2375 register struct conf_trap
*ct
;
2376 register struct interface
*linter
;
2378 struct sockaddr_storage laddr
;
2381 * Prepare sockaddr_storage structure
2383 memset((char *)&laddr
, 0, sizeof laddr
);
2384 laddr
.ss_family
= srcadr
->ss_family
;
2385 NSRCPORT(&laddr
) = ntohs(NTP_PORT
);
2388 * Restrict ourselves to one item only. This eliminates
2389 * the error reporting problem.
2391 if (INFO_NITEMS(inpkt
->err_nitems
) > 1) {
2392 msyslog(LOG_ERR
, "do_setclr_trap: err_nitems > 1");
2393 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
2396 ct
= (struct conf_trap
*)inpkt
->data
;
2399 * Look for the local interface. If none, use the default.
2401 if (ct
->local_address
== 0) {
2402 linter
= any_interface
;
2404 if (laddr
.ss_family
== AF_INET
)
2405 GET_INADDR(laddr
) = ct
->local_address
;
2407 GET_INADDR6(laddr
) = ct
->local_address6
;
2408 linter
= findinterface(&laddr
);
2409 if (linter
== NULL
) {
2410 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2415 if (laddr
.ss_family
== AF_INET
)
2416 GET_INADDR(laddr
) = ct
->trap_address
;
2418 GET_INADDR6(laddr
) = ct
->trap_address6
;
2419 if (ct
->trap_port
!= 0)
2420 NSRCPORT(&laddr
) = ct
->trap_port
;
2422 NSRCPORT(&laddr
) = htons(TRAPPORT
);
2425 res
= ctlsettrap(&laddr
, linter
, 0,
2426 INFO_VERSION(inpkt
->rm_vn_mode
));
2428 res
= ctlclrtrap(&laddr
, linter
, 0);
2432 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2434 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2442 * set_request_keyid - set the keyid used to authenticate requests
2446 struct sockaddr_storage
*srcadr
,
2447 struct interface
*inter
,
2448 struct req_pkt
*inpkt
2454 * Restrict ourselves to one item only.
2456 if (INFO_NITEMS(inpkt
->err_nitems
) > 1) {
2457 msyslog(LOG_ERR
, "set_request_keyid: err_nitems > 1");
2458 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
2462 keyid
= ntohl(*((u_int32
*)(inpkt
->data
)));
2463 info_auth_keyid
= keyid
;
2464 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2470 * set_control_keyid - set the keyid used to authenticate requests
2474 struct sockaddr_storage
*srcadr
,
2475 struct interface
*inter
,
2476 struct req_pkt
*inpkt
2480 extern keyid_t ctl_auth_keyid
;
2483 * Restrict ourselves to one item only.
2485 if (INFO_NITEMS(inpkt
->err_nitems
) > 1) {
2486 msyslog(LOG_ERR
, "set_control_keyid: err_nitems > 1");
2487 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
2491 keyid
= ntohl(*((u_int32
*)(inpkt
->data
)));
2492 ctl_auth_keyid
= keyid
;
2493 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2499 * get_ctl_stats - return some stats concerning the control message module
2503 struct sockaddr_storage
*srcadr
,
2504 struct interface
*inter
,
2505 struct req_pkt
*inpkt
2508 register struct info_control
*ic
;
2511 * Importations from the control module
2513 extern u_long ctltimereset
;
2514 extern u_long numctlreq
;
2515 extern u_long numctlbadpkts
;
2516 extern u_long numctlresponses
;
2517 extern u_long numctlfrags
;
2518 extern u_long numctlerrors
;
2519 extern u_long numctltooshort
;
2520 extern u_long numctlinputresp
;
2521 extern u_long numctlinputfrag
;
2522 extern u_long numctlinputerr
;
2523 extern u_long numctlbadoffset
;
2524 extern u_long numctlbadversion
;
2525 extern u_long numctldatatooshort
;
2526 extern u_long numctlbadop
;
2527 extern u_long numasyncmsgs
;
2529 ic
= (struct info_control
*)prepare_pkt(srcadr
, inter
, inpkt
,
2530 sizeof(struct info_control
));
2532 ic
->ctltimereset
= htonl((u_int32
)(current_time
- ctltimereset
));
2533 ic
->numctlreq
= htonl((u_int32
)numctlreq
);
2534 ic
->numctlbadpkts
= htonl((u_int32
)numctlbadpkts
);
2535 ic
->numctlresponses
= htonl((u_int32
)numctlresponses
);
2536 ic
->numctlfrags
= htonl((u_int32
)numctlfrags
);
2537 ic
->numctlerrors
= htonl((u_int32
)numctlerrors
);
2538 ic
->numctltooshort
= htonl((u_int32
)numctltooshort
);
2539 ic
->numctlinputresp
= htonl((u_int32
)numctlinputresp
);
2540 ic
->numctlinputfrag
= htonl((u_int32
)numctlinputfrag
);
2541 ic
->numctlinputerr
= htonl((u_int32
)numctlinputerr
);
2542 ic
->numctlbadoffset
= htonl((u_int32
)numctlbadoffset
);
2543 ic
->numctlbadversion
= htonl((u_int32
)numctlbadversion
);
2544 ic
->numctldatatooshort
= htonl((u_int32
)numctldatatooshort
);
2545 ic
->numctlbadop
= htonl((u_int32
)numctlbadop
);
2546 ic
->numasyncmsgs
= htonl((u_int32
)numasyncmsgs
);
2555 * get_kernel_info - get kernel pll/pps information
2559 struct sockaddr_storage
*srcadr
,
2560 struct interface
*inter
,
2561 struct req_pkt
*inpkt
2564 register struct info_kernel
*ik
;
2568 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2572 memset((char *)&ntx
, 0, sizeof(ntx
));
2573 if (ntp_adjtime(&ntx
) < 0)
2574 msyslog(LOG_ERR
, "get_kernel_info: ntp_adjtime() failed: %m");
2575 ik
= (struct info_kernel
*)prepare_pkt(srcadr
, inter
, inpkt
,
2576 sizeof(struct info_kernel
));
2581 ik
->offset
= htonl((u_int32
)ntx
.offset
);
2582 ik
->freq
= htonl((u_int32
)ntx
.freq
);
2583 ik
->maxerror
= htonl((u_int32
)ntx
.maxerror
);
2584 ik
->esterror
= htonl((u_int32
)ntx
.esterror
);
2585 ik
->status
= htons(ntx
.status
);
2586 ik
->constant
= htonl((u_int32
)ntx
.constant
);
2587 ik
->precision
= htonl((u_int32
)ntx
.precision
);
2588 ik
->tolerance
= htonl((u_int32
)ntx
.tolerance
);
2593 ik
->ppsfreq
= htonl((u_int32
)ntx
.ppsfreq
);
2594 ik
->jitter
= htonl((u_int32
)ntx
.jitter
);
2595 ik
->shift
= htons(ntx
.shift
);
2596 ik
->stabil
= htonl((u_int32
)ntx
.stabil
);
2597 ik
->jitcnt
= htonl((u_int32
)ntx
.jitcnt
);
2598 ik
->calcnt
= htonl((u_int32
)ntx
.calcnt
);
2599 ik
->errcnt
= htonl((u_int32
)ntx
.errcnt
);
2600 ik
->stbcnt
= htonl((u_int32
)ntx
.stbcnt
);
2605 #endif /* KERNEL_PLL */
2610 * get_clock_info - get info about a clock
2614 struct sockaddr_storage
*srcadr
,
2615 struct interface
*inter
,
2616 struct req_pkt
*inpkt
2619 register struct info_clock
*ic
;
2620 register u_int32
*clkaddr
;
2622 struct refclockstat clock_stat
;
2623 struct sockaddr_storage addr
;
2624 struct sockaddr_in tmp_clock
;
2627 memset((char *)&addr
, 0, sizeof addr
);
2628 addr
.ss_family
= AF_INET
;
2629 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2630 addr
.ss_len
= SOCKLEN(&addr
);
2632 NSRCPORT(&addr
) = htons(NTP_PORT
);
2633 items
= INFO_NITEMS(inpkt
->err_nitems
);
2634 clkaddr
= (u_int32
*) inpkt
->data
;
2636 ic
= (struct info_clock
*)prepare_pkt(srcadr
, inter
, inpkt
,
2637 sizeof(struct info_clock
));
2639 while (items
-- > 0) {
2640 tmp_clock
.sin_addr
.s_addr
= *clkaddr
++;
2641 CAST_V4(addr
)->sin_addr
= tmp_clock
.sin_addr
;
2642 if (!ISREFCLOCKADR(&tmp_clock
) ||
2643 findexistingpeer(&addr
, (struct peer
*)0, -1) == 0) {
2644 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2648 clock_stat
.kv_list
= (struct ctl_var
*)0;
2650 refclock_control(&addr
, (struct refclockstat
*)0, &clock_stat
);
2652 ic
->clockadr
= tmp_clock
.sin_addr
.s_addr
;
2653 ic
->type
= clock_stat
.type
;
2654 ic
->flags
= clock_stat
.flags
;
2655 ic
->lastevent
= clock_stat
.lastevent
;
2656 ic
->currentstatus
= clock_stat
.currentstatus
;
2657 ic
->polls
= htonl((u_int32
)clock_stat
.polls
);
2658 ic
->noresponse
= htonl((u_int32
)clock_stat
.noresponse
);
2659 ic
->badformat
= htonl((u_int32
)clock_stat
.badformat
);
2660 ic
->baddata
= htonl((u_int32
)clock_stat
.baddata
);
2661 ic
->timestarted
= htonl((u_int32
)clock_stat
.timereset
);
2662 DTOLFP(clock_stat
.fudgetime1
, <mp
);
2663 HTONL_FP(<mp
, &ic
->fudgetime1
);
2664 DTOLFP(clock_stat
.fudgetime2
, <mp
);
2665 HTONL_FP(<mp
, &ic
->fudgetime2
);
2666 ic
->fudgeval1
= htonl((u_int32
)clock_stat
.fudgeval1
);
2667 ic
->fudgeval2
= htonl((u_int32
)clock_stat
.fudgeval2
);
2669 free_varlist(clock_stat
.kv_list
);
2671 ic
= (struct info_clock
*)more_pkt();
2679 * set_clock_fudge - get a clock's fudge factors
2683 struct sockaddr_storage
*srcadr
,
2684 struct interface
*inter
,
2685 struct req_pkt
*inpkt
2688 register struct conf_fudge
*cf
;
2690 struct refclockstat clock_stat
;
2691 struct sockaddr_storage addr
;
2692 struct sockaddr_in tmp_clock
;
2695 memset((char *)&addr
, 0, sizeof addr
);
2696 memset((char *)&clock_stat
, 0, sizeof clock_stat
);
2697 memset((char *)&tmp_clock
, 0, sizeof tmp_clock
);
2698 items
= INFO_NITEMS(inpkt
->err_nitems
);
2699 cf
= (struct conf_fudge
*) inpkt
->data
;
2701 while (items
-- > 0) {
2702 tmp_clock
.sin_addr
.s_addr
= cf
->clockadr
;
2703 *CAST_V4(addr
) = tmp_clock
;
2704 addr
.ss_family
= AF_INET
;
2705 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2706 addr
.ss_len
= SOCKLEN(&addr
);
2708 NSRCPORT(&addr
) = htons(NTP_PORT
);
2709 if (!ISREFCLOCKADR(&tmp_clock
) ||
2710 findexistingpeer(&addr
, (struct peer
*)0, -1) == 0) {
2711 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2715 switch(ntohl(cf
->which
)) {
2717 NTOHL_FP(&cf
->fudgetime
, <mp
);
2718 LFPTOD(<mp
, clock_stat
.fudgetime1
);
2719 clock_stat
.haveflags
= CLK_HAVETIME1
;
2722 NTOHL_FP(&cf
->fudgetime
, <mp
);
2723 LFPTOD(<mp
, clock_stat
.fudgetime2
);
2724 clock_stat
.haveflags
= CLK_HAVETIME2
;
2727 clock_stat
.fudgeval1
= ntohl(cf
->fudgeval_flags
);
2728 clock_stat
.haveflags
= CLK_HAVEVAL1
;
2731 clock_stat
.fudgeval2
= ntohl(cf
->fudgeval_flags
);
2732 clock_stat
.haveflags
= CLK_HAVEVAL2
;
2735 clock_stat
.flags
= (u_char
) (ntohl(cf
->fudgeval_flags
) & 0xf);
2736 clock_stat
.haveflags
=
2737 (CLK_HAVEFLAG1
|CLK_HAVEFLAG2
|CLK_HAVEFLAG3
|CLK_HAVEFLAG4
);
2740 msyslog(LOG_ERR
, "set_clock_fudge: default!");
2741 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
2745 refclock_control(&addr
, &clock_stat
, (struct refclockstat
*)0);
2748 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2754 * get_clkbug_info - get debugging info about a clock
2758 struct sockaddr_storage
*srcadr
,
2759 struct interface
*inter
,
2760 struct req_pkt
*inpkt
2764 register struct info_clkbug
*ic
;
2765 register u_int32
*clkaddr
;
2767 struct refclockbug bug
;
2768 struct sockaddr_storage addr
;
2769 struct sockaddr_in tmp_clock
;
2771 memset((char *)&addr
, 0, sizeof addr
);
2772 addr
.ss_family
= AF_INET
;
2773 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2774 addr
.ss_len
= SOCKLEN(&addr
);
2776 NSRCPORT(&addr
) = htons(NTP_PORT
);
2777 items
= INFO_NITEMS(inpkt
->err_nitems
);
2778 clkaddr
= (u_int32
*) inpkt
->data
;
2780 ic
= (struct info_clkbug
*)prepare_pkt(srcadr
, inter
, inpkt
,
2781 sizeof(struct info_clkbug
));
2783 while (items
-- > 0) {
2784 tmp_clock
.sin_addr
.s_addr
= *clkaddr
++;
2785 GET_INADDR(addr
) = tmp_clock
.sin_addr
.s_addr
;
2786 if (!ISREFCLOCKADR(&tmp_clock
) ||
2787 findexistingpeer(&addr
, (struct peer
*)0, -1) == 0) {
2788 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2792 memset((char *)&bug
, 0, sizeof bug
);
2793 refclock_buginfo(&addr
, &bug
);
2794 if (bug
.nvalues
== 0 && bug
.ntimes
== 0) {
2795 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2799 ic
->clockadr
= tmp_clock
.sin_addr
.s_addr
;
2801 if (i
> NUMCBUGVALUES
)
2803 ic
->nvalues
= (u_char
)i
;
2804 ic
->svalues
= htons((u_short
) (bug
.svalues
& ((1<<i
)-1)));
2806 ic
->values
[i
] = htonl(bug
.values
[i
]);
2809 if (i
> NUMCBUGTIMES
)
2811 ic
->ntimes
= (u_char
)i
;
2812 ic
->stimes
= htonl(bug
.stimes
);
2814 HTONL_FP(&bug
.times
[i
], &ic
->times
[i
]);
2817 ic
= (struct info_clkbug
*)more_pkt();
2824 * receiver of interface structures
2827 fill_info_if_stats(void *data
, interface_info_t
*interface_info
)
2829 struct info_if_stats
**ifsp
= (struct info_if_stats
**)data
;
2830 struct info_if_stats
*ifs
= *ifsp
;
2831 struct interface
*interface
= interface_info
->interface
;
2833 memset((char*)ifs
, 0, sizeof(*ifs
));
2835 if (interface
->sin
.ss_family
== AF_INET6
) {
2836 if (!client_v6_capable
) {
2840 memcpy((char *)&ifs
->unaddr
.addr6
, (char *)&CAST_V6(interface
->sin
)->sin6_addr
, sizeof(struct in6_addr
));
2841 memcpy((char *)&ifs
->unbcast
.addr6
, (char *)&CAST_V6(interface
->bcast
)->sin6_addr
, sizeof(struct in6_addr
));
2842 memcpy((char *)&ifs
->unmask
.addr6
, (char *)&CAST_V6(interface
->mask
)->sin6_addr
, sizeof(struct in6_addr
));
2845 memcpy((char *)&ifs
->unaddr
.addr
, (char *)&CAST_V4(interface
->sin
)->sin_addr
, sizeof(struct in_addr
));
2846 memcpy((char *)&ifs
->unbcast
.addr
, (char *)&CAST_V4(interface
->bcast
)->sin_addr
, sizeof(struct in_addr
));
2847 memcpy((char *)&ifs
->unmask
.addr
, (char *)&CAST_V4(interface
->mask
)->sin_addr
, sizeof(struct in_addr
));
2849 ifs
->v6_flag
= htonl(ifs
->v6_flag
);
2850 strcpy(ifs
->name
, interface
->name
);
2851 ifs
->family
= htons(interface
->family
);
2852 ifs
->flags
= htonl(interface
->flags
);
2853 ifs
->last_ttl
= htonl(interface
->last_ttl
);
2854 ifs
->num_mcast
= htonl(interface
->num_mcast
);
2855 ifs
->received
= htonl(interface
->received
);
2856 ifs
->sent
= htonl(interface
->sent
);
2857 ifs
->notsent
= htonl(interface
->notsent
);
2858 ifs
->scopeid
= htonl(interface
->scopeid
);
2859 ifs
->ifindex
= htonl(interface
->ifindex
);
2860 ifs
->ifnum
= htonl(interface
->ifnum
);
2861 ifs
->uptime
= htonl(current_time
- interface
->starttime
);
2862 ifs
->ignore_packets
= interface
->ignore_packets
;
2863 ifs
->peercnt
= htonl(interface
->peercnt
);
2864 ifs
->action
= interface_info
->action
;
2866 *ifsp
= (struct info_if_stats
*)more_pkt();
2870 * get_if_stats - get interface statistics
2874 struct sockaddr_storage
*srcadr
,
2875 struct interface
*inter
,
2876 struct req_pkt
*inpkt
2879 struct info_if_stats
*ifs
;
2881 DPRINTF(3, ("wants interface statistics\n"));
2883 ifs
= (struct info_if_stats
*)prepare_pkt(srcadr
, inter
, inpkt
,
2884 v6sizeof(struct info_if_stats
));
2886 interface_enumerate(fill_info_if_stats
, &ifs
);
2893 struct sockaddr_storage
*srcadr
,
2894 struct interface
*inter
,
2895 struct req_pkt
*inpkt
2898 struct info_if_stats
*ifs
;
2900 DPRINTF(3, ("wants interface reload\n"));
2902 ifs
= (struct info_if_stats
*)prepare_pkt(srcadr
, inter
, inpkt
,
2903 v6sizeof(struct info_if_stats
));
2905 interface_update(fill_info_if_stats
, &ifs
);