|
@@ -38,20 +38,25 @@
|
|
#include <sys/time.h>
|
|
#include <sys/time.h>
|
|
#include <pwd.h>
|
|
#include <pwd.h>
|
|
#include <errno.h>
|
|
#include <errno.h>
|
|
-#include <linux/errno.h>
|
|
|
|
#include <stdarg.h>
|
|
#include <stdarg.h>
|
|
#include <netdb.h>
|
|
#include <netdb.h>
|
|
#include <string.h>
|
|
#include <string.h>
|
|
-#include <sys/syscall.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/poll.h>
|
|
#include <sys/poll.h>
|
|
#include <sys/un.h>
|
|
#include <sys/un.h>
|
|
#include <arpa/inet.h>
|
|
#include <arpa/inet.h>
|
|
#include <sys/resource.h>
|
|
#include <sys/resource.h>
|
|
-#include <linux/net.h> /* for NPROTO */
|
|
|
|
|
|
|
|
-#define SOCK_MAX (SOCK_PACKET + 1)
|
|
|
|
|
|
+#if defined(__linux__)
|
|
|
|
+ #include <linux/errno.h>
|
|
|
|
+ #include <sys/syscall.h>
|
|
|
|
+ #include <linux/net.h> /* for NPROTO */
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#if defined(__linux__)
|
|
|
|
+ #define SOCK_MAX (SOCK_PACKET + 1)
|
|
|
|
+#endif
|
|
#define SOCK_TYPE_MASK 0xf
|
|
#define SOCK_TYPE_MASK 0xf
|
|
|
|
|
|
#include "Intercept.h"
|
|
#include "Intercept.h"
|
|
@@ -92,6 +97,11 @@ static int connected_to_service(int sockfd)
|
|
static int set_up_intercept()
|
|
static int set_up_intercept()
|
|
{
|
|
{
|
|
if (!realconnect) {
|
|
if (!realconnect) {
|
|
|
|
+
|
|
|
|
+#if defined(__linux__)
|
|
|
|
+ realaccept4 = dlsym(RTLD_NEXT, "accept4");
|
|
|
|
+ realsyscall = dlsym(RTLD_NEXT, "syscall");
|
|
|
|
+#endif
|
|
realconnect = dlsym(RTLD_NEXT, "connect");
|
|
realconnect = dlsym(RTLD_NEXT, "connect");
|
|
realbind = dlsym(RTLD_NEXT, "bind");
|
|
realbind = dlsym(RTLD_NEXT, "bind");
|
|
realaccept = dlsym(RTLD_NEXT, "accept");
|
|
realaccept = dlsym(RTLD_NEXT, "accept");
|
|
@@ -100,9 +110,7 @@ static int set_up_intercept()
|
|
realbind = dlsym(RTLD_NEXT, "bind");
|
|
realbind = dlsym(RTLD_NEXT, "bind");
|
|
realsetsockopt = dlsym(RTLD_NEXT, "setsockopt");
|
|
realsetsockopt = dlsym(RTLD_NEXT, "setsockopt");
|
|
realgetsockopt = dlsym(RTLD_NEXT, "getsockopt");
|
|
realgetsockopt = dlsym(RTLD_NEXT, "getsockopt");
|
|
- realaccept4 = dlsym(RTLD_NEXT, "accept4");
|
|
|
|
realclose = dlsym(RTLD_NEXT, "close");
|
|
realclose = dlsym(RTLD_NEXT, "close");
|
|
- realsyscall = dlsym(RTLD_NEXT, "syscall");
|
|
|
|
realgetsockname = dlsym(RTLD_NEXT, "getsockname");
|
|
realgetsockname = dlsym(RTLD_NEXT, "getsockname");
|
|
}
|
|
}
|
|
if (!netpath) {
|
|
if (!netpath) {
|
|
@@ -127,10 +135,12 @@ int setsockopt(SETSOCKOPT_SIG)
|
|
return realsetsockopt(socket, level, option_name, option_value, option_len);
|
|
return realsetsockopt(socket, level, option_name, option_value, option_len);
|
|
|
|
|
|
dwr(MSG_DEBUG,"setsockopt(%d)\n", socket);
|
|
dwr(MSG_DEBUG,"setsockopt(%d)\n", socket);
|
|
|
|
+#if defined(__linux__)
|
|
if(level == SOL_IPV6 && option_name == IPV6_V6ONLY)
|
|
if(level == SOL_IPV6 && option_name == IPV6_V6ONLY)
|
|
return 0;
|
|
return 0;
|
|
if(level == SOL_IP && (option_name == IP_TTL || option_name == IP_TOS))
|
|
if(level == SOL_IP && (option_name == IP_TTL || option_name == IP_TOS))
|
|
return 0;
|
|
return 0;
|
|
|
|
+#endif
|
|
if(level == IPPROTO_TCP || (level == SOL_SOCKET && option_name == SO_KEEPALIVE))
|
|
if(level == IPPROTO_TCP || (level == SOL_SOCKET && option_name == SO_KEEPALIVE))
|
|
return 0;
|
|
return 0;
|
|
if(realsetsockopt(socket, level, option_name, option_value, option_len) < 0)
|
|
if(realsetsockopt(socket, level, option_name, option_value, option_len) < 0)
|
|
@@ -169,13 +179,16 @@ int socket(SOCKET_SIG)
|
|
|
|
|
|
dwr(MSG_DEBUG,"socket():\n");
|
|
dwr(MSG_DEBUG,"socket():\n");
|
|
/* Check that type makes sense */
|
|
/* Check that type makes sense */
|
|
|
|
+#if defined(__linux__)
|
|
int flags = socket_type & ~SOCK_TYPE_MASK;
|
|
int flags = socket_type & ~SOCK_TYPE_MASK;
|
|
if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) {
|
|
if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) {
|
|
errno = EINVAL;
|
|
errno = EINVAL;
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
socket_type &= SOCK_TYPE_MASK;
|
|
socket_type &= SOCK_TYPE_MASK;
|
|
/* Check protocol is in range */
|
|
/* Check protocol is in range */
|
|
|
|
+#if defined(__linux__)
|
|
if (socket_family < 0 || socket_family >= NPROTO){
|
|
if (socket_family < 0 || socket_family >= NPROTO){
|
|
errno = EAFNOSUPPORT;
|
|
errno = EAFNOSUPPORT;
|
|
return -1;
|
|
return -1;
|
|
@@ -184,9 +197,12 @@ int socket(SOCKET_SIG)
|
|
errno = EINVAL;
|
|
errno = EINVAL;
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
/* TODO: detect ENFILE condition */
|
|
/* TODO: detect ENFILE condition */
|
|
if(socket_family == AF_LOCAL
|
|
if(socket_family == AF_LOCAL
|
|
|
|
+#if defined(__linux__)
|
|
|| socket_family == AF_NETLINK
|
|
|| socket_family == AF_NETLINK
|
|
|
|
+#endif
|
|
|| socket_family == AF_UNIX) {
|
|
|| socket_family == AF_UNIX) {
|
|
int err = realsocket(socket_family, socket_type, protocol);
|
|
int err = realsocket(socket_family, socket_type, protocol);
|
|
dwr(MSG_DEBUG,"realsocket() = %d\n", err);
|
|
dwr(MSG_DEBUG,"realsocket() = %d\n", err);
|
|
@@ -244,24 +260,30 @@ int connect(CONNECT_SIG)
|
|
errno = ENOTSOCK;
|
|
errno = ENOTSOCK;
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
+#if defined(__linux__)
|
|
/* Check family */
|
|
/* Check family */
|
|
if (connaddr->sin_family < 0 || connaddr->sin_family >= NPROTO){
|
|
if (connaddr->sin_family < 0 || connaddr->sin_family >= NPROTO){
|
|
errno = EAFNOSUPPORT;
|
|
errno = EAFNOSUPPORT;
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
/* make sure we don't touch any standard outputs */
|
|
/* make sure we don't touch any standard outputs */
|
|
if(__fd == STDIN_FILENO || __fd == STDOUT_FILENO || __fd == STDERR_FILENO)
|
|
if(__fd == STDIN_FILENO || __fd == STDOUT_FILENO || __fd == STDERR_FILENO)
|
|
return(realconnect(__fd, __addr, __len));
|
|
return(realconnect(__fd, __addr, __len));
|
|
|
|
|
|
if(__addr != NULL && (connaddr->sin_family == AF_LOCAL
|
|
if(__addr != NULL && (connaddr->sin_family == AF_LOCAL
|
|
|
|
+#if defined(__linux__)
|
|
|| connaddr->sin_family == PF_NETLINK
|
|
|| connaddr->sin_family == PF_NETLINK
|
|
|| connaddr->sin_family == AF_NETLINK
|
|
|| connaddr->sin_family == AF_NETLINK
|
|
|
|
+#endif
|
|
|| connaddr->sin_family == AF_UNIX)) {
|
|
|| connaddr->sin_family == AF_UNIX)) {
|
|
return realconnect(__fd, __addr, __len);
|
|
return realconnect(__fd, __addr, __len);
|
|
}
|
|
}
|
|
/* Assemble and send RPC */
|
|
/* Assemble and send RPC */
|
|
struct connect_st rpc_st;
|
|
struct connect_st rpc_st;
|
|
|
|
+#if defined(__linux__)
|
|
rpc_st.__tid = syscall(SYS_gettid);
|
|
rpc_st.__tid = syscall(SYS_gettid);
|
|
|
|
+#endif
|
|
rpc_st.__fd = __fd;
|
|
rpc_st.__fd = __fd;
|
|
memcpy(&rpc_st.__addr, __addr, sizeof(struct sockaddr_storage));
|
|
memcpy(&rpc_st.__addr, __addr, sizeof(struct sockaddr_storage));
|
|
memcpy(&rpc_st.__len, &__len, sizeof(socklen_t));
|
|
memcpy(&rpc_st.__len, &__len, sizeof(socklen_t));
|
|
@@ -300,7 +322,9 @@ int bind(BIND_SIG)
|
|
connaddr = (struct sockaddr_in *)addr;
|
|
connaddr = (struct sockaddr_in *)addr;
|
|
|
|
|
|
if(connaddr->sin_family == AF_LOCAL
|
|
if(connaddr->sin_family == AF_LOCAL
|
|
|
|
+#if defined(__linux__)
|
|
|| connaddr->sin_family == AF_NETLINK
|
|
|| connaddr->sin_family == AF_NETLINK
|
|
|
|
+#endif
|
|
|| connaddr->sin_family == AF_UNIX) {
|
|
|| connaddr->sin_family == AF_UNIX) {
|
|
int err = realbind(sockfd, addr, addrlen);
|
|
int err = realbind(sockfd, addr, addrlen);
|
|
dwr(MSG_DEBUG,"realbind, err = %d\n", err);
|
|
dwr(MSG_DEBUG,"realbind, err = %d\n", err);
|
|
@@ -317,7 +341,9 @@ int bind(BIND_SIG)
|
|
/* Assemble and send RPC */
|
|
/* Assemble and send RPC */
|
|
struct bind_st rpc_st;
|
|
struct bind_st rpc_st;
|
|
rpc_st.sockfd = sockfd;
|
|
rpc_st.sockfd = sockfd;
|
|
|
|
+#if defined(__linux__)
|
|
rpc_st.__tid = syscall(SYS_gettid);
|
|
rpc_st.__tid = syscall(SYS_gettid);
|
|
|
|
+#endif
|
|
memcpy(&rpc_st.addr, addr, sizeof(struct sockaddr_storage));
|
|
memcpy(&rpc_st.addr, addr, sizeof(struct sockaddr_storage));
|
|
memcpy(&rpc_st.addrlen, &addrlen, sizeof(socklen_t));
|
|
memcpy(&rpc_st.addrlen, &addrlen, sizeof(socklen_t));
|
|
return rpc_send_command(netpath, RPC_BIND, sockfd, &rpc_st, sizeof(struct bind_st));
|
|
return rpc_send_command(netpath, RPC_BIND, sockfd, &rpc_st, sizeof(struct bind_st));
|
|
@@ -328,6 +354,7 @@ int bind(BIND_SIG)
|
|
------------------------------------------------------------------------------*/
|
|
------------------------------------------------------------------------------*/
|
|
|
|
|
|
/* int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags */
|
|
/* int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags */
|
|
|
|
+#if defined(__linux__)
|
|
int accept4(ACCEPT4_SIG)
|
|
int accept4(ACCEPT4_SIG)
|
|
{
|
|
{
|
|
dwr(MSG_DEBUG,"accept4(%d):\n", sockfd);
|
|
dwr(MSG_DEBUG,"accept4(%d):\n", sockfd);
|
|
@@ -337,6 +364,7 @@ int accept4(ACCEPT4_SIG)
|
|
fcntl(sockfd, F_SETFL, O_NONBLOCK);
|
|
fcntl(sockfd, F_SETFL, O_NONBLOCK);
|
|
return accept(sockfd, addr, addrlen);
|
|
return accept(sockfd, addr, addrlen);
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
|
|
|
|
/*------------------------------------------------------------------------------
|
|
/*------------------------------------------------------------------------------
|
|
----------------------------------- accept() -----------------------------------
|
|
----------------------------------- accept() -----------------------------------
|
|
@@ -442,7 +470,9 @@ int listen(LISTEN_SIG)
|
|
struct listen_st rpc_st;
|
|
struct listen_st rpc_st;
|
|
rpc_st.sockfd = sockfd;
|
|
rpc_st.sockfd = sockfd;
|
|
rpc_st.backlog = backlog;
|
|
rpc_st.backlog = backlog;
|
|
|
|
+#if defined(__linux__)
|
|
rpc_st.__tid = syscall(SYS_gettid);
|
|
rpc_st.__tid = syscall(SYS_gettid);
|
|
|
|
+#endif
|
|
return rpc_send_command(netpath, RPC_LISTEN, sockfd, &rpc_st, sizeof(struct listen_st));
|
|
return rpc_send_command(netpath, RPC_LISTEN, sockfd, &rpc_st, sizeof(struct listen_st));
|
|
}
|
|
}
|
|
|
|
|
|
@@ -502,6 +532,7 @@ int getsockname(GETSOCKNAME_SIG)
|
|
------------------------------------ syscall() ---------------------------------
|
|
------------------------------------ syscall() ---------------------------------
|
|
------------------------------------------------------------------------------*/
|
|
------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
+#if defined(__linux__)
|
|
long syscall(SYSCALL_SIG)
|
|
long syscall(SYSCALL_SIG)
|
|
{
|
|
{
|
|
va_list ap;
|
|
va_list ap;
|
|
@@ -542,3 +573,4 @@ long syscall(SYSCALL_SIG)
|
|
#endif
|
|
#endif
|
|
return realsyscall(number,a,b,c,d,e,f);
|
|
return realsyscall(number,a,b,c,d,e,f);
|
|
}
|
|
}
|
|
|
|
+#endif
|