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 * Both versions of RealVNC (3.3 and 3.8) are supported.
31 * Several VNC implementations available, see:
32 * http://www.realvnc.com/
33 * http://www.tightvnc.com/
34 * http://ultravnc.sourceforge.net/
37 * The protocol itself is known as RFB - Remote Frame Buffer Protocol.
39 * This code is based on the protocol specification:
40 * http://www.realvnc.com/docs/rfbproto.pdf
41 * and the RealVNC free edition source code
45 /* XXX - We can delete entries in the tree, can't we? for when desegmenting */
57 #include <epan/conversation.h>
58 #include <epan/emem.h>
59 #include <epan/packet.h>
60 #include <epan/prefs.h>
61 #include "packet-x11-keysym.h" /* This contains the X11 value_string
62 * "keysym_vals_source" that VNC also uses. */
64 static const value_string security_types_vs[] = {
76 static const value_string auth_result_vs[] = {
82 static const value_string yes_no_vs[] = {
88 static const value_string client_message_types_vs[] = {
89 { 0, "Set Pixel Format" },
90 { 2, "Set Encodings" },
91 { 3, "Framebuffer Update Request" },
93 { 5, "Pointer Event" },
98 static const value_string server_message_types_vs[] = {
99 { 0, "Framebuffer Update" },
100 { 1, "Set Colormap Entries" },
106 static const value_string button_mask_vs[] = {
107 { 0, "Not pressed" },
112 static const value_string encoding_types_vs[] = {
113 { -239, "Cursor (pseudo)" },
114 { -223, "DesktopSize (pseudo)" },
125 void proto_reg_handoff_vnc(void);
127 static void vnc_client_to_server(tvbuff_t *tvb, packet_info *pinfo,
128 gint *offset, proto_tree *tree);
129 static void vnc_server_to_client(tvbuff_t *tvb, packet_info *pinfo,
130 gint *offset, proto_tree *tree);
131 static void vnc_client_set_pixel_format(tvbuff_t *tvb, packet_info *pinfo,
132 gint *offset, proto_tree *tree);
133 static void vnc_client_set_encodings(tvbuff_t *tvb, packet_info *pinfo,
134 gint *offset, proto_tree *tree);
135 static void vnc_client_framebuffer_update_request(tvbuff_t *tvb,
139 static void vnc_client_key_event(tvbuff_t *tvb, packet_info *pinfo,
140 gint *offset, proto_tree *tree);
141 static void vnc_client_pointer_event(tvbuff_t *tvb, packet_info *pinfo,
142 gint *offset, proto_tree *tree);
143 static void vnc_client_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
146 static guint vnc_server_framebuffer_update(tvbuff_t *tvb, packet_info *pinfo,
147 gint *offset, proto_tree *tree);
148 static guint vnc_raw_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
149 proto_tree *tree, guint16 width, guint16 height);
150 static guint vnc_copyrect_encoding(tvbuff_t *tvb, packet_info *pinfo,
151 gint *offset, proto_tree *tree,
152 guint16 width, guint16 height);
153 static guint vnc_rre_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
154 proto_tree *tree, guint16 width, guint16 height);
155 static guint vnc_hextile_encoding(tvbuff_t *tvb, packet_info *pinfo,
156 gint *offset, proto_tree *tree,
157 guint16 width, guint16 height);
158 static guint vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
159 proto_tree *tree, guint16 width, guint16 height);
160 static guint vnc_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo,
161 gint *offset, proto_tree *tree, guint16 width,
163 static guint vnc_server_set_colormap_entries(tvbuff_t *tvb, packet_info *pinfo,
164 gint *offset, proto_tree *tree);
165 static void vnc_server_ring_bell(tvbuff_t *tvb, packet_info *pinfo,
166 gint *offset, proto_tree *tree);
167 static guint vnc_server_cut_text(tvbuff_t *tvb, packet_info *pinfo,
168 gint *offset, proto_tree *tree);
169 static void vnc_set_bytes_per_pixel(packet_info *pinfo, guint8 bytes_per_pixel);
170 static guint8 vnc_get_bytes_per_pixel(packet_info *pinfo);
173 #define DEST_PORT_VNC pinfo->destport == 5500 || pinfo->destport == 5501 || \
174 pinfo->destport == 5900 || pinfo->destport == 5901 || \
175 pinfo->destport == vnc_preference_alternate_port
177 #define VNC_BYTES_NEEDED(a) \
178 if(a > (guint)tvb_length_remaining(tvb, *offset)) \
182 /* Variables for our preferences */
183 static guint vnc_preference_alternate_port = 0;
185 /* This is a behind the scenes variable that is not changed by the user.
186 * This stores last setting of the vnc_preference_alternate_port. Used to keep
187 * track of when the user has changed the setting so that we can delete
188 * and re-register with the new port number. */
189 static guint vnc_preference_alternate_port_last = 0;
191 /* Initialize the protocol and registered fields */
192 static int proto_vnc = -1; /* Protocol subtree */
193 static int hf_vnc_padding = -1;
194 static int hf_vnc_server_proto_ver = -1;
195 static int hf_vnc_client_proto_ver = -1;
196 static int hf_vnc_num_security_types = -1;
197 static int hf_vnc_security_type = -1;
198 static int hf_vnc_server_security_type = -1;
199 static int hf_vnc_client_security_type = -1;
200 static int hf_vnc_auth_challenge = -1;
201 static int hf_vnc_auth_response = -1;
202 static int hf_vnc_auth_result = -1;
203 static int hf_vnc_auth_error = -1;
205 static int hf_vnc_share_desktop_flag = -1;
206 static int hf_vnc_width = -1;
207 static int hf_vnc_height = -1;
208 static int hf_vnc_server_bits_per_pixel = -1;
209 static int hf_vnc_server_depth = -1;
210 static int hf_vnc_server_big_endian_flag = -1;
211 static int hf_vnc_server_true_color_flag = -1;
212 static int hf_vnc_server_red_max = -1;
213 static int hf_vnc_server_green_max = -1;
214 static int hf_vnc_server_blue_max = -1;
215 static int hf_vnc_server_red_shift = -1;
216 static int hf_vnc_server_green_shift = -1;
217 static int hf_vnc_server_blue_shift = -1;
218 static int hf_vnc_desktop_name = -1;
219 static int hf_vnc_desktop_name_len = -1;
222 /********** Client Message Types **********/
224 static int hf_vnc_client_message_type = -1; /* A subtree under VNC */
225 static int hf_vnc_client_bits_per_pixel = -1;
226 static int hf_vnc_client_depth = -1;
227 static int hf_vnc_client_big_endian_flag = -1;
228 static int hf_vnc_client_true_color_flag = -1;
229 static int hf_vnc_client_red_max = -1;
230 static int hf_vnc_client_green_max = -1;
231 static int hf_vnc_client_blue_max = -1;
232 static int hf_vnc_client_red_shift = -1;
233 static int hf_vnc_client_green_shift = -1;
234 static int hf_vnc_client_blue_shift = -1;
236 /* Client Key Event */
237 static int hf_vnc_key_down = -1;
238 static int hf_vnc_key = -1;
240 /* Client Pointer Event */
241 static int hf_vnc_button_1_pos = -1;
242 static int hf_vnc_button_2_pos = -1;
243 static int hf_vnc_button_3_pos = -1;
244 static int hf_vnc_button_4_pos = -1;
245 static int hf_vnc_button_5_pos = -1;
246 static int hf_vnc_button_6_pos = -1;
247 static int hf_vnc_button_7_pos = -1;
248 static int hf_vnc_button_8_pos = -1;
249 static int hf_vnc_pointer_x_pos = -1;
250 static int hf_vnc_pointer_y_pos = -1;
252 /* Client Framebuffer Update Request */
253 static int hf_vnc_update_req_incremental = -1;
254 static int hf_vnc_update_req_x_pos = -1;
255 static int hf_vnc_update_req_y_pos = -1;
256 static int hf_vnc_update_req_width = -1;
257 static int hf_vnc_update_req_height = -1;
259 /* Client Set Encodings */
260 static int hf_vnc_client_set_encodings_encoding_type = -1;
262 /* Client Cut Text */
263 static int hf_vnc_client_cut_text_len = -1;
264 static int hf_vnc_client_cut_text = -1;
266 /********** Server Message Types **********/
268 static int hf_vnc_server_message_type = -1; /* Subtree */
270 /* Server Framebuffer Update */
271 static int hf_vnc_fb_update_x_pos = -1;
272 static int hf_vnc_fb_update_y_pos = -1;
273 static int hf_vnc_fb_update_width = -1;
274 static int hf_vnc_fb_update_height = -1;
275 static int hf_vnc_fb_update_encoding_type = -1;
278 static int hf_vnc_raw_pixel_data = -1;
280 /* CopyRect Encoding */
281 static int hf_vnc_copyrect_src_x_pos = -1;
282 static int hf_vnc_copyrect_src_y_pos = -1;
285 static int hf_vnc_rre_num_subrects = -1;
286 static int hf_vnc_rre_bg_pixel = -1;
288 static int hf_vnc_rre_subrect_pixel = -1;
289 static int hf_vnc_rre_subrect_x_pos = -1;
290 static int hf_vnc_rre_subrect_y_pos = -1;
291 static int hf_vnc_rre_subrect_width = -1;
292 static int hf_vnc_rre_subrect_height = -1;
294 /* Hextile Encoding */
295 static int hf_vnc_hextile_subencoding_mask = -1;
296 static int hf_vnc_hextile_raw = -1;
297 static int hf_vnc_hextile_raw_value = -1;
298 static int hf_vnc_hextile_bg = -1;
299 static int hf_vnc_hextile_bg_value = -1;
300 static int hf_vnc_hextile_fg = -1;
301 static int hf_vnc_hextile_fg_value = -1;
302 static int hf_vnc_hextile_anysubrects = -1;
303 static int hf_vnc_hextile_num_subrects = -1;
304 static int hf_vnc_hextile_subrectscolored = -1;
305 static int hf_vnc_hextile_subrect_pixel_value = -1;
306 static int hf_vnc_hextile_subrect_x_pos = -1;
307 static int hf_vnc_hextile_subrect_y_pos = -1;
308 static int hf_vnc_hextile_subrect_width = -1;
309 static int hf_vnc_hextile_subrect_height = -1;
312 static int hf_vnc_zrle_len = -1;
313 static int hf_vnc_zrle_subencoding = -1;
314 static int hf_vnc_zrle_rle = -1;
315 static int hf_vnc_zrle_palette_size = -1;
316 static int hf_vnc_zrle_data = -1;
317 static int hf_vnc_zrle_raw = -1;
318 static int hf_vnc_zrle_palette = -1;
320 /* Cursor Encoding */
321 static int hf_vnc_cursor_encoding_pixels = -1;
322 static int hf_vnc_cursor_encoding_bitmask = -1;
324 /* Server Set Colormap Entries */
325 static int hf_vnc_colormap_first_color = -1;
326 static int hf_vnc_colormap_num_colors = -1;
327 static int hf_vnc_colormap_red = -1;
328 static int hf_vnc_colormap_green = -1;
329 static int hf_vnc_colormap_blue = -1;
331 /* Server Cut Text */
332 static int hf_vnc_server_cut_text_len = -1;
333 static int hf_vnc_server_cut_text = -1;
335 /********** End of Server Message Types **********/
337 static gboolean vnc_preference_desegment = TRUE;
339 /* Initialize the subtree pointers */
340 static gint ett_vnc = -1;
341 static gint ett_vnc_client_message_type = -1;
342 static gint ett_vnc_server_message_type = -1;
343 static gint ett_vnc_rect = -1;
344 static gint ett_vnc_encoding_type = -1;
345 static gint ett_vnc_rre_subrect = -1;
346 static gint ett_vnc_hextile_subencoding_mask = -1;
347 static gint ett_vnc_hextile_num_subrects = -1;
348 static gint ett_vnc_hextile_subrect = -1;
349 static gint ett_vnc_zrle_subencoding = -1;
350 static gint ett_vnc_colormap_num_groups = -1;
351 static gint ett_vnc_colormap_color_group = -1;
353 static dissector_handle_t vnc_handle;
356 /* Initialize the structure that will be tied to each conversation. */
358 /* Packet numbers for the first 9 packets of each conversation. */
359 guint32 first_packet_number, second_packet_number, third_packet_number,
360 forth_packet_number, fifth_packet_number, sixth_packet_number,
361 seventh_packet_number, eighth_packet_number,
363 gdouble server_proto_ver, client_proto_ver;
364 } vnc_conversation_t;
366 /* Initialize the structure that will be tied to each packet */
368 guint8 bytes_per_pixel;
372 guint8 vnc_bytes_per_pixel; /* Global so it keeps its value between packets */
375 /* Code to dissect the packets */
377 dissect_vnc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
379 guint8 num_security_types;
380 guint32 text_len; /* Part of: Client Cut Text & Server Cut Text */
381 guint32 auth_result, desktop_name_len;
384 /* Set up structures needed to add the protocol subtree and manage it */
386 proto_tree *vnc_tree=NULL;
388 conversation_t *conversation;
389 vnc_conversation_t *per_conversation_info;
391 conversation = find_conversation(pinfo->fd->num, &pinfo->src,
392 &pinfo->dst, pinfo->ptype,
393 pinfo->srcport, pinfo->destport, 0);
395 if(!conversation) { /* Conversation does not exist yet - create it */
396 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
397 &pinfo->dst, pinfo->ptype,
402 /* Retrieve information from conversation, or add it if it isn't
404 per_conversation_info = conversation_get_proto_data(conversation,
406 if(!per_conversation_info) {
407 per_conversation_info = se_alloc(sizeof(vnc_conversation_t));
409 /* We must be on the first packet now */
410 per_conversation_info->first_packet_number = pinfo->fd->num;
412 /* The rest of these values will be set as we come across each
414 per_conversation_info->second_packet_number = 0;
415 per_conversation_info->third_packet_number = 0;
416 per_conversation_info->forth_packet_number = 0;
417 per_conversation_info->fifth_packet_number = 0;
418 per_conversation_info->sixth_packet_number = 0;
419 per_conversation_info->seventh_packet_number = 0;
420 per_conversation_info->eighth_packet_number = 0;
421 per_conversation_info->ninth_packet_number = 0;
423 per_conversation_info->server_proto_ver = 0.0;
424 per_conversation_info->client_proto_ver = 0.0;
426 conversation_add_proto_data(conversation, proto_vnc,
427 per_conversation_info);
430 /* Store the number of the first nine packets of this conversation as
431 * we reach them for the first time. These are the packets that
432 * contain connection setup data and do not have a message type
433 * identifier. The packets after the ninth one do contain message
434 * type identifiers. */
436 if(!per_conversation_info->second_packet_number && pinfo->fd->num >
437 per_conversation_info->first_packet_number) {
438 /* We're on the second packet of the conversation */
439 per_conversation_info->second_packet_number = pinfo->fd->num;
441 } else if(per_conversation_info->second_packet_number &&
442 !per_conversation_info->third_packet_number &&
444 per_conversation_info->second_packet_number) {
445 /* We're on the third packet of the conversation */
446 per_conversation_info->third_packet_number = pinfo->fd->num;
448 } else if(per_conversation_info->third_packet_number &&
449 !per_conversation_info->forth_packet_number &&
450 pinfo->fd->num > per_conversation_info->third_packet_number) {
451 /* We're on the forth packet of the conversation */
452 per_conversation_info->forth_packet_number = pinfo->fd->num;
454 } else if(per_conversation_info->forth_packet_number &&
455 !per_conversation_info->fifth_packet_number &&
456 pinfo->fd->num > per_conversation_info->forth_packet_number) {
457 /* We're on the fifth packet of the conversation */
458 per_conversation_info->fifth_packet_number = pinfo->fd->num;
460 } else if(per_conversation_info->fifth_packet_number &&
461 !per_conversation_info->sixth_packet_number &&
462 pinfo->fd->num > per_conversation_info->fifth_packet_number) {
463 /* We're on the sixth packet of the conversation */
464 per_conversation_info->sixth_packet_number = pinfo->fd->num;
466 } else if(per_conversation_info->sixth_packet_number &&
467 !per_conversation_info->seventh_packet_number &&
468 pinfo->fd->num > per_conversation_info->sixth_packet_number) {
469 /* We're on the seventh packet of the conversation */
470 per_conversation_info->seventh_packet_number = pinfo->fd->num;
472 } else if(per_conversation_info->seventh_packet_number &&
473 !per_conversation_info->eighth_packet_number &&
475 per_conversation_info->seventh_packet_number){
476 /* We're on the eighth packet of the conversation */
477 per_conversation_info->eighth_packet_number = pinfo->fd->num;
479 } else if(per_conversation_info->eighth_packet_number &&
480 !per_conversation_info->ninth_packet_number &&
481 pinfo->fd->num > per_conversation_info->eighth_packet_number){
482 /* We're on the ninth packet of the conversation */
483 per_conversation_info->ninth_packet_number = pinfo->fd->num;
487 /* Make entries in Protocol column and Info column on summary display */
488 if (check_col(pinfo->cinfo, COL_PROTOCOL))
489 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VNC");
491 /* First, clear the info column */
492 if(check_col(pinfo->cinfo, COL_INFO))
493 col_clear(pinfo->cinfo, COL_INFO);
495 /* create display subtree for the protocol */
497 ti = proto_tree_add_item(tree, proto_vnc, tvb, 0, -1, FALSE);
498 vnc_tree = proto_item_add_subtree(ti, ett_vnc);
501 offset = 0; /* Start at the beginning of the VNC protocol data */
503 /* Server Protocol Version */
505 if(pinfo->fd->num == per_conversation_info->first_packet_number) {
506 proto_tree_add_item(vnc_tree, hf_vnc_server_proto_ver, tvb, 4,
508 per_conversation_info->server_proto_ver =
509 g_strtod(tvb_get_ephemeral_string(tvb, 4, 7), NULL);
511 if (check_col(pinfo->cinfo, COL_INFO))
512 col_add_fstr(pinfo->cinfo, COL_INFO,
513 "Server protocol version: %s",
514 tvb_format_text(tvb, 4, 7));
517 /* Second Packet = Client Protocol Version */
518 else if(pinfo->fd->num == per_conversation_info->second_packet_number) {
519 proto_tree_add_item(vnc_tree, hf_vnc_client_proto_ver, tvb, 4,
521 per_conversation_info->client_proto_ver =
522 g_strtod(tvb_get_ephemeral_string(tvb, 4, 7), NULL);
524 if (check_col(pinfo->cinfo, COL_INFO))
525 col_add_fstr(pinfo->cinfo, COL_INFO,
526 "Client protocol version: %s",
527 tvb_format_text(tvb, 4, 7));
530 /* Security Types Supported */
531 else if(pinfo->fd->num == per_conversation_info->third_packet_number) {
533 if (check_col(pinfo->cinfo, COL_INFO))
534 col_set_str(pinfo->cinfo, COL_INFO,
535 "Security types supported");
537 /* We're checking against the client protocol version because
538 * the client is the final decider on which version to use
539 * after the server offers the version it supports. */
541 if(per_conversation_info->client_proto_ver >= 3.007) {
542 proto_tree_add_item(vnc_tree,
543 hf_vnc_num_security_types, tvb,
545 num_security_types = tvb_get_guint8(tvb, offset);
547 for(offset = 1; offset <= num_security_types; offset++){
548 proto_tree_add_item(vnc_tree,
549 hf_vnc_security_type, tvb,
553 /* Version < 3.007: The server decides the
554 * authentication time for us to use */
555 proto_tree_add_item(vnc_tree,
556 hf_vnc_server_security_type, tvb,
563 /* Authentication type selected by client.
564 * This field is skipped by versions < 3.007 so the packet number is
565 * off on each if statement below */
566 else if(per_conversation_info->client_proto_ver >= 3.007 &&
567 pinfo->fd->num == per_conversation_info->forth_packet_number) {
568 if (check_col(pinfo->cinfo, COL_INFO))
569 col_set_str(pinfo->cinfo, COL_INFO,
570 "Authentication type selected by client");
572 proto_tree_add_item(vnc_tree, hf_vnc_client_security_type, tvb,
576 /* Authentication challenge from server */
577 else if((per_conversation_info->client_proto_ver >= 3.007 &&
578 pinfo->fd->num == per_conversation_info->fifth_packet_number)||
579 (per_conversation_info->client_proto_ver < 3.007 &&
580 pinfo->fd->num == per_conversation_info->forth_packet_number)){
581 if (check_col(pinfo->cinfo, COL_INFO))
582 col_set_str(pinfo->cinfo, COL_INFO,
583 "Authentication challenge from server");
585 proto_tree_add_item(vnc_tree, hf_vnc_auth_challenge, tvb,
589 /* Authentication response from client */
590 else if((per_conversation_info->client_proto_ver >= 3.007 &&
591 pinfo->fd->num == per_conversation_info->sixth_packet_number)||
592 (per_conversation_info->client_proto_ver < 3.007 &&
593 pinfo->fd->num == per_conversation_info->fifth_packet_number)){
594 if (check_col(pinfo->cinfo, COL_INFO))
595 col_set_str(pinfo->cinfo, COL_INFO,
596 "Authentication response from client");
598 proto_tree_add_item(vnc_tree, hf_vnc_auth_response, tvb,
602 /* Authentication result */
603 else if((per_conversation_info->client_proto_ver >= 3.007 &&
604 pinfo->fd->num == per_conversation_info->seventh_packet_number)
605 || (per_conversation_info->client_proto_ver < 3.007 &&
607 per_conversation_info->sixth_packet_number)) {
609 if (check_col(pinfo->cinfo, COL_INFO))
610 col_set_str(pinfo->cinfo, COL_INFO,
611 "Authentication result");
613 proto_tree_add_item(vnc_tree, hf_vnc_auth_result, tvb, offset,
615 auth_result = tvb_get_ntohl(tvb, offset);
618 if(per_conversation_info->client_proto_ver >= 3.007 &&
619 auth_result == 1) { /* 1 = failed */
620 text_len = tvb_get_ntohl(tvb, offset);
621 proto_tree_add_text(vnc_tree, tvb, offset, 4,
622 "Length of authentication error: %d", text_len);
625 proto_tree_add_item(vnc_tree, hf_vnc_auth_error, tvb,
626 offset, text_len, FALSE);
633 else if((per_conversation_info->client_proto_ver >= 3.007 &&
634 pinfo->fd->num == per_conversation_info->eighth_packet_number)
635 || (per_conversation_info->client_proto_ver < 3.007 &&
636 pinfo->fd->num == per_conversation_info->seventh_packet_number)) {
637 if (check_col(pinfo->cinfo, COL_INFO))
638 col_set_str(pinfo->cinfo, COL_INFO,
639 "Share desktop flag");
641 proto_tree_add_item(vnc_tree, hf_vnc_share_desktop_flag, tvb,
645 /* Various parameters for the frame buffer (screen) from the server */
646 else if((per_conversation_info->client_proto_ver >= 3.007 &&
647 pinfo->fd->num == per_conversation_info->ninth_packet_number)||
648 (per_conversation_info->client_proto_ver < 3.007 &&
649 pinfo->fd->num == per_conversation_info->eighth_packet_number)) {
651 if (check_col(pinfo->cinfo, COL_INFO))
652 col_set_str(pinfo->cinfo, COL_INFO,
653 "Server framebuffer parameters");
655 proto_tree_add_item(vnc_tree, hf_vnc_width, tvb, offset, 2,
659 proto_tree_add_item(vnc_tree, hf_vnc_height, tvb, offset, 2,
663 proto_tree_add_item(vnc_tree, hf_vnc_server_bits_per_pixel,
664 tvb, offset, 1, FALSE);
665 vnc_bytes_per_pixel = tvb_get_guint8(tvb, offset)/8;
666 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
669 proto_tree_add_item(vnc_tree, hf_vnc_server_depth, tvb, offset,
673 proto_tree_add_item(vnc_tree, hf_vnc_server_big_endian_flag,
674 tvb, offset, 1, FALSE);
677 proto_tree_add_item(vnc_tree, hf_vnc_server_true_color_flag,
678 tvb, offset, 1, FALSE);
681 proto_tree_add_item(vnc_tree, hf_vnc_server_red_max,
682 tvb, offset, 2, FALSE);
685 proto_tree_add_item(vnc_tree, hf_vnc_server_green_max,
686 tvb, offset, 2, FALSE);
689 proto_tree_add_item(vnc_tree, hf_vnc_server_blue_max,
690 tvb, offset, 2, FALSE);
693 proto_tree_add_item(vnc_tree, hf_vnc_server_red_shift,
694 tvb, offset, 1, FALSE);
697 proto_tree_add_item(vnc_tree, hf_vnc_server_green_shift,
698 tvb, offset, 1, FALSE);
701 proto_tree_add_item(vnc_tree, hf_vnc_server_blue_shift,
702 tvb, offset, 1, FALSE);
705 proto_tree_add_item(vnc_tree, hf_vnc_padding,
706 tvb, offset, 3, FALSE);
707 offset += 3; /* Skip over 3 bytes of padding */
709 if(tvb_length_remaining(tvb, offset) > 0) {
710 /* Sometimes the desktop name & length is skipped */
711 proto_tree_add_item(vnc_tree, hf_vnc_desktop_name_len,
712 tvb, offset, 4, FALSE);
713 desktop_name_len = tvb_get_ntohl(tvb, offset);
716 proto_tree_add_item(vnc_tree, hf_vnc_desktop_name,
717 tvb, offset, desktop_name_len,
721 } else { /* All packets beyond #9 */
723 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
726 vnc_client_to_server(tvb, pinfo, &offset, vnc_tree);
728 vnc_server_to_client(tvb, pinfo, &offset, vnc_tree);
734 vnc_client_to_server(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
740 proto_tree *vnc_client_message_type_tree;
742 message_type = tvb_get_guint8(tvb, *offset);
744 ti = proto_tree_add_item(tree, hf_vnc_client_message_type, tvb,
747 vnc_client_message_type_tree =
748 proto_item_add_subtree(ti, ett_vnc_client_message_type);
752 switch(message_type) {
755 vnc_client_set_pixel_format(tvb, pinfo, offset,
756 vnc_client_message_type_tree);
760 vnc_client_set_encodings(tvb, pinfo, offset,
761 vnc_client_message_type_tree);
765 vnc_client_framebuffer_update_request(tvb, pinfo, offset,
766 vnc_client_message_type_tree);
770 vnc_client_key_event(tvb, pinfo, offset,
771 vnc_client_message_type_tree);
775 vnc_client_pointer_event(tvb, pinfo, offset,
776 vnc_client_message_type_tree);
780 vnc_client_cut_text(tvb, pinfo, offset,
781 vnc_client_message_type_tree);
785 if (check_col(pinfo->cinfo, COL_INFO))
786 col_append_str(pinfo->cinfo, COL_INFO,
787 "Unknown client message type");
793 vnc_server_to_client(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
797 gint bytes_needed = 0, length_remaining;
800 proto_tree *vnc_server_message_type_tree;
802 message_type = tvb_get_guint8(tvb, *offset);
804 ti = proto_tree_add_item(tree, hf_vnc_server_message_type, tvb,
806 vnc_server_message_type_tree =
807 proto_item_add_subtree(ti, ett_vnc_server_message_type);
811 switch(message_type) {
815 vnc_server_framebuffer_update(tvb, pinfo, offset,
816 vnc_server_message_type_tree);
820 bytes_needed = vnc_server_set_colormap_entries(tvb, pinfo, offset, vnc_server_message_type_tree);
824 vnc_server_ring_bell(tvb, pinfo, offset,
825 vnc_server_message_type_tree);
829 bytes_needed = vnc_server_cut_text(tvb, pinfo, offset,
830 vnc_server_message_type_tree);
834 if (check_col(pinfo->cinfo, COL_INFO))
835 col_append_str(pinfo->cinfo, COL_INFO,
836 "Unknown server message type");
840 if(bytes_needed > 0 && vnc_preference_desegment &&
841 pinfo->can_desegment) {
842 length_remaining = tvb_length_remaining(tvb, *offset);
844 pinfo->desegment_offset = 0;
845 pinfo->desegment_len = tvb_length(tvb) + bytes_needed -
853 vnc_client_set_pixel_format(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
856 if (check_col(pinfo->cinfo, COL_INFO))
857 col_set_str(pinfo->cinfo, COL_INFO, "Client set pixel format");
859 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset,
861 *offset += 3; /* Skip over 3 bytes of padding */
863 proto_tree_add_item(tree, hf_vnc_client_bits_per_pixel, tvb, *offset,
865 vnc_bytes_per_pixel = tvb_get_guint8(tvb, *offset)/8;
866 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
869 proto_tree_add_item(tree, hf_vnc_client_depth, tvb, *offset,
873 proto_tree_add_item(tree, hf_vnc_client_big_endian_flag, tvb, *offset,
877 proto_tree_add_item(tree, hf_vnc_client_true_color_flag, tvb, *offset,
881 proto_tree_add_item(tree, hf_vnc_client_red_max, tvb, *offset,
885 proto_tree_add_item(tree, hf_vnc_client_green_max, tvb, *offset,
889 proto_tree_add_item(tree, hf_vnc_client_blue_max, tvb, *offset,
893 proto_tree_add_item(tree, hf_vnc_client_red_shift, tvb, *offset,
897 proto_tree_add_item(tree, hf_vnc_client_green_shift, tvb, *offset,
901 proto_tree_add_item(tree, hf_vnc_client_blue_shift, tvb, *offset,
905 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset,
907 *offset += 3; /* Skip over 3 bytes of padding */
912 vnc_client_set_encodings(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
915 guint16 number_of_encodings;
918 if (check_col(pinfo->cinfo, COL_INFO))
919 col_set_str(pinfo->cinfo, COL_INFO, "Client set encodings");
921 proto_tree_add_item(tree, hf_vnc_padding,
922 tvb, *offset, 1, FALSE);
923 *offset += 1; /* Skip over 1 byte of padding */
925 number_of_encodings = tvb_get_ntohs(tvb, *offset);
927 proto_tree_add_text(tree, tvb, *offset, 2,
928 "Number of encodings: %d", number_of_encodings);
931 for(counter = 1; counter <= number_of_encodings; counter++) {
932 proto_tree_add_item(tree,
933 hf_vnc_client_set_encodings_encoding_type,
934 tvb, *offset, 4, FALSE);
941 vnc_client_framebuffer_update_request(tvbuff_t *tvb, packet_info *pinfo,
942 gint *offset, proto_tree *tree)
944 if (check_col(pinfo->cinfo, COL_INFO))
945 col_set_str(pinfo->cinfo, COL_INFO,
946 "Client framebuffer update request");
948 proto_tree_add_item(tree, hf_vnc_update_req_incremental,
949 tvb, *offset, 1, FALSE);
952 proto_tree_add_item(tree, hf_vnc_update_req_x_pos,
953 tvb, *offset, 2, FALSE);
956 proto_tree_add_item(tree, hf_vnc_update_req_y_pos,
957 tvb, *offset, 2, FALSE);
960 proto_tree_add_item(tree, hf_vnc_update_req_width, tvb,
964 proto_tree_add_item(tree, hf_vnc_update_req_height, tvb,
971 vnc_client_key_event(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
974 if (check_col(pinfo->cinfo, COL_INFO))
975 col_set_str(pinfo->cinfo, COL_INFO, "Client key event");
977 proto_tree_add_item(tree, hf_vnc_key_down, tvb, *offset, 1, FALSE);
980 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 2, FALSE);
981 *offset += 2; /* Skip over 2 bytes of padding */
983 proto_tree_add_item(tree, hf_vnc_key, tvb, *offset, 4, FALSE);
989 vnc_client_pointer_event(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
992 if (check_col(pinfo->cinfo, COL_INFO))
993 col_set_str(pinfo->cinfo, COL_INFO, "Client pointer event");
995 proto_tree_add_item(tree, hf_vnc_button_1_pos, tvb, *offset, 1, FALSE);
996 proto_tree_add_item(tree, hf_vnc_button_2_pos, tvb, *offset, 1, FALSE);
997 proto_tree_add_item(tree, hf_vnc_button_3_pos, tvb, *offset, 1, FALSE);
998 proto_tree_add_item(tree, hf_vnc_button_4_pos, tvb, *offset, 1, FALSE);
999 proto_tree_add_item(tree, hf_vnc_button_5_pos, tvb, *offset, 1, FALSE);
1000 proto_tree_add_item(tree, hf_vnc_button_6_pos, tvb, *offset, 1, FALSE);
1001 proto_tree_add_item(tree, hf_vnc_button_7_pos, tvb, *offset, 1, FALSE);
1002 proto_tree_add_item(tree, hf_vnc_button_8_pos, tvb, *offset, 1, FALSE);
1005 proto_tree_add_item(tree, hf_vnc_pointer_x_pos, tvb, *offset, 2, FALSE);
1008 proto_tree_add_item(tree, hf_vnc_pointer_y_pos, tvb, *offset, 2, FALSE);
1014 vnc_client_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1019 if (check_col(pinfo->cinfo, COL_INFO))
1020 col_set_str(pinfo->cinfo, COL_INFO, "Client cut text");
1022 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 3, FALSE);
1023 *offset += 3; /* Skip over 3 bytes of padding */
1025 text_len = tvb_get_ntohl(tvb, *offset);
1026 proto_tree_add_item(tree, hf_vnc_client_cut_text_len, tvb, *offset, 4,
1030 proto_tree_add_item(tree, hf_vnc_client_cut_text, tvb, *offset,
1032 *offset += text_len;
1038 vnc_server_framebuffer_update(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1041 guint16 num_rects, i, width, height;
1042 guint bytes_needed = 0;
1043 gint32 encoding_type;
1045 proto_tree *vnc_rect_tree, *vnc_encoding_type_tree;
1047 if (check_col(pinfo->cinfo, COL_INFO))
1048 col_set_str(pinfo->cinfo, COL_INFO,
1049 "Server framebuffer update");
1051 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 1, FALSE);
1054 num_rects = tvb_get_ntohs(tvb, *offset);
1055 proto_tree_add_text(tree, tvb, *offset, 2, "Number of rectangles: %d",
1059 for(i = 1; i <= num_rects; i++) {
1061 VNC_BYTES_NEEDED(12);
1063 ti = proto_tree_add_text(tree, tvb, *offset, 12,
1064 "Rectangle #%d", i);
1067 proto_item_add_subtree(ti, ett_vnc_rect);
1069 proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_x_pos,
1070 tvb, *offset, 2, FALSE);
1073 proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_y_pos,
1074 tvb, *offset, 2, FALSE);
1077 proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_width,
1078 tvb, *offset, 2, FALSE);
1079 width = tvb_get_ntohs(tvb, *offset);
1082 proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_height,
1083 tvb, *offset, 2, FALSE);
1084 height = tvb_get_ntohs(tvb, *offset);
1087 ti = proto_tree_add_item(vnc_rect_tree,
1088 hf_vnc_fb_update_encoding_type,
1089 tvb, *offset, 4, FALSE);
1091 vnc_encoding_type_tree =
1092 proto_item_add_subtree(ti, ett_vnc_encoding_type);
1094 encoding_type = tvb_get_ntohl(tvb, *offset);
1097 switch(encoding_type) {
1100 bytes_needed = vnc_raw_encoding(tvb, pinfo, offset,
1101 vnc_encoding_type_tree,
1107 vnc_copyrect_encoding(tvb, pinfo, offset,
1108 vnc_encoding_type_tree,
1114 vnc_rre_encoding(tvb, pinfo, offset,
1115 vnc_encoding_type_tree,
1121 vnc_hextile_encoding(tvb, pinfo, offset,
1122 vnc_encoding_type_tree,
1128 vnc_zrle_encoding(tvb, pinfo, offset,
1129 vnc_encoding_type_tree,
1135 vnc_cursor_encoding(tvb, pinfo, offset,
1136 vnc_encoding_type_tree,
1140 case -223 : /* DesktopSize */
1142 /* There is no payload for this message type */
1149 /* Check if the routines above requested more bytes to
1150 * be desegmented. */
1151 if(bytes_needed > 0)
1152 return bytes_needed;
1160 vnc_raw_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1161 proto_tree *tree, guint16 width, guint16 height)
1163 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1166 length = width * height * bytes_per_pixel;
1167 VNC_BYTES_NEEDED(length);
1169 proto_tree_add_item(tree, hf_vnc_raw_pixel_data, tvb, *offset,
1173 return 0; /* bytes_needed */
1178 vnc_copyrect_encoding(tvbuff_t *tvb, packet_info *pinfo _U_, gint *offset,
1179 proto_tree *tree, guint16 width _U_, guint16 height _U_)
1181 proto_tree_add_item(tree, hf_vnc_copyrect_src_x_pos, tvb, *offset,
1185 proto_tree_add_item(tree, hf_vnc_copyrect_src_y_pos, tvb, *offset,
1189 return 0; /* bytes_needed */
1194 vnc_rre_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1195 proto_tree *tree, guint16 width _U_, guint16 height _U_)
1197 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1198 guint32 num_subrects, i;
1201 proto_tree *subrect_tree;
1203 VNC_BYTES_NEEDED(4);
1204 proto_tree_add_item(tree, hf_vnc_rre_num_subrects, tvb, *offset,
1206 num_subrects = tvb_get_ntohl(tvb, *offset);
1209 VNC_BYTES_NEEDED(bytes_per_pixel);
1210 proto_tree_add_item(tree, hf_vnc_rre_bg_pixel, tvb, *offset,
1211 bytes_per_pixel, FALSE);
1212 *offset += bytes_per_pixel;
1214 for(i = 1; i <= num_subrects; i++) {
1215 bytes_needed = bytes_per_pixel + 8;
1216 VNC_BYTES_NEEDED(bytes_needed);
1218 ti = proto_tree_add_text(tree, tvb, *offset, bytes_per_pixel +
1219 8, "Subrectangle #%d", i);
1221 proto_item_add_subtree(ti, ett_vnc_rre_subrect);
1223 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_pixel,
1224 tvb, *offset, bytes_per_pixel, FALSE);
1225 *offset += bytes_per_pixel;
1227 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_x_pos,
1228 tvb, *offset, 2, FALSE);
1231 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_y_pos,
1232 tvb, *offset, 2, FALSE);
1235 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_width,
1236 tvb, *offset, 2, FALSE);
1239 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_height,
1240 tvb, *offset, 2, FALSE);
1244 return 0; /* bytes_needed */
1249 vnc_hextile_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1250 proto_tree *tree, guint16 width, guint16 height)
1252 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1253 guint8 i, subencoding_mask, num_subrects, subrect_len;
1255 proto_tree *subencoding_mask_tree, *subrect_tree, *num_subrects_tree;
1258 VNC_BYTES_NEEDED(1);
1259 ti = proto_tree_add_item(tree, hf_vnc_hextile_subencoding_mask, tvb,
1261 subencoding_mask = tvb_get_guint8(tvb, *offset);
1263 subencoding_mask_tree =
1264 proto_item_add_subtree(ti, ett_vnc_hextile_subencoding_mask);
1266 proto_tree_add_item(subencoding_mask_tree,
1267 hf_vnc_hextile_raw, tvb, *offset, 1,
1269 proto_tree_add_item(subencoding_mask_tree,
1270 hf_vnc_hextile_bg, tvb, *offset, 1,
1272 proto_tree_add_item(subencoding_mask_tree,
1273 hf_vnc_hextile_fg, tvb, *offset, 1,
1275 proto_tree_add_item(subencoding_mask_tree,
1276 hf_vnc_hextile_anysubrects, tvb, *offset, 1,
1278 proto_tree_add_item(subencoding_mask_tree,
1279 hf_vnc_hextile_subrectscolored, tvb, *offset, 1,
1283 if(subencoding_mask & 0x1) { /* Raw */
1284 length = width * height * bytes_per_pixel;
1286 VNC_BYTES_NEEDED(length);
1288 proto_tree_add_item(tree, hf_vnc_hextile_raw_value, tvb,
1289 *offset, length, FALSE);
1292 if(subencoding_mask & 0x2) { /* Background Specified */
1293 proto_tree_add_item(tree, hf_vnc_hextile_bg_value,
1294 tvb, *offset, bytes_per_pixel,
1296 *offset += bytes_per_pixel;
1299 if(subencoding_mask & 0x4) { /* Foreground Specified */
1300 proto_tree_add_item(tree, hf_vnc_hextile_fg_value,
1301 tvb, *offset, bytes_per_pixel,
1303 *offset += bytes_per_pixel;
1306 if(subencoding_mask & 0x8) { /* Any Subrects */
1307 ti = proto_tree_add_item(tree,
1308 hf_vnc_hextile_num_subrects,
1311 num_subrects = tvb_get_guint8(tvb, *offset);
1315 proto_item_add_subtree(ti, ett_vnc_hextile_num_subrects);
1317 for(i = 1; i <= num_subrects; i++) {
1319 if(subencoding_mask & 0x16)
1320 subrect_len = bytes_per_pixel + 2;
1324 ti = proto_tree_add_text(num_subrects_tree, tvb,
1325 *offset, subrect_len,
1326 "Subrectangle #%d", i);
1329 proto_item_add_subtree(ti, ett_vnc_hextile_subrect);
1331 if(subencoding_mask & 0x16) {
1332 /* Subrects Colored */
1333 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_pixel_value, tvb, *offset, bytes_per_pixel, FALSE);
1335 *offset += bytes_per_pixel;
1338 proto_tree_add_item(subrect_tree,
1339 hf_vnc_hextile_subrect_x_pos, tvb, *offset, 1, FALSE);
1341 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_y_pos, tvb, *offset, 1, FALSE);
1345 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_width, tvb, *offset, 1, FALSE);
1347 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_height, tvb, *offset, 1, FALSE);
1354 return 0; /* bytes_needed */
1359 vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1360 proto_tree *tree, guint16 width, guint16 height)
1364 guint8 palette_size;
1365 guint8 bytes_per_cpixel = vnc_get_bytes_per_pixel(pinfo);
1366 gint uncomp_offset = 0;
1368 gint subencoding_type;
1369 tvbuff_t *uncomp_tvb = NULL;
1370 proto_tree *zrle_subencoding_tree;
1374 VNC_BYTES_NEEDED(4);
1375 proto_tree_add_item(tree, hf_vnc_zrle_len, tvb, *offset,
1377 data_len = tvb_get_ntohl(tvb, *offset);
1381 VNC_BYTES_NEEDED(data_len);
1383 proto_tree_add_item(tree, hf_vnc_zrle_data, tvb, *offset,
1387 uncomp_tvb = tvb_uncompress(tvb, *offset, data_len);
1389 if(uncomp_tvb != NULL) {
1390 tvb_set_child_real_data_tvbuff(tvb, uncomp_tvb);
1391 add_new_data_source(pinfo, uncomp_tvb,
1392 "Uncompressed ZRLE data");
1394 ti = proto_tree_add_item(tree, hf_vnc_zrle_subencoding,
1395 uncomp_tvb, uncomp_offset, 1, FALSE);
1396 zrle_subencoding_tree =
1397 proto_item_add_subtree(ti, ett_vnc_zrle_subencoding);
1399 proto_tree_add_item(zrle_subencoding_tree, hf_vnc_zrle_rle,
1400 uncomp_tvb, uncomp_offset, 1, FALSE);
1402 proto_tree_add_item(zrle_subencoding_tree,
1403 hf_vnc_zrle_palette_size, uncomp_tvb,
1404 uncomp_offset, 1, FALSE);
1406 subencoding_type = tvb_get_guint8(uncomp_tvb, uncomp_offset);
1407 palette_size = subencoding_type & 0x7F;
1411 if(subencoding_type == 0) { /* Raw */
1412 length = width * height * bytes_per_cpixel;
1413 VNC_BYTES_NEEDED(length);
1415 /* XXX - not working yet! */
1417 proto_tree_add_item(zrle_subencoding_tree,
1418 hf_vnc_zrle_raw, uncomp_tvb,
1419 uncomp_offset, length, FALSE);
1421 } else if(subencoding_type >= 130 && subencoding_type <= 255) {
1422 length = palette_size * bytes_per_cpixel;
1423 VNC_BYTES_NEEDED(length);
1425 proto_tree_add_item(zrle_subencoding_tree,
1426 hf_vnc_zrle_palette, uncomp_tvb,
1427 uncomp_offset, length, FALSE);
1429 /* XXX - Not complete! */
1433 proto_tree_add_text(tree, tvb, *offset, data_len,
1434 "Decompression of ZRLE data failed");
1436 #endif /* HAVE_LIBZ */
1438 *offset += data_len;
1440 return 0; /* bytes_needed */
1445 vnc_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1446 proto_tree *tree, guint16 width, guint16 height)
1448 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
1451 length = width * height * bytes_per_pixel;
1452 proto_tree_add_item(tree, hf_vnc_cursor_encoding_pixels, tvb, *offset,
1456 length = floor((width + 7)/8) * height;
1457 proto_tree_add_item(tree, hf_vnc_cursor_encoding_bitmask, tvb, *offset,
1461 return 0; /* bytes_needed */
1466 vnc_server_set_colormap_entries(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1469 guint16 number_of_colors;
1470 guint counter, bytes_needed;
1472 proto_tree *vnc_colormap_num_groups, *vnc_colormap_color_group;
1474 if (check_col(pinfo->cinfo, COL_INFO))
1475 col_set_str(pinfo->cinfo, COL_INFO,
1476 "Server set colormap entries");
1478 number_of_colors = tvb_get_ntohs(tvb, 4);
1480 bytes_needed = (number_of_colors * 6) + 6;
1481 VNC_BYTES_NEEDED(bytes_needed);
1483 ti = proto_tree_add_item(tree, hf_vnc_server_message_type, tvb,
1485 tree = proto_item_add_subtree(ti, ett_vnc_server_message_type);
1488 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 1, FALSE);
1489 *offset += 1; /* Skip over 1 byte of padding */
1491 proto_tree_add_item(tree,
1492 hf_vnc_colormap_first_color,
1493 tvb, *offset, 2, FALSE);
1496 ti = proto_tree_add_item(tree, hf_vnc_colormap_num_colors, tvb,
1498 vnc_colormap_num_groups =
1499 proto_item_add_subtree(ti, ett_vnc_colormap_num_groups);
1503 for(counter = 1; counter <= number_of_colors; counter++) {
1504 ti = proto_tree_add_text(vnc_colormap_num_groups, tvb,
1506 "Color group #%d", counter);
1508 vnc_colormap_color_group =
1509 proto_item_add_subtree(ti,
1510 ett_vnc_colormap_color_group);
1512 proto_tree_add_item(vnc_colormap_color_group,
1513 hf_vnc_colormap_red, tvb,
1517 proto_tree_add_item(vnc_colormap_color_group,
1518 hf_vnc_colormap_green, tvb,
1522 proto_tree_add_item(vnc_colormap_color_group,
1523 hf_vnc_colormap_blue, tvb,
1531 vnc_server_ring_bell(tvbuff_t *tvb _U_, packet_info *pinfo, gint *offset _U_,
1532 proto_tree *tree _U_)
1534 if (check_col(pinfo->cinfo, COL_INFO))
1535 col_set_str(pinfo->cinfo, COL_INFO, "Server ring bell on client");
1536 /* This message type has no payload... */
1541 vnc_server_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1546 if (check_col(pinfo->cinfo, COL_INFO))
1547 col_set_str(pinfo->cinfo, COL_INFO,
1550 text_len = tvb_get_ntohl(tvb, *offset);
1551 proto_tree_add_item(tree,
1552 hf_vnc_server_cut_text_len, tvb, *offset, 4,
1556 VNC_BYTES_NEEDED(text_len);
1558 proto_tree_add_item(tree, hf_vnc_server_cut_text, tvb, *offset,
1560 *offset += text_len;
1565 vnc_set_bytes_per_pixel(packet_info *pinfo, guint8 bytes_per_pixel)
1567 vnc_packet_t *per_packet_info;
1569 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
1571 if(!per_packet_info) {
1572 per_packet_info = se_alloc(sizeof(per_packet_info));
1574 per_packet_info->bytes_per_pixel = bytes_per_pixel;
1576 p_add_proto_data(pinfo->fd, proto_vnc, per_packet_info);
1582 vnc_get_bytes_per_pixel(packet_info *pinfo)
1584 vnc_packet_t *per_packet_info;
1586 per_packet_info = p_get_proto_data(pinfo->fd, proto_vnc);
1588 if(per_packet_info) {
1589 return per_packet_info->bytes_per_pixel;
1596 /* Register the protocol with Wireshark */
1598 proto_register_vnc(void)
1600 module_t *vnc_module; /* To handle our preferences */
1602 /* Setup list of header fields */
1603 static hf_register_info hf[] = {
1605 { "Padding", "vnc.padding",
1606 FT_NONE, BASE_NONE, NULL, 0x0,
1607 "Unused space", HFILL }
1610 { &hf_vnc_server_proto_ver,
1611 { "Server protocol version", "vnc.server_proto_ver",
1612 FT_STRING, BASE_NONE, NULL, 0x0,
1613 "VNC protocol version on server", HFILL }
1615 { &hf_vnc_client_proto_ver,
1616 { "Client protocol version", "vnc.client_proto_ver",
1617 FT_STRING, BASE_NONE, NULL, 0x0,
1618 "VNC protocol version on client", HFILL }
1620 { &hf_vnc_num_security_types,
1621 { "Number of security types", "vnc.num_security_types",
1622 FT_UINT8, BASE_DEC, NULL, 0x0,
1623 "Number of security (authentication) types supported by the server", HFILL }
1625 { &hf_vnc_security_type,
1626 { "Security type", "vnc.security_type",
1627 FT_UINT8, BASE_DEC, VALS(security_types_vs), 0x0,
1628 "Security types offered by the server (VNC versions => 3.007", HFILL }
1630 { &hf_vnc_server_security_type,
1631 { "Security type", "vnc.server_security_type",
1632 FT_UINT32, BASE_DEC, VALS(security_types_vs), 0x0,
1633 "Security type mandated by the server (VNC versions < 3.007)", HFILL }
1635 { &hf_vnc_client_security_type,
1636 { "Security type selected", "vnc.security_type",
1637 FT_UINT8, BASE_DEC, VALS(security_types_vs), 0x0,
1638 "Security type selected by the client", HFILL }
1640 { &hf_vnc_auth_challenge,
1641 { "Authentication challenge", "vnc.auth_challenge",
1642 FT_STRING, BASE_NONE, NULL, 0x0,
1643 "Random authentication challenge from server to client", HFILL }
1645 { &hf_vnc_auth_response,
1646 { "Authentication response", "vnc.auth_response",
1647 FT_STRING, BASE_NONE, NULL, 0x0,
1648 "Client's encrypted response to the server's authentication challenge", HFILL }
1650 { &hf_vnc_auth_result,
1651 { "Authentication result", "vnc.auth_result",
1652 FT_UINT32, BASE_DEC, VALS(auth_result_vs), 0x0,
1653 "Authentication result", HFILL }
1655 { &hf_vnc_auth_error,
1656 { "Authentication error", "vnc.auth_error",
1657 FT_STRING, BASE_NONE, NULL, 0x0,
1658 "Authentication error (present only if the authentication result is fail", HFILL }
1660 { &hf_vnc_share_desktop_flag,
1661 { "Share desktop flag", "vnc.share_desktop_flag",
1662 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x0,
1663 "Client's desire to share the server's desktop with other clients", HFILL }
1666 { "Framebuffer width", "vnc.width",
1667 FT_UINT16, BASE_DEC, NULL, 0x0,
1668 "Width of the framebuffer (screen) in pixels", HFILL }
1671 { "Framebuffer height", "vnc.width",
1672 FT_UINT16, BASE_DEC, NULL, 0x0,
1673 "Height of the framebuffer (screen) in pixels", HFILL }
1675 { &hf_vnc_server_bits_per_pixel,
1676 { "Bits per pixel", "vnc.server_bits_per_pixel",
1677 FT_UINT8, BASE_DEC, NULL, 0x0,
1678 "Number of bits used by server for each pixel value on the wire from the server", HFILL }
1680 { &hf_vnc_server_depth,
1681 { "Depth", "vnc.server_depth",
1682 FT_UINT8, BASE_DEC, NULL, 0x0,
1683 "Number of useful bits in the pixel value on server", HFILL }
1685 { &hf_vnc_server_big_endian_flag,
1686 { "Big endian flag", "vnc.server_big_endian_flag",
1687 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1688 "True if multi-byte pixels are interpreted as big endian by server", HFILL }
1690 { &hf_vnc_server_true_color_flag,
1691 { "True color flag", "vnc.server_true_color_flag",
1692 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1693 "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 }
1695 { &hf_vnc_server_red_max,
1696 { "Red maximum", "vnc.server_red_max",
1697 FT_UINT16, BASE_DEC, NULL, 0x0,
1698 "Maximum red value on server as n: 2^n - 1", HFILL }
1700 { &hf_vnc_server_green_max,
1701 { "Green maximum", "vnc.server_green_max",
1702 FT_UINT16, BASE_DEC, NULL, 0x0,
1703 "Maximum green value on server as n: 2^n - 1", HFILL }
1705 { &hf_vnc_server_blue_max,
1706 { "Blue maximum", "vnc.server_blue_max",
1707 FT_UINT16, BASE_DEC, NULL, 0x0,
1708 "Maximum blue value on server as n: 2^n - 1", HFILL }
1710 { &hf_vnc_server_red_shift,
1711 { "Red shift", "vnc.server_red_shift",
1712 FT_UINT8, BASE_DEC, NULL, 0x0,
1713 "Number of shifts needed to get the red value in a pixel to the least significant bit on the server", HFILL }
1715 { &hf_vnc_server_green_shift,
1716 { "Green shift", "vnc.server_green_shift",
1717 FT_UINT8, BASE_DEC, NULL, 0x0,
1718 "Number of shifts needed to get the green value in a pixel to the least significant bit on the server", HFILL }
1720 { &hf_vnc_server_blue_shift,
1721 { "Blue shift", "vnc.server_blue_shift",
1722 FT_UINT8, BASE_DEC, NULL, 0x0,
1723 "Number of shifts needed to get the blue value in a pixel to the least significant bit on the server", HFILL }
1725 { &hf_vnc_desktop_name_len,
1726 { "Desktop name length", "vnc.desktop_name_len",
1727 FT_UINT32, BASE_DEC, NULL, 0x0,
1728 "Length of desktop name in bytes", HFILL }
1730 { &hf_vnc_desktop_name,
1731 { "Desktop name", "vnc.desktop_name",
1732 FT_STRING, BASE_NONE, NULL, 0x0,
1733 "Name of the VNC desktop on the server", HFILL }
1735 { &hf_vnc_client_message_type,
1736 { "Client Message Type", "vnc.client_message_type",
1737 FT_UINT8, BASE_DEC, VALS(client_message_types_vs), 0x0,
1738 "Message type from client", HFILL }
1740 { &hf_vnc_client_bits_per_pixel,
1741 { "Bits per pixel", "vnc.client_bits_per_pixel",
1742 FT_UINT8, BASE_DEC, NULL, 0x0,
1743 "Number of bits used by server for each pixel value on the wire from the client", HFILL }
1745 { &hf_vnc_client_depth,
1746 { "Depth", "vnc.client_depth",
1747 FT_UINT8, BASE_DEC, NULL, 0x0,
1748 "Number of useful bits in the pixel value on client", HFILL }
1750 { &hf_vnc_client_big_endian_flag,
1751 { "Big endian flag", "vnc.client_big_endian_flag",
1752 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1753 "True if multi-byte pixels are interpreted as big endian by client", HFILL }
1755 { &hf_vnc_client_true_color_flag,
1756 { "True color flag", "vnc.client_true_color_flag",
1757 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1758 "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 }
1760 { &hf_vnc_client_red_max,
1761 { "Red maximum", "vnc.client_red_max",
1762 FT_UINT16, BASE_DEC, NULL, 0x0,
1763 "Maximum red value on client as n: 2^n - 1", HFILL }
1765 { &hf_vnc_client_green_max,
1766 { "Green maximum", "vnc.client_green_max",
1767 FT_UINT16, BASE_DEC, NULL, 0x0,
1768 "Maximum green value on client as n: 2^n - 1", HFILL }
1770 { &hf_vnc_client_blue_max,
1771 { "Blue maximum", "vnc.client_blue_max",
1772 FT_UINT16, BASE_DEC, NULL, 0x0,
1773 "Maximum blue value on client as n: 2^n - 1", HFILL }
1775 { &hf_vnc_client_red_shift,
1776 { "Red shift", "vnc.client_red_shift",
1777 FT_UINT8, BASE_DEC, NULL, 0x0,
1778 "Number of shifts needed to get the red value in a pixel to the least significant bit on the client", HFILL }
1780 { &hf_vnc_client_green_shift,
1781 { "Green shift", "vnc.client_green_shift",
1782 FT_UINT8, BASE_DEC, NULL, 0x0,
1783 "Number of shifts needed to get the green value in a pixel to the least significant bit on the client", HFILL }
1785 { &hf_vnc_client_blue_shift,
1786 { "Blue shift", "vnc.client_blue_shift",
1787 FT_UINT8, BASE_DEC, NULL, 0x0,
1788 "Number of shifts needed to get the blue value in a pixel to the least significant bit on the client", HFILL }
1791 /* Client Key Event */
1793 { "Key down", "vnc.key_down",
1794 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x0,
1795 "Specifies whether the key is being pressed or not", HFILL }
1799 FT_UINT32, BASE_HEX, VALS(keysym_vals_source), 0x0, /* keysym_vals_source is from packet-x11-keysym.h */
1800 "Key being pressed/depressed", HFILL }
1803 /* Client Pointer Event */
1804 { &hf_vnc_button_1_pos,
1805 { "Mouse button #1 position", "vnc.button_1_pos",
1806 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x1,
1807 "Whether mouse button #1 is being pressed or not", HFILL }
1809 { &hf_vnc_button_2_pos,
1810 { "Mouse button #2 position", "vnc.button_2_pos",
1811 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x2,
1812 "Whether mouse button #2 is being pressed or not", HFILL }
1814 { &hf_vnc_button_3_pos,
1815 { "Mouse button #3 position", "vnc.button_3_pos",
1816 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x4,
1817 "Whether mouse button #3 is being pressed or not", HFILL }
1819 { &hf_vnc_button_4_pos,
1820 { "Mouse button #4 position", "vnc.button_4_pos",
1821 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x8,
1822 "Whether mouse button #4 is being pressed or not", HFILL }
1824 { &hf_vnc_button_5_pos,
1825 { "Mouse button #5 position", "vnc.button_5_pos",
1826 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x10,
1827 "Whether mouse button #5 is being pressed or not", HFILL }
1829 { &hf_vnc_button_6_pos,
1830 { "Mouse button #6 position", "vnc.button_6_pos",
1831 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x20,
1832 "Whether mouse button #6 is being pressed or not", HFILL }
1834 { &hf_vnc_button_7_pos,
1835 { "Mouse button #7 position", "vnc.button_7_pos",
1836 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x40,
1837 "Whether mouse button #7 is being pressed or not", HFILL }
1839 { &hf_vnc_button_8_pos,
1840 { "Mouse button #8 position", "vnc.button_8_pos",
1841 FT_UINT8, BASE_DEC, VALS(&button_mask_vs), 0x80,
1842 "Whether mouse button #8 is being pressed or not", HFILL }
1844 { &hf_vnc_pointer_x_pos,
1845 { "X position", "vnc.pointer_x_pos",
1846 FT_UINT16, BASE_DEC, NULL, 0x0,
1847 "Position of mouse cursor on the x-axis", HFILL }
1849 { &hf_vnc_pointer_y_pos,
1850 { "Y position", "vnc.pointer_y_pos",
1851 FT_UINT16, BASE_DEC, NULL, 0x0,
1852 "Position of mouse cursor on the y-axis", HFILL }
1854 { &hf_vnc_client_set_encodings_encoding_type,
1855 { "Encoding type", "vnc.client_set_encodings_encoding_type",
1856 FT_INT32, BASE_DEC, VALS(encoding_types_vs), 0x0,
1857 "Type of encoding used to send pixel data from server to client", HFILL }
1860 /* Client Framebuffer Update Request */
1861 { &hf_vnc_update_req_incremental,
1862 { "Incremental update", "vnc.update_req_incremental",
1863 FT_BOOLEAN, BASE_DEC, NULL, 0x0,
1864 "Specifies if the client wants an incremental update instead of a full one", HFILL }
1866 { &hf_vnc_update_req_x_pos,
1867 { "X position", "vnc.update_req_x_pos",
1868 FT_UINT16, BASE_DEC, NULL, 0x0,
1869 "X position of framebuffer (screen) update requested", HFILL }
1871 { &hf_vnc_update_req_y_pos,
1872 { "Y position", "vnc.update_req_y_pos",
1873 FT_UINT16, BASE_DEC, NULL, 0x0,
1874 "Y position of framebuffer (screen) update request", HFILL }
1876 { &hf_vnc_update_req_width,
1877 { "Width", "vnc.update_req_width",
1878 FT_UINT16, BASE_DEC, NULL, 0x0,
1879 "Width of framebuffer (screen) update request", HFILL }
1881 { &hf_vnc_update_req_height,
1882 { "Height", "vnc.update_req_height",
1883 FT_UINT16, BASE_DEC, NULL, 0x0,
1884 "Height of framebuffer (screen) update request", HFILL }
1886 { &hf_vnc_client_cut_text_len,
1887 { "Length", "vnc.client_cut_text_len",
1888 FT_UINT32, BASE_DEC, NULL, 0x0,
1889 "Length of client's copy/cut text (clipboard) string in bytes", HFILL }
1891 { &hf_vnc_client_cut_text,
1892 { "Text", "vnc.client_cut_text",
1893 FT_STRING, BASE_NONE, NULL, 0x0,
1894 "Text string in the client's copy/cut text (clipboard)", HFILL }
1898 /********** Server Message Types **********/
1899 { &hf_vnc_server_message_type,
1900 { "Server Message Type", "vnc.server_message_type",
1901 FT_UINT8, BASE_DEC, VALS(server_message_types_vs), 0x0,
1902 "Message type from server", HFILL }
1905 { &hf_vnc_fb_update_x_pos,
1906 { "X position", "vnc.fb_update_x_pos",
1907 FT_UINT16, BASE_DEC, NULL, 0x0,
1908 "X position of this server framebuffer update", HFILL }
1911 { &hf_vnc_fb_update_y_pos,
1912 { "Y position", "vnc.fb_update_x_pos",
1913 FT_UINT16, BASE_DEC, NULL, 0x0,
1914 "Y position of this server framebuffer update", HFILL }
1917 { &hf_vnc_fb_update_width,
1918 { "Width", "vnc.fb_update_width",
1919 FT_UINT16, BASE_DEC, NULL, 0x0,
1920 "Width of this server framebuffer update", HFILL }
1923 { &hf_vnc_fb_update_height,
1924 { "Height", "vnc.fb_update_width",
1925 FT_UINT16, BASE_DEC, NULL, 0x0,
1926 "Height of this server framebuffer update", HFILL }
1929 { &hf_vnc_fb_update_encoding_type,
1930 { "Encoding type", "vnc.fb_update_encoding_type",
1931 FT_INT32, BASE_DEC, VALS(encoding_types_vs), 0x0,
1932 "Encoding type of this server framebuffer update", HFILL }
1935 /* Cursor encoding */
1936 { &hf_vnc_cursor_encoding_pixels,
1937 { "Cursor encoding pixels", "vnc.cursor_encoding_pixels",
1938 FT_BYTES, BASE_NONE, NULL, 0x0,
1939 "Cursor encoding pixel data", HFILL }
1942 { &hf_vnc_cursor_encoding_bitmask,
1943 { "Cursor encoding bitmask", "vnc.cursor_encoding_bitmask",
1944 FT_BYTES, BASE_NONE, NULL, 0x0,
1945 "Cursor encoding pixel bitmask", HFILL }
1949 { &hf_vnc_raw_pixel_data,
1950 { "Pixel data", "vnc.raw_pixel_data",
1951 FT_BYTES, BASE_NONE, NULL, 0x0,
1952 "Raw pixel data.", HFILL }
1955 /* CopyRect Encoding*/
1956 { &hf_vnc_copyrect_src_x_pos,
1957 { "Source x position", "vnc.copyrect_src_x_pos",
1958 FT_UINT16, BASE_DEC, NULL, 0x0,
1959 "X position of the rectangle to copy from", HFILL }
1962 { &hf_vnc_copyrect_src_y_pos,
1963 { "Source y position", "vnc.copyrect_src_y_pos",
1964 FT_UINT16, BASE_DEC, NULL, 0x0,
1965 "Y position of the rectangle to copy from", HFILL }
1969 { &hf_vnc_rre_num_subrects,
1970 { "Number of subrectangles", "vnc.rre_num_subrects",
1971 FT_UINT32, BASE_DEC, NULL, 0x0,
1972 "Number of subrectangles contained in this encoding type", HFILL }
1975 { &hf_vnc_rre_bg_pixel,
1976 { "Background pixel value", "vnc.rre_bg_pixel",
1977 FT_BYTES, BASE_NONE, NULL, 0x0,
1978 "Background pixel value", HFILL }
1981 { &hf_vnc_rre_subrect_pixel,
1982 { "Pixel value", "vnc.rre_subrect_pixel",
1983 FT_BYTES, BASE_NONE, NULL, 0x0,
1984 "Subrectangle pixel value", HFILL }
1987 { &hf_vnc_rre_subrect_x_pos,
1988 { "X position", "vnc.rre_subrect_x_pos",
1989 FT_UINT16, BASE_DEC, NULL, 0x0,
1990 "Position of this subrectangle on the x axis", HFILL }
1993 { &hf_vnc_rre_subrect_y_pos,
1994 { "Y position", "vnc.rre_subrect_y_pos",
1995 FT_UINT16, BASE_DEC, NULL, 0x0,
1996 "Position of this subrectangle on the y axis", HFILL }
1999 { &hf_vnc_rre_subrect_width,
2000 { "Width", "vnc.rre_subrect_width",
2001 FT_UINT16, BASE_DEC, NULL, 0x0,
2002 "Width of this subrectangle", HFILL }
2005 { &hf_vnc_rre_subrect_height,
2006 { "Height", "vnc.rre_subrect_height",
2007 FT_UINT16, BASE_DEC, NULL, 0x0,
2008 "Height of this subrectangle", HFILL }
2012 /* Hextile Encoding */
2013 { &hf_vnc_hextile_subencoding_mask,
2014 { "Subencoding type", "vnc.hextile_subencoding",
2015 FT_UINT8, BASE_DEC, NULL, 0x0,
2016 "Hextile subencoding type.", HFILL }
2019 { &hf_vnc_hextile_raw,
2020 { "Raw", "vnc.hextile_raw",
2021 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x1,
2022 "Raw subencoding is used in this tile", HFILL }
2025 { &hf_vnc_hextile_raw_value,
2026 { "Raw pixel values", "vnc.hextile_raw_value",
2027 FT_BYTES, BASE_NONE, NULL, 0x0,
2028 "Raw subencoding pixel values", HFILL }
2031 { &hf_vnc_hextile_bg,
2032 { "Background Specified", "vnc.hextile_bg",
2033 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x2,
2034 "Background Specified subencoding is used in this tile", HFILL }
2037 { &hf_vnc_hextile_bg_value,
2038 { "Background pixel value", "vnc.hextile_bg_value",
2039 FT_BYTES, BASE_NONE, NULL, 0x0,
2040 "Background color for this tile", HFILL }
2043 { &hf_vnc_hextile_fg,
2044 { "Foreground Specified", "vnc.hextile_fg",
2045 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x4,
2046 "Foreground Specified subencoding is used in this tile", HFILL }
2049 { &hf_vnc_hextile_fg_value,
2050 { "Foreground pixel value", "vnc.hextile_fg_value",
2051 FT_BYTES, BASE_NONE, NULL, 0x0,
2052 "Foreground color for this tile", HFILL }
2055 { &hf_vnc_hextile_anysubrects,
2056 { "Any Subrects", "vnc.hextile_anysubrects",
2057 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x8,
2058 "Any subrects subencoding is used in this tile", HFILL }
2061 { &hf_vnc_hextile_num_subrects,
2062 { "Number of subrectangles", "vnc.hextile_num_subrects",
2063 FT_UINT8, BASE_DEC, NULL, 0x0,
2064 "Number of subrectangles that follow", HFILL }
2067 { &hf_vnc_hextile_subrectscolored,
2068 { "Subrects Colored", "vnc.hextile_subrectscolored",
2069 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x10,
2070 "Subrects colored subencoding is used in this tile", HFILL }
2073 { &hf_vnc_hextile_subrect_pixel_value,
2074 { "Pixel value", "vnc.hextile_subrect_pixel_value",
2075 FT_BYTES, BASE_NONE, NULL, 0x0,
2076 "Pixel value of this subrectangle", HFILL }
2079 { &hf_vnc_hextile_subrect_x_pos,
2080 { "X position", "vnc.hextile_subrect_x_pos",
2081 FT_UINT8, BASE_DEC, NULL, 0xF0, /* Top 4 bits */
2082 "X position of this subrectangle", HFILL }
2085 { &hf_vnc_hextile_subrect_y_pos,
2086 { "Y position", "vnc.hextile_subrect_y_pos",
2087 FT_UINT8, BASE_DEC, NULL, 0xF, /* Bottom 4 bits */
2088 "Y position of this subrectangle", HFILL }
2091 { &hf_vnc_hextile_subrect_width,
2092 { "Width", "vnc.hextile_subrect_width",
2093 FT_UINT8, BASE_DEC, NULL, 0xF0, /* Top 4 bits */
2094 "Subrectangle width minus one", HFILL }
2097 { &hf_vnc_hextile_subrect_height,
2098 { "Height", "vnc.hextile_subrect_height",
2099 FT_UINT8, BASE_DEC, NULL, 0xF, /* Bottom 4 bits */
2100 "Subrectangle height minus one", HFILL }
2106 { "ZRLE compressed length", "vnc.zrle_len",
2107 FT_UINT32, BASE_DEC, NULL, 0x0,
2108 "Length of compressed ZRLE data that follows", HFILL }
2111 { &hf_vnc_zrle_subencoding,
2112 { "Subencoding type", "vnc.zrle_subencoding",
2113 FT_UINT8, BASE_DEC, NULL, 0x0,
2114 "Subencoding type byte", HFILL }
2118 { "RLE", "vnc.zrle_rle",
2119 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x80, /* Upper bit */
2120 "Specifies that data is run-length encoded", HFILL }
2123 { &hf_vnc_zrle_palette_size,
2124 { "Palette size", "vnc.zrle_palette_size",
2125 FT_UINT8, BASE_DEC, NULL, 0x7F, /* Lower 7 bits */
2126 "Palette size", HFILL }
2129 { &hf_vnc_zrle_data,
2130 { "ZRLE compressed data", "vnc.zrle_data",
2131 FT_BYTES, BASE_NONE, NULL, 0x0,
2132 "Compressed ZRLE data. Compiling with zlib support will uncompress and dissect this data", HFILL }
2136 { "Pixel values", "vnc.zrle_raw",
2137 FT_BYTES, BASE_NONE, NULL, 0x0,
2138 "Raw pixel values for this tile", HFILL }
2141 { &hf_vnc_zrle_palette,
2142 { "Palette", "vnc.zrle_palette",
2143 FT_BYTES, BASE_NONE, NULL, 0x0,
2144 "Palette pixel values", HFILL }
2147 /* Server Set Colormap Entries */
2148 { &hf_vnc_colormap_first_color,
2149 { "First color", "vnc.colormap_first_color",
2150 FT_UINT16, BASE_DEC, NULL, 0x0,
2151 "First color that should be mapped to given RGB intensities", HFILL }
2153 { &hf_vnc_colormap_num_colors,
2154 { "Number of color groups", "vnc.colormap_groups",
2155 FT_UINT16, BASE_DEC, NULL, 0x0,
2156 "Number of red/green/blue color groups", HFILL }
2158 { &hf_vnc_colormap_red,
2159 { "Red", "vnc.colormap_red",
2160 FT_UINT16, BASE_DEC, NULL, 0x0,
2161 "Red intensity", HFILL }
2163 { &hf_vnc_colormap_green,
2164 { "Green", "vnc.colormap_green",
2165 FT_UINT16, BASE_DEC, NULL, 0x0,
2166 "Green intensity", HFILL }
2168 { &hf_vnc_colormap_blue,
2169 { "Blue", "vnc.colormap_blue",
2170 FT_UINT16, BASE_DEC, NULL, 0x0,
2171 "Blue intensity", HFILL }
2174 /* Server Cut Text */
2175 { &hf_vnc_server_cut_text_len,
2176 { "Length", "vnc.server_cut_text_len",
2177 FT_UINT32, BASE_DEC, NULL, 0x0,
2178 "Length of server's copy/cut text (clipboard) string in bytes", HFILL }
2180 { &hf_vnc_server_cut_text,
2181 { "Text", "vnc.server_cut_text",
2182 FT_STRING, BASE_NONE, NULL, 0x0,
2183 "Text string in the server's copy/cut text (clipboard)", HFILL }
2187 /* Setup protocol subtree arrays */
2188 static gint *ett[] = {
2190 &ett_vnc_client_message_type,
2191 &ett_vnc_server_message_type,
2193 &ett_vnc_encoding_type,
2194 &ett_vnc_rre_subrect,
2195 &ett_vnc_hextile_subencoding_mask,
2196 &ett_vnc_hextile_num_subrects,
2197 &ett_vnc_hextile_subrect,
2198 &ett_vnc_zrle_subencoding,
2199 &ett_vnc_colormap_num_groups,
2200 &ett_vnc_colormap_color_group
2203 /* Register the protocol name and description */
2204 proto_vnc = proto_register_protocol("Virtual Network Computing",
2207 /* Required function calls to register the header fields and subtrees */
2208 proto_register_field_array(proto_vnc, hf, array_length(hf));
2209 proto_register_subtree_array(ett, array_length(ett));
2211 /* Register our preferences module */
2212 vnc_module = prefs_register_protocol(proto_vnc, proto_reg_handoff_vnc);
2214 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);
2216 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);
2221 proto_reg_handoff_vnc(void)
2223 static gboolean inited = FALSE;
2226 vnc_handle = create_dissector_handle(dissect_vnc,
2229 dissector_add("tcp.port", 5500, vnc_handle);
2230 dissector_add("tcp.port", 5501, vnc_handle);
2231 dissector_add("tcp.port", 5900, vnc_handle);
2232 dissector_add("tcp.port", 5901, vnc_handle);
2234 /* We don't register a port for the VNC HTTP server because
2235 * that simply provides a java program for download via the
2236 * HTTP protocol. The java program then connects to a standard
2242 if(vnc_preference_alternate_port != 5500 &&
2243 vnc_preference_alternate_port != 5501 &&
2244 vnc_preference_alternate_port != 5900 &&
2245 vnc_preference_alternate_port != 5901 &&
2246 vnc_preference_alternate_port != 0) {
2248 dissector_delete("tcp.port",
2249 vnc_preference_alternate_port_last,
2252 /* Save this setting to see if has changed later */
2253 vnc_preference_alternate_port_last =
2254 vnc_preference_alternate_port;
2256 /* Register the new port setting */
2257 dissector_add("tcp.port", vnc_preference_alternate_port,