/* Copyright (c) 2008-2010, Dirk Krause All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Dirk Krause nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TCPTOOL_H_INCLUDED #define TCPTOOL_H_INCLUDED 1 #include #include #ifndef TCPTOOL_MAX_CLIENTS #define TCPTOOL_MAX_CLIENTS 256 #endif #ifndef TCPTOOL_MAX_ALLOWED_IP #define TCPTOOL_MAX_ALLOWED_IP TCPTOOL_MAX_CLIENTS #endif #include #if DK_HAVE_WINSOCK2_H #include #endif #if DK_HAVE_WINDOWS_H #include #endif #if DK_HAVE_WINBASE_H #include #endif #if DK_HAVE_SYS_TYPES_H #include #endif #if DK_HAVE_STDLIB_H #include #endif #if DK_HAVE_UNISTD_H #include #endif #if DK_HAVE_SIGNAL_H #include #endif #if DK_HAVE_PROCESS_H #include #endif #if DK_HAVE_CTYPE_H #include #endif #if DK_HAVE_STRING_H #include #endif #if DK_HAVE_ERRNO_H #include #endif #if DK_HAVE_IO_H #include #endif #if DK_HAVE_FCNTL_H #include #endif #if DK_HAVE_NETDB_H #include #endif #if DK_HAVE_ARPA_INET_H #include #endif #if DK_TIME_WITH_SYS_TIME #include #include #else #if DK_HAVE_TIME_H #include #else #if DK_HAVE_SYS_TIME_H #include #endif #endif #endif #if DK_HAVE_SYS_WAIT_H #include #endif #include "dktools-version.h" /** Mode: Run as sender. */ #define TCPTOOL_RUN_AS_SENDER 0x02 /** Mode: Run as recipient. */ #define TCPTOOL_RUN_AS_RECIPIENT 0x01 /** Mask to find mode. */ #define TCPTOOL_RUN_MASK (TCPTOOL_RUN_AS_SENDER | TCPTOOL_RUN_AS_RECIPIENT) /** Command: Show help text. */ #define TCPTOOL_CMD_HELP 1 /** Command: Show version. */ #define TCPTOOL_CMD_VERSION 2 #ifdef ON_WINDOWS_SYSTEM #undef ON_WINDOWS_SYSTEM #endif #if defined(_WIN32) || defined(WIN32) /** Indicator: On a Windows system. */ #define ON_WINDOWS_SYSTEM 1 #else #if defined(_WIN64) || defined(WIN64) /** Indicator: On a Windows system. */ #define ON_WINDOWS_SYSTEM 1 #endif #endif #if ON_WINDOWS_SYSTEM /* +++++ Windows */ /** Create socket. */ #define TCP_SOCKET(a,b,c) socket(a, b, c) /** Check whether socket is OK. */ #define TCP_OK_SOCKET(s) s != INVALID_SOCKET /** Close socket. */ #define TCP_CLOSE_SOCKET(s) closesocket(s) /** Data type used for socket. */ #define TCP_TYPE_SOCKET SOCKET /** Return type of read/write operations. */ #define TCP_TYPE_READ_WRITE int /** Listen for incoming connection requests. */ #define TCP_LISTEN(a,b) listen(a, b) /** Accept incoming connection request. */ #define TCP_ACCEPT(a,b,c) accept(a, b, c) /** Connect socket. */ #define TCP_CONNECT(a,b,c) connect(a, b, c) /** Send data over socket. */ #define TCP_SEND(a,b,c,d) send(a, b, c, d) /** Receive data from socket. */ #define TCP_RECV(a,b,c,d) recv(a, b, c, d) /** Shutdown socket for write operations. */ #define TCP_SHUTDOWN_WRITE(s) shutdown(s, SD_SEND) /** Shutdown socket for read operations. */ #define TCP_SHUTDOWN_READ(s) shutdown(s, SD_RECEIVE) /** Start TCP/IP networking. */ #define TCP_START() tcpip_start() /** End TCP/IP networking. */ #define TCP_END() tcpip_end() /** Variable to activate TCP options. */ #define TCP_VARIABLE_YES int yes = 1 /** Set address as reusable. */ #define TCP_REUSEADDR(s) (void)setsockopt(\ s, SOL_SOCKET, SO_REUSEADDR, (const char *)(&yes), sizeof(yes)\ ) /** Bind local socket to address. */ #define TCP_BIND(a,b,c) bind(a, b, c) /* ----- Windows */ #else /* +++++ Unix/Linux */ /** Create socket. */ #define TCP_SOCKET(a,b,c) socket(a, b, c) /** Check whether socket is OK. */ #define TCP_OK_SOCKET(s) s > -1 /** Close socket. */ #define TCP_CLOSE_SOCKET(s) close(s) /** Return type of read/write operations. */ #define TCP_TYPE_READ_WRITE ssize_t /** Data type used for socket. */ #define TCP_TYPE_SOCKET int /** Listen for incoming connection requests. */ #define TCP_LISTEN(a,b) listen(a, b) /** Accept incoming connection request. */ #define TCP_ACCEPT(a,b,c) accept(a, b, c) /** Connect socket. */ #define TCP_CONNECT(a,b,c) connect(a, b, c) /** Send data over socket. */ #define TCP_SEND(a,b,c,d) send(a, b, c, d) /** Receive data from socket. */ #define TCP_RECV(a,b,c,d) recv(a, b, c, d) /** Shutdown socket for write operations. */ #define TCP_SHUTDOWN_WRITE(s) shutdown(s, SHUT_WR) /** Shutdown socket for read operations. */ #define TCP_SHUTDOWN_READ(s) shutdown(s, SHUT_RD) /** Start TCP/IP networking. */ #define TCP_START() tcpip_start() /** End TCP/IP networking. */ #define TCP_END() tcpip_end() /** Variable to activate TCP options. */ #define TCP_VARIABLE_YES int yes = 1 #if DK_HAVE_SETSOCKOPT #ifdef SO_REUSEADDR /** Set addrss as reusable. */ #define TCP_REUSEADDR(s) (void)setsockopt(\ s, SOL_SOCKET, SO_REUSEADDR, (const char *)(&yes), sizeof(yes)\ ) #else /** Set address as reusable. */ #define TCP_REUSEADDR(s) /* nix */ #endif #else /** Set address as reusable. */ #define TCP_REUSEADDR(s) /* nix */ #endif /** Bind local socket to address. */ #define TCP_BIND(a,b,c) bind(a, b, c) /* ----- Unix/Linux */ #endif /** TCPtool job. */ typedef struct { char *host_name; /**< Host name to connect. */ char *file_name; /**< File name. */ unsigned long max_clients; /**< Maximum number of clients. */ int exval; /**< Exit status. */ int cmd; /**< Command to run. */ int ll; /**< Log level. */ unsigned char sender_or_recipient; /**< Flag: Sender. */ unsigned char start_now; /**< Flag: Can start. */ unsigned short host_port; /**< Port number. */ #if ON_WINDOWS_SYSTEM unsigned long wait_timeout; /**< Timeout: Feedback from threads. */ #endif } TTJ; typedef struct sockaddr_in SOIN; #define SZSOIN sizeof(SOIN) /** Error information. */ typedef struct { int error_code; /**< Error code. */ time_t error_time; /**< Timestamp. */ unsigned long error_ip; /**< Peer IP. */ unsigned short error_port; /**< Peer port. */ } TCPTOOL_ERROR_INFO; /** TCPtool process. */ typedef struct { #if ON_WINDOWS_SYSTEM TCPTOOL_ERROR_INFO ei; /**< Error information. */ TTJ *ttj; /**< TCPtool job. */ TCP_TYPE_SOCKET socks; /**< Socket. */ unsigned long ip; /**< IP address of peer. */ unsigned long conn_no; /**< Connection number. */ #ifdef _MSC_VER #if _MSC_VER <= 1100 unsigned long thread_id; /**< Thread ID. */ #else uintptr_t thread_id; /**< Thread ID. */ #endif #else unsigned long thread_id; /**< Thread ID. */ #endif HANDLE hEventSlave; /**< Slave waits for event. */ HANDLE hEventMaster; /**< Master waits for event. */ unsigned char did_timeout; /**< Flag: Timeout occured. */ #else int data_write_head; /**< Data pipe write end (master). */ int data_read_head; /**< Data pipe read end (slave). */ int ctrl_write_head; /**< Control pipe write end (slave). */ int ctrl_read_head; /**< Control pipe read end (master). */ int socks; /**< Service socket. */ pid_t pid; /**< Slave pid (0 in the slave itself. */ unsigned long ip; /**< IP address of peer. */ unsigned short port; /**< IP port number of peer. */ unsigned long conn_no; /**< Connection number. */ #endif } TTPI; /** Error: No error occured, everything OK. */ #define TCPTOOL_ERROR_NONE 0 /** Error: Peer disconnected. */ #define TCPTOOL_ERROR_DISCONNECTED 1 /** Error: SIGPIPE occured (no reader for connection. */ #define TCPTOOL_ERROR_SIGPIPE 2 /** Error: Failed to send. */ #define TCPTOOL_ERROR_SENDFAILED 3 /** Error: Timeout in thread. */ #define TCPTOOL_ERROR_THREAD_TIMEOUT 4 /** Log level: Don't print message. */ #define TCPTOOL_LL_NONE 0 /** Log level: Error. */ #define TCPTOOL_LL_ERROR 1 /** Log level: Warning. */ #define TCPTOOL_LL_WARNING 2 /** Log level: Informational. */ #define TCPTOOL_LL_INFO 3 /** Log level: Progress. */ #define TCPTOOL_LL_PROGRESS 4 /** Log level: Debug. */ #define TCPTOOL_LL_DEBUG 5 #if DK_HAVE_SIGACTION /** Signal handler function type. */ typedef void SIGHANDLER(int); /** Refresh signal handler. */ #define SIGREFRESH(i,d) /* No need to do anything to refresh signal handler */ #else #if DK_HAVE_SIGSET /** Signal handler function type. */ typedef void SIGHANDLER(int); /** Refresh signal handler. */ #define SIGREFRESH(i,d) /* No need to do anything to refresh signal handler */ #else #if DK_HAVE_SIGNAL /** Signal handler function type. */ typedef void SIGHANDLER(int); /** Refresh signal handler. */ #define SIGREFRESH(i,d) signal(i,d); #else /** Signal handler function type. */ typedef void SIGHANDLER(int); /** Refresh signal handler. */ #define SIGREFRESH(i,d) /* No need to do anything to refresh signal handler */ #endif #endif #endif #endif