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