Ale potrzebujesz takie proxy po udp czy TCP? Poniżej kod prostego redirectora w warstwie aplikacyjnej. Instrukcja jak użyć i skompilować na początku pliku.
/* 21.3.97 - opravena chybna manipulace s procesy (uz nevytvari zive mrtvoly) -+= chaky =+-
*/
/* 3.8.97 - Pridan parametr -n pro zmenu jmena procesu pro lepsi maskovani ;) -+= chaky =+-
*/
/* 21.11 Zmena - moze sa specifikovat uid a gid pod ktorym to vsetko bezi */
/* redirect v2.0 * By Alhambra ( snipped-for-privacy@infonexus.com) * and * Maurautius ( snipped-for-privacy@leet.com) * October 6, 1996 * Usage: * redirector [-p localport] [-h remotehost] [-r remoteport] * ie: * redirector -p 4300 * redirector -p 4400 -h whitehouse.gov -r 25 * * Should be fairly portable...to compile on: * Solaris: gcc redirector.c -lsocket -lnsl -o redirector * Linux: gcc redirector.c -DLINUX -o redirector * Irix: gcc redirector.c -o redirector * SunOs: gcc redirector.c -o redirector * You get the idea... * * * By default, it now runs on a port which is #defined a few lines down... * This way, it's a little less obvious what it is from a ps -ef * * * This version also has passwording on the socket. So, when you connect, the * first thing you need to type in the password, followed by a cr. The default * password is xxxxx (but you'll change this, right?). SO you'd do something * like: * telnet foobar.com 4678 * Trying 3.1.3.37 * Connected to foobar.com * Escape character is '^]'. * xxxxx * placetogo.com porttogoto * * And you'll be automagically there. There's also a dynamic static mode... * read the source, and you'll figure it out. */
/* Maximum time for user interaction and connection */ #define INTERACTION_TIMEOUT 60 #define CONNECTION_TIMEOUT 100 #define REDIR_TIMEOUT 180 #define DEFAULT_PORT 19750 #define UID 7000 #define GID 500
#include <sys/types.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/param.h>
#include <sys/times.h>
#ifdef LINUX #include <sys/time.h>
#endif #include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/signal.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <sys/stat.h>
static char localip[64];
typedef void Sigfunc(int);
extern int errno;
void usage (char *progname) { fprintf (stderr, "%s: -l LOCALIP -p LOCALPORT -h REMOTEHOST -r REMOTEPORT [-n NEWCMDNAME]\n", progname); fprintf (stderr, "example: %s -l 192.168.2.1 -p 9100 -h foo.bar.com -r 25 -n httpd\n", progname); fflush (stderr); exit (1); }
int set_fl (int fd, int flags) { /* set file descriptor props */ int val; if ((val = fcntl (fd, F_GETFL, 0)) < 0) return (-1); val |= flags; if ((fcntl (fd, F_SETFL, val)) < 0) return (-1); return (0); }
/*------------------------------------------------ * s e t u p _ s o c k e t * */ int setup_socket (int *tcpsocket, short port) { /* set up incoming socket */ int flag=1; struct sockaddr_in serv_addr;
if ((*tcpsocket = socket (AF_INET, SOCK_STREAM, 0)) < 0) { printf("socket (AF_INET, SOCK_STREAM, 0)) < 0\n"); exit (-1); }
setsockopt(*tcpsocket, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));
memset (&serv_addr, 0, sizeof (serv_addr));
serv_addr.sin_family = AF_INET; // serv_addr.sin_addr.s_addr = htonl (INADDR_ANY); // //inet_aton(localip, &serv_addr.sin_addr); serv_addr.sin_addr.s_addr = inet_addr(localip); serv_addr.sin_port = htons (port); setsockopt(*tcpsocket,SOL_SOCKET,SO_REUSEADDR,0,0); setsockopt(*tcpsocket,SOL_SOCKET,SO_LINGER,0,0); if (bind (*tcpsocket, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0){ printf("can't bind to %s \n",localip); return (-1);
}
return (0); }
void feed_through (int tcpfd, int outfd) {
fd_set fdvar; char buffer[8192]; int width; size_t numbytes;
width = (tcpfd > outfd) ? tcpfd + 1 : outfd + 1;
set_fl (outfd, O_NONBLOCK); set_fl (outfd, O_NONBLOCK);
while (1) { FD_ZERO (&fdvar); FD_SET (tcpfd, &fdvar); FD_SET (outfd, &fdvar);
select (width, &fdvar, (fd_set *) 0, (fd_set *) 0, NULL); if (FD_ISSET (tcpfd, &fdvar)) { if ((numbytes = read (tcpfd, buffer, sizeof (buffer))) == 0) { alarm (0); return; }; if ((write (outfd, buffer, numbytes)) != numbytes) { alarm (0); exit (-1); } } else if (FD_ISSET (outfd, &fdvar)) { /* Read from the outfd and write to the tcp */ if ((numbytes = read (outfd, buffer, sizeof (buffer))) == 0) { alarm (0); return; }; if ((write (tcpfd, buffer, numbytes)) != numbytes) { alarm (0); exit (-1); } } else { alarm (0); exit (-1); } } alarm (0); };
/*-------------------------------------------------- * This does the happy UNIX daemon initialization..... * * Taken from steven's book on unix programming. */ int daemon_init(void) { pid_t pid;
return; if ( (pid=fork()) < 0) return -1; else if (pid != 0) exit(0); /* parent goes bye-bye */
close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); setsid(); /* become session leader */ chdir("/"); /* change working directory */ umask(0); /* clear file creation mask */ setuid(UID); setgid(GID); return 0; }
/*------------------------------------------------ * f d g e t s * * fgets (almost) with a file descriptor instead of a stream * gets the next non-empty line. */ const char *newln = "\n\r"; int fdgets(char *buffer, int size, int fd) { int i=0; /* Start by skipping over any new lines */ if (read(fd, buffer, 1)==-1) return -1; while (strchr(newln, buffer[i])) if (read(fd, buffer, 1)==-1) return -1; /* Now start really reading the line */ while (buffer[i] != '\n' && i < size-1) { i++; if (read(fd, buffer+i, 1)==-1) return -1; }
/* Terminate the string */ buffer[i] = 0; return i; }
/*------------------------------------------------ * d o C o n n e c t */ int doConnect(char *hostname, short port) { int sockfd; struct sockaddr_in remote; struct hostent *host;
alarm (CONNECTION_TIMEOUT); /* Reset timeout */
sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) return -1; host = gethostbyname(hostname); if (!host) return -1;
remote.sin_family = AF_INET; memcpy(&remote.sin_addr, host->h_addr_list[0], sizeof(remote.sin_addr)); remote.sin_port = htons(port); if (connect(sockfd, (struct sockaddr *) &remote, sizeof(remote)) ==
-1) sockfd = -1;
alarm (0); return sockfd; }
/*------------------------------------------------ * s t a t i c R e d i r e c t */ void staticRedirect(short localport, char *hostname, short port) { int listen_sock, in_sock, out_sock; struct sockaddr_in client; int client_size;
alarm (REDIR_TIMEOUT);
if (setup_socket(&listen_sock, localport) == -1) exit(0); listen(listen_sock, 1); client_size = sizeof(client); in_sock = accept(listen_sock, (struct sockaddr *) &client, &client_size); if (in_sock == -1) exit(0);
out_sock = doConnect(hostname, port); if (out_sock == -1) exit(0); alarm(0);
feed_through(in_sock, out_sock); }
/*------------------------------------------------ * i n t e r a c t i o n */ #define BUFFSIZE 100 void interaction(int sockfd) { int outsock; char passwd[10]; char *sep = " \t\n\r"; char buffer[100]; char *tok; char *hostname, *port, *port2;
alarm(INTERACTION_TIMEOUT); /* Enable timeout */ /* avoid "strings" */ /* set up our 'password' string */ passwd[0] = 's'; passwd[1] = 'e'; passwd[2] = 'r'; passwd[3] = 't'; passwd[4] = 0; passwd[5] = 0;
/* Step 1: Check password */ if (fdgets(buffer, BUFFSIZE, sockfd) < 0) exit(0); tok = strtok(buffer, sep); if (!tok || strcmp(tok, passwd)) exit (0); /* Step 2: Get command */ if (fdgets(buffer, BUFFSIZE, sockfd) < 0) exit(0);
hostname = strtok(buffer, sep); port = strtok(NULL, sep); port2 = strtok(NULL, sep);
if (strtok(0,sep)) exit(0); /* Bail if there's trailing crap */
if (!port) exit(0); /* User gave bogus line... */
alarm(0); /* Disable timeout */ if (!port2) { outsock = doConnect(hostname, atoi(port)); if (outsock == -1) exit(0); feed_through(sockfd, outsock); } else { /*-- One-the-fly redirction -----------------*/ close(sockfd); /* Get rid of user */ staticRedirect(atoi(port2), hostname, atoi(port)); }
exit(0); }
/*------------------------------------------------ * m a i n */ int main (int argc, char *argv[]) { int c;
int dset = 0, hset = 0,i; int port = DEFAULT_PORT; char *host=0, *n_cmdname,cmdtext[255]; int remote=0;
int tcpfd, tcpsocket; struct sockaddr_in client_addr; int client_len;
pid_t pid; int outfd;
localip[0]=0;
while ((c = getopt (argc, argv, "p:r:h:n:l:")) != -1) switch (c) { case 'p': port = atoi (optarg); break; case 'r': remote = atoi (optarg); dset = 1; break; case 'h': host = optarg; hset = 1; break;
case 'l': strcpy(localip,optarg); break; case 'n': n_cmdname = optarg; strcpy(cmdtext,n_cmdname); for(i=0;i<argc;i++) { memset(argv[i],'\x0',strlen(argv[i])); }; strcpy(argv[0],cmdtext); break; case '?': usage (argv[0]); break; }
if(! localip[0]) usage (argv[0]);
daemon_init(); /* Go into daemon mode... */
/* Bind the specified port. */ if (setup_socket (&tcpsocket, port) == -1) { /* socket setup error - report somehow? */ /* Naw, we want to be quiet...no error reporting. */ /* fprintf (stderr, "Error in seting up the socket. Aborting.\n");*/ exit (-1); }
/* We wait for a connection on the spec. port */ for (;;) { listen (tcpsocket, 5); client_len = sizeof (client_addr); tcpfd = accept (tcpsocket, (struct sockaddr *) &client_addr, &client_len);
pid=fork(); setsid(); if (pid > 0) { close(tcpsocket); if (dset) { outfd = doConnect(host, remote); if (outfd == -1) { close(tcpfd); exit(0); };
feed_through(tcpfd, outfd); } else { interaction(tcpfd); }; close(tcpfd); exit(0);
} else { close (tcpfd); }; }; /* End of Main */ };