#define EFL_BETA_API_SUPPORT 1 #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_SYS_SOCKET_H # include #endif static int retval = EXIT_SUCCESS; static Eina_List *resolving = NULL; static void _print_ip_addr_info(const Eo *o) { Eina_Slice addr; const struct sockaddr *sa; char buf[INET6_ADDRSTRLEN] = "?"; uint16_t port; size_t i; printf("INFO: %p = %s\n", o, efl_net_ip_address_string_get(o)); printf("INFO: - family: %d (%s)\n", efl_net_ip_address_family_get(o), efl_net_ip_address_family_get(o) == AF_INET ? "AF_INET" : "AF_INET6"); printf("INFO: - port: %hu\n", efl_net_ip_address_port_get(o)); addr = efl_net_ip_address_get(o); printf("INFO: - address %zd bytes:", addr.len); for (i = 0; i < addr.len; i++) printf(" %#hhx", addr.bytes[i]); putchar('\n'); sa = efl_net_ip_address_sockaddr_get(o); if (sa->sa_family == AF_INET) { struct sockaddr_in *a = (struct sockaddr_in *)sa; inet_ntop(sa->sa_family, &a->sin_addr, buf, sizeof(buf)); port = eina_ntohs(a->sin_port); } else { struct sockaddr_in6 *a = (struct sockaddr_in6 *)sa; inet_ntop(sa->sa_family, &a->sin6_addr, buf, sizeof(buf)); port = eina_ntohs(a->sin6_port); } printf("INFO: - sockaddr=%p (%d, '%s', %u)\n", sa, sa->sa_family, buf, port); printf("INFO: - ipv4_class_a: %d\n", efl_net_ip_address_ipv4_class_a_check(o)); printf("INFO: - ipv4_class_b: %d\n", efl_net_ip_address_ipv4_class_b_check(o)); printf("INFO: - ipv4_class_c: %d\n", efl_net_ip_address_ipv4_class_c_check(o)); printf("INFO: - ipv4_class_d: %d\n", efl_net_ip_address_ipv4_class_d_check(o)); printf("INFO: - ipv6_v4mapped: %d\n", efl_net_ip_address_ipv6_v4mapped_check(o)); printf("INFO: - ipv6_v4compat: %d\n", efl_net_ip_address_ipv6_v4compat_check(o)); printf("INFO: - ipv6_local_link: %d\n", efl_net_ip_address_ipv6_local_link_check(o)); printf("INFO: - ipv6_local_site: %d\n", efl_net_ip_address_ipv6_local_site_check(o)); printf("INFO: - multicast: %d\n", efl_net_ip_address_multicast_check(o)); printf("INFO: - loopback: %d\n", efl_net_ip_address_loopback_check(o)); printf("INFO: - any: %d\n", efl_net_ip_address_any_check(o)); } static Eina_Value _resolved(void *data, const Eina_Value v, const Eina_Future *dead_future) { const char *address = data; const char *canonical_name = NULL; const char *request_address = NULL; const Eina_Value_Array desc = { 0 }; const Efl_Net_Ip_Address **o = NULL; if (eina_value_type_get(&v) == EINA_VALUE_TYPE_ERROR) { Eina_Error err = 0; eina_value_error_get(&v, &err); fprintf(stderr, "ERROR: Failed to resolve '%s': %s\n", address, eina_error_msg_get(err)); retval = EXIT_FAILURE; goto end; } eina_value_struct_get(&v, "canonical_name", canonical_name); eina_value_struct_get(&v, "request_address", request_address); eina_value_struct_get(&v, "results", &desc); printf("INFO: resolved '%s' to canonical name '%s':\n", request_address, canonical_name); EINA_INARRAY_FOREACH(desc.array, o) if (o) _print_ip_addr_info(*o); putchar('\n'); eina_stringshare_del(canonical_name); eina_stringshare_del(request_address); end: resolving = eina_list_remove(resolving, dead_future); if (!resolving) ecore_main_loop_quit(); return v; } int main(int argc, char *argv[]) { int i; ecore_init(); ecore_con_init(); for (i = 1; i < argc; i++) { const char *address = argv[i]; Eo *o = efl_net_ip_address_parse( address); if (o) { _print_ip_addr_info(o); efl_del(o); } else { Eina_Future *f = efl_net_ip_address_resolve( address, 0, 0); eina_future_then(f, _resolved, address); printf("INFO: %s is not numeric, resolving...\n", address); resolving = eina_list_append(resolving, f); } } if (resolving) ecore_main_loop_begin(); ecore_con_shutdown(); ecore_shutdown(); return retval; }