Crates.io | xtap |
lib.rs | xtap |
version | 0.2.0 |
created_at | 2025-07-02 19:35:38.612859+00 |
updated_at | 2025-07-11 20:09:09.846249+00 |
description | An LD_PRELOAD interception library for runtime hooking of network calls in Unix-like systems. |
homepage | https://github.com/czee/xtap |
repository | https://github.com/czee/xtap |
max_upload_size | |
id | 1735507 |
size | 65,692 |
xtap
is a Rust crate used with LD_PRELOAD
to hook bind()
and connect()
syscalls to reroute v4 and v6 addresses with environment variables.
bind()
and connect()
syscalls using runtime hooking via dlsym
xtap
should only be given one environment variable. If more are given the interface will take precedence over IP and be ignored. When an IP is specified it will use the corresponding interface.
Variable | Example |
---|---|
XTAP_IFACE |
eth0 |
XTAP_INTERFACE |
tun0 |
XTAP_IP |
192.168.1.100 |
BIND_IP |
10.0.0.2 |
BIND_SRC |
10.0.0.3 |
XTAP_ADDR |
172.16.0.1 |
XTAP_BIND |
192.168.2.1 |
XTAP_BIND_ADDR |
192.168.3.1 |
cargo build --release
Set environment variables to specify interface or IP:
export XTAP_IFACE=eth0
export XTAP_IP=192.168.1.100
Run your binary using LD_PRELOAD
. Socket operations will be transparently bound as configured. connect()
calls will automatically inject a bind()
and setsockopt()
call.
LD_PRELOAD=/usr/lib/xtap/libxtap.so \
XTAP_IFACE=tun0 \
curl -4 -L "http://cloudflare.com/cdn-cgi/trace"
If integrating the xtap
crate, ensure your binary uses the provided bind()
and connect()
hooks:
pub fn bind(sockfd: i32, addr: *const sockaddr, addrlen: socklen_t) -> i32 {
xtap::hooks::Bind::bind(sockfd, addr, addrlen)
}
pub fn connect(sockfd: i32, addr: *const sockaddr, addrlen socklen_t) -> i32 {
xtap::hooks::Connect::connect(sockfd, addr, addrlen)
}
Enable debug logging by compiling with debug assertions:
cargo build
Run each test per-process to prevent race conditions from environment variables and side effects caused by global static mutations:
cargo nextest run --status-level=all
libc
and socket2
for socket handling and syscall hookingnetdev
to discover network interfacesscopeguard
for scoped cleanup and guard patternsThis project is available under multiple licenses. You may choose to use it under one of the following:
Inspired by bindhack
Contributions are welcome! Open issues or PRs on the repository.