1 /* packet-x11.c
2 * Routines for X11 dissection
3 * Copyright 2000, Christophe Tronche <ch.tronche@computer.org>
4 * Copyright 2003, Michael Shuldman
5 *
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13 /* TODO (in no particular order):
14 *
15 * - keep track of Atom creation by server to be able to display
16 * non-predefined atoms
17 * - Idem for keysym <-> keycode ???
18 * - Idem for fonts
19 * - Subtree the request ids (that is x11.create-window.window and
20 * x11.change-window.window should be distinct), and add hidden fields
21 * (so we still have x11.window).
22 * - add hidden fields so we can have x11.circulate-window in addition to
23 * x11.opcode == 13 (but you could match on x11.opcode == "CirculateWindow"
24 * now)
25 * - add hidden fields so we have x11.listOfStuff.length
26 * - use a faster scheme that linear list searching for the opcode.
27 * - correct display of Unicode chars.
28 * - Not everything is homogeneous, in particular the handling of items in
29 * list is a total mess.
30 */
31
32 /* By the way, I wrote a program to generate every request and test
33 * that stuff. If you're interested, you can get it at
34 * http://tronche.com/gui/x/
35 */
36
37 #include "config.h"
38
39
40 #include <epan/packet.h>
41 #include <epan/exceptions.h>
42 #include <epan/conversation.h>
43 #include <epan/expert.h>
44 #include <epan/show_exception.h>
45 #include <epan/prefs.h>
46
47 #include "packet-x11-keysymdef.h"
48 #include "packet-x11.h"
49
50 #include <wsutil/bits_count_ones.h>
51
52 void proto_register_x11(void);
53 void proto_reg_handoff_x11(void);
54
55 #define cVALS(x) (const value_string*)(x)
56
57
58 /*
59 * Data structure associated with a conversation; keeps track of the
60 * request for which we're expecting a reply, the frame number of
61 * the initial connection request, and the byte order of the connection.
62 *
63 * An opcode of -3 means we haven't yet seen any requests yet.
64 * An opcode of -2 means we're not expecting a reply (unused).
65 * An opcode of -1 means we're waiting for a reply to the initial
66 * connection request.
67 * An opcode of 0 means the request was not seen (or unknown).
68 * Other values are the opcode of the request for which we're expecting
69 * a reply.
70 *
71 */
72 #define NOTHING_SEEN -3
73 #define NOTHING_EXPECTED -2
74 #define INITIAL_CONN -1
75 #define UNKNOWN_OPCODE 0
76
77 #define MAX_OPCODES (255 + 1) /* 255 + INITIAL_CONN */
78 #define LastExtensionError 255
79 #define LastExtensionEvent 127
80
81 #define BYTE_ORDER_UNKNOWN 0xFFFFFFFF
82
83 static const char *modifiers[] = {
84 "Shift",
85 "Lock",
86 "Control",
87 "Mod1",
88 "Mod2",
89 "Mod3",
90 "Mod4",
91 "Mod5"
92 };
93
94 /* Keymasks. From <X11/X.h>. */
95 #define ShiftMask (1<<0)
96 #define LockMask (1<<1)
97 #define ControlMask (1<<2)
98 #define Mod1Mask (1<<3)
99 #define Mod2Mask (1<<4)
100 #define Mod3Mask (1<<5)
101 #define Mod4Mask (1<<6)
102 #define Mod5Mask (1<<7)
103
104 static const int modifiermask[] = { ShiftMask, LockMask, ControlMask,
105 Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask };
106
107 /* from <X11/X.h> */
108 #define NoSymbol 0L /* special KeySym */
109
110 typedef struct _x11_conv_data {
111 wmem_map_t *seqtable; /* hashtable of sequencenumber <-> opcode. */
112 wmem_map_t *valtable; /* hashtable of sequencenumber <-> &opcode_vals */
113 /* major opcodes including extensions (NULL terminated) */
114 value_string opcode_vals[MAX_OPCODES+1];
115 /* error codes including extensions (NULL terminated) */
116 value_string errorcode_vals[LastExtensionError + 2];
117 /* event codes including extensions (NULL terminated) */
118 value_string eventcode_vals[LastExtensionEvent + 2];
119 wmem_map_t *eventcode_funcs; /* hashtable of eventcode <-> dissect_event() */
120 wmem_map_t *reply_funcs; /* hashtable of opcode <-> dissect_reply() */
121
122 int sequencenumber; /* sequencenumber of current packet. */
123 guint32 iconn_frame; /* frame # of initial connection request */
124 guint32 iconn_reply; /* frame # of initial connection reply */
125 guint byte_order; /* byte order of connection */
126 gboolean resync; /* resynchronization of sequence number performed */
127
128 int *keycodemap[256]; /* keycode to keysymvalue map. */
129 int keysyms_per_keycode;
130 int first_keycode;
131 int *modifiermap[array_length(modifiers)];/* modifier to keycode.*/
132 int keycodes_per_modifier;
133
134 union {
135 struct {
136 int first_keycode;
137 } GetKeyboardMapping;
138 } request;
139 } x11_conv_data_t;
140
141 static wmem_map_t *extension_table; /* hashtable of extension name <-> dispatch function */
142 static wmem_map_t *event_table; /* hashtable of extension name <-> event info list */
143 static wmem_map_t *genevent_table; /* hashtable of extension name <-> generic event info list */
144 static wmem_map_t *error_table; /* hashtable of extension name <-> error list */
145 static wmem_map_t *reply_table; /* hashtable of extension name <-> reply list */
146
147 /* Initialize the protocol and registered fields */
148 static int proto_x11 = -1;
149
150 #include "x11-declarations.h"
151
152 /* Initialize the subtree pointers */
153 static gint ett_x11 = -1;
154 static gint ett_x11_color_flags = -1;
155 static gint ett_x11_list_of_arc = -1;
156 static gint ett_x11_arc = -1;
157 static gint ett_x11_list_of_atom = -1;
158 static gint ett_x11_list_of_card32 = -1;
159 static gint ett_x11_list_of_float = -1;
160 static gint ett_x11_list_of_double = -1;
161 static gint ett_x11_list_of_color_item = -1;
162 static gint ett_x11_color_item = -1;
163 static gint ett_x11_list_of_keycode = -1;
164 static gint ett_x11_list_of_keysyms = -1;
165 static gint ett_x11_keysym = -1;
166 static gint ett_x11_list_of_point = -1;
167 static gint ett_x11_point = -1;
168 static gint ett_x11_list_of_rectangle = -1;
169 static gint ett_x11_rectangle = -1;
170 static gint ett_x11_list_of_segment = -1;
171 static gint ett_x11_segment = -1;
172 static gint ett_x11_list_of_string8 = -1;
173 static gint ett_x11_list_of_text_item = -1;
174 static gint ett_x11_text_item = -1;
175 static gint ett_x11_gc_value_mask = -1; /* XXX - unused */
176 static gint ett_x11_event_mask = -1; /* XXX - unused */
177 static gint ett_x11_do_not_propagate_mask = -1; /* XXX - unused */
178 static gint ett_x11_set_of_key_mask = -1;
179 static gint ett_x11_pointer_event_mask = -1; /* XXX - unused */
180 static gint ett_x11_window_value_mask = -1; /* XXX - unused */
181 static gint ett_x11_configure_window_mask = -1; /* XXX - unused */
182 static gint ett_x11_keyboard_value_mask = -1; /* XXX - unused */
183 static gint ett_x11_same_screen_focus = -1;
184 static gint ett_x11_event = -1;
185 static gint ett_x11_list_of_pixmap_format = -1;
186 static gint ett_x11_pixmap_format = -1;
187 static gint ett_x11_list_of_screen = -1;
188 static gint ett_x11_screen = -1;
189 static gint ett_x11_list_of_depth_detail = -1;
190 static gint ett_x11_depth_detail = -1;
191 static gint ett_x11_list_of_visualtype= -1;
192 static gint ett_x11_visualtype= -1;
193
194 static expert_field ei_x11_invalid_format = EI_INIT;
195 static expert_field ei_x11_request_length = EI_INIT;
196 static expert_field ei_x11_keycode_value_out_of_range = EI_INIT;
197
198 /* desegmentation of X11 messages */
199 static gboolean x11_desegment = TRUE;
200
201 #define DEFAULT_X11_PORT_RANGE "6000-6063"
202
203 /*
204 * Round a length to a multiple of 4 bytes.
205 */
206 #define ROUND_LENGTH(n) ((((n) + 3)/4) * 4)
207
208 /************************************************************************
209 *** ***
210 *** E N U M T A B L E S D E F I N I T I O N S ***
211 *** ***
212 ************************************************************************/
213
214 static const value_string byte_order_vals[] = {
215 { 'B', "Big-endian" },
216 { 'l', "Little-endian" },
217 { 0, NULL }
218 };
219
220 static const value_string image_byte_order_vals[] = {
221 { 0, "LSBFirst" },
222 { 1, "MSBFirst" },
223 { 0, NULL }
224 };
225
226 static const value_string access_mode_vals[] = {
227 { 0, "Disable" },
228 { 1, "Enable" },
229 { 0, NULL }
230 };
231
232 static const value_string all_temporary_vals[] = {
233 { 0, "AllTemporary" },
234 { 0, NULL }
235 };
236
237 static const value_string alloc_vals[] = {
238 { 0, "None" },
239 { 1, "All" },
240 { 0, NULL }
241 };
242
243 static const value_string allow_events_mode_vals[] = {
244 { 0, "AsyncPointer" },
245 { 1, "SyncPointer" },
246 { 2, "ReplayPointer" },
247 { 3, "AsyncKeyboard" },
248 { 4, "SyncKeyboard" },
249 { 5, "ReplayKeyboard" },
250 { 6, "AsyncBoth" },
251 { 7, "SyncBoth" },
252 { 0, NULL }
253 };
254
255 static const value_string arc_mode_vals[] = {
256 { 0, "Chord" },
257 { 1, "PieSlice" },
258 { 0, NULL }
259 };
260
261 static const char *atom_predefined_interpretation[] = {
262 "<error>",
263 "PRIMARY",
264 "SECONDARY",
265 "ARC",
266 "ATOM",
267 "BITMAP",
268 "CARDINAL",
269 "COLORMAP",
270 "CURSOR",
271 "CUT_BUFFER0",
272 "CUT_BUFFER1",
273 "CUT_BUFFER2",
274 "CUT_BUFFER3",
275 "CUT_BUFFER4",
276 "CUT_BUFFER5",
277 "CUT_BUFFER6",
278 "CUT_BUFFER7",
279 "DRAWABLE",
280 "FONT",
281 "INTEGER",
282 "PIXMAP",
283 "POINT",
284 "RECTANGLE",
285 "RESOURCE_MANAGER",
286 "RGB_COLOR_MAP",
287 "RGB_BEST_MAP",
288 "RGB_BLUE_MAP",
289 "RGB_DEFAULT_MAP",
290 "RGB_GRAY_MAP",
291 "RGB_GREEN_MAP",
292 "RGB_RED_MAP",
293 "STRING",
294 "VISUALID",
295 "WINDOW",
296 "WM_COMMAND",
297 "WM_HINTS",
298 "WM_CLIENT_MACHINE",
299 "WM_ICON_NAME",
300 "WM_ICON_SIZE",
301 "WM_NAME",
302 "WM_NORMAL_HINTS",
303 "WM_SIZE_HINTS",
304 "WM_ZOOM_HINTS",
305 "MIN_SPACE",
306 "NORM_SPACE",
307 "MAX_SPACE",
308 "END_SPACE",
309 "SUPERSCRIPT_X",
310 "SUPERSCRIPT_Y",
311 "SUBSCRIPT_X",
312 "SUBSCRIPT_Y",
313 "UNDERLINE_POSITION",
314 "UNDERLINE_THICKNESS",
315 "STRIKEOUT_ASCENT",
316 "STRIKEOUT_DESCENT",
317 "ITALIC_ANGLE",
318 "X_HEIGHT",
319 "QUAD_WIDTH",
320 "WEIGHT",
321 "POINT_SIZE",
322 "RESOLUTION",
323 "COPYRIGHT",
324 "NOTICE",
325 "FONT_NAME",
326 "FAMILY_NAME",
327 "FULL_NAME",
328 "CAP_HEIGHT",
329 "WM_CLASS",
330 "WM_TRANSIENT_FOR",
331 };
332
333 static const value_string auto_repeat_mode_vals[] = {
334 { 0, "Off" },
335 { 1, "On" },
336 { 2, "Default" },
337 { 0, NULL }
338 };
339
340 static const value_string background_pixmap_vals[] = {
341 { 0, "None" },
342 { 1, "ParentRelative" },
343 { 0, NULL }
344 };
345
346 static const value_string backing_store_vals[] = {
347 { 0, "NotUseful" },
348 { 1, "WhenMapped" },
349 { 2, "Always" },
350 { 0, NULL }
351 };
352
353 static const value_string border_pixmap_vals[] = {
354 { 0, "CopyFromParent" },
355 { 0, NULL }
356 };
357
358 static const value_string button_vals[] = {
359 { 0x8000, "AnyButton" },
360 { 0, NULL }
361 };
362
363 static const value_string cap_style_vals[] = {
364 { 0, "NotLast" },
365 { 1, "Butt" },
366 { 2, "Round" },
367 { 3, "Projecting" },
368 { 0, NULL }
369 };
370
371 static const value_string class_vals[] = {
372 { 0, "Cursor" },
373 { 1, "Tile" },
374 { 2, "Stipple" },
375 { 0, NULL }
376 };
377
378 static const value_string close_down_mode_vals[] = {
379 { 0, "Destroy" },
380 { 1, "RetainPermanent" },
381 { 2, "RetainTemporary" },
382 { 0, NULL }
383 };
384
385 static const value_string colormap_state_vals[] = {
386 { 0, "Uninstalled" },
387 { 1, "Installed" },
388 { 0, NULL }
389 };
390
391 static const value_string coordinate_mode_vals[] = {
392 { 0, "Origin" },
393 { 1, "Previous" },
394 { 0, NULL }
395 };
396
397 static const value_string destination_vals[] = {
398 { 0, "PointerWindow" },
399 { 1, "InputFocus" },
400 { 0, NULL }
401 };
402
403 static const value_string direction_vals[] = {
404 { 0, "RaiseLowest" },
405 { 1, "LowerHighest" },
406 { 0, NULL }
407 };
408
409 static const value_string event_detail_vals[] = {
410 { 0, "Ancestor" },
411 { 1, "Virtual" },
412 { 2, "Inferior" },
413 { 3, "Nonlinear" },
414 { 4, "NonlinearVirtual" },
415 { 0, NULL }
416 };
417
418 #define FAMILY_INTERNET 0
419 #define FAMILY_DECNET 1
420 #define FAMILY_CHAOS 2
421
422 static const value_string family_vals[] = {
423 { FAMILY_INTERNET, "Internet" },
424 { FAMILY_DECNET, "DECnet" },
425 { FAMILY_CHAOS, "Chaos" },
426 { 0, NULL }
427 };
428
429 static const value_string fill_rule_vals[] = {
430 { 0, "EvenOdd" },
431 { 1, "Winding" },
432 { 0, NULL }
433 };
434
435 static const value_string fill_style_vals[] = {
436 { 0, "Solid" },
437 { 1, "Tiled" },
438 { 2, "Stippled" },
439 { 3, "OpaqueStippled" },
440 { 0, NULL }
441 };
442
443 static const value_string focus_detail_vals[] = {
444 { 0, "Ancestor" },
445 { 1, "Virtual" },
446 { 2, "Inferior" },
447 { 3, "Nonlinear" },
448 { 4, "NonlinearVirtual" },
449 { 5, "Pointer" },
450 { 6, "PointerRoot" },
451 { 7, "None" },
452 { 0, NULL }
453 };
454
455 static const value_string focus_mode_vals[] = {
456 { 0, "Normal" },
457 { 1, "Grab" },
458 { 2, "Ungrab" },
459 { 3, "WhileGrabbed" },
460 { 0, NULL }
461 };
462
463 static const value_string focus_vals[] = {
464 { 0, "None" },
465 { 1, "PointerRoot" },
466 { 0, NULL }
467 };
468
469 static const value_string function_vals[] = {
470 { 0, "Clear" },
471 { 1, "And" },
472 { 2, "AndReverse" },
473 { 3, "Copy" },
474 { 4, "AndInverted" },
475 { 5, "NoOp" },
476 { 6, "Xor" },
477 { 7, "Or" },
478 { 8, "Nor" },
479 { 9, "Equiv" },
480 { 10, "Invert" },
481 { 11, "OrReverse" },
482 { 12, "CopyInverted" },
483 { 13, "OrInverted" },
484 { 14, "Nand" },
485 { 15, "Set" },
486 { 0, NULL }
487 };
488
489 static const value_string grab_mode_vals[] = {
490 { 0, "Normal" },
491 { 1, "Grab" },
492 { 2, "Ungrab" },
493 { 0, NULL }
494 };
495
496 static const value_string grab_status_vals[] = {
497 { 0, "Success" },
498 { 1, "AlreadyGrabbed" },
499 { 2, "InvalidTime" },
500 { 3, "NotViewable" },
501 { 4, "Frozen" },
502 { 0, NULL }
503 };
504
505 static const value_string bit_gravity_vals[] = {
506 { 0, "Forget" },
507 { 1, "NorthWest" },
508 { 2, "North" },
509 { 3, "NorthEast" },
510 { 4, "West" },
511 { 5, "Center" },
512 { 6, "East" },
513 { 7, "SouthWest" },
514 { 8, "South" },
515 { 9, "SouthEast" },
516 { 10, "Static" },
517 { 0, NULL }
518 };
519
520 static const value_string win_gravity_vals[] = {
521 { 0, "Unmap" },
522 { 1, "NorthWest" },
523 { 2, "North" },
524 { 3, "NorthEast" },
525 { 4, "West" },
526 { 5, "Center" },
527 { 6, "East" },
528 { 7, "SouthWest" },
529 { 8, "South" },
530 { 9, "SouthEast" },
531 { 10, "Static" },
532 { 0, NULL }
533 };
534
535 static const value_string image_format_vals[] = {
536 { 0, "Bitmap" },
537 { 1, "XYPixmap" },
538 { 2, "ZPixmap" },
539 { 0, NULL }
540 };
541
542 static const value_string image_pixmap_format_vals[] = {
543 { 1, "XYPixmap" },
544 { 2, "ZPixmap" },
545 { 0, NULL }
546 };
547
548 static const value_string join_style_vals[] = {
549 { 0, "Miter" },
550 { 1, "Round" },
551 { 2, "Bevel" },
552 { 0, NULL }
553 };
554
555 static const value_string key_vals[] = {
556 { 0, "AnyKey" },
557 { 0, NULL }
558 };
559
560 #include "x11-keysym.h"
561
562 static const value_string line_style_vals[] = {
563 { 0, "Solid" },
564 { 1, "OnOffDash" },
565 { 2, "DoubleDash" },
566 { 0, NULL }
567 };
568
569 static const value_string mode_vals[] = {
570 { 0, "Replace" },
571 { 1, "Prepend" },
572 { 2, "Append" },
573 { 0, NULL }
574 };
575
576 static const value_string on_off_vals[] = {
577 { 0, "Off" },
578 { 1, "On" },
579 { 0, NULL }
580 };
581
582 static const value_string place_vals[] = {
583 { 0, "Top" },
584 { 1, "Bottom" },
585 { 0, NULL }
586 };
587
588 static const value_string property_state_vals[] = {
589 { 0, "NewValue" },
590 { 1, "Deleted" },
591 { 0, NULL }
592 };
593
594 static const value_string visibility_state_vals[] = {
595 { 0, "Unobscured" },
596 { 1, "PartiallyObscured" },
597 { 2, "FullyObscured" },
598 { 0, NULL }
599 };
600
601 static const value_string mapping_request_vals[] = {
602 { 0, "MappingModifier" },
603 { 1, "MappingKeyboard" },
604 { 2, "MappingPointer" },
605 { 0, NULL }
606 };
607
608 /* Requestcodes. From <X11/Xproto.h>. */
609 #define X_CreateWindow 1
610 #define X_ChangeWindowAttributes 2
611 #define X_GetWindowAttributes 3
612 #define X_DestroyWindow 4
613 #define X_DestroySubwindows 5
614 #define X_ChangeSaveSet 6
615 #define X_ReparentWindow 7
616 #define X_MapWindow 8
617 #define X_MapSubwindows 9
618 #define X_UnmapWindow 10
619 #define X_UnmapSubwindows 11
620 #define X_ConfigureWindow 12
621 #define X_CirculateWindow 13
622 #define X_GetGeometry 14
623 #define X_QueryTree 15
624 #define X_InternAtom 16
625 #define X_GetAtomName 17
626 #define X_ChangeProperty 18
627 #define X_DeleteProperty 19
628 #define X_GetProperty 20
629 #define X_ListProperties 21
630 #define X_SetSelectionOwner 22
631 #define X_GetSelectionOwner 23
632 #define X_ConvertSelection 24
633 #define X_SendEvent 25
634 #define X_GrabPointer 26
635 #define X_UngrabPointer 27
636 #define X_GrabButton 28
637 #define X_UngrabButton 29
638 #define X_ChangeActivePointerGrab 30
639 #define X_GrabKeyboard 31
640 #define X_UngrabKeyboard 32
641 #define X_GrabKey 33
642 #define X_UngrabKey 34
643 #define X_AllowEvents 35
644 #define X_GrabServer 36
645 #define X_UngrabServer 37
646 #define X_QueryPointer 38
647 #define X_GetMotionEvents 39
648 #define X_TranslateCoords 40
649 #define X_WarpPointer 41
650 #define X_SetInputFocus 42
651 #define X_GetInputFocus 43
652 #define X_QueryKeymap 44
653 #define X_OpenFont 45
654 #define X_CloseFont 46
655 #define X_QueryFont 47
656 #define X_QueryTextExtents 48
657 #define X_ListFonts 49
658 #define X_ListFontsWithInfo 50
659 #define X_SetFontPath 51
660 #define X_GetFontPath 52
661 #define X_CreatePixmap 53
662 #define X_FreePixmap 54
663 #define X_CreateGC 55
664 #define X_ChangeGC 56
665 #define X_CopyGC 57
666 #define X_SetDashes 58
667 #define X_SetClipRectangles 59
668 #define X_FreeGC 60
669 #define X_ClearArea 61
670 #define X_CopyArea 62
671 #define X_CopyPlane 63
672 #define X_PolyPoint 64
673 #define X_PolyLine 65
674 #define X_PolySegment 66
675 #define X_PolyRectangle 67
676 #define X_PolyArc 68
677 #define X_FillPoly 69
678 #define X_PolyFillRectangle 70
679 #define X_PolyFillArc 71
680 #define X_PutImage 72
681 #define X_GetImage 73
682 #define X_PolyText8 74
683 #define X_PolyText16 75
684 #define X_ImageText8 76
685 #define X_ImageText16 77
686 #define X_CreateColormap 78
687 #define X_FreeColormap 79
688 #define X_CopyColormapAndFree 80
689 #define X_InstallColormap 81
690 #define X_UninstallColormap 82
691 #define X_ListInstalledColormaps 83
692 #define X_AllocColor 84
693 #define X_AllocNamedColor 85
694 #define X_AllocColorCells 86
695 #define X_AllocColorPlanes 87
696 #define X_FreeColors 88
697 #define X_StoreColors 89
698 #define X_StoreNamedColor 90
699 #define X_QueryColors 91
700 #define X_LookupColor 92
701 #define X_CreateCursor 93
702 #define X_CreateGlyphCursor 94
703 #define X_FreeCursor 95
704 #define X_RecolorCursor 96
705 #define X_QueryBestSize 97
706 #define X_QueryExtension 98
707 #define X_ListExtensions 99
708 #define X_ChangeKeyboardMapping 100
709 #define X_GetKeyboardMapping 101
710 #define X_ChangeKeyboardControl 102
711 #define X_GetKeyboardControl 103
712 #define X_Bell 104
713 #define X_ChangePointerControl 105
714 #define X_GetPointerControl 106
715 #define X_SetScreenSaver 107
716 #define X_GetScreenSaver 108
717 #define X_ChangeHosts 109
718 #define X_ListHosts 110
719 #define X_SetAccessControl 111
720 #define X_SetCloseDownMode 112
721 #define X_KillClient 113
722 #define X_RotateProperties 114
723 #define X_ForceScreenSaver 115
724 #define X_SetPointerMapping 116
725 #define X_GetPointerMapping 117
726 #define X_SetModifierMapping 118
727 #define X_GetModifierMapping 119
728 #define X_NoOperation 127
729 #define X_FirstExtension 128
730 #define X_LastExtension 255
731
732 static const value_string opcode_vals[] = {
733 { INITIAL_CONN, "Initial connection request" },
734 { X_CreateWindow, "CreateWindow" },
735 { X_ChangeWindowAttributes, "ChangeWindowAttributes" },
736 { X_GetWindowAttributes, "GetWindowAttributes" },
737 { X_DestroyWindow, "DestroyWindow" },
738 { X_DestroySubwindows, "DestroySubwindows" },
739 { X_ChangeSaveSet, "ChangeSaveSet" },
740 { X_ReparentWindow, "ReparentWindow" },
741 { X_MapWindow, "MapWindow" },
742 { X_MapSubwindows, "MapSubwindows" },
743 { X_UnmapWindow, "UnmapWindow" },
744 { X_UnmapSubwindows, "UnmapSubwindows" },
745 { X_ConfigureWindow, "ConfigureWindow" },
746 { X_CirculateWindow, "CirculateWindow" },
747 { X_GetGeometry, "GetGeometry" },
748 { X_QueryTree, "QueryTree" },
749 { X_InternAtom, "InternAtom" },
750 { X_GetAtomName, "GetAtomName" },
751 { X_ChangeProperty, "ChangeProperty" },
752 { X_DeleteProperty, "DeleteProperty" },
753 { X_GetProperty, "GetProperty" },
754 { X_ListProperties, "ListProperties" },
755 { X_SetSelectionOwner, "SetSelectionOwner" },
756 { X_GetSelectionOwner, "GetSelectionOwner" },
757 { X_ConvertSelection, "ConvertSelection" },
758 { X_SendEvent, "SendEvent" },
759 { X_GrabPointer, "GrabPointer" },
760 { X_UngrabPointer, "UngrabPointer" },
761 { X_GrabButton, "GrabButton" },
762 { X_UngrabButton, "UngrabButton" },
763 { X_ChangeActivePointerGrab, "ChangeActivePointerGrab" },
764 { X_GrabKeyboard, "GrabKeyboard" },
765 { X_UngrabKeyboard, "UngrabKeyboard" },
766 { X_GrabKey, "GrabKey" },
767 { X_UngrabKey, "UngrabKey" },
768 { X_AllowEvents, "AllowEvents" },
769 { X_GrabServer, "GrabServer" },
770 { X_UngrabServer, "UngrabServer" },
771 { X_QueryPointer, "QueryPointer" },
772 { X_GetMotionEvents, "GetMotionEvents" },
773 { X_TranslateCoords, "TranslateCoordinates" },
774 { X_WarpPointer, "WarpPointer" },
775 { X_SetInputFocus, "SetInputFocus" },
776 { X_GetInputFocus, "GetInputFocus" },
777 { X_QueryKeymap, "QueryKeymap" },
778 { X_OpenFont, "OpenFont" },
779 { X_CloseFont, "CloseFont" },
780 { X_QueryFont, "QueryFont" },
781 { X_QueryTextExtents, "QueryTextExtents" },
782 { X_ListFonts, "ListFonts" },
783 { X_ListFontsWithInfo, "ListFontsWithInfo" },
784 { X_SetFontPath, "SetFontPath" },
785 { X_GetFontPath, "GetFontPath" },
786 { X_CreatePixmap, "CreatePixmap" },
787 { X_FreePixmap, "FreePixmap" },
788 { X_CreateGC, "CreateGC" },
789 { X_ChangeGC, "ChangeGC" },
790 { X_CopyGC, "CopyGC" },
791 { X_SetDashes, "SetDashes" },
792 { X_SetClipRectangles, "SetClipRectangles" },
793 { X_FreeGC, "FreeGC" },
794 { X_ClearArea, "ClearArea" },
795 { X_CopyArea, "CopyArea" },
796 { X_CopyPlane, "CopyPlane" },
797 { X_PolyPoint, "PolyPoint" },
798 { X_PolyLine, "PolyLine" },
799 { X_PolySegment, "PolySegment" },
800 { X_PolyRectangle, "PolyRectangle" },
801 { X_PolyArc, "PolyArc" },
802 { X_FillPoly, "FillPoly" },
803 { X_PolyFillRectangle, "PolyFillRectangle" },
804 { X_PolyFillArc, "PolyFillArc" },
805 { X_PutImage, "PutImage" },
806 { X_GetImage, "GetImage" },
807 { X_PolyText8, "PolyText8" },
808 { X_PolyText16, "PolyText16" },
809 { X_ImageText8, "ImageText8" },
810 { X_ImageText16, "ImageText16" },
811 { X_CreateColormap, "CreateColormap" },
812 { X_FreeColormap, "FreeColormap" },
813 { X_CopyColormapAndFree, "CopyColormapAndFree" },
814 { X_InstallColormap, "InstallColormap" },
815 { X_UninstallColormap, "UninstallColormap" },
816 { X_ListInstalledColormaps, "ListInstalledColormaps" },
817 { X_AllocColor, "AllocColor" },
818 { X_AllocNamedColor, "AllocNamedColor" },
819 { X_AllocColorCells, "AllocColorCells" },
820 { X_AllocColorPlanes, "AllocColorPlanes" },
821 { X_FreeColors, "FreeColors" },
822 { X_StoreColors, "StoreColors" },
823 { X_StoreNamedColor, "StoreNamedColor" },
824 { X_QueryColors, "QueryColors" },
825 { X_LookupColor, "LookupColor" },
826 { X_CreateCursor, "CreateCursor" },
827 { X_CreateGlyphCursor, "CreateGlyphCursor" },
828 { X_FreeCursor, "FreeCursor" },
829 { X_RecolorCursor, "RecolorCursor" },
830 { X_QueryBestSize, "QueryBestSize" },
831 { X_QueryExtension, "QueryExtension" },
832 { X_ListExtensions, "ListExtensions" },
833 { X_ChangeKeyboardMapping, "ChangeKeyboardMapping" },
834 { X_GetKeyboardMapping, "GetKeyboardMapping" },
835 { X_ChangeKeyboardControl, "ChangeKeyboardControl" },
836 { X_GetKeyboardControl, "GetKeyboardControl" },
837 { X_Bell, "Bell" },
838 { X_ChangePointerControl, "ChangePointerControl" },
839 { X_GetPointerControl, "GetPointerControl" },
840 { X_SetScreenSaver, "SetScreenSaver" },
841 { X_GetScreenSaver, "GetScreenSaver" },
842 { X_ChangeHosts, "ChangeHosts" },
843 { X_ListHosts, "ListHosts" },
844 { X_SetAccessControl, "SetAccessControl" },
845 { X_SetCloseDownMode, "SetCloseDownMode" },
846 { X_KillClient, "KillClient" },
847 { X_RotateProperties, "RotateProperties" },
848 { X_ForceScreenSaver, "ForceScreenSaver" },
849 { X_SetPointerMapping, "SetPointerMapping" },
850 { X_GetPointerMapping, "GetPointerMapping" },
851 { X_SetModifierMapping, "SetModifierMapping" },
852 { X_GetModifierMapping, "GetModifierMapping" },
853 { X_NoOperation, "NoOperation" },
854 { 0, NULL }
855 };
856
857 /* Eventscodes. From <X11/X.h>. */
858 #define KeyPress 2
859 #define KeyRelease 3
860 #define ButtonPress 4
861 #define ButtonRelease 5
862 #define MotionNotify 6
863 #define EnterNotify 7
864 #define LeaveNotify 8
865 #define FocusIn 9
866 #define FocusOut 10
867 #define KeymapNotify 11
868 #define Expose 12
869 #define GraphicsExpose 13
870 #define NoExpose 14
871 #define VisibilityNotify 15
872 #define CreateNotify 16
873 #define DestroyNotify 17
874 #define UnmapNotify 18
875 #define MapNotify 19
876 #define MapRequest 20
877 #define ReparentNotify 21
878 #define ConfigureNotify 22
879 #define ConfigureRequest 23
880 #define GravityNotify 24
881 #define ResizeRequest 25
882 #define CirculateNotify 26
883 #define CirculateRequest 27
884 #define PropertyNotify 28
885 #define SelectionClear 29
886 #define SelectionRequest 30
887 #define SelectionNotify 31
888 #define ColormapNotify 32
889 #define ClientMessage 33
890 #define MappingNotify 34
891 #define GenericEvent 35
892
893 static const value_string eventcode_vals[] = {
894 { KeyPress, "KeyPress" },
895 { KeyRelease, "KeyRelease" },
896 { ButtonPress, "ButtonPress" },
897 { ButtonRelease, "ButtonRelease" },
898 { MotionNotify, "MotionNotify" },
899 { EnterNotify, "EnterNotify" },
900 { LeaveNotify, "LeaveNotify" },
901 { FocusIn, "FocusIn" },
902 { FocusOut, "FocusOut" },
903 { KeymapNotify, "KeymapNotify" },
904 { Expose, "Expose" },
905 { GraphicsExpose, "GraphicsExpose" },
906 { NoExpose, "NoExpose" },
907 { VisibilityNotify, "VisibilityNotify" },
908 { CreateNotify, "CreateNotify" },
909 { DestroyNotify, "DestroyNotify" },
910 { UnmapNotify, "UnmapNotify" },
911 { MapNotify, "MapNotify" },
912 { MapRequest, "MapRequest" },
913 { ReparentNotify, "ReparentNotify" },
914 { ConfigureNotify, "ConfigureNotify" },
915 { ConfigureRequest, "ConfigureRequest" },
916 { GravityNotify, "GravityNotify" },
917 { ResizeRequest, "ResizeRequest" },
918 { CirculateNotify, "CirculateNotify" },
919 { CirculateRequest, "CirculateRequest" },
920 { PropertyNotify, "PropertyNotify" },
921 { SelectionClear, "SelectionClear" },
922 { SelectionRequest, "SelectionRequest" },
923 { SelectionNotify, "SelectionNotify" },
924 { ColormapNotify, "ColormapNotify" },
925 { ClientMessage, "ClientMessage" },
926 { MappingNotify, "MappingNotify" },
927 { GenericEvent, "GenericEvent" },
928 { 0, NULL }
929 };
930
931 /* Errorcodes. From <X11/X.h> */
932 #define Success 0 /* everything's okay */
933 #define BadRequest 1 /* bad request code */
934 #define BadValue 2 /* int parameter out of range */
935 #define BadWindow 3 /* parameter not a Window */
936 #define BadPixmap 4 /* parameter not a Pixmap */
937 #define BadAtom 5 /* parameter not an Atom */
938 #define BadCursor 6 /* parameter not a Cursor */
939 #define BadFont 7 /* parameter not a Font */
940 #define BadMatch 8 /* parameter mismatch */
941 #define BadDrawable 9 /* parameter not a Pixmap or Window */
942 #define BadAccess 10 /* depending on context:
943 - key/button already grabbed
944 - attempt to free an illegal
945 cmap entry
946 - attempt to store into a read-only
947 color map entry.
948 - attempt to modify the access control
949 list from other than the local host.
950 */
951 #define BadAlloc 11 /* insufficient resources */
952 #define BadColormap 12 /* no such colormap */
953 #define BadGC 13 /* parameter not a GC */
954 #define BadIDChoice 14 /* choice not in range or already used */
955 #define BadName 15 /* font or color name doesn't exist */
956 #define BadLength 16 /* Request length incorrect */
957 #define BadImplementation 17 /* server is defective */
958
959 static const value_string errorcode_vals[] = {
960 { Success, "Success" },
961 { BadRequest, "BadRequest" },
962 { BadValue, "BadValue" },
963 { BadWindow, "BadWindow" },
964 { BadPixmap, "BadPixmap" },
965 { BadAtom, "BadAtom" },
966 { BadCursor, "BadCursor" },
967 { BadFont, "BadFont" },
968 { BadMatch, "BadMatch" },
969 { BadDrawable, "BadDrawable" },
970 { BadAccess, "BadAccess" },
971 { BadAlloc, "BadAlloc" },
972 { BadColormap, "BadColormap" },
973 { BadGC, "BadGC" },
974 { BadIDChoice, "BadIDChoice" },
975 { BadName, "BadName" },
976 { BadLength, "BadLength" },
977 { BadImplementation, "BadImplementation" },
978 { 0, NULL }
979 };
980
981 static const value_string ordering_vals[] = {
982 { 0, "UnSorted" },
983 { 1, "YSorted" },
984 { 2, "YXSorted" },
985 { 3, "YXBanded" },
986 { 0, NULL }
987 };
988
989 static const value_string plane_mask_vals[] = {
990 { 0xFFFFFFFF, "AllPlanes" },
991 { 0, NULL }
992 };
993
994 static const value_string pointer_keyboard_mode_vals[] = {
995 { 0, "Synchronous" },
996 { 1, "Asynchronous" },
997 { 0, NULL }
998 };
999
1000 static const value_string revert_to_vals[] = {
1001 { 0, "None" },
1002 { 1, "PointerRoot" },
1003 { 2, "Parent" },
1004 { 0, NULL }
1005 };
1006
1007 static const value_string insert_delete_vals[] = {
1008 { 0, "Insert" },
1009 { 1, "Delete" },
1010 { 0, NULL }
1011 };
1012
1013 static const value_string screen_saver_mode_vals[] = {
1014 { 0, "Reset" },
1015 { 1, "Activate" },
1016 { 0, NULL }
1017 };
1018
1019 static const value_string shape_vals[] = {
1020 { 0, "Complex" },
1021 { 1, "Nonconvex" },
1022 { 2, "Convex" },
1023 { 0, NULL }
1024 };
1025
1026 static const value_string stack_mode_vals[] = {
1027 { 0, "Above" },
1028 { 1, "Below" },
1029 { 2, "TopIf" },
1030 { 3, "BottomIf" },
1031 { 4, "Opposite" },
1032 { 0, NULL }
1033 };
1034
1035 static const value_string subwindow_mode_vals[] = {
1036 { 0, "ClipByChildren" },
1037 { 1, "IncludeInferiors" },
1038 { 0, NULL }
1039 };
1040
1041 static const value_string window_class_vals[] = {
1042 { 0, "CopyFromParent" },
1043 { 1, "InputOutput" },
1044 { 2, "InputOnly" },
1045 { 0, NULL }
1046 };
1047
1048 static const value_string yes_no_default_vals[] = {
1049 { 0, "No" },
1050 { 1, "Yes" },
1051 { 2, "Default" },
1052 { 0, NULL }
1053 };
1054
1055 static const value_string zero_is_any_property_type_vals[] = {
1056 { 0, "AnyPropertyType" },
1057 { 0, NULL }
1058 };
1059
1060 static const value_string zero_is_none_vals[] = {
1061 { 0, "None" },
1062 { 0, NULL }
1063 };
1064
1065 /************************************************************************
1066 *** ***
1067 *** F I E L D D E C O D I N G M A C R O S ***
1068 *** ***
1069 ************************************************************************/
1070 #define FIELD8(name) (field8(tvb, offsetp, t, hf_x11_##name, byte_order))
1071 #define FIELD16(name) (field16(tvb, offsetp, t, hf_x11_##name, byte_order))
1072 #define FIELD32(name) (field32(tvb, offsetp, t, hf_x11_##name, byte_order))
1073
1074 #define FLAG(position, name) {\
1075 proto_tree_add_boolean(bitmask_tree, hf_x11_##position##_mask##_##name, tvb, bitmask_offset, bitmask_size, bitmask_value); }
1076
1077 #define FLAG_IF_NONZERO(position, name) do {\
1078 if (bitmask_value & proto_registrar_get_nth(hf_x11_##position##_mask##_##name) -> bitmask) \
1079 proto_tree_add_boolean(bitmask_tree, hf_x11_##position##_mask##_##name, tvb, bitmask_offset, bitmask_size, bitmask_value); } while (0)
1080
1081 #define ATOM(name) { atom(tvb, offsetp, t, hf_x11_##name, byte_order); }
1082 #define BOOL(name) (add_boolean(tvb, offsetp, t, hf_x11_##name))
1083 #define BUTTON(name) FIELD8(name)
1084 #define CARD8(name) FIELD8(name)
1085 #define CARD16(name) (FIELD16(name))
1086 #define CARD32(name) (FIELD32(name))
1087 #define COLOR_FLAGS(name) colorFlags(tvb, offsetp, t)
1088 #define COLORMAP(name) FIELD32(name)
1089 #define CURSOR(name) FIELD32(name)
1090 #define DRAWABLE(name) FIELD32(name)
1091 #define ENUM8(name) (FIELD8(name))
1092 #define ENUM16(name) (FIELD16(name))
1093 #define FONT(name) FIELD32(name)
1094 #define FONTABLE(name) FIELD32(name)
1095 #define GCONTEXT(name) FIELD32(name)
1096 #define INT8(name) FIELD8(name)
1097 #define INT16(name) FIELD16(name)
1098 #define INT32(name) FIELD32(name)
1099 #define KEYCODE(name) FIELD8(name)
1100 #define KEYCODE_DECODED(name, keycode, mask) do { \
1101 proto_tree_add_uint_format(t, hf_x11_##name, tvb, offset, 1, \
1102 keycode, "keycode: %d (%s)", \
1103 keycode, keycode2keysymString(state->keycodemap, \
1104 state->first_keycode, state->keysyms_per_keycode, \
1105 state->modifiermap, state->keycodes_per_modifier, \
1106 keycode, mask)); \
1107 ++offset; \
1108 } while (0)
1109 #define EVENT() do { \
1110 tvbuff_t *next_tvb; \
1111 unsigned char eventcode; \
1112 const char *sent; \
1113 proto_tree *event_proto_tree; \
1114 next_tvb = tvb_new_subset_length_caplen(tvb, offset, next_offset - offset, \
1115 next_offset - offset); \
1116 eventcode = tvb_get_guint8(next_tvb, 0); \
1117 sent = (eventcode & 0x80) ? "Sent-" : ""; \
1118 event_proto_tree = proto_tree_add_subtree_format(t, next_tvb, \
1119 0, -1, ett_x11_event, NULL, \
1120 "event: %d (%s)", \
1121 eventcode, \
1122 val_to_str(eventcode & 0x7F, \
1123 state->eventcode_vals, \
1124 "<Unknown eventcode %u>")); \
1125 decode_x11_event(next_tvb, eventcode, sent, event_proto_tree, \
1126 state, byte_order); \
1127 offset = next_offset; \
1128 } while (0)
1129
1130 #define LISTofARC(name) { listOfArc(tvb, offsetp, t, hf_x11_##name, (next_offset - *offsetp) / 12, byte_order); }
1131 #define LISTofATOM(name, length) { listOfAtom(tvb, offsetp, t, hf_x11_##name, (length) / 4, byte_order); }
1132 #define LISTofBYTE(name, length) { listOfByte(tvb, offsetp, t, hf_x11_##name, (length), byte_order); }
1133 #define LISTofCARD8(name, length) { listOfByte(tvb, offsetp, t, hf_x11_##name, (length), byte_order); }
1134 #define LISTofIPADDRESS(name, length) { listOfByte(tvb, offsetp, t, hf_x11_##name, (length), FALSE); }
1135 #define LISTofCARD16(name, length) { listOfCard16(tvb, offsetp, t, hf_x11_##name, hf_x11_##name##_item, (length) / 2, byte_order); }
1136 #define LISTofCARD32(name, length) { listOfCard32(tvb, offsetp, t, hf_x11_##name, hf_x11_##name##_item, (length) / 4, byte_order); }
1137 #define LISTofCOLORITEM(name, length) { listOfColorItem(tvb, offsetp, t, hf_x11_##name, (length) / 12, byte_order); }
1138 #define LISTofKEYCODE(map, name, length) { listOfKeycode(tvb, offsetp, t, hf_x11_##name, map, (length), byte_order); }
1139 #define LISTofKEYSYM(name, map, keycode_first, keycode_count, \
1140 keysyms_per_keycode) {\
1141 listOfKeysyms(tvb, pinfo, offsetp, t, hf_x11_##name, hf_x11_##name##_item, map, (keycode_first), (keycode_count), (keysyms_per_keycode), byte_order); }
1142 #define LISTofPOINT(name, length) { listOfPoint(tvb, offsetp, t, hf_x11_##name, (length) / 4, byte_order); }
1143 #define LISTofRECTANGLE(name) { listOfRectangle(tvb, offsetp, t, hf_x11_##name, (next_offset - *offsetp) / 8, byte_order); }
1144 #define LISTofPIXMAPFORMAT(name, length) { listOfPixmapFormat(tvb, offsetp, t, hf_x11_##name, (length), byte_order); }
1145 #define LISTofSCREEN(name, length) { listOfScreen(tvb, offsetp, t, hf_x11_##name, (length), byte_order); }
1146 #define LISTofSEGMENT(name) { listOfSegment(tvb, offsetp, t, hf_x11_##name, (next_offset - *offsetp) / 8, byte_order); }
1147 #define LISTofSTRING8(name, length) { listOfString8(tvb, offsetp, t, hf_x11_##name, hf_x11_##name##_string, (length), byte_order); }
1148 #define LISTofTEXTITEM8(name) { listOfTextItem(tvb, offsetp, t, hf_x11_##name, FALSE, next_offset, byte_order); }
1149 #define LISTofTEXTITEM16(name) { listOfTextItem(tvb, offsetp, t, hf_x11_##name, TRUE, next_offset, byte_order); }
1150 #define OPCODE() { \
1151 opcode = tvb_get_guint8(tvb, *offsetp); \
1152 proto_tree_add_uint(t, hf_x11_opcode, tvb, *offsetp, \
1153 1, opcode); \
1154 *offsetp += 1; \
1155 }
1156
1157 #define PIXMAP(name) { FIELD32(name); }
1158 #define REQUEST_LENGTH() (requestLength(tvb, offsetp, t, byte_order))
1159 #define SETofEVENT(name) { setOfEvent(tvb, offsetp, t, byte_order); }
1160 #define SETofDEVICEEVENT(name) { setOfDeviceEvent(tvb, offsetp, t, byte_order);}
1161 #define SETofKEYMASK(name) { setOfKeyButMask(tvb, offsetp, t, byte_order, 0); }
1162 #define SETofKEYBUTMASK(name) { setOfKeyButMask(tvb, offsetp, t, byte_order, 1); }
1163 #define SETofPOINTEREVENT(name) { setOfPointerEvent(tvb, offsetp, t, byte_order); }
1164 #define STRING8(name, length) { string8(tvb, offsetp, t, hf_x11_##name, length); }
1165 #define STRING16(name, length) { string16(tvb, offsetp, t, hf_x11_##name, hf_x11_##name##_bytes, length, byte_order); }
1166 #define TIMESTAMP(name){ timestamp(tvb, offsetp, t, hf_x11_##name, byte_order); }
1167 #define UNDECODED(x) { proto_tree_add_item(t, hf_x11_undecoded, tvb, *offsetp, x, ENC_NA); *offsetp += x; }
1168 #define PAD() { if (next_offset - *offsetp > 0) proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, next_offset - *offsetp, ENC_NA); *offsetp = next_offset; }
1169 #define WINDOW(name) { FIELD32(name); }
1170
1171 #define VISUALID(name) { gint32 v = tvb_get_guint32(tvb, *offsetp, byte_order); \
1172 proto_tree_add_uint_format(t, hf_x11_##name, tvb, *offsetp, 4, v, "Visualid: 0x%08x%s", v, \
1173 v ? "" : " (CopyFromParent)"); *offsetp += 4; }
1174 #define REPLY(name) FIELD8(name);
1175 #define REPLYLENGTH(name) FIELD32(name);
1176
1177 #define EVENTCONTENTS_COMMON() do { \
1178 TIMESTAMP(time); \
1179 WINDOW(rootwindow); \
1180 WINDOW(eventwindow); \
1181 WINDOW(childwindow); \
1182 INT16(root_x); \
1183 INT16(root_y); \
1184 INT16(event_x); \
1185 INT16(event_y); \
1186 setOfKeyButMask(tvb, offsetp, t, byte_order, 1); \
1187 } while (0)
1188
1189 #define SEQUENCENUMBER_REPLY(name) do { \
1190 guint16 seqno; \
1191 \
1192 seqno = tvb_get_guint16(tvb, *offsetp, byte_order); \
1193 proto_tree_add_uint_format(t, hf_x11_reply_##name, tvb, \
1194 *offsetp, 2, seqno, \
1195 "sequencenumber: %d (%s)", \
1196 (int)seqno, \
1197 val_to_str(opcode & 0xFF, state->opcode_vals, "<Unknown opcode %d>")); \
1198 *offsetp += 2; \
1199 } while (0)
1200
1201 #define REPLYCONTENTS_COMMON() do { \
1202 REPLY(reply); \
1203 proto_tree_add_item(t, hf_x11_undecoded, tvb, *offsetp, \
1204 1, ENC_NA); \
1205 ++(*offsetp); \
1206 SEQUENCENUMBER_REPLY(sequencenumber); \
1207 REPLYLENGTH(replylength); \
1208 proto_tree_add_item(t, hf_x11_undecoded, tvb, *offsetp, \
1209 tvb_reported_length_remaining(tvb, *offsetp), ENC_NA); \
1210 *offsetp += tvb_reported_length_remaining(tvb, *offsetp); \
1211 } while (0)
1212
1213
1214 #define HANDLE_REPLY(plen, length_remaining, str, func) do { \
1215 if (length_remaining < plen) { \
1216 if (x11_desegment && pinfo->can_desegment) { \
1217 pinfo->desegment_offset = offset; \
1218 pinfo->desegment_len = plen - length_remaining; \
1219 return; \
1220 } else { \
1221 ; /* XXX yes, what then? Need to skip/join. */ \
1222 } \
1223 } \
1224 if (length_remaining > plen) \
1225 length_remaining = plen; \
1226 next_tvb = tvb_new_subset_length_caplen(tvb, offset, length_remaining, plen); \
1227 \
1228 if (sep == NULL) { \
1229 col_set_str(pinfo->cinfo, COL_INFO, str); \
1230 sep = ":"; \
1231 } \
1232 \
1233 TRY { \
1234 func(next_tvb, pinfo, tree, sep, state, byte_order); \
1235 } \
1236 \
1237 CATCH_NONFATAL_ERRORS { \
1238 show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE); \
1239 } \
1240 ENDTRY; \
1241 \
1242 sep = ","; \
1243 } while (0)
1244
1245 static void
1246 dissect_x11_initial_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1247 const char *sep, x11_conv_data_t *state,
1248 guint byte_order);
1249
1250 static void
1251 dissect_x11_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1252 const char *sep, x11_conv_data_t *state,
1253 guint byte_order);
1254
1255 static void
1256 dissect_x11_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1257 const char *sep, x11_conv_data_t *state,
1258 guint byte_order);
1259
1260 static void
1261 dissect_x11_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1262 const char *sep, x11_conv_data_t *state,
1263 guint byte_order);
1264
1265 static void
1266 decode_x11_event(tvbuff_t *tvb, unsigned char eventcode, const char *sent,
1267 proto_tree *t, x11_conv_data_t *state,
1268 guint byte_order);
1269
1270 static x11_conv_data_t *
1271 x11_stateinit(conversation_t *conversation);
1272
1273 static const char *
1274 keysymString(guint32 v);
1275
1276
1277 /************************************************************************
1278 *** ***
1279 *** D E C O D I N G F I E L D S ***
1280 *** ***
1281 ************************************************************************/
1282
atom(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,guint byte_order)1283 static void atom(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1284 guint byte_order)
1285 {
1286 const char *interpretation = NULL;
1287
1288 guint32 v = tvb_get_guint32(tvb, *offsetp, byte_order);
1289 if (v >= 1 && v < array_length(atom_predefined_interpretation))
1290 interpretation = atom_predefined_interpretation[v];
1291 else if (v)
1292 interpretation = "Not a predefined atom";
1293 else {
1294 header_field_info *hfi = proto_registrar_get_nth(hf);
1295 if (hfi -> strings)
1296 interpretation = try_val_to_str(v, cVALS(hfi -> strings));
1297 }
1298 if (!interpretation) interpretation = "error in Xlib client program ?";
1299 proto_tree_add_uint_format(t, hf, tvb, *offsetp, 4, v, "%s: %u (%s)",
1300 proto_registrar_get_nth(hf) -> name, v, interpretation);
1301 *offsetp += 4;
1302 }
1303
add_boolean(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf)1304 static guint32 add_boolean(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf)
1305 {
1306 guint32 v = tvb_get_guint8(tvb, *offsetp);
1307 proto_tree_add_boolean(t, hf, tvb, *offsetp, 1, v);
1308 *offsetp += 1;
1309 return v;
1310 }
1311
colorFlags(tvbuff_t * tvb,int * offsetp,proto_tree * t)1312 static void colorFlags(tvbuff_t *tvb, int *offsetp, proto_tree *t)
1313 {
1314 guint do_red_green_blue = tvb_get_guint8(tvb, *offsetp);
1315 proto_item *ti;
1316 proto_tree *tt;
1317
1318 if (do_red_green_blue) {
1319 int sep = FALSE;
1320 wmem_strbuf_t *buffer = wmem_strbuf_new_label(wmem_packet_scope());
1321 wmem_strbuf_append(buffer, "flags: ");
1322
1323 if (do_red_green_blue & 0x1) {
1324 wmem_strbuf_append(buffer, "DoRed");
1325 sep = TRUE;
1326 }
1327
1328 if (do_red_green_blue & 0x2) {
1329 if (sep) wmem_strbuf_append(buffer, " | ");
1330 wmem_strbuf_append(buffer, "DoGreen");
1331 sep = TRUE;
1332 }
1333
1334 if (do_red_green_blue & 0x4) {
1335 if (sep) wmem_strbuf_append(buffer, " | ");
1336 wmem_strbuf_append(buffer, "DoBlue");
1337 sep = TRUE;
1338 }
1339
1340 if (do_red_green_blue & 0xf8) {
1341 if (sep) wmem_strbuf_append(buffer, " + trash");
1342 }
1343
1344 ti = proto_tree_add_uint_format(t, hf_x11_coloritem_flags, tvb, *offsetp, 1, do_red_green_blue,
1345 "%s", wmem_strbuf_get_str(buffer));
1346 tt = proto_item_add_subtree(ti, ett_x11_color_flags);
1347 if (do_red_green_blue & 0x1)
1348 proto_tree_add_boolean(tt, hf_x11_coloritem_flags_do_red, tvb, *offsetp, 1,
1349 do_red_green_blue & 0x1);
1350 if (do_red_green_blue & 0x2)
1351 proto_tree_add_boolean(tt, hf_x11_coloritem_flags_do_green, tvb, *offsetp, 1,
1352 do_red_green_blue & 0x2);
1353 if (do_red_green_blue & 0x4)
1354 proto_tree_add_boolean(tt, hf_x11_coloritem_flags_do_blue, tvb, *offsetp, 1,
1355 do_red_green_blue & 0x4);
1356 if (do_red_green_blue & 0xf8)
1357 proto_tree_add_boolean(tt, hf_x11_coloritem_flags_unused, tvb, *offsetp, 1,
1358 do_red_green_blue & 0xf8);
1359 } else
1360 proto_tree_add_uint_format(t, hf_x11_coloritem_flags, tvb, *offsetp, 1, do_red_green_blue,
1361 "flags: none");
1362 *offsetp += 1;
1363 }
1364
listOfArc(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int length,guint byte_order)1365 static void listOfArc(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1366 int length, guint byte_order)
1367 {
1368 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 8, byte_order);
1369 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_arc);
1370 while(length--) {
1371 gint16 x = tvb_get_guint16(tvb, *offsetp, byte_order);
1372 gint16 y = tvb_get_guint16(tvb, *offsetp + 2, byte_order);
1373 guint16 width = tvb_get_guint16(tvb, *offsetp + 4, byte_order);
1374 guint16 height = tvb_get_guint16(tvb, *offsetp + 6, byte_order);
1375 gint16 angle1 = tvb_get_guint16(tvb, *offsetp + 8, byte_order);
1376 gint16 angle2 = tvb_get_guint16(tvb, *offsetp + 10, byte_order);
1377
1378 proto_item *tti = proto_tree_add_none_format(tt, hf_x11_arc, tvb, *offsetp, 12,
1379 "arc: %dx%d+%d+%d, angle %d -> %d (%f degrees -> %f degrees)",
1380 width, height, x, y, angle1, angle2,
1381 angle1 / 64.0, angle2 / 64.0);
1382 proto_tree *ttt = proto_item_add_subtree(tti, ett_x11_arc);
1383 proto_tree_add_int(ttt, hf_x11_arc_x, tvb, *offsetp, 2, x);
1384 *offsetp += 2;
1385 proto_tree_add_int(ttt, hf_x11_arc_y, tvb, *offsetp, 2, y);
1386 *offsetp += 2;
1387 proto_tree_add_uint(ttt, hf_x11_arc_width, tvb, *offsetp, 2, y);
1388 *offsetp += 2;
1389 proto_tree_add_uint(ttt, hf_x11_arc_height, tvb, *offsetp, 2, y);
1390 *offsetp += 2;
1391 proto_tree_add_int(ttt, hf_x11_arc_angle1, tvb, *offsetp, 2, y);
1392 *offsetp += 2;
1393 proto_tree_add_int(ttt, hf_x11_arc_angle2, tvb, *offsetp, 2, y);
1394 *offsetp += 2;
1395 }
1396 }
1397
listOfAtom(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int length,guint byte_order)1398 static void listOfAtom(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1399 int length, guint byte_order)
1400 {
1401 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 4, byte_order);
1402 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_atom);
1403 while(length--)
1404 atom(tvb, offsetp, tt, hf_x11_properties_item, byte_order);
1405 }
1406
listOfByte(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int length,guint byte_order)1407 static void listOfByte(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1408 int length, guint byte_order)
1409 {
1410 if (length <= 0) length = 1;
1411 proto_tree_add_item(t, hf, tvb, *offsetp, length, byte_order);
1412 *offsetp += length;
1413 }
1414
listOfCard16(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int hf_item,int length,guint byte_order)1415 static void listOfCard16(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1416 int hf_item, int length, guint byte_order)
1417 {
1418 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 2, byte_order);
1419 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_card32);
1420 while(length--) {
1421 proto_tree_add_item(tt, hf_item, tvb, *offsetp, 2, byte_order);
1422 *offsetp += 2;
1423 }
1424 }
1425
listOfInt16(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int hf_item,int length,guint byte_order)1426 static void listOfInt16(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1427 int hf_item, int length, guint byte_order)
1428 {
1429 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 2, byte_order);
1430 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_card32);
1431 while(length--) {
1432 proto_tree_add_item(tt, hf_item, tvb, *offsetp, 2, byte_order);
1433 *offsetp += 2;
1434 }
1435 }
1436
listOfCard32(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int hf_item,int length,guint byte_order)1437 static void listOfCard32(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1438 int hf_item, int length, guint byte_order)
1439 {
1440 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 4, byte_order);
1441 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_card32);
1442 while(length--) {
1443 proto_tree_add_item(tt, hf_item, tvb, *offsetp, 4, byte_order);
1444 *offsetp += 4;
1445 }
1446 }
1447
listOfInt32(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int hf_item,int length,guint byte_order)1448 static void listOfInt32(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1449 int hf_item, int length, guint byte_order)
1450 {
1451 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 4, byte_order);
1452 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_card32);
1453 while(length--) {
1454 proto_tree_add_item(tt, hf_item, tvb, *offsetp, 4, byte_order);
1455 *offsetp += 4;
1456 }
1457 }
1458
listOfCard64(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int hf_item,int length,guint byte_order)1459 static void listOfCard64(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1460 int hf_item, int length, guint byte_order)
1461 {
1462 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 8, byte_order);
1463 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_card32);
1464 while(length--) {
1465 proto_tree_add_item(tt, hf_item, tvb, *offsetp, 8, byte_order);
1466 *offsetp += 8;
1467 }
1468 }
1469
1470 #if 0 /* Not yet used by any extension */
1471 static void listOfInt64(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1472 int hf_item, int length, guint byte_order)
1473 {
1474 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 8, byte_order);
1475 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_card32);
1476 while(length--) {
1477 proto_tree_add_item(tt, hf_item, tvb, *offsetp, 8, byte_order);
1478 *offsetp += 8;
1479 }
1480 }
1481 #endif
1482
listOfFloat(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int hf_item,int length,guint byte_order)1483 static void listOfFloat(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1484 int hf_item, int length, guint byte_order)
1485 {
1486 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 4, byte_order);
1487 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_float);
1488 while(length--) {
1489 proto_tree_add_item(tt, hf_item, tvb, *offsetp, 4, byte_order);
1490 *offsetp += 4;
1491 }
1492 }
1493
listOfDouble(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int hf_item,int length,guint byte_order)1494 static void listOfDouble(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1495 int hf_item, int length, guint byte_order)
1496 {
1497 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 8, byte_order);
1498 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_double);
1499 while(length--) {
1500 proto_tree_add_item(tt, hf_item, tvb, *offsetp, 8, byte_order);
1501 *offsetp += 8;
1502 }
1503 }
1504
listOfColorItem(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int length,guint byte_order)1505 static void listOfColorItem(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1506 int length, guint byte_order)
1507 {
1508 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 8, byte_order);
1509 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_color_item);
1510 while(length--) {
1511 proto_item *tti;
1512 proto_tree *ttt;
1513 guint do_red_green_blue;
1514 guint16 red, green, blue;
1515 wmem_strbuf_t *buffer;
1516 const char *sep;
1517
1518 buffer=wmem_strbuf_new_label(wmem_packet_scope());
1519 wmem_strbuf_append(buffer, "colorItem ");
1520 red = tvb_get_guint16(tvb, *offsetp + 4, byte_order);
1521 green = tvb_get_guint16(tvb, *offsetp + 6, byte_order);
1522 blue = tvb_get_guint16(tvb, *offsetp + 8, byte_order);
1523 do_red_green_blue = tvb_get_guint8(tvb, *offsetp + 10);
1524
1525 sep = "";
1526 if (do_red_green_blue & 0x1) {
1527 wmem_strbuf_append_printf(buffer, "red = %d", red);
1528 sep = ", ";
1529 }
1530 if (do_red_green_blue & 0x2) {
1531 wmem_strbuf_append_printf(buffer, "%sgreen = %d", sep, green);
1532 sep = ", ";
1533 }
1534 if (do_red_green_blue & 0x4)
1535 wmem_strbuf_append_printf(buffer, "%sblue = %d", sep, blue);
1536
1537 tti = proto_tree_add_none_format(tt, hf_x11_coloritem, tvb, *offsetp, 12, "%s", wmem_strbuf_get_str(buffer));
1538 ttt = proto_item_add_subtree(tti, ett_x11_color_item);
1539 proto_tree_add_item(ttt, hf_x11_coloritem_pixel, tvb, *offsetp, 4, byte_order);
1540 *offsetp += 4;
1541 proto_tree_add_item(ttt, hf_x11_coloritem_red, tvb, *offsetp, 2, byte_order);
1542 *offsetp += 2;
1543 proto_tree_add_item(ttt, hf_x11_coloritem_green, tvb, *offsetp, 2, byte_order);
1544 *offsetp += 2;
1545 proto_tree_add_item(ttt, hf_x11_coloritem_blue, tvb, *offsetp, 2, byte_order);
1546 *offsetp += 2;
1547 colorFlags(tvb, offsetp, ttt);
1548 proto_tree_add_item(ttt, hf_x11_coloritem_unused, tvb, *offsetp, 1, byte_order);
1549 *offsetp += 1;
1550 }
1551 }
1552
1553 #if 0 /* XXX: Use of GTree no longer needed; use value_string_ext */
1554 static gint compareGuint32(gconstpointer a, gconstpointer b)
1555 {
1556 return GPOINTER_TO_INT(b) - GPOINTER_TO_INT(a);
1557 }
1558 #endif
1559
1560 static void
XConvertCase(register int sym,int * lower,int * upper)1561 XConvertCase(register int sym, int *lower, int *upper)
1562 {
1563 *lower = sym;
1564 *upper = sym;
1565 switch(sym >> 8) {
1566 case 0: /* Latin 1 */
1567 if ((sym >= XK_A) && (sym <= XK_Z))
1568 *lower += (XK_a - XK_A);
1569 else if ((sym >= XK_a) && (sym <= XK_z))
1570 *upper -= (XK_a - XK_A);
1571 else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
1572 *lower += (XK_agrave - XK_Agrave);
1573 else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
1574 *upper -= (XK_agrave - XK_Agrave);
1575 else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
1576 *lower += (XK_oslash - XK_Ooblique);
1577 else if ((sym >= XK_oslash) && (sym <= XK_thorn))
1578 *upper -= (XK_oslash - XK_Ooblique);
1579 break;
1580 case 1: /* Latin 2 */
1581 /* Assume the KeySym is a legal value (ignore discontinuities) */
1582 if (sym == XK_Aogonek)
1583 *lower = XK_aogonek;
1584 else if (sym >= XK_Lstroke && sym <= XK_Sacute)
1585 *lower += (XK_lstroke - XK_Lstroke);
1586 else if (sym >= XK_Scaron && sym <= XK_Zacute)
1587 *lower += (XK_scaron - XK_Scaron);
1588 else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
1589 *lower += (XK_zcaron - XK_Zcaron);
1590 else if (sym == XK_aogonek)
1591 *upper = XK_Aogonek;
1592 else if (sym >= XK_lstroke && sym <= XK_sacute)
1593 *upper -= (XK_lstroke - XK_Lstroke);
1594 else if (sym >= XK_scaron && sym <= XK_zacute)
1595 *upper -= (XK_scaron - XK_Scaron);
1596 else if (sym >= XK_zcaron && sym <= XK_zabovedot)
1597 *upper -= (XK_zcaron - XK_Zcaron);
1598 else if (sym >= XK_Racute && sym <= XK_Tcedilla)
1599 *lower += (XK_racute - XK_Racute);
1600 else if (sym >= XK_racute && sym <= XK_tcedilla)
1601 *upper -= (XK_racute - XK_Racute);
1602 break;
1603 case 2: /* Latin 3 */
1604 /* Assume the KeySym is a legal value (ignore discontinuities) */
1605 if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
1606 *lower += (XK_hstroke - XK_Hstroke);
1607 else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
1608 *lower += (XK_gbreve - XK_Gbreve);
1609 else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
1610 *upper -= (XK_hstroke - XK_Hstroke);
1611 else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
1612 *upper -= (XK_gbreve - XK_Gbreve);
1613 else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
1614 *lower += (XK_cabovedot - XK_Cabovedot);
1615 else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
1616 *upper -= (XK_cabovedot - XK_Cabovedot);
1617 break;
1618 case 3: /* Latin 4 */
1619 /* Assume the KeySym is a legal value (ignore discontinuities) */
1620 if (sym >= XK_Rcedilla && sym <= XK_Tslash)
1621 *lower += (XK_rcedilla - XK_Rcedilla);
1622 else if (sym >= XK_rcedilla && sym <= XK_tslash)
1623 *upper -= (XK_rcedilla - XK_Rcedilla);
1624 else if (sym == XK_ENG)
1625 *lower = XK_eng;
1626 else if (sym == XK_eng)
1627 *upper = XK_ENG;
1628 else if (sym >= XK_Amacron && sym <= XK_Umacron)
1629 *lower += (XK_amacron - XK_Amacron);
1630 else if (sym >= XK_amacron && sym <= XK_umacron)
1631 *upper -= (XK_amacron - XK_Amacron);
1632 break;
1633 case 6: /* Cyrillic */
1634 /* Assume the KeySym is a legal value (ignore discontinuities) */
1635 if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
1636 *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
1637 else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
1638 *upper += (XK_Serbian_DJE - XK_Serbian_dje);
1639 else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
1640 *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
1641 else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
1642 *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
1643 break;
1644 case 7: /* Greek */
1645 /* Assume the KeySym is a legal value (ignore discontinuities) */
1646 if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
1647 *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
1648 else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
1649 sym != XK_Greek_iotaaccentdieresis &&
1650 sym != XK_Greek_upsilonaccentdieresis)
1651 *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
1652 else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
1653 *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
1654 else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
1655 sym != XK_Greek_finalsmallsigma)
1656 *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
1657 break;
1658 }
1659 }
1660
1661 static const char *
keycode2keysymString(int * keycodemap[256],int first_keycode,int keysyms_per_keycode,int * modifiermap[array_length (modifiers)],int keycodes_per_modifier,guint32 keycode,guint32 bitmask)1662 keycode2keysymString(int *keycodemap[256], int first_keycode,
1663 int keysyms_per_keycode,
1664 int *modifiermap[array_length(modifiers)],
1665 int keycodes_per_modifier,
1666 guint32 keycode, guint32 bitmask)
1667 {
1668 int *syms;
1669 int groupmodkc, numlockkc, numlockmod, groupmod;
1670 int lockmod_is_capslock = 0, lockmod_is_shiftlock = 0;
1671 int lockmod_is_nosymbol = 1;
1672 int modifier, kc, keysym;
1673
1674 if ((syms = keycodemap[keycode]) == NULL)
1675 return "<Unknown>";
1676
1677 for (kc = first_keycode, groupmodkc = numlockkc = -1; kc < 256; ++kc)
1678 for (keysym = 0; keysym < keysyms_per_keycode; ++keysym) {
1679 if (keycodemap[kc] == NULL)
1680 return "<Unknown>";
1681 switch (keycodemap[kc][keysym]) {
1682 case 0xff7e:
1683 groupmodkc = kc;
1684 break;
1685
1686 case 0xff7f:
1687 numlockkc = kc;
1688 break;
1689
1690 case 0xffe5:
1691 lockmod_is_capslock = kc;
1692 break;
1693
1694 case 0xffe6:
1695 lockmod_is_shiftlock = kc;
1696 break;
1697 }
1698 }
1699
1700
1701 /*
1702 * If we have not seen the modifiermap we don't know what the
1703 * keycode translates to, but we do know it's one of the keys
1704 * in syms (give or take a case-conversion), so we could in
1705 * theory list them all.
1706 */
1707 if (modifiermap[array_length(modifiers) - 1] == NULL) /* all or none */
1708 return "<Unknown>";
1709
1710 /* find out what the numlockmodifer and groupmodifier is. */
1711 for (modifier = 0, numlockmod = groupmod = -1;
1712 modifier < (int)array_length(modifiers) && numlockmod == -1;
1713 ++modifier)
1714 for (kc = 0; kc < keycodes_per_modifier; ++kc)
1715 if (modifiermap[modifier][kc] == numlockkc)
1716 numlockmod = modifier;
1717 else if (modifiermap[modifier][kc] == groupmodkc)
1718 groupmod = modifier;
1719
1720 /*
1721 * ... and what the lockmodifier is interpreted as.
1722 * (X11v4r6 ref, keyboard and pointers section.)
1723 */
1724 for (kc = 0; kc < keycodes_per_modifier; ++kc)
1725 if (modifiermap[1][kc] == lockmod_is_capslock) {
1726 lockmod_is_shiftlock = lockmod_is_nosymbol = 0;
1727 break;
1728 }
1729 else if (modifiermap[0][kc] == lockmod_is_shiftlock) {
1730 lockmod_is_capslock = lockmod_is_nosymbol = 0;
1731 break;
1732 }
1733
1734 #if 0
1735 /*
1736 * This is (how I understand) the X11v4R6 protocol description given
1737 * in A. Nye's book. It is quite different from the
1738 * code in _XTranslateKey() in the file
1739 * "$XConsortium: KeyBind.c /main/55 1996/02/02 14:08:55 kaleb $"
1740 * as shipped with XFree, and doesn't work correctly, nor do I see
1741 * how it could (e.g. the case of lower/uppercase-letters).
1742 * -- Michael Shuldman
1743 */
1744
1745 if (numlockmod >= 0 && (bitmask & modifiermask[numlockmod])
1746 && ((syms[1] >= 0xff80
1747 && syms[1] <= 0xffbd)
1748 || (syms[1] >= 0x11000000
1749 && syms[1] <= 0x1100ffff))) {
1750 if ((bitmask & ShiftMask) || lockmod_is_shiftlock)
1751 return keysymString(syms[groupmod + 0]);
1752 else
1753 if (syms[groupmod + 1] == NoSymbol)
1754 return keysymString(syms[groupmod + 0]);
1755 else
1756 return keysymString(syms[groupmod + 1]);
1757 }
1758 else if (!(bitmask & ShiftMask) && !(bitmask & LockMask))
1759 return keysymString(syms[groupmod + 0]);
1760 else if (!(bitmask & ShiftMask)
1761 && ((bitmask & LockMask) && lockmod_is_capslock))
1762 if (islower(syms[groupmod + 0]))
1763 /* return toupper(keysymString(syms[groupmod + 0])); */
1764 return "Uppercase"; /* XXX */
1765 else
1766 return keysymString(syms[groupmod + 0]);
1767
1768 else if ((bitmask & ShiftMask)
1769 && ((bitmask & LockMask) && lockmod_is_capslock))
1770 if (islower(syms[groupmod + 1]))
1771 /* return toupper(keysymString(syms[groupmod + 1])); */
1772 return "Uppercase"; /* XXX */
1773 else
1774 return keysymString(syms[groupmod + 1]);
1775
1776 else if ((bitmask & ShiftMask)
1777 || ((bitmask & LockMask) && lockmod_is_shiftlock))
1778 return keysymString(syms[groupmod + 1]);
1779 #else /* _XTranslateKey() based code. */
1780
1781 while (keysyms_per_keycode > 2
1782 && keycodemap[keysyms_per_keycode - 1] == NoSymbol)
1783 --keysyms_per_keycode;
1784 if (keysyms_per_keycode > 2
1785 && (groupmod >= 0 && (modifiermask[groupmod] & bitmask))) {
1786 syms += 2;
1787 keysyms_per_keycode -= 2;
1788 }
1789
1790 if (numlockmod >= 0 && (bitmask & modifiermask[numlockmod])
1791 && keysyms_per_keycode > 1
1792 && ((syms[1] >= 0xff80 && syms[1] <= 0xffbd)
1793 || (syms[1] >= 0x11000000 && syms[1] <= 0x1100ffff))) {
1794 if ((bitmask & ShiftMask)
1795 || (bitmask & LockMask && lockmod_is_shiftlock))
1796 keysym = syms[0];
1797 else
1798 keysym = syms[1];
1799 }
1800 else if (!(bitmask & ShiftMask)
1801 && (!(bitmask & LockMask) || lockmod_is_nosymbol)) {
1802 if (keysyms_per_keycode == 1
1803 || (keysyms_per_keycode > 1 && syms[1] == NoSymbol)) {
1804 int usym;
1805
1806 XConvertCase(syms[0], &keysym, &usym);
1807 }
1808 else
1809 keysym = syms[0];
1810 }
1811 else if (!(bitmask & LockMask) || !lockmod_is_capslock) {
1812 int lsym, usym = 0;
1813
1814 if (keysyms_per_keycode == 1
1815 || (keysyms_per_keycode > 1 && (usym = syms[1]) == NoSymbol))
1816 XConvertCase(syms[0], &lsym, &usym);
1817 keysym = usym;
1818 }
1819 else {
1820 int lsym, usym = 0;
1821
1822 if (keysyms_per_keycode == 1
1823 || (keysyms_per_keycode > 1 && syms[1] == NoSymbol))
1824 keysym = syms[0];
1825
1826 XConvertCase(keysym, &lsym, &usym);
1827
1828 if (!(bitmask & ShiftMask) && keysym != syms[0]
1829 && ((keysym != usym) || (lsym == usym)))
1830 XConvertCase(syms[0], &lsym, &usym);
1831 keysym = usym;
1832 }
1833
1834 if (keysym == XK_VoidSymbol)
1835 keysym = NoSymbol;
1836
1837 return wmem_strdup_printf(wmem_packet_scope(), "%d, \"%s\"", keysym, keysymString(keysym));
1838 #endif
1839 }
1840
keysymString(guint32 v)1841 static const char *keysymString(guint32 v)
1842 {
1843 #if 0 /* XXX: Use of GTree no longer needed; use value_string_ext */
1844 static GTree *keysymTable = NULL;
1845
1846 gpointer res;
1847 if (!keysymTable) {
1848
1849 /* This table is so big that we built it only if necessary */
1850 const value_string *p = x11_keysym_vals_source;
1851 keysymTable = g_tree_new(compareGuint32);
1852 for(; p -> strptr; p++)
1853 g_tree_insert(keysymTable, GINT_TO_POINTER(p -> value), (gpointer) (p -> strptr) );
1854 }
1855 res = g_tree_lookup(keysymTable, GINT_TO_POINTER(v));
1856 return res ? res : "<Unknown>";
1857 #endif
1858
1859 return val_to_str_ext_const(v, &x11_keysym_vals_source_ext, "<Unknown>");
1860
1861 }
1862
listOfKeycode(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int * modifiermap[],int keycodes_per_modifier,guint byte_order _U_)1863 static void listOfKeycode(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1864 int *modifiermap[], int keycodes_per_modifier,
1865 guint byte_order _U_)
1866 {
1867 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp,
1868 (int)array_length(modifiers) * keycodes_per_modifier, ENC_NA);
1869 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_keycode);
1870 size_t m;
1871
1872 for (m = 0; m < array_length(modifiers);
1873 ++m, *offsetp += keycodes_per_modifier) {
1874 proto_item *tikc;
1875 int i;
1876
1877 tikc = proto_tree_add_bytes_format(tt, hf_x11_keycodes_item, tvb,
1878 *offsetp, keycodes_per_modifier, NULL, "item: ");
1879 modifiermap[m] = (int *)
1880 wmem_alloc(wmem_file_scope(), sizeof(*modifiermap[m]) * keycodes_per_modifier);
1881 for(i = 0; i < keycodes_per_modifier; ++i) {
1882 guchar c = tvb_get_guint8(tvb, (*offsetp) + i);
1883
1884 if (c)
1885 proto_item_append_text(tikc, " %s=%d", modifiers[m], c);
1886
1887 modifiermap[m][i] = c;
1888 }
1889 }
1890 }
1891
listOfKeysyms(tvbuff_t * tvb,packet_info * pinfo,int * offsetp,proto_tree * t,int hf,int hf_item,int * keycodemap[256],int keycode_first,int keycode_count,int keysyms_per_keycode,guint byte_order)1892 static void listOfKeysyms(tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t, int hf,
1893 int hf_item, int *keycodemap[256],
1894 int keycode_first, int keycode_count,
1895 int keysyms_per_keycode, guint byte_order)
1896 {
1897 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, keycode_count * keysyms_per_keycode * 4, byte_order);
1898 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_keysyms);
1899 proto_item *tti;
1900 proto_tree *ttt;
1901 int i, keycode;
1902
1903 DISSECTOR_ASSERT(keycode_first >= 0);
1904 DISSECTOR_ASSERT(keycode_count >= 0);
1905
1906 for (keycode = keycode_first; keycode_count > 0;
1907 ++keycode, --keycode_count) {
1908 tti = proto_tree_add_none_format(tt, hf_item, tvb, *offsetp,
1909 4 * keysyms_per_keycode, "keysyms (keycode %d):", keycode);
1910 if (keycode >= 256) {
1911 expert_add_info_format(pinfo, tti, &ei_x11_keycode_value_out_of_range,
1912 "keycode value %d is out of range", keycode);
1913 *offsetp += 4 * keysyms_per_keycode;
1914 continue;
1915 }
1916
1917 ttt = proto_item_add_subtree(tti, ett_x11_keysym);
1918
1919 tvb_ensure_bytes_exist(tvb, *offsetp, 4 * keysyms_per_keycode);
1920 keycodemap[keycode]
1921 = (int *)wmem_alloc(wmem_file_scope(), sizeof(*keycodemap[keycode]) * keysyms_per_keycode);
1922
1923 for(i = 0; i < keysyms_per_keycode; ++i) {
1924 /* keysymvalue = byte3 * 256 + byte4. */
1925 guint32 v = tvb_get_guint32(tvb, *offsetp, byte_order);
1926
1927 proto_item_append_text(tti, " %s", keysymString(v));
1928 proto_tree_add_uint_format(ttt, hf_x11_keysyms_item_keysym,
1929 tvb, *offsetp, 4, v,
1930 "keysym (keycode %d): 0x%08x (%s)",
1931 keycode, v, keysymString(v));
1932
1933 keycodemap[keycode][i] = v;
1934 *offsetp += 4;
1935 }
1936
1937 for (i = 1; i < keysyms_per_keycode; ++i)
1938 if (keycodemap[keycode][i] != NoSymbol)
1939 break;
1940
1941 if (i == keysyms_per_keycode) {
1942 /* all but (possibly) first were NoSymbol. */
1943 if (keysyms_per_keycode == 4) {
1944 keycodemap[keycode][1] = NoSymbol;
1945 keycodemap[keycode][2] = keycodemap[keycode][0];
1946 keycodemap[keycode][3] = NoSymbol;
1947 }
1948
1949 continue;
1950 }
1951
1952 for (i = 2; i < keysyms_per_keycode; ++i)
1953 if (keycodemap[keycode][i] != NoSymbol)
1954 break;
1955 if (i == keysyms_per_keycode) {
1956 /* all but (possibly) first two were NoSymbol. */
1957 if (keysyms_per_keycode == 4) {
1958 keycodemap[keycode][2] = keycodemap[keycode][0];
1959 keycodemap[keycode][3] = keycodemap[keycode][1];
1960 }
1961
1962 continue;
1963 }
1964 }
1965 }
1966
listOfPoint(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int length,guint byte_order)1967 static void listOfPoint(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1968 int length, guint byte_order)
1969 {
1970 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 4, byte_order);
1971 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_point);
1972 while(length--) {
1973 gint16 x, y;
1974 proto_item *tti;
1975 proto_tree *ttt;
1976
1977 x = tvb_get_guint16(tvb, *offsetp, byte_order);
1978 y = tvb_get_guint16(tvb, *offsetp + 2, byte_order);
1979
1980 tti = proto_tree_add_none_format(tt, hf_x11_point, tvb, *offsetp, 4, "point: (%d,%d)", x, y);
1981 ttt = proto_item_add_subtree(tti, ett_x11_point);
1982 proto_tree_add_int(ttt, hf_x11_point_x, tvb, *offsetp, 2, x);
1983 *offsetp += 2;
1984 proto_tree_add_int(ttt, hf_x11_point_y, tvb, *offsetp, 2, y);
1985 *offsetp += 2;
1986 }
1987 }
1988
listOfRectangle(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int length,guint byte_order)1989 static void listOfRectangle(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
1990 int length, guint byte_order)
1991 {
1992 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 8, byte_order);
1993 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_rectangle);
1994 while(length--) {
1995 gint16 x, y;
1996 guint width, height;
1997 proto_item *tti;
1998 proto_tree *ttt;
1999
2000 x = tvb_get_guint16(tvb, *offsetp, byte_order);
2001 y = tvb_get_guint16(tvb, *offsetp + 2, byte_order);
2002 width = tvb_get_guint16(tvb, *offsetp + 4, byte_order);
2003 height = tvb_get_guint16(tvb, *offsetp + 6, byte_order);
2004
2005 tti = proto_tree_add_none_format(tt, hf_x11_rectangle, tvb, *offsetp, 8,
2006 "rectangle: %dx%d+%d+%d", width, height, x, y);
2007 ttt = proto_item_add_subtree(tti, ett_x11_rectangle);
2008 proto_tree_add_int(ttt, hf_x11_rectangle_x, tvb, *offsetp, 2, x);
2009 *offsetp += 2;
2010 proto_tree_add_int(ttt, hf_x11_rectangle_y, tvb, *offsetp, 2, y);
2011 *offsetp += 2;
2012 proto_tree_add_uint(ttt, hf_x11_rectangle_width, tvb, *offsetp, 2, width);
2013 *offsetp += 2;
2014 proto_tree_add_uint(ttt, hf_x11_rectangle_height, tvb, *offsetp, 2, height);
2015 *offsetp += 2;
2016 }
2017 }
2018
listOfSegment(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int length,guint byte_order)2019 static void listOfSegment(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
2020 int length, guint byte_order)
2021 {
2022 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 8, byte_order);
2023 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_segment);
2024 while(length--) {
2025 gint16 x1, y1, x2, y2;
2026 proto_item *tti;
2027 proto_tree *ttt;
2028
2029 x1 = tvb_get_guint16(tvb, *offsetp, byte_order);
2030 y1 = tvb_get_guint16(tvb, *offsetp + 2, byte_order);
2031 x2 = tvb_get_guint16(tvb, *offsetp + 4, byte_order);
2032 y2 = tvb_get_guint16(tvb, *offsetp + 6, byte_order);
2033
2034 tti = proto_tree_add_none_format(tt, hf_x11_segment, tvb, *offsetp, 8,
2035 "segment: (%d,%d)-(%d,%d)", x1, y1, x2, y2);
2036 ttt = proto_item_add_subtree(tti, ett_x11_segment);
2037 proto_tree_add_item(ttt, hf_x11_segment_x1, tvb, *offsetp, 2, byte_order);
2038 *offsetp += 2;
2039 proto_tree_add_item(ttt, hf_x11_segment_y1, tvb, *offsetp, 2, byte_order);
2040 *offsetp += 2;
2041 proto_tree_add_item(ttt, hf_x11_segment_x2, tvb, *offsetp, 2, byte_order);
2042 *offsetp += 2;
2043 proto_tree_add_item(ttt, hf_x11_segment_y2, tvb, *offsetp, 2, byte_order);
2044 *offsetp += 2;
2045 }
2046 }
2047
listOfVisualTypes(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int length,guint byte_order)2048 static void listOfVisualTypes(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
2049 int length, guint byte_order)
2050 {
2051 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 24, byte_order);
2052 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_visualtype);
2053 while(length--) {
2054 proto_item *tti;
2055 proto_tree *ttt;
2056
2057 tti = proto_tree_add_none_format(tt, hf_x11_visualtype, tvb, *offsetp, 24,
2058 "visualtype");
2059 ttt = proto_item_add_subtree(tti, ett_x11_visualtype);
2060 proto_tree_add_item(ttt, hf_x11_visualtype_visualid, tvb, *offsetp, 4, byte_order);
2061 *offsetp += 4;
2062 proto_tree_add_item(ttt, hf_x11_visualtype_class, tvb, *offsetp, 1, byte_order);
2063 *offsetp += 1;
2064 proto_tree_add_item(ttt, hf_x11_visualtype_bits_per_rgb_value, tvb, *offsetp, 1, byte_order);
2065 *offsetp += 1;
2066 proto_tree_add_item(ttt, hf_x11_visualtype_colormap_entries, tvb, *offsetp, 2, byte_order);
2067 *offsetp += 2;
2068 proto_tree_add_item(ttt, hf_x11_visualtype_red_mask, tvb, *offsetp, 4, byte_order);
2069 *offsetp += 4;
2070 proto_tree_add_item(ttt, hf_x11_visualtype_green_mask, tvb, *offsetp, 4, byte_order);
2071 *offsetp += 4;
2072 proto_tree_add_item(ttt, hf_x11_visualtype_blue_mask, tvb, *offsetp, 4, byte_order);
2073 *offsetp += 4;
2074 proto_tree_add_item(ttt, hf_x11_unused, tvb, *offsetp, 4, byte_order);
2075 *offsetp += 4;
2076 }
2077 }
listOfDepth(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int length,guint byte_order)2078 static void listOfDepth(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
2079 int length, guint byte_order)
2080 {
2081 guint16 number_of_visualtypes;
2082 proto_item *ti;
2083 proto_tree *tt;
2084
2085 ti = proto_tree_add_item(t, hf, tvb, *offsetp, -1, byte_order);
2086 tt = proto_item_add_subtree(ti, ett_x11_list_of_depth_detail);
2087 while(length--) {
2088 proto_item *tti;
2089 proto_tree *ttt;
2090 number_of_visualtypes = tvb_get_guint16(tvb, *offsetp + 2, byte_order);
2091
2092 tti = proto_tree_add_none_format(tt, hf_x11_depth_detail, tvb, *offsetp, 8 + 24 * number_of_visualtypes,
2093 "depth-detail");
2094 ttt = proto_item_add_subtree(tti, ett_x11_screen);
2095 proto_tree_add_item(ttt, hf_x11_depth_detail_depth, tvb, *offsetp, 1, byte_order);
2096 *offsetp += 1;
2097 proto_tree_add_item(ttt, hf_x11_unused, tvb, *offsetp, 1, byte_order);
2098 *offsetp += 1;
2099 proto_tree_add_item(ttt, hf_x11_depth_detail_visualtypes_numbers, tvb, *offsetp, 2, byte_order);
2100 *offsetp += 2;
2101 proto_tree_add_item(ttt, hf_x11_unused, tvb, *offsetp, 4, byte_order);
2102 *offsetp += 4;
2103 if (number_of_visualtypes > 0)
2104 listOfVisualTypes(tvb, offsetp, ttt, hf_x11_visualtype, number_of_visualtypes, byte_order);
2105 }
2106 }
2107
listOfScreen(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int length,guint byte_order)2108 static void listOfScreen(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
2109 int length, guint byte_order)
2110 {
2111 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, -1, byte_order);
2112 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_screen);
2113 while(length--) {
2114 guint8 number_of_depths, root_depth;
2115 guint16 width_in_pixels, height_in_pixels;
2116 guint32 screen_root;
2117 proto_item *tti;
2118 proto_tree *ttt;
2119
2120 screen_root = tvb_get_guint32(tvb, *offsetp, byte_order);
2121 width_in_pixels = tvb_get_guint16(tvb, *offsetp + 20, byte_order);
2122 height_in_pixels = tvb_get_guint16(tvb, *offsetp + 22, byte_order);
2123 root_depth = tvb_get_guint8(tvb, *offsetp + 38);
2124 tti = proto_tree_add_none_format(tt, hf_x11_screen, tvb, *offsetp, 0,
2125 "screen (%08x: %d x %d x %d)", screen_root,
2126 width_in_pixels, height_in_pixels, root_depth);
2127 ttt = proto_item_add_subtree(tti, ett_x11_screen);
2128 proto_tree_add_item(ttt, hf_x11_screen_root, tvb, *offsetp, 4, byte_order);
2129 *offsetp += 4;
2130 proto_tree_add_item(ttt, hf_x11_screen_default_colormap, tvb, *offsetp, 4, byte_order);
2131 *offsetp += 4;
2132 proto_tree_add_item(ttt, hf_x11_screen_white_pixel, tvb, *offsetp, 4, byte_order);
2133 *offsetp += 4;
2134 proto_tree_add_item(ttt, hf_x11_screen_black_pixel, tvb, *offsetp, 4, byte_order);
2135 *offsetp += 4;
2136 proto_tree_add_item(ttt, hf_x11_screen_current_input_masks, tvb, *offsetp, 4, byte_order);
2137 *offsetp += 4;
2138 proto_tree_add_item(ttt, hf_x11_screen_width_in_pixels, tvb, *offsetp, 2, byte_order);
2139 *offsetp += 2;
2140 proto_tree_add_item(ttt, hf_x11_screen_height_in_pixels, tvb, *offsetp, 2, byte_order);
2141 *offsetp += 2;
2142 proto_tree_add_item(ttt, hf_x11_screen_width_in_millimeters, tvb, *offsetp, 2, byte_order);
2143 *offsetp += 2;
2144 proto_tree_add_item(ttt, hf_x11_screen_height_in_millimeters, tvb, *offsetp, 2, byte_order);
2145 *offsetp += 2;
2146 proto_tree_add_item(ttt, hf_x11_screen_min_installed_maps, tvb, *offsetp, 2, byte_order);
2147 *offsetp += 2;
2148 proto_tree_add_item(ttt, hf_x11_screen_max_installed_maps, tvb, *offsetp, 2, byte_order);
2149 *offsetp += 2;
2150 proto_tree_add_item(ttt, hf_x11_screen_root_visual, tvb, *offsetp, 4, byte_order);
2151 *offsetp += 4;
2152 proto_tree_add_item(ttt, hf_x11_screen_backing_stores, tvb, *offsetp, 1, byte_order);
2153 *offsetp += 1;
2154 proto_tree_add_item(ttt, hf_x11_screen_save_unders, tvb, *offsetp, 1, byte_order);
2155 *offsetp += 1;
2156 proto_tree_add_item(ttt, hf_x11_screen_root_depth, tvb, *offsetp, 1, byte_order);
2157 *offsetp += 1;
2158 number_of_depths = tvb_get_guint8(tvb, *offsetp);
2159 proto_tree_add_item(ttt, hf_x11_screen_allowed_depths_len, tvb, *offsetp, 1, byte_order);
2160 *offsetp += 1;
2161 listOfDepth(tvb, offsetp, ttt, hf_x11_depth_detail, number_of_depths, byte_order);
2162 }
2163 }
listOfPixmapFormat(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int length,guint byte_order)2164 static void listOfPixmapFormat(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
2165 int length, guint byte_order)
2166 {
2167 proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 8, byte_order);
2168 proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_pixmap_format);
2169 while(length--) {
2170 proto_item *tti;
2171 proto_tree *ttt;
2172
2173 tti = proto_tree_add_none_format(tt, hf_x11_pixmap_format, tvb, *offsetp, 8,
2174 "pixmap-format");
2175 ttt = proto_item_add_subtree(tti, ett_x11_pixmap_format);
2176 proto_tree_add_item(ttt, hf_x11_pixmap_format_depth, tvb, *offsetp, 1, byte_order);
2177 *offsetp += 1;
2178 proto_tree_add_item(ttt, hf_x11_pixmap_format_bits_per_pixel, tvb, *offsetp, 1, byte_order);
2179 *offsetp += 1;
2180 proto_tree_add_item(ttt, hf_x11_pixmap_format_scanline_pad, tvb, *offsetp, 1, byte_order);
2181 *offsetp += 1;
2182 proto_tree_add_item(ttt, hf_x11_unused, tvb, *offsetp, 5, byte_order);
2183 *offsetp += 5;
2184 }
2185 }
2186
listOfString8(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int hf_item,int length,guint byte_order)2187 static void listOfString8(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
2188 int hf_item, int length, guint byte_order)
2189 {
2190 char *s = NULL;
2191 proto_item *ti;
2192 proto_tree *tt;
2193 int i;
2194
2195 /* Compute total length */
2196
2197 int scanning_offset = *offsetp; /* Scanning pointer */
2198 for(i = length; i; i--) {
2199 int l;
2200 l = tvb_get_guint8(tvb, scanning_offset);
2201 scanning_offset += 1 + l;
2202 }
2203
2204 ti = proto_tree_add_item(t, hf, tvb, *offsetp, scanning_offset - *offsetp, byte_order);
2205 tt = proto_item_add_subtree(ti, ett_x11_list_of_string8);
2206
2207 while(length--) {
2208 guint l = tvb_get_guint8(tvb, *offsetp);
2209 s = tvb_get_string_enc(wmem_packet_scope(), tvb, *offsetp + 1, l, ENC_ASCII);
2210 proto_tree_add_string_format(tt, hf_item, tvb, *offsetp, l + 1, s, "\"%s\"", s);
2211 *offsetp += l + 1;
2212 }
2213 }
2214
stringIsActuallyAn8BitString(tvbuff_t * tvb,int offset,guint length)2215 static int stringIsActuallyAn8BitString(tvbuff_t *tvb, int offset, guint length)
2216 {
2217 for(; length > 0; offset += 2, length--) {
2218 if (tvb_get_guint8(tvb, offset))
2219 return FALSE;
2220 }
2221 return TRUE;
2222 }
2223
2224 #define UNREPL 0x00FFFD
2225
2226 /* XXX - assumes that the string encoding is ASCII; even if 0x00 through
2227 0x7F are ASCII, 0x80 through 0xFF might not be, and even 0x00 through
2228 0x7F aren't necessarily ASCII. */
tvb_get_ascii_string16(tvbuff_t * tvb,int offset,guint length)2229 static char *tvb_get_ascii_string16(tvbuff_t *tvb, int offset, guint length)
2230 {
2231 wmem_strbuf_t *str;
2232 guint8 ch;
2233
2234 str = wmem_strbuf_sized_new(wmem_packet_scope(), length + 1, 0);
2235
2236 while(length--) {
2237 offset++;
2238 ch = tvb_get_guint8(tvb, offset);
2239 if (ch < 0x80)
2240 wmem_strbuf_append_c(str, ch);
2241 else
2242 wmem_strbuf_append_unichar(str, UNREPL);
2243 offset++;
2244 }
2245 return wmem_strbuf_finalize(str);
2246 }
2247
listOfTextItem(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int sizeIs16,int next_offset,guint byte_order)2248 static void listOfTextItem(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
2249 int sizeIs16, int next_offset, guint byte_order)
2250 {
2251 char *s = NULL;
2252 proto_item *ti;
2253 proto_tree *tt;
2254 guint32 fid;
2255
2256 /* Compute total length */
2257
2258 int scanning_offset = *offsetp; /* Scanning pointer */
2259 int n = 0; /* Number of items */
2260
2261 while(scanning_offset < next_offset) {
2262 int l; /* Length of an individual item */
2263 l = tvb_get_guint8(tvb, scanning_offset);
2264 scanning_offset++;
2265 if (!l) break;
2266 n++;
2267 scanning_offset += l == 255 ? 4 : l + (sizeIs16 ? l : 0) + 1;
2268 }
2269
2270 ti = proto_tree_add_item(t, hf, tvb, *offsetp, scanning_offset - *offsetp, byte_order);
2271 tt = proto_item_add_subtree(ti, ett_x11_list_of_text_item);
2272
2273 while(n--) {
2274 guint l = tvb_get_guint8(tvb, *offsetp);
2275 if (l == 255) { /* Item is a font */
2276 fid = tvb_get_ntohl(tvb, *offsetp + 1);
2277 proto_tree_add_uint(tt, hf_x11_textitem_font, tvb, *offsetp, 5, fid);
2278 *offsetp += 5;
2279 } else { /* Item is a string */
2280 proto_item *tti;
2281 proto_tree *ttt;
2282 gint8 delta = tvb_get_guint8(tvb, *offsetp + 1);
2283 if (sizeIs16) {
2284 if (stringIsActuallyAn8BitString(tvb, *offsetp + 2, l)) {
2285 s = tvb_get_ascii_string16(tvb, *offsetp + 2, l);
2286 tti = proto_tree_add_none_format(tt, hf_x11_textitem_string, tvb, *offsetp, l*2 + 2,
2287 "textitem (string): delta = %d, \"%s\"",
2288 delta, s);
2289 ttt = proto_item_add_subtree(tti, ett_x11_text_item);
2290 proto_tree_add_item(ttt, hf_x11_textitem_string_delta, tvb, *offsetp + 1, 1, byte_order);
2291 proto_tree_add_string_format_value(ttt, hf_x11_textitem_string_string16, tvb,
2292 *offsetp + 2, l, s, "\"%s\"", s);
2293 } else {
2294 tti = proto_tree_add_none_format(tt, hf_x11_textitem_string, tvb, *offsetp, l*2 + 2,
2295 "textitem (string): delta = %d, %s",
2296 delta,
2297 tvb_bytes_to_str(wmem_packet_scope(), tvb, *offsetp + 2, l*2));
2298 ttt = proto_item_add_subtree(tti, ett_x11_text_item);
2299 proto_tree_add_item(ttt, hf_x11_textitem_string_delta, tvb, *offsetp + 1, 1, byte_order);
2300 proto_tree_add_item(ttt, hf_x11_textitem_string_string16_bytes, tvb, *offsetp + 2, l*2, byte_order);
2301 }
2302 *offsetp += l*2 + 2;
2303 } else {
2304 s = tvb_get_string_enc(wmem_packet_scope(), tvb, *offsetp + 2, l, ENC_ASCII);
2305 tti = proto_tree_add_none_format(tt, hf_x11_textitem_string, tvb, *offsetp, l + 2,
2306 "textitem (string): delta = %d, \"%s\"",
2307 delta, s);
2308 ttt = proto_item_add_subtree(tti, ett_x11_text_item);
2309 proto_tree_add_item(ttt, hf_x11_textitem_string_delta, tvb, *offsetp + 1, 1, byte_order);
2310 proto_tree_add_string_format(ttt, hf_x11_textitem_string_string8, tvb,
2311 *offsetp + 2, l, s, "\"%s\"", s);
2312 *offsetp += l + 2;
2313 }
2314 }
2315 }
2316 }
2317
field8(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,guint byte_order)2318 static guint32 field8(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
2319 guint byte_order)
2320 {
2321 guint32 v = tvb_get_guint8(tvb, *offsetp);
2322 header_field_info *hfi = proto_registrar_get_nth(hf);
2323 const gchar *enumValue = NULL;
2324
2325 if (hfi -> strings)
2326 enumValue = try_val_to_str(v, cVALS(hfi -> strings));
2327 if (enumValue)
2328 proto_tree_add_uint_format(t, hf, tvb, *offsetp, 1, v,
2329 hfi -> display == BASE_DEC ? "%s: %u (%s)" : "%s: 0x%02x (%s)",
2330 hfi -> name, v, enumValue);
2331 else
2332 proto_tree_add_item(t, hf, tvb, *offsetp, 1, byte_order);
2333 *offsetp += 1;
2334 return v;
2335 }
2336
field16(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,guint byte_order)2337 static guint32 field16(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
2338 guint byte_order)
2339 {
2340 guint32 v = tvb_get_guint16(tvb, *offsetp, byte_order);
2341 header_field_info *hfi = proto_registrar_get_nth(hf);
2342 const gchar *enumValue = NULL;
2343
2344 if (hfi -> strings)
2345 enumValue = try_val_to_str(v, cVALS(hfi -> strings));
2346 if (enumValue)
2347 proto_tree_add_uint_format(t, hf, tvb, *offsetp, 2, v,
2348 hfi -> display == BASE_DEC ? "%s: %u (%s)" : "%s: 0x%02x (%s)",
2349 hfi -> name, v, enumValue);
2350 else
2351 proto_tree_add_item(t, hf, tvb, *offsetp, 2, byte_order);
2352 *offsetp += 2;
2353 return v;
2354 }
2355
field32(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,guint byte_order)2356 static guint32 field32(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
2357 guint byte_order)
2358 {
2359 guint32 v = tvb_get_guint32(tvb, *offsetp, byte_order);
2360 header_field_info *hfi = proto_registrar_get_nth(hf);
2361 const gchar *enumValue = NULL;
2362 const gchar *nameAsChar = hfi -> name;
2363
2364 if (hfi -> strings)
2365 enumValue = try_val_to_str(v, cVALS(hfi -> strings));
2366 if (enumValue)
2367 proto_tree_add_uint_format(t, hf, tvb, *offsetp, 4, v,
2368 hfi -> display == BASE_DEC ? "%s: %u (%s)" : "%s: 0x%08x (%s)",
2369 nameAsChar, v, enumValue);
2370 else
2371 proto_tree_add_uint_format(t, hf, tvb, *offsetp, 4, v,
2372 hfi -> display == BASE_DEC ? "%s: %u" : "%s: 0x%08x",
2373 nameAsChar, v);
2374 *offsetp += 4;
2375 return v;
2376 }
2377
2378 static int * const gc_mask_attributes[] = {
2379 &hf_x11_gc_value_mask_function,
2380 &hf_x11_gc_value_mask_plane_mask,
2381 &hf_x11_gc_value_mask_foreground,
2382 &hf_x11_gc_value_mask_background,
2383 &hf_x11_gc_value_mask_line_width,
2384 &hf_x11_gc_value_mask_line_style,
2385 &hf_x11_gc_value_mask_cap_style,
2386 &hf_x11_gc_value_mask_join_style,
2387 &hf_x11_gc_value_mask_fill_style,
2388 &hf_x11_gc_value_mask_fill_rule,
2389 &hf_x11_gc_value_mask_tile,
2390 &hf_x11_gc_value_mask_stipple,
2391 &hf_x11_gc_value_mask_tile_stipple_x_origin,
2392 &hf_x11_gc_value_mask_tile_stipple_y_origin,
2393 &hf_x11_gc_value_mask_font,
2394 &hf_x11_gc_value_mask_subwindow_mode,
2395 &hf_x11_gc_value_mask_graphics_exposures,
2396 &hf_x11_gc_value_mask_clip_x_origin,
2397 &hf_x11_gc_value_mask_clip_y_origin,
2398 &hf_x11_gc_value_mask_clip_mask,
2399 &hf_x11_gc_value_mask_dash_offset,
2400 &hf_x11_gc_value_mask_gc_dashes,
2401 &hf_x11_gc_value_mask_arc_mode,
2402 NULL
2403 };
2404
gcAttributes(tvbuff_t * tvb,int * offsetp,proto_tree * t,guint byte_order)2405 static void gcAttributes(tvbuff_t *tvb, int *offsetp, proto_tree *t,
2406 guint byte_order)
2407 {
2408 guint32 bitmask;
2409 bitmask = tvb_get_guint32(tvb, *offsetp, byte_order);
2410 proto_tree_add_bitmask(t, tvb, *offsetp, hf_x11_gc_value_mask, ett_x11_gc_value_mask, gc_mask_attributes, byte_order);
2411 *offsetp += 4;
2412
2413 if (bitmask & 0x00000001) {
2414 proto_tree_add_item(t, hf_x11_function, tvb, *offsetp, 1, byte_order);
2415 *offsetp += 1;
2416 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
2417 *offsetp += 3;
2418 }
2419 if (bitmask & 0x00000002) {
2420 proto_tree_add_item(t, hf_x11_plane_mask, tvb, *offsetp, 4, byte_order);
2421 *offsetp += 4;
2422 }
2423 if (bitmask & 0x00000004) {
2424 proto_tree_add_item(t, hf_x11_foreground, tvb, *offsetp, 4, byte_order);
2425 *offsetp += 4;
2426 }
2427 if (bitmask & 0x00000008) {
2428 proto_tree_add_item(t, hf_x11_background, tvb, *offsetp, 4, byte_order);
2429 *offsetp += 4;
2430 }
2431 if (bitmask & 0x00000010) {
2432 proto_tree_add_item(t, hf_x11_line_width, tvb, *offsetp, 2, byte_order);
2433 *offsetp += 2;
2434 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
2435 *offsetp += 2;
2436 }
2437 if (bitmask & 0x00000020) {
2438 proto_tree_add_item(t, hf_x11_line_style, tvb, *offsetp, 1, byte_order);
2439 *offsetp += 1;
2440 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
2441 *offsetp += 3;
2442 }
2443 if (bitmask & 0x00000040) {
2444 proto_tree_add_item(t, hf_x11_cap_style, tvb, *offsetp, 1, byte_order);
2445 *offsetp += 1;
2446 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
2447 *offsetp += 3;
2448 }
2449 if (bitmask & 0x00000080) {
2450 proto_tree_add_item(t, hf_x11_join_style, tvb, *offsetp, 1, byte_order);
2451 *offsetp += 1;
2452 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
2453 *offsetp += 3;
2454 }
2455 if (bitmask & 0x00000100) {
2456 proto_tree_add_item(t, hf_x11_fill_style, tvb, *offsetp, 1, byte_order);
2457 *offsetp += 1;
2458 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
2459 *offsetp += 3;
2460 }
2461 if (bitmask & 0x00000200) {
2462 proto_tree_add_item(t, hf_x11_fill_rule, tvb, *offsetp, 1, byte_order);
2463 *offsetp += 1;
2464 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
2465 *offsetp += 3;
2466 }
2467 if (bitmask & 0x00000400) {
2468 proto_tree_add_item(t, hf_x11_tile, tvb, *offsetp, 4, byte_order);
2469 *offsetp += 4;
2470 }
2471 if (bitmask & 0x00000800) {
2472 proto_tree_add_item(t, hf_x11_stipple, tvb, *offsetp, 4, byte_order);
2473 *offsetp += 4;
2474 }
2475 if (bitmask & 0x00001000) {
2476 proto_tree_add_item(t, hf_x11_tile_stipple_x_origin, tvb, *offsetp, 2, byte_order);
2477 *offsetp += 2;
2478 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
2479 *offsetp += 2;
2480 }
2481 if (bitmask & 0x00002000) {
2482 proto_tree_add_item(t, hf_x11_tile_stipple_y_origin, tvb, *offsetp, 2, byte_order);
2483 *offsetp += 2;
2484 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
2485 *offsetp += 2;
2486 }
2487 if (bitmask & 0x00004000) {
2488 proto_tree_add_item(t, hf_x11_font, tvb, *offsetp, 4, byte_order);
2489 *offsetp += 4;
2490 }
2491 if (bitmask & 0x00008000) {
2492 proto_tree_add_item(t, hf_x11_subwindow_mode, tvb, *offsetp, 1, byte_order);
2493 *offsetp += 1;
2494 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
2495 *offsetp += 3;
2496 }
2497 if (bitmask & 0x00010000) {
2498 proto_tree_add_item(t, hf_x11_graphics_exposures, tvb, *offsetp, 1, byte_order);
2499 *offsetp += 1;
2500 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
2501 *offsetp += 3;
2502 }
2503 if (bitmask & 0x00020000) {
2504 proto_tree_add_item(t, hf_x11_clip_x_origin, tvb, *offsetp, 2, byte_order);
2505 *offsetp += 2;
2506 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
2507 *offsetp += 2;
2508 }
2509 if (bitmask & 0x00040000) {
2510 proto_tree_add_item(t, hf_x11_clip_y_origin, tvb, *offsetp, 2, byte_order);
2511 *offsetp += 2;
2512 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
2513 *offsetp += 2;
2514 }
2515 if (bitmask & 0x00080000) {
2516 proto_tree_add_item(t, hf_x11_clip_mask, tvb, *offsetp, 4, byte_order);
2517 *offsetp += 4;
2518 }
2519 if (bitmask & 0x00100000) {
2520 proto_tree_add_item(t, hf_x11_dash_offset, tvb, *offsetp, 2, byte_order);
2521 *offsetp += 2;
2522 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
2523 *offsetp += 2;
2524 }
2525 if (bitmask & 0x00200000) {
2526 proto_tree_add_item(t, hf_x11_gc_dashes, tvb, *offsetp, 1, byte_order);
2527 *offsetp += 1;
2528 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
2529 *offsetp += 3;
2530 }
2531 if (bitmask & 0x00400000) {
2532 proto_tree_add_item(t, hf_x11_arc_mode, tvb, *offsetp, 1, byte_order);
2533 *offsetp += 1;
2534 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
2535 *offsetp += 3;
2536 }
2537 }
2538
gcMask(tvbuff_t * tvb,int * offsetp,proto_tree * t,guint byte_order)2539 static void gcMask(tvbuff_t *tvb, int *offsetp, proto_tree *t,
2540 guint byte_order)
2541 {
2542 proto_tree_add_bitmask(t, tvb, *offsetp, hf_x11_gc_value_mask, ett_x11_gc_value_mask, gc_mask_attributes, byte_order);
2543 *offsetp += 4;
2544 }
2545
requestLength(tvbuff_t * tvb,int * offsetp,proto_tree * t,guint byte_order)2546 static guint32 requestLength(tvbuff_t *tvb, int *offsetp, proto_tree *t,
2547 guint byte_order)
2548 {
2549 guint32 res;
2550 proto_item *ti = proto_tree_add_item_ret_uint(t, hf_x11_request_length, tvb, *offsetp, 2, byte_order, &res);
2551 *offsetp += 2;
2552 if (res == 0) {
2553 proto_item_append_text(ti, " (extended length flag)");
2554 proto_tree_add_item_ret_uint(t, hf_x11_request_length, tvb, *offsetp, 4, byte_order, &res);
2555 *offsetp += 4;
2556 }
2557 return res * 4;
2558 }
2559
setOfEvent(tvbuff_t * tvb,int * offsetp,proto_tree * t,guint byte_order)2560 static void setOfEvent(tvbuff_t *tvb, int *offsetp, proto_tree *t,
2561 guint byte_order)
2562 {
2563 static int * const events[] = {
2564 &hf_x11_event_mask_KeyPress,
2565 &hf_x11_event_mask_KeyRelease,
2566 &hf_x11_event_mask_ButtonPress,
2567 &hf_x11_event_mask_ButtonRelease,
2568 &hf_x11_event_mask_EnterWindow,
2569 &hf_x11_event_mask_LeaveWindow,
2570 &hf_x11_event_mask_PointerMotion,
2571 &hf_x11_event_mask_PointerMotionHint,
2572 &hf_x11_event_mask_Button1Motion,
2573 &hf_x11_event_mask_Button2Motion,
2574 &hf_x11_event_mask_Button3Motion,
2575 &hf_x11_event_mask_Button4Motion,
2576 &hf_x11_event_mask_Button5Motion,
2577 &hf_x11_event_mask_ButtonMotion,
2578 &hf_x11_event_mask_KeymapState,
2579 &hf_x11_event_mask_Exposure,
2580 &hf_x11_event_mask_VisibilityChange,
2581 &hf_x11_event_mask_StructureNotify,
2582 &hf_x11_event_mask_ResizeRedirect,
2583 &hf_x11_event_mask_SubstructureNotify,
2584 &hf_x11_event_mask_SubstructureRedirect,
2585 &hf_x11_event_mask_FocusChange,
2586 &hf_x11_event_mask_PropertyChange,
2587 &hf_x11_event_mask_ColormapChange,
2588 &hf_x11_event_mask_OwnerGrabButton,
2589 NULL
2590 };
2591
2592 proto_tree_add_bitmask(t, tvb, *offsetp, hf_x11_event_mask, ett_x11_event_mask, events, byte_order);
2593 *offsetp += 4;
2594 }
2595
setOfDeviceEvent(tvbuff_t * tvb,int * offsetp,proto_tree * t,guint byte_order)2596 static void setOfDeviceEvent(tvbuff_t *tvb, int *offsetp, proto_tree *t,
2597 guint byte_order)
2598 {
2599 static int * const do_not_propagate_events[] = {
2600 &hf_x11_do_not_propagate_mask_KeyPress,
2601 &hf_x11_do_not_propagate_mask_KeyRelease,
2602 &hf_x11_do_not_propagate_mask_ButtonPress,
2603 &hf_x11_do_not_propagate_mask_ButtonRelease,
2604 &hf_x11_do_not_propagate_mask_PointerMotion,
2605 &hf_x11_do_not_propagate_mask_Button1Motion,
2606 &hf_x11_do_not_propagate_mask_Button2Motion,
2607 &hf_x11_do_not_propagate_mask_Button3Motion,
2608 &hf_x11_do_not_propagate_mask_Button4Motion,
2609 &hf_x11_do_not_propagate_mask_Button5Motion,
2610 &hf_x11_do_not_propagate_mask_ButtonMotion,
2611 NULL
2612 };
2613
2614 proto_tree_add_bitmask(t, tvb, *offsetp, hf_x11_do_not_propagate_mask, ett_x11_do_not_propagate_mask, do_not_propagate_events, byte_order);
2615 *offsetp += 4;
2616 }
2617
2618
setOfKeyButMask(tvbuff_t * tvb,int * offsetp,proto_tree * t,guint byte_order,gboolean butmask)2619 static void setOfKeyButMask(tvbuff_t *tvb, int *offsetp, proto_tree *t,
2620 guint byte_order, gboolean butmask)
2621 {
2622 proto_item *ti;
2623 guint32 bitmask_value;
2624 int bitmask_offset;
2625 int bitmask_size;
2626 proto_tree *bitmask_tree;
2627
2628 bitmask_value = tvb_get_guint16(tvb, *offsetp, byte_order);
2629 bitmask_offset = *offsetp;
2630 bitmask_size = 2;
2631
2632 if (!butmask && bitmask_value == 0x8000)
2633 proto_tree_add_uint_format(t, hf_x11_modifiers_mask_AnyModifier, tvb, *offsetp, 2, 0x8000,
2634 "modifiers-masks: 0x8000 (AnyModifier)");
2635 else {
2636 ti = proto_tree_add_uint(t, hf_x11_modifiers_mask, tvb, *offsetp, 2,
2637 bitmask_value);
2638 bitmask_tree = proto_item_add_subtree(ti, ett_x11_set_of_key_mask);
2639 FLAG(modifiers, Shift);
2640 FLAG(modifiers, Lock);
2641 FLAG(modifiers, Control);
2642 FLAG(modifiers, Mod1);
2643 FLAG(modifiers, Mod2);
2644 FLAG(modifiers, Mod3);
2645 FLAG(modifiers, Mod4);
2646 FLAG(modifiers, Mod5);
2647
2648 if (butmask) {
2649 FLAG(modifiers, Button1);
2650 FLAG(modifiers, Button2);
2651 FLAG(modifiers, Button3);
2652 FLAG(modifiers, Button4);
2653 FLAG(modifiers, Button5);
2654 }
2655
2656 if (butmask)
2657 FLAG_IF_NONZERO(keybut, erroneous_bits);
2658 else
2659 FLAG_IF_NONZERO(modifiers, erroneous_bits);
2660 }
2661 *offsetp += 2;
2662 }
2663
setOfPointerEvent(tvbuff_t * tvb,int * offsetp,proto_tree * t,guint byte_order)2664 static void setOfPointerEvent(tvbuff_t *tvb, int *offsetp, proto_tree *t,
2665 guint byte_order)
2666 {
2667 static int * const pointer_events[] = {
2668 &hf_x11_pointer_event_mask_ButtonRelease,
2669 &hf_x11_pointer_event_mask_EnterWindow,
2670 &hf_x11_pointer_event_mask_LeaveWindow,
2671 &hf_x11_pointer_event_mask_PointerMotion,
2672 &hf_x11_pointer_event_mask_PointerMotionHint,
2673 &hf_x11_pointer_event_mask_Button1Motion,
2674 &hf_x11_pointer_event_mask_Button2Motion,
2675 &hf_x11_pointer_event_mask_Button3Motion,
2676 &hf_x11_pointer_event_mask_Button4Motion,
2677 &hf_x11_pointer_event_mask_Button5Motion,
2678 &hf_x11_pointer_event_mask_ButtonMotion,
2679 &hf_x11_pointer_event_mask_KeymapState,
2680 NULL
2681 };
2682
2683 proto_tree_add_bitmask(t, tvb, *offsetp, hf_x11_pointer_event_mask, ett_x11_pointer_event_mask, pointer_events, byte_order);
2684 *offsetp += 2;
2685 }
2686
string8(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,guint length)2687 static void string8(tvbuff_t *tvb, int *offsetp, proto_tree *t,
2688 int hf, guint length)
2689 {
2690 proto_tree_add_item(t, hf, tvb, *offsetp, length, ENC_NA|ENC_ASCII);
2691 *offsetp += length;
2692 }
2693
2694 /* The length supplied is the length of the string in CHAR2Bs (half the number of bytes) */
2695
string16(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,int hf_bytes,guint length,guint byte_order)2696 static void string16(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
2697 int hf_bytes, guint length, guint byte_order)
2698 {
2699 guint l = length*2; /* byte count */
2700 char *s;
2701
2702 if (stringIsActuallyAn8BitString(tvb, *offsetp, length)) {
2703 s = tvb_get_ascii_string16(tvb, *offsetp, length);
2704 proto_tree_add_string_format_value(t, hf, tvb, *offsetp, l, s, "\"%s\"", s);
2705 } else
2706 proto_tree_add_item(t, hf_bytes, tvb, *offsetp, l, byte_order);
2707
2708 *offsetp += l;
2709 }
2710
timestamp(tvbuff_t * tvb,int * offsetp,proto_tree * t,int hf,guint byte_order)2711 static void timestamp(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
2712 guint byte_order)
2713 {
2714 guint32 v = tvb_get_guint32(tvb, *offsetp, byte_order);
2715
2716 if (!v)
2717 proto_tree_add_uint_format(t, hf, tvb, *offsetp, 4, 0, "%s: 0 (CurrentTime)",
2718 proto_registrar_get_nth(hf) -> name);
2719 else
2720 proto_tree_add_uint(t, hf, tvb, *offsetp, 4, v);
2721 *offsetp += 4;
2722 }
2723
windowAttributes(tvbuff_t * tvb,int * offsetp,proto_tree * t,guint byte_order)2724 static void windowAttributes(tvbuff_t *tvb, int *offsetp, proto_tree *t,
2725 guint byte_order)
2726 {
2727 guint32 bitmask;
2728 static int * const window_attributes_flags[] = {
2729 &hf_x11_window_value_mask_background_pixmap,
2730 &hf_x11_window_value_mask_background_pixel,
2731 &hf_x11_window_value_mask_border_pixmap,
2732 &hf_x11_window_value_mask_border_pixel,
2733 &hf_x11_window_value_mask_bit_gravity,
2734 &hf_x11_window_value_mask_win_gravity,
2735 &hf_x11_window_value_mask_backing_store,
2736 &hf_x11_window_value_mask_backing_planes,
2737 &hf_x11_window_value_mask_backing_pixel,
2738 &hf_x11_window_value_mask_override_redirect,
2739 &hf_x11_window_value_mask_save_under,
2740 &hf_x11_window_value_mask_event_mask,
2741 &hf_x11_window_value_mask_do_not_propagate_mask,
2742 &hf_x11_window_value_mask_colormap,
2743 &hf_x11_window_value_mask_cursor,
2744 NULL
2745 };
2746
2747 bitmask = tvb_get_guint32(tvb, *offsetp, byte_order);
2748 proto_tree_add_bitmask(t, tvb, *offsetp, hf_x11_window_value_mask, ett_x11_window_value_mask, window_attributes_flags, byte_order);
2749 *offsetp += 4;
2750
2751 if (bitmask & 0x00000001) {
2752 proto_tree_add_item(t, hf_x11_background_pixmap, tvb, *offsetp, 4, byte_order);
2753 *offsetp += 4;
2754 }
2755 if (bitmask & 0x00000002) {
2756 proto_tree_add_item(t, hf_x11_background_pixel, tvb, *offsetp, 4, byte_order);
2757 *offsetp += 4;
2758 }
2759 if (bitmask & 0x00000004) {
2760 proto_tree_add_item(t, hf_x11_border_pixmap, tvb, *offsetp, 4, byte_order);
2761 *offsetp += 4;
2762 }
2763 if (bitmask & 0x00000008) {
2764 proto_tree_add_item(t, hf_x11_border_pixel, tvb, *offsetp, 4, byte_order);
2765 *offsetp += 4;
2766 }
2767 if (bitmask & 0x00000010) {
2768 proto_tree_add_item(t, hf_x11_bit_gravity, tvb, *offsetp, 1, byte_order);
2769 *offsetp += 1;
2770 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
2771 *offsetp += 3;
2772 }
2773 if (bitmask & 0x00000020) {
2774 proto_tree_add_item(t, hf_x11_win_gravity, tvb, *offsetp, 1, byte_order);
2775 *offsetp += 1;
2776 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
2777 *offsetp += 3;
2778 }
2779 if (bitmask & 0x00000040) {
2780 proto_tree_add_item(t, hf_x11_backing_store, tvb, *offsetp, 1, byte_order);
2781 *offsetp += 1;
2782 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
2783 *offsetp += 3;
2784 }
2785 if (bitmask & 0x00000080) {
2786 proto_tree_add_item(t, hf_x11_backing_planes, tvb, *offsetp, 4, byte_order);
2787 *offsetp += 4;
2788 }
2789 if (bitmask & 0x00000100) {
2790 proto_tree_add_item(t, hf_x11_backing_pixel, tvb, *offsetp, 4, byte_order);
2791 *offsetp += 4;
2792 }
2793 if (bitmask & 0x00000200) {
2794 proto_tree_add_item(t, hf_x11_override_redirect, tvb, *offsetp, 1, byte_order);
2795 *offsetp += 1;
2796 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
2797 *offsetp += 3;
2798 }
2799 if (bitmask & 0x00000400) {
2800 proto_tree_add_item(t, hf_x11_save_under, tvb, *offsetp, 1, byte_order);
2801 *offsetp += 1;
2802 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
2803 *offsetp += 3;
2804 }
2805 if (bitmask & 0x00000800) {
2806 setOfEvent(tvb, offsetp, t, byte_order);
2807 }
2808 if (bitmask & 0x00001000) {
2809 setOfDeviceEvent(tvb, offsetp, t, byte_order);
2810 }
2811 if (bitmask & 0x00002000) {
2812 proto_tree_add_item(t, hf_x11_colormap, tvb, *offsetp, 4, byte_order);
2813 *offsetp += 4;
2814 }
2815 if (bitmask & 0x00004000) {
2816 proto_tree_add_item(t, hf_x11_cursor, tvb, *offsetp, 4, byte_order);
2817 *offsetp += 4;
2818 }
2819 }
2820
2821 /************************************************************************
2822 *** ***
2823 *** G U E S S I N G T H E B Y T E O R D E R I N G ***
2824 *** ***
2825 ************************************************************************/
2826
2827 /* If we can't guess, we return ENC_LITTLE_ENDIAN, cause
2828 I'm developing on a Linux box :-). The (non-)guess isn't cached
2829 however, so we may have more luck next time. I'm quite conservative
2830 in my assertions, cause once it's cached, it stays in cache, and
2831 we may be fooled up by a packet starting with the end of a request
2832 started in a previous packet...
2833 */
2834
2835 static int numberOfBitSetTable[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
2836
numberOfBitSet(tvbuff_t * tvb,int offset,int maskLength)2837 static int numberOfBitSet(tvbuff_t *tvb, int offset, int maskLength)
2838 {
2839 int res = 0;
2840 while(maskLength--) {
2841 int c = tvb_get_guint8(tvb, offset);
2842 offset++;
2843 res += numberOfBitSetTable[c & 0xf] + numberOfBitSetTable[c >> 4];
2844 }
2845 return res;
2846 }
2847
listOfStringLengthConsistent(tvbuff_t * tvb,int offset,int length,int listLength)2848 static int listOfStringLengthConsistent(tvbuff_t *tvb, int offset, int length, int listLength)
2849 {
2850 if (listLength > length) return FALSE;
2851 while(listLength--) {
2852 int l;
2853 if (!tvb_bytes_exist(tvb, offset, 1)) return TRUE;
2854 l = tvb_get_guint8(tvb, offset);
2855 if (!l) break;
2856 l++;
2857 if (l > length) return FALSE;
2858 if (!tvb_bytes_exist(tvb, offset, l)) return TRUE;
2859 offset += l;
2860 length -= l;
2861 }
2862 if (length > 3) return FALSE;
2863 return TRUE;
2864 }
2865
rounded4(int n)2866 static int rounded4(int n)
2867 {
2868 int remainder = n % 4;
2869 int res = n / 4;
2870 if (remainder) res++;
2871 return res;
2872 }
2873
2874 /* We assume the order to be consistent, until proven wrong. */
2875
consistentWithOrder(int length,tvbuff_t * tvb,int offset,int encoding)2876 static gboolean consistentWithOrder(int length, tvbuff_t *tvb, int offset, int encoding)
2877 {
2878 switch(tvb_get_guint8(tvb, offset)) {
2879 case X_CreateWindow:
2880 return !tvb_bytes_exist(tvb, offset, 32) || length == 8 + numberOfBitSet(tvb, offset + 7 * 4, 4);
2881
2882 case X_ChangeWindowAttributes:
2883 case X_ChangeGC:
2884 return !tvb_bytes_exist(tvb, offset, 12) || length == 3 + numberOfBitSet(tvb, offset + 8, 4);
2885
2886 case X_GetWindowAttributes:
2887 case X_DestroyWindow:
2888 case X_DestroySubwindows:
2889 case X_ChangeSaveSet:
2890 case X_MapWindow:
2891 case X_MapSubwindows:
2892 case X_UnmapWindow:
2893 case X_UnmapSubwindows:
2894 case X_CirculateWindow:
2895 case X_GetGeometry:
2896 case X_QueryTree:
2897 case X_GetAtomName:
2898 case X_ListProperties:
2899 case X_GetSelectionOwner:
2900 case X_UngrabPointer:
2901 case X_UngrabKeyboard:
2902 case X_AllowEvents:
2903 case X_QueryPointer:
2904 case X_CloseFont:
2905 case X_QueryFont:
2906 case X_FreePixmap:
2907 case X_FreeGC:
2908 case X_FreeColormap:
2909 case X_InstallColormap:
2910 case X_UninstallColormap:
2911 case X_ListInstalledColormaps:
2912 case X_FreeCursor:
2913 case X_GetKeyboardMapping:
2914 case X_KillClient:
2915 return length == 2;
2916
2917 case X_ReparentWindow:
2918 case X_SetSelectionOwner:
2919 case X_ChangeActivePointerGrab:
2920 case X_GrabKeyboard:
2921 case X_GrabKey:
2922 case X_GetMotionEvents:
2923 case X_TranslateCoords:
2924 case X_CreatePixmap:
2925 case X_CopyGC:
2926 case X_ClearArea:
2927 case X_CreateColormap:
2928 case X_AllocColor:
2929 case X_AllocColorPlanes:
2930 return length == 4;
2931
2932 case X_ConfigureWindow:
2933 return !tvb_bytes_exist(tvb, offset, 10) || length == 3 + numberOfBitSet(tvb, offset + 8, 2);
2934
2935 case X_InternAtom:
2936 case X_QueryExtension:
2937 return !tvb_bytes_exist(tvb, offset, 6) || length == 2 + rounded4(tvb_get_guint16(tvb, offset + 4, encoding));
2938
2939 case X_ChangeProperty:
2940 {
2941 int multiplier, type;
2942 if (!tvb_bytes_exist(tvb, offset, 17)) return TRUE;
2943 type = tvb_get_guint8(tvb, 16);
2944 if (type != 8 && type != 16 && type != 32) return FALSE;
2945 multiplier = type == 8 ? 1 : type == 16 ? 2 : 4;
2946 if (!tvb_bytes_exist(tvb, offset, 24)) return TRUE;
2947 return length == 6 + rounded4(tvb_get_guint32(tvb, offset + 20, encoding) * multiplier);
2948 }
2949
2950 case X_DeleteProperty:
2951 case X_UngrabButton:
2952 case X_UngrabKey:
2953 case X_SetInputFocus:
2954 case X_CopyColormapAndFree:
2955 case X_AllocColorCells:
2956 case X_QueryBestSize:
2957 case X_ChangePointerControl:
2958 case X_SetScreenSaver:
2959 return length == 3;
2960
2961 case X_GetProperty:
2962 case X_ConvertSelection:
2963 case X_GrabPointer:
2964 case X_GrabButton:
2965 case X_WarpPointer:
2966 return length == 6;
2967
2968 case X_SendEvent:
2969 return length == 11;
2970
2971 case X_GrabServer:
2972 case X_UngrabServer:
2973 case X_GetInputFocus:
2974 case X_QueryKeymap:
2975 case X_GetFontPath:
2976 case X_ListExtensions:
2977 case X_GetKeyboardControl:
2978 case X_Bell:
2979 case X_GetPointerControl:
2980 case X_GetScreenSaver:
2981 case X_ListHosts:
2982 case X_SetAccessControl:
2983 case X_SetCloseDownMode:
2984 case X_ForceScreenSaver:
2985 case X_GetPointerMapping:
2986 case X_GetModifierMapping:
2987 return length == 1;
2988
2989 case X_OpenFont:
2990 case X_AllocNamedColor:
2991 case X_LookupColor:
2992 return !tvb_bytes_exist(tvb, offset, 10) || length == 3 + rounded4(tvb_get_guint16(tvb, offset + 8, encoding));
2993
2994 case X_QueryTextExtents:
2995 return length >= 2;
2996
2997 case X_ListFonts:
2998 case X_ListFontsWithInfo:
2999 case X_ChangeHosts:
3000 return !tvb_bytes_exist(tvb, offset, 8) || length == 2 + rounded4(tvb_get_guint16(tvb, offset + 6, encoding));
3001
3002 case X_SetFontPath:
3003 if (length < 2) return FALSE;
3004 if (!tvb_bytes_exist(tvb, offset, 8)) return TRUE;
3005 return listOfStringLengthConsistent(tvb, offset + 8, (length - 2) * 4, tvb_get_guint16(tvb, offset + 4, encoding));
3006
3007 case X_CreateGC:
3008 return !tvb_bytes_exist(tvb, offset, 16) || length == 4 + numberOfBitSet(tvb, offset + 12, 4);
3009
3010 case X_SetDashes:
3011 return !tvb_bytes_exist(tvb, offset, 12) || length == 3 + rounded4(tvb_get_guint16(tvb, offset + 10, encoding));
3012
3013 case X_SetClipRectangles:
3014 case X_PolySegment:
3015 case X_PolyRectangle:
3016 case X_PolyFillRectangle:
3017 return length >= 3 && (length - 3) % 2 == 0;
3018
3019 case X_CopyArea:
3020 return length == 7;
3021
3022 case X_CopyPlane:
3023 case X_CreateCursor:
3024 case X_CreateGlyphCursor:
3025 return length == 8;
3026
3027 case X_PolyPoint:
3028 case X_PolyLine:
3029 case X_FreeColors:
3030 return length >= 3;
3031
3032 case X_PolyArc:
3033 case X_PolyFillArc:
3034 return length >= 3 && (length - 3) % 3 == 0;
3035
3036 case X_FillPoly:
3037 case X_ImageText8:
3038 return length >= 4;
3039
3040 case X_PutImage:
3041 return length >= 6;
3042
3043 case X_GetImage:
3044 case X_RecolorCursor:
3045 return length == 5;
3046
3047 case X_PolyText8:
3048 if (length < 4) return FALSE;
3049 return TRUE; /* We don't perform many controls on this one */
3050
3051 case X_PolyText16:
3052 if (length < 4) return FALSE;
3053 return TRUE; /* We don't perform many controls on this one */
3054
3055 case X_ImageText16:
3056 return length >= 4;
3057
3058 case X_StoreColors:
3059 return length > 2 && (length - 2) % 3 == 0;
3060
3061 case X_StoreNamedColor:
3062 return !tvb_bytes_exist(tvb, offset, 14) || length == 4 + rounded4(tvb_get_guint16(tvb, offset + 12, encoding));
3063
3064 case X_QueryColors:
3065 return length >= 2;
3066
3067 case X_ChangeKeyboardMapping:
3068 return !tvb_bytes_exist(tvb, offset, 6) || length == 2 + tvb_get_guint8(tvb, 1) * tvb_get_guint8(tvb, 5);
3069
3070 case X_ChangeKeyboardControl:
3071 return !tvb_bytes_exist(tvb, offset, 6) || length == 2 + numberOfBitSet(tvb, offset + 4, 2);
3072
3073 case X_RotateProperties:
3074 return !tvb_bytes_exist(tvb, offset, 10) || length == 3 + tvb_get_guint16(tvb, offset + 8, encoding);
3075
3076 case X_SetPointerMapping:
3077 return length == 1 + rounded4(tvb_get_guint8(tvb, 1));
3078
3079 case X_SetModifierMapping:
3080 return length == 1 + tvb_get_guint8(tvb, 1) * 2;
3081
3082 case X_NoOperation:
3083 return length >= 1;
3084
3085 default:
3086 return TRUE;
3087 }
3088 }
3089
3090 /* -1 means doesn't match, +1 means match, 0 means don't know */
3091
x_endian_match(tvbuff_t * tvb,int encoding)3092 static int x_endian_match(tvbuff_t *tvb, int encoding)
3093 {
3094 int offset, nextoffset;
3095 int atLeastOne = 0;
3096
3097 for(offset = 0; tvb_bytes_exist(tvb, offset, 4); offset = nextoffset) {
3098 int length;
3099 length = tvb_get_guint16(tvb, offset + 2, encoding);
3100 if (!length)
3101 return -1;
3102 nextoffset = offset + length * 4;
3103 if (!consistentWithOrder(length, tvb, offset, encoding))
3104 return -1;
3105 atLeastOne = 1;
3106 }
3107 return atLeastOne;
3108 }
3109
3110 static guint
guess_byte_ordering(tvbuff_t * tvb,packet_info * pinfo,x11_conv_data_t * state)3111 guess_byte_ordering(tvbuff_t *tvb, packet_info *pinfo,
3112 x11_conv_data_t *state)
3113 {
3114 /* With X the client gives the byte ordering for the protocol,
3115 and the port on the server tells us we're speaking X. */
3116
3117 int le, be;
3118 guint decision;
3119
3120 if (state->byte_order == ENC_BIG_ENDIAN)
3121 return ENC_BIG_ENDIAN; /* known to be big-endian */
3122 else if (state->byte_order == ENC_LITTLE_ENDIAN)
3123 return ENC_LITTLE_ENDIAN; /* known to be little-endian */
3124
3125 if (pinfo->srcport == pinfo->match_uint) {
3126 /*
3127 * This is a reply or event; we don't try to guess the
3128 * byte order on it for now.
3129 */
3130 return ENC_LITTLE_ENDIAN;
3131 }
3132
3133 le = x_endian_match(tvb, ENC_LITTLE_ENDIAN);
3134 be = x_endian_match(tvb, ENC_BIG_ENDIAN);
3135
3136 if (le == be) {
3137 /* We have no reason to believe it's little- rather than
3138 big-endian, so we guess the shortest length is the
3139 right one.
3140 */
3141 if (!tvb_bytes_exist(tvb, 0, 4))
3142 /* Not even a way to get the length. We're biased
3143 toward little endianness here (essentially the
3144 x86 world right now). Decoding won't go very far
3145 anyway.
3146 */
3147 decision = ENC_LITTLE_ENDIAN;
3148 else {
3149 if (tvb_get_letohs(tvb, 2) <= tvb_get_ntohs(tvb, 2))
3150 decision = ENC_LITTLE_ENDIAN;
3151 else
3152 decision = ENC_BIG_ENDIAN;
3153 }
3154 } else {
3155 if (le >= be)
3156 decision = ENC_LITTLE_ENDIAN;
3157 else
3158 decision = ENC_BIG_ENDIAN;
3159 }
3160
3161 if ((le < 0 && be > 0) || (le > 0 && be < 0)) {
3162 /*
3163 * Remember the decision.
3164 */
3165 state->byte_order = decision;
3166 }
3167
3168 return decision;
3169 }
3170
3171 /************************************************************************
3172 *** ***
3173 *** D E C O D I N G O N E P A C K E T ***
3174 *** ***
3175 ************************************************************************/
3176
3177 /*
3178 * Decode an initial connection request.
3179 */
dissect_x11_initial_conn(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,x11_conv_data_t * state,guint byte_order)3180 static void dissect_x11_initial_conn(tvbuff_t *tvb, packet_info *pinfo,
3181 proto_tree *tree, x11_conv_data_t *state, guint byte_order)
3182 {
3183 int offset = 0;
3184 int *offsetp = &offset;
3185 proto_item *ti;
3186 proto_tree *t;
3187 guint16 auth_proto_name_length, auth_proto_data_length;
3188 gint left;
3189
3190 ti = proto_tree_add_item(tree, proto_x11, tvb, 0, -1, ENC_NA);
3191 proto_item_append_text(ti, ", Request, Initial connection request");
3192 t = proto_item_add_subtree(ti, ett_x11);
3193
3194 CARD8(byte_order);
3195 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3196 *offsetp += 1;
3197 CARD16(protocol_major_version);
3198 CARD16(protocol_minor_version);
3199 auth_proto_name_length = CARD16(authorization_protocol_name_length);
3200 auth_proto_data_length = CARD16(authorization_protocol_data_length);
3201 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
3202 *offsetp += 2;
3203
3204 if (auth_proto_name_length != 0) {
3205 STRING8(authorization_protocol_name, auth_proto_name_length);
3206 offset = ROUND_LENGTH(offset);
3207 }
3208
3209 if (auth_proto_data_length != 0) {
3210 STRING8(authorization_protocol_data, auth_proto_data_length);
3211 offset = ROUND_LENGTH(offset);
3212 }
3213
3214 if ((left = tvb_reported_length_remaining(tvb, offset)) > 0)
3215 proto_tree_add_item(t, hf_x11_undecoded, tvb, offset, left,
3216 ENC_NA);
3217
3218 /*
3219 * This is the initial connection request...
3220 */
3221 state->iconn_frame = pinfo->num;
3222
3223 /*
3224 * ...and we're expecting a reply to it.
3225 */
3226 state->sequencenumber = 0;
3227 wmem_map_insert(state->seqtable, GINT_TO_POINTER(state->sequencenumber),
3228 (int *)INITIAL_CONN);
3229 }
3230
dissect_x11_initial_reply(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,const char _U_ * sep,x11_conv_data_t * state,guint byte_order)3231 static void dissect_x11_initial_reply(tvbuff_t *tvb, packet_info *pinfo,
3232 proto_tree *tree, const char _U_ *sep, x11_conv_data_t *state,
3233 guint byte_order)
3234 {
3235 int offset = 0, *offsetp = &offset, left;
3236 unsigned char success;
3237 int length_of_vendor;
3238 int length_of_reason;
3239 int number_of_formats_in_pixmap_formats;
3240 int number_of_screens_in_roots;
3241 int unused;
3242 proto_item *ti;
3243 proto_tree *t;
3244
3245 ti = proto_tree_add_item(tree, proto_x11, tvb, 0, -1, ENC_NA);
3246 proto_item_append_text(ti, ", Reply, Initial connection reply");
3247 t = proto_item_add_subtree(ti, ett_x11);
3248
3249 state->iconn_reply = pinfo->num;
3250 success = INT8(success);
3251 if (success) {
3252 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3253 *offsetp += 1;
3254 length_of_reason = 0;
3255 }
3256 else {
3257 length_of_reason = INT8(length_of_reason);
3258 }
3259
3260 INT16(protocol_major_version);
3261 INT16(protocol_minor_version);
3262 INT16(replylength);
3263 if (success) {
3264 INT32(release_number);
3265 INT32(resource_id_base);
3266 INT32(resource_id_mask);
3267 INT32(motion_buffer_size);
3268 length_of_vendor = INT16(length_of_vendor);
3269 INT16(maximum_request_length);
3270 number_of_screens_in_roots = INT8(number_of_screens_in_roots);
3271 number_of_formats_in_pixmap_formats = INT8(number_of_formats_in_pixmap_formats);
3272 INT8(image_byte_order);
3273 INT8(bitmap_format_bit_order);
3274 INT8(bitmap_format_scanline_unit);
3275 INT8(bitmap_format_scanline_pad);
3276 INT8(min_keycode);
3277 INT8(max_keycode);
3278 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 4, ENC_NA);
3279 *offsetp += 4;
3280 STRING8(vendor, length_of_vendor);
3281 unused = (4 - (length_of_vendor % 4)) % 4;
3282 if (unused > 0) {
3283 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, unused, ENC_NA);
3284 *offsetp += unused;
3285 }
3286 LISTofPIXMAPFORMAT(pixmap_format, number_of_formats_in_pixmap_formats);
3287 LISTofSCREEN(screen, number_of_screens_in_roots);
3288 } else {
3289 STRING8(reason, length_of_reason);
3290 }
3291
3292 if ((left = tvb_reported_length_remaining(tvb, offset)) > 0)
3293 UNDECODED(left);
3294
3295 }
3296
3297 typedef struct x11_reply_info {
3298 const guint8 minor;
3299 void (*dissect)(tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t, guint byte_order);
3300 } x11_reply_info;
3301
3302 typedef struct event_info {
3303 const gchar *name;
3304 void (*dissect)(tvbuff_t *tvb, int *offsetp, proto_tree *t, guint byte_order);
3305 } x11_event_info;
3306
3307 typedef struct x11_generic_event_info {
3308 const guint16 minor;
3309 void (*dissect)(tvbuff_t *tvb, int length, int *offsetp, proto_tree *t, guint byte_order);
3310 } x11_generic_event_info;
3311
set_handler(const char * name,void (* func)(tvbuff_t * tvb,packet_info * pinfo,int * offsetp,proto_tree * t,guint byte_order),const char ** errors,const x11_event_info * event_info,const x11_generic_event_info * genevent_info,const x11_reply_info * reply_info)3312 static void set_handler(const char *name, void (*func)(tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t, guint byte_order),
3313 const char **errors,
3314 const x11_event_info *event_info,
3315 const x11_generic_event_info *genevent_info,
3316 const x11_reply_info *reply_info)
3317 {
3318 wmem_map_insert(extension_table, (gpointer)name, (gpointer)func);
3319 wmem_map_insert(error_table, (gpointer)name, (gpointer)errors);
3320 wmem_map_insert(event_table, (gpointer)name, (gpointer)event_info);
3321 if (genevent_info)
3322 wmem_map_insert(genevent_table, (gpointer)name, (gpointer)genevent_info);
3323 wmem_map_insert(reply_table, (gpointer)name, (gpointer)reply_info);
3324 }
3325
3326 #include "x11-extension-errors.h"
3327 #include "x11-extension-implementation.h"
3328
tryExtension(int opcode,tvbuff_t * tvb,packet_info * pinfo,int * offsetp,proto_tree * t,x11_conv_data_t * state,guint byte_order)3329 static void tryExtension(int opcode, tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t,
3330 x11_conv_data_t *state, guint byte_order)
3331 {
3332 const gchar *extension;
3333 void (*func)(tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t, guint byte_order);
3334
3335 extension = try_val_to_str(opcode, state->opcode_vals);
3336 if (!extension)
3337 return;
3338
3339 func = (void (*)(tvbuff_t *, packet_info *, int *, proto_tree *, guint))wmem_map_lookup(extension_table, extension);
3340 if (func)
3341 func(tvb, pinfo, offsetp, t, byte_order);
3342 }
3343
tryExtensionReply(int opcode,tvbuff_t * tvb,packet_info * pinfo,int * offsetp,proto_tree * t,x11_conv_data_t * state,guint byte_order)3344 static void tryExtensionReply(int opcode, tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t,
3345 x11_conv_data_t *state, guint byte_order)
3346 {
3347 void (*func)(tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t, guint byte_order);
3348
3349 func = (void (*)(tvbuff_t *, packet_info *, int *, proto_tree *, guint))wmem_map_lookup(state->reply_funcs, GINT_TO_POINTER(opcode));
3350 if (func)
3351 func(tvb, pinfo, offsetp, t, byte_order);
3352 else
3353 REPLYCONTENTS_COMMON();
3354 }
3355
tryExtensionEvent(int event,tvbuff_t * tvb,int * offsetp,proto_tree * t,x11_conv_data_t * state,guint byte_order)3356 static void tryExtensionEvent(int event, tvbuff_t *tvb, int *offsetp, proto_tree *t,
3357 x11_conv_data_t *state, guint byte_order)
3358 {
3359 void (*func)(tvbuff_t *tvb, int *offsetp, proto_tree *t, guint byte_order);
3360
3361 func = (void (*)(tvbuff_t *, int *, proto_tree *, guint))wmem_map_lookup(state->eventcode_funcs, GINT_TO_POINTER(event));
3362 if (func)
3363 func(tvb, offsetp, t, byte_order);
3364 }
3365
tryGenericExtensionEvent(tvbuff_t * tvb,int * offsetp,proto_tree * t,x11_conv_data_t * state,guint byte_order)3366 static void tryGenericExtensionEvent(tvbuff_t *tvb, int *offsetp, proto_tree *t,
3367 x11_conv_data_t *state, guint byte_order)
3368 {
3369 const gchar *extname;
3370 int extension, length;
3371
3372 extension = tvb_get_guint8(tvb, *offsetp);
3373 (*offsetp)++;
3374 extname = try_val_to_str(extension, state->opcode_vals);
3375
3376 if (extname) {
3377 proto_tree_add_uint_format(t, hf_x11_extension, tvb, *offsetp, 1, extension, "extension: %d (%s)", extension, extname);
3378 } else {
3379 proto_tree_add_uint(t, hf_x11_extension, tvb, *offsetp, 1, extension);
3380 }
3381
3382 CARD16(event_sequencenumber);
3383
3384 length = REPLYLENGTH(eventlength);
3385 length = length * 4 + 32;
3386 *offsetp += 4;
3387
3388 if (extname) {
3389 x11_generic_event_info *info;
3390 info = (x11_generic_event_info *)wmem_map_lookup(genevent_table, extname);
3391
3392 if (info) {
3393 int i;
3394
3395 int opcode = tvb_get_guint16(tvb, *offsetp, byte_order);
3396
3397 for (i = 0; info[i].dissect != NULL; i++) {
3398 if (info[i].minor == opcode) {
3399 *offsetp += 2;
3400 info[i].dissect(tvb, length, offsetp, t, byte_order);
3401 return;
3402 }
3403 }
3404 }
3405 }
3406 CARD16(minor_opcode);
3407 }
3408
register_extension(x11_conv_data_t * state,value_string * vals_p,int major_opcode,unsigned int first_event,unsigned int first_error)3409 static void register_extension(x11_conv_data_t *state, value_string *vals_p,
3410 int major_opcode, unsigned int first_event, unsigned int first_error)
3411 {
3412 const char **error_string;
3413 x11_event_info *event_info;
3414 x11_reply_info *reply_info;
3415 int i;
3416
3417 vals_p->value = major_opcode;
3418
3419 error_string = (const char **)wmem_map_lookup(error_table, vals_p->strptr);
3420 while (error_string && *error_string && first_error <= LastExtensionError) {
3421 /* store string of extension error */
3422 for (i = 0; i <= LastExtensionError; i++) {
3423 if (state->errorcode_vals[i].strptr == NULL) {
3424 state->errorcode_vals[i].value = first_error;
3425 state->errorcode_vals[i].strptr = *error_string;
3426 break;
3427 } else if (state->errorcode_vals[i].value == first_error) {
3428 /* TODO: Warn about extensions stepping on each other */
3429 state->errorcode_vals[i].strptr = *error_string;
3430 break;
3431 }
3432 }
3433 first_error++;
3434 error_string++;
3435 }
3436
3437 event_info = (x11_event_info *)wmem_map_lookup(event_table, vals_p->strptr);
3438 while (event_info && event_info->name && first_event <= LastExtensionEvent) {
3439 /* store string of extension event */
3440 for (i = 0; i <= LastExtensionEvent; i++) {
3441 if (state->eventcode_vals[i].strptr == NULL) {
3442 state->eventcode_vals[i].value = first_event;
3443 state->eventcode_vals[i].strptr = event_info->name;
3444 break;
3445 } else if (state->eventcode_vals[i].value == first_event) {
3446 /* TODO: Warn about extensions stepping on each other */
3447 state->eventcode_vals[i].strptr = event_info->name;
3448 break;
3449 }
3450 }
3451
3452 /* store event decode function */
3453 wmem_map_insert(state->eventcode_funcs, GINT_TO_POINTER(first_event), (gpointer)event_info->dissect);
3454
3455 first_event++;
3456 event_info++;
3457 }
3458
3459 reply_info = (x11_reply_info *)wmem_map_lookup(reply_table, vals_p->strptr);
3460 if (reply_info)
3461 for (i = 0; reply_info[i].dissect; i++)
3462 wmem_map_insert(state->reply_funcs,
3463 GINT_TO_POINTER(major_opcode | (reply_info[i].minor << 8)),
3464 (gpointer)reply_info[i].dissect);
3465 }
3466
3467
dissect_x11_request(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,const char * sep,x11_conv_data_t * state,guint byte_order)3468 static void dissect_x11_request(tvbuff_t *tvb, packet_info *pinfo,
3469 proto_tree *tree, const char *sep, x11_conv_data_t *state,
3470 guint byte_order)
3471 {
3472 int offset = 0;
3473 int *offsetp = &offset;
3474 int query_ext_offset;
3475 int next_offset;
3476 proto_item *ti;
3477 proto_tree *t;
3478 int length, opcode, i;
3479 guint8 v8, v8_2, v8_3;
3480 guint16 v16;
3481 guint32 v32;
3482 gint left;
3483 gchar *name;
3484
3485 query_ext_offset = 2; /* "opcode" and "unused" */
3486
3487 length = tvb_get_guint16(tvb, query_ext_offset, byte_order) * 4;
3488 query_ext_offset += 2;
3489
3490 if (length == 0) {
3491 /* BIG-REQUESTS extension */
3492 length = tvb_get_guint32(tvb, query_ext_offset, byte_order);
3493 if ((gint64)length * 4 > G_MAXINT32)
3494 return;
3495 length *= 4;
3496 query_ext_offset += 4;
3497 }
3498
3499 if (length < 4) {
3500 /* Bogus message length? */
3501 return;
3502 }
3503
3504 next_offset = offset + length;
3505
3506 ti = proto_tree_add_item(tree, proto_x11, tvb, 0, -1, ENC_NA);
3507 t = proto_item_add_subtree(ti, ett_x11);
3508
3509 if (!pinfo->fd->visited)
3510 ++state->sequencenumber;
3511
3512 OPCODE();
3513
3514 col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s", sep,
3515 val_to_str(opcode, state->opcode_vals,
3516 "<Unknown opcode %d>"));
3517
3518 proto_item_append_text(ti, ", Request, opcode: %d (%s)",
3519 opcode, val_to_str(opcode, state->opcode_vals,
3520 "<Unknown opcode %d>"));
3521
3522 /*
3523 * Does this request expect a reply?
3524 */
3525 switch(opcode) {
3526
3527 case X_QueryExtension:
3528
3529 /* necessary processing even if tree == NULL */
3530
3531 v16 = tvb_get_guint16(tvb, query_ext_offset, byte_order);
3532 query_ext_offset += 2;
3533 /* Some unused bytes */
3534 query_ext_offset += 2;
3535 name = tvb_get_string_enc(wmem_file_scope(), tvb, query_ext_offset, v16, ENC_ASCII);
3536
3537 /* store string of extension, opcode will be set at reply */
3538 i = 0;
3539 while(i < MAX_OPCODES) {
3540 if (state->opcode_vals[i].strptr == NULL) {
3541 state->opcode_vals[i].strptr = name;
3542 state->opcode_vals[i].value = -1;
3543 wmem_map_insert(state->valtable,
3544 GINT_TO_POINTER(state->sequencenumber),
3545 (int *)&state->opcode_vals[i]);
3546 break;
3547 } else if (strcmp(state->opcode_vals[i].strptr,
3548 name) == 0) {
3549 wmem_map_insert(state->valtable,
3550 GINT_TO_POINTER(state->sequencenumber),
3551 (int *)&state->opcode_vals[i]);
3552 break;
3553 }
3554 i++;
3555 }
3556
3557 /* QueryExtension expects a reply, fall through */
3558 /* FALLTHROUGH */
3559 case X_AllocColor:
3560 case X_AllocColorCells:
3561 case X_AllocColorPlanes:
3562 case X_AllocNamedColor:
3563 case X_GetAtomName:
3564 case X_GetFontPath:
3565 case X_GetGeometry:
3566 case X_GetImage:
3567 case X_GetInputFocus:
3568 case X_GetKeyboardControl:
3569 case X_GetKeyboardMapping:
3570 case X_GetModifierMapping:
3571 case X_GetMotionEvents:
3572 case X_GetPointerControl:
3573 case X_GetPointerMapping:
3574 case X_GetProperty:
3575 case X_GetScreenSaver:
3576 case X_GetSelectionOwner:
3577 case X_GetWindowAttributes:
3578 case X_GrabKeyboard:
3579 case X_GrabPointer:
3580 case X_InternAtom:
3581 case X_ListExtensions:
3582 case X_ListFonts:
3583 case X_ListFontsWithInfo:
3584 case X_ListHosts:
3585 case X_ListInstalledColormaps:
3586 case X_ListProperties:
3587 case X_LookupColor:
3588 case X_QueryBestSize:
3589 case X_QueryColors:
3590 case X_QueryFont:
3591 case X_QueryKeymap:
3592 case X_QueryPointer:
3593 case X_QueryTextExtents:
3594 case X_QueryTree:
3595 case X_SetModifierMapping:
3596 case X_SetPointerMapping:
3597 case X_TranslateCoords:
3598 /*
3599 * Those requests expect a reply.
3600 */
3601 wmem_map_insert(state->seqtable,
3602 GINT_TO_POINTER(state->sequencenumber),
3603 GINT_TO_POINTER(opcode));
3604
3605 break;
3606
3607 default:
3608 /*
3609 * With Extension, we don't know, so assume there could be one
3610 */
3611 if (opcode >= X_FirstExtension && opcode <= X_LastExtension) {
3612 guint32 minor;
3613 minor = tvb_get_guint8(tvb, 1);
3614
3615 wmem_map_insert(state->seqtable,
3616 GINT_TO_POINTER(state->sequencenumber),
3617 GINT_TO_POINTER(opcode | (minor << 8)));
3618 }
3619
3620 /*
3621 * No reply is expected from any other request.
3622 */
3623 break;
3624 }
3625
3626 if (tree == NULL)
3627 return;
3628
3629 switch(opcode) {
3630
3631 case X_CreateWindow:
3632 CARD8(depth);
3633 requestLength(tvb, offsetp, t, byte_order);
3634 WINDOW(wid);
3635 WINDOW(parent);
3636 INT16(x);
3637 INT16(y);
3638 CARD16(width);
3639 CARD16(height);
3640 CARD16(border_width);
3641 ENUM16(window_class);
3642 VISUALID(visual);
3643 windowAttributes(tvb, offsetp, t, byte_order);
3644 break;
3645
3646 case X_ChangeWindowAttributes:
3647 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3648 *offsetp += 1;
3649 requestLength(tvb, offsetp, t, byte_order);
3650 WINDOW(window);
3651 windowAttributes(tvb, offsetp, t, byte_order);
3652 break;
3653
3654 case X_GetWindowAttributes:
3655 case X_DestroyWindow:
3656 case X_DestroySubwindows:
3657 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3658 *offsetp += 1;
3659 requestLength(tvb, offsetp, t, byte_order);
3660 WINDOW(window);
3661 break;
3662
3663 case X_ChangeSaveSet:
3664 ENUM8(save_set_mode);
3665 requestLength(tvb, offsetp, t, byte_order);
3666 WINDOW(window);
3667 break;
3668
3669 case X_ReparentWindow:
3670 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3671 *offsetp += 1;
3672 requestLength(tvb, offsetp, t, byte_order);
3673 WINDOW(window);
3674 WINDOW(parent);
3675 INT16(x);
3676 INT16(y);
3677 break;
3678
3679 case X_MapWindow:
3680 case X_MapSubwindows:
3681 case X_UnmapWindow:
3682 case X_UnmapSubwindows:
3683 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3684 *offsetp += 1;
3685 requestLength(tvb, offsetp, t, byte_order);
3686 WINDOW(window);
3687 break;
3688
3689 case X_ConfigureWindow:
3690 {
3691 guint16 bitmask16;
3692 static int * const window_attributes_flags[] = {
3693 &hf_x11_window_value_mask_background_pixmap,
3694 &hf_x11_window_value_mask_background_pixel,
3695 &hf_x11_window_value_mask_border_pixmap,
3696 &hf_x11_window_value_mask_border_pixel,
3697 &hf_x11_window_value_mask_bit_gravity,
3698 &hf_x11_window_value_mask_win_gravity,
3699 &hf_x11_window_value_mask_backing_store,
3700 &hf_x11_window_value_mask_backing_planes,
3701 &hf_x11_window_value_mask_backing_pixel,
3702 &hf_x11_window_value_mask_override_redirect,
3703 &hf_x11_window_value_mask_save_under,
3704 &hf_x11_window_value_mask_event_mask,
3705 &hf_x11_window_value_mask_do_not_propagate_mask,
3706 &hf_x11_window_value_mask_colormap,
3707 &hf_x11_window_value_mask_cursor,
3708 NULL
3709 };
3710
3711 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3712 *offsetp += 1;
3713 requestLength(tvb, offsetp, t, byte_order);
3714 proto_tree_add_item(t, hf_x11_window, tvb, *offsetp, 1, byte_order);
3715 *offsetp += 4;
3716 bitmask16 = tvb_get_guint16(tvb, *offsetp, byte_order);
3717 proto_tree_add_bitmask(t, tvb, *offsetp, hf_x11_configure_window_mask, ett_x11_configure_window_mask, window_attributes_flags, byte_order);
3718 *offsetp += 2;
3719 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
3720 *offsetp += 2;
3721 if (bitmask16 & 0x0001) {
3722 proto_tree_add_item(t, hf_x11_x, tvb, *offsetp, 2, byte_order);
3723 *offsetp += 2;
3724 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
3725 *offsetp += 2;
3726 }
3727 if (bitmask16 & 0x0002) {
3728 proto_tree_add_item(t, hf_x11_y, tvb, *offsetp, 2, byte_order);
3729 *offsetp += 2;
3730 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
3731 *offsetp += 2;
3732 }
3733 if (bitmask16 & 0x0004) {
3734 proto_tree_add_item(t, hf_x11_width, tvb, *offsetp, 2, byte_order);
3735 *offsetp += 2;
3736 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
3737 *offsetp += 2;
3738 }
3739 if (bitmask16 & 0x0008) {
3740 proto_tree_add_item(t, hf_x11_height, tvb, *offsetp, 2, byte_order);
3741 *offsetp += 2;
3742 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
3743 *offsetp += 2;
3744 }
3745 if (bitmask16 & 0x0010) {
3746 proto_tree_add_item(t, hf_x11_border_width, tvb, *offsetp, 2, byte_order);
3747 *offsetp += 2;
3748 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
3749 *offsetp += 2;
3750 }
3751 if (bitmask16 & 0x0020) {
3752 proto_tree_add_item(t, hf_x11_sibling, tvb, *offsetp, 4, byte_order);
3753 *offsetp += 4;
3754 }
3755 if (bitmask16 & 0x0040) {
3756 proto_tree_add_item(t, hf_x11_stack_mode, tvb, *offsetp, 1, byte_order);
3757 *offsetp += 1;
3758 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
3759 *offsetp += 3;
3760 }
3761 if (next_offset - *offsetp > 0) {
3762 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, next_offset - *offsetp, ENC_NA);
3763 *offsetp = next_offset;
3764 }
3765 }
3766 break;
3767
3768 case X_CirculateWindow:
3769 ENUM8(direction);
3770 requestLength(tvb, offsetp, t, byte_order);
3771 WINDOW(window);
3772 break;
3773
3774 case X_GetGeometry:
3775 case X_QueryTree:
3776 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3777 *offsetp += 1;
3778 requestLength(tvb, offsetp, t, byte_order);
3779 DRAWABLE(drawable);
3780 break;
3781
3782 case X_InternAtom:
3783 BOOL(only_if_exists);
3784 requestLength(tvb, offsetp, t, byte_order);
3785 v16 = FIELD16(name_length);
3786 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
3787 *offsetp += 2;
3788 STRING8(name, v16);
3789 PAD();
3790 break;
3791
3792 case X_GetAtomName:
3793 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3794 *offsetp += 1;
3795 requestLength(tvb, offsetp, t, byte_order);
3796 ATOM(atom);
3797 break;
3798
3799 case X_ChangeProperty:
3800 ENUM8(mode);
3801 requestLength(tvb, offsetp, t, byte_order);
3802 WINDOW(window);
3803 ATOM(property);
3804 ATOM(type);
3805 v8 = CARD8(format);
3806 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
3807 *offsetp += 3;
3808 v32 = CARD32(data_length);
3809 switch (v8) {
3810 case 8:
3811 if (v32)
3812 LISTofBYTE(data, v32);
3813 break;
3814 case 16:
3815 if (v32)
3816 LISTofCARD16(data16, v32 * 2);
3817 break;
3818 case 32:
3819 if (v32)
3820 LISTofCARD32(data32, v32 * 4);
3821 break;
3822 default:
3823 expert_add_info(pinfo, ti, &ei_x11_invalid_format);
3824 break;
3825 }
3826 PAD();
3827 break;
3828
3829 case X_DeleteProperty:
3830 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3831 *offsetp += 1;
3832 requestLength(tvb, offsetp, t, byte_order);
3833 WINDOW(window);
3834 ATOM(property);
3835 break;
3836
3837 case X_GetProperty:
3838 BOOL(delete);
3839 requestLength(tvb, offsetp, t, byte_order);
3840 WINDOW(window);
3841 ATOM(property);
3842 ATOM(get_property_type);
3843 CARD32(long_offset);
3844 CARD32(long_length);
3845 break;
3846
3847 case X_ListProperties:
3848 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3849 *offsetp += 1;
3850 requestLength(tvb, offsetp, t, byte_order);
3851 WINDOW(window);
3852 break;
3853
3854 case X_SetSelectionOwner:
3855 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3856 *offsetp += 1;
3857 requestLength(tvb, offsetp, t, byte_order);
3858 WINDOW(owner);
3859 ATOM(selection);
3860 TIMESTAMP(time);
3861 break;
3862
3863 case X_GetSelectionOwner:
3864 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3865 *offsetp += 1;
3866 requestLength(tvb, offsetp, t, byte_order);
3867 ATOM(selection);
3868 break;
3869
3870 case X_ConvertSelection:
3871 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3872 *offsetp += 1;
3873 requestLength(tvb, offsetp, t, byte_order);
3874 WINDOW(requestor);
3875 ATOM(selection);
3876 ATOM(target);
3877 ATOM(property);
3878 TIMESTAMP(time);
3879 break;
3880
3881 case X_SendEvent:
3882 BOOL(propagate);
3883 requestLength(tvb, offsetp, t, byte_order);
3884 WINDOW(destination);
3885 SETofEVENT(event_mask);
3886 EVENT();
3887 break;
3888
3889 case X_GrabPointer:
3890 BOOL(owner_events);
3891 requestLength(tvb, offsetp, t, byte_order);
3892 WINDOW(grab_window);
3893 SETofPOINTEREVENT(pointer_event_mask);
3894 ENUM8(pointer_mode);
3895 ENUM8(keyboard_mode);
3896 WINDOW(confine_to);
3897 CURSOR(cursor);
3898 TIMESTAMP(time);
3899 break;
3900
3901 case X_UngrabPointer:
3902 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3903 *offsetp += 1;
3904 requestLength(tvb, offsetp, t, byte_order);
3905 TIMESTAMP(time);
3906 break;
3907
3908 case X_GrabButton:
3909 BOOL(owner_events);
3910 requestLength(tvb, offsetp, t, byte_order);
3911 WINDOW(grab_window);
3912 SETofPOINTEREVENT(event_mask);
3913 ENUM8(pointer_mode);
3914 ENUM8(keyboard_mode);
3915 WINDOW(confine_to);
3916 CURSOR(cursor);
3917 BUTTON(button);
3918 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3919 *offsetp += 1;
3920 SETofKEYMASK(modifiers);
3921 break;
3922
3923 case X_UngrabButton:
3924 BUTTON(button);
3925 requestLength(tvb, offsetp, t, byte_order);
3926 WINDOW(grab_window);
3927 SETofKEYMASK(modifiers);
3928 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
3929 *offsetp += 2;
3930 break;
3931
3932 case X_ChangeActivePointerGrab:
3933 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3934 *offsetp += 1;
3935 requestLength(tvb, offsetp, t, byte_order);
3936 CURSOR(cursor);
3937 TIMESTAMP(time);
3938 SETofPOINTEREVENT(event_mask);
3939 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
3940 *offsetp += 2;
3941 break;
3942
3943 case X_GrabKeyboard:
3944 BOOL(owner_events);
3945 requestLength(tvb, offsetp, t, byte_order);
3946 WINDOW(grab_window);
3947 TIMESTAMP(time);
3948 ENUM8(pointer_mode);
3949 ENUM8(keyboard_mode);
3950 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
3951 *offsetp += 2;
3952 break;
3953
3954 case X_UngrabKeyboard:
3955 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3956 *offsetp += 1;
3957 requestLength(tvb, offsetp, t, byte_order);
3958 TIMESTAMP(time);
3959 break;
3960
3961 case X_GrabKey:
3962 BOOL(owner_events);
3963 requestLength(tvb, offsetp, t, byte_order);
3964 WINDOW(grab_window);
3965 SETofKEYMASK(modifiers);
3966 KEYCODE(key);
3967 ENUM8(pointer_mode);
3968 ENUM8(keyboard_mode);
3969 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
3970 *offsetp += 3;
3971 break;
3972
3973 case X_UngrabKey:
3974 KEYCODE(key);
3975 requestLength(tvb, offsetp, t, byte_order);
3976 WINDOW(grab_window);
3977 SETofKEYMASK(modifiers);
3978 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
3979 *offsetp += 2;
3980 break;
3981
3982 case X_AllowEvents:
3983 ENUM8(allow_events_mode);
3984 requestLength(tvb, offsetp, t, byte_order);
3985 TIMESTAMP(time);
3986 break;
3987
3988 case X_GrabServer:
3989 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3990 *offsetp += 1;
3991 requestLength(tvb, offsetp, t, byte_order);
3992 break;
3993
3994 case X_UngrabServer:
3995 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
3996 *offsetp += 1;
3997 requestLength(tvb, offsetp, t, byte_order);
3998 break;
3999
4000 case X_QueryPointer:
4001 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4002 *offsetp += 1;
4003 requestLength(tvb, offsetp, t, byte_order);
4004 WINDOW(window);
4005 break;
4006
4007 case X_GetMotionEvents:
4008 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4009 *offsetp += 1;
4010 requestLength(tvb, offsetp, t, byte_order);
4011 WINDOW(window);
4012 TIMESTAMP(start);
4013 TIMESTAMP(stop);
4014 break;
4015
4016 case X_TranslateCoords:
4017 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4018 *offsetp += 1;
4019 requestLength(tvb, offsetp, t, byte_order);
4020 WINDOW(src_window);
4021 WINDOW(dst_window);
4022 INT16(src_x);
4023 INT16(src_y);
4024 break;
4025
4026 case X_WarpPointer:
4027 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4028 *offsetp += 1;
4029 requestLength(tvb, offsetp, t, byte_order);
4030 WINDOW(warp_pointer_src_window);
4031 WINDOW(warp_pointer_dst_window);
4032 INT16(src_x);
4033 INT16(src_y);
4034 CARD16(src_width);
4035 CARD16(src_height);
4036 INT16(dst_x);
4037 INT16(dst_y);
4038 break;
4039
4040 case X_SetInputFocus:
4041 ENUM8(revert_to);
4042 requestLength(tvb, offsetp, t, byte_order);
4043 WINDOW(focus);
4044 TIMESTAMP(time);
4045 break;
4046
4047 case X_GetInputFocus:
4048 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4049 *offsetp += 1;
4050 requestLength(tvb, offsetp, t, byte_order);
4051 break;
4052
4053 case X_QueryKeymap:
4054 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4055 *offsetp += 1;
4056 requestLength(tvb, offsetp, t, byte_order);
4057 break;
4058
4059 case X_OpenFont:
4060 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4061 *offsetp += 1;
4062 requestLength(tvb, offsetp, t, byte_order);
4063 FONT(fid);
4064 v16 = FIELD16(name_length);
4065 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
4066 *offsetp += 2;
4067 STRING8(name, v16);
4068 PAD();
4069 break;
4070
4071 case X_CloseFont:
4072 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4073 *offsetp += 1;
4074 requestLength(tvb, offsetp, t, byte_order);
4075 FONT(font);
4076 break;
4077
4078 case X_QueryFont:
4079 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4080 *offsetp += 1;
4081 requestLength(tvb, offsetp, t, byte_order);
4082 FONTABLE(font);
4083 break;
4084
4085 case X_QueryTextExtents:
4086 v8 = BOOL(odd_length);
4087 requestLength(tvb, offsetp, t, byte_order);
4088 FONTABLE(font);
4089 STRING16(string16, (next_offset - offset - (v8 ? 2 : 0)) / 2);
4090 PAD();
4091 break;
4092
4093 case X_ListFonts:
4094 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4095 *offsetp += 1;
4096 requestLength(tvb, offsetp, t, byte_order);
4097 CARD16(max_names);
4098 v16 = FIELD16(pattern_length);
4099 STRING8(pattern, v16);
4100 PAD();
4101 break;
4102
4103 case X_ListFontsWithInfo:
4104 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4105 *offsetp += 1;
4106 requestLength(tvb, offsetp, t, byte_order);
4107 CARD16(max_names);
4108 v16 = FIELD16(pattern_length);
4109 STRING8(pattern, v16);
4110 PAD();
4111 break;
4112
4113 case X_SetFontPath:
4114 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4115 *offsetp += 1;
4116 requestLength(tvb, offsetp, t, byte_order);
4117 v16 = CARD16(str_number_in_path);
4118 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
4119 *offsetp += 2;
4120 LISTofSTRING8(path, v16);
4121 PAD();
4122 break;
4123
4124 case X_GetFontPath:
4125 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4126 *offsetp += 1;
4127 requestLength(tvb, offsetp, t, byte_order);
4128 break;
4129
4130 case X_CreatePixmap:
4131 CARD8(depth);
4132 requestLength(tvb, offsetp, t, byte_order);
4133 PIXMAP(pid);
4134 DRAWABLE(drawable);
4135 CARD16(width);
4136 CARD16(height);
4137 break;
4138
4139 case X_FreePixmap:
4140 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4141 *offsetp += 1;
4142 requestLength(tvb, offsetp, t, byte_order);
4143 PIXMAP(pixmap);
4144 break;
4145
4146 case X_CreateGC:
4147 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4148 *offsetp += 1;
4149 requestLength(tvb, offsetp, t, byte_order);
4150 GCONTEXT(cid);
4151 DRAWABLE(drawable);
4152 gcAttributes(tvb, offsetp, t, byte_order);
4153 break;
4154
4155 case X_ChangeGC:
4156 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4157 *offsetp += 1;
4158 requestLength(tvb, offsetp, t, byte_order);
4159 GCONTEXT(gc);
4160 gcAttributes(tvb, offsetp, t, byte_order);
4161 break;
4162
4163 case X_CopyGC:
4164 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4165 *offsetp += 1;
4166 requestLength(tvb, offsetp, t, byte_order);
4167 GCONTEXT(src_gc);
4168 GCONTEXT(dst_gc);
4169 gcMask(tvb, offsetp, t, byte_order);
4170 break;
4171
4172 case X_SetDashes:
4173 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4174 *offsetp += 1;
4175 requestLength(tvb, offsetp, t, byte_order);
4176 GCONTEXT(gc);
4177 CARD16(dash_offset);
4178 v16 = FIELD16(dashes_length);
4179 LISTofCARD8(dashes, v16);
4180 PAD();
4181 break;
4182
4183 case X_SetClipRectangles:
4184 ENUM8(ordering);
4185 requestLength(tvb, offsetp, t, byte_order);
4186 GCONTEXT(gc);
4187 INT16(clip_x_origin);
4188 INT16(clip_y_origin);
4189 LISTofRECTANGLE(rectangles);
4190 break;
4191
4192 case X_FreeGC:
4193 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4194 *offsetp += 1;
4195 requestLength(tvb, offsetp, t, byte_order);
4196 GCONTEXT(gc);
4197 break;
4198
4199 case X_ClearArea:
4200 BOOL(exposures);
4201 requestLength(tvb, offsetp, t, byte_order);
4202 WINDOW(window);
4203 INT16(x);
4204 INT16(y);
4205 CARD16(width);
4206 CARD16(height);
4207 break;
4208
4209 case X_CopyArea:
4210 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4211 *offsetp += 1;
4212 requestLength(tvb, offsetp, t, byte_order);
4213 DRAWABLE(src_drawable);
4214 DRAWABLE(dst_drawable);
4215 GCONTEXT(gc);
4216 INT16(src_x);
4217 INT16(src_y);
4218 INT16(dst_x);
4219 INT16(dst_y);
4220 CARD16(width);
4221 CARD16(height);
4222 break;
4223
4224 case X_CopyPlane:
4225 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4226 *offsetp += 1;
4227 requestLength(tvb, offsetp, t, byte_order);
4228 DRAWABLE(src_drawable);
4229 DRAWABLE(dst_drawable);
4230 GCONTEXT(gc);
4231 INT16(src_x);
4232 INT16(src_y);
4233 INT16(dst_x);
4234 INT16(dst_y);
4235 CARD16(width);
4236 CARD16(height);
4237 CARD32(bit_plane);
4238 break;
4239
4240 case X_PolyPoint:
4241 ENUM8(coordinate_mode);
4242 v16 = requestLength(tvb, offsetp, t, byte_order);
4243 DRAWABLE(drawable);
4244 GCONTEXT(gc);
4245 LISTofPOINT(points, v16 - 12);
4246 break;
4247
4248 case X_PolyLine:
4249 ENUM8(coordinate_mode);
4250 v16 = requestLength(tvb, offsetp, t, byte_order);
4251 DRAWABLE(drawable);
4252 GCONTEXT(gc);
4253 LISTofPOINT(points, v16 - 12);
4254 break;
4255
4256 case X_PolySegment:
4257 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4258 *offsetp += 1;
4259 requestLength(tvb, offsetp, t, byte_order);
4260 DRAWABLE(drawable);
4261 GCONTEXT(gc);
4262 LISTofSEGMENT(segments);
4263 break;
4264
4265 case X_PolyRectangle:
4266 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4267 *offsetp += 1;
4268 requestLength(tvb, offsetp, t, byte_order);
4269 DRAWABLE(drawable);
4270 GCONTEXT(gc);
4271 LISTofRECTANGLE(rectangles);
4272 break;
4273
4274 case X_PolyArc:
4275 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4276 *offsetp += 1;
4277 requestLength(tvb, offsetp, t, byte_order);
4278 DRAWABLE(drawable);
4279 GCONTEXT(gc);
4280 LISTofARC(arcs);
4281 break;
4282
4283 case X_FillPoly:
4284 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4285 *offsetp += 1;
4286 v16 = requestLength(tvb, offsetp, t, byte_order);
4287 DRAWABLE(drawable);
4288 GCONTEXT(gc);
4289 ENUM8(shape);
4290 ENUM8(coordinate_mode);
4291 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
4292 *offsetp += 2;
4293 LISTofPOINT(points, v16 - 16);
4294 break;
4295
4296 case X_PolyFillRectangle:
4297 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4298 *offsetp += 1;
4299 requestLength(tvb, offsetp, t, byte_order);
4300 DRAWABLE(drawable);
4301 GCONTEXT(gc);
4302 LISTofRECTANGLE(rectangles);
4303 break;
4304
4305 case X_PolyFillArc:
4306 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4307 *offsetp += 1;
4308 requestLength(tvb, offsetp, t, byte_order);
4309 DRAWABLE(drawable);
4310 GCONTEXT(gc);
4311 LISTofARC(arcs);
4312 break;
4313
4314 case X_PutImage:
4315 ENUM8(image_format);
4316 v16 = requestLength(tvb, offsetp, t, byte_order);
4317 DRAWABLE(drawable);
4318 GCONTEXT(gc);
4319 CARD16(width);
4320 CARD16(height);
4321 INT16(dst_x);
4322 INT16(dst_y);
4323 CARD8(left_pad);
4324 CARD8(depth);
4325 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
4326 *offsetp += 2;
4327 LISTofBYTE(data, v16 - 24);
4328 PAD();
4329 break;
4330
4331 case X_GetImage:
4332 ENUM8(image_pixmap_format);
4333 requestLength(tvb, offsetp, t, byte_order);
4334 DRAWABLE(drawable);
4335 INT16(x);
4336 INT16(y);
4337 CARD16(width);
4338 CARD16(height);
4339 CARD32(plane_mask);
4340 break;
4341
4342 case X_PolyText8:
4343 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4344 *offsetp += 1;
4345 requestLength(tvb, offsetp, t, byte_order);
4346 DRAWABLE(drawable);
4347 GCONTEXT(gc);
4348 INT16(x);
4349 INT16(y);
4350 LISTofTEXTITEM8(items);
4351 PAD();
4352 break;
4353
4354 case X_PolyText16:
4355 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4356 *offsetp += 1;
4357 requestLength(tvb, offsetp, t, byte_order);
4358 DRAWABLE(drawable);
4359 GCONTEXT(gc);
4360 INT16(x);
4361 INT16(y);
4362 LISTofTEXTITEM16(items);
4363 PAD();
4364 break;
4365
4366 case X_ImageText8:
4367 v8 = FIELD8(string_length);
4368 requestLength(tvb, offsetp, t, byte_order);
4369 DRAWABLE(drawable);
4370 GCONTEXT(gc);
4371 INT16(x);
4372 INT16(y);
4373 STRING8(string, v8);
4374 PAD();
4375 break;
4376
4377 case X_ImageText16:
4378 v8 = FIELD8(string_length);
4379 requestLength(tvb, offsetp, t, byte_order);
4380 DRAWABLE(drawable);
4381 GCONTEXT(gc);
4382 INT16(x);
4383 INT16(y);
4384 STRING16(string16, v8);
4385 PAD();
4386 break;
4387
4388 case X_CreateColormap:
4389 ENUM8(alloc);
4390 requestLength(tvb, offsetp, t, byte_order);
4391 COLORMAP(mid);
4392 WINDOW(window);
4393 VISUALID(visual);
4394 break;
4395
4396 case X_FreeColormap:
4397 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4398 *offsetp += 1;
4399 requestLength(tvb, offsetp, t, byte_order);
4400 COLORMAP(cmap);
4401 break;
4402
4403 case X_CopyColormapAndFree:
4404 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4405 *offsetp += 1;
4406 requestLength(tvb, offsetp, t, byte_order);
4407 COLORMAP(mid);
4408 COLORMAP(src_cmap);
4409 break;
4410
4411 case X_InstallColormap:
4412 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4413 *offsetp += 1;
4414 requestLength(tvb, offsetp, t, byte_order);
4415 COLORMAP(cmap);
4416 break;
4417
4418 case X_UninstallColormap:
4419 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4420 *offsetp += 1;
4421 requestLength(tvb, offsetp, t, byte_order);
4422 COLORMAP(cmap);
4423 break;
4424
4425 case X_ListInstalledColormaps:
4426 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4427 *offsetp += 1;
4428 requestLength(tvb, offsetp, t, byte_order);
4429 WINDOW(window);
4430 break;
4431
4432 case X_AllocColor:
4433 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4434 *offsetp += 1;
4435 requestLength(tvb, offsetp, t, byte_order);
4436 COLORMAP(cmap);
4437 CARD16(red);
4438 CARD16(green);
4439 CARD16(blue);
4440 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
4441 *offsetp += 2;
4442 break;
4443
4444 case X_AllocNamedColor:
4445 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4446 *offsetp += 1;
4447 requestLength(tvb, offsetp, t, byte_order);
4448 COLORMAP(cmap);
4449 v16 = FIELD16(name_length);
4450 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
4451 *offsetp += 2;
4452 STRING8(name, v16);
4453 PAD();
4454 break;
4455
4456 case X_AllocColorCells:
4457 BOOL(contiguous);
4458 requestLength(tvb, offsetp, t, byte_order);
4459 COLORMAP(cmap);
4460 CARD16(colors);
4461 CARD16(planes);
4462 break;
4463
4464 case X_AllocColorPlanes:
4465 BOOL(contiguous);
4466 requestLength(tvb, offsetp, t, byte_order);
4467 COLORMAP(cmap);
4468 CARD16(colors);
4469 CARD16(reds);
4470 CARD16(greens);
4471 CARD16(blues);
4472 break;
4473
4474 case X_FreeColors:
4475 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4476 *offsetp += 1;
4477 v16 = requestLength(tvb, offsetp, t, byte_order);
4478 COLORMAP(cmap);
4479 CARD32(plane_mask);
4480 LISTofCARD32(pixels, v16 - 12);
4481 break;
4482
4483 case X_StoreColors:
4484 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4485 *offsetp += 1;
4486 v16 = requestLength(tvb, offsetp, t, byte_order);
4487 COLORMAP(cmap);
4488 LISTofCOLORITEM(color_items, v16 - 8);
4489 break;
4490
4491 case X_StoreNamedColor:
4492 COLOR_FLAGS(color);
4493 requestLength(tvb, offsetp, t, byte_order);
4494 COLORMAP(cmap);
4495 CARD32(pixel);
4496 v16 = FIELD16(name_length);
4497 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
4498 *offsetp += 2;
4499 STRING8(name, v16);
4500 PAD();
4501 break;
4502
4503 case X_QueryColors:
4504 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4505 *offsetp += 1;
4506 v16 = requestLength(tvb, offsetp, t, byte_order);
4507 COLORMAP(cmap);
4508 LISTofCARD32(pixels, v16 - 8);
4509 break;
4510
4511 case X_LookupColor:
4512 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4513 *offsetp += 1;
4514 requestLength(tvb, offsetp, t, byte_order);
4515 COLORMAP(cmap);
4516 v16 = FIELD16(name_length);
4517 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
4518 *offsetp += 2;
4519 STRING8(name, v16);
4520 PAD();
4521 break;
4522
4523 case X_CreateCursor:
4524 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4525 *offsetp += 1;
4526 requestLength(tvb, offsetp, t, byte_order);
4527 CURSOR(cid);
4528 PIXMAP(source_pixmap);
4529 PIXMAP(mask);
4530 CARD16(fore_red);
4531 CARD16(fore_green);
4532 CARD16(fore_blue);
4533 CARD16(back_red);
4534 CARD16(back_green);
4535 CARD16(back_blue);
4536 CARD16(x);
4537 CARD16(y);
4538 break;
4539
4540 case X_CreateGlyphCursor:
4541 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4542 *offsetp += 1;
4543 requestLength(tvb, offsetp, t, byte_order);
4544 CURSOR(cid);
4545 FONT(source_font);
4546 FONT(mask_font);
4547 CARD16(source_char);
4548 CARD16(mask_char);
4549 CARD16(fore_red);
4550 CARD16(fore_green);
4551 CARD16(fore_blue);
4552 CARD16(back_red);
4553 CARD16(back_green);
4554 CARD16(back_blue);
4555 break;
4556
4557 case X_FreeCursor:
4558 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4559 *offsetp += 1;
4560 requestLength(tvb, offsetp, t, byte_order);
4561 CURSOR(cursor);
4562 break;
4563
4564 case X_RecolorCursor:
4565 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4566 *offsetp += 1;
4567 requestLength(tvb, offsetp, t, byte_order);
4568 CURSOR(cursor);
4569 CARD16(fore_red);
4570 CARD16(fore_green);
4571 CARD16(fore_blue);
4572 CARD16(back_red);
4573 CARD16(back_green);
4574 CARD16(back_blue);
4575 break;
4576
4577 case X_QueryBestSize:
4578 ENUM8(class);
4579 requestLength(tvb, offsetp, t, byte_order);
4580 DRAWABLE(drawable);
4581 CARD16(width);
4582 CARD16(height);
4583 break;
4584
4585 case X_QueryExtension:
4586 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4587 *offsetp += 1;
4588 requestLength(tvb, offsetp, t, byte_order);
4589 v16 = FIELD16(name_length);
4590 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
4591 *offsetp += 2;
4592 STRING8(name, v16);
4593 PAD();
4594 break;
4595
4596 case X_ListExtensions:
4597 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4598 *offsetp += 1;
4599 requestLength(tvb, offsetp, t, byte_order);
4600 break;
4601
4602 case X_ChangeKeyboardMapping:
4603 v8 = FIELD8(keycode_count);
4604 requestLength(tvb, offsetp, t, byte_order);
4605 v8_2 = KEYCODE(first_keycode);
4606 v8_3 = FIELD8(keysyms_per_keycode);
4607 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
4608 *offsetp += 2;
4609 LISTofKEYSYM(keysyms, state->keycodemap, v8_2, v8, v8_3);
4610 break;
4611
4612 case X_GetKeyboardMapping:
4613 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4614 *offsetp += 1;
4615 requestLength(tvb, offsetp, t, byte_order);
4616 state->request.GetKeyboardMapping.first_keycode
4617 = KEYCODE(first_keycode);
4618 FIELD8(count);
4619 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
4620 *offsetp += 2;
4621 break;
4622
4623 case X_ChangeKeyboardControl:
4624 {
4625 guint32 bitmask32;
4626 static int * const keyboard_value_flags[] = {
4627 &hf_x11_keyboard_value_mask_key_click_percent,
4628 &hf_x11_keyboard_value_mask_bell_percent,
4629 &hf_x11_keyboard_value_mask_bell_pitch,
4630 &hf_x11_keyboard_value_mask_bell_duration,
4631 &hf_x11_keyboard_value_mask_led,
4632 &hf_x11_keyboard_value_mask_led_mode,
4633 &hf_x11_keyboard_value_mask_keyboard_key,
4634 &hf_x11_keyboard_value_mask_auto_repeat_mode,
4635 NULL
4636 };
4637
4638 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4639 *offsetp += 1;
4640 requestLength(tvb, offsetp, t, byte_order);
4641 bitmask32 = tvb_get_guint32(tvb, *offsetp, byte_order);
4642 proto_tree_add_bitmask(t, tvb, *offsetp, hf_x11_keyboard_value_mask, ett_x11_keyboard_value_mask, keyboard_value_flags, byte_order);
4643 *offsetp += 4;
4644 if (bitmask32 & 0x00000001) {
4645 proto_tree_add_item(t, hf_x11_key_click_percent, tvb, *offsetp, 1, byte_order);
4646 *offsetp += 1;
4647 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
4648 *offsetp += 3;
4649 }
4650 if (bitmask32 & 0x00000002) {
4651 proto_tree_add_item(t, hf_x11_bell_percent, tvb, *offsetp, 1, byte_order);
4652 *offsetp += 1;
4653 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
4654 *offsetp += 3;
4655 }
4656 if (bitmask32 & 0x00000004) {
4657 proto_tree_add_item(t, hf_x11_bell_pitch, tvb, *offsetp, 2, byte_order);
4658 *offsetp += 2;
4659 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
4660 *offsetp += 2;
4661 }
4662 if (bitmask32 & 0x00000008) {
4663 proto_tree_add_item(t, hf_x11_bell_duration, tvb, *offsetp, 2, byte_order);
4664 *offsetp += 2;
4665 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
4666 *offsetp += 2;
4667 }
4668 if (bitmask32 & 0x00000010) {
4669 proto_tree_add_item(t, hf_x11_led, tvb, *offsetp, 2, byte_order);
4670 *offsetp += 2;
4671 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
4672 *offsetp += 2;
4673 }
4674 if (bitmask32 & 0x00000020) {
4675 proto_tree_add_item(t, hf_x11_led_mode, tvb, *offsetp, 1, byte_order);
4676 *offsetp += 1;
4677 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
4678 *offsetp += 3;
4679 }
4680 if (bitmask32 & 0x00000040) {
4681 proto_tree_add_item(t, hf_x11_keyboard_key, tvb, *offsetp, 1, byte_order);
4682 *offsetp += 1;
4683 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
4684 *offsetp += 3;
4685 }
4686 if (bitmask32 & 0x00000080) {
4687 proto_tree_add_item(t, hf_x11_auto_repeat_mode, tvb, *offsetp, 1, byte_order);
4688 *offsetp += 1;
4689 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 3, ENC_NA);
4690 *offsetp += 3;
4691 }
4692 }
4693 break;
4694
4695 case X_GetKeyboardControl:
4696 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4697 *offsetp += 1;
4698 requestLength(tvb, offsetp, t, byte_order);
4699 break;
4700
4701 case X_Bell:
4702 INT8(percent);
4703 requestLength(tvb, offsetp, t, byte_order);
4704 break;
4705
4706 case X_ChangePointerControl:
4707 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4708 *offsetp += 1;
4709 requestLength(tvb, offsetp, t, byte_order);
4710 INT16(acceleration_numerator);
4711 INT16(acceleration_denominator);
4712 INT16(threshold);
4713 BOOL(do_acceleration);
4714 BOOL(do_threshold);
4715 break;
4716
4717 case X_GetPointerControl:
4718 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4719 *offsetp += 1;
4720 requestLength(tvb, offsetp, t, byte_order);
4721 break;
4722
4723 case X_SetScreenSaver:
4724 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4725 *offsetp += 1;
4726 requestLength(tvb, offsetp, t, byte_order);
4727 INT16(timeout);
4728 INT16(interval);
4729 ENUM8(prefer_blanking);
4730 ENUM8(allow_exposures);
4731 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
4732 *offsetp += 2;
4733 break;
4734
4735 case X_GetScreenSaver:
4736 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4737 *offsetp += 1;
4738 requestLength(tvb, offsetp, t, byte_order);
4739 break;
4740
4741 case X_ChangeHosts:
4742 ENUM8(change_host_mode);
4743 requestLength(tvb, offsetp, t, byte_order);
4744 v8 = ENUM8(family);
4745 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4746 *offsetp += 1;
4747 v16 = CARD16(address_length);
4748 if (v8 == FAMILY_INTERNET && v16 == 4) {
4749 /*
4750 * IPv4 addresses.
4751 * XXX - what about IPv6? Is that a family of
4752 * FAMILY_INTERNET (0) with a length of 16?
4753 */
4754 LISTofIPADDRESS(ip_address, v16);
4755 } else
4756 LISTofCARD8(address, v16);
4757 break;
4758
4759 case X_ListHosts:
4760 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4761 *offsetp += 1;
4762 requestLength(tvb, offsetp, t, byte_order);
4763 break;
4764
4765 case X_SetAccessControl:
4766 ENUM8(access_mode);
4767 requestLength(tvb, offsetp, t, byte_order);
4768 break;
4769
4770 case X_SetCloseDownMode:
4771 ENUM8(close_down_mode);
4772 requestLength(tvb, offsetp, t, byte_order);
4773 break;
4774
4775 case X_KillClient:
4776 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4777 *offsetp += 1;
4778 requestLength(tvb, offsetp, t, byte_order);
4779 CARD32(resource);
4780 break;
4781
4782 case X_RotateProperties:
4783 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4784 *offsetp += 1;
4785 v16 = requestLength(tvb, offsetp, t, byte_order);
4786 WINDOW(window);
4787 CARD16(property_number);
4788 INT16(delta);
4789 LISTofATOM(properties, (v16 - 12));
4790 break;
4791
4792 case X_ForceScreenSaver:
4793 ENUM8(screen_saver_mode);
4794 requestLength(tvb, offsetp, t, byte_order);
4795 break;
4796
4797 case X_SetPointerMapping:
4798 v8 = FIELD8(map_length);
4799 requestLength(tvb, offsetp, t, byte_order);
4800 LISTofCARD8(map, v8);
4801 PAD();
4802 break;
4803
4804 case X_GetPointerMapping:
4805 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4806 *offsetp += 1;
4807 requestLength(tvb, offsetp, t, byte_order);
4808 break;
4809
4810 case X_SetModifierMapping:
4811 v8 = FIELD8(keycodes_per_modifier);
4812 requestLength(tvb, offsetp, t, byte_order);
4813 LISTofKEYCODE(state->modifiermap, keycodes, v8);
4814 break;
4815
4816 case X_GetModifierMapping:
4817 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4818 *offsetp += 1;
4819 requestLength(tvb, offsetp, t, byte_order);
4820 break;
4821
4822 case X_NoOperation:
4823 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
4824 *offsetp += 1;
4825 requestLength(tvb, offsetp, t, byte_order);
4826 break;
4827 default:
4828 tryExtension(opcode, tvb, pinfo, offsetp, t, state, byte_order);
4829 break;
4830 }
4831
4832 if ((left = tvb_reported_length_remaining(tvb, offset)) > 0)
4833 UNDECODED(left);
4834 }
4835
dissect_x11_requests(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)4836 static void dissect_x11_requests(tvbuff_t *tvb, packet_info *pinfo,
4837 proto_tree *tree)
4838 {
4839 volatile int offset = 0;
4840 int length_remaining;
4841 volatile guint byte_order;
4842 guint8 opcode;
4843 volatile gint plen;
4844 proto_item *ti;
4845 volatile gboolean is_initial_creq;
4846 guint16 auth_proto_len, auth_data_len;
4847 const char *volatile sep = NULL;
4848 conversation_t *conversation;
4849 x11_conv_data_t *volatile state;
4850 int length;
4851 tvbuff_t *volatile next_tvb;
4852
4853 while ((length_remaining = tvb_reported_length_remaining(tvb, offset)) > 0) {
4854
4855 /*
4856 * Can we do reassembly?
4857 */
4858 if (x11_desegment && pinfo->can_desegment) {
4859 /*
4860 * Yes - is the X11 request header split across
4861 * segment boundaries?
4862 */
4863 if (length_remaining < 4) {
4864 /*
4865 * Yes. Tell the TCP dissector where the data
4866 * for this message starts in the data it handed
4867 * us and that we need "some more data." Don't tell
4868 * it exactly how many bytes we need because if/when
4869 * we ask for even more (after the header) that will
4870 * break reassembly.
4871 */
4872 pinfo->desegment_offset = offset;
4873 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
4874 return;
4875 }
4876 }
4877
4878 /*
4879 * Get the state for this conversation; create the conversation
4880 * if we don't have one, and create the state if we don't have
4881 * any.
4882 */
4883 conversation = find_or_create_conversation(pinfo);
4884
4885 /*
4886 * Is there state attached to this conversation?
4887 */
4888 if ((state = (x11_conv_data_t *)conversation_get_proto_data(conversation, proto_x11))
4889 == NULL)
4890 state = x11_stateinit(conversation);
4891
4892 /*
4893 * Guess the byte order if we don't already know it.
4894 */
4895 byte_order = guess_byte_ordering(tvb, pinfo, state);
4896
4897 /*
4898 * Get the opcode and length of the putative X11 request.
4899 */
4900 opcode = tvb_get_guint8(tvb, 0);
4901 plen = tvb_get_guint16(tvb, offset + 2, byte_order);
4902
4903 if (plen == 0) {
4904 /*
4905 * A length field of 0 indicates that the BIG-REQUESTS
4906 * extension is used: The next four bytes are the real length.
4907 */
4908 plen = tvb_get_guint32(tvb, offset + 4, byte_order);
4909 }
4910
4911 if (plen <= 0) {
4912 /*
4913 * This can't be less then 0, as it includes the header length.
4914 * A different choice of byte order wouldn't have
4915 * helped.
4916 * Give up.
4917 */
4918 ti = proto_tree_add_item(tree, proto_x11, tvb, offset, -1, ENC_NA);
4919 expert_add_info_format(pinfo, ti, &ei_x11_request_length, "Bogus request length (%d)", plen);
4920 return;
4921 }
4922
4923 if (state->iconn_frame == pinfo->num ||
4924 (wmem_map_lookup(state->seqtable,
4925 GINT_TO_POINTER(state->sequencenumber)) == (int *)NOTHING_SEEN &&
4926 (opcode == 'B' || opcode == 'l') &&
4927 (plen == 11 || plen == 2816))) {
4928 /*
4929 * Either
4930 *
4931 * we saw this on the first pass and this is
4932 * it again
4933 *
4934 * or
4935 * we haven't already seen any requests, the first
4936 * byte of the message is 'B' or 'l', and the 16-bit
4937 * integer 2 bytes into the data stream is either 11
4938 * or a byte-swapped 11.
4939 *
4940 * This means it's probably an initial connection
4941 * request, not a message.
4942 *
4943 * 'B' is decimal 66, which is the opcode for a
4944 * PolySegment request; unfortunately, 11 is a valid
4945 * length for a PolySegment request request, so we
4946 * might mis-identify that request. (Are there any
4947 * other checks we can do?)
4948 *
4949 * 'l' is decimal 108, which is the opcode for a
4950 * GetScreenSaver request; the only valid length
4951 * for that request is 1.
4952 */
4953 is_initial_creq = TRUE;
4954
4955 /*
4956 * We now know the byte order. Override the guess.
4957 */
4958 if (state->byte_order == BYTE_ORDER_UNKNOWN) {
4959 if (opcode == 'B') {
4960 /*
4961 * Big-endian.
4962 */
4963 byte_order = state->byte_order = ENC_BIG_ENDIAN;
4964 } else {
4965 /*
4966 * Little-endian.
4967 */
4968 byte_order = state->byte_order = ENC_LITTLE_ENDIAN;
4969 }
4970 }
4971
4972 /*
4973 * Can we do reassembly?
4974 */
4975 if (x11_desegment && pinfo->can_desegment) {
4976 /*
4977 * Yes - is the fixed-length portion of the
4978 * initial connection header split across
4979 * segment boundaries?
4980 */
4981 if (length_remaining < 10) {
4982 /*
4983 * Yes. Tell the TCP dissector where the
4984 * data for this message starts in the data
4985 * it handed us and that we need "some more
4986 * data." Don't tell it exactly how many bytes
4987 * we need because if/when we ask for even more
4988 * (after the header) that will break reassembly.
4989 */
4990 pinfo->desegment_offset = offset;
4991 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
4992 return;
4993 }
4994 }
4995
4996 /*
4997 * Get the lengths of the authorization protocol and
4998 * the authorization data.
4999 */
5000 auth_proto_len = tvb_get_guint16(tvb, offset + 6, byte_order);
5001 auth_data_len = tvb_get_guint16(tvb, offset + 8, byte_order);
5002 plen = 12 + ROUND_LENGTH(auth_proto_len) +
5003 ROUND_LENGTH(auth_data_len);
5004 } else {
5005 volatile gint64 tmp = (gint64)plen * 4;
5006 /*
5007 * This is probably an ordinary request.
5008 */
5009 is_initial_creq = FALSE;
5010
5011 /*
5012 * The length of a request is in 4-byte words.
5013 */
5014 if (tmp > G_MAXINT32) {
5015 ti = proto_tree_add_item(tree, proto_x11, tvb, offset, -1, ENC_NA);
5016 expert_add_info_format(pinfo, ti, &ei_x11_request_length, "Bogus request length (%"G_GINT64_MODIFIER"d)", tmp);
5017 return;
5018 }
5019 plen = (gint)tmp;
5020 }
5021
5022 /*
5023 * Can we do reassembly?
5024 */
5025 if (x11_desegment && pinfo->can_desegment) {
5026 /*
5027 * Yes - is the X11 request split across segment
5028 * boundaries?
5029 */
5030 if (length_remaining < plen) {
5031 /*
5032 * Yes. Tell the TCP dissector where the data
5033 * for this message starts in the data it handed
5034 * us, and how many more bytes we need, and return.
5035 */
5036 pinfo->desegment_offset = offset;
5037 pinfo->desegment_len = plen - length_remaining;
5038 return;
5039 }
5040 }
5041
5042 /*
5043 * Construct a tvbuff containing the amount of the payload
5044 * we have available. Make its reported length the
5045 * amount of data in the X11 request.
5046 *
5047 * XXX - if reassembly isn't enabled. the subdissector
5048 * will throw a BoundsError exception, rather than a
5049 * ReportedBoundsError exception. We really want a tvbuff
5050 * where the length is "length", the reported length is "plen",
5051 * and the "if the snapshot length were infinite" length is the
5052 * minimum of the reported length of the tvbuff handed to us
5053 * and "plen", with a new type of exception thrown if the offset
5054 * is within the reported length but beyond that third length,
5055 * with that exception getting the "Unreassembled Packet" error.
5056 */
5057 length = length_remaining;
5058 if (length > plen)
5059 length = plen;
5060 next_tvb = tvb_new_subset_length_caplen(tvb, offset, length, plen);
5061
5062 /*
5063 * Set the column appropriately.
5064 */
5065 if (is_initial_creq) {
5066 col_set_str(pinfo->cinfo, COL_INFO, "Initial connection request");
5067 } else {
5068 if (sep == NULL) {
5069 /*
5070 * We haven't set the column yet; set it.
5071 */
5072 col_set_str(pinfo->cinfo, COL_INFO, "Requests");
5073
5074 /*
5075 * Initialize the separator.
5076 */
5077 sep = ":";
5078 }
5079 }
5080
5081 /*
5082 * Dissect the X11 request.
5083 *
5084 * Catch the ReportedBoundsError exception; if this
5085 * particular message happens to get a ReportedBoundsError
5086 * exception, that doesn't mean that we should stop
5087 * dissecting X11 requests within this frame or chunk of
5088 * reassembled data.
5089 *
5090 * If it gets a BoundsError, we can stop, as there's nothing
5091 * more to see, so we just re-throw it.
5092 */
5093 TRY {
5094 if (is_initial_creq) {
5095 dissect_x11_initial_conn(next_tvb, pinfo, tree,
5096 state, byte_order);
5097 } else {
5098 dissect_x11_request(next_tvb, pinfo, tree, sep,
5099 state, byte_order);
5100 }
5101 }
5102 CATCH_NONFATAL_ERRORS {
5103 show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
5104 }
5105 ENDTRY;
5106
5107 /*
5108 * Skip the X11 message.
5109 */
5110 offset += plen;
5111
5112 sep = ",";
5113 }
5114 }
5115
5116 static x11_conv_data_t *
x11_stateinit(conversation_t * conversation)5117 x11_stateinit(conversation_t *conversation)
5118 {
5119 x11_conv_data_t *state;
5120 static x11_conv_data_t stateinit;
5121 int i;
5122
5123 state = wmem_new(wmem_file_scope(), x11_conv_data_t);
5124 *state = stateinit;
5125
5126 /* initialise opcodes */
5127 for (i = 0; opcode_vals[i].strptr != NULL; i++) {
5128 state->opcode_vals[i].value = opcode_vals[i].value;
5129 state->opcode_vals[i].strptr = opcode_vals[i].strptr;
5130 }
5131 for (; i <= MAX_OPCODES; i++) {
5132 state->opcode_vals[i].value = 0;
5133 state->opcode_vals[i].strptr = NULL;
5134 }
5135
5136 /* initialise errorcodes */
5137 for (i = 0; errorcode_vals[i].strptr != NULL; i++) {
5138 state->errorcode_vals[i].value = errorcode_vals[i].value;
5139 state->errorcode_vals[i].strptr = errorcode_vals[i].strptr;
5140 }
5141 for (; i <= LastExtensionError + 1; i++) {
5142 state->errorcode_vals[i].value = 0;
5143 state->errorcode_vals[i].strptr = NULL;
5144 }
5145
5146 /* initialise eventcodes */
5147 for (i = 0; eventcode_vals[i].strptr != NULL; i++) {
5148 state->eventcode_vals[i].value = eventcode_vals[i].value;
5149 state->eventcode_vals[i].strptr = eventcode_vals[i].strptr;
5150 }
5151 for (; i <= LastExtensionEvent + 1; i++) {
5152 state->eventcode_vals[i].value = 0;
5153 state->eventcode_vals[i].strptr = NULL;
5154 }
5155 state->eventcode_funcs = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
5156 state->reply_funcs = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
5157
5158 state->seqtable = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
5159 state->valtable = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
5160 wmem_map_insert(state->seqtable, (int *)0, (int *)NOTHING_SEEN);
5161 state->byte_order = BYTE_ORDER_UNKNOWN; /* don't know yet*/
5162 conversation_add_proto_data(conversation, proto_x11, state);
5163 return state;
5164 }
5165
5166
5167 static void
dissect_x11_replies(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)5168 dissect_x11_replies(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5169 {
5170 /* Set up structures we will need to add the protocol subtree and manage it */
5171 volatile int offset, plen;
5172 tvbuff_t *volatile next_tvb;
5173 conversation_t *conversation;
5174 x11_conv_data_t *volatile state;
5175 volatile guint byte_order;
5176 int length_remaining;
5177 const char *volatile sep = NULL;
5178
5179
5180 /*
5181 * Get the state for this conversation; create the conversation
5182 * if we don't have one, and create the state if we don't have
5183 * any.
5184 */
5185 conversation = find_or_create_conversation(pinfo);
5186
5187 /*
5188 * Is there state attached to this conversation?
5189 */
5190 if ((state = (x11_conv_data_t *)conversation_get_proto_data(conversation, proto_x11))
5191 == NULL) {
5192 /*
5193 * No - create a state structure and attach it.
5194 */
5195 state = x11_stateinit(conversation);
5196 }
5197
5198 /*
5199 * Guess the byte order if we don't already know it.
5200 */
5201 byte_order = guess_byte_ordering(tvb, pinfo, state);
5202
5203 offset = 0;
5204 while ((length_remaining = tvb_reported_length_remaining(tvb, offset)) > 0) {
5205 /*
5206 * Can we do reassembly?
5207 */
5208 if (x11_desegment && pinfo->can_desegment) {
5209 /*
5210 * Yes - is the X11 Reply or GenericEvent header split across
5211 * segment boundaries?
5212 */
5213 if (length_remaining < 8) {
5214 /*
5215 * Yes. Tell the TCP dissector where the data
5216 * for this message starts in the data it handed
5217 * us and that we need "some more data." Don't tell
5218 * it exactly how many bytes we need because if/when
5219 * we ask for even more (after the header) that will
5220 * break reassembly.
5221 */
5222 pinfo->desegment_offset = offset;
5223 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
5224 return;
5225 }
5226 }
5227
5228 /*
5229 * Find out what kind of a reply it is.
5230 * There are four possible:
5231 * - reply to initial connection
5232 * - errorreply (a request generated an error)
5233 * - requestreply (reply to a request)
5234 * - event (some event occurred)
5235 */
5236 if (wmem_map_lookup(state->seqtable,
5237 GINT_TO_POINTER(state->sequencenumber)) == (int *)INITIAL_CONN
5238 || (state->iconn_reply == pinfo->num)) {
5239 /*
5240 * Either the connection is in the "initial
5241 * connection" state, or this frame is known
5242 * to have the initial connection reply.
5243 * That means this is the initial connection
5244 * reply.
5245 */
5246 plen = 8 + tvb_get_guint16(tvb, offset + 6, byte_order) * 4;
5247
5248 HANDLE_REPLY(plen, length_remaining,
5249 "Initial connection reply",
5250 dissect_x11_initial_reply);
5251 } else {
5252 /*
5253 * This isn't an initial connection reply
5254 * (XXX - unless we missed the initial
5255 * connection request). Look at the first
5256 * byte to determine what it is; errors
5257 * start with a byte of 0, replies start
5258 * with a byte of 1, events start with
5259 * a byte with of 2 or greater.
5260 */
5261 switch (tvb_get_guint8(tvb, offset)) {
5262
5263 case 0:
5264 plen = 32;
5265 HANDLE_REPLY(plen, length_remaining,
5266 "Error", dissect_x11_error);
5267 break;
5268
5269 case 1:
5270 {
5271 /* To avoid an "assert w/side-effect" warning,
5272 * use a non-volatile temp variable instead. */
5273 int tmp_plen;
5274
5275 /* replylength is in units of four. */
5276 tmp_plen = plen = 32 + tvb_get_guint32(tvb, offset + 4, byte_order) * 4;
5277 /* If tmp_plen < 32, we got an overflow;
5278 * the reply length is too long. */
5279 THROW_ON(tmp_plen < 32, ReportedBoundsError);
5280 HANDLE_REPLY(plen, length_remaining,
5281 "Reply", dissect_x11_reply);
5282 break;
5283 }
5284
5285 case GenericEvent:
5286 {
5287 /* An Event, but with a length field like a Reply. */
5288
5289 /* To avoid an "assert w/side-effect" warning,
5290 * use a non-volatile temp variable instead. */
5291 int tmp_plen;
5292
5293 /* GenericEvent's length is also in units of four. */
5294 tmp_plen = plen = 32 + tvb_get_guint32(tvb, offset + 4, byte_order) * 4;
5295 /* If tmp_plen < 32, we got an overflow;
5296 * the event length is too long. */
5297 THROW_ON(tmp_plen < 32, ReportedBoundsError);
5298 HANDLE_REPLY(plen, length_remaining,
5299 "Event", dissect_x11_event);
5300 break;
5301 }
5302
5303 default:
5304 /* Event */
5305 plen = 32;
5306 HANDLE_REPLY(plen, length_remaining,
5307 "Event", dissect_x11_event);
5308 break;
5309 }
5310 }
5311
5312 offset += plen;
5313 }
5314
5315 return;
5316 }
5317
5318 static void
dissect_x11_reply(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,const char * sep,x11_conv_data_t * state,guint byte_order)5319 dissect_x11_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5320 const char *sep, x11_conv_data_t *state,
5321 guint byte_order)
5322 {
5323 int offset = 0, *offsetp = &offset, length, left, opcode;
5324 int major_opcode, sequence_number, first_error, first_event;
5325 value_string *vals_p;
5326 proto_item *ti;
5327 proto_tree *t;
5328
5329 ti = proto_tree_add_item(tree, proto_x11, tvb, 0, -1, ENC_NA);
5330 t = proto_item_add_subtree(ti, ett_x11);
5331
5332
5333 /*
5334 * XXX - this doesn't work correctly if either
5335 *
5336 * 1) the request sequence number wraps in the lower 16
5337 * bits;
5338 *
5339 * 2) we don't see the initial connection request and the
5340 * resynchronization of sequence number fails and thus
5341 * don't have the right sequence numbers
5342 *
5343 * 3) we don't have all the packets in the capture and
5344 * get out of sequence.
5345 *
5346 * We might, instead, want to assume that a reply is a reply to
5347 * the most recent not-already-replied-to request in the same
5348 * connection. That also might mismatch replies to requests if
5349 * packets are lost, but there's nothing you can do to fix that.
5350 */
5351
5352 sequence_number = tvb_get_guint16(tvb, offset + 2, byte_order);
5353 opcode = GPOINTER_TO_INT(wmem_map_lookup(state->seqtable,
5354 GINT_TO_POINTER(sequence_number)));
5355
5356 if (state->iconn_frame == 0 && state->resync == FALSE) {
5357
5358 /*
5359 * We don't see the initial connection request and no
5360 * resynchronization has been performed yet (first reply),
5361 * set the current sequence number to the one of the
5362 * current reply (this is only performed once).
5363 */
5364 state->sequencenumber = sequence_number;
5365 state->resync = TRUE;
5366 }
5367
5368 if (opcode == UNKNOWN_OPCODE) {
5369 col_append_fstr(pinfo->cinfo, COL_INFO,
5370 "%s to unknown request", sep);
5371 proto_item_append_text(ti, ", Reply to unknown request");
5372 } else {
5373 col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
5374 sep,
5375 val_to_str(opcode & 0xFF, state->opcode_vals,
5376 "<Unknown opcode %d>"));
5377
5378 if (opcode > 0xFF)
5379 proto_item_append_text(ti, ", Reply, opcode: %d.%d (%s)",
5380 opcode & 0xFF, opcode >> 8, val_to_str(opcode & 0xFF,
5381 state->opcode_vals,
5382 "<Unknown opcode %d>"));
5383 else
5384 proto_item_append_text(ti, ", Reply, opcode: %d (%s)",
5385 opcode, val_to_str(opcode,
5386 state->opcode_vals,
5387 "<Unknown opcode %d>"));
5388 }
5389
5390 switch (opcode) {
5391
5392 /*
5393 * Replies that need special processing outside tree
5394 */
5395
5396 case X_QueryExtension:
5397
5398 /*
5399 * if extension is present and request is known:
5400 * store opcode of extension in value_string of
5401 * opcodes
5402 */
5403 if (!tvb_get_guint8(tvb, offset + 8)) {
5404 /* not present */
5405 break;
5406 }
5407
5408 vals_p = (value_string *)wmem_map_lookup(state->valtable,
5409 GINT_TO_POINTER(sequence_number));
5410 if (vals_p != NULL) {
5411 major_opcode = tvb_get_guint8(tvb, offset + 9);
5412 first_event = tvb_get_guint8(tvb, offset + 10);
5413 first_error = tvb_get_guint8(tvb, offset + 11);
5414
5415 register_extension(state, vals_p, major_opcode, first_event, first_error);
5416 wmem_map_remove(state->valtable,
5417 GINT_TO_POINTER(sequence_number));
5418 }
5419 break;
5420
5421 default:
5422 break;
5423 }
5424
5425 if (tree == NULL)
5426 return;
5427
5428 switch (opcode) {
5429 /*
5430 * Requests that expect a reply.
5431 */
5432
5433 case X_GetWindowAttributes:
5434 REPLYCONTENTS_COMMON();
5435 break;
5436
5437 case X_GetGeometry:
5438 REPLY(reply);
5439 CARD8(depth);
5440 SEQUENCENUMBER_REPLY(sequencenumber);
5441 REPLYLENGTH(replylength);
5442 WINDOW(rootwindow);
5443 INT16(x);
5444 INT16(y);
5445 CARD16(width);
5446 CARD16(height);
5447 CARD16(border_width);
5448 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 10, ENC_NA);
5449 *offsetp += 10;
5450 break;
5451
5452 case X_QueryTree:
5453 REPLYCONTENTS_COMMON();
5454 break;
5455
5456 case X_InternAtom:
5457 REPLY(reply);
5458 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5459 *offsetp += 1;
5460 SEQUENCENUMBER_REPLY(sequencenumber);
5461 REPLYLENGTH(replylength);
5462 ATOM(atom);
5463 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 20, ENC_NA);
5464 *offsetp += 20;
5465 break;
5466
5467 case X_GetAtomName:
5468 REPLYCONTENTS_COMMON();
5469 break;
5470
5471 case X_GetProperty:
5472 REPLY(reply);
5473 CARD8(format);
5474 SEQUENCENUMBER_REPLY(sequencenumber);
5475 REPLYLENGTH(replylength);
5476 ATOM(get_property_type);
5477 CARD32(bytes_after);
5478 CARD32(valuelength);
5479 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 12, ENC_NA);
5480 *offsetp += 12;
5481 break;
5482
5483 case X_ListProperties:
5484 REPLY(reply);
5485 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5486 *offsetp += 1;
5487 SEQUENCENUMBER_REPLY(sequencenumber);
5488 REPLYLENGTH(replylength);
5489 length = CARD16(property_number);
5490 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 22, ENC_NA);
5491 *offsetp += 22;
5492 LISTofATOM(properties, length*4);
5493 break;
5494
5495 case X_GetSelectionOwner:
5496 REPLY(reply);
5497 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5498 *offsetp += 1;
5499 SEQUENCENUMBER_REPLY(sequencenumber);
5500 REPLYLENGTH(replylength);
5501 WINDOW(owner);
5502 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 20, ENC_NA);
5503 *offsetp += 20;
5504 break;
5505
5506 case X_GrabPointer:
5507 case X_GrabKeyboard:
5508 REPLY(reply);
5509 ENUM8(grab_status);
5510 SEQUENCENUMBER_REPLY(sequencenumber);
5511 REPLYLENGTH(replylength);
5512 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 24, ENC_NA);
5513 *offsetp += 24;
5514 break;
5515
5516 case X_QueryPointer:
5517 REPLY(reply);
5518 BOOL(same_screen);
5519 SEQUENCENUMBER_REPLY(sequencenumber);
5520 REPLYLENGTH(replylength);
5521 WINDOW(rootwindow);
5522 WINDOW(childwindow);
5523 INT16(root_x);
5524 INT16(root_y);
5525 INT16(win_x);
5526 INT16(win_y);
5527 SETofKEYBUTMASK(mask);
5528 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 6, ENC_NA);
5529 *offsetp += 6;
5530 break;
5531
5532 case X_GetMotionEvents:
5533 REPLYCONTENTS_COMMON();
5534 break;
5535
5536 case X_TranslateCoords:
5537 REPLY(reply);
5538 BOOL(same_screen);
5539 SEQUENCENUMBER_REPLY(sequencenumber);
5540 REPLYLENGTH(replylength);
5541 WINDOW(childwindow);
5542 INT16(dst_x);
5543 INT16(dst_y);
5544 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 16, ENC_NA);
5545 *offsetp += 16;
5546 break;
5547
5548 case X_GetInputFocus:
5549 REPLY(reply);
5550 ENUM8(revert_to);
5551 SEQUENCENUMBER_REPLY(sequencenumber);
5552 REPLYLENGTH(replylength);
5553 WINDOW(focus);
5554 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 20, ENC_NA);
5555 *offsetp += 20;
5556 break;
5557
5558 case X_QueryKeymap:
5559 REPLY(reply);
5560 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5561 *offsetp += 1;
5562 SEQUENCENUMBER_REPLY(sequencenumber);
5563 REPLYLENGTH(replylength);
5564 LISTofCARD8(keys, 32);
5565 break;
5566
5567 case X_QueryFont:
5568 case X_QueryTextExtents:
5569 case X_ListFonts:
5570 case X_GetImage:
5571 case X_ListInstalledColormaps:
5572 REPLYCONTENTS_COMMON();
5573 break;
5574
5575 case X_AllocColor:
5576 REPLY(reply);
5577 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5578 *offsetp += 1;
5579 SEQUENCENUMBER_REPLY(sequencenumber);
5580 REPLYLENGTH(replylength);
5581 CARD16(red);
5582 CARD16(green);
5583 CARD16(blue);
5584 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 2, ENC_NA);
5585 *offsetp += 2;
5586 CARD32(pixel);
5587 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 12, ENC_NA);
5588 *offsetp += 12;
5589 break;
5590
5591 case X_QueryColors:
5592 REPLYCONTENTS_COMMON();
5593 break;
5594
5595 case X_LookupColor:
5596 REPLY(reply);
5597 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5598 *offsetp += 1;
5599 SEQUENCENUMBER_REPLY(sequencenumber);
5600 REPLYLENGTH(replylength);
5601 CARD16(exact_red);
5602 CARD16(exact_green);
5603 CARD16(exact_blue);
5604 CARD16(visual_red);
5605 CARD16(visual_green);
5606 CARD16(visual_blue);
5607 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 12, ENC_NA);
5608 *offsetp += 12;
5609 break;
5610
5611 case X_QueryBestSize:
5612 REPLY(reply);
5613 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5614 *offsetp += 1;
5615 SEQUENCENUMBER_REPLY(sequencenumber);
5616 REPLYLENGTH(replylength);
5617 CARD16(width);
5618 CARD16(height);
5619 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 20, ENC_NA);
5620 *offsetp += 20;
5621 break;
5622
5623 case X_QueryExtension:
5624 REPLY(reply);
5625 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5626 *offsetp += 1;
5627 SEQUENCENUMBER_REPLY(sequencenumber);
5628 REPLYLENGTH(replylength);
5629 BOOL(present);
5630 CARD8(major_opcode);
5631 CARD8(first_event);
5632 CARD8(first_error);
5633 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 20, ENC_NA);
5634 *offsetp += 20;
5635 break;
5636
5637 case X_ListExtensions:
5638 REPLYCONTENTS_COMMON();
5639 break;
5640
5641 case X_GetKeyboardMapping:
5642 state->first_keycode =
5643 state->request.GetKeyboardMapping.first_keycode;
5644 REPLY(reply);
5645 state->keysyms_per_keycode =
5646 FIELD8(keysyms_per_keycode);
5647 SEQUENCENUMBER_REPLY(sequencenumber);
5648 length = REPLYLENGTH(replylength);
5649 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 24, ENC_NA);
5650 *offsetp += 24;
5651 LISTofKEYSYM(keysyms, state->keycodemap,
5652 state->request.GetKeyboardMapping.first_keycode,
5653 /* XXX - length / state->keysyms_per_keycode can raise a division by zero,
5654 * don't know if this is the *right* way to fix it ... */
5655 state->keysyms_per_keycode ? length / state->keysyms_per_keycode : 0,
5656 state->keysyms_per_keycode);
5657 break;
5658
5659 case X_GetKeyboardControl:
5660 REPLYCONTENTS_COMMON();
5661 break;
5662
5663 case X_GetPointerControl:
5664 REPLY(reply);
5665 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5666 *offsetp += 1;
5667 SEQUENCENUMBER_REPLY(sequencenumber);
5668 REPLYLENGTH(replylength);
5669 CARD16(acceleration_numerator);
5670 CARD16(acceleration_denominator);
5671 CARD16(threshold);
5672 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 18, ENC_NA);
5673 *offsetp += 18;
5674 break;
5675
5676 case X_GetScreenSaver:
5677 REPLY(reply);
5678 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5679 *offsetp += 1;
5680 SEQUENCENUMBER_REPLY(sequencenumber);
5681 REPLYLENGTH(replylength);
5682 CARD16(timeout);
5683 CARD16(interval);
5684 ENUM8(prefer_blanking);
5685 ENUM8(allow_exposures);
5686 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 18, ENC_NA);
5687 *offsetp += 18;
5688 break;
5689
5690 case X_ListHosts:
5691 case X_SetPointerMapping:
5692 case X_GetPointerMapping:
5693 case X_SetModifierMapping:
5694 REPLYCONTENTS_COMMON();
5695 break;
5696
5697 case X_GetModifierMapping:
5698 REPLY(reply);
5699 state->keycodes_per_modifier =
5700 FIELD8(keycodes_per_modifier);
5701 SEQUENCENUMBER_REPLY(sequencenumber);
5702 REPLYLENGTH(replylength);
5703 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 24, ENC_NA);
5704 *offsetp += 24;
5705 LISTofKEYCODE(state->modifiermap, keycodes,
5706 state->keycodes_per_modifier);
5707 break;
5708
5709 case UNKNOWN_OPCODE:
5710 REPLYCONTENTS_COMMON();
5711 break;
5712
5713 default:
5714 tryExtensionReply(opcode, tvb, pinfo, offsetp, t, state, byte_order);
5715 }
5716
5717 if ((left = tvb_reported_length_remaining(tvb, offset)) > 0)
5718 UNDECODED(left);
5719 }
5720
5721 static void
same_screen_focus(tvbuff_t * tvb,int * offsetp,proto_tree * t)5722 same_screen_focus(tvbuff_t *tvb, int *offsetp, proto_tree *t)
5723 {
5724 proto_item *ti;
5725 guint32 bitmask_value;
5726 int bitmask_offset;
5727 int bitmask_size;
5728 proto_tree *bitmask_tree;
5729
5730 bitmask_value = tvb_get_guint8(tvb, *offsetp);
5731 bitmask_offset = *offsetp;
5732 bitmask_size = 1;
5733
5734 ti = proto_tree_add_uint(t, hf_x11_same_screen_focus_mask, tvb, *offsetp, 1,
5735 bitmask_value);
5736 bitmask_tree = proto_item_add_subtree(ti, ett_x11_same_screen_focus);
5737 FLAG(same_screen_focus, focus);
5738 FLAG(same_screen_focus, same_screen);
5739
5740 *offsetp += 1;
5741 }
5742
5743 static void
dissect_x11_event(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,const char * sep,x11_conv_data_t * state,guint byte_order)5744 dissect_x11_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5745 const char *sep, x11_conv_data_t *state,
5746 guint byte_order)
5747 {
5748 unsigned char eventcode;
5749 const char *sent;
5750 proto_item *ti;
5751 proto_tree *t;
5752
5753 ti = proto_tree_add_item(tree, proto_x11, tvb, 0, -1, ENC_NA);
5754 t = proto_item_add_subtree(ti, ett_x11);
5755
5756 eventcode = tvb_get_guint8(tvb, 0);
5757 sent = (eventcode & 0x80) ? "Sent-" : "";
5758
5759 col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s%s",
5760 sep, sent,
5761 val_to_str(eventcode & 0x7F, state->eventcode_vals,
5762 "<Unknown eventcode %u>"));
5763
5764 proto_item_append_text(ti, ", Event, eventcode: %d (%s%s)",
5765 eventcode, sent,
5766 val_to_str(eventcode & 0x7F, state->eventcode_vals,
5767 "<Unknown eventcode %u>"));
5768
5769 if (tree == NULL)
5770 return;
5771
5772 decode_x11_event(tvb, eventcode, sent, t, state, byte_order);
5773
5774 return;
5775 }
5776
5777 static void
decode_x11_event(tvbuff_t * tvb,unsigned char eventcode,const char * sent,proto_tree * t,x11_conv_data_t * state,guint byte_order)5778 decode_x11_event(tvbuff_t *tvb, unsigned char eventcode, const char *sent,
5779 proto_tree *t, x11_conv_data_t *state,
5780 guint byte_order)
5781 {
5782 int offset = 0, *offsetp = &offset, left;
5783
5784 proto_tree_add_uint_format(t, hf_x11_eventcode, tvb, offset, 1,
5785 eventcode,
5786 "eventcode: %d (%s%s)",
5787 eventcode, sent,
5788 val_to_str(eventcode & 0x7F, state->eventcode_vals,
5789 "<Unknown eventcode %u>"));
5790 ++offset;
5791
5792 switch (eventcode & 0x7F) {
5793 case KeyPress:
5794 case KeyRelease: {
5795 int code, mask;
5796
5797 /* need to do some prefetching here ... */
5798 code = tvb_get_guint8(tvb, offset);
5799 mask = tvb_get_guint16(tvb, 28, byte_order);
5800
5801 KEYCODE_DECODED(keycode, code, mask);
5802 CARD16(event_sequencenumber);
5803 EVENTCONTENTS_COMMON();
5804 BOOL(same_screen);
5805 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5806 *offsetp += 1;
5807 break;
5808 }
5809
5810 case ButtonPress:
5811 case ButtonRelease:
5812 BUTTON(eventbutton);
5813 CARD16(event_sequencenumber);
5814 EVENTCONTENTS_COMMON();
5815 BOOL(same_screen);
5816 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5817 *offsetp += 1;
5818 break;
5819
5820 case MotionNotify:
5821 CARD8(detail);
5822 CARD16(event_sequencenumber);
5823 EVENTCONTENTS_COMMON();
5824 BOOL(same_screen);
5825 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5826 *offsetp += 1;
5827 break;
5828
5829 case EnterNotify:
5830 case LeaveNotify:
5831 ENUM8(event_detail);
5832 CARD16(event_sequencenumber);
5833 EVENTCONTENTS_COMMON();
5834 ENUM8(grab_mode);
5835 same_screen_focus(tvb, offsetp, t);
5836 break;
5837
5838 case FocusIn:
5839 case FocusOut:
5840 ENUM8(focus_detail);
5841 CARD16(event_sequencenumber);
5842 WINDOW(eventwindow);
5843 ENUM8(focus_mode);
5844 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 23, ENC_NA);
5845 *offsetp += 23;
5846 break;
5847
5848 case KeymapNotify:
5849 break;
5850
5851 case Expose:
5852 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5853 *offsetp += 1;
5854 CARD16(event_sequencenumber);
5855 WINDOW(eventwindow);
5856 INT16(x);
5857 INT16(y);
5858 CARD16(width);
5859 CARD16(height);
5860 CARD16(count);
5861 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 14, ENC_NA);
5862 *offsetp += 14;
5863 break;
5864
5865 case GraphicsExpose:
5866 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5867 *offsetp += 1;
5868 CARD16(event_sequencenumber);
5869 DRAWABLE(drawable);
5870 CARD16(x);
5871 CARD16(y);
5872 CARD16(width);
5873 CARD16(height);
5874 CARD16(minor_opcode);
5875 CARD16(count);
5876 CARD8(major_opcode);
5877 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 11, ENC_NA);
5878 *offsetp += 11;
5879 break;
5880
5881 case NoExpose:
5882 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5883 *offsetp += 1;
5884 CARD16(event_sequencenumber);
5885 DRAWABLE(drawable);
5886 CARD16(minor_opcode);
5887 CARD8(major_opcode);
5888 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 21, ENC_NA);
5889 *offsetp += 21;
5890 break;
5891
5892 case VisibilityNotify:
5893 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5894 *offsetp += 1;
5895 CARD16(event_sequencenumber);
5896 WINDOW(eventwindow);
5897 ENUM8(visibility_state);
5898 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 23, ENC_NA);
5899 *offsetp += 23;
5900 break;
5901
5902 case CreateNotify:
5903 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5904 *offsetp += 1;
5905 CARD16(event_sequencenumber);
5906 WINDOW(parent);
5907 WINDOW(eventwindow);
5908 INT16(x);
5909 INT16(y);
5910 CARD16(width);
5911 CARD16(height);
5912 CARD16(border_width);
5913 BOOL(override_redirect);
5914 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 9, ENC_NA);
5915 *offsetp += 9;
5916 break;
5917
5918 case DestroyNotify:
5919 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5920 *offsetp += 1;
5921 CARD16(event_sequencenumber);
5922 WINDOW(eventwindow);
5923 WINDOW(window);
5924 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 20, ENC_NA);
5925 *offsetp += 20;
5926 break;
5927
5928 case UnmapNotify:
5929 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5930 *offsetp += 1;
5931 CARD16(event_sequencenumber);
5932 WINDOW(eventwindow);
5933 WINDOW(window);
5934 BOOL(from_configure);
5935 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 19, ENC_NA);
5936 *offsetp += 19;
5937 break;
5938
5939 case MapNotify:
5940 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5941 *offsetp += 1;
5942 CARD16(event_sequencenumber);
5943 WINDOW(eventwindow);
5944 WINDOW(window);
5945 BOOL(override_redirect);
5946 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 19, ENC_NA);
5947 *offsetp += 19;
5948 break;
5949
5950 case MapRequest:
5951 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5952 *offsetp += 1;
5953 CARD16(event_sequencenumber);
5954 WINDOW(parent);
5955 WINDOW(eventwindow);
5956 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 20, ENC_NA);
5957 *offsetp += 20;
5958 break;
5959
5960 case ReparentNotify:
5961 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5962 *offsetp += 1;
5963 CARD16(event_sequencenumber);
5964 WINDOW(eventwindow);
5965 WINDOW(window);
5966 WINDOW(parent);
5967 INT16(x);
5968 INT16(y);
5969 BOOL(override_redirect);
5970 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 11, ENC_NA);
5971 *offsetp += 11;
5972 break;
5973
5974 case ConfigureNotify:
5975 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5976 *offsetp += 1;
5977 CARD16(event_sequencenumber);
5978 WINDOW(eventwindow);
5979 WINDOW(window);
5980 WINDOW(above_sibling);
5981 INT16(x);
5982 INT16(y);
5983 CARD16(width);
5984 CARD16(height);
5985 CARD16(border_width);
5986 BOOL(override_redirect);
5987 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 5, ENC_NA);
5988 *offsetp += 5;
5989 break;
5990
5991 case ConfigureRequest:
5992 break;
5993
5994 case GravityNotify:
5995 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
5996 *offsetp += 1;
5997 CARD16(event_sequencenumber);
5998 WINDOW(eventwindow);
5999 WINDOW(window);
6000 INT16(x);
6001 INT16(y);
6002 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 16, ENC_NA);
6003 *offsetp += 16;
6004 break;
6005
6006 case ResizeRequest:
6007 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
6008 *offsetp += 1;
6009 CARD16(event_sequencenumber);
6010 WINDOW(eventwindow);
6011 CARD16(width);
6012 CARD16(height);
6013 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 20, ENC_NA);
6014 *offsetp += 20;
6015 break;
6016
6017 case CirculateNotify:
6018 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
6019 *offsetp += 1;
6020 CARD16(event_sequencenumber);
6021 WINDOW(eventwindow);
6022 WINDOW(window);
6023 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 4, ENC_NA);
6024 *offsetp += 4;
6025 ENUM8(place);
6026 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 15, ENC_NA);
6027 *offsetp += 15;
6028 break;
6029
6030 case CirculateRequest:
6031 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
6032 *offsetp += 1;
6033 CARD16(event_sequencenumber);
6034 WINDOW(parent);
6035 WINDOW(eventwindow);
6036 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 4, ENC_NA);
6037 *offsetp += 4;
6038 ENUM8(place);
6039 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 15, ENC_NA);
6040 *offsetp += 15;
6041 break;
6042
6043 case PropertyNotify:
6044 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
6045 *offsetp += 1;
6046 CARD16(event_sequencenumber);
6047 WINDOW(eventwindow);
6048 ATOM(atom);
6049 TIMESTAMP(time);
6050 ENUM8(property_state);
6051 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 15, ENC_NA);
6052 *offsetp += 15;
6053 break;
6054
6055 case SelectionClear:
6056 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
6057 *offsetp += 1;
6058 CARD16(event_sequencenumber);
6059 TIMESTAMP(time);
6060 WINDOW(owner);
6061 ATOM(selection);
6062 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 16, ENC_NA);
6063 *offsetp += 16;
6064 break;
6065
6066 case SelectionRequest:
6067 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
6068 *offsetp += 1;
6069 CARD16(event_sequencenumber);
6070 TIMESTAMP(time);
6071 WINDOW(owner);
6072 WINDOW(requestor);
6073 ATOM(selection);
6074 ATOM(target);
6075 ATOM(property);
6076 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 4, ENC_NA);
6077 *offsetp += 4;
6078 break;
6079
6080 case SelectionNotify:
6081 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
6082 *offsetp += 1;
6083 CARD16(event_sequencenumber);
6084 TIMESTAMP(time);
6085 WINDOW(requestor);
6086 ATOM(selection);
6087 ATOM(target);
6088 ATOM(property);
6089 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 8, ENC_NA);
6090 *offsetp += 8;
6091 break;
6092
6093 case ColormapNotify:
6094 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
6095 *offsetp += 1;
6096 CARD16(event_sequencenumber);
6097 WINDOW(eventwindow);
6098 COLORMAP(cmap);
6099 BOOL(new);
6100 ENUM8(colormap_state);
6101 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 18, ENC_NA);
6102 *offsetp += 18;
6103 break;
6104
6105 case ClientMessage:
6106 CARD8(format);
6107 CARD16(event_sequencenumber);
6108 WINDOW(eventwindow);
6109 ATOM(type);
6110 LISTofBYTE(data, 20);
6111 break;
6112
6113 case MappingNotify:
6114 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 1, ENC_NA);
6115 *offsetp += 1;
6116 CARD16(event_sequencenumber);
6117 ENUM8(mapping_request);
6118 CARD8(first_keycode);
6119 CARD8(count);
6120 proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, 25, ENC_NA);
6121 *offsetp += 25;
6122 break;
6123
6124 case GenericEvent:
6125 tryGenericExtensionEvent(tvb, offsetp, t, state, byte_order);
6126 break;
6127
6128 default:
6129 tryExtensionEvent(eventcode & 0x7F, tvb, offsetp, t, state, byte_order);
6130 break;
6131 }
6132
6133 if ((left = tvb_reported_length_remaining(tvb, offset)) > 0)
6134 UNDECODED(left);
6135 }
6136
6137 static void
dissect_x11_error(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,const char * sep,x11_conv_data_t * state _U_,guint byte_order)6138 dissect_x11_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6139 const char *sep, x11_conv_data_t *state _U_,
6140 guint byte_order)
6141 {
6142 int offset = 0, *offsetp = &offset, left;
6143 unsigned char errorcode;
6144 proto_item *ti;
6145 proto_tree *t;
6146
6147 ti = proto_tree_add_item(tree, proto_x11, tvb, 0, -1, ENC_NA);
6148 t = proto_item_add_subtree(ti, ett_x11);
6149
6150 CARD8(error);
6151
6152 errorcode = tvb_get_guint8(tvb, offset);
6153 col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
6154 sep, val_to_str(errorcode, state->errorcode_vals, "<Unknown errorcode %u>"));
6155
6156 proto_tree_add_uint_format(t, hf_x11_errorcode, tvb, offset, 1,
6157 errorcode,
6158 "errorcode: %d (%s)",
6159 errorcode,
6160 val_to_str(errorcode, state->errorcode_vals,
6161 "<Unknown errorcode %u>"));
6162 ++offset;
6163
6164 proto_item_append_text(ti, ", Error, errorcode: %d (%s)",
6165 errorcode, val_to_str(errorcode, state->errorcode_vals,
6166 "<Unknown errorcode %u>"));
6167
6168 if (tree == NULL)
6169 return;
6170
6171 CARD16(error_sequencenumber);
6172
6173 switch (errorcode) {
6174 case BadValue:
6175 CARD32(error_badvalue);
6176 break;
6177 case BadWindow:
6178 case BadPixmap:
6179 case BadCursor:
6180 case BadFont:
6181 case BadDrawable:
6182 case BadColormap:
6183 case BadGC:
6184 case BadIDChoice:
6185 CARD32(error_badresourceid);
6186 break;
6187
6188 default:
6189 UNDECODED(4);
6190 }
6191
6192 CARD16(minor_opcode);
6193 CARD8(major_opcode);
6194
6195 if ((left = tvb_reported_length_remaining(tvb, offset)) > 0)
6196 UNDECODED(left);
6197 }
6198
6199
6200
6201 /************************************************************************
6202 *** ***
6203 *** I N I T I A L I Z A T I O N A N D M A I N ***
6204 *** ***
6205 ************************************************************************/
6206
6207 static int
dissect_x11(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)6208 dissect_x11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
6209 {
6210 col_set_str(pinfo->cinfo, COL_PROTOCOL, "X11");
6211
6212 if (pinfo->match_uint == pinfo->srcport)
6213 dissect_x11_replies(tvb, pinfo, tree);
6214 else
6215 dissect_x11_requests(tvb, pinfo, tree);
6216
6217 return tvb_captured_length(tvb);
6218 }
6219
6220 /* Register the protocol with Wireshark */
proto_register_x11(void)6221 void proto_register_x11(void)
6222 {
6223
6224 /* Setup list of header fields */
6225 static hf_register_info hf[] = {
6226 #include "x11-register-info.h"
6227 };
6228
6229 /* Setup protocol subtree array */
6230 static gint *ett[] = {
6231 &ett_x11,
6232 &ett_x11_color_flags,
6233 &ett_x11_list_of_arc,
6234 &ett_x11_arc,
6235 &ett_x11_list_of_atom,
6236 &ett_x11_list_of_card32,
6237 &ett_x11_list_of_float,
6238 &ett_x11_list_of_double,
6239 &ett_x11_list_of_color_item,
6240 &ett_x11_color_item,
6241 &ett_x11_list_of_keycode,
6242 &ett_x11_list_of_keysyms,
6243 &ett_x11_keysym,
6244 &ett_x11_list_of_point,
6245 &ett_x11_point,
6246 &ett_x11_list_of_rectangle,
6247 &ett_x11_rectangle,
6248 &ett_x11_list_of_segment,
6249 &ett_x11_segment,
6250 &ett_x11_list_of_string8,
6251 &ett_x11_list_of_text_item,
6252 &ett_x11_text_item,
6253 &ett_x11_gc_value_mask,
6254 &ett_x11_event_mask,
6255 &ett_x11_do_not_propagate_mask,
6256 &ett_x11_set_of_key_mask,
6257 &ett_x11_pointer_event_mask,
6258 &ett_x11_window_value_mask,
6259 &ett_x11_configure_window_mask,
6260 &ett_x11_keyboard_value_mask,
6261 &ett_x11_same_screen_focus,
6262 &ett_x11_event,
6263 &ett_x11_list_of_pixmap_format,
6264 &ett_x11_pixmap_format,
6265 &ett_x11_list_of_screen,
6266 &ett_x11_screen,
6267 &ett_x11_list_of_depth_detail,
6268 &ett_x11_depth_detail,
6269 &ett_x11_list_of_visualtype,
6270 &ett_x11_visualtype,
6271 };
6272
6273 static ei_register_info ei[] = {
6274 { &ei_x11_invalid_format, { "x11.invalid_format", PI_PROTOCOL, PI_WARN, "Invalid Format", EXPFILL }},
6275 { &ei_x11_request_length, { "x11.request-length.invalid", PI_PROTOCOL, PI_WARN, "Invalid Length", EXPFILL }},
6276 { &ei_x11_keycode_value_out_of_range, { "x11.keycode_value_out_of_range", PI_PROTOCOL, PI_WARN, "keycode value is out of range", EXPFILL }},
6277 };
6278
6279 module_t *x11_module;
6280 expert_module_t* expert_x11;
6281
6282 /* Register the protocol name and description */
6283 proto_x11 = proto_register_protocol("X11", "X11", "x11");
6284
6285 /* Required function calls to register the header fields and subtrees used */
6286 proto_register_field_array(proto_x11, hf, array_length(hf));
6287 proto_register_subtree_array(ett, array_length(ett));
6288 expert_x11 = expert_register_protocol(proto_x11);
6289 expert_register_field_array(expert_x11, ei, array_length(ei));
6290
6291 extension_table = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
6292 error_table = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
6293 event_table = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
6294 genevent_table = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
6295 reply_table = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
6296 register_x11_extensions();
6297
6298 x11_module = prefs_register_protocol(proto_x11, NULL);
6299 prefs_register_bool_preference(x11_module, "desegment",
6300 "Reassemble X11 messages spanning multiple TCP segments",
6301 "Whether the X11 dissector should reassemble messages spanning multiple TCP segments. "
6302 "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
6303 &x11_desegment);
6304 }
6305
6306 void
proto_reg_handoff_x11(void)6307 proto_reg_handoff_x11(void)
6308 {
6309 dissector_handle_t x11_handle = NULL;
6310
6311 x11_handle = create_dissector_handle(dissect_x11, proto_x11);
6312
6313 dissector_add_uint_range_with_preference("tcp.port", DEFAULT_X11_PORT_RANGE, x11_handle);
6314 }
6315
6316 /*
6317 * Editor modelines
6318 *
6319 * Local Variables:
6320 * c-basic-offset: 6
6321 * tab-width: 8
6322 * indent-tabs-mode: nil
6323 * End:
6324 *
6325 * ex: set shiftwidth=6 tabstop=8 expandtab:
6326 * :indentSize=6:tabSize=8:noTabs=true:
6327 */
6328