home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / hacking / internet / datapipe.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-06-11  |  4.5 KB  |  173 lines

  1. /*
  2.  
  3. The following is an interesting snippet of code I wrote recently. It 
  4. makes a data pipe between a listen port on the machine it's being run on 
  5. and a port on a remote machine. For example, running
  6.   datapipe 2222 23 your.machine.com
  7.  
  8. would create a port 2222 on the local machine that, if telnetted to, would
  9. be the same as telnetting to port 23 on your.machine.com. This can be used
  10. for a variety of purposes: redirect IRC connections so that identd shows
  11. the username of the datapipe process; redirect sendmail direct connections
  12. for the same reason; even use on a firewall machine to give access to an
  13. internal service (ftpd, for instance). Cascaded datapipes make for
  14. interesting traceback dilemmas. Questions and comments accepted.
  15.  
  16. Compile with:
  17.     cc -o datapipe -O datapipe.c
  18. On boxes without strerror() (like SunOS 4.x), compile with:
  19.     cc -o datapipe -O -DSTRERROR datapipe.c
  20.  
  21. Run as:
  22.     datapipe localport remoteport remotehost
  23.  
  24. It will fork itself into the background.
  25.  
  26. /*
  27.  * Datapipe - Create a listen socket to pipe connections to another
  28.  * machine/port. 'localport' accepts connections on the machine running    
  29.  * datapipe, which will connect to 'remoteport' on 'remotehost'. Fairly
  30.  * standard 500 xxxx extended errors are used if something drastic
  31.  * happens.
  32.  *
  33.  * (c) 1995 Todd Vierling
  34.  *
  35.  * Define STRERROR while compiling on a SunOS 4.x box
  36.  */
  37.  
  38. #include <sys/types.h>
  39. #include <sys/socket.h>
  40. #include <sys/wait.h>
  41. #include <netinet/in.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <errno.h>
  45. #include <unistd.h>
  46. #include <netdb.h>
  47.  
  48. #ifdef STRERROR
  49. extern char *sys_errlist[];
  50. extern int sys_nerr;
  51. char *undef = "Undefined error";
  52.  
  53. char *strerror(error)  
  54.   int error;  
  55.   if (error > sys_nerr)
  56.     return undef;
  57.   return sys_errlist[error];
  58. }
  59. #endif
  60.  
  61. main(argc, argv)  
  62.   int argc;  
  63.   char **argv;  
  64.   int lsock, csock, osock;
  65.   FILE *cfile;
  66.   char buf[4096];
  67.   struct sockaddr_in laddr, caddr, oaddr;
  68.   int caddrlen = sizeof(caddr);
  69.   fd_set fdsr, fdse;
  70.   struct hostent *h;
  71.   struct servent *s;
  72.   int nbyt;
  73.   unsigned long a;
  74.   unsigned short oport;
  75.  
  76.   if (argc != 4) {
  77.     fprintf(stderr,"Usage: %s localport remoteport remotehost\n",argv[0]);
  78.     return 30;
  79.   }
  80.   a = inet_addr(argv[3]);
  81.   if (!(h = gethostbyname(argv[3])) &&
  82.       !(h = gethostbyaddr(&a, 4, AF_INET))) {
  83.     perror(argv[3]);
  84.     return 25;
  85.   }
  86.   oport = atol(argv[2]);
  87.   laddr.sin_port = htons((unsigned short)(atol(argv[1])));
  88.   if ((lsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
  89.     perror("socket");
  90.     return 20;
  91.   }
  92.   laddr.sin_family = htons(AF_INET);
  93.   laddr.sin_addr.s_addr = htonl(0);
  94.   if (bind(lsock, &laddr, sizeof(laddr))) {
  95.     perror("bind");
  96.     return 20;
  97.   }
  98.   if (listen(lsock, 1)) {
  99.     perror("listen");
  100.     return 20;
  101.   }
  102.   if ((nbyt = fork()) == -1) {
  103.     perror("fork");
  104.     return 20;
  105.   }
  106.   if (nbyt > 0)
  107.     return 0;
  108.   setsid();
  109.   while ((csock = accept(lsock, &caddr, &caddrlen)) != -1) {
  110.     cfile = fdopen(csock,"r+");
  111.     if ((nbyt = fork()) == -1) {
  112.       fprintf(cfile, "500 fork: %s\n", strerror(errno));
  113.       shutdown(csock,2);
  114.       fclose(cfile);
  115.       continue;
  116.     }
  117.     if (nbyt == 0)
  118.       goto gotsock;
  119.     fclose(cfile);
  120.     while (waitpid(-1, NULL, WNOHANG) > 0);
  121.   }
  122.   return 20;
  123.  
  124.  gotsock:
  125.   if ((osock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
  126.     fprintf(cfile, "500 socket: %s\n", strerror(errno));
  127.     goto quit1;
  128.   }
  129.   oaddr.sin_family = h->h_addrtype;
  130.   oaddr.sin_port = htons(oport);
  131.   memcpy(&oaddr.sin_addr, h->h_addr, h->h_length);
  132.   if (connect(osock, &oaddr, sizeof(oaddr))) {
  133.     fprintf(cfile, "500 connect: %s\n", strerror(errno));
  134.     goto quit1;
  135.   }
  136.   while (1) {
  137.     FD_ZERO(&fdsr);
  138.     FD_ZERO(&fdse);
  139.     FD_SET(csock,&fdsr);
  140.     FD_SET(csock,&fdse);
  141.     FD_SET(osock,&fdsr);
  142.     FD_SET(osock,&fdse);
  143.     if (select(20, &fdsr, NULL, &fdse, NULL) == -1) {
  144.       fprintf(cfile, "500 select: %s\n", strerror(errno));
  145.       goto quit2;
  146.     }
  147.     if (FD_ISSET(csock,&fdsr) || FD_ISSET(csock,&fdse)) {
  148.       if ((nbyt = read(csock,buf,4096)) <= 0)
  149.     goto quit2;
  150.       if ((write(osock,buf,nbyt)) <= 0)
  151.     goto quit2;
  152.     } else if (FD_ISSET(osock,&fdsr) || FD_ISSET(osock,&fdse)) {
  153.       if ((nbyt = read(osock,buf,4096)) <= 0)
  154.     goto quit2;
  155.       if ((write(csock,buf,nbyt)) <= 0)
  156.     goto quit2;
  157.     }
  158.   }
  159.  
  160.  quit2:
  161.   shutdown(osock,2);
  162.   close(osock);
  163.  quit1:
  164.   fflush(cfile);
  165.   shutdown(csock,2);
  166.  quit0:
  167.   fclose(cfile);
  168.   return 0;
  169. }
  170.  
  171.