HACK: 2nd try to match RowsetProperties
[wireshark-wip.git] / epan / dissectors / packet-vnc.c
blob90c6a89b9cf6983bf625ea026531b1227244d1d7
1 /* packet-vnc.c
2 * Routines for VNC dissection (Virtual Network Computing)
3 * Copyright 2005, Ulf Lamping <ulf.lamping@web.de>
4 * Copyright 2006-2007, Stephen Fisher (see AUTHORS file)
6 * $Id$
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 /* Dissection of the VNC (Virtual Network Computing) network traffic.
29 * All versions of RealVNC and TightVNC are supported.
30 * Note: The addition of TightVNC support is not yet complete.
32 * Several VNC implementations available, see:
33 * http://www.realvnc.com/
34 * http://www.tightvnc.com/
35 * http://ultravnc.sourceforge.net/
36 * ...
38 * The protocol itself is known as RFB - Remote Frame Buffer Protocol.
40 * This code is based on the protocol specification:
41 * http://www.realvnc.com/docs/rfbproto.pdf
42 * and the RealVNC free edition & TightVNC source code
45 #include "config.h"
47 #include <glib.h>
49 #include <epan/conversation.h>
50 #include <epan/wmem/wmem.h>
51 #include <epan/packet.h>
52 #include <epan/prefs.h>
53 #include <epan/expert.h>
54 #include "packet-x11.h" /* This contains the extern for the X11 value_string_ext
55 * "x11_keysym_vals_source_ext" that VNC uses. */
57 typedef enum {
58 VNC_SECURITY_TYPE_INVALID = 0,
59 VNC_SECURITY_TYPE_NONE = 1,
60 VNC_SECURITY_TYPE_VNC = 2,
61 VNC_SECURITY_TYPE_RA2 = 5,
62 VNC_SECURITY_TYPE_RA2ne = 6,
63 VNC_SECURITY_TYPE_TIGHT = 16,
64 VNC_SECURITY_TYPE_ULTRA = 17,
65 VNC_SECURITY_TYPE_TLS = 18,
66 VNC_SECURITY_TYPE_VENCRYPT = 19,
67 VNC_SECURITY_TYPE_GTK_VNC_SASL = 20,
68 VNC_SECURITY_TYPE_MD5_HASH_AUTH = 21,
69 VNC_SECURITY_TYPE_XVP = 22,
70 VNC_SECURITY_TYPE_ARD = 30,
71 VNC_TIGHT_AUTH_TGHT_ULGNAUTH = 119,
72 VNC_TIGHT_AUTH_TGHT_XTRNAUTH = 130
73 } vnc_security_types_e;
75 static const value_string vnc_security_types_vs[] = {
76 { VNC_SECURITY_TYPE_INVALID, "Invalid" },
77 { VNC_SECURITY_TYPE_NONE, "None" },
78 { VNC_SECURITY_TYPE_VNC, "VNC" },
79 { VNC_SECURITY_TYPE_RA2, "RA2" },
80 { VNC_SECURITY_TYPE_RA2ne, "RA2ne" },
81 { VNC_SECURITY_TYPE_TIGHT, "Tight" },
82 { VNC_SECURITY_TYPE_ULTRA, "Ultra" },
83 { VNC_SECURITY_TYPE_TLS, "TLS" },
84 { VNC_SECURITY_TYPE_VENCRYPT, "VeNCrypt" },
85 { VNC_SECURITY_TYPE_GTK_VNC_SASL, "GTK-VNC SASL" },
86 { VNC_SECURITY_TYPE_ARD, "Apple Remote Desktop" },
87 { 0, NULL }
90 static const true_false_string auth_result_tfs = {
91 "Failed",
92 "OK"
95 static const value_string yes_no_vs[] = {
96 { 0, "No" },
97 { 1, "Yes" },
98 { 0, NULL }
101 typedef enum {
102 VNC_CLIENT_MESSAGE_TYPE_SET_PIXEL_FORMAT = 0,
103 VNC_CLIENT_MESSAGE_TYPE_SET_ENCODING = 2,
104 VNC_CLIENT_MESSAGE_TYPE_FRAMEBUF_UPDATE_REQ = 3,
105 VNC_CLIENT_MESSAGE_TYPE_KEY_EVENT = 4,
106 VNC_CLIENT_MESSAGE_TYPE_POINTER_EVENT = 5,
107 VNC_CLIENT_MESSAGE_TYPE_CLIENT_CUT_TEXT = 6,
108 VNC_CLIENT_MESSAGE_TYPE_MIRRORLINK = 128
109 } vnc_client_message_types_e;
111 static const value_string vnc_client_message_types_vs[] = {
112 { VNC_CLIENT_MESSAGE_TYPE_SET_PIXEL_FORMAT, "Set Pixel Format" },
113 { VNC_CLIENT_MESSAGE_TYPE_SET_ENCODING, "Set Encodings" },
114 { VNC_CLIENT_MESSAGE_TYPE_FRAMEBUF_UPDATE_REQ, "Framebuffer Update Request" },
115 { VNC_CLIENT_MESSAGE_TYPE_KEY_EVENT, "Key Event" },
116 { VNC_CLIENT_MESSAGE_TYPE_POINTER_EVENT, "Pointer Event" },
117 { VNC_CLIENT_MESSAGE_TYPE_CLIENT_CUT_TEXT, "Cut Text" },
118 { VNC_CLIENT_MESSAGE_TYPE_MIRRORLINK, "MirrorLink" },
119 { 0, NULL }
122 typedef enum {
123 VNC_SERVER_MESSAGE_TYPE_FRAMEBUFFER_UPDATE = 0,
124 VNC_SERVER_MESSAGE_TYPE_SET_COLORMAP_ENTRIES = 1,
125 VNC_SERVER_MESSAGE_TYPE_RING_BELL = 2,
126 VNC_SERVER_MESSAGE_TYPE_CUT_TEXT = 3,
127 VNC_SERVER_MESSAGE_TYPE_MIRRORLINK = 128
128 } vnc_server_message_types_e;
130 static const value_string vnc_server_message_types_vs[] = {
131 { VNC_SERVER_MESSAGE_TYPE_FRAMEBUFFER_UPDATE, "Framebuffer Update" },
132 { VNC_SERVER_MESSAGE_TYPE_SET_COLORMAP_ENTRIES, "Set Colormap Entries" },
133 { VNC_SERVER_MESSAGE_TYPE_RING_BELL, "Ring Bell" },
134 { VNC_SERVER_MESSAGE_TYPE_CUT_TEXT, "Cut Text" },
135 { VNC_SERVER_MESSAGE_TYPE_MIRRORLINK, "MirrorLink" },
136 { 0, NULL }
139 static const true_false_string button_mask_tfs = {
140 "Pressed",
141 "Not pressed"
144 #define VNC_ENCODING_TYPE_DESKTOP_SIZE 0xFFFFFF21
145 #define VNC_ENCODING_TYPE_LAST_RECT 0xFFFFFF20
146 #define VNC_ENCODING_TYPE_POINTER_POS 0xFFFFFF18
147 #define VNC_ENCODING_TYPE_RICH_CURSOR 0xFFFFFF11
148 #define VNC_ENCODING_TYPE_X_CURSOR 0xFFFFFF10
149 #define VNC_ENCODING_TYPE_RAW 0
150 #define VNC_ENCODING_TYPE_COPY_RECT 1
151 #define VNC_ENCODING_TYPE_RRE 2
152 #define VNC_ENCODING_TYPE_CORRE 4
153 #define VNC_ENCODING_TYPE_HEXTILE 5
154 #define VNC_ENCODING_TYPE_ZLIB 6
155 #define VNC_ENCODING_TYPE_TIGHT 7
156 #define VNC_ENCODING_TYPE_ZLIBHEX 8
157 #define VNC_ENCODING_TYPE_ULTRA 9
158 #define VNC_ENCODING_TYPE_TRLE 15
159 #define VNC_ENCODING_TYPE_RLE 16
160 #define VNC_ENCODING_TYPE_HITACHI_ZYWRLE 17
161 #define VNC_ENCODING_TYPE_JPEG_0 -32
162 #define VNC_ENCODING_TYPE_JPEG_1 -31
163 #define VNC_ENCODING_TYPE_JPEG_2 -30
164 #define VNC_ENCODING_TYPE_JPEG_3 -29
165 #define VNC_ENCODING_TYPE_JPEG_4 -28
166 #define VNC_ENCODING_TYPE_JPEG_5 -27
167 #define VNC_ENCODING_TYPE_JPEG_6 -26
168 #define VNC_ENCODING_TYPE_JPEG_7 -25
169 #define VNC_ENCODING_TYPE_JPEG_8 -24
170 #define VNC_ENCODING_TYPE_JPEG_9 -23
171 #define VNC_ENCODING_TYPE_COMPRESSION_0 0xFFFFFF00
172 #define VNC_ENCODING_TYPE_COMPRESSION_1 0xFFFFFF01
173 #define VNC_ENCODING_TYPE_COMPRESSION_2 0xFFFFFF02
174 #define VNC_ENCODING_TYPE_COMPRESSION_3 0xFFFFFF03
175 #define VNC_ENCODING_TYPE_COMPRESSION_4 0xFFFFFF04
176 #define VNC_ENCODING_TYPE_COMPRESSION_5 0xFFFFFF05
177 #define VNC_ENCODING_TYPE_COMPRESSION_6 0xFFFFFF06
178 #define VNC_ENCODING_TYPE_COMPRESSION_7 0xFFFFFF07
179 #define VNC_ENCODING_TYPE_COMPRESSION_8 0xFFFFFF08
180 #define VNC_ENCODING_TYPE_COMPRESSION_9 0xFFFFFF09
181 #define VNC_ENCODING_TYPE_WMVi 0x574D5669
182 #define VNC_ENCODING_TYPE_CACHE 0xFFFF0000
183 #define VNC_ENCODING_TYPE_CACHE_ENABLE 0xFFFF0001
184 #define VNC_ENCODING_TYPE_XOR_ZLIB 0xFFFF0002
185 #define VNC_ENCODING_TYPE_XOR_MONO_ZLIB 0xFFFF0003
186 #define VNC_ENCODING_TYPE_XOR_MULTI_ZLIB 0xFFFF0004
187 #define VNC_ENCODING_TYPE_SOLID_COLOR 0xFFFF0005
188 #define VNC_ENCODING_TYPE_XOR_ENABLE 0xFFFF0006
189 #define VNC_ENCODING_TYPE_CACHE_ZIP 0xFFFF0007
190 #define VNC_ENCODING_TYPE_SOL_MONO_ZIP 0xFFFF0008
191 #define VNC_ENCODING_TYPE_ULTRA_ZIP 0xFFFF0009
192 #define VNC_ENCODING_TYPE_SERVER_STATE 0xFFFF8000
193 #define VNC_ENCODING_TYPE_ENABLE_KEEP_ALIVE 0xFFFF8001
194 #define VNC_ENCODING_TYPE_FTP_PROTO_VER 0xFFFF8002
195 #define VNC_ENCODING_TYPE_POINTER_CHANGE -257
196 #define VNC_ENCODING_TYPE_EXT_KEY_EVENT -258
197 #define VNC_ENCODING_TYPE_AUDIO 259
198 #define VNC_ENCODING_TYPE_DESKTOP_NAME -307
199 #define VNC_ENCODING_TYPE_EXTENDED_DESK_SIZE -308
200 #define VNC_ENCODING_TYPE_KEYBOARD_LED_STATE 0XFFFE0000
201 #define VNC_ENCODING_TYPE_SUPPORTED_MESSAGES 0XFFFE0001
202 #define VNC_ENCODING_TYPE_SUPPORTED_ENCODINGS 0XFFFE0002
203 #define VNC_ENCODING_TYPE_SERVER_IDENTITY 0XFFFE0003
204 #define VNC_ENCODING_TYPE_MIRRORLINK 0xFFFFFDF5
205 #define VNC_ENCODING_TYPE_CONTEXT_INFORMATION 0xFFFFFDF4
206 #define VNC_ENCODING_TYPE_SLRLE 0xFFFFFDF3
207 #define VNC_ENCODING_TYPE_TRANSFORM 0xFFFFFDF2
208 #define VNC_ENCODING_TYPE_HSML 0xFFFFFDF1
209 #define VNC_ENCODING_TYPE_H264 0X48323634
211 static const value_string encoding_types_vs[] = {
212 { VNC_ENCODING_TYPE_DESKTOP_SIZE, "DesktopSize (pseudo)" },
213 { VNC_ENCODING_TYPE_LAST_RECT, "LastRect (pseudo)" },
214 { VNC_ENCODING_TYPE_POINTER_POS, "Pointer pos (pseudo)" },
215 { VNC_ENCODING_TYPE_RICH_CURSOR, "Rich Cursor (pseudo)" },
216 { VNC_ENCODING_TYPE_X_CURSOR, "X Cursor (pseudo)" },
217 { VNC_ENCODING_TYPE_RAW, "Raw" },
218 { VNC_ENCODING_TYPE_COPY_RECT, "CopyRect" },
219 { VNC_ENCODING_TYPE_RRE, "RRE" },
220 { VNC_ENCODING_TYPE_CORRE, "CoRRE" },
221 { VNC_ENCODING_TYPE_HEXTILE, "Hextile" },
222 { VNC_ENCODING_TYPE_ZLIB, "Zlib" },
223 { VNC_ENCODING_TYPE_TIGHT, "Tight" },
224 { VNC_ENCODING_TYPE_ZLIBHEX, "ZlibHex" },
225 { VNC_ENCODING_TYPE_ULTRA, "Ultra" },
226 { VNC_ENCODING_TYPE_RLE, "ZRLE" },
227 { VNC_ENCODING_TYPE_HITACHI_ZYWRLE, "Hitachi ZYWRLE" },
228 { VNC_ENCODING_TYPE_JPEG_0, "JPEG quality level 0" },
229 { VNC_ENCODING_TYPE_JPEG_1, "JPEG quality level 1" },
230 { VNC_ENCODING_TYPE_JPEG_2, "JPEG quality level 2" },
231 { VNC_ENCODING_TYPE_JPEG_3, "JPEG quality level 3" },
232 { VNC_ENCODING_TYPE_JPEG_4, "JPEG quality level 4" },
233 { VNC_ENCODING_TYPE_JPEG_5, "JPEG quality level 5" },
234 { VNC_ENCODING_TYPE_JPEG_6, "JPEG quality level 6" },
235 { VNC_ENCODING_TYPE_JPEG_7, "JPEG quality level 7" },
236 { VNC_ENCODING_TYPE_JPEG_8, "JPEG quality level 8" },
237 { VNC_ENCODING_TYPE_JPEG_9, "JPEG quality level 9" },
238 { VNC_ENCODING_TYPE_COMPRESSION_0, "Compression level 0" },
239 { VNC_ENCODING_TYPE_COMPRESSION_1, "Compression level 1" },
240 { VNC_ENCODING_TYPE_COMPRESSION_2, "Compression level 2" },
241 { VNC_ENCODING_TYPE_COMPRESSION_3, "Compression level 3" },
242 { VNC_ENCODING_TYPE_COMPRESSION_4, "Compression level 4" },
243 { VNC_ENCODING_TYPE_COMPRESSION_5, "Compression level 5" },
244 { VNC_ENCODING_TYPE_COMPRESSION_6, "Compression level 6" },
245 { VNC_ENCODING_TYPE_COMPRESSION_7, "Compression level 7" },
246 { VNC_ENCODING_TYPE_COMPRESSION_8, "Compression level 8" },
247 { VNC_ENCODING_TYPE_COMPRESSION_9, "Compression level 9" },
248 /* FIXME understand for real what the below mean. Taken from Ultra VNC source code */
249 /* { VNC_ENCODING_TYPE_CACHE, */
250 { VNC_ENCODING_TYPE_CACHE_ENABLE, "Enable Caching"},
251 /* { VNC_ENCODING_TYPE_XOR_ZLIB,
252 { VNC_ENCODING_TYPE_XOR_MONO_ZLIB,
253 { VNC_ENCODING_TYPE_XOR_MULTI_ZLIB,
254 { VNC_ENCODING_TYPE_SOLID_COLOR,
255 { VNC_ENCODING_TYPE_XOR_ENABLE,
256 { VNC_ENCODING_TYPE_CACHE_ZIP,
257 { VNC_ENCODING_TYPE_SOL_MONO_ZIP,
258 { VNC_ENCODING_TYPE_ULTRA_ZIP,
259 */ { VNC_ENCODING_TYPE_SERVER_STATE, "Server State" },
260 { VNC_ENCODING_TYPE_ENABLE_KEEP_ALIVE, "Enable Keep Alive" },
261 { VNC_ENCODING_TYPE_FTP_PROTO_VER, "FTP protocol version" },
262 { VNC_ENCODING_TYPE_EXTENDED_DESK_SIZE, "Extended Desktop Size"},
263 { VNC_ENCODING_TYPE_DESKTOP_NAME, "Desktop Name" },
264 { VNC_ENCODING_TYPE_KEYBOARD_LED_STATE, "Keyboard LED State" },
265 { VNC_ENCODING_TYPE_SUPPORTED_MESSAGES, "Supported Messages" },
266 { VNC_ENCODING_TYPE_SUPPORTED_ENCODINGS, "Supported Encodings" },
267 { VNC_ENCODING_TYPE_SERVER_IDENTITY, "Server Identity" },
268 { VNC_ENCODING_TYPE_MIRRORLINK, "MirrorLink" },
269 { VNC_ENCODING_TYPE_CONTEXT_INFORMATION, "Context Information" },
270 { VNC_ENCODING_TYPE_SLRLE, "SLRLE" },
271 { VNC_ENCODING_TYPE_TRANSFORM, "Transform" },
272 { VNC_ENCODING_TYPE_HSML, "HSML" },
273 { VNC_ENCODING_TYPE_H264, "H264" },
274 { 0, NULL }
277 /* Rectangle types for Tight encoding. These come in the "control byte" at the
278 * start of a rectangle's payload. Note that these are with respect to the most
279 * significant bits 4-7 of the control byte, so you must shift it to the right 4
280 * bits before comparing against these values.
282 #define TIGHT_RECT_FILL 0x08
283 #define TIGHT_RECT_JPEG 0x09
284 #define TIGHT_RECT_MAX_VALUE 0x09
286 #define TIGHT_RECT_EXPLICIT_FILTER_FLAG 0x04
288 /* Filter types for Basic encoding of Tight rectangles */
289 #define TIGHT_RECT_FILTER_COPY 0x00
290 #define TIGHT_RECT_FILTER_PALETTE 0x01
291 #define TIGHT_RECT_FILTER_GRADIENT 0x02
293 /* Minimum number of bytes to compress for Tight encoding */
294 #define TIGHT_MIN_BYTES_TO_COMPRESS 12
296 static const value_string tight_filter_ids_vs[] = {
297 { TIGHT_RECT_FILTER_COPY, "Copy" },
298 { TIGHT_RECT_FILTER_PALETTE, "Palette" },
299 { TIGHT_RECT_FILTER_GRADIENT, "Gradient" },
300 { 0, NULL }
303 /* MirrorLink messages */
304 typedef enum {
305 VNC_ML_EXT_BYE_BYE = 0,
306 VNC_ML_EXT_SERVER_DISPLAY_CONFIGURATION = 1,
307 VNC_ML_EXT_CLIENT_DISPLAY_CONFIGURATION = 2,
308 VNC_ML_EXT_SERVER_EVENT_CONFIGURATION = 3,
309 VNC_ML_EXT_CLIENT_EVENT_CONFIGURATION = 4,
310 VNC_ML_EXT_EVENT_MAPPING = 5,
311 VNC_ML_EXT_EVENT_MAPPING_REQUEST = 6,
312 VNC_ML_EXT_KEY_EVENT_LISTING = 7,
313 VNC_ML_EXT_KEY_EVENT_LISTING_REQUEST = 8,
314 VNC_ML_EXT_VIRTUAL_KEYBOARD = 9,
315 VNC_ML_EXT_VIRTUAL_KEYBOARD_REQUEST = 10,
316 VNC_ML_EXT_DEVICE_STATUS = 11,
317 VNC_ML_EXT_DEVICE_STATUS_REQUEST = 12,
318 VNC_ML_EXT_CONTENT_ATTESTATION = 13,
319 VNC_ML_EXT_CONTENT_ATTESTATION_REQUEST = 14,
320 VNC_ML_EXT_FB_BLOCKING_NOTIFICATION = 16,
321 VNC_ML_EXT_AUDIO_BLOCKING_NOTIFICATION = 18,
322 VNC_ML_EXT_TOUCH_EVENT = 20,
323 VNC_ML_EXT_FB_ALTERNATIVE_TEXT = 21,
324 VNC_ML_EXT_FB_ALTERNATIVE_TEXT_REQUEST = 22
325 } vnc_mirrorlink_ext_types_e;
327 static const value_string vnc_mirrorlink_types_vs[] = {
328 { VNC_ML_EXT_BYE_BYE, "ByeBye" },
329 { VNC_ML_EXT_SERVER_DISPLAY_CONFIGURATION, "Server Display Configuration" },
330 { VNC_ML_EXT_CLIENT_DISPLAY_CONFIGURATION, "Client Display Configuration" },
331 { VNC_ML_EXT_SERVER_EVENT_CONFIGURATION, "Server Event Configuration" },
332 { VNC_ML_EXT_CLIENT_EVENT_CONFIGURATION, "Client Event Configuration" },
333 { VNC_ML_EXT_EVENT_MAPPING, "Event Mapping" },
334 { VNC_ML_EXT_EVENT_MAPPING_REQUEST, "Event Mapping Request" },
335 { VNC_ML_EXT_KEY_EVENT_LISTING, "Key Event Listing" },
336 { VNC_ML_EXT_KEY_EVENT_LISTING_REQUEST, "Key Event Listing Request" },
337 { VNC_ML_EXT_VIRTUAL_KEYBOARD, "Virtual Keyboard Trigger" },
338 { VNC_ML_EXT_VIRTUAL_KEYBOARD_REQUEST, "Virtual Keyboard Trigger Request" },
339 { VNC_ML_EXT_DEVICE_STATUS, "Device Status" },
340 { VNC_ML_EXT_DEVICE_STATUS_REQUEST, "Device Status Request" },
341 { VNC_ML_EXT_CONTENT_ATTESTATION, "Content Attestation" },
342 { VNC_ML_EXT_CONTENT_ATTESTATION_REQUEST, "Content Attestation Request" },
343 { VNC_ML_EXT_FB_BLOCKING_NOTIFICATION, "Framebuffer Blocking Notification" },
344 { VNC_ML_EXT_AUDIO_BLOCKING_NOTIFICATION, "Audio Blocking Notification" },
345 { VNC_ML_EXT_TOUCH_EVENT, "Touch Event" },
346 { VNC_ML_EXT_FB_ALTERNATIVE_TEXT, "Framebuffer Alternative Text" },
347 { VNC_ML_EXT_FB_ALTERNATIVE_TEXT_REQUEST, "Framebuffer Alternative Text Request" },
348 { 0, NULL }
351 /* Slice types for H.264 encoding */
352 typedef enum {
353 VNC_H264_SLICE_TYPE_P = 0,
354 VNC_H264_SLICE_TYPE_B = 1,
355 VNC_H264_SLICE_TYPE_I = 2
356 } vnc_h264_slice_types_e;
358 static const value_string vnc_h264_slice_types_vs[] = {
359 { VNC_H264_SLICE_TYPE_P, "Predicted" },
360 { VNC_H264_SLICE_TYPE_B, "Bi-predicted" },
361 { VNC_H264_SLICE_TYPE_I, "Intra coded" },
362 { 0, NULL }
366 typedef enum {
367 VNC_SESSION_STATE_SERVER_VERSION,
368 VNC_SESSION_STATE_CLIENT_VERSION,
370 VNC_SESSION_STATE_SECURITY,
371 VNC_SESSION_STATE_SECURITY_TYPES,
373 VNC_SESSION_STATE_TIGHT_TUNNELING_CAPABILITIES,
374 VNC_SESSION_STATE_TIGHT_TUNNEL_TYPE_REPLY,
375 VNC_SESSION_STATE_TIGHT_AUTH_CAPABILITIES,
376 VNC_SESSION_STATE_TIGHT_AUTH_TYPE_REPLY,
377 VNC_SESSION_STATE_TIGHT_UNKNOWN_PACKET3,
379 VNC_SESSION_STATE_VNC_AUTHENTICATION_CHALLENGE,
380 VNC_SESSION_STATE_VNC_AUTHENTICATION_RESPONSE,
382 VNC_SESSION_STATE_ARD_AUTHENTICATION_CHALLENGE,
383 VNC_SESSION_STATE_ARD_AUTHENTICATION_RESPONSE,
385 VNC_SESSION_STATE_SECURITY_RESULT,
387 VNC_SESSION_STATE_CLIENT_INIT,
388 VNC_SESSION_STATE_SERVER_INIT,
390 VNC_SESSION_STATE_TIGHT_INTERACTION_CAPS,
392 VNC_SESSION_STATE_NORMAL_TRAFFIC
393 } vnc_session_state_e;
395 /* This structure will be tied to each conversation. */
396 typedef struct {
397 gdouble server_proto_ver, client_proto_ver;
398 vnc_session_state_e vnc_next_state;
399 guint32 server_port;
400 /* These are specific to TightVNC */
401 gint num_server_message_types;
402 gint num_client_message_types;
403 gint num_encoding_types;
404 guint8 security_type_selected;
405 gboolean tight_enabled;
406 /* This is specific to Apple Remote Desktop */
407 guint16 ard_key_length;
408 } vnc_conversation_t;
410 /* This structure will be tied to each packet */
411 typedef struct {
412 vnc_session_state_e state;
413 gint preferred_encoding;
414 guint8 bytes_per_pixel;
415 guint8 depth;
416 } vnc_packet_t;
418 void proto_reg_handoff_vnc(void);
420 static gboolean vnc_startup_messages(tvbuff_t *tvb, packet_info *pinfo,
421 gint offset, proto_tree *tree,
422 vnc_conversation_t *per_conversation_info);
423 static void vnc_client_to_server(tvbuff_t *tvb, packet_info *pinfo,
424 gint *offset, proto_tree *tree);
425 static void vnc_server_to_client(tvbuff_t *tvb, packet_info *pinfo,
426 gint *offset, proto_tree *tree);
427 static void vnc_client_set_pixel_format(tvbuff_t *tvb, packet_info *pinfo,
428 gint *offset, proto_tree *tree);
429 static void vnc_client_set_encodings(tvbuff_t *tvb, packet_info *pinfo,
430 gint *offset, proto_tree *tree);
431 static void vnc_client_framebuffer_update_request(tvbuff_t *tvb,
432 packet_info *pinfo,
433 gint *offset,
434 proto_tree *tree);
435 static void vnc_client_key_event(tvbuff_t *tvb, packet_info *pinfo,
436 gint *offset, proto_tree *tree);
437 static void vnc_client_pointer_event(tvbuff_t *tvb, packet_info *pinfo,
438 gint *offset, proto_tree *tree);
439 static void vnc_client_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
440 proto_tree *tree);
442 static guint vnc_server_framebuffer_update(tvbuff_t *tvb, packet_info *pinfo,
443 gint *offset, proto_tree *tree);
444 static guint vnc_raw_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
445 proto_tree *tree, const guint16 width, const guint16 height);
446 static guint vnc_copyrect_encoding(tvbuff_t *tvb, packet_info *pinfo,
447 gint *offset, proto_tree *tree,
448 const guint16 width, const guint16 height);
449 static guint vnc_rre_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
450 proto_tree *tree, const guint16 width, const guint16 height);
451 static guint vnc_hextile_encoding(tvbuff_t *tvb, packet_info *pinfo,
452 gint *offset, proto_tree *tree,
453 const guint16 width, const guint16 height);
454 static guint vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
455 proto_tree *tree, const guint16 width, const guint16 height);
456 static guint vnc_tight_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
457 proto_tree *tree, const guint16 width, const guint16 height);
458 static guint vnc_rich_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo,
459 gint *offset, proto_tree *tree, const guint16 width,
460 const guint16 height);
461 static guint vnc_x_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo,
462 gint *offset, proto_tree *tree, const guint16 width,
463 const guint16 height);
464 static guint vnc_server_set_colormap_entries(tvbuff_t *tvb, packet_info *pinfo,
465 gint *offset, proto_tree *tree);
466 static void vnc_server_ring_bell(tvbuff_t *tvb, packet_info *pinfo,
467 gint *offset, proto_tree *tree);
468 static guint vnc_server_cut_text(tvbuff_t *tvb, packet_info *pinfo,
469 gint *offset, proto_tree *tree);
470 static void vnc_set_bytes_per_pixel(const packet_info *pinfo, const guint8 bytes_per_pixel);
471 static void vnc_set_depth(const packet_info *pinfo, const guint8 depth);
472 static guint8 vnc_get_bytes_per_pixel(const packet_info *pinfo);
473 static guint8 vnc_get_depth(const packet_info *pinfo);
474 static guint32 vnc_extended_desktop_size(tvbuff_t *tvb, gint *offset, proto_tree *tree);
476 static guint vnc_supported_messages(tvbuff_t *tvb, gint *offset,
477 proto_tree *tree, const guint16 width);
478 static guint vnc_supported_encodings(tvbuff_t *tvb, gint *offset,
479 proto_tree *tree, const guint16 width,
480 const guint16 height);
481 static guint vnc_server_identity(tvbuff_t *tvb, gint *offset,
482 proto_tree *tree, const guint16 width);
484 static guint vnc_mirrorlink(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
485 proto_tree *tree);
486 static guint vnc_context_information(tvbuff_t *tvb, gint *offset,
487 proto_tree *tree);
488 static guint vnc_slrle_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
489 proto_tree *tree, const guint16 height);
491 static guint vnc_h264_encoding(tvbuff_t *tvb, gint *offset, proto_tree *tree);
493 #define DEST_PORT_VNC pinfo->destport == 5500 || pinfo->destport == 5501 || \
494 pinfo->destport == 5900 || pinfo->destport == 5901 || \
495 pinfo->destport == vnc_preference_alternate_port
497 #define VNC_BYTES_NEEDED(a) \
498 if(a > (guint)tvb_length_remaining(tvb, *offset)) \
499 return a;
501 /* Variables for our preferences */
502 static guint vnc_preference_alternate_port = 0;
504 /* Initialize the protocol and registered fields */
505 static int proto_vnc = -1; /* Protocol subtree */
506 static int hf_vnc_padding = -1;
507 static int hf_vnc_server_proto_ver = -1;
508 static int hf_vnc_client_proto_ver = -1;
509 static int hf_vnc_num_security_types = -1;
510 static int hf_vnc_security_type = -1;
511 static int hf_vnc_server_security_type = -1;
512 static int hf_vnc_client_security_type = -1;
513 static int hf_vnc_auth_challenge = -1;
514 static int hf_vnc_auth_response = -1;
515 static int hf_vnc_auth_result = -1;
516 static int hf_vnc_auth_error = -1;
517 static int hf_vnc_auth_error_length = -1;
519 static int hf_vnc_ard_auth_generator = -1;
520 static int hf_vnc_ard_auth_key_len = -1;
521 static int hf_vnc_ard_auth_modulus = -1;
522 static int hf_vnc_ard_auth_server_key = -1;
523 static int hf_vnc_ard_auth_credentials = -1;
524 static int hf_vnc_ard_auth_client_key = -1;
526 static int hf_vnc_share_desktop_flag = -1;
527 static int hf_vnc_width = -1;
528 static int hf_vnc_height = -1;
529 static int hf_vnc_server_bits_per_pixel = -1;
530 static int hf_vnc_server_depth = -1;
531 static int hf_vnc_server_big_endian_flag = -1;
532 static int hf_vnc_server_true_color_flag = -1;
533 static int hf_vnc_server_red_max = -1;
534 static int hf_vnc_server_green_max = -1;
535 static int hf_vnc_server_blue_max = -1;
536 static int hf_vnc_server_red_shift = -1;
537 static int hf_vnc_server_green_shift = -1;
538 static int hf_vnc_server_blue_shift = -1;
539 static int hf_vnc_desktop_name = -1;
540 static int hf_vnc_desktop_name_len = -1;
541 static int hf_vnc_desktop_screen_num = -1;
542 static int hf_vnc_desktop_screen_id = -1;
543 static int hf_vnc_desktop_screen_x = -1;
544 static int hf_vnc_desktop_screen_y = -1;
545 static int hf_vnc_desktop_screen_width = -1;
546 static int hf_vnc_desktop_screen_height = -1;
547 static int hf_vnc_desktop_screen_flags = -1;
548 static int hf_vnc_num_server_message_types = -1;
549 static int hf_vnc_num_client_message_types = -1;
550 static int hf_vnc_num_encoding_types = -1;
552 /********** Client Message Types **********/
554 static int hf_vnc_client_message_type = -1; /* A subtree under VNC */
555 static int hf_vnc_client_bits_per_pixel = -1;
556 static int hf_vnc_client_depth = -1;
557 static int hf_vnc_client_big_endian_flag = -1;
558 static int hf_vnc_client_true_color_flag = -1;
559 static int hf_vnc_client_red_max = -1;
560 static int hf_vnc_client_green_max = -1;
561 static int hf_vnc_client_blue_max = -1;
562 static int hf_vnc_client_red_shift = -1;
563 static int hf_vnc_client_green_shift = -1;
564 static int hf_vnc_client_blue_shift = -1;
566 /* Client Key Event */
567 static int hf_vnc_key_down = -1;
568 static int hf_vnc_key = -1;
570 /* Client Pointer Event */
571 static int hf_vnc_button_1_pos = -1;
572 static int hf_vnc_button_2_pos = -1;
573 static int hf_vnc_button_3_pos = -1;
574 static int hf_vnc_button_4_pos = -1;
575 static int hf_vnc_button_5_pos = -1;
576 static int hf_vnc_button_6_pos = -1;
577 static int hf_vnc_button_7_pos = -1;
578 static int hf_vnc_button_8_pos = -1;
579 static int hf_vnc_pointer_x_pos = -1;
580 static int hf_vnc_pointer_y_pos = -1;
582 /* Client Framebuffer Update Request */
583 static int hf_vnc_update_req_incremental = -1;
584 static int hf_vnc_update_req_x_pos = -1;
585 static int hf_vnc_update_req_y_pos = -1;
586 static int hf_vnc_update_req_width = -1;
587 static int hf_vnc_update_req_height = -1;
589 /* Client Set Encodings */
590 static int hf_vnc_encoding_num = -1;
591 static int hf_vnc_client_set_encodings_encoding_type = -1;
593 /* Client Cut Text */
594 static int hf_vnc_client_cut_text_len = -1;
595 static int hf_vnc_client_cut_text = -1;
597 /********** Server Message Types **********/
599 static int hf_vnc_server_message_type = -1; /* Subtree */
601 /* Tunneling capabilities (TightVNC extension) */
602 static int hf_vnc_tight_num_tunnel_types = -1;
603 static int hf_vnc_tight_tunnel_type = -1;
605 /* Authentication capabilities (TightVNC extension) */
606 static int hf_vnc_tight_num_auth_types = -1;
607 static int hf_vnc_tight_auth_code = -1;
608 /* TightVNC capabilities */
609 static int hf_vnc_tight_server_message_type = -1;
610 static int hf_vnc_tight_server_vendor = -1;
611 static int hf_vnc_tight_server_name = -1;
613 static int hf_vnc_tight_client_message_type = -1;
614 static int hf_vnc_tight_client_vendor = -1;
615 static int hf_vnc_tight_client_name = -1;
617 static int hf_vnc_tight_encoding_type = -1;
618 static int hf_vnc_tight_encoding_vendor = -1;
619 static int hf_vnc_tight_encoding_name = -1;
621 /* Tight compression parameters */
622 static int hf_vnc_tight_reset_stream0 = -1;
623 static int hf_vnc_tight_reset_stream1 = -1;
624 static int hf_vnc_tight_reset_stream2 = -1;
625 static int hf_vnc_tight_reset_stream3 = -1;
627 static int hf_vnc_tight_rect_type = -1;
629 static int hf_vnc_tight_image_len = -1;
630 static int hf_vnc_tight_image_data = -1;
632 static int hf_vnc_tight_fill_color = -1;
634 static int hf_vnc_tight_filter_flag = -1;
635 static int hf_vnc_tight_filter_id = -1;
637 static int hf_vnc_tight_palette_num_colors = -1;
638 static int hf_vnc_tight_palette_data = -1;
640 /* Server Framebuffer Update */
641 static int hf_vnc_rectangle_num = -1;
642 static int hf_vnc_fb_update_x_pos = -1;
643 static int hf_vnc_fb_update_y_pos = -1;
644 static int hf_vnc_fb_update_width = -1;
645 static int hf_vnc_fb_update_height = -1;
646 static int hf_vnc_fb_update_encoding_type = -1;
648 /* Raw Encoding */
649 static int hf_vnc_raw_pixel_data = -1;
651 /* CopyRect Encoding */
652 static int hf_vnc_copyrect_src_x_pos = -1;
653 static int hf_vnc_copyrect_src_y_pos = -1;
655 /* RRE Encoding */
656 static int hf_vnc_rre_num_subrects = -1;
657 static int hf_vnc_rre_bg_pixel = -1;
659 static int hf_vnc_rre_subrect_pixel = -1;
660 static int hf_vnc_rre_subrect_x_pos = -1;
661 static int hf_vnc_rre_subrect_y_pos = -1;
662 static int hf_vnc_rre_subrect_width = -1;
663 static int hf_vnc_rre_subrect_height = -1;
665 /* Hextile Encoding */
666 static int hf_vnc_hextile_subencoding_mask = -1;
667 static int hf_vnc_hextile_raw = -1;
668 static int hf_vnc_hextile_raw_value = -1;
669 static int hf_vnc_hextile_bg = -1;
670 static int hf_vnc_hextile_bg_value = -1;
671 static int hf_vnc_hextile_fg = -1;
672 static int hf_vnc_hextile_fg_value = -1;
673 static int hf_vnc_hextile_anysubrects = -1;
674 static int hf_vnc_hextile_num_subrects = -1;
675 static int hf_vnc_hextile_subrectscolored = -1;
676 static int hf_vnc_hextile_subrect_pixel_value = -1;
677 static int hf_vnc_hextile_subrect_x_pos = -1;
678 static int hf_vnc_hextile_subrect_y_pos = -1;
679 static int hf_vnc_hextile_subrect_width = -1;
680 static int hf_vnc_hextile_subrect_height = -1;
682 /* ZRLE Encoding */
683 static int hf_vnc_zrle_len = -1;
684 static int hf_vnc_zrle_subencoding = -1;
685 static int hf_vnc_zrle_rle = -1;
686 static int hf_vnc_zrle_palette_size = -1;
687 static int hf_vnc_zrle_data = -1;
688 static int hf_vnc_zrle_raw = -1;
689 static int hf_vnc_zrle_palette = -1;
691 /* Cursor Encoding */
692 static int hf_vnc_cursor_x_fore_back = -1;
693 static int hf_vnc_cursor_encoding_pixels = -1;
694 static int hf_vnc_cursor_encoding_bitmask = -1;
696 /* Server Set Colormap Entries */
697 static int hf_vnc_color_groups = -1;
698 static int hf_vnc_colormap_first_color = -1;
699 static int hf_vnc_colormap_num_colors = -1;
700 static int hf_vnc_colormap_red = -1;
701 static int hf_vnc_colormap_green = -1;
702 static int hf_vnc_colormap_blue = -1;
704 /* Server Cut Text */
705 static int hf_vnc_server_cut_text_len = -1;
706 static int hf_vnc_server_cut_text = -1;
708 /* LibVNCServer additions */
709 static int hf_vnc_supported_messages_client2server = -1;
710 static int hf_vnc_supported_messages_server2client = -1;
711 static int hf_vnc_supported_encodings = -1;
712 static int hf_vnc_server_identity = -1;
714 /* MirrorLink */
715 static int hf_vnc_mirrorlink_type = -1;
716 static int hf_vnc_mirrorlink_length = -1;
717 static int hf_vnc_mirrorlink_version_major = -1;
718 static int hf_vnc_mirrorlink_version_minor = -1;
719 static int hf_vnc_mirrorlink_framebuffer_configuration = -1;
720 static int hf_vnc_mirrorlink_pixel_width = -1;
721 static int hf_vnc_mirrorlink_pixel_height = -1;
722 static int hf_vnc_mirrorlink_pixel_format = -1;
723 static int hf_vnc_mirrorlink_display_width = -1;
724 static int hf_vnc_mirrorlink_display_height = -1;
725 static int hf_vnc_mirrorlink_display_distance = -1;
726 static int hf_vnc_mirrorlink_keyboard_language = -1;
727 static int hf_vnc_mirrorlink_keyboard_country = -1;
728 static int hf_vnc_mirrorlink_ui_language = -1;
729 static int hf_vnc_mirrorlink_ui_country = -1;
730 static int hf_vnc_mirrorlink_knob_keys = -1;
731 static int hf_vnc_mirrorlink_device_keys = -1;
732 static int hf_vnc_mirrorlink_multimedia_keys = -1;
733 static int hf_vnc_mirrorlink_key_related = -1;
734 static int hf_vnc_mirrorlink_pointer_related = -1;
735 static int hf_vnc_mirrorlink_key_symbol_value_client = -1;
736 static int hf_vnc_mirrorlink_key_symbol_value_server = -1;
737 static int hf_vnc_mirrorlink_key_configuration = -1;
738 static int hf_vnc_mirrorlink_key_num_events = -1;
739 static int hf_vnc_mirrorlink_key_event_counter = -1;
740 static int hf_vnc_mirrorlink_key_symbol_value = -1;
741 static int hf_vnc_mirrorlink_key_request_configuration = -1;
742 static int hf_vnc_mirrorlink_keyboard_configuration = -1;
743 static int hf_vnc_mirrorlink_cursor_x = -1;
744 static int hf_vnc_mirrorlink_cursor_y = -1;
745 static int hf_vnc_mirrorlink_text_x = -1;
746 static int hf_vnc_mirrorlink_text_y = -1;
747 static int hf_vnc_mirrorlink_text_width = -1;
748 static int hf_vnc_mirrorlink_text_height = -1;
749 static int hf_vnc_mirrorlink_keyboard_request_configuration = -1;
750 static int hf_vnc_mirrorlink_device_status = -1;
751 static int hf_vnc_mirrorlink_app_id = -1;
752 static int hf_vnc_mirrorlink_fb_block_x = -1;
753 static int hf_vnc_mirrorlink_fb_block_y = -1;
754 static int hf_vnc_mirrorlink_fb_block_width = -1;
755 static int hf_vnc_mirrorlink_fb_block_height = -1;
756 static int hf_vnc_mirrorlink_fb_block_reason = -1;
757 static int hf_vnc_mirrorlink_audio_block_reason = -1;
758 static int hf_vnc_mirrorlink_touch_num_events = -1;
759 static int hf_vnc_mirrorlink_touch_x = -1;
760 static int hf_vnc_mirrorlink_touch_y = -1;
761 static int hf_vnc_mirrorlink_touch_id = -1;
762 static int hf_vnc_mirrorlink_touch_pressure = -1;
763 static int hf_vnc_mirrorlink_text = -1;
764 static int hf_vnc_mirrorlink_text_length = -1;
765 static int hf_vnc_mirrorlink_text_max_length = -1;
766 static int hf_vnc_mirrorlink_unknown = -1;
768 /* Context Information */
769 static int hf_vnc_context_information_app_id = -1;
770 static int hf_vnc_context_information_app_category = -1;
771 static int hf_vnc_context_information_app_trust_level = -1;
772 static int hf_vnc_context_information_content_category = -1;
773 static int hf_vnc_context_information_content_rules = -1;
774 static int hf_vnc_context_information_content_trust_level = -1;
776 /* Scan Line based Run-Length Encoding */
777 static int hf_vnc_slrle_run_num = -1;
778 static int hf_vnc_slrle_run_data = -1;
780 /* H.264 Encoding */
781 static int hf_vnc_h264_slice_type = -1;
782 static int hf_vnc_h264_nbytes = -1;
783 static int hf_vnc_h264_width = -1;
784 static int hf_vnc_h264_height = -1;
785 static int hf_vnc_h264_data = -1;
787 /********** End of Server Message Types **********/
789 static gboolean vnc_preference_desegment = TRUE;
791 /* Initialize the subtree pointers */
792 static gint ett_vnc = -1;
793 static gint ett_vnc_client_message_type = -1;
794 static gint ett_vnc_server_message_type = -1;
795 static gint ett_vnc_rect = -1;
796 static gint ett_vnc_encoding_type = -1;
797 static gint ett_vnc_rre_subrect = -1;
798 static gint ett_vnc_hextile_subencoding_mask = -1;
799 static gint ett_vnc_hextile_num_subrects = -1;
800 static gint ett_vnc_hextile_subrect = -1;
801 static gint ett_vnc_hextile_tile = -1;
802 static gint ett_vnc_zrle_subencoding = -1;
803 static gint ett_vnc_colormap_num_groups = -1;
804 static gint ett_vnc_colormap_color_group = -1;
805 static gint ett_vnc_desktop_screen = -1;
806 static gint ett_vnc_key_events = -1;
807 static gint ett_vnc_touch_events = -1;
808 static gint ett_vnc_slrle_subline = -1;
810 static expert_field ei_vnc_possible_gtk_vnc_bug = EI_INIT;
811 static expert_field ei_vnc_auth_code_mismatch = EI_INIT;
812 static expert_field ei_vnc_unknown_tight_vnc_auth = EI_INIT;
813 static expert_field ei_vnc_too_many_rectangles = EI_INIT;
814 static expert_field ei_vnc_too_many_sub_rectangles = EI_INIT;
815 static expert_field ei_vnc_invalid_encoding = EI_INIT;
816 static expert_field ei_vnc_too_many_colors = EI_INIT;
817 static expert_field ei_vnc_too_many_cut_text = EI_INIT;
819 /* Global so they keep their value between packets */
820 guint8 vnc_bytes_per_pixel;
821 guint8 vnc_depth;
824 static dissector_handle_t vnc_handle;
826 /* Code to dissect the packets */
827 static void
828 dissect_vnc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
830 gboolean ret;
831 gint offset = 0;
833 /* Set up structures needed to add the protocol subtree and manage it */
834 proto_item *ti = NULL;
835 proto_tree *vnc_tree = NULL;
837 conversation_t *conversation;
838 vnc_conversation_t *per_conversation_info;
840 conversation = find_or_create_conversation(pinfo);
842 /* Retrieve information from conversation, or add it if it isn't
843 * there yet */
844 per_conversation_info = (vnc_conversation_t *)conversation_get_proto_data(conversation, proto_vnc);
845 if(!per_conversation_info) {
846 per_conversation_info = wmem_new(wmem_file_scope(), vnc_conversation_t);
848 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_SERVER_VERSION;
849 per_conversation_info->security_type_selected = VNC_SECURITY_TYPE_INVALID;
850 per_conversation_info->tight_enabled = FALSE;
852 conversation_add_proto_data(conversation, proto_vnc, per_conversation_info);
856 /* Make entries in Protocol column and Info column on summary display */
857 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VNC");
859 /* First, clear the info column */
860 col_clear(pinfo->cinfo, COL_INFO);
862 /* create display subtree for the protocol */
863 if(tree) {
864 ti = proto_tree_add_item(tree, proto_vnc, tvb, 0, -1, ENC_NA);
865 vnc_tree = proto_item_add_subtree(ti, ett_vnc);
868 offset = 0; /* Start at the beginning of the VNC protocol data */
870 /* Dissect any remaining session startup messages */
871 ret = vnc_startup_messages(tvb, pinfo, offset, vnc_tree,
872 per_conversation_info);
874 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
875 vnc_set_depth(pinfo, vnc_depth);
877 if(!ret) {
878 if(DEST_PORT_VNC || per_conversation_info->server_port == pinfo->destport)
879 vnc_client_to_server(tvb, pinfo, &offset, vnc_tree);
880 else
881 vnc_server_to_client(tvb, pinfo, &offset, vnc_tree);
885 /* Returns the new offset after processing the 4-byte vendor string */
886 static gint
887 process_vendor(proto_tree *tree, gint hfindex, tvbuff_t *tvb, gint offset)
889 gchar *vendor;
890 proto_item *ti;
892 if (tree) {
893 vendor = tvb_get_string(wmem_packet_scope(), tvb, offset, 4);
895 ti = proto_tree_add_string(tree, hfindex, tvb, offset, 4, vendor);
897 if(g_ascii_strcasecmp(vendor, "STDV") == 0)
898 proto_item_append_text(ti, " (Standard VNC vendor)");
899 else if(g_ascii_strcasecmp(vendor, "TRDV") == 0)
900 proto_item_append_text(ti, " (Tridia VNC vendor)");
901 else if(g_ascii_strcasecmp(vendor, "TGHT") == 0)
902 proto_item_append_text(ti, " (Tight VNC vendor)");
905 offset += 4;
906 return offset;
909 /* Returns the new offset after processing the specified number of capabilities */
910 static gint
911 process_tight_capabilities(proto_tree *tree,
912 gint type_index, gint vendor_index, gint name_index,
913 tvbuff_t *tvb, gint offset, const gint num_capabilities)
915 gint i;
916 /* See vnc_unixsrc/include/rfbproto.h:rfbCapabilityInfo */
918 for (i = 0; i < num_capabilities; i++) {
919 char *name;
921 proto_tree_add_item(tree, type_index, tvb, offset, 4, ENC_BIG_ENDIAN);
922 offset += 4;
924 offset = process_vendor(tree, vendor_index, tvb, offset);
926 name = tvb_get_string(wmem_packet_scope(), tvb, offset, 8);
927 proto_tree_add_string(tree, name_index, tvb, offset, 8, name);
928 offset += 8;
931 return offset;
934 /* Returns true if this looks like a client or server version packet: 12 bytes, in the format "RFB xxx.yyy\n" .
935 * Will check for the 12 bytes exact length, the 'RFB ' string and that it ends with a '\n'.
936 * The exact 'xxx.yyy' is checked later, by trying to convert it to a double using g_ascii_strtod.
937 * pinfo and tree are NULL when using this function to check the heuristics for dissection. If we're
938 * checking the heuristics, we don't need to add expert_info, we just reject that packet as not
939 * being a VNC packet.
941 static gboolean
942 vnc_is_client_or_server_version_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
944 proto_item *bug_item;
946 if(tvb_length(tvb) != 12) {
947 return FALSE;
950 if(tvb_strncaseeql(tvb, 0, "RFB ", 4) != 0) {
951 return FALSE;
954 /* 0x2e = '.' 0xa = '\n' */
955 if (tvb_get_guint8(tvb, 7) != 0x2e) {
956 return FALSE;
959 if (tvb_get_guint8(tvb,11) != 0xa) {
960 if (tvb_get_guint8(tvb,11) == 0) {
961 /* Per bug 5469, It appears that any VNC clients using gtk-vnc before [1] was
962 * fixed will exhibit the described protocol violation that prevents wireshark
963 * from dissecting the session.
965 * [1] http://git.gnome.org/browse/gtk-vnc/commit/?id=bc9e2b19167686dd381a0508af1a5113675d08a2
967 if ((pinfo != NULL) && (tree != NULL)) {
968 bug_item = proto_tree_add_text(tree, tvb, -1, 0, "NULL found in greeting");
969 expert_add_info(pinfo, bug_item, &ei_vnc_possible_gtk_vnc_bug);
972 return TRUE;
975 return FALSE;
978 return TRUE;
981 static gboolean test_vnc_protocol(tvbuff_t *tvb, packet_info *pinfo,
982 proto_tree *tree, void *data _U_)
984 conversation_t *conversation;
986 if (vnc_is_client_or_server_version_message(tvb, NULL, NULL)) {
987 conversation = conversation_new(pinfo->fd->num, &pinfo->src,
988 &pinfo->dst, pinfo->ptype,
989 pinfo->srcport,
990 pinfo->destport, 0);
991 conversation_set_dissector(conversation, vnc_handle);
992 dissect_vnc(tvb, pinfo, tree);
993 return TRUE;
995 return FALSE;
998 /* Returns true if additional session startup messages follow */
999 static gboolean
1000 vnc_startup_messages(tvbuff_t *tvb, packet_info *pinfo, gint offset,
1001 proto_tree *tree, vnc_conversation_t
1002 *per_conversation_info)
1004 guint8 num_security_types;
1005 guint32 desktop_name_len, auth_result, text_len, auth_code;
1006 vnc_packet_t *per_packet_info;
1007 gint num_tunnel_types;
1008 gint num_auth_types;
1009 proto_item* auth_item;
1011 per_packet_info = (vnc_packet_t *)p_get_proto_data(pinfo->fd, proto_vnc, 0);
1013 if(!per_packet_info) {
1014 per_packet_info = wmem_new(wmem_file_scope(), vnc_packet_t);
1016 per_packet_info->state = per_conversation_info->vnc_next_state;
1017 per_packet_info->preferred_encoding = -1;
1019 p_add_proto_data(pinfo->fd, proto_vnc, 0, per_packet_info);
1022 /* Packet dissection follows */
1023 switch(per_packet_info->state) {
1025 case VNC_SESSION_STATE_SERVER_VERSION :
1026 if (!vnc_is_client_or_server_version_message(tvb, pinfo, tree))
1027 return TRUE; /* we still hope to get a SERVER_VERSION message some day. Do not proceed yet */
1029 proto_tree_add_item(tree, hf_vnc_server_proto_ver, tvb, 4,
1030 7, ENC_ASCII|ENC_NA);
1031 per_conversation_info->server_proto_ver =
1032 g_ascii_strtod((char *)tvb_get_string(wmem_packet_scope(), tvb, 4, 7), NULL);
1033 per_conversation_info->server_port = pinfo->srcport;
1035 col_add_fstr(pinfo->cinfo, COL_INFO,
1036 "Server protocol version: %s",
1037 tvb_format_text(tvb, 4, 7));
1039 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_CLIENT_VERSION;
1040 break;
1042 case VNC_SESSION_STATE_CLIENT_VERSION :
1043 if (!vnc_is_client_or_server_version_message(tvb, pinfo, tree))
1044 return TRUE; /* we still hope to get a CLIENT_VERSION message some day. Do not proceed yet */
1046 proto_tree_add_item(tree, hf_vnc_client_proto_ver, tvb,
1047 4, 7, ENC_ASCII|ENC_NA);
1048 per_conversation_info->client_proto_ver =
1049 g_ascii_strtod((char *)tvb_get_string(wmem_packet_scope(), tvb, 4, 7), NULL);
1051 col_add_fstr(pinfo->cinfo, COL_INFO,
1052 "Client protocol version: %s",
1053 tvb_format_text(tvb, 4, 7));
1055 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_SECURITY;
1056 break;
1058 case VNC_SESSION_STATE_SECURITY :
1059 col_set_str(pinfo->cinfo, COL_INFO, "Security types supported");
1061 /* We're checking against the client protocol version because
1062 * the client is the final decider on which version to use
1063 * after the server offers the highest version it supports. */
1065 if(per_conversation_info->client_proto_ver >= 3.007) {
1066 num_security_types = tvb_get_guint8(tvb, offset);
1067 if (tree) {
1068 proto_tree_add_item(tree,
1069 hf_vnc_num_security_types,
1070 tvb, offset, 1, ENC_BIG_ENDIAN);
1072 for(offset = 1; offset <= num_security_types; offset++){
1073 proto_tree_add_item(tree,
1074 hf_vnc_security_type, tvb,
1075 offset, 1, ENC_BIG_ENDIAN);
1078 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_SECURITY_TYPES;
1079 } else {
1080 /* Version < 3.007: The server decides the
1081 * authentication type for us to use */
1082 proto_tree_add_item(tree, hf_vnc_server_security_type,
1083 tvb, offset, 4, ENC_BIG_ENDIAN);
1084 /* The cast below is possible since in older versions of the protocol the only possible values are 0,1,2 */
1085 per_conversation_info->security_type_selected = (guint8)tvb_get_ntohl(tvb, offset);
1086 switch(per_conversation_info->security_type_selected) {
1088 case VNC_SECURITY_TYPE_INVALID:
1089 /* TODO: In this case (INVALID) the connection has failed */
1090 /* and there should be an error string describing the error */
1091 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_SECURITY_TYPES;
1092 break;
1094 case VNC_SECURITY_TYPE_NONE:
1095 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_CLIENT_INIT;
1096 break;
1098 case VNC_SECURITY_TYPE_VNC:
1099 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_VNC_AUTHENTICATION_CHALLENGE;
1100 break;
1102 case VNC_SECURITY_TYPE_ARD:
1103 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_ARD_AUTHENTICATION_CHALLENGE;
1104 break;
1106 default:
1107 /* Security type not supported by this dissector */
1108 break;
1112 break;
1114 case VNC_SESSION_STATE_SECURITY_TYPES :
1115 col_set_str(pinfo->cinfo, COL_INFO, "Authentication type selected by client");
1116 proto_tree_add_item(tree, hf_vnc_client_security_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1117 per_conversation_info->security_type_selected =
1118 tvb_get_guint8(tvb, offset);
1120 switch(per_conversation_info->security_type_selected) {
1122 case VNC_SECURITY_TYPE_NONE :
1123 if(per_conversation_info->client_proto_ver >= 3.008)
1124 per_conversation_info->vnc_next_state =
1125 VNC_SESSION_STATE_SECURITY_RESULT;
1126 else
1127 per_conversation_info->vnc_next_state =
1128 VNC_SESSION_STATE_CLIENT_INIT;
1130 break;
1132 case VNC_SECURITY_TYPE_VNC :
1133 per_conversation_info->vnc_next_state =
1134 VNC_SESSION_STATE_VNC_AUTHENTICATION_CHALLENGE;
1135 break;
1137 case VNC_SECURITY_TYPE_TIGHT :
1138 per_conversation_info->vnc_next_state =
1139 VNC_SESSION_STATE_TIGHT_TUNNELING_CAPABILITIES;
1140 per_conversation_info->tight_enabled = TRUE;
1141 break;
1143 case VNC_SECURITY_TYPE_ARD:
1144 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_ARD_AUTHENTICATION_CHALLENGE;
1145 break;
1147 default :
1148 /* Security type not supported by this dissector */
1149 break;
1152 break;
1154 case VNC_SESSION_STATE_TIGHT_TUNNELING_CAPABILITIES :
1156 gint i;
1158 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC tunneling capabilities supported");
1160 proto_tree_add_item(tree, hf_vnc_tight_num_tunnel_types, tvb, offset, 4, ENC_BIG_ENDIAN);
1161 num_tunnel_types = tvb_get_ntohl(tvb, offset);
1163 offset += 4;
1165 for(i = 0; i < num_tunnel_types; i++) {
1166 /* TightVNC and Xvnc don't support any tunnel capabilities yet, but each capability
1167 * is 16 bytes, so skip them.
1170 proto_tree_add_item(tree, hf_vnc_tight_tunnel_type, tvb, offset, 16, ENC_BIG_ENDIAN);
1171 offset += 16;
1174 if (num_tunnel_types == 0)
1175 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_TIGHT_AUTH_CAPABILITIES;
1176 else
1177 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_TIGHT_TUNNEL_TYPE_REPLY;
1178 break;
1180 case VNC_SESSION_STATE_TIGHT_TUNNEL_TYPE_REPLY:
1181 /* Neither TightVNC nor Xvnc implement this; they just have a placeholder that emits an error
1182 * message and closes the connection (xserver/hw/vnc/auth.c:rfbProcessClientTunnelingType).
1183 * We should actually never get here...
1185 break;
1187 case VNC_SESSION_STATE_TIGHT_AUTH_CAPABILITIES:
1188 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC authentication capabilities supported");
1190 proto_tree_add_item(tree, hf_vnc_tight_num_auth_types, tvb, offset, 4, ENC_BIG_ENDIAN);
1191 num_auth_types = tvb_get_ntohl(tvb, offset);
1192 offset += 4;
1195 int i;
1196 guint8 *vendor, *signature;
1197 for (i = 0; i < 1; i++) {
1198 auth_code = tvb_get_ntohl(tvb, offset);
1199 auth_item = proto_tree_add_item(tree, hf_vnc_tight_auth_code, tvb, offset, 4, ENC_BIG_ENDIAN);
1200 offset += 4;
1201 vendor = tvb_get_string(wmem_packet_scope(), tvb, offset, 4);
1202 process_vendor(tree, hf_vnc_tight_server_vendor, tvb, offset);
1203 offset += 4;
1204 signature = tvb_get_string(wmem_packet_scope(), tvb, offset, 8);
1205 proto_tree_add_text(tree, tvb, offset, 8, "Signature: %s", signature);
1206 offset += 8;
1208 switch(auth_code) {
1209 case VNC_SECURITY_TYPE_NONE:
1210 if ((g_ascii_strcasecmp(vendor, "STDV") != 0) || (g_ascii_strcasecmp(signature, "NOAUTH__") != 0)) {
1211 expert_add_info(pinfo, auth_item, &ei_vnc_auth_code_mismatch);
1213 break;
1214 case VNC_SECURITY_TYPE_VNC:
1215 if ((g_ascii_strcasecmp(vendor, "STDV") != 0) || (g_ascii_strcasecmp(signature, "VNCAUTH_") != 0)) {
1216 expert_add_info(pinfo, auth_item, &ei_vnc_auth_code_mismatch);
1218 break;
1219 case VNC_SECURITY_TYPE_VENCRYPT:
1220 if ((g_ascii_strcasecmp(vendor, "VENC") != 0) || (g_ascii_strcasecmp(signature, "VENCRYPT") != 0)) {
1221 expert_add_info(pinfo, auth_item, &ei_vnc_auth_code_mismatch);
1223 break;
1224 case VNC_SECURITY_TYPE_GTK_VNC_SASL:
1225 if ((g_ascii_strcasecmp(vendor, "GTKV") != 0) || (g_ascii_strcasecmp(signature, "SASL____") != 0)) {
1226 expert_add_info(pinfo, auth_item, &ei_vnc_auth_code_mismatch);
1228 break;
1229 case VNC_TIGHT_AUTH_TGHT_ULGNAUTH:
1230 if ((g_ascii_strcasecmp(vendor, "TGHT") != 0) || (g_ascii_strcasecmp(signature, "ULGNAUTH") != 0)) {
1231 expert_add_info(pinfo, auth_item, &ei_vnc_auth_code_mismatch);
1233 break;
1234 case VNC_TIGHT_AUTH_TGHT_XTRNAUTH:
1235 if ((g_ascii_strcasecmp(vendor, "TGHT") != 0) || (g_ascii_strcasecmp(signature, "XTRNAUTH") != 0)) {
1236 expert_add_info(pinfo, auth_item, &ei_vnc_auth_code_mismatch);
1238 break;
1239 default:
1240 expert_add_info(pinfo, auth_item, &ei_vnc_unknown_tight_vnc_auth);
1241 break;
1246 if (num_auth_types == 0)
1247 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_CLIENT_INIT;
1248 else
1249 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_TIGHT_AUTH_TYPE_REPLY;
1250 break;
1252 case VNC_SESSION_STATE_TIGHT_AUTH_TYPE_REPLY:
1253 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC authentication type selected by client");
1254 auth_code = tvb_get_ntohl(tvb, offset);
1255 auth_item = proto_tree_add_item(tree, hf_vnc_tight_auth_code, tvb, offset, 4, ENC_BIG_ENDIAN);
1257 switch(auth_code) {
1258 case VNC_SECURITY_TYPE_NONE:
1259 per_conversation_info->security_type_selected = VNC_SECURITY_TYPE_NONE;
1260 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_CLIENT_INIT;
1261 break;
1262 case VNC_SECURITY_TYPE_VNC:
1263 per_conversation_info->security_type_selected = VNC_SECURITY_TYPE_VNC;
1264 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_VNC_AUTHENTICATION_CHALLENGE;
1265 break;
1266 case VNC_SECURITY_TYPE_GTK_VNC_SASL:
1267 per_conversation_info->security_type_selected = VNC_SECURITY_TYPE_GTK_VNC_SASL;
1268 /* TODO: dissection not implemented yet */
1269 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_TIGHT_UNKNOWN_PACKET3;
1270 break;
1271 case VNC_TIGHT_AUTH_TGHT_ULGNAUTH:
1272 per_conversation_info->security_type_selected = VNC_TIGHT_AUTH_TGHT_ULGNAUTH;
1273 /* TODO: dissection not implemented yet */
1274 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_TIGHT_UNKNOWN_PACKET3;
1275 break;
1276 case VNC_TIGHT_AUTH_TGHT_XTRNAUTH:
1277 per_conversation_info->security_type_selected = VNC_TIGHT_AUTH_TGHT_XTRNAUTH;
1278 /* TODO: dissection not implemented yet */
1279 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_TIGHT_UNKNOWN_PACKET3;
1280 break;
1281 default:
1282 expert_add_info(pinfo, auth_item, &ei_vnc_unknown_tight_vnc_auth);
1283 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_TIGHT_UNKNOWN_PACKET3;
1284 break;
1287 break;
1289 case VNC_SESSION_STATE_TIGHT_UNKNOWN_PACKET3 :
1290 col_set_str(pinfo->cinfo, COL_INFO, "Unknown packet (TightVNC)");
1292 proto_tree_add_text(tree, tvb, offset, -1,
1293 "Unknown packet (TightVNC)");
1295 per_conversation_info->vnc_next_state =
1296 VNC_SESSION_STATE_VNC_AUTHENTICATION_CHALLENGE;
1298 break;
1300 case VNC_SESSION_STATE_VNC_AUTHENTICATION_CHALLENGE :
1301 col_set_str(pinfo->cinfo, COL_INFO, "Authentication challenge from server");
1303 proto_tree_add_item(tree, hf_vnc_auth_challenge, tvb,
1304 offset, 16, ENC_NA);
1306 per_conversation_info->vnc_next_state =
1307 VNC_SESSION_STATE_VNC_AUTHENTICATION_RESPONSE;
1308 break;
1310 case VNC_SESSION_STATE_VNC_AUTHENTICATION_RESPONSE :
1311 col_set_str(pinfo->cinfo, COL_INFO, "Authentication response from client");
1313 proto_tree_add_item(tree, hf_vnc_auth_response, tvb,
1314 offset, 16, ENC_NA);
1316 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_SECURITY_RESULT;
1317 break;
1319 case VNC_SESSION_STATE_ARD_AUTHENTICATION_CHALLENGE :
1321 gint key_len;
1323 col_set_str(pinfo->cinfo, COL_INFO, "ARD authentication challenge");
1325 proto_tree_add_item(tree, hf_vnc_ard_auth_generator, tvb,
1326 offset, 2, ENC_BIG_ENDIAN);
1327 proto_tree_add_item(tree, hf_vnc_ard_auth_key_len, tvb,
1328 offset + 2, 2, ENC_BIG_ENDIAN);
1330 key_len = tvb_get_ntohs(tvb, offset + 2);
1332 offset += 4;
1334 proto_tree_add_item(tree, hf_vnc_ard_auth_modulus, tvb,
1335 offset, key_len, ENC_NA);
1336 proto_tree_add_item(tree, hf_vnc_ard_auth_server_key, tvb,
1337 offset + key_len, key_len, ENC_NA);
1339 per_conversation_info->ard_key_length = key_len;
1340 per_conversation_info->vnc_next_state =
1341 VNC_SESSION_STATE_ARD_AUTHENTICATION_RESPONSE;
1343 break;
1345 case VNC_SESSION_STATE_ARD_AUTHENTICATION_RESPONSE :
1346 col_set_str(pinfo->cinfo, COL_INFO, "ARD authentication response");
1348 proto_tree_add_item(tree, hf_vnc_ard_auth_credentials, tvb,
1349 offset, 128, ENC_NA);
1350 proto_tree_add_item(tree, hf_vnc_ard_auth_client_key, tvb,
1351 offset + 128, per_conversation_info->ard_key_length, ENC_NA);
1353 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_SECURITY_RESULT;
1354 break;
1356 case VNC_SESSION_STATE_SECURITY_RESULT :
1357 col_set_str(pinfo->cinfo, COL_INFO, "Authentication result");
1359 proto_tree_add_item(tree, hf_vnc_auth_result, tvb, offset,
1360 4, ENC_BIG_ENDIAN);
1361 auth_result = tvb_get_ntohl(tvb, offset);
1362 offset += 4;
1364 switch(auth_result) {
1366 case 0 : /* OK */
1367 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_CLIENT_INIT;
1368 break;
1370 case 1 : /* Failed */
1371 if(per_conversation_info->client_proto_ver >= 3.008) {
1372 text_len = tvb_get_ntohl(tvb, offset);
1373 proto_tree_add_item(tree, hf_vnc_auth_error_length, tvb, offset, 4, ENC_BIG_ENDIAN);
1374 offset += 4;
1376 proto_tree_add_item(tree, hf_vnc_auth_error, tvb,
1377 offset, text_len, ENC_ASCII|ENC_NA);
1380 return TRUE; /* All versions: Do not continue
1381 processing VNC packets as connection
1382 will be closed after this packet. */
1384 break;
1387 break;
1389 case VNC_SESSION_STATE_CLIENT_INIT :
1390 col_set_str(pinfo->cinfo, COL_INFO, "Share desktop flag");
1392 proto_tree_add_item(tree, hf_vnc_share_desktop_flag, tvb,
1393 offset, 1, ENC_BIG_ENDIAN);
1395 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_SERVER_INIT;
1397 break;
1399 case VNC_SESSION_STATE_SERVER_INIT :
1400 col_set_str(pinfo->cinfo, COL_INFO, "Server framebuffer parameters");
1402 proto_tree_add_item(tree, hf_vnc_width, tvb, offset, 2,
1403 ENC_BIG_ENDIAN);
1404 offset += 2;
1406 proto_tree_add_item(tree, hf_vnc_height, tvb, offset, 2,
1407 ENC_BIG_ENDIAN);
1408 offset += 2;
1410 proto_tree_add_item(tree, hf_vnc_server_bits_per_pixel,
1411 tvb, offset, 1, ENC_BIG_ENDIAN);
1412 vnc_bytes_per_pixel = tvb_get_guint8(tvb, offset)/8;
1413 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
1414 offset += 1;
1416 proto_tree_add_item(tree, hf_vnc_server_depth, tvb, offset,
1417 1, ENC_BIG_ENDIAN);
1418 offset += 1;
1420 proto_tree_add_item(tree, hf_vnc_server_big_endian_flag,
1421 tvb, offset, 1, ENC_BIG_ENDIAN);
1422 offset += 1;
1424 proto_tree_add_item(tree, hf_vnc_server_true_color_flag,
1425 tvb, offset, 1, ENC_BIG_ENDIAN);
1426 offset += 1;
1428 proto_tree_add_item(tree, hf_vnc_server_red_max,
1429 tvb, offset, 2, ENC_BIG_ENDIAN);
1430 offset += 2;
1432 proto_tree_add_item(tree, hf_vnc_server_green_max,
1433 tvb, offset, 2, ENC_BIG_ENDIAN);
1434 offset += 2;
1436 proto_tree_add_item(tree, hf_vnc_server_blue_max,
1437 tvb, offset, 2, ENC_BIG_ENDIAN);
1438 offset += 2;
1440 proto_tree_add_item(tree, hf_vnc_server_red_shift,
1441 tvb, offset, 1, ENC_BIG_ENDIAN);
1442 offset += 1;
1444 proto_tree_add_item(tree, hf_vnc_server_green_shift,
1445 tvb, offset, 1, ENC_BIG_ENDIAN);
1446 offset += 1;
1448 proto_tree_add_item(tree, hf_vnc_server_blue_shift,
1449 tvb, offset, 1, ENC_BIG_ENDIAN);
1450 offset += 1;
1452 proto_tree_add_item(tree, hf_vnc_padding,
1453 tvb, offset, 3, ENC_NA);
1454 offset += 3; /* Skip over 3 bytes of padding */
1456 if(tvb_length_remaining(tvb, offset) > 4) {
1457 /* Sometimes the desktop name & length is skipped */
1458 proto_tree_add_item(tree, hf_vnc_desktop_name_len,
1459 tvb, offset, 4, ENC_BIG_ENDIAN);
1460 desktop_name_len = tvb_get_ntohl(tvb, offset);
1461 offset += 4;
1463 proto_tree_add_item(tree, hf_vnc_desktop_name,
1464 tvb, offset, desktop_name_len,
1465 ENC_ASCII|ENC_NA);
1468 if(per_conversation_info->tight_enabled == TRUE)
1469 per_conversation_info->vnc_next_state =
1470 VNC_SESSION_STATE_TIGHT_INTERACTION_CAPS;
1471 else
1472 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_NORMAL_TRAFFIC;
1473 break;
1475 case VNC_SESSION_STATE_TIGHT_INTERACTION_CAPS :
1476 col_set_str(pinfo->cinfo, COL_INFO, "TightVNC Interaction Capabilities");
1478 proto_tree_add_item(tree, hf_vnc_num_server_message_types,
1479 tvb, offset, 2, ENC_BIG_ENDIAN);
1480 per_conversation_info->num_server_message_types = tvb_get_ntohs(tvb, offset);
1481 offset += 2;
1483 proto_tree_add_item(tree, hf_vnc_num_client_message_types,
1484 tvb, offset, 2, ENC_BIG_ENDIAN);
1485 per_conversation_info->num_client_message_types = tvb_get_ntohs(tvb, offset);
1486 offset += 2;
1488 proto_tree_add_item(tree, hf_vnc_num_encoding_types,
1489 tvb, offset, 2, ENC_BIG_ENDIAN);
1490 per_conversation_info->num_encoding_types = tvb_get_ntohs(tvb, offset);
1491 offset += 2;
1493 proto_tree_add_item(tree, hf_vnc_padding, tvb, offset, 2, ENC_NA);
1494 offset += 2;
1496 offset = process_tight_capabilities(tree,
1497 hf_vnc_tight_server_message_type,
1498 hf_vnc_tight_server_vendor,
1499 hf_vnc_tight_server_name,
1500 tvb, offset, per_conversation_info->num_server_message_types);
1501 offset = process_tight_capabilities(tree,
1502 hf_vnc_tight_client_message_type,
1503 hf_vnc_tight_client_vendor,
1504 hf_vnc_tight_client_name,
1505 tvb, offset, per_conversation_info->num_client_message_types);
1506 process_tight_capabilities(tree,
1507 hf_vnc_tight_encoding_type,
1508 hf_vnc_tight_encoding_vendor,
1509 hf_vnc_tight_encoding_name,
1510 tvb, offset, per_conversation_info->num_encoding_types);
1512 per_conversation_info->vnc_next_state = VNC_SESSION_STATE_NORMAL_TRAFFIC;
1513 break;
1515 case VNC_SESSION_STATE_NORMAL_TRAFFIC :
1516 return FALSE;
1519 return TRUE;
1523 static void
1524 vnc_client_to_server(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1525 proto_tree *tree)
1527 guint8 message_type;
1529 proto_item *ti = NULL;
1530 proto_tree *vnc_client_message_type_tree;
1532 message_type = tvb_get_guint8(tvb, *offset);
1534 ti = proto_tree_add_item(tree, hf_vnc_client_message_type, tvb,
1535 *offset, 1, ENC_BIG_ENDIAN);
1537 vnc_client_message_type_tree =
1538 proto_item_add_subtree(ti, ett_vnc_client_message_type);
1540 *offset += 1;
1542 switch(message_type) {
1544 case VNC_CLIENT_MESSAGE_TYPE_SET_PIXEL_FORMAT :
1545 vnc_client_set_pixel_format(tvb, pinfo, offset,
1546 vnc_client_message_type_tree);
1547 break;
1549 case VNC_CLIENT_MESSAGE_TYPE_SET_ENCODING :
1550 vnc_client_set_encodings(tvb, pinfo, offset,
1551 vnc_client_message_type_tree);
1552 break;
1554 case VNC_CLIENT_MESSAGE_TYPE_FRAMEBUF_UPDATE_REQ :
1555 vnc_client_framebuffer_update_request(tvb, pinfo, offset,
1556 vnc_client_message_type_tree);
1557 break;
1559 case VNC_CLIENT_MESSAGE_TYPE_KEY_EVENT :
1560 vnc_client_key_event(tvb, pinfo, offset,
1561 vnc_client_message_type_tree);
1562 break;
1564 case VNC_CLIENT_MESSAGE_TYPE_POINTER_EVENT:
1565 vnc_client_pointer_event(tvb, pinfo, offset,
1566 vnc_client_message_type_tree);
1567 break;
1569 case VNC_CLIENT_MESSAGE_TYPE_CLIENT_CUT_TEXT :
1570 vnc_client_cut_text(tvb, pinfo, offset,
1571 vnc_client_message_type_tree);
1572 break;
1574 case VNC_CLIENT_MESSAGE_TYPE_MIRRORLINK :
1575 vnc_mirrorlink(tvb, pinfo, offset,
1576 vnc_client_message_type_tree);
1577 break;
1579 default :
1580 col_append_fstr(pinfo->cinfo, COL_INFO,
1581 "Unknown client message type (%u)",
1582 message_type);
1583 break;
1587 static void
1588 vnc_server_to_client(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1589 proto_tree *tree)
1591 gint start_offset;
1592 guint8 message_type;
1593 gint bytes_needed = 0, length_remaining;
1595 proto_item *ti = NULL;
1596 proto_tree *vnc_server_message_type_tree;
1598 start_offset = *offset;
1600 message_type = tvb_get_guint8(tvb, *offset);
1602 ti = proto_tree_add_item(tree, hf_vnc_server_message_type, tvb,
1603 *offset, 1, ENC_BIG_ENDIAN);
1604 vnc_server_message_type_tree =
1605 proto_item_add_subtree(ti, ett_vnc_server_message_type);
1607 *offset += 1;
1609 switch(message_type) {
1611 case VNC_SERVER_MESSAGE_TYPE_FRAMEBUFFER_UPDATE :
1612 bytes_needed =
1613 vnc_server_framebuffer_update(tvb, pinfo, offset,
1614 vnc_server_message_type_tree);
1615 break;
1617 case VNC_SERVER_MESSAGE_TYPE_SET_COLORMAP_ENTRIES :
1618 bytes_needed = vnc_server_set_colormap_entries(tvb, pinfo, offset, vnc_server_message_type_tree);
1619 break;
1621 case VNC_SERVER_MESSAGE_TYPE_RING_BELL :
1622 vnc_server_ring_bell(tvb, pinfo, offset,
1623 vnc_server_message_type_tree);
1624 break;
1626 case VNC_SERVER_MESSAGE_TYPE_CUT_TEXT :
1627 bytes_needed = vnc_server_cut_text(tvb, pinfo, offset,
1628 vnc_server_message_type_tree);
1629 break;
1631 case VNC_SERVER_MESSAGE_TYPE_MIRRORLINK :
1632 bytes_needed = vnc_mirrorlink(tvb, pinfo, offset,
1633 vnc_server_message_type_tree);
1634 break;
1636 default :
1637 col_append_str(pinfo->cinfo, COL_INFO,
1638 "Unknown server message type");
1639 break;
1642 if(bytes_needed > 0 && vnc_preference_desegment &&
1643 pinfo->can_desegment) {
1644 length_remaining = tvb_length_remaining(tvb, *offset);
1646 pinfo->desegment_offset = start_offset;
1647 pinfo->desegment_len = bytes_needed - length_remaining;
1648 return;
1653 static void
1654 vnc_client_set_pixel_format(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1655 proto_tree *tree)
1657 col_set_str(pinfo->cinfo, COL_INFO, "Client set pixel format");
1659 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 3, ENC_NA);
1660 *offset += 3; /* Skip over 3 bytes of padding */
1662 proto_tree_add_item(tree, hf_vnc_client_bits_per_pixel, tvb, *offset,
1663 1, ENC_BIG_ENDIAN);
1664 vnc_bytes_per_pixel = tvb_get_guint8(tvb, *offset)/8;
1665 vnc_set_bytes_per_pixel(pinfo, vnc_bytes_per_pixel);
1666 *offset += 1;
1668 proto_tree_add_item(tree, hf_vnc_client_depth, tvb, *offset,
1669 1, ENC_BIG_ENDIAN);
1670 vnc_depth = tvb_get_guint8(tvb, *offset);
1671 vnc_set_depth(pinfo, vnc_depth);
1672 *offset += 1;
1674 proto_tree_add_item(tree, hf_vnc_client_big_endian_flag, tvb, *offset,
1675 1, ENC_BIG_ENDIAN);
1676 *offset += 1;
1678 proto_tree_add_item(tree, hf_vnc_client_true_color_flag, tvb, *offset,
1679 1, ENC_BIG_ENDIAN);
1680 *offset += 1;
1682 proto_tree_add_item(tree, hf_vnc_client_red_max, tvb, *offset,
1683 2, ENC_BIG_ENDIAN);
1684 *offset += 2;
1686 proto_tree_add_item(tree, hf_vnc_client_green_max, tvb, *offset,
1687 2, ENC_BIG_ENDIAN);
1688 *offset += 2;
1690 proto_tree_add_item(tree, hf_vnc_client_blue_max, tvb, *offset,
1691 2, ENC_BIG_ENDIAN);
1692 *offset += 2;
1694 proto_tree_add_item(tree, hf_vnc_client_red_shift, tvb, *offset,
1695 1, ENC_BIG_ENDIAN);
1696 *offset += 1;
1698 proto_tree_add_item(tree, hf_vnc_client_green_shift, tvb, *offset,
1699 1, ENC_BIG_ENDIAN);
1700 *offset += 1;
1702 proto_tree_add_item(tree, hf_vnc_client_blue_shift, tvb, *offset,
1703 1, ENC_BIG_ENDIAN);
1704 *offset += 1;
1706 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 3, ENC_NA);
1707 *offset += 3; /* Skip over 3 bytes of padding */
1711 static void
1712 vnc_client_set_encodings(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1713 proto_tree *tree)
1715 guint16 number_of_encodings;
1716 guint counter;
1717 vnc_packet_t *per_packet_info;
1719 per_packet_info = (vnc_packet_t *)p_get_proto_data(pinfo->fd, proto_vnc, 0);
1720 /* Our calling function should have set the packet's proto data already */
1721 DISSECTOR_ASSERT(per_packet_info != NULL);
1723 col_set_str(pinfo->cinfo, COL_INFO, "Client set encodings");
1725 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 1, ENC_NA);
1726 *offset += 1; /* Skip over 1 byte of padding */
1728 number_of_encodings = tvb_get_ntohs(tvb, *offset);
1729 proto_tree_add_item(tree, hf_vnc_encoding_num, tvb, *offset, 2, ENC_BIG_ENDIAN);
1730 *offset += 2;
1732 per_packet_info->preferred_encoding = -1;
1734 for(counter = 0; counter < number_of_encodings; counter++) {
1735 proto_tree_add_item(tree,
1736 hf_vnc_client_set_encodings_encoding_type,
1737 tvb, *offset, 4, ENC_BIG_ENDIAN);
1739 /* Remember the first real encoding as the preferred encoding,
1740 * per xserver/hw/vnc/rfbserver.c:rfbProcessClientNormalMessage().
1741 * Otherwise, use RAW as the preferred encoding.
1743 if (per_packet_info->preferred_encoding == -1) {
1744 int encoding;
1746 encoding = tvb_get_ntohl(tvb, *offset);
1748 switch(encoding) {
1749 case VNC_ENCODING_TYPE_RAW:
1750 case VNC_ENCODING_TYPE_RRE:
1751 case VNC_ENCODING_TYPE_CORRE:
1752 case VNC_ENCODING_TYPE_HEXTILE:
1753 case VNC_ENCODING_TYPE_ZLIB:
1754 case VNC_ENCODING_TYPE_TIGHT:
1755 per_packet_info->preferred_encoding = encoding;
1756 break;
1760 *offset += 4;
1763 if (per_packet_info->preferred_encoding == -1)
1764 per_packet_info->preferred_encoding = VNC_ENCODING_TYPE_RAW;
1768 static void
1769 vnc_client_framebuffer_update_request(tvbuff_t *tvb, packet_info *pinfo,
1770 gint *offset, proto_tree *tree)
1772 col_set_str(pinfo->cinfo, COL_INFO, "Client framebuffer update request");
1774 proto_tree_add_item(tree, hf_vnc_update_req_incremental,
1775 tvb, *offset, 1, ENC_BIG_ENDIAN);
1776 *offset += 1;
1778 proto_tree_add_item(tree, hf_vnc_update_req_x_pos,
1779 tvb, *offset, 2, ENC_BIG_ENDIAN);
1780 *offset += 2;
1782 proto_tree_add_item(tree, hf_vnc_update_req_y_pos,
1783 tvb, *offset, 2, ENC_BIG_ENDIAN);
1784 *offset += 2;
1786 proto_tree_add_item(tree, hf_vnc_update_req_width, tvb,
1787 *offset, 2, ENC_BIG_ENDIAN);
1788 *offset += 2;
1790 proto_tree_add_item(tree, hf_vnc_update_req_height, tvb,
1791 *offset, 2, ENC_BIG_ENDIAN);
1792 *offset += 2;
1796 static void
1797 vnc_client_key_event(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1798 proto_tree *tree)
1800 col_set_str(pinfo->cinfo, COL_INFO, "Client key event");
1802 proto_tree_add_item(tree, hf_vnc_key_down, tvb, *offset, 1, ENC_BIG_ENDIAN);
1803 *offset += 1;
1805 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 2, ENC_NA);
1806 *offset += 2; /* Skip over 2 bytes of padding */
1808 proto_tree_add_item(tree, hf_vnc_key, tvb, *offset, 4, ENC_BIG_ENDIAN);
1809 *offset += 4;
1813 static void
1814 vnc_client_pointer_event(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1815 proto_tree *tree)
1817 col_set_str(pinfo->cinfo, COL_INFO, "Client pointer event");
1819 proto_tree_add_item(tree, hf_vnc_button_1_pos, tvb, *offset, 1, ENC_BIG_ENDIAN);
1820 proto_tree_add_item(tree, hf_vnc_button_2_pos, tvb, *offset, 1, ENC_BIG_ENDIAN);
1821 proto_tree_add_item(tree, hf_vnc_button_3_pos, tvb, *offset, 1, ENC_BIG_ENDIAN);
1822 proto_tree_add_item(tree, hf_vnc_button_4_pos, tvb, *offset, 1, ENC_BIG_ENDIAN);
1823 proto_tree_add_item(tree, hf_vnc_button_5_pos, tvb, *offset, 1, ENC_BIG_ENDIAN);
1824 proto_tree_add_item(tree, hf_vnc_button_6_pos, tvb, *offset, 1, ENC_BIG_ENDIAN);
1825 proto_tree_add_item(tree, hf_vnc_button_7_pos, tvb, *offset, 1, ENC_BIG_ENDIAN);
1826 proto_tree_add_item(tree, hf_vnc_button_8_pos, tvb, *offset, 1, ENC_BIG_ENDIAN);
1827 *offset += 1;
1829 proto_tree_add_item(tree, hf_vnc_pointer_x_pos, tvb, *offset, 2, ENC_BIG_ENDIAN);
1830 *offset += 2;
1832 proto_tree_add_item(tree, hf_vnc_pointer_y_pos, tvb, *offset, 2, ENC_BIG_ENDIAN);
1833 *offset += 2;
1837 static void
1838 vnc_client_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1839 proto_tree *tree)
1841 guint32 text_len;
1843 col_set_str(pinfo->cinfo, COL_INFO, "Client cut text");
1845 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 3, ENC_NA);
1846 *offset += 3; /* Skip over 3 bytes of padding */
1848 text_len = tvb_get_ntohl(tvb, *offset);
1849 proto_tree_add_item(tree, hf_vnc_client_cut_text_len, tvb, *offset, 4,
1850 ENC_BIG_ENDIAN);
1851 *offset += 4;
1853 proto_tree_add_item(tree, hf_vnc_client_cut_text, tvb, *offset,
1854 text_len, ENC_ASCII|ENC_NA);
1855 *offset += text_len;
1860 static guint
1861 vnc_server_framebuffer_update(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
1862 proto_tree *tree)
1864 gint ii;
1865 guint16 num_rects, width, height;
1866 guint bytes_needed = 0;
1867 guint32 encoding_type;
1868 proto_item *ti, *ti_x, *ti_y, *ti_width, *ti_height;
1869 proto_tree *vnc_rect_tree, *vnc_encoding_type_tree;
1871 col_set_str(pinfo->cinfo, COL_INFO, "Server framebuffer update");
1873 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 1, ENC_NA);
1874 *offset += 1;
1876 num_rects = tvb_get_ntohs(tvb, *offset);
1877 ti = proto_tree_add_item(tree, hf_vnc_rectangle_num, tvb, *offset, 2, ENC_BIG_ENDIAN);
1879 if (num_rects > 5000) {
1880 expert_add_info_format(pinfo, ti, &ei_vnc_too_many_rectangles,
1881 "Too many rectangles (%d), aborting dissection", num_rects);
1882 return(0);
1885 *offset += 2;
1887 for(ii = 0; ii < num_rects; ii++) {
1888 VNC_BYTES_NEEDED(12);
1890 ti = proto_tree_add_text(tree, tvb, *offset, 12,
1891 "Rectangle #%d", ii+1);
1893 vnc_rect_tree =
1894 proto_item_add_subtree(ti, ett_vnc_rect);
1896 ti_x = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_x_pos,
1897 tvb, *offset, 2, ENC_BIG_ENDIAN);
1898 *offset += 2;
1900 ti_y = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_y_pos,
1901 tvb, *offset, 2, ENC_BIG_ENDIAN);
1902 *offset += 2;
1904 ti_width = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_width,
1905 tvb, *offset, 2, ENC_BIG_ENDIAN);
1906 width = tvb_get_ntohs(tvb, *offset);
1907 *offset += 2;
1909 ti_height = proto_tree_add_item(vnc_rect_tree, hf_vnc_fb_update_height,
1910 tvb, *offset, 2, ENC_BIG_ENDIAN);
1911 height = tvb_get_ntohs(tvb, *offset);
1912 *offset += 2;
1914 ti = proto_tree_add_item(vnc_rect_tree,
1915 hf_vnc_fb_update_encoding_type,
1916 tvb, *offset, 4, ENC_BIG_ENDIAN);
1918 encoding_type = tvb_get_ntohl(tvb, *offset);
1919 *offset += 4;
1921 if (encoding_type == VNC_ENCODING_TYPE_LAST_RECT)
1922 break; /* exit the loop */
1924 vnc_encoding_type_tree =
1925 proto_item_add_subtree(ti, ett_vnc_encoding_type);
1927 switch(encoding_type) {
1929 case VNC_ENCODING_TYPE_RAW:
1930 bytes_needed = vnc_raw_encoding(tvb, pinfo, offset,
1931 vnc_encoding_type_tree,
1932 width, height);
1933 break;
1935 case VNC_ENCODING_TYPE_COPY_RECT:
1936 bytes_needed =
1937 vnc_copyrect_encoding(tvb, pinfo, offset,
1938 vnc_encoding_type_tree,
1939 width, height);
1940 break;
1942 case VNC_ENCODING_TYPE_RRE:
1943 bytes_needed =
1944 vnc_rre_encoding(tvb, pinfo, offset,
1945 vnc_encoding_type_tree,
1946 width, height);
1947 break;
1949 case VNC_ENCODING_TYPE_HEXTILE:
1950 bytes_needed =
1951 vnc_hextile_encoding(tvb, pinfo, offset,
1952 vnc_encoding_type_tree,
1953 width, height);
1954 break;
1956 case VNC_ENCODING_TYPE_RLE:
1957 bytes_needed =
1958 vnc_zrle_encoding(tvb, pinfo, offset,
1959 vnc_encoding_type_tree,
1960 width, height);
1961 break;
1963 case VNC_ENCODING_TYPE_TIGHT:
1964 bytes_needed =
1965 vnc_tight_encoding(tvb, pinfo, offset,
1966 vnc_encoding_type_tree,
1967 width, height);
1968 break;
1970 case VNC_ENCODING_TYPE_RICH_CURSOR:
1971 case VNC_ENCODING_TYPE_X_CURSOR:
1972 proto_item_append_text (ti_x, " (hotspot X)");
1973 proto_item_append_text (ti_y, " (hotspot Y)");
1974 proto_item_append_text (ti_width, " (cursor width)");
1975 proto_item_append_text (ti_height, " (cursor height)");
1977 if (encoding_type == VNC_ENCODING_TYPE_RICH_CURSOR)
1978 bytes_needed = vnc_rich_cursor_encoding(tvb, pinfo, offset, vnc_encoding_type_tree, width, height);
1979 else
1980 bytes_needed = vnc_x_cursor_encoding(tvb, pinfo, offset, vnc_encoding_type_tree, width, height);
1982 break;
1984 case VNC_ENCODING_TYPE_POINTER_POS:
1985 proto_item_append_text (ti_x, " (pointer X)");
1986 proto_item_append_text (ti_y, " (pointer Y)");
1987 proto_item_append_text (ti_width, " (unused)");
1988 proto_item_append_text (ti_height, " (unused)");
1989 bytes_needed = 0;
1990 break;
1992 case VNC_ENCODING_TYPE_DESKTOP_SIZE:
1994 /* There is no payload for this message type */
1996 bytes_needed = 0;
1997 break;
1999 case VNC_ENCODING_TYPE_EXTENDED_DESK_SIZE :
2000 bytes_needed = vnc_extended_desktop_size(tvb, offset, vnc_encoding_type_tree);
2001 break;
2003 case VNC_ENCODING_TYPE_KEYBOARD_LED_STATE :
2005 /* There is no payload for this message type */
2007 bytes_needed = 0;
2008 break;
2010 case VNC_ENCODING_TYPE_SUPPORTED_MESSAGES :
2011 bytes_needed = vnc_supported_messages(tvb, offset,
2012 vnc_encoding_type_tree,
2013 width);
2014 break;
2016 case VNC_ENCODING_TYPE_SUPPORTED_ENCODINGS :
2017 bytes_needed = vnc_supported_encodings(tvb, offset,
2018 vnc_encoding_type_tree,
2019 width, height);
2020 break;
2022 case VNC_ENCODING_TYPE_SERVER_IDENTITY :
2023 bytes_needed = vnc_server_identity(tvb, offset,
2024 vnc_encoding_type_tree,
2025 width);
2026 break;
2028 case VNC_ENCODING_TYPE_CONTEXT_INFORMATION :
2029 bytes_needed = vnc_context_information(tvb, offset,
2030 vnc_encoding_type_tree);
2031 break;
2033 case VNC_ENCODING_TYPE_SLRLE :
2034 bytes_needed = vnc_slrle_encoding(tvb, pinfo, offset,
2035 vnc_encoding_type_tree,
2036 height);
2037 break;
2039 case VNC_ENCODING_TYPE_H264 :
2040 bytes_needed = vnc_h264_encoding(tvb, offset,
2041 vnc_encoding_type_tree);
2042 break;
2046 /* Check if the routines above requested more bytes to
2047 * be desegmented. */
2048 if(bytes_needed > 0)
2049 return bytes_needed;
2052 return 0;
2055 static guint32
2056 vnc_extended_desktop_size(tvbuff_t *tvb, gint *offset, proto_tree *tree)
2059 guint8 i, num_of_screens;
2060 proto_item *ti;
2061 proto_tree *screen_tree;
2063 num_of_screens = tvb_get_guint8(tvb, *offset);
2064 proto_tree_add_item(tree, hf_vnc_desktop_screen_num, tvb, *offset, 1, ENC_BIG_ENDIAN);
2065 *offset += 1;
2066 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 3, ENC_NA);
2068 VNC_BYTES_NEEDED((guint32)(3 + (num_of_screens * 16)));
2069 *offset += 3;
2070 for(i = 0; i < num_of_screens; i++) {
2071 ti = proto_tree_add_text(tree, tvb, *offset, 16, "Screen #%u", i+1);
2072 screen_tree = proto_item_add_subtree(ti, ett_vnc_desktop_screen);
2074 proto_tree_add_item(screen_tree, hf_vnc_desktop_screen_id, tvb, *offset, 4, ENC_BIG_ENDIAN);
2075 *offset += 4;
2076 proto_tree_add_item(screen_tree, hf_vnc_desktop_screen_x, tvb, *offset, 2, ENC_BIG_ENDIAN);
2077 *offset += 2;
2078 proto_tree_add_item(screen_tree, hf_vnc_desktop_screen_y, tvb, *offset, 2, ENC_BIG_ENDIAN);
2079 *offset += 2;
2080 proto_tree_add_item(screen_tree, hf_vnc_desktop_screen_width, tvb, *offset, 2, ENC_BIG_ENDIAN);
2081 *offset += 2;
2082 proto_tree_add_item(screen_tree, hf_vnc_desktop_screen_height, tvb, *offset, 2, ENC_BIG_ENDIAN);
2083 *offset += 2;
2084 proto_tree_add_item(screen_tree, hf_vnc_desktop_screen_flags, tvb, *offset, 4, ENC_BIG_ENDIAN);
2085 *offset += 4;
2088 return 0;
2091 static guint
2092 vnc_raw_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2093 proto_tree *tree, const guint16 width, const guint16 height)
2095 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
2096 guint length;
2098 length = width * height * bytes_per_pixel;
2099 VNC_BYTES_NEEDED(length);
2101 proto_tree_add_item(tree, hf_vnc_raw_pixel_data, tvb, *offset,
2102 length, ENC_NA);
2103 *offset += length;
2105 return 0; /* bytes_needed */
2109 static guint
2110 vnc_copyrect_encoding(tvbuff_t *tvb, packet_info *pinfo _U_, gint *offset,
2111 proto_tree *tree, const guint16 width _U_, const guint16 height _U_)
2113 proto_tree_add_item(tree, hf_vnc_copyrect_src_x_pos, tvb, *offset,
2114 2, ENC_BIG_ENDIAN);
2115 *offset += 2;
2117 proto_tree_add_item(tree, hf_vnc_copyrect_src_y_pos, tvb, *offset,
2118 2, ENC_BIG_ENDIAN);
2119 *offset += 2;
2121 return 0; /* bytes_needed */
2125 static guint
2126 vnc_rre_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2127 proto_tree *tree, const guint16 width _U_, const guint16 height _U_)
2129 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
2130 guint32 num_subrects, i;
2131 guint bytes_needed;
2132 proto_item *ti;
2133 proto_tree *subrect_tree;
2135 VNC_BYTES_NEEDED(4);
2136 ti = proto_tree_add_item(tree, hf_vnc_rre_num_subrects, tvb, *offset,
2137 4, ENC_BIG_ENDIAN);
2138 num_subrects = tvb_get_ntohl(tvb, *offset);
2139 *offset += 4;
2141 if (num_subrects > 10000) {
2142 expert_add_info_format(pinfo, ti, &ei_vnc_too_many_sub_rectangles,
2143 "Too many sub-rectangles (%d), aborting dissection", num_subrects);
2144 return(0);
2147 *offset += 2;
2148 VNC_BYTES_NEEDED(bytes_per_pixel);
2149 proto_tree_add_item(tree, hf_vnc_rre_bg_pixel, tvb, *offset,
2150 bytes_per_pixel, ENC_NA);
2151 *offset += bytes_per_pixel;
2153 /* We know we need (at least) all these bytes, so ask for them now
2154 * (instead of a few at a time...).
2156 bytes_needed = bytes_per_pixel + 8;
2157 VNC_BYTES_NEEDED(bytes_needed * num_subrects);
2158 for(i = 0; i < num_subrects; i++) {
2160 ti = proto_tree_add_text(tree, tvb, *offset, bytes_per_pixel +
2161 8, "Subrectangle #%d", i+1);
2162 subrect_tree =
2163 proto_item_add_subtree(ti, ett_vnc_rre_subrect);
2165 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_pixel,
2166 tvb, *offset, bytes_per_pixel, ENC_NA);
2167 *offset += bytes_per_pixel;
2169 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_x_pos,
2170 tvb, *offset, 2, ENC_BIG_ENDIAN);
2171 *offset += 2;
2173 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_y_pos,
2174 tvb, *offset, 2, ENC_BIG_ENDIAN);
2175 *offset += 2;
2177 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_width,
2178 tvb, *offset, 2, ENC_BIG_ENDIAN);
2179 *offset += 2;
2181 proto_tree_add_item(subrect_tree, hf_vnc_rre_subrect_height,
2182 tvb, *offset, 2, ENC_BIG_ENDIAN);
2183 *offset += 2;
2186 return 0; /* bytes_needed */
2190 static guint
2191 vnc_hextile_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2192 proto_tree *tree, const guint16 width, const guint16 height)
2194 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
2195 guint8 i, subencoding_mask, num_subrects, subrect_len, tile_height, tile_width;
2196 guint32 raw_length;
2197 proto_tree *tile_tree, *subencoding_mask_tree, *subrect_tree, *num_subrects_tree;
2198 proto_item *ti, *tile_item;
2199 guint16 current_height = 0, current_width;
2201 while(current_height != height) {
2202 if (current_height + 16 > height)
2203 tile_height = height - current_height;
2204 else
2205 tile_height = 16;
2206 current_height += tile_height;
2207 current_width = 0;
2208 while(current_width != width) {
2209 if (current_width + 16 > width)
2210 tile_width = width - current_width;
2211 else
2212 tile_width = 16;
2214 current_width += tile_width;
2216 VNC_BYTES_NEEDED(1);
2217 subencoding_mask = tvb_get_guint8(tvb, *offset);
2219 tile_item = proto_tree_add_text(tree, tvb, *offset, 1, "Tile {%d:%d}, sub encoding mask %u", current_width, current_height, subencoding_mask);
2220 tile_tree = proto_item_add_subtree(tile_item, ett_vnc_hextile_tile);
2222 ti = proto_tree_add_item(tile_tree, hf_vnc_hextile_subencoding_mask, tvb,
2223 *offset, 1, ENC_BIG_ENDIAN);
2225 subencoding_mask_tree =
2226 proto_item_add_subtree(ti, ett_vnc_hextile_subencoding_mask);
2228 proto_tree_add_item(subencoding_mask_tree,
2229 hf_vnc_hextile_raw, tvb, *offset, 1,
2230 ENC_BIG_ENDIAN);
2231 proto_tree_add_item(subencoding_mask_tree,
2232 hf_vnc_hextile_bg, tvb, *offset, 1,
2233 ENC_BIG_ENDIAN);
2234 proto_tree_add_item(subencoding_mask_tree,
2235 hf_vnc_hextile_fg, tvb, *offset, 1,
2236 ENC_BIG_ENDIAN);
2237 proto_tree_add_item(subencoding_mask_tree,
2238 hf_vnc_hextile_anysubrects, tvb, *offset, 1,
2239 ENC_BIG_ENDIAN);
2240 proto_tree_add_item(subencoding_mask_tree,
2241 hf_vnc_hextile_subrectscolored, tvb, *offset, 1,
2242 ENC_BIG_ENDIAN);
2243 *offset += 1;
2245 if(subencoding_mask & 0x1) { /* Raw */
2246 raw_length = tile_width * tile_height * bytes_per_pixel;
2248 proto_tree_add_item(tile_tree, hf_vnc_hextile_raw_value, tvb,
2249 *offset, raw_length, ENC_NA);
2250 VNC_BYTES_NEEDED(raw_length);
2251 *offset += raw_length;
2252 } else {
2253 if(subencoding_mask & 0x2) { /* Background Specified */
2254 VNC_BYTES_NEEDED(bytes_per_pixel);
2255 proto_tree_add_item(tile_tree, hf_vnc_hextile_bg_value,
2256 tvb, *offset, bytes_per_pixel,
2257 ENC_NA);
2258 *offset += bytes_per_pixel;
2261 if(subencoding_mask & 0x4) { /* Foreground Specified */
2262 VNC_BYTES_NEEDED(bytes_per_pixel);
2263 proto_tree_add_item(tile_tree, hf_vnc_hextile_fg_value,
2264 tvb, *offset, bytes_per_pixel,
2265 ENC_NA);
2266 *offset += bytes_per_pixel;
2269 if(subencoding_mask & 0x8) { /* Any Subrects */
2270 VNC_BYTES_NEEDED(3); /* 1 byte for number of subrects field, +2 at least for 1 subrect */
2271 ti = proto_tree_add_item(tile_tree,
2272 hf_vnc_hextile_num_subrects,
2273 tvb, *offset, 1,
2274 ENC_BIG_ENDIAN);
2275 num_subrects = tvb_get_guint8(tvb, *offset);
2276 *offset += 1;
2278 if(subencoding_mask & 0x10)
2279 subrect_len = bytes_per_pixel + 2;
2280 else
2281 subrect_len = 2;
2282 VNC_BYTES_NEEDED((guint)(subrect_len * num_subrects));
2284 num_subrects_tree =
2285 proto_item_add_subtree(ti, ett_vnc_hextile_num_subrects);
2287 for(i = 0; i < num_subrects; i++) {
2288 ti = proto_tree_add_text(num_subrects_tree, tvb,
2289 *offset, subrect_len,
2290 "Subrectangle #%d", i+1);
2291 subrect_tree =
2292 proto_item_add_subtree(ti, ett_vnc_hextile_subrect);
2294 if(subencoding_mask & 0x10) {
2295 /* Subrects Colored */
2296 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_pixel_value, tvb, *offset, bytes_per_pixel, ENC_NA);
2298 *offset += bytes_per_pixel;
2301 proto_tree_add_item(subrect_tree,
2302 hf_vnc_hextile_subrect_x_pos, tvb, *offset, 1, ENC_BIG_ENDIAN);
2304 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_y_pos, tvb, *offset, 1, ENC_BIG_ENDIAN);
2306 *offset += 1;
2308 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_width, tvb, *offset, 1, ENC_BIG_ENDIAN);
2310 proto_tree_add_item(subrect_tree, hf_vnc_hextile_subrect_height, tvb, *offset, 1, ENC_BIG_ENDIAN);
2312 *offset += 1;
2318 return 0; /* bytes_needed */
2321 static guint
2322 vnc_supported_messages(tvbuff_t *tvb, gint *offset, proto_tree *tree,
2323 const guint16 width)
2325 VNC_BYTES_NEEDED(width);
2326 if (width >= 64) {
2327 proto_tree_add_item(tree,
2328 hf_vnc_supported_messages_client2server,
2329 tvb, *offset, 32, ENC_NA);
2330 *offset += 32;
2331 proto_tree_add_item(tree,
2332 hf_vnc_supported_messages_server2client,
2333 tvb, *offset, 32, ENC_NA);
2334 *offset += 32;
2335 *offset += width - 64;
2336 } else {
2337 *offset += width;
2340 return 0; /* bytes_needed */
2343 static guint
2344 vnc_supported_encodings(tvbuff_t *tvb, gint *offset, proto_tree *tree,
2345 const guint16 width, const guint16 height)
2347 guint16 i = width;
2349 proto_tree_add_text(tree, tvb, *offset, 0,
2350 "Number of supported encodings: %d", height);
2352 VNC_BYTES_NEEDED(width);
2353 for (; i >= 4; i -= 4) {
2354 proto_tree_add_item(tree, hf_vnc_supported_encodings,
2355 tvb, *offset, 4, ENC_BIG_ENDIAN);
2356 *offset += 4;
2358 *offset += i;
2360 return 0; /* bytes_needed */
2363 static guint
2364 vnc_server_identity(tvbuff_t *tvb, gint *offset, proto_tree *tree,
2365 const guint16 width)
2367 VNC_BYTES_NEEDED(width);
2368 proto_tree_add_item(tree, hf_vnc_server_identity,
2369 tvb, *offset, width, ENC_ASCII|ENC_NA);
2370 *offset += width;
2372 return 0; /* bytes_needed */
2375 static guint
2376 vnc_mirrorlink(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2377 proto_tree *tree)
2379 guint8 type;
2380 guint16 length;
2381 guint16 num, i;
2382 gint end;
2383 proto_item *ti;
2384 proto_tree *sub_tree;
2386 /* Header */
2387 VNC_BYTES_NEEDED(3);
2389 type = tvb_get_guint8(tvb, *offset);
2390 proto_tree_add_item(tree, hf_vnc_mirrorlink_type,
2391 tvb, *offset, 1, ENC_BIG_ENDIAN);
2392 *offset += 1;
2394 length = tvb_get_ntohs(tvb, *offset);
2395 proto_tree_add_item(tree, hf_vnc_mirrorlink_length,
2396 tvb, *offset, 2, ENC_BIG_ENDIAN);
2397 *offset += 2;
2399 col_add_fstr(pinfo->cinfo, COL_INFO, "MirrorLink (%s)",
2400 val_to_str_const(type, vnc_mirrorlink_types_vs,
2401 "Unknown"));
2403 /* Payload */
2404 end = *offset + length;
2406 switch(type) {
2408 case VNC_ML_EXT_BYE_BYE :
2409 break;
2411 case VNC_ML_EXT_SERVER_DISPLAY_CONFIGURATION :
2412 VNC_BYTES_NEEDED(12);
2413 proto_tree_add_item(tree, hf_vnc_mirrorlink_version_major,
2414 tvb, *offset, 1, ENC_BIG_ENDIAN);
2415 *offset += 1;
2416 proto_tree_add_item(tree, hf_vnc_mirrorlink_version_minor,
2417 tvb, *offset, 1, ENC_BIG_ENDIAN);
2418 *offset += 1;
2419 proto_tree_add_item(tree,
2420 hf_vnc_mirrorlink_framebuffer_configuration,
2421 tvb, *offset, 2, ENC_BIG_ENDIAN);
2422 *offset += 2;
2423 proto_tree_add_item(tree, hf_vnc_mirrorlink_pixel_width,
2424 tvb, *offset, 2, ENC_BIG_ENDIAN);
2425 *offset += 2;
2426 proto_tree_add_item(tree, hf_vnc_mirrorlink_pixel_height,
2427 tvb, *offset, 2, ENC_BIG_ENDIAN);
2428 *offset += 2;
2429 proto_tree_add_item(tree, hf_vnc_mirrorlink_pixel_format,
2430 tvb, *offset, 4, ENC_BIG_ENDIAN);
2431 *offset += 4;
2432 break;
2434 case VNC_ML_EXT_CLIENT_DISPLAY_CONFIGURATION :
2435 VNC_BYTES_NEEDED(14);
2436 proto_tree_add_item(tree, hf_vnc_mirrorlink_version_major,
2437 tvb, *offset, 1, ENC_BIG_ENDIAN);
2438 *offset += 1;
2439 proto_tree_add_item(tree, hf_vnc_mirrorlink_version_minor,
2440 tvb, *offset, 1, ENC_BIG_ENDIAN);
2441 *offset += 1;
2442 proto_tree_add_item(tree,
2443 hf_vnc_mirrorlink_framebuffer_configuration,
2444 tvb, *offset, 2, ENC_BIG_ENDIAN);
2445 *offset += 2;
2446 proto_tree_add_item(tree, hf_vnc_mirrorlink_pixel_width,
2447 tvb, *offset, 2, ENC_BIG_ENDIAN);
2448 *offset += 2;
2449 proto_tree_add_item(tree, hf_vnc_mirrorlink_pixel_height,
2450 tvb, *offset, 2, ENC_BIG_ENDIAN);
2451 *offset += 2;
2452 proto_tree_add_item(tree, hf_vnc_mirrorlink_display_width,
2453 tvb, *offset, 2, ENC_BIG_ENDIAN);
2454 *offset += 2;
2455 proto_tree_add_item(tree, hf_vnc_mirrorlink_display_height,
2456 tvb, *offset, 2, ENC_BIG_ENDIAN);
2457 *offset += 2;
2458 proto_tree_add_item(tree, hf_vnc_mirrorlink_display_distance,
2459 tvb, *offset, 2, ENC_BIG_ENDIAN);
2460 *offset += 2;
2461 break;
2463 case VNC_ML_EXT_SERVER_EVENT_CONFIGURATION :
2464 case VNC_ML_EXT_CLIENT_EVENT_CONFIGURATION :
2465 VNC_BYTES_NEEDED(28);
2466 proto_tree_add_item(tree, hf_vnc_mirrorlink_keyboard_language,
2467 tvb, *offset, 2, ENC_ASCII|ENC_NA);
2468 *offset += 2;
2469 proto_tree_add_item(tree, hf_vnc_mirrorlink_keyboard_country,
2470 tvb, *offset, 2, ENC_ASCII|ENC_NA);
2471 *offset += 2;
2472 proto_tree_add_item(tree, hf_vnc_mirrorlink_ui_language,
2473 tvb, *offset, 2, ENC_ASCII|ENC_NA);
2474 *offset += 2;
2475 proto_tree_add_item(tree, hf_vnc_mirrorlink_ui_country,
2476 tvb, *offset, 2, ENC_ASCII|ENC_NA);
2477 *offset += 2;
2478 proto_tree_add_item(tree, hf_vnc_mirrorlink_knob_keys,
2479 tvb, *offset, 4, ENC_BIG_ENDIAN);
2480 *offset += 4;
2481 proto_tree_add_item(tree, hf_vnc_mirrorlink_device_keys,
2482 tvb, *offset, 4, ENC_BIG_ENDIAN);
2483 *offset += 4;
2484 proto_tree_add_item(tree, hf_vnc_mirrorlink_multimedia_keys,
2485 tvb, *offset, 4, ENC_BIG_ENDIAN);
2486 *offset += 4;
2487 proto_tree_add_item(tree, hf_vnc_mirrorlink_key_related,
2488 tvb, *offset, 4, ENC_BIG_ENDIAN);
2489 *offset += 4;
2490 proto_tree_add_item(tree, hf_vnc_mirrorlink_pointer_related,
2491 tvb, *offset, 4, ENC_BIG_ENDIAN);
2492 *offset += 4;
2493 break;
2495 case VNC_ML_EXT_EVENT_MAPPING :
2496 case VNC_ML_EXT_EVENT_MAPPING_REQUEST :
2497 VNC_BYTES_NEEDED(8);
2498 proto_tree_add_item(tree,
2499 hf_vnc_mirrorlink_key_symbol_value_client,
2500 tvb, *offset, 4, ENC_BIG_ENDIAN);
2501 *offset += 4;
2502 proto_tree_add_item(tree,
2503 hf_vnc_mirrorlink_key_symbol_value_server,
2504 tvb, *offset, 4, ENC_BIG_ENDIAN);
2505 *offset += 4;
2506 break;
2508 case VNC_ML_EXT_KEY_EVENT_LISTING :
2509 VNC_BYTES_NEEDED(4);
2510 proto_tree_add_item(tree, hf_vnc_mirrorlink_key_configuration,
2511 tvb, *offset, 1, ENC_BIG_ENDIAN);
2512 *offset += 1;
2513 num = tvb_get_guint8(tvb, *offset);
2514 proto_tree_add_item(tree, hf_vnc_mirrorlink_key_num_events,
2515 tvb, *offset, 1, ENC_BIG_ENDIAN);
2516 *offset += 1;
2517 proto_tree_add_item(tree, hf_vnc_mirrorlink_key_event_counter,
2518 tvb, *offset, 2, ENC_BIG_ENDIAN);
2519 *offset += 2;
2520 VNC_BYTES_NEEDED((guint)(4 * num));
2521 ti = proto_tree_add_text(tree, tvb, *offset, 4 * num,
2522 "Key Event List");
2523 sub_tree = proto_item_add_subtree(ti, ett_vnc_key_events);
2524 for (; num > 0; num--) {
2525 proto_tree_add_item(sub_tree,
2526 hf_vnc_mirrorlink_key_symbol_value,
2527 tvb, *offset, 4, ENC_BIG_ENDIAN);
2528 *offset += 4 ;
2530 break;
2532 case VNC_ML_EXT_KEY_EVENT_LISTING_REQUEST :
2533 VNC_BYTES_NEEDED(4);
2534 proto_tree_add_item(tree,
2535 hf_vnc_mirrorlink_key_request_configuration,
2536 tvb, *offset, 4, ENC_BIG_ENDIAN);
2537 *offset += 4;
2538 break;
2540 case VNC_ML_EXT_VIRTUAL_KEYBOARD :
2541 VNC_BYTES_NEEDED(16);
2542 proto_tree_add_item(tree,
2543 hf_vnc_mirrorlink_keyboard_configuration,
2544 tvb, *offset, 4, ENC_BIG_ENDIAN);
2545 *offset += 4;
2546 proto_tree_add_item(tree, hf_vnc_mirrorlink_cursor_x,
2547 tvb, *offset, 2, ENC_BIG_ENDIAN);
2548 *offset += 2;
2549 proto_tree_add_item(tree, hf_vnc_mirrorlink_cursor_y,
2550 tvb, *offset, 2, ENC_BIG_ENDIAN);
2551 *offset += 2;
2552 proto_tree_add_item(tree, hf_vnc_mirrorlink_text_x,
2553 tvb, *offset, 2, ENC_BIG_ENDIAN);
2554 *offset += 2;
2555 proto_tree_add_item(tree, hf_vnc_mirrorlink_text_y,
2556 tvb, *offset, 2, ENC_BIG_ENDIAN);
2557 *offset += 2;
2558 proto_tree_add_item(tree, hf_vnc_mirrorlink_text_width,
2559 tvb, *offset, 2, ENC_BIG_ENDIAN);
2560 *offset += 2;
2561 proto_tree_add_item(tree, hf_vnc_mirrorlink_text_height,
2562 tvb, *offset, 2, ENC_BIG_ENDIAN);
2563 *offset += 2;
2564 break;
2566 case VNC_ML_EXT_VIRTUAL_KEYBOARD_REQUEST :
2567 VNC_BYTES_NEEDED(4);
2568 proto_tree_add_item(tree,
2569 hf_vnc_mirrorlink_keyboard_request_configuration,
2570 tvb, *offset, 4, ENC_BIG_ENDIAN);
2571 *offset += 4;
2572 break;
2574 case VNC_ML_EXT_DEVICE_STATUS :
2575 case VNC_ML_EXT_DEVICE_STATUS_REQUEST :
2576 VNC_BYTES_NEEDED(4);
2577 proto_tree_add_item(tree, hf_vnc_mirrorlink_device_status,
2578 tvb, *offset, 4, ENC_BIG_ENDIAN);
2579 *offset += 4;
2580 break;
2582 case VNC_ML_EXT_CONTENT_ATTESTATION :
2583 break;
2585 case VNC_ML_EXT_CONTENT_ATTESTATION_REQUEST :
2586 break;
2588 case VNC_ML_EXT_FB_BLOCKING_NOTIFICATION :
2589 VNC_BYTES_NEEDED(14);
2590 proto_tree_add_item(tree, hf_vnc_mirrorlink_fb_block_x,
2591 tvb, *offset, 2, ENC_BIG_ENDIAN);
2592 *offset += 2;
2593 proto_tree_add_item(tree, hf_vnc_mirrorlink_fb_block_y,
2594 tvb, *offset, 2, ENC_BIG_ENDIAN);
2595 *offset += 2;
2596 proto_tree_add_item(tree, hf_vnc_mirrorlink_fb_block_width,
2597 tvb, *offset, 2, ENC_BIG_ENDIAN);
2598 *offset += 2;
2599 proto_tree_add_item(tree, hf_vnc_mirrorlink_fb_block_height,
2600 tvb, *offset, 2, ENC_BIG_ENDIAN);
2601 *offset += 2;
2602 proto_tree_add_item(tree, hf_vnc_mirrorlink_app_id,
2603 tvb, *offset, 4, ENC_BIG_ENDIAN);
2604 *offset += 4;
2605 proto_tree_add_item(tree, hf_vnc_mirrorlink_fb_block_reason,
2606 tvb, *offset, 2, ENC_BIG_ENDIAN);
2607 *offset += 2;
2608 break;
2610 case VNC_ML_EXT_AUDIO_BLOCKING_NOTIFICATION :
2611 VNC_BYTES_NEEDED(6);
2612 proto_tree_add_item(tree, hf_vnc_mirrorlink_app_id,
2613 tvb, *offset, 4, ENC_BIG_ENDIAN);
2614 *offset += 4;
2615 proto_tree_add_item(tree, hf_vnc_mirrorlink_audio_block_reason,
2616 tvb, *offset, 2, ENC_BIG_ENDIAN);
2617 *offset += 2;
2618 break;
2620 case VNC_ML_EXT_TOUCH_EVENT :
2621 VNC_BYTES_NEEDED(1);
2622 num = tvb_get_guint8(tvb, *offset);
2623 proto_tree_add_item(tree, hf_vnc_mirrorlink_touch_num_events,
2624 tvb, *offset, 1, ENC_BIG_ENDIAN);
2625 *offset += 1;
2626 VNC_BYTES_NEEDED((guint)(6 * num));
2627 /*sub_tree = proto_item_add_subtree(tree, ett_vnc_touch_events);*/
2628 for (i = 0; i < num; i++) {
2629 ti = proto_tree_add_text(tree, tvb, *offset, 6,
2630 "Touch Event #%d", i + 1);
2631 sub_tree = proto_item_add_subtree(ti,
2632 ett_vnc_touch_events);
2634 proto_tree_add_item(sub_tree, hf_vnc_mirrorlink_touch_x,
2635 tvb, *offset, 2, ENC_BIG_ENDIAN);
2636 *offset += 2;
2637 proto_tree_add_item(sub_tree, hf_vnc_mirrorlink_touch_y,
2638 tvb, *offset, 2, ENC_BIG_ENDIAN);
2639 *offset += 2;
2640 proto_tree_add_item(sub_tree,
2641 hf_vnc_mirrorlink_touch_id,
2642 tvb, *offset, 1, ENC_BIG_ENDIAN);
2643 *offset += 1;
2644 proto_tree_add_item(sub_tree,
2645 hf_vnc_mirrorlink_touch_pressure,
2646 tvb, *offset, 1, ENC_BIG_ENDIAN);
2647 *offset += 1;
2649 break;
2651 case VNC_ML_EXT_FB_ALTERNATIVE_TEXT :
2652 VNC_BYTES_NEEDED(6);
2653 proto_tree_add_item(tree, hf_vnc_mirrorlink_app_id,
2654 tvb, *offset, 4, ENC_BIG_ENDIAN);
2655 *offset += 4;
2656 num = tvb_get_ntohs(tvb, *offset);
2657 proto_tree_add_item(tree, hf_vnc_mirrorlink_text_length,
2658 tvb, *offset, 2, ENC_BIG_ENDIAN);
2659 *offset += 2;
2660 VNC_BYTES_NEEDED(num);
2661 proto_tree_add_item(tree, hf_vnc_mirrorlink_text,
2662 tvb, *offset, num, ENC_ASCII|ENC_NA);
2663 *offset += num;
2664 break;
2666 case VNC_ML_EXT_FB_ALTERNATIVE_TEXT_REQUEST :
2667 VNC_BYTES_NEEDED(2);
2668 proto_tree_add_item(tree, hf_vnc_mirrorlink_text_max_length,
2669 tvb, *offset, 2, ENC_BIG_ENDIAN);
2670 *offset += 2;
2671 break;
2675 if (end > *offset) {
2676 length = end - *offset;
2677 VNC_BYTES_NEEDED(length);
2678 proto_tree_add_item(tree, hf_vnc_mirrorlink_unknown,
2679 tvb, *offset, length, ENC_NA);
2680 *offset = end;
2683 return 0; /* bytes_needed */
2686 static guint
2687 vnc_context_information(tvbuff_t *tvb, gint *offset, proto_tree *tree)
2689 VNC_BYTES_NEEDED(20);
2691 proto_tree_add_item(tree, hf_vnc_context_information_app_id,
2692 tvb, *offset, 4, ENC_BIG_ENDIAN);
2693 *offset += 4;
2695 proto_tree_add_item(tree, hf_vnc_context_information_app_trust_level,
2696 tvb, *offset, 2, ENC_BIG_ENDIAN);
2697 *offset += 2;
2699 proto_tree_add_item(tree,
2700 hf_vnc_context_information_content_trust_level,
2701 tvb, *offset, 2, ENC_BIG_ENDIAN);
2702 *offset += 2;
2704 proto_tree_add_item(tree, hf_vnc_context_information_app_category,
2705 tvb, *offset, 4, ENC_BIG_ENDIAN);
2706 *offset += 4;
2708 proto_tree_add_item(tree, hf_vnc_context_information_content_category,
2709 tvb, *offset, 4, ENC_BIG_ENDIAN);
2710 *offset += 4;
2712 proto_tree_add_item(tree, hf_vnc_context_information_content_rules,
2713 tvb, *offset, 4, ENC_BIG_ENDIAN);
2714 *offset += 4;
2716 return 0; /* bytes_needed */
2719 static guint
2720 vnc_slrle_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2721 proto_tree *tree, const guint16 height)
2723 guint8 depth = vnc_get_depth(pinfo);
2724 guint8 depth_mod = depth % 8;
2725 guint8 bytes_per_run;
2726 guint16 num_runs, i;
2727 guint length;
2728 proto_item *ti;
2729 proto_tree *sub_tree;
2731 if (depth_mod <= 4)
2732 bytes_per_run = ( 8 - depth_mod + depth) / 8;
2733 else
2734 bytes_per_run = (16 - depth_mod + depth) / 8;
2736 for (i = 0; i < height; i++) {
2737 VNC_BYTES_NEEDED(2);
2738 num_runs = tvb_get_ntohs(tvb, *offset);
2740 length = num_runs * bytes_per_run;
2742 ti = proto_tree_add_text(tree, tvb, *offset, 2 + length,
2743 "Scanline #%d", i+1);
2744 sub_tree = proto_item_add_subtree(ti, ett_vnc_slrle_subline);
2746 proto_tree_add_item(sub_tree, hf_vnc_slrle_run_num,
2747 tvb, *offset, 2, ENC_BIG_ENDIAN);
2748 *offset += 2;
2750 VNC_BYTES_NEEDED(length);
2751 proto_tree_add_item(sub_tree, hf_vnc_slrle_run_data,
2752 tvb, *offset, length, ENC_NA);
2753 *offset += length;
2756 return 0; /* bytes_needed */
2759 static guint
2760 vnc_h264_encoding(tvbuff_t *tvb, gint *offset, proto_tree *tree)
2762 guint32 nbytes;
2764 VNC_BYTES_NEEDED(16);
2766 /*0 == P-Frame; 1 == B-Frame; 2 == I-Frame*/
2767 proto_tree_add_item(tree, hf_vnc_h264_slice_type,
2768 tvb, *offset, 4, ENC_BIG_ENDIAN);
2769 *offset += 4;
2771 nbytes = tvb_get_ntohl(tvb, *offset);
2772 proto_tree_add_item(tree, hf_vnc_h264_nbytes,
2773 tvb, *offset, 4, ENC_BIG_ENDIAN);
2774 *offset += 4;
2776 proto_tree_add_item(tree, hf_vnc_h264_width,
2777 tvb, *offset, 4, ENC_BIG_ENDIAN);
2778 *offset += 4;
2780 proto_tree_add_item(tree, hf_vnc_h264_height,
2781 tvb, *offset, 4, ENC_BIG_ENDIAN);
2782 *offset += 4;
2784 VNC_BYTES_NEEDED(nbytes);
2785 proto_tree_add_item(tree, hf_vnc_h264_data,
2786 tvb, *offset, nbytes, ENC_NA);
2787 *offset += nbytes;
2789 return 0; /* bytes_needed */
2792 #ifdef HAVE_LIBZ
2793 static guint
2794 vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2795 proto_tree *tree, const guint16 width, const guint16 height)
2796 #else
2797 static guint
2798 vnc_zrle_encoding(tvbuff_t *tvb, packet_info *pinfo _U_, gint *offset,
2799 proto_tree *tree, const guint16 width _U_, const guint16 height _U_)
2800 #endif
2802 guint32 data_len;
2803 #ifdef HAVE_LIBZ
2804 guint8 palette_size;
2805 guint8 bytes_per_cpixel = vnc_get_bytes_per_pixel(pinfo);
2806 gint uncomp_offset = 0;
2807 guint length;
2808 gint subencoding_type;
2809 tvbuff_t *uncomp_tvb = NULL;
2810 proto_tree *zrle_subencoding_tree;
2811 proto_item *ti;
2812 #endif
2814 VNC_BYTES_NEEDED(4);
2815 proto_tree_add_item(tree, hf_vnc_zrle_len, tvb, *offset,
2816 4, ENC_BIG_ENDIAN);
2817 data_len = tvb_get_ntohl(tvb, *offset);
2819 *offset += 4;
2821 VNC_BYTES_NEEDED(data_len);
2823 proto_tree_add_item(tree, hf_vnc_zrle_data, tvb, *offset,
2824 data_len, ENC_NA);
2826 #ifdef HAVE_LIBZ
2827 uncomp_tvb = tvb_child_uncompress(tvb, tvb, *offset, data_len);
2829 if(uncomp_tvb != NULL) {
2830 add_new_data_source(pinfo, uncomp_tvb,
2831 "Uncompressed ZRLE data");
2833 ti = proto_tree_add_item(tree, hf_vnc_zrle_subencoding,
2834 uncomp_tvb, uncomp_offset, 1, ENC_BIG_ENDIAN);
2835 zrle_subencoding_tree =
2836 proto_item_add_subtree(ti, ett_vnc_zrle_subencoding);
2838 proto_tree_add_item(zrle_subencoding_tree, hf_vnc_zrle_rle,
2839 uncomp_tvb, uncomp_offset, 1, ENC_BIG_ENDIAN);
2841 proto_tree_add_item(zrle_subencoding_tree,
2842 hf_vnc_zrle_palette_size, uncomp_tvb,
2843 uncomp_offset, 1, ENC_BIG_ENDIAN);
2845 subencoding_type = tvb_get_guint8(uncomp_tvb, uncomp_offset);
2846 palette_size = subencoding_type & 0x7F;
2848 uncomp_offset += 1;
2850 if(subencoding_type == 0) { /* Raw */
2851 length = width * height * bytes_per_cpixel;
2852 VNC_BYTES_NEEDED(length);
2854 /* XXX - not working yet! */
2856 proto_tree_add_item(zrle_subencoding_tree,
2857 hf_vnc_zrle_raw, uncomp_tvb,
2858 uncomp_offset, length, ENC_NA);
2860 } else if(subencoding_type >= 130 && subencoding_type <= 255) {
2861 length = palette_size * bytes_per_cpixel;
2862 VNC_BYTES_NEEDED(length);
2864 proto_tree_add_item(zrle_subencoding_tree,
2865 hf_vnc_zrle_palette, uncomp_tvb,
2866 uncomp_offset, length, ENC_NA);
2868 /* XXX - Not complete! */
2871 } else {
2872 proto_tree_add_text(tree, tvb, *offset, data_len,
2873 "Decompression of ZRLE data failed");
2875 #endif /* HAVE_LIBZ */
2877 *offset += data_len;
2879 return 0; /* bytes_needed */
2883 static guint
2884 read_compact_len(tvbuff_t *tvb, gint *offset, gint *length, gint *value_length)
2886 gint b;
2888 VNC_BYTES_NEEDED(1);
2890 *value_length = 0;
2892 b = tvb_get_guint8(tvb, *offset);
2893 *offset += 1;
2894 *value_length += 1;
2896 *length = b & 0x7f;
2897 if ((b & 0x80) != 0) {
2898 VNC_BYTES_NEEDED(1);
2900 b = tvb_get_guint8(tvb, *offset);
2901 *offset += 1;
2902 *value_length += 1;
2904 *length |= (b & 0x7f) << 7;
2906 if ((b & 0x80) != 0) {
2907 VNC_BYTES_NEEDED (1);
2909 b = tvb_get_guint8(tvb, *offset);
2910 *offset += 1;
2911 *value_length += 1;
2913 *length |= (b & 0xff) << 14;
2917 return 0;
2921 static guint
2922 process_compact_length_and_image_data(tvbuff_t *tvb, gint *offset, proto_tree *tree)
2924 guint bytes_needed;
2925 guint length, value_length;
2927 bytes_needed = read_compact_len (tvb, offset, &length, &value_length);
2928 if (bytes_needed != 0)
2929 return bytes_needed;
2931 proto_tree_add_uint(tree, hf_vnc_tight_image_len, tvb, *offset - value_length, value_length, length);
2933 VNC_BYTES_NEEDED(length);
2934 proto_tree_add_item(tree, hf_vnc_tight_image_data, tvb, *offset, length, ENC_NA);
2935 *offset += length;
2937 return 0; /* bytes_needed */
2941 static guint
2942 process_tight_rect_filter_palette(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2943 proto_tree *tree, gint *bits_per_pixel)
2945 vnc_packet_t *per_packet_info;
2946 gint num_colors;
2947 guint palette_bytes;
2949 /* See TightVNC's vnc_unixsrc/vncviewer/tight.c:InitFilterPaletteBPP() */
2951 per_packet_info = (vnc_packet_t *)p_get_proto_data(pinfo->fd, proto_vnc, 0);
2952 /* Our calling function should have set the packet's proto data already */
2953 DISSECTOR_ASSERT(per_packet_info != NULL);
2955 VNC_BYTES_NEEDED(1);
2956 proto_tree_add_item(tree, hf_vnc_tight_palette_num_colors, tvb, *offset, 1, ENC_BIG_ENDIAN);
2957 num_colors = tvb_get_guint8(tvb, *offset);
2958 *offset += 1;
2960 num_colors++;
2961 if (num_colors < 2)
2962 return 0;
2964 if (per_packet_info->depth == 24)
2965 palette_bytes = num_colors * 3;
2966 else
2967 palette_bytes = num_colors * per_packet_info->depth / 8;
2969 VNC_BYTES_NEEDED(palette_bytes);
2970 proto_tree_add_item(tree, hf_vnc_tight_palette_data, tvb, *offset, palette_bytes, ENC_NA);
2971 *offset += palette_bytes;
2973 /* This is the number of bits per pixel *in the image data*, not the actual client depth */
2974 if (num_colors == 2)
2975 *bits_per_pixel = 1;
2976 else
2977 *bits_per_pixel = 8;
2979 return 0;
2982 static guint
2983 vnc_tight_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
2984 proto_tree *tree, const guint16 width _U_, const guint16 height _U_)
2986 vnc_packet_t *per_packet_info;
2987 guint8 comp_ctl;
2988 proto_item *compression_type_ti;
2989 gint bit_offset;
2990 gint bytes_needed = -1;
2992 per_packet_info = (vnc_packet_t *)p_get_proto_data(pinfo->fd, proto_vnc, 0);
2993 /* Our calling function should have set the packet's proto data already */
2994 DISSECTOR_ASSERT(per_packet_info != NULL);
2996 /* See xserver/hw/vnc/rfbproto.h and grep for "Tight Encoding." for the following layout */
2998 VNC_BYTES_NEEDED(1);
3000 /* least significant bits 0-3 are "reset compression stream N" */
3001 bit_offset = *offset * 8;
3002 proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream0, tvb, bit_offset + 7, 1, ENC_BIG_ENDIAN);
3003 proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream1, tvb, bit_offset + 6, 1, ENC_BIG_ENDIAN);
3004 proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream2, tvb, bit_offset + 5, 1, ENC_BIG_ENDIAN);
3005 proto_tree_add_bits_item(tree, hf_vnc_tight_reset_stream3, tvb, bit_offset + 4, 1, ENC_BIG_ENDIAN);
3007 /* most significant bits 4-7 are "compression type" */
3008 compression_type_ti = proto_tree_add_bits_item(tree, hf_vnc_tight_rect_type, tvb, bit_offset + 0, 4, ENC_BIG_ENDIAN);
3010 comp_ctl = tvb_get_guint8(tvb, *offset);
3011 *offset += 1;
3013 comp_ctl >>= 4; /* skip over the "reset compression" bits from above */
3015 /* compression format */
3017 if (comp_ctl == TIGHT_RECT_FILL) {
3018 /* "fill" encoding (solid rectangle) */
3020 proto_item_append_text(compression_type_ti, " (fill encoding - solid rectangle)");
3022 if (per_packet_info->depth == 24) {
3023 VNC_BYTES_NEEDED(3);
3024 proto_tree_add_item(tree, hf_vnc_tight_fill_color, tvb, *offset, 3, ENC_NA);
3025 *offset += 3;
3026 } else {
3027 VNC_BYTES_NEEDED(per_packet_info->bytes_per_pixel);
3028 proto_tree_add_item(tree, hf_vnc_tight_fill_color, tvb, *offset, per_packet_info->bytes_per_pixel, ENC_NA);
3029 *offset += per_packet_info->bytes_per_pixel;
3032 bytes_needed = 0;
3033 } else if (comp_ctl == TIGHT_RECT_JPEG) {
3034 /* jpeg encoding */
3036 proto_item_append_text(compression_type_ti, " (JPEG encoding)");
3037 bytes_needed = process_compact_length_and_image_data(tvb, offset, tree);
3038 if (bytes_needed != 0)
3039 return bytes_needed;
3040 } else if (comp_ctl > TIGHT_RECT_MAX_VALUE) {
3041 /* invalid encoding */
3043 expert_add_info(pinfo, compression_type_ti, &ei_vnc_invalid_encoding);
3044 } else {
3045 guint row_size;
3046 gint bits_per_pixel;
3048 /* basic encoding */
3050 proto_item_append_text(compression_type_ti, " (basic encoding)");
3052 proto_tree_add_bits_item(tree, hf_vnc_tight_filter_flag, tvb, bit_offset + 1, 1, ENC_BIG_ENDIAN);
3054 bits_per_pixel = per_packet_info->depth;
3056 if ((comp_ctl & TIGHT_RECT_EXPLICIT_FILTER_FLAG) != 0) {
3057 guint8 filter_id;
3059 /* explicit filter */
3061 VNC_BYTES_NEEDED(1);
3062 proto_tree_add_item(tree, hf_vnc_tight_filter_id, tvb, *offset, 1, ENC_BIG_ENDIAN);
3063 filter_id = tvb_get_guint8(tvb, *offset);
3064 *offset += 1;
3066 switch (filter_id) {
3067 case TIGHT_RECT_FILTER_COPY:
3068 /* nothing to do */
3069 break;
3071 case TIGHT_RECT_FILTER_PALETTE:
3072 bytes_needed = process_tight_rect_filter_palette(tvb, pinfo, offset, tree, &bits_per_pixel);
3073 if (bytes_needed != 0)
3074 return bytes_needed;
3076 break;
3078 case TIGHT_RECT_FILTER_GRADIENT:
3079 /* nothing to do */
3080 break;
3082 } else {
3083 /* this is the same case as TIGHT_RECT_FILTER_COPY, so there's nothing special to do */
3086 row_size = ((guint) width * bits_per_pixel + 7) / 8;
3087 if (row_size * height < TIGHT_MIN_BYTES_TO_COMPRESS) {
3088 guint num_bytes;
3090 /* The data is not compressed; just skip over it */
3092 num_bytes = row_size * height;
3093 VNC_BYTES_NEEDED(num_bytes);
3094 proto_tree_add_item(tree, hf_vnc_tight_image_data, tvb, *offset, num_bytes, ENC_NA);
3095 *offset += num_bytes;
3097 bytes_needed = 0;
3098 } else {
3099 /* The data is compressed; read its length and data */
3100 bytes_needed = process_compact_length_and_image_data(tvb, offset, tree);
3101 if (bytes_needed != 0)
3102 return bytes_needed;
3106 DISSECTOR_ASSERT(bytes_needed != -1);
3108 return bytes_needed;
3112 static guint
3113 decode_cursor(tvbuff_t *tvb, gint *offset, proto_tree *tree,
3114 guint pixels_bytes, guint mask_bytes)
3116 guint total_bytes;
3118 total_bytes = pixels_bytes + mask_bytes;
3119 VNC_BYTES_NEEDED (total_bytes);
3121 proto_tree_add_item(tree, hf_vnc_cursor_encoding_pixels, tvb, *offset,
3122 pixels_bytes, ENC_NA);
3123 *offset += pixels_bytes;
3125 proto_tree_add_item(tree, hf_vnc_cursor_encoding_bitmask, tvb, *offset,
3126 mask_bytes, ENC_NA);
3127 *offset += mask_bytes;
3129 return 0; /* bytes_needed */
3133 static guint
3134 vnc_rich_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
3135 proto_tree *tree, const guint16 width, const guint16 height)
3137 guint8 bytes_per_pixel = vnc_get_bytes_per_pixel(pinfo);
3138 guint pixels_bytes, mask_bytes;
3140 pixels_bytes = width * height * bytes_per_pixel;
3141 mask_bytes = ((width + 7) / 8) * height;
3143 return decode_cursor(tvb, offset, tree,
3144 pixels_bytes, mask_bytes);
3148 static guint
3149 vnc_x_cursor_encoding(tvbuff_t *tvb, packet_info *pinfo _U_, gint *offset,
3150 proto_tree *tree, const guint16 width, const guint16 height)
3152 gint bitmap_row_bytes = (width + 7) / 8;
3153 gint mask_bytes = bitmap_row_bytes * height;
3155 VNC_BYTES_NEEDED (6);
3156 proto_tree_add_item(tree, hf_vnc_cursor_x_fore_back, tvb, *offset, 6, ENC_NA);
3157 *offset += 6;
3159 /* The length of the pixel data is the same as the length of the mask data (X cursors are strictly black/white) */
3160 return decode_cursor(tvb, offset, tree,
3161 mask_bytes, mask_bytes);
3165 static guint
3166 vnc_server_set_colormap_entries(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
3167 proto_tree *tree)
3169 guint16 number_of_colors;
3170 guint counter, bytes_needed;
3171 proto_item *ti;
3172 proto_tree *vnc_colormap_num_groups, *vnc_colormap_color_group;
3174 col_set_str(pinfo->cinfo, COL_INFO, "Server set colormap entries");
3176 number_of_colors = tvb_get_ntohs(tvb, 4);
3178 VNC_BYTES_NEEDED(3);
3179 proto_tree_add_item(tree, hf_vnc_padding, tvb, *offset, 1, ENC_NA);
3180 *offset += 1; /* Skip over 1 byte of padding */
3182 proto_tree_add_item(tree, hf_vnc_colormap_first_color,
3183 tvb, *offset, 2, ENC_BIG_ENDIAN);
3184 *offset += 2;
3186 /* XXX - this is 3 bytes into the tvb, but number_of_colors is set off
3187 * of 4 bytes in... Bug???
3189 ti = proto_tree_add_item(tree, hf_vnc_colormap_num_colors, tvb,
3190 *offset, 2, ENC_BIG_ENDIAN);
3192 if (number_of_colors > 10000) {
3193 expert_add_info_format(pinfo, ti, &ei_vnc_too_many_colors,"Too many colors (%d), aborting dissection",
3194 number_of_colors);
3195 return(0);
3198 bytes_needed = (number_of_colors * 6) + 5;
3199 VNC_BYTES_NEEDED(bytes_needed);
3201 *offset += 2;
3203 ti = proto_tree_add_item(tree, hf_vnc_color_groups, tvb,
3204 *offset, number_of_colors * 6, ENC_NA);
3205 vnc_colormap_num_groups =
3206 proto_item_add_subtree(ti, ett_vnc_colormap_num_groups);
3208 for(counter = 0; counter < number_of_colors; counter++) {
3209 ti = proto_tree_add_text(vnc_colormap_num_groups, tvb,
3210 *offset, 6,
3211 "Color group #%d", counter+1);
3213 vnc_colormap_color_group =
3214 proto_item_add_subtree(ti,
3215 ett_vnc_colormap_color_group);
3217 proto_tree_add_item(vnc_colormap_color_group,
3218 hf_vnc_colormap_red, tvb,
3219 *offset, 2, ENC_BIG_ENDIAN);
3220 *offset += 2;
3222 proto_tree_add_item(vnc_colormap_color_group,
3223 hf_vnc_colormap_green, tvb,
3224 *offset, 2, ENC_BIG_ENDIAN);
3225 *offset += 2;
3227 proto_tree_add_item(vnc_colormap_color_group,
3228 hf_vnc_colormap_blue, tvb,
3229 *offset, 2, ENC_BIG_ENDIAN);
3230 *offset += 2;
3232 return 0;
3236 static void
3237 vnc_server_ring_bell(tvbuff_t *tvb _U_, packet_info *pinfo, gint *offset _U_,
3238 proto_tree *tree _U_)
3240 col_set_str(pinfo->cinfo, COL_INFO, "Server ring bell on client");
3241 /* This message type has no payload... */
3245 static guint
3246 vnc_server_cut_text(tvbuff_t *tvb, packet_info *pinfo, gint *offset,
3247 proto_tree *tree)
3249 guint32 text_len;
3250 proto_item *pi;
3252 col_set_str(pinfo->cinfo, COL_INFO, "Server cut text");
3254 text_len = tvb_get_ntohl(tvb, *offset);
3255 pi = proto_tree_add_item(tree, hf_vnc_server_cut_text_len, tvb, *offset, 4,
3256 ENC_BIG_ENDIAN);
3257 *offset += 4;
3259 if (text_len > 100000) {
3260 expert_add_info_format(pinfo, pi, &ei_vnc_too_many_cut_text,
3261 "Too much cut text (%d), aborting dissection", text_len);
3262 return(0);
3265 VNC_BYTES_NEEDED(text_len);
3267 proto_tree_add_item(tree, hf_vnc_server_cut_text, tvb, *offset,
3268 text_len, ENC_ASCII|ENC_NA);
3269 *offset += text_len;
3271 return *offset;
3275 static void
3276 vnc_set_bytes_per_pixel(const packet_info *pinfo, const guint8 bytes_per_pixel)
3278 vnc_packet_t *per_packet_info;
3280 per_packet_info = (vnc_packet_t *)p_get_proto_data(pinfo->fd, proto_vnc, 0);
3281 /* Our calling function should have set the packet's proto data already */
3282 DISSECTOR_ASSERT(per_packet_info != NULL);
3284 per_packet_info->bytes_per_pixel = bytes_per_pixel;
3288 static void
3289 vnc_set_depth(const packet_info *pinfo, const guint8 depth)
3291 vnc_packet_t *per_packet_info;
3293 per_packet_info = (vnc_packet_t *)p_get_proto_data(pinfo->fd, proto_vnc, 0);
3294 /* Our calling function should have set the packet's proto data already */
3295 DISSECTOR_ASSERT(per_packet_info != NULL);
3297 per_packet_info->depth = depth;
3301 static guint8
3302 vnc_get_bytes_per_pixel(const packet_info *pinfo)
3304 vnc_packet_t *per_packet_info;
3306 per_packet_info = (vnc_packet_t *)p_get_proto_data(pinfo->fd, proto_vnc, 0);
3307 /* Our calling function should have set the packet's proto data already */
3308 DISSECTOR_ASSERT(per_packet_info != NULL);
3310 return per_packet_info->bytes_per_pixel;
3314 static guint8
3315 vnc_get_depth(const packet_info *pinfo)
3317 vnc_packet_t *per_packet_info;
3319 per_packet_info = (vnc_packet_t *)p_get_proto_data(pinfo->fd, proto_vnc, 0);
3320 /* Our calling function should have set the packet's proto data already */
3321 DISSECTOR_ASSERT(per_packet_info != NULL);
3323 return per_packet_info->depth;
3327 /* Register the protocol with Wireshark */
3328 void
3329 proto_register_vnc(void)
3331 module_t *vnc_module; /* To handle our preferences */
3332 expert_module_t* expert_vnc;
3334 /* Setup list of header fields */
3335 static hf_register_info hf[] = {
3336 { &hf_vnc_padding,
3337 { "Padding", "vnc.padding",
3338 FT_NONE, BASE_NONE, NULL, 0x0,
3339 "Unused space", HFILL }
3342 { &hf_vnc_server_proto_ver,
3343 { "Server protocol version", "vnc.server_proto_ver",
3344 FT_STRING, BASE_NONE, NULL, 0x0,
3345 "VNC protocol version on server", HFILL }
3347 { &hf_vnc_client_proto_ver,
3348 { "Client protocol version", "vnc.client_proto_ver",
3349 FT_STRING, BASE_NONE, NULL, 0x0,
3350 "VNC protocol version on client", HFILL }
3352 { &hf_vnc_num_security_types,
3353 { "Number of security types", "vnc.num_security_types",
3354 FT_UINT8, BASE_DEC, NULL, 0x0,
3355 "Number of security (authentication) types supported by the server", HFILL }
3357 { &hf_vnc_security_type,
3358 { "Security type", "vnc.security_type",
3359 FT_UINT8, BASE_DEC, VALS(vnc_security_types_vs), 0x0,
3360 "Security types offered by the server (VNC versions => 3.007", HFILL }
3362 { &hf_vnc_server_security_type,
3363 { "Security type", "vnc.server_security_type",
3364 FT_UINT32, BASE_DEC, VALS(vnc_security_types_vs), 0x0,
3365 "Security type mandated by the server", HFILL }
3367 { &hf_vnc_client_security_type,
3368 { "Security type selected", "vnc.client_security_type",
3369 FT_UINT8, BASE_DEC, VALS(vnc_security_types_vs), 0x0,
3370 "Security type selected by the client", HFILL }
3372 { &hf_vnc_tight_num_tunnel_types,
3373 { "Number of supported tunnel types", "vnc.num_tunnel_types",
3374 FT_UINT32, BASE_DEC, NULL, 0x0,
3375 "Number of tunnel types for TightVNC", HFILL }
3377 { &hf_vnc_tight_tunnel_type,
3378 { "Tunnel type", "vnc.tunnel_type",
3379 FT_UINT8, BASE_DEC, NULL, 0x0,
3380 "Tunnel type specific to TightVNC", HFILL }
3382 { &hf_vnc_tight_num_auth_types,
3383 { "Number of supported authentication types", "vnc.num_auth_types",
3384 FT_UINT32, BASE_DEC, NULL, 0x0,
3385 "Authentication types specific to TightVNC", HFILL }
3387 { &hf_vnc_tight_auth_code,
3388 { "Authentication code", "vnc.tight_auth_code",
3389 FT_UINT32, BASE_DEC, VALS(vnc_security_types_vs), 0x0,
3390 "Authentication code specific to TightVNC", HFILL }
3392 { &hf_vnc_tight_server_message_type,
3393 { "Server message type (TightVNC)", "vnc.tight_server_message_type",
3394 FT_INT32, BASE_DEC, NULL, 0x0,
3395 "Server message type specific to TightVNC", HFILL }
3397 { &hf_vnc_tight_server_vendor,
3398 { "Server vendor code", "vnc.server_vendor",
3399 FT_STRING, BASE_NONE, NULL, 0x0,
3400 "Server vendor code specific to TightVNC", HFILL }
3402 { &hf_vnc_tight_server_name,
3403 { "Server name", "vnc.server_name",
3404 FT_STRING, BASE_NONE, NULL, 0x0,
3405 "Server name specific to TightVNC", HFILL }
3407 { &hf_vnc_tight_client_message_type,
3408 { "Client message type (TightVNC)", "vnc.tight_client_message_type",
3409 FT_INT32, BASE_DEC, NULL, 0x0,
3410 "Client message type specific to TightVNC", HFILL }
3412 { &hf_vnc_tight_client_vendor,
3413 { "Client vendor code", "vnc.client_vendor",
3414 FT_STRING, BASE_NONE, NULL, 0x0,
3415 "Client vendor code specific to TightVNC", HFILL }
3417 { &hf_vnc_tight_client_name,
3418 { "Client name", "vnc.client_name",
3419 FT_STRING, BASE_NONE, NULL, 0x0,
3420 "Client name specific to TightVNC", HFILL }
3422 { &hf_vnc_tight_encoding_type,
3423 { "Encoding type", "vnc.encoding_type",
3424 FT_INT32, BASE_DEC, VALS(encoding_types_vs), 0x0,
3425 "Encoding type specific to TightVNC", HFILL }
3427 { &hf_vnc_tight_encoding_vendor,
3428 { "Encoding vendor code", "vnc.encoding_vendor",
3429 FT_STRING, BASE_NONE, NULL, 0x0,
3430 "Encoding vendor code specific to TightVNC", HFILL }
3432 { &hf_vnc_tight_encoding_name,
3433 { "Encoding name", "vnc.encoding_name",
3434 FT_STRING, BASE_NONE, NULL, 0x0,
3435 "Encoding name specific to TightVNC", HFILL }
3437 { &hf_vnc_tight_reset_stream0,
3438 { "Reset compression stream 0", "vnc.tight_reset_stream0",
3439 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3440 "Tight compression, reset compression stream 0", HFILL }
3442 { &hf_vnc_tight_reset_stream1,
3443 { "Reset compression stream 1", "vnc.tight_reset_stream1",
3444 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3445 "Tight compression, reset compression stream 1", HFILL }
3447 { &hf_vnc_tight_reset_stream2,
3448 { "Reset compression stream 2", "vnc.tight_reset_stream2",
3449 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3450 "Tight compression, reset compression stream 2", HFILL }
3452 { &hf_vnc_tight_reset_stream3,
3453 { "Reset compression stream 3", "vnc.tight_reset_stream3",
3454 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3455 "Tight compression, reset compression stream 3", HFILL }
3457 { &hf_vnc_tight_rect_type,
3458 { "Rectangle type", "vnc.tight_rect_type",
3459 FT_UINT8, BASE_HEX, NULL, 0x0,
3460 "Tight compression, rectangle type", HFILL }
3462 { &hf_vnc_tight_image_len,
3463 { "Image data length", "vnc.tight_image_len",
3464 FT_UINT32, BASE_DEC, NULL, 0x0,
3465 "Tight compression, length of image data", HFILL }
3467 { &hf_vnc_tight_image_data,
3468 { "Image data", "vnc.tight_image_data",
3469 FT_BYTES, BASE_NONE, NULL, 0x0,
3470 "Tight compression, image data", HFILL }
3472 { &hf_vnc_tight_fill_color,
3473 { "Fill color (RGB)", "vnc.tight_fill_color",
3474 FT_BYTES, BASE_NONE, NULL, 0x0,
3475 "Tight compression, fill color for solid rectangle", HFILL }
3477 { &hf_vnc_tight_filter_flag,
3478 { "Explicit filter flag", "vnc.tight_filter_flag",
3479 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3480 "Tight compression, explicit filter flag", HFILL }
3482 { &hf_vnc_tight_filter_id,
3483 { "Filter ID", "vnc.tight_filter_id",
3484 FT_UINT8, BASE_DEC, VALS(tight_filter_ids_vs), 0x0,
3485 "Tight compression, filter ID", HFILL }
3487 { &hf_vnc_tight_palette_num_colors,
3488 { "Number of colors in palette", "vnc.tight_palette_num_colors",
3489 FT_UINT8, BASE_DEC, NULL, 0x0,
3490 "Tight compression, number of colors in rectangle's palette", HFILL }
3492 { &hf_vnc_tight_palette_data,
3493 { "Palette data", "vnc.tight_palette_data",
3494 FT_BYTES, BASE_NONE, NULL, 0x0,
3495 "Tight compression, palette data for a rectangle", HFILL }
3497 { &hf_vnc_auth_challenge,
3498 { "Authentication challenge", "vnc.auth_challenge",
3499 FT_BYTES, BASE_NONE, NULL, 0x0,
3500 "Random authentication challenge from server to client", HFILL }
3502 { &hf_vnc_auth_response,
3503 { "Authentication response", "vnc.auth_response",
3504 FT_BYTES, BASE_NONE, NULL, 0x0,
3505 "Client's encrypted response to the server's authentication challenge", HFILL }
3507 { &hf_vnc_auth_result,
3508 { "Authentication result", "vnc.auth_result",
3509 FT_BOOLEAN, 32, TFS(&auth_result_tfs), 0x1,
3510 NULL, HFILL }
3512 { &hf_vnc_auth_error_length,
3513 { "Length of authentication error", "vnc.auth_error_len",
3514 FT_UINT32, BASE_DEC, NULL, 0x0,
3515 "Authentication error length (present only if the authentication result is fail", HFILL }
3517 { &hf_vnc_auth_error,
3518 { "Authentication error", "vnc.auth_error",
3519 FT_STRING, BASE_NONE, NULL, 0x0,
3520 "Authentication error (present only if the authentication result is fail", HFILL }
3522 { &hf_vnc_ard_auth_generator,
3523 { "Generator", "vnc.ard_auth_generator",
3524 FT_UINT16, BASE_DEC, NULL, 0x0,
3525 "Generator for Diffie-Hellman key exchange", HFILL }
3527 { &hf_vnc_ard_auth_key_len,
3528 { "Key length", "vnc.ard_auth_key_len",
3529 FT_UINT16, BASE_DEC, NULL, 0x0,
3530 "Diffie-Hellman key length", HFILL }
3532 { &hf_vnc_ard_auth_modulus,
3533 { "Prime modulus", "vnc.ard_auth_modulus",
3534 FT_BYTES, BASE_NONE, NULL, 0x0,
3535 "Prime modulus for Diffie-Hellman key exchange", HFILL }
3537 { &hf_vnc_ard_auth_server_key,
3538 { "Server public key", "vnc.ard_auth_server_key",
3539 FT_BYTES, BASE_NONE, NULL, 0x0,
3540 "Server's public Diffie-Hellman key", HFILL }
3542 { &hf_vnc_ard_auth_credentials,
3543 { "Encrypted credentials", "vnc.ard_auth_credentials",
3544 FT_BYTES, BASE_NONE, NULL, 0x0,
3545 "Encrypted client username and password", HFILL }
3547 { &hf_vnc_ard_auth_client_key,
3548 { "Client public key", "vnc.ard_auth_client_key",
3549 FT_BYTES, BASE_NONE, NULL, 0x0,
3550 "Client's public Diffie-Hellman key", HFILL }
3552 { &hf_vnc_share_desktop_flag,
3553 { "Share desktop flag", "vnc.share_desktop_flag",
3554 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3555 "Client's desire to share the server's desktop with other clients", HFILL }
3557 { &hf_vnc_width,
3558 { "Framebuffer width", "vnc.width",
3559 FT_UINT16, BASE_DEC, NULL, 0x0,
3560 "Width of the framebuffer (screen) in pixels", HFILL }
3562 { &hf_vnc_height,
3563 { "Framebuffer height", "vnc.height",
3564 FT_UINT16, BASE_DEC, NULL, 0x0,
3565 "Height of the framebuffer (screen) in pixels", HFILL }
3567 { &hf_vnc_server_bits_per_pixel,
3568 { "Bits per pixel", "vnc.server_bits_per_pixel",
3569 FT_UINT8, BASE_DEC, NULL, 0x0,
3570 "Number of bits used by server for each pixel value on the wire from the server", HFILL }
3572 { &hf_vnc_server_depth,
3573 { "Depth", "vnc.server_depth",
3574 FT_UINT8, BASE_DEC, NULL, 0x0,
3575 "Number of useful bits in the pixel value on server", HFILL }
3577 { &hf_vnc_server_big_endian_flag,
3578 { "Big endian flag", "vnc.server_big_endian_flag",
3579 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3580 "True if multi-byte pixels are interpreted as big endian by server", HFILL }
3582 { &hf_vnc_server_true_color_flag,
3583 { "True color flag", "vnc.server_true_color_flag",
3584 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3585 "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 }
3587 { &hf_vnc_server_red_max,
3588 { "Red maximum", "vnc.server_red_max",
3589 FT_UINT16, BASE_DEC, NULL, 0x0,
3590 "Maximum red value on server as n: 2^n - 1", HFILL }
3592 { &hf_vnc_server_green_max,
3593 { "Green maximum", "vnc.server_green_max",
3594 FT_UINT16, BASE_DEC, NULL, 0x0,
3595 "Maximum green value on server as n: 2^n - 1", HFILL }
3597 { &hf_vnc_server_blue_max,
3598 { "Blue maximum", "vnc.server_blue_max",
3599 FT_UINT16, BASE_DEC, NULL, 0x0,
3600 "Maximum blue value on server as n: 2^n - 1", HFILL }
3602 { &hf_vnc_server_red_shift,
3603 { "Red shift", "vnc.server_red_shift",
3604 FT_UINT8, BASE_DEC, NULL, 0x0,
3605 "Number of shifts needed to get the red value in a pixel to the least significant bit on the server", HFILL }
3607 { &hf_vnc_server_green_shift,
3608 { "Green shift", "vnc.server_green_shift",
3609 FT_UINT8, BASE_DEC, NULL, 0x0,
3610 "Number of shifts needed to get the green value in a pixel to the least significant bit on the server", HFILL }
3612 { &hf_vnc_server_blue_shift,
3613 { "Blue shift", "vnc.server_blue_shift",
3614 FT_UINT8, BASE_DEC, NULL, 0x0,
3615 "Number of shifts needed to get the blue value in a pixel to the least significant bit on the server", HFILL }
3617 { &hf_vnc_desktop_name_len,
3618 { "Desktop name length", "vnc.desktop_name_len",
3619 FT_UINT32, BASE_DEC, NULL, 0x0,
3620 "Length of desktop name in bytes", HFILL }
3622 { &hf_vnc_desktop_screen_num,
3623 { "Number of screens", "vnc.screen_num",
3624 FT_UINT8, BASE_DEC, NULL, 0x0,
3625 NULL, HFILL }
3627 { &hf_vnc_desktop_screen_id,
3628 { "Screen ID", "vnc.screen_id",
3629 FT_UINT32, BASE_DEC, NULL, 0x0,
3630 "ID of screen", HFILL }
3632 { &hf_vnc_desktop_screen_x,
3633 { "Screen X position", "vnc.screen_x",
3634 FT_UINT16, BASE_DEC, NULL, 0x0,
3635 "X coordinate of screen", HFILL }
3637 { &hf_vnc_desktop_screen_y,
3638 { "Screen Y position", "vnc.screen_y",
3639 FT_UINT16, BASE_DEC, NULL, 0x0,
3640 "Y coordinate of screen", HFILL }
3642 { &hf_vnc_desktop_screen_width,
3643 { "Screen width", "vnc.screen_width",
3644 FT_UINT16, BASE_DEC, NULL, 0x0,
3645 "Width of screen", HFILL }
3647 { &hf_vnc_desktop_screen_height,
3648 { "Screen height", "vnc.screen_height",
3649 FT_UINT16, BASE_DEC, NULL, 0x0,
3650 "Height of screen", HFILL }
3652 { &hf_vnc_desktop_screen_flags,
3653 { "Screen flags", "vnc.screen_flags",
3654 FT_UINT32, BASE_DEC, NULL, 0x0,
3655 "Flags of screen", HFILL }
3657 { &hf_vnc_desktop_name,
3658 { "Desktop name", "vnc.desktop_name",
3659 FT_STRING, BASE_NONE, NULL, 0x0,
3660 "Name of the VNC desktop on the server", HFILL }
3662 { &hf_vnc_num_server_message_types,
3663 { "Server message types", "vnc.num_server_message_types",
3664 FT_UINT16, BASE_DEC, NULL, 0x0,
3665 "Unknown", HFILL } /* XXX - Needs description */
3667 { &hf_vnc_num_client_message_types,
3668 { "Client message types", "vnc.num_client_message_types",
3669 FT_UINT16, BASE_DEC, NULL, 0x0,
3670 "Unknown", HFILL } /* XXX - Needs description */
3672 { &hf_vnc_num_encoding_types,
3673 { "Encoding types", "vnc.num_encoding_types",
3674 FT_UINT16, BASE_DEC, NULL, 0x0,
3675 "Unknown", HFILL } /* XXX - Needs description */
3677 { &hf_vnc_client_message_type,
3678 { "Client Message Type", "vnc.client_message_type",
3679 FT_UINT8, BASE_DEC, VALS(vnc_client_message_types_vs), 0x0,
3680 "Message type from client", HFILL }
3682 { &hf_vnc_client_bits_per_pixel,
3683 { "Bits per pixel", "vnc.client_bits_per_pixel",
3684 FT_UINT8, BASE_DEC, NULL, 0x0,
3685 "Number of bits used by server for each pixel value on the wire from the client", HFILL }
3687 { &hf_vnc_client_depth,
3688 { "Depth", "vnc.client_depth",
3689 FT_UINT8, BASE_DEC, NULL, 0x0,
3690 "Number of useful bits in the pixel value on client", HFILL }
3692 { &hf_vnc_client_big_endian_flag,
3693 { "Big endian flag", "vnc.client_big_endian_flag",
3694 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3695 "True if multi-byte pixels are interpreted as big endian by client", HFILL }
3697 { &hf_vnc_client_true_color_flag,
3698 { "True color flag", "vnc.client_true_color_flag",
3699 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3700 "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 }
3702 { &hf_vnc_client_red_max,
3703 { "Red maximum", "vnc.client_red_max",
3704 FT_UINT16, BASE_DEC, NULL, 0x0,
3705 "Maximum red value on client as n: 2^n - 1", HFILL }
3707 { &hf_vnc_client_green_max,
3708 { "Green maximum", "vnc.client_green_max",
3709 FT_UINT16, BASE_DEC, NULL, 0x0,
3710 "Maximum green value on client as n: 2^n - 1", HFILL }
3712 { &hf_vnc_client_blue_max,
3713 { "Blue maximum", "vnc.client_blue_max",
3714 FT_UINT16, BASE_DEC, NULL, 0x0,
3715 "Maximum blue value on client as n: 2^n - 1", HFILL }
3717 { &hf_vnc_client_red_shift,
3718 { "Red shift", "vnc.client_red_shift",
3719 FT_UINT8, BASE_DEC, NULL, 0x0,
3720 "Number of shifts needed to get the red value in a pixel to the least significant bit on the client", HFILL }
3722 { &hf_vnc_client_green_shift,
3723 { "Green shift", "vnc.client_green_shift",
3724 FT_UINT8, BASE_DEC, NULL, 0x0,
3725 "Number of shifts needed to get the green value in a pixel to the least significant bit on the client", HFILL }
3727 { &hf_vnc_client_blue_shift,
3728 { "Blue shift", "vnc.client_blue_shift",
3729 FT_UINT8, BASE_DEC, NULL, 0x0,
3730 "Number of shifts needed to get the blue value in a pixel to the least significant bit on the client", HFILL }
3733 /* Client Key Event */
3734 { &hf_vnc_key_down,
3735 { "Key down", "vnc.key_down",
3736 FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x0,
3737 "Specifies whether the key is being pressed or not", HFILL }
3739 { &hf_vnc_key,
3740 { "Key", "vnc.key",
3741 FT_UINT32, BASE_HEX | BASE_EXT_STRING, &x11_keysym_vals_source_ext, 0x0, /* keysym_vals_source_exr is from packet-x11.c */
3742 "Key being pressed/depressed", HFILL }
3745 /* Client Pointer Event */
3746 { &hf_vnc_button_1_pos,
3747 { "Mouse button #1 position", "vnc.button_1_pos",
3748 FT_BOOLEAN, 8, TFS(&button_mask_tfs), 0x1,
3749 "Whether mouse button #1 is being pressed or not", HFILL }
3751 { &hf_vnc_button_2_pos,
3752 { "Mouse button #2 position", "vnc.button_2_pos",
3753 FT_BOOLEAN, 8, TFS(&button_mask_tfs), 0x2,
3754 "Whether mouse button #2 is being pressed or not", HFILL }
3756 { &hf_vnc_button_3_pos,
3757 { "Mouse button #3 position", "vnc.button_3_pos",
3758 FT_BOOLEAN, 8, TFS(&button_mask_tfs), 0x4,
3759 "Whether mouse button #3 is being pressed or not", HFILL }
3761 { &hf_vnc_button_4_pos,
3762 { "Mouse button #4 position", "vnc.button_4_pos",
3763 FT_BOOLEAN, 8, TFS(&button_mask_tfs), 0x8,
3764 "Whether mouse button #4 is being pressed or not", HFILL }
3766 { &hf_vnc_button_5_pos,
3767 { "Mouse button #5 position", "vnc.button_5_pos",
3768 FT_BOOLEAN, 8, TFS(&button_mask_tfs), 0x10,
3769 "Whether mouse button #5 is being pressed or not", HFILL }
3771 { &hf_vnc_button_6_pos,
3772 { "Mouse button #6 position", "vnc.button_6_pos",
3773 FT_BOOLEAN, 8, TFS(&button_mask_tfs), 0x20,
3774 "Whether mouse button #6 is being pressed or not", HFILL }
3776 { &hf_vnc_button_7_pos,
3777 { "Mouse button #7 position", "vnc.button_7_pos",
3778 FT_BOOLEAN, 8, TFS(&button_mask_tfs), 0x40,
3779 "Whether mouse button #7 is being pressed or not", HFILL }
3781 { &hf_vnc_button_8_pos,
3782 { "Mouse button #8 position", "vnc.button_8_pos",
3783 FT_BOOLEAN, 8, TFS(&button_mask_tfs), 0x80,
3784 "Whether mouse button #8 is being pressed or not", HFILL }
3786 { &hf_vnc_pointer_x_pos,
3787 { "X position", "vnc.pointer_x_pos",
3788 FT_UINT16, BASE_DEC, NULL, 0x0,
3789 "Position of mouse cursor on the x-axis", HFILL }
3791 { &hf_vnc_pointer_y_pos,
3792 { "Y position", "vnc.pointer_y_pos",
3793 FT_UINT16, BASE_DEC, NULL, 0x0,
3794 "Position of mouse cursor on the y-axis", HFILL }
3796 { &hf_vnc_encoding_num,
3797 { "Number of encodings", "vnc.client_set_encodings_num",
3798 FT_UINT16, BASE_DEC, NULL, 0x0,
3799 "Number of encodings used to send pixel data from server to client", HFILL }
3801 { &hf_vnc_client_set_encodings_encoding_type,
3802 { "Encoding type", "vnc.client_set_encodings_encoding_type",
3803 FT_INT32, BASE_DEC, VALS(encoding_types_vs), 0x0,
3804 "Type of encoding used to send pixel data from server to client", HFILL }
3807 /* Client Framebuffer Update Request */
3808 { &hf_vnc_update_req_incremental,
3809 { "Incremental update", "vnc.update_req_incremental",
3810 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3811 "Specifies if the client wants an incremental update instead of a full one", HFILL }
3813 { &hf_vnc_update_req_x_pos,
3814 { "X position", "vnc.update_req_x_pos",
3815 FT_UINT16, BASE_DEC, NULL, 0x0,
3816 "X position of framebuffer (screen) update requested", HFILL }
3818 { &hf_vnc_update_req_y_pos,
3819 { "Y position", "vnc.update_req_y_pos",
3820 FT_UINT16, BASE_DEC, NULL, 0x0,
3821 "Y position of framebuffer (screen) update request", HFILL }
3823 { &hf_vnc_update_req_width,
3824 { "Width", "vnc.update_req_width",
3825 FT_UINT16, BASE_DEC, NULL, 0x0,
3826 "Width of framebuffer (screen) update request", HFILL }
3828 { &hf_vnc_update_req_height,
3829 { "Height", "vnc.update_req_height",
3830 FT_UINT16, BASE_DEC, NULL, 0x0,
3831 "Height of framebuffer (screen) update request", HFILL }
3833 { &hf_vnc_client_cut_text_len,
3834 { "Length", "vnc.client_cut_text_len",
3835 FT_UINT32, BASE_DEC, NULL, 0x0,
3836 "Length of client's copy/cut text (clipboard) string in bytes", HFILL }
3838 { &hf_vnc_client_cut_text,
3839 { "Text", "vnc.client_cut_text",
3840 FT_STRING, BASE_NONE, NULL, 0x0,
3841 "Text string in the client's copy/cut text (clipboard)", HFILL }
3845 /********** Server Message Types **********/
3846 { &hf_vnc_server_message_type,
3847 { "Server Message Type", "vnc.server_message_type",
3848 FT_UINT8, BASE_DEC, VALS(vnc_server_message_types_vs), 0x0,
3849 "Message type from server", HFILL }
3852 { &hf_vnc_rectangle_num,
3853 { "Number of rectangles", "vnc.fb_update_num_rects",
3854 FT_UINT16, BASE_DEC, NULL, 0x0,
3855 "Number of rectangles of this server framebuffer update", HFILL }
3858 { &hf_vnc_fb_update_x_pos,
3859 { "X position", "vnc.fb_update_x_pos",
3860 FT_UINT16, BASE_DEC, NULL, 0x0,
3861 "X position of this server framebuffer update", HFILL }
3864 { &hf_vnc_fb_update_y_pos,
3865 { "Y position", "vnc.fb_update_y_pos",
3866 FT_UINT16, BASE_DEC, NULL, 0x0,
3867 "Y position of this server framebuffer update", HFILL }
3870 { &hf_vnc_fb_update_width,
3871 { "Width", "vnc.fb_update_width",
3872 FT_UINT16, BASE_DEC, NULL, 0x0,
3873 "Width of this server framebuffer update", HFILL }
3876 { &hf_vnc_fb_update_height,
3877 { "Height", "vnc.fb_update_height",
3878 FT_UINT16, BASE_DEC, NULL, 0x0,
3879 "Height of this server framebuffer update", HFILL }
3882 { &hf_vnc_fb_update_encoding_type,
3883 { "Encoding type", "vnc.fb_update_encoding_type",
3884 FT_INT32, BASE_DEC, VALS(encoding_types_vs), 0x0,
3885 "Encoding type of this server framebuffer update", HFILL }
3888 /* Cursor encoding */
3889 { &hf_vnc_cursor_x_fore_back,
3890 { "X Cursor foreground RGB / background RGB", "vnc.cursor_x_fore_back",
3891 FT_BYTES, BASE_NONE, NULL, 0x0,
3892 "RGB values for the X cursor's foreground and background", HFILL }
3895 { &hf_vnc_cursor_encoding_pixels,
3896 { "Cursor encoding pixels", "vnc.cursor_encoding_pixels",
3897 FT_BYTES, BASE_NONE, NULL, 0x0,
3898 "Cursor encoding pixel data", HFILL }
3901 { &hf_vnc_cursor_encoding_bitmask,
3902 { "Cursor encoding bitmask", "vnc.cursor_encoding_bitmask",
3903 FT_BYTES, BASE_NONE, NULL, 0x0,
3904 "Cursor encoding pixel bitmask", HFILL }
3907 /* Raw Encoding */
3908 { &hf_vnc_raw_pixel_data,
3909 { "Pixel data", "vnc.raw_pixel_data",
3910 FT_BYTES, BASE_NONE, NULL, 0x0,
3911 "Raw pixel data.", HFILL }
3914 /* CopyRect Encoding*/
3915 { &hf_vnc_copyrect_src_x_pos,
3916 { "Source x position", "vnc.copyrect_src_x_pos",
3917 FT_UINT16, BASE_DEC, NULL, 0x0,
3918 "X position of the rectangle to copy from", HFILL }
3921 { &hf_vnc_copyrect_src_y_pos,
3922 { "Source y position", "vnc.copyrect_src_y_pos",
3923 FT_UINT16, BASE_DEC, NULL, 0x0,
3924 "Y position of the rectangle to copy from", HFILL }
3927 /* RRE Encoding */
3928 { &hf_vnc_rre_num_subrects,
3929 { "Number of subrectangles", "vnc.rre_num_subrects",
3930 FT_UINT32, BASE_DEC, NULL, 0x0,
3931 "Number of subrectangles contained in this encoding type", HFILL }
3934 { &hf_vnc_rre_bg_pixel,
3935 { "Background pixel value", "vnc.rre_bg_pixel",
3936 FT_BYTES, BASE_NONE, NULL, 0x0,
3937 NULL, HFILL }
3940 { &hf_vnc_rre_subrect_pixel,
3941 { "Pixel value", "vnc.rre_subrect_pixel",
3942 FT_BYTES, BASE_NONE, NULL, 0x0,
3943 "Subrectangle pixel value", HFILL }
3946 { &hf_vnc_rre_subrect_x_pos,
3947 { "X position", "vnc.rre_subrect_x_pos",
3948 FT_UINT16, BASE_DEC, NULL, 0x0,
3949 "Position of this subrectangle on the x axis", HFILL }
3952 { &hf_vnc_rre_subrect_y_pos,
3953 { "Y position", "vnc.rre_subrect_y_pos",
3954 FT_UINT16, BASE_DEC, NULL, 0x0,
3955 "Position of this subrectangle on the y axis", HFILL }
3958 { &hf_vnc_rre_subrect_width,
3959 { "Width", "vnc.rre_subrect_width",
3960 FT_UINT16, BASE_DEC, NULL, 0x0,
3961 "Width of this subrectangle", HFILL }
3964 { &hf_vnc_rre_subrect_height,
3965 { "Height", "vnc.rre_subrect_height",
3966 FT_UINT16, BASE_DEC, NULL, 0x0,
3967 "Height of this subrectangle", HFILL }
3971 /* Hextile Encoding */
3972 { &hf_vnc_hextile_subencoding_mask,
3973 { "Subencoding type", "vnc.hextile_subencoding",
3974 FT_UINT8, BASE_DEC, NULL, 0x0,
3975 "Hextile subencoding type.", HFILL }
3978 { &hf_vnc_hextile_raw,
3979 { "Raw", "vnc.hextile_raw",
3980 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x1,
3981 "Raw subencoding is used in this tile", HFILL }
3984 { &hf_vnc_hextile_raw_value,
3985 { "Raw pixel values", "vnc.hextile_raw_value",
3986 FT_BYTES, BASE_NONE, NULL, 0x0,
3987 "Raw subencoding pixel values", HFILL }
3990 { &hf_vnc_hextile_bg,
3991 { "Background Specified", "vnc.hextile_bg",
3992 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x2,
3993 "Background Specified subencoding is used in this tile", HFILL }
3996 { &hf_vnc_hextile_bg_value,
3997 { "Background pixel value", "vnc.hextile_bg_value",
3998 FT_BYTES, BASE_NONE, NULL, 0x0,
3999 "Background color for this tile", HFILL }
4002 { &hf_vnc_hextile_fg,
4003 { "Foreground Specified", "vnc.hextile_fg",
4004 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x4,
4005 "Foreground Specified subencoding is used in this tile", HFILL }
4008 { &hf_vnc_hextile_fg_value,
4009 { "Foreground pixel value", "vnc.hextile_fg_value",
4010 FT_BYTES, BASE_NONE, NULL, 0x0,
4011 "Foreground color for this tile", HFILL }
4014 { &hf_vnc_hextile_anysubrects,
4015 { "Any Subrects", "vnc.hextile_anysubrects",
4016 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x8,
4017 "Any subrects subencoding is used in this tile", HFILL }
4020 { &hf_vnc_hextile_num_subrects,
4021 { "Number of subrectangles", "vnc.hextile_num_subrects",
4022 FT_UINT8, BASE_DEC, NULL, 0x0,
4023 "Number of subrectangles that follow", HFILL }
4026 { &hf_vnc_hextile_subrectscolored,
4027 { "Subrects Colored", "vnc.hextile_subrectscolored",
4028 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10,
4029 "Subrects colored subencoding is used in this tile", HFILL }
4032 { &hf_vnc_hextile_subrect_pixel_value,
4033 { "Pixel value", "vnc.hextile_subrect_pixel_value",
4034 FT_BYTES, BASE_NONE, NULL, 0x0,
4035 "Pixel value of this subrectangle", HFILL }
4038 { &hf_vnc_hextile_subrect_x_pos,
4039 { "X position", "vnc.hextile_subrect_x_pos",
4040 FT_UINT8, BASE_DEC, NULL, 0xF0, /* Top 4 bits */
4041 "X position of this subrectangle", HFILL }
4044 { &hf_vnc_hextile_subrect_y_pos,
4045 { "Y position", "vnc.hextile_subrect_y_pos",
4046 FT_UINT8, BASE_DEC, NULL, 0xF, /* Bottom 4 bits */
4047 "Y position of this subrectangle", HFILL }
4050 { &hf_vnc_hextile_subrect_width,
4051 { "Width", "vnc.hextile_subrect_width",
4052 FT_UINT8, BASE_DEC, NULL, 0xF0, /* Top 4 bits */
4053 "Subrectangle width minus one", HFILL }
4056 { &hf_vnc_hextile_subrect_height,
4057 { "Height", "vnc.hextile_subrect_height",
4058 FT_UINT8, BASE_DEC, NULL, 0xF, /* Bottom 4 bits */
4059 "Subrectangle height minus one", HFILL }
4063 /* ZRLE Encoding */
4064 { &hf_vnc_zrle_len,
4065 { "ZRLE compressed length", "vnc.zrle_len",
4066 FT_UINT32, BASE_DEC, NULL, 0x0,
4067 "Length of compressed ZRLE data that follows", HFILL }
4070 { &hf_vnc_zrle_subencoding,
4071 { "Subencoding type", "vnc.zrle_subencoding",
4072 FT_UINT8, BASE_DEC, NULL, 0x0,
4073 "Subencoding type byte", HFILL }
4076 { &hf_vnc_zrle_rle,
4077 { "RLE", "vnc.zrle_rle",
4078 FT_UINT8, BASE_DEC, VALS(yes_no_vs), 0x80, /* Upper bit */
4079 "Specifies that data is run-length encoded", HFILL }
4082 { &hf_vnc_zrle_palette_size,
4083 { "Palette size", "vnc.zrle_palette_size",
4084 FT_UINT8, BASE_DEC, NULL, 0x7F, /* Lower 7 bits */
4085 NULL, HFILL }
4088 { &hf_vnc_zrle_data,
4089 { "ZRLE compressed data", "vnc.zrle_data",
4090 FT_BYTES, BASE_NONE, NULL, 0x0,
4091 "Compressed ZRLE data. Compiling with zlib support will uncompress and dissect this data", HFILL }
4094 { &hf_vnc_zrle_raw,
4095 { "Pixel values", "vnc.zrle_raw",
4096 FT_BYTES, BASE_NONE, NULL, 0x0,
4097 "Raw pixel values for this tile", HFILL }
4100 { &hf_vnc_zrle_palette,
4101 { "Palette", "vnc.zrle_palette",
4102 FT_BYTES, BASE_NONE, NULL, 0x0,
4103 "Palette pixel values", HFILL }
4106 /* Server Set Colormap Entries */
4107 { &hf_vnc_colormap_first_color,
4108 { "First color", "vnc.colormap_first_color",
4109 FT_UINT16, BASE_DEC, NULL, 0x0,
4110 "First color that should be mapped to given RGB intensities", HFILL }
4113 { &hf_vnc_color_groups,
4114 { "Color groups", "vnc.color_groups",
4115 FT_NONE, BASE_NONE, NULL, 0x0,
4116 NULL, HFILL }
4119 { &hf_vnc_colormap_num_colors,
4120 { "Number of color groups", "vnc.colormap_groups",
4121 FT_UINT16, BASE_DEC, NULL, 0x0,
4122 "Number of red/green/blue color groups", HFILL }
4124 { &hf_vnc_colormap_red,
4125 { "Red", "vnc.colormap_red",
4126 FT_UINT16, BASE_DEC, NULL, 0x0,
4127 "Red intensity", HFILL }
4129 { &hf_vnc_colormap_green,
4130 { "Green", "vnc.colormap_green",
4131 FT_UINT16, BASE_DEC, NULL, 0x0,
4132 "Green intensity", HFILL }
4134 { &hf_vnc_colormap_blue,
4135 { "Blue", "vnc.colormap_blue",
4136 FT_UINT16, BASE_DEC, NULL, 0x0,
4137 "Blue intensity", HFILL }
4140 /* Server Cut Text */
4141 { &hf_vnc_server_cut_text_len,
4142 { "Length", "vnc.server_cut_text_len",
4143 FT_UINT32, BASE_DEC, NULL, 0x0,
4144 "Length of server's copy/cut text (clipboard) string in bytes", HFILL }
4146 { &hf_vnc_server_cut_text,
4147 { "Text", "vnc.server_cut_text",
4148 FT_STRING, BASE_NONE, NULL, 0x0,
4149 "Text string in the server's copy/cut text (clipboard)", HFILL }
4152 /* LibVNCServer additions */
4153 { &hf_vnc_supported_messages_client2server,
4154 { "Client2server", "vnc.supported_messages_client2server",
4155 FT_BYTES, BASE_NONE, NULL, 0x0,
4156 "Supported client to server messages (bit flags)", HFILL }
4158 { &hf_vnc_supported_messages_server2client,
4159 { "Server2client", "vnc.supported_messages_server2client",
4160 FT_BYTES, BASE_NONE, NULL, 0x0,
4161 "Supported server to client messages (bit flags)", HFILL }
4163 { &hf_vnc_supported_encodings,
4164 { "Encoding", "vnc.supported_encodings",
4165 FT_UINT32, BASE_HEX, NULL, 0x0,
4166 "Supported encoding", HFILL }
4168 { &hf_vnc_server_identity,
4169 { "Server Identity", "vnc.server_identity",
4170 FT_STRING, BASE_NONE, NULL, 0x0,
4171 "Server identity string", HFILL }
4174 /* MirrorLink */
4175 { &hf_vnc_mirrorlink_type,
4176 { "Type", "vnc.mirrorlink_type",
4177 FT_UINT8, BASE_DEC, VALS(vnc_mirrorlink_types_vs), 0x0,
4178 "MirrorLink extension message type", HFILL }
4180 { &hf_vnc_mirrorlink_length,
4181 { "Length", "vnc.mirrorlink_length",
4182 FT_UINT16, BASE_DEC, NULL, 0x0,
4183 "Payload length", HFILL }
4185 { &hf_vnc_mirrorlink_version_major,
4186 { "Major Version", "vnc.mirrorlink_version_major",
4187 FT_UINT8, BASE_DEC, NULL, 0x0,
4188 "MirrorLink major version", HFILL }
4190 { &hf_vnc_mirrorlink_version_minor,
4191 { "Minor Version", "vnc.mirrorlink_version_minor",
4192 FT_UINT8, BASE_DEC, NULL, 0x0,
4193 "MirrorLink minor version", HFILL }
4195 { &hf_vnc_mirrorlink_framebuffer_configuration,
4196 { "Configuration",
4197 "vnc.mirrorlink_framebuffer_configuration",
4198 FT_UINT16, BASE_HEX, NULL, 0x0,
4199 "Framebuffer configuration", HFILL }
4201 { &hf_vnc_mirrorlink_pixel_width,
4202 { "Pixel Width", "vnc.mirrorlink_pixel_width",
4203 FT_UINT16, BASE_DEC, NULL, 0x0,
4204 "Display width [pixel]", HFILL }
4206 { &hf_vnc_mirrorlink_pixel_height,
4207 { "Pixel Height", "vnc.mirrorlink_pixel_height",
4208 FT_UINT16, BASE_DEC, NULL, 0x0,
4209 "Display height [pixel]", HFILL }
4211 { &hf_vnc_mirrorlink_pixel_format,
4212 { "Pixel Format", "vnc.mirrorlink_pixel_format",
4213 FT_UINT16, BASE_HEX, NULL, 0x0,
4214 "Pixel format support", HFILL }
4216 { &hf_vnc_mirrorlink_display_width,
4217 { "Display Width", "vnc.mirrorlink_display_width",
4218 FT_UINT16, BASE_DEC, NULL, 0x0,
4219 "Display width [mm]", HFILL }
4221 { &hf_vnc_mirrorlink_display_height,
4222 { "Display Height", "vnc.mirrorlink_display_height",
4223 FT_UINT16, BASE_DEC, NULL, 0x0,
4224 "Display height [mm]", HFILL }
4226 { &hf_vnc_mirrorlink_display_distance,
4227 { "Display Distance", "vnc.mirrorlink_display_distance",
4228 FT_UINT16, BASE_DEC, NULL, 0x0,
4229 "Display distance [mm]", HFILL }
4231 { &hf_vnc_mirrorlink_keyboard_language,
4232 { "Keyboard Language", "vnc.mirrorlink_keyboard_language",
4233 FT_STRING, BASE_NONE, NULL, 0x0,
4234 "Keyboard layout - Language code (according ISO 639-1)",
4235 HFILL }
4237 { &hf_vnc_mirrorlink_keyboard_country,
4238 { "Keyboard Country", "vnc.mirrorlink_keyboard_country",
4239 FT_STRING, BASE_NONE, NULL, 0x0,
4240 "Keyboard layout - Country code (according ISO 3166-1 alpha-2)",
4241 HFILL }
4243 { &hf_vnc_mirrorlink_ui_language,
4244 { "UI Language", "vnc.mirrorlink_ui_language",
4245 FT_STRING, BASE_NONE, NULL, 0x0,
4246 "UI language - Language code (according ISO 639-1)", HFILL }
4248 { &hf_vnc_mirrorlink_ui_country,
4249 { "UI Country", "vnc.mirrorlink_ui_country",
4250 FT_STRING, BASE_NONE, NULL, 0x0,
4251 "UI language - Country code (according ISO 3166-1 alpha 2)",
4252 HFILL }
4254 { &hf_vnc_mirrorlink_knob_keys,
4255 { "Knob Keys", "vnc.mirrorlink_knob_keys",
4256 FT_UINT32, BASE_HEX, NULL, 0x0,
4257 "Supported knob keys", HFILL }
4259 { &hf_vnc_mirrorlink_device_keys,
4260 { "Device Keys", "vnc.mirrorlink_device_keys",
4261 FT_UINT32, BASE_HEX, NULL, 0x0,
4262 "Supported device keys", HFILL }
4264 { &hf_vnc_mirrorlink_multimedia_keys,
4265 { "Multimedia Keys", "vnc.mirrorlink_multimedia_keys",
4266 FT_UINT32, BASE_HEX, NULL, 0x0,
4267 "Supported multimedia keys", HFILL }
4269 { &hf_vnc_mirrorlink_key_related,
4270 { "Keyboard", "vnc.mirrorlink_key_related",
4271 FT_UINT32, BASE_HEX, NULL, 0x0,
4272 "Keyboard related", HFILL }
4274 { &hf_vnc_mirrorlink_pointer_related,
4275 { "Pointer", "vnc.mirrorlink_pointer_related",
4276 FT_UINT32, BASE_HEX, NULL, 0x0,
4277 "Pointer related", HFILL }
4279 { &hf_vnc_mirrorlink_key_symbol_value_client,
4280 { "Client KeySymValue",
4281 "vnc.mirrorlink_key_symbol_value_client",
4282 FT_UINT32, BASE_HEX, NULL, 0x0,
4283 "Client key symbol value", HFILL }
4285 { &hf_vnc_mirrorlink_key_symbol_value_server,
4286 { "Server KeySymValue",
4287 "vnc.mirrorlink_key_symbol_value_server",
4288 FT_UINT32, BASE_HEX, NULL, 0x0,
4289 "Server key symbol value", HFILL }
4291 { &hf_vnc_mirrorlink_key_configuration,
4292 { "Configuration", "vnc.mirrorlink_key_configuration",
4293 FT_UINT8, BASE_HEX, NULL, 0x0,
4294 "Key event listing configuration", HFILL }
4296 { &hf_vnc_mirrorlink_key_num_events,
4297 { "Number of Key Events", "vnc.mirrorlink_key_num_events",
4298 FT_UINT8, BASE_DEC, NULL, 0x0,
4299 "Number of key events in list", HFILL }
4301 { &hf_vnc_mirrorlink_key_event_counter,
4302 { "Key Event Counter", "vnc.mirrorlink_key_event_counter",
4303 FT_UINT16, BASE_DEC, NULL, 0x0,
4304 "Key event listing counter", HFILL }
4306 { &hf_vnc_mirrorlink_key_symbol_value,
4307 { "KeySymValue",
4308 "vnc.mirrorlink_key_symbol_value",
4309 FT_UINT32, BASE_HEX, NULL, 0x0,
4310 "Key symbol value", HFILL }
4312 { &hf_vnc_mirrorlink_key_request_configuration,
4313 { "Configuration", "vnc.mirrorlink_key_request_configuration",
4314 FT_UINT32, BASE_HEX, NULL, 0x0,
4315 "Key event listing request configuration", HFILL }
4317 { &hf_vnc_mirrorlink_keyboard_configuration,
4318 { "Configuration", "vnc.mirrorlink_keyboard_configuration",
4319 FT_UINT32, BASE_HEX, NULL, 0x0,
4320 "Virtual keyboard configuration", HFILL }
4322 { &hf_vnc_mirrorlink_cursor_x,
4323 { "Cursor X", "vnc.mirrorlink_cursor_x",
4324 FT_UINT16, BASE_DEC, NULL, 0x0,
4325 "Cursor - X position", HFILL }
4327 { &hf_vnc_mirrorlink_cursor_y,
4328 { "Cursor Y", "vnc.mirrorlink_cursor_y",
4329 FT_UINT16, BASE_DEC, NULL, 0x0,
4330 "Cursor - Y position", HFILL }
4332 { &hf_vnc_mirrorlink_text_x,
4333 { "Text X", "vnc.mirrorlink_text_x",
4334 FT_UINT16, BASE_DEC, NULL, 0x0,
4335 "Text input area - X position", HFILL }
4337 { &hf_vnc_mirrorlink_text_y,
4338 { "Text Y", "vnc.mirrorlink_text_y",
4339 FT_UINT16, BASE_DEC, NULL, 0x0,
4340 "Text input area - Y position", HFILL }
4342 { &hf_vnc_mirrorlink_text_width,
4343 { "Text Width", "vnc.mirrorlink_text_width",
4344 FT_UINT16, BASE_DEC, NULL, 0x0,
4345 "Text input area - Width", HFILL }
4347 { &hf_vnc_mirrorlink_text_height,
4348 { "Text Height", "vnc.mirrorlink_text_height",
4349 FT_UINT16, BASE_DEC, NULL, 0x0,
4350 "Text input area - Height", HFILL }
4352 { &hf_vnc_mirrorlink_keyboard_request_configuration,
4353 { "Configuration",
4354 "vnc.mirrorlink_keyboard_request_configuration",
4355 FT_UINT32, BASE_HEX, NULL, 0x0,
4356 "Virtual keyboard request configuration", HFILL }
4358 { &hf_vnc_mirrorlink_device_status,
4359 { "Device Status", "vnc.mirrorlink_device_status",
4360 FT_UINT32, BASE_HEX, NULL, 0x0,
4361 "Status of Device Features", HFILL }
4363 { &hf_vnc_mirrorlink_app_id,
4364 { "App Id", "vnc.mirrorlink_app_id",
4365 FT_UINT32, BASE_HEX, NULL, 0x0,
4366 "Unique application id", HFILL }
4368 { &hf_vnc_mirrorlink_fb_block_x,
4369 { "Frambuffer X", "vnc.mirrorlink_fb_block_x",
4370 FT_UINT16, BASE_DEC, NULL, 0x0,
4371 "Frambuffer blocking - X position", HFILL }
4373 { &hf_vnc_mirrorlink_fb_block_y,
4374 { "Frambuffer Y", "vnc.mirrorlink_fb_block_y",
4375 FT_UINT16, BASE_DEC, NULL, 0x0,
4376 "Frambuffer blocking - Y position", HFILL }
4378 { &hf_vnc_mirrorlink_fb_block_width,
4379 { "Frambuffer Width", "vnc.mirrorlink_fb_block_width",
4380 FT_UINT16, BASE_DEC, NULL, 0x0,
4381 "Frambuffer blocking - Width", HFILL }
4383 { &hf_vnc_mirrorlink_fb_block_height,
4384 { "Frambuffer Height", "vnc.mirrorlink_fb_block_height",
4385 FT_UINT16, BASE_DEC, NULL, 0x0,
4386 "Frambuffer blocking - Height", HFILL }
4388 { &hf_vnc_mirrorlink_fb_block_reason,
4389 { "Reason", "vnc.mirrorlink_fb_block_reason",
4390 FT_UINT16, BASE_HEX, NULL, 0x0,
4391 "Reason for blocking", HFILL }
4393 { &hf_vnc_mirrorlink_audio_block_reason,
4394 { "Reason", "vnc.mirrorlink_audio_block_reason",
4395 FT_UINT16, BASE_HEX, NULL, 0x0,
4396 "Reason for blocking", HFILL }
4398 { &hf_vnc_mirrorlink_touch_num_events,
4399 { "Number of Touch Events", "vnc.mirrorlink_touch_num_events",
4400 FT_UINT8, BASE_DEC, NULL, 0x0,
4401 "Number of touch events in list", HFILL }
4403 { &hf_vnc_mirrorlink_touch_x,
4404 { "Touch X", "vnc.mirrorlink_touch_x",
4405 FT_UINT16, BASE_DEC, NULL, 0x0,
4406 "Touch event - X position", HFILL }
4408 { &hf_vnc_mirrorlink_touch_y,
4409 { "Touch Y", "vnc.mirrorlink_touch_y",
4410 FT_UINT16, BASE_DEC, NULL, 0x0,
4411 "Touch event - Y position", HFILL }
4413 { &hf_vnc_mirrorlink_touch_id,
4414 { "Touch Id", "vnc.mirrorlink_touch_id",
4415 FT_UINT8, BASE_DEC, NULL, 0x0,
4416 "Touch event - identifier", HFILL }
4418 { &hf_vnc_mirrorlink_touch_pressure,
4419 { "Touch Pressure", "vnc.mirrorlink_touch_pressure",
4420 FT_UINT8, BASE_DEC, NULL, 0x0,
4421 "Touch event - pressure value", HFILL }
4423 { &hf_vnc_mirrorlink_text,
4424 { "Text", "vnc.mirrorlink_text",
4425 FT_STRING, BASE_NONE, NULL, 0x0,
4426 "Textual information", HFILL }
4428 { &hf_vnc_mirrorlink_text_length,
4429 { "Length", "vnc.mirrorlink_text_length",
4430 FT_UINT16, BASE_DEC, NULL, 0x0,
4431 "Length of textual information", HFILL }
4433 { &hf_vnc_mirrorlink_text_max_length,
4434 { "Max Length", "vnc.mirrorlink_text_max_length",
4435 FT_UINT16, BASE_DEC, NULL, 0x0,
4436 "Maximum length of textual information", HFILL }
4438 { &hf_vnc_mirrorlink_unknown,
4439 { "Unknown", "vnc.mirrorlink_unknown",
4440 FT_BYTES, BASE_NONE, NULL, 0x0,
4441 "Unknown data", HFILL }
4444 /* Context Information */
4445 { &hf_vnc_context_information_app_id,
4446 { "App Id", "vnc.context_information_app_id",
4447 FT_UINT32, BASE_HEX, NULL, 0x0,
4448 "Unique application id", HFILL }
4450 { &hf_vnc_context_information_app_trust_level,
4451 { "App Trust Level",
4452 "vnc.context_information_app_trust_level",
4453 FT_UINT16, BASE_HEX, NULL, 0x0,
4454 "Trust Level for Application Category", HFILL }
4456 { &hf_vnc_context_information_content_trust_level,
4457 { "Content Trust Level",
4458 "vnc.context_information_content_trust_level",
4459 FT_UINT16, BASE_HEX, NULL, 0x0,
4460 "Trust Level for Content Category", HFILL }
4462 { &hf_vnc_context_information_app_category,
4463 { "App Category", "vnc.context_information_app_category",
4464 FT_UINT32, BASE_HEX, NULL, 0x0,
4465 "Application Category", HFILL }
4467 { &hf_vnc_context_information_content_category,
4468 { "Content Category",
4469 "vnc.context_information_content_category",
4470 FT_UINT32, BASE_HEX, NULL, 0x0,
4471 "Visual content category", HFILL }
4473 { &hf_vnc_context_information_content_rules,
4474 { "Content Rules", "vnc.context_information_content_rules",
4475 FT_UINT32, BASE_HEX, NULL, 0x0,
4476 "Visual content rules", HFILL }
4479 /* Scan Line based Run-Length Encoding */
4480 { &hf_vnc_slrle_run_num,
4481 { "Number of Runs", "vnc.slrle_run_num",
4482 FT_UINT16, BASE_DEC, NULL, 0x0,
4483 "Number of Runs within Line", HFILL }
4485 { &hf_vnc_slrle_run_data,
4486 { "Raw RLE data", "vnc.slrle_run_data",
4487 FT_BYTES, BASE_NONE, NULL, 0x0,
4488 "Raw Run-Length encoded data within Line", HFILL }
4491 /* H.264 Encoding */
4492 { &hf_vnc_h264_slice_type,
4493 { "Slice Type", "vnc.h264_slice_type",
4494 FT_UINT32, BASE_DEC, VALS(vnc_h264_slice_types_vs), 0x0,
4495 "Frame slice type", HFILL }
4497 { &hf_vnc_h264_nbytes,
4498 { "Number of Bytes", "vnc.h264_nbytes",
4499 FT_UINT32, BASE_DEC, NULL, 0x0,
4500 "Number of bytes within frame", HFILL }
4502 { &hf_vnc_h264_width,
4503 { "Width", "vnc.h264_width",
4504 FT_UINT32, BASE_DEC, NULL, 0x0,
4505 "Frame Width", HFILL }
4507 { &hf_vnc_h264_height,
4508 { "Height", "vnc.h264_height",
4509 FT_UINT32, BASE_DEC, NULL, 0x0,
4510 "Frame Height", HFILL }
4512 { &hf_vnc_h264_data,
4513 { "Data", "vnc.h264_data",
4514 FT_BYTES, BASE_NONE, NULL, 0x0,
4515 "Frame H.264 data", HFILL }
4520 /* Setup protocol subtree arrays */
4521 static gint *ett[] = {
4522 &ett_vnc,
4523 &ett_vnc_client_message_type,
4524 &ett_vnc_server_message_type,
4525 &ett_vnc_rect,
4526 &ett_vnc_encoding_type,
4527 &ett_vnc_rre_subrect,
4528 &ett_vnc_hextile_subencoding_mask,
4529 &ett_vnc_hextile_num_subrects,
4530 &ett_vnc_hextile_subrect,
4531 &ett_vnc_hextile_tile,
4532 &ett_vnc_zrle_subencoding,
4533 &ett_vnc_colormap_num_groups,
4534 &ett_vnc_desktop_screen,
4535 &ett_vnc_colormap_color_group,
4536 &ett_vnc_key_events,
4537 &ett_vnc_touch_events,
4538 &ett_vnc_slrle_subline
4541 static ei_register_info ei[] = {
4542 { &ei_vnc_possible_gtk_vnc_bug, { "vnc.possible_gtk_vnc_bug", PI_MALFORMED, PI_ERROR, "client -> server greeting must be 12 bytes (possible gtk-vnc bug)", EXPFILL }},
4543 { &ei_vnc_auth_code_mismatch, { "vnc.auth_code_mismatch", PI_PROTOCOL, PI_WARN, "Authentication code does not match vendor or signature", EXPFILL }},
4544 { &ei_vnc_unknown_tight_vnc_auth, { "vnc.unknown_tight_vnc_auth", PI_PROTOCOL, PI_ERROR, "Unknown TIGHT VNC authentication", EXPFILL }},
4545 { &ei_vnc_too_many_rectangles, { "vnc.too_many_rectangles", PI_MALFORMED, PI_ERROR, "Too many rectangles, aborting dissection", EXPFILL }},
4546 { &ei_vnc_too_many_sub_rectangles, { "vnc.too_many_sub_rectangles", PI_MALFORMED, PI_ERROR, "Too many sub-rectangles, aborting dissection", EXPFILL }},
4547 { &ei_vnc_invalid_encoding, { "vnc.invalid_encoding", PI_MALFORMED, PI_ERROR, "Invalid encoding", EXPFILL }},
4548 { &ei_vnc_too_many_colors, { "vnc.too_many_colors", PI_MALFORMED, PI_ERROR, "Too many colors, aborting dissection", EXPFILL }},
4549 { &ei_vnc_too_many_cut_text, { "vnc.too_many_cut_text", PI_MALFORMED, PI_ERROR, "Too much cut text, aborting dissection", EXPFILL }},
4552 /* Register the protocol name and description */
4553 proto_vnc = proto_register_protocol("Virtual Network Computing",
4554 "VNC", "vnc");
4556 /* Required function calls to register the header fields and subtrees */
4557 proto_register_field_array(proto_vnc, hf, array_length(hf));
4558 proto_register_subtree_array(ett, array_length(ett));
4559 expert_vnc = expert_register_protocol(proto_vnc);
4560 expert_register_field_array(expert_vnc, ei, array_length(ei));
4562 /* Register our preferences module */
4563 vnc_module = prefs_register_protocol(proto_vnc, proto_reg_handoff_vnc);
4565 prefs_register_bool_preference(vnc_module, "desegment",
4566 "Reassemble VNC messages spanning multiple TCP segments.",
4567 "Whether the VNC dissector should reassemble messages spanning "
4568 "multiple TCP segments. To use this option, you must also enable "
4569 "\"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
4570 &vnc_preference_desegment);
4572 prefs_register_uint_preference(vnc_module, "alternate_port", "Alternate TCP port",
4573 "Decode this port's traffic as VNC in addition to the default ports (5500, 5501, 5900, 5901)",
4574 10, &vnc_preference_alternate_port);
4578 void
4579 proto_reg_handoff_vnc(void)
4581 static gboolean inited = FALSE;
4583 /* This is a behind the scenes variable that is not changed by the user.
4584 * This stores last setting of the vnc_preference_alternate_port. Used to keep
4585 * track of when the user has changed the setting so that we can delete
4586 * and re-register with the new port number. */
4587 static guint vnc_preference_alternate_port_last = 0;
4589 if(!inited) {
4590 vnc_handle = create_dissector_handle(dissect_vnc, proto_vnc);
4592 dissector_add_uint("tcp.port", 5500, vnc_handle);
4593 dissector_add_uint("tcp.port", 5501, vnc_handle);
4594 dissector_add_uint("tcp.port", 5900, vnc_handle);
4595 dissector_add_uint("tcp.port", 5901, vnc_handle);
4597 heur_dissector_add("tcp", test_vnc_protocol, proto_vnc);
4598 /* We don't register a port for the VNC HTTP server because
4599 * that simply provides a java program for download via the
4600 * HTTP protocol. The java program then connects to a standard
4601 * VNC port. */
4603 inited = TRUE;
4604 } else { /* only after preferences have been read/changed */
4605 if(vnc_preference_alternate_port != vnc_preference_alternate_port_last &&
4606 vnc_preference_alternate_port != 5500 &&
4607 vnc_preference_alternate_port != 5501 &&
4608 vnc_preference_alternate_port != 5900 &&
4609 vnc_preference_alternate_port != 5901) {
4610 if (vnc_preference_alternate_port_last != 0) {
4611 dissector_delete_uint("tcp.port",
4612 vnc_preference_alternate_port_last,
4613 vnc_handle);
4615 /* Save this setting to see if has changed later */
4616 vnc_preference_alternate_port_last =
4617 vnc_preference_alternate_port;
4619 /* Register the new port setting */
4620 if (vnc_preference_alternate_port != 0) {
4621 dissector_add_uint("tcp.port",
4622 vnc_preference_alternate_port,
4623 vnc_handle);