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

📄 getaddrinfo.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//==========================================================================
//
//      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 + -