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 + -
显示快捷键?