Skip to content

Commit

Permalink
Add support for ipv6 addresses to net_adapter.
Browse files Browse the repository at this point in the history
  • Loading branch information
nmoinvaz committed Dec 12, 2023
1 parent 8d75d9c commit 3854db2
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 17 deletions.
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);

Check warning on line 33 in net_adapter_win.c

View check run for this annotation

Codecov / codecov/patch

net_adapter_win.c#L33

Added line #L33 was not covered by tests
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,

Check warning on line 43 in net_adapter_win.c

View check run for this annotation

Codecov / codecov/patch

net_adapter_win.c#L43

Added line #L43 was not covered by tests
(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));

Check warning on line 96 in net_adapter_win.c

View check run for this annotation

Codecov / codecov/patch

net_adapter_win.c#L96

Added line #L96 was not covered by tests
} 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;

Check warning on line 100 in net_adapter_win.c

View check run for this annotation

Codecov / codecov/patch

net_adapter_win.c#L98-L100

Added lines #L98 - L100 were not covered by tests
}
unicast_address = unicast_address->Next;

Check warning on line 102 in net_adapter_win.c

View check run for this annotation

Codecov / codecov/patch

net_adapter_win.c#L102

Added line #L102 was not covered by tests
}

// 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));

Check warning on line 109 in net_adapter_win.c

View check run for this annotation

Codecov / codecov/patch

net_adapter_win.c#L109

Added line #L109 was not covered by tests
} else if (prefix->Address.lpSockaddr->sa_family == AF_INET6) {
struct sockaddr_in6 *sockaddr_ipv6 = (struct sockaddr_in6 *)unicast_address->Address.lpSockaddr;
memcpy(adapter.netmaskv6, &sockaddr_ipv6->sin6_addr, sizeof(adapter.netmaskv6));
adapter.is_ipv6 = true;

Check warning on line 113 in net_adapter_win.c

View check run for this annotation

Codecov / codecov/patch

net_adapter_win.c#L111-L113

Added lines #L111 - L113 were not covered by tests
}
prefix = prefix->Next;
}

Expand Down

0 comments on commit 3854db2

Please sign in to comment.