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

📄 ifiter_ioctl.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003  Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *//* $Id: ifiter_ioctl.c,v 1.19.2.5.2.14 2004/06/22 04:40:23 marka Exp $ *//* * Obtain the list of network interfaces using the SIOCGLIFCONF ioctl. * See netintro(4). */#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)#ifdef ISC_PLATFORM_HAVEIF_LADDRCONF#define lifc_len iflc_len#define lifc_buf iflc_buf#define lifc_req iflc_req#define LIFCONF if_laddrconf#else#define ISC_HAVE_LIFC_FAMILY 1#define ISC_HAVE_LIFC_FLAGS 1#define LIFCONF lifconf#endif#ifdef ISC_PLATFORM_HAVEIF_LADDRREQ#define lifr_addr iflr_addr#define lifr_name iflr_name#define lifr_dstaddr iflr_dstaddr#define lifr_flags iflr_flags#define ss_family sa_family#define LIFREQ if_laddrreq#else#define LIFREQ lifreq#endif#endif#define IFITER_MAGIC		ISC_MAGIC('I', 'F', 'I', 'T')#define VALID_IFITER(t)		ISC_MAGIC_VALID(t, IFITER_MAGIC)#define ISC_IF_INET6_SZ \    sizeof("00000000000000000000000000000001 01 80 10 80 XXXXXXloXXXXXXXX\n")struct isc_interfaceiter {	unsigned int		magic;		/* Magic number. */	isc_mem_t		*mctx;	int			mode;	int			socket;	struct ifconf 		ifc;	void			*buf;		/* Buffer for sysctl data. */	unsigned int		bufsize;	/* Bytes allocated. */	unsigned int		pos;		/* Current offset in						   SIOCGIFCONF data */#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)	int			socket6;	struct LIFCONF 		lifc;	void			*buf6;		/* Buffer for sysctl data. */	unsigned int		bufsize6;	/* Bytes allocated. */	unsigned int		pos6;		/* Current offset in						   SIOCGLIFCONF data */	isc_result_t		result6;	/* Last result code. */	isc_boolean_t		first6;#endif#ifdef HAVE_TRUCLUSTER	int			clua_context;	/* Cluster alias context */	isc_boolean_t		clua_done;	struct sockaddr		clua_sa;#endif#ifdef	__linux	FILE *			proc;	char			entry[ISC_IF_INET6_SZ];	isc_result_t		valid;	isc_boolean_t		first;#endif	isc_interface_t		current;	/* Current interface data. */	isc_result_t		result;		/* Last result code. */};#ifdef HAVE_TRUCLUSTER#include <clua/clua.h>#include <sys/socket.h>#endif/* * Size of buffer for SIOCGLIFCONF, in bytes.  We assume no sane system * will have more than a megabyte of interface configuration data. */#define IFCONF_BUFSIZE_INITIAL	4096#define IFCONF_BUFSIZE_MAX	1048576#ifdef __linux#ifndef IF_NAMESIZE# ifdef IFNAMSIZ#  define IF_NAMESIZE  IFNAMSIZ  # else#  define IF_NAMESIZE 16# endif#endif#endifstatic isc_result_tgetbuf4(isc_interfaceiter_t *iter) {	char strbuf[ISC_STRERRORSIZE];	iter->bufsize = IFCONF_BUFSIZE_INITIAL;	for (;;) {		iter->buf = isc_mem_get(iter->mctx, iter->bufsize);		if (iter->buf == NULL)			return (ISC_R_NOMEMORY);		memset(&iter->ifc.ifc_len, 0, sizeof(iter->ifc.ifc_len));		iter->ifc.ifc_len = iter->bufsize;		iter->ifc.ifc_buf = iter->buf;		/*		 * Ignore the HP/UX warning about "interger overflow during		 * conversion".  It comes from its own macro definition,		 * and is really hard to shut up.		 */		if (ioctl(iter->socket, SIOCGIFCONF, (char *)&iter->ifc)		    == -1) {			if (errno != EINVAL) {				isc__strerror(errno, strbuf, sizeof(strbuf));				UNEXPECTED_ERROR(__FILE__, __LINE__,						 isc_msgcat_get(isc_msgcat,							ISC_MSGSET_IFITERIOCTL,							ISC_MSG_GETIFCONFIG,							"get interface "							"configuration: %s"),						 strbuf);				goto unexpected;			}			/*			 * EINVAL.  Retry with a bigger buffer.			 */		} else {			/*			 * The ioctl succeeded.			 * Some OS's just return what will fit rather			 * than set EINVAL if the buffer is too small			 * to fit all the interfaces in.  If			 * ifc.lifc_len is too near to the end of the			 * buffer we will grow it just in case and			 * retry.			 */			if (iter->ifc.ifc_len + 2 * sizeof(struct ifreq)			    < iter->bufsize)				break;		}		if (iter->bufsize >= IFCONF_BUFSIZE_MAX) {			UNEXPECTED_ERROR(__FILE__, __LINE__,					 isc_msgcat_get(isc_msgcat,							ISC_MSGSET_IFITERIOCTL,							ISC_MSG_BUFFERMAX,							"get interface "							"configuration: "							"maximum buffer "							"size exceeded"));			goto unexpected;		}		isc_mem_put(iter->mctx, iter->buf, iter->bufsize);		iter->bufsize *= 2;	}	return (ISC_R_SUCCESS); unexpected:	isc_mem_put(iter->mctx, iter->buf, iter->bufsize);	iter->buf = NULL;	return (ISC_R_UNEXPECTED);}#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)static isc_result_tgetbuf6(isc_interfaceiter_t *iter) {	char strbuf[ISC_STRERRORSIZE];	isc_result_t result;	iter->bufsize6 = IFCONF_BUFSIZE_INITIAL;	for (;;) {		iter->buf6 = isc_mem_get(iter->mctx, iter->bufsize6);		if (iter->buf6 == NULL)			return (ISC_R_NOMEMORY);		memset(&iter->lifc, 0, sizeof(iter->lifc));#ifdef ISC_HAVE_LIFC_FAMILY		iter->lifc.lifc_family = AF_INET6;#endif#ifdef ISC_HAVE_LIFC_FLAGS		iter->lifc.lifc_flags = 0;#endif		iter->lifc.lifc_len = iter->bufsize6;		iter->lifc.lifc_buf = iter->buf6;		/*		 * Ignore the HP/UX warning about "interger overflow during		 * conversion".  It comes from its own macro definition,		 * and is really hard to shut up.		 */		if (ioctl(iter->socket6, SIOCGLIFCONF, (char *)&iter->lifc)		    == -1) {#ifdef __hpux			/*			 * IPv6 interface scanning is not available on all			 * kernels w/ IPv6 sockets.			 */			if (errno == ENOENT) {				isc__strerror(errno, strbuf, sizeof(strbuf));				isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,					      ISC_LOGMODULE_INTERFACE,					      ISC_LOG_DEBUG(1),					      isc_msgcat_get(isc_msgcat,							ISC_MSGSET_IFITERIOCTL,							ISC_MSG_GETIFCONFIG,							"get interface "							"configuration: %s"),					       strbuf);				result = ISC_R_FAILURE;				goto cleanup;			}#endif			if (errno != EINVAL) {				isc__strerror(errno, strbuf, sizeof(strbuf));				UNEXPECTED_ERROR(__FILE__, __LINE__,						 isc_msgcat_get(isc_msgcat,							ISC_MSGSET_IFITERIOCTL,							ISC_MSG_GETIFCONFIG,							"get interface "							"configuration: %s"),						 strbuf);				result = ISC_R_UNEXPECTED;				goto cleanup;			}			/*			 * EINVAL.  Retry with a bigger buffer.			 */		} else {			/*			 * The ioctl succeeded.			 * Some OS's just return what will fit rather			 * than set EINVAL if the buffer is too small			 * to fit all the interfaces in.  If			 * ifc.ifc_len is too near to the end of the			 * buffer we will grow it just in case and			 * retry.			 */			if (iter->lifc.lifc_len + 2 * sizeof(struct LIFREQ)			    < iter->bufsize6)				break;		}		if (iter->bufsize6 >= IFCONF_BUFSIZE_MAX) {			UNEXPECTED_ERROR(__FILE__, __LINE__,					 isc_msgcat_get(isc_msgcat,							ISC_MSGSET_IFITERIOCTL,							ISC_MSG_BUFFERMAX,							"get interface "							"configuration: "							"maximum buffer "							"size exceeded"));			result = ISC_R_UNEXPECTED;			goto cleanup;		}		isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6);		iter->bufsize6 *= 2;	}	if (iter->lifc.lifc_len != 0)		iter->mode = 6;	return (ISC_R_SUCCESS); cleanup:	isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6);	iter->buf6 = NULL;	return (result);}#endifisc_result_tisc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {	isc_interfaceiter_t *iter;	isc_result_t result;	char strbuf[ISC_STRERRORSIZE];	REQUIRE(mctx != NULL);	REQUIRE(iterp != NULL);	REQUIRE(*iterp == NULL);	iter = isc_mem_get(mctx, sizeof(*iter));	if (iter == NULL)		return (ISC_R_NOMEMORY);	iter->mctx = mctx;	iter->mode = 4;	iter->buf = NULL;	iter->pos = (unsigned int) -1;#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)	iter->buf6 = NULL;	iter->pos6 = (unsigned int) -1;	iter->result6 = ISC_R_NOMORE;	iter->socket6 = -1;	iter->first6 = ISC_FALSE;#endif	/*	 * Get the interface configuration, allocating more memory if	 * necessary.	 */#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)	result = isc_net_probeipv6();	if (result == ISC_R_SUCCESS) {		/*		 * Create an unbound datagram socket to do the SIOCGLIFCONF		 * ioctl on.  HP/UX requires an AF_INET6 socket for		 * SIOCGLIFCONF to get IPv6 addresses.		 */		if ((iter->socket6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {			isc__strerror(errno, strbuf, sizeof(strbuf));			UNEXPECTED_ERROR(__FILE__, __LINE__,					 isc_msgcat_get(isc_msgcat,							ISC_MSGSET_IFITERIOCTL,							ISC_MSG_MAKESCANSOCKET,							"making interface "							"scan socket: %s"),					 strbuf);			result = ISC_R_UNEXPECTED;			goto socket6_failure;		}		iter->result6 = getbuf6(iter);		if (iter->result6 != ISC_R_NOTIMPLEMENTED &&		    iter->result6 != ISC_R_SUCCESS)			goto ioctl6_failure;	}#endif	if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {		isc__strerror(errno, strbuf, sizeof(strbuf));		UNEXPECTED_ERROR(__FILE__, __LINE__,				 isc_msgcat_get(isc_msgcat,						ISC_MSGSET_IFITERIOCTL,						ISC_MSG_MAKESCANSOCKET,						"making interface "						"scan socket: %s"),				 strbuf);		result = ISC_R_UNEXPECTED;		goto socket_failure;	}	result = getbuf4(iter);	if (result != ISC_R_SUCCESS)		goto ioctl_failure;	/*	 * A newly created iterator has an undefined position	 * until isc_interfaceiter_first() is called.	 */#ifdef HAVE_TRUCLUSTER	iter->clua_context = -1;	iter->clua_done = ISC_TRUE;#endif#ifdef __linux	iter->proc = fopen("/proc/net/if_inet6", "r");	iter->valid = ISC_R_FAILURE;	iter->first = ISC_FALSE;#endif	iter->result = ISC_R_FAILURE;	iter->magic = IFITER_MAGIC;	*iterp = iter;	return (ISC_R_SUCCESS); ioctl_failure:	if (iter->buf != NULL)		isc_mem_put(mctx, iter->buf, iter->bufsize);	(void) close(iter->socket); socket_failure:#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)	if (iter->buf6 != NULL)		isc_mem_put(mctx, iter->buf6, iter->bufsize6);  ioctl6_failure:	if (iter->socket6 != -1)		(void) close(iter->socket6);  socket6_failure:#endif 	isc_mem_put(mctx, iter, sizeof(*iter));	return (result);}#ifdef HAVE_TRUCLUSTERstatic voidget_inaddr(isc_netaddr_t *dst, struct in_addr *src) {	dst->family = AF_INET;	memcpy(&dst->type.in, src, sizeof(struct in_addr));}static isc_result_tinternal_current_clusteralias(isc_interfaceiter_t *iter) {	struct clua_info ci;	if (clua_getaliasinfo(&iter->clua_sa, &ci) != CLUA_SUCCESS)		return (ISC_R_IGNORE);	memset(&iter->current, 0, sizeof(iter->current));	iter->current.af = iter->clua_sa.sa_family;	memset(iter->current.name, 0, sizeof(iter->current.name));	sprintf(iter->current.name, "clua%d", ci.aliasid);	iter->current.flags = INTERFACE_F_UP;	get_inaddr(&iter->current.address, &ci.addr);	get_inaddr(&iter->current.netmask, &ci.netmask);	return (ISC_R_SUCCESS);}#endif#ifdef __linuxstatic isc_result_tlinux_if_inet6_next(isc_interfaceiter_t *iter) {	if (iter->proc != NULL &&	    fgets(iter->entry, sizeof(iter->entry), iter->proc) != NULL)		iter->valid = ISC_R_SUCCESS;	else		iter->valid = ISC_R_NOMORE;	return (iter->valid);}static voidlinux_if_inet6_first(isc_interfaceiter_t *iter) {	if (iter->proc != NULL) {		rewind(iter->proc);		(void)linux_if_inet6_next(iter);	} else		iter->valid = ISC_R_NOMORE;	iter->first = ISC_FALSE;}static isc_result_tlinux_if_inet6_current(isc_interfaceiter_t *iter) {	char address[33];	char name[IF_NAMESIZE+1];	struct in6_addr addr6;	int ifindex, prefix, flag3, flag4;	int res;	unsigned int i;	if (iter->valid != ISC_R_SUCCESS)		return (iter->valid);	if (iter->proc == NULL) {		isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,			      ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,			      "/proc/net/if_inet6:iter->proc == NULL");		return (ISC_R_FAILURE);	}	res = sscanf(iter->entry, "%32[a-f0-9] %x %x %x %x %16s\n",		     address, &ifindex, &prefix, &flag3, &flag4, name);	if (res != 6) {		isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,			      ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,			      "/proc/net/if_inet6:sscanf() -> %d (expected 6)",			      res);		return (ISC_R_FAILURE);	}	if (strlen(address) != 32) {		isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,			      ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,			      "/proc/net/if_inet6:strlen(%s) != 32", address);		return (ISC_R_FAILURE);	}	for (i = 0; i < 16; i++) {		unsigned char byte;		static const char hex[] = "0123456789abcdef";		byte = ((index(hex, address[i * 2]) - hex) << 4) |		       (index(hex, address[i * 2 + 1]) - hex);		addr6.s6_addr[i] = byte;	}	iter->current.af = AF_INET6;	iter->current.flags = INTERFACE_F_UP;	isc_netaddr_fromin6(&iter->current.address, &addr6);	if (isc_netaddr_islinklocal(&iter->current.address)) {		isc_netaddr_setzone(&iter->current.address,				    (isc_uint32_t)ifindex);	}	for (i = 0; i < 16; i++) {		if (prefix > 8) {			addr6.s6_addr[i] = 0xff;			prefix -= 8;		} else {			addr6.s6_addr[i] = (0xff << (8 - prefix)) & 0xff;			prefix = 0;		}	}	isc_netaddr_fromin6(&iter->current.netmask, &addr6);	strncpy(iter->current.name, name, sizeof(iter->current.name));	return (ISC_R_SUCCESS);}#endif/* * Get information about the current interface to iter->current.

⌨️ 快捷键说明

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