PageRenderTime 47ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/epan/dissectors/packet-x11.c

https://github.com/labx-technologies-llc/wireshark
C | 5658 lines | 4515 code | 650 blank | 493 comment | 535 complexity | 8e585c65f8191423a1c8a34fc80b582c MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  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. * $Id$
  7. *
  8. * Wireshark - Network traffic analyzer
  9. * By Gerald Combs <gerald@wireshark.org>
  10. * Copyright 1998 Gerald Combs
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License
  14. * as published by the Free Software Foundation; either version 2
  15. * of the License, or (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  25. */
  26. /* TODO (in no particular order):
  27. *
  28. * - keep track of Atom creation by server to be able to display
  29. * non-predefined atoms
  30. * - Idem for keysym <-> keycode ???
  31. * - Idem for fonts
  32. * - Subtree the request ids (that is x11.create-window.window and
  33. * x11.change-window.window should be distinct), and add hidden fields
  34. * (so we still have x11.window).
  35. * - add hidden fields so we can have x11.circulate-window in addition to
  36. * x11.opcode == 13 (but you could match on x11.opcode == "CirculateWindow"
  37. * now)
  38. * - add hidden fields so we have x11.listOfStuff.length
  39. * - use a faster scheme that linear list searching for the opcode.
  40. * - correct display of Unicode chars.
  41. * - Not everything is homogeneous, in particular the handling of items in
  42. * list is a total mess.
  43. */
  44. /* By the way, I wrote a program to generate every request and test
  45. * that stuff. If you're interested, you can get it at
  46. * http://tronche.com/gui/x/
  47. */
  48. #include "config.h"
  49. #include <assert.h>
  50. #include <string.h>
  51. #include <ctype.h>
  52. #include <glib.h>
  53. #include <epan/packet.h>
  54. #include <epan/conversation.h>
  55. #include <epan/expert.h>
  56. #include <epan/show_exception.h>
  57. #include <epan/prefs.h>
  58. #include <epan/emem.h>
  59. #include "packet-x11-keysymdef.h"
  60. #include "packet-x11.h"
  61. #define cVALS(x) (const value_string*)(x)
  62. /*
  63. * Data structure associated with a conversation; keeps track of the
  64. * request for which we're expecting a reply, the frame number of
  65. * the initial connection request, and the byte order of the connection.
  66. *
  67. * An opcode of -3 means we haven't yet seen any requests yet.
  68. * An opcode of -2 means we're not expecting a reply (unused).
  69. * An opcode of -1 means we're waiting for a reply to the initial
  70. * connection request.
  71. * An opcode of 0 means the request was not seen (or unknown).
  72. * Other values are the opcode of the request for which we're expecting
  73. * a reply.
  74. *
  75. */
  76. #define NOTHING_SEEN -3
  77. #define NOTHING_EXPECTED -2
  78. #define INITIAL_CONN -1
  79. #define UNKNOWN_OPCODE 0
  80. #define MAX_OPCODES (255 + 1) /* 255 + INITIAL_CONN */
  81. #define LastExtensionError 255
  82. #define LastExtensionEvent 127
  83. #define BYTE_ORDER_BE 0
  84. #define BYTE_ORDER_LE 1
  85. #define BYTE_ORDER_UNKNOWN -1
  86. static const char *modifiers[] = {
  87. "Shift",
  88. "Lock",
  89. "Control",
  90. "Mod1",
  91. "Mod2",
  92. "Mod3",
  93. "Mod4",
  94. "Mod5"
  95. };
  96. /* Keymasks. From <X11/X.h>. */
  97. #define ShiftMask (1<<0)
  98. #define LockMask (1<<1)
  99. #define ControlMask (1<<2)
  100. #define Mod1Mask (1<<3)
  101. #define Mod2Mask (1<<4)
  102. #define Mod3Mask (1<<5)
  103. #define Mod4Mask (1<<6)
  104. #define Mod5Mask (1<<7)
  105. static const int modifiermask[] = { ShiftMask, LockMask, ControlMask,
  106. Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask };
  107. /* from <X11/X.h> */
  108. #define NoSymbol 0L /* special KeySym */
  109. typedef struct _x11_conv_data {
  110. struct _x11_conv_data *next;
  111. GHashTable *seqtable; /* hashtable of sequencenumber <-> opcode. */
  112. GHashTable *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. GHashTable *eventcode_funcs; /* hashtable of eventcode <-> dissect_event() */
  120. GHashTable *reply_funcs; /* hashtable of opcode <-> dissect_reply() */
  121. int sequencenumber; /* sequencenumber of current packet. */
  122. guint32 iconn_frame; /* frame # of initial connection request */
  123. guint32 iconn_reply; /* frame # of initial connection reply */
  124. int byte_order; /* byte order of connection */
  125. gboolean resync; /* resynchronization of sequence number performed */
  126. int *keycodemap[256]; /* keycode to keysymvalue map. */
  127. int keysyms_per_keycode;
  128. int first_keycode;
  129. int *modifiermap[array_length(modifiers)];/* modifier to keycode.*/
  130. int keycodes_per_modifier;
  131. union {
  132. struct {
  133. int first_keycode;
  134. } GetKeyboardMapping;
  135. } request;
  136. } x11_conv_data_t;
  137. static x11_conv_data_t *x11_conv_data_list = NULL;
  138. static GHashTable *extension_table; /* hashtable of extension name <-> dispatch function */
  139. static GHashTable *event_table; /* hashtable of extension name <-> event info list */
  140. static GHashTable *error_table; /* hashtable of extension name <-> error list */
  141. static GHashTable *reply_table; /* hashtable of extension name <-> reply list */
  142. /* Initialize the protocol and registered fields */
  143. static int proto_x11 = -1;
  144. #include "x11-declarations.h"
  145. /* Initialize the subtree pointers */
  146. static gint ett_x11 = -1;
  147. static gint ett_x11_color_flags = -1;
  148. static gint ett_x11_list_of_arc = -1;
  149. static gint ett_x11_arc = -1;
  150. static gint ett_x11_list_of_atom = -1;
  151. static gint ett_x11_list_of_card32 = -1;
  152. static gint ett_x11_list_of_float = -1;
  153. static gint ett_x11_list_of_double = -1;
  154. static gint ett_x11_list_of_color_item = -1;
  155. static gint ett_x11_color_item = -1;
  156. static gint ett_x11_list_of_keycode = -1;
  157. static gint ett_x11_list_of_keysyms = -1;
  158. static gint ett_x11_keysym = -1;
  159. static gint ett_x11_list_of_point = -1;
  160. static gint ett_x11_point = -1;
  161. static gint ett_x11_list_of_rectangle = -1;
  162. static gint ett_x11_rectangle = -1;
  163. static gint ett_x11_list_of_segment = -1;
  164. static gint ett_x11_segment = -1;
  165. static gint ett_x11_list_of_string8 = -1;
  166. static gint ett_x11_list_of_text_item = -1;
  167. static gint ett_x11_text_item = -1;
  168. static gint ett_x11_gc_value_mask = -1; /* XXX - unused */
  169. static gint ett_x11_event_mask = -1; /* XXX - unused */
  170. static gint ett_x11_do_not_propagate_mask = -1; /* XXX - unused */
  171. static gint ett_x11_set_of_key_mask = -1;
  172. static gint ett_x11_pointer_event_mask = -1; /* XXX - unused */
  173. static gint ett_x11_window_value_mask = -1; /* XXX - unused */
  174. static gint ett_x11_configure_window_mask = -1; /* XXX - unused */
  175. static gint ett_x11_keyboard_value_mask = -1; /* XXX - unused */
  176. static gint ett_x11_same_screen_focus = -1;
  177. static gint ett_x11_event = -1;
  178. static expert_field ei_x11_invalid_format = EI_INIT;
  179. /* desegmentation of X11 messages */
  180. static gboolean x11_desegment = TRUE;
  181. #define TCP_PORT_X11 6000
  182. #define TCP_PORT_X11_2 6001
  183. #define TCP_PORT_X11_3 6002
  184. /*
  185. * Round a length to a multiple of 4 bytes.
  186. */
  187. #define ROUND_LENGTH(n) ((((n) + 3)/4) * 4)
  188. /************************************************************************
  189. *** ***
  190. *** E N U M T A B L E S D E F I N I T I O N S ***
  191. *** ***
  192. ************************************************************************/
  193. static const value_string byte_order_vals[] = {
  194. { 'B', "Big-endian" },
  195. { 'l', "Little-endian" },
  196. { 0, NULL }
  197. };
  198. static const value_string image_byte_order_vals[] = {
  199. { 0, "LSBFirst" },
  200. { 1, "MSBFirst" },
  201. { 0, NULL }
  202. };
  203. static const value_string access_mode_vals[] = {
  204. { 0, "Disable" },
  205. { 1, "Enable" },
  206. { 0, NULL }
  207. };
  208. static const value_string all_temporary_vals[] = {
  209. { 0, "AllTemporary" },
  210. { 0, NULL }
  211. };
  212. static const value_string alloc_vals[] = {
  213. { 0, "None" },
  214. { 1, "All" },
  215. { 0, NULL }
  216. };
  217. static const value_string allow_events_mode_vals[] = {
  218. { 0, "AsyncPointer" },
  219. { 1, "SyncPointer" },
  220. { 2, "ReplayPointer" },
  221. { 3, "AsyncKeyboard" },
  222. { 4, "SyncKeyboard" },
  223. { 5, "ReplayKeyboard" },
  224. { 6, "AsyncBoth" },
  225. { 7, "SyncBoth" },
  226. { 0, NULL }
  227. };
  228. static const value_string arc_mode_vals[] = {
  229. { 0, "Chord" },
  230. { 1, "PieSlice" },
  231. { 0, NULL }
  232. };
  233. static const char *atom_predefined_interpretation[] = {
  234. "<error>",
  235. "PRIMARY",
  236. "SECONDARY",
  237. "ARC",
  238. "ATOM",
  239. "BITMAP",
  240. "CARDINAL",
  241. "COLORMAP",
  242. "CURSOR",
  243. "CUT_BUFFER0",
  244. "CUT_BUFFER1",
  245. "CUT_BUFFER2",
  246. "CUT_BUFFER3",
  247. "CUT_BUFFER4",
  248. "CUT_BUFFER5",
  249. "CUT_BUFFER6",
  250. "CUT_BUFFER7",
  251. "DRAWABLE",
  252. "FONT",
  253. "INTEGER",
  254. "PIXMAP",
  255. "POINT",
  256. "RECTANGLE",
  257. "RESOURCE_MANAGER",
  258. "RGB_COLOR_MAP",
  259. "RGB_BEST_MAP",
  260. "RGB_BLUE_MAP",
  261. "RGB_DEFAULT_MAP",
  262. "RGB_GRAY_MAP",
  263. "RGB_GREEN_MAP",
  264. "RGB_RED_MAP",
  265. "STRING",
  266. "VISUALID",
  267. "WINDOW",
  268. "WM_COMMAND",
  269. "WM_HINTS",
  270. "WM_CLIENT_MACHINE",
  271. "WM_ICON_NAME",
  272. "WM_ICON_SIZE",
  273. "WM_NAME",
  274. "WM_NORMAL_HINTS",
  275. "WM_SIZE_HINTS",
  276. "WM_ZOOM_HINTS",
  277. "MIN_SPACE",
  278. "NORM_SPACE",
  279. "MAX_SPACE",
  280. "END_SPACE",
  281. "SUPERSCRIPT_X",
  282. "SUPERSCRIPT_Y",
  283. "SUBSCRIPT_X",
  284. "SUBSCRIPT_Y",
  285. "UNDERLINE_POSITION",
  286. "UNDERLINE_THICKNESS",
  287. "STRIKEOUT_ASCENT",
  288. "STRIKEOUT_DESCENT",
  289. "ITALIC_ANGLE",
  290. "X_HEIGHT",
  291. "QUAD_WIDTH",
  292. "WEIGHT",
  293. "POINT_SIZE",
  294. "RESOLUTION",
  295. "COPYRIGHT",
  296. "NOTICE",
  297. "FONT_NAME",
  298. "FAMILY_NAME",
  299. "FULL_NAME",
  300. "CAP_HEIGHT",
  301. "WM_CLASS",
  302. "WM_TRANSIENT_FOR",
  303. };
  304. static const value_string auto_repeat_mode_vals[] = {
  305. { 0, "Off" },
  306. { 1, "On" },
  307. { 2, "Default" },
  308. { 0, NULL }
  309. };
  310. static const value_string background_pixmap_vals[] = {
  311. { 0, "None" },
  312. { 1, "ParentRelative" },
  313. { 0, NULL }
  314. };
  315. static const value_string backing_store_vals[] = {
  316. { 0, "NotUseful" },
  317. { 1, "WhenMapped" },
  318. { 2, "Always" },
  319. { 0, NULL }
  320. };
  321. static const value_string border_pixmap_vals[] = {
  322. { 0, "CopyFromParent" },
  323. { 0, NULL }
  324. };
  325. static const value_string button_vals[] = {
  326. { 0x8000, "AnyButton" },
  327. { 0, NULL }
  328. };
  329. static const value_string cap_style_vals[] = {
  330. { 0, "NotLast" },
  331. { 1, "Butt" },
  332. { 2, "Round" },
  333. { 3, "Projecting" },
  334. { 0, NULL }
  335. };
  336. static const value_string class_vals[] = {
  337. { 0, "Cursor" },
  338. { 1, "Tile" },
  339. { 2, "Stipple" },
  340. { 0, NULL }
  341. };
  342. static const value_string close_down_mode_vals[] = {
  343. { 0, "Destroy" },
  344. { 1, "RetainPermanent" },
  345. { 2, "RetainTemporary" },
  346. { 0, NULL }
  347. };
  348. static const value_string colormap_state_vals[] = {
  349. { 0, "Uninstalled" },
  350. { 1, "Installed" },
  351. { 0, NULL }
  352. };
  353. static const value_string coordinate_mode_vals[] = {
  354. { 0, "Origin" },
  355. { 1, "Previous" },
  356. { 0, NULL }
  357. };
  358. static const value_string destination_vals[] = {
  359. { 0, "PointerWindow" },
  360. { 1, "InputFocus" },
  361. { 0, NULL }
  362. };
  363. static const value_string direction_vals[] = {
  364. { 0, "RaiseLowest" },
  365. { 1, "LowerHighest" },
  366. { 0, NULL }
  367. };
  368. static const value_string event_detail_vals[] = {
  369. { 0, "Ancestor" },
  370. { 1, "Virtual" },
  371. { 2, "Inferior" },
  372. { 3, "Nonlinear" },
  373. { 4, "NonlinearVirtual" },
  374. { 0, NULL }
  375. };
  376. #define FAMILY_INTERNET 0
  377. #define FAMILY_DECNET 1
  378. #define FAMILY_CHAOS 2
  379. static const value_string family_vals[] = {
  380. { FAMILY_INTERNET, "Internet" },
  381. { FAMILY_DECNET, "DECnet" },
  382. { FAMILY_CHAOS, "Chaos" },
  383. { 0, NULL }
  384. };
  385. static const value_string fill_rule_vals[] = {
  386. { 0, "EvenOdd" },
  387. { 1, "Winding" },
  388. { 0, NULL }
  389. };
  390. static const value_string fill_style_vals[] = {
  391. { 0, "Solid" },
  392. { 1, "Tiled" },
  393. { 2, "Stippled" },
  394. { 3, "OpaqueStippled" },
  395. { 0, NULL }
  396. };
  397. static const value_string focus_detail_vals[] = {
  398. { 0, "Ancestor" },
  399. { 1, "Virtual" },
  400. { 2, "Inferior" },
  401. { 3, "Nonlinear" },
  402. { 4, "NonlinearVirtual" },
  403. { 5, "Pointer" },
  404. { 6, "PointerRoot" },
  405. { 7, "None" },
  406. { 0, NULL }
  407. };
  408. static const value_string focus_mode_vals[] = {
  409. { 0, "Normal" },
  410. { 1, "Grab" },
  411. { 2, "Ungrab" },
  412. { 3, "WhileGrabbed" },
  413. { 0, NULL }
  414. };
  415. static const value_string focus_vals[] = {
  416. { 0, "None" },
  417. { 1, "PointerRoot" },
  418. { 0, NULL }
  419. };
  420. static const value_string function_vals[] = {
  421. { 0, "Clear" },
  422. { 1, "And" },
  423. { 2, "AndReverse" },
  424. { 3, "Copy" },
  425. { 4, "AndInverted" },
  426. { 5, "NoOp" },
  427. { 6, "Xor" },
  428. { 7, "Or" },
  429. { 8, "Nor" },
  430. { 9, "Equiv" },
  431. { 10, "Invert" },
  432. { 11, "OrReverse" },
  433. { 12, "CopyInverted" },
  434. { 13, "OrInverted" },
  435. { 14, "Nand" },
  436. { 15, "Set" },
  437. { 0, NULL }
  438. };
  439. static const value_string grab_mode_vals[] = {
  440. { 0, "Normal" },
  441. { 1, "Grab" },
  442. { 2, "Ungrab" },
  443. { 0, NULL }
  444. };
  445. static const value_string grab_status_vals[] = {
  446. { 0, "Success" },
  447. { 1, "AlreadyGrabbed" },
  448. { 2, "InvalidTime" },
  449. { 3, "NotViewable" },
  450. { 4, "Frozen" },
  451. { 0, NULL }
  452. };
  453. static const value_string gravity_vals[] = {
  454. { 1, "NorthWest" },
  455. { 2, "North" },
  456. { 3, "NorthEast" },
  457. { 4, "West" },
  458. { 5, "Center" },
  459. { 6, "East" },
  460. { 7, "SouthWest" },
  461. { 8, "South" },
  462. { 9, "SouthEast" },
  463. { 10, "Static" },
  464. { 0, NULL }
  465. };
  466. static const value_string image_format_vals[] = {
  467. { 0, "Bitmap" },
  468. { 1, "XYPixmap" },
  469. { 2, "ZPixmap" },
  470. { 0, NULL }
  471. };
  472. static const value_string image_pixmap_format_vals[] = {
  473. { 1, "XYPixmap" },
  474. { 2, "ZPixmap" },
  475. { 0, NULL }
  476. };
  477. static const value_string join_style_vals[] = {
  478. { 0, "Miter" },
  479. { 1, "Round" },
  480. { 2, "Bevel" },
  481. { 0, NULL }
  482. };
  483. static const value_string key_vals[] = {
  484. { 0, "AnyKey" },
  485. { 0, NULL }
  486. };
  487. #include "x11-keysym.h"
  488. static const value_string line_style_vals[] = {
  489. { 0, "Solid" },
  490. { 1, "OnOffDash" },
  491. { 2, "DoubleDash" },
  492. { 0, NULL }
  493. };
  494. static const value_string mode_vals[] = {
  495. { 0, "Replace" },
  496. { 1, "Prepend" },
  497. { 2, "Append" },
  498. { 0, NULL }
  499. };
  500. static const value_string on_off_vals[] = {
  501. { 0, "Off" },
  502. { 1, "On" },
  503. { 0, NULL }
  504. };
  505. static const value_string place_vals[] = {
  506. { 0, "Top" },
  507. { 1, "Bottom" },
  508. { 0, NULL }
  509. };
  510. static const value_string property_state_vals[] = {
  511. { 0, "NewValue" },
  512. { 1, "Deleted" },
  513. { 0, NULL }
  514. };
  515. static const value_string visibility_state_vals[] = {
  516. { 0, "Unobscured" },
  517. { 1, "PartiallyObscured" },
  518. { 2, "FullyObscured" },
  519. { 0, NULL }
  520. };
  521. static const value_string mapping_request_vals[] = {
  522. { 0, "MappingModifier" },
  523. { 1, "MappingKeyboard" },
  524. { 2, "MappingPointer" },
  525. { 0, NULL }
  526. };
  527. /* Requestcodes. From <X11/Xproto.h>. */
  528. #define X_CreateWindow 1
  529. #define X_ChangeWindowAttributes 2
  530. #define X_GetWindowAttributes 3
  531. #define X_DestroyWindow 4
  532. #define X_DestroySubwindows 5
  533. #define X_ChangeSaveSet 6
  534. #define X_ReparentWindow 7
  535. #define X_MapWindow 8
  536. #define X_MapSubwindows 9
  537. #define X_UnmapWindow 10
  538. #define X_UnmapSubwindows 11
  539. #define X_ConfigureWindow 12
  540. #define X_CirculateWindow 13
  541. #define X_GetGeometry 14
  542. #define X_QueryTree 15
  543. #define X_InternAtom 16
  544. #define X_GetAtomName 17
  545. #define X_ChangeProperty 18
  546. #define X_DeleteProperty 19
  547. #define X_GetProperty 20
  548. #define X_ListProperties 21
  549. #define X_SetSelectionOwner 22
  550. #define X_GetSelectionOwner 23
  551. #define X_ConvertSelection 24
  552. #define X_SendEvent 25
  553. #define X_GrabPointer 26
  554. #define X_UngrabPointer 27
  555. #define X_GrabButton 28
  556. #define X_UngrabButton 29
  557. #define X_ChangeActivePointerGrab 30
  558. #define X_GrabKeyboard 31
  559. #define X_UngrabKeyboard 32
  560. #define X_GrabKey 33
  561. #define X_UngrabKey 34
  562. #define X_AllowEvents 35
  563. #define X_GrabServer 36
  564. #define X_UngrabServer 37
  565. #define X_QueryPointer 38
  566. #define X_GetMotionEvents 39
  567. #define X_TranslateCoords 40
  568. #define X_WarpPointer 41
  569. #define X_SetInputFocus 42
  570. #define X_GetInputFocus 43
  571. #define X_QueryKeymap 44
  572. #define X_OpenFont 45
  573. #define X_CloseFont 46
  574. #define X_QueryFont 47
  575. #define X_QueryTextExtents 48
  576. #define X_ListFonts 49
  577. #define X_ListFontsWithInfo 50
  578. #define X_SetFontPath 51
  579. #define X_GetFontPath 52
  580. #define X_CreatePixmap 53
  581. #define X_FreePixmap 54
  582. #define X_CreateGC 55
  583. #define X_ChangeGC 56
  584. #define X_CopyGC 57
  585. #define X_SetDashes 58
  586. #define X_SetClipRectangles 59
  587. #define X_FreeGC 60
  588. #define X_ClearArea 61
  589. #define X_CopyArea 62
  590. #define X_CopyPlane 63
  591. #define X_PolyPoint 64
  592. #define X_PolyLine 65
  593. #define X_PolySegment 66
  594. #define X_PolyRectangle 67
  595. #define X_PolyArc 68
  596. #define X_FillPoly 69
  597. #define X_PolyFillRectangle 70
  598. #define X_PolyFillArc 71
  599. #define X_PutImage 72
  600. #define X_GetImage 73
  601. #define X_PolyText8 74
  602. #define X_PolyText16 75
  603. #define X_ImageText8 76
  604. #define X_ImageText16 77
  605. #define X_CreateColormap 78
  606. #define X_FreeColormap 79
  607. #define X_CopyColormapAndFree 80
  608. #define X_InstallColormap 81
  609. #define X_UninstallColormap 82
  610. #define X_ListInstalledColormaps 83
  611. #define X_AllocColor 84
  612. #define X_AllocNamedColor 85
  613. #define X_AllocColorCells 86
  614. #define X_AllocColorPlanes 87
  615. #define X_FreeColors 88
  616. #define X_StoreColors 89
  617. #define X_StoreNamedColor 90
  618. #define X_QueryColors 91
  619. #define X_LookupColor 92
  620. #define X_CreateCursor 93
  621. #define X_CreateGlyphCursor 94
  622. #define X_FreeCursor 95
  623. #define X_RecolorCursor 96
  624. #define X_QueryBestSize 97
  625. #define X_QueryExtension 98
  626. #define X_ListExtensions 99
  627. #define X_ChangeKeyboardMapping 100
  628. #define X_GetKeyboardMapping 101
  629. #define X_ChangeKeyboardControl 102
  630. #define X_GetKeyboardControl 103
  631. #define X_Bell 104
  632. #define X_ChangePointerControl 105
  633. #define X_GetPointerControl 106
  634. #define X_SetScreenSaver 107
  635. #define X_GetScreenSaver 108
  636. #define X_ChangeHosts 109
  637. #define X_ListHosts 110
  638. #define X_SetAccessControl 111
  639. #define X_SetCloseDownMode 112
  640. #define X_KillClient 113
  641. #define X_RotateProperties 114
  642. #define X_ForceScreenSaver 115
  643. #define X_SetPointerMapping 116
  644. #define X_GetPointerMapping 117
  645. #define X_SetModifierMapping 118
  646. #define X_GetModifierMapping 119
  647. #define X_NoOperation 127
  648. #define X_FirstExtension 128
  649. #define X_LastExtension 255
  650. static const value_string opcode_vals[] = {
  651. { INITIAL_CONN, "Initial connection request" },
  652. { X_CreateWindow, "CreateWindow" },
  653. { X_ChangeWindowAttributes, "ChangeWindowAttributes" },
  654. { X_GetWindowAttributes, "GetWindowAttributes" },
  655. { X_DestroyWindow, "DestroyWindow" },
  656. { X_DestroySubwindows, "DestroySubwindows" },
  657. { X_ChangeSaveSet, "ChangeSaveSet" },
  658. { X_ReparentWindow, "ReparentWindow" },
  659. { X_MapWindow, "MapWindow" },
  660. { X_MapSubwindows, "MapSubwindows" },
  661. { X_UnmapWindow, "UnmapWindow" },
  662. { X_UnmapSubwindows, "UnmapSubwindows" },
  663. { X_ConfigureWindow, "ConfigureWindow" },
  664. { X_CirculateWindow, "CirculateWindow" },
  665. { X_GetGeometry, "GetGeometry" },
  666. { X_QueryTree, "QueryTree" },
  667. { X_InternAtom, "InternAtom" },
  668. { X_GetAtomName, "GetAtomName" },
  669. { X_ChangeProperty, "ChangeProperty" },
  670. { X_DeleteProperty, "DeleteProperty" },
  671. { X_GetProperty, "GetProperty" },
  672. { X_ListProperties, "ListProperties" },
  673. { X_SetSelectionOwner, "SetSelectionOwner" },
  674. { X_GetSelectionOwner, "GetSelectionOwner" },
  675. { X_ConvertSelection, "ConvertSelection" },
  676. { X_SendEvent, "SendEvent" },
  677. { X_GrabPointer, "GrabPointer" },
  678. { X_UngrabPointer, "UngrabPointer" },
  679. { X_GrabButton, "GrabButton" },
  680. { X_UngrabButton, "UngrabButton" },
  681. { X_ChangeActivePointerGrab, "ChangeActivePointerGrab" },
  682. { X_GrabKeyboard, "GrabKeyboard" },
  683. { X_UngrabKeyboard, "UngrabKeyboard" },
  684. { X_GrabKey, "GrabKey" },
  685. { X_UngrabKey, "UngrabKey" },
  686. { X_AllowEvents, "AllowEvents" },
  687. { X_GrabServer, "GrabServer" },
  688. { X_UngrabServer, "UngrabServer" },
  689. { X_QueryPointer, "QueryPointer" },
  690. { X_GetMotionEvents, "GetMotionEvents" },
  691. { X_TranslateCoords, "TranslateCoordinates" },
  692. { X_WarpPointer, "WarpPointer" },
  693. { X_SetInputFocus, "SetInputFocus" },
  694. { X_GetInputFocus, "GetInputFocus" },
  695. { X_QueryKeymap, "QueryKeymap" },
  696. { X_OpenFont, "OpenFont" },
  697. { X_CloseFont, "CloseFont" },
  698. { X_QueryFont, "QueryFont" },
  699. { X_QueryTextExtents, "QueryTextExtents" },
  700. { X_ListFonts, "ListFonts" },
  701. { X_ListFontsWithInfo, "ListFontsWithInfo" },
  702. { X_SetFontPath, "SetFontPath" },
  703. { X_GetFontPath, "GetFontPath" },
  704. { X_CreatePixmap, "CreatePixmap" },
  705. { X_FreePixmap, "FreePixmap" },
  706. { X_CreateGC, "CreateGC" },
  707. { X_ChangeGC, "ChangeGC" },
  708. { X_CopyGC, "CopyGC" },
  709. { X_SetDashes, "SetDashes" },
  710. { X_SetClipRectangles, "SetClipRectangles" },
  711. { X_FreeGC, "FreeGC" },
  712. { X_ClearArea, "ClearArea" },
  713. { X_CopyArea, "CopyArea" },
  714. { X_CopyPlane, "CopyPlane" },
  715. { X_PolyPoint, "PolyPoint" },
  716. { X_PolyLine, "PolyLine" },
  717. { X_PolySegment, "PolySegment" },
  718. { X_PolyRectangle, "PolyRectangle" },
  719. { X_PolyArc, "PolyArc" },
  720. { X_FillPoly, "FillPoly" },
  721. { X_PolyFillRectangle, "PolyFillRectangle" },
  722. { X_PolyFillArc, "PolyFillArc" },
  723. { X_PutImage, "PutImage" },
  724. { X_GetImage, "GetImage" },
  725. { X_PolyText8, "PolyText8" },
  726. { X_PolyText16, "PolyText16" },
  727. { X_ImageText8, "ImageText8" },
  728. { X_ImageText16, "ImageText16" },
  729. { X_CreateColormap, "CreateColormap" },
  730. { X_FreeColormap, "FreeColormap" },
  731. { X_CopyColormapAndFree, "CopyColormapAndFree" },
  732. { X_InstallColormap, "InstallColormap" },
  733. { X_UninstallColormap, "UninstallColormap" },
  734. { X_ListInstalledColormaps, "ListInstalledColormaps" },
  735. { X_AllocColor, "AllocColor" },
  736. { X_AllocNamedColor, "AllocNamedColor" },
  737. { X_AllocColorCells, "AllocColorCells" },
  738. { X_AllocColorPlanes, "AllocColorPlanes" },
  739. { X_FreeColors, "FreeColors" },
  740. { X_StoreColors, "StoreColors" },
  741. { X_StoreNamedColor, "StoreNamedColor" },
  742. { X_QueryColors, "QueryColors" },
  743. { X_LookupColor, "LookupColor" },
  744. { X_CreateCursor, "CreateCursor" },
  745. { X_CreateGlyphCursor, "CreateGlyphCursor" },
  746. { X_FreeCursor, "FreeCursor" },
  747. { X_RecolorCursor, "RecolorCursor" },
  748. { X_QueryBestSize, "QueryBestSize" },
  749. { X_QueryExtension, "QueryExtension" },
  750. { X_ListExtensions, "ListExtensions" },
  751. { X_ChangeKeyboardMapping, "ChangeKeyboardMapping" },
  752. { X_GetKeyboardMapping, "GetKeyboardMapping" },
  753. { X_ChangeKeyboardControl, "ChangeKeyboardControl" },
  754. { X_GetKeyboardControl, "GetKeyboardControl" },
  755. { X_Bell, "Bell" },
  756. { X_ChangePointerControl, "ChangePointerControl" },
  757. { X_GetPointerControl, "GetPointerControl" },
  758. { X_SetScreenSaver, "SetScreenSaver" },
  759. { X_GetScreenSaver, "GetScreenSaver" },
  760. { X_ChangeHosts, "ChangeHosts" },
  761. { X_ListHosts, "ListHosts" },
  762. { X_SetAccessControl, "SetAccessControl" },
  763. { X_SetCloseDownMode, "SetCloseDownMode" },
  764. { X_KillClient, "KillClient" },
  765. { X_RotateProperties, "RotateProperties" },
  766. { X_ForceScreenSaver, "ForceScreenSaver" },
  767. { X_SetPointerMapping, "SetPointerMapping" },
  768. { X_GetPointerMapping, "GetPointerMapping" },
  769. { X_SetModifierMapping, "SetModifierMapping" },
  770. { X_GetModifierMapping, "GetModifierMapping" },
  771. { X_NoOperation, "NoOperation" },
  772. { 0, NULL }
  773. };
  774. /* Eventscodes. From <X11/X.h>. */
  775. #define KeyPress 2
  776. #define KeyRelease 3
  777. #define ButtonPress 4
  778. #define ButtonRelease 5
  779. #define MotionNotify 6
  780. #define EnterNotify 7
  781. #define LeaveNotify 8
  782. #define FocusIn 9
  783. #define FocusOut 10
  784. #define KeymapNotify 11
  785. #define Expose 12
  786. #define GraphicsExpose 13
  787. #define NoExpose 14
  788. #define VisibilityNotify 15
  789. #define CreateNotify 16
  790. #define DestroyNotify 17
  791. #define UnmapNotify 18
  792. #define MapNotify 19
  793. #define MapRequest 20
  794. #define ReparentNotify 21
  795. #define ConfigureNotify 22
  796. #define ConfigureRequest 23
  797. #define GravityNotify 24
  798. #define ResizeRequest 25
  799. #define CirculateNotify 26
  800. #define CirculateRequest 27
  801. #define PropertyNotify 28
  802. #define SelectionClear 29
  803. #define SelectionRequest 30
  804. #define SelectionNotify 31
  805. #define ColormapNotify 32
  806. #define ClientMessage 33
  807. #define MappingNotify 34
  808. static const value_string eventcode_vals[] = {
  809. { KeyPress, "KeyPress" },
  810. { KeyRelease, "KeyRelease" },
  811. { ButtonPress, "ButtonPress" },
  812. { ButtonRelease, "ButtonRelease" },
  813. { MotionNotify, "MotionNotify" },
  814. { EnterNotify, "EnterNotify" },
  815. { LeaveNotify, "LeaveNotify" },
  816. { FocusIn, "FocusIn" },
  817. { FocusOut, "FocusOut" },
  818. { KeymapNotify, "KeymapNotify" },
  819. { Expose, "Expose" },
  820. { GraphicsExpose, "GraphicsExpose" },
  821. { NoExpose, "NoExpose" },
  822. { VisibilityNotify, "VisibilityNotify" },
  823. { CreateNotify, "CreateNotify" },
  824. { DestroyNotify, "DestroyNotify" },
  825. { UnmapNotify, "UnmapNotify" },
  826. { MapNotify, "MapNotify" },
  827. { MapRequest, "MapRequest" },
  828. { ReparentNotify, "ReparentNotify" },
  829. { ConfigureNotify, "ConfigureNotify" },
  830. { ConfigureRequest, "ConfigureRequest" },
  831. { GravityNotify, "GravityNotify" },
  832. { ResizeRequest, "ResizeRequest" },
  833. { CirculateNotify, "CirculateNotify" },
  834. { CirculateRequest, "CirculateRequest" },
  835. { PropertyNotify, "PropertyNotify" },
  836. { SelectionClear, "SelectionClear" },
  837. { SelectionRequest, "SelectionRequest" },
  838. { SelectionNotify, "SelectionNotify" },
  839. { ColormapNotify, "ColormapNotify" },
  840. { ClientMessage, "ClientMessage" },
  841. { MappingNotify, "MappingNotify" },
  842. { 0, NULL }
  843. };
  844. /* Errorcodes. From <X11/X.h> */
  845. #define Success 0 /* everything's okay */
  846. #define BadRequest 1 /* bad request code */
  847. #define BadValue 2 /* int parameter out of range */
  848. #define BadWindow 3 /* parameter not a Window */
  849. #define BadPixmap 4 /* parameter not a Pixmap */
  850. #define BadAtom 5 /* parameter not an Atom */
  851. #define BadCursor 6 /* parameter not a Cursor */
  852. #define BadFont 7 /* parameter not a Font */
  853. #define BadMatch 8 /* parameter mismatch */
  854. #define BadDrawable 9 /* parameter not a Pixmap or Window */
  855. #define BadAccess 10 /* depending on context:
  856. - key/button already grabbed
  857. - attempt to free an illegal
  858. cmap entry
  859. - attempt to store into a read-only
  860. color map entry.
  861. - attempt to modify the access control
  862. list from other than the local host.
  863. */
  864. #define BadAlloc 11 /* insufficient resources */
  865. #define BadColor 12 /* no such colormap */
  866. #define BadGC 13 /* parameter not a GC */
  867. #define BadIDChoice 14 /* choice not in range or already used */
  868. #define BadName 15 /* font or color name doesn't exist */
  869. #define BadLength 16 /* Request length incorrect */
  870. #define BadImplementation 17 /* server is defective */
  871. static const value_string errorcode_vals[] = {
  872. { Success, "Success" },
  873. { BadRequest, "BadRequest" },
  874. { BadValue, "BadValue" },
  875. { BadWindow, "BadWindow" },
  876. { BadPixmap, "BadPixmap" },
  877. { BadAtom, "BadAtom" },
  878. { BadCursor, "BadCursor" },
  879. { BadFont, "BadFont" },
  880. { BadMatch, "BadMatch" },
  881. { BadDrawable, "BadDrawable" },
  882. { BadAccess, "BadAccess" },
  883. { BadAlloc, "BadAlloc" },
  884. { BadColor, "BadColor" },
  885. { BadGC, "BadGC" },
  886. { BadIDChoice, "BadIDChoice" },
  887. { BadName, "BadName" },
  888. { BadLength, "BadLength" },
  889. { BadImplementation, "BadImplementation" },
  890. { 0, NULL }
  891. };
  892. static const value_string ordering_vals[] = {
  893. { 0, "UnSorted" },
  894. { 1, "YSorted" },
  895. { 2, "YXSorted" },
  896. { 3, "YXBanded" },
  897. { 0, NULL }
  898. };
  899. static const value_string plane_mask_vals[] = {
  900. { 0xFFFFFFFF, "AllPlanes" },
  901. { 0, NULL }
  902. };
  903. static const value_string pointer_keyboard_mode_vals[] = {
  904. { 0, "Synchronous" },
  905. { 1, "Asynchronous" },
  906. { 0, NULL }
  907. };
  908. static const value_string revert_to_vals[] = {
  909. { 0, "None" },
  910. { 1, "PointerRoot" },
  911. { 2, "Parent" },
  912. { 0, NULL }
  913. };
  914. static const value_string insert_delete_vals[] = {
  915. { 0, "Insert" },
  916. { 1, "Delete" },
  917. { 0, NULL }
  918. };
  919. static const value_string screen_saver_mode_vals[] = {
  920. { 0, "Reset" },
  921. { 1, "Activate" },
  922. { 0, NULL }
  923. };
  924. static const value_string shape_vals[] = {
  925. { 0, "Complex" },
  926. { 1, "Nonconvex" },
  927. { 2, "Convex" },
  928. { 0, NULL }
  929. };
  930. static const value_string stack_mode_vals[] = {
  931. { 0, "Above" },
  932. { 1, "Below" },
  933. { 2, "TopIf" },
  934. { 3, "BottomIf" },
  935. { 4, "Opposite" },
  936. { 0, NULL }
  937. };
  938. static const value_string subwindow_mode_vals[] = {
  939. { 0, "ClipByChildren" },
  940. { 1, "IncludeInferiors" },
  941. { 0, NULL }
  942. };
  943. static const value_string window_class_vals[] = {
  944. { 0, "CopyFromParent" },
  945. { 1, "InputOutput" },
  946. { 2, "InputOnly" },
  947. { 0, NULL }
  948. };
  949. static const value_string yes_no_default_vals[] = {
  950. { 0, "No" },
  951. { 1, "Yes" },
  952. { 2, "Default" },
  953. { 0, NULL }
  954. };
  955. static const value_string zero_is_any_property_type_vals[] = {
  956. { 0, "AnyPropertyType" },
  957. { 0, NULL }
  958. };
  959. static const value_string zero_is_none_vals[] = {
  960. { 0, "None" },
  961. { 0, NULL }
  962. };
  963. /* we have not seen packet before. */
  964. #define PACKET_IS_NEW(pinfo) \
  965. (!((pinfo)->fd->flags.visited))
  966. /************************************************************************
  967. *** ***
  968. *** F I E L D D E C O D I N G M A C R O S ***
  969. *** ***
  970. ************************************************************************/
  971. #define VALUE8(tvb, offset) (tvb_get_guint8(tvb, offset))
  972. #define VALUE16(tvb, offset) (byte_order == ENC_BIG_ENDIAN ? tvb_get_ntohs(tvb, offset) : tvb_get_letohs(tvb, offset))
  973. #define VALUE32(tvb, offset) (byte_order == ENC_BIG_ENDIAN ? tvb_get_ntohl(tvb, offset) : tvb_get_letohl(tvb, offset))
  974. #define FLOAT(tvb, offset) (byte_order == ENC_BIG_ENDIAN ? tvb_get_ntohieee_float(tvb, offset) : tvb_get_letohieee_float(tvb, offset))
  975. #define DOUBLE(tvb, offset) (byte_order == ENC_BIG_ENDIAN ? tvb_get_ntohieee_double(tvb, offset) : tvb_get_letohieee_double(tvb, offset))
  976. #define FIELD8(name) (field8(tvb, offsetp, t, hf_x11_##name, byte_order))
  977. #define FIELD16(name) (field16(tvb, offsetp, t, hf_x11_##name, byte_order))
  978. #define FIELD32(name) (field32(tvb, offsetp, t, hf_x11_##name, byte_order))
  979. #define BITFIELD(TYPE, position, name) { \
  980. int unused; \
  981. int save = *offsetp; \
  982. proto_tree_add_item(bitmask_tree, hf_x11_##position##_##name, tvb, bitmask_offset, \
  983. bitmask_size, byte_order); \
  984. if (bitmask_value & proto_registrar_get_nth(hf_x11_##position##_##name) -> bitmask) { \
  985. TYPE(name); \
  986. unused = save + 4 - *offsetp; \
  987. if (unused) \
  988. proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, unused, ENC_NA); \
  989. *offsetp = save + 4; \
  990. } \
  991. }
  992. #define FLAG(position, name) {\
  993. proto_tree_add_boolean(bitmask_tree, hf_x11_##position##_mask##_##name, tvb, bitmask_offset, bitmask_size, bitmask_value); }
  994. #define FLAG_IF_NONZERO(position, name) do {\
  995. if (bitmask_value & proto_registrar_get_nth(hf_x11_##position##_mask##_##name) -> bitmask) \
  996. proto_tree_add_boolean(bitmask_tree, hf_x11_##position##_mask##_##name, tvb, bitmask_offset, bitmask_size, bitmask_value); } while (0)
  997. #define ATOM(name) { atom(tvb, offsetp, t, hf_x11_##name, byte_order); }
  998. #define BITGRAVITY(name) { gravity(tvb, offsetp, t, hf_x11_##name, "Forget"); }
  999. #define BITMASK(name, size) {\
  1000. proto_item *bitmask_ti; \
  1001. guint32 bitmask_value; \
  1002. int bitmask_offset; \
  1003. int bitmask_size; \
  1004. proto_tree *bitmask_tree; \
  1005. bitmask_value = ((size == 1) ? (guint32)VALUE8(tvb, *offsetp) : \
  1006. ((size == 2) ? (guint32)VALUE16(tvb, *offsetp) : \
  1007. (guint32)VALUE32(tvb, *offsetp))); \
  1008. bitmask_offset = *offsetp; \
  1009. bitmask_size = size; \
  1010. bitmask_ti = proto_tree_add_uint(t, hf_x11_##name##_mask, tvb, *offsetp, size, bitmask_value); \
  1011. bitmask_tree = proto_item_add_subtree(bitmask_ti, ett_x11_##name##_mask); \
  1012. *offsetp += size;
  1013. #define ENDBITMASK }
  1014. #define BITMASK8(name) BITMASK(name, 1);
  1015. #define BITMASK16(name) BITMASK(name, 2);
  1016. #define BITMASK32(name) BITMASK(name, 4);
  1017. #define BOOL(name) (add_boolean(tvb, offsetp, t, hf_x11_##name))
  1018. #define BUTTON(name) FIELD8(name)
  1019. #define CARD8(name) FIELD8(name)
  1020. #define CARD16(name) (FIELD16(name))
  1021. #define CARD32(name) (FIELD32(name))
  1022. #define COLOR_FLAGS(name) colorFlags(tvb, offsetp, t)
  1023. #define COLORMAP(name) FIELD32(name)
  1024. #define CURSOR(name) FIELD32(name)
  1025. #define DRAWABLE(name) FIELD32(name)
  1026. #define ENUM8(name) (FIELD8(name))
  1027. #define ENUM16(name) (FIELD16(name))
  1028. #define FONT(name) FIELD32(name)
  1029. #define FONTABLE(name) FIELD32(name)
  1030. #define GCONTEXT(name) FIELD32(name)
  1031. #define INT8(name) FIELD8(name)
  1032. #define INT16(name) FIELD16(name)
  1033. #define INT32(name) FIELD32(name)
  1034. #define KEYCODE(name) FIELD8(name)
  1035. #define KEYCODE_DECODED(name, keycode, mask) do { \
  1036. proto_tree_add_uint_format(t, hf_x11_##name, tvb, offset, 1, \
  1037. keycode, "keycode: %d (%s)", \
  1038. keycode, keycode2keysymString(state->keycodemap, \
  1039. state->first_keycode, state->keysyms_per_keycode, \
  1040. state->modifiermap, state->keycodes_per_modifier, \
  1041. keycode, mask)); \
  1042. ++offset; \
  1043. } while (0)
  1044. #define EVENT() do { \
  1045. tvbuff_t *next_tvb; \
  1046. unsigned char eventcode; \
  1047. const char *sent; \
  1048. proto_item *event_ti; \
  1049. proto_tree *event_proto_tree; \
  1050. next_tvb = tvb_new_subset(tvb, offset, next_offset - offset, \
  1051. next_offset - offset); \
  1052. eventcode = tvb_get_guint8(next_tvb, 0); \
  1053. sent = (eventcode & 0x80) ? "Sent-" : ""; \
  1054. event_ti = proto_tree_add_text(t, next_tvb, 0, -1, \
  1055. "event: %d (%s)", \
  1056. eventcode, \
  1057. val_to_str(eventcode & 0x7F, \
  1058. state->eventcode_vals, \
  1059. "<Unknown eventcode %u>")); \
  1060. event_proto_tree = proto_item_add_subtree(event_ti, \
  1061. ett_x11_event); \
  1062. decode_x11_event(next_tvb, eventcode, sent, event_proto_tree, \
  1063. state, byte_order); \
  1064. offset = next_offset; \
  1065. } while (0)
  1066. #define LISTofARC(name) { listOfArc(tvb, offsetp, t, hf_x11_##name, (next_offset - *offsetp) / 12, byte_order); }
  1067. #define LISTofATOM(name, length) { listOfAtom(tvb, offsetp, t, hf_x11_##name, (length) / 4, byte_order); }
  1068. #define LISTofBYTE(name, length) { listOfByte(tvb, offsetp, t, hf_x11_##name, (length), byte_order); }
  1069. #define LISTofCARD8(name, length) { listOfByte(tvb, offsetp, t, hf_x11_##name, (length), byte_order); }
  1070. #define LISTofIPADDRESS(name, length) { listOfByte(tvb, offsetp, t, hf_x11_##name, (length), FALSE); }
  1071. #define LISTofCARD16(name, length) { listOfCard16(tvb, offsetp, t, hf_x11_##name, hf_x11_##name##_item, (length) / 2, byte_order); }
  1072. #define LISTofCARD32(name, length) { listOfCard32(tvb, offsetp, t, hf_x11_##name, hf_x11_##name##_item, (length) / 4, byte_order); }
  1073. #define LISTofCOLORITEM(name, length) { listOfColorItem(tvb, offsetp, t, hf_x11_##name, (length) / 12, byte_order); }
  1074. #define LISTofKEYCODE(map, name, length) { listOfKeycode(tvb, offsetp, t, hf_x11_##name, map, (length), byte_order); }
  1075. #define LISTofKEYSYM(name, map, keycode_first, keycode_count, \
  1076. keysyms_per_keycode) {\
  1077. listOfKeysyms(tvb, offsetp, t, hf_x11_##name, hf_x11_##name##_item, map, (keycode_first), (keycode_count), (keysyms_per_keycode), byte_order); }
  1078. #define LISTofPOINT(name, length) { listOfPoint(tvb, offsetp, t, hf_x11_##name, (length) / 4, byte_order); }
  1079. #define LISTofRECTANGLE(name) { listOfRectangle(tvb, offsetp, t, hf_x11_##name, (next_offset - *offsetp) / 8, byte_order); }
  1080. #define LISTofSEGMENT(name) { listOfSegment(tvb, offsetp, t, hf_x11_##name, (next_offset - *offsetp) / 8, byte_order); }
  1081. #define LISTofSTRING8(name, length) { listOfString8(tvb, offsetp, t, hf_x11_##name, hf_x11_##name##_string, (length), byte_order); }
  1082. #define LISTofTEXTITEM8(name) { listOfTextItem(tvb, offsetp, t, hf_x11_##name, FALSE, next_offset, byte_order); }
  1083. #define LISTofTEXTITEM16(name) { listOfTextItem(tvb, offsetp, t, hf_x11_##name, TRUE, next_offset, byte_order); }
  1084. #define OPCODE() { \
  1085. opcode = VALUE8(tvb, *offsetp); \
  1086. proto_tree_add_uint_format(t, hf_x11_opcode, tvb, *offsetp, \
  1087. 1, opcode, "opcode: %u (%s)", opcode, \
  1088. val_to_str_const(opcode, state->opcode_vals, "Unknown")); \
  1089. *offsetp += 1; \
  1090. }
  1091. #define PIXMAP(name) { FIELD32(name); }
  1092. #define REQUEST_LENGTH() (requestLength(tvb, offsetp, t, byte_order))
  1093. #define SETofEVENT(name) { setOfEvent(tvb, offsetp, t, byte_order); }
  1094. #define SETofDEVICEEVENT(name) { setOfDeviceEvent(tvb, offsetp, t, byte_order);}
  1095. #define SETofKEYMASK(name) { setOfKeyButMask(tvb, offsetp, t, byte_order, 0); }
  1096. #define SETofKEYBUTMASK(name) { setOfKeyButMask(tvb, offsetp, t, byte_order, 1); }
  1097. #define SETofPOINTEREVENT(name) { setOfPointerEvent(tvb, offsetp, t, byte_order); }
  1098. #define STRING8(name, length) { string8(tvb, offsetp, t, hf_x11_##name, length); }
  1099. #define STRING16(name, length) { string16(tvb, offsetp, t, hf_x11_##name, hf_x11_##name##_bytes, length, byte_order); }
  1100. #define TIMESTAMP(name){ timestamp(tvb, offsetp, t, hf_x11_##name, byte_order); }
  1101. #define UNDECODED(x) { proto_tree_add_item(t, hf_x11_undecoded, tvb, *offsetp, x, ENC_NA); *offsetp += x; }
  1102. #define UNUSED(x) { proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, x, ENC_NA); *offsetp += x; }
  1103. #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; }
  1104. #define WINDOW(name) { FIELD32(name); }
  1105. #define WINGRAVITY(name) { gravity(tvb, offsetp, t, hf_x11_##name, "Unmap"); }
  1106. #define VISUALID(name) { gint32 v = VALUE32(tvb, *offsetp); \
  1107. proto_tree_add_uint_format(t, hf_x11_##name, tvb, *offsetp, 4, v, "Visualid: 0x%08x%s", v, \
  1108. v ? "" : " (CopyFromParent)"); *offsetp += 4; }
  1109. #define REPLY(name) FIELD8(name);
  1110. #define REPLYLENGTH(name) FIELD32(name);
  1111. #define EVENTCONTENTS_COMMON() do { \
  1112. TIMESTAMP(time); \
  1113. WINDOW(rootwindow); \
  1114. WINDOW(eventwindow); \
  1115. WINDOW(childwindow); \
  1116. INT16(root_x); \
  1117. INT16(root_y); \
  1118. INT16(event_x); \
  1119. INT16(event_y); \
  1120. setOfKeyButMask(tvb, offsetp, t, byte_order, 1); \
  1121. } while (0)
  1122. #define SEQUENCENUMBER_REPLY(name) do { \
  1123. guint16 seqno; \
  1124. \
  1125. seqno = VALUE16(tvb, *offsetp); \
  1126. proto_tree_add_uint_format(t, hf_x11_reply_##name, tvb, \
  1127. *offsetp, 2, seqno, \
  1128. "sequencenumber: %d (%s)", \
  1129. (int)seqno, \
  1130. val_to_str(opcode & 0xFF, state->opcode_vals, "<Unknown opcode %d>")); \
  1131. *offsetp += 2; \
  1132. } while (0)
  1133. #define REPLYCONTENTS_COMMON() do { \
  1134. REPLY(reply); \
  1135. proto_tree_add_item(t, hf_x11_undecoded, tvb, *offsetp, \
  1136. 1, ENC_NA); \
  1137. ++(*offsetp); \
  1138. SEQUENCENUMBER_REPLY(sequencenumber); \
  1139. REPLYLENGTH(replylength); \
  1140. proto_tree_add_item(t, hf_x11_undecoded, tvb, *offsetp, \
  1141. tvb_reported_length_remaining(tvb, *offsetp), ENC_NA); \
  1142. *offsetp += tvb_reported_length_remaining(tvb, *offsetp); \
  1143. } while (0)
  1144. #define HANDLE_REPLY(plen, length_remaining, str, func) do { \
  1145. if (length_remaining < plen) { \
  1146. if (x11_desegment && pinfo->can_desegment) { \
  1147. pinfo->desegment_offset = offset; \
  1148. pinfo->desegment_len = plen - length_remaining; \
  1149. return; \
  1150. } else { \
  1151. ; /* XXX yes, what then? Need to skip/join. */ \
  1152. } \
  1153. } \
  1154. if (length_remaining > plen) \
  1155. length_remaining = plen; \
  1156. next_tvb = tvb_new_subset(tvb, offset, length_remaining, plen); \
  1157. \
  1158. if (sep == NULL) { \
  1159. col_set_str(pinfo->cinfo, COL_INFO, str); \
  1160. sep = ":"; \
  1161. } \
  1162. \
  1163. TRY { \
  1164. func(next_tvb, pinfo, tree, sep, state, byte_order); \
  1165. } \
  1166. \
  1167. CATCH_NONFATAL_ERRORS { \
  1168. show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE); \
  1169. } \
  1170. ENDTRY; \
  1171. \
  1172. sep = ","; \
  1173. } while (0)
  1174. static void
  1175. dissect_x11_initial_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
  1176. const char *sep, x11_conv_data_t *volatile state,
  1177. guint byte_order);
  1178. static void
  1179. dissect_x11_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
  1180. const char *volatile sep, x11_conv_data_t *volatile state,
  1181. guint byte_order);
  1182. static void
  1183. dissect_x11_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
  1184. const char *volatile sep, x11_conv_data_t *volatile state,
  1185. guint byte_order);
  1186. static void
  1187. dissect_x11_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
  1188. const char *volatile sep, x11_conv_data_t *volatile state,
  1189. guint byte_order);
  1190. static void
  1191. decode_x11_event(tvbuff_t *tvb, unsigned char eventcode, const char *sent,
  1192. proto_tree *t, x11_conv_data_t *volatile state,
  1193. guint byte_order);
  1194. static x11_conv_data_t *
  1195. x11_stateinit(conversation_t *conversation);
  1196. static const char *
  1197. keysymString(guint32 v);
  1198. /************************************************************************
  1199. *** ***
  1200. *** D E C O D I N G F I E L D S ***
  1201. *** ***
  1202. ************************************************************************/
  1203. static void atom(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1204. guint byte_order)
  1205. {
  1206. const char *interpretation = NULL;
  1207. guint32 v = VALUE32(tvb, *offsetp);
  1208. if (v >= 1 && v < array_length(atom_predefined_interpretation))
  1209. interpretation = atom_predefined_interpretation[v];
  1210. else if (v)
  1211. interpretation = "Not a predefined atom";
  1212. else {
  1213. header_field_info *hfi = proto_registrar_get_nth(hf);
  1214. if (hfi -> strings)
  1215. interpretation = try_val_to_str(v, cVALS(hfi -> strings));
  1216. }
  1217. if (!interpretation) interpretation = "error in Xlib client program ?";
  1218. proto_tree_add_uint_format(t, hf, tvb, *offsetp, 4, v, "%s: %u (%s)",
  1219. proto_registrar_get_nth(hf) -> name, v, interpretation);
  1220. *offsetp += 4;
  1221. }
  1222. static guint32 add_boolean(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf)
  1223. {
  1224. guint32 v = VALUE8(tvb, *offsetp);
  1225. proto_tree_add_boolean(t, hf, tvb, *offsetp, 1, v);
  1226. *offsetp += 1;
  1227. return v;
  1228. }
  1229. static void colorFlags(tvbuff_t *tvb, int *offsetp, proto_tree *t)
  1230. {
  1231. guint do_red_green_blue = VALUE8(tvb, *offsetp);
  1232. proto_item *ti;
  1233. proto_tree *tt;
  1234. if (do_red_green_blue) {
  1235. int sep = FALSE;
  1236. emem_strbuf_t *buffer = ep_strbuf_new_label("flags: ");
  1237. if (do_red_green_blue & 0x1) {
  1238. ep_strbuf_append(buffer, "DoRed");
  1239. sep = TRUE;
  1240. }
  1241. if (do_red_green_blue & 0x2) {
  1242. if (sep) ep_strbuf_append(buffer, " | ");
  1243. ep_strbuf_append(buffer, "DoGreen");
  1244. sep = TRUE;
  1245. }
  1246. if (do_red_green_blue & 0x4) {
  1247. if (sep) ep_strbuf_append(buffer, " | ");
  1248. ep_strbuf_append(buffer, "DoBlue");
  1249. sep = TRUE;
  1250. }
  1251. if (do_red_green_blue & 0xf8) {
  1252. if (sep) ep_strbuf_append(buffer, " + trash");
  1253. }
  1254. ti = proto_tree_add_uint_format(t, hf_x11_coloritem_flags, tvb, *offsetp, 1, do_red_green_blue,
  1255. "%s", buffer->str);
  1256. tt = proto_item_add_subtree(ti, ett_x11_color_flags);
  1257. if (do_red_green_blue & 0x1)
  1258. proto_tree_add_boolean(tt, hf_x11_coloritem_flags_do_red, tvb, *offsetp, 1,
  1259. do_red_green_blue & 0x1);
  1260. if (do_red_green_blue & 0x2)
  1261. proto_tree_add_boolean(tt, hf_x11_coloritem_flags_do_green, tvb, *offsetp, 1,
  1262. do_red_green_blue & 0x2);
  1263. if (do_red_green_blue & 0x4)
  1264. proto_tree_add_boolean(tt, hf_x11_coloritem_flags_do_blue, tvb, *offsetp, 1,
  1265. do_red_green_blue & 0x4);
  1266. if (do_red_green_blue & 0xf8)
  1267. proto_tree_add_boolean(tt, hf_x11_coloritem_flags_unused, tvb, *offsetp, 1,
  1268. do_red_green_blue & 0xf8);
  1269. } else
  1270. proto_tree_add_uint_format(t, hf_x11_coloritem_flags, tvb, *offsetp, 1, do_red_green_blue,
  1271. "flags: none");
  1272. *offsetp += 1;
  1273. }
  1274. static void gravity(tvbuff_t *tvb, int *offsetp, proto_tree *t,
  1275. int hf, const char *nullInterpretation)
  1276. {
  1277. guint8 v = VALUE8(tvb, *offsetp);
  1278. if (!v)
  1279. proto_tree_add_uint_format(t, hf, tvb, *offsetp, 1, v, "%s: 0 (%s)",
  1280. proto_registrar_get_nth(hf) -> name,
  1281. nullInterpretation);
  1282. else
  1283. proto_tree_add_uint(t, hf, tvb, *offsetp, 1, v);
  1284. *offsetp += 1;
  1285. }
  1286. static void listOfArc(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1287. int length, guint byte_order)
  1288. {
  1289. proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 8, byte_order);
  1290. proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_arc);
  1291. while(length--) {
  1292. gint16 x = VALUE16(tvb, *offsetp);
  1293. gint16 y = VALUE16(tvb, *offsetp + 2);
  1294. guint16 width = VALUE16(tvb, *offsetp + 4);
  1295. guint16 height = VALUE16(tvb, *offsetp + 6);
  1296. gint16 angle1 = VALUE16(tvb, *offsetp + 8);
  1297. gint16 angle2 = VALUE16(tvb, *offsetp + 10);
  1298. proto_item *tti = proto_tree_add_none_format(tt, hf_x11_arc, tvb, *offsetp, 12,
  1299. "arc: %dx%d+%d+%d, angle %d -> %d (%f degrees -> %f degrees)",
  1300. width, height, x, y, angle1, angle2,
  1301. angle1 / 64.0, angle2 / 64.0);
  1302. proto_tree *ttt = proto_item_add_subtree(tti, ett_x11_arc);
  1303. proto_tree_add_int(ttt, hf_x11_arc_x, tvb, *offsetp, 2, x);
  1304. *offsetp += 2;
  1305. proto_tree_add_int(ttt, hf_x11_arc_y, tvb, *offsetp, 2, y);
  1306. *offsetp += 2;
  1307. proto_tree_add_uint(ttt, hf_x11_arc_width, tvb, *offsetp, 2, y);
  1308. *offsetp += 2;
  1309. proto_tree_add_uint(ttt, hf_x11_arc_height, tvb, *offsetp, 2, y);
  1310. *offsetp += 2;
  1311. proto_tree_add_int(ttt, hf_x11_arc_angle1, tvb, *offsetp, 2, y);
  1312. *offsetp += 2;
  1313. proto_tree_add_int(ttt, hf_x11_arc_angle2, tvb, *offsetp, 2, y);
  1314. *offsetp += 2;
  1315. }
  1316. }
  1317. static void listOfAtom(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1318. int length, guint byte_order)
  1319. {
  1320. proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 4, byte_order);
  1321. proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_atom);
  1322. while(length--)
  1323. atom(tvb, offsetp, tt, hf_x11_properties_item, byte_order);
  1324. }
  1325. static void listOfByte(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1326. int length, guint byte_order)
  1327. {
  1328. if (length <= 0) length = 1;
  1329. proto_tree_add_item(t, hf, tvb, *offsetp, length, byte_order);
  1330. *offsetp += length;
  1331. }
  1332. static void listOfCard16(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1333. int hf_item, int length, guint byte_order)
  1334. {
  1335. proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 2, byte_order);
  1336. proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_card32);
  1337. while(length--) {
  1338. proto_tree_add_uint(tt, hf_item, tvb, *offsetp, 2, VALUE16(tvb, *offsetp));
  1339. *offsetp += 2;
  1340. }
  1341. }
  1342. static void listOfInt16(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1343. int hf_item, int length, guint byte_order)
  1344. {
  1345. proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 2, byte_order);
  1346. proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_card32);
  1347. while(length--) {
  1348. proto_tree_add_int(tt, hf_item, tvb, *offsetp, 2, VALUE16(tvb, *offsetp));
  1349. *offsetp += 2;
  1350. }
  1351. }
  1352. static void listOfCard32(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1353. int hf_item, int length, guint byte_order)
  1354. {
  1355. proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 4, byte_order);
  1356. proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_card32);
  1357. while(length--) {
  1358. proto_tree_add_uint(tt, hf_item, tvb, *offsetp, 4, VALUE32(tvb, *offsetp));
  1359. *offsetp += 4;
  1360. }
  1361. }
  1362. static void listOfInt32(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1363. int hf_item, int length, guint byte_order)
  1364. {
  1365. proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 4, byte_order);
  1366. proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_card32);
  1367. while(length--) {
  1368. proto_tree_add_int(tt, hf_item, tvb, *offsetp, 4, VALUE32(tvb, *offsetp));
  1369. *offsetp += 4;
  1370. }
  1371. }
  1372. static void listOfFloat(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1373. int hf_item, int length, guint byte_order)
  1374. {
  1375. proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 4, byte_order);
  1376. proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_float);
  1377. while(length--) {
  1378. proto_tree_add_float(tt, hf_item, tvb, *offsetp, 4, FLOAT(tvb, *offsetp));
  1379. *offsetp += 4;
  1380. }
  1381. }
  1382. static void listOfDouble(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1383. int hf_item, int length, guint byte_order)
  1384. {
  1385. proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 8, byte_order);
  1386. proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_double);
  1387. while(length--) {
  1388. proto_tree_add_double(tt, hf_item, tvb, *offsetp, 8, DOUBLE(tvb, *offsetp));
  1389. *offsetp += 8;
  1390. }
  1391. }
  1392. static void listOfColorItem(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1393. int length, guint byte_order)
  1394. {
  1395. proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 8, byte_order);
  1396. proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_color_item);
  1397. while(length--) {
  1398. proto_item *tti;
  1399. proto_tree *ttt;
  1400. guint do_red_green_blue;
  1401. guint16 red, green, blue;
  1402. emem_strbuf_t *buffer;
  1403. const char *sep;
  1404. buffer=ep_strbuf_new_label("colorItem ");
  1405. red = VALUE16(tvb, *offsetp + 4);
  1406. green = VALUE16(tvb, *offsetp + 6);
  1407. blue = VALUE16(tvb, *offsetp + 8);
  1408. do_red_green_blue = VALUE8(tvb, *offsetp + 10);
  1409. sep = "";
  1410. if (do_red_green_blue & 0x1) {
  1411. ep_strbuf_append_printf(buffer, "red = %d", red);
  1412. sep = ", ";
  1413. }
  1414. if (do_red_green_blue & 0x2) {
  1415. ep_strbuf_append_printf(buffer, "%sgreen = %d", sep, green);
  1416. sep = ", ";
  1417. }
  1418. if (do_red_green_blue & 0x4)
  1419. ep_strbuf_append_printf(buffer, "%sblue = %d", sep, blue);
  1420. tti = proto_tree_add_none_format(tt, hf_x11_coloritem, tvb, *offsetp, 12, "%s", buffer->str);
  1421. ttt = proto_item_add_subtree(tti, ett_x11_color_item);
  1422. proto_tree_add_item(ttt, hf_x11_coloritem_pixel, tvb, *offsetp, 4, byte_order);
  1423. *offsetp += 4;
  1424. proto_tree_add_item(ttt, hf_x11_coloritem_red, tvb, *offsetp, 2, byte_order);
  1425. *offsetp += 2;
  1426. proto_tree_add_item(ttt, hf_x11_coloritem_green, tvb, *offsetp, 2, byte_order);
  1427. *offsetp += 2;
  1428. proto_tree_add_item(ttt, hf_x11_coloritem_blue, tvb, *offsetp, 2, byte_order);
  1429. *offsetp += 2;
  1430. colorFlags(tvb, offsetp, ttt);
  1431. proto_tree_add_item(ttt, hf_x11_coloritem_unused, tvb, *offsetp, 1, byte_order);
  1432. *offsetp += 1;
  1433. }
  1434. }
  1435. #if 0 /* XXX: Use of GTree no longer needed; use value_string_ext */
  1436. static gint compareGuint32(gconstpointer a, gconstpointer b)
  1437. {
  1438. return GPOINTER_TO_INT(b) - GPOINTER_TO_INT(a);
  1439. }
  1440. #endif
  1441. static void
  1442. XConvertCase(register int sym, int *lower, int *upper)
  1443. {
  1444. *lower = sym;
  1445. *upper = sym;
  1446. switch(sym >> 8) {
  1447. case 0: /* Latin 1 */
  1448. if ((sym >= XK_A) && (sym <= XK_Z))
  1449. *lower += (XK_a - XK_A);
  1450. else if ((sym >= XK_a) && (sym <= XK_z))
  1451. *upper -= (XK_a - XK_A);
  1452. else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
  1453. *lower += (XK_agrave - XK_Agrave);
  1454. else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
  1455. *upper -= (XK_agrave - XK_Agrave);
  1456. else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
  1457. *lower += (XK_oslash - XK_Ooblique);
  1458. else if ((sym >= XK_oslash) && (sym <= XK_thorn))
  1459. *upper -= (XK_oslash - XK_Ooblique);
  1460. break;
  1461. case 1: /* Latin 2 */
  1462. /* Assume the KeySym is a legal value (ignore discontinuities) */
  1463. if (sym == XK_Aogonek)
  1464. *lower = XK_aogonek;
  1465. else if (sym >= XK_Lstroke && sym <= XK_Sacute)
  1466. *lower += (XK_lstroke - XK_Lstroke);
  1467. else if (sym >= XK_Scaron && sym <= XK_Zacute)
  1468. *lower += (XK_scaron - XK_Scaron);
  1469. else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
  1470. *lower += (XK_zcaron - XK_Zcaron);
  1471. else if (sym == XK_aogonek)
  1472. *upper = XK_Aogonek;
  1473. else if (sym >= XK_lstroke && sym <= XK_sacute)
  1474. *upper -= (XK_lstroke - XK_Lstroke);
  1475. else if (sym >= XK_scaron && sym <= XK_zacute)
  1476. *upper -= (XK_scaron - XK_Scaron);
  1477. else if (sym >= XK_zcaron && sym <= XK_zabovedot)
  1478. *upper -= (XK_zcaron - XK_Zcaron);
  1479. else if (sym >= XK_Racute && sym <= XK_Tcedilla)
  1480. *lower += (XK_racute - XK_Racute);
  1481. else if (sym >= XK_racute && sym <= XK_tcedilla)
  1482. *upper -= (XK_racute - XK_Racute);
  1483. break;
  1484. case 2: /* Latin 3 */
  1485. /* Assume the KeySym is a legal value (ignore discontinuities) */
  1486. if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
  1487. *lower += (XK_hstroke - XK_Hstroke);
  1488. else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
  1489. *lower += (XK_gbreve - XK_Gbreve);
  1490. else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
  1491. *upper -= (XK_hstroke - XK_Hstroke);
  1492. else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
  1493. *upper -= (XK_gbreve - XK_Gbreve);
  1494. else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
  1495. *lower += (XK_cabovedot - XK_Cabovedot);
  1496. else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
  1497. *upper -= (XK_cabovedot - XK_Cabovedot);
  1498. break;
  1499. case 3: /* Latin 4 */
  1500. /* Assume the KeySym is a legal value (ignore discontinuities) */
  1501. if (sym >= XK_Rcedilla && sym <= XK_Tslash)
  1502. *lower += (XK_rcedilla - XK_Rcedilla);
  1503. else if (sym >= XK_rcedilla && sym <= XK_tslash)
  1504. *upper -= (XK_rcedilla - XK_Rcedilla);
  1505. else if (sym == XK_ENG)
  1506. *lower = XK_eng;
  1507. else if (sym == XK_eng)
  1508. *upper = XK_ENG;
  1509. else if (sym >= XK_Amacron && sym <= XK_Umacron)
  1510. *lower += (XK_amacron - XK_Amacron);
  1511. else if (sym >= XK_amacron && sym <= XK_umacron)
  1512. *upper -= (XK_amacron - XK_Amacron);
  1513. break;
  1514. case 6: /* Cyrillic */
  1515. /* Assume the KeySym is a legal value (ignore discontinuities) */
  1516. if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
  1517. *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
  1518. else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
  1519. *upper += (XK_Serbian_DJE - XK_Serbian_dje);
  1520. else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
  1521. *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
  1522. else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
  1523. *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
  1524. break;
  1525. case 7: /* Greek */
  1526. /* Assume the KeySym is a legal value (ignore discontinuities) */
  1527. if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
  1528. *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
  1529. else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
  1530. sym != XK_Greek_iotaaccentdieresis &&
  1531. sym != XK_Greek_upsilonaccentdieresis)
  1532. *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
  1533. else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
  1534. *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
  1535. else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
  1536. sym != XK_Greek_finalsmallsigma)
  1537. *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
  1538. break;
  1539. }
  1540. }
  1541. static const char *
  1542. keycode2keysymString(int *keycodemap[256], int first_keycode,
  1543. int keysyms_per_keycode,
  1544. int *modifiermap[array_length(modifiers)],
  1545. int keycodes_per_modifier,
  1546. guint32 keycode, guint32 bitmask)
  1547. {
  1548. int *syms;
  1549. int groupmodkc, numlockkc, numlockmod, groupmod;
  1550. int lockmod_is_capslock = 0, lockmod_is_shiftlock = 0;
  1551. int lockmod_is_nosymbol = 1;
  1552. int modifier, kc, keysym;
  1553. if ((syms = keycodemap[keycode]) == NULL)
  1554. return "<Unknown>";
  1555. for (kc = first_keycode, groupmodkc = numlockkc = -1; kc < 256; ++kc)
  1556. for (keysym = 0; keysym < keysyms_per_keycode; ++keysym) {
  1557. if (keycodemap[kc] == NULL)
  1558. return "<Unknown>";
  1559. switch (keycodemap[kc][keysym]) {
  1560. case 0xff7e:
  1561. groupmodkc = kc;
  1562. break;
  1563. case 0xff7f:
  1564. numlockkc = kc;
  1565. break;
  1566. case 0xffe5:
  1567. lockmod_is_capslock = kc;
  1568. break;
  1569. case 0xffe6:
  1570. lockmod_is_shiftlock = kc;
  1571. break;
  1572. }
  1573. }
  1574. /*
  1575. * If we have not seen the modifiermap we don't know what the
  1576. * keycode translates to, but we do know it's one of the keys
  1577. * in syms (give or take a case-conversion), so we could in
  1578. * theory list them all.
  1579. */
  1580. if (modifiermap[array_length(modifiers) - 1] == NULL) /* all or none */
  1581. return "<Unknown>";
  1582. /* find out what the numlockmodifer and groupmodifier is. */
  1583. for (modifier = 0, numlockmod = groupmod = -1;
  1584. modifier < (int)array_length(modifiers) && numlockmod == -1;
  1585. ++modifier)
  1586. for (kc = 0; kc < keycodes_per_modifier; ++kc)
  1587. if (modifiermap[modifier][kc] == numlockkc)
  1588. numlockmod = modifier;
  1589. else if (modifiermap[modifier][kc] == groupmodkc)
  1590. groupmod = modifier;
  1591. /*
  1592. * ... and what the lockmodifier is interpreted as.
  1593. * (X11v4r6 ref, keyboard and pointers section.)
  1594. */
  1595. for (kc = 0; kc < keycodes_per_modifier; ++kc)
  1596. if (modifiermap[1][kc] == lockmod_is_capslock) {
  1597. lockmod_is_shiftlock = lockmod_is_nosymbol = 0;
  1598. break;
  1599. }
  1600. else if (modifiermap[0][kc] == lockmod_is_shiftlock) {
  1601. lockmod_is_capslock = lockmod_is_nosymbol = 0;
  1602. break;
  1603. }
  1604. #if 0
  1605. /*
  1606. * This is (how I understand) the X11v4R6 protocol description given
  1607. * in A. Nye's book. It is quite different from the
  1608. * code in _XTranslateKey() in the file
  1609. * "$XConsortium: KeyBind.c /main/55 1996/02/02 14:08:55 kaleb $"
  1610. * as shipped with XFree, and doesn't work correctly, nor do I see
  1611. * how it could (e.g. the case of lower/uppercase-letters).
  1612. * -- Michael Shuldman
  1613. */
  1614. if (numlockmod >= 0 && (bitmask & modifiermask[numlockmod])
  1615. && ((syms[1] >= 0xff80
  1616. && syms[1] <= 0xffbd)
  1617. || (syms[1] >= 0x11000000
  1618. && syms[1] <= 0x1100ffff))) {
  1619. if ((bitmask & ShiftMask) || lockmod_is_shiftlock)
  1620. return keysymString(syms[groupmod + 0]);
  1621. else
  1622. if (syms[groupmod + 1] == NoSymbol)
  1623. return keysymString(syms[groupmod + 0]);
  1624. else
  1625. return keysymString(syms[groupmod + 1]);
  1626. }
  1627. else if (!(bitmask & ShiftMask) && !(bitmask & LockMask))
  1628. return keysymString(syms[groupmod + 0]);
  1629. else if (!(bitmask & ShiftMask)
  1630. && ((bitmask & LockMask) && lockmod_is_capslock))
  1631. if (islower(syms[groupmod + 0]))
  1632. /* return toupper(keysymString(syms[groupmod + 0])); */
  1633. return "Uppercase"; /* XXX */
  1634. else
  1635. return keysymString(syms[groupmod + 0]);
  1636. else if ((bitmask & ShiftMask)
  1637. && ((bitmask & LockMask) && lockmod_is_capslock))
  1638. if (islower(syms[groupmod + 1]))
  1639. /* return toupper(keysymString(syms[groupmod + 1])); */
  1640. return "Uppercase"; /* XXX */
  1641. else
  1642. return keysymString(syms[groupmod + 1]);
  1643. else if ((bitmask & ShiftMask)
  1644. || ((bitmask & LockMask) && lockmod_is_shiftlock))
  1645. return keysymString(syms[groupmod + 1]);
  1646. #else /* _XTranslateKey() based code. */
  1647. while (keysyms_per_keycode > 2
  1648. && keycodemap[keysyms_per_keycode - 1] == NoSymbol)
  1649. --keysyms_per_keycode;
  1650. if (keysyms_per_keycode > 2
  1651. && (groupmod >= 0 && (modifiermask[groupmod] & bitmask))) {
  1652. syms += 2;
  1653. keysyms_per_keycode -= 2;
  1654. }
  1655. if (numlockmod >= 0 && (bitmask & modifiermask[numlockmod])
  1656. && keysyms_per_keycode > 1
  1657. && ((syms[1] >= 0xff80 && syms[1] <= 0xffbd)
  1658. || (syms[1] >= 0x11000000 && syms[1] <= 0x1100ffff))) {
  1659. if ((bitmask & ShiftMask)
  1660. || (bitmask & LockMask && lockmod_is_shiftlock))
  1661. keysym = syms[0];
  1662. else
  1663. keysym = syms[1];
  1664. }
  1665. else if (!(bitmask & ShiftMask)
  1666. && (!(bitmask & LockMask) || lockmod_is_nosymbol)) {
  1667. if (keysyms_per_keycode == 1
  1668. || (keysyms_per_keycode > 1 && syms[1] == NoSymbol)) {
  1669. int usym;
  1670. XConvertCase(syms[0], &keysym, &usym);
  1671. }
  1672. else
  1673. keysym = syms[0];
  1674. }
  1675. else if (!(bitmask & LockMask) || !lockmod_is_capslock) {
  1676. int lsym, usym = 0;
  1677. if (keysyms_per_keycode == 1
  1678. || (keysyms_per_keycode > 1 && (usym = syms[1]) == NoSymbol))
  1679. XConvertCase(syms[0], &lsym, &usym);
  1680. keysym = usym;
  1681. }
  1682. else {
  1683. int lsym, usym = 0;
  1684. if (keysyms_per_keycode == 1
  1685. || (keysyms_per_keycode > 1 && syms[1] == NoSymbol))
  1686. keysym = syms[0];
  1687. XConvertCase(keysym, &lsym, &usym);
  1688. if (!(bitmask & ShiftMask) && keysym != syms[0]
  1689. && ((keysym != usym) || (lsym == usym)))
  1690. XConvertCase(syms[0], &lsym, &usym);
  1691. keysym = usym;
  1692. }
  1693. if (keysym == XK_VoidSymbol)
  1694. keysym = NoSymbol;
  1695. return ep_strdup_printf("%d, \"%s\"", keysym, keysymString(keysym));
  1696. #endif
  1697. }
  1698. static const char *keysymString(guint32 v)
  1699. {
  1700. #if 0 /* XXX: Use of GTree no longer needed; use value_string_ext */
  1701. static GTree *keysymTable = NULL;
  1702. gpointer res;
  1703. if (!keysymTable) {
  1704. /* This table is so big that we built it only if necessary */
  1705. const value_string *p = x11_keysym_vals_source;
  1706. keysymTable = g_tree_new(compareGuint32);
  1707. for(; p -> strptr; p++)
  1708. g_tree_insert(keysymTable, GINT_TO_POINTER(p -> value), (gpointer) (p -> strptr) );
  1709. }
  1710. res = g_tree_lookup(keysymTable, GINT_TO_POINTER(v));
  1711. return res ? res : "<Unknown>";
  1712. #endif
  1713. return val_to_str_ext_const(v, &x11_keysym_vals_source_ext, "<Unknown>");
  1714. }
  1715. static void listOfKeycode(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1716. int *modifiermap[], int keycodes_per_modifier,
  1717. guint byte_order _U_)
  1718. {
  1719. proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp,
  1720. (int)array_length(modifiers) * keycodes_per_modifier, ENC_NA);
  1721. proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_keycode);
  1722. size_t m;
  1723. for (m = 0; m < array_length(modifiers);
  1724. ++m, *offsetp += keycodes_per_modifier) {
  1725. const guint8 *p;
  1726. proto_item *tikc;
  1727. int i;
  1728. p = tvb_get_ptr(tvb, *offsetp, keycodes_per_modifier);
  1729. modifiermap[m] = (int *)
  1730. g_malloc(sizeof(*modifiermap[m]) * keycodes_per_modifier);
  1731. tikc = proto_tree_add_bytes_format(tt, hf_x11_keycodes_item, tvb,
  1732. *offsetp, keycodes_per_modifier, p, "item: ");
  1733. for(i = 0; i < keycodes_per_modifier; ++i) {
  1734. guchar c = p[i];
  1735. if (c)
  1736. proto_item_append_text(tikc, " %s=%d", modifiers[m], c);
  1737. modifiermap[m][i] = c;
  1738. }
  1739. }
  1740. }
  1741. static void listOfKeysyms(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1742. int hf_item, int *keycodemap[256],
  1743. int keycode_first, int keycode_count,
  1744. int keysyms_per_keycode, guint byte_order)
  1745. {
  1746. proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, keycode_count * keysyms_per_keycode * 4, byte_order);
  1747. proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_keysyms);
  1748. proto_item *tti;
  1749. proto_tree *ttt;
  1750. int i, keycode;
  1751. DISSECTOR_ASSERT(keycode_first >= 0);
  1752. DISSECTOR_ASSERT(keycode_count >= 0);
  1753. for (keycode = keycode_first; keycode_count > 0;
  1754. ++keycode, --keycode_count) {
  1755. if (keycode >= 256) {
  1756. proto_tree_add_text(tt, tvb, *offsetp, 4 * keysyms_per_keycode,
  1757. "keycode value %d is out of range", keycode);
  1758. *offsetp += 4 * keysyms_per_keycode;
  1759. continue;
  1760. }
  1761. tti = proto_tree_add_none_format(tt, hf_item, tvb, *offsetp,
  1762. 4 * keysyms_per_keycode, "keysyms (keycode %d):", keycode);
  1763. ttt = proto_item_add_subtree(tti, ett_x11_keysym);
  1764. tvb_ensure_bytes_exist(tvb, *offsetp, 4 * keysyms_per_keycode);
  1765. keycodemap[keycode]
  1766. = (int *)g_malloc(sizeof(*keycodemap[keycode]) * keysyms_per_keycode);
  1767. for(i = 0; i < keysyms_per_keycode; ++i) {
  1768. /* keysymvalue = byte3 * 256 + byte4. */
  1769. guint32 v = VALUE32(tvb, *offsetp);
  1770. proto_item_append_text(tti, " %s", keysymString(v));
  1771. proto_tree_add_uint_format(ttt, hf_x11_keysyms_item_keysym,
  1772. tvb, *offsetp, 4, v,
  1773. "keysym (keycode %d): 0x%08x (%s)",
  1774. keycode, v, keysymString(v));
  1775. keycodemap[keycode][i] = v;
  1776. *offsetp += 4;
  1777. }
  1778. for (i = 1; i < keysyms_per_keycode; ++i)
  1779. if (keycodemap[keycode][i] != NoSymbol)
  1780. break;
  1781. if (i == keysyms_per_keycode) {
  1782. /* all but (possibly) first were NoSymbol. */
  1783. if (keysyms_per_keycode == 4) {
  1784. keycodemap[keycode][1] = NoSymbol;
  1785. keycodemap[keycode][2] = keycodemap[keycode][0];
  1786. keycodemap[keycode][3] = NoSymbol;
  1787. }
  1788. continue;
  1789. }
  1790. for (i = 2; i < keysyms_per_keycode; ++i)
  1791. if (keycodemap[keycode][i] != NoSymbol)
  1792. break;
  1793. if (i == keysyms_per_keycode) {
  1794. /* all but (possibly) first two were NoSymbol. */
  1795. if (keysyms_per_keycode == 4) {
  1796. keycodemap[keycode][2] = keycodemap[keycode][0];
  1797. keycodemap[keycode][3] = keycodemap[keycode][1];
  1798. }
  1799. continue;
  1800. }
  1801. }
  1802. }
  1803. static void listOfPoint(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1804. int length, guint byte_order)
  1805. {
  1806. proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 4, byte_order);
  1807. proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_point);
  1808. while(length--) {
  1809. gint16 x, y;
  1810. proto_item *tti;
  1811. proto_tree *ttt;
  1812. x = VALUE16(tvb, *offsetp);
  1813. y = VALUE16(tvb, *offsetp + 2);
  1814. tti = proto_tree_add_none_format(tt, hf_x11_point, tvb, *offsetp, 4, "point: (%d,%d)", x, y);
  1815. ttt = proto_item_add_subtree(tti, ett_x11_point);
  1816. proto_tree_add_int(ttt, hf_x11_point_x, tvb, *offsetp, 2, x);
  1817. *offsetp += 2;
  1818. proto_tree_add_int(ttt, hf_x11_point_y, tvb, *offsetp, 2, y);
  1819. *offsetp += 2;
  1820. }
  1821. }
  1822. static void listOfRectangle(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1823. int length, guint byte_order)
  1824. {
  1825. proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 8, byte_order);
  1826. proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_rectangle);
  1827. while(length--) {
  1828. gint16 x, y;
  1829. guint width, height;
  1830. proto_item *tti;
  1831. proto_tree *ttt;
  1832. x = VALUE16(tvb, *offsetp);
  1833. y = VALUE16(tvb, *offsetp + 2);
  1834. width = VALUE16(tvb, *offsetp + 4);
  1835. height = VALUE16(tvb, *offsetp + 6);
  1836. tti = proto_tree_add_none_format(tt, hf_x11_rectangle, tvb, *offsetp, 8,
  1837. "rectangle: %dx%d+%d+%d", width, height, x, y);
  1838. ttt = proto_item_add_subtree(tti, ett_x11_rectangle);
  1839. proto_tree_add_int(ttt, hf_x11_rectangle_x, tvb, *offsetp, 2, x);
  1840. *offsetp += 2;
  1841. proto_tree_add_int(ttt, hf_x11_rectangle_y, tvb, *offsetp, 2, y);
  1842. *offsetp += 2;
  1843. proto_tree_add_uint(ttt, hf_x11_rectangle_width, tvb, *offsetp, 2, width);
  1844. *offsetp += 2;
  1845. proto_tree_add_uint(ttt, hf_x11_rectangle_height, tvb, *offsetp, 2, height);
  1846. *offsetp += 2;
  1847. }
  1848. }
  1849. static void listOfSegment(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1850. int length, guint byte_order)
  1851. {
  1852. proto_item *ti = proto_tree_add_item(t, hf, tvb, *offsetp, length * 8, byte_order);
  1853. proto_tree *tt = proto_item_add_subtree(ti, ett_x11_list_of_segment);
  1854. while(length--) {
  1855. gint16 x1, y1, x2, y2;
  1856. proto_item *tti;
  1857. proto_tree *ttt;
  1858. x1 = VALUE16(tvb, *offsetp);
  1859. y1 = VALUE16(tvb, *offsetp + 2);
  1860. x2 = VALUE16(tvb, *offsetp + 4);
  1861. y2 = VALUE16(tvb, *offsetp + 6);
  1862. tti = proto_tree_add_none_format(tt, hf_x11_segment, tvb, *offsetp, 8,
  1863. "segment: (%d,%d)-(%d,%d)", x1, y1, x2, y2);
  1864. ttt = proto_item_add_subtree(tti, ett_x11_segment);
  1865. proto_tree_add_item(ttt, hf_x11_segment_x1, tvb, *offsetp, 2, byte_order);
  1866. *offsetp += 2;
  1867. proto_tree_add_item(ttt, hf_x11_segment_y1, tvb, *offsetp, 2, byte_order);
  1868. *offsetp += 2;
  1869. proto_tree_add_item(ttt, hf_x11_segment_x2, tvb, *offsetp, 2, byte_order);
  1870. *offsetp += 2;
  1871. proto_tree_add_item(ttt, hf_x11_segment_y2, tvb, *offsetp, 2, byte_order);
  1872. *offsetp += 2;
  1873. }
  1874. }
  1875. static void listOfString8(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1876. int hf_item, int length, guint byte_order)
  1877. {
  1878. char *s = NULL;
  1879. proto_item *ti;
  1880. proto_tree *tt;
  1881. int i;
  1882. /* Compute total length */
  1883. int scanning_offset = *offsetp; /* Scanning pointer */
  1884. for(i = length; i; i--) {
  1885. int l;
  1886. l = tvb_get_guint8(tvb, scanning_offset);
  1887. scanning_offset += 1 + l;
  1888. }
  1889. ti = proto_tree_add_item(t, hf, tvb, *offsetp, scanning_offset - *offsetp, byte_order);
  1890. tt = proto_item_add_subtree(ti, ett_x11_list_of_string8);
  1891. while(length--) {
  1892. guint l = VALUE8(tvb, *offsetp);
  1893. s = tvb_get_ephemeral_string(tvb, *offsetp + 1, l);
  1894. proto_tree_add_string_format(tt, hf_item, tvb, *offsetp, l + 1, s, "\"%s\"", s);
  1895. *offsetp += l + 1;
  1896. }
  1897. }
  1898. #define STRING16_MAX_DISPLAYED_LENGTH 150
  1899. static int stringIsActuallyAn8BitString(tvbuff_t *tvb, int offset, guint length)
  1900. {
  1901. if (length > STRING16_MAX_DISPLAYED_LENGTH) length = STRING16_MAX_DISPLAYED_LENGTH;
  1902. for(; length > 0; offset += 2, length--) {
  1903. if (tvb_get_guint8(tvb, offset))
  1904. return FALSE;
  1905. }
  1906. return TRUE;
  1907. }
  1908. /* length is the length of the _byte_zone_ (that is, twice the length of the string) */
  1909. static void string16_with_buffer_preallocated(tvbuff_t *tvb, proto_tree *t,
  1910. int hf, int hf_bytes,
  1911. int offset, guint length,
  1912. char **s, guint byte_order)
  1913. {
  1914. int truncated = FALSE;
  1915. guint l = length / 2;
  1916. if (stringIsActuallyAn8BitString(tvb, offset, l)) {
  1917. char *dp;
  1918. int soffset = offset;
  1919. if (l > STRING16_MAX_DISPLAYED_LENGTH) {
  1920. truncated = TRUE;
  1921. l = STRING16_MAX_DISPLAYED_LENGTH;
  1922. }
  1923. *s = (char *)ep_alloc(l + 3);
  1924. dp = *s;
  1925. *dp++ = '"';
  1926. if (truncated) l -= 3;
  1927. while(l--) {
  1928. soffset++;
  1929. *dp++ = tvb_get_guint8(tvb, soffset);
  1930. soffset++;
  1931. }
  1932. *dp++ = '"';
  1933. /* If truncated, add an ellipsis */
  1934. if (truncated) { *dp++ = '.'; *dp++ = '.'; *dp++ = '.'; }
  1935. *dp++ = '\0';
  1936. proto_tree_add_string_format(t, hf, tvb, offset, length,
  1937. (const gchar *)tvb_get_ptr(tvb, offset, length),
  1938. "%s: %s",
  1939. proto_registrar_get_nth(hf) -> name,
  1940. *s);
  1941. } else
  1942. proto_tree_add_item(t, hf_bytes, tvb, offset, length, byte_order);
  1943. }
  1944. static void listOfTextItem(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1945. int sizeIs16, int next_offset, guint byte_order)
  1946. {
  1947. char *s = NULL;
  1948. proto_item *ti;
  1949. proto_tree *tt;
  1950. guint32 fid;
  1951. /* Compute total length */
  1952. int scanning_offset = *offsetp; /* Scanning pointer */
  1953. int n = 0; /* Number of items */
  1954. while(scanning_offset < next_offset) {
  1955. int l; /* Length of an individual item */
  1956. l = tvb_get_guint8(tvb, scanning_offset);
  1957. scanning_offset++;
  1958. if (!l) break;
  1959. n++;
  1960. scanning_offset += l == 255 ? 4 : l + (sizeIs16 ? l : 0) + 1;
  1961. }
  1962. ti = proto_tree_add_item(t, hf, tvb, *offsetp, scanning_offset - *offsetp, byte_order);
  1963. tt = proto_item_add_subtree(ti, ett_x11_list_of_text_item);
  1964. while(n--) {
  1965. guint l = VALUE8(tvb, *offsetp);
  1966. if (l == 255) { /* Item is a font */
  1967. fid = tvb_get_ntohl(tvb, *offsetp + 1);
  1968. proto_tree_add_uint(tt, hf_x11_textitem_font, tvb, *offsetp, 5, fid);
  1969. *offsetp += 5;
  1970. } else { /* Item is a string */
  1971. proto_item *tti;
  1972. proto_tree *ttt;
  1973. gint8 delta = VALUE8(tvb, *offsetp + 1);
  1974. if (sizeIs16) l += l;
  1975. s = tvb_get_ephemeral_string(tvb, *offsetp + 2, l);
  1976. tti = proto_tree_add_none_format(tt, hf_x11_textitem_string, tvb, *offsetp, l + 2,
  1977. "textitem (string): delta = %d, \"%s\"",
  1978. delta, s);
  1979. ttt = proto_item_add_subtree(tti, ett_x11_text_item);
  1980. proto_tree_add_item(ttt, hf_x11_textitem_string_delta, tvb, *offsetp + 1, 1, byte_order);
  1981. if (sizeIs16)
  1982. string16_with_buffer_preallocated(tvb, ttt, hf_x11_textitem_string_string16,
  1983. hf_x11_textitem_string_string16_bytes,
  1984. *offsetp + 2, l,
  1985. &s, byte_order);
  1986. else
  1987. proto_tree_add_string_format(ttt, hf_x11_textitem_string_string8, tvb,
  1988. *offsetp + 2, l, s, "\"%s\"", s);
  1989. *offsetp += l + 2;
  1990. }
  1991. }
  1992. }
  1993. static guint32 field8(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  1994. guint byte_order)
  1995. {
  1996. guint32 v = VALUE8(tvb, *offsetp);
  1997. header_field_info *hfi = proto_registrar_get_nth(hf);
  1998. const gchar *enumValue = NULL;
  1999. if (hfi -> strings)
  2000. enumValue = try_val_to_str(v, cVALS(hfi -> strings));
  2001. if (enumValue)
  2002. proto_tree_add_uint_format(t, hf, tvb, *offsetp, 1, v,
  2003. hfi -> display == BASE_DEC ? "%s: %u (%s)" : "%s: 0x%02x (%s)",
  2004. hfi -> name, v, enumValue);
  2005. else
  2006. proto_tree_add_item(t, hf, tvb, *offsetp, 1, byte_order);
  2007. *offsetp += 1;
  2008. return v;
  2009. }
  2010. static guint32 field16(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  2011. guint byte_order)
  2012. {
  2013. guint32 v = VALUE16(tvb, *offsetp);
  2014. header_field_info *hfi = proto_registrar_get_nth(hf);
  2015. const gchar *enumValue = NULL;
  2016. if (hfi -> strings)
  2017. enumValue = try_val_to_str(v, cVALS(hfi -> strings));
  2018. if (enumValue)
  2019. proto_tree_add_uint_format(t, hf, tvb, *offsetp, 2, v,
  2020. hfi -> display == BASE_DEC ? "%s: %u (%s)" : "%s: 0x%02x (%s)",
  2021. hfi -> name, v, enumValue);
  2022. else
  2023. proto_tree_add_item(t, hf, tvb, *offsetp, 2, byte_order);
  2024. *offsetp += 2;
  2025. return v;
  2026. }
  2027. static guint32 field32(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  2028. guint byte_order)
  2029. {
  2030. guint32 v = VALUE32(tvb, *offsetp);
  2031. header_field_info *hfi = proto_registrar_get_nth(hf);
  2032. const gchar *enumValue = NULL;
  2033. const gchar *nameAsChar = hfi -> name;
  2034. if (hfi -> strings)
  2035. enumValue = try_val_to_str(v, cVALS(hfi -> strings));
  2036. if (enumValue)
  2037. proto_tree_add_uint_format(t, hf, tvb, *offsetp, 4, v,
  2038. hfi -> display == BASE_DEC ? "%s: %u (%s)" : "%s: 0x%08x (%s)",
  2039. nameAsChar, v, enumValue);
  2040. else
  2041. proto_tree_add_uint_format(t, hf, tvb, *offsetp, 4, v,
  2042. hfi -> display == BASE_DEC ? "%s: %u" : "%s: 0x%08x",
  2043. nameAsChar, v);
  2044. *offsetp += 4;
  2045. return v;
  2046. }
  2047. static void gcAttributes(tvbuff_t *tvb, int *offsetp, proto_tree *t,
  2048. guint byte_order)
  2049. {
  2050. BITMASK32(gc_value);
  2051. BITFIELD(ENUM8, gc_value_mask, function);
  2052. BITFIELD(CARD32, gc_value_mask, plane_mask);
  2053. BITFIELD(CARD32, gc_value_mask, foreground);
  2054. BITFIELD(CARD32, gc_value_mask, background);
  2055. BITFIELD(CARD16, gc_value_mask, line_width);
  2056. BITFIELD(ENUM8, gc_value_mask, line_style);
  2057. BITFIELD(ENUM8, gc_value_mask, cap_style);
  2058. BITFIELD(ENUM8, gc_value_mask, join_style);
  2059. BITFIELD(ENUM8, gc_value_mask, fill_style);
  2060. BITFIELD(ENUM8, gc_value_mask, fill_rule);
  2061. BITFIELD(PIXMAP, gc_value_mask, tile);
  2062. BITFIELD(PIXMAP, gc_value_mask, stipple);
  2063. BITFIELD(INT16, gc_value_mask, tile_stipple_x_origin);
  2064. BITFIELD(INT16, gc_value_mask, tile_stipple_y_origin);
  2065. BITFIELD(FONT, gc_value_mask, font);
  2066. BITFIELD(ENUM8, gc_value_mask, subwindow_mode);
  2067. BITFIELD(BOOL, gc_value_mask, graphics_exposures);
  2068. BITFIELD(INT16, gc_value_mask, clip_x_origin);
  2069. BITFIELD(INT16, gc_value_mask, clip_y_origin);
  2070. BITFIELD(PIXMAP, gc_value_mask, clip_mask);
  2071. BITFIELD(CARD16, gc_value_mask, dash_offset);
  2072. BITFIELD(CARD8, gc_value_mask, gc_dashes);
  2073. BITFIELD(ENUM8, gc_value_mask, arc_mode);
  2074. ENDBITMASK;
  2075. }
  2076. static void gcMask(tvbuff_t *tvb, int *offsetp, proto_tree *t,
  2077. guint byte_order)
  2078. {
  2079. BITMASK32(gc_value);
  2080. FLAG(gc_value, function);
  2081. FLAG(gc_value, plane_mask);
  2082. FLAG(gc_value, foreground);
  2083. FLAG(gc_value, background);
  2084. FLAG(gc_value, line_width);
  2085. FLAG(gc_value, line_style);
  2086. FLAG(gc_value, cap_style);
  2087. FLAG(gc_value, join_style);
  2088. FLAG(gc_value, fill_style);
  2089. FLAG(gc_value, fill_rule);
  2090. FLAG(gc_value, tile);
  2091. FLAG(gc_value, stipple);
  2092. FLAG(gc_value, tile_stipple_x_origin);
  2093. FLAG(gc_value, tile_stipple_y_origin);
  2094. FLAG(gc_value, font);
  2095. FLAG(gc_value, subwindow_mode);
  2096. FLAG(gc_value, graphics_exposures);
  2097. FLAG(gc_value, clip_x_origin);
  2098. FLAG(gc_value, clip_y_origin);
  2099. FLAG(gc_value, clip_mask);
  2100. FLAG(gc_value, dash_offset);
  2101. FLAG(gc_value, gc_dashes);
  2102. FLAG(gc_value, arc_mode);
  2103. ENDBITMASK;
  2104. }
  2105. static guint32 requestLength(tvbuff_t *tvb, int *offsetp, proto_tree *t,
  2106. guint byte_order)
  2107. {
  2108. guint32 res = VALUE16(tvb, *offsetp);
  2109. proto_tree_add_uint(t, hf_x11_request_length, tvb, *offsetp, 2, res);
  2110. *offsetp += 2;
  2111. return res * 4;
  2112. }
  2113. static void setOfEvent(tvbuff_t *tvb, int *offsetp, proto_tree *t,
  2114. guint byte_order)
  2115. {
  2116. BITMASK32(event);
  2117. FLAG(event, KeyPress);
  2118. FLAG(event, KeyRelease);
  2119. FLAG(event, ButtonPress);
  2120. FLAG(event, ButtonRelease);
  2121. FLAG(event, EnterWindow);
  2122. FLAG(event, LeaveWindow);
  2123. FLAG(event, PointerMotion);
  2124. FLAG(event, PointerMotionHint);
  2125. FLAG(event, Button1Motion);
  2126. FLAG(event, Button2Motion);
  2127. FLAG(event, Button3Motion);
  2128. FLAG(event, Button4Motion);
  2129. FLAG(event, Button5Motion);
  2130. FLAG(event, ButtonMotion);
  2131. FLAG(event, KeymapState);
  2132. FLAG(event, Exposure);
  2133. FLAG(event, VisibilityChange);
  2134. FLAG(event, StructureNotify);
  2135. FLAG(event, ResizeRedirect);
  2136. FLAG(event, SubstructureNotify);
  2137. FLAG(event, SubstructureRedirect);
  2138. FLAG(event, FocusChange);
  2139. FLAG(event, PropertyChange);
  2140. FLAG(event, ColormapChange);
  2141. FLAG(event, OwnerGrabButton);
  2142. FLAG_IF_NONZERO(event, erroneous_bits);
  2143. ENDBITMASK;
  2144. }
  2145. static void setOfDeviceEvent(tvbuff_t *tvb, int *offsetp, proto_tree *t,
  2146. guint byte_order)
  2147. {
  2148. BITMASK32(do_not_propagate);
  2149. FLAG(do_not_propagate, KeyPress);
  2150. FLAG(do_not_propagate, KeyRelease);
  2151. FLAG(do_not_propagate, ButtonPress);
  2152. FLAG(do_not_propagate, ButtonRelease);
  2153. FLAG(do_not_propagate, PointerMotion);
  2154. FLAG(do_not_propagate, Button1Motion);
  2155. FLAG(do_not_propagate, Button2Motion);
  2156. FLAG(do_not_propagate, Button3Motion);
  2157. FLAG(do_not_propagate, Button4Motion);
  2158. FLAG(do_not_propagate, Button5Motion);
  2159. FLAG(do_not_propagate, ButtonMotion);
  2160. FLAG_IF_NONZERO(do_not_propagate, erroneous_bits);
  2161. ENDBITMASK;
  2162. }
  2163. static void setOfKeyButMask(tvbuff_t *tvb, int *offsetp, proto_tree *t,
  2164. guint byte_order, gboolean butmask)
  2165. {
  2166. proto_item *ti;
  2167. guint32 bitmask_value;
  2168. int bitmask_offset;
  2169. int bitmask_size;
  2170. proto_tree *bitmask_tree;
  2171. bitmask_value = VALUE16(tvb, *offsetp);
  2172. bitmask_offset = *offsetp;
  2173. bitmask_size = 2;
  2174. if (!butmask && bitmask_value == 0x8000)
  2175. proto_tree_add_uint_format(t, hf_x11_modifiers_mask_AnyModifier, tvb, *offsetp, 2, 0x8000,
  2176. "modifiers-masks: 0x8000 (AnyModifier)");
  2177. else {
  2178. ti = proto_tree_add_uint(t, hf_x11_modifiers_mask, tvb, *offsetp, 2,
  2179. bitmask_value);
  2180. bitmask_tree = proto_item_add_subtree(ti, ett_x11_set_of_key_mask);
  2181. FLAG(modifiers, Shift);
  2182. FLAG(modifiers, Lock);
  2183. FLAG(modifiers, Control);
  2184. FLAG(modifiers, Mod1);
  2185. FLAG(modifiers, Mod2);
  2186. FLAG(modifiers, Mod3);
  2187. FLAG(modifiers, Mod4);
  2188. FLAG(modifiers, Mod5);
  2189. if (butmask) {
  2190. FLAG(modifiers, Button1);
  2191. FLAG(modifiers, Button2);
  2192. FLAG(modifiers, Button3);
  2193. FLAG(modifiers, Button4);
  2194. FLAG(modifiers, Button5);
  2195. }
  2196. if (butmask)
  2197. FLAG_IF_NONZERO(keybut, erroneous_bits);
  2198. else
  2199. FLAG_IF_NONZERO(modifiers, erroneous_bits);
  2200. }
  2201. *offsetp += 2;
  2202. }
  2203. static void setOfPointerEvent(tvbuff_t *tvb, int *offsetp, proto_tree *t,
  2204. guint byte_order)
  2205. {
  2206. BITMASK16(pointer_event);
  2207. FLAG(pointer_event, ButtonPress);
  2208. FLAG(pointer_event, ButtonRelease);
  2209. FLAG(pointer_event, EnterWindow);
  2210. FLAG(pointer_event, LeaveWindow);
  2211. FLAG(pointer_event, PointerMotion);
  2212. FLAG(pointer_event, PointerMotionHint);
  2213. FLAG(pointer_event, Button1Motion);
  2214. FLAG(pointer_event, Button2Motion);
  2215. FLAG(pointer_event, Button3Motion);
  2216. FLAG(pointer_event, Button4Motion);
  2217. FLAG(pointer_event, Button5Motion);
  2218. FLAG(pointer_event, ButtonMotion);
  2219. FLAG(pointer_event, KeymapState);
  2220. FLAG_IF_NONZERO(pointer_event, erroneous_bits);
  2221. ENDBITMASK;
  2222. }
  2223. static void string8(tvbuff_t *tvb, int *offsetp, proto_tree *t,
  2224. int hf, guint length)
  2225. {
  2226. proto_tree_add_item(t, hf, tvb, *offsetp, length, ENC_NA|ENC_ASCII);
  2227. *offsetp += length;
  2228. }
  2229. /* The length is the length of the _byte_zone_ (twice the length of the string) */
  2230. static void string16(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  2231. int hf_bytes, guint length, guint byte_order)
  2232. {
  2233. char *s = NULL;
  2234. length += length;
  2235. string16_with_buffer_preallocated(tvb, t, hf, hf_bytes, *offsetp, length,
  2236. &s, byte_order);
  2237. *offsetp += length;
  2238. }
  2239. static void timestamp(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
  2240. guint byte_order)
  2241. {
  2242. guint32 v = VALUE32(tvb, *offsetp);
  2243. if (!v)
  2244. proto_tree_add_uint_format(t, hf, tvb, *offsetp, 4, 0, "%s: 0 (CurrentTime)",
  2245. proto_registrar_get_nth(hf) -> name);
  2246. else
  2247. proto_tree_add_uint(t, hf, tvb, *offsetp, 4, v);
  2248. *offsetp += 4;
  2249. }
  2250. static void windowAttributes(tvbuff_t *tvb, int *offsetp, proto_tree *t,
  2251. guint byte_order)
  2252. {
  2253. BITMASK32(window_value);
  2254. BITFIELD(PIXMAP, window_value_mask, background_pixmap);
  2255. BITFIELD(CARD32, window_value_mask, background_pixel);
  2256. BITFIELD(PIXMAP, window_value_mask, border_pixmap);
  2257. BITFIELD(CARD32, window_value_mask, border_pixel);
  2258. BITFIELD(BITGRAVITY, window_value_mask, bit_gravity);
  2259. BITFIELD(WINGRAVITY, window_value_mask, win_gravity);
  2260. BITFIELD(ENUM8, window_value_mask, backing_store);
  2261. BITFIELD(CARD32, window_value_mask, backing_planes);
  2262. BITFIELD(CARD32, window_value_mask, backing_pixel);
  2263. BITFIELD(BOOL, window_value_mask, override_redirect);
  2264. BITFIELD(BOOL, window_value_mask, save_under);
  2265. BITFIELD(SETofEVENT, window_value_mask, event_mask);
  2266. BITFIELD(SETofDEVICEEVENT, window_value_mask, do_not_propagate_mask);
  2267. BITFIELD(COLORMAP, window_value_mask, colormap);
  2268. BITFIELD(CURSOR, window_value_mask, cursor);
  2269. ENDBITMASK;
  2270. }
  2271. static void x11_init_protocol(void)
  2272. {
  2273. x11_conv_data_t *state;
  2274. for (state = x11_conv_data_list; state != NULL; ) {
  2275. x11_conv_data_t *last;
  2276. g_hash_table_destroy(state->seqtable);
  2277. g_hash_table_destroy(state->valtable);
  2278. last = state;
  2279. state = state->next;
  2280. g_free(last);
  2281. }
  2282. x11_conv_data_list = NULL;
  2283. }
  2284. /************************************************************************
  2285. *** ***
  2286. *** G U E S S I N G T H E B Y T E O R D E R I N G ***
  2287. *** ***
  2288. ************************************************************************/
  2289. /* If we can't guess, we return ENC_LITTLE_ENDIAN, cause
  2290. I'm developing on a Linux box :-). The (non-)guess isn't cached
  2291. however, so we may have more luck next time. I'm quite conservative
  2292. in my assertions, cause once it's cached, it stays in cache, and
  2293. we may be fooled up by a packet starting with the end of a request
  2294. started in a previous packet...
  2295. */
  2296. static int numberOfBitSetTable[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
  2297. static int numberOfBitSet(tvbuff_t *tvb, int offset, int maskLength)
  2298. {
  2299. int res = 0;
  2300. while(maskLength--) {
  2301. int c = tvb_get_guint8(tvb, offset);
  2302. offset++;
  2303. res += numberOfBitSetTable[c & 0xf] + numberOfBitSetTable[c >> 4];
  2304. }
  2305. return res;
  2306. }
  2307. static int listOfStringLengthConsistent(tvbuff_t *tvb, int offset, int length, int listLength)
  2308. {
  2309. if (listLength > length) return FALSE;
  2310. while(listLength--) {
  2311. int l;
  2312. if (!tvb_bytes_exist(tvb, offset, 1)) return TRUE;
  2313. l = tvb_get_guint8(tvb, offset);
  2314. if (!l) break;
  2315. l++;
  2316. if (l > length) return FALSE;
  2317. if (!tvb_bytes_exist(tvb, offset, l)) return TRUE;
  2318. offset += l;
  2319. length -= l;
  2320. }
  2321. if (length > 3) return FALSE;
  2322. return TRUE;
  2323. }
  2324. static int rounded4(int n)
  2325. {
  2326. int remainder = n % 4;
  2327. int res = n / 4;
  2328. if (remainder) res++;
  2329. return res;
  2330. }
  2331. /* We assume the order to be consistent, until proven wrong. */
  2332. static gboolean consistentWithOrder(int length, tvbuff_t *tvb, int offset, guint16 (*v16)(tvbuff_t *, const gint))
  2333. {
  2334. switch(tvb_get_guint8(tvb, offset)) {
  2335. case X_CreateWindow:
  2336. return !tvb_bytes_exist(tvb, offset, 32) || length == 8 + numberOfBitSet(tvb, offset + 7 * 4, 4);
  2337. case X_ChangeWindowAttributes:
  2338. case X_ChangeGC:
  2339. return !tvb_bytes_exist(tvb, offset, 12) || length == 3 + numberOfBitSet(tvb, offset + 8, 4);
  2340. case X_GetWindowAttributes:
  2341. case X_DestroyWindow:
  2342. case X_DestroySubwindows:
  2343. case X_ChangeSaveSet:
  2344. case X_MapWindow:
  2345. case X_MapSubwindows:
  2346. case X_UnmapWindow:
  2347. case X_UnmapSubwindows:
  2348. case X_CirculateWindow:
  2349. case X_GetGeometry:
  2350. case X_QueryTree:
  2351. case X_GetAtomName:
  2352. case X_ListProperties:
  2353. case X_GetSelectionOwner:
  2354. case X_UngrabPointer:
  2355. case X_UngrabKeyboard:
  2356. case X_AllowEvents:
  2357. case X_QueryPointer:
  2358. case X_CloseFont:
  2359. case X_QueryFont:
  2360. case X_FreePixmap:
  2361. case X_FreeGC:
  2362. case X_FreeColormap:
  2363. case X_InstallColormap:
  2364. case X_UninstallColormap:
  2365. case X_ListInstalledColormaps:
  2366. case X_FreeCursor:
  2367. case X_GetKeyboardMapping:
  2368. case X_KillClient:
  2369. return length == 2;
  2370. case X_ReparentWindow:
  2371. case X_SetSelectionOwner:
  2372. case X_ChangeActivePointerGrab:
  2373. case X_GrabKeyboard:
  2374. case X_GrabKey:
  2375. case X_GetMotionEvents:
  2376. case X_TranslateCoords:
  2377. case X_CreatePixmap:
  2378. case X_CopyGC:
  2379. case X_ClearArea:
  2380. case X_CreateColormap:
  2381. case X_AllocColor:
  2382. case X_AllocColorPlanes:
  2383. return length == 4;
  2384. case X_ConfigureWindow:
  2385. return !tvb_bytes_exist(tvb, offset, 10) || length == 3 + numberOfBitSet(tvb, offset + 8, 2);
  2386. case X_InternAtom:
  2387. case X_QueryExtension:
  2388. return !tvb_bytes_exist(tvb, offset, 6) || length == 2 + rounded4(v16(tvb, offset + 4));
  2389. case X_ChangeProperty:
  2390. {
  2391. int multiplier, type;
  2392. if (!tvb_bytes_exist(tvb, offset, 17)) return TRUE;
  2393. type = tvb_get_guint8(tvb, 16);
  2394. if (type != 8 && type != 16 && type != 32) return FALSE;
  2395. multiplier = type == 8 ? 1 : type == 16 ? 2 : 4;
  2396. if (!tvb_bytes_exist(tvb, offset, 24)) return TRUE;
  2397. return length == 6 + rounded4((v16 == tvb_get_letohs ? tvb_get_letohl : tvb_get_ntohl)(tvb, offset + 20) * multiplier);
  2398. }
  2399. case X_DeleteProperty:
  2400. case X_UngrabButton:
  2401. case X_UngrabKey:
  2402. case X_SetInputFocus:
  2403. case X_CopyColormapAndFree:
  2404. case X_AllocColorCells:
  2405. case X_QueryBestSize:
  2406. case X_ChangePointerControl:
  2407. case X_SetScreenSaver:
  2408. return length == 3;
  2409. case X_GetProperty:
  2410. case X_ConvertSelection:
  2411. case X_GrabPointer:
  2412. case X_GrabButton:
  2413. case X_WarpPointer:
  2414. return length == 6;
  2415. case X_SendEvent:
  2416. return length == 11;
  2417. case X_GrabServer:
  2418. case X_UngrabServer:
  2419. case X_GetInputFocus:
  2420. case X_QueryKeymap:
  2421. case X_GetFontPath:
  2422. case X_ListExtensions:
  2423. case X_GetKeyboardControl:
  2424. case X_Bell:
  2425. case X_GetPointerControl:
  2426. case X_GetScreenSaver:
  2427. case X_ListHosts:
  2428. case X_SetAccessControl:
  2429. case X_SetCloseDownMode:
  2430. case X_ForceScreenSaver:
  2431. case X_GetPointerMapping:
  2432. case X_GetModifierMapping:
  2433. return length == 1;
  2434. case X_OpenFont:
  2435. case X_AllocNamedColor:
  2436. case X_LookupColor:
  2437. return !tvb_bytes_exist(tvb, offset, 10) || length == 3 + rounded4(v16(tvb, offset + 8));
  2438. case X_QueryTextExtents:
  2439. return length >= 2;
  2440. case X_ListFonts:
  2441. case X_ListFontsWithInfo:
  2442. case X_ChangeHosts:
  2443. return !tvb_bytes_exist(tvb, offset, 8) || length == 2 + rounded4(v16(tvb, offset + 6));
  2444. case X_SetFontPath:
  2445. if (length < 2) return FALSE;
  2446. if (!tvb_bytes_exist(tvb, offset, 8)) return TRUE;
  2447. return listOfStringLengthConsistent(tvb, offset + 8, (length - 2) * 4, v16(tvb, offset + 4));
  2448. case X_CreateGC:
  2449. return !tvb_bytes_exist(tvb, offset, 16) || length == 4 + numberOfBitSet(tvb, offset + 12, 4);
  2450. case X_SetDashes:
  2451. return !tvb_bytes_exist(tvb, offset, 12) || length == 3 + rounded4(v16(tvb, offset + 10));
  2452. case X_SetClipRectangles:
  2453. case X_PolySegment:
  2454. case X_PolyRectangle:
  2455. case X_PolyFillRectangle:
  2456. return length >= 3 && (length - 3) % 2 == 0;
  2457. case X_CopyArea:
  2458. return length == 7;
  2459. case X_CopyPlane:
  2460. case X_CreateCursor:
  2461. case X_CreateGlyphCursor:
  2462. return length == 8;
  2463. case X_PolyPoint:
  2464. case X_PolyLine:
  2465. case X_FreeColors:
  2466. return length >= 3;
  2467. case X_PolyArc:
  2468. case X_PolyFillArc:
  2469. return length >= 3 && (length - 3) % 3 == 0;
  2470. case X_FillPoly:
  2471. case X_ImageText8:
  2472. return length >= 4;
  2473. case X_PutImage:
  2474. return length >= 6;
  2475. case X_GetImage:
  2476. case X_RecolorCursor:
  2477. return length == 5;
  2478. case X_PolyText8:
  2479. if (length < 4) return FALSE;
  2480. return TRUE; /* We don't perform many controls on this one */
  2481. case X_PolyText16:
  2482. if (length < 4) return FALSE;
  2483. return TRUE; /* We don't perform many controls on this one */
  2484. case X_ImageText16:
  2485. return length >= 4;
  2486. case X_StoreColors:
  2487. return length > 2 && (length - 2) % 3 == 0;
  2488. case X_StoreNamedColor:
  2489. return !tvb_bytes_exist(tvb, offset, 14) || length == 4 + rounded4(v16(tvb, offset + 12));
  2490. case X_QueryColors:
  2491. return length >= 2;
  2492. case X_ChangeKeyboardMapping:
  2493. return !tvb_bytes_exist(tvb, offset, 6) || length == 2 + tvb_get_guint8(tvb, 1) * tvb_get_guint8(tvb, 5);
  2494. case X_ChangeKeyboardControl:
  2495. return !tvb_bytes_exist(tvb, offset, 6) || length == 2 + numberOfBitSet(tvb, offset + 4, 2);
  2496. case X_RotateProperties:
  2497. return !tvb_bytes_exist(tvb, offset, 10) || length == 3 + v16(tvb, offset + 8);
  2498. case X_SetPointerMapping:
  2499. return length == 1 + rounded4(tvb_get_guint8(tvb, 1));
  2500. case X_SetModifierMapping:
  2501. return length == 1 + tvb_get_guint8(tvb, 1) * 2;
  2502. case X_NoOperation:
  2503. return length >= 1;
  2504. default:
  2505. return TRUE;
  2506. }
  2507. }
  2508. /* -1 means doesn't match, +1 means match, 0 means don't know */
  2509. static int x_endian_match(tvbuff_t *tvb, guint16 (*v16)(tvbuff_t *, const gint))
  2510. {
  2511. int offset, nextoffset;
  2512. int atLeastOne = 0;
  2513. for(offset = 0; tvb_bytes_exist(tvb, offset, 4); offset = nextoffset) {
  2514. int length;
  2515. length = v16(tvb, offset + 2);
  2516. if (!length) return -1;
  2517. nextoffset = offset + length * 4;
  2518. if (!consistentWithOrder(length, tvb, offset, v16)) return -1;
  2519. atLeastOne = 1;
  2520. }
  2521. return atLeastOne;
  2522. }
  2523. static guint
  2524. guess_byte_ordering(tvbuff_t *tvb, packet_info *pinfo,
  2525. x11_conv_data_t *state)
  2526. {
  2527. /* With X the client gives the byte ordering for the protocol,
  2528. and the port on the server tells us we're speaking X. */
  2529. int le, be;
  2530. guint decision;
  2531. if (state->byte_order == BYTE_ORDER_BE)
  2532. return ENC_BIG_ENDIAN; /* known to be big-endian */
  2533. else if (state->byte_order == BYTE_ORDER_LE)
  2534. return ENC_LITTLE_ENDIAN; /* known to be little-endian */
  2535. if (pinfo->srcport == pinfo->match_uint) {
  2536. /*
  2537. * This is a reply or event; we don't try to guess the
  2538. * byte order on it for now.
  2539. */
  2540. return ENC_LITTLE_ENDIAN;
  2541. }
  2542. le = x_endian_match(tvb, tvb_get_letohs);
  2543. be = x_endian_match(tvb, tvb_get_ntohs);
  2544. if (le == be) {
  2545. /* We have no reason to believe it's little- rather than
  2546. big-endian, so we guess the shortest length is the
  2547. right one.
  2548. */
  2549. if (!tvb_bytes_exist(tvb, 0, 4))
  2550. /* Not even a way to get the length. We're biased
  2551. toward little endianness here (essentially the
  2552. x86 world right now). Decoding won't go very far
  2553. anyway.
  2554. */
  2555. decision = ENC_LITTLE_ENDIAN;
  2556. else {
  2557. if (tvb_get_letohs(tvb, 2) <= tvb_get_ntohs(tvb, 2))
  2558. decision = ENC_LITTLE_ENDIAN;
  2559. else
  2560. decision = ENC_BIG_ENDIAN;
  2561. }
  2562. } else {
  2563. if (le >= be)
  2564. decision = ENC_LITTLE_ENDIAN;
  2565. else
  2566. decision = ENC_BIG_ENDIAN;
  2567. }
  2568. if ((le < 0 && be > 0) || (le > 0 && be < 0)) {
  2569. /*
  2570. * Remember the decision.
  2571. */
  2572. state->byte_order = (decision == ENC_BIG_ENDIAN) ? BYTE_ORDER_BE : BYTE_ORDER_LE;
  2573. }
  2574. return decision;
  2575. }
  2576. /************************************************************************
  2577. *** ***
  2578. *** D E C O D I N G O N E P A C K E T ***
  2579. *** ***
  2580. ************************************************************************/
  2581. /*
  2582. * Decode an initial connection request.
  2583. */
  2584. static void dissect_x11_initial_conn(tvbuff_t *tvb, packet_info *pinfo,
  2585. proto_tree *tree, x11_conv_data_t *state, guint byte_order)
  2586. {
  2587. int offset = 0;
  2588. int *offsetp = &offset;
  2589. proto_item *ti;
  2590. proto_tree *t;
  2591. guint16 auth_proto_name_length, auth_proto_data_length;
  2592. gint left;
  2593. ti = proto_tree_add_item(tree, proto_x11, tvb, 0, -1, ENC_NA);
  2594. proto_item_append_text(ti, ", Request, Initial connection request");
  2595. t = proto_item_add_subtree(ti, ett_x11);
  2596. CARD8(byte_order);
  2597. UNUSED(1);
  2598. CARD16(protocol_major_version);
  2599. CARD16(protocol_minor_version);
  2600. auth_proto_name_length = CARD16(authorization_protocol_name_length);
  2601. auth_proto_data_length = CARD16(authorization_protocol_data_length);
  2602. UNUSED(2);
  2603. if (auth_proto_name_length != 0) {
  2604. STRING8(authorization_protocol_name, auth_proto_name_length);
  2605. offset = ROUND_LENGTH(offset);
  2606. }
  2607. if (auth_proto_data_length != 0) {
  2608. STRING8(authorization_protocol_data, auth_proto_data_length);
  2609. offset = ROUND_LENGTH(offset);
  2610. }
  2611. if ((left = tvb_reported_length_remaining(tvb, offset)) > 0)
  2612. proto_tree_add_item(t, hf_x11_undecoded, tvb, offset, left,
  2613. ENC_NA);
  2614. /*
  2615. * This is the initial connection request...
  2616. */
  2617. state->iconn_frame = pinfo->fd->num;
  2618. /*
  2619. * ...and we're expecting a reply to it.
  2620. */
  2621. state->sequencenumber = 0;
  2622. g_hash_table_insert(state->seqtable, GINT_TO_POINTER(state->sequencenumber),
  2623. (int *)INITIAL_CONN);
  2624. }
  2625. static void dissect_x11_initial_reply(tvbuff_t *tvb, packet_info *pinfo,
  2626. proto_tree *tree, const char _U_ *sep, x11_conv_data_t *volatile state,
  2627. guint byte_order)
  2628. {
  2629. int offset = 0, *offsetp = &offset, left;
  2630. unsigned char success;
  2631. int length_of_vendor;
  2632. int length_of_reason;
  2633. proto_item *ti;
  2634. proto_tree *t;
  2635. ti = proto_tree_add_item(tree, proto_x11, tvb, 0, -1, ENC_NA);
  2636. proto_item_append_text(ti, ", Reply, Initial connection reply");
  2637. t = proto_item_add_subtree(ti, ett_x11);
  2638. state->iconn_reply = pinfo->fd->num;
  2639. success = INT8(success);
  2640. if (success) {
  2641. UNUSED(1);
  2642. length_of_reason = 0;
  2643. }
  2644. else {
  2645. length_of_reason = INT8(length_of_reason);
  2646. }
  2647. INT16(protocol_major_version);
  2648. INT16(protocol_minor_version);
  2649. INT16(replylength);
  2650. if (success) {
  2651. INT32(release_number);
  2652. INT32(resource_id_base);
  2653. INT32(resource_id_mask);
  2654. INT32(motion_buffer_size);
  2655. length_of_vendor = INT16(length_of_vendor);
  2656. INT16(maximum_request_length);
  2657. INT8(number_of_screens_in_roots);
  2658. INT8(number_of_formats_in_pixmap_formats);
  2659. INT8(image_byte_order);
  2660. INT8(bitmap_format_bit_order);
  2661. INT8(bitmap_format_scanline_unit);
  2662. INT8(bitmap_format_scanline_pad);
  2663. INT8(min_keycode);
  2664. INT8(max_keycode);
  2665. UNUSED(4);
  2666. STRING8(vendor, length_of_vendor);
  2667. } else {
  2668. STRING8(reason, length_of_reason);
  2669. }
  2670. if ((left = tvb_reported_length_remaining(tvb, offset)) > 0)
  2671. UNDECODED(left);
  2672. }
  2673. typedef struct x11_reply_info {
  2674. const guint8 minor;
  2675. void (*dissect)(tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t, guint byte_order);
  2676. } x11_reply_info;
  2677. typedef struct event_info {
  2678. const gchar *name;
  2679. void (*dissect)(tvbuff_t *tvb, int *offsetp, proto_tree *t, guint byte_order);
  2680. } x11_event_info;
  2681. static void set_handler(const char *name, void (*func)(tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t, guint byte_order),
  2682. const char **errors,
  2683. const x11_event_info *event_info,
  2684. const x11_reply_info *reply_info)
  2685. {
  2686. g_hash_table_insert(extension_table, (gpointer)name, (gpointer)func);
  2687. g_hash_table_insert(error_table, (gpointer)name, (gpointer)errors);
  2688. g_hash_table_insert(event_table, (gpointer)name, (gpointer)event_info);
  2689. g_hash_table_insert(reply_table, (gpointer)name, (gpointer)reply_info);
  2690. }
  2691. static int popcount(unsigned int mask)
  2692. {
  2693. #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
  2694. /* GCC 3.4 or newer */
  2695. return __builtin_popcount(mask);
  2696. #else
  2697. /* HACKMEM 169 */
  2698. unsigned long y;
  2699. y = (mask >> 1) &033333333333;
  2700. y = mask - y - ((y >>1) & 033333333333);
  2701. return (((y + (y >> 3)) & 030707070707) % 077);
  2702. #endif
  2703. }
  2704. #include "x11-extension-errors.h"
  2705. #include "x11-extension-implementation.h"
  2706. static void tryExtension(int opcode, tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t,
  2707. x11_conv_data_t *state, guint byte_order)
  2708. {
  2709. const gchar *extension;
  2710. void (*func)(tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t, guint byte_order);
  2711. extension = try_val_to_str(opcode, state->opcode_vals);
  2712. if (!extension)
  2713. return;
  2714. func = (void (*)(tvbuff_t *, packet_info *, int *, proto_tree *, guint))g_hash_table_lookup(extension_table, extension);
  2715. if (func)
  2716. func(tvb, pinfo, offsetp, t, byte_order);
  2717. }
  2718. static void tryExtensionReply(int opcode, tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t,
  2719. x11_conv_data_t *state, guint byte_order)
  2720. {
  2721. void (*func)(tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t, guint byte_order);
  2722. func = (void (*)(tvbuff_t *, packet_info *, int *, proto_tree *, guint))g_hash_table_lookup(state->reply_funcs, GINT_TO_POINTER(opcode));
  2723. if (func)
  2724. func(tvb, pinfo, offsetp, t, byte_order);
  2725. else
  2726. REPLYCONTENTS_COMMON();
  2727. }
  2728. static void tryExtensionEvent(int event, tvbuff_t *tvb, int *offsetp, proto_tree *t,
  2729. x11_conv_data_t *state, guint byte_order)
  2730. {
  2731. void (*func)(tvbuff_t *tvb, int *offsetp, proto_tree *t, guint byte_order);
  2732. func = (void (*)(tvbuff_t *, int *, proto_tree *, guint))g_hash_table_lookup(state->eventcode_funcs, GINT_TO_POINTER(event));
  2733. if (func)
  2734. func(tvb, offsetp, t, byte_order);
  2735. }
  2736. static void register_extension(x11_conv_data_t *state, value_string *vals_p,
  2737. int major_opcode, unsigned int first_event, unsigned int first_error)
  2738. {
  2739. const char **error_string;
  2740. x11_event_info *event_info;
  2741. x11_reply_info *reply_info;
  2742. int i;
  2743. vals_p->value = major_opcode;
  2744. error_string = (const char **)g_hash_table_lookup(error_table, vals_p->strptr);
  2745. while (error_string && *error_string && first_error <= LastExtensionError) {
  2746. /* store string of extension error */
  2747. for (i = 0; i <= LastExtensionError; i++) {
  2748. if (state->errorcode_vals[i].strptr == NULL) {
  2749. state->errorcode_vals[i].value = first_error;
  2750. state->errorcode_vals[i].strptr = *error_string;
  2751. break;
  2752. } else if (state->errorcode_vals[i].value == first_error) {
  2753. /* TODO: Warn about extensions stepping on each other */
  2754. state->errorcode_vals[i].strptr = *error_string;
  2755. break;
  2756. }
  2757. }
  2758. first_error++;
  2759. error_string++;
  2760. }
  2761. event_info = (x11_event_info *)g_hash_table_lookup(event_table, vals_p->strptr);
  2762. while (event_info && event_info->name && first_event <= LastExtensionEvent) {
  2763. /* store string of extension event */
  2764. for (i = 0; i <= LastExtensionEvent; i++) {
  2765. if (state->eventcode_vals[i].strptr == NULL) {
  2766. state->eventcode_vals[i].value = first_event;
  2767. state->eventcode_vals[i].strptr = event_info->name;
  2768. break;
  2769. } else if (state->eventcode_vals[i].value == first_event) {
  2770. /* TODO: Warn about extensions stepping on each other */
  2771. state->eventcode_vals[i].strptr = event_info->name;
  2772. break;
  2773. }
  2774. }
  2775. /* store event decode function */
  2776. g_hash_table_insert(state->eventcode_funcs, GINT_TO_POINTER(first_event), (gpointer)event_info->dissect);
  2777. first_event++;
  2778. event_info++;
  2779. }
  2780. reply_info = (x11_reply_info *)g_hash_table_lookup(reply_table, vals_p->strptr);
  2781. if (reply_info)
  2782. for (i = 0; reply_info[i].dissect; i++)
  2783. g_hash_table_insert(state->reply_funcs,
  2784. GINT_TO_POINTER(major_opcode | (reply_info[i].minor << 8)),
  2785. (gpointer)reply_info[i].dissect);
  2786. }
  2787. static void dissect_x11_request(tvbuff_t *tvb, packet_info *pinfo,
  2788. proto_tree *tree, const char *sep, x11_conv_data_t *state,
  2789. guint byte_order)
  2790. {
  2791. int offset = 0;
  2792. int *offsetp = &offset;
  2793. int next_offset;
  2794. proto_item *ti;
  2795. proto_tree *t;
  2796. int length, opcode, i;
  2797. guint8 v8, v8_2, v8_3;
  2798. guint16 v16;
  2799. guint32 v32;
  2800. gint left;
  2801. gchar *name;
  2802. length = VALUE16(tvb, 2) * 4;
  2803. if (length < 4) {
  2804. /* Bogus message length? */
  2805. return;
  2806. }
  2807. next_offset = offset + length;
  2808. ti = proto_tree_add_item(tree, proto_x11, tvb, 0, -1, ENC_NA);
  2809. t = proto_item_add_subtree(ti, ett_x11);
  2810. if (PACKET_IS_NEW(pinfo))
  2811. ++state->sequencenumber;
  2812. OPCODE();
  2813. col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s", sep,
  2814. val_to_str(opcode, state->opcode_vals,
  2815. "<Unknown opcode %d>"));
  2816. proto_item_append_text(ti, ", Request, opcode: %d (%s)",
  2817. opcode, val_to_str(opcode, state->opcode_vals,
  2818. "<Unknown opcode %d>"));
  2819. /*
  2820. * Does this request expect a reply?
  2821. */
  2822. switch(opcode) {
  2823. case X_QueryExtension:
  2824. /* necessary processing even if tree == NULL */
  2825. v16 = VALUE16(tvb, 4);
  2826. name = tvb_get_seasonal_string(tvb, 8, v16);
  2827. /* store string of extension, opcode will be set at reply */
  2828. i = 0;
  2829. while(i < MAX_OPCODES) {
  2830. if (state->opcode_vals[i].strptr == NULL) {
  2831. state->opcode_vals[i].strptr = name;
  2832. state->opcode_vals[i].value = -1;
  2833. g_hash_table_insert(state->valtable,
  2834. GINT_TO_POINTER(state->sequencenumber),
  2835. (int *)&state->opcode_vals[i]);
  2836. break;
  2837. } else if (strcmp(state->opcode_vals[i].strptr,
  2838. name) == 0) {
  2839. g_hash_table_insert(state->valtable,
  2840. GINT_TO_POINTER(state->sequencenumber),
  2841. (int *)&state->opcode_vals[i]);
  2842. break;
  2843. }
  2844. i++;
  2845. }
  2846. /* QueryExtension expects a reply, fall through */
  2847. case X_AllocColor:
  2848. case X_AllocColorCells:
  2849. case X_AllocColorPlanes:
  2850. case X_AllocNamedColor:
  2851. case X_GetAtomName:
  2852. case X_GetFontPath:
  2853. case X_GetGeometry:
  2854. case X_GetImage:
  2855. case X_GetInputFocus:
  2856. case X_GetKeyboardControl:
  2857. case X_GetKeyboardMapping:
  2858. case X_GetModifierMapping:
  2859. case X_GetMotionEvents:
  2860. case X_GetPointerControl:
  2861. case X_GetPointerMapping:
  2862. case X_GetProperty:
  2863. case X_GetScreenSaver:
  2864. case X_GetSelectionOwner:
  2865. case X_GetWindowAttributes:
  2866. case X_GrabKeyboard:
  2867. case X_GrabPointer:
  2868. case X_InternAtom:
  2869. case X_ListExtensions:
  2870. case X_ListFonts:
  2871. case X_ListFontsWithInfo:
  2872. case X_ListHosts:
  2873. case X_ListInstalledColormaps:
  2874. case X_ListProperties:
  2875. case X_LookupColor:
  2876. case X_QueryBestSize:
  2877. case X_QueryColors:
  2878. case X_QueryFont:
  2879. case X_QueryKeymap:
  2880. case X_QueryPointer:
  2881. case X_QueryTextExtents:
  2882. case X_QueryTree:
  2883. case X_SetModifierMapping:
  2884. case X_SetPointerMapping:
  2885. case X_TranslateCoords:
  2886. /*
  2887. * Those requests expect a reply.
  2888. */
  2889. g_hash_table_insert(state->seqtable,
  2890. GINT_TO_POINTER(state->sequencenumber),
  2891. GINT_TO_POINTER(opcode));
  2892. break;
  2893. default:
  2894. /*
  2895. * With Extension, we don't know, so assume there could be one
  2896. */
  2897. if (opcode >= X_FirstExtension && opcode <= X_LastExtension) {
  2898. guint32 minor;
  2899. minor = tvb_get_guint8(tvb, 1);
  2900. g_hash_table_insert(state->seqtable,
  2901. GINT_TO_POINTER(state->sequencenumber),
  2902. GINT_TO_POINTER(opcode | (minor << 8)));
  2903. }
  2904. /*
  2905. * No reply is expected from any other request.
  2906. */
  2907. break;
  2908. }
  2909. if (tree == NULL)
  2910. return;
  2911. switch(opcode) {
  2912. case X_CreateWindow:
  2913. CARD8(depth);
  2914. REQUEST_LENGTH();
  2915. WINDOW(wid);
  2916. WINDOW(parent);
  2917. INT16(x);
  2918. INT16(y);
  2919. CARD16(width);
  2920. CARD16(height);
  2921. CARD16(border_width);
  2922. ENUM16(window_class);
  2923. VISUALID(visual);
  2924. windowAttributes(tvb, offsetp, t, byte_order);
  2925. break;
  2926. case X_ChangeWindowAttributes:
  2927. UNUSED(1);
  2928. REQUEST_LENGTH();
  2929. WINDOW(window);
  2930. windowAttributes(tvb, offsetp, t, byte_order);
  2931. break;
  2932. case X_GetWindowAttributes:
  2933. case X_DestroyWindow:
  2934. case X_DestroySubwindows:
  2935. UNUSED(1);
  2936. REQUEST_LENGTH();
  2937. WINDOW(window);
  2938. break;
  2939. case X_ChangeSaveSet:
  2940. ENUM8(save_set_mode);
  2941. REQUEST_LENGTH();
  2942. WINDOW(window);
  2943. break;
  2944. case X_ReparentWindow:
  2945. UNUSED(1);
  2946. REQUEST_LENGTH();
  2947. WINDOW(window);
  2948. WINDOW(parent);
  2949. INT16(x);
  2950. INT16(y);
  2951. break;
  2952. case X_MapWindow:
  2953. case X_MapSubwindows:
  2954. case X_UnmapWindow:
  2955. case X_UnmapSubwindows:
  2956. UNUSED(1);
  2957. REQUEST_LENGTH();
  2958. WINDOW(window);
  2959. break;
  2960. case X_ConfigureWindow:
  2961. UNUSED(1);
  2962. REQUEST_LENGTH();
  2963. WINDOW(window);
  2964. BITMASK16(configure_window);
  2965. UNUSED(2);
  2966. BITFIELD(INT16, configure_window_mask, x);
  2967. BITFIELD(INT16, configure_window_mask, y);
  2968. BITFIELD(CARD16, configure_window_mask, width);
  2969. BITFIELD(CARD16, configure_window_mask, height);
  2970. BITFIELD(CARD16, configure_window_mask, border_width);
  2971. BITFIELD(WINDOW, configure_window_mask, sibling);
  2972. BITFIELD(ENUM8, configure_window_mask, stack_mode);
  2973. ENDBITMASK;
  2974. PAD();
  2975. break;
  2976. case X_CirculateWindow:
  2977. ENUM8(direction);
  2978. REQUEST_LENGTH();
  2979. WINDOW(window);
  2980. break;
  2981. case X_GetGeometry:
  2982. case X_QueryTree:
  2983. UNUSED(1);
  2984. REQUEST_LENGTH();
  2985. DRAWABLE(drawable);
  2986. break;
  2987. case X_InternAtom:
  2988. BOOL(only_if_exists);
  2989. REQUEST_LENGTH();
  2990. v16 = FIELD16(name_length);
  2991. UNUSED(2);
  2992. STRING8(name, v16);
  2993. PAD();
  2994. break;
  2995. case X_GetAtomName:
  2996. UNUSED(1);
  2997. REQUEST_LENGTH();
  2998. ATOM(atom);
  2999. break;
  3000. case X_ChangeProperty:
  3001. ENUM8(mode);
  3002. REQUEST_LENGTH();
  3003. WINDOW(window);
  3004. ATOM(property);
  3005. ATOM(type);
  3006. v8 = CARD8(format);
  3007. UNUSED(3);
  3008. v32 = CARD32(data_length);
  3009. switch (v8) {
  3010. case 8:
  3011. if (v32)
  3012. LISTofBYTE(data, v32);
  3013. break;
  3014. case 16:
  3015. if (v32)
  3016. LISTofCARD16(data16, v32 * 2);
  3017. break;
  3018. case 32:
  3019. if (v32)
  3020. LISTofCARD32(data32, v32 * 4);
  3021. break;
  3022. default:
  3023. expert_add_info(pinfo, ti, &ei_x11_invalid_format);
  3024. break;
  3025. }
  3026. PAD();
  3027. break;
  3028. case X_DeleteProperty:
  3029. UNUSED(1);
  3030. REQUEST_LENGTH();
  3031. WINDOW(window);
  3032. ATOM(property);
  3033. break;
  3034. case X_GetProperty:
  3035. BOOL(delete);
  3036. REQUEST_LENGTH();
  3037. WINDOW(window);
  3038. ATOM(property);
  3039. ATOM(get_property_type);
  3040. CARD32(long_offset);
  3041. CARD32(long_length);
  3042. break;
  3043. case X_ListProperties:
  3044. UNUSED(1);
  3045. REQUEST_LENGTH();
  3046. WINDOW(window);
  3047. break;
  3048. case X_SetSelectionOwner:
  3049. UNUSED(1);
  3050. REQUEST_LENGTH();
  3051. WINDOW(owner);
  3052. ATOM(selection);
  3053. TIMESTAMP(time);
  3054. break;
  3055. case X_GetSelectionOwner:
  3056. UNUSED(1);
  3057. REQUEST_LENGTH();
  3058. ATOM(selection);
  3059. break;
  3060. case X_ConvertSelection:
  3061. UNUSED(1);
  3062. REQUEST_LENGTH();
  3063. WINDOW(requestor);
  3064. ATOM(selection);
  3065. ATOM(target);
  3066. ATOM(property);
  3067. TIMESTAMP(time);
  3068. break;
  3069. case X_SendEvent:
  3070. BOOL(propagate);
  3071. REQUEST_LENGTH();
  3072. WINDOW(destination);
  3073. SETofEVENT(event_mask);
  3074. EVENT();
  3075. break;
  3076. case X_GrabPointer:
  3077. BOOL(owner_events);
  3078. REQUEST_LENGTH();
  3079. WINDOW(grab_window);
  3080. SETofPOINTEREVENT(pointer_event_mask);
  3081. ENUM8(pointer_mode);
  3082. ENUM8(keyboard_mode);
  3083. WINDOW(confine_to);
  3084. CURSOR(cursor);
  3085. TIMESTAMP(time);
  3086. break;
  3087. case X_UngrabPointer:
  3088. UNUSED(1);
  3089. REQUEST_LENGTH();
  3090. TIMESTAMP(time);
  3091. break;
  3092. case X_GrabButton:
  3093. BOOL(owner_events);
  3094. REQUEST_LENGTH();
  3095. WINDOW(grab_window);
  3096. SETofPOINTEREVENT(event_mask);
  3097. ENUM8(pointer_mode);
  3098. ENUM8(keyboard_mode);
  3099. WINDOW(confine_to);
  3100. CURSOR(cursor);
  3101. BUTTON(button);
  3102. UNUSED(1);
  3103. SETofKEYMASK(modifiers);
  3104. break;
  3105. case X_UngrabButton:
  3106. BUTTON(button);
  3107. REQUEST_LENGTH();
  3108. WINDOW(grab_window);
  3109. SETofKEYMASK(modifiers);
  3110. UNUSED(2);
  3111. break;
  3112. case X_ChangeActivePointerGrab:
  3113. UNUSED(1);
  3114. REQUEST_LENGTH();
  3115. CURSOR(cursor);
  3116. TIMESTAMP(time);
  3117. SETofPOINTEREVENT(event_mask);
  3118. UNUSED(2);
  3119. break;
  3120. case X_GrabKeyboard:
  3121. BOOL(owner_events);
  3122. REQUEST_LENGTH();
  3123. WINDOW(grab_window);
  3124. TIMESTAMP(time);
  3125. ENUM8(pointer_mode);
  3126. ENUM8(keyboard_mode);
  3127. UNUSED(2);
  3128. break;
  3129. case X_UngrabKeyboard:
  3130. UNUSED(1);
  3131. REQUEST_LENGTH();
  3132. TIMESTAMP(time);
  3133. break;
  3134. case X_GrabKey:
  3135. BOOL(owner_events);
  3136. REQUEST_LENGTH();
  3137. WINDOW(grab_window);
  3138. SETofKEYMASK(modifiers);
  3139. KEYCODE(key);
  3140. ENUM8(pointer_mode);
  3141. ENUM8(keyboard_mode);
  3142. UNUSED(3);
  3143. break;
  3144. case X_UngrabKey:
  3145. KEYCODE(key);
  3146. REQUEST_LENGTH();
  3147. WINDOW(grab_window);
  3148. SETofKEYMASK(modifiers);
  3149. UNUSED(2);
  3150. break;
  3151. case X_AllowEvents:
  3152. ENUM8(allow_events_mode);
  3153. REQUEST_LENGTH();
  3154. TIMESTAMP(time);
  3155. break;
  3156. case X_GrabServer:
  3157. UNUSED(1);
  3158. REQUEST_LENGTH();
  3159. break;
  3160. case X_UngrabServer:
  3161. UNUSED(1);
  3162. REQUEST_LENGTH();
  3163. break;
  3164. case X_QueryPointer:
  3165. UNUSED(1);
  3166. REQUEST_LENGTH();
  3167. WINDOW(window);
  3168. break;
  3169. case X_GetMotionEvents:
  3170. UNUSED(1);
  3171. REQUEST_LENGTH();
  3172. WINDOW(window);
  3173. TIMESTAMP(start);
  3174. TIMESTAMP(stop);
  3175. break;
  3176. case X_TranslateCoords:
  3177. UNUSED(1);
  3178. REQUEST_LENGTH();
  3179. WINDOW(src_window);
  3180. WINDOW(dst_window);
  3181. INT16(src_x);
  3182. INT16(src_y);
  3183. break;
  3184. case X_WarpPointer:
  3185. UNUSED(1);
  3186. REQUEST_LENGTH();
  3187. WINDOW(warp_pointer_src_window);
  3188. WINDOW(warp_pointer_dst_window);
  3189. INT16(src_x);
  3190. INT16(src_y);
  3191. CARD16(src_width);
  3192. CARD16(src_height);
  3193. INT16(dst_x);
  3194. INT16(dst_y);
  3195. break;
  3196. case X_SetInputFocus:
  3197. ENUM8(revert_to);
  3198. REQUEST_LENGTH();
  3199. WINDOW(focus);
  3200. TIMESTAMP(time);
  3201. break;
  3202. case X_GetInputFocus:
  3203. UNUSED(1);
  3204. REQUEST_LENGTH();
  3205. break;
  3206. case X_QueryKeymap:
  3207. UNUSED(1);
  3208. REQUEST_LENGTH();
  3209. break;
  3210. case X_OpenFont:
  3211. UNUSED(1);
  3212. REQUEST_LENGTH();
  3213. FONT(fid);
  3214. v16 = FIELD16(name_length);
  3215. UNUSED(2);
  3216. STRING8(name, v16);
  3217. PAD();
  3218. break;
  3219. case X_CloseFont:
  3220. UNUSED(1);
  3221. REQUEST_LENGTH();
  3222. FONT(font);
  3223. break;
  3224. case X_QueryFont:
  3225. UNUSED(1);
  3226. REQUEST_LENGTH();
  3227. FONTABLE(font);
  3228. break;
  3229. case X_QueryTextExtents:
  3230. v8 = BOOL(odd_length);
  3231. REQUEST_LENGTH();
  3232. FONTABLE(font);
  3233. STRING16(string16, (next_offset - offset - (v8 ? 2 : 0)) / 2);
  3234. PAD();
  3235. break;
  3236. case X_ListFonts:
  3237. UNUSED(1);
  3238. REQUEST_LENGTH();
  3239. CARD16(max_names);
  3240. v16 = FIELD16(pattern_length);
  3241. STRING8(pattern, v16);
  3242. PAD();
  3243. break;
  3244. case X_ListFontsWithInfo:
  3245. UNUSED(1);
  3246. REQUEST_LENGTH();
  3247. CARD16(max_names);
  3248. v16 = FIELD16(pattern_length);
  3249. STRING8(pattern, v16);
  3250. PAD();
  3251. break;
  3252. case X_SetFontPath:
  3253. UNUSED(1);
  3254. REQUEST_LENGTH();
  3255. v16 = CARD16(str_number_in_path);
  3256. UNUSED(2);
  3257. LISTofSTRING8(path, v16);
  3258. PAD();
  3259. break;
  3260. case X_GetFontPath:
  3261. UNUSED(1);
  3262. REQUEST_LENGTH();
  3263. break;
  3264. case X_CreatePixmap:
  3265. CARD8(depth);
  3266. REQUEST_LENGTH();
  3267. PIXMAP(pid);
  3268. DRAWABLE(drawable);
  3269. CARD16(width);
  3270. CARD16(height);
  3271. break;
  3272. case X_FreePixmap:
  3273. UNUSED(1);
  3274. REQUEST_LENGTH();
  3275. PIXMAP(pixmap);
  3276. break;
  3277. case X_CreateGC:
  3278. UNUSED(1);
  3279. REQUEST_LENGTH();
  3280. GCONTEXT(cid);
  3281. DRAWABLE(drawable);
  3282. gcAttributes(tvb, offsetp, t, byte_order);
  3283. break;
  3284. case X_ChangeGC:
  3285. UNUSED(1);
  3286. REQUEST_LENGTH();
  3287. GCONTEXT(gc);
  3288. gcAttributes(tvb, offsetp, t, byte_order);
  3289. break;
  3290. case X_CopyGC:
  3291. UNUSED(1);
  3292. REQUEST_LENGTH();
  3293. GCONTEXT(src_gc);
  3294. GCONTEXT(dst_gc);
  3295. gcMask(tvb, offsetp, t, byte_order);
  3296. break;
  3297. case X_SetDashes:
  3298. UNUSED(1);
  3299. REQUEST_LENGTH();
  3300. GCONTEXT(gc);
  3301. CARD16(dash_offset);
  3302. v16 = FIELD16(dashes_length);
  3303. LISTofCARD8(dashes, v16);
  3304. PAD();
  3305. break;
  3306. case X_SetClipRectangles:
  3307. ENUM8(ordering);
  3308. REQUEST_LENGTH();
  3309. GCONTEXT(gc);
  3310. INT16(clip_x_origin);
  3311. INT16(clip_y_origin);
  3312. LISTofRECTANGLE(rectangles);
  3313. break;
  3314. case X_FreeGC:
  3315. UNUSED(1);
  3316. REQUEST_LENGTH();
  3317. GCONTEXT(gc);
  3318. break;
  3319. case X_ClearArea:
  3320. BOOL(exposures);
  3321. REQUEST_LENGTH();
  3322. WINDOW(window);
  3323. INT16(x);
  3324. INT16(y);
  3325. CARD16(width);
  3326. CARD16(height);
  3327. break;
  3328. case X_CopyArea:
  3329. UNUSED(1);
  3330. REQUEST_LENGTH();
  3331. DRAWABLE(src_drawable);
  3332. DRAWABLE(dst_drawable);
  3333. GCONTEXT(gc);
  3334. INT16(src_x);
  3335. INT16(src_y);
  3336. INT16(dst_x);
  3337. INT16(dst_y);
  3338. CARD16(width);
  3339. CARD16(height);
  3340. break;
  3341. case X_CopyPlane:
  3342. UNUSED(1);
  3343. REQUEST_LENGTH();
  3344. DRAWABLE(src_drawable);
  3345. DRAWABLE(dst_drawable);
  3346. GCONTEXT(gc);
  3347. INT16(src_x);
  3348. INT16(src_y);
  3349. INT16(dst_x);
  3350. INT16(dst_y);
  3351. CARD16(width);
  3352. CARD16(height);
  3353. CARD32(bit_plane);
  3354. break;
  3355. case X_PolyPoint:
  3356. ENUM8(coordinate_mode);
  3357. v16 = REQUEST_LENGTH();
  3358. DRAWABLE(drawable);
  3359. GCONTEXT(gc);
  3360. LISTofPOINT(points, v16 - 12);
  3361. break;
  3362. case X_PolyLine:
  3363. ENUM8(coordinate_mode);
  3364. v16 = REQUEST_LENGTH();
  3365. DRAWABLE(drawable);
  3366. GCONTEXT(gc);
  3367. LISTofPOINT(points, v16 - 12);
  3368. break;
  3369. case X_PolySegment:
  3370. UNUSED(1);
  3371. REQUEST_LENGTH();
  3372. DRAWABLE(drawable);
  3373. GCONTEXT(gc);
  3374. LISTofSEGMENT(segments);
  3375. break;
  3376. case X_PolyRectangle:
  3377. UNUSED(1);
  3378. REQUEST_LENGTH();
  3379. DRAWABLE(drawable);
  3380. GCONTEXT(gc);
  3381. LISTofRECTANGLE(rectangles);
  3382. break;
  3383. case X_PolyArc:
  3384. UNUSED(1);
  3385. REQUEST_LENGTH();
  3386. DRAWABLE(drawable);
  3387. GCONTEXT(gc);
  3388. LISTofARC(arcs);
  3389. break;
  3390. case X_FillPoly:
  3391. UNUSED(1);
  3392. v16 = REQUEST_LENGTH();
  3393. DRAWABLE(drawable);
  3394. GCONTEXT(gc);
  3395. ENUM8(shape);
  3396. ENUM8(coordinate_mode);
  3397. UNUSED(2);
  3398. LISTofPOINT(points, v16 - 16);
  3399. break;
  3400. case X_PolyFillRectangle:
  3401. UNUSED(1);
  3402. REQUEST_LENGTH();
  3403. DRAWABLE(drawable);
  3404. GCONTEXT(gc);
  3405. LISTofRECTANGLE(rectangles);
  3406. break;
  3407. case X_PolyFillArc:
  3408. UNUSED(1);
  3409. REQUEST_LENGTH();
  3410. DRAWABLE(drawable);
  3411. GCONTEXT(gc);
  3412. LISTofARC(arcs);
  3413. break;
  3414. case X_PutImage:
  3415. ENUM8(image_format);
  3416. v16 = REQUEST_LENGTH();
  3417. DRAWABLE(drawable);
  3418. GCONTEXT(gc);
  3419. CARD16(width);
  3420. CARD16(height);
  3421. INT16(dst_x);
  3422. INT16(dst_y);
  3423. CARD8(left_pad);
  3424. CARD8(depth);
  3425. UNUSED(2);
  3426. LISTofBYTE(data, v16 - 24);
  3427. PAD();
  3428. break;
  3429. case X_GetImage:
  3430. ENUM8(image_pixmap_format);
  3431. REQUEST_LENGTH();
  3432. DRAWABLE(drawable);
  3433. INT16(x);
  3434. INT16(y);
  3435. CARD16(width);
  3436. CARD16(height);
  3437. CARD32(plane_mask);
  3438. break;
  3439. case X_PolyText8:
  3440. UNUSED(1);
  3441. REQUEST_LENGTH();
  3442. DRAWABLE(drawable);
  3443. GCONTEXT(gc);
  3444. INT16(x);
  3445. INT16(y);
  3446. LISTofTEXTITEM8(items);
  3447. PAD();
  3448. break;
  3449. case X_PolyText16:
  3450. UNUSED(1);
  3451. REQUEST_LENGTH();
  3452. DRAWABLE(drawable);
  3453. GCONTEXT(gc);
  3454. INT16(x);
  3455. INT16(y);
  3456. LISTofTEXTITEM16(items);
  3457. PAD();
  3458. break;
  3459. case X_ImageText8:
  3460. v8 = FIELD8(string_length);
  3461. REQUEST_LENGTH();
  3462. DRAWABLE(drawable);
  3463. GCONTEXT(gc);
  3464. INT16(x);
  3465. INT16(y);
  3466. STRING8(string, v8);
  3467. PAD();
  3468. break;
  3469. case X_ImageText16:
  3470. v8 = FIELD8(string_length);
  3471. REQUEST_LENGTH();
  3472. DRAWABLE(drawable);
  3473. GCONTEXT(gc);
  3474. INT16(x);
  3475. INT16(y);
  3476. STRING16(string16, v8);
  3477. PAD();
  3478. break;
  3479. case X_CreateColormap:
  3480. ENUM8(alloc);
  3481. REQUEST_LENGTH();
  3482. COLORMAP(mid);
  3483. WINDOW(window);
  3484. VISUALID(visual);
  3485. break;
  3486. case X_FreeColormap:
  3487. UNUSED(1);
  3488. REQUEST_LENGTH();
  3489. COLORMAP(cmap);
  3490. break;
  3491. case X_CopyColormapAndFree:
  3492. UNUSED(1);
  3493. REQUEST_LENGTH();
  3494. COLORMAP(mid);
  3495. COLORMAP(src_cmap);
  3496. break;
  3497. case X_InstallColormap:
  3498. UNUSED(1);
  3499. REQUEST_LENGTH();
  3500. COLORMAP(cmap);
  3501. break;
  3502. case X_UninstallColormap:
  3503. UNUSED(1);
  3504. REQUEST_LENGTH();
  3505. COLORMAP(cmap);
  3506. break;
  3507. case X_ListInstalledColormaps:
  3508. UNUSED(1);
  3509. REQUEST_LENGTH();
  3510. WINDOW(window);
  3511. break;
  3512. case X_AllocColor:
  3513. UNUSED(1);
  3514. REQUEST_LENGTH();
  3515. COLORMAP(cmap);
  3516. CARD16(red);
  3517. CARD16(green);
  3518. CARD16(blue);
  3519. UNUSED(2);
  3520. break;
  3521. case X_AllocNamedColor:
  3522. UNUSED(1);
  3523. REQUEST_LENGTH();
  3524. COLORMAP(cmap);
  3525. v16 = FIELD16(name_length);
  3526. UNUSED(2);
  3527. STRING8(name, v16);
  3528. PAD();
  3529. break;
  3530. case X_AllocColorCells:
  3531. BOOL(contiguous);
  3532. REQUEST_LENGTH();
  3533. COLORMAP(cmap);
  3534. CARD16(colors);
  3535. CARD16(planes);
  3536. break;
  3537. case X_AllocColorPlanes:
  3538. BOOL(contiguous);
  3539. REQUEST_LENGTH();
  3540. COLORMAP(cmap);
  3541. CARD16(colors);
  3542. CARD16(reds);
  3543. CARD16(greens);
  3544. CARD16(blues);
  3545. break;
  3546. case X_FreeColors:
  3547. UNUSED(1);
  3548. v16 = REQUEST_LENGTH();
  3549. COLORMAP(cmap);
  3550. CARD32(plane_mask);
  3551. LISTofCARD32(pixels, v16 - 12);
  3552. break;
  3553. case X_StoreColors:
  3554. UNUSED(1);
  3555. v16 = REQUEST_LENGTH();
  3556. COLORMAP(cmap);
  3557. LISTofCOLORITEM(color_items, v16 - 8);
  3558. break;
  3559. case X_StoreNamedColor:
  3560. COLOR_FLAGS(color);
  3561. REQUEST_LENGTH();
  3562. COLORMAP(cmap);
  3563. CARD32(pixel);
  3564. v16 = FIELD16(name_length);
  3565. UNUSED(2);
  3566. STRING8(name, v16);
  3567. PAD();
  3568. break;
  3569. case X_QueryColors:
  3570. UNUSED(1);
  3571. v16 = REQUEST_LENGTH();
  3572. COLORMAP(cmap);
  3573. LISTofCARD32(pixels, v16 - 8);
  3574. break;
  3575. case X_LookupColor:
  3576. UNUSED(1);
  3577. REQUEST_LENGTH();
  3578. COLORMAP(cmap);
  3579. v16 = FIELD16(name_length);
  3580. UNUSED(2);
  3581. STRING8(name, v16);
  3582. PAD();
  3583. break;
  3584. case X_CreateCursor:
  3585. UNUSED(1);
  3586. REQUEST_LENGTH();
  3587. CURSOR(cid);
  3588. PIXMAP(source_pixmap);
  3589. PIXMAP(mask);
  3590. CARD16(fore_red);
  3591. CARD16(fore_green);
  3592. CARD16(fore_blue);
  3593. CARD16(back_red);
  3594. CARD16(back_green);
  3595. CARD16(back_blue);
  3596. CARD16(x);
  3597. CARD16(y);
  3598. break;
  3599. case X_CreateGlyphCursor:
  3600. UNUSED(1);
  3601. REQUEST_LENGTH();
  3602. CURSOR(cid);
  3603. FONT(source_font);
  3604. FONT(mask_font);
  3605. CARD16(source_char);
  3606. CARD16(mask_char);
  3607. CARD16(fore_red);
  3608. CARD16(fore_green);
  3609. CARD16(fore_blue);
  3610. CARD16(back_red);
  3611. CARD16(back_green);
  3612. CARD16(back_blue);
  3613. break;
  3614. case X_FreeCursor:
  3615. UNUSED(1);
  3616. REQUEST_LENGTH();
  3617. CURSOR(cursor);
  3618. break;
  3619. case X_RecolorCursor:
  3620. UNUSED(1);
  3621. REQUEST_LENGTH();
  3622. CURSOR(cursor);
  3623. CARD16(fore_red);
  3624. CARD16(fore_green);
  3625. CARD16(fore_blue);
  3626. CARD16(back_red);
  3627. CARD16(back_green);
  3628. CARD16(back_blue);
  3629. break;
  3630. case X_QueryBestSize:
  3631. ENUM8(class);
  3632. REQUEST_LENGTH();
  3633. DRAWABLE(drawable);
  3634. CARD16(width);
  3635. CARD16(height);
  3636. break;
  3637. case X_QueryExtension:
  3638. UNUSED(1);
  3639. REQUEST_LENGTH();
  3640. v16 = FIELD16(name_length);
  3641. UNUSED(2);
  3642. STRING8(name, v16);
  3643. PAD();
  3644. break;
  3645. case X_ListExtensions:
  3646. UNUSED(1);
  3647. REQUEST_LENGTH();
  3648. break;
  3649. case X_ChangeKeyboardMapping:
  3650. v8 = FIELD8(keycode_count);
  3651. REQUEST_LENGTH();
  3652. v8_2 = KEYCODE(first_keycode);
  3653. v8_3 = FIELD8(keysyms_per_keycode);
  3654. UNUSED(2);
  3655. LISTofKEYSYM(keysyms, state->keycodemap, v8_2, v8, v8_3);
  3656. break;
  3657. case X_GetKeyboardMapping:
  3658. UNUSED(1);
  3659. REQUEST_LENGTH();
  3660. state->request.GetKeyboardMapping.first_keycode
  3661. = KEYCODE(first_keycode);
  3662. FIELD8(count);
  3663. UNUSED(2);
  3664. break;
  3665. case X_ChangeKeyboardControl:
  3666. UNUSED(1);
  3667. REQUEST_LENGTH();
  3668. BITMASK32(keyboard_value);
  3669. BITFIELD(INT8, keyboard_value_mask, key_click_percent);
  3670. BITFIELD(INT8, keyboard_value_mask, bell_percent);
  3671. BITFIELD(INT16, keyboard_value_mask, bell_pitch);
  3672. BITFIELD(INT16, keyboard_value_mask, bell_duration);
  3673. BITFIELD(INT16, keyboard_value_mask, led);
  3674. BITFIELD(ENUM8, keyboard_value_mask, led_mode);
  3675. BITFIELD(KEYCODE, keyboard_value_mask, keyboard_key);
  3676. BITFIELD(ENUM8, keyboard_value_mask, auto_repeat_mode);
  3677. ENDBITMASK;
  3678. break;
  3679. case X_GetKeyboardControl:
  3680. UNUSED(1);
  3681. REQUEST_LENGTH();
  3682. break;
  3683. case X_Bell:
  3684. INT8(percent);
  3685. REQUEST_LENGTH();
  3686. break;
  3687. case X_ChangePointerControl:
  3688. UNUSED(1);
  3689. REQUEST_LENGTH();
  3690. INT16(acceleration_numerator);
  3691. INT16(acceleration_denominator);
  3692. INT16(threshold);
  3693. BOOL(do_acceleration);
  3694. BOOL(do_threshold);
  3695. break;
  3696. case X_GetPointerControl:
  3697. UNUSED(1);
  3698. REQUEST_LENGTH();
  3699. break;
  3700. case X_SetScreenSaver:
  3701. UNUSED(1);
  3702. REQUEST_LENGTH();
  3703. INT16(timeout);
  3704. INT16(interval);
  3705. ENUM8(prefer_blanking);
  3706. ENUM8(allow_exposures);
  3707. UNUSED(2);
  3708. break;
  3709. case X_GetScreenSaver:
  3710. UNUSED(1);
  3711. REQUEST_LENGTH();
  3712. break;
  3713. case X_ChangeHosts:
  3714. ENUM8(change_host_mode);
  3715. REQUEST_LENGTH();
  3716. v8 = ENUM8(family);
  3717. UNUSED(1);
  3718. v16 = CARD16(address_length);
  3719. if (v8 == FAMILY_INTERNET && v16 == 4) {
  3720. /*
  3721. * IPv4 addresses.
  3722. * XXX - what about IPv6? Is that a family of
  3723. * FAMILY_INTERNET (0) with a length of 16?
  3724. */
  3725. LISTofIPADDRESS(ip_address, v16);
  3726. } else
  3727. LISTofCARD8(address, v16);
  3728. break;
  3729. case X_ListHosts:
  3730. UNUSED(1);
  3731. REQUEST_LENGTH();
  3732. break;
  3733. case X_SetAccessControl:
  3734. ENUM8(access_mode);
  3735. REQUEST_LENGTH();
  3736. break;
  3737. case X_SetCloseDownMode:
  3738. ENUM8(close_down_mode);
  3739. REQUEST_LENGTH();
  3740. break;
  3741. case X_KillClient:
  3742. UNUSED(1);
  3743. REQUEST_LENGTH();
  3744. CARD32(resource);
  3745. break;
  3746. case X_RotateProperties:
  3747. UNUSED(1);
  3748. v16 = REQUEST_LENGTH();
  3749. WINDOW(window);
  3750. CARD16(property_number);
  3751. INT16(delta);
  3752. LISTofATOM(properties, (v16 - 12));
  3753. break;
  3754. case X_ForceScreenSaver:
  3755. ENUM8(screen_saver_mode);
  3756. REQUEST_LENGTH();
  3757. break;
  3758. case X_SetPointerMapping:
  3759. v8 = FIELD8(map_length);
  3760. REQUEST_LENGTH();
  3761. LISTofCARD8(map, v8);
  3762. PAD();
  3763. break;
  3764. case X_GetPointerMapping:
  3765. UNUSED(1);
  3766. REQUEST_LENGTH();
  3767. break;
  3768. case X_SetModifierMapping:
  3769. v8 = FIELD8(keycodes_per_modifier);
  3770. REQUEST_LENGTH();
  3771. LISTofKEYCODE(state->modifiermap, keycodes, v8);
  3772. break;
  3773. case X_GetModifierMapping:
  3774. UNUSED(1);
  3775. REQUEST_LENGTH();
  3776. break;
  3777. case X_NoOperation:
  3778. UNUSED(1);
  3779. REQUEST_LENGTH();
  3780. break;
  3781. default:
  3782. tryExtension(opcode, tvb, pinfo, offsetp, t, state, byte_order);
  3783. break;
  3784. }
  3785. if ((left = tvb_reported_length_remaining(tvb, offset)) > 0)
  3786. UNDECODED(left);
  3787. }
  3788. static void dissect_x11_requests(tvbuff_t *tvb, packet_info *pinfo,
  3789. proto_tree *tree)
  3790. {
  3791. volatile int offset = 0;
  3792. int length_remaining;
  3793. volatile guint byte_order;
  3794. guint8 opcode;
  3795. volatile int plen;
  3796. proto_item *ti;
  3797. proto_tree *t;
  3798. volatile gboolean is_initial_creq;
  3799. guint16 auth_proto_len, auth_data_len;
  3800. const char *volatile sep = NULL;
  3801. conversation_t *conversation;
  3802. x11_conv_data_t *volatile state;
  3803. int length;
  3804. tvbuff_t *volatile next_tvb;
  3805. while (tvb_reported_length_remaining(tvb, offset) != 0) {
  3806. /*
  3807. * We use "tvb_ensure_length_remaining()" to make sure there
  3808. * actually *is* data remaining.
  3809. *
  3810. * This means we're guaranteed that "length_remaining" is
  3811. * positive.
  3812. */
  3813. length_remaining = tvb_ensure_length_remaining(tvb, offset);
  3814. /*
  3815. * Can we do reassembly?
  3816. */
  3817. if (x11_desegment && pinfo->can_desegment) {
  3818. /*
  3819. * Yes - is the X11 request header split across
  3820. * segment boundaries?
  3821. */
  3822. if (length_remaining < 4) {
  3823. /*
  3824. * Yes. Tell the TCP dissector where the data
  3825. * for this message starts in the data it handed
  3826. * us and that we need "some more data." Don't tell
  3827. * it exactly how many bytes we need because if/when
  3828. * we ask for even more (after the header) that will
  3829. * break reassembly.
  3830. */
  3831. pinfo->desegment_offset = offset;
  3832. pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
  3833. return;
  3834. }
  3835. }
  3836. /*
  3837. * Get the state for this conversation; create the conversation
  3838. * if we don't have one, and create the state if we don't have
  3839. * any.
  3840. */
  3841. conversation = find_or_create_conversation(pinfo);
  3842. /*
  3843. * Is there state attached to this conversation?
  3844. */
  3845. if ((state = (x11_conv_data_t *)conversation_get_proto_data(conversation, proto_x11))
  3846. == NULL)
  3847. state = x11_stateinit(conversation);
  3848. /*
  3849. * Guess the byte order if we don't already know it.
  3850. */
  3851. byte_order = guess_byte_ordering(tvb, pinfo, state);
  3852. /*
  3853. * Get the opcode and length of the putative X11 request.
  3854. */
  3855. opcode = VALUE8(tvb, 0);
  3856. plen = VALUE16(tvb, offset + 2);
  3857. if (plen == 0) {
  3858. /*
  3859. * This can't be 0, as it includes the header length.
  3860. * A different choice of byte order wouldn't have
  3861. * helped.
  3862. * Give up.
  3863. */
  3864. ti = proto_tree_add_item(tree, proto_x11, tvb, offset, -1,
  3865. ENC_NA);
  3866. t = proto_item_add_subtree(ti, ett_x11);
  3867. proto_tree_add_text(t, tvb, offset, -1,
  3868. "Bogus request length (0)");
  3869. return;
  3870. }
  3871. if (state->iconn_frame == pinfo->fd->num ||
  3872. (g_hash_table_lookup(state->seqtable,
  3873. GINT_TO_POINTER(state->sequencenumber)) == (int *)NOTHING_SEEN &&
  3874. (opcode == 'B' || opcode == 'l') &&
  3875. (plen == 11 || plen == 2816))) {
  3876. /*
  3877. * Either
  3878. *
  3879. * we saw this on the first pass and this is
  3880. * it again
  3881. *
  3882. * or
  3883. * we haven't already seen any requests, the first
  3884. * byte of the message is 'B' or 'l', and the 16-bit
  3885. * integer 2 bytes into the data stream is either 11
  3886. * or a byte-swapped 11.
  3887. *
  3888. * This means it's probably an initial connection
  3889. * request, not a message.
  3890. *
  3891. * 'B' is decimal 66, which is the opcode for a
  3892. * PolySegment request; unfortunately, 11 is a valid
  3893. * length for a PolySegment request request, so we
  3894. * might mis-identify that request. (Are there any
  3895. * other checks we can do?)
  3896. *
  3897. * 'l' is decimal 108, which is the opcode for a
  3898. * GetScreenSaver request; the only valid length
  3899. * for that request is 1.
  3900. */
  3901. is_initial_creq = TRUE;
  3902. /*
  3903. * We now know the byte order. Override the guess.
  3904. */
  3905. if (state->byte_order == BYTE_ORDER_UNKNOWN) {
  3906. if (opcode == 'B') {
  3907. /*
  3908. * Big-endian.
  3909. */
  3910. state->byte_order = BYTE_ORDER_BE;
  3911. byte_order = ENC_BIG_ENDIAN;
  3912. } else {
  3913. /*
  3914. * Little-endian.
  3915. */
  3916. state->byte_order = BYTE_ORDER_LE;
  3917. byte_order = ENC_LITTLE_ENDIAN;
  3918. }
  3919. }
  3920. /*
  3921. * Can we do reassembly?
  3922. */
  3923. if (x11_desegment && pinfo->can_desegment) {
  3924. /*
  3925. * Yes - is the fixed-length portion of the
  3926. * initial connection header split across
  3927. * segment boundaries?
  3928. */
  3929. if (length_remaining < 10) {
  3930. /*
  3931. * Yes. Tell the TCP dissector where the
  3932. * data for this message starts in the data
  3933. * it handed us and that we need "some more
  3934. * data." Don't tell it exactly how many bytes
  3935. * we need because if/when we ask for even more
  3936. * (after the header) that will break reassembly.
  3937. */
  3938. pinfo->desegment_offset = offset;
  3939. pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
  3940. return;
  3941. }
  3942. }
  3943. /*
  3944. * Get the lengths of the authorization protocol and
  3945. * the authorization data.
  3946. */
  3947. auth_proto_len = VALUE16(tvb, offset + 6);
  3948. auth_data_len = VALUE16(tvb, offset + 8);
  3949. plen = 12 + ROUND_LENGTH(auth_proto_len) +
  3950. ROUND_LENGTH(auth_data_len);
  3951. } else {
  3952. /*
  3953. * This is probably an ordinary request.
  3954. */
  3955. is_initial_creq = FALSE;
  3956. /*
  3957. * The length of a request is in 4-byte words.
  3958. */
  3959. plen *= 4;
  3960. }
  3961. /*
  3962. * Can we do reassembly?
  3963. */
  3964. if (x11_desegment && pinfo->can_desegment) {
  3965. /*
  3966. * Yes - is the X11 request split across segment
  3967. * boundaries?
  3968. */
  3969. if (length_remaining < plen) {
  3970. /*
  3971. * Yes. Tell the TCP dissector where the data
  3972. * for this message starts in the data it handed
  3973. * us, and how many more bytes we need, and return.
  3974. */
  3975. pinfo->desegment_offset = offset;
  3976. pinfo->desegment_len = plen - length_remaining;
  3977. return;
  3978. }
  3979. }
  3980. /*
  3981. * Construct a tvbuff containing the amount of the payload
  3982. * we have available. Make its reported length the
  3983. * amount of data in the X11 request.
  3984. *
  3985. * XXX - if reassembly isn't enabled. the subdissector
  3986. * will throw a BoundsError exception, rather than a
  3987. * ReportedBoundsError exception. We really want a tvbuff
  3988. * where the length is "length", the reported length is "plen",
  3989. * and the "if the snapshot length were infinite" length is the
  3990. * minimum of the reported length of the tvbuff handed to us
  3991. * and "plen", with a new type of exception thrown if the offset
  3992. * is within the reported length but beyond that third length,
  3993. * with that exception getting the "Unreassembled Packet" error.
  3994. */
  3995. length = length_remaining;
  3996. if (length > plen)
  3997. length = plen;
  3998. next_tvb = tvb_new_subset(tvb, offset, length, plen);
  3999. /*
  4000. * Set the column appropriately.
  4001. */
  4002. if (is_initial_creq) {
  4003. col_set_str(pinfo->cinfo, COL_INFO, "Initial connection request");
  4004. } else {
  4005. if (sep == NULL) {
  4006. /*
  4007. * We haven't set the column yet; set it.
  4008. */
  4009. col_set_str(pinfo->cinfo, COL_INFO, "Requests");
  4010. /*
  4011. * Initialize the separator.
  4012. */
  4013. sep = ":";
  4014. }
  4015. }
  4016. /*
  4017. * Dissect the X11 request.
  4018. *
  4019. * Catch the ReportedBoundsError exception; if this
  4020. * particular message happens to get a ReportedBoundsError
  4021. * exception, that doesn't mean that we should stop
  4022. * dissecting X11 requests within this frame or chunk of
  4023. * reassembled data.
  4024. *
  4025. * If it gets a BoundsError, we can stop, as there's nothing
  4026. * more to see, so we just re-throw it.
  4027. */
  4028. TRY {
  4029. if (is_initial_creq) {
  4030. dissect_x11_initial_conn(next_tvb, pinfo, tree,
  4031. state, byte_order);
  4032. } else {
  4033. dissect_x11_request(next_tvb, pinfo, tree, sep,
  4034. state, byte_order);
  4035. }
  4036. }
  4037. CATCH_NONFATAL_ERRORS {
  4038. show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
  4039. }
  4040. ENDTRY;
  4041. /*
  4042. * Skip the X11 message.
  4043. */
  4044. offset += plen;
  4045. sep = ",";
  4046. }
  4047. }
  4048. static x11_conv_data_t *
  4049. x11_stateinit(conversation_t *conversation)
  4050. {
  4051. x11_conv_data_t *state;
  4052. static x11_conv_data_t stateinit;
  4053. int i;
  4054. state = (x11_conv_data_t *)g_malloc(sizeof (x11_conv_data_t));
  4055. *state = stateinit;
  4056. state->next = x11_conv_data_list;
  4057. x11_conv_data_list = state;
  4058. /* initialise opcodes */
  4059. for (i = 0; opcode_vals[i].strptr != NULL; i++) {
  4060. state->opcode_vals[i].value = opcode_vals[i].value;
  4061. state->opcode_vals[i].strptr = opcode_vals[i].strptr;
  4062. }
  4063. for (; i <= MAX_OPCODES; i++) {
  4064. state->opcode_vals[i].value = 0;
  4065. state->opcode_vals[i].strptr = NULL;
  4066. }
  4067. /* initialise errorcodes */
  4068. for (i = 0; errorcode_vals[i].strptr != NULL; i++) {
  4069. state->errorcode_vals[i].value = errorcode_vals[i].value;
  4070. state->errorcode_vals[i].strptr = errorcode_vals[i].strptr;
  4071. }
  4072. for (; i <= LastExtensionError + 1; i++) {
  4073. state->errorcode_vals[i].value = 0;
  4074. state->errorcode_vals[i].strptr = NULL;
  4075. }
  4076. /* initialise eventcodes */
  4077. for (i = 0; eventcode_vals[i].strptr != NULL; i++) {
  4078. state->eventcode_vals[i].value = eventcode_vals[i].value;
  4079. state->eventcode_vals[i].strptr = eventcode_vals[i].strptr;
  4080. }
  4081. for (; i <= LastExtensionEvent + 1; i++) {
  4082. state->eventcode_vals[i].value = 0;
  4083. state->eventcode_vals[i].strptr = NULL;
  4084. }
  4085. state->eventcode_funcs = g_hash_table_new(g_direct_hash, g_direct_equal);
  4086. state->reply_funcs = g_hash_table_new(g_direct_hash, g_direct_equal);
  4087. state->seqtable = g_hash_table_new(g_direct_hash, g_direct_equal);
  4088. state->valtable = g_hash_table_new(g_direct_hash, g_direct_equal);
  4089. g_hash_table_insert(state->seqtable, (int *)0, (int *)NOTHING_SEEN);
  4090. state->byte_order = BYTE_ORDER_UNKNOWN; /* don't know yet*/
  4091. conversation_add_proto_data(conversation, proto_x11, state);
  4092. return state;
  4093. }
  4094. static void
  4095. dissect_x11_replies(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
  4096. {
  4097. /* Set up structures we will need to add the protocol subtree and manage it */
  4098. volatile int offset, plen;
  4099. tvbuff_t * volatile next_tvb;
  4100. conversation_t *conversation;
  4101. x11_conv_data_t *volatile state;
  4102. volatile guint byte_order;
  4103. int length_remaining;
  4104. const char *volatile sep = NULL;
  4105. /*
  4106. * Get the state for this conversation; create the conversation
  4107. * if we don't have one, and create the state if we don't have
  4108. * any.
  4109. */
  4110. conversation = find_or_create_conversation(pinfo);
  4111. /*
  4112. * Is there state attached to this conversation?
  4113. */
  4114. if ((state = (x11_conv_data_t *)conversation_get_proto_data(conversation, proto_x11))
  4115. == NULL) {
  4116. /*
  4117. * No - create a state structure and attach it.
  4118. */
  4119. state = x11_stateinit(conversation);
  4120. }
  4121. /*
  4122. * Guess the byte order if we don't already know it.
  4123. */
  4124. byte_order = guess_byte_ordering(tvb, pinfo, state);
  4125. offset = 0;
  4126. while (tvb_reported_length_remaining(tvb, offset) != 0) {
  4127. /*
  4128. * We use "tvb_ensure_length_remaining()" to make sure there
  4129. * actually *is* data remaining.
  4130. *
  4131. * This means we're guaranteed that "length_remaining" is
  4132. * positive.
  4133. */
  4134. length_remaining = tvb_ensure_length_remaining(tvb, offset);
  4135. /*
  4136. * Can we do reassembly?
  4137. */
  4138. if (x11_desegment && pinfo->can_desegment) {
  4139. /*
  4140. * Yes - is the X11 reply header split across
  4141. * segment boundaries?
  4142. */
  4143. if (length_remaining < 8) {
  4144. /*
  4145. * Yes. Tell the TCP dissector where the data
  4146. * for this message starts in the data it handed
  4147. * us and that we need "some more data." Don't tell
  4148. * it exactly how many bytes we need because if/when
  4149. * we ask for even more (after the header) that will
  4150. * break reassembly.
  4151. */
  4152. pinfo->desegment_offset = offset;
  4153. pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
  4154. return;
  4155. }
  4156. }
  4157. /*
  4158. * Find out what kind of a reply it is.
  4159. * There are four possible:
  4160. * - reply to initial connection
  4161. * - errorreply (a request generated an error)
  4162. * - requestreply (reply to a request)
  4163. * - event (some event occurred)
  4164. */
  4165. if (g_hash_table_lookup(state->seqtable,
  4166. GINT_TO_POINTER(state->sequencenumber)) == (int *)INITIAL_CONN
  4167. || (state->iconn_reply == pinfo->fd->num)) {
  4168. /*
  4169. * Either the connection is in the "initial
  4170. * connection" state, or this frame is known
  4171. * to have the initial connection reply.
  4172. * That means this is the initial connection
  4173. * reply.
  4174. */
  4175. plen = 8 + VALUE16(tvb, offset + 6) * 4;
  4176. HANDLE_REPLY(plen, length_remaining,
  4177. "Initial connection reply",
  4178. dissect_x11_initial_reply);
  4179. } else {
  4180. /*
  4181. * This isn't an initial connection reply
  4182. * (XXX - unless we missed the initial
  4183. * connection request). Look at the first
  4184. * byte to determine what it is; errors
  4185. * start with a byte of 0, replies start
  4186. * with a byte of 1, events start with
  4187. * a byte with of 2 or greater.
  4188. */
  4189. switch (tvb_get_guint8(tvb, offset)) {
  4190. case 0:
  4191. plen = 32;
  4192. HANDLE_REPLY(plen, length_remaining,
  4193. "Error", dissect_x11_error);
  4194. break;
  4195. case 1:
  4196. {
  4197. /* To avoid an "assert w/side-effect" warning,
  4198. * use a non-volatile temp variable instead. */
  4199. int tmp_plen;
  4200. /* replylength is in units of four. */
  4201. tmp_plen = plen = 32 + VALUE32(tvb, offset + 4) * 4;
  4202. /* If tmp_plen < 32, we got an overflow;
  4203. * the reply length is too long. */
  4204. THROW_ON(tmp_plen < 32, ReportedBoundsError);
  4205. HANDLE_REPLY(plen, length_remaining,
  4206. "Reply", dissect_x11_reply);
  4207. break;
  4208. }
  4209. default:
  4210. /* Event */
  4211. plen = 32;
  4212. HANDLE_REPLY(plen, length_remaining,
  4213. "Event", dissect_x11_event);
  4214. break;
  4215. }
  4216. }
  4217. offset += plen;
  4218. }
  4219. return;
  4220. }
  4221. static void
  4222. dissect_x11_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
  4223. const char *volatile sep, x11_conv_data_t *volatile state,
  4224. guint byte_order)
  4225. {
  4226. int offset = 0, *offsetp = &offset, length, left, opcode;
  4227. int major_opcode, sequence_number, first_error, first_event;
  4228. value_string *vals_p;
  4229. proto_item *ti;
  4230. proto_tree *t;
  4231. ti = proto_tree_add_item(tree, proto_x11, tvb, 0, -1, ENC_NA);
  4232. t = proto_item_add_subtree(ti, ett_x11);
  4233. /*
  4234. * XXX - this doesn't work correctly if either
  4235. *
  4236. * 1) the request sequence number wraps in the lower 16
  4237. * bits;
  4238. *
  4239. * 2) we don't see the initial connection request and the
  4240. * resynchronization of sequence number fails and thus
  4241. * don't have the right sequence numbers
  4242. *
  4243. * 3) we don't have all the packets in the capture and
  4244. * get out of sequence.
  4245. *
  4246. * We might, instead, want to assume that a reply is a reply to
  4247. * the most recent not-already-replied-to request in the same
  4248. * connection. That also might mismatch replies to requests if
  4249. * packets are lost, but there's nothing you can do to fix that.
  4250. */
  4251. sequence_number = VALUE16(tvb, offset + 2);
  4252. opcode = GPOINTER_TO_INT(g_hash_table_lookup(state->seqtable,
  4253. GINT_TO_POINTER(sequence_number)));
  4254. if (state->iconn_frame == 0 && state->resync == FALSE) {
  4255. /*
  4256. * We don't see the initial connection request and no
  4257. * resynchronization has been performed yet (first reply),
  4258. * set the current sequence number to the one of the
  4259. * current reply (this is only performed once).
  4260. */
  4261. state->sequencenumber = sequence_number;
  4262. state->resync = TRUE;
  4263. }
  4264. if (opcode == UNKNOWN_OPCODE) {
  4265. col_append_fstr(pinfo->cinfo, COL_INFO,
  4266. "%s to unknown request", sep);
  4267. proto_item_append_text(ti, ", Reply to unknown request");
  4268. } else {
  4269. col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
  4270. sep,
  4271. val_to_str(opcode & 0xFF, state->opcode_vals,
  4272. "<Unknown opcode %d>"));
  4273. if (opcode > 0xFF)
  4274. proto_item_append_text(ti, ", Reply, opcode: %d.%d (%s)",
  4275. opcode & 0xFF, opcode >> 8, val_to_str(opcode & 0xFF,
  4276. state->opcode_vals,
  4277. "<Unknown opcode %d>"));
  4278. else
  4279. proto_item_append_text(ti, ", Reply, opcode: %d (%s)",
  4280. opcode, val_to_str(opcode,
  4281. state->opcode_vals,
  4282. "<Unknown opcode %d>"));
  4283. }
  4284. switch (opcode) {
  4285. /*
  4286. * Replies that need special processing outside tree
  4287. */
  4288. case X_QueryExtension:
  4289. /*
  4290. * if extension is present and request is known:
  4291. * store opcode of extension in value_string of
  4292. * opcodes
  4293. */
  4294. if (!VALUE8(tvb, offset + 8)) {
  4295. /* not present */
  4296. break;
  4297. }
  4298. vals_p = (value_string *)g_hash_table_lookup(state->valtable,
  4299. GINT_TO_POINTER(sequence_number));
  4300. if (vals_p != NULL) {
  4301. major_opcode = VALUE8(tvb, offset + 9);
  4302. first_event = VALUE8(tvb, offset + 10);
  4303. first_error = VALUE8(tvb, offset + 11);
  4304. register_extension(state, vals_p, major_opcode, first_event, first_error);
  4305. g_hash_table_remove(state->valtable,
  4306. GINT_TO_POINTER(sequence_number));
  4307. }
  4308. break;
  4309. default:
  4310. break;
  4311. }
  4312. if (tree == NULL)
  4313. return;
  4314. switch (opcode) {
  4315. /*
  4316. * Requests that expect a reply.
  4317. */
  4318. case X_GetWindowAttributes:
  4319. REPLYCONTENTS_COMMON();
  4320. break;
  4321. case X_GetGeometry:
  4322. REPLY(reply);
  4323. CARD8(depth);
  4324. SEQUENCENUMBER_REPLY(sequencenumber);
  4325. REPLYLENGTH(replylength);
  4326. WINDOW(rootwindow);
  4327. INT16(x);
  4328. INT16(y);
  4329. CARD16(width);
  4330. CARD16(height);
  4331. CARD16(border_width);
  4332. UNUSED(10);
  4333. break;
  4334. case X_QueryTree:
  4335. REPLYCONTENTS_COMMON();
  4336. break;
  4337. case X_InternAtom:
  4338. REPLY(reply);
  4339. UNUSED(1);
  4340. SEQUENCENUMBER_REPLY(sequencenumber);
  4341. REPLYLENGTH(replylength);
  4342. ATOM(atom);
  4343. UNUSED(20);
  4344. break;
  4345. case X_GetAtomName:
  4346. REPLYCONTENTS_COMMON();
  4347. break;
  4348. case X_GetProperty:
  4349. REPLY(reply);
  4350. CARD8(format);
  4351. SEQUENCENUMBER_REPLY(sequencenumber);
  4352. REPLYLENGTH(replylength);
  4353. ATOM(get_property_type);
  4354. CARD32(bytes_after);
  4355. CARD32(valuelength);
  4356. UNUSED(12);
  4357. break;
  4358. case X_ListProperties:
  4359. REPLY(reply);
  4360. UNUSED(1);
  4361. SEQUENCENUMBER_REPLY(sequencenumber);
  4362. REPLYLENGTH(replylength);
  4363. length = CARD16(property_number);
  4364. UNUSED(22);
  4365. LISTofATOM(properties, length*4);
  4366. break;
  4367. case X_GetSelectionOwner:
  4368. REPLY(reply);
  4369. UNUSED(1);
  4370. SEQUENCENUMBER_REPLY(sequencenumber);
  4371. REPLYLENGTH(replylength);
  4372. WINDOW(owner);
  4373. UNUSED(20);
  4374. break;
  4375. case X_GrabPointer:
  4376. case X_GrabKeyboard:
  4377. REPLY(reply);
  4378. ENUM8(grab_status);
  4379. SEQUENCENUMBER_REPLY(sequencenumber);
  4380. REPLYLENGTH(replylength);
  4381. UNUSED(24);
  4382. break;
  4383. case X_QueryPointer:
  4384. REPLY(reply);
  4385. BOOL(same_screen);
  4386. SEQUENCENUMBER_REPLY(sequencenumber);
  4387. REPLYLENGTH(replylength);
  4388. WINDOW(rootwindow);
  4389. WINDOW(childwindow);
  4390. INT16(root_x);
  4391. INT16(root_y);
  4392. INT16(win_x);
  4393. INT16(win_y);
  4394. SETofKEYBUTMASK(mask);
  4395. UNUSED(6);
  4396. break;
  4397. case X_GetMotionEvents:
  4398. REPLYCONTENTS_COMMON();
  4399. break;
  4400. case X_TranslateCoords:
  4401. REPLY(reply);
  4402. BOOL(same_screen);
  4403. SEQUENCENUMBER_REPLY(sequencenumber);
  4404. REPLYLENGTH(replylength);
  4405. WINDOW(childwindow);
  4406. INT16(dst_x);
  4407. INT16(dst_y);
  4408. UNUSED(16);
  4409. break;
  4410. case X_GetInputFocus:
  4411. REPLY(reply);
  4412. ENUM8(revert_to);
  4413. SEQUENCENUMBER_REPLY(sequencenumber);
  4414. REPLYLENGTH(replylength);
  4415. WINDOW(focus);
  4416. UNUSED(20);
  4417. break;
  4418. case X_QueryKeymap:
  4419. REPLY(reply);
  4420. UNUSED(1);
  4421. SEQUENCENUMBER_REPLY(sequencenumber);
  4422. REPLYLENGTH(replylength);
  4423. LISTofCARD8(keys, 32);
  4424. break;
  4425. case X_QueryFont:
  4426. case X_QueryTextExtents:
  4427. case X_ListFonts:
  4428. case X_GetImage:
  4429. case X_ListInstalledColormaps:
  4430. REPLYCONTENTS_COMMON();
  4431. break;
  4432. case X_AllocColor:
  4433. REPLY(reply);
  4434. UNUSED(1);
  4435. SEQUENCENUMBER_REPLY(sequencenumber);
  4436. REPLYLENGTH(replylength);
  4437. CARD16(red);
  4438. CARD16(green);
  4439. CARD16(blue);
  4440. UNUSED(2);
  4441. CARD32(pixel);
  4442. UNUSED(12);
  4443. break;
  4444. case X_QueryColors:
  4445. REPLYCONTENTS_COMMON();
  4446. break;
  4447. case X_LookupColor:
  4448. REPLY(reply);
  4449. UNUSED(1);
  4450. SEQUENCENUMBER_REPLY(sequencenumber);
  4451. REPLYLENGTH(replylength);
  4452. CARD16(exact_red);
  4453. CARD16(exact_green);
  4454. CARD16(exact_blue);
  4455. CARD16(visual_red);
  4456. CARD16(visual_green);
  4457. CARD16(visual_blue);
  4458. UNUSED(12);
  4459. break;
  4460. case X_QueryBestSize:
  4461. REPLY(reply);
  4462. UNUSED(1);
  4463. SEQUENCENUMBER_REPLY(sequencenumber);
  4464. REPLYLENGTH(replylength);
  4465. CARD16(width);
  4466. CARD16(height);
  4467. UNUSED(20);
  4468. break;
  4469. case X_QueryExtension:
  4470. REPLY(reply);
  4471. UNUSED(1);
  4472. SEQUENCENUMBER_REPLY(sequencenumber);
  4473. REPLYLENGTH(replylength);
  4474. BOOL(present);
  4475. CARD8(major_opcode);
  4476. CARD8(first_event);
  4477. CARD8(first_error);
  4478. UNUSED(20);
  4479. break;
  4480. case X_ListExtensions:
  4481. REPLYCONTENTS_COMMON();
  4482. break;
  4483. case X_GetKeyboardMapping:
  4484. state->first_keycode =
  4485. state->request.GetKeyboardMapping.first_keycode;
  4486. REPLY(reply);
  4487. state->keysyms_per_keycode =
  4488. FIELD8(keysyms_per_keycode);
  4489. SEQUENCENUMBER_REPLY(sequencenumber);
  4490. length = REPLYLENGTH(replylength);
  4491. UNUSED(24);
  4492. LISTofKEYSYM(keysyms, state->keycodemap,
  4493. state->request.GetKeyboardMapping.first_keycode,
  4494. /* XXX - length / state->keysyms_per_keycode can raise a division by zero,
  4495. * don't know if this is the *right* way to fix it ... */
  4496. state->keysyms_per_keycode ? length / state->keysyms_per_keycode : 0,
  4497. state->keysyms_per_keycode);
  4498. break;
  4499. case X_GetKeyboardControl:
  4500. REPLYCONTENTS_COMMON();
  4501. break;
  4502. case X_GetPointerControl:
  4503. REPLY(reply);
  4504. UNUSED(1);
  4505. SEQUENCENUMBER_REPLY(sequencenumber);
  4506. REPLYLENGTH(replylength);
  4507. CARD16(acceleration_numerator);
  4508. CARD16(acceleration_denominator);
  4509. CARD16(threshold);
  4510. UNUSED(18);
  4511. break;
  4512. case X_GetScreenSaver:
  4513. REPLY(reply);
  4514. UNUSED(1);
  4515. SEQUENCENUMBER_REPLY(sequencenumber);
  4516. REPLYLENGTH(replylength);
  4517. CARD16(timeout);
  4518. CARD16(interval);
  4519. ENUM8(prefer_blanking);
  4520. ENUM8(allow_exposures);
  4521. UNUSED(18);
  4522. break;
  4523. case X_ListHosts:
  4524. case X_SetPointerMapping:
  4525. case X_GetPointerMapping:
  4526. case X_SetModifierMapping:
  4527. REPLYCONTENTS_COMMON();
  4528. break;
  4529. case X_GetModifierMapping:
  4530. REPLY(reply);
  4531. state->keycodes_per_modifier =
  4532. FIELD8(keycodes_per_modifier);
  4533. SEQUENCENUMBER_REPLY(sequencenumber);
  4534. REPLYLENGTH(replylength);
  4535. UNUSED(24);
  4536. LISTofKEYCODE(state->modifiermap, keycodes,
  4537. state->keycodes_per_modifier);
  4538. break;
  4539. case UNKNOWN_OPCODE:
  4540. REPLYCONTENTS_COMMON();
  4541. break;
  4542. default:
  4543. tryExtensionReply(opcode, tvb, pinfo, offsetp, t, state, byte_order);
  4544. }
  4545. if ((left = tvb_reported_length_remaining(tvb, offset)) > 0)
  4546. UNDECODED(left);
  4547. }
  4548. static void
  4549. same_screen_focus(tvbuff_t *tvb, int *offsetp, proto_tree *t)
  4550. {
  4551. proto_item *ti;
  4552. guint32 bitmask_value;
  4553. int bitmask_offset;
  4554. int bitmask_size;
  4555. proto_tree *bitmask_tree;
  4556. bitmask_value = VALUE8(tvb, *offsetp);
  4557. bitmask_offset = *offsetp;
  4558. bitmask_size = 1;
  4559. ti = proto_tree_add_uint(t, hf_x11_same_screen_focus_mask, tvb, *offsetp, 1,
  4560. bitmask_value);
  4561. bitmask_tree = proto_item_add_subtree(ti, ett_x11_same_screen_focus);
  4562. FLAG(same_screen_focus, focus);
  4563. FLAG(same_screen_focus, same_screen);
  4564. *offsetp += 1;
  4565. }
  4566. static void
  4567. dissect_x11_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
  4568. const char *volatile sep, x11_conv_data_t *volatile state,
  4569. guint byte_order)
  4570. {
  4571. unsigned char eventcode;
  4572. const char *sent;
  4573. proto_item *ti;
  4574. proto_tree *t;
  4575. ti = proto_tree_add_item(tree, proto_x11, tvb, 0, -1, ENC_NA);
  4576. t = proto_item_add_subtree(ti, ett_x11);
  4577. eventcode = tvb_get_guint8(tvb, 0);
  4578. sent = (eventcode & 0x80) ? "Sent-" : "";
  4579. col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s%s",
  4580. sep, sent,
  4581. val_to_str(eventcode & 0x7F, state->eventcode_vals,
  4582. "<Unknown eventcode %u>"));
  4583. proto_item_append_text(ti, ", Event, eventcode: %d (%s%s)",
  4584. eventcode, sent,
  4585. val_to_str(eventcode & 0x7F, state->eventcode_vals,
  4586. "<Unknown eventcode %u>"));
  4587. if (tree == NULL)
  4588. return;
  4589. decode_x11_event(tvb, eventcode, sent, t, state, byte_order);
  4590. return;
  4591. }
  4592. static void
  4593. decode_x11_event(tvbuff_t *tvb, unsigned char eventcode, const char *sent,
  4594. proto_tree *t, x11_conv_data_t *volatile state,
  4595. guint byte_order)
  4596. {
  4597. int offset = 0, *offsetp = &offset, left;
  4598. proto_tree_add_uint_format(t, hf_x11_eventcode, tvb, offset, 1,
  4599. eventcode,
  4600. "eventcode: %d (%s%s)",
  4601. eventcode, sent,
  4602. val_to_str(eventcode & 0x7F, state->eventcode_vals,
  4603. "<Unknown eventcode %u>"));
  4604. ++offset;
  4605. switch (eventcode & 0x7F) {
  4606. case KeyPress:
  4607. case KeyRelease: {
  4608. int code, mask;
  4609. /* need to do some prefetching here ... */
  4610. code = VALUE8(tvb, offset);
  4611. mask = VALUE16(tvb, 28);
  4612. KEYCODE_DECODED(keycode, code, mask);
  4613. CARD16(event_sequencenumber);
  4614. EVENTCONTENTS_COMMON();
  4615. BOOL(same_screen);
  4616. UNUSED(1);
  4617. break;
  4618. }
  4619. case ButtonPress:
  4620. case ButtonRelease:
  4621. BUTTON(eventbutton);
  4622. CARD16(event_sequencenumber);
  4623. EVENTCONTENTS_COMMON();
  4624. BOOL(same_screen);
  4625. UNUSED(1);
  4626. break;
  4627. case MotionNotify:
  4628. CARD8(detail);
  4629. CARD16(event_sequencenumber);
  4630. EVENTCONTENTS_COMMON();
  4631. BOOL(same_screen);
  4632. UNUSED(1);
  4633. break;
  4634. case EnterNotify:
  4635. case LeaveNotify:
  4636. ENUM8(event_detail);
  4637. CARD16(event_sequencenumber);
  4638. EVENTCONTENTS_COMMON();
  4639. ENUM8(grab_mode);
  4640. same_screen_focus(tvb, offsetp, t);
  4641. break;
  4642. case FocusIn:
  4643. case FocusOut:
  4644. ENUM8(focus_detail);
  4645. CARD16(event_sequencenumber);
  4646. WINDOW(eventwindow);
  4647. ENUM8(focus_mode);
  4648. UNUSED(23);
  4649. break;
  4650. case KeymapNotify:
  4651. break;
  4652. case Expose:
  4653. UNUSED(1);
  4654. CARD16(event_sequencenumber);
  4655. WINDOW(eventwindow);
  4656. INT16(x);
  4657. INT16(y);
  4658. CARD16(width);
  4659. CARD16(height);
  4660. CARD16(count);
  4661. UNUSED(14);
  4662. break;
  4663. case GraphicsExpose:
  4664. UNUSED(1);
  4665. CARD16(event_sequencenumber);
  4666. DRAWABLE(drawable);
  4667. CARD16(x);
  4668. CARD16(y);
  4669. CARD16(width);
  4670. CARD16(height);
  4671. CARD16(minor_opcode);
  4672. CARD16(count);
  4673. CARD8(major_opcode);
  4674. UNUSED(11);
  4675. break;
  4676. case NoExpose:
  4677. UNUSED(1);
  4678. CARD16(event_sequencenumber);
  4679. DRAWABLE(drawable);
  4680. CARD16(minor_opcode);
  4681. CARD8(major_opcode);
  4682. UNUSED(21);
  4683. break;
  4684. case VisibilityNotify:
  4685. UNUSED(1);
  4686. CARD16(event_sequencenumber);
  4687. WINDOW(eventwindow);
  4688. ENUM8(visibility_state);
  4689. UNUSED(23);
  4690. break;
  4691. case CreateNotify:
  4692. UNUSED(1);
  4693. CARD16(event_sequencenumber);
  4694. WINDOW(parent);
  4695. WINDOW(eventwindow);
  4696. INT16(x);
  4697. INT16(y);
  4698. CARD16(width);
  4699. CARD16(height);
  4700. CARD16(border_width);
  4701. BOOL(override_redirect);
  4702. UNUSED(9);
  4703. break;
  4704. case DestroyNotify:
  4705. UNUSED(1);
  4706. CARD16(event_sequencenumber);
  4707. WINDOW(eventwindow);
  4708. WINDOW(window);
  4709. UNUSED(20);
  4710. break;
  4711. case UnmapNotify:
  4712. UNUSED(1);
  4713. CARD16(event_sequencenumber);
  4714. WINDOW(eventwindow);
  4715. WINDOW(window);
  4716. BOOL(from_configure);
  4717. UNUSED(19);
  4718. break;
  4719. case MapNotify:
  4720. UNUSED(1);
  4721. CARD16(event_sequencenumber);
  4722. WINDOW(eventwindow);
  4723. WINDOW(window);
  4724. BOOL(override_redirect);
  4725. UNUSED(19);
  4726. break;
  4727. case MapRequest:
  4728. UNUSED(1);
  4729. CARD16(event_sequencenumber);
  4730. WINDOW(parent);
  4731. WINDOW(eventwindow);
  4732. UNUSED(20);
  4733. break;
  4734. case ReparentNotify:
  4735. UNUSED(1);
  4736. CARD16(event_sequencenumber);
  4737. WINDOW(eventwindow);
  4738. WINDOW(window);
  4739. WINDOW(parent);
  4740. INT16(x);
  4741. INT16(y);
  4742. BOOL(override_redirect);
  4743. UNUSED(11);
  4744. break;
  4745. case ConfigureNotify:
  4746. UNUSED(1);
  4747. CARD16(event_sequencenumber);
  4748. WINDOW(eventwindow);
  4749. WINDOW(window);
  4750. WINDOW(above_sibling);
  4751. INT16(x);
  4752. INT16(y);
  4753. CARD16(width);
  4754. CARD16(height);
  4755. CARD16(border_width);
  4756. BOOL(override_redirect);
  4757. UNUSED(5);
  4758. break;
  4759. case ConfigureRequest:
  4760. break;
  4761. case GravityNotify:
  4762. UNUSED(1);
  4763. CARD16(event_sequencenumber);
  4764. WINDOW(eventwindow);
  4765. WINDOW(window);
  4766. INT16(x);
  4767. INT16(y);
  4768. UNUSED(16);
  4769. break;
  4770. case ResizeRequest:
  4771. UNUSED(1);
  4772. CARD16(event_sequencenumber);
  4773. WINDOW(eventwindow);
  4774. CARD16(width);
  4775. CARD16(height);
  4776. UNUSED(20);
  4777. break;
  4778. case CirculateNotify:
  4779. UNUSED(1);
  4780. CARD16(event_sequencenumber);
  4781. WINDOW(eventwindow);
  4782. WINDOW(window);
  4783. UNUSED(4);
  4784. ENUM8(place);
  4785. UNUSED(15);
  4786. break;
  4787. case CirculateRequest:
  4788. UNUSED(1);
  4789. CARD16(event_sequencenumber);
  4790. WINDOW(parent);
  4791. WINDOW(eventwindow);
  4792. UNUSED(4);
  4793. ENUM8(place);
  4794. UNUSED(15);
  4795. break;
  4796. case PropertyNotify:
  4797. UNUSED(1);
  4798. CARD16(event_sequencenumber);
  4799. WINDOW(eventwindow);
  4800. ATOM(atom);
  4801. TIMESTAMP(time);
  4802. ENUM8(property_state);
  4803. UNUSED(15);
  4804. break;
  4805. case SelectionClear:
  4806. UNUSED(1);
  4807. CARD16(event_sequencenumber);
  4808. TIMESTAMP(time);
  4809. WINDOW(owner);
  4810. ATOM(selection);
  4811. UNUSED(16);
  4812. break;
  4813. case SelectionRequest:
  4814. UNUSED(1);
  4815. CARD16(event_sequencenumber);
  4816. TIMESTAMP(time);
  4817. WINDOW(owner);
  4818. WINDOW(requestor);
  4819. ATOM(selection);
  4820. ATOM(target);
  4821. ATOM(property);
  4822. UNUSED(4);
  4823. break;
  4824. case SelectionNotify:
  4825. UNUSED(1);
  4826. CARD16(event_sequencenumber);
  4827. TIMESTAMP(time);
  4828. WINDOW(requestor);
  4829. ATOM(selection);
  4830. ATOM(target);
  4831. ATOM(property);
  4832. UNUSED(8);
  4833. break;
  4834. case ColormapNotify:
  4835. UNUSED(1);
  4836. CARD16(event_sequencenumber);
  4837. WINDOW(eventwindow);
  4838. COLORMAP(cmap);
  4839. BOOL(new);
  4840. ENUM8(colormap_state);
  4841. UNUSED(18);
  4842. break;
  4843. case ClientMessage:
  4844. CARD8(format);
  4845. CARD16(event_sequencenumber);
  4846. WINDOW(eventwindow);
  4847. ATOM(type);
  4848. LISTofBYTE(data, 20);
  4849. break;
  4850. case MappingNotify:
  4851. UNUSED(1);
  4852. CARD16(event_sequencenumber);
  4853. ENUM8(mapping_request);
  4854. CARD8(first_keycode);
  4855. CARD8(count);
  4856. UNUSED(25);
  4857. break;
  4858. default:
  4859. tryExtensionEvent(eventcode & 0x7F, tvb, offsetp, t, state, byte_order);
  4860. break;
  4861. }
  4862. if ((left = tvb_reported_length_remaining(tvb, offset)) > 0)
  4863. UNDECODED(left);
  4864. return;
  4865. }
  4866. static void
  4867. dissect_x11_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
  4868. const char *volatile sep, x11_conv_data_t *volatile state _U_,
  4869. guint byte_order)
  4870. {
  4871. int offset = 0, *offsetp = &offset, left;
  4872. unsigned char errorcode;
  4873. proto_item *ti;
  4874. proto_tree *t;
  4875. ti = proto_tree_add_item(tree, proto_x11, tvb, 0, -1, ENC_NA);
  4876. t = proto_item_add_subtree(ti, ett_x11);
  4877. CARD8(error);
  4878. errorcode = tvb_get_guint8(tvb, offset);
  4879. col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
  4880. sep, val_to_str(errorcode, state->errorcode_vals, "<Unknown errorcode %u>"));
  4881. proto_tree_add_uint_format(t, hf_x11_errorcode, tvb, offset, 1,
  4882. errorcode,
  4883. "errorcode: %d (%s)",
  4884. errorcode,
  4885. val_to_str(errorcode, state->errorcode_vals,
  4886. "<Unknown errorcode %u>"));
  4887. ++offset;
  4888. proto_item_append_text(ti, ", Error, errorcode: %d (%s)",
  4889. errorcode, val_to_str(errorcode, state->errorcode_vals,
  4890. "<Unknown errorcode %u>"));
  4891. if (tree == NULL)
  4892. return;
  4893. CARD16(error_sequencenumber);
  4894. switch (errorcode) {
  4895. case BadValue:
  4896. CARD32(error_badvalue);
  4897. break;
  4898. default:
  4899. UNDECODED(4);
  4900. }
  4901. CARD16(minor_opcode);
  4902. CARD8(major_opcode);
  4903. if ((left = tvb_reported_length_remaining(tvb, offset)) > 0)
  4904. UNDECODED(left);
  4905. }
  4906. /************************************************************************
  4907. *** ***
  4908. *** I N I T I A L I Z A T I O N A N D M A I N ***
  4909. *** ***
  4910. ************************************************************************/
  4911. static void
  4912. dissect_x11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
  4913. {
  4914. col_set_str(pinfo->cinfo, COL_PROTOCOL, "X11");
  4915. if (pinfo->match_uint == pinfo->srcport)
  4916. dissect_x11_replies(tvb, pinfo, tree);
  4917. else
  4918. dissect_x11_requests(tvb, pinfo, tree);
  4919. }
  4920. /* Register the protocol with Wireshark */
  4921. void proto_register_x11(void)
  4922. {
  4923. /* Setup list of header fields */
  4924. static hf_register_info hf[] = {
  4925. #include "x11-register-info.h"
  4926. };
  4927. /* Setup protocol subtree array */
  4928. static gint *ett[] = {
  4929. &ett_x11,
  4930. &ett_x11_color_flags,
  4931. &ett_x11_list_of_arc,
  4932. &ett_x11_arc,
  4933. &ett_x11_list_of_atom,
  4934. &ett_x11_list_of_card32,
  4935. &ett_x11_list_of_float,
  4936. &ett_x11_list_of_double,
  4937. &ett_x11_list_of_color_item,
  4938. &ett_x11_color_item,
  4939. &ett_x11_list_of_keycode,
  4940. &ett_x11_list_of_keysyms,
  4941. &ett_x11_keysym,
  4942. &ett_x11_list_of_point,
  4943. &ett_x11_point,
  4944. &ett_x11_list_of_rectangle,
  4945. &ett_x11_rectangle,
  4946. &ett_x11_list_of_segment,
  4947. &ett_x11_segment,
  4948. &ett_x11_list_of_string8,
  4949. &ett_x11_list_of_text_item,
  4950. &ett_x11_text_item,
  4951. &ett_x11_gc_value_mask,
  4952. &ett_x11_event_mask,
  4953. &ett_x11_do_not_propagate_mask,
  4954. &ett_x11_set_of_key_mask,
  4955. &ett_x11_pointer_event_mask,
  4956. &ett_x11_window_value_mask,
  4957. &ett_x11_configure_window_mask,
  4958. &ett_x11_keyboard_value_mask,
  4959. &ett_x11_same_screen_focus,
  4960. &ett_x11_event,
  4961. };
  4962. static ei_register_info ei[] = {
  4963. { &ei_x11_invalid_format, { "x11.invalid_format", PI_PROTOCOL, PI_WARN, "Invalid Format", EXPFILL }},
  4964. };
  4965. module_t *x11_module;
  4966. expert_module_t* expert_x11;
  4967. /* Register the protocol name and description */
  4968. proto_x11 = proto_register_protocol("X11", "X11", "x11");
  4969. /* Required function calls to register the header fields and subtrees used */
  4970. proto_register_field_array(proto_x11, hf, array_length(hf));
  4971. proto_register_subtree_array(ett, array_length(ett));
  4972. expert_x11 = expert_register_protocol(proto_x11);
  4973. expert_register_field_array(expert_x11, ei, array_length(ei));
  4974. register_init_routine(x11_init_protocol);
  4975. extension_table = g_hash_table_new(g_str_hash, g_str_equal);
  4976. error_table = g_hash_table_new(g_str_hash, g_str_equal);
  4977. event_table = g_hash_table_new(g_str_hash, g_str_equal);
  4978. reply_table = g_hash_table_new(g_str_hash, g_str_equal);
  4979. register_x11_extensions();
  4980. x11_module = prefs_register_protocol(proto_x11, NULL);
  4981. prefs_register_bool_preference(x11_module, "desegment",
  4982. "Reassemble X11 messages spanning multiple TCP segments",
  4983. "Whether the X11 dissector should reassemble messages spanning multiple TCP segments. "
  4984. "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
  4985. &x11_desegment);
  4986. }
  4987. void
  4988. proto_reg_handoff_x11(void)
  4989. {
  4990. dissector_handle_t x11_handle;
  4991. x11_handle = create_dissector_handle(dissect_x11, proto_x11);
  4992. dissector_add_uint("tcp.port", TCP_PORT_X11, x11_handle);
  4993. dissector_add_uint("tcp.port", TCP_PORT_X11_2, x11_handle);
  4994. dissector_add_uint("tcp.port", TCP_PORT_X11_3, x11_handle);
  4995. }
  4996. /*
  4997. * Editor modelines
  4998. *
  4999. * Local Variables:
  5000. * c-basic-offset: 6
  5001. * tab-width: 8
  5002. * indent-tabs-mode: nil
  5003. * End:
  5004. *
  5005. * ex: set shiftwidth=6 tabstop=8 expandtab:
  5006. * :indentSize=6:tabSize=8:noTabs=true:
  5007. */