peer_info (
	sockaddr_u *srcadr,
	endpt *inter,
	struct req_pkt *inpkt
	)
{
	u_short			items;
	size_t			item_sz;
	char *			datap;
	struct info_peer_list	ipl;
	struct peer *		pp;
	struct info_peer *	ip;
	int			i;
	int			j;
	sockaddr_u		addr;
	l_fp			ltmp;

	items = INFO_NITEMS(inpkt->err_nitems);
	item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize);
	datap = inpkt->u.data;
	if (item_sz != sizeof(ipl)) {
		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
		return;
	}
	ip = prepare_pkt(srcadr, inter, inpkt,
			 v6sizeof(struct info_peer));
	while (items-- > 0 && ip != NULL) {
		ZERO(ipl);
		memcpy(&ipl, datap, item_sz);
		ZERO_SOCK(&addr);
		NSRCPORT(&addr) = ipl.port;
		if (client_v6_capable && ipl.v6_flag) {
			AF(&addr) = AF_INET6;
			SOCK_ADDR6(&addr) = ipl.addr6;
		} else {
			AF(&addr) = AF_INET;
			NSRCADR(&addr) = ipl.addr;
		}
#ifdef ISC_PLATFORM_HAVESALEN
		addr.sa.sa_len = SOCKLEN(&addr);
#endif
		datap += item_sz;

		pp = findexistingpeer(&addr, NULL, NULL, -1, 0);
		if (NULL == pp)
			continue;
		if (IS_IPV6(srcadr)) {
			if (pp->dstadr)
				ip->dstadr6 =
				    (MDF_BCAST == pp->cast_flags)
					? SOCK_ADDR6(&pp->dstadr->bcast)
					: SOCK_ADDR6(&pp->dstadr->sin);
			else
				ZERO(ip->dstadr6);

			ip->srcadr6 = SOCK_ADDR6(&pp->srcadr);
			ip->v6_flag = 1;
		} else {
			if (pp->dstadr) {
				if (!pp->processed)
					ip->dstadr = NSRCADR(&pp->dstadr->sin);
				else {
					if (MDF_BCAST == pp->cast_flags)
						ip->dstadr = NSRCADR(&pp->dstadr->bcast);
					else if (pp->cast_flags) {
						ip->dstadr = NSRCADR(&pp->dstadr->sin);
						if (!ip->dstadr)
							ip->dstadr = NSRCADR(&pp->dstadr->bcast);
					}
				}
			} else
				ip->dstadr = 0;

			ip->srcadr = NSRCADR(&pp->srcadr);
			if (client_v6_capable)
				ip->v6_flag = 0;
		}
		ip->srcport = NSRCPORT(&pp->srcadr);
		ip->flags = 0;
		if (pp == sys_peer)
			ip->flags |= INFO_FLAG_SYSPEER;
		if (pp->flags & FLAG_CONFIG)
			ip->flags |= INFO_FLAG_CONFIG;
		if (pp->flags & FLAG_REFCLOCK)
			ip->flags |= INFO_FLAG_REFCLOCK;
		if (pp->flags & FLAG_PREFER)
			ip->flags |= INFO_FLAG_PREFER;
		if (pp->flags & FLAG_BURST)
			ip->flags |= INFO_FLAG_BURST;
		if (pp->status == CTL_PST_SEL_SYNCCAND)
			ip->flags |= INFO_FLAG_SEL_CANDIDATE;
		if (pp->status >= CTL_PST_SEL_SYSPEER)
			ip->flags |= INFO_FLAG_SHORTLIST;
		ip->leap = pp->leap;
		ip->hmode = pp->hmode;
		ip->keyid = pp->keyid;
		ip->stratum = pp->stratum;
		ip->ppoll = pp->ppoll;
		ip->hpoll = pp->hpoll;
		ip->precision = pp->precision;
		ip->version = pp->version;
		ip->reach = pp->reach;
		ip->unreach = (u_char)pp->unreach;
		ip->flash = (u_char)pp->flash;
		ip->flash2 = (u_short)pp->flash;
		ip->estbdelay = HTONS_FP(DTOFP(pp->delay));
		ip->ttl = (u_char)pp->ttl;
		ip->associd = htons(pp->associd);
		ip->rootdelay = HTONS_FP(DTOUFP(pp->rootdelay));
		ip->rootdispersion = HTONS_FP(DTOUFP(pp->rootdisp));
		ip->refid = pp->refid;
		HTONL_FP(&pp->reftime, &ip->reftime);
		HTONL_FP(&pp->aorg, &ip->org);
		HTONL_FP(&pp->rec, &ip->rec);
		HTONL_FP(&pp->xmt, &ip->xmt);
		j = pp->filter_nextpt - 1;
		for (i = 0; i < NTP_SHIFT; i++, j--) {
			if (j < 0)
				j = NTP_SHIFT-1;
			ip->filtdelay[i] = HTONS_FP(DTOFP(pp->filter_delay[j]));
			DTOLFP(pp->filter_offset[j], &ltmp);
			HTONL_FP(&ltmp, &ip->filtoffset[i]);
			ip->order[i] = (u_char)((pp->filter_nextpt +
						 NTP_SHIFT - 1) -
						pp->filter_order[i]);
			if (ip->order[i] >= NTP_SHIFT)
				ip->order[i] -= NTP_SHIFT;
		}
		DTOLFP(pp->offset, &ltmp);
		HTONL_FP(&ltmp, &ip->offset);
		ip->delay = HTONS_FP(DTOFP(pp->delay));
		ip->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp)));
		ip->selectdisp = HTONS_FP(DTOUFP(SQRT(pp->jitter)));
		ip = more_pkt();
	}
	flush_pkt();
}