A small unix program to redirect TCP connection to another server and/or port.
/*
* tcpredir.c: redirect TCP connection to another server and/or port
*
* Original author: abbelf@usa.net
*
* $Id: tcpredir.c,v 1.3 2000/12/01 00:15:28 hanhua Exp $
*/
/*
* Compilation:
* cc -o tcpredir tcpredir.c [-lsocket -lnsl]
*
* Usage:
* tcpredir 4000 202.112.26.39 2323
* To redirect connection accepted on port 4000 to 202.112.26.39:2323
* tcpredir 4000 202.112.26.39 2323 1800
* To redirect connection and cut off the connection in half an hour
* tcpredir 4000 202.112.26.39 2323 0 2
* To redirect connection, monitor mode 2, without cutting off connection
*
* Comments:
* Monitor mode including 1(hex mode) 2(c string mode).
* This program goes into background automatically by folking a sub-process.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void reaper( int i )
{
int status;
while ( wait3( &status, WNOHANG, 0 ) > 0 )
;
}
int dflag = 0;
#define BUF_SIZE 4096
int main( int argc, char *argv[] )
{
int sock, cfd, sinsize, sfd, pid, idle;
struct sockaddr_in sin;
fd_set readfds;
unsigned char buf[BUF_SIZE];
struct timeval tv;
int n;
if ( 4 != argc && 5 != argc && 6 != argc )
{
char *p = strrchr( argv[0], '/' );
fprintf( stderr, "Usage: %s <port> <remote_ip> <remote_port>"
" [<idle_seconds> [<d_flag>]]\n",
p ? p+1 : argv[0] );
return 0;
}
if ( 6 == argc )
dflag = atoi( argv[5] );
if ( 5 == argc || 6 == argc )
idle = atoi( argv[4] );
else
idle = 0;
if ( ( sock = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
{
perror( "socket" );
return -1;
}
sin.sin_family = AF_INET;
sin.sin_port = htons( atoi( argv[1] ) );
sin.sin_addr.s_addr = INADDR_ANY;
if ( bind( sock, (struct sockaddr *) &sin, sizeof(sin) ) < 0 )
{
perror( "bind" );
return -1;
}
sinsize = sizeof(sin);
if ( getsockname( sock, (struct sockaddr *) & sin, &sinsize ) == -1 )
{
perror( "getsockname" );
return -1;
}
if ( listen( sock, 5 ) == -1 )
{
perror( "listen" );
return -1;
}
if ( ( pid = fork() ) )
{
printf( "%d\n", pid );
return 0;
}
setpgid( 0, 0 );
signal( SIGHUP, SIG_IGN );
signal( SIGINT, SIG_IGN );
signal( SIGQUIT, SIG_IGN );
signal( SIGALRM, SIG_IGN );
signal( SIGURG, SIG_IGN );
signal( SIGTSTP, SIG_IGN );
signal( SIGTTIN, SIG_IGN );
signal( SIGTTOU, SIG_IGN );
for(;;)
{
signal( SIGCHLD, reaper );
sinsize = sizeof(sin);
sfd = accept( sock, (struct sockaddr *)&sin, &sinsize );
if ( sfd == -1 )
continue;
pid = fork();
if ( 0 == pid )
break;
close( sfd );
}
close( sock );
sin.sin_family = PF_INET;
sin.sin_addr.s_addr = inet_addr( argv[2] );
sin.sin_port = htons( atoi( argv[3] ) );
cfd = socket( sin.sin_family, SOCK_STREAM, 0 );
if ( cfd < 0 )
{
char *errmsg = "Socket error\n";
send( sfd, errmsg, strlen( errmsg ), 0 );
return -1;
}
if ( connect( cfd, (struct sockaddr *) &sin, sizeof sin) )
{
char *errmsg = "Connecting failed\n";
send( sfd, errmsg, strlen( errmsg ), 0 );
return -1;
}
for (;;)
{
tv.tv_sec = idle;
tv.tv_usec = 0;
FD_ZERO( &readfds );
FD_SET( sfd, &readfds );
FD_SET( cfd, &readfds );
if ( select( sfd>cfd ? sfd+1 : cfd+1, &readfds, NULL, NULL,
idle > 0 ? &tv : NULL ) <= 0 )
break;
if ( FD_ISSET( cfd, &readfds ) )
{
n = recv( cfd, buf, BUF_SIZE, 0 );
if (n <= 0)
break;
send( sfd, buf, n, 0 );
}
if ( FD_ISSET( sfd, &readfds ) )
{
n = recv( sfd, buf, BUF_SIZE, 0 );
if (n <= 0)
break;
send( cfd, buf, n, 0 );
}
}
close( cfd );
close( sfd );
/* printf( "\n" ); */
exit( 0 );
return 0;
}
fork version
/*
* tcpredir.c: redirect TCP connection to another server and/or port
*
* Original author: abbelf@usa.net
*
* $Id: tcpredir.c,v 1.3 2000/12/01 00:15:28 hanhua Exp $
*/
/*
* Compilation:
* cc -o tcpredir tcpredir.c [-lsocket -lnsl]
*
* Usage:
* tcpredir 4000 202.112.26.39 2323
* To redirect connection accepted on port 4000 to 202.112.26.39:2323
* tcpredir 4000 202.112.26.39 2323 1800
* To redirect connection and cut off the connection in half an hour
* tcpredir 4000 202.112.26.39 2323 0 2
* To redirect connection, monitor mode 2, without cutting off connection
*
* Comments:
* Monitor mode including 1(hex mode) 2(c string mode).
* This program goes into background automatically by folking a sub-process.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void reaper( int i )
{
int status;
while ( wait3( &status, WNOHANG, 0 ) > 0 )
;
}
int dflag = 0;
#define BUF_SIZE 4096
int main( int argc, char *argv[] )
{
int sock, cfd, sinsize, sfd, pid, idle;
struct sockaddr_in sin;
fd_set readfds;
unsigned char buf[BUF_SIZE];
struct timeval tv;
int n;
if ( 4 != argc && 5 != argc && 6 != argc )
{
char *p = strrchr( argv[0], '/' );
fprintf( stderr, "Usage: %s <port> <remote_ip> <remote_port>"
" [<idle_seconds> [<d_flag>]]\n",
p ? p+1 : argv[0] );
return 0;
}
if ( 6 == argc )
dflag = atoi( argv[5] );
if ( 5 == argc || 6 == argc )
idle = atoi( argv[4] );
else
idle = 0;
if ( ( sock = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
{
perror( "socket" );
return -1;
}
sin.sin_family = AF_INET;
sin.sin_port = htons( atoi( argv[1] ) );
sin.sin_addr.s_addr = INADDR_ANY;
if ( bind( sock, (struct sockaddr *) &sin, sizeof(sin) ) < 0 )
{
perror( "bind" );
return -1;
}
sinsize = sizeof(sin);
if ( getsockname( sock, (struct sockaddr *) & sin, &sinsize ) == -1 )
{
perror( "getsockname" );
return -1;
}
if ( listen( sock, 5 ) == -1 )
{
perror( "listen" );
return -1;
}
if ( ( pid = fork() ) )
{
printf( "%d\n", pid );
return 0;
}
setpgid( 0, 0 );
signal( SIGHUP, SIG_IGN );
signal( SIGINT, SIG_IGN );
signal( SIGQUIT, SIG_IGN );
signal( SIGALRM, SIG_IGN );
signal( SIGURG, SIG_IGN );
signal( SIGTSTP, SIG_IGN );
signal( SIGTTIN, SIG_IGN );
signal( SIGTTOU, SIG_IGN );
for(;;)
{
signal( SIGCHLD, reaper );
sinsize = sizeof(sin);
sfd = accept( sock, (struct sockaddr *)&sin, &sinsize );
if ( sfd == -1 )
continue;
pid = fork();
if ( 0 == pid )
break;
close( sfd );
}
close( sock );
sin.sin_family = PF_INET;
sin.sin_addr.s_addr = inet_addr( argv[2] );
sin.sin_port = htons( atoi( argv[3] ) );
cfd = socket( sin.sin_family, SOCK_STREAM, 0 );
if ( cfd < 0 )
{
char *errmsg = "Socket error\n";
send( sfd, errmsg, strlen( errmsg ), 0 );
return -1;
}
if ( connect( cfd, (struct sockaddr *) &sin, sizeof sin) )
{
char *errmsg = "Connecting failed\n";
send( sfd, errmsg, strlen( errmsg ), 0 );
return -1;
}
if(fork() == 0) { // child
for (;;)
{
n = recv( cfd, buf, BUF_SIZE, 0 );
if (n <= 0) break;
send( sfd, buf, n, 0 );
}
} else {
for (;;)
{
n = recv( sfd, buf, BUF_SIZE, 0 );
if (n <= 0) break;
send( cfd, buf, n, 0 );
}
}
close( cfd );
close( sfd );
/* printf( "\n" ); */
exit( 0 );
return 0;
}
원본: http://abbelfy.tripod.com/tcpredir.c
/*
* tcpredir.c: redirect TCP connection to another server and/or port
*
* Author: abbelf@usa.net
*
* $Id: tcpredir.c,v 1.3 2000/12/01 00:15:28 hanhua Exp $
*/
/*
* Compilation:
* cc -o tcpredir tcpredir.c [-lsocket -lnsl]
*
* Usage:
* tcpredir 4000 202.112.26.39 2323
* To redirect connection accepted on port 4000 to 202.112.26.39:2323
* tcpredir 4000 202.112.26.39 2323 1800
* To redirect connection and cut off the connection in half an hour
* tcpredir 4000 202.112.26.39 2323 0 2
* To redirect connection, monitor mode 2, without cutting off connection
*
* Comments:
* Monitor mode including 1(hex mode) 2(c string mode).
* This program goes into background automatically by folking a sub-process.
*/
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void reaper( int i )
{
int status;
while ( wait3( &status, WNOHANG, 0 ) > 0 )
;
}
int dflag = 0;
void debug( unsigned char ch, int n )
{
static char buf[2][82];
static int p[2] = { 0, 0 };
if ( dflag == 0 )
return;
if ( dflag == 1 )
{
printf("%c%02X", n ? '>' : '<', ch );
return;
}
if ( dflag == 2 )
{
switch( ch )
{
case '\r':
buf[n][p[n]++] = '\\';
buf[n][p[n]++] = 'r';
break;
case '\n':
buf[n][p[n]++] = '\\';
buf[n][p[n]++] = 'n';
buf[n][p[n]] = '\0';
p[n] = 78;
break;
case '\t':
buf[n][p[n]++] = '\\';
buf[n][p[n]++] = 't';
break;
case '\\':
buf[n][p[n]++] = '\\';
buf[n][p[n]++] = '\\';
break;
default:
if ( ch >= 0x20 && ch < 0x7f )
{
buf[n][p[n]++] = ch;
}
else
{
buf[n][p[n]++] = '\\';
buf[n][p[n]++] = 'x';
buf[n][p[n]++] = ch/16 >= 10 ? ch/16 + 'A' - 10 : ch/16 + '0';
buf[n][p[n]++] = ch%16 >= 10 ? ch%16 + 'A' - 10 : ch%16 + '0';
}
}
if ( p[n] >= 76 )
{
buf[n][p[n]] = '\0';
printf( "%c%s\n", n ? '>' : '<', buf[n] );
p[n] = 0;
}
}
}
int main( int argc, char *argv[] )
{
int sock, cfd, sinsize, sfd, pid, idle;
struct sockaddr_in sin;
fd_set readfds;
unsigned char ch;
struct timeval tv;
if ( 4 != argc && 5 != argc && 6 != argc )
{
char *p = strrchr( argv[0], '/' );
fprintf( stderr, "Usage: %s <port> <remote_ip> <remote_port>"
" [<idle_seconds> [<d_flag>]]\n",
p ? p+1 : argv[0] );
return 0;
}
if ( 6 == argc )
dflag = atoi( argv[5] );
if ( 5 == argc || 6 == argc )
idle = atoi( argv[4] );
else
idle = 0;
if ( ( sock = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
{
perror( "socket" );
return -1;
}
sin.sin_family = AF_INET;
sin.sin_port = htons( atoi( argv[1] ) );
sin.sin_addr.s_addr = INADDR_ANY;
if ( bind( sock, (struct sockaddr *) &sin, sizeof(sin) ) < 0 )
{
perror( "bind" );
return -1;
}
sinsize = sizeof(sin);
if ( getsockname( sock, (struct sockaddr *) & sin, &sinsize ) == -1 )
{
perror( "getsockname" );
return -1;
}
if ( listen( sock, 5 ) == -1 )
{
perror( "listen" );
return -1;
}
if ( ( pid = fork() ) )
{
printf( "%d\n", pid );
return 0;
}
setpgid( 0, 0 );
signal( SIGHUP, SIG_IGN );
signal( SIGINT, SIG_IGN );
signal( SIGQUIT, SIG_IGN );
signal( SIGALRM, SIG_IGN );
signal( SIGURG, SIG_IGN );
signal( SIGTSTP, SIG_IGN );
signal( SIGTTIN, SIG_IGN );
signal( SIGTTOU, SIG_IGN );
for(;;)
{
signal( SIGCHLD, reaper );
sinsize = sizeof(sin);
sfd = accept( sock, (struct sockaddr *)&sin, &sinsize );
if ( sfd == -1 )
continue;
pid = fork();
if ( 0 == pid )
break;
close( sfd );
}
close( sock );
sin.sin_family = PF_INET;
sin.sin_addr.s_addr = inet_addr( argv[2] );
sin.sin_port = htons( atoi( argv[3] ) );
cfd = socket( sin.sin_family, SOCK_STREAM, 0 );
if ( cfd < 0 )
{
char *errmsg = "Socket error\n";
send( sfd, errmsg, strlen( errmsg ), 0 );
return -1;
}
if ( connect( cfd, (struct sockaddr *) &sin, sizeof sin) )
{
char *errmsg = "Connecting failed\n";
send( sfd, errmsg, strlen( errmsg ), 0 );
return -1;
}
for (;;)
{
tv.tv_sec = idle;
tv.tv_usec = 0;
FD_ZERO( &readfds );
FD_SET( sfd, &readfds );
FD_SET( cfd, &readfds );
if ( select( sfd>cfd ? sfd+1 : cfd+1, &readfds, NULL, NULL,
idle > 0 ? &tv : NULL ) <= 0 )
break;
if ( FD_ISSET( cfd, &readfds ) )
{
if ( 1 != recv( cfd, &ch, 1, 0 ) )
break;
send( sfd, &ch, 1, 0 );
debug( ch, 1 );
}
if ( FD_ISSET( sfd, &readfds ) )
{
if ( 1 != recv( sfd, &ch, 1, 0 ) )
break;
send( cfd, &ch, 1, 0 );
debug( ch, 0 );
}
}
close( cfd );
close( sfd );
/* printf( "\n" ); */
exit( 0 );
return 0;
}
'Programming' 카테고리의 다른 글
| (C, Unix) Joinc: select를 이용한 입출력 다중화 (0) | 2013.04.26 |
|---|---|
| (C) Unix Daemon Server Programming (0) | 2013.04.24 |
| C++ 0x : 람다(Lambda) (0) | 2013.04.14 |
| (Visual C++ 2010) Examples of Lambda Expressions (0) | 2013.04.14 |
| (JavaScript) How to make a cool $() selector (0) | 2013.04.09 |