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

📄 ntp_io.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 5 页
字号:
		       sizeof(struct in6_addr));		((struct sockaddr_in6 *)&itf->sin)->sin6_port = port;#ifdef ISC_PLATFORM_HAVESCOPEID		((struct sockaddr_in6 *)&itf->sin)->sin6_scope_id = isc_netaddr_getzone(&isc_if->address);		itf->scopeid = isc_netaddr_getzone(&isc_if->address);#endif		itf->mask.ss_family = itf->sin.ss_family;		memcpy(&(((struct sockaddr_in6 *)&itf->mask)->sin6_addr),		       &(isc_if->netmask.type.in6),		       sizeof(struct in6_addr));		((struct sockaddr_in6 *)&itf->mask)->sin6_port = port;		if (((isc_if->flags & INTERFACE_F_LOOPBACK) != 0) && (loopback6_interface == NULL))		{			loopback6_interface = itf;		}		/* Copy the scopeid and the interface index */		itf->ifindex = isc_if->ifindex;	}#endif /* INCLUDE_IPV6_SUPPORT */		/* Process the rest of the flags */	if((isc_if->flags & INTERFACE_F_UP) != 0)		itf->flags |= INT_UP;	if((isc_if->flags & INTERFACE_F_LOOPBACK) != 0)		itf->flags |= INT_LOOPBACK;	if((isc_if->flags & INTERFACE_F_POINTTOPOINT) != 0)		itf->flags |= INT_PPP;	if((isc_if->flags & INTERFACE_F_MULTICAST) != 0)		itf->flags |= INT_MULTICAST;}/* * create_sockets - create a socket for each interface plus a default *			socket for when we don't know where to send */static intcreate_sockets(	u_short port	){	struct sockaddr_storage resmask;	int i;	isc_mem_t *mctx = NULL;	isc_interfaceiter_t *iter = NULL;	isc_boolean_t scan_ipv4 = ISC_FALSE;	isc_boolean_t scan_ipv6 = ISC_FALSE;	isc_result_t result;	int idx = 0;#ifndef HAVE_IO_COMPLETION_PORT	/*	 * I/O Completion Ports don't care about the select and FD_SET	 */	maxactivefd = 0;	FD_ZERO(&activefds);#endif#ifdef DEBUG	if (debug)	    printf("create_sockets(%d)\n", ntohs( (u_short) port));#endif#ifdef INCLUDE_IPV6_SUPPORT	if (isc_net_probeipv6() == ISC_R_SUCCESS)		scan_ipv6 = ISC_TRUE;#if defined(DEBUG)	else		if(debug)			netsyslog(LOG_ERR, "no IPv6 interfaces found");#endif#endif	if (isc_net_probeipv4() == ISC_R_SUCCESS)		scan_ipv4 = ISC_TRUE;#ifdef DEBUG	else		if(debug)			netsyslog(LOG_ERR, "no IPv4 interfaces found");#endif	/*	 * Create wildcard addresses	 * This ensures that no other application	 * can be receiving ntp packets 	 */	nwilds = create_wildcards(port);	idx = nwilds;	result = isc_interfaceiter_create(mctx, &iter);	if (result != ISC_R_SUCCESS)		return (result);	for (result = isc_interfaceiter_first(iter);	     result == ISC_R_SUCCESS;	     result = isc_interfaceiter_next(iter))	{		isc_interface_t isc_if;		unsigned int family; 		result = isc_interfaceiter_current(iter, &isc_if);		if (result != ISC_R_SUCCESS)			break;		/* See if we have a valid family to use */		family = isc_if.address.family;		if (family != AF_INET && family != AF_INET6)			continue;		if (scan_ipv4 == ISC_FALSE && family == AF_INET)			continue;		if (scan_ipv6 == ISC_FALSE && family == AF_INET6)			continue;		/* 		 * Check to see if we are going to use the interface		 * If we don't use it we mark it to drop any packet		 * received but we still must create the socket and		 * bind to it. This prevents other apps binding to it		 * and potentially causing problems with more than one		 * process fiddling with the clock		 */		if (address_okay(&isc_if) == ISC_TRUE) {			inter_list[idx].ignore_packets = ISC_FALSE;		}		else {			inter_list[idx].ignore_packets = ISC_TRUE;		}		convert_isc_if(&isc_if, &inter_list[idx], port);		inter_list[idx].fd = INVALID_SOCKET;		inter_list[idx].bfd = INVALID_SOCKET;		inter_list[idx].num_mcast = 0;		inter_list[idx].received = 0;		inter_list[idx].sent = 0;		inter_list[idx].notsent = 0;		idx++;	}	isc_interfaceiter_destroy(&iter);	ninterfaces = idx;	/*	 * Create the sockets	 */	for (i = 0; i < ninterfaces; i++) {		inter_list[i].fd = open_socket(&inter_list[i].sin,		    inter_list[i].flags, 0, &inter_list[i], i);		if (inter_list[i].fd != INVALID_SOCKET)			msyslog(LOG_INFO, "Listening on interface %s, %s#%d %s",				inter_list[i].name,				stoa((&inter_list[i].sin)),				NTP_PORT,				(inter_list[i].ignore_packets == ISC_FALSE) ?				"Enabled": "Disabled");	/*	 * Calculate the address hash for each interface address.	 */		inter_list[i].addr_refid = addr2refid(&inter_list[i].sin);	}	/*	 * Now that we have opened all the sockets, turn off the reuse	 * flag for security.	 */	set_reuseaddr(0);	/*	 * Blacklist all bound interface addresses	 * Wildcard interfaces, if any, are ignored.	 */	for (i = nwilds; i < ninterfaces; i++) {		SET_HOSTMASK(&resmask, inter_list[i].sin.ss_family);		hack_restrict(RESTRICT_FLAGS, &inter_list[i].sin, &resmask,		    RESM_NTPONLY|RESM_INTERFACE, RES_IGNORE);	}#ifdef DEBUG	if (debug > 1) {		printf("create_sockets: Total interfaces = %d\n", ninterfaces);		for (i = 0; i < ninterfaces; i++) {			print_interface(i);		}	}#endif	return ninterfaces;}/* * set_reuseaddr() - set/clear REUSEADDR on all sockets *			NB possible hole - should we be doing this on broadcast *			fd's also? */static voidset_reuseaddr(int flag) {	int i;	for (i=0; i < ninterfaces; i++) {		/*		 * if inter_list[ n ].fd  is -1, we might have a adapter		 * configured but not present		 */		if (inter_list[i].fd != INVALID_SOCKET) {			if (setsockopt(inter_list[i].fd, SOL_SOCKET,					SO_REUSEADDR, (char *)&flag,					sizeof(flag))) {				netsyslog(LOG_ERR, "set_reuseaddr: setsockopt(SO_REUSEADDR, %s) failed: %m", flag ? "on" : "off");			}		}	}}/* * This is just a wrapper around an internal function so we can * make other changes as necessary later on */voidenable_broadcast(struct interface *iface, struct sockaddr_storage *baddr){#ifdef SO_BROADCAST	socket_broadcast_enable(iface, iface->fd, baddr);#endif}#ifdef OPEN_BCAST_SOCKET /* * Enable a broadcast address to a given socket * The socket is in the inter_list all we need to do is enable * broadcasting. It is not this function's job to select the socket */static isc_boolean_tsocket_broadcast_enable(struct interface *iface, SOCKET fd, struct sockaddr_storage *maddr){#ifdef SO_BROADCAST	int on = 1;	if (maddr->ss_family == AF_INET)	{		/* if this interface can support broadcast, set SO_BROADCAST */		if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,			       (char *)&on, sizeof(on)))		{			netsyslog(LOG_ERR, "setsockopt(SO_BROADCAST) enable failure on address %s: %m",				stoa(maddr));		}#ifdef DEBUG		else if (debug > 1) {			printf("Broadcast enabled on socket %d for address %s\n",				fd, stoa(maddr));		}#endif	}	iface->flags |= INT_BCASTOPEN;	modify_addr_in_list(maddr, iface->flags);	return ISC_TRUE;#else	return ISC_FALSE;#endif /* SO_BROADCAST */}/* * Remove a broadcast address from a given socket * The socket is in the inter_list all we need to do is disable * broadcasting. It is not this function's job to select the socket */static isc_boolean_tsocket_broadcast_disable(struct interface *iface, int ind, struct sockaddr_storage *maddr){#ifdef SO_BROADCAST	int off = 0;	if (maddr->ss_family == AF_INET)	{		if (setsockopt(iface->fd, SOL_SOCKET, SO_BROADCAST,			       (char *)&off, sizeof(off)))		{			netsyslog(LOG_ERR, "setsockopt(SO_BROADCAST) disable failure on address %s: %m",				stoa(maddr));		}	}	iface->flags &= ~INT_BCASTOPEN;	modify_addr_in_list(maddr, iface->flags);	return ISC_TRUE;#else	return ISC_FALSE;#endif /* SO_BROADCAST */}#endif /* OPEN_BCAST_SOCKET *//* * Check to see if the address is a multicast address */static isc_boolean_taddr_ismulticast(struct sockaddr_storage *maddr){	switch (maddr->ss_family)	{	case AF_INET :		if (!IN_CLASSD(ntohl(((struct sockaddr_in*)maddr)->sin_addr.s_addr))) {#ifdef DEBUG			if (debug > 1)				printf("multicast address %s not class D\n",				stoa(maddr));#endif			return (ISC_FALSE);		}		else		{			return (ISC_TRUE);		}	case AF_INET6 :#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT		if (!IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)maddr)->sin6_addr)) {#ifdef DEBUG			if (debug > 1)				printf("address %s not IPv6 multicast address\n",				stoa(maddr));#endif			return (ISC_FALSE);		}		else		{			return (ISC_TRUE);		}/* * If we don't have IPV6 support any IPV6 address is not multicast */#else		return (ISC_FALSE);#endif	/*	 * Never valid	 */	default:		return (ISC_FALSE);	}}/* * Multicast servers need to set the appropriate Multicast interface * socket option in order for it to know which interface to use for * send the multicast packet. */voidenable_multicast_if(struct interface *iface, struct sockaddr_storage *maddr){#ifdef MCAST	switch (maddr->ss_family)	{	case AF_INET:		if (setsockopt(iface->fd, IPPROTO_IP, IP_MULTICAST_IF,		   (char *)&(((struct sockaddr_in*)&iface->sin)->sin_addr.s_addr),		    sizeof(struct sockaddr_in*)) == -1) {			netsyslog(LOG_ERR,			"setsockopt IP_MULTICAST_IF failure: %m on socket %d, addr %s for multicast address %s",			iface->fd, stoa(&iface->sin), stoa(maddr));			return;		}#ifdef DEBUG		if (debug > 0) {			printf(			"Added IPv4 multicast interface on socket %d, addr %s for multicast address %s\n",			iface->fd, stoa(&iface->sin),			stoa(maddr));		}#endif		break;	case AF_INET6:#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT		if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,		    &iface->scopeid, sizeof(iface->scopeid)) == -1) {			netsyslog(LOG_ERR,			"setsockopt IPV6_MULTICAST_IF failure: %m on socket %d, addr %s, scope %d for multicast address %s",			iface->fd, stoa(&iface->sin), iface->scopeid,			stoa(maddr));			return;		}#ifdef DEBUG		if (debug > 0) {			printf(			"Added IPv6 multicast interface on socket %d, addr %s, scope %d for multicast address %s\n",			iface->fd,  stoa(&iface->sin), iface->scopeid,			stoa(maddr));		}#endif		break;#else		return;#endif	/* INCLUDE_IPV6_MULTICAST_SUPPORT */	}	return;#endif}/* * NOTE: Not all platforms support multicast */#ifdef MCAST/* * Add a multicast address to a given socket * The socket is in the inter_list all we need to do is enable * multicasting. It is not this function's job to select the socket */static isc_boolean_tsocket_multicast_enable(struct interface *iface, int ind, int lscope, struct sockaddr_storage *maddr){#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT	struct ipv6_mreq mreq6;	struct in6_addr iaddr6;#endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */	struct ip_mreq mreq;	switch (maddr->ss_family)	{	case AF_INET:		memset((char *)&mreq, 0, sizeof(mreq));		mreq.imr_multiaddr = (((struct sockaddr_in*)maddr)->sin_addr);		mreq.imr_interface.s_addr = htonl(INADDR_ANY);		if (setsockopt(iface->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,			(char *)&mreq, sizeof(mreq)) == -1) {			netsyslog(LOG_ERR,			"setsockopt IP_ADD_MEMBERSHIP failure: %m on socket %d, addr %s for %x / %x (%s)",			iface->fd, stoa(&iface->sin),			mreq.imr_multiaddr.s_addr,			mreq.imr_interface.s_addr, stoa(maddr));			return ISC_FALSE;		}#ifdef DEBUG		if (debug > 0) {			printf(			"Added IPv4 multicast membership on socket %d, addr %s for %x / %x (%s)\n",			iface->fd, stoa(&iface->sin),			mreq.imr_multiaddr.s_addr,			mreq.imr_interface.s_addr, stoa(maddr));		}#endif		break;	case AF_INET6:#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT		/*		 * Enable reception of multicast packets		 * If the address is link-local we can get the interface index		 * from the scope id. Don't do this for other types of multicast		 * addresses. For now let the kernel figure it out.		 */		memset((char *)&mreq6, 0, sizeof(mreq6));		iaddr6 = ((struct sockaddr_in6*)maddr)->sin6_addr;		mreq6.ipv6mr_multiaddr = iaddr6;		mreq6.ipv6mr_interface = lscope;		if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,			(char *)&mreq6, sizeof(mreq6)) == -1) {			netsyslog(LOG_ERR,			 "setsockopt IPV6_JOIN_GROUP failure: %m on socket %d, addr %s for interface %d(%s)",			iface->fd, stoa(&iface->sin),			mreq6.ipv6mr_interface, stoa(maddr));			return ISC_FALSE;		}#ifdef DEBUG		if (debug > 0) {			printf(			 "Added IPv6 multicast group on socket %d, addr %s for interface %d(%s)\n",			iface->fd, stoa(&iface->sin),			mreq6.ipv6mr_interface, stoa(maddr));		}#endif		break;#else		return ISC_FALSE;#endif	/* INCLUDE_IPV6_MULTICAST_SUPPORT */	}	iface->flags |= INT_MCASTOPEN;	iface->num_mcast++;	add_addr_to_list(maddr, ind, iface->flags);	return ISC_TRUE;}/* * Remove a multicast address from a given socket * The socket is in the inter_list all we need to do is disable * multicasting. It is not this function's job to select the socket */static isc_boolean_tsocket_multicast_disable(struct interface *iface, int ind, struct sockaddr_storage *maddr){#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT	struct ipv6_mreq mreq6;	struct in6_addr iaddr6;#endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */	struct ip_mreq mreq;	memset((char *)&mreq, 0, sizeof(mreq));	switch (maddr->ss_family)	{	case AF_INET:		mreq.imr_multiaddr = (((struct sockaddr_in*)&maddr)->sin_addr);		mreq.imr_interface.s_addr = ((struct sockaddr_in*)&iface->sin)->sin_addr.s_addr;		if (setsockopt(iface->fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,			(char *)&mreq, sizeof(mreq)) == -1) {			netsyslog(LOG_ERR,			"setsockopt IP_DROP_MEMBERSHIP failure: %m on socket %d, addr %s for %x / %x (%s)",			iface->fd, stoa(&iface->sin),			mreq.imr_multiaddr.s_addr,			mreq.imr_interface.s_addr, stoa(maddr));			return ISC_FALSE;		}		break;	case AF_INET6:#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT		/*		 * Disable reception of multicast packets		 * If the address is link-local we can get the interface index		 * from the scope id. Don't do this for other types of multicast		 * addresses. For now let the kernel figure it out.		 */		iaddr6 = ((struct sockaddr_in6*)&maddr)->sin6_addr;		mreq6.ipv6mr_multiaddr = iaddr6;		mreq6.ipv6mr_interface = iface->scopeid;		if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,			(char *)&mreq6, sizeof(mreq6)) == -1) {

⌨️ 快捷键说明

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