#include #include #include #include #include #include #include #include "proxy.h" static int parse_host(const char *host, const char *port, struct addrinfo **addr) { struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM, .ai_flags = AI_PASSIVE, }; int err; if ((err = getaddrinfo(host, port, &hints, addr))) { fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(err)); return -1; } return 0; } static int listen_source(struct addrinfo *source) { int fd = -1; for (struct addrinfo *a = source; a; a = a->ai_next) { if ((fd = socket(a->ai_family, a->ai_socktype, a->ai_protocol)) == -1) continue; if (!bind(fd, a->ai_addr, a->ai_addrlen) && !listen(fd, 1)) break; close(fd); fd = -1; } return fd; } static int connect_target(struct addrinfo *target) { int fd = -1; for (struct addrinfo *a = target; a; a = a->ai_next) { if ((fd = socket(a->ai_family, a->ai_socktype, a->ai_protocol)) == -1) continue; if (connect(fd, a->ai_addr, a->ai_addrlen) != -1) break; close(fd); fd = -1; } return fd; } int main(int argc, char **argv) { struct addrinfo *source; struct addrinfo *target; if (argc != 3) { fprintf(stderr, "usage: %s targethost targetport\n", argv[0]); return -1; } if (parse_host(NULL, "1234", &source)) return -1; if (parse_host(argv[1], argv[2], &target)) return -1; int listenfd = listen_source(source); if (listenfd < 0) { perror("listen_source"); return -1; } for (;;) { int sourcefd = accept(listenfd, NULL, NULL); if (sourcefd == -1) break; int targetfd = connect_target(target); if (targetfd == -1) { perror("connect_target"); close(sourcefd); break; } proxy(sourcefd, targetfd, 500); close(targetfd); close(sourcefd); } close(listenfd); return 0; }