Annotation of embedaddon/ntp/ntpdc/ntpdc_ops.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * ntpdc_ops.c - subroutines which are called to perform operations by
        !             3:  *              ntpdc
        !             4:  */
        !             5: 
        !             6: #ifdef HAVE_CONFIG_H
        !             7: # include <config.h>
        !             8: #endif
        !             9: 
        !            10: #include <stdio.h>
        !            11: #include <stddef.h>
        !            12: 
        !            13: #include "ntpdc.h"
        !            14: #include "ntp_net.h"
        !            15: #include "ntp_control.h"
        !            16: #include "ntp_refclock.h"
        !            17: #include "ntp_stdlib.h"
        !            18: 
        !            19: #include <ctype.h>
        !            20: #ifdef HAVE_SYS_TIMEX_H
        !            21: # include <sys/timex.h>
        !            22: #endif
        !            23: #if !defined(__bsdi__) && !defined(apollo)
        !            24: #ifdef HAVE_NETINET_IN_H
        !            25: #include <netinet/in.h>
        !            26: #endif
        !            27: #endif
        !            28: 
        !            29: #include <arpa/inet.h>
        !            30: 
        !            31: /*
        !            32:  * utility functions
        !            33:  */
        !            34: static int     checkitems      (int, FILE *);
        !            35: static int     checkitemsize   (int, int);
        !            36: static int     check1item      (int, FILE *);
        !            37: 
        !            38: /*
        !            39:  * Declarations for command handlers in here
        !            40:  */
        !            41: static void    peerlist        (struct parse *, FILE *);
        !            42: static void    peers           (struct parse *, FILE *);
        !            43: static void    doconfig        (struct parse *pcmd, FILE *fp, int mode, int refc);
        !            44: static void    dmpeers         (struct parse *, FILE *);
        !            45: static void    dopeers         (struct parse *, FILE *, int);
        !            46: static void    printpeer       (struct info_peer *, FILE *);
        !            47: static void    showpeer        (struct parse *, FILE *);
        !            48: static void    peerstats       (struct parse *, FILE *);
        !            49: static void    loopinfo        (struct parse *, FILE *);
        !            50: static void    sysinfo         (struct parse *, FILE *);
        !            51: static void    sysstats        (struct parse *, FILE *);
        !            52: static void    iostats         (struct parse *, FILE *);
        !            53: static void    memstats        (struct parse *, FILE *);
        !            54: static void    timerstats      (struct parse *, FILE *);
        !            55: static void    addpeer         (struct parse *, FILE *);
        !            56: static void    addserver       (struct parse *, FILE *);
        !            57: static void    addrefclock     (struct parse *, FILE *);
        !            58: static void    broadcast       (struct parse *, FILE *);
        !            59: static void    doconfig        (struct parse *, FILE *, int, int);
        !            60: static void    unconfig        (struct parse *, FILE *);
        !            61: static void    set             (struct parse *, FILE *);
        !            62: static void    sys_clear       (struct parse *, FILE *);
        !            63: static void    doset           (struct parse *, FILE *, int);
        !            64: static void    reslist         (struct parse *, FILE *);
        !            65: static void    new_restrict    (struct parse *, FILE *);
        !            66: static void    unrestrict      (struct parse *, FILE *);
        !            67: static void    delrestrict     (struct parse *, FILE *);
        !            68: static void    do_restrict     (struct parse *, FILE *, int);
        !            69: static void    monlist         (struct parse *, FILE *);
        !            70: static void    reset           (struct parse *, FILE *);
        !            71: static void    preset          (struct parse *, FILE *);
        !            72: static void    readkeys        (struct parse *, FILE *);
        !            73: static void    trustkey        (struct parse *, FILE *);
        !            74: static void    untrustkey      (struct parse *, FILE *);
        !            75: static void    do_trustkey     (struct parse *, FILE *, int);
        !            76: static void    authinfo        (struct parse *, FILE *);
        !            77: static void    traps           (struct parse *, FILE *);
        !            78: static void    addtrap         (struct parse *, FILE *);
        !            79: static void    clrtrap         (struct parse *, FILE *);
        !            80: static void    do_addclr_trap  (struct parse *, FILE *, int);
        !            81: static void    requestkey      (struct parse *, FILE *);
        !            82: static void    controlkey      (struct parse *, FILE *);
        !            83: static void    do_changekey    (struct parse *, FILE *, int);
        !            84: static void    ctlstats        (struct parse *, FILE *);
        !            85: static void    clockstat       (struct parse *, FILE *);
        !            86: static void    fudge           (struct parse *, FILE *);
        !            87: static void    clkbug          (struct parse *, FILE *);
        !            88: static void    kerninfo        (struct parse *, FILE *);
        !            89: static  void    get_if_stats    (struct parse *, FILE *);
        !            90: static  void    do_if_reload    (struct parse *, FILE *);
        !            91: 
        !            92: /*
        !            93:  * Commands we understand.  Ntpdc imports this.
        !            94:  */
        !            95: struct xcmd opcmds[] = {
        !            96:        { "listpeers",  peerlist,       { OPT|IP_VERSION, NO, NO, NO },
        !            97:          { "-4|-6", "", "", "" },
        !            98:          "display list of peers the server knows about [IP Version]" },
        !            99:        { "peers",      peers,  { OPT|IP_VERSION, NO, NO, NO },
        !           100:          { "-4|-6", "", "", "" },
        !           101:          "display peer summary information [IP Version]" },
        !           102:        { "dmpeers",    dmpeers,        { OPT|IP_VERSION, NO, NO, NO },
        !           103:          { "-4|-6", "", "", "" },
        !           104:          "display peer summary info the way Dave Mills likes it (IP Version)" },
        !           105:        { "showpeer",   showpeer,       { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD},
        !           106:          { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" },
        !           107:          "display detailed information for one or more peers" },
        !           108:        { "pstats",     peerstats,      { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD },
        !           109:          { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" },
        !           110:          "display statistical information for one or more peers" },
        !           111:        { "loopinfo",   loopinfo,       { OPT|NTP_STR, NO, NO, NO },
        !           112:          { "oneline|multiline", "", "", "" },
        !           113:          "display loop filter information" },
        !           114:        { "sysinfo",    sysinfo,        { NO, NO, NO, NO },
        !           115:          { "", "", "", "" },
        !           116:          "display local server information" },
        !           117:        { "sysstats",   sysstats,       { NO, NO, NO, NO },
        !           118:          { "", "", "", "" },
        !           119:          "display local server statistics" },
        !           120:        { "memstats",   memstats,       { NO, NO, NO, NO },
        !           121:          { "", "", "", "" },
        !           122:          "display peer memory usage statistics" },
        !           123:        { "iostats",    iostats,        { NO, NO, NO, NO },
        !           124:          { "", "", "", "" },
        !           125:          "display I/O subsystem statistics" },
        !           126:        { "timerstats", timerstats,     { NO, NO, NO, NO },
        !           127:          { "", "", "", "" },
        !           128:          "display event timer subsystem statistics" },
        !           129:        { "addpeer",    addpeer,        { NTP_ADD, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR },
        !           130:          { "addr", "keyid", "version", "minpoll#|prefer|burst|iburst|'minpoll N'|'maxpoll N'|'keyid N'|'version N' ..." },
        !           131:          "configure a new peer association" },
        !           132:        { "addserver",  addserver,      { NTP_ADD, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR },
        !           133:          { "addr", "keyid", "version", "minpoll#|prefer|burst|iburst|'minpoll N'|'maxpoll N'|'keyid N'|'version N' ..." },
        !           134:          "configure a new server" },
        !           135:        { "addrefclock",addrefclock,    { NTP_ADD, OPT|NTP_UINT, OPT|NTP_STR, OPT|NTP_STR },
        !           136:          { "addr", "mode", "minpoll|prefer", "minpoll|prefer" },
        !           137:          "configure a new server" },
        !           138:        { "broadcast",  broadcast,      { NTP_ADD, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR },
        !           139:          { "addr", "keyid", "version", "minpoll" },
        !           140:          "configure broadcasting time service" },
        !           141:        { "unconfig",   unconfig,       { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD },
        !           142:          { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" },
        !           143:          "unconfigure existing peer assocations" },
        !           144:        { "enable",     set,            { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR },
        !           145:          { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." },
        !           146:          "set a system flag (auth, bclient, monitor, pll, kernel, stats)" },
        !           147:         { "disable",   sys_clear,      { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR },
        !           148:          { "auth|bclient|monitor|pll|kernel|stats", "...", "...", "..." },
        !           149:          "clear a system flag (auth, bclient, monitor, pll, kernel, stats)" },
        !           150:        { "reslist",    reslist,        {OPT|IP_VERSION, NO, NO, NO },
        !           151:          { "-4|-6", "", "", "" },
        !           152:          "display the server's restrict list" },
        !           153:        { "restrict",   new_restrict,   { NTP_ADD, NTP_ADD, NTP_STR, OPT|NTP_STR },
        !           154:          { "address", "mask",
        !           155:            "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod",
        !           156:            "..." },
        !           157:          "create restrict entry/add flags to entry" },
        !           158:        { "unrestrict", unrestrict,     { NTP_ADD, NTP_ADD, NTP_STR, OPT|NTP_STR },
        !           159:          { "address", "mask",
        !           160:            "ntpport|ignore|noserve|notrust|noquery|nomodify|nopeer|version|kod",
        !           161:            "..." },
        !           162:          "remove flags from a restrict entry" },
        !           163:        { "delrestrict", delrestrict,   { NTP_ADD, NTP_ADD, OPT|NTP_STR, NO },
        !           164:          { "address", "mask", "ntpport", "" },
        !           165:          "delete a restrict entry" },
        !           166:        { "monlist",    monlist,        { OPT|NTP_INT, NO, NO, NO },
        !           167:          { "version", "", "", "" },
        !           168:          "display data the server's monitor routines have collected" },
        !           169:        { "reset",      reset,          { NTP_STR, OPT|NTP_STR, OPT|NTP_STR, OPT|NTP_STR },
        !           170:          { "io|sys|mem|timer|auth|allpeers", "...", "...", "..." },
        !           171:          "reset various subsystem statistics counters" },
        !           172:        { "preset",     preset,         { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD },
        !           173:          { "peer_address", "peer2_addr", "peer3_addr", "peer4_addr" },
        !           174:          "reset stat counters associated with particular peer(s)" },
        !           175:        { "readkeys",   readkeys,       { NO, NO, NO, NO },
        !           176:          { "", "", "", "" },
        !           177:          "request a reread of the keys file and re-init of system keys" },
        !           178:        { "trustedkey", trustkey,       { NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT },
        !           179:          { "keyid", "keyid", "keyid", "keyid" },
        !           180:          "add one or more key ID's to the trusted list" },
        !           181:        { "untrustedkey", untrustkey,   { NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT, OPT|NTP_UINT },
        !           182:          { "keyid", "keyid", "keyid", "keyid" },
        !           183:          "remove one or more key ID's from the trusted list" },
        !           184:        { "authinfo",   authinfo,       { NO, NO, NO, NO },
        !           185:          { "", "", "", "" },
        !           186:          "display the state of the authentication code" },
        !           187:        { "traps",      traps,          { NO, NO, NO, NO },
        !           188:          { "", "", "", "" },
        !           189:          "display the traps set in the server" },
        !           190:        { "addtrap",    addtrap,        { NTP_ADD, OPT|NTP_UINT, OPT|NTP_ADD, NO },
        !           191:          { "address", "port", "interface", "" },
        !           192:          "configure a trap in the server" },
        !           193:        { "clrtrap",    clrtrap,        { NTP_ADD, OPT|NTP_UINT, OPT|NTP_ADD, NO },
        !           194:          { "address", "port", "interface", "" },
        !           195:          "remove a trap (configured or otherwise) from the server" },
        !           196:        { "requestkey", requestkey,     { NTP_UINT, NO, NO, NO },
        !           197:          { "keyid", "", "", "" },
        !           198:          "change the keyid the server uses to authenticate requests" },
        !           199:        { "controlkey", controlkey,     { NTP_UINT, NO, NO, NO },
        !           200:          { "keyid", "", "", "" },
        !           201:          "change the keyid the server uses to authenticate control messages" },
        !           202:        { "ctlstats",   ctlstats,       { NO, NO, NO, NO },
        !           203:          { "", "", "", "" },
        !           204:          "display packet count statistics from the control module" },
        !           205:        { "clockstat",  clockstat,      { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD },
        !           206:          { "address", "address", "address", "address" },
        !           207:          "display clock status information" },
        !           208:        { "fudge",      fudge,          { NTP_ADD, NTP_STR, NTP_STR, NO },
        !           209:          { "address", "time1|time2|val1|val2|flags", "value", "" },
        !           210:          "set/change one of a clock's fudge factors" },
        !           211:        { "clkbug",     clkbug,         { NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD, OPT|NTP_ADD },
        !           212:          { "address", "address", "address", "address" },
        !           213:          "display clock debugging information" },
        !           214:        { "kerninfo",   kerninfo,       { NO, NO, NO, NO },
        !           215:          { "", "", "", "" },
        !           216:          "display the kernel pll/pps variables" },
        !           217:        { "ifstats",    get_if_stats,   { NO, NO, NO, NO },
        !           218:          { "", "", "", "" },
        !           219:          "list interface statistics" },
        !           220:        { "ifreload",   do_if_reload,   { NO, NO, NO, NO },
        !           221:          { "", "", "", "" },
        !           222:          "reload interface configuration" },
        !           223:        { 0,            0,              { NO, NO, NO, NO },
        !           224:          { "", "", "", "" }, "" }
        !           225: };
        !           226: 
        !           227: /*
        !           228:  * For quick string comparisons
        !           229:  */
        !           230: #define        STREQ(a, b)     (*(a) == *(b) && strcmp((a), (b)) == 0)
        !           231: 
        !           232: /*
        !           233:  * SET_SS_LEN_IF_PRESENT - used by SET_ADDR, SET_ADDRS macros
        !           234:  */
        !           235: 
        !           236: #ifdef ISC_PLATFORM_HAVESALEN
        !           237: #define SET_SS_LEN_IF_PRESENT(psau)                            \
        !           238:        do {                                                    \
        !           239:                (psau)->sa.sa_len = SOCKLEN(psau);              \
        !           240:        } while (0)
        !           241: #else
        !           242: #define SET_SS_LEN_IF_PRESENT(psau)    do { } while (0)
        !           243: #endif
        !           244: 
        !           245: /*
        !           246:  * SET_ADDR - setup address for v4/v6 as needed
        !           247:  */
        !           248: #define SET_ADDR(address, v6flag, v4addr, v6addr)              \
        !           249: do {                                                           \
        !           250:        memset(&(address), 0, sizeof(address));                 \
        !           251:        if (v6flag) {                                           \
        !           252:                AF(&(address)) = AF_INET6;                      \
        !           253:                SOCK_ADDR6(&(address)) = (v6addr);              \
        !           254:        } else {                                                \
        !           255:                AF(&(address)) = AF_INET;                       \
        !           256:                NSRCADR(&(address)) = (v4addr);                 \
        !           257:        }                                                       \
        !           258:        SET_SS_LEN_IF_PRESENT(&(address));                      \
        !           259: } while (0)
        !           260: 
        !           261: 
        !           262: /*
        !           263:  * SET_ADDRS - setup source and destination addresses for 
        !           264:  * v4/v6 as needed
        !           265:  */
        !           266: #define SET_ADDRS(a1, a2, info, a1prefix, a2prefix)            \
        !           267: do {                                                           \
        !           268:        memset(&(a1), 0, sizeof(a1));                           \
        !           269:        memset(&(a2), 0, sizeof(a2));                           \
        !           270:        if ((info)->v6_flag) {                                  \
        !           271:                AF(&(a1)) = AF_INET6;                           \
        !           272:                AF(&(a2)) = AF_INET6;                           \
        !           273:                SOCK_ADDR6(&(a1)) = (info)->a1prefix##6;        \
        !           274:                SOCK_ADDR6(&(a2)) = (info)->a2prefix##6;        \
        !           275:        } else {                                                \
        !           276:                AF(&(a1)) = AF_INET;                            \
        !           277:                AF(&(a2)) = AF_INET;                            \
        !           278:                NSRCADR(&(a1)) = (info)->a1prefix;              \
        !           279:                NSRCADR(&(a2)) = (info)->a2prefix;              \
        !           280:        }                                                       \
        !           281:        SET_SS_LEN_IF_PRESENT(&(a1));                           \
        !           282:        SET_SS_LEN_IF_PRESENT(&(a2));                           \
        !           283: } while (0)
        !           284: 
        !           285: 
        !           286: /*
        !           287:  * SET_ADDRS - setup source and destination addresses for 
        !           288:  * v4/v6 as needed
        !           289:  */
        !           290: #if 0
        !           291: #define SET_ADDR_MASK(address, addrmask, info)                 \
        !           292: do {                                                           \
        !           293:        memset(&(address), 0, sizeof(address));                 \
        !           294:        memset(&(mask), 0, sizeof(mask));                       \
        !           295:        if ((info)->v6_flag) {                                  \
        !           296:                AF(&(address)) = AF_INET6;                      \
        !           297:                AF(&(addrmask)) = AF_INET6;                     \
        !           298:                SOCK_ADDR6(&(address)) = (info)->addr6;         \
        !           299:                SOCK_ADDR6(&(addrmask)) = (info)->mask6;        \
        !           300:        } else {                                                \
        !           301:                AF(&(address)) = AF_INET;                       \
        !           302:                AF(&(addrmask)) = AF_INET;                      \
        !           303:                NSRCADR(&(address)) = (info)->addr;             \
        !           304:                NSRCADR(&(addrmask)) = (info)->mask;            \
        !           305:        }                                                       \
        !           306:        SET_SS_LEN_IF_PRESENT(&(address));                      \
        !           307:        SET_SS_LEN_IF_PRESENT(&(addrmask));                     \
        !           308: } while (0)
        !           309: #endif
        !           310: 
        !           311: /*
        !           312:  * checkitems - utility to print a message if no items were returned
        !           313:  */
        !           314: static int
        !           315: checkitems(
        !           316:        int items,
        !           317:        FILE *fp
        !           318:        )
        !           319: {
        !           320:        if (items == 0) {
        !           321:                (void) fprintf(fp, "No data returned in response to query\n");
        !           322:                return 0;
        !           323:        }
        !           324:        return 1;
        !           325: }
        !           326: 
        !           327: 
        !           328: /*
        !           329:  * checkitemsize - utility to print a message if the item size is wrong
        !           330:  */
        !           331: static int
        !           332: checkitemsize(
        !           333:        int itemsize,
        !           334:        int expected
        !           335:        )
        !           336: {
        !           337:        if (itemsize != expected) {
        !           338:                (void) fprintf(stderr,
        !           339:                               "***Incorrect item size returned by remote host (%d should be %d)\n",
        !           340:                               itemsize, expected);
        !           341:                return 0;
        !           342:        }
        !           343:        return 1;
        !           344: }
        !           345: 
        !           346: 
        !           347: /*
        !           348:  * check1item - check to make sure we have exactly one item
        !           349:  */
        !           350: static int
        !           351: check1item(
        !           352:        int items,
        !           353:        FILE *fp
        !           354:        )
        !           355: {
        !           356:        if (items == 0) {
        !           357:                (void) fprintf(fp, "No data returned in response to query\n");
        !           358:                return 0;
        !           359:        }
        !           360:        if (items > 1) {
        !           361:                (void) fprintf(fp, "Expected one item in response, got %d\n",
        !           362:                               items);
        !           363:                return 0;
        !           364:        }
        !           365:        return 1;
        !           366: }
        !           367: 
        !           368: 
        !           369: /*
        !           370:  * peerlist - get a short list of peers
        !           371:  */
        !           372: /*ARGSUSED*/
        !           373: static void
        !           374: peerlist(
        !           375:        struct parse *pcmd,
        !           376:        FILE *fp
        !           377:        )
        !           378: {
        !           379:        struct info_peer_list *plist;
        !           380:        sockaddr_u paddr;
        !           381:        int items;
        !           382:        int itemsize;
        !           383:        int res;
        !           384: 
        !           385: again:
        !           386:        res = doquery(impl_ver, REQ_PEER_LIST, 0, 0, 0, (char *)NULL, &items,
        !           387:                      &itemsize, (void *)&plist, 0, 
        !           388:                      sizeof(struct info_peer_list));
        !           389:        
        !           390:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !           391:                impl_ver = IMPL_XNTPD_OLD;
        !           392:                goto again;
        !           393:        }
        !           394: 
        !           395:        if (res != 0)
        !           396:            return;
        !           397: 
        !           398:        if (!checkitems(items, fp))
        !           399:            return;
        !           400: 
        !           401:        if (!checkitemsize(itemsize, sizeof(struct info_peer_list)) &&
        !           402:            !checkitemsize(itemsize, v4sizeof(struct info_peer_list)))
        !           403:            return;
        !           404: 
        !           405:        while (items > 0) {
        !           406:                SET_ADDR(paddr, plist->v6_flag, plist->addr, plist->addr6);
        !           407:                if ((pcmd->nargs == 0) ||
        !           408:                    ((pcmd->argval->ival == 6) && (plist->v6_flag != 0)) ||
        !           409:                    ((pcmd->argval->ival == 4) && (plist->v6_flag == 0)))
        !           410:                        (void) fprintf(fp, "%-9s %s\n",
        !           411:                                modetoa(plist->hmode),
        !           412:                                nntohost(&paddr));
        !           413:                plist++;
        !           414:                items--;
        !           415:        }
        !           416: }
        !           417: 
        !           418: 
        !           419: /*
        !           420:  * peers - show peer summary
        !           421:  */
        !           422: static void
        !           423: peers(
        !           424:        struct parse *pcmd,
        !           425:        FILE *fp
        !           426:        )
        !           427: {
        !           428:        dopeers(pcmd, fp, 0);
        !           429: }
        !           430: 
        !           431: /*
        !           432:  * dmpeers - show peer summary, Dave Mills style
        !           433:  */
        !           434: static void
        !           435: dmpeers(
        !           436:        struct parse *pcmd,
        !           437:        FILE *fp
        !           438:        )
        !           439: {
        !           440:        dopeers(pcmd, fp, 1);
        !           441: }
        !           442: 
        !           443: 
        !           444: /*
        !           445:  * peers - show peer summary
        !           446:  */
        !           447: /*ARGSUSED*/
        !           448: static void
        !           449: dopeers(
        !           450:        struct parse *pcmd,
        !           451:        FILE *fp,
        !           452:        int dmstyle
        !           453:        )
        !           454: {
        !           455:        struct info_peer_summary *plist;
        !           456:        sockaddr_u dstadr;
        !           457:        sockaddr_u srcadr;
        !           458:        int items;
        !           459:        int itemsize;
        !           460:        int ntp_poll;
        !           461:        int res;
        !           462:        int c;
        !           463:        l_fp tempts;
        !           464: 
        !           465: again:
        !           466:        res = doquery(impl_ver, REQ_PEER_LIST_SUM, 0, 0, 0, (char *)NULL,
        !           467:                      &items, &itemsize, (void *)&plist, 0, 
        !           468:                      sizeof(struct info_peer_summary));
        !           469:        
        !           470:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !           471:                impl_ver = IMPL_XNTPD_OLD;
        !           472:                goto again;
        !           473:        }
        !           474: 
        !           475:        if (res != 0)
        !           476:            return;
        !           477: 
        !           478:        if (!checkitems(items, fp))
        !           479:            return;
        !           480: 
        !           481:        if (!checkitemsize(itemsize, sizeof(struct info_peer_summary)) &&
        !           482:            !checkitemsize(itemsize, v4sizeof(struct info_peer_summary)))
        !           483:                return;
        !           484: 
        !           485:        (void) fprintf(fp,
        !           486:                       "     remote           local      st poll reach  delay   offset    disp\n");
        !           487:        (void) fprintf(fp,
        !           488:                       "=======================================================================\n");
        !           489:        while (items > 0) {
        !           490:                if (!dmstyle) {
        !           491:                        if (plist->flags & INFO_FLAG_SYSPEER)
        !           492:                            c = '*';
        !           493:                        else if (plist->hmode == MODE_ACTIVE)
        !           494:                            c = '+';
        !           495:                        else if (plist->hmode == MODE_PASSIVE)
        !           496:                            c = '-';
        !           497:                        else if (plist->hmode == MODE_CLIENT)
        !           498:                            c = '=';
        !           499:                        else if (plist->hmode == MODE_BROADCAST)
        !           500:                            c = '^';
        !           501:                        else if (plist->hmode == MODE_BCLIENT)
        !           502:                            c = '~';
        !           503:                        else
        !           504:                            c = ' ';
        !           505:                } else {
        !           506:                        if (plist->flags & INFO_FLAG_SYSPEER)
        !           507:                            c = '*';
        !           508:                        else if (plist->flags & INFO_FLAG_SHORTLIST)
        !           509:                            c = '+';
        !           510:                        else if (plist->flags & INFO_FLAG_SEL_CANDIDATE)
        !           511:                            c = '.';
        !           512:                        else
        !           513:                            c = ' ';
        !           514:                }
        !           515:                NTOHL_FP(&(plist->offset), &tempts);
        !           516:                ntp_poll = 1<<max(min3(plist->ppoll, plist->hpoll, NTP_MAXPOLL),
        !           517:                                  NTP_MINPOLL);
        !           518:                SET_ADDRS(dstadr, srcadr, plist, dstadr, srcadr);
        !           519:                if ((pcmd->nargs == 0) ||
        !           520:                    ((pcmd->argval->ival == 6) && (plist->v6_flag != 0)) ||
        !           521:                    ((pcmd->argval->ival == 4) && (plist->v6_flag == 0)))
        !           522:                        (void) fprintf(fp,
        !           523:                            "%c%-15.15s %-15.15s %2u %4d  %3o %7.7s %9.9s %7.7s\n",
        !           524:                            c, nntohost(&srcadr), stoa(&dstadr),
        !           525:                            plist->stratum, ntp_poll, plist->reach,
        !           526:                            fptoa(NTOHS_FP(plist->delay), 5),
        !           527:                            lfptoa(&tempts, 6),
        !           528:                            ufptoa(NTOHS_FP(plist->dispersion), 5));
        !           529:                plist++;
        !           530:                items--;
        !           531:        }
        !           532: }
        !           533: 
        !           534: /* Convert a refid & stratum (in host order) to a string */
        !           535: static char*
        !           536: refid_string(
        !           537:        u_int32 refid,
        !           538:        int stratum
        !           539:        )
        !           540: {
        !           541:        if (stratum <= 1) {
        !           542:                static char junk[5];
        !           543:                junk[4] = 0;
        !           544:                memmove(junk, (char *)&refid, 4);
        !           545:                return junk;
        !           546:        }
        !           547: 
        !           548:        return numtoa(refid);
        !           549: }
        !           550: 
        !           551: static void
        !           552: print_pflag(
        !           553:            FILE *fp,
        !           554:            u_int32 flags
        !           555:            )
        !           556: {
        !           557:      const char *str;
        !           558: 
        !           559:      if (flags == 0) {
        !           560:                (void) fprintf(fp, " none\n");
        !           561:        } else {
        !           562:                str = "";
        !           563:                if (flags & INFO_FLAG_SYSPEER) {
        !           564:                        (void) fprintf(fp, " system_peer");
        !           565:                        str = ",";
        !           566:                }
        !           567:                if (flags & INFO_FLAG_CONFIG) {
        !           568:                        (void) fprintf(fp, "%s config", str);
        !           569:                        str = ",";
        !           570:                }
        !           571:                if (flags & INFO_FLAG_REFCLOCK) {
        !           572:                        (void) fprintf(fp, "%s refclock", str);
        !           573:                        str = ",";
        !           574:                }
        !           575:                if (flags & INFO_FLAG_AUTHENABLE) {
        !           576:                        (void) fprintf(fp, "%s auth", str);
        !           577:                        str = ",";
        !           578:                }
        !           579:                if (flags & INFO_FLAG_BCLIENT) {
        !           580:                        (void) fprintf(fp, "%s bclient", str);
        !           581:                        str = ",";
        !           582:                }
        !           583:                if (flags & INFO_FLAG_PREFER) {
        !           584:                        (void) fprintf(fp, "%s prefer", str);
        !           585:                        str = ",";
        !           586:                }
        !           587:                if (flags & INFO_FLAG_IBURST) {
        !           588:                        (void) fprintf(fp, "%s iburst", str);
        !           589:                        str = ",";
        !           590:                }
        !           591:                if (flags & INFO_FLAG_BURST) {
        !           592:                        (void) fprintf(fp, "%s burst", str);
        !           593:                }
        !           594:                (void) fprintf(fp, "\n");
        !           595:        }
        !           596: }
        !           597: /*
        !           598:  * printpeer - print detail information for a peer
        !           599:  */
        !           600: static void
        !           601: printpeer(
        !           602:        register struct info_peer *pp,
        !           603:        FILE *fp
        !           604:        )
        !           605: {
        !           606:        register int i;
        !           607:        l_fp tempts;
        !           608:        sockaddr_u srcadr, dstadr;
        !           609:        
        !           610:        SET_ADDRS(dstadr, srcadr, pp, dstadr, srcadr);
        !           611:        
        !           612:        (void) fprintf(fp, "remote %s, local %s\n",
        !           613:                       stoa(&srcadr), stoa(&dstadr));
        !           614:        (void) fprintf(fp, "hmode %s, pmode %s, stratum %d, precision %d\n",
        !           615:                       modetoa(pp->hmode), modetoa(pp->pmode),
        !           616:                       pp->stratum, pp->precision);
        !           617:        
        !           618:        (void) fprintf(fp,
        !           619:                       "leap %c%c, refid [%s], rootdistance %s, rootdispersion %s\n",
        !           620:                       pp->leap & 0x2 ? '1' : '0',
        !           621:                       pp->leap & 0x1 ? '1' : '0',
        !           622:                       refid_string(pp->refid, pp->stratum), fptoa(NTOHS_FP(pp->rootdelay), 5),
        !           623:                       ufptoa(NTOHS_FP(pp->rootdispersion), 5));
        !           624:        
        !           625:        (void) fprintf(fp,
        !           626:                       "ppoll %d, hpoll %d, keyid %lu, version %d, association %u\n",
        !           627:                       pp->ppoll, pp->hpoll, (u_long)pp->keyid, pp->version, ntohs(pp->associd));
        !           628: 
        !           629:        (void) fprintf(fp,
        !           630:                       "reach %03o, unreach %d, flash 0x%04x, ",
        !           631:                       pp->reach, pp->unreach, pp->flash2);
        !           632: 
        !           633:        (void) fprintf(fp, "boffset %s, ttl/mode %d\n",
        !           634:                       fptoa(NTOHS_FP(pp->estbdelay), 5), pp->ttl);
        !           635:        
        !           636:        (void) fprintf(fp, "timer %lds, flags", (long)ntohl(pp->timer));
        !           637:        print_pflag(fp, pp->flags); 
        !           638: 
        !           639:        NTOHL_FP(&pp->reftime, &tempts);
        !           640:        (void) fprintf(fp, "reference time:      %s\n",
        !           641:                       prettydate(&tempts));
        !           642:        NTOHL_FP(&pp->org, &tempts);
        !           643:        (void) fprintf(fp, "originate timestamp: %s\n",
        !           644:                       prettydate(&tempts));
        !           645:        NTOHL_FP(&pp->rec, &tempts);
        !           646:        (void) fprintf(fp, "receive timestamp:   %s\n",
        !           647:                       prettydate(&tempts));
        !           648:        NTOHL_FP(&pp->xmt, &tempts);
        !           649:        (void) fprintf(fp, "transmit timestamp:  %s\n",
        !           650:                       prettydate(&tempts));
        !           651:        
        !           652:        (void) fprintf(fp, "filter delay: ");
        !           653:        for (i = 0; i < NTP_SHIFT; i++) {
        !           654:                (void) fprintf(fp, " %-8.8s",
        !           655:                               fptoa(NTOHS_FP(pp->filtdelay[i]), 5));
        !           656:                if (i == (NTP_SHIFT>>1)-1)
        !           657:                    (void) fprintf(fp, "\n              ");
        !           658:        }
        !           659:        (void) fprintf(fp, "\n");
        !           660: 
        !           661:        (void) fprintf(fp, "filter offset:");
        !           662:        for (i = 0; i < NTP_SHIFT; i++) {
        !           663:                NTOHL_FP(&pp->filtoffset[i], &tempts);
        !           664:                (void) fprintf(fp, " %-8.8s", lfptoa(&tempts, 6));
        !           665:                if (i == (NTP_SHIFT>>1)-1)
        !           666:                    (void) fprintf(fp, "\n              ");
        !           667:        }
        !           668:        (void) fprintf(fp, "\n");
        !           669: 
        !           670:        (void) fprintf(fp, "filter order: ");
        !           671:        for (i = 0; i < NTP_SHIFT; i++) {
        !           672:                (void) fprintf(fp, " %-8d", pp->order[i]);
        !           673:                if (i == (NTP_SHIFT>>1)-1)
        !           674:                    (void) fprintf(fp, "\n              ");
        !           675:        }
        !           676:        (void) fprintf(fp, "\n");
        !           677:        
        !           678: 
        !           679:        NTOHL_FP(&pp->offset, &tempts);
        !           680:        (void) fprintf(fp,
        !           681:                       "offset %s, delay %s, error bound %s, filter error %s\n",
        !           682:                       lfptoa(&tempts, 6), fptoa(NTOHS_FP(pp->delay), 5),
        !           683:                       ufptoa(NTOHS_FP(pp->dispersion), 5),
        !           684:                       ufptoa(NTOHS_FP(pp->selectdisp), 5));
        !           685: }
        !           686: 
        !           687: 
        !           688: /*
        !           689:  * showpeer - show detailed information for a peer
        !           690:  */
        !           691: static void
        !           692: showpeer(
        !           693:        struct parse *pcmd,
        !           694:        FILE *fp
        !           695:        )
        !           696: {
        !           697:        struct info_peer *pp;
        !           698:        /* 4 is the maximum number of peers which will fit in a packet */
        !           699:        struct info_peer_list *pl, plist[min(MAXARGS, 4)];
        !           700:        int qitemlim;
        !           701:        int qitems;
        !           702:        int items;
        !           703:        int itemsize;
        !           704:        int res;
        !           705:        int sendsize;
        !           706: 
        !           707: again:
        !           708:        if (impl_ver == IMPL_XNTPD)
        !           709:                sendsize = sizeof(struct info_peer_list);
        !           710:        else
        !           711:                sendsize = v4sizeof(struct info_peer_list);
        !           712: 
        !           713:        qitemlim = min(pcmd->nargs, COUNTOF(plist));
        !           714:        for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) {
        !           715:                if (IS_IPV4(&pcmd->argval[qitems].netnum)) {
        !           716:                        pl->addr = NSRCADR(&pcmd->argval[qitems].netnum);
        !           717:                        if (impl_ver == IMPL_XNTPD)
        !           718:                                pl->v6_flag = 0;
        !           719:                } else {
        !           720:                        if (impl_ver == IMPL_XNTPD_OLD) {
        !           721:                                fprintf(stderr,
        !           722:                                    "***Server doesn't understand IPv6 addresses\n");
        !           723:                                return;
        !           724:                        }
        !           725:                        pl->addr6 = SOCK_ADDR6(&pcmd->argval[qitems].netnum);
        !           726:                        pl->v6_flag = 1;
        !           727:                }
        !           728:                pl->port = (u_short)s_port;
        !           729:                pl->hmode = pl->flags = 0;
        !           730:                pl = (struct info_peer_list *)((char *)pl + sendsize);
        !           731:        }
        !           732: 
        !           733:        res = doquery(impl_ver, REQ_PEER_INFO, 0, qitems,
        !           734:                      sendsize, (char *)plist, &items,
        !           735:                      &itemsize, (void *)&pp, 0, sizeof(struct info_peer));
        !           736:        
        !           737:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !           738:                impl_ver = IMPL_XNTPD_OLD;
        !           739:                goto again;
        !           740:        }
        !           741: 
        !           742:        if (res != 0)
        !           743:            return;
        !           744: 
        !           745:        if (!checkitems(items, fp))
        !           746:            return;
        !           747: 
        !           748:        if (!checkitemsize(itemsize, sizeof(struct info_peer)) &&
        !           749:            !checkitemsize(itemsize, v4sizeof(struct info_peer)))
        !           750:            return;
        !           751: 
        !           752:        while (items-- > 0) {
        !           753:                printpeer(pp, fp);
        !           754:                if (items > 0)
        !           755:                    (void) fprintf(fp, "\n");
        !           756:                pp++;
        !           757:        }
        !           758: }
        !           759: 
        !           760: 
        !           761: /*
        !           762:  * peerstats - return statistics for a peer
        !           763:  */
        !           764: static void
        !           765: peerstats(
        !           766:        struct parse *pcmd,
        !           767:        FILE *fp
        !           768:        )
        !           769: {
        !           770:        struct info_peer_stats *pp;
        !           771:        /* 4 is the maximum number of peers which will fit in a packet */
        !           772:        struct info_peer_list *pl, plist[min(MAXARGS, 4)];
        !           773:        sockaddr_u src, dst;
        !           774:        int qitemlim;
        !           775:        int qitems;
        !           776:        int items;
        !           777:        int itemsize;
        !           778:        int res;
        !           779:        int sendsize;
        !           780: 
        !           781: again:
        !           782:        if (impl_ver == IMPL_XNTPD)
        !           783:                sendsize = sizeof(struct info_peer_list);
        !           784:        else
        !           785:                sendsize = v4sizeof(struct info_peer_list);
        !           786: 
        !           787:        memset(plist, 0, sizeof(plist));
        !           788: 
        !           789:        qitemlim = min(pcmd->nargs, COUNTOF(plist));
        !           790:        for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) {
        !           791:                if (IS_IPV4(&pcmd->argval[qitems].netnum)) {
        !           792:                        pl->addr = NSRCADR(&pcmd->argval[qitems].netnum);
        !           793:                        if (impl_ver == IMPL_XNTPD)
        !           794:                                pl->v6_flag = 0;
        !           795:                } else {
        !           796:                        if (impl_ver == IMPL_XNTPD_OLD) {
        !           797:                                fprintf(stderr,
        !           798:                                    "***Server doesn't understand IPv6 addresses\n");
        !           799:                                return;
        !           800:                        }
        !           801:                        pl->addr6 = SOCK_ADDR6(&pcmd->argval[qitems].netnum);
        !           802:                        pl->v6_flag = 1;
        !           803:                }
        !           804:                pl->port = (u_short)s_port;
        !           805:                pl->hmode = plist[qitems].flags = 0;
        !           806:                pl = (struct info_peer_list *)((char *)pl + sendsize);
        !           807:        }
        !           808: 
        !           809:        res = doquery(impl_ver, REQ_PEER_STATS, 0, qitems,
        !           810:                      sendsize, (char *)plist, &items,
        !           811:                      &itemsize, (void *)&pp, 0, 
        !           812:                      sizeof(struct info_peer_stats));
        !           813:        
        !           814:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !           815:                impl_ver = IMPL_XNTPD_OLD;
        !           816:                goto again;
        !           817:        }
        !           818: 
        !           819:        if (res != 0)
        !           820:            return;
        !           821: 
        !           822:        if (!checkitems(items, fp))
        !           823:            return;
        !           824: 
        !           825:        if (!checkitemsize(itemsize, sizeof(struct info_peer_stats)) &&
        !           826:            !checkitemsize(itemsize, v4sizeof(struct info_peer_stats)))
        !           827:            return;
        !           828: 
        !           829:        while (items-- > 0) {
        !           830:                ZERO_SOCK(&dst);
        !           831:                ZERO_SOCK(&src);
        !           832:                if (pp->v6_flag != 0) {
        !           833:                        AF(&dst) = AF_INET6;
        !           834:                        AF(&src) = AF_INET6;
        !           835:                        SOCK_ADDR6(&dst) = pp->dstadr6;
        !           836:                        SOCK_ADDR6(&src) = pp->srcadr6;
        !           837:                } else {
        !           838:                        AF(&dst) = AF_INET;
        !           839:                        AF(&src) = AF_INET;
        !           840:                        NSRCADR(&dst) = pp->dstadr;
        !           841:                        NSRCADR(&src) = pp->srcadr;
        !           842:                }
        !           843: #ifdef ISC_PLATFORM_HAVESALEN
        !           844:                src.sa.sa_len = SOCKLEN(&src);
        !           845:                dst.sa.sa_len = SOCKLEN(&dst);
        !           846: #endif
        !           847:                fprintf(fp, "remote host:          %s\n",
        !           848:                        nntohost(&src));
        !           849:                fprintf(fp, "local interface:      %s\n",
        !           850:                        stoa(&dst));
        !           851:                fprintf(fp, "time last received:   %lus\n",
        !           852:                        (u_long)ntohl(pp->timereceived));
        !           853:                fprintf(fp, "time until next send: %lus\n",
        !           854:                        (u_long)ntohl(pp->timetosend));
        !           855:                fprintf(fp, "reachability change:  %lus\n",
        !           856:                        (u_long)ntohl(pp->timereachable));
        !           857:                fprintf(fp, "packets sent:         %lu\n",
        !           858:                        (u_long)ntohl(pp->sent));
        !           859:                fprintf(fp, "packets received:     %lu\n",
        !           860:                        (u_long)ntohl(pp->processed));
        !           861:                fprintf(fp, "bad authentication:   %lu\n",
        !           862:                        (u_long)ntohl(pp->badauth));
        !           863:                fprintf(fp, "bogus origin:         %lu\n",
        !           864:                        (u_long)ntohl(pp->bogusorg));
        !           865:                fprintf(fp, "duplicate:            %lu\n",
        !           866:                        (u_long)ntohl(pp->oldpkt));
        !           867:                fprintf(fp, "bad dispersion:       %lu\n",
        !           868:                        (u_long)ntohl(pp->seldisp));
        !           869:                fprintf(fp, "bad reference time:   %lu\n",
        !           870:                        (u_long)ntohl(pp->selbroken));
        !           871:                fprintf(fp, "candidate order:      %u\n",
        !           872:                        pp->candidate);
        !           873:                if (items > 0)
        !           874:                        fprintf(fp, "\n");
        !           875:                fprintf(fp, "flags:     ");
        !           876:                print_pflag(fp, ntohs(pp->flags));
        !           877:                pp++;
        !           878:        }
        !           879: }
        !           880: 
        !           881: 
        !           882: /*
        !           883:  * loopinfo - show loop filter information
        !           884:  */
        !           885: static void
        !           886: loopinfo(
        !           887:        struct parse *pcmd,
        !           888:        FILE *fp
        !           889:        )
        !           890: {
        !           891:        struct info_loop *il;
        !           892:        int items;
        !           893:        int itemsize;
        !           894:        int oneline = 0;
        !           895:        int res;
        !           896:        l_fp tempts;
        !           897: 
        !           898:        if (pcmd->nargs > 0) {
        !           899:                if (STREQ(pcmd->argval[0].string, "oneline"))
        !           900:                    oneline = 1;
        !           901:                else if (STREQ(pcmd->argval[0].string, "multiline"))
        !           902:                    oneline = 0;
        !           903:                else {
        !           904:                        (void) fprintf(stderr, "How many lines?\n");
        !           905:                        return;
        !           906:                }
        !           907:        }
        !           908: 
        !           909: again:
        !           910:        res = doquery(impl_ver, REQ_LOOP_INFO, 0, 0, 0, (char *)NULL,
        !           911:                      &items, &itemsize, (void *)&il, 0, 
        !           912:                      sizeof(struct info_loop));
        !           913:        
        !           914:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !           915:                impl_ver = IMPL_XNTPD_OLD;
        !           916:                goto again;
        !           917:        }
        !           918: 
        !           919:        if (res != 0)
        !           920:            return;
        !           921: 
        !           922:        if (!check1item(items, fp))
        !           923:            return;
        !           924: 
        !           925:        if (!checkitemsize(itemsize, sizeof(struct info_loop)))
        !           926:            return;
        !           927: 
        !           928:        if (oneline) {
        !           929:                l_fp temp2ts;
        !           930: 
        !           931:                NTOHL_FP(&il->last_offset, &tempts);
        !           932:                NTOHL_FP(&il->drift_comp, &temp2ts);
        !           933: 
        !           934:                (void) fprintf(fp,
        !           935:                               "offset %s, frequency %s, time_const %ld, watchdog %ld\n",
        !           936:                               lfptoa(&tempts, 6),
        !           937:                               lfptoa(&temp2ts, 3),
        !           938:                               (long)(int32)ntohl((u_long)il->compliance),
        !           939:                               (u_long)ntohl((u_long)il->watchdog_timer));
        !           940:        } else {
        !           941:                NTOHL_FP(&il->last_offset, &tempts);
        !           942:                (void) fprintf(fp, "offset:               %s s\n",
        !           943:                               lfptoa(&tempts, 6));
        !           944:                NTOHL_FP(&il->drift_comp, &tempts);
        !           945:                (void) fprintf(fp, "frequency:            %s ppm\n",
        !           946:                               lfptoa(&tempts, 3));
        !           947:                (void) fprintf(fp, "poll adjust:          %ld\n",
        !           948:                               (long)(int32)ntohl(il->compliance));
        !           949:                (void) fprintf(fp, "watchdog timer:       %ld s\n",
        !           950:                               (u_long)ntohl(il->watchdog_timer));
        !           951:        }
        !           952: }
        !           953: 
        !           954: 
        !           955: /*
        !           956:  * sysinfo - show current system state
        !           957:  */
        !           958: /*ARGSUSED*/
        !           959: static void
        !           960: sysinfo(
        !           961:        struct parse *pcmd,
        !           962:        FILE *fp
        !           963:        )
        !           964: {
        !           965:        struct info_sys *is;
        !           966:        sockaddr_u peeraddr;
        !           967:        int items;
        !           968:        int itemsize;
        !           969:        int res;
        !           970:        l_fp tempts;
        !           971: 
        !           972: again:
        !           973:        res = doquery(impl_ver, REQ_SYS_INFO, 0, 0, 0, (char *)NULL,
        !           974:                      &items, &itemsize, (void *)&is, 0,
        !           975:                      sizeof(struct info_sys));
        !           976:        
        !           977:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !           978:                impl_ver = IMPL_XNTPD_OLD;
        !           979:                goto again;
        !           980:        }
        !           981: 
        !           982:        if (res != 0)
        !           983:            return;
        !           984: 
        !           985:        if (!check1item(items, fp))
        !           986:            return;
        !           987: 
        !           988:        if (!checkitemsize(itemsize, sizeof(struct info_sys)) &&
        !           989:            !checkitemsize(itemsize, v4sizeof(struct info_sys)))
        !           990:            return;
        !           991: 
        !           992:        SET_ADDR(peeraddr, is->v6_flag, is->peer, is->peer6);
        !           993: 
        !           994:        (void) fprintf(fp, "system peer:          %s\n", nntohost(&peeraddr));
        !           995:        (void) fprintf(fp, "system peer mode:     %s\n", modetoa(is->peer_mode));
        !           996:        (void) fprintf(fp, "leap indicator:       %c%c\n",
        !           997:                       is->leap & 0x2 ? '1' : '0',
        !           998:                       is->leap & 0x1 ? '1' : '0');
        !           999:        (void) fprintf(fp, "stratum:              %d\n", (int)is->stratum);
        !          1000:        (void) fprintf(fp, "precision:            %d\n", (int)is->precision);
        !          1001:        (void) fprintf(fp, "root distance:        %s s\n",
        !          1002:                       fptoa(NTOHS_FP(is->rootdelay), 5));
        !          1003:        (void) fprintf(fp, "root dispersion:      %s s\n",
        !          1004:                       ufptoa(NTOHS_FP(is->rootdispersion), 5));
        !          1005:        (void) fprintf(fp, "reference ID:         [%s]\n",
        !          1006:                       refid_string(is->refid, is->stratum));
        !          1007:        NTOHL_FP(&is->reftime, &tempts);
        !          1008:        (void) fprintf(fp, "reference time:       %s\n", prettydate(&tempts));
        !          1009: 
        !          1010:        (void) fprintf(fp, "system flags:         ");
        !          1011:        if ((is->flags & (INFO_FLAG_BCLIENT | INFO_FLAG_AUTHENABLE |
        !          1012:            INFO_FLAG_NTP | INFO_FLAG_KERNEL| INFO_FLAG_CAL |
        !          1013:            INFO_FLAG_PPS_SYNC | INFO_FLAG_MONITOR | INFO_FLAG_FILEGEN)) == 0) {
        !          1014:                (void) fprintf(fp, "none\n");
        !          1015:        } else {
        !          1016:                if (is->flags & INFO_FLAG_BCLIENT)
        !          1017:                    (void) fprintf(fp, "bclient ");
        !          1018:                if (is->flags & INFO_FLAG_AUTHENTICATE)
        !          1019:                    (void) fprintf(fp, "auth ");
        !          1020:                if (is->flags & INFO_FLAG_MONITOR)
        !          1021:                    (void) fprintf(fp, "monitor ");
        !          1022:                if (is->flags & INFO_FLAG_NTP)
        !          1023:                    (void) fprintf(fp, "ntp ");
        !          1024:                if (is->flags & INFO_FLAG_KERNEL)
        !          1025:                    (void) fprintf(fp, "kernel ");
        !          1026:                if (is->flags & INFO_FLAG_FILEGEN)
        !          1027:                    (void) fprintf(fp, "stats ");
        !          1028:                if (is->flags & INFO_FLAG_CAL)
        !          1029:                    (void) fprintf(fp, "calibrate ");
        !          1030:                if (is->flags & INFO_FLAG_PPS_SYNC)
        !          1031:                    (void) fprintf(fp, "pps ");
        !          1032:                (void) fprintf(fp, "\n");
        !          1033:        }
        !          1034:        (void) fprintf(fp, "jitter:               %s s\n",
        !          1035:                       fptoa(ntohl(is->frequency), 6));
        !          1036:        (void) fprintf(fp, "stability:            %s ppm\n",
        !          1037:                       ufptoa(ntohl(is->stability), 3));
        !          1038:        (void) fprintf(fp, "broadcastdelay:       %s s\n",
        !          1039:                       fptoa(NTOHS_FP(is->bdelay), 6));
        !          1040:        NTOHL_FP(&is->authdelay, &tempts);
        !          1041:        (void) fprintf(fp, "authdelay:            %s s\n", lfptoa(&tempts, 6));
        !          1042: }
        !          1043: 
        !          1044: 
        !          1045: /*
        !          1046:  * sysstats - print system statistics
        !          1047:  */
        !          1048: /*ARGSUSED*/
        !          1049: static void
        !          1050: sysstats(
        !          1051:        struct parse *pcmd,
        !          1052:        FILE *fp
        !          1053:        )
        !          1054: {
        !          1055:        struct info_sys_stats *ss;
        !          1056:        int items;
        !          1057:        int itemsize;
        !          1058:        int res;
        !          1059: 
        !          1060: again:
        !          1061:        res = doquery(impl_ver, REQ_SYS_STATS, 0, 0, 0, (char *)NULL,
        !          1062:                      &items, &itemsize, (void *)&ss, 0, 
        !          1063:                      sizeof(struct info_sys_stats));
        !          1064:        
        !          1065:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          1066:                impl_ver = IMPL_XNTPD_OLD;
        !          1067:                goto again;
        !          1068:        }
        !          1069: 
        !          1070:        if (res != 0)
        !          1071:            return;
        !          1072: 
        !          1073:        if (!check1item(items, fp))
        !          1074:            return;
        !          1075: 
        !          1076:        if (itemsize != sizeof(struct info_sys_stats) &&
        !          1077:            itemsize != sizeof(struct old_info_sys_stats)) {
        !          1078:                /* issue warning according to new structure size */
        !          1079:                checkitemsize(itemsize, sizeof(struct info_sys_stats));
        !          1080:                return;
        !          1081:        }
        !          1082:        fprintf(fp, "time since restart:     %lu\n",
        !          1083:                (u_long)ntohl(ss->timeup));
        !          1084:        fprintf(fp, "time since reset:       %lu\n",
        !          1085:                (u_long)ntohl(ss->timereset));
        !          1086:        fprintf(fp, "packets received:       %lu\n",
        !          1087:                (u_long)ntohl(ss->received));
        !          1088:        fprintf(fp, "packets processed:      %lu\n",
        !          1089:                (u_long)ntohl(ss->processed));
        !          1090:        fprintf(fp, "current version:        %lu\n",
        !          1091:                (u_long)ntohl(ss->newversionpkt));
        !          1092:        fprintf(fp, "previous version:       %lu\n",
        !          1093:                (u_long)ntohl(ss->oldversionpkt));
        !          1094:        fprintf(fp, "declined:               %lu\n",
        !          1095:                (u_long)ntohl(ss->unknownversion));
        !          1096:        fprintf(fp, "access denied:          %lu\n",
        !          1097:                (u_long)ntohl(ss->denied));
        !          1098:        fprintf(fp, "bad length or format:   %lu\n",
        !          1099:                (u_long)ntohl(ss->badlength));
        !          1100:        fprintf(fp, "bad authentication:     %lu\n",
        !          1101:                (u_long)ntohl(ss->badauth));
        !          1102:        if (itemsize != sizeof(struct info_sys_stats))
        !          1103:            return;
        !          1104:        
        !          1105:        fprintf(fp, "rate exceeded:          %lu\n",
        !          1106:               (u_long)ntohl(ss->limitrejected));
        !          1107: }
        !          1108: 
        !          1109: 
        !          1110: 
        !          1111: /*
        !          1112:  * iostats - print I/O statistics
        !          1113:  */
        !          1114: /*ARGSUSED*/
        !          1115: static void
        !          1116: iostats(
        !          1117:        struct parse *pcmd,
        !          1118:        FILE *fp
        !          1119:        )
        !          1120: {
        !          1121:        struct info_io_stats *io;
        !          1122:        int items;
        !          1123:        int itemsize;
        !          1124:        int res;
        !          1125: 
        !          1126: again:
        !          1127:        res = doquery(impl_ver, REQ_IO_STATS, 0, 0, 0, NULL, &items,
        !          1128:                      &itemsize, (void *)&io, 0, sizeof(*io));
        !          1129:        
        !          1130:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          1131:                impl_ver = IMPL_XNTPD_OLD;
        !          1132:                goto again;
        !          1133:        }
        !          1134: 
        !          1135:        if (res != 0)
        !          1136:                return;
        !          1137: 
        !          1138:        if (!check1item(items, fp))
        !          1139:                return;
        !          1140: 
        !          1141:        if (!checkitemsize(itemsize, sizeof(*io)))
        !          1142:                return;
        !          1143: 
        !          1144:        fprintf(fp, "time since reset:     %lu\n",
        !          1145:                (u_long)ntohl(io->timereset));
        !          1146:        fprintf(fp, "receive buffers:      %u\n",
        !          1147:                (u_int)ntohs(io->totalrecvbufs));
        !          1148:        fprintf(fp, "free receive buffers: %u\n",
        !          1149:                (u_int)ntohs(io->freerecvbufs));
        !          1150:        fprintf(fp, "used receive buffers: %u\n",
        !          1151:                (u_int)ntohs(io->fullrecvbufs));
        !          1152:        fprintf(fp, "low water refills:    %u\n",
        !          1153:                (u_int)ntohs(io->lowwater));
        !          1154:        fprintf(fp, "dropped packets:      %lu\n",
        !          1155:                (u_long)ntohl(io->dropped));
        !          1156:        fprintf(fp, "ignored packets:      %lu\n",
        !          1157:                (u_long)ntohl(io->ignored));
        !          1158:        fprintf(fp, "received packets:     %lu\n",
        !          1159:                (u_long)ntohl(io->received));
        !          1160:        fprintf(fp, "packets sent:         %lu\n",
        !          1161:                (u_long)ntohl(io->sent));
        !          1162:        fprintf(fp, "packets not sent:     %lu\n",
        !          1163:                (u_long)ntohl(io->notsent));
        !          1164:        fprintf(fp, "interrupts handled:   %lu\n",
        !          1165:                (u_long)ntohl(io->interrupts));
        !          1166:        fprintf(fp, "received by int:      %lu\n",
        !          1167:                (u_long)ntohl(io->int_received));
        !          1168: }
        !          1169: 
        !          1170: 
        !          1171: /*
        !          1172:  * memstats - print peer memory statistics
        !          1173:  */
        !          1174: /*ARGSUSED*/
        !          1175: static void
        !          1176: memstats(
        !          1177:        struct parse *pcmd,
        !          1178:        FILE *fp
        !          1179:        )
        !          1180: {
        !          1181:        struct info_mem_stats *mem;
        !          1182:        int i;
        !          1183:        int items;
        !          1184:        int itemsize;
        !          1185:        int res;
        !          1186: 
        !          1187: again:
        !          1188:        res = doquery(impl_ver, REQ_MEM_STATS, 0, 0, 0, NULL, &items,
        !          1189:                      &itemsize, (void *)&mem, 0, sizeof(*mem));
        !          1190:        
        !          1191:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          1192:                impl_ver = IMPL_XNTPD_OLD;
        !          1193:                goto again;
        !          1194:        }
        !          1195: 
        !          1196:        if (res != 0)
        !          1197:                return;
        !          1198: 
        !          1199:        if (!check1item(items, fp))
        !          1200:                return;
        !          1201: 
        !          1202:        if (!checkitemsize(itemsize, sizeof(*mem)))
        !          1203:                return;
        !          1204: 
        !          1205:        fprintf(fp, "time since reset:     %lu\n",
        !          1206:                (u_long)ntohl(mem->timereset));
        !          1207:        fprintf(fp, "total peer memory:    %u\n",
        !          1208:                (u_int)ntohs(mem->totalpeermem));
        !          1209:        fprintf(fp, "free peer memory:     %u\n",
        !          1210:                (u_int)ntohs(mem->freepeermem));
        !          1211:        fprintf(fp, "calls to findpeer:    %lu\n",
        !          1212:                (u_long)ntohl(mem->findpeer_calls));
        !          1213:        fprintf(fp, "new peer allocations: %lu\n",
        !          1214:                (u_long)ntohl(mem->allocations));
        !          1215:        fprintf(fp, "peer demobilizations: %lu\n",
        !          1216:                (u_long)ntohl(mem->demobilizations));
        !          1217: 
        !          1218:        fprintf(fp, "hash table counts:   ");
        !          1219:        for (i = 0; i < NTP_HASH_SIZE; i++) {
        !          1220:                fprintf(fp, "%4d", (int)mem->hashcount[i]);
        !          1221:                if ((i % 8) == 7 && i != (NTP_HASH_SIZE-1))
        !          1222:                        fprintf(fp, "\n                     ");
        !          1223:        }
        !          1224:        fprintf(fp, "\n");
        !          1225: }
        !          1226: 
        !          1227: 
        !          1228: 
        !          1229: /*
        !          1230:  * timerstats - print timer statistics
        !          1231:  */
        !          1232: /*ARGSUSED*/
        !          1233: static void
        !          1234: timerstats(
        !          1235:        struct parse *pcmd,
        !          1236:        FILE *fp
        !          1237:        )
        !          1238: {
        !          1239:        struct info_timer_stats *tim;
        !          1240:        int items;
        !          1241:        int itemsize;
        !          1242:        int res;
        !          1243: 
        !          1244: again:
        !          1245:        res = doquery(impl_ver, REQ_TIMER_STATS, 0, 0, 0, NULL, &items,
        !          1246:                      &itemsize, (void *)&tim, 0, sizeof(*tim));
        !          1247:        
        !          1248:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          1249:                impl_ver = IMPL_XNTPD_OLD;
        !          1250:                goto again;
        !          1251:        }
        !          1252: 
        !          1253:        if (res != 0)
        !          1254:                return;
        !          1255: 
        !          1256:        if (!check1item(items, fp))
        !          1257:                return;
        !          1258: 
        !          1259:        if (!checkitemsize(itemsize, sizeof(*tim)))
        !          1260:                return;
        !          1261: 
        !          1262:        fprintf(fp, "time since reset:  %lu\n",
        !          1263:                (u_long)ntohl(tim->timereset));
        !          1264:        fprintf(fp, "alarms handled:    %lu\n",
        !          1265:                (u_long)ntohl(tim->alarms));
        !          1266:        fprintf(fp, "alarm overruns:    %lu\n",
        !          1267:                (u_long)ntohl(tim->overflows));
        !          1268:        fprintf(fp, "calls to transmit: %lu\n",
        !          1269:                (u_long)ntohl(tim->xmtcalls));
        !          1270: }
        !          1271: 
        !          1272: 
        !          1273: /*
        !          1274:  * addpeer - configure an active mode association
        !          1275:  */
        !          1276: static void
        !          1277: addpeer(
        !          1278:        struct parse *pcmd,
        !          1279:        FILE *fp
        !          1280:        )
        !          1281: {
        !          1282:        doconfig(pcmd, fp, MODE_ACTIVE, 0);
        !          1283: }
        !          1284: 
        !          1285: 
        !          1286: /*
        !          1287:  * addserver - configure a client mode association
        !          1288:  */
        !          1289: static void
        !          1290: addserver(
        !          1291:        struct parse *pcmd,
        !          1292:        FILE *fp
        !          1293:        )
        !          1294: {
        !          1295:        doconfig(pcmd, fp, MODE_CLIENT, 0);
        !          1296: }
        !          1297: 
        !          1298: /*
        !          1299:  * addrefclock - configure a reference clock association
        !          1300:  */
        !          1301: static void
        !          1302: addrefclock(
        !          1303:        struct parse *pcmd,
        !          1304:        FILE *fp
        !          1305:        )
        !          1306: {
        !          1307:        doconfig(pcmd, fp, MODE_CLIENT, 1);
        !          1308: }
        !          1309: 
        !          1310: /*
        !          1311:  * broadcast - configure a broadcast mode association
        !          1312:  */
        !          1313: static void
        !          1314: broadcast(
        !          1315:        struct parse *pcmd,
        !          1316:        FILE *fp
        !          1317:        )
        !          1318: {
        !          1319:        doconfig(pcmd, fp, MODE_BROADCAST, 0);
        !          1320: }
        !          1321: 
        !          1322: 
        !          1323: /*
        !          1324:  * config - configure a new peer association
        !          1325:  */
        !          1326: static void
        !          1327: doconfig(
        !          1328:        struct parse *pcmd,
        !          1329:        FILE *fp,
        !          1330:        int mode,
        !          1331:        int refc
        !          1332:        )
        !          1333: {
        !          1334:        struct conf_peer cpeer;
        !          1335:        int items;
        !          1336:        int itemsize;
        !          1337:        char *dummy;
        !          1338:        u_long keyid;
        !          1339:        u_int version;
        !          1340:        u_char minpoll;
        !          1341:        u_char maxpoll;
        !          1342:        u_int flags;
        !          1343:        u_char cmode;
        !          1344:        int res;
        !          1345:        int sendsize;
        !          1346:        int numtyp;
        !          1347:        long val;
        !          1348: 
        !          1349: again:
        !          1350:        keyid = 0;
        !          1351:        version = 3;
        !          1352:        flags = 0;
        !          1353:        res = FALSE;
        !          1354:        cmode = 0;
        !          1355:        minpoll = NTP_MINDPOLL;
        !          1356:        maxpoll = NTP_MAXDPOLL;
        !          1357:        numtyp = 1;
        !          1358:        if (refc)
        !          1359:                numtyp = 5;
        !          1360: 
        !          1361:        if (impl_ver == IMPL_XNTPD)
        !          1362:                sendsize = sizeof(struct conf_peer);
        !          1363:        else
        !          1364:                sendsize = v4sizeof(struct conf_peer);
        !          1365: 
        !          1366:        items = 1;
        !          1367:        while (pcmd->nargs > items) {
        !          1368:                if (STREQ(pcmd->argval[items].string, "prefer"))
        !          1369:                        flags |= CONF_FLAG_PREFER;
        !          1370:                else if (STREQ(pcmd->argval[items].string, "burst"))
        !          1371:                        flags |= CONF_FLAG_BURST;
        !          1372:                else if (STREQ(pcmd->argval[items].string, "iburst"))
        !          1373:                        flags |= CONF_FLAG_IBURST;
        !          1374:                else if (!refc && STREQ(pcmd->argval[items].string, "keyid"))
        !          1375:                        numtyp = 1;
        !          1376:                else if (!refc && STREQ(pcmd->argval[items].string, "version"))
        !          1377:                        numtyp = 2;
        !          1378:                else if (STREQ(pcmd->argval[items].string, "minpoll"))
        !          1379:                        numtyp = 3;
        !          1380:                else if (STREQ(pcmd->argval[items].string, "maxpoll"))
        !          1381:                        numtyp = 4;
        !          1382:                else {
        !          1383:                        if (!atoint(pcmd->argval[items].string, &val))
        !          1384:                                numtyp = 0;
        !          1385:                        switch (numtyp) {
        !          1386:                        case 1:
        !          1387:                                keyid = val;
        !          1388:                                numtyp = 2;
        !          1389:                                break;
        !          1390: 
        !          1391:                        case 2:
        !          1392:                                version = (u_int)val;
        !          1393:                                numtyp = 0;
        !          1394:                                break;
        !          1395: 
        !          1396:                        case 3:
        !          1397:                                minpoll = (u_char)val;
        !          1398:                                numtyp = 0;
        !          1399:                                break;
        !          1400: 
        !          1401:                        case 4:
        !          1402:                                maxpoll = (u_char)val;
        !          1403:                                numtyp = 0;
        !          1404:                                break;
        !          1405: 
        !          1406:                        case 5:
        !          1407:                                cmode = (u_char)val;
        !          1408:                                numtyp = 0;
        !          1409:                                break;
        !          1410: 
        !          1411:                        default:
        !          1412:                                fprintf(fp, "*** '%s' not understood\n",
        !          1413:                                        pcmd->argval[items].string);
        !          1414:                                res = TRUE;
        !          1415:                                numtyp = 0;
        !          1416:                        }
        !          1417:                        if (val < 0) {
        !          1418:                                fprintf(stderr,
        !          1419:                                        "*** Value '%s' should be unsigned\n",
        !          1420:                                        pcmd->argval[items].string);
        !          1421:                                res = TRUE;
        !          1422:                        }
        !          1423:                }
        !          1424:                items++;
        !          1425:        }
        !          1426:        if (keyid > 0)
        !          1427:                flags |= CONF_FLAG_AUTHENABLE;
        !          1428:        if (version > NTP_VERSION || version < NTP_OLDVERSION) {
        !          1429:                fprintf(fp, "***invalid version number: %u\n",
        !          1430:                        version);
        !          1431:                res = TRUE;
        !          1432:        }
        !          1433:        if (minpoll < NTP_MINPOLL || minpoll > NTP_MAXPOLL || 
        !          1434:            maxpoll < NTP_MINPOLL || maxpoll > NTP_MAXPOLL || 
        !          1435:            minpoll > maxpoll) {
        !          1436:                fprintf(fp, "***min/max-poll must be within %d..%d\n",
        !          1437:                        NTP_MINPOLL, NTP_MAXPOLL);
        !          1438:                res = TRUE;
        !          1439:        }                                       
        !          1440: 
        !          1441:        if (res)
        !          1442:                return;
        !          1443: 
        !          1444:        memset(&cpeer, 0, sizeof(cpeer));
        !          1445: 
        !          1446:        if (IS_IPV4(&pcmd->argval[0].netnum)) {
        !          1447:                cpeer.peeraddr = NSRCADR(&pcmd->argval[0].netnum);
        !          1448:                if (impl_ver == IMPL_XNTPD)
        !          1449:                        cpeer.v6_flag = 0;
        !          1450:        } else {
        !          1451:                if (impl_ver == IMPL_XNTPD_OLD) {
        !          1452:                        fprintf(stderr,
        !          1453:                            "***Server doesn't understand IPv6 addresses\n");
        !          1454:                        return;
        !          1455:                }
        !          1456:                cpeer.peeraddr6 = SOCK_ADDR6(&pcmd->argval[0].netnum);
        !          1457:                cpeer.v6_flag = 1;
        !          1458:        }
        !          1459:        cpeer.hmode = (u_char) mode;
        !          1460:        cpeer.keyid = keyid;
        !          1461:        cpeer.version = (u_char) version;
        !          1462:        cpeer.minpoll = minpoll;
        !          1463:        cpeer.maxpoll = maxpoll;
        !          1464:        cpeer.flags = (u_char)flags;
        !          1465:        cpeer.ttl = cmode;
        !          1466: 
        !          1467:        res = doquery(impl_ver, REQ_CONFIG, 1, 1,
        !          1468:                      sendsize, (char *)&cpeer, &items,
        !          1469:                      &itemsize, &dummy, 0, sizeof(struct conf_peer));
        !          1470:        
        !          1471:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          1472:                impl_ver = IMPL_XNTPD_OLD;
        !          1473:                goto again;
        !          1474:        }
        !          1475: 
        !          1476:        if (res == INFO_ERR_FMT) {
        !          1477:                (void) fprintf(fp,
        !          1478:                    "***Retrying command with old conf_peer size\n");
        !          1479:                res = doquery(impl_ver, REQ_CONFIG, 1, 1,
        !          1480:                              sizeof(struct old_conf_peer), (char *)&cpeer,
        !          1481:                              &items, &itemsize, &dummy, 0,
        !          1482:                              sizeof(struct conf_peer));
        !          1483:        }
        !          1484:        if (res == 0)
        !          1485:            (void) fprintf(fp, "done!\n");
        !          1486:        return;
        !          1487: }
        !          1488: 
        !          1489: 
        !          1490: /*
        !          1491:  * unconfig - unconfigure some associations
        !          1492:  */
        !          1493: static void
        !          1494: unconfig(
        !          1495:        struct parse *pcmd,
        !          1496:        FILE *fp
        !          1497:        )
        !          1498: {
        !          1499:        /* 8 is the maximum number of peers which will fit in a packet */
        !          1500:        struct conf_unpeer *pl, plist[min(MAXARGS, 8)];
        !          1501:        int qitemlim;
        !          1502:        int qitems;
        !          1503:        int items;
        !          1504:        int itemsize;
        !          1505:        char *dummy;
        !          1506:        int res;
        !          1507:        int sendsize;
        !          1508: 
        !          1509: again:
        !          1510:        if (impl_ver == IMPL_XNTPD)
        !          1511:                sendsize = sizeof(struct conf_unpeer);
        !          1512:        else
        !          1513:                sendsize = v4sizeof(struct conf_unpeer);
        !          1514: 
        !          1515:        qitemlim = min(pcmd->nargs, COUNTOF(plist));
        !          1516:        for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) {
        !          1517:                if (IS_IPV4(&pcmd->argval[0].netnum)) {
        !          1518:                        pl->peeraddr = NSRCADR(&pcmd->argval[qitems].netnum);
        !          1519:                        if (impl_ver == IMPL_XNTPD)
        !          1520:                                pl->v6_flag = 0;
        !          1521:                } else {
        !          1522:                        if (impl_ver == IMPL_XNTPD_OLD) {
        !          1523:                                fprintf(stderr,
        !          1524:                                    "***Server doesn't understand IPv6 addresses\n");
        !          1525:                                return;
        !          1526:                        }
        !          1527:                        pl->peeraddr6 =
        !          1528:                            SOCK_ADDR6(&pcmd->argval[qitems].netnum);
        !          1529:                        pl->v6_flag = 1;
        !          1530:                }
        !          1531:                pl = (struct conf_unpeer *)((char *)pl + sendsize);
        !          1532:        }
        !          1533: 
        !          1534:        res = doquery(impl_ver, REQ_UNCONFIG, 1, qitems,
        !          1535:                      sendsize, (char *)plist, &items,
        !          1536:                      &itemsize, &dummy, 0, sizeof(struct conf_unpeer));
        !          1537:        
        !          1538:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          1539:                impl_ver = IMPL_XNTPD_OLD;
        !          1540:                goto again;
        !          1541:        }
        !          1542: 
        !          1543:        if (res == 0)
        !          1544:            (void) fprintf(fp, "done!\n");
        !          1545: }
        !          1546: 
        !          1547: 
        !          1548: /*
        !          1549:  * set - set some system flags
        !          1550:  */
        !          1551: static void
        !          1552: set(
        !          1553:        struct parse *pcmd,
        !          1554:        FILE *fp
        !          1555:        )
        !          1556: {
        !          1557:        doset(pcmd, fp, REQ_SET_SYS_FLAG);
        !          1558: }
        !          1559: 
        !          1560: 
        !          1561: /*
        !          1562:  * clear - clear some system flags
        !          1563:  */
        !          1564: static void
        !          1565: sys_clear(
        !          1566:        struct parse *pcmd,
        !          1567:        FILE *fp
        !          1568:        )
        !          1569: {
        !          1570:        doset(pcmd, fp, REQ_CLR_SYS_FLAG);
        !          1571: }
        !          1572: 
        !          1573: 
        !          1574: /*
        !          1575:  * doset - set/clear system flags
        !          1576:  */
        !          1577: static void
        !          1578: doset(
        !          1579:        struct parse *pcmd,
        !          1580:        FILE *fp,
        !          1581:        int req
        !          1582:        )
        !          1583: {
        !          1584:        struct conf_sys_flags sys;
        !          1585:        int items;
        !          1586:        int itemsize;
        !          1587:        char *dummy;
        !          1588:        int res;
        !          1589: 
        !          1590:        sys.flags = 0;
        !          1591:        res = 0;
        !          1592:        for (items = 0; items < pcmd->nargs; items++) {
        !          1593:                if (STREQ(pcmd->argval[items].string, "auth"))
        !          1594:                        sys.flags |= SYS_FLAG_AUTH;
        !          1595:                else if (STREQ(pcmd->argval[items].string, "bclient"))
        !          1596:                        sys.flags |= SYS_FLAG_BCLIENT;
        !          1597:                else if (STREQ(pcmd->argval[items].string, "calibrate"))
        !          1598:                        sys.flags |= SYS_FLAG_CAL;
        !          1599:                else if (STREQ(pcmd->argval[items].string, "kernel"))
        !          1600:                        sys.flags |= SYS_FLAG_KERNEL;
        !          1601:                else if (STREQ(pcmd->argval[items].string, "monitor"))
        !          1602:                        sys.flags |= SYS_FLAG_MONITOR;
        !          1603:                else if (STREQ(pcmd->argval[items].string, "ntp"))
        !          1604:                        sys.flags |= SYS_FLAG_NTP;
        !          1605:                else if (STREQ(pcmd->argval[items].string, "pps"))
        !          1606:                        sys.flags |= SYS_FLAG_PPS;
        !          1607:                else if (STREQ(pcmd->argval[items].string, "stats"))
        !          1608:                        sys.flags |= SYS_FLAG_FILEGEN;
        !          1609:                else {
        !          1610:                        (void) fprintf(fp, "Unknown flag %s\n",
        !          1611:                            pcmd->argval[items].string);
        !          1612:                        res = 1;
        !          1613:                }
        !          1614:        }
        !          1615: 
        !          1616:        sys.flags = htonl(sys.flags);
        !          1617:        if (res || sys.flags == 0)
        !          1618:            return;
        !          1619: 
        !          1620: again:
        !          1621:        res = doquery(impl_ver, req, 1, 1,
        !          1622:                      sizeof(struct conf_sys_flags), (char *)&sys, &items,
        !          1623:                      &itemsize, &dummy, 0, sizeof(struct conf_sys_flags));
        !          1624:        
        !          1625:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          1626:                impl_ver = IMPL_XNTPD_OLD;
        !          1627:                goto again;
        !          1628:        }
        !          1629: 
        !          1630:        if (res == 0)
        !          1631:            (void) fprintf(fp, "done!\n");
        !          1632: }
        !          1633: 
        !          1634: 
        !          1635: /*
        !          1636:  * data for printing/interrpreting the restrict flags
        !          1637:  */
        !          1638: struct resflags {
        !          1639:   const char *str;
        !          1640:        int bit;
        !          1641: };
        !          1642: 
        !          1643: /* XXX: HMS: we apparently don't report set bits we do not recognize. */
        !          1644: 
        !          1645: static struct resflags resflagsV2[] = {
        !          1646:        { "ignore",     0x001 },
        !          1647:        { "noserve",    0x002 },
        !          1648:        { "notrust",    0x004 },
        !          1649:        { "noquery",    0x008 },
        !          1650:        { "nomodify",   0x010 },
        !          1651:        { "nopeer",     0x020 },
        !          1652:        { "notrap",     0x040 },
        !          1653:        { "lptrap",     0x080 },
        !          1654:        { "limited",    0x100 },
        !          1655:        { "",           0 }
        !          1656: };
        !          1657: 
        !          1658: static struct resflags resflagsV3[] = {
        !          1659:        { "ignore",     RES_IGNORE },
        !          1660:        { "noserve",    RES_DONTSERVE },
        !          1661:        { "notrust",    RES_DONTTRUST },
        !          1662:        { "noquery",    RES_NOQUERY },
        !          1663:        { "nomodify",   RES_NOMODIFY },
        !          1664:        { "nopeer",     RES_NOPEER },
        !          1665:        { "notrap",     RES_NOTRAP },
        !          1666:        { "lptrap",     RES_LPTRAP },
        !          1667:        { "limited",    RES_LIMITED },
        !          1668:        { "version",    RES_VERSION },
        !          1669:        { "kod",        RES_KOD },
        !          1670:        { "timeout",    RES_TIMEOUT },
        !          1671: 
        !          1672:        { "",           0 }
        !          1673: };
        !          1674: 
        !          1675: static struct resflags resmflags[] = {
        !          1676:        { "ntpport",    RESM_NTPONLY },
        !          1677:        { "interface",  RESM_INTERFACE },
        !          1678:        { "",           0 }
        !          1679: };
        !          1680: 
        !          1681: 
        !          1682: /*
        !          1683:  * reslist - obtain and print the server's restrict list
        !          1684:  */
        !          1685: /*ARGSUSED*/
        !          1686: static void
        !          1687: reslist(
        !          1688:        struct parse *pcmd,
        !          1689:        FILE *fp
        !          1690:        )
        !          1691: {
        !          1692:        struct info_restrict *rl;
        !          1693:        sockaddr_u resaddr;
        !          1694:        sockaddr_u maskaddr;
        !          1695:        int items;
        !          1696:        int itemsize;
        !          1697:        int res;
        !          1698:        int skip;
        !          1699:        char *addr;
        !          1700:        char *mask;
        !          1701:        struct resflags *rf;
        !          1702:        u_int32 count;
        !          1703:        u_short flags;
        !          1704:        u_short mflags;
        !          1705:        char flagstr[300];
        !          1706:        static const char *comma = ", ";
        !          1707: 
        !          1708: again:
        !          1709:        res = doquery(impl_ver, REQ_GET_RESTRICT, 0, 0, 0, (char *)NULL,
        !          1710:                      &items, &itemsize, (void *)&rl, 0, 
        !          1711:                      sizeof(struct info_restrict));
        !          1712:        
        !          1713:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          1714:                impl_ver = IMPL_XNTPD_OLD;
        !          1715:                goto again;
        !          1716:        }
        !          1717: 
        !          1718:        if (res != 0)
        !          1719:            return;
        !          1720: 
        !          1721:        if (!checkitems(items, fp))
        !          1722:            return;
        !          1723: 
        !          1724:        if (!checkitemsize(itemsize, sizeof(struct info_restrict)) &&
        !          1725:            !checkitemsize(itemsize, v4sizeof(struct info_restrict)))
        !          1726:            return;
        !          1727: 
        !          1728:        (void) fprintf(fp,
        !          1729:               "   address          mask            count        flags\n");
        !          1730:        (void) fprintf(fp,
        !          1731:                       "=====================================================================\n");
        !          1732: 
        !          1733:        while (items > 0) {
        !          1734:                SET_ADDRS(resaddr, maskaddr, rl, addr, mask);
        !          1735:                if (rl->v6_flag != 0) {
        !          1736:                        addr = nntohost(&resaddr);
        !          1737:                } else {
        !          1738:                        if ((rl->mask == (u_int32)0xffffffff))
        !          1739:                                addr = nntohost(&resaddr);
        !          1740:                        else
        !          1741:                                addr = stoa(&resaddr);
        !          1742:                }
        !          1743:                mask = stoa(&maskaddr);
        !          1744:                skip = 1;
        !          1745:                if ((pcmd->nargs == 0) ||
        !          1746:                    ((pcmd->argval->ival == 6) && (rl->v6_flag != 0)) ||
        !          1747:                    ((pcmd->argval->ival == 4) && (rl->v6_flag == 0)))
        !          1748:                        skip = 0;
        !          1749:                count = ntohl(rl->count);
        !          1750:                flags = ntohs(rl->flags);
        !          1751:                mflags = ntohs(rl->mflags);
        !          1752:                flagstr[0] = '\0';
        !          1753: 
        !          1754:                res = 1;
        !          1755:                rf = &resmflags[0];
        !          1756:                while (rf->bit != 0) {
        !          1757:                        if (mflags & rf->bit) {
        !          1758:                                if (!res)
        !          1759:                                    (void) strcat(flagstr, comma);
        !          1760:                                res = 0;
        !          1761:                                (void) strcat(flagstr, rf->str);
        !          1762:                        }
        !          1763:                        rf++;
        !          1764:                }
        !          1765: 
        !          1766:                rf = (impl_ver == IMPL_XNTPD_OLD)
        !          1767:                     ? &resflagsV2[0]
        !          1768:                     : &resflagsV3[0]
        !          1769:                     ;
        !          1770:                while (rf->bit != 0) {
        !          1771:                        if (flags & rf->bit) {
        !          1772:                                if (!res)
        !          1773:                                    (void) strcat(flagstr, comma);
        !          1774:                                res = 0;
        !          1775:                                (void) strcat(flagstr, rf->str);
        !          1776:                        }
        !          1777:                        rf++;
        !          1778:                }
        !          1779: 
        !          1780:                if (flagstr[0] == '\0')
        !          1781:                        strcpy(flagstr, "none");
        !          1782: 
        !          1783:                if (!skip)
        !          1784:                        fprintf(fp, "%-15.15s %-15.15s %9lu  %s\n",
        !          1785:                                addr, mask, (u_long)count, flagstr);
        !          1786:                rl++;
        !          1787:                items--;
        !          1788:        }
        !          1789: }
        !          1790: 
        !          1791: 
        !          1792: 
        !          1793: /*
        !          1794:  * new_restrict - create/add a set of restrictions
        !          1795:  */
        !          1796: static void
        !          1797: new_restrict(
        !          1798:        struct parse *pcmd,
        !          1799:        FILE *fp
        !          1800:        )
        !          1801: {
        !          1802:        do_restrict(pcmd, fp, REQ_RESADDFLAGS);
        !          1803: }
        !          1804: 
        !          1805: 
        !          1806: /*
        !          1807:  * unrestrict - remove restriction flags from existing entry
        !          1808:  */
        !          1809: static void
        !          1810: unrestrict(
        !          1811:        struct parse *pcmd,
        !          1812:        FILE *fp
        !          1813:        )
        !          1814: {
        !          1815:        do_restrict(pcmd, fp, REQ_RESSUBFLAGS);
        !          1816: }
        !          1817: 
        !          1818: 
        !          1819: /*
        !          1820:  * delrestrict - delete an existing restriction
        !          1821:  */
        !          1822: static void
        !          1823: delrestrict(
        !          1824:        struct parse *pcmd,
        !          1825:        FILE *fp
        !          1826:        )
        !          1827: {
        !          1828:        do_restrict(pcmd, fp, REQ_UNRESTRICT);
        !          1829: }
        !          1830: 
        !          1831: 
        !          1832: /*
        !          1833:  * do_restrict - decode commandline restrictions and make the request
        !          1834:  */
        !          1835: static void
        !          1836: do_restrict(
        !          1837:        struct parse *pcmd,
        !          1838:        FILE *fp,
        !          1839:        int req_code
        !          1840:        )
        !          1841: {
        !          1842:        struct conf_restrict cres;
        !          1843:        int items;
        !          1844:        int itemsize;
        !          1845:        char *dummy;
        !          1846:        u_int32 num;
        !          1847:        u_long bit;
        !          1848:        int i;
        !          1849:        int res;
        !          1850:        int err;
        !          1851:        int sendsize;
        !          1852: 
        !          1853:        /* Initialize cres */
        !          1854:        cres.addr = 0;
        !          1855:        cres.mask = 0;
        !          1856:        cres.flags = 0;
        !          1857:        cres.mflags = 0;
        !          1858:        cres.v6_flag = 0;
        !          1859: 
        !          1860: again:
        !          1861:        if (impl_ver == IMPL_XNTPD)
        !          1862:                sendsize = sizeof(struct conf_restrict);
        !          1863:        else
        !          1864:                sendsize = v4sizeof(struct conf_restrict);
        !          1865: 
        !          1866:        if (IS_IPV4(&pcmd->argval[0].netnum)) {
        !          1867:                cres.addr = NSRCADR(&pcmd->argval[0].netnum);
        !          1868:                cres.mask = NSRCADR(&pcmd->argval[1].netnum);
        !          1869:                if (impl_ver == IMPL_XNTPD)
        !          1870:                        cres.v6_flag = 0;
        !          1871:        } else {
        !          1872:                if (impl_ver == IMPL_XNTPD_OLD) {
        !          1873:                        fprintf(stderr,
        !          1874:                                "***Server doesn't understand IPv6 addresses\n");
        !          1875:                        return;
        !          1876:                }
        !          1877:                cres.addr6 = SOCK_ADDR6(&pcmd->argval[0].netnum);
        !          1878:                cres.v6_flag = 1;
        !          1879:        }
        !          1880:        cres.flags = 0;
        !          1881:        cres.mflags = 0;
        !          1882:        err = FALSE;
        !          1883:        for (res = 2; res < pcmd->nargs; res++) {
        !          1884:                if (STREQ(pcmd->argval[res].string, "ntpport")) {
        !          1885:                        cres.mflags |= RESM_NTPONLY;
        !          1886:                } else {
        !          1887:                        for (i = 0; resflagsV3[i].bit != 0; i++) {
        !          1888:                                if (STREQ(pcmd->argval[res].string,
        !          1889:                                          resflagsV3[i].str))
        !          1890:                                        break;
        !          1891:                        }
        !          1892:                        if (resflagsV3[i].bit != 0) {
        !          1893:                                cres.flags |= resflagsV3[i].bit;
        !          1894:                                if (req_code == REQ_UNRESTRICT) {
        !          1895:                                        fprintf(fp,
        !          1896:                                                "Flag %s inappropriate\n",
        !          1897:                                                resflagsV3[i].str);
        !          1898:                                        err = TRUE;
        !          1899:                                }
        !          1900:                        } else {
        !          1901:                                fprintf(fp, "Unknown flag %s\n",
        !          1902:                                        pcmd->argval[res].string);
        !          1903:                                err = TRUE;
        !          1904:                        }
        !          1905:                }
        !          1906:        }
        !          1907:        cres.flags = htons(cres.flags);
        !          1908:        cres.mflags = htons(cres.mflags);
        !          1909: 
        !          1910:        /*
        !          1911:         * Make sure mask for default address is zero.  Otherwise,
        !          1912:         * make sure mask bits are contiguous.
        !          1913:         */
        !          1914:        if (IS_IPV4(&pcmd->argval[0].netnum)) {
        !          1915:                if (cres.addr == 0) {
        !          1916:                        cres.mask = 0;
        !          1917:                } else {
        !          1918:                        num = ntohl(cres.mask);
        !          1919:                        for (bit = 0x80000000; bit != 0; bit >>= 1)
        !          1920:                                if ((num & bit) == 0)
        !          1921:                                        break;
        !          1922:                        for ( ; bit != 0; bit >>= 1)
        !          1923:                                if ((num & bit) != 0)
        !          1924:                                        break;
        !          1925:                        if (bit != 0) {
        !          1926:                                fprintf(fp, "Invalid mask %s\n",
        !          1927:                                        numtoa(cres.mask));
        !          1928:                                err = TRUE;
        !          1929:                        }
        !          1930:                }
        !          1931:        } else {
        !          1932:                /* XXX IPv6 sanity checking stuff */
        !          1933:        }
        !          1934: 
        !          1935:        if (err)
        !          1936:                return;
        !          1937: 
        !          1938:        res = doquery(impl_ver, req_code, 1, 1, sendsize, (char *)&cres,
        !          1939:                      &items, &itemsize, &dummy, 0, sizeof(cres));
        !          1940:        
        !          1941:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          1942:                impl_ver = IMPL_XNTPD_OLD;
        !          1943:                goto again;
        !          1944:        }
        !          1945: 
        !          1946:        if (res == 0)
        !          1947:            (void) fprintf(fp, "done!\n");
        !          1948:        return;
        !          1949: }
        !          1950: 
        !          1951: 
        !          1952: /*
        !          1953:  * monlist - obtain and print the server's monitor data
        !          1954:  */
        !          1955: /*ARGSUSED*/
        !          1956: static void
        !          1957: monlist(
        !          1958:        struct parse *pcmd,
        !          1959:        FILE *fp
        !          1960:        )
        !          1961: {
        !          1962:        char *struct_star;
        !          1963:        sockaddr_u addr;
        !          1964:        sockaddr_u dstadr;
        !          1965:        int items;
        !          1966:        int itemsize;
        !          1967:        int res;
        !          1968:        int version = -1;
        !          1969: 
        !          1970:        if (pcmd->nargs > 0) {
        !          1971:                version = pcmd->argval[0].ival;
        !          1972:        }
        !          1973: 
        !          1974: again:
        !          1975:        res = doquery(impl_ver,
        !          1976:                      (version == 1 || version == -1) ? REQ_MON_GETLIST_1 :
        !          1977:                      REQ_MON_GETLIST, 0, 0, 0, (char *)NULL,
        !          1978:                      &items, &itemsize, &struct_star,
        !          1979:                      (version < 0) ? (1 << INFO_ERR_REQ) : 0, 
        !          1980:                      sizeof(struct info_monitor_1));
        !          1981: 
        !          1982:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          1983:                impl_ver = IMPL_XNTPD_OLD;
        !          1984:                goto again;
        !          1985:        }
        !          1986: 
        !          1987:        if (res == INFO_ERR_REQ && version < 0) 
        !          1988:            res = doquery(impl_ver, REQ_MON_GETLIST, 0, 0, 0, (char *)NULL,
        !          1989:                          &items, &itemsize, &struct_star, 0, 
        !          1990:                          sizeof(struct info_monitor));
        !          1991:        
        !          1992:        if (res != 0)
        !          1993:            return;
        !          1994: 
        !          1995:        if (!checkitems(items, fp))
        !          1996:            return;
        !          1997: 
        !          1998:        if (itemsize == sizeof(struct info_monitor_1) ||
        !          1999:            itemsize == v4sizeof(struct info_monitor_1)) {
        !          2000:                struct info_monitor_1 *ml = (struct info_monitor_1 *) struct_star;
        !          2001: 
        !          2002:                (void) fprintf(fp,
        !          2003:                               "remote address          port local address      count m ver rstr avgint  lstint\n");
        !          2004:                (void) fprintf(fp,
        !          2005:                               "===============================================================================\n");
        !          2006:                while (items > 0) {
        !          2007:                        SET_ADDRS(dstadr, addr, ml, daddr, addr);
        !          2008:                        if ((pcmd->nargs == 0) ||
        !          2009:                            ((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) ||
        !          2010:                            ((pcmd->argval->ival == 4) && (ml->v6_flag == 0)))
        !          2011:                                fprintf(fp, 
        !          2012:                                    "%-22.22s %5d %-15s %8lu %1u %1u %6lx %6lu %7lu\n",
        !          2013:                                    nntohost(&addr), 
        !          2014:                                    ntohs(ml->port),
        !          2015:                                    stoa(&dstadr),
        !          2016:                                    (u_long)ntohl(ml->count),
        !          2017:                                    ml->mode,
        !          2018:                                    ml->version,
        !          2019:                                    (u_long)ntohl(ml->restr),
        !          2020:                                    (u_long)ntohl(ml->lasttime),
        !          2021:                                    (u_long)ntohl(ml->firsttime));
        !          2022:                        ml++;
        !          2023:                        items--;
        !          2024:                }
        !          2025:        } else if (itemsize == sizeof(struct info_monitor) ||
        !          2026:            itemsize == v4sizeof(struct info_monitor)) {
        !          2027:                struct info_monitor *ml = (struct info_monitor *) struct_star;
        !          2028: 
        !          2029:                (void) fprintf(fp,
        !          2030:                               "     address               port     count mode ver rstr avgint  lstint\n");
        !          2031:                (void) fprintf(fp,
        !          2032:                               "===============================================================================\n");
        !          2033:                while (items > 0) {
        !          2034:                        SET_ADDR(dstadr, ml->v6_flag, ml->addr, ml->addr6);
        !          2035:                        if ((pcmd->nargs == 0) ||
        !          2036:                            ((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) ||
        !          2037:                            ((pcmd->argval->ival == 4) && (ml->v6_flag == 0)))
        !          2038:                                (void) fprintf(fp,
        !          2039:                                    "%-25.25s %5u %9lu %4u %2u %9lx %9lu %9lu\n",
        !          2040:                                    nntohost(&dstadr),
        !          2041:                                    ntohs(ml->port),
        !          2042:                                    (u_long)ntohl(ml->count),
        !          2043:                                    ml->mode,
        !          2044:                                    ml->version,
        !          2045:                                    (u_long)ntohl(ml->restr),
        !          2046:                                    (u_long)ntohl(ml->lasttime),
        !          2047:                                    (u_long)ntohl(ml->firsttime));
        !          2048:                        ml++;
        !          2049:                        items--;
        !          2050:                }
        !          2051:        } else if (itemsize == sizeof(struct old_info_monitor)) {
        !          2052:                struct old_info_monitor *oml = (struct old_info_monitor *)struct_star;
        !          2053:                (void) fprintf(fp,
        !          2054:                               "     address          port     count  mode version  lasttime firsttime\n");
        !          2055:                (void) fprintf(fp,
        !          2056:                               "======================================================================\n");
        !          2057:                while (items > 0) {
        !          2058:                        SET_ADDR(dstadr, oml->v6_flag, oml->addr, oml->addr6);
        !          2059:                        (void) fprintf(fp, "%-20.20s %5u %9lu %4u   %3u %9lu %9lu\n",
        !          2060:                                       nntohost(&dstadr),
        !          2061:                                       ntohs(oml->port),
        !          2062:                                       (u_long)ntohl(oml->count),
        !          2063:                                       oml->mode,
        !          2064:                                       oml->version,
        !          2065:                                       (u_long)ntohl(oml->lasttime),
        !          2066:                                       (u_long)ntohl(oml->firsttime));
        !          2067:                        oml++;
        !          2068:                        items--;
        !          2069:                }
        !          2070:        } else {
        !          2071:                /* issue warning according to new info_monitor size */
        !          2072:                checkitemsize(itemsize, sizeof(struct info_monitor));
        !          2073:        }
        !          2074: }
        !          2075: 
        !          2076: 
        !          2077: /*
        !          2078:  * Mapping between command line strings and stat reset flags
        !          2079:  */
        !          2080: struct statreset {
        !          2081:   const char *str;
        !          2082:        int flag;
        !          2083: } sreset[] = {
        !          2084:        { "io",         RESET_FLAG_IO },
        !          2085:        { "sys",        RESET_FLAG_SYS },
        !          2086:        { "mem",        RESET_FLAG_MEM },
        !          2087:        { "timer",      RESET_FLAG_TIMER },
        !          2088:        { "auth",       RESET_FLAG_AUTH },
        !          2089:        { "allpeers",   RESET_FLAG_ALLPEERS },
        !          2090:        { "",           0 }
        !          2091: };
        !          2092: 
        !          2093: /*
        !          2094:  * reset - reset statistic counters
        !          2095:  */
        !          2096: static void
        !          2097: reset(
        !          2098:        struct parse *pcmd,
        !          2099:        FILE *fp
        !          2100:        )
        !          2101: {
        !          2102:        struct reset_flags rflags;
        !          2103:        int items;
        !          2104:        int itemsize;
        !          2105:        char *dummy;
        !          2106:        int i;
        !          2107:        int res;
        !          2108:        int err;
        !          2109: 
        !          2110:        err = 0;
        !          2111:        rflags.flags = 0;
        !          2112:        for (res = 0; res < pcmd->nargs; res++) {
        !          2113:                for (i = 0; sreset[i].flag != 0; i++) {
        !          2114:                        if (STREQ(pcmd->argval[res].string, sreset[i].str))
        !          2115:                            break;
        !          2116:                }
        !          2117:                if (sreset[i].flag == 0) {
        !          2118:                        (void) fprintf(fp, "Flag %s unknown\n",
        !          2119:                                       pcmd->argval[res].string);
        !          2120:                        err++;
        !          2121:                } else {
        !          2122:                        rflags.flags |= sreset[i].flag;
        !          2123:                }
        !          2124:        }
        !          2125:        rflags.flags = htonl(rflags.flags);
        !          2126: 
        !          2127:        if (err) {
        !          2128:                (void) fprintf(fp, "Not done due to errors\n");
        !          2129:                return;
        !          2130:        }
        !          2131: 
        !          2132: again:
        !          2133:        res = doquery(impl_ver, REQ_RESET_STATS, 1, 1,
        !          2134:                      sizeof(struct reset_flags), (char *)&rflags, &items,
        !          2135:                      &itemsize, &dummy, 0, sizeof(struct reset_flags));
        !          2136:        
        !          2137:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          2138:                impl_ver = IMPL_XNTPD_OLD;
        !          2139:                goto again;
        !          2140:        }
        !          2141: 
        !          2142:        if (res == 0)
        !          2143:            (void) fprintf(fp, "done!\n");
        !          2144:        return;
        !          2145: }
        !          2146: 
        !          2147: 
        !          2148: 
        !          2149: /*
        !          2150:  * preset - reset stat counters for particular peers
        !          2151:  */
        !          2152: static void
        !          2153: preset(
        !          2154:        struct parse *pcmd,
        !          2155:        FILE *fp
        !          2156:        )
        !          2157: {
        !          2158:        /* 8 is the maximum number of peers which will fit in a packet */
        !          2159:        struct conf_unpeer *pl, plist[min(MAXARGS, 8)];
        !          2160:        int qitemlim;
        !          2161:        int qitems;
        !          2162:        int items;
        !          2163:        int itemsize;
        !          2164:        char *dummy;
        !          2165:        int res;
        !          2166:        int sendsize;
        !          2167: 
        !          2168: again:
        !          2169:        if (impl_ver == IMPL_XNTPD)
        !          2170:                sendsize = sizeof(struct conf_unpeer);
        !          2171:        else
        !          2172:                sendsize = v4sizeof(struct conf_unpeer);
        !          2173: 
        !          2174:        qitemlim = min(pcmd->nargs, COUNTOF(plist));
        !          2175:        for (qitems = 0, pl = plist; qitems < qitemlim; qitems++) {
        !          2176:                if (IS_IPV4(&pcmd->argval[qitems].netnum)) {
        !          2177:                        pl->peeraddr = NSRCADR(&pcmd->argval[qitems].netnum);
        !          2178:                        if (impl_ver == IMPL_XNTPD)
        !          2179:                                pl->v6_flag = 0;
        !          2180:                } else {
        !          2181:                        if (impl_ver == IMPL_XNTPD_OLD) {
        !          2182:                                fprintf(stderr,
        !          2183:                                    "***Server doesn't understand IPv6 addresses\n");
        !          2184:                                return;
        !          2185:                        }
        !          2186:                        pl->peeraddr6 =
        !          2187:                            SOCK_ADDR6(&pcmd->argval[qitems].netnum);
        !          2188:                        pl->v6_flag = 1;
        !          2189:                }
        !          2190:                pl = (struct conf_unpeer *)((char *)pl + sendsize);
        !          2191:        }
        !          2192: 
        !          2193:        res = doquery(impl_ver, REQ_RESET_PEER, 1, qitems,
        !          2194:                      sendsize, (char *)plist, &items,
        !          2195:                      &itemsize, &dummy, 0, sizeof(struct conf_unpeer));
        !          2196:        
        !          2197:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          2198:                impl_ver = IMPL_XNTPD_OLD;
        !          2199:                goto again;
        !          2200:        }
        !          2201: 
        !          2202:        if (res == 0)
        !          2203:            (void) fprintf(fp, "done!\n");
        !          2204: }
        !          2205: 
        !          2206: 
        !          2207: /*
        !          2208:  * readkeys - request the server to reread the keys file
        !          2209:  */
        !          2210: /*ARGSUSED*/
        !          2211: static void
        !          2212: readkeys(
        !          2213:        struct parse *pcmd,
        !          2214:        FILE *fp
        !          2215:        )
        !          2216: {
        !          2217:        int items;
        !          2218:        int itemsize;
        !          2219:        char *dummy;
        !          2220:        int res;
        !          2221: 
        !          2222: again:
        !          2223:        res = doquery(impl_ver, REQ_REREAD_KEYS, 1, 0, 0, (char *)0,
        !          2224:                      &items, &itemsize, &dummy, 0, sizeof(dummy));
        !          2225:        
        !          2226:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          2227:                impl_ver = IMPL_XNTPD_OLD;
        !          2228:                goto again;
        !          2229:        }
        !          2230: 
        !          2231:        if (res == 0)
        !          2232:            (void) fprintf(fp, "done!\n");
        !          2233:        return;
        !          2234: }
        !          2235: 
        !          2236: 
        !          2237: /*
        !          2238:  * trustkey - add some keys to the trusted key list
        !          2239:  */
        !          2240: static void
        !          2241: trustkey(
        !          2242:        struct parse *pcmd,
        !          2243:        FILE *fp
        !          2244:        )
        !          2245: {
        !          2246:        do_trustkey(pcmd, fp, REQ_TRUSTKEY);
        !          2247: }
        !          2248: 
        !          2249: 
        !          2250: /*
        !          2251:  * untrustkey - remove some keys from the trusted key list
        !          2252:  */
        !          2253: static void
        !          2254: untrustkey(
        !          2255:        struct parse *pcmd,
        !          2256:        FILE *fp
        !          2257:        )
        !          2258: {
        !          2259:        do_trustkey(pcmd, fp, REQ_UNTRUSTKEY);
        !          2260: }
        !          2261: 
        !          2262: 
        !          2263: /*
        !          2264:  * do_trustkey - do grunge work of adding/deleting keys
        !          2265:  */
        !          2266: static void
        !          2267: do_trustkey(
        !          2268:        struct parse *pcmd,
        !          2269:        FILE *fp,
        !          2270:        int req
        !          2271:        )
        !          2272: {
        !          2273:        u_long keyids[MAXARGS];
        !          2274:        int i;
        !          2275:        int items;
        !          2276:        int itemsize;
        !          2277:        char *dummy;
        !          2278:        int ritems;
        !          2279:        int res;
        !          2280: 
        !          2281:        ritems = 0;
        !          2282:        for (i = 0; i < pcmd->nargs; i++) {
        !          2283:                keyids[ritems++] = pcmd->argval[i].uval;
        !          2284:        }
        !          2285: 
        !          2286: again:
        !          2287:        res = doquery(impl_ver, req, 1, ritems, sizeof(u_long),
        !          2288:                      (char *)keyids, &items, &itemsize, &dummy, 0, 
        !          2289:                      sizeof(dummy));
        !          2290:        
        !          2291:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          2292:                impl_ver = IMPL_XNTPD_OLD;
        !          2293:                goto again;
        !          2294:        }
        !          2295: 
        !          2296:        if (res == 0)
        !          2297:            (void) fprintf(fp, "done!\n");
        !          2298:        return;
        !          2299: }
        !          2300: 
        !          2301: 
        !          2302: 
        !          2303: /*
        !          2304:  * authinfo - obtain and print info about authentication
        !          2305:  */
        !          2306: /*ARGSUSED*/
        !          2307: static void
        !          2308: authinfo(
        !          2309:        struct parse *pcmd,
        !          2310:        FILE *fp
        !          2311:        )
        !          2312: {
        !          2313:        struct info_auth *ia;
        !          2314:        int items;
        !          2315:        int itemsize;
        !          2316:        int res;
        !          2317: 
        !          2318: again:
        !          2319:        res = doquery(impl_ver, REQ_AUTHINFO, 0, 0, 0, NULL, &items,
        !          2320:                      &itemsize, (void *)&ia, 0, sizeof(*ia));
        !          2321:        
        !          2322:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          2323:                impl_ver = IMPL_XNTPD_OLD;
        !          2324:                goto again;
        !          2325:        }
        !          2326: 
        !          2327:        if (res != 0)
        !          2328:                return;
        !          2329: 
        !          2330:        if (!check1item(items, fp))
        !          2331:                return;
        !          2332: 
        !          2333:        if (!checkitemsize(itemsize, sizeof(*ia)))
        !          2334:                return;
        !          2335: 
        !          2336:        fprintf(fp, "time since reset:     %lu\n",
        !          2337:                (u_long)ntohl(ia->timereset));
        !          2338:        fprintf(fp, "stored keys:          %lu\n",
        !          2339:                (u_long)ntohl(ia->numkeys));
        !          2340:        fprintf(fp, "free keys:            %lu\n",
        !          2341:                (u_long)ntohl(ia->numfreekeys));
        !          2342:        fprintf(fp, "key lookups:          %lu\n",
        !          2343:                (u_long)ntohl(ia->keylookups));
        !          2344:        fprintf(fp, "keys not found:       %lu\n",
        !          2345:                (u_long)ntohl(ia->keynotfound));
        !          2346:        fprintf(fp, "uncached keys:        %lu\n",
        !          2347:                (u_long)ntohl(ia->keyuncached));
        !          2348:        fprintf(fp, "encryptions:          %lu\n",
        !          2349:                (u_long)ntohl(ia->encryptions));
        !          2350:        fprintf(fp, "decryptions:          %lu\n",
        !          2351:                (u_long)ntohl(ia->decryptions));
        !          2352:        fprintf(fp, "expired keys:         %lu\n",
        !          2353:                (u_long)ntohl(ia->expired));
        !          2354: }
        !          2355: 
        !          2356: 
        !          2357: 
        !          2358: /*
        !          2359:  * traps - obtain and print a list of traps
        !          2360:  */
        !          2361: /*ARGSUSED*/
        !          2362: static void
        !          2363: traps(
        !          2364:        struct parse *pcmd,
        !          2365:        FILE *fp
        !          2366:        )
        !          2367: {
        !          2368:        int i;
        !          2369:        struct info_trap *it;
        !          2370:        sockaddr_u trap_addr, local_addr;
        !          2371:        int items;
        !          2372:        int itemsize;
        !          2373:        int res;
        !          2374: 
        !          2375: again:
        !          2376:        res = doquery(impl_ver, REQ_TRAPS, 0, 0, 0, (char *)NULL,
        !          2377:                      &items, &itemsize, (void *)&it, 0, 
        !          2378:                      sizeof(struct info_trap));
        !          2379:        
        !          2380:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          2381:                impl_ver = IMPL_XNTPD_OLD;
        !          2382:                goto again;
        !          2383:        }
        !          2384: 
        !          2385:        if (res != 0)
        !          2386:            return;
        !          2387: 
        !          2388:        if (!checkitems(items, fp))
        !          2389:            return;
        !          2390: 
        !          2391:        if (!checkitemsize(itemsize, sizeof(struct info_trap)) &&
        !          2392:            !checkitemsize(itemsize, v4sizeof(struct info_trap)))
        !          2393:            return;
        !          2394: 
        !          2395:        for (i = 0; i < items; i++ ) {
        !          2396:                if (i != 0)
        !          2397:                    (void) fprintf(fp, "\n");
        !          2398:                SET_ADDRS(trap_addr, local_addr, it, trap_address, local_address);
        !          2399:                (void) fprintf(fp, "address %s, port %d\n",
        !          2400:                                stoa(&trap_addr), 
        !          2401:                                ntohs(it->trap_port));
        !          2402:                (void) fprintf(fp, "interface: %s, ",
        !          2403:                                (it->local_address == 0)
        !          2404:                                ? "wildcard"
        !          2405:                                : stoa(&local_addr));
        !          2406:                if (ntohl(it->flags) & TRAP_CONFIGURED)
        !          2407:                    (void) fprintf(fp, "configured\n");
        !          2408:                else if (ntohl(it->flags) & TRAP_NONPRIO)
        !          2409:                    (void) fprintf(fp, "low priority\n");
        !          2410:                else
        !          2411:                    (void) fprintf(fp, "normal priority\n");
        !          2412:                
        !          2413:                (void) fprintf(fp, "set for %ld secs, last set %ld secs ago\n",
        !          2414:                               (long)ntohl(it->origtime),
        !          2415:                               (long)ntohl(it->settime));
        !          2416:                (void) fprintf(fp, "sequence %d, number of resets %ld\n",
        !          2417:                               ntohs(it->sequence),
        !          2418:                               (long)ntohl(it->resets));
        !          2419:        }
        !          2420: }
        !          2421: 
        !          2422: 
        !          2423: /*
        !          2424:  * addtrap - configure a trap
        !          2425:  */
        !          2426: static void
        !          2427: addtrap(
        !          2428:        struct parse *pcmd,
        !          2429:        FILE *fp
        !          2430:        )
        !          2431: {
        !          2432:        do_addclr_trap(pcmd, fp, REQ_ADD_TRAP);
        !          2433: }
        !          2434: 
        !          2435: 
        !          2436: /*
        !          2437:  * clrtrap - clear a trap from the server
        !          2438:  */
        !          2439: static void
        !          2440: clrtrap(
        !          2441:        struct parse *pcmd,
        !          2442:        FILE *fp
        !          2443:        )
        !          2444: {
        !          2445:        do_addclr_trap(pcmd, fp, REQ_CLR_TRAP);
        !          2446: }
        !          2447: 
        !          2448: 
        !          2449: /*
        !          2450:  * do_addclr_trap - do grunge work of adding/deleting traps
        !          2451:  */
        !          2452: static void
        !          2453: do_addclr_trap(
        !          2454:        struct parse *pcmd,
        !          2455:        FILE *fp,
        !          2456:        int req
        !          2457:        )
        !          2458: {
        !          2459:        struct conf_trap ctrap;
        !          2460:        int items;
        !          2461:        int itemsize;
        !          2462:        char *dummy;
        !          2463:        int res;
        !          2464:        int sendsize;
        !          2465: 
        !          2466: again:
        !          2467:        if (impl_ver == IMPL_XNTPD)
        !          2468:                sendsize = sizeof(struct conf_trap);
        !          2469:        else
        !          2470:                sendsize = v4sizeof(struct conf_trap);
        !          2471: 
        !          2472:        if (IS_IPV4(&pcmd->argval[0].netnum)) {
        !          2473:                ctrap.trap_address = NSRCADR(&pcmd->argval[0].netnum);
        !          2474:                if (impl_ver == IMPL_XNTPD)
        !          2475:                        ctrap.v6_flag = 0;
        !          2476:        } else {
        !          2477:                if (impl_ver == IMPL_XNTPD_OLD) {
        !          2478:                        fprintf(stderr,
        !          2479:                            "***Server doesn't understand IPv6 addresses\n");
        !          2480:                        return;
        !          2481:                }
        !          2482:                ctrap.trap_address6 = SOCK_ADDR6(&pcmd->argval[0].netnum);
        !          2483:                ctrap.v6_flag = 1;
        !          2484:        }
        !          2485:        ctrap.local_address = 0;
        !          2486:        ctrap.trap_port = htons(TRAPPORT);
        !          2487:        ctrap.unused = 0;
        !          2488: 
        !          2489:        if (pcmd->nargs > 1) {
        !          2490:                ctrap.trap_port = htons((u_short)pcmd->argval[1].uval);
        !          2491:                if (pcmd->nargs > 2) {
        !          2492:                        if (AF(&pcmd->argval[2].netnum) !=
        !          2493:                            AF(&pcmd->argval[0].netnum)) {
        !          2494:                                fprintf(stderr,
        !          2495:                                    "***Cannot mix IPv4 and IPv6 addresses\n");
        !          2496:                                return;
        !          2497:                        }
        !          2498:                        if (IS_IPV4(&pcmd->argval[2].netnum))
        !          2499:                                ctrap.local_address = NSRCADR(&pcmd->argval[2].netnum);
        !          2500:                        else
        !          2501:                                ctrap.local_address6 = SOCK_ADDR6(&pcmd->argval[2].netnum);
        !          2502:                }
        !          2503:        }
        !          2504: 
        !          2505:        res = doquery(impl_ver, req, 1, 1, sendsize,
        !          2506:                      (char *)&ctrap, &items, &itemsize, &dummy, 0, 
        !          2507:                      sizeof(struct conf_trap));
        !          2508:        
        !          2509:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          2510:                impl_ver = IMPL_XNTPD_OLD;
        !          2511:                goto again;
        !          2512:        }
        !          2513: 
        !          2514:        if (res == 0)
        !          2515:            (void) fprintf(fp, "done!\n");
        !          2516:        return;
        !          2517: }
        !          2518: 
        !          2519: 
        !          2520: 
        !          2521: /*
        !          2522:  * requestkey - change the server's request key (a dangerous request)
        !          2523:  */
        !          2524: static void
        !          2525: requestkey(
        !          2526:        struct parse *pcmd,
        !          2527:        FILE *fp
        !          2528:        )
        !          2529: {
        !          2530:        do_changekey(pcmd, fp, REQ_REQUEST_KEY);
        !          2531: }
        !          2532: 
        !          2533: 
        !          2534: /*
        !          2535:  * controlkey - change the server's control key
        !          2536:  */
        !          2537: static void
        !          2538: controlkey(
        !          2539:        struct parse *pcmd,
        !          2540:        FILE *fp
        !          2541:        )
        !          2542: {
        !          2543:        do_changekey(pcmd, fp, REQ_CONTROL_KEY);
        !          2544: }
        !          2545: 
        !          2546: 
        !          2547: 
        !          2548: /*
        !          2549:  * do_changekey - do grunge work of changing keys
        !          2550:  */
        !          2551: static void
        !          2552: do_changekey(
        !          2553:        struct parse *pcmd,
        !          2554:        FILE *fp,
        !          2555:        int req
        !          2556:        )
        !          2557: {
        !          2558:        u_long key;
        !          2559:        int items;
        !          2560:        int itemsize;
        !          2561:        char *dummy;
        !          2562:        int res;
        !          2563: 
        !          2564: 
        !          2565:        key = htonl((u_int32)pcmd->argval[0].uval);
        !          2566: 
        !          2567: again:
        !          2568:        res = doquery(impl_ver, req, 1, 1, sizeof(u_int32),
        !          2569:                      (char *)&key, &items, &itemsize, &dummy, 0, 
        !          2570:                      sizeof(dummy));
        !          2571:        
        !          2572:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          2573:                impl_ver = IMPL_XNTPD_OLD;
        !          2574:                goto again;
        !          2575:        }
        !          2576: 
        !          2577:        if (res == 0)
        !          2578:            (void) fprintf(fp, "done!\n");
        !          2579:        return;
        !          2580: }
        !          2581: 
        !          2582: 
        !          2583: 
        !          2584: /*
        !          2585:  * ctlstats - obtain and print info about authentication
        !          2586:  */
        !          2587: /*ARGSUSED*/
        !          2588: static void
        !          2589: ctlstats(
        !          2590:        struct parse *pcmd,
        !          2591:        FILE *fp
        !          2592:        )
        !          2593: {
        !          2594:        struct info_control *ic;
        !          2595:        int items;
        !          2596:        int itemsize;
        !          2597:        int res;
        !          2598: 
        !          2599: again:
        !          2600:        res = doquery(impl_ver, REQ_GET_CTLSTATS, 0, 0, 0, NULL, &items,
        !          2601:                      &itemsize, (void *)&ic, 0, sizeof(*ic));
        !          2602:        
        !          2603:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          2604:                impl_ver = IMPL_XNTPD_OLD;
        !          2605:                goto again;
        !          2606:        }
        !          2607: 
        !          2608:        if (res != 0)
        !          2609:                return;
        !          2610: 
        !          2611:        if (!check1item(items, fp))
        !          2612:                return;
        !          2613: 
        !          2614:        if (!checkitemsize(itemsize, sizeof(*ic)))
        !          2615:                return;
        !          2616: 
        !          2617:        fprintf(fp, "time since reset:       %lu\n",
        !          2618:                (u_long)ntohl(ic->ctltimereset));
        !          2619:        fprintf(fp, "requests received:      %lu\n",
        !          2620:                (u_long)ntohl(ic->numctlreq));
        !          2621:        fprintf(fp, "responses sent:         %lu\n",
        !          2622:                (u_long)ntohl(ic->numctlresponses));
        !          2623:        fprintf(fp, "fragments sent:         %lu\n",
        !          2624:                (u_long)ntohl(ic->numctlfrags));
        !          2625:        fprintf(fp, "async messages sent:    %lu\n",
        !          2626:                (u_long)ntohl(ic->numasyncmsgs));
        !          2627:        fprintf(fp, "error msgs sent:        %lu\n",
        !          2628:                (u_long)ntohl(ic->numctlerrors));
        !          2629:        fprintf(fp, "total bad pkts:         %lu\n",
        !          2630:                (u_long)ntohl(ic->numctlbadpkts));
        !          2631:        fprintf(fp, "packet too short:       %lu\n",
        !          2632:                (u_long)ntohl(ic->numctltooshort));
        !          2633:        fprintf(fp, "response on input:      %lu\n",
        !          2634:                (u_long)ntohl(ic->numctlinputresp));
        !          2635:        fprintf(fp, "fragment on input:      %lu\n",
        !          2636:                (u_long)ntohl(ic->numctlinputfrag));
        !          2637:        fprintf(fp, "error set on input:     %lu\n",
        !          2638:                (u_long)ntohl(ic->numctlinputerr));
        !          2639:        fprintf(fp, "bad offset on input:    %lu\n",
        !          2640:                (u_long)ntohl(ic->numctlbadoffset));
        !          2641:        fprintf(fp, "bad version packets:    %lu\n",
        !          2642:                (u_long)ntohl(ic->numctlbadversion));
        !          2643:        fprintf(fp, "data in pkt too short:  %lu\n",
        !          2644:                (u_long)ntohl(ic->numctldatatooshort));
        !          2645:        fprintf(fp, "unknown op codes:       %lu\n",
        !          2646:                (u_long)ntohl(ic->numctlbadop));
        !          2647: }
        !          2648: 
        !          2649: 
        !          2650: /*
        !          2651:  * clockstat - get and print clock status information
        !          2652:  */
        !          2653: static void
        !          2654: clockstat(
        !          2655:        struct parse *pcmd,
        !          2656:        FILE *fp
        !          2657:        )
        !          2658: {
        !          2659:        struct info_clock *cl;
        !          2660:        /* 8 is the maximum number of clocks which will fit in a packet */
        !          2661:        u_long clist[min(MAXARGS, 8)];
        !          2662:        int qitemlim;
        !          2663:        int qitems;
        !          2664:        int items;
        !          2665:        int itemsize;
        !          2666:        int res;
        !          2667:        l_fp ts;
        !          2668:        struct clktype *clk;
        !          2669: 
        !          2670:        qitemlim = min(pcmd->nargs, COUNTOF(clist));
        !          2671:        for (qitems = 0; qitems < qitemlim; qitems++)
        !          2672:                clist[qitems] = NSRCADR(&pcmd->argval[qitems].netnum);
        !          2673: 
        !          2674: again:
        !          2675:        res = doquery(impl_ver, REQ_GET_CLOCKINFO, 0, qitems,
        !          2676:                      sizeof(u_int32), (char *)clist, &items,
        !          2677:                      &itemsize, (void *)&cl, 0, sizeof(struct info_clock));
        !          2678:        
        !          2679:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          2680:                impl_ver = IMPL_XNTPD_OLD;
        !          2681:                goto again;
        !          2682:        }
        !          2683: 
        !          2684:        if (res != 0)
        !          2685:                return;
        !          2686: 
        !          2687:        if (!checkitems(items, fp))
        !          2688:                return;
        !          2689: 
        !          2690:        if (!checkitemsize(itemsize, sizeof(struct info_clock)))
        !          2691:                return;
        !          2692: 
        !          2693:        while (items-- > 0) {
        !          2694:                (void) fprintf(fp, "clock address:        %s\n",
        !          2695:                               numtoa(cl->clockadr));
        !          2696:                for (clk = clktypes; clk->code >= 0; clk++)
        !          2697:                    if (clk->code == cl->type)
        !          2698:                        break;
        !          2699:                if (clk->code >= 0)
        !          2700:                    (void) fprintf(fp, "clock type:           %s\n",
        !          2701:                                   clk->clocktype);
        !          2702:                else
        !          2703:                    (void) fprintf(fp, "clock type:           unknown type (%d)\n",
        !          2704:                                   cl->type);
        !          2705:                (void) fprintf(fp, "last event:           %d\n",
        !          2706:                               cl->lastevent);
        !          2707:                (void) fprintf(fp, "current status:       %d\n",
        !          2708:                               cl->currentstatus);
        !          2709:                (void) fprintf(fp, "number of polls:      %lu\n",
        !          2710:                               (u_long)ntohl(cl->polls));
        !          2711:                (void) fprintf(fp, "no response to poll:  %lu\n",
        !          2712:                               (u_long)ntohl(cl->noresponse));
        !          2713:                (void) fprintf(fp, "bad format responses: %lu\n",
        !          2714:                               (u_long)ntohl(cl->badformat));
        !          2715:                (void) fprintf(fp, "bad data responses:   %lu\n",
        !          2716:                               (u_long)ntohl(cl->baddata));
        !          2717:                (void) fprintf(fp, "running time:         %lu\n",
        !          2718:                               (u_long)ntohl(cl->timestarted));
        !          2719:                NTOHL_FP(&cl->fudgetime1, &ts);
        !          2720:                (void) fprintf(fp, "fudge time 1:         %s\n",
        !          2721:                               lfptoa(&ts, 6));
        !          2722:                NTOHL_FP(&cl->fudgetime2, &ts);
        !          2723:                (void) fprintf(fp, "fudge time 2:         %s\n",
        !          2724:                               lfptoa(&ts, 6));
        !          2725:                (void) fprintf(fp, "stratum:              %ld\n",
        !          2726:                               (u_long)ntohl(cl->fudgeval1));
        !          2727:                (void) fprintf(fp, "reference ID:         %s\n",
        !          2728:                               refid_string(ntohl(cl->fudgeval2), 0));
        !          2729:                (void) fprintf(fp, "fudge flags:          0x%x\n",
        !          2730:                               cl->flags);
        !          2731: 
        !          2732:                if (items > 0)
        !          2733:                    (void) fprintf(fp, "\n");
        !          2734:                cl++;
        !          2735:        }
        !          2736: }
        !          2737: 
        !          2738: 
        !          2739: /*
        !          2740:  * fudge - set clock fudge factors
        !          2741:  */
        !          2742: static void
        !          2743: fudge(
        !          2744:        struct parse *pcmd,
        !          2745:        FILE *fp
        !          2746:        )
        !          2747: {
        !          2748:        struct conf_fudge fudgedata;
        !          2749:        int items;
        !          2750:        int itemsize;
        !          2751:        char *dummy;
        !          2752:        l_fp ts;
        !          2753:        int res;
        !          2754:        long val;
        !          2755:        u_long u_val;
        !          2756:        int err;
        !          2757: 
        !          2758: 
        !          2759:        err = 0;
        !          2760:        memset((char *)&fudgedata, 0, sizeof fudgedata);
        !          2761:        fudgedata.clockadr = NSRCADR(&pcmd->argval[0].netnum);
        !          2762: 
        !          2763:        if (STREQ(pcmd->argval[1].string, "time1")) {
        !          2764:                fudgedata.which = htonl(FUDGE_TIME1);
        !          2765:                if (!atolfp(pcmd->argval[2].string, &ts))
        !          2766:                    err = 1;
        !          2767:                else
        !          2768:                    NTOHL_FP(&ts, &fudgedata.fudgetime);
        !          2769:        } else if (STREQ(pcmd->argval[1].string, "time2")) {
        !          2770:                fudgedata.which = htonl(FUDGE_TIME2);
        !          2771:                if (!atolfp(pcmd->argval[2].string, &ts))
        !          2772:                    err = 1;
        !          2773:                else
        !          2774:                    NTOHL_FP(&ts, &fudgedata.fudgetime);
        !          2775:        } else if (STREQ(pcmd->argval[1].string, "val1")) {
        !          2776:                fudgedata.which = htonl(FUDGE_VAL1);
        !          2777:                if (!atoint(pcmd->argval[2].string, &val))
        !          2778:                    err = 1;
        !          2779:                else
        !          2780:                    fudgedata.fudgeval_flags = htonl(val);
        !          2781:        } else if (STREQ(pcmd->argval[1].string, "val2")) {
        !          2782:                fudgedata.which = htonl(FUDGE_VAL2);
        !          2783:                if (!atoint(pcmd->argval[2].string, &val))
        !          2784:                    err = 1;
        !          2785:                else
        !          2786:                    fudgedata.fudgeval_flags = htonl((u_int32)val);
        !          2787:        } else if (STREQ(pcmd->argval[1].string, "flags")) {
        !          2788:                fudgedata.which = htonl(FUDGE_FLAGS);
        !          2789:                if (!hextoint(pcmd->argval[2].string, &u_val))
        !          2790:                    err = 1;
        !          2791:                else
        !          2792:                    fudgedata.fudgeval_flags = htonl((u_int32)(u_val & 0xf));
        !          2793:        } else {
        !          2794:                (void) fprintf(stderr, "What fudge is %s?\n",
        !          2795:                               pcmd->argval[1].string);
        !          2796:                return;
        !          2797:        }
        !          2798: 
        !          2799:        if (err) {
        !          2800:                (void) fprintf(stderr, "Unknown fudge parameter %s\n",
        !          2801:                               pcmd->argval[2].string);
        !          2802:                return;
        !          2803:        }
        !          2804: 
        !          2805: again:
        !          2806:        res = doquery(impl_ver, REQ_SET_CLKFUDGE, 1, 1,
        !          2807:                      sizeof(struct conf_fudge), (char *)&fudgedata, &items,
        !          2808:                      &itemsize, &dummy, 0, sizeof(dummy));
        !          2809: 
        !          2810:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          2811:                impl_ver = IMPL_XNTPD_OLD;
        !          2812:                goto again;
        !          2813:        }
        !          2814: 
        !          2815:        if (res == 0)
        !          2816:            (void) fprintf(fp, "done!\n");
        !          2817:        return;
        !          2818: }
        !          2819: 
        !          2820: /*
        !          2821:  * clkbug - get and print clock debugging information
        !          2822:  */
        !          2823: static void
        !          2824: clkbug(
        !          2825:        struct parse *pcmd,
        !          2826:        FILE *fp
        !          2827:        )
        !          2828: {
        !          2829:        register int i;
        !          2830:        register int n;
        !          2831:        register u_int32 s;
        !          2832:        struct info_clkbug *cl;
        !          2833:        /* 8 is the maximum number of clocks which will fit in a packet */
        !          2834:        u_long clist[min(MAXARGS, 8)];
        !          2835:        u_int32 ltemp;
        !          2836:        int qitemlim;
        !          2837:        int qitems;
        !          2838:        int items;
        !          2839:        int itemsize;
        !          2840:        int res;
        !          2841:        int needsp;
        !          2842:        l_fp ts;
        !          2843: 
        !          2844:        qitemlim = min(pcmd->nargs, COUNTOF(clist));
        !          2845:        for (qitems = 0; qitems < qitemlim; qitems++)
        !          2846:                clist[qitems] = NSRCADR(&pcmd->argval[qitems].netnum);
        !          2847: 
        !          2848: again:
        !          2849:        res = doquery(impl_ver, REQ_GET_CLKBUGINFO, 0, qitems,
        !          2850:                      sizeof(u_int32), (char *)clist, &items,
        !          2851:                      &itemsize, (void *)&cl, 0, sizeof(struct info_clkbug));
        !          2852:        
        !          2853:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          2854:                impl_ver = IMPL_XNTPD_OLD;
        !          2855:                goto again;
        !          2856:        }
        !          2857: 
        !          2858:        if (res != 0)
        !          2859:                return;
        !          2860: 
        !          2861:        if (!checkitems(items, fp))
        !          2862:                return;
        !          2863: 
        !          2864:        if (!checkitemsize(itemsize, sizeof(struct info_clkbug)))
        !          2865:                return;
        !          2866: 
        !          2867:        while (items-- > 0) {
        !          2868:                (void) fprintf(fp, "clock address:        %s\n",
        !          2869:                               numtoa(cl->clockadr));
        !          2870:                n = (int)cl->nvalues;
        !          2871:                (void) fprintf(fp, "values: %d", n);
        !          2872:                s = ntohs(cl->svalues);
        !          2873:                if (n > NUMCBUGVALUES)
        !          2874:                    n = NUMCBUGVALUES;
        !          2875:                for (i = 0; i < n; i++) {
        !          2876:                        ltemp = ntohl(cl->values[i]);
        !          2877:                        ltemp &= 0xffffffff;    /* HMS: This does nothing now */
        !          2878:                        if ((i & 0x3) == 0)
        !          2879:                            (void) fprintf(fp, "\n");
        !          2880:                        if (s & (1 << i))
        !          2881:                            (void) fprintf(fp, "%12ld", (u_long)ltemp);
        !          2882:                        else
        !          2883:                            (void) fprintf(fp, "%12lu", (u_long)ltemp);
        !          2884:                }
        !          2885:                (void) fprintf(fp, "\n");
        !          2886: 
        !          2887:                n = (int)cl->ntimes;
        !          2888:                (void) fprintf(fp, "times: %d", n);
        !          2889:                s = ntohl(cl->stimes);
        !          2890:                if (n > NUMCBUGTIMES)
        !          2891:                    n = NUMCBUGTIMES;
        !          2892:                needsp = 0;
        !          2893:                for (i = 0; i < n; i++) {
        !          2894:                        if ((i & 0x1) == 0) {
        !          2895:                            (void) fprintf(fp, "\n");
        !          2896:                        } else {
        !          2897:                                for (;needsp > 0; needsp--)
        !          2898:                                    putc(' ', fp);
        !          2899:                        }
        !          2900:                        NTOHL_FP(&cl->times[i], &ts);
        !          2901:                        if (s & (1 << i)) {
        !          2902:                                (void) fprintf(fp, "%17s",
        !          2903:                                               lfptoa(&ts, 6));
        !          2904:                                needsp = 22;
        !          2905:                        } else {
        !          2906:                                (void) fprintf(fp, "%37s",
        !          2907:                                               uglydate(&ts));
        !          2908:                                needsp = 2;
        !          2909:                        }
        !          2910:                }
        !          2911:                (void) fprintf(fp, "\n");
        !          2912:                if (items > 0) {
        !          2913:                        cl++;
        !          2914:                        (void) fprintf(fp, "\n");
        !          2915:                }
        !          2916:        }
        !          2917: }
        !          2918: 
        !          2919: 
        !          2920: /*
        !          2921:  * kerninfo - display the kernel pll/pps variables
        !          2922:  */
        !          2923: static void
        !          2924: kerninfo(
        !          2925:        struct parse *pcmd,
        !          2926:        FILE *fp
        !          2927:        )
        !          2928: {
        !          2929:        struct info_kernel *ik;
        !          2930:        int items;
        !          2931:        int itemsize;
        !          2932:        int res;
        !          2933:        unsigned status;
        !          2934:        double tscale = 1e-6;
        !          2935: 
        !          2936: again:
        !          2937:        res = doquery(impl_ver, REQ_GET_KERNEL, 0, 0, 0, (char *)NULL,
        !          2938:                      &items, &itemsize, (void *)&ik, 0, 
        !          2939:                      sizeof(struct info_kernel));
        !          2940: 
        !          2941:        if (res == INFO_ERR_IMPL && impl_ver == IMPL_XNTPD) {
        !          2942:                impl_ver = IMPL_XNTPD_OLD;
        !          2943:                goto again;
        !          2944:        }
        !          2945: 
        !          2946:        if (res != 0)
        !          2947:            return;
        !          2948:        if (!check1item(items, fp))
        !          2949:            return;
        !          2950:        if (!checkitemsize(itemsize, sizeof(struct info_kernel)))
        !          2951:            return;
        !          2952: 
        !          2953:        status = ntohs(ik->status) & 0xffff;
        !          2954:        /*
        !          2955:         * pll variables. We know more than we should about the NANO bit.
        !          2956:         */
        !          2957: #ifdef STA_NANO
        !          2958:        if (status & STA_NANO)
        !          2959:                tscale = 1e-9;
        !          2960: #endif
        !          2961:        (void)fprintf(fp, "pll offset:           %g s\n",
        !          2962:            (int32)ntohl(ik->offset) * tscale);
        !          2963:        (void)fprintf(fp, "pll frequency:        %s ppm\n",
        !          2964:            fptoa((s_fp)ntohl(ik->freq), 3));
        !          2965:        (void)fprintf(fp, "maximum error:        %g s\n",
        !          2966:            (u_long)ntohl(ik->maxerror) * 1e-6);
        !          2967:        (void)fprintf(fp, "estimated error:      %g s\n",
        !          2968:            (u_long)ntohl(ik->esterror) * 1e-6);
        !          2969:        (void)fprintf(fp, "status:               %04x ", status);
        !          2970: #ifdef STA_PLL
        !          2971:        if (status & STA_PLL) (void)fprintf(fp, " pll");
        !          2972: #endif
        !          2973: #ifdef STA_PPSFREQ
        !          2974:        if (status & STA_PPSFREQ) (void)fprintf(fp, " ppsfreq");
        !          2975: #endif
        !          2976: #ifdef STA_PPSTIME
        !          2977:        if (status & STA_PPSTIME) (void)fprintf(fp, " ppstime");
        !          2978: #endif
        !          2979: #ifdef STA_FLL
        !          2980:        if (status & STA_FLL) (void)fprintf(fp, " fll");
        !          2981: #endif
        !          2982: #ifdef STA_INS
        !          2983:        if (status & STA_INS) (void)fprintf(fp, " ins");
        !          2984: #endif
        !          2985: #ifdef STA_DEL
        !          2986:        if (status & STA_DEL) (void)fprintf(fp, " del");
        !          2987: #endif
        !          2988: #ifdef STA_UNSYNC
        !          2989:        if (status & STA_UNSYNC) (void)fprintf(fp, " unsync");
        !          2990: #endif
        !          2991: #ifdef STA_FREQHOLD
        !          2992:        if (status & STA_FREQHOLD) (void)fprintf(fp, " freqhold");
        !          2993: #endif
        !          2994: #ifdef STA_PPSSIGNAL
        !          2995:        if (status & STA_PPSSIGNAL) (void)fprintf(fp, " ppssignal");
        !          2996: #endif
        !          2997: #ifdef STA_PPSJITTER
        !          2998:        if (status & STA_PPSJITTER) (void)fprintf(fp, " ppsjitter");
        !          2999: #endif
        !          3000: #ifdef STA_PPSWANDER
        !          3001:        if (status & STA_PPSWANDER) (void)fprintf(fp, " ppswander");
        !          3002: #endif
        !          3003: #ifdef STA_PPSERROR
        !          3004:        if (status & STA_PPSERROR) (void)fprintf(fp, " ppserror");
        !          3005: #endif
        !          3006: #ifdef STA_CLOCKERR
        !          3007:        if (status & STA_CLOCKERR) (void)fprintf(fp, " clockerr");
        !          3008: #endif
        !          3009: #ifdef STA_NANO
        !          3010:        if (status & STA_NANO) (void)fprintf(fp, " nano");
        !          3011: #endif
        !          3012: #ifdef STA_MODE
        !          3013:        if (status & STA_MODE) (void)fprintf(fp, " mode=fll");
        !          3014: #endif
        !          3015: #ifdef STA_CLK
        !          3016:        if (status & STA_CLK) (void)fprintf(fp, " src=B");
        !          3017: #endif
        !          3018:        (void)fprintf(fp, "\n");
        !          3019:        (void)fprintf(fp, "pll time constant:    %ld\n",
        !          3020:            (u_long)ntohl(ik->constant));
        !          3021:        (void)fprintf(fp, "precision:            %g s\n",
        !          3022:            (u_long)ntohl(ik->precision) * tscale);
        !          3023:        (void)fprintf(fp, "frequency tolerance:  %s ppm\n",
        !          3024:            fptoa((s_fp)ntohl(ik->tolerance), 0));
        !          3025: 
        !          3026:        /*
        !          3027:         * For backwards compatibility (ugh), we find the pps variables
        !          3028:         * only if the shift member is nonzero.
        !          3029:         */
        !          3030:        if (!ik->shift)
        !          3031:            return;
        !          3032: 
        !          3033:        /*
        !          3034:         * pps variables
        !          3035:         */
        !          3036:        (void)fprintf(fp, "pps frequency:        %s ppm\n",
        !          3037:            fptoa((s_fp)ntohl(ik->ppsfreq), 3));
        !          3038:        (void)fprintf(fp, "pps stability:        %s ppm\n",
        !          3039:            fptoa((s_fp)ntohl(ik->stabil), 3));
        !          3040:        (void)fprintf(fp, "pps jitter:           %g s\n",
        !          3041:            (u_long)ntohl(ik->jitter) * tscale);
        !          3042:        (void)fprintf(fp, "calibration interval: %d s\n",
        !          3043:                      1 << ntohs(ik->shift));
        !          3044:        (void)fprintf(fp, "calibration cycles:   %ld\n",
        !          3045:                      (u_long)ntohl(ik->calcnt));
        !          3046:        (void)fprintf(fp, "jitter exceeded:      %ld\n",
        !          3047:                      (u_long)ntohl(ik->jitcnt));
        !          3048:        (void)fprintf(fp, "stability exceeded:   %ld\n",
        !          3049:                      (u_long)ntohl(ik->stbcnt));
        !          3050:        (void)fprintf(fp, "calibration errors:   %ld\n",
        !          3051:                      (u_long)ntohl(ik->errcnt));
        !          3052: }
        !          3053: 
        !          3054: #define IF_LIST_FMT     "%2d %c %48s %c %c %12.12s %03lx %3lu %2lu %5lu %5lu %5lu %2lu %3lu %7lu\n"
        !          3055: #define IF_LIST_FMT_STR "%2s %c %48s %c %c %12.12s %3s %3s %2s %5s %5s %5s %2s %3s %7s\n"
        !          3056: #define IF_LIST_AFMT_STR "     %48s %c\n"
        !          3057: #define IF_LIST_LABELS  "#", 'A', "Address/Mask/Broadcast", 'T', 'E', "IF name", "Flg", "TL", "#M", "recv", "sent", "drop", "S", "PC", "uptime"
        !          3058: #define IF_LIST_LINE    "==================================================================================================================\n"
        !          3059: 
        !          3060: static void
        !          3061: iflist(
        !          3062:        FILE *fp,
        !          3063:        struct info_if_stats *ifs,
        !          3064:        int items,
        !          3065:        int itemsize,
        !          3066:        int res
        !          3067:        )
        !          3068: {
        !          3069:        static char *actions = "?.+-";
        !          3070:        sockaddr_u saddr;
        !          3071: 
        !          3072:        if (res != 0)
        !          3073:            return;
        !          3074: 
        !          3075:        if (!checkitems(items, fp))
        !          3076:            return;
        !          3077: 
        !          3078:        if (!checkitemsize(itemsize, sizeof(struct info_if_stats)))
        !          3079:            return;
        !          3080: 
        !          3081:        fprintf(fp, IF_LIST_FMT_STR, IF_LIST_LABELS);
        !          3082:        fprintf(fp, IF_LIST_LINE);
        !          3083:        
        !          3084:        while (items > 0) {
        !          3085:                SET_ADDR(saddr, ntohl(ifs->v6_flag), 
        !          3086:                         ifs->unaddr.addr.s_addr, ifs->unaddr.addr6);
        !          3087:                fprintf(fp, IF_LIST_FMT,
        !          3088:                        ntohl(ifs->ifnum),
        !          3089:                        actions[(ifs->action >= 1 && ifs->action < 4) ? ifs->action : 0],
        !          3090:                        stoa((&saddr)), 'A',
        !          3091:                        ifs->ignore_packets ? 'D' : 'E',
        !          3092:                        ifs->name,
        !          3093:                        (u_long)ntohl(ifs->flags),
        !          3094:                        (u_long)ntohl(ifs->last_ttl),
        !          3095:                        (u_long)ntohl(ifs->num_mcast),
        !          3096:                        (u_long)ntohl(ifs->received),
        !          3097:                        (u_long)ntohl(ifs->sent),
        !          3098:                        (u_long)ntohl(ifs->notsent),
        !          3099:                        (u_long)ntohl(ifs->scopeid),
        !          3100:                        (u_long)ntohl(ifs->peercnt),
        !          3101:                        (u_long)ntohl(ifs->uptime));
        !          3102: 
        !          3103:                SET_ADDR(saddr, ntohl(ifs->v6_flag), 
        !          3104:                         ifs->unmask.addr.s_addr, ifs->unmask.addr6);
        !          3105:                fprintf(fp, IF_LIST_AFMT_STR, stoa(&saddr), 'M');
        !          3106: 
        !          3107:                if (!ntohl(ifs->v6_flag) && ntohl(ifs->flags) & (INT_BCASTOPEN)) {
        !          3108:                        SET_ADDR(saddr, ntohl(ifs->v6_flag), 
        !          3109:                                 ifs->unbcast.addr.s_addr, ifs->unbcast.addr6);
        !          3110:                        fprintf(fp, IF_LIST_AFMT_STR, stoa(&saddr), 'B');
        !          3111: 
        !          3112:                }
        !          3113: 
        !          3114:                ifs++;
        !          3115:                items--;
        !          3116:        }
        !          3117: }
        !          3118: 
        !          3119: /*ARGSUSED*/
        !          3120: static void
        !          3121: get_if_stats(
        !          3122:        struct parse *pcmd,
        !          3123:        FILE *fp
        !          3124:        )
        !          3125: {
        !          3126:        struct info_if_stats *ifs;
        !          3127:        int items;
        !          3128:        int itemsize;
        !          3129:        int res;
        !          3130: 
        !          3131:        res = doquery(impl_ver, REQ_IF_STATS, 1, 0, 0, (char *)NULL, &items,
        !          3132:                      &itemsize, (void *)&ifs, 0, 
        !          3133:                      sizeof(struct info_if_stats));
        !          3134:        iflist(fp, ifs, items, itemsize, res);
        !          3135: }
        !          3136: 
        !          3137: /*ARGSUSED*/
        !          3138: static void
        !          3139: do_if_reload(
        !          3140:        struct parse *pcmd,
        !          3141:        FILE *fp
        !          3142:        )
        !          3143: {
        !          3144:        struct info_if_stats *ifs;
        !          3145:        int items;
        !          3146:        int itemsize;
        !          3147:        int res;
        !          3148: 
        !          3149:        res = doquery(impl_ver, REQ_IF_RELOAD, 1, 0, 0, (char *)NULL, &items,
        !          3150:                      &itemsize, (void *)&ifs, 0, 
        !          3151:                      sizeof(struct info_if_stats));
        !          3152:        iflist(fp, ifs, items, itemsize, res);
        !          3153: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>