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

📄 getaddrinfo.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001  Internet Software Consortium. * * This code is derived from software contributed to ISC by * Berkeley Software Design, Inc. * * 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 AND BERKELEY SOFTWARE DESIGN, INC. * 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: getaddrinfo.c,v 1.41.206.1 2004/03/06 08:15:30 marka Exp $ */#include <config.h>#include <string.h>#include <errno.h>#include <stdlib.h>#include <lwres/lwres.h>#include <lwres/net.h>#include <lwres/netdb.h>#define SA(addr)	((struct sockaddr *)(addr))#define SIN(addr)	((struct sockaddr_in *)(addr))#define SIN6(addr)	((struct sockaddr_in6 *)(addr))#define SUN(addr)	((struct sockaddr_un *)(addr))static struct addrinfo	*ai_reverse(struct addrinfo *oai),	*ai_clone(struct addrinfo *oai, int family),	*ai_alloc(int family, int addrlen);#ifdef AF_LOCALstatic int get_local(const char *name, int socktype, struct addrinfo **res);#endifstatic int add_ipv4(const char *hostname, int flags, struct addrinfo **aip,    int socktype, int port);static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip,    int socktype, int port);static void set_order(int, int (**)(const char *, int, struct addrinfo **,         int, int));#define FOUND_IPV4	0x1#define FOUND_IPV6	0x2#define FOUND_MAX	2#define ISC_AI_MASK (AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST)intlwres_getaddrinfo(const char *hostname, const char *servname,	const struct addrinfo *hints, struct addrinfo **res){	struct servent *sp;	const char *proto;	int family, socktype, flags, protocol;	struct addrinfo *ai, *ai_list;	int port, err, i;	int (*net_order[FOUND_MAX+1])(const char *, int, struct addrinfo **,		 int, int);	if (hostname == NULL && servname == NULL)		return (EAI_NONAME);	proto = NULL;	if (hints != NULL) {		if ((hints->ai_flags & ~(ISC_AI_MASK)) != 0)			return (EAI_BADFLAGS);		if (hints->ai_addrlen || hints->ai_canonname ||		    hints->ai_addr || hints->ai_next) {			errno = EINVAL;			return (EAI_SYSTEM);		}		family = hints->ai_family;		socktype = hints->ai_socktype;		protocol = hints->ai_protocol;		flags = hints->ai_flags;		switch (family) {		case AF_UNSPEC:			switch (hints->ai_socktype) {			case SOCK_STREAM:				proto = "tcp";				break;			case SOCK_DGRAM:				proto = "udp";				break;			}			break;		case AF_INET:		case AF_INET6:			switch (hints->ai_socktype) {			case 0:				break;			case SOCK_STREAM:				proto = "tcp";				break;			case SOCK_DGRAM:				proto = "udp";				break;			case SOCK_RAW:				break;			default:				return (EAI_SOCKTYPE);			}			break;#ifdef	AF_LOCAL		case AF_LOCAL:			switch (hints->ai_socktype) {			case 0:				break;			case SOCK_STREAM:				break;			case SOCK_DGRAM:				break;			default:				return (EAI_SOCKTYPE);			}			break;#endif		default:			return (EAI_FAMILY);		}	} else {		protocol = 0;		family = 0;		socktype = 0;		flags = 0;	}#ifdef	AF_LOCAL	/*	 * First, deal with AF_LOCAL.  If the family was not set,	 * then assume AF_LOCAL if the first character of the	 * hostname/servname is '/'.	 */	if (hostname != NULL &&	    (family == AF_LOCAL || (family == 0 && *hostname == '/')))		return (get_local(hostname, socktype, res));	if (servname != NULL &&	    (family == AF_LOCAL || (family == 0 && *servname == '/')))		return (get_local(servname, socktype, res));#endif	/*	 * Ok, only AF_INET and AF_INET6 left.	 */	ai_list = NULL;	/*	 * First, look up the service name (port) if it was	 * requested.  If the socket type wasn't specified, then	 * try and figure it out.	 */	if (servname != NULL) {		char *e;		port = strtol(servname, &e, 10);		if (*e == '\0') {			if (socktype == 0)				return (EAI_SOCKTYPE);			if (port < 0 || port > 65535)				return (EAI_SERVICE);			port = htons((unsigned short) port);		} else {			sp = getservbyname(servname, proto);			if (sp == NULL)				return (EAI_SERVICE);			port = sp->s_port;			if (socktype == 0) {				if (strcmp(sp->s_proto, "tcp") == 0)					socktype = SOCK_STREAM;				else if (strcmp(sp->s_proto, "udp") == 0)					socktype = SOCK_DGRAM;			}		}	} else		port = 0;	/*	 * Next, deal with just a service name, and no hostname.	 * (we verified that one of them was non-null up above).	 */	if (hostname == NULL && (flags & AI_PASSIVE) != 0) {		if (family == AF_INET || family == 0) {			ai = ai_alloc(AF_INET, sizeof(struct sockaddr_in));			if (ai == NULL)				return (EAI_MEMORY);			ai->ai_socktype = socktype;			ai->ai_protocol = protocol;			SIN(ai->ai_addr)->sin_port = port;			ai->ai_next = ai_list;			ai_list = ai;		}		if (family == AF_INET6 || family == 0) {			ai = ai_alloc(AF_INET6, sizeof(struct sockaddr_in6));			if (ai == NULL) {				lwres_freeaddrinfo(ai_list);				return (EAI_MEMORY);			}			ai->ai_socktype = socktype;			ai->ai_protocol = protocol;			SIN6(ai->ai_addr)->sin6_port = port;			ai->ai_next = ai_list;			ai_list = ai;		}		*res = ai_list;		return (0);	}	/*	 * If the family isn't specified or AI_NUMERICHOST specified,	 * check first to see if it is a numeric address.	 * Though the gethostbyname2() routine	 * will recognize numeric addresses, it will only recognize	 * the format that it is being called for.  Thus, a numeric	 * AF_INET address will be treated by the AF_INET6 call as	 * a domain name, and vice versa.  Checking for both numerics	 * here avoids that.	 */	if (hostname != NULL &&	    (family == 0 || (flags & AI_NUMERICHOST) != 0)) {		char abuf[sizeof(struct in6_addr)];		char nbuf[NI_MAXHOST];		int addrsize, addroff;#ifdef LWRES_HAVE_SIN6_SCOPE_ID		char *p, *ep;		char ntmp[NI_MAXHOST];		lwres_uint32_t scopeid;#endif#ifdef LWRES_HAVE_SIN6_SCOPE_ID		/*		 * Scope identifier portion.		 */		ntmp[0] = '\0';		if (strchr(hostname, '%') != NULL) {			strncpy(ntmp, hostname, sizeof(ntmp) - 1);			ntmp[sizeof(ntmp) - 1] = '\0';			p = strchr(ntmp, '%');			ep = NULL;			/*			 * Vendors may want to support non-numeric			 * scopeid around here.			 */			if (p != NULL)				scopeid = (lwres_uint32_t)strtoul(p + 1,								  &ep, 10);			if (p != NULL && ep != NULL && ep[0] == '\0')				*p = '\0';			else {				ntmp[0] = '\0';				scopeid = 0;			}		} else			scopeid = 0;#endif               if (lwres_net_pton(AF_INET, hostname, (struct in_addr *)abuf)		   == 1)	       {			if (family == AF_INET6) {				/*				 * Convert to a V4 mapped address.				 */				struct in6_addr *a6 = (struct in6_addr *)abuf;				memcpy(&a6->s6_addr[12], &a6->s6_addr[0], 4);				memset(&a6->s6_addr[10], 0xff, 2);				memset(&a6->s6_addr[0], 0, 10);				goto inet6_addr;			}			addrsize = sizeof(struct in_addr);			addroff = (char *)(&SIN(0)->sin_addr) - (char *)0;			family = AF_INET;			goto common;#ifdef LWRES_HAVE_SIN6_SCOPE_ID		} else if (ntmp[0] != '\0' &&			   lwres_net_pton(AF_INET6, ntmp, abuf) == 1)		{			if (family && family != AF_INET6)				return (EAI_NONAME);			addrsize = sizeof(struct in6_addr);			addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;			family = AF_INET6;			goto common;#endif		} else if (lwres_net_pton(AF_INET6, hostname, abuf) == 1) {			if (family != 0 && family != AF_INET6)				return (EAI_NONAME);		inet6_addr:			addrsize = sizeof(struct in6_addr);			addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;			family = AF_INET6;		common:			ai = ai_clone(ai_list, family);			if (ai == NULL)				return (EAI_MEMORY);			ai_list = ai;			ai->ai_socktype = socktype;			SIN(ai->ai_addr)->sin_port = port;			memcpy((char *)ai->ai_addr + addroff, abuf, addrsize);			if (flags & AI_CANONNAME) {#if defined(LWRES_HAVE_SIN6_SCOPE_ID)				if (ai->ai_family == AF_INET6)					SIN6(ai->ai_addr)->sin6_scope_id =									scopeid;#endif				if (lwres_getnameinfo(ai->ai_addr,				    ai->ai_addrlen, nbuf, sizeof(nbuf),						      NULL, 0,						      NI_NUMERICHOST) == 0) {					ai->ai_canonname = strdup(nbuf);					if (ai->ai_canonname == NULL)						return (EAI_MEMORY);				} else {					/* XXX raise error? */					ai->ai_canonname = NULL;				}			}			goto done;		} else if ((flags & AI_NUMERICHOST) != 0) {			return (EAI_NONAME);		}	}	set_order(family, net_order);	for (i = 0; i < FOUND_MAX; i++) {		if (net_order[i] == NULL)			break;		err = (net_order[i])(hostname, flags, &ai_list,				     socktype, port);

⌨️ 快捷键说明

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