2 * Routines for VNC dissection (Virtual Network Computing)
3 * Copyright 2005, Ulf Lamping <ulf.lamping@web.de>
4 * Copyright 2006-2007, Stephen Fisher <stephentfisher@yahoo.com>
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. */
62 #ifdef NEED_G_ASCII_STRCASECMP_H
63 #include "g_ascii_strcasecmp.h"
66 static const value_string security_types_vs[] = {
91 static const value_string auth_result_vs[] = {
97 static const value_string yes_no_vs[] = {
103 static const value_string client_message_types_vs[] = {
104 { 0, "Set Pixel Format" },
105 { 2, "Set Encodings" },
106 { 3, "Framebuffer Update Request" },
108 { 5, "Pointer Event" },
113 static const value_string server_message_types_vs[] = {
114 { 0, "Framebuffer Update" },
115 { 1, "Set Colormap Entries" },
121 static const value_string button_mask_vs[] = {
122 { 0, "Not pressed" },
127 static const value_string encoding_types_vs[] = {
128 { -239, "Cursor (pseudo)" },
129 { -223, "DesktopSize (pseudo)" },
149 TIGHT_UNKNOWN_PACKET1,
150 TIGHT_UNKNOWN_PACKET2,
151 TIGHT_AUTH_TYPE_AND_VENDOR_CODE,
152 TIGHT_UNKNOWN_PACKET3,
154 VNC_AUTHENTICATION_CHALLENGE,
155 VNC_AUTHENTICATION_RESPONSE,
162 TIGHT_INTERACTION_CAPS,
163 TIGHT_UNKNOWN_PACKET4,
166 } vnc_session_state_e;
168 /* This structure will be tied to each conversation. */
170 guint8 security_type_selected;
171 gdouble server_proto_ver, client_proto_ver;
172 vnc_session_state_e vnc_next_state;
173 } vnc_conversation_t;
175 /* This structure will be tied to each packet */
177 guint8 bytes_per_pixel;
178 vnc_session_state_e state;
181 void proto_reg_handoff_vnc(void);
183 static gboolean vnc_startup_messages(tvbuff_t *tvb, packet_info *pinfo,
184 gint offset, proto_tree *tree,
185 vnc_conversation_t *per_conversation_info);
186 static void vnc_client_to_server(tvbuff_t *tvb, packet_info *pinfo,
187 gint *offset, proto_tree *tree);
188 static void vnc_server_to_client(tvbuff_t *tvb, packet_info *pinfo,
189 gint *offset, proto_tree *tree);
190 static void vnc_client_set_pixel_format(tvbuff_t *tvb, packet_info *pinfo,
191 gint *offset, proto_tree *tree);
192 static void vnc_client_set_encodings(tvbuff_t *tvb, packet_info *pinfo,
193 gint *offset, proto_tree *tree);
194 static void vnc_client_framebuffer_update_request(tvbuff_t *tvb,
198 static void vnc_client_key_event(tvbuff_t *tvb, packet_info *pinfo,
199 gint *offset, proto_tree *tree);
200 static void vnc_client_pointer_event(tvbuff_t *tvb, packet_info *pinfo,
201 gint *offset, proto_tree *tree);
202 static void vnc_client_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
205 static guint vnc_server_framebuffer_update(tvbuff_t *tvb, packet_info *pinfo,
206 gint *offset, proto_tree *tree);
207 static guint vnc_raw_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
208 proto_tree *tree, guint16 width, guint16 height);
209 static guint vnc_copyrect_encoding(tvbuff_t *tvb, packet_info *pinfo,
210 gint *offset, proto_tree *tree,
211 guint16 width, guint16 height);
212 static guint vnc_rre_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
213 proto_tree *tree, guint16 width, guint16 height);
214 static guint vnc_hextile_encoding(tvbuff_t *tvb, packet_info *pinfo,
215 gint *offset, proto_tree *tree,
216 guint16 width, guint16 height);
217 static guint vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
218 proto_tree *tree, guint16 width, guint16 height);
219 static guint vnc_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo,
220 gint *offset, proto_tree *tree, guint16 width,
222 static guint vnc_server_set_colormap_entries(tvbuff_t *tvb, packet_info *pinfo,
223 gint *offset, proto_tree *tree);
224 static void vnc_server_ring_bell(tvbuff_t *tvb, packet_info *pinfo,
225 gint *offset, proto_tree *tree);
226 static guint vnc_server_cut_text(tvbuff_t *tvb, packet_info *pinfo,
227 gint *offset, proto_tree *tree);
228 static void vnc_set_bytes_per_pixel(packet_info *pinfo, guint8 bytes_per_pixel);
229 static guint8 vnc_get_bytes_per_pixel(packet_info *pinfo);
232 #define DEST_PORT_VNC pinfo->destport == 5500 || pinfo->destport == 5501 || \
233 pinfo->destport == 5900 || pinfo->destport == 5901 || \
234 pinfo->destport == vnc_preference_alternate_port
236 #define VNC_BYTES_NEEDED(a) \
237 if(a > (guint)tvb_length_remaining(tvb, *offset)) \
241 /* Variables for our preferences */
242 static guint vnc_preference_alternate_port = 0;
244 /* This is a behind the scenes variable that is not changed by the user.
245 * This stores last setting of the vnc_preference_alternate_port. Used to keep
246 * track of when the user has changed the setting so that we can delete
247 * and re-register with the new port number. */
248 static guint vnc_preference_alternate_port_last = 0;
250 /* Initialize the protocol and registered fields */
251 static int proto_vnc = -1; /* Protocol subtree */
252 static int hf_vnc_padding = -1;
253 static int hf_vnc_server_proto_ver = -1;
254 static int hf_vnc_client_proto_ver = -1;
255 static int hf_vnc_num_security_types = -1;
256 static int hf_vnc_security_type = -1;
257 static int hf_vnc_server_security_type = -1;
258 static int hf_vnc_client_security_type = -1;
259 static int hf_vnc_vendor_code = -1;
260 static int hf_vnc_security_type_string = -1;
261 static int hf_vnc_auth_challenge = -1;
262 static int hf_vnc_auth_response = -1;
263 static int hf_vnc_auth_result = -1;
264 static int hf_vnc_auth_error = -1;
266 static int hf_vnc_share_desktop_flag = -1;
267 static int hf_vnc_width = -1;
268 static int hf_vnc_height = -1;
269 static int hf_vnc_server_bits_per_pixel = -1;
270 static int hf_vnc_server_depth = -1;
271 static int hf_vnc_server_big_endian_flag = -1;
272 static int hf_vnc_server_true_color_flag = -1;
273 static int hf_vnc_server_red_max = -1;
274 static int hf_vnc_server_green_max = -1;
275 static int hf_vnc_server_blue_max = -1;
276 static int hf_vnc_server_red_shift = -1;
277 static int hf_vnc_server_green_shift = -1;
278 static int hf_vnc_server_blue_shift = -1;
279 static int hf_vnc_desktop_name = -1;
280 static int hf_vnc_desktop_name_len = -1;
282 static int hf_vnc_num_server_message_types = -1;
283 static int hf_vnc_num_client_message_types = -1;
284 static int hf_vnc_num_encoding_types = -1;
286 /********** Client Message Types **********/
288 static int hf_vnc_client_message_type = -1; /* A subtree under VNC */
289 static int hf_vnc_client_bits_per_pixel = -1;
290 static int hf_vnc_client_depth = -1;
291 static int hf_vnc_client_big_endian_flag = -1;
292 static int hf_vnc_client_true_color_flag = -1;
293 static int hf_vnc_client_red_max = -1;
294 static int hf_vnc_client_green_max = -1;
295 static int hf_vnc_client_blue_max = -1;
296 static int hf_vnc_client_red_shift = -1;
297 static int hf_vnc_client_green_shift = -1;
298 static int hf_vnc_client_blue_shift = -1;
300 /* Client Key Event */
301 static int hf_vnc_key_down = -1;
302 static int hf_vnc_key = -1;
304 /* Client Pointer Event */
305 static int hf_vnc_button_1_pos = -1;
306 static int hf_vnc_button_2_pos = -1;
307 static int hf_vnc_button_3_pos = -1;
308 static int hf_vnc_button_4_pos = -1;
309 static int hf_vnc_button_5_pos = -1;
310 static int hf_vnc_button_6_pos = -1;
311 static int hf_vnc_button_7_pos = -1;
312 static int hf_vnc_button_8_pos = -1;
313 static int hf_vnc_pointer_x_pos = -1;
314 static int hf_vnc_pointer_y_pos = -1;
316 /* Client Framebuffer Update Request */
317 static int hf_vnc_update_req_incremental = -1;
318 static int hf_vnc_update_req_x_pos = -1;
319 static int hf_vnc_update_req_y_pos = -1;
320 static int hf_vnc_update_req_width = -1;
321 static int hf_vnc_update_req_height = -1;
323 /* Client Set Encodings */
324 static int hf_vnc_client_set_encodings_encoding_type = -1;
326 /* Client Cut Text */
327 static int hf_vnc_client_cut_text_len = -1;
328 static int hf_vnc_client_cut_text = -1;
330 /********** Server Message Types **********/
332 static int hf_vnc_server_message_type = -1; /* Subtree */
334 /* Server Framebuffer Update */
335 static int hf_vnc_fb_update_x_pos = -1;
336 static int hf_vnc_fb_update_y_pos = -1;
337 static int hf_vnc_fb_update_width = -1;
338 static int hf_vnc_fb_update_height = -1;
339 static int hf_vnc_fb_update_encoding_type = -1;
342 static int hf_vnc_raw_pixel_data = -1;
344 /* CopyRect Encoding */
345 static int hf_vnc_copyrect_src_x_pos = -1;
346 static int hf_vnc_copyrect_src_y_pos = -1;
349 static int hf_vnc_rre_num_subrects = -1;
350 static int hf_vnc_rre_bg_pixel = -1;
352 static int hf_vnc_rre_subrect_pixel = -1;
353 static int hf_vnc_rre_subrect_x_pos = -1;
354 static int hf_vnc_rre_subrect_y_pos = -1;
355 static int hf_vnc_rre_subrect_width = -1;
356 static int hf_vnc_rre_subrect_height = -1;
358 /* Hextile Encoding */
359 static int hf_vnc_hextile_subencoding_mask = -1;
360 static int hf_vnc_hextile_raw = -1;
361 static int hf_vnc_hextile_raw_value = -1;
362 static int hf_vnc_hextile_bg = -1;
363 static int hf_vnc_hextile_bg_value = -1;
364 static int hf_vnc_hextile_fg = -1;
365 static int hf_vnc_hextile_fg_value = -1;
366 static int hf_vnc_hextile_anysubrects = -1;
367 static int hf_vnc_hextile_num_subrects = -1;
368 static int hf_vnc_hextile_subrectscolored = -1;
369 static int hf_vnc_hextile_subrect_pixel_value = -1;
370 static int hf_vnc_hextile_subrect_x_pos = -1;
371 static int hf_vnc_hextile_subrect_y_pos = -1;
372 static int hf_vnc_hextile_subrect_width = -1;
373 static int hf_vnc_hextile_subrect_height = -1;
376 static int hf_vnc_zrle_len = -1;
377 static int hf_vnc_zrle_subencoding = -1;
378 static int hf_vnc_zrle_rle = -1;
379 static int hf_vnc_zrle_palette_size = -1;
380 static int hf_vnc_zrle_data = -1;
381 static int hf_vnc_zrle_raw = -1;
382 static int hf_vnc_zrle_palette = -1;
384 /* Cursor Encoding */
385 static int hf_vnc_cursor_encoding_pixels = -1;
386 static int hf_vnc_cursor_encoding_bitmask = -1;
388 /* Server Set Colormap Entries */
389 static int hf_vnc_colormap_first_color = -1;
390 static int hf_vnc_colormap_num_colors = -1;
391 static int hf_vnc_colormap_red = -1;
392 static int hf_vnc_colormap_green = -1;
393 static int hf_vnc_colormap_blue = -1;
395 /* Server Cut Text */
396 static int hf_vnc_server_cut_text_len = -1;
397 static int hf_vnc_server_cut_text = -1;
399 /********** End of Server Message Types **********/
401 static gboolean vnc_preference_desegment = TRUE;
403 /* Initialize the subtree pointers */
404 static gint ett_vnc = -1;
405 static gint ett_vnc_client_message_type = -1;
406 static gint ett_vnc_server_message_type = -1;
407 static gint ett_vnc_rect = -1;
408 static gint ett_vnc_encoding_type = -1;
409 static gint ett_vnc_rre_subrect = -1;
410 static gint ett_vnc_hextile_subencoding_mask = -1;
411 static gint ett_vnc_hextile_num_subrects = -1;
412 static gint ett_vnc_hextile_subrect = -1;
413 static gint ett_vnc_zrle_subencoding = -1;
414 static gint ett_vnc_colormap_num_groups = -1;
415 static gint ett_vnc_colormap_color_group = -1;
417 static dissector_handle_t vnc_handle;
419 guint8 vnc_bytes_per_pixel; /* Global so it keeps its value between packets */
422 /* Code to dissect the packets */
424 dissect_vnc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
429 /* Set up structures needed to add the protocol subtree and manage it */
431 proto_tree *vnc_tree=NULL;
433 conversation_t *conversation;
434 vnc_conversation_t *per_conversation_info;
436 conversation = find_conversation(pinfo->fd->num, &pinfo->src,
437 &pinfo->dst, pinfo->ptype,
438 pinfo->srcport, pinfo->destport, 0);
440 if(!conversation) { /* Conversation does not exist yet - create it */
441 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
442 &pinfo->dst, pinfo->ptype,
447 /* Retrieve information from conversation, or add it if it isn't
449 per_conversation_info = conversation_get_proto_data(conversation,
451 if(!per_conversation_info) {
452 per_conversation_info = se_alloc(sizeof(vnc_conversation_t));
454 per_conversation_info->vnc_next_state = SERVER_VERSION;
456 conversation_add_proto_data(conversation, proto_vnc,
457 per_conversation_info);
461 /* Make entries in Protocol column and Info column on summary display */
462 if (check_col(pinfo->cinfo, COL_PROTOCOL))
463 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VNC");
465 /* First, clear the info column */
466 if(check_col(pinfo->cinfo, COL_INFO))
467 col_clear(pinfo->cinfo, COL_INFO);
469 /* create display subtree for the protocol */
471 ti = proto_tree_add_item(tree, proto_vnc, tvb, 0, -1, FALSE);
472 vnc_tree = proto_item_add_subtree(ti, ett_vnc);
475 offset = 0; /* Start at the beginning of the VNC protocol data */
477 /* Dissect any remaining session startup messages */
478 ret = vnc_startup_messages(tvb, pinfo, offset, vnc_tree,
479 per_conversation_info);
481 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
485 vnc_client_to_server(tvb, pinfo, &offset, vnc_tree);
487 vnc_server_to_client(tvb, pinfo, &offset, vnc_tree);
491 /* Returns true if additional session startup messages follow */
493 vnc_startup_messages(tvbuff_t *tvb, packet_info *pinfo, gint offset,
494 proto_tree *tree, vnc_conversation_t
495 *per_conversation_info)
497 guint8 num_security_types;
499 guint32 desktop_name_len, auth_result, text_len;
500 vnc_packet_t *per_packet_info;
503 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
505 if(!per_packet_info) {
506 per_packet_info = se_alloc(sizeof(vnc_packet_t));
508 per_packet_info->state = per_conversation_info->vnc_next_state;
510 p_add_proto_data(pinfo->fd, proto_vnc, per_packet_info);
513 /* Packet dissection follows */
514 switch(per_packet_info->state) {
516 case SERVER_VERSION :
517 proto_tree_add_item(tree, hf_vnc_server_proto_ver, tvb, 4,
520 per_conversation_info->server_proto_ver =
521 g_strtod((char *)tvb_get_ephemeral_string(tvb, 4, 7),
524 if (check_col(pinfo->cinfo, COL_INFO))
525 col_add_fstr(pinfo->cinfo, COL_INFO,
526 "Server protocol version: %s",
527 tvb_format_text(tvb, 4, 7));
529 per_conversation_info->vnc_next_state = CLIENT_VERSION;
532 case CLIENT_VERSION :
533 proto_tree_add_item(tree, hf_vnc_client_proto_ver, tvb,
536 per_conversation_info->client_proto_ver =
537 g_strtod((char *)tvb_get_ephemeral_string(tvb, 4, 7),
540 if (check_col(pinfo->cinfo, COL_INFO))
541 col_add_fstr(pinfo->cinfo, COL_INFO,
542 "Client protocol version: %s",
543 tvb_format_text(tvb, 4, 7));
545 per_conversation_info->vnc_next_state = SECURITY;
549 if (check_col(pinfo->cinfo, COL_INFO))
550 col_set_str(pinfo->cinfo, COL_INFO,
551 "Security types supported");
553 /* We're checking against the client protocol version because
554 * the client is the final decider on which version to use
555 * after the server offers the highest version it supports. */
557 if(per_conversation_info->client_proto_ver >= 3.007) {
558 proto_tree_add_item(tree,
559 hf_vnc_num_security_types, tvb,
561 num_security_types = tvb_get_guint8(tvb, offset);
563 for(offset = 1; offset <= num_security_types; offset++){
564 proto_tree_add_item(tree,
565 hf_vnc_security_type, tvb,
570 /* Version < 3.007: The server decides the
571 * authentication type for us to use */
572 proto_tree_add_item(tree,
573 hf_vnc_server_security_type, tvb,
577 per_conversation_info->vnc_next_state = SECURITY_TYPES;
580 case SECURITY_TYPES :
581 if (check_col(pinfo->cinfo, COL_INFO))
582 col_set_str(pinfo->cinfo, COL_INFO,
583 "Authentication type selected by client");
585 proto_tree_add_item(tree, hf_vnc_client_security_type, tvb,
587 per_conversation_info->security_type_selected =
588 tvb_get_guint8(tvb, offset);
590 switch(per_conversation_info->security_type_selected) {
593 if(per_conversation_info->client_proto_ver >= 3.008)
594 per_conversation_info->vnc_next_state =
597 per_conversation_info->vnc_next_state =
603 per_conversation_info->vnc_next_state =
604 VNC_AUTHENTICATION_CHALLENGE;
607 case 16 : /* Tight */
608 per_conversation_info->vnc_next_state =
609 TIGHT_UNKNOWN_PACKET1;
612 /* Security type not supported by this dissector */
618 case TIGHT_UNKNOWN_PACKET1 :
619 if (check_col(pinfo->cinfo, COL_INFO))
620 col_set_str(pinfo->cinfo, COL_INFO,
621 "Unknown packet (TightVNC)");
623 proto_tree_add_text(tree, tvb, offset, -1,
624 "Unknown packet (TightVNC)");
626 per_conversation_info->vnc_next_state =
627 TIGHT_UNKNOWN_PACKET2;
631 case TIGHT_UNKNOWN_PACKET2 :
632 if (check_col(pinfo->cinfo, COL_INFO))
633 col_set_str(pinfo->cinfo, COL_INFO,
634 "Unknown packet (TightVNC)");
636 proto_tree_add_text(tree, tvb, offset, -1,
637 "Unknown packet (TightVNC)");
639 per_conversation_info->vnc_next_state =
640 TIGHT_AUTH_TYPE_AND_VENDOR_CODE;
644 case TIGHT_AUTH_TYPE_AND_VENDOR_CODE :
645 if (check_col(pinfo->cinfo, COL_INFO))
646 col_set_str(pinfo->cinfo, COL_INFO,
647 "Authentication type / vendor code");
649 proto_tree_add_item(tree, hf_vnc_server_security_type, tvb,
654 /* Display vendor code */
655 vendor = tvb_get_ephemeral_string(tvb, offset, 4);
657 ti = proto_tree_add_string(tree, hf_vnc_vendor_code, tvb,
660 if(g_ascii_strcasecmp(vendor, "STDV") == 0)
661 proto_item_append_text(ti, " (Standard VNC vendor)");
663 else if(g_ascii_strcasecmp(vendor, "TRDV") == 0)
664 proto_item_append_text(ti, " (Tridia VNC vendor)");
666 else if(g_ascii_strcasecmp(vendor, "TGHT") == 0)
667 proto_item_append_text(ti, " (Tight VNC vendor)");
671 /* Display authentication method string */
672 proto_tree_add_item(tree, hf_vnc_security_type_string, tvb,
675 per_conversation_info->vnc_next_state =
676 TIGHT_UNKNOWN_PACKET3;
680 case TIGHT_UNKNOWN_PACKET3 :
681 if (check_col(pinfo->cinfo, COL_INFO))
682 col_set_str(pinfo->cinfo, COL_INFO,
683 "Unknown packet (TightVNC)");
685 proto_tree_add_text(tree, tvb, offset, -1,
686 "Unknown packet (TightVNC)");
688 per_conversation_info->vnc_next_state =
689 VNC_AUTHENTICATION_CHALLENGE;
693 case VNC_AUTHENTICATION_CHALLENGE :
694 if (check_col(pinfo->cinfo, COL_INFO))
695 col_set_str(pinfo->cinfo, COL_INFO,
696 "Authentication challenge from server");
698 proto_tree_add_item(tree, hf_vnc_auth_challenge, tvb,
701 per_conversation_info->vnc_next_state =
702 VNC_AUTHENTICATION_RESPONSE;
705 case VNC_AUTHENTICATION_RESPONSE :
706 if (check_col(pinfo->cinfo, COL_INFO))
707 col_set_str(pinfo->cinfo, COL_INFO,
708 "Authentication response from client");
710 proto_tree_add_item(tree, hf_vnc_auth_response, tvb,
713 per_conversation_info->vnc_next_state = SECURITY_RESULT;
716 case SECURITY_RESULT :
717 if (check_col(pinfo->cinfo, COL_INFO))
718 col_set_str(pinfo->cinfo, COL_INFO,
719 "Authentication result");
721 proto_tree_add_item(tree, hf_vnc_auth_result, tvb, offset,
723 auth_result = tvb_get_ntohl(tvb, offset);
726 switch(auth_result) {
729 per_conversation_info->vnc_next_state = CLIENT_INIT;
732 case 1 : /* Failed */
733 if(per_conversation_info->client_proto_ver >= 3.008) {
734 text_len = tvb_get_ntohl(tvb, offset);
735 proto_tree_add_text(tree, tvb, offset, 4, "Length of authentication error: %d", text_len);
738 proto_tree_add_item(tree, hf_vnc_auth_error, tvb,
739 offset, text_len, FALSE);
743 return TRUE; /* All versions: Do not continue
744 processing VNC packets as connection
745 will be closed after this packet. */
753 if (check_col(pinfo->cinfo, COL_INFO))
754 col_set_str(pinfo->cinfo, COL_INFO,
755 "Share desktop flag");
757 proto_tree_add_item(tree, hf_vnc_share_desktop_flag, tvb,
760 per_conversation_info->vnc_next_state = SERVER_INIT;
765 if (check_col(pinfo->cinfo, COL_INFO))
766 col_set_str(pinfo->cinfo, COL_INFO,
767 "Server framebuffer parameters");
769 proto_tree_add_item(tree, hf_vnc_width, tvb, offset, 2,
773 proto_tree_add_item(tree, hf_vnc_height, tvb, offset, 2,
777 proto_tree_add_item(tree, hf_vnc_server_bits_per_pixel,
778 tvb, offset, 1, FALSE);
779 vnc_bytes_per_pixel = tvb_get_guint8(tvb, offset)/8;
780 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
783 proto_tree_add_item(tree, hf_vnc_server_depth, tvb, offset,
787 proto_tree_add_item(tree, hf_vnc_server_big_endian_flag,
788 tvb, offset, 1, FALSE);
791 proto_tree_add_item(tree, hf_vnc_server_true_color_flag,
792 tvb, offset, 1, FALSE);
795 proto_tree_add_item(tree, hf_vnc_server_red_max,
796 tvb, offset, 2, FALSE);
799 proto_tree_add_item(tree, hf_vnc_server_green_max,
800 tvb, offset, 2, FALSE);
803 proto_tree_add_item(tree, hf_vnc_server_blue_max,
804 tvb, offset, 2, FALSE);
807 proto_tree_add_item(tree, hf_vnc_server_red_shift,
808 tvb, offset, 1, FALSE);
811 proto_tree_add_item(tree, hf_vnc_server_green_shift,
812 tvb, offset, 1, FALSE);
815 proto_tree_add_item(tree, hf_vnc_server_blue_shift,
816 tvb, offset, 1, FALSE);
819 proto_tree_add_item(tree, hf_vnc_padding,
820 tvb, offset, 3, FALSE);
821 offset += 3; /* Skip over 3 bytes of padding */
823 if(tvb_length_remaining(tvb, offset) > 0) {
824 /* Sometimes the desktop name & length is skipped */
825 proto_tree_add_item(tree, hf_vnc_desktop_name_len,
826 tvb, offset, 4, FALSE);
827 desktop_name_len = tvb_get_ntohl(tvb, offset);
830 proto_tree_add_item(tree, hf_vnc_desktop_name,
831 tvb, offset, desktop_name_len,
835 if(per_conversation_info->security_type_selected == TIGHT)
836 per_conversation_info->vnc_next_state =
837 TIGHT_INTERACTION_CAPS;
839 per_conversation_info->vnc_next_state = NORMAL_TRAFFIC;
842 case TIGHT_INTERACTION_CAPS :
843 if (check_col(pinfo->cinfo, COL_INFO))
844 col_set_str(pinfo->cinfo, COL_INFO,
845 "Interaction Capabilities");
847 proto_tree_add_item(tree, hf_vnc_num_server_message_types,
848 tvb, offset, 2, FALSE);
852 proto_tree_add_item(tree, hf_vnc_num_client_message_types,
853 tvb, offset, 2, FALSE);
857 proto_tree_add_item(tree, hf_vnc_num_encoding_types,
858 tvb, offset, 2, FALSE);
862 proto_tree_add_item(tree, hf_vnc_padding, tvb, offset, 2,
865 /* XXX - Display lists of server and client messages, the
866 * number of each in the packet is found above. */
868 per_conversation_info->vnc_next_state = TIGHT_UNKNOWN_PACKET4;
872 case TIGHT_UNKNOWN_PACKET4 :
873 if (check_col(pinfo->cinfo, COL_INFO))
874 col_set_str(pinfo->cinfo, COL_INFO,
875 "Unknown packet (TightVNC)");
877 proto_tree_add_text(tree, tvb, offset, -1,
878 "Unknown packet (TightVNC)");
880 per_conversation_info->vnc_next_state = NORMAL_TRAFFIC;
884 case NORMAL_TRAFFIC :
893 vnc_client_to_server(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
899 proto_tree *vnc_client_message_type_tree;
901 message_type = tvb_get_guint8(tvb, *offset);
903 ti = proto_tree_add_item(tree, hf_vnc_client_message_type, tvb,
906 vnc_client_message_type_tree =
907 proto_item_add_subtree(ti, ett_vnc_client_message_type);
911 switch(message_type) {
914 vnc_client_set_pixel_format(tvb, pinfo, offset,
915 vnc_client_message_type_tree);
919 vnc_client_set_encodings(tvb, pinfo, offset,
920 vnc_client_message_type_tree);
924 vnc_client_framebuffer_update_request(tvb, pinfo, offset,
925 vnc_client_message_type_tree);
929 vnc_client_key_event(tvb, pinfo, offset,
930 vnc_client_message_type_tree);
934 vnc_client_pointer_event(tvb, pinfo, offset,
935 vnc_client_message_type_tree);
939 vnc_client_cut_text(tvb, pinfo, offset,
940 vnc_client_message_type_tree);
944 if (check_col(pinfo->cinfo, COL_INFO))
945 col_append_fstr(pinfo->cinfo, COL_INFO,
946 "Unknown client message type (%u)",
953 vnc_server_to_client(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
957 gint bytes_needed = 0, length_remaining;
960 proto_tree *vnc_server_message_type_tree;
962 message_type = tvb_get_guint8(tvb, *offset);
964 ti = proto_tree_add_item(tree, hf_vnc_server_message_type, tvb,
966 vnc_server_message_type_tree =
967 proto_item_add_subtree(ti, ett_vnc_server_message_type);
971 switch(message_type) {
975 vnc_server_framebuffer_update(tvb, pinfo, offset,
976 vnc_server_message_type_tree);
980 bytes_needed = vnc_server_set_colormap_entries(tvb, pinfo, offset, vnc_server_message_type_tree);
984 vnc_server_ring_bell(tvb, pinfo, offset,
985 vnc_server_message_type_tree);
989 bytes_needed = vnc_server_cut_text(tvb, pinfo, offset,
990 vnc_server_message_type_tree);
994 if (check_col(pinfo->cinfo, COL_INFO))
995 col_append_str(pinfo->cinfo, COL_INFO,
996 "Unknown server message type");
1000 if(bytes_needed > 0 && vnc_preference_desegment &&
1001 pinfo->can_desegment) {
1002 length_remaining = tvb_length_remaining(tvb, *offset);
1004 pinfo->desegment_offset = 0;
1005 pinfo->desegment_len = tvb_length(tvb) + bytes_needed -
1013 vnc_client_set_pixel_format(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1016 if (check_col(pinfo->cinfo, COL_INFO))
1017 col_set_str(pinfo->cinfo, COL_INFO, "Client set pixel format");
1019 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset,
1021 *offset += 3; /* Skip over 3 bytes of padding */
1023 proto_tree_add_item(tree, hf_vnc_client_bits_per_pixel, tvb, *offset,
1025 vnc_bytes_per_pixel = tvb_get_guint8(tvb, *offset)/8;
1026 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
1029 proto_tree_add_item(tree, hf_vnc_client_depth, tvb, *offset,
1033 proto_tree_add_item(tree, hf_vnc_client_big_endian_flag, tvb, *offset,
1037 proto_tree_add_item(tree, hf_vnc_client_true_color_flag, tvb, *offset,
1041 proto_tree_add_item(tree, hf_vnc_client_red_max, tvb, *offset,
1045 proto_tree_add_item(tree, hf_vnc_client_green_max, tvb, *offset,
1049 proto_tree_add_item(tree, hf_vnc_client_blue_max, tvb, *offset,
1053 proto_tree_add_item(tree, hf_vnc_client_red_shift, tvb, *offset,
1057 proto_tree_add_item(tree, hf_vnc_client_green_shift, tvb, *offset,
1061 proto_tree_add_item(tree, hf_vnc_client_blue_shift, tvb, *offset,
1065 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset,
1067 *offset += 3; /* Skip over 3 bytes of padding */
1072 vnc_client_set_encodings(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1075 guint16 number_of_encodings;
1078 if (check_col(pinfo->cinfo, COL_INFO))
1079 col_set_str(pinfo->cinfo, COL_INFO, "Client set encodings");
1081 proto_tree_add_item(tree, hf_vnc_padding,
1082 tvb, *offset, 1, FALSE);
1083 *offset += 1; /* Skip over 1 byte of padding */
1085 number_of_encodings = tvb_get_ntohs(tvb, *offset);
1087 proto_tree_add_text(tree, tvb, *offset, 2,
1088 "Number of encodings: %d", number_of_encodings);
1091 for(counter = 1; counter <= number_of_encodings; counter++) {
1092 proto_tree_add_item(tree,
1093 hf_vnc_client_set_encodings_encoding_type,
1094 tvb, *offset, 4, FALSE);
1101 vnc_client_framebuffer_update_request(tvbuff_t *tvb, packet_info *pinfo,
1102 gint *offset, proto_tree *tree)
1104 if (check_col(pinfo->cinfo, COL_INFO))
1105 col_set_str(pinfo->cinfo, COL_INFO,
1106 "Client framebuffer update request");
1108 proto_tree_add_item(tree, hf_vnc_update_req_incremental,
1109 tvb, *offset, 1, FALSE);
1112 proto_tree_add_item(tree, hf_vnc_update_req_x_pos,
1113 tvb, *offset, 2, FALSE);
1116 proto_tree_add_item(tree, hf_vnc_update_req_y_pos,
1117 tvb, *offset, 2, FALSE);
1120 proto_tree_add_item(tree, hf_vnc_update_req_width, tvb,
1124 proto_tree_add_item(tree, hf_vnc_update_req_height, tvb,
1131 vnc_client_key_event(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1134 if (check_col(pinfo->cinfo, COL_INFO))
1135 col_set_str(pinfo->cinfo, COL_INFO, "Client key event");
1137 proto_tree_add_item(tree, hf_vnc_key_down, tvb, *offset, 1, FALSE);
1140 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 2, FALSE);
1141 *offset += 2; /* Skip over 2 bytes of padding */
1143 proto_tree_add_item(tree, hf_vnc_key, tvb, *offset, 4, FALSE);
1149 vnc_client_pointer_event(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1152 if (check_col(pinfo->cinfo, COL_INFO))
1153 col_set_str(pinfo->cinfo, COL_INFO, "Client pointer event");
1155 proto_tree_add_item(tree, hf_vnc_button_1_pos, tvb, *offset, 1, FALSE);
1156 proto_tree_add_item(tree, hf_vnc_button_2_pos, tvb, *offset, 1, FALSE);
1157 proto_tree_add_item(tree, hf_vnc_button_3_pos, tvb, *offset, 1, FALSE);
1158 proto_tree_add_item(tree, hf_vnc_button_4_pos, tvb, *offset, 1, FALSE);
1159 proto_tree_add_item(tree, hf_vnc_button_5_pos, tvb, *offset, 1, FALSE);
1160 proto_tree_add_item(tree, hf_vnc_button_6_pos, tvb, *offset, 1, FALSE);
1161 proto_tree_add_item(tree, hf_vnc_button_7_pos, tvb, *offset, 1, FALSE);
1162 proto_tree_add_item(tree, hf_vnc_button_8_pos, tvb, *offset, 1, FALSE);
1165 proto_tree_add_item(tree, hf_vnc_pointer_x_pos, tvb, *offset, 2, FALSE);
1168 proto_tree_add_item(tree, hf_vnc_pointer_y_pos, tvb, *offset, 2, FALSE);
1174 vnc_client_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1179 if (check_col(pinfo->cinfo, COL_INFO))
1180 col_set_str(pinfo->cinfo, COL_INFO, "Client cut text");
1182 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 3, FALSE);
1183 *offset += 3; /* Skip over 3 bytes of padding */
1185 text_len = tvb_get_ntohl(tvb, *offset);
1186 proto_tree_add_item(tree, hf_vnc_client_cut_text_len, tvb, *offset, 4,
1190 proto_tree_add_item(tree, hf_vnc_client_cut_text, tvb, *offset,
1192 *offset += text_len;
1198 vnc_server_framebuffer_update(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1201 guint16 num_rects, i, width, height;
1202 guint bytes_needed = 0;
1203 gint32 encoding_type;
1205 proto_tree *vnc_rect_tree, *vnc_encoding_type_tree;
1207 if (check_col(pinfo->cinfo, COL_INFO))
1208 col_set_str(pinfo->cinfo, COL_INFO,
1209 "Server framebuffer update");
1211 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 1, FALSE);
1214 num_rects = tvb_get_ntohs(tvb, *offset);
1215 proto_tree_add_text(tree, tvb, *offset, 2, "Number of rectangles: %d",
1219 for(i = 1; i <= num_rects; i++) {
1221 VNC_BYTES_NEEDED(12);
1223 ti = proto_tree_add_text(tree, tvb, *offset, 12,
1224 "Rectangle #%d", i);
1227 proto_item_add_subtree(ti, ett_vnc_rect);
1229 proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_x_pos,
1230 tvb, *offset, 2, FALSE);
1233 proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_y_pos,
1234 tvb, *offset, 2, FALSE);
1237 proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_width,
1238 tvb, *offset, 2, FALSE);
1239 width = tvb_get_ntohs(tvb, *offset);
1242 proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_height,
1243 tvb, *offset, 2, FALSE);
1244 height = tvb_get_ntohs(tvb, *offset);
1247 ti = proto_tree_add_item(vnc_rect_tree,
1248 hf_vnc_fb_update_encoding_type,
1249 tvb, *offset, 4, FALSE);
1251 vnc_encoding_type_tree =
1252 proto_item_add_subtree(ti, ett_vnc_encoding_type);
1254 encoding_type = tvb_get_ntohl(tvb, *offset);
1257 switch(encoding_type) {
1260 bytes_needed = vnc_raw_encoding(tvb, pinfo, offset,
1261 vnc_encoding_type_tree,
1267 vnc_copyrect_encoding(tvb, pinfo, offset,
1268 vnc_encoding_type_tree,
1274 vnc_rre_encoding(tvb, pinfo, offset,
1275 vnc_encoding_type_tree,
1281 vnc_hextile_encoding(tvb, pinfo, offset,
1282 vnc_encoding_type_tree,
1288 vnc_zrle_encoding(tvb, pinfo, offset,
1289 vnc_encoding_type_tree,
1295 vnc_cursor_encoding(tvb, pinfo, offset,
1296 vnc_encoding_type_tree,
1300 case -223 : /* DesktopSize */
1302 /* There is no payload for this message type */
1309 /* Check if the routines above requested more bytes to
1310 * be desegmented. */
1311 if(bytes_needed > 0)
1312 return bytes_needed;
1320 vnc_raw_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1321 proto_tree *tree, guint16 width, guint16 height)
1323 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1326 length = width * height * bytes_per_pixel;
1327 VNC_BYTES_NEEDED(length);
1329 proto_tree_add_item(tree, hf_vnc_raw_pixel_data, tvb, *offset,
1333 return 0; /* bytes_needed */
1338 vnc_copyrect_encoding(tvbuff_t *tvb, packet_info *pinfo _U_, gint *offset,
1339 proto_tree *tree, guint16 width _U_, guint16 height _U_)
1341 proto_tree_add_item(tree, hf_vnc_copyrect_src_x_pos, tvb, *offset,
1345 proto_tree_add_item(tree, hf_vnc_copyrect_src_y_pos, tvb, *offset,
1349 return 0; /* bytes_needed */
1354 vnc_rre_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1355 proto_tree *tree, guint16 width _U_, guint16 height _U_)
1357 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1358 guint32 num_subrects, i;
1361 proto_tree *subrect_tree;
1363 VNC_BYTES_NEEDED(4);
1364 proto_tree_add_item(tree, hf_vnc_rre_num_subrects, tvb, *offset,
1366 num_subrects = tvb_get_ntohl(tvb, *offset);
1369 VNC_BYTES_NEEDED(bytes_per_pixel);
1370 proto_tree_add_item(tree, hf_vnc_rre_bg_pixel, tvb, *offset,
1371 bytes_per_pixel, FALSE);
1372 *offset += bytes_per_pixel;
1374 for(i = 1; i <= num_subrects; i++) {
1375 bytes_needed = bytes_per_pixel + 8;
1376 VNC_BYTES_NEEDED(bytes_needed);
1378 ti = proto_tree_add_text(tree, tvb, *offset, bytes_per_pixel +
1379 8, "Subrectangle #%d", i);
1381 proto_item_add_subtree(ti, ett_vnc_rre_subrect);
1383 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_pixel,
1384 tvb, *offset, bytes_per_pixel, FALSE);
1385 *offset += bytes_per_pixel;
1387 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_x_pos,
1388 tvb, *offset, 2, FALSE);
1391 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_y_pos,
1392 tvb, *offset, 2, FALSE);
1395 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_width,
1396 tvb, *offset, 2, FALSE);
1399 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_height,
1400 tvb, *offset, 2, FALSE);
1404 return 0; /* bytes_needed */
1409 vnc_hextile_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1410 proto_tree *tree, guint16 width, guint16 height)
1412 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1413 guint8 i, subencoding_mask, num_subrects, subrect_len;
1415 proto_tree *subencoding_mask_tree, *subrect_tree, *num_subrects_tree;
1418 VNC_BYTES_NEEDED(1);
1419 ti = proto_tree_add_item(tree, hf_vnc_hextile_subencoding_mask, tvb,
1421 subencoding_mask = tvb_get_guint8(tvb, *offset);
1423 subencoding_mask_tree =
1424 proto_item_add_subtree(ti, ett_vnc_hextile_subencoding_mask);
1426 proto_tree_add_item(subencoding_mask_tree,
1427 hf_vnc_hextile_raw, tvb, *offset, 1,
1429 proto_tree_add_item(subencoding_mask_tree,
1430 hf_vnc_hextile_bg, tvb, *offset, 1,
1432 proto_tree_add_item(subencoding_mask_tree,
1433 hf_vnc_hextile_fg, tvb, *offset, 1,
1435 proto_tree_add_item(subencoding_mask_tree,
1436 hf_vnc_hextile_anysubrects, tvb, *offset, 1,
1438 proto_tree_add_item(subencoding_mask_tree,
1439 hf_vnc_hextile_subrectscolored, tvb, *offset, 1,
1443 if(subencoding_mask & 0x1) { /* Raw */
1444 length = width * height * bytes_per_pixel;
1446 VNC_BYTES_NEEDED(length);
1448 proto_tree_add_item(tree, hf_vnc_hextile_raw_value, tvb,
1449 *offset, length, FALSE);
1452 if(subencoding_mask & 0x2) { /* Background Specified */
1453 proto_tree_add_item(tree, hf_vnc_hextile_bg_value,
1454 tvb, *offset, bytes_per_pixel,
1456 *offset += bytes_per_pixel;
1459 if(subencoding_mask & 0x4) { /* Foreground Specified */
1460 proto_tree_add_item(tree, hf_vnc_hextile_fg_value,
1461 tvb, *offset, bytes_per_pixel,
1463 *offset += bytes_per_pixel;
1466 if(subencoding_mask & 0x8) { /* Any Subrects */
1467 ti = proto_tree_add_item(tree,
1468 hf_vnc_hextile_num_subrects,
1471 num_subrects = tvb_get_guint8(tvb, *offset);
1475 proto_item_add_subtree(ti, ett_vnc_hextile_num_subrects);
1477 for(i = 1; i <= num_subrects; i++) {
1479 if(subencoding_mask & 0x16)
1480 subrect_len = bytes_per_pixel + 2;
1484 ti = proto_tree_add_text(num_subrects_tree, tvb,
1485 *offset, subrect_len,
1486 "Subrectangle #%d", i);
1489 proto_item_add_subtree(ti, ett_vnc_hextile_subrect);
1491 if(subencoding_mask & 0x16) {
1492 /* Subrects Colored */
1493 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_pixel_value, tvb, *offset, bytes_per_pixel, FALSE);
1495 *offset += bytes_per_pixel;
1498 proto_tree_add_item(subrect_tree,
1499 hf_vnc_hextile_subrect_x_pos, tvb, *offset, 1, FALSE);
1501 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_y_pos, tvb, *offset, 1, FALSE);
1505 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_width, tvb, *offset, 1, FALSE);
1507 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_height, tvb, *offset, 1, FALSE);
1514 return 0; /* bytes_needed */
1519 vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1520 proto_tree *tree, guint16 width, guint16 height)
1524 guint8 palette_size;
1525 guint8 bytes_per_cpixel = vnc_get_bytes_per_pixel(pinfo);
1526 gint uncomp_offset = 0;
1528 gint subencoding_type;
1529 tvbuff_t *uncomp_tvb = NULL;
1530 proto_tree *zrle_subencoding_tree;
1534 VNC_BYTES_NEEDED(4);
1535 proto_tree_add_item(tree, hf_vnc_zrle_len, tvb, *offset,
1537 data_len = tvb_get_ntohl(tvb, *offset);
1541 VNC_BYTES_NEEDED(data_len);
1543 proto_tree_add_item(tree, hf_vnc_zrle_data, tvb, *offset,
1547 uncomp_tvb = tvb_uncompress(tvb, *offset, data_len);
1549 if(uncomp_tvb != NULL) {
1550 tvb_set_child_real_data_tvbuff(tvb, uncomp_tvb);
1551 add_new_data_source(pinfo, uncomp_tvb,
1552 "Uncompressed ZRLE data");
1554 ti = proto_tree_add_item(tree, hf_vnc_zrle_subencoding,
1555 uncomp_tvb, uncomp_offset, 1, FALSE);
1556 zrle_subencoding_tree =
1557 proto_item_add_subtree(ti, ett_vnc_zrle_subencoding);
1559 proto_tree_add_item(zrle_subencoding_tree, hf_vnc_zrle_rle,
1560 uncomp_tvb, uncomp_offset, 1, FALSE);
1562 proto_tree_add_item(zrle_subencoding_tree,
1563 hf_vnc_zrle_palette_size, uncomp_tvb,
1564 uncomp_offset, 1, FALSE);
1566 subencoding_type = tvb_get_guint8(uncomp_tvb, uncomp_offset);
1567 palette_size = subencoding_type & 0x7F;
1571 if(subencoding_type == 0) { /* Raw */
1572 length = width * height * bytes_per_cpixel;
1573 VNC_BYTES_NEEDED(length);
1575 /* XXX - not working yet! */
1577 proto_tree_add_item(zrle_subencoding_tree,
1578 hf_vnc_zrle_raw, uncomp_tvb,
1579 uncomp_offset, length, FALSE);
1581 } else if(subencoding_type >= 130 && subencoding_type <= 255) {
1582 length = palette_size * bytes_per_cpixel;
1583 VNC_BYTES_NEEDED(length);
1585 proto_tree_add_item(zrle_subencoding_tree,
1586 hf_vnc_zrle_palette, uncomp_tvb,
1587 uncomp_offset, length, FALSE);
1589 /* XXX - Not complete! */
1593 proto_tree_add_text(tree, tvb, *offset, data_len,
1594 "Decompression of ZRLE data failed");
1596 #endif /* HAVE_LIBZ */
1598 *offset += data_len;
1600 return 0; /* bytes_needed */
1605 vnc_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1606 proto_tree *tree, guint16 width, guint16 height)
1608 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1611 length = width * height * bytes_per_pixel;
1612 proto_tree_add_item(tree, hf_vnc_cursor_encoding_pixels, tvb, *offset,
1616 length = (guint) (floor((width + 7)/8) * height);
1617 proto_tree_add_item(tree, hf_vnc_cursor_encoding_bitmask, tvb, *offset,
1621 return 0; /* bytes_needed */
1626 vnc_server_set_colormap_entries(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1629 guint16 number_of_colors;
1630 guint counter, bytes_needed;
1632 proto_tree *vnc_colormap_num_groups, *vnc_colormap_color_group;
1634 if (check_col(pinfo->cinfo, COL_INFO))
1635 col_set_str(pinfo->cinfo, COL_INFO,
1636 "Server set colormap entries");
1638 number_of_colors = tvb_get_ntohs(tvb, 4);
1640 bytes_needed = (number_of_colors * 6) + 6;
1641 VNC_BYTES_NEEDED(bytes_needed);
1643 ti = proto_tree_add_item(tree, hf_vnc_server_message_type, tvb,
1645 tree = proto_item_add_subtree(ti, ett_vnc_server_message_type);
1648 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 1, FALSE);
1649 *offset += 1; /* Skip over 1 byte of padding */
1651 proto_tree_add_item(tree,
1652 hf_vnc_colormap_first_color,
1653 tvb, *offset, 2, FALSE);
1656 ti = proto_tree_add_item(tree, hf_vnc_colormap_num_colors, tvb,
1658 vnc_colormap_num_groups =
1659 proto_item_add_subtree(ti, ett_vnc_colormap_num_groups);
1663 for(counter = 1; counter <= number_of_colors; counter++) {
1664 ti = proto_tree_add_text(vnc_colormap_num_groups, tvb,
1666 "Color group #%d", counter);
1668 vnc_colormap_color_group =
1669 proto_item_add_subtree(ti,
1670 ett_vnc_colormap_color_group);
1672 proto_tree_add_item(vnc_colormap_color_group,
1673 hf_vnc_colormap_red, tvb,
1677 proto_tree_add_item(vnc_colormap_color_group,
1678 hf_vnc_colormap_green, tvb,
1682 proto_tree_add_item(vnc_colormap_color_group,
1683 hf_vnc_colormap_blue, tvb,
1692 vnc_server_ring_bell(tvbuff_t *tvb _U_, packet_info *pinfo, gint *offset _U_,
1693 proto_tree *tree _U_)
1695 if (check_col(pinfo->cinfo, COL_INFO))
1696 col_set_str(pinfo->cinfo, COL_INFO, "Server ring bell on client");
1697 /* This message type has no payload... */
1702 vnc_server_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1707 if (check_col(pinfo->cinfo, COL_INFO))
1708 col_set_str(pinfo->cinfo, COL_INFO,
1711 text_len = tvb_get_ntohl(tvb, *offset);
1712 proto_tree_add_item(tree,
1713 hf_vnc_server_cut_text_len, tvb, *offset, 4,
1717 VNC_BYTES_NEEDED(text_len);
1719 proto_tree_add_item(tree, hf_vnc_server_cut_text, tvb, *offset,
1721 *offset += text_len;
1728 vnc_set_bytes_per_pixel(packet_info *pinfo, guint8 bytes_per_pixel)
1730 vnc_packet_t *per_packet_info;
1732 /* The per_packet_info has already been created by the
1733 * vnc_startup_messages() routine. */
1734 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
1735 per_packet_info->bytes_per_pixel = bytes_per_pixel;
1740 vnc_get_bytes_per_pixel(packet_info *pinfo)
1742 vnc_packet_t *per_packet_info;
1744 /* The per_packet_info has already been created by the
1745 * vnc_startup_messages() routine. */
1746 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
1747 return per_packet_info->bytes_per_pixel;
1751 /* Register the protocol with Wireshark */
1753 proto_register_vnc(void)
1755 module_t *vnc_module; /* To handle our preferences */
1757 /* Setup list of header fields */
1758 static hf_register_info hf[] = {
1760 { "Padding", "vnc.padding",
1761 FT_NONE, BASE_NONE, NULL, 0x0,
1762 "Unused space", HFILL }
1765 { &hf_vnc_server_proto_ver,
1766 { "Server protocol version", "vnc.server_proto_ver",
1767 FT_STRING, BASE_NONE, NULL, 0x0,
1768 "VNC protocol version on server", HFILL }
1770 { &hf_vnc_client_proto_ver,
1771 { "Client protocol version", "vnc.client_proto_ver",
1772 FT_STRING, BASE_NONE, NULL, 0x0,
1773 "VNC protocol version on client", HFILL }
1775 { &hf_vnc_num_security_types,
1776 { "Number of security types", "vnc.num_security_types",
1777 FT_UINT8, BASE_DEC, NULL, 0x0,
1778 "Number of security (authentication) types supported by the server", HFILL }
1780 { &hf_vnc_security_type,
1781 { "Security type", "vnc.security_type",
1782 FT_UINT8, BASE_DEC, VALS(security_types_vs), 0x0,
1783 "Security types offered by the server (VNC versions => 3.007", HFILL }
1785 { &hf_vnc_server_security_type,
1786 { "Security type", "vnc.server_security_type",
1787 FT_UINT32, BASE_DEC, VALS(security_types_vs), 0x0,
1788 "Security type mandated by the server", HFILL }
1790 { &hf_vnc_client_security_type,
1791 { "Security type selected", "vnc.security_type",
1792 FT_UINT8, BASE_DEC, VALS(security_types_vs), 0x0,
1793 "Security type selected by the client", HFILL }
1795 { &hf_vnc_vendor_code,
1796 { "Vendor code", "vnc.vendor_code",
1797 FT_STRING, BASE_NONE, NULL, 0x0,
1798 "Identifies the VNC server software's vendor", HFILL }
1800 { &hf_vnc_security_type_string,
1801 { "Security type string", "vnc.security_type_string",
1802 FT_STRING, BASE_NONE, NULL, 0x0,
1803 "Security type being used", HFILL }
1805 { &hf_vnc_auth_challenge,
1806 { "Authentication challenge", "vnc.auth_challenge",
1807 FT_STRING, BASE_NONE, NULL, 0x0,
1808 "Random authentication challenge from server to client", HFILL }
1810 { &hf_vnc_auth_response,
1811 { "Authentication response", "vnc.auth_response",
1812 FT_STRING, BASE_NONE, NULL, 0x0,
1813 "Client's encrypted response to the server's authentication challenge", HFILL }
1815 { &hf_vnc_auth_result,
1816 { "Authentication result", "vnc.auth_result",
1817 FT_UINT32, BASE_DEC, VALS(auth_result_vs), 0x0,
1818 "Authentication result", HFILL }
1820 { &hf_vnc_auth_error,
1821 { "Authentication error", "vnc.auth_error",
1822 FT_STRING, BASE_NONE, NULL, 0x0,
1823 "Authentication error (present only if the authentication result is fail", HFILL }
1825 { &hf_vnc_share_desktop_flag,
1826 { "Share desktop flag", "vnc.share_desktop_flag",
1827 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x0,
1828 "Client's desire to share the server's desktop with other clients", HFILL }
1831 { "Framebuffer width", "vnc.width",
1832 FT_UINT16, BASE_DEC, NULL, 0x0,
1833 "Width of the framebuffer (screen) in pixels", HFILL }
1836 { "Framebuffer height", "vnc.width",
1837 FT_UINT16, BASE_DEC, NULL, 0x0,
1838 "Height of the framebuffer (screen) in pixels", HFILL }
1840 { &hf_vnc_server_bits_per_pixel,
1841 { "Bits per pixel", "vnc.server_bits_per_pixel",
1842 FT_UINT8, BASE_DEC, NULL, 0x0,
1843 "Number of bits used by server for each pixel value on the wire from the server", HFILL }
1845 { &hf_vnc_server_depth,
1846 { "Depth", "vnc.server_depth",
1847 FT_UINT8, BASE_DEC, NULL, 0x0,
1848 "Number of useful bits in the pixel value on server", HFILL }
1850 { &hf_vnc_server_big_endian_flag,
1851 { "Big endian flag", "vnc.server_big_endian_flag",
1852 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1853 "True if multi-byte pixels are interpreted as big endian by server", HFILL }
1855 { &hf_vnc_server_true_color_flag,
1856 { "True color flag", "vnc.server_true_color_flag",
1857 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1858 "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 }
1860 { &hf_vnc_server_red_max,
1861 { "Red maximum", "vnc.server_red_max",
1862 FT_UINT16, BASE_DEC, NULL, 0x0,
1863 "Maximum red value on server as n: 2^n - 1", HFILL }
1865 { &hf_vnc_server_green_max,
1866 { "Green maximum", "vnc.server_green_max",
1867 FT_UINT16, BASE_DEC, NULL, 0x0,
1868 "Maximum green value on server as n: 2^n - 1", HFILL }
1870 { &hf_vnc_server_blue_max,
1871 { "Blue maximum", "vnc.server_blue_max",
1872 FT_UINT16, BASE_DEC, NULL, 0x0,
1873 "Maximum blue value on server as n: 2^n - 1", HFILL }
1875 { &hf_vnc_server_red_shift,
1876 { "Red shift", "vnc.server_red_shift",
1877 FT_UINT8, BASE_DEC, NULL, 0x0,
1878 "Number of shifts needed to get the red value in a pixel to the least significant bit on the server", HFILL }
1880 { &hf_vnc_server_green_shift,
1881 { "Green shift", "vnc.server_green_shift",
1882 FT_UINT8, BASE_DEC, NULL, 0x0,
1883 "Number of shifts needed to get the green value in a pixel to the least significant bit on the server", HFILL }
1885 { &hf_vnc_server_blue_shift,
1886 { "Blue shift", "vnc.server_blue_shift",
1887 FT_UINT8, BASE_DEC, NULL, 0x0,
1888 "Number of shifts needed to get the blue value in a pixel to the least significant bit on the server", HFILL }
1890 { &hf_vnc_desktop_name_len,
1891 { "Desktop name length", "vnc.desktop_name_len",
1892 FT_UINT32, BASE_DEC, NULL, 0x0,
1893 "Length of desktop name in bytes", HFILL }
1895 { &hf_vnc_desktop_name,
1896 { "Desktop name", "vnc.desktop_name",
1897 FT_STRING, BASE_NONE, NULL, 0x0,
1898 "Name of the VNC desktop on the server", HFILL }
1900 { &hf_vnc_num_server_message_types,
1901 { "Server message types", "vnc.num_server_message_types",
1902 FT_UINT16, BASE_DEC, NULL, 0x0,
1903 "Unknown", HFILL } /* XXX - Needs description */
1905 { &hf_vnc_num_client_message_types,
1906 { "Client message types", "vnc.num_client_message_types",
1907 FT_UINT16, BASE_DEC, NULL, 0x0,
1908 "Unknown", HFILL } /* XXX - Needs description */
1910 { &hf_vnc_num_encoding_types,
1911 { "Encoding types", "vnc.num_encoding_types",
1912 FT_UINT16, BASE_DEC, NULL, 0x0,
1913 "Unknown", HFILL } /* XXX - Needs description */
1915 { &hf_vnc_client_message_type,
1916 { "Client Message Type", "vnc.client_message_type",
1917 FT_UINT8, BASE_DEC, VALS(client_message_types_vs), 0x0,
1918 "Message type from client", HFILL }
1920 { &hf_vnc_client_bits_per_pixel,
1921 { "Bits per pixel", "vnc.client_bits_per_pixel",
1922 FT_UINT8, BASE_DEC, NULL, 0x0,
1923 "Number of bits used by server for each pixel value on the wire from the client", HFILL }
1925 { &hf_vnc_client_depth,
1926 { "Depth", "vnc.client_depth",
1927 FT_UINT8, BASE_DEC, NULL, 0x0,
1928 "Number of useful bits in the pixel value on client", HFILL }
1930 { &hf_vnc_client_big_endian_flag,
1931 { "Big endian flag", "vnc.client_big_endian_flag",
1932 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1933 "True if multi-byte pixels are interpreted as big endian by client", HFILL }
1935 { &hf_vnc_client_true_color_flag,
1936 { "True color flag", "vnc.client_true_color_flag",
1937 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1938 "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 }
1940 { &hf_vnc_client_red_max,
1941 { "Red maximum", "vnc.client_red_max",
1942 FT_UINT16, BASE_DEC, NULL, 0x0,
1943 "Maximum red value on client as n: 2^n - 1", HFILL }
1945 { &hf_vnc_client_green_max,
1946 { "Green maximum", "vnc.client_green_max",
1947 FT_UINT16, BASE_DEC, NULL, 0x0,
1948 "Maximum green value on client as n: 2^n - 1", HFILL }
1950 { &hf_vnc_client_blue_max,
1951 { "Blue maximum", "vnc.client_blue_max",
1952 FT_UINT16, BASE_DEC, NULL, 0x0,
1953 "Maximum blue value on client as n: 2^n - 1", HFILL }
1955 { &hf_vnc_client_red_shift,
1956 { "Red shift", "vnc.client_red_shift",
1957 FT_UINT8, BASE_DEC, NULL, 0x0,
1958 "Number of shifts needed to get the red value in a pixel to the least significant bit on the client", HFILL }
1960 { &hf_vnc_client_green_shift,
1961 { "Green shift", "vnc.client_green_shift",
1962 FT_UINT8, BASE_DEC, NULL, 0x0,
1963 "Number of shifts needed to get the green value in a pixel to the least significant bit on the client", HFILL }
1965 { &hf_vnc_client_blue_shift,
1966 { "Blue shift", "vnc.client_blue_shift",
1967 FT_UINT8, BASE_DEC, NULL, 0x0,
1968 "Number of shifts needed to get the blue value in a pixel to the least significant bit on the client", HFILL }
1971 /* Client Key Event */
1973 { "Key down", "vnc.key_down",
1974 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x0,
1975 "Specifies whether the key is being pressed or not", HFILL }
1979 FT_UINT32, BASE_HEX, VALS(keysym_vals_source), 0x0, /* keysym_vals_source is from packet-x11-keysym.h */
1980 "Key being pressed/depressed", HFILL }
1983 /* Client Pointer Event */
1984 { &hf_vnc_button_1_pos,
1985 { "Mouse button #1 position", "vnc.button_1_pos",
1986 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x1,
1987 "Whether mouse button #1 is being pressed or not", HFILL }
1989 { &hf_vnc_button_2_pos,
1990 { "Mouse button #2 position", "vnc.button_2_pos",
1991 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x2,
1992 "Whether mouse button #2 is being pressed or not", HFILL }
1994 { &hf_vnc_button_3_pos,
1995 { "Mouse button #3 position", "vnc.button_3_pos",
1996 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x4,
1997 "Whether mouse button #3 is being pressed or not", HFILL }
1999 { &hf_vnc_button_4_pos,
2000 { "Mouse button #4 position", "vnc.button_4_pos",
2001 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x8,
2002 "Whether mouse button #4 is being pressed or not", HFILL }
2004 { &hf_vnc_button_5_pos,
2005 { "Mouse button #5 position", "vnc.button_5_pos",
2006 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x10,
2007 "Whether mouse button #5 is being pressed or not", HFILL }
2009 { &hf_vnc_button_6_pos,
2010 { "Mouse button #6 position", "vnc.button_6_pos",
2011 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x20,
2012 "Whether mouse button #6 is being pressed or not", HFILL }
2014 { &hf_vnc_button_7_pos,
2015 { "Mouse button #7 position", "vnc.button_7_pos",
2016 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x40,
2017 "Whether mouse button #7 is being pressed or not", HFILL }
2019 { &hf_vnc_button_8_pos,
2020 { "Mouse button #8 position", "vnc.button_8_pos",
2021 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x80,
2022 "Whether mouse button #8 is being pressed or not", HFILL }
2024 { &hf_vnc_pointer_x_pos,
2025 { "X position", "vnc.pointer_x_pos",
2026 FT_UINT16, BASE_DEC, NULL, 0x0,
2027 "Position of mouse cursor on the x-axis", HFILL }
2029 { &hf_vnc_pointer_y_pos,
2030 { "Y position", "vnc.pointer_y_pos",
2031 FT_UINT16, BASE_DEC, NULL, 0x0,
2032 "Position of mouse cursor on the y-axis", HFILL }
2034 { &hf_vnc_client_set_encodings_encoding_type,
2035 { "Encoding type", "vnc.client_set_encodings_encoding_type",
2036 FT_INT32, BASE_DEC, VALS(encoding_types_vs), 0x0,
2037 "Type of encoding used to send pixel data from server to client", HFILL }
2040 /* Client Framebuffer Update Request */
2041 { &hf_vnc_update_req_incremental,
2042 { "Incremental update", "vnc.update_req_incremental",
2043 FT_BOOLEAN, BASE_DEC, NULL, 0x0,
2044 "Specifies if the client wants an incremental update instead of a full one", HFILL }
2046 { &hf_vnc_update_req_x_pos,
2047 { "X position", "vnc.update_req_x_pos",
2048 FT_UINT16, BASE_DEC, NULL, 0x0,
2049 "X position of framebuffer (screen) update requested", HFILL }
2051 { &hf_vnc_update_req_y_pos,
2052 { "Y position", "vnc.update_req_y_pos",
2053 FT_UINT16, BASE_DEC, NULL, 0x0,
2054 "Y position of framebuffer (screen) update request", HFILL }
2056 { &hf_vnc_update_req_width,
2057 { "Width", "vnc.update_req_width",
2058 FT_UINT16, BASE_DEC, NULL, 0x0,
2059 "Width of framebuffer (screen) update request", HFILL }
2061 { &hf_vnc_update_req_height,
2062 { "Height", "vnc.update_req_height",
2063 FT_UINT16, BASE_DEC, NULL, 0x0,
2064 "Height of framebuffer (screen) update request", HFILL }
2066 { &hf_vnc_client_cut_text_len,
2067 { "Length", "vnc.client_cut_text_len",
2068 FT_UINT32, BASE_DEC, NULL, 0x0,
2069 "Length of client's copy/cut text (clipboard) string in bytes", HFILL }
2071 { &hf_vnc_client_cut_text,
2072 { "Text", "vnc.client_cut_text",
2073 FT_STRING, BASE_NONE, NULL, 0x0,
2074 "Text string in the client's copy/cut text (clipboard)", HFILL }
2078 /********** Server Message Types **********/
2079 { &hf_vnc_server_message_type,
2080 { "Server Message Type", "vnc.server_message_type",
2081 FT_UINT8, BASE_DEC, VALS(server_message_types_vs), 0x0,
2082 "Message type from server", HFILL }
2085 { &hf_vnc_fb_update_x_pos,
2086 { "X position", "vnc.fb_update_x_pos",
2087 FT_UINT16, BASE_DEC, NULL, 0x0,
2088 "X position of this server framebuffer update", HFILL }
2091 { &hf_vnc_fb_update_y_pos,
2092 { "Y position", "vnc.fb_update_x_pos",
2093 FT_UINT16, BASE_DEC, NULL, 0x0,
2094 "Y position of this server framebuffer update", HFILL }
2097 { &hf_vnc_fb_update_width,
2098 { "Width", "vnc.fb_update_width",
2099 FT_UINT16, BASE_DEC, NULL, 0x0,
2100 "Width of this server framebuffer update", HFILL }
2103 { &hf_vnc_fb_update_height,
2104 { "Height", "vnc.fb_update_width",
2105 FT_UINT16, BASE_DEC, NULL, 0x0,
2106 "Height of this server framebuffer update", HFILL }
2109 { &hf_vnc_fb_update_encoding_type,
2110 { "Encoding type", "vnc.fb_update_encoding_type",
2111 FT_INT32, BASE_DEC, VALS(encoding_types_vs), 0x0,
2112 "Encoding type of this server framebuffer update", HFILL }
2115 /* Cursor encoding */
2116 { &hf_vnc_cursor_encoding_pixels,
2117 { "Cursor encoding pixels", "vnc.cursor_encoding_pixels",
2118 FT_BYTES, BASE_NONE, NULL, 0x0,
2119 "Cursor encoding pixel data", HFILL }
2122 { &hf_vnc_cursor_encoding_bitmask,
2123 { "Cursor encoding bitmask", "vnc.cursor_encoding_bitmask",
2124 FT_BYTES, BASE_NONE, NULL, 0x0,
2125 "Cursor encoding pixel bitmask", HFILL }
2129 { &hf_vnc_raw_pixel_data,
2130 { "Pixel data", "vnc.raw_pixel_data",
2131 FT_BYTES, BASE_NONE, NULL, 0x0,
2132 "Raw pixel data.", HFILL }
2135 /* CopyRect Encoding*/
2136 { &hf_vnc_copyrect_src_x_pos,
2137 { "Source x position", "vnc.copyrect_src_x_pos",
2138 FT_UINT16, BASE_DEC, NULL, 0x0,
2139 "X position of the rectangle to copy from", HFILL }
2142 { &hf_vnc_copyrect_src_y_pos,
2143 { "Source y position", "vnc.copyrect_src_y_pos",
2144 FT_UINT16, BASE_DEC, NULL, 0x0,
2145 "Y position of the rectangle to copy from", HFILL }
2149 { &hf_vnc_rre_num_subrects,
2150 { "Number of subrectangles", "vnc.rre_num_subrects",
2151 FT_UINT32, BASE_DEC, NULL, 0x0,
2152 "Number of subrectangles contained in this encoding type", HFILL }
2155 { &hf_vnc_rre_bg_pixel,
2156 { "Background pixel value", "vnc.rre_bg_pixel",
2157 FT_BYTES, BASE_NONE, NULL, 0x0,
2158 "Background pixel value", HFILL }
2161 { &hf_vnc_rre_subrect_pixel,
2162 { "Pixel value", "vnc.rre_subrect_pixel",
2163 FT_BYTES, BASE_NONE, NULL, 0x0,
2164 "Subrectangle pixel value", HFILL }
2167 { &hf_vnc_rre_subrect_x_pos,
2168 { "X position", "vnc.rre_subrect_x_pos",
2169 FT_UINT16, BASE_DEC, NULL, 0x0,
2170 "Position of this subrectangle on the x axis", HFILL }
2173 { &hf_vnc_rre_subrect_y_pos,
2174 { "Y position", "vnc.rre_subrect_y_pos",
2175 FT_UINT16, BASE_DEC, NULL, 0x0,
2176 "Position of this subrectangle on the y axis", HFILL }
2179 { &hf_vnc_rre_subrect_width,
2180 { "Width", "vnc.rre_subrect_width",
2181 FT_UINT16, BASE_DEC, NULL, 0x0,
2182 "Width of this subrectangle", HFILL }
2185 { &hf_vnc_rre_subrect_height,
2186 { "Height", "vnc.rre_subrect_height",
2187 FT_UINT16, BASE_DEC, NULL, 0x0,
2188 "Height of this subrectangle", HFILL }
2192 /* Hextile Encoding */
2193 { &hf_vnc_hextile_subencoding_mask,
2194 { "Subencoding type", "vnc.hextile_subencoding",
2195 FT_UINT8, BASE_DEC, NULL, 0x0,
2196 "Hextile subencoding type.", HFILL }
2199 { &hf_vnc_hextile_raw,
2200 { "Raw", "vnc.hextile_raw",
2201 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x1,
2202 "Raw subencoding is used in this tile", HFILL }
2205 { &hf_vnc_hextile_raw_value,
2206 { "Raw pixel values", "vnc.hextile_raw_value",
2207 FT_BYTES, BASE_NONE, NULL, 0x0,
2208 "Raw subencoding pixel values", HFILL }
2211 { &hf_vnc_hextile_bg,
2212 { "Background Specified", "vnc.hextile_bg",
2213 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x2,
2214 "Background Specified subencoding is used in this tile", HFILL }
2217 { &hf_vnc_hextile_bg_value,
2218 { "Background pixel value", "vnc.hextile_bg_value",
2219 FT_BYTES, BASE_NONE, NULL, 0x0,
2220 "Background color for this tile", HFILL }
2223 { &hf_vnc_hextile_fg,
2224 { "Foreground Specified", "vnc.hextile_fg",
2225 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x4,
2226 "Foreground Specified subencoding is used in this tile", HFILL }
2229 { &hf_vnc_hextile_fg_value,
2230 { "Foreground pixel value", "vnc.hextile_fg_value",
2231 FT_BYTES, BASE_NONE, NULL, 0x0,
2232 "Foreground color for this tile", HFILL }
2235 { &hf_vnc_hextile_anysubrects,
2236 { "Any Subrects", "vnc.hextile_anysubrects",
2237 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x8,
2238 "Any subrects subencoding is used in this tile", HFILL }
2241 { &hf_vnc_hextile_num_subrects,
2242 { "Number of subrectangles", "vnc.hextile_num_subrects",
2243 FT_UINT8, BASE_DEC, NULL, 0x0,
2244 "Number of subrectangles that follow", HFILL }
2247 { &hf_vnc_hextile_subrectscolored,
2248 { "Subrects Colored", "vnc.hextile_subrectscolored",
2249 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x10,
2250 "Subrects colored subencoding is used in this tile", HFILL }
2253 { &hf_vnc_hextile_subrect_pixel_value,
2254 { "Pixel value", "vnc.hextile_subrect_pixel_value",
2255 FT_BYTES, BASE_NONE, NULL, 0x0,
2256 "Pixel value of this subrectangle", HFILL }
2259 { &hf_vnc_hextile_subrect_x_pos,
2260 { "X position", "vnc.hextile_subrect_x_pos",
2261 FT_UINT8, BASE_DEC, NULL, 0xF0, /* Top 4 bits */
2262 "X position of this subrectangle", HFILL }
2265 { &hf_vnc_hextile_subrect_y_pos,
2266 { "Y position", "vnc.hextile_subrect_y_pos",
2267 FT_UINT8, BASE_DEC, NULL, 0xF, /* Bottom 4 bits */
2268 "Y position of this subrectangle", HFILL }
2271 { &hf_vnc_hextile_subrect_width,
2272 { "Width", "vnc.hextile_subrect_width",
2273 FT_UINT8, BASE_DEC, NULL, 0xF0, /* Top 4 bits */
2274 "Subrectangle width minus one", HFILL }
2277 { &hf_vnc_hextile_subrect_height,
2278 { "Height", "vnc.hextile_subrect_height",
2279 FT_UINT8, BASE_DEC, NULL, 0xF, /* Bottom 4 bits */
2280 "Subrectangle height minus one", HFILL }
2286 { "ZRLE compressed length", "vnc.zrle_len",
2287 FT_UINT32, BASE_DEC, NULL, 0x0,
2288 "Length of compressed ZRLE data that follows", HFILL }
2291 { &hf_vnc_zrle_subencoding,
2292 { "Subencoding type", "vnc.zrle_subencoding",
2293 FT_UINT8, BASE_DEC, NULL, 0x0,
2294 "Subencoding type byte", HFILL }
2298 { "RLE", "vnc.zrle_rle",
2299 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x80, /* Upper bit */
2300 "Specifies that data is run-length encoded", HFILL }
2303 { &hf_vnc_zrle_palette_size,
2304 { "Palette size", "vnc.zrle_palette_size",
2305 FT_UINT8, BASE_DEC, NULL, 0x7F, /* Lower 7 bits */
2306 "Palette size", HFILL }
2309 { &hf_vnc_zrle_data,
2310 { "ZRLE compressed data", "vnc.zrle_data",
2311 FT_BYTES, BASE_NONE, NULL, 0x0,
2312 "Compressed ZRLE data. Compiling with zlib support will uncompress and dissect this data", HFILL }
2316 { "Pixel values", "vnc.zrle_raw",
2317 FT_BYTES, BASE_NONE, NULL, 0x0,
2318 "Raw pixel values for this tile", HFILL }
2321 { &hf_vnc_zrle_palette,
2322 { "Palette", "vnc.zrle_palette",
2323 FT_BYTES, BASE_NONE, NULL, 0x0,
2324 "Palette pixel values", HFILL }
2327 /* Server Set Colormap Entries */
2328 { &hf_vnc_colormap_first_color,
2329 { "First color", "vnc.colormap_first_color",
2330 FT_UINT16, BASE_DEC, NULL, 0x0,
2331 "First color that should be mapped to given RGB intensities", HFILL }
2333 { &hf_vnc_colormap_num_colors,
2334 { "Number of color groups", "vnc.colormap_groups",
2335 FT_UINT16, BASE_DEC, NULL, 0x0,
2336 "Number of red/green/blue color groups", HFILL }
2338 { &hf_vnc_colormap_red,
2339 { "Red", "vnc.colormap_red",
2340 FT_UINT16, BASE_DEC, NULL, 0x0,
2341 "Red intensity", HFILL }
2343 { &hf_vnc_colormap_green,
2344 { "Green", "vnc.colormap_green",
2345 FT_UINT16, BASE_DEC, NULL, 0x0,
2346 "Green intensity", HFILL }
2348 { &hf_vnc_colormap_blue,
2349 { "Blue", "vnc.colormap_blue",
2350 FT_UINT16, BASE_DEC, NULL, 0x0,
2351 "Blue intensity", HFILL }
2354 /* Server Cut Text */
2355 { &hf_vnc_server_cut_text_len,
2356 { "Length", "vnc.server_cut_text_len",
2357 FT_UINT32, BASE_DEC, NULL, 0x0,
2358 "Length of server's copy/cut text (clipboard) string in bytes", HFILL }
2360 { &hf_vnc_server_cut_text,
2361 { "Text", "vnc.server_cut_text",
2362 FT_STRING, BASE_NONE, NULL, 0x0,
2363 "Text string in the server's copy/cut text (clipboard)", HFILL }
2367 /* Setup protocol subtree arrays */
2368 static gint *ett[] = {
2370 &ett_vnc_client_message_type,
2371 &ett_vnc_server_message_type,
2373 &ett_vnc_encoding_type,
2374 &ett_vnc_rre_subrect,
2375 &ett_vnc_hextile_subencoding_mask,
2376 &ett_vnc_hextile_num_subrects,
2377 &ett_vnc_hextile_subrect,
2378 &ett_vnc_zrle_subencoding,
2379 &ett_vnc_colormap_num_groups,
2380 &ett_vnc_colormap_color_group
2383 /* Register the protocol name and description */
2384 proto_vnc = proto_register_protocol("Virtual Network Computing",
2387 /* Required function calls to register the header fields and subtrees */
2388 proto_register_field_array(proto_vnc, hf, array_length(hf));
2389 proto_register_subtree_array(ett, array_length(ett));
2391 /* Register our preferences module */
2392 vnc_module = prefs_register_protocol(proto_vnc, proto_reg_handoff_vnc);
2394 prefs_register_bool_preference(vnc_module, "desegment", "Reassemble VNC messages spanning multiple TCP segments.", "Whether the VNC dissector should reasss emble 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);
2396 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);
2401 proto_reg_handoff_vnc(void)
2403 static gboolean inited = FALSE;
2406 vnc_handle = create_dissector_handle(dissect_vnc,
2409 dissector_add("tcp.port", 5500, vnc_handle);
2410 dissector_add("tcp.port", 5501, vnc_handle);
2411 dissector_add("tcp.port", 5900, vnc_handle);
2412 dissector_add("tcp.port", 5901, vnc_handle);
2414 /* We don't register a port for the VNC HTTP server because
2415 * that simply provides a java program for download via the
2416 * HTTP protocol. The java program then connects to a standard
2422 if(vnc_preference_alternate_port != 5500 &&
2423 vnc_preference_alternate_port != 5501 &&
2424 vnc_preference_alternate_port != 5900 &&
2425 vnc_preference_alternate_port != 5901 &&
2426 vnc_preference_alternate_port != 0) {
2428 dissector_delete("tcp.port",
2429 vnc_preference_alternate_port_last,
2432 /* Save this setting to see if has changed later */
2433 vnc_preference_alternate_port_last =
2434 vnc_preference_alternate_port;
2436 /* Register the new port setting */
2437 dissector_add("tcp.port", vnc_preference_alternate_port,