File force_bind.c changed (mode: 100644) (index 8e92748..a5207a6) |
30 |
30 |
#include <arpa/inet.h> |
#include <arpa/inet.h> |
31 |
31 |
|
|
32 |
32 |
|
|
33 |
|
static int (*old_bind)(int sockfd, const struct sockaddr *addr, socklen_t addrlen) = NULL; |
|
34 |
|
static char *force_address = NULL; |
|
35 |
|
static int force_port = -1; |
|
|
33 |
|
static int (*old_bind)(int sockfd, const struct sockaddr *addr, socklen_t addrlen) = NULL; |
|
34 |
|
static int (*old_setsockopt)(int sockfd, int level, int optname, const void *optval, socklen_t optlen); |
|
35 |
|
static int (*old_socket)(int domain, int type, int protocol); |
|
36 |
|
static char *force_address = NULL; |
|
37 |
|
static int force_port = -1; |
|
38 |
|
static char set_tos = 0; |
|
39 |
|
static unsigned char tos; |
36 |
40 |
|
|
37 |
41 |
/* Functions */ |
/* Functions */ |
38 |
42 |
|
|
|
... |
... |
void init(void) |
47 |
51 |
inited = 1; |
inited = 1; |
48 |
52 |
|
|
49 |
53 |
x = getenv("FORCE_BIND_ADDRESS"); |
x = getenv("FORCE_BIND_ADDRESS"); |
50 |
|
if (x != NULL) |
|
|
54 |
|
if (x != NULL) { |
51 |
55 |
force_address = x; |
force_address = x; |
|
56 |
|
syslog(LOG_INFO, "force_bind: Force bind to address %s.\n", |
|
57 |
|
force_address); |
|
58 |
|
} |
52 |
59 |
|
|
53 |
60 |
x = getenv("FORCE_BIND_PORT"); |
x = getenv("FORCE_BIND_PORT"); |
54 |
|
if (x != NULL) |
|
|
61 |
|
if (x != NULL) { |
55 |
62 |
force_port = strtol(x, NULL, 10); |
force_port = strtol(x, NULL, 10); |
|
63 |
|
syslog(LOG_INFO, "force_bind: Force bind to port %d.\n", |
|
64 |
|
force_port); |
|
65 |
|
} |
56 |
66 |
|
|
57 |
|
syslog(LOG_INFO, "force_bind: Force bind to %s/%d.\n", |
|
58 |
|
force_address, force_port); |
|
|
67 |
|
/* tos */ |
|
68 |
|
x = getenv("FORCE_NET_TOS"); |
|
69 |
|
if (x != NULL) { |
|
70 |
|
set_tos = 1; |
|
71 |
|
tos = strtoul(x, NULL, 0); |
|
72 |
|
syslog(LOG_INFO, "force_bind: Force TOS to %hhu.\n", |
|
73 |
|
tos); |
|
74 |
|
} |
59 |
75 |
|
|
60 |
76 |
old_bind = dlsym(RTLD_NEXT, "bind"); |
old_bind = dlsym(RTLD_NEXT, "bind"); |
61 |
77 |
if (old_bind == NULL) { |
if (old_bind == NULL) { |
62 |
78 |
syslog(LOG_ERR, "force_bind: Cannot resolve 'bind'!\n"); |
syslog(LOG_ERR, "force_bind: Cannot resolve 'bind'!\n"); |
63 |
79 |
exit(1); |
exit(1); |
64 |
80 |
} |
} |
|
81 |
|
|
|
82 |
|
old_setsockopt = dlsym(RTLD_NEXT, "setsockopt"); |
|
83 |
|
if (old_setsockopt == NULL) { |
|
84 |
|
syslog(LOG_ERR, "force_bind: Cannot resolve 'setsockopt'!\n"); |
|
85 |
|
exit(1); |
|
86 |
|
} |
|
87 |
|
|
|
88 |
|
old_socket = dlsym(RTLD_NEXT, "socket"); |
|
89 |
|
if (old_socket == NULL) { |
|
90 |
|
syslog(LOG_ERR, "force_bind: Cannot resolve 'socket'!\n"); |
|
91 |
|
exit(1); |
|
92 |
|
} |
65 |
93 |
} |
} |
66 |
94 |
|
|
67 |
95 |
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) |
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) |
|
... |
... |
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) |
111 |
139 |
|
|
112 |
140 |
return old_bind(sockfd, &new, addrlen); |
return old_bind(sockfd, &new, addrlen); |
113 |
141 |
} |
} |
|
142 |
|
|
|
143 |
|
int setsockopt(int sockfd, int level, int optname, const void *optval, |
|
144 |
|
socklen_t optlen) |
|
145 |
|
{ |
|
146 |
|
init(); |
|
147 |
|
|
|
148 |
|
switch (optname) { |
|
149 |
|
case IP_TOS: |
|
150 |
|
if (set_tos == 1) { |
|
151 |
|
syslog(LOG_INFO, "force_bind: changing TOS from %hhu to %hhu.\n", |
|
152 |
|
*(char *)optval, tos); |
|
153 |
|
optval = &tos; |
|
154 |
|
} |
|
155 |
|
break; |
|
156 |
|
} |
|
157 |
|
|
|
158 |
|
|
|
159 |
|
return old_setsockopt(sockfd, level, optname, optval, optlen); |
|
160 |
|
} |
|
161 |
|
|
|
162 |
|
/* |
|
163 |
|
* 'socket' is hijacked to be able to call setsockopt on it. |
|
164 |
|
*/ |
|
165 |
|
int socket(int domain, int type, int protocol) |
|
166 |
|
{ |
|
167 |
|
int sock; |
|
168 |
|
|
|
169 |
|
init(); |
|
170 |
|
|
|
171 |
|
sock = old_socket(domain, type, protocol); |
|
172 |
|
if (sock == -1) |
|
173 |
|
return -1; |
|
174 |
|
|
|
175 |
|
if (set_tos == 1) |
|
176 |
|
setsockopt(sock, IPPROTO_IP, IP_TOS, &tos, 1); |
|
177 |
|
|
|
178 |
|
return sock; |
|
179 |
|
} |
|
180 |
|
|
File test_bind.c changed (mode: 100644) (index 117d3cf..ef56403) |
... |
... |
int main(int argc, char *argv[]) |
14 |
14 |
socklen_t sa_len; |
socklen_t sa_len; |
15 |
15 |
int port = 4444; |
int port = 4444; |
16 |
16 |
char junk[128]; |
char junk[128]; |
|
17 |
|
unsigned char tos; |
17 |
18 |
|
|
18 |
19 |
sock = socket(AF_INET, SOCK_STREAM, 0); |
sock = socket(AF_INET, SOCK_STREAM, 0); |
19 |
20 |
if (sock == -1) { |
if (sock == -1) { |
|
... |
... |
int main(int argc, char *argv[]) |
46 |
47 |
inet_ntop(sa2.sin_family, &sa2.sin_addr, junk, sa_len), |
inet_ntop(sa2.sin_family, &sa2.sin_addr, junk, sa_len), |
47 |
48 |
ntohs(sa2.sin_port)); |
ntohs(sa2.sin_port)); |
48 |
49 |
|
|
|
50 |
|
tos = 0x00; |
|
51 |
|
err = setsockopt(sock, IPPROTO_IP, IP_TOS, &tos, 1); |
|
52 |
|
if (err != 0) |
|
53 |
|
perror("setsockopt"); |
|
54 |
|
|
49 |
55 |
close(sock); |
close(sock); |
50 |
56 |
|
|
51 |
57 |
return 0; |
return 0; |