commit ba3cb97357e24cadc9254157a62f48f82672fc12 Author: norohind <60548839+norohind@users.noreply.github.com> Date: Thu Feb 13 23:20:19 2025 +0100 init diff --git a/bind.c b/bind.c new file mode 100644 index 0000000..8578d4e --- /dev/null +++ b/bind.c @@ -0,0 +1,88 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include // 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); +}