// sysctl net.ipv4.ip_nonlocal_bind=1 int fd = socket (PF_INET, SOCK_STREAM, 0); int setopt = 1; int result = setsockopt (fd, IPPROTO_IP, IP_TRANSPARENT, &setopt, sizeof(setopt)); struct sockaddr_in nonlocal; struct sockaddr_in remote; memset (&nonlocal, 0, sizeof(nonlocal)); memset (&remote, 0, sizeof(remote)); char NONLOCAL_ADDR[] = "8.8.8.8"; enum { NONLOCAL_PORT = 53 }; char REMOTE_ADDR[] = "192.168.96.1"; enum { REMOTE_PORT = 53 }; // eg only 0- use getaddrinfo(3) nonlocal.sin_family = AF_INET; remote.sin_family = AF_INET; nonlocal.sin_port = htons(NONLOCAL_PORT); remote.sin_port = htons(REMOTE_PORT); nonlocal.sin_addr.s_addr = inet_addr(NONLOCAL_ADDR); remote.sin_addr.s_addr = inet_addr(REMOTE_ADDR); int result = bind (fd, &nonlocal, sizeof(nonlocal)); int result = connect (fd, &remote, sizeof(remote)); // In reality you will be fetching the original source address // from the "input" socket to spoof it on the "output" socket // to complete the "illusion" :)