]> git.sesse.net Git - rdpsrv/blob - rdpsrv.c
Endianness fixes. Sets encoding. Requests entire area.
[rdpsrv] / rdpsrv.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <errno.h>
5 #include <sys/socket.h>
6 #include <sys/ioctl.h>
7 #include <arpa/inet.h>
8
9 #include "rdesktop.h"
10
11 const int tcp_port_rdp = 3389;
12 int create_server_socket();
13 int serve_client();
14
15 int main()
16 {
17         int server_sock = create_server_socket();
18         for ( ;; ) {
19                 iso_recv_connect(server_sock);
20                 printf("Got connection.\n");
21                 serve_client();
22                 printf("Client closed.\n");
23         }
24 }
25
26 int create_server_socket()
27 {
28         int server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
29         const unsigned int one = 1, zero = 0;
30         struct sockaddr_in addr;
31         int err;
32
33         setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
34         ioctl(server_sock, FIONBIO, &zero);
35
36         addr.sin_family = AF_INET;
37         addr.sin_addr.s_addr = INADDR_ANY;
38         addr.sin_port = htons(tcp_port_rdp);
39
40         do {
41                 err = bind(server_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr));
42
43                 if (err == -1) {
44                         perror("bind()");
45
46                         /* try to recover from recoverable errors... */
47                         if (errno == ENOMEM || errno == EADDRINUSE) {
48                                 puts("Waiting 1 sec before trying again...");
49                                 sleep(1);
50                         } else {
51                                 puts("Giving up.");
52                                 exit(1);
53                         }
54                 }
55         } while (err == -1);
56
57         listen(server_sock, 20);
58         return server_sock;
59 }
60
61 void handle_input_pdu(STREAM s)
62 {
63         uint32 time;
64         uint16 message_type, device_flags, param1, param2;
65         uint16 num_events;
66         int i;
67
68         in_uint16_le(s, num_events);   // number of events
69         in_uint8s(s, 2);        // pad
70
71         for (i = 0; i < num_events; ++i) {
72                 rdp_recv_input(s, &time, &message_type, &device_flags, &param1, &param2);
73                 printf("Input event at time %u\n", time);
74                 
75                 switch (message_type) {
76                 case RDP_INPUT_SYNCHRONIZE:
77                         printf("- Type: Synchronize (ignored)\n");
78                         break;
79                 case RDP_INPUT_CODEPOINT:
80                         printf("- Type: Codepoint (ignored)\n");
81                         break;
82                 case RDP_INPUT_VIRTKEY:
83                         printf("- Type: Virtual key (ignored)\n");
84                         break;
85                 case RDP_INPUT_SCANCODE:
86                         printf("- Type: Scancode (ignored)\n");
87                         break;
88                 case RDP_INPUT_MOUSE:
89                         printf("- Type: Mouse\n");
90                         printf("- Device flags: %x\n", device_flags);
91                         printf("- Position: (%u,%u)\n", param1, param2);
92
93                         // debug
94                         rdp_send_bitmap_update(param1, param2);
95                         
96                         break;
97                 default:
98                         printf("- Unknown type %x\n", message_type);
99                         break;
100                 }
101                 printf("\n");
102         }
103 }
104
105 struct ServerInitialization {
106         unsigned short width;
107         unsigned short height;
108         unsigned char pixelformat[16]; // FIXME
109         unsigned int name_len;
110 };
111
112 int vnc_init()
113 {
114         char buf[256];
115         int vnc_sock = tcp_connect("127.0.0.1", 5901);
116         struct ServerInitialization si;
117
118         // get handshake
119         if (read(vnc_sock, buf, 12) != 12)
120                 error("short read on handshake\n");
121         write(vnc_sock, "RFB 003.003\n", 12);
122
123         // get auth
124         if (read(vnc_sock, buf, 4) != 4)
125                 error("short read on auth\n");
126
127         if (buf[3] != 1)
128                 error("auth needed or connection failed\n");
129
130         // send shared flag
131         buf[0] = 1;
132         write(vnc_sock, buf, 1);
133
134         // read the server initialization
135         if (read(vnc_sock, &si, sizeof(struct ServerInitialization)) != sizeof(struct ServerInitialization))
136                 error("short read on SI");
137
138         printf("Server is %u x %u\n", ntohs(si.width), ntohs(si.height));
139
140         if (read(vnc_sock, buf, ntohs(si.name_len)) != ntohs(si.name_len))
141                 error("short read on server name\n");
142
143         printf("Server name is '%*s'\n", ntohs(si.name_len), buf);
144
145         // we can only accept raw encoding
146         buf[0] = 2; // message type
147         buf[1] = 0; // padding
148         buf[2] = 0; // number of encodings
149         buf[3] = 1;
150         buf[4] = 0; // raw encoding
151
152         write(vnc_sock, buf, 5);
153         
154         // request the entire framebuffer
155         buf[0] = 3; // message type
156         buf[1] = 0; // incremental
157         buf[2] = 0; // xpos
158         buf[3] = 0;
159         buf[4] = 0; // ypos
160         buf[5] = 0;
161         buf[6] = 640 >> 8; // width
162         buf[7] = 640 % 0xff;
163         buf[8] = 480 >> 8; // height
164         buf[9] = 480 % 0xff;
165
166         write(vnc_sock, buf, 10);
167         
168         printf("Connected to VNC!\n");
169
170         return vnc_sock;
171 }
172
173 int serve_client()
174 {
175         int vnc_sock = vnc_init();
176         
177         if (!mcs_recv_connect_initial())
178                 error("MCS_CONNECT_INITIAL recv failed");
179         mcs_send_connect_response();
180
181         for ( ;; ) {
182                 uint8 type, data_pdu_type;
183                 STREAM s;
184
185                 while ((s = rdp_recv(&type)) != NULL) {
186                         if (type != RDP_PDU_DATA) {
187                                 printf("Unknown RDP packet of type %u\n", type);
188                                 continue;
189                         }
190
191                         in_uint8s(s, 8);        /* shareid, pad, streamid, length */
192                         in_uint8(s, data_pdu_type);
193                         in_uint8s(s, 3);        /* compress_type, compress_len */
194
195                         switch (data_pdu_type) {
196                         case RDP_DATA_PDU_INPUT:
197                                 printf("Input PDU\n");
198                                 handle_input_pdu(s);
199                                 break;
200                         default:
201                                 printf("Unknown data PDU type %u\n", data_pdu_type);
202                         };
203                 }
204         }
205 }