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

📄 getaddrinfo.c

📁 Linux 2.6 内核上配置IPSec VPN 的工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 1995, 1996, 1997, and 1998 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. *//* * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator. * * Issues to be discussed: * - Thread safe-ness must be checked. * - Return values.  There are nonstandard return values defined and used *   in the source code.  This is because RFC2553 is silent about which error *   code must be returned for which situation. * - PF_UNSPEC case would be handled in getipnodebyname() with the AI_ALL flag. */#include <sys/types.h>#include <sys/param.h>#include <sys/sysctl.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <arpa/nameser.h>#include <netdb.h>#include <resolv.h>#include <string.h>#include <stdlib.h>#include <stddef.h>#include <ctype.h>#include <unistd.h>#include "missing/addrinfo.h"#if defined(__KAME__) && defined(INET6)# define FAITH#endif#define SUCCESS 0#define ANY 0#define YES 1#define NO  0#ifdef FAITHstatic int translate = NO;static struct in6_addr faith_prefix = IN6ADDR_ANY_INIT;#endifstatic const char in_addrany[] = { 0, 0, 0, 0 };static const char in6_addrany[] = {	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};static const char in_loopback[] = { 127, 0, 0, 1 }; static const char in6_loopback[] = {	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};struct sockinet {	u_char	si_len;	u_char	si_family;	u_short	si_port;};static struct afd {	int a_af;	int a_addrlen;	int a_socklen;	int a_off;	const char *a_addrany;	const char *a_loopback;	} afdl [] = {#ifdef INET6#define N_INET6 0	{PF_INET6, sizeof(struct in6_addr),	 sizeof(struct sockaddr_in6),	 offsetof(struct sockaddr_in6, sin6_addr),	 in6_addrany, in6_loopback},#define N_INET  1#else#define N_INET  0#endif	{PF_INET, sizeof(struct in_addr),	 sizeof(struct sockaddr_in),	 offsetof(struct sockaddr_in, sin_addr),	 in_addrany, in_loopback},	{0, 0, 0, 0, NULL, NULL},};#ifdef INET6#define PTON_MAX	16#else#define PTON_MAX	4#endifstatic int get_name __P((const char *, struct afd *,			  struct addrinfo **, char *, struct addrinfo *,			  int));static int get_addr __P((const char *, int, struct addrinfo **,			struct addrinfo *, int));static int get_addr0 __P((const char *, int, struct addrinfo **,			struct addrinfo *, int));static int str_isnumber __P((const char *));	static char *ai_errlist[] = {	"Success",	"Address family for hostname not supported",	/* EAI_ADDRFAMILY */	"Temporary failure in name resolution",		/* EAI_AGAIN      */	"Invalid value for ai_flags",		       	/* EAI_BADFLAGS   */	"Non-recoverable failure in name resolution", 	/* EAI_FAIL       */	"ai_family not supported",			/* EAI_FAMILY     */	"Memory allocation failure", 			/* EAI_MEMORY     */	"No address associated with hostname", 		/* EAI_NODATA     */	"hostname nor servname provided, or not known",/* EAI_NONAME     */	"servname not supported for ai_socktype",	/* EAI_SERVICE    */	"ai_socktype not supported", 			/* EAI_SOCKTYPE   */	"System error returned in errno", 		/* EAI_SYSTEM     */	"Invalid value for hints",			/* EAI_BADHINTS	  */	"Resolved protocol is unknown",			/* EAI_PROTOCOL   */	"Unknown error", 				/* EAI_MAX        */};#define GET_CANONNAME(ai, str) \if (pai->ai_flags & AI_CANONNAME) {\	if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\		strcpy((ai)->ai_canonname, (str));\	} else {\		error = EAI_MEMORY;\		goto free;\	}\}#define GET_AI(ai, afd, addr, port) {\	char *p;\	if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\					      ((afd)->a_socklen)))\	    == NULL) {\		error = EAI_MEMORY;\		goto free;\	}\	memcpy(ai, pai, sizeof(struct addrinfo));\	(ai)->ai_addr = (struct sockaddr *)((ai) + 1);\	memset((ai)->ai_addr, 0, (afd)->a_socklen);\	(ai)->ai_addr->sa_len = (ai)->ai_addrlen = (afd)->a_socklen;\	(ai)->ai_addr->sa_family = (ai)->ai_family = (afd)->a_af;\	((struct sockinet *)(ai)->ai_addr)->si_port = port;\	p = (char *)((ai)->ai_addr);\	memcpy(p + (afd)->a_off, (addr), (afd)->a_addrlen);\}#define ERR(err) { error = (err); goto bad; }char *gai_strerror(ecode)	int ecode;{	if (ecode < 0 || ecode > EAI_MAX)		ecode = EAI_MAX;	return ai_errlist[ecode];}voidfreeaddrinfo(ai)	struct addrinfo *ai;{	struct addrinfo *next;	do {		next = ai->ai_next;		if (ai->ai_canonname)			free(ai->ai_canonname);		/* no need to free(ai->ai_addr) */		free(ai);	} while ((ai = next) != NULL);}static intstr_isnumber(p)	const char *p;{	char *q = (char *)p;	while (*q) {		if (! isdigit(*q))			return NO;		q++;	}	return YES;}intgetaddrinfo(hostname, servname, hints, res)	const char *hostname, *servname;	const struct addrinfo *hints;	struct addrinfo **res;{	struct addrinfo sentinel;	struct addrinfo *top = NULL;	struct addrinfo *cur;	int i, error = 0;	char pton[PTON_MAX];	struct addrinfo ai;	struct addrinfo *pai;	u_short port;#ifdef FAITH	static int firsttime = 1;	if (firsttime) {		/* translator hack */		{			char *q = getenv("GAI");			if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1)				translate = YES;		}		firsttime = 0;	}#endif	/* initialize file static vars */	sentinel.ai_next = NULL;	cur = &sentinel;	pai = &ai;	pai->ai_flags = 0;	pai->ai_family = PF_UNSPEC;	pai->ai_socktype = ANY;	pai->ai_protocol = ANY;	pai->ai_addrlen = 0;	pai->ai_canonname = NULL;	pai->ai_addr = NULL;	pai->ai_next = NULL;	port = ANY;		if (hostname == NULL && servname == NULL)		return EAI_NONAME;	if (hints) {		/* error check for hints */		if (hints->ai_addrlen || hints->ai_canonname ||		    hints->ai_addr || hints->ai_next)			ERR(EAI_BADHINTS); /* xxx */		if (hints->ai_flags & ~AI_MASK)			ERR(EAI_BADFLAGS);		switch (hints->ai_family) {		case PF_UNSPEC:		case PF_INET:#ifdef INET6		case PF_INET6:#endif			break;		default:			ERR(EAI_FAMILY);		}		memcpy(pai, hints, sizeof(*pai));		switch (pai->ai_socktype) {		case ANY:			switch (pai->ai_protocol) {			case ANY:				break;			case IPPROTO_UDP:				pai->ai_socktype = SOCK_DGRAM;				break;			case IPPROTO_TCP:				pai->ai_socktype = SOCK_STREAM;				break;			default:				pai->ai_socktype = SOCK_RAW;				break;			}			break;		case SOCK_RAW:			break;		case SOCK_DGRAM:			if (pai->ai_protocol != IPPROTO_UDP &&			    pai->ai_protocol != ANY)				ERR(EAI_BADHINTS);	/*xxx*/			pai->ai_protocol = IPPROTO_UDP;			break;		case SOCK_STREAM:			if (pai->ai_protocol != IPPROTO_TCP &&			    pai->ai_protocol != ANY)				ERR(EAI_BADHINTS);	/*xxx*/			pai->ai_protocol = IPPROTO_TCP;			break;		default:			ERR(EAI_SOCKTYPE);			break;		}	}	/*	 * service port	 */	if (servname) {		if (str_isnumber(servname)) {			if (pai->ai_socktype == ANY) {				/* caller accept *ANY* socktype */				pai->ai_socktype = SOCK_DGRAM;				pai->ai_protocol = IPPROTO_UDP;			}			port = htons(atoi(servname));		} else {			struct servent *sp;			char *proto;			proto = NULL;			switch (pai->ai_socktype) {			case ANY:				proto = NULL;				break;			case SOCK_DGRAM:				proto = "udp";				break;			case SOCK_STREAM:				proto = "tcp";				break;			default:				fprintf(stderr, "panic!\n");				break;			}			if ((sp = getservbyname(servname, proto)) == NULL)				ERR(EAI_SERVICE);			port = sp->s_port;			if (pai->ai_socktype == ANY) {				if (strcmp(sp->s_proto, "udp") == 0) {					pai->ai_socktype = SOCK_DGRAM;					pai->ai_protocol = IPPROTO_UDP;				} else if (strcmp(sp->s_proto, "tcp") == 0) {

⌨️ 快捷键说明

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