/**************************************************************************
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Coded By Matrix86 ----> matrix86 {AT} tuxmealux {DOT} net
****************************************************************************/
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define N_BUF 6144
#define BACKLOG 10
#define USAGE "Usage: %s listen_port\n"
#define PASS "matrix86"
void HandSigCHLD(int sig)
{
int status;
pid_t wpid;
wpid = waitpid(WAIT_ANY, &status, WNOHANG);
//if (wpid > 0) printf("BG child %d terminated with status %x\n", wpid, status);
return;
}
void tunnel(int con){
char buffer[N_BUF+1];
struct sockaddr_in client;
int nw,nr,ip,port,sock;
char char_ip[]="62.211.72.30";
char char_port[]="65535";
if((nw = write(con,"Password: ",10)) == 0) _exit(1);
nr = recv(con,buffer,N_BUF,0);
if(nr < 0){
// perror("Errore recv(): ");
return;
}
buffer[nr-2] = 0; //Elimina il carattere di invio =)
// Controlla la password...
if(strcmp(buffer, PASS) != 0) return;
// Richiesta IP
if((nw = write(con,"Ip address: ",12)) == 0) _exit(1);
nr = recv(con,buffer,N_BUF,0);
if(nr < 0){
// perror("Errore recv(): ");
return;
}
buffer[nr-2] = 0;
strcpy(char_ip,buffer);
// Richiesta porta
if((nw = write(con,"Port: ",6)) == 0) _exit(1);
nr = recv(con,buffer,N_BUF,0);
if(nr < 0){
// perror("Errore recv(): ");
return;
}
buffer[nr-2] = 0;
strcpy(char_port,buffer);
port = atoi(char_port);
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock < 0){
// perror("Errore durante la creazione del socket: ");
_exit(1);
}
memset((void *)&client,0,sizeof(client));
client.sin_family = PF_INET;
client.sin_port = htons(port);
if ( (inet_pton(PF_INET, char_ip, &client.sin_addr)) < 0) {
// perror("Errore durante la creazione dell'indirizzo ");
_exit(1);
}
if (connect(sock, (struct sockaddr *)&client, sizeof(client)) < 0) {
// perror("Errore in connessione ");
_exit(1);
}
// Creo due processi figli: uno riceve dal client connesso e invia al server successivo, e l'altro legge la risposta del server e la invia al client connesso!!!
if(fork() == 0){
while(1){
// Leggo le informazioni ricevute dal server...
nr = recv(sock,buffer,N_BUF,0);
if(nr < 0){
// perror("Errore recv(): ");
return;
}
if(nr == 0) break; //Connection close!
// ...e le invio al client!
if((nw = send(con,buffer,nr,0)) == 0) return;
}
_exit(0);
}
if(fork() == 0){
while(1){
// Leggo le informazioni ricevute dal client...
nr = recv(con,buffer,N_BUF,0);
if(nr < 0){
// perror("Errore recv(): ");
return;
}
if(nr == 0) break; //Connection close!
buffer[nr-2] = 0; // Delete return value!
// ...e le invio al server!
if((nw = send(sock,buffer,nr,0)) == 0) return;
}
_exit(0);
}
//printf("Socket chiuso");
close(sock);
return;
}
void usage(char name[]){
return;
}
int main(int argc,char *argv[]){
struct sockaddr_in server;
int sock,conn,nw,port;
pid_t pid;
char init[] = "**********************************************\n* RBT-4 CREW *\n**********************************************\n* Tunnel coded by Matrix86 for Rbt-4 Crew *\n* Thx to Black_Student,r080cy90r and *\n* all my friends. *\n* Special Thx to my girlfriend ;) *\n* *\n**********************************************\n\n";
if(argc < 2){
usage(argv[0]);
_exit(0);
}
port = atoi(argv[1]);
signal(SIGCHLD, HandSigCHLD);
strcpy(argv[0],"[ httpd ]");
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock < 0){
// perror("Errore durante la creazione del socket: ");
_exit(1);
}
memset((void *)&server,0,sizeof(server));
server.sin_family = PF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sock, (struct sockaddr *)&server, sizeof(server)) < 0){
// perror("Errore Bind: ");
_exit(1);
}
if (listen(sock, BACKLOG) < 0 ) {
// perror("Errore Listen: ");
_exit(1);
}
while(1){
while(((conn = accept(sock, (struct sockaddr *) NULL, NULL)) < 0) && (errno == EINTR));
if (conn < 0) {
// perror("Errore accept: ");
_exit(1);
}
// Creo un processo figlio...in modo da gestire più connessioni contemporaneamente.
if ((pid=fork()) < 0){
// perror("Errore fork() :");
_exit(1);
}
if(pid == 0){
// Siamo nel processo figlio.
close(sock);
if((nw = write(conn,init,strlen(init))) == 0) _exit(1);
tunnel(conn);
close(conn);
_exit(0);
}
else {
close(conn);
}
}
return 0;
}