00001
00002
00003
00004
00005 #include "rcs_defs.hh"
00006 #include "sokintrf.h"
00007 #include "linklist.hh"
00008 #include "rcs_prnt.hh"
00009 #include "tcp_opts.hh"
00010
00011
00012 #ifdef EXTERN_C_STD_HEADERS
00013 extern "C"
00014 {
00015 #endif
00016
00017 #include <string.h>
00018 #include <errno.h>
00019 #include <signal.h>
00020 #include <stdlib.h>
00021
00022 #ifdef EXTERN_C_STD_HEADERS
00023 }
00024 #endif
00025
00026
00027 extern "C"
00028 {
00029 #include "recvn.h"
00030 #include "sendn.h"
00031 }
00032
00033 class TCP_PROXY_ENTRY
00034 {
00035 public:
00036 SOCKET client_socket;
00037 SOCKET server_socket;
00038 struct sockaddr_in client_address;
00039 };
00040
00041 static int last_pipe_error_id = 0;
00042
00043 static void
00044 handle_pipe_error (int id)
00045 {
00046 last_pipe_error_id = id;
00047 rcs_print_error ("SIGPIPE intercepted.\n");
00048 }
00049
00050 int tcpproxy_quit = 0;
00051 static int last_sigint_id = 0;
00052
00053 static void
00054 handle_sigint (int id)
00055 {
00056 last_sigint_id = id;
00057 tcpproxy_quit = 1;
00058 }
00059
00060 #ifndef VXWORKS
00061 struct hostent *server_host_entry;
00062 #endif
00063
00064
00065 #ifdef VXWORKS
00066 extern "C" int tcpproxy (long local_port, char *remote_host,
00067 long remote_port);
00068
00069 int
00070 tcpproxy (long local_port, char *remote_host, long remote_port)
00071 {
00072 #else
00073
00074 int
00075 main (int argc, char **argv)
00076 {
00077 set_rcs_print_destination (RCS_PRINT_TO_STDOUT);
00078
00079 if (argc < 3)
00080 {
00081 rcs_print_error ("insufficient arguments (%d)\n", argc);
00082 rcs_print_error
00083 ("usage: tcpproxy local-port remote-host [remote-port]\n");
00084 rcs_print_error (" Some interesting ports to try:\n");
00085 rcs_print_error (" \tEcho: \t7\n");
00086 rcs_print_error (" \tFTP: \t21\n");
00087 rcs_print_error (" \tTelnet: \t23\n");
00088 rcs_print_error (" \tHTTP: \t80\n");
00089 exit (-1);
00090 }
00091
00092 long local_port = strtol (argv[1], NULL, 0);
00093 char *remote_host = argv[2];
00094 long remote_port = 0;
00095
00096
00097 if (argc > 3)
00098 {
00099 remote_port = strtol (argv[3], NULL, 0);
00100 }
00101 else
00102 {
00103 remote_port = local_port;
00104 }
00105
00106 #endif
00107
00108 RCS_LINKED_LIST *proxy_sockets = NULL;
00109 struct sockaddr_in proxy_socket_address;
00110 struct sockaddr_in proxy_client_socket_address;
00111 struct sockaddr_in server_socket_address;
00112
00113 if (load_socket_interface () < 0)
00114 {
00115 rcs_print_error ("Can't load socket interface.\n");
00116 exit (-1);
00117 }
00118 proxy_sockets = new RCS_LINKED_LIST;
00119
00120
00121
00122 server_socket_address.sin_family = AF_INET;
00123 #ifndef VXWORKS
00124 dl_gethostbyname (remote_host, &server_host_entry);
00125 if (NULL == server_host_entry)
00126 {
00127 rcs_print_error ("Couldn't get host address for (%s).\n", remote_host);
00128 #if defined(_WINDOWS)
00129 rcs_print_error ("WSA error = %d\n", dl_WSAGetLastError ());
00130 #endif
00131 exit (-1);
00132 }
00133 #ifdef __MSDOS__
00134 server_socket_address.sin_addr.s_addr =
00135 *((u_long *) server_host_entry->h_addr_list[0]);
00136 #else
00137 server_socket_address.sin_addr.s_addr =
00138 *((int *) server_host_entry->h_addr_list[0]);
00139 #endif
00140 #else
00141 server_socket_address.sin_addr.s_addr = hostGetByName (remote_host);
00142 if (server_socket_address.sin_addr.s_addr == ERROR)
00143 {
00144 rcs_print_error ("TCPMEM: Couldn't get host address for (%s).\n",
00145 remote_host);
00146 exit (-1);
00147 }
00148 #endif
00149 server_socket_address.sin_port = dl_htons ((unsigned short) remote_port);
00150
00151 memset (&proxy_socket_address, 0, sizeof (proxy_socket_address));
00152 proxy_socket_address.sin_family = AF_INET;
00153 proxy_socket_address.sin_addr.s_addr = dl_htonl (INADDR_ANY);
00154 proxy_socket_address.sin_port = dl_htons (local_port);
00155
00156 rcs_print_debug (PRINT_CMS_CONFIG_INFO,
00157 "Registering server on TCP port %d.\n",
00158 dl_ntohs (proxy_socket_address.sin_port));
00159 if (proxy_socket_address.sin_port == 0)
00160 {
00161 rcs_print_error ("server can not register on port number 0.\n");
00162 exit (-1);
00163 }
00164 SOCKET connection_socket;
00165
00166 if ((long) (connection_socket = dl_socket (AF_INET, SOCK_STREAM, 0)) <= 0)
00167 {
00168 rcs_print_error ("socket error: %d -- %s\n", errno, strerror (errno));
00169 rcs_print_error ("Server can not open stream socket.\n");
00170 exit (-1);
00171 }
00172
00173 if (set_tcp_socket_options (connection_socket) < 0)
00174 {
00175 exit (-1);
00176 }
00177 if (dl_bind (connection_socket, (struct sockaddr *) &proxy_socket_address,
00178 sizeof (proxy_socket_address)) < 0)
00179 {
00180 rcs_print_error ("bind error: %d -- %s\n", errno, strerror (errno));
00181 rcs_print_error
00182 ("Server can not bind the connection socket on port %d.\n",
00183 dl_ntohs (proxy_socket_address.sin_port));
00184 exit (-1);
00185 }
00186 if (dl_listen (connection_socket, 5) < 0)
00187 {
00188 rcs_print_error ("listen error: %d -- %s\n", errno, strerror (errno));
00189 rcs_print_error ("TCP Server: error on call to listen for port %d.\n",
00190 dl_ntohs (server_socket_address.sin_port));
00191 exit (-1);
00192 }
00193
00194 unsigned long bytes_ready;
00195 int ready_descriptors;
00196 fd_set read_fd_set, write_fd_set;
00197 FD_ZERO (&read_fd_set);
00198 FD_ZERO (&write_fd_set);
00199 RCS_FD_SET (connection_socket, &read_fd_set);
00200 SOCKET maxfdpl;
00201 maxfdpl = connection_socket + 1;
00202 TCP_PROXY_ENTRY *current_entry;
00203
00204 #ifndef DOS_WINDOWS
00205 signal (SIGPIPE, handle_pipe_error);
00206 #endif
00207 signal (SIGINT, handle_sigint);
00208 rcs_print
00209 ("Running TCP proxy for:\n (TCP port %d) \n(connection_socket = %d)\n(remote_host = %s)\n(server_IP_address = %s)\n(remote_port = %d)",
00210 dl_ntohs (proxy_socket_address.sin_port), connection_socket, remote_host,
00211 dl_inet_ntoa (server_socket_address.sin_addr), remote_port);
00212
00213 char temp_buffer[4096];
00214
00215 while (!tcpproxy_quit)
00216 {
00217 ready_descriptors =
00218 dl_select (maxfdpl,
00219 &read_fd_set,
00220 &write_fd_set, (fd_set *) NULL, (timeval *) NULL);
00221 if (ready_descriptors < 0)
00222 {
00223 rcs_print_error
00224 ("select(%d,%d,%d,NULL,NULL) error.(errno = %d | %s)\n", maxfdpl,
00225 read_fd_set, write_fd_set, errno, strerror (errno));
00226 continue;
00227 }
00228 current_entry = (TCP_PROXY_ENTRY *) proxy_sockets->get_head ();
00229 while (NULL != current_entry)
00230 {
00231 if (dl_fd_isset (current_entry->client_socket, &read_fd_set))
00232 {
00233 ready_descriptors--;
00234 dl_ioctlsocket (current_entry->client_socket, FIONREAD,
00235 &bytes_ready);
00236 if (bytes_ready == 0)
00237 {
00238 rcs_print ("Socket closed by host with IP address %s.\n",
00239 dl_inet_ntoa (current_entry->client_address.
00240 sin_addr));
00241 dl_closesocket (current_entry->server_socket);
00242 dl_closesocket (current_entry->client_socket);
00243 if (dl_fd_isset
00244 (current_entry->server_socket, &read_fd_set))
00245 {
00246 RCS_FD_CLR (current_entry->server_socket, &read_fd_set);
00247 }
00248 if (dl_fd_isset
00249 (current_entry->client_socket, &read_fd_set))
00250 {
00251 RCS_FD_CLR (current_entry->client_socket, &read_fd_set);
00252 }
00253 proxy_sockets->delete_current_node ();
00254 current_entry =
00255 (TCP_PROXY_ENTRY *) proxy_sockets->get_next ();
00256 continue;
00257 }
00258 else
00259 {
00260 while (bytes_ready > 0)
00261 {
00262 if (bytes_ready > 4096)
00263 {
00264 recvn (current_entry->client_socket, temp_buffer,
00265 4096, 0, -1, NULL);
00266 sendn (current_entry->server_socket, temp_buffer,
00267 4096, 0, -1);
00268 bytes_ready -= 4096;
00269 }
00270 else
00271 {
00272 recvn (current_entry->client_socket, temp_buffer,
00273 bytes_ready, 0, -1, NULL);
00274 sendn (current_entry->server_socket, temp_buffer,
00275 bytes_ready, 0, -1);
00276 bytes_ready = 0;
00277 break;
00278 }
00279 }
00280 }
00281 }
00282 else
00283 {
00284 RCS_FD_SET (current_entry->client_socket, &read_fd_set);
00285 }
00286 if (dl_fd_isset (current_entry->server_socket, &read_fd_set))
00287 {
00288 ready_descriptors--;
00289 #ifdef WIN32
00290 dl_ioctlsocket (current_entry->server_socket, FIONREAD,
00291 &bytes_ready);
00292 #else
00293 #ifndef VXWORKS
00294 ioctl (current_entry->server_socket, FIONREAD,
00295 (caddr_t) & bytes_ready);
00296 #else
00297 ioctl (current_entry->server_socket, FIONREAD,
00298 (int) &bytes_ready);
00299 #endif
00300 #endif
00301 if (bytes_ready == 0)
00302 {
00303 rcs_print ("Socket closed by host with IP address %s.\n",
00304 dl_inet_ntoa (server_socket_address.sin_addr));
00305 dl_closesocket (current_entry->server_socket);
00306 dl_closesocket (current_entry->client_socket);
00307 if (dl_fd_isset
00308 (current_entry->server_socket, &read_fd_set))
00309 {
00310 RCS_FD_CLR (current_entry->server_socket, &read_fd_set);
00311 }
00312 if (dl_fd_isset
00313 (current_entry->client_socket, &read_fd_set))
00314 {
00315 RCS_FD_CLR (current_entry->client_socket, &read_fd_set);
00316 }
00317 proxy_sockets->delete_current_node ();
00318 current_entry =
00319 (TCP_PROXY_ENTRY *) proxy_sockets->get_next ();
00320 continue;
00321 }
00322 else
00323 {
00324 while (bytes_ready > 0)
00325 {
00326 if (bytes_ready > 4096)
00327 {
00328 recvn (current_entry->server_socket, temp_buffer,
00329 4096, 0, -1, NULL);
00330 sendn (current_entry->client_socket, temp_buffer,
00331 4096, 0, -1);
00332 bytes_ready -= 4096;
00333 }
00334 else
00335 {
00336 recvn (current_entry->server_socket, temp_buffer,
00337 bytes_ready, 0, -1, NULL);
00338 sendn (current_entry->client_socket, temp_buffer,
00339 bytes_ready, 0, -1);
00340 bytes_ready = 0;
00341 break;
00342 }
00343 }
00344 }
00345 }
00346 else
00347 {
00348 RCS_FD_SET (current_entry->server_socket, &read_fd_set);
00349 }
00350 current_entry = (TCP_PROXY_ENTRY *) proxy_sockets->get_next ();
00351 }
00352 if (dl_fd_isset (connection_socket, &read_fd_set)
00353 && ready_descriptors > 0)
00354 {
00355 ready_descriptors--;
00356 current_entry = new TCP_PROXY_ENTRY;
00357 if (NULL == current_entry)
00358 {
00359 continue;
00360 }
00361 current_entry->server_socket = dl_socket (AF_INET, SOCK_STREAM, 0);
00362 if (((long) current_entry->server_socket) <= 0)
00363 {
00364 rcs_print_error ("Error from socket() (errno = %d:%s)\n",
00365 errno, strerror (errno));
00366 delete current_entry;
00367 continue;
00368 }
00369 proxy_client_socket_address.sin_family = AF_INET;
00370 proxy_client_socket_address.sin_addr.s_addr = dl_htonl (INADDR_ANY);
00371 proxy_client_socket_address.sin_port = dl_htons (0);
00372
00373 if (dl_bind (current_entry->server_socket,
00374 (struct sockaddr *) &proxy_client_socket_address,
00375 sizeof (proxy_client_socket_address)) < 0)
00376 {
00377 #if defined(_Windows) && !defined(USE_PCNFS)
00378 rcs_print_error (" bind error %d\n", dl_WSAGetLastError ());
00379 #else
00380 rcs_print_error (" bind error %d = %s\n", errno,
00381 strerror (errno));
00382 #endif
00383 delete current_entry;
00384 continue;
00385 }
00386 if (dl_connect (current_entry->server_socket,
00387 (struct sockaddr *) &server_socket_address,
00388 sizeof (server_socket_address)) < 0)
00389 {
00390 #if defined(_WINDOWS) && !defined(USE_PCNFS)
00391 rcs_print_error ("Couldn't connect. Error = (%d)\n",
00392 dl_WSAGetLastError ());
00393 #else
00394 rcs_print_error ("Couldn't connect. Error = (%d:%s)\n",
00395 errno, strerror (errno));
00396 #endif
00397 delete current_entry;
00398 current_entry = NULL;
00399 continue;
00400 }
00401 int client_address_length;
00402 client_address_length = sizeof (current_entry->client_address);
00403 current_entry->client_socket = dl_accept (connection_socket,
00404 (struct sockaddr *)
00405 &
00406 (current_entry->
00407 client_address),
00408 &client_address_length);
00409 if (((long) current_entry->client_socket) <= 0)
00410 {
00411 #if defined(_WINDOWS) && !defined(USE_PCNFS)
00412 rcs_print_error ("accept error = (%d)\n",
00413 dl_WSAGetLastError ());
00414 #else
00415 rcs_print_error ("accept error = (%d:%s)\n",
00416 errno, strerror (errno));
00417 #endif
00418 continue;
00419 }
00420 rcs_print ("Socket opened by host with IP address %s.\n",
00421 dl_inet_ntoa (current_entry->client_address.sin_addr));
00422 if (NULL != proxy_sockets)
00423 {
00424 proxy_sockets->store_at_tail (current_entry,
00425 sizeof (TCP_PROXY_ENTRY), 0);
00426 }
00427 if (maxfdpl < current_entry->client_socket + 1)
00428 {
00429 maxfdpl = current_entry->client_socket + 1;
00430 }
00431 if (maxfdpl < current_entry->server_socket + 1)
00432 {
00433 maxfdpl = current_entry->server_socket + 1;
00434 }
00435 RCS_FD_SET (current_entry->server_socket, &read_fd_set);
00436 RCS_FD_SET (current_entry->client_socket, &read_fd_set);
00437 }
00438 else
00439 {
00440 RCS_FD_SET (connection_socket, &read_fd_set);
00441 }
00442 if (0 != ready_descriptors)
00443 {
00444 rcs_print_error ("%d descriptors ready but not serviced.\n",
00445 ready_descriptors);
00446 }
00447 }
00448
00449
00450 current_entry = (TCP_PROXY_ENTRY *) proxy_sockets->get_head ();
00451 while (NULL != current_entry)
00452 {
00453 dl_closesocket (current_entry->server_socket);
00454 dl_closesocket (current_entry->client_socket);
00455 current_entry = (TCP_PROXY_ENTRY *) proxy_sockets->get_next ();
00456 }
00457 dl_closesocket (connection_socket);
00458 delete proxy_sockets;
00459 exit (0);
00460 }