]>
git.proxmox.com Git - mirror_novnc.git/blob - utils/rebind.c
2 * rebind: Intercept bind calls and bind to a different port
3 * Copyright 2010 Joel Martin
4 * Licensed under MPL-2.0 (see docs/LICENSE.MPL-2.0)
6 * Overload (LD_PRELOAD) bind system call. If REBIND_PORT_OLD and
7 * REBIND_PORT_NEW environment variables are set then bind on the new
8 * port (of localhost) instead of the old port.
10 * This allows a proxy (such as wsproxy) to run on the old port and translate
11 * traffic to/from the new port.
14 * LD_PRELOAD=./rebind.so \
15 * REBIND_PORT_OLD=23 \
16 * REBIND_PORT_NEW=2023 \
25 #define __USE_GNU 1 // Pull in RTLD_NEXT
29 #include <netinet/in.h>
34 fprintf(stderr, "wswrapper: "); \
35 fprintf(stderr, __VA_ARGS__);
41 int bind(int sockfd
, const struct sockaddr
*addr
, socklen_t addrlen
)
43 static void * (*func
)();
45 struct sockaddr_in
* addr_in
= (struct sockaddr_in
*)addr
;
46 struct sockaddr_in addr_tmp
;
47 socklen_t addrlen_tmp
;
48 char * PORT_OLD
, * PORT_NEW
, * end1
, * end2
;
49 int ret
, oldport
, newport
, askport
= htons(addr_in
->sin_port
);
50 uint32_t askaddr
= htons(addr_in
->sin_addr
.s_addr
);
51 if (!func
) func
= (void *(*)()) dlsym(RTLD_NEXT
, "bind");
53 DEBUG(">> bind(%d, _, %d), askaddr %d, askport %d\n",
54 sockfd
, addrlen
, askaddr
, askport
);
56 /* Determine if we should move this socket */
57 if (addr_in
->sin_family
== AF_INET
) {
59 PORT_OLD
= getenv("REBIND_OLD_PORT");
60 PORT_NEW
= getenv("REBIND_NEW_PORT");
61 if (PORT_OLD
&& (*PORT_OLD
!= '\0') &&
62 PORT_NEW
&& (*PORT_NEW
!= '\0')) {
63 oldport
= strtol(PORT_OLD
, &end1
, 10);
64 newport
= strtol(PORT_NEW
, &end2
, 10);
65 if (oldport
&& (*end1
== '\0') &&
66 newport
&& (*end2
== '\0') &&
67 (oldport
== askport
)) {
74 /* Just pass everything right through to the real bind */
75 ret
= (int) func(sockfd
, addr
, addrlen
);
76 DEBUG("<< bind(%d, _, %d) ret %d\n", sockfd
, addrlen
, ret
);
80 DEBUG("binding fd %d on localhost:%d instead of 0x%x:%d\n",
81 sockfd
, newport
, ntohl(addr_in
->sin_addr
.s_addr
), oldport
);
83 /* Use a temporary location for the new address information */
84 addrlen_tmp
= sizeof(addr_tmp
);
85 memcpy(&addr_tmp
, addr
, addrlen_tmp
);
87 /* Bind to other port on the loopback instead */
88 addr_tmp
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
89 addr_tmp
.sin_port
= htons(newport
);
90 ret
= (int) func(sockfd
, &addr_tmp
, addrlen_tmp
);
92 DEBUG("<< bind(%d, _, %d) ret %d\n", sockfd
, addrlen
, ret
);