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

📄 ntp_io.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 5 页
字号:
		return (rb->recv_length);	}#ifdef DEBUG	if (debug > 2) {		if(rb->recv_srcadr.ss_family == AF_INET)			printf("input_handler: fd=%d length %d from %08lx %s\n",				fd, rb->recv_length,				(u_long)ntohl(((struct sockaddr_in*)&rb->recv_srcadr)->sin_addr.s_addr) &				0x00000000ffffffff,				stoa(&rb->recv_srcadr));		else			printf("input_handler: fd=%d length %d from %s\n",				fd, rb->recv_length,				stoa(&rb->recv_srcadr));	}#endif	/*	 * Got one.  Mark how and when it got here,	 * put it on the full list and do bookkeeping.	 */	rb->dstadr = itf;	rb->fd = fd;	rb->recv_time = ts;	rb->receiver = receive;	add_full_recv_buffer(rb);	itf->received++;	packets_received++;	return (rb->recv_length);}/* * input_handler - receive packets asynchronously */voidinput_handler(	l_fp *cts	){	int buflen;	register int i, n;	register int doing;	register SOCKET fd;	struct timeval tvzero;	l_fp ts;			/* Timestamp at BOselect() gob */#ifdef DEBUG	l_fp ts_e;			/* Timestamp at EOselect() gob */#endif	fd_set fds;	int select_count = 0;	handler_calls++;	/*	 * If we have something to do, freeze a timestamp.	 * See below for the other cases (nothing (left) to do or error)	 */	ts = *cts;	/*	 * Do a poll to see who has data	 */	fds = activefds;	tvzero.tv_sec = tvzero.tv_usec = 0;#ifdef REFCLOCK	/*	 * Check out the reference clocks first, if any	 */	n = select(maxactivefd+1, &fds, (fd_set *)0, (fd_set *)0, &tvzero);	/*	 * If there are no packets waiting just return	 */	if (n < 0)	{		int err = errno;		/*		 * extended FAU debugging output		 */		if (err != EINTR)		    netsyslog(LOG_ERR,			      "select(%d, %s, 0L, 0L, &0.0) error: %m",			      maxactivefd+1,			      fdbits(maxactivefd, &activefds));		if (err == EBADF) {			int j, b;			fds = activefds;			for (j = 0; j <= maxactivefd; j++)			    if ((FD_ISSET(j, &fds) && (read(j, &b, 0) == -1)))				netsyslog(LOG_ERR, "Bad file descriptor %d", j);		}		return;	}	else if (n == 0)		return;	++handler_pkts;	if (refio != 0)	{		register struct refclockio *rp;		for (rp = refio; rp != 0; rp = rp->next)		{			fd = rp->fd;			if (FD_ISSET(fd, &fds))			{				do {					++select_count;					buflen = read_refclock_packet(fd, rp, ts);				} while (buflen > 0);			} /* End if (FD_ISSET(fd, &fds)) */		} /* End for (rp = refio; rp != 0 && n > 0; rp = rp->next) */	} /* End if (refio != 0) */#endif /* REFCLOCK */	/*	 * Loop through the interfaces looking for data to read.	 */	for (i = ninterfaces - 1; (i >= 0) ; i--)	{		for (doing = 0; (doing < 2); doing++)		{			if (doing == 0)			{				fd = inter_list[i].fd;			}			else			{				if (!(inter_list[i].flags & INT_BCASTOPEN))				    break;				fd = inter_list[i].bfd;			}			if (fd < 0) continue;			if (FD_ISSET(fd, &fds))			{				do {					++select_count;					buflen = read_network_packet(fd, &inter_list[i], ts);				} while (buflen > 0);			}		/* Check more interfaces */		}	}	/*	 * Done everything from that select.	 */	/*	 * If nothing to do, just return.	 * If an error occurred, complain and return.	 */	if (select_count == 0) /* We really had nothing to do */	{#ifdef DEBUG		if (debug)		    netsyslog(LOG_DEBUG, "input_handler: select() returned 0");#endif		return;	}		/* We've done our work */#ifdef DEBUG	get_systime(&ts_e);	/*	 * (ts_e - ts) is the amount of time we spent	 * processing this gob of file descriptors.  Log	 * it.	 */	L_SUB(&ts_e, &ts);	if (debug > 3)	    netsyslog(LOG_INFO, "input_handler: Processed a gob of fd's in %s msec", lfptoms(&ts_e, 6));#endif	/* just bail. */	return;}#endif/* * findinterface - find local interface corresponding to address */struct interface *findinterface(	struct sockaddr_storage *addr	){	int retind;		retind = findlocalinterface(addr);#ifdef DEBUG	if (debug > 1)		printf("Found interface index %d for address %s\n",			retind, stoa(addr));#endif	if (retind < 0)	{		return (ANY_INTERFACE_CHOOSE(addr));	}	else	{		return (&inter_list[retind]);	}}/* * findlocalinterface - find local interface index corresponding to address */intfindlocalinterface(	struct sockaddr_storage *addr	){	SOCKET s;	int rtn, i, idx;	struct sockaddr_storage saddr;	int saddrlen = SOCKLEN(addr);#ifdef DEBUG	if (debug>2)	    printf("Finding interface for addr %s in list of addresses\n",		   stoa(addr));#endif	/*	 * This is considerably hoke. We open a socket, connect to it	 * and slap a getsockname() on it. If anything breaks, as it	 * probably will in some j-random knockoff, we just return the	 * wildcard interface.	 */	memset(&saddr, 0, sizeof(saddr));	saddr.ss_family = addr->ss_family;	if(addr->ss_family == AF_INET) {		memcpy(&((struct sockaddr_in*)&saddr)->sin_addr, &((struct sockaddr_in*)addr)->sin_addr, sizeof(struct in_addr));		((struct sockaddr_in*)&saddr)->sin_port = htons(2000);	}#ifdef INCLUDE_IPV6_SUPPORT	else if(addr->ss_family == AF_INET6) {		memcpy(&((struct sockaddr_in6*)&saddr)->sin6_addr, &((struct sockaddr_in6*)addr)->sin6_addr, sizeof(struct in6_addr));		((struct sockaddr_in6*)&saddr)->sin6_port = htons(2000);# ifdef ISC_PLATFORM_HAVESCOPEID		((struct sockaddr_in6*)&saddr)->sin6_scope_id = ((struct sockaddr_in6*)addr)->sin6_scope_id;# endif	}#endif	s = socket(addr->ss_family, SOCK_DGRAM, 0);	if (s == INVALID_SOCKET)		return (-1);	rtn = connect(s, (struct sockaddr *)&saddr, SOCKLEN(&saddr));#ifndef SYS_WINNT	if (rtn < 0)#else	if (rtn == SOCKET_ERROR)#endif	{		closesocket(s);		return (-1);	}	rtn = getsockname(s, (struct sockaddr *)&saddr, &saddrlen);	closesocket(s);#ifndef SYS_WINNT	if (rtn < 0)#else	if (rtn == SOCKET_ERROR)#endif		return (-1);	idx = -1;	for (i = nwilds; i < ninterfaces; i++) {		/* Don't both with ignore interfaces */		if (inter_list[i].ignore_packets == ISC_TRUE)			continue;		/*		 * First look if is the the correct family		 */		if(inter_list[i].sin.ss_family != saddr.ss_family)	  		continue;		/*		 * We match the unicast address only.		 */		if (SOCKCMP(&inter_list[i].sin, &saddr))		{			idx = i;			break;		}	}	if (idx != -1)	{		return (idx);	}	return (-1);}/* * findlocalcastinterface - find local *cast interface index corresponding to address * depending on the flags passed */intfindlocalcastinterface(	struct sockaddr_storage *addr, int flags	){	int i;	int nif = -1;#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT	isc_boolean_t want_linklocal = ISC_FALSE; 	if (addr_ismulticast(addr) && flags == INT_MULTICAST)	{		if (IN6_IS_ADDR_MC_LINKLOCAL(&((struct sockaddr_in6*)addr)->sin6_addr))		{			want_linklocal = ISC_TRUE;		}		else if (IN6_IS_ADDR_MC_SITELOCAL(&((struct sockaddr_in6*)addr)->sin6_addr))		{			want_linklocal = ISC_TRUE;		}	}#endif	for (i = nwilds; i < ninterfaces; i++) {		/* use only allowed addresses */		if (inter_list[i].ignore_packets == ISC_TRUE)			continue;		/* Skip the loopback addresses */		if (inter_list[i].flags & INT_LOOPBACK)			continue;		/* Skip if different family */		if(inter_list[i].sin.ss_family != addr->ss_family)			continue;		/* Is this it one of these based on flags? */		if (!(inter_list[i].flags & flags))			continue;		/* for IPv6 multicast check the address for linklocal */#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT		if (flags == INT_MULTICAST && inter_list[i].sin.ss_family == AF_INET6 &&		   (IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6*)&inter_list[i].sin)->sin6_addr))		   && want_linklocal == ISC_TRUE)		{			nif = i;			break;		}		/* If we want a linklocal address and this isn't it, skip */\		if (want_linklocal == ISC_TRUE)			continue;#endif		/* Otherwise just look for the flag */		if((inter_list[i].flags & flags))		{			nif = i;			break;		}	}#ifdef DEBUG	if (debug > 1)		printf("findlocalcastinterface: found index = %d\n", nif);#endif	return (nif);}/* * findbcastinter - find broadcast interface corresponding to address */struct interface *findbcastinter(	struct sockaddr_storage *addr	){#if !defined(MPE) && (defined(SIOCGIFCONF) || defined(SYS_WINNT))	int i = -1;	#ifdef DEBUG	if (debug>2)	    printf("Finding broadcast interface for addr %s in list of addresses\n",		   stoa(addr));#endif	i = find_flagged_addr_in_list(addr, INT_BCASTOPEN|INT_MCASTOPEN);#ifdef DEBUG	if (debug > 1)		printf("Found bcastinter index %d\n", i);#endif		/*		 * Do nothing right now		 * Eventually we will find the interface this		 * way, but until it works properly we just see		 * which one we got		 *//*	if(i >= 0)	{		return (&inter_list[i]);	}*/	for (i = nwilds; i < ninterfaces; i++) {		/* Don't bother with ignored interfaces */		if (inter_list[i].ignore_packets == ISC_TRUE)			continue;		/*		 * First look if this is the correct family		 */		if(inter_list[i].sin.ss_family != addr->ss_family)	  		continue;		/* Skip the loopback addresses */		if (inter_list[i].flags & INT_LOOPBACK)			continue;		/* for IPv6 multicast check the address for linklocal */#ifdef INCLUDE_IPV6_SUPPORT		if (inter_list[i].sin.ss_family == AF_INET6 &&		   (IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6*)&inter_list[i].sin)->sin6_addr)))		{/*			continue; */		}#endif		/*		 * If we are looking to match a multicast address grab it.		 * We must not do this before we have eliminated any linklocal		 * addresses		 */		if (addr_ismulticast(addr) == ISC_TRUE && inter_list[i].flags & INT_MULTICAST)		{			return (&inter_list[i]);		}		/*		 * We match only those interfaces marked as		 * broadcastable and either the explicit broadcast		 * address or the network portion of the IP address.		 * Sloppy.		 */		if(addr->ss_family == AF_INET) {			if (SOCKCMP(&inter_list[i].bcast, addr))				return (&inter_list[i]);			if ((NSRCADR(&inter_list[i].sin) &				NSRCADR(&inter_list[i].mask)) == (NSRCADR(addr) &			    	NSRCADR(&inter_list[i].mask)))				return (&inter_list[i]);		}#ifdef INCLUDE_IPV6_SUPPORT		else if(addr->ss_family == AF_INET6) {			if (SOCKCMP(&inter_list[i].bcast, addr))				return (&inter_list[i]);			if (SOCKCMP(netof(&inter_list[i].sin), netof(addr)))				return (&inter_list[i]);		}#endif	}#endif /* SIOCGIFCONF */ 	return ANY_INTERFACE_CHOOSE(addr);}/* * io_clr_stats - clear I/O module statistics */voidio_clr_stats(void){	packets_dropped = 0;	packets_ignored = 0;	packets_received = 0;	packets_sent = 0;	packets_notsent = 0;	handler_calls = 0;	handler_pkts = 0;	io_timereset = current_time;}#ifdef REFCLOCK/* * This is a hack so that I don't have to fool with these ioctls in the * pps driver ... we are already non-blocking and turn on SIGIO thru * another mechanisim */intio_addclock_simple(	struct refclockio *rio	){	BLOCKIO();	/*	 * Stuff the I/O structure in the list and mark the descriptor	 * in use.	There is a harmless (I hope) race condition here.	 */	rio->next = refio;	refio = rio;	/*	 * I/O Completion Ports don't care about select and fd_set	 */#ifndef HAVE_IO_COMPLETION_PORT	if (rio->fd > maxactivefd)	    maxactivefd = rio->fd;	FD_SET(rio->fd, &activefds);#endif	UNBLOCKIO();	return 1;}/* * io_addclock - add a reference clock to the list and arrange that we *				 get SIGIO interrupts from it. */intio_addclock(	struc

⌨️ 快捷键说明

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