"Fossies" - the Fresh Open Source Software Archive

Member "ntp-4.2.8p17/ntpd/ntp_control.c" (6 Jun 2023, 126089 Bytes) of package /linux/misc/ntp-4.2.8p17.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ntp_control.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.2.8p16_vs_4.2.8p17.

    1 /*
    2  * ntp_control.c - respond to mode 6 control messages and send async
    3  *         traps.  Provides service to ntpq and others.
    4  */
    5 
    6 #ifdef HAVE_CONFIG_H
    7 # include <config.h>
    8 #endif
    9 
   10 #include <stdio.h>
   11 #include <ctype.h>
   12 #include <signal.h>
   13 #include <sys/stat.h>
   14 #ifdef HAVE_NETINET_IN_H
   15 # include <netinet/in.h>
   16 #endif
   17 #include <arpa/inet.h>
   18 
   19 #include "ntpd.h"
   20 #include "ntp_io.h"
   21 #include "ntp_refclock.h"
   22 #include "ntp_control.h"
   23 #include "ntp_unixtime.h"
   24 #include "ntp_stdlib.h"
   25 #include "ntp_config.h"
   26 #include "ntp_crypto.h"
   27 #include "ntp_assert.h"
   28 #include "ntp_leapsec.h"
   29 #include "lib_strbuf.h"
   30 #include "timexsup.h"
   31 
   32 #include <rc_cmdlength.h>
   33 #ifdef KERNEL_PLL
   34 # include "ntp_syscall.h"
   35 #endif
   36 
   37 /*
   38  * Structure to hold request procedure information
   39  */
   40 
   41 struct ctl_proc {
   42     short control_code;     /* defined request code */
   43 #define NO_REQUEST  (-1)
   44     u_short flags;          /* flags word */
   45     /* Only one flag.  Authentication required or not. */
   46 #define NOAUTH  0
   47 #define AUTH    1
   48     void (*handler) (struct recvbuf *, int); /* handle request */
   49 };
   50 
   51 
   52 /*
   53  * Request processing routines
   54  */
   55 static  void    ctl_error   (u_char);
   56 #ifdef REFCLOCK
   57 static  u_short ctlclkstatus    (struct refclockstat *);
   58 #endif
   59 static  void    ctl_flushpkt    (u_char);
   60 static  void    ctl_putdata (const char *, unsigned int, int);
   61 static  void    ctl_putstr  (const char *, const char *, size_t);
   62 static  void    ctl_putdblf (const char *, int, int, double);
   63 #define ctl_putdbl(tag, d)  ctl_putdblf(tag, 1, 3, d)
   64 #define ctl_putdbl6(tag, d) ctl_putdblf(tag, 1, 6, d)
   65 #define ctl_putsfp(tag, sfp)    ctl_putdblf(tag, 0, -1, \
   66                         FPTOD(sfp))
   67 static  void    ctl_putuint (const char *, u_long);
   68 static  void    ctl_puthex  (const char *, u_long);
   69 static  void    ctl_putint  (const char *, long);
   70 static  void    ctl_putts   (const char *, l_fp *);
   71 static  void    ctl_putadr  (const char *, u_int32,
   72                  sockaddr_u *);
   73 static  void    ctl_putrefid    (const char *, u_int32);
   74 static  void    ctl_putarray    (const char *, double *, int);
   75 static  void    ctl_putsys  (int);
   76 static  void    ctl_putpeer (int, struct peer *);
   77 static  void    ctl_putfs   (const char *, tstamp_t);
   78 static  void    ctl_printf  (const char *, ...) NTP_PRINTF(1, 2);
   79 #ifdef REFCLOCK
   80 static  void    ctl_putclock    (int, struct refclockstat *, int);
   81 #endif  /* REFCLOCK */
   82 static  const struct ctl_var *ctl_getitem(const struct ctl_var *,
   83                       char **);
   84 static  u_short count_var   (const struct ctl_var *);
   85 static  void    control_unspec  (struct recvbuf *, int);
   86 static  void    read_status (struct recvbuf *, int);
   87 static  void    read_sysvars    (void);
   88 static  void    read_peervars   (void);
   89 static  void    read_variables  (struct recvbuf *, int);
   90 static  void    write_variables (struct recvbuf *, int);
   91 static  void    read_clockstatus(struct recvbuf *, int);
   92 static  void    write_clockstatus(struct recvbuf *, int);
   93 static  void    set_trap    (struct recvbuf *, int);
   94 static  void    save_config (struct recvbuf *, int);
   95 static  void    configure   (struct recvbuf *, int);
   96 static  void    send_mru_entry  (mon_entry *, int);
   97 static  void    send_random_tag_value(int);
   98 static  void    read_mru_list   (struct recvbuf *, int);
   99 static  void    send_ifstats_entry(endpt *, u_int);
  100 static  void    read_ifstats    (struct recvbuf *);
  101 static  void    sockaddrs_from_restrict_u(sockaddr_u *, sockaddr_u *,
  102                       restrict_u *, int);
  103 static  void    send_restrict_entry(restrict_u *, int, u_int);
  104 static  void    send_restrict_list(restrict_u *, int, u_int *);
  105 static  void    read_addr_restrictions(struct recvbuf *);
  106 static  void    read_ordlist    (struct recvbuf *, int);
  107 static  u_int32 derive_nonce    (sockaddr_u *, u_int32, u_int32);
  108 static  void    generate_nonce  (struct recvbuf *, char *, size_t);
  109 static  int validate_nonce  (const char *, struct recvbuf *);
  110 static  void    req_nonce   (struct recvbuf *, int);
  111 static  void    unset_trap  (struct recvbuf *, int);
  112 static  struct ctl_trap *ctlfindtrap(sockaddr_u *,
  113                      struct interface *);
  114 
  115 int/*BOOL*/ is_safe_filename(const char * name);
  116 
  117 static const struct ctl_proc control_codes[] = {
  118     { CTL_OP_UNSPEC,        NOAUTH, control_unspec },
  119     { CTL_OP_READSTAT,      NOAUTH, read_status },
  120     { CTL_OP_READVAR,       NOAUTH, read_variables },
  121     { CTL_OP_WRITEVAR,      AUTH,   write_variables },
  122     { CTL_OP_READCLOCK,     NOAUTH, read_clockstatus },
  123     { CTL_OP_WRITECLOCK,        AUTH,   write_clockstatus },
  124     { CTL_OP_SETTRAP,       AUTH,   set_trap },
  125     { CTL_OP_CONFIGURE,     AUTH,   configure },
  126     { CTL_OP_SAVECONFIG,        AUTH,   save_config },
  127     { CTL_OP_READ_MRU,      NOAUTH, read_mru_list },
  128     { CTL_OP_READ_ORDLIST_A,    AUTH,   read_ordlist },
  129     { CTL_OP_REQ_NONCE,     NOAUTH, req_nonce },
  130     { CTL_OP_UNSETTRAP,     AUTH,   unset_trap },
  131     { NO_REQUEST,           0,  NULL }
  132 };
  133 
  134 /*
  135  * System variables we understand
  136  */
  137 #define CS_LEAP         1
  138 #define CS_STRATUM      2
  139 #define CS_PRECISION        3
  140 #define CS_ROOTDELAY        4
  141 #define CS_ROOTDISPERSION   5
  142 #define CS_REFID        6
  143 #define CS_REFTIME      7
  144 #define CS_POLL         8
  145 #define CS_PEERID       9
  146 #define CS_OFFSET       10
  147 #define CS_DRIFT        11
  148 #define CS_JITTER       12
  149 #define CS_ERROR        13
  150 #define CS_CLOCK        14
  151 #define CS_PROCESSOR        15
  152 #define CS_SYSTEM       16
  153 #define CS_VERSION      17
  154 #define CS_STABIL       18
  155 #define CS_VARLIST      19
  156 #define CS_TAI          20
  157 #define CS_LEAPTAB      21
  158 #define CS_LEAPEND      22
  159 #define CS_RATE         23
  160 #define CS_MRU_ENABLED      24
  161 #define CS_MRU_DEPTH        25
  162 #define CS_MRU_DEEPEST      26
  163 #define CS_MRU_MINDEPTH     27
  164 #define CS_MRU_MAXAGE       28
  165 #define CS_MRU_MAXDEPTH     29
  166 #define CS_MRU_MEM      30
  167 #define CS_MRU_MAXMEM       31
  168 #define CS_SS_UPTIME        32
  169 #define CS_SS_RESET     33
  170 #define CS_SS_RECEIVED      34
  171 #define CS_SS_THISVER       35
  172 #define CS_SS_OLDVER        36
  173 #define CS_SS_BADFORMAT     37
  174 #define CS_SS_BADAUTH       38
  175 #define CS_SS_DECLINED      39
  176 #define CS_SS_RESTRICTED    40
  177 #define CS_SS_LIMITED       41
  178 #define CS_SS_KODSENT       42
  179 #define CS_SS_PROCESSED     43
  180 #define CS_SS_LAMPORT       44
  181 #define CS_SS_TSROUNDING    45
  182 #define CS_PEERADR      46
  183 #define CS_PEERMODE     47
  184 #define CS_BCASTDELAY       48
  185 #define CS_AUTHDELAY        49
  186 #define CS_AUTHKEYS     50
  187 #define CS_AUTHFREEK        51
  188 #define CS_AUTHKLOOKUPS     52
  189 #define CS_AUTHKNOTFOUND    53
  190 #define CS_AUTHKUNCACHED    54
  191 #define CS_AUTHKEXPIRED     55
  192 #define CS_AUTHENCRYPTS     56
  193 #define CS_AUTHDECRYPTS     57
  194 #define CS_AUTHRESET        58
  195 #define CS_K_OFFSET     59
  196 #define CS_K_FREQ       60
  197 #define CS_K_MAXERR     61
  198 #define CS_K_ESTERR     62
  199 #define CS_K_STFLAGS        63
  200 #define CS_K_TIMECONST      64
  201 #define CS_K_PRECISION      65
  202 #define CS_K_FREQTOL        66
  203 #define CS_K_PPS_FREQ       67
  204 #define CS_K_PPS_STABIL     68
  205 #define CS_K_PPS_JITTER     69
  206 #define CS_K_PPS_CALIBDUR   70
  207 #define CS_K_PPS_CALIBS     71
  208 #define CS_K_PPS_CALIBERRS  72
  209 #define CS_K_PPS_JITEXC     73
  210 #define CS_K_PPS_STBEXC     74
  211 #define CS_KERN_FIRST       CS_K_OFFSET
  212 #define CS_KERN_LAST        CS_K_PPS_STBEXC
  213 #define CS_IOSTATS_RESET    75
  214 #define CS_TOTAL_RBUF       76
  215 #define CS_FREE_RBUF        77
  216 #define CS_USED_RBUF        78
  217 #define CS_RBUF_LOWATER     79
  218 #define CS_IO_DROPPED       80
  219 #define CS_IO_IGNORED       81
  220 #define CS_IO_RECEIVED      82
  221 #define CS_IO_SENT      83
  222 #define CS_IO_SENDFAILED    84
  223 #define CS_IO_WAKEUPS       85
  224 #define CS_IO_GOODWAKEUPS   86
  225 #define CS_TIMERSTATS_RESET 87
  226 #define CS_TIMER_OVERRUNS   88
  227 #define CS_TIMER_XMTS       89
  228 #define CS_FUZZ         90
  229 #define CS_WANDER_THRESH    91
  230 #define CS_LEAPSMEARINTV    92
  231 #define CS_LEAPSMEAROFFS    93
  232 #define CS_MAX_NOAUTOKEY    CS_LEAPSMEAROFFS
  233 #ifdef AUTOKEY
  234 #define CS_FLAGS        (1 + CS_MAX_NOAUTOKEY)
  235 #define CS_HOST         (2 + CS_MAX_NOAUTOKEY)
  236 #define CS_PUBLIC       (3 + CS_MAX_NOAUTOKEY)
  237 #define CS_CERTIF       (4 + CS_MAX_NOAUTOKEY)
  238 #define CS_SIGNATURE        (5 + CS_MAX_NOAUTOKEY)
  239 #define CS_REVTIME      (6 + CS_MAX_NOAUTOKEY)
  240 #define CS_IDENT        (7 + CS_MAX_NOAUTOKEY)
  241 #define CS_DIGEST       (8 + CS_MAX_NOAUTOKEY)
  242 #define CS_MAXCODE      CS_DIGEST
  243 #else   /* !AUTOKEY follows */
  244 #define CS_MAXCODE      CS_MAX_NOAUTOKEY
  245 #endif  /* !AUTOKEY */
  246 
  247 /*
  248  * Peer variables we understand
  249  */
  250 #define CP_CONFIG       1
  251 #define CP_AUTHENABLE       2
  252 #define CP_AUTHENTIC        3
  253 #define CP_SRCADR       4
  254 #define CP_SRCPORT      5
  255 #define CP_DSTADR       6
  256 #define CP_DSTPORT      7
  257 #define CP_LEAP         8
  258 #define CP_HMODE        9
  259 #define CP_STRATUM      10
  260 #define CP_PPOLL        11
  261 #define CP_HPOLL        12
  262 #define CP_PRECISION        13
  263 #define CP_ROOTDELAY        14
  264 #define CP_ROOTDISPERSION   15
  265 #define CP_REFID        16
  266 #define CP_REFTIME      17
  267 #define CP_ORG          18
  268 #define CP_REC          19
  269 #define CP_XMT          20
  270 #define CP_REACH        21
  271 #define CP_UNREACH      22
  272 #define CP_TIMER        23
  273 #define CP_DELAY        24
  274 #define CP_OFFSET       25
  275 #define CP_JITTER       26
  276 #define CP_DISPERSION       27
  277 #define CP_KEYID        28
  278 #define CP_FILTDELAY        29
  279 #define CP_FILTOFFSET       30
  280 #define CP_PMODE        31
  281 #define CP_RECEIVED     32
  282 #define CP_SENT         33
  283 #define CP_FILTERROR        34
  284 #define CP_FLASH        35
  285 #define CP_TTL          36
  286 #define CP_VARLIST      37
  287 #define CP_IN           38
  288 #define CP_OUT          39
  289 #define CP_RATE         40
  290 #define CP_BIAS         41
  291 #define CP_SRCHOST      42
  292 #define CP_TIMEREC      43
  293 #define CP_TIMEREACH        44
  294 #define CP_BADAUTH      45
  295 #define CP_BOGUSORG     46
  296 #define CP_OLDPKT       47
  297 #define CP_SELDISP      48
  298 #define CP_SELBROKEN        49
  299 #define CP_CANDIDATE        50
  300 #define CP_MAX_NOAUTOKEY    CP_CANDIDATE
  301 #ifdef AUTOKEY
  302 #define CP_FLAGS        (1 + CP_MAX_NOAUTOKEY)
  303 #define CP_HOST         (2 + CP_MAX_NOAUTOKEY)
  304 #define CP_VALID        (3 + CP_MAX_NOAUTOKEY)
  305 #define CP_INITSEQ      (4 + CP_MAX_NOAUTOKEY)
  306 #define CP_INITKEY      (5 + CP_MAX_NOAUTOKEY)
  307 #define CP_INITTSP      (6 + CP_MAX_NOAUTOKEY)
  308 #define CP_SIGNATURE        (7 + CP_MAX_NOAUTOKEY)
  309 #define CP_IDENT        (8 + CP_MAX_NOAUTOKEY)
  310 #define CP_MAXCODE      CP_IDENT
  311 #else   /* !AUTOKEY follows */
  312 #define CP_MAXCODE      CP_MAX_NOAUTOKEY
  313 #endif  /* !AUTOKEY */
  314 
  315 /*
  316  * Clock variables we understand
  317  */
  318 #define CC_TYPE     1
  319 #define CC_TIMECODE 2
  320 #define CC_POLL     3
  321 #define CC_NOREPLY  4
  322 #define CC_BADFORMAT    5
  323 #define CC_BADDATA  6
  324 #define CC_FUDGETIME1   7
  325 #define CC_FUDGETIME2   8
  326 #define CC_FUDGEVAL1    9
  327 #define CC_FUDGEVAL2    10
  328 #define CC_FLAGS    11
  329 #define CC_DEVICE   12
  330 #define CC_VARLIST  13
  331 #define CC_FUDGEMINJIT  14
  332 #define CC_MAXCODE  CC_FUDGEMINJIT
  333 
  334 /*
  335  * System variable values. The array can be indexed by the variable
  336  * index to find the textual name.
  337  */
  338 static const struct ctl_var sys_var[] = {
  339     { 0,        PADDING, "" },      /* 0 */
  340     { CS_LEAP,  RW, "leap" },       /* 1 */
  341     { CS_STRATUM,   RO, "stratum" },    /* 2 */
  342     { CS_PRECISION, RO, "precision" },  /* 3 */
  343     { CS_ROOTDELAY, RO, "rootdelay" },  /* 4 */
  344     { CS_ROOTDISPERSION, RO, "rootdisp" },  /* 5 */
  345     { CS_REFID, RO, "refid" },      /* 6 */
  346     { CS_REFTIME,   RO, "reftime" },    /* 7 */
  347     { CS_POLL,  RO, "tc" },     /* 8 */
  348     { CS_PEERID,    RO, "peer" },       /* 9 */
  349     { CS_OFFSET,    RO, "offset" },     /* 10 */
  350     { CS_DRIFT, RO, "frequency" },  /* 11 */
  351     { CS_JITTER,    RO, "sys_jitter" }, /* 12 */
  352     { CS_ERROR, RO, "clk_jitter" }, /* 13 */
  353     { CS_CLOCK, RO, "clock" },      /* 14 */
  354     { CS_PROCESSOR, RO, "processor" },  /* 15 */
  355     { CS_SYSTEM,    RO, "system" },     /* 16 */
  356     { CS_VERSION,   RO, "version" },    /* 17 */
  357     { CS_STABIL,    RO, "clk_wander" }, /* 18 */
  358     { CS_VARLIST,   RO, "sys_var_list" },   /* 19 */
  359     { CS_TAI,   RO, "tai" },        /* 20 */
  360     { CS_LEAPTAB,   RO, "leapsec" },    /* 21 */
  361     { CS_LEAPEND,   RO, "expire" },     /* 22 */
  362     { CS_RATE,  RO, "mintc" },      /* 23 */
  363     { CS_MRU_ENABLED,   RO, "mru_enabled" },    /* 24 */
  364     { CS_MRU_DEPTH,     RO, "mru_depth" },  /* 25 */
  365     { CS_MRU_DEEPEST,   RO, "mru_deepest" },    /* 26 */
  366     { CS_MRU_MINDEPTH,  RO, "mru_mindepth" },   /* 27 */
  367     { CS_MRU_MAXAGE,    RO, "mru_maxage" }, /* 28 */
  368     { CS_MRU_MAXDEPTH,  RO, "mru_maxdepth" },   /* 29 */
  369     { CS_MRU_MEM,       RO, "mru_mem" },    /* 30 */
  370     { CS_MRU_MAXMEM,    RO, "mru_maxmem" }, /* 31 */
  371     { CS_SS_UPTIME,     RO, "ss_uptime" },  /* 32 */
  372     { CS_SS_RESET,      RO, "ss_reset" },   /* 33 */
  373     { CS_SS_RECEIVED,   RO, "ss_received" },    /* 34 */
  374     { CS_SS_THISVER,    RO, "ss_thisver" }, /* 35 */
  375     { CS_SS_OLDVER,     RO, "ss_oldver" },  /* 36 */
  376     { CS_SS_BADFORMAT,  RO, "ss_badformat" },   /* 37 */
  377     { CS_SS_BADAUTH,    RO, "ss_badauth" }, /* 38 */
  378     { CS_SS_DECLINED,   RO, "ss_declined" },    /* 39 */
  379     { CS_SS_RESTRICTED, RO, "ss_restricted" },  /* 40 */
  380     { CS_SS_LIMITED,    RO, "ss_limited" }, /* 41 */
  381     { CS_SS_KODSENT,    RO, "ss_kodsent" }, /* 42 */
  382     { CS_SS_PROCESSED,  RO, "ss_processed" },   /* 43 */
  383     { CS_SS_LAMPORT,    RO, "ss_lamport" }, /* 44 */
  384     { CS_SS_TSROUNDING, RO, "ss_tsrounding" },  /* 45 */
  385     { CS_PEERADR,       RO, "peeradr" },    /* 46 */
  386     { CS_PEERMODE,      RO, "peermode" },   /* 47 */
  387     { CS_BCASTDELAY,    RO, "bcastdelay" }, /* 48 */
  388     { CS_AUTHDELAY,     RO, "authdelay" },  /* 49 */
  389     { CS_AUTHKEYS,      RO, "authkeys" },   /* 50 */
  390     { CS_AUTHFREEK,     RO, "authfreek" },  /* 51 */
  391     { CS_AUTHKLOOKUPS,  RO, "authklookups" },   /* 52 */
  392     { CS_AUTHKNOTFOUND, RO, "authknotfound" },  /* 53 */
  393     { CS_AUTHKUNCACHED, RO, "authkuncached" },  /* 54 */
  394     { CS_AUTHKEXPIRED,  RO, "authkexpired" },   /* 55 */
  395     { CS_AUTHENCRYPTS,  RO, "authencrypts" },   /* 56 */
  396     { CS_AUTHDECRYPTS,  RO, "authdecrypts" },   /* 57 */
  397     { CS_AUTHRESET,     RO, "authreset" },  /* 58 */
  398     { CS_K_OFFSET,      RO, "koffset" },    /* 59 */
  399     { CS_K_FREQ,        RO, "kfreq" },      /* 60 */
  400     { CS_K_MAXERR,      RO, "kmaxerr" },    /* 61 */
  401     { CS_K_ESTERR,      RO, "kesterr" },    /* 62 */
  402     { CS_K_STFLAGS,     RO, "kstflags" },   /* 63 */
  403     { CS_K_TIMECONST,   RO, "ktimeconst" }, /* 64 */
  404     { CS_K_PRECISION,   RO, "kprecis" },    /* 65 */
  405     { CS_K_FREQTOL,     RO, "kfreqtol" },   /* 66 */
  406     { CS_K_PPS_FREQ,    RO, "kppsfreq" },   /* 67 */
  407     { CS_K_PPS_STABIL,  RO, "kppsstab" },   /* 68 */
  408     { CS_K_PPS_JITTER,  RO, "kppsjitter" }, /* 69 */
  409     { CS_K_PPS_CALIBDUR,    RO, "kppscalibdur" },   /* 70 */
  410     { CS_K_PPS_CALIBS,  RO, "kppscalibs" }, /* 71 */
  411     { CS_K_PPS_CALIBERRS,   RO, "kppscaliberrs" },  /* 72 */
  412     { CS_K_PPS_JITEXC,  RO, "kppsjitexc" }, /* 73 */
  413     { CS_K_PPS_STBEXC,  RO, "kppsstbexc" }, /* 74 */
  414     { CS_IOSTATS_RESET, RO, "iostats_reset" },  /* 75 */
  415     { CS_TOTAL_RBUF,    RO, "total_rbuf" }, /* 76 */
  416     { CS_FREE_RBUF,     RO, "free_rbuf" },  /* 77 */
  417     { CS_USED_RBUF,     RO, "used_rbuf" },  /* 78 */
  418     { CS_RBUF_LOWATER,  RO, "rbuf_lowater" },   /* 79 */
  419     { CS_IO_DROPPED,    RO, "io_dropped" }, /* 80 */
  420     { CS_IO_IGNORED,    RO, "io_ignored" }, /* 81 */
  421     { CS_IO_RECEIVED,   RO, "io_received" },    /* 82 */
  422     { CS_IO_SENT,       RO, "io_sent" },    /* 83 */
  423     { CS_IO_SENDFAILED, RO, "io_sendfailed" },  /* 84 */
  424     { CS_IO_WAKEUPS,    RO, "io_wakeups" }, /* 85 */
  425     { CS_IO_GOODWAKEUPS,    RO, "io_goodwakeups" }, /* 86 */
  426     { CS_TIMERSTATS_RESET,  RO, "timerstats_reset" },/* 87 */
  427     { CS_TIMER_OVERRUNS,    RO, "timer_overruns" }, /* 88 */
  428     { CS_TIMER_XMTS,    RO, "timer_xmts" }, /* 89 */
  429     { CS_FUZZ,      RO, "fuzz" },       /* 90 */
  430     { CS_WANDER_THRESH, RO, "clk_wander_threshold" }, /* 91 */
  431 
  432     { CS_LEAPSMEARINTV, RO, "leapsmearinterval" },    /* 92 */
  433     { CS_LEAPSMEAROFFS, RO, "leapsmearoffset" },      /* 93 */
  434 
  435 #ifdef AUTOKEY
  436     { CS_FLAGS, RO, "flags" },      /* 1 + CS_MAX_NOAUTOKEY */
  437     { CS_HOST,  RO, "host" },       /* 2 + CS_MAX_NOAUTOKEY */
  438     { CS_PUBLIC,    RO, "update" },     /* 3 + CS_MAX_NOAUTOKEY */
  439     { CS_CERTIF,    RO, "cert" },       /* 4 + CS_MAX_NOAUTOKEY */
  440     { CS_SIGNATURE, RO, "signature" },  /* 5 + CS_MAX_NOAUTOKEY */
  441     { CS_REVTIME,   RO, "until" },      /* 6 + CS_MAX_NOAUTOKEY */
  442     { CS_IDENT, RO, "ident" },      /* 7 + CS_MAX_NOAUTOKEY */
  443     { CS_DIGEST,    RO, "digest" },     /* 8 + CS_MAX_NOAUTOKEY */
  444 #endif  /* AUTOKEY */
  445     { 0,        EOV, "" }       /* 94/102 */
  446 };
  447 
  448 static struct ctl_var *ext_sys_var = NULL;
  449 
  450 /*
  451  * System variables we print by default (in fuzzball order,
  452  * more-or-less)
  453  */
  454 static const u_char def_sys_var[] = {
  455     CS_VERSION,
  456     CS_PROCESSOR,
  457     CS_SYSTEM,
  458     CS_LEAP,
  459     CS_STRATUM,
  460     CS_PRECISION,
  461     CS_ROOTDELAY,
  462     CS_ROOTDISPERSION,
  463     CS_REFID,
  464     CS_REFTIME,
  465     CS_CLOCK,
  466     CS_PEERID,
  467     CS_POLL,
  468     CS_RATE,
  469     CS_OFFSET,
  470     CS_DRIFT,
  471     CS_JITTER,
  472     CS_ERROR,
  473     CS_STABIL,
  474     CS_TAI,
  475     CS_LEAPTAB,
  476     CS_LEAPEND,
  477     CS_LEAPSMEARINTV,
  478     CS_LEAPSMEAROFFS,
  479 #ifdef AUTOKEY
  480     CS_HOST,
  481     CS_IDENT,
  482     CS_FLAGS,
  483     CS_DIGEST,
  484     CS_SIGNATURE,
  485     CS_PUBLIC,
  486     CS_CERTIF,
  487 #endif  /* AUTOKEY */
  488     0
  489 };
  490 
  491 
  492 /*
  493  * Peer variable list
  494  */
  495 static const struct ctl_var peer_var[] = {
  496     { 0,        PADDING, "" },      /* 0 */
  497     { CP_CONFIG,    RO, "config" },     /* 1 */
  498     { CP_AUTHENABLE, RO,    "authenable" }, /* 2 */
  499     { CP_AUTHENTIC, RO, "authentic" },  /* 3 */
  500     { CP_SRCADR,    RO, "srcadr" },     /* 4 */
  501     { CP_SRCPORT,   RO, "srcport" },    /* 5 */
  502     { CP_DSTADR,    RO, "dstadr" },     /* 6 */
  503     { CP_DSTPORT,   RO, "dstport" },    /* 7 */
  504     { CP_LEAP,  RO, "leap" },       /* 8 */
  505     { CP_HMODE, RO, "hmode" },      /* 9 */
  506     { CP_STRATUM,   RO, "stratum" },    /* 10 */
  507     { CP_PPOLL, RO, "ppoll" },      /* 11 */
  508     { CP_HPOLL, RO, "hpoll" },      /* 12 */
  509     { CP_PRECISION, RO, "precision" },  /* 13 */
  510     { CP_ROOTDELAY, RO, "rootdelay" },  /* 14 */
  511     { CP_ROOTDISPERSION, RO, "rootdisp" },  /* 15 */
  512     { CP_REFID, RO, "refid" },      /* 16 */
  513     { CP_REFTIME,   RO, "reftime" },    /* 17 */
  514     { CP_ORG,   RO, "org" },        /* 18 */
  515     { CP_REC,   RO, "rec" },        /* 19 */
  516     { CP_XMT,   RO, "xleave" },     /* 20 */
  517     { CP_REACH, RO, "reach" },      /* 21 */
  518     { CP_UNREACH,   RO, "unreach" },    /* 22 */
  519     { CP_TIMER, RO, "timer" },      /* 23 */
  520     { CP_DELAY, RO, "delay" },      /* 24 */
  521     { CP_OFFSET,    RO, "offset" },     /* 25 */
  522     { CP_JITTER,    RO, "jitter" },     /* 26 */
  523     { CP_DISPERSION, RO, "dispersion" },    /* 27 */
  524     { CP_KEYID, RO, "keyid" },      /* 28 */
  525     { CP_FILTDELAY, RO, "filtdelay" },  /* 29 */
  526     { CP_FILTOFFSET, RO, "filtoffset" },    /* 30 */
  527     { CP_PMODE, RO, "pmode" },      /* 31 */
  528     { CP_RECEIVED,  RO, "received"},    /* 32 */
  529     { CP_SENT,  RO, "sent" },       /* 33 */
  530     { CP_FILTERROR, RO, "filtdisp" },   /* 34 */
  531     { CP_FLASH, RO, "flash" },      /* 35 */
  532     { CP_TTL,   RO, "ttl" },        /* 36 */
  533     { CP_VARLIST,   RO, "peer_var_list" },  /* 37 */
  534     { CP_IN,    RO, "in" },     /* 38 */
  535     { CP_OUT,   RO, "out" },        /* 39 */
  536     { CP_RATE,  RO, "headway" },    /* 40 */
  537     { CP_BIAS,  RO, "bias" },       /* 41 */
  538     { CP_SRCHOST,   RO, "srchost" },    /* 42 */
  539     { CP_TIMEREC,   RO, "timerec" },    /* 43 */
  540     { CP_TIMEREACH, RO, "timereach" },  /* 44 */
  541     { CP_BADAUTH,   RO, "badauth" },    /* 45 */
  542     { CP_BOGUSORG,  RO, "bogusorg" },   /* 46 */
  543     { CP_OLDPKT,    RO, "oldpkt" },     /* 47 */
  544     { CP_SELDISP,   RO, "seldisp" },    /* 48 */
  545     { CP_SELBROKEN, RO, "selbroken" },  /* 49 */
  546     { CP_CANDIDATE, RO, "candidate" },  /* 50 */
  547 #ifdef AUTOKEY
  548     { CP_FLAGS, RO, "flags" },      /* 1 + CP_MAX_NOAUTOKEY */
  549     { CP_HOST,  RO, "host" },       /* 2 + CP_MAX_NOAUTOKEY */
  550     { CP_VALID, RO, "valid" },      /* 3 + CP_MAX_NOAUTOKEY */
  551     { CP_INITSEQ,   RO, "initsequence" },   /* 4 + CP_MAX_NOAUTOKEY */
  552     { CP_INITKEY,   RO, "initkey" },    /* 5 + CP_MAX_NOAUTOKEY */
  553     { CP_INITTSP,   RO, "timestamp" },  /* 6 + CP_MAX_NOAUTOKEY */
  554     { CP_SIGNATURE, RO, "signature" },  /* 7 + CP_MAX_NOAUTOKEY */
  555     { CP_IDENT, RO, "ident" },      /* 8 + CP_MAX_NOAUTOKEY */
  556 #endif  /* AUTOKEY */
  557     { 0,        EOV, "" }       /* 50/58 */
  558 };
  559 
  560 
  561 /*
  562  * Peer variables we print by default
  563  */
  564 static const u_char def_peer_var[] = {
  565     CP_SRCADR,
  566     CP_SRCPORT,
  567     CP_SRCHOST,
  568     CP_DSTADR,
  569     CP_DSTPORT,
  570     CP_OUT,
  571     CP_IN,
  572     CP_LEAP,
  573     CP_STRATUM,
  574     CP_PRECISION,
  575     CP_ROOTDELAY,
  576     CP_ROOTDISPERSION,
  577     CP_REFID,
  578     CP_REFTIME,
  579     CP_REC,
  580     CP_REACH,
  581     CP_UNREACH,
  582     CP_HMODE,
  583     CP_PMODE,
  584     CP_HPOLL,
  585     CP_PPOLL,
  586     CP_RATE,
  587     CP_FLASH,
  588     CP_KEYID,
  589     CP_TTL,
  590     CP_OFFSET,
  591     CP_DELAY,
  592     CP_DISPERSION,
  593     CP_JITTER,
  594     CP_XMT,
  595     CP_BIAS,
  596     CP_FILTDELAY,
  597     CP_FILTOFFSET,
  598     CP_FILTERROR,
  599 #ifdef AUTOKEY
  600     CP_HOST,
  601     CP_FLAGS,
  602     CP_SIGNATURE,
  603     CP_VALID,
  604     CP_INITSEQ,
  605     CP_IDENT,
  606 #endif  /* AUTOKEY */
  607     0
  608 };
  609 
  610 
  611 #ifdef REFCLOCK
  612 /*
  613  * Clock variable list
  614  */
  615 static const struct ctl_var clock_var[] = {
  616     { 0,        PADDING, "" },      /* 0 */
  617     { CC_TYPE,  RO, "type" },       /* 1 */
  618     { CC_TIMECODE,  RO, "timecode" },   /* 2 */
  619     { CC_POLL,  RO, "poll" },       /* 3 */
  620     { CC_NOREPLY,   RO, "noreply" },    /* 4 */
  621     { CC_BADFORMAT, RO, "badformat" },  /* 5 */
  622     { CC_BADDATA,   RO, "baddata" },    /* 6 */
  623     { CC_FUDGETIME1, RO, "fudgetime1" },    /* 7 */
  624     { CC_FUDGETIME2, RO, "fudgetime2" },    /* 8 */
  625     { CC_FUDGEVAL1, RO, "stratum" },    /* 9 */
  626     { CC_FUDGEVAL2, RO, "refid" },      /* 10 */
  627     { CC_FLAGS, RO, "flags" },      /* 11 */
  628     { CC_DEVICE,    RO, "device" },     /* 12 */
  629     { CC_VARLIST,   RO, "clock_var_list" }, /* 13 */
  630     { CC_FUDGEMINJIT, RO, "minjitter" },    /* 14 */
  631     { 0,        EOV, ""  }      /* 15 */
  632 };
  633 
  634 
  635 /*
  636  * Clock variables printed by default
  637  */
  638 static const u_char def_clock_var[] = {
  639     CC_DEVICE,
  640     CC_TYPE,    /* won't be output if device = known */
  641     CC_TIMECODE,
  642     CC_POLL,
  643     CC_NOREPLY,
  644     CC_BADFORMAT,
  645     CC_BADDATA,
  646     CC_FUDGEMINJIT,
  647     CC_FUDGETIME1,
  648     CC_FUDGETIME2,
  649     CC_FUDGEVAL1,
  650     CC_FUDGEVAL2,
  651     CC_FLAGS,
  652     0
  653 };
  654 #endif
  655 
  656 /*
  657  * MRU string constants shared by send_mru_entry() and read_mru_list().
  658  */
  659 static const char addr_fmt[] =      "addr.%d";
  660 static const char last_fmt[] =      "last.%d";
  661 
  662 /*
  663  * System and processor definitions.
  664  */
  665 #ifndef HAVE_UNAME
  666 # ifndef STR_SYSTEM
  667 #  define       STR_SYSTEM  "UNIX"
  668 # endif
  669 # ifndef STR_PROCESSOR
  670 #  define       STR_PROCESSOR   "unknown"
  671 # endif
  672 
  673 static const char str_system[] = STR_SYSTEM;
  674 static const char str_processor[] = STR_PROCESSOR;
  675 #else
  676 # include <sys/utsname.h>
  677 static struct utsname utsnamebuf;
  678 #endif /* HAVE_UNAME */
  679 
  680 /*
  681  * Trap structures. We only allow a few of these, and send a copy of
  682  * each async message to each live one. Traps time out after an hour, it
  683  * is up to the trap receipient to keep resetting it to avoid being
  684  * timed out.
  685  */
  686 /* ntp_request.c */
  687 struct ctl_trap ctl_traps[CTL_MAXTRAPS];
  688 int num_ctl_traps;
  689 
  690 /*
  691  * Type bits, for ctlsettrap() call.
  692  */
  693 #define TRAP_TYPE_CONFIG    0   /* used by configuration code */
  694 #define TRAP_TYPE_PRIO      1   /* priority trap */
  695 #define TRAP_TYPE_NONPRIO   2   /* nonpriority trap */
  696 
  697 
  698 /*
  699  * List relating reference clock types to control message time sources.
  700  * Index by the reference clock type. This list will only be used iff
  701  * the reference clock driver doesn't set peer->sstclktype to something
  702  * different than CTL_SST_TS_UNSPEC.
  703  */
  704 #ifdef REFCLOCK
  705 static const u_char clocktypes[] = {
  706     CTL_SST_TS_NTP,     /* REFCLK_NONE (0) */
  707     CTL_SST_TS_LOCAL,   /* REFCLK_LOCALCLOCK (1) */
  708     CTL_SST_TS_UHF,     /* deprecated REFCLK_GPS_TRAK (2) */
  709     CTL_SST_TS_HF,      /* REFCLK_WWV_PST (3) */
  710     CTL_SST_TS_LF,      /* REFCLK_WWVB_SPECTRACOM (4) */
  711     CTL_SST_TS_UHF,     /* REFCLK_TRUETIME (5) */
  712     CTL_SST_TS_UHF,     /* REFCLK_IRIG_AUDIO (6) */
  713     CTL_SST_TS_HF,      /* REFCLK_CHU (7) */
  714     CTL_SST_TS_LF,      /* REFCLOCK_PARSE (default) (8) */
  715     CTL_SST_TS_LF,      /* REFCLK_GPS_MX4200 (9) */
  716     CTL_SST_TS_UHF,     /* REFCLK_GPS_AS2201 (10) */
  717     CTL_SST_TS_UHF,     /* REFCLK_GPS_ARBITER (11) */
  718     CTL_SST_TS_UHF,     /* REFCLK_IRIG_TPRO (12) */
  719     CTL_SST_TS_ATOM,    /* REFCLK_ATOM_LEITCH (13) */
  720     CTL_SST_TS_LF,      /* deprecated REFCLK_MSF_EES (14) */
  721     CTL_SST_TS_NTP,     /* not used (15) */
  722     CTL_SST_TS_UHF,     /* REFCLK_IRIG_BANCOMM (16) */
  723     CTL_SST_TS_UHF,     /* REFCLK_GPS_DATU (17) */
  724     CTL_SST_TS_TELEPHONE,   /* REFCLK_NIST_ACTS (18) */
  725     CTL_SST_TS_HF,      /* REFCLK_WWV_HEATH (19) */
  726     CTL_SST_TS_UHF,     /* REFCLK_GPS_NMEA (20) */
  727     CTL_SST_TS_UHF,     /* REFCLK_GPS_VME (21) */
  728     CTL_SST_TS_ATOM,    /* REFCLK_ATOM_PPS (22) */
  729     CTL_SST_TS_NTP,     /* not used (23) */
  730     CTL_SST_TS_NTP,     /* not used (24) */
  731     CTL_SST_TS_NTP,     /* not used (25) */
  732     CTL_SST_TS_UHF,     /* REFCLK_GPS_HP (26) */
  733     CTL_SST_TS_LF,      /* REFCLK_ARCRON_MSF (27) */
  734     CTL_SST_TS_UHF,     /* REFCLK_SHM (28) */
  735     CTL_SST_TS_UHF,     /* REFCLK_PALISADE (29) */
  736     CTL_SST_TS_UHF,     /* REFCLK_ONCORE (30) */
  737     CTL_SST_TS_UHF,     /* REFCLK_JUPITER (31) */
  738     CTL_SST_TS_LF,      /* REFCLK_CHRONOLOG (32) */
  739     CTL_SST_TS_LF,      /* REFCLK_DUMBCLOCK (33) */
  740     CTL_SST_TS_LF,      /* REFCLK_ULINK (34) */
  741     CTL_SST_TS_LF,      /* REFCLK_PCF (35) */
  742     CTL_SST_TS_HF,      /* REFCLK_WWV (36) */
  743     CTL_SST_TS_LF,      /* REFCLK_FG (37) */
  744     CTL_SST_TS_UHF,     /* REFCLK_HOPF_SERIAL (38) */
  745     CTL_SST_TS_UHF,     /* REFCLK_HOPF_PCI (39) */
  746     CTL_SST_TS_LF,      /* REFCLK_JJY (40) */
  747     CTL_SST_TS_UHF,     /* REFCLK_TT560 (41) */
  748     CTL_SST_TS_UHF,     /* REFCLK_ZYFER (42) */
  749     CTL_SST_TS_UHF,     /* REFCLK_RIPENCC (43) */
  750     CTL_SST_TS_UHF,     /* REFCLK_NEOCLOCK4X (44) */
  751     CTL_SST_TS_UHF,     /* REFCLK_TSYNCPCI (45) */
  752     CTL_SST_TS_UHF      /* REFCLK_GPSDJSON (46) */
  753 };
  754 #endif  /* REFCLOCK */
  755 
  756 
  757 /*
  758  * Keyid used for authenticating write requests.
  759  */
  760 keyid_t ctl_auth_keyid;
  761 
  762 /*
  763  * We keep track of the last error reported by the system internally
  764  */
  765 static  u_char ctl_sys_last_event;
  766 static  u_char ctl_sys_num_events;
  767 
  768 
  769 /*
  770  * Statistic counters to keep track of requests and responses.
  771  */
  772 u_long ctltimereset;        /* time stats reset */
  773 u_long numctlreq;       /* number of requests we've received */
  774 u_long numctlbadpkts;       /* number of bad control packets */
  775 u_long numctlresponses;     /* number of resp packets sent with data */
  776 u_long numctlfrags;     /* number of fragments sent */
  777 u_long numctlerrors;        /* number of error responses sent */
  778 u_long numctltooshort;      /* number of too short input packets */
  779 u_long numctlinputresp;     /* number of responses on input */
  780 u_long numctlinputfrag;     /* number of fragments on input */
  781 u_long numctlinputerr;      /* number of input pkts with err bit set */
  782 u_long numctlbadoffset;     /* number of input pkts with nonzero offset */
  783 u_long numctlbadversion;    /* number of input pkts with unknown version */
  784 u_long numctldatatooshort;  /* data too short for count */
  785 u_long numctlbadop;     /* bad op code found in packet */
  786 u_long numasyncmsgs;        /* number of async messages we've sent */
  787 
  788 /*
  789  * Response packet used by these routines. Also some state information
  790  * so that we can handle packet formatting within a common set of
  791  * subroutines.  Note we try to enter data in place whenever possible,
  792  * but the need to set the more bit correctly means we occasionally
  793  * use the extra buffer and copy.
  794  */
  795 static struct ntp_control rpkt;
  796 static u_char   res_version;
  797 static u_char   res_opcode;
  798 static associd_t res_associd;
  799 static u_short  res_frags;  /* datagrams in this response */
  800 static int  res_offset; /* offset of payload in response */
  801 static u_char * datapt;
  802 static u_char * dataend;
  803 static int  datalinelen;
  804 static int  datasent;   /* flag to avoid initial ", " */
  805 static int  datanotbinflag;
  806 static sockaddr_u *rmt_addr;
  807 static struct interface *lcl_inter;
  808 
  809 static u_char   res_authenticate;
  810 static u_char   res_authokay;
  811 static keyid_t  res_keyid;
  812 
  813 #define MAXDATALINELEN  (72)
  814 
  815 static u_char   res_async;  /* sending async trap response? */
  816 
  817 /*
  818  * Pointers for saving state when decoding request packets
  819  */
  820 static  char *reqpt;
  821 static  char *reqend;
  822 
  823 /*
  824  * init_control - initialize request data
  825  */
  826 void
  827 init_control(void)
  828 {
  829     size_t i;
  830 
  831 #ifdef HAVE_UNAME
  832     uname(&utsnamebuf);
  833 #endif /* HAVE_UNAME */
  834 
  835     ctl_clr_stats();
  836 
  837     ctl_auth_keyid = 0;
  838     ctl_sys_last_event = EVNT_UNSPEC;
  839     ctl_sys_num_events = 0;
  840 
  841     num_ctl_traps = 0;
  842     for (i = 0; i < COUNTOF(ctl_traps); i++)
  843         ctl_traps[i].tr_flags = 0;
  844 }
  845 
  846 
  847 /*
  848  * ctl_error - send an error response for the current request
  849  */
  850 static void
  851 ctl_error(
  852     u_char errcode
  853     )
  854 {
  855     size_t      maclen;
  856 
  857     numctlerrors++;
  858     DPRINTF(3, ("sending control error %u\n", errcode));
  859 
  860     /*
  861      * Fill in the fields. We assume rpkt.sequence and rpkt.associd
  862      * have already been filled in.
  863      */
  864     rpkt.r_m_e_op = (u_char)CTL_RESPONSE | CTL_ERROR |
  865             (res_opcode & CTL_OP_MASK);
  866     rpkt.status = htons((u_short)(errcode << 8) & 0xff00);
  867     rpkt.count = 0;
  868 
  869     /*
  870      * send packet and bump counters
  871      */
  872     if (res_authenticate && sys_authenticate) {
  873         maclen = authencrypt(res_keyid, (u_int32 *)&rpkt,
  874                      CTL_HEADER_LEN);
  875         sendpkt(rmt_addr, lcl_inter, -2, (void *)&rpkt,
  876             CTL_HEADER_LEN + maclen);
  877     } else
  878         sendpkt(rmt_addr, lcl_inter, -3, (void *)&rpkt,
  879             CTL_HEADER_LEN);
  880 }
  881 
  882 int/*BOOL*/
  883 is_safe_filename(const char * name)
  884 {
  885     /* We need a strict validation of filenames we should write: The
  886      * daemon might run with special permissions and is remote
  887      * controllable, so we better take care what we allow as file
  888      * name!
  889      *
  890      * The first character must be digit or a letter from the ASCII
  891      * base plane or a '_' ([_A-Za-z0-9]), the following characters
  892      * must be from [-._+A-Za-z0-9].
  893      *
  894      * We do not trust the character classification much here: Since
  895      * the NTP protocol makes no provisions for UTF-8 or local code
  896      * pages, we strictly require the 7bit ASCII code page.
  897      *
  898      * The following table is a packed bit field of 128 two-bit
  899      * groups. The LSB in each group tells us if a character is
  900      * acceptable at the first position, the MSB if the character is
  901      * accepted at any other position.
  902      *
  903      * This does not ensure that the file name is syntactically
  904      * correct (multiple dots will not work with VMS...) but it will
  905      * exclude potential globbing bombs and directory traversal. It
  906      * also rules out drive selection. (For systems that have this
  907      * notion, like Windows or VMS.)
  908      */
  909     static const uint32_t chclass[8] = {
  910         0x00000000, 0x00000000,
  911         0x28800000, 0x000FFFFF,
  912         0xFFFFFFFC, 0xC03FFFFF,
  913         0xFFFFFFFC, 0x003FFFFF
  914     };
  915 
  916     u_int widx, bidx, mask;
  917     if ( ! (name && *name))
  918         return FALSE;
  919 
  920     mask = 1u;
  921     while (0 != (widx = (u_char)*name++)) {
  922         bidx = (widx & 15) << 1;
  923         widx = widx >> 4;
  924         if (widx >= sizeof(chclass)/sizeof(chclass[0]))
  925             return FALSE;
  926         if (0 == ((chclass[widx] >> bidx) & mask))
  927             return FALSE;
  928         mask = 2u;
  929     }
  930     return TRUE;
  931 }
  932 
  933 
  934 /*
  935  * save_config - Implements ntpq -c "saveconfig <filename>"
  936  *       Writes current configuration including any runtime
  937  *       changes by ntpq's :config or config-from-file
  938  *
  939  * Note: There should be no buffer overflow or truncation in the
  940  * processing of file names -- both cause security problems. This is bit
  941  * painful to code but essential here.
  942  */
  943 void
  944 save_config(
  945     struct recvbuf *rbufp,
  946     int restrict_mask
  947     )
  948 {
  949     /* block directory traversal by searching for characters that
  950      * indicate directory components in a file path.
  951      *
  952      * Conceptually we should be searching for DIRSEP in filename,
  953      * however Windows actually recognizes both forward and
  954      * backslashes as equivalent directory separators at the API
  955      * level.  On POSIX systems we could allow '\\' but such
  956      * filenames are tricky to manipulate from a shell, so just
  957      * reject both types of slashes on all platforms.
  958      */
  959     /* TALOS-CAN-0062: block directory traversal for VMS, too */
  960     static const char * illegal_in_filename =
  961 #if defined(VMS)
  962         ":[]"   /* do not allow drive and path components here */
  963 #elif defined(SYS_WINNT)
  964         ":\\/"  /* path and drive separators */
  965 #else
  966         "\\/"   /* separator and critical char for POSIX */
  967 #endif
  968         ;
  969     char reply[128];
  970 #ifdef SAVECONFIG
  971     static const char savedconfig_eq[] = "savedconfig=";
  972 
  973     /* Build a safe open mode from the available mode flags. We want
  974      * to create a new file and write it in text mode (when
  975      * applicable -- only Windows does this...)
  976      */
  977     static const int openmode = O_CREAT | O_TRUNC | O_WRONLY
  978 #  if defined(O_EXCL)       /* posix, vms */
  979         | O_EXCL
  980 #  elif defined(_O_EXCL)    /* windows is alway very special... */
  981         | _O_EXCL
  982 #  endif
  983 #  if defined(_O_TEXT)      /* windows, again */
  984         | _O_TEXT
  985 #endif
  986         ;
  987 
  988     char filespec[128];
  989     char filename[128];
  990     char fullpath[512];
  991     char savedconfig[sizeof(savedconfig_eq) + sizeof(filename)];
  992     time_t now;
  993     int fd;
  994     FILE *fptr;
  995     int prc;
  996     size_t reqlen;
  997 #endif
  998 
  999     if (RES_NOMODIFY & restrict_mask) {
 1000         ctl_printf("%s", "saveconfig prohibited by restrict ... nomodify");
 1001         ctl_flushpkt(0);
 1002         NLOG(NLOG_SYSINFO)
 1003             msyslog(LOG_NOTICE,
 1004                 "saveconfig from %s rejected due to nomodify restriction",
 1005                 stoa(&rbufp->recv_srcadr));
 1006         sys_restricted++;
 1007         return;
 1008     }
 1009 
 1010 #ifdef SAVECONFIG
 1011     if (NULL == saveconfigdir) {
 1012         ctl_printf("%s", "saveconfig prohibited, no saveconfigdir configured");
 1013         ctl_flushpkt(0);
 1014         NLOG(NLOG_SYSINFO)
 1015             msyslog(LOG_NOTICE,
 1016                 "saveconfig from %s rejected, no saveconfigdir",
 1017                 stoa(&rbufp->recv_srcadr));
 1018         return;
 1019     }
 1020 
 1021     /* The length checking stuff gets serious. Do not assume a NUL
 1022      * byte can be found, but if so, use it to calculate the needed
 1023      * buffer size. If the available buffer is too short, bail out;
 1024      * likewise if there is no file spec. (The latter will not
 1025      * happen when using NTPQ, but there are other ways to craft a
 1026      * network packet!)
 1027      */
 1028     reqlen = (size_t)(reqend - reqpt);
 1029     if (0 != reqlen) {
 1030         char * nulpos = (char*)memchr(reqpt, 0, reqlen);
 1031         if (NULL != nulpos)
 1032             reqlen = (size_t)(nulpos - reqpt);
 1033     }
 1034     if (0 == reqlen)
 1035         return;
 1036     if (reqlen >= sizeof(filespec)) {
 1037         ctl_printf("saveconfig exceeded maximum raw name length (%u)",
 1038                (u_int)sizeof(filespec));
 1039         ctl_flushpkt(0);
 1040         msyslog(LOG_NOTICE,
 1041             "saveconfig exceeded maximum raw name length from %s",
 1042             stoa(&rbufp->recv_srcadr));
 1043         return;
 1044     }
 1045 
 1046     /* copy data directly as we exactly know the size */
 1047     memcpy(filespec, reqpt, reqlen);
 1048     filespec[reqlen] = '\0';
 1049 
 1050     /*
 1051      * allow timestamping of the saved config filename with
 1052      * strftime() format such as:
 1053      *   ntpq -c "saveconfig ntp-%Y%m%d-%H%M%S.conf"
 1054      * XXX: Nice feature, but not too safe.
 1055      * YYY: The check for permitted characters in file names should
 1056      *      weed out the worst. Let's hope 'strftime()' does not
 1057      *      develop pathological problems.
 1058      */
 1059     time(&now);
 1060     if (0 == strftime(filename, sizeof(filename), filespec,
 1061               localtime(&now)))
 1062     {
 1063         /*
 1064          * If we arrive here, 'strftime()' balked; most likely
 1065          * the buffer was too short. (Or it encounterd an empty
 1066          * format, or just a format that expands to an empty
 1067          * string.) We try to use the original name, though this
 1068          * is very likely to fail later if there are format
 1069          * specs in the string. Note that truncation cannot
 1070          * happen here as long as both buffers have the same
 1071          * size!
 1072          */
 1073         strlcpy(filename, filespec, sizeof(filename));
 1074     }
 1075 
 1076     /*
 1077      * Check the file name for sanity. This might/will rule out file
 1078      * names that would be legal but problematic, and it blocks
 1079      * directory traversal.
 1080      */
 1081     if (!is_safe_filename(filename)) {
 1082         ctl_printf("saveconfig rejects unsafe file name '%s'",
 1083                filename);
 1084         ctl_flushpkt(0);
 1085         msyslog(LOG_NOTICE,
 1086             "saveconfig rejects unsafe file name from %s",
 1087             stoa(&rbufp->recv_srcadr));
 1088         return;
 1089     }
 1090 
 1091     /*
 1092      * XXX: This next test may not be needed with is_safe_filename()
 1093      */
 1094 
 1095     /* block directory/drive traversal */
 1096     /* TALOS-CAN-0062: block directory traversal for VMS, too */
 1097     if (NULL != strpbrk(filename, illegal_in_filename)) {
 1098         snprintf(reply, sizeof(reply),
 1099              "saveconfig does not allow directory in filename");
 1100         ctl_putdata(reply, strlen(reply), 0);
 1101         ctl_flushpkt(0);
 1102         msyslog(LOG_NOTICE,
 1103             "saveconfig rejects unsafe file name from %s",
 1104             stoa(&rbufp->recv_srcadr));
 1105         return;
 1106     }
 1107 
 1108     /* concatenation of directory and path can cause another
 1109      * truncation...
 1110      */
 1111     prc = snprintf(fullpath, sizeof(fullpath), "%s%s",
 1112                saveconfigdir, filename);
 1113     if (prc < 0 || (size_t)prc >= sizeof(fullpath)) {
 1114         ctl_printf("saveconfig exceeded maximum path length (%u)",
 1115                (u_int)sizeof(fullpath));
 1116         ctl_flushpkt(0);
 1117         msyslog(LOG_NOTICE,
 1118             "saveconfig exceeded maximum path length from %s",
 1119             stoa(&rbufp->recv_srcadr));
 1120         return;
 1121     }
 1122 
 1123     fd = open(fullpath, openmode, S_IRUSR | S_IWUSR);
 1124     if (-1 == fd)
 1125         fptr = NULL;
 1126     else
 1127         fptr = fdopen(fd, "w");
 1128 
 1129     if (NULL == fptr || -1 == dump_all_config_trees(fptr, 1)) {
 1130         ctl_printf("Unable to save configuration to file '%s': %s",
 1131                filename, strerror(errno));
 1132         msyslog(LOG_ERR,
 1133             "saveconfig %s from %s failed", filename,
 1134             stoa(&rbufp->recv_srcadr));
 1135     } else {
 1136         ctl_printf("Configuration saved to '%s'", filename);
 1137         msyslog(LOG_NOTICE,
 1138             "Configuration saved to '%s' (requested by %s)",
 1139             fullpath, stoa(&rbufp->recv_srcadr));
 1140         /*
 1141          * save the output filename in system variable
 1142          * savedconfig, retrieved with:
 1143          *   ntpq -c "rv 0 savedconfig"
 1144          * Note: the way 'savedconfig' is defined makes overflow
 1145          * checks unnecessary here.
 1146          */
 1147         snprintf(savedconfig, sizeof(savedconfig), "%s%s",
 1148              savedconfig_eq, filename);
 1149         set_sys_var(savedconfig, strlen(savedconfig) + 1, RO);
 1150     }
 1151 
 1152     if (NULL != fptr)
 1153         fclose(fptr);
 1154 #else   /* !SAVECONFIG follows */
 1155     ctl_printf("%s",
 1156            "saveconfig unavailable, configured with --disable-saveconfig");
 1157 #endif
 1158     ctl_flushpkt(0);
 1159 }
 1160 
 1161 
 1162 /*
 1163  * process_control - process an incoming control message
 1164  */
 1165 void
 1166 process_control(
 1167     struct recvbuf *rbufp,
 1168     int restrict_mask
 1169     )
 1170 {
 1171     struct ntp_control *pkt;
 1172     int req_count;
 1173     int req_data;
 1174     const struct ctl_proc *cc;
 1175     keyid_t *pkid;
 1176     int properlen;
 1177     size_t maclen;
 1178 
 1179     DPRINTF(3, ("in process_control()\n"));
 1180 
 1181     /*
 1182      * Save the addresses for error responses
 1183      */
 1184     numctlreq++;
 1185     rmt_addr = &rbufp->recv_srcadr;
 1186     lcl_inter = rbufp->dstadr;
 1187     pkt = (struct ntp_control *)&rbufp->recv_pkt;
 1188 
 1189     /*
 1190      * If the length is less than required for the header,
 1191      * ignore it.
 1192      */
 1193     if (rbufp->recv_length < (int)CTL_HEADER_LEN) {
 1194         DPRINTF(1, ("Short control packet\n"));
 1195         numctltooshort++;
 1196         return;
 1197     }
 1198 
 1199     /*
 1200      * If this packet is a response or a fragment, ignore it.
 1201      */
 1202     if (   (CTL_RESPONSE | CTL_MORE | CTL_ERROR) & pkt->r_m_e_op
 1203         || pkt->offset != 0) {
 1204         DPRINTF(1, ("invalid format in control packet\n"));
 1205         if (CTL_RESPONSE & pkt->r_m_e_op)
 1206             numctlinputresp++;
 1207         if (CTL_MORE & pkt->r_m_e_op)
 1208             numctlinputfrag++;
 1209         if (CTL_ERROR & pkt->r_m_e_op)
 1210             numctlinputerr++;
 1211         if (pkt->offset != 0)
 1212             numctlbadoffset++;
 1213         return;
 1214     }
 1215 
 1216     res_version = PKT_VERSION(pkt->li_vn_mode);
 1217     if (res_version > NTP_VERSION || res_version < NTP_OLDVERSION) {
 1218         DPRINTF(1, ("unknown version %d in control packet\n",
 1219                 res_version));
 1220         numctlbadversion++;
 1221         return;
 1222     }
 1223 
 1224     /*
 1225      * Pull enough data from the packet to make intelligent
 1226      * responses
 1227      */
 1228     rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, res_version,
 1229                      MODE_CONTROL);
 1230     res_opcode = pkt->r_m_e_op;
 1231     rpkt.sequence = pkt->sequence;
 1232     rpkt.associd = pkt->associd;
 1233     rpkt.status = 0;
 1234     res_frags = 1;
 1235     res_offset = 0;
 1236     res_associd = htons(pkt->associd);
 1237     res_async = FALSE;
 1238     res_authenticate = FALSE;
 1239     res_keyid = 0;
 1240     res_authokay = FALSE;
 1241     req_count = (int)ntohs(pkt->count);
 1242     datanotbinflag = FALSE;
 1243     datalinelen = 0;
 1244     datasent = 0;
 1245     datapt = rpkt.u.data;
 1246     dataend = &rpkt.u.data[CTL_MAX_DATA_LEN];
 1247 
 1248     if ((rbufp->recv_length & 0x3) != 0)
 1249         DPRINTF(3, ("Control packet length %d unrounded\n",
 1250                 rbufp->recv_length));
 1251 
 1252     /*
 1253      * We're set up now. Make sure we've got at least enough
 1254      * incoming data space to match the count.
 1255      */
 1256     req_data = rbufp->recv_length - CTL_HEADER_LEN;
 1257     if (req_data < req_count || rbufp->recv_length & 0x3) {
 1258         ctl_error(CERR_BADFMT);
 1259         numctldatatooshort++;
 1260         return;
 1261     }
 1262 
 1263     properlen = req_count + CTL_HEADER_LEN;
 1264     /* round up proper len to a 8 octet boundary */
 1265 
 1266     properlen = (properlen + 7) & ~7;
 1267     maclen = rbufp->recv_length - properlen;
 1268     if ((rbufp->recv_length & 3) == 0 &&
 1269         maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN &&
 1270         sys_authenticate) {
 1271         res_authenticate = TRUE;
 1272         pkid = (void *)((char *)pkt + properlen);
 1273         res_keyid = ntohl(*pkid);
 1274         DPRINTF(3, ("recv_len %d, properlen %d, wants auth with keyid %08x, MAC length=%zu\n",
 1275                 rbufp->recv_length, properlen, res_keyid,
 1276                 maclen));
 1277 
 1278         if (!authistrustedip(res_keyid, &rbufp->recv_srcadr))
 1279             DPRINTF(3, ("invalid keyid %08x\n", res_keyid));
 1280         else if (authdecrypt(res_keyid, (u_int32 *)pkt,
 1281                      rbufp->recv_length - maclen,
 1282                      maclen)) {
 1283             res_authokay = TRUE;
 1284             DPRINTF(3, ("authenticated okay\n"));
 1285         } else {
 1286             res_keyid = 0;
 1287             DPRINTF(3, ("authentication failed\n"));
 1288         }
 1289     }
 1290 
 1291     /*
 1292      * Set up translate pointers
 1293      */
 1294     reqpt = (char *)pkt->u.data;
 1295     reqend = reqpt + req_count;
 1296 
 1297     /*
 1298      * Look for the opcode processor
 1299      */
 1300     for (cc = control_codes; cc->control_code != NO_REQUEST; cc++) {
 1301         if (cc->control_code == res_opcode) {
 1302             DPRINTF(3, ("opcode %d, found command handler\n",
 1303                     res_opcode));
 1304             if (cc->flags == AUTH
 1305                 && (!res_authokay
 1306                 || res_keyid != ctl_auth_keyid)) {
 1307                 ctl_error(CERR_PERMISSION);
 1308                 return;
 1309             }
 1310             (cc->handler)(rbufp, restrict_mask);
 1311             return;
 1312         }
 1313     }
 1314 
 1315     /*
 1316      * Can't find this one, return an error.
 1317      */
 1318     numctlbadop++;
 1319     ctl_error(CERR_BADOP);
 1320     return;
 1321 }
 1322 
 1323 
 1324 /*
 1325  * ctlpeerstatus - return a status word for this peer
 1326  */
 1327 u_short
 1328 ctlpeerstatus(
 1329     register struct peer *p
 1330     )
 1331 {
 1332     u_short status;
 1333 
 1334     status = p->status;
 1335     if (FLAG_CONFIG & p->flags)
 1336         status |= CTL_PST_CONFIG;
 1337     if (p->keyid)
 1338         status |= CTL_PST_AUTHENABLE;
 1339     if (FLAG_AUTHENTIC & p->flags)
 1340         status |= CTL_PST_AUTHENTIC;
 1341     if (p->reach)
 1342         status |= CTL_PST_REACH;
 1343     if (MDF_TXONLY_MASK & p->cast_flags)
 1344         status |= CTL_PST_BCAST;
 1345 
 1346     return CTL_PEER_STATUS(status, p->num_events, p->last_event);
 1347 }
 1348 
 1349 
 1350 /*
 1351  * ctlclkstatus - return a status word for this clock
 1352  */
 1353 #ifdef REFCLOCK
 1354 static u_short
 1355 ctlclkstatus(
 1356     struct refclockstat *pcs
 1357     )
 1358 {
 1359     return CTL_PEER_STATUS(0, pcs->lastevent, pcs->currentstatus);
 1360 }
 1361 #endif
 1362 
 1363 
 1364 /*
 1365  * ctlsysstatus - return the system status word
 1366  */
 1367 u_short
 1368 ctlsysstatus(void)
 1369 {
 1370     register u_char this_clock;
 1371 
 1372     this_clock = CTL_SST_TS_UNSPEC;
 1373 #ifdef REFCLOCK
 1374     if (sys_peer != NULL) {
 1375         if (CTL_SST_TS_UNSPEC != sys_peer->sstclktype)
 1376             this_clock = sys_peer->sstclktype;
 1377         else if (sys_peer->refclktype < COUNTOF(clocktypes))
 1378             this_clock = clocktypes[sys_peer->refclktype];
 1379     }
 1380 #else /* REFCLOCK */
 1381     if (sys_peer != 0)
 1382         this_clock = CTL_SST_TS_NTP;
 1383 #endif /* REFCLOCK */
 1384     return CTL_SYS_STATUS(sys_leap, this_clock, ctl_sys_num_events,
 1385                   ctl_sys_last_event);
 1386 }
 1387 
 1388 
 1389 /*
 1390  * ctl_flushpkt - write out the current packet and prepare
 1391  *        another if necessary.
 1392  */
 1393 static void
 1394 ctl_flushpkt(
 1395     u_char more
 1396     )
 1397 {
 1398     size_t i;
 1399     size_t dlen;
 1400     size_t sendlen;
 1401     size_t maclen;
 1402     size_t totlen;
 1403     keyid_t keyid;
 1404 
 1405     dlen = datapt - rpkt.u.data;
 1406     if (!more && datanotbinflag && dlen + 2 < CTL_MAX_DATA_LEN) {
 1407         /*
 1408          * Big hack, output a trailing \r\n
 1409          */
 1410         *datapt++ = '\r';
 1411         *datapt++ = '\n';
 1412         dlen += 2;
 1413     }
 1414     sendlen = dlen + CTL_HEADER_LEN;
 1415 
 1416     /*
 1417      * Pad to a multiple of 32 bits
 1418      */
 1419     while (sendlen & 0x3) {
 1420         *datapt++ = '\0';
 1421         sendlen++;
 1422     }
 1423 
 1424     /*
 1425      * Fill in the packet with the current info
 1426      */
 1427     rpkt.r_m_e_op = CTL_RESPONSE | more |
 1428             (res_opcode & CTL_OP_MASK);
 1429     rpkt.count = htons((u_short)dlen);
 1430     rpkt.offset = htons((u_short)res_offset);
 1431     if (res_async) {
 1432         for (i = 0; i < COUNTOF(ctl_traps); i++) {
 1433             if (TRAP_INUSE & ctl_traps[i].tr_flags) {
 1434                 rpkt.li_vn_mode =
 1435                     PKT_LI_VN_MODE(
 1436                     sys_leap,
 1437                     ctl_traps[i].tr_version,
 1438                     MODE_CONTROL);
 1439                 rpkt.sequence =
 1440                     htons(ctl_traps[i].tr_sequence);
 1441                 sendpkt(&ctl_traps[i].tr_addr,
 1442                     ctl_traps[i].tr_localaddr, -4,
 1443                     (struct pkt *)&rpkt, sendlen);
 1444                 if (!more)
 1445                     ctl_traps[i].tr_sequence++;
 1446                 numasyncmsgs++;
 1447             }
 1448         }
 1449     } else {
 1450         if (res_authenticate && sys_authenticate) {
 1451             totlen = sendlen;
 1452             /*
 1453              * If we are going to authenticate, then there
 1454              * is an additional requirement that the MAC
 1455              * begin on a 64 bit boundary.
 1456              */
 1457             while (totlen & 7) {
 1458                 *datapt++ = '\0';
 1459                 totlen++;
 1460             }
 1461             keyid = htonl(res_keyid);
 1462             memcpy(datapt, &keyid, sizeof(keyid));
 1463             maclen = authencrypt(res_keyid,
 1464                          (u_int32 *)&rpkt, totlen);
 1465             sendpkt(rmt_addr, lcl_inter, -5,
 1466                 (struct pkt *)&rpkt, totlen + maclen);
 1467         } else {
 1468             sendpkt(rmt_addr, lcl_inter, -6,
 1469                 (struct pkt *)&rpkt, sendlen);
 1470         }
 1471         if (more)
 1472             numctlfrags++;
 1473         else
 1474             numctlresponses++;
 1475     }
 1476 
 1477     /*
 1478      * Set us up for another go around.
 1479      */
 1480     res_frags++;
 1481     res_offset += dlen;
 1482     datapt = rpkt.u.data;
 1483 }
 1484 
 1485 
 1486 /* --------------------------------------------------------------------
 1487  * block transfer API -- stream string/data fragments into xmit buffer
 1488  * without additional copying
 1489  */
 1490 
 1491 /* buffer descriptor: address & size of fragment
 1492  * 'buf' may only be NULL when 'len' is zero!
 1493  */
 1494 typedef struct {
 1495     const void  *buf;
 1496     size_t       len;
 1497 } CtlMemBufT;
 1498 
 1499 /* put ctl data in a gather-style operation */
 1500 static void
 1501 ctl_putdata_ex(
 1502     const CtlMemBufT * argv,
 1503     size_t             argc,
 1504     int/*BOOL*/        bin      /* set to 1 when data is binary */
 1505     )
 1506 {
 1507     const char * src_ptr;
 1508     size_t       src_len, cur_len, add_len, argi;
 1509 
 1510     /* text / binary preprocessing, possibly create new linefeed */
 1511     if (bin) {
 1512         add_len = 0;
 1513     } else {
 1514         datanotbinflag = TRUE;
 1515         add_len = 3;
 1516 
 1517         if (datasent) {
 1518             *datapt++ = ',';
 1519             datalinelen++;
 1520 
 1521             /* sum up total length */
 1522             for (argi = 0, src_len = 0; argi < argc; ++argi)
 1523                 src_len += argv[argi].len;
 1524             /* possibly start a new line, assume no size_t overflow */
 1525             if ((src_len + datalinelen + 1) >= MAXDATALINELEN) {
 1526                 *datapt++ = '\r';
 1527                 *datapt++ = '\n';
 1528                 datalinelen = 0;
 1529             } else {
 1530                 *datapt++ = ' ';
 1531                 datalinelen++;
 1532             }
 1533         }
 1534     }
 1535 
 1536     /* now stream out all buffers */
 1537     for (argi = 0; argi < argc; ++argi) {
 1538         src_ptr = argv[argi].buf;
 1539         src_len = argv[argi].len;
 1540 
 1541         if ( ! (src_ptr && src_len))
 1542             continue;
 1543 
 1544         cur_len = (size_t)(dataend - datapt);
 1545         while ((src_len + add_len) > cur_len) {
 1546             /* Not enough room in this one, flush it out. */
 1547             if (src_len < cur_len)
 1548                 cur_len = src_len;
 1549 
 1550             memcpy(datapt, src_ptr, cur_len);
 1551             datapt      += cur_len;
 1552             datalinelen += cur_len;
 1553 
 1554             src_ptr     += cur_len;
 1555             src_len     -= cur_len;
 1556 
 1557             ctl_flushpkt(CTL_MORE);
 1558             cur_len = (size_t)(dataend - datapt);
 1559         }
 1560 
 1561         memcpy(datapt, src_ptr, src_len);
 1562         datapt      += src_len;
 1563         datalinelen += src_len;
 1564 
 1565         datasent = TRUE;
 1566     }
 1567 }
 1568 
 1569 /*
 1570  * ctl_putdata - write data into the packet, fragmenting and starting
 1571  * another if this one is full.
 1572  */
 1573 static void
 1574 ctl_putdata(
 1575     const char *dp,
 1576     unsigned int dlen,
 1577     int bin         /* set to 1 when data is binary */
 1578     )
 1579 {
 1580     CtlMemBufT args[1];
 1581 
 1582     args[0].buf = dp;
 1583     args[0].len = dlen;
 1584     ctl_putdata_ex(args, 1, bin);
 1585 }
 1586 
 1587 /*
 1588  * ctl_putstr - write a tagged string into the response packet
 1589  *      in the form:
 1590  *
 1591  *      tag="data"
 1592  *
 1593  *      len is the data length excluding the NUL terminator,
 1594  *      as in ctl_putstr("var", "value", strlen("value"));
 1595  */
 1596 static void
 1597 ctl_putstr(
 1598     const char *    tag,
 1599     const char *    data,
 1600     size_t      len
 1601     )
 1602 {
 1603     CtlMemBufT args[4];
 1604 
 1605     args[0].buf = tag;
 1606     args[0].len = strlen(tag);
 1607     if (data && len) {
 1608         args[1].buf = "=\"";
 1609         args[1].len = 2;
 1610         args[2].buf = data;
 1611         args[2].len = len;
 1612         args[3].buf = "\"";
 1613         args[3].len = 1;
 1614         ctl_putdata_ex(args, 4, FALSE);
 1615     } else {
 1616         args[1].buf = "=\"\"";
 1617         args[1].len = 3;
 1618         ctl_putdata_ex(args, 2, FALSE);
 1619     }
 1620 }
 1621 
 1622 
 1623 /*
 1624  * ctl_putunqstr - write a tagged string into the response packet
 1625  *         in the form:
 1626  *
 1627  *         tag=data
 1628  *
 1629  *  len is the data length excluding the NUL terminator.
 1630  *  data must not contain a comma or whitespace.
 1631  */
 1632 static void
 1633 ctl_putunqstr(
 1634     const char *    tag,
 1635     const char *    data,
 1636     size_t      len
 1637     )
 1638 {
 1639     CtlMemBufT args[3];
 1640 
 1641     args[0].buf = tag;
 1642     args[0].len = strlen(tag);
 1643     args[1].buf = "=";
 1644     args[1].len = 1;
 1645     if (data && len) {
 1646         args[2].buf = data;
 1647         args[2].len = len;
 1648         ctl_putdata_ex(args, 3, FALSE);
 1649     } else {
 1650         ctl_putdata_ex(args, 2, FALSE);
 1651     }
 1652 }
 1653 
 1654 
 1655 /*
 1656  * ctl_putdblf - write a tagged, signed double into the response packet
 1657  */
 1658 static void
 1659 ctl_putdblf(
 1660     const char *    tag,
 1661     int     use_f,
 1662     int     precision,
 1663     double      d
 1664     )
 1665 {
 1666     char buffer[40];
 1667     int  rc;
 1668 
 1669     rc = snprintf(buffer, sizeof(buffer),
 1670               (use_f ? "%.*f" : "%.*g"),
 1671               precision, d);
 1672     INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
 1673     ctl_putunqstr(tag, buffer, rc);
 1674 }
 1675 
 1676 /*
 1677  * ctl_putuint - write a tagged unsigned integer into the response
 1678  */
 1679 static void
 1680 ctl_putuint(
 1681     const char *tag,
 1682     u_long uval
 1683     )
 1684 {
 1685     char buffer[24]; /* needs to fit for 64 bits! */
 1686     int  rc;
 1687 
 1688     rc = snprintf(buffer, sizeof(buffer), "%lu", uval);
 1689     INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
 1690     ctl_putunqstr(tag, buffer, rc);
 1691 }
 1692 
 1693 /*
 1694  * ctl_putcal - write a decoded calendar data into the response.
 1695  * only used with AUTOKEY currently, so compiled conditional
 1696  */
 1697 #ifdef AUTOKEY
 1698 static void
 1699 ctl_putcal(
 1700     const char *tag,
 1701     const struct calendar *pcal
 1702     )
 1703 {
 1704     char buffer[16];
 1705     int  rc;
 1706 
 1707     rc = snprintf(buffer, sizeof(buffer),
 1708               "%04d%02d%02d%02d%02d",
 1709               pcal->year, pcal->month, pcal->monthday,
 1710               pcal->hour, pcal->minute
 1711         );
 1712     INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
 1713     ctl_putunqstr(tag, buffer, rc);
 1714 }
 1715 #endif
 1716 
 1717 /*
 1718  * ctl_putfs - write a decoded filestamp into the response
 1719  */
 1720 static void
 1721 ctl_putfs(
 1722     const char *tag,
 1723     tstamp_t uval
 1724     )
 1725 {
 1726     char buffer[16];
 1727     int  rc;
 1728 
 1729     time_t fstamp = (time_t)uval - JAN_1970;
 1730     struct tm *tm = gmtime(&fstamp);
 1731 
 1732     if (NULL == tm)
 1733         return;
 1734 
 1735     rc = snprintf(buffer, sizeof(buffer),
 1736               "%04d%02d%02d%02d%02d",
 1737               tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
 1738               tm->tm_hour, tm->tm_min);
 1739     INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
 1740     ctl_putunqstr(tag, buffer, rc);
 1741 }
 1742 
 1743 
 1744 /*
 1745  * ctl_puthex - write a tagged unsigned integer, in hex, into the
 1746  * response
 1747  */
 1748 static void
 1749 ctl_puthex(
 1750     const char *tag,
 1751     u_long uval
 1752     )
 1753 {
 1754     char buffer[24];    /* must fit 64bit int! */
 1755     int  rc;
 1756 
 1757     rc = snprintf(buffer, sizeof(buffer), "0x%lx", uval);
 1758     INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
 1759     ctl_putunqstr(tag, buffer, rc);
 1760 }
 1761 
 1762 
 1763 /*
 1764  * ctl_putint - write a tagged signed integer into the response
 1765  */
 1766 static void
 1767 ctl_putint(
 1768     const char *tag,
 1769     long ival
 1770     )
 1771 {
 1772     char buffer[24];    /*must fit 64bit int */
 1773     int  rc;
 1774 
 1775     rc = snprintf(buffer, sizeof(buffer), "%ld", ival);
 1776     INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
 1777     ctl_putunqstr(tag, buffer, rc);
 1778 }
 1779 
 1780 
 1781 /*
 1782  * ctl_putts - write a tagged timestamp, in hex, into the response
 1783  */
 1784 static void
 1785 ctl_putts(
 1786     const char *tag,
 1787     l_fp *ts
 1788     )
 1789 {
 1790     char buffer[24];
 1791     int  rc;
 1792 
 1793     rc = snprintf(buffer, sizeof(buffer),
 1794               "0x%08lx.%08lx",
 1795               (u_long)ts->l_ui, (u_long)ts->l_uf);
 1796     INSIST(rc >= 0 && (size_t)rc < sizeof(buffer));
 1797     ctl_putunqstr(tag, buffer, rc);
 1798 }
 1799 
 1800 
 1801 /*
 1802  * ctl_putadr - write an IP address into the response
 1803  */
 1804 static void
 1805 ctl_putadr(
 1806     const char *tag,
 1807     u_int32 addr32,
 1808     sockaddr_u *addr
 1809     )
 1810 {
 1811     const char *cq;
 1812 
 1813     if (NULL == addr)
 1814         cq = numtoa(addr32);
 1815     else
 1816         cq = stoa(addr);
 1817     ctl_putunqstr(tag, cq, strlen(cq));
 1818 }
 1819 
 1820 
 1821 /*
 1822  * ctl_putrefid - send a u_int32 refid as printable text
 1823  */
 1824 static void
 1825 ctl_putrefid(
 1826     const char *    tag,
 1827     u_int32     refid
 1828     )
 1829 {
 1830     size_t nc;
 1831 
 1832     union {
 1833         uint32_t w;
 1834         uint8_t  b[sizeof(uint32_t)];
 1835     } bytes;
 1836 
 1837     bytes.w = refid;
 1838     for (nc = 0; nc < sizeof(bytes.b) && bytes.b[nc]; ++nc)
 1839         if (  !isprint(bytes.b[nc])
 1840             || isspace(bytes.b[nc])
 1841             || bytes.b[nc] == ','  )
 1842             bytes.b[nc] = '.';
 1843     ctl_putunqstr(tag, (const char*)bytes.b, nc);
 1844 }
 1845 
 1846 
 1847 /*
 1848  * ctl_putarray - write a tagged eight element double array into the response
 1849  */
 1850 static void
 1851 ctl_putarray(
 1852     const char *tag,
 1853     double *arr,
 1854     int start
 1855     )
 1856 {
 1857     char *cp, *ep;
 1858     char buffer[200];
 1859     int  i, rc;
 1860 
 1861     cp = buffer;
 1862     ep = buffer + sizeof(buffer);
 1863     i  = start;
 1864     do {
 1865         if (i == 0)
 1866             i = NTP_SHIFT;
 1867         i--;
 1868         rc = snprintf(cp, (size_t)(ep - cp), " %.2f", arr[i] * 1e3);
 1869         INSIST(rc >= 0 && (size_t)rc < (size_t)(ep - cp));
 1870         cp += rc;
 1871     } while (i != start);
 1872     ctl_putunqstr(tag, buffer, (size_t)(cp - buffer));
 1873 }
 1874 
 1875 /*
 1876  * ctl_printf - put a formatted string into the data buffer
 1877  */
 1878 static void
 1879 ctl_printf(
 1880     const char * fmt,
 1881     ...
 1882     )
 1883 {
 1884     static const char * ellipsis = "[...]";
 1885     va_list va;
 1886     char    fmtbuf[128];
 1887     int     rc;
 1888 
 1889     va_start(va, fmt);
 1890     rc = vsnprintf(fmtbuf, sizeof(fmtbuf), fmt, va);
 1891     va_end(va);
 1892     if (rc < 0 || (size_t)rc >= sizeof(fmtbuf))
 1893         strcpy(fmtbuf + sizeof(fmtbuf) - strlen(ellipsis) - 1,
 1894                ellipsis);
 1895     ctl_putdata(fmtbuf, strlen(fmtbuf), 0);
 1896 }
 1897 
 1898 
 1899 /*
 1900  * ctl_putsys - output a system variable
 1901  */
 1902 static void
 1903 ctl_putsys(
 1904     int varid
 1905     )
 1906 {
 1907     l_fp tmp;
 1908     char str[256];
 1909     u_int u;
 1910     double kb;
 1911     double dtemp;
 1912     const char *ss;
 1913 #ifdef AUTOKEY
 1914     struct cert_info *cp;
 1915 #endif  /* AUTOKEY */
 1916 #ifdef KERNEL_PLL
 1917     static struct timex ntx;
 1918     static u_long ntp_adjtime_time;
 1919 
 1920     /*
 1921      * CS_K_* variables depend on up-to-date output of ntp_adjtime()
 1922      */
 1923     if (CS_KERN_FIRST <= varid && varid <= CS_KERN_LAST &&
 1924         current_time != ntp_adjtime_time) {
 1925         ZERO(ntx);
 1926         if (ntp_adjtime(&ntx) < 0)
 1927             msyslog(LOG_ERR, "ntp_adjtime() for mode 6 query failed: %m");
 1928         else
 1929             ntp_adjtime_time = current_time;
 1930     }
 1931 #endif  /* KERNEL_PLL */
 1932 
 1933     switch (varid) {
 1934 
 1935     case CS_LEAP:
 1936         ctl_putuint(sys_var[CS_LEAP].text, sys_leap);
 1937         break;
 1938 
 1939     case CS_STRATUM:
 1940         ctl_putuint(sys_var[CS_STRATUM].text, sys_stratum);
 1941         break;
 1942 
 1943     case CS_PRECISION:
 1944         ctl_putint(sys_var[CS_PRECISION].text, sys_precision);
 1945         break;
 1946 
 1947     case CS_ROOTDELAY:
 1948         ctl_putdbl(sys_var[CS_ROOTDELAY].text, sys_rootdelay *
 1949                1e3);
 1950         break;
 1951 
 1952     case CS_ROOTDISPERSION:
 1953         ctl_putdbl(sys_var[CS_ROOTDISPERSION].text,
 1954                sys_rootdisp * 1e3);
 1955         break;
 1956 
 1957     case CS_REFID:
 1958         if (REFID_ISTEXT(sys_stratum))
 1959             ctl_putrefid(sys_var[varid].text, sys_refid);
 1960         else
 1961             ctl_putadr(sys_var[varid].text, sys_refid, NULL);
 1962         break;
 1963 
 1964     case CS_REFTIME:
 1965         ctl_putts(sys_var[CS_REFTIME].text, &sys_reftime);
 1966         break;
 1967 
 1968     case CS_POLL:
 1969         ctl_putuint(sys_var[CS_POLL].text, sys_poll);
 1970         break;
 1971 
 1972     case CS_PEERID:
 1973         if (sys_peer == NULL)
 1974             ctl_putuint(sys_var[CS_PEERID].text, 0);
 1975         else
 1976             ctl_putuint(sys_var[CS_PEERID].text,
 1977                     sys_peer->associd);
 1978         break;
 1979 
 1980     case CS_PEERADR:
 1981         if (sys_peer != NULL && sys_peer->dstadr != NULL)
 1982             ss = sptoa(&sys_peer->srcadr);
 1983         else
 1984             ss = "0.0.0.0:0";
 1985         ctl_putunqstr(sys_var[CS_PEERADR].text, ss, strlen(ss));
 1986         break;
 1987 
 1988     case CS_PEERMODE:
 1989         u = (sys_peer != NULL)
 1990             ? sys_peer->hmode
 1991             : MODE_UNSPEC;
 1992         ctl_putuint(sys_var[CS_PEERMODE].text, u);
 1993         break;
 1994 
 1995     case CS_OFFSET:
 1996         ctl_putdbl6(sys_var[CS_OFFSET].text, last_offset * 1e3);
 1997         break;
 1998 
 1999     case CS_DRIFT:
 2000         ctl_putdbl(sys_var[CS_DRIFT].text, drift_comp * 1e6);
 2001         break;
 2002 
 2003     case CS_JITTER:
 2004         ctl_putdbl6(sys_var[CS_JITTER].text, sys_jitter * 1e3);
 2005         break;
 2006 
 2007     case CS_ERROR:
 2008         ctl_putdbl(sys_var[CS_ERROR].text, clock_jitter * 1e3);
 2009         break;
 2010 
 2011     case CS_CLOCK:
 2012         get_systime(&tmp);
 2013         ctl_putts(sys_var[CS_CLOCK].text, &tmp);
 2014         break;
 2015 
 2016     case CS_PROCESSOR:
 2017 #ifndef HAVE_UNAME
 2018         ctl_putstr(sys_var[CS_PROCESSOR].text, str_processor,
 2019                sizeof(str_processor) - 1);
 2020 #else
 2021         ctl_putstr(sys_var[CS_PROCESSOR].text,
 2022                utsnamebuf.machine, strlen(utsnamebuf.machine));
 2023 #endif /* HAVE_UNAME */
 2024         break;
 2025 
 2026     case CS_SYSTEM:
 2027 #ifndef HAVE_UNAME
 2028         ctl_putstr(sys_var[CS_SYSTEM].text, str_system,
 2029                sizeof(str_system) - 1);
 2030 #else
 2031         snprintf(str, sizeof(str), "%s/%s", utsnamebuf.sysname,
 2032              utsnamebuf.release);
 2033         ctl_putstr(sys_var[CS_SYSTEM].text, str, strlen(str));
 2034 #endif /* HAVE_UNAME */
 2035         break;
 2036 
 2037     case CS_VERSION:
 2038         ctl_putstr(sys_var[CS_VERSION].text, Version,
 2039                strlen(Version));
 2040         break;
 2041 
 2042     case CS_STABIL:
 2043         ctl_putdbl(sys_var[CS_STABIL].text, clock_stability *
 2044                1e6);
 2045         break;
 2046 
 2047     case CS_VARLIST:
 2048     {
 2049         char buf[CTL_MAX_DATA_LEN];
 2050         //buffPointer, firstElementPointer, buffEndPointer
 2051         char *buffp, *buffend;
 2052         int firstVarName;
 2053         const char *ss1;
 2054         int len;
 2055         const struct ctl_var *k;
 2056 
 2057         buffp = buf;
 2058         buffend = buf + sizeof(buf);
 2059         if (strlen(sys_var[CS_VARLIST].text) > (sizeof(buf) - 4))
 2060             break;  /* really long var name */
 2061 
 2062         snprintf(buffp, sizeof(buf), "%s=\"",sys_var[CS_VARLIST].text);
 2063         buffp += strlen(buffp);
 2064         firstVarName = TRUE;
 2065         for (k = sys_var; !(k->flags & EOV); k++) {
 2066             if (k->flags & PADDING)
 2067                 continue;
 2068             len = strlen(k->text);
 2069             if (len + 1 >= buffend - buffp)
 2070                 break;
 2071             if (!firstVarName)
 2072                 *buffp++ = ',';
 2073             else
 2074                 firstVarName = FALSE;
 2075             memcpy(buffp, k->text, len);
 2076             buffp += len;
 2077         }
 2078 
 2079         for (k = ext_sys_var; k && !(k->flags & EOV); k++) {
 2080             if (k->flags & PADDING)
 2081                 continue;
 2082             if (NULL == k->text)
 2083                 continue;
 2084             ss1 = strchr(k->text, '=');
 2085             if (NULL == ss1)
 2086                 len = strlen(k->text);
 2087             else
 2088                 len = ss1 - k->text;
 2089             if (len + 1 >= buffend - buffp)
 2090                 break;
 2091             if (firstVarName) {
 2092                 *buffp++ = ',';
 2093                 firstVarName = FALSE;
 2094             }
 2095             memcpy(buffp, k->text,(unsigned)len);
 2096             buffp += len;
 2097         }
 2098         if (2 >= buffend - buffp)
 2099             break;
 2100 
 2101         *buffp++ = '"';
 2102         *buffp = '\0';
 2103 
 2104         ctl_putdata(buf, (unsigned)( buffp - buf ), 0);
 2105         break;
 2106     }
 2107 
 2108     case CS_TAI:
 2109         if (sys_tai > 0)
 2110             ctl_putuint(sys_var[CS_TAI].text, sys_tai);
 2111         break;
 2112 
 2113     case CS_LEAPTAB:
 2114     {
 2115         leap_signature_t lsig;
 2116         leapsec_getsig(&lsig);
 2117         if (lsig.ttime > 0)
 2118             ctl_putfs(sys_var[CS_LEAPTAB].text, lsig.ttime);
 2119         break;
 2120     }
 2121 
 2122     case CS_LEAPEND:
 2123     {
 2124         leap_signature_t lsig;
 2125         leapsec_getsig(&lsig);
 2126         if (lsig.etime > 0)
 2127             ctl_putfs(sys_var[CS_LEAPEND].text, lsig.etime);
 2128         break;
 2129     }
 2130 
 2131 #ifdef LEAP_SMEAR
 2132     case CS_LEAPSMEARINTV:
 2133         if (leap_smear_intv > 0)
 2134             ctl_putuint(sys_var[CS_LEAPSMEARINTV].text, leap_smear_intv);
 2135         break;
 2136 
 2137     case CS_LEAPSMEAROFFS:
 2138         if (leap_smear_intv > 0)
 2139             ctl_putdbl(sys_var[CS_LEAPSMEAROFFS].text,
 2140                    leap_smear.doffset * 1e3);
 2141         break;
 2142 #endif  /* LEAP_SMEAR */
 2143 
 2144     case CS_RATE:
 2145         ctl_putuint(sys_var[CS_RATE].text, ntp_minpoll);
 2146         break;
 2147 
 2148     case CS_MRU_ENABLED:
 2149         ctl_puthex(sys_var[varid].text, mon_enabled);
 2150         break;
 2151 
 2152     case CS_MRU_DEPTH:
 2153         ctl_putuint(sys_var[varid].text, mru_entries);
 2154         break;
 2155 
 2156     case CS_MRU_MEM:
 2157         kb = mru_entries * (sizeof(mon_entry) / 1024.);
 2158         u = (u_int)kb;
 2159         if (kb - u >= 0.5)
 2160             u++;
 2161         ctl_putuint(sys_var[varid].text, u);
 2162         break;
 2163 
 2164     case CS_MRU_DEEPEST:
 2165         ctl_putuint(sys_var[varid].text, mru_peakentries);
 2166         break;
 2167 
 2168     case CS_MRU_MINDEPTH:
 2169         ctl_putuint(sys_var[varid].text, mru_mindepth);
 2170         break;
 2171 
 2172     case CS_MRU_MAXAGE:
 2173         ctl_putint(sys_var[varid].text, mru_maxage);
 2174         break;
 2175 
 2176     case CS_MRU_MAXDEPTH:
 2177         ctl_putuint(sys_var[varid].text, mru_maxdepth);
 2178         break;
 2179 
 2180     case CS_MRU_MAXMEM:
 2181         kb = mru_maxdepth * (sizeof(mon_entry) / 1024.);
 2182         u = (u_int)kb;
 2183         if (kb - u >= 0.5)
 2184             u++;
 2185         ctl_putuint(sys_var[varid].text, u);
 2186         break;
 2187 
 2188     case CS_SS_UPTIME:
 2189         ctl_putuint(sys_var[varid].text, current_time);
 2190         break;
 2191 
 2192     case CS_SS_RESET:
 2193         ctl_putuint(sys_var[varid].text,
 2194                 current_time - sys_stattime);
 2195         break;
 2196 
 2197     case CS_SS_RECEIVED:
 2198         ctl_putuint(sys_var[varid].text, sys_received);
 2199         break;
 2200 
 2201     case CS_SS_THISVER:
 2202         ctl_putuint(sys_var[varid].text, sys_newversion);
 2203         break;
 2204 
 2205     case CS_SS_OLDVER:
 2206         ctl_putuint(sys_var[varid].text, sys_oldversion);
 2207         break;
 2208 
 2209     case CS_SS_BADFORMAT:
 2210         ctl_putuint(sys_var[varid].text, sys_badlength);
 2211         break;
 2212 
 2213     case CS_SS_BADAUTH:
 2214         ctl_putuint(sys_var[varid].text, sys_badauth);
 2215         break;
 2216 
 2217     case CS_SS_DECLINED:
 2218         ctl_putuint(sys_var[varid].text, sys_declined);
 2219         break;
 2220 
 2221     case CS_SS_RESTRICTED:
 2222         ctl_putuint(sys_var[varid].text, sys_restricted);
 2223         break;
 2224 
 2225     case CS_SS_LIMITED:
 2226         ctl_putuint(sys_var[varid].text, sys_limitrejected);
 2227         break;
 2228 
 2229     case CS_SS_LAMPORT:
 2230         ctl_putuint(sys_var[varid].text, sys_lamport);
 2231         break;
 2232 
 2233     case CS_SS_TSROUNDING:
 2234         ctl_putuint(sys_var[varid].text, sys_tsrounding);
 2235         break;
 2236 
 2237     case CS_SS_KODSENT:
 2238         ctl_putuint(sys_var[varid].text, sys_kodsent);
 2239         break;
 2240 
 2241     case CS_SS_PROCESSED:
 2242         ctl_putuint(sys_var[varid].text, sys_processed);
 2243         break;
 2244 
 2245     case CS_BCASTDELAY:
 2246         ctl_putdbl(sys_var[varid].text, sys_bdelay * 1e3);
 2247         break;
 2248 
 2249     case CS_AUTHDELAY:
 2250         LFPTOD(&sys_authdelay, dtemp);
 2251         ctl_putdbl(sys_var[varid].text, dtemp * 1e3);
 2252         break;
 2253 
 2254     case CS_AUTHKEYS:
 2255         ctl_putuint(sys_var[varid].text, authnumkeys);
 2256         break;
 2257 
 2258     case CS_AUTHFREEK:
 2259         ctl_putuint(sys_var[varid].text, authnumfreekeys);
 2260         break;
 2261 
 2262     case CS_AUTHKLOOKUPS:
 2263         ctl_putuint(sys_var[varid].text, authkeylookups);
 2264         break;
 2265 
 2266     case CS_AUTHKNOTFOUND:
 2267         ctl_putuint(sys_var[varid].text, authkeynotfound);
 2268         break;
 2269 
 2270     case CS_AUTHKUNCACHED:
 2271         ctl_putuint(sys_var[varid].text, authkeyuncached);
 2272         break;
 2273 
 2274     case CS_AUTHKEXPIRED:
 2275         ctl_putuint(sys_var[varid].text, authkeyexpired);
 2276         break;
 2277 
 2278     case CS_AUTHENCRYPTS:
 2279         ctl_putuint(sys_var[varid].text, authencryptions);
 2280         break;
 2281 
 2282     case CS_AUTHDECRYPTS:
 2283         ctl_putuint(sys_var[varid].text, authdecryptions);
 2284         break;
 2285 
 2286     case CS_AUTHRESET:
 2287         ctl_putuint(sys_var[varid].text,
 2288                 current_time - auth_timereset);
 2289         break;
 2290 
 2291         /*
 2292          * CTL_IF_KERNLOOP() puts a zero if the kernel loop is
 2293          * unavailable, otherwise calls putfunc with args.
 2294          */
 2295 #ifndef KERNEL_PLL
 2296 # define    CTL_IF_KERNLOOP(putfunc, args)  \
 2297         ctl_putint(sys_var[varid].text, 0)
 2298 #else
 2299 # define    CTL_IF_KERNLOOP(putfunc, args)  \
 2300         putfunc args
 2301 #endif
 2302 
 2303         /*
 2304          * CTL_IF_KERNPPS() puts a zero if either the kernel
 2305          * loop is unavailable, or kernel hard PPS is not
 2306          * active, otherwise calls putfunc with args.
 2307          */
 2308 #ifndef KERNEL_PLL
 2309 # define    CTL_IF_KERNPPS(putfunc, args)   \
 2310         ctl_putint(sys_var[varid].text, 0)
 2311 #else
 2312 # define    CTL_IF_KERNPPS(putfunc, args)           \
 2313         if (0 == ntx.shift)             \
 2314             ctl_putint(sys_var[varid].text, 0); \
 2315         else                        \
 2316             putfunc args    /* no trailing ; */
 2317 #endif
 2318 
 2319     case CS_K_OFFSET:
 2320         CTL_IF_KERNLOOP(
 2321             ctl_putdblf,
 2322             (sys_var[varid].text, 0, -1,
 2323              1000 * dbl_from_var_long(ntx.offset, ntx.status))
 2324         );
 2325         break;
 2326 
 2327     case CS_K_FREQ:
 2328         CTL_IF_KERNLOOP(
 2329             ctl_putsfp,
 2330             (sys_var[varid].text, ntx.freq)
 2331         );
 2332         break;
 2333 
 2334     case CS_K_MAXERR:
 2335         CTL_IF_KERNLOOP(
 2336             ctl_putdblf,
 2337             (sys_var[varid].text, 0, 6,
 2338              1000 * dbl_from_usec_long(ntx.maxerror))
 2339         );
 2340         break;
 2341 
 2342     case CS_K_ESTERR:
 2343         CTL_IF_KERNLOOP(
 2344             ctl_putdblf,
 2345             (sys_var[varid].text, 0, 6,
 2346              1000 * dbl_from_usec_long(ntx.esterror))
 2347         );
 2348         break;
 2349 
 2350     case CS_K_STFLAGS:
 2351 #ifndef KERNEL_PLL
 2352         ss = "";
 2353 #else
 2354         ss = k_st_flags(ntx.status);
 2355 #endif
 2356         ctl_putstr(sys_var[varid].text, ss, strlen(ss));
 2357         break;
 2358 
 2359     case CS_K_TIMECONST:
 2360         CTL_IF_KERNLOOP(
 2361             ctl_putint,
 2362             (sys_var[varid].text, ntx.constant)
 2363         );
 2364         break;
 2365 
 2366     case CS_K_PRECISION:
 2367         CTL_IF_KERNLOOP(
 2368             ctl_putdblf,
 2369             (sys_var[varid].text, 0, 6,
 2370              1000 * dbl_from_var_long(ntx.precision, ntx.status))
 2371         );
 2372         break;
 2373 
 2374     case CS_K_FREQTOL:
 2375         CTL_IF_KERNLOOP(
 2376             ctl_putsfp,
 2377             (sys_var[varid].text, ntx.tolerance)
 2378         );
 2379         break;
 2380 
 2381     case CS_K_PPS_FREQ:
 2382         CTL_IF_KERNPPS(
 2383             ctl_putsfp,
 2384             (sys_var[varid].text, ntx.ppsfreq)
 2385         );
 2386         break;
 2387 
 2388     case CS_K_PPS_STABIL:
 2389         CTL_IF_KERNPPS(
 2390             ctl_putsfp,
 2391             (sys_var[varid].text, ntx.stabil)
 2392         );
 2393         break;
 2394 
 2395     case CS_K_PPS_JITTER:
 2396         CTL_IF_KERNPPS(
 2397             ctl_putdbl,
 2398             (sys_var[varid].text,
 2399              1000 * dbl_from_var_long(ntx.jitter, ntx.status))
 2400         );
 2401         break;
 2402 
 2403     case CS_K_PPS_CALIBDUR:
 2404         CTL_IF_KERNPPS(
 2405             ctl_putint,
 2406             (sys_var[varid].text, 1 << ntx.shift)
 2407         );
 2408         break;
 2409 
 2410     case CS_K_PPS_CALIBS:
 2411         CTL_IF_KERNPPS(
 2412             ctl_putint,
 2413             (sys_var[varid].text, ntx.calcnt)
 2414         );
 2415         break;
 2416 
 2417     case CS_K_PPS_CALIBERRS:
 2418         CTL_IF_KERNPPS(
 2419             ctl_putint,
 2420             (sys_var[varid].text, ntx.errcnt)
 2421         );
 2422         break;
 2423 
 2424     case CS_K_PPS_JITEXC:
 2425         CTL_IF_KERNPPS(
 2426             ctl_putint,
 2427             (sys_var[varid].text, ntx.jitcnt)
 2428         );
 2429         break;
 2430 
 2431     case CS_K_PPS_STBEXC:
 2432         CTL_IF_KERNPPS(
 2433             ctl_putint,
 2434             (sys_var[varid].text, ntx.stbcnt)
 2435         );
 2436         break;
 2437 
 2438     case CS_IOSTATS_RESET:
 2439         ctl_putuint(sys_var[varid].text,
 2440                 current_time - io_timereset);
 2441         break;
 2442 
 2443     case CS_TOTAL_RBUF:
 2444         ctl_putuint(sys_var[varid].text, total_recvbuffs());
 2445         break;
 2446 
 2447     case CS_FREE_RBUF:
 2448         ctl_putuint(sys_var[varid].text, free_recvbuffs());
 2449         break;
 2450 
 2451     case CS_USED_RBUF:
 2452         ctl_putuint(sys_var[varid].text, full_recvbuffs());
 2453         break;
 2454 
 2455     case CS_RBUF_LOWATER:
 2456         ctl_putuint(sys_var[varid].text, lowater_additions());
 2457         break;
 2458 
 2459     case CS_IO_DROPPED:
 2460         ctl_putuint(sys_var[varid].text, packets_dropped);
 2461         break;
 2462 
 2463     case CS_IO_IGNORED:
 2464         ctl_putuint(sys_var[varid].text, packets_ignored);
 2465         break;
 2466 
 2467     case CS_IO_RECEIVED:
 2468         ctl_putuint(sys_var[varid].text, packets_received);
 2469         break;
 2470 
 2471     case CS_IO_SENT:
 2472         ctl_putuint(sys_var[varid].text, packets_sent);
 2473         break;
 2474 
 2475     case CS_IO_SENDFAILED:
 2476         ctl_putuint(sys_var[varid].text, packets_notsent);
 2477         break;
 2478 
 2479     case CS_IO_WAKEUPS:
 2480         ctl_putuint(sys_var[varid].text, handler_calls);
 2481         break;
 2482 
 2483     case CS_IO_GOODWAKEUPS:
 2484         ctl_putuint(sys_var[varid].text, handler_pkts);
 2485         break;
 2486 
 2487     case CS_TIMERSTATS_RESET:
 2488         ctl_putuint(sys_var[varid].text,
 2489                 current_time - timer_timereset);
 2490         break;
 2491 
 2492     case CS_TIMER_OVERRUNS:
 2493         ctl_putuint(sys_var[varid].text, alarm_overflow);
 2494         break;
 2495 
 2496     case CS_TIMER_XMTS:
 2497         ctl_putuint(sys_var[varid].text, timer_xmtcalls);
 2498         break;
 2499 
 2500     case CS_FUZZ:
 2501         ctl_putdbl(sys_var[varid].text, sys_fuzz * 1e3);
 2502         break;
 2503     case CS_WANDER_THRESH:
 2504         ctl_putdbl(sys_var[varid].text, wander_threshold * 1e6);
 2505         break;
 2506 #ifdef AUTOKEY
 2507     case CS_FLAGS:
 2508         if (crypto_flags)
 2509             ctl_puthex(sys_var[CS_FLAGS].text,
 2510                 crypto_flags);
 2511         break;
 2512 
 2513     case CS_DIGEST:
 2514         if (crypto_flags) {
 2515             strlcpy(str, OBJ_nid2ln(crypto_nid),
 2516                 COUNTOF(str));
 2517             ctl_putstr(sys_var[CS_DIGEST].text, str,
 2518                 strlen(str));
 2519         }
 2520         break;
 2521 
 2522     case CS_SIGNATURE:
 2523         if (crypto_flags) {
 2524             const EVP_MD *dp;
 2525 
 2526             dp = EVP_get_digestbynid(crypto_flags >> 16);
 2527             strlcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)),
 2528                 COUNTOF(str));
 2529             ctl_putstr(sys_var[CS_SIGNATURE].text, str,
 2530                 strlen(str));
 2531         }
 2532         break;
 2533 
 2534     case CS_HOST:
 2535         if (hostval.ptr != NULL)
 2536             ctl_putstr(sys_var[CS_HOST].text, hostval.ptr,
 2537                 strlen(hostval.ptr));
 2538         break;
 2539 
 2540     case CS_IDENT:
 2541         if (sys_ident != NULL)
 2542             ctl_putstr(sys_var[CS_IDENT].text, sys_ident,
 2543                 strlen(sys_ident));
 2544         break;
 2545 
 2546     case CS_CERTIF:
 2547         for (cp = cinfo; cp != NULL; cp = cp->link) {
 2548             snprintf(str, sizeof(str), "%s %s 0x%x",
 2549                 cp->subject, cp->issuer, cp->flags);
 2550             ctl_putstr(sys_var[CS_CERTIF].text, str,
 2551                 strlen(str));
 2552             ctl_putcal(sys_var[CS_REVTIME].text, &(cp->last));
 2553         }
 2554         break;
 2555 
 2556     case CS_PUBLIC:
 2557         if (hostval.tstamp != 0)
 2558             ctl_putfs(sys_var[CS_PUBLIC].text,
 2559                 ntohl(hostval.tstamp));
 2560         break;
 2561 #endif  /* AUTOKEY */
 2562 
 2563     default:
 2564         break;
 2565     }
 2566 }
 2567 
 2568 
 2569 /*
 2570  * ctl_putpeer - output a peer variable
 2571  */
 2572 static void
 2573 ctl_putpeer(
 2574     int id,
 2575     struct peer *p
 2576     )
 2577 {
 2578     char buf[CTL_MAX_DATA_LEN];
 2579     char *s;
 2580     char *t;
 2581     char *be;
 2582     int i;
 2583     const struct ctl_var *k;
 2584 #ifdef AUTOKEY
 2585     struct autokey *ap;
 2586     const EVP_MD *dp;
 2587     const char *str;
 2588 #endif  /* AUTOKEY */
 2589 
 2590     switch (id) {
 2591 
 2592     case CP_CONFIG:
 2593         ctl_putuint(peer_var[id].text,
 2594                 !(FLAG_PREEMPT & p->flags));
 2595         break;
 2596 
 2597     case CP_AUTHENABLE:
 2598         ctl_putuint(peer_var[id].text, !(p->keyid));
 2599         break;
 2600 
 2601     case CP_AUTHENTIC:
 2602         ctl_putuint(peer_var[id].text,
 2603                 !!(FLAG_AUTHENTIC & p->flags));
 2604         break;
 2605 
 2606     case CP_SRCADR:
 2607         ctl_putadr(peer_var[id].text, 0, &p->srcadr);
 2608         break;
 2609 
 2610     case CP_SRCPORT:
 2611         ctl_putuint(peer_var[id].text, SRCPORT(&p->srcadr));
 2612         break;
 2613 
 2614     case CP_SRCHOST:
 2615         if (p->hostname != NULL)
 2616             ctl_putstr(peer_var[id].text, p->hostname,
 2617                    strlen(p->hostname));
 2618         break;
 2619 
 2620     case CP_DSTADR:
 2621         ctl_putadr(peer_var[id].text, 0,
 2622                (p->dstadr != NULL)
 2623                 ? &p->dstadr->sin
 2624                 : NULL);
 2625         break;
 2626 
 2627     case CP_DSTPORT:
 2628         ctl_putuint(peer_var[id].text,
 2629                 (p->dstadr != NULL)
 2630                 ? SRCPORT(&p->dstadr->sin)
 2631                 : 0);
 2632         break;
 2633 
 2634     case CP_IN:
 2635         if (p->r21 > 0.)
 2636             ctl_putdbl(peer_var[id].text, p->r21 / 1e3);
 2637         break;
 2638 
 2639     case CP_OUT:
 2640         if (p->r34 > 0.)
 2641             ctl_putdbl(peer_var[id].text, p->r34 / 1e3);
 2642         break;
 2643 
 2644     case CP_RATE:
 2645         ctl_putuint(peer_var[id].text, p->throttle);
 2646         break;
 2647 
 2648     case CP_LEAP:
 2649         ctl_putuint(peer_var[id].text, p->leap);
 2650         break;
 2651 
 2652     case CP_HMODE:
 2653         ctl_putuint(peer_var[id].text, p->hmode);
 2654         break;
 2655 
 2656     case CP_STRATUM:
 2657         ctl_putuint(peer_var[id].text, p->stratum);
 2658         break;
 2659 
 2660     case CP_PPOLL:
 2661         ctl_putuint(peer_var[id].text, p->ppoll);
 2662         break;
 2663 
 2664     case CP_HPOLL:
 2665         ctl_putuint(peer_var[id].text, p->hpoll);
 2666         break;
 2667 
 2668     case CP_PRECISION:
 2669         ctl_putint(peer_var[id].text, p->precision);
 2670         break;
 2671 
 2672     case CP_ROOTDELAY:
 2673         ctl_putdbl(peer_var[id].text, p->rootdelay * 1e3);
 2674         break;
 2675 
 2676     case CP_ROOTDISPERSION:
 2677         ctl_putdbl(peer_var[id].text, p->rootdisp * 1e3);
 2678         break;
 2679 
 2680     case CP_REFID:
 2681 #ifdef REFCLOCK
 2682         if (p->flags & FLAG_REFCLOCK) {
 2683             ctl_putrefid(peer_var[id].text, p->refid);
 2684             break;
 2685         }
 2686 #endif
 2687         if (REFID_ISTEXT(p->stratum))
 2688             ctl_putrefid(peer_var[id].text, p->refid);
 2689         else
 2690             ctl_putadr(peer_var[id].text, p->refid, NULL);
 2691         break;
 2692 
 2693     case CP_REFTIME:
 2694         ctl_putts(peer_var[id].text, &p->reftime);
 2695         break;
 2696 
 2697     case CP_ORG:
 2698         ctl_putts(peer_var[id].text, &p->aorg);
 2699         break;
 2700 
 2701     case CP_REC:
 2702         ctl_putts(peer_var[id].text, &p->dst);
 2703         break;
 2704 
 2705     case CP_XMT:
 2706         if (p->xleave)
 2707             ctl_putdbl(peer_var[id].text, p->xleave * 1e3);
 2708         break;
 2709 
 2710     case CP_BIAS:
 2711         if (p->bias != 0.)
 2712             ctl_putdbl(peer_var[id].text, p->bias * 1e3);
 2713         break;
 2714 
 2715     case CP_REACH:
 2716         ctl_puthex(peer_var[id].text, p->reach);
 2717         break;
 2718 
 2719     case CP_FLASH:
 2720         ctl_puthex(peer_var[id].text, p->flash);
 2721         break;
 2722 
 2723     case CP_TTL:
 2724 #ifdef REFCLOCK
 2725         if (p->flags & FLAG_REFCLOCK) {
 2726             ctl_putuint(peer_var[id].text, p->ttl);
 2727             break;
 2728         }
 2729 #endif
 2730         if (p->ttl > 0 && p->ttl < COUNTOF(sys_ttl))
 2731             ctl_putint(peer_var[id].text,
 2732                    sys_ttl[p->ttl]);
 2733         break;
 2734 
 2735     case CP_UNREACH:
 2736         ctl_putuint(peer_var[id].text, p->unreach);
 2737         break;
 2738 
 2739     case CP_TIMER:
 2740         ctl_putuint(peer_var[id].text,
 2741                 p->nextdate - current_time);
 2742         break;
 2743 
 2744     case CP_DELAY:
 2745         ctl_putdbl(peer_var[id].text, p->delay * 1e3);
 2746         break;
 2747 
 2748     case CP_OFFSET:
 2749         ctl_putdbl(peer_var[id].text, p->offset * 1e3);
 2750         break;
 2751 
 2752     case CP_JITTER:
 2753         ctl_putdbl(peer_var[id].text, p->jitter * 1e3);
 2754         break;
 2755 
 2756     case CP_DISPERSION:
 2757         ctl_putdbl(peer_var[id].text, p->disp * 1e3);
 2758         break;
 2759 
 2760     case CP_KEYID:
 2761         if (p->keyid > NTP_MAXKEY)
 2762             ctl_puthex(peer_var[id].text, p->keyid);
 2763         else
 2764             ctl_putuint(peer_var[id].text, p->keyid);
 2765         break;
 2766 
 2767     case CP_FILTDELAY:
 2768         ctl_putarray(peer_var[id].text, p->filter_delay,
 2769                  p->filter_nextpt);
 2770         break;
 2771 
 2772     case CP_FILTOFFSET:
 2773         ctl_putarray(peer_var[id].text, p->filter_offset,
 2774                  p->filter_nextpt);
 2775         break;
 2776 
 2777     case CP_FILTERROR:
 2778         ctl_putarray(peer_var[id].text, p->filter_disp,
 2779                  p->filter_nextpt);
 2780         break;
 2781 
 2782     case CP_PMODE:
 2783         ctl_putuint(peer_var[id].text, p->pmode);
 2784         break;
 2785 
 2786     case CP_RECEIVED:
 2787         ctl_putuint(peer_var[id].text, p->received);
 2788         break;
 2789 
 2790     case CP_SENT:
 2791         ctl_putuint(peer_var[id].text, p->sent);
 2792         break;
 2793 
 2794     case CP_VARLIST:
 2795         s = buf;
 2796         be = buf + sizeof(buf);
 2797         if (strlen(peer_var[id].text) + 4 > sizeof(buf))
 2798             break;  /* really long var name */
 2799 
 2800         snprintf(s, sizeof(buf), "%s=\"", peer_var[id].text);
 2801         s += strlen(s);
 2802         t = s;
 2803         for (k = peer_var; !(EOV & k->flags); k++) {
 2804             if (PADDING & k->flags)
 2805                 continue;
 2806             i = strlen(k->text);
 2807             if (s + i + 1 >= be)
 2808                 break;
 2809             if (s != t)
 2810                 *s++ = ',';
 2811             memcpy(s, k->text, i);
 2812             s += i;
 2813         }
 2814         if (s + 2 < be) {
 2815             *s++ = '"';
 2816             *s = '\0';
 2817             ctl_putdata(buf, (u_int)(s - buf), 0);
 2818         }
 2819         break;
 2820 
 2821     case CP_TIMEREC:
 2822         ctl_putuint(peer_var[id].text,
 2823                 current_time - p->timereceived);
 2824         break;
 2825 
 2826     case CP_TIMEREACH:
 2827         ctl_putuint(peer_var[id].text,
 2828                 current_time - p->timereachable);
 2829         break;
 2830 
 2831     case CP_BADAUTH:
 2832         ctl_putuint(peer_var[id].text, p->badauth);
 2833         break;
 2834 
 2835     case CP_BOGUSORG:
 2836         ctl_putuint(peer_var[id].text, p->bogusorg);
 2837         break;
 2838 
 2839     case CP_OLDPKT:
 2840         ctl_putuint(peer_var[id].text, p->oldpkt);
 2841         break;
 2842 
 2843     case CP_SELDISP:
 2844         ctl_putuint(peer_var[id].text, p->seldisptoolarge);
 2845         break;
 2846 
 2847     case CP_SELBROKEN:
 2848         ctl_putuint(peer_var[id].text, p->selbroken);
 2849         break;
 2850 
 2851     case CP_CANDIDATE:
 2852         ctl_putuint(peer_var[id].text, p->status);
 2853         break;
 2854 #ifdef AUTOKEY
 2855     case CP_FLAGS:
 2856         if (p->crypto)
 2857             ctl_puthex(peer_var[id].text, p->crypto);
 2858         break;
 2859 
 2860     case CP_SIGNATURE:
 2861         if (p->crypto) {
 2862             dp = EVP_get_digestbynid(p->crypto >> 16);
 2863             str = OBJ_nid2ln(EVP_MD_pkey_type(dp));
 2864             ctl_putstr(peer_var[id].text, str, strlen(str));
 2865         }
 2866         break;
 2867 
 2868     case CP_HOST:
 2869         if (p->subject != NULL)
 2870             ctl_putstr(peer_var[id].text, p->subject,
 2871                 strlen(p->subject));
 2872         break;
 2873 
 2874     case CP_VALID:      /* not used */
 2875         break;
 2876 
 2877     case CP_INITSEQ:
 2878         if (NULL == (ap = p->recval.ptr))
 2879             break;
 2880 
 2881         ctl_putint(peer_var[CP_INITSEQ].text, ap->seq);
 2882         ctl_puthex(peer_var[CP_INITKEY].text, ap->key);
 2883         ctl_putfs(peer_var[CP_INITTSP].text,
 2884               ntohl(p->recval.tstamp));
 2885         break;
 2886 
 2887     case CP_IDENT:
 2888         if (p->ident != NULL)
 2889             ctl_putstr(peer_var[id].text, p->ident,
 2890                 strlen(p->ident));
 2891         break;
 2892 
 2893 
 2894 #endif  /* AUTOKEY */
 2895     }
 2896 }
 2897 
 2898 
 2899 #ifdef REFCLOCK
 2900 /*
 2901  * ctl_putclock - output clock variables
 2902  */
 2903 static void
 2904 ctl_putclock(
 2905     int id,
 2906     struct refclockstat *pcs,
 2907     int mustput
 2908     )
 2909 {
 2910     char buf[CTL_MAX_DATA_LEN];
 2911     char *s, *t, *be;
 2912     const char *ss;
 2913     int i;
 2914     const struct ctl_var *k;
 2915 
 2916     switch (id) {
 2917 
 2918     case CC_TYPE:
 2919         if (mustput || pcs->clockdesc == NULL
 2920             || *(pcs->clockdesc) == '\0') {
 2921             ctl_putuint(clock_var[id].text, pcs->type);
 2922         }
 2923         break;
 2924     case CC_TIMECODE:
 2925         ctl_putstr(clock_var[id].text,
 2926                pcs->p_lastcode,
 2927                (unsigned)pcs->lencode);
 2928         break;
 2929 
 2930     case CC_POLL:
 2931         ctl_putuint(clock_var[id].text, pcs->polls);
 2932         break;
 2933 
 2934     case CC_NOREPLY:
 2935         ctl_putuint(clock_var[id].text,
 2936                 pcs->noresponse);
 2937         break;
 2938 
 2939     case CC_BADFORMAT:
 2940         ctl_putuint(clock_var[id].text,
 2941                 pcs->badformat);
 2942         break;
 2943 
 2944     case CC_BADDATA:
 2945         ctl_putuint(clock_var[id].text,
 2946                 pcs->baddata);
 2947         break;
 2948 
 2949     case CC_FUDGETIME1:
 2950         if (mustput || (pcs->haveflags & CLK_HAVETIME1))
 2951             ctl_putdbl(clock_var[id].text,
 2952                    pcs->fudgetime1 * 1e3);
 2953         break;
 2954 
 2955     case CC_FUDGETIME2:
 2956         if (mustput || (pcs->haveflags & CLK_HAVETIME2))
 2957             ctl_putdbl(clock_var[id].text,
 2958                    pcs->fudgetime2 * 1e3);
 2959         break;
 2960 
 2961     case CC_FUDGEVAL1:
 2962         if (mustput || (pcs->haveflags & CLK_HAVEVAL1))
 2963             ctl_putint(clock_var[id].text,
 2964                    pcs->fudgeval1);
 2965         break;
 2966 
 2967     case CC_FUDGEVAL2:
 2968         /* RefID of clocks are always text even if stratum is fudged */
 2969         if (mustput || (pcs->haveflags & CLK_HAVEVAL2))
 2970             ctl_putrefid(clock_var[id].text, pcs->fudgeval2);
 2971         break;
 2972 
 2973     case CC_FLAGS:
 2974         ctl_putuint(clock_var[id].text, pcs->flags);
 2975         break;
 2976 
 2977     case CC_DEVICE:
 2978         if (pcs->clockdesc == NULL ||
 2979             *(pcs->clockdesc) == '\0') {
 2980             if (mustput)
 2981                 ctl_putstr(clock_var[id].text,
 2982                        "", 0);
 2983         } else {
 2984             ctl_putstr(clock_var[id].text,
 2985                    pcs->clockdesc,
 2986                    strlen(pcs->clockdesc));
 2987         }
 2988         break;
 2989 
 2990     case CC_VARLIST:
 2991         s = buf;
 2992         be = buf + sizeof(buf);
 2993         if (strlen(clock_var[CC_VARLIST].text) + 4 >
 2994             sizeof(buf))
 2995             break;  /* really long var name */
 2996 
 2997         snprintf(s, sizeof(buf), "%s=\"",
 2998              clock_var[CC_VARLIST].text);
 2999         s += strlen(s);
 3000         t = s;
 3001 
 3002         for (k = clock_var; !(EOV & k->flags); k++) {
 3003             if (PADDING & k->flags)
 3004                 continue;
 3005 
 3006             i = strlen(k->text);
 3007             if (s + i + 1 >= be)
 3008                 break;
 3009 
 3010             if (s != t)
 3011                 *s++ = ',';
 3012             memcpy(s, k->text, i);
 3013             s += i;
 3014         }
 3015 
 3016         for (k = pcs->kv_list; k && !(EOV & k->flags); k++) {
 3017             if (PADDING & k->flags)
 3018                 continue;
 3019 
 3020             ss = k->text;
 3021             if (NULL == ss)
 3022                 continue;
 3023 
 3024             while (*ss && *ss != '=')
 3025                 ss++;
 3026             i = ss - k->text;
 3027             if (s + i + 1 >= be)
 3028                 break;
 3029 
 3030             if (s != t)
 3031                 *s++ = ',';
 3032             memcpy(s, k->text, (unsigned)i);
 3033             s += i;
 3034             *s = '\0';
 3035         }
 3036         if (s + 2 >= be)
 3037             break;
 3038 
 3039         *s++ = '"';
 3040         *s = '\0';
 3041         ctl_putdata(buf, (unsigned)(s - buf), 0);
 3042         break;
 3043         
 3044     case CC_FUDGEMINJIT:
 3045         if (mustput || (pcs->haveflags & CLK_HAVEMINJIT))
 3046             ctl_putdbl(clock_var[id].text,
 3047                    pcs->fudgeminjitter * 1e3);
 3048         break;
 3049 
 3050     default:
 3051         break;
 3052 
 3053     }
 3054 }
 3055 #endif
 3056 
 3057 
 3058 
 3059 /*
 3060  * ctl_getitem - get the next data item from the incoming packet
 3061  */
 3062 static const struct ctl_var *
 3063 ctl_getitem(
 3064     const struct ctl_var *var_list,
 3065     char **data
 3066     )
 3067 {
 3068     /* [Bug 3008] First check the packet data sanity, then search
 3069      * the key. This improves the consistency of result values: If
 3070      * the result is NULL once, it will never be EOV again for this
 3071      * packet; If it's EOV, it will never be NULL again until the
 3072      * variable is found and processed in a given 'var_list'. (That
 3073      * is, a result is returned that is neither NULL nor EOV).
 3074      */
 3075     static const struct ctl_var eol = { 0, EOV, NULL };
 3076     static char buf[128];
 3077     static u_long quiet_until;
 3078     const struct ctl_var *v;
 3079     char *cp;
 3080     char *tp;
 3081 
 3082     /*
 3083      * Part One: Validate the packet state
 3084      */
 3085 
 3086     /* Delete leading commas and white space */
 3087     while (reqpt < reqend && (*reqpt == ',' ||
 3088                   isspace((unsigned char)*reqpt)))
 3089         reqpt++;
 3090     if (reqpt >= reqend)
 3091         return NULL;
 3092 
 3093     /* Scan the string in the packet until we hit comma or
 3094      * EoB. Register position of first '=' on the fly. */
 3095     for (tp = NULL, cp = reqpt; cp != reqend; ++cp) {
 3096         if (*cp == '=' && tp == NULL)
 3097             tp = cp;
 3098         if (*cp == ',')
 3099             break;
 3100     }
 3101 
 3102     /* Process payload, if any. */
 3103     *data = NULL;
 3104     if (NULL != tp) {
 3105         /* eventually strip white space from argument. */
 3106         const char *plhead = tp + 1; /* skip the '=' */
 3107         const char *pltail = cp;
 3108         size_t      plsize;
 3109 
 3110         while (plhead != pltail && isspace((u_char)plhead[0]))
 3111             ++plhead;
 3112         while (plhead != pltail && isspace((u_char)pltail[-1]))
 3113             --pltail;
 3114 
 3115         /* check payload size, terminate packet on overflow */
 3116         plsize = (size_t)(pltail - plhead);
 3117         if (plsize >= sizeof(buf))
 3118             goto badpacket;
 3119 
 3120         /* copy data, NUL terminate, and set result data ptr */
 3121         memcpy(buf, plhead, plsize);
 3122         buf[plsize] = '\0';
 3123         *data = buf;
 3124     } else {
 3125         /* no payload, current end --> current name termination */
 3126         tp = cp;
 3127     }
 3128 
 3129     /* Part Two
 3130      *
 3131      * Now we're sure that the packet data itself is sane. Scan the
 3132      * list now. Make sure a NULL list is properly treated by
 3133      * returning a synthetic End-Of-Values record. We must not
 3134      * return NULL pointers after this point, or the behaviour would
 3135      * become inconsistent if called several times with different
 3136      * variable lists after an EoV was returned.  (Such a behavior
 3137      * actually caused Bug 3008.)
 3138      */
 3139 
 3140     if (NULL == var_list)
 3141         return &eol;
 3142 
 3143     for (v = var_list; !(EOV & v->flags); ++v)
 3144         if (!(PADDING & v->flags)) {
 3145             /* Check if the var name matches the buffer. The
 3146              * name is bracketed by [reqpt..tp] and not NUL
 3147              * terminated, and it contains no '=' char. The
 3148              * lookup value IS NUL-terminated but might
 3149              * include a '='... We have to look out for
 3150              * that!
 3151              */
 3152             const char *sp1 = reqpt;
 3153             const char *sp2 = v->text;
 3154 
 3155             /* [Bug 3412] do not compare past NUL byte in name */
 3156             while (   (sp1 != tp)
 3157                    && ('\0' != *sp2) && (*sp1 == *sp2)) {
 3158                 ++sp1;
 3159                 ++sp2;
 3160             }
 3161             if (sp1 == tp && (*sp2 == '\0' || *sp2 == '='))
 3162                 break;
 3163         }
 3164 
 3165     /* See if we have found a valid entry or not. If found, advance
 3166      * the request pointer for the next round; if not, clear the
 3167      * data pointer so we have no dangling garbage here.
 3168      */
 3169     if (EOV & v->flags)
 3170         *data = NULL;
 3171     else
 3172         reqpt = cp + (cp != reqend);
 3173     return v;
 3174 
 3175   badpacket:
 3176     /*TODO? somehow indicate this packet was bad, apart from syslog? */
 3177     numctlbadpkts++;
 3178     NLOG(NLOG_SYSEVENT)
 3179         if (quiet_until <= current_time) {
 3180             quiet_until = current_time + 300;
 3181             msyslog(LOG_WARNING,
 3182                 "Possible 'ntpdx' exploit from %s#%u (possibly spoofed)",
 3183                 stoa(rmt_addr), SRCPORT(rmt_addr));
 3184         }
 3185     reqpt = reqend; /* never again for this packet! */
 3186     return NULL;
 3187 }
 3188 
 3189 
 3190 /*
 3191  * control_unspec - response to an unspecified op-code
 3192  */
 3193 /*ARGSUSED*/
 3194 static void
 3195 control_unspec(
 3196     struct recvbuf *rbufp,
 3197     int restrict_mask
 3198     )
 3199 {
 3200     struct peer *peer;
 3201 
 3202     /*
 3203      * What is an appropriate response to an unspecified op-code?
 3204      * I return no errors and no data, unless a specified assocation
 3205      * doesn't exist.
 3206      */
 3207     if (res_associd) {
 3208         peer = findpeerbyassoc(res_associd);
 3209         if (NULL == peer) {
 3210             ctl_error(CERR_BADASSOC);
 3211             return;
 3212         }
 3213         rpkt.status = htons(ctlpeerstatus(peer));
 3214     } else
 3215         rpkt.status = htons(ctlsysstatus());
 3216     ctl_flushpkt(0);
 3217 }
 3218 
 3219 
 3220 /*
 3221  * read_status - return either a list of associd's, or a particular
 3222  * peer's status.
 3223  */
 3224 /*ARGSUSED*/
 3225 static void
 3226 read_status(
 3227     struct recvbuf *rbufp,
 3228     int restrict_mask
 3229     )
 3230 {
 3231     struct peer *peer;
 3232     const u_char *cp;
 3233     size_t n;
 3234     /* a_st holds association ID, status pairs alternating */
 3235     u_short a_st[CTL_MAX_DATA_LEN / sizeof(u_short)];
 3236 
 3237 #ifdef DEBUG
 3238     if (debug > 2)
 3239         printf("read_status: ID %d\n", res_associd);
 3240 #endif
 3241     /*
 3242      * Two choices here. If the specified association ID is
 3243      * zero we return all known assocation ID's.  Otherwise
 3244      * we return a bunch of stuff about the particular peer.
 3245      */
 3246     if (res_associd) {
 3247         peer = findpeerbyassoc(res_associd);
 3248         if (NULL == peer) {
 3249             ctl_error(CERR_BADASSOC);
 3250             return;
 3251         }
 3252         rpkt.status = htons(ctlpeerstatus(peer));
 3253         if (res_authokay)
 3254             peer->num_events = 0;
 3255         /*
 3256          * For now, output everything we know about the
 3257          * peer. May be more selective later.
 3258          */
 3259         for (cp = def_peer_var; *cp != 0; cp++)
 3260             ctl_putpeer((int)*cp, peer);
 3261         ctl_flushpkt(0);
 3262         return;
 3263     }
 3264     n = 0;
 3265     rpkt.status = htons(ctlsysstatus());
 3266     for (peer = peer_list; peer != NULL; peer = peer->p_link) {
 3267         a_st[n++] = htons(peer->associd);
 3268         a_st[n++] = htons(ctlpeerstatus(peer));
 3269         /* two entries each loop iteration, so n + 1 */
 3270         if (n + 1 >= COUNTOF(a_st)) {
 3271             ctl_putdata((void *)a_st, n * sizeof(a_st[0]),
 3272                     1);
 3273             n = 0;
 3274         }
 3275     }
 3276     if (n)
 3277         ctl_putdata((void *)a_st, n * sizeof(a_st[0]), 1);
 3278     ctl_flushpkt(0);
 3279 }
 3280 
 3281 
 3282 /*
 3283  * read_peervars - half of read_variables() implementation
 3284  */
 3285 static void
 3286 read_peervars(void)
 3287 {
 3288     const struct ctl_var *v;
 3289     struct peer *peer;
 3290     const u_char *cp;
 3291     size_t i;
 3292     char *  valuep;
 3293     u_char  wants[CP_MAXCODE + 1];
 3294     u_int   gotvar;
 3295 
 3296     /*
 3297      * Wants info for a particular peer. See if we know
 3298      * the guy.
 3299      */
 3300     peer = findpeerbyassoc(res_associd);
 3301     if (NULL == peer) {
 3302         ctl_error(CERR_BADASSOC);
 3303         return;
 3304     }
 3305     rpkt.status = htons(ctlpeerstatus(peer));
 3306     if (res_authokay)
 3307         peer->num_events = 0;
 3308     ZERO(wants);
 3309     gotvar = 0;
 3310     while (NULL != (v = ctl_getitem(peer_var, &valuep))) {
 3311         if (v->flags & EOV) {
 3312             ctl_error(CERR_UNKNOWNVAR);
 3313             return;
 3314         }
 3315         INSIST(v->code < COUNTOF(wants));
 3316         wants[v->code] = 1;
 3317         gotvar = 1;
 3318     }
 3319     if (gotvar) {
 3320         for (i = 1; i < COUNTOF(wants); i++)
 3321             if (wants[i])
 3322                 ctl_putpeer(i, peer);
 3323     } else
 3324         for (cp = def_peer_var; *cp != 0; cp++)
 3325             ctl_putpeer((int)*cp, peer);
 3326     ctl_flushpkt(0);
 3327 }
 3328 
 3329 
 3330 /*
 3331  * read_sysvars - half of read_variables() implementation
 3332  */
 3333 static void
 3334 read_sysvars(void)
 3335 {
 3336     const struct ctl_var *v;
 3337     struct ctl_var *kv;
 3338     u_int   n;
 3339     u_int   gotvar;
 3340     const u_char *cs;
 3341     char *  valuep;
 3342     const char * pch;
 3343     u_char *wants;
 3344     size_t  wants_count;
 3345 
 3346     /*
 3347      * Wants system variables. Figure out which he wants
 3348      * and give them to him.
 3349      */
 3350     rpkt.status = htons(ctlsysstatus());
 3351     if (res_authokay)
 3352         ctl_sys_num_events = 0;
 3353     wants_count = CS_MAXCODE + 1 + count_var(ext_sys_var);
 3354     wants = emalloc_zero(wants_count);
 3355     gotvar = 0;
 3356     while (NULL != (v = ctl_getitem(sys_var, &valuep))) {
 3357         if (!(EOV & v->flags)) {
 3358             INSIST(v->code < wants_count);
 3359             wants[v->code] = 1;
 3360             gotvar = 1;
 3361         } else {
 3362             v = ctl_getitem(ext_sys_var, &valuep);
 3363             if (NULL == v) {
 3364                 ctl_error(CERR_BADVALUE);
 3365                 free(wants);
 3366                 return;
 3367             }
 3368             if (EOV & v->flags) {
 3369                 ctl_error(CERR_UNKNOWNVAR);
 3370                 free(wants);
 3371                 return;
 3372             }
 3373             n = v->code + CS_MAXCODE + 1;
 3374             INSIST(n < wants_count);
 3375             wants[n] = 1;
 3376             gotvar = 1;
 3377         }
 3378     }
 3379     if (gotvar) {
 3380         for (n = 1; n <= CS_MAXCODE; n++)
 3381             if (wants[n])
 3382                 ctl_putsys(n);
 3383         for (n = 0; n + CS_MAXCODE + 1 < wants_count; n++)
 3384             if (wants[n + CS_MAXCODE + 1]) {
 3385                 pch = ext_sys_var[n].text;
 3386                 ctl_putdata(pch, strlen(pch), 0);
 3387             }
 3388     } else {
 3389         for (cs = def_sys_var; *cs != 0; cs++)
 3390             ctl_putsys((int)*cs);
 3391         for (kv = ext_sys_var; kv && !(EOV & kv->flags); kv++)
 3392             if (DEF & kv->flags)
 3393                 ctl_putdata(kv->text, strlen(kv->text),
 3394                         0);
 3395     }
 3396     free(wants);
 3397     ctl_flushpkt(0);
 3398 }
 3399 
 3400 
 3401 /*
 3402  * read_variables - return the variables the caller asks for
 3403  */
 3404 /*ARGSUSED*/
 3405 static void
 3406 read_variables(
 3407     struct recvbuf *rbufp,
 3408     int restrict_mask
 3409     )
 3410 {
 3411     if (res_associd)
 3412         read_peervars();
 3413     else
 3414         read_sysvars();
 3415 }
 3416 
 3417 
 3418 /*
 3419  * write_variables - write into variables. We only allow leap bit
 3420  * writing this way.
 3421  */
 3422 /*ARGSUSED*/
 3423 static void
 3424 write_variables(
 3425     struct recvbuf *rbufp,
 3426     int restrict_mask
 3427     )
 3428 {
 3429     const struct ctl_var *v;
 3430     int ext_var;
 3431     char *valuep;
 3432     long val;
 3433     size_t octets;
 3434     char *vareqv;
 3435     const char *t;
 3436     char *tt;
 3437 
 3438     val = 0;
 3439     /*
 3440      * If he's trying to write into a peer tell him no way
 3441      */
 3442     if (res_associd != 0) {
 3443         ctl_error(CERR_PERMISSION);
 3444         return;
 3445     }
 3446 
 3447     /*
 3448      * Set status
 3449      */
 3450     rpkt.status = htons(ctlsysstatus());
 3451 
 3452     /*
 3453      * Look through the variables. Dump out at the first sign of
 3454      * trouble.
 3455      */
 3456     while ((v = ctl_getitem(sys_var, &valuep)) != NULL) {
 3457         ext_var = 0;
 3458         if (v->flags & EOV) {
 3459             v = ctl_getitem(ext_sys_var, &valuep);
 3460             if (v != NULL) {
 3461                 if (v->flags & EOV) {
 3462                     ctl_error(CERR_UNKNOWNVAR);
 3463                     return;
 3464                 }
 3465                 ext_var = 1;
 3466             } else {
 3467                 break;
 3468             }
 3469         }
 3470         if (!(v->flags & CAN_WRITE)) {
 3471             ctl_error(CERR_PERMISSION);
 3472             return;
 3473         }
 3474         /* [bug 3565] writing makes sense only if we *have* a
 3475          * value in the packet!
 3476          */
 3477         if (valuep == NULL) {
 3478             ctl_error(CERR_BADFMT);
 3479             return;
 3480         }
 3481         if (!ext_var) {
 3482             if ( !(*valuep && atoint(valuep, &val))) {
 3483                 ctl_error(CERR_BADFMT);
 3484                 return;
 3485             }
 3486             if ((val & ~LEAP_NOTINSYNC) != 0) {
 3487                 ctl_error(CERR_BADVALUE);
 3488                 return;
 3489             }
 3490         }
 3491         
 3492         if (ext_var) {
 3493             octets = strlen(v->text) + strlen(valuep) + 2;
 3494             vareqv = emalloc(octets);
 3495             tt = vareqv;
 3496             t = v->text;
 3497             while (*t && *t != '=')
 3498                 *tt++ = *t++;
 3499             *tt++ = '=';
 3500             memcpy(tt, valuep, 1 + strlen(valuep));
 3501             set_sys_var(vareqv, 1 + strlen(vareqv), v->flags);
 3502             free(vareqv);
 3503         } else {
 3504             ctl_error(CERR_UNSPEC); /* really */
 3505             return;
 3506         }
 3507     }
 3508 
 3509     /*
 3510      * If we got anything, do it. xxx nothing to do ***
 3511      */
 3512     /*
 3513       if (leapind != ~0 || leapwarn != ~0) {
 3514       if (!leap_setleap((int)leapind, (int)leapwarn)) {
 3515       ctl_error(CERR_PERMISSION);
 3516       return;
 3517       }
 3518       }
 3519     */
 3520     ctl_flushpkt(0);
 3521 }
 3522 
 3523 
 3524 /*
 3525  * configure() processes ntpq :config/config-from-file, allowing
 3526  *      generic runtime reconfiguration.
 3527  */
 3528 static void configure(
 3529     struct recvbuf *rbufp,
 3530     int restrict_mask
 3531     )
 3532 {
 3533     size_t data_count;
 3534     int retval;
 3535 
 3536     /* I haven't yet implemented changes to an existing association.
 3537      * Hence check if the association id is 0
 3538      */
 3539     if (res_associd != 0) {
 3540         ctl_error(CERR_BADVALUE);
 3541         return;
 3542     }
 3543 
 3544     if (RES_NOMODIFY & restrict_mask) {
 3545         snprintf(remote_config.err_msg,
 3546              sizeof(remote_config.err_msg),
 3547              "runtime configuration prohibited by restrict ... nomodify");
 3548         ctl_putdata(remote_config.err_msg,
 3549                 strlen(remote_config.err_msg), 0);
 3550         ctl_flushpkt(0);
 3551         NLOG(NLOG_SYSINFO)
 3552             msyslog(LOG_NOTICE,
 3553                 "runtime config from %s rejected due to nomodify restriction",
 3554                 stoa(&rbufp->recv_srcadr));
 3555         sys_restricted++;
 3556         return;
 3557     }
 3558 
 3559     /* Initialize the remote config buffer */
 3560     data_count = remoteconfig_cmdlength(reqpt, reqend);
 3561 
 3562     if (data_count > sizeof(remote_config.buffer) - 2) {
 3563         snprintf(remote_config.err_msg,
 3564              sizeof(remote_config.err_msg),
 3565              "runtime configuration failed: request too long");
 3566         ctl_putdata(remote_config.err_msg,
 3567                 strlen(remote_config.err_msg), 0);
 3568         ctl_flushpkt(0);
 3569         msyslog(LOG_NOTICE,
 3570             "runtime config from %s rejected: request too long",
 3571             stoa(&rbufp->recv_srcadr));
 3572         return;
 3573     }
 3574     /* Bug 2853 -- check if all characters were acceptable */
 3575     if (data_count != (size_t)(reqend - reqpt)) {
 3576         snprintf(remote_config.err_msg,
 3577              sizeof(remote_config.err_msg),
 3578              "runtime configuration failed: request contains an unprintable character");
 3579         ctl_putdata(remote_config.err_msg,
 3580                 strlen(remote_config.err_msg), 0);
 3581         ctl_flushpkt(0);
 3582         msyslog(LOG_NOTICE,
 3583             "runtime config from %s rejected: request contains an unprintable character: %0x",
 3584             stoa(&rbufp->recv_srcadr),
 3585             reqpt[data_count]);
 3586         return;
 3587     }
 3588 
 3589     memcpy(remote_config.buffer, reqpt, data_count);
 3590     /* The buffer has no trailing linefeed or NUL right now. For
 3591      * logging, we do not want a newline, so we do that first after
 3592      * adding the necessary NUL byte.
 3593      */
 3594     remote_config.buffer[data_count] = '\0';
 3595     DPRINTF(1, ("Got Remote Configuration Command: %s\n",
 3596         remote_config.buffer));
 3597     msyslog(LOG_NOTICE, "%s config: %s",
 3598         stoa(&rbufp->recv_srcadr),
 3599         remote_config.buffer);
 3600 
 3601     /* Now we have to make sure there is a NL/NUL sequence at the
 3602      * end of the buffer before we parse it.
 3603      */
 3604     remote_config.buffer[data_count++] = '\n';
 3605     remote_config.buffer[data_count] = '\0';
 3606     remote_config.pos = 0;
 3607     remote_config.err_pos = 0;
 3608     remote_config.no_errors = 0;
 3609     config_remotely(&rbufp->recv_srcadr);
 3610 
 3611     /*
 3612      * Check if errors were reported. If not, output 'Config
 3613      * Succeeded'.  Else output the error count.  It would be nice
 3614      * to output any parser error messages.
 3615      */
 3616     if (0 == remote_config.no_errors) {
 3617         retval = snprintf(remote_config.err_msg,
 3618                   sizeof(remote_config.err_msg),
 3619                   "Config Succeeded");
 3620         if (retval > 0)
 3621             remote_config.err_pos += retval;
 3622     }
 3623 
 3624     ctl_putdata(remote_config.err_msg, remote_config.err_pos, 0);
 3625     ctl_flushpkt(0);
 3626 
 3627     DPRINTF(1, ("Reply: %s\n", remote_config.err_msg));
 3628 
 3629     if (remote_config.no_errors > 0)
 3630         msyslog(LOG_NOTICE, "%d error in %s config",
 3631             remote_config.no_errors,
 3632             stoa(&rbufp->recv_srcadr));
 3633 }
 3634 
 3635 
 3636 /*
 3637  * derive_nonce - generate client-address-specific nonce value
 3638  *        associated with a given timestamp.
 3639  */
 3640 static u_int32 derive_nonce(
 3641     sockaddr_u *    addr,
 3642     u_int32     ts_i,
 3643     u_int32     ts_f
 3644     )
 3645 {
 3646     static u_int32  salt[4];
 3647     static u_long   last_salt_update;
 3648     union d_tag {
 3649         u_char  digest[EVP_MAX_MD_SIZE];
 3650         u_int32 extract;
 3651     }       d;
 3652     EVP_MD_CTX  *ctx;
 3653     u_int       len;
 3654     int rc;
 3655 
 3656     while (!salt[0] || current_time - last_salt_update >= 3600) {
 3657         salt[0] = ntp_random();
 3658         salt[1] = ntp_random();
 3659         salt[2] = ntp_random();
 3660         salt[3] = ntp_random();
 3661         last_salt_update = current_time;
 3662     }
 3663 
 3664     ctx = EVP_MD_CTX_new();
 3665 #   if defined(OPENSSL) && defined(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)
 3666     /* [Bug 3457] set flags and don't kill them again */
 3667     EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
 3668     rc = EVP_DigestInit_ex(ctx, EVP_get_digestbynid(NID_md5), NULL);
 3669 #   else
 3670     rc = EVP_DigestInit(ctx, EVP_get_digestbynid(NID_md5));
 3671 #   endif
 3672     if (!rc) {
 3673         msyslog(LOG_ERR, "EVP_DigestInit failed in '%s'", __func__);
 3674         return (0);
 3675     }
 3676 
 3677     EVP_DigestUpdate(ctx, salt, sizeof(salt));
 3678     EVP_DigestUpdate(ctx, &ts_i, sizeof(ts_i));
 3679     EVP_DigestUpdate(ctx, &ts_f, sizeof(ts_f));
 3680     if (IS_IPV4(addr))
 3681         EVP_DigestUpdate(ctx, &SOCK_ADDR4(addr),
 3682                      sizeof(SOCK_ADDR4(addr)));
 3683     else
 3684         EVP_DigestUpdate(ctx, &SOCK_ADDR6(addr),
 3685                      sizeof(SOCK_ADDR6(addr)));
 3686     EVP_DigestUpdate(ctx, &NSRCPORT(addr), sizeof(NSRCPORT(addr)));
 3687     EVP_DigestUpdate(ctx, salt, sizeof(salt));
 3688     EVP_DigestFinal(ctx, d.digest, &len);
 3689     EVP_MD_CTX_free(ctx);
 3690 
 3691     return d.extract;
 3692 }
 3693 
 3694 
 3695 /*
 3696  * generate_nonce - generate client-address-specific nonce string.
 3697  */
 3698 static void generate_nonce(
 3699     struct recvbuf *    rbufp,
 3700     char *          nonce,
 3701     size_t          nonce_octets
 3702     )
 3703 {
 3704     u_int32 derived;
 3705 
 3706     derived = derive_nonce(&rbufp->recv_srcadr,
 3707                    rbufp->recv_time.l_ui,
 3708                    rbufp->recv_time.l_uf);
 3709     snprintf(nonce, nonce_octets, "%08x%08x%08x",
 3710          rbufp->recv_time.l_ui, rbufp->recv_time.l_uf, derived);
 3711 }
 3712 
 3713 
 3714 /*
 3715  * validate_nonce - validate client-address-specific nonce string.
 3716  *
 3717  * Returns TRUE if the local calculation of the nonce matches the
 3718  * client-provided value and the timestamp is recent enough.
 3719  */
 3720 static int validate_nonce(
 3721     const char *        pnonce,
 3722     struct recvbuf *    rbufp
 3723     )
 3724 {
 3725     u_int   ts_i;
 3726     u_int   ts_f;
 3727     l_fp    ts;
 3728     l_fp    now_delta;
 3729     u_int   supposed;
 3730     u_int   derived;
 3731 
 3732     if (3 != sscanf(pnonce, "%08x%08x%08x", &ts_i, &ts_f, &supposed))
 3733         return FALSE;
 3734 
 3735     ts.l_ui = (u_int32)ts_i;
 3736     ts.l_uf = (u_int32)ts_f;
 3737     derived = derive_nonce(&rbufp->recv_srcadr, ts.l_ui, ts.l_uf);
 3738     get_systime(&now_delta);
 3739     L_SUB(&now_delta, &ts);
 3740 
 3741     return (supposed == derived && now_delta.l_ui < 16);
 3742 }
 3743 
 3744 
 3745 /*
 3746  * send_random_tag_value - send a randomly-generated three character
 3747  *             tag prefix, a '.', an index, a '=' and a
 3748  *             random integer value.
 3749  *
 3750  * To try to force clients to ignore unrecognized tags in mrulist,
 3751  * reslist, and ifstats responses, the first and last rows are spiced
 3752  * with randomly-generated tag names with correct .# index.  Make it
 3753  * three characters knowing that none of the currently-used subscripted
 3754  * tags have that length, avoiding the need to test for
 3755  * tag collision.
 3756  */
 3757 static void
 3758 send_random_tag_value(
 3759     int indx
 3760     )
 3761 {
 3762     int noise;
 3763     char    buf[32];
 3764 
 3765     noise = rand() ^ (rand() << 16);
 3766     buf[0] = 'a' + noise % 26;
 3767     noise >>= 5;
 3768     buf[1] = 'a' + noise % 26;
 3769     noise >>= 5;
 3770     buf[2] = 'a' + noise % 26;
 3771     noise >>= 5;
 3772     buf[3] = '.';
 3773     snprintf(&buf[4], sizeof(buf) - 4, "%d", indx);
 3774     ctl_putuint(buf, noise);
 3775 }
 3776 
 3777 
 3778 /*
 3779  * Send a MRU list entry in response to a "ntpq -c mrulist" operation.
 3780  *
 3781  * To keep clients honest about not depending on the order of values,
 3782  * and thereby avoid being locked into ugly workarounds to maintain
 3783  * backward compatibility later as new fields are added to the response,
 3784  * the order is random.
 3785  */
 3786 static void
 3787 send_mru_entry(
 3788     mon_entry * mon,
 3789     int     count
 3790     )
 3791 {
 3792     const char first_fmt[] =    "first.%d";
 3793     const char ct_fmt[] =       "ct.%d";
 3794     const char mv_fmt[] =       "mv.%d";
 3795     const char rs_fmt[] =       "rs.%d";
 3796     char    tag[32];
 3797     u_char  sent[6]; /* 6 tag=value pairs */
 3798     u_int32 noise;
 3799     u_int   which;
 3800     u_int   remaining;
 3801     const char * pch;
 3802 
 3803     remaining = COUNTOF(sent);
 3804     ZERO(sent);
 3805     noise = (u_int32)(rand() ^ (rand() << 16));
 3806     while (remaining > 0) {
 3807         which = (noise & 7) % COUNTOF(sent);
 3808         noise >>= 3;
 3809         while (sent[which])
 3810             which = (which + 1) % COUNTOF(sent);
 3811 
 3812         switch (which) {
 3813 
 3814         case 0:
 3815             snprintf(tag, sizeof(tag), addr_fmt, count);
 3816             pch = sptoa(&mon->rmtadr);
 3817             ctl_putunqstr(tag, pch, strlen(pch));
 3818             break;
 3819 
 3820         case 1:
 3821             snprintf(tag, sizeof(tag), last_fmt, count);
 3822             ctl_putts(tag, &mon->last);
 3823             break;
 3824 
 3825         case 2:
 3826             snprintf(tag, sizeof(tag), first_fmt, count);
 3827             ctl_putts(tag, &mon->first);
 3828             break;
 3829 
 3830         case 3:
 3831             snprintf(tag, sizeof(tag), ct_fmt, count);
 3832             ctl_putint(tag, mon->count);
 3833             break;
 3834 
 3835         case 4:
 3836             snprintf(tag, sizeof(tag), mv_fmt, count);
 3837             ctl_putuint(tag, mon->vn_mode);
 3838             break;
 3839 
 3840         case 5:
 3841             snprintf(tag, sizeof(tag), rs_fmt, count);
 3842             ctl_puthex(tag, mon->flags);
 3843             break;
 3844         }
 3845         sent[which] = TRUE;
 3846         remaining--;
 3847     }
 3848 }
 3849 
 3850 
 3851 /*
 3852  * read_mru_list - supports ntpq's mrulist command.
 3853  *
 3854  * The challenge here is to match ntpdc's monlist functionality without
 3855  * being limited to hundreds of entries returned total, and without
 3856  * requiring state on the server.  If state were required, ntpq's
 3857  * mrulist command would require authentication.
 3858  *
 3859  * The approach was suggested by Ry Jones.  A finite and variable number
 3860  * of entries are retrieved per request, to avoid having responses with
 3861  * such large numbers of packets that socket buffers are overflowed and
 3862  * packets lost.  The entries are retrieved oldest-first, taking into
 3863  * account that the MRU list will be changing between each request.  We
 3864  * can expect to see duplicate entries for addresses updated in the MRU
 3865  * list during the fetch operation.  In the end, the client can assemble
 3866  * a close approximation of the MRU list at the point in time the last
 3867  * response was sent by ntpd.  The only difference is it may be longer,
 3868  * containing some number of oldest entries which have since been
 3869  * reclaimed.  If necessary, the protocol could be extended to zap those
 3870  * from the client snapshot at the end, but so far that doesn't seem
 3871  * useful.
 3872  *
 3873  * To accomodate the changing MRU list, the starting point for requests
 3874  * after the first request is supplied as a series of last seen
 3875  * timestamps and associated addresses, the newest ones the client has
 3876  * received.  As long as at least one of those entries hasn't been
 3877  * bumped to the head of the MRU list, ntpd can pick up at that point.
 3878  * Otherwise, the request is failed and it is up to ntpq to back up and
 3879  * provide the next newest entry's timestamps and addresses, conceivably
 3880  * backing up all the way to the starting point.
 3881  *
 3882  * input parameters:
 3883  *  nonce=      Regurgitated nonce retrieved by the client
 3884  *          previously using CTL_OP_REQ_NONCE, demonstrating
 3885  *          ability to receive traffic sent to its address.
 3886  *  frags=      Limit on datagrams (fragments) in response.  Used
 3887  *          by newer ntpq versions instead of limit= when
 3888  *          retrieving multiple entries.
 3889  *  limit=      Limit on MRU entries returned.  One of frags= or
 3890  *          limit= must be provided.
 3891  *          limit=1 is a special case:  Instead of fetching
 3892  *          beginning with the supplied starting point's
 3893  *          newer neighbor, fetch the supplied entry, and
 3894  *          in that case the #.last timestamp can be zero.
 3895  *          This enables fetching a single entry by IP
 3896  *          address.  When limit is not one and frags= is
 3897  *          provided, the fragment limit controls.
 3898  *  mincount=   (decimal) Return entries with count >= mincount.
 3899  *  laddr=      Return entries associated with the server's IP
 3900  *          address given.  No port specification is needed,
 3901  *          and any supplied is ignored.
 3902  *  resall=     0x-prefixed hex restrict bits which must all be
 3903  *          lit for an MRU entry to be included.
 3904  *          Has precedence over any resany=.
 3905  *  resany=     0x-prefixed hex restrict bits, at least one of
 3906  *          which must be list for an MRU entry to be
 3907  *          included.
 3908  *  last.0=     0x-prefixed hex l_fp timestamp of newest entry
 3909  *          which client previously received.
 3910  *  addr.0=     text of newest entry's IP address and port,
 3911  *          IPv6 addresses in bracketed form: [::]:123
 3912  *  last.1=     timestamp of 2nd newest entry client has.
 3913  *  addr.1=     address of 2nd newest entry.
 3914  *  [...]
 3915  *
 3916  * ntpq provides as many last/addr pairs as will fit in a single request
 3917  * packet, except for the first request in a MRU fetch operation.
 3918  *
 3919  * The response begins with a new nonce value to be used for any
 3920  * followup request.  Following the nonce is the next newer entry than
 3921  * referred to by last.0 and addr.0, if the "0" entry has not been
 3922  * bumped to the front.  If it has, the first entry returned will be the
 3923  * next entry newer than referred to by last.1 and addr.1, and so on.
 3924  * If none of the referenced entries remain unchanged, the request fails
 3925  * and ntpq backs up to the next earlier set of entries to resync.
 3926  *
 3927  * Except for the first response, the response begins with confirmation
 3928  * of the entry that precedes the first additional entry provided:
 3929  *
 3930  *  last.older= hex l_fp timestamp matching one of the input
 3931  *          .last timestamps, which entry now precedes the
 3932  *          response 0. entry in the MRU list.
 3933  *  addr.older= text of address corresponding to older.last.
 3934  *
 3935  * And in any case, a successful response contains sets of values
 3936  * comprising entries, with the oldest numbered 0 and incrementing from
 3937  * there:
 3938  *
 3939  *  addr.#      text of IPv4 or IPv6 address and port
 3940  *  last.#      hex l_fp timestamp of last receipt
 3941  *  first.#     hex l_fp timestamp of first receipt
 3942  *  ct.#        count of packets received
 3943  *  mv.#        mode and version
 3944  *  rs.#        restriction mask (RES_* bits)
 3945  *
 3946  * Note the code currently assumes there are no valid three letter
 3947  * tags sent with each row, and needs to be adjusted if that changes.
 3948  *
 3949  * The client should accept the values in any order, and ignore .#
 3950  * values which it does not understand, to allow a smooth path to
 3951  * future changes without requiring a new opcode.  Clients can rely
 3952  * on all *.0 values preceding any *.1 values, that is all values for
 3953  * a given index number are together in the response.
 3954  *
 3955  * The end of the response list is noted with one or two tag=value
 3956  * pairs.  Unconditionally:
 3957  *
 3958  *  now=        0x-prefixed l_fp timestamp at the server marking
 3959  *          the end of the operation.
 3960  *
 3961  * If any entries were returned, now= is followed by:
 3962  *
 3963  *  last.newest=    hex l_fp identical to last.# of the prior
 3964  *          entry.
 3965  */
 3966 static void read_mru_list(
 3967     struct recvbuf *rbufp,
 3968     int restrict_mask
 3969     )
 3970 {
 3971     static const char   nulltxt[1] =        { '\0' };
 3972     static const char   nonce_text[] =      "nonce";
 3973     static const char   frags_text[] =      "frags";
 3974     static const char   limit_text[] =      "limit";
 3975     static const char   mincount_text[] =   "mincount";
 3976     static const char   resall_text[] =     "resall";
 3977     static const char   resany_text[] =     "resany";
 3978     static const char   maxlstint_text[] =  "maxlstint";
 3979     static const char   laddr_text[] =      "laddr";
 3980     static const char   resaxx_fmt[] =      "0x%hx";
 3981 
 3982     u_int           limit;
 3983     u_short         frags;
 3984     u_short         resall;
 3985     u_short         resany;
 3986     int         mincount;
 3987     u_int           maxlstint;
 3988     sockaddr_u      laddr;
 3989     struct interface *  lcladr;
 3990     u_int           count;
 3991     u_int           ui;
 3992     u_int           uf;
 3993     l_fp            last[16];
 3994     sockaddr_u      addr[COUNTOF(last)];
 3995     char            buf[128];
 3996     struct ctl_var *    in_parms;
 3997     const struct ctl_var *  v;
 3998     const char *        val;
 3999     const char *        pch;
 4000     char *          pnonce;
 4001     int         nonce_valid;
 4002     size_t          i;
 4003     int         priors;
 4004     u_short         hash;
 4005     mon_entry *     mon;
 4006     mon_entry *     prior_mon;
 4007     l_fp            now;
 4008 
 4009     if (RES_NOMRULIST & restrict_mask) {
 4010         ctl_error(CERR_PERMISSION);
 4011         NLOG(NLOG_SYSINFO)
 4012             msyslog(LOG_NOTICE,
 4013                 "mrulist from %s rejected due to nomrulist restriction",
 4014                 stoa(&rbufp->recv_srcadr));
 4015         sys_restricted++;
 4016         return;
 4017     }
 4018     /*
 4019      * fill in_parms var list with all possible input parameters.
 4020      */
 4021     in_parms = NULL;
 4022     set_var(&in_parms, nonce_text, sizeof(nonce_text), 0);
 4023     set_var(&in_parms, frags_text, sizeof(frags_text), 0);
 4024     set_var(&in_parms, limit_text, sizeof(limit_text), 0);
 4025     set_var(&in_parms, mincount_text, sizeof(mincount_text), 0);
 4026     set_var(&in_parms, resall_text, sizeof(resall_text), 0);
 4027     set_var(&in_parms, resany_text, sizeof(resany_text), 0);
 4028     set_var(&in_parms, maxlstint_text, sizeof(maxlstint_text), 0);
 4029     set_var(&in_parms, laddr_text, sizeof(laddr_text), 0);
 4030     for (i = 0; i < COUNTOF(last); i++) {
 4031         snprintf(buf, sizeof(buf), last_fmt, (int)i);
 4032         set_var(&in_parms, buf, strlen(buf) + 1, 0);
 4033         snprintf(buf, sizeof(buf), addr_fmt, (int)i);
 4034         set_var(&in_parms, buf, strlen(buf) + 1, 0);
 4035     }
 4036 
 4037     /* decode input parms */
 4038     pnonce = NULL;
 4039     frags = 0;
 4040     limit = 0;
 4041     mincount = 0;
 4042     resall = 0;
 4043     resany = 0;
 4044     maxlstint = 0;
 4045     lcladr = NULL;
 4046     priors = 0;
 4047     ZERO(last);
 4048     ZERO(addr);
 4049 
 4050     /* have to go through '(void*)' to drop 'const' property from pointer.
 4051      * ctl_getitem()' needs some cleanup, too.... perlinger@ntp.org
 4052      */
 4053     while (NULL != (v = ctl_getitem(in_parms, (void*)&val)) &&
 4054            !(EOV & v->flags)) {
 4055         int si;
 4056 
 4057         if (NULL == val)
 4058             val = nulltxt;
 4059 
 4060         if (!strcmp(nonce_text, v->text)) {
 4061             free(pnonce);
 4062             pnonce = (*val) ? estrdup(val) : NULL;
 4063         } else if (!strcmp(frags_text, v->text)) {
 4064             if (1 != sscanf(val, "%hu", &frags))
 4065                 goto blooper;
 4066         } else if (!strcmp(limit_text, v->text)) {
 4067             if (1 != sscanf(val, "%u", &limit))
 4068                 goto blooper;
 4069         } else if (!strcmp(mincount_text, v->text)) {
 4070             if (1 != sscanf(val, "%d", &mincount))
 4071                 goto blooper;
 4072             if (mincount < 0)
 4073                 mincount = 0;
 4074         } else if (!strcmp(resall_text, v->text)) {
 4075             if (1 != sscanf(val, resaxx_fmt, &resall))
 4076                 goto blooper;
 4077         } else if (!strcmp(resany_text, v->text)) {
 4078             if (1 != sscanf(val, resaxx_fmt, &resany))
 4079                 goto blooper;
 4080         } else if (!strcmp(maxlstint_text, v->text)) {
 4081             if (1 != sscanf(val, "%u", &maxlstint))
 4082                 goto blooper;
 4083         } else if (!strcmp(laddr_text, v->text)) {
 4084             if (!decodenetnum(val, &laddr))
 4085                 goto blooper;
 4086             lcladr = getinterface(&laddr, 0);
 4087         } else if (1 == sscanf(v->text, last_fmt, &si) &&
 4088                (size_t)si < COUNTOF(last)) {
 4089             if (2 != sscanf(val, "0x%08x.%08x", &ui, &uf))
 4090                 goto blooper;
 4091             last[si].l_ui = ui;
 4092             last[si].l_uf = uf;
 4093             if (!SOCK_UNSPEC(&addr[si]) && si == priors)
 4094                 priors++;
 4095         } else if (1 == sscanf(v->text, addr_fmt, &si) &&
 4096                (size_t)si < COUNTOF(addr)) {
 4097             if (!decodenetnum(val, &addr[si]))
 4098                 goto blooper;
 4099             if (last[si].l_ui && last[si].l_uf && si == priors)
 4100                 priors++;
 4101         } else {
 4102             DPRINTF(1, ("read_mru_list: invalid key item: '%s' (ignored)\n",
 4103                     v->text));
 4104             continue;
 4105 
 4106         blooper:
 4107             DPRINTF(1, ("read_mru_list: invalid param for '%s': '%s' (bailing)\n",
 4108                     v->text, val));
 4109             free(pnonce);
 4110             pnonce = NULL;
 4111             break;
 4112         }
 4113     }
 4114     free_varlist(in_parms);
 4115     in_parms = NULL;
 4116 
 4117     /* return no responses until the nonce is validated */
 4118     if (NULL == pnonce)
 4119         return;
 4120 
 4121     nonce_valid = validate_nonce(pnonce, rbufp);
 4122     free(pnonce);
 4123     if (!nonce_valid)
 4124         return;
 4125 
 4126     if ((0 == frags && !(0 < limit && limit <= MRU_ROW_LIMIT)) ||
 4127         frags > MRU_FRAGS_LIMIT) {
 4128         ctl_error(CERR_BADVALUE);
 4129         return;
 4130     }
 4131 
 4132     /*
 4133      * If either frags or limit is not given, use the max.
 4134      */
 4135     if (0 != frags && 0 == limit)
 4136         limit = UINT_MAX;
 4137     else if (0 != limit && 0 == frags)
 4138         frags = MRU_FRAGS_LIMIT;
 4139 
 4140     /*
 4141      * Find the starting point if one was provided.
 4142      */
 4143     mon = NULL;
 4144     for (i = 0; i < (size_t)priors; i++) {
 4145         hash = MON_HASH(&addr[i]);
 4146         for (mon = mon_hash[hash];
 4147              mon != NULL;
 4148              mon = mon->hash_next)
 4149             if (ADDR_PORT_EQ(&mon->rmtadr, &addr[i]))
 4150                 break;
 4151         if (mon != NULL) {
 4152             if (L_ISEQU(&mon->last, &last[i]))
 4153                 break;
 4154             mon = NULL;
 4155         }
 4156     }
 4157 
 4158     /* If a starting point was provided... */
 4159     if (priors) {
 4160         /* and none could be found unmodified... */
 4161         if (NULL == mon) {
 4162             /* tell ntpq to try again with older entries */
 4163             ctl_error(CERR_UNKNOWNVAR);
 4164             return;
 4165         }
 4166         /* confirm the prior entry used as starting point */
 4167         ctl_putts("last.older", &mon->last);
 4168         pch = sptoa(&mon->rmtadr);
 4169         ctl_putunqstr("addr.older", pch, strlen(pch));
 4170 
 4171         /*
 4172          * Move on to the first entry the client doesn't have,
 4173          * except in the special case of a limit of one.  In
 4174          * that case return the starting point entry.
 4175          */
 4176         if (limit > 1)
 4177             mon = PREV_DLIST(mon_mru_list, mon, mru);
 4178     } else {    /* start with the oldest */
 4179         mon = TAIL_DLIST(mon_mru_list, mru);
 4180     }
 4181 
 4182     /*
 4183      * send up to limit= entries in up to frags= datagrams
 4184      */
 4185     get_systime(&now);
 4186     generate_nonce(rbufp, buf, sizeof(buf));
 4187     ctl_putunqstr("nonce", buf, strlen(buf));
 4188     prior_mon = NULL;
 4189     for (count = 0;
 4190          mon != NULL && res_frags < frags && count < limit;
 4191          mon = PREV_DLIST(mon_mru_list, mon, mru)) {
 4192 
 4193         if (mon->count < mincount)
 4194             continue;
 4195         if (resall && resall != (resall & mon->flags))
 4196             continue;
 4197         if (resany && !(resany & mon->flags))
 4198             continue;
 4199         if (maxlstint > 0 && now.l_ui - mon->last.l_ui >
 4200             maxlstint)
 4201             continue;
 4202         if (lcladr != NULL && mon->lcladr != lcladr)
 4203             continue;
 4204 
 4205         send_mru_entry(mon, count);
 4206         if (!count)
 4207             send_random_tag_value(0);
 4208         count++;
 4209         prior_mon = mon;
 4210     }
 4211 
 4212     /*
 4213      * If this batch completes the MRU list, say so explicitly with
 4214      * a now= l_fp timestamp.
 4215      */
 4216     if (NULL == mon) {
 4217         if (count > 1)
 4218             send_random_tag_value(count - 1);
 4219         ctl_putts("now", &now);
 4220         /* if any entries were returned confirm the last */
 4221         if (prior_mon != NULL)
 4222             ctl_putts("last.newest", &prior_mon->last);
 4223     }
 4224     ctl_flushpkt(0);
 4225 }
 4226 
 4227 
 4228 /*
 4229  * Send a ifstats entry in response to a "ntpq -c ifstats" request.
 4230  *
 4231  * To keep clients honest about not depending on the order of values,
 4232  * and thereby avoid being locked into ugly workarounds to maintain
 4233  * backward compatibility later as new fields are added to the response,
 4234  * the order is random.
 4235  */
 4236 static void
 4237 send_ifstats_entry(
 4238     endpt * la,
 4239     u_int   ifnum
 4240     )
 4241 {
 4242     const char addr_fmtu[] =    "addr.%u";
 4243     const char bcast_fmt[] =    "bcast.%u";
 4244     const char en_fmt[] =       "en.%u";    /* enabled */
 4245     const char name_fmt[] =     "name.%u";
 4246     const char flags_fmt[] =    "flags.%u";
 4247     const char tl_fmt[] =       "tl.%u";    /* ttl */
 4248     const char mc_fmt[] =       "mc.%u";    /* mcast count */
 4249     const char rx_fmt[] =       "rx.%u";
 4250     const char tx_fmt[] =       "tx.%u";
 4251     const char txerr_fmt[] =    "txerr.%u";
 4252     const char pc_fmt[] =       "pc.%u";    /* peer count */
 4253     const char up_fmt[] =       "up.%u";    /* uptime */
 4254     char    tag[32];
 4255     u_char  sent[IFSTATS_FIELDS]; /* 12 tag=value pairs */
 4256     int noisebits;
 4257     u_int32 noise;
 4258     u_int   which;
 4259     u_int   remaining;
 4260     const char *pch;
 4261 
 4262     remaining = COUNTOF(sent);
 4263     ZERO(sent);
 4264     noise = 0;
 4265     noisebits = 0;
 4266     while (remaining > 0) {
 4267         if (noisebits < 4) {
 4268             noise = rand() ^ (rand() << 16);
 4269             noisebits = 31;
 4270         }
 4271         which = (noise & 0xf) % COUNTOF(sent);
 4272         noise >>= 4;
 4273         noisebits -= 4;
 4274 
 4275         while (sent[which])
 4276             which = (which + 1) % COUNTOF(sent);
 4277 
 4278         switch (which) {
 4279 
 4280         case 0:
 4281             snprintf(tag, sizeof(tag), addr_fmtu, ifnum);
 4282             pch = sptoa(&la->sin);
 4283             ctl_putunqstr(tag, pch, strlen(pch));
 4284             break;
 4285 
 4286         case 1:
 4287             snprintf(tag, sizeof(tag), bcast_fmt, ifnum);
 4288             if (INT_BCASTOPEN & la->flags)
 4289                 pch = sptoa(&la->bcast);
 4290             else
 4291                 pch = "";
 4292             ctl_putunqstr(tag, pch, strlen(pch));
 4293             break;
 4294 
 4295         case 2:
 4296             snprintf(tag, sizeof(tag), en_fmt, ifnum);
 4297             ctl_putint(tag, !la->ignore_packets);
 4298             break;
 4299 
 4300         case 3:
 4301             snprintf(tag, sizeof(tag), name_fmt, ifnum);
 4302             ctl_putstr(tag, la->name, strlen(la->name));
 4303             break;
 4304 
 4305         case 4:
 4306             snprintf(tag, sizeof(tag), flags_fmt, ifnum);
 4307             ctl_puthex(tag, (u_int)la->flags);
 4308             break;
 4309 
 4310         case 5:
 4311             snprintf(tag, sizeof(tag), tl_fmt, ifnum);
 4312             ctl_putint(tag, la->last_ttl);
 4313             break;
 4314 
 4315         case 6:
 4316             snprintf(tag, sizeof(tag), mc_fmt, ifnum);
 4317             ctl_putint(tag, la->num_mcast);
 4318             break;
 4319 
 4320         case 7:
 4321             snprintf(tag, sizeof(tag), rx_fmt, ifnum);
 4322             ctl_putint(tag, la->received);
 4323             break;
 4324 
 4325         case 8:
 4326             snprintf(tag, sizeof(tag), tx_fmt, ifnum);
 4327             ctl_putint(tag, la->sent);
 4328             break;
 4329 
 4330         case 9:
 4331             snprintf(tag, sizeof(tag), txerr_fmt, ifnum);
 4332             ctl_putint(tag, la->notsent);
 4333             break;
 4334 
 4335         case 10:
 4336             snprintf(tag, sizeof(tag), pc_fmt, ifnum);
 4337             ctl_putuint(tag, la->peercnt);
 4338             break;
 4339 
 4340         case 11:
 4341             snprintf(tag, sizeof(tag), up_fmt, ifnum);
 4342             ctl_putuint(tag, current_time - la->starttime);
 4343             break;
 4344         }
 4345         sent[which] = TRUE;
 4346         remaining--;
 4347     }
 4348     send_random_tag_value((int)ifnum);
 4349 }
 4350 
 4351 
 4352 /*
 4353  * read_ifstats - send statistics for each local address, exposed by
 4354  *        ntpq -c ifstats
 4355  */
 4356 static void
 4357 read_ifstats(
 4358     struct recvbuf *    rbufp
 4359     )
 4360 {
 4361     u_int   ifidx;
 4362     endpt * la;
 4363 
 4364     /*
 4365      * loop over [0..sys_ifnum] searching ep_list for each
 4366      * ifnum in turn.
 4367      */
 4368     for (ifidx = 0; ifidx < sys_ifnum; ifidx++) {
 4369         for (la = ep_list; la != NULL; la = la->elink)
 4370             if (ifidx == la->ifnum)
 4371                 break;
 4372         if (NULL == la)
 4373             continue;
 4374         /* return stats for one local address */
 4375         send_ifstats_entry(la, ifidx);
 4376     }
 4377     ctl_flushpkt(0);
 4378 }
 4379 
 4380 static void
 4381 sockaddrs_from_restrict_u(
 4382     sockaddr_u *    psaA,
 4383     sockaddr_u *    psaM,
 4384     restrict_u *    pres,
 4385     int     ipv6
 4386     )
 4387 {
 4388     ZERO(*psaA);
 4389     ZERO(*psaM);
 4390     if (!ipv6) {
 4391         psaA->sa.sa_family = AF_INET;
 4392         psaA->sa4.sin_addr.s_addr = htonl(pres->u.v4.addr);
 4393         psaM->sa.sa_family = AF_INET;
 4394         psaM->sa4.sin_addr.s_addr = htonl(pres->u.v4.mask);
 4395     } else {
 4396         psaA->sa.sa_family = AF_INET6;
 4397         memcpy(&psaA->sa6.sin6_addr, &pres->u.v6.addr,
 4398                sizeof(psaA->sa6.sin6_addr));
 4399         psaM->sa.sa_family = AF_INET6;
 4400         memcpy(&psaM->sa6.sin6_addr, &pres->u.v6.mask,
 4401                sizeof(psaA->sa6.sin6_addr));
 4402     }
 4403 }
 4404 
 4405 
 4406 /*
 4407  * Send a restrict entry in response to a "ntpq -c reslist" request.
 4408  *
 4409  * To keep clients honest about not depending on the order of values,
 4410  * and thereby avoid being locked into ugly workarounds to maintain
 4411  * backward compatibility later as new fields are added to the response,
 4412  * the order is random.
 4413  */
 4414 static void
 4415 send_restrict_entry(
 4416     restrict_u *    pres,
 4417     int     ipv6,
 4418     u_int       idx
 4419     )
 4420 {
 4421     const char addr_fmtu[] =    "addr.%u";
 4422     const char mask_fmtu[] =    "mask.%u";
 4423     const char hits_fmt[] =     "hits.%u";
 4424     const char flags_fmt[] =    "flags.%u";
 4425     char        tag[32];
 4426     u_char      sent[RESLIST_FIELDS]; /* 4 tag=value pairs */
 4427     int     noisebits;
 4428     u_int32     noise;
 4429     u_int       which;
 4430     u_int       remaining;
 4431     sockaddr_u  addr;
 4432     sockaddr_u  mask;
 4433     const char *    pch;
 4434     char *      buf;
 4435     const char *    match_str;
 4436     const char *    access_str;
 4437 
 4438     sockaddrs_from_restrict_u(&addr, &mask, pres, ipv6);
 4439     remaining = COUNTOF(sent);
 4440     ZERO(sent);
 4441     noise = 0;
 4442     noisebits = 0;
 4443     while (remaining > 0) {
 4444         if (noisebits < 2) {
 4445             noise = rand() ^ (rand() << 16);
 4446             noisebits = 31;
 4447         }
 4448         which = (noise & 0x3) % COUNTOF(sent);
 4449         noise >>= 2;
 4450         noisebits -= 2;
 4451 
 4452         while (sent[which])
 4453             which = (which + 1) % COUNTOF(sent);
 4454 
 4455         /* XXX: Numbers?  Really? */
 4456         switch (which) {
 4457 
 4458         case 0:
 4459             snprintf(tag, sizeof(tag), addr_fmtu, idx);
 4460             pch = stoa(&addr);
 4461             ctl_putunqstr(tag, pch, strlen(pch));
 4462             break;
 4463 
 4464         case 1:
 4465             snprintf(tag, sizeof(tag), mask_fmtu, idx);
 4466             pch = stoa(&mask);
 4467             ctl_putunqstr(tag, pch, strlen(pch));
 4468             break;
 4469 
 4470         case 2:
 4471             snprintf(tag, sizeof(tag), hits_fmt, idx);
 4472             ctl_putuint(tag, pres->count);
 4473             break;
 4474 
 4475         case 3:
 4476             snprintf(tag, sizeof(tag), flags_fmt, idx);
 4477             match_str = res_match_flags(pres->mflags);
 4478             access_str = res_access_flags(pres->rflags);
 4479             if ('\0' == match_str[0]) {
 4480                 pch = access_str;
 4481             } else {
 4482                 LIB_GETBUF(buf);
 4483                 snprintf(buf, LIB_BUFLENGTH, "%s %s",
 4484                      match_str, access_str);
 4485                 pch = buf;
 4486             }
 4487             ctl_putunqstr(tag, pch, strlen(pch));
 4488             break;
 4489         }
 4490         sent[which] = TRUE;
 4491         remaining--;
 4492     }
 4493     send_random_tag_value((int)idx);
 4494 }
 4495 
 4496 
 4497 static void
 4498 send_restrict_list(
 4499     restrict_u *    pres,
 4500     int     ipv6,
 4501     u_int *     pidx
 4502     )
 4503 {
 4504     for ( ; pres != NULL; pres = pres->link) {
 4505         send_restrict_entry(pres, ipv6, *pidx);
 4506         (*pidx)++;
 4507     }
 4508 }
 4509 
 4510 
 4511 /*
 4512  * read_addr_restrictions - returns IPv4 and IPv6 access control lists
 4513  */
 4514 static void
 4515 read_addr_restrictions(
 4516     struct recvbuf *    rbufp
 4517 )
 4518 {
 4519     u_int idx;
 4520 
 4521     idx = 0;
 4522     send_restrict_list(restrictlist4, FALSE, &idx);
 4523     send_restrict_list(restrictlist6, TRUE, &idx);
 4524     ctl_flushpkt(0);
 4525 }
 4526 
 4527 
 4528 /*
 4529  * read_ordlist - CTL_OP_READ_ORDLIST_A for ntpq -c ifstats & reslist
 4530  */
 4531 static void
 4532 read_ordlist(
 4533     struct recvbuf *    rbufp,
 4534     int         restrict_mask
 4535     )
 4536 {
 4537     const char ifstats_s[] = "ifstats";
 4538     const size_t ifstats_chars = COUNTOF(ifstats_s) - 1;
 4539     const char addr_rst_s[] = "addr_restrictions";
 4540     const size_t a_r_chars = COUNTOF(addr_rst_s) - 1;
 4541     struct ntp_control *    cpkt;
 4542     u_short         qdata_octets;
 4543 
 4544     /*
 4545      * CTL_OP_READ_ORDLIST_A was first named CTL_OP_READ_IFSTATS and
 4546      * used only for ntpq -c ifstats.  With the addition of reslist
 4547      * the same opcode was generalized to retrieve ordered lists
 4548      * which require authentication.  The request data is empty or
 4549      * contains "ifstats" (not null terminated) to retrieve local
 4550      * addresses and associated stats.  It is "addr_restrictions"
 4551      * to retrieve the IPv4 then IPv6 remote address restrictions,
 4552      * which are access control lists.  Other request data return
 4553      * CERR_UNKNOWNVAR.
 4554      */
 4555     cpkt = (struct ntp_control *)&rbufp->recv_pkt;
 4556     qdata_octets = ntohs(cpkt->count);
 4557     if (0 == qdata_octets || (ifstats_chars == qdata_octets &&
 4558         !memcmp(ifstats_s, cpkt->u.data, ifstats_chars))) {
 4559         read_ifstats(rbufp);
 4560         return;
 4561     }
 4562     if (a_r_chars == qdata_octets &&
 4563         !memcmp(addr_rst_s, cpkt->u.data, a_r_chars)) {
 4564         read_addr_restrictions(rbufp);
 4565         return;
 4566     }
 4567     ctl_error(CERR_UNKNOWNVAR);
 4568 }
 4569 
 4570 
 4571 /*
 4572  * req_nonce - CTL_OP_REQ_NONCE for ntpq -c mrulist prerequisite.
 4573  */
 4574 static void req_nonce(
 4575     struct recvbuf *    rbufp,
 4576     int         restrict_mask
 4577     )
 4578 {
 4579     char    buf[64];
 4580 
 4581     generate_nonce(rbufp, buf, sizeof(buf));
 4582     ctl_putunqstr("nonce", buf, strlen(buf));
 4583     ctl_flushpkt(0);
 4584 }
 4585 
 4586 
 4587 /*
 4588  * read_clockstatus - return clock radio status
 4589  */
 4590 /*ARGSUSED*/
 4591 static void
 4592 read_clockstatus(
 4593     struct recvbuf *rbufp,
 4594     int restrict_mask
 4595     )
 4596 {
 4597 #ifndef REFCLOCK
 4598     /*
 4599      * If no refclock support, no data to return
 4600      */
 4601     ctl_error(CERR_BADASSOC);
 4602 #else
 4603     const struct ctl_var *  v;
 4604     int         i;
 4605     struct peer *       peer;
 4606     char *          valuep;
 4607     u_char *        wants;
 4608     size_t          wants_alloc;
 4609     int         gotvar;
 4610     const u_char *      cc;
 4611     struct ctl_var *    kv;
 4612     struct refclockstat cs;
 4613 
 4614     if (res_associd != 0) {
 4615         peer = findpeerbyassoc(res_associd);
 4616     } else {
 4617         /*
 4618          * Find a clock for this jerk.  If the system peer
 4619          * is a clock use it, else search peer_list for one.
 4620          */
 4621         if (sys_peer != NULL && (FLAG_REFCLOCK &
 4622             sys_peer->flags))
 4623             peer = sys_peer;
 4624         else
 4625             for (peer = peer_list;
 4626                  peer != NULL;
 4627                  peer = peer->p_link)
 4628                 if (FLAG_REFCLOCK & peer->flags)
 4629                     break;
 4630     }
 4631     if (NULL == peer || !(FLAG_REFCLOCK & peer->flags)) {
 4632         ctl_error(CERR_BADASSOC);
 4633         return;
 4634     }
 4635     /*
 4636      * If we got here we have a peer which is a clock. Get his
 4637      * status.
 4638      */
 4639     cs.kv_list = NULL;
 4640     refclock_control(&peer->srcadr, NULL, &cs);
 4641     kv = cs.kv_list;
 4642     /*
 4643      * Look for variables in the packet.
 4644      */
 4645     rpkt.status = htons(ctlclkstatus(&cs));
 4646     wants_alloc = CC_MAXCODE + 1 + count_var(kv);
 4647     wants = emalloc_zero(wants_alloc);
 4648     gotvar = FALSE;
 4649     while (NULL != (v = ctl_getitem(clock_var, &valuep))) {
 4650         if (!(EOV & v->flags)) {
 4651             wants[v->code] = TRUE;
 4652             gotvar = TRUE;
 4653         } else {
 4654             v = ctl_getitem(kv, &valuep);
 4655             if (NULL == v) {
 4656                 ctl_error(CERR_BADVALUE);
 4657                 free(wants);
 4658                 free_varlist(cs.kv_list);
 4659                 return;
 4660             }
 4661             if (EOV & v->flags) {
 4662                 ctl_error(CERR_UNKNOWNVAR);
 4663                 free(wants);
 4664                 free_varlist(cs.kv_list);
 4665                 return;
 4666             }
 4667             wants[CC_MAXCODE + 1 + v->code] = TRUE;
 4668             gotvar = TRUE;
 4669         }
 4670     }
 4671 
 4672     if (gotvar) {
 4673         for (i = 1; i <= CC_MAXCODE; i++)
 4674             if (wants[i])
 4675                 ctl_putclock(i, &cs, TRUE);
 4676         if (kv != NULL)
 4677             for (i = 0; !(EOV & kv[i].flags); i++)
 4678                 if (wants[i + CC_MAXCODE + 1])
 4679                     ctl_putdata(kv[i].text,
 4680                             strlen(kv[i].text),
 4681                             FALSE);
 4682     } else {
 4683         for (cc = def_clock_var; *cc != 0; cc++)
 4684             ctl_putclock((int)*cc, &cs, FALSE);
 4685         for ( ; kv != NULL && !(EOV & kv->flags); kv++)
 4686             if (DEF & kv->flags)
 4687                 ctl_putdata(kv->text, strlen(kv->text),
 4688                         FALSE);
 4689     }
 4690 
 4691     free(wants);
 4692     free_varlist(cs.kv_list);
 4693 
 4694     ctl_flushpkt(0);
 4695 #endif
 4696 }
 4697 
 4698 
 4699 /*
 4700  * write_clockstatus - we don't do this
 4701  */
 4702 /*ARGSUSED*/
 4703 static void
 4704 write_clockstatus(
 4705     struct recvbuf *rbufp,
 4706     int restrict_mask
 4707     )
 4708 {
 4709     ctl_error(CERR_PERMISSION);
 4710 }
 4711 
 4712 /*
 4713  * Trap support from here on down. We send async trap messages when the
 4714  * upper levels report trouble. Traps can by set either by control
 4715  * messages or by configuration.
 4716  */
 4717 /*
 4718  * set_trap - set a trap in response to a control message
 4719  */
 4720 static void
 4721 set_trap(
 4722     struct recvbuf *rbufp,
 4723     int restrict_mask
 4724     )
 4725 {
 4726     int traptype;
 4727 
 4728     /*
 4729      * See if this guy is allowed
 4730      */
 4731     if (restrict_mask & RES_NOTRAP) {
 4732         ctl_error(CERR_PERMISSION);
 4733         return;
 4734     }
 4735 
 4736     /*
 4737      * Determine his allowed trap type.
 4738      */
 4739     traptype = TRAP_TYPE_PRIO;
 4740     if (restrict_mask & RES_LPTRAP)
 4741         traptype = TRAP_TYPE_NONPRIO;
 4742 
 4743     /*
 4744      * Call ctlsettrap() to do the work.  Return
 4745      * an error if it can't assign the trap.
 4746      */
 4747     if (!ctlsettrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype,
 4748             (int)res_version))
 4749         ctl_error(CERR_NORESOURCE);
 4750     ctl_flushpkt(0);
 4751 }
 4752 
 4753 
 4754 /*
 4755  * unset_trap - unset a trap in response to a control message
 4756  */
 4757 static void
 4758 unset_trap(
 4759     struct recvbuf *rbufp,
 4760     int restrict_mask
 4761     )
 4762 {
 4763     int traptype;
 4764 
 4765     /*
 4766      * We don't prevent anyone from removing his own trap unless the
 4767      * trap is configured. Note we also must be aware of the
 4768      * possibility that restriction flags were changed since this
 4769      * guy last set his trap. Set the trap type based on this.
 4770      */
 4771     traptype = TRAP_TYPE_PRIO;
 4772     if (restrict_mask & RES_LPTRAP)
 4773         traptype = TRAP_TYPE_NONPRIO;
 4774 
 4775     /*
 4776      * Call ctlclrtrap() to clear this out.
 4777      */
 4778     if (!ctlclrtrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype))
 4779         ctl_error(CERR_BADASSOC);
 4780     ctl_flushpkt(0);
 4781 }
 4782 
 4783 
 4784 /*
 4785  * ctlsettrap - called to set a trap
 4786  */
 4787 int
 4788 ctlsettrap(
 4789     sockaddr_u *raddr,
 4790     struct interface *linter,
 4791     int traptype,
 4792     int version
 4793     )
 4794 {
 4795     size_t n;
 4796     struct ctl_trap *tp;
 4797     struct ctl_trap *tptouse;
 4798 
 4799     /*
 4800      * See if we can find this trap.  If so, we only need update
 4801      * the flags and the time.
 4802      */
 4803     if ((tp = ctlfindtrap(raddr, linter)) != NULL) {
 4804         switch (traptype) {
 4805 
 4806         case TRAP_TYPE_CONFIG:
 4807             tp->tr_flags = TRAP_INUSE|TRAP_CONFIGURED;
 4808             break;
 4809 
 4810         case TRAP_TYPE_PRIO:
 4811             if (tp->tr_flags & TRAP_CONFIGURED)
 4812                 return (1); /* don't change anything */
 4813             tp->tr_flags = TRAP_INUSE;
 4814             break;
 4815 
 4816         case TRAP_TYPE_NONPRIO:
 4817             if (tp->tr_flags & TRAP_CONFIGURED)
 4818                 return (1); /* don't change anything */
 4819             tp->tr_flags = TRAP_INUSE|TRAP_NONPRIO;
 4820             break;
 4821         }
 4822         tp->tr_settime = current_time;
 4823         tp->tr_resets++;
 4824         return (1);
 4825     }
 4826 
 4827     /*
 4828      * First we heard of this guy.  Try to find a trap structure
 4829      * for him to use, clearing out lesser priority guys if we
 4830      * have to. Clear out anyone who's expired while we're at it.
 4831      */
 4832     tptouse = NULL;
 4833     for (n = 0; n < COUNTOF(ctl_traps); n++) {
 4834         tp = &ctl_traps[n];
 4835         if ((TRAP_INUSE & tp->tr_flags) &&
 4836             !(TRAP_CONFIGURED & tp->tr_flags) &&
 4837             ((tp->tr_settime + CTL_TRAPTIME) > current_time)) {
 4838             tp->tr_flags = 0;
 4839             num_ctl_traps--;
 4840         }
 4841         if (!(TRAP_INUSE & tp->tr_flags)) {
 4842             tptouse = tp;
 4843         } else if (!(TRAP_CONFIGURED & tp->tr_flags)) {
 4844             switch (traptype) {
 4845 
 4846             case TRAP_TYPE_CONFIG:
 4847                 if (tptouse == NULL) {
 4848                     tptouse = tp;
 4849                     break;
 4850                 }
 4851                 if ((TRAP_NONPRIO & tptouse->tr_flags) &&
 4852                     !(TRAP_NONPRIO & tp->tr_flags))
 4853                     break;
 4854 
 4855                 if (!(TRAP_NONPRIO & tptouse->tr_flags)
 4856                     && (TRAP_NONPRIO & tp->tr_flags)) {
 4857                     tptouse = tp;
 4858                     break;
 4859                 }
 4860                 if (tptouse->tr_origtime <
 4861                     tp->tr_origtime)
 4862                     tptouse = tp;
 4863                 break;
 4864 
 4865             case TRAP_TYPE_PRIO:
 4866                 if ( TRAP_NONPRIO & tp->tr_flags) {
 4867                     if (tptouse == NULL ||
 4868                         ((TRAP_INUSE &
 4869                           tptouse->tr_flags) &&
 4870                          tptouse->tr_origtime <
 4871                          tp->tr_origtime))
 4872                         tptouse = tp;
 4873                 }
 4874                 break;
 4875 
 4876             case TRAP_TYPE_NONPRIO:
 4877                 break;
 4878             }
 4879         }
 4880     }
 4881 
 4882     /*
 4883      * If we don't have room for him return an error.
 4884      */
 4885     if (tptouse == NULL)
 4886         return (0);
 4887 
 4888     /*
 4889      * Set up this structure for him.
 4890      */
 4891     tptouse->tr_settime = tptouse->tr_origtime = current_time;
 4892     tptouse->tr_count = tptouse->tr_resets = 0;
 4893     tptouse->tr_sequence = 1;
 4894     tptouse->tr_addr = *raddr;
 4895     tptouse->tr_localaddr = linter;
 4896     tptouse->tr_version = (u_char) version;
 4897     tptouse->tr_flags = TRAP_INUSE;
 4898     if (traptype == TRAP_TYPE_CONFIG)
 4899         tptouse->tr_flags |= TRAP_CONFIGURED;
 4900     else if (traptype == TRAP_TYPE_NONPRIO)
 4901         tptouse->tr_flags |= TRAP_NONPRIO;
 4902     num_ctl_traps++;
 4903     return (1);
 4904 }
 4905 
 4906 
 4907 /*
 4908  * ctlclrtrap - called to clear a trap
 4909  */
 4910 int
 4911 ctlclrtrap(
 4912     sockaddr_u *raddr,
 4913     struct interface *linter,
 4914     int traptype
 4915     )
 4916 {
 4917     register struct ctl_trap *tp;
 4918 
 4919     if ((tp = ctlfindtrap(raddr, linter)) == NULL)
 4920         return (0);
 4921 
 4922     if (tp->tr_flags & TRAP_CONFIGURED
 4923         && traptype != TRAP_TYPE_CONFIG)
 4924         return (0);
 4925 
 4926     tp->tr_flags = 0;
 4927     num_ctl_traps--;
 4928     return (1);
 4929 }
 4930 
 4931 
 4932 /*
 4933  * ctlfindtrap - find a trap given the remote and local addresses
 4934  */
 4935 static struct ctl_trap *
 4936 ctlfindtrap(
 4937     sockaddr_u *raddr,
 4938     struct interface *linter
 4939     )
 4940 {
 4941     size_t  n;
 4942 
 4943     for (n = 0; n < COUNTOF(ctl_traps); n++)
 4944         if ((ctl_traps[n].tr_flags & TRAP_INUSE)
 4945             && ADDR_PORT_EQ(raddr, &ctl_traps[n].tr_addr)
 4946             && (linter == ctl_traps[n].tr_localaddr))
 4947             return &ctl_traps[n];
 4948 
 4949     return NULL;
 4950 }
 4951 
 4952 
 4953 /*
 4954  * report_event - report an event to the trappers
 4955  */
 4956 void
 4957 report_event(
 4958     int err,        /* error code */
 4959     struct peer *peer,  /* peer structure pointer */
 4960     const char *str     /* protostats string */
 4961     )
 4962 {
 4963     char    statstr[NTP_MAXSTRLEN];
 4964     int i;
 4965     size_t  len;
 4966 
 4967     /*
 4968      * Report the error to the protostats file, system log and
 4969      * trappers.
 4970      */
 4971     if (peer == NULL) {
 4972 
 4973         /*
 4974          * Discard a system report if the number of reports of
 4975          * the same type exceeds the maximum.
 4976          */
 4977         if (ctl_sys_last_event != (u_char)err)
 4978             ctl_sys_num_events= 0;
 4979         if (ctl_sys_num_events >= CTL_SYS_MAXEVENTS)
 4980             return;
 4981 
 4982         ctl_sys_last_event = (u_char)err;
 4983         ctl_sys_num_events++;
 4984         snprintf(statstr, sizeof(statstr),
 4985             "0.0.0.0 %04x %02x %s",
 4986             ctlsysstatus(), err, eventstr(err));
 4987         if (str != NULL) {
 4988             len = strlen(statstr);
 4989             snprintf(statstr + len, sizeof(statstr) - len,
 4990                 " %s", str);
 4991         }
 4992         NLOG(NLOG_SYSEVENT)
 4993             msyslog(LOG_INFO, "%s", statstr);
 4994     } else {
 4995 
 4996         /*
 4997          * Discard a peer report if the number of reports of
 4998          * the same type exceeds the maximum for that peer.
 4999          */
 5000         const char *    src;
 5001         u_char      errlast;
 5002 
 5003         errlast = (u_char)err & ~PEER_EVENT;
 5004         if (peer->last_event != errlast)
 5005             peer->num_events = 0;
 5006         if (peer->num_events >= CTL_PEER_MAXEVENTS)
 5007             return;
 5008 
 5009         peer->last_event = errlast;
 5010         peer->num_events++;
 5011         if (ISREFCLOCKADR(&peer->srcadr))
 5012             src = refnumtoa(&peer->srcadr);
 5013         else
 5014             src = stoa(&peer->srcadr);
 5015 
 5016         snprintf(statstr, sizeof(statstr),
 5017             "%s %04x %02x %s", src,
 5018             ctlpeerstatus(peer), err, eventstr(err));
 5019         if (str != NULL) {
 5020             len = strlen(statstr);
 5021             snprintf(statstr + len, sizeof(statstr) - len,
 5022                 " %s", str);
 5023         }
 5024         NLOG(NLOG_PEEREVENT)
 5025             msyslog(LOG_INFO, "%s", statstr);
 5026     }
 5027     record_proto_stats(statstr);
 5028 #if DEBUG
 5029     if (debug)
 5030         printf("event at %lu %s\n", current_time, statstr);
 5031 #endif
 5032 
 5033     /*
 5034      * If no trappers, return.
 5035      */
 5036     if (num_ctl_traps <= 0)
 5037         return;
 5038 
 5039     /* [Bug 3119]
 5040      * Peer Events should be associated with a peer -- hence the
 5041      * name. But there are instances where this function is called
 5042      * *without* a valid peer. This happens e.g. with an unsolicited
 5043      * CryptoNAK, or when a leap second alarm is going off while
 5044      * currently without a system peer.
 5045      *
 5046      * The most sensible approach to this seems to bail out here if
 5047      * this happens. Avoiding to call this function would also
 5048      * bypass the log reporting in the first part of this function,
 5049      * and this is probably not the best of all options.
 5050      *   -*-perlinger@ntp.org-*-
 5051      */
 5052     if ((err & PEER_EVENT) && !peer)
 5053         return;
 5054 
 5055     /*
 5056      * Set up the outgoing packet variables
 5057      */
 5058     res_opcode = CTL_OP_ASYNCMSG;
 5059     res_offset = 0;
 5060     res_async = TRUE;
 5061     res_authenticate = FALSE;
 5062     datapt = rpkt.u.data;
 5063     dataend = &rpkt.u.data[CTL_MAX_DATA_LEN];
 5064     if (!(err & PEER_EVENT)) {
 5065         rpkt.associd = 0;
 5066         rpkt.status = htons(ctlsysstatus());
 5067 
 5068         /* Include the core system variables and the list. */
 5069         for (i = 1; i <= CS_VARLIST; i++)
 5070             ctl_putsys(i);
 5071     } else if (NULL != peer) { /* paranoia -- skip output */
 5072         rpkt.associd = htons(peer->associd);
 5073         rpkt.status = htons(ctlpeerstatus(peer));
 5074 
 5075         /* Dump it all. Later, maybe less. */
 5076         for (i = 1; i <= CP_MAX_NOAUTOKEY; i++)
 5077             ctl_putpeer(i, peer);
 5078 #       ifdef REFCLOCK
 5079         /*
 5080          * for clock exception events: add clock variables to
 5081          * reflect info on exception
 5082          */
 5083         if (err == PEVNT_CLOCK) {
 5084             struct refclockstat cs;
 5085             struct ctl_var *kv;
 5086 
 5087             cs.kv_list = NULL;
 5088             refclock_control(&peer->srcadr, NULL, &cs);
 5089 
 5090             ctl_puthex("refclockstatus",
 5091                    ctlclkstatus(&cs));
 5092 
 5093             for (i = 1; i <= CC_MAXCODE; i++)
 5094                 ctl_putclock(i, &cs, FALSE);
 5095             for (kv = cs.kv_list;
 5096                  kv != NULL && !(EOV & kv->flags);
 5097                  kv++)
 5098                 if (DEF & kv->flags)
 5099                     ctl_putdata(kv->text,
 5100                             strlen(kv->text),
 5101                             FALSE);
 5102             free_varlist(cs.kv_list);
 5103         }
 5104 #       endif /* REFCLOCK */
 5105     }
 5106 
 5107     /*
 5108      * We're done, return.
 5109      */
 5110     ctl_flushpkt(0);
 5111 }
 5112 
 5113 
 5114 /*
 5115  * mprintf_event - printf-style varargs variant of report_event()
 5116  */
 5117 int
 5118 mprintf_event(
 5119     int     evcode,     /* event code */
 5120     struct peer *   p,      /* may be NULL */
 5121     const char *    fmt,        /* msnprintf format */
 5122     ...
 5123     )
 5124 {
 5125     va_list ap;
 5126     int rc;
 5127     char    msg[512];
 5128 
 5129     va_start(ap, fmt);
 5130     rc = mvsnprintf(msg, sizeof(msg), fmt, ap);
 5131     va_end(ap);
 5132     report_event(evcode, p, msg);
 5133 
 5134     return rc;
 5135 }
 5136 
 5137 
 5138 /*
 5139  * ctl_clr_stats - clear stat counters
 5140  */
 5141 void
 5142 ctl_clr_stats(void)
 5143 {
 5144     ctltimereset = current_time;
 5145     numctlreq = 0;
 5146     numctlbadpkts = 0;
 5147     numctlresponses = 0;
 5148     numctlfrags = 0;
 5149     numctlerrors = 0;
 5150     numctlfrags = 0;
 5151     numctltooshort = 0;
 5152     numctlinputresp = 0;
 5153     numctlinputfrag = 0;
 5154     numctlinputerr = 0;
 5155     numctlbadoffset = 0;
 5156     numctlbadversion = 0;
 5157     numctldatatooshort = 0;
 5158     numctlbadop = 0;
 5159     numasyncmsgs = 0;
 5160 }
 5161 
 5162 static u_short
 5163 count_var(
 5164     const struct ctl_var *k
 5165     )
 5166 {
 5167     u_int c;
 5168 
 5169     if (NULL == k)
 5170         return 0;
 5171 
 5172     c = 0;
 5173     while (!(EOV & (k++)->flags))
 5174         c++;
 5175 
 5176     ENSURE(c <= USHRT_MAX);
 5177     return (u_short)c;
 5178 }
 5179 
 5180 
 5181 char *
 5182 add_var(
 5183     struct ctl_var **kv,
 5184     u_long size,
 5185     u_short def
 5186     )
 5187 {
 5188     u_short     c;
 5189     struct ctl_var *k;
 5190     char *      buf;
 5191 
 5192     c = count_var(*kv);
 5193     *kv  = erealloc(*kv, (c + 2) * sizeof(**kv));
 5194     k = *kv;
 5195     buf = emalloc(size);
 5196     k[c].code  = c;
 5197     k[c].text  = buf;
 5198     k[c].flags = def;
 5199     k[c + 1].code  = 0;
 5200     k[c + 1].text  = NULL;
 5201     k[c + 1].flags = EOV;
 5202 
 5203     return buf;
 5204 }
 5205 
 5206 
 5207 void
 5208 set_var(
 5209     struct ctl_var **kv,
 5210     const char *data,
 5211     u_long size,
 5212     u_short def
 5213     )
 5214 {
 5215     struct ctl_var *k;
 5216     const char *s;
 5217     const char *t;
 5218     char *td;
 5219 
 5220     if (NULL == data || !size)
 5221         return;
 5222 
 5223     k = *kv;
 5224     if (k != NULL) {
 5225         while (!(EOV & k->flags)) {
 5226             if (NULL == k->text)    {
 5227                 td = emalloc(size);
 5228                 memcpy(td, data, size);
 5229                 k->text = td;
 5230                 k->flags = def;
 5231                 return;
 5232             } else {
 5233                 s = data;
 5234                 t = k->text;
 5235                 while (*t != '=' && *s == *t) {
 5236                     s++;
 5237                     t++;
 5238                 }
 5239                 if (*s == *t && ((*t == '=') || !*t)) {
 5240                     td = erealloc((void *)(intptr_t)k->text, size);
 5241                     memcpy(td, data, size);
 5242                     k->text = td;
 5243                     k->flags = def;
 5244                     return;
 5245                 }
 5246             }
 5247             k++;
 5248         }
 5249     }
 5250     td = add_var(kv, size, def);
 5251     memcpy(td, data, size);
 5252 }
 5253 
 5254 
 5255 void
 5256 set_sys_var(
 5257     const char *data,
 5258     u_long size,
 5259     u_short def
 5260     )
 5261 {
 5262     set_var(&ext_sys_var, data, size, def);
 5263 }
 5264 
 5265 
 5266 /*
 5267  * get_ext_sys_var() retrieves the value of a user-defined variable or
 5268  * NULL if the variable has not been setvar'd.
 5269  */
 5270 const char *
 5271 get_ext_sys_var(const char *tag)
 5272 {
 5273     struct ctl_var *    v;
 5274     size_t          c;
 5275     const char *        val;
 5276 
 5277     val = NULL;
 5278     c = strlen(tag);
 5279     for (v = ext_sys_var; !(EOV & v->flags); v++) {
 5280         if (NULL != v->text && !memcmp(tag, v->text, c)) {
 5281             if ('=' == v->text[c]) {
 5282                 val = v->text + c + 1;
 5283                 break;
 5284             } else if ('\0' == v->text[c]) {
 5285                 val = "";
 5286                 break;
 5287             }
 5288         }
 5289     }
 5290 
 5291     return val;
 5292 }
 5293 
 5294 
 5295 void
 5296 free_varlist(
 5297     struct ctl_var *kv
 5298     )
 5299 {
 5300     struct ctl_var *k;
 5301     if (kv) {
 5302         for (k = kv; !(k->flags & EOV); k++)
 5303             free((void *)(intptr_t)k->text);
 5304         free((void *)kv);
 5305     }
 5306 }