1 /*
2 chronyd/chronyc - Programs for keeping computer clocks accurate.
3
4 **********************************************************************
5 * Copyright (C) Richard P. Curnow 1997-2003
6 * Copyright (C) Miroslav Lichvar 2009-2016, 2018-2021
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 **********************************************************************
22
23 =======================================================================
24
25 Command and monitoring module in the main program
26 */
27
28 #include "config.h"
29
30 #include "sysincl.h"
31
32 #include "cmdmon.h"
33 #include "candm.h"
34 #include "sched.h"
35 #include "util.h"
36 #include "logging.h"
37 #include "keys.h"
38 #include "ntp_sources.h"
39 #include "ntp_core.h"
40 #include "smooth.h"
41 #include "socket.h"
42 #include "sources.h"
43 #include "sourcestats.h"
44 #include "reference.h"
45 #include "manual.h"
46 #include "memory.h"
47 #include "nts_ke_server.h"
48 #include "local.h"
49 #include "addrfilt.h"
50 #include "conf.h"
51 #include "rtc.h"
52 #include "pktlength.h"
53 #include "clientlog.h"
54 #include "refclock.h"
55
56 /* ================================================== */
57
58 #define INVALID_SOCK_FD (-5)
59
60 /* File descriptors for command and monitoring sockets */
61 static int sock_fdu;
62 static int sock_fd4;
63 static int sock_fd6;
64
65 /* Flag indicating the IPv4 socket is bound to an address */
66 static int bound_sock_fd4;
67
68 /* Flag indicating whether this module has been initialised or not */
69 static int initialised = 0;
70
71 /* ================================================== */
72 /* Array of permission levels for command types */
73
74 static const char permissions[] = {
75 PERMIT_OPEN, /* NULL */
76 PERMIT_AUTH, /* ONLINE */
77 PERMIT_AUTH, /* OFFLINE */
78 PERMIT_AUTH, /* BURST */
79 PERMIT_AUTH, /* MODIFY_MINPOLL */
80 PERMIT_AUTH, /* MODIFY_MAXPOLL */
81 PERMIT_AUTH, /* DUMP */
82 PERMIT_AUTH, /* MODIFY_MAXDELAY */
83 PERMIT_AUTH, /* MODIFY_MAXDELAYRATIO */
84 PERMIT_AUTH, /* MODIFY_MAXUPDATESKEW */
85 PERMIT_OPEN, /* LOGON */
86 PERMIT_AUTH, /* SETTIME */
87 PERMIT_AUTH, /* LOCAL */
88 PERMIT_AUTH, /* MANUAL */
89 PERMIT_OPEN, /* N_SOURCES */
90 PERMIT_OPEN, /* SOURCE_DATA */
91 PERMIT_AUTH, /* REKEY */
92 PERMIT_AUTH, /* ALLOW */
93 PERMIT_AUTH, /* ALLOWALL */
94 PERMIT_AUTH, /* DENY */
95 PERMIT_AUTH, /* DENYALL */
96 PERMIT_AUTH, /* CMDALLOW */
97 PERMIT_AUTH, /* CMDALLOWALL */
98 PERMIT_AUTH, /* CMDDENY */
99 PERMIT_AUTH, /* CMDDENYALL */
100 PERMIT_AUTH, /* ACCHECK */
101 PERMIT_AUTH, /* CMDACCHECK */
102 PERMIT_AUTH, /* ADD_SERVER */
103 PERMIT_AUTH, /* ADD_PEER */
104 PERMIT_AUTH, /* DEL_SOURCE */
105 PERMIT_AUTH, /* WRITERTC */
106 PERMIT_AUTH, /* DFREQ */
107 PERMIT_AUTH, /* DOFFSET */
108 PERMIT_OPEN, /* TRACKING */
109 PERMIT_OPEN, /* SOURCESTATS */
110 PERMIT_OPEN, /* RTCREPORT */
111 PERMIT_AUTH, /* TRIMRTC */
112 PERMIT_AUTH, /* CYCLELOGS */
113 PERMIT_AUTH, /* SUBNETS_ACCESSED */
114 PERMIT_AUTH, /* CLIENT_ACCESSES (by subnet) */
115 PERMIT_AUTH, /* CLIENT_ACCESSES_BY_INDEX */
116 PERMIT_OPEN, /* MANUAL_LIST */
117 PERMIT_AUTH, /* MANUAL_DELETE */
118 PERMIT_AUTH, /* MAKESTEP */
119 PERMIT_OPEN, /* ACTIVITY */
120 PERMIT_AUTH, /* MODIFY_MINSTRATUM */
121 PERMIT_AUTH, /* MODIFY_POLLTARGET */
122 PERMIT_AUTH, /* MODIFY_MAXDELAYDEVRATIO */
123 PERMIT_AUTH, /* RESELECT */
124 PERMIT_AUTH, /* RESELECTDISTANCE */
125 PERMIT_AUTH, /* MODIFY_MAKESTEP */
126 PERMIT_OPEN, /* SMOOTHING */
127 PERMIT_AUTH, /* SMOOTHTIME */
128 PERMIT_AUTH, /* REFRESH */
129 PERMIT_AUTH, /* SERVER_STATS */
130 PERMIT_AUTH, /* CLIENT_ACCESSES_BY_INDEX2 */
131 PERMIT_AUTH, /* LOCAL2 */
132 PERMIT_AUTH, /* NTP_DATA */
133 PERMIT_AUTH, /* ADD_SERVER2 */
134 PERMIT_AUTH, /* ADD_PEER2 */
135 PERMIT_AUTH, /* ADD_SERVER3 */
136 PERMIT_AUTH, /* ADD_PEER3 */
137 PERMIT_AUTH, /* SHUTDOWN */
138 PERMIT_AUTH, /* ONOFFLINE */
139 PERMIT_AUTH, /* ADD_SOURCE */
140 PERMIT_OPEN, /* NTP_SOURCE_NAME */
141 PERMIT_AUTH, /* RESET_SOURCES */
142 PERMIT_AUTH, /* AUTH_DATA */
143 PERMIT_AUTH, /* CLIENT_ACCESSES_BY_INDEX3 */
144 PERMIT_AUTH, /* SELECT_DATA */
145 PERMIT_AUTH, /* RELOAD_SOURCES */
146 PERMIT_AUTH, /* DOFFSET2 */
147 };
148
149 /* ================================================== */
150
151 /* This authorisation table is used for checking whether particular
152 machines are allowed to make command and monitoring requests. */
153 static ADF_AuthTable access_auth_table;
154
155 /* ================================================== */
156 /* Forward prototypes */
157 static void read_from_cmd_socket(int sock_fd, int event, void *anything);
158
159 /* ================================================== */
160
161 static int
open_socket(int family)162 open_socket(int family)
163 {
164 const char *local_path, *iface;
165 IPSockAddr local_addr;
166 int sock_fd, port;
167
168 switch (family) {
169 case IPADDR_INET4:
170 case IPADDR_INET6:
171 port = CNF_GetCommandPort();
172 if (port == 0 || !SCK_IsIpFamilyEnabled(family))
173 return INVALID_SOCK_FD;
174
175 CNF_GetBindCommandAddress(family, &local_addr.ip_addr);
176 local_addr.port = port;
177 iface = CNF_GetBindCommandInterface();
178
179 sock_fd = SCK_OpenUdpSocket(NULL, &local_addr, iface, SCK_FLAG_RX_DEST_ADDR);
180 if (sock_fd < 0) {
181 LOG(LOGS_ERR, "Could not open command socket on %s",
182 UTI_IPSockAddrToString(&local_addr));
183 return INVALID_SOCK_FD;
184 }
185
186 if (family == IPADDR_INET4)
187 bound_sock_fd4 = local_addr.ip_addr.addr.in4 != INADDR_ANY;
188
189 break;
190 case IPADDR_UNSPEC:
191 local_path = CNF_GetBindCommandPath();
192
193 sock_fd = SCK_OpenUnixDatagramSocket(NULL, local_path, 0);
194 if (sock_fd < 0) {
195 LOG(LOGS_ERR, "Could not open command socket on %s", local_path);
196 return INVALID_SOCK_FD;
197 }
198
199 break;
200 default:
201 assert(0);
202 }
203
204 /* Register handler for read events on the socket */
205 SCH_AddFileHandler(sock_fd, SCH_FILE_INPUT, read_from_cmd_socket, NULL);
206
207 return sock_fd;
208 }
209
210 /* ================================================== */
211
212 static void
do_size_checks(void)213 do_size_checks(void)
214 {
215 int i, request_length, padding_length, reply_length;
216 CMD_Request request;
217 CMD_Reply reply;
218
219 assert(offsetof(CMD_Request, data) == 20);
220 assert(offsetof(CMD_Reply, data) == 28);
221
222 for (i = 0; i < N_REQUEST_TYPES; i++) {
223 request.version = PROTO_VERSION_NUMBER;
224 request.command = htons(i);
225 request_length = PKL_CommandLength(&request);
226 padding_length = PKL_CommandPaddingLength(&request);
227 if (padding_length > MAX_PADDING_LENGTH || padding_length > request_length ||
228 request_length > sizeof (CMD_Request) ||
229 (request_length && request_length < offsetof(CMD_Request, data)))
230 assert(0);
231 }
232
233 for (i = 1; i < N_REPLY_TYPES; i++) {
234 reply.reply = htons(i);
235 reply.status = STT_SUCCESS;
236 reply_length = PKL_ReplyLength(&reply);
237 if ((reply_length && reply_length < offsetof(CMD_Reply, data)) ||
238 reply_length > sizeof (CMD_Reply))
239 assert(0);
240 }
241 }
242
243 /* ================================================== */
244
245 void
CAM_Initialise(void)246 CAM_Initialise(void)
247 {
248 assert(!initialised);
249 assert(sizeof (permissions) / sizeof (permissions[0]) == N_REQUEST_TYPES);
250 do_size_checks();
251
252 initialised = 1;
253
254 bound_sock_fd4 = 0;
255
256 sock_fdu = INVALID_SOCK_FD;
257 sock_fd4 = open_socket(IPADDR_INET4);
258 sock_fd6 = open_socket(IPADDR_INET6);
259
260 access_auth_table = ADF_CreateTable();
261 }
262
263 /* ================================================== */
264
265 void
CAM_Finalise(void)266 CAM_Finalise(void)
267 {
268 if (sock_fdu != INVALID_SOCK_FD) {
269 SCH_RemoveFileHandler(sock_fdu);
270 SCK_RemoveSocket(sock_fdu);
271 SCK_CloseSocket(sock_fdu);
272 sock_fdu = INVALID_SOCK_FD;
273 }
274
275 if (sock_fd4 != INVALID_SOCK_FD) {
276 SCH_RemoveFileHandler(sock_fd4);
277 SCK_CloseSocket(sock_fd4);
278 sock_fd4 = INVALID_SOCK_FD;
279 }
280
281 if (sock_fd6 != INVALID_SOCK_FD) {
282 SCH_RemoveFileHandler(sock_fd6);
283 SCK_CloseSocket(sock_fd6);
284 sock_fd6 = INVALID_SOCK_FD;
285 }
286
287 ADF_DestroyTable(access_auth_table);
288
289 initialised = 0;
290 }
291
292 /* ================================================== */
293
294 void
CAM_OpenUnixSocket(void)295 CAM_OpenUnixSocket(void)
296 {
297 /* This is separated from CAM_Initialise() as it needs to be called when
298 the process has already dropped the root privileges */
299 if (CNF_GetBindCommandPath())
300 sock_fdu = open_socket(IPADDR_UNSPEC);
301 }
302
303 /* ================================================== */
304
305 static void
transmit_reply(int sock_fd,int request_length,SCK_Message * message)306 transmit_reply(int sock_fd, int request_length, SCK_Message *message)
307 {
308 message->length = PKL_ReplyLength((CMD_Reply *)message->data);
309
310 if (request_length < message->length) {
311 DEBUG_LOG("Response longer than request req_len=%d res_len=%d",
312 request_length, message->length);
313 return;
314 }
315
316 /* Don't require responses to non-link-local addresses to use the same
317 interface */
318 if (message->addr_type == SCK_ADDR_IP &&
319 !SCK_IsLinkLocalIPAddress(&message->remote_addr.ip.ip_addr))
320 message->if_index = INVALID_IF_INDEX;
321
322 #if !defined(HAVE_IN_PKTINFO) && defined(IP_SENDSRCADDR)
323 /* On FreeBSD a local IPv4 address cannot be specified on bound socket */
324 if (message->addr_type == SCK_ADDR_IP && message->local_addr.ip.family == IPADDR_INET4 &&
325 (sock_fd != sock_fd4 || bound_sock_fd4))
326 message->local_addr.ip.family = IPADDR_UNSPEC;
327 #endif
328
329 if (!SCK_SendMessage(sock_fd, message, 0))
330 return;
331 }
332
333 /* ================================================== */
334
335 static void
handle_dump(CMD_Request * rx_message,CMD_Reply * tx_message)336 handle_dump(CMD_Request *rx_message, CMD_Reply *tx_message)
337 {
338 SRC_DumpSources();
339 NSR_DumpAuthData();
340 NKS_DumpKeys();
341 }
342
343 /* ================================================== */
344
345 static void
handle_online(CMD_Request * rx_message,CMD_Reply * tx_message)346 handle_online(CMD_Request *rx_message, CMD_Reply *tx_message)
347 {
348 IPAddr address, mask;
349
350 UTI_IPNetworkToHost(&rx_message->data.online.mask, &mask);
351 UTI_IPNetworkToHost(&rx_message->data.online.address, &address);
352 if (!NSR_SetConnectivity(&mask, &address, SRC_ONLINE))
353 tx_message->status = htons(STT_NOSUCHSOURCE);
354 }
355
356 /* ================================================== */
357
358 static void
handle_offline(CMD_Request * rx_message,CMD_Reply * tx_message)359 handle_offline(CMD_Request *rx_message, CMD_Reply *tx_message)
360 {
361 IPAddr address, mask;
362
363 UTI_IPNetworkToHost(&rx_message->data.offline.mask, &mask);
364 UTI_IPNetworkToHost(&rx_message->data.offline.address, &address);
365 if (!NSR_SetConnectivity(&mask, &address, SRC_OFFLINE))
366 tx_message->status = htons(STT_NOSUCHSOURCE);
367 }
368
369 /* ================================================== */
370
371 static void
handle_onoffline(CMD_Request * rx_message,CMD_Reply * tx_message)372 handle_onoffline(CMD_Request *rx_message, CMD_Reply *tx_message)
373 {
374 IPAddr address, mask;
375
376 address.family = mask.family = IPADDR_UNSPEC;
377 if (!NSR_SetConnectivity(&mask, &address, SRC_MAYBE_ONLINE))
378 ;
379 }
380
381 /* ================================================== */
382
383 static void
handle_burst(CMD_Request * rx_message,CMD_Reply * tx_message)384 handle_burst(CMD_Request *rx_message, CMD_Reply *tx_message)
385 {
386 IPAddr address, mask;
387
388 UTI_IPNetworkToHost(&rx_message->data.burst.mask, &mask);
389 UTI_IPNetworkToHost(&rx_message->data.burst.address, &address);
390 if (!NSR_InitiateSampleBurst(ntohl(rx_message->data.burst.n_good_samples),
391 ntohl(rx_message->data.burst.n_total_samples),
392 &mask, &address))
393 tx_message->status = htons(STT_NOSUCHSOURCE);
394 }
395
396 /* ================================================== */
397
398 static void
handle_modify_minpoll(CMD_Request * rx_message,CMD_Reply * tx_message)399 handle_modify_minpoll(CMD_Request *rx_message, CMD_Reply *tx_message)
400 {
401 IPAddr address;
402
403 UTI_IPNetworkToHost(&rx_message->data.modify_minpoll.address, &address);
404 if (!NSR_ModifyMinpoll(&address,
405 ntohl(rx_message->data.modify_minpoll.new_minpoll)))
406 tx_message->status = htons(STT_NOSUCHSOURCE);
407 }
408
409 /* ================================================== */
410
411 static void
handle_modify_maxpoll(CMD_Request * rx_message,CMD_Reply * tx_message)412 handle_modify_maxpoll(CMD_Request *rx_message, CMD_Reply *tx_message)
413 {
414 IPAddr address;
415
416 UTI_IPNetworkToHost(&rx_message->data.modify_minpoll.address, &address);
417 if (!NSR_ModifyMaxpoll(&address,
418 ntohl(rx_message->data.modify_minpoll.new_minpoll)))
419 tx_message->status = htons(STT_NOSUCHSOURCE);
420 }
421
422 /* ================================================== */
423
424 static void
handle_modify_maxdelay(CMD_Request * rx_message,CMD_Reply * tx_message)425 handle_modify_maxdelay(CMD_Request *rx_message, CMD_Reply *tx_message)
426 {
427 IPAddr address;
428
429 UTI_IPNetworkToHost(&rx_message->data.modify_maxdelay.address, &address);
430 if (!NSR_ModifyMaxdelay(&address,
431 UTI_FloatNetworkToHost(rx_message->data.modify_maxdelay.new_max_delay)))
432 tx_message->status = htons(STT_NOSUCHSOURCE);
433 }
434
435 /* ================================================== */
436
437 static void
handle_modify_maxdelayratio(CMD_Request * rx_message,CMD_Reply * tx_message)438 handle_modify_maxdelayratio(CMD_Request *rx_message, CMD_Reply *tx_message)
439 {
440 IPAddr address;
441
442 UTI_IPNetworkToHost(&rx_message->data.modify_maxdelayratio.address, &address);
443 if (!NSR_ModifyMaxdelayratio(&address,
444 UTI_FloatNetworkToHost(rx_message->data.modify_maxdelayratio.new_max_delay_ratio)))
445 tx_message->status = htons(STT_NOSUCHSOURCE);
446 }
447
448 /* ================================================== */
449
450 static void
handle_modify_maxdelaydevratio(CMD_Request * rx_message,CMD_Reply * tx_message)451 handle_modify_maxdelaydevratio(CMD_Request *rx_message, CMD_Reply *tx_message)
452 {
453 IPAddr address;
454
455 UTI_IPNetworkToHost(&rx_message->data.modify_maxdelaydevratio.address, &address);
456 if (!NSR_ModifyMaxdelaydevratio(&address,
457 UTI_FloatNetworkToHost(rx_message->data.modify_maxdelaydevratio.new_max_delay_dev_ratio)))
458 tx_message->status = htons(STT_NOSUCHSOURCE);
459 }
460
461 /* ================================================== */
462
463 static void
handle_modify_minstratum(CMD_Request * rx_message,CMD_Reply * tx_message)464 handle_modify_minstratum(CMD_Request *rx_message, CMD_Reply *tx_message)
465 {
466 IPAddr address;
467
468 UTI_IPNetworkToHost(&rx_message->data.modify_minpoll.address, &address);
469 if (!NSR_ModifyMinstratum(&address,
470 ntohl(rx_message->data.modify_minstratum.new_min_stratum)))
471 tx_message->status = htons(STT_NOSUCHSOURCE);
472 }
473
474 /* ================================================== */
475
476 static void
handle_modify_polltarget(CMD_Request * rx_message,CMD_Reply * tx_message)477 handle_modify_polltarget(CMD_Request *rx_message, CMD_Reply *tx_message)
478 {
479 IPAddr address;
480
481 UTI_IPNetworkToHost(&rx_message->data.modify_polltarget.address, &address);
482 if (!NSR_ModifyPolltarget(&address,
483 ntohl(rx_message->data.modify_polltarget.new_poll_target)))
484 tx_message->status = htons(STT_NOSUCHSOURCE);
485 }
486
487 /* ================================================== */
488
489 static void
handle_modify_maxupdateskew(CMD_Request * rx_message,CMD_Reply * tx_message)490 handle_modify_maxupdateskew(CMD_Request *rx_message, CMD_Reply *tx_message)
491 {
492 REF_ModifyMaxupdateskew(UTI_FloatNetworkToHost(rx_message->data.modify_maxupdateskew.new_max_update_skew));
493 }
494
495 /* ================================================== */
496
497 static void
handle_modify_makestep(CMD_Request * rx_message,CMD_Reply * tx_message)498 handle_modify_makestep(CMD_Request *rx_message, CMD_Reply *tx_message)
499 {
500 REF_ModifyMakestep(ntohl(rx_message->data.modify_makestep.limit),
501 UTI_FloatNetworkToHost(rx_message->data.modify_makestep.threshold));
502 }
503
504 /* ================================================== */
505
506 static void
handle_settime(CMD_Request * rx_message,CMD_Reply * tx_message)507 handle_settime(CMD_Request *rx_message, CMD_Reply *tx_message)
508 {
509 struct timespec ts;
510 double offset, dfreq_ppm, new_afreq_ppm;
511 UTI_TimespecNetworkToHost(&rx_message->data.settime.ts, &ts);
512 if (!MNL_IsEnabled()) {
513 tx_message->status = htons(STT_NOTENABLED);
514 } else if (MNL_AcceptTimestamp(&ts, &offset, &dfreq_ppm, &new_afreq_ppm)) {
515 tx_message->reply = htons(RPY_MANUAL_TIMESTAMP2);
516 tx_message->data.manual_timestamp.offset = UTI_FloatHostToNetwork(offset);
517 tx_message->data.manual_timestamp.dfreq_ppm = UTI_FloatHostToNetwork(dfreq_ppm);
518 tx_message->data.manual_timestamp.new_afreq_ppm = UTI_FloatHostToNetwork(new_afreq_ppm);
519 } else {
520 tx_message->status = htons(STT_FAILED);
521 }
522 }
523
524 /* ================================================== */
525
526 static void
handle_local(CMD_Request * rx_message,CMD_Reply * tx_message)527 handle_local(CMD_Request *rx_message, CMD_Reply *tx_message)
528 {
529 if (ntohl(rx_message->data.local.on_off)) {
530 REF_EnableLocal(ntohl(rx_message->data.local.stratum),
531 UTI_FloatNetworkToHost(rx_message->data.local.distance),
532 ntohl(rx_message->data.local.orphan));
533 } else {
534 REF_DisableLocal();
535 }
536 }
537
538 /* ================================================== */
539
540 static void
handle_manual(CMD_Request * rx_message,CMD_Reply * tx_message)541 handle_manual(CMD_Request *rx_message, CMD_Reply *tx_message)
542 {
543 int option;
544 option = ntohl(rx_message->data.manual.option);
545 switch (option) {
546 case 0:
547 MNL_Disable();
548 break;
549 case 1:
550 MNL_Enable();
551 break;
552 case 2:
553 MNL_Reset();
554 break;
555 default:
556 tx_message->status = htons(STT_INVALID);
557 break;
558 }
559 }
560
561 /* ================================================== */
562
563 static void
handle_n_sources(CMD_Request * rx_message,CMD_Reply * tx_message)564 handle_n_sources(CMD_Request *rx_message, CMD_Reply *tx_message)
565 {
566 int n_sources;
567 n_sources = SRC_ReadNumberOfSources();
568 tx_message->reply = htons(RPY_N_SOURCES);
569 tx_message->data.n_sources.n_sources = htonl(n_sources);
570 }
571
572 /* ================================================== */
573
574 static void
handle_source_data(CMD_Request * rx_message,CMD_Reply * tx_message)575 handle_source_data(CMD_Request *rx_message, CMD_Reply *tx_message)
576 {
577 RPT_SourceReport report;
578 struct timespec now_corr;
579
580 /* Get data */
581 SCH_GetLastEventTime(&now_corr, NULL, NULL);
582 if (SRC_ReportSource(ntohl(rx_message->data.source_data.index), &report, &now_corr)) {
583 switch (SRC_GetType(ntohl(rx_message->data.source_data.index))) {
584 case SRC_NTP:
585 NSR_ReportSource(&report, &now_corr);
586 break;
587 case SRC_REFCLOCK:
588 RCL_ReportSource(&report, &now_corr);
589 break;
590 }
591
592 tx_message->reply = htons(RPY_SOURCE_DATA);
593
594 UTI_IPHostToNetwork(&report.ip_addr, &tx_message->data.source_data.ip_addr);
595 tx_message->data.source_data.stratum = htons(report.stratum);
596 tx_message->data.source_data.poll = htons(report.poll);
597 switch (report.state) {
598 case RPT_NONSELECTABLE:
599 tx_message->data.source_data.state = htons(RPY_SD_ST_NONSELECTABLE);
600 break;
601 case RPT_FALSETICKER:
602 tx_message->data.source_data.state = htons(RPY_SD_ST_FALSETICKER);
603 break;
604 case RPT_JITTERY:
605 tx_message->data.source_data.state = htons(RPY_SD_ST_JITTERY);
606 break;
607 case RPT_SELECTABLE:
608 tx_message->data.source_data.state = htons(RPY_SD_ST_SELECTABLE);
609 break;
610 case RPT_UNSELECTED:
611 tx_message->data.source_data.state = htons(RPY_SD_ST_UNSELECTED);
612 break;
613 case RPT_SELECTED:
614 tx_message->data.source_data.state = htons(RPY_SD_ST_SELECTED);
615 break;
616 }
617 switch (report.mode) {
618 case RPT_NTP_CLIENT:
619 tx_message->data.source_data.mode = htons(RPY_SD_MD_CLIENT);
620 break;
621 case RPT_NTP_PEER:
622 tx_message->data.source_data.mode = htons(RPY_SD_MD_PEER);
623 break;
624 case RPT_LOCAL_REFERENCE:
625 tx_message->data.source_data.mode = htons(RPY_SD_MD_REF);
626 break;
627 }
628 tx_message->data.source_data.flags = htons(0);
629 tx_message->data.source_data.reachability = htons(report.reachability);
630 tx_message->data.source_data.since_sample = htonl(report.latest_meas_ago);
631 tx_message->data.source_data.orig_latest_meas = UTI_FloatHostToNetwork(report.orig_latest_meas);
632 tx_message->data.source_data.latest_meas = UTI_FloatHostToNetwork(report.latest_meas);
633 tx_message->data.source_data.latest_meas_err = UTI_FloatHostToNetwork(report.latest_meas_err);
634 } else {
635 tx_message->status = htons(STT_NOSUCHSOURCE);
636 }
637 }
638
639 /* ================================================== */
640
641 static void
handle_rekey(CMD_Request * rx_message,CMD_Reply * tx_message)642 handle_rekey(CMD_Request *rx_message, CMD_Reply *tx_message)
643 {
644 KEY_Reload();
645 NKS_ReloadKeys();
646 }
647
648 /* ================================================== */
649
650 static void
handle_allowdeny(CMD_Request * rx_message,CMD_Reply * tx_message,int allow,int all)651 handle_allowdeny(CMD_Request *rx_message, CMD_Reply *tx_message, int allow, int all)
652 {
653 IPAddr ip;
654 int subnet_bits;
655
656 UTI_IPNetworkToHost(&rx_message->data.allow_deny.ip, &ip);
657 subnet_bits = ntohl(rx_message->data.allow_deny.subnet_bits);
658 if (!NCR_AddAccessRestriction(&ip, subnet_bits, allow, all))
659 tx_message->status = htons(STT_BADSUBNET);
660 }
661
662 /* ================================================== */
663
664 static void
handle_cmdallowdeny(CMD_Request * rx_message,CMD_Reply * tx_message,int allow,int all)665 handle_cmdallowdeny(CMD_Request *rx_message, CMD_Reply *tx_message, int allow, int all)
666 {
667 IPAddr ip;
668 int subnet_bits;
669
670 UTI_IPNetworkToHost(&rx_message->data.allow_deny.ip, &ip);
671 subnet_bits = ntohl(rx_message->data.allow_deny.subnet_bits);
672 if (!CAM_AddAccessRestriction(&ip, subnet_bits, allow, all))
673 tx_message->status = htons(STT_BADSUBNET);
674 }
675
676 /* ================================================== */
677
678 static void
handle_accheck(CMD_Request * rx_message,CMD_Reply * tx_message)679 handle_accheck(CMD_Request *rx_message, CMD_Reply *tx_message)
680 {
681 IPAddr ip;
682 UTI_IPNetworkToHost(&rx_message->data.ac_check.ip, &ip);
683 if (NCR_CheckAccessRestriction(&ip)) {
684 tx_message->status = htons(STT_ACCESSALLOWED);
685 } else {
686 tx_message->status = htons(STT_ACCESSDENIED);
687 }
688 }
689
690 /* ================================================== */
691
692 static void
handle_cmdaccheck(CMD_Request * rx_message,CMD_Reply * tx_message)693 handle_cmdaccheck(CMD_Request *rx_message, CMD_Reply *tx_message)
694 {
695 IPAddr ip;
696 UTI_IPNetworkToHost(&rx_message->data.ac_check.ip, &ip);
697 if (CAM_CheckAccessRestriction(&ip)) {
698 tx_message->status = htons(STT_ACCESSALLOWED);
699 } else {
700 tx_message->status = htons(STT_ACCESSDENIED);
701 }
702 }
703
704 /* ================================================== */
705
706 static void
handle_add_source(CMD_Request * rx_message,CMD_Reply * tx_message)707 handle_add_source(CMD_Request *rx_message, CMD_Reply *tx_message)
708 {
709 NTP_Source_Type type;
710 SourceParameters params;
711 NSR_Status status;
712 char *name;
713 int pool, port;
714
715 switch (ntohl(rx_message->data.ntp_source.type)) {
716 case REQ_ADDSRC_SERVER:
717 type = NTP_SERVER;
718 pool = 0;
719 break;
720 case REQ_ADDSRC_PEER:
721 type = NTP_PEER;
722 pool = 0;
723 break;
724 case REQ_ADDSRC_POOL:
725 type = NTP_SERVER;
726 pool = 1;
727 break;
728 default:
729 tx_message->status = htons(STT_INVALID);
730 return;
731 }
732
733 name = (char *)rx_message->data.ntp_source.name;
734
735 /* Make sure the name is terminated */
736 if (name[sizeof (rx_message->data.ntp_source.name) - 1] != '\0') {
737 tx_message->status = htons(STT_INVALIDNAME);
738 return;
739 }
740
741 port = ntohl(rx_message->data.ntp_source.port);
742 params.minpoll = ntohl(rx_message->data.ntp_source.minpoll);
743 params.maxpoll = ntohl(rx_message->data.ntp_source.maxpoll);
744 params.presend_minpoll = ntohl(rx_message->data.ntp_source.presend_minpoll);
745 params.min_stratum = ntohl(rx_message->data.ntp_source.min_stratum);
746 params.poll_target = ntohl(rx_message->data.ntp_source.poll_target);
747 params.version = ntohl(rx_message->data.ntp_source.version);
748 params.max_sources = ntohl(rx_message->data.ntp_source.max_sources);
749 params.min_samples = ntohl(rx_message->data.ntp_source.min_samples);
750 params.max_samples = ntohl(rx_message->data.ntp_source.max_samples);
751 params.filter_length = ntohl(rx_message->data.ntp_source.filter_length);
752 params.authkey = ntohl(rx_message->data.ntp_source.authkey);
753 params.nts_port = ntohl(rx_message->data.ntp_source.nts_port);
754 params.cert_set = ntohl(rx_message->data.ntp_source.cert_set);
755 params.max_delay = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay);
756 params.max_delay_ratio =
757 UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay_ratio);
758 params.max_delay_dev_ratio =
759 UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay_dev_ratio);
760 params.min_delay = UTI_FloatNetworkToHost(rx_message->data.ntp_source.min_delay);
761 params.asymmetry = UTI_FloatNetworkToHost(rx_message->data.ntp_source.asymmetry);
762 params.offset = UTI_FloatNetworkToHost(rx_message->data.ntp_source.offset);
763
764 params.connectivity = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_ONLINE ?
765 SRC_ONLINE : SRC_OFFLINE;
766 params.auto_offline = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_AUTOOFFLINE ? 1 : 0;
767 params.iburst = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_IBURST ? 1 : 0;
768 params.interleaved = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_INTERLEAVED ? 1 : 0;
769 params.burst = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_BURST ? 1 : 0;
770 params.nts = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_NTS ? 1 : 0;
771 params.copy = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_COPY ? 1 : 0;
772 params.ext_fields =
773 ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_EF_EXP1 ? NTP_EF_FLAG_EXP1 : 0;
774 params.sel_options =
775 (ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_PREFER ? SRC_SELECT_PREFER : 0) |
776 (ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_NOSELECT ? SRC_SELECT_NOSELECT : 0) |
777 (ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_TRUST ? SRC_SELECT_TRUST : 0) |
778 (ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_REQUIRE ? SRC_SELECT_REQUIRE : 0);
779
780 status = NSR_AddSourceByName(name, port, pool, type, ¶ms, NULL);
781 switch (status) {
782 case NSR_Success:
783 break;
784 case NSR_UnresolvedName:
785 /* Try to resolve the name now */
786 NSR_ResolveSources();
787 break;
788 case NSR_AlreadyInUse:
789 tx_message->status = htons(STT_SOURCEALREADYKNOWN);
790 break;
791 case NSR_TooManySources:
792 tx_message->status = htons(STT_TOOMANYSOURCES);
793 break;
794 case NSR_InvalidName:
795 tx_message->status = htons(STT_INVALIDNAME);
796 break;
797 case NSR_InvalidAF:
798 case NSR_NoSuchSource:
799 assert(0);
800 break;
801 }
802 }
803
804 /* ================================================== */
805
806 static void
handle_del_source(CMD_Request * rx_message,CMD_Reply * tx_message)807 handle_del_source(CMD_Request *rx_message, CMD_Reply *tx_message)
808 {
809 NSR_Status status;
810 IPAddr ip_addr;
811
812 UTI_IPNetworkToHost(&rx_message->data.del_source.ip_addr, &ip_addr);
813
814 status = NSR_RemoveSource(&ip_addr);
815 switch (status) {
816 case NSR_Success:
817 break;
818 case NSR_NoSuchSource:
819 tx_message->status = htons(STT_NOSUCHSOURCE);
820 break;
821 case NSR_TooManySources:
822 case NSR_AlreadyInUse:
823 case NSR_InvalidAF:
824 case NSR_InvalidName:
825 case NSR_UnresolvedName:
826 assert(0);
827 break;
828 }
829 }
830
831 /* ================================================== */
832
833 static void
handle_writertc(CMD_Request * rx_message,CMD_Reply * tx_message)834 handle_writertc(CMD_Request *rx_message, CMD_Reply *tx_message)
835 {
836 switch (RTC_WriteParameters()) {
837 case RTC_ST_OK:
838 break;
839 case RTC_ST_NODRV:
840 tx_message->status = htons(STT_NORTC);
841 break;
842 case RTC_ST_BADFILE:
843 tx_message->status = htons(STT_BADRTCFILE);
844 break;
845 }
846 }
847
848 /* ================================================== */
849
850 static void
handle_dfreq(CMD_Request * rx_message,CMD_Reply * tx_message)851 handle_dfreq(CMD_Request *rx_message, CMD_Reply *tx_message)
852 {
853 double dfreq;
854 dfreq = UTI_FloatNetworkToHost(rx_message->data.dfreq.dfreq);
855 LCL_AccumulateDeltaFrequency(dfreq * 1.0e-6);
856 LOG(LOGS_INFO, "Accumulated delta freq of %.3fppm", dfreq);
857 }
858
859 /* ================================================== */
860
861 static void
handle_doffset(CMD_Request * rx_message,CMD_Reply * tx_message)862 handle_doffset(CMD_Request *rx_message, CMD_Reply *tx_message)
863 {
864 double doffset;
865
866 doffset = UTI_FloatNetworkToHost(rx_message->data.doffset.doffset);
867 if (!LCL_AccumulateOffset(doffset, 0.0)) {
868 tx_message->status = htons(STT_FAILED);
869 } else {
870 LOG(LOGS_INFO, "Accumulated delta offset of %.6f seconds", doffset);
871 }
872 }
873
874 /* ================================================== */
875
876 static void
handle_tracking(CMD_Request * rx_message,CMD_Reply * tx_message)877 handle_tracking(CMD_Request *rx_message, CMD_Reply *tx_message)
878 {
879 RPT_TrackingReport rpt;
880
881 REF_GetTrackingReport(&rpt);
882 tx_message->reply = htons(RPY_TRACKING);
883 tx_message->data.tracking.ref_id = htonl(rpt.ref_id);
884 UTI_IPHostToNetwork(&rpt.ip_addr, &tx_message->data.tracking.ip_addr);
885 tx_message->data.tracking.stratum = htons(rpt.stratum);
886 tx_message->data.tracking.leap_status = htons(rpt.leap_status);
887 UTI_TimespecHostToNetwork(&rpt.ref_time, &tx_message->data.tracking.ref_time);
888 tx_message->data.tracking.current_correction = UTI_FloatHostToNetwork(rpt.current_correction);
889 tx_message->data.tracking.last_offset = UTI_FloatHostToNetwork(rpt.last_offset);
890 tx_message->data.tracking.rms_offset = UTI_FloatHostToNetwork(rpt.rms_offset);
891 tx_message->data.tracking.freq_ppm = UTI_FloatHostToNetwork(rpt.freq_ppm);
892 tx_message->data.tracking.resid_freq_ppm = UTI_FloatHostToNetwork(rpt.resid_freq_ppm);
893 tx_message->data.tracking.skew_ppm = UTI_FloatHostToNetwork(rpt.skew_ppm);
894 tx_message->data.tracking.root_delay = UTI_FloatHostToNetwork(rpt.root_delay);
895 tx_message->data.tracking.root_dispersion = UTI_FloatHostToNetwork(rpt.root_dispersion);
896 tx_message->data.tracking.last_update_interval = UTI_FloatHostToNetwork(rpt.last_update_interval);
897 }
898
899 /* ================================================== */
900
901 static void
handle_smoothing(CMD_Request * rx_message,CMD_Reply * tx_message)902 handle_smoothing(CMD_Request *rx_message, CMD_Reply *tx_message)
903 {
904 RPT_SmoothingReport report;
905 struct timespec now;
906
907 SCH_GetLastEventTime(&now, NULL, NULL);
908
909 if (!SMT_GetSmoothingReport(&report, &now)) {
910 tx_message->status = htons(STT_NOTENABLED);
911 return;
912 }
913
914 tx_message->reply = htons(RPY_SMOOTHING);
915 tx_message->data.smoothing.flags = htonl((report.active ? RPY_SMT_FLAG_ACTIVE : 0) |
916 (report.leap_only ? RPY_SMT_FLAG_LEAPONLY : 0));
917 tx_message->data.smoothing.offset = UTI_FloatHostToNetwork(report.offset);
918 tx_message->data.smoothing.freq_ppm = UTI_FloatHostToNetwork(report.freq_ppm);
919 tx_message->data.smoothing.wander_ppm = UTI_FloatHostToNetwork(report.wander_ppm);
920 tx_message->data.smoothing.last_update_ago = UTI_FloatHostToNetwork(report.last_update_ago);
921 tx_message->data.smoothing.remaining_time = UTI_FloatHostToNetwork(report.remaining_time);
922 }
923
924 /* ================================================== */
925
926 static void
handle_smoothtime(CMD_Request * rx_message,CMD_Reply * tx_message)927 handle_smoothtime(CMD_Request *rx_message, CMD_Reply *tx_message)
928 {
929 struct timespec now;
930 int option;
931
932 if (!SMT_IsEnabled()) {
933 tx_message->status = htons(STT_NOTENABLED);
934 return;
935 }
936
937 option = ntohl(rx_message->data.smoothtime.option);
938 SCH_GetLastEventTime(&now, NULL, NULL);
939
940 switch (option) {
941 case REQ_SMOOTHTIME_RESET:
942 SMT_Reset(&now);
943 break;
944 case REQ_SMOOTHTIME_ACTIVATE:
945 SMT_Activate(&now);
946 break;
947 default:
948 tx_message->status = htons(STT_INVALID);
949 break;
950 }
951 }
952
953 /* ================================================== */
954
955 static void
handle_sourcestats(CMD_Request * rx_message,CMD_Reply * tx_message)956 handle_sourcestats(CMD_Request *rx_message, CMD_Reply *tx_message)
957 {
958 int status;
959 RPT_SourcestatsReport report;
960 struct timespec now_corr;
961
962 SCH_GetLastEventTime(&now_corr, NULL, NULL);
963 status = SRC_ReportSourcestats(ntohl(rx_message->data.sourcestats.index),
964 &report, &now_corr);
965
966 if (status) {
967 tx_message->reply = htons(RPY_SOURCESTATS);
968 tx_message->data.sourcestats.ref_id = htonl(report.ref_id);
969 UTI_IPHostToNetwork(&report.ip_addr, &tx_message->data.sourcestats.ip_addr);
970 tx_message->data.sourcestats.n_samples = htonl(report.n_samples);
971 tx_message->data.sourcestats.n_runs = htonl(report.n_runs);
972 tx_message->data.sourcestats.span_seconds = htonl(report.span_seconds);
973 tx_message->data.sourcestats.resid_freq_ppm = UTI_FloatHostToNetwork(report.resid_freq_ppm);
974 tx_message->data.sourcestats.skew_ppm = UTI_FloatHostToNetwork(report.skew_ppm);
975 tx_message->data.sourcestats.sd = UTI_FloatHostToNetwork(report.sd);
976 tx_message->data.sourcestats.est_offset = UTI_FloatHostToNetwork(report.est_offset);
977 tx_message->data.sourcestats.est_offset_err = UTI_FloatHostToNetwork(report.est_offset_err);
978 } else {
979 tx_message->status = htons(STT_NOSUCHSOURCE);
980 }
981 }
982
983 /* ================================================== */
984
985 static void
handle_rtcreport(CMD_Request * rx_message,CMD_Reply * tx_message)986 handle_rtcreport(CMD_Request *rx_message, CMD_Reply *tx_message)
987 {
988 int status;
989 RPT_RTC_Report report;
990 status = RTC_GetReport(&report);
991 if (status) {
992 tx_message->reply = htons(RPY_RTC);
993 UTI_TimespecHostToNetwork(&report.ref_time, &tx_message->data.rtc.ref_time);
994 tx_message->data.rtc.n_samples = htons(report.n_samples);
995 tx_message->data.rtc.n_runs = htons(report.n_runs);
996 tx_message->data.rtc.span_seconds = htonl(report.span_seconds);
997 tx_message->data.rtc.rtc_seconds_fast = UTI_FloatHostToNetwork(report.rtc_seconds_fast);
998 tx_message->data.rtc.rtc_gain_rate_ppm = UTI_FloatHostToNetwork(report.rtc_gain_rate_ppm);
999 } else {
1000 tx_message->status = htons(STT_NORTC);
1001 }
1002 }
1003
1004 /* ================================================== */
1005
1006 static void
handle_trimrtc(CMD_Request * rx_message,CMD_Reply * tx_message)1007 handle_trimrtc(CMD_Request *rx_message, CMD_Reply *tx_message)
1008 {
1009 if (!RTC_Trim())
1010 tx_message->status = htons(STT_NORTC);
1011 }
1012
1013 /* ================================================== */
1014
1015 static void
handle_cyclelogs(CMD_Request * rx_message,CMD_Reply * tx_message)1016 handle_cyclelogs(CMD_Request *rx_message, CMD_Reply *tx_message)
1017 {
1018 LOG_CycleLogFiles();
1019 }
1020
1021 /* ================================================== */
1022
1023 static void
handle_client_accesses_by_index(CMD_Request * rx_message,CMD_Reply * tx_message)1024 handle_client_accesses_by_index(CMD_Request *rx_message, CMD_Reply *tx_message)
1025 {
1026 RPT_ClientAccessByIndex_Report report;
1027 RPY_ClientAccesses_Client *client;
1028 int n_indices;
1029 uint32_t i, j, req_first_index, req_n_clients, req_min_hits, req_reset;
1030 struct timespec now;
1031
1032 SCH_GetLastEventTime(&now, NULL, NULL);
1033
1034 req_first_index = ntohl(rx_message->data.client_accesses_by_index.first_index);
1035 req_n_clients = ntohl(rx_message->data.client_accesses_by_index.n_clients);
1036 if (req_n_clients > MAX_CLIENT_ACCESSES)
1037 req_n_clients = MAX_CLIENT_ACCESSES;
1038 req_min_hits = ntohl(rx_message->data.client_accesses_by_index.min_hits);
1039 req_reset = ntohl(rx_message->data.client_accesses_by_index.reset);
1040
1041 n_indices = CLG_GetNumberOfIndices();
1042 if (n_indices < 0) {
1043 tx_message->status = htons(STT_INACTIVE);
1044 return;
1045 }
1046
1047 tx_message->reply = htons(RPY_CLIENT_ACCESSES_BY_INDEX3);
1048 tx_message->data.client_accesses_by_index.n_indices = htonl(n_indices);
1049
1050 for (i = req_first_index, j = 0; i < (uint32_t)n_indices && j < req_n_clients; i++) {
1051 if (!CLG_GetClientAccessReportByIndex(i, req_reset, req_min_hits, &report, &now))
1052 continue;
1053
1054 client = &tx_message->data.client_accesses_by_index.clients[j++];
1055
1056 UTI_IPHostToNetwork(&report.ip_addr, &client->ip);
1057 client->ntp_hits = htonl(report.ntp_hits);
1058 client->nke_hits = htonl(report.nke_hits);
1059 client->cmd_hits = htonl(report.cmd_hits);
1060 client->ntp_drops = htonl(report.ntp_drops);
1061 client->nke_drops = htonl(report.nke_drops);
1062 client->cmd_drops = htonl(report.cmd_drops);
1063 client->ntp_interval = report.ntp_interval;
1064 client->nke_interval = report.nke_interval;
1065 client->cmd_interval = report.cmd_interval;
1066 client->ntp_timeout_interval = report.ntp_timeout_interval;
1067 client->last_ntp_hit_ago = htonl(report.last_ntp_hit_ago);
1068 client->last_nke_hit_ago = htonl(report.last_nke_hit_ago);
1069 client->last_cmd_hit_ago = htonl(report.last_cmd_hit_ago);
1070 }
1071
1072 tx_message->data.client_accesses_by_index.next_index = htonl(i);
1073 tx_message->data.client_accesses_by_index.n_clients = htonl(j);
1074 }
1075
1076 /* ================================================== */
1077
1078 static void
handle_manual_list(CMD_Request * rx_message,CMD_Reply * tx_message)1079 handle_manual_list(CMD_Request *rx_message, CMD_Reply *tx_message)
1080 {
1081 int n_samples;
1082 int i;
1083 RPY_ManualListSample *sample;
1084 RPT_ManualSamplesReport report[MAX_MANUAL_LIST_SAMPLES];
1085
1086 tx_message->reply = htons(RPY_MANUAL_LIST2);
1087
1088 MNL_ReportSamples(report, MAX_MANUAL_LIST_SAMPLES, &n_samples);
1089 tx_message->data.manual_list.n_samples = htonl(n_samples);
1090
1091 for (i=0; i<n_samples; i++) {
1092 sample = &tx_message->data.manual_list.samples[i];
1093 UTI_TimespecHostToNetwork(&report[i].when, &sample->when);
1094 sample->slewed_offset = UTI_FloatHostToNetwork(report[i].slewed_offset);
1095 sample->orig_offset = UTI_FloatHostToNetwork(report[i].orig_offset);
1096 sample->residual = UTI_FloatHostToNetwork(report[i].residual);
1097 }
1098 }
1099
1100 /* ================================================== */
1101
1102 static void
handle_manual_delete(CMD_Request * rx_message,CMD_Reply * tx_message)1103 handle_manual_delete(CMD_Request *rx_message, CMD_Reply *tx_message)
1104 {
1105 int index;
1106
1107 index = ntohl(rx_message->data.manual_delete.index);
1108 if (!MNL_DeleteSample(index))
1109 tx_message->status = htons(STT_BADSAMPLE);
1110 }
1111
1112 /* ================================================== */
1113
1114 static void
handle_make_step(CMD_Request * rx_message,CMD_Reply * tx_message)1115 handle_make_step(CMD_Request *rx_message, CMD_Reply *tx_message)
1116 {
1117 if (!LCL_MakeStep())
1118 tx_message->status = htons(STT_FAILED);
1119 }
1120
1121 /* ================================================== */
1122
1123 static void
handle_activity(CMD_Request * rx_message,CMD_Reply * tx_message)1124 handle_activity(CMD_Request *rx_message, CMD_Reply *tx_message)
1125 {
1126 RPT_ActivityReport report;
1127 NSR_GetActivityReport(&report);
1128 tx_message->data.activity.online = htonl(report.online);
1129 tx_message->data.activity.offline = htonl(report.offline);
1130 tx_message->data.activity.burst_online = htonl(report.burst_online);
1131 tx_message->data.activity.burst_offline = htonl(report.burst_offline);
1132 tx_message->data.activity.unresolved = htonl(report.unresolved);
1133 tx_message->reply = htons(RPY_ACTIVITY);
1134 }
1135
1136 /* ================================================== */
1137
1138 static void
handle_reselect_distance(CMD_Request * rx_message,CMD_Reply * tx_message)1139 handle_reselect_distance(CMD_Request *rx_message, CMD_Reply *tx_message)
1140 {
1141 double dist;
1142 dist = UTI_FloatNetworkToHost(rx_message->data.reselect_distance.distance);
1143 SRC_SetReselectDistance(dist);
1144 }
1145
1146 /* ================================================== */
1147
1148 static void
handle_reselect(CMD_Request * rx_message,CMD_Reply * tx_message)1149 handle_reselect(CMD_Request *rx_message, CMD_Reply *tx_message)
1150 {
1151 SRC_ReselectSource();
1152 }
1153
1154 /* ================================================== */
1155
1156 static void
handle_refresh(CMD_Request * rx_message,CMD_Reply * tx_message)1157 handle_refresh(CMD_Request *rx_message, CMD_Reply *tx_message)
1158 {
1159 NSR_RefreshAddresses();
1160 }
1161
1162 /* ================================================== */
1163
1164 static void
handle_server_stats(CMD_Request * rx_message,CMD_Reply * tx_message)1165 handle_server_stats(CMD_Request *rx_message, CMD_Reply *tx_message)
1166 {
1167 RPT_ServerStatsReport report;
1168
1169 CLG_GetServerStatsReport(&report);
1170 tx_message->reply = htons(RPY_SERVER_STATS3);
1171 tx_message->data.server_stats.ntp_hits = htonl(report.ntp_hits);
1172 tx_message->data.server_stats.nke_hits = htonl(report.nke_hits);
1173 tx_message->data.server_stats.cmd_hits = htonl(report.cmd_hits);
1174 tx_message->data.server_stats.ntp_drops = htonl(report.ntp_drops);
1175 tx_message->data.server_stats.nke_drops = htonl(report.nke_drops);
1176 tx_message->data.server_stats.cmd_drops = htonl(report.cmd_drops);
1177 tx_message->data.server_stats.log_drops = htonl(report.log_drops);
1178 tx_message->data.server_stats.ntp_auth_hits = htonl(report.ntp_auth_hits);
1179 tx_message->data.server_stats.ntp_interleaved_hits = htonl(report.ntp_interleaved_hits);
1180 tx_message->data.server_stats.ntp_timestamps = htonl(report.ntp_timestamps);
1181 tx_message->data.server_stats.ntp_span_seconds = htonl(report.ntp_span_seconds);
1182 }
1183
1184 /* ================================================== */
1185
1186 static void
handle_ntp_data(CMD_Request * rx_message,CMD_Reply * tx_message)1187 handle_ntp_data(CMD_Request *rx_message, CMD_Reply *tx_message)
1188 {
1189 RPT_NTPReport report;
1190
1191 UTI_IPNetworkToHost(&rx_message->data.ntp_data.ip_addr, &report.remote_addr);
1192
1193 if (!NSR_GetNTPReport(&report)) {
1194 tx_message->status = htons(STT_NOSUCHSOURCE);
1195 return;
1196 }
1197
1198 tx_message->reply = htons(RPY_NTP_DATA);
1199 UTI_IPHostToNetwork(&report.remote_addr, &tx_message->data.ntp_data.remote_addr);
1200 UTI_IPHostToNetwork(&report.local_addr, &tx_message->data.ntp_data.local_addr);
1201 tx_message->data.ntp_data.remote_port = htons(report.remote_port);
1202 tx_message->data.ntp_data.leap = report.leap;
1203 tx_message->data.ntp_data.version = report.version;
1204 tx_message->data.ntp_data.mode = report.mode;
1205 tx_message->data.ntp_data.stratum = report.stratum;
1206 tx_message->data.ntp_data.poll = report.poll;
1207 tx_message->data.ntp_data.precision = report.precision;
1208 tx_message->data.ntp_data.root_delay = UTI_FloatHostToNetwork(report.root_delay);
1209 tx_message->data.ntp_data.root_dispersion = UTI_FloatHostToNetwork(report.root_dispersion);
1210 tx_message->data.ntp_data.ref_id = htonl(report.ref_id);
1211 UTI_TimespecHostToNetwork(&report.ref_time, &tx_message->data.ntp_data.ref_time);
1212 tx_message->data.ntp_data.offset = UTI_FloatHostToNetwork(report.offset);
1213 tx_message->data.ntp_data.peer_delay = UTI_FloatHostToNetwork(report.peer_delay);
1214 tx_message->data.ntp_data.peer_dispersion = UTI_FloatHostToNetwork(report.peer_dispersion);
1215 tx_message->data.ntp_data.response_time = UTI_FloatHostToNetwork(report.response_time);
1216 tx_message->data.ntp_data.jitter_asymmetry = UTI_FloatHostToNetwork(report.jitter_asymmetry);
1217 tx_message->data.ntp_data.flags = htons((report.tests & RPY_NTP_FLAGS_TESTS) |
1218 (report.interleaved ? RPY_NTP_FLAG_INTERLEAVED : 0) |
1219 (report.authenticated ? RPY_NTP_FLAG_AUTHENTICATED : 0));
1220 tx_message->data.ntp_data.tx_tss_char = report.tx_tss_char;
1221 tx_message->data.ntp_data.rx_tss_char = report.rx_tss_char;
1222 tx_message->data.ntp_data.total_tx_count = htonl(report.total_tx_count);
1223 tx_message->data.ntp_data.total_rx_count = htonl(report.total_rx_count);
1224 tx_message->data.ntp_data.total_valid_count = htonl(report.total_valid_count);
1225 memset(tx_message->data.ntp_data.reserved, 0xff, sizeof (tx_message->data.ntp_data.reserved));
1226 }
1227
1228 /* ================================================== */
1229
1230 static void
handle_shutdown(CMD_Request * rx_message,CMD_Reply * tx_message)1231 handle_shutdown(CMD_Request *rx_message, CMD_Reply *tx_message)
1232 {
1233 LOG(LOGS_INFO, "Received shutdown command");
1234 SCH_QuitProgram();
1235 }
1236
1237 /* ================================================== */
1238
1239 static void
handle_ntp_source_name(CMD_Request * rx_message,CMD_Reply * tx_message)1240 handle_ntp_source_name(CMD_Request *rx_message, CMD_Reply *tx_message)
1241 {
1242 IPAddr addr;
1243 char *name;
1244
1245 UTI_IPNetworkToHost(&rx_message->data.ntp_source_name.ip_addr, &addr);
1246 name = NSR_GetName(&addr);
1247
1248 if (!name) {
1249 tx_message->status = htons(STT_NOSUCHSOURCE);
1250 return;
1251 }
1252
1253 tx_message->reply = htons(RPY_NTP_SOURCE_NAME);
1254
1255 /* Avoid compiler warning */
1256 if (strlen(name) >= sizeof (tx_message->data.ntp_source_name.name))
1257 memcpy(tx_message->data.ntp_source_name.name, name,
1258 sizeof (tx_message->data.ntp_source_name.name));
1259 else
1260 strncpy((char *)tx_message->data.ntp_source_name.name, name,
1261 sizeof (tx_message->data.ntp_source_name.name));
1262 }
1263
1264 /* ================================================== */
1265
1266 static void
handle_reload_sources(CMD_Request * rx_message,CMD_Reply * tx_message)1267 handle_reload_sources(CMD_Request *rx_message, CMD_Reply *tx_message)
1268 {
1269 CNF_ReloadSources();
1270 }
1271
1272 /* ================================================== */
1273
1274 static void
handle_reset_sources(CMD_Request * rx_message,CMD_Reply * tx_message)1275 handle_reset_sources(CMD_Request *rx_message, CMD_Reply *tx_message)
1276 {
1277 struct timespec cooked_now, now;
1278
1279 SRC_ResetSources();
1280 SCH_GetLastEventTime(&cooked_now, NULL, &now);
1281 LCL_NotifyExternalTimeStep(&now, &cooked_now, 0.0, 0.0);
1282 }
1283
1284 /* ================================================== */
1285
1286 static void
handle_auth_data(CMD_Request * rx_message,CMD_Reply * tx_message)1287 handle_auth_data(CMD_Request *rx_message, CMD_Reply *tx_message)
1288 {
1289 RPT_AuthReport report;
1290 IPAddr ip_addr;
1291
1292 UTI_IPNetworkToHost(&rx_message->data.auth_data.ip_addr, &ip_addr);
1293
1294 if (!NSR_GetAuthReport(&ip_addr, &report)) {
1295 tx_message->status = htons(STT_NOSUCHSOURCE);
1296 return;
1297 }
1298
1299 tx_message->reply = htons(RPY_AUTH_DATA);
1300
1301 switch (report.mode) {
1302 case NTP_AUTH_NONE:
1303 tx_message->data.auth_data.mode = htons(RPY_AD_MD_NONE);
1304 break;
1305 case NTP_AUTH_SYMMETRIC:
1306 tx_message->data.auth_data.mode = htons(RPY_AD_MD_SYMMETRIC);
1307 break;
1308 case NTP_AUTH_NTS:
1309 tx_message->data.auth_data.mode = htons(RPY_AD_MD_NTS);
1310 break;
1311 default:
1312 break;
1313 }
1314
1315 tx_message->data.auth_data.key_type = htons(report.key_type);
1316 tx_message->data.auth_data.key_id = htonl(report.key_id);
1317 tx_message->data.auth_data.key_length = htons(report.key_length);
1318 tx_message->data.auth_data.ke_attempts = htons(report.ke_attempts);
1319 tx_message->data.auth_data.last_ke_ago = htonl(report.last_ke_ago);
1320 tx_message->data.auth_data.cookies = htons(report.cookies);
1321 tx_message->data.auth_data.cookie_length = htons(report.cookie_length);
1322 tx_message->data.auth_data.nak = htons(report.nak);
1323 }
1324
1325 /* ================================================== */
1326
1327 static uint16_t
convert_select_options(int options)1328 convert_select_options(int options)
1329 {
1330 return (options & SRC_SELECT_PREFER ? RPY_SD_OPTION_PREFER : 0) |
1331 (options & SRC_SELECT_NOSELECT ? RPY_SD_OPTION_NOSELECT : 0) |
1332 (options & SRC_SELECT_TRUST ? RPY_SD_OPTION_TRUST : 0) |
1333 (options & SRC_SELECT_REQUIRE ? RPY_SD_OPTION_REQUIRE : 0);
1334 }
1335
1336 /* ================================================== */
1337
1338 static void
handle_select_data(CMD_Request * rx_message,CMD_Reply * tx_message)1339 handle_select_data(CMD_Request *rx_message, CMD_Reply *tx_message)
1340 {
1341 RPT_SelectReport report;
1342
1343 if (!SRC_GetSelectReport(ntohl(rx_message->data.select_data.index), &report)) {
1344 tx_message->status = htons(STT_NOSUCHSOURCE);
1345 return;
1346 }
1347
1348 tx_message->reply = htons(RPY_SELECT_DATA);
1349
1350 tx_message->data.select_data.ref_id = htonl(report.ref_id);
1351 UTI_IPHostToNetwork(&report.ip_addr, &tx_message->data.select_data.ip_addr);
1352 tx_message->data.select_data.state_char = report.state_char;
1353 tx_message->data.select_data.authentication = report.authentication;
1354 tx_message->data.select_data.leap = report.leap;
1355 tx_message->data.select_data.conf_options = htons(convert_select_options(report.conf_options));
1356 tx_message->data.select_data.eff_options = htons(convert_select_options(report.eff_options));
1357 tx_message->data.select_data.last_sample_ago = htonl(report.last_sample_ago);
1358 tx_message->data.select_data.score = UTI_FloatHostToNetwork(report.score);
1359 tx_message->data.select_data.hi_limit = UTI_FloatHostToNetwork(report.hi_limit);
1360 tx_message->data.select_data.lo_limit = UTI_FloatHostToNetwork(report.lo_limit);
1361 }
1362
1363 /* ================================================== */
1364 /* Read a packet and process it */
1365
1366 static void
read_from_cmd_socket(int sock_fd,int event,void * anything)1367 read_from_cmd_socket(int sock_fd, int event, void *anything)
1368 {
1369 SCK_Message *sck_message;
1370 CMD_Request rx_message;
1371 CMD_Reply tx_message;
1372 IPAddr loopback_addr, remote_ip;
1373 int read_length, expected_length;
1374 int localhost, allowed, log_index;
1375 uint16_t rx_command;
1376 struct timespec now, cooked_now;
1377
1378 sck_message = SCK_ReceiveMessage(sock_fd, 0);
1379 if (!sck_message)
1380 return;
1381
1382 read_length = sck_message->length;
1383
1384 /* Get current time cheaply */
1385 SCH_GetLastEventTime(&cooked_now, NULL, &now);
1386
1387 /* Check if it's from localhost (127.0.0.1, ::1, or Unix domain),
1388 or an authorised address */
1389 switch (sck_message->addr_type) {
1390 case SCK_ADDR_IP:
1391 assert(sock_fd == sock_fd4 || sock_fd == sock_fd6);
1392 remote_ip = sck_message->remote_addr.ip.ip_addr;
1393 SCK_GetLoopbackIPAddress(remote_ip.family, &loopback_addr);
1394 localhost = UTI_CompareIPs(&remote_ip, &loopback_addr, NULL) == 0;
1395
1396 if (!localhost && !ADF_IsAllowed(access_auth_table, &remote_ip)) {
1397 DEBUG_LOG("Unauthorised host %s",
1398 UTI_IPSockAddrToString(&sck_message->remote_addr.ip));
1399 return;
1400 }
1401
1402 assert(remote_ip.family != IPADDR_UNSPEC);
1403
1404 break;
1405 case SCK_ADDR_UNIX:
1406 assert(sock_fd == sock_fdu);
1407 remote_ip.family = IPADDR_UNSPEC;
1408 localhost = 1;
1409 break;
1410 default:
1411 DEBUG_LOG("Unexpected address type");
1412 return;
1413 }
1414
1415 if (read_length < offsetof(CMD_Request, data) ||
1416 read_length < offsetof(CMD_Reply, data) ||
1417 read_length > sizeof (CMD_Request)) {
1418 /* We don't know how to process anything like this or an error reply
1419 would be larger than the request */
1420 DEBUG_LOG("Unexpected length");
1421 return;
1422 }
1423
1424 memcpy(&rx_message, sck_message->data, read_length);
1425
1426 if (rx_message.pkt_type != PKT_TYPE_CMD_REQUEST ||
1427 rx_message.res1 != 0 ||
1428 rx_message.res2 != 0) {
1429 DEBUG_LOG("Command packet dropped");
1430 return;
1431 }
1432
1433 log_index = CLG_LogServiceAccess(CLG_CMDMON, &remote_ip, &cooked_now);
1434
1435 /* Don't reply to all requests from hosts other than localhost if the rate
1436 is excessive */
1437 if (!localhost && log_index >= 0 && CLG_LimitServiceRate(CLG_CMDMON, log_index)) {
1438 DEBUG_LOG("Command packet discarded to limit response rate");
1439 return;
1440 }
1441
1442 expected_length = PKL_CommandLength(&rx_message);
1443 rx_command = ntohs(rx_message.command);
1444
1445 memset(&tx_message, 0, sizeof (tx_message));
1446 sck_message->data = &tx_message;
1447 sck_message->length = 0;
1448
1449 tx_message.version = PROTO_VERSION_NUMBER;
1450 tx_message.pkt_type = PKT_TYPE_CMD_REPLY;
1451 tx_message.command = rx_message.command;
1452 tx_message.reply = htons(RPY_NULL);
1453 tx_message.status = htons(STT_SUCCESS);
1454 tx_message.sequence = rx_message.sequence;
1455
1456 if (rx_message.version != PROTO_VERSION_NUMBER) {
1457 DEBUG_LOG("Command packet has invalid version (%d != %d)",
1458 rx_message.version, PROTO_VERSION_NUMBER);
1459
1460 if (rx_message.version >= PROTO_VERSION_MISMATCH_COMPAT_SERVER) {
1461 tx_message.status = htons(STT_BADPKTVERSION);
1462 transmit_reply(sock_fd, read_length, sck_message);
1463 }
1464 return;
1465 }
1466
1467 if (rx_command >= N_REQUEST_TYPES ||
1468 expected_length < (int)offsetof(CMD_Request, data)) {
1469 DEBUG_LOG("Command packet has invalid command %d", rx_command);
1470
1471 tx_message.status = htons(STT_INVALID);
1472 transmit_reply(sock_fd, read_length, sck_message);
1473 return;
1474 }
1475
1476 if (read_length < expected_length) {
1477 DEBUG_LOG("Command packet is too short (%d < %d)", read_length,
1478 expected_length);
1479
1480 tx_message.status = htons(STT_BADPKTLENGTH);
1481 transmit_reply(sock_fd, read_length, sck_message);
1482 return;
1483 }
1484
1485 /* OK, we have a valid message. Now dispatch on message type and process it. */
1486
1487 if (rx_command >= N_REQUEST_TYPES) {
1488 /* This should be already handled */
1489 assert(0);
1490 } else {
1491 /* Check level of authority required to issue the command. All commands
1492 from the Unix domain socket (which is accessible only by the root and
1493 chrony user/group) are allowed. */
1494 if (remote_ip.family == IPADDR_UNSPEC) {
1495 assert(sock_fd == sock_fdu);
1496 allowed = 1;
1497 } else {
1498 switch (permissions[rx_command]) {
1499 case PERMIT_AUTH:
1500 allowed = 0;
1501 break;
1502 case PERMIT_LOCAL:
1503 allowed = localhost;
1504 break;
1505 case PERMIT_OPEN:
1506 allowed = 1;
1507 break;
1508 default:
1509 assert(0);
1510 allowed = 0;
1511 }
1512 }
1513
1514 if (allowed) {
1515 switch(rx_command) {
1516 case REQ_NULL:
1517 /* Do nothing */
1518 break;
1519
1520 case REQ_DUMP:
1521 handle_dump(&rx_message, &tx_message);
1522 break;
1523
1524 case REQ_ONLINE:
1525 handle_online(&rx_message, &tx_message);
1526 break;
1527
1528 case REQ_OFFLINE:
1529 handle_offline(&rx_message, &tx_message);
1530 break;
1531
1532 case REQ_BURST:
1533 handle_burst(&rx_message, &tx_message);
1534 break;
1535
1536 case REQ_MODIFY_MINPOLL:
1537 handle_modify_minpoll(&rx_message, &tx_message);
1538 break;
1539
1540 case REQ_MODIFY_MAXPOLL:
1541 handle_modify_maxpoll(&rx_message, &tx_message);
1542 break;
1543
1544 case REQ_MODIFY_MAXDELAY:
1545 handle_modify_maxdelay(&rx_message, &tx_message);
1546 break;
1547
1548 case REQ_MODIFY_MAXDELAYRATIO:
1549 handle_modify_maxdelayratio(&rx_message, &tx_message);
1550 break;
1551
1552 case REQ_MODIFY_MAXDELAYDEVRATIO:
1553 handle_modify_maxdelaydevratio(&rx_message, &tx_message);
1554 break;
1555
1556 case REQ_MODIFY_MAXUPDATESKEW:
1557 handle_modify_maxupdateskew(&rx_message, &tx_message);
1558 break;
1559
1560 case REQ_MODIFY_MAKESTEP:
1561 handle_modify_makestep(&rx_message, &tx_message);
1562 break;
1563
1564 case REQ_LOGON:
1565 /* Authentication is no longer supported, log-on always fails */
1566 tx_message.status = htons(STT_FAILED);
1567 break;
1568
1569 case REQ_SETTIME:
1570 handle_settime(&rx_message, &tx_message);
1571 break;
1572
1573 case REQ_LOCAL2:
1574 handle_local(&rx_message, &tx_message);
1575 break;
1576
1577 case REQ_MANUAL:
1578 handle_manual(&rx_message, &tx_message);
1579 break;
1580
1581 case REQ_N_SOURCES:
1582 handle_n_sources(&rx_message, &tx_message);
1583 break;
1584
1585 case REQ_SOURCE_DATA:
1586 handle_source_data(&rx_message, &tx_message);
1587 break;
1588
1589 case REQ_REKEY:
1590 handle_rekey(&rx_message, &tx_message);
1591 break;
1592
1593 case REQ_ALLOW:
1594 handle_allowdeny(&rx_message, &tx_message, 1, 0);
1595 break;
1596
1597 case REQ_ALLOWALL:
1598 handle_allowdeny(&rx_message, &tx_message, 1, 1);
1599 break;
1600
1601 case REQ_DENY:
1602 handle_allowdeny(&rx_message, &tx_message, 0, 0);
1603 break;
1604
1605 case REQ_DENYALL:
1606 handle_allowdeny(&rx_message, &tx_message, 0, 1);
1607 break;
1608
1609 case REQ_CMDALLOW:
1610 handle_cmdallowdeny(&rx_message, &tx_message, 1, 0);
1611 break;
1612
1613 case REQ_CMDALLOWALL:
1614 handle_cmdallowdeny(&rx_message, &tx_message, 1, 1);
1615 break;
1616
1617 case REQ_CMDDENY:
1618 handle_cmdallowdeny(&rx_message, &tx_message, 0, 0);
1619 break;
1620
1621 case REQ_CMDDENYALL:
1622 handle_cmdallowdeny(&rx_message, &tx_message, 0, 1);
1623 break;
1624
1625 case REQ_ACCHECK:
1626 handle_accheck(&rx_message, &tx_message);
1627 break;
1628
1629 case REQ_CMDACCHECK:
1630 handle_cmdaccheck(&rx_message, &tx_message);
1631 break;
1632
1633 case REQ_ADD_SOURCE:
1634 handle_add_source(&rx_message, &tx_message);
1635 break;
1636
1637 case REQ_DEL_SOURCE:
1638 handle_del_source(&rx_message, &tx_message);
1639 break;
1640
1641 case REQ_WRITERTC:
1642 handle_writertc(&rx_message, &tx_message);
1643 break;
1644
1645 case REQ_DFREQ:
1646 handle_dfreq(&rx_message, &tx_message);
1647 break;
1648
1649 case REQ_DOFFSET2:
1650 handle_doffset(&rx_message, &tx_message);
1651 break;
1652
1653 case REQ_TRACKING:
1654 handle_tracking(&rx_message, &tx_message);
1655 break;
1656
1657 case REQ_SMOOTHING:
1658 handle_smoothing(&rx_message, &tx_message);
1659 break;
1660
1661 case REQ_SMOOTHTIME:
1662 handle_smoothtime(&rx_message, &tx_message);
1663 break;
1664
1665 case REQ_SOURCESTATS:
1666 handle_sourcestats(&rx_message, &tx_message);
1667 break;
1668
1669 case REQ_RTCREPORT:
1670 handle_rtcreport(&rx_message, &tx_message);
1671 break;
1672
1673 case REQ_TRIMRTC:
1674 handle_trimrtc(&rx_message, &tx_message);
1675 break;
1676
1677 case REQ_CYCLELOGS:
1678 handle_cyclelogs(&rx_message, &tx_message);
1679 break;
1680
1681 case REQ_CLIENT_ACCESSES_BY_INDEX3:
1682 handle_client_accesses_by_index(&rx_message, &tx_message);
1683 break;
1684
1685 case REQ_MANUAL_LIST:
1686 handle_manual_list(&rx_message, &tx_message);
1687 break;
1688
1689 case REQ_MANUAL_DELETE:
1690 handle_manual_delete(&rx_message, &tx_message);
1691 break;
1692
1693 case REQ_MAKESTEP:
1694 handle_make_step(&rx_message, &tx_message);
1695 break;
1696
1697 case REQ_ACTIVITY:
1698 handle_activity(&rx_message, &tx_message);
1699 break;
1700
1701 case REQ_RESELECTDISTANCE:
1702 handle_reselect_distance(&rx_message, &tx_message);
1703 break;
1704
1705 case REQ_RESELECT:
1706 handle_reselect(&rx_message, &tx_message);
1707 break;
1708
1709 case REQ_MODIFY_MINSTRATUM:
1710 handle_modify_minstratum(&rx_message, &tx_message);
1711 break;
1712
1713 case REQ_MODIFY_POLLTARGET:
1714 handle_modify_polltarget(&rx_message, &tx_message);
1715 break;
1716
1717 case REQ_REFRESH:
1718 handle_refresh(&rx_message, &tx_message);
1719 break;
1720
1721 case REQ_SERVER_STATS:
1722 handle_server_stats(&rx_message, &tx_message);
1723 break;
1724
1725 case REQ_NTP_DATA:
1726 handle_ntp_data(&rx_message, &tx_message);
1727 break;
1728
1729 case REQ_SHUTDOWN:
1730 handle_shutdown(&rx_message, &tx_message);
1731 break;
1732
1733 case REQ_ONOFFLINE:
1734 handle_onoffline(&rx_message, &tx_message);
1735 break;
1736
1737 case REQ_NTP_SOURCE_NAME:
1738 handle_ntp_source_name(&rx_message, &tx_message);
1739 break;
1740
1741 case REQ_RESET_SOURCES:
1742 handle_reset_sources(&rx_message, &tx_message);
1743 break;
1744
1745 case REQ_AUTH_DATA:
1746 handle_auth_data(&rx_message, &tx_message);
1747 break;
1748
1749 case REQ_SELECT_DATA:
1750 handle_select_data(&rx_message, &tx_message);
1751 break;
1752
1753 case REQ_RELOAD_SOURCES:
1754 handle_reload_sources(&rx_message, &tx_message);
1755 break;
1756
1757 default:
1758 DEBUG_LOG("Unhandled command %d", rx_command);
1759 tx_message.status = htons(STT_FAILED);
1760 break;
1761 }
1762 } else {
1763 tx_message.status = htons(STT_UNAUTH);
1764 }
1765 }
1766
1767 /* Transmit the response */
1768 transmit_reply(sock_fd, read_length, sck_message);
1769 }
1770
1771 /* ================================================== */
1772
1773 int
CAM_AddAccessRestriction(IPAddr * ip_addr,int subnet_bits,int allow,int all)1774 CAM_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all)
1775 {
1776 ADF_Status status;
1777
1778 if (allow) {
1779 if (all) {
1780 status = ADF_AllowAll(access_auth_table, ip_addr, subnet_bits);
1781 } else {
1782 status = ADF_Allow(access_auth_table, ip_addr, subnet_bits);
1783 }
1784 } else {
1785 if (all) {
1786 status = ADF_DenyAll(access_auth_table, ip_addr, subnet_bits);
1787 } else {
1788 status = ADF_Deny(access_auth_table, ip_addr, subnet_bits);
1789 }
1790 }
1791
1792 if (status == ADF_BADSUBNET) {
1793 return 0;
1794 } else if (status == ADF_SUCCESS) {
1795 return 1;
1796 } else {
1797 return 0;
1798 }
1799 }
1800
1801 /* ================================================== */
1802
1803 int
CAM_CheckAccessRestriction(IPAddr * ip_addr)1804 CAM_CheckAccessRestriction(IPAddr *ip_addr)
1805 {
1806 return ADF_IsAllowed(access_auth_table, ip_addr);
1807 }
1808
1809
1810 /* ================================================== */
1811 /* ================================================== */
1812