/** * 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; }