#define HAVE_BIND               /* XXX -- for now, see below... */
#define HAVE_HELP               /* undefine if you dont want the help text */
/* #define ANAL                 /* if you want case-sensitive DNS matching */

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#else
#include <malloc.h> /* xxx: or does it live in sys/ ?? */ #endif

/* have to do this *before* including types.h. xxx: Linux still has it wrong */

#ifdef FD_SETSIZE               /* should be in types.h, butcha never know. */
#undef FD_SETSIZE               /* if we ever need more than 16 active */
#endif                          /* fd's, something is horribly wrong! */
#ifdef WIN32
#define FD_SETSIZE 64           /* WIN32 does this as an array not a bitfield and it likes 64 */
#else
#define FD_SETSIZE 16           /* <-- this'll give us a long anyways, wtf */
#endif
#include <sys/types.h>          /* *now* do it.  Sigh, this is broken */

#ifdef WIN32
#undef HAVE_RANDOM
#undef IP_OPTIONS
#undef SO_REUSEPORT
#include <windows.h>
#endif

#ifdef WIN32
//#include "getopt.h"

#define sleep                   _sleep
#define strcasecmp              strcmpi
#define EADDRINUSE              WSAEADDRINUSE
#define ETIMEDOUT               WSAETIMEDOUT

#define ECONNREFUSED WSAECONNREFUSED #endif

#ifdef HAVE_RANDOM
#define SRAND srandom
#define RAND random
#else
#define SRAND srand
#define RAND rand
#endif /* HAVE_RANDOM */

#ifndef WIN32

#include <sys/socket.h>         /* basics, SO_ and AF_ defs, sockaddr, ... */
#include <netinet/in.h>         /* sockaddr_in, htons, in_addr */
#include <netinet/in_systm.h>   /* misc crud that netinet/ip.h references */
#include <netinet/ip.h>         /* IPOPT_LSRR, header stuff */
#include <netdb.h>              /* hostent, gethostby*, getservby* */
#include <arpa/inet.h>          /* inet_ntoa */

#else
#include <fcntl.h>
#include <io.h>
#include <conio.h>
#include <winsock.h>
#endif

#include <stdio.h>
#include <string.h> /* strcpy, strchr, yadda yadda */ #include <errno.h>
#include <signal.h>

void ores_init(void);
#ifdef STRERROR
extern char *sys_errlist[];
extern int sys_nerr;
char *undef = "Undefined error";

char *strerror(error)
int error;
{
if (error > sys_nerr)
return undef;
return sys_errlist[error];
}
#endif

main(argc, argv)
int argc;
char **argv;
{
int lsock, csock, osock;
//FILE *cfile;
char buf[5000];
struct sockaddr_in laddr, caddr, oaddr; int caddrlen = sizeof(caddr);
fd_set fdsr, fdse;
WSADATA wsaData;
struct hostent *h;
struct hostent *h2;
struct servent *s;
int nbyt;
unsigned int a;
unsigned short oport;

        int resul;
        int salir;
        salir=0;

// argc=4;
if (argc < 4) {
fprintf(stderr,"Eid0 conexion inversa multiplexada v1.00: Usage: %s remotehost remoteport localport bouncehost(127.0.0.1 default)\n",argv[0]); return 30;
}

                if (WSAStartup(MAKEWORD(1,1),&wsaData)!=0)
                {
                        printf ("error en winsock");
                        return 0;
                }

// argv[1]="192.168.0.1";argv[2]="9000";argv[3]="80";

if ((csock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { perror("socket");
return 20;
}

//oport = atol(argv[3]);
memset(&laddr,0,sizeof(laddr));
if ((laddr.sin_addr.s_addr=inet_addr(argv[1]))==INADDR_NONE)

                {
                        //HOSTENT *he;
                        if (h2=gethostbyname(argv[1]))
                        laddr.sin_addr.s_addr=*((DWORD*)h2->h_addr);
                        else
                        printf("LA DIRECCION REMOTA NO ES VALIDA CALAMAR\n");

                }

laddr.sin_family = PF_INET;
//memcpy(&laddr.sin_addr, h2->h_addr, h2->h_length); laddr.sin_port = htons(atoi(argv[2])); //laddr.sin_addr.s_addr = INADDR_ANY;

if (connect(csock, &laddr, sizeof(laddr))==SOCKET_ERROR) { printf("connect a destino remoto\n,error winsock->%u\n",WSAGetLastError()); goto quit1;
}

gotsock:
if ((osock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { perror("socket a destino");
goto quit1;
}
memset(&oaddr,0,sizeof(oaddr));

if (argc==4) a = inet_addr("127.0.0.1"); else a=inet_addr(argv[4]);

oaddr.sin_family = AF_INET;
oaddr.sin_port = htons(atoi(argv[3])); //memcpy(&oaddr.sin_addr, h->h_addr, h->h_length); oaddr.sin_addr.s_addr=a;
if (connect(osock, &oaddr, sizeof(oaddr))==SOCKET_ERROR) { printf("connect a destino,error winsock-> %u\n",WSAGetLastError()); goto quit1;
}
while (1) {
FD_ZERO(&fdsr);
//FD_ZERO(&fdse);
FD_SET(csock,&fdsr);
//FD_SET(csock,&fdse);
FD_SET(osock,&fdsr);
//FD_SET(osock,&fdse);
if (select(20, &fdsr, NULL, NULL, NULL) == -1) {

      perror("select");
      goto quit2;

}
if (FD_ISSET(csock,&fdsr)) {

      if ((nbyt = recv(csock,buf,4096,0)) <= 0)
        salir=1;
      if ((send(osock,buf,nbyt,0)) <= 0)
        salir=1;
    }
        if (FD_ISSET(osock,&fdsr)) {
      if ((nbyt = recv(osock,buf,4096,0)) <= 0)
        salir=1;
      if ((send(csock,buf,nbyt,0)) <= 0)
        salir=1;
        }
        if (salir==1) goto quit2;

}

quit2:
shutdown(osock,1);
close(osock);
quit1:

quit0:
//fclose(cfile);
shutdown(csock,1);
close(csock);
//Sleep(10000);
return 0;
}