File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / ntpd / ntp_request.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:37 2012 UTC (12 years, 2 months ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

    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>