Annotation of embedaddon/ntp/ntpd/ntp_request.c, revision 1.1

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

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