#include #include #include #include #include #include #include #include #include #include short from_inside_port = 6000; short from_ouside_port = 5115; struct pt_param { int in_fd; int out_fd; }; void* pass_through(void *p){ struct pt_param *ptp = p; char buffer[2048]; size_t readlen; while(1){ readlen = read(ptp->in_fd, buffer, 2048); if(readlen < 1) break; if(write(ptp->out_fd, buffer, readlen) != readlen) break; } printf("Terminating forward from fd %d to fd %d\n", ptp->in_fd, ptp->out_fd); } int main(int argc, char ** argv){ struct sockaddr_in sad; sad.sin_port = htons(from_inside_port); sad.sin_addr.s_addr = INADDR_ANY; sad.sin_family = AF_INET; int skt = socket(AF_INET, SOCK_STREAM, 0); // Step 1 if(skt == -1){ perror("socket"); return 1; } while( bind(skt, (struct sockaddr*)(&sad), sizeof(struct sockaddr_in)) ){ // step 2 if(from_inside_port < 6005){ from_inside_port++; sad.sin_port = htons(from_inside_port); } else { perror("bind"); return 1; } } printf("Listening on port %d\n", from_inside_port); if( listen(skt, 5) ){ // step 3 perror("listen"); return 1; } int inside_fd; struct sockaddr_in inside_address; socklen_t address_size = sizeof(struct sockaddr_in); inside_fd = accept(skt, (struct sockaddr *)(&inside_address), &address_size); // step 4 printf("Inside connection is ready!\n"); // After this, accept connections from outside and forward the traffic in sad.sin_port = htons(from_ouside_port); sad.sin_family = AF_INET; int oskt = socket(AF_INET, SOCK_STREAM, 0); if(oskt == -1){ perror("socket"); return 1; } if( bind(oskt, (struct sockaddr*)(&sad), sizeof(struct sockaddr_in)) ){ // step 2 perror("bind"); return 1; } if( listen(oskt, 5) ){ // step 3 perror("listen"); return 1; } int client_fd; struct sockaddr_in client_address; while(1){ client_fd = accept(oskt, (struct sockaddr*)(&client_address), &address_size); // Pass to inside loop // But it should go both directions! pthread_t threads[2]; struct pt_param outside_to_inside = {client_fd, inside_fd}; struct pt_param inside_to_outside = {inside_fd, client_fd}; pthread_create(&threads[0], 0, pass_through, &outside_to_inside); pthread_create(&threads[1], 0, pass_through, &inside_to_outside); for(int i = 0; i < 2; i++) pthread_join(threads[i], 0); } close(skt); close(oskt); return 0; }