PageRenderTime 91ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/epan/proto.c

https://github.com/labx-technologies-llc/wireshark
C | 7564 lines | 5237 code | 1162 blank | 1165 comment | 898 complexity | 949f7def75a5a6f0cc4c3a4d9679517f MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. /* proto.c
  2. * Routines for protocol tree
  3. *
  4. * $Id$
  5. *
  6. * Wireshark - Network traffic analyzer
  7. * By Gerald Combs <gerald@wireshark.org>
  8. * Copyright 1998 Gerald Combs
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License
  12. * as published by the Free Software Foundation; either version 2
  13. * of the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  23. */
  24. #include "config.h"
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <ctype.h>
  28. #include <glib.h>
  29. #include <float.h>
  30. #include "packet.h"
  31. #include "ptvcursor.h"
  32. #include "strutil.h"
  33. #include "addr_resolv.h"
  34. #include "oids.h"
  35. #include "plugins.h"
  36. #include "proto.h"
  37. #include "epan_dissect.h"
  38. #include "tvbuff.h"
  39. #include "emem.h"
  40. #include "charsets.h"
  41. #include "asm_utils.h"
  42. #include "column-utils.h"
  43. #include "to_str.h"
  44. #include "expert.h"
  45. #include "show_exception.h"
  46. #include "wspython/wspy_register.h"
  47. #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
  48. #define SUBTREE_MAX_LEVELS 256
  49. /* Throw an exception if we exceed this many tree items. */
  50. /* XXX - This should probably be a preference */
  51. #define MAX_TREE_ITEMS (1 * 1000 * 1000)
  52. typedef struct __subtree_lvl {
  53. gint cursor_offset;
  54. proto_item *it;
  55. proto_tree *tree;
  56. } subtree_lvl;
  57. struct ptvcursor {
  58. subtree_lvl *pushed_tree;
  59. guint8 pushed_tree_index;
  60. guint8 pushed_tree_max;
  61. proto_tree *tree;
  62. tvbuff_t *tvb;
  63. gint offset;
  64. };
  65. #define cVALS(x) (const value_string*)(x)
  66. /** See inlined comments.
  67. @param tree the tree to append this item to
  68. @param hfindex field index
  69. @param hfinfo header_field
  70. @return the header field matching 'hfinfo' */
  71. #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
  72. /* If this item is not referenced we dont have to do much work \
  73. at all but we should still return a node so that field items \
  74. below this node (think proto_item_add_subtree()) will still \
  75. have somewhere to attach to or else filtering will not work \
  76. (they would be ignored since tree would be NULL). \
  77. DONT try to fake a node where PTREE_FINFO(tree) is NULL \
  78. since dissectors that want to do proto_item_set_len() or \
  79. other operations that dereference this would crash. \
  80. We fake FT_PROTOCOL unless some clients have requested us \
  81. not to do so. \
  82. */ \
  83. if (!tree) \
  84. return NULL; \
  85. PTREE_DATA(tree)->count++; \
  86. if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) { \
  87. if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) \
  88. g_error("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS); \
  89. /* Let the exception handler add items to the tree */ \
  90. PTREE_DATA(tree)->count = 0; \
  91. THROW_MESSAGE(DissectorError, \
  92. ep_strdup_printf("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS)); \
  93. } \
  94. PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); \
  95. if (!(PTREE_DATA(tree)->visible)) { \
  96. if (PTREE_FINFO(tree)) { \
  97. if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
  98. && (hfinfo->type != FT_PROTOCOL || \
  99. PTREE_DATA(tree)->fake_protocols)) { \
  100. /* just return tree back to the caller */\
  101. return tree; \
  102. } \
  103. } \
  104. }
  105. /** See inlined comments.
  106. @param pi the created protocol item we're about to return */
  107. #define TRY_TO_FAKE_THIS_REPR(pi) \
  108. g_assert(pi); \
  109. if (!(PTREE_DATA(pi)->visible)) { \
  110. /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
  111. * items string representation */ \
  112. return pi; \
  113. }
  114. static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
  115. static void fill_label_boolean(field_info *fi, gchar *label_str);
  116. static void fill_label_bitfield(field_info *fi, gchar *label_str);
  117. static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
  118. static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
  119. static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
  120. static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
  121. static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
  122. static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
  123. static const char* hfinfo_uint64_format(const header_field_info *hfinfo);
  124. static const char* hfinfo_int64_format(const header_field_info *hfinfo);
  125. static proto_item *
  126. proto_tree_add_node(proto_tree *tree, field_info *fi);
  127. static void
  128. get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
  129. gint *item_length);
  130. static field_info *
  131. new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
  132. const gint start, const gint item_length);
  133. static field_info *
  134. alloc_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
  135. const gint start, gint *length);
  136. static proto_item *
  137. proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
  138. gint start, gint *length, field_info **pfi);
  139. static void
  140. proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
  141. static void
  142. proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
  143. static void
  144. proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb);
  145. static void
  146. proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
  147. static void
  148. proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
  149. static void
  150. proto_tree_set_time(field_info *fi, nstime_t *value_ptr);
  151. static void
  152. proto_tree_set_string(field_info *fi, const char* value);
  153. static void
  154. proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length, gint encoding);
  155. static void
  156. proto_tree_set_ax25(field_info *fi, const guint8* value);
  157. static void
  158. proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
  159. static void
  160. proto_tree_set_vines(field_info *fi, const guint8* value);
  161. static void
  162. proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
  163. static void
  164. proto_tree_set_ether(field_info *fi, const guint8* value);
  165. static void
  166. proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
  167. static void
  168. proto_tree_set_ipxnet(field_info *fi, guint32 value);
  169. static void
  170. proto_tree_set_ipv4(field_info *fi, guint32 value);
  171. static void
  172. proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
  173. static void
  174. proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
  175. static void
  176. proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
  177. static void
  178. proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
  179. static void
  180. proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
  181. static void
  182. proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
  183. static void
  184. proto_tree_set_boolean(field_info *fi, guint32 value);
  185. static void
  186. proto_tree_set_float(field_info *fi, float value);
  187. static void
  188. proto_tree_set_double(field_info *fi, double value);
  189. static void
  190. proto_tree_set_uint(field_info *fi, guint32 value);
  191. static void
  192. proto_tree_set_int(field_info *fi, gint32 value);
  193. static void
  194. proto_tree_set_uint64(field_info *fi, guint64 value);
  195. static void
  196. proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, guint length, const guint encoding);
  197. static void
  198. proto_tree_set_eui64(field_info *fi, const guint64 value);
  199. static void
  200. proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
  201. static gboolean
  202. proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
  203. const int len, const gint ett, const gint **fields,
  204. const guint encoding, const int flags,
  205. gboolean first);
  206. static int proto_register_field_init(header_field_info *hfinfo, const int parent);
  207. /* special-case header field used within proto.c */
  208. static header_field_info hfi_text_only =
  209. { "Text item", "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
  210. int hf_text_only = -1;
  211. /* Structure for information about a protocol */
  212. struct _protocol {
  213. const char *name; /* long description */
  214. const char *short_name; /* short description */
  215. const char *filter_name; /* name of this protocol in filters */
  216. int proto_id; /* field ID for this protocol */
  217. GSList *fields; /* fields for this protocol */
  218. GSList *last_field; /* pointer to end of list of fields */
  219. gboolean is_enabled; /* TRUE if protocol is enabled */
  220. gboolean can_toggle; /* TRUE if is_enabled can be changed */
  221. gboolean is_private; /* TRUE is protocol is private */
  222. };
  223. /* List of all protocols */
  224. static GList *protocols = NULL;
  225. #define INITIAL_NUM_PROTOCOL_HFINFO 1500
  226. /* Contains information about a field when a dissector calls
  227. * proto_tree_add_item. */
  228. #define FIELD_INFO_NEW(fi) fi = g_slice_new(field_info)
  229. #define FIELD_INFO_FREE(fi) g_slice_free(field_info, fi)
  230. /* Contains the space for proto_nodes. */
  231. #define PROTO_NODE_NEW(node) \
  232. node = g_slice_new(proto_node); \
  233. node->first_child = NULL; \
  234. node->last_child = NULL; \
  235. node->next = NULL;
  236. #define PROTO_NODE_FREE(node) \
  237. g_slice_free(proto_node, node)
  238. /* String space for protocol and field items for the GUI */
  239. #define ITEM_LABEL_NEW(il) \
  240. il = g_slice_new(item_label_t);
  241. #define ITEM_LABEL_FREE(il) \
  242. g_slice_free(item_label_t, il);
  243. #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
  244. if((guint)hfindex >= gpa_hfinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG")) \
  245. g_error("Unregistered hf! index=%d", hfindex); \
  246. DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!"); \
  247. hfinfo = gpa_hfinfo.hfi[hfindex];
  248. /* List which stores protocols and fields that have been registered */
  249. typedef struct _gpa_hfinfo_t {
  250. guint32 len;
  251. guint32 allocated_len;
  252. header_field_info **hfi;
  253. } gpa_hfinfo_t;
  254. static gpa_hfinfo_t gpa_hfinfo;
  255. /* Balanced tree of abbreviations and IDs */
  256. static GTree *gpa_name_tree = NULL;
  257. static header_field_info *same_name_hfinfo;
  258. static void save_same_name_hfinfo(gpointer data)
  259. {
  260. same_name_hfinfo = (header_field_info*)data;
  261. }
  262. /* Points to the first element of an array of bits, indexed by
  263. a subtree item type; that array element is TRUE if subtrees of
  264. an item of that type are to be expanded. */
  265. static guint32 *tree_is_expanded;
  266. /* Number of elements in that array. */
  267. int num_tree_types;
  268. /* Name hashtables for fast detection of duplicate names */
  269. static GHashTable* proto_names = NULL;
  270. static GHashTable* proto_short_names = NULL;
  271. static GHashTable* proto_filter_names = NULL;
  272. static gint
  273. proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
  274. {
  275. const protocol_t *p1 = (const protocol_t *)p1_arg;
  276. const protocol_t *p2 = (const protocol_t *)p2_arg;
  277. return g_ascii_strcasecmp(p1->short_name, p2->short_name);
  278. }
  279. /* initialize data structures and register protocols and fields */
  280. void
  281. proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_data),
  282. void (register_all_handoffs_func)(register_cb cb, gpointer client_data),
  283. register_cb cb,
  284. gpointer client_data)
  285. {
  286. proto_cleanup();
  287. proto_names = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
  288. proto_short_names = g_hash_table_new(wrs_str_hash, g_str_equal);
  289. proto_filter_names = g_hash_table_new(wrs_str_hash, g_str_equal);
  290. gpa_hfinfo.len = 0;
  291. gpa_hfinfo.allocated_len = 0;
  292. gpa_hfinfo.hfi = NULL;
  293. gpa_name_tree = g_tree_new_full(wrs_strcmp_with_data, NULL, NULL, save_same_name_hfinfo);
  294. /* Initialize the ftype subsystem */
  295. ftypes_initialize();
  296. /* Register one special-case FT_TEXT_ONLY field for use when
  297. converting wireshark to new-style proto_tree. These fields
  298. are merely strings on the GUI tree; they are not filterable */
  299. hf_text_only = proto_register_field_init(&hfi_text_only, -1);
  300. /* Register the pseudo-protocols used for exceptions. */
  301. register_show_exception();
  302. /* Have each built-in dissector register its protocols, fields,
  303. dissector tables, and dissectors to be called through a
  304. handle, and do whatever one-time initialization it needs to
  305. do. */
  306. register_all_protocols_func(cb, client_data);
  307. #ifdef HAVE_PYTHON
  308. /* Now scan for python protocols */
  309. if (cb)
  310. (*cb)(RA_PYTHON_REGISTER, NULL, client_data);
  311. register_all_py_protocols_func();
  312. #endif
  313. #ifdef HAVE_PLUGINS
  314. /* Now scan for plugins and load all the ones we find, calling
  315. their register routines to do the stuff described above. */
  316. if (cb)
  317. (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
  318. init_plugins();
  319. register_all_plugin_registrations();
  320. #endif
  321. /* Now call the "handoff registration" routines of all built-in
  322. dissectors; those routines register the dissector in other
  323. dissectors' handoff tables, and fetch any dissector handles
  324. they need. */
  325. register_all_handoffs_func(cb, client_data);
  326. #ifdef HAVE_PYTHON
  327. /* Now do the same with python dissectors */
  328. if (cb)
  329. (*cb)(RA_PYTHON_HANDOFF, NULL, client_data);
  330. register_all_py_handoffs_func();
  331. #endif
  332. #ifdef HAVE_PLUGINS
  333. /* Now do the same with plugins. */
  334. if (cb)
  335. (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
  336. register_all_plugin_handoffs();
  337. #endif
  338. /* sort the protocols by protocol name */
  339. protocols = g_list_sort(protocols, proto_compare_name);
  340. /* We've assigned all the subtree type values; allocate the array
  341. for them, and zero it out. */
  342. tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
  343. }
  344. void
  345. proto_cleanup(void)
  346. {
  347. /* Free the abbrev/ID GTree */
  348. if (gpa_name_tree) {
  349. g_tree_destroy(gpa_name_tree);
  350. gpa_name_tree = NULL;
  351. }
  352. while (protocols) {
  353. protocol_t *protocol = (protocol_t *)protocols->data;
  354. header_field_info *hfinfo;
  355. PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
  356. DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
  357. g_slice_free(header_field_info, hfinfo);
  358. g_slist_free(protocol->fields);
  359. protocols = g_list_remove(protocols, protocol);
  360. g_free(protocol);
  361. }
  362. if (proto_names) {
  363. g_hash_table_destroy(proto_names);
  364. proto_names = NULL;
  365. }
  366. if (proto_short_names) {
  367. g_hash_table_destroy(proto_short_names);
  368. proto_short_names = NULL;
  369. }
  370. if (proto_filter_names) {
  371. g_hash_table_destroy(proto_filter_names);
  372. proto_filter_names = NULL;
  373. }
  374. if (gpa_hfinfo.allocated_len) {
  375. gpa_hfinfo.len = 0;
  376. gpa_hfinfo.allocated_len = 0;
  377. g_free(gpa_hfinfo.hfi);
  378. gpa_hfinfo.hfi = NULL;
  379. }
  380. g_free(tree_is_expanded);
  381. tree_is_expanded = NULL;
  382. }
  383. static gboolean
  384. proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
  385. gpointer data)
  386. {
  387. proto_node *pnode = tree;
  388. proto_node *child;
  389. proto_node *current;
  390. if (func(pnode, data))
  391. return TRUE;
  392. child = pnode->first_child;
  393. while (child != NULL) {
  394. /*
  395. * The routine we call might modify the child, e.g. by
  396. * freeing it, so we get the child's successor before
  397. * calling that routine.
  398. */
  399. current = child;
  400. child = current->next;
  401. if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
  402. return TRUE;
  403. }
  404. return FALSE;
  405. }
  406. gboolean
  407. proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
  408. gpointer data)
  409. {
  410. proto_node *pnode = tree;
  411. proto_node *child;
  412. proto_node *current;
  413. child = pnode->first_child;
  414. while (child != NULL) {
  415. /*
  416. * The routine we call might modify the child, e.g. by
  417. * freeing it, so we get the child's successor before
  418. * calling that routine.
  419. */
  420. current = child;
  421. child = current->next;
  422. if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
  423. return TRUE;
  424. }
  425. if (func(pnode, data))
  426. return TRUE;
  427. return FALSE;
  428. }
  429. void
  430. proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
  431. gpointer data)
  432. {
  433. proto_node *node = tree;
  434. proto_node *current;
  435. if (!node)
  436. return;
  437. node = node->first_child;
  438. while (node != NULL) {
  439. current = node;
  440. node = current->next;
  441. func((proto_tree *)current, data);
  442. }
  443. }
  444. static void
  445. free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
  446. {
  447. GPtrArray *ptrs = (GPtrArray *)value;
  448. gint hfid = (gint)(long)key;
  449. header_field_info *hfinfo;
  450. PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
  451. if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
  452. /* when a field is referenced by a filter this also
  453. affects the refcount for the parent protocol so we need
  454. to adjust the refcount for the parent as well
  455. */
  456. if (hfinfo->parent != -1) {
  457. header_field_info *parent_hfinfo;
  458. PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
  459. parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
  460. }
  461. hfinfo->ref_type = HF_REF_TYPE_NONE;
  462. }
  463. g_ptr_array_free(ptrs, TRUE);
  464. }
  465. static void
  466. free_node_tree_data(tree_data_t *tree_data)
  467. {
  468. if (tree_data->interesting_hfids) {
  469. /* Free all the GPtrArray's in the interesting_hfids hash. */
  470. g_hash_table_foreach(tree_data->interesting_hfids,
  471. free_GPtrArray_value, NULL);
  472. /* And then destroy the hash. */
  473. g_hash_table_destroy(tree_data->interesting_hfids);
  474. }
  475. if (tree_data->fi_tmp)
  476. FIELD_INFO_FREE(tree_data->fi_tmp);
  477. /* And finally the tree_data_t itself. */
  478. g_free(tree_data);
  479. }
  480. #define FREE_NODE_FIELD_INFO(finfo) \
  481. if (finfo->rep) { \
  482. ITEM_LABEL_FREE(finfo->rep); \
  483. } \
  484. FVALUE_CLEANUP(&finfo->value); \
  485. FIELD_INFO_FREE(finfo);
  486. static void
  487. proto_tree_free_node(proto_node *node, gpointer data _U_)
  488. {
  489. field_info *finfo = PNODE_FINFO(node);
  490. proto_tree_children_foreach(node, proto_tree_free_node, NULL);
  491. /* free the field_info data. */
  492. FREE_NODE_FIELD_INFO(finfo);
  493. node->finfo = NULL;
  494. /* Free the proto_node. */
  495. PROTO_NODE_FREE(node);
  496. }
  497. /* frees the resources that the dissection a proto_tree uses */
  498. void
  499. proto_tree_free(proto_tree *tree)
  500. {
  501. tree_data_t *tree_data = PTREE_DATA(tree);
  502. proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
  503. /* free root node */
  504. PROTO_NODE_FREE(tree);
  505. /* free tree data */
  506. free_node_tree_data(tree_data);
  507. }
  508. /* Is the parsing being done for a visible proto_tree or an invisible one?
  509. * By setting this correctly, the proto_tree creation is sped up by not
  510. * having to call g_vsnprintf and copy strings around.
  511. */
  512. gboolean
  513. proto_tree_set_visible(proto_tree *tree, gboolean visible)
  514. {
  515. gboolean old_visible = PTREE_DATA(tree)->visible;
  516. PTREE_DATA(tree)->visible = visible;
  517. return old_visible;
  518. }
  519. void
  520. proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
  521. {
  522. PTREE_DATA(tree)->fake_protocols = fake_protocols;
  523. }
  524. /* Assume dissector set only its protocol fields.
  525. This function is called by dissectors and allows the speeding up of filtering
  526. in wireshark; if this function returns FALSE it is safe to reset tree to NULL
  527. and thus skip calling most of the expensive proto_tree_add_...()
  528. functions.
  529. If the tree is visible we implicitly assume the field is referenced.
  530. */
  531. gboolean
  532. proto_field_is_referenced(proto_tree *tree, int proto_id)
  533. {
  534. register header_field_info *hfinfo;
  535. if (!tree)
  536. return FALSE;
  537. if (PTREE_DATA(tree)->visible)
  538. return TRUE;
  539. PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
  540. if (hfinfo->ref_type != HF_REF_TYPE_NONE)
  541. return TRUE;
  542. if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
  543. return TRUE;
  544. return FALSE;
  545. }
  546. /* Finds a record in the hfinfo array by id. */
  547. header_field_info *
  548. proto_registrar_get_nth(guint hfindex)
  549. {
  550. register header_field_info *hfinfo;
  551. PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
  552. return hfinfo;
  553. }
  554. /* Prefix initialization
  555. * this allows for a dissector to register a display filter name prefix
  556. * so that it can delay the initialization of the hf array as long as
  557. * possible.
  558. */
  559. /* compute a hash for the part before the dot of a display filter */
  560. static guint
  561. prefix_hash (gconstpointer key) {
  562. /* end the string at the dot and compute its hash */
  563. gchar* copy = ep_strdup((const gchar *)key);
  564. gchar* c = copy;
  565. for (; *c; c++) {
  566. if (*c == '.') {
  567. *c = 0;
  568. break;
  569. }
  570. }
  571. return g_str_hash(copy);
  572. }
  573. /* are both strings equal up to the end or the dot? */
  574. static gboolean
  575. prefix_equal (gconstpointer ap, gconstpointer bp) {
  576. const gchar* a = (const gchar *)ap;
  577. const gchar* b = (const gchar *)bp;
  578. do {
  579. gchar ac = *a++;
  580. gchar bc = *b++;
  581. if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE;
  582. if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
  583. if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
  584. if (ac != bc) return FALSE;
  585. } while (1);
  586. return FALSE;
  587. }
  588. /* indexed by prefix, contains initializers */
  589. static GHashTable* prefixes = NULL;
  590. /* Register a new prefix for "delayed" initialization of field arrays */
  591. void
  592. proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
  593. if (! prefixes ) {
  594. prefixes = g_hash_table_new(prefix_hash, prefix_equal);
  595. }
  596. g_hash_table_insert(prefixes, (gpointer)prefix, pi);
  597. }
  598. /* helper to call all prefix initializers */
  599. static gboolean
  600. initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
  601. ((prefix_initializer_t)v)((const char *)k);
  602. return TRUE;
  603. }
  604. /** Initialize every remaining uninitialized prefix. */
  605. void
  606. proto_initialize_all_prefixes(void) {
  607. g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
  608. }
  609. /* Finds a record in the hfinfo array by name.
  610. * If it fails to find it in the already registered fields,
  611. * it tries to find and call an initializer in the prefixes
  612. * table and if so it looks again.
  613. */
  614. header_field_info *
  615. proto_registrar_get_byname(const char *field_name)
  616. {
  617. header_field_info *hfinfo;
  618. prefix_initializer_t pi;
  619. if (!field_name)
  620. return NULL;
  621. hfinfo = (header_field_info *)g_tree_lookup(gpa_name_tree, field_name);
  622. if (hfinfo)
  623. return hfinfo;
  624. if (!prefixes)
  625. return NULL;
  626. if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
  627. pi(field_name);
  628. g_hash_table_remove(prefixes, field_name);
  629. } else {
  630. return NULL;
  631. }
  632. return (header_field_info *)g_tree_lookup(gpa_name_tree, field_name);
  633. }
  634. int
  635. proto_registrar_get_id_byname(const char *field_name)
  636. {
  637. header_field_info *hfinfo;
  638. hfinfo = proto_registrar_get_byname(field_name);
  639. if (!hfinfo)
  640. return -1;
  641. return hfinfo->id;
  642. }
  643. static void
  644. ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
  645. {
  646. subtree_lvl *pushed_tree;
  647. DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
  648. ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
  649. pushed_tree = (subtree_lvl *)ep_alloc(sizeof(subtree_lvl) * ptvc->pushed_tree_max);
  650. DISSECTOR_ASSERT(pushed_tree != NULL);
  651. if (ptvc->pushed_tree)
  652. memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
  653. ptvc->pushed_tree = pushed_tree;
  654. }
  655. static void
  656. ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
  657. {
  658. ptvc->pushed_tree = NULL;
  659. ptvc->pushed_tree_max = 0;
  660. DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
  661. ptvc->pushed_tree_index = 0;
  662. }
  663. /* Allocates an initializes a ptvcursor_t with 3 variables:
  664. * proto_tree, tvbuff, and offset. */
  665. ptvcursor_t *
  666. ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
  667. {
  668. ptvcursor_t *ptvc;
  669. ptvc = (ptvcursor_t *)ep_alloc(sizeof(ptvcursor_t));
  670. ptvc->tree = tree;
  671. ptvc->tvb = tvb;
  672. ptvc->offset = offset;
  673. ptvc->pushed_tree = NULL;
  674. ptvc->pushed_tree_max = 0;
  675. ptvc->pushed_tree_index = 0;
  676. return ptvc;
  677. }
  678. /* Frees memory for ptvcursor_t, but nothing deeper than that. */
  679. void
  680. ptvcursor_free(ptvcursor_t *ptvc)
  681. {
  682. ptvcursor_free_subtree_levels(ptvc);
  683. /*g_free(ptvc);*/
  684. }
  685. /* Returns tvbuff. */
  686. tvbuff_t *
  687. ptvcursor_tvbuff(ptvcursor_t *ptvc)
  688. {
  689. return ptvc->tvb;
  690. }
  691. /* Returns current offset. */
  692. gint
  693. ptvcursor_current_offset(ptvcursor_t *ptvc)
  694. {
  695. return ptvc->offset;
  696. }
  697. proto_tree *
  698. ptvcursor_tree(ptvcursor_t *ptvc)
  699. {
  700. if (!ptvc)
  701. return NULL;
  702. return ptvc->tree;
  703. }
  704. void
  705. ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
  706. {
  707. ptvc->tree = tree;
  708. }
  709. /* creates a subtree, sets it as the working tree and pushes the old working tree */
  710. proto_tree *
  711. ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
  712. {
  713. subtree_lvl *subtree;
  714. if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
  715. ptvcursor_new_subtree_levels(ptvc);
  716. subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
  717. subtree->tree = ptvc->tree;
  718. subtree->it= NULL;
  719. ptvc->pushed_tree_index++;
  720. return ptvcursor_set_subtree(ptvc, it, ett_subtree);
  721. }
  722. /* pops a subtree */
  723. void
  724. ptvcursor_pop_subtree(ptvcursor_t *ptvc)
  725. {
  726. subtree_lvl *subtree;
  727. if (ptvc->pushed_tree_index <= 0)
  728. return;
  729. ptvc->pushed_tree_index--;
  730. subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
  731. if (subtree->it != NULL)
  732. proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
  733. ptvc->tree = subtree->tree;
  734. }
  735. /* saves the current tvb offset and the item in the current subtree level */
  736. static void
  737. ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
  738. {
  739. subtree_lvl *subtree;
  740. DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
  741. subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
  742. subtree->it = it;
  743. subtree->cursor_offset = ptvcursor_current_offset(ptvc);
  744. }
  745. /* Creates a subtree and adds it to the cursor as the working tree but does not
  746. * save the old working tree */
  747. proto_tree *
  748. ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
  749. {
  750. ptvc->tree = proto_item_add_subtree(it, ett_subtree);
  751. return ptvc->tree;
  752. }
  753. static proto_tree *
  754. ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
  755. {
  756. ptvcursor_push_subtree(ptvc, it, ett_subtree);
  757. if (length == SUBTREE_UNDEFINED_LENGTH)
  758. ptvcursor_subtree_set_item(ptvc, it);
  759. return ptvcursor_tree(ptvc);
  760. }
  761. /* Add an item to the tree and create a subtree
  762. * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
  763. * In this case, when the subtree will be closed, the parent item length will
  764. * be equal to the advancement of the cursor since the creation of the subtree.
  765. */
  766. proto_tree *
  767. ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
  768. const guint encoding, gint ett_subtree)
  769. {
  770. proto_item *it;
  771. it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
  772. return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
  773. }
  774. static proto_item *
  775. proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
  776. /* Add a text node to the tree and create a subtree
  777. * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
  778. * In this case, when the subtree will be closed, the item length will be equal
  779. * to the advancement of the cursor since the creation of the subtree.
  780. */
  781. proto_tree *
  782. ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
  783. gint ett_subtree, const char *format, ...)
  784. {
  785. proto_item *pi;
  786. va_list ap;
  787. header_field_info *hfinfo;
  788. proto_tree *tree;
  789. tree = ptvcursor_tree(ptvc);
  790. TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
  791. pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
  792. ptvcursor_current_offset(ptvc), length);
  793. TRY_TO_FAKE_THIS_REPR(pi);
  794. va_start(ap, format);
  795. proto_tree_set_representation(pi, format, ap);
  796. va_end(ap);
  797. return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
  798. }
  799. /* Add a text-only node, leaving it to our caller to fill the text in */
  800. static proto_item *
  801. proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
  802. {
  803. proto_item *pi;
  804. field_info *new_fi;
  805. if (tree == NULL)
  806. return NULL;
  807. pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length, &new_fi);
  808. return pi;
  809. }
  810. /* Add a text-only node to the proto_tree */
  811. proto_item *
  812. proto_tree_add_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
  813. const char *format, ...)
  814. {
  815. proto_item *pi;
  816. va_list ap;
  817. header_field_info *hfinfo;
  818. TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
  819. pi = proto_tree_add_text_node(tree, tvb, start, length);
  820. TRY_TO_FAKE_THIS_REPR(pi);
  821. va_start(ap, format);
  822. proto_tree_set_representation(pi, format, ap);
  823. va_end(ap);
  824. return pi;
  825. }
  826. /* Add a text-only node to the proto_tree (va_list version) */
  827. proto_item *
  828. proto_tree_add_text_valist(proto_tree *tree, tvbuff_t *tvb, gint start,
  829. gint length, const char *format, va_list ap)
  830. {
  831. proto_item *pi;
  832. header_field_info *hfinfo;
  833. TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
  834. pi = proto_tree_add_text_node(tree, tvb, start, length);
  835. TRY_TO_FAKE_THIS_REPR(pi);
  836. proto_tree_set_representation(pi, format, ap);
  837. return pi;
  838. }
  839. /* Add a text-only node for debugging purposes. The caller doesn't need
  840. * to worry about tvbuff, start, or length. Debug message gets sent to
  841. * STDOUT, too */
  842. proto_item *
  843. proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
  844. {
  845. proto_item *pi;
  846. va_list ap;
  847. pi = proto_tree_add_text_node(tree, NULL, 0, 0);
  848. if (pi) {
  849. va_start(ap, format);
  850. proto_tree_set_representation(pi, format, ap);
  851. va_end(ap);
  852. }
  853. va_start(ap, format);
  854. vprintf(format, ap);
  855. va_end(ap);
  856. printf("\n");
  857. return pi;
  858. }
  859. /* We could probably get away with changing is_error to a minimum length value. */
  860. static void
  861. report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
  862. if (tree) {
  863. tree_data_t *tree_data = PTREE_DATA(tree);
  864. field_info *fi_save = tree_data->fi_tmp;
  865. /* Keep the current item from getting freed by proto_tree_new_item. */
  866. tree_data->fi_tmp = NULL;
  867. expert_add_info_format(NULL, tree, PI_MALFORMED, is_error ? PI_ERROR : PI_WARN, "Trying to fetch %s with length %d", descr, length);
  868. tree_data->fi_tmp = fi_save;
  869. }
  870. if (is_error) {
  871. THROW(ReportedBoundsError);
  872. }
  873. }
  874. static guint32
  875. get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
  876. {
  877. guint32 value;
  878. gboolean length_error;
  879. switch (length) {
  880. case 1:
  881. value = tvb_get_guint8(tvb, offset);
  882. break;
  883. case 2:
  884. value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
  885. : tvb_get_ntohs(tvb, offset);
  886. break;
  887. case 3:
  888. value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
  889. : tvb_get_ntoh24(tvb, offset);
  890. break;
  891. case 4:
  892. value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
  893. : tvb_get_ntohl(tvb, offset);
  894. break;
  895. default:
  896. if (length < 1) {
  897. length_error = TRUE;
  898. value = 0;
  899. } else {
  900. length_error = FALSE;
  901. value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
  902. : tvb_get_ntohl(tvb, offset);
  903. }
  904. report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
  905. break;
  906. }
  907. return value;
  908. }
  909. /*
  910. * NOTE: to support code written when proto_tree_add_item() took a
  911. * gboolean as its last argument, with FALSE meaning "big-endian"
  912. * and TRUE meaning "little-endian", we treat any non-zero value of
  913. * "encoding" as meaning "little-endian".
  914. */
  915. static gint32
  916. get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
  917. {
  918. gint32 value;
  919. gboolean length_error;
  920. switch (length) {
  921. case 1:
  922. value = (gint8)tvb_get_guint8(tvb, offset);
  923. break;
  924. case 2:
  925. value = (gint16) (encoding ? tvb_get_letohs(tvb, offset)
  926. : tvb_get_ntohs(tvb, offset));
  927. break;
  928. case 3:
  929. value = encoding ? tvb_get_letoh24(tvb, offset)
  930. : tvb_get_ntoh24(tvb, offset);
  931. if (value & 0x00800000) {
  932. /* Sign bit is set; sign-extend it. */
  933. value |= 0xFF000000;
  934. }
  935. break;
  936. case 4:
  937. value = encoding ? tvb_get_letohl(tvb, offset)
  938. : tvb_get_ntohl(tvb, offset);
  939. break;
  940. default:
  941. if (length < 1) {
  942. length_error = TRUE;
  943. value = 0;
  944. } else {
  945. length_error = FALSE;
  946. value = encoding ? tvb_get_letohl(tvb, offset)
  947. : tvb_get_ntohl(tvb, offset);
  948. }
  949. report_type_length_mismatch(tree, "a signed integer", length, length_error);
  950. break;
  951. }
  952. return value;
  953. }
  954. static void
  955. tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
  956. {
  957. const header_field_info *hfinfo = fi->hfinfo;
  958. if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
  959. GPtrArray *ptrs = NULL;
  960. if (tree_data->interesting_hfids == NULL) {
  961. /* Initialize the hash because we now know that it is needed */
  962. tree_data->interesting_hfids =
  963. g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
  964. } else
  965. ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
  966. GINT_TO_POINTER(hfinfo->id));
  967. if (!ptrs) {
  968. /* First element triggers the creation of pointer array */
  969. ptrs = g_ptr_array_new();
  970. g_hash_table_insert(tree_data->interesting_hfids,
  971. GINT_TO_POINTER(hfinfo->id), ptrs);
  972. }
  973. g_ptr_array_add(ptrs, fi);
  974. }
  975. }
  976. /* Add an item to a proto_tree, using the text label registered to that item;
  977. the item is extracted from the tvbuff handed to it. */
  978. static proto_item *
  979. proto_tree_new_item(field_info *new_fi, proto_tree *tree,
  980. tvbuff_t *tvb, gint start, gint length,
  981. guint encoding)
  982. {
  983. tree_data_t *tree_data = PTREE_DATA(tree);
  984. proto_item *pi;
  985. guint32 value, n;
  986. float floatval;
  987. double doubleval;
  988. const char *string;
  989. nstime_t time_stamp;
  990. guint32 tmpsecs;
  991. gboolean length_error;
  992. /* there is a possibility here that we might raise an exception
  993. * and thus would lose track of the field_info.
  994. * store it in a temp so that if we come here again we can reclaim
  995. * the field_info without leaking memory.
  996. */
  997. if (tree_data->fi_tmp) {
  998. /* oops, last one we got must have been lost due
  999. * to an exception.
  1000. * good thing we saved it, now we can reverse the
  1001. * memory leak and reclaim it.
  1002. */
  1003. FIELD_INFO_FREE(tree_data->fi_tmp);
  1004. }
  1005. /* we might throw an exception, keep track of this one
  1006. * across the "dangerous" section below.
  1007. */
  1008. tree_data->fi_tmp = new_fi;
  1009. switch (new_fi->hfinfo->type) {
  1010. case FT_NONE:
  1011. /* no value to set for FT_NONE */
  1012. break;
  1013. case FT_PROTOCOL:
  1014. proto_tree_set_protocol_tvb(new_fi, tvb);
  1015. break;
  1016. case FT_BYTES:
  1017. proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
  1018. break;
  1019. case FT_UINT_BYTES:
  1020. /*
  1021. * Map all non-zero values to little-endian for
  1022. * backwards compatibility.
  1023. */
  1024. if (encoding)
  1025. encoding = ENC_LITTLE_ENDIAN;
  1026. n = get_uint_value(tree, tvb, start, length, encoding);
  1027. proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
  1028. /* Instead of calling proto_item_set_len(), since we don't yet
  1029. * have a proto_item, we set the field_info's length ourselves. */
  1030. new_fi->length = n + length;
  1031. break;
  1032. case FT_BOOLEAN:
  1033. /*
  1034. * Map all non-zero values to little-endian for
  1035. * backwards compatibility.
  1036. */
  1037. if (encoding)
  1038. encoding = ENC_LITTLE_ENDIAN;
  1039. proto_tree_set_boolean(new_fi,
  1040. get_uint_value(tree, tvb, start, length, encoding));
  1041. break;
  1042. /* XXX - make these just FT_UINT? */
  1043. case FT_UINT8:
  1044. case FT_UINT16:
  1045. case FT_UINT24:
  1046. case FT_UINT32:
  1047. /*
  1048. * Map all non-zero values to little-endian for
  1049. * backwards compatibility.
  1050. */
  1051. if (encoding)
  1052. encoding = ENC_LITTLE_ENDIAN;
  1053. proto_tree_set_uint(new_fi,
  1054. get_uint_value(tree, tvb, start, length, encoding));
  1055. break;
  1056. case FT_INT64:
  1057. case FT_UINT64:
  1058. /*
  1059. * Map all non-zero values to little-endian for
  1060. * backwards compatibility.
  1061. */
  1062. if (encoding)
  1063. encoding = ENC_LITTLE_ENDIAN;
  1064. if (length < 1 || length > 8) {
  1065. length_error = length < 1 ? TRUE : FALSE;
  1066. report_type_length_mismatch(tree, "a 64-bit integer", length, length_error);
  1067. }
  1068. proto_tree_set_uint64_tvb(new_fi, tvb, start, length, encoding);
  1069. break;
  1070. /* XXX - make these just FT_INT? */
  1071. case FT_INT8:
  1072. case FT_INT16:
  1073. case FT_INT24:
  1074. case FT_INT32:
  1075. /*
  1076. * Map all non-zero values to little-endian for
  1077. * backwards compatibility.
  1078. */
  1079. if (encoding)
  1080. encoding = ENC_LITTLE_ENDIAN;
  1081. proto_tree_set_int(new_fi,
  1082. get_int_value(tree, tvb, start, length, encoding));
  1083. break;
  1084. case FT_IPv4:
  1085. /*
  1086. * Map all non-zero values to little-endian for
  1087. * backwards compatibility.
  1088. */
  1089. if (encoding)
  1090. encoding = ENC_LITTLE_ENDIAN;
  1091. if (length != FT_IPv4_LEN) {
  1092. length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
  1093. report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
  1094. }
  1095. value = tvb_get_ipv4(tvb, start);
  1096. /*
  1097. * NOTE: to support code written when
  1098. * proto_tree_add_item() took a gboolean as its
  1099. * last argument, with FALSE meaning "big-endian"
  1100. * and TRUE meaning "little-endian", we treat any
  1101. * non-zero value of "encoding" as meaning
  1102. * "little-endian".
  1103. */
  1104. proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
  1105. break;
  1106. case FT_IPXNET:
  1107. if (length != FT_IPXNET_LEN) {
  1108. length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
  1109. report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
  1110. }
  1111. proto_tree_set_ipxnet(new_fi,
  1112. get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
  1113. break;
  1114. case FT_IPv6:
  1115. if (length != FT_IPv6_LEN) {
  1116. length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
  1117. report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
  1118. }
  1119. proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
  1120. break;
  1121. case FT_AX25:
  1122. if (length != 7) {
  1123. length_error = length < 7 ? TRUE : FALSE;
  1124. report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
  1125. }
  1126. proto_tree_set_ax25_tvb(new_fi, tvb, start);
  1127. break;
  1128. case FT_VINES:
  1129. if (length != VINES_ADDR_LEN) {
  1130. length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
  1131. report_type_length_mismatch(tree, "a Vines address", length, length_error);
  1132. }
  1133. proto_tree_set_vines_tvb(new_fi, tvb, start);
  1134. break;
  1135. case FT_ETHER:
  1136. if (length != FT_ETHER_LEN) {
  1137. length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
  1138. report_type_length_mismatch(tree, "an Ethernet", length, length_error);
  1139. }
  1140. proto_tree_set_ether_tvb(new_fi, tvb, start);
  1141. break;
  1142. case FT_EUI64:
  1143. /*
  1144. * Map all non-zero values to little-endian for
  1145. * backwards compatibility.
  1146. */
  1147. if (encoding)
  1148. encoding = ENC_LITTLE_ENDIAN;
  1149. if (length != FT_EUI64_LEN) {
  1150. length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
  1151. report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
  1152. }
  1153. proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
  1154. break;
  1155. case FT_GUID:
  1156. /*
  1157. * Map all non-zero values to little-endian for
  1158. * backwards compatibility.
  1159. */
  1160. if (encoding)
  1161. encoding = ENC_LITTLE_ENDIAN;
  1162. if (length != FT_GUID_LEN) {
  1163. length_error = length < FT_GUID_LEN ? TRUE : FALSE;
  1164. report_type_length_mismatch(tree, "a GUID", length, length_error);
  1165. }
  1166. proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
  1167. break;
  1168. case FT_OID:
  1169. proto_tree_set_oid_tvb(new_fi, tvb, start, length);
  1170. break;
  1171. case FT_FLOAT:
  1172. /*
  1173. * NOTE: to support code written when
  1174. * proto_tree_add_item() took a gboolean as its
  1175. * last argument, with FALSE meaning "big-endian"
  1176. * and TRUE meaning "little-endian", we treat any
  1177. * non-zero value of "encoding" as meaning
  1178. * "little-endian".
  1179. *
  1180. * At some point in the future, we might
  1181. * support non-IEEE-binary floating-point
  1182. * formats in the encoding as well
  1183. * (IEEE decimal, System/3x0, VAX).
  1184. */
  1185. if (encoding)
  1186. encoding = ENC_LITTLE_ENDIAN;
  1187. if (length != 4) {
  1188. length_error = length < 4 ? TRUE : FALSE;
  1189. report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
  1190. }
  1191. if (encoding)
  1192. floatval = tvb_get_letohieee_float(tvb, start);
  1193. else
  1194. floatval = tvb_get_ntohieee_float(tvb, start);
  1195. proto_tree_set_float(new_fi, floatval);
  1196. break;
  1197. case FT_DOUBLE:
  1198. /*
  1199. * NOTE: to support code written when
  1200. * proto_tree_add_item() took a gboolean as its
  1201. * last argument, with FALSE meaning "big-endian"
  1202. * and TRUE meaning "little-endian", we treat any
  1203. * non-zero value of "encoding" as meaning
  1204. * "little-endian".
  1205. *
  1206. * At some point in the future, we might
  1207. * support non-IEEE-binary floating-point
  1208. * formats in the encoding as well
  1209. * (IEEE decimal, System/3x0, VAX).
  1210. */
  1211. if (encoding == TRUE)
  1212. encoding = ENC_LITTLE_ENDIAN;
  1213. if (length != 8) {
  1214. length_error = length < 8 ? TRUE : FALSE;
  1215. report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
  1216. }
  1217. if (encoding)
  1218. doubleval = tvb_get_letohieee_double(tvb, start);
  1219. else
  1220. doubleval = tvb_get_ntohieee_double(tvb, start);
  1221. proto_tree_set_double(new_fi, doubleval);
  1222. break;
  1223. case FT_STRING:
  1224. proto_tree_set_string_tvb(new_fi, tvb, start, length,
  1225. encoding);
  1226. break;
  1227. case FT_STRINGZ:
  1228. if (length < -1 ) {
  1229. report_type_length_mismatch(tree, "a string", length, TRUE);
  1230. }
  1231. /* Instead of calling proto_item_set_len(),
  1232. * since we don't yet have a proto_item, we
  1233. * set the field_info's length ourselves.
  1234. *
  1235. * XXX - our caller can't use that length to
  1236. * advance an offset unless they arrange that
  1237. * there always be a protocol tree into which
  1238. * we're putting this item.
  1239. */
  1240. if (length == -1) {
  1241. /* This can throw an exception */
  1242. string = tvb_get_stringz_enc(tvb, start, &length, encoding);
  1243. } else if (length == 0) {
  1244. string = "[Empty]";
  1245. } else {
  1246. /* In this case, length signifies
  1247. * the length of the string.
  1248. *
  1249. * This could either be a null-padded
  1250. * string, which doesn't necessarily
  1251. * have a '\0' at the end, or a
  1252. * null-terminated string, with a
  1253. * trailing '\0'. (Yes, there are
  1254. * cases where you have a string
  1255. * that's both counted and null-
  1256. * terminated.)
  1257. *
  1258. * In the first case, we must
  1259. * allocate a buffer of length
  1260. * "length+1", to make room for
  1261. * a trailing '\0'.
  1262. *
  1263. * In the second case, we don't
  1264. * assume that there is a trailing
  1265. * '\0' there, as the packet might
  1266. * be malformed. (XXX - should we
  1267. * throw an exception if there's no
  1268. * trailing '\0'?) Therefore, we
  1269. * allocate a buffer of length
  1270. * "length+1", and put in a trailing
  1271. * '\0', just to be safe.
  1272. *
  1273. * (XXX - this would change if
  1274. * we made string values counted
  1275. * rather than null-terminated.)
  1276. */
  1277. string = tvb_get_ephemeral_string_enc(tvb, start, length, encoding);
  1278. }
  1279. new_fi->length = length;
  1280. proto_tree_set_string(new_fi, string);
  1281. break;
  1282. case FT_UINT_STRING:
  1283. /*
  1284. * NOTE: to support code written when
  1285. * proto_tree_add_item() took a gboolean as its
  1286. * last argument, with FALSE meaning "big-endian"
  1287. * and TRUE meaning "little-endian", if the
  1288. * encoding value is TRUE, treat that as
  1289. * ASCII with a little-endian length.
  1290. *
  1291. * This won't work for code that passes
  1292. * arbitrary non-zero values; that code
  1293. * will need to be fixed.
  1294. */
  1295. if (encoding == TRUE)
  1296. encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
  1297. n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
  1298. proto_tree_set_string_tvb(new_fi, tvb, start + length, n,
  1299. encoding);
  1300. /* Instead of calling proto_item_set_len(), since we
  1301. * don't yet have a proto_item, we set the
  1302. * field_info's length ourselves.
  1303. *
  1304. * XXX - our caller can't use that length to
  1305. * advance an offset unless they arrange that
  1306. * there always be a protocol tree into which
  1307. * we're putting this item.
  1308. */
  1309. new_fi->length = n + length;
  1310. break;
  1311. case FT_ABSOLUTE_TIME:
  1312. /*
  1313. * Absolute times can be in any of a number of
  1314. * formats, and they can be big-endian or
  1315. * little-endian.
  1316. *
  1317. * Historically FT_TIMEs were only timespecs;
  1318. * the only question was whether they were stored
  1319. * in big- or little-endian format.
  1320. *
  1321. * For backwards compatibility, we interpret an
  1322. * encoding of 1 as meaning "little-endian timespec",
  1323. * so that passing TRUE is interpreted as that.
  1324. */
  1325. if (encoding == TRUE)
  1326. encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
  1327. if (length != 8 && length != 4) {
  1328. length_error = length < 4 ? TRUE : FALSE;
  1329. report_type_length_mismatch(tree, "an absolute time value", length, length_error);
  1330. }
  1331. switch (encoding) {
  1332. case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
  1333. /*
  1334. * 4-byte UNIX epoch, possibly followed by
  1335. * 4-byte fractional time in nanoseconds,
  1336. * both big-endian.
  1337. */
  1338. time_stamp.secs = tvb_get_ntohl(tvb, start);
  1339. if (length == 8)
  1340. time_stamp.nsecs = tvb_get_ntohl(tvb, start+4);
  1341. else
  1342. time_stamp.nsecs = 0;
  1343. break;
  1344. case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
  1345. /*
  1346. * 4-byte UNIX epoch, possibly followed by
  1347. * 4-byte fractional time in nanoseconds,
  1348. * both little-endian.
  1349. */
  1350. time_stamp.secs = tvb_get_letohl(tvb, start);
  1351. if (length == 8)
  1352. time_stamp.nsecs = tvb_get_letohl(tvb, start+4);
  1353. else
  1354. time_stamp.nsecs = 0;
  1355. break;
  1356. case ENC_TIME_NTP|ENC_BIG_ENDIAN:
  1357. /*
  1358. * NTP time stamp, big-endian.
  1359. */
  1360. /* XXX - where should this go? */
  1361. #define NTP_BASETIME 2208988800ul
  1362. /* We need a temporary variable here so the unsigned math
  1363. * works correctly (for years > 2036 according to RFC 2030
  1364. * chapter 3).
  1365. */
  1366. tmpsecs = tvb_get_ntohl(tvb, start);
  1367. if (tmpsecs)
  1368. time_stamp.secs = tmpsecs - (guint32)NTP_BASETIME;
  1369. else
  1370. time_stamp.secs = tmpsecs; /* 0 */
  1371. if (length == 8) {
  1372. /*
  1373. * We're using nanoseconds here (and we will
  1374. * display nanoseconds), but NTP's timestamps
  1375. * have a precision in microseconds or greater.
  1376. * Round to 1 microsecond.
  1377. */
  1378. time_stamp.nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
  1379. time_stamp.nsecs *= 1000;
  1380. } else {
  1381. time_stamp.nsecs = 0;
  1382. }
  1383. break;
  1384. case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
  1385. /*
  1386. * NTP time stamp, big-endian.
  1387. */
  1388. tmpsecs = tvb_get_letohl(tvb, start);
  1389. if (tmpsecs)
  1390. time_stamp.secs = tmpsecs - (guint32)NTP_BASETIME;
  1391. else
  1392. time_stamp.secs = tmpsecs; /* 0 */
  1393. if (length == 8) {
  1394. /*
  1395. * We're using nanoseconds here (and we will
  1396. * display nanoseconds), but NTP's timestamps
  1397. * have a precision in microseconds or greater.
  1398. * Round to 1 microsecond.
  1399. */
  1400. time_stamp.nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
  1401. time_stamp.nsecs *= 1000;
  1402. } else {
  1403. time_stamp.nsecs = 0;
  1404. }
  1405. break;
  1406. default:
  1407. DISSECTOR_ASSERT_NOT_REACHED();
  1408. time_stamp.secs = 0;
  1409. time_stamp.nsecs = 0;
  1410. break;
  1411. }
  1412. proto_tree_set_time(new_fi, &time_stamp);
  1413. break;
  1414. case FT_RELATIVE_TIME:
  1415. /*
  1416. * Relative times can be in any of a number of
  1417. * formats, and they can be big-endian or
  1418. * little-endian.
  1419. *
  1420. * Historically FT_TIMEs were only timespecs;
  1421. * the only question was whether they were stored
  1422. * in big- or little-endian format.
  1423. *
  1424. * For backwards compatibility, we interpret an
  1425. * encoding of 1 as meaning "little-endian timespec",
  1426. * so that passing TRUE is interpreted as that.
  1427. */
  1428. if (encoding == TRUE)
  1429. encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
  1430. switch (encoding) {
  1431. if (length != 8 && length != 4) {
  1432. length_error = length < 4 ? TRUE : FALSE;
  1433. report_type_length_mismatch(tree, "a relative time value", length, length_error);
  1434. }
  1435. case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
  1436. /*
  1437. * 4-byte UNIX epoch, possibly followed by
  1438. * 4-byte fractional time in nanoseconds,
  1439. * both big-endian.
  1440. */
  1441. time_stamp.secs = tvb_get_ntohl(tvb, start);
  1442. if (length == 8)
  1443. time_stamp.nsecs = tvb_get_ntohl(tvb, start+4);
  1444. else
  1445. time_stamp.nsecs = 0;
  1446. break;
  1447. case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
  1448. /*
  1449. * 4-byte UNIX epoch, possibly followed by
  1450. * 4-byte fractional time in nanoseconds,
  1451. * both little-endian.
  1452. */
  1453. time_stamp.secs = tvb_get_letohl(tvb, start);
  1454. if (length == 8)
  1455. time_stamp.nsecs = tvb_get_letohl(tvb, start+4);
  1456. else
  1457. time_stamp.nsecs = 0;
  1458. break;
  1459. }
  1460. proto_tree_set_time(new_fi, &time_stamp);
  1461. break;
  1462. default:
  1463. g_error("new_fi->hfinfo->type %d (%s) not handled\n",
  1464. new_fi->hfinfo->type,
  1465. ftype_name(new_fi->hfinfo->type));
  1466. DISSECTOR_ASSERT_NOT_REACHED();
  1467. break;
  1468. }
  1469. FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
  1470. /* Don't add new node to proto_tree until now so that any exceptions
  1471. * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
  1472. /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
  1473. * to know which item caused exception? */
  1474. pi = proto_tree_add_node(tree, new_fi);
  1475. /* we did not raise an exception so we dont have to remember this
  1476. * field_info struct any more.
  1477. */
  1478. tree_data->fi_tmp = NULL;
  1479. return pi;
  1480. }
  1481. /* Gets data from tvbuff, adds it to proto_tree, increments offset,
  1482. and returns proto_item* */
  1483. proto_item *
  1484. ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
  1485. const guint encoding)
  1486. {
  1487. field_info *new_fi;
  1488. header_field_info *hfinfo;
  1489. gint item_length;
  1490. guint32 n;
  1491. int offset;
  1492. /* We can't fake it just yet. We have to advance the cursor
  1493. TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo); */
  1494. offset = ptvc->offset;
  1495. PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
  1496. get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
  1497. ptvc->offset += length;
  1498. if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
  1499. /*
  1500. * The length of the rest of the item is in the first N
  1501. * bytes of the item.
  1502. */
  1503. n = get_uint_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
  1504. ptvc->offset += n;
  1505. }
  1506. /* Coast clear. Try and fake it */
  1507. TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
  1508. new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
  1509. return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
  1510. offset, length, encoding);
  1511. }
  1512. /*
  1513. * Validates that field length bytes are available starting from
  1514. * start (pos/neg). Throws an exception if they aren't.
  1515. */
  1516. static void
  1517. test_length(header_field_info *hfinfo, proto_tree *tree, tvbuff_t *tvb,
  1518. gint start, gint length, const guint encoding)
  1519. {
  1520. gint size = length;
  1521. if (!tvb)
  1522. return;
  1523. if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
  1524. guint32 n;
  1525. n = get_uint_value(tree, tvb, start, length, encoding);
  1526. if (n > size + n) {
  1527. /* If n > size + n then we have an integer overflow, so
  1528. * set size to -1, which will force the
  1529. * tvb_ensure_bytes_exist call below to throw a
  1530. * ReportedBoundsError
  1531. */
  1532. size = -1;
  1533. }
  1534. else {
  1535. size += n;
  1536. }
  1537. } else if (hfinfo->type == FT_STRINGZ) {
  1538. /* If we're fetching until the end of the TVB, only validate
  1539. * that the offset is within range.
  1540. */
  1541. if (length == -1)
  1542. size = 0;
  1543. }
  1544. tvb_ensure_bytes_exist(tvb, start, size);
  1545. }
  1546. /* Add an item to a proto_tree, using the text label registered to that item;
  1547. the item is extracted from the tvbuff handed to it. */
  1548. proto_item *
  1549. proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
  1550. const gint start, gint length, const guint encoding)
  1551. {
  1552. field_info *new_fi;
  1553. gint item_length;
  1554. DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
  1555. get_hfi_length(hfinfo, tvb, start, &length, &item_length);
  1556. test_length(hfinfo, tree, tvb, start, item_length, encoding);
  1557. TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
  1558. new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
  1559. if (new_fi == NULL)
  1560. return NULL;
  1561. return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
  1562. }
  1563. proto_item *
  1564. proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  1565. const gint start, gint length, const guint encoding)
  1566. {
  1567. return proto_tree_add_item_new(tree, proto_registrar_get_nth(hfindex), tvb, start, length, encoding);
  1568. }
  1569. /* Add a FT_NONE to a proto_tree */
  1570. proto_item *
  1571. proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
  1572. const gint start, gint length, const char *format,
  1573. ...)
  1574. {
  1575. proto_item *pi;
  1576. va_list ap;
  1577. header_field_info *hfinfo;
  1578. field_info *new_fi;
  1579. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  1580. DISSECTOR_ASSERT(hfinfo->type == FT_NONE);
  1581. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  1582. TRY_TO_FAKE_THIS_REPR(pi);
  1583. va_start(ap, format);
  1584. proto_tree_set_representation(pi, format, ap);
  1585. va_end(ap);
  1586. /* no value to set for FT_NONE */
  1587. return pi;
  1588. }
  1589. /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
  1590. * offset, and returns proto_item* */
  1591. proto_item *
  1592. ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
  1593. const guint encoding)
  1594. {
  1595. proto_item *item;
  1596. item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
  1597. length, encoding);
  1598. return item;
  1599. }
  1600. /* Advance the ptvcursor's offset within its tvbuff without
  1601. * adding anything to the proto_tree. */
  1602. void
  1603. ptvcursor_advance(ptvcursor_t* ptvc, gint length)
  1604. {
  1605. ptvc->offset += length;
  1606. }
  1607. static void
  1608. proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb)
  1609. {
  1610. fvalue_set(&fi->value, tvb, TRUE);
  1611. }
  1612. /* Add a FT_PROTOCOL to a proto_tree */
  1613. proto_item *
  1614. proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  1615. gint start, gint length, const char *format, ...)
  1616. {
  1617. proto_item *pi;
  1618. va_list ap;
  1619. field_info *new_fi;
  1620. header_field_info *hfinfo;
  1621. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  1622. DISSECTOR_ASSERT(hfinfo->type == FT_PROTOCOL);
  1623. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  1624. proto_tree_set_protocol_tvb(new_fi, (start == 0 ? tvb : tvb_new_subset(tvb, start, length, length)));
  1625. TRY_TO_FAKE_THIS_REPR(pi);
  1626. va_start(ap, format);
  1627. proto_tree_set_representation(pi, format, ap);
  1628. va_end(ap);
  1629. return pi;
  1630. }
  1631. /* Add a FT_BYTES to a proto_tree */
  1632. proto_item *
  1633. proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  1634. gint length, const guint8 *start_ptr)
  1635. {
  1636. proto_item *pi;
  1637. field_info *new_fi;
  1638. header_field_info *hfinfo;
  1639. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  1640. DISSECTOR_ASSERT(hfinfo->type == FT_BYTES);
  1641. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  1642. proto_tree_set_bytes(new_fi, start_ptr, length);
  1643. return pi;
  1644. }
  1645. proto_item *
  1646. proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  1647. gint start, gint length,
  1648. const guint8 *start_ptr,
  1649. const char *format, ...)
  1650. {
  1651. proto_item *pi;
  1652. va_list ap;
  1653. header_field_info *hfinfo;
  1654. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  1655. if (start_ptr)
  1656. pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
  1657. start_ptr);
  1658. else
  1659. pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
  1660. tvb_get_ptr(tvb, start, length));
  1661. va_start(ap, format);
  1662. proto_tree_set_representation_value(pi, format, ap);
  1663. va_end(ap);
  1664. return pi;
  1665. }
  1666. proto_item *
  1667. proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  1668. gint start, gint length, const guint8 *start_ptr,
  1669. const char *format, ...)
  1670. {
  1671. proto_item *pi;
  1672. va_list ap;
  1673. header_field_info *hfinfo;
  1674. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  1675. if (start_ptr)
  1676. pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
  1677. start_ptr);
  1678. else
  1679. pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
  1680. tvb_get_ptr(tvb, start, length));
  1681. TRY_TO_FAKE_THIS_REPR(pi);
  1682. va_start(ap, format);
  1683. proto_tree_set_representation(pi, format, ap);
  1684. va_end(ap);
  1685. return pi;
  1686. }
  1687. static void
  1688. proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
  1689. {
  1690. GByteArray *bytes;
  1691. bytes = g_byte_array_new();
  1692. if (length > 0) {
  1693. g_byte_array_append(bytes, start_ptr, length);
  1694. }
  1695. fvalue_set(&fi->value, bytes, TRUE);
  1696. }
  1697. static void
  1698. proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
  1699. {
  1700. proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
  1701. }
  1702. /* Add a FT_*TIME to a proto_tree */
  1703. proto_item *
  1704. proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  1705. gint length, nstime_t *value_ptr)
  1706. {
  1707. proto_item *pi;
  1708. field_info *new_fi;
  1709. header_field_info *hfinfo;
  1710. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  1711. DISSECTOR_ASSERT(hfinfo->type == FT_ABSOLUTE_TIME ||
  1712. hfinfo->type == FT_RELATIVE_TIME);
  1713. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  1714. proto_tree_set_time(new_fi, value_ptr);
  1715. return pi;
  1716. }
  1717. proto_item *
  1718. proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  1719. gint start, gint length, nstime_t *value_ptr,
  1720. const char *format, ...)
  1721. {
  1722. proto_item *pi;
  1723. va_list ap;
  1724. pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
  1725. if (pi != tree) {
  1726. va_start(ap, format);
  1727. proto_tree_set_representation_value(pi, format, ap);
  1728. va_end(ap);
  1729. }
  1730. return pi;
  1731. }
  1732. proto_item *
  1733. proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  1734. gint start, gint length, nstime_t *value_ptr,
  1735. const char *format, ...)
  1736. {
  1737. proto_item *pi;
  1738. va_list ap;
  1739. pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
  1740. if (pi != tree) {
  1741. TRY_TO_FAKE_THIS_REPR(pi);
  1742. va_start(ap, format);
  1743. proto_tree_set_representation(pi, format, ap);
  1744. va_end(ap);
  1745. }
  1746. return pi;
  1747. }
  1748. /* Set the FT_*TIME value */
  1749. static void
  1750. proto_tree_set_time(field_info *fi, nstime_t *value_ptr)
  1751. {
  1752. DISSECTOR_ASSERT(value_ptr != NULL);
  1753. fvalue_set(&fi->value, value_ptr, FALSE);
  1754. }
  1755. /* Add a FT_IPXNET to a proto_tree */
  1756. proto_item *
  1757. proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  1758. gint length, guint32 value)
  1759. {
  1760. proto_item *pi;
  1761. field_info *new_fi;
  1762. header_field_info *hfinfo;
  1763. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  1764. DISSECTOR_ASSERT(hfinfo->type == FT_IPXNET);
  1765. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  1766. proto_tree_set_ipxnet(new_fi, value);
  1767. return pi;
  1768. }
  1769. proto_item *
  1770. proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  1771. gint start, gint length, guint32 value,
  1772. const char *format, ...)
  1773. {
  1774. proto_item *pi;
  1775. va_list ap;
  1776. pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
  1777. if (pi != tree) {
  1778. va_start(ap, format);
  1779. proto_tree_set_representation_value(pi, format, ap);
  1780. va_end(ap);
  1781. }
  1782. return pi;
  1783. }
  1784. proto_item *
  1785. proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  1786. gint start, gint length, guint32 value,
  1787. const char *format, ...)
  1788. {
  1789. proto_item *pi;
  1790. va_list ap;
  1791. pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
  1792. if (pi != tree) {
  1793. TRY_TO_FAKE_THIS_REPR(pi);
  1794. va_start(ap, format);
  1795. proto_tree_set_representation(pi, format, ap);
  1796. va_end(ap);
  1797. }
  1798. return pi;
  1799. }
  1800. /* Set the FT_IPXNET value */
  1801. static void
  1802. proto_tree_set_ipxnet(field_info *fi, guint32 value)
  1803. {
  1804. fvalue_set_uinteger(&fi->value, value);
  1805. }
  1806. /* Add a FT_IPv4 to a proto_tree */
  1807. proto_item *
  1808. proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  1809. gint length, guint32 value)
  1810. {
  1811. proto_item *pi;
  1812. field_info *new_fi;
  1813. header_field_info *hfinfo;
  1814. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  1815. DISSECTOR_ASSERT(hfinfo->type == FT_IPv4);
  1816. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  1817. proto_tree_set_ipv4(new_fi, value);
  1818. return pi;
  1819. }
  1820. proto_item *
  1821. proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  1822. gint start, gint length, guint32 value,
  1823. const char *format, ...)
  1824. {
  1825. proto_item *pi;
  1826. va_list ap;
  1827. pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
  1828. if (pi != tree) {
  1829. va_start(ap, format);
  1830. proto_tree_set_representation_value(pi, format, ap);
  1831. va_end(ap);
  1832. }
  1833. return pi;
  1834. }
  1835. proto_item *
  1836. proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  1837. gint start, gint length, guint32 value,
  1838. const char *format, ...)
  1839. {
  1840. proto_item *pi;
  1841. va_list ap;
  1842. pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
  1843. if (pi != tree) {
  1844. TRY_TO_FAKE_THIS_REPR(pi);
  1845. va_start(ap, format);
  1846. proto_tree_set_representation(pi, format, ap);
  1847. va_end(ap);
  1848. }
  1849. return pi;
  1850. }
  1851. /* Set the FT_IPv4 value */
  1852. static void
  1853. proto_tree_set_ipv4(field_info *fi, guint32 value)
  1854. {
  1855. fvalue_set_uinteger(&fi->value, value);
  1856. }
  1857. /* Add a FT_IPv6 to a proto_tree */
  1858. proto_item *
  1859. proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  1860. gint length, const guint8* value_ptr)
  1861. {
  1862. proto_item *pi;
  1863. field_info *new_fi;
  1864. header_field_info *hfinfo;
  1865. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  1866. DISSECTOR_ASSERT(hfinfo->type == FT_IPv6);
  1867. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  1868. proto_tree_set_ipv6(new_fi, value_ptr);
  1869. return pi;
  1870. }
  1871. proto_item *
  1872. proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  1873. gint start, gint length,
  1874. const guint8* value_ptr,
  1875. const char *format, ...)
  1876. {
  1877. proto_item *pi;
  1878. va_list ap;
  1879. pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
  1880. if (pi != tree) {
  1881. va_start(ap, format);
  1882. proto_tree_set_representation_value(pi, format, ap);
  1883. va_end(ap);
  1884. }
  1885. return pi;
  1886. }
  1887. proto_item *
  1888. proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  1889. gint start, gint length, const guint8* value_ptr,
  1890. const char *format, ...)
  1891. {
  1892. proto_item *pi;
  1893. va_list ap;
  1894. pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
  1895. if (pi != tree) {
  1896. TRY_TO_FAKE_THIS_REPR(pi);
  1897. va_start(ap, format);
  1898. proto_tree_set_representation(pi, format, ap);
  1899. va_end(ap);
  1900. }
  1901. return pi;
  1902. }
  1903. /* Set the FT_IPv6 value */
  1904. static void
  1905. proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
  1906. {
  1907. DISSECTOR_ASSERT(value_ptr != NULL);
  1908. fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
  1909. }
  1910. static void
  1911. proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
  1912. {
  1913. proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
  1914. }
  1915. /* Add a FT_GUID to a proto_tree */
  1916. proto_item *
  1917. proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  1918. gint length, const e_guid_t *value_ptr)
  1919. {
  1920. proto_item *pi;
  1921. field_info *new_fi;
  1922. header_field_info *hfinfo;
  1923. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  1924. DISSECTOR_ASSERT(hfinfo->type == FT_GUID);
  1925. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  1926. proto_tree_set_guid(new_fi, value_ptr);
  1927. return pi;
  1928. }
  1929. proto_item *
  1930. proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  1931. gint start, gint length,
  1932. const e_guid_t *value_ptr,
  1933. const char *format, ...)
  1934. {
  1935. proto_item *pi;
  1936. va_list ap;
  1937. pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
  1938. if (pi != tree) {
  1939. va_start(ap, format);
  1940. proto_tree_set_representation_value(pi, format, ap);
  1941. va_end(ap);
  1942. }
  1943. return pi;
  1944. }
  1945. proto_item *
  1946. proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  1947. gint start, gint length, const e_guid_t *value_ptr,
  1948. const char *format, ...)
  1949. {
  1950. proto_item *pi;
  1951. va_list ap;
  1952. pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
  1953. if (pi != tree) {
  1954. TRY_TO_FAKE_THIS_REPR(pi);
  1955. va_start(ap, format);
  1956. proto_tree_set_representation(pi, format, ap);
  1957. va_end(ap);
  1958. }
  1959. return pi;
  1960. }
  1961. /* Set the FT_GUID value */
  1962. static void
  1963. proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
  1964. {
  1965. DISSECTOR_ASSERT(value_ptr != NULL);
  1966. fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
  1967. }
  1968. static void
  1969. proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
  1970. const guint encoding)
  1971. {
  1972. e_guid_t guid;
  1973. tvb_get_guid(tvb, start, &guid, encoding);
  1974. proto_tree_set_guid(fi, &guid);
  1975. }
  1976. /* Add a FT_OID to a proto_tree */
  1977. proto_item *
  1978. proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  1979. gint length, const guint8* value_ptr)
  1980. {
  1981. proto_item *pi;
  1982. field_info *new_fi;
  1983. header_field_info *hfinfo;
  1984. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  1985. DISSECTOR_ASSERT(hfinfo->type == FT_OID);
  1986. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  1987. proto_tree_set_oid(new_fi, value_ptr, length);
  1988. return pi;
  1989. }
  1990. proto_item *
  1991. proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  1992. gint start, gint length,
  1993. const guint8* value_ptr,
  1994. const char *format, ...)
  1995. {
  1996. proto_item *pi;
  1997. va_list ap;
  1998. pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
  1999. if (pi != tree) {
  2000. va_start(ap, format);
  2001. proto_tree_set_representation_value(pi, format, ap);
  2002. va_end(ap);
  2003. }
  2004. return pi;
  2005. }
  2006. proto_item *
  2007. proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2008. gint start, gint length, const guint8* value_ptr,
  2009. const char *format, ...)
  2010. {
  2011. proto_item *pi;
  2012. va_list ap;
  2013. pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
  2014. if (pi != tree) {
  2015. TRY_TO_FAKE_THIS_REPR(pi);
  2016. va_start(ap, format);
  2017. proto_tree_set_representation(pi, format, ap);
  2018. va_end(ap);
  2019. }
  2020. return pi;
  2021. }
  2022. /* Set the FT_OID value */
  2023. static void
  2024. proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
  2025. {
  2026. GByteArray *bytes;
  2027. DISSECTOR_ASSERT(value_ptr != NULL);
  2028. bytes = g_byte_array_new();
  2029. if (length > 0) {
  2030. g_byte_array_append(bytes, value_ptr, length);
  2031. }
  2032. fvalue_set(&fi->value, bytes, TRUE);
  2033. }
  2034. static void
  2035. proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
  2036. {
  2037. proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
  2038. }
  2039. static void
  2040. proto_tree_set_uint64(field_info *fi, guint64 value)
  2041. {
  2042. fvalue_set_integer64(&fi->value, value);
  2043. }
  2044. /*
  2045. * NOTE: to support code written when proto_tree_add_item() took a
  2046. * gboolean as its last argument, with FALSE meaning "big-endian"
  2047. * and TRUE meaning "little-endian", we treat any non-zero value of
  2048. * "encoding" as meaning "little-endian".
  2049. */
  2050. static void
  2051. proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start,
  2052. guint length, const guint encoding)
  2053. {
  2054. guint64 value = 0;
  2055. guint8* b = (guint8 *)ep_tvb_memdup(tvb, start, length);
  2056. if (encoding) {
  2057. b += length;
  2058. switch (length) {
  2059. default: DISSECTOR_ASSERT_NOT_REACHED();
  2060. case 8: value <<= 8; value += *--b;
  2061. case 7: value <<= 8; value += *--b;
  2062. case 6: value <<= 8; value += *--b;
  2063. case 5: value <<= 8; value += *--b;
  2064. case 4: value <<= 8; value += *--b;
  2065. case 3: value <<= 8; value += *--b;
  2066. case 2: value <<= 8; value += *--b;
  2067. case 1: value <<= 8; value += *--b;
  2068. break;
  2069. }
  2070. } else {
  2071. switch (length) {
  2072. default: DISSECTOR_ASSERT_NOT_REACHED();
  2073. case 8: value <<= 8; value += *b++;
  2074. case 7: value <<= 8; value += *b++;
  2075. case 6: value <<= 8; value += *b++;
  2076. case 5: value <<= 8; value += *b++;
  2077. case 4: value <<= 8; value += *b++;
  2078. case 3: value <<= 8; value += *b++;
  2079. case 2: value <<= 8; value += *b++;
  2080. case 1: value <<= 8; value += *b++;
  2081. break;
  2082. }
  2083. }
  2084. proto_tree_set_uint64(fi, value);
  2085. }
  2086. /* Add a FT_STRING or FT_STRINGZ to a proto_tree. Creates own copy of string,
  2087. * and frees it when the proto_tree is destroyed. */
  2088. proto_item *
  2089. proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  2090. gint length, const char* value)
  2091. {
  2092. proto_item *pi;
  2093. field_info *new_fi;
  2094. header_field_info *hfinfo;
  2095. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  2096. DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
  2097. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  2098. DISSECTOR_ASSERT(length >= 0);
  2099. proto_tree_set_string(new_fi, value);
  2100. return pi;
  2101. }
  2102. proto_item *
  2103. proto_tree_add_unicode_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  2104. gint length, const char* value)
  2105. {
  2106. DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
  2107. return proto_tree_add_string_format_value(tree, hfindex, tvb, start, length, value, "%s", value);
  2108. }
  2109. proto_item *
  2110. proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2111. gint start, gint length, const char* value,
  2112. const char *format,
  2113. ...)
  2114. {
  2115. proto_item *pi;
  2116. va_list ap;
  2117. pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
  2118. if (pi != tree) {
  2119. va_start(ap, format);
  2120. proto_tree_set_representation_value(pi, format, ap);
  2121. va_end(ap);
  2122. }
  2123. return pi;
  2124. }
  2125. proto_item *
  2126. proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2127. gint start, gint length, const char* value,
  2128. const char *format, ...)
  2129. {
  2130. proto_item *pi;
  2131. va_list ap;
  2132. pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
  2133. if (pi != tree) {
  2134. TRY_TO_FAKE_THIS_REPR(pi);
  2135. va_start(ap, format);
  2136. proto_tree_set_representation(pi, format, ap);
  2137. va_end(ap);
  2138. }
  2139. return pi;
  2140. }
  2141. /* Appends string data to a FT_STRING or FT_STRINGZ, allowing progressive
  2142. * field info update instead of only updating the representation as does
  2143. * proto_item_append_text()
  2144. */
  2145. /* NOTE: this function will break with the TRY_TO_FAKE_THIS_ITEM()
  2146. * speed optimization.
  2147. * Currently only WSP use this function so it is not that bad but try to
  2148. * avoid using this one if possible.
  2149. * IF you must use this function you MUST also disable the
  2150. * TRY_TO_FAKE_THIS_ITEM() optimization for your dissector/function
  2151. * using proto_item_append_string().
  2152. * Do that by faking that the tree is visible by calling
  2153. * proto_tree_set_visible(tree, TRUE) (see packet-wsp.c)
  2154. * BEFORE you create the item you are later going to use
  2155. * proto_item_append_string() on.
  2156. */
  2157. void
  2158. proto_item_append_string(proto_item *pi, const char *str)
  2159. {
  2160. field_info *fi;
  2161. header_field_info *hfinfo;
  2162. const gchar *old_str, *new_str;
  2163. if (!pi)
  2164. return;
  2165. if (!*str)
  2166. return;
  2167. fi = PITEM_FINFO(pi);
  2168. DISSECTOR_ASSERT_HINT(fi, "proto_tree_set_visible(tree, TRUE) should have been called previously");
  2169. hfinfo = fi->hfinfo;
  2170. if (hfinfo->type == FT_PROTOCOL) {
  2171. /* TRY_TO_FAKE_THIS_ITEM() speed optimization: silently skip */
  2172. return;
  2173. }
  2174. DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
  2175. old_str = (guint8 *)fvalue_get(&fi->value);
  2176. if (old_str && old_str[0])
  2177. new_str = ep_strconcat(old_str, str, NULL);
  2178. else
  2179. new_str = str;
  2180. fvalue_set(&fi->value, (gpointer) new_str, FALSE);
  2181. }
  2182. /* Set the FT_STRING value */
  2183. static void
  2184. proto_tree_set_string(field_info *fi, const char* value)
  2185. {
  2186. if (value) {
  2187. fvalue_set(&fi->value, (gpointer) value, FALSE);
  2188. } else {
  2189. fvalue_set(&fi->value, (gpointer) "[ Null ]", FALSE);
  2190. }
  2191. }
  2192. static void
  2193. proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length, gint encoding)
  2194. {
  2195. gchar *string;
  2196. if (length == -1) {
  2197. length = tvb_ensure_length_remaining(tvb, start);
  2198. }
  2199. string = tvb_get_ephemeral_string_enc(tvb, start, length, encoding);
  2200. proto_tree_set_string(fi, string);
  2201. }
  2202. /* Add a FT_AX25 to a proto_tree */
  2203. proto_item *
  2204. proto_tree_add_ax25(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
  2205. const guint8* value)
  2206. {
  2207. proto_item *pi;
  2208. field_info *new_fi;
  2209. header_field_info *hfinfo;
  2210. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  2211. DISSECTOR_ASSERT(hfinfo->type == FT_AX25);
  2212. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  2213. proto_tree_set_ax25(new_fi, value);
  2214. return pi;
  2215. }
  2216. /* Set the FT_AX25 value */
  2217. static void
  2218. proto_tree_set_ax25(field_info *fi, const guint8* value)
  2219. {
  2220. fvalue_set(&fi->value, (gpointer) value, FALSE);
  2221. }
  2222. static void
  2223. proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
  2224. {
  2225. proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
  2226. }
  2227. /* Set the FT_VINES value */
  2228. static void
  2229. proto_tree_set_vines(field_info *fi, const guint8* value)
  2230. {
  2231. fvalue_set(&fi->value, (gpointer) value, FALSE);
  2232. }
  2233. static void
  2234. proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
  2235. {
  2236. proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
  2237. }
  2238. /* Add a FT_ETHER to a proto_tree */
  2239. proto_item *
  2240. proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  2241. gint length, const guint8* value)
  2242. {
  2243. proto_item *pi;
  2244. field_info *new_fi;
  2245. header_field_info *hfinfo;
  2246. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  2247. DISSECTOR_ASSERT(hfinfo->type == FT_ETHER);
  2248. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  2249. proto_tree_set_ether(new_fi, value);
  2250. return pi;
  2251. }
  2252. proto_item *
  2253. proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2254. gint start, gint length, const guint8* value,
  2255. const char *format, ...)
  2256. {
  2257. proto_item *pi;
  2258. va_list ap;
  2259. pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
  2260. if (pi != tree) {
  2261. va_start(ap, format);
  2262. proto_tree_set_representation_value(pi, format, ap);
  2263. va_end(ap);
  2264. }
  2265. return pi;
  2266. }
  2267. proto_item *
  2268. proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2269. gint start, gint length, const guint8* value,
  2270. const char *format, ...)
  2271. {
  2272. proto_item *pi;
  2273. va_list ap;
  2274. pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
  2275. if (pi != tree) {
  2276. TRY_TO_FAKE_THIS_REPR(pi);
  2277. va_start(ap, format);
  2278. proto_tree_set_representation(pi, format, ap);
  2279. va_end(ap);
  2280. }
  2281. return pi;
  2282. }
  2283. /* Set the FT_ETHER value */
  2284. static void
  2285. proto_tree_set_ether(field_info *fi, const guint8* value)
  2286. {
  2287. fvalue_set(&fi->value, (gpointer) value, FALSE);
  2288. }
  2289. static void
  2290. proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
  2291. {
  2292. proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
  2293. }
  2294. /* Add a FT_BOOLEAN to a proto_tree */
  2295. proto_item *
  2296. proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  2297. gint length, guint32 value)
  2298. {
  2299. proto_item *pi;
  2300. field_info *new_fi;
  2301. header_field_info *hfinfo;
  2302. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  2303. DISSECTOR_ASSERT(hfinfo->type == FT_BOOLEAN);
  2304. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  2305. proto_tree_set_boolean(new_fi, value);
  2306. return pi;
  2307. }
  2308. proto_item *
  2309. proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
  2310. tvbuff_t *tvb, gint start, gint length,
  2311. guint32 value, const char *format, ...)
  2312. {
  2313. proto_item *pi;
  2314. va_list ap;
  2315. pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
  2316. if (pi != tree) {
  2317. va_start(ap, format);
  2318. proto_tree_set_representation_value(pi, format, ap);
  2319. va_end(ap);
  2320. }
  2321. return pi;
  2322. }
  2323. proto_item *
  2324. proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2325. gint start, gint length, guint32 value,
  2326. const char *format, ...)
  2327. {
  2328. proto_item *pi;
  2329. va_list ap;
  2330. pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
  2331. if (pi != tree) {
  2332. TRY_TO_FAKE_THIS_REPR(pi);
  2333. va_start(ap, format);
  2334. proto_tree_set_representation(pi, format, ap);
  2335. va_end(ap);
  2336. }
  2337. return pi;
  2338. }
  2339. /* Set the FT_BOOLEAN value */
  2340. static void
  2341. proto_tree_set_boolean(field_info *fi, guint32 value)
  2342. {
  2343. proto_tree_set_uint(fi, value);
  2344. }
  2345. /* Add a FT_FLOAT to a proto_tree */
  2346. proto_item *
  2347. proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  2348. gint length, float value)
  2349. {
  2350. proto_item *pi;
  2351. field_info *new_fi;
  2352. header_field_info *hfinfo;
  2353. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  2354. DISSECTOR_ASSERT(hfinfo->type == FT_FLOAT);
  2355. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  2356. proto_tree_set_float(new_fi, value);
  2357. return pi;
  2358. }
  2359. proto_item *
  2360. proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2361. gint start, gint length, float value,
  2362. const char *format, ...)
  2363. {
  2364. proto_item *pi;
  2365. va_list ap;
  2366. pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
  2367. if (pi != tree) {
  2368. va_start(ap, format);
  2369. proto_tree_set_representation_value(pi, format, ap);
  2370. va_end(ap);
  2371. }
  2372. return pi;
  2373. }
  2374. proto_item *
  2375. proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2376. gint start, gint length, float value,
  2377. const char *format, ...)
  2378. {
  2379. proto_item *pi;
  2380. va_list ap;
  2381. pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
  2382. if (pi != tree) {
  2383. TRY_TO_FAKE_THIS_REPR(pi);
  2384. va_start(ap, format);
  2385. proto_tree_set_representation(pi, format, ap);
  2386. va_end(ap);
  2387. }
  2388. return pi;
  2389. }
  2390. /* Set the FT_FLOAT value */
  2391. static void
  2392. proto_tree_set_float(field_info *fi, float value)
  2393. {
  2394. fvalue_set_floating(&fi->value, value);
  2395. }
  2396. /* Add a FT_DOUBLE to a proto_tree */
  2397. proto_item *
  2398. proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  2399. gint length, double value)
  2400. {
  2401. proto_item *pi;
  2402. field_info *new_fi;
  2403. header_field_info *hfinfo;
  2404. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  2405. DISSECTOR_ASSERT(hfinfo->type == FT_DOUBLE);
  2406. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  2407. proto_tree_set_double(new_fi, value);
  2408. return pi;
  2409. }
  2410. proto_item *
  2411. proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2412. gint start, gint length, double value,
  2413. const char *format, ...)
  2414. {
  2415. proto_item *pi;
  2416. va_list ap;
  2417. pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
  2418. if (pi != tree) {
  2419. va_start(ap, format);
  2420. proto_tree_set_representation_value(pi, format, ap);
  2421. va_end(ap);
  2422. }
  2423. return pi;
  2424. }
  2425. proto_item *
  2426. proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2427. gint start, gint length, double value,
  2428. const char *format, ...)
  2429. {
  2430. proto_item *pi;
  2431. va_list ap;
  2432. pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
  2433. if (pi != tree) {
  2434. TRY_TO_FAKE_THIS_REPR(pi);
  2435. va_start(ap, format);
  2436. proto_tree_set_representation(pi, format, ap);
  2437. va_end(ap);
  2438. }
  2439. return pi;
  2440. }
  2441. /* Set the FT_DOUBLE value */
  2442. static void
  2443. proto_tree_set_double(field_info *fi, double value)
  2444. {
  2445. fvalue_set_floating(&fi->value, value);
  2446. }
  2447. /* Add FT_UINT{8,16,24,32} to a proto_tree */
  2448. proto_item *
  2449. proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  2450. gint length, guint32 value)
  2451. {
  2452. proto_item *pi = NULL;
  2453. field_info *new_fi;
  2454. header_field_info *hfinfo;
  2455. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  2456. switch (hfinfo->type) {
  2457. case FT_UINT8:
  2458. case FT_UINT16:
  2459. case FT_UINT24:
  2460. case FT_UINT32:
  2461. case FT_FRAMENUM:
  2462. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length,
  2463. &new_fi);
  2464. proto_tree_set_uint(new_fi, value);
  2465. break;
  2466. default:
  2467. DISSECTOR_ASSERT_NOT_REACHED();
  2468. }
  2469. return pi;
  2470. }
  2471. proto_item *
  2472. proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2473. gint start, gint length, guint32 value,
  2474. const char *format, ...)
  2475. {
  2476. proto_item *pi;
  2477. va_list ap;
  2478. pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
  2479. if (pi != tree) {
  2480. va_start(ap, format);
  2481. proto_tree_set_representation_value(pi, format, ap);
  2482. va_end(ap);
  2483. }
  2484. return pi;
  2485. }
  2486. proto_item *
  2487. proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2488. gint start, gint length, guint32 value,
  2489. const char *format, ...)
  2490. {
  2491. proto_item *pi;
  2492. va_list ap;
  2493. pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
  2494. if (pi != tree) {
  2495. TRY_TO_FAKE_THIS_REPR(pi);
  2496. va_start(ap, format);
  2497. proto_tree_set_representation(pi, format, ap);
  2498. va_end(ap);
  2499. }
  2500. return pi;
  2501. }
  2502. /* Set the FT_UINT{8,16,24,32} value */
  2503. static void
  2504. proto_tree_set_uint(field_info *fi, guint32 value)
  2505. {
  2506. header_field_info *hfinfo;
  2507. guint32 integer;
  2508. hfinfo = fi->hfinfo;
  2509. integer = value;
  2510. if (hfinfo->bitmask) {
  2511. /* Mask out irrelevant portions */
  2512. integer &= hfinfo->bitmask;
  2513. /* Shift bits */
  2514. integer >>= hfinfo_bitshift(hfinfo);
  2515. }
  2516. fvalue_set_uinteger(&fi->value, integer);
  2517. }
  2518. /* Add FT_UINT64 to a proto_tree */
  2519. proto_item *
  2520. proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  2521. gint length, guint64 value)
  2522. {
  2523. proto_item *pi = NULL;
  2524. field_info *new_fi;
  2525. header_field_info *hfinfo;
  2526. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  2527. DISSECTOR_ASSERT(hfinfo->type == FT_UINT64);
  2528. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  2529. proto_tree_set_uint64(new_fi, value);
  2530. return pi;
  2531. }
  2532. proto_item *
  2533. proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2534. gint start, gint length, guint64 value,
  2535. const char *format, ...)
  2536. {
  2537. proto_item *pi;
  2538. va_list ap;
  2539. pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
  2540. if (pi != tree) {
  2541. va_start(ap, format);
  2542. proto_tree_set_representation_value(pi, format, ap);
  2543. va_end(ap);
  2544. }
  2545. return pi;
  2546. }
  2547. proto_item *
  2548. proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2549. gint start, gint length, guint64 value,
  2550. const char *format, ...)
  2551. {
  2552. proto_item *pi;
  2553. va_list ap;
  2554. pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
  2555. if (pi != tree) {
  2556. TRY_TO_FAKE_THIS_REPR(pi);
  2557. va_start(ap, format);
  2558. proto_tree_set_representation(pi, format, ap);
  2559. va_end(ap);
  2560. }
  2561. return pi;
  2562. }
  2563. /* Add FT_INT{8,16,24,32} to a proto_tree */
  2564. proto_item *
  2565. proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  2566. gint length, gint32 value)
  2567. {
  2568. proto_item *pi = NULL;
  2569. field_info *new_fi;
  2570. header_field_info *hfinfo;
  2571. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  2572. switch (hfinfo->type) {
  2573. case FT_INT8:
  2574. case FT_INT16:
  2575. case FT_INT24:
  2576. case FT_INT32:
  2577. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length,
  2578. &new_fi);
  2579. proto_tree_set_int(new_fi, value);
  2580. break;
  2581. default:
  2582. DISSECTOR_ASSERT_NOT_REACHED();
  2583. }
  2584. return pi;
  2585. }
  2586. proto_item *
  2587. proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2588. gint start, gint length, gint32 value,
  2589. const char *format, ...)
  2590. {
  2591. proto_item *pi;
  2592. va_list ap;
  2593. pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
  2594. if (pi != tree) {
  2595. va_start(ap, format);
  2596. proto_tree_set_representation_value(pi, format, ap);
  2597. va_end(ap);
  2598. }
  2599. return pi;
  2600. }
  2601. proto_item *
  2602. proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2603. gint start, gint length, gint32 value,
  2604. const char *format, ...)
  2605. {
  2606. proto_item *pi;
  2607. va_list ap;
  2608. pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
  2609. if (pi != tree) {
  2610. TRY_TO_FAKE_THIS_REPR(pi);
  2611. va_start(ap, format);
  2612. proto_tree_set_representation(pi, format, ap);
  2613. va_end(ap);
  2614. }
  2615. return pi;
  2616. }
  2617. /* Set the FT_INT{8,16,24,32} value */
  2618. static void
  2619. proto_tree_set_int(field_info *fi, gint32 value)
  2620. {
  2621. header_field_info *hfinfo;
  2622. guint32 integer;
  2623. hfinfo = fi->hfinfo;
  2624. integer = (guint32) value;
  2625. if (hfinfo->bitmask) {
  2626. /* Mask out irrelevant portions */
  2627. integer &= hfinfo->bitmask;
  2628. /* Shift bits */
  2629. integer >>= hfinfo_bitshift(hfinfo);
  2630. }
  2631. fvalue_set_sinteger(&fi->value, integer);
  2632. }
  2633. /* Add FT_INT64 to a proto_tree */
  2634. proto_item *
  2635. proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  2636. gint length, gint64 value)
  2637. {
  2638. proto_item *pi = NULL;
  2639. field_info *new_fi;
  2640. header_field_info *hfinfo;
  2641. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  2642. DISSECTOR_ASSERT(hfinfo->type == FT_INT64);
  2643. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  2644. proto_tree_set_uint64(new_fi, (guint64)value);
  2645. return pi;
  2646. }
  2647. proto_item *
  2648. proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2649. gint start, gint length, gint64 value,
  2650. const char *format, ...)
  2651. {
  2652. proto_item *pi;
  2653. va_list ap;
  2654. pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
  2655. if (pi != tree) {
  2656. va_start(ap, format);
  2657. proto_tree_set_representation_value(pi, format, ap);
  2658. va_end(ap);
  2659. }
  2660. return pi;
  2661. }
  2662. proto_item *
  2663. proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2664. gint start, gint length, gint64 value,
  2665. const char *format, ...)
  2666. {
  2667. proto_item *pi;
  2668. va_list ap;
  2669. pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
  2670. if (pi != tree) {
  2671. TRY_TO_FAKE_THIS_REPR(pi);
  2672. va_start(ap, format);
  2673. proto_tree_set_representation(pi, format, ap);
  2674. va_end(ap);
  2675. }
  2676. return pi;
  2677. }
  2678. /* Add a FT_EUI64 to a proto_tree */
  2679. proto_item *
  2680. proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
  2681. gint length, const guint64 value)
  2682. {
  2683. proto_item *pi;
  2684. field_info *new_fi;
  2685. header_field_info *hfinfo;
  2686. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  2687. DISSECTOR_ASSERT(hfinfo->type == FT_EUI64);
  2688. pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
  2689. proto_tree_set_eui64(new_fi, value);
  2690. return pi;
  2691. }
  2692. proto_item *
  2693. proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2694. gint start, gint length, const guint64 value,
  2695. const char *format, ...)
  2696. {
  2697. proto_item *pi;
  2698. va_list ap;
  2699. pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
  2700. if (pi != tree) {
  2701. va_start(ap, format);
  2702. proto_tree_set_representation_value(pi, format, ap);
  2703. va_end(ap);
  2704. }
  2705. return pi;
  2706. }
  2707. proto_item *
  2708. proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
  2709. gint start, gint length, const guint64 value,
  2710. const char *format, ...)
  2711. {
  2712. proto_item *pi;
  2713. va_list ap;
  2714. pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
  2715. if (pi != tree) {
  2716. TRY_TO_FAKE_THIS_REPR(pi);
  2717. va_start(ap, format);
  2718. proto_tree_set_representation(pi, format, ap);
  2719. va_end(ap);
  2720. }
  2721. return pi;
  2722. }
  2723. /* Set the FT_EUI64 value */
  2724. static void
  2725. proto_tree_set_eui64(field_info *fi, const guint64 value)
  2726. {
  2727. fvalue_set_integer64(&fi->value, value);
  2728. }
  2729. static void
  2730. proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
  2731. {
  2732. if (encoding)
  2733. {
  2734. proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
  2735. } else {
  2736. proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
  2737. }
  2738. }
  2739. /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
  2740. static proto_item *
  2741. proto_tree_add_node(proto_tree *tree, field_info *fi)
  2742. {
  2743. proto_node *pnode, *tnode, *sibling;
  2744. field_info *tfi;
  2745. /*
  2746. * Make sure "tree" is ready to have subtrees under it, by
  2747. * checking whether it's been given an ett_ value.
  2748. *
  2749. * "PNODE_FINFO(tnode)" may be null; that's the case for the root
  2750. * node of the protocol tree. That node is not displayed,
  2751. * so it doesn't need an ett_ value to remember whether it
  2752. * was expanded.
  2753. */
  2754. tnode = tree;
  2755. tfi = PNODE_FINFO(tnode);
  2756. if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
  2757. REPORT_DISSECTOR_BUG(ep_strdup_printf("\"%s\" - \"%s\" tfi->tree_type: %u invalid (%s:%u)",
  2758. fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
  2759. /* XXX - is it safe to continue here? */
  2760. }
  2761. PROTO_NODE_NEW(pnode);
  2762. pnode->parent = tnode;
  2763. PNODE_FINFO(pnode) = fi;
  2764. pnode->tree_data = PTREE_DATA(tree);
  2765. if (tnode->last_child != NULL) {
  2766. sibling = tnode->last_child;
  2767. DISSECTOR_ASSERT(sibling->next == NULL);
  2768. sibling->next = pnode;
  2769. } else
  2770. tnode->first_child = pnode;
  2771. tnode->last_child = pnode;
  2772. tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
  2773. return (proto_item *)pnode;
  2774. }
  2775. /* Generic way to allocate field_info and add to proto_tree.
  2776. * Sets *pfi to address of newly-allocated field_info struct */
  2777. static proto_item *
  2778. proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
  2779. gint *length, field_info **pfi)
  2780. {
  2781. proto_item *pi;
  2782. field_info *fi;
  2783. fi = alloc_field_info(tree, hfinfo, tvb, start, length);
  2784. pi = proto_tree_add_node(tree, fi);
  2785. *pfi = fi;
  2786. return pi;
  2787. }
  2788. static void
  2789. get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
  2790. gint *item_length)
  2791. {
  2792. gint length_remaining;
  2793. /*
  2794. * We only allow a null tvbuff if the item has a zero length,
  2795. * i.e. if there's no data backing it.
  2796. */
  2797. DISSECTOR_ASSERT(tvb != NULL || *length == 0);
  2798. /*
  2799. * XXX - in some protocols, there are 32-bit unsigned length
  2800. * fields, so lengths in protocol tree and tvbuff routines
  2801. * should really be unsigned. We should have, for those
  2802. * field types for which "to the end of the tvbuff" makes sense,
  2803. * additional routines that take no length argument and
  2804. * add fields that run to the end of the tvbuff.
  2805. */
  2806. if (*length == -1) {
  2807. /*
  2808. * For FT_NONE, FT_PROTOCOL, FT_BYTES, and FT_STRING fields,
  2809. * a length of -1 means "set the length to what remains in
  2810. * the tvbuff".
  2811. *
  2812. * The assumption is either that
  2813. *
  2814. * 1) the length of the item can only be determined
  2815. * by dissection (typically true of items with
  2816. * subitems, which are probably FT_NONE or
  2817. * FT_PROTOCOL)
  2818. *
  2819. * or
  2820. *
  2821. * 2) if the tvbuff is "short" (either due to a short
  2822. * snapshot length or due to lack of reassembly of
  2823. * fragments/segments/whatever), we want to display
  2824. * what's available in the field (probably FT_BYTES
  2825. * or FT_STRING) and then throw an exception later
  2826. *
  2827. * or
  2828. *
  2829. * 3) the field is defined to be "what's left in the
  2830. * packet"
  2831. *
  2832. * so we set the length to what remains in the tvbuff so
  2833. * that, if we throw an exception while dissecting, it
  2834. * has what is probably the right value.
  2835. *
  2836. * For FT_STRINGZ, it means "the string is null-terminated,
  2837. * not null-padded; set the length to the actual length
  2838. * of the string", and if the tvbuff if short, we just
  2839. * throw an exception.
  2840. *
  2841. * It's not valid for any other type of field.
  2842. */
  2843. switch (hfinfo->type) {
  2844. case FT_PROTOCOL:
  2845. /*
  2846. * We allow this to be zero-length - for
  2847. * example, an ONC RPC NULL procedure has
  2848. * neither arguments nor reply, so the
  2849. * payload for that protocol is empty.
  2850. *
  2851. * However, if the length is negative, the
  2852. * start offset is *past* the byte past the
  2853. * end of the tvbuff, so we throw an
  2854. * exception.
  2855. */
  2856. *length = tvb_length_remaining(tvb, start);
  2857. if (*length < 0) {
  2858. /*
  2859. * Use "tvb_ensure_bytes_exist()"
  2860. * to force the appropriate exception
  2861. * to be thrown.
  2862. */
  2863. tvb_ensure_bytes_exist(tvb, start, 0);
  2864. }
  2865. DISSECTOR_ASSERT(*length >= 0);
  2866. break;
  2867. case FT_NONE:
  2868. case FT_BYTES:
  2869. case FT_STRING:
  2870. *length = tvb_ensure_length_remaining(tvb, start);
  2871. DISSECTOR_ASSERT(*length >= 0);
  2872. break;
  2873. case FT_STRINGZ:
  2874. /*
  2875. * Leave the length as -1, so our caller knows
  2876. * it was -1.
  2877. */
  2878. break;
  2879. default:
  2880. DISSECTOR_ASSERT_NOT_REACHED();
  2881. }
  2882. *item_length = *length;
  2883. } else {
  2884. *item_length = *length;
  2885. if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
  2886. /*
  2887. * These types are for interior nodes of the
  2888. * tree, and don't have data associated with
  2889. * them; if the length is negative (XXX - see
  2890. * above) or goes past the end of the tvbuff,
  2891. * cut it short at the end of the tvbuff.
  2892. * That way, if this field is selected in
  2893. * Wireshark, we don't highlight stuff past
  2894. * the end of the data.
  2895. */
  2896. /* XXX - what to do, if we don't have a tvb? */
  2897. if (tvb) {
  2898. length_remaining = tvb_length_remaining(tvb, start);
  2899. if (*item_length < 0 ||
  2900. (*item_length > 0 &&
  2901. (length_remaining < *item_length)))
  2902. *item_length = length_remaining;
  2903. }
  2904. }
  2905. if (*item_length < 0) {
  2906. THROW(ReportedBoundsError);
  2907. }
  2908. }
  2909. }
  2910. static field_info *
  2911. new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
  2912. const gint start, const gint item_length)
  2913. {
  2914. field_info *fi;
  2915. FIELD_INFO_NEW(fi);
  2916. fi->hfinfo = hfinfo;
  2917. fi->start = start;
  2918. fi->start += (tvb)?tvb_raw_offset(tvb):0;
  2919. fi->length = item_length;
  2920. fi->tree_type = -1;
  2921. fi->flags = 0;
  2922. if (!PTREE_DATA(tree)->visible)
  2923. FI_SET_FLAG(fi, FI_HIDDEN);
  2924. fvalue_init(&fi->value, fi->hfinfo->type);
  2925. fi->rep = NULL;
  2926. /* add the data source tvbuff */
  2927. fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
  2928. fi->appendix_start = 0;
  2929. fi->appendix_length = 0;
  2930. return fi;
  2931. }
  2932. static field_info *
  2933. alloc_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
  2934. gint *length)
  2935. {
  2936. gint item_length;
  2937. get_hfi_length(hfinfo, tvb, start, length, &item_length);
  2938. return new_field_info(tree, hfinfo, tvb, start, item_length);
  2939. }
  2940. static void
  2941. label_mark_truncated_start(char *label_str)
  2942. {
  2943. static const char trunc_str[] = "[truncated] ";
  2944. const size_t trunc_len = sizeof(trunc_str)-1;
  2945. memmove(label_str + trunc_len, label_str, ITEM_LABEL_LENGTH - trunc_len);
  2946. memcpy(label_str, trunc_str, trunc_len);
  2947. label_str[ITEM_LABEL_LENGTH-1] = '\0';
  2948. }
  2949. /* If the protocol tree is to be visible, set the representation of a
  2950. proto_tree entry with the name of the field for the item and with
  2951. the value formatted with the supplied printf-style format and
  2952. argument list. */
  2953. static void
  2954. proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
  2955. {
  2956. g_assert(pi);
  2957. /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
  2958. * items string representation */
  2959. if (PTREE_DATA(pi)->visible && !PROTO_ITEM_IS_HIDDEN(pi)) {
  2960. int ret = 0;
  2961. field_info *fi = PITEM_FINFO(pi);
  2962. header_field_info *hf;
  2963. DISSECTOR_ASSERT(fi);
  2964. hf = fi->hfinfo;
  2965. ITEM_LABEL_NEW(fi->rep);
  2966. if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
  2967. guint32 val;
  2968. char *p;
  2969. val = fvalue_get_uinteger(&fi->value);
  2970. val <<= hfinfo_bitshift(hf);
  2971. p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_bitwidth(hf));
  2972. ret = (int) (p - fi->rep->representation);
  2973. }
  2974. /* put in the hf name */
  2975. ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
  2976. /* If possible, Put in the value of the string */
  2977. if (ret < ITEM_LABEL_LENGTH) {
  2978. ret += g_vsnprintf(fi->rep->representation + ret,
  2979. ITEM_LABEL_LENGTH - ret, format, ap);
  2980. }
  2981. if (ret >= ITEM_LABEL_LENGTH) {
  2982. /* Uh oh, we don't have enough room. Tell the user
  2983. * that the field is truncated.
  2984. */
  2985. /* XXX, label_mark_truncated() ? */
  2986. label_mark_truncated_start(fi->rep->representation);
  2987. }
  2988. }
  2989. }
  2990. /* If the protocol tree is to be visible, set the representation of a
  2991. proto_tree entry with the representation formatted with the supplied
  2992. printf-style format and argument list. */
  2993. static void
  2994. proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
  2995. {
  2996. int ret; /*tmp return value */
  2997. field_info *fi = PITEM_FINFO(pi);
  2998. DISSECTOR_ASSERT(fi);
  2999. if (!PROTO_ITEM_IS_HIDDEN(pi)) {
  3000. ITEM_LABEL_NEW(fi->rep);
  3001. ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
  3002. format, ap);
  3003. if (ret >= ITEM_LABEL_LENGTH) {
  3004. /* Uh oh, we don't have enough room. Tell the user
  3005. * that the field is truncated.
  3006. */
  3007. label_mark_truncated_start(fi->rep->representation);
  3008. }
  3009. }
  3010. }
  3011. static int
  3012. protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
  3013. {
  3014. gsize res = g_strlcpy(dest, src, dest_size);
  3015. if (res > dest_size)
  3016. res = dest_size;
  3017. return (int) res;
  3018. }
  3019. static header_field_info *
  3020. hfinfo_same_name_get_prev(const header_field_info *hfinfo)
  3021. {
  3022. if (hfinfo->same_name_prev_id == -1)
  3023. return NULL;
  3024. return proto_registrar_get_nth(hfinfo->same_name_prev_id);
  3025. }
  3026. /* -------------------------- */
  3027. const gchar *
  3028. proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
  3029. gchar *result, gchar *expr, const int size)
  3030. {
  3031. guint32 number;
  3032. guint8 *bytes;
  3033. ipv4_addr *ipv4;
  3034. struct e_in6_addr *ipv6;
  3035. address addr;
  3036. guint32 n_addr; /* network-order IPv4 address */
  3037. const true_false_string *tfstring;
  3038. int len, prev_len = 0, last, i, offset_r = 0, offset_e = 0;
  3039. GPtrArray *finfos;
  3040. field_info *finfo = NULL;
  3041. header_field_info* hfinfo;
  3042. const gchar *abbrev = NULL;
  3043. const char *hf_str_val;
  3044. char number_buf[32];
  3045. const char *number_out;
  3046. g_assert(field_id >= 0);
  3047. hfinfo = proto_registrar_get_nth((guint)field_id);
  3048. /* do we need to rewind ? */
  3049. if (!hfinfo)
  3050. return "";
  3051. if (occurrence < 0) {
  3052. /* Search other direction */
  3053. while (hfinfo->same_name_prev_id != -1) {
  3054. hfinfo = proto_registrar_get_nth(hfinfo->same_name_prev_id);
  3055. }
  3056. }
  3057. while (hfinfo) {
  3058. finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
  3059. if (!finfos || !(len = g_ptr_array_len(finfos))) {
  3060. if (occurrence < 0) {
  3061. hfinfo = hfinfo->same_name_next;
  3062. } else {
  3063. hfinfo = hfinfo_same_name_get_prev(hfinfo);
  3064. }
  3065. continue;
  3066. }
  3067. /* Are there enough occurrences of the field? */
  3068. if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
  3069. if (occurrence < 0) {
  3070. hfinfo = hfinfo->same_name_next;
  3071. } else {
  3072. hfinfo = hfinfo_same_name_get_prev(hfinfo);
  3073. }
  3074. prev_len += len;
  3075. continue;
  3076. }
  3077. /* Calculate single index or set outer bounderies */
  3078. if (occurrence < 0) {
  3079. i = occurrence + len + prev_len;
  3080. last = i;
  3081. } else if (occurrence > 0) {
  3082. i = occurrence - 1 - prev_len;
  3083. last = i;
  3084. } else {
  3085. i = 0;
  3086. last = len - 1;
  3087. }
  3088. prev_len += len; /* Count handled occurrences */
  3089. while (i <= last) {
  3090. finfo = (field_info *)g_ptr_array_index(finfos, i);
  3091. if (offset_r && (offset_r < (size - 2)))
  3092. result[offset_r++] = ',';
  3093. if (offset_e && (offset_e < (size - 2)))
  3094. expr[offset_e++] = ',';
  3095. switch (hfinfo->type) {
  3096. case FT_NONE: /* Nothing to add */
  3097. if (offset_r == 0) {
  3098. result[0] = '\0';
  3099. } else if (result[offset_r-1] == ',') {
  3100. result[offset_r-1] = '\0';
  3101. }
  3102. break;
  3103. case FT_PROTOCOL:
  3104. /* prevent multiple "yes" entries by setting result directly */
  3105. g_strlcpy(result, "Yes", size);
  3106. break;
  3107. case FT_UINT_BYTES:
  3108. case FT_BYTES:
  3109. bytes = (guint8 *)fvalue_get(&finfo->value);
  3110. offset_r += protoo_strlcpy(result+offset_r,
  3111. bytes_to_str(bytes,
  3112. fvalue_length(&finfo->value)),
  3113. size-offset_r);
  3114. break;
  3115. case FT_ABSOLUTE_TIME:
  3116. offset_r += protoo_strlcpy(result+offset_r,
  3117. abs_time_to_str((const nstime_t *)fvalue_get(&finfo->value),
  3118. (absolute_time_display_e)hfinfo->display, TRUE),
  3119. size-offset_r);
  3120. break;
  3121. case FT_RELATIVE_TIME:
  3122. offset_r += protoo_strlcpy(result+offset_r,
  3123. rel_time_to_secs_str((const nstime_t *)fvalue_get(&finfo->value)),
  3124. size-offset_r);
  3125. break;
  3126. case FT_BOOLEAN:
  3127. number = fvalue_get_uinteger(&finfo->value);
  3128. tfstring = (const true_false_string *)&tfs_true_false;
  3129. if (hfinfo->strings) {
  3130. tfstring = (const struct true_false_string*) hfinfo->strings;
  3131. }
  3132. offset_r += protoo_strlcpy(result+offset_r,
  3133. number ?
  3134. tfstring->true_string :
  3135. tfstring->false_string, size-offset_r);
  3136. offset_e += protoo_strlcpy(expr+offset_e,
  3137. number ? "1" : "0", size-offset_e);
  3138. break;
  3139. /* XXX - make these just FT_NUMBER? */
  3140. case FT_INT8:
  3141. case FT_INT16:
  3142. case FT_INT24:
  3143. case FT_INT32:
  3144. case FT_UINT8:
  3145. case FT_UINT16:
  3146. case FT_UINT24:
  3147. case FT_UINT32:
  3148. case FT_FRAMENUM:
  3149. hf_str_val = NULL;
  3150. number = IS_FT_INT(hfinfo->type) ?
  3151. (guint32) fvalue_get_sinteger(&finfo->value) :
  3152. fvalue_get_uinteger(&finfo->value);
  3153. if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_CUSTOM) {
  3154. gchar tmp[ITEM_LABEL_LENGTH];
  3155. custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
  3156. DISSECTOR_ASSERT(fmtfunc);
  3157. fmtfunc(tmp, number);
  3158. offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
  3159. } else if (hfinfo->strings) {
  3160. number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
  3161. if (!number_out)
  3162. number_out = hfinfo_number_value_format_display(hfinfo, BASE_DEC, number_buf, number);
  3163. offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
  3164. } else {
  3165. number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
  3166. offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
  3167. }
  3168. if (hf_str_val && (hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
  3169. g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
  3170. } else {
  3171. number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
  3172. g_strlcpy(expr+offset_e, number_out, size-offset_e);
  3173. }
  3174. offset_e = (int)strlen(expr);
  3175. break;
  3176. case FT_INT64:
  3177. /* XXX: Should handle BASE_CUSTOM ? */
  3178. g_snprintf(result+offset_r, size-offset_r,
  3179. "%" G_GINT64_MODIFIER "d",
  3180. fvalue_get_integer64(&finfo->value));
  3181. offset_r = (int)strlen(result);
  3182. break;
  3183. case FT_UINT64:
  3184. g_snprintf(result+offset_r, size-offset_r,
  3185. /* XXX: Should handle BASE_CUSTOM ? */
  3186. "%" G_GINT64_MODIFIER "u",
  3187. fvalue_get_integer64(&finfo->value));
  3188. offset_r = (int)strlen(result);
  3189. break;
  3190. case FT_EUI64:
  3191. offset_r += protoo_strlcpy(result+offset_r,
  3192. eui64_to_str(fvalue_get_integer64(&finfo->value)),
  3193. size-offset_r);
  3194. break;
  3195. case FT_IPv4:
  3196. ipv4 = (ipv4_addr *)fvalue_get(&finfo->value);
  3197. n_addr = ipv4_get_net_order_addr(ipv4);
  3198. offset_r += protoo_strlcpy(result+offset_r,
  3199. ip_to_str((guint8 *)&n_addr),
  3200. size-offset_r);
  3201. break;
  3202. case FT_IPv6:
  3203. ipv6 = (struct e_in6_addr *)fvalue_get(&finfo->value);
  3204. SET_ADDRESS (&addr, AT_IPv6, sizeof(struct e_in6_addr), ipv6);
  3205. address_to_str_buf(&addr, result+offset_r, size-offset_r);
  3206. offset_r = (int)strlen(result);
  3207. break;
  3208. case FT_ETHER:
  3209. offset_r += protoo_strlcpy(result+offset_r,
  3210. bytes_to_str_punct((const guint8 *)fvalue_get(&finfo->value),
  3211. FT_ETHER_LEN, ':'),
  3212. size-offset_r);
  3213. break;
  3214. case FT_GUID:
  3215. offset_r += protoo_strlcpy(result+offset_r,
  3216. guid_to_str((e_guid_t *)fvalue_get(&finfo->value)),
  3217. size-offset_r);
  3218. break;
  3219. case FT_OID:
  3220. bytes = (guint8 *)fvalue_get(&finfo->value);
  3221. offset_r += protoo_strlcpy(result+offset_r,
  3222. oid_resolved_from_encoded(bytes,
  3223. fvalue_length(&finfo->value)),
  3224. size-offset_r);
  3225. offset_e += protoo_strlcpy(expr+offset_e,
  3226. oid_encoded2string(bytes, fvalue_length(&finfo->value)),
  3227. size-offset_e);
  3228. break;
  3229. case FT_FLOAT:
  3230. g_snprintf(result+offset_r, size-offset_r,
  3231. "%." STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
  3232. offset_r = (int)strlen(result);
  3233. break;
  3234. case FT_DOUBLE:
  3235. g_snprintf(result+offset_r, size-offset_r,
  3236. "%." STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
  3237. offset_r = (int)strlen(result);
  3238. break;
  3239. case FT_STRING:
  3240. case FT_STRINGZ:
  3241. case FT_UINT_STRING:
  3242. bytes = (guint8 *)fvalue_get(&finfo->value);
  3243. offset_r += protoo_strlcpy(result+offset_r,
  3244. format_text(bytes, strlen(bytes)),
  3245. size-offset_r);
  3246. break;
  3247. case FT_IPXNET: /*XXX really No column custom ?*/
  3248. case FT_PCRE:
  3249. default:
  3250. g_error("hfinfo->type %d (%s) not handled\n",
  3251. hfinfo->type,
  3252. ftype_name(hfinfo->type));
  3253. DISSECTOR_ASSERT_NOT_REACHED();
  3254. break;
  3255. }
  3256. i++;
  3257. }
  3258. switch (hfinfo->type) {
  3259. case FT_BOOLEAN:
  3260. case FT_UINT8:
  3261. case FT_UINT16:
  3262. case FT_UINT24:
  3263. case FT_UINT32:
  3264. case FT_FRAMENUM:
  3265. case FT_INT8:
  3266. case FT_INT16:
  3267. case FT_INT24:
  3268. case FT_INT32:
  3269. case FT_OID:
  3270. /* for these types, "expr" is filled in the loop above */
  3271. break;
  3272. default:
  3273. /* for all others, just copy "result" to "expr" */
  3274. g_strlcpy(expr, result, size);
  3275. break;
  3276. }
  3277. if (!abbrev) {
  3278. /* Store abbrev for return value */
  3279. abbrev = hfinfo->abbrev;
  3280. }
  3281. if (occurrence == 0) {
  3282. /* Fetch next hfinfo with same name (abbrev) */
  3283. hfinfo = hfinfo_same_name_get_prev(hfinfo);
  3284. } else {
  3285. hfinfo = NULL;
  3286. }
  3287. }
  3288. return abbrev ? abbrev : "";
  3289. }
  3290. /* Set text of proto_item after having already been created. */
  3291. void
  3292. proto_item_set_text(proto_item *pi, const char *format, ...)
  3293. {
  3294. field_info *fi = NULL;
  3295. va_list ap;
  3296. if (pi == NULL) {
  3297. return;
  3298. }
  3299. fi = PITEM_FINFO(pi);
  3300. if (fi == NULL)
  3301. return;
  3302. if (fi->rep) {
  3303. ITEM_LABEL_FREE(fi->rep);
  3304. fi->rep = NULL;
  3305. }
  3306. va_start(ap, format);
  3307. proto_tree_set_representation(pi, format, ap);
  3308. va_end(ap);
  3309. }
  3310. /* Append to text of proto_item after having already been created. */
  3311. void
  3312. proto_item_append_text(proto_item *pi, const char *format, ...)
  3313. {
  3314. field_info *fi = NULL;
  3315. size_t curlen;
  3316. va_list ap;
  3317. if (pi == NULL) {
  3318. return;
  3319. }
  3320. fi = PITEM_FINFO(pi);
  3321. if (fi == NULL) {
  3322. return;
  3323. }
  3324. if (!PROTO_ITEM_IS_HIDDEN(pi)) {
  3325. /*
  3326. * If we don't already have a representation,
  3327. * generate the default representation.
  3328. */
  3329. if (fi->rep == NULL) {
  3330. ITEM_LABEL_NEW(fi->rep);
  3331. proto_item_fill_label(fi, fi->rep->representation);
  3332. }
  3333. curlen = strlen(fi->rep->representation);
  3334. if (ITEM_LABEL_LENGTH > curlen) {
  3335. va_start(ap, format);
  3336. g_vsnprintf(fi->rep->representation + curlen,
  3337. ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
  3338. va_end(ap);
  3339. }
  3340. }
  3341. }
  3342. /* Prepend to text of proto_item after having already been created. */
  3343. void
  3344. proto_item_prepend_text(proto_item *pi, const char *format, ...)
  3345. {
  3346. field_info *fi = NULL;
  3347. char representation[ITEM_LABEL_LENGTH];
  3348. va_list ap;
  3349. if (pi == NULL) {
  3350. return;
  3351. }
  3352. fi = PITEM_FINFO(pi);
  3353. if (fi == NULL) {
  3354. return;
  3355. }
  3356. if (!PROTO_ITEM_IS_HIDDEN(pi)) {
  3357. /*
  3358. * If we don't already have a representation,
  3359. * generate the default representation.
  3360. */
  3361. if (fi->rep == NULL) {
  3362. ITEM_LABEL_NEW(fi->rep);
  3363. proto_item_fill_label(fi, representation);
  3364. } else
  3365. g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
  3366. va_start(ap, format);
  3367. g_vsnprintf(fi->rep->representation,
  3368. ITEM_LABEL_LENGTH, format, ap);
  3369. va_end(ap);
  3370. g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
  3371. }
  3372. }
  3373. void
  3374. proto_item_set_len(proto_item *pi, const gint length)
  3375. {
  3376. field_info *fi;
  3377. if (pi == NULL)
  3378. return;
  3379. fi = PITEM_FINFO(pi);
  3380. if (fi == NULL)
  3381. return;
  3382. DISSECTOR_ASSERT(length >= 0);
  3383. fi->length = length;
  3384. /*
  3385. * You cannot just make the "len" field of a GByteArray
  3386. * larger, if there's no data to back that length;
  3387. * you can only make it smaller.
  3388. */
  3389. if (fi->value.ftype->ftype == FT_BYTES && length <= (gint)fi->value.value.bytes->len)
  3390. fi->value.value.bytes->len = length;
  3391. }
  3392. /*
  3393. * Sets the length of the item based on its start and on the specified
  3394. * offset, which is the offset past the end of the item; as the start
  3395. * in the item is relative to the beginning of the data source tvbuff,
  3396. * we need to pass in a tvbuff - the end offset is relative to the beginning
  3397. * of that tvbuff.
  3398. */
  3399. void
  3400. proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
  3401. {
  3402. field_info *fi;
  3403. if (pi == NULL)
  3404. return;
  3405. fi = PITEM_FINFO(pi);
  3406. if (fi == NULL)
  3407. return;
  3408. end += tvb_raw_offset(tvb);
  3409. DISSECTOR_ASSERT(end >= fi->start);
  3410. fi->length = end - fi->start;
  3411. }
  3412. int
  3413. proto_item_get_len(const proto_item *pi)
  3414. {
  3415. field_info *fi = PITEM_FINFO(pi);
  3416. return fi ? fi->length : -1;
  3417. }
  3418. proto_tree *
  3419. proto_tree_create_root(packet_info *pinfo)
  3420. {
  3421. proto_node *pnode;
  3422. /* Initialize the proto_node */
  3423. PROTO_NODE_NEW(pnode);
  3424. pnode->parent = NULL;
  3425. PNODE_FINFO(pnode) = NULL;
  3426. pnode->tree_data = g_new(tree_data_t, 1);
  3427. /* Make sure we can access pinfo everywhere */
  3428. pnode->tree_data->pinfo = pinfo;
  3429. /* Don't initialize the tree_data_t. Wait until we know we need it */
  3430. pnode->tree_data->interesting_hfids = NULL;
  3431. /* Set the default to FALSE so it's easier to
  3432. * find errors; if we expect to see the protocol tree
  3433. * but for some reason the default 'visible' is not
  3434. * changed, then we'll find out very quickly. */
  3435. pnode->tree_data->visible = FALSE;
  3436. /* Make sure that we fake protocols (if possible) */
  3437. pnode->tree_data->fake_protocols = TRUE;
  3438. /* Keep track of the number of children */
  3439. pnode->tree_data->count = 0;
  3440. pnode->tree_data->fi_tmp = NULL;
  3441. return (proto_tree *)pnode;
  3442. }
  3443. /* "prime" a proto_tree with a single hfid that a dfilter
  3444. * is interested in. */
  3445. void
  3446. proto_tree_prime_hfid(proto_tree *tree _U_, const gint hfid)
  3447. {
  3448. header_field_info *hfinfo;
  3449. PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
  3450. /* this field is referenced by a filter so increase the refcount.
  3451. also increase the refcount for the parent, i.e the protocol.
  3452. */
  3453. hfinfo->ref_type = HF_REF_TYPE_DIRECT;
  3454. /* only increase the refcount if there is a parent.
  3455. if this is a protocol and not a field then parent will be -1
  3456. and there is no parent to add any refcounting for.
  3457. */
  3458. if (hfinfo->parent != -1) {
  3459. header_field_info *parent_hfinfo;
  3460. PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
  3461. /* Mark parent as indirectly referenced unless it is already directly
  3462. * referenced, i.e. the user has specified the parent in a filter.
  3463. */
  3464. if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
  3465. parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
  3466. }
  3467. }
  3468. proto_tree *
  3469. proto_item_add_subtree(proto_item *pi, const gint idx) {
  3470. field_info *fi;
  3471. if (!pi)
  3472. return NULL;
  3473. DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
  3474. fi = PITEM_FINFO(pi);
  3475. if (!fi)
  3476. return (proto_tree *)pi;
  3477. fi->tree_type = idx;
  3478. return (proto_tree *)pi;
  3479. }
  3480. proto_tree *
  3481. proto_item_get_subtree(const proto_item *pi) {
  3482. field_info *fi;
  3483. if (!pi)
  3484. return NULL;
  3485. fi = PITEM_FINFO(pi);
  3486. if ( (!fi) || (fi->tree_type == -1) )
  3487. return NULL;
  3488. return (proto_tree *)pi;
  3489. }
  3490. proto_item *
  3491. proto_item_get_parent(const proto_item *ti) {
  3492. if (!ti)
  3493. return NULL;
  3494. return ti->parent;
  3495. }
  3496. proto_item *
  3497. proto_item_get_parent_nth(proto_item *ti, int gen) {
  3498. if (!ti)
  3499. return NULL;
  3500. while (gen--) {
  3501. ti = ti->parent;
  3502. if (!ti)
  3503. return NULL;
  3504. }
  3505. return ti;
  3506. }
  3507. proto_item *
  3508. proto_tree_get_parent(const proto_tree *tree) {
  3509. if (!tree)
  3510. return NULL;
  3511. return (proto_item *)tree;
  3512. }
  3513. proto_tree *
  3514. proto_tree_get_root(proto_tree *tree) {
  3515. if (!tree)
  3516. return NULL;
  3517. while (tree->parent) {
  3518. tree = tree->parent;
  3519. }
  3520. return tree;
  3521. }
  3522. void
  3523. proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
  3524. proto_item *item_to_move)
  3525. {
  3526. /* Revert part of: http://anonsvn.wireshark.org/viewvc?view=rev&revision=32443
  3527. * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5500
  3528. */
  3529. /* This function doesn't generate any values. It only reorganizes the prococol tree
  3530. * so we can bail out immediately if it isn't visible. */
  3531. if (!tree || !PTREE_DATA(tree)->visible)
  3532. return;
  3533. DISSECTOR_ASSERT(item_to_move->parent == tree);
  3534. DISSECTOR_ASSERT(fixed_item->parent == tree);
  3535. /*** cut item_to_move out ***/
  3536. /* is item_to_move the first? */
  3537. if (tree->first_child == item_to_move) {
  3538. /* simply change first child to next */
  3539. tree->first_child = item_to_move->next;
  3540. DISSECTOR_ASSERT(tree->last_child != item_to_move);
  3541. } else {
  3542. proto_item *curr_item;
  3543. /* find previous and change it's next */
  3544. for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
  3545. if (curr_item->next == item_to_move) {
  3546. break;
  3547. }
  3548. }
  3549. DISSECTOR_ASSERT(curr_item);
  3550. curr_item->next = item_to_move->next;
  3551. /* fix last_child if required */
  3552. if (tree->last_child == item_to_move) {
  3553. tree->last_child = curr_item;
  3554. }
  3555. }
  3556. /*** insert to_move after fixed ***/
  3557. item_to_move->next = fixed_item->next;
  3558. fixed_item->next = item_to_move;
  3559. if (tree->last_child == fixed_item) {
  3560. tree->last_child = item_to_move;
  3561. }
  3562. }
  3563. void
  3564. proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
  3565. const gint length)
  3566. {
  3567. field_info *fi;
  3568. if (tree == NULL)
  3569. return;
  3570. fi = PTREE_FINFO(tree);
  3571. if (fi == NULL)
  3572. return;
  3573. start += tvb_raw_offset(tvb);
  3574. DISSECTOR_ASSERT(start >= 0);
  3575. DISSECTOR_ASSERT(length >= 0);
  3576. fi->appendix_start = start;
  3577. fi->appendix_length = length;
  3578. }
  3579. int
  3580. proto_register_protocol(const char *name, const char *short_name,
  3581. const char *filter_name)
  3582. {
  3583. protocol_t *protocol;
  3584. header_field_info *hfinfo;
  3585. int proto_id;
  3586. char *existing_name;
  3587. gint *key;
  3588. guint i;
  3589. guchar c;
  3590. gboolean found_invalid;
  3591. /*
  3592. * Make sure there's not already a protocol with any of those
  3593. * names. Crash if there is, as that's an error in the code
  3594. * or an inappropriate plugin.
  3595. * This situation has to be fixed to not register more than one
  3596. * protocol with the same name.
  3597. *
  3598. * This is done by reducing the number of strcmp (and alike) calls
  3599. * as much as possible, as this significally slows down startup time.
  3600. *
  3601. * Drawback: As a hash value is used to reduce insert time,
  3602. * this might lead to a hash collision.
  3603. * However, although we have somewhat over 1000 protocols, we're using
  3604. * a 32 bit int so this is very, very unlikely.
  3605. */
  3606. key = (gint *)g_malloc (sizeof(gint));
  3607. *key = wrs_str_hash(name);
  3608. existing_name = (char *)g_hash_table_lookup(proto_names, key);
  3609. if (existing_name != NULL) {
  3610. /* g_error will terminate the program */
  3611. g_error("Duplicate protocol name \"%s\"!"
  3612. " This might be caused by an inappropriate plugin or a development error.", name);
  3613. }
  3614. g_hash_table_insert(proto_names, key, (gpointer)name);
  3615. existing_name = (char *)g_hash_table_lookup(proto_short_names, (gpointer)short_name);
  3616. if (existing_name != NULL) {
  3617. g_error("Duplicate protocol short_name \"%s\"!"
  3618. " This might be caused by an inappropriate plugin or a development error.", short_name);
  3619. }
  3620. g_hash_table_insert(proto_short_names, (gpointer)short_name, (gpointer)short_name);
  3621. found_invalid = FALSE;
  3622. for (i = 0; filter_name[i]; i++) {
  3623. c = filter_name[i];
  3624. if (!(islower(c) || isdigit(c) || c == '-' || c == '_' || c == '.')) {
  3625. found_invalid = TRUE;
  3626. }
  3627. }
  3628. if (found_invalid) {
  3629. g_error("Protocol filter name \"%s\" has one or more invalid characters."
  3630. " Allowed are lower characters, digits, '-', '_' and '.'."
  3631. " This might be caused by an inappropriate plugin or a development error.", filter_name);
  3632. }
  3633. existing_name = (char *)g_hash_table_lookup(proto_filter_names, (gpointer)filter_name);
  3634. if (existing_name != NULL) {
  3635. g_error("Duplicate protocol filter_name \"%s\"!"
  3636. " This might be caused by an inappropriate plugin or a development error.", filter_name);
  3637. }
  3638. g_hash_table_insert(proto_filter_names, (gpointer)filter_name, (gpointer)filter_name);
  3639. /* Add this protocol to the list of known protocols; the list
  3640. is sorted by protocol short name. */
  3641. protocol = g_new(protocol_t, 1);
  3642. protocol->name = name;
  3643. protocol->short_name = short_name;
  3644. protocol->filter_name = filter_name;
  3645. protocol->fields = NULL;
  3646. protocol->is_enabled = TRUE; /* protocol is enabled by default */
  3647. protocol->can_toggle = TRUE;
  3648. protocol->is_private = FALSE;
  3649. /* list will be sorted later by name, when all protocols completed registering */
  3650. protocols = g_list_prepend(protocols, protocol);
  3651. /* Here we allocate a new header_field_info struct */
  3652. hfinfo = g_slice_new(header_field_info);
  3653. hfinfo->name = name;
  3654. hfinfo->abbrev = filter_name;
  3655. hfinfo->type = FT_PROTOCOL;
  3656. hfinfo->display = BASE_NONE;
  3657. hfinfo->strings = protocol;
  3658. hfinfo->bitmask = 0;
  3659. hfinfo->ref_type = HF_REF_TYPE_NONE;
  3660. hfinfo->blurb = NULL;
  3661. hfinfo->parent = -1; /* this field differentiates protos and fields */
  3662. proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
  3663. protocol->proto_id = proto_id;
  3664. return proto_id;
  3665. }
  3666. void
  3667. proto_mark_private(const int proto_id)
  3668. {
  3669. protocol_t *protocol = find_protocol_by_id(proto_id);
  3670. if (protocol)
  3671. protocol->is_private = TRUE;
  3672. }
  3673. gboolean
  3674. proto_is_private(const int proto_id)
  3675. {
  3676. protocol_t *protocol = find_protocol_by_id(proto_id);
  3677. if (protocol)
  3678. return protocol->is_private;
  3679. else
  3680. return FALSE;
  3681. }
  3682. /*
  3683. * Routines to use to iterate over the protocols.
  3684. * The argument passed to the iterator routines is an opaque cookie to
  3685. * their callers; it's the GList pointer for the current element in
  3686. * the list.
  3687. * The ID of the protocol is returned, or -1 if there is no protocol.
  3688. */
  3689. int
  3690. proto_get_first_protocol(void **cookie)
  3691. {
  3692. protocol_t *protocol;
  3693. if (protocols == NULL)
  3694. return -1;
  3695. *cookie = protocols;
  3696. protocol = (protocol_t *)protocols->data;
  3697. return protocol->proto_id;
  3698. }
  3699. int
  3700. proto_get_data_protocol(void *cookie)
  3701. {
  3702. GList *list_item = (GList *)cookie;
  3703. protocol_t *protocol = (protocol_t *)list_item->data;
  3704. return protocol->proto_id;
  3705. }
  3706. int
  3707. proto_get_next_protocol(void **cookie)
  3708. {
  3709. GList *list_item = (GList *)*cookie;
  3710. protocol_t *protocol;
  3711. list_item = g_list_next(list_item);
  3712. if (list_item == NULL)
  3713. return -1;
  3714. *cookie = list_item;
  3715. protocol = (protocol_t *)list_item->data;
  3716. return protocol->proto_id;
  3717. }
  3718. header_field_info *
  3719. proto_get_first_protocol_field(const int proto_id, void **cookie)
  3720. {
  3721. protocol_t *protocol = find_protocol_by_id(proto_id);
  3722. if ((protocol == NULL) || (protocol->fields == NULL))
  3723. return NULL;
  3724. *cookie = protocol->fields;
  3725. return (header_field_info *)protocol->fields->data;
  3726. }
  3727. header_field_info *
  3728. proto_get_next_protocol_field(void **cookie)
  3729. {
  3730. GSList *list_item = (GSList *)*cookie;
  3731. list_item = g_slist_next(list_item);
  3732. if (list_item == NULL)
  3733. return NULL;
  3734. *cookie = list_item;
  3735. return (header_field_info *)list_item->data;
  3736. }
  3737. protocol_t *
  3738. find_protocol_by_id(const int proto_id)
  3739. {
  3740. header_field_info *hfinfo;
  3741. if (proto_id < 0)
  3742. return NULL;
  3743. PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
  3744. DISSECTOR_ASSERT(hfinfo->type == FT_PROTOCOL);
  3745. return (protocol_t *)hfinfo->strings;
  3746. }
  3747. static gint compare_filter_name(gconstpointer proto_arg,
  3748. gconstpointer filter_name)
  3749. {
  3750. const protocol_t *protocol = (const protocol_t *)proto_arg;
  3751. const gchar *f_name = (const gchar *)filter_name;
  3752. return (strcmp(protocol->filter_name, f_name));
  3753. }
  3754. int
  3755. proto_get_id(const protocol_t *protocol)
  3756. {
  3757. return protocol->proto_id;
  3758. }
  3759. int proto_get_id_by_filter_name(const gchar* filter_name)
  3760. {
  3761. GList *list_entry;
  3762. protocol_t *protocol;
  3763. if(!filter_name){
  3764. fprintf(stderr, "No filter name present");
  3765. DISSECTOR_ASSERT(filter_name);
  3766. }
  3767. list_entry = g_list_find_custom(protocols, filter_name,
  3768. compare_filter_name);
  3769. if (list_entry == NULL)
  3770. return -1;
  3771. protocol = (protocol_t *)list_entry->data;
  3772. return protocol->proto_id;
  3773. }
  3774. const char *
  3775. proto_get_protocol_name(const int proto_id)
  3776. {
  3777. protocol_t *protocol;
  3778. protocol = find_protocol_by_id(proto_id);
  3779. if (protocol == NULL)
  3780. return NULL;
  3781. return protocol->name;
  3782. }
  3783. const char *
  3784. proto_get_protocol_short_name(const protocol_t *protocol)
  3785. {
  3786. if (protocol == NULL)
  3787. return "(none)";
  3788. return protocol->short_name;
  3789. }
  3790. const char *
  3791. proto_get_protocol_long_name(const protocol_t *protocol)
  3792. {
  3793. if (protocol == NULL)
  3794. return "(none)";
  3795. return protocol->name;
  3796. }
  3797. const char *
  3798. proto_get_protocol_filter_name(const int proto_id)
  3799. {
  3800. protocol_t *protocol;
  3801. protocol = find_protocol_by_id(proto_id);
  3802. if (protocol == NULL)
  3803. return "(none)";
  3804. return protocol->filter_name;
  3805. }
  3806. gboolean
  3807. proto_is_protocol_enabled(const protocol_t *protocol)
  3808. {
  3809. return protocol->is_enabled;
  3810. }
  3811. gboolean
  3812. proto_can_toggle_protocol(const int proto_id)
  3813. {
  3814. protocol_t *protocol;
  3815. protocol = find_protocol_by_id(proto_id);
  3816. return protocol->can_toggle;
  3817. }
  3818. void
  3819. proto_set_decoding(const int proto_id, const gboolean enabled)
  3820. {
  3821. protocol_t *protocol;
  3822. protocol = find_protocol_by_id(proto_id);
  3823. DISSECTOR_ASSERT(protocol->can_toggle);
  3824. protocol->is_enabled = enabled;
  3825. }
  3826. void
  3827. proto_enable_all(void)
  3828. {
  3829. protocol_t *protocol;
  3830. GList *list_item = protocols;
  3831. if (protocols == NULL)
  3832. return;
  3833. while (list_item) {
  3834. protocol = (protocol_t *)list_item->data;
  3835. if (protocol->can_toggle)
  3836. protocol->is_enabled = TRUE;
  3837. list_item = g_list_next(list_item);
  3838. }
  3839. }
  3840. void
  3841. proto_set_cant_toggle(const int proto_id)
  3842. {
  3843. protocol_t *protocol;
  3844. protocol = find_protocol_by_id(proto_id);
  3845. protocol->can_toggle = FALSE;
  3846. }
  3847. /* for use with static arrays only, since we don't allocate our own copies
  3848. of the header_field_info struct contained within the hf_register_info struct */
  3849. void
  3850. proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
  3851. {
  3852. int field_id, i;
  3853. hf_register_info *ptr = hf;
  3854. protocol_t *proto;
  3855. proto = find_protocol_by_id(parent);
  3856. for (i = 0; i < num_records; i++, ptr++) {
  3857. /*
  3858. * Make sure we haven't registered this yet.
  3859. * Most fields have variables associated with them
  3860. * that are initialized to -1; some have array elements,
  3861. * or possibly uninitialized variables, so we also allow
  3862. * 0 (which is unlikely to be the field ID we get back
  3863. * from "proto_register_field_init()").
  3864. */
  3865. if (*ptr->p_id != -1 && *ptr->p_id != 0) {
  3866. fprintf(stderr,
  3867. "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
  3868. ptr->hfinfo.abbrev);
  3869. return;
  3870. }
  3871. if (proto != NULL) {
  3872. if (proto->fields == NULL) {
  3873. proto->fields = g_slist_append(NULL, &ptr->hfinfo);
  3874. proto->last_field = proto->fields;
  3875. } else {
  3876. proto->last_field =
  3877. g_slist_append(proto->last_field, &ptr->hfinfo)->next;
  3878. }
  3879. }
  3880. field_id = proto_register_field_init(&ptr->hfinfo, parent);
  3881. *ptr->p_id = field_id;
  3882. }
  3883. }
  3884. void
  3885. proto_register_fields(const int parent, header_field_info **hfi, const int num_records)
  3886. {
  3887. int i;
  3888. protocol_t *proto;
  3889. proto = find_protocol_by_id(parent);
  3890. for (i = 0; i < num_records; i++) {
  3891. /*
  3892. * Make sure we haven't registered this yet.
  3893. */
  3894. if (hfi[i]->id != -1) {
  3895. fprintf(stderr,
  3896. "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
  3897. hfi[i]->abbrev);
  3898. return;
  3899. }
  3900. if (proto != NULL) {
  3901. if (proto->fields == NULL) {
  3902. proto->fields = g_slist_append(NULL, hfi[i]);
  3903. proto->last_field = proto->fields;
  3904. } else {
  3905. proto->last_field =
  3906. g_slist_append(proto->last_field, hfi[i])->next;
  3907. }
  3908. }
  3909. proto_register_field_init(hfi[i], parent);
  3910. }
  3911. }
  3912. /* unregister already registered fields */
  3913. void
  3914. proto_unregister_field (const int parent, gint hf_id)
  3915. {
  3916. hf_register_info *hf;
  3917. protocol_t *proto;
  3918. GSList *field;
  3919. if (hf_id == -1 || hf_id == 0)
  3920. return;
  3921. proto = find_protocol_by_id (parent);
  3922. if (!proto || !proto->fields) {
  3923. return;
  3924. }
  3925. for (field = proto->fields; field; field = field->next) {
  3926. hf = (hf_register_info *)field->data;
  3927. if (*hf->p_id == hf_id) {
  3928. /* Found the hf_id in this protocol */
  3929. g_tree_steal (gpa_name_tree, hf->hfinfo.abbrev);
  3930. /* XXX, memleak? g_slist_delete_link() */
  3931. proto->fields = g_slist_remove_link (proto->fields, field);
  3932. proto->last_field = g_slist_last (proto->fields);
  3933. break;
  3934. }
  3935. }
  3936. }
  3937. /* chars allowed in field abbrev */
  3938. static
  3939. const guchar fld_abbrev_chars[256] = {
  3940. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
  3941. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
  3942. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.' */
  3943. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9' */
  3944. 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O' */
  3945. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
  3946. 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o' */
  3947. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z' */
  3948. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
  3949. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
  3950. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
  3951. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
  3952. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
  3953. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
  3954. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
  3955. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
  3956. };
  3957. static const value_string hf_types[] = {
  3958. { FT_NONE, "FT_NONE" },
  3959. { FT_PROTOCOL, "FT_PROTOCOL" },
  3960. { FT_BOOLEAN, "FT_BOOLEAN" },
  3961. { FT_UINT8, "FT_UINT8" },
  3962. { FT_UINT16, "FT_UINT16" },
  3963. { FT_UINT24, "FT_UINT24" },
  3964. { FT_UINT32, "FT_UINT32" },
  3965. { FT_UINT64, "FT_UINT64" },
  3966. { FT_INT8, "FT_INT8" },
  3967. { FT_INT16, "FT_INT16" },
  3968. { FT_INT24, "FT_INT24" },
  3969. { FT_INT32, "FT_INT32" },
  3970. { FT_INT64, "FT_INT64" },
  3971. { FT_EUI64, "FT_EUI64" },
  3972. { FT_FLOAT, "FT_FLOAT" },
  3973. { FT_DOUBLE, "FT_DOUBLE" },
  3974. { FT_ABSOLUTE_TIME, "FT_ABSOLUTE_TIME" },
  3975. { FT_RELATIVE_TIME, "FT_RELATIVE_TIME" },
  3976. { FT_STRING, "FT_STRING" },
  3977. { FT_STRINGZ, "FT_STRINGZ" },
  3978. { FT_UINT_STRING, "FT_UINT_STRING" },
  3979. { FT_ETHER, "FT_ETHER" },
  3980. { FT_BYTES, "FT_BYTES" },
  3981. { FT_UINT_BYTES, "FT_UINT_BYTES" },
  3982. { FT_IPv4, "FT_IPv4" },
  3983. { FT_IPv6, "FT_IPv6" },
  3984. { FT_IPXNET, "FT_IPXNET" },
  3985. { FT_FRAMENUM, "FT_FRAMENUM" },
  3986. { FT_PCRE, "FT_PCR" },
  3987. { FT_GUID, "FT_GUID" },
  3988. { FT_OID, "FT_OID" },
  3989. { 0, NULL } };
  3990. static const value_string hf_display[] = {
  3991. { BASE_NONE, "BASE_NONE" },
  3992. { BASE_DEC, "BASE_DEC" },
  3993. { BASE_HEX, "BASE_HEX" },
  3994. { BASE_OCT, "BASE_OCT" },
  3995. { BASE_DEC_HEX, "BASE_DEC_HEX" },
  3996. { BASE_HEX_DEC, "BASE_HEX_DEC" },
  3997. { BASE_CUSTOM, "BASE_CUSTOM" },
  3998. { BASE_NONE|BASE_RANGE_STRING, "BASE_NONE|BASE_RANGE_STRING" },
  3999. { BASE_DEC|BASE_RANGE_STRING, "BASE_DEC|BASE_RANGE_STRING" },
  4000. { BASE_HEX|BASE_RANGE_STRING, "BASE_HEX|BASE_RANGE_STRING" },
  4001. { BASE_OCT|BASE_RANGE_STRING, "BASE_OCT|BASE_RANGE_STRING" },
  4002. { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
  4003. { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
  4004. { BASE_CUSTOM|BASE_RANGE_STRING, "BASE_CUSTOM|BASE_RANGE_STRING" },
  4005. { BASE_NONE|BASE_VAL64_STRING, "BASE_NONE|BASE_VAL64_STRING" },
  4006. { BASE_DEC|BASE_VAL64_STRING, "BASE_DEC|BASE_VAL64_STRING" },
  4007. { BASE_HEX|BASE_VAL64_STRING, "BASE_HEX|BASE_VAL64_STRING" },
  4008. { BASE_OCT|BASE_VAL64_STRING, "BASE_OCT|BASE_VAL64_STRING" },
  4009. { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
  4010. { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
  4011. { BASE_CUSTOM|BASE_VAL64_STRING, "BASE_CUSTOM|BASE_VAL64_STRING" },
  4012. { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
  4013. { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
  4014. { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
  4015. { 0, NULL } };
  4016. /* temporary function containing assert part for easier profiling */
  4017. static void
  4018. tmp_fld_check_assert(header_field_info *hfinfo)
  4019. {
  4020. /* The field must have a name (with length > 0) */
  4021. if (!hfinfo->name || !hfinfo->name[0]) {
  4022. if (hfinfo->abbrev)
  4023. /* Try to identify the field */
  4024. g_error("Field (abbrev='%s') does not have a name\n",
  4025. hfinfo->abbrev);
  4026. else
  4027. /* Hum, no luck */
  4028. g_error("Field does not have a name (nor an abbreviation)\n");
  4029. }
  4030. /* fields with an empty string for an abbreviation aren't filterable */
  4031. if (!hfinfo->abbrev || !hfinfo->abbrev[0])
  4032. g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
  4033. /* These types of fields are allowed to have value_strings,
  4034. * true_false_strings or a protocol_t struct
  4035. */
  4036. if (hfinfo->strings != NULL && !(
  4037. (hfinfo->type == FT_UINT8) ||
  4038. (hfinfo->type == FT_UINT16) ||
  4039. (hfinfo->type == FT_UINT24) ||
  4040. (hfinfo->type == FT_UINT32) ||
  4041. (hfinfo->type == FT_UINT64) ||
  4042. (hfinfo->type == FT_INT8) ||
  4043. (hfinfo->type == FT_INT16) ||
  4044. (hfinfo->type == FT_INT24) ||
  4045. (hfinfo->type == FT_INT32) ||
  4046. (hfinfo->type == FT_INT64) ||
  4047. (hfinfo->type == FT_BOOLEAN) ||
  4048. (hfinfo->type == FT_PROTOCOL) ))
  4049. g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
  4050. " (which is not allowed to have strings)\n",
  4051. hfinfo->name, hfinfo->abbrev,
  4052. val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"));
  4053. /* TODO: This check may slow down startup, and output quite a few warnings.
  4054. It would be good to be able to enable this (and possibly other checks?)
  4055. in non-release builds. */
  4056. #if 0
  4057. /* Check for duplicate value_string values.
  4058. There are lots that have the same value *and* string, so for now only
  4059. report those that have same value but different string. */
  4060. if ((hfinfo->strings != NULL) &&
  4061. !(hfinfo->display & BASE_RANGE_STRING) &&
  4062. !((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_CUSTOM) &&
  4063. (
  4064. (hfinfo->type == FT_UINT8) ||
  4065. (hfinfo->type == FT_UINT16) ||
  4066. (hfinfo->type == FT_UINT24) ||
  4067. (hfinfo->type == FT_UINT32) ||
  4068. (hfinfo->type == FT_INT8) ||
  4069. (hfinfo->type == FT_INT16) ||
  4070. (hfinfo->type == FT_INT24) ||
  4071. (hfinfo->type == FT_INT32) ||
  4072. (hfinfo->type == FT_FRAMENUM) )) {
  4073. int n, m;
  4074. const value_string *start_values;
  4075. const value_string *current;
  4076. if (hfinfo->display & BASE_EXT_STRING)
  4077. start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
  4078. else
  4079. start_values = (const value_string*)hfinfo->strings;
  4080. current = start_values;
  4081. for (n=0; current; n++, current++) {
  4082. /* Drop out if we reached the end. */
  4083. if ((current->value == 0) && (current->strptr == NULL)) {
  4084. break;
  4085. }
  4086. /* Check value against all previous */
  4087. for (m=0; m < n; m++) {
  4088. /* There are lots of duplicates with the same string,
  4089. so only report if different... */
  4090. if ((start_values[m].value == current->value) &&
  4091. (strcmp(start_values[m].strptr, current->strptr) != 0)) {
  4092. g_warning("Field '%s' (%s) has a conflicting entry in its"
  4093. " value_string: %u is at indices %u (%s) and %u (%s))\n",
  4094. hfinfo->name, hfinfo->abbrev,
  4095. current->value, m, start_values[m].strptr, n, current->strptr);
  4096. }
  4097. }
  4098. }
  4099. }
  4100. #endif
  4101. switch (hfinfo->type) {
  4102. case FT_INT8:
  4103. case FT_INT16:
  4104. case FT_INT24:
  4105. case FT_INT32:
  4106. case FT_INT64:
  4107. /* Hexadecimal and octal are, in printf() and everywhere
  4108. * else, unsigned so don't allow dissectors to register a
  4109. * signed field to be displayed unsigned. (Else how would
  4110. * we display negative values?)
  4111. */
  4112. switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
  4113. case BASE_HEX:
  4114. case BASE_OCT:
  4115. case BASE_DEC_HEX:
  4116. case BASE_HEX_DEC:
  4117. g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
  4118. hfinfo->name, hfinfo->abbrev,
  4119. val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
  4120. val_to_str(hfinfo->display, hf_display, "(Bit count: %d)"));
  4121. }
  4122. /* FALL THROUGH */
  4123. case FT_UINT8:
  4124. case FT_UINT16:
  4125. case FT_UINT24:
  4126. case FT_UINT32:
  4127. case FT_UINT64:
  4128. /* Require integral types (other than frame number,
  4129. * which is always displayed in decimal) to have a
  4130. * number base.
  4131. * If there is a strings value then this base is not
  4132. * normally used except when constructing a display
  4133. * filter for a value not found in the strings lookup.
  4134. */
  4135. switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
  4136. case BASE_DEC:
  4137. case BASE_HEX:
  4138. case BASE_OCT:
  4139. case BASE_DEC_HEX:
  4140. case BASE_HEX_DEC:
  4141. case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
  4142. break;
  4143. default:
  4144. g_error("Field '%s' (%s) is an integral value (%s)"
  4145. " but is being displayed as %s\n",
  4146. hfinfo->name, hfinfo->abbrev,
  4147. val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
  4148. val_to_str(hfinfo->display, hf_display, "(Unknown: 0x%x)"));
  4149. }
  4150. break;
  4151. case FT_PROTOCOL:
  4152. case FT_FRAMENUM:
  4153. if (hfinfo->display != BASE_NONE)
  4154. g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
  4155. hfinfo->name, hfinfo->abbrev,
  4156. val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
  4157. val_to_str(hfinfo->display, hf_display, "(Bit count: %d)"));
  4158. if (hfinfo->bitmask != 0)
  4159. g_error("Field '%s' (%s) is an %s but has a bitmask\n",
  4160. hfinfo->name, hfinfo->abbrev,
  4161. val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"));
  4162. break;
  4163. case FT_BOOLEAN:
  4164. break;
  4165. case FT_ABSOLUTE_TIME:
  4166. if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
  4167. hfinfo->display == ABSOLUTE_TIME_UTC ||
  4168. hfinfo->display == ABSOLUTE_TIME_DOY_UTC))
  4169. g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
  4170. hfinfo->name, hfinfo->abbrev,
  4171. val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
  4172. val_to_str(hfinfo->display, hf_display, "(Bit count: %d)"));
  4173. if (hfinfo->bitmask != 0)
  4174. g_error("Field '%s' (%s) is an %s but has a bitmask\n",
  4175. hfinfo->name, hfinfo->abbrev,
  4176. val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"));
  4177. break;
  4178. default:
  4179. if (hfinfo->display != BASE_NONE)
  4180. g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
  4181. hfinfo->name, hfinfo->abbrev,
  4182. val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
  4183. val_to_str(hfinfo->display, hf_display, "(Bit count: %d)"));
  4184. if (hfinfo->bitmask != 0)
  4185. g_error("Field '%s' (%s) is an %s but has a bitmask\n",
  4186. hfinfo->name, hfinfo->abbrev,
  4187. val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"));
  4188. if (hfinfo->strings != NULL)
  4189. g_error("Field '%s' (%s) is an %s but has a strings value\n",
  4190. hfinfo->name, hfinfo->abbrev,
  4191. val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"));
  4192. break;
  4193. }
  4194. }
  4195. #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (120000+PRE_ALLOC_EXPERT_FIELDS_MEM)
  4196. static int
  4197. proto_register_field_init(header_field_info *hfinfo, const int parent)
  4198. {
  4199. tmp_fld_check_assert(hfinfo);
  4200. hfinfo->parent = parent;
  4201. hfinfo->same_name_next = NULL;
  4202. hfinfo->same_name_prev_id = -1;
  4203. /* if we always add and never delete, then id == len - 1 is correct */
  4204. if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
  4205. if (!gpa_hfinfo.hfi) {
  4206. gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
  4207. gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
  4208. } else {
  4209. gpa_hfinfo.allocated_len += 1000;
  4210. gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
  4211. sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
  4212. /*g_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
  4213. }
  4214. }
  4215. gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
  4216. gpa_hfinfo.len++;
  4217. hfinfo->id = gpa_hfinfo.len - 1;
  4218. /* if we have real names, enter this field in the name tree */
  4219. if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
  4220. header_field_info *same_name_next_hfinfo;
  4221. guchar c;
  4222. /* Check that the filter name (abbreviation) is legal;
  4223. * it must contain only alphanumerics, '-', "_", and ".". */
  4224. c = wrs_check_charset(fld_abbrev_chars, hfinfo->abbrev);
  4225. if (c) {
  4226. fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
  4227. DISSECTOR_ASSERT(!c);
  4228. }
  4229. /* We allow multiple hfinfo's to be registered under the same
  4230. * abbreviation. This was done for X.25, as, depending
  4231. * on whether it's modulo-8 or modulo-128 operation,
  4232. * some bitfield fields may be in different bits of
  4233. * a byte, and we want to be able to refer to that field
  4234. * with one name regardless of whether the packets
  4235. * are modulo-8 or modulo-128 packets. */
  4236. same_name_hfinfo = NULL;
  4237. g_tree_insert(gpa_name_tree, (gpointer) (hfinfo->abbrev), hfinfo);
  4238. /* GLIB 2.x - if it is already present
  4239. * the previous hfinfo with the same name is saved
  4240. * to same_name_hfinfo by value destroy callback */
  4241. if (same_name_hfinfo) {
  4242. /* There's already a field with this name.
  4243. * Put it after that field in the list of
  4244. * fields with this name, then allow the code
  4245. * after this if{} block to replace the old
  4246. * hfinfo with the new hfinfo in the GTree. Thus,
  4247. * we end up with a linked-list of same-named hfinfo's,
  4248. * with the root of the list being the hfinfo in the GTree */
  4249. same_name_next_hfinfo =
  4250. same_name_hfinfo->same_name_next;
  4251. hfinfo->same_name_next = same_name_next_hfinfo;
  4252. if (same_name_next_hfinfo)
  4253. same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
  4254. same_name_hfinfo->same_name_next = hfinfo;
  4255. hfinfo->same_name_prev_id = same_name_hfinfo->id;
  4256. }
  4257. }
  4258. return hfinfo->id;
  4259. }
  4260. void
  4261. proto_register_subtree_array(gint *const *indices, const int num_indices)
  4262. {
  4263. int i;
  4264. gint *const *ptr = indices;
  4265. /*
  4266. * If we've already allocated the array of tree types, expand
  4267. * it; this lets plugins such as mate add tree types after
  4268. * the initial startup. (If we haven't already allocated it,
  4269. * we don't allocate it; on the first pass, we just assign
  4270. * ett values and keep track of how many we've assigned, and
  4271. * when we're finished registering all dissectors we allocate
  4272. * the array, so that we do only one allocation rather than
  4273. * wasting CPU time and memory by growing the array for each
  4274. * dissector that registers ett values.)
  4275. */
  4276. if (tree_is_expanded != NULL) {
  4277. tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
  4278. /* set new items to 0 */
  4279. /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
  4280. for (i = num_tree_types; i < num_tree_types + num_indices; i++)
  4281. tree_is_expanded[i >> 5] &= ~(1 << (i & 31));
  4282. }
  4283. /*
  4284. * Assign "num_indices" subtree numbers starting at "num_tree_types",
  4285. * returning the indices through the pointers in the array whose
  4286. * first element is pointed to by "indices", and update
  4287. * "num_tree_types" appropriately.
  4288. */
  4289. for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
  4290. if (**ptr != -1) {
  4291. /* g_error will terminate the program */
  4292. g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
  4293. " This is a development error:"
  4294. " Either the subtree item type has already been assigned or"
  4295. " was not initialized to -1.");
  4296. }
  4297. **ptr = num_tree_types;
  4298. }
  4299. }
  4300. static inline gsize
  4301. label_concat(char *label_str, gsize pos, const char *str)
  4302. {
  4303. if (pos < ITEM_LABEL_LENGTH)
  4304. pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
  4305. return pos;
  4306. }
  4307. static void
  4308. label_mark_truncated(char *label_str, gsize name_pos)
  4309. {
  4310. static const char trunc_str[] = " [truncated]";
  4311. const size_t trunc_len = sizeof(trunc_str)-1;
  4312. /* ..... field_name: dataaaaaaaaaaaaa
  4313. * |
  4314. * ^^^^^ name_pos
  4315. *
  4316. * ..... field_name [truncated]: dataaaaaaaaaaaaa */
  4317. if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
  4318. memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
  4319. memcpy(label_str + name_pos, trunc_str, trunc_len);
  4320. label_str[ITEM_LABEL_LENGTH-1] = '\0';
  4321. } else if (name_pos < ITEM_LABEL_LENGTH)
  4322. g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
  4323. }
  4324. static gsize
  4325. label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
  4326. {
  4327. gsize name_pos;
  4328. /* "%s: %s", hfinfo->name, text */
  4329. name_pos = pos = label_concat(label_str, pos, hfinfo->name);
  4330. pos = label_concat(label_str, pos, ": ");
  4331. pos = label_concat(label_str, pos, text ? text : "(null)");
  4332. if (pos >= ITEM_LABEL_LENGTH) {
  4333. /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
  4334. label_mark_truncated(label_str, name_pos);
  4335. }
  4336. return pos;
  4337. }
  4338. static gsize
  4339. label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
  4340. {
  4341. gsize name_pos;
  4342. /* "%s: %s (%s)", hfinfo->name, text, descr */
  4343. name_pos = pos = label_concat(label_str, pos, hfinfo->name);
  4344. pos = label_concat(label_str, pos, ": ");
  4345. pos = label_concat(label_str, pos, text ? text : "(null)");
  4346. pos = label_concat(label_str, pos, " (");
  4347. pos = label_concat(label_str, pos, descr ? descr : "(null)");
  4348. pos = label_concat(label_str, pos, ")");
  4349. if (pos >= ITEM_LABEL_LENGTH) {
  4350. /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
  4351. label_mark_truncated(label_str, name_pos);
  4352. }
  4353. return pos;
  4354. }
  4355. void
  4356. proto_item_fill_label(field_info *fi, gchar *label_str)
  4357. {
  4358. header_field_info *hfinfo;
  4359. guint8 *bytes;
  4360. guint32 integer;
  4361. guint64 integer64;
  4362. ipv4_addr *ipv4;
  4363. e_guid_t *guid;
  4364. guint32 n_addr; /* network-order IPv4 address */
  4365. const gchar *name;
  4366. address addr;
  4367. if (!fi) {
  4368. if (label_str)
  4369. label_str[0]= '\0';
  4370. /* XXX: Check validity of hfinfo->type */
  4371. return;
  4372. }
  4373. hfinfo = fi->hfinfo;
  4374. switch (hfinfo->type) {
  4375. case FT_NONE:
  4376. case FT_PROTOCOL:
  4377. g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
  4378. break;
  4379. case FT_BOOLEAN:
  4380. fill_label_boolean(fi, label_str);
  4381. break;
  4382. case FT_BYTES:
  4383. case FT_UINT_BYTES:
  4384. bytes = (guint8 *)fvalue_get(&fi->value);
  4385. label_fill(label_str, 0, hfinfo,
  4386. (bytes) ? bytes_to_str(bytes, fvalue_length(&fi->value)) : "<MISSING>");
  4387. break;
  4388. /* Four types of integers to take care of:
  4389. * Bitfield, with val_string
  4390. * Bitfield, w/o val_string
  4391. * Non-bitfield, with val_string
  4392. * Non-bitfield, w/o val_string
  4393. */
  4394. case FT_UINT8:
  4395. case FT_UINT16:
  4396. case FT_UINT24:
  4397. case FT_UINT32:
  4398. if (hfinfo->bitmask) {
  4399. fill_label_bitfield(fi, label_str);
  4400. } else {
  4401. fill_label_number(fi, label_str, FALSE);
  4402. }
  4403. break;
  4404. case FT_FRAMENUM:
  4405. fill_label_number(fi, label_str, FALSE);
  4406. break;
  4407. case FT_UINT64:
  4408. fill_label_number64(fi, label_str, FALSE);
  4409. break;
  4410. case FT_INT8:
  4411. case FT_INT16:
  4412. case FT_INT24:
  4413. case FT_INT32:
  4414. DISSECTOR_ASSERT(!hfinfo->bitmask);
  4415. fill_label_number(fi, label_str, TRUE);
  4416. break;
  4417. case FT_INT64:
  4418. fill_label_number64(fi, label_str, TRUE);
  4419. break;
  4420. case FT_FLOAT:
  4421. g_snprintf(label_str, ITEM_LABEL_LENGTH,
  4422. "%s: %." STRINGIFY(FLT_DIG) "g",
  4423. hfinfo->name, fvalue_get_floating(&fi->value));
  4424. break;
  4425. case FT_DOUBLE:
  4426. g_snprintf(label_str, ITEM_LABEL_LENGTH,
  4427. "%s: %." STRINGIFY(DBL_DIG) "g",
  4428. hfinfo->name, fvalue_get_floating(&fi->value));
  4429. break;
  4430. case FT_ABSOLUTE_TIME:
  4431. label_fill(label_str, 0, hfinfo,
  4432. abs_time_to_str((const nstime_t *)fvalue_get(&fi->value),
  4433. (absolute_time_display_e)hfinfo->display, TRUE));
  4434. break;
  4435. case FT_RELATIVE_TIME:
  4436. g_snprintf(label_str, ITEM_LABEL_LENGTH,
  4437. "%s: %s seconds", hfinfo->name,
  4438. rel_time_to_secs_str((const nstime_t *)fvalue_get(&fi->value)));
  4439. break;
  4440. case FT_IPXNET:
  4441. integer = fvalue_get_uinteger(&fi->value);
  4442. g_snprintf(label_str, ITEM_LABEL_LENGTH,
  4443. "%s: %s (0x%08X)", hfinfo->name,
  4444. get_ipxnet_name(integer), integer);
  4445. break;
  4446. case FT_AX25:
  4447. bytes = (guint8 *)fvalue_get(&fi->value);
  4448. label_fill_descr(label_str, 0, hfinfo,
  4449. get_ax25_name(bytes),
  4450. ax25_to_str(bytes));
  4451. break;
  4452. case FT_VINES:
  4453. addr.type = AT_VINES;
  4454. addr.len = VINES_ADDR_LEN;
  4455. addr.data = (guint8 *)fvalue_get(&fi->value);
  4456. g_snprintf(label_str, ITEM_LABEL_LENGTH,
  4457. "%s: %s", hfinfo->name,
  4458. address_to_str( &addr ));
  4459. break;
  4460. case FT_ETHER:
  4461. bytes = (guint8 *)fvalue_get(&fi->value);
  4462. label_fill_descr(label_str, 0, hfinfo,
  4463. get_ether_name(bytes),
  4464. ether_to_str(bytes));
  4465. break;
  4466. case FT_IPv4:
  4467. ipv4 = (ipv4_addr *)fvalue_get(&fi->value);
  4468. n_addr = ipv4_get_net_order_addr(ipv4);
  4469. label_fill_descr(label_str, 0, hfinfo,
  4470. get_hostname(n_addr),
  4471. ip_to_str((guint8*)&n_addr));
  4472. break;
  4473. case FT_IPv6:
  4474. bytes = (guint8 *)fvalue_get(&fi->value);
  4475. label_fill_descr(label_str, 0, hfinfo,
  4476. get_hostname6((struct e_in6_addr *)bytes),
  4477. ip6_to_str((struct e_in6_addr*)bytes));
  4478. break;
  4479. case FT_GUID:
  4480. guid = (e_guid_t *)fvalue_get(&fi->value);
  4481. label_fill(label_str, 0, hfinfo, guid_to_str(guid));
  4482. break;
  4483. case FT_OID:
  4484. bytes = (guint8 *)fvalue_get(&fi->value);
  4485. name = oid_resolved_from_encoded(bytes, fvalue_length(&fi->value));
  4486. if (name) {
  4487. label_fill_descr(label_str, 0, hfinfo,
  4488. oid_encoded2string(bytes, fvalue_length(&fi->value)), name);
  4489. } else {
  4490. label_fill(label_str, 0, hfinfo,
  4491. oid_encoded2string(bytes, fvalue_length(&fi->value)));
  4492. }
  4493. break;
  4494. case FT_EUI64:
  4495. integer64 = fvalue_get_integer64(&fi->value);
  4496. label_fill_descr(label_str, 0, hfinfo,
  4497. get_eui64_name(integer64),
  4498. eui64_to_str(integer64));
  4499. break;
  4500. case FT_STRING:
  4501. case FT_STRINGZ:
  4502. case FT_UINT_STRING:
  4503. bytes = (guint8 *)fvalue_get(&fi->value);
  4504. label_fill(label_str, 0, hfinfo, format_text(bytes, strlen(bytes)));
  4505. break;
  4506. default:
  4507. g_error("hfinfo->type %d (%s) not handled\n",
  4508. hfinfo->type, ftype_name(hfinfo->type));
  4509. DISSECTOR_ASSERT_NOT_REACHED();
  4510. break;
  4511. }
  4512. }
  4513. static void
  4514. fill_label_boolean(field_info *fi, gchar *label_str)
  4515. {
  4516. char *p = label_str;
  4517. int bitfield_byte_length = 0, bitwidth;
  4518. guint32 unshifted_value;
  4519. guint32 value;
  4520. header_field_info *hfinfo = fi->hfinfo;
  4521. const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
  4522. if (hfinfo->strings) {
  4523. tfstring = (const struct true_false_string*) hfinfo->strings;
  4524. }
  4525. value = fvalue_get_uinteger(&fi->value);
  4526. if (hfinfo->bitmask) {
  4527. /* Figure out the bit width */
  4528. bitwidth = hfinfo_bitwidth(hfinfo);
  4529. /* Un-shift bits */
  4530. unshifted_value = value;
  4531. unshifted_value <<= hfinfo_bitshift(hfinfo);
  4532. /* Create the bitfield first */
  4533. p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
  4534. bitfield_byte_length = (int) (p - label_str);
  4535. }
  4536. /* Fill in the textual info */
  4537. label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
  4538. }
  4539. static const char *
  4540. hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
  4541. {
  4542. if (hfinfo->display & BASE_RANGE_STRING)
  4543. return try_rval_to_str(value, (const range_string *) hfinfo->strings);
  4544. if (hfinfo->display & BASE_EXT_STRING)
  4545. return try_val_to_str_ext(value, (const value_string_ext *) hfinfo->strings);
  4546. if (hfinfo->display & BASE_VAL64_STRING)
  4547. return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
  4548. return try_val_to_str(value, (const value_string *) hfinfo->strings);
  4549. }
  4550. static const char *
  4551. hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
  4552. {
  4553. if (hfinfo->display & BASE_VAL64_STRING)
  4554. return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
  4555. /* If this is reached somebody registered a 64-bit field with a 32-bit
  4556. * value-string, which isn't right. */
  4557. DISSECTOR_ASSERT_NOT_REACHED();
  4558. /* This is necessary to squelch MSVC errors; is there
  4559. any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
  4560. never returns? */
  4561. return NULL;
  4562. }
  4563. static const char *
  4564. hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
  4565. {
  4566. const char *str = hf_try_val_to_str(value, hfinfo);
  4567. return (str) ? str : unknown_str;
  4568. }
  4569. static const char *
  4570. hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
  4571. {
  4572. const char *str = hf_try_val64_to_str(value, hfinfo);
  4573. return (str) ? str : unknown_str;
  4574. }
  4575. /* Fills data for bitfield ints with val_strings */
  4576. static void
  4577. fill_label_bitfield(field_info *fi, gchar *label_str)
  4578. {
  4579. char *p;
  4580. int bitfield_byte_length, bitwidth;
  4581. guint32 unshifted_value;
  4582. guint32 value;
  4583. char buf[32];
  4584. const char *out;
  4585. header_field_info *hfinfo = fi->hfinfo;
  4586. /* Figure out the bit width */
  4587. bitwidth = hfinfo_bitwidth(hfinfo);
  4588. /* Un-shift bits */
  4589. unshifted_value = fvalue_get_uinteger(&fi->value);
  4590. value = unshifted_value;
  4591. if (hfinfo->bitmask) {
  4592. unshifted_value <<= hfinfo_bitshift(hfinfo);
  4593. }
  4594. /* Create the bitfield first */
  4595. p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
  4596. bitfield_byte_length = (int) (p - label_str);
  4597. /* Fill in the textual info using stored (shifted) value */
  4598. if (hfinfo->display == BASE_CUSTOM) {
  4599. gchar tmp[ITEM_LABEL_LENGTH];
  4600. const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
  4601. DISSECTOR_ASSERT(fmtfunc);
  4602. fmtfunc(tmp, value);
  4603. label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
  4604. }
  4605. else if (hfinfo->strings) {
  4606. const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
  4607. out = hfinfo_number_vals_format(hfinfo, buf, value);
  4608. if (out == NULL) /* BASE_NONE so don't put integer in descr */
  4609. label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
  4610. else
  4611. label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
  4612. }
  4613. else {
  4614. out = hfinfo_number_value_format(hfinfo, buf, value);
  4615. label_fill(label_str, bitfield_byte_length, hfinfo, out);
  4616. }
  4617. }
  4618. static void
  4619. fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
  4620. {
  4621. header_field_info *hfinfo = fi->hfinfo;
  4622. guint32 value;
  4623. char buf[32];
  4624. const char *out;
  4625. if (is_signed)
  4626. value = fvalue_get_sinteger(&fi->value);
  4627. else
  4628. value = fvalue_get_uinteger(&fi->value);
  4629. /* Fill in the textual info */
  4630. if (hfinfo->display == BASE_CUSTOM) {
  4631. gchar tmp[ITEM_LABEL_LENGTH];
  4632. const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
  4633. DISSECTOR_ASSERT(fmtfunc);
  4634. fmtfunc(tmp, value);
  4635. label_fill(label_str, 0, hfinfo, tmp);
  4636. }
  4637. else if (hfinfo->strings) {
  4638. const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
  4639. out = hfinfo_number_vals_format(hfinfo, buf, value);
  4640. if (out == NULL) /* BASE_NONE so don't put integer in descr */
  4641. label_fill(label_str, 0, hfinfo, val_str);
  4642. else
  4643. label_fill_descr(label_str, 0, hfinfo, val_str, out);
  4644. }
  4645. else {
  4646. out = hfinfo_number_value_format(hfinfo, buf, value);
  4647. label_fill(label_str, 0, hfinfo, out);
  4648. }
  4649. }
  4650. static void
  4651. fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
  4652. {
  4653. const char *format = NULL;
  4654. header_field_info *hfinfo = fi->hfinfo;
  4655. guint64 value;
  4656. char tmp[ITEM_LABEL_LENGTH+1];
  4657. /* Pick the proper format string */
  4658. if (is_signed)
  4659. format = hfinfo_int64_format(hfinfo);
  4660. else
  4661. format = hfinfo_uint64_format(hfinfo);
  4662. value = fvalue_get_integer64(&fi->value);
  4663. /* Format the temporary string */
  4664. if (IS_BASE_DUAL(hfinfo->display))
  4665. g_snprintf(tmp, ITEM_LABEL_LENGTH, format, value, value);
  4666. else
  4667. g_snprintf(tmp, ITEM_LABEL_LENGTH, format, value);
  4668. if (hfinfo->strings) {
  4669. const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
  4670. if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
  4671. label_fill(label_str, 0, hfinfo, val_str);
  4672. }
  4673. else {
  4674. label_fill_descr(label_str, 0, hfinfo, val_str, tmp);
  4675. }
  4676. }
  4677. else {
  4678. label_fill(label_str, 0, hfinfo, tmp);
  4679. }
  4680. }
  4681. int
  4682. hfinfo_bitshift(const header_field_info *hfinfo)
  4683. {
  4684. const guint32 bitmask = hfinfo->bitmask;
  4685. #if defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
  4686. g_assert(bitmask != 0);
  4687. return __builtin_ctz(bitmask);
  4688. #else
  4689. /* From http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup */
  4690. static const int table[32] = {
  4691. 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
  4692. 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
  4693. };
  4694. return table[((guint32)((bitmask & -(gint32)bitmask) * 0x077CB531U)) >> 27];
  4695. #endif
  4696. }
  4697. int
  4698. hfinfo_bitwidth(const header_field_info *hfinfo)
  4699. {
  4700. int bitwidth = 0;
  4701. if (!hfinfo->bitmask) {
  4702. return 0;
  4703. }
  4704. switch (hfinfo->type) {
  4705. case FT_UINT8:
  4706. case FT_INT8:
  4707. bitwidth = 8;
  4708. break;
  4709. case FT_UINT16:
  4710. case FT_INT16:
  4711. bitwidth = 16;
  4712. break;
  4713. case FT_UINT24:
  4714. case FT_INT24:
  4715. bitwidth = 24;
  4716. break;
  4717. case FT_UINT32:
  4718. case FT_INT32:
  4719. bitwidth = 32;
  4720. break;
  4721. case FT_BOOLEAN:
  4722. bitwidth = hfinfo->display; /* hacky? :) */
  4723. break;
  4724. default:
  4725. DISSECTOR_ASSERT_NOT_REACHED();
  4726. ;
  4727. }
  4728. return bitwidth;
  4729. }
  4730. static int
  4731. _hfinfo_type_hex_octet(int type)
  4732. {
  4733. switch (type) {
  4734. case FT_INT8:
  4735. case FT_UINT8:
  4736. return 2;
  4737. case FT_UINT16:
  4738. case FT_INT16:
  4739. return 4;
  4740. case FT_UINT24:
  4741. case FT_INT24:
  4742. return 6;
  4743. case FT_UINT32:
  4744. case FT_INT32:
  4745. return 8;
  4746. default:
  4747. DISSECTOR_ASSERT_NOT_REACHED();
  4748. ;
  4749. }
  4750. return -1;
  4751. }
  4752. /* private to_str.c API don't export to .h! */
  4753. char *oct_to_str_back(char *ptr, guint32 value);
  4754. char *hex_to_str_back(char *ptr, int pad, guint32 value);
  4755. char *uint_to_str_back(char *ptr, guint32 value);
  4756. char *int_to_str_back(char *ptr, gint32 value);
  4757. static const char *
  4758. hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
  4759. {
  4760. char *ptr = &buf[31];
  4761. gboolean isint = IS_FT_INT(hfinfo->type);
  4762. *ptr = '\0';
  4763. /* Properly format value */
  4764. switch (display) {
  4765. case BASE_DEC:
  4766. return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
  4767. case BASE_DEC_HEX:
  4768. *(--ptr) = ')';
  4769. ptr = hex_to_str_back(ptr, _hfinfo_type_hex_octet(hfinfo->type), value);
  4770. *(--ptr) = '(';
  4771. *(--ptr) = ' ';
  4772. ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
  4773. return ptr;
  4774. case BASE_OCT:
  4775. return oct_to_str_back(ptr, value);
  4776. case BASE_HEX:
  4777. return hex_to_str_back(ptr, _hfinfo_type_hex_octet(hfinfo->type), value);
  4778. case BASE_HEX_DEC:
  4779. *(--ptr) = ')';
  4780. ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
  4781. *(--ptr) = '(';
  4782. *(--ptr) = ' ';
  4783. ptr = hex_to_str_back(ptr, _hfinfo_type_hex_octet(hfinfo->type), value);
  4784. return ptr;
  4785. default:
  4786. DISSECTOR_ASSERT_NOT_REACHED();
  4787. ;
  4788. }
  4789. return ptr;
  4790. }
  4791. static const char *
  4792. hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
  4793. {
  4794. int display = hfinfo->display;
  4795. if (hfinfo->type == FT_FRAMENUM) {
  4796. /*
  4797. * Frame numbers are always displayed in decimal.
  4798. */
  4799. display = BASE_DEC;
  4800. }
  4801. return hfinfo_number_value_format_display(hfinfo, display, buf, value);
  4802. }
  4803. static const char *
  4804. hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
  4805. {
  4806. /* Get the underlying BASE_ value */
  4807. int display = hfinfo->display & BASE_DISPLAY_E_MASK;
  4808. if (hfinfo->type == FT_FRAMENUM) {
  4809. /*
  4810. * Frame numbers are always displayed in decimal.
  4811. */
  4812. display = BASE_DEC;
  4813. }
  4814. switch (display) {
  4815. case BASE_NONE:
  4816. /* case BASE_DEC: */
  4817. case BASE_DEC_HEX:
  4818. case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
  4819. case BASE_CUSTOM:
  4820. display = BASE_DEC;
  4821. break;
  4822. /* case BASE_HEX: */
  4823. case BASE_HEX_DEC:
  4824. display = BASE_HEX;
  4825. break;
  4826. }
  4827. return hfinfo_number_value_format_display(hfinfo, display, buf, value);
  4828. }
  4829. static const char *
  4830. hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
  4831. {
  4832. /* Get the underlying BASE_ value */
  4833. int display = hfinfo->display & BASE_DISPLAY_E_MASK;
  4834. if (display == BASE_NONE)
  4835. return NULL;
  4836. if (display == BASE_DEC_HEX)
  4837. display = BASE_DEC;
  4838. if (display == BASE_HEX_DEC)
  4839. display = BASE_HEX;
  4840. return hfinfo_number_value_format_display(hfinfo, display, buf, value);
  4841. }
  4842. static const char *
  4843. hfinfo_uint64_format(const header_field_info *hfinfo)
  4844. {
  4845. const char *format = NULL;
  4846. /* Pick the proper format string */
  4847. switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
  4848. case BASE_DEC:
  4849. format = "%" G_GINT64_MODIFIER "u";
  4850. break;
  4851. case BASE_DEC_HEX:
  4852. format = "%" G_GINT64_MODIFIER "u (0x%016" G_GINT64_MODIFIER "x)";
  4853. break;
  4854. case BASE_OCT: /* I'm lazy */
  4855. format = "%#" G_GINT64_MODIFIER "o";
  4856. break;
  4857. case BASE_HEX:
  4858. format = "0x%016" G_GINT64_MODIFIER "x";
  4859. break;
  4860. case BASE_HEX_DEC:
  4861. format = "0x%016" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "u)";
  4862. break;
  4863. default:
  4864. DISSECTOR_ASSERT_NOT_REACHED();
  4865. ;
  4866. }
  4867. return format;
  4868. }
  4869. static const char *
  4870. hfinfo_int64_format(const header_field_info *hfinfo)
  4871. {
  4872. const char *format = NULL;
  4873. /* Pick the proper format string */
  4874. switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
  4875. case BASE_DEC:
  4876. format = "%" G_GINT64_MODIFIER "d";
  4877. break;
  4878. case BASE_DEC_HEX:
  4879. format = "%" G_GINT64_MODIFIER "d (0x%016" G_GINT64_MODIFIER "x)";
  4880. break;
  4881. case BASE_OCT: /* I'm lazy */
  4882. format = "%#" G_GINT64_MODIFIER "o";
  4883. break;
  4884. case BASE_HEX:
  4885. format = "0x%016" G_GINT64_MODIFIER "x";
  4886. break;
  4887. case BASE_HEX_DEC:
  4888. format = "0x%016" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)";
  4889. break;
  4890. default:
  4891. DISSECTOR_ASSERT_NOT_REACHED();
  4892. ;
  4893. }
  4894. return format;
  4895. }
  4896. int
  4897. proto_registrar_n(void)
  4898. {
  4899. return gpa_hfinfo.len;
  4900. }
  4901. const char *
  4902. proto_registrar_get_name(const int n)
  4903. {
  4904. header_field_info *hfinfo;
  4905. PROTO_REGISTRAR_GET_NTH(n, hfinfo);
  4906. return hfinfo->name;
  4907. }
  4908. const char *
  4909. proto_registrar_get_abbrev(const int n)
  4910. {
  4911. header_field_info *hfinfo;
  4912. PROTO_REGISTRAR_GET_NTH(n, hfinfo);
  4913. return hfinfo->abbrev;
  4914. }
  4915. enum ftenum
  4916. proto_registrar_get_ftype(const int n)
  4917. {
  4918. header_field_info *hfinfo;
  4919. PROTO_REGISTRAR_GET_NTH(n, hfinfo);
  4920. return hfinfo->type;
  4921. }
  4922. int
  4923. proto_registrar_get_parent(const int n)
  4924. {
  4925. header_field_info *hfinfo;
  4926. PROTO_REGISTRAR_GET_NTH(n, hfinfo);
  4927. return hfinfo->parent;
  4928. }
  4929. gboolean
  4930. proto_registrar_is_protocol(const int n)
  4931. {
  4932. header_field_info *hfinfo;
  4933. PROTO_REGISTRAR_GET_NTH(n, hfinfo);
  4934. return (hfinfo->parent == -1 ? TRUE : FALSE);
  4935. }
  4936. /* Returns length of field in packet (not necessarily the length
  4937. * in our internal representation, as in the case of IPv4).
  4938. * 0 means undeterminable at time of registration
  4939. * -1 means the field is not registered. */
  4940. gint
  4941. proto_registrar_get_length(const int n)
  4942. {
  4943. header_field_info *hfinfo;
  4944. PROTO_REGISTRAR_GET_NTH(n, hfinfo);
  4945. return ftype_length(hfinfo->type);
  4946. }
  4947. /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
  4948. * it exists anywhere, or FALSE if it exists nowhere. */
  4949. gboolean
  4950. proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
  4951. {
  4952. GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
  4953. if (!ptrs) {
  4954. return FALSE;
  4955. }
  4956. else if (g_ptr_array_len(ptrs) > 0) {
  4957. return TRUE;
  4958. }
  4959. else {
  4960. return FALSE;
  4961. }
  4962. }
  4963. /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
  4964. * This only works if the hfindex was "primed" before the dissection
  4965. * took place, as we just pass back the already-created GPtrArray*.
  4966. * The caller should *not* free the GPtrArray*; proto_tree_free_node()
  4967. * handles that. */
  4968. GPtrArray *
  4969. proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
  4970. {
  4971. if (!tree)
  4972. return NULL;
  4973. if (PTREE_DATA(tree)->interesting_hfids != NULL)
  4974. return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
  4975. GINT_TO_POINTER(id));
  4976. else
  4977. return NULL;
  4978. }
  4979. gboolean
  4980. proto_tracking_interesting_fields(const proto_tree *tree)
  4981. {
  4982. if (!tree)
  4983. return FALSE;
  4984. return (PTREE_DATA(tree)->interesting_hfids != NULL);
  4985. }
  4986. /* Helper struct for proto_find_info() and proto_all_finfos() */
  4987. typedef struct {
  4988. GPtrArray *array;
  4989. int id;
  4990. } ffdata_t;
  4991. /* Helper function for proto_find_info() */
  4992. static gboolean
  4993. find_finfo(proto_node *node, gpointer data)
  4994. {
  4995. field_info *fi = PNODE_FINFO(node);
  4996. if (fi && fi->hfinfo) {
  4997. if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
  4998. g_ptr_array_add(((ffdata_t*)data)->array, fi);
  4999. }
  5000. }
  5001. /* Don't stop traversing. */
  5002. return FALSE;
  5003. }
  5004. /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
  5005. * This works on any proto_tree, primed or unprimed, but actually searches
  5006. * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
  5007. * The caller does need to free the returned GPtrArray with
  5008. * g_ptr_array_free(<array>, TRUE).
  5009. */
  5010. GPtrArray *
  5011. proto_find_finfo(proto_tree *tree, const int id)
  5012. {
  5013. ffdata_t ffdata;
  5014. ffdata.array = g_ptr_array_new();
  5015. ffdata.id = id;
  5016. proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
  5017. return ffdata.array;
  5018. }
  5019. /* Helper function for proto_all_finfos() */
  5020. static gboolean
  5021. every_finfo(proto_node *node, gpointer data)
  5022. {
  5023. field_info *fi = PNODE_FINFO(node);
  5024. if (fi && fi->hfinfo) {
  5025. g_ptr_array_add(((ffdata_t*)data)->array, fi);
  5026. }
  5027. /* Don't stop traversing. */
  5028. return FALSE;
  5029. }
  5030. /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
  5031. GPtrArray *
  5032. proto_all_finfos(proto_tree *tree)
  5033. {
  5034. ffdata_t ffdata;
  5035. ffdata.array = g_ptr_array_new();
  5036. ffdata.id = 0;
  5037. proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
  5038. return ffdata.array;
  5039. }
  5040. typedef struct {
  5041. guint offset;
  5042. field_info *finfo;
  5043. tvbuff_t *tvb;
  5044. } offset_search_t;
  5045. static gboolean
  5046. check_for_offset(proto_node *node, const gpointer data)
  5047. {
  5048. field_info *fi = PNODE_FINFO(node);
  5049. offset_search_t *offsearch = (offset_search_t *)data;
  5050. /* !fi == the top most container node which holds nothing */
  5051. if (fi && !PROTO_ITEM_IS_HIDDEN(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
  5052. if (offsearch->offset >= (guint) fi->start &&
  5053. offsearch->offset < (guint) (fi->start + fi->length)) {
  5054. offsearch->finfo = fi;
  5055. return FALSE; /* keep traversing */
  5056. }
  5057. }
  5058. return FALSE; /* keep traversing */
  5059. }
  5060. /* Search a proto_tree backwards (from leaves to root) looking for the field
  5061. * whose start/length occupies 'offset' */
  5062. /* XXX - I couldn't find an easy way to search backwards, so I search
  5063. * forwards, w/o stopping. Therefore, the last finfo I find will the be
  5064. * the one I want to return to the user. This algorithm is inefficient
  5065. * and could be re-done, but I'd have to handle all the children and
  5066. * siblings of each node myself. When I have more time I'll do that.
  5067. * (yeah right) */
  5068. field_info *
  5069. proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
  5070. {
  5071. offset_search_t offsearch;
  5072. offsearch.offset = offset;
  5073. offsearch.finfo = NULL;
  5074. offsearch.tvb = tvb;
  5075. proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
  5076. return offsearch.finfo;
  5077. }
  5078. /* Dumps the protocols in the registration database to stdout. An independent
  5079. * program can take this output and format it into nice tables or HTML or
  5080. * whatever.
  5081. *
  5082. * There is one record per line. The fields are tab-delimited.
  5083. *
  5084. * Field 1 = protocol name
  5085. * Field 2 = protocol short name
  5086. * Field 3 = protocol filter name
  5087. */
  5088. void
  5089. proto_registrar_dump_protocols(void)
  5090. {
  5091. protocol_t *protocol;
  5092. int i;
  5093. void *cookie = NULL;
  5094. i = proto_get_first_protocol(&cookie);
  5095. while (i != -1) {
  5096. protocol = find_protocol_by_id(i);
  5097. printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
  5098. protocol->filter_name);
  5099. i = proto_get_next_protocol(&cookie);
  5100. }
  5101. }
  5102. /* Dumps the value_strings, extended value string headers, range_strings
  5103. * or true/false strings for fields that have them.
  5104. * There is one record per line. Fields are tab-delimited.
  5105. * There are four types of records: Value String, Extended Value String Header,
  5106. * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
  5107. * the type of record.
  5108. *
  5109. * Note that a record will be generated only if the value_string,... is referenced
  5110. * in a registered hfinfo entry.
  5111. *
  5112. *
  5113. * Value Strings
  5114. * -------------
  5115. * Field 1 = 'V'
  5116. * Field 2 = Field abbreviation to which this value string corresponds
  5117. * Field 3 = Integer value
  5118. * Field 4 = String
  5119. *
  5120. * Extended Value String Headers
  5121. * -----------------------------
  5122. * Field 1 = 'E'
  5123. * Field 2 = Field abbreviation to which this extended value string header corresponds
  5124. * Field 3 = Extended Value String "Name"
  5125. * Field 4 = Number of entries in the associated value_string array
  5126. * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
  5127. *
  5128. * Range Strings
  5129. * -------------
  5130. * Field 1 = 'R'
  5131. * Field 2 = Field abbreviation to which this range string corresponds
  5132. * Field 3 = Integer value: lower bound
  5133. * Field 4 = Integer value: upper bound
  5134. * Field 5 = String
  5135. *
  5136. * True/False Strings
  5137. * ------------------
  5138. * Field 1 = 'T'
  5139. * Field 2 = Field abbreviation to which this true/false string corresponds
  5140. * Field 3 = True String
  5141. * Field 4 = False String
  5142. */
  5143. void
  5144. proto_registrar_dump_values(void)
  5145. {
  5146. header_field_info *hfinfo;
  5147. int i, len, vi;
  5148. const value_string *vals;
  5149. const val64_string *vals64;
  5150. const range_string *range;
  5151. const true_false_string *tfs;
  5152. len = gpa_hfinfo.len;
  5153. for (i = 0; i < len ; i++) {
  5154. PROTO_REGISTRAR_GET_NTH(i, hfinfo);
  5155. if (hfinfo->id == hf_text_only) {
  5156. continue;
  5157. }
  5158. /* ignore protocols */
  5159. if (proto_registrar_is_protocol(i)) {
  5160. continue;
  5161. }
  5162. /* process header fields */
  5163. else {
  5164. /*
  5165. * If this field isn't at the head of the list of
  5166. * fields with this name, skip this field - all
  5167. * fields with the same name are really just versions
  5168. * of the same field stored in different bits, and
  5169. * should have the same type/radix/value list, and
  5170. * just differ in their bit masks. (If a field isn't
  5171. * a bitfield, but can be, say, 1 or 2 bytes long,
  5172. * it can just be made FT_UINT16, meaning the
  5173. * *maximum* length is 2 bytes, and be used
  5174. * for all lengths.)
  5175. */
  5176. if (hfinfo->same_name_prev_id != -1)
  5177. continue;
  5178. vals = NULL;
  5179. vals64 = NULL;
  5180. range = NULL;
  5181. tfs = NULL;
  5182. if (hfinfo->strings != NULL) {
  5183. if ((hfinfo->display & BASE_DISPLAY_E_MASK) != BASE_CUSTOM &&
  5184. (hfinfo->type == FT_UINT8 ||
  5185. hfinfo->type == FT_UINT16 ||
  5186. hfinfo->type == FT_UINT24 ||
  5187. hfinfo->type == FT_UINT32 ||
  5188. hfinfo->type == FT_UINT64 ||
  5189. hfinfo->type == FT_INT8 ||
  5190. hfinfo->type == FT_INT16 ||
  5191. hfinfo->type == FT_INT24 ||
  5192. hfinfo->type == FT_INT32 ||
  5193. hfinfo->type == FT_INT64)) {
  5194. if (hfinfo->display & BASE_EXT_STRING) {
  5195. vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings);
  5196. } else if ((hfinfo->display & BASE_RANGE_STRING) == 0) {
  5197. vals = (const value_string *)hfinfo->strings;
  5198. } else if ((hfinfo->display & BASE_VAL64_STRING) == 0) {
  5199. vals64 = (const val64_string *)hfinfo->strings;
  5200. } else {
  5201. range = (const range_string *)hfinfo->strings;
  5202. }
  5203. }
  5204. else if (hfinfo->type == FT_BOOLEAN) {
  5205. tfs = (const struct true_false_string *)hfinfo->strings;
  5206. }
  5207. }
  5208. /* Print value strings? */
  5209. if (vals) {
  5210. if (hfinfo->display & BASE_EXT_STRING) {
  5211. const value_string_ext *vse_p = (const value_string_ext *)hfinfo->strings;
  5212. if (!value_string_ext_validate(vse_p)) {
  5213. g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
  5214. continue;
  5215. }
  5216. try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
  5217. printf("E\t%s\t%d\t%s\t%s\n",
  5218. hfinfo->abbrev,
  5219. VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
  5220. VALUE_STRING_EXT_VS_NAME(vse_p),
  5221. value_string_ext_match_type_str(vse_p));
  5222. }
  5223. vi = 0;
  5224. while (vals[vi].strptr) {
  5225. /* Print in the proper base */
  5226. if (hfinfo->display == BASE_HEX) {
  5227. printf("V\t%s\t0x%x\t%s\n",
  5228. hfinfo->abbrev,
  5229. vals[vi].value,
  5230. vals[vi].strptr);
  5231. }
  5232. else {
  5233. printf("V\t%s\t%u\t%s\n",
  5234. hfinfo->abbrev,
  5235. vals[vi].value,
  5236. vals[vi].strptr);
  5237. }
  5238. vi++;
  5239. }
  5240. }
  5241. else if (vals64) {
  5242. vi = 0;
  5243. while (vals64[vi].strptr) {
  5244. printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
  5245. hfinfo->abbrev,
  5246. vals64[vi].value,
  5247. vals64[vi].strptr);
  5248. vi++;
  5249. }
  5250. }
  5251. /* print range strings? */
  5252. else if (range) {
  5253. vi = 0;
  5254. while (range[vi].strptr) {
  5255. /* Print in the proper base */
  5256. if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_HEX) {
  5257. printf("R\t%s\t0x%x\t0x%x\t%s\n",
  5258. hfinfo->abbrev,
  5259. range[vi].value_min,
  5260. range[vi].value_max,
  5261. range[vi].strptr);
  5262. }
  5263. else {
  5264. printf("R\t%s\t%u\t%u\t%s\n",
  5265. hfinfo->abbrev,
  5266. range[vi].value_min,
  5267. range[vi].value_max,
  5268. range[vi].strptr);
  5269. }
  5270. vi++;
  5271. }
  5272. }
  5273. /* Print true/false strings? */
  5274. else if (tfs) {
  5275. printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
  5276. tfs->true_string, tfs->false_string);
  5277. }
  5278. }
  5279. }
  5280. }
  5281. /* Dumps the contents of the registration database to stdout. An independent
  5282. * program can take this output and format it into nice tables or HTML or
  5283. * whatever.
  5284. *
  5285. * There is one record per line. Each record is either a protocol or a header
  5286. * field, differentiated by the first field. The fields are tab-delimited.
  5287. *
  5288. * Protocols
  5289. * ---------
  5290. * Field 1 = 'P'
  5291. * Field 2 = descriptive protocol name
  5292. * Field 3 = protocol abbreviation
  5293. *
  5294. * Header Fields
  5295. * -------------
  5296. * Field 1 = 'F'
  5297. * Field 2 = descriptive field name
  5298. * Field 3 = field abbreviation
  5299. * Field 4 = type ( textual representation of the the ftenum type )
  5300. * Field 5 = parent protocol abbreviation
  5301. * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
  5302. * Field 7 = bitmask: format: hex: 0x....
  5303. * Field 8 = blurb describing field
  5304. */
  5305. void
  5306. proto_registrar_dump_fields(void)
  5307. {
  5308. header_field_info *hfinfo, *parent_hfinfo;
  5309. int i, len;
  5310. const char *enum_name;
  5311. const char *base_name;
  5312. const char *blurb;
  5313. char width[5];
  5314. len = gpa_hfinfo.len;
  5315. for (i = 0; i < len ; i++) {
  5316. PROTO_REGISTRAR_GET_NTH(i, hfinfo);
  5317. /*
  5318. * Skip the pseudo-field for "proto_tree_add_text()" since
  5319. * we don't want it in the list of filterable fields.
  5320. */
  5321. if (hfinfo->id == hf_text_only)
  5322. continue;
  5323. /* format for protocols */
  5324. if (proto_registrar_is_protocol(i)) {
  5325. printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
  5326. }
  5327. /* format for header fields */
  5328. else {
  5329. /*
  5330. * If this field isn't at the head of the list of
  5331. * fields with this name, skip this field - all
  5332. * fields with the same name are really just versions
  5333. * of the same field stored in different bits, and
  5334. * should have the same type/radix/value list, and
  5335. * just differ in their bit masks. (If a field isn't
  5336. * a bitfield, but can be, say, 1 or 2 bytes long,
  5337. * it can just be made FT_UINT16, meaning the
  5338. * *maximum* length is 2 bytes, and be used
  5339. * for all lengths.)
  5340. */
  5341. if (hfinfo->same_name_prev_id != -1)
  5342. continue;
  5343. PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
  5344. enum_name = ftype_name(hfinfo->type);
  5345. base_name = "";
  5346. if (hfinfo->type == FT_UINT8 ||
  5347. hfinfo->type == FT_UINT16 ||
  5348. hfinfo->type == FT_UINT24 ||
  5349. hfinfo->type == FT_UINT32 ||
  5350. hfinfo->type == FT_UINT64 ||
  5351. hfinfo->type == FT_INT8 ||
  5352. hfinfo->type == FT_INT16 ||
  5353. hfinfo->type == FT_INT24 ||
  5354. hfinfo->type == FT_INT32 ||
  5355. hfinfo->type == FT_INT64) {
  5356. switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
  5357. case BASE_NONE:
  5358. base_name = "BASE_NONE";
  5359. break;
  5360. case BASE_DEC:
  5361. base_name = "BASE_DEC";
  5362. break;
  5363. case BASE_HEX:
  5364. base_name = "BASE_HEX";
  5365. break;
  5366. case BASE_OCT:
  5367. base_name = "BASE_OCT";
  5368. break;
  5369. case BASE_DEC_HEX:
  5370. base_name = "BASE_DEC_HEX";
  5371. break;
  5372. case BASE_HEX_DEC:
  5373. base_name = "BASE_HEX_DEC";
  5374. break;
  5375. case BASE_CUSTOM:
  5376. base_name = "BASE_CUSTOM";
  5377. break;
  5378. default:
  5379. base_name = "????";
  5380. break;
  5381. }
  5382. } else if (hfinfo->type == FT_BOOLEAN) {
  5383. /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
  5384. g_snprintf(width, sizeof(width), "%d", hfinfo->display);
  5385. base_name = width;
  5386. }
  5387. blurb = hfinfo->blurb;
  5388. if (blurb == NULL)
  5389. blurb = "";
  5390. else if (strlen(blurb) == 0)
  5391. blurb = "\"\"";
  5392. printf("F\t%s\t%s\t%s\t%s\t%s\t0x%x\t%s\n",
  5393. hfinfo->name, hfinfo->abbrev, enum_name,
  5394. parent_hfinfo->abbrev, base_name, hfinfo->bitmask, blurb);
  5395. }
  5396. }
  5397. }
  5398. /* Dumps field types and descriptive names to stdout. An independent
  5399. * program can take this output and format it into nice tables or HTML or
  5400. * whatever.
  5401. *
  5402. * There is one record per line. The fields are tab-delimited.
  5403. *
  5404. * Field 1 = field type name, e.g. FT_UINT8
  5405. * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
  5406. */
  5407. void
  5408. proto_registrar_dump_ftypes(void)
  5409. {
  5410. int fte;
  5411. for (fte = 0; fte < FT_NUM_TYPES; fte++) {
  5412. printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
  5413. }
  5414. }
  5415. static const char *
  5416. hfinfo_numeric_format(const header_field_info *hfinfo)
  5417. {
  5418. const char *format = NULL;
  5419. /* Get the underlying BASE_ value */
  5420. switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
  5421. case BASE_DEC:
  5422. case BASE_DEC_HEX:
  5423. case BASE_OCT: /* I'm lazy */
  5424. case BASE_CUSTOM:
  5425. switch (hfinfo->type) {
  5426. case FT_UINT64:
  5427. format = "%s == %" G_GINT64_MODIFIER "u";
  5428. break;
  5429. case FT_INT64:
  5430. format = "%s == %" G_GINT64_MODIFIER "d";
  5431. break;
  5432. default:
  5433. DISSECTOR_ASSERT_NOT_REACHED();
  5434. ;
  5435. }
  5436. break;
  5437. case BASE_HEX:
  5438. case BASE_HEX_DEC:
  5439. switch (hfinfo->type) {
  5440. case FT_UINT64:
  5441. case FT_INT64:
  5442. format = "%s == 0x%016" G_GINT64_MODIFIER "x";
  5443. break;
  5444. default:
  5445. DISSECTOR_ASSERT_NOT_REACHED();
  5446. ;
  5447. }
  5448. break;
  5449. default:
  5450. DISSECTOR_ASSERT_NOT_REACHED();
  5451. ;
  5452. }
  5453. return format;
  5454. }
  5455. /* This function indicates whether it's possible to construct a
  5456. * "match selected" display filter string for the specified field,
  5457. * returns an indication of whether it's possible, and, if it's
  5458. * possible and "filter" is non-null, constructs the filter and
  5459. * sets "*filter" to point to it.
  5460. * You do not need to [g_]free() this string since it will be automatically
  5461. * freed once the next packet is dissected.
  5462. */
  5463. static gboolean
  5464. construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
  5465. char **filter)
  5466. {
  5467. header_field_info *hfinfo;
  5468. int abbrev_len;
  5469. char *ptr;
  5470. int buf_len;
  5471. int dfilter_len, i;
  5472. gint start, length, length_remaining;
  5473. guint8 c;
  5474. gchar is_signed_num = FALSE;
  5475. if (!finfo)
  5476. return FALSE;
  5477. hfinfo = finfo->hfinfo;
  5478. DISSECTOR_ASSERT(hfinfo);
  5479. abbrev_len = (int) strlen(hfinfo->abbrev);
  5480. if (hfinfo->strings && (hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
  5481. const gchar *str = NULL;
  5482. switch (hfinfo->type) {
  5483. case FT_INT8:
  5484. case FT_INT16:
  5485. case FT_INT24:
  5486. case FT_INT32:
  5487. str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
  5488. break;
  5489. case FT_UINT8:
  5490. case FT_UINT16:
  5491. case FT_UINT24:
  5492. case FT_UINT32:
  5493. str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
  5494. break;
  5495. default:
  5496. break;
  5497. }
  5498. if (str != NULL && filter != NULL) {
  5499. *filter = ep_strdup_printf("%s == \"%s\"", hfinfo->abbrev, str);
  5500. return TRUE;
  5501. }
  5502. }
  5503. /*
  5504. * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
  5505. * functions for FT_UINT and FT_INT types, as we choose the base in
  5506. * the string expression based on the display base of the field.
  5507. *
  5508. * Note that the base does matter, as this is also used for
  5509. * the protocolinfo tap.
  5510. *
  5511. * It might be nice to use them in "proto_item_fill_label()"
  5512. * as well, although, there, you'd have to deal with the base
  5513. * *and* with resolved values for addresses.
  5514. *
  5515. * Perhaps we need two different val_to_string routines, one
  5516. * to generate items for display filters and one to generate
  5517. * strings for display, and pass to both of them the
  5518. * "display" and "strings" values in the header_field_info
  5519. * structure for the field, so they can get the base and,
  5520. * if the field is Boolean or an enumerated integer type,
  5521. * the tables used to generate human-readable values.
  5522. */
  5523. switch (hfinfo->type) {
  5524. case FT_INT8:
  5525. case FT_INT16:
  5526. case FT_INT24:
  5527. case FT_INT32:
  5528. is_signed_num = TRUE;
  5529. /* FALLTHRU */
  5530. case FT_UINT8:
  5531. case FT_UINT16:
  5532. case FT_UINT24:
  5533. case FT_UINT32:
  5534. case FT_FRAMENUM:
  5535. if (filter != NULL) {
  5536. guint32 number;
  5537. char buf[32];
  5538. const char *out;
  5539. if (is_signed_num)
  5540. number = fvalue_get_sinteger(&finfo->value);
  5541. else
  5542. number = fvalue_get_uinteger(&finfo->value);
  5543. out = hfinfo_numeric_value_format(hfinfo, buf, number);
  5544. *filter = ep_strdup_printf("%s == %s", hfinfo->abbrev, out);
  5545. }
  5546. break;
  5547. case FT_INT64:
  5548. case FT_UINT64:
  5549. if (filter != NULL) {
  5550. const char *format = hfinfo_numeric_format(hfinfo);
  5551. *filter = ep_strdup_printf(format,
  5552. hfinfo->abbrev,
  5553. fvalue_get_integer64(&finfo->value));
  5554. }
  5555. break;
  5556. case FT_PROTOCOL:
  5557. if (filter != NULL)
  5558. *filter = ep_strdup(finfo->hfinfo->abbrev);
  5559. break;
  5560. case FT_NONE:
  5561. /*
  5562. * If the length is 0, just match the name of the
  5563. * field.
  5564. *
  5565. * (Also check for negative values, just in case,
  5566. * as we'll cast it to an unsigned value later.)
  5567. */
  5568. length = finfo->length;
  5569. if (length == 0) {
  5570. if (filter != NULL)
  5571. *filter = ep_strdup(finfo->hfinfo->abbrev);
  5572. break;
  5573. }
  5574. if (length < 0)
  5575. return FALSE;
  5576. /*
  5577. * This doesn't have a value, so we'd match
  5578. * on the raw bytes at this address.
  5579. *
  5580. * Should we be allowed to access to the raw bytes?
  5581. * If "edt" is NULL, the answer is "no".
  5582. */
  5583. if (edt == NULL)
  5584. return FALSE;
  5585. /*
  5586. * Is this field part of the raw frame tvbuff?
  5587. * If not, we can't use "frame[N:M]" to match
  5588. * it.
  5589. *
  5590. * XXX - should this be frame-relative, or
  5591. * protocol-relative?
  5592. *
  5593. * XXX - does this fallback for non-registered
  5594. * fields even make sense?
  5595. */
  5596. if (finfo->ds_tvb != edt->tvb)
  5597. return FALSE; /* you lose */
  5598. /*
  5599. * Don't go past the end of that tvbuff.
  5600. */
  5601. length_remaining = tvb_length_remaining(finfo->ds_tvb, finfo->start);
  5602. if (length > length_remaining)
  5603. length = length_remaining;
  5604. if (length <= 0)
  5605. return FALSE;
  5606. if (filter != NULL) {
  5607. start = finfo->start;
  5608. buf_len = 32 + length * 3;
  5609. *filter = (char *)ep_alloc0(buf_len);
  5610. ptr = *filter;
  5611. ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
  5612. "frame[%d:%d] == ", finfo->start, length);
  5613. for (i=0; i<length; i++) {
  5614. c = tvb_get_guint8(finfo->ds_tvb, start);
  5615. start++;
  5616. if (i == 0 ) {
  5617. ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
  5618. }
  5619. else {
  5620. ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
  5621. }
  5622. }
  5623. }
  5624. break;
  5625. case FT_PCRE:
  5626. /* FT_PCRE never appears as a type for a registered field. It is
  5627. * only used internally. */
  5628. DISSECTOR_ASSERT_NOT_REACHED();
  5629. break;
  5630. /* By default, use the fvalue's "to_string_repr" method. */
  5631. default:
  5632. /* Figure out the string length needed.
  5633. * The ft_repr length.
  5634. * 4 bytes for " == ".
  5635. * 1 byte for trailing NUL.
  5636. */
  5637. if (filter != NULL) {
  5638. dfilter_len = fvalue_string_repr_len(&finfo->value,
  5639. FTREPR_DFILTER);
  5640. dfilter_len += abbrev_len + 4 + 1;
  5641. *filter = (char *)ep_alloc0(dfilter_len);
  5642. /* Create the string */
  5643. g_snprintf(*filter, dfilter_len, "%s == ",
  5644. hfinfo->abbrev);
  5645. fvalue_to_string_repr(&finfo->value,
  5646. FTREPR_DFILTER,
  5647. &(*filter)[abbrev_len + 4]);
  5648. }
  5649. break;
  5650. }
  5651. return TRUE;
  5652. }
  5653. /*
  5654. * Returns TRUE if we can do a "match selected" on the field, FALSE
  5655. * otherwise.
  5656. */
  5657. gboolean
  5658. proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
  5659. {
  5660. return construct_match_selected_string(finfo, edt, NULL);
  5661. }
  5662. /* This function attempts to construct a "match selected" display filter
  5663. * string for the specified field; if it can do so, it returns a pointer
  5664. * to the string, otherwise it returns NULL.
  5665. *
  5666. * The string is allocated with packet lifetime scope.
  5667. * You do not need to [g_]free() this string since it will be automatically
  5668. * freed once the next packet is dissected.
  5669. */
  5670. char *
  5671. proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
  5672. {
  5673. char *filter;
  5674. if (!construct_match_selected_string(finfo, edt, &filter))
  5675. return NULL;
  5676. return filter;
  5677. }
  5678. /* This function is common code for both proto_tree_add_bitmask() and
  5679. * proto_tree_add_bitmask_text() functions.
  5680. */
  5681. /* NOTE: to support code written when proto_tree_add_bitmask() and
  5682. * proto_tree_add_bitmask_text took a
  5683. * gboolean as its last argument, with FALSE meaning "big-endian"
  5684. * and TRUE meaning "little-endian", we treat any non-zero value of
  5685. * "encoding" as meaning "little-endian".
  5686. */
  5687. static gboolean
  5688. proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
  5689. const int len, const gint ett, const int **fields,
  5690. const guint encoding, const int flags,
  5691. gboolean first)
  5692. {
  5693. guint32 value = 0;
  5694. guint32 available_bits = 0;
  5695. guint32 tmpval;
  5696. proto_tree *tree = NULL;
  5697. header_field_info *hf;
  5698. switch (len) {
  5699. case 1:
  5700. value = tvb_get_guint8(tvb, offset);
  5701. available_bits = 0xFF;
  5702. break;
  5703. case 2:
  5704. value = encoding ? tvb_get_letohs(tvb, offset) :
  5705. tvb_get_ntohs(tvb, offset);
  5706. available_bits = 0xFFFF;
  5707. break;
  5708. case 3:
  5709. value = encoding ? tvb_get_letoh24(tvb, offset) :
  5710. tvb_get_ntoh24(tvb, offset);
  5711. available_bits = 0xFFFFFF;
  5712. break;
  5713. case 4:
  5714. value = encoding ? tvb_get_letohl(tvb, offset) :
  5715. tvb_get_ntohl(tvb, offset);
  5716. available_bits = 0xFFFFFFFF;
  5717. break;
  5718. default:
  5719. g_assert_not_reached();
  5720. }
  5721. tree = proto_item_add_subtree(item, ett);
  5722. while (*fields) {
  5723. guint32 present_bits;
  5724. hf = proto_registrar_get_nth(**fields);
  5725. DISSECTOR_ASSERT(hf->bitmask != 0);
  5726. /* Skip fields that aren't fully present */
  5727. present_bits = available_bits & hf->bitmask;
  5728. if (present_bits != hf->bitmask) {
  5729. fields++;
  5730. continue;
  5731. }
  5732. proto_tree_add_item(tree, **fields, tvb, offset, len, encoding);
  5733. if (flags & BMT_NO_APPEND) {
  5734. fields++;
  5735. continue;
  5736. }
  5737. tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
  5738. switch (hf->type) {
  5739. case FT_INT8:
  5740. case FT_UINT8:
  5741. case FT_INT16:
  5742. case FT_UINT16:
  5743. case FT_INT24:
  5744. case FT_UINT24:
  5745. case FT_INT32:
  5746. case FT_UINT32:
  5747. if (hf->display == BASE_CUSTOM) {
  5748. gchar lbl[ITEM_LABEL_LENGTH];
  5749. const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
  5750. DISSECTOR_ASSERT(fmtfunc);
  5751. fmtfunc(lbl, tmpval);
  5752. proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
  5753. hf->name, lbl);
  5754. first = FALSE;
  5755. }
  5756. else if (hf->strings) {
  5757. proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
  5758. hf->name, hf_try_val_to_str_const(tmpval, hf, "Unknown"));
  5759. first = FALSE;
  5760. }
  5761. else if (!(flags & BMT_NO_INT)) {
  5762. char buf[32];
  5763. const char *out;
  5764. if (!first) {
  5765. proto_item_append_text(item, ", ");
  5766. }
  5767. out = hfinfo_number_value_format(hf, buf, tmpval);
  5768. proto_item_append_text(item, "%s: %s", hf->name, out);
  5769. first = FALSE;
  5770. }
  5771. break;
  5772. case FT_BOOLEAN:
  5773. if (hf->strings && !(flags & BMT_NO_TFS)) {
  5774. /* If we have true/false strings, emit full - otherwise messages
  5775. might look weird */
  5776. const struct true_false_string *tfs =
  5777. (const struct true_false_string *)hf->strings;
  5778. if (tmpval) {
  5779. proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
  5780. hf->name, tfs->true_string);
  5781. first = FALSE;
  5782. } else if (!(flags & BMT_NO_FALSE)) {
  5783. proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
  5784. hf->name, tfs->false_string);
  5785. first = FALSE;
  5786. }
  5787. } else if (hf->bitmask & value) {
  5788. /* If the flag is set, show the name */
  5789. proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
  5790. first = FALSE;
  5791. }
  5792. break;
  5793. default:
  5794. g_assert_not_reached();
  5795. }
  5796. fields++;
  5797. }
  5798. return first;
  5799. }
  5800. /* This function will dissect a sequence of bytes that describe a
  5801. * bitmask.
  5802. * hf_hdr is a 8/16/24/32 bit integer that describes the bitmask to be dissected.
  5803. * This field will form an expansion under which the individual fields of the
  5804. * bitmask is dissected and displayed.
  5805. * This field must be of the type FT_[U]INT{8|16|24|32}.
  5806. *
  5807. * fields is an array of pointers to int that lists all the fields of the
  5808. * bitmask. These fields can be either of the type FT_BOOLEAN for flags
  5809. * or another integer of the same type/size as hf_hdr with a mask specified.
  5810. * This array is terminated by a NULL entry.
  5811. *
  5812. * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
  5813. * FT_integer fields that have a value_string attached will have the
  5814. * matched string displayed on the expansion line.
  5815. */
  5816. proto_item *
  5817. proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
  5818. const guint offset, const int hf_hdr,
  5819. const gint ett, const int **fields,
  5820. const guint encoding)
  5821. {
  5822. proto_item *item = NULL;
  5823. header_field_info *hf;
  5824. int len;
  5825. hf = proto_registrar_get_nth(hf_hdr);
  5826. DISSECTOR_ASSERT(IS_FT_INT(hf->type) || IS_FT_UINT(hf->type));
  5827. len = ftype_length(hf->type);
  5828. if (parent_tree) {
  5829. item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
  5830. proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields, encoding,
  5831. BMT_NO_INT|BMT_NO_TFS, FALSE);
  5832. }
  5833. return item;
  5834. }
  5835. /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
  5836. * This is intended to support bitmask fields whose lengths can vary, perhaps
  5837. * as the underlying standard evolves over time.
  5838. * With this API there is the possibility of being called to display more or
  5839. * less data than the dissector was coded to support.
  5840. * In such cases, it is assumed that bitmasks are extended on the MSb end.
  5841. * Thus when presented with "too much" or "too little" data, MSbits will be
  5842. * ignored or MSfields sacrificed.
  5843. *
  5844. * Only fields for which all defined bits are available are displayed.
  5845. */
  5846. proto_item *
  5847. proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
  5848. const guint offset, const guint len, const int hf_hdr,
  5849. const gint ett, const int **fields,
  5850. const guint encoding)
  5851. {
  5852. proto_item *item = NULL;
  5853. header_field_info *hf;
  5854. hf = proto_registrar_get_nth(hf_hdr);
  5855. DISSECTOR_ASSERT(IS_FT_INT(hf->type) || IS_FT_UINT(hf->type));
  5856. if (parent_tree) {
  5857. guint decodable_len;
  5858. guint decodable_offset;
  5859. guint32 decodable_value;
  5860. decodable_offset = offset;
  5861. decodable_len = MIN(len, (guint) ftype_length(hf->type));
  5862. /* If we are ftype_length-limited,
  5863. * make sure we decode as many LSBs as possible.
  5864. */
  5865. if (encoding == ENC_BIG_ENDIAN) {
  5866. decodable_offset += (len - decodable_len);
  5867. }
  5868. decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
  5869. decodable_len, encoding);
  5870. /* The root item covers all the bytes even if we can't decode them all */
  5871. item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
  5872. decodable_value);
  5873. if (decodable_len < len) {
  5874. /* Dissector likely requires updating for new protocol revision */
  5875. expert_add_info_format(NULL, item, PI_UNDECODED, PI_WARN,
  5876. "Only least-significant %d of %d bytes decoded",
  5877. decodable_len, len);
  5878. }
  5879. proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
  5880. ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS, FALSE);
  5881. }
  5882. return item;
  5883. }
  5884. /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
  5885. proto_item *
  5886. proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
  5887. const guint offset, const guint len,
  5888. const char *name, const char *fallback,
  5889. const gint ett, const int **fields,
  5890. const guint encoding, const int flags)
  5891. {
  5892. proto_item *item = NULL;
  5893. if (parent_tree) {
  5894. item = proto_tree_add_text(parent_tree, tvb, offset, len, "%s", name ? name : "");
  5895. if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields, encoding,
  5896. flags, TRUE) && fallback) {
  5897. /* Still at first item - append 'fallback' text if any */
  5898. proto_item_append_text(item, "%s", fallback);
  5899. }
  5900. }
  5901. return item;
  5902. }
  5903. proto_item *
  5904. proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
  5905. const guint bit_offset, const gint no_of_bits,
  5906. const guint encoding)
  5907. {
  5908. header_field_info *hfinfo;
  5909. gint octet_length;
  5910. gint octet_offset;
  5911. PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
  5912. octet_length = (no_of_bits + 7) >> 3;
  5913. octet_offset = bit_offset >> 3;
  5914. test_length(hfinfo, tree, tvb, octet_offset, octet_length, encoding);
  5915. /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
  5916. * but only after doing a bunch more work (which we can, in the common
  5917. * case, shortcut here).
  5918. */
  5919. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
  5920. return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
  5921. }
  5922. /*
  5923. * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
  5924. * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
  5925. * Offset should be given in bits from the start of the tvb.
  5926. */
  5927. static proto_item *
  5928. _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
  5929. const guint bit_offset, const gint no_of_bits,
  5930. guint64 *return_value, const guint encoding)
  5931. {
  5932. gint offset;
  5933. guint length;
  5934. guint8 tot_no_bits;
  5935. char *bf_str;
  5936. char lbl_str[ITEM_LABEL_LENGTH];
  5937. guint64 value = 0;
  5938. proto_item *pi;
  5939. header_field_info *hf_field;
  5940. const true_false_string *tfstring;
  5941. /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
  5942. PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
  5943. if (hf_field->bitmask != 0) {
  5944. REPORT_DISSECTOR_BUG(ep_strdup_printf("Incompatible use of proto_tree_add_bits_ret_val"
  5945. " with field '%s' (%s) with bitmask != 0",
  5946. hf_field->abbrev, hf_field->name));
  5947. }
  5948. DISSECTOR_ASSERT(no_of_bits > 0);
  5949. /* Byte align offset */
  5950. offset = bit_offset>>3;
  5951. /*
  5952. * Calculate the number of octets used to hold the bits
  5953. */
  5954. tot_no_bits = ((bit_offset&0x7) + no_of_bits);
  5955. length = (tot_no_bits + 7) >> 3;
  5956. if (no_of_bits < 65) {
  5957. value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
  5958. } else {
  5959. DISSECTOR_ASSERT_NOT_REACHED();
  5960. return NULL;
  5961. }
  5962. /* Sign extend for signed types */
  5963. switch (hf_field->type) {
  5964. case FT_INT8:
  5965. case FT_INT16:
  5966. case FT_INT24:
  5967. case FT_INT32:
  5968. case FT_INT64:
  5969. if (value & (G_GINT64_CONSTANT(1) << (no_of_bits-1)))
  5970. value |= (G_GINT64_CONSTANT(-1) << no_of_bits);
  5971. break;
  5972. default:
  5973. break;
  5974. }
  5975. if (return_value) {
  5976. *return_value = value;
  5977. }
  5978. /* Coast clear. Try and fake it */
  5979. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
  5980. bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
  5981. switch (hf_field->type) {
  5982. case FT_BOOLEAN:
  5983. /* Boolean field */
  5984. tfstring = (const true_false_string *) &tfs_true_false;
  5985. if (hf_field->strings)
  5986. tfstring = (const true_false_string *)hf_field->strings;
  5987. return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
  5988. "%s = %s: %s",
  5989. bf_str, hf_field->name,
  5990. (guint32)value ? tfstring->true_string : tfstring->false_string);
  5991. break;
  5992. case FT_UINT8:
  5993. case FT_UINT16:
  5994. case FT_UINT24:
  5995. case FT_UINT32:
  5996. pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
  5997. fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
  5998. break;
  5999. case FT_INT8:
  6000. case FT_INT16:
  6001. case FT_INT24:
  6002. case FT_INT32:
  6003. pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
  6004. fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
  6005. break;
  6006. case FT_UINT64:
  6007. pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
  6008. fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
  6009. break;
  6010. case FT_INT64:
  6011. pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
  6012. fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
  6013. break;
  6014. default:
  6015. DISSECTOR_ASSERT_NOT_REACHED();
  6016. return NULL;
  6017. break;
  6018. }
  6019. proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
  6020. return pi;
  6021. }
  6022. proto_item *
  6023. proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
  6024. const guint bit_offset, const crumb_spec_t *crumb_spec,
  6025. guint64 *return_value)
  6026. {
  6027. proto_item *pi;
  6028. gint no_of_bits;
  6029. gint octet_offset;
  6030. guint mask_initial_bit_offset;
  6031. guint mask_greatest_bit_offset;
  6032. guint octet_length;
  6033. guint8 i;
  6034. char *bf_str;
  6035. char lbl_str[ITEM_LABEL_LENGTH];
  6036. guint64 value;
  6037. guint64 composite_bitmask;
  6038. guint64 composite_bitmap;
  6039. header_field_info *hf_field;
  6040. const true_false_string *tfstring;
  6041. /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
  6042. PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
  6043. if (hf_field->bitmask != 0) {
  6044. REPORT_DISSECTOR_BUG(ep_strdup_printf(
  6045. "Incompatible use of proto_tree_add_split_bits_item_ret_val"
  6046. " with field '%s' (%s) with bitmask != 0",
  6047. hf_field->abbrev, hf_field->name));
  6048. }
  6049. mask_initial_bit_offset = bit_offset % 8;
  6050. no_of_bits = 0;
  6051. value = 0;
  6052. i = 0;
  6053. mask_greatest_bit_offset = 0;
  6054. composite_bitmask = 0;
  6055. composite_bitmap = 0;
  6056. while (crumb_spec[i].crumb_bit_length != 0) {
  6057. guint64 crumb_mask, crumb_value;
  6058. guint8 crumb_end_bit_offset;
  6059. DISSECTOR_ASSERT(i < 64);
  6060. crumb_value = tvb_get_bits64(tvb,
  6061. bit_offset + crumb_spec[i].crumb_bit_offset,
  6062. crumb_spec[i].crumb_bit_length,
  6063. ENC_BIG_ENDIAN);
  6064. value += crumb_value;
  6065. no_of_bits += crumb_spec[i].crumb_bit_length;
  6066. /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
  6067. octet containing the initial offset.
  6068. If the mask is beyond 32 bits, then give up on bit map display.
  6069. This could be improved in future, probably showing a table
  6070. of 32 or 64 bits per row */
  6071. if (mask_greatest_bit_offset < 32) {
  6072. crumb_end_bit_offset = mask_initial_bit_offset
  6073. + crumb_spec[i].crumb_bit_offset
  6074. + crumb_spec[i].crumb_bit_length;
  6075. crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
  6076. if (crumb_end_bit_offset > mask_greatest_bit_offset) {
  6077. mask_greatest_bit_offset = crumb_end_bit_offset;
  6078. }
  6079. composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
  6080. composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
  6081. }
  6082. /* Shift left for the next segment */
  6083. value <<= crumb_spec[++i].crumb_bit_length;
  6084. }
  6085. /* Sign extend for signed types */
  6086. switch (hf_field->type) {
  6087. case FT_INT8:
  6088. case FT_INT16:
  6089. case FT_INT24:
  6090. case FT_INT32:
  6091. case FT_INT64:
  6092. if (no_of_bits && (value & (G_GINT64_CONSTANT(1) << (no_of_bits-1))))
  6093. value |= (G_GINT64_CONSTANT(-1) << no_of_bits);
  6094. break;
  6095. default:
  6096. break;
  6097. }
  6098. if (return_value) {
  6099. *return_value = value;
  6100. }
  6101. /* Coast clear. Try and fake it */
  6102. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
  6103. /* initialise the format string */
  6104. bf_str = (char *)ep_alloc(256);
  6105. bf_str[0] = '\0';
  6106. octet_offset = bit_offset >> 3;
  6107. /* Round up mask length to nearest octet */
  6108. octet_length = ((mask_greatest_bit_offset + 7) >> 3);
  6109. mask_greatest_bit_offset = octet_length << 3;
  6110. /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
  6111. It would be a useful enhancement to eliminate this restriction. */
  6112. if (mask_greatest_bit_offset <= 32) {
  6113. other_decode_bitfield_value(bf_str,
  6114. (guint32)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
  6115. (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
  6116. mask_greatest_bit_offset);
  6117. }
  6118. switch (hf_field->type) {
  6119. case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
  6120. /* Boolean field */
  6121. tfstring = (const true_false_string *) &tfs_true_false;
  6122. if (hf_field->strings)
  6123. tfstring = (const true_false_string *) hf_field->strings;
  6124. return proto_tree_add_boolean_format(tree, hfindex,
  6125. tvb, octet_offset, octet_length, (guint32)value,
  6126. "%s = %s: %s",
  6127. bf_str, hf_field->name,
  6128. (guint32)value ? tfstring->true_string : tfstring->false_string);
  6129. break;
  6130. case FT_UINT8:
  6131. case FT_UINT16:
  6132. case FT_UINT24:
  6133. case FT_UINT32:
  6134. pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
  6135. fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
  6136. break;
  6137. case FT_INT8:
  6138. case FT_INT16:
  6139. case FT_INT24:
  6140. case FT_INT32:
  6141. pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
  6142. fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
  6143. break;
  6144. case FT_UINT64:
  6145. pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
  6146. fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
  6147. break;
  6148. case FT_INT64:
  6149. pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
  6150. fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
  6151. break;
  6152. default:
  6153. DISSECTOR_ASSERT_NOT_REACHED();
  6154. return NULL;
  6155. break;
  6156. }
  6157. proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
  6158. return pi;
  6159. }
  6160. void
  6161. proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
  6162. const crumb_spec_t *crumb_spec, guint16 crumb_index)
  6163. {
  6164. header_field_info *hfinfo;
  6165. PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
  6166. proto_tree_add_text(tree, tvb,
  6167. bit_offset >> 3,
  6168. ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
  6169. "%s crumb %d of %s (decoded above)",
  6170. decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
  6171. tvb_get_bits(tvb,
  6172. bit_offset,
  6173. crumb_spec[crumb_index].crumb_bit_length,
  6174. ENC_BIG_ENDIAN)),
  6175. crumb_index,
  6176. hfinfo->name);
  6177. }
  6178. proto_item *
  6179. proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
  6180. const guint bit_offset, const gint no_of_bits,
  6181. guint64 *return_value, const guint encoding)
  6182. {
  6183. proto_item *item;
  6184. if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
  6185. bit_offset, no_of_bits,
  6186. return_value, encoding))) {
  6187. FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
  6188. FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
  6189. }
  6190. return item;
  6191. }
  6192. static proto_item *
  6193. _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
  6194. tvbuff_t *tvb, const guint bit_offset,
  6195. const gint no_of_bits, void *value_ptr,
  6196. gchar *value_str)
  6197. {
  6198. gint offset;
  6199. guint length;
  6200. guint8 tot_no_bits;
  6201. char *str;
  6202. guint64 value = 0;
  6203. header_field_info *hf_field;
  6204. /* We do not have to return a value, try to fake it as soon as possible */
  6205. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
  6206. if (hf_field->bitmask != 0) {
  6207. REPORT_DISSECTOR_BUG(ep_strdup_printf(
  6208. "Incompatible use of proto_tree_add_bits_format_value"
  6209. " with field '%s' (%s) with bitmask != 0",
  6210. hf_field->abbrev, hf_field->name));
  6211. }
  6212. DISSECTOR_ASSERT(no_of_bits > 0);
  6213. /* Byte align offset */
  6214. offset = bit_offset>>3;
  6215. /*
  6216. * Calculate the number of octets used to hold the bits
  6217. */
  6218. tot_no_bits = ((bit_offset&0x7) + no_of_bits);
  6219. length = tot_no_bits>>3;
  6220. /* If we are using part of the next octet, increase length by 1 */
  6221. if (tot_no_bits & 0x07)
  6222. length++;
  6223. if (no_of_bits < 65) {
  6224. value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
  6225. } else {
  6226. DISSECTOR_ASSERT_NOT_REACHED();
  6227. return NULL;
  6228. }
  6229. str = decode_bits_in_field(bit_offset, no_of_bits, value);
  6230. strcat(str, " = ");
  6231. strcat(str, hf_field->name);
  6232. /*
  6233. * This function does not receive an actual value but a dimensionless pointer to that value.
  6234. * For this reason, the type of the header field is examined in order to determine
  6235. * what kind of value we should read from this address.
  6236. * The caller of this function must make sure that for the specific header field type the address of
  6237. * a compatible value is provided.
  6238. */
  6239. switch (hf_field->type) {
  6240. case FT_BOOLEAN:
  6241. return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
  6242. "%s: %s", str, value_str);
  6243. break;
  6244. case FT_UINT8:
  6245. case FT_UINT16:
  6246. case FT_UINT24:
  6247. case FT_UINT32:
  6248. return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
  6249. "%s: %s", str, value_str);
  6250. break;
  6251. case FT_UINT64:
  6252. return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
  6253. "%s: %s", str, value_str);
  6254. break;
  6255. case FT_INT8:
  6256. case FT_INT16:
  6257. case FT_INT24:
  6258. case FT_INT32:
  6259. return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
  6260. "%s: %s", str, value_str);
  6261. break;
  6262. case FT_INT64:
  6263. return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
  6264. "%s: %s", str, value_str);
  6265. break;
  6266. case FT_FLOAT:
  6267. return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
  6268. "%s: %s", str, value_str);
  6269. break;
  6270. default:
  6271. DISSECTOR_ASSERT_NOT_REACHED();
  6272. return NULL;
  6273. break;
  6274. }
  6275. }
  6276. static proto_item *
  6277. proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
  6278. tvbuff_t *tvb, const guint bit_offset,
  6279. const gint no_of_bits, void *value_ptr,
  6280. gchar *value_str)
  6281. {
  6282. proto_item *item;
  6283. if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
  6284. tvb, bit_offset, no_of_bits,
  6285. value_ptr, value_str))) {
  6286. FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
  6287. FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
  6288. }
  6289. return item;
  6290. }
  6291. #define CREATE_VALUE_STRING(dst,format,ap) \
  6292. va_start(ap, format); \
  6293. dst = ep_strdup_vprintf(format, ap); \
  6294. va_end(ap);
  6295. proto_item *
  6296. proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
  6297. tvbuff_t *tvb, const guint bit_offset,
  6298. const gint no_of_bits, guint32 value,
  6299. const char *format, ...)
  6300. {
  6301. va_list ap;
  6302. gchar *dst;
  6303. header_field_info *hf_field;
  6304. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
  6305. switch (hf_field->type) {
  6306. case FT_UINT8:
  6307. case FT_UINT16:
  6308. case FT_UINT24:
  6309. case FT_UINT32:
  6310. break;
  6311. default:
  6312. DISSECTOR_ASSERT_NOT_REACHED();
  6313. return NULL;
  6314. break;
  6315. }
  6316. CREATE_VALUE_STRING(dst, format, ap);
  6317. return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
  6318. }
  6319. proto_item *
  6320. proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
  6321. tvbuff_t *tvb, const guint bit_offset,
  6322. const gint no_of_bits, float value,
  6323. const char *format, ...)
  6324. {
  6325. va_list ap;
  6326. gchar *dst;
  6327. header_field_info *hf_field;
  6328. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
  6329. DISSECTOR_ASSERT(hf_field->type == FT_FLOAT);
  6330. CREATE_VALUE_STRING(dst, format, ap);
  6331. return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
  6332. }
  6333. proto_item *
  6334. proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
  6335. tvbuff_t *tvb, const guint bit_offset,
  6336. const gint no_of_bits, gint32 value,
  6337. const char *format, ...)
  6338. {
  6339. va_list ap;
  6340. gchar *dst;
  6341. header_field_info *hf_field;
  6342. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
  6343. switch (hf_field->type) {
  6344. case FT_INT8:
  6345. case FT_INT16:
  6346. case FT_INT24:
  6347. case FT_INT32:
  6348. break;
  6349. default:
  6350. DISSECTOR_ASSERT_NOT_REACHED();
  6351. return NULL;
  6352. break;
  6353. }
  6354. CREATE_VALUE_STRING(dst, format, ap);
  6355. return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
  6356. }
  6357. proto_item *
  6358. proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
  6359. tvbuff_t *tvb, const guint bit_offset,
  6360. const gint no_of_bits, guint32 value,
  6361. const char *format, ...)
  6362. {
  6363. va_list ap;
  6364. gchar *dst;
  6365. header_field_info *hf_field;
  6366. TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
  6367. DISSECTOR_ASSERT(hf_field->type == FT_BOOLEAN);
  6368. CREATE_VALUE_STRING(dst, format, ap);
  6369. return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
  6370. }
  6371. guchar
  6372. proto_check_field_name(const gchar *field_name)
  6373. {
  6374. return wrs_check_charset(fld_abbrev_chars, field_name);
  6375. }
  6376. gboolean
  6377. tree_expanded(int tree_type)
  6378. {
  6379. g_assert(tree_type >= 0 && tree_type < num_tree_types);
  6380. return tree_is_expanded[tree_type >> 5] & (1 << (tree_type & 31));
  6381. }
  6382. void
  6383. tree_expanded_set(int tree_type, gboolean value)
  6384. {
  6385. g_assert(tree_type >= 0 && tree_type < num_tree_types);
  6386. if (value)
  6387. tree_is_expanded[tree_type >> 5] |= (1 << (tree_type & 31));
  6388. else
  6389. tree_is_expanded[tree_type >> 5] &= ~(1 << (tree_type & 31));
  6390. }
  6391. /*
  6392. * Editor modelines - http://www.wireshark.org/tools/modelines.html
  6393. *
  6394. * Local variables:
  6395. * c-basic-offset: 8
  6396. * tab-width: 8
  6397. * indent-tabs-mode: t
  6398. * End:
  6399. *
  6400. * vi: set shiftwidth=8 tabstop=8 noexpandtab:
  6401. * :indentSize=8:tabSize=8:noTabs=false:
  6402. */