Trivial warning fixes
[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 <stephentfisher@yahoo.com>
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
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
516 /* Code to dissect the packets */
517 static void
518 dissect_vnc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
519 {
520         gboolean ret;
521         gint offset = 0;
522
523         /* Set up structures needed to add the protocol subtree and manage it */
524         proto_item *ti=NULL;
525         proto_tree *vnc_tree=NULL;
526
527         conversation_t *conversation;
528         vnc_conversation_t *per_conversation_info;
529
530         conversation = find_conversation(pinfo->fd->num, &pinfo->src,
531                                          &pinfo->dst, pinfo->ptype,
532                                          pinfo->srcport, pinfo->destport, 0);
533
534         if(!conversation) {  /* Conversation does not exist yet - create it */
535                 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
536                                                 &pinfo->dst, pinfo->ptype,
537                                                 pinfo->srcport,
538                                                 pinfo->destport, 0);
539         }
540
541         /* Retrieve information from conversation, or add it if it isn't
542          * there yet */
543         per_conversation_info = conversation_get_proto_data(conversation,
544                                                             proto_vnc);
545         if(!per_conversation_info) {
546                 per_conversation_info = se_alloc(sizeof(vnc_conversation_t));
547                 
548                 per_conversation_info->vnc_next_state = SERVER_VERSION;
549
550                 conversation_add_proto_data(conversation, proto_vnc,
551                                             per_conversation_info);
552         }
553
554
555         /* Make entries in Protocol column and Info column on summary display */
556         if (check_col(pinfo->cinfo, COL_PROTOCOL))
557                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VNC");
558
559         /* First, clear the info column */
560         if(check_col(pinfo->cinfo, COL_INFO))
561                 col_clear(pinfo->cinfo, COL_INFO);
562
563         /* create display subtree for the protocol */
564         if(tree) {
565                 ti = proto_tree_add_item(tree, proto_vnc, tvb, 0, -1, FALSE);
566                 vnc_tree = proto_item_add_subtree(ti, ett_vnc);
567         }
568
569         offset = 0; /* Start at the beginning of the VNC protocol data */
570
571         /* Dissect any remaining session startup messages */
572         ret = vnc_startup_messages(tvb, pinfo, offset, vnc_tree,
573                                    per_conversation_info);
574
575         vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
576         vnc_set_depth(pinfo, vnc_depth);
577
578         if(!ret) {      
579                 if(DEST_PORT_VNC)
580                         vnc_client_to_server(tvb, pinfo, &offset, vnc_tree);
581                 else
582                         vnc_server_to_client(tvb, pinfo, &offset, vnc_tree);
583         }
584 }
585
586 /* Returns the new offset after processing the 4-byte vendor string */
587 static gint
588 process_vendor(proto_tree *tree, gint hfindex, tvbuff_t *tvb, gint offset)
589 {
590         gchar *vendor;
591         proto_item *ti;
592
593         vendor = tvb_get_ephemeral_string(tvb, offset, 4);
594
595         ti = proto_tree_add_string(tree, hfindex, tvb, offset, 4, vendor);
596
597         if(g_ascii_strcasecmp(vendor, "STDV") == 0)
598                 proto_item_append_text(ti, " (Standard VNC vendor)");
599         else if(g_ascii_strcasecmp(vendor, "TRDV") == 0)
600                 proto_item_append_text(ti, " (Tridia VNC vendor)");
601         else if(g_ascii_strcasecmp(vendor, "TGHT") == 0)
602                 proto_item_append_text(ti, " (Tight VNC vendor)");
603                         
604         offset += 4;
605         return offset;
606 }
607
608 /* Returns the new offset after processing the specified number of capabilities */
609 static gint
610 process_tight_capabilities(proto_tree *tree,
611                            gint type_index, gint vendor_index, gint name_index,
612                            tvbuff_t *tvb, gint offset, gint num_capabilities)
613 {
614         gint i;
615
616         /* See vnc_unixsrc/include/rfbproto.h:rfbCapabilityInfo */
617
618         for (i = 0; i < num_capabilities; i++) {
619                 char *name;
620
621                 proto_tree_add_item(tree, type_index, tvb, offset, 4, FALSE);
622                 offset += 4;
623
624                 offset = process_vendor(tree, vendor_index, tvb, offset);
625
626                 name = tvb_get_ephemeral_string(tvb, offset, 8);
627                 proto_tree_add_string(tree, name_index, tvb, offset, 8, name);
628                 offset += 8;
629         }
630
631         return offset;
632 }
633
634 /* Returns true if additional session startup messages follow */
635 static gboolean
636 vnc_startup_messages(tvbuff_t *tvb, packet_info *pinfo, gint offset,
637                      proto_tree *tree, vnc_conversation_t
638                      *per_conversation_info)
639 {
640         guint8 num_security_types;
641         guint32 desktop_name_len, auth_result, text_len;
642         vnc_packet_t *per_packet_info;
643         gint num_tunnel_types;
644         gint num_auth_types;
645
646         per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
647
648         if(!per_packet_info) {
649                 per_packet_info = se_alloc(sizeof(vnc_packet_t));
650
651                 per_packet_info->state = per_conversation_info->vnc_next_state;
652                 per_packet_info->preferred_encoding = -1;
653
654                 p_add_proto_data(pinfo->fd, proto_vnc, per_packet_info);
655         } 
656                 
657         /* Packet dissection follows */
658         switch(per_packet_info->state) {
659
660         case SERVER_VERSION :
661                 proto_tree_add_item(tree, hf_vnc_server_proto_ver, tvb, 4,
662                                     7, FALSE);
663
664                 per_conversation_info->server_proto_ver =
665                         g_strtod((char *)tvb_get_ephemeral_string(tvb, 4, 7),
666                                  NULL);
667                 
668                 if (check_col(pinfo->cinfo, COL_INFO))
669                         col_add_fstr(pinfo->cinfo, COL_INFO,
670                                      "Server protocol version: %s",
671                                      tvb_format_text(tvb, 4, 7));
672                 
673                 per_conversation_info->vnc_next_state = CLIENT_VERSION;
674                 break;
675                 
676         case CLIENT_VERSION :
677                 proto_tree_add_item(tree, hf_vnc_client_proto_ver, tvb,
678                                     4, 7, FALSE);
679
680                 per_conversation_info->client_proto_ver =
681                         g_strtod((char *)tvb_get_ephemeral_string(tvb, 4, 7),
682                                  NULL);
683                 
684                 if (check_col(pinfo->cinfo, COL_INFO))
685                         col_add_fstr(pinfo->cinfo, COL_INFO,
686                                      "Client protocol version: %s",
687                                      tvb_format_text(tvb, 4, 7));
688                 
689                 per_conversation_info->vnc_next_state = SECURITY;
690                 break;
691
692         case SECURITY :
693                 if (check_col(pinfo->cinfo, COL_INFO))
694                         col_set_str(pinfo->cinfo, COL_INFO,
695                                     "Security types supported");
696                 
697                 /* We're checking against the client protocol version because
698                  * the client is the final decider on which version to use
699                  * after the server offers the highest version it supports. */
700                 
701                 if(per_conversation_info->client_proto_ver >= 3.007) {
702                         proto_tree_add_item(tree,
703                                             hf_vnc_num_security_types, tvb,
704                                             offset, 1, FALSE);
705                         num_security_types = tvb_get_guint8(tvb, offset);
706                         
707                         for(offset = 1; offset <= num_security_types; offset++){
708                                 proto_tree_add_item(tree,
709                                                     hf_vnc_security_type, tvb,
710                                                     offset, 1, FALSE);
711
712                         }
713                 } else {
714                         /* Version < 3.007: The server decides the
715                          * authentication type for us to use */
716                         proto_tree_add_item(tree,
717                                             hf_vnc_server_security_type, tvb,
718                                             offset, 4, FALSE);
719                 }
720
721                 per_conversation_info->vnc_next_state = SECURITY_TYPES;
722                 break;
723
724         case SECURITY_TYPES :
725                 if (check_col(pinfo->cinfo, COL_INFO))
726                         col_set_str(pinfo->cinfo, COL_INFO,
727                                     "Authentication type selected by client");
728                 
729                 proto_tree_add_item(tree, hf_vnc_client_security_type, tvb,
730                                     offset, 1, FALSE);
731                 per_conversation_info->security_type_selected =
732                         tvb_get_guint8(tvb, offset);
733         
734                 switch(per_conversation_info->security_type_selected) {
735
736                 case 1 : /* None */
737                         if(per_conversation_info->client_proto_ver >= 3.008)
738                                 per_conversation_info->vnc_next_state =
739                                         SECURITY_RESULT;
740                         else
741                                 per_conversation_info->vnc_next_state =
742                                         CLIENT_INIT;
743
744                         break;
745
746                 case 2 : /* VNC */
747                         per_conversation_info->vnc_next_state =
748                                 VNC_AUTHENTICATION_CHALLENGE;
749                         break;
750
751                 case 16 : /* Tight */
752                         per_conversation_info->vnc_next_state =
753                                 TIGHT_TUNNELING_CAPABILITIES;
754                         
755                 default :
756                         /* Security type not supported by this dissector */
757                         break;
758                 }
759
760                 break;
761
762         case TIGHT_TUNNELING_CAPABILITIES :
763                 if (check_col(pinfo->cinfo, COL_INFO))
764                         col_set_str(pinfo->cinfo, COL_INFO,
765                                     "TightVNC tunneling capabilities supported");
766
767                 proto_tree_add_item(tree, hf_vnc_tight_num_tunnel_types, tvb, offset, 4, FALSE);
768                 num_tunnel_types = tvb_get_ntohl(tvb, offset);
769                 offset += 4;
770
771                 {
772                         gint i;
773
774                         for(i = 0; i < num_tunnel_types; i++) {
775                                 /* TightVNC and Xvnc don't support any tunnel capabilities yet, but each capability
776                                  * is 16 bytes, so skip them.
777                                  */
778
779                                 proto_tree_add_item(tree, hf_vnc_tight_tunnel_type, tvb, offset, 16, FALSE);
780                                 offset += 16;
781                         }
782                 }
783
784                 if (num_tunnel_types == 0)
785                         per_conversation_info->vnc_next_state = TIGHT_AUTH_CAPABILITIES;
786                 else
787                         per_conversation_info->vnc_next_state = TIGHT_TUNNEL_TYPE_REPLY;
788                 break;
789
790         case TIGHT_TUNNEL_TYPE_REPLY:
791                 /* Neither TightVNC nor Xvnc implement this; they just have a placeholder that emits an error
792                  * message and closes the connection (xserver/hw/vnc/auth.c:rfbProcessClientTunnelingType).
793                  * We should actually never get here...
794                  */
795                 break;
796
797         case TIGHT_AUTH_CAPABILITIES:
798                 if (check_col(pinfo->cinfo, COL_INFO))
799                         col_set_str(pinfo->cinfo, COL_INFO,
800                                     "TightVNC authentication capabilities supported");
801
802                 proto_tree_add_item(tree, hf_vnc_tight_num_auth_types, tvb, offset, 4, FALSE);
803                 num_auth_types = tvb_get_ntohl(tvb, offset);
804                 offset += 4;
805
806                 {
807                         int i;
808
809                         for (i = 0; i < num_auth_types; i++) {
810                                 /* See xserver/hw/vnc/auth.c:rfbSendAuthCaps()
811                                  * We don't actually display the auth types for now.
812                                  */
813                                 proto_tree_add_item(tree, hf_vnc_tight_auth_type, tvb, offset, 16, FALSE);
814                                 offset += 16;
815                         }
816                 }
817
818                 if (num_auth_types == 0)
819                         per_conversation_info->vnc_next_state = CLIENT_INIT;
820                 else
821                         per_conversation_info->vnc_next_state = TIGHT_AUTH_TYPE_REPLY;
822                 break;
823
824         case TIGHT_AUTH_TYPE_REPLY:
825                 REPORT_DISSECTOR_BUG("Unimplemented case: TightVNC authentication reply");
826                 /* FIXME: implement.  See xserver/hw/vnc/auth.c:rfbProcessClientAuthType() */
827                 break;          
828
829         case TIGHT_AUTH_TYPE_AND_VENDOR_CODE :
830                 if (check_col(pinfo->cinfo, COL_INFO))
831                         col_set_str(pinfo->cinfo, COL_INFO,
832                                     "Authentication type / vendor code");
833
834                 proto_tree_add_item(tree, hf_vnc_server_security_type, tvb,
835                                     offset, 4, FALSE);          
836
837                 offset += 4;
838
839                 offset = process_vendor(tree, hf_vnc_vendor_code, tvb, offset);
840
841                 /* Display authentication method string */
842                 proto_tree_add_item(tree, hf_vnc_security_type_string, tvb,
843                                     offset, 8, FALSE);
844
845                 per_conversation_info->vnc_next_state =
846                         TIGHT_UNKNOWN_PACKET3;
847
848                 break;
849                 
850         case TIGHT_UNKNOWN_PACKET3 :
851                 if (check_col(pinfo->cinfo, COL_INFO))
852                         col_set_str(pinfo->cinfo, COL_INFO,
853                                     "Unknown packet (TightVNC)");
854                 
855                 proto_tree_add_text(tree, tvb, offset, -1,
856                                     "Unknown packet (TightVNC)");
857
858                 per_conversation_info->vnc_next_state =
859                         VNC_AUTHENTICATION_CHALLENGE;
860
861                 break;
862
863         case VNC_AUTHENTICATION_CHALLENGE :
864                 if (check_col(pinfo->cinfo, COL_INFO))
865                         col_set_str(pinfo->cinfo, COL_INFO,
866                                     "Authentication challenge from server");
867                 
868                 proto_tree_add_item(tree, hf_vnc_auth_challenge, tvb,
869                                     offset, 16, FALSE);
870
871                 per_conversation_info->vnc_next_state =
872                         VNC_AUTHENTICATION_RESPONSE;
873                 break;
874
875         case VNC_AUTHENTICATION_RESPONSE :
876                 if (check_col(pinfo->cinfo, COL_INFO))
877                         col_set_str(pinfo->cinfo, COL_INFO,
878                                     "Authentication response from client");
879                 
880                 proto_tree_add_item(tree, hf_vnc_auth_response, tvb,
881                                     offset, 16, FALSE);
882                 
883                 per_conversation_info->vnc_next_state = SECURITY_RESULT;
884                 break;
885
886         case SECURITY_RESULT :
887                 if (check_col(pinfo->cinfo, COL_INFO))
888                         col_set_str(pinfo->cinfo, COL_INFO,
889                                     "Authentication result");
890                 
891                 proto_tree_add_item(tree, hf_vnc_auth_result, tvb, offset,
892                                     4, FALSE);
893                 auth_result = tvb_get_ntohl(tvb, offset);
894                 offset += 4;
895
896                 switch(auth_result) {
897
898                 case 0 : /* OK */
899                         per_conversation_info->vnc_next_state = CLIENT_INIT;
900                         break;
901
902                 case 1 : /* Failed */
903                         if(per_conversation_info->client_proto_ver >= 3.008) {
904                                 text_len = tvb_get_ntohl(tvb, offset);
905                                 proto_tree_add_text(tree, tvb, offset, 4, "Length of authentication error: %d", text_len);
906                                 offset += 4;
907                                 
908                                 proto_tree_add_item(tree, hf_vnc_auth_error, tvb,
909                                                     offset, text_len, FALSE);
910                                 offset += text_len;
911                         }
912
913                         return TRUE; /* All versions: Do not continue
914                                         processing VNC packets as connection
915                                         will be closed after this packet. */
916                         
917                         break;
918                 }
919
920                 break;
921
922         case CLIENT_INIT :
923                 if (check_col(pinfo->cinfo, COL_INFO))
924                         col_set_str(pinfo->cinfo, COL_INFO,
925                                     "Share desktop flag");
926
927                 proto_tree_add_item(tree, hf_vnc_share_desktop_flag, tvb,
928                                     offset, 1, FALSE);
929                 
930                 per_conversation_info->vnc_next_state = SERVER_INIT;
931
932                 break;
933                 
934         case SERVER_INIT :
935                 if (check_col(pinfo->cinfo, COL_INFO))
936                         col_set_str(pinfo->cinfo, COL_INFO,
937                                     "Server framebuffer parameters");
938                
939                 proto_tree_add_item(tree, hf_vnc_width, tvb, offset, 2,
940                                     FALSE);
941                 offset += 2;
942
943                 proto_tree_add_item(tree, hf_vnc_height, tvb, offset, 2,
944                                     FALSE);
945                 offset += 2;
946
947                 proto_tree_add_item(tree, hf_vnc_server_bits_per_pixel,
948                                     tvb, offset, 1, FALSE);
949                 vnc_bytes_per_pixel = tvb_get_guint8(tvb, offset)/8;
950                 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
951                 offset += 1;
952
953                 proto_tree_add_item(tree, hf_vnc_server_depth, tvb, offset,
954                                     1, FALSE);
955                 offset += 1;
956
957                 proto_tree_add_item(tree, hf_vnc_server_big_endian_flag,
958                                     tvb, offset, 1, FALSE);
959                 offset += 1;
960
961                 proto_tree_add_item(tree, hf_vnc_server_true_color_flag,
962                                     tvb, offset, 1, FALSE);
963                 offset += 1;
964
965                 proto_tree_add_item(tree, hf_vnc_server_red_max,
966                                     tvb, offset, 2, FALSE);
967                 offset += 2;
968
969                 proto_tree_add_item(tree, hf_vnc_server_green_max,
970                                     tvb, offset, 2, FALSE);
971                 offset += 2;
972
973                 proto_tree_add_item(tree, hf_vnc_server_blue_max,
974                                     tvb, offset, 2, FALSE);
975                 offset += 2;
976
977                 proto_tree_add_item(tree, hf_vnc_server_red_shift,
978                                     tvb, offset, 1, FALSE);
979                 offset += 1;
980
981                 proto_tree_add_item(tree, hf_vnc_server_green_shift,
982                                     tvb, offset, 1, FALSE);
983                 offset += 1;
984
985                 proto_tree_add_item(tree, hf_vnc_server_blue_shift,
986                                     tvb, offset, 1, FALSE);
987                 offset += 1;
988
989                 proto_tree_add_item(tree, hf_vnc_padding,
990                                     tvb, offset, 3, FALSE);
991                 offset += 3; /* Skip over 3 bytes of padding */
992                 
993                 if(tvb_length_remaining(tvb, offset) > 0) {
994                         /* Sometimes the desktop name & length is skipped */
995                         proto_tree_add_item(tree, hf_vnc_desktop_name_len,
996                                             tvb, offset, 4, FALSE);
997                         desktop_name_len = tvb_get_ntohl(tvb, offset);
998                         offset += 4;
999
1000                         proto_tree_add_item(tree, hf_vnc_desktop_name,
1001                                             tvb, offset, desktop_name_len,
1002                                             FALSE);
1003                 }
1004
1005                 if(per_conversation_info->security_type_selected == TIGHT)
1006                         per_conversation_info->vnc_next_state =
1007                                 TIGHT_INTERACTION_CAPS;
1008                 else
1009                         per_conversation_info->vnc_next_state = NORMAL_TRAFFIC;
1010                 break;
1011                 
1012         case TIGHT_INTERACTION_CAPS :
1013                 if (check_col(pinfo->cinfo, COL_INFO))
1014                         col_set_str(pinfo->cinfo, COL_INFO,
1015                                     "TightVNC Interaction Capabilities");
1016
1017                 proto_tree_add_item(tree, hf_vnc_num_server_message_types,
1018                                     tvb, offset, 2, FALSE);
1019                 per_conversation_info->num_server_message_types = tvb_get_ntohs(tvb, offset);
1020                 offset += 2;
1021
1022                 proto_tree_add_item(tree, hf_vnc_num_client_message_types,
1023                                     tvb, offset, 2, FALSE);
1024                 per_conversation_info->num_client_message_types = tvb_get_ntohs(tvb, offset);
1025                 offset += 2;
1026
1027                 proto_tree_add_item(tree, hf_vnc_num_encoding_types,
1028                                     tvb, offset, 2, FALSE);
1029                 per_conversation_info->num_encoding_types = tvb_get_ntohs(tvb, offset);
1030                 offset += 2;
1031
1032                 proto_tree_add_item(tree, hf_vnc_padding, tvb, offset, 2,
1033                                     FALSE);
1034                 offset += 2;
1035
1036                 per_conversation_info->vnc_next_state = TIGHT_INTERACTION_CAPS_LIST;
1037                 break;
1038
1039         case TIGHT_INTERACTION_CAPS_LIST:
1040                 if (check_col(pinfo->cinfo, COL_INFO))
1041                         col_set_str(pinfo->cinfo, COL_INFO,
1042                                     "TightVNC Interaction Capabilities list");
1043
1044                 offset = process_tight_capabilities(tree,
1045                                                     hf_vnc_tight_server_message_type,
1046                                                     hf_vnc_tight_server_vendor,
1047                                                     hf_vnc_tight_server_name,
1048                                                     tvb, offset, per_conversation_info->num_server_message_types);
1049                 offset = process_tight_capabilities(tree,
1050                                                     hf_vnc_tight_client_message_type,
1051                                                     hf_vnc_tight_client_vendor,
1052                                                     hf_vnc_tight_client_name,
1053                                                     tvb, offset, per_conversation_info->num_client_message_types);
1054                 offset = process_tight_capabilities(tree,
1055                                                     hf_vnc_tight_encoding_type,
1056                                                     hf_vnc_tight_encoding_vendor,
1057                                                     hf_vnc_tight_encoding_name,
1058                                                     tvb, offset, per_conversation_info->num_encoding_types);
1059
1060                 per_conversation_info->vnc_next_state = NORMAL_TRAFFIC;
1061                 break;
1062
1063         case NORMAL_TRAFFIC :
1064                 return FALSE;
1065         }
1066
1067         return TRUE;
1068 }
1069
1070
1071 static void
1072 vnc_client_to_server(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1073                      proto_tree *tree)
1074 {
1075         guint8 message_type;
1076
1077         proto_item *ti=NULL;
1078         proto_tree *vnc_client_message_type_tree;
1079
1080         message_type = tvb_get_guint8(tvb, *offset);
1081
1082         ti = proto_tree_add_item(tree, hf_vnc_client_message_type, tvb,
1083                                  *offset, 1, FALSE);
1084
1085         vnc_client_message_type_tree =
1086                 proto_item_add_subtree(ti, ett_vnc_client_message_type);
1087
1088         *offset += 1;
1089
1090         switch(message_type) {
1091                 
1092         case 0 :
1093                 vnc_client_set_pixel_format(tvb, pinfo, offset,
1094                                             vnc_client_message_type_tree);
1095                 break;
1096
1097         case 2 :
1098                 vnc_client_set_encodings(tvb, pinfo, offset,
1099                                          vnc_client_message_type_tree);
1100                 break;
1101
1102         case 3 :
1103                 vnc_client_framebuffer_update_request(tvb, pinfo, offset,
1104                                                       vnc_client_message_type_tree);
1105                 break;
1106
1107         case 4 :
1108                 vnc_client_key_event(tvb, pinfo, offset,
1109                                      vnc_client_message_type_tree);
1110                 break;
1111
1112         case 5:
1113                 vnc_client_pointer_event(tvb, pinfo, offset,
1114                                          vnc_client_message_type_tree);
1115                 break;
1116
1117         case 6 :
1118                 vnc_client_cut_text(tvb, pinfo, offset,
1119                                     vnc_client_message_type_tree);
1120                 break;
1121
1122         default :
1123                 if (check_col(pinfo->cinfo, COL_INFO))
1124                         col_append_fstr(pinfo->cinfo, COL_INFO,
1125                                         "Unknown client message type (%u)",
1126                                         message_type);
1127                 break;
1128         }
1129 }
1130
1131 static void
1132 vnc_server_to_client(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1133                      proto_tree *tree)
1134 {
1135         gint start_offset;
1136         guint8 message_type;
1137         gint bytes_needed = 0, length_remaining;
1138         
1139         proto_item *ti=NULL;
1140         proto_tree *vnc_server_message_type_tree;
1141
1142         start_offset = *offset;
1143
1144         message_type = tvb_get_guint8(tvb, *offset);
1145
1146         ti = proto_tree_add_item(tree, hf_vnc_server_message_type, tvb,
1147                                  *offset, 1, FALSE);
1148         vnc_server_message_type_tree =
1149                 proto_item_add_subtree(ti, ett_vnc_server_message_type);
1150
1151         *offset += 1;
1152
1153         switch(message_type) {
1154
1155         case 0 :
1156                 bytes_needed =
1157                         vnc_server_framebuffer_update(tvb, pinfo, offset,
1158                                                       vnc_server_message_type_tree);
1159                 break;
1160
1161         case 1 :
1162                 bytes_needed = vnc_server_set_colormap_entries(tvb, pinfo, offset, vnc_server_message_type_tree);
1163                 break;
1164
1165         case 2 :
1166                 vnc_server_ring_bell(tvb, pinfo, offset,
1167                                      vnc_server_message_type_tree);
1168                 break;
1169
1170         case 3 :
1171                 bytes_needed = vnc_server_cut_text(tvb, pinfo, offset,
1172                                                    vnc_server_message_type_tree);
1173                 break;
1174
1175         default :
1176                 if (check_col(pinfo->cinfo, COL_INFO))
1177                         col_append_str(pinfo->cinfo, COL_INFO,
1178                                        "Unknown server message type");
1179                 break;
1180         }
1181
1182         if(bytes_needed > 0 && vnc_preference_desegment &&
1183            pinfo->can_desegment) {
1184                 length_remaining = tvb_length_remaining(tvb, *offset);
1185
1186                 pinfo->desegment_offset = start_offset;
1187                 pinfo->desegment_len = bytes_needed - length_remaining;
1188                 return;
1189         }
1190 }
1191
1192
1193 static void
1194 vnc_client_set_pixel_format(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1195                             proto_tree *tree)
1196 {
1197         if (check_col(pinfo->cinfo, COL_INFO))
1198                 col_set_str(pinfo->cinfo, COL_INFO, "Client set pixel format");
1199         
1200         proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset,
1201                             3, FALSE);
1202         *offset += 3; /* Skip over 3 bytes of padding */
1203                 
1204         proto_tree_add_item(tree, hf_vnc_client_bits_per_pixel, tvb, *offset,
1205                             1, FALSE);
1206         vnc_bytes_per_pixel = tvb_get_guint8(tvb, *offset)/8;
1207         vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
1208         *offset += 1;
1209
1210         proto_tree_add_item(tree, hf_vnc_client_depth, tvb, *offset,
1211                             1, FALSE);
1212         vnc_depth = tvb_get_guint8(tvb, *offset);
1213         vnc_set_depth(pinfo, vnc_depth);
1214         *offset += 1;
1215
1216         proto_tree_add_item(tree, hf_vnc_client_big_endian_flag, tvb, *offset,
1217                             1, FALSE);
1218         *offset += 1;
1219
1220         proto_tree_add_item(tree, hf_vnc_client_true_color_flag, tvb, *offset,
1221                             1, FALSE);
1222         *offset += 1;
1223
1224         proto_tree_add_item(tree, hf_vnc_client_red_max, tvb, *offset,
1225                             2, FALSE);
1226         *offset += 2;
1227
1228         proto_tree_add_item(tree, hf_vnc_client_green_max, tvb, *offset,
1229                             2, FALSE);
1230         *offset += 2;
1231
1232         proto_tree_add_item(tree, hf_vnc_client_blue_max, tvb, *offset,
1233                             2, FALSE);
1234         *offset += 2;
1235
1236         proto_tree_add_item(tree, hf_vnc_client_red_shift, tvb, *offset,
1237                             1, FALSE);
1238         *offset += 1;
1239
1240         proto_tree_add_item(tree, hf_vnc_client_green_shift, tvb, *offset,
1241                             1, FALSE);
1242         *offset += 1;
1243
1244         proto_tree_add_item(tree, hf_vnc_client_blue_shift, tvb, *offset,
1245                             1, FALSE);
1246         *offset += 1;
1247
1248         proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset,
1249                             3, FALSE);
1250         *offset += 3; /* Skip over 3 bytes of padding */
1251 }
1252
1253
1254 static void
1255 vnc_client_set_encodings(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1256                          proto_tree *tree)
1257 {
1258         guint16 number_of_encodings;
1259         guint counter;
1260         vnc_packet_t *per_packet_info;
1261
1262         per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
1263
1264         if (check_col(pinfo->cinfo, COL_INFO))
1265                 col_set_str(pinfo->cinfo, COL_INFO, "Client set encodings");
1266
1267         proto_tree_add_item(tree, hf_vnc_padding,
1268                             tvb, *offset, 1, FALSE);
1269         *offset += 1; /* Skip over 1 byte of padding */
1270
1271         number_of_encodings = tvb_get_ntohs(tvb, *offset);
1272
1273         proto_tree_add_text(tree, tvb, *offset, 2,
1274                             "Number of encodings: %d", number_of_encodings);
1275         *offset += 2;
1276
1277         per_packet_info->preferred_encoding = -1;
1278
1279         for(counter = 1; counter <= number_of_encodings; counter++) {
1280                 proto_tree_add_item(tree,
1281                                     hf_vnc_client_set_encodings_encoding_type,
1282                                     tvb, *offset, 4, FALSE);
1283
1284                 /* Remember the first real encoding as the preferred encoding,
1285                  * per xserver/hw/vnc/rfbserver.c:rfbProcessClientNormalMessage().
1286                  * Otherwise, use RAW as the preferred encoding.
1287                  */
1288                 if (per_packet_info->preferred_encoding == -1) {
1289                         int encoding;
1290
1291                         encoding = tvb_get_ntohl(tvb, *offset);
1292
1293                         switch(encoding) {
1294                         case ENCODING_RAW:
1295                         case ENCODING_RRE:
1296                         case ENCODING_CORRE:
1297                         case ENCODING_HEXTILE:
1298                         case ENCODING_ZLIB:
1299                         case ENCODING_TIGHT:
1300                                 per_packet_info->preferred_encoding = encoding;
1301                                 break;
1302                         }
1303                 }
1304
1305                 *offset += 4;
1306         }
1307
1308         if (per_packet_info->preferred_encoding == -1)
1309                 per_packet_info->preferred_encoding = ENCODING_RAW;
1310 }
1311
1312
1313 static void
1314 vnc_client_framebuffer_update_request(tvbuff_t *tvb, packet_info *pinfo,
1315                                       gint *offset, proto_tree *tree)
1316 {
1317         if (check_col(pinfo->cinfo, COL_INFO))
1318                 col_set_str(pinfo->cinfo, COL_INFO,
1319                             "Client framebuffer update request");
1320
1321         proto_tree_add_item(tree, hf_vnc_update_req_incremental,
1322                             tvb, *offset, 1, FALSE);
1323         *offset += 1;
1324
1325         proto_tree_add_item(tree, hf_vnc_update_req_x_pos,
1326                             tvb, *offset, 2, FALSE);
1327         *offset += 2;
1328
1329         proto_tree_add_item(tree, hf_vnc_update_req_y_pos,
1330                             tvb, *offset, 2, FALSE);
1331         *offset += 2;
1332
1333         proto_tree_add_item(tree, hf_vnc_update_req_width, tvb,
1334                             *offset, 2, FALSE);
1335         *offset += 2;
1336
1337         proto_tree_add_item(tree, hf_vnc_update_req_height, tvb,
1338                             *offset, 2, FALSE);
1339         *offset += 2;
1340 }
1341
1342
1343 static void
1344 vnc_client_key_event(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1345                      proto_tree *tree)
1346 {
1347         if (check_col(pinfo->cinfo, COL_INFO))
1348                 col_set_str(pinfo->cinfo, COL_INFO, "Client key event");
1349         
1350         proto_tree_add_item(tree, hf_vnc_key_down, tvb, *offset, 1, FALSE);
1351         *offset += 1;
1352         
1353         proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 2, FALSE);
1354         *offset += 2; /* Skip over 2 bytes of padding */
1355         
1356         proto_tree_add_item(tree, hf_vnc_key, tvb, *offset, 4, FALSE);
1357         *offset += 4;
1358 }
1359
1360
1361 static void
1362 vnc_client_pointer_event(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1363                          proto_tree *tree)
1364 {
1365         if (check_col(pinfo->cinfo, COL_INFO))
1366                 col_set_str(pinfo->cinfo, COL_INFO, "Client pointer event");
1367         
1368         proto_tree_add_item(tree, hf_vnc_button_1_pos, tvb, *offset, 1, FALSE);
1369         proto_tree_add_item(tree, hf_vnc_button_2_pos, tvb, *offset, 1, FALSE);
1370         proto_tree_add_item(tree, hf_vnc_button_3_pos, tvb, *offset, 1, FALSE);
1371         proto_tree_add_item(tree, hf_vnc_button_4_pos, tvb, *offset, 1, FALSE);
1372         proto_tree_add_item(tree, hf_vnc_button_5_pos, tvb, *offset, 1, FALSE);
1373         proto_tree_add_item(tree, hf_vnc_button_6_pos, tvb, *offset, 1, FALSE);
1374         proto_tree_add_item(tree, hf_vnc_button_7_pos, tvb, *offset, 1, FALSE);
1375         proto_tree_add_item(tree, hf_vnc_button_8_pos, tvb, *offset, 1, FALSE);
1376         *offset += 1;
1377         
1378         proto_tree_add_item(tree, hf_vnc_pointer_x_pos, tvb, *offset, 2, FALSE);
1379         *offset += 2;
1380         
1381         proto_tree_add_item(tree, hf_vnc_pointer_y_pos, tvb, *offset, 2, FALSE);
1382         *offset += 2;
1383 }
1384
1385
1386 static void
1387 vnc_client_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1388                     proto_tree *tree)
1389 {
1390         guint32 text_len;
1391
1392         if (check_col(pinfo->cinfo, COL_INFO))
1393                 col_set_str(pinfo->cinfo, COL_INFO, "Client cut text");
1394
1395         proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 3, FALSE);
1396         *offset += 3; /* Skip over 3 bytes of padding */
1397
1398         text_len = tvb_get_ntohl(tvb, *offset);
1399         proto_tree_add_item(tree, hf_vnc_client_cut_text_len, tvb, *offset, 4,
1400                             FALSE);
1401         *offset += 4;
1402
1403         proto_tree_add_item(tree, hf_vnc_client_cut_text, tvb, *offset,
1404                             text_len, FALSE);
1405         *offset += text_len;
1406
1407 }
1408
1409
1410 static guint
1411 vnc_server_framebuffer_update(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1412                               proto_tree *tree)
1413 {
1414         gint num_rects, i;
1415         guint16 width, height;
1416         guint bytes_needed = 0;
1417         gint32 encoding_type;
1418         proto_item *ti, *ti_x, *ti_y, *ti_width, *ti_height;
1419         proto_tree *vnc_rect_tree, *vnc_encoding_type_tree;
1420         
1421         if (check_col(pinfo->cinfo, COL_INFO))
1422                 col_set_str(pinfo->cinfo, COL_INFO,
1423                             "Server framebuffer update");       
1424
1425         proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 1, FALSE);
1426         *offset += 1;
1427         
1428         num_rects = tvb_get_ntohs(tvb, *offset);
1429         proto_tree_add_text(tree, tvb, *offset, 2, "Number of rectangles: %d",
1430                             num_rects);
1431         *offset += 2;
1432         
1433         for(i = 1; i <= num_rects; i++) {
1434
1435                 VNC_BYTES_NEEDED(12);
1436
1437                 ti = proto_tree_add_text(tree, tvb, *offset, 12,
1438                                          "Rectangle #%d", i);
1439
1440                 vnc_rect_tree =
1441                         proto_item_add_subtree(ti, ett_vnc_rect);
1442
1443                 ti_x = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_x_pos,
1444                                            tvb, *offset, 2, FALSE);
1445                 *offset += 2;
1446                 
1447                 ti_y = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_y_pos,
1448                                            tvb, *offset, 2, FALSE);
1449                 *offset += 2;
1450                 
1451                 ti_width = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_width,
1452                                                tvb, *offset, 2, FALSE);
1453                 width = tvb_get_ntohs(tvb, *offset);
1454                 *offset += 2;
1455                 
1456                 ti_height = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_height,
1457                                                 tvb, *offset, 2, FALSE);
1458                 height = tvb_get_ntohs(tvb, *offset);
1459                 *offset += 2;
1460
1461                 ti = proto_tree_add_item(vnc_rect_tree,
1462                                          hf_vnc_fb_update_encoding_type,
1463                                          tvb, *offset, 4, FALSE);
1464
1465                 encoding_type = tvb_get_ntohl(tvb, *offset);
1466                 *offset += 4;
1467
1468                 if (encoding_type == ENCODING_LAST_RECT)
1469                         break; /* exit the loop */
1470
1471                 vnc_encoding_type_tree =
1472                         proto_item_add_subtree(ti, ett_vnc_encoding_type);
1473
1474                 switch(encoding_type) {
1475                         
1476                 case ENCODING_RAW:
1477                         bytes_needed = vnc_raw_encoding(tvb, pinfo, offset,
1478                                                         vnc_encoding_type_tree,
1479                                                         width, height);
1480                         break;
1481                         
1482                 case ENCODING_COPY_RECT:
1483                         bytes_needed =
1484                                 vnc_copyrect_encoding(tvb, pinfo, offset,
1485                                                       vnc_encoding_type_tree,
1486                                                       width, height);
1487                         break;
1488                         
1489                 case ENCODING_RRE:
1490                         bytes_needed = 
1491                                 vnc_rre_encoding(tvb, pinfo, offset,
1492                                                  vnc_encoding_type_tree,
1493                                                  width, height);
1494                         break;
1495                         
1496                 case ENCODING_HEXTILE:
1497                         bytes_needed =
1498                                 vnc_hextile_encoding(tvb, pinfo, offset,
1499                                                      vnc_encoding_type_tree,
1500                                                      width, height);
1501                         break;
1502                         
1503                 case ENCODING_RLE:
1504                         bytes_needed =
1505                                 vnc_zrle_encoding(tvb, pinfo, offset,
1506                                                   vnc_encoding_type_tree,
1507                                                   width, height);
1508                         break;
1509
1510                 case ENCODING_TIGHT:
1511                         bytes_needed =
1512                                 vnc_tight_encoding(tvb, pinfo, offset,
1513                                                    vnc_encoding_type_tree,
1514                                                    width, height);
1515                         break;
1516
1517                 case ENCODING_RICH_CURSOR:
1518                 case ENCODING_X_CURSOR:
1519                         proto_item_append_text (ti_x,      " (hotspot X)");
1520                         proto_item_append_text (ti_y,      " (hotspot Y)");
1521                         proto_item_append_text (ti_width,  " (cursor width)");
1522                         proto_item_append_text (ti_height, " (cursor height)");
1523
1524                         if (encoding_type == ENCODING_RICH_CURSOR)
1525                                 bytes_needed = vnc_rich_cursor_encoding(tvb, pinfo, offset, vnc_encoding_type_tree, width, height);
1526                         else
1527                                 bytes_needed = vnc_x_cursor_encoding(tvb, pinfo, offset, vnc_encoding_type_tree, width, height);
1528
1529                         break;
1530
1531                 case ENCODING_POINTER_POS:
1532                         proto_item_append_text (ti_x,      " (pointer X)");
1533                         proto_item_append_text (ti_y,      " (pointer Y)");
1534                         proto_item_append_text (ti_width,  " (unused)");
1535                         proto_item_append_text (ti_height, " (unused)");
1536                         bytes_needed = 0;
1537                         break;
1538
1539                 case ENCODING_DESKTOP_SIZE:
1540
1541                         /* There is no payload for this message type */
1542
1543                         bytes_needed = 0;
1544                         break;
1545
1546                 }
1547
1548                 /* Check if the routines above requested more bytes to
1549                  * be desegmented. */
1550                 if(bytes_needed > 0)
1551                         return bytes_needed;
1552         }
1553
1554         return 0;
1555 }
1556
1557
1558 static guint
1559 vnc_raw_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1560                  proto_tree *tree, guint16 width, guint16 height)
1561 {
1562         guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1563         guint length;
1564
1565         length = width * height * bytes_per_pixel;
1566         VNC_BYTES_NEEDED(length);
1567
1568         proto_tree_add_item(tree, hf_vnc_raw_pixel_data, tvb, *offset, 
1569                             length, FALSE);
1570         *offset += length;
1571
1572         return 0; /* bytes_needed */
1573 }
1574
1575
1576 static guint
1577 vnc_copyrect_encoding(tvbuff_t *tvb, packet_info *pinfo _U_, gint *offset,
1578                       proto_tree *tree, guint16 width _U_, guint16 height _U_)
1579 {
1580         proto_tree_add_item(tree, hf_vnc_copyrect_src_x_pos, tvb, *offset, 
1581                             2, FALSE);
1582         *offset += 2;
1583
1584         proto_tree_add_item(tree, hf_vnc_copyrect_src_y_pos, tvb, *offset, 
1585                             2, FALSE);
1586         *offset += 2;
1587
1588         return 0; /* bytes_needed */
1589 }
1590
1591
1592 static guint
1593 vnc_rre_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1594                  proto_tree *tree, guint16 width _U_, guint16 height _U_)
1595 {
1596         guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1597         guint32 num_subrects, i;
1598         guint bytes_needed;
1599         proto_item *ti;
1600         proto_tree *subrect_tree;
1601
1602         VNC_BYTES_NEEDED(4);
1603         proto_tree_add_item(tree, hf_vnc_rre_num_subrects, tvb, *offset, 
1604                             4, FALSE);
1605         num_subrects = tvb_get_ntohl(tvb, *offset);
1606         *offset += 4;
1607
1608         VNC_BYTES_NEEDED(bytes_per_pixel);
1609         proto_tree_add_item(tree, hf_vnc_rre_bg_pixel, tvb, *offset, 
1610                             bytes_per_pixel, FALSE);
1611         *offset += bytes_per_pixel;
1612
1613         for(i = 1; i <= num_subrects; i++) {
1614                 bytes_needed = bytes_per_pixel + 8;
1615                 VNC_BYTES_NEEDED(bytes_needed);
1616
1617                 ti = proto_tree_add_text(tree, tvb, *offset, bytes_per_pixel +
1618                                          8, "Subrectangle #%d", i);
1619                 subrect_tree =
1620                         proto_item_add_subtree(ti, ett_vnc_rre_subrect);
1621
1622                 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_pixel,
1623                                     tvb, *offset, bytes_per_pixel, FALSE);
1624                 *offset += bytes_per_pixel;
1625
1626                 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_x_pos,
1627                                     tvb, *offset, 2, FALSE);
1628                 *offset += 2;
1629
1630                 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_y_pos,
1631                                     tvb, *offset, 2, FALSE);
1632                 *offset += 2;
1633
1634                 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_width,
1635                                     tvb, *offset, 2, FALSE);
1636                 *offset += 2;
1637
1638                 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_height,
1639                                     tvb, *offset, 2, FALSE);
1640                 *offset += 2;
1641         }
1642
1643         return 0; /* bytes_needed */
1644 }
1645
1646
1647 static guint
1648 vnc_hextile_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1649                      proto_tree *tree, guint16 width, guint16 height)
1650 {
1651         guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1652         guint8 i, subencoding_mask, num_subrects, subrect_len;
1653         guint length;
1654         proto_tree *subencoding_mask_tree, *subrect_tree, *num_subrects_tree;
1655         proto_item *ti;
1656
1657         VNC_BYTES_NEEDED(1);
1658         ti = proto_tree_add_item(tree, hf_vnc_hextile_subencoding_mask, tvb,
1659                                  *offset, 1, FALSE);
1660         subencoding_mask = tvb_get_guint8(tvb, *offset);
1661
1662         subencoding_mask_tree =
1663                 proto_item_add_subtree(ti, ett_vnc_hextile_subencoding_mask);
1664
1665         proto_tree_add_item(subencoding_mask_tree,
1666                             hf_vnc_hextile_raw, tvb, *offset, 1,
1667                             FALSE);
1668         proto_tree_add_item(subencoding_mask_tree,
1669                             hf_vnc_hextile_bg, tvb, *offset, 1,
1670                             FALSE);
1671         proto_tree_add_item(subencoding_mask_tree,
1672                             hf_vnc_hextile_fg, tvb, *offset, 1,
1673                             FALSE);
1674         proto_tree_add_item(subencoding_mask_tree,
1675                             hf_vnc_hextile_anysubrects, tvb, *offset, 1,
1676                             FALSE);
1677         proto_tree_add_item(subencoding_mask_tree,
1678                             hf_vnc_hextile_subrectscolored, tvb, *offset, 1,
1679                             FALSE);
1680         *offset += 1;
1681         
1682         if(subencoding_mask & 0x1) { /* Raw */
1683                 length = width * height * bytes_per_pixel;
1684
1685                 VNC_BYTES_NEEDED(length);
1686
1687                 proto_tree_add_item(tree, hf_vnc_hextile_raw_value, tvb,
1688                                     *offset, length, FALSE);
1689                 *offset += length;
1690         } else { 
1691                 if(subencoding_mask & 0x2) { /* Background Specified */
1692                         proto_tree_add_item(tree, hf_vnc_hextile_bg_value,
1693                                             tvb, *offset, bytes_per_pixel,
1694                                             FALSE);
1695                         *offset += bytes_per_pixel;
1696                 }
1697
1698                 if(subencoding_mask & 0x4) { /* Foreground Specified */
1699                         proto_tree_add_item(tree, hf_vnc_hextile_fg_value,
1700                                             tvb, *offset, bytes_per_pixel,
1701                                             FALSE);
1702                         *offset += bytes_per_pixel;
1703                 }
1704
1705                 if(subencoding_mask & 0x8) { /* Any Subrects */
1706                         ti = proto_tree_add_item(tree,
1707                                                  hf_vnc_hextile_num_subrects,
1708                                                  tvb, *offset, 1,
1709                                                  FALSE);
1710                         num_subrects = tvb_get_guint8(tvb, *offset);
1711                         *offset += 1;
1712                         
1713                         num_subrects_tree =
1714                                 proto_item_add_subtree(ti, ett_vnc_hextile_num_subrects);
1715
1716                         for(i = 1; i <= num_subrects; i++) {
1717
1718                                 if(subencoding_mask & 0x16) 
1719                                         subrect_len = bytes_per_pixel + 2;
1720                                 else
1721                                         subrect_len = 2;
1722
1723                                 ti = proto_tree_add_text(num_subrects_tree, tvb,
1724                                                          *offset, subrect_len,
1725                                                          "Subrectangle #%d", i);
1726
1727                                 subrect_tree = 
1728                                         proto_item_add_subtree(ti, ett_vnc_hextile_subrect);
1729
1730                                 if(subencoding_mask & 0x16) {
1731                                         /* Subrects Colored */
1732                                         proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_pixel_value, tvb, *offset, bytes_per_pixel, FALSE);
1733                                         
1734                                         *offset += bytes_per_pixel;
1735                                 }
1736
1737                                 proto_tree_add_item(subrect_tree,
1738                                                     hf_vnc_hextile_subrect_x_pos, tvb, *offset, 1, FALSE);
1739
1740                                 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_y_pos, tvb, *offset, 1, FALSE);
1741
1742                                 *offset += 1;
1743
1744                                 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_width, tvb, *offset, 1, FALSE);
1745
1746                                 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_height, tvb, *offset, 1, FALSE);
1747
1748                                 *offset += 1;
1749                         }
1750                 }
1751         }
1752
1753         return 0; /* bytes_needed */
1754 }
1755
1756 #ifdef HAVE_LIBZ
1757 static guint
1758 vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1759                   proto_tree *tree, guint16 width, guint16 height)
1760 #else
1761 static guint
1762 vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo _U_, gint *offset,
1763                   proto_tree *tree, guint16 width _U_, guint16 height _U_)
1764 #endif
1765 {
1766         guint32 data_len;
1767 #ifdef HAVE_LIBZ
1768         guint8 palette_size;
1769         guint8 bytes_per_cpixel = vnc_get_bytes_per_pixel(pinfo);
1770         gint uncomp_offset = 0;
1771         guint length;
1772         gint subencoding_type;
1773         tvbuff_t *uncomp_tvb = NULL;
1774         proto_tree *zrle_subencoding_tree;
1775         proto_item *ti;
1776 #endif
1777
1778         VNC_BYTES_NEEDED(4);
1779         proto_tree_add_item(tree, hf_vnc_zrle_len, tvb, *offset, 
1780                             4, FALSE);
1781         data_len = tvb_get_ntohl(tvb, *offset);
1782
1783         *offset += 4;
1784
1785         VNC_BYTES_NEEDED(data_len);
1786
1787         proto_tree_add_item(tree, hf_vnc_zrle_data, tvb, *offset,
1788                             data_len, FALSE);
1789
1790 #ifdef HAVE_LIBZ
1791         uncomp_tvb = tvb_uncompress(tvb, *offset, data_len);
1792
1793         if(uncomp_tvb != NULL) {
1794                 tvb_set_child_real_data_tvbuff(tvb, uncomp_tvb);
1795                 add_new_data_source(pinfo, uncomp_tvb,
1796                                     "Uncompressed ZRLE data");
1797
1798                 ti = proto_tree_add_item(tree, hf_vnc_zrle_subencoding,
1799                                          uncomp_tvb, uncomp_offset, 1, FALSE);
1800                 zrle_subencoding_tree =
1801                         proto_item_add_subtree(ti, ett_vnc_zrle_subencoding);
1802
1803                 proto_tree_add_item(zrle_subencoding_tree, hf_vnc_zrle_rle,
1804                                     uncomp_tvb, uncomp_offset, 1, FALSE);
1805
1806                 proto_tree_add_item(zrle_subencoding_tree,
1807                                     hf_vnc_zrle_palette_size, uncomp_tvb,
1808                                     uncomp_offset, 1, FALSE);
1809
1810                 subencoding_type = tvb_get_guint8(uncomp_tvb, uncomp_offset);
1811                 palette_size = subencoding_type & 0x7F;
1812
1813                 uncomp_offset += 1;
1814
1815                 if(subencoding_type == 0) { /* Raw */
1816                         length = width * height * bytes_per_cpixel;
1817                         VNC_BYTES_NEEDED(length);
1818
1819                         /* XXX - not working yet! */
1820
1821                         proto_tree_add_item(zrle_subencoding_tree,
1822                                             hf_vnc_zrle_raw, uncomp_tvb,
1823                                             uncomp_offset, length, FALSE);
1824
1825                 } else if(subencoding_type >= 130 && subencoding_type <= 255) {
1826                         length = palette_size * bytes_per_cpixel;
1827                         VNC_BYTES_NEEDED(length);
1828
1829                         proto_tree_add_item(zrle_subencoding_tree,
1830                                             hf_vnc_zrle_palette, uncomp_tvb,
1831                                             uncomp_offset, length, FALSE);
1832                 
1833                         /* XXX - Not complete! */
1834                 }
1835                         
1836         } else {
1837                 proto_tree_add_text(tree, tvb, *offset, data_len,
1838                                     "Decompression of ZRLE data failed");
1839         }
1840 #endif /* HAVE_LIBZ */
1841         
1842         *offset += data_len;
1843
1844         return 0; /* bytes_needed */
1845 }
1846
1847
1848 static guint
1849 read_compact_len(tvbuff_t *tvb, gint *offset, gint *length, gint *value_length)
1850 {
1851         gint b;
1852
1853         VNC_BYTES_NEEDED(1);
1854
1855         *value_length = 0;
1856
1857         b = tvb_get_guint8(tvb, *offset);
1858         *offset += 1;
1859         *value_length += 1;
1860
1861         *length = b & 0x7f;
1862         if ((b & 0x80) != 0) {
1863                 VNC_BYTES_NEEDED(1);
1864
1865                 b = tvb_get_guint8(tvb, *offset);
1866                 *offset += 1;
1867                 *value_length += 1;
1868
1869                 *length |= (b & 0x7f) << 7;
1870
1871                 if ((b & 0x80) != 0) {
1872                         VNC_BYTES_NEEDED (1);
1873
1874                         b = tvb_get_guint8(tvb, *offset);
1875                         *offset += 1;
1876                         *value_length += 1;
1877
1878                         *length |= (b & 0xff) << 14;
1879                 }
1880         }
1881
1882         return 0;
1883 }
1884
1885
1886 static guint
1887 process_compact_length_and_image_data(tvbuff_t *tvb, gint *offset, proto_tree *tree)
1888 {
1889         guint bytes_needed;
1890         guint length, value_length;
1891
1892         bytes_needed = read_compact_len (tvb, offset, &length, &value_length);
1893         if (bytes_needed != 0)
1894                 return bytes_needed;
1895
1896         proto_tree_add_uint(tree, hf_vnc_tight_image_len, tvb, *offset - value_length, value_length, length);
1897
1898         VNC_BYTES_NEEDED(length);
1899         proto_tree_add_item(tree, hf_vnc_tight_image_data, tvb, *offset, length, FALSE);
1900         *offset += length;
1901
1902         return 0; /* bytes_needed */
1903 }
1904
1905
1906 static guint
1907 process_tight_rect_filter_palette(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1908                                   proto_tree *tree, gint *bits_per_pixel)
1909 {
1910         vnc_packet_t *per_packet_info;
1911         gint num_colors;
1912         guint palette_bytes;
1913
1914         /* See TightVNC's vnc_unixsrc/vncviewer/tight.c:InitFilterPaletteBPP() */
1915
1916         per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
1917
1918         VNC_BYTES_NEEDED(1);
1919         proto_tree_add_item(tree, hf_vnc_tight_palette_num_colors, tvb, *offset, 1, FALSE);
1920         num_colors = tvb_get_guint8(tvb, *offset);
1921         *offset += 1;
1922
1923         num_colors++;
1924         if (num_colors < 2)
1925                 return 0;
1926
1927         if (per_packet_info->depth == 24)
1928                 palette_bytes = num_colors * 3;
1929         else
1930                 palette_bytes = num_colors * per_packet_info->depth / 8;
1931
1932         VNC_BYTES_NEEDED(palette_bytes);
1933         proto_tree_add_item(tree, hf_vnc_tight_palette_data, tvb, *offset, palette_bytes, FALSE);
1934         *offset += palette_bytes;
1935
1936         /* This is the number of bits per pixel *in the image data*, not the actual client depth */
1937         if (num_colors == 2)
1938                 *bits_per_pixel = 1;
1939         else
1940                 *bits_per_pixel = 8;
1941
1942         return 0;
1943 }
1944
1945 static guint
1946 vnc_tight_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1947                    proto_tree *tree, guint16 width, guint16 height)
1948 {
1949         vnc_packet_t *per_packet_info;
1950         guint8 comp_ctl;
1951         proto_item *compression_type_ti;
1952         gint bit_offset;
1953         gint bytes_needed = -1;
1954
1955         /* unused arguments */
1956         (void) width;
1957         (void) height;
1958
1959         per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
1960
1961         /* See xserver/hw/vnc/rfbproto.h and grep for "Tight Encoding." for the following layout */
1962
1963         VNC_BYTES_NEEDED(1);
1964
1965         /* least significant bits 0-3 are "reset compression stream N" */
1966         bit_offset = *offset * 8;
1967         proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream0, tvb, bit_offset + 7, 1, FALSE);
1968         proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream1, tvb, bit_offset + 6, 1, FALSE);
1969         proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream2, tvb, bit_offset + 5, 1, FALSE);
1970         proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream3, tvb, bit_offset + 4, 1, FALSE);
1971
1972         /* most significant bits 4-7 are "compression type" */
1973         compression_type_ti = proto_tree_add_bits_item(tree, hf_vnc_tight_rect_type, tvb, bit_offset + 0, 4, FALSE);
1974
1975         comp_ctl = tvb_get_guint8(tvb, *offset);
1976         *offset += 1;
1977
1978         comp_ctl >>= 4; /* skip over the "reset compression" bits from above */
1979
1980         /* compression format */
1981
1982         if (comp_ctl == TIGHT_RECT_FILL) {
1983                 /* "fill" encoding (solid rectangle) */
1984
1985                 proto_item_append_text(compression_type_ti, " (fill encoding - solid rectangle)");
1986
1987                 if (per_packet_info->depth == 24) {
1988                         VNC_BYTES_NEEDED(3);
1989                         proto_tree_add_item(tree, hf_vnc_tight_fill_color, tvb, *offset, 3, FALSE);
1990                         *offset += 3;
1991                 } else {
1992                         VNC_BYTES_NEEDED(per_packet_info->bytes_per_pixel);
1993                         proto_tree_add_item(tree, hf_vnc_tight_fill_color, tvb, *offset, per_packet_info->bytes_per_pixel, FALSE);
1994                         *offset += per_packet_info->bytes_per_pixel;
1995                 }
1996
1997                 bytes_needed = 0;
1998         } else if (comp_ctl == TIGHT_RECT_JPEG) {
1999                 /* jpeg encoding */
2000
2001                 proto_item_append_text(compression_type_ti, " (JPEG encoding)");
2002                 bytes_needed = process_compact_length_and_image_data(tvb, offset, tree);
2003                 if (bytes_needed != 0)
2004                         return bytes_needed;
2005         } else if (comp_ctl > TIGHT_RECT_MAX_VALUE) {
2006                 /* invalid encoding */
2007
2008                 proto_item_append_text(compression_type_ti, " (invalid encoding)");
2009                 DISSECTOR_ASSERT_NOT_REACHED();
2010         } else {
2011                 guint row_size;
2012                 gint bits_per_pixel;
2013
2014                 /* basic encoding */
2015
2016                 proto_item_append_text(compression_type_ti, " (basic encoding)");
2017
2018                 proto_tree_add_bits_item(tree, hf_vnc_tight_filter_flag, tvb, bit_offset + 1, 1, FALSE);
2019
2020                 bits_per_pixel = per_packet_info->depth;
2021
2022                 if ((comp_ctl & TIGHT_RECT_EXPLICIT_FILTER_FLAG) != 0) {
2023                         guint8 filter_id;
2024
2025                         /* explicit filter */
2026
2027                         VNC_BYTES_NEEDED(1);
2028                         proto_tree_add_item(tree, hf_vnc_tight_filter_id, tvb, *offset, 1, FALSE);
2029                         filter_id = tvb_get_guint8(tvb, *offset);
2030                         *offset += 1;
2031
2032                         switch (filter_id) {
2033                         case TIGHT_RECT_FILTER_COPY:
2034                                 /* nothing to do */
2035                                 break;
2036
2037                         case TIGHT_RECT_FILTER_PALETTE:
2038                                 bytes_needed = process_tight_rect_filter_palette(tvb, pinfo, offset, tree, &bits_per_pixel);
2039                                 if (bytes_needed != 0)
2040                                         return bytes_needed;
2041
2042                                 break;
2043
2044                         case TIGHT_RECT_FILTER_GRADIENT:
2045                                 /* nothing to do */
2046                                 break;
2047                         }
2048                 } else {
2049                         /* this is the same case as TIGHT_RECT_FILTER_COPY, so there's nothing special to do */
2050                 }
2051
2052                 row_size = ((guint) width * bits_per_pixel + 7) / 8;
2053                 if (row_size * height < TIGHT_MIN_BYTES_TO_COMPRESS) {
2054                         guint num_bytes;
2055
2056                         /* The data is not compressed; just skip over it */
2057
2058                         num_bytes = row_size * height;
2059                         VNC_BYTES_NEEDED(num_bytes);
2060                         proto_tree_add_item(tree, hf_vnc_tight_image_data, tvb, *offset, num_bytes, FALSE);
2061                         *offset += num_bytes;
2062
2063                         bytes_needed = 0;
2064                 } else {
2065                         /* The data is compressed; read its length and data */
2066                         bytes_needed = process_compact_length_and_image_data(tvb, offset, tree);
2067                         if (bytes_needed != 0)
2068                                 return bytes_needed;
2069                 }
2070         }
2071
2072         DISSECTOR_ASSERT(bytes_needed != -1);
2073
2074         return bytes_needed;
2075 }
2076
2077
2078 static guint
2079 decode_cursor(tvbuff_t *tvb, gint *offset, proto_tree *tree,
2080               guint pixels_bytes, guint mask_bytes)
2081 {
2082         guint total_bytes;
2083
2084         total_bytes = pixels_bytes + mask_bytes;
2085         VNC_BYTES_NEEDED (total_bytes);
2086
2087         proto_tree_add_item(tree, hf_vnc_cursor_encoding_pixels, tvb, *offset, 
2088                             pixels_bytes, FALSE);
2089         *offset += pixels_bytes;
2090
2091         proto_tree_add_item(tree, hf_vnc_cursor_encoding_bitmask, tvb, *offset,
2092                             mask_bytes, FALSE);
2093         *offset += mask_bytes;
2094
2095         return 0; /* bytes_needed */
2096 }
2097
2098
2099 static guint
2100 vnc_rich_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2101                          proto_tree *tree, guint16 width, guint16 height)
2102 {
2103         guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
2104         guint pixels_bytes, mask_bytes;
2105
2106         pixels_bytes = width * height * bytes_per_pixel;
2107         mask_bytes = ((width + 7) / 8) * height;
2108
2109         return decode_cursor(tvb, offset, tree,
2110                              pixels_bytes, mask_bytes);
2111 }
2112
2113
2114 static guint
2115 vnc_x_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2116                       proto_tree *tree, guint16 width, guint16 height)
2117 {
2118         gint bitmap_row_bytes = (width + 7) / 8;
2119         gint mask_bytes = bitmap_row_bytes * height;
2120         (void) pinfo; /* unused argument */
2121
2122         VNC_BYTES_NEEDED (6);
2123         proto_tree_add_item(tree, hf_vnc_cursor_x_fore_back, tvb, *offset, 6, FALSE);
2124         *offset += 6;
2125
2126         /* The length of the pixel data is the same as the length of the mask data (X cursors are strictly black/white) */
2127         return decode_cursor(tvb, offset, tree,
2128                              mask_bytes, mask_bytes);
2129 }
2130
2131
2132 static guint
2133 vnc_server_set_colormap_entries(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2134                                 proto_tree *tree)
2135 {
2136         guint16 number_of_colors;
2137         guint counter, bytes_needed;
2138         proto_item *ti;
2139         proto_tree *vnc_colormap_num_groups, *vnc_colormap_color_group;
2140
2141         if (check_col(pinfo->cinfo, COL_INFO))
2142                 col_set_str(pinfo->cinfo, COL_INFO,
2143                             "Server set colormap entries");
2144
2145         number_of_colors = tvb_get_ntohs(tvb, 4);
2146
2147         bytes_needed = (number_of_colors * 6) + 6;
2148         VNC_BYTES_NEEDED(bytes_needed);
2149
2150         ti = proto_tree_add_item(tree, hf_vnc_server_message_type, tvb,
2151                                  *offset, 1, FALSE);
2152         tree = proto_item_add_subtree(ti, ett_vnc_server_message_type);
2153         *offset += 1;
2154
2155         proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 1, FALSE);
2156         *offset += 1; /* Skip over 1 byte of padding */
2157
2158         proto_tree_add_item(tree,
2159                             hf_vnc_colormap_first_color,
2160                             tvb, *offset, 2, FALSE);
2161         *offset += 2;
2162
2163         ti = proto_tree_add_item(tree, hf_vnc_colormap_num_colors, tvb,
2164                                  *offset, 2, FALSE);
2165         vnc_colormap_num_groups =
2166                 proto_item_add_subtree(ti, ett_vnc_colormap_num_groups);
2167
2168         *offset += 2;
2169
2170         for(counter = 1; counter <= number_of_colors; counter++) {
2171                 ti = proto_tree_add_text(vnc_colormap_num_groups, tvb,
2172                                          *offset, 6,
2173                                          "Color group #%d", counter);
2174
2175                 vnc_colormap_color_group =
2176                         proto_item_add_subtree(ti,
2177                                                ett_vnc_colormap_color_group);
2178
2179                 proto_tree_add_item(vnc_colormap_color_group,
2180                                     hf_vnc_colormap_red, tvb,
2181                                     *offset, 2, FALSE);
2182                 *offset += 2;
2183
2184                 proto_tree_add_item(vnc_colormap_color_group,
2185                                     hf_vnc_colormap_green, tvb,
2186                                     *offset, 2, FALSE);
2187                 *offset += 2;
2188
2189                 proto_tree_add_item(vnc_colormap_color_group,
2190                                     hf_vnc_colormap_blue, tvb,
2191                                     *offset, 2, FALSE);
2192                 *offset += 2;
2193         }
2194         return *offset;
2195 }
2196
2197
2198 static void
2199 vnc_server_ring_bell(tvbuff_t *tvb _U_, packet_info *pinfo, gint *offset _U_,
2200                      proto_tree *tree _U_)
2201 {
2202         if (check_col(pinfo->cinfo, COL_INFO))
2203                 col_set_str(pinfo->cinfo, COL_INFO, "Server ring bell on client");
2204         /* This message type has no payload... */
2205 }
2206
2207
2208 static guint
2209 vnc_server_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2210                     proto_tree *tree)
2211 {
2212         guint32 text_len;
2213
2214         if (check_col(pinfo->cinfo, COL_INFO))
2215                 col_set_str(pinfo->cinfo, COL_INFO,
2216                             "Server cut text");
2217
2218         text_len = tvb_get_ntohl(tvb, *offset);
2219         proto_tree_add_item(tree,
2220                             hf_vnc_server_cut_text_len, tvb, *offset, 4,
2221                             FALSE);
2222         *offset += 4;
2223         
2224         VNC_BYTES_NEEDED(text_len);
2225
2226         proto_tree_add_item(tree, hf_vnc_server_cut_text, tvb, *offset,
2227                             text_len, FALSE);
2228         *offset += text_len;
2229
2230         return *offset;
2231 }
2232
2233
2234 static void
2235 vnc_set_bytes_per_pixel(packet_info *pinfo, guint8 bytes_per_pixel)
2236 {
2237         vnc_packet_t *per_packet_info;
2238
2239         /* The per_packet_info has already been created by the
2240          * vnc_startup_messages() routine. */
2241         per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
2242         per_packet_info->bytes_per_pixel = bytes_per_pixel;
2243 }
2244
2245
2246 static void
2247 vnc_set_depth(packet_info *pinfo, guint8 depth)
2248 {
2249         vnc_packet_t *per_packet_info;
2250
2251         /* The per_packet_info has already been created by the
2252          * vnc_startup_messages() routine. */
2253         per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
2254         per_packet_info->depth = depth;
2255 }
2256
2257
2258 static guint8
2259 vnc_get_bytes_per_pixel(packet_info *pinfo)
2260 {
2261         vnc_packet_t *per_packet_info;
2262
2263         /* The per_packet_info has already been created by the
2264          * vnc_startup_messages() routine. */
2265         per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
2266         return per_packet_info->bytes_per_pixel;
2267 }
2268
2269
2270 /* Register the protocol with Wireshark */
2271 void
2272 proto_register_vnc(void)
2273 {
2274         module_t *vnc_module; /* To handle our preferences */
2275
2276         /* Setup list of header fields */
2277         static hf_register_info hf[] = {
2278                 { &hf_vnc_padding,
2279                   { "Padding", "vnc.padding",
2280                     FT_NONE, BASE_NONE, NULL, 0x0,
2281                     "Unused space", HFILL }
2282                 },
2283
2284                 { &hf_vnc_server_proto_ver,
2285                   { "Server protocol version", "vnc.server_proto_ver",
2286                     FT_STRING, BASE_NONE, NULL, 0x0,
2287                     "VNC protocol version on server", HFILL }
2288                 },
2289                 { &hf_vnc_client_proto_ver,
2290                   { "Client protocol version", "vnc.client_proto_ver",
2291                     FT_STRING, BASE_NONE, NULL, 0x0,
2292                     "VNC protocol version on client", HFILL }
2293                 },
2294                 { &hf_vnc_num_security_types,
2295                   { "Number of security types", "vnc.num_security_types",
2296                     FT_UINT8, BASE_DEC, NULL, 0x0,
2297                     "Number of security (authentication) types supported by the server", HFILL }
2298                 },
2299                 { &hf_vnc_security_type,
2300                   { "Security type", "vnc.security_type",
2301                     FT_UINT8, BASE_DEC, VALS(security_types_vs), 0x0,
2302                     "Security types offered by the server (VNC versions => 3.007", HFILL }
2303                 },
2304                 { &hf_vnc_server_security_type,
2305                   { "Security type", "vnc.server_security_type",
2306                     FT_UINT32, BASE_DEC, VALS(security_types_vs), 0x0,
2307                     "Security type mandated by the server", HFILL }
2308                 },
2309                 { &hf_vnc_client_security_type,
2310                   { "Security type selected", "vnc.security_type",
2311                     FT_UINT8, BASE_DEC, VALS(security_types_vs), 0x0,
2312                     "Security type selected by the client", HFILL }
2313                 },
2314                 { &hf_vnc_tight_num_tunnel_types,
2315                   { "Number of supported tunnel types",  "vnc.num_tunnel_types",
2316                     FT_UINT32, BASE_DEC, NULL, 0x0,
2317                     "Number of tunnel types for TightVNC", HFILL }
2318                 },
2319                 { &hf_vnc_tight_tunnel_type,
2320                   { "Tunnel type", "vnc.tunnel_type",
2321                     FT_UINT8, BASE_DEC, NULL, 0x0,
2322                     "Tunnel type specific to TightVNC", HFILL }
2323                 },
2324                 { &hf_vnc_tight_num_auth_types,
2325                   { "Number of supported authentication types", "vnc.num_auth_types",
2326                     FT_UINT32, BASE_DEC, NULL, 0x0,
2327                     "Authentication types specific to TightVNC", HFILL }
2328                 },
2329                 { &hf_vnc_tight_auth_type,
2330                   { "Authentication type", "vnc.auth_type",
2331                     FT_UINT8, BASE_DEC, NULL, 0x0,
2332                     "Authentication type specific to TightVNC", HFILL }
2333                 },
2334                 { &hf_vnc_tight_server_message_type,
2335                   { "Server message type", "vnc.server_message_type",
2336                     FT_INT32, BASE_DEC, NULL, 0x0,
2337                     "Server message type specific to TightVNC", HFILL }
2338                 },
2339                 { &hf_vnc_tight_server_vendor,
2340                   { "Server vendor code", "vnc.server_vendor",
2341                     FT_STRING, BASE_NONE, NULL, 0x0,
2342                     "Server vendor code specific to TightVNC", HFILL }
2343                 },
2344                 { &hf_vnc_tight_server_name,
2345                   { "Server name", "vnc.server_name",
2346                     FT_STRING, BASE_NONE, NULL, 0x0,
2347                     "Server name specific to TightVNC", HFILL }
2348                 },
2349                 { &hf_vnc_tight_client_message_type,
2350                   { "Client message type", "vnc.client_message_type",
2351                     FT_INT32, BASE_DEC, NULL, 0x0,
2352                     "Client message type specific to TightVNC", HFILL }
2353                 },
2354                 { &hf_vnc_tight_client_vendor,
2355                   { "Client vendor code", "vnc.client_vendor",
2356                     FT_STRING, BASE_NONE, NULL, 0x0,
2357                     "Client vendor code specific to TightVNC", HFILL }
2358                 },
2359                 { &hf_vnc_tight_client_name,
2360                   { "Client name", "vnc.client_name",
2361                     FT_STRING, BASE_NONE, NULL, 0x0,
2362                     "Client name specific to TightVNC", HFILL }
2363                 },
2364                 { &hf_vnc_tight_encoding_type,
2365                   { "Encoding type", "vnc.encoding_type",
2366                     FT_INT32, BASE_DEC, NULL, 0x0,
2367                     "Encoding type specific to TightVNC", HFILL }
2368                 },
2369                 { &hf_vnc_tight_encoding_vendor,
2370                   { "Encoding vendor code", "vnc.encoding_vendor",
2371                     FT_STRING, BASE_NONE, NULL, 0x0,
2372                     "Encoding vendor code specific to TightVNC", HFILL }
2373                 },
2374                 { &hf_vnc_tight_encoding_name,
2375                   { "Encoding name", "vnc.encoding_name",
2376                     FT_STRING, BASE_NONE, NULL, 0x0,
2377                     "Encoding name specific to TightVNC", HFILL }
2378                 },
2379                 { &hf_vnc_tight_reset_stream0,
2380                   { "Reset compression stream 0", "vnc.tight_reset_stream0",
2381                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2382                     "Tight compression, reset compression stream 0", HFILL }
2383                 },
2384                 { &hf_vnc_tight_reset_stream1,
2385                   { "Reset compression stream 1", "vnc.tight_reset_stream0",
2386                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2387                     "Tight compression, reset compression stream 1", HFILL }
2388                 },
2389                 { &hf_vnc_tight_reset_stream2,
2390                   { "Reset compression stream 2", "vnc.tight_reset_stream0",
2391                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2392                     "Tight compression, reset compression stream 2", HFILL }
2393                 },
2394                 { &hf_vnc_tight_reset_stream3,
2395                   { "Reset compression stream 3", "vnc.tight_reset_stream0",
2396                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2397                     "Tight compression, reset compression stream 3", HFILL }
2398                 },
2399                 { &hf_vnc_tight_rect_type,
2400                   { "Rectangle type", "vnc.tight_rect_type",
2401                     FT_UINT8, BASE_HEX, NULL, 0x0,
2402                     "Tight compression, rectangle type", HFILL }
2403                 },
2404                 { &hf_vnc_tight_image_len,
2405                   { "Image data length", "vnc.tight_image_len",
2406                     FT_UINT32, BASE_DEC, NULL, 0x0,
2407                     "Tight compression, length of image data", HFILL }
2408                 },
2409                 { &hf_vnc_tight_image_data,
2410                   { "Image data", "vnc.tight_image_data",
2411                     FT_BYTES, BASE_NONE, NULL, 0x0,
2412                     "Tight compression, image data", HFILL }
2413                 },
2414                 { &hf_vnc_tight_fill_color,
2415                   { "Fill color (RGB)", "vnc.tight_fill_color",
2416                     FT_BYTES, BASE_NONE, NULL, 0x0,
2417                     "Tight compression, fill color for solid rectangle", HFILL }
2418                 },
2419                 { &hf_vnc_tight_filter_flag,
2420                   { "Explicit filter flag", "vnc.tight_filter_flag",
2421                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2422                     "Tight compression, explicit filter flag", HFILL }
2423                 },
2424                 { &hf_vnc_tight_filter_id,
2425                   { "Filter ID", "vnc.tight_filter_id",
2426                     FT_UINT8, BASE_DEC, VALS(tight_filter_ids_vs), 0x0,
2427                     "Tight compression, filter ID", HFILL }
2428                 },
2429                 { &hf_vnc_tight_palette_num_colors,
2430                   { "Number of colors in palette", "vnc.tight_palette_num_colors",
2431                     FT_UINT8, BASE_DEC, NULL, 0x0,
2432                     "Tight compression, number of colors in rectangle's palette", HFILL }
2433                 },
2434                 { &hf_vnc_tight_palette_data,
2435                   { "Palette data", "vnc.tight_palette_data",
2436                     FT_BYTES, BASE_NONE, NULL, 0x0,
2437                     "Tight compression, palette data for a rectangle", HFILL }
2438                 },
2439                 { &hf_vnc_vendor_code,
2440                   { "Vendor code", "vnc.vendor_code",
2441                     FT_STRING, BASE_NONE, NULL, 0x0,
2442                     "Identifies the VNC server software's vendor", HFILL }
2443                 },
2444                 { &hf_vnc_security_type_string,
2445                   { "Security type string", "vnc.security_type_string",
2446                     FT_STRING, BASE_NONE, NULL, 0x0,
2447                     "Security type being used", HFILL }
2448                 },
2449                 { &hf_vnc_auth_challenge,
2450                   { "Authentication challenge", "vnc.auth_challenge",
2451                     FT_STRING, BASE_NONE, NULL, 0x0,
2452                     "Random authentication challenge from server to client", HFILL }
2453                 },
2454                 { &hf_vnc_auth_response,
2455                   { "Authentication response", "vnc.auth_response",
2456                     FT_STRING, BASE_NONE, NULL, 0x0,
2457                     "Client's encrypted response to the server's authentication challenge", HFILL }
2458                 },
2459                 { &hf_vnc_auth_result,
2460                   { "Authentication result", "vnc.auth_result",
2461                     FT_UINT32, BASE_DEC, VALS(auth_result_vs), 0x0,
2462                     "Authentication result", HFILL }
2463                 },
2464                 { &hf_vnc_auth_error,
2465                   { "Authentication error", "vnc.auth_error",
2466                     FT_STRING, BASE_NONE, NULL, 0x0,
2467                     "Authentication error (present only if the authentication result is fail", HFILL }
2468                 },
2469                 { &hf_vnc_share_desktop_flag,
2470                   { "Share desktop flag", "vnc.share_desktop_flag",
2471                     FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x0,
2472                     "Client's desire to share the server's desktop with other clients", HFILL }
2473                 },
2474                 { &hf_vnc_width,
2475                   { "Framebuffer width", "vnc.width",
2476                     FT_UINT16, BASE_DEC, NULL, 0x0,
2477                     "Width of the framebuffer (screen) in pixels", HFILL }
2478                 },
2479                 { &hf_vnc_height,
2480                   { "Framebuffer height", "vnc.width",
2481                     FT_UINT16, BASE_DEC, NULL, 0x0,
2482                     "Height of the framebuffer (screen) in pixels", HFILL }
2483                 },
2484                 { &hf_vnc_server_bits_per_pixel,
2485                   { "Bits per pixel", "vnc.server_bits_per_pixel",
2486                     FT_UINT8, BASE_DEC, NULL, 0x0,
2487                     "Number of bits used by server for each pixel value on the wire from the server", HFILL }
2488                 },
2489                 { &hf_vnc_server_depth,
2490                   { "Depth", "vnc.server_depth",
2491                     FT_UINT8, BASE_DEC, NULL, 0x0,
2492                     "Number of useful bits in the pixel value on server", HFILL }
2493                 },
2494                 { &hf_vnc_server_big_endian_flag,
2495                   { "Big endian flag", "vnc.server_big_endian_flag",
2496                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2497                     "True if multi-byte pixels are interpreted as big endian by server", HFILL }
2498                 },
2499                 { &hf_vnc_server_true_color_flag,
2500                   { "True color flag", "vnc.server_true_color_flag",
2501                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2502                     "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 }
2503                 },
2504                 { &hf_vnc_server_red_max,
2505                   { "Red maximum", "vnc.server_red_max",
2506                     FT_UINT16, BASE_DEC, NULL, 0x0,
2507                     "Maximum red value on server as n: 2^n - 1", HFILL }
2508                 },
2509                 { &hf_vnc_server_green_max,
2510                   { "Green maximum", "vnc.server_green_max",
2511                     FT_UINT16, BASE_DEC, NULL, 0x0,
2512                     "Maximum green value on server as n: 2^n - 1", HFILL }
2513                 },
2514                 { &hf_vnc_server_blue_max,
2515                   { "Blue maximum", "vnc.server_blue_max",
2516                     FT_UINT16, BASE_DEC, NULL, 0x0,
2517                     "Maximum blue value on server as n: 2^n - 1", HFILL }
2518                 },
2519                 { &hf_vnc_server_red_shift,
2520                   { "Red shift", "vnc.server_red_shift",
2521                     FT_UINT8, BASE_DEC, NULL, 0x0,
2522                     "Number of shifts needed to get the red value in a pixel to the least significant bit on the server", HFILL }
2523                 },
2524                 { &hf_vnc_server_green_shift,
2525                   { "Green shift", "vnc.server_green_shift",
2526                     FT_UINT8, BASE_DEC, NULL, 0x0,
2527                     "Number of shifts needed to get the green value in a pixel to the least significant bit on the server", HFILL }
2528                 },
2529                 { &hf_vnc_server_blue_shift,
2530                   { "Blue shift", "vnc.server_blue_shift",
2531                     FT_UINT8, BASE_DEC, NULL, 0x0,
2532                     "Number of shifts needed to get the blue value in a pixel to the least significant bit on the server", HFILL }
2533                 },
2534                 { &hf_vnc_desktop_name_len,
2535                   { "Desktop name length", "vnc.desktop_name_len",
2536                     FT_UINT32, BASE_DEC, NULL, 0x0,
2537                     "Length of desktop name in bytes", HFILL }
2538                 },
2539                 { &hf_vnc_desktop_name,
2540                   { "Desktop name", "vnc.desktop_name",
2541                     FT_STRING, BASE_NONE, NULL, 0x0,
2542                     "Name of the VNC desktop on the server", HFILL }
2543                 },
2544                 { &hf_vnc_num_server_message_types,
2545                   { "Server message types", "vnc.num_server_message_types",
2546                     FT_UINT16, BASE_DEC, NULL, 0x0,
2547                     "Unknown", HFILL } /* XXX - Needs description */
2548                 },
2549                 { &hf_vnc_num_client_message_types,
2550                   { "Client message types", "vnc.num_client_message_types",
2551                     FT_UINT16, BASE_DEC, NULL, 0x0,
2552                     "Unknown", HFILL } /* XXX - Needs description */
2553                 },
2554                 { &hf_vnc_num_encoding_types,
2555                   { "Encoding types", "vnc.num_encoding_types",
2556                     FT_UINT16, BASE_DEC, NULL, 0x0,
2557                     "Unknown", HFILL } /* XXX - Needs description */
2558                 },
2559                 { &hf_vnc_client_message_type,
2560                   { "Client Message Type", "vnc.client_message_type",
2561                     FT_UINT8, BASE_DEC, VALS(client_message_types_vs), 0x0,
2562                     "Message type from client", HFILL }
2563                 },
2564                 { &hf_vnc_client_bits_per_pixel,
2565                   { "Bits per pixel", "vnc.client_bits_per_pixel",
2566                     FT_UINT8, BASE_DEC, NULL, 0x0,
2567                     "Number of bits used by server for each pixel value on the wire from the client", HFILL }
2568                 },
2569                 { &hf_vnc_client_depth,
2570                   { "Depth", "vnc.client_depth",
2571                     FT_UINT8, BASE_DEC, NULL, 0x0,
2572                     "Number of useful bits in the pixel value on client", HFILL }
2573                 },
2574                 { &hf_vnc_client_big_endian_flag,
2575                   { "Big endian flag", "vnc.client_big_endian_flag",
2576                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2577                     "True if multi-byte pixels are interpreted as big endian by client", HFILL }
2578                 },
2579                 { &hf_vnc_client_true_color_flag,
2580                   { "True color flag", "vnc.client_true_color_flag",
2581                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2582                     "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 }
2583                 },
2584                 { &hf_vnc_client_red_max,
2585                   { "Red maximum", "vnc.client_red_max",
2586                     FT_UINT16, BASE_DEC, NULL, 0x0,
2587                     "Maximum red value on client as n: 2^n - 1", HFILL }
2588                 },
2589                 { &hf_vnc_client_green_max,
2590                   { "Green maximum", "vnc.client_green_max",
2591                     FT_UINT16, BASE_DEC, NULL, 0x0,
2592                     "Maximum green value on client as n: 2^n - 1", HFILL }
2593                 },
2594                 { &hf_vnc_client_blue_max,
2595                   { "Blue maximum", "vnc.client_blue_max",
2596                     FT_UINT16, BASE_DEC, NULL, 0x0,
2597                     "Maximum blue value on client as n: 2^n - 1", HFILL }
2598                 },
2599                 { &hf_vnc_client_red_shift,
2600                   { "Red shift", "vnc.client_red_shift",
2601                     FT_UINT8, BASE_DEC, NULL, 0x0,
2602                     "Number of shifts needed to get the red value in a pixel to the least significant bit on the client", HFILL }
2603                 },
2604                 { &hf_vnc_client_green_shift,
2605                   { "Green shift", "vnc.client_green_shift",
2606                     FT_UINT8, BASE_DEC, NULL, 0x0,
2607                     "Number of shifts needed to get the green value in a pixel to the least significant bit on the client", HFILL }
2608                 },
2609                 { &hf_vnc_client_blue_shift,
2610                   { "Blue shift", "vnc.client_blue_shift",
2611                     FT_UINT8, BASE_DEC, NULL, 0x0,
2612                     "Number of shifts needed to get the blue value in a pixel to the least significant bit on the client", HFILL }
2613                 },
2614
2615                 /* Client Key Event */
2616                 { &hf_vnc_key_down,
2617                   { "Key down", "vnc.key_down",
2618                     FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x0,
2619                     "Specifies whether the key is being pressed or not", HFILL }
2620                 },
2621                 { &hf_vnc_key,
2622                   { "Key", "vnc.key",
2623                     FT_UINT32, BASE_HEX, VALS(keysym_vals_source), 0x0, /* keysym_vals_source is from packet-x11-keysym.h */
2624                     "Key being pressed/depressed", HFILL }
2625                 },
2626
2627                 /* Client Pointer Event */
2628                 { &hf_vnc_button_1_pos,
2629                   { "Mouse button #1 position", "vnc.button_1_pos",
2630                     FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x1,
2631                     "Whether mouse button #1 is being pressed or not", HFILL }
2632                 },
2633                 { &hf_vnc_button_2_pos,
2634                   { "Mouse button #2 position", "vnc.button_2_pos",
2635                     FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x2,
2636                     "Whether mouse button #2 is being pressed or not", HFILL }
2637                 },
2638                 { &hf_vnc_button_3_pos,
2639                   { "Mouse button #3 position", "vnc.button_3_pos",
2640                     FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x4,
2641                     "Whether mouse button #3 is being pressed or not", HFILL }
2642                 },
2643                 { &hf_vnc_button_4_pos,
2644                   { "Mouse button #4 position", "vnc.button_4_pos",
2645                     FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x8,
2646                     "Whether mouse button #4 is being pressed or not", HFILL }
2647                 },
2648                 { &hf_vnc_button_5_pos,
2649                   { "Mouse button #5 position", "vnc.button_5_pos",
2650                     FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x10,
2651                     "Whether mouse button #5 is being pressed or not", HFILL }
2652                 },
2653                 { &hf_vnc_button_6_pos,
2654                   { "Mouse button #6 position", "vnc.button_6_pos",
2655                     FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x20,
2656                     "Whether mouse button #6 is being pressed or not", HFILL }
2657                 },
2658                 { &hf_vnc_button_7_pos,
2659                   { "Mouse button #7 position", "vnc.button_7_pos",
2660                     FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x40,
2661                     "Whether mouse button #7 is being pressed or not", HFILL }
2662                 },
2663                 { &hf_vnc_button_8_pos,
2664                   { "Mouse button #8 position", "vnc.button_8_pos",
2665                     FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x80,
2666                     "Whether mouse button #8 is being pressed or not", HFILL }
2667                 },
2668                 { &hf_vnc_pointer_x_pos,
2669                   { "X position", "vnc.pointer_x_pos",
2670                     FT_UINT16, BASE_DEC, NULL, 0x0,
2671                     "Position of mouse cursor on the x-axis", HFILL }
2672                 },
2673                 { &hf_vnc_pointer_y_pos,
2674                   { "Y position", "vnc.pointer_y_pos",
2675                     FT_UINT16, BASE_DEC, NULL, 0x0,
2676                     "Position of mouse cursor on the y-axis", HFILL }
2677                 },
2678                 { &hf_vnc_client_set_encodings_encoding_type,
2679                   { "Encoding type", "vnc.client_set_encodings_encoding_type",
2680                     FT_INT32, BASE_DEC, VALS(encoding_types_vs), 0x0,
2681                     "Type of encoding used to send pixel data from server to client", HFILL }
2682                 },
2683
2684                 /* Client Framebuffer Update Request */
2685                 { &hf_vnc_update_req_incremental,
2686                   { "Incremental update", "vnc.update_req_incremental",
2687                     FT_BOOLEAN, BASE_DEC, NULL, 0x0,
2688                     "Specifies if the client wants an incremental update instead of a full one", HFILL }
2689                 },
2690                 { &hf_vnc_update_req_x_pos,
2691                   { "X position", "vnc.update_req_x_pos",
2692                     FT_UINT16, BASE_DEC, NULL, 0x0,
2693                     "X position of framebuffer (screen) update requested", HFILL }
2694                 },
2695                 { &hf_vnc_update_req_y_pos,
2696                   { "Y position", "vnc.update_req_y_pos",
2697                     FT_UINT16, BASE_DEC, NULL, 0x0,
2698                     "Y position of framebuffer (screen) update request", HFILL }
2699                 },
2700                 { &hf_vnc_update_req_width,
2701                   { "Width", "vnc.update_req_width",
2702                     FT_UINT16, BASE_DEC, NULL, 0x0,
2703                     "Width of framebuffer (screen) update request", HFILL }
2704                 },
2705                 { &hf_vnc_update_req_height,
2706                   { "Height", "vnc.update_req_height",
2707                     FT_UINT16, BASE_DEC, NULL, 0x0,
2708                     "Height of framebuffer (screen) update request", HFILL }
2709                 },
2710                 { &hf_vnc_client_cut_text_len,
2711                   { "Length", "vnc.client_cut_text_len",
2712                     FT_UINT32, BASE_DEC, NULL, 0x0,
2713                     "Length of client's copy/cut text (clipboard) string in bytes", HFILL }
2714                 },
2715                 { &hf_vnc_client_cut_text,
2716                   { "Text", "vnc.client_cut_text",
2717                     FT_STRING, BASE_NONE, NULL, 0x0,
2718                     "Text string in the client's copy/cut text (clipboard)", HFILL }
2719                 },
2720
2721
2722                 /********** Server Message Types **********/
2723                 { &hf_vnc_server_message_type,
2724                   { "Server Message Type", "vnc.server_message_type",
2725                     FT_UINT8, BASE_DEC, VALS(server_message_types_vs), 0x0,
2726                     "Message type from server", HFILL }
2727                 },
2728
2729                 { &hf_vnc_fb_update_x_pos,
2730                   { "X position", "vnc.fb_update_x_pos",
2731                     FT_UINT16, BASE_DEC, NULL, 0x0,
2732                     "X position of this server framebuffer update", HFILL }
2733                 },
2734
2735                 { &hf_vnc_fb_update_y_pos,
2736                   { "Y position", "vnc.fb_update_x_pos",
2737                     FT_UINT16, BASE_DEC, NULL, 0x0,
2738                     "Y position of this server framebuffer update", HFILL }
2739                 },
2740
2741                 { &hf_vnc_fb_update_width,
2742                   { "Width", "vnc.fb_update_width",
2743                     FT_UINT16, BASE_DEC, NULL, 0x0,
2744                     "Width of this server framebuffer update", HFILL }
2745                 },
2746
2747                 { &hf_vnc_fb_update_height,
2748                   { "Height", "vnc.fb_update_height",
2749                     FT_UINT16, BASE_DEC, NULL, 0x0,
2750                     "Height of this server framebuffer update", HFILL }
2751                 },
2752
2753                 { &hf_vnc_fb_update_encoding_type,
2754                   { "Encoding type", "vnc.fb_update_encoding_type",
2755                     FT_INT32, BASE_DEC, VALS(encoding_types_vs), 0x0,
2756                     "Encoding type of this server framebuffer update", HFILL }
2757                 },
2758
2759                 /* Cursor encoding */
2760                 { &hf_vnc_cursor_x_fore_back,
2761                   { "X Cursor foreground RGB / background RGB", "vnc.cursor_x_fore_back",
2762                     FT_BYTES, BASE_NONE, NULL, 0x0,
2763                     "RGB values for the X cursor's foreground and background", HFILL }
2764                 },
2765
2766                 { &hf_vnc_cursor_encoding_pixels,
2767                   { "Cursor encoding pixels", "vnc.cursor_encoding_pixels",
2768                     FT_BYTES, BASE_NONE, NULL, 0x0,
2769                     "Cursor encoding pixel data", HFILL }
2770                 },              
2771
2772                 { &hf_vnc_cursor_encoding_bitmask,
2773                   { "Cursor encoding bitmask", "vnc.cursor_encoding_bitmask",
2774                     FT_BYTES, BASE_NONE, NULL, 0x0,
2775                     "Cursor encoding pixel bitmask", HFILL }
2776                 },              
2777
2778                 /* Raw Encoding */
2779                 { &hf_vnc_raw_pixel_data,
2780                   { "Pixel data", "vnc.raw_pixel_data",
2781                     FT_BYTES, BASE_NONE, NULL, 0x0,
2782                     "Raw pixel data.", HFILL }
2783                 },              
2784
2785                 /* CopyRect Encoding*/
2786                 { &hf_vnc_copyrect_src_x_pos,
2787                   { "Source x position", "vnc.copyrect_src_x_pos",
2788                     FT_UINT16, BASE_DEC, NULL, 0x0,
2789                     "X position of the rectangle to copy from", HFILL }
2790                 },              
2791
2792                 { &hf_vnc_copyrect_src_y_pos,
2793                   { "Source y position", "vnc.copyrect_src_y_pos",
2794                     FT_UINT16, BASE_DEC, NULL, 0x0,
2795                     "Y position of the rectangle to copy from", HFILL }
2796                 },              
2797
2798                 /* RRE Encoding */
2799                 { &hf_vnc_rre_num_subrects,
2800                   { "Number of subrectangles", "vnc.rre_num_subrects",
2801                     FT_UINT32, BASE_DEC, NULL, 0x0,
2802                     "Number of subrectangles contained in this encoding type", HFILL }
2803                 },
2804
2805                 { &hf_vnc_rre_bg_pixel,
2806                   { "Background pixel value", "vnc.rre_bg_pixel",
2807                     FT_BYTES, BASE_NONE, NULL, 0x0,
2808                     "Background pixel value", HFILL }
2809                 },
2810
2811                 { &hf_vnc_rre_subrect_pixel,
2812                   { "Pixel value", "vnc.rre_subrect_pixel",
2813                     FT_BYTES, BASE_NONE, NULL, 0x0,
2814                     "Subrectangle pixel value", HFILL }
2815                 },
2816
2817                 { &hf_vnc_rre_subrect_x_pos,
2818                   { "X position", "vnc.rre_subrect_x_pos",
2819                     FT_UINT16, BASE_DEC, NULL, 0x0,
2820                     "Position of this subrectangle on the x axis", HFILL }
2821                 },
2822
2823                 { &hf_vnc_rre_subrect_y_pos,
2824                   { "Y position", "vnc.rre_subrect_y_pos",
2825                     FT_UINT16, BASE_DEC, NULL, 0x0,
2826                     "Position of this subrectangle on the y axis", HFILL }
2827                 },
2828
2829                 { &hf_vnc_rre_subrect_width,
2830                   { "Width", "vnc.rre_subrect_width",
2831                     FT_UINT16, BASE_DEC, NULL, 0x0,
2832                     "Width of this subrectangle", HFILL }
2833                 },
2834
2835                 { &hf_vnc_rre_subrect_height,
2836                   { "Height", "vnc.rre_subrect_height",
2837                     FT_UINT16, BASE_DEC, NULL, 0x0,
2838                     "Height of this subrectangle", HFILL }
2839                 },
2840
2841
2842                 /* Hextile Encoding */
2843                 { &hf_vnc_hextile_subencoding_mask,
2844                   { "Subencoding type", "vnc.hextile_subencoding",
2845                     FT_UINT8, BASE_DEC, NULL, 0x0,
2846                     "Hextile subencoding type.", HFILL }
2847                 },              
2848
2849                 { &hf_vnc_hextile_raw,
2850                   { "Raw", "vnc.hextile_raw",
2851                     FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x1,
2852                     "Raw subencoding is used in this tile", HFILL }
2853                 },              
2854
2855                 { &hf_vnc_hextile_raw_value,
2856                   { "Raw pixel values", "vnc.hextile_raw_value",
2857                     FT_BYTES, BASE_NONE, NULL, 0x0,
2858                     "Raw subencoding pixel values", HFILL }
2859                 },              
2860
2861                 { &hf_vnc_hextile_bg,
2862                   { "Background Specified", "vnc.hextile_bg",
2863                     FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x2,
2864                     "Background Specified subencoding is used in this tile", HFILL }
2865                 },
2866
2867                 { &hf_vnc_hextile_bg_value,
2868                   { "Background pixel value", "vnc.hextile_bg_value",
2869                     FT_BYTES, BASE_NONE, NULL, 0x0,
2870                     "Background color for this tile", HFILL }
2871                 },
2872
2873                 { &hf_vnc_hextile_fg,
2874                   { "Foreground Specified", "vnc.hextile_fg",
2875                     FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x4,
2876                     "Foreground Specified subencoding is used in this tile", HFILL }
2877                 },              
2878
2879                 { &hf_vnc_hextile_fg_value,
2880                   { "Foreground pixel value", "vnc.hextile_fg_value",
2881                     FT_BYTES, BASE_NONE, NULL, 0x0,
2882                     "Foreground color for this tile", HFILL }
2883                 },
2884
2885                 { &hf_vnc_hextile_anysubrects,
2886                   { "Any Subrects", "vnc.hextile_anysubrects",
2887                     FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x8,
2888                     "Any subrects subencoding is used in this tile", HFILL }
2889                 },              
2890
2891                 { &hf_vnc_hextile_num_subrects,
2892                   { "Number of subrectangles", "vnc.hextile_num_subrects",
2893                     FT_UINT8, BASE_DEC, NULL, 0x0,
2894                     "Number of subrectangles that follow", HFILL }
2895                 },              
2896
2897                 { &hf_vnc_hextile_subrectscolored,
2898                   { "Subrects Colored", "vnc.hextile_subrectscolored",
2899                     FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x10,
2900                     "Subrects colored subencoding is used in this tile", HFILL }
2901                 },              
2902
2903                 { &hf_vnc_hextile_subrect_pixel_value,
2904                   { "Pixel value", "vnc.hextile_subrect_pixel_value",
2905                     FT_BYTES, BASE_NONE, NULL, 0x0,
2906                     "Pixel value of this subrectangle", HFILL }
2907                 },              
2908
2909                 { &hf_vnc_hextile_subrect_x_pos,
2910                   { "X position", "vnc.hextile_subrect_x_pos",
2911                     FT_UINT8, BASE_DEC, NULL, 0xF0, /* Top 4 bits */
2912                     "X position of this subrectangle", HFILL }
2913                 },              
2914
2915                 { &hf_vnc_hextile_subrect_y_pos,
2916                   { "Y position", "vnc.hextile_subrect_y_pos",
2917                     FT_UINT8, BASE_DEC, NULL, 0xF, /* Bottom 4 bits */
2918                     "Y position of this subrectangle", HFILL }
2919                 },              
2920
2921                 { &hf_vnc_hextile_subrect_width,
2922                   { "Width", "vnc.hextile_subrect_width",
2923                     FT_UINT8, BASE_DEC, NULL, 0xF0, /* Top 4 bits */
2924                     "Subrectangle width minus one", HFILL }
2925                 },              
2926
2927                 { &hf_vnc_hextile_subrect_height,
2928                   { "Height", "vnc.hextile_subrect_height",
2929                     FT_UINT8, BASE_DEC, NULL, 0xF, /* Bottom 4 bits */
2930                     "Subrectangle height minus one", HFILL }
2931                 },              
2932
2933
2934                 /* ZRLE Encoding */
2935                 { &hf_vnc_zrle_len,
2936                   { "ZRLE compressed length", "vnc.zrle_len",
2937                     FT_UINT32, BASE_DEC, NULL, 0x0,
2938                     "Length of compressed ZRLE data that follows", HFILL }
2939                 },