--- /dev/null
+#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;
+}
+