Mon Jan 6 19:12:23 2014 UTC ()
etc/ntp.conf					1.16, 1.17, 1.18 via patch
external/bsd/ntp/dist/ntpd/ntp_request.c	patch

	Patch from ntp 4.2.7p404 to prevent an amplifier and DoS attack.
	Add several "restrict" lines to the default ntp.conf and
	improve comments
	[spz, ticket #1010]


(bouyer)
diff -r1.14 -r1.14.16.1 src/etc/ntp.conf
diff -r1.7 -r1.7.16.1 src/external/bsd/ntp/dist/ntpd/ntp_request.c

cvs diff -r1.14 -r1.14.16.1 src/etc/ntp.conf (expand / switch to context diff)
--- src/etc/ntp.conf 2012/01/16 22:20:45 1.14
+++ src/etc/ntp.conf 2014/01/06 19:12:23 1.14.16.1
@@ -1,4 +1,4 @@
-# $NetBSD: ntp.conf,v 1.14 2012/01/16 22:20:45 christos Exp $
+# $NetBSD: ntp.conf,v 1.14.16.1 2014/01/06 19:12:23 bouyer Exp $
 #
 # NetBSD default Network Time Protocol (NTP) configuration file for ntpd
 
@@ -23,7 +23,8 @@
 
 logconfig	-syncstatus
 
-# This will help minimize disruptions due to network congestion. Don't
+# Refuse to set the local clock if there are too few good peers or servers.
+# This may help minimize disruptions due to network congestion. Don't
 # do this if you configure only one server!
 
 tos		minsane 2
@@ -32,45 +33,87 @@
 #
 mdnstries	0
 
+# Access control restrictions.
+# See /usr/share/doc/html/ntp/accopt.html for syntax.
+# See <http://support.ntp.org/bin/view/Support/AccessRestrictions> for advice.
+# Last match wins.
+#
+# Some of the more common keywords are:
+#   ignore      Deny packets of all kinds.
+#   kod         Send "kiss-o'-death" packets if clients exceed rate
+#               limits.
+#   nomodify    Deny attempts to modify the state of the server via
+#               ntpq or ntpdc queries.
+#   noquery     Deny all ntpq and ntpdc queries.  Does not affect time
+#               synchronisation.
+#   nopeer      Prevent establishing an new peer association.
+#               Does not affect preconfigured peer associations.
+#               Does not affect client/server time synchronisation.
+#   noserve     Deny all time synchronisation.  Does not affect ntpq or
+#               ntpdc queries.
+#   notrap      Deny the trap subset of the ntpdc control message protocol.
+#   notrust     Deny packets that are not cryptographically authenticated.
+#
+# By default, either deny everything, or allow client/server time exchange
+# but deny configuration changes, queries, and peer associations that were not
+# explicitly configured.
+# (Uncomment one of the following "restrict default" lines.)
+#
+#restrict default ignore
+restrict default kod nopeer noquery
+
+# Fewer restrictions for the local subnet.
+# (Uncomment and adjust as appropriate.)
+#
+#restrict 192.0.2.0 mask 255.255.255.0 kod nomodify notrap nopeer
+#restrict 2001:db8:: mask ffff:ffff::  kod nomodify notrap nopeer
+
+# No restrictions for localhost.
+#
+restrict 127.0.0.1
+restrict ::1
+
 # Hereafter should be "server" or "peer" statements to configure other
-# hosts to exchange NTP packets with. Peers should be selected in such
-# a way that the network path to them is symmetric (that is, the series
-# of links and routers used to get to the peer is the same one that the
-# peer uses to get back. NTP assumes such symmetry in its network delay
-# calculation. NTP will apply an incorrect adjustment to timestamps
-# received from the peer if the path is not symmetric. This can result
-# in clock skew (your system clock being maintained consistently wrong
-# by a certain amount).
+# hosts to exchange NTP packets with.
 #
-# The best way to select symmetric peers is to make sure that the
-# network path to them is as short as possible (this reduces the chance
-# that there is more than one network path between you and your peer).
-# You can measure these distances with the traceroute(8)  program. The
-# best place to start looking for NTP peers for your system is within
-# your own network, or at your Internet Service Provider (ISP).
+# See <http://support.ntp.org/bin/view/Support/DesigningYourNTPNetwork>
+# and <http://support.ntp.org/bin/view/Support/SelectingOffsiteNTPServers>
+# for advice.
 #
+# Peers should be selected in such a way that the network path to them
+# is short, uncongested, and symmetric (that is, the series of links
+# and routers used to get to the peer is the same one that the peer
+# uses to get back).  The best place to start looking for NTP peers for
+# your system is within your own network, or at your Internet Service
+# Provider (ISP).
+#
 # Ideally, you should select at least three other systems to talk NTP
 # with, for an "what I tell you three times is true" effect.
 #
 
 #peer		an.ntp.peer.goes.here
 #server		an.ntp.server.goes.here
+#restrict	an.ntp.server.goes.here nomodify notrap
 
-# Public servers from the pool.ntp.org project. Volunteer's servers
-# are dynamically assigned to the CNAMES below via DNS round-robin.
+# The pool.ntp.org project coordinates public time servers provided by
+# volunteers.  See <http://www.pool.ntp.org>.  The *.netbsd.pool.ntp.org
+# servers are intended to be used by default on NetBSD hosts, but
+# servers that are closer to you are likely to be better.  Consider
+# using servers specific to your country, a nearby country, or your
+# continent.
+#
 # The pool.ntp.org project needs more volunteers! The only criteria to
 # join are a nailed-up connection and a static IP address. For details,
 # see the web page:
 #
-#	http://www.pool.ntp.org/join.html
+#       http://www.pool.ntp.org/join.html
 #
 
-# Depending on the vagaries of DNS can occasionally pull in the same
+server          0.netbsd.pool.ntp.org
-# server twice. The following CNAMES are guaranteed to be disjoint, at
+restrict        0.netbsd.pool.ntp.org nomodify notrap
-# least over some short interval. The following servers are allocated
+server          1.netbsd.pool.ntp.org
-# to the NetBSD project.
+restrict        1.netbsd.pool.ntp.org nomodify notrap
-
+server          2.netbsd.pool.ntp.org
-server		0.netbsd.pool.ntp.org
+restrict        2.netbsd.pool.ntp.org nomodify notrap
-server		1.netbsd.pool.ntp.org
+server          3.netbsd.pool.ntp.org
-server		2.netbsd.pool.ntp.org
+restrict        3.netbsd.pool.ntp.org nomodify notrap
-server		3.netbsd.pool.ntp.org

cvs diff -r1.7 -r1.7.16.1 src/external/bsd/ntp/dist/ntpd/ntp_request.c (expand / switch to context diff)
--- src/external/bsd/ntp/dist/ntpd/ntp_request.c 2012/02/01 22:48:15 1.7
+++ src/external/bsd/ntp/dist/ntpd/ntp_request.c 2014/01/06 19:12:22 1.7.16.1
@@ -1,4 +1,4 @@
-/*	$NetBSD: ntp_request.c,v 1.7 2012/02/01 22:48:15 kardel Exp $	*/
+/*	$NetBSD: ntp_request.c,v 1.7.16.1 2014/01/06 19:12:22 bouyer Exp $	*/
 
 /*
  * ntp_request.c - respond to information requests
@@ -88,8 +88,7 @@
 static	void	do_ressubflags	(sockaddr_u *, struct interface *, struct req_pkt *);
 static	void	do_unrestrict	(sockaddr_u *, struct interface *, struct req_pkt *);
 static	void	do_restrict	(sockaddr_u *, struct interface *, struct req_pkt *, int);
-static	void	mon_getlist_0	(sockaddr_u *, struct interface *, struct req_pkt *);
-static	void	mon_getlist_1	(sockaddr_u *, struct interface *, struct req_pkt *);
+static	void	mon_getlist	(sockaddr_u *, struct interface *, struct req_pkt *);
 static	void	reset_stats	(sockaddr_u *, struct interface *, struct req_pkt *);
 static	void	reset_peer	(sockaddr_u *, struct interface *, struct req_pkt *);
 static	void	do_key_reread	(sockaddr_u *, struct interface *, struct req_pkt *);
@@ -149,8 +148,8 @@
 				sizeof(struct conf_restrict), do_ressubflags },
 	{ REQ_UNRESTRICT, AUTH, v4sizeof(struct conf_restrict),
 				sizeof(struct conf_restrict), do_unrestrict },
-	{ REQ_MON_GETLIST,	NOAUTH,	0, 0,	mon_getlist_0 },
-	{ REQ_MON_GETLIST_1,	NOAUTH,	0, 0,	mon_getlist_1 },
+	{ REQ_MON_GETLIST,	NOAUTH,	0, 0,	mon_getlist },
+	{ REQ_MON_GETLIST_1,	NOAUTH,	0, 0,	mon_getlist },
 	{ REQ_RESET_STATS, AUTH, sizeof(struct reset_flags), 0, reset_stats },
 	{ REQ_RESET_PEER,  AUTH, v4sizeof(struct conf_unpeer),
 				sizeof(struct conf_unpeer), reset_peer },
@@ -614,6 +613,9 @@
 				"process_private: failed auth mod_okay %d\n",
 				mod_okay);
 #endif
+			if (!mod_okay) {
+				sys_restricted++;
+			}
 			req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
 			return;
 		}
@@ -825,34 +827,42 @@
 	struct req_pkt *inpkt
 	)
 {
-	register struct info_peer_list *ipl;
+	struct info_peer_list ipl;
 	register struct peer *pp;
 	register struct info_peer *ip;
 	register int items;
+	size_t item_sz;
+	char * datap;
 	register int i, j;
 	sockaddr_u addr;
 	extern struct peer *sys_peer;
 	l_fp ltmp;
 
 	items = INFO_NITEMS(inpkt->err_nitems);
-	ipl = (struct info_peer_list *) inpkt->data;
-
+	item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize);
+	datap = inpkt->data;  
+	if (item_sz != sizeof(ipl)) {
+		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+		return; 
+	}
 	ip = (struct info_peer *)prepare_pkt(srcadr, inter, inpkt,
 	    v6sizeof(struct info_peer));
 	while (items-- > 0 && ip != 0) {
+		memset(&ipl,0,sizeof(ipl));
+		memcpy(&ipl, datap, item_sz);
 		ZERO_SOCK(&addr);
-		NSRCPORT(&addr) = ipl->port;
-		if (client_v6_capable && ipl->v6_flag) {
+		NSRCPORT(&addr) = ipl.port;
+		if (client_v6_capable && ipl.v6_flag) {
 			AF(&addr) = AF_INET6;
-			SOCK_ADDR6(&addr) = ipl->addr6;
+			SOCK_ADDR6(&addr) = ipl.addr6;
 		} else {
 			AF(&addr) = AF_INET;
-			NSRCADR(&addr) = ipl->addr;
+			NSRCADR(&addr) = ipl.addr;
 		}
 #ifdef ISC_PLATFORM_HAVESALEN
 		addr.sa.sa_len = SOCKLEN(&addr);
 #endif
-		ipl++;
+		datap += item_sz;
 		pp = findexistingpeer(&addr, NULL, -1, 0);
 		if (NULL == pp)
 			continue;
@@ -958,10 +968,12 @@
 	struct req_pkt *inpkt
 	)
 {
-	register struct info_peer_list *ipl;
+	struct info_peer_list ipl;
 	register struct peer *pp;
 	register struct info_peer_stats *ip;
 	register int items;
+	size_t item_sz;
+	char * datap;
 	sockaddr_u addr;
 	extern struct peer *sys_peer;
 
@@ -970,27 +982,33 @@
 	     printf("peer_stats: called\n");
 #endif
 	items = INFO_NITEMS(inpkt->err_nitems);
-	ipl = (struct info_peer_list *) inpkt->data;
+	item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize);
+	datap = inpkt->data;  
+	if (item_sz > sizeof(ipl)) {
+		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+		return; 
+	}
 	ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt,
 	    v6sizeof(struct info_peer_stats));
 	while (items-- > 0 && ip != 0) {
+		memset(&ipl,0,sizeof(ipl));
+		memcpy(&ipl, datap, item_sz);
 		memset((char *)&addr, 0, sizeof(addr));
-		NSRCPORT(&addr) = ipl->port;
-		if (client_v6_capable && ipl->v6_flag) {
+		NSRCPORT(&addr) = ipl.port;
+		if (client_v6_capable && ipl.v6_flag) {
 			AF(&addr) = AF_INET6;
-			SOCK_ADDR6(&addr) = ipl->addr6;
+			SOCK_ADDR6(&addr) = ipl.addr6;
 		} else {
 			AF(&addr) = AF_INET;
-			NSRCADR(&addr) = ipl->addr;
+			NSRCADR(&addr) = ipl.addr;
 		}	
 #ifdef ISC_PLATFORM_HAVESALEN
 		addr.sa.sa_len = SOCKLEN(&addr);
 #endif
 		DPRINTF(1, ("peer_stats: looking for %s, %d, %d\n",
-			    stoa(&addr), ipl->port, NSRCPORT(&addr)));
+			    stoa(&addr), ipl.port, NSRCPORT(&addr)));
 
-		ipl = (struct info_peer_list *)((char *)ipl +
-		    INFO_ITEMSIZE(inpkt->mbz_itemsize));
+		datap += item_sz;
 
 		pp = findexistingpeer(&addr, NULL, -1, 0);
 		if (NULL == pp)
@@ -1326,10 +1344,10 @@
 	struct req_pkt *inpkt
 	)
 {
-	static u_long soonest_ifrescan_time = 0;
 	int items;
+	size_t item_sz;
+	char * datap;
 	u_int fl;
-	struct conf_peer *cp; 
 	struct conf_peer temp_cp;
 	sockaddr_u peeraddr;
 
@@ -1339,42 +1357,16 @@
 	 * very picky here.
 	 */
 	items = INFO_NITEMS(inpkt->err_nitems);
-	cp = (struct conf_peer *)inpkt->data;
-	memset(&temp_cp, 0, sizeof(struct conf_peer));
-	memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
-
-#if 0 /* paranoid checking - these are done in newpeer() */
-	fl = 0;
-	while (items-- > 0 && !fl) {
-		if (((temp_cp.version) > NTP_VERSION)
-		    || ((temp_cp.version) < NTP_OLDVERSION))
-		    fl = 1;
-		if (temp_cp.hmode != MODE_ACTIVE
-		    && temp_cp.hmode != MODE_CLIENT
-		    && temp_cp.hmode != MODE_BROADCAST)
-		    fl = 1;
-		if (temp_cp.flags & ~(CONF_FLAG_PREFER | CONF_FLAG_BURST |
-		    CONF_FLAG_IBURST | CONF_FLAG_SKEY))
-			fl = 1;
-		cp = (struct conf_peer *)
-		    ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
-	}
-
-	if (fl) {
+	item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize);
+	datap = inpkt->data;
+	if (item_sz > sizeof(temp_cp)) {
 		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
 		return;
 	}
-#endif /* end paranoid checking */
 
-	/*
-	 * Looks okay, try it out
-	 */
-	items = INFO_NITEMS(inpkt->err_nitems);
-	cp = (struct conf_peer *)inpkt->data;  
-
 	while (items-- > 0) {
 		memset(&temp_cp, 0, sizeof(struct conf_peer));
-		memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
+		memcpy(&temp_cp, datap, item_sz);
 		ZERO_SOCK(&peeraddr);
 
 		fl = 0;
@@ -1418,24 +1410,7 @@
 			return;
 		}
 
-		/*
-		 * ntp_intres.c uses REQ_CONFIG/doconf() to add each
-		 * server after its name is resolved.  If we have been
-		 * disconnected from the network, it may notice the
-		 * network has returned and add the first server while
-		 * the relevant interface is still disabled, awaiting
-		 * the next interface rescan.  To get things moving
-		 * more quickly, trigger an interface scan now, except
-		 * if we have done so in the last half minute.
-		 */
-		if (soonest_ifrescan_time < current_time) {
-			soonest_ifrescan_time = current_time + 30;
-			timer_interfacetimeout(current_time);
-			DPRINTF(1, ("do_conf triggering interface rescan\n"));
-		}
-
-		cp = (struct conf_peer *)
-		    ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
+		datap += item_sz;
 	}
 
 	req_ack(srcadr, inter, inpkt, INFO_OKAY);
@@ -1540,9 +1515,10 @@
 	struct req_pkt *inpkt
 	)
 {
-	register struct conf_unpeer *cp;
 	struct conf_unpeer temp_cp;
 	register int items;
+	size_t item_sz;
+	char * datap;
 	register struct peer *peer;
 	sockaddr_u peeraddr;
 	int bad, found;
@@ -1554,13 +1530,18 @@
 	 * an error.
 	 */
 	items = INFO_NITEMS(inpkt->err_nitems);
-	cp = (struct conf_unpeer *)inpkt->data;
+	item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize);
+	datap = inpkt->data;  
+	if (item_sz > sizeof(temp_cp)) {
+		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+		return; 
+	}
 
 	bad = 0;
 	while (items-- > 0 && !bad) {
 		memset(&temp_cp, 0, sizeof(temp_cp));
+		memcpy(&temp_cp, datap, item_sz);
 		ZERO_SOCK(&peeraddr);
-		memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
 		if (client_v6_capable && temp_cp.v6_flag) {
 			AF(&peeraddr) = AF_INET6;
 			SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6;
@@ -1586,8 +1567,7 @@
 		}
 		if (!found)
 			bad = 1;
-		cp = (struct conf_unpeer *)
-			((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
+		datap += item_sz;
 	}
 
 	if (bad) {
@@ -1600,12 +1580,12 @@
 	 */
 
 	items = INFO_NITEMS(inpkt->err_nitems);
-	cp = (struct conf_unpeer *)inpkt->data;
+	datap = inpkt->data;
 
 	while (items-- > 0) {
 		memset(&temp_cp, 0, sizeof(temp_cp));
+		memcpy(&temp_cp, datap, item_sz);
 		memset(&peeraddr, 0, sizeof(peeraddr));
-		memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
 		if (client_v6_capable && temp_cp.v6_flag) {
 			AF(&peeraddr) = AF_INET6;
 			SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6;
@@ -1633,8 +1613,7 @@
 		peer_clear(peer, "GONE");
 		unpeer(peer);
 
-		cp = (struct conf_unpeer *)
-			((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
+		datap += item_sz;
 	}
 
 	req_ack(srcadr, inter, inpkt, INFO_OKAY);
@@ -1868,8 +1847,10 @@
 	int op
 	)
 {
-	register struct conf_restrict *cr;
+	struct conf_restrict cr;
 	register int items;
+	size_t item_sz;
+	char * datap;
 	sockaddr_u matchaddr;
 	sockaddr_u matchmask;
 	int bad;
@@ -1880,26 +1861,31 @@
 	 * about it.  Note we are very picky here.
 	 */
 	items = INFO_NITEMS(inpkt->err_nitems);
-	cr = (struct conf_restrict *)inpkt->data;
+	item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize);
+	datap = inpkt->data;  
+	if (item_sz > sizeof(cr)) {
+		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+		return; 
+	}
 
 	bad = 0;
-	cr->flags = ntohs(cr->flags);
-	cr->mflags = ntohs(cr->mflags);
 	while (items-- > 0 && !bad) {
-		if (cr->mflags & ~(RESM_NTPONLY))
+		memcpy(&cr, datap, item_sz);
+		cr.flags = ntohs(cr.flags);
+		cr.mflags = ntohs(cr.mflags);
+		if (cr.mflags & ~(RESM_NTPONLY))
 		    bad |= 1;
-		if (cr->flags & ~(RES_ALLFLAGS))
+		if (cr.flags & ~(RES_ALLFLAGS))
 		    bad |= 2;
-		if (cr->mask != htonl(INADDR_ANY)) {
-			if (client_v6_capable && cr->v6_flag != 0) {
-				if (IN6_IS_ADDR_UNSPECIFIED(&cr->addr6))
+		if (cr.mask != htonl(INADDR_ANY)) {
+			if (client_v6_capable && cr.v6_flag != 0) {
+				if (IN6_IS_ADDR_UNSPECIFIED(&cr.addr6))
 					bad |= 4;
 			} else
-				if (cr->addr == htonl(INADDR_ANY))
+				if (cr.addr == htonl(INADDR_ANY))
 					bad |= 8;
 		}
-		cr = (struct conf_restrict *)((char *)cr +
-		    INFO_ITEMSIZE(inpkt->mbz_itemsize));
+		datap += item_sz;
 	}
 
 	if (bad) {
@@ -1911,26 +1897,28 @@
 	/*
 	 * Looks okay, try it out
 	 */
-	items = INFO_NITEMS(inpkt->err_nitems);
-	cr = (struct conf_restrict *)inpkt->data;
 	ZERO_SOCK(&matchaddr);
 	ZERO_SOCK(&matchmask);
+	datap = inpkt->data;
 
 	while (items-- > 0) {
-		if (client_v6_capable && cr->v6_flag) {
+		memcpy(&cr, datap, item_sz);
+		cr.flags = ntohs(cr.flags);
+		cr.mflags = ntohs(cr.mflags);
+		if (client_v6_capable && cr.v6_flag) {
 			AF(&matchaddr) = AF_INET6;
 			AF(&matchmask) = AF_INET6;
-			SOCK_ADDR6(&matchaddr) = cr->addr6;
-			SOCK_ADDR6(&matchmask) = cr->mask6;
+			SOCK_ADDR6(&matchaddr) = cr.addr6;
+			SOCK_ADDR6(&matchmask) = cr.mask6;
 		} else {
 			AF(&matchaddr) = AF_INET;
 			AF(&matchmask) = AF_INET;
-			NSRCADR(&matchaddr) = cr->addr;
-			NSRCADR(&matchmask) = cr->mask;
+			NSRCADR(&matchaddr) = cr.addr;
+			NSRCADR(&matchmask) = cr.mask;
 		}
-		hack_restrict(op, &matchaddr, &matchmask, cr->mflags,
-			 cr->flags);
-		cr++;
+		hack_restrict(op, &matchaddr, &matchmask, cr.mflags,
+			 cr.flags);
+		datap += item_sz;
 	}
 
 	req_ack(srcadr, inter, inpkt, INFO_OKAY);
@@ -1941,109 +1929,16 @@
  * mon_getlist - return monitor data
  */
 static void
-mon_getlist_0(
+mon_getlist(
 	sockaddr_u *srcadr,
 	struct interface *inter,
 	struct req_pkt *inpkt
 	)
 {
-	register struct info_monitor *im;
-	register struct mon_data *md;
-	extern struct mon_data mon_mru_list;
-	extern int mon_enabled;
-
-#ifdef DEBUG
-	if (debug > 2)
-	    printf("wants monitor 0 list\n");
-#endif
-	if (!mon_enabled) {
-		req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
-		return;
-	}
-	im = (struct info_monitor *)prepare_pkt(srcadr, inter, inpkt,
-	    v6sizeof(struct info_monitor));
-	for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
-	     md = md->mru_next) {
-		im->lasttime = htonl((u_int32)((current_time -
-		    md->firsttime) / md->count));
-		im->firsttime = htonl((u_int32)(current_time - md->lasttime));
-		im->restr = htonl((u_int32)md->flags);
-		im->count = htonl((u_int32)(md->count));
-		if (IS_IPV6(&md->rmtadr)) {
-			if (!client_v6_capable)
-				continue;
-			im->addr6 = SOCK_ADDR6(&md->rmtadr);
-			im->v6_flag = 1;
-		} else {
-			im->addr = NSRCADR(&md->rmtadr);
-			if (client_v6_capable)
-				im->v6_flag = 0;
-		}
-		im->port = md->rmtport;
-		im->mode = md->mode;
-		im->version = md->version;
-		im = (struct info_monitor *)more_pkt();
-	}
-	flush_pkt();
+	req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
 }
 
 /*
- * mon_getlist - return monitor data
- */
-static void
-mon_getlist_1(
-	sockaddr_u *srcadr,
-	struct interface *inter,
-	struct req_pkt *inpkt
-	)
-{
-	register struct info_monitor_1 *im;
-	register struct mon_data *md;
-	extern struct mon_data mon_mru_list;
-	extern int mon_enabled;
-
-	if (!mon_enabled) {
-		req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
-		return;
-	}
-	im = (struct info_monitor_1 *)prepare_pkt(srcadr, inter, inpkt,
-	    v6sizeof(struct info_monitor_1));
-	for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
-	     md = md->mru_next) {
-		im->lasttime = htonl((u_int32)((current_time -
-		    md->firsttime) / md->count));
-		im->firsttime = htonl((u_int32)(current_time - md->lasttime));
-		im->restr = htonl((u_int32)md->flags);
-		im->count = htonl((u_int32)md->count);
-		if (IS_IPV6(&md->rmtadr)) {
-			if (!client_v6_capable)
-				continue;
-			im->addr6 = SOCK_ADDR6(&md->rmtadr);
-			im->v6_flag = 1;
-			im->daddr6 = SOCK_ADDR6(&md->interface->sin);
-		} else {
-			im->addr = NSRCADR(&md->rmtadr);
-			if (client_v6_capable)
-				im->v6_flag = 0;
-			if (MDF_BCAST == md->cast_flags)
-				im->daddr = NSRCADR(&md->interface->bcast);
-			else if (md->cast_flags) {
-				im->daddr = NSRCADR(&md->interface->sin);
-				if (!im->daddr)
-					im->daddr = NSRCADR(&md->interface->bcast);
-			} else
-				im->daddr = 4;
-		}
-		im->flags = htonl(md->cast_flags);
-		im->port = md->rmtport;
-		im->mode = md->mode;
-		im->version = md->version;
-		im = (struct info_monitor_1 *)more_pkt();
-	}
-	flush_pkt();
-}
-
-/*
  * Module entry points and the flags they correspond with
  */
 struct reset_entry {
@@ -2110,8 +2005,10 @@
 	struct req_pkt *inpkt
 	)
 {
-	struct conf_unpeer *cp;
+	struct conf_unpeer cp;
 	int items;
+	size_t item_sz;
+	char * datap;
 	struct peer *peer;
 	sockaddr_u peeraddr;
 	int bad;
@@ -2122,17 +2019,24 @@
 	 */
 
 	items = INFO_NITEMS(inpkt->err_nitems);
-	cp = (struct conf_unpeer *)inpkt->data;
+	item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize);
+	datap = inpkt->data;  
+	if (item_sz > sizeof(cp)) {
+		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
+		return; 
+	}
 
 	bad = 0;
 	while (items-- > 0 && !bad) {
+		memset(&cp,0,sizeof(cp));
+		memcpy(&cp, datap, item_sz);
 		ZERO_SOCK(&peeraddr);
-		if (client_v6_capable && cp->v6_flag) {
+		if (client_v6_capable && cp.v6_flag) {
 			AF(&peeraddr) = AF_INET6;
-			SOCK_ADDR6(&peeraddr) = cp->peeraddr6;
+			SOCK_ADDR6(&peeraddr) = cp.peeraddr6;
 		} else {
 			AF(&peeraddr) = AF_INET;
-			NSRCADR(&peeraddr) = cp->peeraddr;
+			NSRCADR(&peeraddr) = cp.peeraddr;
 		}
 
 #ifdef ISC_PLATFORM_HAVESALEN
@@ -2141,8 +2045,7 @@
 		peer = findexistingpeer(&peeraddr, NULL, -1, 0);
 		if (NULL == peer)
 			bad++;
-		cp = (struct conf_unpeer *)((char *)cp +
-		    INFO_ITEMSIZE(inpkt->mbz_itemsize));
+		datap += item_sz;
 	}
 
 	if (bad) {
@@ -2154,16 +2057,17 @@
 	 * Now do it in earnest.
 	 */
 
-	items = INFO_NITEMS(inpkt->err_nitems);
-	cp = (struct conf_unpeer *)inpkt->data;
+	datap = inpkt->data;
 	while (items-- > 0) {
+		memset(&cp,0,sizeof(cp));
+		memcpy(&cp, datap, item_sz);
 		ZERO_SOCK(&peeraddr);
-		if (client_v6_capable && cp->v6_flag) {
+		if (client_v6_capable && cp.v6_flag) {
 			AF(&peeraddr) = AF_INET6;
-			SOCK_ADDR6(&peeraddr) = cp->peeraddr6;
+			SOCK_ADDR6(&peeraddr) = cp.peeraddr6;
 		} else {
 			AF(&peeraddr) = AF_INET;
-			NSRCADR(&peeraddr) = cp->peeraddr;
+			NSRCADR(&peeraddr) = cp.peeraddr;
 		}
 		SET_PORT(&peeraddr, 123);
 #ifdef ISC_PLATFORM_HAVESALEN
@@ -2174,8 +2078,7 @@
 			peer_reset(peer);
 			peer = findexistingpeer(&peeraddr, peer, -1, 0);
 		}
-		cp = (struct conf_unpeer *)((char *)cp +
-		    INFO_ITEMSIZE(inpkt->mbz_itemsize));
+		datap += item_sz;
 	}
 
 	req_ack(srcadr, inter, inpkt, INFO_OKAY);
@@ -2887,7 +2790,7 @@
 		ifs->unmask.addr = SOCK_ADDR4(&ep->mask);
 	}
 	ifs->v6_flag = htonl(ifs->v6_flag);
-	strncpy(ifs->name, ep->name, sizeof(ifs->name));
+	strlcpy(ifs->name, ep->name, sizeof(ifs->name));
 	ifs->family = htons(ep->family);
 	ifs->flags = htonl(ep->flags);
 	ifs->last_ttl = htonl(ep->last_ttl);