bf8 /* Quake proxy */ #include #include #include #include #include #include #include #include #include #include #include #include extern char *optarg; extern int optind; #define VERSION "1.0" #define MAX 4096 unsigned char msg[MAX]; char *name; void usage () { fprintf(stderr, "usage: %s [-l localport] [-r remoteport]", name); fprintf(stderr, " [-h] server\n"); } int main(int argc, char **argv) { int sfd, cfd, c2fd, n, ucl, i, pid, opt; fd_set fds; struct sockaddr_in cremote_addr, clocal_addr; struct sockaddr_in sremote_addr, slocal_addr; struct sockaddr_in kuk_addr; struct hostent *host; struct timeval tv, *tvp; int localport = 27000, remoteport = 27000, debug = 0; name = argv[0]; while (opt = getopt(argc, argv, "l:r:hv"), opt != -1) { switch (opt) { case 'l': localport = atoi(optarg); break; case 'r': remoteport = atoi(optarg); break; case 'v': fprintf(stderr, "qudproxy version %s", VERSION); return 0; default: usage(); return opt != 'h'; } } if (optind != argc - 1) { usage(); return 1; } ucl = sizeof(struct sockaddr_in); bzero(&sremote_addr, ucl); sremote_addr.sin_family = AF_INET; sremote_addr.sin_port = htons(remoteport); n = inet_addr(argv[optind]); if (n != -1) memcpy(&sremote_addr.sin_addr, &n, sizeof(n)); else { host = gethostbyname(argv[optind]); if (host == NULL) return(-1); memcpy (&sremote_addr.sin_addr, host->h_addr, host->h_length); } bzero(&clocal_addr, ucl); clocal_addr.sin_family = AF_INET; clocal_addr.sin_port = htons(localport); /* Surely there's a better way to determine our IP address. */ gethostname(msg, MAX); host = gethostbyname(msg); memcpy(&clocal_addr.sin_addr, host->h_addr, host->h_length); bzero(&slocal_addr, ucl); slocal_addr.sin_family = AF_INET; slocal_addr.sin_addr.s_addr = htonl(INADDR_ANY); cfd = socket(AF_INET, SOCK_DGRAM, 0); bind(cfd, (struct sockaddr *)&clocal_addr, ucl); sfd = socket(AF_INET, SOCK_DGRAM, 0); bind(sfd, (struct sockaddr *)&slocal_addr, ucl); while (1) { int i; FD_ZERO(&fds); FD_SET(sfd, &fds); FD_SET(cfd, &fds); if (0 >= select(1 + (cfd > sfd ? cfd : sfd), &fds, NULL, NULL, NULL)) return 0; if (FD_ISSET(cfd, &fds)) { n = recvfrom(cfd, msg, MAX, 0, (struct sockaddr *)&cremote_addr, &ucl); if (n == -1) { perror("qudproxy"); return 1; } sendto(sfd, msg, n, 0, (struct sockaddr *)&sremote_addr, ucl); } if (FD_ISSET(sfd, &fds)) { n = recvfrom(sfd, msg, MAX, 0, NULL, &ucl); if (n == -1) { perror("qudproxy"); return 1; } sendto(cfd, msg, n, 0, (struct sockaddr *)&cremote_addr, ucl); } } } . 0