diff --git a/net_adapter.c b/net_adapter.c index d220c11..28f32fa 100644 --- a/net_adapter.c +++ b/net_adapter.c @@ -2,10 +2,24 @@ #include #include +#ifdef _WIN32 +# include +#else +# include +#endif + #include "net_adapter.h" static inline void print_ip(const char *name, uint8_t ip[4]) { - printf(" %s: %d.%d.%d.%d\n", name, ip[0], ip[1], ip[2], ip[3]); + char ip_str[INET_ADDRSTRLEN] = {0}; + inet_ntop(AF_INET, ip, ip_str, sizeof(ip_str)); + printf(" %s: %s\n", name, ip_str); +} + +static inline void print_ipv6(const char *name, uint8_t ipv6[16]) { + char ipv6_str[INET6_ADDRSTRLEN] = {0}; + inet_ntop(AF_INET6, ipv6, ipv6_str, sizeof(ipv6_str)); + printf(" %s: %s\n", name, ipv6_str); } void net_adapter_print(net_adapter_s *adapter) { @@ -20,6 +34,10 @@ void net_adapter_print(net_adapter_s *adapter) { print_ip("ip", adapter->ip); print_ip("netmask", adapter->netmask); print_ip("gateway", adapter->gateway); + if (adapter->is_ipv6) { + print_ipv6("ipv6", adapter->ipv6); + print_ipv6("netmaskv6", adapter->netmaskv6); + } print_ip("primary dns", adapter->primary_dns); print_ip("secondary dns", adapter->secondary_dns); diff --git a/net_adapter.h b/net_adapter.h index 62a0ebc..1542f1a 100644 --- a/net_adapter.h +++ b/net_adapter.h @@ -9,7 +9,9 @@ typedef struct net_adapter_s { char guid[256]; char description[256]; uint8_t ip[4]; + uint8_t ipv6[16]; uint8_t netmask[4]; + uint8_t netmaskv6[16]; uint8_t gateway[4]; uint8_t primary_dns[4]; uint8_t secondary_dns[4]; @@ -18,6 +20,7 @@ typedef struct net_adapter_s { uint8_t mac_length; bool is_connected; bool is_dhcp_v4; + bool is_ipv6; } net_adapter_s; // Callback to enumerate network adapters diff --git a/net_adapter_linux.c b/net_adapter_linux.c index 57f8ccb..3725ff1 100644 --- a/net_adapter_linux.c +++ b/net_adapter_linux.c @@ -32,8 +32,7 @@ bool net_adapter_enum(void *user_data, net_adapter_cb callback) { return false; for (ifa = ifp; ifa; ifa = ifa->ifa_next) { - // Ignore non-IPv4 adapters - if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET) + if (!ifa->ifa_addr) continue; // Ignore non-physical adapters if (ifa->ifa_flags & IFF_LOOPBACK) @@ -72,9 +71,15 @@ bool net_adapter_enum(void *user_data, net_adapter_cb callback) { strncat(adapter.name, ifa->ifa_name, sizeof(adapter.name) - 1); } - memcpy(adapter.ip, &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, sizeof(adapter.ip)); - memcpy(adapter.gateway, &((struct sockaddr_in *)ifa->ifa_broadaddr)->sin_addr, sizeof(adapter.gateway)); - memcpy(adapter.netmask, &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr, sizeof(adapter.netmask)); + if (ifa->ifa_addr->sa_family == AF_INET) { + memcpy(adapter.ip, &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, sizeof(adapter.ip)); + memcpy(adapter.gateway, &((struct sockaddr_in *)ifa->ifa_broadaddr)->sin_addr, sizeof(adapter.gateway)); + memcpy(adapter.netmask, &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr, sizeof(adapter.netmask)); + } else if (ifa->ifa_addr->sa_family == AF_INET6) { + memcpy(adapter.ipv6, &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr, sizeof(adapter.ipv6)); + memcpy(adapter.netmaskv6, &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr, sizeof(adapter.netmaskv6)); + adapter.is_ipv6 = true; + } if (!callback(user_data, &adapter)) break; diff --git a/net_adapter_mac.c b/net_adapter_mac.c index a43eaf5..bf5bf90 100644 --- a/net_adapter_mac.c +++ b/net_adapter_mac.c @@ -32,8 +32,7 @@ bool net_adapter_enum(void *user_data, net_adapter_cb callback) { return false; for (ifa = ifp; ifa; ifa = ifa->ifa_next) { - // Ignore non-IPv4 adapters - if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET) + if (!ifa->ifa_addr) continue; memset(&adapter, 0, sizeof(adapter)); @@ -72,12 +71,18 @@ bool net_adapter_enum(void *user_data, net_adapter_cb callback) { adapter.is_connected = true; strncat(adapter.name, ifa->ifa_name, sizeof(adapter.name) - 1); - adapter.mac_length = 6; memcpy(adapter.mac, LLADDR((struct sockaddr_dl *)(ifm + 1)), adapter.mac_length); - memcpy(adapter.ip, &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, sizeof(adapter.ip)); - memcpy(adapter.gateway, &((struct sockaddr_in *)ifa->ifa_broadaddr)->sin_addr, sizeof(adapter.gateway)); - memcpy(adapter.netmask, &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr, sizeof(adapter.netmask)); + + if (ifa->ifa_addr->sa_family == AF_INET) { + memcpy(adapter.ip, &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, sizeof(adapter.ip)); + memcpy(adapter.gateway, &((struct sockaddr_in *)ifa->ifa_broadaddr)->sin_addr, sizeof(adapter.gateway)); + memcpy(adapter.netmask, &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr, sizeof(adapter.netmask)); + } else if (ifa->ifa_addr->sa_family == AF_INET6) { + memcpy(adapter.ipv6, &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr, sizeof(adapter.ipv6)); + memcpy(adapter.netmaskv6, &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr, sizeof(adapter.netmaskv6)); + adapter.is_ipv6 = true; + } if (!callback(user_data, &adapter)) break; diff --git a/net_adapter_win.c b/net_adapter_win.c index fbc0e23..f1e8654 100644 --- a/net_adapter_win.c +++ b/net_adapter_win.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -29,7 +30,7 @@ bool net_adapter_enum(void *user_data, net_adapter_cb callback) { if (!callback) return false; - error = GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS, 0, NULL, &buffer_size); + error = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS, 0, NULL, &buffer_size); if (error != ERROR_SUCCESS && error != ERROR_BUFFER_OVERFLOW) { LOG_ERROR("Unable to allocate memory for %s (%lu)\n", "adapter info", error); return false; @@ -39,7 +40,7 @@ bool net_adapter_enum(void *user_data, net_adapter_cb callback) { buffer = calloc(buffer_size, sizeof(uint8_t)); required_size = buffer_size; - error = GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS, 0, + error = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS, 0, (IP_ADAPTER_ADDRESSES *)buffer, &required_size); if (error != ERROR_SUCCESS) { LOG_ERROR("Unable to get adapter info (%lu / %lu:%lu)\n", error, buffer_size, required_size); @@ -91,14 +92,26 @@ bool net_adapter_enum(void *user_data, net_adapter_cb callback) { // Populate adapter ip address unicast_address = adapter_addresses->FirstUnicastAddress; while (unicast_address) { - memcpy(adapter.ip, &unicast_address->Address.lpSockaddr->sa_data[2], sizeof(adapter.ip)); - break; + if (unicast_address->Address.lpSockaddr->sa_family == AF_INET) { + memcpy(adapter.ip, &unicast_address->Address.lpSockaddr->sa_data[2], sizeof(adapter.ip)); + } else if (unicast_address->Address.lpSockaddr->sa_family == AF_INET6) { + struct sockaddr_in6 *sockaddr_ipv6 = (struct sockaddr_in6 *)unicast_address->Address.lpSockaddr; + memcpy(adapter.ipv6, &sockaddr_ipv6->sin6_addr, sizeof(adapter.ipv6)); + adapter.is_ipv6 = true; + } + unicast_address = unicast_address->Next; } // Populate adapter netmask prefix = adapter_addresses->FirstPrefix; while (prefix) { - memcpy(adapter.netmask, &prefix->Address.lpSockaddr->sa_data[2], sizeof(adapter.netmask)); + if (prefix->Address.lpSockaddr->sa_family == AF_INET) { + memcpy(adapter.netmask, &prefix->Address.lpSockaddr->sa_data[2], sizeof(adapter.netmask)); + } else if (prefix->Address.lpSockaddr->sa_family == AF_INET6) { + struct sockaddr_in6 *sockaddr_ipv6 = (struct sockaddr_in6 *)prefix->Address.lpSockaddr; + memcpy(adapter.netmaskv6, &sockaddr_ipv6->sin6_addr, sizeof(adapter.netmaskv6)); + adapter.is_ipv6 = true; + } prefix = prefix->Next; }