7 LD_PRELOAD=$PWD/connredir.so CONNREDIR_ORIG_IP=169.254.169.254 CONNREDIR_ORIG_PORT=80 CONNREDIR_TO_IP=127.0.0.1 CONNREDIR_TO_PORT=8080 wget ...
9 LD_PRELOAD=$PWD/connredir.so CONNREDIR_ORIG_IP=127.0.0.1 CONNREDIR_ORIG_PORT=25 CONNREDIR_TO=stdout sendmail ...
13 This shared library is intended to extend connect(2) standard library function by ip/port override capability, so you control
14 programs, where to connect, without modifying or configuring themself.
16 On each connect() calls, it checks that the destination IP and port match to the ones in CONNREDIR_ORIG_IP and CONNREDIR_ORIG_PORT
17 environment variables. Then changes them to the IP and port numbers in CONNREDIR_TO_IP and CONNREDIR_TO_PORT respectively.
19 Leave CONNREDIR_ORIG_PORT unset to override all ports.
20 Leave CONNREDIR_TO_PORT unset to not override the destination port number.
22 If CONNREDIR_TO is set, then it's evaluated before CONNREDIR_TO_IP.
23 Valid values for CONNREDIR_TO: stdout.
24 When CONNREDIR_TO is 'stdout', connredir replaces the socket's FD, which is about to be connected, to the STDOUT, so you can
25 make your program communicate on STDIO instead of INET. Useful when combined with socat(1).
42 gcc -D_GNU_SOURCE -ldl -shared -fPIC -o connredir.so connredir.c
47 #include <sys/types.h>
48 #include <sys/socket.h>
49 #include <netinet/in.h>
50 #include <arpa/inet.h>
54 void _connredir_ip_parse_error(const char* s
)
56 fprintf(stderr
, "connredir: failed to parse ip address: %s\n", s
);
59 int connect(int sockfd
, const struct sockaddr_in
*orig_sockaddr
, socklen_t addrlen
)
61 struct in_addr orig_ip
;
64 in_port_t orig_port
= 0;
71 in_port_t to_port
= 0;
73 struct sockaddr_in to_sockaddr
;
74 int (*orig_connect
)(int, const struct sockaddr_in
*, socklen_t
) = dlsym(RTLD_NEXT
, "connect");
77 if(orig_sockaddr
->sin_family
!= AF_INET
) goto stdlib
;
79 orig_ip_str
= getenv("CONNREDIR_ORIG_IP");
80 if(orig_ip_str
== NULL
) goto stdlib
;
82 if(inet_aton(orig_ip_str
, &orig_ip
) == 0)
84 _connredir_ip_parse_error(orig_ip_str
);
87 if(ntohl(orig_sockaddr
->sin_addr
.s_addr
) != ntohl(orig_ip
.s_addr
)) goto stdlib
;
89 orig_port_str
= getenv("CONNREDIR_ORIG_PORT");
90 if(orig_port_str
!= NULL
) orig_port
= atoi(orig_port_str
);
91 if(orig_port
!= 0 && orig_port
!= ntohs(orig_sockaddr
->sin_port
)) goto stdlib
;
94 redir_to
= getenv("CONNREDIR_TO");
97 if(strcmp(redir_to
, "stdout")==0)
99 if(dup2(fileno(stdout
), sockfd
) == -1) { perror("connredir: dup2"); goto stdlib
; }
100 fprintf(stderr
, "connredir: redirecting %s:%d -> stdout\n", inet_ntoa(orig_sockaddr
->sin_addr
), ntohs(orig_sockaddr
->sin_port
));
105 fprintf(stderr
, "connredir: unknown redirection '%s'\n", redir_to
);
110 to_ip_str
= getenv("CONNREDIR_TO_IP");
111 if(to_ip_str
== NULL
) goto stdlib
;
113 if(inet_aton(to_ip_str
, &to_ip
) == 0)
115 _connredir_ip_parse_error(to_ip_str
);
119 to_port_str
= getenv("CONNREDIR_TO_PORT");
120 if(to_port_str
!= NULL
) to_port
= atoi(to_port_str
);
122 to_sockaddr
.sin_family
= AF_INET
;
123 to_sockaddr
.sin_port
= to_port
== 0 ? orig_sockaddr
->sin_port
: htons(to_port
);
124 to_sockaddr
.sin_addr
= to_ip
;
126 fprintf(stderr
, "connredir: redirecting %s:%d -> ", inet_ntoa(orig_sockaddr
->sin_addr
), ntohs(orig_sockaddr
->sin_port
));
127 fprintf(stderr
, "%s:%d\n", inet_ntoa(to_sockaddr
.sin_addr
), ntohs(to_sockaddr
.sin_port
));
128 orig_sockaddr
= &to_sockaddr
;
131 return orig_connect(sockfd
, orig_sockaddr
, addrlen
);