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

📄 getipnode.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: getipnode.c,v 1.30.2.4.2.4 2004/03/06 08:15:31 marka Exp $ */#include <config.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <lwres/lwres.h>#include <lwres/net.h>#include <lwres/netdb.h>	/* XXX #include <netdb.h> */#include "assert_p.h"#ifndef INADDRSZ#define INADDRSZ 4#endif#ifndef IN6ADDRSZ#define IN6ADDRSZ 16#endif#ifdef LWRES_PLATFORM_NEEDIN6ADDRANYLIBLWRES_EXTERNAL_DATA const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;#endif#ifndef IN6_IS_ADDR_V4COMPATstatic const unsigned char in6addr_compat[12] = {        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};#define IN6_IS_ADDR_V4COMPAT(x) (!memcmp((x)->s6_addr, in6addr_compat, 12) && \                                 ((x)->s6_addr[12] != 0 || \                                  (x)->s6_addr[13] != 0 || \                                  (x)->s6_addr[14] != 0 || \                                   ((x)->s6_addr[15] != 0 && \                                    (x)->s6_addr[15] != 1)))#endif#ifndef IN6_IS_ADDR_V4MAPPED#define IN6_IS_ADDR_V4MAPPED(x) (!memcmp((x)->s6_addr, in6addr_mapped, 12))#endifstatic const unsigned char in6addr_mapped[12] = {        0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0xff, 0xff};/*** ***	Forward declarations. ***/static intscan_interfaces(int *, int *);static struct hostent *copyandmerge(struct hostent *, struct hostent *, int, int *);static struct hostent *hostfromaddr(lwres_gnbaresponse_t *addr, int af, const void *src);static struct hostent *hostfromname(lwres_gabnresponse_t *name, int af);/*** ***	Public functions. ***//* *	AI_V4MAPPED + AF_INET6 *	If no IPv6 address then a query for IPv4 and map returned values. * *	AI_ALL + AI_V4MAPPED + AF_INET6 *	Return IPv6 and IPv4 mapped. * *	AI_ADDRCONFIG *	Only return IPv6 / IPv4 address if there is an interface of that *	type active. */struct hostent *lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) {	int have_v4 = 1, have_v6 = 1;	struct in_addr in4;	struct in6_addr in6;	struct hostent he, *he1 = NULL, *he2 = NULL, *he3 = NULL;	int v4 = 0, v6 = 0;	int tmp_err;	lwres_context_t *lwrctx = NULL;	lwres_gabnresponse_t *by = NULL;	int n;	/*	 * If we care about active interfaces then check.	 */	if ((flags & AI_ADDRCONFIG) != 0)		if (scan_interfaces(&have_v4, &have_v6) == -1) {			*error_num = NO_RECOVERY;			return (NULL);		}	/* Check for literal address. */	if ((v4 = lwres_net_pton(AF_INET, name, &in4)) != 1)		v6 = lwres_net_pton(AF_INET6, name, &in6);	/*	 * Impossible combination?	 */	if ((af == AF_INET6 && (flags & AI_V4MAPPED) == 0 && v4 == 1) ||	    (af == AF_INET && v6 == 1) ||	    (have_v4 == 0 && v4 == 1) ||	    (have_v6 == 0 && v6 == 1) ||	    (have_v4 == 0 && af == AF_INET) ||	    (have_v6 == 0 && af == AF_INET6 &&	     (((flags & AI_V4MAPPED) != 0 && have_v4) ||	      (flags & AI_V4MAPPED) == 0))) {		*error_num = HOST_NOT_FOUND;		return (NULL);	}	/*	 * Literal address?	 */	if (v4 == 1 || v6 == 1) {		char *addr_list[2];		char *aliases[1];		char mappedname[sizeof("::ffff:123.123.123.123")];		union {			const char *const_name;			char *deconst_name;		} u;		u.const_name = name;		if (v4 == 1 && af == AF_INET6) {			strcpy(mappedname, "::ffff:");			lwres_net_ntop(AF_INET, (char *)&in4,				       mappedname + sizeof("::ffff:") - 1,				       sizeof(mappedname) - sizeof("::ffff:")				       + 1);			he.h_name = mappedname;		} else			he.h_name = u.deconst_name;		he.h_addr_list = addr_list;		he.h_addr_list[0] = (v4 == 1) ? (char *)&in4 : (char *)&in6;		he.h_addr_list[1] = NULL;		he.h_aliases = aliases;		he.h_aliases[0] = NULL;		he.h_length = (v4 == 1) ? INADDRSZ : IN6ADDRSZ;		he.h_addrtype = (v4 == 1) ? AF_INET : AF_INET6;		return (copyandmerge(&he, NULL, af, error_num));	}	n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);	if (n != 0) {		*error_num = NO_RECOVERY;		goto cleanup;	}	(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);	tmp_err = NO_RECOVERY;	if (have_v6 && af == AF_INET6) {		n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V6, &by);		if (n == 0) {			he1 = hostfromname(by, AF_INET6);			lwres_gabnresponse_free(lwrctx, &by);			if (he1 == NULL) {				*error_num = NO_RECOVERY;				goto cleanup;			}		} else {			tmp_err = HOST_NOT_FOUND;		}	}	if (have_v4 &&	    ((af == AF_INET) ||	     (af == AF_INET6 && (flags & AI_V4MAPPED) != 0 &&	      (he1 == NULL || (flags & AI_ALL) != 0)))) {		n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V4, &by);		if (n == 0) {			he2 = hostfromname(by, AF_INET);			lwres_gabnresponse_free(lwrctx, &by);			if (he2 == NULL) {				*error_num = NO_RECOVERY;				goto cleanup;			}		} else if (he1 == NULL) {			if (n == LWRES_R_NOTFOUND)				*error_num = HOST_NOT_FOUND;			else				*error_num = NO_RECOVERY;			goto cleanup;		}	} else		*error_num = tmp_err;	he3 = copyandmerge(he1, he2, af, error_num); cleanup:	if (he1 != NULL)		lwres_freehostent(he1);	if (he2 != NULL)		lwres_freehostent(he2);	if (lwrctx != NULL) {		lwres_conf_clear(lwrctx);		lwres_context_destroy(&lwrctx);	}	return (he3);}struct hostent *lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) {	struct hostent *he1, *he2;	lwres_context_t *lwrctx = NULL;	lwres_gnbaresponse_t *by = NULL;	lwres_result_t n;	union {		const void *konst;		struct in6_addr *in6;	} u;	/*	 * Sanity checks.	 */	if (src == NULL) {		*error_num = NO_RECOVERY;		return (NULL);	}	switch (af) {	case AF_INET:		if (len != (unsigned int)INADDRSZ) {			*error_num = NO_RECOVERY;			return (NULL);		}		break;	case AF_INET6:		if (len != (unsigned int)IN6ADDRSZ) {			*error_num = NO_RECOVERY;			return (NULL);		}		break;	default:		*error_num = NO_RECOVERY;		return (NULL);	}	/*	 * The de-"const"-ing game is done because at least one	 * vendor's system (RedHat 6.0) defines the IN6_IS_ADDR_*	 * macros in such a way that they discard the const with	 * internal casting, and gcc ends up complaining.  Rather	 * than replacing their own (possibly optimized) definitions	 * with our own, cleanly discarding the const is the easiest	 * thing to do.	 */	u.konst = src;	/*	 * Look up IPv4 and IPv4 mapped/compatible addresses.	 */	if ((af == AF_INET6 && IN6_IS_ADDR_V4COMPAT(u.in6)) ||	    (af == AF_INET6 && IN6_IS_ADDR_V4MAPPED(u.in6)) ||	    (af == AF_INET)) {		const unsigned char *cp = src;		if (af == AF_INET6)			cp += 12;		n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);		if (n == LWRES_R_SUCCESS)			(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);		if (n == LWRES_R_SUCCESS)			n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V4,						INADDRSZ, cp, &by);		if (n != LWRES_R_SUCCESS) {			lwres_conf_clear(lwrctx);			lwres_context_destroy(&lwrctx);			if (n == LWRES_R_NOTFOUND)				*error_num = HOST_NOT_FOUND;			else				*error_num = NO_RECOVERY;			return (NULL);		}		he1 = hostfromaddr(by, AF_INET, cp);		lwres_gnbaresponse_free(lwrctx, &by);		lwres_conf_clear(lwrctx);		lwres_context_destroy(&lwrctx);		if (af != AF_INET6)			return (he1);		/*		 * Convert from AF_INET to AF_INET6.		 */		he2 = copyandmerge(he1, NULL, af, error_num);		lwres_freehostent(he1);		if (he2 == NULL)			return (NULL);		/*		 * Restore original address.		 */		memcpy(he2->h_addr, src, len);		return (he2);	}	/*	 * Lookup IPv6 address.	 */	if (memcmp(src, &in6addr_any, IN6ADDRSZ) == 0) {		*error_num = HOST_NOT_FOUND;		return (NULL);	}	n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);	if (n == LWRES_R_SUCCESS)		(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);	if (n == LWRES_R_SUCCESS)		n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V6, IN6ADDRSZ,					src, &by);	if (n != 0) {		*error_num = HOST_NOT_FOUND;		return (NULL);	}	he1 = hostfromaddr(by, AF_INET6, src);	lwres_gnbaresponse_free(lwrctx, &by);	if (he1 == NULL)		*error_num = NO_RECOVERY;	lwres_context_destroy(&lwrctx);	return (he1);}voidlwres_freehostent(struct hostent *he) {	char **cpp;	int names = 1;	int addresses = 1;	free(he->h_name);	cpp = he->h_addr_list;	while (*cpp != NULL) {		free(*cpp);		*cpp = NULL;		cpp++;		addresses++;	}	cpp = he->h_aliases;	while (*cpp != NULL) {		free(*cpp);		cpp++;		names++;	}	free(he->h_aliases);	free(he->h_addr_list);	free(he);}/* * Private *//* * Scan the interface table and set have_v4 and have_v6 depending * upon whether there are IPv4 and IPv6 interface addresses. * * Returns: *	0 on success *	-1 on failure. */#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \    !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) #ifdef __hpux#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 __hpux#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#endifstatic intscan_interfaces6(int *have_v4, int *have_v6) {	struct LIFCONF lifc;	struct LIFREQ lifreq;	struct in_addr in4;	struct in6_addr in6;	char *buf = NULL, *cp, *cplim;	static unsigned int bufsiz = 4095;	int s, cpsize, n;	/*	 * Set to zero.  Used as loop terminators below.	 */	*have_v4 = *have_v6 = 0;	/*	 * Get interface list from system.	 */	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) == -1)		goto err_ret;	/*	 * Grow buffer until large enough to contain all interface	 * descriptions.	 */	for (;;) {		buf = malloc(bufsiz);		if (buf == NULL)			goto err_ret;#ifdef ISC_HAVE_LIFC_FAMILY		lifc.lifc_family = AF_UNSPEC;	/* request all families */#endif#ifdef ISC_HAVE_LIFC_FLAGS		lifc.lifc_flags = 0;#endif		lifc.lifc_len = bufsiz;		lifc.lifc_buf = buf;		if ((n = ioctl(s, SIOCGLIFCONF, (char *)&lifc)) != -1) {			/*			 * 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 			 * lifc.lifc_len is too near to the end of the			 * buffer we will grow it just in case and			 * retry.			 */			if (lifc.lifc_len + 2 * sizeof(lifreq) < bufsiz)				break;		}		if ((n == -1) && errno != EINVAL)			goto err_ret;		if (bufsiz > 1000000)			goto err_ret;		free(buf);		bufsiz += 4096;	}	/*	 * Parse system's interface list.	 */	cplim = buf + lifc.lifc_len;    /* skip over if's with big ifr_addr's */	for (cp = buf;	     (*have_v4 == 0 || *have_v6 == 0) && cp < cplim;	     cp += cpsize) {		memcpy(&lifreq, cp, sizeof(lifreq));#ifdef LWRES_PLATFORM_HAVESALEN#ifdef FIX_ZERO_SA_LEN		if (lifreq.lifr_addr.sa_len == 0)			lifreq.lifr_addr.sa_len = 16;#endif#ifdef HAVE_MINIMUM_IFREQ		cpsize = sizeof(lifreq);		if (lifreq.lifr_addr.sa_len > sizeof(struct sockaddr))			cpsize += (int)lifreq.lifr_addr.sa_len -				(int)(sizeof(struct sockaddr));#else		cpsize = sizeof(lifreq.lifr_name) + lifreq.lifr_addr.sa_len;#endif /* HAVE_MINIMUM_IFREQ */#elif defined SIOCGIFCONF_ADDR		cpsize = sizeof(lifreq);#else		cpsize = sizeof(lifreq.lifr_name);		/* XXX maybe this should be a hard error? */		if (ioctl(s, SIOCGLIFADDR, (char *)&lifreq) < 0)			continue;#endif		switch (lifreq.lifr_addr.ss_family) {		case AF_INET:			if (*have_v4 == 0) {				memcpy(&in4,				       &((struct sockaddr_in *)				       &lifreq.lifr_addr)->sin_addr,				       sizeof(in4));				if (in4.s_addr == INADDR_ANY)					break;				n = ioctl(s, SIOCGLIFFLAGS, (char *)&lifreq);				if (n < 0)					break;				if ((lifreq.lifr_flags & IFF_UP) == 0)					break;				*have_v4 = 1;			} 

⌨️ 快捷键说明

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