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