diff options
author | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2013-04-22 12:54:57 -0700 |
---|---|---|
committer | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2013-04-22 12:54:57 -0700 |
commit | 1d1e804a1ca72d521f9d9dc9ed1883fb02201f1b (patch) | |
tree | 9ab801042e25e9cf1729549d23ea64911a1a9b39 /tests/gtcp_proxy/gtcp.c | |
parent | c5ebc9ae51b7a0c9a805ecd93055557d64341baf (diff) | |
download | xrdp-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.c | 394 |
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 +} |