Files
dusk/src/dusklinux/network/networklinux.c
T
2026-06-07 21:16:46 -05:00

120 lines
2.7 KiB
C

/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "networklinux.h"
#include "util/memory.h"
#include "util/string.h"
#include "assert/assert.h"
errorret_t networkLinuxInit() {
errorOk();
}
errorret_t networkLinuxUpdate() {
errorOk();
}
bool_t networkLinuxIsConnected() {
// Call the OS network stack to check for connectivity.
struct ifaddrs *ifaddr, *ifa;
if(getifaddrs(&ifaddr) == -1) {
return false;
}
// Check if any non loopback interfaces have running flag set.
bool_t connected = false;
for(ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if(!ifa->ifa_name || !ifa->ifa_flags) continue;
// Skip loopback (localhost)
if(ifa->ifa_flags & IFF_LOOPBACK) continue;
// Is interface up and running?
if(!(ifa->ifa_flags & IFF_UP)) continue;
if(!(ifa->ifa_flags & IFF_RUNNING)) continue;
connected = true;
break;
}
// Free the linked list of interfaces
freeifaddrs(ifaddr);
return connected;
}
errorret_t networkLinuxDispose() {
errorOk();
}
networkinfo_t networkLinuxGetInfo() {
networkinfo_t info;
memoryZero(&info, sizeof(networkinfo_t));
bool_t found = false;
struct ifaddrs *ifaddr, *ifa;
if(getifaddrs(&ifaddr) == -1) {
assertUnreachable("getifaddrs failed");
}
// Find the first non-loopback interface with an IP address
for(ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if(!ifa->ifa_name || !ifa->ifa_flags) continue;
// Skip loopback (localhost)
if(ifa->ifa_flags & IFF_LOOPBACK) continue;
// Is interface up and running?
if(!(ifa->ifa_flags & IFF_UP)) continue;
if(!(ifa->ifa_flags & IFF_RUNNING)) continue;
if(ifa->ifa_addr == NULL) continue;
// Check for IPv4 address
if(ifa->ifa_addr->sa_family == AF_INET) {
info.type = NETWORK_TYPE_IPV4;
struct sockaddr_in *sa = (struct sockaddr_in *)ifa->ifa_addr;
memoryCopy(
info.ipv4.ip,
&sa->sin_addr,
NETWORK_INFO_IPV4_OCTET_COUNT
);
found = true;
// sa = (struct sockaddr_in *)ifa->ifa_netmask;
// memoryCopy(
// info.ipv4.subnet,
// &sa->sin_addr,
// NETWORK_INFO_IPV4_OCTET_COUNT
// );
break;
}
// Check for IPv6 address
#ifdef DUSK_NETWORK_IPV6
if(ifa->ifa_addr->sa_family == AF_INET6) {
info.type = NETWORK_TYPE_IPV6;
struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ifa->ifa_addr;
memoryCopy(
info.ipv6.ip,
&sa->sin6_addr,
NETWORK_INFO_IPV6_OCTET_COUNT
);
found = true;
break;
}
#endif
}
freeifaddrs(ifaddr);
assertTrue(found, "No active network interface found?");
return info;
}