#include #include #include #include #include #include #include #include #include #define _perror(s) perror(s); errno = 0 #define _probably_perror(s) if (errno) { perror(s); errno = 0; } unsigned short portfrom, portto; int sock, client, server, peer_size; struct sockaddr_in *local, *peer, *remote; char *buffer; int main(int argc, char **argv) { buffer = malloc(65537); remote = malloc(sizeof(struct sockaddr_in)); local = malloc(sizeof(struct sockaddr_in)); peer = malloc(sizeof(struct sockaddr_in)); peer_size = sizeof(struct sockaddr_in); portfrom = 26; portto = 25; if (argc >= 3) { portfrom = (short)(atol(argv[1]) & 0xFFFF); portto = (short)(atol(argv[2]) & 0xFFFF); } local->sin_family = AF_INET; local->sin_port = htons(portfrom); local->sin_addr.s_addr = htonl(INADDR_ANY); remote->sin_family = AF_INET; remote->sin_port = htons(portto); remote->sin_addr.s_addr = inet_addr("192.168.1.1"); printf("Target address: %i.%i.%i.%i:%i\n", remote->sin_addr.s_addr & 0xFF, (remote->sin_addr.s_addr >> 8) & 0xFF, (remote->sin_addr.s_addr >> 16) & 0xFF, (remote->sin_addr.s_addr >> 24) & 0xFF, ntohs(remote->sin_port)); sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == -1) { _perror("socket (controller)"); exit(1); } if (bind(sock, (struct sockaddr *)local, sizeof(struct sockaddr_in)) < 0) { _perror("bind"); exit(1); } if (listen(sock, 10) < 0) { _perror("listen"); exit(1); } while ((client = accept(sock, (struct sockaddr *)peer, &peer_size)) >= 0) { unsigned long s; int in_recvq, overhead = 0, nr_loops = 0; for (s = 0; s < 65536; s++) buffer[s] = 0; printf("Connection from %s:%i\n", inet_ntoa(peer->sin_addr), ntohs(peer->sin_port)); server = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (server == -1) { _perror("socket (server)"); exit(1); } if (connect(server, (struct sockaddr *)remote, sizeof(struct sockaddr_in)) < 0) { _perror("connect (server)"); goto out; } printf("Server connection is up.\n"); usleep(100); if (ioctl(server, TIOCINQ, &in_recvq) != 0) { _perror("TIOCINQ (server)"); goto out; } data_waiting: if (overhead - nr_loops >= 100) goto out; while (in_recvq) { nr_loops++; overhead = nr_loops; for (s = 0; s < 65536; s++) buffer[s] = 0; if (recv(server,buffer, 65535, 0) < 0) { _perror("recv (server)"); goto out; } printf("%s", buffer); if (send(client, buffer, strlen(buffer), 0) < 0) { _perror("send (server)"); goto out; } if (ioctl(server, TIOCINQ, &in_recvq) != 0) { _perror("TIOCINQ (server)"); goto out; } } if (ioctl(client, TIOCINQ, &in_recvq) != 0) { _perror("TIOCINQ (client)"); goto out; } while (in_recvq) { nr_loops++; overhead = nr_loops; for (s = 0; s < 65536; s++) buffer[s] = 0; if (recv(client, buffer, 65535, 0) < 0) { _perror("recv (client)"); goto out; } printf("%s", buffer); if (send(server, buffer, strlen(buffer), 0) < 0) { _perror("send (server)"); goto out; } if (ioctl(client, TIOCINQ, &in_recvq) != 0) { _perror("TIOCINQ (client)"); goto out; } } if (ioctl(server, TIOCINQ, &in_recvq) != 0) { _perror("TIOCINQ (server)"); goto out; } overhead++; usleep(100); goto data_waiting; out: printf("Connection closing.\n"); shutdown(client, SHUT_RDWR); _probably_perror("shutdown (client)"); shutdown(server, SHUT_RDWR); _probably_perror("shutdown (server)"); close(client); _probably_perror("close (client)"); close(server); _probably_perror("close (server)"); } if (close(sock)) { _perror("close (controller)"); } exit(0); } /* * Local variables: * compile-command: "gcc -W -Wall -Os -o pf portforwarder.c" * c-basic-offset: 8 * End: */