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 if (check_col(pinfo->cinfo, COL_INFO)) {
768 col_set_str(pinfo->cinfo, COL_INFO,
769 "Authentication type selected by client");
771 proto_tree_add_item(tree, hf_vnc_client_security_type, tvb,
773 per_conversation_info->security_type_selected =
774 tvb_get_guint8(tvb, offset);
776 switch(per_conversation_info->security_type_selected) {
779 if(per_conversation_info->client_proto_ver >= 3.008)
780 per_conversation_info->vnc_next_state =
783 per_conversation_info->vnc_next_state =
789 per_conversation_info->vnc_next_state =
790 VNC_AUTHENTICATION_CHALLENGE;
793 case 16 : /* Tight */
794 per_conversation_info->vnc_next_state =
795 TIGHT_TUNNELING_CAPABILITIES;
798 /* Security type not supported by this dissector */
804 case TIGHT_TUNNELING_CAPABILITIES :
805 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC tunneling capabilities supported");
807 proto_tree_add_item(tree, hf_vnc_tight_num_tunnel_types, tvb, offset, 4, FALSE);
808 num_tunnel_types = tvb_get_ntohl(tvb, offset);
814 for(i = 0; i < num_tunnel_types; i++) {
815 /* TightVNC and Xvnc don't support any tunnel capabilities yet, but each capability
816 * is 16 bytes, so skip them.
819 proto_tree_add_item(tree, hf_vnc_tight_tunnel_type, tvb, offset, 16, FALSE);
824 if (num_tunnel_types == 0)
825 per_conversation_info->vnc_next_state = TIGHT_AUTH_CAPABILITIES;
827 per_conversation_info->vnc_next_state = TIGHT_TUNNEL_TYPE_REPLY;
830 case TIGHT_TUNNEL_TYPE_REPLY:
831 /* Neither TightVNC nor Xvnc implement this; they just have a placeholder that emits an error
832 * message and closes the connection (xserver/hw/vnc/auth.c:rfbProcessClientTunnelingType).
833 * We should actually never get here...
837 case TIGHT_AUTH_CAPABILITIES:
838 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC authentication capabilities supported");
840 proto_tree_add_item(tree, hf_vnc_tight_num_auth_types, tvb, offset, 4, FALSE);
841 num_auth_types = tvb_get_ntohl(tvb, offset);
847 for (i = 0; i < num_auth_types; i++) {
848 /* See xserver/hw/vnc/auth.c:rfbSendAuthCaps()
849 * We don't actually display the auth types for now.
851 proto_tree_add_item(tree, hf_vnc_tight_auth_type, tvb, offset, 16, FALSE);
856 if (num_auth_types == 0)
857 per_conversation_info->vnc_next_state = CLIENT_INIT;
859 per_conversation_info->vnc_next_state = TIGHT_AUTH_TYPE_REPLY;
862 case TIGHT_AUTH_TYPE_REPLY:
863 REPORT_DISSECTOR_BUG("Unimplemented case: TightVNC authentication reply");
864 /* FIXME: implement. See xserver/hw/vnc/auth.c:rfbProcessClientAuthType() */
867 case TIGHT_AUTH_TYPE_AND_VENDOR_CODE :
868 col_set_str(pinfo->cinfo, COL_INFO, "Authentication type / vendor code");
870 proto_tree_add_item(tree, hf_vnc_server_security_type, tvb,
875 offset = process_vendor(tree, hf_vnc_vendor_code, tvb, offset);
877 /* Display authentication method string */
878 proto_tree_add_item(tree, hf_vnc_security_type_string, tvb,
881 per_conversation_info->vnc_next_state =
882 TIGHT_UNKNOWN_PACKET3;
886 case TIGHT_UNKNOWN_PACKET3 :
887 col_set_str(pinfo->cinfo, COL_INFO, "Unknown packet (TightVNC)");
889 proto_tree_add_text(tree, tvb, offset, -1,
890 "Unknown packet (TightVNC)");
892 per_conversation_info->vnc_next_state =
893 VNC_AUTHENTICATION_CHALLENGE;
897 case VNC_AUTHENTICATION_CHALLENGE :
898 col_set_str(pinfo->cinfo, COL_INFO, "Authentication challenge from server");
900 proto_tree_add_item(tree, hf_vnc_auth_challenge, tvb,
903 per_conversation_info->vnc_next_state =
904 VNC_AUTHENTICATION_RESPONSE;
907 case VNC_AUTHENTICATION_RESPONSE :
908 col_set_str(pinfo->cinfo, COL_INFO, "Authentication response from client");
910 proto_tree_add_item(tree, hf_vnc_auth_response, tvb,
913 per_conversation_info->vnc_next_state = SECURITY_RESULT;
916 case SECURITY_RESULT :
917 col_set_str(pinfo->cinfo, COL_INFO, "Authentication result");
919 proto_tree_add_item(tree, hf_vnc_auth_result, tvb, offset,
921 auth_result = tvb_get_ntohl(tvb, offset);
924 switch(auth_result) {
927 per_conversation_info->vnc_next_state = CLIENT_INIT;
930 case 1 : /* Failed */
931 if(per_conversation_info->client_proto_ver >= 3.008) {
932 text_len = tvb_get_ntohl(tvb, offset);
933 proto_tree_add_text(tree, tvb, offset, 4, "Length of authentication error: %d", text_len);
936 proto_tree_add_item(tree, hf_vnc_auth_error, tvb,
937 offset, text_len, FALSE);
941 return TRUE; /* All versions: Do not continue
942 processing VNC packets as connection
943 will be closed after this packet. */
951 col_set_str(pinfo->cinfo, COL_INFO, "Share desktop flag");
953 proto_tree_add_item(tree, hf_vnc_share_desktop_flag, tvb,
956 per_conversation_info->vnc_next_state = SERVER_INIT;
961 col_set_str(pinfo->cinfo, COL_INFO, "Server framebuffer parameters");
963 proto_tree_add_item(tree, hf_vnc_width, tvb, offset, 2,
967 proto_tree_add_item(tree, hf_vnc_height, tvb, offset, 2,
971 proto_tree_add_item(tree, hf_vnc_server_bits_per_pixel,
972 tvb, offset, 1, FALSE);
973 vnc_bytes_per_pixel = tvb_get_guint8(tvb, offset)/8;
974 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
977 proto_tree_add_item(tree, hf_vnc_server_depth, tvb, offset,
981 proto_tree_add_item(tree, hf_vnc_server_big_endian_flag,
982 tvb, offset, 1, FALSE);
985 proto_tree_add_item(tree, hf_vnc_server_true_color_flag,
986 tvb, offset, 1, FALSE);
989 proto_tree_add_item(tree, hf_vnc_server_red_max,
990 tvb, offset, 2, FALSE);
993 proto_tree_add_item(tree, hf_vnc_server_green_max,
994 tvb, offset, 2, FALSE);
997 proto_tree_add_item(tree, hf_vnc_server_blue_max,
998 tvb, offset, 2, FALSE);
1001 proto_tree_add_item(tree, hf_vnc_server_red_shift,
1002 tvb, offset, 1, FALSE);
1005 proto_tree_add_item(tree, hf_vnc_server_green_shift,
1006 tvb, offset, 1, FALSE);
1009 proto_tree_add_item(tree, hf_vnc_server_blue_shift,
1010 tvb, offset, 1, FALSE);
1013 proto_tree_add_item(tree, hf_vnc_padding,
1014 tvb, offset, 3, FALSE);
1015 offset += 3; /* Skip over 3 bytes of padding */
1017 if(tvb_length_remaining(tvb, offset) > 0) {
1018 /* Sometimes the desktop name & length is skipped */
1019 proto_tree_add_item(tree, hf_vnc_desktop_name_len,
1020 tvb, offset, 4, FALSE);
1021 desktop_name_len = tvb_get_ntohl(tvb, offset);
1024 proto_tree_add_item(tree, hf_vnc_desktop_name,
1025 tvb, offset, desktop_name_len,
1029 if(per_conversation_info->security_type_selected == TIGHT)
1030 per_conversation_info->vnc_next_state =
1031 TIGHT_INTERACTION_CAPS;
1033 per_conversation_info->vnc_next_state = NORMAL_TRAFFIC;
1036 case TIGHT_INTERACTION_CAPS :
1037 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC Interaction Capabilities");
1039 proto_tree_add_item(tree, hf_vnc_num_server_message_types,
1040 tvb, offset, 2, FALSE);
1041 per_conversation_info->num_server_message_types = tvb_get_ntohs(tvb, offset);
1044 proto_tree_add_item(tree, hf_vnc_num_client_message_types,
1045 tvb, offset, 2, FALSE);
1046 per_conversation_info->num_client_message_types = tvb_get_ntohs(tvb, offset);
1049 proto_tree_add_item(tree, hf_vnc_num_encoding_types,
1050 tvb, offset, 2, FALSE);
1051 per_conversation_info->num_encoding_types = tvb_get_ntohs(tvb, offset);
1054 proto_tree_add_item(tree, hf_vnc_padding, tvb, offset, 2,
1058 per_conversation_info->vnc_next_state = TIGHT_INTERACTION_CAPS_LIST;
1061 case TIGHT_INTERACTION_CAPS_LIST:
1062 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC Interaction Capabilities list");
1064 offset = process_tight_capabilities(tree,
1065 hf_vnc_tight_server_message_type,
1066 hf_vnc_tight_server_vendor,
1067 hf_vnc_tight_server_name,
1068 tvb, offset, per_conversation_info->num_server_message_types);
1069 offset = process_tight_capabilities(tree,
1070 hf_vnc_tight_client_message_type,
1071 hf_vnc_tight_client_vendor,
1072 hf_vnc_tight_client_name,
1073 tvb, offset, per_conversation_info->num_client_message_types);
1074 offset = process_tight_capabilities(tree,
1075 hf_vnc_tight_encoding_type,
1076 hf_vnc_tight_encoding_vendor,
1077 hf_vnc_tight_encoding_name,
1078 tvb, offset, per_conversation_info->num_encoding_types);
1080 per_conversation_info->vnc_next_state = NORMAL_TRAFFIC;
1083 case NORMAL_TRAFFIC :
1092 vnc_client_to_server(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1095 guint8 message_type;
1097 proto_item *ti=NULL;
1098 proto_tree *vnc_client_message_type_tree;
1100 message_type = tvb_get_guint8(tvb, *offset);
1102 ti = proto_tree_add_item(tree, hf_vnc_client_message_type, tvb,
1105 vnc_client_message_type_tree =
1106 proto_item_add_subtree(ti, ett_vnc_client_message_type);
1110 switch(message_type) {
1113 vnc_client_set_pixel_format(tvb, pinfo, offset,
1114 vnc_client_message_type_tree);
1118 vnc_client_set_encodings(tvb, pinfo, offset,
1119 vnc_client_message_type_tree);
1123 vnc_client_framebuffer_update_request(tvb, pinfo, offset,
1124 vnc_client_message_type_tree);
1128 vnc_client_key_event(tvb, pinfo, offset,
1129 vnc_client_message_type_tree);
1133 vnc_client_pointer_event(tvb, pinfo, offset,
1134 vnc_client_message_type_tree);
1138 vnc_client_cut_text(tvb, pinfo, offset,
1139 vnc_client_message_type_tree);
1143 if (check_col(pinfo->cinfo, COL_INFO))
1144 col_append_fstr(pinfo->cinfo, COL_INFO,
1145 "Unknown client message type (%u)",
1152 vnc_server_to_client(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1156 guint8 message_type;
1157 gint bytes_needed = 0, length_remaining;
1159 proto_item *ti=NULL;
1160 proto_tree *vnc_server_message_type_tree;
1162 start_offset = *offset;
1164 message_type = tvb_get_guint8(tvb, *offset);
1166 ti = proto_tree_add_item(tree, hf_vnc_server_message_type, tvb,
1168 vnc_server_message_type_tree =
1169 proto_item_add_subtree(ti, ett_vnc_server_message_type);
1173 switch(message_type) {
1177 vnc_server_framebuffer_update(tvb, pinfo, offset,
1178 vnc_server_message_type_tree);
1182 bytes_needed = vnc_server_set_colormap_entries(tvb, pinfo, offset, vnc_server_message_type_tree);
1186 vnc_server_ring_bell(tvb, pinfo, offset,
1187 vnc_server_message_type_tree);
1191 bytes_needed = vnc_server_cut_text(tvb, pinfo, offset,
1192 vnc_server_message_type_tree);
1196 if (check_col(pinfo->cinfo, COL_INFO))
1197 col_append_str(pinfo->cinfo, COL_INFO,
1198 "Unknown server message type");
1202 if(bytes_needed > 0 && vnc_preference_desegment &&
1203 pinfo->can_desegment) {
1204 length_remaining = tvb_length_remaining(tvb, *offset);
1206 pinfo->desegment_offset = start_offset;
1207 pinfo->desegment_len = bytes_needed - length_remaining;
1214 vnc_client_set_pixel_format(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1217 col_set_str(pinfo->cinfo, COL_INFO, "Client set pixel format");
1219 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset,
1221 *offset += 3; /* Skip over 3 bytes of padding */
1223 proto_tree_add_item(tree, hf_vnc_client_bits_per_pixel, tvb, *offset,
1225 vnc_bytes_per_pixel = tvb_get_guint8(tvb, *offset)/8;
1226 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
1229 proto_tree_add_item(tree, hf_vnc_client_depth, tvb, *offset,
1231 vnc_depth = tvb_get_guint8(tvb, *offset);
1232 vnc_set_depth(pinfo, vnc_depth);
1235 proto_tree_add_item(tree, hf_vnc_client_big_endian_flag, tvb, *offset,
1239 proto_tree_add_item(tree, hf_vnc_client_true_color_flag, tvb, *offset,
1243 proto_tree_add_item(tree, hf_vnc_client_red_max, tvb, *offset,
1247 proto_tree_add_item(tree, hf_vnc_client_green_max, tvb, *offset,
1251 proto_tree_add_item(tree, hf_vnc_client_blue_max, tvb, *offset,
1255 proto_tree_add_item(tree, hf_vnc_client_red_shift, tvb, *offset,
1259 proto_tree_add_item(tree, hf_vnc_client_green_shift, tvb, *offset,
1263 proto_tree_add_item(tree, hf_vnc_client_blue_shift, tvb, *offset,
1267 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset,
1269 *offset += 3; /* Skip over 3 bytes of padding */
1274 vnc_client_set_encodings(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1277 guint16 number_of_encodings;
1279 vnc_packet_t *per_packet_info;
1281 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
1283 col_set_str(pinfo->cinfo, COL_INFO, "Client set encodings");
1285 proto_tree_add_item(tree, hf_vnc_padding,
1286 tvb, *offset, 1, FALSE);
1287 *offset += 1; /* Skip over 1 byte of padding */
1289 number_of_encodings = tvb_get_ntohs(tvb, *offset);
1291 proto_tree_add_text(tree, tvb, *offset, 2,
1292 "Number of encodings: %d", number_of_encodings);
1295 per_packet_info->preferred_encoding = -1;
1297 for(counter = 1; counter <= number_of_encodings; counter++) {
1298 proto_tree_add_item(tree,
1299 hf_vnc_client_set_encodings_encoding_type,
1300 tvb, *offset, 4, FALSE);
1302 /* Remember the first real encoding as the preferred encoding,
1303 * per xserver/hw/vnc/rfbserver.c:rfbProcessClientNormalMessage().
1304 * Otherwise, use RAW as the preferred encoding.
1306 if (per_packet_info->preferred_encoding == -1) {
1309 encoding = tvb_get_ntohl(tvb, *offset);
1314 case ENCODING_CORRE:
1315 case ENCODING_HEXTILE:
1317 case ENCODING_TIGHT:
1318 per_packet_info->preferred_encoding = encoding;
1326 if (per_packet_info->preferred_encoding == -1)
1327 per_packet_info->preferred_encoding = ENCODING_RAW;
1332 vnc_client_framebuffer_update_request(tvbuff_t *tvb, packet_info *pinfo,
1333 gint *offset, proto_tree *tree)
1335 col_set_str(pinfo->cinfo, COL_INFO, "Client framebuffer update request");
1337 proto_tree_add_item(tree, hf_vnc_update_req_incremental,
1338 tvb, *offset, 1, FALSE);
1341 proto_tree_add_item(tree, hf_vnc_update_req_x_pos,
1342 tvb, *offset, 2, FALSE);
1345 proto_tree_add_item(tree, hf_vnc_update_req_y_pos,
1346 tvb, *offset, 2, FALSE);
1349 proto_tree_add_item(tree, hf_vnc_update_req_width, tvb,
1353 proto_tree_add_item(tree, hf_vnc_update_req_height, tvb,
1360 vnc_client_key_event(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1363 col_set_str(pinfo->cinfo, COL_INFO, "Client key event");
1365 proto_tree_add_item(tree, hf_vnc_key_down, tvb, *offset, 1, FALSE);
1368 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 2, FALSE);
1369 *offset += 2; /* Skip over 2 bytes of padding */
1371 proto_tree_add_item(tree, hf_vnc_key, tvb, *offset, 4, FALSE);
1377 vnc_client_pointer_event(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1380 col_set_str(pinfo->cinfo, COL_INFO, "Client pointer event");
1382 proto_tree_add_item(tree, hf_vnc_button_1_pos, tvb, *offset, 1, FALSE);
1383 proto_tree_add_item(tree, hf_vnc_button_2_pos, tvb, *offset, 1, FALSE);
1384 proto_tree_add_item(tree, hf_vnc_button_3_pos, tvb, *offset, 1, FALSE);
1385 proto_tree_add_item(tree, hf_vnc_button_4_pos, tvb, *offset, 1, FALSE);
1386 proto_tree_add_item(tree, hf_vnc_button_5_pos, tvb, *offset, 1, FALSE);
1387 proto_tree_add_item(tree, hf_vnc_button_6_pos, tvb, *offset, 1, FALSE);
1388 proto_tree_add_item(tree, hf_vnc_button_7_pos, tvb, *offset, 1, FALSE);
1389 proto_tree_add_item(tree, hf_vnc_button_8_pos, tvb, *offset, 1, FALSE);
1392 proto_tree_add_item(tree, hf_vnc_pointer_x_pos, tvb, *offset, 2, FALSE);
1395 proto_tree_add_item(tree, hf_vnc_pointer_y_pos, tvb, *offset, 2, FALSE);
1401 vnc_client_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1406 col_set_str(pinfo->cinfo, COL_INFO, "Client cut text");
1408 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 3, FALSE);
1409 *offset += 3; /* Skip over 3 bytes of padding */
1411 text_len = tvb_get_ntohl(tvb, *offset);
1412 proto_tree_add_item(tree, hf_vnc_client_cut_text_len, tvb, *offset, 4,
1416 proto_tree_add_item(tree, hf_vnc_client_cut_text, tvb, *offset,
1418 *offset += text_len;
1424 vnc_server_framebuffer_update(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1428 guint16 width, height;
1429 guint bytes_needed = 0;
1430 gint32 encoding_type;
1431 proto_item *ti, *ti_x, *ti_y, *ti_width, *ti_height;
1432 proto_tree *vnc_rect_tree, *vnc_encoding_type_tree;
1434 col_set_str(pinfo->cinfo, COL_INFO, "Server framebuffer update");
1436 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 1, FALSE);
1439 num_rects = tvb_get_ntohs(tvb, *offset);
1440 proto_tree_add_text(tree, tvb, *offset, 2, "Number of rectangles: %d",
1444 for(i = 1; i <= num_rects; i++) {
1446 VNC_BYTES_NEEDED(12);
1448 ti = proto_tree_add_text(tree, tvb, *offset, 12,
1449 "Rectangle #%d", i);
1452 proto_item_add_subtree(ti, ett_vnc_rect);
1454 ti_x = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_x_pos,
1455 tvb, *offset, 2, FALSE);
1458 ti_y = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_y_pos,
1459 tvb, *offset, 2, FALSE);
1462 ti_width = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_width,
1463 tvb, *offset, 2, FALSE);
1464 width = tvb_get_ntohs(tvb, *offset);
1467 ti_height = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_height,
1468 tvb, *offset, 2, FALSE);
1469 height = tvb_get_ntohs(tvb, *offset);
1472 ti = proto_tree_add_item(vnc_rect_tree,
1473 hf_vnc_fb_update_encoding_type,
1474 tvb, *offset, 4, FALSE);
1476 encoding_type = tvb_get_ntohl(tvb, *offset);
1479 if (encoding_type == ENCODING_LAST_RECT)
1480 break; /* exit the loop */
1482 vnc_encoding_type_tree =
1483 proto_item_add_subtree(ti, ett_vnc_encoding_type);
1485 switch(encoding_type) {
1488 bytes_needed = vnc_raw_encoding(tvb, pinfo, offset,
1489 vnc_encoding_type_tree,
1493 case ENCODING_COPY_RECT:
1495 vnc_copyrect_encoding(tvb, pinfo, offset,
1496 vnc_encoding_type_tree,
1502 vnc_rre_encoding(tvb, pinfo, offset,
1503 vnc_encoding_type_tree,
1507 case ENCODING_HEXTILE:
1509 vnc_hextile_encoding(tvb, pinfo, offset,
1510 vnc_encoding_type_tree,
1516 vnc_zrle_encoding(tvb, pinfo, offset,
1517 vnc_encoding_type_tree,
1521 case ENCODING_TIGHT:
1523 vnc_tight_encoding(tvb, pinfo, offset,
1524 vnc_encoding_type_tree,
1528 case ENCODING_RICH_CURSOR:
1529 case ENCODING_X_CURSOR:
1530 proto_item_append_text (ti_x, " (hotspot X)");
1531 proto_item_append_text (ti_y, " (hotspot Y)");
1532 proto_item_append_text (ti_width, " (cursor width)");
1533 proto_item_append_text (ti_height, " (cursor height)");
1535 if (encoding_type == ENCODING_RICH_CURSOR)
1536 bytes_needed = vnc_rich_cursor_encoding(tvb, pinfo, offset, vnc_encoding_type_tree, width, height);
1538 bytes_needed = vnc_x_cursor_encoding(tvb, pinfo, offset, vnc_encoding_type_tree, width, height);
1542 case ENCODING_POINTER_POS:
1543 proto_item_append_text (ti_x, " (pointer X)");
1544 proto_item_append_text (ti_y, " (pointer Y)");
1545 proto_item_append_text (ti_width, " (unused)");
1546 proto_item_append_text (ti_height, " (unused)");
1550 case ENCODING_DESKTOP_SIZE:
1552 /* There is no payload for this message type */
1559 /* Check if the routines above requested more bytes to
1560 * be desegmented. */
1561 if(bytes_needed > 0)
1562 return bytes_needed;
1570 vnc_raw_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1571 proto_tree *tree, guint16 width, guint16 height)
1573 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1576 length = width * height * bytes_per_pixel;
1577 VNC_BYTES_NEEDED(length);
1579 proto_tree_add_item(tree, hf_vnc_raw_pixel_data, tvb, *offset,
1583 return 0; /* bytes_needed */
1588 vnc_copyrect_encoding(tvbuff_t *tvb, packet_info *pinfo _U_, gint *offset,
1589 proto_tree *tree, guint16 width _U_, guint16 height _U_)
1591 proto_tree_add_item(tree, hf_vnc_copyrect_src_x_pos, tvb, *offset,
1595 proto_tree_add_item(tree, hf_vnc_copyrect_src_y_pos, tvb, *offset,
1599 return 0; /* bytes_needed */
1604 vnc_rre_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1605 proto_tree *tree, guint16 width _U_, guint16 height _U_)
1607 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1608 guint32 num_subrects, i;
1611 proto_tree *subrect_tree;
1613 VNC_BYTES_NEEDED(4);
1614 proto_tree_add_item(tree, hf_vnc_rre_num_subrects, tvb, *offset,
1616 num_subrects = tvb_get_ntohl(tvb, *offset);
1619 VNC_BYTES_NEEDED(bytes_per_pixel);
1620 proto_tree_add_item(tree, hf_vnc_rre_bg_pixel, tvb, *offset,
1621 bytes_per_pixel, FALSE);
1622 *offset += bytes_per_pixel;
1624 for(i = 1; i <= num_subrects; i++) {
1625 bytes_needed = bytes_per_pixel + 8;
1626 VNC_BYTES_NEEDED(bytes_needed);
1628 ti = proto_tree_add_text(tree, tvb, *offset, bytes_per_pixel +
1629 8, "Subrectangle #%d", i);
1631 proto_item_add_subtree(ti, ett_vnc_rre_subrect);
1633 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_pixel,
1634 tvb, *offset, bytes_per_pixel, FALSE);
1635 *offset += bytes_per_pixel;
1637 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_x_pos,
1638 tvb, *offset, 2, FALSE);
1641 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_y_pos,
1642 tvb, *offset, 2, FALSE);
1645 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_width,
1646 tvb, *offset, 2, FALSE);
1649 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_height,
1650 tvb, *offset, 2, FALSE);
1654 return 0; /* bytes_needed */
1659 vnc_hextile_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1660 proto_tree *tree, guint16 width, guint16 height)
1662 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1663 guint8 i, subencoding_mask, num_subrects, subrect_len;
1665 proto_tree *subencoding_mask_tree, *subrect_tree, *num_subrects_tree;
1668 VNC_BYTES_NEEDED(1);
1669 ti = proto_tree_add_item(tree, hf_vnc_hextile_subencoding_mask, tvb,
1671 subencoding_mask = tvb_get_guint8(tvb, *offset);
1673 subencoding_mask_tree =
1674 proto_item_add_subtree(ti, ett_vnc_hextile_subencoding_mask);
1676 proto_tree_add_item(subencoding_mask_tree,
1677 hf_vnc_hextile_raw, tvb, *offset, 1,
1679 proto_tree_add_item(subencoding_mask_tree,
1680 hf_vnc_hextile_bg, tvb, *offset, 1,
1682 proto_tree_add_item(subencoding_mask_tree,
1683 hf_vnc_hextile_fg, tvb, *offset, 1,
1685 proto_tree_add_item(subencoding_mask_tree,
1686 hf_vnc_hextile_anysubrects, tvb, *offset, 1,
1688 proto_tree_add_item(subencoding_mask_tree,
1689 hf_vnc_hextile_subrectscolored, tvb, *offset, 1,
1693 if(subencoding_mask & 0x1) { /* Raw */
1694 length = width * height * bytes_per_pixel;
1696 VNC_BYTES_NEEDED(length);
1698 proto_tree_add_item(tree, hf_vnc_hextile_raw_value, tvb,
1699 *offset, length, FALSE);
1702 if(subencoding_mask & 0x2) { /* Background Specified */
1703 proto_tree_add_item(tree, hf_vnc_hextile_bg_value,
1704 tvb, *offset, bytes_per_pixel,
1706 *offset += bytes_per_pixel;
1709 if(subencoding_mask & 0x4) { /* Foreground Specified */
1710 proto_tree_add_item(tree, hf_vnc_hextile_fg_value,
1711 tvb, *offset, bytes_per_pixel,
1713 *offset += bytes_per_pixel;
1716 if(subencoding_mask & 0x8) { /* Any Subrects */
1717 ti = proto_tree_add_item(tree,
1718 hf_vnc_hextile_num_subrects,
1721 num_subrects = tvb_get_guint8(tvb, *offset);
1725 proto_item_add_subtree(ti, ett_vnc_hextile_num_subrects);
1727 for(i = 1; i <= num_subrects; i++) {
1729 if(subencoding_mask & 0x16)
1730 subrect_len = bytes_per_pixel + 2;
1734 ti = proto_tree_add_text(num_subrects_tree, tvb,
1735 *offset, subrect_len,
1736 "Subrectangle #%d", i);
1739 proto_item_add_subtree(ti, ett_vnc_hextile_subrect);
1741 if(subencoding_mask & 0x16) {
1742 /* Subrects Colored */
1743 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_pixel_value, tvb, *offset, bytes_per_pixel, FALSE);
1745 *offset += bytes_per_pixel;
1748 proto_tree_add_item(subrect_tree,
1749 hf_vnc_hextile_subrect_x_pos, tvb, *offset, 1, FALSE);
1751 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_y_pos, tvb, *offset, 1, FALSE);
1755 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_width, tvb, *offset, 1, FALSE);
1757 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_height, tvb, *offset, 1, FALSE);
1764 return 0; /* bytes_needed */
1769 vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1770 proto_tree *tree, guint16 width, guint16 height)
1773 vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo _U_, gint *offset,
1774 proto_tree *tree, guint16 width _U_, guint16 height _U_)
1779 guint8 palette_size;
1780 guint8 bytes_per_cpixel = vnc_get_bytes_per_pixel(pinfo);
1781 gint uncomp_offset = 0;
1783 gint subencoding_type;
1784 tvbuff_t *uncomp_tvb = NULL;
1785 proto_tree *zrle_subencoding_tree;
1789 VNC_BYTES_NEEDED(4);
1790 proto_tree_add_item(tree, hf_vnc_zrle_len, tvb, *offset,
1792 data_len = tvb_get_ntohl(tvb, *offset);
1796 VNC_BYTES_NEEDED(data_len);
1798 proto_tree_add_item(tree, hf_vnc_zrle_data, tvb, *offset,
1802 uncomp_tvb = tvb_child_uncompress(tvb, tvb, *offset, data_len);
1804 if(uncomp_tvb != NULL) {
1805 add_new_data_source(pinfo, uncomp_tvb,
1806 "Uncompressed ZRLE data");
1808 ti = proto_tree_add_item(tree, hf_vnc_zrle_subencoding,
1809 uncomp_tvb, uncomp_offset, 1, FALSE);
1810 zrle_subencoding_tree =
1811 proto_item_add_subtree(ti, ett_vnc_zrle_subencoding);
1813 proto_tree_add_item(zrle_subencoding_tree, hf_vnc_zrle_rle,
1814 uncomp_tvb, uncomp_offset, 1, FALSE);
1816 proto_tree_add_item(zrle_subencoding_tree,
1817 hf_vnc_zrle_palette_size, uncomp_tvb,
1818 uncomp_offset, 1, FALSE);
1820 subencoding_type = tvb_get_guint8(uncomp_tvb, uncomp_offset);
1821 palette_size = subencoding_type & 0x7F;
1825 if(subencoding_type == 0) { /* Raw */
1826 length = width * height * bytes_per_cpixel;
1827 VNC_BYTES_NEEDED(length);
1829 /* XXX - not working yet! */
1831 proto_tree_add_item(zrle_subencoding_tree,
1832 hf_vnc_zrle_raw, uncomp_tvb,
1833 uncomp_offset, length, FALSE);
1835 } else if(subencoding_type >= 130 && subencoding_type <= 255) {
1836 length = palette_size * bytes_per_cpixel;
1837 VNC_BYTES_NEEDED(length);
1839 proto_tree_add_item(zrle_subencoding_tree,
1840 hf_vnc_zrle_palette, uncomp_tvb,
1841 uncomp_offset, length, FALSE);
1843 /* XXX - Not complete! */
1847 proto_tree_add_text(tree, tvb, *offset, data_len,
1848 "Decompression of ZRLE data failed");
1850 #endif /* HAVE_LIBZ */
1852 *offset += data_len;
1854 return 0; /* bytes_needed */
1859 read_compact_len(tvbuff_t *tvb, gint *offset, gint *length, gint *value_length)
1863 VNC_BYTES_NEEDED(1);
1867 b = tvb_get_guint8(tvb, *offset);
1872 if ((b & 0x80) != 0) {
1873 VNC_BYTES_NEEDED(1);
1875 b = tvb_get_guint8(tvb, *offset);
1879 *length |= (b & 0x7f) << 7;
1881 if ((b & 0x80) != 0) {
1882 VNC_BYTES_NEEDED (1);
1884 b = tvb_get_guint8(tvb, *offset);
1888 *length |= (b & 0xff) << 14;
1897 process_compact_length_and_image_data(tvbuff_t *tvb, gint *offset, proto_tree *tree)
1900 guint length, value_length;
1902 bytes_needed = read_compact_len (tvb, offset, &length, &value_length);
1903 if (bytes_needed != 0)
1904 return bytes_needed;
1906 proto_tree_add_uint(tree, hf_vnc_tight_image_len, tvb, *offset - value_length, value_length, length);
1908 VNC_BYTES_NEEDED(length);
1909 proto_tree_add_item(tree, hf_vnc_tight_image_data, tvb, *offset, length, FALSE);
1912 return 0; /* bytes_needed */
1917 process_tight_rect_filter_palette(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1918 proto_tree *tree, gint *bits_per_pixel)
1920 vnc_packet_t *per_packet_info;
1922 guint palette_bytes;
1924 /* See TightVNC's vnc_unixsrc/vncviewer/tight.c:InitFilterPaletteBPP() */
1926 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
1928 VNC_BYTES_NEEDED(1);
1929 proto_tree_add_item(tree, hf_vnc_tight_palette_num_colors, tvb, *offset, 1, FALSE);
1930 num_colors = tvb_get_guint8(tvb, *offset);
1937 if (per_packet_info->depth == 24)
1938 palette_bytes = num_colors * 3;
1940 palette_bytes = num_colors * per_packet_info->depth / 8;
1942 VNC_BYTES_NEEDED(palette_bytes);
1943 proto_tree_add_item(tree, hf_vnc_tight_palette_data, tvb, *offset, palette_bytes, FALSE);
1944 *offset += palette_bytes;
1946 /* This is the number of bits per pixel *in the image data*, not the actual client depth */
1947 if (num_colors == 2)
1948 *bits_per_pixel = 1;
1950 *bits_per_pixel = 8;
1956 vnc_tight_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1957 proto_tree *tree, guint16 width, guint16 height)
1959 vnc_packet_t *per_packet_info;
1961 proto_item *compression_type_ti;
1963 gint bytes_needed = -1;
1965 /* unused arguments */
1969 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
1971 /* See xserver/hw/vnc/rfbproto.h and grep for "Tight Encoding." for the following layout */
1973 VNC_BYTES_NEEDED(1);
1975 /* least significant bits 0-3 are "reset compression stream N" */
1976 bit_offset = *offset * 8;
1977 proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream0, tvb, bit_offset + 7, 1, FALSE);
1978 proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream1, tvb, bit_offset + 6, 1, FALSE);
1979 proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream2, tvb, bit_offset + 5, 1, FALSE);
1980 proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream3, tvb, bit_offset + 4, 1, FALSE);
1982 /* most significant bits 4-7 are "compression type" */
1983 compression_type_ti = proto_tree_add_bits_item(tree, hf_vnc_tight_rect_type, tvb, bit_offset + 0, 4, FALSE);
1985 comp_ctl = tvb_get_guint8(tvb, *offset);
1988 comp_ctl >>= 4; /* skip over the "reset compression" bits from above */
1990 /* compression format */
1992 if (comp_ctl == TIGHT_RECT_FILL) {
1993 /* "fill" encoding (solid rectangle) */
1995 proto_item_append_text(compression_type_ti, " (fill encoding - solid rectangle)");
1997 if (per_packet_info->depth == 24) {
1998 VNC_BYTES_NEEDED(3);
1999 proto_tree_add_item(tree, hf_vnc_tight_fill_color, tvb, *offset, 3, FALSE);
2002 VNC_BYTES_NEEDED(per_packet_info->bytes_per_pixel);
2003 proto_tree_add_item(tree, hf_vnc_tight_fill_color, tvb, *offset, per_packet_info->bytes_per_pixel, FALSE);
2004 *offset += per_packet_info->bytes_per_pixel;
2008 } else if (comp_ctl == TIGHT_RECT_JPEG) {
2011 proto_item_append_text(compression_type_ti, " (JPEG encoding)");
2012 bytes_needed = process_compact_length_and_image_data(tvb, offset, tree);
2013 if (bytes_needed != 0)
2014 return bytes_needed;
2015 } else if (comp_ctl > TIGHT_RECT_MAX_VALUE) {
2016 /* invalid encoding */
2018 proto_item_append_text(compression_type_ti, " (invalid encoding)");
2019 DISSECTOR_ASSERT_NOT_REACHED();
2022 gint bits_per_pixel;
2024 /* basic encoding */
2026 proto_item_append_text(compression_type_ti, " (basic encoding)");
2028 proto_tree_add_bits_item(tree, hf_vnc_tight_filter_flag, tvb, bit_offset + 1, 1, FALSE);
2030 bits_per_pixel = per_packet_info->depth;
2032 if ((comp_ctl & TIGHT_RECT_EXPLICIT_FILTER_FLAG) != 0) {
2035 /* explicit filter */
2037 VNC_BYTES_NEEDED(1);
2038 proto_tree_add_item(tree, hf_vnc_tight_filter_id, tvb, *offset, 1, FALSE);
2039 filter_id = tvb_get_guint8(tvb, *offset);
2042 switch (filter_id) {
2043 case TIGHT_RECT_FILTER_COPY:
2047 case TIGHT_RECT_FILTER_PALETTE:
2048 bytes_needed = process_tight_rect_filter_palette(tvb, pinfo, offset, tree, &bits_per_pixel);
2049 if (bytes_needed != 0)
2050 return bytes_needed;
2054 case TIGHT_RECT_FILTER_GRADIENT:
2059 /* this is the same case as TIGHT_RECT_FILTER_COPY, so there's nothing special to do */
2062 row_size = ((guint) width * bits_per_pixel + 7) / 8;
2063 if (row_size * height < TIGHT_MIN_BYTES_TO_COMPRESS) {
2066 /* The data is not compressed; just skip over it */
2068 num_bytes = row_size * height;
2069 VNC_BYTES_NEEDED(num_bytes);
2070 proto_tree_add_item(tree, hf_vnc_tight_image_data, tvb, *offset, num_bytes, FALSE);
2071 *offset += num_bytes;
2075 /* The data is compressed; read its length and data */
2076 bytes_needed = process_compact_length_and_image_data(tvb, offset, tree);
2077 if (bytes_needed != 0)
2078 return bytes_needed;
2082 DISSECTOR_ASSERT(bytes_needed != -1);
2084 return bytes_needed;
2089 decode_cursor(tvbuff_t *tvb, gint *offset, proto_tree *tree,
2090 guint pixels_bytes, guint mask_bytes)
2094 total_bytes = pixels_bytes + mask_bytes;
2095 VNC_BYTES_NEEDED (total_bytes);
2097 proto_tree_add_item(tree, hf_vnc_cursor_encoding_pixels, tvb, *offset,
2098 pixels_bytes, FALSE);
2099 *offset += pixels_bytes;
2101 proto_tree_add_item(tree, hf_vnc_cursor_encoding_bitmask, tvb, *offset,
2103 *offset += mask_bytes;
2105 return 0; /* bytes_needed */
2110 vnc_rich_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2111 proto_tree *tree, guint16 width, guint16 height)
2113 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
2114 guint pixels_bytes, mask_bytes;
2116 pixels_bytes = width * height * bytes_per_pixel;
2117 mask_bytes = ((width + 7) / 8) * height;
2119 return decode_cursor(tvb, offset, tree,
2120 pixels_bytes, mask_bytes);
2125 vnc_x_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2126 proto_tree *tree, guint16 width, guint16 height)
2128 gint bitmap_row_bytes = (width + 7) / 8;
2129 gint mask_bytes = bitmap_row_bytes * height;
2130 (void) pinfo; /* unused argument */
2132 VNC_BYTES_NEEDED (6);
2133 proto_tree_add_item(tree, hf_vnc_cursor_x_fore_back, tvb, *offset, 6, FALSE);
2136 /* The length of the pixel data is the same as the length of the mask data (X cursors are strictly black/white) */
2137 return decode_cursor(tvb, offset, tree,
2138 mask_bytes, mask_bytes);
2143 vnc_server_set_colormap_entries(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2146 guint16 number_of_colors;
2147 guint counter, bytes_needed;
2149 proto_tree *vnc_colormap_num_groups, *vnc_colormap_color_group;
2151 col_set_str(pinfo->cinfo, COL_INFO, "Server set colormap entries");
2153 number_of_colors = tvb_get_ntohs(tvb, 4);
2155 bytes_needed = (number_of_colors * 6) + 6;
2156 VNC_BYTES_NEEDED(bytes_needed);
2158 ti = proto_tree_add_item(tree, hf_vnc_server_message_type, tvb,
2160 tree = proto_item_add_subtree(ti, ett_vnc_server_message_type);
2163 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 1, FALSE);
2164 *offset += 1; /* Skip over 1 byte of padding */
2166 proto_tree_add_item(tree,
2167 hf_vnc_colormap_first_color,
2168 tvb, *offset, 2, FALSE);
2171 ti = proto_tree_add_item(tree, hf_vnc_colormap_num_colors, tvb,
2173 vnc_colormap_num_groups =
2174 proto_item_add_subtree(ti, ett_vnc_colormap_num_groups);
2178 for(counter = 1; counter <= number_of_colors; counter++) {
2179 ti = proto_tree_add_text(vnc_colormap_num_groups, tvb,
2181 "Color group #%d", counter);
2183 vnc_colormap_color_group =
2184 proto_item_add_subtree(ti,
2185 ett_vnc_colormap_color_group);
2187 proto_tree_add_item(vnc_colormap_color_group,
2188 hf_vnc_colormap_red, tvb,
2192 proto_tree_add_item(vnc_colormap_color_group,
2193 hf_vnc_colormap_green, tvb,
2197 proto_tree_add_item(vnc_colormap_color_group,
2198 hf_vnc_colormap_blue, tvb,
2207 vnc_server_ring_bell(tvbuff_t *tvb _U_, packet_info *pinfo, gint *offset _U_,
2208 proto_tree *tree _U_)
2210 col_set_str(pinfo->cinfo, COL_INFO, "Server ring bell on client");
2211 /* This message type has no payload... */
2216 vnc_server_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2221 col_set_str(pinfo->cinfo, COL_INFO, "Server cut text");
2223 text_len = tvb_get_ntohl(tvb, *offset);
2224 proto_tree_add_item(tree,
2225 hf_vnc_server_cut_text_len, tvb, *offset, 4,
2229 VNC_BYTES_NEEDED(text_len);
2231 proto_tree_add_item(tree, hf_vnc_server_cut_text, tvb, *offset,
2233 *offset += text_len;
2240 vnc_set_bytes_per_pixel(packet_info *pinfo, guint8 bytes_per_pixel)
2242 vnc_packet_t *per_packet_info;
2244 /* The per_packet_info has already been created by the
2245 * vnc_startup_messages() routine. */
2246 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
2247 per_packet_info->bytes_per_pixel = bytes_per_pixel;
2252 vnc_set_depth(packet_info *pinfo, guint8 depth)
2254 vnc_packet_t *per_packet_info;
2256 /* The per_packet_info has already been created by the
2257 * vnc_startup_messages() routine. */
2258 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
2259 per_packet_info->depth = depth;
2264 vnc_get_bytes_per_pixel(packet_info *pinfo)
2266 vnc_packet_t *per_packet_info;
2268 /* The per_packet_info has already been created by the
2269 * vnc_startup_messages() routine. */
2270 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
2271 return per_packet_info->bytes_per_pixel;
2275 /* Register the protocol with Wireshark */
2277 proto_register_vnc(void)
2279 module_t *vnc_module; /* To handle our preferences */
2281 /* Setup list of header fields */
2282 static hf_register_info hf[] = {
2284 { "Padding", "vnc.padding",
2285 FT_NONE, BASE_NONE, NULL, 0x0,
2286 "Unused space", HFILL }
2289 { &hf_vnc_server_proto_ver,
2290 { "Server protocol version", "vnc.server_proto_ver",
2291 FT_STRING, BASE_NONE, NULL, 0x0,
2292 "VNC protocol version on server", HFILL }
2294 { &hf_vnc_client_proto_ver,
2295 { "Client protocol version", "vnc.client_proto_ver",
2296 FT_STRING, BASE_NONE, NULL, 0x0,
2297 "VNC protocol version on client", HFILL }
2299 { &hf_vnc_num_security_types,
2300 { "Number of security types", "vnc.num_security_types",
2301 FT_UINT8, BASE_DEC, NULL, 0x0,
2302 "Number of security (authentication) types supported by the server", HFILL }
2304 { &hf_vnc_security_type,
2305 { "Security type", "vnc.security_type",
2306 FT_UINT8, BASE_DEC, VALS(security_types_vs), 0x0,
2307 "Security types offered by the server (VNC versions => 3.007", HFILL }
2309 { &hf_vnc_server_security_type,
2310 { "Security type", "vnc.server_security_type",
2311 FT_UINT32, BASE_DEC, VALS(security_types_vs), 0x0,
2312 "Security type mandated by the server", HFILL }
2314 { &hf_vnc_client_security_type,
2315 { "Security type selected", "vnc.security_type",
2316 FT_UINT8, BASE_DEC, VALS(security_types_vs), 0x0,
2317 "Security type selected by the client", HFILL }
2319 { &hf_vnc_tight_num_tunnel_types,
2320 { "Number of supported tunnel types", "vnc.num_tunnel_types",
2321 FT_UINT32, BASE_DEC, NULL, 0x0,
2322 "Number of tunnel types for TightVNC", HFILL }
2324 { &hf_vnc_tight_tunnel_type,
2325 { "Tunnel type", "vnc.tunnel_type",
2326 FT_UINT8, BASE_DEC, NULL, 0x0,
2327 "Tunnel type specific to TightVNC", HFILL }
2329 { &hf_vnc_tight_num_auth_types,
2330 { "Number of supported authentication types", "vnc.num_auth_types",
2331 FT_UINT32, BASE_DEC, NULL, 0x0,
2332 "Authentication types specific to TightVNC", HFILL }
2334 { &hf_vnc_tight_auth_type,
2335 { "Authentication type", "vnc.auth_type",
2336 FT_UINT8, BASE_DEC, NULL, 0x0,
2337 "Authentication type specific to TightVNC", HFILL }
2339 { &hf_vnc_tight_server_message_type,
2340 { "Server message type", "vnc.server_message_type",
2341 FT_INT32, BASE_DEC, NULL, 0x0,
2342 "Server message type specific to TightVNC", HFILL }
2344 { &hf_vnc_tight_server_vendor,
2345 { "Server vendor code", "vnc.server_vendor",
2346 FT_STRING, BASE_NONE, NULL, 0x0,
2347 "Server vendor code specific to TightVNC", HFILL }
2349 { &hf_vnc_tight_server_name,
2350 { "Server name", "vnc.server_name",
2351 FT_STRING, BASE_NONE, NULL, 0x0,
2352 "Server name specific to TightVNC", HFILL }
2354 { &hf_vnc_tight_client_message_type,
2355 { "Client message type", "vnc.client_message_type",
2356 FT_INT32, BASE_DEC, NULL, 0x0,
2357 "Client message type specific to TightVNC", HFILL }
2359 { &hf_vnc_tight_client_vendor,
2360 { "Client vendor code", "vnc.client_vendor",
2361 FT_STRING, BASE_NONE, NULL, 0x0,
2362 "Client vendor code specific to TightVNC", HFILL }
2364 { &hf_vnc_tight_client_name,
2365 { "Client name", "vnc.client_name",
2366 FT_STRING, BASE_NONE, NULL, 0x0,
2367 "Client name specific to TightVNC", HFILL }
2369 { &hf_vnc_tight_encoding_type,
2370 { "Encoding type", "vnc.encoding_type",
2371 FT_INT32, BASE_DEC, NULL, 0x0,
2372 "Encoding type specific to TightVNC", HFILL }
2374 { &hf_vnc_tight_encoding_vendor,
2375 { "Encoding vendor code", "vnc.encoding_vendor",
2376 FT_STRING, BASE_NONE, NULL, 0x0,
2377 "Encoding vendor code specific to TightVNC", HFILL }
2379 { &hf_vnc_tight_encoding_name,
2380 { "Encoding name", "vnc.encoding_name",
2381 FT_STRING, BASE_NONE, NULL, 0x0,
2382 "Encoding name specific to TightVNC", HFILL }
2384 { &hf_vnc_tight_reset_stream0,
2385 { "Reset compression stream 0", "vnc.tight_reset_stream0",
2386 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2387 "Tight compression, reset compression stream 0", HFILL }
2389 { &hf_vnc_tight_reset_stream1,
2390 { "Reset compression stream 1", "vnc.tight_reset_stream0",
2391 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2392 "Tight compression, reset compression stream 1", HFILL }
2394 { &hf_vnc_tight_reset_stream2,
2395 { "Reset compression stream 2", "vnc.tight_reset_stream0",
2396 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2397 "Tight compression, reset compression stream 2", HFILL }
2399 { &hf_vnc_tight_reset_stream3,
2400 { "Reset compression stream 3", "vnc.tight_reset_stream0",
2401 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2402 "Tight compression, reset compression stream 3", HFILL }
2404 { &hf_vnc_tight_rect_type,
2405 { "Rectangle type", "vnc.tight_rect_type",
2406 FT_UINT8, BASE_HEX, NULL, 0x0,
2407 "Tight compression, rectangle type", HFILL }
2409 { &hf_vnc_tight_image_len,
2410 { "Image data length", "vnc.tight_image_len",
2411 FT_UINT32, BASE_DEC, NULL, 0x0,
2412 "Tight compression, length of image data", HFILL }
2414 { &hf_vnc_tight_image_data,
2415 { "Image data", "vnc.tight_image_data",
2416 FT_BYTES, BASE_NONE, NULL, 0x0,
2417 "Tight compression, image data", HFILL }
2419 { &hf_vnc_tight_fill_color,
2420 { "Fill color (RGB)", "vnc.tight_fill_color",
2421 FT_BYTES, BASE_NONE, NULL, 0x0,
2422 "Tight compression, fill color for solid rectangle", HFILL }
2424 { &hf_vnc_tight_filter_flag,
2425 { "Explicit filter flag", "vnc.tight_filter_flag",
2426 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2427 "Tight compression, explicit filter flag", HFILL }
2429 { &hf_vnc_tight_filter_id,
2430 { "Filter ID", "vnc.tight_filter_id",
2431 FT_UINT8, BASE_DEC, VALS(tight_filter_ids_vs), 0x0,
2432 "Tight compression, filter ID", HFILL }
2434 { &hf_vnc_tight_palette_num_colors,
2435 { "Number of colors in palette", "vnc.tight_palette_num_colors",
2436 FT_UINT8, BASE_DEC, NULL, 0x0,
2437 "Tight compression, number of colors in rectangle's palette", HFILL }
2439 { &hf_vnc_tight_palette_data,
2440 { "Palette data", "vnc.tight_palette_data",
2441 FT_BYTES, BASE_NONE, NULL, 0x0,
2442 "Tight compression, palette data for a rectangle", HFILL }
2444 { &hf_vnc_vendor_code,
2445 { "Vendor code", "vnc.vendor_code",
2446 FT_STRING, BASE_NONE, NULL, 0x0,
2447 "Identifies the VNC server software's vendor", HFILL }
2449 { &hf_vnc_security_type_string,
2450 { "Security type string", "vnc.security_type_string",
2451 FT_STRING, BASE_NONE, NULL, 0x0,
2452 "Security type being used", HFILL }
2454 { &hf_vnc_auth_challenge,
2455 { "Authentication challenge", "vnc.auth_challenge",
2456 FT_STRING, BASE_NONE, NULL, 0x0,
2457 "Random authentication challenge from server to client", HFILL }
2459 { &hf_vnc_auth_response,
2460 { "Authentication response", "vnc.auth_response",
2461 FT_STRING, BASE_NONE, NULL, 0x0,
2462 "Client's encrypted response to the server's authentication challenge", HFILL }
2464 { &hf_vnc_auth_result,
2465 { "Authentication result", "vnc.auth_result",
2466 FT_UINT32, BASE_DEC, VALS(auth_result_vs), 0x0,
2469 { &hf_vnc_auth_error,
2470 { "Authentication error", "vnc.auth_error",
2471 FT_STRING, BASE_NONE, NULL, 0x0,
2472 "Authentication error (present only if the authentication result is fail", HFILL }
2474 { &hf_vnc_share_desktop_flag,
2475 { "Share desktop flag", "vnc.share_desktop_flag",
2476 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x0,
2477 "Client's desire to share the server's desktop with other clients", HFILL }
2480 { "Framebuffer width", "vnc.width",
2481 FT_UINT16, BASE_DEC, NULL, 0x0,
2482 "Width of the framebuffer (screen) in pixels", HFILL }
2485 { "Framebuffer height", "vnc.width",
2486 FT_UINT16, BASE_DEC, NULL, 0x0,
2487 "Height of the framebuffer (screen) in pixels", HFILL }
2489 { &hf_vnc_server_bits_per_pixel,
2490 { "Bits per pixel", "vnc.server_bits_per_pixel",
2491 FT_UINT8, BASE_DEC, NULL, 0x0,
2492 "Number of bits used by server for each pixel value on the wire from the server", HFILL }
2494 { &hf_vnc_server_depth,
2495 { "Depth", "vnc.server_depth",
2496 FT_UINT8, BASE_DEC, NULL, 0x0,
2497 "Number of useful bits in the pixel value on server", HFILL }
2499 { &hf_vnc_server_big_endian_flag,
2500 { "Big endian flag", "vnc.server_big_endian_flag",
2501 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2502 "True if multi-byte pixels are interpreted as big endian by server", HFILL }
2504 { &hf_vnc_server_true_color_flag,
2505 { "True color flag", "vnc.server_true_color_flag",
2506 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2507 "If true, then the next six items specify how to extract the red, green and blue intensities from the pixel value on the server.", HFILL }
2509 { &hf_vnc_server_red_max,
2510 { "Red maximum", "vnc.server_red_max",
2511 FT_UINT16, BASE_DEC, NULL, 0x0,
2512 "Maximum red value on server as n: 2^n - 1", HFILL }
2514 { &hf_vnc_server_green_max,
2515 { "Green maximum", "vnc.server_green_max",
2516 FT_UINT16, BASE_DEC, NULL, 0x0,
2517 "Maximum green value on server as n: 2^n - 1", HFILL }
2519 { &hf_vnc_server_blue_max,
2520 { "Blue maximum", "vnc.server_blue_max",
2521 FT_UINT16, BASE_DEC, NULL, 0x0,
2522 "Maximum blue value on server as n: 2^n - 1", HFILL }
2524 { &hf_vnc_server_red_shift,
2525 { "Red shift", "vnc.server_red_shift",
2526 FT_UINT8, BASE_DEC, NULL, 0x0,
2527 "Number of shifts needed to get the red value in a pixel to the least significant bit on the server", HFILL }
2529 { &hf_vnc_server_green_shift,
2530 { "Green shift", "vnc.server_green_shift",
2531 FT_UINT8, BASE_DEC, NULL, 0x0,
2532 "Number of shifts needed to get the green value in a pixel to the least significant bit on the server", HFILL }
2534 { &hf_vnc_server_blue_shift,
2535 { "Blue shift", "vnc.server_blue_shift",
2536 FT_UINT8, BASE_DEC, NULL, 0x0,
2537 "Number of shifts needed to get the blue value in a pixel to the least significant bit on the server", HFILL }
2539 { &hf_vnc_desktop_name_len,
2540 { "Desktop name length", "vnc.desktop_name_len",
2541 FT_UINT32, BASE_DEC, NULL, 0x0,
2542 "Length of desktop name in bytes", HFILL }
2544 { &hf_vnc_desktop_name,
2545 { "Desktop name", "vnc.desktop_name",
2546 FT_STRING, BASE_NONE, NULL, 0x0,
2547 "Name of the VNC desktop on the server", HFILL }
2549 { &hf_vnc_num_server_message_types,
2550 { "Server message types", "vnc.num_server_message_types",
2551 FT_UINT16, BASE_DEC, NULL, 0x0,
2552 "Unknown", HFILL } /* XXX - Needs description */
2554 { &hf_vnc_num_client_message_types,
2555 { "Client message types", "vnc.num_client_message_types",
2556 FT_UINT16, BASE_DEC, NULL, 0x0,
2557 "Unknown", HFILL } /* XXX - Needs description */
2559 { &hf_vnc_num_encoding_types,
2560 { "Encoding types", "vnc.num_encoding_types",
2561 FT_UINT16, BASE_DEC, NULL, 0x0,
2562 "Unknown", HFILL } /* XXX - Needs description */
2564 { &hf_vnc_client_message_type,
2565 { "Client Message Type", "vnc.client_message_type",
2566 FT_UINT8, BASE_DEC, VALS(client_message_types_vs), 0x0,
2567 "Message type from client", HFILL }
2569 { &hf_vnc_client_bits_per_pixel,
2570 { "Bits per pixel", "vnc.client_bits_per_pixel",
2571 FT_UINT8, BASE_DEC, NULL, 0x0,
2572 "Number of bits used by server for each pixel value on the wire from the client", HFILL }
2574 { &hf_vnc_client_depth,
2575 { "Depth", "vnc.client_depth",
2576 FT_UINT8, BASE_DEC, NULL, 0x0,
2577 "Number of useful bits in the pixel value on client", HFILL }
2579 { &hf_vnc_client_big_endian_flag,
2580 { "Big endian flag", "vnc.client_big_endian_flag",
2581 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2582 "True if multi-byte pixels are interpreted as big endian by client", HFILL }
2584 { &hf_vnc_client_true_color_flag,
2585 { "True color flag", "vnc.client_true_color_flag",
2586 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2587 "If true, then the next six items specify how to extract the red, green and blue intensities from the pixel value on the client.", HFILL }
2589 { &hf_vnc_client_red_max,
2590 { "Red maximum", "vnc.client_red_max",
2591 FT_UINT16, BASE_DEC, NULL, 0x0,
2592 "Maximum red value on client as n: 2^n - 1", HFILL }
2594 { &hf_vnc_client_green_max,
2595 { "Green maximum", "vnc.client_green_max",
2596 FT_UINT16, BASE_DEC, NULL, 0x0,
2597 "Maximum green value on client as n: 2^n - 1", HFILL }
2599 { &hf_vnc_client_blue_max,
2600 { "Blue maximum", "vnc.client_blue_max",
2601 FT_UINT16, BASE_DEC, NULL, 0x0,
2602 "Maximum blue value on client as n: 2^n - 1", HFILL }
2604 { &hf_vnc_client_red_shift,
2605 { "Red shift", "vnc.client_red_shift",
2606 FT_UINT8, BASE_DEC, NULL, 0x0,
2607 "Number of shifts needed to get the red value in a pixel to the least significant bit on the client", HFILL }
2609 { &hf_vnc_client_green_shift,
2610 { "Green shift", "vnc.client_green_shift",
2611 FT_UINT8, BASE_DEC, NULL, 0x0,
2612 "Number of shifts needed to get the green value in a pixel to the least significant bit on the client", HFILL }
2614 { &hf_vnc_client_blue_shift,
2615 { "Blue shift", "vnc.client_blue_shift",
2616 FT_UINT8, BASE_DEC, NULL, 0x0,
2617 "Number of shifts needed to get the blue value in a pixel to the least significant bit on the client", HFILL }
2620 /* Client Key Event */
2622 { "Key down", "vnc.key_down",
2623 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x0,
2624 "Specifies whether the key is being pressed or not", HFILL }
2628 FT_UINT32, BASE_HEX, VALS(keysym_vals_source), 0x0, /* keysym_vals_source is from packet-x11-keysym.h */
2629 "Key being pressed/depressed", HFILL }
2632 /* Client Pointer Event */
2633 { &hf_vnc_button_1_pos,
2634 { "Mouse button #1 position", "vnc.button_1_pos",
2635 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x1,
2636 "Whether mouse button #1 is being pressed or not", HFILL }
2638 { &hf_vnc_button_2_pos,
2639 { "Mouse button #2 position", "vnc.button_2_pos",
2640 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x2,
2641 "Whether mouse button #2 is being pressed or not", HFILL }
2643 { &hf_vnc_button_3_pos,
2644 { "Mouse button #3 position", "vnc.button_3_pos",
2645 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x4,
2646 "Whether mouse button #3 is being pressed or not", HFILL }
2648 { &hf_vnc_button_4_pos,
2649 { "Mouse button #4 position", "vnc.button_4_pos",
2650 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x8,
2651 "Whether mouse button #4 is being pressed or not", HFILL }
2653 { &hf_vnc_button_5_pos,
2654 { "Mouse button #5 position", "vnc.button_5_pos",
2655 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x10,
2656 "Whether mouse button #5 is being pressed or not", HFILL }
2658 { &hf_vnc_button_6_pos,
2659 { "Mouse button #6 position", "vnc.button_6_pos",
2660 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x20,
2661 "Whether mouse button #6 is being pressed or not", HFILL }
2663 { &hf_vnc_button_7_pos,
2664 { "Mouse button #7 position", "vnc.button_7_pos",
2665 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x40,
2666 "Whether mouse button #7 is being pressed or not", HFILL }
2668 { &hf_vnc_button_8_pos,
2669 { "Mouse button #8 position", "vnc.button_8_pos",
2670 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x80,
2671 "Whether mouse button #8 is being pressed or not", HFILL }
2673 { &hf_vnc_pointer_x_pos,
2674 { "X position", "vnc.pointer_x_pos",
2675 FT_UINT16, BASE_DEC, NULL, 0x0,
2676 "Position of mouse cursor on the x-axis", HFILL }
2678 { &hf_vnc_pointer_y_pos,
2679 { "Y position", "vnc.pointer_y_pos",
2680 FT_UINT16, BASE_DEC, NULL, 0x0,
2681 "Position of mouse cursor on the y-axis", HFILL }
2683 { &hf_vnc_client_set_encodings_encoding_type,
2684 { "Encoding type", "vnc.client_set_encodings_encoding_type",
2685 FT_INT32, BASE_DEC, VALS(encoding_types_vs), 0x0,
2686 "Type of encoding used to send pixel data from server to client", HFILL }
2689 /* Client Framebuffer Update Request */
2690 { &hf_vnc_update_req_incremental,
2691 { "Incremental update", "vnc.update_req_incremental",
2692 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2693 "Specifies if the client wants an incremental update instead of a full one", HFILL }
2695 { &hf_vnc_update_req_x_pos,
2696 { "X position", "vnc.update_req_x_pos",
2697 FT_UINT16, BASE_DEC, NULL, 0x0,
2698 "X position of framebuffer (screen) update requested", HFILL }
2700 { &hf_vnc_update_req_y_pos,
2701 { "Y position", "vnc.update_req_y_pos",
2702 FT_UINT16, BASE_DEC, NULL, 0x0,
2703 "Y position of framebuffer (screen) update request", HFILL }
2705 { &hf_vnc_update_req_width,
2706 { "Width", "vnc.update_req_width",
2707 FT_UINT16, BASE_DEC, NULL, 0x0,
2708 "Width of framebuffer (screen) update request", HFILL }
2710 { &hf_vnc_update_req_height,
2711 { "Height", "vnc.update_req_height",
2712 FT_UINT16, BASE_DEC, NULL, 0x0,
2713 "Height of framebuffer (screen) update request", HFILL }
2715 { &hf_vnc_client_cut_text_len,
2716 { "Length", "vnc.client_cut_text_len",
2717 FT_UINT32, BASE_DEC, NULL, 0x0,
2718 "Length of client's copy/cut text (clipboard) string in bytes", HFILL }
2720 { &hf_vnc_client_cut_text,
2721 { "Text", "vnc.client_cut_text",
2722 FT_STRING, BASE_NONE, NULL, 0x0,
2723 "Text string in the client's copy/cut text (clipboard)", HFILL }
2727 /********** Server Message Types **********/
2728 { &hf_vnc_server_message_type,
2729 { "Server Message Type", "vnc.server_message_type",
2730 FT_UINT8, BASE_DEC, VALS(server_message_types_vs), 0x0,
2731 "Message type from server", HFILL }
2734 { &hf_vnc_fb_update_x_pos,
2735 { "X position", "vnc.fb_update_x_pos",
2736 FT_UINT16, BASE_DEC, NULL, 0x0,
2737 "X position of this server framebuffer update", HFILL }
2740 { &hf_vnc_fb_update_y_pos,
2741 { "Y position", "vnc.fb_update_x_pos",
2742 FT_UINT16, BASE_DEC, NULL, 0x0,
2743 "Y position of this server framebuffer update", HFILL }
2746 { &hf_vnc_fb_update_width,
2747 { "Width", "vnc.fb_update_width",
2748 FT_UINT16, BASE_DEC, NULL, 0x0,
2749 "Width of this server framebuffer update", HFILL }
2752 { &hf_vnc_fb_update_height,
2753 { "Height", "vnc.fb_update_height",
2754 FT_UINT16, BASE_DEC, NULL, 0x0,
2755 "Height of this server framebuffer update", HFILL }
2758 { &hf_vnc_fb_update_encoding_type,
2759 { "Encoding type", "vnc.fb_update_encoding_type",
2760 FT_INT32, BASE_DEC, VALS(encoding_types_vs), 0x0,
2761 "Encoding type of this server framebuffer update", HFILL }
2764 /* Cursor encoding */
2765 { &hf_vnc_cursor_x_fore_back,
2766 { "X Cursor foreground RGB / background RGB", "vnc.cursor_x_fore_back",
2767 FT_BYTES, BASE_NONE, NULL, 0x0,
2768 "RGB values for the X cursor's foreground and background", HFILL }
2771 { &hf_vnc_cursor_encoding_pixels,
2772 { "Cursor encoding pixels", "vnc.cursor_encoding_pixels",
2773 FT_BYTES, BASE_NONE, NULL, 0x0,
2774 "Cursor encoding pixel data", HFILL }
2777 { &hf_vnc_cursor_encoding_bitmask,
2778 { "Cursor encoding bitmask", "vnc.cursor_encoding_bitmask",
2779 FT_BYTES, BASE_NONE, NULL, 0x0,
2780 "Cursor encoding pixel bitmask", HFILL }
2784 { &hf_vnc_raw_pixel_data,
2785 { "Pixel data", "vnc.raw_pixel_data",
2786 FT_BYTES, BASE_NONE, NULL, 0x0,
2787 "Raw pixel data.", HFILL }
2790 /* CopyRect Encoding*/
2791 { &hf_vnc_copyrect_src_x_pos,
2792 { "Source x position", "vnc.copyrect_src_x_pos",
2793 FT_UINT16, BASE_DEC, NULL, 0x0,
2794 "X position of the rectangle to copy from", HFILL }
2797 { &hf_vnc_copyrect_src_y_pos,
2798 { "Source y position", "vnc.copyrect_src_y_pos",
2799 FT_UINT16, BASE_DEC, NULL, 0x0,
2800 "Y position of the rectangle to copy from", HFILL }
2804 { &hf_vnc_rre_num_subrects,
2805 { "Number of subrectangles", "vnc.rre_num_subrects",
2806 FT_UINT32, BASE_DEC, NULL, 0x0,
2807 "Number of subrectangles contained in this encoding type", HFILL }
2810 { &hf_vnc_rre_bg_pixel,
2811 { "Background pixel value", "vnc.rre_bg_pixel",
2812 FT_BYTES, BASE_NONE, NULL, 0x0,
2816 { &hf_vnc_rre_subrect_pixel,
2817 { "Pixel value", "vnc.rre_subrect_pixel",
2818 FT_BYTES, BASE_NONE, NULL, 0x0,
2819 "Subrectangle pixel value", HFILL }
2822 { &hf_vnc_rre_subrect_x_pos,
2823 { "X position", "vnc.rre_subrect_x_pos",
2824 FT_UINT16, BASE_DEC, NULL, 0x0,
2825 "Position of this subrectangle on the x axis", HFILL }
2828 { &hf_vnc_rre_subrect_y_pos,
2829 { "Y position", "vnc.rre_subrect_y_pos",
2830 FT_UINT16, BASE_DEC, NULL, 0x0,
2831 "Position of this subrectangle on the y axis", HFILL }
2834 { &hf_vnc_rre_subrect_width,
2835 { "Width", "vnc.rre_subrect_width",
2836 FT_UINT16, BASE_DEC, NULL, 0x0,
2837 "Width of this subrectangle", HFILL }
2840 { &hf_vnc_rre_subrect_height,
2841 { "Height", "vnc.rre_subrect_height",
2842 FT_UINT16, BASE_DEC, NULL, 0x0,
2843 "Height of this subrectangle", HFILL }
2847 /* Hextile Encoding */
2848 { &hf_vnc_hextile_subencoding_mask,
2849 { "Subencoding type", "vnc.hextile_subencoding",
2850 FT_UINT8, BASE_DEC, NULL, 0x0,
2851 "Hextile subencoding type.", HFILL }
2854 { &hf_vnc_hextile_raw,
2855 { "Raw", "vnc.hextile_raw",
2856 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x1,
2857 "Raw subencoding is used in this tile", HFILL }
2860 { &hf_vnc_hextile_raw_value,
2861 { "Raw pixel values", "vnc.hextile_raw_value",
2862 FT_BYTES, BASE_NONE, NULL, 0x0,
2863 "Raw subencoding pixel values", HFILL }
2866 { &hf_vnc_hextile_bg,
2867 { "Background Specified", "vnc.hextile_bg",
2868 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x2,
2869 "Background Specified subencoding is used in this tile", HFILL }
2872 { &hf_vnc_hextile_bg_value,
2873 { "Background pixel value", "vnc.hextile_bg_value",
2874 FT_BYTES, BASE_NONE, NULL, 0x0,
2875 "Background color for this tile", HFILL }
2878 { &hf_vnc_hextile_fg,
2879 { "Foreground Specified", "vnc.hextile_fg",
2880 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x4,
2881 "Foreground Specified subencoding is used in this tile", HFILL }
2884 { &hf_vnc_hextile_fg_value,
2885 { "Foreground pixel value", "vnc.hextile_fg_value",
2886 FT_BYTES, BASE_NONE, NULL, 0x0,
2887 "Foreground color for this tile", HFILL }
2890 { &hf_vnc_hextile_anysubrects,
2891 { "Any Subrects", "vnc.hextile_anysubrects",
2892 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x8,
2893 "Any subrects subencoding is used in this tile", HFILL }
2896 { &hf_vnc_hextile_num_subrects,
2897 { "Number of subrectangles", "vnc.hextile_num_subrects",
2898 FT_UINT8, BASE_DEC, NULL, 0x0,
2899 "Number of subrectangles that follow", HFILL }
2902 { &hf_vnc_hextile_subrectscolored,
2903 { "Subrects Colored", "vnc.hextile_subrectscolored",
2904 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x10,
2905 "Subrects colored subencoding is used in this tile", HFILL }
2908 { &hf_vnc_hextile_subrect_pixel_value,
2909 { "Pixel value", "vnc.hextile_subrect_pixel_value",
2910 FT_BYTES, BASE_NONE, NULL, 0x0,
2911 "Pixel value of this subrectangle", HFILL }
2914 { &hf_vnc_hextile_subrect_x_pos,
2915 { "X position", "vnc.hextile_subrect_x_pos",
2916 FT_UINT8, BASE_DEC, NULL, 0xF0, /* Top 4 bits */
2917 "X position of this subrectangle", HFILL }
2920 { &hf_vnc_hextile_subrect_y_pos,
2921 { "Y position", "vnc.hextile_subrect_y_pos",
2922 FT_UINT8, BASE_DEC, NULL, 0xF, /* Bottom 4 bits */
2923 "Y position of this subrectangle", HFILL }
2926 { &hf_vnc_hextile_subrect_width,
2927 { "Width", "vnc.hextile_subrect_width",
2928 FT_UINT8, BASE_DEC, NULL, 0xF0, /* Top 4 bits */
2929 "Subrectangle width minus one", HFILL }
2932 { &hf_vnc_hextile_subrect_height,
2933 { "Height", "vnc.hextile_subrect_height",
2934 FT_UINT8, BASE_DEC, NULL, 0xF, /* Bottom 4 bits */
2935 "Subrectangle height minus one", HFILL }
2941 { "ZRLE compressed length", "vnc.zrle_len",
2942 FT_UINT32, BASE_DEC, NULL, 0x0,
2943 "Length of compressed ZRLE data that follows", HFILL }
2946 { &hf_vnc_zrle_subencoding,
2947 { "Subencoding type", "vnc.zrle_subencoding",
2948 FT_UINT8, BASE_DEC, NULL, 0x0,
2949 "Subencoding type byte", HFILL }
2953 { "RLE", "vnc.zrle_rle",
2954 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x80, /* Upper bit */
2955 "Specifies that data is run-length encoded", HFILL }
2958 { &hf_vnc_zrle_palette_size,
2959 { "Palette size", "vnc.zrle_palette_size",
2960 FT_UINT8, BASE_DEC, NULL, 0x7F, /* Lower 7 bits */
2964 { &hf_vnc_zrle_data,
2965 { "ZRLE compressed data", "vnc.zrle_data",
2966 FT_BYTES, BASE_NONE, NULL, 0x0,
2967 "Compressed ZRLE data. Compiling with zlib support will uncompress and dissect this data", HFILL }
2971 { "Pixel values", "vnc.zrle_raw",
2972 FT_BYTES, BASE_NONE, NULL, 0x0,
2973 "Raw pixel values for this tile", HFILL }
2976 { &hf_vnc_zrle_palette,
2977 { "Palette", "vnc.zrle_palette",
2978 FT_BYTES, BASE_NONE, NULL, 0x0,
2979 "Palette pixel values", HFILL }
2982 /* Server Set Colormap Entries */
2983 { &hf_vnc_colormap_first_color,
2984 { "First color", "vnc.colormap_first_color",
2985 FT_UINT16, BASE_DEC, NULL, 0x0,
2986 "First color that should be mapped to given RGB intensities", HFILL }
2988 { &hf_vnc_colormap_num_colors,
2989 { "Number of color groups", "vnc.colormap_groups",
2990 FT_UINT16, BASE_DEC, NULL, 0x0,
2991 "Number of red/green/blue color groups", HFILL }
2993 { &hf_vnc_colormap_red,
2994 { "Red", "vnc.colormap_red",
2995 FT_UINT16, BASE_DEC, NULL, 0x0,
2996 "Red intensity", HFILL }
2998 { &hf_vnc_colormap_green,
2999 { "Green", "vnc.colormap_green",
3000 FT_UINT16, BASE_DEC, NULL, 0x0,
3001 "Green intensity", HFILL }
3003 { &hf_vnc_colormap_blue,
3004 { "Blue", "vnc.colormap_blue",
3005 FT_UINT16, BASE_DEC, NULL, 0x0,
3006 "Blue intensity", HFILL }
3009 /* Server Cut Text */
3010 { &hf_vnc_server_cut_text_len,
3011 { "Length", "vnc.server_cut_text_len",
3012 FT_UINT32, BASE_DEC, NULL, 0x0,
3013 "Length of server's copy/cut text (clipboard) string in bytes", HFILL }
3015 { &hf_vnc_server_cut_text,
3016 { "Text", "vnc.server_cut_text",
3017 FT_STRING, BASE_NONE, NULL, 0x0,
3018 "Text string in the server's copy/cut text (clipboard)", HFILL }
3022 /* Setup protocol subtree arrays */
3023 static gint *ett[] = {
3025 &ett_vnc_client_message_type,
3026 &ett_vnc_server_message_type,
3028 &ett_vnc_encoding_type,
3029 &ett_vnc_rre_subrect,
3030 &ett_vnc_hextile_subencoding_mask,
3031 &ett_vnc_hextile_num_subrects,
3032 &ett_vnc_hextile_subrect,
3033 &ett_vnc_zrle_subencoding,
3034 &ett_vnc_colormap_num_groups,
3035 &ett_vnc_colormap_color_group
3038 /* Register the protocol name and description */
3039 proto_vnc = proto_register_protocol("Virtual Network Computing",
3042 /* Required function calls to register the header fields and subtrees */
3043 proto_register_field_array(proto_vnc, hf, array_length(hf));
3044 proto_register_subtree_array(ett, array_length(ett));
3046 /* Register our preferences module */
3047 vnc_module = prefs_register_protocol(proto_vnc, proto_reg_handoff_vnc);
3049 prefs_register_bool_preference(vnc_module, "desegment", "Reassemble VNC messages spanning multiple TCP segments.", "Whether the VNC dissector should reassemble messages spanning multiple TCP segments. To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.", &vnc_preference_desegment);
3051 prefs_register_uint_preference(vnc_module, "alternate_port", "Alternate TCP port", "Decode this port's traffic as VNC in addition to the default ports (5500, 5501, 5900, 5901)", 10, &vnc_preference_alternate_port);
3056 proto_reg_handoff_vnc(void)
3058 static gboolean inited = FALSE;
3060 /* This is a behind the scenes variable that is not changed by the user.
3061 * This stores last setting of the vnc_preference_alternate_port. Used to keep
3062 * track of when the user has changed the setting so that we can delete
3063 * and re-register with the new port number. */
3064 static guint vnc_preference_alternate_port_last = 0;
3067 vnc_handle = create_dissector_handle(dissect_vnc, proto_vnc);
3069 dissector_add("tcp.port", 5500, vnc_handle);
3070 dissector_add("tcp.port", 5501, vnc_handle);
3071 dissector_add("tcp.port", 5900, vnc_handle);
3072 dissector_add("tcp.port", 5901, vnc_handle);
3074 heur_dissector_add("tcp", test_vnc_protocol, proto_vnc);
3075 /* We don't register a port for the VNC HTTP server because
3076 * that simply provides a java program for download via the
3077 * HTTP protocol. The java program then connects to a standard
3081 } else { /* only after preferences have been read/changed */
3082 if(vnc_preference_alternate_port != vnc_preference_alternate_port_last &&
3083 vnc_preference_alternate_port != 5500 &&
3084 vnc_preference_alternate_port != 5501 &&
3085 vnc_preference_alternate_port != 5900 &&
3086 vnc_preference_alternate_port != 5901) {
3087 if (vnc_preference_alternate_port_last != 0) {
3088 dissector_delete("tcp.port",
3089 vnc_preference_alternate_port_last,
3092 /* Save this setting to see if has changed later */
3093 vnc_preference_alternate_port_last =
3094 vnc_preference_alternate_port;
3096 /* Register the new port setting */
3097 if (vnc_preference_alternate_port != 0) {
3098 dissector_add("tcp.port",
3099 vnc_preference_alternate_port,
3103 heur_dissector_add("tcp", test_vnc_protocol, proto_vnc);