2005-03-14 00:53:58 +00:00
/* packet-vnc.c
* Routines for VNC dissection ( Virtual Network Computing )
* Copyright 2005 , Ulf Lamping < ulf . lamping @ web . de >
2006-09-05 05:38:11 +00:00
* Copyright 2006 , Stephen Fisher < stephentfisher @ yahoo . com >
2005-03-14 00:53:58 +00:00
*
* $ Id $
*
2006-05-21 04:49:01 +00:00
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
2005-03-14 00:53:58 +00:00
* Copyright 1998 Gerald Combs
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
2006-10-31 01:46:59 +00:00
*
2005-03-14 00:53:58 +00:00
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2006-10-31 01:46:59 +00:00
*
2005-03-14 00:53:58 +00:00
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
/* Dissection of the VNC (Virtual Network Computing) network traffic.
*
* Several VNC implementations available , see :
* http : //www.realvnc.com/
* http : //www.tightvnc.com/
* http : //ultravnc.sourceforge.net/
* . . .
2006-10-31 01:46:59 +00:00
*
2005-03-14 00:53:58 +00:00
* The protocol itself is known as RFB - Remote Frame Buffer Protocol .
*
2006-09-05 05:38:11 +00:00
* This code is based on the protocol specification :
* http : //www.realvnc.com/docs/rfbproto.pdf
* and the RealVNC free edition source code
2005-03-14 00:53:58 +00:00
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <glib.h>
2006-09-05 05:38:11 +00:00
# include <epan/conversation.h>
# include <epan/emem.h>
2005-03-14 00:53:58 +00:00
# include <epan/packet.h>
# include <epan/prefs.h>
2006-09-05 05:38:11 +00:00
# include "packet-x11-keysym.h" /* This contains the X11 value_string "keysym_vals_source" that VNC uses */
static const value_string security_types_vs [ ] = {
{ 0 , " Invalid " } ,
{ 1 , " None " } ,
{ 2 , " VNC " } ,
{ 5 , " RA2 " } ,
{ 6 , " RA2ne " } ,
{ 16 , " Tight " } ,
{ 17 , " Ultra " } ,
{ 18 , " TLS " } ,
{ 0 , NULL }
} ;
static const value_string auth_result_vs [ ] = {
{ 0 , " OK " } ,
{ 1 , " Failed " } ,
{ 0 , NULL }
} ;
static const value_string yes_no_vs [ ] = {
{ 0 , " No " } ,
{ 1 , " Yes " } ,
{ 0 , NULL }
} ;
static const value_string client_message_types_vs [ ] = {
{ 0 , " Set Pixel Format " } ,
{ 2 , " Set Encodings " } ,
{ 3 , " Framebuffer Update Request " } ,
{ 4 , " Key Event " } ,
{ 5 , " Pointer Event " } ,
{ 6 , " Cut Text " } ,
{ 0 , NULL }
} ;
static const value_string server_message_types_vs [ ] = {
{ 0 , " Framebuffer Update " } ,
{ 1 , " Set Colormap Entries " } ,
{ 2 , " Ring Bell " } ,
{ 3 , " Cut Text " } ,
{ 0 , NULL }
} ;
static const value_string button_mask_vs [ ] = {
{ 0 , " Not pressed " } ,
{ 1 , " Pressed " } ,
{ 0 , NULL }
} ;
static const value_string encoding_types_vs [ ] = {
{ - 239 , " Cursor (pseudo) " } ,
{ - 223 , " DesktopSize (pseudo) " } ,
{ 0 , " Raw " } ,
{ 1 , " CopyRect " } ,
{ 2 , " RRE " } ,
{ 4 , " CoRRE " } ,
{ 5 , " Hextile " } ,
{ 16 , " ZRLE " } ,
{ 0 , NULL }
} ;
2005-03-14 00:53:58 +00:00
void proto_reg_handoff_vnc ( void ) ;
2006-09-05 05:38:11 +00:00
/* Variables for our preferences */
static guint vnc_preference_alternate_port = 0 ; /* An alternate port besides the default (5500, 5501, 5900, 5901) */
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
/* This is a behind the scenes variable that is not changed by the user.
* This stores last setting of the vnc_preference_alternate_port . Used to keep
* track of when the user has changed the setting so that we can delete
* and re - register with the new port number . */
static guint vnc_preference_alternate_port_last = 0 ;
2005-03-14 00:53:58 +00:00
/* Initialize the protocol and registered fields */
2006-09-05 05:38:11 +00:00
static int proto_vnc = - 1 ; /* Protocol subtree */
static int hf_vnc_padding = - 1 ;
static int hf_vnc_server_proto_ver = - 1 ;
static int hf_vnc_client_proto_ver = - 1 ;
static int hf_vnc_num_security_types = - 1 ;
static int hf_vnc_security_type = - 1 ;
static int hf_vnc_server_security_type = - 1 ;
static int hf_vnc_client_security_type = - 1 ;
static int hf_vnc_auth_challenge = - 1 ;
static int hf_vnc_auth_response = - 1 ;
static int hf_vnc_auth_result = - 1 ;
static int hf_vnc_auth_error = - 1 ;
static int hf_vnc_share_desktop_flag = - 1 ;
static int hf_vnc_width = - 1 ;
static int hf_vnc_height = - 1 ;
static int hf_vnc_server_bits_per_pixel = - 1 ;
static int hf_vnc_server_depth = - 1 ;
static int hf_vnc_server_big_endian_flag = - 1 ;
static int hf_vnc_server_true_color_flag = - 1 ;
static int hf_vnc_server_red_max = - 1 ;
static int hf_vnc_server_green_max = - 1 ;
static int hf_vnc_server_blue_max = - 1 ;
static int hf_vnc_server_red_shift = - 1 ;
static int hf_vnc_server_green_shift = - 1 ;
static int hf_vnc_server_blue_shift = - 1 ;
static int hf_vnc_desktop_name = - 1 ;
static int hf_vnc_desktop_name_len = - 1 ;
/********** Client Message Types **********/
static int hf_vnc_client_message_type = - 1 ; /* A subtree under VNC */
static int hf_vnc_client_bits_per_pixel = - 1 ;
static int hf_vnc_client_depth = - 1 ;
static int hf_vnc_client_big_endian_flag = - 1 ;
static int hf_vnc_client_true_color_flag = - 1 ;
static int hf_vnc_client_red_max = - 1 ;
static int hf_vnc_client_green_max = - 1 ;
static int hf_vnc_client_blue_max = - 1 ;
static int hf_vnc_client_red_shift = - 1 ;
static int hf_vnc_client_green_shift = - 1 ;
static int hf_vnc_client_blue_shift = - 1 ;
/* Client Key Event */
static int hf_vnc_key_down = - 1 ;
static int hf_vnc_key = - 1 ;
/* Client Pointer Event */
static int hf_vnc_button_1_pos = - 1 ;
static int hf_vnc_button_2_pos = - 1 ;
static int hf_vnc_button_3_pos = - 1 ;
static int hf_vnc_button_4_pos = - 1 ;
static int hf_vnc_button_5_pos = - 1 ;
static int hf_vnc_button_6_pos = - 1 ;
static int hf_vnc_button_7_pos = - 1 ;
static int hf_vnc_button_8_pos = - 1 ;
static int hf_vnc_pointer_x_pos = - 1 ;
static int hf_vnc_pointer_y_pos = - 1 ;
/* Client Framebuffer Update Request */
static int hf_vnc_update_req_incremental = - 1 ;
static int hf_vnc_update_req_x_pos = - 1 ;
static int hf_vnc_update_req_y_pos = - 1 ;
static int hf_vnc_update_req_width = - 1 ;
static int hf_vnc_update_req_height = - 1 ;
/* Client Set Encodings */
static int hf_vnc_client_set_encodings_encoding_type = - 1 ;
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
/* Client Cut Text */
static int hf_vnc_client_cut_text_len = - 1 ;
static int hf_vnc_client_cut_text = - 1 ;
/********** Server Message Types **********/
static int hf_vnc_server_message_type = - 1 ; /* Subtree */
/* Server Set Colormap Entries */
static int hf_vnc_colormap_first_color = - 1 ;
static int hf_vnc_colormap_num_colors = - 1 ;
static int hf_vnc_colormap_red = - 1 ;
static int hf_vnc_colormap_green = - 1 ;
static int hf_vnc_colormap_blue = - 1 ;
/* Server Cut Text */
static int hf_vnc_server_cut_text_len = - 1 ;
static int hf_vnc_server_cut_text = - 1 ;
/********** End of Server Message Types **********/
static gboolean vnc_preference_desegment = TRUE ;
2005-03-14 00:53:58 +00:00
/* Initialize the subtree pointers */
static gint ett_vnc = - 1 ;
2006-09-05 05:38:11 +00:00
static gint ett_vnc_client_message_type = - 1 ;
static gint ett_vnc_server_message_type = - 1 ;
static gint ett_vnc_colormap_num_groups = - 1 ;
static gint ett_vnc_colormap_color_group = - 1 ;
static dissector_handle_t vnc_handle ;
/* Initialize the structure that will be tied to each conversation. */
typedef struct {
/* Packet numbers for the first 9 packets of each conversation. */
guint32 first_packet_number , second_packet_number , third_packet_number , forth_packet_number , fifth_packet_number ,
sixth_packet_number , seventh_packet_number , eighth_packet_number , ninth_packet_number ;
gdouble server_proto_ver , client_proto_ver ;
} vnc_hash_entry_t ;
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
/* Code to dissect the packets */
2005-03-14 00:53:58 +00:00
static void
dissect_vnc ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
{
2006-09-05 05:38:11 +00:00
guint8 num_security_types , message_type ;
guint16 number_of_encodings = 0 ; /* Part of: Client Set Encodings */
guint16 number_of_colors ; /* Part of: Server Set Colormap Entries */
guint32 text_len ; /* Part of: Client Cut Text & Server Cut Text */
guint32 auth_result , desktop_name_len ;
guint offset = 0 , counter ;
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
/* Set up structures needed to add the protocol subtree and manage it */
proto_item * ti = NULL ;
proto_tree * vnc_tree = NULL , * vnc_client_message_type_tree , * vnc_server_message_type_tree , * vnc_colormap_num_groups ,
* vnc_colormap_color_group ;
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
conversation_t * conversation ;
vnc_hash_entry_t * hash_info ;
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
conversation = find_conversation ( pinfo - > fd - > num , & pinfo - > src , & pinfo - > dst , pinfo - > ptype , pinfo - > srcport , pinfo - > destport , 0 ) ;
if ( ! conversation ) { /* Conversation does not exist yet - create it */
conversation = conversation_new ( pinfo - > fd - > num , & pinfo - > src , & pinfo - > dst ,
pinfo - > ptype , pinfo - > srcport , pinfo - > destport , 0 ) ;
}
2006-10-31 01:46:59 +00:00
/* Retrieve information from conversation
2006-09-05 05:38:11 +00:00
* or add it if it isn ' t there yet */
hash_info = conversation_get_proto_data ( conversation , proto_vnc ) ;
if ( ! hash_info ) {
hash_info = se_alloc ( sizeof ( vnc_hash_entry_t ) ) ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
/* We must be on the first packet now */
hash_info - > first_packet_number = pinfo - > fd - > num ;
/* The rest of these values will be set as we come across each packet */
hash_info - > second_packet_number = 0 ;
hash_info - > third_packet_number = 0 ;
hash_info - > forth_packet_number = 0 ;
hash_info - > fifth_packet_number = 0 ;
hash_info - > sixth_packet_number = 0 ;
hash_info - > seventh_packet_number = 0 ;
hash_info - > eighth_packet_number = 0 ;
hash_info - > ninth_packet_number = 0 ;
hash_info - > server_proto_ver = 0.0 ;
hash_info - > client_proto_ver = 0.0 ;
conversation_add_proto_data ( conversation , proto_vnc , hash_info ) ;
}
/* Store the number of the first nine packets of this conversation as we reach them for the first time.
* These are the packets that contain connection setup data and do not have a message type identifier .
* The packets after the ninth one do contain message type identifiers . */
if ( ! hash_info - > second_packet_number & & pinfo - > fd - > num > hash_info - > first_packet_number ) {
/* We're on the second packet of the conversation */
hash_info - > second_packet_number = pinfo - > fd - > num ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
} else if ( hash_info - > second_packet_number & & ! hash_info - > third_packet_number & & pinfo - > fd - > num > hash_info - > second_packet_number ) {
/* We're on the third packet of the conversation */
hash_info - > third_packet_number = pinfo - > fd - > num ;
} else if ( hash_info - > third_packet_number & & ! hash_info - > forth_packet_number & & pinfo - > fd - > num > hash_info - > third_packet_number ) {
/* We're on the forth packet of the conversation */
hash_info - > forth_packet_number = pinfo - > fd - > num ;
} else if ( hash_info - > forth_packet_number & & ! hash_info - > fifth_packet_number & & pinfo - > fd - > num > hash_info - > forth_packet_number ) {
/* We're on the fifth packet of the conversation */
hash_info - > fifth_packet_number = pinfo - > fd - > num ;
} else if ( hash_info - > fifth_packet_number & & ! hash_info - > sixth_packet_number & & pinfo - > fd - > num > hash_info - > fifth_packet_number ) {
/* We're on the sixth packet of the conversation */
hash_info - > sixth_packet_number = pinfo - > fd - > num ;
} else if ( hash_info - > sixth_packet_number & & ! hash_info - > seventh_packet_number & & pinfo - > fd - > num > hash_info - > sixth_packet_number ) {
/* We're on the seventh packet of the conversation */
hash_info - > seventh_packet_number = pinfo - > fd - > num ;
} else if ( hash_info - > seventh_packet_number & & ! hash_info - > eighth_packet_number & & pinfo - > fd - > num > hash_info - > seventh_packet_number )
{
/* We're on the eighth packet of the conversation */
hash_info - > eighth_packet_number = pinfo - > fd - > num ;
} else if ( hash_info - > eighth_packet_number & & ! hash_info - > ninth_packet_number & & pinfo - > fd - > num > hash_info - > eighth_packet_number ) {
/* We're on the ninth packet of the conversation */
hash_info - > ninth_packet_number = pinfo - > fd - > num ;
}
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
/* Make entries in Protocol column and Info column on summary display */
2006-10-31 01:46:59 +00:00
if ( check_col ( pinfo - > cinfo , COL_PROTOCOL ) )
2005-03-14 00:53:58 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " VNC " ) ;
2006-09-05 05:38:11 +00:00
/* First, clear the info column */
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_clear ( pinfo - > cinfo , COL_INFO ) ;
/* create display subtree for the protocol */
if ( tree ) {
ti = proto_tree_add_item ( tree , proto_vnc , tvb , 0 , - 1 , FALSE ) ;
vnc_tree = proto_item_add_subtree ( ti , ett_vnc ) ;
2005-03-14 00:53:58 +00:00
}
2006-09-05 05:38:11 +00:00
offset = 0 ; /* Start at the beginning of the VNC protocol data */
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
/* Server Protocol Version */
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
if ( pinfo - > fd - > num = = hash_info - > first_packet_number ) {
proto_tree_add_item ( vnc_tree , hf_vnc_server_proto_ver , tvb , 4 , 7 , FALSE ) ;
hash_info - > server_proto_ver = g_strtod ( tvb_get_ephemeral_string ( tvb , 4 , 7 ) , NULL ) ;
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
2006-10-31 01:46:59 +00:00
col_add_fstr ( pinfo - > cinfo , COL_INFO , " Server protocol version: %s " , tvb_format_text ( tvb , 4 , 7 ) ) ;
2006-09-05 05:38:11 +00:00
}
/* Second Packet = Client Protocol Version */
else if ( pinfo - > fd - > num = = hash_info - > second_packet_number ) {
proto_tree_add_item ( vnc_tree , hf_vnc_client_proto_ver , tvb , 4 , 7 , FALSE ) ;
hash_info - > client_proto_ver = g_strtod ( tvb_get_ephemeral_string ( tvb , 4 , 7 ) , NULL ) ;
2006-10-31 01:46:59 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_add_fstr ( pinfo - > cinfo , COL_INFO , " Client protocol version: %s " , tvb_format_text ( tvb , 4 , 7 ) ) ;
2006-09-05 05:38:11 +00:00
}
/* Security Types Supported */
else if ( pinfo - > fd - > num = = hash_info - > third_packet_number ) {
2006-10-31 01:46:59 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
2006-09-05 05:38:11 +00:00
col_set_str ( pinfo - > cinfo , COL_INFO , " Security types supported " ) ;
/* We're checking against the client protocol version because the client is the final decider
* on which version to use after the server offers the version it supports . */
if ( hash_info - > client_proto_ver > = 3.007 ) {
proto_tree_add_item ( vnc_tree , hf_vnc_num_security_types , tvb , offset , 1 , FALSE ) ;
num_security_types = tvb_get_guint8 ( tvb , offset ) ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
for ( offset = 1 ; offset < = num_security_types ; offset + + ) {
proto_tree_add_item ( vnc_tree , hf_vnc_security_type , tvb , offset , 1 , FALSE ) ;
}
} else {
/* Version < 3.007: The server decides the authentication time for us to use */
proto_tree_add_item ( vnc_tree , hf_vnc_server_security_type , tvb , offset , 4 , FALSE ) ;
}
}
/* Authentication type selected by client */
/* This field is skipped by versions < 3.007 so the packet number is off on each if statement below */
else if ( hash_info - > client_proto_ver > = 3.007 & & pinfo - > fd - > num = = hash_info - > forth_packet_number ) {
2006-10-31 01:46:59 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
2006-09-05 05:38:11 +00:00
col_set_str ( pinfo - > cinfo , COL_INFO , " Authentication type selected by client " ) ;
proto_tree_add_item ( vnc_tree , hf_vnc_client_security_type , tvb , offset , 1 , FALSE ) ;
}
/* Authentication challenge from server */
else if ( ( hash_info - > client_proto_ver > = 3.007 & & pinfo - > fd - > num = = hash_info - > fifth_packet_number ) | |
( hash_info - > client_proto_ver < 3.007 & & pinfo - > fd - > num = = hash_info - > forth_packet_number ) ) {
2006-10-31 01:46:59 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
2006-09-05 05:38:11 +00:00
col_set_str ( pinfo - > cinfo , COL_INFO , " Authentication challenge from server " ) ;
proto_tree_add_item ( vnc_tree , hf_vnc_auth_challenge , tvb , offset , 16 , FALSE ) ;
}
/* Authentication response from client */
else if ( ( hash_info - > client_proto_ver > = 3.007 & & pinfo - > fd - > num = = hash_info - > sixth_packet_number ) | |
( hash_info - > client_proto_ver < 3.007 & & pinfo - > fd - > num = = hash_info - > fifth_packet_number ) ) {
2006-10-31 01:46:59 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
2006-09-05 05:38:11 +00:00
col_set_str ( pinfo - > cinfo , COL_INFO , " Authentication response from client " ) ;
proto_tree_add_item ( vnc_tree , hf_vnc_auth_response , tvb , offset , 16 , FALSE ) ;
}
/* Authentication result */
else if ( ( hash_info - > client_proto_ver > = 3.007 & & pinfo - > fd - > num = = hash_info - > seventh_packet_number ) | |
( hash_info - > client_proto_ver < 3.007 & & pinfo - > fd - > num = = hash_info - > sixth_packet_number ) ) {
2006-10-31 01:46:59 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
2006-09-05 05:38:11 +00:00
col_set_str ( pinfo - > cinfo , COL_INFO , " Authentication result " ) ;
proto_tree_add_item ( vnc_tree , hf_vnc_auth_result , tvb , offset , 4 , FALSE ) ;
auth_result = tvb_get_ntohl ( tvb , offset ) ; /* 32-bit big endian accessor */
offset + = 4 ;
if ( hash_info - > client_proto_ver > = 3.007 & & auth_result = = 1 ) { /* 1 = failed */
text_len = tvb_get_ntohl ( tvb , offset ) ;
proto_tree_add_text ( vnc_tree , tvb , offset , 4 , " Length of authentication error: %d " , text_len ) ;
offset + = 4 ;
proto_tree_add_item ( vnc_tree , hf_vnc_auth_error , tvb , offset , text_len , FALSE ) ;
offset + = text_len ;
}
}
/* Share desktop */
else if ( ( hash_info - > client_proto_ver > = 3.007 & & pinfo - > fd - > num = = hash_info - > eighth_packet_number ) | |
( hash_info - > client_proto_ver < 3.007 & & pinfo - > fd - > num = = hash_info - > seventh_packet_number ) ) {
2006-10-31 01:46:59 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
2006-09-05 05:38:11 +00:00
col_set_str ( pinfo - > cinfo , COL_INFO , " Share desktop flag " ) ;
proto_tree_add_item ( vnc_tree , hf_vnc_share_desktop_flag , tvb , offset , 1 , FALSE ) ;
}
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
/* Various parameters for the frame buffer (screen) from the server */
else if ( ( hash_info - > client_proto_ver > = 3.007 & & pinfo - > fd - > num = = hash_info - > ninth_packet_number ) | |
( hash_info - > client_proto_ver < 3.007 & & pinfo - > fd - > num = = hash_info - > eighth_packet_number ) ) {
2006-10-31 01:46:59 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
2006-09-05 05:38:11 +00:00
col_set_str ( pinfo - > cinfo , COL_INFO , " Server framebuffer parameters " ) ;
proto_tree_add_item ( vnc_tree , hf_vnc_width , tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_tree , hf_vnc_height , tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
proto_tree_add_item ( vnc_tree , hf_vnc_server_bits_per_pixel , tvb , offset , 1 , FALSE ) ;
offset + = 1 ;
proto_tree_add_item ( vnc_tree , hf_vnc_server_depth , tvb , offset , 1 , FALSE ) ;
offset + = 1 ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_tree , hf_vnc_server_big_endian_flag , tvb , offset , 1 , FALSE ) ;
offset + = 1 ;
proto_tree_add_item ( vnc_tree , hf_vnc_server_true_color_flag , tvb , offset , 1 , FALSE ) ;
offset + = 1 ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_tree , hf_vnc_server_red_max , tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
proto_tree_add_item ( vnc_tree , hf_vnc_server_green_max , tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
proto_tree_add_item ( vnc_tree , hf_vnc_server_blue_max , tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
proto_tree_add_item ( vnc_tree , hf_vnc_server_red_shift , tvb , offset , 1 , FALSE ) ;
offset + = 1 ;
proto_tree_add_item ( vnc_tree , hf_vnc_server_green_shift , tvb , offset , 1 , FALSE ) ;
offset + = 1 ;
proto_tree_add_item ( vnc_tree , hf_vnc_server_blue_shift , tvb , offset , 1 , FALSE ) ;
offset + = 1 ;
proto_tree_add_item ( vnc_tree , hf_vnc_padding , tvb , offset , 3 , FALSE ) ;
offset + = 3 ; /* Skip over 3 bytes of padding */
if ( tvb_length_remaining ( tvb , offset ) > 0 ) { /* Sometimes the desktop name & length is skipped */
proto_tree_add_item ( vnc_tree , hf_vnc_desktop_name_len , tvb , offset , 4 , FALSE ) ;
desktop_name_len = tvb_get_ntohl ( tvb , offset ) ; /* 32-bit big endian accessor */
offset + = 4 ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_tree , hf_vnc_desktop_name , tvb , offset , desktop_name_len , FALSE ) ;
}
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
}
/* All packets beyond #9 */
else {
if ( pinfo - > destport = = 5500 | | pinfo - > destport = = 5501 | | pinfo - > destport = = 5900 | |
pinfo - > destport = = 5901 | | pinfo - > destport = = vnc_preference_alternate_port ) { /* From client to server */
message_type = tvb_get_guint8 ( tvb , offset ) ;
switch ( message_type ) {
case 0 : /* Client Set Pixel Format */
2006-10-31 01:46:59 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
2006-09-05 05:38:11 +00:00
col_set_str ( pinfo - > cinfo , COL_INFO , " Client set pixel format " ) ;
ti = proto_tree_add_item ( vnc_tree , hf_vnc_client_message_type , tvb , offset , 1 , FALSE ) ;
vnc_client_message_type_tree = proto_item_add_subtree ( ti , ett_vnc_client_message_type ) ;
2006-10-31 01:46:59 +00:00
offset + = 1 ;
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_padding , tvb , offset , 3 , FALSE ) ;
offset + = 3 ; /* Skip over 3 bytes of padding */
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_client_bits_per_pixel , tvb , offset , 1 ,
FALSE ) ;
offset + = 1 ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_client_depth , tvb , offset , 1 , FALSE ) ;
offset + = 1 ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_client_big_endian_flag , tvb , offset , 1 ,
FALSE ) ;
offset + = 1 ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_client_true_color_flag , tvb , offset , 1 ,
FALSE ) ;
offset + = 1 ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_client_red_max , tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_client_green_max , tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_client_blue_max , tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_client_red_shift , tvb , offset , 1 , FALSE ) ;
offset + = 1 ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_client_green_shift , tvb , offset , 1 , FALSE ) ;
offset + = 1 ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_client_blue_shift , tvb , offset , 1 , FALSE ) ;
offset + = 1 ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_padding , tvb , offset , 3 , FALSE ) ;
offset + = 3 ; /* Skip over 3 bytes of padding */
break ;
case 2 : /* Client Set Encodings */
2006-10-31 01:46:59 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
2006-09-05 05:38:11 +00:00
col_set_str ( pinfo - > cinfo , COL_INFO , " Client set encodings " ) ;
ti = proto_tree_add_item ( vnc_tree , hf_vnc_client_message_type , tvb , offset , 1 , FALSE ) ;
vnc_client_message_type_tree = proto_item_add_subtree ( ti , ett_vnc_client_message_type ) ;
offset + = 1 ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_padding , tvb , offset , 1 , FALSE ) ;
offset + = 1 ; /* Skip over 1 byte of padding */
number_of_encodings = tvb_get_ntohs ( tvb , offset ) ;
proto_tree_add_text ( vnc_client_message_type_tree , tvb , offset , 2 ,
" Number of encodings: %d " , number_of_encodings ) ;
offset + = 2 ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
for ( counter = 1 ; counter < = number_of_encodings ; counter + + ) {
proto_tree_add_item ( vnc_client_message_type_tree ,
hf_vnc_client_set_encodings_encoding_type , tvb , offset , 4 , FALSE ) ;
offset + = 4 ;
}
break ;
case 3 : /* Client Framebuffer Update Request */
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_set_str ( pinfo - > cinfo , COL_INFO , " Client framebuffer update request " ) ;
ti = proto_tree_add_item ( vnc_tree , hf_vnc_client_message_type , tvb , offset , 1 , FALSE ) ;
vnc_client_message_type_tree = proto_item_add_subtree ( ti , ett_vnc_client_message_type ) ;
offset + = 1 ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_update_req_incremental ,
tvb , offset , 1 , FALSE ) ;
offset + = 1 ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_update_req_x_pos ,
tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_update_req_y_pos ,
tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_update_req_width , tvb ,
offset , 2 , FALSE ) ;
offset + = 2 ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_update_req_height , tvb ,
offset , 2 , FALSE ) ;
offset + = 2 ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
break ;
case 4 : /* Client Key Event */
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_set_str ( pinfo - > cinfo , COL_INFO , " Client key event " ) ;
ti = proto_tree_add_item ( vnc_tree , hf_vnc_client_message_type , tvb , offset , 1 , FALSE ) ;
vnc_client_message_type_tree = proto_item_add_subtree ( ti , ett_vnc_client_message_type ) ;
offset + = 1 ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_key_down , tvb , offset , 1 , FALSE ) ;
offset + = 1 ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_padding , tvb , offset , 2 , FALSE ) ;
offset + = 2 ; /* Skip over 2 bytes of padding */
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_key , tvb , offset , 4 , FALSE ) ;
offset + = 4 ;
break ;
case 5 : /* Client Pointer Event */
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_set_str ( pinfo - > cinfo , COL_INFO , " Client pointer event " ) ;
ti = proto_tree_add_item ( vnc_tree , hf_vnc_client_message_type , tvb , offset , 1 , FALSE ) ;
vnc_client_message_type_tree = proto_item_add_subtree ( ti , ett_vnc_client_message_type ) ;
offset + = 1 ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_button_1_pos , tvb ,
offset , 1 , FALSE ) ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_button_2_pos , tvb ,
offset , 1 , FALSE ) ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_button_3_pos , tvb ,
offset , 1 , FALSE ) ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_button_4_pos , tvb ,
offset , 1 , FALSE ) ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_button_5_pos , tvb ,
offset , 1 , FALSE ) ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_button_6_pos , tvb ,
offset , 1 , FALSE ) ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_button_7_pos , tvb ,
offset , 1 , FALSE ) ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_button_8_pos , tvb ,
offset , 1 , FALSE ) ;
offset + = 1 ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_pointer_x_pos , tvb ,
offset , 2 , FALSE ) ;
offset + = 2 ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_pointer_y_pos , tvb ,
offset , 2 , FALSE ) ;
offset + = 2 ;
break ;
case 6 : /* Client Cut Text */
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_set_str ( pinfo - > cinfo , COL_INFO , " Client cut text " ) ;
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
ti = proto_tree_add_item ( vnc_tree , hf_vnc_client_message_type , tvb , offset , 1 , FALSE ) ;
vnc_client_message_type_tree = proto_item_add_subtree ( ti , ett_vnc_client_message_type ) ;
offset + = 1 ;
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_padding , tvb , offset , 3 , FALSE ) ;
offset + = 3 ; /* Skip over 3 bytes of padding */
text_len = tvb_get_ntohl ( tvb , offset ) ; /* 32-bit big endian accessor */
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_client_cut_text_len , tvb , offset , 4 ,
FALSE ) ;
offset + = 4 ;
proto_tree_add_item ( vnc_client_message_type_tree , hf_vnc_client_cut_text , tvb , offset , text_len ,
FALSE ) ;
offset + = text_len ;
break ;
default :
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_append_str ( pinfo - > cinfo , COL_INFO , " Unknown client message type " ) ;
2006-10-31 01:46:59 +00:00
proto_tree_add_text ( vnc_tree , tvb , 0 , - 1 , " Unknown client message type " ) ;
2006-09-05 05:38:11 +00:00
break ;
}
} else { /* Packet is going from server to client */
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
message_type = tvb_get_guint8 ( tvb , offset ) ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
switch ( message_type ) {
case 0 : /* Server Framebuffer Update */
/* XXX - This message type is not fully dissected yet */
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_set_str ( pinfo - > cinfo , COL_INFO , " Server framebuffer update " ) ;
ti = proto_tree_add_item ( vnc_tree , hf_vnc_server_message_type , tvb , offset , 1 , FALSE ) ;
vnc_server_message_type_tree = proto_item_add_subtree ( ti , ett_vnc_server_message_type ) ;
offset + = 1 ;
proto_tree_add_text ( vnc_server_message_type_tree , tvb , offset , - 1 ,
" Data " ) ;
break ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
case 1 : /* Server Set Colormap Entries */
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_set_str ( pinfo - > cinfo , COL_INFO , " Server set colormap entries " ) ;
number_of_colors = tvb_get_ntohs ( tvb , 4 ) ;
if ( vnc_preference_desegment & & pinfo - > can_desegment & &
tvb_length_remaining ( tvb , offset ) < ( number_of_colors * 6 ) + 6 ) {
pinfo - > desegment_offset = 0 ;
pinfo - > desegment_len = ( number_of_colors * 6 ) + 6 - tvb_length_remaining ( tvb , offset ) ;
return ;
}
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
ti = proto_tree_add_item ( vnc_tree , hf_vnc_server_message_type , tvb , offset , 1 , FALSE ) ;
vnc_server_message_type_tree = proto_item_add_subtree ( ti , ett_vnc_server_message_type ) ;
offset + = 1 ;
proto_tree_add_item ( vnc_server_message_type_tree , hf_vnc_padding , tvb , offset , 1 , FALSE ) ;
offset + = 1 ; /* Skip over 1 byte of padding */
proto_tree_add_item ( vnc_server_message_type_tree ,
hf_vnc_colormap_first_color , tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
ti = proto_tree_add_item ( vnc_server_message_type_tree , hf_vnc_colormap_num_colors , tvb ,
offset , 2 , FALSE ) ;
vnc_colormap_num_groups = proto_item_add_subtree ( ti , ett_vnc_colormap_num_groups ) ;
offset + = 2 ;
for ( counter = 1 ; counter < = number_of_colors ; counter + + ) {
2006-10-31 01:46:59 +00:00
ti = proto_tree_add_text ( vnc_colormap_num_groups , tvb , offset , 6 ,
2006-09-05 05:38:11 +00:00
" Color group #%d " , counter ) ;
vnc_colormap_color_group = proto_item_add_subtree ( ti , ett_vnc_colormap_color_group ) ;
proto_tree_add_item ( vnc_colormap_color_group ,
hf_vnc_colormap_red , tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
proto_tree_add_item ( vnc_colormap_color_group ,
hf_vnc_colormap_green , tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
proto_tree_add_item ( vnc_colormap_color_group ,
hf_vnc_colormap_blue , tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
}
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
break ;
case 2 : /* Server Ring Bell (on client) */
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_set_str ( pinfo - > cinfo , COL_INFO , " Server ring bell on client " ) ;
ti = proto_tree_add_item ( vnc_tree , hf_vnc_server_message_type , tvb , offset , 1 , FALSE ) ;
vnc_server_message_type_tree = proto_item_add_subtree ( ti , ett_vnc_server_message_type ) ;
offset + = 1 ;
/* This message type has no payload... */
break ;
case 3 : /* Server Cut Text */
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_set_str ( pinfo - > cinfo , COL_INFO , " Server cut text " ) ;
ti = proto_tree_add_item ( vnc_tree , hf_vnc_server_message_type , tvb , offset , 1 , FALSE ) ;
vnc_server_message_type_tree = proto_item_add_subtree ( ti , ett_vnc_server_message_type ) ;
offset + = 1 ;
proto_tree_add_item ( vnc_server_message_type_tree , hf_vnc_padding , tvb , offset , 3 , FALSE ) ;
offset + = 3 ; /* Skip over 3 bytes of padding */
text_len = tvb_get_ntohl ( tvb , offset ) ; /* 32-bit big endian accessor */
proto_tree_add_item ( vnc_server_message_type_tree , hf_vnc_server_cut_text_len , tvb , offset , 4 ,
FALSE ) ;
offset + = 4 ;
2006-10-03 05:48:47 +00:00
if ( vnc_preference_desegment & & pinfo - > can_desegment & &
tvb_length_remaining ( tvb , offset ) < text_len ) {
pinfo - > desegment_offset = 0 ;
pinfo - > desegment_len = text_len - tvb_length_remaining ( tvb , offset ) ;
return ;
}
2006-09-05 05:38:11 +00:00
proto_tree_add_item ( vnc_server_message_type_tree , hf_vnc_server_cut_text , tvb , offset , text_len ,
FALSE ) ;
offset + = text_len ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
break ;
2006-10-31 01:46:59 +00:00
default :
2006-09-05 05:38:11 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
col_append_str ( pinfo - > cinfo , COL_INFO , " Server framebuffer update (continuation) " ) ;
proto_tree_add_text ( vnc_tree , tvb , 0 , - 1 , " Server framebuffer update data (continuation) " ) ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
break ;
}
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
}
}
}
/* Register the protocol with Wireshark */
2005-03-14 00:53:58 +00:00
void
proto_register_vnc ( void )
2006-10-31 01:46:59 +00:00
{
2006-09-05 05:38:11 +00:00
module_t * vnc_module ; /* To handle our preferences */
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
/* Setup list of header fields */
static hf_register_info hf [ ] = {
{ & hf_vnc_padding ,
{ " Padding " , " vnc.padding " ,
FT_NONE , BASE_NONE , NULL , 0x0 ,
" Unused space " , HFILL }
} ,
{ & hf_vnc_server_proto_ver ,
{ " Server protocol version " , " vnc.server_proto_ver " ,
2006-10-31 01:46:59 +00:00
FT_STRING , BASE_NONE , NULL , 0x0 ,
2006-09-05 05:38:11 +00:00
" VNC protocol version on server " , HFILL }
} ,
{ & hf_vnc_client_proto_ver ,
{ " Client protocol version " , " vnc.client_proto_ver " ,
FT_STRING , BASE_NONE , NULL , 0x0 ,
" VNC protocol version on client " , HFILL }
} ,
{ & hf_vnc_num_security_types ,
{ " Number of security types " , " vnc.num_security_types " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" Number of security (authentication) types supported by the server " , HFILL }
} ,
{ & hf_vnc_security_type ,
{ " Security type " , " vnc.security_type " ,
FT_UINT8 , BASE_DEC , VALS ( security_types_vs ) , 0x0 ,
" Security types offered by the server (VNC versions => 3.007 " , HFILL }
} ,
{ & hf_vnc_server_security_type ,
{ " Security type " , " vnc.server_security_type " ,
FT_UINT32 , BASE_DEC , VALS ( security_types_vs ) , 0x0 ,
" Security type mandated by the server (VNC versions < 3.007) " , HFILL }
} ,
{ & hf_vnc_client_security_type ,
{ " Security type selected " , " vnc.security_type " ,
FT_UINT8 , BASE_DEC , VALS ( security_types_vs ) , 0x0 ,
" Security type selected by the client " , HFILL }
} ,
{ & hf_vnc_auth_challenge ,
{ " Authentication challenge " , " vnc.auth_challenge " ,
FT_STRING , BASE_NONE , NULL , 0x0 ,
" Random authentication challenge from server to client " , HFILL }
} ,
{ & hf_vnc_auth_response ,
{ " Authentication response " , " vnc.auth_response " ,
FT_STRING , BASE_NONE , NULL , 0x0 ,
" Client's encrypted response to the server's authentication challenge " , HFILL }
} ,
{ & hf_vnc_auth_result ,
{ " Authentication result " , " vnc.auth_result " ,
FT_UINT32 , BASE_DEC , VALS ( auth_result_vs ) , 0x0 ,
" Authentication result " , HFILL }
} ,
{ & hf_vnc_auth_error ,
{ " Authentication error " , " vnc.auth_error " ,
FT_STRING , BASE_NONE , NULL , 0x0 ,
" Authentication error (present only if the authentication result is fail " , HFILL }
} ,
{ & hf_vnc_share_desktop_flag ,
{ " Share desktop flag " , " vnc.share_desktop_flag " ,
FT_UINT8 , BASE_DEC , VALS ( yes_no_vs ) , 0x0 ,
" Client's desire to share the server's desktop with other clients " , HFILL }
} ,
{ & hf_vnc_width ,
{ " Framebuffer width " , " vnc.width " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Width of the framebuffer (screen) in pixels " , HFILL }
} ,
{ & hf_vnc_height ,
{ " Framebuffer height " , " vnc.width " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Height of the framebuffer (screen) in pixels " , HFILL }
} ,
{ & hf_vnc_server_bits_per_pixel ,
{ " Bits per pixel " , " vnc.server_bits_per_pixel " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" Number of bits used by server for each pixel value on the wire from the server " , HFILL }
} ,
{ & hf_vnc_server_depth ,
{ " Depth " , " vnc.server_depth " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" Number of useful bits in the pixel value on server " , HFILL }
} ,
{ & hf_vnc_server_big_endian_flag ,
{ " Big endian flag " , " vnc.server_big_endian_flag " ,
FT_BOOLEAN , BASE_NONE , NULL , 0x0 ,
" True if multi-byte pixels are interpreted as big endian by server " , HFILL }
} ,
{ & hf_vnc_server_true_color_flag ,
{ " True color flag " , " vnc.server_true_color_flag " ,
FT_BOOLEAN , BASE_NONE , NULL , 0x0 ,
" 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 }
} ,
{ & hf_vnc_server_red_max ,
{ " Red maximum " , " vnc.server_red_max " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Maximum red value on server as n: 2^n - 1 " , HFILL }
} ,
{ & hf_vnc_server_green_max ,
{ " Green maximum " , " vnc.server_green_max " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Maximum green value on server as n: 2^n - 1 " , HFILL }
} ,
{ & hf_vnc_server_blue_max ,
{ " Blue maximum " , " vnc.server_blue_max " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Maximum blue value on server as n: 2^n - 1 " , HFILL }
} ,
{ & hf_vnc_server_red_shift ,
{ " Red shift " , " vnc.server_red_shift " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" Number of shifts needed to get the red value in a pixel to the least significant bit on the server " , HFILL }
} ,
{ & hf_vnc_server_green_shift ,
{ " Green shift " , " vnc.server_green_shift " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" Number of shifts needed to get the green value in a pixel to the least significant bit on the server " , HFILL }
} ,
{ & hf_vnc_server_blue_shift ,
{ " Blue shift " , " vnc.server_blue_shift " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" Number of shifts needed to get the blue value in a pixel to the least significant bit on the server " , HFILL }
} ,
{ & hf_vnc_desktop_name_len ,
{ " Desktop name length " , " vnc.desktop_name_len " ,
FT_UINT32 , BASE_DEC , NULL , 0x0 ,
" Length of desktop name in bytes " , HFILL }
} ,
{ & hf_vnc_desktop_name ,
{ " Desktop name " , " vnc.desktop_name " ,
FT_STRING , BASE_NONE , NULL , 0x0 ,
" Name of the VNC desktop on the server " , HFILL }
} ,
{ & hf_vnc_client_message_type ,
{ " Client Message Type " , " vnc.client_message_type " ,
FT_UINT8 , BASE_DEC , VALS ( client_message_types_vs ) , 0x0 ,
" Message type from client " , HFILL }
} ,
{ & hf_vnc_client_bits_per_pixel ,
{ " Bits per pixel " , " vnc.client_bits_per_pixel " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" Number of bits used by server for each pixel value on the wire from the client " , HFILL }
} ,
{ & hf_vnc_client_depth ,
{ " Depth " , " vnc.client_depth " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" Number of useful bits in the pixel value on client " , HFILL }
} ,
{ & hf_vnc_client_big_endian_flag ,
{ " Big endian flag " , " vnc.client_big_endian_flag " ,
FT_BOOLEAN , BASE_NONE , NULL , 0x0 ,
" True if multi-byte pixels are interpreted as big endian by client " , HFILL }
} ,
{ & hf_vnc_client_true_color_flag ,
{ " True color flag " , " vnc.client_true_color_flag " ,
FT_BOOLEAN , BASE_NONE , NULL , 0x0 ,
" 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 }
} ,
{ & hf_vnc_client_red_max ,
{ " Red maximum " , " vnc.client_red_max " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Maximum red value on client as n: 2^n - 1 " , HFILL }
} ,
{ & hf_vnc_client_green_max ,
{ " Green maximum " , " vnc.client_green_max " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Maximum green value on client as n: 2^n - 1 " , HFILL }
} ,
{ & hf_vnc_client_blue_max ,
{ " Blue maximum " , " vnc.client_blue_max " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Maximum blue value on client as n: 2^n - 1 " , HFILL }
} ,
{ & hf_vnc_client_red_shift ,
{ " Red shift " , " vnc.client_red_shift " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" Number of shifts needed to get the red value in a pixel to the least significant bit on the client " , HFILL }
} ,
{ & hf_vnc_client_green_shift ,
{ " Green shift " , " vnc.client_green_shift " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" Number of shifts needed to get the green value in a pixel to the least significant bit on the client " , HFILL }
} ,
{ & hf_vnc_client_blue_shift ,
{ " Blue shift " , " vnc.client_blue_shift " ,
FT_UINT8 , BASE_DEC , NULL , 0x0 ,
" Number of shifts needed to get the blue value in a pixel to the least significant bit on the client " , HFILL }
} ,
/* Client Key Event */
{ & hf_vnc_key_down ,
{ " Key down " , " vnc.key_down " ,
FT_UINT8 , BASE_DEC , VALS ( yes_no_vs ) , 0x0 ,
" Specifies whether the key is being pressed or not " , HFILL }
} ,
{ & hf_vnc_key ,
{ " Key " , " vnc.key " ,
FT_UINT32 , BASE_HEX , VALS ( keysym_vals_source ) , 0x0 , /* keysym_vals_source is from packet-x11-keysym.h */
" Key being pressed/depressed " , HFILL }
} ,
/* Client Pointer Event */
{ & hf_vnc_button_1_pos ,
{ " Mouse button #1 position " , " vnc.button_1_pos " ,
FT_UINT8 , BASE_DEC , VALS ( & button_mask_vs ) , 0x1 ,
" Whether mouse button #1 is being pressed or not " , HFILL }
} ,
{ & hf_vnc_button_2_pos ,
{ " Mouse button #2 position " , " vnc.button_2_pos " ,
FT_UINT8 , BASE_DEC , VALS ( & button_mask_vs ) , 0x2 ,
" Whether mouse button #2 is being pressed or not " , HFILL }
} ,
{ & hf_vnc_button_3_pos ,
{ " Mouse button #3 position " , " vnc.button_3_pos " ,
FT_UINT8 , BASE_DEC , VALS ( & button_mask_vs ) , 0x4 ,
" Whether mouse button #3 is being pressed or not " , HFILL }
} ,
{ & hf_vnc_button_4_pos ,
{ " Mouse button #4 position " , " vnc.button_4_pos " ,
FT_UINT8 , BASE_DEC , VALS ( & button_mask_vs ) , 0x8 ,
" Whether mouse button #4 is being pressed or not " , HFILL }
} ,
{ & hf_vnc_button_5_pos ,
{ " Mouse button #5 position " , " vnc.button_5_pos " ,
FT_UINT8 , BASE_DEC , VALS ( & button_mask_vs ) , 0x10 ,
" Whether mouse button #5 is being pressed or not " , HFILL }
} ,
{ & hf_vnc_button_6_pos ,
{ " Mouse button #6 position " , " vnc.button_6_pos " ,
FT_UINT8 , BASE_DEC , VALS ( & button_mask_vs ) , 0x20 ,
" Whether mouse button #6 is being pressed or not " , HFILL }
} ,
{ & hf_vnc_button_7_pos ,
{ " Mouse button #7 position " , " vnc.button_7_pos " ,
FT_UINT8 , BASE_DEC , VALS ( & button_mask_vs ) , 0x40 ,
" Whether mouse button #7 is being pressed or not " , HFILL }
} ,
{ & hf_vnc_button_8_pos ,
{ " Mouse button #8 position " , " vnc.button_8_pos " ,
FT_UINT8 , BASE_DEC , VALS ( & button_mask_vs ) , 0x80 ,
" Whether mouse button #8 is being pressed or not " , HFILL }
} ,
{ & hf_vnc_pointer_x_pos ,
{ " X position " , " vnc.pointer_x_pos " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Position of mouse cursor on the x-axis " , HFILL }
} ,
{ & hf_vnc_pointer_y_pos ,
{ " Y position " , " vnc.pointer_y_pos " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Position of mouse cursor on the y-axis " , HFILL }
} ,
{ & hf_vnc_client_set_encodings_encoding_type ,
{ " Encoding type " , " vnc.client_set_encodings_encoding_type " ,
FT_INT32 , BASE_DEC , VALS ( encoding_types_vs ) , 0x0 ,
" Type of encoding used to send pixel data from server to client " , HFILL }
} ,
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
/* Client Framebuffer Update Request */
{ & hf_vnc_update_req_incremental ,
{ " Incremental update " , " vnc.update_req_incremental " ,
FT_BOOLEAN , BASE_DEC , NULL , 0x0 ,
" Specifies if the client wants an incremental update instead of a full one " , HFILL }
} ,
{ & hf_vnc_update_req_x_pos ,
{ " X position " , " vnc.update_req_x_pos " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" X position of framebuffer (screen) update requested " , HFILL }
} ,
{ & hf_vnc_update_req_y_pos ,
{ " Y position " , " vnc.update_req_y_pos " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Y position of framebuffer (screen) update request " , HFILL }
} ,
{ & hf_vnc_update_req_width ,
{ " Width " , " vnc.update_req_width " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Width of framebuffer (screen) update request " , HFILL }
} ,
{ & hf_vnc_update_req_height ,
{ " Height " , " vnc.update_req_height " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Height of framebuffer (screen) update request " , HFILL }
} ,
{ & hf_vnc_client_cut_text_len ,
{ " Length " , " vnc.client_cut_text_len " ,
FT_UINT32 , BASE_DEC , NULL , 0x0 ,
" Length of client's copy/cut text (clipboard) string in bytes " , HFILL }
} ,
{ & hf_vnc_client_cut_text ,
{ " Text " , " vnc.client_cut_text " ,
FT_STRING , BASE_NONE , NULL , 0x0 ,
" Text string in the client's copy/cut text (clipboard) " , HFILL }
} ,
/********** Server Message Types **********/
{ & hf_vnc_server_message_type ,
{ " Server Message Type " , " vnc.server_message_type " ,
FT_UINT8 , BASE_DEC , VALS ( server_message_types_vs ) , 0x0 ,
" Message type from server " , HFILL }
} ,
/* Server Set Colormap Entries */
{ & hf_vnc_colormap_first_color ,
{ " First color " , " vnc.colormap_first_color " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" First color that should be mapped to given RGB intensities " , HFILL }
} ,
{ & hf_vnc_colormap_num_colors ,
{ " Number of color groups " , " vnc.colormap_groups " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Number of red/green/blue color groups " , HFILL }
} ,
{ & hf_vnc_colormap_red ,
{ " Red " , " vnc.colormap_red " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Red intensity " , HFILL }
} ,
{ & hf_vnc_colormap_green ,
{ " Green " , " vnc.colormap_green " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Green intensity " , HFILL }
} ,
{ & hf_vnc_colormap_blue ,
{ " Blue " , " vnc.colormap_blue " ,
FT_UINT16 , BASE_DEC , NULL , 0x0 ,
" Blue intensity " , HFILL }
} ,
/* Server Cut Text */
{ & hf_vnc_server_cut_text_len ,
{ " Length " , " vnc.server_cut_text_len " ,
FT_UINT32 , BASE_DEC , NULL , 0x0 ,
" Length of server's copy/cut text (clipboard) string in bytes " , HFILL }
} ,
{ & hf_vnc_server_cut_text ,
{ " Text " , " vnc.server_cut_text " ,
FT_STRING , BASE_NONE , NULL , 0x0 ,
" Text string in the server's copy/cut text (clipboard) " , HFILL }
2005-03-14 00:53:58 +00:00
} ,
} ;
2006-09-05 05:38:11 +00:00
/* Setup protocol subtree arrays */
2005-03-14 00:53:58 +00:00
static gint * ett [ ] = {
& ett_vnc ,
2006-09-05 05:38:11 +00:00
& ett_vnc_client_message_type ,
& ett_vnc_server_message_type ,
& ett_vnc_colormap_num_groups ,
& ett_vnc_colormap_color_group
2005-03-14 00:53:58 +00:00
} ;
2006-09-05 05:38:11 +00:00
/* Register the protocol name and description */
2005-03-14 00:53:58 +00:00
proto_vnc = proto_register_protocol ( " Virtual Network Computing " ,
2006-09-05 05:38:11 +00:00
" VNC " , " vnc " ) ;
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
/* Required function calls to register the header fields and subtrees used */
2005-03-14 00:53:58 +00:00
proto_register_field_array ( proto_vnc , hf , array_length ( hf ) ) ;
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
/* Register our preferences module */
vnc_module = prefs_register_protocol ( proto_vnc , proto_reg_handoff_vnc ) ;
prefs_register_bool_preference ( vnc_module , " desegment " , " Reassemble VNC 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 ) ;
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
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 ) ;
}
2005-03-14 00:53:58 +00:00
void
proto_reg_handoff_vnc ( void )
{
static gboolean inited = FALSE ;
2006-09-05 05:38:11 +00:00
if ( ! inited ) {
vnc_handle = create_dissector_handle ( dissect_vnc ,
proto_vnc ) ;
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
dissector_add ( " tcp.port " , 5500 , vnc_handle ) ; /* First screen on listening vnc viewer */
dissector_add ( " tcp.port " , 5501 , vnc_handle ) ; /* Second screen on listening vnc viewer */
dissector_add ( " tcp.port " , 5900 , vnc_handle ) ; /* First screen on server */
dissector_add ( " tcp.port " , 5901 , vnc_handle ) ; /* Second screen on server */
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
/* We don't register a port for the VNC HTTP server because that simply provides a java program
* for download via the normal HTTP protocol . The java program then connects to a standard VNC port ( above ) . */
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
inited = TRUE ;
}
2005-03-14 00:53:58 +00:00
2006-09-05 05:38:11 +00:00
if ( vnc_preference_alternate_port ! = 5500 & & vnc_preference_alternate_port ! = 5501 & &
vnc_preference_alternate_port ! = 5900 & & vnc_preference_alternate_port ! = 5901 & &
vnc_preference_alternate_port ! = 0 ) {
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
dissector_delete ( " tcp.port " , vnc_preference_alternate_port_last , vnc_handle ) ;
vnc_preference_alternate_port_last = vnc_preference_alternate_port ; /* Save this setting to see if has changed later */
dissector_add ( " tcp.port " , vnc_preference_alternate_port , vnc_handle ) ; /* Register the new port setting */
2006-10-31 01:46:59 +00:00
2006-09-05 05:38:11 +00:00
}
2005-03-14 00:53:58 +00:00
}