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

📄 getaddrinfo.c

📁 libcap是一个在linux下的抓包工具
💻 C
📖 第 1 页 / 共 2 页
字号:
		return 0;	hp = gethostbyname(hostname);#ifdef HAVE_H_ERRNO	h_error = h_errno;#else	h_error = EINVAL;#endif#endif /*HAVE_GETHOSTBYNAME2*/#endif /*USE_GETIPNODEBY*/	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;		}	} else if ((hp->h_name == NULL) || (hp->h_name[0] == 0)			|| (hp->h_addr_list[0] == NULL)) {#ifdef USE_GETIPNODEBY		freehostent(hp);#endif		hp = NULL;		error = EAI_FAIL;	}	if (hp == NULL)		goto free;#ifdef USE_GETIPNODEBY	aplist = hp->h_addr_list;#else	/*	 * hp will be overwritten if we use gethostbyname2().	 * always deep copy for simplification.	 */	for (naddrs = 0; hp->h_addr_list[naddrs] != NULL; naddrs++)		;	naddrs++;	aplist = (char **)malloc(sizeof(aplist[0]) * naddrs);	apbuf = (char *)malloc(hp->h_length * naddrs);	if (aplist == NULL || apbuf == NULL) {		error = EAI_MEMORY;		goto free;	}	memset(aplist, 0, sizeof(aplist[0]) * naddrs);	for (i = 0; i < naddrs; i++) {		if (hp->h_addr_list[i] == NULL) {			aplist[i] = NULL;			continue;		}		memcpy(&apbuf[i * hp->h_length], hp->h_addr_list[i],			hp->h_length);		aplist[i] = &apbuf[i * hp->h_length];	}#endif	for (i = 0; aplist[i] != NULL; i++) {		af = hp->h_addrtype;		ap = aplist[i];#ifdef AF_INET6		if (af == AF_INET6		 && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {			af = AF_INET;			ap = ap + sizeof(struct in6_addr)				- sizeof(struct in_addr);		}#endif		if (af != pai->ai_family)			continue;		if ((pai->ai_flags & AI_CANONNAME) == 0) {			GET_AI(cur->ai_next, afd, ap);			GET_PORT(cur->ai_next, servname);		} else {			/*			 * 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(ap, afd, &cur->ai_next,				ap, pai, servname);		}		while (cur && cur->ai_next)			cur = cur->ai_next;	}	*res = sentinel.ai_next;	return 0;free:#ifdef USE_GETIPNODEBY	if (hp)		freehostent(hp);#endif	if (aplist)		free(aplist);	if (apbuf)		free(apbuf);	if (sentinel.ai_next)		freeaddrinfo(sentinel.ai_next);	return error;}/* * hostname == NULL. * passive socket -> anyaddr (0.0.0.0 or ::) * non-passive socket -> localhost (127.0.0.1 or ::1) */static intexplore_null(pai, hostname, servname, res)	const struct addrinfo *pai;	const char *hostname;	const char *servname;	struct addrinfo **res;{	int s;	const struct afd *afd;	struct addrinfo *cur;	struct addrinfo sentinel;	int error;	*res = NULL;	sentinel.ai_next = NULL;	cur = &sentinel;	/*	 * filter out AFs that are not supported by the kernel	 * XXX errno?	 */	s = socket(pai->ai_family, SOCK_DGRAM, 0);	if (s < 0) {		if (errno != EMFILE)			return 0;	} else		close(s);	/*	 * if the servname does not match socktype/protocol, ignore it.	 */	if (get_portmatch(pai, servname) != 0)		return 0;	afd = find_afd(pai->ai_family);	if (pai->ai_flags & AI_PASSIVE) {		GET_AI(cur->ai_next, afd, afd->a_addrany);		/* xxx meaningless?		 * GET_CANONNAME(cur->ai_next, "anyaddr");		 */		GET_PORT(cur->ai_next, servname);	} else {		GET_AI(cur->ai_next, afd, afd->a_loopback);		/* xxx meaningless?		 * GET_CANONNAME(cur->ai_next, "localhost");		 */		GET_PORT(cur->ai_next, servname);	}	cur = cur->ai_next;	*res = sentinel.ai_next;	return 0;free:	if (sentinel.ai_next)		freeaddrinfo(sentinel.ai_next);	return error;}/* * numeric hostname */static intexplore_numeric(pai, hostname, servname, res)	const struct addrinfo *pai;	const char *hostname;	const char *servname;	struct addrinfo **res;{	const struct afd *afd;	struct addrinfo *cur;	struct addrinfo sentinel;	int error;	char pton[PTON_MAX];	int flags;	*res = NULL;	sentinel.ai_next = NULL;	cur = &sentinel;	/*	 * if the servname does not match socktype/protocol, ignore it.	 */	if (get_portmatch(pai, servname) != 0)		return 0;	afd = find_afd(pai->ai_family);	flags = pai->ai_flags;	if (inet_pton(afd->a_af, hostname, pton) == 1) {		u_int32_t v4a;#ifdef INET6		u_char pfx;#endif		switch (afd->a_af) {		case AF_INET:			v4a = (u_int32_t)ntohl(((struct in_addr *)pton)->s_addr);			if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))				flags &= ~AI_CANONNAME;			v4a >>= IN_CLASSA_NSHIFT;			if (v4a == 0 || v4a == IN_LOOPBACKNET)				flags &= ~AI_CANONNAME;			break;#ifdef INET6		case AF_INET6:			pfx = ((struct in6_addr *)pton)->s6_addr[0];			if (pfx == 0 || pfx == 0xfe || pfx == 0xff)				flags &= ~AI_CANONNAME;			break;#endif		}		if (pai->ai_family == afd->a_af ||		    pai->ai_family == PF_UNSPEC /*?*/) {			if ((flags & AI_CANONNAME) == 0) {				GET_AI(cur->ai_next, afd, pton);				GET_PORT(cur->ai_next, servname);			} else {				/*				 * 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, afd, &cur->ai_next,					pton, pai, servname);			}			while (cur && cur->ai_next)				cur = cur->ai_next;		} else 			ERR(EAI_FAMILY);	/*xxx*/	}	*res = sentinel.ai_next;	return 0;free:bad:	if (sentinel.ai_next)		freeaddrinfo(sentinel.ai_next);	return error;}/* * numeric hostname with scope */static intexplore_numeric_scope(pai, hostname, servname, res)	const struct addrinfo *pai;	const char *hostname;	const char *servname;	struct addrinfo **res;{#ifndef SCOPE_DELIMITER	return explore_numeric(pai, hostname, servname, res);#else	const struct afd *afd;	struct addrinfo *cur;	int error;	char *cp, *hostname2 = NULL;	int scope;	struct sockaddr_in6 *sin6;	/*	 * if the servname does not match socktype/protocol, ignore it.	 */	if (get_portmatch(pai, servname) != 0)		return 0;	afd = find_afd(pai->ai_family);	if (!afd->a_scoped)		return explore_numeric(pai, hostname, servname, res);	cp = strchr(hostname, SCOPE_DELIMITER);	if (cp == NULL)		return explore_numeric(pai, hostname, servname, res);	/*	 * Handle special case of <scoped_address><delimiter><scope id>	 */	hostname2 = strdup(hostname);	if (hostname2 == NULL)		return EAI_MEMORY;	/* terminate at the delimiter */	hostname2[cp - hostname] = '\0';	cp++;	switch (pai->ai_family) {#ifdef INET6	case AF_INET6:		scope = if_nametoindex(cp);		if (scope == 0) {			free(hostname2);			return (EAI_NONAME);		}		break;#endif	}	error = explore_numeric(pai, hostname2, servname, res);	if (error == 0) {		for (cur = *res; cur; cur = cur->ai_next) {			if (cur->ai_family != AF_INET6)				continue;			sin6 = (struct sockaddr_in6 *)cur->ai_addr;			if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||			    IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr))				sin6->sin6_scope_id = scope;		}	}	free(hostname2);	return error;#endif}static intget_name(addr, afd, res, numaddr, pai, servname)	const char *addr;	const struct afd *afd;	struct addrinfo **res;	char *numaddr;	const struct addrinfo *pai;	const char *servname;{	struct hostent *hp = NULL;	struct addrinfo *cur = NULL;	int error = 0;	char *ap = NULL, *cn = NULL;#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]) {#ifdef USE_GETIPNODEBY		GET_AI(cur, afd, hp->h_addr_list[0]);		GET_PORT(cur, servname);		GET_CANONNAME(cur, hp->h_name);#else		/* hp will be damaged if we use gethostbyaddr() */		if ((ap = (char *)malloc(hp->h_length)) == NULL) {			error = EAI_MEMORY;			goto free;		}		memcpy(ap, hp->h_addr_list[0], hp->h_length);		if ((cn = strdup(hp->h_name)) == NULL) {			error = EAI_MEMORY;			goto free;		}		GET_AI(cur, afd, ap);		GET_PORT(cur, servname);		GET_CANONNAME(cur, cn);		free(ap); ap = NULL;		free(cn); cn = NULL;#endif	} else {		GET_AI(cur, afd, numaddr);		GET_PORT(cur, servname);	}	#ifdef USE_GETIPNODEBY	if (hp)		freehostent(hp);#endif	*res = cur;	return SUCCESS; free:	if (cur)		freeaddrinfo(cur);	if (ap)		free(ap);	if (cn)		free(cn);#ifdef USE_GETIPNODEBY	if (hp)		freehostent(hp);#endif	*res = NULL;	return error;}static intget_canonname(pai, ai, str)	const struct addrinfo *pai;	struct addrinfo *ai;	const char *str;{	if ((pai->ai_flags & AI_CANONNAME) != 0) {		ai->ai_canonname = (char *)malloc(strlen(str) + 1);		if (ai->ai_canonname == NULL)			return EAI_MEMORY;		strcpy(ai->ai_canonname, str);	}	return 0;}static struct addrinfo *get_ai(pai, afd, addr)	const struct addrinfo *pai;	const struct afd *afd;	const char *addr;{	char *p;	struct addrinfo *ai;	ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)		+ (afd->a_socklen));	if (ai == NULL)		return NULL;	memcpy(ai, pai, sizeof(struct addrinfo));	ai->ai_addr = (struct sockaddr *)(ai + 1);	memset(ai->ai_addr, 0, afd->a_socklen);#ifdef HAVE_SOCKADDR_SA_LEN	ai->ai_addr->sa_len = afd->a_socklen;#endif	ai->ai_addrlen = afd->a_socklen;	ai->ai_addr->sa_family = ai->ai_family = afd->a_af;	p = (char *)(ai->ai_addr);	memcpy(p + afd->a_off, addr, afd->a_addrlen);	return ai;}static intget_portmatch(ai, servname)	const struct addrinfo *ai;	const char *servname;{	/* get_port does not touch first argument. when matchonly == 1. */	return get_port((struct addrinfo *)ai, servname, 1);}static intget_port(ai, servname, matchonly)	struct addrinfo *ai;	const char *servname;	int matchonly;{	const char *proto;	struct servent *sp;	int port;	int allownumeric;	if (servname == NULL)		return 0;	switch (ai->ai_family) {	case AF_INET:#ifdef AF_INET6	case AF_INET6:#endif		break;	default:		return 0;	}	switch (ai->ai_socktype) {	case SOCK_RAW:		return EAI_SERVICE;	case SOCK_DGRAM:	case SOCK_STREAM:		allownumeric = 1;		break;	case ANY:		allownumeric = 0;		break;	default:		return EAI_SOCKTYPE;	}	if (str_isnumber(servname)) {		if (!allownumeric)			return EAI_SERVICE;		port = htons(atoi(servname));		if (port < 0 || port > 65535)			return EAI_SERVICE;	} else {		switch (ai->ai_socktype) {		case SOCK_DGRAM:			proto = "udp";			break;		case SOCK_STREAM:			proto = "tcp";			break;		default:			proto = NULL;			break;		}		if ((sp = getservbyname(servname, proto)) == NULL)			return EAI_SERVICE;		port = sp->s_port;	}	if (!matchonly) {		switch (ai->ai_family) {		case AF_INET:			((struct sockaddr_in *)ai->ai_addr)->sin_port = port;			break;#ifdef INET6		case AF_INET6:			((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = port;			break;#endif		}	}	return 0;}static const struct afd *find_afd(af)	int af;{	const struct afd *afd;	if (af == PF_UNSPEC)		return NULL;	for (afd = afdl; afd->a_af; afd++) {		if (afd->a_af == af)			return afd;	}	return NULL;}

⌨️ 快捷键说明

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