Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for ipv6 addresses to net_adapter. #58

Merged
merged 1 commit into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion net_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,24 @@
#include <stdbool.h>
#include <stdio.h>

#ifdef _WIN32
# include <ws2tcpip.h>
#else
# include <arpa/inet.h>
#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) {
Expand All @@ -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);

Expand Down
3 changes: 3 additions & 0 deletions net_adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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
Expand Down
15 changes: 10 additions & 5 deletions net_adapter_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
17 changes: 11 additions & 6 deletions net_adapter_mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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;
Expand Down
23 changes: 18 additions & 5 deletions net_adapter_win.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <inttypes.h>

#include <winsock2.h>
#include <ws2ipdef.h>
#include <windows.h>
#include <iptypes.h>
#include <iphlpapi.h>
Expand All @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down
Loading