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

📄 getaddrinfo.c

📁 Linux 2.6 内核上配置IPSec VPN 的工具
💻 C
📖 第 1 页 / 共 2 页
字号:
					pai->ai_socktype = SOCK_STREAM;					pai->ai_protocol = IPPROTO_TCP;				} else					ERR(EAI_PROTOCOL);	/*xxx*/			}		}	}		/*	 * hostname == NULL.	 * passive socket -> anyaddr (0.0.0.0 or ::)	 * non-passive socket -> localhost (127.0.0.1 or ::1)	 */	if (hostname == NULL) {		struct afd *afd;		int s;		for (afd = &afdl[0]; afd->a_af; afd++) {			if (!(pai->ai_family == PF_UNSPEC			   || pai->ai_family == afd->a_af)) {				continue;			}			/*			 * filter out AFs that are not supported by the kernel			 * XXX errno?			 */			s = socket(afd->a_af, SOCK_DGRAM, 0);			if (s < 0)				continue;			close(s);			if (pai->ai_flags & AI_PASSIVE) {				GET_AI(cur->ai_next, afd, afd->a_addrany, port);				/* xxx meaningless?				 * GET_CANONNAME(cur->ai_next, "anyaddr");				 */			} else {				GET_AI(cur->ai_next, afd, afd->a_loopback,					port);				/* xxx meaningless?				 * GET_CANONNAME(cur->ai_next, "localhost");				 */			}			cur = cur->ai_next;		}		top = sentinel.ai_next;		if (top)			goto good;		else			ERR(EAI_FAMILY);	}		/* hostname as numeric name */	for (i = 0; afdl[i].a_af; i++) {		if (inet_pton(afdl[i].a_af, hostname, pton) == 1) {			u_long v4a;			u_char pfx;			switch (afdl[i].a_af) {			case AF_INET:				v4a = ntohl(((struct in_addr *)pton)->s_addr);				if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))					pai->ai_flags &= ~AI_CANONNAME;				v4a >>= IN_CLASSA_NSHIFT;				if (v4a == 0 || v4a == IN_LOOPBACKNET)					pai->ai_flags &= ~AI_CANONNAME;				break;#ifdef INET6			case AF_INET6:				pfx = ((struct in6_addr *)pton)->s6_addr[0];				if (pfx == 0 || pfx == 0xfe || pfx == 0xff)					pai->ai_flags &= ~AI_CANONNAME;				break;#endif			}						if (pai->ai_family == afdl[i].a_af ||			    pai->ai_family == PF_UNSPEC) {				if (! (pai->ai_flags & AI_CANONNAME)) {					GET_AI(top, &afdl[i], pton, port);					goto good;				}				/*				 * if AI_CANONNAME and if reverse lookup				 * fail, return ai anyway to pacify				 * calling application.				 *				 * XXX getaddrinfo() is a name->address				 * translation function, and it looks strange				 * that we do addr->name translation here.				 */				get_name(pton, &afdl[i], &top, pton, pai, port);				goto good;			} else 				ERR(EAI_FAMILY);	/*xxx*/		}	}	if (pai->ai_flags & AI_NUMERICHOST)		ERR(EAI_NONAME);	/* hostname as alphabetical name */	error = get_addr(hostname, pai->ai_family, &top, pai, port);	if (error == 0) {		if (top) { good:			*res = top;			return SUCCESS;		} else			error = EAI_FAIL;	} free:	if (top)		freeaddrinfo(top); bad:	*res = NULL;	return error;}static intget_name(addr, afd, res, numaddr, pai, port0)	const char *addr;	struct afd *afd;	struct addrinfo **res;	char *numaddr;	struct addrinfo *pai;	int port0;{	u_short port = port0 & 0xffff;	struct hostent *hp;	struct addrinfo *cur;	int error = 0;#ifdef USE_GETIPNODEBY	int h_error;	hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);#else	hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);#endif	if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {		GET_AI(cur, afd, hp->h_addr_list[0], port);		GET_CANONNAME(cur, hp->h_name);	} else		GET_AI(cur, afd, numaddr, port);	#ifdef USE_GETIPNODEBY	if (hp)		freehostent(hp);#endif	*res = cur;	return SUCCESS; free:	if (cur)		freeaddrinfo(cur);#ifdef USE_GETIPNODEBY	if (hp)		freehostent(hp);#endif /* bad: */	*res = NULL;	return error;}static intget_addr(hostname, af, res0, pai, port0)	const char *hostname;	int af;	struct addrinfo **res0;	struct addrinfo *pai;	int port0;{#ifdef USE_GETIPNODEBY	return get_addr0(hostname, af, res0, pai, port0);#else	int i, error, ekeep;	struct addrinfo *cur;	struct addrinfo **res;	int retry;	int s;	res = res0;	ekeep = 0;	error = 0;	for (i = 0; afdl[i].a_af; i++) {		retry = 0;		if (af == AF_UNSPEC) {			/*			 * filter out AFs that are not supported by the kernel			 * XXX errno?			 */			s = socket(afdl[i].a_af, SOCK_DGRAM, 0);			if (s < 0)				continue;			close(s);		} else {			if (af != afdl[i].a_af)				continue;		}		/* It is WRONG, we need getipnodebyname(). */again:		error = get_addr0(hostname, afdl[i].a_af, res, pai, port0);		switch (error) {		case EAI_AGAIN:			if (++retry < 3)				goto again;			/* FALL THROUGH*/		default:			if (ekeep == 0)				ekeep = error;			break;		}		if (*res) {			/* make chain of addrs */			for (cur = *res;			     cur && cur->ai_next;			     cur = cur->ai_next)				;			if (!cur)				return EAI_FAIL;			res = &cur->ai_next;		}	}	/* if we got something, it's okay */	if (*res0)		return 0;	return error ? error : ekeep;#endif}static intget_addr0(hostname, af, res, pai, port0)	const char *hostname;	int af;	struct addrinfo **res;	struct addrinfo *pai;	int port0;{	u_short port = port0 & 0xffff;	struct addrinfo sentinel;	struct hostent *hp;	struct addrinfo *top, *cur;	struct afd *afd;	int i, error = 0, h_error;	char *ap;#ifndef USE_GETIPNODEBY	extern int h_errno;#endif	top = NULL;	sentinel.ai_next = NULL;	cur = &sentinel;#ifdef USE_GETIPNODEBY	if (af == AF_UNSPEC) {		hp = getipnodebyname(hostname, AF_INET6,				AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error);	} else		hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error);#else	if (af == AF_UNSPEC) {		error = EAI_FAIL;		goto bad;	}	hp = gethostbyname2(hostname, af);	h_error = h_errno;#endif	if (hp == NULL) {		switch (h_error) {		case HOST_NOT_FOUND:		case NO_DATA:			error = EAI_NODATA;			break;		case TRY_AGAIN:			error = EAI_AGAIN;			break;		case NO_RECOVERY:		case NETDB_INTERNAL:		default:			error = EAI_FAIL;			break;		}		goto bad;	}	if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||	    (hp->h_addr_list[0] == NULL))		ERR(EAI_FAIL);		for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) {		switch (af) {#ifdef INET6		case AF_INET6:			afd = &afdl[N_INET6];			break;#endif#ifndef INET6		default:	/* AF_UNSPEC */#endif		case AF_INET:			afd = &afdl[N_INET];			break;#ifdef INET6		default:	/* AF_UNSPEC */			if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {				ap += sizeof(struct in6_addr) -					sizeof(struct in_addr);				afd = &afdl[N_INET];			} else				afd = &afdl[N_INET6];			break;#endif		}#ifdef FAITH		if (translate && afd->a_af == AF_INET) {			struct in6_addr *in6;			GET_AI(cur->ai_next, &afdl[N_INET6], ap, port);			in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr;			memcpy(&in6->s6_addr[0], &faith_prefix,			    sizeof(struct in6_addr) - sizeof(struct in_addr));			memcpy(&in6->s6_addr[12], ap, sizeof(struct in_addr));		} else#endif /* FAITH */		GET_AI(cur->ai_next, afd, ap, port);		if (cur == &sentinel) {			top = cur->ai_next;			GET_CANONNAME(top, hp->h_name);		}		cur = cur->ai_next;	}#ifdef USE_GETIPNODEBY	freehostent(hp);#endif	*res = top;	return SUCCESS; free:	if (top)		freeaddrinfo(top);#ifdef USE_GETIPNODEBY	if (hp)		freehostent(hp);#endif bad:	*res = NULL;	return error;}

⌨️ 快捷键说明

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