コード例 #1
0
ファイル: snmpIPv6BaseDomain.c プロジェクト: 274914765/C
int netsnmp_sockaddr_in6_2 (struct sockaddr_in6 *addr, const char *inpeername, const char *default_target)
{
    char *cp = NULL, *peername = NULL;

    char debug_addr[INET6_ADDRSTRLEN];

#if HAVE_GETADDRINFO
    struct addrinfo *addrs = NULL;

    int err;
#elif HAVE_GETIPNODEBYNAME
    struct hostent *hp = NULL;

    int err;
#elif HAVE_GETHOSTBYNAME
    struct hostent *hp = NULL;
#endif
    int portno;

    if (addr == NULL)
    {
        return 0;
    }

    DEBUGMSGTL (("netsnmp_sockaddr_in6",
                 "addr %p, peername \"%s\", default_target \"%s\"\n",
                 addr, inpeername ? inpeername : "[NIL]", default_target ? default_target : "[NIL]"));

    memset (addr, 0, sizeof (struct sockaddr_in6));
    addr->sin6_family = AF_INET6;
    addr->sin6_addr = in6addr_any;
    addr->sin6_port = htons ((u_short) SNMP_PORT);

    {
        int port = netsnmp_ds_get_int (NETSNMP_DS_LIBRARY_ID,
                                       NETSNMP_DS_LIB_DEFAULT_PORT);

        if (port != 0)
            addr->sin6_port = htons ((u_short) port);
        else if (default_target != NULL)
            netsnmp_sockaddr_in6_2 (addr, default_target, NULL);
    }

    if (inpeername != NULL)
    {
        /*
         * Duplicate the peername because we might want to mank around with
         * it.  
         */

        peername = strdup (inpeername);
        if (peername == NULL)
        {
            return 0;
        }

        for (cp = peername; *cp && isdigit ((unsigned char) *cp); cp++);
        portno = atoi (peername);
        if (!*cp && portno != 0)
        {
            /*
             * Okay, it looks like JUST a port number.  
             */
            DEBUGMSGTL (("netsnmp_sockaddr_in6", "totally numeric: %d\n", portno));
            addr->sin6_port = htons ((u_short) portno);
            goto resolved;
        }

        /*
         * See if it is an IPv6 address covered with square brackets. Also check
         * for an appended :port.  
         */
        if (*peername == '[')
        {
            cp = strchr (peername, ']');
            if (cp != NULL)
            {
                /*
                 * See if it is an IPv6 link-local address with interface
                 * name as <zone_id>, like fe80::1234%eth0.
                 * Please refer to the internet draft, IPv6 Scoped Address Architecture
                 * http://www.ietf.org/internet-drafts/draft-ietf-ipngwg-scoping-arch-04.txt
                 *
                 */
                char *scope_id;

                unsigned int if_index = 0;

                *cp = '\0';
                scope_id = strchr (peername + 1, '%');
                if (scope_id != NULL)
                {
                    *scope_id = '\0';
                    if_index = netsnmp_if_nametoindex (scope_id + 1);
                }
                if (*(cp + 1) == ':')
                {
                    portno = atoi (cp + 2);
                    if (portno != 0 && inet_pton (AF_INET6, peername + 1, (void *) &(addr->sin6_addr)))
                    {
                        DEBUGMSGTL (("netsnmp_sockaddr_in6", "IPv6 address with port suffix :%d\n", portno));
                        if (portno > 0 && portno < 0xffff)
                        {
                            addr->sin6_port = htons ((u_short) portno);
                        }
                        else
                        {
                            DEBUGMSGTL (("netsnmp_sockaddr_in6", "invalid port number: %d", portno));
                            return 0;
                        }

#if defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID)
                        addr->sin6_scope_id = if_index;
#endif
                        goto resolved;
                    }
                }
                else
                {
                    if (inet_pton (AF_INET6, peername + 1, (void *) &(addr->sin6_addr)))
                    {
                        DEBUGMSGTL (("netsnmp_sockaddr_in6", "IPv6 address with square brackets\n"));
                        portno = netsnmp_ds_get_int (NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DEFAULT_PORT);
                        if (portno <= 0)
                            portno = SNMP_PORT;
                        addr->sin6_port = htons ((u_short) portno);
#if defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID)
                        addr->sin6_scope_id = if_index;
#endif
                        goto resolved;
                    }
                }
                if (scope_id != NULL)
                {
                    *scope_id = '%';
                }
                *cp = ']';
            }
        }

        cp = strrchr (peername, ':');
        if (cp != NULL)
        {
            char *scope_id;

            unsigned int if_index = 0;

            *cp = '\0';
            scope_id = strchr (peername + 1, '%');
            if (scope_id != NULL)
            {
                *scope_id = '\0';
                if_index = netsnmp_if_nametoindex (scope_id + 1);
            }
            portno = atoi (cp + 1);
            if (portno != 0 && inet_pton (AF_INET6, peername, (void *) &(addr->sin6_addr)))
            {
                DEBUGMSGTL (("netsnmp_sockaddr_in6", "IPv6 address with port suffix :%d\n", atoi (cp + 1)));
                if (portno > 0 && portno < 0xffff)
                {
                    addr->sin6_port = htons ((u_short) portno);
                }
                else
                {
                    DEBUGMSGTL (("netsnmp_sockaddr_in6", "invalid port number: %d", portno));
                    return 0;
                }

#if defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID)
                addr->sin6_scope_id = if_index;
#endif
                goto resolved;
            }
            if (scope_id != NULL)
            {
                *scope_id = '%';
            }
            *cp = ':';
        }

        /*
         * See if it is JUST an IPv6 address.  
         */
        if (inet_pton (AF_INET6, peername, (void *) &(addr->sin6_addr)))
        {
            DEBUGMSGTL (("netsnmp_sockaddr_in6", "just IPv6 address\n"));
            goto resolved;
        }

        /*
         * Well, it must be a hostname then, possibly with an appended :port.
         * Sort that out first.  
         */

        cp = strrchr (peername, ':');
        if (cp != NULL)
        {
            *cp = '\0';
            portno = atoi (cp + 1);
            if (portno != 0)
            {
                DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname(?) with port suffix :%d\n", portno));
                if (portno > 0 && portno < 0xffff)
                {
                    addr->sin6_port = htons ((u_short) portno);
                }
                else
                {
                    DEBUGMSGTL (("netsnmp_sockaddr_in6", "invalid port number: %d", portno));
                    return 0;
                }

            }
            else
            {
                /*
                 * No idea, looks bogus but we might as well pass the full thing to
                 * the name resolver below.  
                 */
                *cp = ':';
                DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname(?) with embedded ':'?\n"));
            }
            /*
             * Fall through.  
             */
        }

        if (peername[0] == '\0')
        {
            DEBUGMSGTL (("netsnmp_sockaddr_in6", "empty hostname\n"));
            free (peername);
            return 0;
        }

#if HAVE_GETADDRINFO
        {
            struct addrinfo hint = { 0 };
            hint.ai_flags = 0;
            hint.ai_family = PF_INET6;
            hint.ai_socktype = SOCK_DGRAM;
            hint.ai_protocol = 0;

            err = netsnmp_getaddrinfo (peername, NULL, &hint, &addrs);
        }
        if (err != 0)
        {
#if HAVE_GAI_STRERROR
            snmp_log (LOG_ERR, "getaddrinfo(\"%s\", NULL, ...): %s\n", peername, gai_strerror (err));
#else
            snmp_log (LOG_ERR, "getaddrinfo(\"%s\", NULL, ...): (error %d)\n", peername, err);
#endif
            free (peername);
            return 0;
        }
        if (addrs != NULL)
        {
            DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname (resolved okay)\n"));
            memcpy (&addr->sin6_addr, &((struct sockaddr_in6 *) addrs->ai_addr)->sin6_addr, sizeof (struct in6_addr));
            freeaddrinfo (addrs);
        }
        else
        {
            DEBUGMSGTL (("netsnmp_sockaddr_in6", "Failed to resolve IPv6 hostname\n"));
        }
#elif HAVE_GETIPNODEBYNAME
        hp = getipnodebyname (peername, AF_INET6, 0, &err);
        if (hp == NULL)
        {
            DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname (couldn't resolve = %d)\n", err));
            free (peername);
            return 0;
        }
        DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname (resolved okay)\n"));
        memcpy (&(addr->sin6_addr), hp->h_addr, hp->h_length);
#elif HAVE_GETHOSTBYNAME
        hp = netsnmp_gethostbyname (peername);
        if (hp == NULL)
        {
            DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname (couldn't resolve)\n"));
            free (peername);
            return 0;
        }
        else
        {
            if (hp->h_addrtype != AF_INET6)
            {
                DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname (not AF_INET6!)\n"));
                free (peername);
                return 0;
            }
            else
            {
                DEBUGMSGTL (("netsnmp_sockaddr_in6", "hostname (resolved okay)\n"));
                memcpy (&(addr->sin6_addr), hp->h_addr, hp->h_length);
            }
        }
#else                            /*HAVE_GETHOSTBYNAME */
        /*
         * There is no name resolving function available.  
         */
        snmp_log (LOG_ERR, "no getaddrinfo()/getipnodebyname()/gethostbyname()\n");
        free (peername);
        return 0;
#endif                            /*HAVE_GETHOSTBYNAME */
    }
    else
    {
        DEBUGMSGTL (("netsnmp_sockaddr_in6", "NULL peername"));
        return 0;
    }

  resolved:
    DEBUGMSGTL (("netsnmp_sockaddr_in6", "return { AF_INET6, [%s]:%hu }\n",
                 inet_ntop (AF_INET6, &addr->sin6_addr, debug_addr, sizeof (debug_addr)), ntohs (addr->sin6_port)));
    free (peername);
    return 1;
}
コード例 #2
0
ファイル: system.c プロジェクト: michalklempa/net-snmp
int
netsnmp_gethostbyname_v4(const char* name, in_addr_t *addr_out)
{
#if HAVE_GETADDRINFO
    struct addrinfo *addrs = NULL;
    struct addrinfo hint;
    int             err;

    memset(&hint, 0, sizeof hint);
    hint.ai_flags = 0;
    hint.ai_family = PF_INET;
    hint.ai_socktype = SOCK_DGRAM;
    hint.ai_protocol = 0;

    err = netsnmp_getaddrinfo(name, NULL, &hint, &addrs);
    if (err != 0) {
        return -1;
    }

    if (addrs != NULL) {
        memcpy(addr_out,
               &((struct sockaddr_in *) addrs->ai_addr)->sin_addr,
               sizeof(in_addr_t));
        freeaddrinfo(addrs);
    } else {
        DEBUGMSGTL(("get_thisaddr",
                    "Failed to resolve IPv4 hostname\n"));
    }
    return 0;

#elif HAVE_GETHOSTBYNAME
    struct hostent *hp = NULL;

    hp = netsnmp_gethostbyname(name);
    if (hp == NULL) {
        DEBUGMSGTL(("get_thisaddr",
                    "hostname (couldn't resolve)\n"));
        return -1;
    } else if (hp->h_addrtype != AF_INET) {
        DEBUGMSGTL(("get_thisaddr",
                    "hostname (not AF_INET!)\n"));
        return -1;
    } else {
        DEBUGMSGTL(("get_thisaddr",
                    "hostname (resolved okay)\n"));
        memcpy(addr_out, hp->h_addr, sizeof(in_addr_t));
    }
    return 0;

#elif HAVE_GETIPNODEBYNAME
    struct hostent *hp = NULL;
    int             err;

    hp = getipnodebyname(peername, AF_INET, 0, &err);
    if (hp == NULL) {
        DEBUGMSGTL(("get_thisaddr",
                    "hostname (couldn't resolve = %d)\n", err));
        return -1;
    }
    DEBUGMSGTL(("get_thisaddr",
                "hostname (resolved okay)\n"));
    memcpy(addr_out, hp->h_addr, sizeof(in_addr_t));
    return 0;

#else /* HAVE_GETIPNODEBYNAME */
    return -1;
#endif
}