/* platform_compat.c - Platform compatibility layer implementation */ #include "platform_compat.h" #include #include #include #include #include #ifdef _WIN32 #include #include #include #pragma comment(lib, "iphlpapi.lib") #ifndef STATUS_SUCCESS #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #endif #else #include #include #include #include #include #include #include #include #endif /* * Generate cryptographically secure random bytes * Returns 0 on success, -1 on error */ int random_bytes(uint8_t *buffer, size_t len) { if (!buffer || len == 0) return -1; #ifdef _WIN32 NTSTATUS status = BCryptGenRandom(NULL, buffer, (ULONG)len, BCRYPT_USE_SYSTEM_PREFERRED_RNG); return (status == STATUS_SUCCESS) ? 0 : -1; #else int fd = open("/dev/urandom", O_RDONLY); if (fd < 0) return -1; ssize_t ret = read(fd, buffer, len); close(fd); return (ret == (ssize_t)len) ? 0 : -1; #endif } #ifndef _WIN32 static uint32_t get_default_route_ip_linux(void) { FILE *f = fopen("/proc/net/route", "r"); if (!f) return 0; char line[256]; char *ifname = NULL; unsigned int dest, gw; if (!fgets(line, sizeof(line), f)) { fclose(f); return 0; } while (fgets(line, sizeof(line), f)) { int items = sscanf(line, "%ms %x %x", &ifname, &dest, &gw); if (items != 3) { free(ifname); continue; } if (dest == 0) { free(ifname); break; } free(ifname); ifname = NULL; } fclose(f); if (!ifname) return 0; struct ifaddrs *ifaddr, *ifa; if (getifaddrs(&ifaddr) == -1) { free(ifname); return 0; } uint32_t result = 0; for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr == NULL) continue; if (ifa->ifa_name == NULL) continue; if (strcmp(ifa->ifa_name, ifname) != 0) continue; if (ifa->ifa_addr->sa_family != AF_INET) continue; struct sockaddr_in *addr = (struct sockaddr_in *)ifa->ifa_addr; result = addr->sin_addr.s_addr; break; } freeifaddrs(ifaddr); free(ifname); return result; } #else static uint32_t get_default_route_ip_windows(void) { SOCKET s = socket(AF_INET, SOCK_DGRAM, 0); if (s == INVALID_SOCKET) return 0; struct sockaddr_in remote; remote.sin_family = AF_INET; remote.sin_port = htons(53); remote.sin_addr.s_addr = inet_addr("8.8.8.8"); if (connect(s, (struct sockaddr *)&remote, sizeof(remote)) == SOCKET_ERROR) { closesocket(s); return 0; } struct sockaddr_in local; int len = sizeof(local); if (getsockname(s, (struct sockaddr *)&local, &len) == SOCKET_ERROR) { closesocket(s); return 0; } closesocket(s); return local.sin_addr.s_addr; } #endif uint32_t get_default_route_ip(void) { #ifdef _WIN32 return get_default_route_ip_windows(); #else return get_default_route_ip_linux(); #endif }