📄 getaddrinfo.c
字号:
//==========================================================================
//
// 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
#endif
extern 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 int
no_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 int
numeric_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 int
with_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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -