⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntp_request.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);		return;	}	if ((proc->sizeofitem != 0) &&	    ((temp_size * INFO_NITEMS(inpkt->err_nitems)) >	    (rbufp->recv_length - REQ_LEN_HDR))) {#ifdef DEBUG		if (debug > 2)			printf("process_private: not enough data\n");#endif		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);		return;	}	switch (inpkt->implementation) {	case IMPL_XNTPD:		client_v6_capable = 1;		break;	case IMPL_XNTPD_OLD:		client_v6_capable = 0;		break;	default:		req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);		return;	}	/*	 * If we need to authenticate, do so.  Note that an	 * authenticatable packet must include a mac field, must	 * have used key info_auth_keyid and must have included	 * a time stamp in the appropriate field.  The time stamp	 * must be within INFO_TS_MAXSKEW of the receive	 * time stamp.	 */	if (proc->needs_auth && sys_authenticate) {		l_fp ftmp;		double dtemp;			if (rbufp->recv_length < (int)((REQ_LEN_HDR +		    (INFO_ITEMSIZE(inpkt->mbz_itemsize) *		    INFO_NITEMS(inpkt->err_nitems))		    + sizeof(struct req_pkt_tail)))) {			req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);		}		tailinpkt = (struct req_pkt_tail *)((char *)&rbufp->recv_pkt +		    rbufp->recv_length - sizeof(struct req_pkt_tail));		/*		 * If this guy is restricted from doing this, don't let him		 * If wrong key was used, or packet doesn't have mac, return.		 */		if (!INFO_IS_AUTH(inpkt->auth_seq) || info_auth_keyid == 0		    || ntohl(tailinpkt->keyid) != info_auth_keyid) {#ifdef DEBUG			if (debug > 4)			    printf("failed auth %d info_auth_keyid %lu pkt keyid %lu\n",				   INFO_IS_AUTH(inpkt->auth_seq),				   (u_long)info_auth_keyid,				   (u_long)ntohl(tailinpkt->keyid));			msyslog(LOG_DEBUG,				"process_private: failed auth %d info_auth_keyid %lu pkt keyid %lu\n",				INFO_IS_AUTH(inpkt->auth_seq),				(u_long)info_auth_keyid,				(u_long)ntohl(tailinpkt->keyid));#endif			req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);			return;		}		if (rbufp->recv_length > REQ_LEN_MAC) {#ifdef DEBUG			if (debug > 4)			    printf("bad pkt length %d\n",				   rbufp->recv_length);#endif			msyslog(LOG_ERR, "process_private: bad pkt length %d",				rbufp->recv_length);			req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);			return;		}		if (!mod_okay || !authhavekey(info_auth_keyid)) {#ifdef DEBUG			if (debug > 4)			    printf("failed auth mod_okay %d\n", mod_okay);			msyslog(LOG_DEBUG,				"process_private: failed auth mod_okay %d\n",				mod_okay);#endif			req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);			return;		}		/*		 * calculate absolute time difference between xmit time stamp		 * and receive time stamp.  If too large, too bad.		 */		NTOHL_FP(&tailinpkt->tstamp, &ftmp);		L_SUB(&ftmp, &rbufp->recv_time);		LFPTOD(&ftmp, dtemp);		if (fabs(dtemp) >= INFO_TS_MAXSKEW) {			/*			 * He's a loser.  Tell him.			 */#ifdef DEBUG			if (debug > 4)			    printf("xmit/rcv timestamp delta > INFO_TS_MAXSKEW\n");#endif			req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);			return;		}		/*		 * So far so good.  See if decryption works out okay.		 */		if (!authdecrypt(info_auth_keyid, (u_int32 *)inpkt,		    rbufp->recv_length - sizeof(struct req_pkt_tail) +		    REQ_LEN_HDR, sizeof(struct req_pkt_tail) - REQ_LEN_HDR)) {#ifdef DEBUG			if (debug > 4)			    printf("authdecrypt failed\n");#endif			req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);			return;		}	}#ifdef DEBUG	if (debug > 3)	    printf("process_private: all okay, into handler\n");#endif	/*	 * Packet is okay.  Call the handler to send him data.	 */	(proc->handler)(srcadr, inter, inpkt);}/* * peer_list - send a list of the peers */static voidpeer_list(	struct sockaddr_storage *srcadr,	struct interface *inter,	struct req_pkt *inpkt	){	register struct info_peer_list *ip;	register struct peer *pp;	register int i;	register int skip = 0;	ip = (struct info_peer_list *)prepare_pkt(srcadr, inter, inpkt,	    v6sizeof(struct info_peer_list));	for (i = 0; i < NTP_HASH_SIZE && ip != 0; i++) {		pp = peer_hash[i];		while (pp != 0 && ip != 0) {			if (pp->srcadr.ss_family == AF_INET6) {				if (client_v6_capable) {					ip->addr6 = GET_INADDR6(pp->srcadr);					ip->v6_flag = 1;					skip = 0;				} else {					skip = 1;					break;				}			} else {				ip->addr = GET_INADDR(pp->srcadr);				if (client_v6_capable)					ip->v6_flag = 0;				skip = 0;			}			if(!skip) {				ip->port = NSRCPORT(&pp->srcadr);				ip->hmode = pp->hmode;				ip->flags = 0;				if (pp->flags & FLAG_CONFIG)				    ip->flags |= INFO_FLAG_CONFIG;				if (pp == sys_peer)				    ip->flags |= INFO_FLAG_SYSPEER;				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 = (struct info_peer_list *)more_pkt();			}			pp = pp->next; 		}	}	flush_pkt();}/* * peer_list_sum - return extended peer list */static voidpeer_list_sum(	struct sockaddr_storage *srcadr,	struct interface *inter,	struct req_pkt *inpkt	){	register struct info_peer_summary *ips;	register struct peer *pp;	register int i;	l_fp ltmp;	register int skip;#ifdef DEBUG	if (debug > 2)	    printf("wants peer list summary\n");#endif	ips = (struct info_peer_summary *)prepare_pkt(srcadr, inter, inpkt,	    v6sizeof(struct info_peer_summary));	for (i = 0; i < NTP_HASH_SIZE && ips != 0; i++) {		pp = peer_hash[i];		while (pp != 0 && ips != 0) {#ifdef DEBUG			if (debug > 3)			    printf("sum: got one\n");#endif			/*			 * Be careful here not to return v6 peers when we			 * want only v4.			 */			if (pp->srcadr.ss_family == AF_INET6) {				if (client_v6_capable) {					ips->srcadr6 = GET_INADDR6(pp->srcadr);					ips->v6_flag = 1;					ips->dstadr6 = GET_INADDR6(pp->dstadr->sin);					skip = 0;				} else {					skip = 1;					break;				}			} else {				ips->srcadr = GET_INADDR(pp->srcadr);				if (client_v6_capable)					ips->v6_flag = 0;/* XXX PDM This code is buggy. Need to replace with a straightforward assignment */				ips->dstadr = (pp->processed) ?					pp->cast_flags == MDF_BCAST ?					GET_INADDR(pp->dstadr->bcast):					pp->cast_flags ?					GET_INADDR(pp->dstadr->sin) ?					GET_INADDR(pp->dstadr->sin):					GET_INADDR(pp->dstadr->bcast):					1 : GET_INADDR(pp->dstadr->sin);				skip = 0;			}			if (!skip){ 				ips->srcport = NSRCPORT(&pp->srcadr);				ips->stratum = pp->stratum;				ips->hpoll = pp->hpoll;				ips->ppoll = pp->ppoll;				ips->reach = pp->reach;				ips->flags = 0;				if (pp == sys_peer)				    ips->flags |= INFO_FLAG_SYSPEER;				if (pp->flags & FLAG_CONFIG)				    ips->flags |= INFO_FLAG_CONFIG;				if (pp->flags & FLAG_REFCLOCK)				    ips->flags |= INFO_FLAG_REFCLOCK;				if (pp->flags & FLAG_AUTHENABLE)				    ips->flags |= INFO_FLAG_AUTHENABLE;				if (pp->flags & FLAG_PREFER)				    ips->flags |= INFO_FLAG_PREFER;				if (pp->flags & FLAG_BURST)				    ips->flags |= INFO_FLAG_BURST;				if (pp->status == CTL_PST_SEL_SYNCCAND)				    ips->flags |= INFO_FLAG_SEL_CANDIDATE;				if (pp->status >= CTL_PST_SEL_SYSPEER)				    ips->flags |= INFO_FLAG_SHORTLIST;				ips->hmode = pp->hmode;				ips->delay = HTONS_FP(DTOFP(pp->delay));				DTOLFP(pp->offset, &ltmp);				HTONL_FP(&ltmp, &ips->offset);				ips->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp)));			}				pp = pp->next; 			ips = (struct info_peer_summary *)more_pkt();		}	}	flush_pkt();}/* * peer_info - send information for one or more peers */static voidpeer_info (	struct sockaddr_storage *srcadr,	struct interface *inter,	struct req_pkt *inpkt	){	register struct info_peer_list *ipl;	register struct peer *pp;	register struct info_peer *ip;	register int items;	register int i, j;	struct sockaddr_storage addr;	extern struct peer *sys_peer;	l_fp ltmp;	memset((char *)&addr, 0, sizeof addr);	items = INFO_NITEMS(inpkt->err_nitems);	ipl = (struct info_peer_list *) inpkt->data;	ip = (struct info_peer *)prepare_pkt(srcadr, inter, inpkt,	    v6sizeof(struct info_peer));	while (items-- > 0 && ip != 0) {		memset((char *)&addr, 0, sizeof(addr));		NSRCPORT(&addr) = ipl->port;		if (client_v6_capable && ipl->v6_flag != 0) {			addr.ss_family = AF_INET6;			GET_INADDR6(addr) = ipl->addr6;		} else {			addr.ss_family = AF_INET;			GET_INADDR(addr) = ipl->addr;		}#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR		addr.ss_len = SOCKLEN(&addr);#endif		ipl++;		if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0)		    continue;		if (pp->srcadr.ss_family == AF_INET6) {			ip->dstadr6 = pp->cast_flags == MDF_BCAST ?				GET_INADDR6(pp->dstadr->bcast) :				GET_INADDR6(pp->dstadr->sin);			ip->srcadr6 = GET_INADDR6(pp->srcadr);			ip->v6_flag = 1;		} else {/* XXX PDM This code is buggy. Need to replace with a straightforward assignment */			ip->dstadr = (pp->processed) ?				pp->cast_flags == MDF_BCAST ?				GET_INADDR(pp->dstadr->bcast):				pp->cast_flags ?				GET_INADDR(pp->dstadr->sin) ?				GET_INADDR(pp->dstadr->sin):				GET_INADDR(pp->dstadr->bcast):				2 : GET_INADDR(pp->dstadr->sin);			ip->srcadr = GET_INADDR(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_AUTHENABLE)		    ip->flags |= INFO_FLAG_AUTHENABLE;		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->estbdelay));		ip->ttl = pp->ttl;		ip->associd = htons(pp->associd);		ip->rootdelay = HTONS_FP(DTOUFP(pp->rootdelay));		ip->rootdispersion = HTONS_FP(DTOUFP(pp->rootdispersion));		ip->refid = pp->refid;		HTONL_FP(&pp->reftime, &ip->reftime);		HTONL_FP(&pp->org, &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 = (struct info_peer *)more_pkt();	}	flush_pkt();}/* * peer_stats - send statistics for one or more peers */static voidpeer_stats (	struct sockaddr_storage *srcadr,	struct interface *inter,	struct req_pkt *inpkt	){	register struct info_peer_list *ipl;	register struct peer *pp;	register struct info_peer_stats *ip;	register int items;	struct sockaddr_storage addr;	extern struct peer *sys_peer;#ifdef DEBUG	if (debug)	     printf("peer_stats: called\n");#endif	items = INFO_NITEMS(inpkt->err_nitems);	ipl = (struct info_peer_list *) inpkt->data;	ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt,	    v6sizeof(struct info_peer_stats));	while (items-- > 0 && ip != 0) {		memset((char *)&addr, 0, sizeof(addr));		NSRCPORT(&addr) = ipl->port;		if (client_v6_capable && ipl->v6_flag) {			addr.ss_family = AF_INET6;			GET_INADDR6(addr) = ipl->addr6;		} else {			addr.ss_family = AF_INET;			GET_INADDR(addr) = ipl->addr;		}	#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR		addr.ss_len = SOCKLEN(&addr);#endif#ifdef DEBUG		if (debug)		    printf("peer_stats: looking for %s, %d, %d\n", stoa(&addr),		    ipl->port, ((struct sockaddr_in6 *)&addr)->sin6_port);#endif		ipl = (struct info_peer_list *)((char *)ipl +		    INFO_ITEMSIZE(inpkt->mbz_itemsize));		if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0)		    continue;#ifdef DEBUG		if (debug)		     printf("peer_stats: found %s\n", stoa(&addr));#endif		if (pp->srcadr.ss_family == AF_INET) {			ip->dstadr = (pp->processed) ?				pp->cast_flags == MDF_BCAST ?				GET_INADDR(pp->dstadr->bcast):				pp->cast_flags ?				GET_INADDR(pp->dstadr->sin) ?				GET_INADDR(pp->dstadr->sin):				GET_INADDR(pp->dstadr->bcast):				3 : 7;			ip->srcadr = GET_INADDR(pp->srcadr);			if (client_v6_capable)				ip->v6_flag = 0;		} else {			ip->dstadr6 = pp->cast_flags == MDF_BCAST ?				GET_INADDR6(pp->dstadr->bcast):				GET_INADDR6(pp->dstadr->sin);			ip->srcadr6 = GET_INADDR6(pp->srcadr);			ip->v6_flag = 1;		}			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_AUTHENABLE)		    ip->flags |= INFO_FLAG_AUTHENABLE;		if (pp->flags & FLAG_PREFER)		    ip->flags |= INFO_FLAG_PREFER;		if (pp->flags & FLAG_BURST)		    ip->flags |= INFO_FLAG_BURST;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -