Added "protodiff", a small tool for trying to diff the real and fake servers.
authorSteinar H. Gunderson <sesse@samfundet.no>
Sat, 5 Feb 2005 00:57:30 +0000 (00:57 +0000)
committerSteinar H. Gunderson <sesse@samfundet.no>
Sat, 5 Feb 2005 00:57:30 +0000 (00:57 +0000)
Makefile
protodiff.c [new file with mode: 0644]

index 3109ef3..e49a400 100644 (file)
--- 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 (file)
index 0000000..6bc8570
--- /dev/null
@@ -0,0 +1,135 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+
+#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;
+}
+