5 #include <sys/select.h>
6 #include <sys/socket.h>
12 const int tcp_port_rdp = 3389;
13 int create_server_socket();
18 int server_sock = create_server_socket();
20 iso_recv_connect(server_sock);
21 printf("Got connection.\n");
23 printf("Client closed.\n");
27 int create_server_socket()
29 int server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
30 const unsigned int one = 1, zero = 0;
31 struct sockaddr_in addr;
34 setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
35 ioctl(server_sock, FIONBIO, &zero);
37 addr.sin_family = AF_INET;
38 addr.sin_addr.s_addr = INADDR_ANY;
39 addr.sin_port = htons(tcp_port_rdp);
42 err = bind(server_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr));
47 /* try to recover from recoverable errors... */
48 if (errno == ENOMEM || errno == EADDRINUSE) {
49 puts("Waiting 1 sec before trying again...");
58 listen(server_sock, 20);
62 void handle_input_pdu(STREAM s, int vnc_sock)
65 uint16 message_type, device_flags, param1, param2;
69 static int mouse1_down = 0, mouse2_down = 0;
71 in_uint16_le(s, num_events); // number of events
72 in_uint8s(s, 2); // pad
74 for (i = 0; i < num_events; ++i) {
75 rdp_recv_input(s, &time, &message_type, &device_flags, ¶m1, ¶m2);
76 printf("Input event at time %u\n", time);
78 switch (message_type) {
79 case RDP_INPUT_SYNCHRONIZE:
80 printf("- Type: Synchronize (ignored)\n");
82 case RDP_INPUT_CODEPOINT:
83 printf("- Type: Codepoint (ignored)\n");
85 case RDP_INPUT_VIRTKEY:
86 printf("- Type: Virtual key (ignored)\n");
88 case RDP_INPUT_SCANCODE:
89 printf("- Type: Scancode (ignored)\n");
92 printf("- Type: Mouse\n");
93 printf("- Device flags: %x\n", device_flags);
94 printf("- Position: (%u,%u)\n", param1, param2);
96 if (device_flags & MOUSE_FLAG_BUTTON1)
97 mouse1_down = (device_flags & MOUSE_FLAG_DOWN) ? 0x01 : 0;
98 if (device_flags & MOUSE_FLAG_BUTTON2)
99 mouse2_down = (device_flags & MOUSE_FLAG_DOWN) ? 0x02 : 0;
101 buf[0] = 5; // message type
102 buf[1] = mouse1_down | mouse2_down; // button mask
103 buf[2] = param1 >> 8;
104 buf[3] = param1 & 0xff;
105 buf[4] = param2 >> 8;
106 buf[5] = param2 & 0xff;
107 write(vnc_sock, buf, 6);
111 printf("- Unknown type %x\n", message_type);
117 // re-request the entire framebuffer
118 buf[0] = 3; // message type
119 buf[1] = 1; // incremental
124 buf[6] = 640 >> 8; // width
126 buf[8] = 480 >> 8; // height
129 write(vnc_sock, buf, 10);
132 struct ServerInitialization {
133 unsigned short width;
134 unsigned short height;
135 unsigned char pixelformat[16]; // FIXME
136 unsigned int name_len;
142 int vnc_sock = tcp_connect("127.0.0.1", 5901);
143 struct ServerInitialization si;
146 if (read(vnc_sock, buf, 12) != 12)
147 error("short read on handshake\n");
148 write(vnc_sock, "RFB 003.003\n", 12);
151 if (read(vnc_sock, buf, 4) != 4)
152 error("short read on auth\n");
155 error("auth needed or connection failed\n");
159 write(vnc_sock, buf, 1);
161 // read the server initialization
162 if (read(vnc_sock, &si, sizeof(struct ServerInitialization)) != sizeof(struct ServerInitialization))
163 error("short read on SI");
165 printf("Server is %u x %u\n", ntohs(si.width), ntohs(si.height));
167 if (read(vnc_sock, buf, ntohl(si.name_len)) != ntohl(si.name_len))
168 error("short read on server name\n");
170 // printf("Server name is '%*s' (%u bytes)\n", ntohl(si.name_len), buf, ntohl(si.name_len));
172 // we can only accept raw encoding
173 buf[0] = 2; // message type
174 buf[1] = 0; // padding
175 buf[2] = 0; // number of encodings
177 buf[4] = 0; // raw encoding
182 write(vnc_sock, buf, 8);
184 // request the entire framebuffer
185 buf[0] = 3; // message type
186 buf[1] = 0; // incremental
191 buf[6] = 640 >> 8; // width
193 buf[8] = 480 >> 8; // height
196 write(vnc_sock, buf, 10);
198 printf("Connected to VNC!\n");
203 struct vnc_rectangle {
204 unsigned short x, y, width, height;
205 unsigned int encoding;
208 void handle_vnc_fbupdate(int vnc_sock)
210 struct vnc_rectangle rect;
211 unsigned char *data, *ptr, *src, *dst;
212 unsigned short num_rect;
213 int ret, data_left, i, xt, yt;
214 unsigned char smallblock[64 * 64 * 3];
216 if (read(vnc_sock, &num_rect, 2) != 2)
217 error("short read on num_rect\n");
219 for (i = 0; i < ntohs(num_rect); ++i) {
222 if (read(vnc_sock, &rect, sizeof(struct vnc_rectangle)) != sizeof(struct vnc_rectangle))
223 error("short read on vnc_rectangle\n");
225 if (ntohl(rect.encoding) != 0)
226 error("unsupported encoding\n");
228 width = ntohs(rect.width);
229 height = ntohs(rect.height);
231 printf("UPDATE: %ux%u at (%u,%u)\n", width, height,
232 ntohs(rect.x), ntohs(rect.y));
234 ptr = data = xmalloc(width * height * 4);
235 data_left = width * height * 4;
237 while (data_left > 0) {
238 ret = read(vnc_sock, ptr, data_left);
240 error("error on data read\n");
246 // push our 32-bit RGB data into small enough chunks
247 // (64x64) so we are sure we can send them without
248 // everything crashing and stuff :-)
249 for (yt = 0; yt < (height + 63) / 64; ++yt) {
250 for (xt = 0; xt < (width + 63) / 64; ++xt) {
252 int bw = width - xt * 64;
253 int bh = height - yt * 64;
260 for (y = 0; y < bh; ++y) {
261 src = data + ((yt * 64 + (bh - 1 - y)) * width + (xt * 64)) * 4;
262 for (x = 0; x < bw; ++x) {
270 rdp_send_bitmap_update(ntohs(rect.x) + xt * 64, ntohs(rect.y) + yt * 64, bw, bh, smallblock);
280 int vnc_sock = vnc_init();
281 int listen_on_vnc = 0;
283 if (!mcs_recv_connect_initial())
284 error("MCS_CONNECT_INITIAL recv failed");
285 mcs_send_connect_response();
288 uint8 type, data_pdu_type;
293 FD_SET(tcp_get_socket(), &readfs);
294 FD_SET(vnc_sock, &readfs);
296 select(FD_SETSIZE, &readfs, NULL, NULL, NULL);
298 // activity on RDP socket?
299 if (FD_ISSET(tcp_get_socket(), &readfs)) {
300 if ((s = rdp_recv(&type)) != NULL) {
301 if (type != RDP_PDU_DATA) {
302 printf("Unknown RDP packet of type %u\n", type);
306 in_uint8s(s, 8); /* shareid, pad, streamid, length */
307 in_uint8(s, data_pdu_type);
308 in_uint8s(s, 3); /* compress_type, compress_len */
310 switch (data_pdu_type) {
311 case RDP_DATA_PDU_INPUT:
312 handle_input_pdu(s, vnc_sock);
316 printf("Unknown data PDU type %u\n", data_pdu_type);
321 // activity on VNC socket?
322 if (FD_ISSET(vnc_sock, &readfs) && listen_on_vnc) {
323 unsigned char buf[256];
325 printf("Activity on VNC socket!\n");
327 if (read(vnc_sock, buf, 1) != 1)
328 error("short read on vnc_sock\n");
332 // frame buffer update!
333 printf("Framebuffer update\n");
334 if (read(vnc_sock, buf, 1) != 1)
335 error("short read on vnc_sock\n");
336 handle_vnc_fbupdate(vnc_sock);
342 printf("Unknown VNC server message %x\n", buf[0]);