Datapipe.c TCP / IP套接字重定向

时间:2011-11-30 01:15:03

标签: c sockets redirect tcp ip

我正在尝试让这段代码正常工作,但它在命令行参数中引发了错误。由于argc!= 5,它不会继续该程序。我知道(好吧,我认为)我需要指定它是否在localhost,remotehost等上运行。这是代码,来自https://github.com/bovine/datapipe

#pragma comment (lib, "Ws2_32.lib")
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#if defined(__WIN32__) || defined(WIN32) || defined(_WIN32)
  #define WIN32_LEAN_AND_MEAN
  #include <winsock.h>
  #define bzero(p, l) memset(p, 0, l)
  #define bcopy(s, t, l) memmove(t, s, l)
#else
  #include <sys/time.h>
  #include <sys/types.h>
  #include <sys/socket.h>
  #include <sys/wait.h>
  #include <netinet/in.h>
  #include <arpa/inet.h>
  #include <unistd.h>
  #include <netdb.h>
  #include <strings.h>
  #define recv(x,y,z,a) read(x,y,z)
  #define send(x,y,z,a) write(x,y,z)
  #define closesocket(s) close(s)
  typedef int SOCKET;
#endif

#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif


struct client_t
{
  int inuse;
  SOCKET csock, osock;
  time_t activity;
};

#define MAXCLIENTS 20
#define IDLETIMEOUT 300


const char ident[] = "$Id: datapipe.c,v 1.8 1999/01/29 01:21:54 jlawson Exp $";

int main(int argc, char *argv[])
{ 
  SOCKET lsock;
  char buf[4096];
  struct sockaddr_in laddr, oaddr;
  int i;
  struct client_t clients[MAXCLIENTS];


#if defined(__WIN32__) || defined(WIN32) || defined(_WIN32)
  /* Winsock needs additional startup activities */
  WSADATA wsadata;
  WSAStartup(MAKEWORD(1,1), &wsadata);
#endif


  /* check number of command line arguments */
  if (argc != 5) {
    fprintf(stderr,"Usage: %s localhost localport remotehost remoteport\n",argv[0]);
    system ("pause");
    return 30;
  }


  /* reset all of the client structures */
  for (i = 0; i < MAXCLIENTS; i++)
    clients[i].inuse = 0;


  /* determine the listener address and port */
  bzero(&laddr, sizeof(struct sockaddr_in));
  laddr.sin_family = AF_INET;
  laddr.sin_port = htons((unsigned short) atol(argv[2]));
  laddr.sin_addr.s_addr = inet_addr(argv[1]);
  if (!laddr.sin_port) {
    fprintf(stderr, "invalid listener port\n");
    system ("pause");
    return 20;
  }
  if (laddr.sin_addr.s_addr == INADDR_NONE) {
    struct hostent *n;
    if ((n = gethostbyname(argv[1])) == NULL) {
      perror("gethostbyname");
          system ("pause");
      return 20;
    }    
    bcopy(n->h_addr, (char *) &laddr.sin_addr, n->h_length);
  }


  /* determine the outgoing address and port */
  bzero(&oaddr, sizeof(struct sockaddr_in));
  oaddr.sin_family = AF_INET;
  oaddr.sin_port = htons((unsigned short) atol(argv[4]));
  if (!oaddr.sin_port) {
    fprintf(stderr, "invalid target port\n");
    system ("pause");
    return 25;
  }
  oaddr.sin_addr.s_addr = inet_addr(argv[3]);
  if (oaddr.sin_addr.s_addr == INADDR_NONE) {
    struct hostent *n;
    if ((n = gethostbyname(argv[3])) == NULL) {
      perror("gethostbyname");
      system ("pause");
      return 25;
    }    
    bcopy(n->h_addr, (char *) &oaddr.sin_addr, n->h_length);
  }


  /* create the listener socket */
  if ((lsock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    system ("pause");
    return 20;
  }
  if (bind(lsock, (struct sockaddr *)&laddr, sizeof(laddr))) {
    perror("bind");
    system ("pause");
    return 20;
  }
  if (listen(lsock, 5)) {
    perror("listen");
system ("pause");
    return 20;
  }


  /* change the port in the listener struct to zero, since we will
   * use it for binding to outgoing local sockets in the future. */
  laddr.sin_port = htons(0);


  /* fork off into the background. */
#if !defined(__WIN32__) && !defined(WIN32) && !defined(_WIN32)
  if ((i = fork()) == -1) {
    perror("fork");
    system ("pause");
    return 20;
  }
  if (i > 0)
    return 0;
  setsid();
#endif


  /* main polling loop. */
  while (1)
  {
    fd_set fdsr;
    int maxsock;
    struct timeval tv = {1,0};
    time_t now = time(NULL);

    /* build the list of sockets to check. */
    FD_ZERO(&fdsr);
    FD_SET(lsock, &fdsr);
    maxsock = (int) lsock;
for (i = 0; i < MAXCLIENTS; i++)
  if (clients[i].inuse) {
    FD_SET(clients[i].csock, &fdsr);
    if ((int) clients[i].csock > maxsock)
      maxsock = (int) clients[i].csock;
    FD_SET(clients[i].osock, &fdsr);
    if ((int) clients[i].osock > maxsock)
      maxsock = (int) clients[i].osock;
  }      
if (select(maxsock + 1, &fdsr, NULL, NULL, &tv) < 0) {
    system ("pause");
  return 30;
}


/* check if there are new connections to accept. */
if (FD_ISSET(lsock, &fdsr))
{
  SOCKET csock = accept(lsock, NULL, 0);

  for (i = 0; i < MAXCLIENTS; i++)
    if (!clients[i].inuse) break;
  if (i < MAXCLIENTS)
  {
    /* connect a socket to the outgoing host/port */
    SOCKET osock;
    if ((osock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
      perror("socket");
      closesocket(csock);
    }
    else if (bind(osock, (struct sockaddr *)&laddr, sizeof(laddr))) {
      perror("bind");
      closesocket(csock);
      closesocket(osock);
    }
    else if (connect(osock, (struct sockaddr *)&oaddr, sizeof(oaddr))) {
      perror("connect");
      closesocket(csock);
      closesocket(osock);
    }
    else {
      clients[i].osock = osock;
      clients[i].csock = csock;
      clients[i].activity = now;
      clients[i].inuse = 1;
    }
  } else {
    fprintf(stderr, "too many clients\n");
    closesocket(csock);
  }        
}


/* service any client connections that have waiting data. */
for (i = 0; i < MAXCLIENTS; i++)
{
  int nbyt, closeneeded = 0;
  if (!clients[i].inuse) {
    continue;
  } else if (FD_ISSET(clients[i].csock, &fdsr)) {
    if ((nbyt = recv(clients[i].csock, buf, sizeof(buf), 0)) <= 0 ||
      send(clients[i].osock, buf, nbyt, 0) <= 0) closeneeded = 1;
    else clients[i].activity = now;
  } else if (FD_ISSET(clients[i].osock, &fdsr)) {
    if ((nbyt = recv(clients[i].osock, buf, sizeof(buf), 0)) <= 0 ||
      send(clients[i].csock, buf, nbyt, 0) <= 0) closeneeded = 1;
    else clients[i].activity = now;
  } else if (now - clients[i].activity > IDLETIMEOUT) {
    closeneeded = 1;
  }
  if (closeneeded) {
    closesocket(clients[i].csock);
    closesocket(clients[i].osock);
    clients[i].inuse = 0;
      }      
    }

  }
  system ("pause");
  return 0;
}

我只需要找到一种方法使其工作并使用它,以便我可以剖析它。不幸的是,我不知道该怎么做才能给它制作argc = 5所需的内容,或者如何确定它的运行方式(localhost,localport,remotehost,remoteport)。

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

运行它。它将输出使用信息:

if (argc != 5) {
    fprintf(stderr,"Usage: %s localhost localport remotehost remoteport\n",argv[0]);
    system ("pause");
    return 30;
}

我推测示例运行可能是./datapipe 10.0.0.1 1337 10.0.0.3 1234,其中10.0.0.1是本地IP地址,而10.0.0.3是远程主机。