2 * Routines for VNC dissection (Virtual Network Computing)
3 * Copyright 2005, Ulf Lamping <ulf.lamping@web.de>
4 * Copyright 2006-2007, Stephen Fisher (see AUTHORS file)
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
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.
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.
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.
27 /* Dissection of the VNC (Virtual Network Computing) network traffic.
29 * All versions of RealVNC and TightVNC are supported.
30 * Note: The addition of TightVNC support is not yet complete.
32 * Several VNC implementations available, see:
33 * http://www.realvnc.com/
34 * http://www.tightvnc.com/
35 * http://ultravnc.sourceforge.net/
38 * The protocol itself is known as RFB - Remote Frame Buffer Protocol.
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
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. */
63 static const value_string security_types_vs[] = {
88 static const value_string auth_result_vs[] = {
94 static const value_string yes_no_vs[] = {
100 static const value_string client_message_types_vs[] = {
101 { 0, "Set Pixel Format" },
102 { 2, "Set Encodings" },
103 { 3, "Framebuffer Update Request" },
105 { 5, "Pointer Event" },
110 static const value_string server_message_types_vs[] = {
111 { 0, "Framebuffer Update" },
112 { 1, "Set Colormap Entries" },
118 static const value_string button_mask_vs[] = {
119 { 0, "Not pressed" },
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,
131 ENCODING_COPY_RECT = 1,
134 ENCODING_HEXTILE = 5,
137 ENCODING_ZLIBHEX = 8,
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" },
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.
164 #define TIGHT_RECT_FILL 0x08
165 #define TIGHT_RECT_JPEG 0x09
166 #define TIGHT_RECT_MAX_VALUE 0x09
168 #define TIGHT_RECT_EXPLICIT_FILTER_FLAG 0x04
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
175 /* Minimum number of bytes to compress for Tight encoding */
176 #define TIGHT_MIN_BYTES_TO_COMPRESS 12
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" },
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,
200 VNC_AUTHENTICATION_CHALLENGE,
201 VNC_AUTHENTICATION_RESPONSE,
208 TIGHT_INTERACTION_CAPS,
209 TIGHT_INTERACTION_CAPS_LIST,
212 } vnc_session_state_e;
214 /* This structure will be tied to each conversation. */
216 guint8 security_type_selected;
217 gdouble server_proto_ver, client_proto_ver;
218 vnc_session_state_e vnc_next_state;
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;
226 /* This structure will be tied to each packet */
228 guint8 bytes_per_pixel;
230 vnc_session_state_e state;
231 gint preferred_encoding;
234 void proto_reg_handoff_vnc(void);
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,
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,
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,
277 static guint vnc_x_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo,
278 gint *offset, proto_tree *tree, guint16 width,
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);
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
295 #define VNC_BYTES_NEEDED(a) \
296 if(a > (guint)tvb_length_remaining(tvb, *offset)) \
300 /* Variables for our preferences */
301 static guint vnc_preference_alternate_port = 0;
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;
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;
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;
339 /********** Client Message Types **********/
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;
353 /* Client Key Event */
354 static int hf_vnc_key_down = -1;
355 static int hf_vnc_key = -1;
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;
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;
376 /* Client Set Encodings */
377 static int hf_vnc_client_set_encodings_encoding_type = -1;
379 /* Client Cut Text */
380 static int hf_vnc_client_cut_text_len = -1;
381 static int hf_vnc_client_cut_text = -1;
383 /********** Server Message Types **********/
385 static int hf_vnc_server_message_type = -1; /* Subtree */
387 /* Tunneling capabilities (TightVNC extension) */
388 static int hf_vnc_tight_num_tunnel_types = -1;
389 static int hf_vnc_tight_tunnel_type = -1;
391 /* Authentication capabilities (TightVNC extension) */
392 static int hf_vnc_tight_num_auth_types = -1;
393 static int hf_vnc_tight_auth_type = -1;
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;
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;
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;
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;
414 static int hf_vnc_tight_rect_type = -1;
416 static int hf_vnc_tight_image_len = -1;
417 static int hf_vnc_tight_image_data = -1;
419 static int hf_vnc_tight_fill_color = -1;
421 static int hf_vnc_tight_filter_flag = -1;
422 static int hf_vnc_tight_filter_id = -1;
424 static int hf_vnc_tight_palette_num_colors = -1;
425 static int hf_vnc_tight_palette_data = -1;
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;
435 static int hf_vnc_raw_pixel_data = -1;
437 /* CopyRect Encoding */
438 static int hf_vnc_copyrect_src_x_pos = -1;
439 static int hf_vnc_copyrect_src_y_pos = -1;
442 static int hf_vnc_rre_num_subrects = -1;
443 static int hf_vnc_rre_bg_pixel = -1;
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;
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;
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;
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;
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;
489 /* Server Cut Text */
490 static int hf_vnc_server_cut_text_len = -1;
491 static int hf_vnc_server_cut_text = -1;
493 /********** End of Server Message Types **********/
495 static gboolean vnc_preference_desegment = TRUE;
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;
511 /* Global so they keep their value between packets */
512 guint8 vnc_bytes_per_pixel;
515 static dissector_handle_t vnc_handle;
517 /* Code to dissect the packets */
519 dissect_vnc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
524 /* Set up structures needed to add the protocol subtree and manage it */
526 proto_tree *vnc_tree=NULL;
528 conversation_t *conversation;
529 vnc_conversation_t *per_conversation_info;
531 conversation = find_conversation(pinfo->fd->num, &pinfo->src,
532 &pinfo->dst, pinfo->ptype,
533 pinfo->srcport, pinfo->destport, 0);
535 if(!conversation) { /* Conversation does not exist yet - create it */
536 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
537 &pinfo->dst, pinfo->ptype,
542 /* Retrieve information from conversation, or add it if it isn't
544 per_conversation_info = conversation_get_proto_data(conversation,
546 if(!per_conversation_info) {
547 per_conversation_info = se_alloc(sizeof(vnc_conversation_t));
549 per_conversation_info->vnc_next_state = SERVER_VERSION;
551 conversation_add_proto_data(conversation, proto_vnc,
552 per_conversation_info);
556 /* Make entries in Protocol column and Info column on summary display */
557 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VNC");
559 /* First, clear the info column */
560 col_clear(pinfo->cinfo, COL_INFO);
562 /* create display subtree for the protocol */
564 ti = proto_tree_add_item(tree, proto_vnc, tvb, 0, -1, FALSE);
565 vnc_tree = proto_item_add_subtree(ti, ett_vnc);
568 offset = 0; /* Start at the beginning of the VNC protocol data */
570 /* Dissect any remaining session startup messages */
571 ret = vnc_startup_messages(tvb, pinfo, offset, vnc_tree,
572 per_conversation_info);
574 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
575 vnc_set_depth(pinfo, vnc_depth);
578 if(DEST_PORT_VNC || per_conversation_info->server_port == pinfo->destport)
579 vnc_client_to_server(tvb, pinfo, &offset, vnc_tree);
581 vnc_server_to_client(tvb, pinfo, &offset, vnc_tree);
585 /* Returns the new offset after processing the 4-byte vendor string */
587 process_vendor(proto_tree *tree, gint hfindex, tvbuff_t *tvb, gint offset)
592 vendor = tvb_get_ephemeral_string(tvb, offset, 4);
594 ti = proto_tree_add_string(tree, hfindex, tvb, offset, 4, vendor);
596 if(g_ascii_strcasecmp(vendor, "STDV") == 0)
597 proto_item_append_text(ti, " (Standard VNC vendor)");
598 else if(g_ascii_strcasecmp(vendor, "TRDV") == 0)
599 proto_item_append_text(ti, " (Tridia VNC vendor)");
600 else if(g_ascii_strcasecmp(vendor, "TGHT") == 0)
601 proto_item_append_text(ti, " (Tight VNC vendor)");
607 /* Returns the new offset after processing the specified number of capabilities */
609 process_tight_capabilities(proto_tree *tree,
610 gint type_index, gint vendor_index, gint name_index,
611 tvbuff_t *tvb, gint offset, gint num_capabilities)
615 /* See vnc_unixsrc/include/rfbproto.h:rfbCapabilityInfo */
617 for (i = 0; i < num_capabilities; i++) {
620 proto_tree_add_item(tree, type_index, tvb, offset, 4, FALSE);
623 offset = process_vendor(tree, vendor_index, tvb, offset);
625 name = tvb_get_ephemeral_string(tvb, offset, 8);
626 proto_tree_add_string(tree, name_index, tvb, offset, 8, name);
633 /* Returns true if this looks like a client or server version packet: 12 bytes, in the format "RFB xxx.yyy\n" .
634 * Will check for the 12 bytes exact length, the 'RFB ' string and that it ends with a '\n'.
635 * The exact 'xxx.yyy' is checked later, by trying to convert it to a double using g_ascii_strtod.
638 vnc_is_client_or_server_version_message(tvbuff_t *tvb)
640 if(tvb_length(tvb) != 12) {
644 if(tvb_strncaseeql(tvb, 0, "RFB ", 4) != 0) {
647 /* 0x2e = '.' 0xa = '\n' */
648 if((tvb_get_guint8(tvb, 7) != 0x2e) || (tvb_get_guint8(tvb,11) != 0xa)) {
655 static gboolean test_vnc_protocol(tvbuff_t *tvb, packet_info *pinfo,
658 conversation_t *conversation;
660 if (vnc_is_client_or_server_version_message(tvb)) {
661 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
662 &pinfo->dst, pinfo->ptype,
665 conversation_set_dissector(conversation, vnc_handle);
666 dissect_vnc(tvb, pinfo, tree);
672 /* Returns true if additional session startup messages follow */
674 vnc_startup_messages(tvbuff_t *tvb, packet_info *pinfo, gint offset,
675 proto_tree *tree, vnc_conversation_t
676 *per_conversation_info)
678 guint8 num_security_types;
679 guint32 desktop_name_len, auth_result, text_len;
680 vnc_packet_t *per_packet_info;
681 gint num_tunnel_types;
684 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
686 if(!per_packet_info) {
687 per_packet_info = se_alloc(sizeof(vnc_packet_t));
689 per_packet_info->state = per_conversation_info->vnc_next_state;
690 per_packet_info->preferred_encoding = -1;
692 p_add_proto_data(pinfo->fd, proto_vnc, per_packet_info);
695 /* Packet dissection follows */
696 switch(per_packet_info->state) {
698 case SERVER_VERSION :
699 if (!vnc_is_client_or_server_version_message(tvb))
700 return TRUE; /* we still hope to get a SERVER_VERSION message some day. Do not proceed yet */
702 proto_tree_add_item(tree, hf_vnc_server_proto_ver, tvb, 4,
704 per_conversation_info->server_proto_ver =
705 g_ascii_strtod((char *)tvb_get_ephemeral_string(tvb, 4, 7),
707 per_conversation_info->server_port = pinfo->srcport;
709 if (check_col(pinfo->cinfo, COL_INFO))
710 col_add_fstr(pinfo->cinfo, COL_INFO,
711 "Server protocol version: %s",
712 tvb_format_text(tvb, 4, 7));
714 per_conversation_info->vnc_next_state = CLIENT_VERSION;
717 case CLIENT_VERSION :
718 if (!vnc_is_client_or_server_version_message(tvb))
719 return TRUE; /* we still hope to get a CLIENT_VERSION message some day. Do not proceed yet */
721 proto_tree_add_item(tree, hf_vnc_client_proto_ver, tvb,
723 per_conversation_info->client_proto_ver =
724 g_ascii_strtod((char *)tvb_get_ephemeral_string(tvb, 4, 7),
727 if (check_col(pinfo->cinfo, COL_INFO))
728 col_add_fstr(pinfo->cinfo, COL_INFO,
729 "Client protocol version: %s",
730 tvb_format_text(tvb, 4, 7));
732 per_conversation_info->vnc_next_state = SECURITY;
736 col_set_str(pinfo->cinfo, COL_INFO, "Security types supported");
738 /* We're checking against the client protocol version because
739 * the client is the final decider on which version to use
740 * after the server offers the highest version it supports. */
742 if(per_conversation_info->client_proto_ver >= 3.007) {
743 num_security_types = tvb_get_guint8(tvb, offset);
745 proto_tree_add_item(tree,
746 hf_vnc_num_security_types, tvb,
749 for(offset = 1; offset <= num_security_types; offset++){
750 proto_tree_add_item(tree,
751 hf_vnc_security_type, tvb,
756 /* Version < 3.007: The server decides the
757 * authentication type for us to use */
758 proto_tree_add_item(tree,
759 hf_vnc_server_security_type, tvb,
763 per_conversation_info->vnc_next_state = SECURITY_TYPES;
766 case SECURITY_TYPES :
767 col_set_str(pinfo->cinfo, COL_INFO, "Authentication type selected by client");
768 proto_tree_add_item(tree, hf_vnc_client_security_type, tvb,
770 per_conversation_info->security_type_selected =
771 tvb_get_guint8(tvb, offset);
773 switch(per_conversation_info->security_type_selected) {
776 if(per_conversation_info->client_proto_ver >= 3.008)
777 per_conversation_info->vnc_next_state =
780 per_conversation_info->vnc_next_state =
786 per_conversation_info->vnc_next_state =
787 VNC_AUTHENTICATION_CHALLENGE;
790 case 16 : /* Tight */
791 per_conversation_info->vnc_next_state =
792 TIGHT_TUNNELING_CAPABILITIES;
795 /* Security type not supported by this dissector */
801 case TIGHT_TUNNELING_CAPABILITIES :
802 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC tunneling capabilities supported");
804 proto_tree_add_item(tree, hf_vnc_tight_num_tunnel_types, tvb, offset, 4, FALSE);
805 num_tunnel_types = tvb_get_ntohl(tvb, offset);
811 for(i = 0; i < num_tunnel_types; i++) {
812 /* TightVNC and Xvnc don't support any tunnel capabilities yet, but each capability
813 * is 16 bytes, so skip them.
816 proto_tree_add_item(tree, hf_vnc_tight_tunnel_type, tvb, offset, 16, FALSE);
821 if (num_tunnel_types == 0)
822 per_conversation_info->vnc_next_state = TIGHT_AUTH_CAPABILITIES;
824 per_conversation_info->vnc_next_state = TIGHT_TUNNEL_TYPE_REPLY;
827 case TIGHT_TUNNEL_TYPE_REPLY:
828 /* Neither TightVNC nor Xvnc implement this; they just have a placeholder that emits an error
829 * message and closes the connection (xserver/hw/vnc/auth.c:rfbProcessClientTunnelingType).
830 * We should actually never get here...
834 case TIGHT_AUTH_CAPABILITIES:
835 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC authentication capabilities supported");
837 proto_tree_add_item(tree, hf_vnc_tight_num_auth_types, tvb, offset, 4, FALSE);
838 num_auth_types = tvb_get_ntohl(tvb, offset);
844 for (i = 0; i < num_auth_types; i++) {
845 /* See xserver/hw/vnc/auth.c:rfbSendAuthCaps()
846 * We don't actually display the auth types for now.
848 proto_tree_add_item(tree, hf_vnc_tight_auth_type, tvb, offset, 16, FALSE);
853 if (num_auth_types == 0)
854 per_conversation_info->vnc_next_state = CLIENT_INIT;
856 per_conversation_info->vnc_next_state = TIGHT_AUTH_TYPE_REPLY;
859 case TIGHT_AUTH_TYPE_REPLY:
860 REPORT_DISSECTOR_BUG("Unimplemented case: TightVNC authentication reply");
861 /* FIXME: implement. See xserver/hw/vnc/auth.c:rfbProcessClientAuthType() */
864 case TIGHT_AUTH_TYPE_AND_VENDOR_CODE :
865 col_set_str(pinfo->cinfo, COL_INFO, "Authentication type / vendor code");
867 proto_tree_add_item(tree, hf_vnc_server_security_type, tvb,
872 offset = process_vendor(tree, hf_vnc_vendor_code, tvb, offset);
874 /* Display authentication method string */
875 proto_tree_add_item(tree, hf_vnc_security_type_string, tvb,
878 per_conversation_info->vnc_next_state =
879 TIGHT_UNKNOWN_PACKET3;
883 case TIGHT_UNKNOWN_PACKET3 :
884 col_set_str(pinfo->cinfo, COL_INFO, "Unknown packet (TightVNC)");
886 proto_tree_add_text(tree, tvb, offset, -1,
887 "Unknown packet (TightVNC)");
889 per_conversation_info->vnc_next_state =
890 VNC_AUTHENTICATION_CHALLENGE;
894 case VNC_AUTHENTICATION_CHALLENGE :
895 col_set_str(pinfo->cinfo, COL_INFO, "Authentication challenge from server");
897 proto_tree_add_item(tree, hf_vnc_auth_challenge, tvb,
900 per_conversation_info->vnc_next_state =
901 VNC_AUTHENTICATION_RESPONSE;
904 case VNC_AUTHENTICATION_RESPONSE :
905 col_set_str(pinfo->cinfo, COL_INFO, "Authentication response from client");
907 proto_tree_add_item(tree, hf_vnc_auth_response, tvb,
910 per_conversation_info->vnc_next_state = SECURITY_RESULT;
913 case SECURITY_RESULT :
914 col_set_str(pinfo->cinfo, COL_INFO, "Authentication result");
916 proto_tree_add_item(tree, hf_vnc_auth_result, tvb, offset,
918 auth_result = tvb_get_ntohl(tvb, offset);
921 switch(auth_result) {
924 per_conversation_info->vnc_next_state = CLIENT_INIT;
927 case 1 : /* Failed */
928 if(per_conversation_info->client_proto_ver >= 3.008) {
929 text_len = tvb_get_ntohl(tvb, offset);
930 proto_tree_add_text(tree, tvb, offset, 4, "Length of authentication error: %d", text_len);
933 proto_tree_add_item(tree, hf_vnc_auth_error, tvb,
934 offset, text_len, FALSE);
938 return TRUE; /* All versions: Do not continue
939 processing VNC packets as connection
940 will be closed after this packet. */
948 col_set_str(pinfo->cinfo, COL_INFO, "Share desktop flag");
950 proto_tree_add_item(tree, hf_vnc_share_desktop_flag, tvb,
953 per_conversation_info->vnc_next_state = SERVER_INIT;
958 col_set_str(pinfo->cinfo, COL_INFO, "Server framebuffer parameters");
960 proto_tree_add_item(tree, hf_vnc_width, tvb, offset, 2,
964 proto_tree_add_item(tree, hf_vnc_height, tvb, offset, 2,
968 proto_tree_add_item(tree, hf_vnc_server_bits_per_pixel,
969 tvb, offset, 1, FALSE);
970 vnc_bytes_per_pixel = tvb_get_guint8(tvb, offset)/8;
971 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
974 proto_tree_add_item(tree, hf_vnc_server_depth, tvb, offset,
978 proto_tree_add_item(tree, hf_vnc_server_big_endian_flag,
979 tvb, offset, 1, FALSE);
982 proto_tree_add_item(tree, hf_vnc_server_true_color_flag,
983 tvb, offset, 1, FALSE);
986 proto_tree_add_item(tree, hf_vnc_server_red_max,
987 tvb, offset, 2, FALSE);
990 proto_tree_add_item(tree, hf_vnc_server_green_max,
991 tvb, offset, 2, FALSE);
994 proto_tree_add_item(tree, hf_vnc_server_blue_max,
995 tvb, offset, 2, FALSE);
998 proto_tree_add_item(tree, hf_vnc_server_red_shift,
999 tvb, offset, 1, FALSE);
1002 proto_tree_add_item(tree, hf_vnc_server_green_shift,
1003 tvb, offset, 1, FALSE);
1006 proto_tree_add_item(tree, hf_vnc_server_blue_shift,
1007 tvb, offset, 1, FALSE);
1010 proto_tree_add_item(tree, hf_vnc_padding,
1011 tvb, offset, 3, FALSE);
1012 offset += 3; /* Skip over 3 bytes of padding */
1014 if(tvb_length_remaining(tvb, offset) > 0) {
1015 /* Sometimes the desktop name & length is skipped */
1016 proto_tree_add_item(tree, hf_vnc_desktop_name_len,
1017 tvb, offset, 4, FALSE);
1018 desktop_name_len = tvb_get_ntohl(tvb, offset);
1021 proto_tree_add_item(tree, hf_vnc_desktop_name,
1022 tvb, offset, desktop_name_len,
1026 if(per_conversation_info->security_type_selected == TIGHT)
1027 per_conversation_info->vnc_next_state =
1028 TIGHT_INTERACTION_CAPS;
1030 per_conversation_info->vnc_next_state = NORMAL_TRAFFIC;
1033 case TIGHT_INTERACTION_CAPS :
1034 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC Interaction Capabilities");
1036 proto_tree_add_item(tree, hf_vnc_num_server_message_types,
1037 tvb, offset, 2, FALSE);
1038 per_conversation_info->num_server_message_types = tvb_get_ntohs(tvb, offset);
1041 proto_tree_add_item(tree, hf_vnc_num_client_message_types,
1042 tvb, offset, 2, FALSE);
1043 per_conversation_info->num_client_message_types = tvb_get_ntohs(tvb, offset);
1046 proto_tree_add_item(tree, hf_vnc_num_encoding_types,
1047 tvb, offset, 2, FALSE);
1048 per_conversation_info->num_encoding_types = tvb_get_ntohs(tvb, offset);
1051 proto_tree_add_item(tree, hf_vnc_padding, tvb, offset, 2,
1055 per_conversation_info->vnc_next_state = TIGHT_INTERACTION_CAPS_LIST;
1058 case TIGHT_INTERACTION_CAPS_LIST:
1059 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC Interaction Capabilities list");
1061 offset = process_tight_capabilities(tree,
1062 hf_vnc_tight_server_message_type,
1063 hf_vnc_tight_server_vendor,
1064 hf_vnc_tight_server_name,
1065 tvb, offset, per_conversation_info->num_server_message_types);
1066 offset = process_tight_capabilities(tree,
1067 hf_vnc_tight_client_message_type,
1068 hf_vnc_tight_client_vendor,
1069 hf_vnc_tight_client_name,
1070 tvb, offset, per_conversation_info->num_client_message_types);
1071 offset = process_tight_capabilities(tree,
1072 hf_vnc_tight_encoding_type,
1073 hf_vnc_tight_encoding_vendor,
1074 hf_vnc_tight_encoding_name,
1075 tvb, offset, per_conversation_info->num_encoding_types);
1077 per_conversation_info->vnc_next_state = NORMAL_TRAFFIC;
1080 case NORMAL_TRAFFIC :
1089 vnc_client_to_server(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1092 guint8 message_type;
1094 proto_item *ti=NULL;
1095 proto_tree *vnc_client_message_type_tree;
1097 message_type = tvb_get_guint8(tvb, *offset);
1099 ti = proto_tree_add_item(tree, hf_vnc_client_message_type, tvb,
1102 vnc_client_message_type_tree =
1103 proto_item_add_subtree(ti, ett_vnc_client_message_type);
1107 switch(message_type) {
1110 vnc_client_set_pixel_format(tvb, pinfo, offset,
1111 vnc_client_message_type_tree);
1115 vnc_client_set_encodings(tvb, pinfo, offset,
1116 vnc_client_message_type_tree);
1120 vnc_client_framebuffer_update_request(tvb, pinfo, offset,
1121 vnc_client_message_type_tree);
1125 vnc_client_key_event(tvb, pinfo, offset,
1126 vnc_client_message_type_tree);
1130 vnc_client_pointer_event(tvb, pinfo, offset,
1131 vnc_client_message_type_tree);
1135 vnc_client_cut_text(tvb, pinfo, offset,
1136 vnc_client_message_type_tree);
1140 if (check_col(pinfo->cinfo, COL_INFO))
1141 col_append_fstr(pinfo->cinfo, COL_INFO,
1142 "Unknown client message type (%u)",
1149 vnc_server_to_client(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1153 guint8 message_type;
1154 gint bytes_needed = 0, length_remaining;
1156 proto_item *ti=NULL;
1157 proto_tree *vnc_server_message_type_tree;
1159 start_offset = *offset;
1161 message_type = tvb_get_guint8(tvb, *offset);
1163 ti = proto_tree_add_item(tree, hf_vnc_server_message_type, tvb,
1165 vnc_server_message_type_tree =
1166 proto_item_add_subtree(ti, ett_vnc_server_message_type);
1170 switch(message_type) {
1174 vnc_server_framebuffer_update(tvb, pinfo, offset,
1175 vnc_server_message_type_tree);
1179 bytes_needed = vnc_server_set_colormap_entries(tvb, pinfo, offset, vnc_server_message_type_tree);
1183 vnc_server_ring_bell(tvb, pinfo, offset,
1184 vnc_server_message_type_tree);
1188 bytes_needed = vnc_server_cut_text(tvb, pinfo, offset,
1189 vnc_server_message_type_tree);
1193 if (check_col(pinfo->cinfo, COL_INFO))
1194 col_append_str(pinfo->cinfo, COL_INFO,
1195 "Unknown server message type");
1199 if(bytes_needed > 0 && vnc_preference_desegment &&
1200 pinfo->can_desegment) {
1201 length_remaining = tvb_length_remaining(tvb, *offset);
1203 pinfo->desegment_offset = start_offset;
1204 pinfo->desegment_len = bytes_needed - length_remaining;
1211 vnc_client_set_pixel_format(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1214 col_set_str(pinfo->cinfo, COL_INFO, "Client set pixel format");
1216 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset,
1218 *offset += 3; /* Skip over 3 bytes of padding */
1220 proto_tree_add_item(tree, hf_vnc_client_bits_per_pixel, tvb, *offset,
1222 vnc_bytes_per_pixel = tvb_get_guint8(tvb, *offset)/8;
1223 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
1226 proto_tree_add_item(tree, hf_vnc_client_depth, tvb, *offset,
1228 vnc_depth = tvb_get_guint8(tvb, *offset);
1229 vnc_set_depth(pinfo, vnc_depth);
1232 proto_tree_add_item(tree, hf_vnc_client_big_endian_flag, tvb, *offset,
1236 proto_tree_add_item(tree, hf_vnc_client_true_color_flag, tvb, *offset,
1240 proto_tree_add_item(tree, hf_vnc_client_red_max, tvb, *offset,
1244 proto_tree_add_item(tree, hf_vnc_client_green_max, tvb, *offset,
1248 proto_tree_add_item(tree, hf_vnc_client_blue_max, tvb, *offset,
1252 proto_tree_add_item(tree, hf_vnc_client_red_shift, tvb, *offset,
1256 proto_tree_add_item(tree, hf_vnc_client_green_shift, tvb, *offset,
1260 proto_tree_add_item(tree, hf_vnc_client_blue_shift, tvb, *offset,
1264 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset,
1266 *offset += 3; /* Skip over 3 bytes of padding */
1271 vnc_client_set_encodings(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1274 guint16 number_of_encodings;
1276 vnc_packet_t *per_packet_info;
1278 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
1280 col_set_str(pinfo->cinfo, COL_INFO, "Client set encodings");
1282 proto_tree_add_item(tree, hf_vnc_padding,
1283 tvb, *offset, 1, FALSE);
1284 *offset += 1; /* Skip over 1 byte of padding */
1286 number_of_encodings = tvb_get_ntohs(tvb, *offset);
1288 proto_tree_add_text(tree, tvb, *offset, 2,
1289 "Number of encodings: %d", number_of_encodings);
1292 per_packet_info->preferred_encoding = -1;
1294 for(counter = 1; counter <= number_of_encodings; counter++) {
1295 proto_tree_add_item(tree,
1296 hf_vnc_client_set_encodings_encoding_type,
1297 tvb, *offset, 4, FALSE);
1299 /* Remember the first real encoding as the preferred encoding,
1300 * per xserver/hw/vnc/rfbserver.c:rfbProcessClientNormalMessage().
1301 * Otherwise, use RAW as the preferred encoding.
1303 if (per_packet_info->preferred_encoding == -1) {
1306 encoding = tvb_get_ntohl(tvb, *offset);
1311 case ENCODING_CORRE:
1312 case ENCODING_HEXTILE:
1314 case ENCODING_TIGHT:
1315 per_packet_info->preferred_encoding = encoding;
1323 if (per_packet_info->preferred_encoding == -1)
1324 per_packet_info->preferred_encoding = ENCODING_RAW;
1329 vnc_client_framebuffer_update_request(tvbuff_t *tvb, packet_info *pinfo,
1330 gint *offset, proto_tree *tree)
1332 col_set_str(pinfo->cinfo, COL_INFO, "Client framebuffer update request");
1334 proto_tree_add_item(tree, hf_vnc_update_req_incremental,
1335 tvb, *offset, 1, FALSE);
1338 proto_tree_add_item(tree, hf_vnc_update_req_x_pos,
1339 tvb, *offset, 2, FALSE);
1342 proto_tree_add_item(tree, hf_vnc_update_req_y_pos,
1343 tvb, *offset, 2, FALSE);
1346 proto_tree_add_item(tree, hf_vnc_update_req_width, tvb,
1350 proto_tree_add_item(tree, hf_vnc_update_req_height, tvb,
1357 vnc_client_key_event(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1360 col_set_str(pinfo->cinfo, COL_INFO, "Client key event");
1362 proto_tree_add_item(tree, hf_vnc_key_down, tvb, *offset, 1, FALSE);
1365 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 2, FALSE);
1366 *offset += 2; /* Skip over 2 bytes of padding */
1368 proto_tree_add_item(tree, hf_vnc_key, tvb, *offset, 4, FALSE);
1374 vnc_client_pointer_event(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1377 col_set_str(pinfo->cinfo, COL_INFO, "Client pointer event");
1379 proto_tree_add_item(tree, hf_vnc_button_1_pos, tvb, *offset, 1, FALSE);
1380 proto_tree_add_item(tree, hf_vnc_button_2_pos, tvb, *offset, 1, FALSE);
1381 proto_tree_add_item(tree, hf_vnc_button_3_pos, tvb, *offset, 1, FALSE);
1382 proto_tree_add_item(tree, hf_vnc_button_4_pos, tvb, *offset, 1, FALSE);
1383 proto_tree_add_item(tree, hf_vnc_button_5_pos, tvb, *offset, 1, FALSE);
1384 proto_tree_add_item(tree, hf_vnc_button_6_pos, tvb, *offset, 1, FALSE);
1385 proto_tree_add_item(tree, hf_vnc_button_7_pos, tvb, *offset, 1, FALSE);
1386 proto_tree_add_item(tree, hf_vnc_button_8_pos, tvb, *offset, 1, FALSE);
1389 proto_tree_add_item(tree, hf_vnc_pointer_x_pos, tvb, *offset, 2, FALSE);
1392 proto_tree_add_item(tree, hf_vnc_pointer_y_pos, tvb, *offset, 2, FALSE);
1398 vnc_client_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1403 col_set_str(pinfo->cinfo, COL_INFO, "Client cut text");
1405 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 3, FALSE);
1406 *offset += 3; /* Skip over 3 bytes of padding */
1408 text_len = tvb_get_ntohl(tvb, *offset);
1409 proto_tree_add_item(tree, hf_vnc_client_cut_text_len, tvb, *offset, 4,
1413 proto_tree_add_item(tree, hf_vnc_client_cut_text, tvb, *offset,
1415 *offset += text_len;
1421 vnc_server_framebuffer_update(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1425 guint16 width, height;
1426 guint bytes_needed = 0;
1427 gint32 encoding_type;
1428 proto_item *ti, *ti_x, *ti_y, *ti_width, *ti_height;
1429 proto_tree *vnc_rect_tree, *vnc_encoding_type_tree;
1431 col_set_str(pinfo->cinfo, COL_INFO, "Server framebuffer update");
1433 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 1, FALSE);
1436 num_rects = tvb_get_ntohs(tvb, *offset);
1437 proto_tree_add_text(tree, tvb, *offset, 2, "Number of rectangles: %d",
1441 for(i = 1; i <= num_rects; i++) {
1443 VNC_BYTES_NEEDED(12);
1445 ti = proto_tree_add_text(tree, tvb, *offset, 12,
1446 "Rectangle #%d", i);
1449 proto_item_add_subtree(ti, ett_vnc_rect);
1451 ti_x = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_x_pos,
1452 tvb, *offset, 2, FALSE);
1455 ti_y = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_y_pos,
1456 tvb, *offset, 2, FALSE);
1459 ti_width = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_width,
1460 tvb, *offset, 2, FALSE);
1461 width = tvb_get_ntohs(tvb, *offset);
1464 ti_height = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_height,
1465 tvb, *offset, 2, FALSE);
1466 height = tvb_get_ntohs(tvb, *offset);
1469 ti = proto_tree_add_item(vnc_rect_tree,
1470 hf_vnc_fb_update_encoding_type,
1471 tvb, *offset, 4, FALSE);
1473 encoding_type = tvb_get_ntohl(tvb, *offset);
1476 if (encoding_type == ENCODING_LAST_RECT)
1477 break; /* exit the loop */
1479 vnc_encoding_type_tree =
1480 proto_item_add_subtree(ti, ett_vnc_encoding_type);
1482 switch(encoding_type) {
1485 bytes_needed = vnc_raw_encoding(tvb, pinfo, offset,
1486 vnc_encoding_type_tree,
1490 case ENCODING_COPY_RECT:
1492 vnc_copyrect_encoding(tvb, pinfo, offset,
1493 vnc_encoding_type_tree,
1499 vnc_rre_encoding(tvb, pinfo, offset,
1500 vnc_encoding_type_tree,
1504 case ENCODING_HEXTILE:
1506 vnc_hextile_encoding(tvb, pinfo, offset,
1507 vnc_encoding_type_tree,
1513 vnc_zrle_encoding(tvb, pinfo, offset,
1514 vnc_encoding_type_tree,
1518 case ENCODING_TIGHT:
1520 vnc_tight_encoding(tvb, pinfo, offset,
1521 vnc_encoding_type_tree,
1525 case ENCODING_RICH_CURSOR:
1526 case ENCODING_X_CURSOR:
1527 proto_item_append_text (ti_x, " (hotspot X)");
1528 proto_item_append_text (ti_y, " (hotspot Y)");
1529 proto_item_append_text (ti_width, " (cursor width)");
1530 proto_item_append_text (ti_height, " (cursor height)");
1532 if (encoding_type == ENCODING_RICH_CURSOR)
1533 bytes_needed = vnc_rich_cursor_encoding(tvb, pinfo, offset, vnc_encoding_type_tree, width, height);
1535 bytes_needed = vnc_x_cursor_encoding(tvb, pinfo, offset, vnc_encoding_type_tree, width, height);
1539 case ENCODING_POINTER_POS:
1540 proto_item_append_text (ti_x, " (pointer X)");
1541 proto_item_append_text (ti_y, " (pointer Y)");
1542 proto_item_append_text (ti_width, " (unused)");
1543 proto_item_append_text (ti_height, " (unused)");
1547 case ENCODING_DESKTOP_SIZE:
1549 /* There is no payload for this message type */
1556 /* Check if the routines above requested more bytes to
1557 * be desegmented. */
1558 if(bytes_needed > 0)
1559 return bytes_needed;
1567 vnc_raw_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1568 proto_tree *tree, guint16 width, guint16 height)
1570 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1573 length = width * height * bytes_per_pixel;
1574 VNC_BYTES_NEEDED(length);
1576 proto_tree_add_item(tree, hf_vnc_raw_pixel_data, tvb, *offset,
1580 return 0; /* bytes_needed */
1585 vnc_copyrect_encoding(tvbuff_t *tvb, packet_info *pinfo _U_, gint *offset,
1586 proto_tree *tree, guint16 width _U_, guint16 height _U_)
1588 proto_tree_add_item(tree, hf_vnc_copyrect_src_x_pos, tvb, *offset,
1592 proto_tree_add_item(tree, hf_vnc_copyrect_src_y_pos, tvb, *offset,
1596 return 0; /* bytes_needed */
1601 vnc_rre_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1602 proto_tree *tree, guint16 width _U_, guint16 height _U_)
1604 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1605 guint32 num_subrects, i;
1608 proto_tree *subrect_tree;
1610 VNC_BYTES_NEEDED(4);
1611 proto_tree_add_item(tree, hf_vnc_rre_num_subrects, tvb, *offset,
1613 num_subrects = tvb_get_ntohl(tvb, *offset);
1616 VNC_BYTES_NEEDED(bytes_per_pixel);
1617 proto_tree_add_item(tree, hf_vnc_rre_bg_pixel, tvb, *offset,
1618 bytes_per_pixel, FALSE);
1619 *offset += bytes_per_pixel;
1621 for(i = 1; i <= num_subrects; i++) {
1622 bytes_needed = bytes_per_pixel + 8;
1623 VNC_BYTES_NEEDED(bytes_needed);
1625 ti = proto_tree_add_text(tree, tvb, *offset, bytes_per_pixel +
1626 8, "Subrectangle #%d", i);
1628 proto_item_add_subtree(ti, ett_vnc_rre_subrect);
1630 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_pixel,
1631 tvb, *offset, bytes_per_pixel, FALSE);
1632 *offset += bytes_per_pixel;
1634 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_x_pos,
1635 tvb, *offset, 2, FALSE);
1638 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_y_pos,
1639 tvb, *offset, 2, FALSE);
1642 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_width,
1643 tvb, *offset, 2, FALSE);
1646 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_height,
1647 tvb, *offset, 2, FALSE);
1651 return 0; /* bytes_needed */
1656 vnc_hextile_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1657 proto_tree *tree, guint16 width, guint16 height)
1659 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1660 guint8 i, subencoding_mask, num_subrects, subrect_len;
1662 proto_tree *subencoding_mask_tree, *subrect_tree, *num_subrects_tree;
1665 VNC_BYTES_NEEDED(1);
1666 ti = proto_tree_add_item(tree, hf_vnc_hextile_subencoding_mask, tvb,
1668 subencoding_mask = tvb_get_guint8(tvb, *offset);
1670 subencoding_mask_tree =
1671 proto_item_add_subtree(ti, ett_vnc_hextile_subencoding_mask);
1673 proto_tree_add_item(subencoding_mask_tree,
1674 hf_vnc_hextile_raw, tvb, *offset, 1,
1676 proto_tree_add_item(subencoding_mask_tree,
1677 hf_vnc_hextile_bg, tvb, *offset, 1,
1679 proto_tree_add_item(subencoding_mask_tree,
1680 hf_vnc_hextile_fg, tvb, *offset, 1,
1682 proto_tree_add_item(subencoding_mask_tree,
1683 hf_vnc_hextile_anysubrects, tvb, *offset, 1,
1685 proto_tree_add_item(subencoding_mask_tree,
1686 hf_vnc_hextile_subrectscolored, tvb, *offset, 1,
1690 if(subencoding_mask & 0x1) { /* Raw */
1691 length = width * height * bytes_per_pixel;
1693 VNC_BYTES_NEEDED(length);
1695 proto_tree_add_item(tree, hf_vnc_hextile_raw_value, tvb,
1696 *offset, length, FALSE);
1699 if(subencoding_mask & 0x2) { /* Background Specified */
1700 proto_tree_add_item(tree, hf_vnc_hextile_bg_value,
1701 tvb, *offset, bytes_per_pixel,
1703 *offset += bytes_per_pixel;
1706 if(subencoding_mask & 0x4) { /* Foreground Specified */
1707 proto_tree_add_item(tree, hf_vnc_hextile_fg_value,
1708 tvb, *offset, bytes_per_pixel,
1710 *offset += bytes_per_pixel;
1713 if(subencoding_mask & 0x8) { /* Any Subrects */
1714 ti = proto_tree_add_item(tree,
1715 hf_vnc_hextile_num_subrects,
1718 num_subrects = tvb_get_guint8(tvb, *offset);
1722 proto_item_add_subtree(ti, ett_vnc_hextile_num_subrects);
1724 for(i = 1; i <= num_subrects; i++) {
1726 if(subencoding_mask & 0x16)
1727 subrect_len = bytes_per_pixel + 2;
1731 ti = proto_tree_add_text(num_subrects_tree, tvb,
1732 *offset, subrect_len,
1733 "Subrectangle #%d", i);
1736 proto_item_add_subtree(ti, ett_vnc_hextile_subrect);
1738 if(subencoding_mask & 0x16) {
1739 /* Subrects Colored */
1740 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_pixel_value, tvb, *offset, bytes_per_pixel, FALSE);
1742 *offset += bytes_per_pixel;
1745 proto_tree_add_item(subrect_tree,
1746 hf_vnc_hextile_subrect_x_pos, tvb, *offset, 1, FALSE);
1748 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_y_pos, tvb, *offset, 1, FALSE);
1752 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_width, tvb, *offset, 1, FALSE);
1754 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_height, tvb, *offset, 1, FALSE);
1761 return 0; /* bytes_needed */
1766 vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1767 proto_tree *tree, guint16 width, guint16 height)
1770 vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo _U_, gint *offset,
1771 proto_tree *tree, guint16 width _U_, guint16 height _U_)
1776 guint8 palette_size;
1777 guint8 bytes_per_cpixel = vnc_get_bytes_per_pixel(pinfo);
1778 gint uncomp_offset = 0;
1780 gint subencoding_type;
1781 tvbuff_t *uncomp_tvb = NULL;
1782 proto_tree *zrle_subencoding_tree;
1786 VNC_BYTES_NEEDED(4);
1787 proto_tree_add_item(tree, hf_vnc_zrle_len, tvb, *offset,
1789 data_len = tvb_get_ntohl(tvb, *offset);
1793 VNC_BYTES_NEEDED(data_len);
1795 proto_tree_add_item(tree, hf_vnc_zrle_data, tvb, *offset,
1799 uncomp_tvb = tvb_child_uncompress(tvb, tvb, *offset, data_len);
1801 if(uncomp_tvb != NULL) {
1802 add_new_data_source(pinfo, uncomp_tvb,
1803 "Uncompressed ZRLE data");
1805 ti = proto_tree_add_item(tree, hf_vnc_zrle_subencoding,
1806 uncomp_tvb, uncomp_offset, 1, FALSE);
1807 zrle_subencoding_tree =
1808 proto_item_add_subtree(ti, ett_vnc_zrle_subencoding);
1810 proto_tree_add_item(zrle_subencoding_tree, hf_vnc_zrle_rle,
1811 uncomp_tvb, uncomp_offset, 1, FALSE);
1813 proto_tree_add_item(zrle_subencoding_tree,
1814 hf_vnc_zrle_palette_size, uncomp_tvb,
1815 uncomp_offset, 1, FALSE);
1817 subencoding_type = tvb_get_guint8(uncomp_tvb, uncomp_offset);
1818 palette_size = subencoding_type & 0x7F;
1822 if(subencoding_type == 0) { /* Raw */
1823 length = width * height * bytes_per_cpixel;
1824 VNC_BYTES_NEEDED(length);
1826 /* XXX - not working yet! */
1828 proto_tree_add_item(zrle_subencoding_tree,
1829 hf_vnc_zrle_raw, uncomp_tvb,
1830 uncomp_offset, length, FALSE);
1832 } else if(subencoding_type >= 130 && subencoding_type <= 255) {
1833 length = palette_size * bytes_per_cpixel;
1834 VNC_BYTES_NEEDED(length);
1836 proto_tree_add_item(zrle_subencoding_tree,
1837 hf_vnc_zrle_palette, uncomp_tvb,
1838 uncomp_offset, length, FALSE);
1840 /* XXX - Not complete! */
1844 proto_tree_add_text(tree, tvb, *offset, data_len,
1845 "Decompression of ZRLE data failed");
1847 #endif /* HAVE_LIBZ */
1849 *offset += data_len;
1851 return 0; /* bytes_needed */
1856 read_compact_len(tvbuff_t *tvb, gint *offset, gint *length, gint *value_length)
1860 VNC_BYTES_NEEDED(1);
1864 b = tvb_get_guint8(tvb, *offset);
1869 if ((b & 0x80) != 0) {
1870 VNC_BYTES_NEEDED(1);
1872 b = tvb_get_guint8(tvb, *offset);
1876 *length |= (b & 0x7f) << 7;
1878 if ((b & 0x80) != 0) {
1879 VNC_BYTES_NEEDED (1);
1881 b = tvb_get_guint8(tvb, *offset);
1885 *length |= (b & 0xff) << 14;
1894 process_compact_length_and_image_data(tvbuff_t *tvb, gint *offset, proto_tree *tree)
1897 guint length, value_length;
1899 bytes_needed = read_compact_len (tvb, offset, &length, &value_length);
1900 if (bytes_needed != 0)
1901 return bytes_needed;
1903 proto_tree_add_uint(tree, hf_vnc_tight_image_len, tvb, *offset - value_length, value_length, length);
1905 VNC_BYTES_NEEDED(length);
1906 proto_tree_add_item(tree, hf_vnc_tight_image_data, tvb, *offset, length, FALSE);
1909 return 0; /* bytes_needed */
1914 process_tight_rect_filter_palette(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1915 proto_tree *tree, gint *bits_per_pixel)
1917 vnc_packet_t *per_packet_info;
1919 guint palette_bytes;
1921 /* See TightVNC's vnc_unixsrc/vncviewer/tight.c:InitFilterPaletteBPP() */
1923 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
1925 VNC_BYTES_NEEDED(1);
1926 proto_tree_add_item(tree, hf_vnc_tight_palette_num_colors, tvb, *offset, 1, FALSE);
1927 num_colors = tvb_get_guint8(tvb, *offset);
1934 if (per_packet_info->depth == 24)
1935 palette_bytes = num_colors * 3;
1937 palette_bytes = num_colors * per_packet_info->depth / 8;
1939 VNC_BYTES_NEEDED(palette_bytes);
1940 proto_tree_add_item(tree, hf_vnc_tight_palette_data, tvb, *offset, palette_bytes, FALSE);
1941 *offset += palette_bytes;
1943 /* This is the number of bits per pixel *in the image data*, not the actual client depth */
1944 if (num_colors == 2)
1945 *bits_per_pixel = 1;
1947 *bits_per_pixel = 8;
1953 vnc_tight_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1954 proto_tree *tree, guint16 width, guint16 height)
1956 vnc_packet_t *per_packet_info;
1958 proto_item *compression_type_ti;
1960 gint bytes_needed = -1;
1962 /* unused arguments */
1966 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
1968 /* See xserver/hw/vnc/rfbproto.h and grep for "Tight Encoding." for the following layout */
1970 VNC_BYTES_NEEDED(1);
1972 /* least significant bits 0-3 are "reset compression stream N" */
1973 bit_offset = *offset * 8;
1974 proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream0, tvb, bit_offset + 7, 1, FALSE);
1975 proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream1, tvb, bit_offset + 6, 1, FALSE);
1976 proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream2, tvb, bit_offset + 5, 1, FALSE);
1977 proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream3, tvb, bit_offset + 4, 1, FALSE);
1979 /* most significant bits 4-7 are "compression type" */
1980 compression_type_ti = proto_tree_add_bits_item(tree, hf_vnc_tight_rect_type, tvb, bit_offset + 0, 4, FALSE);
1982 comp_ctl = tvb_get_guint8(tvb, *offset);
1985 comp_ctl >>= 4; /* skip over the "reset compression" bits from above */
1987 /* compression format */
1989 if (comp_ctl == TIGHT_RECT_FILL) {
1990 /* "fill" encoding (solid rectangle) */
1992 proto_item_append_text(compression_type_ti, " (fill encoding - solid rectangle)");
1994 if (per_packet_info->depth == 24) {
1995 VNC_BYTES_NEEDED(3);
1996 proto_tree_add_item(tree, hf_vnc_tight_fill_color, tvb, *offset, 3, FALSE);
1999 VNC_BYTES_NEEDED(per_packet_info->bytes_per_pixel);
2000 proto_tree_add_item(tree, hf_vnc_tight_fill_color, tvb, *offset, per_packet_info->bytes_per_pixel, FALSE);
2001 *offset += per_packet_info->bytes_per_pixel;
2005 } else if (comp_ctl == TIGHT_RECT_JPEG) {
2008 proto_item_append_text(compression_type_ti, " (JPEG encoding)");
2009 bytes_needed = process_compact_length_and_image_data(tvb, offset, tree);
2010 if (bytes_needed != 0)
2011 return bytes_needed;
2012 } else if (comp_ctl > TIGHT_RECT_MAX_VALUE) {
2013 /* invalid encoding */
2015 proto_item_append_text(compression_type_ti, " (invalid encoding)");
2016 DISSECTOR_ASSERT_NOT_REACHED();
2019 gint bits_per_pixel;
2021 /* basic encoding */
2023 proto_item_append_text(compression_type_ti, " (basic encoding)");
2025 proto_tree_add_bits_item(tree, hf_vnc_tight_filter_flag, tvb, bit_offset + 1, 1, FALSE);
2027 bits_per_pixel = per_packet_info->depth;
2029 if ((comp_ctl & TIGHT_RECT_EXPLICIT_FILTER_FLAG) != 0) {
2032 /* explicit filter */
2034 VNC_BYTES_NEEDED(1);
2035 proto_tree_add_item(tree, hf_vnc_tight_filter_id, tvb, *offset, 1, FALSE);
2036 filter_id = tvb_get_guint8(tvb, *offset);
2039 switch (filter_id) {
2040 case TIGHT_RECT_FILTER_COPY:
2044 case TIGHT_RECT_FILTER_PALETTE:
2045 bytes_needed = process_tight_rect_filter_palette(tvb, pinfo, offset, tree, &bits_per_pixel);
2046 if (bytes_needed != 0)
2047 return bytes_needed;
2051 case TIGHT_RECT_FILTER_GRADIENT:
2056 /* this is the same case as TIGHT_RECT_FILTER_COPY, so there's nothing special to do */
2059 row_size = ((guint) width * bits_per_pixel + 7) / 8;
2060 if (row_size * height < TIGHT_MIN_BYTES_TO_COMPRESS) {
2063 /* The data is not compressed; just skip over it */
2065 num_bytes = row_size * height;
2066 VNC_BYTES_NEEDED(num_bytes);
2067 proto_tree_add_item(tree, hf_vnc_tight_image_data, tvb, *offset, num_bytes, FALSE);
2068 *offset += num_bytes;
2072 /* The data is compressed; read its length and data */
2073 bytes_needed = process_compact_length_and_image_data(tvb, offset, tree);
2074 if (bytes_needed != 0)
2075 return bytes_needed;
2079 DISSECTOR_ASSERT(bytes_needed != -1);
2081 return bytes_needed;
2086 decode_cursor(tvbuff_t *tvb, gint *offset, proto_tree *tree,
2087 guint pixels_bytes, guint mask_bytes)
2091 total_bytes = pixels_bytes + mask_bytes;
2092 VNC_BYTES_NEEDED (total_bytes);
2094 proto_tree_add_item(tree, hf_vnc_cursor_encoding_pixels, tvb, *offset,
2095 pixels_bytes, FALSE);
2096 *offset += pixels_bytes;
2098 proto_tree_add_item(tree, hf_vnc_cursor_encoding_bitmask, tvb, *offset,
2100 *offset += mask_bytes;
2102 return 0; /* bytes_needed */
2107 vnc_rich_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2108 proto_tree *tree, guint16 width, guint16 height)
2110 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
2111 guint pixels_bytes, mask_bytes;
2113 pixels_bytes = width * height * bytes_per_pixel;
2114 mask_bytes = ((width + 7) / 8) * height;
2116 return decode_cursor(tvb, offset, tree,
2117 pixels_bytes, mask_bytes);
2122 vnc_x_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2123 proto_tree *tree, guint16 width, guint16 height)
2125 gint bitmap_row_bytes = (width + 7) / 8;
2126 gint mask_bytes = bitmap_row_bytes * height;
2127 (void) pinfo; /* unused argument */
2129 VNC_BYTES_NEEDED (6);
2130 proto_tree_add_item(tree, hf_vnc_cursor_x_fore_back, tvb, *offset, 6, FALSE);
2133 /* The length of the pixel data is the same as the length of the mask data (X cursors are strictly black/white) */
2134 return decode_cursor(tvb, offset, tree,
2135 mask_bytes, mask_bytes);
2140 vnc_server_set_colormap_entries(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2143 guint16 number_of_colors;
2144 guint counter, bytes_needed;
2146 proto_tree *vnc_colormap_num_groups, *vnc_colormap_color_group;
2148 col_set_str(pinfo->cinfo, COL_INFO, "Server set colormap entries");
2150 number_of_colors = tvb_get_ntohs(tvb, 4);
2152 bytes_needed = (number_of_colors * 6) + 6;
2153 VNC_BYTES_NEEDED(bytes_needed);
2155 ti = proto_tree_add_item(tree, hf_vnc_server_message_type, tvb,
2157 tree = proto_item_add_subtree(ti, ett_vnc_server_message_type);
2160 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 1, FALSE);
2161 *offset += 1; /* Skip over 1 byte of padding */
2163 proto_tree_add_item(tree,
2164 hf_vnc_colormap_first_color,
2165 tvb, *offset, 2, FALSE);
2168 ti = proto_tree_add_item(tree, hf_vnc_colormap_num_colors, tvb,
2170 vnc_colormap_num_groups =
2171 proto_item_add_subtree(ti, ett_vnc_colormap_num_groups);
2175 for(counter = 1; counter <= number_of_colors; counter++) {
2176 ti = proto_tree_add_text(vnc_colormap_num_groups, tvb,
2178 "Color group #%d", counter);
2180 vnc_colormap_color_group =
2181 proto_item_add_subtree(ti,
2182 ett_vnc_colormap_color_group);
2184 proto_tree_add_item(vnc_colormap_color_group,
2185 hf_vnc_colormap_red, tvb,
2189 proto_tree_add_item(vnc_colormap_color_group,
2190 hf_vnc_colormap_green, tvb,
2194 proto_tree_add_item(vnc_colormap_color_group,
2195 hf_vnc_colormap_blue, tvb,
2204 vnc_server_ring_bell(tvbuff_t *tvb _U_, packet_info *pinfo, gint *offset _U_,
2205 proto_tree *tree _U_)
2207 col_set_str(pinfo->cinfo, COL_INFO, "Server ring bell on client");
2208 /* This message type has no payload... */
2213 vnc_server_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2218 col_set_str(pinfo->cinfo, COL_INFO, "Server cut text");
2220 text_len = tvb_get_ntohl(tvb, *offset);
2221 proto_tree_add_item(tree,
2222 hf_vnc_server_cut_text_len, tvb, *offset, 4,
2226 VNC_BYTES_NEEDED(text_len);
2228 proto_tree_add_item(tree, hf_vnc_server_cut_text, tvb, *offset,
2230 *offset += text_len;
2237 vnc_set_bytes_per_pixel(packet_info *pinfo, guint8 bytes_per_pixel)
2239 vnc_packet_t *per_packet_info;
2241 /* The per_packet_info has already been created by the
2242 * vnc_startup_messages() routine. */
2243 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
2244 per_packet_info->bytes_per_pixel = bytes_per_pixel;
2249 vnc_set_depth(packet_info *pinfo, guint8 depth)
2251 vnc_packet_t *per_packet_info;
2253 /* The per_packet_info has already been created by the
2254 * vnc_startup_messages() routine. */
2255 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
2256 per_packet_info->depth = depth;
2261 vnc_get_bytes_per_pixel(packet_info *pinfo)
2263 vnc_packet_t *per_packet_info;
2265 /* The per_packet_info has already been created by the
2266 * vnc_startup_messages() routine. */
2267 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
2268 return per_packet_info->bytes_per_pixel;
2272 /* Register the protocol with Wireshark */
2274 proto_register_vnc(void)
2276 module_t *vnc_module; /* To handle our preferences */
2278 /* Setup list of header fields */
2279 static hf_register_info hf[] = {
2281 { "Padding", "vnc.padding",
2282 FT_NONE, BASE_NONE, NULL, 0x0,
2283 "Unused space", HFILL }
2286 { &hf_vnc_server_proto_ver,
2287 { "Server protocol version", "vnc.server_proto_ver",
2288 FT_STRING, BASE_NONE, NULL, 0x0,
2289 "VNC protocol version on server", HFILL }
2291 { &hf_vnc_client_proto_ver,
2292 { "Client protocol version", "vnc.client_proto_ver",
2293 FT_STRING, BASE_NONE, NULL, 0x0,
2294 "VNC protocol version on client", HFILL }
2296 { &hf_vnc_num_security_types,
2297 { "Number of security types", "vnc.num_security_types",
2298 FT_UINT8, BASE_DEC, NULL, 0x0,
2299 "Number of security (authentication) types supported by the server", HFILL }
2301 { &hf_vnc_security_type,
2302 { "Security type", "vnc.security_type",
2303 FT_UINT8, BASE_DEC, VALS(security_types_vs), 0x0,
2304 "Security types offered by the server (VNC versions => 3.007", HFILL }
2306 { &hf_vnc_server_security_type,
2307 { "Security type", "vnc.server_security_type",
2308 FT_UINT32, BASE_DEC, VALS(security_types_vs), 0x0,
2309 "Security type mandated by the server", HFILL }
2311 { &hf_vnc_client_security_type,
2312 { "Security type selected", "vnc.security_type",
2313 FT_UINT8, BASE_DEC, VALS(security_types_vs), 0x0,
2314 "Security type selected by the client", HFILL }
2316 { &hf_vnc_tight_num_tunnel_types,
2317 { "Number of supported tunnel types", "vnc.num_tunnel_types",
2318 FT_UINT32, BASE_DEC, NULL, 0x0,
2319 "Number of tunnel types for TightVNC", HFILL }
2321 { &hf_vnc_tight_tunnel_type,
2322 { "Tunnel type", "vnc.tunnel_type",
2323 FT_UINT8, BASE_DEC, NULL, 0x0,
2324 "Tunnel type specific to TightVNC", HFILL }
2326 { &hf_vnc_tight_num_auth_types,
2327 { "Number of supported authentication types", "vnc.num_auth_types",
2328 FT_UINT32, BASE_DEC, NULL, 0x0,
2329 "Authentication types specific to TightVNC", HFILL }
2331 { &hf_vnc_tight_auth_type,
2332 { "Authentication type", "vnc.auth_type",
2333 FT_UINT8, BASE_DEC, NULL, 0x0,
2334 "Authentication type specific to TightVNC", HFILL }
2336 { &hf_vnc_tight_server_message_type,
2337 { "Server message type", "vnc.server_message_type",
2338 FT_INT32, BASE_DEC, NULL, 0x0,
2339 "Server message type specific to TightVNC", HFILL }
2341 { &hf_vnc_tight_server_vendor,
2342 { "Server vendor code", "vnc.server_vendor",
2343 FT_STRING, BASE_NONE, NULL, 0x0,
2344 "Server vendor code specific to TightVNC", HFILL }
2346 { &hf_vnc_tight_server_name,
2347 { "Server name", "vnc.server_name",
2348 FT_STRING, BASE_NONE, NULL, 0x0,
2349 "Server name specific to TightVNC", HFILL }
2351 { &hf_vnc_tight_client_message_type,
2352 { "Client message type", "vnc.client_message_type",
2353 FT_INT32, BASE_DEC, NULL, 0x0,
2354 "Client message type specific to TightVNC", HFILL }
2356 { &hf_vnc_tight_client_vendor,
2357 { "Client vendor code", "vnc.client_vendor",
2358 FT_STRING, BASE_NONE, NULL, 0x0,
2359 "Client vendor code specific to TightVNC", HFILL }
2361 { &hf_vnc_tight_client_name,
2362 { "Client name", "vnc.client_name",
2363 FT_STRING, BASE_NONE, NULL, 0x0,
2364 "Client name specific to TightVNC", HFILL }
2366 { &hf_vnc_tight_encoding_type,
2367 { "Encoding type", "vnc.encoding_type",
2368 FT_INT32, BASE_DEC, NULL, 0x0,
2369 "Encoding type specific to TightVNC", HFILL }
2371 { &hf_vnc_tight_encoding_vendor,
2372 { "Encoding vendor code", "vnc.encoding_vendor",
2373 FT_STRING, BASE_NONE, NULL, 0x0,
2374 "Encoding vendor code specific to TightVNC", HFILL }
2376 { &hf_vnc_tight_encoding_name,
2377 { "Encoding name", "vnc.encoding_name",
2378 FT_STRING, BASE_NONE, NULL, 0x0,
2379 "Encoding name specific to TightVNC", HFILL }
2381 { &hf_vnc_tight_reset_stream0,
2382 { "Reset compression stream 0", "vnc.tight_reset_stream0",
2383 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2384 "Tight compression, reset compression stream 0", HFILL }
2386 { &hf_vnc_tight_reset_stream1,
2387 { "Reset compression stream 1", "vnc.tight_reset_stream0",
2388 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2389 "Tight compression, reset compression stream 1", HFILL }
2391 { &hf_vnc_tight_reset_stream2,
2392 { "Reset compression stream 2", "vnc.tight_reset_stream0",
2393 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2394 "Tight compression, reset compression stream 2", HFILL }
2396 { &hf_vnc_tight_reset_stream3,
2397 { "Reset compression stream 3", "vnc.tight_reset_stream0",
2398 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2399 "Tight compression, reset compression stream 3", HFILL }
2401 { &hf_vnc_tight_rect_type,
2402 { "Rectangle type", "vnc.tight_rect_type",
2403 FT_UINT8, BASE_HEX, NULL, 0x0,
2404 "Tight compression, rectangle type", HFILL }
2406 { &hf_vnc_tight_image_len,
2407 { "Image data length", "vnc.tight_image_len",
2408 FT_UINT32, BASE_DEC, NULL, 0x0,
2409 "Tight compression, length of image data", HFILL }
2411 { &hf_vnc_tight_image_data,
2412 { "Image data", "vnc.tight_image_data",
2413 FT_BYTES, BASE_NONE, NULL, 0x0,
2414 "Tight compression, image data", HFILL }
2416 { &hf_vnc_tight_fill_color,
2417 { "Fill color (RGB)", "vnc.tight_fill_color",
2418 FT_BYTES, BASE_NONE, NULL, 0x0,
2419 "Tight compression, fill color for solid rectangle", HFILL }
2421 { &hf_vnc_tight_filter_flag,
2422 { "Explicit filter flag", "vnc.tight_filter_flag",
2423 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2424 "Tight compression, explicit filter flag", HFILL }
2426 { &hf_vnc_tight_filter_id,
2427 { "Filter ID", "vnc.tight_filter_id",
2428 FT_UINT8, BASE_DEC, VALS(tight_filter_ids_vs), 0x0,
2429 "Tight compression, filter ID", HFILL }
2431 { &hf_vnc_tight_palette_num_colors,
2432 { "Number of colors in palette", "vnc.tight_palette_num_colors",
2433 FT_UINT8, BASE_DEC, NULL, 0x0,
2434 "Tight compression, number of colors in rectangle's palette", HFILL }
2436 { &hf_vnc_tight_palette_data,
2437 { "Palette data", "vnc.tight_palette_data",
2438 FT_BYTES, BASE_NONE, NULL, 0x0,
2439 "Tight compression, palette data for a rectangle", HFILL }
2441 { &hf_vnc_vendor_code,
2442 { "Vendor code", "vnc.vendor_code",
2443 FT_STRING, BASE_NONE, NULL, 0x0,
2444 "Identifies the VNC server software's vendor", HFILL }
2446 { &hf_vnc_security_type_string,
2447 { "Security type string", "vnc.security_type_string",
2448 FT_STRING, BASE_NONE, NULL, 0x0,
2449 "Security type being used", HFILL }
2451 { &hf_vnc_auth_challenge,
2452 { "Authentication challenge", "vnc.auth_challenge",
2453 FT_STRING, BASE_NONE, NULL, 0x0,
2454 "Random authentication challenge from server to client", HFILL }
2456 { &hf_vnc_auth_response,
2457 { "Authentication response", "vnc.auth_response",
2458 FT_STRING, BASE_NONE, NULL, 0x0,
2459 "Client's encrypted response to the server's authentication challenge", HFILL }
2461 { &hf_vnc_auth_result,
2462 { "Authentication result", "vnc.auth_result",
2463 FT_UINT32, BASE_DEC, VALS(auth_result_vs), 0x0,
2466 { &hf_vnc_auth_error,
2467 { "Authentication error", "vnc.auth_error",
2468 FT_STRING, BASE_NONE, NULL, 0x0,
2469 "Authentication error (present only if the authentication result is fail", HFILL }
2471 { &hf_vnc_share_desktop_flag,
2472 { "Share desktop flag", "vnc.share_desktop_flag",
2473 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x0,
2474 "Client's desire to share the server's desktop with other clients", HFILL }
2477 { "Framebuffer width", "vnc.width",
2478 FT_UINT16, BASE_DEC, NULL, 0x0,
2479 "Width of the framebuffer (screen) in pixels", HFILL }
2482 { "Framebuffer height", "vnc.width",
2483 FT_UINT16, BASE_DEC, NULL, 0x0,
2484 "Height of the framebuffer (screen) in pixels", HFILL }
2486 { &hf_vnc_server_bits_per_pixel,
2487 { "Bits per pixel", "vnc.server_bits_per_pixel",
2488 FT_UINT8, BASE_DEC, NULL, 0x0,
2489 "Number of bits used by server for each pixel value on the wire from the server", HFILL }
2491 { &hf_vnc_server_depth,
2492 { "Depth", "vnc.server_depth",
2493 FT_UINT8, BASE_DEC, NULL, 0x0,
2494 "Number of useful bits in the pixel value on server", HFILL }
2496 { &hf_vnc_server_big_endian_flag,
2497 { "Big endian flag", "vnc.server_big_endian_flag",
2498 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2499 "True if multi-byte pixels are interpreted as big endian by server", HFILL }
2501 { &hf_vnc_server_true_color_flag,
2502 { "True color flag", "vnc.server_true_color_flag",
2503 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2504 "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 }
2506 { &hf_vnc_server_red_max,
2507 { "Red maximum", "vnc.server_red_max",
2508 FT_UINT16, BASE_DEC, NULL, 0x0,
2509 "Maximum red value on server as n: 2^n - 1", HFILL }
2511 { &hf_vnc_server_green_max,
2512 { "Green maximum", "vnc.server_green_max",
2513 FT_UINT16, BASE_DEC, NULL, 0x0,
2514 "Maximum green value on server as n: 2^n - 1", HFILL }
2516 { &hf_vnc_server_blue_max,
2517 { "Blue maximum", "vnc.server_blue_max",
2518 FT_UINT16, BASE_DEC, NULL, 0x0,
2519 "Maximum blue value on server as n: 2^n - 1", HFILL }
2521 { &hf_vnc_server_red_shift,
2522 { "Red shift", "vnc.server_red_shift",
2523 FT_UINT8, BASE_DEC, NULL, 0x0,
2524 "Number of shifts needed to get the red value in a pixel to the least significant bit on the server", HFILL }
2526 { &hf_vnc_server_green_shift,
2527 { "Green shift", "vnc.server_green_shift",
2528 FT_UINT8, BASE_DEC, NULL, 0x0,
2529 "Number of shifts needed to get the green value in a pixel to the least significant bit on the server", HFILL }
2531 { &hf_vnc_server_blue_shift,
2532 { "Blue shift", "vnc.server_blue_shift",
2533 FT_UINT8, BASE_DEC, NULL, 0x0,
2534 "Number of shifts needed to get the blue value in a pixel to the least significant bit on the server", HFILL }
2536 { &hf_vnc_desktop_name_len,
2537 { "Desktop name length", "vnc.desktop_name_len",
2538 FT_UINT32, BASE_DEC, NULL, 0x0,
2539 "Length of desktop name in bytes", HFILL }
2541 { &hf_vnc_desktop_name,
2542 { "Desktop name", "vnc.desktop_name",
2543 FT_STRING, BASE_NONE, NULL, 0x0,
2544 "Name of the VNC desktop on the server", HFILL }
2546 { &hf_vnc_num_server_message_types,
2547 { "Server message types", "vnc.num_server_message_types",
2548 FT_UINT16, BASE_DEC, NULL, 0x0,
2549 "Unknown", HFILL } /* XXX - Needs description */
2551 { &hf_vnc_num_client_message_types,
2552 { "Client message types", "vnc.num_client_message_types",
2553 FT_UINT16, BASE_DEC, NULL, 0x0,
2554 "Unknown", HFILL } /* XXX - Needs description */
2556 { &hf_vnc_num_encoding_types,
2557 { "Encoding types", "vnc.num_encoding_types",
2558 FT_UINT16, BASE_DEC, NULL, 0x0,
2559 "Unknown", HFILL } /* XXX - Needs description */
2561 { &hf_vnc_client_message_type,
2562 { "Client Message Type", "vnc.client_message_type",
2563 FT_UINT8, BASE_DEC, VALS(client_message_types_vs), 0x0,
2564 "Message type from client", HFILL }
2566 { &hf_vnc_client_bits_per_pixel,
2567 { "Bits per pixel", "vnc.client_bits_per_pixel",
2568 FT_UINT8, BASE_DEC, NULL, 0x0,
2569 "Number of bits used by server for each pixel value on the wire from the client", HFILL }
2571 { &hf_vnc_client_depth,
2572 { "Depth", "vnc.client_depth",
2573 FT_UINT8, BASE_DEC, NULL, 0x0,
2574 "Number of useful bits in the pixel value on client", HFILL }
2576 { &hf_vnc_client_big_endian_flag,
2577 { "Big endian flag", "vnc.client_big_endian_flag",
2578 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2579 "True if multi-byte pixels are interpreted as big endian by client", HFILL }
2581 { &hf_vnc_client_true_color_flag,
2582 { "True color flag", "vnc.client_true_color_flag",
2583 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2584 "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 }
2586 { &hf_vnc_client_red_max,
2587 { "Red maximum", "vnc.client_red_max",
2588 FT_UINT16, BASE_DEC, NULL, 0x0,
2589 "Maximum red value on client as n: 2^n - 1", HFILL }
2591 { &hf_vnc_client_green_max,
2592 { "Green maximum", "vnc.client_green_max",
2593 FT_UINT16, BASE_DEC, NULL, 0x0,
2594 "Maximum green value on client as n: 2^n - 1", HFILL }
2596 { &hf_vnc_client_blue_max,
2597 { "Blue maximum", "vnc.client_blue_max",
2598 FT_UINT16, BASE_DEC, NULL, 0x0,
2599 "Maximum blue value on client as n: 2^n - 1", HFILL }
2601 { &hf_vnc_client_red_shift,
2602 { "Red shift", "vnc.client_red_shift",
2603 FT_UINT8, BASE_DEC, NULL, 0x0,
2604 "Number of shifts needed to get the red value in a pixel to the least significant bit on the client", HFILL }
2606 { &hf_vnc_client_green_shift,
2607 { "Green shift", "vnc.client_green_shift",
2608 FT_UINT8, BASE_DEC, NULL, 0x0,
2609 "Number of shifts needed to get the green value in a pixel to the least significant bit on the client", HFILL }
2611 { &hf_vnc_client_blue_shift,
2612 { "Blue shift", "vnc.client_blue_shift",
2613 FT_UINT8, BASE_DEC, NULL, 0x0,
2614 "Number of shifts needed to get the blue value in a pixel to the least significant bit on the client", HFILL }
2617 /* Client Key Event */
2619 { "Key down", "vnc.key_down",
2620 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x0,
2621 "Specifies whether the key is being pressed or not", HFILL }
2625 FT_UINT32, BASE_HEX, VALS(keysym_vals_source), 0x0, /* keysym_vals_source is from packet-x11-keysym.h */
2626 "Key being pressed/depressed", HFILL }
2629 /* Client Pointer Event */
2630 { &hf_vnc_button_1_pos,
2631 { "Mouse button #1 position", "vnc.button_1_pos",
2632 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x1,
2633 "Whether mouse button #1 is being pressed or not", HFILL }
2635 { &hf_vnc_button_2_pos,
2636 { "Mouse button #2 position", "vnc.button_2_pos",
2637 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x2,
2638 "Whether mouse button #2 is being pressed or not", HFILL }
2640 { &hf_vnc_button_3_pos,
2641 { "Mouse button #3 position", "vnc.button_3_pos",
2642 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x4,
2643 "Whether mouse button #3 is being pressed or not", HFILL }
2645 { &hf_vnc_button_4_pos,
2646 { "Mouse button #4 position", "vnc.button_4_pos",
2647 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x8,
2648 "Whether mouse button #4 is being pressed or not", HFILL }
2650 { &hf_vnc_button_5_pos,
2651 { "Mouse button #5 position", "vnc.button_5_pos",
2652 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x10,
2653 "Whether mouse button #5 is being pressed or not", HFILL }
2655 { &hf_vnc_button_6_pos,
2656 { "Mouse button #6 position", "vnc.button_6_pos",
2657 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x20,
2658 "Whether mouse button #6 is being pressed or not", HFILL }
2660 { &hf_vnc_button_7_pos,
2661 { "Mouse button #7 position", "vnc.button_7_pos",
2662 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x40,
2663 "Whether mouse button #7 is being pressed or not", HFILL }
2665 { &hf_vnc_button_8_pos,
2666 { "Mouse button #8 position", "vnc.button_8_pos",
2667 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x80,
2668 "Whether mouse button #8 is being pressed or not", HFILL }
2670 { &hf_vnc_pointer_x_pos,
2671 { "X position", "vnc.pointer_x_pos",
2672 FT_UINT16, BASE_DEC, NULL, 0x0,
2673 "Position of mouse cursor on the x-axis", HFILL }
2675 { &hf_vnc_pointer_y_pos,
2676 { "Y position", "vnc.pointer_y_pos",
2677 FT_UINT16, BASE_DEC, NULL, 0x0,
2678 "Position of mouse cursor on the y-axis", HFILL }
2680 { &hf_vnc_client_set_encodings_encoding_type,
2681 { "Encoding type", "vnc.client_set_encodings_encoding_type",
2682 FT_INT32, BASE_DEC, VALS(encoding_types_vs), 0x0,
2683 "Type of encoding used to send pixel data from server to client", HFILL }
2686 /* Client Framebuffer Update Request */
2687 { &hf_vnc_update_req_incremental,
2688 { "Incremental update", "vnc.update_req_incremental",
2689 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2690 "Specifies if the client wants an incremental update instead of a full one", HFILL }
2692 { &hf_vnc_update_req_x_pos,
2693 { "X position", "vnc.update_req_x_pos",
2694 FT_UINT16, BASE_DEC, NULL, 0x0,
2695 "X position of framebuffer (screen) update requested", HFILL }
2697 { &hf_vnc_update_req_y_pos,
2698 { "Y position", "vnc.update_req_y_pos",
2699 FT_UINT16, BASE_DEC, NULL, 0x0,
2700 "Y position of framebuffer (screen) update request", HFILL }
2702 { &hf_vnc_update_req_width,
2703 { "Width", "vnc.update_req_width",
2704 FT_UINT16, BASE_DEC, NULL, 0x0,
2705 "Width of framebuffer (screen) update request", HFILL }
2707 { &hf_vnc_update_req_height,
2708 { "Height", "vnc.update_req_height",
2709 FT_UINT16, BASE_DEC, NULL, 0x0,
2710 "Height of framebuffer (screen) update request", HFILL }
2712 { &hf_vnc_client_cut_text_len,
2713 { "Length", "vnc.client_cut_text_len",
2714 FT_UINT32, BASE_DEC, NULL, 0x0,
2715 "Length of client's copy/cut text (clipboard) string in bytes", HFILL }
2717 { &hf_vnc_client_cut_text,
2718 { "Text", "vnc.client_cut_text",
2719 FT_STRING, BASE_NONE, NULL, 0x0,
2720 "Text string in the client's copy/cut text (clipboard)", HFILL }
2724 /********** Server Message Types **********/
2725 { &hf_vnc_server_message_type,
2726 { "Server Message Type", "vnc.server_message_type",
2727 FT_UINT8, BASE_DEC, VALS(server_message_types_vs), 0x0,
2728 "Message type from server", HFILL }
2731 { &hf_vnc_fb_update_x_pos,
2732 { "X position", "vnc.fb_update_x_pos",
2733 FT_UINT16, BASE_DEC, NULL, 0x0,
2734 "X position of this server framebuffer update", HFILL }
2737 { &hf_vnc_fb_update_y_pos,
2738 { "Y position", "vnc.fb_update_x_pos",
2739 FT_UINT16, BASE_DEC, NULL, 0x0,
2740 "Y position of this server framebuffer update", HFILL }
2743 { &hf_vnc_fb_update_width,
2744 { "Width", "vnc.fb_update_width",
2745 FT_UINT16, BASE_DEC, NULL, 0x0,
2746 "Width of this server framebuffer update", HFILL }
2749 { &hf_vnc_fb_update_height,
2750 { "Height", "vnc.fb_update_height",
2751 FT_UINT16, BASE_DEC, NULL, 0x0,
2752 "Height of this server framebuffer update", HFILL }
2755 { &hf_vnc_fb_update_encoding_type,
2756 { "Encoding type", "vnc.fb_update_encoding_type",
2757 FT_INT32, BASE_DEC, VALS(encoding_types_vs), 0x0,
2758 "Encoding type of this server framebuffer update", HFILL }
2761 /* Cursor encoding */
2762 { &hf_vnc_cursor_x_fore_back,
2763 { "X Cursor foreground RGB / background RGB", "vnc.cursor_x_fore_back",
2764 FT_BYTES, BASE_NONE, NULL, 0x0,
2765 "RGB values for the X cursor's foreground and background", HFILL }
2768 { &hf_vnc_cursor_encoding_pixels,
2769 { "Cursor encoding pixels", "vnc.cursor_encoding_pixels",
2770 FT_BYTES, BASE_NONE, NULL, 0x0,
2771 "Cursor encoding pixel data", HFILL }
2774 { &hf_vnc_cursor_encoding_bitmask,
2775 { "Cursor encoding bitmask", "vnc.cursor_encoding_bitmask",
2776 FT_BYTES, BASE_NONE, NULL, 0x0,
2777 "Cursor encoding pixel bitmask", HFILL }
2781 { &hf_vnc_raw_pixel_data,
2782 { "Pixel data", "vnc.raw_pixel_data",
2783 FT_BYTES, BASE_NONE, NULL, 0x0,
2784 "Raw pixel data.", HFILL }
2787 /* CopyRect Encoding*/
2788 { &hf_vnc_copyrect_src_x_pos,
2789 { "Source x position", "vnc.copyrect_src_x_pos",
2790 FT_UINT16, BASE_DEC, NULL, 0x0,
2791 "X position of the rectangle to copy from", HFILL }
2794 { &hf_vnc_copyrect_src_y_pos,
2795 { "Source y position", "vnc.copyrect_src_y_pos",
2796 FT_UINT16, BASE_DEC, NULL, 0x0,
2797 "Y position of the rectangle to copy from", HFILL }
2801 { &hf_vnc_rre_num_subrects,
2802 { "Number of subrectangles", "vnc.rre_num_subrects",
2803 FT_UINT32, BASE_DEC, NULL, 0x0,
2804 "Number of subrectangles contained in this encoding type", HFILL }
2807 { &hf_vnc_rre_bg_pixel,
2808 { "Background pixel value", "vnc.rre_bg_pixel",
2809 FT_BYTES, BASE_NONE, NULL, 0x0,
2813 { &hf_vnc_rre_subrect_pixel,
2814 { "Pixel value", "vnc.rre_subrect_pixel",
2815 FT_BYTES, BASE_NONE, NULL, 0x0,
2816 "Subrectangle pixel value", HFILL }
2819 { &hf_vnc_rre_subrect_x_pos,
2820 { "X position", "vnc.rre_subrect_x_pos",
2821 FT_UINT16, BASE_DEC, NULL, 0x0,
2822 "Position of this subrectangle on the x axis", HFILL }
2825 { &hf_vnc_rre_subrect_y_pos,
2826 { "Y position", "vnc.rre_subrect_y_pos",
2827 FT_UINT16, BASE_DEC, NULL, 0x0,
2828 "Position of this subrectangle on the y axis", HFILL }
2831 { &hf_vnc_rre_subrect_width,
2832 { "Width", "vnc.rre_subrect_width",
2833 FT_UINT16, BASE_DEC, NULL, 0x0,
2834 "Width of this subrectangle", HFILL }
2837 { &hf_vnc_rre_subrect_height,
2838 { "Height", "vnc.rre_subrect_height",
2839 FT_UINT16, BASE_DEC, NULL, 0x0,
2840 "Height of this subrectangle", HFILL }
2844 /* Hextile Encoding */
2845 { &hf_vnc_hextile_subencoding_mask,
2846 { "Subencoding type", "vnc.hextile_subencoding",
2847 FT_UINT8, BASE_DEC, NULL, 0x0,
2848 "Hextile subencoding type.", HFILL }
2851 { &hf_vnc_hextile_raw,
2852 { "Raw", "vnc.hextile_raw",
2853 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x1,
2854 "Raw subencoding is used in this tile", HFILL }
2857 { &hf_vnc_hextile_raw_value,
2858 { "Raw pixel values", "vnc.hextile_raw_value",
2859 FT_BYTES, BASE_NONE, NULL, 0x0,
2860 "Raw subencoding pixel values", HFILL }
2863 { &hf_vnc_hextile_bg,
2864 { "Background Specified", "vnc.hextile_bg",
2865 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x2,
2866 "Background Specified subencoding is used in this tile", HFILL }
2869 { &hf_vnc_hextile_bg_value,
2870 { "Background pixel value", "vnc.hextile_bg_value",
2871 FT_BYTES, BASE_NONE, NULL, 0x0,
2872 "Background color for this tile", HFILL }
2875 { &hf_vnc_hextile_fg,
2876 { "Foreground Specified", "vnc.hextile_fg",
2877 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x4,
2878 "Foreground Specified subencoding is used in this tile", HFILL }
2881 { &hf_vnc_hextile_fg_value,
2882 { "Foreground pixel value", "vnc.hextile_fg_value",
2883 FT_BYTES, BASE_NONE, NULL, 0x0,
2884 "Foreground color for this tile", HFILL }
2887 { &hf_vnc_hextile_anysubrects,
2888 { "Any Subrects", "vnc.hextile_anysubrects",
2889 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x8,
2890 "Any subrects subencoding is used in this tile", HFILL }
2893 { &hf_vnc_hextile_num_subrects,
2894 { "Number of subrectangles", "vnc.hextile_num_subrects",
2895 FT_UINT8, BASE_DEC, NULL, 0x0,
2896 "Number of subrectangles that follow", HFILL }
2899 { &hf_vnc_hextile_subrectscolored,
2900 { "Subrects Colored", "vnc.hextile_subrectscolored",
2901 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x10,
2902 "Subrects colored subencoding is used in this tile", HFILL }
2905 { &hf_vnc_hextile_subrect_pixel_value,
2906 { "Pixel value", "vnc.hextile_subrect_pixel_value",
2907 FT_BYTES, BASE_NONE, NULL, 0x0,
2908 "Pixel value of this subrectangle", HFILL }
2911 { &hf_vnc_hextile_subrect_x_pos,
2912 { "X position", "vnc.hextile_subrect_x_pos",
2913 FT_UINT8, BASE_DEC, NULL, 0xF0, /* Top 4 bits */
2914 "X position of this subrectangle", HFILL }
2917 { &hf_vnc_hextile_subrect_y_pos,
2918 { "Y position", "vnc.hextile_subrect_y_pos",
2919 FT_UINT8, BASE_DEC, NULL, 0xF, /* Bottom 4 bits */
2920 "Y position of this subrectangle", HFILL }
2923 { &hf_vnc_hextile_subrect_width,
2924 { "Width", "vnc.hextile_subrect_width",
2925 FT_UINT8, BASE_DEC, NULL, 0xF0, /* Top 4 bits */
2926 "Subrectangle width minus one", HFILL }
2929 { &hf_vnc_hextile_subrect_height,
2930 { "Height", "vnc.hextile_subrect_height",
2931 FT_UINT8, BASE_DEC, NULL, 0xF, /* Bottom 4 bits */
2932 "Subrectangle height minus one", HFILL }
2938 { "ZRLE compressed length", "vnc.zrle_len",
2939 FT_UINT32, BASE_DEC, NULL, 0x0,
2940 "Length of compressed ZRLE data that follows", HFILL }
2943 { &hf_vnc_zrle_subencoding,
2944 { "Subencoding type", "vnc.zrle_subencoding",
2945 FT_UINT8, BASE_DEC, NULL, 0x0,
2946 "Subencoding type byte", HFILL }
2950 { "RLE", "vnc.zrle_rle",
2951 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x80, /* Upper bit */
2952 "Specifies that data is run-length encoded", HFILL }
2955 { &hf_vnc_zrle_palette_size,
2956 { "Palette size", "vnc.zrle_palette_size",
2957 FT_UINT8, BASE_DEC, NULL, 0x7F, /* Lower 7 bits */
2961 { &hf_vnc_zrle_data,
2962 { "ZRLE compressed data", "vnc.zrle_data",
2963 FT_BYTES, BASE_NONE, NULL, 0x0,
2964 "Compressed ZRLE data. Compiling with zlib support will uncompress and dissect this data", HFILL }
2968 { "Pixel values", "vnc.zrle_raw",
2969 FT_BYTES, BASE_NONE, NULL, 0x0,
2970 "Raw pixel values for this tile", HFILL }
2973 { &hf_vnc_zrle_palette,
2974 { "Palette", "vnc.zrle_palette",
2975 FT_BYTES, BASE_NONE, NULL, 0x0,
2976 "Palette pixel values", HFILL }
2979 /* Server Set Colormap Entries */
2980 { &hf_vnc_colormap_first_color,
2981 { "First color", "vnc.colormap_first_color",
2982 FT_UINT16, BASE_DEC, NULL, 0x0,
2983 "First color that should be mapped to given RGB intensities", HFILL }
2985 { &hf_vnc_colormap_num_colors,
2986 { "Number of color groups", "vnc.colormap_groups",
2987 FT_UINT16, BASE_DEC, NULL, 0x0,
2988 "Number of red/green/blue color groups", HFILL }
2990 { &hf_vnc_colormap_red,
2991 { "Red", "vnc.colormap_red",
2992 FT_UINT16, BASE_DEC, NULL, 0x0,
2993 "Red intensity", HFILL }
2995 { &hf_vnc_colormap_green,
2996 { "Green", "vnc.colormap_green",
2997 FT_UINT16, BASE_DEC, NULL, 0x0,
2998 "Green intensity", HFILL }
3000 { &hf_vnc_colormap_blue,
3001 { "Blue", "vnc.colormap_blue",
3002 FT_UINT16, BASE_DEC, NULL, 0x0,
3003 "Blue intensity", HFILL }
3006 /* Server Cut Text */
3007 { &hf_vnc_server_cut_text_len,
3008 { "Length", "vnc.server_cut_text_len",
3009 FT_UINT32, BASE_DEC, NULL, 0x0,
3010 "Length of server's copy/cut text (clipboard) string in bytes", HFILL }
3012 { &hf_vnc_server_cut_text,
3013 { "Text", "vnc.server_cut_text",
3014 FT_STRING, BASE_NONE, NULL, 0x0,
3015 "Text string in the server's copy/cut text (clipboard)", HFILL }
3019 /* Setup protocol subtree arrays */
3020 static gint *ett[] = {
3022 &ett_vnc_client_message_type,
3023 &ett_vnc_server_message_type,
3025 &ett_vnc_encoding_type,
3026 &ett_vnc_rre_subrect,
3027 &ett_vnc_hextile_subencoding_mask,
3028 &ett_vnc_hextile_num_subrects,
3029 &ett_vnc_hextile_subrect,
3030 &ett_vnc_zrle_subencoding,
3031 &ett_vnc_colormap_num_groups,
3032 &ett_vnc_colormap_color_group
3035 /* Register the protocol name and description */
3036 proto_vnc = proto_register_protocol("Virtual Network Computing",
3039 /* Required function calls to register the header fields and subtrees */
3040 proto_register_field_array(proto_vnc, hf, array_length(hf));
3041 proto_register_subtree_array(ett, array_length(ett));
3043 /* Register our preferences module */
3044 vnc_module = prefs_register_protocol(proto_vnc, proto_reg_handoff_vnc);
3046 prefs_register_bool_preference(vnc_module, "desegment", "Reassemble VNC messages spanning multiple TCP segments.", "Whether the VNC dissector should reassemble messages spanning multiple TCP segments. To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.", &vnc_preference_desegment);
3048 prefs_register_uint_preference(vnc_module, "alternate_port", "Alternate TCP port", "Decode this port's traffic as VNC in addition to the default ports (5500, 5501, 5900, 5901)", 10, &vnc_preference_alternate_port);
3053 proto_reg_handoff_vnc(void)
3055 static gboolean inited = FALSE;
3057 /* This is a behind the scenes variable that is not changed by the user.
3058 * This stores last setting of the vnc_preference_alternate_port. Used to keep
3059 * track of when the user has changed the setting so that we can delete
3060 * and re-register with the new port number. */
3061 static guint vnc_preference_alternate_port_last = 0;
3064 vnc_handle = create_dissector_handle(dissect_vnc, proto_vnc);
3066 dissector_add("tcp.port", 5500, vnc_handle);
3067 dissector_add("tcp.port", 5501, vnc_handle);
3068 dissector_add("tcp.port", 5900, vnc_handle);
3069 dissector_add("tcp.port", 5901, vnc_handle);
3071 heur_dissector_add("tcp", test_vnc_protocol, proto_vnc);
3072 /* We don't register a port for the VNC HTTP server because
3073 * that simply provides a java program for download via the
3074 * HTTP protocol. The java program then connects to a standard
3078 } else { /* only after preferences have been read/changed */
3079 if(vnc_preference_alternate_port != vnc_preference_alternate_port_last &&
3080 vnc_preference_alternate_port != 5500 &&
3081 vnc_preference_alternate_port != 5501 &&
3082 vnc_preference_alternate_port != 5900 &&
3083 vnc_preference_alternate_port != 5901) {
3084 if (vnc_preference_alternate_port_last != 0) {
3085 dissector_delete("tcp.port",
3086 vnc_preference_alternate_port_last,
3089 /* Save this setting to see if has changed later */
3090 vnc_preference_alternate_port_last =
3091 vnc_preference_alternate_port;
3093 /* Register the new port setting */
3094 if (vnc_preference_alternate_port != 0) {
3095 dissector_add("tcp.port",
3096 vnc_preference_alternate_port,
3100 heur_dissector_add("tcp", test_vnc_protocol, proto_vnc);