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

📄 name6.c

📁 Newlib 嵌入式 C库 标准实现代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*	$KAME: name6.c,v 1.25 2000/06/26 16:44:40 itojun Exp $	*//* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* * ++Copyright++ 1985, 1988, 1993 * - * Copyright (c) 1985, 1988, 1993 *    The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: * 	This product includes software developed by the University of * 	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * 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, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION 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. * - * --Copyright-- *//* *	Atsushi Onoe <onoe@sm.sony.co.jp> *//* * TODO for thread safe *	use mutex for _hostconf, _hostconf_init. *	rewrite resolvers to be thread safe */#include <sys/cdefs.h>#include <sys/types.h>#include <machine/endian.h>#include <sys/types.h>#include <unistd.h>#include "namespace.h"#include <sys/param.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/queue.h>#include <netinet/in.h>#include <arpa/inet.h>#include <arpa/nameser.h>#include <errno.h>#include <netdb.h>#include <resolv.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdarg.h>#include <nsswitch.h>#include <unistd.h>#include "un-namespace.h"#ifndef _PATH_HOSTS#define	_PATH_HOSTS	"/etc/hosts"#endif#ifndef MAXALIASES#define	MAXALIASES	35#endif#ifndef	MAXADDRS#define	MAXADDRS	2#endif#ifndef MAXDNAME#define	MAXDNAME	1025#endif#ifdef INET6#define	ADDRLEN(af)	((af) == AF_INET6 ? sizeof(struct in6_addr) : \					    sizeof(struct in_addr))#else#define	ADDRLEN(af)	sizeof(struct in_addr)#endif#define	MAPADDR(ab, ina) \do {									\	memcpy(&(ab)->map_inaddr, ina, sizeof(struct in_addr));		\	memset((ab)->map_zero, 0, sizeof((ab)->map_zero));		\	memset((ab)->map_one, 0xff, sizeof((ab)->map_one));		\} while (0)#define	MAPADDRENABLED(flags) \	(((flags) & AI_V4MAPPED) || \	 (((flags) & AI_V4MAPPED_CFG) && _mapped_addr_enabled()))union inx_addr {	struct in_addr	in_addr;#ifdef INET6	struct in6_addr	in6_addr;#endif	struct {		u_char	mau_zero[10];		u_char	mau_one[2];		struct in_addr mau_inaddr;	}		map_addr_un;#define	map_zero	map_addr_un.mau_zero#define	map_one		map_addr_un.mau_one#define	map_inaddr	map_addr_un.mau_inaddr};u_int16_t _getshort(const u_char *src);static struct	 hostent *_hpcopy(struct hostent *hp, int *errp);static struct	 hostent *_hpaddr(int af, const char *name, void *addr, int *errp);static struct	 hostent *_hpmerge(struct hostent *hp1, struct hostent *hp2, int *errp);#ifdef INET6static struct	 hostent *_hpmapv6(struct hostent *hp, int *errp);#endifstatic struct	 hostent *_hpsort(struct hostent *hp);static struct	 hostent *_ghbyname(const char *name, int af, int flags, int *errp);static char	*_hgetword(char **pp);static int	 _mapped_addr_enabled(void);static FILE	*_files_open(int *errp);static int	 _files_ghbyname(void *, void *, va_list);static int	 _files_ghbyaddr(void *, void *, va_list);#if 0 // keep gcc happystatic void	 _files_shent(int stayopen);static void	 _files_ehent(void);#endif#ifdef YPstatic int	 _nis_ghbyname(void *, void *, va_list);static int	 _nis_ghbyaddr(void *, void *, va_list);#endifstatic int	 _dns_ghbyname(void *, void *, va_list);static int	 _dns_ghbyaddr(void *, void *, va_list);#if 0 // keep gcc happystatic void	 _dns_shent(int stayopen);static void	 _dns_ehent(void);#endif#ifdef ICMPNLstatic int	 _icmp_ghbyaddr(void *, void *, va_list);#endif /* ICMPNL *//* Host lookup order if nsswitch.conf is broken or nonexistant */static const ns_src default_src[] = { 	{ NSSRC_FILES, NS_SUCCESS },	{ NSSRC_DNS, NS_SUCCESS },#ifdef ICMPNL#define NSSRC_ICMP "icmp"	{ NSSRC_ICMP, NS_SUCCESS },#endif	{ 0 }};/* * Check if kernel supports mapped address. *	implementation dependent */#ifdef __KAME__#include <sys/sysctl.h>#endif /* __KAME__ */static int_mapped_addr_enabled(void){	/* implementation dependent check */#if defined(__KAME__) && defined(IPV6CTL_MAPPED_ADDR)	int mib[4];	size_t len;	int val;	mib[0] = CTL_NET;	mib[1] = PF_INET6;	mib[2] = IPPROTO_IPV6;	mib[3] = IPV6CTL_MAPPED_ADDR;	len = sizeof(val);	if (__sysctl(mib, 4, &val, &len, 0, 0) == 0 && val != 0)		return 1;#endif /* __KAME__ && IPV6CTL_MAPPED_ADDR */	return 0;}/* * Functions defined in RFC2553 *	getipnodebyname, getipnodebyaddr, freehostent */static struct hostent *_ghbyname(const char *name, int af, int flags, int *errp){	struct hostent *hp;	int rval;		static const ns_dtab dtab[] = {		NS_FILES_CB(_files_ghbyname, NULL)		{ NSSRC_DNS, _dns_ghbyname, NULL },		NS_NIS_CB(_nis_ghbyname, NULL)		{ 0 }	};	if (flags & AI_ADDRCONFIG) {		int s;		/*		 * TODO:		 * Note that implementation dependent test for address		 * configuration should be done everytime called		 * (or apropriate interval),		 * because addresses will be dynamically assigned or deleted.		 */		if (af == AF_UNSPEC) {			if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)				af = AF_INET;			else {				close(s);				if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)					af = AF_INET6;				else				close(s);			}		}		if (af != AF_UNSPEC) {			if ((s = socket(af, SOCK_DGRAM, 0)) < 0)				return NULL;			close(s);		}	}	rval = nsdispatch(&hp, dtab, NSDB_HOSTS, "ghbyname", default_src,			  name, af, errp);	return (rval == NS_SUCCESS) ? hp : NULL;}/* getipnodebyname() internal routine for multiple query(PF_UNSPEC) support. */struct hostent *_getipnodebyname_multi(const char *name, int af, int flags, int *errp){	struct hostent *hp;	union inx_addr addrbuf;	/* XXX: PF_UNSPEC is only supposed to be passed from getaddrinfo() */	if (af != AF_INET#ifdef INET6	    && af != AF_INET6#endif	    && af != PF_UNSPEC		)	{		*errp = NO_RECOVERY;		return NULL;	}#ifdef INET6	/* special case for literal address */	if (inet_pton(AF_INET6, name, &addrbuf) == 1) {		if (af != AF_INET6) {			*errp = HOST_NOT_FOUND;			return NULL;		}		return _hpaddr(af, name, &addrbuf, errp);	}#endif	if (inet_aton(name, (struct in_addr *)&addrbuf) == 1) {		if (af != AF_INET) {			if (MAPADDRENABLED(flags)) {				MAPADDR(&addrbuf, &addrbuf.in_addr);			} else {				*errp = HOST_NOT_FOUND;				return NULL;			}		}		return _hpaddr(af, name, &addrbuf, errp);	}	*errp = HOST_NOT_FOUND;	hp = _ghbyname(name, af, flags, errp);#ifdef INET6	if (af == AF_INET6	&&  ((flags & AI_ALL) || hp == NULL)	&&  (MAPADDRENABLED(flags))) {		struct hostent *hp2 = _ghbyname(name, AF_INET, flags, errp);		if (hp == NULL)			hp = _hpmapv6(hp2, errp);		else {			if (hp2 && strcmp(hp->h_name, hp2->h_name) != 0) {				freehostent(hp2);				hp2 = NULL;			}			hp = _hpmerge(hp, hp2, errp);		}	}#endif	return _hpsort(hp);}struct hostent *getipnodebyname(const char *name, int af, int flags, int *errp){	if (af != AF_INET#ifdef INET6	    && af != AF_INET6#endif		)	{		*errp = NO_RECOVERY;		return NULL;	}	return(_getipnodebyname_multi(name, af ,flags, errp));}struct hostent *getipnodebyaddr(const void *src, size_t len, int af, int *errp){	struct hostent *hp;	int rval;#ifdef INET6	struct in6_addr addrbuf;#else	struct in_addr addrbuf;#endif	static const ns_dtab dtab[] = {		NS_FILES_CB(_files_ghbyaddr, NULL)		{ NSSRC_DNS, _dns_ghbyaddr, NULL },		NS_NIS_CB(_nis_ghbyaddr, NULL)#ifdef ICMPNL		{ NSSRC_ICMP, _icmp_ghbyaddr, NULL },#endif		{ 0 }	};	*errp = HOST_NOT_FOUND;	switch (af) {	case AF_INET:		if (len != sizeof(struct in_addr)) {			*errp = NO_RECOVERY;			return NULL;		}		if ((long)src & ~(sizeof(struct in_addr) - 1)) {			memcpy(&addrbuf, src, len);			src = &addrbuf;		}		if (((struct in_addr *)src)->s_addr == 0)			return NULL;		break;#ifdef INET6	case AF_INET6:		if (len != sizeof(struct in6_addr)) {			*errp = NO_RECOVERY;			return NULL;		}		if ((long)src & ~(sizeof(struct in6_addr) / 2 - 1)) {	/*XXX*/			memcpy(&addrbuf, src, len);			src = &addrbuf;		}		if (IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *)src))			return NULL;		if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)src)		||  IN6_IS_ADDR_V4COMPAT((struct in6_addr *)src)) {			src = (char *)src +			    (sizeof(struct in6_addr) - sizeof(struct in_addr));			af = AF_INET;			len = sizeof(struct in_addr);		}		break;#endif	default:		*errp = NO_RECOVERY;		return NULL;	}	rval = nsdispatch(&hp, dtab, NSDB_HOSTS, "ghbyaddr", default_src,			  src, len, af, errp);	return (rval == NS_SUCCESS) ? hp : NULL;}voidfreehostent(struct hostent *ptr){	free(ptr);}#if 0/* XXX: should be deprecated */struct hostent *getnodebyname(const char *name, int af, int flags){	return getipnodebyname(name, af, flags, &h_errno);}#ifdef __warn_references__warn_references(getnodebyname,	"warning: getnodebyname() deprecated, "	"should use getaddrinfo() or getipnodebyname()");#endifstruct hostent *getnodebyaddr(const void *src, size_t len, int af){	return getipnodebyaddr(src, len, af, &h_errno);}#ifdef __warn_references__warn_references(getnodebyaddr,	"warning: getnodebyaddr() deprecated, "	"should use getnameinfo() or getipnodebyaddr()");#endif#endif/* * Private utility functions *//* * _hpcopy: allocate and copy hostent structure */static struct hostent *_hpcopy(struct hostent *hp, int *errp){	struct hostent *nhp;	char *cp, **pp;	int size, addrsize;	int nalias = 0, naddr = 0;	int al_off;	int i;	if (hp == NULL)		return hp;	/* count size to be allocated */	size = sizeof(struct hostent);	if (hp->h_name != NULL)		size += strlen(hp->h_name) + 1;	if ((pp = hp->h_aliases) != NULL) {		for (i = 0; *pp != NULL; i++, pp++) {			if (**pp != '\0') {				size += strlen(*pp) + 1;				nalias++;			}		}	}	/* adjust alignment */#ifdef	ALIGN	size = ALIGN(size);#endif	al_off = size;	size += sizeof(char *) * (nalias + 1);#ifdef ALIGN	addrsize = ALIGN(hp->h_length);#else	addrsize = hp->h_length;#endif        	if ((pp = hp->h_addr_list) != NULL) {		while (*pp++ != NULL)			naddr++;	}	size += addrsize * naddr;	size += sizeof(char *) * (naddr + 1);	/* copy */	if ((nhp = (struct hostent *)malloc(size)) == NULL) {		*errp = TRY_AGAIN;		return NULL;	}	cp = (char *)&nhp[1];	if (hp->h_name != NULL) {		nhp->h_name = cp;		strcpy(cp, hp->h_name);		cp += strlen(cp) + 1;	} else		nhp->h_name = NULL;	nhp->h_aliases = (char **)((char *)nhp + al_off);	if ((pp = hp->h_aliases) != NULL) {		for (i = 0; *pp != NULL; pp++) {			if (**pp != '\0') {				nhp->h_aliases[i++] = cp;				strcpy(cp, *pp);				cp += strlen(cp) + 1;			}		}	}	nhp->h_aliases[nalias] = NULL;	cp = (char *)&nhp->h_aliases[nalias + 1];	nhp->h_addrtype = hp->h_addrtype;	nhp->h_length = hp->h_length;	nhp->h_addr_list = (char **)cp;	if ((pp = hp->h_addr_list) != NULL) {		cp = (char *)&nhp->h_addr_list[naddr + 1];		for (i = 0; *pp != NULL; pp++) {			nhp->h_addr_list[i++] = cp;			memcpy(cp, *pp, hp->h_length);			cp += addrsize;		}	}	nhp->h_addr_list[naddr] = NULL;	return nhp;}/* * _hpaddr: construct hostent structure with one address */static struct hostent *_hpaddr(int af, const char *name, void *addr, int *errp){	struct hostent *hp, hpbuf;	char *addrs[2];	hp = &hpbuf;	hp->h_name = (char *)name;	hp->h_aliases = NULL;	hp->h_addrtype = af;	hp->h_length = ADDRLEN(af);	hp->h_addr_list = addrs;	addrs[0] = (char *)addr;	addrs[1] = NULL;	return _hpcopy(hp, errp);}/* * _hpmerge: merge 2 hostent structure, arguments will be freed */static struct hostent *_hpmerge(struct hostent *hp1, struct hostent *hp2, int *errp){	int i, j;	int naddr, nalias;	char **pp;	struct hostent *hp, hpbuf;	char *aliases[MAXALIASES + 1], *addrs[MAXADDRS + 1];	union inx_addr addrbuf[MAXADDRS];	if (hp1 == NULL)		return hp2;	if (hp2 == NULL)		return hp1;#define	HP(i)	(i == 1 ? hp1 : hp2)	hp = &hpbuf;	hp->h_name = (hp1->h_name != NULL ? hp1->h_name : hp2->h_name);

⌨️ 快捷键说明

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