1
This commit is contained in:
1 parent
17e1a193c5
commit
b27ea97055
6 files changed
+136
No files matched your search
@@ -3,16 +3,27 @@
|
||||
#include "platform_compat.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <bcrypt.h>
|
||||
#include <iphlpapi.h>
|
||||
#pragma comment(lib, "iphlpapi.lib")
|
||||
#ifndef STATUS_SUCCESS
|
||||
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
|
||||
#endif
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -35,3 +46,93 @@ int random_bytes(uint8_t *buffer, size_t len) {
|
||||
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
|
||||
}
|
||||
@@ -136,8 +136,14 @@
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Generate cryptographically secure random bytes
|
||||
// Returns 0 on success, -1 on error
|
||||
int random_bytes(uint8_t *buffer, size_t len);
|
||||
|
||||
// Get IPv4 address of interface with default route (0.0.0.0 destination)
|
||||
// Returns IPv4 address in network byte order, 0 on error
|
||||
uint32_t get_default_route_ip(void);
|
||||
|
||||
#endif // PLATFORM_COMPAT_H
|
||||
Reference in new issue
Block a user