getaddrinfo.c
来自「eCos操作系统源码」· C语言 代码 · 共 528 行 · 第 1/2 页
C
528 行
//==========================================================================//// lib/getaddrinfo.c//// getaddrinfo(), freeaddrinfo(), gai_strerror(), getnameinfo()////==========================================================================//####ECOSPDCOPYRIGHTBEGIN####//// Copyright (C) 2000, 2001, 2002 Red Hat, Inc.// Copyright (C) 2003 Gary Thomas// Copyright (C) 2003 andrew.lunn@ascom.ch// All Rights Reserved.//// Permission is granted to use, copy, modify and redistribute this// file.////####ECOSPDCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): gthomas// Contributors: gthomas, andrew.lunn@ascom.ch// Date: 2002-03-05// Purpose: // Description: // ////####DESCRIPTIONEND####////==========================================================================#include <sys/param.h>#include <sys/socket.h> // PF_xxx#include <netinet/in.h> // IPPROTO_xx#include <net/netdb.h>#include <netdb.h> // DNS support routines#include <errno.h>#include <cyg/infra/cyg_ass.h>#include <pkgconf/system.h>#ifdef CYGPKG_NS_DNS#include <pkgconf/ns_dns.h>#ifdef CYGPKG_NS_DNS_BUILD#include <cyg/ns/dns/dns.h>#endif#endifextern int sprintf(char *, const char *, ...);extern long strtol(const char *, char **, int);extern void *malloc(size_t);extern void *calloc(int, size_t);extern void free(void *);// Allocate a new addrinfo structure and if passed an existing// addrinfo copy all the port, protocol info into the new structure// and then link the new onto the old.struct addrinfo * alloc_addrinfo(struct addrinfo * ai) { struct addrinfo * nai; struct sockaddr * sa; nai = (struct addrinfo *)malloc(sizeof(struct addrinfo)); if (!nai) { return NULL; } sa = (struct sockaddr *) malloc(sizeof(struct sockaddr)); if (!sa) { free (nai); return NULL; } memset(sa,0,sizeof(*sa)); if (ai) { memcpy(nai,ai,sizeof(struct addrinfo)); ai->ai_next = nai; } else { memset(nai,0,sizeof(*nai)); } nai->ai_addr = sa; nai->ai_addrlen = sizeof(*sa); return nai;}// getaddrinfo has not been passed a hostname. So it should use the// loopback or the any address.static intno_node_addr(struct addrinfo *ai, const struct addrinfo *hints, int port) { switch (hints->ai_family) { case AF_INET: { struct sockaddr_in *sa = (struct sockaddr_in *) ai->ai_addr; if (hints->ai_flags & AI_PASSIVE) { sa->sin_addr.s_addr = htonl(INADDR_ANY); } else { sa->sin_addr.s_addr = htonl(INADDR_LOOPBACK); } sa->sin_len = sizeof(*sa); sa->sin_port = htons(port); sa->sin_family = AF_INET; ai->ai_family = AF_INET; break; }#ifdef CYGPKG_NET_INET6 case AF_INET6: { struct sockaddr_in6 *sa = (struct sockaddr_in6 *) ai->ai_addr; if (hints->ai_flags & AI_PASSIVE) { memcpy(&sa->sin6_addr, &in6addr_any, sizeof(sa->sin6_addr)); } else { memcpy(&sa->sin6_addr, &in6addr_loopback, sizeof(sa->sin6_addr)); } sa->sin6_len = sizeof(*sa); sa->sin6_port = htons(port); sa->sin6_family = AF_INET6; ai->ai_family = AF_INET6; break; }#endif case PF_UNSPEC: { struct sockaddr_in *sa = (struct sockaddr_in *) ai->ai_addr; if (hints->ai_flags & AI_PASSIVE) { sa->sin_addr.s_addr = htonl(INADDR_ANY); } else { sa->sin_addr.s_addr = htonl(INADDR_LOOPBACK); } sa->sin_len = sizeof(*sa); sa->sin_port = htons(port); sa->sin_family = AF_INET; ai->ai_family = AF_INET;#ifdef CYGPKG_NET_INET6 { struct sockaddr_in6 *sa6; ai=alloc_addrinfo(ai); if (ai == NULL) { return EAI_MEMORY; } sa6 = (struct sockaddr_in6 *) ai->ai_addr; if (hints->ai_flags & AI_PASSIVE) { memcpy(&sa6->sin6_addr, &in6addr_any, sizeof(sa6->sin6_addr)); } else { memcpy(&sa6->sin6_addr, &in6addr_loopback, sizeof(sa6->sin6_addr)); } sa6->sin6_len = sizeof(*sa); sa6->sin6_port = htons(port); sa6->sin6_family = AF_INET6; ai->ai_family = AF_INET6; }#endif break; } } return EAI_NONE;}// We have been asked to convert only numeric addresses so as to not// need a DNS server query.static intnumeric_node_addr(struct addrinfo *ai, const char *node, const struct addrinfo *hints, int port) { switch (hints->ai_family) { case AF_INET: { struct sockaddr_in *sa = (struct sockaddr_in *) ai->ai_addr; if (!inet_pton(AF_INET, node, (void *)&sa->sin_addr.s_addr)) { return EAI_FAIL; } sa->sin_port = htons(port); sa->sin_family = AF_INET; sa->sin_len = sizeof(*sa); ai->ai_family = AF_INET; break; }#ifdef CYGPKG_NET_INET6 case AF_INET6: { struct sockaddr_in6 *sa = (struct sockaddr_in6 *) ai->ai_addr; if (!inet_pton(AF_INET6, node, (void *)&sa->sin6_addr.s6_addr)) { return EAI_FAIL; } sa->sin6_port = htons(port); sa->sin6_family = AF_INET6; sa->sin6_len = sizeof(*sa); ai->ai_family = AF_INET6; break; }#endif case PF_UNSPEC: { struct sockaddr_in *sa = (struct sockaddr_in *) ai->ai_addr; sa->sin_len = sizeof(*sa); sa->sin_port = htons(port); sa->sin_family = AF_INET; ai->ai_family = AF_INET; if (inet_pton(AF_INET, node, (void *)&sa->sin_addr.s_addr)) { return EAI_NONE; }#ifdef CYGPKG_NET_INET6 { struct sockaddr_in6 *sa = (struct sockaddr_in6 *) ai->ai_addr; sa->sin6_len = sizeof(*sa); sa->sin6_port = htons(port); sa->sin6_family = AF_INET6; ai->ai_family = AF_INET6; if (inet_pton(AF_INET6, node, (void *)&sa->sin6_addr.s6_addr)) { return EAI_NONE; } }#endif return EAI_FAIL; break; } } return EAI_NONE;}// We have a host name. Use the DNS client to perform a lookup. If the// DNS client is not part of the configuration try using the numeric// convertion.static intwith_node_addr(struct addrinfo *ai, const char *node, const struct addrinfo *hints, int port) { #ifdef CYGPKG_NS_DNS_BUILD struct sockaddr addrs[CYGNUM_NS_DNS_GETADDRINFO_ADDRESSES]; int nresults; int i; char ** canon = NULL; if (hints->ai_flags & AI_CANONNAME) { canon = &ai->ai_canonname; } nresults = cyg_dns_getaddrinfo(node, addrs, CYGNUM_NS_DNS_GETADDRINFO_ADDRESSES, hints->ai_family, canon); if (nresults < 0) { return -nresults; } for (i=0; i < nresults; i++) { if (i != 0) { ai = alloc_addrinfo(ai); if (ai == NULL) { return EAI_MEMORY; } } memcpy(ai->ai_addr, &addrs[i], sizeof(addrs[i])); ai->ai_family = addrs[i].sa_family; ai->ai_addrlen = addrs[i].sa_len; switch (ai->ai_family) { case AF_INET: { struct sockaddr_in *sa = (struct sockaddr_in *) ai->ai_addr; sa->sin_port = htons(port); break; }#ifdef CYGPKG_NET_INET6 case AF_INET6: { struct sockaddr_in6 *sa = (struct sockaddr_in6 *) ai->ai_addr; sa->sin6_port = htons(port); break; }#endif } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?