Coverage Report

Created: 2026-08-31 07:18

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