From: Steinar H. Gunderson Date: Sat, 5 Feb 2005 00:57:30 +0000 (+0000) Subject: Added "protodiff", a small tool for trying to diff the real and fake servers. X-Git-Url: https://git.sesse.net/?p=rdpsrv;a=commitdiff_plain;h=80f21a637435efb027085ce28ed6aa3a31eb70a5;hp=ce66b81460e5353db09d45c02339d4583fbda255 Added "protodiff", a small tool for trying to diff the real and fake servers. --- diff --git a/Makefile b/Makefile index 3109ef3..e49a400 100644 --- a/Makefile +++ b/Makefile @@ -2,12 +2,15 @@ CC=gcc CFLAGS=-g -Wall LIBS=-lssl -all: rdpsrv +all: rdpsrv protodiff OBJS=rdpsrv.o iso.o tcp.o util.o mcs.o secure.o channels.o rdp.o +OBJS_PROTODIFF=protodiff.o tcp.o util.o rdpsrv: $(OBJS) $(CC) -o rdpsrv $(OBJS) $(LIBS) +protodiff: $(OBJS_PROTODIFF) + $(CC) -o protodiff $(OBJS_PROTODIFF) $(LIBS) clean: - $(RM) $(OBJS) rdpsrv + $(RM) $(OBJS) $(OBJS_PROTODIFF) rdpsrv protodiff .PHONY: clean diff --git a/protodiff.c b/protodiff.c new file mode 100644 index 0000000..6bc8570 --- /dev/null +++ b/protodiff.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rdesktop.h" +#include "scancodes.h" + +const int tcp_port_rdp = 3389; +int create_server_socket(); + +int main() +{ + int server_sock = create_server_socket(); + int sock_serv, sock_real, sock_fake; + char buf[4096], buf1[4096], buf2[4096]; + int len1, len2, i; + + tcp_recv_connect(server_sock); + sock_serv = tcp_get_socket(); + + printf("Got connection.\n"); + + sock_real = tcp_connect("glasur.uka.no", 3389); + sock_fake = tcp_connect("127.0.0.1", 3390); + + for ( ;; ) { + fd_set readfs; + FD_ZERO(&readfs); + FD_SET(sock_serv, &readfs); + FD_SET(sock_real, &readfs); + FD_SET(sock_fake, &readfs); + + select(FD_SETSIZE, &readfs, NULL, NULL, NULL); + + if (FD_ISSET(sock_serv, &readfs)) { + // data from the client + len1 = read(sock_serv, buf, 4096); + + if (len1 <= 0) { + perror("read()"); + exit(1); + } + + printf("<== "); + for (i = 0; i < len1; ++i) + printf(" 0x%02x", buf[i]); + printf("\n"); + + if (write(sock_real, buf, len1) != len1) { + perror("write_real"); + exit(1); + } + if (write(sock_fake, buf, len1) != len1) { + perror("write_fake"); + exit(1); + } + } else if (FD_ISSET(sock_real, &readfs) || FD_ISSET(sock_fake, &readfs)) { + len1 = len2 = 0; + + if (FD_ISSET(sock_real, &readfs)) { + len1 = read(sock_real, buf1, 4096); + if (len1 <= 0) { + perror("read_real"); + exit(1); + } + } + if (FD_ISSET(sock_fake, &readfs)) { + len2 = read(sock_fake, buf2, 4096); + if (len2 <= 0) { + perror("read_fake"); + exit(1); + } + } + + printf("R==>"); + for (i = 0; i < len1; ++i) + printf(" 0x%02x", buf1[i]); + printf("\n"); + + printf("F==>"); + for (i = 0; i < len2; ++i) + printf(" 0x%02x", buf2[i]); + printf("\n"); + + if (write(sock_serv, buf1, len1) != len1) { + perror("write_serv"); + exit(1); + } + } + + // give the clients a bit of time to synchronize + usleep(300000); + } +} + +int create_server_socket() +{ + int server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + const unsigned int one = 1, zero = 0; + struct sockaddr_in addr; + int err; + + setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + ioctl(server_sock, FIONBIO, &zero); + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = htons(tcp_port_rdp); + + do { + err = bind(server_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr)); + + if (err == -1) { + perror("bind()"); + + /* try to recover from recoverable errors... */ + if (errno == ENOMEM || errno == EADDRINUSE) { + puts("Waiting 1 sec before trying again..."); + sleep(1); + } else { + puts("Giving up."); + exit(1); + } + } + } while (err == -1); + + listen(server_sock, 20); + return server_sock; +} +