Annotation of embedaddon/ntp/ntpd/ntp_request.c, revision 1.1.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>