csocket_forward.c #include <stdio.h> #include <stdlib.h> #include <winsock2.h> int error (char *s) { printf ("%s/n", s); return 0; } void info (char *s) { puts (s); } int usage() { printf ("forward request to localhost:local_port to remote_ip:remote_port/n"); printf ("csockfwd.exe {local_port} {remote_ip} {remote_port}/n"); } int main (int argc, char *argv[]) { if (argc < 4) return usage (0); /* check version */ WORD wVersionRequested = MAKEWORD (2,2); WSADATA wsaData; WSAStartup (wVersionRequested, &wsaData); if (wsaData.wVersion != wVersionRequested) return error ("Wrong Version of Winsock2"); int local_port = atoi (argv[1]); int remote_port = atoi (argv[3]); return tcp_forward (local_port, argv[2], remote_port); } tcp_forward.c #include <winsock2.h> #define BUF_SIZE 1024 const unsigned int nTimeout = 200; static unsigned int local_port; static char remote_ip [128]; static unsigned int remote_port; static SOCKADDR_IN local_server; static SOCKET listen_sock; static SOCKET request_sock; static SOCKADDR_IN remote_server; static SOCKET remote_sock; static LPHOSTENT remote_host; int teardown (char *s) { if (listen_sock) closesocket (listen_sock); if (request_sock) closesocket (request_sock); if (remote_sock) closesocket (remote_sock); WSACleanup(); if (strlen (s) > 0) return error (s); return 1; } DWORD WINAPI client_thread (LPVOID lpParam) { return 0; } int tcp_forward (int localport, char * remoteip, int remoteport) { /* HANDLE handler_thread; DWORD thread_id; */ local_port = localport; strcpy (remote_ip, remoteip); remote_port = remoteport; int nret; remote_host = gethostbyname (remote_ip); if (remote_host == NULL) return error ("remote server NO found"); remote_server.sin_family = AF_INET; remote_server.sin_addr = * ( (LPIN_ADDR) *remote_host->h_addr_list); remote_server.sin_port = htons (remote_port); local_server.sin_family = AF_INET; local_server.sin_addr.s_addr = INADDR_ANY; local_server.sin_port = htons (local_port); listen_sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (listen_sock == INVALID_SOCKET) return error ("local socket failure"); /* start to listen */ nret = bind (listen_sock, (LPSOCKADDR) &local_server, sizeof (local_server)); if (nret == SOCKET_ERROR) return teardown ("local bind failure"); setsockopt (listen_sock, SOL_SOCKET, SO_RCVTIMEO, (char*) &nTimeout, sizeof (nTimeout)); int recvc; int sentc; int request_len = 0; int result_len = 0; char buf[BUF_SIZE]; nret = listen (listen_sock, SOMAXCONN); if (nret == SOCKET_ERROR) return teardown ("local listen failure"); /* waiting for incoming request */ while (1) { request_sock = accept (listen_sock, NULL, NULL); if (request_sock == INVALID_SOCKET) return teardown ("local accept failure"); /* connecting to remote server */ remote_sock = socket (AF_INET, SOCK_STREAM, IPPROTO_IP); if (remote_sock == INVALID_SOCKET) return error ("remote socket error"); nret = connect (remote_sock, (LPSOCKADDR) &remote_server, sizeof (remote_server)); if (nret == INVALID_SOCKET) return teardown ("remote connect error"); setsockopt (remote_sock, SOL_SOCKET, SO_RCVTIMEO, (char*) &nTimeout, sizeof (nTimeout)); do { buf[0] = '/0'; request_len = recv (request_sock, buf, BUF_SIZE, 0); if (request_len > 0) { nret = send (remote_sock, buf, request_len, 0); if (nret != request_len) error ("relay request size mismatch"); } } while (request_len > 0); do { buf[0] = '/0'; result_len = recv (remote_sock, buf, BUF_SIZE, 0); if (result_len > 0) { nret = send (request_sock, buf, result_len, 0); if (nret != result_len) error ("relay result size mismatch"); } } while (result_len > 0); /* out of do-while */ shutdown (remote_sock, SD_BOTH); closesocket (remote_sock); shutdown (request_sock, SD_BOTH); closesocket (request_sock); } /* out while */ closesocket (listen_sock); WASCleanup(); return 0; }