summaryrefslogtreecommitdiffstats
path: root/tests/gtcp_proxy/gtcp.c
diff options
context:
space:
mode:
authorLaxmikant Rashinkar <LK.Rashinkar@gmail.com>2013-04-22 12:54:57 -0700
committerLaxmikant Rashinkar <LK.Rashinkar@gmail.com>2013-04-22 12:54:57 -0700
commit1d1e804a1ca72d521f9d9dc9ed1883fb02201f1b (patch)
tree9ab801042e25e9cf1729549d23ea64911a1a9b39 /tests/gtcp_proxy/gtcp.c
parentc5ebc9ae51b7a0c9a805ecd93055557d64341baf (diff)
downloadxrdp-proprietary-1d1e804a1ca72d521f9d9dc9ed1883fb02201f1b.tar.gz
xrdp-proprietary-1d1e804a1ca72d521f9d9dc9ed1883fb02201f1b.zip
first checkin for gtcp-proxy, a man-in-the-middle program to monitor network traffice
Diffstat (limited to 'tests/gtcp_proxy/gtcp.c')
-rw-r--r--tests/gtcp_proxy/gtcp.c394
1 files changed, 394 insertions, 0 deletions
diff --git a/tests/gtcp_proxy/gtcp.c b/tests/gtcp_proxy/gtcp.c
new file mode 100644
index 00000000..9f0fcf88
--- /dev/null
+++ b/tests/gtcp_proxy/gtcp.c
@@ -0,0 +1,394 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "gtcp.h"
+
+/**
+ * Return a newly created socket or -1 on error
+ *****************************************************************************/
+
+int tcp_socket_create(void)
+{
+ int rv;
+ int option_value;
+
+#if defined(_WIN32)
+ int option_len;
+#else
+ unsigned int option_len;
+#endif
+
+ /* in win32 a socket is an unsigned int, in linux, its an int */
+ if ((rv = (int) socket(PF_INET, SOCK_STREAM, 0)) < 0)
+ return -1;
+
+ option_len = sizeof(option_value);
+
+ if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *) &option_value,
+ &option_len) == 0)
+ {
+ if (option_value == 0)
+ {
+ option_value = 1;
+ option_len = sizeof(option_value);
+ setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *) &option_value,
+ option_len);
+ }
+ }
+
+ option_len = sizeof(option_value);
+
+ if (getsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *) &option_value,
+ &option_len) == 0)
+ {
+ if (option_value < (1024 * 32))
+ {
+ option_value = 1024 * 32;
+ option_len = sizeof(option_value);
+ setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *) &option_value,
+ option_len);
+ }
+ }
+
+ return rv;
+}
+
+/**
+ * Place specifed socket in non blocking mode
+ *****************************************************************************/
+
+void tcp_set_non_blocking(int skt)
+{
+ unsigned long i;
+
+#if defined(_WIN32)
+ i = 1;
+ ioctlsocket(skt, FIONBIO, &i);
+#else
+ i = fcntl(skt, F_GETFL);
+ i = i | O_NONBLOCK;
+ fcntl(skt, F_SETFL, i);
+#endif
+}
+
+/**
+ * Assign name to socket
+ *
+ * @param skt the socket to bind
+ * @param port the port to bind to
+ *
+ * @return 0 on success, -1 on error
+ *****************************************************************************/
+
+int tcp_bind(int skt, char *port)
+{
+ struct sockaddr_in s;
+
+ memset(&s, 0, sizeof(struct sockaddr_in));
+ s.sin_family = AF_INET;
+ s.sin_port = htons((uint16_t) atoi(port));
+ s.sin_addr.s_addr = INADDR_ANY;
+
+ return bind(skt, (struct sockaddr *) &s, sizeof(struct sockaddr_in));
+}
+
+/**
+ * Listen for incoming connections
+ *
+ * @param skt the socket to listen on
+ *
+ * @return 0 on success, -1 on error
+ *****************************************************************************/
+
+int tcp_listen(int skt)
+{
+ return listen(skt, 2);
+}
+
+/**
+ * Accept incoming connection
+ *
+ * @param skt socket to accept incoming connection on
+ *
+ * @return 0 on success, -1 on error
+ *****************************************************************************/
+
+int tcp_accept(int skt)
+{
+ int ret ;
+ char ipAddr[256] ;
+ struct sockaddr_in s;
+
+#if defined(_WIN32)
+ int i;
+#else
+ unsigned int i;
+#endif
+
+ i = sizeof(struct sockaddr_in);
+ memset(&s, 0, i);
+ return accept(skt, (struct sockaddr *)&s, &i);
+}
+
+/**
+ * Check if the socket would block
+ *
+ * @return TRUE if would block, else FALSE
+ *****************************************************************************/
+
+int tcp_last_error_would_block()
+{
+#if defined(_WIN32)
+ return WSAGetLastError() == WSAEWOULDBLOCK;
+#else
+ return (errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINPROGRESS);
+#endif
+}
+
+/**
+ * Close specified socket
+ *****************************************************************************/
+
+void tcp_close(int skt)
+{
+ if (skt <= 0)
+ return;
+
+#if defined(_WIN32)
+ closesocket(skt);
+#else
+ close(skt);
+#endif
+}
+
+/**
+ * Create a new socket
+ *
+ * @return new socket or -1 on error
+ *****************************************************************************/
+
+int tcp_socket(void)
+{
+ int rv;
+ int option_value;
+
+#if defined(_WIN32)
+ int option_len;
+#else
+ unsigned int option_len;
+#endif
+
+ /* in win32 a socket is an unsigned int, in linux, its an int */
+ if ((rv = (int) socket(PF_INET, SOCK_STREAM, 0)) < 0)
+ return -1;
+
+ option_len = sizeof(option_value);
+
+ if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *) &option_value,
+ &option_len) == 0)
+ {
+ if (option_value == 0)
+ {
+ option_value = 1;
+ option_len = sizeof(option_value);
+ setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *) &option_value,
+ option_len);
+ }
+ }
+
+ option_len = sizeof(option_value);
+
+ if (getsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *) &option_value,
+ &option_len) == 0)
+ {
+ if (option_value < (1024 * 32))
+ {
+ option_value = 1024 * 32;
+ option_len = sizeof(option_value);
+ setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *) &option_value,
+ option_len);
+ }
+ }
+
+ return rv;
+}
+
+/**
+ * Connect to a server
+ *
+ * @param skt opaque socket obj
+ * @param address connect to this server
+ * @param port using this port
+ *
+ * @return 0 on success, -1 on error
+ *****************************************************************************/
+
+int tcp_connect(int skt, const char *hostname, const char *port)
+{
+ struct sockaddr_in s;
+ struct hostent *h;
+
+ memset(&s, 0, sizeof(struct sockaddr_in));
+ s.sin_family = AF_INET;
+ s.sin_port = htons((uint16_t) atoi(port));
+ s.sin_addr.s_addr = inet_addr(hostname);
+
+ if (s.sin_addr.s_addr == INADDR_NONE)
+ {
+ h = gethostbyname(hostname);
+
+ if (h != 0)
+ {
+ if (h->h_name != 0)
+ {
+ if (h->h_addr_list != 0)
+ {
+ if ((*(h->h_addr_list)) != 0)
+ {
+ s.sin_addr.s_addr = *((int *)(*(h->h_addr_list)));
+ }
+ }
+ }
+ }
+ }
+
+ return connect(skt, (struct sockaddr *) &s, sizeof(struct sockaddr_in));
+}
+
+/**
+ * Return 1 if we can write to the socket, 0 otherwise
+ *****************************************************************************/
+
+int tcp_can_send(int skt, int millis)
+{
+ fd_set wfds;
+ struct timeval time;
+ int rv;
+
+ time.tv_sec = millis / 1000;
+ time.tv_usec = (millis * 1000) % 1000000;
+ FD_ZERO(&wfds);
+
+ if (skt > 0)
+ {
+ FD_SET(((unsigned int) skt), &wfds);
+ rv = select(skt + 1, 0, &wfds, 0, &time);
+
+ if (rv > 0)
+ {
+ return tcp_socket_ok(skt);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Return 1 if socket is OK, 0 otherwise
+ *****************************************************************************/
+
+int tcp_socket_ok(int skt)
+{
+ int opt;
+
+#if defined(_WIN32)
+ int opt_len;
+#else
+ unsigned int opt_len;
+#endif
+
+ opt_len = sizeof(opt);
+
+ if (getsockopt(skt, SOL_SOCKET, SO_ERROR, (char *) (&opt), &opt_len) == 0)
+ {
+ if (opt == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * Check if specified sockets can be operated on without blocking
+ *
+ * @return 1 if they can be operated on or 0 if blocking would occur
+ *****************************************************************************/
+
+int tcp_select(int sck1, int sck2)
+{
+ fd_set rfds;
+ struct timeval time;
+
+ int max = 0;
+ int rv = 0;
+
+ memset(&rfds, 0, sizeof(fd_set));
+ memset(&time, 0, sizeof(struct timeval));
+
+ time.tv_sec = 0;
+ time.tv_usec = 0;
+ FD_ZERO(&rfds);
+
+ if (sck1 > 0)
+ FD_SET(((unsigned int) sck1), &rfds);
+
+ if (sck2 > 0)
+ FD_SET(((unsigned int) sck2), &rfds);
+
+ max = sck1;
+
+ if (sck2 > max)
+ max = sck2;
+
+ rv = select(max + 1, &rfds, 0, 0, &time);
+
+ if (rv > 0)
+ {
+ rv = 0;
+
+ if (FD_ISSET(((unsigned int) sck1), &rfds))
+ rv = rv | 1;
+
+ if (FD_ISSET(((unsigned int)sck2), &rfds))
+ rv = rv | 2;
+ }
+ else
+ {
+ rv = 0;
+ }
+
+ return rv;
+}
+
+int tcp_recv(int skt, void *ptr, int len, int flags)
+{
+#if defined(_WIN32)
+ return recv(skt, (char *) ptr, len, flags);
+#else
+ return recv(skt, ptr, len, flags);
+#endif
+}
+
+int tcp_send(int skt, const void *ptr, int len, int flags)
+{
+#if defined(_WIN32)
+ return send(skt, (const char *)ptr, len, flags);
+#else
+ return send(skt, ptr, len, flags);
+#endif
+}