summaryrefslogtreecommitdiff
path: root/netcon
diff options
context:
space:
mode:
Diffstat (limited to 'netcon')
-rw-r--r--netcon/Intercept.c34
-rw-r--r--netcon/Intercept.h9
-rw-r--r--netcon/NetconEthernetTap.cpp50
-rw-r--r--netcon/NetconEthernetTap.hpp4
4 files changed, 90 insertions, 7 deletions
diff --git a/netcon/Intercept.c b/netcon/Intercept.c
index 30d57901..36c9229e 100644
--- a/netcon/Intercept.c
+++ b/netcon/Intercept.c
@@ -691,6 +691,7 @@ int bind(BIND_SIG)
memcpy(&cmd[1], &rpc_st, sizeof(struct bind_st));
pthread_mutex_lock(&lock);
send_command(fdret_sock, cmd);
+
err = get_retval();
pthread_mutex_unlock(&lock);
errno = ERR_OK;
@@ -1022,6 +1023,7 @@ int dup3(DUP3_SIG)
-------------------------------------- getsockname()----------------------------
------------------------------------------------------------------------------*/
+/* define GETSOCKNAME_SIG int sockfd, struct sockaddr *addr, socklen_t *addrlen */
int getsockname(GETSOCKNAME_SIG)
{
if (realgetsockname == NULL) {
@@ -1029,9 +1031,37 @@ int getsockname(GETSOCKNAME_SIG)
return -1;
}
- // TODO
+ char cmd[BUF_SZ];
+ struct getsockname_st rpc_st;
+ rpc_st.sockfd = sockfd;
+ memcpy(&rpc_st.addr, addr, sizeof(struct sockaddr));
+ memcpy(&rpc_st.addrlen, &addrlen, sizeof(socklen_t));
+ cmd[0] = RPC_GETSOCKNAME;
+ memcpy(&cmd[1], &rpc_st, sizeof(struct getsockname_st));
+ pthread_mutex_lock(&lock);
+ send_command(fdret_sock, cmd);
+ pthread_mutex_unlock(&lock);
+
+ char addrbuf[sizeof(struct sockaddr)];
+ memset(addrbuf, '\0', sizeof(struct sockaddr));
+ read(fdret_sock, &addrbuf, sizeof(struct sockaddr)); // read address from service
+ memcpy(addr, addrbuf, sizeof(struct sockaddr));
+ *addrlen = 16;
+
+ struct sockaddr_in *connaddr;
+ connaddr = (struct sockaddr_in *) &addr;
- return realgetsockname(sockfd,addr,addrlen);
+ int ip = connaddr->sin_addr.s_addr;
+ unsigned char d[4];
+ d[0] = ip & 0xFF;
+ d[1] = (ip >> 8) & 0xFF;
+ d[2] = (ip >> 16) & 0xFF;
+ d[3] = (ip >> 24) & 0xFF;
+
+ int port = connaddr->sin_port;
+ dwr(MSG_ERROR, " handle_getsockname(): returning address: %d.%d.%d.%d: %d\n", d[0],d[1],d[2],d[3], port);
+
+ return 0;
}
/*------------------------------------------------------------------------------
diff --git a/netcon/Intercept.h b/netcon/Intercept.h
index 0a9103ad..fe549f22 100644
--- a/netcon/Intercept.h
+++ b/netcon/Intercept.h
@@ -56,6 +56,7 @@
#define RPC_LISTEN 10
#define RPC_SOCKET 11
#define RPC_SHUTDOWN 12
+#define RPC_GETSOCKNAME 13
/* Administration RPC codes */
#define RPC_MAP 20 /* Give the service the value we "see" for the new buffer fd */
@@ -175,6 +176,14 @@ struct shutdown_st
int how;
};
+struct getsockname_st
+{
+ int sockfd;
+ struct sockaddr addr;
+ socklen_t addrlen;
+};
+
+
#define CONNECT_SOCKARG struct sockaddr *
#define SELECT_SIG int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout
#define IOCTL_SIG int __fd, unsigned long int __request, ...
diff --git a/netcon/NetconEthernetTap.cpp b/netcon/NetconEthernetTap.cpp
index f33e7ffa..5a98c413 100644
--- a/netcon/NetconEthernetTap.cpp
+++ b/netcon/NetconEthernetTap.cpp
@@ -149,6 +149,8 @@ public:
PhySocket *dataSock;
struct tcp_pcb *pcb;
+ struct sockaddr_in *addr;
+
unsigned char buf[DEFAULT_READ_BUFFER_SIZE];
int idx;
};
@@ -715,7 +717,7 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns
memcpy(&bind_rpc, &buf[IDX_PAYLOAD+1], sizeof(struct bind_st));
handle_bind(sock, uptr, &bind_rpc);
break;
- case RPC_CONNECT:
+ case RPC_CONNECT:
dwr(MSG_DEBUG, "RPC_CONNECT\n");
struct connect_st connect_rpc;
memcpy(&connect_rpc, &buf[IDX_PAYLOAD+1], sizeof(struct connect_st));
@@ -727,11 +729,17 @@ void NetconEthernetTap::phyOnUnixData(PhySocket *sock,void **uptr,void *data,uns
memcpy(&newfd, &buf[IDX_PAYLOAD+1], sizeof(int));
handle_retval(sock, uptr, rpc_count, newfd);
break;
- case RPC_MAP_REQ:
+ case RPC_MAP_REQ:
dwr(MSG_DEBUG, "RPC_MAP_REQ\n");
handle_map_request(sock, uptr, buf);
break;
- default:
+ case RPC_GETSOCKNAME:
+ dwr(MSG_DEBUG, "RPC_GETSOCKNAME\n");
+ struct getsockname_st getsockname_rpc;
+ memcpy(&getsockname_rpc, &buf[IDX_PAYLOAD+1], sizeof(struct getsockname_st));
+ handle_getsockname(sock, uptr, &getsockname_rpc);
+ break;
+ default:
break;
}
}
@@ -1166,6 +1174,35 @@ void NetconEthernetTap::handle_retval(PhySocket *sock, void **uptr, int rpc_coun
}
}
+
+/* Return the address that the socket is bound to */
+void NetconEthernetTap::handle_getsockname(PhySocket *sock, void **uptr, struct getsockname_st *getsockname_rpc)
+{
+ TcpConnection *conn = getConnectionByTheirFD(sock, getsockname_rpc->sockfd);
+ dwr(MSG_DEBUG, "handle_getsockname(): sockfd = %d\n", getsockname_rpc->sockfd);
+
+ /*
+ int ip = conn->addr->sin_addr.s_addr;
+ unsigned char d[4];
+ d[0] = ip & 0xFF;
+ d[1] = (ip >> 8) & 0xFF;
+ d[2] = (ip >> 16) & 0xFF;
+ d[3] = (ip >> 24) & 0xFF;
+ int port = conn->addr->sin_port;
+ dwr(MSG_ERROR, " handle_getsockname(): returning address: %d.%d.%d.%d: %d\n", d[0],d[1],d[2],d[3], port);
+ */
+
+ // Assemble address "command" to send to intercept
+ char retmsg[sizeof(struct sockaddr)];
+ memset(&retmsg, '\0', sizeof(retmsg));
+ dwr(MSG_ERROR, " handle_getsockname(): %d\n", sizeof(retmsg));
+ memcpy(&retmsg, conn->addr, sizeof(struct sockaddr));
+
+ // Get connection's RPC fd and send structure containing bound address
+ int fd = _phy.getDescriptor(conn->rpcSock);
+ write(fd, &retmsg, sizeof(struct sockaddr));
+}
+
/*
* Handles an RPC to bind an LWIP PCB to a given address and port
*
@@ -1207,8 +1244,8 @@ void NetconEthernetTap::handle_bind(PhySocket *sock, void **uptr, struct bind_st
connaddr = (struct sockaddr_in *) &bind_rpc->addr;
int conn_port = lwipstack->ntohs(connaddr->sin_port);
ip_addr_t conn_addr;
- conn_addr.addr = *((u32_t *)_ips[0].rawIpData());
- TcpConnection *conn = getConnectionByTheirFD(sock, bind_rpc->sockfd);
+ conn_addr.addr = *((u32_t *)_ips[0].rawIpData());
+ TcpConnection *conn = getConnectionByTheirFD(sock, bind_rpc->sockfd);
dwr(MSG_DEBUG, " handle_bind(%d)\n", bind_rpc->sockfd);
@@ -1233,7 +1270,10 @@ void NetconEthernetTap::handle_bind(PhySocket *sock, void **uptr, struct bind_st
send_return_value(conn, -1, ENOMEM); // FIXME: Closest match
}
else
+ {
+ conn->addr = (struct sockaddr_in *) &bind_rpc->addr;
send_return_value(conn, ERR_OK, ERR_OK); // Success
+ }
}
else {
dwr(MSG_ERROR, " handle_bind(): PCB (%x) not in CLOSED state. Ignoring BIND request.\n", conn->pcb);
diff --git a/netcon/NetconEthernetTap.hpp b/netcon/NetconEthernetTap.hpp
index f6fdb6e1..f18e0da8 100644
--- a/netcon/NetconEthernetTap.hpp
+++ b/netcon/NetconEthernetTap.hpp
@@ -49,6 +49,9 @@ struct socket_st;
struct listen_st;
struct bind_st;
struct connect_st;
+struct getsockname_st;
+struct accept_st;
+
namespace ZeroTier {
@@ -109,6 +112,7 @@ private:
// RPC handlers (from NetconIntercept)
void unload_rpc(void *data, pid_t &pid, pid_t &tid, int &rpc_count, char (timestamp[20]), char &cmd, void* &payload);
+ void handle_getsockname(PhySocket *sock, void **uptr, struct getsockname_st *getsockname_rpc);
void handle_bind(PhySocket *sock, void **uptr, struct bind_st *bind_rpc);
void handle_listen(PhySocket *sock, void **uptr, struct listen_st *listen_rpc);
void handle_map_request(PhySocket *sock, void **uptr, unsigned char* buf);