Fix coverity 268, 269, 546, 547, 548, 549 by checking for null return
[obnox/wireshark/wip.git] / epan / dissectors / packet-vnc.c
1 /* packet-vnc.c
2  * Routines for VNC dissection (Virtual Network Computing)
3  * Copyright 2005, Ulf Lamping <ulf.lamping@web.de>
4  * Copyright 2006-2007, Stephen Fisher (see AUTHORS file)
5  *
6  * $Id$
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25  */
26
27 /* Dissection of the VNC (Virtual Network Computing) network traffic.
28  *
29  * All versions of RealVNC and TightVNC are supported.
30  * Note: The addition of TightVNC support is not yet complete.
31  *
32  * Several VNC implementations available, see:
33  * http://www.realvnc.com/
34  * http://www.tightvnc.com/
35  * http://ultravnc.sourceforge.net/
36  * ...
37  *
38  * The protocol itself is known as RFB - Remote Frame Buffer Protocol.
39  *
40  * This code is based on the protocol specification:
41  *   http://www.realvnc.com/docs/rfbproto.pdf
42  *  and the RealVNC free edition & TightVNC source code
43  */
44
45 #ifdef HAVE_CONFIG_H
46 # include "config.h"
47 #endif
48
49 #include <glib.h>
50
51 #include <epan/conversation.h>
52 #include <epan/emem.h>
53 #include <epan/packet.h>
54 #include <epan/prefs.h>
55 #include <epan/expert.h>
56 #include "packet-x11-keysym.h" /* This contains the X11 value_string
57                                 * "keysym_vals_source" that VNC also uses. */
58
59 typedef enum {
60         VNC_SECURITY_TYPE_INVALID       =  0,
61         VNC_SECURITY_TYPE_NONE          =  1,
62         VNC_SECURITY_TYPE_VNC           =  2,
63         VNC_SECURITY_TYPE_RA2           =  5,
64         VNC_SECURITY_TYPE_RA2ne         =  6,
65         VNC_SECURITY_TYPE_TIGHT         = 16,
66         VNC_SECURITY_TYPE_ULTRA         = 17,
67         VNC_SECURITY_TYPE_TLS           = 18,
68         VNC_SECURITY_TYPE_VENCRYPT      = 19,
69         VNC_SECURITY_TYPE_GTK_VNC_SASL  = 20,
70         VNC_SECURITY_TYPE_MD5_HASH_AUTH = 21,
71         VNC_SECURITY_TYPE_XVP           = 22,
72         VNC_TIGHT_AUTH_TGHT_ULGNAUTH    = 119,
73         VNC_TIGHT_AUTH_TGHT_XTRNAUTH    = 130
74 } vnc_security_types_e;
75
76 static const value_string vnc_security_types_vs[] = {
77         { VNC_SECURITY_TYPE_INVALID,      "Invalid"      },
78         { VNC_SECURITY_TYPE_NONE,         "None"         },
79         { VNC_SECURITY_TYPE_VNC,          "VNC"          },
80         { VNC_SECURITY_TYPE_RA2,          "RA2"          },
81         { VNC_SECURITY_TYPE_RA2ne,        "RA2ne"        },
82         { VNC_SECURITY_TYPE_TIGHT,        "Tight"        },
83         { VNC_SECURITY_TYPE_ULTRA,        "Ultra"        },
84         { VNC_SECURITY_TYPE_TLS,          "TLS"          },
85         { VNC_SECURITY_TYPE_VENCRYPT,     "VeNCrypt"     },
86         { VNC_SECURITY_TYPE_GTK_VNC_SASL, "GTK-VNC SASL" },
87         { 0,  NULL                     }
88 };
89
90 static const true_false_string auth_result_tfs = {
91        "Failed",
92        "OK"
93 };
94
95 static const value_string yes_no_vs[] = {
96         { 0, "No"  },
97         { 1, "Yes" },
98         { 0,  NULL }
99 };
100
101 typedef enum {
102         VNC_CLIENT_MESSAGE_TYPE_SET_PIXEL_FORMAT        = 0,
103         VNC_CLIENT_MESSAGE_TYPE_SET_ENCODING            = 2,
104         VNC_CLIENT_MESSAGE_TYPE_FRAMEBUF_UPDATE_REQ     = 3,
105         VNC_CLIENT_MESSAGE_TYPE_KEY_EVENT               = 4,
106         VNC_CLIENT_MESSAGE_TYPE_POINTER_EVENT           = 5,
107         VNC_CLIENT_MESSAGE_TYPE_CLIENT_CUT_TEXT         = 6,
108 } vnc_client_message_types_e;
109
110 static const value_string vnc_client_message_types_vs[] = {
111         { VNC_CLIENT_MESSAGE_TYPE_SET_PIXEL_FORMAT,    "Set Pixel Format"               },
112         { VNC_CLIENT_MESSAGE_TYPE_SET_ENCODING,        "Set Encodings"                  },
113         { VNC_CLIENT_MESSAGE_TYPE_FRAMEBUF_UPDATE_REQ, "Framebuffer Update Request"     },
114         { VNC_CLIENT_MESSAGE_TYPE_KEY_EVENT,           "Key Event"                      },
115         { VNC_CLIENT_MESSAGE_TYPE_POINTER_EVENT,       "Pointer Event"                  },
116         { VNC_CLIENT_MESSAGE_TYPE_CLIENT_CUT_TEXT,     "Cut Text"                       },
117         { 0,  NULL                                                                      }
118 };
119
120 typedef enum {
121         VNC_SERVER_MESSAGE_TYPE_FRAMEBUFFER_UPDATE   = 0,
122         VNC_SERVER_MESSAGE_TYPE_SET_COLORMAP_ENTRIES = 1,
123         VNC_SERVER_MESSAGE_TYPE_RING_BELL            = 2,
124         VNC_SERVER_MESSAGE_TYPE_CUT_TEXT             = 3,
125 } vnc_server_message_types_e;
126
127 static const value_string vnc_server_message_types_vs[] = {
128         { VNC_SERVER_MESSAGE_TYPE_FRAMEBUFFER_UPDATE,   "Framebuffer Update"   },
129         { VNC_SERVER_MESSAGE_TYPE_SET_COLORMAP_ENTRIES, "Set Colormap Entries" },
130         { VNC_SERVER_MESSAGE_TYPE_RING_BELL,            "Ring Bell"            },
131         { VNC_SERVER_MESSAGE_TYPE_CUT_TEXT,             "Cut Text"             },
132         { 0,  NULL                                                             }
133 };
134
135 static const true_false_string button_mask_tfs = {
136         "Pressed",
137         "Not pressed"
138 };
139
140 typedef enum {
141         VNC_ENCODING_TYPE_DESKTOP_SIZE      = 0xFFFFFF21,
142         VNC_ENCODING_TYPE_LAST_RECT         = 0xFFFFFF20,
143         VNC_ENCODING_TYPE_POINTER_POS       = 0xFFFFFF18,
144         VNC_ENCODING_TYPE_RICH_CURSOR       = 0xFFFFFF11,
145         VNC_ENCODING_TYPE_X_CURSOR          = 0xFFFFFF10,
146         VNC_ENCODING_TYPE_RAW               =   0,
147         VNC_ENCODING_TYPE_COPY_RECT         =   1,
148         VNC_ENCODING_TYPE_RRE               =   2,
149         VNC_ENCODING_TYPE_CORRE             =   4,
150         VNC_ENCODING_TYPE_HEXTILE           =   5,
151         VNC_ENCODING_TYPE_ZLIB              =   6,
152         VNC_ENCODING_TYPE_TIGHT             =   7,
153         VNC_ENCODING_TYPE_ZLIBHEX           =   8,
154         VNC_ENCODING_TYPE_ULTRA             =   9,
155         VNC_ENCODING_TYPE_TRLE              =  15,
156         VNC_ENCODING_TYPE_RLE               =  16,
157         VNC_ENCODING_TYPE_HITACHI_ZYWRLE    =  17,
158         VNC_ENCODING_TYPE_JPEG_0            = -32,
159         VNC_ENCODING_TYPE_JPEG_1            = -31,
160         VNC_ENCODING_TYPE_JPEG_2            = -30,
161         VNC_ENCODING_TYPE_JPEG_3            = -29,
162         VNC_ENCODING_TYPE_JPEG_4            = -28,
163         VNC_ENCODING_TYPE_JPEG_5            = -27,
164         VNC_ENCODING_TYPE_JPEG_6            = -26,
165         VNC_ENCODING_TYPE_JPEG_7            = -25,
166         VNC_ENCODING_TYPE_JPEG_8            = -24,
167         VNC_ENCODING_TYPE_JPEG_9            = -23,
168         VNC_ENCODING_TYPE_COMPRESSION_0     = 0xFFFFFF00,
169         VNC_ENCODING_TYPE_COMPRESSION_1     = 0xFFFFFF01,
170         VNC_ENCODING_TYPE_COMPRESSION_2     = 0xFFFFFF02,
171         VNC_ENCODING_TYPE_COMPRESSION_3     = 0xFFFFFF03,
172         VNC_ENCODING_TYPE_COMPRESSION_4     = 0xFFFFFF04,
173         VNC_ENCODING_TYPE_COMPRESSION_5     = 0xFFFFFF05,
174         VNC_ENCODING_TYPE_COMPRESSION_6     = 0xFFFFFF06,
175         VNC_ENCODING_TYPE_COMPRESSION_7     = 0xFFFFFF07,
176         VNC_ENCODING_TYPE_COMPRESSION_8     = 0xFFFFFF08,
177         VNC_ENCODING_TYPE_COMPRESSION_9     = 0xFFFFFF09,
178         VNC_ENCODING_TYPE_WMVi              = 0x574D5669,
179         VNC_ENCODING_TYPE_CACHE             = 0xFFFF0000,
180         VNC_ENCODING_TYPE_CACHE_ENABLE      = 0xFFFF0001,
181         VNC_ENCODING_TYPE_XOR_ZLIB          = 0xFFFF0002,
182         VNC_ENCODING_TYPE_XOR_MONO_ZLIB     = 0xFFFF0003,
183         VNC_ENCODING_TYPE_XOR_MULTI_ZLIB    = 0xFFFF0004,
184         VNC_ENCODING_TYPE_SOLID_COLOR       = 0xFFFF0005,
185         VNC_ENCODING_TYPE_XOR_ENABLE        = 0xFFFF0006,
186         VNC_ENCODING_TYPE_CACHE_ZIP         = 0xFFFF0007,
187         VNC_ENCODING_TYPE_SOL_MONO_ZIP      = 0xFFFF0008,
188         VNC_ENCODING_TYPE_ULTRA_ZIP         = 0xFFFF0009,
189         VNC_ENCODING_TYPE_SERVER_STATE      = 0xFFFF8000,
190         VNC_ENCODING_TYPE_ENABLE_KEEP_ALIVE = 0xFFFF8001,
191         VNC_ENCODING_TYPE_FTP_PROTO_VER     = 0xFFFF8002,
192         VNC_ENCODING_TYPE_POINTER_CHANGE    = -257,
193         VNC_ENCODING_TYPE_EXT_KEY_EVENT     = -258,
194         VNC_ENCODING_TYPE_AUDIO             =  259,
195         VNC_ENCODING_TYPE_DESKTOP_NAME      = -307,
196         VNC_ENCODING_TYPE_EXTENDED_DESK_SIZE= -308
197 } vnc_encoding_type_e;
198
199 static const value_string encoding_types_vs[] = {
200         { VNC_ENCODING_TYPE_DESKTOP_SIZE,       "DesktopSize (pseudo)" },
201         { VNC_ENCODING_TYPE_LAST_RECT,          "LastRect (pseudo)"    },
202         { VNC_ENCODING_TYPE_POINTER_POS,        "Pointer pos (pseudo)" },
203         { VNC_ENCODING_TYPE_RICH_CURSOR,        "Rich Cursor (pseudo)" },
204         { VNC_ENCODING_TYPE_X_CURSOR,           "X Cursor (pseudo)"    },
205         { VNC_ENCODING_TYPE_RAW,                "Raw"                  },
206         { VNC_ENCODING_TYPE_COPY_RECT,          "CopyRect"             },
207         { VNC_ENCODING_TYPE_RRE,                "RRE"                  },
208         { VNC_ENCODING_TYPE_CORRE,              "CoRRE"                },
209         { VNC_ENCODING_TYPE_HEXTILE,            "Hextile"              },
210         { VNC_ENCODING_TYPE_ZLIB,               "Zlib"                 },
211         { VNC_ENCODING_TYPE_TIGHT,              "Tight"                },
212         { VNC_ENCODING_TYPE_ZLIBHEX,            "ZlibHex"              },
213         { VNC_ENCODING_TYPE_ULTRA,              "Ultra"                },
214         { VNC_ENCODING_TYPE_RLE,                "ZRLE"                 },
215         { VNC_ENCODING_TYPE_HITACHI_ZYWRLE,     "Hitachi ZYWRLE"       },
216         { VNC_ENCODING_TYPE_JPEG_0,             "JPEG quality level 0" },
217         { VNC_ENCODING_TYPE_JPEG_1,             "JPEG quality level 1" },
218         { VNC_ENCODING_TYPE_JPEG_2,             "JPEG quality level 2" },
219         { VNC_ENCODING_TYPE_JPEG_3,             "JPEG quality level 3" },
220         { VNC_ENCODING_TYPE_JPEG_4,             "JPEG quality level 4" },
221         { VNC_ENCODING_TYPE_JPEG_5,             "JPEG quality level 5" },
222         { VNC_ENCODING_TYPE_JPEG_6,             "JPEG quality level 6" },
223         { VNC_ENCODING_TYPE_JPEG_7,             "JPEG quality level 7" },
224         { VNC_ENCODING_TYPE_JPEG_8,             "JPEG quality level 8" },
225         { VNC_ENCODING_TYPE_JPEG_9,             "JPEG quality level 9" },
226         { VNC_ENCODING_TYPE_COMPRESSION_0,      "Compression level 0"  },
227         { VNC_ENCODING_TYPE_COMPRESSION_1,      "Compression level 1"  },
228         { VNC_ENCODING_TYPE_COMPRESSION_2,      "Compression level 2"  },
229         { VNC_ENCODING_TYPE_COMPRESSION_3,      "Compression level 3"  },
230         { VNC_ENCODING_TYPE_COMPRESSION_4,      "Compression level 4"  },
231         { VNC_ENCODING_TYPE_COMPRESSION_5,      "Compression level 5"  },
232         { VNC_ENCODING_TYPE_COMPRESSION_6,      "Compression level 6"  },
233         { VNC_ENCODING_TYPE_COMPRESSION_7,      "Compression level 7"  },
234         { VNC_ENCODING_TYPE_COMPRESSION_8,      "Compression level 8"  },
235         { VNC_ENCODING_TYPE_COMPRESSION_9,      "Compression level 9"  },
236         /* FIXME understand for real what the below mean. Taken from Ultra VNC source code */
237 /*      { VNC_ENCODING_TYPE_CACHE,     */
238         { VNC_ENCODING_TYPE_CACHE_ENABLE,       "Enable Caching"},
239 /*      { VNC_ENCODING_TYPE_XOR_ZLIB,
240         { VNC_ENCODING_TYPE_XOR_MONO_ZLIB,
241         { VNC_ENCODING_TYPE_XOR_MULTI_ZLIB,
242         { VNC_ENCODING_TYPE_SOLID_COLOR,
243         { VNC_ENCODING_TYPE_XOR_ENABLE,
244         { VNC_ENCODING_TYPE_CACHE_ZIP,
245         { VNC_ENCODING_TYPE_SOL_MONO_ZIP,
246         { VNC_ENCODING_TYPE_ULTRA_ZIP,
247 */      { VNC_ENCODING_TYPE_SERVER_STATE,       "Server State"         },
248         { VNC_ENCODING_TYPE_ENABLE_KEEP_ALIVE,  "Enable Keep Alive"    },
249         { VNC_ENCODING_TYPE_FTP_PROTO_VER,      "FTP protocol version" },
250         { VNC_ENCODING_TYPE_EXTENDED_DESK_SIZE, "Extended Desktop Size"},
251         { VNC_ENCODING_TYPE_DESKTOP_NAME,       "Desktop Name"         },
252         { 0,                            NULL                   }
253 };
254
255 /* Rectangle types for Tight encoding.  These come in the "control byte" at the
256  * start of a rectangle's payload.  Note that these are with respect to the most
257  * significant bits 4-7 of the control byte, so you must shift it to the right 4
258  * bits before comparing against these values.
259  */
260 #define TIGHT_RECT_FILL      0x08
261 #define TIGHT_RECT_JPEG      0x09
262 #define TIGHT_RECT_MAX_VALUE 0x09
263
264 #define TIGHT_RECT_EXPLICIT_FILTER_FLAG 0x04
265
266 /* Filter types for Basic encoding of Tight rectangles */
267 #define TIGHT_RECT_FILTER_COPY     0x00
268 #define TIGHT_RECT_FILTER_PALETTE  0x01
269 #define TIGHT_RECT_FILTER_GRADIENT 0x02
270
271 /* Minimum number of bytes to compress for Tight encoding */
272 #define TIGHT_MIN_BYTES_TO_COMPRESS 12
273
274 static const value_string tight_filter_ids_vs[] = {
275         { TIGHT_RECT_FILTER_COPY,     "Copy"     },
276         { TIGHT_RECT_FILTER_PALETTE,  "Palette"  },
277         { TIGHT_RECT_FILTER_GRADIENT, "Gradient" },
278         { 0, NULL }
279 };
280
281
282 typedef enum {
283         VNC_SESSION_STATE_SERVER_VERSION,
284         VNC_SESSION_STATE_CLIENT_VERSION,
285
286         VNC_SESSION_STATE_SECURITY,
287         VNC_SESSION_STATE_SECURITY_TYPES,
288
289         VNC_SESSION_STATE_TIGHT_TUNNELING_CAPABILITIES,
290         VNC_SESSION_STATE_TIGHT_TUNNEL_TYPE_REPLY,
291         VNC_SESSION_STATE_TIGHT_AUTH_CAPABILITIES,
292         VNC_SESSION_STATE_TIGHT_AUTH_TYPE_REPLY,
293         VNC_SESSION_STATE_TIGHT_UNKNOWN_PACKET3,
294
295         VNC_SESSION_STATE_VNC_AUTHENTICATION_CHALLENGE,
296         VNC_SESSION_STATE_VNC_AUTHENTICATION_RESPONSE,
297
298         VNC_SESSION_STATE_SECURITY_RESULT,
299
300         VNC_SESSION_STATE_CLIENT_INIT,
301         VNC_SESSION_STATE_SERVER_INIT,
302
303         VNC_SESSION_STATE_TIGHT_INTERACTION_CAPS,
304
305         VNC_SESSION_STATE_NORMAL_TRAFFIC
306 } vnc_session_state_e;
307
308 /* This structure will be tied to each conversation. */
309 typedef struct {
310         gdouble server_proto_ver, client_proto_ver;
311         vnc_session_state_e vnc_next_state;
312         guint32 server_port;
313         /* These are specific to TightVNC */
314         gint num_server_message_types;
315         gint num_client_message_types;
316         gint num_encoding_types;
317         guint8 security_type_selected;
318         gboolean tight_enabled;
319 } vnc_conversation_t;
320
321 /* This structure will be tied to each packet */
322 typedef struct {
323         vnc_session_state_e state;
324         gint preferred_encoding;
325         guint8 bytes_per_pixel;
326         guint8 depth;
327 } vnc_packet_t;
328
329 void proto_reg_handoff_vnc(void);
330
331 static gboolean vnc_startup_messages(tvbuff_t *tvb, packet_info *pinfo,
332                                      gint offset, proto_tree *tree,
333                                      vnc_conversation_t *per_conversation_info);
334 static void vnc_client_to_server(tvbuff_t *tvb, packet_info *pinfo,
335                                  gint *offset, proto_tree *tree);
336 static void vnc_server_to_client(tvbuff_t *tvb, packet_info *pinfo,
337                                  gint *offset, proto_tree *tree);
338 static void vnc_client_set_pixel_format(tvbuff_t *tvb, packet_info *pinfo,
339                                         gint *offset, proto_tree *tree);
340 static void vnc_client_set_encodings(tvbuff_t *tvb, packet_info *pinfo,
341                                      gint *offset, proto_tree *tree);
342 static void vnc_client_framebuffer_update_request(tvbuff_t *tvb,
343                                                   packet_info *pinfo,
344                                                   gint *offset,
345                                                   proto_tree *tree);
346 static void vnc_client_key_event(tvbuff_t *tvb, packet_info *pinfo,
347                                  gint *offset, proto_tree *tree);
348 static void vnc_client_pointer_event(tvbuff_t *tvb, packet_info *pinfo,
349                                      gint *offset, proto_tree *tree);
350 static void vnc_client_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
351                                 proto_tree *tree);
352
353 static guint vnc_server_framebuffer_update(tvbuff_t *tvb, packet_info *pinfo,
354                                            gint *offset, proto_tree *tree);
355 static guint vnc_raw_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
356                               proto_tree *tree, const guint16 width, const guint16 height);
357 static guint vnc_copyrect_encoding(tvbuff_t *tvb, packet_info *pinfo,
358                                    gint *offset, proto_tree *tree,
359                                    const guint16 width, const guint16 height);
360 static guint vnc_rre_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
361                               proto_tree *tree, const guint16 width, const guint16 height);
362 static guint vnc_hextile_encoding(tvbuff_t *tvb, packet_info *pinfo,
363                                   gint *offset, proto_tree *tree,
364                                   const guint16 width, const guint16 height);
365 static guint vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
366                                proto_tree *tree, const guint16 width, const guint16 height);
367 static guint vnc_tight_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
368                                 proto_tree *tree, const guint16 width, const guint16 height);
369 static guint vnc_rich_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo,
370                                       gint *offset, proto_tree *tree, const guint16 width,
371                                       const guint16 height);
372 static guint vnc_x_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo,
373                                    gint *offset, proto_tree *tree, const guint16 width,
374                                    const guint16 height);
375 static guint vnc_server_set_colormap_entries(tvbuff_t *tvb, packet_info *pinfo,
376                                              gint *offset, proto_tree *tree);
377 static void vnc_server_ring_bell(tvbuff_t *tvb, packet_info *pinfo,
378                                  gint *offset, proto_tree *tree);
379 static guint vnc_server_cut_text(tvbuff_t *tvb, packet_info *pinfo,
380                                  gint *offset, proto_tree *tree);
381 static void vnc_set_bytes_per_pixel(const packet_info *pinfo, const guint8 bytes_per_pixel);
382 static void vnc_set_depth(const packet_info *pinfo, const guint8 depth);
383 static guint8 vnc_get_bytes_per_pixel(const packet_info *pinfo);
384 static guint32 vnc_extended_desktop_size(tvbuff_t *tvb, gint *offset, proto_tree *tree);
385
386 #define DEST_PORT_VNC pinfo->destport == 5500 || pinfo->destport == 5501 || \
387                 pinfo->destport == 5900 || pinfo->destport == 5901 ||   \
388                 pinfo->destport == vnc_preference_alternate_port
389
390 #define VNC_BYTES_NEEDED(a)                                     \
391         if(a > (guint)tvb_length_remaining(tvb, *offset))       \
392                 return a;
393
394 /* Variables for our preferences */
395 static guint vnc_preference_alternate_port = 0;
396
397 /* Initialize the protocol and registered fields */
398 static int proto_vnc = -1; /* Protocol subtree */
399 static int hf_vnc_padding = -1;
400 static int hf_vnc_server_proto_ver = -1;
401 static int hf_vnc_client_proto_ver = -1;
402 static int hf_vnc_num_security_types = -1;
403 static int hf_vnc_security_type = -1;
404 static int hf_vnc_server_security_type = -1;
405 static int hf_vnc_client_security_type = -1;
406 static int hf_vnc_vendor_code = -1;
407 static int hf_vnc_security_type_string = -1;
408 static int hf_vnc_auth_challenge = -1;
409 static int hf_vnc_auth_response = -1;
410 static int hf_vnc_auth_result = -1;
411 static int hf_vnc_auth_error = -1;
412
413 static int hf_vnc_share_desktop_flag = -1;
414 static int hf_vnc_width = -1;
415 static int hf_vnc_height = -1;
416 static int hf_vnc_server_bits_per_pixel = -1;
417 static int hf_vnc_server_depth = -1;
418 static int hf_vnc_server_big_endian_flag = -1;
419 static int hf_vnc_server_true_color_flag = -1;
420 static int hf_vnc_server_red_max = -1;
421 static int hf_vnc_server_green_max = -1;
422 static int hf_vnc_server_blue_max = -1;
423 static int hf_vnc_server_red_shift = -1;
424 static int hf_vnc_server_green_shift = -1;
425 static int hf_vnc_server_blue_shift = -1;
426 static int hf_vnc_desktop_name = -1;
427 static int hf_vnc_desktop_name_len = -1;
428 static int hf_vnc_desktop_screen_id = -1;
429 static int hf_vnc_desktop_screen_x = -1;
430 static int hf_vnc_desktop_screen_y = -1;
431 static int hf_vnc_desktop_screen_width = -1;
432 static int hf_vnc_desktop_screen_height = -1;
433 static int hf_vnc_desktop_screen_flags = -1;
434 static int hf_vnc_num_server_message_types = -1;
435 static int hf_vnc_num_client_message_types = -1;
436 static int hf_vnc_num_encoding_types = -1;
437
438 /********** Client Message Types **********/
439
440 static int hf_vnc_client_message_type = -1; /* A subtree under VNC */
441 static int hf_vnc_client_bits_per_pixel = -1;
442 static int hf_vnc_client_depth = -1;
443 static int hf_vnc_client_big_endian_flag = -1;
444 static int hf_vnc_client_true_color_flag = -1;
445 static int hf_vnc_client_red_max = -1;
446 static int hf_vnc_client_green_max = -1;
447 static int hf_vnc_client_blue_max = -1;
448 static int hf_vnc_client_red_shift = -1;
449 static int hf_vnc_client_green_shift = -1;
450 static int hf_vnc_client_blue_shift = -1;
451
452 /* Client Key Event */
453 static int hf_vnc_key_down = -1;
454 static int hf_vnc_key = -1;
455
456 /* Client Pointer Event */
457 static int hf_vnc_button_1_pos = -1;
458 static int hf_vnc_button_2_pos = -1;
459 static int hf_vnc_button_3_pos = -1;
460 static int hf_vnc_button_4_pos = -1;
461 static int hf_vnc_button_5_pos = -1;
462 static int hf_vnc_button_6_pos = -1;
463 static int hf_vnc_button_7_pos = -1;
464 static int hf_vnc_button_8_pos = -1;
465 static int hf_vnc_pointer_x_pos = -1;
466 static int hf_vnc_pointer_y_pos = -1;
467
468 /* Client Framebuffer Update Request */
469 static int hf_vnc_update_req_incremental = -1;
470 static int hf_vnc_update_req_x_pos = -1;
471 static int hf_vnc_update_req_y_pos = -1;
472 static int hf_vnc_update_req_width = -1;
473 static int hf_vnc_update_req_height = -1;
474
475 /* Client Set Encodings */
476 static int hf_vnc_client_set_encodings_encoding_type = -1;
477
478 /* Client Cut Text */
479 static int hf_vnc_client_cut_text_len = -1;
480 static int hf_vnc_client_cut_text = -1;
481
482 /********** Server Message Types **********/
483
484 static int hf_vnc_server_message_type = -1; /* Subtree */
485
486 /* Tunneling capabilities (TightVNC extension) */
487 static int hf_vnc_tight_num_tunnel_types = -1;
488 static int hf_vnc_tight_tunnel_type = -1;
489
490 /* Authentication capabilities (TightVNC extension) */
491 static int hf_vnc_tight_num_auth_types = -1;
492 static int hf_vnc_tight_auth_code = -1;
493 /* TightVNC capabilities */
494 static int hf_vnc_tight_server_message_type = -1;
495 static int hf_vnc_tight_server_vendor = -1;
496 static int hf_vnc_tight_server_name = -1;
497
498 static int hf_vnc_tight_client_message_type = -1;
499 static int hf_vnc_tight_client_vendor = -1;
500 static int hf_vnc_tight_client_name = -1;
501
502 static int hf_vnc_tight_encoding_type = -1;
503 static int hf_vnc_tight_encoding_vendor = -1;
504 static int hf_vnc_tight_encoding_name = -1;
505
506 /* Tight compression parameters */
507 static int hf_vnc_tight_reset_stream0 = -1;
508 static int hf_vnc_tight_reset_stream1 = -1;
509 static int hf_vnc_tight_reset_stream2 = -1;
510 static int hf_vnc_tight_reset_stream3 = -1;
511
512 static int hf_vnc_tight_rect_type = -1;
513
514 static int hf_vnc_tight_image_len = -1;
515 static int hf_vnc_tight_image_data = -1;
516
517 static int hf_vnc_tight_fill_color = -1;
518
519 static int hf_vnc_tight_filter_flag = -1;
520 static int hf_vnc_tight_filter_id = -1;
521
522 static int hf_vnc_tight_palette_num_colors = -1;
523 static int hf_vnc_tight_palette_data = -1;
524
525 /* Server Framebuffer Update */
526 static int hf_vnc_fb_update_x_pos = -1;
527 static int hf_vnc_fb_update_y_pos = -1;
528 static int hf_vnc_fb_update_width = -1;
529 static int hf_vnc_fb_update_height = -1;
530 static int hf_vnc_fb_update_encoding_type = -1;
531
532 /* Raw Encoding */
533 static int hf_vnc_raw_pixel_data = -1;
534
535 /* CopyRect Encoding */
536 static int hf_vnc_copyrect_src_x_pos = -1;
537 static int hf_vnc_copyrect_src_y_pos = -1;
538
539 /* RRE Encoding */
540 static int hf_vnc_rre_num_subrects = -1;
541 static int hf_vnc_rre_bg_pixel = -1;
542
543 static int hf_vnc_rre_subrect_pixel = -1;
544 static int hf_vnc_rre_subrect_x_pos = -1;
545 static int hf_vnc_rre_subrect_y_pos = -1;
546 static int hf_vnc_rre_subrect_width = -1;
547 static int hf_vnc_rre_subrect_height = -1;
548
549 /* Hextile Encoding */
550 static int hf_vnc_hextile_subencoding_mask = -1;
551 static int hf_vnc_hextile_raw = -1;
552 static int hf_vnc_hextile_raw_value = -1;
553 static int hf_vnc_hextile_bg = -1;
554 static int hf_vnc_hextile_bg_value = -1;
555 static int hf_vnc_hextile_fg = -1;
556 static int hf_vnc_hextile_fg_value = -1;
557 static int hf_vnc_hextile_anysubrects = -1;
558 static int hf_vnc_hextile_num_subrects = -1;
559 static int hf_vnc_hextile_subrectscolored = -1;
560 static int hf_vnc_hextile_subrect_pixel_value = -1;
561 static int hf_vnc_hextile_subrect_x_pos = -1;
562 static int hf_vnc_hextile_subrect_y_pos = -1;
563 static int hf_vnc_hextile_subrect_width = -1;
564 static int hf_vnc_hextile_subrect_height = -1;
565
566 /* ZRLE Encoding */
567 static int hf_vnc_zrle_len = -1;
568 static int hf_vnc_zrle_subencoding = -1;
569 static int hf_vnc_zrle_rle = -1;
570 static int hf_vnc_zrle_palette_size = -1;
571 static int hf_vnc_zrle_data = -1;
572 static int hf_vnc_zrle_raw = -1;
573 static int hf_vnc_zrle_palette = -1;
574
575 /* Cursor Encoding */
576 static int hf_vnc_cursor_x_fore_back = -1;
577 static int hf_vnc_cursor_encoding_pixels = -1;
578 static int hf_vnc_cursor_encoding_bitmask = -1;
579
580 /* Server Set Colormap Entries */
581 static int hf_vnc_color_groups = -1;
582 static int hf_vnc_colormap_first_color = -1;
583 static int hf_vnc_colormap_num_colors = -1;
584 static int hf_vnc_colormap_red = -1;
585 static int hf_vnc_colormap_green = -1;
586 static int hf_vnc_colormap_blue = -1;
587
588 /* Server Cut Text */
589 static int hf_vnc_server_cut_text_len = -1;
590 static int hf_vnc_server_cut_text = -1;
591
592 /********** End of Server Message Types **********/
593
594 static gboolean vnc_preference_desegment = TRUE;
595
596 /* Initialize the subtree pointers */
597 static gint ett_vnc = -1;
598 static gint ett_vnc_client_message_type = -1;
599 static gint ett_vnc_server_message_type = -1;
600 static gint ett_vnc_rect = -1;
601 static gint ett_vnc_encoding_type = -1;
602 static gint ett_vnc_rre_subrect = -1;
603 static gint ett_vnc_hextile_subencoding_mask = -1;
604 static gint ett_vnc_hextile_num_subrects = -1;
605 static gint ett_vnc_hextile_subrect = -1;
606 static gint ett_vnc_zrle_subencoding = -1;
607 static gint ett_vnc_colormap_num_groups = -1;
608 static gint ett_vnc_colormap_color_group = -1;
609 static gint ett_vnc_desktop_screen = -1;
610
611 /* Global so they keep their value between packets */
612 guint8 vnc_bytes_per_pixel;
613 guint8 vnc_depth;
614
615
616 static dissector_handle_t vnc_handle;
617
618 /* Code to dissect the packets */
619 static void
620 dissect_vnc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
621 {
622         gboolean ret;
623         gint offset = 0;
624
625         /* Set up structures needed to add the protocol subtree and manage it */
626         proto_item *ti=NULL;
627         proto_tree *vnc_tree=NULL;
628
629         conversation_t *conversation;
630         vnc_conversation_t *per_conversation_info;
631
632         conversation = find_or_create_conversation(pinfo);
633
634         /* Retrieve information from conversation, or add it if it isn't
635          * there yet */
636         per_conversation_info = conversation_get_proto_data(conversation, proto_vnc);
637         if(!per_conversation_info) {
638                 per_conversation_info = se_alloc(sizeof(vnc_conversation_t));
639
640                 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_SERVER_VERSION;
641                 per_conversation_info->security_type_selected = VNC_SECURITY_TYPE_INVALID;
642                 per_conversation_info->tight_enabled = FALSE;
643
644                 conversation_add_proto_data(conversation, proto_vnc, per_conversation_info);
645         }
646
647
648         /* Make entries in Protocol column and Info column on summary display */
649         col_set_str(pinfo->cinfo, COL_PROTOCOL, "VNC");
650
651         /* First, clear the info column */
652         col_clear(pinfo->cinfo, COL_INFO);
653
654         /* create display subtree for the protocol */
655         if(tree) {
656                 ti = proto_tree_add_item(tree, proto_vnc, tvb, 0, -1, FALSE);
657                 vnc_tree = proto_item_add_subtree(ti, ett_vnc);
658         }
659
660         offset = 0; /* Start at the beginning of the VNC protocol data */
661
662         /* Dissect any remaining session startup messages */
663         ret = vnc_startup_messages(tvb, pinfo, offset, vnc_tree,
664                                    per_conversation_info);
665
666         vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
667         vnc_set_depth(pinfo, vnc_depth);
668
669         if(!ret) {
670                 if(DEST_PORT_VNC || per_conversation_info->server_port == pinfo->destport)
671                         vnc_client_to_server(tvb, pinfo, &offset, vnc_tree);
672                 else
673                         vnc_server_to_client(tvb, pinfo, &offset, vnc_tree);
674         }
675 }
676
677 /* Returns the new offset after processing the 4-byte vendor string */
678 static gint
679 process_vendor(proto_tree *tree, gint hfindex, tvbuff_t *tvb, gint offset)
680 {
681         gchar *vendor;
682         proto_item *ti;
683
684         if (tree) {
685                 vendor = tvb_get_ephemeral_string(tvb, offset, 4);
686
687                 ti = proto_tree_add_string(tree, hfindex, tvb, offset, 4, vendor);
688
689                 if(g_ascii_strcasecmp(vendor, "STDV") == 0)
690                         proto_item_append_text(ti, " (Standard VNC vendor)");
691                 else if(g_ascii_strcasecmp(vendor, "TRDV") == 0)
692                         proto_item_append_text(ti, " (Tridia VNC vendor)");
693                 else if(g_ascii_strcasecmp(vendor, "TGHT") == 0)
694                         proto_item_append_text(ti, " (Tight VNC vendor)");
695         }
696
697         offset += 4;
698         return offset;
699 }
700
701 /* Returns the new offset after processing the specified number of capabilities */
702 static gint
703 process_tight_capabilities(proto_tree *tree,
704                            gint type_index, gint vendor_index, gint name_index,
705                            tvbuff_t *tvb, gint offset, const gint num_capabilities)
706 {
707         gint i;
708         /* See vnc_unixsrc/include/rfbproto.h:rfbCapabilityInfo */
709
710         for (i = 0; i < num_capabilities; i++) {
711                 char *name;
712
713                 proto_tree_add_item(tree, type_index, tvb, offset, 4, FALSE);
714                 offset += 4;
715
716                 offset = process_vendor(tree, vendor_index, tvb, offset);
717
718                 name = tvb_get_ephemeral_string(tvb, offset, 8);
719                 proto_tree_add_string(tree, name_index, tvb, offset, 8, name);
720                 offset += 8;
721         }
722
723         return offset;
724 }
725
726 /* Returns true if this looks like a client or server version packet: 12 bytes, in the format "RFB xxx.yyy\n" .
727 * Will check for the 12 bytes exact length, the 'RFB ' string and that it ends with a '\n'.
728 * The exact 'xxx.yyy' is checked later, by trying to convert it to a double using g_ascii_strtod.
729 */
730 static gboolean
731 vnc_is_client_or_server_version_message(tvbuff_t *tvb)
732 {
733         if(tvb_length(tvb) != 12) {
734                 return FALSE;
735         }
736
737         if(tvb_strncaseeql(tvb, 0, "RFB ", 4) != 0) {
738                 return FALSE;
739         }
740         /* 0x2e = '.'   0xa = '\n' */
741         if((tvb_get_guint8(tvb, 7) != 0x2e) || (tvb_get_guint8(tvb,11) != 0xa)) {
742                 return FALSE;
743         }
744
745         return TRUE;
746 }
747
748 static gboolean test_vnc_protocol(tvbuff_t *tvb, packet_info *pinfo,
749                                   proto_tree *tree)
750 {
751         conversation_t *conversation;
752
753         if (vnc_is_client_or_server_version_message(tvb)) {
754                 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
755                                                 &pinfo->dst, pinfo->ptype,
756                                                 pinfo->srcport,
757                                                 pinfo->destport, 0);
758                 conversation_set_dissector(conversation, vnc_handle);
759                 dissect_vnc(tvb, pinfo, tree);
760                 return TRUE;
761         }
762         return FALSE;
763 }
764
765 /* Returns true if additional session startup messages follow */
766 static gboolean
767 vnc_startup_messages(tvbuff_t *tvb, packet_info *pinfo, gint offset,
768                      proto_tree *tree, vnc_conversation_t
769                      *per_conversation_info)
770 {
771         guint8 num_security_types;
772         guint32 desktop_name_len, auth_result, text_len, auth_code;
773         vnc_packet_t *per_packet_info;
774         gint num_tunnel_types;
775         gint num_auth_types;
776
777         per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
778
779         if(!per_packet_info) {
780                 per_packet_info = se_alloc(sizeof(vnc_packet_t));
781
782                 per_packet_info->state = per_conversation_info->vnc_next_state;
783                 per_packet_info->preferred_encoding = -1;
784
785                 p_add_proto_data(pinfo->fd, proto_vnc, per_packet_info);
786         }
787
788         /* Packet dissection follows */
789         switch(per_packet_info->state) {
790
791         case VNC_SESSION_STATE_SERVER_VERSION :
792                 if (!vnc_is_client_or_server_version_message(tvb))
793                         return TRUE; /* we still hope to get a SERVER_VERSION message some day. Do not proceed yet */
794
795                 proto_tree_add_item(tree, hf_vnc_server_proto_ver, tvb, 4,
796                                     7, FALSE);
797                 per_conversation_info->server_proto_ver =
798                         g_ascii_strtod((char *)tvb_get_ephemeral_string(tvb, 4, 7), NULL);
799                 per_conversation_info->server_port = pinfo->srcport;
800
801                 if (check_col(pinfo->cinfo, COL_INFO))
802                         col_add_fstr(pinfo->cinfo, COL_INFO,
803                                      "Server protocol version: %s",
804                                      tvb_format_text(tvb, 4, 7));
805
806                 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_CLIENT_VERSION;
807                 break;
808
809         case VNC_SESSION_STATE_CLIENT_VERSION :
810                 if (!vnc_is_client_or_server_version_message(tvb))
811                         return TRUE; /* we still hope to get a CLIENT_VERSION message some day. Do not proceed yet */
812
813                 proto_tree_add_item(tree, hf_vnc_client_proto_ver, tvb,
814                                     4, 7, FALSE);
815                 per_conversation_info->client_proto_ver =
816                         g_ascii_strtod((char *)tvb_get_ephemeral_string(tvb, 4, 7), NULL);
817
818                 if (check_col(pinfo->cinfo, COL_INFO))
819                         col_add_fstr(pinfo->cinfo, COL_INFO,
820                                      "Client protocol version: %s",
821                                      tvb_format_text(tvb, 4, 7));
822
823                 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_SECURITY;
824                 break;
825
826         case VNC_SESSION_STATE_SECURITY :
827                 col_set_str(pinfo->cinfo, COL_INFO, "Security types supported");
828
829                 /* We're checking against the client protocol version because
830                  * the client is the final decider on which version to use
831                  * after the server offers the highest version it supports. */
832
833                 if(per_conversation_info->client_proto_ver >= 3.007) {
834                         num_security_types = tvb_get_guint8(tvb, offset);
835                         if (tree) {
836                                 proto_tree_add_item(tree,
837                                                     hf_vnc_num_security_types,
838                                                     tvb, offset, 1, FALSE);
839
840                                 for(offset = 1; offset <= num_security_types; offset++){
841                                         proto_tree_add_item(tree,
842                                                             hf_vnc_security_type, tvb,
843                                                             offset, 1, FALSE);
844                                 }
845                         }
846                         per_conversation_info->vnc_next_state = VNC_SESSION_STATE_SECURITY_TYPES;
847                 } else {
848                         /* Version < 3.007: The server decides the
849                          * authentication type for us to use */
850                         proto_tree_add_item(tree, hf_vnc_server_security_type,
851                                             tvb, offset, 4, FALSE);
852                         /* The cast below is possible since in older versions of the protocol the only possible values are 0,1,2 */
853                         per_conversation_info->security_type_selected = (guint8)tvb_get_ntohl(tvb, offset);
854                         switch(per_conversation_info->security_type_selected) {
855
856                         case VNC_SECURITY_TYPE_INVALID:
857                                 /* TODO: In this case (INVALID) the connection has failed */
858                                 /* and there should be an error string describing the error */
859                                 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_SECURITY_TYPES;
860                                 break;
861
862                         case VNC_SECURITY_TYPE_NONE:
863                                 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_CLIENT_INIT;
864                                 break;
865
866                         case VNC_SECURITY_TYPE_VNC:
867                                 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_VNC_AUTHENTICATION_CHALLENGE;
868                                 break;
869
870                         default:
871                                 /* Security type not supported by this dissector */
872                                 break;
873                         }
874                 }
875
876                 break;
877
878         case VNC_SESSION_STATE_SECURITY_TYPES :
879                 col_set_str(pinfo->cinfo, COL_INFO, "Authentication type selected by client");
880                 proto_tree_add_item(tree, hf_vnc_client_security_type, tvb, offset, 1, FALSE);
881                 per_conversation_info->security_type_selected =
882                         tvb_get_guint8(tvb, offset);
883
884                 switch(per_conversation_info->security_type_selected) {
885
886                 case VNC_SECURITY_TYPE_NONE :
887                         if(per_conversation_info->client_proto_ver >= 3.008)
888                                 per_conversation_info->vnc_next_state =
889                                         VNC_SESSION_STATE_SECURITY_RESULT;
890                         else
891                                 per_conversation_info->vnc_next_state =
892                                         VNC_SESSION_STATE_CLIENT_INIT;
893
894                         break;
895
896                 case VNC_SECURITY_TYPE_VNC :
897                         per_conversation_info->vnc_next_state =
898                                 VNC_SESSION_STATE_VNC_AUTHENTICATION_CHALLENGE;
899                         break;
900
901                 case VNC_SECURITY_TYPE_TIGHT :
902                         per_conversation_info->vnc_next_state =
903                                 VNC_SESSION_STATE_TIGHT_TUNNELING_CAPABILITIES;
904                         per_conversation_info->tight_enabled = TRUE;
905                         break;
906
907                 default :
908                         /* Security type not supported by this dissector */
909                         break;
910                 }
911
912                 break;
913
914         case VNC_SESSION_STATE_TIGHT_TUNNELING_CAPABILITIES :
915         {
916                 gint i;
917
918                 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC tunneling capabilities supported");
919
920                 proto_tree_add_item(tree, hf_vnc_tight_num_tunnel_types, tvb, offset, 4, FALSE);
921                 num_tunnel_types = tvb_get_ntohl(tvb, offset);
922
923                 offset += 4;
924
925                 for(i = 0; i < num_tunnel_types; i++) {
926                         /* TightVNC and Xvnc don't support any tunnel capabilities yet, but each capability
927                          * is 16 bytes, so skip them.
928                          */
929
930                         proto_tree_add_item(tree, hf_vnc_tight_tunnel_type, tvb, offset, 16, FALSE);
931                         offset += 16;
932                 }
933
934                 if (num_tunnel_types == 0)
935                         per_conversation_info->vnc_next_state = VNC_SESSION_STATE_TIGHT_AUTH_CAPABILITIES;
936                 else
937                         per_conversation_info->vnc_next_state = VNC_SESSION_STATE_TIGHT_TUNNEL_TYPE_REPLY;
938                 break;
939         }
940         case VNC_SESSION_STATE_TIGHT_TUNNEL_TYPE_REPLY:
941                 /* Neither TightVNC nor Xvnc implement this; they just have a placeholder that emits an error
942                  * message and closes the connection (xserver/hw/vnc/auth.c:rfbProcessClientTunnelingType).
943                  * We should actually never get here...
944                  */
945                 break;
946
947         case VNC_SESSION_STATE_TIGHT_AUTH_CAPABILITIES:
948                 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC authentication capabilities supported");
949
950                 proto_tree_add_item(tree, hf_vnc_tight_num_auth_types, tvb, offset, 4, FALSE);
951                 num_auth_types = tvb_get_ntohl(tvb, offset);
952                 offset += 4;
953
954                 {
955                         int i;
956                         guint8 *vendor, *signature;
957                         for (i = 0; i < 1; i++) {
958                                 auth_code = tvb_get_ntohl(tvb, offset);
959                                 proto_tree_add_item(tree, hf_vnc_tight_auth_code, tvb, offset, 4, FALSE);
960                                 offset += 4;
961                                 vendor = tvb_get_ephemeral_string(tvb, offset, 4);
962                                 process_vendor(tree, hf_vnc_tight_server_vendor, tvb, offset);
963                                 offset += 4;
964                                 signature = tvb_get_ephemeral_string(tvb, offset, 8);
965                                 proto_tree_add_text(tree, tvb, offset, 8, "Signature: %s", signature);
966                                 offset += 8;
967
968                                 switch(auth_code) {
969                                         case VNC_SECURITY_TYPE_NONE:
970                                                 if ((g_ascii_strcasecmp(vendor, "STDV") != 0) || (g_ascii_strcasecmp(signature, "NOAUTH__") != 0)) {
971                                                 /* TODO: create a Expert Info */
972                                                         proto_tree_add_text(tree, tvb, offset, 0, "Authentication code does not match vendor or signature");
973                                                 }
974                                                 break;
975                                         case VNC_SECURITY_TYPE_VNC:
976                                                 if ((g_ascii_strcasecmp(vendor, "STDV") != 0) || (g_ascii_strcasecmp(signature, "VNCAUTH_") != 0)) {
977                                                 /* TODO: create a Expert Info */
978                                                         proto_tree_add_text(tree, tvb, offset, 0, "Authentication code does not match vendor or signature");
979                                                 }
980                                                 break;
981                                         case VNC_SECURITY_TYPE_VENCRYPT:
982                                                 if ((g_ascii_strcasecmp(vendor, "VENC") != 0) || (g_ascii_strcasecmp(signature, "VENCRYPT") != 0)) {
983                                                 /* TODO: create a Expert Info */
984                                                         proto_tree_add_text(tree, tvb, offset, 0, "Authentication code does not match vendor or signature");
985                                                 }
986                                                 break;
987                                         case VNC_SECURITY_TYPE_GTK_VNC_SASL:
988                                                 if ((g_ascii_strcasecmp(vendor, "GTKV") != 0) || (g_ascii_strcasecmp(signature, "SASL____") != 0)) {
989                                                 /* TODO: create a Expert Info */
990                                                         proto_tree_add_text(tree, tvb, offset, 0, "Authentication code does not match vendor or signature");
991                                                 }
992                                                 break;
993                                         case VNC_TIGHT_AUTH_TGHT_ULGNAUTH:
994                                                 if ((g_ascii_strcasecmp(vendor, "TGHT") != 0) || (g_ascii_strcasecmp(signature, "ULGNAUTH") != 0)) {
995                                                 /* TODO: create a Expert Info */
996                                                         proto_tree_add_text(tree, tvb, offset, 0, "Authentication code does not match vendor or signature");
997                                                 }
998                                                 break;
999                                         case VNC_TIGHT_AUTH_TGHT_XTRNAUTH:
1000                                                 if ((g_ascii_strcasecmp(vendor, "TGHT") != 0) || (g_ascii_strcasecmp(signature, "XTRNAUTH") != 0)) {
1001                                                 /* TODO: create a Expert Info */
1002                                                         proto_tree_add_text(tree, tvb, offset, 0, "Authentication code does not match vendor or signature");
1003                                                 }
1004                                                 break;
1005                                         default:
1006                                                 proto_tree_add_text(tree, tvb, offset, 0, "Unknown TIGHT VNC authentication");
1007                                                 break;
1008                                 }
1009                         }
1010                 }
1011
1012                 if (num_auth_types == 0)
1013                         per_conversation_info->vnc_next_state = VNC_SESSION_STATE_CLIENT_INIT;
1014                 else
1015                         per_conversation_info->vnc_next_state = VNC_SESSION_STATE_TIGHT_AUTH_TYPE_REPLY;
1016                 break;
1017
1018         case VNC_SESSION_STATE_TIGHT_AUTH_TYPE_REPLY:
1019                 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC authentication type selected by client");
1020                 auth_code = tvb_get_ntohl(tvb, offset);
1021                 proto_tree_add_item(tree, hf_vnc_tight_auth_code, tvb, offset, 4, FALSE);
1022
1023                 switch(auth_code) {
1024                         case VNC_SECURITY_TYPE_NONE:
1025                                 per_conversation_info->security_type_selected = VNC_SECURITY_TYPE_NONE;
1026                                 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_CLIENT_INIT;
1027                         break;
1028                         case VNC_SECURITY_TYPE_VNC:
1029                                 per_conversation_info->security_type_selected = VNC_SECURITY_TYPE_VNC;
1030                                 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_VNC_AUTHENTICATION_CHALLENGE;
1031                         break;
1032                         case VNC_SECURITY_TYPE_GTK_VNC_SASL:
1033                                 per_conversation_info->security_type_selected = VNC_SECURITY_TYPE_GTK_VNC_SASL;
1034                                 /* TODO: dissection not implemented yet */
1035                                 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_TIGHT_UNKNOWN_PACKET3;
1036                                 break;
1037                         case VNC_TIGHT_AUTH_TGHT_ULGNAUTH:
1038                                 per_conversation_info->security_type_selected = VNC_TIGHT_AUTH_TGHT_ULGNAUTH;
1039                                 /* TODO: dissection not implemented yet */
1040                                 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_TIGHT_UNKNOWN_PACKET3;
1041                                 break;
1042                         case VNC_TIGHT_AUTH_TGHT_XTRNAUTH:
1043                                 per_conversation_info->security_type_selected = VNC_TIGHT_AUTH_TGHT_XTRNAUTH;
1044                                 /* TODO: dissection not implemented yet */
1045                                 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_TIGHT_UNKNOWN_PACKET3;
1046                                 break;
1047                         default:
1048                                 proto_tree_add_text(tree, tvb, offset, 0, "Unknown authentication selected");
1049                                 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_TIGHT_UNKNOWN_PACKET3;
1050                                 break;
1051                 }
1052
1053                 break;
1054
1055         case VNC_SESSION_STATE_TIGHT_UNKNOWN_PACKET3 :
1056                 col_set_str(pinfo->cinfo, COL_INFO, "Unknown packet (TightVNC)");
1057
1058                 proto_tree_add_text(tree, tvb, offset, -1,
1059                                     "Unknown packet (TightVNC)");
1060
1061                 per_conversation_info->vnc_next_state =
1062                         VNC_SESSION_STATE_VNC_AUTHENTICATION_CHALLENGE;
1063
1064                 break;
1065
1066         case VNC_SESSION_STATE_VNC_AUTHENTICATION_CHALLENGE :
1067                 col_set_str(pinfo->cinfo, COL_INFO, "Authentication challenge from server");
1068
1069                 proto_tree_add_item(tree, hf_vnc_auth_challenge, tvb,
1070                                     offset, 16, FALSE);
1071
1072                 per_conversation_info->vnc_next_state =
1073                         VNC_SESSION_STATE_VNC_AUTHENTICATION_RESPONSE;
1074                 break;
1075
1076         case VNC_SESSION_STATE_VNC_AUTHENTICATION_RESPONSE :
1077                 col_set_str(pinfo->cinfo, COL_INFO, "Authentication response from client");
1078
1079                 proto_tree_add_item(tree, hf_vnc_auth_response, tvb,
1080                                     offset, 16, FALSE);
1081
1082                 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_SECURITY_RESULT;
1083                 break;
1084
1085         case VNC_SESSION_STATE_SECURITY_RESULT :
1086                 col_set_str(pinfo->cinfo, COL_INFO, "Authentication result");
1087
1088                 proto_tree_add_item(tree, hf_vnc_auth_result, tvb, offset,
1089                                     4, FALSE);
1090                 auth_result = tvb_get_ntohl(tvb, offset);
1091                 offset += 4;
1092
1093                 switch(auth_result) {
1094
1095                 case 0 : /* OK */
1096                         per_conversation_info->vnc_next_state = VNC_SESSION_STATE_CLIENT_INIT;
1097                         break;
1098
1099                 case 1 : /* Failed */
1100                         if(per_conversation_info->client_proto_ver >= 3.008) {
1101                                 text_len = tvb_get_ntohl(tvb, offset);
1102                                 proto_tree_add_text(tree, tvb, offset, 4, "Length of authentication error: %d", text_len);
1103                                 offset += 4;
1104
1105                                 proto_tree_add_item(tree, hf_vnc_auth_error, tvb,
1106                                                     offset, text_len, FALSE);
1107                         }
1108
1109                         return TRUE; /* All versions: Do not continue
1110                                         processing VNC packets as connection
1111                                         will be closed after this packet. */
1112
1113                         break;
1114                 }
1115
1116                 break;
1117
1118         case VNC_SESSION_STATE_CLIENT_INIT :
1119                 col_set_str(pinfo->cinfo, COL_INFO, "Share desktop flag");
1120
1121                 proto_tree_add_item(tree, hf_vnc_share_desktop_flag, tvb,
1122                                     offset, 1, FALSE);
1123
1124                 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_SERVER_INIT;
1125
1126                 break;
1127
1128         case VNC_SESSION_STATE_SERVER_INIT :
1129                 col_set_str(pinfo->cinfo, COL_INFO, "Server framebuffer parameters");
1130
1131                 proto_tree_add_item(tree, hf_vnc_width, tvb, offset, 2,
1132                                     FALSE);
1133                 offset += 2;
1134
1135                 proto_tree_add_item(tree, hf_vnc_height, tvb, offset, 2,
1136                                     FALSE);
1137                 offset += 2;
1138
1139                 proto_tree_add_item(tree, hf_vnc_server_bits_per_pixel,
1140                                     tvb, offset, 1, FALSE);
1141                 vnc_bytes_per_pixel = tvb_get_guint8(tvb, offset)/8;
1142                 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
1143                 offset += 1;
1144
1145                 proto_tree_add_item(tree, hf_vnc_server_depth, tvb, offset,
1146                                     1, FALSE);
1147                 offset += 1;
1148
1149                 proto_tree_add_item(tree, hf_vnc_server_big_endian_flag,
1150                                     tvb, offset, 1, FALSE);
1151                 offset += 1;
1152
1153                 proto_tree_add_item(tree, hf_vnc_server_true_color_flag,
1154                                     tvb, offset, 1, FALSE);
1155                 offset += 1;
1156
1157                 proto_tree_add_item(tree, hf_vnc_server_red_max,
1158                                     tvb, offset, 2, FALSE);
1159                 offset += 2;
1160
1161                 proto_tree_add_item(tree, hf_vnc_server_green_max,
1162                                     tvb, offset, 2, FALSE);
1163                 offset += 2;
1164
1165                 proto_tree_add_item(tree, hf_vnc_server_blue_max,
1166                                     tvb, offset, 2, FALSE);
1167                 offset += 2;
1168
1169                 proto_tree_add_item(tree, hf_vnc_server_red_shift,
1170                                     tvb, offset, 1, FALSE);
1171                 offset += 1;
1172
1173                 proto_tree_add_item(tree, hf_vnc_server_green_shift,
1174                                     tvb, offset, 1, FALSE);
1175                 offset += 1;
1176
1177                 proto_tree_add_item(tree, hf_vnc_server_blue_shift,
1178                                     tvb, offset, 1, FALSE);
1179                 offset += 1;
1180
1181                 proto_tree_add_item(tree, hf_vnc_padding,
1182                                     tvb, offset, 3, FALSE);
1183                 offset += 3; /* Skip over 3 bytes of padding */
1184
1185                 if(tvb_length_remaining(tvb, offset) > 4) {
1186                         /* Sometimes the desktop name & length is skipped */
1187                         proto_tree_add_item(tree, hf_vnc_desktop_name_len,
1188                                             tvb, offset, 4, FALSE);
1189                         desktop_name_len = tvb_get_ntohl(tvb, offset);
1190                         offset += 4;
1191
1192                         proto_tree_add_item(tree, hf_vnc_desktop_name,
1193                                             tvb, offset, desktop_name_len,
1194                                             FALSE);
1195                 }
1196
1197                 if(per_conversation_info->tight_enabled == TRUE)
1198                         per_conversation_info->vnc_next_state =
1199                                 VNC_SESSION_STATE_TIGHT_INTERACTION_CAPS;
1200                 else
1201                         per_conversation_info->vnc_next_state = VNC_SESSION_STATE_NORMAL_TRAFFIC;
1202                 break;
1203
1204         case VNC_SESSION_STATE_TIGHT_INTERACTION_CAPS :
1205                 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC Interaction Capabilities");
1206
1207                 proto_tree_add_item(tree, hf_vnc_num_server_message_types,
1208                                     tvb, offset, 2, FALSE);
1209                 per_conversation_info->num_server_message_types = tvb_get_ntohs(tvb, offset);
1210                 offset += 2;
1211
1212                 proto_tree_add_item(tree, hf_vnc_num_client_message_types,
1213                                     tvb, offset, 2, FALSE);
1214                 per_conversation_info->num_client_message_types = tvb_get_ntohs(tvb, offset);
1215                 offset += 2;
1216
1217                 proto_tree_add_item(tree, hf_vnc_num_encoding_types,
1218                                     tvb, offset, 2, FALSE);
1219                 per_conversation_info->num_encoding_types = tvb_get_ntohs(tvb, offset);
1220                 offset += 2;
1221
1222                 proto_tree_add_item(tree, hf_vnc_padding, tvb, offset, 2,
1223                                     FALSE);
1224                 offset += 2;
1225
1226                 offset = process_tight_capabilities(tree,
1227                                                     hf_vnc_tight_server_message_type,
1228                                                     hf_vnc_tight_server_vendor,
1229                                                     hf_vnc_tight_server_name,
1230                                                     tvb, offset, per_conversation_info->num_server_message_types);
1231                 offset = process_tight_capabilities(tree,
1232                                                     hf_vnc_tight_client_message_type,
1233                                                     hf_vnc_tight_client_vendor,
1234                                                     hf_vnc_tight_client_name,
1235                                                     tvb, offset, per_conversation_info->num_client_message_types);
1236                 process_tight_capabilities(tree,
1237                                                     hf_vnc_tight_encoding_type,
1238                                                     hf_vnc_tight_encoding_vendor,
1239                                                     hf_vnc_tight_encoding_name,
1240                                                     tvb, offset, per_conversation_info->num_encoding_types);
1241
1242                 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_NORMAL_TRAFFIC;
1243                 break;
1244
1245         case VNC_SESSION_STATE_NORMAL_TRAFFIC :
1246                 return FALSE;
1247         }
1248
1249         return TRUE;
1250 }
1251
1252
1253 static void
1254 vnc_client_to_server(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1255                      proto_tree *tree)
1256 {
1257         guint8 message_type;
1258
1259         proto_item *ti=NULL;
1260         proto_tree *vnc_client_message_type_tree;
1261
1262         message_type = tvb_get_guint8(tvb, *offset);
1263
1264         ti = proto_tree_add_item(tree, hf_vnc_client_message_type, tvb,
1265                                  *offset, 1, FALSE);
1266
1267         vnc_client_message_type_tree =
1268                 proto_item_add_subtree(ti, ett_vnc_client_message_type);
1269
1270         *offset += 1;
1271
1272         switch(message_type) {
1273
1274         case VNC_CLIENT_MESSAGE_TYPE_SET_PIXEL_FORMAT :
1275                 vnc_client_set_pixel_format(tvb, pinfo, offset,
1276                                             vnc_client_message_type_tree);
1277                 break;
1278
1279         case VNC_CLIENT_MESSAGE_TYPE_SET_ENCODING :
1280                 vnc_client_set_encodings(tvb, pinfo, offset,
1281                                          vnc_client_message_type_tree);
1282                 break;
1283
1284         case VNC_CLIENT_MESSAGE_TYPE_FRAMEBUF_UPDATE_REQ :
1285                 vnc_client_framebuffer_update_request(tvb, pinfo, offset,
1286                                                       vnc_client_message_type_tree);
1287                 break;
1288
1289         case VNC_CLIENT_MESSAGE_TYPE_KEY_EVENT :
1290                 vnc_client_key_event(tvb, pinfo, offset,
1291                                      vnc_client_message_type_tree);
1292                 break;
1293
1294         case VNC_CLIENT_MESSAGE_TYPE_POINTER_EVENT:
1295                 vnc_client_pointer_event(tvb, pinfo, offset,
1296                                          vnc_client_message_type_tree);
1297                 break;
1298
1299         case VNC_CLIENT_MESSAGE_TYPE_CLIENT_CUT_TEXT :
1300                 vnc_client_cut_text(tvb, pinfo, offset,
1301                                     vnc_client_message_type_tree);
1302                 break;
1303
1304         default :
1305                 col_append_fstr(pinfo->cinfo, COL_INFO,
1306                                 "Unknown client message type (%u)",
1307                                 message_type);
1308                 break;
1309         }
1310 }
1311
1312 static void
1313 vnc_server_to_client(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1314                      proto_tree *tree)
1315 {
1316         gint start_offset;
1317         guint8 message_type;
1318         gint bytes_needed = 0, length_remaining;
1319
1320         proto_item *ti=NULL;
1321         proto_tree *vnc_server_message_type_tree;
1322
1323         start_offset = *offset;
1324
1325         message_type = tvb_get_guint8(tvb, *offset);
1326
1327         ti = proto_tree_add_item(tree, hf_vnc_server_message_type, tvb,
1328                                  *offset, 1, FALSE);
1329         vnc_server_message_type_tree =
1330                 proto_item_add_subtree(ti, ett_vnc_server_message_type);
1331
1332         *offset += 1;
1333
1334         switch(message_type) {
1335
1336         case VNC_SERVER_MESSAGE_TYPE_FRAMEBUFFER_UPDATE :
1337                 bytes_needed =
1338                         vnc_server_framebuffer_update(tvb, pinfo, offset,
1339                                                       vnc_server_message_type_tree);
1340                 break;
1341
1342         case VNC_SERVER_MESSAGE_TYPE_SET_COLORMAP_ENTRIES :
1343                 bytes_needed = vnc_server_set_colormap_entries(tvb, pinfo, offset, vnc_server_message_type_tree);
1344                 break;
1345
1346         case VNC_SERVER_MESSAGE_TYPE_RING_BELL :
1347                 vnc_server_ring_bell(tvb, pinfo, offset,
1348                                      vnc_server_message_type_tree);
1349                 break;
1350
1351         case VNC_SERVER_MESSAGE_TYPE_CUT_TEXT :
1352                 bytes_needed = vnc_server_cut_text(tvb, pinfo, offset,
1353                                                    vnc_server_message_type_tree);
1354                 break;
1355
1356         default :
1357                 col_append_str(pinfo->cinfo, COL_INFO,
1358                                        "Unknown server message type");
1359                 break;
1360         }
1361
1362         if(bytes_needed > 0 && vnc_preference_desegment &&
1363            pinfo->can_desegment) {
1364                 length_remaining = tvb_length_remaining(tvb, *offset);
1365
1366                 pinfo->desegment_offset = start_offset;
1367                 pinfo->desegment_len = bytes_needed - length_remaining;
1368                 return;
1369         }
1370 }
1371
1372
1373 static void
1374 vnc_client_set_pixel_format(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1375                             proto_tree *tree)
1376 {
1377         col_set_str(pinfo->cinfo, COL_INFO, "Client set pixel format");
1378
1379         proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset,
1380                             3, FALSE);
1381         *offset += 3; /* Skip over 3 bytes of padding */
1382
1383         proto_tree_add_item(tree, hf_vnc_client_bits_per_pixel, tvb, *offset,
1384                             1, FALSE);
1385         vnc_bytes_per_pixel = tvb_get_guint8(tvb, *offset)/8;
1386         vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
1387         *offset += 1;
1388
1389         proto_tree_add_item(tree, hf_vnc_client_depth, tvb, *offset,
1390                             1, FALSE);
1391         vnc_depth = tvb_get_guint8(tvb, *offset);
1392         vnc_set_depth(pinfo, vnc_depth);
1393         *offset += 1;
1394
1395         proto_tree_add_item(tree, hf_vnc_client_big_endian_flag, tvb, *offset,
1396                             1, FALSE);
1397         *offset += 1;
1398
1399         proto_tree_add_item(tree, hf_vnc_client_true_color_flag, tvb, *offset,
1400                             1, FALSE);
1401         *offset += 1;
1402
1403         proto_tree_add_item(tree, hf_vnc_client_red_max, tvb, *offset,
1404                             2, FALSE);
1405         *offset += 2;
1406
1407         proto_tree_add_item(tree, hf_vnc_client_green_max, tvb, *offset,
1408                             2, FALSE);
1409         *offset += 2;
1410
1411         proto_tree_add_item(tree, hf_vnc_client_blue_max, tvb, *offset,
1412                             2, FALSE);
1413         *offset += 2;
1414
1415         proto_tree_add_item(tree, hf_vnc_client_red_shift, tvb, *offset,
1416                             1, FALSE);
1417         *offset += 1;
1418
1419         proto_tree_add_item(tree, hf_vnc_client_green_shift, tvb, *offset,
1420                             1, FALSE);
1421         *offset += 1;
1422
1423         proto_tree_add_item(tree, hf_vnc_client_blue_shift, tvb, *offset,
1424                             1, FALSE);
1425         *offset += 1;
1426
1427         proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 3, FALSE);
1428         *offset += 3; /* Skip over 3 bytes of padding */
1429 }
1430
1431
1432 static void
1433 vnc_client_set_encodings(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1434                          proto_tree *tree)
1435 {
1436         guint16 number_of_encodings;
1437         guint counter;
1438         vnc_packet_t *per_packet_info;
1439
1440         per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
1441         /* Our calling function should have set the packet's proto data already */
1442         DISSECTOR_ASSERT(per_packet_info != NULL);
1443
1444         col_set_str(pinfo->cinfo, COL_INFO, "Client set encodings");
1445
1446         proto_tree_add_item(tree, hf_vnc_padding,
1447                             tvb, *offset, 1, FALSE);
1448         *offset += 1; /* Skip over 1 byte of padding */
1449
1450         number_of_encodings = tvb_get_ntohs(tvb, *offset);
1451
1452         proto_tree_add_text(tree, tvb, *offset, 2,
1453                             "Number of encodings: %d", number_of_encodings);
1454         *offset += 2;
1455
1456         per_packet_info->preferred_encoding = -1;
1457
1458         for(counter = 1; counter <= number_of_encodings; counter++) {
1459                 proto_tree_add_item(tree,
1460                                     hf_vnc_client_set_encodings_encoding_type,
1461                                     tvb, *offset, 4, FALSE);
1462
1463                 /* Remember the first real encoding as the preferred encoding,
1464                  * per xserver/hw/vnc/rfbserver.c:rfbProcessClientNormalMessage().
1465                  * Otherwise, use RAW as the preferred encoding.
1466                  */
1467                 if (per_packet_info->preferred_encoding == -1) {
1468                         int encoding;
1469
1470                         encoding = tvb_get_ntohl(tvb, *offset);
1471
1472                         switch(encoding) {
1473                         case VNC_ENCODING_TYPE_RAW:
1474                         case VNC_ENCODING_TYPE_RRE:
1475                         case VNC_ENCODING_TYPE_CORRE:
1476                         case VNC_ENCODING_TYPE_HEXTILE:
1477                         case VNC_ENCODING_TYPE_ZLIB:
1478                         case VNC_ENCODING_TYPE_TIGHT:
1479                                 per_packet_info->preferred_encoding = encoding;
1480                                 break;
1481                         }
1482                 }
1483
1484                 *offset += 4;
1485         }
1486
1487         if (per_packet_info->preferred_encoding == -1)
1488                 per_packet_info->preferred_encoding = VNC_ENCODING_TYPE_RAW;
1489 }
1490
1491
1492 static void
1493 vnc_client_framebuffer_update_request(tvbuff_t *tvb, packet_info *pinfo,
1494                                       gint *offset, proto_tree *tree)
1495 {
1496         col_set_str(pinfo->cinfo, COL_INFO, "Client framebuffer update request");
1497
1498         proto_tree_add_item(tree, hf_vnc_update_req_incremental,
1499                             tvb, *offset, 1, FALSE);
1500         *offset += 1;
1501
1502         proto_tree_add_item(tree, hf_vnc_update_req_x_pos,
1503                             tvb, *offset, 2, FALSE);
1504         *offset += 2;
1505
1506         proto_tree_add_item(tree, hf_vnc_update_req_y_pos,
1507                             tvb, *offset, 2, FALSE);
1508         *offset += 2;
1509
1510         proto_tree_add_item(tree, hf_vnc_update_req_width, tvb,
1511                             *offset, 2, FALSE);
1512         *offset += 2;
1513
1514         proto_tree_add_item(tree, hf_vnc_update_req_height, tvb,
1515                             *offset, 2, FALSE);
1516         *offset += 2;
1517 }
1518
1519
1520 static void
1521 vnc_client_key_event(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1522                      proto_tree *tree)
1523 {
1524         col_set_str(pinfo->cinfo, COL_INFO, "Client key event");
1525
1526         proto_tree_add_item(tree, hf_vnc_key_down, tvb, *offset, 1, FALSE);
1527         *offset += 1;
1528
1529         proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 2, FALSE);
1530         *offset += 2; /* Skip over 2 bytes of padding */
1531
1532         proto_tree_add_item(tree, hf_vnc_key, tvb, *offset, 4, FALSE);
1533         *offset += 4;
1534 }
1535
1536
1537 static void
1538 vnc_client_pointer_event(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1539                          proto_tree *tree)
1540 {
1541         col_set_str(pinfo->cinfo, COL_INFO, "Client pointer event");
1542
1543         proto_tree_add_item(tree, hf_vnc_button_1_pos, tvb, *offset, 1, FALSE);
1544         proto_tree_add_item(tree, hf_vnc_button_2_pos, tvb, *offset, 1, FALSE);
1545         proto_tree_add_item(tree, hf_vnc_button_3_pos, tvb, *offset, 1, FALSE);
1546         proto_tree_add_item(tree, hf_vnc_button_4_pos, tvb, *offset, 1, FALSE);
1547         proto_tree_add_item(tree, hf_vnc_button_5_pos, tvb, *offset, 1, FALSE);
1548         proto_tree_add_item(tree, hf_vnc_button_6_pos, tvb, *offset, 1, FALSE);
1549         proto_tree_add_item(tree, hf_vnc_button_7_pos, tvb, *offset, 1, FALSE);
1550         proto_tree_add_item(tree, hf_vnc_button_8_pos, tvb, *offset, 1, FALSE);
1551         *offset += 1;
1552
1553         proto_tree_add_item(tree, hf_vnc_pointer_x_pos, tvb, *offset, 2, FALSE);
1554         *offset += 2;
1555
1556         proto_tree_add_item(tree, hf_vnc_pointer_y_pos, tvb, *offset, 2, FALSE);
1557         *offset += 2;
1558 }
1559
1560
1561 static void
1562 vnc_client_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1563                     proto_tree *tree)
1564 {
1565         guint32 text_len;
1566
1567         col_set_str(pinfo->cinfo, COL_INFO, "Client cut text");
1568
1569         proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 3, FALSE);
1570         *offset += 3; /* Skip over 3 bytes of padding */
1571
1572         text_len = tvb_get_ntohl(tvb, *offset);
1573         proto_tree_add_item(tree, hf_vnc_client_cut_text_len, tvb, *offset, 4,
1574                             FALSE);
1575         *offset += 4;
1576
1577         proto_tree_add_item(tree, hf_vnc_client_cut_text, tvb, *offset,
1578                             text_len, FALSE);
1579         *offset += text_len;
1580
1581 }
1582
1583
1584 static guint
1585 vnc_server_framebuffer_update(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1586                               proto_tree *tree)
1587 {
1588         gint i;
1589         guint16 num_rects, width, height;
1590         guint bytes_needed = 0;
1591         guint32 encoding_type;
1592         proto_item *ti, *ti_x, *ti_y, *ti_width, *ti_height;
1593         proto_tree *vnc_rect_tree, *vnc_encoding_type_tree;
1594
1595         col_set_str(pinfo->cinfo, COL_INFO, "Server framebuffer update");
1596
1597         proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 1, FALSE);
1598         *offset += 1;
1599
1600         num_rects = tvb_get_ntohs(tvb, *offset);
1601         ti = proto_tree_add_text(tree, tvb, *offset, 2, "Number of rectangles: %d",
1602                                  num_rects);
1603
1604         if (num_rects > 5000) {
1605                 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1606                                        "Too many rectangles, aborting dissection");
1607                 return(0);
1608         }
1609
1610         *offset += 2;
1611
1612         /*  We know we need (at least) all these bytes, so ask for them now
1613          *  (instead of 12 at a time...).
1614          */
1615         VNC_BYTES_NEEDED((guint)12*num_rects);
1616
1617         for(i = 1; i <= num_rects; i++) {
1618
1619                 ti = proto_tree_add_text(tree, tvb, *offset, 12,
1620                                          "Rectangle #%d", i);
1621
1622                 vnc_rect_tree =
1623                         proto_item_add_subtree(ti, ett_vnc_rect);
1624
1625                 ti_x = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_x_pos,
1626                                            tvb, *offset, 2, FALSE);
1627                 *offset += 2;
1628
1629                 ti_y = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_y_pos,
1630                                            tvb, *offset, 2, FALSE);
1631                 *offset += 2;
1632
1633                 ti_width = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_width,
1634                                                tvb, *offset, 2, FALSE);
1635                 width = tvb_get_ntohs(tvb, *offset);
1636                 *offset += 2;
1637
1638                 ti_height = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_height,
1639                                                 tvb, *offset, 2, FALSE);
1640                 height = tvb_get_ntohs(tvb, *offset);
1641                 *offset += 2;
1642
1643                 ti = proto_tree_add_item(vnc_rect_tree,
1644                                          hf_vnc_fb_update_encoding_type,
1645                                          tvb, *offset, 4, FALSE);
1646
1647                 encoding_type = tvb_get_ntohl(tvb, *offset);
1648                 *offset += 4;
1649
1650                 if (encoding_type == VNC_ENCODING_TYPE_LAST_RECT)
1651                         break; /* exit the loop */
1652
1653                 vnc_encoding_type_tree =
1654                         proto_item_add_subtree(ti, ett_vnc_encoding_type);
1655
1656                 switch(encoding_type) {
1657
1658                 case VNC_ENCODING_TYPE_RAW:
1659                         bytes_needed = vnc_raw_encoding(tvb, pinfo, offset,
1660                                                         vnc_encoding_type_tree,
1661                                                         width, height);
1662                         break;
1663
1664                 case VNC_ENCODING_TYPE_COPY_RECT:
1665                         bytes_needed =
1666                                 vnc_copyrect_encoding(tvb, pinfo, offset,
1667                                                       vnc_encoding_type_tree,
1668                                                       width, height);
1669                         break;
1670
1671                 case VNC_ENCODING_TYPE_RRE:
1672                         bytes_needed =
1673                                 vnc_rre_encoding(tvb, pinfo, offset,
1674                                                  vnc_encoding_type_tree,
1675                                                  width, height);
1676                         break;
1677
1678                 case VNC_ENCODING_TYPE_HEXTILE:
1679                         bytes_needed =
1680                                 vnc_hextile_encoding(tvb, pinfo, offset,
1681                                                      vnc_encoding_type_tree,
1682                                                      width, height);
1683                         break;
1684
1685                 case VNC_ENCODING_TYPE_RLE:
1686                         bytes_needed =
1687                                 vnc_zrle_encoding(tvb, pinfo, offset,
1688                                                   vnc_encoding_type_tree,
1689                                                   width, height);
1690                         break;
1691
1692                 case VNC_ENCODING_TYPE_TIGHT:
1693                         bytes_needed =
1694                                 vnc_tight_encoding(tvb, pinfo, offset,
1695                                                    vnc_encoding_type_tree,
1696                                                    width, height);
1697                         break;
1698
1699                 case VNC_ENCODING_TYPE_RICH_CURSOR:
1700                 case VNC_ENCODING_TYPE_X_CURSOR:
1701                         proto_item_append_text (ti_x,      " (hotspot X)");
1702                         proto_item_append_text (ti_y,      " (hotspot Y)");
1703                         proto_item_append_text (ti_width,  " (cursor width)");
1704                         proto_item_append_text (ti_height, " (cursor height)");
1705
1706                         if (encoding_type == VNC_ENCODING_TYPE_RICH_CURSOR)
1707                                 bytes_needed = vnc_rich_cursor_encoding(tvb, pinfo, offset, vnc_encoding_type_tree, width, height);
1708                         else
1709                                 bytes_needed = vnc_x_cursor_encoding(tvb, pinfo, offset, vnc_encoding_type_tree, width, height);
1710
1711                         break;
1712
1713                 case VNC_ENCODING_TYPE_POINTER_POS:
1714                         proto_item_append_text (ti_x,      " (pointer X)");
1715                         proto_item_append_text (ti_y,      " (pointer Y)");
1716                         proto_item_append_text (ti_width,  " (unused)");
1717                         proto_item_append_text (ti_height, " (unused)");
1718                         bytes_needed = 0;
1719                         break;
1720
1721                 case VNC_ENCODING_TYPE_DESKTOP_SIZE:
1722
1723                         /* There is no payload for this message type */
1724
1725                         bytes_needed = 0;
1726                         break;
1727
1728                 case VNC_ENCODING_TYPE_EXTENDED_DESK_SIZE :
1729                         bytes_needed = vnc_extended_desktop_size(tvb, offset, vnc_encoding_type_tree);
1730                         break;
1731
1732                 }
1733
1734                 /* Check if the routines above requested more bytes to
1735                  * be desegmented. */
1736                 if(bytes_needed > 0)
1737                         return bytes_needed;
1738         }
1739
1740         return 0;
1741 }
1742
1743 static guint32
1744 vnc_extended_desktop_size(tvbuff_t *tvb, gint *offset, proto_tree *tree)
1745 {
1746
1747         guint8 i, num_of_screens;
1748         proto_item *ti;
1749         proto_tree *screen_tree;
1750         
1751         num_of_screens = tvb_get_guint8(tvb, *offset);
1752         proto_tree_add_text(tree, tvb, *offset, 1, "Number of screens: %d", num_of_screens);
1753         *offset += 1;
1754         proto_tree_add_text(tree, tvb, *offset, 3, "Padding");
1755         VNC_BYTES_NEEDED((guint32)(3 + (num_of_screens * 16)));
1756         *offset += 3;
1757         for(i = 1; i <= num_of_screens; i++) {
1758                 ti = proto_tree_add_text(tree, tvb, *offset, 16, "Screen #%u", i);
1759                 screen_tree = proto_item_add_subtree(ti, ett_vnc_desktop_screen);
1760
1761                 proto_tree_add_item(screen_tree, hf_vnc_desktop_screen_id, tvb, *offset, 4, FALSE);
1762                 *offset += 4;
1763                 proto_tree_add_item(screen_tree, hf_vnc_desktop_screen_x, tvb, *offset, 2, FALSE);
1764                 *offset += 2;
1765                 proto_tree_add_item(screen_tree, hf_vnc_desktop_screen_y, tvb, *offset, 2, FALSE);
1766                 *offset += 2;
1767                 proto_tree_add_item(screen_tree, hf_vnc_desktop_screen_width, tvb, *offset, 2, FALSE);
1768                 *offset += 2;
1769                 proto_tree_add_item(screen_tree, hf_vnc_desktop_screen_height, tvb, *offset, 2, FALSE);
1770                 *offset += 2;
1771                 proto_tree_add_item(screen_tree, hf_vnc_desktop_screen_flags, tvb, *offset, 4, FALSE);
1772                 *offset += 4;
1773         }
1774         
1775         return 0;
1776 }
1777
1778 static guint
1779 vnc_raw_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1780                  proto_tree *tree, const guint16 width, const guint16 height)
1781 {
1782         guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1783         guint length;
1784
1785         length = width * height * bytes_per_pixel;
1786         VNC_BYTES_NEEDED(length);
1787
1788         proto_tree_add_item(tree, hf_vnc_raw_pixel_data, tvb, *offset,
1789                             length, FALSE);
1790         *offset += length;
1791
1792         return 0; /* bytes_needed */
1793 }
1794
1795
1796 static guint
1797 vnc_copyrect_encoding(tvbuff_t *tvb, packet_info *pinfo _U_, gint *offset,
1798                       proto_tree *tree, const guint16 width _U_, const guint16 height _U_)
1799 {
1800         proto_tree_add_item(tree, hf_vnc_copyrect_src_x_pos, tvb, *offset,
1801                             2, FALSE);
1802         *offset += 2;
1803
1804         proto_tree_add_item(tree, hf_vnc_copyrect_src_y_pos, tvb, *offset,
1805                             2, FALSE);
1806         *offset += 2;
1807
1808         return 0; /* bytes_needed */
1809 }
1810
1811
1812 static guint
1813 vnc_rre_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1814                  proto_tree *tree, const guint16 width _U_, const guint16 height _U_)
1815 {
1816         guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1817         guint32 num_subrects, i;
1818         guint bytes_needed;
1819         proto_item *ti;
1820         proto_tree *subrect_tree;
1821
1822         VNC_BYTES_NEEDED(4);
1823         ti = proto_tree_add_item(tree, hf_vnc_rre_num_subrects, tvb, *offset,
1824                                  4, FALSE);
1825         num_subrects = tvb_get_ntohl(tvb, *offset);
1826         *offset += 4;
1827
1828         if (num_subrects > 10000) {
1829                 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
1830                                        "Too many sub-rectangles, aborting dissection");
1831                 return(0);
1832         }
1833
1834         *offset += 2;
1835         VNC_BYTES_NEEDED(bytes_per_pixel);
1836         proto_tree_add_item(tree, hf_vnc_rre_bg_pixel, tvb, *offset,
1837                             bytes_per_pixel, FALSE);
1838         *offset += bytes_per_pixel;
1839
1840         /*  We know we need (at least) all these bytes, so ask for them now
1841          *  (instead of a few at a time...).
1842          */
1843         bytes_needed = bytes_per_pixel + 8;
1844         VNC_BYTES_NEEDED(bytes_needed * num_subrects);
1845         for(i = 1; i <= num_subrects; i++) {
1846
1847                 ti = proto_tree_add_text(tree, tvb, *offset, bytes_per_pixel +
1848                                          8, "Subrectangle #%d", i);
1849                 subrect_tree =
1850                         proto_item_add_subtree(ti, ett_vnc_rre_subrect);
1851
1852                 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_pixel,
1853                                     tvb, *offset, bytes_per_pixel, FALSE);
1854                 *offset += bytes_per_pixel;
1855
1856                 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_x_pos,
1857                                     tvb, *offset, 2, FALSE);
1858                 *offset += 2;
1859
1860                 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_y_pos,
1861                                     tvb, *offset, 2, FALSE);
1862                 *offset += 2;
1863
1864                 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_width,
1865                                     tvb, *offset, 2, FALSE);
1866                 *offset += 2;
1867
1868                 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_height,
1869                                     tvb, *offset, 2, FALSE);
1870                 *offset += 2;
1871         }
1872
1873         return 0; /* bytes_needed */
1874 }
1875
1876
1877 static guint
1878 vnc_hextile_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1879                      proto_tree *tree, const guint16 width, const guint16 height)
1880 {
1881         guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1882         guint8 i, subencoding_mask, num_subrects, subrect_len;
1883         guint length, bytes_needed;
1884         proto_tree *subencoding_mask_tree, *subrect_tree, *num_subrects_tree;
1885         proto_item *ti;
1886
1887         VNC_BYTES_NEEDED(1);
1888         ti = proto_tree_add_item(tree, hf_vnc_hextile_subencoding_mask, tvb,
1889                                  *offset, 1, FALSE);
1890         subencoding_mask = tvb_get_guint8(tvb, *offset);
1891
1892         subencoding_mask_tree =
1893                 proto_item_add_subtree(ti, ett_vnc_hextile_subencoding_mask);
1894
1895         proto_tree_add_item(subencoding_mask_tree,
1896                             hf_vnc_hextile_raw, tvb, *offset, 1,
1897                             FALSE);
1898         proto_tree_add_item(subencoding_mask_tree,
1899                             hf_vnc_hextile_bg, tvb, *offset, 1,
1900                             FALSE);
1901         proto_tree_add_item(subencoding_mask_tree,
1902                             hf_vnc_hextile_fg, tvb, *offset, 1,
1903                             FALSE);
1904         proto_tree_add_item(subencoding_mask_tree,
1905                             hf_vnc_hextile_anysubrects, tvb, *offset, 1,
1906                             FALSE);
1907         proto_tree_add_item(subencoding_mask_tree,
1908                             hf_vnc_hextile_subrectscolored, tvb, *offset, 1,
1909                             FALSE);
1910         *offset += 1;
1911
1912         if(subencoding_mask & 0x1) { /* Raw */
1913                 length = width * height * bytes_per_pixel;
1914
1915                 VNC_BYTES_NEEDED(length);
1916
1917                 proto_tree_add_item(tree, hf_vnc_hextile_raw_value, tvb,
1918                                     *offset, length, FALSE);
1919                 *offset += length;
1920         } else {
1921                 if(subencoding_mask & 0x2) { /* Background Specified */
1922                         VNC_BYTES_NEEDED(bytes_per_pixel);
1923                         proto_tree_add_item(tree, hf_vnc_hextile_bg_value,
1924                                             tvb, *offset, bytes_per_pixel,
1925                                             FALSE);
1926                         *offset += bytes_per_pixel;
1927                 }
1928
1929                 if(subencoding_mask & 0x4) { /* Foreground Specified */
1930                         VNC_BYTES_NEEDED(bytes_per_pixel);
1931                         proto_tree_add_item(tree, hf_vnc_hextile_fg_value,
1932                                             tvb, *offset, bytes_per_pixel,
1933                                             FALSE);
1934                         *offset += bytes_per_pixel;
1935                 }
1936
1937                 if(subencoding_mask & 0x8) { /* Any Subrects */
1938                         VNC_BYTES_NEEDED(3); /* 1 byte for number of subrects field, +2 at least for 1 subrect */
1939                         ti = proto_tree_add_item(tree,
1940                                                  hf_vnc_hextile_num_subrects,
1941                                                  tvb, *offset, 1,
1942                                                  FALSE);
1943                         num_subrects = tvb_get_guint8(tvb, *offset);
1944                         *offset += 1;
1945
1946                         if(subencoding_mask & 0x16)
1947                                 subrect_len = bytes_per_pixel + 2;
1948                         else
1949                                 subrect_len = 2;
1950                         bytes_needed = subrect_len * num_subrects;
1951                         VNC_BYTES_NEEDED(bytes_needed);
1952
1953                         num_subrects_tree =
1954                                 proto_item_add_subtree(ti, ett_vnc_hextile_num_subrects);
1955
1956                         for(i = 1; i <= num_subrects; i++) {
1957                                 ti = proto_tree_add_text(num_subrects_tree, tvb,
1958                                                          *offset, subrect_len,
1959                                                          "Subrectangle #%d", i);
1960
1961                                 subrect_tree =
1962                                         proto_item_add_subtree(ti, ett_vnc_hextile_subrect);
1963
1964                                 if(subencoding_mask & 0x16) {
1965                                         /* Subrects Colored */
1966                                         proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_pixel_value, tvb, *offset, bytes_per_pixel, FALSE);
1967
1968                                         *offset += bytes_per_pixel;
1969                                 }
1970
1971                                 proto_tree_add_item(subrect_tree,
1972                                                     hf_vnc_hextile_subrect_x_pos, tvb, *offset, 1, FALSE);
1973
1974                                 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_y_pos, tvb, *offset, 1, FALSE);
1975
1976                                 *offset += 1;
1977
1978                                 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_width, tvb, *offset, 1, FALSE);
1979
1980                                 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_height, tvb, *offset, 1, FALSE);
1981
1982                                 *offset += 1;
1983                         }
1984                 }
1985         }
1986         return 0; /* bytes_needed */
1987 }
1988
1989 #ifdef HAVE_LIBZ
1990 static guint
1991 vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1992                   proto_tree *tree, const guint16 width, const guint16 height)
1993 #else
1994 static guint
1995 vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo _U_, gint *offset,
1996                   proto_tree *tree, const guint16 width _U_, const guint16 height _U_)
1997 #endif
1998 {
1999         guint32 data_len;
2000 #ifdef HAVE_LIBZ
2001         guint8 palette_size;
2002         guint8 bytes_per_cpixel = vnc_get_bytes_per_pixel(pinfo);
2003         gint uncomp_offset = 0;
2004         guint length;
2005         gint subencoding_type;
2006         tvbuff_t *uncomp_tvb = NULL;
2007         proto_tree *zrle_subencoding_tree;
2008         proto_item *ti;
2009 #endif
2010
2011         VNC_BYTES_NEEDED(4);
2012         proto_tree_add_item(tree, hf_vnc_zrle_len, tvb, *offset,
2013                             4, FALSE);
2014         data_len = tvb_get_ntohl(tvb, *offset);
2015
2016         *offset += 4;
2017
2018         VNC_BYTES_NEEDED(data_len);
2019
2020         proto_tree_add_item(tree, hf_vnc_zrle_data, tvb, *offset,
2021                             data_len, FALSE);
2022
2023 #ifdef HAVE_LIBZ
2024         uncomp_tvb = tvb_child_uncompress(tvb, tvb, *offset, data_len);
2025
2026         if(uncomp_tvb != NULL) {
2027                 add_new_data_source(pinfo, uncomp_tvb,
2028                                     "Uncompressed ZRLE data");
2029
2030                 ti = proto_tree_add_item(tree, hf_vnc_zrle_subencoding,
2031                                          uncomp_tvb, uncomp_offset, 1, FALSE);
2032                 zrle_subencoding_tree =
2033                         proto_item_add_subtree(ti, ett_vnc_zrle_subencoding);
2034
2035                 proto_tree_add_item(zrle_subencoding_tree, hf_vnc_zrle_rle,
2036                                     uncomp_tvb, uncomp_offset, 1, FALSE);
2037
2038                 proto_tree_add_item(zrle_subencoding_tree,
2039                                     hf_vnc_zrle_palette_size, uncomp_tvb,
2040                                     uncomp_offset, 1, FALSE);
2041
2042                 subencoding_type = tvb_get_guint8(uncomp_tvb, uncomp_offset);
2043                 palette_size = subencoding_type & 0x7F;
2044
2045                 uncomp_offset += 1;
2046
2047                 if(subencoding_type == 0) { /* Raw */
2048                         length = width * height * bytes_per_cpixel;
2049                         VNC_BYTES_NEEDED(length);
2050
2051                         /* XXX - not working yet! */
2052
2053                         proto_tree_add_item(zrle_subencoding_tree,
2054                                             hf_vnc_zrle_raw, uncomp_tvb,
2055                                             uncomp_offset, length, FALSE);
2056
2057                 } else if(subencoding_type >= 130 && subencoding_type <= 255) {
2058                         length = palette_size * bytes_per_cpixel;
2059                         VNC_BYTES_NEEDED(length);
2060
2061                         proto_tree_add_item(zrle_subencoding_tree,
2062                                             hf_vnc_zrle_palette, uncomp_tvb,
2063                                             uncomp_offset, length, FALSE);
2064
2065                         /* XXX - Not complete! */
2066                 }
2067
2068         } else {
2069                 proto_tree_add_text(tree, tvb, *offset, data_len,
2070                                     "Decompression of ZRLE data failed");
2071         }
2072 #endif /* HAVE_LIBZ */
2073
2074         *offset += data_len;
2075
2076         return 0; /* bytes_needed */
2077 }
2078
2079
2080 static guint
2081 read_compact_len(tvbuff_t *tvb, gint *offset, gint *length, gint *value_length)
2082 {
2083         gint b;
2084
2085         VNC_BYTES_NEEDED(1);
2086
2087         *value_length = 0;
2088
2089         b = tvb_get_guint8(tvb, *offset);
2090         *offset += 1;
2091         *value_length += 1;
2092
2093         *length = b & 0x7f;
2094         if ((b & 0x80) != 0) {
2095                 VNC_BYTES_NEEDED(1);
2096
2097                 b = tvb_get_guint8(tvb, *offset);
2098                 *offset += 1;
2099                 *value_length += 1;
2100
2101                 *length |= (b & 0x7f) << 7;
2102
2103                 if ((b & 0x80) != 0) {
2104                         VNC_BYTES_NEEDED (1);
2105
2106                         b = tvb_get_guint8(tvb, *offset);
2107                         *offset += 1;
2108                         *value_length += 1;
2109
2110                         *length |= (b & 0xff) << 14;
2111                 }
2112         }
2113
2114         return 0;
2115 }
2116
2117
2118 static guint
2119 process_compact_length_and_image_data(tvbuff_t *tvb, gint *offset, proto_tree *tree)
2120 {
2121         guint bytes_needed;
2122         guint length, value_length;
2123
2124         bytes_needed = read_compact_len (tvb, offset, &length, &value_length);
2125         if (bytes_needed != 0)
2126                 return bytes_needed;
2127
2128         proto_tree_add_uint(tree, hf_vnc_tight_image_len, tvb, *offset - value_length, value_length, length);
2129
2130         VNC_BYTES_NEEDED(length);
2131         proto_tree_add_item(tree, hf_vnc_tight_image_data, tvb, *offset, length, FALSE);
2132         *offset += length;
2133
2134         return 0; /* bytes_needed */
2135 }
2136
2137
2138 static guint
2139 process_tight_rect_filter_palette(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2140                                   proto_tree *tree, gint *bits_per_pixel)
2141 {
2142         vnc_packet_t *per_packet_info;
2143         gint num_colors;
2144         guint palette_bytes;
2145
2146         /* See TightVNC's vnc_unixsrc/vncviewer/tight.c:InitFilterPaletteBPP() */
2147
2148         per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
2149         /* Our calling function should have set the packet's proto data already */
2150         DISSECTOR_ASSERT(per_packet_info != NULL);
2151
2152         VNC_BYTES_NEEDED(1);
2153         proto_tree_add_item(tree, hf_vnc_tight_palette_num_colors, tvb, *offset, 1, FALSE);
2154         num_colors = tvb_get_guint8(tvb, *offset);
2155         *offset += 1;
2156
2157         num_colors++;
2158         if (num_colors < 2)
2159                 return 0;
2160
2161         if (per_packet_info->depth == 24)
2162                 palette_bytes = num_colors * 3;
2163         else
2164                 palette_bytes = num_colors * per_packet_info->depth / 8;
2165
2166         VNC_BYTES_NEEDED(palette_bytes);
2167         proto_tree_add_item(tree, hf_vnc_tight_palette_data, tvb, *offset, palette_bytes, FALSE);
2168         *offset += palette_bytes;
2169
2170         /* This is the number of bits per pixel *in the image data*, not the actual client depth */
2171         if (num_colors == 2)
2172                 *bits_per_pixel = 1;
2173         else
2174                 *bits_per_pixel = 8;
2175
2176         return 0;
2177 }
2178
2179 static guint
2180 vnc_tight_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2181                    proto_tree *tree, const guint16 width _U_, const guint16 height _U_)
2182 {
2183         vnc_packet_t *per_packet_info;
2184         guint8 comp_ctl;
2185         proto_item *compression_type_ti;
2186         gint bit_offset;
2187         gint bytes_needed = -1;
2188
2189         per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
2190         /* Our calling function should have set the packet's proto data already */
2191         DISSECTOR_ASSERT(per_packet_info != NULL);
2192
2193         /* See xserver/hw/vnc/rfbproto.h and grep for "Tight Encoding." for the following layout */
2194
2195         VNC_BYTES_NEEDED(1);
2196
2197         /* least significant bits 0-3 are "reset compression stream N" */
2198         bit_offset = *offset * 8;
2199         proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream0, tvb, bit_offset + 7, 1, FALSE);
2200         proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream1, tvb, bit_offset + 6, 1, FALSE);
2201         proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream2, tvb, bit_offset + 5, 1, FALSE);
2202         proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream3, tvb, bit_offset + 4, 1, FALSE);
2203
2204         /* most significant bits 4-7 are "compression type" */
2205         compression_type_ti = proto_tree_add_bits_item(tree, hf_vnc_tight_rect_type, tvb, bit_offset + 0, 4, FALSE);
2206
2207         comp_ctl = tvb_get_guint8(tvb, *offset);
2208         *offset += 1;
2209
2210         comp_ctl >>= 4; /* skip over the "reset compression" bits from above */
2211
2212         /* compression format */
2213
2214         if (comp_ctl == TIGHT_RECT_FILL) {
2215                 /* "fill" encoding (solid rectangle) */
2216
2217                 proto_item_append_text(compression_type_ti, " (fill encoding - solid rectangle)");
2218
2219                 if (per_packet_info->depth == 24) {
2220                         VNC_BYTES_NEEDED(3);
2221                         proto_tree_add_item(tree, hf_vnc_tight_fill_color, tvb, *offset, 3, FALSE);
2222                         *offset += 3;
2223                 } else {
2224                         VNC_BYTES_NEEDED(per_packet_info->bytes_per_pixel);
2225                         proto_tree_add_item(tree, hf_vnc_tight_fill_color, tvb, *offset, per_packet_info->bytes_per_pixel, FALSE);
2226                         *offset += per_packet_info->bytes_per_pixel;
2227                 }
2228
2229                 bytes_needed = 0;
2230         } else if (comp_ctl == TIGHT_RECT_JPEG) {
2231                 /* jpeg encoding */
2232
2233                 proto_item_append_text(compression_type_ti, " (JPEG encoding)");
2234                 bytes_needed = process_compact_length_and_image_data(tvb, offset, tree);
2235                 if (bytes_needed != 0)
2236                         return bytes_needed;
2237         } else if (comp_ctl > TIGHT_RECT_MAX_VALUE) {
2238                 /* invalid encoding */
2239
2240                 expert_add_info_format(pinfo, compression_type_ti, PI_MALFORMED, PI_ERROR,
2241                                        "Invalid encoding");
2242         } else {
2243                 guint row_size;
2244                 gint bits_per_pixel;
2245
2246                 /* basic encoding */
2247
2248                 proto_item_append_text(compression_type_ti, " (basic encoding)");
2249
2250                 proto_tree_add_bits_item(tree, hf_vnc_tight_filter_flag, tvb, bit_offset + 1, 1, FALSE);
2251
2252                 bits_per_pixel = per_packet_info->depth;
2253
2254                 if ((comp_ctl & TIGHT_RECT_EXPLICIT_FILTER_FLAG) != 0) {
2255                         guint8 filter_id;
2256
2257                         /* explicit filter */
2258
2259                         VNC_BYTES_NEEDED(1);
2260                         proto_tree_add_item(tree, hf_vnc_tight_filter_id, tvb, *offset, 1, FALSE);
2261                         filter_id = tvb_get_guint8(tvb, *offset);
2262                         *offset += 1;
2263
2264                         switch (filter_id) {
2265                         case TIGHT_RECT_FILTER_COPY:
2266                                 /* nothing to do */
2267                                 break;
2268
2269                         case TIGHT_RECT_FILTER_PALETTE:
2270                                 bytes_needed = process_tight_rect_filter_palette(tvb, pinfo, offset, tree, &bits_per_pixel);
2271                                 if (bytes_needed != 0)
2272                                         return bytes_needed;
2273
2274                                 break;
2275
2276                         case TIGHT_RECT_FILTER_GRADIENT:
2277                                 /* nothing to do */
2278                                 break;
2279                         }
2280                 } else {
2281                         /* this is the same case as TIGHT_RECT_FILTER_COPY, so there's nothing special to do */
2282                 }
2283
2284                 row_size = ((guint) width * bits_per_pixel + 7) / 8;
2285                 if (row_size * height < TIGHT_MIN_BYTES_TO_COMPRESS) {
2286                         guint num_bytes;
2287
2288                         /* The data is not compressed; just skip over it */
2289
2290                         num_bytes = row_size * height;
2291                         VNC_BYTES_NEEDED(num_bytes);
2292                         proto_tree_add_item(tree, hf_vnc_tight_image_data, tvb, *offset, num_bytes, FALSE);
2293                         *offset += num_bytes;
2294
2295                         bytes_needed = 0;
2296                 } else {
2297                         /* The data is compressed; read its length and data */
2298                         bytes_needed = process_compact_length_and_image_data(tvb, offset, tree);
2299                         if (bytes_needed != 0)
2300                                 return bytes_needed;
2301                 }
2302         }
2303
2304         DISSECTOR_ASSERT(bytes_needed != -1);
2305
2306         return bytes_needed;
2307 }
2308
2309
2310 static guint
2311 decode_cursor(tvbuff_t *tvb, gint *offset, proto_tree *tree,
2312               guint pixels_bytes, guint mask_bytes)
2313 {
2314         guint total_bytes;
2315
2316         total_bytes = pixels_bytes + mask_bytes;
2317         VNC_BYTES_NEEDED (total_bytes);
2318
2319         proto_tree_add_item(tree, hf_vnc_cursor_encoding_pixels, tvb, *offset,
2320                             pixels_bytes, FALSE);
2321         *offset += pixels_bytes;
2322
2323         proto_tree_add_item(tree, hf_vnc_cursor_encoding_bitmask, tvb, *offset,
2324                             mask_bytes, FALSE);
2325         *offset += mask_bytes;
2326
2327         return 0; /* bytes_needed */
2328 }
2329
2330
2331 static guint
2332 vnc_rich_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2333                          proto_tree *tree, const guint16 width, const guint16 height)
2334 {
2335         guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
2336         guint pixels_bytes, mask_bytes;
2337
2338         pixels_bytes = width * height * bytes_per_pixel;
2339         mask_bytes = ((width + 7) / 8) * height;
2340
2341         return decode_cursor(tvb, offset, tree,
2342                              pixels_bytes, mask_bytes);
2343 }
2344
2345
2346 static guint
2347 vnc_x_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo _U_, gint *offset,
2348                       proto_tree *tree, const guint16 width, const guint16 height)
2349 {
2350         gint bitmap_row_bytes = (width + 7) / 8;
2351         gint mask_bytes = bitmap_row_bytes * height;
2352
2353         VNC_BYTES_NEEDED (6);
2354         proto_tree_add_item(tree, hf_vnc_cursor_x_fore_back, tvb, *offset, 6, FALSE);
2355         *offset += 6;
2356
2357         /* The length of the pixel data is the same as the length of the mask data (X cursors are strictly black/white) */
2358         return decode_cursor(tvb, offset, tree,
2359                              mask_bytes, mask_bytes);
2360 }
2361
2362
2363 static guint
2364 vnc_server_set_colormap_entries(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2365                                 proto_tree *tree)
2366 {
2367         guint16 number_of_colors;
2368         guint counter, bytes_needed;
2369         proto_item *ti;
2370         proto_tree *vnc_colormap_num_groups, *vnc_colormap_color_group;
2371
2372         col_set_str(pinfo->cinfo, COL_INFO, "Server set colormap entries");
2373
2374         number_of_colors = tvb_get_ntohs(tvb, 4);
2375
2376         VNC_BYTES_NEEDED(3);
2377         proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 1, FALSE);
2378         *offset += 1; /* Skip over 1 byte of padding */
2379
2380         proto_tree_add_item(tree, hf_vnc_colormap_first_color,
2381                             tvb, *offset, 2, FALSE);
2382         *offset += 2;
2383
2384         /*  XXX - this is 3 bytes into the tvb, but number_of_colors is set off
2385          *  of 4 bytes in... Bug???
2386          */
2387         ti = proto_tree_add_item(tree, hf_vnc_colormap_num_colors, tvb,
2388                                  *offset, 2, FALSE);
2389
2390         if (number_of_colors > 10000) {
2391                 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
2392                                        "Too many colors (%d), aborting dissection",
2393                                        number_of_colors);
2394                 return(0);
2395         }
2396
2397         bytes_needed = (number_of_colors * 6) + 5;
2398         VNC_BYTES_NEEDED(bytes_needed);
2399
2400         proto_item_add_subtree(ti, ett_vnc_colormap_num_groups);
2401
2402         *offset += 2;
2403
2404         ti = proto_tree_add_item(tree, hf_vnc_color_groups, tvb,
2405                                 *offset, number_of_colors * 6, FALSE);
2406         vnc_colormap_num_groups =
2407                 proto_item_add_subtree(ti, ett_vnc_colormap_num_groups);
2408
2409         for(counter = 1; counter <= number_of_colors; counter++) {
2410                 ti = proto_tree_add_text(vnc_colormap_num_groups, tvb,
2411                                          *offset, 6,
2412                                          "Color group #%d", counter);
2413
2414                 vnc_colormap_color_group =
2415                         proto_item_add_subtree(ti,
2416                                                ett_vnc_colormap_color_group);
2417
2418                 proto_tree_add_item(vnc_colormap_color_group,
2419                                     hf_vnc_colormap_red, tvb,
2420                                     *offset, 2, FALSE);
2421                 *offset += 2;
2422
2423                 proto_tree_add_item(vnc_colormap_color_group,
2424                                     hf_vnc_colormap_green, tvb,
2425                                     *offset, 2, FALSE);
2426                 *offset += 2;
2427
2428                 proto_tree_add_item(vnc_colormap_color_group,
2429                                     hf_vnc_colormap_blue, tvb,
2430                                     *offset, 2, FALSE);
2431                 *offset += 2;
2432         }
2433         return 0;
2434 }
2435
2436
2437 static void
2438 vnc_server_ring_bell(tvbuff_t *tvb _U_, packet_info *pinfo, gint *offset _U_,
2439                      proto_tree *tree _U_)
2440 {
2441         col_set_str(pinfo->cinfo, COL_INFO, "Server ring bell on client");
2442         /* This message type has no payload... */
2443 }
2444
2445
2446 static guint
2447 vnc_server_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2448                     proto_tree *tree)
2449 {
2450         guint32 text_len;
2451         proto_item *pi;
2452
2453         col_set_str(pinfo->cinfo, COL_INFO, "Server cut text");
2454
2455         text_len = tvb_get_ntohl(tvb, *offset);
2456         pi = proto_tree_add_item(tree, hf_vnc_server_cut_text_len, tvb, *offset, 4,
2457                             FALSE);
2458         *offset += 4;
2459
2460         if (text_len > 100000) {
2461                 expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_ERROR,
2462                                        "Too much cut text, aborting dissection");
2463                 return(0);
2464         }
2465
2466         VNC_BYTES_NEEDED(text_len);
2467
2468         proto_tree_add_item(tree, hf_vnc_server_cut_text, tvb, *offset,
2469                             text_len, FALSE);
2470         *offset += text_len;
2471
2472         return *offset;
2473 }
2474
2475
2476 static void
2477 vnc_set_bytes_per_pixel(const packet_info *pinfo, const guint8 bytes_per_pixel)
2478 {
2479         vnc_packet_t *per_packet_info;
2480
2481         per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
2482         /* Our calling function should have set the packet's proto data already */
2483         DISSECTOR_ASSERT(per_packet_info != NULL);
2484
2485         per_packet_info->bytes_per_pixel = bytes_per_pixel;
2486 }
2487
2488
2489 static void
2490 vnc_set_depth(const packet_info *pinfo, const guint8 depth)
2491 {
2492         vnc_packet_t *per_packet_info;
2493
2494         per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
2495         /* Our calling function should have set the packet's proto data already */
2496         DISSECTOR_ASSERT(per_packet_info != NULL);
2497
2498         per_packet_info->depth = depth;
2499 }
2500
2501
2502 static guint8
2503 vnc_get_bytes_per_pixel(const packet_info *pinfo)
2504 {
2505         vnc_packet_t *per_packet_info;
2506
2507         per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
2508         /* Our calling function should have set the packet's proto data already */
2509         DISSECTOR_ASSERT(per_packet_info != NULL);
2510
2511         return per_packet_info->bytes_per_pixel;
2512 }
2513
2514
2515 /* Register the protocol with Wireshark */
2516 void
2517 proto_register_vnc(void)
2518 {
2519         module_t *vnc_module; /* To handle our preferences */
2520
2521         /* Setup list of header fields */
2522         static hf_register_info hf[] = {
2523                 { &hf_vnc_padding,
2524                   { "Padding", "vnc.padding",
2525                     FT_NONE, BASE_NONE, NULL, 0x0,
2526                     "Unused space", HFILL }
2527                 },
2528
2529                 { &hf_vnc_server_proto_ver,
2530                   { "Server protocol version", "vnc.server_proto_ver",
2531                     FT_STRING, BASE_NONE, NULL, 0x0,
2532                     "VNC protocol version on server", HFILL }
2533                 },
2534                 { &hf_vnc_client_proto_ver,
2535                   { "Client protocol version", "vnc.client_proto_ver",
2536                     FT_STRING, BASE_NONE, NULL, 0x0,
2537                     "VNC protocol version on client", HFILL }
2538                 },
2539                 { &hf_vnc_num_security_types,
2540                   { "Number of security types", "vnc.num_security_types",
2541                     FT_UINT8, BASE_DEC, NULL, 0x0,
2542                     "Number of security (authentication) types supported by the server", HFILL }
2543                 },
2544                 { &hf_vnc_security_type,
2545                   { "Security type", "vnc.security_type",
2546                     FT_UINT8, BASE_DEC, VALS(vnc_security_types_vs), 0x0,
2547                     "Security types offered by the server (VNC versions => 3.007", HFILL }
2548                 },
2549                 { &hf_vnc_server_security_type,
2550                   { "Security type", "vnc.server_security_type",
2551                     FT_UINT32, BASE_DEC, VALS(vnc_security_types_vs), 0x0,
2552                     "Security type mandated by the server", HFILL }
2553                 },
2554                 { &hf_vnc_client_security_type,
2555                   { "Security type selected", "vnc.client_security_type",
2556                     FT_UINT8, BASE_DEC, VALS(vnc_security_types_vs), 0x0,
2557                     "Security type selected by the client", HFILL }
2558                 },
2559                 { &hf_vnc_tight_num_tunnel_types,
2560                   { "Number of supported tunnel types",  "vnc.num_tunnel_types",
2561                     FT_UINT32, BASE_DEC, NULL, 0x0,
2562                     "Number of tunnel types for TightVNC", HFILL }
2563                 },
2564                 { &hf_vnc_tight_tunnel_type,
2565                   { "Tunnel type", "vnc.tunnel_type",
2566                     FT_UINT8, BASE_DEC, NULL, 0x0,
2567                     "Tunnel type specific to TightVNC", HFILL }
2568                 },
2569                 { &hf_vnc_tight_num_auth_types,
2570                   { "Number of supported authentication types", "vnc.num_auth_types",
2571                     FT_UINT32, BASE_DEC, NULL, 0x0,
2572                     "Authentication types specific to TightVNC", HFILL }
2573                 },
2574                 { &hf_vnc_tight_auth_code,
2575                   { "Authentication code", "vnc.tight_auth_code",
2576                     FT_UINT32, BASE_DEC, VALS(vnc_security_types_vs), 0x0,
2577                     "Authentication code specific to TightVNC", HFILL }
2578                 },
2579                 { &hf_vnc_tight_server_message_type,
2580                   { "Server message type (TightVNC)", "vnc.tight_server_message_type",
2581                     FT_INT32, BASE_DEC, NULL, 0x0,
2582                     "Server message type specific to TightVNC", HFILL }
2583                 },
2584                 { &hf_vnc_tight_server_vendor,
2585                   { "Server vendor code", "vnc.server_vendor",
2586                     FT_STRING, BASE_NONE, NULL, 0x0,
2587                     "Server vendor code specific to TightVNC", HFILL }
2588                 },
2589                 { &hf_vnc_tight_server_name,
2590                   { "Server name", "vnc.server_name",
2591                     FT_STRING, BASE_NONE, NULL, 0x0,
2592                     "Server name specific to TightVNC", HFILL }
2593                 },
2594                 { &hf_vnc_tight_client_message_type,
2595                   { "Client message type (TightVNC)", "vnc.tight_client_message_type",
2596                     FT_INT32, BASE_DEC, NULL, 0x0,
2597                     "Client message type specific to TightVNC", HFILL }
2598                 },
2599                 { &hf_vnc_tight_client_vendor,
2600                   { "Client vendor code", "vnc.client_vendor",
2601                     FT_STRING, BASE_NONE, NULL, 0x0,
2602                     "Client vendor code specific to TightVNC", HFILL }
2603                 },
2604                 { &hf_vnc_tight_client_name,
2605                   { "Client name", "vnc.client_name",
2606                     FT_STRING, BASE_NONE, NULL, 0x0,
2607                     "Client name specific to TightVNC", HFILL }
2608                 },
2609                 { &hf_vnc_tight_encoding_type,
2610                   { "Encoding type", "vnc.encoding_type",
2611                     FT_INT32, BASE_DEC, VALS(encoding_types_vs), 0x0,
2612                     "Encoding type specific to TightVNC", HFILL }
2613                 },
2614                 { &hf_vnc_tight_encoding_vendor,
2615                   { "Encoding vendor code", "vnc.encoding_vendor",
2616                     FT_STRING, BASE_NONE, NULL, 0x0,
2617                     "Encoding vendor code specific to TightVNC", HFILL }
2618                 },
2619                 { &hf_vnc_tight_encoding_name,
2620                   { "Encoding name", "vnc.encoding_name",
2621                     FT_STRING, BASE_NONE, NULL, 0x0,
2622                     "Encoding name specific to TightVNC", HFILL }
2623                 },
2624                 { &hf_vnc_tight_reset_stream0,
2625                   { "Reset compression stream 0", "vnc.tight_reset_stream0",
2626                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2627                     "Tight compression, reset compression stream 0", HFILL }
2628                 },
2629                 { &hf_vnc_tight_reset_stream1,
2630                   { "Reset compression stream 1", "vnc.tight_reset_stream1",
2631                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2632                     "Tight compression, reset compression stream 1", HFILL }
2633                 },
2634                 { &hf_vnc_tight_reset_stream2,
2635                   { "Reset compression stream 2", "vnc.tight_reset_stream2",
2636                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2637                     "Tight compression, reset compression stream 2", HFILL }
2638                 },
2639                 { &hf_vnc_tight_reset_stream3,
2640                   { "Reset compression stream 3", "vnc.tight_reset_stream3",
2641                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2642                     "Tight compression, reset compression stream 3", HFILL }
2643                 },
2644                 { &hf_vnc_tight_rect_type,
2645                   { "Rectangle type", "vnc.tight_rect_type",
2646                     FT_UINT8, BASE_HEX, NULL, 0x0,
2647                     "Tight compression, rectangle type", HFILL }
2648                 },
2649                 { &hf_vnc_tight_image_len,
2650                   { "Image data length", "vnc.tight_image_len",
2651                     FT_UINT32, BASE_DEC, NULL, 0x0,
2652                     "Tight compression, length of image data", HFILL }
2653                 },
2654                 { &hf_vnc_tight_image_data,
2655                   { "Image data", "vnc.tight_image_data",
2656                     FT_BYTES, BASE_NONE, NULL, 0x0,
2657                     "Tight compression, image data", HFILL }
2658                 },
2659                 { &hf_vnc_tight_fill_color,
2660                   { "Fill color (RGB)", "vnc.tight_fill_color",
2661                     FT_BYTES, BASE_NONE, NULL, 0x0,
2662                     "Tight compression, fill color for solid rectangle", HFILL }
2663                 },
2664                 { &hf_vnc_tight_filter_flag,
2665                   { "Explicit filter flag", "vnc.tight_filter_flag",
2666                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2667                     "Tight compression, explicit filter flag", HFILL }
2668                 },
2669                 { &hf_vnc_tight_filter_id,
2670                   { "Filter ID", "vnc.tight_filter_id",
2671                     FT_UINT8, BASE_DEC, VALS(tight_filter_ids_vs), 0x0,
2672                     "Tight compression, filter ID", HFILL }
2673                 },
2674                 { &hf_vnc_tight_palette_num_colors,
2675                   { "Number of colors in palette", "vnc.tight_palette_num_colors",
2676                     FT_UINT8, BASE_DEC, NULL, 0x0,
2677                     "Tight compression, number of colors in rectangle's palette", HFILL }
2678                 },
2679                 { &hf_vnc_tight_palette_data,
2680                   { "Palette data", "vnc.tight_palette_data",
2681                     FT_BYTES, BASE_NONE, NULL, 0x0,
2682                     "Tight compression, palette data for a rectangle", HFILL }
2683                 },
2684                 { &hf_vnc_vendor_code,
2685                   { "Vendor code", "vnc.vendor_code",
2686                     FT_STRING, BASE_NONE, NULL, 0x0,
2687                     "Identifies the VNC server software's vendor", HFILL }
2688                 },
2689                 { &hf_vnc_security_type_string,
2690                   { "Security type string", "vnc.security_type_string",
2691                     FT_STRING, BASE_NONE, NULL, 0x0,
2692                     "Security type being used", HFILL }
2693                 },
2694                 { &hf_vnc_auth_challenge,
2695                   { "Authentication challenge", "vnc.auth_challenge",
2696                     FT_BYTES, BASE_NONE, NULL, 0x0,
2697                     "Random authentication challenge from server to client", HFILL }
2698                 },
2699                 { &hf_vnc_auth_response,
2700                   { "Authentication response", "vnc.auth_response",
2701                     FT_BYTES, BASE_NONE, NULL, 0x0,
2702                     "Client's encrypted response to the server's authentication challenge", HFILL }
2703                 },
2704                 { &hf_vnc_auth_result,
2705                   { "Authentication result", "vnc.auth_result",
2706                     FT_BOOLEAN, 32, TFS(&auth_result_tfs), 0x1,
2707                     NULL, HFILL }
2708                 },
2709                 { &hf_vnc_auth_error,
2710                   { "Authentication error", "vnc.auth_error",
2711                     FT_STRING, BASE_NONE, NULL, 0x0,
2712                     "Authentication error (present only if the authentication result is fail", HFILL }
2713                 },
2714                 { &hf_vnc_share_desktop_flag,
2715                   { "Share desktop flag", "vnc.share_desktop_flag",
2716                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2717                     "Client's desire to share the server's desktop with other clients", HFILL }
2718                 },
2719                 { &hf_vnc_width,
2720                   { "Framebuffer width", "vnc.width",
2721                     FT_UINT16, BASE_DEC, NULL, 0x0,
2722                     "Width of the framebuffer (screen) in pixels", HFILL }
2723                 },
2724                 { &hf_vnc_height,
2725                   { "Framebuffer height", "vnc.height",
2726                     FT_UINT16, BASE_DEC, NULL, 0x0,
2727                     "Height of the framebuffer (screen) in pixels", HFILL }
2728                 },
2729                 { &hf_vnc_server_bits_per_pixel,
2730                   { "Bits per pixel", "vnc.server_bits_per_pixel",
2731                     FT_UINT8, BASE_DEC, NULL, 0x0,
2732                     "Number of bits used by server for each pixel value on the wire from the server", HFILL }
2733                 },
2734                 { &hf_vnc_server_depth,
2735                   { "Depth", "vnc.server_depth",
2736                     FT_UINT8, BASE_DEC, NULL, 0x0,
2737                     "Number of useful bits in the pixel value on server", HFILL }
2738                 },
2739                 { &hf_vnc_server_big_endian_flag,
2740                   { "Big endian flag", "vnc.server_big_endian_flag",
2741                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2742                     "True if multi-byte pixels are interpreted as big endian by server", HFILL }
2743                 },
2744                 { &hf_vnc_server_true_color_flag,
2745                   { "True color flag", "vnc.server_true_color_flag",
2746                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2747                     "If true, then the next six items specify how to extract the red, green and blue intensities from the pixel value on the server.", HFILL }
2748                 },
2749                 { &hf_vnc_server_red_max,
2750                   { "Red maximum", "vnc.server_red_max",
2751                     FT_UINT16, BASE_DEC, NULL, 0x0,
2752                     "Maximum red value on server as n: 2^n - 1", HFILL }
2753                 },
2754                 { &hf_vnc_server_green_max,
2755                   { "Green maximum", "vnc.server_green_max",
2756                     FT_UINT16, BASE_DEC, NULL, 0x0,
2757                     "Maximum green value on server as n: 2^n - 1", HFILL }
2758                 },
2759                 { &hf_vnc_server_blue_max,
2760                   { "Blue maximum", "vnc.server_blue_max",
2761                     FT_UINT16, BASE_DEC, NULL, 0x0,
2762                     "Maximum blue value on server as n: 2^n - 1", HFILL }
2763                 },
2764                 { &hf_vnc_server_red_shift,
2765                   { "Red shift", "vnc.server_red_shift",
2766                     FT_UINT8, BASE_DEC, NULL, 0x0,
2767                     "Number of shifts needed to get the red value in a pixel to the least significant bit on the server", HFILL }
2768                 },
2769                 { &hf_vnc_server_green_shift,
2770                   { "Green shift", "vnc.server_green_shift",
2771                     FT_UINT8, BASE_DEC, NULL, 0x0,
2772                     "Number of shifts needed to get the green value in a pixel to the least significant bit on the server", HFILL }
2773                 },
2774                 { &hf_vnc_server_blue_shift,
2775                   { "Blue shift", "vnc.server_blue_shift",
2776                     FT_UINT8, BASE_DEC, NULL, 0x0,
2777                     "Number of shifts needed to get the blue value in a pixel to the least significant bit on the server", HFILL }
2778                 },
2779                 { &hf_vnc_desktop_name_len,
2780                   { "Desktop name length", "vnc.desktop_name_len",
2781                     FT_UINT32, BASE_DEC, NULL, 0x0,
2782                     "Length of desktop name in bytes", HFILL }
2783                 },
2784                 { &hf_vnc_desktop_screen_id,
2785                   { "Screen ID", "vnc.screen_id",
2786                     FT_UINT32, BASE_DEC, NULL, 0x0,
2787                     "ID of screen", HFILL }
2788                 },
2789                 { &hf_vnc_desktop_screen_x,
2790                   { "Screen X position", "vnc.screen_x",
2791                     FT_UINT16, BASE_DEC, NULL, 0x0,
2792                     "X coordinate of screen", HFILL }
2793                 },
2794                 { &hf_vnc_desktop_screen_y,
2795                   { "Screen Y position", "vnc.screen_y",
2796                     FT_UINT16, BASE_DEC, NULL, 0x0,
2797                     "Y coordinate of screen", HFILL }
2798                 },
2799                 { &hf_vnc_desktop_screen_width,
2800                   { "Screen width", "vnc.screen_width",
2801                     FT_UINT16, BASE_DEC, NULL, 0x0,
2802                     "Width of screen", HFILL }
2803                 },
2804                 { &hf_vnc_desktop_screen_height,
2805                   { "Screen height", "vnc.screen_height",
2806                     FT_UINT16, BASE_DEC, NULL, 0x0,
2807                     "Height of screen", HFILL }
2808                 },
2809                 { &hf_vnc_desktop_screen_flags,
2810                   { "Screen flags", "vnc.screen_flags",
2811                     FT_UINT32, BASE_DEC, NULL, 0x0,
2812                     "Flags of screen", HFILL }
2813                 },
2814                 { &hf_vnc_desktop_name,
2815                   { "Desktop name", "vnc.desktop_name",
2816                     FT_STRING, BASE_NONE, NULL, 0x0,
2817                     "Name of the VNC desktop on the server", HFILL }
2818                 },
2819                 { &hf_vnc_num_server_message_types,
2820                   { "Server message types", "vnc.num_server_message_types",
2821                     FT_UINT16, BASE_DEC, NULL, 0x0,
2822                     "Unknown", HFILL } /* XXX - Needs description */
2823                 },
2824                 { &hf_vnc_num_client_message_types,
2825                   { "Client message types", "vnc.num_client_message_types",
2826                     FT_UINT16, BASE_DEC, NULL, 0x0,
2827                     "Unknown", HFILL } /* XXX - Needs description */
2828                 },
2829                 { &hf_vnc_num_encoding_types,
2830                   { "Encoding types", "vnc.num_encoding_types",
2831                     FT_UINT16, BASE_DEC, NULL, 0x0,
2832                     "Unknown", HFILL } /* XXX - Needs description */
2833                 },
2834                 { &hf_vnc_client_message_type,
2835                   { "Client Message Type", "vnc.client_message_type",
2836                     FT_UINT8, BASE_DEC, VALS(vnc_client_message_types_vs), 0x0,
2837                     "Message type from client", HFILL }
2838                 },
2839                 { &hf_vnc_client_bits_per_pixel,
2840                   { "Bits per pixel", "vnc.client_bits_per_pixel",
2841                     FT_UINT8, BASE_DEC, NULL, 0x0,
2842                     "Number of bits used by server for each pixel value on the wire from the client", HFILL }
2843                 },
2844                 { &hf_vnc_client_depth,
2845                   { "Depth", "vnc.client_depth",
2846                     FT_UINT8, BASE_DEC, NULL, 0x0,
2847                     "Number of useful bits in the pixel value on client", HFILL }
2848                 },
2849                 { &hf_vnc_client_big_endian_flag,
2850                   { "Big endian flag", "vnc.client_big_endian_flag",
2851                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2852                     "True if multi-byte pixels are interpreted as big endian by client", HFILL }
2853                 },
2854                 { &hf_vnc_client_true_color_flag,
2855                   { "True color flag", "vnc.client_true_color_flag",
2856                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2857                     "If true, then the next six items specify how to extract the red, green and blue intensities from the pixel value on the client.", HFILL }
2858                 },
2859                 { &hf_vnc_client_red_max,
2860                   { "Red maximum", "vnc.client_red_max",
2861                     FT_UINT16, BASE_DEC, NULL, 0x0,
2862                     "Maximum red value on client as n: 2^n - 1", HFILL }
2863                 },
2864                 { &hf_vnc_client_green_max,
2865                   { "Green maximum", "vnc.client_green_max",
2866                     FT_UINT16, BASE_DEC, NULL, 0x0,
2867                     "Maximum green value on client as n: 2^n - 1", HFILL }
2868                 },
2869                 { &hf_vnc_client_blue_max,
2870                   { "Blue maximum", "vnc.client_blue_max",
2871                     FT_UINT16, BASE_DEC, NULL, 0x0,
2872                     "Maximum blue value on client as n: 2^n - 1", HFILL }
2873                 },
2874                 { &hf_vnc_client_red_shift,
2875                   { "Red shift", "vnc.client_red_shift",
2876                     FT_UINT8, BASE_DEC, NULL, 0x0,
2877                     "Number of shifts needed to get the red value in a pixel to the least significant bit on the client", HFILL }
2878                 },
2879                 { &hf_vnc_client_green_shift,
2880                   { "Green shift", "vnc.client_green_shift",
2881                     FT_UINT8, BASE_DEC, NULL, 0x0,
2882                     "Number of shifts needed to get the green value in a pixel to the least significant bit on the client", HFILL }
2883                 },
2884                 { &hf_vnc_client_blue_shift,
2885                   { "Blue shift", "vnc.client_blue_shift",
2886                     FT_UINT8, BASE_DEC, NULL, 0x0,
2887                     "Number of shifts needed to get the blue value in a pixel to the least significant bit on the client", HFILL }
2888                 },
2889
2890                 /* Client Key Event */
2891                 { &hf_vnc_key_down,
2892                   { "Key down", "vnc.key_down",
2893                     FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x0,
2894                     "Specifies whether the key is being pressed or not", HFILL }
2895                 },
2896                 { &hf_vnc_key,
2897                   { "Key", "vnc.key",
2898                     FT_UINT32, BASE_HEX, VALS(keysym_vals_source), 0x0, /* keysym_vals_source is from packet-x11-keysym.h */
2899                     "Key being pressed/depressed", HFILL }
2900                 },
2901
2902                 /* Client Pointer Event */
2903                 { &hf_vnc_button_1_pos,
2904                   { "Mouse button #1 position", "vnc.button_1_pos",
2905                     FT_BOOLEAN, 8, TFS(&button_mask_tfs), 0x1,
2906                     "Whether mouse button #1 is being pressed or not", HFILL }
2907                 },
2908                 { &hf_vnc_button_2_pos,
2909                   { "Mouse button #2 position", "vnc.button_2_pos",
2910                     FT_BOOLEAN, 8, TFS(&button_mask_tfs), 0x2,
2911                     "Whether mouse button #2 is being pressed or not", HFILL }
2912                 },
2913                 { &hf_vnc_button_3_pos,
2914                   { "Mouse button #3 position", "vnc.button_3_pos",
2915                     FT_BOOLEAN, 8, TFS(&button_mask_tfs), 0x4,
2916                     "Whether mouse button #3 is being pressed or not", HFILL }
2917                 },
2918                 { &hf_vnc_button_4_pos,
2919                   { "Mouse button #4 position", "vnc.button_4_pos",
2920              &nbs