diff options
Diffstat (limited to 'netcon')
-rw-r--r-- | netcon/Intercept.c | 34 | ||||
-rw-r--r-- | netcon/Intercept.h | 9 | ||||
-rw-r--r-- | netcon/NetconEthernetTap.cpp | 50 | ||||
-rw-r--r-- | netcon/NetconEthernetTap.hpp | 4 |
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); |