You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

126 lines
5.1 KiB

#ifndef UTUN_TEST_HOOKS_H
#define UTUN_TEST_HOOKS_H
#include <sys/types.h>
#include <sys/socket.h>
#include <stdint.h>
#include <stddef.h>
#include <unistd.h>
// Forward declarations
struct UTUN_INSTANCE;
struct ETCP_SOCKET;
// UDP packet interception callbacks
typedef ssize_t (*utun_sendto_hook_t)(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen,
void* context);
typedef ssize_t (*utun_recvfrom_hook_t)(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen,
void* context);
// TUN virtual interface callbacks
typedef int (*tun_create_hook_t)(void* priv_data);
typedef ssize_t (*tun_read_hook_t)(int fd, void *buf, size_t count, void* priv_data);
typedef ssize_t (*tun_write_hook_t)(int fd, const void *buf, size_t count, void* priv_data);
// Socket creation callback
typedef int (*socket_create_hook_t)(int domain, int type, int protocol, void* context);
// Test packet capture callback
typedef void (*packet_capture_hook_t)(struct UTUN_INSTANCE* instance,
const uint8_t* packet, size_t len,
const char* direction, // "tun_in", "tun_out", "udp_in", "udp_out"
void* context);
struct utun_test_hooks {
// UDP socket hooks
utun_sendto_hook_t sendto_override;
utun_recvfrom_hook_t recvfrom_override;
// TUN hooks
tun_create_hook_t tun_create_override;
tun_read_hook_t tun_read_override;
tun_write_hook_t tun_write_override;
// Socket creation hook
socket_create_hook_t socket_create_override;
// Packet capture
packet_capture_hook_t packet_captured;
// Context for callbacks
void* test_context;
};
// Global test hooks - NULL in production, set only by test code
extern struct utun_test_hooks* g_utun_test_hooks;
// Test-aware wrapper functions - inline for zero overhead when NULL
static inline ssize_t utun_sendto_hook(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen) {
if (g_utun_test_hooks && g_utun_test_hooks->sendto_override) {
return g_utun_test_hooks->sendto_override(sockfd, buf, len, flags, dest_addr, addrlen,
g_utun_test_hooks->test_context);
}
return sendto(sockfd, buf, len, flags, dest_addr, addrlen);
}
static inline ssize_t utun_recvfrom_hook(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen) {
if (g_utun_test_hooks && g_utun_test_hooks->recvfrom_override) {
return g_utun_test_hooks->recvfrom_override(sockfd, buf, len, flags, src_addr, addrlen,
g_utun_test_hooks->test_context);
}
return recvfrom(sockfd, buf, len, flags, src_addr, addrlen);
}
static inline int tun_create_hook(void* priv_data) {
if (g_utun_test_hooks && g_utun_test_hooks->tun_create_override) {
return g_utun_test_hooks->tun_create_override(priv_data);
}
return -1; // Default: no TUN available in test mode
}
static inline ssize_t tun_read_hook(int fd, void *buf, size_t count, void* priv_data) {
if (g_utun_test_hooks && g_utun_test_hooks->tun_read_override) {
return g_utun_test_hooks->tun_read_override(fd, buf, count, priv_data);
}
return read(fd, buf, count);
}
static inline ssize_t tun_write_hook(int fd, const void *buf, size_t count, void* priv_data) {
if (g_utun_test_hooks && g_utun_test_hooks->tun_write_override) {
return g_utun_test_hooks->tun_write_override(fd, buf, count, priv_data);
}
return write(fd, buf, count);
}
static inline int socket_create_hook(int domain, int type, int protocol) {
if (g_utun_test_hooks && g_utun_test_hooks->socket_create_override) {
return g_utun_test_hooks->socket_create_override(domain, type, protocol,
g_utun_test_hooks->test_context);
}
return socket(domain, type, protocol);
}
static inline void packet_capture_hook(struct UTUN_INSTANCE* instance,
const uint8_t* packet, size_t len,
const char* direction) {
if (g_utun_test_hooks && g_utun_test_hooks->packet_captured) {
g_utun_test_hooks->packet_captured(instance, packet, len, direction,
g_utun_test_hooks->test_context);
}
}
// Functions to set/clear test hooks (only available in test builds)
#ifdef TEST_BUILD
void utun_test_hooks_set(struct utun_test_hooks* hooks);
void utun_test_hooks_clear(void);
#else
// In production builds, these are no-ops for safety
static inline void utun_test_hooks_set(struct utun_test_hooks* hooks) { (void)hooks; }
static inline void utun_test_hooks_clear(void) {}
#endif
#endif // UTUN_TEST_HOOKS_H