This commit is contained in:
norohind 2025-02-13 23:20:19 +01:00
commit ba3cb97357
Signed by: norohind
SSH Key Fingerprint: SHA256:SnI4bWnejM2/YEQ5hpH58TUohiQpnjoKN6tXUQlobE0

88
bind.c Normal file
View File

@ -0,0 +1,88 @@
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <net/if.h> // For if_nametoindex
// Build with: gcc -shared -fPIC bind.c -o libbind.so -ldl
// Typedef for the original `bind()` function
typedef int (*pfn_bind_t)(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
// Hardcoded adapter name for the IPv6 link-local address
#define HARDCODED_ADAPTER "enp5s0f3u1"
// Our custom `bind()` function
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
// Get the original `bind()` function
pfn_bind_t original_bind = (pfn_bind_t)dlsym(RTLD_NEXT, "bind");
// Get environment variables
const char *bind_addr_env = getenv("BIND_ADDR");
const char *bind_addr6_env = getenv("BIND_ADDR6");
// Handle IPv4 binding
if (addr->sa_family == AF_INET) {
if (!bind_addr_env) {
fprintf(stderr, "bind(): BIND_ADDR not set, skipping IPv4 bind\n");
return 0; // Simulate success
}
struct sockaddr_in new_addr;
memcpy(&new_addr, addr, sizeof(new_addr)); // Copy the original address
// Replace the IP address
if (inet_pton(AF_INET, bind_addr_env, &new_addr.sin_addr) != 1) {
fprintf(stderr, "Invalid BIND_ADDR: %s\n", bind_addr_env);
return 0; // Simulate success even if the address is invalid
}
// Log the modification
char original_ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &((struct sockaddr_in *)addr)->sin_addr, original_ip, INET_ADDRSTRLEN);
fprintf(stderr, "bind(): Replacing IPv4 address %s with %s\n", original_ip, bind_addr_env);
// Call the original `bind()` with the modified address
return original_bind(sockfd, (struct sockaddr *)&new_addr, addrlen);
}
// Handle IPv6 binding
if (addr->sa_family == AF_INET6) {
if (!bind_addr6_env) {
fprintf(stderr, "bind(): BIND_ADDR6 not set, skipping IPv6 bind\n");
return 0; // Simulate success
}
struct sockaddr_in6 new_addr6;
memcpy(&new_addr6, addr, sizeof(new_addr6)); // Copy the original address
// Replace the IP address
if (inet_pton(AF_INET6, bind_addr6_env, &new_addr6.sin6_addr) != 1) {
fprintf(stderr, "Invalid BIND_ADDR6: %s\n", bind_addr6_env);
return 0; // Simulate success even if the address is invalid
}
// Set the scope ID using the hardcoded adapter name
new_addr6.sin6_scope_id = if_nametoindex(HARDCODED_ADAPTER);
if (new_addr6.sin6_scope_id == 0) {
fprintf(stderr, "bind(): Failed to get scope ID for adapter %s\n", HARDCODED_ADAPTER);
return 0; // Simulate success even if scope ID can't be set
}
// Log the modification
char original_ip6[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &((struct sockaddr_in6 *)addr)->sin6_addr, original_ip6, INET6_ADDRSTRLEN);
fprintf(stderr, "bind(): Replacing IPv6 address %s with %s and scope ID %d\n",
original_ip6, bind_addr6_env, new_addr6.sin6_scope_id);
// Call the original `bind()` with the modified address
return original_bind(sockfd, (struct sockaddr *)&new_addr6, addrlen);
}
// If it's neither IPv4 nor IPv6, call the original `bind()` as-is
return original_bind(sockfd, addr, addrlen);
}