| @@ -1,2950 +1,2853 @@ | | | @@ -1,2950 +1,2853 @@ |
1 | /* $NetBSD: ntp_request.c,v 1.7 2012/02/01 22:48:15 kardel Exp $ */ | | 1 | /* $NetBSD: ntp_request.c,v 1.7.16.1 2014/01/06 19:12:22 bouyer Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * ntp_request.c - respond to information requests | | 4 | * ntp_request.c - respond to information requests |
5 | */ | | 5 | */ |
6 | | | 6 | |
7 | #ifdef HAVE_CONFIG_H | | 7 | #ifdef HAVE_CONFIG_H |
8 | # include <config.h> | | 8 | # include <config.h> |
9 | #endif | | 9 | #endif |
10 | | | 10 | |
11 | #include "ntpd.h" | | 11 | #include "ntpd.h" |
12 | #include "ntp_io.h" | | 12 | #include "ntp_io.h" |
13 | #include "ntp_request.h" | | 13 | #include "ntp_request.h" |
14 | #include "ntp_control.h" | | 14 | #include "ntp_control.h" |
15 | #include "ntp_refclock.h" | | 15 | #include "ntp_refclock.h" |
16 | #include "ntp_if.h" | | 16 | #include "ntp_if.h" |
17 | #include "ntp_stdlib.h" | | 17 | #include "ntp_stdlib.h" |
18 | #include "ntp_assert.h" | | 18 | #include "ntp_assert.h" |
19 | | | 19 | |
20 | #include <stdio.h> | | 20 | #include <stdio.h> |
21 | #include <stddef.h> | | 21 | #include <stddef.h> |
22 | #include <signal.h> | | 22 | #include <signal.h> |
23 | #ifdef HAVE_NETINET_IN_H | | 23 | #ifdef HAVE_NETINET_IN_H |
24 | #include <netinet/in.h> | | 24 | #include <netinet/in.h> |
25 | #endif | | 25 | #endif |
26 | #include <arpa/inet.h> | | 26 | #include <arpa/inet.h> |
27 | | | 27 | |
28 | #include "recvbuff.h" | | 28 | #include "recvbuff.h" |
29 | | | 29 | |
30 | #ifdef KERNEL_PLL | | 30 | #ifdef KERNEL_PLL |
31 | #include "ntp_syscall.h" | | 31 | #include "ntp_syscall.h" |
32 | #endif /* KERNEL_PLL */ | | 32 | #endif /* KERNEL_PLL */ |
33 | | | 33 | |
34 | /* | | 34 | /* |
35 | * Structure to hold request procedure information | | 35 | * Structure to hold request procedure information |
36 | */ | | 36 | */ |
37 | #define NOAUTH 0 | | 37 | #define NOAUTH 0 |
38 | #define AUTH 1 | | 38 | #define AUTH 1 |
39 | | | 39 | |
40 | #define NO_REQUEST (-1) | | 40 | #define NO_REQUEST (-1) |
41 | /* | | 41 | /* |
42 | * Because we now have v6 addresses in the messages, we need to compensate | | 42 | * Because we now have v6 addresses in the messages, we need to compensate |
43 | * for the larger size. Therefore, we introduce the alternate size to | | 43 | * for the larger size. Therefore, we introduce the alternate size to |
44 | * keep us friendly with older implementations. A little ugly. | | 44 | * keep us friendly with older implementations. A little ugly. |
45 | */ | | 45 | */ |
46 | static int client_v6_capable = 0; /* the client can handle longer messages */ | | 46 | static int client_v6_capable = 0; /* the client can handle longer messages */ |
47 | | | 47 | |
48 | #define v6sizeof(type) (client_v6_capable ? sizeof(type) : v4sizeof(type)) | | 48 | #define v6sizeof(type) (client_v6_capable ? sizeof(type) : v4sizeof(type)) |
49 | | | 49 | |
50 | struct req_proc { | | 50 | struct req_proc { |
51 | short request_code; /* defined request code */ | | 51 | short request_code; /* defined request code */ |
52 | short needs_auth; /* true when authentication needed */ | | 52 | short needs_auth; /* true when authentication needed */ |
53 | short sizeofitem; /* size of request data item (older size)*/ | | 53 | short sizeofitem; /* size of request data item (older size)*/ |
54 | short v6_sizeofitem; /* size of request data item (new size)*/ | | 54 | short v6_sizeofitem; /* size of request data item (new size)*/ |
55 | void (*handler) (sockaddr_u *, struct interface *, | | 55 | void (*handler) (sockaddr_u *, struct interface *, |
56 | struct req_pkt *); /* routine to handle request */ | | 56 | struct req_pkt *); /* routine to handle request */ |
57 | }; | | 57 | }; |
58 | | | 58 | |
59 | /* | | 59 | /* |
60 | * Universal request codes | | 60 | * Universal request codes |
61 | */ | | 61 | */ |
62 | static struct req_proc univ_codes[] = { | | 62 | static struct req_proc univ_codes[] = { |
63 | { NO_REQUEST, NOAUTH, 0, 0, NULL } | | 63 | { NO_REQUEST, NOAUTH, 0, 0, NULL } |
64 | }; | | 64 | }; |
65 | | | 65 | |
66 | static void req_ack (sockaddr_u *, struct interface *, struct req_pkt *, int); | | 66 | static void req_ack (sockaddr_u *, struct interface *, struct req_pkt *, int); |
67 | static char * prepare_pkt (sockaddr_u *, struct interface *, | | 67 | static char * prepare_pkt (sockaddr_u *, struct interface *, |
68 | struct req_pkt *, size_t); | | 68 | struct req_pkt *, size_t); |
69 | static char * more_pkt (void); | | 69 | static char * more_pkt (void); |
70 | static void flush_pkt (void); | | 70 | static void flush_pkt (void); |
71 | static void peer_list (sockaddr_u *, struct interface *, struct req_pkt *); | | 71 | static void peer_list (sockaddr_u *, struct interface *, struct req_pkt *); |
72 | static void peer_list_sum (sockaddr_u *, struct interface *, struct req_pkt *); | | 72 | static void peer_list_sum (sockaddr_u *, struct interface *, struct req_pkt *); |
73 | static void peer_info (sockaddr_u *, struct interface *, struct req_pkt *); | | 73 | static void peer_info (sockaddr_u *, struct interface *, struct req_pkt *); |
74 | static void peer_stats (sockaddr_u *, struct interface *, struct req_pkt *); | | 74 | static void peer_stats (sockaddr_u *, struct interface *, struct req_pkt *); |
75 | static void sys_info (sockaddr_u *, struct interface *, struct req_pkt *); | | 75 | static void sys_info (sockaddr_u *, struct interface *, struct req_pkt *); |
76 | static void sys_stats (sockaddr_u *, struct interface *, struct req_pkt *); | | 76 | static void sys_stats (sockaddr_u *, struct interface *, struct req_pkt *); |
77 | static void mem_stats (sockaddr_u *, struct interface *, struct req_pkt *); | | 77 | static void mem_stats (sockaddr_u *, struct interface *, struct req_pkt *); |
78 | static void io_stats (sockaddr_u *, struct interface *, struct req_pkt *); | | 78 | static void io_stats (sockaddr_u *, struct interface *, struct req_pkt *); |
79 | static void timer_stats (sockaddr_u *, struct interface *, struct req_pkt *); | | 79 | static void timer_stats (sockaddr_u *, struct interface *, struct req_pkt *); |
80 | static void loop_info (sockaddr_u *, struct interface *, struct req_pkt *); | | 80 | static void loop_info (sockaddr_u *, struct interface *, struct req_pkt *); |
81 | static void do_conf (sockaddr_u *, struct interface *, struct req_pkt *); | | 81 | static void do_conf (sockaddr_u *, struct interface *, struct req_pkt *); |
82 | static void do_unconf (sockaddr_u *, struct interface *, struct req_pkt *); | | 82 | static void do_unconf (sockaddr_u *, struct interface *, struct req_pkt *); |
83 | static void set_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *); | | 83 | static void set_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *); |
84 | static void clr_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *); | | 84 | static void clr_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *); |
85 | static void setclr_flags (sockaddr_u *, struct interface *, struct req_pkt *, u_long); | | 85 | static void setclr_flags (sockaddr_u *, struct interface *, struct req_pkt *, u_long); |
86 | static void list_restrict (sockaddr_u *, struct interface *, struct req_pkt *); | | 86 | static void list_restrict (sockaddr_u *, struct interface *, struct req_pkt *); |
87 | static void do_resaddflags (sockaddr_u *, struct interface *, struct req_pkt *); | | 87 | static void do_resaddflags (sockaddr_u *, struct interface *, struct req_pkt *); |
88 | static void do_ressubflags (sockaddr_u *, struct interface *, struct req_pkt *); | | 88 | static void do_ressubflags (sockaddr_u *, struct interface *, struct req_pkt *); |
89 | static void do_unrestrict (sockaddr_u *, struct interface *, struct req_pkt *); | | 89 | static void do_unrestrict (sockaddr_u *, struct interface *, struct req_pkt *); |
90 | static void do_restrict (sockaddr_u *, struct interface *, struct req_pkt *, int); | | 90 | static void do_restrict (sockaddr_u *, struct interface *, struct req_pkt *, int); |
91 | static void mon_getlist_0 (sockaddr_u *, struct interface *, struct req_pkt *); | | 91 | static void mon_getlist (sockaddr_u *, struct interface *, struct req_pkt *); |
92 | static void mon_getlist_1 (sockaddr_u *, struct interface *, struct req_pkt *); | | | |
93 | static void reset_stats (sockaddr_u *, struct interface *, struct req_pkt *); | | 92 | static void reset_stats (sockaddr_u *, struct interface *, struct req_pkt *); |
94 | static void reset_peer (sockaddr_u *, struct interface *, struct req_pkt *); | | 93 | static void reset_peer (sockaddr_u *, struct interface *, struct req_pkt *); |
95 | static void do_key_reread (sockaddr_u *, struct interface *, struct req_pkt *); | | 94 | static void do_key_reread (sockaddr_u *, struct interface *, struct req_pkt *); |
96 | static void trust_key (sockaddr_u *, struct interface *, struct req_pkt *); | | 95 | static void trust_key (sockaddr_u *, struct interface *, struct req_pkt *); |
97 | static void untrust_key (sockaddr_u *, struct interface *, struct req_pkt *); | | 96 | static void untrust_key (sockaddr_u *, struct interface *, struct req_pkt *); |
98 | static void do_trustkey (sockaddr_u *, struct interface *, struct req_pkt *, u_long); | | 97 | static void do_trustkey (sockaddr_u *, struct interface *, struct req_pkt *, u_long); |
99 | static void get_auth_info (sockaddr_u *, struct interface *, struct req_pkt *); | | 98 | static void get_auth_info (sockaddr_u *, struct interface *, struct req_pkt *); |
100 | static void reset_auth_stats (void); | | 99 | static void reset_auth_stats (void); |
101 | static void req_get_traps (sockaddr_u *, struct interface *, struct req_pkt *); | | 100 | static void req_get_traps (sockaddr_u *, struct interface *, struct req_pkt *); |
102 | static void req_set_trap (sockaddr_u *, struct interface *, struct req_pkt *); | | 101 | static void req_set_trap (sockaddr_u *, struct interface *, struct req_pkt *); |
103 | static void req_clr_trap (sockaddr_u *, struct interface *, struct req_pkt *); | | 102 | static void req_clr_trap (sockaddr_u *, struct interface *, struct req_pkt *); |
104 | static void do_setclr_trap (sockaddr_u *, struct interface *, struct req_pkt *, int); | | 103 | static void do_setclr_trap (sockaddr_u *, struct interface *, struct req_pkt *, int); |
105 | static void set_request_keyid (sockaddr_u *, struct interface *, struct req_pkt *); | | 104 | static void set_request_keyid (sockaddr_u *, struct interface *, struct req_pkt *); |
106 | static void set_control_keyid (sockaddr_u *, struct interface *, struct req_pkt *); | | 105 | static void set_control_keyid (sockaddr_u *, struct interface *, struct req_pkt *); |
107 | static void get_ctl_stats (sockaddr_u *, struct interface *, struct req_pkt *); | | 106 | static void get_ctl_stats (sockaddr_u *, struct interface *, struct req_pkt *); |
108 | static void get_if_stats (sockaddr_u *, struct interface *, struct req_pkt *); | | 107 | static void get_if_stats (sockaddr_u *, struct interface *, struct req_pkt *); |
109 | static void do_if_reload (sockaddr_u *, struct interface *, struct req_pkt *); | | 108 | static void do_if_reload (sockaddr_u *, struct interface *, struct req_pkt *); |
110 | #ifdef KERNEL_PLL | | 109 | #ifdef KERNEL_PLL |
111 | static void get_kernel_info (sockaddr_u *, struct interface *, struct req_pkt *); | | 110 | static void get_kernel_info (sockaddr_u *, struct interface *, struct req_pkt *); |
112 | #endif /* KERNEL_PLL */ | | 111 | #endif /* KERNEL_PLL */ |
113 | #ifdef REFCLOCK | | 112 | #ifdef REFCLOCK |
114 | static void get_clock_info (sockaddr_u *, struct interface *, struct req_pkt *); | | 113 | static void get_clock_info (sockaddr_u *, struct interface *, struct req_pkt *); |
115 | static void set_clock_fudge (sockaddr_u *, struct interface *, struct req_pkt *); | | 114 | static void set_clock_fudge (sockaddr_u *, struct interface *, struct req_pkt *); |
116 | #endif /* REFCLOCK */ | | 115 | #endif /* REFCLOCK */ |
117 | #ifdef REFCLOCK | | 116 | #ifdef REFCLOCK |
118 | static void get_clkbug_info (sockaddr_u *, struct interface *, struct req_pkt *); | | 117 | static void get_clkbug_info (sockaddr_u *, struct interface *, struct req_pkt *); |
119 | #endif /* REFCLOCK */ | | 118 | #endif /* REFCLOCK */ |
120 | | | 119 | |
121 | /* | | 120 | /* |
122 | * ntpd request codes | | 121 | * ntpd request codes |
123 | */ | | 122 | */ |
124 | static struct req_proc ntp_codes[] = { | | 123 | static struct req_proc ntp_codes[] = { |
125 | { REQ_PEER_LIST, NOAUTH, 0, 0, peer_list }, | | 124 | { REQ_PEER_LIST, NOAUTH, 0, 0, peer_list }, |
126 | { REQ_PEER_LIST_SUM, NOAUTH, 0, 0, peer_list_sum }, | | 125 | { REQ_PEER_LIST_SUM, NOAUTH, 0, 0, peer_list_sum }, |
127 | { REQ_PEER_INFO, NOAUTH, v4sizeof(struct info_peer_list), | | 126 | { REQ_PEER_INFO, NOAUTH, v4sizeof(struct info_peer_list), |
128 | sizeof(struct info_peer_list), peer_info}, | | 127 | sizeof(struct info_peer_list), peer_info}, |
129 | { REQ_PEER_STATS, NOAUTH, v4sizeof(struct info_peer_list), | | 128 | { REQ_PEER_STATS, NOAUTH, v4sizeof(struct info_peer_list), |
130 | sizeof(struct info_peer_list), peer_stats}, | | 129 | sizeof(struct info_peer_list), peer_stats}, |
131 | { REQ_SYS_INFO, NOAUTH, 0, 0, sys_info }, | | 130 | { REQ_SYS_INFO, NOAUTH, 0, 0, sys_info }, |
132 | { REQ_SYS_STATS, NOAUTH, 0, 0, sys_stats }, | | 131 | { REQ_SYS_STATS, NOAUTH, 0, 0, sys_stats }, |
133 | { REQ_IO_STATS, NOAUTH, 0, 0, io_stats }, | | 132 | { REQ_IO_STATS, NOAUTH, 0, 0, io_stats }, |
134 | { REQ_MEM_STATS, NOAUTH, 0, 0, mem_stats }, | | 133 | { REQ_MEM_STATS, NOAUTH, 0, 0, mem_stats }, |
135 | { REQ_LOOP_INFO, NOAUTH, 0, 0, loop_info }, | | 134 | { REQ_LOOP_INFO, NOAUTH, 0, 0, loop_info }, |
136 | { REQ_TIMER_STATS, NOAUTH, 0, 0, timer_stats }, | | 135 | { REQ_TIMER_STATS, NOAUTH, 0, 0, timer_stats }, |
137 | { REQ_CONFIG, AUTH, v4sizeof(struct conf_peer), | | 136 | { REQ_CONFIG, AUTH, v4sizeof(struct conf_peer), |
138 | sizeof(struct conf_peer), do_conf }, | | 137 | sizeof(struct conf_peer), do_conf }, |
139 | { REQ_UNCONFIG, AUTH, v4sizeof(struct conf_unpeer), | | 138 | { REQ_UNCONFIG, AUTH, v4sizeof(struct conf_unpeer), |
140 | sizeof(struct conf_unpeer), do_unconf }, | | 139 | sizeof(struct conf_unpeer), do_unconf }, |
141 | { REQ_SET_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags), | | 140 | { REQ_SET_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags), |
142 | sizeof(struct conf_sys_flags), set_sys_flag }, | | 141 | sizeof(struct conf_sys_flags), set_sys_flag }, |
143 | { REQ_CLR_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags), | | 142 | { REQ_CLR_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags), |
144 | sizeof(struct conf_sys_flags), clr_sys_flag }, | | 143 | sizeof(struct conf_sys_flags), clr_sys_flag }, |
145 | { REQ_GET_RESTRICT, NOAUTH, 0, 0, list_restrict }, | | 144 | { REQ_GET_RESTRICT, NOAUTH, 0, 0, list_restrict }, |
146 | { REQ_RESADDFLAGS, AUTH, v4sizeof(struct conf_restrict), | | 145 | { REQ_RESADDFLAGS, AUTH, v4sizeof(struct conf_restrict), |
147 | sizeof(struct conf_restrict), do_resaddflags }, | | 146 | sizeof(struct conf_restrict), do_resaddflags }, |
148 | { REQ_RESSUBFLAGS, AUTH, v4sizeof(struct conf_restrict), | | 147 | { REQ_RESSUBFLAGS, AUTH, v4sizeof(struct conf_restrict), |
149 | sizeof(struct conf_restrict), do_ressubflags }, | | 148 | sizeof(struct conf_restrict), do_ressubflags }, |
150 | { REQ_UNRESTRICT, AUTH, v4sizeof(struct conf_restrict), | | 149 | { REQ_UNRESTRICT, AUTH, v4sizeof(struct conf_restrict), |
151 | sizeof(struct conf_restrict), do_unrestrict }, | | 150 | sizeof(struct conf_restrict), do_unrestrict }, |
152 | { REQ_MON_GETLIST, NOAUTH, 0, 0, mon_getlist_0 }, | | 151 | { REQ_MON_GETLIST, NOAUTH, 0, 0, mon_getlist }, |
153 | { REQ_MON_GETLIST_1, NOAUTH, 0, 0, mon_getlist_1 }, | | 152 | { REQ_MON_GETLIST_1, NOAUTH, 0, 0, mon_getlist }, |
154 | { REQ_RESET_STATS, AUTH, sizeof(struct reset_flags), 0, reset_stats }, | | 153 | { REQ_RESET_STATS, AUTH, sizeof(struct reset_flags), 0, reset_stats }, |
155 | { REQ_RESET_PEER, AUTH, v4sizeof(struct conf_unpeer), | | 154 | { REQ_RESET_PEER, AUTH, v4sizeof(struct conf_unpeer), |
156 | sizeof(struct conf_unpeer), reset_peer }, | | 155 | sizeof(struct conf_unpeer), reset_peer }, |
157 | { REQ_REREAD_KEYS, AUTH, 0, 0, do_key_reread }, | | 156 | { REQ_REREAD_KEYS, AUTH, 0, 0, do_key_reread }, |
158 | { REQ_TRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), trust_key }, | | 157 | { REQ_TRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), trust_key }, |
159 | { REQ_UNTRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), untrust_key }, | | 158 | { REQ_UNTRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), untrust_key }, |
160 | { REQ_AUTHINFO, NOAUTH, 0, 0, get_auth_info }, | | 159 | { REQ_AUTHINFO, NOAUTH, 0, 0, get_auth_info }, |
161 | { REQ_TRAPS, NOAUTH, 0, 0, req_get_traps }, | | 160 | { REQ_TRAPS, NOAUTH, 0, 0, req_get_traps }, |
162 | { REQ_ADD_TRAP, AUTH, v4sizeof(struct conf_trap), | | 161 | { REQ_ADD_TRAP, AUTH, v4sizeof(struct conf_trap), |
163 | sizeof(struct conf_trap), req_set_trap }, | | 162 | sizeof(struct conf_trap), req_set_trap }, |
164 | { REQ_CLR_TRAP, AUTH, v4sizeof(struct conf_trap), | | 163 | { REQ_CLR_TRAP, AUTH, v4sizeof(struct conf_trap), |
165 | sizeof(struct conf_trap), req_clr_trap }, | | 164 | sizeof(struct conf_trap), req_clr_trap }, |
166 | { REQ_REQUEST_KEY, AUTH, sizeof(u_long), sizeof(u_long), | | 165 | { REQ_REQUEST_KEY, AUTH, sizeof(u_long), sizeof(u_long), |
167 | set_request_keyid }, | | 166 | set_request_keyid }, |
168 | { REQ_CONTROL_KEY, AUTH, sizeof(u_long), sizeof(u_long), | | 167 | { REQ_CONTROL_KEY, AUTH, sizeof(u_long), sizeof(u_long), |
169 | set_control_keyid }, | | 168 | set_control_keyid }, |
170 | { REQ_GET_CTLSTATS, NOAUTH, 0, 0, get_ctl_stats }, | | 169 | { REQ_GET_CTLSTATS, NOAUTH, 0, 0, get_ctl_stats }, |
171 | #ifdef KERNEL_PLL | | 170 | #ifdef KERNEL_PLL |
172 | { REQ_GET_KERNEL, NOAUTH, 0, 0, get_kernel_info }, | | 171 | { REQ_GET_KERNEL, NOAUTH, 0, 0, get_kernel_info }, |
173 | #endif | | 172 | #endif |
174 | #ifdef REFCLOCK | | 173 | #ifdef REFCLOCK |
175 | { REQ_GET_CLOCKINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32), | | 174 | { REQ_GET_CLOCKINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32), |
176 | get_clock_info }, | | 175 | get_clock_info }, |
177 | { REQ_SET_CLKFUDGE, AUTH, sizeof(struct conf_fudge), | | 176 | { REQ_SET_CLKFUDGE, AUTH, sizeof(struct conf_fudge), |
178 | sizeof(struct conf_fudge), set_clock_fudge }, | | 177 | sizeof(struct conf_fudge), set_clock_fudge }, |
179 | { REQ_GET_CLKBUGINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32), | | 178 | { REQ_GET_CLKBUGINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32), |
180 | get_clkbug_info }, | | 179 | get_clkbug_info }, |
181 | #endif | | 180 | #endif |
182 | { REQ_IF_STATS, AUTH, 0, 0, get_if_stats }, | | 181 | { REQ_IF_STATS, AUTH, 0, 0, get_if_stats }, |
183 | { REQ_IF_RELOAD, AUTH, 0, 0, do_if_reload }, | | 182 | { REQ_IF_RELOAD, AUTH, 0, 0, do_if_reload }, |
184 | | | 183 | |
185 | { NO_REQUEST, NOAUTH, 0, 0, 0 } | | 184 | { NO_REQUEST, NOAUTH, 0, 0, 0 } |
186 | }; | | 185 | }; |
187 | | | 186 | |
188 | | | 187 | |
189 | /* | | 188 | /* |
190 | * Authentication keyid used to authenticate requests. Zero means we | | 189 | * Authentication keyid used to authenticate requests. Zero means we |
191 | * don't allow writing anything. | | 190 | * don't allow writing anything. |
192 | */ | | 191 | */ |
193 | keyid_t info_auth_keyid; | | 192 | keyid_t info_auth_keyid; |
194 | | | 193 | |
195 | /* | | 194 | /* |
196 | * Statistic counters to keep track of requests and responses. | | 195 | * Statistic counters to keep track of requests and responses. |
197 | */ | | 196 | */ |
198 | u_long numrequests; /* number of requests we've received */ | | 197 | u_long numrequests; /* number of requests we've received */ |
199 | u_long numresppkts; /* number of resp packets sent with data */ | | 198 | u_long numresppkts; /* number of resp packets sent with data */ |
200 | | | 199 | |
201 | u_long errorcounter[INFO_ERR_AUTH+1]; /* lazy way to count errors, indexed */ | | 200 | u_long errorcounter[INFO_ERR_AUTH+1]; /* lazy way to count errors, indexed */ |
202 | /* by the error code */ | | 201 | /* by the error code */ |
203 | | | 202 | |
204 | /* | | 203 | /* |
205 | * A hack. To keep the authentication module clear of ntp-ism's, we | | 204 | * A hack. To keep the authentication module clear of ntp-ism's, we |
206 | * include a time reset variable for its stats here. | | 205 | * include a time reset variable for its stats here. |
207 | */ | | 206 | */ |
208 | static u_long auth_timereset; | | 207 | static u_long auth_timereset; |
209 | | | 208 | |
210 | /* | | 209 | /* |
211 | * Response packet used by these routines. Also some state information | | 210 | * Response packet used by these routines. Also some state information |
212 | * so that we can handle packet formatting within a common set of | | 211 | * so that we can handle packet formatting within a common set of |
213 | * subroutines. Note we try to enter data in place whenever possible, | | 212 | * subroutines. Note we try to enter data in place whenever possible, |
214 | * but the need to set the more bit correctly means we occasionally | | 213 | * but the need to set the more bit correctly means we occasionally |
215 | * use the extra buffer and copy. | | 214 | * use the extra buffer and copy. |
216 | */ | | 215 | */ |
217 | static struct resp_pkt rpkt; | | 216 | static struct resp_pkt rpkt; |
218 | static int reqver; | | 217 | static int reqver; |
219 | static int seqno; | | 218 | static int seqno; |
220 | static int nitems; | | 219 | static int nitems; |
221 | static int itemsize; | | 220 | static int itemsize; |
222 | static int databytes; | | 221 | static int databytes; |
223 | static char exbuf[RESP_DATA_SIZE]; | | 222 | static char exbuf[RESP_DATA_SIZE]; |
224 | static int usingexbuf; | | 223 | static int usingexbuf; |
225 | static sockaddr_u *toaddr; | | 224 | static sockaddr_u *toaddr; |
226 | static struct interface *frominter; | | 225 | static struct interface *frominter; |
227 | | | 226 | |
228 | /* | | 227 | /* |
229 | * init_request - initialize request data | | 228 | * init_request - initialize request data |
230 | */ | | 229 | */ |
231 | void | | 230 | void |
232 | init_request (void) | | 231 | init_request (void) |
233 | { | | 232 | { |
234 | size_t i; | | 233 | size_t i; |
235 | | | 234 | |
236 | numrequests = 0; | | 235 | numrequests = 0; |
237 | numresppkts = 0; | | 236 | numresppkts = 0; |
238 | auth_timereset = 0; | | 237 | auth_timereset = 0; |
239 | info_auth_keyid = 0; /* by default, can't do this */ | | 238 | info_auth_keyid = 0; /* by default, can't do this */ |
240 | | | 239 | |
241 | for (i = 0; i < sizeof(errorcounter)/sizeof(errorcounter[0]); i++) | | 240 | for (i = 0; i < sizeof(errorcounter)/sizeof(errorcounter[0]); i++) |
242 | errorcounter[i] = 0; | | 241 | errorcounter[i] = 0; |
243 | } | | 242 | } |
244 | | | 243 | |
245 | | | 244 | |
246 | /* | | 245 | /* |
247 | * req_ack - acknowledge request with no data | | 246 | * req_ack - acknowledge request with no data |
248 | */ | | 247 | */ |
249 | static void | | 248 | static void |
250 | req_ack( | | 249 | req_ack( |
251 | sockaddr_u *srcadr, | | 250 | sockaddr_u *srcadr, |
252 | struct interface *inter, | | 251 | struct interface *inter, |
253 | struct req_pkt *inpkt, | | 252 | struct req_pkt *inpkt, |
254 | int errcode | | 253 | int errcode |
255 | ) | | 254 | ) |
256 | { | | 255 | { |
257 | /* | | 256 | /* |
258 | * fill in the fields | | 257 | * fill in the fields |
259 | */ | | 258 | */ |
260 | rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver); | | 259 | rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver); |
261 | rpkt.auth_seq = AUTH_SEQ(0, 0); | | 260 | rpkt.auth_seq = AUTH_SEQ(0, 0); |
262 | rpkt.implementation = inpkt->implementation; | | 261 | rpkt.implementation = inpkt->implementation; |
263 | rpkt.request = inpkt->request; | | 262 | rpkt.request = inpkt->request; |
264 | rpkt.err_nitems = ERR_NITEMS(errcode, 0); | | 263 | rpkt.err_nitems = ERR_NITEMS(errcode, 0); |
265 | rpkt.mbz_itemsize = MBZ_ITEMSIZE(0); | | 264 | rpkt.mbz_itemsize = MBZ_ITEMSIZE(0); |
266 | | | 265 | |
267 | /* | | 266 | /* |
268 | * send packet and bump counters | | 267 | * send packet and bump counters |
269 | */ | | 268 | */ |
270 | sendpkt(srcadr, inter, -1, (struct pkt *)&rpkt, RESP_HEADER_SIZE); | | 269 | sendpkt(srcadr, inter, -1, (struct pkt *)&rpkt, RESP_HEADER_SIZE); |
271 | errorcounter[errcode]++; | | 270 | errorcounter[errcode]++; |
272 | } | | 271 | } |
273 | | | 272 | |
274 | | | 273 | |
275 | /* | | 274 | /* |
276 | * prepare_pkt - prepare response packet for transmission, return pointer | | 275 | * prepare_pkt - prepare response packet for transmission, return pointer |
277 | * to storage for data item. | | 276 | * to storage for data item. |
278 | */ | | 277 | */ |
279 | static char * | | 278 | static char * |
280 | prepare_pkt( | | 279 | prepare_pkt( |
281 | sockaddr_u *srcadr, | | 280 | sockaddr_u *srcadr, |
282 | struct interface *inter, | | 281 | struct interface *inter, |
283 | struct req_pkt *pkt, | | 282 | struct req_pkt *pkt, |
284 | size_t structsize | | 283 | size_t structsize |
285 | ) | | 284 | ) |
286 | { | | 285 | { |
287 | DPRINTF(4, ("request: preparing pkt\n")); | | 286 | DPRINTF(4, ("request: preparing pkt\n")); |
288 | | | 287 | |
289 | /* | | 288 | /* |
290 | * Fill in the implementation, request and itemsize fields | | 289 | * Fill in the implementation, request and itemsize fields |
291 | * since these won't change. | | 290 | * since these won't change. |
292 | */ | | 291 | */ |
293 | rpkt.implementation = pkt->implementation; | | 292 | rpkt.implementation = pkt->implementation; |
294 | rpkt.request = pkt->request; | | 293 | rpkt.request = pkt->request; |
295 | rpkt.mbz_itemsize = MBZ_ITEMSIZE(structsize); | | 294 | rpkt.mbz_itemsize = MBZ_ITEMSIZE(structsize); |
296 | | | 295 | |
297 | /* | | 296 | /* |
298 | * Compute the static data needed to carry on. | | 297 | * Compute the static data needed to carry on. |
299 | */ | | 298 | */ |
300 | toaddr = srcadr; | | 299 | toaddr = srcadr; |
301 | frominter = inter; | | 300 | frominter = inter; |
302 | seqno = 0; | | 301 | seqno = 0; |
303 | nitems = 0; | | 302 | nitems = 0; |
304 | itemsize = structsize; | | 303 | itemsize = structsize; |
305 | databytes = 0; | | 304 | databytes = 0; |
306 | usingexbuf = 0; | | 305 | usingexbuf = 0; |
307 | | | 306 | |
308 | /* | | 307 | /* |
309 | * return the beginning of the packet buffer. | | 308 | * return the beginning of the packet buffer. |
310 | */ | | 309 | */ |
311 | return &rpkt.data[0]; | | 310 | return &rpkt.data[0]; |
312 | } | | 311 | } |
313 | | | 312 | |
314 | | | 313 | |
315 | /* | | 314 | /* |
316 | * more_pkt - return a data pointer for a new item. | | 315 | * more_pkt - return a data pointer for a new item. |
317 | */ | | 316 | */ |
318 | static char * | | 317 | static char * |
319 | more_pkt(void) | | 318 | more_pkt(void) |
320 | { | | 319 | { |
321 | /* | | 320 | /* |
322 | * If we were using the extra buffer, send the packet. | | 321 | * If we were using the extra buffer, send the packet. |
323 | */ | | 322 | */ |
324 | if (usingexbuf) { | | 323 | if (usingexbuf) { |
325 | DPRINTF(3, ("request: sending pkt\n")); | | 324 | DPRINTF(3, ("request: sending pkt\n")); |
326 | rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, MORE_BIT, reqver); | | 325 | rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, MORE_BIT, reqver); |
327 | rpkt.auth_seq = AUTH_SEQ(0, seqno); | | 326 | rpkt.auth_seq = AUTH_SEQ(0, seqno); |
328 | rpkt.err_nitems = htons((u_short)nitems); | | 327 | rpkt.err_nitems = htons((u_short)nitems); |
329 | sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt, | | 328 | sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt, |
330 | RESP_HEADER_SIZE + databytes); | | 329 | RESP_HEADER_SIZE + databytes); |
331 | numresppkts++; | | 330 | numresppkts++; |
332 | | | 331 | |
333 | /* | | 332 | /* |
334 | * Copy data out of exbuf into the packet. | | 333 | * Copy data out of exbuf into the packet. |
335 | */ | | 334 | */ |
336 | memcpy(&rpkt.data[0], exbuf, (unsigned)itemsize); | | 335 | memcpy(&rpkt.data[0], exbuf, (unsigned)itemsize); |
337 | seqno++; | | 336 | seqno++; |
338 | databytes = 0; | | 337 | databytes = 0; |
339 | nitems = 0; | | 338 | nitems = 0; |
340 | usingexbuf = 0; | | 339 | usingexbuf = 0; |
341 | } | | 340 | } |
342 | | | 341 | |
343 | databytes += itemsize; | | 342 | databytes += itemsize; |
344 | nitems++; | | 343 | nitems++; |
345 | if (databytes + itemsize <= RESP_DATA_SIZE) { | | 344 | if (databytes + itemsize <= RESP_DATA_SIZE) { |
346 | DPRINTF(4, ("request: giving him more data\n")); | | 345 | DPRINTF(4, ("request: giving him more data\n")); |
347 | /* | | 346 | /* |
348 | * More room in packet. Give him the | | 347 | * More room in packet. Give him the |
349 | * next address. | | 348 | * next address. |
350 | */ | | 349 | */ |
351 | return &rpkt.data[databytes]; | | 350 | return &rpkt.data[databytes]; |
352 | } else { | | 351 | } else { |
353 | /* | | 352 | /* |
354 | * No room in packet. Give him the extra | | 353 | * No room in packet. Give him the extra |
355 | * buffer unless this was the last in the sequence. | | 354 | * buffer unless this was the last in the sequence. |
356 | */ | | 355 | */ |
357 | DPRINTF(4, ("request: into extra buffer\n")); | | 356 | DPRINTF(4, ("request: into extra buffer\n")); |
358 | if (seqno == MAXSEQ) | | 357 | if (seqno == MAXSEQ) |
359 | return NULL; | | 358 | return NULL; |
360 | else { | | 359 | else { |
361 | usingexbuf = 1; | | 360 | usingexbuf = 1; |
362 | return exbuf; | | 361 | return exbuf; |
363 | } | | 362 | } |
364 | } | | 363 | } |
365 | } | | 364 | } |
366 | | | 365 | |
367 | | | 366 | |
368 | /* | | 367 | /* |
369 | * flush_pkt - we're done, return remaining information. | | 368 | * flush_pkt - we're done, return remaining information. |
370 | */ | | 369 | */ |
371 | static void | | 370 | static void |
372 | flush_pkt(void) | | 371 | flush_pkt(void) |
373 | { | | 372 | { |
374 | DPRINTF(3, ("request: flushing packet, %d items\n", nitems)); | | 373 | DPRINTF(3, ("request: flushing packet, %d items\n", nitems)); |
375 | /* | | 374 | /* |
376 | * Must send the last packet. If nothing in here and nothing | | 375 | * Must send the last packet. If nothing in here and nothing |
377 | * has been sent, send an error saying no data to be found. | | 376 | * has been sent, send an error saying no data to be found. |
378 | */ | | 377 | */ |
379 | if (seqno == 0 && nitems == 0) | | 378 | if (seqno == 0 && nitems == 0) |
380 | req_ack(toaddr, frominter, (struct req_pkt *)&rpkt, | | 379 | req_ack(toaddr, frominter, (struct req_pkt *)&rpkt, |
381 | INFO_ERR_NODATA); | | 380 | INFO_ERR_NODATA); |
382 | else { | | 381 | else { |
383 | rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver); | | 382 | rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver); |
384 | rpkt.auth_seq = AUTH_SEQ(0, seqno); | | 383 | rpkt.auth_seq = AUTH_SEQ(0, seqno); |
385 | rpkt.err_nitems = htons((u_short)nitems); | | 384 | rpkt.err_nitems = htons((u_short)nitems); |
386 | sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt, | | 385 | sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt, |
387 | RESP_HEADER_SIZE+databytes); | | 386 | RESP_HEADER_SIZE+databytes); |
388 | numresppkts++; | | 387 | numresppkts++; |
389 | } | | 388 | } |
390 | } | | 389 | } |
391 | | | 390 | |
392 | | | 391 | |
393 | | | 392 | |
394 | /* | | 393 | /* |
395 | * Given a buffer, return the packet mode | | 394 | * Given a buffer, return the packet mode |
396 | */ | | 395 | */ |
397 | int | | 396 | int |
398 | get_packet_mode(struct recvbuf *rbufp) | | 397 | get_packet_mode(struct recvbuf *rbufp) |
399 | { | | 398 | { |
400 | struct req_pkt *inpkt = (struct req_pkt *)&rbufp->recv_pkt; | | 399 | struct req_pkt *inpkt = (struct req_pkt *)&rbufp->recv_pkt; |
401 | return (INFO_MODE(inpkt->rm_vn_mode)); | | 400 | return (INFO_MODE(inpkt->rm_vn_mode)); |
402 | } | | 401 | } |
403 | | | 402 | |
404 | | | 403 | |
405 | /* | | 404 | /* |
406 | * process_private - process private mode (7) packets | | 405 | * process_private - process private mode (7) packets |
407 | */ | | 406 | */ |
408 | void | | 407 | void |
409 | process_private( | | 408 | process_private( |
410 | struct recvbuf *rbufp, | | 409 | struct recvbuf *rbufp, |
411 | int mod_okay | | 410 | int mod_okay |
412 | ) | | 411 | ) |
413 | { | | 412 | { |
414 | static u_long quiet_until; | | 413 | static u_long quiet_until; |
415 | struct req_pkt *inpkt; | | 414 | struct req_pkt *inpkt; |
416 | struct req_pkt_tail *tailinpkt; | | 415 | struct req_pkt_tail *tailinpkt; |
417 | sockaddr_u *srcadr; | | 416 | sockaddr_u *srcadr; |
418 | struct interface *inter; | | 417 | struct interface *inter; |
419 | struct req_proc *proc; | | 418 | struct req_proc *proc; |
420 | int ec; | | 419 | int ec; |
421 | short temp_size; | | 420 | short temp_size; |
422 | l_fp ftmp; | | 421 | l_fp ftmp; |
423 | double dtemp; | | 422 | double dtemp; |
424 | size_t recv_len; | | 423 | size_t recv_len; |
425 | size_t noslop_len; | | 424 | size_t noslop_len; |
426 | size_t mac_len; | | 425 | size_t mac_len; |
427 | | | 426 | |
428 | /* | | 427 | /* |
429 | * Initialize pointers, for convenience | | 428 | * Initialize pointers, for convenience |
430 | */ | | 429 | */ |
431 | recv_len = rbufp->recv_length; | | 430 | recv_len = rbufp->recv_length; |
432 | inpkt = (struct req_pkt *)&rbufp->recv_pkt; | | 431 | inpkt = (struct req_pkt *)&rbufp->recv_pkt; |
433 | srcadr = &rbufp->recv_srcadr; | | 432 | srcadr = &rbufp->recv_srcadr; |
434 | inter = rbufp->dstadr; | | 433 | inter = rbufp->dstadr; |
435 | | | 434 | |
436 | DPRINTF(3, ("process_private: impl %d req %d\n", | | 435 | DPRINTF(3, ("process_private: impl %d req %d\n", |
437 | inpkt->implementation, inpkt->request)); | | 436 | inpkt->implementation, inpkt->request)); |
438 | | | 437 | |
439 | /* | | 438 | /* |
440 | * Do some sanity checks on the packet. Return a format | | 439 | * Do some sanity checks on the packet. Return a format |
441 | * error if it fails. | | 440 | * error if it fails. |
442 | */ | | 441 | */ |
443 | ec = 0; | | 442 | ec = 0; |
444 | if ( (++ec, ISRESPONSE(inpkt->rm_vn_mode)) | | 443 | if ( (++ec, ISRESPONSE(inpkt->rm_vn_mode)) |
445 | || (++ec, ISMORE(inpkt->rm_vn_mode)) | | 444 | || (++ec, ISMORE(inpkt->rm_vn_mode)) |
446 | || (++ec, INFO_VERSION(inpkt->rm_vn_mode) > NTP_VERSION) | | 445 | || (++ec, INFO_VERSION(inpkt->rm_vn_mode) > NTP_VERSION) |
447 | || (++ec, INFO_VERSION(inpkt->rm_vn_mode) < NTP_OLDVERSION) | | 446 | || (++ec, INFO_VERSION(inpkt->rm_vn_mode) < NTP_OLDVERSION) |
448 | || (++ec, INFO_SEQ(inpkt->auth_seq) != 0) | | 447 | || (++ec, INFO_SEQ(inpkt->auth_seq) != 0) |
449 | || (++ec, INFO_ERR(inpkt->err_nitems) != 0) | | 448 | || (++ec, INFO_ERR(inpkt->err_nitems) != 0) |
450 | || (++ec, INFO_MBZ(inpkt->mbz_itemsize) != 0) | | 449 | || (++ec, INFO_MBZ(inpkt->mbz_itemsize) != 0) |
451 | || (++ec, rbufp->recv_length < (int)REQ_LEN_HDR) | | 450 | || (++ec, rbufp->recv_length < (int)REQ_LEN_HDR) |
452 | ) { | | 451 | ) { |
453 | NLOG(NLOG_SYSEVENT) | | 452 | NLOG(NLOG_SYSEVENT) |
454 | if (current_time >= quiet_until) { | | 453 | if (current_time >= quiet_until) { |
455 | msyslog(LOG_ERR, | | 454 | msyslog(LOG_ERR, |
456 | "process_private: drop test %d" | | 455 | "process_private: drop test %d" |
457 | " failed, pkt from %s", | | 456 | " failed, pkt from %s", |
458 | ec, stoa(srcadr)); | | 457 | ec, stoa(srcadr)); |
459 | quiet_until = current_time + 60; | | 458 | quiet_until = current_time + 60; |
460 | } | | 459 | } |
461 | return; | | 460 | return; |
462 | } | | 461 | } |
463 | | | 462 | |
464 | reqver = INFO_VERSION(inpkt->rm_vn_mode); | | 463 | reqver = INFO_VERSION(inpkt->rm_vn_mode); |
465 | | | 464 | |
466 | /* | | 465 | /* |
467 | * Get the appropriate procedure list to search. | | 466 | * Get the appropriate procedure list to search. |
468 | */ | | 467 | */ |
469 | if (inpkt->implementation == IMPL_UNIV) | | 468 | if (inpkt->implementation == IMPL_UNIV) |
470 | proc = univ_codes; | | 469 | proc = univ_codes; |
471 | else if ((inpkt->implementation == IMPL_XNTPD) || | | 470 | else if ((inpkt->implementation == IMPL_XNTPD) || |
472 | (inpkt->implementation == IMPL_XNTPD_OLD)) | | 471 | (inpkt->implementation == IMPL_XNTPD_OLD)) |
473 | proc = ntp_codes; | | 472 | proc = ntp_codes; |
474 | else { | | 473 | else { |
475 | req_ack(srcadr, inter, inpkt, INFO_ERR_IMPL); | | 474 | req_ack(srcadr, inter, inpkt, INFO_ERR_IMPL); |
476 | return; | | 475 | return; |
477 | } | | 476 | } |
478 | | | 477 | |
479 | /* | | 478 | /* |
480 | * Search the list for the request codes. If it isn't one | | 479 | * Search the list for the request codes. If it isn't one |
481 | * we know, return an error. | | 480 | * we know, return an error. |
482 | */ | | 481 | */ |
483 | while (proc->request_code != NO_REQUEST) { | | 482 | while (proc->request_code != NO_REQUEST) { |
484 | if (proc->request_code == (short) inpkt->request) | | 483 | if (proc->request_code == (short) inpkt->request) |
485 | break; | | 484 | break; |
486 | proc++; | | 485 | proc++; |
487 | } | | 486 | } |
488 | if (proc->request_code == NO_REQUEST) { | | 487 | if (proc->request_code == NO_REQUEST) { |
489 | req_ack(srcadr, inter, inpkt, INFO_ERR_REQ); | | 488 | req_ack(srcadr, inter, inpkt, INFO_ERR_REQ); |
490 | return; | | 489 | return; |
491 | } | | 490 | } |
492 | | | 491 | |
493 | DPRINTF(4, ("found request in tables\n")); | | 492 | DPRINTF(4, ("found request in tables\n")); |
494 | | | 493 | |
495 | /* | | 494 | /* |
496 | * If we need data, check to see if we have some. If we | | 495 | * 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). | | 496 | * don't, check to see that there is none (picky, picky). |
498 | */ | | 497 | */ |
499 | | | 498 | |
500 | /* This part is a bit tricky, we want to be sure that the size | | 499 | /* 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 | | 500 | * 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. | | 501 | * out if the client can accept both types of messages this way. |
503 | * | | 502 | * |
504 | * Handle the exception of REQ_CONFIG. It can have two data sizes. | | 503 | * Handle the exception of REQ_CONFIG. It can have two data sizes. |
505 | */ | | 504 | */ |
506 | temp_size = INFO_ITEMSIZE(inpkt->mbz_itemsize); | | 505 | temp_size = INFO_ITEMSIZE(inpkt->mbz_itemsize); |
507 | if ((temp_size != proc->sizeofitem && | | 506 | if ((temp_size != proc->sizeofitem && |
508 | temp_size != proc->v6_sizeofitem) && | | 507 | temp_size != proc->v6_sizeofitem) && |
509 | !(inpkt->implementation == IMPL_XNTPD && | | 508 | !(inpkt->implementation == IMPL_XNTPD && |
510 | inpkt->request == REQ_CONFIG && | | 509 | inpkt->request == REQ_CONFIG && |
511 | temp_size == sizeof(struct old_conf_peer))) { | | 510 | temp_size == sizeof(struct old_conf_peer))) { |
512 | DPRINTF(3, ("process_private: wrong item size, received %d, should be %d or %d\n", | | 511 | DPRINTF(3, ("process_private: wrong item size, received %d, should be %d or %d\n", |
513 | temp_size, proc->sizeofitem, proc->v6_sizeofitem)); | | 512 | temp_size, proc->sizeofitem, proc->v6_sizeofitem)); |
514 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 513 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
515 | return; | | 514 | return; |
516 | } | | 515 | } |
517 | if ((proc->sizeofitem != 0) && | | 516 | if ((proc->sizeofitem != 0) && |
518 | ((size_t)(temp_size * INFO_NITEMS(inpkt->err_nitems)) > | | 517 | ((size_t)(temp_size * INFO_NITEMS(inpkt->err_nitems)) > |
519 | (recv_len - REQ_LEN_HDR))) { | | 518 | (recv_len - REQ_LEN_HDR))) { |
520 | DPRINTF(3, ("process_private: not enough data\n")); | | 519 | DPRINTF(3, ("process_private: not enough data\n")); |
521 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 520 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
522 | return; | | 521 | return; |
523 | } | | 522 | } |
524 | | | 523 | |
525 | switch (inpkt->implementation) { | | 524 | switch (inpkt->implementation) { |
526 | case IMPL_XNTPD: | | 525 | case IMPL_XNTPD: |
527 | client_v6_capable = 1; | | 526 | client_v6_capable = 1; |
528 | break; | | 527 | break; |
529 | case IMPL_XNTPD_OLD: | | 528 | case IMPL_XNTPD_OLD: |
530 | client_v6_capable = 0; | | 529 | client_v6_capable = 0; |
531 | break; | | 530 | break; |
532 | default: | | 531 | default: |
533 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 532 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
534 | return; | | 533 | return; |
535 | } | | 534 | } |
536 | | | 535 | |
537 | /* | | 536 | /* |
538 | * If we need to authenticate, do so. Note that an | | 537 | * If we need to authenticate, do so. Note that an |
539 | * authenticatable packet must include a mac field, must | | 538 | * authenticatable packet must include a mac field, must |
540 | * have used key info_auth_keyid and must have included | | 539 | * have used key info_auth_keyid and must have included |
541 | * a time stamp in the appropriate field. The time stamp | | 540 | * a time stamp in the appropriate field. The time stamp |
542 | * must be within INFO_TS_MAXSKEW of the receive | | 541 | * must be within INFO_TS_MAXSKEW of the receive |
543 | * time stamp. | | 542 | * time stamp. |
544 | */ | | 543 | */ |
545 | if (proc->needs_auth && sys_authenticate) { | | 544 | if (proc->needs_auth && sys_authenticate) { |
546 | | | 545 | |
547 | if (recv_len < (REQ_LEN_HDR + | | 546 | if (recv_len < (REQ_LEN_HDR + |
548 | (INFO_ITEMSIZE(inpkt->mbz_itemsize) * | | 547 | (INFO_ITEMSIZE(inpkt->mbz_itemsize) * |
549 | INFO_NITEMS(inpkt->err_nitems)) + | | 548 | INFO_NITEMS(inpkt->err_nitems)) + |
550 | REQ_TAIL_MIN)) { | | 549 | REQ_TAIL_MIN)) { |
551 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 550 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
552 | return; | | 551 | return; |
553 | } | | 552 | } |
554 | | | 553 | |
555 | /* | | 554 | /* |
556 | * For 16-octet digests, regardless of itemsize and | | 555 | * For 16-octet digests, regardless of itemsize and |
557 | * nitems, authenticated requests are a fixed size | | 556 | * nitems, authenticated requests are a fixed size |
558 | * with the timestamp, key ID, and digest located | | 557 | * with the timestamp, key ID, and digest located |
559 | * at the end of the packet. Because the key ID | | 558 | * at the end of the packet. Because the key ID |
560 | * determining the digest size precedes the digest, | | 559 | * determining the digest size precedes the digest, |
561 | * for larger digests the fixed size request scheme | | 560 | * for larger digests the fixed size request scheme |
562 | * is abandoned and the timestamp, key ID, and digest | | 561 | * is abandoned and the timestamp, key ID, and digest |
563 | * are located relative to the start of the packet, | | 562 | * are located relative to the start of the packet, |
564 | * with the digest size determined by the packet size. | | 563 | * with the digest size determined by the packet size. |
565 | */ | | 564 | */ |
566 | noslop_len = REQ_LEN_HDR | | 565 | noslop_len = REQ_LEN_HDR |
567 | + INFO_ITEMSIZE(inpkt->mbz_itemsize) * | | 566 | + INFO_ITEMSIZE(inpkt->mbz_itemsize) * |
568 | INFO_NITEMS(inpkt->err_nitems) | | 567 | INFO_NITEMS(inpkt->err_nitems) |
569 | + sizeof(inpkt->tstamp); | | 568 | + sizeof(inpkt->tstamp); |
570 | /* 32-bit alignment */ | | 569 | /* 32-bit alignment */ |
571 | noslop_len = (noslop_len + 3) & ~3; | | 570 | noslop_len = (noslop_len + 3) & ~3; |
572 | if (recv_len > (noslop_len + MAX_MAC_LEN)) | | 571 | if (recv_len > (noslop_len + MAX_MAC_LEN)) |
573 | mac_len = 20; | | 572 | mac_len = 20; |
574 | else | | 573 | else |
575 | mac_len = recv_len - noslop_len; | | 574 | mac_len = recv_len - noslop_len; |
576 | | | 575 | |
577 | tailinpkt = (void *)((char *)inpkt + recv_len - | | 576 | tailinpkt = (void *)((char *)inpkt + recv_len - |
578 | (mac_len + sizeof(inpkt->tstamp))); | | 577 | (mac_len + sizeof(inpkt->tstamp))); |
579 | | | 578 | |
580 | /* | | 579 | /* |
581 | * If this guy is restricted from doing this, don't let | | 580 | * If this guy is restricted from doing this, don't let |
582 | * him. If the wrong key was used, or packet doesn't | | 581 | * him. If the wrong key was used, or packet doesn't |
583 | * have mac, return. | | 582 | * have mac, return. |
584 | */ | | 583 | */ |
585 | if (!INFO_IS_AUTH(inpkt->auth_seq) || !info_auth_keyid | | 584 | if (!INFO_IS_AUTH(inpkt->auth_seq) || !info_auth_keyid |
586 | || ntohl(tailinpkt->keyid) != info_auth_keyid) { | | 585 | || ntohl(tailinpkt->keyid) != info_auth_keyid) { |
587 | DPRINTF(5, ("failed auth %d info_auth_keyid %u pkt keyid %u maclen %lu\n", | | 586 | DPRINTF(5, ("failed auth %d info_auth_keyid %u pkt keyid %u maclen %lu\n", |
588 | INFO_IS_AUTH(inpkt->auth_seq), | | 587 | INFO_IS_AUTH(inpkt->auth_seq), |
589 | info_auth_keyid, | | 588 | info_auth_keyid, |
590 | ntohl(tailinpkt->keyid), (u_long)mac_len)); | | 589 | ntohl(tailinpkt->keyid), (u_long)mac_len)); |
591 | #ifdef DEBUG | | 590 | #ifdef DEBUG |
592 | msyslog(LOG_DEBUG, | | 591 | msyslog(LOG_DEBUG, |
593 | "process_private: failed auth %d info_auth_keyid %u pkt keyid %u maclen %lu\n", | | 592 | "process_private: failed auth %d info_auth_keyid %u pkt keyid %u maclen %lu\n", |
594 | INFO_IS_AUTH(inpkt->auth_seq), | | 593 | INFO_IS_AUTH(inpkt->auth_seq), |
595 | info_auth_keyid, | | 594 | info_auth_keyid, |
596 | ntohl(tailinpkt->keyid), (u_long)mac_len); | | 595 | ntohl(tailinpkt->keyid), (u_long)mac_len); |
597 | #endif | | 596 | #endif |
598 | req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH); | | 597 | req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH); |
599 | return; | | 598 | return; |
600 | } | | 599 | } |
601 | if (recv_len > REQ_LEN_NOMAC + MAX_MAC_LEN) { | | 600 | if (recv_len > REQ_LEN_NOMAC + MAX_MAC_LEN) { |
602 | DPRINTF(5, ("bad pkt length %zu\n", recv_len)); | | 601 | DPRINTF(5, ("bad pkt length %zu\n", recv_len)); |
603 | msyslog(LOG_ERR, | | 602 | msyslog(LOG_ERR, |
604 | "process_private: bad pkt length %zu", | | 603 | "process_private: bad pkt length %zu", |
605 | recv_len); | | 604 | recv_len); |
606 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 605 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
607 | return; | | 606 | return; |
608 | } | | 607 | } |
609 | if (!mod_okay || !authhavekey(info_auth_keyid)) { | | 608 | if (!mod_okay || !authhavekey(info_auth_keyid)) { |
610 | DPRINTF(5, ("failed auth mod_okay %d\n", | | 609 | DPRINTF(5, ("failed auth mod_okay %d\n", |
611 | mod_okay)); | | 610 | mod_okay)); |
612 | #ifdef DEBUG | | 611 | #ifdef DEBUG |
613 | msyslog(LOG_DEBUG, | | 612 | msyslog(LOG_DEBUG, |
614 | "process_private: failed auth mod_okay %d\n", | | 613 | "process_private: failed auth mod_okay %d\n", |
615 | mod_okay); | | 614 | mod_okay); |
616 | #endif | | 615 | #endif |
| | | 616 | if (!mod_okay) { |
| | | 617 | sys_restricted++; |
| | | 618 | } |
617 | req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH); | | 619 | req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH); |
618 | return; | | 620 | return; |
619 | } | | 621 | } |
620 | | | 622 | |
621 | /* | | 623 | /* |
622 | * calculate absolute time difference between xmit time stamp | | 624 | * calculate absolute time difference between xmit time stamp |
623 | * and receive time stamp. If too large, too bad. | | 625 | * and receive time stamp. If too large, too bad. |
624 | */ | | 626 | */ |
625 | NTOHL_FP(&tailinpkt->tstamp, &ftmp); | | 627 | NTOHL_FP(&tailinpkt->tstamp, &ftmp); |
626 | L_SUB(&ftmp, &rbufp->recv_time); | | 628 | L_SUB(&ftmp, &rbufp->recv_time); |
627 | LFPTOD(&ftmp, dtemp); | | 629 | LFPTOD(&ftmp, dtemp); |
628 | if (fabs(dtemp) > INFO_TS_MAXSKEW) { | | 630 | if (fabs(dtemp) > INFO_TS_MAXSKEW) { |
629 | /* | | 631 | /* |
630 | * He's a loser. Tell him. | | 632 | * He's a loser. Tell him. |
631 | */ | | 633 | */ |
632 | DPRINTF(5, ("xmit/rcv timestamp delta %g > INFO_TS_MAXSKEW %g\n", | | 634 | DPRINTF(5, ("xmit/rcv timestamp delta %g > INFO_TS_MAXSKEW %g\n", |
633 | dtemp, INFO_TS_MAXSKEW)); | | 635 | dtemp, INFO_TS_MAXSKEW)); |
634 | req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH); | | 636 | req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH); |
635 | return; | | 637 | return; |
636 | } | | 638 | } |
637 | | | 639 | |
638 | /* | | 640 | /* |
639 | * So far so good. See if decryption works out okay. | | 641 | * So far so good. See if decryption works out okay. |
640 | */ | | 642 | */ |
641 | if (!authdecrypt(info_auth_keyid, (u_int32 *)inpkt, | | 643 | if (!authdecrypt(info_auth_keyid, (u_int32 *)inpkt, |
642 | recv_len - mac_len, mac_len)) { | | 644 | recv_len - mac_len, mac_len)) { |
643 | DPRINTF(5, ("authdecrypt failed\n")); | | 645 | DPRINTF(5, ("authdecrypt failed\n")); |
644 | req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH); | | 646 | req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH); |
645 | return; | | 647 | return; |
646 | } | | 648 | } |
647 | } | | 649 | } |
648 | | | 650 | |
649 | DPRINTF(3, ("process_private: all okay, into handler\n")); | | 651 | DPRINTF(3, ("process_private: all okay, into handler\n")); |
650 | /* | | 652 | /* |
651 | * Packet is okay. Call the handler to send him data. | | 653 | * Packet is okay. Call the handler to send him data. |
652 | */ | | 654 | */ |
653 | (proc->handler)(srcadr, inter, inpkt); | | 655 | (proc->handler)(srcadr, inter, inpkt); |
654 | } | | 656 | } |
655 | | | 657 | |
656 | | | 658 | |
657 | /* | | 659 | /* |
658 | * peer_list - send a list of the peers | | 660 | * peer_list - send a list of the peers |
659 | */ | | 661 | */ |
660 | static void | | 662 | static void |
661 | peer_list( | | 663 | peer_list( |
662 | sockaddr_u *srcadr, | | 664 | sockaddr_u *srcadr, |
663 | struct interface *inter, | | 665 | struct interface *inter, |
664 | struct req_pkt *inpkt | | 666 | struct req_pkt *inpkt |
665 | ) | | 667 | ) |
666 | { | | 668 | { |
667 | register struct info_peer_list *ip; | | 669 | register struct info_peer_list *ip; |
668 | register struct peer *pp; | | 670 | register struct peer *pp; |
669 | register int i; | | 671 | register int i; |
670 | register int skip = 0; | | 672 | register int skip = 0; |
671 | | | 673 | |
672 | ip = (struct info_peer_list *)prepare_pkt(srcadr, inter, inpkt, | | 674 | ip = (struct info_peer_list *)prepare_pkt(srcadr, inter, inpkt, |
673 | v6sizeof(struct info_peer_list)); | | 675 | v6sizeof(struct info_peer_list)); |
674 | for (i = 0; i < NTP_HASH_SIZE && ip != 0; i++) { | | 676 | for (i = 0; i < NTP_HASH_SIZE && ip != 0; i++) { |
675 | pp = peer_hash[i]; | | 677 | pp = peer_hash[i]; |
676 | while (pp != 0 && ip != 0) { | | 678 | while (pp != 0 && ip != 0) { |
677 | if (IS_IPV6(&pp->srcadr)) { | | 679 | if (IS_IPV6(&pp->srcadr)) { |
678 | if (client_v6_capable) { | | 680 | if (client_v6_capable) { |
679 | ip->addr6 = SOCK_ADDR6(&pp->srcadr); | | 681 | ip->addr6 = SOCK_ADDR6(&pp->srcadr); |
680 | ip->v6_flag = 1; | | 682 | ip->v6_flag = 1; |
681 | skip = 0; | | 683 | skip = 0; |
682 | } else { | | 684 | } else { |
683 | skip = 1; | | 685 | skip = 1; |
684 | break; | | 686 | break; |
685 | } | | 687 | } |
686 | } else { | | 688 | } else { |
687 | ip->addr = NSRCADR(&pp->srcadr); | | 689 | ip->addr = NSRCADR(&pp->srcadr); |
688 | if (client_v6_capable) | | 690 | if (client_v6_capable) |
689 | ip->v6_flag = 0; | | 691 | ip->v6_flag = 0; |
690 | skip = 0; | | 692 | skip = 0; |
691 | } | | 693 | } |
692 | | | 694 | |
693 | if(!skip) { | | 695 | if(!skip) { |
694 | ip->port = NSRCPORT(&pp->srcadr); | | 696 | ip->port = NSRCPORT(&pp->srcadr); |
695 | ip->hmode = pp->hmode; | | 697 | ip->hmode = pp->hmode; |
696 | ip->flags = 0; | | 698 | ip->flags = 0; |
697 | if (pp->flags & FLAG_CONFIG) | | 699 | if (pp->flags & FLAG_CONFIG) |
698 | ip->flags |= INFO_FLAG_CONFIG; | | 700 | ip->flags |= INFO_FLAG_CONFIG; |
699 | if (pp == sys_peer) | | 701 | if (pp == sys_peer) |
700 | ip->flags |= INFO_FLAG_SYSPEER; | | 702 | ip->flags |= INFO_FLAG_SYSPEER; |
701 | if (pp->status == CTL_PST_SEL_SYNCCAND) | | 703 | if (pp->status == CTL_PST_SEL_SYNCCAND) |
702 | ip->flags |= INFO_FLAG_SEL_CANDIDATE; | | 704 | ip->flags |= INFO_FLAG_SEL_CANDIDATE; |
703 | if (pp->status >= CTL_PST_SEL_SYSPEER) | | 705 | if (pp->status >= CTL_PST_SEL_SYSPEER) |
704 | ip->flags |= INFO_FLAG_SHORTLIST; | | 706 | ip->flags |= INFO_FLAG_SHORTLIST; |
705 | ip = (struct info_peer_list *)more_pkt(); | | 707 | ip = (struct info_peer_list *)more_pkt(); |
706 | } | | 708 | } |
707 | pp = pp->next; | | 709 | pp = pp->next; |
708 | } | | 710 | } |
709 | } | | 711 | } |
710 | flush_pkt(); | | 712 | flush_pkt(); |
711 | } | | 713 | } |
712 | | | 714 | |
713 | | | 715 | |
714 | /* | | 716 | /* |
715 | * peer_list_sum - return extended peer list | | 717 | * peer_list_sum - return extended peer list |
716 | */ | | 718 | */ |
717 | static void | | 719 | static void |
718 | peer_list_sum( | | 720 | peer_list_sum( |
719 | sockaddr_u *srcadr, | | 721 | sockaddr_u *srcadr, |
720 | struct interface *inter, | | 722 | struct interface *inter, |
721 | struct req_pkt *inpkt | | 723 | struct req_pkt *inpkt |
722 | ) | | 724 | ) |
723 | { | | 725 | { |
724 | register struct info_peer_summary *ips; | | 726 | register struct info_peer_summary *ips; |
725 | register struct peer *pp; | | 727 | register struct peer *pp; |
726 | register int i; | | 728 | register int i; |
727 | l_fp ltmp; | | 729 | l_fp ltmp; |
728 | register int skip; | | 730 | register int skip; |
729 | | | 731 | |
730 | #ifdef DEBUG | | 732 | #ifdef DEBUG |
731 | if (debug > 2) | | 733 | if (debug > 2) |
732 | printf("wants peer list summary\n"); | | 734 | printf("wants peer list summary\n"); |
733 | #endif | | 735 | #endif |
734 | ips = (struct info_peer_summary *)prepare_pkt(srcadr, inter, inpkt, | | 736 | ips = (struct info_peer_summary *)prepare_pkt(srcadr, inter, inpkt, |
735 | v6sizeof(struct info_peer_summary)); | | 737 | v6sizeof(struct info_peer_summary)); |
736 | for (i = 0; i < NTP_HASH_SIZE && ips != 0; i++) { | | 738 | for (i = 0; i < NTP_HASH_SIZE && ips != 0; i++) { |
737 | pp = peer_hash[i]; | | 739 | pp = peer_hash[i]; |
738 | while (pp != 0 && ips != 0) { | | 740 | while (pp != 0 && ips != 0) { |
739 | #ifdef DEBUG | | 741 | #ifdef DEBUG |
740 | if (debug > 3) | | 742 | if (debug > 3) |
741 | printf("sum: got one\n"); | | 743 | printf("sum: got one\n"); |
742 | #endif | | 744 | #endif |
743 | /* | | 745 | /* |
744 | * Be careful here not to return v6 peers when we | | 746 | * Be careful here not to return v6 peers when we |
745 | * want only v4. | | 747 | * want only v4. |
746 | */ | | 748 | */ |
747 | if (IS_IPV6(&pp->srcadr)) { | | 749 | if (IS_IPV6(&pp->srcadr)) { |
748 | if (client_v6_capable) { | | 750 | if (client_v6_capable) { |
749 | ips->srcadr6 = SOCK_ADDR6(&pp->srcadr); | | 751 | ips->srcadr6 = SOCK_ADDR6(&pp->srcadr); |
750 | ips->v6_flag = 1; | | 752 | ips->v6_flag = 1; |
751 | if (pp->dstadr) | | 753 | if (pp->dstadr) |
752 | ips->dstadr6 = SOCK_ADDR6(&pp->dstadr->sin); | | 754 | ips->dstadr6 = SOCK_ADDR6(&pp->dstadr->sin); |
753 | else | | 755 | else |
754 | memset(&ips->dstadr6, 0, sizeof(ips->dstadr6)); | | 756 | memset(&ips->dstadr6, 0, sizeof(ips->dstadr6)); |
755 | skip = 0; | | 757 | skip = 0; |
756 | } else { | | 758 | } else { |
757 | skip = 1; | | 759 | skip = 1; |
758 | break; | | 760 | break; |
759 | } | | 761 | } |
760 | } else { | | 762 | } else { |
761 | ips->srcadr = NSRCADR(&pp->srcadr); | | 763 | ips->srcadr = NSRCADR(&pp->srcadr); |
762 | if (client_v6_capable) | | 764 | if (client_v6_capable) |
763 | ips->v6_flag = 0; | | 765 | ips->v6_flag = 0; |
764 | | | 766 | |
765 | if (pp->dstadr) { | | 767 | if (pp->dstadr) { |
766 | if (!pp->processed) | | 768 | if (!pp->processed) |
767 | ips->dstadr = NSRCADR(&pp->dstadr->sin); | | 769 | ips->dstadr = NSRCADR(&pp->dstadr->sin); |
768 | else { | | 770 | else { |
769 | if (MDF_BCAST == pp->cast_flags) | | 771 | if (MDF_BCAST == pp->cast_flags) |
770 | ips->dstadr = NSRCADR(&pp->dstadr->bcast); | | 772 | ips->dstadr = NSRCADR(&pp->dstadr->bcast); |
771 | else if (pp->cast_flags) { | | 773 | else if (pp->cast_flags) { |
772 | ips->dstadr = NSRCADR(&pp->dstadr->sin); | | 774 | ips->dstadr = NSRCADR(&pp->dstadr->sin); |
773 | if (!ips->dstadr) | | 775 | if (!ips->dstadr) |
774 | ips->dstadr = NSRCADR(&pp->dstadr->bcast); | | 776 | ips->dstadr = NSRCADR(&pp->dstadr->bcast); |
775 | } | | 777 | } |
776 | } | | 778 | } |
777 | } else | | 779 | } else |
778 | ips->dstadr = 0; | | 780 | ips->dstadr = 0; |
779 | | | 781 | |
780 | skip = 0; | | 782 | skip = 0; |
781 | } | | 783 | } |
782 | | | 784 | |
783 | if (!skip){ | | 785 | if (!skip){ |
784 | ips->srcport = NSRCPORT(&pp->srcadr); | | 786 | ips->srcport = NSRCPORT(&pp->srcadr); |
785 | ips->stratum = pp->stratum; | | 787 | ips->stratum = pp->stratum; |
786 | ips->hpoll = pp->hpoll; | | 788 | ips->hpoll = pp->hpoll; |
787 | ips->ppoll = pp->ppoll; | | 789 | ips->ppoll = pp->ppoll; |
788 | ips->reach = pp->reach; | | 790 | ips->reach = pp->reach; |
789 | ips->flags = 0; | | 791 | ips->flags = 0; |
790 | if (pp == sys_peer) | | 792 | if (pp == sys_peer) |
791 | ips->flags |= INFO_FLAG_SYSPEER; | | 793 | ips->flags |= INFO_FLAG_SYSPEER; |
792 | if (pp->flags & FLAG_CONFIG) | | 794 | if (pp->flags & FLAG_CONFIG) |
793 | ips->flags |= INFO_FLAG_CONFIG; | | 795 | ips->flags |= INFO_FLAG_CONFIG; |
794 | if (pp->flags & FLAG_REFCLOCK) | | 796 | if (pp->flags & FLAG_REFCLOCK) |
795 | ips->flags |= INFO_FLAG_REFCLOCK; | | 797 | ips->flags |= INFO_FLAG_REFCLOCK; |
796 | if (pp->flags & FLAG_PREFER) | | 798 | if (pp->flags & FLAG_PREFER) |
797 | ips->flags |= INFO_FLAG_PREFER; | | 799 | ips->flags |= INFO_FLAG_PREFER; |
798 | if (pp->flags & FLAG_BURST) | | 800 | if (pp->flags & FLAG_BURST) |
799 | ips->flags |= INFO_FLAG_BURST; | | 801 | ips->flags |= INFO_FLAG_BURST; |
800 | if (pp->status == CTL_PST_SEL_SYNCCAND) | | 802 | if (pp->status == CTL_PST_SEL_SYNCCAND) |
801 | ips->flags |= INFO_FLAG_SEL_CANDIDATE; | | 803 | ips->flags |= INFO_FLAG_SEL_CANDIDATE; |
802 | if (pp->status >= CTL_PST_SEL_SYSPEER) | | 804 | if (pp->status >= CTL_PST_SEL_SYSPEER) |
803 | ips->flags |= INFO_FLAG_SHORTLIST; | | 805 | ips->flags |= INFO_FLAG_SHORTLIST; |
804 | ips->hmode = pp->hmode; | | 806 | ips->hmode = pp->hmode; |
805 | ips->delay = HTONS_FP(DTOFP(pp->delay)); | | 807 | ips->delay = HTONS_FP(DTOFP(pp->delay)); |
806 | DTOLFP(pp->offset, <mp); | | 808 | DTOLFP(pp->offset, <mp); |
807 | HTONL_FP(<mp, &ips->offset); | | 809 | HTONL_FP(<mp, &ips->offset); |
808 | ips->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp))); | | 810 | ips->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp))); |
809 | } | | 811 | } |
810 | pp = pp->next; | | 812 | pp = pp->next; |
811 | ips = (struct info_peer_summary *)more_pkt(); | | 813 | ips = (struct info_peer_summary *)more_pkt(); |
812 | } | | 814 | } |
813 | } | | 815 | } |
814 | flush_pkt(); | | 816 | flush_pkt(); |
815 | } | | 817 | } |
816 | | | 818 | |
817 | | | 819 | |
818 | /* | | 820 | /* |
819 | * peer_info - send information for one or more peers | | 821 | * peer_info - send information for one or more peers |
820 | */ | | 822 | */ |
821 | static void | | 823 | static void |
822 | peer_info ( | | 824 | peer_info ( |
823 | sockaddr_u *srcadr, | | 825 | sockaddr_u *srcadr, |
824 | struct interface *inter, | | 826 | struct interface *inter, |
825 | struct req_pkt *inpkt | | 827 | struct req_pkt *inpkt |
826 | ) | | 828 | ) |
827 | { | | 829 | { |
828 | register struct info_peer_list *ipl; | | 830 | struct info_peer_list ipl; |
829 | register struct peer *pp; | | 831 | register struct peer *pp; |
830 | register struct info_peer *ip; | | 832 | register struct info_peer *ip; |
831 | register int items; | | 833 | register int items; |
| | | 834 | size_t item_sz; |
| | | 835 | char * datap; |
832 | register int i, j; | | 836 | register int i, j; |
833 | sockaddr_u addr; | | 837 | sockaddr_u addr; |
834 | extern struct peer *sys_peer; | | 838 | extern struct peer *sys_peer; |
835 | l_fp ltmp; | | 839 | l_fp ltmp; |
836 | | | 840 | |
837 | items = INFO_NITEMS(inpkt->err_nitems); | | 841 | items = INFO_NITEMS(inpkt->err_nitems); |
838 | ipl = (struct info_peer_list *) inpkt->data; | | 842 | item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); |
839 | | | 843 | datap = inpkt->data; |
| | | 844 | if (item_sz != sizeof(ipl)) { |
| | | 845 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
| | | 846 | return; |
| | | 847 | } |
840 | ip = (struct info_peer *)prepare_pkt(srcadr, inter, inpkt, | | 848 | ip = (struct info_peer *)prepare_pkt(srcadr, inter, inpkt, |
841 | v6sizeof(struct info_peer)); | | 849 | v6sizeof(struct info_peer)); |
842 | while (items-- > 0 && ip != 0) { | | 850 | while (items-- > 0 && ip != 0) { |
| | | 851 | memset(&ipl,0,sizeof(ipl)); |
| | | 852 | memcpy(&ipl, datap, item_sz); |
843 | ZERO_SOCK(&addr); | | 853 | ZERO_SOCK(&addr); |
844 | NSRCPORT(&addr) = ipl->port; | | 854 | NSRCPORT(&addr) = ipl.port; |
845 | if (client_v6_capable && ipl->v6_flag) { | | 855 | if (client_v6_capable && ipl.v6_flag) { |
846 | AF(&addr) = AF_INET6; | | 856 | AF(&addr) = AF_INET6; |
847 | SOCK_ADDR6(&addr) = ipl->addr6; | | 857 | SOCK_ADDR6(&addr) = ipl.addr6; |
848 | } else { | | 858 | } else { |
849 | AF(&addr) = AF_INET; | | 859 | AF(&addr) = AF_INET; |
850 | NSRCADR(&addr) = ipl->addr; | | 860 | NSRCADR(&addr) = ipl.addr; |
851 | } | | 861 | } |
852 | #ifdef ISC_PLATFORM_HAVESALEN | | 862 | #ifdef ISC_PLATFORM_HAVESALEN |
853 | addr.sa.sa_len = SOCKLEN(&addr); | | 863 | addr.sa.sa_len = SOCKLEN(&addr); |
854 | #endif | | 864 | #endif |
855 | ipl++; | | 865 | datap += item_sz; |
856 | pp = findexistingpeer(&addr, NULL, -1, 0); | | 866 | pp = findexistingpeer(&addr, NULL, -1, 0); |
857 | if (NULL == pp) | | 867 | if (NULL == pp) |
858 | continue; | | 868 | continue; |
859 | if (IS_IPV6(srcadr)) { | | 869 | if (IS_IPV6(srcadr)) { |
860 | if (pp->dstadr) | | 870 | if (pp->dstadr) |
861 | ip->dstadr6 = | | 871 | ip->dstadr6 = |
862 | (MDF_BCAST == pp->cast_flags) | | 872 | (MDF_BCAST == pp->cast_flags) |
863 | ? SOCK_ADDR6(&pp->dstadr->bcast) | | 873 | ? SOCK_ADDR6(&pp->dstadr->bcast) |
864 | : SOCK_ADDR6(&pp->dstadr->sin); | | 874 | : SOCK_ADDR6(&pp->dstadr->sin); |
865 | else | | 875 | else |
866 | memset(&ip->dstadr6, 0, sizeof(ip->dstadr6)); | | 876 | memset(&ip->dstadr6, 0, sizeof(ip->dstadr6)); |
867 | | | 877 | |
868 | ip->srcadr6 = SOCK_ADDR6(&pp->srcadr); | | 878 | ip->srcadr6 = SOCK_ADDR6(&pp->srcadr); |
869 | ip->v6_flag = 1; | | 879 | ip->v6_flag = 1; |
870 | } else { | | 880 | } else { |
871 | if (pp->dstadr) { | | 881 | if (pp->dstadr) { |
872 | if (!pp->processed) | | 882 | if (!pp->processed) |
873 | ip->dstadr = NSRCADR(&pp->dstadr->sin); | | 883 | ip->dstadr = NSRCADR(&pp->dstadr->sin); |
874 | else { | | 884 | else { |
875 | if (MDF_BCAST == pp->cast_flags) | | 885 | if (MDF_BCAST == pp->cast_flags) |
876 | ip->dstadr = NSRCADR(&pp->dstadr->bcast); | | 886 | ip->dstadr = NSRCADR(&pp->dstadr->bcast); |
877 | else if (pp->cast_flags) { | | 887 | else if (pp->cast_flags) { |
878 | ip->dstadr = NSRCADR(&pp->dstadr->sin); | | 888 | ip->dstadr = NSRCADR(&pp->dstadr->sin); |
879 | if (!ip->dstadr) | | 889 | if (!ip->dstadr) |
880 | ip->dstadr = NSRCADR(&pp->dstadr->bcast); | | 890 | ip->dstadr = NSRCADR(&pp->dstadr->bcast); |
881 | } | | 891 | } |
882 | } | | 892 | } |
883 | } else | | 893 | } else |
884 | ip->dstadr = 0; | | 894 | ip->dstadr = 0; |
885 | | | 895 | |
886 | ip->srcadr = NSRCADR(&pp->srcadr); | | 896 | ip->srcadr = NSRCADR(&pp->srcadr); |
887 | if (client_v6_capable) | | 897 | if (client_v6_capable) |
888 | ip->v6_flag = 0; | | 898 | ip->v6_flag = 0; |
889 | } | | 899 | } |
890 | ip->srcport = NSRCPORT(&pp->srcadr); | | 900 | ip->srcport = NSRCPORT(&pp->srcadr); |
891 | ip->flags = 0; | | 901 | ip->flags = 0; |
892 | if (pp == sys_peer) | | 902 | if (pp == sys_peer) |
893 | ip->flags |= INFO_FLAG_SYSPEER; | | 903 | ip->flags |= INFO_FLAG_SYSPEER; |
894 | if (pp->flags & FLAG_CONFIG) | | 904 | if (pp->flags & FLAG_CONFIG) |
895 | ip->flags |= INFO_FLAG_CONFIG; | | 905 | ip->flags |= INFO_FLAG_CONFIG; |
896 | if (pp->flags & FLAG_REFCLOCK) | | 906 | if (pp->flags & FLAG_REFCLOCK) |
897 | ip->flags |= INFO_FLAG_REFCLOCK; | | 907 | ip->flags |= INFO_FLAG_REFCLOCK; |
898 | if (pp->flags & FLAG_PREFER) | | 908 | if (pp->flags & FLAG_PREFER) |
899 | ip->flags |= INFO_FLAG_PREFER; | | 909 | ip->flags |= INFO_FLAG_PREFER; |
900 | if (pp->flags & FLAG_BURST) | | 910 | if (pp->flags & FLAG_BURST) |
901 | ip->flags |= INFO_FLAG_BURST; | | 911 | ip->flags |= INFO_FLAG_BURST; |
902 | if (pp->status == CTL_PST_SEL_SYNCCAND) | | 912 | if (pp->status == CTL_PST_SEL_SYNCCAND) |
903 | ip->flags |= INFO_FLAG_SEL_CANDIDATE; | | 913 | ip->flags |= INFO_FLAG_SEL_CANDIDATE; |
904 | if (pp->status >= CTL_PST_SEL_SYSPEER) | | 914 | if (pp->status >= CTL_PST_SEL_SYSPEER) |
905 | ip->flags |= INFO_FLAG_SHORTLIST; | | 915 | ip->flags |= INFO_FLAG_SHORTLIST; |
906 | ip->leap = pp->leap; | | 916 | ip->leap = pp->leap; |
907 | ip->hmode = pp->hmode; | | 917 | ip->hmode = pp->hmode; |
908 | ip->keyid = pp->keyid; | | 918 | ip->keyid = pp->keyid; |
909 | ip->stratum = pp->stratum; | | 919 | ip->stratum = pp->stratum; |
910 | ip->ppoll = pp->ppoll; | | 920 | ip->ppoll = pp->ppoll; |
911 | ip->hpoll = pp->hpoll; | | 921 | ip->hpoll = pp->hpoll; |
912 | ip->precision = pp->precision; | | 922 | ip->precision = pp->precision; |
913 | ip->version = pp->version; | | 923 | ip->version = pp->version; |
914 | ip->reach = pp->reach; | | 924 | ip->reach = pp->reach; |
915 | ip->unreach = (u_char) pp->unreach; | | 925 | ip->unreach = (u_char) pp->unreach; |
916 | ip->flash = (u_char)pp->flash; | | 926 | ip->flash = (u_char)pp->flash; |
917 | ip->flash2 = (u_short) pp->flash; | | 927 | ip->flash2 = (u_short) pp->flash; |
918 | ip->estbdelay = HTONS_FP(DTOFP(pp->delay)); | | 928 | ip->estbdelay = HTONS_FP(DTOFP(pp->delay)); |
919 | ip->ttl = pp->ttl; | | 929 | ip->ttl = pp->ttl; |
920 | ip->associd = htons(pp->associd); | | 930 | ip->associd = htons(pp->associd); |
921 | ip->rootdelay = HTONS_FP(DTOUFP(pp->rootdelay)); | | 931 | ip->rootdelay = HTONS_FP(DTOUFP(pp->rootdelay)); |
922 | ip->rootdispersion = HTONS_FP(DTOUFP(pp->rootdisp)); | | 932 | ip->rootdispersion = HTONS_FP(DTOUFP(pp->rootdisp)); |
923 | ip->refid = pp->refid; | | 933 | ip->refid = pp->refid; |
924 | HTONL_FP(&pp->reftime, &ip->reftime); | | 934 | HTONL_FP(&pp->reftime, &ip->reftime); |
925 | HTONL_FP(&pp->aorg, &ip->org); | | 935 | HTONL_FP(&pp->aorg, &ip->org); |
926 | HTONL_FP(&pp->rec, &ip->rec); | | 936 | HTONL_FP(&pp->rec, &ip->rec); |
927 | HTONL_FP(&pp->xmt, &ip->xmt); | | 937 | HTONL_FP(&pp->xmt, &ip->xmt); |
928 | j = pp->filter_nextpt - 1; | | 938 | j = pp->filter_nextpt - 1; |
929 | for (i = 0; i < NTP_SHIFT; i++, j--) { | | 939 | for (i = 0; i < NTP_SHIFT; i++, j--) { |
930 | if (j < 0) | | 940 | if (j < 0) |
931 | j = NTP_SHIFT-1; | | 941 | j = NTP_SHIFT-1; |
932 | ip->filtdelay[i] = HTONS_FP(DTOFP(pp->filter_delay[j])); | | 942 | ip->filtdelay[i] = HTONS_FP(DTOFP(pp->filter_delay[j])); |
933 | DTOLFP(pp->filter_offset[j], <mp); | | 943 | DTOLFP(pp->filter_offset[j], <mp); |
934 | HTONL_FP(<mp, &ip->filtoffset[i]); | | 944 | HTONL_FP(<mp, &ip->filtoffset[i]); |
935 | ip->order[i] = (u_char)((pp->filter_nextpt+NTP_SHIFT-1) | | 945 | ip->order[i] = (u_char)((pp->filter_nextpt+NTP_SHIFT-1) |
936 | - pp->filter_order[i]); | | 946 | - pp->filter_order[i]); |
937 | if (ip->order[i] >= NTP_SHIFT) | | 947 | if (ip->order[i] >= NTP_SHIFT) |
938 | ip->order[i] -= NTP_SHIFT; | | 948 | ip->order[i] -= NTP_SHIFT; |
939 | } | | 949 | } |
940 | DTOLFP(pp->offset, <mp); | | 950 | DTOLFP(pp->offset, <mp); |
941 | HTONL_FP(<mp, &ip->offset); | | 951 | HTONL_FP(<mp, &ip->offset); |
942 | ip->delay = HTONS_FP(DTOFP(pp->delay)); | | 952 | ip->delay = HTONS_FP(DTOFP(pp->delay)); |
943 | ip->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp))); | | 953 | ip->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp))); |
944 | ip->selectdisp = HTONS_FP(DTOUFP(SQRT(pp->jitter))); | | 954 | ip->selectdisp = HTONS_FP(DTOUFP(SQRT(pp->jitter))); |
945 | ip = (struct info_peer *)more_pkt(); | | 955 | ip = (struct info_peer *)more_pkt(); |
946 | } | | 956 | } |
947 | flush_pkt(); | | 957 | flush_pkt(); |
948 | } | | 958 | } |
949 | | | 959 | |
950 | | | 960 | |
951 | /* | | 961 | /* |
952 | * peer_stats - send statistics for one or more peers | | 962 | * peer_stats - send statistics for one or more peers |
953 | */ | | 963 | */ |
954 | static void | | 964 | static void |
955 | peer_stats ( | | 965 | peer_stats ( |
956 | sockaddr_u *srcadr, | | 966 | sockaddr_u *srcadr, |
957 | struct interface *inter, | | 967 | struct interface *inter, |
958 | struct req_pkt *inpkt | | 968 | struct req_pkt *inpkt |
959 | ) | | 969 | ) |
960 | { | | 970 | { |
961 | register struct info_peer_list *ipl; | | 971 | struct info_peer_list ipl; |
962 | register struct peer *pp; | | 972 | register struct peer *pp; |
963 | register struct info_peer_stats *ip; | | 973 | register struct info_peer_stats *ip; |
964 | register int items; | | 974 | register int items; |
| | | 975 | size_t item_sz; |
| | | 976 | char * datap; |
965 | sockaddr_u addr; | | 977 | sockaddr_u addr; |
966 | extern struct peer *sys_peer; | | 978 | extern struct peer *sys_peer; |
967 | | | 979 | |
968 | #ifdef DEBUG | | 980 | #ifdef DEBUG |
969 | if (debug) | | 981 | if (debug) |
970 | printf("peer_stats: called\n"); | | 982 | printf("peer_stats: called\n"); |
971 | #endif | | 983 | #endif |
972 | items = INFO_NITEMS(inpkt->err_nitems); | | 984 | items = INFO_NITEMS(inpkt->err_nitems); |
973 | ipl = (struct info_peer_list *) inpkt->data; | | 985 | item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); |
| | | 986 | datap = inpkt->data; |
| | | 987 | if (item_sz > sizeof(ipl)) { |
| | | 988 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
| | | 989 | return; |
| | | 990 | } |
974 | ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt, | | 991 | ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt, |
975 | v6sizeof(struct info_peer_stats)); | | 992 | v6sizeof(struct info_peer_stats)); |
976 | while (items-- > 0 && ip != 0) { | | 993 | while (items-- > 0 && ip != 0) { |
| | | 994 | memset(&ipl,0,sizeof(ipl)); |
| | | 995 | memcpy(&ipl, datap, item_sz); |
977 | memset((char *)&addr, 0, sizeof(addr)); | | 996 | memset((char *)&addr, 0, sizeof(addr)); |
978 | NSRCPORT(&addr) = ipl->port; | | 997 | NSRCPORT(&addr) = ipl.port; |
979 | if (client_v6_capable && ipl->v6_flag) { | | 998 | if (client_v6_capable && ipl.v6_flag) { |
980 | AF(&addr) = AF_INET6; | | 999 | AF(&addr) = AF_INET6; |
981 | SOCK_ADDR6(&addr) = ipl->addr6; | | 1000 | SOCK_ADDR6(&addr) = ipl.addr6; |
982 | } else { | | 1001 | } else { |
983 | AF(&addr) = AF_INET; | | 1002 | AF(&addr) = AF_INET; |
984 | NSRCADR(&addr) = ipl->addr; | | 1003 | NSRCADR(&addr) = ipl.addr; |
985 | } | | 1004 | } |
986 | #ifdef ISC_PLATFORM_HAVESALEN | | 1005 | #ifdef ISC_PLATFORM_HAVESALEN |
987 | addr.sa.sa_len = SOCKLEN(&addr); | | 1006 | addr.sa.sa_len = SOCKLEN(&addr); |
988 | #endif | | 1007 | #endif |
989 | DPRINTF(1, ("peer_stats: looking for %s, %d, %d\n", | | 1008 | DPRINTF(1, ("peer_stats: looking for %s, %d, %d\n", |
990 | stoa(&addr), ipl->port, NSRCPORT(&addr))); | | 1009 | stoa(&addr), ipl.port, NSRCPORT(&addr))); |
991 | | | 1010 | |
992 | ipl = (struct info_peer_list *)((char *)ipl + | | 1011 | datap += item_sz; |
993 | INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
994 | | | 1012 | |
995 | pp = findexistingpeer(&addr, NULL, -1, 0); | | 1013 | pp = findexistingpeer(&addr, NULL, -1, 0); |
996 | if (NULL == pp) | | 1014 | if (NULL == pp) |
997 | continue; | | 1015 | continue; |
998 | | | 1016 | |
999 | DPRINTF(1, ("peer_stats: found %s\n", stoa(&addr))); | | 1017 | DPRINTF(1, ("peer_stats: found %s\n", stoa(&addr))); |
1000 | | | 1018 | |
1001 | if (IS_IPV4(&pp->srcadr)) { | | 1019 | if (IS_IPV4(&pp->srcadr)) { |
1002 | if (pp->dstadr) { | | 1020 | if (pp->dstadr) { |
1003 | if (!pp->processed) | | 1021 | if (!pp->processed) |
1004 | ip->dstadr = NSRCADR(&pp->dstadr->sin); | | 1022 | ip->dstadr = NSRCADR(&pp->dstadr->sin); |
1005 | else { | | 1023 | else { |
1006 | if (MDF_BCAST == pp->cast_flags) | | 1024 | if (MDF_BCAST == pp->cast_flags) |
1007 | ip->dstadr = NSRCADR(&pp->dstadr->bcast); | | 1025 | ip->dstadr = NSRCADR(&pp->dstadr->bcast); |
1008 | else if (pp->cast_flags) { | | 1026 | else if (pp->cast_flags) { |
1009 | ip->dstadr = NSRCADR(&pp->dstadr->sin); | | 1027 | ip->dstadr = NSRCADR(&pp->dstadr->sin); |
1010 | if (!ip->dstadr) | | 1028 | if (!ip->dstadr) |
1011 | ip->dstadr = NSRCADR(&pp->dstadr->bcast); | | 1029 | ip->dstadr = NSRCADR(&pp->dstadr->bcast); |
1012 | } | | 1030 | } |
1013 | } | | 1031 | } |
1014 | } else | | 1032 | } else |
1015 | ip->dstadr = 0; | | 1033 | ip->dstadr = 0; |
1016 | | | 1034 | |
1017 | ip->srcadr = NSRCADR(&pp->srcadr); | | 1035 | ip->srcadr = NSRCADR(&pp->srcadr); |
1018 | if (client_v6_capable) | | 1036 | if (client_v6_capable) |
1019 | ip->v6_flag = 0; | | 1037 | ip->v6_flag = 0; |
1020 | } else { | | 1038 | } else { |
1021 | if (pp->dstadr) | | 1039 | if (pp->dstadr) |
1022 | ip->dstadr6 = | | 1040 | ip->dstadr6 = |
1023 | (MDF_BCAST == pp->cast_flags) | | 1041 | (MDF_BCAST == pp->cast_flags) |
1024 | ? SOCK_ADDR6(&pp->dstadr->bcast) | | 1042 | ? SOCK_ADDR6(&pp->dstadr->bcast) |
1025 | : SOCK_ADDR6(&pp->dstadr->sin); | | 1043 | : SOCK_ADDR6(&pp->dstadr->sin); |
1026 | else | | 1044 | else |
1027 | memset(&ip->dstadr6, 0, sizeof(ip->dstadr6)); | | 1045 | memset(&ip->dstadr6, 0, sizeof(ip->dstadr6)); |
1028 | | | 1046 | |
1029 | ip->srcadr6 = SOCK_ADDR6(&pp->srcadr); | | 1047 | ip->srcadr6 = SOCK_ADDR6(&pp->srcadr); |
1030 | ip->v6_flag = 1; | | 1048 | ip->v6_flag = 1; |
1031 | } | | 1049 | } |
1032 | ip->srcport = NSRCPORT(&pp->srcadr); | | 1050 | ip->srcport = NSRCPORT(&pp->srcadr); |
1033 | ip->flags = 0; | | 1051 | ip->flags = 0; |
1034 | if (pp == sys_peer) | | 1052 | if (pp == sys_peer) |
1035 | ip->flags |= INFO_FLAG_SYSPEER; | | 1053 | ip->flags |= INFO_FLAG_SYSPEER; |
1036 | if (pp->flags & FLAG_CONFIG) | | 1054 | if (pp->flags & FLAG_CONFIG) |
1037 | ip->flags |= INFO_FLAG_CONFIG; | | 1055 | ip->flags |= INFO_FLAG_CONFIG; |
1038 | if (pp->flags & FLAG_REFCLOCK) | | 1056 | if (pp->flags & FLAG_REFCLOCK) |
1039 | ip->flags |= INFO_FLAG_REFCLOCK; | | 1057 | ip->flags |= INFO_FLAG_REFCLOCK; |
1040 | if (pp->flags & FLAG_PREFER) | | 1058 | if (pp->flags & FLAG_PREFER) |
1041 | ip->flags |= INFO_FLAG_PREFER; | | 1059 | ip->flags |= INFO_FLAG_PREFER; |
1042 | if (pp->flags & FLAG_BURST) | | 1060 | if (pp->flags & FLAG_BURST) |
1043 | ip->flags |= INFO_FLAG_BURST; | | 1061 | ip->flags |= INFO_FLAG_BURST; |
1044 | if (pp->flags & FLAG_IBURST) | | 1062 | if (pp->flags & FLAG_IBURST) |
1045 | ip->flags |= INFO_FLAG_IBURST; | | 1063 | ip->flags |= INFO_FLAG_IBURST; |
1046 | if (pp->status == CTL_PST_SEL_SYNCCAND) | | 1064 | if (pp->status == CTL_PST_SEL_SYNCCAND) |
1047 | ip->flags |= INFO_FLAG_SEL_CANDIDATE; | | 1065 | ip->flags |= INFO_FLAG_SEL_CANDIDATE; |
1048 | if (pp->status >= CTL_PST_SEL_SYSPEER) | | 1066 | if (pp->status >= CTL_PST_SEL_SYSPEER) |
1049 | ip->flags |= INFO_FLAG_SHORTLIST; | | 1067 | ip->flags |= INFO_FLAG_SHORTLIST; |
1050 | ip->flags = htons(ip->flags); | | 1068 | ip->flags = htons(ip->flags); |
1051 | ip->timereceived = htonl((u_int32)(current_time - pp->timereceived)); | | 1069 | ip->timereceived = htonl((u_int32)(current_time - pp->timereceived)); |
1052 | ip->timetosend = htonl(pp->nextdate - current_time); | | 1070 | ip->timetosend = htonl(pp->nextdate - current_time); |
1053 | ip->timereachable = htonl((u_int32)(current_time - pp->timereachable)); | | 1071 | ip->timereachable = htonl((u_int32)(current_time - pp->timereachable)); |
1054 | ip->sent = htonl((u_int32)(pp->sent)); | | 1072 | ip->sent = htonl((u_int32)(pp->sent)); |
1055 | ip->processed = htonl((u_int32)(pp->processed)); | | 1073 | ip->processed = htonl((u_int32)(pp->processed)); |
1056 | ip->badauth = htonl((u_int32)(pp->badauth)); | | 1074 | ip->badauth = htonl((u_int32)(pp->badauth)); |
1057 | ip->bogusorg = htonl((u_int32)(pp->bogusorg)); | | 1075 | ip->bogusorg = htonl((u_int32)(pp->bogusorg)); |
1058 | ip->oldpkt = htonl((u_int32)(pp->oldpkt)); | | 1076 | ip->oldpkt = htonl((u_int32)(pp->oldpkt)); |
1059 | ip->seldisp = htonl((u_int32)(pp->seldisptoolarge)); | | 1077 | ip->seldisp = htonl((u_int32)(pp->seldisptoolarge)); |
1060 | ip->selbroken = htonl((u_int32)(pp->selbroken)); | | 1078 | ip->selbroken = htonl((u_int32)(pp->selbroken)); |
1061 | ip->candidate = pp->status; | | 1079 | ip->candidate = pp->status; |
1062 | ip = (struct info_peer_stats *)more_pkt(); | | 1080 | ip = (struct info_peer_stats *)more_pkt(); |
1063 | } | | 1081 | } |
1064 | flush_pkt(); | | 1082 | flush_pkt(); |
1065 | } | | 1083 | } |
1066 | | | 1084 | |
1067 | | | 1085 | |
1068 | /* | | 1086 | /* |
1069 | * sys_info - return system info | | 1087 | * sys_info - return system info |
1070 | */ | | 1088 | */ |
1071 | static void | | 1089 | static void |
1072 | sys_info( | | 1090 | sys_info( |
1073 | sockaddr_u *srcadr, | | 1091 | sockaddr_u *srcadr, |
1074 | struct interface *inter, | | 1092 | struct interface *inter, |
1075 | struct req_pkt *inpkt | | 1093 | struct req_pkt *inpkt |
1076 | ) | | 1094 | ) |
1077 | { | | 1095 | { |
1078 | register struct info_sys *is; | | 1096 | register struct info_sys *is; |
1079 | | | 1097 | |
1080 | is = (struct info_sys *)prepare_pkt(srcadr, inter, inpkt, | | 1098 | is = (struct info_sys *)prepare_pkt(srcadr, inter, inpkt, |
1081 | v6sizeof(struct info_sys)); | | 1099 | v6sizeof(struct info_sys)); |
1082 | | | 1100 | |
1083 | if (sys_peer) { | | 1101 | if (sys_peer) { |
1084 | if (IS_IPV4(&sys_peer->srcadr)) { | | 1102 | if (IS_IPV4(&sys_peer->srcadr)) { |
1085 | is->peer = NSRCADR(&sys_peer->srcadr); | | 1103 | is->peer = NSRCADR(&sys_peer->srcadr); |
1086 | if (client_v6_capable) | | 1104 | if (client_v6_capable) |
1087 | is->v6_flag = 0; | | 1105 | is->v6_flag = 0; |
1088 | } else if (client_v6_capable) { | | 1106 | } else if (client_v6_capable) { |
1089 | is->peer6 = SOCK_ADDR6(&sys_peer->srcadr); | | 1107 | is->peer6 = SOCK_ADDR6(&sys_peer->srcadr); |
1090 | is->v6_flag = 1; | | 1108 | is->v6_flag = 1; |
1091 | } | | 1109 | } |
1092 | is->peer_mode = sys_peer->hmode; | | 1110 | is->peer_mode = sys_peer->hmode; |
1093 | } else { | | 1111 | } else { |
1094 | is->peer = 0; | | 1112 | is->peer = 0; |
1095 | if (client_v6_capable) { | | 1113 | if (client_v6_capable) { |
1096 | is->v6_flag = 0; | | 1114 | is->v6_flag = 0; |
1097 | } | | 1115 | } |
1098 | is->peer_mode = 0; | | 1116 | is->peer_mode = 0; |
1099 | } | | 1117 | } |
1100 | | | 1118 | |
1101 | is->leap = sys_leap; | | 1119 | is->leap = sys_leap; |
1102 | is->stratum = sys_stratum; | | 1120 | is->stratum = sys_stratum; |
1103 | is->precision = sys_precision; | | 1121 | is->precision = sys_precision; |
1104 | is->rootdelay = htonl(DTOFP(sys_rootdelay)); | | 1122 | is->rootdelay = htonl(DTOFP(sys_rootdelay)); |
1105 | is->rootdispersion = htonl(DTOUFP(sys_rootdisp)); | | 1123 | is->rootdispersion = htonl(DTOUFP(sys_rootdisp)); |
1106 | is->frequency = htonl(DTOFP(sys_jitter)); | | 1124 | is->frequency = htonl(DTOFP(sys_jitter)); |
1107 | is->stability = htonl(DTOUFP(clock_stability)); | | 1125 | is->stability = htonl(DTOUFP(clock_stability)); |
1108 | is->refid = sys_refid; | | 1126 | is->refid = sys_refid; |
1109 | HTONL_FP(&sys_reftime, &is->reftime); | | 1127 | HTONL_FP(&sys_reftime, &is->reftime); |
1110 | | | 1128 | |
1111 | is->poll = sys_poll; | | 1129 | is->poll = sys_poll; |
1112 | | | 1130 | |
1113 | is->flags = 0; | | 1131 | is->flags = 0; |
1114 | if (sys_authenticate) | | 1132 | if (sys_authenticate) |
1115 | is->flags |= INFO_FLAG_AUTHENTICATE; | | 1133 | is->flags |= INFO_FLAG_AUTHENTICATE; |
1116 | if (sys_bclient) | | 1134 | if (sys_bclient) |
1117 | is->flags |= INFO_FLAG_BCLIENT; | | 1135 | is->flags |= INFO_FLAG_BCLIENT; |
1118 | #ifdef REFCLOCK | | 1136 | #ifdef REFCLOCK |
1119 | if (cal_enable) | | 1137 | if (cal_enable) |
1120 | is->flags |= INFO_FLAG_CAL; | | 1138 | is->flags |= INFO_FLAG_CAL; |
1121 | #endif /* REFCLOCK */ | | 1139 | #endif /* REFCLOCK */ |
1122 | if (kern_enable) | | 1140 | if (kern_enable) |
1123 | is->flags |= INFO_FLAG_KERNEL; | | 1141 | is->flags |= INFO_FLAG_KERNEL; |
1124 | if (mon_enabled != MON_OFF) | | 1142 | if (mon_enabled != MON_OFF) |
1125 | is->flags |= INFO_FLAG_MONITOR; | | 1143 | is->flags |= INFO_FLAG_MONITOR; |
1126 | if (ntp_enable) | | 1144 | if (ntp_enable) |
1127 | is->flags |= INFO_FLAG_NTP; | | 1145 | is->flags |= INFO_FLAG_NTP; |
1128 | if (pps_enable) | | 1146 | if (pps_enable) |
1129 | is->flags |= INFO_FLAG_PPS_SYNC; | | 1147 | is->flags |= INFO_FLAG_PPS_SYNC; |
1130 | if (stats_control) | | 1148 | if (stats_control) |
1131 | is->flags |= INFO_FLAG_FILEGEN; | | 1149 | is->flags |= INFO_FLAG_FILEGEN; |
1132 | is->bdelay = HTONS_FP(DTOFP(sys_bdelay)); | | 1150 | is->bdelay = HTONS_FP(DTOFP(sys_bdelay)); |
1133 | HTONL_UF(sys_authdelay.l_f, &is->authdelay); | | 1151 | HTONL_UF(sys_authdelay.l_f, &is->authdelay); |
1134 | (void) more_pkt(); | | 1152 | (void) more_pkt(); |
1135 | flush_pkt(); | | 1153 | flush_pkt(); |
1136 | } | | 1154 | } |
1137 | | | 1155 | |
1138 | | | 1156 | |
1139 | /* | | 1157 | /* |
1140 | * sys_stats - return system statistics | | 1158 | * sys_stats - return system statistics |
1141 | */ | | 1159 | */ |
1142 | static void | | 1160 | static void |
1143 | sys_stats( | | 1161 | sys_stats( |
1144 | sockaddr_u *srcadr, | | 1162 | sockaddr_u *srcadr, |
1145 | struct interface *inter, | | 1163 | struct interface *inter, |
1146 | struct req_pkt *inpkt | | 1164 | struct req_pkt *inpkt |
1147 | ) | | 1165 | ) |
1148 | { | | 1166 | { |
1149 | register struct info_sys_stats *ss; | | 1167 | register struct info_sys_stats *ss; |
1150 | | | 1168 | |
1151 | /* | | 1169 | /* |
1152 | * Importations from the protocol module | | 1170 | * Importations from the protocol module |
1153 | */ | | 1171 | */ |
1154 | ss = (struct info_sys_stats *)prepare_pkt(srcadr, inter, inpkt, | | 1172 | ss = (struct info_sys_stats *)prepare_pkt(srcadr, inter, inpkt, |
1155 | sizeof(struct info_sys_stats)); | | 1173 | sizeof(struct info_sys_stats)); |
1156 | ss->timeup = htonl((u_int32)current_time); | | 1174 | ss->timeup = htonl((u_int32)current_time); |
1157 | ss->timereset = htonl((u_int32)(current_time - sys_stattime)); | | 1175 | ss->timereset = htonl((u_int32)(current_time - sys_stattime)); |
1158 | ss->denied = htonl((u_int32)sys_restricted); | | 1176 | ss->denied = htonl((u_int32)sys_restricted); |
1159 | ss->oldversionpkt = htonl((u_int32)sys_oldversion); | | 1177 | ss->oldversionpkt = htonl((u_int32)sys_oldversion); |
1160 | ss->newversionpkt = htonl((u_int32)sys_newversion); | | 1178 | ss->newversionpkt = htonl((u_int32)sys_newversion); |
1161 | ss->unknownversion = htonl((u_int32)sys_declined); | | 1179 | ss->unknownversion = htonl((u_int32)sys_declined); |
1162 | ss->badlength = htonl((u_int32)sys_badlength); | | 1180 | ss->badlength = htonl((u_int32)sys_badlength); |
1163 | ss->processed = htonl((u_int32)sys_processed); | | 1181 | ss->processed = htonl((u_int32)sys_processed); |
1164 | ss->badauth = htonl((u_int32)sys_badauth); | | 1182 | ss->badauth = htonl((u_int32)sys_badauth); |
1165 | ss->limitrejected = htonl((u_int32)sys_limitrejected); | | 1183 | ss->limitrejected = htonl((u_int32)sys_limitrejected); |
1166 | ss->received = htonl((u_int32)sys_received); | | 1184 | ss->received = htonl((u_int32)sys_received); |
1167 | (void) more_pkt(); | | 1185 | (void) more_pkt(); |
1168 | flush_pkt(); | | 1186 | flush_pkt(); |
1169 | } | | 1187 | } |
1170 | | | 1188 | |
1171 | | | 1189 | |
1172 | /* | | 1190 | /* |
1173 | * mem_stats - return memory statistics | | 1191 | * mem_stats - return memory statistics |
1174 | */ | | 1192 | */ |
1175 | static void | | 1193 | static void |
1176 | mem_stats( | | 1194 | mem_stats( |
1177 | sockaddr_u *srcadr, | | 1195 | sockaddr_u *srcadr, |
1178 | struct interface *inter, | | 1196 | struct interface *inter, |
1179 | struct req_pkt *inpkt | | 1197 | struct req_pkt *inpkt |
1180 | ) | | 1198 | ) |
1181 | { | | 1199 | { |
1182 | register struct info_mem_stats *ms; | | 1200 | register struct info_mem_stats *ms; |
1183 | register int i; | | 1201 | register int i; |
1184 | | | 1202 | |
1185 | /* | | 1203 | /* |
1186 | * Importations from the peer module | | 1204 | * Importations from the peer module |
1187 | */ | | 1205 | */ |
1188 | extern int peer_hash_count[]; | | 1206 | extern int peer_hash_count[]; |
1189 | extern int peer_free_count; | | 1207 | extern int peer_free_count; |
1190 | extern u_long peer_timereset; | | 1208 | extern u_long peer_timereset; |
1191 | extern u_long findpeer_calls; | | 1209 | extern u_long findpeer_calls; |
1192 | extern u_long peer_allocations; | | 1210 | extern u_long peer_allocations; |
1193 | extern u_long peer_demobilizations; | | 1211 | extern u_long peer_demobilizations; |
1194 | extern int total_peer_structs; | | 1212 | extern int total_peer_structs; |
1195 | | | 1213 | |
1196 | ms = (struct info_mem_stats *)prepare_pkt(srcadr, inter, inpkt, | | 1214 | ms = (struct info_mem_stats *)prepare_pkt(srcadr, inter, inpkt, |
1197 | sizeof(struct info_mem_stats)); | | 1215 | sizeof(struct info_mem_stats)); |
1198 | | | 1216 | |
1199 | ms->timereset = htonl((u_int32)(current_time - peer_timereset)); | | 1217 | ms->timereset = htonl((u_int32)(current_time - peer_timereset)); |
1200 | ms->totalpeermem = htons((u_short)total_peer_structs); | | 1218 | ms->totalpeermem = htons((u_short)total_peer_structs); |
1201 | ms->freepeermem = htons((u_short)peer_free_count); | | 1219 | ms->freepeermem = htons((u_short)peer_free_count); |
1202 | ms->findpeer_calls = htonl((u_int32)findpeer_calls); | | 1220 | ms->findpeer_calls = htonl((u_int32)findpeer_calls); |
1203 | ms->allocations = htonl((u_int32)peer_allocations); | | 1221 | ms->allocations = htonl((u_int32)peer_allocations); |
1204 | ms->demobilizations = htonl((u_int32)peer_demobilizations); | | 1222 | ms->demobilizations = htonl((u_int32)peer_demobilizations); |
1205 | | | 1223 | |
1206 | for (i = 0; i < NTP_HASH_SIZE; i++) { | | 1224 | for (i = 0; i < NTP_HASH_SIZE; i++) { |
1207 | if (peer_hash_count[i] > 255) | | 1225 | if (peer_hash_count[i] > 255) |
1208 | ms->hashcount[i] = 255; | | 1226 | ms->hashcount[i] = 255; |
1209 | else | | 1227 | else |
1210 | ms->hashcount[i] = (u_char)peer_hash_count[i]; | | 1228 | ms->hashcount[i] = (u_char)peer_hash_count[i]; |
1211 | } | | 1229 | } |
1212 | | | 1230 | |
1213 | (void) more_pkt(); | | 1231 | (void) more_pkt(); |
1214 | flush_pkt(); | | 1232 | flush_pkt(); |
1215 | } | | 1233 | } |
1216 | | | 1234 | |
1217 | | | 1235 | |
1218 | /* | | 1236 | /* |
1219 | * io_stats - return io statistics | | 1237 | * io_stats - return io statistics |
1220 | */ | | 1238 | */ |
1221 | static void | | 1239 | static void |
1222 | io_stats( | | 1240 | io_stats( |
1223 | sockaddr_u *srcadr, | | 1241 | sockaddr_u *srcadr, |
1224 | struct interface *inter, | | 1242 | struct interface *inter, |
1225 | struct req_pkt *inpkt | | 1243 | struct req_pkt *inpkt |
1226 | ) | | 1244 | ) |
1227 | { | | 1245 | { |
1228 | register struct info_io_stats *io; | | 1246 | register struct info_io_stats *io; |
1229 | | | 1247 | |
1230 | /* | | 1248 | /* |
1231 | * Importations from the io module | | 1249 | * Importations from the io module |
1232 | */ | | 1250 | */ |
1233 | extern u_long io_timereset; | | 1251 | extern u_long io_timereset; |
1234 | | | 1252 | |
1235 | io = (struct info_io_stats *)prepare_pkt(srcadr, inter, inpkt, | | 1253 | io = (struct info_io_stats *)prepare_pkt(srcadr, inter, inpkt, |
1236 | sizeof(struct info_io_stats)); | | 1254 | sizeof(struct info_io_stats)); |
1237 | | | 1255 | |
1238 | io->timereset = htonl((u_int32)(current_time - io_timereset)); | | 1256 | io->timereset = htonl((u_int32)(current_time - io_timereset)); |
1239 | io->totalrecvbufs = htons((u_short) total_recvbuffs()); | | 1257 | io->totalrecvbufs = htons((u_short) total_recvbuffs()); |
1240 | io->freerecvbufs = htons((u_short) free_recvbuffs()); | | 1258 | io->freerecvbufs = htons((u_short) free_recvbuffs()); |
1241 | io->fullrecvbufs = htons((u_short) full_recvbuffs()); | | 1259 | io->fullrecvbufs = htons((u_short) full_recvbuffs()); |
1242 | io->lowwater = htons((u_short) lowater_additions()); | | 1260 | io->lowwater = htons((u_short) lowater_additions()); |
1243 | io->dropped = htonl((u_int32)packets_dropped); | | 1261 | io->dropped = htonl((u_int32)packets_dropped); |
1244 | io->ignored = htonl((u_int32)packets_ignored); | | 1262 | io->ignored = htonl((u_int32)packets_ignored); |
1245 | io->received = htonl((u_int32)packets_received); | | 1263 | io->received = htonl((u_int32)packets_received); |
1246 | io->sent = htonl((u_int32)packets_sent); | | 1264 | io->sent = htonl((u_int32)packets_sent); |
1247 | io->notsent = htonl((u_int32)packets_notsent); | | 1265 | io->notsent = htonl((u_int32)packets_notsent); |
1248 | io->interrupts = htonl((u_int32)handler_calls); | | 1266 | io->interrupts = htonl((u_int32)handler_calls); |
1249 | io->int_received = htonl((u_int32)handler_pkts); | | 1267 | io->int_received = htonl((u_int32)handler_pkts); |
1250 | | | 1268 | |
1251 | (void) more_pkt(); | | 1269 | (void) more_pkt(); |
1252 | flush_pkt(); | | 1270 | flush_pkt(); |
1253 | } | | 1271 | } |
1254 | | | 1272 | |
1255 | | | 1273 | |
1256 | /* | | 1274 | /* |
1257 | * timer_stats - return timer statistics | | 1275 | * timer_stats - return timer statistics |
1258 | */ | | 1276 | */ |
1259 | static void | | 1277 | static void |
1260 | timer_stats( | | 1278 | timer_stats( |
1261 | sockaddr_u * srcadr, | | 1279 | sockaddr_u * srcadr, |
1262 | struct interface * inter, | | 1280 | struct interface * inter, |
1263 | struct req_pkt * inpkt | | 1281 | struct req_pkt * inpkt |
1264 | ) | | 1282 | ) |
1265 | { | | 1283 | { |
1266 | struct info_timer_stats * ts; | | 1284 | struct info_timer_stats * ts; |
1267 | u_long sincereset; | | 1285 | u_long sincereset; |
1268 | | | 1286 | |
1269 | ts = (struct info_timer_stats *)prepare_pkt(srcadr, inter, | | 1287 | ts = (struct info_timer_stats *)prepare_pkt(srcadr, inter, |
1270 | inpkt, sizeof(*ts)); | | 1288 | inpkt, sizeof(*ts)); |
1271 | | | 1289 | |
1272 | sincereset = current_time - timer_timereset; | | 1290 | sincereset = current_time - timer_timereset; |
1273 | ts->timereset = htonl((u_int32)sincereset); | | 1291 | ts->timereset = htonl((u_int32)sincereset); |
1274 | ts->alarms = ts->timereset; | | 1292 | ts->alarms = ts->timereset; |
1275 | ts->overflows = htonl((u_int32)alarm_overflow); | | 1293 | ts->overflows = htonl((u_int32)alarm_overflow); |
1276 | ts->xmtcalls = htonl((u_int32)timer_xmtcalls); | | 1294 | ts->xmtcalls = htonl((u_int32)timer_xmtcalls); |
1277 | | | 1295 | |
1278 | (void) more_pkt(); | | 1296 | (void) more_pkt(); |
1279 | flush_pkt(); | | 1297 | flush_pkt(); |
1280 | } | | 1298 | } |
1281 | | | 1299 | |
1282 | | | 1300 | |
1283 | /* | | 1301 | /* |
1284 | * loop_info - return the current state of the loop filter | | 1302 | * loop_info - return the current state of the loop filter |
1285 | */ | | 1303 | */ |
1286 | static void | | 1304 | static void |
1287 | loop_info( | | 1305 | loop_info( |
1288 | sockaddr_u *srcadr, | | 1306 | sockaddr_u *srcadr, |
1289 | struct interface *inter, | | 1307 | struct interface *inter, |
1290 | struct req_pkt *inpkt | | 1308 | struct req_pkt *inpkt |
1291 | ) | | 1309 | ) |
1292 | { | | 1310 | { |
1293 | register struct info_loop *li; | | 1311 | register struct info_loop *li; |
1294 | l_fp ltmp; | | 1312 | l_fp ltmp; |
1295 | | | 1313 | |
1296 | /* | | 1314 | /* |
1297 | * Importations from the loop filter module | | 1315 | * Importations from the loop filter module |
1298 | */ | | 1316 | */ |
1299 | extern double last_offset; | | 1317 | extern double last_offset; |
1300 | extern double drift_comp; | | 1318 | extern double drift_comp; |
1301 | extern int tc_counter; | | 1319 | extern int tc_counter; |
1302 | extern u_long sys_epoch; | | 1320 | extern u_long sys_epoch; |
1303 | | | 1321 | |
1304 | li = (struct info_loop *)prepare_pkt(srcadr, inter, inpkt, | | 1322 | li = (struct info_loop *)prepare_pkt(srcadr, inter, inpkt, |
1305 | sizeof(struct info_loop)); | | 1323 | sizeof(struct info_loop)); |
1306 | | | 1324 | |
1307 | DTOLFP(last_offset, <mp); | | 1325 | DTOLFP(last_offset, <mp); |
1308 | HTONL_FP(<mp, &li->last_offset); | | 1326 | HTONL_FP(<mp, &li->last_offset); |
1309 | DTOLFP(drift_comp * 1e6, <mp); | | 1327 | DTOLFP(drift_comp * 1e6, <mp); |
1310 | HTONL_FP(<mp, &li->drift_comp); | | 1328 | HTONL_FP(<mp, &li->drift_comp); |
1311 | li->compliance = htonl((u_int32)(tc_counter)); | | 1329 | li->compliance = htonl((u_int32)(tc_counter)); |
1312 | li->watchdog_timer = htonl((u_int32)(current_time - sys_epoch)); | | 1330 | li->watchdog_timer = htonl((u_int32)(current_time - sys_epoch)); |
1313 | | | 1331 | |
1314 | (void) more_pkt(); | | 1332 | (void) more_pkt(); |
1315 | flush_pkt(); | | 1333 | flush_pkt(); |
1316 | } | | 1334 | } |
1317 | | | 1335 | |
1318 | | | 1336 | |
1319 | /* | | 1337 | /* |
1320 | * do_conf - add a peer to the configuration list | | 1338 | * do_conf - add a peer to the configuration list |
1321 | */ | | 1339 | */ |
1322 | static void | | 1340 | static void |
1323 | do_conf( | | 1341 | do_conf( |
1324 | sockaddr_u *srcadr, | | 1342 | sockaddr_u *srcadr, |
1325 | struct interface *inter, | | 1343 | struct interface *inter, |
1326 | struct req_pkt *inpkt | | 1344 | struct req_pkt *inpkt |
1327 | ) | | 1345 | ) |
1328 | { | | 1346 | { |
1329 | static u_long soonest_ifrescan_time = 0; | | | |
1330 | int items; | | 1347 | int items; |
| | | 1348 | size_t item_sz; |
| | | 1349 | char * datap; |
1331 | u_int fl; | | 1350 | u_int fl; |
1332 | struct conf_peer *cp; | | | |
1333 | struct conf_peer temp_cp; | | 1351 | struct conf_peer temp_cp; |
1334 | sockaddr_u peeraddr; | | 1352 | sockaddr_u peeraddr; |
1335 | | | 1353 | |
1336 | /* | | 1354 | /* |
1337 | * Do a check of everything to see that it looks | | 1355 | * Do a check of everything to see that it looks |
1338 | * okay. If not, complain about it. Note we are | | 1356 | * okay. If not, complain about it. Note we are |
1339 | * very picky here. | | 1357 | * very picky here. |
1340 | */ | | 1358 | */ |
1341 | items = INFO_NITEMS(inpkt->err_nitems); | | 1359 | items = INFO_NITEMS(inpkt->err_nitems); |
1342 | cp = (struct conf_peer *)inpkt->data; | | 1360 | item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); |
1343 | memset(&temp_cp, 0, sizeof(struct conf_peer)); | | 1361 | datap = inpkt->data; |
1344 | memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | 1362 | if (item_sz > sizeof(temp_cp)) { |
1345 | | | | |
1346 | #if 0 /* paranoid checking - these are done in newpeer() */ | | | |
1347 | fl = 0; | | | |
1348 | while (items-- > 0 && !fl) { | | | |
1349 | if (((temp_cp.version) > NTP_VERSION) | | | |
1350 | || ((temp_cp.version) < NTP_OLDVERSION)) | | | |
1351 | fl = 1; | | | |
1352 | if (temp_cp.hmode != MODE_ACTIVE | | | |
1353 | && temp_cp.hmode != MODE_CLIENT | | | |
1354 | && temp_cp.hmode != MODE_BROADCAST) | | | |
1355 | fl = 1; | | | |
1356 | if (temp_cp.flags & ~(CONF_FLAG_PREFER | CONF_FLAG_BURST | | | | |
1357 | CONF_FLAG_IBURST | CONF_FLAG_SKEY)) | | | |
1358 | fl = 1; | | | |
1359 | cp = (struct conf_peer *) | | | |
1360 | ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
1361 | } | | | |
1362 | | | | |
1363 | if (fl) { | | | |
1364 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 1363 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
1365 | return; | | 1364 | return; |
1366 | } | | 1365 | } |
1367 | #endif /* end paranoid checking */ | | | |
1368 | | | | |
1369 | /* | | | |
1370 | * Looks okay, try it out | | | |
1371 | */ | | | |
1372 | items = INFO_NITEMS(inpkt->err_nitems); | | | |
1373 | cp = (struct conf_peer *)inpkt->data; | | | |
1374 | | | 1366 | |
1375 | while (items-- > 0) { | | 1367 | while (items-- > 0) { |
1376 | memset(&temp_cp, 0, sizeof(struct conf_peer)); | | 1368 | memset(&temp_cp, 0, sizeof(struct conf_peer)); |
1377 | memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | 1369 | memcpy(&temp_cp, datap, item_sz); |
1378 | ZERO_SOCK(&peeraddr); | | 1370 | ZERO_SOCK(&peeraddr); |
1379 | | | 1371 | |
1380 | fl = 0; | | 1372 | fl = 0; |
1381 | if (temp_cp.flags & CONF_FLAG_PREFER) | | 1373 | if (temp_cp.flags & CONF_FLAG_PREFER) |
1382 | fl |= FLAG_PREFER; | | 1374 | fl |= FLAG_PREFER; |
1383 | if (temp_cp.flags & CONF_FLAG_BURST) | | 1375 | if (temp_cp.flags & CONF_FLAG_BURST) |
1384 | fl |= FLAG_BURST; | | 1376 | fl |= FLAG_BURST; |
1385 | if (temp_cp.flags & CONF_FLAG_IBURST) | | 1377 | if (temp_cp.flags & CONF_FLAG_IBURST) |
1386 | fl |= FLAG_IBURST; | | 1378 | fl |= FLAG_IBURST; |
1387 | #ifdef OPENSSL | | 1379 | #ifdef OPENSSL |
1388 | if (temp_cp.flags & CONF_FLAG_SKEY) | | 1380 | if (temp_cp.flags & CONF_FLAG_SKEY) |
1389 | fl |= FLAG_SKEY; | | 1381 | fl |= FLAG_SKEY; |
1390 | #endif /* OPENSSL */ | | 1382 | #endif /* OPENSSL */ |
1391 | if (client_v6_capable && temp_cp.v6_flag != 0) { | | 1383 | if (client_v6_capable && temp_cp.v6_flag != 0) { |
1392 | AF(&peeraddr) = AF_INET6; | | 1384 | AF(&peeraddr) = AF_INET6; |
1393 | SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; | | 1385 | SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; |
1394 | } else { | | 1386 | } else { |
1395 | AF(&peeraddr) = AF_INET; | | 1387 | AF(&peeraddr) = AF_INET; |
1396 | NSRCADR(&peeraddr) = temp_cp.peeraddr; | | 1388 | NSRCADR(&peeraddr) = temp_cp.peeraddr; |
1397 | /* | | 1389 | /* |
1398 | * Make sure the address is valid | | 1390 | * Make sure the address is valid |
1399 | */ | | 1391 | */ |
1400 | if (!ISREFCLOCKADR(&peeraddr) && | | 1392 | if (!ISREFCLOCKADR(&peeraddr) && |
1401 | ISBADADR(&peeraddr)) { | | 1393 | ISBADADR(&peeraddr)) { |
1402 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 1394 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
1403 | return; | | 1395 | return; |
1404 | } | | 1396 | } |
1405 | | | 1397 | |
1406 | } | | 1398 | } |
1407 | NSRCPORT(&peeraddr) = htons(NTP_PORT); | | 1399 | NSRCPORT(&peeraddr) = htons(NTP_PORT); |
1408 | #ifdef ISC_PLATFORM_HAVESALEN | | 1400 | #ifdef ISC_PLATFORM_HAVESALEN |
1409 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); | | 1401 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); |
1410 | #endif | | 1402 | #endif |
1411 | | | 1403 | |
1412 | /* XXX W2DO? minpoll/maxpoll arguments ??? */ | | 1404 | /* XXX W2DO? minpoll/maxpoll arguments ??? */ |
1413 | if (peer_config(&peeraddr, (struct interface *)0, | | 1405 | if (peer_config(&peeraddr, (struct interface *)0, |
1414 | temp_cp.hmode, temp_cp.version, temp_cp.minpoll, | | 1406 | temp_cp.hmode, temp_cp.version, temp_cp.minpoll, |
1415 | temp_cp.maxpoll, fl, temp_cp.ttl, temp_cp.keyid, | | 1407 | temp_cp.maxpoll, fl, temp_cp.ttl, temp_cp.keyid, |
1416 | NULL) == 0) { | | 1408 | NULL) == 0) { |
1417 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | 1409 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
1418 | return; | | 1410 | return; |
1419 | } | | 1411 | } |
1420 | | | 1412 | |
1421 | /* | | 1413 | datap += item_sz; |
1422 | * ntp_intres.c uses REQ_CONFIG/doconf() to add each | | | |
1423 | * server after its name is resolved. If we have been | | | |
1424 | * disconnected from the network, it may notice the | | | |
1425 | * network has returned and add the first server while | | | |
1426 | * the relevant interface is still disabled, awaiting | | | |
1427 | * the next interface rescan. To get things moving | | | |
1428 | * more quickly, trigger an interface scan now, except | | | |
1429 | * if we have done so in the last half minute. | | | |
1430 | */ | | | |
1431 | if (soonest_ifrescan_time < current_time) { | | | |
1432 | soonest_ifrescan_time = current_time + 30; | | | |
1433 | timer_interfacetimeout(current_time); | | | |
1434 | DPRINTF(1, ("do_conf triggering interface rescan\n")); | | | |
1435 | } | | | |
1436 | | | | |
1437 | cp = (struct conf_peer *) | | | |
1438 | ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
1439 | } | | 1414 | } |
1440 | | | 1415 | |
1441 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 1416 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
1442 | } | | 1417 | } |
1443 | | | 1418 | |
1444 | #if 0 | | 1419 | #if 0 |
1445 | /* XXX */ | | 1420 | /* XXX */ |
1446 | /* | | 1421 | /* |
1447 | * dns_a - Snarf DNS info for an association ID | | 1422 | * dns_a - Snarf DNS info for an association ID |
1448 | */ | | 1423 | */ |
1449 | static void | | 1424 | static void |
1450 | dns_a( | | 1425 | dns_a( |
1451 | sockaddr_u *srcadr, | | 1426 | sockaddr_u *srcadr, |
1452 | struct interface *inter, | | 1427 | struct interface *inter, |
1453 | struct req_pkt *inpkt | | 1428 | struct req_pkt *inpkt |
1454 | ) | | 1429 | ) |
1455 | { | | 1430 | { |
1456 | register struct info_dns_assoc *dp; | | 1431 | register struct info_dns_assoc *dp; |
1457 | register int items; | | 1432 | register int items; |
1458 | struct sockaddr_in peeraddr; | | 1433 | struct sockaddr_in peeraddr; |
1459 | | | 1434 | |
1460 | /* | | 1435 | /* |
1461 | * Do a check of everything to see that it looks | | 1436 | * Do a check of everything to see that it looks |
1462 | * okay. If not, complain about it. Note we are | | 1437 | * okay. If not, complain about it. Note we are |
1463 | * very picky here. | | 1438 | * very picky here. |
1464 | */ | | 1439 | */ |
1465 | items = INFO_NITEMS(inpkt->err_nitems); | | 1440 | items = INFO_NITEMS(inpkt->err_nitems); |
1466 | dp = (struct info_dns_assoc *)inpkt->data; | | 1441 | dp = (struct info_dns_assoc *)inpkt->data; |
1467 | | | 1442 | |
1468 | /* | | 1443 | /* |
1469 | * Looks okay, try it out | | 1444 | * Looks okay, try it out |
1470 | */ | | 1445 | */ |
1471 | items = INFO_NITEMS(inpkt->err_nitems); | | 1446 | items = INFO_NITEMS(inpkt->err_nitems); |
1472 | dp = (struct info_dns_assoc *)inpkt->data; | | 1447 | dp = (struct info_dns_assoc *)inpkt->data; |
1473 | memset((char *)&peeraddr, 0, sizeof(struct sockaddr_in)); | | 1448 | memset((char *)&peeraddr, 0, sizeof(struct sockaddr_in)); |
1474 | peeraddr.sin_family = AF_INET; | | 1449 | peeraddr.sin_family = AF_INET; |
1475 | peeraddr.sin_port = htons(NTP_PORT); | | 1450 | peeraddr.sin_port = htons(NTP_PORT); |
1476 | | | 1451 | |
1477 | /* | | 1452 | /* |
1478 | * Make sure the address is valid | | 1453 | * Make sure the address is valid |
1479 | */ | | 1454 | */ |
1480 | if (!ISREFCLOCKADR(&peeraddr) && ISBADADR(&peeraddr)) { | | 1455 | if (!ISREFCLOCKADR(&peeraddr) && ISBADADR(&peeraddr)) { |
1481 | msyslog(LOG_ERR, "dns_a: !ISREFCLOCKADR && ISBADADR"); | | 1456 | msyslog(LOG_ERR, "dns_a: !ISREFCLOCKADR && ISBADADR"); |
1482 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 1457 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
1483 | return; | | 1458 | return; |
1484 | } | | 1459 | } |
1485 | | | 1460 | |
1486 | while (items-- > 0) { | | 1461 | while (items-- > 0) { |
1487 | associd_t associd; | | 1462 | associd_t associd; |
1488 | size_t hnl; | | 1463 | size_t hnl; |
1489 | struct peer *peer; | | 1464 | struct peer *peer; |
1490 | int bogon = 0; | | 1465 | int bogon = 0; |
1491 | | | 1466 | |
1492 | associd = dp->associd; | | 1467 | associd = dp->associd; |
1493 | peer = findpeerbyassoc(associd); | | 1468 | peer = findpeerbyassoc(associd); |
1494 | if (peer == 0 || peer->flags & FLAG_REFCLOCK) { | | 1469 | if (peer == 0 || peer->flags & FLAG_REFCLOCK) { |
1495 | msyslog(LOG_ERR, "dns_a: %s", | | 1470 | msyslog(LOG_ERR, "dns_a: %s", |
1496 | (peer == 0) | | 1471 | (peer == 0) |
1497 | ? "peer == 0" | | 1472 | ? "peer == 0" |
1498 | : "peer->flags & FLAG_REFCLOCK"); | | 1473 | : "peer->flags & FLAG_REFCLOCK"); |
1499 | ++bogon; | | 1474 | ++bogon; |
1500 | } | | 1475 | } |
1501 | peeraddr.sin_addr.s_addr = dp->peeraddr; | | 1476 | peeraddr.sin_addr.s_addr = dp->peeraddr; |
1502 | for (hnl = 0; dp->hostname[hnl] && hnl < sizeof dp->hostname; ++hnl) ; | | 1477 | for (hnl = 0; dp->hostname[hnl] && hnl < sizeof dp->hostname; ++hnl) ; |
1503 | if (hnl >= sizeof dp->hostname) { | | 1478 | if (hnl >= sizeof dp->hostname) { |
1504 | msyslog(LOG_ERR, "dns_a: hnl (%ld) >= %ld", | | 1479 | msyslog(LOG_ERR, "dns_a: hnl (%ld) >= %ld", |
1505 | (long)hnl, (long)sizeof dp->hostname); | | 1480 | (long)hnl, (long)sizeof dp->hostname); |
1506 | ++bogon; | | 1481 | ++bogon; |
1507 | } | | 1482 | } |
1508 | | | 1483 | |
1509 | msyslog(LOG_INFO, "dns_a: <%s> for %s, AssocID %d, bogon %d", | | 1484 | msyslog(LOG_INFO, "dns_a: <%s> for %s, AssocID %d, bogon %d", |
1510 | dp->hostname, | | 1485 | dp->hostname, |
1511 | stoa((sockaddr_u *)&peeraddr), associd, | | 1486 | stoa((sockaddr_u *)&peeraddr), associd, |
1512 | bogon); | | 1487 | bogon); |
1513 | | | 1488 | |
1514 | if (bogon) { | | 1489 | if (bogon) { |
1515 | /* If it didn't work */ | | 1490 | /* If it didn't work */ |
1516 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | 1491 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
1517 | return; | | 1492 | return; |
1518 | } else { | | 1493 | } else { |
1519 | #if 0 | | 1494 | #if 0 |
1520 | #ifdef PUBKEY | | 1495 | #ifdef PUBKEY |
1521 | crypto_public(peer, dp->hostname); | | 1496 | crypto_public(peer, dp->hostname); |
1522 | #endif /* PUBKEY */ | | 1497 | #endif /* PUBKEY */ |
1523 | #endif | | 1498 | #endif |
1524 | } | | 1499 | } |
1525 | | | 1500 | |
1526 | dp++; | | 1501 | dp++; |
1527 | } | | 1502 | } |
1528 | | | 1503 | |
1529 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 1504 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
1530 | } | | 1505 | } |
1531 | #endif /* 0 */ | | 1506 | #endif /* 0 */ |
1532 | | | 1507 | |
1533 | /* | | 1508 | /* |
1534 | * do_unconf - remove a peer from the configuration list | | 1509 | * do_unconf - remove a peer from the configuration list |
1535 | */ | | 1510 | */ |
1536 | static void | | 1511 | static void |
1537 | do_unconf( | | 1512 | do_unconf( |
1538 | sockaddr_u *srcadr, | | 1513 | sockaddr_u *srcadr, |
1539 | struct interface *inter, | | 1514 | struct interface *inter, |
1540 | struct req_pkt *inpkt | | 1515 | struct req_pkt *inpkt |
1541 | ) | | 1516 | ) |
1542 | { | | 1517 | { |
1543 | register struct conf_unpeer *cp; | | | |
1544 | struct conf_unpeer temp_cp; | | 1518 | struct conf_unpeer temp_cp; |
1545 | register int items; | | 1519 | register int items; |
| | | 1520 | size_t item_sz; |
| | | 1521 | char * datap; |
1546 | register struct peer *peer; | | 1522 | register struct peer *peer; |
1547 | sockaddr_u peeraddr; | | 1523 | sockaddr_u peeraddr; |
1548 | int bad, found; | | 1524 | int bad, found; |
1549 | | | 1525 | |
1550 | /* | | 1526 | /* |
1551 | * This is a bit unstructured, but I like to be careful. | | 1527 | * This is a bit unstructured, but I like to be careful. |
1552 | * We check to see that every peer exists and is actually | | 1528 | * We check to see that every peer exists and is actually |
1553 | * configured. If so, we remove them. If not, we return | | 1529 | * configured. If so, we remove them. If not, we return |
1554 | * an error. | | 1530 | * an error. |
1555 | */ | | 1531 | */ |
1556 | items = INFO_NITEMS(inpkt->err_nitems); | | 1532 | items = INFO_NITEMS(inpkt->err_nitems); |
1557 | cp = (struct conf_unpeer *)inpkt->data; | | 1533 | item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); |
| | | 1534 | datap = inpkt->data; |
| | | 1535 | if (item_sz > sizeof(temp_cp)) { |
| | | 1536 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
| | | 1537 | return; |
| | | 1538 | } |
1558 | | | 1539 | |
1559 | bad = 0; | | 1540 | bad = 0; |
1560 | while (items-- > 0 && !bad) { | | 1541 | while (items-- > 0 && !bad) { |
1561 | memset(&temp_cp, 0, sizeof(temp_cp)); | | 1542 | memset(&temp_cp, 0, sizeof(temp_cp)); |
| | | 1543 | memcpy(&temp_cp, datap, item_sz); |
1562 | ZERO_SOCK(&peeraddr); | | 1544 | ZERO_SOCK(&peeraddr); |
1563 | memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
1564 | if (client_v6_capable && temp_cp.v6_flag) { | | 1545 | if (client_v6_capable && temp_cp.v6_flag) { |
1565 | AF(&peeraddr) = AF_INET6; | | 1546 | AF(&peeraddr) = AF_INET6; |
1566 | SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; | | 1547 | SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; |
1567 | } else { | | 1548 | } else { |
1568 | AF(&peeraddr) = AF_INET; | | 1549 | AF(&peeraddr) = AF_INET; |
1569 | NSRCADR(&peeraddr) = temp_cp.peeraddr; | | 1550 | NSRCADR(&peeraddr) = temp_cp.peeraddr; |
1570 | } | | 1551 | } |
1571 | SET_PORT(&peeraddr, NTP_PORT); | | 1552 | SET_PORT(&peeraddr, NTP_PORT); |
1572 | #ifdef ISC_PLATFORM_HAVESALEN | | 1553 | #ifdef ISC_PLATFORM_HAVESALEN |
1573 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); | | 1554 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); |
1574 | #endif | | 1555 | #endif |
1575 | found = 0; | | 1556 | found = 0; |
1576 | peer = NULL; | | 1557 | peer = NULL; |
1577 | | | 1558 | |
1578 | DPRINTF(1, ("searching for %s\n", stoa(&peeraddr))); | | 1559 | DPRINTF(1, ("searching for %s\n", stoa(&peeraddr))); |
1579 | | | 1560 | |
1580 | while (!found) { | | 1561 | while (!found) { |
1581 | peer = findexistingpeer(&peeraddr, peer, -1, 0); | | 1562 | peer = findexistingpeer(&peeraddr, peer, -1, 0); |
1582 | if (!peer) | | 1563 | if (!peer) |
1583 | break; | | 1564 | break; |
1584 | if (peer->flags & FLAG_CONFIG) | | 1565 | if (peer->flags & FLAG_CONFIG) |
1585 | found = 1; | | 1566 | found = 1; |
1586 | } | | 1567 | } |
1587 | if (!found) | | 1568 | if (!found) |
1588 | bad = 1; | | 1569 | bad = 1; |
1589 | cp = (struct conf_unpeer *) | | 1570 | datap += item_sz; |
1590 | ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
1591 | } | | 1571 | } |
1592 | | | 1572 | |
1593 | if (bad) { | | 1573 | if (bad) { |
1594 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | 1574 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
1595 | return; | | 1575 | return; |
1596 | } | | 1576 | } |
1597 | | | 1577 | |
1598 | /* | | 1578 | /* |
1599 | * Now do it in earnest. | | 1579 | * Now do it in earnest. |
1600 | */ | | 1580 | */ |
1601 | | | 1581 | |
1602 | items = INFO_NITEMS(inpkt->err_nitems); | | 1582 | items = INFO_NITEMS(inpkt->err_nitems); |
1603 | cp = (struct conf_unpeer *)inpkt->data; | | 1583 | datap = inpkt->data; |
1604 | | | 1584 | |
1605 | while (items-- > 0) { | | 1585 | while (items-- > 0) { |
1606 | memset(&temp_cp, 0, sizeof(temp_cp)); | | 1586 | memset(&temp_cp, 0, sizeof(temp_cp)); |
| | | 1587 | memcpy(&temp_cp, datap, item_sz); |
1607 | memset(&peeraddr, 0, sizeof(peeraddr)); | | 1588 | memset(&peeraddr, 0, sizeof(peeraddr)); |
1608 | memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
1609 | if (client_v6_capable && temp_cp.v6_flag) { | | 1589 | if (client_v6_capable && temp_cp.v6_flag) { |
1610 | AF(&peeraddr) = AF_INET6; | | 1590 | AF(&peeraddr) = AF_INET6; |
1611 | SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; | | 1591 | SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; |
1612 | } else { | | 1592 | } else { |
1613 | AF(&peeraddr) = AF_INET; | | 1593 | AF(&peeraddr) = AF_INET; |
1614 | NSRCADR(&peeraddr) = temp_cp.peeraddr; | | 1594 | NSRCADR(&peeraddr) = temp_cp.peeraddr; |
1615 | } | | 1595 | } |
1616 | SET_PORT(&peeraddr, NTP_PORT); | | 1596 | SET_PORT(&peeraddr, NTP_PORT); |
1617 | #ifdef ISC_PLATFORM_HAVESALEN | | 1597 | #ifdef ISC_PLATFORM_HAVESALEN |
1618 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); | | 1598 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); |
1619 | #endif | | 1599 | #endif |
1620 | found = 0; | | 1600 | found = 0; |
1621 | peer = NULL; | | 1601 | peer = NULL; |
1622 | | | 1602 | |
1623 | while (!found) { | | 1603 | while (!found) { |
1624 | peer = findexistingpeer(&peeraddr, peer, -1, 0); | | 1604 | peer = findexistingpeer(&peeraddr, peer, -1, 0); |
1625 | if (!peer) | | 1605 | if (!peer) |
1626 | break; | | 1606 | break; |
1627 | if (peer->flags & FLAG_CONFIG) | | 1607 | if (peer->flags & FLAG_CONFIG) |
1628 | found = 1; | | 1608 | found = 1; |
1629 | } | | 1609 | } |
1630 | NTP_INSIST(found); | | 1610 | NTP_INSIST(found); |
1631 | NTP_INSIST(peer); | | 1611 | NTP_INSIST(peer); |
1632 | | | 1612 | |
1633 | peer_clear(peer, "GONE"); | | 1613 | peer_clear(peer, "GONE"); |
1634 | unpeer(peer); | | 1614 | unpeer(peer); |
1635 | | | 1615 | |
1636 | cp = (struct conf_unpeer *) | | 1616 | datap += item_sz; |
1637 | ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
1638 | } | | 1617 | } |
1639 | | | 1618 | |
1640 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 1619 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
1641 | } | | 1620 | } |
1642 | | | 1621 | |
1643 | | | 1622 | |
1644 | /* | | 1623 | /* |
1645 | * set_sys_flag - set system flags | | 1624 | * set_sys_flag - set system flags |
1646 | */ | | 1625 | */ |
1647 | static void | | 1626 | static void |
1648 | set_sys_flag( | | 1627 | set_sys_flag( |
1649 | sockaddr_u *srcadr, | | 1628 | sockaddr_u *srcadr, |
1650 | struct interface *inter, | | 1629 | struct interface *inter, |
1651 | struct req_pkt *inpkt | | 1630 | struct req_pkt *inpkt |
1652 | ) | | 1631 | ) |
1653 | { | | 1632 | { |
1654 | setclr_flags(srcadr, inter, inpkt, 1); | | 1633 | setclr_flags(srcadr, inter, inpkt, 1); |
1655 | } | | 1634 | } |
1656 | | | 1635 | |
1657 | | | 1636 | |
1658 | /* | | 1637 | /* |
1659 | * clr_sys_flag - clear system flags | | 1638 | * clr_sys_flag - clear system flags |
1660 | */ | | 1639 | */ |
1661 | static void | | 1640 | static void |
1662 | clr_sys_flag( | | 1641 | clr_sys_flag( |
1663 | sockaddr_u *srcadr, | | 1642 | sockaddr_u *srcadr, |
1664 | struct interface *inter, | | 1643 | struct interface *inter, |
1665 | struct req_pkt *inpkt | | 1644 | struct req_pkt *inpkt |
1666 | ) | | 1645 | ) |
1667 | { | | 1646 | { |
1668 | setclr_flags(srcadr, inter, inpkt, 0); | | 1647 | setclr_flags(srcadr, inter, inpkt, 0); |
1669 | } | | 1648 | } |
1670 | | | 1649 | |
1671 | | | 1650 | |
1672 | /* | | 1651 | /* |
1673 | * setclr_flags - do the grunge work of flag setting/clearing | | 1652 | * setclr_flags - do the grunge work of flag setting/clearing |
1674 | */ | | 1653 | */ |
1675 | static void | | 1654 | static void |
1676 | setclr_flags( | | 1655 | setclr_flags( |
1677 | sockaddr_u *srcadr, | | 1656 | sockaddr_u *srcadr, |
1678 | struct interface *inter, | | 1657 | struct interface *inter, |
1679 | struct req_pkt *inpkt, | | 1658 | struct req_pkt *inpkt, |
1680 | u_long set | | 1659 | u_long set |
1681 | ) | | 1660 | ) |
1682 | { | | 1661 | { |
1683 | struct conf_sys_flags *sf; | | 1662 | struct conf_sys_flags *sf; |
1684 | u_int32 flags; | | 1663 | u_int32 flags; |
1685 | int prev_kern_enable; | | 1664 | int prev_kern_enable; |
1686 | | | 1665 | |
1687 | prev_kern_enable = kern_enable; | | 1666 | prev_kern_enable = kern_enable; |
1688 | if (INFO_NITEMS(inpkt->err_nitems) > 1) { | | 1667 | if (INFO_NITEMS(inpkt->err_nitems) > 1) { |
1689 | msyslog(LOG_ERR, "setclr_flags: err_nitems > 1"); | | 1668 | msyslog(LOG_ERR, "setclr_flags: err_nitems > 1"); |
1690 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 1669 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
1691 | return; | | 1670 | return; |
1692 | } | | 1671 | } |
1693 | | | 1672 | |
1694 | sf = (struct conf_sys_flags *)inpkt->data; | | 1673 | sf = (struct conf_sys_flags *)inpkt->data; |
1695 | flags = ntohl(sf->flags); | | 1674 | flags = ntohl(sf->flags); |
1696 | | | 1675 | |
1697 | if (flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS | | | 1676 | if (flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS | |
1698 | SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR | | | 1677 | SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR | |
1699 | SYS_FLAG_FILEGEN | SYS_FLAG_AUTH | SYS_FLAG_CAL)) { | | 1678 | SYS_FLAG_FILEGEN | SYS_FLAG_AUTH | SYS_FLAG_CAL)) { |
1700 | msyslog(LOG_ERR, "setclr_flags: extra flags: %#x", | | 1679 | msyslog(LOG_ERR, "setclr_flags: extra flags: %#x", |
1701 | flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS | | | 1680 | flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS | |
1702 | SYS_FLAG_NTP | SYS_FLAG_KERNEL | | | 1681 | SYS_FLAG_NTP | SYS_FLAG_KERNEL | |
1703 | SYS_FLAG_MONITOR | SYS_FLAG_FILEGEN | | | 1682 | SYS_FLAG_MONITOR | SYS_FLAG_FILEGEN | |
1704 | SYS_FLAG_AUTH | SYS_FLAG_CAL)); | | 1683 | SYS_FLAG_AUTH | SYS_FLAG_CAL)); |
1705 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 1684 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
1706 | return; | | 1685 | return; |
1707 | } | | 1686 | } |
1708 | | | 1687 | |
1709 | if (flags & SYS_FLAG_BCLIENT) | | 1688 | if (flags & SYS_FLAG_BCLIENT) |
1710 | proto_config(PROTO_BROADCLIENT, set, 0., NULL); | | 1689 | proto_config(PROTO_BROADCLIENT, set, 0., NULL); |
1711 | if (flags & SYS_FLAG_PPS) | | 1690 | if (flags & SYS_FLAG_PPS) |
1712 | proto_config(PROTO_PPS, set, 0., NULL); | | 1691 | proto_config(PROTO_PPS, set, 0., NULL); |
1713 | if (flags & SYS_FLAG_NTP) | | 1692 | if (flags & SYS_FLAG_NTP) |
1714 | proto_config(PROTO_NTP, set, 0., NULL); | | 1693 | proto_config(PROTO_NTP, set, 0., NULL); |
1715 | if (flags & SYS_FLAG_KERNEL) | | 1694 | if (flags & SYS_FLAG_KERNEL) |
1716 | proto_config(PROTO_KERNEL, set, 0., NULL); | | 1695 | proto_config(PROTO_KERNEL, set, 0., NULL); |
1717 | if (flags & SYS_FLAG_MONITOR) | | 1696 | if (flags & SYS_FLAG_MONITOR) |
1718 | proto_config(PROTO_MONITOR, set, 0., NULL); | | 1697 | proto_config(PROTO_MONITOR, set, 0., NULL); |
1719 | if (flags & SYS_FLAG_FILEGEN) | | 1698 | if (flags & SYS_FLAG_FILEGEN) |
1720 | proto_config(PROTO_FILEGEN, set, 0., NULL); | | 1699 | proto_config(PROTO_FILEGEN, set, 0., NULL); |
1721 | if (flags & SYS_FLAG_AUTH) | | 1700 | if (flags & SYS_FLAG_AUTH) |
1722 | proto_config(PROTO_AUTHENTICATE, set, 0., NULL); | | 1701 | proto_config(PROTO_AUTHENTICATE, set, 0., NULL); |
1723 | if (flags & SYS_FLAG_CAL) | | 1702 | if (flags & SYS_FLAG_CAL) |
1724 | proto_config(PROTO_CAL, set, 0., NULL); | | 1703 | proto_config(PROTO_CAL, set, 0., NULL); |
1725 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 1704 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
1726 | | | 1705 | |
1727 | /* Reset the kernel ntp parameters if the kernel flag changed. */ | | 1706 | /* Reset the kernel ntp parameters if the kernel flag changed. */ |
1728 | if (prev_kern_enable && !kern_enable) | | 1707 | if (prev_kern_enable && !kern_enable) |
1729 | loop_config(LOOP_KERN_CLEAR, 0.0); | | 1708 | loop_config(LOOP_KERN_CLEAR, 0.0); |
1730 | if (!prev_kern_enable && kern_enable) | | 1709 | if (!prev_kern_enable && kern_enable) |
1731 | loop_config(LOOP_DRIFTCOMP, drift_comp); | | 1710 | loop_config(LOOP_DRIFTCOMP, drift_comp); |
1732 | } | | 1711 | } |
1733 | | | 1712 | |
1734 | /* | | 1713 | /* |
1735 | * list_restrict4 - recursive helper for list_restrict dumps IPv4 | | 1714 | * list_restrict4 - recursive helper for list_restrict dumps IPv4 |
1736 | * restriction list in reverse order. | | 1715 | * restriction list in reverse order. |
1737 | */ | | 1716 | */ |
1738 | static void | | 1717 | static void |
1739 | list_restrict4( | | 1718 | list_restrict4( |
1740 | restrict_u * res, | | 1719 | restrict_u * res, |
1741 | struct info_restrict ** ppir | | 1720 | struct info_restrict ** ppir |
1742 | ) | | 1721 | ) |
1743 | { | | 1722 | { |
1744 | struct info_restrict * pir; | | 1723 | struct info_restrict * pir; |
1745 | | | 1724 | |
1746 | if (res->link != NULL) | | 1725 | if (res->link != NULL) |
1747 | list_restrict4(res->link, ppir); | | 1726 | list_restrict4(res->link, ppir); |
1748 | | | 1727 | |
1749 | pir = *ppir; | | 1728 | pir = *ppir; |
1750 | pir->addr = htonl(res->u.v4.addr); | | 1729 | pir->addr = htonl(res->u.v4.addr); |
1751 | if (client_v6_capable) | | 1730 | if (client_v6_capable) |
1752 | pir->v6_flag = 0; | | 1731 | pir->v6_flag = 0; |
1753 | pir->mask = htonl(res->u.v4.mask); | | 1732 | pir->mask = htonl(res->u.v4.mask); |
1754 | pir->count = htonl(res->count); | | 1733 | pir->count = htonl(res->count); |
1755 | pir->flags = htons(res->flags); | | 1734 | pir->flags = htons(res->flags); |
1756 | pir->mflags = htons(res->mflags); | | 1735 | pir->mflags = htons(res->mflags); |
1757 | *ppir = (struct info_restrict *)more_pkt(); | | 1736 | *ppir = (struct info_restrict *)more_pkt(); |
1758 | } | | 1737 | } |
1759 | | | 1738 | |
1760 | | | 1739 | |
1761 | /* | | 1740 | /* |
1762 | * list_restrict6 - recursive helper for list_restrict dumps IPv6 | | 1741 | * list_restrict6 - recursive helper for list_restrict dumps IPv6 |
1763 | * restriction list in reverse order. | | 1742 | * restriction list in reverse order. |
1764 | */ | | 1743 | */ |
1765 | static void | | 1744 | static void |
1766 | list_restrict6( | | 1745 | list_restrict6( |
1767 | restrict_u * res, | | 1746 | restrict_u * res, |
1768 | struct info_restrict ** ppir | | 1747 | struct info_restrict ** ppir |
1769 | ) | | 1748 | ) |
1770 | { | | 1749 | { |
1771 | struct info_restrict * pir; | | 1750 | struct info_restrict * pir; |
1772 | | | 1751 | |
1773 | if (res->link != NULL) | | 1752 | if (res->link != NULL) |
1774 | list_restrict6(res->link, ppir); | | 1753 | list_restrict6(res->link, ppir); |
1775 | | | 1754 | |
1776 | pir = *ppir; | | 1755 | pir = *ppir; |
1777 | pir->addr6 = res->u.v6.addr; | | 1756 | pir->addr6 = res->u.v6.addr; |
1778 | pir->mask6 = res->u.v6.mask; | | 1757 | pir->mask6 = res->u.v6.mask; |
1779 | pir->v6_flag = 1; | | 1758 | pir->v6_flag = 1; |
1780 | pir->count = htonl(res->count); | | 1759 | pir->count = htonl(res->count); |
1781 | pir->flags = htons(res->flags); | | 1760 | pir->flags = htons(res->flags); |
1782 | pir->mflags = htons(res->mflags); | | 1761 | pir->mflags = htons(res->mflags); |
1783 | *ppir = (struct info_restrict *)more_pkt(); | | 1762 | *ppir = (struct info_restrict *)more_pkt(); |
1784 | } | | 1763 | } |
1785 | | | 1764 | |
1786 | | | 1765 | |
1787 | /* | | 1766 | /* |
1788 | * list_restrict - return the restrict list | | 1767 | * list_restrict - return the restrict list |
1789 | */ | | 1768 | */ |
1790 | static void | | 1769 | static void |
1791 | list_restrict( | | 1770 | list_restrict( |
1792 | sockaddr_u *srcadr, | | 1771 | sockaddr_u *srcadr, |
1793 | struct interface *inter, | | 1772 | struct interface *inter, |
1794 | struct req_pkt *inpkt | | 1773 | struct req_pkt *inpkt |
1795 | ) | | 1774 | ) |
1796 | { | | 1775 | { |
1797 | struct info_restrict *ir; | | 1776 | struct info_restrict *ir; |
1798 | | | 1777 | |
1799 | DPRINTF(3, ("wants restrict list summary\n")); | | 1778 | DPRINTF(3, ("wants restrict list summary\n")); |
1800 | | | 1779 | |
1801 | ir = (struct info_restrict *)prepare_pkt(srcadr, inter, inpkt, | | 1780 | ir = (struct info_restrict *)prepare_pkt(srcadr, inter, inpkt, |
1802 | v6sizeof(struct info_restrict)); | | 1781 | v6sizeof(struct info_restrict)); |
1803 | | | 1782 | |
1804 | /* | | 1783 | /* |
1805 | * The restriction lists are kept sorted in the reverse order | | 1784 | * The restriction lists are kept sorted in the reverse order |
1806 | * than they were originally. To preserve the output semantics, | | 1785 | * than they were originally. To preserve the output semantics, |
1807 | * dump each list in reverse order. A recursive helper function | | 1786 | * dump each list in reverse order. A recursive helper function |
1808 | * achieves that. | | 1787 | * achieves that. |
1809 | */ | | 1788 | */ |
1810 | list_restrict4(restrictlist4, &ir); | | 1789 | list_restrict4(restrictlist4, &ir); |
1811 | if (client_v6_capable) | | 1790 | if (client_v6_capable) |
1812 | list_restrict6(restrictlist6, &ir); | | 1791 | list_restrict6(restrictlist6, &ir); |
1813 | flush_pkt(); | | 1792 | flush_pkt(); |
1814 | } | | 1793 | } |
1815 | | | 1794 | |
1816 | | | 1795 | |
1817 | /* | | 1796 | /* |
1818 | * do_resaddflags - add flags to a restrict entry (or create one) | | 1797 | * do_resaddflags - add flags to a restrict entry (or create one) |
1819 | */ | | 1798 | */ |
1820 | static void | | 1799 | static void |
1821 | do_resaddflags( | | 1800 | do_resaddflags( |
1822 | sockaddr_u *srcadr, | | 1801 | sockaddr_u *srcadr, |
1823 | struct interface *inter, | | 1802 | struct interface *inter, |
1824 | struct req_pkt *inpkt | | 1803 | struct req_pkt *inpkt |
1825 | ) | | 1804 | ) |
1826 | { | | 1805 | { |
1827 | do_restrict(srcadr, inter, inpkt, RESTRICT_FLAGS); | | 1806 | do_restrict(srcadr, inter, inpkt, RESTRICT_FLAGS); |
1828 | } | | 1807 | } |
1829 | | | 1808 | |
1830 | | | 1809 | |
1831 | | | 1810 | |
1832 | /* | | 1811 | /* |
1833 | * do_ressubflags - remove flags from a restrict entry | | 1812 | * do_ressubflags - remove flags from a restrict entry |
1834 | */ | | 1813 | */ |
1835 | static void | | 1814 | static void |
1836 | do_ressubflags( | | 1815 | do_ressubflags( |
1837 | sockaddr_u *srcadr, | | 1816 | sockaddr_u *srcadr, |
1838 | struct interface *inter, | | 1817 | struct interface *inter, |
1839 | struct req_pkt *inpkt | | 1818 | struct req_pkt *inpkt |
1840 | ) | | 1819 | ) |
1841 | { | | 1820 | { |
1842 | do_restrict(srcadr, inter, inpkt, RESTRICT_UNFLAG); | | 1821 | do_restrict(srcadr, inter, inpkt, RESTRICT_UNFLAG); |
1843 | } | | 1822 | } |
1844 | | | 1823 | |
1845 | | | 1824 | |
1846 | /* | | 1825 | /* |
1847 | * do_unrestrict - remove a restrict entry from the list | | 1826 | * do_unrestrict - remove a restrict entry from the list |
1848 | */ | | 1827 | */ |
1849 | static void | | 1828 | static void |
1850 | do_unrestrict( | | 1829 | do_unrestrict( |
1851 | sockaddr_u *srcadr, | | 1830 | sockaddr_u *srcadr, |
1852 | struct interface *inter, | | 1831 | struct interface *inter, |
1853 | struct req_pkt *inpkt | | 1832 | struct req_pkt *inpkt |
1854 | ) | | 1833 | ) |
1855 | { | | 1834 | { |
1856 | do_restrict(srcadr, inter, inpkt, RESTRICT_REMOVE); | | 1835 | do_restrict(srcadr, inter, inpkt, RESTRICT_REMOVE); |
1857 | } | | 1836 | } |
1858 | | | 1837 | |
1859 | | | 1838 | |
1860 | /* | | 1839 | /* |
1861 | * do_restrict - do the dirty stuff of dealing with restrictions | | 1840 | * do_restrict - do the dirty stuff of dealing with restrictions |
1862 | */ | | 1841 | */ |
1863 | static void | | 1842 | static void |
1864 | do_restrict( | | 1843 | do_restrict( |
1865 | sockaddr_u *srcadr, | | 1844 | sockaddr_u *srcadr, |
1866 | struct interface *inter, | | 1845 | struct interface *inter, |
1867 | struct req_pkt *inpkt, | | 1846 | struct req_pkt *inpkt, |
1868 | int op | | 1847 | int op |
1869 | ) | | 1848 | ) |
1870 | { | | 1849 | { |
1871 | register struct conf_restrict *cr; | | 1850 | struct conf_restrict cr; |
1872 | register int items; | | 1851 | register int items; |
| | | 1852 | size_t item_sz; |
| | | 1853 | char * datap; |
1873 | sockaddr_u matchaddr; | | 1854 | sockaddr_u matchaddr; |
1874 | sockaddr_u matchmask; | | 1855 | sockaddr_u matchmask; |
1875 | int bad; | | 1856 | int bad; |
1876 | | | 1857 | |
1877 | /* | | 1858 | /* |
1878 | * Do a check of the flags to make sure that only | | 1859 | * Do a check of the flags to make sure that only |
1879 | * the NTPPORT flag is set, if any. If not, complain | | 1860 | * the NTPPORT flag is set, if any. If not, complain |
1880 | * about it. Note we are very picky here. | | 1861 | * about it. Note we are very picky here. |
1881 | */ | | 1862 | */ |
1882 | items = INFO_NITEMS(inpkt->err_nitems); | | 1863 | items = INFO_NITEMS(inpkt->err_nitems); |
1883 | cr = (struct conf_restrict *)inpkt->data; | | 1864 | item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); |
| | | 1865 | datap = inpkt->data; |
| | | 1866 | if (item_sz > sizeof(cr)) { |
| | | 1867 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
| | | 1868 | return; |
| | | 1869 | } |
1884 | | | 1870 | |
1885 | bad = 0; | | 1871 | bad = 0; |
1886 | cr->flags = ntohs(cr->flags); | | | |
1887 | cr->mflags = ntohs(cr->mflags); | | | |
1888 | while (items-- > 0 && !bad) { | | 1872 | while (items-- > 0 && !bad) { |
1889 | if (cr->mflags & ~(RESM_NTPONLY)) | | 1873 | memcpy(&cr, datap, item_sz); |
| | | 1874 | cr.flags = ntohs(cr.flags); |
| | | 1875 | cr.mflags = ntohs(cr.mflags); |
| | | 1876 | if (cr.mflags & ~(RESM_NTPONLY)) |
1890 | bad |= 1; | | 1877 | bad |= 1; |
1891 | if (cr->flags & ~(RES_ALLFLAGS)) | | 1878 | if (cr.flags & ~(RES_ALLFLAGS)) |
1892 | bad |= 2; | | 1879 | bad |= 2; |
1893 | if (cr->mask != htonl(INADDR_ANY)) { | | 1880 | if (cr.mask != htonl(INADDR_ANY)) { |
1894 | if (client_v6_capable && cr->v6_flag != 0) { | | 1881 | if (client_v6_capable && cr.v6_flag != 0) { |
1895 | if (IN6_IS_ADDR_UNSPECIFIED(&cr->addr6)) | | 1882 | if (IN6_IS_ADDR_UNSPECIFIED(&cr.addr6)) |
1896 | bad |= 4; | | 1883 | bad |= 4; |
1897 | } else | | 1884 | } else |
1898 | if (cr->addr == htonl(INADDR_ANY)) | | 1885 | if (cr.addr == htonl(INADDR_ANY)) |
1899 | bad |= 8; | | 1886 | bad |= 8; |
1900 | } | | 1887 | } |
1901 | cr = (struct conf_restrict *)((char *)cr + | | 1888 | datap += item_sz; |
1902 | INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
1903 | } | | 1889 | } |
1904 | | | 1890 | |
1905 | if (bad) { | | 1891 | if (bad) { |
1906 | msyslog(LOG_ERR, "do_restrict: bad = %#x", bad); | | 1892 | msyslog(LOG_ERR, "do_restrict: bad = %#x", bad); |
1907 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 1893 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
1908 | return; | | 1894 | return; |
1909 | } | | 1895 | } |
1910 | | | 1896 | |
1911 | /* | | 1897 | /* |
1912 | * Looks okay, try it out | | 1898 | * Looks okay, try it out |
1913 | */ | | 1899 | */ |
1914 | items = INFO_NITEMS(inpkt->err_nitems); | | | |
1915 | cr = (struct conf_restrict *)inpkt->data; | | | |
1916 | ZERO_SOCK(&matchaddr); | | 1900 | ZERO_SOCK(&matchaddr); |
1917 | ZERO_SOCK(&matchmask); | | 1901 | ZERO_SOCK(&matchmask); |
| | | 1902 | datap = inpkt->data; |
1918 | | | 1903 | |
1919 | while (items-- > 0) { | | 1904 | while (items-- > 0) { |
1920 | if (client_v6_capable && cr->v6_flag) { | | 1905 | memcpy(&cr, datap, item_sz); |
| | | 1906 | cr.flags = ntohs(cr.flags); |
| | | 1907 | cr.mflags = ntohs(cr.mflags); |
| | | 1908 | if (client_v6_capable && cr.v6_flag) { |
1921 | AF(&matchaddr) = AF_INET6; | | 1909 | AF(&matchaddr) = AF_INET6; |
1922 | AF(&matchmask) = AF_INET6; | | 1910 | AF(&matchmask) = AF_INET6; |
1923 | SOCK_ADDR6(&matchaddr) = cr->addr6; | | 1911 | SOCK_ADDR6(&matchaddr) = cr.addr6; |
1924 | SOCK_ADDR6(&matchmask) = cr->mask6; | | 1912 | SOCK_ADDR6(&matchmask) = cr.mask6; |
1925 | } else { | | 1913 | } else { |
1926 | AF(&matchaddr) = AF_INET; | | 1914 | AF(&matchaddr) = AF_INET; |
1927 | AF(&matchmask) = AF_INET; | | 1915 | AF(&matchmask) = AF_INET; |
1928 | NSRCADR(&matchaddr) = cr->addr; | | 1916 | NSRCADR(&matchaddr) = cr.addr; |
1929 | NSRCADR(&matchmask) = cr->mask; | | 1917 | NSRCADR(&matchmask) = cr.mask; |
1930 | } | | 1918 | } |
1931 | hack_restrict(op, &matchaddr, &matchmask, cr->mflags, | | 1919 | hack_restrict(op, &matchaddr, &matchmask, cr.mflags, |
1932 | cr->flags); | | 1920 | cr.flags); |
1933 | cr++; | | 1921 | datap += item_sz; |
1934 | } | | 1922 | } |
1935 | | | 1923 | |
1936 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 1924 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
1937 | } | | 1925 | } |
1938 | | | 1926 | |
1939 | | | 1927 | |
1940 | /* | | 1928 | /* |
1941 | * mon_getlist - return monitor data | | 1929 | * mon_getlist - return monitor data |
1942 | */ | | 1930 | */ |
1943 | static void | | 1931 | static void |
1944 | mon_getlist_0( | | 1932 | mon_getlist( |
1945 | sockaddr_u *srcadr, | | | |
1946 | struct interface *inter, | | | |
1947 | struct req_pkt *inpkt | | | |
1948 | ) | | | |
1949 | { | | | |
1950 | register struct info_monitor *im; | | | |
1951 | register struct mon_data *md; | | | |
1952 | extern struct mon_data mon_mru_list; | | | |
1953 | extern int mon_enabled; | | | |
1954 | | | | |
1955 | #ifdef DEBUG | | | |
1956 | if (debug > 2) | | | |
1957 | printf("wants monitor 0 list\n"); | | | |
1958 | #endif | | | |
1959 | if (!mon_enabled) { | | | |
1960 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | | |
1961 | return; | | | |
1962 | } | | | |
1963 | im = (struct info_monitor *)prepare_pkt(srcadr, inter, inpkt, | | | |
1964 | v6sizeof(struct info_monitor)); | | | |
1965 | for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0; | | | |
1966 | md = md->mru_next) { | | | |
1967 | im->lasttime = htonl((u_int32)((current_time - | | | |
1968 | md->firsttime) / md->count)); | | | |
1969 | im->firsttime = htonl((u_int32)(current_time - md->lasttime)); | | | |
1970 | im->restr = htonl((u_int32)md->flags); | | | |
1971 | im->count = htonl((u_int32)(md->count)); | | | |
1972 | if (IS_IPV6(&md->rmtadr)) { | | | |
1973 | if (!client_v6_capable) | | | |
1974 | continue; | | | |
1975 | im->addr6 = SOCK_ADDR6(&md->rmtadr); | | | |
1976 | im->v6_flag = 1; | | | |
1977 | } else { | | | |
1978 | im->addr = NSRCADR(&md->rmtadr); | | | |
1979 | if (client_v6_capable) | | | |
1980 | im->v6_flag = 0; | | | |
1981 | } | | | |
1982 | im->port = md->rmtport; | | | |
1983 | im->mode = md->mode; | | | |
1984 | im->version = md->version; | | | |
1985 | im = (struct info_monitor *)more_pkt(); | | | |
1986 | } | | | |
1987 | flush_pkt(); | | | |
1988 | } | | | |
1989 | | | | |
1990 | /* | | | |
1991 | * mon_getlist - return monitor data | | | |
1992 | */ | | | |
1993 | static void | | | |
1994 | mon_getlist_1( | | | |
1995 | sockaddr_u *srcadr, | | 1933 | sockaddr_u *srcadr, |
1996 | struct interface *inter, | | 1934 | struct interface *inter, |
1997 | struct req_pkt *inpkt | | 1935 | struct req_pkt *inpkt |
1998 | ) | | 1936 | ) |
1999 | { | | 1937 | { |
2000 | register struct info_monitor_1 *im; | | 1938 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
2001 | register struct mon_data *md; | | | |
2002 | extern struct mon_data mon_mru_list; | | | |
2003 | extern int mon_enabled; | | | |
2004 | | | | |
2005 | if (!mon_enabled) { | | | |
2006 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | | |
2007 | return; | | | |
2008 | } | | | |
2009 | im = (struct info_monitor_1 *)prepare_pkt(srcadr, inter, inpkt, | | | |
2010 | v6sizeof(struct info_monitor_1)); | | | |
2011 | for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0; | | | |
2012 | md = md->mru_next) { | | | |
2013 | im->lasttime = htonl((u_int32)((current_time - | | | |
2014 | md->firsttime) / md->count)); | | | |
2015 | im->firsttime = htonl((u_int32)(current_time - md->lasttime)); | | | |
2016 | im->restr = htonl((u_int32)md->flags); | | | |
2017 | im->count = htonl((u_int32)md->count); | | | |
2018 | if (IS_IPV6(&md->rmtadr)) { | | | |
2019 | if (!client_v6_capable) | | | |
2020 | continue; | | | |
2021 | im->addr6 = SOCK_ADDR6(&md->rmtadr); | | | |
2022 | im->v6_flag = 1; | | | |
2023 | im->daddr6 = SOCK_ADDR6(&md->interface->sin); | | | |
2024 | } else { | | | |
2025 | im->addr = NSRCADR(&md->rmtadr); | | | |
2026 | if (client_v6_capable) | | | |
2027 | im->v6_flag = 0; | | | |
2028 | if (MDF_BCAST == md->cast_flags) | | | |
2029 | im->daddr = NSRCADR(&md->interface->bcast); | | | |
2030 | else if (md->cast_flags) { | | | |
2031 | im->daddr = NSRCADR(&md->interface->sin); | | | |
2032 | if (!im->daddr) | | | |
2033 | im->daddr = NSRCADR(&md->interface->bcast); | | | |
2034 | } else | | | |
2035 | im->daddr = 4; | | | |
2036 | } | | | |
2037 | im->flags = htonl(md->cast_flags); | | | |
2038 | im->port = md->rmtport; | | | |
2039 | im->mode = md->mode; | | | |
2040 | im->version = md->version; | | | |
2041 | im = (struct info_monitor_1 *)more_pkt(); | | | |
2042 | } | | | |
2043 | flush_pkt(); | | | |
2044 | } | | 1939 | } |
2045 | | | 1940 | |
2046 | /* | | 1941 | /* |
2047 | * Module entry points and the flags they correspond with | | 1942 | * Module entry points and the flags they correspond with |
2048 | */ | | 1943 | */ |
2049 | struct reset_entry { | | 1944 | struct reset_entry { |
2050 | int flag; /* flag this corresponds to */ | | 1945 | int flag; /* flag this corresponds to */ |
2051 | void (*handler) (void); /* routine to handle request */ | | 1946 | void (*handler) (void); /* routine to handle request */ |
2052 | }; | | 1947 | }; |
2053 | | | 1948 | |
2054 | struct reset_entry reset_entries[] = { | | 1949 | struct reset_entry reset_entries[] = { |
2055 | { RESET_FLAG_ALLPEERS, peer_all_reset }, | | 1950 | { RESET_FLAG_ALLPEERS, peer_all_reset }, |
2056 | { RESET_FLAG_IO, io_clr_stats }, | | 1951 | { RESET_FLAG_IO, io_clr_stats }, |
2057 | { RESET_FLAG_SYS, proto_clr_stats }, | | 1952 | { RESET_FLAG_SYS, proto_clr_stats }, |
2058 | { RESET_FLAG_MEM, peer_clr_stats }, | | 1953 | { RESET_FLAG_MEM, peer_clr_stats }, |
2059 | { RESET_FLAG_TIMER, timer_clr_stats }, | | 1954 | { RESET_FLAG_TIMER, timer_clr_stats }, |
2060 | { RESET_FLAG_AUTH, reset_auth_stats }, | | 1955 | { RESET_FLAG_AUTH, reset_auth_stats }, |
2061 | { RESET_FLAG_CTL, ctl_clr_stats }, | | 1956 | { RESET_FLAG_CTL, ctl_clr_stats }, |
2062 | { 0, 0 } | | 1957 | { 0, 0 } |
2063 | }; | | 1958 | }; |
2064 | | | 1959 | |
2065 | /* | | 1960 | /* |
2066 | * reset_stats - reset statistic counters here and there | | 1961 | * reset_stats - reset statistic counters here and there |
2067 | */ | | 1962 | */ |
2068 | static void | | 1963 | static void |
2069 | reset_stats( | | 1964 | reset_stats( |
2070 | sockaddr_u *srcadr, | | 1965 | sockaddr_u *srcadr, |
2071 | struct interface *inter, | | 1966 | struct interface *inter, |
2072 | struct req_pkt *inpkt | | 1967 | struct req_pkt *inpkt |
2073 | ) | | 1968 | ) |
2074 | { | | 1969 | { |
2075 | struct reset_flags *rflags; | | 1970 | struct reset_flags *rflags; |
2076 | u_long flags; | | 1971 | u_long flags; |
2077 | struct reset_entry *rent; | | 1972 | struct reset_entry *rent; |
2078 | | | 1973 | |
2079 | if (INFO_NITEMS(inpkt->err_nitems) > 1) { | | 1974 | if (INFO_NITEMS(inpkt->err_nitems) > 1) { |
2080 | msyslog(LOG_ERR, "reset_stats: err_nitems > 1"); | | 1975 | msyslog(LOG_ERR, "reset_stats: err_nitems > 1"); |
2081 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 1976 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
2082 | return; | | 1977 | return; |
2083 | } | | 1978 | } |
2084 | | | 1979 | |
2085 | rflags = (struct reset_flags *)inpkt->data; | | 1980 | rflags = (struct reset_flags *)inpkt->data; |
2086 | flags = ntohl(rflags->flags); | | 1981 | flags = ntohl(rflags->flags); |
2087 | | | 1982 | |
2088 | if (flags & ~RESET_ALLFLAGS) { | | 1983 | if (flags & ~RESET_ALLFLAGS) { |
2089 | msyslog(LOG_ERR, "reset_stats: reset leaves %#lx", | | 1984 | msyslog(LOG_ERR, "reset_stats: reset leaves %#lx", |
2090 | flags & ~RESET_ALLFLAGS); | | 1985 | flags & ~RESET_ALLFLAGS); |
2091 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 1986 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
2092 | return; | | 1987 | return; |
2093 | } | | 1988 | } |
2094 | | | 1989 | |
2095 | for (rent = reset_entries; rent->flag != 0; rent++) { | | 1990 | for (rent = reset_entries; rent->flag != 0; rent++) { |
2096 | if (flags & rent->flag) | | 1991 | if (flags & rent->flag) |
2097 | (*rent->handler)(); | | 1992 | (*rent->handler)(); |
2098 | } | | 1993 | } |
2099 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 1994 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
2100 | } | | 1995 | } |
2101 | | | 1996 | |
2102 | | | 1997 | |
2103 | /* | | 1998 | /* |
2104 | * reset_peer - clear a peer's statistics | | 1999 | * reset_peer - clear a peer's statistics |
2105 | */ | | 2000 | */ |
2106 | static void | | 2001 | static void |
2107 | reset_peer( | | 2002 | reset_peer( |
2108 | sockaddr_u *srcadr, | | 2003 | sockaddr_u *srcadr, |
2109 | struct interface *inter, | | 2004 | struct interface *inter, |
2110 | struct req_pkt *inpkt | | 2005 | struct req_pkt *inpkt |
2111 | ) | | 2006 | ) |
2112 | { | | 2007 | { |
2113 | struct conf_unpeer *cp; | | 2008 | struct conf_unpeer cp; |
2114 | int items; | | 2009 | int items; |
| | | 2010 | size_t item_sz; |
| | | 2011 | char * datap; |
2115 | struct peer *peer; | | 2012 | struct peer *peer; |
2116 | sockaddr_u peeraddr; | | 2013 | sockaddr_u peeraddr; |
2117 | int bad; | | 2014 | int bad; |
2118 | | | 2015 | |
2119 | /* | | 2016 | /* |
2120 | * We check first to see that every peer exists. If not, | | 2017 | * We check first to see that every peer exists. If not, |
2121 | * we return an error. | | 2018 | * we return an error. |
2122 | */ | | 2019 | */ |
2123 | | | 2020 | |
2124 | items = INFO_NITEMS(inpkt->err_nitems); | | 2021 | items = INFO_NITEMS(inpkt->err_nitems); |
2125 | cp = (struct conf_unpeer *)inpkt->data; | | 2022 | item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); |
| | | 2023 | datap = inpkt->data; |
| | | 2024 | if (item_sz > sizeof(cp)) { |
| | | 2025 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
| | | 2026 | return; |
| | | 2027 | } |
2126 | | | 2028 | |
2127 | bad = 0; | | 2029 | bad = 0; |
2128 | while (items-- > 0 && !bad) { | | 2030 | while (items-- > 0 && !bad) { |
| | | 2031 | memset(&cp,0,sizeof(cp)); |
| | | 2032 | memcpy(&cp, datap, item_sz); |
2129 | ZERO_SOCK(&peeraddr); | | 2033 | ZERO_SOCK(&peeraddr); |
2130 | if (client_v6_capable && cp->v6_flag) { | | 2034 | if (client_v6_capable && cp.v6_flag) { |
2131 | AF(&peeraddr) = AF_INET6; | | 2035 | AF(&peeraddr) = AF_INET6; |
2132 | SOCK_ADDR6(&peeraddr) = cp->peeraddr6; | | 2036 | SOCK_ADDR6(&peeraddr) = cp.peeraddr6; |
2133 | } else { | | 2037 | } else { |
2134 | AF(&peeraddr) = AF_INET; | | 2038 | AF(&peeraddr) = AF_INET; |
2135 | NSRCADR(&peeraddr) = cp->peeraddr; | | 2039 | NSRCADR(&peeraddr) = cp.peeraddr; |
2136 | } | | 2040 | } |
2137 | | | 2041 | |
2138 | #ifdef ISC_PLATFORM_HAVESALEN | | 2042 | #ifdef ISC_PLATFORM_HAVESALEN |
2139 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); | | 2043 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); |
2140 | #endif | | 2044 | #endif |
2141 | peer = findexistingpeer(&peeraddr, NULL, -1, 0); | | 2045 | peer = findexistingpeer(&peeraddr, NULL, -1, 0); |
2142 | if (NULL == peer) | | 2046 | if (NULL == peer) |
2143 | bad++; | | 2047 | bad++; |
2144 | cp = (struct conf_unpeer *)((char *)cp + | | 2048 | datap += item_sz; |
2145 | INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
2146 | } | | 2049 | } |
2147 | | | 2050 | |
2148 | if (bad) { | | 2051 | if (bad) { |
2149 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | 2052 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
2150 | return; | | 2053 | return; |
2151 | } | | 2054 | } |
2152 | | | 2055 | |
2153 | /* | | 2056 | /* |
2154 | * Now do it in earnest. | | 2057 | * Now do it in earnest. |
2155 | */ | | 2058 | */ |
2156 | | | 2059 | |
2157 | items = INFO_NITEMS(inpkt->err_nitems); | | 2060 | datap = inpkt->data; |
2158 | cp = (struct conf_unpeer *)inpkt->data; | | | |
2159 | while (items-- > 0) { | | 2061 | while (items-- > 0) { |
| | | 2062 | memset(&cp,0,sizeof(cp)); |
| | | 2063 | memcpy(&cp, datap, item_sz); |
2160 | ZERO_SOCK(&peeraddr); | | 2064 | ZERO_SOCK(&peeraddr); |
2161 | if (client_v6_capable && cp->v6_flag) { | | 2065 | if (client_v6_capable && cp.v6_flag) { |
2162 | AF(&peeraddr) = AF_INET6; | | 2066 | AF(&peeraddr) = AF_INET6; |
2163 | SOCK_ADDR6(&peeraddr) = cp->peeraddr6; | | 2067 | SOCK_ADDR6(&peeraddr) = cp.peeraddr6; |
2164 | } else { | | 2068 | } else { |
2165 | AF(&peeraddr) = AF_INET; | | 2069 | AF(&peeraddr) = AF_INET; |
2166 | NSRCADR(&peeraddr) = cp->peeraddr; | | 2070 | NSRCADR(&peeraddr) = cp.peeraddr; |
2167 | } | | 2071 | } |
2168 | SET_PORT(&peeraddr, 123); | | 2072 | SET_PORT(&peeraddr, 123); |
2169 | #ifdef ISC_PLATFORM_HAVESALEN | | 2073 | #ifdef ISC_PLATFORM_HAVESALEN |
2170 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); | | 2074 | peeraddr.sa.sa_len = SOCKLEN(&peeraddr); |
2171 | #endif | | 2075 | #endif |
2172 | peer = findexistingpeer(&peeraddr, NULL, -1, 0); | | 2076 | peer = findexistingpeer(&peeraddr, NULL, -1, 0); |
2173 | while (peer != NULL) { | | 2077 | while (peer != NULL) { |
2174 | peer_reset(peer); | | 2078 | peer_reset(peer); |
2175 | peer = findexistingpeer(&peeraddr, peer, -1, 0); | | 2079 | peer = findexistingpeer(&peeraddr, peer, -1, 0); |
2176 | } | | 2080 | } |
2177 | cp = (struct conf_unpeer *)((char *)cp + | | 2081 | datap += item_sz; |
2178 | INFO_ITEMSIZE(inpkt->mbz_itemsize)); | | | |
2179 | } | | 2082 | } |
2180 | | | 2083 | |
2181 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 2084 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
2182 | } | | 2085 | } |
2183 | | | 2086 | |
2184 | | | 2087 | |
2185 | /* | | 2088 | /* |
2186 | * do_key_reread - reread the encryption key file | | 2089 | * do_key_reread - reread the encryption key file |
2187 | */ | | 2090 | */ |
2188 | static void | | 2091 | static void |
2189 | do_key_reread( | | 2092 | do_key_reread( |
2190 | sockaddr_u *srcadr, | | 2093 | sockaddr_u *srcadr, |
2191 | struct interface *inter, | | 2094 | struct interface *inter, |
2192 | struct req_pkt *inpkt | | 2095 | struct req_pkt *inpkt |
2193 | ) | | 2096 | ) |
2194 | { | | 2097 | { |
2195 | rereadkeys(); | | 2098 | rereadkeys(); |
2196 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 2099 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
2197 | } | | 2100 | } |
2198 | | | 2101 | |
2199 | | | 2102 | |
2200 | /* | | 2103 | /* |
2201 | * trust_key - make one or more keys trusted | | 2104 | * trust_key - make one or more keys trusted |
2202 | */ | | 2105 | */ |
2203 | static void | | 2106 | static void |
2204 | trust_key( | | 2107 | trust_key( |
2205 | sockaddr_u *srcadr, | | 2108 | sockaddr_u *srcadr, |
2206 | struct interface *inter, | | 2109 | struct interface *inter, |
2207 | struct req_pkt *inpkt | | 2110 | struct req_pkt *inpkt |
2208 | ) | | 2111 | ) |
2209 | { | | 2112 | { |
2210 | do_trustkey(srcadr, inter, inpkt, 1); | | 2113 | do_trustkey(srcadr, inter, inpkt, 1); |
2211 | } | | 2114 | } |
2212 | | | 2115 | |
2213 | | | 2116 | |
2214 | /* | | 2117 | /* |
2215 | * untrust_key - make one or more keys untrusted | | 2118 | * untrust_key - make one or more keys untrusted |
2216 | */ | | 2119 | */ |
2217 | static void | | 2120 | static void |
2218 | untrust_key( | | 2121 | untrust_key( |
2219 | sockaddr_u *srcadr, | | 2122 | sockaddr_u *srcadr, |
2220 | struct interface *inter, | | 2123 | struct interface *inter, |
2221 | struct req_pkt *inpkt | | 2124 | struct req_pkt *inpkt |
2222 | ) | | 2125 | ) |
2223 | { | | 2126 | { |
2224 | do_trustkey(srcadr, inter, inpkt, 0); | | 2127 | do_trustkey(srcadr, inter, inpkt, 0); |
2225 | } | | 2128 | } |
2226 | | | 2129 | |
2227 | | | 2130 | |
2228 | /* | | 2131 | /* |
2229 | * do_trustkey - make keys either trustable or untrustable | | 2132 | * do_trustkey - make keys either trustable or untrustable |
2230 | */ | | 2133 | */ |
2231 | static void | | 2134 | static void |
2232 | do_trustkey( | | 2135 | do_trustkey( |
2233 | sockaddr_u *srcadr, | | 2136 | sockaddr_u *srcadr, |
2234 | struct interface *inter, | | 2137 | struct interface *inter, |
2235 | struct req_pkt *inpkt, | | 2138 | struct req_pkt *inpkt, |
2236 | u_long trust | | 2139 | u_long trust |
2237 | ) | | 2140 | ) |
2238 | { | | 2141 | { |
2239 | register u_long *kp; | | 2142 | register u_long *kp; |
2240 | register int items; | | 2143 | register int items; |
2241 | | | 2144 | |
2242 | items = INFO_NITEMS(inpkt->err_nitems); | | 2145 | items = INFO_NITEMS(inpkt->err_nitems); |
2243 | kp = (u_long *)inpkt->data; | | 2146 | kp = (u_long *)inpkt->data; |
2244 | while (items-- > 0) { | | 2147 | while (items-- > 0) { |
2245 | authtrust(*kp, trust); | | 2148 | authtrust(*kp, trust); |
2246 | kp++; | | 2149 | kp++; |
2247 | } | | 2150 | } |
2248 | | | 2151 | |
2249 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 2152 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
2250 | } | | 2153 | } |
2251 | | | 2154 | |
2252 | | | 2155 | |
2253 | /* | | 2156 | /* |
2254 | * get_auth_info - return some stats concerning the authentication module | | 2157 | * get_auth_info - return some stats concerning the authentication module |
2255 | */ | | 2158 | */ |
2256 | static void | | 2159 | static void |
2257 | get_auth_info( | | 2160 | get_auth_info( |
2258 | sockaddr_u *srcadr, | | 2161 | sockaddr_u *srcadr, |
2259 | struct interface *inter, | | 2162 | struct interface *inter, |
2260 | struct req_pkt *inpkt | | 2163 | struct req_pkt *inpkt |
2261 | ) | | 2164 | ) |
2262 | { | | 2165 | { |
2263 | register struct info_auth *ia; | | 2166 | register struct info_auth *ia; |
2264 | | | 2167 | |
2265 | /* | | 2168 | /* |
2266 | * Importations from the authentication module | | 2169 | * Importations from the authentication module |
2267 | */ | | 2170 | */ |
2268 | extern u_long authnumkeys; | | 2171 | extern u_long authnumkeys; |
2269 | extern int authnumfreekeys; | | 2172 | extern int authnumfreekeys; |
2270 | extern u_long authkeylookups; | | 2173 | extern u_long authkeylookups; |
2271 | extern u_long authkeynotfound; | | 2174 | extern u_long authkeynotfound; |
2272 | extern u_long authencryptions; | | 2175 | extern u_long authencryptions; |
2273 | extern u_long authdecryptions; | | 2176 | extern u_long authdecryptions; |
2274 | extern u_long authkeyuncached; | | 2177 | extern u_long authkeyuncached; |
2275 | extern u_long authkeyexpired; | | 2178 | extern u_long authkeyexpired; |
2276 | | | 2179 | |
2277 | ia = (struct info_auth *)prepare_pkt(srcadr, inter, inpkt, | | 2180 | ia = (struct info_auth *)prepare_pkt(srcadr, inter, inpkt, |
2278 | sizeof(struct info_auth)); | | 2181 | sizeof(struct info_auth)); |
2279 | | | 2182 | |
2280 | ia->numkeys = htonl((u_int32)authnumkeys); | | 2183 | ia->numkeys = htonl((u_int32)authnumkeys); |
2281 | ia->numfreekeys = htonl((u_int32)authnumfreekeys); | | 2184 | ia->numfreekeys = htonl((u_int32)authnumfreekeys); |
2282 | ia->keylookups = htonl((u_int32)authkeylookups); | | 2185 | ia->keylookups = htonl((u_int32)authkeylookups); |
2283 | ia->keynotfound = htonl((u_int32)authkeynotfound); | | 2186 | ia->keynotfound = htonl((u_int32)authkeynotfound); |
2284 | ia->encryptions = htonl((u_int32)authencryptions); | | 2187 | ia->encryptions = htonl((u_int32)authencryptions); |
2285 | ia->decryptions = htonl((u_int32)authdecryptions); | | 2188 | ia->decryptions = htonl((u_int32)authdecryptions); |
2286 | ia->keyuncached = htonl((u_int32)authkeyuncached); | | 2189 | ia->keyuncached = htonl((u_int32)authkeyuncached); |
2287 | ia->expired = htonl((u_int32)authkeyexpired); | | 2190 | ia->expired = htonl((u_int32)authkeyexpired); |
2288 | ia->timereset = htonl((u_int32)(current_time - auth_timereset)); | | 2191 | ia->timereset = htonl((u_int32)(current_time - auth_timereset)); |
2289 | | | 2192 | |
2290 | (void) more_pkt(); | | 2193 | (void) more_pkt(); |
2291 | flush_pkt(); | | 2194 | flush_pkt(); |
2292 | } | | 2195 | } |
2293 | | | 2196 | |
2294 | | | 2197 | |
2295 | | | 2198 | |
2296 | /* | | 2199 | /* |
2297 | * reset_auth_stats - reset the authentication stat counters. Done here | | 2200 | * reset_auth_stats - reset the authentication stat counters. Done here |
2298 | * to keep ntp-isms out of the authentication module | | 2201 | * to keep ntp-isms out of the authentication module |
2299 | */ | | 2202 | */ |
2300 | static void | | 2203 | static void |
2301 | reset_auth_stats(void) | | 2204 | reset_auth_stats(void) |
2302 | { | | 2205 | { |
2303 | /* | | 2206 | /* |
2304 | * Importations from the authentication module | | 2207 | * Importations from the authentication module |
2305 | */ | | 2208 | */ |
2306 | extern u_long authkeylookups; | | 2209 | extern u_long authkeylookups; |
2307 | extern u_long authkeynotfound; | | 2210 | extern u_long authkeynotfound; |
2308 | extern u_long authencryptions; | | 2211 | extern u_long authencryptions; |
2309 | extern u_long authdecryptions; | | 2212 | extern u_long authdecryptions; |
2310 | extern u_long authkeyuncached; | | 2213 | extern u_long authkeyuncached; |
2311 | | | 2214 | |
2312 | authkeylookups = 0; | | 2215 | authkeylookups = 0; |
2313 | authkeynotfound = 0; | | 2216 | authkeynotfound = 0; |
2314 | authencryptions = 0; | | 2217 | authencryptions = 0; |
2315 | authdecryptions = 0; | | 2218 | authdecryptions = 0; |
2316 | authkeyuncached = 0; | | 2219 | authkeyuncached = 0; |
2317 | auth_timereset = current_time; | | 2220 | auth_timereset = current_time; |
2318 | } | | 2221 | } |
2319 | | | 2222 | |
2320 | | | 2223 | |
2321 | /* | | 2224 | /* |
2322 | * req_get_traps - return information about current trap holders | | 2225 | * req_get_traps - return information about current trap holders |
2323 | */ | | 2226 | */ |
2324 | static void | | 2227 | static void |
2325 | req_get_traps( | | 2228 | req_get_traps( |
2326 | sockaddr_u *srcadr, | | 2229 | sockaddr_u *srcadr, |
2327 | struct interface *inter, | | 2230 | struct interface *inter, |
2328 | struct req_pkt *inpkt | | 2231 | struct req_pkt *inpkt |
2329 | ) | | 2232 | ) |
2330 | { | | 2233 | { |
2331 | register struct info_trap *it; | | 2234 | register struct info_trap *it; |
2332 | register struct ctl_trap *tr; | | 2235 | register struct ctl_trap *tr; |
2333 | register int i; | | 2236 | register int i; |
2334 | | | 2237 | |
2335 | /* | | 2238 | /* |
2336 | * Imported from the control module | | 2239 | * Imported from the control module |
2337 | */ | | 2240 | */ |
2338 | extern struct ctl_trap ctl_trap[]; | | 2241 | extern struct ctl_trap ctl_trap[]; |
2339 | extern int num_ctl_traps; | | 2242 | extern int num_ctl_traps; |
2340 | | | 2243 | |
2341 | if (num_ctl_traps == 0) { | | 2244 | if (num_ctl_traps == 0) { |
2342 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | 2245 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
2343 | return; | | 2246 | return; |
2344 | } | | 2247 | } |
2345 | | | 2248 | |
2346 | it = (struct info_trap *)prepare_pkt(srcadr, inter, inpkt, | | 2249 | it = (struct info_trap *)prepare_pkt(srcadr, inter, inpkt, |
2347 | v6sizeof(struct info_trap)); | | 2250 | v6sizeof(struct info_trap)); |
2348 | | | 2251 | |
2349 | for (i = 0, tr = ctl_trap; i < CTL_MAXTRAPS; i++, tr++) { | | 2252 | for (i = 0, tr = ctl_trap; i < CTL_MAXTRAPS; i++, tr++) { |
2350 | if (tr->tr_flags & TRAP_INUSE) { | | 2253 | if (tr->tr_flags & TRAP_INUSE) { |
2351 | if (IS_IPV4(&tr->tr_addr)) { | | 2254 | if (IS_IPV4(&tr->tr_addr)) { |
2352 | if (tr->tr_localaddr == any_interface) | | 2255 | if (tr->tr_localaddr == any_interface) |
2353 | it->local_address = 0; | | 2256 | it->local_address = 0; |
2354 | else | | 2257 | else |
2355 | it->local_address | | 2258 | it->local_address |
2356 | = NSRCADR(&tr->tr_localaddr->sin); | | 2259 | = NSRCADR(&tr->tr_localaddr->sin); |
2357 | it->trap_address = NSRCADR(&tr->tr_addr); | | 2260 | it->trap_address = NSRCADR(&tr->tr_addr); |
2358 | if (client_v6_capable) | | 2261 | if (client_v6_capable) |
2359 | it->v6_flag = 0; | | 2262 | it->v6_flag = 0; |
2360 | } else { | | 2263 | } else { |
2361 | if (!client_v6_capable) | | 2264 | if (!client_v6_capable) |
2362 | continue; | | 2265 | continue; |
2363 | it->local_address6 | | 2266 | it->local_address6 |
2364 | = SOCK_ADDR6(&tr->tr_localaddr->sin); | | 2267 | = SOCK_ADDR6(&tr->tr_localaddr->sin); |
2365 | it->trap_address6 = SOCK_ADDR6(&tr->tr_addr); | | 2268 | it->trap_address6 = SOCK_ADDR6(&tr->tr_addr); |
2366 | it->v6_flag = 1; | | 2269 | it->v6_flag = 1; |
2367 | } | | 2270 | } |
2368 | it->trap_port = NSRCPORT(&tr->tr_addr); | | 2271 | it->trap_port = NSRCPORT(&tr->tr_addr); |
2369 | it->sequence = htons(tr->tr_sequence); | | 2272 | it->sequence = htons(tr->tr_sequence); |
2370 | it->settime = htonl((u_int32)(current_time - tr->tr_settime)); | | 2273 | it->settime = htonl((u_int32)(current_time - tr->tr_settime)); |
2371 | it->origtime = htonl((u_int32)(current_time - tr->tr_origtime)); | | 2274 | it->origtime = htonl((u_int32)(current_time - tr->tr_origtime)); |
2372 | it->resets = htonl((u_int32)tr->tr_resets); | | 2275 | it->resets = htonl((u_int32)tr->tr_resets); |
2373 | it->flags = htonl((u_int32)tr->tr_flags); | | 2276 | it->flags = htonl((u_int32)tr->tr_flags); |
2374 | it = (struct info_trap *)more_pkt(); | | 2277 | it = (struct info_trap *)more_pkt(); |
2375 | } | | 2278 | } |
2376 | } | | 2279 | } |
2377 | flush_pkt(); | | 2280 | flush_pkt(); |
2378 | } | | 2281 | } |
2379 | | | 2282 | |
2380 | | | 2283 | |
2381 | /* | | 2284 | /* |
2382 | * req_set_trap - configure a trap | | 2285 | * req_set_trap - configure a trap |
2383 | */ | | 2286 | */ |
2384 | static void | | 2287 | static void |
2385 | req_set_trap( | | 2288 | req_set_trap( |
2386 | sockaddr_u *srcadr, | | 2289 | sockaddr_u *srcadr, |
2387 | struct interface *inter, | | 2290 | struct interface *inter, |
2388 | struct req_pkt *inpkt | | 2291 | struct req_pkt *inpkt |
2389 | ) | | 2292 | ) |
2390 | { | | 2293 | { |
2391 | do_setclr_trap(srcadr, inter, inpkt, 1); | | 2294 | do_setclr_trap(srcadr, inter, inpkt, 1); |
2392 | } | | 2295 | } |
2393 | | | 2296 | |
2394 | | | 2297 | |
2395 | | | 2298 | |
2396 | /* | | 2299 | /* |
2397 | * req_clr_trap - unconfigure a trap | | 2300 | * req_clr_trap - unconfigure a trap |
2398 | */ | | 2301 | */ |
2399 | static void | | 2302 | static void |
2400 | req_clr_trap( | | 2303 | req_clr_trap( |
2401 | sockaddr_u *srcadr, | | 2304 | sockaddr_u *srcadr, |
2402 | struct interface *inter, | | 2305 | struct interface *inter, |
2403 | struct req_pkt *inpkt | | 2306 | struct req_pkt *inpkt |
2404 | ) | | 2307 | ) |
2405 | { | | 2308 | { |
2406 | do_setclr_trap(srcadr, inter, inpkt, 0); | | 2309 | do_setclr_trap(srcadr, inter, inpkt, 0); |
2407 | } | | 2310 | } |
2408 | | | 2311 | |
2409 | | | 2312 | |
2410 | | | 2313 | |
2411 | /* | | 2314 | /* |
2412 | * do_setclr_trap - do the grunge work of (un)configuring a trap | | 2315 | * do_setclr_trap - do the grunge work of (un)configuring a trap |
2413 | */ | | 2316 | */ |
2414 | static void | | 2317 | static void |
2415 | do_setclr_trap( | | 2318 | do_setclr_trap( |
2416 | sockaddr_u *srcadr, | | 2319 | sockaddr_u *srcadr, |
2417 | struct interface *inter, | | 2320 | struct interface *inter, |
2418 | struct req_pkt *inpkt, | | 2321 | struct req_pkt *inpkt, |
2419 | int set | | 2322 | int set |
2420 | ) | | 2323 | ) |
2421 | { | | 2324 | { |
2422 | register struct conf_trap *ct; | | 2325 | register struct conf_trap *ct; |
2423 | register struct interface *linter; | | 2326 | register struct interface *linter; |
2424 | int res; | | 2327 | int res; |
2425 | sockaddr_u laddr; | | 2328 | sockaddr_u laddr; |
2426 | | | 2329 | |
2427 | /* | | 2330 | /* |
2428 | * Prepare sockaddr | | 2331 | * Prepare sockaddr |
2429 | */ | | 2332 | */ |
2430 | ZERO_SOCK(&laddr); | | 2333 | ZERO_SOCK(&laddr); |
2431 | AF(&laddr) = AF(srcadr); | | 2334 | AF(&laddr) = AF(srcadr); |
2432 | SET_PORT(&laddr, NTP_PORT); | | 2335 | SET_PORT(&laddr, NTP_PORT); |
2433 | | | 2336 | |
2434 | /* | | 2337 | /* |
2435 | * Restrict ourselves to one item only. This eliminates | | 2338 | * Restrict ourselves to one item only. This eliminates |
2436 | * the error reporting problem. | | 2339 | * the error reporting problem. |
2437 | */ | | 2340 | */ |
2438 | if (INFO_NITEMS(inpkt->err_nitems) > 1) { | | 2341 | if (INFO_NITEMS(inpkt->err_nitems) > 1) { |
2439 | msyslog(LOG_ERR, "do_setclr_trap: err_nitems > 1"); | | 2342 | msyslog(LOG_ERR, "do_setclr_trap: err_nitems > 1"); |
2440 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 2343 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
2441 | return; | | 2344 | return; |
2442 | } | | 2345 | } |
2443 | ct = (struct conf_trap *)inpkt->data; | | 2346 | ct = (struct conf_trap *)inpkt->data; |
2444 | | | 2347 | |
2445 | /* | | 2348 | /* |
2446 | * Look for the local interface. If none, use the default. | | 2349 | * Look for the local interface. If none, use the default. |
2447 | */ | | 2350 | */ |
2448 | if (ct->local_address == 0) { | | 2351 | if (ct->local_address == 0) { |
2449 | linter = any_interface; | | 2352 | linter = any_interface; |
2450 | } else { | | 2353 | } else { |
2451 | if (IS_IPV4(&laddr)) | | 2354 | if (IS_IPV4(&laddr)) |
2452 | NSRCADR(&laddr) = ct->local_address; | | 2355 | NSRCADR(&laddr) = ct->local_address; |
2453 | else | | 2356 | else |
2454 | SOCK_ADDR6(&laddr) = ct->local_address6; | | 2357 | SOCK_ADDR6(&laddr) = ct->local_address6; |
2455 | linter = findinterface(&laddr); | | 2358 | linter = findinterface(&laddr); |
2456 | if (NULL == linter) { | | 2359 | if (NULL == linter) { |
2457 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | 2360 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
2458 | return; | | 2361 | return; |
2459 | } | | 2362 | } |
2460 | } | | 2363 | } |
2461 | | | 2364 | |
2462 | if (IS_IPV4(&laddr)) | | 2365 | if (IS_IPV4(&laddr)) |
2463 | NSRCADR(&laddr) = ct->trap_address; | | 2366 | NSRCADR(&laddr) = ct->trap_address; |
2464 | else | | 2367 | else |
2465 | SOCK_ADDR6(&laddr) = ct->trap_address6; | | 2368 | SOCK_ADDR6(&laddr) = ct->trap_address6; |
2466 | if (ct->trap_port) | | 2369 | if (ct->trap_port) |
2467 | NSRCPORT(&laddr) = ct->trap_port; | | 2370 | NSRCPORT(&laddr) = ct->trap_port; |
2468 | else | | 2371 | else |
2469 | SET_PORT(&laddr, TRAPPORT); | | 2372 | SET_PORT(&laddr, TRAPPORT); |
2470 | | | 2373 | |
2471 | if (set) { | | 2374 | if (set) { |
2472 | res = ctlsettrap(&laddr, linter, 0, | | 2375 | res = ctlsettrap(&laddr, linter, 0, |
2473 | INFO_VERSION(inpkt->rm_vn_mode)); | | 2376 | INFO_VERSION(inpkt->rm_vn_mode)); |
2474 | } else { | | 2377 | } else { |
2475 | res = ctlclrtrap(&laddr, linter, 0); | | 2378 | res = ctlclrtrap(&laddr, linter, 0); |
2476 | } | | 2379 | } |
2477 | | | 2380 | |
2478 | if (!res) { | | 2381 | if (!res) { |
2479 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | 2382 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
2480 | } else { | | 2383 | } else { |
2481 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 2384 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
2482 | } | | 2385 | } |
2483 | return; | | 2386 | return; |
2484 | } | | 2387 | } |
2485 | | | 2388 | |
2486 | | | 2389 | |
2487 | | | 2390 | |
2488 | /* | | 2391 | /* |
2489 | * set_request_keyid - set the keyid used to authenticate requests | | 2392 | * set_request_keyid - set the keyid used to authenticate requests |
2490 | */ | | 2393 | */ |
2491 | static void | | 2394 | static void |
2492 | set_request_keyid( | | 2395 | set_request_keyid( |
2493 | sockaddr_u *srcadr, | | 2396 | sockaddr_u *srcadr, |
2494 | struct interface *inter, | | 2397 | struct interface *inter, |
2495 | struct req_pkt *inpkt | | 2398 | struct req_pkt *inpkt |
2496 | ) | | 2399 | ) |
2497 | { | | 2400 | { |
2498 | keyid_t *pkeyid; | | 2401 | keyid_t *pkeyid; |
2499 | | | 2402 | |
2500 | /* | | 2403 | /* |
2501 | * Restrict ourselves to one item only. | | 2404 | * Restrict ourselves to one item only. |
2502 | */ | | 2405 | */ |
2503 | if (INFO_NITEMS(inpkt->err_nitems) > 1) { | | 2406 | if (INFO_NITEMS(inpkt->err_nitems) > 1) { |
2504 | msyslog(LOG_ERR, "set_request_keyid: err_nitems > 1"); | | 2407 | msyslog(LOG_ERR, "set_request_keyid: err_nitems > 1"); |
2505 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 2408 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
2506 | return; | | 2409 | return; |
2507 | } | | 2410 | } |
2508 | | | 2411 | |
2509 | pkeyid = (keyid_t *)inpkt->data; | | 2412 | pkeyid = (keyid_t *)inpkt->data; |
2510 | info_auth_keyid = ntohl(*pkeyid); | | 2413 | info_auth_keyid = ntohl(*pkeyid); |
2511 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 2414 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
2512 | } | | 2415 | } |
2513 | | | 2416 | |
2514 | | | 2417 | |
2515 | | | 2418 | |
2516 | /* | | 2419 | /* |
2517 | * set_control_keyid - set the keyid used to authenticate requests | | 2420 | * set_control_keyid - set the keyid used to authenticate requests |
2518 | */ | | 2421 | */ |
2519 | static void | | 2422 | static void |
2520 | set_control_keyid( | | 2423 | set_control_keyid( |
2521 | sockaddr_u *srcadr, | | 2424 | sockaddr_u *srcadr, |
2522 | struct interface *inter, | | 2425 | struct interface *inter, |
2523 | struct req_pkt *inpkt | | 2426 | struct req_pkt *inpkt |
2524 | ) | | 2427 | ) |
2525 | { | | 2428 | { |
2526 | keyid_t *pkeyid; | | 2429 | keyid_t *pkeyid; |
2527 | extern keyid_t ctl_auth_keyid; | | 2430 | extern keyid_t ctl_auth_keyid; |
2528 | | | 2431 | |
2529 | /* | | 2432 | /* |
2530 | * Restrict ourselves to one item only. | | 2433 | * Restrict ourselves to one item only. |
2531 | */ | | 2434 | */ |
2532 | if (INFO_NITEMS(inpkt->err_nitems) > 1) { | | 2435 | if (INFO_NITEMS(inpkt->err_nitems) > 1) { |
2533 | msyslog(LOG_ERR, "set_control_keyid: err_nitems > 1"); | | 2436 | msyslog(LOG_ERR, "set_control_keyid: err_nitems > 1"); |
2534 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 2437 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
2535 | return; | | 2438 | return; |
2536 | } | | 2439 | } |
2537 | | | 2440 | |
2538 | pkeyid = (keyid_t *)inpkt->data; | | 2441 | pkeyid = (keyid_t *)inpkt->data; |
2539 | ctl_auth_keyid = ntohl(*pkeyid); | | 2442 | ctl_auth_keyid = ntohl(*pkeyid); |
2540 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 2443 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
2541 | } | | 2444 | } |
2542 | | | 2445 | |
2543 | | | 2446 | |
2544 | | | 2447 | |
2545 | /* | | 2448 | /* |
2546 | * get_ctl_stats - return some stats concerning the control message module | | 2449 | * get_ctl_stats - return some stats concerning the control message module |
2547 | */ | | 2450 | */ |
2548 | static void | | 2451 | static void |
2549 | get_ctl_stats( | | 2452 | get_ctl_stats( |
2550 | sockaddr_u *srcadr, | | 2453 | sockaddr_u *srcadr, |
2551 | struct interface *inter, | | 2454 | struct interface *inter, |
2552 | struct req_pkt *inpkt | | 2455 | struct req_pkt *inpkt |
2553 | ) | | 2456 | ) |
2554 | { | | 2457 | { |
2555 | register struct info_control *ic; | | 2458 | register struct info_control *ic; |
2556 | | | 2459 | |
2557 | /* | | 2460 | /* |
2558 | * Importations from the control module | | 2461 | * Importations from the control module |
2559 | */ | | 2462 | */ |
2560 | extern u_long ctltimereset; | | 2463 | extern u_long ctltimereset; |
2561 | extern u_long numctlreq; | | 2464 | extern u_long numctlreq; |
2562 | extern u_long numctlbadpkts; | | 2465 | extern u_long numctlbadpkts; |
2563 | extern u_long numctlresponses; | | 2466 | extern u_long numctlresponses; |
2564 | extern u_long numctlfrags; | | 2467 | extern u_long numctlfrags; |
2565 | extern u_long numctlerrors; | | 2468 | extern u_long numctlerrors; |
2566 | extern u_long numctltooshort; | | 2469 | extern u_long numctltooshort; |
2567 | extern u_long numctlinputresp; | | 2470 | extern u_long numctlinputresp; |
2568 | extern u_long numctlinputfrag; | | 2471 | extern u_long numctlinputfrag; |
2569 | extern u_long numctlinputerr; | | 2472 | extern u_long numctlinputerr; |
2570 | extern u_long numctlbadoffset; | | 2473 | extern u_long numctlbadoffset; |
2571 | extern u_long numctlbadversion; | | 2474 | extern u_long numctlbadversion; |
2572 | extern u_long numctldatatooshort; | | 2475 | extern u_long numctldatatooshort; |
2573 | extern u_long numctlbadop; | | 2476 | extern u_long numctlbadop; |
2574 | extern u_long numasyncmsgs; | | 2477 | extern u_long numasyncmsgs; |
2575 | | | 2478 | |
2576 | ic = (struct info_control *)prepare_pkt(srcadr, inter, inpkt, | | 2479 | ic = (struct info_control *)prepare_pkt(srcadr, inter, inpkt, |
2577 | sizeof(struct info_control)); | | 2480 | sizeof(struct info_control)); |
2578 | | | 2481 | |
2579 | ic->ctltimereset = htonl((u_int32)(current_time - ctltimereset)); | | 2482 | ic->ctltimereset = htonl((u_int32)(current_time - ctltimereset)); |
2580 | ic->numctlreq = htonl((u_int32)numctlreq); | | 2483 | ic->numctlreq = htonl((u_int32)numctlreq); |
2581 | ic->numctlbadpkts = htonl((u_int32)numctlbadpkts); | | 2484 | ic->numctlbadpkts = htonl((u_int32)numctlbadpkts); |
2582 | ic->numctlresponses = htonl((u_int32)numctlresponses); | | 2485 | ic->numctlresponses = htonl((u_int32)numctlresponses); |
2583 | ic->numctlfrags = htonl((u_int32)numctlfrags); | | 2486 | ic->numctlfrags = htonl((u_int32)numctlfrags); |
2584 | ic->numctlerrors = htonl((u_int32)numctlerrors); | | 2487 | ic->numctlerrors = htonl((u_int32)numctlerrors); |
2585 | ic->numctltooshort = htonl((u_int32)numctltooshort); | | 2488 | ic->numctltooshort = htonl((u_int32)numctltooshort); |
2586 | ic->numctlinputresp = htonl((u_int32)numctlinputresp); | | 2489 | ic->numctlinputresp = htonl((u_int32)numctlinputresp); |
2587 | ic->numctlinputfrag = htonl((u_int32)numctlinputfrag); | | 2490 | ic->numctlinputfrag = htonl((u_int32)numctlinputfrag); |
2588 | ic->numctlinputerr = htonl((u_int32)numctlinputerr); | | 2491 | ic->numctlinputerr = htonl((u_int32)numctlinputerr); |
2589 | ic->numctlbadoffset = htonl((u_int32)numctlbadoffset); | | 2492 | ic->numctlbadoffset = htonl((u_int32)numctlbadoffset); |
2590 | ic->numctlbadversion = htonl((u_int32)numctlbadversion); | | 2493 | ic->numctlbadversion = htonl((u_int32)numctlbadversion); |
2591 | ic->numctldatatooshort = htonl((u_int32)numctldatatooshort); | | 2494 | ic->numctldatatooshort = htonl((u_int32)numctldatatooshort); |
2592 | ic->numctlbadop = htonl((u_int32)numctlbadop); | | 2495 | ic->numctlbadop = htonl((u_int32)numctlbadop); |
2593 | ic->numasyncmsgs = htonl((u_int32)numasyncmsgs); | | 2496 | ic->numasyncmsgs = htonl((u_int32)numasyncmsgs); |
2594 | | | 2497 | |
2595 | (void) more_pkt(); | | 2498 | (void) more_pkt(); |
2596 | flush_pkt(); | | 2499 | flush_pkt(); |
2597 | } | | 2500 | } |
2598 | | | 2501 | |
2599 | | | 2502 | |
2600 | #ifdef KERNEL_PLL | | 2503 | #ifdef KERNEL_PLL |
2601 | /* | | 2504 | /* |
2602 | * get_kernel_info - get kernel pll/pps information | | 2505 | * get_kernel_info - get kernel pll/pps information |
2603 | */ | | 2506 | */ |
2604 | static void | | 2507 | static void |
2605 | get_kernel_info( | | 2508 | get_kernel_info( |
2606 | sockaddr_u *srcadr, | | 2509 | sockaddr_u *srcadr, |
2607 | struct interface *inter, | | 2510 | struct interface *inter, |
2608 | struct req_pkt *inpkt | | 2511 | struct req_pkt *inpkt |
2609 | ) | | 2512 | ) |
2610 | { | | 2513 | { |
2611 | register struct info_kernel *ik; | | 2514 | register struct info_kernel *ik; |
2612 | struct timex ntx; | | 2515 | struct timex ntx; |
2613 | | | 2516 | |
2614 | if (!pll_control) { | | 2517 | if (!pll_control) { |
2615 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | 2518 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
2616 | return; | | 2519 | return; |
2617 | } | | 2520 | } |
2618 | | | 2521 | |
2619 | memset((char *)&ntx, 0, sizeof(ntx)); | | 2522 | memset((char *)&ntx, 0, sizeof(ntx)); |
2620 | if (ntp_adjtime(&ntx) < 0) | | 2523 | if (ntp_adjtime(&ntx) < 0) |
2621 | msyslog(LOG_ERR, "get_kernel_info: ntp_adjtime() failed: %m"); | | 2524 | msyslog(LOG_ERR, "get_kernel_info: ntp_adjtime() failed: %m"); |
2622 | ik = (struct info_kernel *)prepare_pkt(srcadr, inter, inpkt, | | 2525 | ik = (struct info_kernel *)prepare_pkt(srcadr, inter, inpkt, |
2623 | sizeof(struct info_kernel)); | | 2526 | sizeof(struct info_kernel)); |
2624 | | | 2527 | |
2625 | /* | | 2528 | /* |
2626 | * pll variables | | 2529 | * pll variables |
2627 | */ | | 2530 | */ |
2628 | ik->offset = htonl((u_int32)ntx.offset); | | 2531 | ik->offset = htonl((u_int32)ntx.offset); |
2629 | ik->freq = htonl((u_int32)ntx.freq); | | 2532 | ik->freq = htonl((u_int32)ntx.freq); |
2630 | ik->maxerror = htonl((u_int32)ntx.maxerror); | | 2533 | ik->maxerror = htonl((u_int32)ntx.maxerror); |
2631 | ik->esterror = htonl((u_int32)ntx.esterror); | | 2534 | ik->esterror = htonl((u_int32)ntx.esterror); |
2632 | ik->status = htons(ntx.status); | | 2535 | ik->status = htons(ntx.status); |
2633 | ik->constant = htonl((u_int32)ntx.constant); | | 2536 | ik->constant = htonl((u_int32)ntx.constant); |
2634 | ik->precision = htonl((u_int32)ntx.precision); | | 2537 | ik->precision = htonl((u_int32)ntx.precision); |
2635 | ik->tolerance = htonl((u_int32)ntx.tolerance); | | 2538 | ik->tolerance = htonl((u_int32)ntx.tolerance); |
2636 | | | 2539 | |
2637 | /* | | 2540 | /* |
2638 | * pps variables | | 2541 | * pps variables |
2639 | */ | | 2542 | */ |
2640 | ik->ppsfreq = htonl((u_int32)ntx.ppsfreq); | | 2543 | ik->ppsfreq = htonl((u_int32)ntx.ppsfreq); |
2641 | ik->jitter = htonl((u_int32)ntx.jitter); | | 2544 | ik->jitter = htonl((u_int32)ntx.jitter); |
2642 | ik->shift = htons(ntx.shift); | | 2545 | ik->shift = htons(ntx.shift); |
2643 | ik->stabil = htonl((u_int32)ntx.stabil); | | 2546 | ik->stabil = htonl((u_int32)ntx.stabil); |
2644 | ik->jitcnt = htonl((u_int32)ntx.jitcnt); | | 2547 | ik->jitcnt = htonl((u_int32)ntx.jitcnt); |
2645 | ik->calcnt = htonl((u_int32)ntx.calcnt); | | 2548 | ik->calcnt = htonl((u_int32)ntx.calcnt); |
2646 | ik->errcnt = htonl((u_int32)ntx.errcnt); | | 2549 | ik->errcnt = htonl((u_int32)ntx.errcnt); |
2647 | ik->stbcnt = htonl((u_int32)ntx.stbcnt); | | 2550 | ik->stbcnt = htonl((u_int32)ntx.stbcnt); |
2648 | | | 2551 | |
2649 | (void) more_pkt(); | | 2552 | (void) more_pkt(); |
2650 | flush_pkt(); | | 2553 | flush_pkt(); |
2651 | } | | 2554 | } |
2652 | #endif /* KERNEL_PLL */ | | 2555 | #endif /* KERNEL_PLL */ |
2653 | | | 2556 | |
2654 | | | 2557 | |
2655 | #ifdef REFCLOCK | | 2558 | #ifdef REFCLOCK |
2656 | /* | | 2559 | /* |
2657 | * get_clock_info - get info about a clock | | 2560 | * get_clock_info - get info about a clock |
2658 | */ | | 2561 | */ |
2659 | static void | | 2562 | static void |
2660 | get_clock_info( | | 2563 | get_clock_info( |
2661 | sockaddr_u *srcadr, | | 2564 | sockaddr_u *srcadr, |
2662 | struct interface *inter, | | 2565 | struct interface *inter, |
2663 | struct req_pkt *inpkt | | 2566 | struct req_pkt *inpkt |
2664 | ) | | 2567 | ) |
2665 | { | | 2568 | { |
2666 | register struct info_clock *ic; | | 2569 | register struct info_clock *ic; |
2667 | register u_int32 *clkaddr; | | 2570 | register u_int32 *clkaddr; |
2668 | register int items; | | 2571 | register int items; |
2669 | struct refclockstat clock_stat; | | 2572 | struct refclockstat clock_stat; |
2670 | sockaddr_u addr; | | 2573 | sockaddr_u addr; |
2671 | l_fp ltmp; | | 2574 | l_fp ltmp; |
2672 | | | 2575 | |
2673 | ZERO_SOCK(&addr); | | 2576 | ZERO_SOCK(&addr); |
2674 | AF(&addr) = AF_INET; | | 2577 | AF(&addr) = AF_INET; |
2675 | #ifdef ISC_PLATFORM_HAVESALEN | | 2578 | #ifdef ISC_PLATFORM_HAVESALEN |
2676 | addr.sa.sa_len = SOCKLEN(&addr); | | 2579 | addr.sa.sa_len = SOCKLEN(&addr); |
2677 | #endif | | 2580 | #endif |
2678 | SET_PORT(&addr, NTP_PORT); | | 2581 | SET_PORT(&addr, NTP_PORT); |
2679 | items = INFO_NITEMS(inpkt->err_nitems); | | 2582 | items = INFO_NITEMS(inpkt->err_nitems); |
2680 | clkaddr = (u_int32 *) inpkt->data; | | 2583 | clkaddr = (u_int32 *) inpkt->data; |
2681 | | | 2584 | |
2682 | ic = (struct info_clock *)prepare_pkt(srcadr, inter, inpkt, | | 2585 | ic = (struct info_clock *)prepare_pkt(srcadr, inter, inpkt, |
2683 | sizeof(struct info_clock)); | | 2586 | sizeof(struct info_clock)); |
2684 | | | 2587 | |
2685 | while (items-- > 0) { | | 2588 | while (items-- > 0) { |
2686 | NSRCADR(&addr) = *clkaddr++; | | 2589 | NSRCADR(&addr) = *clkaddr++; |
2687 | if (!ISREFCLOCKADR(&addr) || | | 2590 | if (!ISREFCLOCKADR(&addr) || |
2688 | findexistingpeer(&addr, NULL, -1, 0) == NULL) { | | 2591 | findexistingpeer(&addr, NULL, -1, 0) == NULL) { |
2689 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | 2592 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
2690 | return; | | 2593 | return; |
2691 | } | | 2594 | } |
2692 | | | 2595 | |
2693 | clock_stat.kv_list = (struct ctl_var *)0; | | 2596 | clock_stat.kv_list = (struct ctl_var *)0; |
2694 | | | 2597 | |
2695 | refclock_control(&addr, NULL, &clock_stat); | | 2598 | refclock_control(&addr, NULL, &clock_stat); |
2696 | | | 2599 | |
2697 | ic->clockadr = NSRCADR(&addr); | | 2600 | ic->clockadr = NSRCADR(&addr); |
2698 | ic->type = clock_stat.type; | | 2601 | ic->type = clock_stat.type; |
2699 | ic->flags = clock_stat.flags; | | 2602 | ic->flags = clock_stat.flags; |
2700 | ic->lastevent = clock_stat.lastevent; | | 2603 | ic->lastevent = clock_stat.lastevent; |
2701 | ic->currentstatus = clock_stat.currentstatus; | | 2604 | ic->currentstatus = clock_stat.currentstatus; |
2702 | ic->polls = htonl((u_int32)clock_stat.polls); | | 2605 | ic->polls = htonl((u_int32)clock_stat.polls); |
2703 | ic->noresponse = htonl((u_int32)clock_stat.noresponse); | | 2606 | ic->noresponse = htonl((u_int32)clock_stat.noresponse); |
2704 | ic->badformat = htonl((u_int32)clock_stat.badformat); | | 2607 | ic->badformat = htonl((u_int32)clock_stat.badformat); |
2705 | ic->baddata = htonl((u_int32)clock_stat.baddata); | | 2608 | ic->baddata = htonl((u_int32)clock_stat.baddata); |
2706 | ic->timestarted = htonl((u_int32)clock_stat.timereset); | | 2609 | ic->timestarted = htonl((u_int32)clock_stat.timereset); |
2707 | DTOLFP(clock_stat.fudgetime1, <mp); | | 2610 | DTOLFP(clock_stat.fudgetime1, <mp); |
2708 | HTONL_FP(<mp, &ic->fudgetime1); | | 2611 | HTONL_FP(<mp, &ic->fudgetime1); |
2709 | DTOLFP(clock_stat.fudgetime2, <mp); | | 2612 | DTOLFP(clock_stat.fudgetime2, <mp); |
2710 | HTONL_FP(<mp, &ic->fudgetime2); | | 2613 | HTONL_FP(<mp, &ic->fudgetime2); |
2711 | ic->fudgeval1 = htonl((u_int32)clock_stat.fudgeval1); | | 2614 | ic->fudgeval1 = htonl((u_int32)clock_stat.fudgeval1); |
2712 | ic->fudgeval2 = htonl(clock_stat.fudgeval2); | | 2615 | ic->fudgeval2 = htonl(clock_stat.fudgeval2); |
2713 | | | 2616 | |
2714 | free_varlist(clock_stat.kv_list); | | 2617 | free_varlist(clock_stat.kv_list); |
2715 | | | 2618 | |
2716 | ic = (struct info_clock *)more_pkt(); | | 2619 | ic = (struct info_clock *)more_pkt(); |
2717 | } | | 2620 | } |
2718 | flush_pkt(); | | 2621 | flush_pkt(); |
2719 | } | | 2622 | } |
2720 | | | 2623 | |
2721 | | | 2624 | |
2722 | | | 2625 | |
2723 | /* | | 2626 | /* |
2724 | * set_clock_fudge - get a clock's fudge factors | | 2627 | * set_clock_fudge - get a clock's fudge factors |
2725 | */ | | 2628 | */ |
2726 | static void | | 2629 | static void |
2727 | set_clock_fudge( | | 2630 | set_clock_fudge( |
2728 | sockaddr_u *srcadr, | | 2631 | sockaddr_u *srcadr, |
2729 | struct interface *inter, | | 2632 | struct interface *inter, |
2730 | struct req_pkt *inpkt | | 2633 | struct req_pkt *inpkt |
2731 | ) | | 2634 | ) |
2732 | { | | 2635 | { |
2733 | register struct conf_fudge *cf; | | 2636 | register struct conf_fudge *cf; |
2734 | register int items; | | 2637 | register int items; |
2735 | struct refclockstat clock_stat; | | 2638 | struct refclockstat clock_stat; |
2736 | sockaddr_u addr; | | 2639 | sockaddr_u addr; |
2737 | l_fp ltmp; | | 2640 | l_fp ltmp; |
2738 | | | 2641 | |
2739 | ZERO_SOCK(&addr); | | 2642 | ZERO_SOCK(&addr); |
2740 | memset((char *)&clock_stat, 0, sizeof clock_stat); | | 2643 | memset((char *)&clock_stat, 0, sizeof clock_stat); |
2741 | items = INFO_NITEMS(inpkt->err_nitems); | | 2644 | items = INFO_NITEMS(inpkt->err_nitems); |
2742 | cf = (struct conf_fudge *) inpkt->data; | | 2645 | cf = (struct conf_fudge *) inpkt->data; |
2743 | | | 2646 | |
2744 | while (items-- > 0) { | | 2647 | while (items-- > 0) { |
2745 | AF(&addr) = AF_INET; | | 2648 | AF(&addr) = AF_INET; |
2746 | NSRCADR(&addr) = cf->clockadr; | | 2649 | NSRCADR(&addr) = cf->clockadr; |
2747 | #ifdef ISC_PLATFORM_HAVESALEN | | 2650 | #ifdef ISC_PLATFORM_HAVESALEN |
2748 | addr.sa.sa_len = SOCKLEN(&addr); | | 2651 | addr.sa.sa_len = SOCKLEN(&addr); |
2749 | #endif | | 2652 | #endif |
2750 | SET_PORT(&addr, NTP_PORT); | | 2653 | SET_PORT(&addr, NTP_PORT); |
2751 | if (!ISREFCLOCKADR(&addr) || | | 2654 | if (!ISREFCLOCKADR(&addr) || |
2752 | findexistingpeer(&addr, NULL, -1, 0) == 0) { | | 2655 | findexistingpeer(&addr, NULL, -1, 0) == 0) { |
2753 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | 2656 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
2754 | return; | | 2657 | return; |
2755 | } | | 2658 | } |
2756 | | | 2659 | |
2757 | switch(ntohl(cf->which)) { | | 2660 | switch(ntohl(cf->which)) { |
2758 | case FUDGE_TIME1: | | 2661 | case FUDGE_TIME1: |
2759 | NTOHL_FP(&cf->fudgetime, <mp); | | 2662 | NTOHL_FP(&cf->fudgetime, <mp); |
2760 | LFPTOD(<mp, clock_stat.fudgetime1); | | 2663 | LFPTOD(<mp, clock_stat.fudgetime1); |
2761 | clock_stat.haveflags = CLK_HAVETIME1; | | 2664 | clock_stat.haveflags = CLK_HAVETIME1; |
2762 | break; | | 2665 | break; |
2763 | case FUDGE_TIME2: | | 2666 | case FUDGE_TIME2: |
2764 | NTOHL_FP(&cf->fudgetime, <mp); | | 2667 | NTOHL_FP(&cf->fudgetime, <mp); |
2765 | LFPTOD(<mp, clock_stat.fudgetime2); | | 2668 | LFPTOD(<mp, clock_stat.fudgetime2); |
2766 | clock_stat.haveflags = CLK_HAVETIME2; | | 2669 | clock_stat.haveflags = CLK_HAVETIME2; |
2767 | break; | | 2670 | break; |
2768 | case FUDGE_VAL1: | | 2671 | case FUDGE_VAL1: |
2769 | clock_stat.fudgeval1 = ntohl(cf->fudgeval_flags); | | 2672 | clock_stat.fudgeval1 = ntohl(cf->fudgeval_flags); |
2770 | clock_stat.haveflags = CLK_HAVEVAL1; | | 2673 | clock_stat.haveflags = CLK_HAVEVAL1; |
2771 | break; | | 2674 | break; |
2772 | case FUDGE_VAL2: | | 2675 | case FUDGE_VAL2: |
2773 | clock_stat.fudgeval2 = ntohl(cf->fudgeval_flags); | | 2676 | clock_stat.fudgeval2 = ntohl(cf->fudgeval_flags); |
2774 | clock_stat.haveflags = CLK_HAVEVAL2; | | 2677 | clock_stat.haveflags = CLK_HAVEVAL2; |
2775 | break; | | 2678 | break; |
2776 | case FUDGE_FLAGS: | | 2679 | case FUDGE_FLAGS: |
2777 | clock_stat.flags = (u_char) (ntohl(cf->fudgeval_flags) & 0xf); | | 2680 | clock_stat.flags = (u_char) (ntohl(cf->fudgeval_flags) & 0xf); |
2778 | clock_stat.haveflags = | | 2681 | clock_stat.haveflags = |
2779 | (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4); | | 2682 | (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4); |
2780 | break; | | 2683 | break; |
2781 | default: | | 2684 | default: |
2782 | msyslog(LOG_ERR, "set_clock_fudge: default!"); | | 2685 | msyslog(LOG_ERR, "set_clock_fudge: default!"); |
2783 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); | | 2686 | req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); |
2784 | return; | | 2687 | return; |
2785 | } | | 2688 | } |
2786 | | | 2689 | |
2787 | refclock_control(&addr, &clock_stat, (struct refclockstat *)0); | | 2690 | refclock_control(&addr, &clock_stat, (struct refclockstat *)0); |
2788 | } | | 2691 | } |
2789 | | | 2692 | |
2790 | req_ack(srcadr, inter, inpkt, INFO_OKAY); | | 2693 | req_ack(srcadr, inter, inpkt, INFO_OKAY); |
2791 | } | | 2694 | } |
2792 | #endif | | 2695 | #endif |
2793 | | | 2696 | |
2794 | #ifdef REFCLOCK | | 2697 | #ifdef REFCLOCK |
2795 | /* | | 2698 | /* |
2796 | * get_clkbug_info - get debugging info about a clock | | 2699 | * get_clkbug_info - get debugging info about a clock |
2797 | */ | | 2700 | */ |
2798 | static void | | 2701 | static void |
2799 | get_clkbug_info( | | 2702 | get_clkbug_info( |
2800 | sockaddr_u *srcadr, | | 2703 | sockaddr_u *srcadr, |
2801 | struct interface *inter, | | 2704 | struct interface *inter, |
2802 | struct req_pkt *inpkt | | 2705 | struct req_pkt *inpkt |
2803 | ) | | 2706 | ) |
2804 | { | | 2707 | { |
2805 | register int i; | | 2708 | register int i; |
2806 | register struct info_clkbug *ic; | | 2709 | register struct info_clkbug *ic; |
2807 | register u_int32 *clkaddr; | | 2710 | register u_int32 *clkaddr; |
2808 | register int items; | | 2711 | register int items; |
2809 | struct refclockbug bug; | | 2712 | struct refclockbug bug; |
2810 | sockaddr_u addr; | | 2713 | sockaddr_u addr; |
2811 | | | 2714 | |
2812 | ZERO_SOCK(&addr); | | 2715 | ZERO_SOCK(&addr); |
2813 | AF(&addr) = AF_INET; | | 2716 | AF(&addr) = AF_INET; |
2814 | #ifdef ISC_PLATFORM_HAVESALEN | | 2717 | #ifdef ISC_PLATFORM_HAVESALEN |
2815 | addr.sa.sa_len = SOCKLEN(&addr); | | 2718 | addr.sa.sa_len = SOCKLEN(&addr); |
2816 | #endif | | 2719 | #endif |
2817 | SET_PORT(&addr, NTP_PORT); | | 2720 | SET_PORT(&addr, NTP_PORT); |
2818 | items = INFO_NITEMS(inpkt->err_nitems); | | 2721 | items = INFO_NITEMS(inpkt->err_nitems); |
2819 | clkaddr = (u_int32 *) inpkt->data; | | 2722 | clkaddr = (u_int32 *) inpkt->data; |
2820 | | | 2723 | |
2821 | ic = (struct info_clkbug *)prepare_pkt(srcadr, inter, inpkt, | | 2724 | ic = (struct info_clkbug *)prepare_pkt(srcadr, inter, inpkt, |
2822 | sizeof(struct info_clkbug)); | | 2725 | sizeof(struct info_clkbug)); |
2823 | | | 2726 | |
2824 | while (items-- > 0) { | | 2727 | while (items-- > 0) { |
2825 | NSRCADR(&addr) = *clkaddr++; | | 2728 | NSRCADR(&addr) = *clkaddr++; |
2826 | if (!ISREFCLOCKADR(&addr) || | | 2729 | if (!ISREFCLOCKADR(&addr) || |
2827 | findexistingpeer(&addr, NULL, -1, 0) == 0) { | | 2730 | findexistingpeer(&addr, NULL, -1, 0) == 0) { |
2828 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | 2731 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
2829 | return; | | 2732 | return; |
2830 | } | | 2733 | } |
2831 | | | 2734 | |
2832 | memset((char *)&bug, 0, sizeof bug); | | 2735 | memset((char *)&bug, 0, sizeof bug); |
2833 | refclock_buginfo(&addr, &bug); | | 2736 | refclock_buginfo(&addr, &bug); |
2834 | if (bug.nvalues == 0 && bug.ntimes == 0) { | | 2737 | if (bug.nvalues == 0 && bug.ntimes == 0) { |
2835 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); | | 2738 | req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); |
2836 | return; | | 2739 | return; |
2837 | } | | 2740 | } |
2838 | | | 2741 | |
2839 | ic->clockadr = NSRCADR(&addr); | | 2742 | ic->clockadr = NSRCADR(&addr); |
2840 | i = bug.nvalues; | | 2743 | i = bug.nvalues; |
2841 | if (i > NUMCBUGVALUES) | | 2744 | if (i > NUMCBUGVALUES) |
2842 | i = NUMCBUGVALUES; | | 2745 | i = NUMCBUGVALUES; |
2843 | ic->nvalues = (u_char)i; | | 2746 | ic->nvalues = (u_char)i; |
2844 | ic->svalues = htons((u_short) (bug.svalues & ((1<<i)-1))); | | 2747 | ic->svalues = htons((u_short) (bug.svalues & ((1<<i)-1))); |
2845 | while (--i >= 0) | | 2748 | while (--i >= 0) |
2846 | ic->values[i] = htonl(bug.values[i]); | | 2749 | ic->values[i] = htonl(bug.values[i]); |
2847 | | | 2750 | |
2848 | i = bug.ntimes; | | 2751 | i = bug.ntimes; |
2849 | if (i > NUMCBUGTIMES) | | 2752 | if (i > NUMCBUGTIMES) |
2850 | i = NUMCBUGTIMES; | | 2753 | i = NUMCBUGTIMES; |
2851 | ic->ntimes = (u_char)i; | | 2754 | ic->ntimes = (u_char)i; |
2852 | ic->stimes = htonl(bug.stimes); | | 2755 | ic->stimes = htonl(bug.stimes); |
2853 | while (--i >= 0) { | | 2756 | while (--i >= 0) { |
2854 | HTONL_FP(&bug.times[i], &ic->times[i]); | | 2757 | HTONL_FP(&bug.times[i], &ic->times[i]); |
2855 | } | | 2758 | } |
2856 | | | 2759 | |
2857 | ic = (struct info_clkbug *)more_pkt(); | | 2760 | ic = (struct info_clkbug *)more_pkt(); |
2858 | } | | 2761 | } |
2859 | flush_pkt(); | | 2762 | flush_pkt(); |
2860 | } | | 2763 | } |
2861 | #endif | | 2764 | #endif |
2862 | | | 2765 | |
2863 | /* | | 2766 | /* |
2864 | * receiver of interface structures | | 2767 | * receiver of interface structures |
2865 | */ | | 2768 | */ |
2866 | static void | | 2769 | static void |
2867 | fill_info_if_stats(void *data, interface_info_t *interface_info) | | 2770 | fill_info_if_stats(void *data, interface_info_t *interface_info) |
2868 | { | | 2771 | { |
2869 | struct info_if_stats **ifsp = (struct info_if_stats **)data; | | 2772 | struct info_if_stats **ifsp = (struct info_if_stats **)data; |
2870 | struct info_if_stats *ifs = *ifsp; | | 2773 | struct info_if_stats *ifs = *ifsp; |
2871 | endpt *ep = interface_info->ep; | | 2774 | endpt *ep = interface_info->ep; |
2872 | | | 2775 | |
2873 | memset(ifs, 0, sizeof(*ifs)); | | 2776 | memset(ifs, 0, sizeof(*ifs)); |
2874 | | | 2777 | |
2875 | if (IS_IPV6(&ep->sin)) { | | 2778 | if (IS_IPV6(&ep->sin)) { |
2876 | if (!client_v6_capable) { | | 2779 | if (!client_v6_capable) { |
2877 | return; | | 2780 | return; |
2878 | } | | 2781 | } |
2879 | ifs->v6_flag = 1; | | 2782 | ifs->v6_flag = 1; |
2880 | ifs->unaddr.addr6 = SOCK_ADDR6(&ep->sin); | | 2783 | ifs->unaddr.addr6 = SOCK_ADDR6(&ep->sin); |
2881 | ifs->unbcast.addr6 = SOCK_ADDR6(&ep->bcast); | | 2784 | ifs->unbcast.addr6 = SOCK_ADDR6(&ep->bcast); |
2882 | ifs->unmask.addr6 = SOCK_ADDR6(&ep->mask); | | 2785 | ifs->unmask.addr6 = SOCK_ADDR6(&ep->mask); |
2883 | } else { | | 2786 | } else { |
2884 | ifs->v6_flag = 0; | | 2787 | ifs->v6_flag = 0; |
2885 | ifs->unaddr.addr = SOCK_ADDR4(&ep->sin); | | 2788 | ifs->unaddr.addr = SOCK_ADDR4(&ep->sin); |
2886 | ifs->unbcast.addr = SOCK_ADDR4(&ep->bcast); | | 2789 | ifs->unbcast.addr = SOCK_ADDR4(&ep->bcast); |
2887 | ifs->unmask.addr = SOCK_ADDR4(&ep->mask); | | 2790 | ifs->unmask.addr = SOCK_ADDR4(&ep->mask); |
2888 | } | | 2791 | } |
2889 | ifs->v6_flag = htonl(ifs->v6_flag); | | 2792 | ifs->v6_flag = htonl(ifs->v6_flag); |
2890 | strncpy(ifs->name, ep->name, sizeof(ifs->name)); | | 2793 | strlcpy(ifs->name, ep->name, sizeof(ifs->name)); |
2891 | ifs->family = htons(ep->family); | | 2794 | ifs->family = htons(ep->family); |
2892 | ifs->flags = htonl(ep->flags); | | 2795 | ifs->flags = htonl(ep->flags); |
2893 | ifs->last_ttl = htonl(ep->last_ttl); | | 2796 | ifs->last_ttl = htonl(ep->last_ttl); |
2894 | ifs->num_mcast = htonl(ep->num_mcast); | | 2797 | ifs->num_mcast = htonl(ep->num_mcast); |
2895 | ifs->received = htonl(ep->received); | | 2798 | ifs->received = htonl(ep->received); |
2896 | ifs->sent = htonl(ep->sent); | | 2799 | ifs->sent = htonl(ep->sent); |
2897 | ifs->notsent = htonl(ep->notsent); | | 2800 | ifs->notsent = htonl(ep->notsent); |
2898 | ifs->ifindex = htonl(ep->ifindex); | | 2801 | ifs->ifindex = htonl(ep->ifindex); |
2899 | /* scope no longer in struct interface, in in6_addr typically */ | | 2802 | /* scope no longer in struct interface, in in6_addr typically */ |
2900 | ifs->scopeid = ifs->ifindex; | | 2803 | ifs->scopeid = ifs->ifindex; |
2901 | ifs->ifnum = htonl(ep->ifnum); | | 2804 | ifs->ifnum = htonl(ep->ifnum); |
2902 | ifs->uptime = htonl(current_time - ep->starttime); | | 2805 | ifs->uptime = htonl(current_time - ep->starttime); |
2903 | ifs->ignore_packets = ep->ignore_packets; | | 2806 | ifs->ignore_packets = ep->ignore_packets; |
2904 | ifs->peercnt = htonl(ep->peercnt); | | 2807 | ifs->peercnt = htonl(ep->peercnt); |
2905 | ifs->action = interface_info->action; | | 2808 | ifs->action = interface_info->action; |
2906 | | | 2809 | |
2907 | *ifsp = (struct info_if_stats *)more_pkt(); | | 2810 | *ifsp = (struct info_if_stats *)more_pkt(); |
2908 | } | | 2811 | } |
2909 | | | 2812 | |
2910 | /* | | 2813 | /* |
2911 | * get_if_stats - get interface statistics | | 2814 | * get_if_stats - get interface statistics |
2912 | */ | | 2815 | */ |
2913 | static void | | 2816 | static void |
2914 | get_if_stats( | | 2817 | get_if_stats( |
2915 | sockaddr_u *srcadr, | | 2818 | sockaddr_u *srcadr, |
2916 | struct interface *inter, | | 2819 | struct interface *inter, |
2917 | struct req_pkt *inpkt | | 2820 | struct req_pkt *inpkt |
2918 | ) | | 2821 | ) |
2919 | { | | 2822 | { |
2920 | struct info_if_stats *ifs; | | 2823 | struct info_if_stats *ifs; |
2921 | | | 2824 | |
2922 | DPRINTF(3, ("wants interface statistics\n")); | | 2825 | DPRINTF(3, ("wants interface statistics\n")); |
2923 | | | 2826 | |
2924 | ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt, | | 2827 | ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt, |
2925 | v6sizeof(struct info_if_stats)); | | 2828 | v6sizeof(struct info_if_stats)); |
2926 | | | 2829 | |
2927 | interface_enumerate(fill_info_if_stats, &ifs); | | 2830 | interface_enumerate(fill_info_if_stats, &ifs); |
2928 | | | 2831 | |
2929 | flush_pkt(); | | 2832 | flush_pkt(); |
2930 | } | | 2833 | } |
2931 | | | 2834 | |
2932 | static void | | 2835 | static void |
2933 | do_if_reload( | | 2836 | do_if_reload( |
2934 | sockaddr_u *srcadr, | | 2837 | sockaddr_u *srcadr, |
2935 | struct interface *inter, | | 2838 | struct interface *inter, |
2936 | struct req_pkt *inpkt | | 2839 | struct req_pkt *inpkt |
2937 | ) | | 2840 | ) |
2938 | { | | 2841 | { |
2939 | struct info_if_stats *ifs; | | 2842 | struct info_if_stats *ifs; |
2940 | | | 2843 | |
2941 | DPRINTF(3, ("wants interface reload\n")); | | 2844 | DPRINTF(3, ("wants interface reload\n")); |
2942 | | | 2845 | |
2943 | ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt, | | 2846 | ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt, |
2944 | v6sizeof(struct info_if_stats)); | | 2847 | v6sizeof(struct info_if_stats)); |
2945 | | | 2848 | |
2946 | interface_update(fill_info_if_stats, &ifs); | | 2849 | interface_update(fill_info_if_stats, &ifs); |
2947 | | | 2850 | |
2948 | flush_pkt(); | | 2851 | flush_pkt(); |
2949 | } | | 2852 | } |
2950 | | | 2853 | |