1 /* $NetBSD: ntp_request.c,v 1.1.1.8 2009/12/08 20:43:48 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 static u_long quiet_until
;
415 struct req_pkt
*inpkt
;
416 struct req_pkt_tail
*tailinpkt
;
417 struct sockaddr_storage
*srcadr
;
418 struct interface
*inter
;
419 struct req_proc
*proc
;
424 * Initialize pointers, for convenience
426 inpkt
= (struct req_pkt
*)&rbufp
->recv_pkt
;
427 srcadr
= &rbufp
->recv_srcadr
;
428 inter
= rbufp
->dstadr
;
432 printf("process_private: impl %d req %d\n",
433 inpkt
->implementation
, inpkt
->request
);
437 * Do some sanity checks on the packet. Return a format
441 if ( (++ec
, ISRESPONSE(inpkt
->rm_vn_mode
))
442 || (++ec
, ISMORE(inpkt
->rm_vn_mode
))
443 || (++ec
, INFO_VERSION(inpkt
->rm_vn_mode
) > NTP_VERSION
)
444 || (++ec
, INFO_VERSION(inpkt
->rm_vn_mode
) < NTP_OLDVERSION
)
445 || (++ec
, INFO_SEQ(inpkt
->auth_seq
) != 0)
446 || (++ec
, INFO_ERR(inpkt
->err_nitems
) != 0)
447 || (++ec
, INFO_MBZ(inpkt
->mbz_itemsize
) != 0)
448 || (++ec
, rbufp
->recv_length
< REQ_LEN_HDR
)
451 if (current_time
>= quiet_until
) {
453 "process_private: drop test %d"
454 " failed, pkt from %s",
456 quiet_until
= current_time
+ 60;
461 reqver
= INFO_VERSION(inpkt
->rm_vn_mode
);
464 * Get the appropriate procedure list to search.
466 if (inpkt
->implementation
== IMPL_UNIV
)
468 else if ((inpkt
->implementation
== IMPL_XNTPD
) ||
469 (inpkt
->implementation
== IMPL_XNTPD_OLD
))
472 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_IMPL
);
477 * Search the list for the request codes. If it isn't one
478 * we know, return an error.
480 while (proc
->request_code
!= NO_REQUEST
) {
481 if (proc
->request_code
== (short) inpkt
->request
)
485 if (proc
->request_code
== NO_REQUEST
) {
486 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_REQ
);
492 printf("found request in tables\n");
496 * If we need data, check to see if we have some. If we
497 * don't, check to see that there is none (picky, picky).
500 /* This part is a bit tricky, we want to be sure that the size
501 * returned is either the old or the new size. We also can find
502 * out if the client can accept both types of messages this way.
504 * Handle the exception of REQ_CONFIG. It can have two data sizes.
506 temp_size
= INFO_ITEMSIZE(inpkt
->mbz_itemsize
);
507 if ((temp_size
!= proc
->sizeofitem
&&
508 temp_size
!= proc
->v6_sizeofitem
) &&
509 !(inpkt
->implementation
== IMPL_XNTPD
&&
510 inpkt
->request
== REQ_CONFIG
&&
511 temp_size
== sizeof(struct old_conf_peer
))) {
514 printf("process_private: wrong item size, received %d, should be %d or %d\n",
515 temp_size
, proc
->sizeofitem
, proc
->v6_sizeofitem
);
517 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
520 if ((proc
->sizeofitem
!= 0) &&
521 ((temp_size
* INFO_NITEMS(inpkt
->err_nitems
)) >
522 (rbufp
->recv_length
- REQ_LEN_HDR
))) {
525 printf("process_private: not enough data\n");
527 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
531 switch (inpkt
->implementation
) {
533 client_v6_capable
= 1;
536 client_v6_capable
= 0;
539 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
544 * If we need to authenticate, do so. Note that an
545 * authenticatable packet must include a mac field, must
546 * have used key info_auth_keyid and must have included
547 * a time stamp in the appropriate field. The time stamp
548 * must be within INFO_TS_MAXSKEW of the receive
551 if (proc
->needs_auth
&& sys_authenticate
) {
555 if (rbufp
->recv_length
< (int)((REQ_LEN_HDR
+
556 (INFO_ITEMSIZE(inpkt
->mbz_itemsize
) *
557 INFO_NITEMS(inpkt
->err_nitems
))
558 + sizeof(struct req_pkt_tail
)))) {
559 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
561 tailinpkt
= (struct req_pkt_tail
*)((char *)&rbufp
->recv_pkt
+
562 rbufp
->recv_length
- sizeof(struct req_pkt_tail
));
565 * If this guy is restricted from doing this, don't let him
566 * If wrong key was used, or packet doesn't have mac, return.
568 if (!INFO_IS_AUTH(inpkt
->auth_seq
) || info_auth_keyid
== 0
569 || ntohl(tailinpkt
->keyid
) != info_auth_keyid
) {
572 printf("failed auth %d info_auth_keyid %lu pkt keyid %lu\n",
573 INFO_IS_AUTH(inpkt
->auth_seq
),
574 (u_long
)info_auth_keyid
,
575 (u_long
)ntohl(tailinpkt
->keyid
));
577 "process_private: failed auth %d info_auth_keyid %lu pkt keyid %lu\n",
578 INFO_IS_AUTH(inpkt
->auth_seq
),
579 (u_long
)info_auth_keyid
,
580 (u_long
)ntohl(tailinpkt
->keyid
));
582 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_AUTH
);
585 if (rbufp
->recv_length
> REQ_LEN_MAC
) {
588 printf("bad pkt length %d\n",
591 msyslog(LOG_ERR
, "process_private: bad pkt length %d",
593 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
596 if (!mod_okay
|| !authhavekey(info_auth_keyid
)) {
599 printf("failed auth mod_okay %d\n", mod_okay
);
601 "process_private: failed auth mod_okay %d\n",
604 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_AUTH
);
609 * calculate absolute time difference between xmit time stamp
610 * and receive time stamp. If too large, too bad.
612 NTOHL_FP(&tailinpkt
->tstamp
, &ftmp
);
613 L_SUB(&ftmp
, &rbufp
->recv_time
);
614 LFPTOD(&ftmp
, dtemp
);
615 if (fabs(dtemp
) >= INFO_TS_MAXSKEW
) {
617 * He's a loser. Tell him.
621 printf("xmit/rcv timestamp delta > INFO_TS_MAXSKEW\n");
623 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_AUTH
);
628 * So far so good. See if decryption works out okay.
630 if (!authdecrypt(info_auth_keyid
, (u_int32
*)inpkt
,
631 rbufp
->recv_length
- sizeof(struct req_pkt_tail
) +
632 REQ_LEN_HDR
, sizeof(struct req_pkt_tail
) - REQ_LEN_HDR
)) {
635 printf("authdecrypt failed\n");
637 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_AUTH
);
644 printf("process_private: all okay, into handler\n");
648 * Packet is okay. Call the handler to send him data.
650 (proc
->handler
)(srcadr
, inter
, inpkt
);
655 * peer_list - send a list of the peers
659 struct sockaddr_storage
*srcadr
,
660 struct interface
*inter
,
661 struct req_pkt
*inpkt
664 register struct info_peer_list
*ip
;
665 register struct peer
*pp
;
667 register int skip
= 0;
669 ip
= (struct info_peer_list
*)prepare_pkt(srcadr
, inter
, inpkt
,
670 v6sizeof(struct info_peer_list
));
671 for (i
= 0; i
< NTP_HASH_SIZE
&& ip
!= 0; i
++) {
673 while (pp
!= 0 && ip
!= 0) {
674 if (pp
->srcadr
.ss_family
== AF_INET6
) {
675 if (client_v6_capable
) {
676 ip
->addr6
= GET_INADDR6(pp
->srcadr
);
684 ip
->addr
= GET_INADDR(pp
->srcadr
);
685 if (client_v6_capable
)
691 ip
->port
= NSRCPORT(&pp
->srcadr
);
692 ip
->hmode
= pp
->hmode
;
694 if (pp
->flags
& FLAG_CONFIG
)
695 ip
->flags
|= INFO_FLAG_CONFIG
;
697 ip
->flags
|= INFO_FLAG_SYSPEER
;
698 if (pp
->status
== CTL_PST_SEL_SYNCCAND
)
699 ip
->flags
|= INFO_FLAG_SEL_CANDIDATE
;
700 if (pp
->status
>= CTL_PST_SEL_SYSPEER
)
701 ip
->flags
|= INFO_FLAG_SHORTLIST
;
702 ip
= (struct info_peer_list
*)more_pkt();
712 * peer_list_sum - return extended peer list
716 struct sockaddr_storage
*srcadr
,
717 struct interface
*inter
,
718 struct req_pkt
*inpkt
721 register struct info_peer_summary
*ips
;
722 register struct peer
*pp
;
729 printf("wants peer list summary\n");
731 ips
= (struct info_peer_summary
*)prepare_pkt(srcadr
, inter
, inpkt
,
732 v6sizeof(struct info_peer_summary
));
733 for (i
= 0; i
< NTP_HASH_SIZE
&& ips
!= 0; i
++) {
735 while (pp
!= 0 && ips
!= 0) {
738 printf("sum: got one\n");
741 * Be careful here not to return v6 peers when we
744 if (pp
->srcadr
.ss_family
== AF_INET6
) {
745 if (client_v6_capable
) {
746 ips
->srcadr6
= GET_INADDR6(pp
->srcadr
);
749 ips
->dstadr6
= GET_INADDR6(pp
->dstadr
->sin
);
751 memset(&ips
->dstadr6
, 0, sizeof(ips
->dstadr6
));
758 ips
->srcadr
= GET_INADDR(pp
->srcadr
);
759 if (client_v6_capable
)
761 /* XXX PDM This code is buggy. Need to replace with a straightforward assignment */
764 ips
->dstadr
= (pp
->processed
) ?
765 pp
->cast_flags
== MDF_BCAST
?
766 GET_INADDR(pp
->dstadr
->bcast
):
768 GET_INADDR(pp
->dstadr
->sin
) ?
769 GET_INADDR(pp
->dstadr
->sin
):
770 GET_INADDR(pp
->dstadr
->bcast
):
771 1 : GET_INADDR(pp
->dstadr
->sin
);
773 memset(&ips
->dstadr
, 0, sizeof(ips
->dstadr
));
779 ips
->srcport
= NSRCPORT(&pp
->srcadr
);
780 ips
->stratum
= pp
->stratum
;
781 ips
->hpoll
= pp
->hpoll
;
782 ips
->ppoll
= pp
->ppoll
;
783 ips
->reach
= pp
->reach
;
786 ips
->flags
|= INFO_FLAG_SYSPEER
;
787 if (pp
->flags
& FLAG_CONFIG
)
788 ips
->flags
|= INFO_FLAG_CONFIG
;
789 if (pp
->flags
& FLAG_REFCLOCK
)
790 ips
->flags
|= INFO_FLAG_REFCLOCK
;
791 if (pp
->flags
& FLAG_AUTHENABLE
)
792 ips
->flags
|= INFO_FLAG_AUTHENABLE
;
793 if (pp
->flags
& FLAG_PREFER
)
794 ips
->flags
|= INFO_FLAG_PREFER
;
795 if (pp
->flags
& FLAG_BURST
)
796 ips
->flags
|= INFO_FLAG_BURST
;
797 if (pp
->status
== CTL_PST_SEL_SYNCCAND
)
798 ips
->flags
|= INFO_FLAG_SEL_CANDIDATE
;
799 if (pp
->status
>= CTL_PST_SEL_SYSPEER
)
800 ips
->flags
|= INFO_FLAG_SHORTLIST
;
801 ips
->hmode
= pp
->hmode
;
802 ips
->delay
= HTONS_FP(DTOFP(pp
->delay
));
803 DTOLFP(pp
->offset
, <mp
);
804 HTONL_FP(<mp
, &ips
->offset
);
805 ips
->dispersion
= HTONS_FP(DTOUFP(SQRT(pp
->disp
)));
808 ips
= (struct info_peer_summary
*)more_pkt();
816 * peer_info - send information for one or more peers
820 struct sockaddr_storage
*srcadr
,
821 struct interface
*inter
,
822 struct req_pkt
*inpkt
825 register struct info_peer_list
*ipl
;
826 register struct peer
*pp
;
827 register struct info_peer
*ip
;
830 struct sockaddr_storage addr
;
831 extern struct peer
*sys_peer
;
834 memset((char *)&addr
, 0, sizeof addr
);
835 items
= INFO_NITEMS(inpkt
->err_nitems
);
836 ipl
= (struct info_peer_list
*) inpkt
->data
;
838 ip
= (struct info_peer
*)prepare_pkt(srcadr
, inter
, inpkt
,
839 v6sizeof(struct info_peer
));
840 while (items
-- > 0 && ip
!= 0) {
841 memset((char *)&addr
, 0, sizeof(addr
));
842 NSRCPORT(&addr
) = ipl
->port
;
843 if (client_v6_capable
&& ipl
->v6_flag
!= 0) {
844 addr
.ss_family
= AF_INET6
;
845 GET_INADDR6(addr
) = ipl
->addr6
;
847 addr
.ss_family
= AF_INET
;
848 GET_INADDR(addr
) = ipl
->addr
;
850 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
851 addr
.ss_len
= SOCKLEN(&addr
);
854 if ((pp
= findexistingpeer(&addr
, (struct peer
*)0, -1)) == 0)
856 if (pp
->srcadr
.ss_family
== AF_INET6
) {
858 ip
->dstadr6
= pp
->cast_flags
== MDF_BCAST
?
859 GET_INADDR6(pp
->dstadr
->bcast
) :
860 GET_INADDR6(pp
->dstadr
->sin
);
862 memset(&ip
->dstadr6
, 0, sizeof(ip
->dstadr6
));
864 ip
->srcadr6
= GET_INADDR6(pp
->srcadr
);
867 /* XXX PDM This code is buggy. Need to replace with a straightforward assignment */
869 ip
->dstadr
= (pp
->processed
) ?
870 pp
->cast_flags
== MDF_BCAST
?
871 GET_INADDR(pp
->dstadr
->bcast
):
873 GET_INADDR(pp
->dstadr
->sin
) ?
874 GET_INADDR(pp
->dstadr
->sin
):
875 GET_INADDR(pp
->dstadr
->bcast
):
876 2 : GET_INADDR(pp
->dstadr
->sin
);
878 memset(&ip
->dstadr
, 0, sizeof(ip
->dstadr
));
880 ip
->srcadr
= GET_INADDR(pp
->srcadr
);
881 if (client_v6_capable
)
884 ip
->srcport
= NSRCPORT(&pp
->srcadr
);
887 ip
->flags
|= INFO_FLAG_SYSPEER
;
888 if (pp
->flags
& FLAG_CONFIG
)
889 ip
->flags
|= INFO_FLAG_CONFIG
;
890 if (pp
->flags
& FLAG_REFCLOCK
)
891 ip
->flags
|= INFO_FLAG_REFCLOCK
;
892 if (pp
->flags
& FLAG_AUTHENABLE
)
893 ip
->flags
|= INFO_FLAG_AUTHENABLE
;
894 if (pp
->flags
& FLAG_PREFER
)
895 ip
->flags
|= INFO_FLAG_PREFER
;
896 if (pp
->flags
& FLAG_BURST
)
897 ip
->flags
|= INFO_FLAG_BURST
;
898 if (pp
->status
== CTL_PST_SEL_SYNCCAND
)
899 ip
->flags
|= INFO_FLAG_SEL_CANDIDATE
;
900 if (pp
->status
>= CTL_PST_SEL_SYSPEER
)
901 ip
->flags
|= INFO_FLAG_SHORTLIST
;
903 ip
->hmode
= pp
->hmode
;
904 ip
->keyid
= pp
->keyid
;
905 ip
->stratum
= pp
->stratum
;
906 ip
->ppoll
= pp
->ppoll
;
907 ip
->hpoll
= pp
->hpoll
;
908 ip
->precision
= pp
->precision
;
909 ip
->version
= pp
->version
;
910 ip
->reach
= pp
->reach
;
911 ip
->unreach
= (u_char
) pp
->unreach
;
912 ip
->flash
= (u_char
)pp
->flash
;
913 ip
->flash2
= (u_short
) pp
->flash
;
914 ip
->estbdelay
= HTONS_FP(DTOFP(pp
->estbdelay
));
916 ip
->associd
= htons(pp
->associd
);
917 ip
->rootdelay
= HTONS_FP(DTOUFP(pp
->rootdelay
));
918 ip
->rootdispersion
= HTONS_FP(DTOUFP(pp
->rootdispersion
));
919 ip
->refid
= pp
->refid
;
920 HTONL_FP(&pp
->reftime
, &ip
->reftime
);
921 HTONL_FP(&pp
->org
, &ip
->org
);
922 HTONL_FP(&pp
->rec
, &ip
->rec
);
923 HTONL_FP(&pp
->xmt
, &ip
->xmt
);
924 j
= pp
->filter_nextpt
- 1;
925 for (i
= 0; i
< NTP_SHIFT
; i
++, j
--) {
928 ip
->filtdelay
[i
] = HTONS_FP(DTOFP(pp
->filter_delay
[j
]));
929 DTOLFP(pp
->filter_offset
[j
], <mp
);
930 HTONL_FP(<mp
, &ip
->filtoffset
[i
]);
931 ip
->order
[i
] = (u_char
)((pp
->filter_nextpt
+NTP_SHIFT
-1)
932 - pp
->filter_order
[i
]);
933 if (ip
->order
[i
] >= NTP_SHIFT
)
934 ip
->order
[i
] -= NTP_SHIFT
;
936 DTOLFP(pp
->offset
, <mp
);
937 HTONL_FP(<mp
, &ip
->offset
);
938 ip
->delay
= HTONS_FP(DTOFP(pp
->delay
));
939 ip
->dispersion
= HTONS_FP(DTOUFP(SQRT(pp
->disp
)));
940 ip
->selectdisp
= HTONS_FP(DTOUFP(SQRT(pp
->jitter
)));
941 ip
= (struct info_peer
*)more_pkt();
948 * peer_stats - send statistics for one or more peers
952 struct sockaddr_storage
*srcadr
,
953 struct interface
*inter
,
954 struct req_pkt
*inpkt
957 register struct info_peer_list
*ipl
;
958 register struct peer
*pp
;
959 register struct info_peer_stats
*ip
;
961 struct sockaddr_storage addr
;
962 extern struct peer
*sys_peer
;
966 printf("peer_stats: called\n");
968 items
= INFO_NITEMS(inpkt
->err_nitems
);
969 ipl
= (struct info_peer_list
*) inpkt
->data
;
970 ip
= (struct info_peer_stats
*)prepare_pkt(srcadr
, inter
, inpkt
,
971 v6sizeof(struct info_peer_stats
));
972 while (items
-- > 0 && ip
!= 0) {
973 memset((char *)&addr
, 0, sizeof(addr
));
974 NSRCPORT(&addr
) = ipl
->port
;
975 if (client_v6_capable
&& ipl
->v6_flag
) {
976 addr
.ss_family
= AF_INET6
;
977 GET_INADDR6(addr
) = ipl
->addr6
;
979 addr
.ss_family
= AF_INET
;
980 GET_INADDR(addr
) = ipl
->addr
;
982 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
983 addr
.ss_len
= SOCKLEN(&addr
);
987 printf("peer_stats: looking for %s, %d, %d\n", stoa(&addr
),
988 ipl
->port
, ((struct sockaddr_in6
*)&addr
)->sin6_port
);
990 ipl
= (struct info_peer_list
*)((char *)ipl
+
991 INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
993 if ((pp
= findexistingpeer(&addr
, (struct peer
*)0, -1)) == 0)
997 printf("peer_stats: found %s\n", stoa(&addr
));
999 if (pp
->srcadr
.ss_family
== AF_INET
) {
1001 ip
->dstadr
= (pp
->processed
) ?
1002 pp
->cast_flags
== MDF_BCAST
?
1003 GET_INADDR(pp
->dstadr
->bcast
):
1005 GET_INADDR(pp
->dstadr
->sin
) ?
1006 GET_INADDR(pp
->dstadr
->sin
):
1007 GET_INADDR(pp
->dstadr
->bcast
):
1010 memset(&ip
->dstadr
, 0, sizeof(ip
->dstadr
));
1012 ip
->srcadr
= GET_INADDR(pp
->srcadr
);
1013 if (client_v6_capable
)
1017 ip
->dstadr6
= pp
->cast_flags
== MDF_BCAST
?
1018 GET_INADDR6(pp
->dstadr
->bcast
):
1019 GET_INADDR6(pp
->dstadr
->sin
);
1021 memset(&ip
->dstadr6
, 0, sizeof(ip
->dstadr6
));
1023 ip
->srcadr6
= GET_INADDR6(pp
->srcadr
);
1026 ip
->srcport
= NSRCPORT(&pp
->srcadr
);
1029 ip
->flags
|= INFO_FLAG_SYSPEER
;
1030 if (pp
->flags
& FLAG_CONFIG
)
1031 ip
->flags
|= INFO_FLAG_CONFIG
;
1032 if (pp
->flags
& FLAG_REFCLOCK
)
1033 ip
->flags
|= INFO_FLAG_REFCLOCK
;
1034 if (pp
->flags
& FLAG_AUTHENABLE
)
1035 ip
->flags
|= INFO_FLAG_AUTHENABLE
;
1036 if (pp
->flags
& FLAG_PREFER
)
1037 ip
->flags
|= INFO_FLAG_PREFER
;
1038 if (pp
->flags
& FLAG_BURST
)
1039 ip
->flags
|= INFO_FLAG_BURST
;
1040 if (pp
->flags
& FLAG_IBURST
)
1041 ip
->flags
|= INFO_FLAG_IBURST
;
1042 if (pp
->status
== CTL_PST_SEL_SYNCCAND
)
1043 ip
->flags
|= INFO_FLAG_SEL_CANDIDATE
;
1044 if (pp
->status
>= CTL_PST_SEL_SYSPEER
)
1045 ip
->flags
|= INFO_FLAG_SHORTLIST
;
1046 ip
->flags
= htons(ip
->flags
);
1047 ip
->timereceived
= htonl((u_int32
)(current_time
- pp
->timereceived
));
1048 ip
->timetosend
= htonl(pp
->nextdate
- current_time
);
1049 ip
->timereachable
= htonl((u_int32
)(current_time
- pp
->timereachable
));
1050 ip
->sent
= htonl((u_int32
)(pp
->sent
));
1051 ip
->processed
= htonl((u_int32
)(pp
->processed
));
1052 ip
->badauth
= htonl((u_int32
)(pp
->badauth
));
1053 ip
->bogusorg
= htonl((u_int32
)(pp
->bogusorg
));
1054 ip
->oldpkt
= htonl((u_int32
)(pp
->oldpkt
));
1055 ip
->seldisp
= htonl((u_int32
)(pp
->seldisptoolarge
));
1056 ip
->selbroken
= htonl((u_int32
)(pp
->selbroken
));
1057 ip
->candidate
= pp
->status
;
1058 ip
= (struct info_peer_stats
*)more_pkt();
1065 * sys_info - return system info
1069 struct sockaddr_storage
*srcadr
,
1070 struct interface
*inter
,
1071 struct req_pkt
*inpkt
1074 register struct info_sys
*is
;
1076 is
= (struct info_sys
*)prepare_pkt(srcadr
, inter
, inpkt
,
1077 v6sizeof(struct info_sys
));
1079 if (sys_peer
!= 0) {
1080 if (sys_peer
->srcadr
.ss_family
== AF_INET
) {
1081 is
->peer
= GET_INADDR(sys_peer
->srcadr
);
1082 if (client_v6_capable
)
1084 } else if (client_v6_capable
) {
1085 is
->peer6
= GET_INADDR6(sys_peer
->srcadr
);
1088 is
->peer_mode
= sys_peer
->hmode
;
1091 if (client_v6_capable
) {
1097 is
->leap
= sys_leap
;
1098 is
->stratum
= sys_stratum
;
1099 is
->precision
= sys_precision
;
1100 is
->rootdelay
= htonl(DTOFP(sys_rootdelay
));
1101 is
->rootdispersion
= htonl(DTOUFP(sys_rootdispersion
));
1102 is
->frequency
= htonl(DTOFP(sys_jitter
));
1103 is
->stability
= htonl(DTOUFP(clock_stability
));
1104 is
->refid
= sys_refid
;
1105 HTONL_FP(&sys_reftime
, &is
->reftime
);
1107 is
->poll
= sys_poll
;
1110 if (sys_authenticate
)
1111 is
->flags
|= INFO_FLAG_AUTHENTICATE
;
1113 is
->flags
|= INFO_FLAG_BCLIENT
;
1116 is
->flags
|= INFO_FLAG_CAL
;
1117 #endif /* REFCLOCK */
1119 is
->flags
|= INFO_FLAG_KERNEL
;
1120 if (mon_enabled
!= MON_OFF
)
1121 is
->flags
|= INFO_FLAG_MONITOR
;
1123 is
->flags
|= INFO_FLAG_NTP
;
1125 is
->flags
|= INFO_FLAG_PPS_SYNC
;
1127 is
->flags
|= INFO_FLAG_FILEGEN
;
1128 is
->bdelay
= HTONS_FP(DTOFP(sys_bdelay
));
1129 HTONL_UF(sys_authdelay
.l_f
, &is
->authdelay
);
1137 * sys_stats - return system statistics
1141 struct sockaddr_storage
*srcadr
,
1142 struct interface
*inter
,
1143 struct req_pkt
*inpkt
1146 register struct info_sys_stats
*ss
;
1149 * Importations from the protocol module
1151 ss
= (struct info_sys_stats
*)prepare_pkt(srcadr
, inter
, inpkt
,
1152 sizeof(struct info_sys_stats
));
1153 ss
->timeup
= htonl((u_int32
)current_time
);
1154 ss
->timereset
= htonl((u_int32
)(current_time
- sys_stattime
));
1155 ss
->denied
= htonl((u_int32
)sys_restricted
);
1156 ss
->oldversionpkt
= htonl((u_int32
)sys_oldversionpkt
);
1157 ss
->newversionpkt
= htonl((u_int32
)sys_newversionpkt
);
1158 ss
->unknownversion
= htonl((u_int32
)sys_unknownversion
);
1159 ss
->badlength
= htonl((u_int32
)sys_badlength
);
1160 ss
->processed
= htonl((u_int32
)sys_processed
);
1161 ss
->badauth
= htonl((u_int32
)sys_badauth
);
1162 ss
->limitrejected
= htonl((u_int32
)sys_limitrejected
);
1163 ss
->received
= htonl((u_int32
)sys_received
);
1170 * mem_stats - return memory statistics
1174 struct sockaddr_storage
*srcadr
,
1175 struct interface
*inter
,
1176 struct req_pkt
*inpkt
1179 register struct info_mem_stats
*ms
;
1183 * Importations from the peer module
1185 extern int peer_hash_count
[];
1186 extern int peer_free_count
;
1187 extern u_long peer_timereset
;
1188 extern u_long findpeer_calls
;
1189 extern u_long peer_allocations
;
1190 extern u_long peer_demobilizations
;
1191 extern int total_peer_structs
;
1193 ms
= (struct info_mem_stats
*)prepare_pkt(srcadr
, inter
, inpkt
,
1194 sizeof(struct info_mem_stats
));
1196 ms
->timereset
= htonl((u_int32
)(current_time
- peer_timereset
));
1197 ms
->totalpeermem
= htons((u_short
)total_peer_structs
);
1198 ms
->freepeermem
= htons((u_short
)peer_free_count
);
1199 ms
->findpeer_calls
= htonl((u_int32
)findpeer_calls
);
1200 ms
->allocations
= htonl((u_int32
)peer_allocations
);
1201 ms
->demobilizations
= htonl((u_int32
)peer_demobilizations
);
1203 for (i
= 0; i
< NTP_HASH_SIZE
; i
++) {
1204 if (peer_hash_count
[i
] > 255)
1205 ms
->hashcount
[i
] = 255;
1207 ms
->hashcount
[i
] = (u_char
)peer_hash_count
[i
];
1216 * io_stats - return io statistics
1220 struct sockaddr_storage
*srcadr
,
1221 struct interface
*inter
,
1222 struct req_pkt
*inpkt
1225 register struct info_io_stats
*io
;
1228 * Importations from the io module
1230 extern u_long io_timereset
;
1232 io
= (struct info_io_stats
*)prepare_pkt(srcadr
, inter
, inpkt
,
1233 sizeof(struct info_io_stats
));
1235 io
->timereset
= htonl((u_int32
)(current_time
- io_timereset
));
1236 io
->totalrecvbufs
= htons((u_short
) total_recvbuffs());
1237 io
->freerecvbufs
= htons((u_short
) free_recvbuffs());
1238 io
->fullrecvbufs
= htons((u_short
) full_recvbuffs());
1239 io
->lowwater
= htons((u_short
) lowater_additions());
1240 io
->dropped
= htonl((u_int32
)packets_dropped
);
1241 io
->ignored
= htonl((u_int32
)packets_ignored
);
1242 io
->received
= htonl((u_int32
)packets_received
);
1243 io
->sent
= htonl((u_int32
)packets_sent
);
1244 io
->notsent
= htonl((u_int32
)packets_notsent
);
1245 io
->interrupts
= htonl((u_int32
)handler_calls
);
1246 io
->int_received
= htonl((u_int32
)handler_pkts
);
1254 * timer_stats - return timer statistics
1258 struct sockaddr_storage
*srcadr
,
1259 struct interface
*inter
,
1260 struct req_pkt
*inpkt
1263 register struct info_timer_stats
*ts
;
1266 * Importations from the timer module
1268 extern u_long timer_timereset
;
1269 extern u_long timer_overflows
;
1270 extern u_long timer_xmtcalls
;
1272 ts
= (struct info_timer_stats
*)prepare_pkt(srcadr
, inter
, inpkt
,
1273 sizeof(struct info_timer_stats
));
1275 ts
->timereset
= htonl((u_int32
)(current_time
- timer_timereset
));
1276 ts
->alarms
= htonl((u_int32
)alarm_overflow
);
1277 ts
->overflows
= htonl((u_int32
)timer_overflows
);
1278 ts
->xmtcalls
= htonl((u_int32
)timer_xmtcalls
);
1286 * loop_info - return the current state of the loop filter
1290 struct sockaddr_storage
*srcadr
,
1291 struct interface
*inter
,
1292 struct req_pkt
*inpkt
1295 register struct info_loop
*li
;
1299 * Importations from the loop filter module
1301 extern double last_offset
;
1302 extern double drift_comp
;
1303 extern int tc_counter
;
1304 extern u_long sys_clocktime
;
1306 li
= (struct info_loop
*)prepare_pkt(srcadr
, inter
, inpkt
,
1307 sizeof(struct info_loop
));
1309 DTOLFP(last_offset
, <mp
);
1310 HTONL_FP(<mp
, &li
->last_offset
);
1311 DTOLFP(drift_comp
* 1e6
, <mp
);
1312 HTONL_FP(<mp
, &li
->drift_comp
);
1313 li
->compliance
= htonl((u_int32
)(tc_counter
));
1314 li
->watchdog_timer
= htonl((u_int32
)(current_time
- sys_clocktime
));
1322 * do_conf - add a peer to the configuration list
1326 struct sockaddr_storage
*srcadr
,
1327 struct interface
*inter
,
1328 struct req_pkt
*inpkt
1331 static u_long soonest_ifrescan_time
= 0;
1334 struct conf_peer
*cp
;
1335 struct conf_peer temp_cp
;
1336 struct sockaddr_storage peeraddr
;
1337 struct sockaddr_in tmp_clock
;
1340 * Do a check of everything to see that it looks
1341 * okay. If not, complain about it. Note we are
1344 items
= INFO_NITEMS(inpkt
->err_nitems
);
1345 cp
= (struct conf_peer
*)inpkt
->data
;
1346 memset(&temp_cp
, 0, sizeof(struct conf_peer
));
1347 memcpy(&temp_cp
, (char *)cp
, INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1349 while (items
-- > 0 && !fl
) {
1350 if (((temp_cp
.version
) > NTP_VERSION
)
1351 || ((temp_cp
.version
) < NTP_OLDVERSION
))
1353 if (temp_cp
.hmode
!= MODE_ACTIVE
1354 && temp_cp
.hmode
!= MODE_CLIENT
1355 && temp_cp
.hmode
!= MODE_BROADCAST
)
1357 if (temp_cp
.flags
& ~(CONF_FLAG_AUTHENABLE
| CONF_FLAG_PREFER
1358 | CONF_FLAG_BURST
| CONF_FLAG_IBURST
| CONF_FLAG_SKEY
))
1360 cp
= (struct conf_peer
*)
1361 ((char *)cp
+ INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1365 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
1370 * Looks okay, try it out
1372 items
= INFO_NITEMS(inpkt
->err_nitems
);
1373 cp
= (struct conf_peer
*)inpkt
->data
;
1375 while (items
-- > 0) {
1376 memset(&temp_cp
, 0, sizeof(struct conf_peer
));
1377 memcpy(&temp_cp
, (char *)cp
, INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1378 memset((char *)&peeraddr
, 0, sizeof(struct sockaddr_storage
));
1381 if (temp_cp
.flags
& CONF_FLAG_AUTHENABLE
)
1382 fl
|= FLAG_AUTHENABLE
;
1383 if (temp_cp
.flags
& CONF_FLAG_PREFER
)
1385 if (temp_cp
.flags
& CONF_FLAG_BURST
)
1387 if (temp_cp
.flags
& CONF_FLAG_IBURST
)
1389 if (temp_cp
.flags
& CONF_FLAG_SKEY
)
1392 if (client_v6_capable
&& temp_cp
.v6_flag
!= 0) {
1393 peeraddr
.ss_family
= AF_INET6
;
1394 GET_INADDR6(peeraddr
) = temp_cp
.peeraddr6
;
1396 peeraddr
.ss_family
= AF_INET
;
1397 GET_INADDR(peeraddr
) = temp_cp
.peeraddr
;
1399 * Make sure the address is valid
1401 tmp_clock
= *CAST_V4(peeraddr
);
1404 !ISREFCLOCKADR(&tmp_clock
) &&
1406 ISBADADR(&tmp_clock
)) {
1407 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
1412 NSRCPORT(&peeraddr
) = htons(NTP_PORT
);
1413 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
1414 peeraddr
.ss_len
= SOCKLEN(&peeraddr
);
1417 /* XXX W2DO? minpoll/maxpoll arguments ??? */
1418 if (peer_config(&peeraddr
, (struct interface
*)0,
1419 temp_cp
.hmode
, temp_cp
.version
, temp_cp
.minpoll
,
1420 temp_cp
.maxpoll
, fl
, temp_cp
.ttl
, temp_cp
.keyid
,
1422 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
1427 * ntp_intres.c uses REQ_CONFIG/doconf() to add each
1428 * server after its name is resolved. If we have been
1429 * disconnected from the network, it may notice the
1430 * network has returned and add the first server while
1431 * the relevant interface is still disabled, awaiting
1432 * the next interface rescan. To get things moving
1433 * more quickly, trigger an interface scan now, except
1434 * if we have done so in the last half minute.
1436 if (soonest_ifrescan_time
< current_time
) {
1437 soonest_ifrescan_time
= current_time
+ 30;
1438 timer_interfacetimeout(current_time
);
1439 DPRINTF(1, ("do_conf triggering interface rescan\n"));
1442 cp
= (struct conf_peer
*)
1443 ((char *)cp
+ INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1446 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
1452 * dns_a - Snarf DNS info for an association ID
1456 struct sockaddr_storage
*srcadr
,
1457 struct interface
*inter
,
1458 struct req_pkt
*inpkt
1461 register struct info_dns_assoc
*dp
;
1463 struct sockaddr_in peeraddr
;
1466 * Do a check of everything to see that it looks
1467 * okay. If not, complain about it. Note we are
1470 items
= INFO_NITEMS(inpkt
->err_nitems
);
1471 dp
= (struct info_dns_assoc
*)inpkt
->data
;
1474 * Looks okay, try it out
1476 items
= INFO_NITEMS(inpkt
->err_nitems
);
1477 dp
= (struct info_dns_assoc
*)inpkt
->data
;
1478 memset((char *)&peeraddr
, 0, sizeof(struct sockaddr_in
));
1479 peeraddr
.sin_family
= AF_INET
;
1480 peeraddr
.sin_port
= htons(NTP_PORT
);
1483 * Make sure the address is valid
1487 !ISREFCLOCKADR(&peeraddr
) &&
1489 ISBADADR(&peeraddr
)) {
1491 msyslog(LOG_ERR
, "dns_a: !ISREFCLOCK && ISBADADR");
1493 msyslog(LOG_ERR
, "dns_a: ISBADADR");
1495 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
1499 while (items
-- > 0) {
1505 associd
= dp
->associd
;
1506 peer
= findpeerbyassoc(associd
);
1507 if (peer
== 0 || peer
->flags
& FLAG_REFCLOCK
) {
1508 msyslog(LOG_ERR
, "dns_a: %s",
1511 : "peer->flags & FLAG_REFCLOCK");
1514 peeraddr
.sin_addr
.s_addr
= dp
->peeraddr
;
1515 for (hnl
= 0; dp
->hostname
[hnl
] && hnl
< sizeof dp
->hostname
; ++hnl
) ;
1516 if (hnl
>= sizeof dp
->hostname
) {
1517 msyslog(LOG_ERR
, "dns_a: hnl (%ld) >= %ld",
1518 (long)hnl
, (long)sizeof dp
->hostname
);
1522 msyslog(LOG_INFO
, "dns_a: <%s> for %s, AssocID %d, bogon %d",
1524 stoa((struct sockaddr_storage
*)&peeraddr
), associd
,
1528 /* If it didn't work */
1529 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
1534 crypto_public(peer
, dp
->hostname
);
1542 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
1547 * do_unconf - remove a peer from the configuration list
1551 struct sockaddr_storage
*srcadr
,
1552 struct interface
*inter
,
1553 struct req_pkt
*inpkt
1556 register struct conf_unpeer
*cp
;
1557 struct conf_unpeer temp_cp
;
1559 register struct peer
*peer
;
1560 struct sockaddr_storage peeraddr
;
1564 * This is a bit unstructured, but I like to be careful.
1565 * We check to see that every peer exists and is actually
1566 * configured. If so, we remove them. If not, we return
1569 items
= INFO_NITEMS(inpkt
->err_nitems
);
1570 cp
= (struct conf_unpeer
*)inpkt
->data
;
1573 while (items
-- > 0 && !bad
) {
1574 memset(&temp_cp
, 0, sizeof(temp_cp
));
1575 memset(&peeraddr
, 0, sizeof(peeraddr
));
1576 memcpy(&temp_cp
, cp
, INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1577 if (client_v6_capable
&& temp_cp
.v6_flag
!= 0) {
1578 peeraddr
.ss_family
= AF_INET6
;
1579 GET_INADDR6(peeraddr
) = temp_cp
.peeraddr6
;
1581 peeraddr
.ss_family
= AF_INET
;
1582 GET_INADDR(peeraddr
) = temp_cp
.peeraddr
;
1584 NSRCPORT(&peeraddr
) = htons(NTP_PORT
);
1585 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
1586 peeraddr
.ss_len
= SOCKLEN(&peeraddr
);
1589 peer
= (struct peer
*)0;
1592 printf("searching for %s\n", stoa(&peeraddr
));
1595 peer
= findexistingpeer(&peeraddr
, peer
, -1);
1596 if (peer
== (struct peer
*)0)
1598 if (peer
->flags
& FLAG_CONFIG
)
1603 cp
= (struct conf_unpeer
*)
1604 ((char *)cp
+ INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1608 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
1613 * Now do it in earnest.
1616 items
= INFO_NITEMS(inpkt
->err_nitems
);
1617 cp
= (struct conf_unpeer
*)inpkt
->data
;
1618 while (items
-- > 0) {
1619 memset(&temp_cp
, 0, sizeof(temp_cp
));
1620 memset(&peeraddr
, 0, sizeof(peeraddr
));
1621 memcpy(&temp_cp
, cp
, INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1622 if (client_v6_capable
&& temp_cp
.v6_flag
!= 0) {
1623 peeraddr
.ss_family
= AF_INET6
;
1624 GET_INADDR6(peeraddr
) = temp_cp
.peeraddr6
;
1626 peeraddr
.ss_family
= AF_INET
;
1627 GET_INADDR(peeraddr
) = temp_cp
.peeraddr
;
1629 NSRCPORT(&peeraddr
) = htons(NTP_PORT
);
1630 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
1631 peeraddr
.ss_len
= SOCKLEN(&peeraddr
);
1633 peer_unconfig(&peeraddr
, (struct interface
*)0, -1);
1634 cp
= (struct conf_unpeer
*)
1635 ((char *)cp
+ INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1638 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
1643 * set_sys_flag - set system flags
1647 struct sockaddr_storage
*srcadr
,
1648 struct interface
*inter
,
1649 struct req_pkt
*inpkt
1652 setclr_flags(srcadr
, inter
, inpkt
, 1);
1657 * clr_sys_flag - clear system flags
1661 struct sockaddr_storage
*srcadr
,
1662 struct interface
*inter
,
1663 struct req_pkt
*inpkt
1666 setclr_flags(srcadr
, inter
, inpkt
, 0);
1671 * setclr_flags - do the grunge work of flag setting/clearing
1675 struct sockaddr_storage
*srcadr
,
1676 struct interface
*inter
,
1677 struct req_pkt
*inpkt
,
1681 register u_int flags
;
1682 int prev_kern_enable
;
1684 prev_kern_enable
= kern_enable
;
1685 if (INFO_NITEMS(inpkt
->err_nitems
) > 1) {
1686 msyslog(LOG_ERR
, "setclr_flags: err_nitems > 1");
1687 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
1691 flags
= ((struct conf_sys_flags
*)inpkt
->data
)->flags
;
1692 flags
= ntohl(flags
);
1694 if (flags
& ~(SYS_FLAG_BCLIENT
| SYS_FLAG_PPS
|
1695 SYS_FLAG_NTP
| SYS_FLAG_KERNEL
| SYS_FLAG_MONITOR
|
1696 SYS_FLAG_FILEGEN
| SYS_FLAG_AUTH
| SYS_FLAG_CAL
)) {
1697 msyslog(LOG_ERR
, "setclr_flags: extra flags: %#x",
1698 flags
& ~(SYS_FLAG_BCLIENT
| SYS_FLAG_PPS
|
1699 SYS_FLAG_NTP
| SYS_FLAG_KERNEL
|
1700 SYS_FLAG_MONITOR
| SYS_FLAG_FILEGEN
|
1701 SYS_FLAG_AUTH
| SYS_FLAG_CAL
));
1702 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
1706 if (flags
& SYS_FLAG_BCLIENT
)
1707 proto_config(PROTO_BROADCLIENT
, set
, 0., NULL
);
1708 if (flags
& SYS_FLAG_PPS
)
1709 proto_config(PROTO_PPS
, set
, 0., NULL
);
1710 if (flags
& SYS_FLAG_NTP
)
1711 proto_config(PROTO_NTP
, set
, 0., NULL
);
1712 if (flags
& SYS_FLAG_KERNEL
)
1713 proto_config(PROTO_KERNEL
, set
, 0., NULL
);
1714 if (flags
& SYS_FLAG_MONITOR
)
1715 proto_config(PROTO_MONITOR
, set
, 0., NULL
);
1716 if (flags
& SYS_FLAG_FILEGEN
)
1717 proto_config(PROTO_FILEGEN
, set
, 0., NULL
);
1718 if (flags
& SYS_FLAG_AUTH
)
1719 proto_config(PROTO_AUTHENTICATE
, set
, 0., NULL
);
1720 if (flags
& SYS_FLAG_CAL
)
1721 proto_config(PROTO_CAL
, set
, 0., NULL
);
1722 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
1724 /* Reset the kernel ntp parameters if the kernel flag changed. */
1725 if (prev_kern_enable
&& !kern_enable
)
1726 loop_config(LOOP_KERN_CLEAR
, 0.0);
1727 if (!prev_kern_enable
&& kern_enable
)
1728 loop_config(LOOP_DRIFTCOMP
, drift_comp
);
1733 * list_restrict - return the restrict list
1737 struct sockaddr_storage
*srcadr
,
1738 struct interface
*inter
,
1739 struct req_pkt
*inpkt
1742 register struct info_restrict
*ir
;
1743 register struct restrictlist
*rl
;
1744 register struct restrictlist6
*rl6
;
1748 printf("wants restrict list summary\n");
1751 ir
= (struct info_restrict
*)prepare_pkt(srcadr
, inter
, inpkt
,
1752 v6sizeof(struct info_restrict
));
1754 for (rl
= restrictlist
; rl
!= 0 && ir
!= 0; rl
= rl
->next
) {
1755 ir
->addr
= htonl(rl
->addr
);
1756 if (client_v6_capable
)
1758 ir
->mask
= htonl(rl
->mask
);
1759 ir
->count
= htonl((u_int32
)rl
->count
);
1760 ir
->flags
= htons(rl
->flags
);
1761 ir
->mflags
= htons(rl
->mflags
);
1762 ir
= (struct info_restrict
*)more_pkt();
1764 if (client_v6_capable
)
1765 for (rl6
= restrictlist6
; rl6
!= 0 && ir
!= 0; rl6
= rl6
->next
) {
1766 ir
->addr6
= rl6
->addr6
;
1767 ir
->mask6
= rl6
->mask6
;
1769 ir
->count
= htonl((u_int32
)rl6
->count
);
1770 ir
->flags
= htons(rl6
->flags
);
1771 ir
->mflags
= htons(rl6
->mflags
);
1772 ir
= (struct info_restrict
*)more_pkt();
1780 * do_resaddflags - add flags to a restrict entry (or create one)
1784 struct sockaddr_storage
*srcadr
,
1785 struct interface
*inter
,
1786 struct req_pkt
*inpkt
1789 do_restrict(srcadr
, inter
, inpkt
, RESTRICT_FLAGS
);
1795 * do_ressubflags - remove flags from a restrict entry
1799 struct sockaddr_storage
*srcadr
,
1800 struct interface
*inter
,
1801 struct req_pkt
*inpkt
1804 do_restrict(srcadr
, inter
, inpkt
, RESTRICT_UNFLAG
);
1809 * do_unrestrict - remove a restrict entry from the list
1813 struct sockaddr_storage
*srcadr
,
1814 struct interface
*inter
,
1815 struct req_pkt
*inpkt
1818 do_restrict(srcadr
, inter
, inpkt
, RESTRICT_REMOVE
);
1826 * do_restrict - do the dirty stuff of dealing with restrictions
1830 struct sockaddr_storage
*srcadr
,
1831 struct interface
*inter
,
1832 struct req_pkt
*inpkt
,
1836 register struct conf_restrict
*cr
;
1838 struct sockaddr_storage matchaddr
;
1839 struct sockaddr_storage matchmask
;
1843 * Do a check of the flags to make sure that only
1844 * the NTPPORT flag is set, if any. If not, complain
1845 * about it. Note we are very picky here.
1847 items
= INFO_NITEMS(inpkt
->err_nitems
);
1848 cr
= (struct conf_restrict
*)inpkt
->data
;
1851 cr
->flags
= ntohs(cr
->flags
);
1852 cr
->mflags
= ntohs(cr
->mflags
);
1853 while (items
-- > 0 && !bad
) {
1854 if (cr
->mflags
& ~(RESM_NTPONLY
))
1856 if (cr
->flags
& ~(RES_ALLFLAGS
))
1858 if (cr
->mask
!= htonl(INADDR_ANY
)) {
1859 if (client_v6_capable
&& cr
->v6_flag
!= 0) {
1860 if (IN6_IS_ADDR_UNSPECIFIED(&cr
->addr6
))
1863 if (cr
->addr
== htonl(INADDR_ANY
))
1866 cr
= (struct conf_restrict
*)((char *)cr
+
1867 INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
1871 msyslog(LOG_ERR
, "do_restrict: bad = %#x", bad
);
1872 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
1877 * Looks okay, try it out
1879 items
= INFO_NITEMS(inpkt
->err_nitems
);
1880 cr
= (struct conf_restrict
*)inpkt
->data
;
1881 memset((char *)&matchaddr
, 0, sizeof(struct sockaddr_storage
));
1882 memset((char *)&matchmask
, 0, sizeof(struct sockaddr_storage
));
1884 while (items
-- > 0) {
1885 if (client_v6_capable
&& cr
->v6_flag
!= 0) {
1886 GET_INADDR6(matchaddr
) = cr
->addr6
;
1887 GET_INADDR6(matchmask
) = cr
->mask6
;
1888 matchaddr
.ss_family
= AF_INET6
;
1889 matchmask
.ss_family
= AF_INET6
;
1891 GET_INADDR(matchaddr
) = cr
->addr
;
1892 GET_INADDR(matchmask
) = cr
->mask
;
1893 matchaddr
.ss_family
= AF_INET
;
1894 matchmask
.ss_family
= AF_INET
;
1896 hack_restrict(op
, &matchaddr
, &matchmask
, cr
->mflags
,
1901 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
1906 * mon_getlist - return monitor data
1910 struct sockaddr_storage
*srcadr
,
1911 struct interface
*inter
,
1912 struct req_pkt
*inpkt
1915 register struct info_monitor
*im
;
1916 register struct mon_data
*md
;
1917 extern struct mon_data mon_mru_list
;
1918 extern int mon_enabled
;
1922 printf("wants monitor 0 list\n");
1925 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
1928 im
= (struct info_monitor
*)prepare_pkt(srcadr
, inter
, inpkt
,
1929 v6sizeof(struct info_monitor
));
1930 for (md
= mon_mru_list
.mru_next
; md
!= &mon_mru_list
&& im
!= 0;
1931 md
= md
->mru_next
) {
1932 im
->lasttime
= htonl((u_int32
)md
->avg_interval
);
1933 im
->firsttime
= htonl((u_int32
)(current_time
- md
->lasttime
));
1934 im
->lastdrop
= htonl((u_int32
)md
->drop_count
);
1935 im
->count
= htonl((u_int32
)(md
->count
));
1936 if (md
->rmtadr
.ss_family
== AF_INET6
) {
1937 if (!client_v6_capable
)
1939 im
->addr6
= GET_INADDR6(md
->rmtadr
);
1942 im
->addr
= GET_INADDR(md
->rmtadr
);
1943 if (client_v6_capable
)
1946 im
->port
= md
->rmtport
;
1947 im
->mode
= md
->mode
;
1948 im
->version
= md
->version
;
1949 im
= (struct info_monitor
*)more_pkt();
1955 * mon_getlist - return monitor data
1959 struct sockaddr_storage
*srcadr
,
1960 struct interface
*inter
,
1961 struct req_pkt
*inpkt
1964 register struct info_monitor_1
*im
;
1965 register struct mon_data
*md
;
1966 extern struct mon_data mon_mru_list
;
1967 extern int mon_enabled
;
1970 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
1973 im
= (struct info_monitor_1
*)prepare_pkt(srcadr
, inter
, inpkt
,
1974 v6sizeof(struct info_monitor_1
));
1975 for (md
= mon_mru_list
.mru_next
; md
!= &mon_mru_list
&& im
!= 0;
1976 md
= md
->mru_next
) {
1977 im
->lasttime
= htonl((u_int32
)md
->avg_interval
);
1978 im
->firsttime
= htonl((u_int32
)(current_time
- md
->lasttime
));
1979 im
->lastdrop
= htonl((u_int32
)md
->drop_count
);
1980 im
->count
= htonl((u_int32
)md
->count
);
1981 if (md
->rmtadr
.ss_family
== AF_INET6
) {
1982 if (!client_v6_capable
)
1984 im
->addr6
= GET_INADDR6(md
->rmtadr
);
1986 im
->daddr6
= GET_INADDR6(md
->interface
->sin
);
1988 im
->addr
= GET_INADDR(md
->rmtadr
);
1989 if (client_v6_capable
)
1991 im
->daddr
= (md
->cast_flags
== MDF_BCAST
)
1992 ? GET_INADDR(md
->interface
->bcast
)
1994 ? (GET_INADDR(md
->interface
->sin
)
1995 ? GET_INADDR(md
->interface
->sin
)
1996 : GET_INADDR(md
->interface
->bcast
))
1999 im
->flags
= htonl(md
->cast_flags
);
2000 im
->port
= md
->rmtport
;
2001 im
->mode
= md
->mode
;
2002 im
->version
= md
->version
;
2003 im
= (struct info_monitor_1
*)more_pkt();
2009 * Module entry points and the flags they correspond with
2011 struct reset_entry
{
2012 int flag
; /* flag this corresponds to */
2013 void (*handler
) P((void)); /* routine to handle request */
2016 struct reset_entry reset_entries
[] = {
2017 { RESET_FLAG_ALLPEERS
, peer_all_reset
},
2018 { RESET_FLAG_IO
, io_clr_stats
},
2019 { RESET_FLAG_SYS
, proto_clr_stats
},
2020 { RESET_FLAG_MEM
, peer_clr_stats
},
2021 { RESET_FLAG_TIMER
, timer_clr_stats
},
2022 { RESET_FLAG_AUTH
, reset_auth_stats
},
2023 { RESET_FLAG_CTL
, ctl_clr_stats
},
2028 * reset_stats - reset statistic counters here and there
2032 struct sockaddr_storage
*srcadr
,
2033 struct interface
*inter
,
2034 struct req_pkt
*inpkt
2038 struct reset_entry
*rent
;
2040 if (INFO_NITEMS(inpkt
->err_nitems
) > 1) {
2041 msyslog(LOG_ERR
, "reset_stats: err_nitems > 1");
2042 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
2046 flags
= ((struct reset_flags
*)inpkt
->data
)->flags
;
2047 flags
= ntohl(flags
);
2049 if (flags
& ~RESET_ALLFLAGS
) {
2050 msyslog(LOG_ERR
, "reset_stats: reset leaves %#lx",
2051 flags
& ~RESET_ALLFLAGS
);
2052 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
2056 for (rent
= reset_entries
; rent
->flag
!= 0; rent
++) {
2057 if (flags
& rent
->flag
)
2060 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2065 * reset_peer - clear a peer's statistics
2069 struct sockaddr_storage
*srcadr
,
2070 struct interface
*inter
,
2071 struct req_pkt
*inpkt
2074 register struct conf_unpeer
*cp
;
2076 register struct peer
*peer
;
2077 struct sockaddr_storage peeraddr
;
2081 * We check first to see that every peer exists. If not,
2082 * we return an error.
2085 items
= INFO_NITEMS(inpkt
->err_nitems
);
2086 cp
= (struct conf_unpeer
*)inpkt
->data
;
2089 while (items
-- > 0 && !bad
) {
2090 memset((char *)&peeraddr
, 0, sizeof(peeraddr
));
2091 if (client_v6_capable
&& cp
->v6_flag
!= 0) {
2092 GET_INADDR6(peeraddr
) = cp
->peeraddr6
;
2093 peeraddr
.ss_family
= AF_INET6
;
2095 GET_INADDR(peeraddr
) = cp
->peeraddr
;
2096 peeraddr
.ss_family
= AF_INET
;
2098 NSRCPORT(&peeraddr
) = htons(NTP_PORT
);
2099 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2100 peeraddr
.ss_len
= SOCKLEN(&peeraddr
);
2102 peer
= findexistingpeer(&peeraddr
, (struct peer
*)0, -1);
2103 if (peer
== (struct peer
*)0)
2105 cp
= (struct conf_unpeer
*)((char *)cp
+
2106 INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
2110 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2115 * Now do it in earnest.
2118 items
= INFO_NITEMS(inpkt
->err_nitems
);
2119 cp
= (struct conf_unpeer
*)inpkt
->data
;
2120 while (items
-- > 0) {
2121 memset((char *)&peeraddr
, 0, sizeof(peeraddr
));
2122 if (client_v6_capable
&& cp
->v6_flag
!= 0) {
2123 GET_INADDR6(peeraddr
) = cp
->peeraddr6
;
2124 peeraddr
.ss_family
= AF_INET6
;
2126 GET_INADDR(peeraddr
) = cp
->peeraddr
;
2127 peeraddr
.ss_family
= AF_INET
;
2129 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2130 peeraddr
.ss_len
= SOCKLEN(&peeraddr
);
2132 peer
= findexistingpeer(&peeraddr
, (struct peer
*)0, -1);
2135 peer
= findexistingpeer(&peeraddr
, (struct peer
*)peer
, -1);
2137 cp
= (struct conf_unpeer
*)((char *)cp
+
2138 INFO_ITEMSIZE(inpkt
->mbz_itemsize
));
2141 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2146 * do_key_reread - reread the encryption key file
2150 struct sockaddr_storage
*srcadr
,
2151 struct interface
*inter
,
2152 struct req_pkt
*inpkt
2156 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2161 * trust_key - make one or more keys trusted
2165 struct sockaddr_storage
*srcadr
,
2166 struct interface
*inter
,
2167 struct req_pkt
*inpkt
2170 do_trustkey(srcadr
, inter
, inpkt
, 1);
2175 * untrust_key - make one or more keys untrusted
2179 struct sockaddr_storage
*srcadr
,
2180 struct interface
*inter
,
2181 struct req_pkt
*inpkt
2184 do_trustkey(srcadr
, inter
, inpkt
, 0);
2189 * do_trustkey - make keys either trustable or untrustable
2193 struct sockaddr_storage
*srcadr
,
2194 struct interface
*inter
,
2195 struct req_pkt
*inpkt
,
2199 register u_long
*kp
;
2202 items
= INFO_NITEMS(inpkt
->err_nitems
);
2203 kp
= (u_long
*)inpkt
->data
;
2204 while (items
-- > 0) {
2205 authtrust(*kp
, trust
);
2209 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2214 * get_auth_info - return some stats concerning the authentication module
2218 struct sockaddr_storage
*srcadr
,
2219 struct interface
*inter
,
2220 struct req_pkt
*inpkt
2223 register struct info_auth
*ia
;
2226 * Importations from the authentication module
2228 extern u_long authnumkeys
;
2229 extern int authnumfreekeys
;
2230 extern u_long authkeylookups
;
2231 extern u_long authkeynotfound
;
2232 extern u_long authencryptions
;
2233 extern u_long authdecryptions
;
2234 extern u_long authkeyuncached
;
2235 extern u_long authkeyexpired
;
2237 ia
= (struct info_auth
*)prepare_pkt(srcadr
, inter
, inpkt
,
2238 sizeof(struct info_auth
));
2240 ia
->numkeys
= htonl((u_int32
)authnumkeys
);
2241 ia
->numfreekeys
= htonl((u_int32
)authnumfreekeys
);
2242 ia
->keylookups
= htonl((u_int32
)authkeylookups
);
2243 ia
->keynotfound
= htonl((u_int32
)authkeynotfound
);
2244 ia
->encryptions
= htonl((u_int32
)authencryptions
);
2245 ia
->decryptions
= htonl((u_int32
)authdecryptions
);
2246 ia
->keyuncached
= htonl((u_int32
)authkeyuncached
);
2247 ia
->expired
= htonl((u_int32
)authkeyexpired
);
2248 ia
->timereset
= htonl((u_int32
)(current_time
- auth_timereset
));
2257 * reset_auth_stats - reset the authentication stat counters. Done here
2258 * to keep ntp-isms out of the authentication module
2261 reset_auth_stats(void)
2264 * Importations from the authentication module
2266 extern u_long authkeylookups
;
2267 extern u_long authkeynotfound
;
2268 extern u_long authencryptions
;
2269 extern u_long authdecryptions
;
2270 extern u_long authkeyuncached
;
2273 authkeynotfound
= 0;
2274 authencryptions
= 0;
2275 authdecryptions
= 0;
2276 authkeyuncached
= 0;
2277 auth_timereset
= current_time
;
2282 * req_get_traps - return information about current trap holders
2286 struct sockaddr_storage
*srcadr
,
2287 struct interface
*inter
,
2288 struct req_pkt
*inpkt
2291 register struct info_trap
*it
;
2292 register struct ctl_trap
*tr
;
2296 * Imported from the control module
2298 extern struct ctl_trap ctl_trap
[];
2299 extern int num_ctl_traps
;
2301 if (num_ctl_traps
== 0) {
2302 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2306 it
= (struct info_trap
*)prepare_pkt(srcadr
, inter
, inpkt
,
2307 v6sizeof(struct info_trap
));
2309 for (i
= 0, tr
= ctl_trap
; i
< CTL_MAXTRAPS
; i
++, tr
++) {
2310 if (tr
->tr_flags
& TRAP_INUSE
) {
2311 if (tr
->tr_addr
.ss_family
== AF_INET
) {
2312 if (tr
->tr_localaddr
== any_interface
)
2313 it
->local_address
= 0;
2316 = GET_INADDR(tr
->tr_localaddr
->sin
);
2317 it
->trap_address
= GET_INADDR(tr
->tr_addr
);
2318 if (client_v6_capable
)
2321 if (!client_v6_capable
)
2324 = GET_INADDR6(tr
->tr_localaddr
->sin
);
2325 it
->trap_address6
= GET_INADDR6(tr
->tr_addr
);
2328 it
->trap_port
= NSRCPORT(&tr
->tr_addr
);
2329 it
->sequence
= htons(tr
->tr_sequence
);
2330 it
->settime
= htonl((u_int32
)(current_time
- tr
->tr_settime
));
2331 it
->origtime
= htonl((u_int32
)(current_time
- tr
->tr_origtime
));
2332 it
->resets
= htonl((u_int32
)tr
->tr_resets
);
2333 it
->flags
= htonl((u_int32
)tr
->tr_flags
);
2334 it
= (struct info_trap
*)more_pkt();
2342 * req_set_trap - configure a trap
2346 struct sockaddr_storage
*srcadr
,
2347 struct interface
*inter
,
2348 struct req_pkt
*inpkt
2351 do_setclr_trap(srcadr
, inter
, inpkt
, 1);
2357 * req_clr_trap - unconfigure a trap
2361 struct sockaddr_storage
*srcadr
,
2362 struct interface
*inter
,
2363 struct req_pkt
*inpkt
2366 do_setclr_trap(srcadr
, inter
, inpkt
, 0);
2372 * do_setclr_trap - do the grunge work of (un)configuring a trap
2376 struct sockaddr_storage
*srcadr
,
2377 struct interface
*inter
,
2378 struct req_pkt
*inpkt
,
2382 register struct conf_trap
*ct
;
2383 register struct interface
*linter
;
2385 struct sockaddr_storage laddr
;
2388 * Prepare sockaddr_storage structure
2390 memset((char *)&laddr
, 0, sizeof laddr
);
2391 laddr
.ss_family
= srcadr
->ss_family
;
2392 NSRCPORT(&laddr
) = ntohs(NTP_PORT
);
2395 * Restrict ourselves to one item only. This eliminates
2396 * the error reporting problem.
2398 if (INFO_NITEMS(inpkt
->err_nitems
) > 1) {
2399 msyslog(LOG_ERR
, "do_setclr_trap: err_nitems > 1");
2400 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
2403 ct
= (struct conf_trap
*)inpkt
->data
;
2406 * Look for the local interface. If none, use the default.
2408 if (ct
->local_address
== 0) {
2409 linter
= any_interface
;
2411 if (laddr
.ss_family
== AF_INET
)
2412 GET_INADDR(laddr
) = ct
->local_address
;
2414 GET_INADDR6(laddr
) = ct
->local_address6
;
2415 linter
= findinterface(&laddr
);
2416 if (linter
== NULL
) {
2417 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2422 if (laddr
.ss_family
== AF_INET
)
2423 GET_INADDR(laddr
) = ct
->trap_address
;
2425 GET_INADDR6(laddr
) = ct
->trap_address6
;
2426 if (ct
->trap_port
!= 0)
2427 NSRCPORT(&laddr
) = ct
->trap_port
;
2429 NSRCPORT(&laddr
) = htons(TRAPPORT
);
2432 res
= ctlsettrap(&laddr
, linter
, 0,
2433 INFO_VERSION(inpkt
->rm_vn_mode
));
2435 res
= ctlclrtrap(&laddr
, linter
, 0);
2439 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2441 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2449 * set_request_keyid - set the keyid used to authenticate requests
2453 struct sockaddr_storage
*srcadr
,
2454 struct interface
*inter
,
2455 struct req_pkt
*inpkt
2461 * Restrict ourselves to one item only.
2463 if (INFO_NITEMS(inpkt
->err_nitems
) > 1) {
2464 msyslog(LOG_ERR
, "set_request_keyid: err_nitems > 1");
2465 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
2469 keyid
= ntohl(*((u_int32
*)(inpkt
->data
)));
2470 info_auth_keyid
= keyid
;
2471 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2477 * set_control_keyid - set the keyid used to authenticate requests
2481 struct sockaddr_storage
*srcadr
,
2482 struct interface
*inter
,
2483 struct req_pkt
*inpkt
2487 extern keyid_t ctl_auth_keyid
;
2490 * Restrict ourselves to one item only.
2492 if (INFO_NITEMS(inpkt
->err_nitems
) > 1) {
2493 msyslog(LOG_ERR
, "set_control_keyid: err_nitems > 1");
2494 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
2498 keyid
= ntohl(*((u_int32
*)(inpkt
->data
)));
2499 ctl_auth_keyid
= keyid
;
2500 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2506 * get_ctl_stats - return some stats concerning the control message module
2510 struct sockaddr_storage
*srcadr
,
2511 struct interface
*inter
,
2512 struct req_pkt
*inpkt
2515 register struct info_control
*ic
;
2518 * Importations from the control module
2520 extern u_long ctltimereset
;
2521 extern u_long numctlreq
;
2522 extern u_long numctlbadpkts
;
2523 extern u_long numctlresponses
;
2524 extern u_long numctlfrags
;
2525 extern u_long numctlerrors
;
2526 extern u_long numctltooshort
;
2527 extern u_long numctlinputresp
;
2528 extern u_long numctlinputfrag
;
2529 extern u_long numctlinputerr
;
2530 extern u_long numctlbadoffset
;
2531 extern u_long numctlbadversion
;
2532 extern u_long numctldatatooshort
;
2533 extern u_long numctlbadop
;
2534 extern u_long numasyncmsgs
;
2536 ic
= (struct info_control
*)prepare_pkt(srcadr
, inter
, inpkt
,
2537 sizeof(struct info_control
));
2539 ic
->ctltimereset
= htonl((u_int32
)(current_time
- ctltimereset
));
2540 ic
->numctlreq
= htonl((u_int32
)numctlreq
);
2541 ic
->numctlbadpkts
= htonl((u_int32
)numctlbadpkts
);
2542 ic
->numctlresponses
= htonl((u_int32
)numctlresponses
);
2543 ic
->numctlfrags
= htonl((u_int32
)numctlfrags
);
2544 ic
->numctlerrors
= htonl((u_int32
)numctlerrors
);
2545 ic
->numctltooshort
= htonl((u_int32
)numctltooshort
);
2546 ic
->numctlinputresp
= htonl((u_int32
)numctlinputresp
);
2547 ic
->numctlinputfrag
= htonl((u_int32
)numctlinputfrag
);
2548 ic
->numctlinputerr
= htonl((u_int32
)numctlinputerr
);
2549 ic
->numctlbadoffset
= htonl((u_int32
)numctlbadoffset
);
2550 ic
->numctlbadversion
= htonl((u_int32
)numctlbadversion
);
2551 ic
->numctldatatooshort
= htonl((u_int32
)numctldatatooshort
);
2552 ic
->numctlbadop
= htonl((u_int32
)numctlbadop
);
2553 ic
->numasyncmsgs
= htonl((u_int32
)numasyncmsgs
);
2562 * get_kernel_info - get kernel pll/pps information
2566 struct sockaddr_storage
*srcadr
,
2567 struct interface
*inter
,
2568 struct req_pkt
*inpkt
2571 register struct info_kernel
*ik
;
2575 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2579 memset((char *)&ntx
, 0, sizeof(ntx
));
2580 if (ntp_adjtime(&ntx
) < 0)
2581 msyslog(LOG_ERR
, "get_kernel_info: ntp_adjtime() failed: %m");
2582 ik
= (struct info_kernel
*)prepare_pkt(srcadr
, inter
, inpkt
,
2583 sizeof(struct info_kernel
));
2588 ik
->offset
= htonl((u_int32
)ntx
.offset
);
2589 ik
->freq
= htonl((u_int32
)ntx
.freq
);
2590 ik
->maxerror
= htonl((u_int32
)ntx
.maxerror
);
2591 ik
->esterror
= htonl((u_int32
)ntx
.esterror
);
2592 ik
->status
= htons(ntx
.status
);
2593 ik
->constant
= htonl((u_int32
)ntx
.constant
);
2594 ik
->precision
= htonl((u_int32
)ntx
.precision
);
2595 ik
->tolerance
= htonl((u_int32
)ntx
.tolerance
);
2600 ik
->ppsfreq
= htonl((u_int32
)ntx
.ppsfreq
);
2601 ik
->jitter
= htonl((u_int32
)ntx
.jitter
);
2602 ik
->shift
= htons(ntx
.shift
);
2603 ik
->stabil
= htonl((u_int32
)ntx
.stabil
);
2604 ik
->jitcnt
= htonl((u_int32
)ntx
.jitcnt
);
2605 ik
->calcnt
= htonl((u_int32
)ntx
.calcnt
);
2606 ik
->errcnt
= htonl((u_int32
)ntx
.errcnt
);
2607 ik
->stbcnt
= htonl((u_int32
)ntx
.stbcnt
);
2612 #endif /* KERNEL_PLL */
2617 * get_clock_info - get info about a clock
2621 struct sockaddr_storage
*srcadr
,
2622 struct interface
*inter
,
2623 struct req_pkt
*inpkt
2626 register struct info_clock
*ic
;
2627 register u_int32
*clkaddr
;
2629 struct refclockstat clock_stat
;
2630 struct sockaddr_storage addr
;
2631 struct sockaddr_in tmp_clock
;
2634 memset((char *)&addr
, 0, sizeof addr
);
2635 addr
.ss_family
= AF_INET
;
2636 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2637 addr
.ss_len
= SOCKLEN(&addr
);
2639 NSRCPORT(&addr
) = htons(NTP_PORT
);
2640 items
= INFO_NITEMS(inpkt
->err_nitems
);
2641 clkaddr
= (u_int32
*) inpkt
->data
;
2643 ic
= (struct info_clock
*)prepare_pkt(srcadr
, inter
, inpkt
,
2644 sizeof(struct info_clock
));
2646 while (items
-- > 0) {
2647 tmp_clock
.sin_addr
.s_addr
= *clkaddr
++;
2648 CAST_V4(addr
)->sin_addr
= tmp_clock
.sin_addr
;
2649 if (!ISREFCLOCKADR(&tmp_clock
) ||
2650 findexistingpeer(&addr
, (struct peer
*)0, -1) == 0) {
2651 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2655 clock_stat
.kv_list
= (struct ctl_var
*)0;
2657 refclock_control(&addr
, (struct refclockstat
*)0, &clock_stat
);
2659 ic
->clockadr
= tmp_clock
.sin_addr
.s_addr
;
2660 ic
->type
= clock_stat
.type
;
2661 ic
->flags
= clock_stat
.flags
;
2662 ic
->lastevent
= clock_stat
.lastevent
;
2663 ic
->currentstatus
= clock_stat
.currentstatus
;
2664 ic
->polls
= htonl((u_int32
)clock_stat
.polls
);
2665 ic
->noresponse
= htonl((u_int32
)clock_stat
.noresponse
);
2666 ic
->badformat
= htonl((u_int32
)clock_stat
.badformat
);
2667 ic
->baddata
= htonl((u_int32
)clock_stat
.baddata
);
2668 ic
->timestarted
= htonl((u_int32
)clock_stat
.timereset
);
2669 DTOLFP(clock_stat
.fudgetime1
, <mp
);
2670 HTONL_FP(<mp
, &ic
->fudgetime1
);
2671 DTOLFP(clock_stat
.fudgetime2
, <mp
);
2672 HTONL_FP(<mp
, &ic
->fudgetime2
);
2673 ic
->fudgeval1
= htonl((u_int32
)clock_stat
.fudgeval1
);
2674 ic
->fudgeval2
= htonl((u_int32
)clock_stat
.fudgeval2
);
2676 free_varlist(clock_stat
.kv_list
);
2678 ic
= (struct info_clock
*)more_pkt();
2686 * set_clock_fudge - get a clock's fudge factors
2690 struct sockaddr_storage
*srcadr
,
2691 struct interface
*inter
,
2692 struct req_pkt
*inpkt
2695 register struct conf_fudge
*cf
;
2697 struct refclockstat clock_stat
;
2698 struct sockaddr_storage addr
;
2699 struct sockaddr_in tmp_clock
;
2702 memset((char *)&addr
, 0, sizeof addr
);
2703 memset((char *)&clock_stat
, 0, sizeof clock_stat
);
2704 memset((char *)&tmp_clock
, 0, sizeof tmp_clock
);
2705 items
= INFO_NITEMS(inpkt
->err_nitems
);
2706 cf
= (struct conf_fudge
*) inpkt
->data
;
2708 while (items
-- > 0) {
2709 tmp_clock
.sin_addr
.s_addr
= cf
->clockadr
;
2710 *CAST_V4(addr
) = tmp_clock
;
2711 addr
.ss_family
= AF_INET
;
2712 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2713 addr
.ss_len
= SOCKLEN(&addr
);
2715 NSRCPORT(&addr
) = htons(NTP_PORT
);
2716 if (!ISREFCLOCKADR(&tmp_clock
) ||
2717 findexistingpeer(&addr
, (struct peer
*)0, -1) == 0) {
2718 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2722 switch(ntohl(cf
->which
)) {
2724 NTOHL_FP(&cf
->fudgetime
, <mp
);
2725 LFPTOD(<mp
, clock_stat
.fudgetime1
);
2726 clock_stat
.haveflags
= CLK_HAVETIME1
;
2729 NTOHL_FP(&cf
->fudgetime
, <mp
);
2730 LFPTOD(<mp
, clock_stat
.fudgetime2
);
2731 clock_stat
.haveflags
= CLK_HAVETIME2
;
2734 clock_stat
.fudgeval1
= ntohl(cf
->fudgeval_flags
);
2735 clock_stat
.haveflags
= CLK_HAVEVAL1
;
2738 clock_stat
.fudgeval2
= ntohl(cf
->fudgeval_flags
);
2739 clock_stat
.haveflags
= CLK_HAVEVAL2
;
2742 clock_stat
.flags
= (u_char
) (ntohl(cf
->fudgeval_flags
) & 0xf);
2743 clock_stat
.haveflags
=
2744 (CLK_HAVEFLAG1
|CLK_HAVEFLAG2
|CLK_HAVEFLAG3
|CLK_HAVEFLAG4
);
2747 msyslog(LOG_ERR
, "set_clock_fudge: default!");
2748 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_FMT
);
2752 refclock_control(&addr
, &clock_stat
, (struct refclockstat
*)0);
2755 req_ack(srcadr
, inter
, inpkt
, INFO_OKAY
);
2761 * get_clkbug_info - get debugging info about a clock
2765 struct sockaddr_storage
*srcadr
,
2766 struct interface
*inter
,
2767 struct req_pkt
*inpkt
2771 register struct info_clkbug
*ic
;
2772 register u_int32
*clkaddr
;
2774 struct refclockbug bug
;
2775 struct sockaddr_storage addr
;
2776 struct sockaddr_in tmp_clock
;
2778 memset((char *)&addr
, 0, sizeof addr
);
2779 addr
.ss_family
= AF_INET
;
2780 #ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
2781 addr
.ss_len
= SOCKLEN(&addr
);
2783 NSRCPORT(&addr
) = htons(NTP_PORT
);
2784 items
= INFO_NITEMS(inpkt
->err_nitems
);
2785 clkaddr
= (u_int32
*) inpkt
->data
;
2787 ic
= (struct info_clkbug
*)prepare_pkt(srcadr
, inter
, inpkt
,
2788 sizeof(struct info_clkbug
));
2790 while (items
-- > 0) {
2791 tmp_clock
.sin_addr
.s_addr
= *clkaddr
++;
2792 GET_INADDR(addr
) = tmp_clock
.sin_addr
.s_addr
;
2793 if (!ISREFCLOCKADR(&tmp_clock
) ||
2794 findexistingpeer(&addr
, (struct peer
*)0, -1) == 0) {
2795 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2799 memset((char *)&bug
, 0, sizeof bug
);
2800 refclock_buginfo(&addr
, &bug
);
2801 if (bug
.nvalues
== 0 && bug
.ntimes
== 0) {
2802 req_ack(srcadr
, inter
, inpkt
, INFO_ERR_NODATA
);
2806 ic
->clockadr
= tmp_clock
.sin_addr
.s_addr
;
2808 if (i
> NUMCBUGVALUES
)
2810 ic
->nvalues
= (u_char
)i
;
2811 ic
->svalues
= htons((u_short
) (bug
.svalues
& ((1<<i
)-1)));
2813 ic
->values
[i
] = htonl(bug
.values
[i
]);
2816 if (i
> NUMCBUGTIMES
)
2818 ic
->ntimes
= (u_char
)i
;
2819 ic
->stimes
= htonl(bug
.stimes
);
2821 HTONL_FP(&bug
.times
[i
], &ic
->times
[i
]);
2824 ic
= (struct info_clkbug
*)more_pkt();
2831 * receiver of interface structures
2834 fill_info_if_stats(void *data
, interface_info_t
*interface_info
)
2836 struct info_if_stats
**ifsp
= (struct info_if_stats
**)data
;
2837 struct info_if_stats
*ifs
= *ifsp
;
2838 struct interface
*interface
= interface_info
->interface
;
2840 memset((char*)ifs
, 0, sizeof(*ifs
));
2842 if (interface
->sin
.ss_family
== AF_INET6
) {
2843 if (!client_v6_capable
) {
2847 memcpy((char *)&ifs
->unaddr
.addr6
, (char *)&CAST_V6(interface
->sin
)->sin6_addr
, sizeof(struct in6_addr
));
2848 memcpy((char *)&ifs
->unbcast
.addr6
, (char *)&CAST_V6(interface
->bcast
)->sin6_addr
, sizeof(struct in6_addr
));
2849 memcpy((char *)&ifs
->unmask
.addr6
, (char *)&CAST_V6(interface
->mask
)->sin6_addr
, sizeof(struct in6_addr
));
2852 memcpy((char *)&ifs
->unaddr
.addr
, (char *)&CAST_V4(interface
->sin
)->sin_addr
, sizeof(struct in_addr
));
2853 memcpy((char *)&ifs
->unbcast
.addr
, (char *)&CAST_V4(interface
->bcast
)->sin_addr
, sizeof(struct in_addr
));
2854 memcpy((char *)&ifs
->unmask
.addr
, (char *)&CAST_V4(interface
->mask
)->sin_addr
, sizeof(struct in_addr
));
2856 ifs
->v6_flag
= htonl(ifs
->v6_flag
);
2857 strcpy(ifs
->name
, interface
->name
);
2858 ifs
->family
= htons(interface
->family
);
2859 ifs
->flags
= htonl(interface
->flags
);
2860 ifs
->last_ttl
= htonl(interface
->last_ttl
);
2861 ifs
->num_mcast
= htonl(interface
->num_mcast
);
2862 ifs
->received
= htonl(interface
->received
);
2863 ifs
->sent
= htonl(interface
->sent
);
2864 ifs
->notsent
= htonl(interface
->notsent
);
2865 ifs
->scopeid
= htonl(interface
->scopeid
);
2866 ifs
->ifindex
= htonl(interface
->ifindex
);
2867 ifs
->ifnum
= htonl(interface
->ifnum
);
2868 ifs
->uptime
= htonl(current_time
- interface
->starttime
);
2869 ifs
->ignore_packets
= interface
->ignore_packets
;
2870 ifs
->peercnt
= htonl(interface
->peercnt
);
2871 ifs
->action
= interface_info
->action
;
2873 *ifsp
= (struct info_if_stats
*)more_pkt();
2877 * get_if_stats - get interface statistics
2881 struct sockaddr_storage
*srcadr
,
2882 struct interface
*inter
,
2883 struct req_pkt
*inpkt
2886 struct info_if_stats
*ifs
;
2888 DPRINTF(3, ("wants interface statistics\n"));
2890 ifs
= (struct info_if_stats
*)prepare_pkt(srcadr
, inter
, inpkt
,
2891 v6sizeof(struct info_if_stats
));
2893 interface_enumerate(fill_info_if_stats
, &ifs
);
2900 struct sockaddr_storage
*srcadr
,
2901 struct interface
*inter
,
2902 struct req_pkt
*inpkt
2905 struct info_if_stats
*ifs
;
2907 DPRINTF(3, ("wants interface reload\n"));
2909 ifs
= (struct info_if_stats
*)prepare_pkt(srcadr
, inter
, inpkt
,
2910 v6sizeof(struct info_if_stats
));
2912 interface_update(fill_info_if_stats
, &ifs
);