Ejemplo n.º 1
0
tb_bool_t tb_addrinfo_addr(tb_char_t const* name, tb_ipaddr_ref_t addr)
{
    // check
    tb_assert_and_check_return_val(name && addr, tb_false);

#ifndef TB_CONFIG_MICRO_ENABLE
    // attempt to get address using dns looker
    if (tb_ipaddr_family(addr) != TB_IPADDR_FAMILY_IPV6 && tb_dns_looker_done(name, addr))
        return tb_true;
#endif

#if defined(TB_CONFIG_POSIX_HAVE_GETADDRINFO)
    // done
    tb_bool_t           ok = tb_false;
    struct addrinfo*    answer = tb_null;
    do
    {
        // init hints
        struct addrinfo hints = {0};
        hints.ai_family = tb_addrinfo_ai_family(addr);
        hints.ai_socktype = SOCK_STREAM;

        // init service
        tb_char_t   service[32] = {0};
        tb_uint16_t port = tb_ipaddr_port(addr);
        if (port) tb_snprintf(service, sizeof(service), "%u", port);

        // get address info
        if (getaddrinfo(name, port? service : tb_null, &hints, &answer)) break;
        tb_assert_and_check_break(answer && answer->ai_addr);

        // save address
        ok = tb_sockaddr_save(addr, (struct sockaddr_storage const*)answer->ai_addr) != 0;

    } while (0);

    // exit answer
    if (answer) freeaddrinfo(answer);
    answer = tb_null;

    // ok?
    return ok;

#elif defined(TB_CONFIG_POSIX_HAVE_GETHOSTBYNAME)

    // not support ipv6
    tb_assert_and_check_return_val(tb_ipaddr_family(addr) != TB_IPADDR_FAMILY_IPV6, tb_false);

    // get first host address
    struct hostent* hostaddr = gethostbyname(name);
    tb_check_return_val(hostaddr && hostaddr->h_addr && hostaddr->h_addrtype == AF_INET, tb_false);

    // save family
    tb_ipaddr_family_set(addr, TB_IPADDR_FAMILY_IPV4);

    // make ipv4
    tb_ipv4_t ipv4;
    ipv4.u32 = (tb_uint32_t)((struct in_addr const*)hostaddr->h_addr)->s_addr;

    // save ipv4
    tb_ipaddr_ipv4_set(addr, &ipv4);

    // ok
    return tb_true;
#else
    tb_trace_noimpl();
    return tb_false;
#endif
}
Ejemplo n.º 2
0
static tb_size_t tb_ifaddrs_netlink_ipaddr_save(tb_ipaddr_ref_t ipaddr, tb_size_t family, tb_size_t scope_id, tb_cpointer_t saddr)
{
    // check
    tb_assert_and_check_return_val(ipaddr && saddr, 0);

    // clear address
    tb_ipaddr_clear(ipaddr);

    // done
    tb_size_t size = 0;
    switch (family)
    {
    case AF_INET:
        {
            // the ipv4 ipaddr
            struct in_addr* addr4 = (struct in_addr*)saddr;

            // save family
            tb_ipaddr_family_set(ipaddr, TB_IPADDR_FAMILY_IPV4);

            // make ipv4
            tb_ipv4_t ipv4;
            ipv4.u32 = (tb_uint32_t)addr4->s_addr;

            // save ipv4
            tb_ipaddr_ipv4_set(ipaddr, &ipv4);

            // save size
            size = sizeof(struct in_addr);
        }
        break;
    case AF_INET6:
        {
            // the ipv6 ipaddr
            struct in6_addr* addr6 = (struct in6_addr*)saddr;

            // check
            tb_assert_static(sizeof(ipaddr->u.ipv6.addr.u8) == sizeof(addr6->s6_addr));
            tb_assert_static(tb_arrayn(ipaddr->u.ipv6.addr.u8) == tb_arrayn(addr6->s6_addr));

            // save family
            tb_ipaddr_family_set(ipaddr, TB_IPADDR_FAMILY_IPV6);

            // make ipv6
            tb_ipv6_t ipv6;
            tb_memcpy(ipv6.addr.u8, addr6->s6_addr, sizeof(ipv6.addr.u8));

            // save scope id
            ipv6.scope_id = 0;
            if (IN6_IS_ADDR_LINKLOCAL(addr6) || IN6_IS_ADDR_MC_LINKLOCAL(addr6))
                ipv6.scope_id = (tb_uint32_t)scope_id;

            // save ipv6
            tb_ipaddr_ipv6_set(ipaddr, &ipv6);

            // save size
            size = sizeof(struct in6_addr);
        }
        break;
    default:
        tb_assert(0);
        break;
    }
    
    // ok?
    return size;
}