drsuapi_dissect_element_DsReplicaObjectIdentifier_dn parents append
[wireshark-sm.git] / plugins / epan / mate / packet-mate.c
blob6e76ab4d3344c0a609260486f0aad5cb9e8d693e
1 /* packet-mate.c
2 * Routines for the mate Facility's Pseudo-Protocol dissection
4 * Copyright 2004, Luis E. Garcia Ontanon <gopo@webflies.org>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
14 /**************************************************************************
15 * This is the pseudo protocol dissector for the mate module. ***
16 * It is intended for this to be just the user interface to the module. ***
17 **************************************************************************/
19 #include "config.h"
21 #include "mate.h"
22 #include <epan/expert.h>
24 void proto_register_mate(void);
25 void proto_reg_handoff_mate(void);
27 static mate_config* mc;
29 static int proto_mate;
31 static int hf_mate_released_time;
32 static int hf_mate_duration;
33 static int hf_mate_number_of_pdus;
34 static int hf_mate_started_at;
35 static int hf_mate_gop_key;
37 static expert_field ei_mate_undefined_attribute;
39 static const char* pref_mate_config_filename = "";
40 static const char* current_mate_config_filename;
42 #ifdef _AVP_DEBUGGING
43 static int pref_avp_debug_general;
44 static int pref_avp_debug_avp;
45 static int pref_avp_debug_avp_op;
46 static int pref_avp_debug_avpl;
47 static int pref_avp_debug_avpl_op;
48 #endif
50 static dissector_handle_t mate_handle;
52 static void
53 pdu_attrs_tree(proto_tree* tree, packet_info *pinfo, tvbuff_t *tvb, mate_pdu* pdu)
55 AVPN* c;
56 proto_tree *avpl_t;
57 int* hfi_p;
59 avpl_t = proto_tree_add_subtree_format(tree,tvb,0,0,pdu->cfg->ett_attr,NULL,"%s Attributes",pdu->cfg->name);
61 for ( c = pdu->avpl->null.next; c->avp; c = c->next) {
62 hfi_p = (int *)g_hash_table_lookup(pdu->cfg->my_hfids,(char*)c->avp->n);
64 if (hfi_p) {
65 proto_tree_add_string(avpl_t,*hfi_p,tvb,0,0,c->avp->v);
66 } else {
67 proto_tree_add_expert_format(avpl_t,pinfo,&ei_mate_undefined_attribute,tvb,0,0,"Undefined attribute: %s=%s",c->avp->n, c->avp->v);
72 static void
73 gop_attrs_tree(proto_tree* tree, packet_info *pinfo, tvbuff_t *tvb, mate_gop* gop)
75 AVPN* c;
76 proto_tree *avpl_t;
77 int* hfi_p;
79 avpl_t = proto_tree_add_subtree_format(tree,tvb,0,0,gop->cfg->ett_attr,NULL,"%s Attributes",gop->cfg->name);
81 for ( c = gop->avpl->null.next; c->avp; c = c->next) {
82 hfi_p = (int *)g_hash_table_lookup(gop->cfg->my_hfids,(char*)c->avp->n);
84 if (hfi_p) {
85 proto_tree_add_string(avpl_t,*hfi_p,tvb,0,0,c->avp->v);
86 } else {
87 proto_tree_add_expert_format(avpl_t,pinfo,&ei_mate_undefined_attribute,tvb,0,0,"Undefined attribute: %s=%s",c->avp->n, c->avp->v);
92 static void
93 gog_attrs_tree(proto_tree* tree, packet_info *pinfo, tvbuff_t *tvb, mate_gog* gog)
95 AVPN* c;
96 proto_tree *avpl_t;
97 int* hfi_p;
99 avpl_t = proto_tree_add_subtree_format(tree,tvb,0,0,gog->cfg->ett_attr,NULL,"%s Attributes",gog->cfg->name);
101 for ( c = gog->avpl->null.next; c->avp; c = c->next) {
102 hfi_p = (int *)g_hash_table_lookup(gog->cfg->my_hfids,(char*)c->avp->n);
104 if (hfi_p) {
105 proto_tree_add_string(avpl_t,*hfi_p,tvb,0,0,c->avp->v);
106 } else {
107 proto_tree_add_expert_format(avpl_t,pinfo,&ei_mate_undefined_attribute,tvb,0,0,"Undefined attribute: %s=%s",c->avp->n, c->avp->v);
112 static void mate_gop_tree(proto_tree* pdu_tree, packet_info *pinfo, tvbuff_t *tvb, mate_gop* gop);
114 static void
115 mate_gog_tree(proto_tree* tree, packet_info *pinfo, tvbuff_t *tvb, mate_gog* gog, mate_gop* gop)
117 proto_item *gog_item;
118 proto_tree *gog_tree;
119 proto_tree *gog_time_tree;
120 proto_item *gog_gops_item;
121 proto_tree *gog_gops_tree;
122 mate_gop* gog_gops;
123 proto_item *gog_gop_item;
124 proto_tree *gog_gop_tree;
125 mate_pdu* pdu;
127 gog_item = proto_tree_add_uint(tree,gog->cfg->hfid,tvb,0,0,gog->id);
128 gog_tree = proto_item_add_subtree(gog_item,gog->cfg->ett);
130 gog_attrs_tree(gog_tree,pinfo,tvb,gog);
132 if (gog->cfg->show_times) {
133 gog_time_tree = proto_tree_add_subtree_format(gog_tree,tvb,0,0,gog->cfg->ett_times,NULL,"%s Times",gog->cfg->name);
135 proto_tree_add_double(gog_time_tree, gog->cfg->hfid_start_time, tvb, 0, 0, gog->start_time);
136 proto_tree_add_double(gog_time_tree, gog->cfg->hfid_last_time, tvb, 0, 0, gog->last_time - gog->start_time);
139 gog_gops_item = proto_tree_add_uint(gog_tree, gog->cfg->hfid_gog_num_of_gops, tvb, 0, 0, gog->num_of_gops);
141 gog_gops_tree = proto_item_add_subtree(gog_gops_item, gog->cfg->ett_children);
143 for (gog_gops = gog->gops; gog_gops; gog_gops = gog_gops->next) {
145 if (gop != gog_gops) {
146 if (gog->cfg->gop_tree_mode == GOP_FULL_TREE) {
147 mate_gop_tree(gog_gops_tree, pinfo, tvb, gog_gops);
148 } else {
149 gog_gop_item = proto_tree_add_uint(gog_gops_tree,gog_gops->cfg->hfid,tvb,0,0,gog_gops->id);
151 if (gog->cfg->gop_tree_mode == GOP_BASIC_TREE) {
152 gog_gop_tree = proto_item_add_subtree(gog_gop_item, gog->cfg->ett_gog_gop);
154 proto_tree_add_double(gog_gop_tree, hf_mate_started_at, tvb,0,0,gog_gops->start_time);
156 proto_tree_add_double_format(gog_gop_tree, hf_mate_duration, tvb,0,0, gog_gops->last_time - gog_gops->start_time,
157 "%s Duration: %f", gog_gops->cfg->name, gog_gops->last_time - gog_gops->start_time);
159 if (gog_gops->released)
160 proto_tree_add_double_format(gog_gop_tree, hf_mate_released_time, tvb,0,0, gog_gops->release_time - gog_gops->start_time,
161 "%s has been released, Time: %f", gog_gops->cfg->name, gog_gops->release_time - gog_gops->start_time);
163 proto_tree_add_uint(gog_gop_tree, hf_mate_number_of_pdus, tvb,0,0, gog_gops->num_of_pdus);
165 if (gop->pdus && gop->cfg->pdu_tree_mode != GOP_NO_TREE) {
166 proto_tree_add_uint(gog_gop_tree,gog->cfg->hfid_gog_gopstart,tvb,0,0,gog_gops->pdus->frame);
168 for (pdu = gog_gops->pdus->next ; pdu; pdu = pdu->next) {
169 if (pdu->is_stop) {
170 proto_tree_add_uint(gog_gop_tree,gog->cfg->hfid_gog_gopstop,tvb,0,0,pdu->frame);
171 break;
178 } else {
179 proto_tree_add_uint_format(gog_gops_tree,gop->cfg->hfid,tvb,0,0,gop->id,"current %s Gop: %d",gop->cfg->name,gop->id);
184 static void
185 mate_gop_tree(proto_tree* tree, packet_info *pinfo, tvbuff_t *tvb, mate_gop* gop)
187 proto_item *gop_item;
188 proto_tree *gop_time_tree;
189 proto_tree *gop_tree;
190 proto_item *gop_pdu_item;
191 proto_tree *gop_pdu_tree;
192 mate_pdu* gop_pdus;
193 double rel_time;
194 double pdu_rel_time;
195 const char* pdu_str;
196 const char* type_str;
197 uint32_t pdu_item;
199 gop_item = proto_tree_add_uint(tree,gop->cfg->hfid,tvb,0,0,gop->id);
200 gop_tree = proto_item_add_subtree(gop_item, gop->cfg->ett);
202 if (gop->gop_key) proto_tree_add_string(gop_tree,hf_mate_gop_key,tvb,0,0,gop->gop_key);
204 gop_attrs_tree(gop_tree,pinfo,tvb,gop);
206 if (gop->cfg->show_times) {
207 gop_time_tree = proto_tree_add_subtree_format(gop_tree,tvb,0,0,gop->cfg->ett_times,NULL,"%s Times",gop->cfg->name);
209 proto_tree_add_double(gop_time_tree, gop->cfg->hfid_start_time, tvb, 0, 0, gop->start_time);
211 if (gop->released) {
212 proto_tree_add_double(gop_time_tree, gop->cfg->hfid_stop_time, tvb, 0, 0, gop->release_time - gop->start_time);
213 proto_tree_add_double(gop_time_tree, gop->cfg->hfid_last_time, tvb, 0, 0, gop->last_time - gop->start_time);
214 } else {
215 proto_tree_add_double(gop_time_tree, gop->cfg->hfid_last_time, tvb, 0, 0, gop->last_time - gop->start_time);
219 gop_pdu_item = proto_tree_add_uint(gop_tree, gop->cfg->hfid_gop_num_pdus, tvb, 0, 0,gop->num_of_pdus);
221 if (gop->cfg->pdu_tree_mode != GOP_NO_TREE) {
223 gop_pdu_tree = proto_item_add_subtree(gop_pdu_item, gop->cfg->ett_children);
225 rel_time = gop->start_time;
227 type_str = (gop->cfg->pdu_tree_mode == GOP_FRAME_TREE ) ? "in frame:" : "id:";
229 for (gop_pdus = gop->pdus; gop_pdus; gop_pdus = gop_pdus->next) {
231 pdu_item = (gop->cfg->pdu_tree_mode == GOP_FRAME_TREE ) ? gop_pdus->frame : gop_pdus->id;
233 if (gop_pdus->is_start) {
234 pdu_str = "Start ";
235 } else if (gop_pdus->is_stop) {
236 pdu_str = "Stop ";
237 } else if (gop_pdus->after_release) {
238 pdu_str = "After stop ";
239 } else {
240 pdu_str = "";
243 pdu_rel_time = gop_pdus->time_in_gop != 0.0 ? gop_pdus->time_in_gop - rel_time : 0.0;
245 proto_tree_add_uint_format(gop_pdu_tree,gop->cfg->hfid_gop_pdu,tvb,0,0,pdu_item,
246 "%sPDU: %s %i (%f : %f)",pdu_str, type_str,
247 pdu_item, gop_pdus->time_in_gop,
248 pdu_rel_time);
250 rel_time = gop_pdus->time_in_gop;
257 static void
258 mate_pdu_tree(mate_pdu *pdu, packet_info *pinfo, tvbuff_t *tvb, proto_item *item, proto_tree* tree)
260 proto_item *pdu_item;
261 proto_tree *pdu_tree;
263 if ( ! pdu ) return;
265 if (pdu->gop && pdu->gop->gog) {
266 proto_item_append_text(item," %s:%d->%s:%d->%s:%d",
267 pdu->cfg->name,pdu->id,
268 pdu->gop->cfg->name,pdu->gop->id,
269 pdu->gop->gog->cfg->name,pdu->gop->gog->id);
270 } else if (pdu->gop) {
271 proto_item_append_text(item," %s:%d->%s:%d",
272 pdu->cfg->name,pdu->id,
273 pdu->gop->cfg->name,pdu->gop->id);
274 } else {
275 proto_item_append_text(item," %s:%d",pdu->cfg->name,pdu->id);
278 pdu_item = proto_tree_add_uint(tree,pdu->cfg->hfid,tvb,0,0,pdu->id);
279 pdu_tree = proto_item_add_subtree(pdu_item, pdu->cfg->ett);
280 proto_tree_add_double(pdu_tree,pdu->cfg->hfid_pdu_rel_time, tvb, 0, 0, pdu->rel_time);
282 if (pdu->gop) {
283 proto_tree_add_double(pdu_tree,pdu->cfg->hfid_pdu_time_in_gop, tvb, 0, 0, pdu->time_in_gop);
284 mate_gop_tree(tree,pinfo,tvb,pdu->gop);
286 if (pdu->gop->gog)
287 mate_gog_tree(tree,pinfo,tvb,pdu->gop->gog,pdu->gop);
290 if (pdu->avpl) {
291 pdu_attrs_tree(pdu_tree,pinfo,tvb,pdu);
295 static int
296 mate_tree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
298 mate_pdu* pdus;
299 proto_item *mate_i;
300 proto_tree *mate_t;
302 /* If there is no MATE configuration, don't claim the packet */
303 if ( mc == NULL)
304 return 0;
306 /* There is a MATE configuration, just no tree, so there's nothing to do */
307 if ( tree == NULL)
308 return tvb_captured_length(tvb);
310 mate_analyze_frame(mc, pinfo,tree);
312 if (( pdus = mate_get_pdus(pinfo->num) )) {
313 for ( ; pdus; pdus = pdus->next_in_frame) {
314 mate_i = proto_tree_add_protocol_format(tree,mc->hfid_mate,tvb,0,0,"MATE");
315 mate_t = proto_item_add_subtree(mate_i, mc->ett_root);
316 mate_pdu_tree(pdus,pinfo,tvb,mate_i,mate_t);
319 return tvb_captured_length(tvb);
322 static void
323 initialize_mate(void)
325 initialize_mate_runtime(mc);
326 #ifdef _AVP_DEBUGGING
327 setup_avp_debug(mc->dbg_facility,
328 &pref_avp_debug_general,
329 &pref_avp_debug_avp,
330 &pref_avp_debug_avp_op,
331 &pref_avp_debug_avpl,
332 &pref_avp_debug_avpl_op);
333 #endif
336 static void
337 flush_mate_debug(void)
339 /* Flush debug information */
340 if (mc->dbg_facility)
341 fflush(mc->dbg_facility);
344 extern
345 void
346 proto_reg_handoff_mate(void)
348 if ( *pref_mate_config_filename != '\0' ) {
350 if (current_mate_config_filename) {
351 report_failure("MATE cannot reconfigure itself.\n"
352 "For changes to be applied you have to restart Wireshark\n");
353 return;
356 if (!mc) {
357 mc = mate_make_config(pref_mate_config_filename,proto_mate);
359 if (mc) {
360 /* XXX: alignment warnings, what do they mean? */
361 proto_register_field_array(proto_mate, (hf_register_info*)(void *)mc->hfrs->data, mc->hfrs->len );
362 proto_register_subtree_array((int**)(void*)mc->ett->data, mc->ett->len);
363 register_init_routine(initialize_mate);
364 register_postseq_cleanup_routine(flush_mate_debug);
367 * Set the list of hfids we want.
369 set_postdissector_wanted_hfids(mate_handle,
370 mc->wanted_hfids);
371 /* XXX: Due to #17877, any protocol added to the tree with length -1
372 * that changes its length later (and there are many, such as TCP)
373 * doesn't actually change its length unless the tree is visible,
374 * which means that entire range checking work in MATE to split up
375 * multiple PDUs of the target protocol in the same frame doesn't
376 * work. Set the tree as visible as with Lua postdissectors that
377 * need all fields. It's overkill and bad for performance, though.
379 epan_set_always_visible(true);
381 initialize_mate_runtime(mc);
384 current_mate_config_filename = pref_mate_config_filename;
390 extern
391 void
392 proto_register_mate(void)
394 static hf_register_info hf[] = {
395 { &hf_mate_started_at, { "Started at", "mate.started_at", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
396 { &hf_mate_duration, { "Duration", "mate.duration", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
397 { &hf_mate_released_time, { "Release time", "mate.released_time", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
398 { &hf_mate_number_of_pdus, { "Number of Pdus", "mate.number_of_pdus", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
399 { &hf_mate_gop_key, { "GOP Key", "mate.gop_key", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
402 static ei_register_info ei[] = {
403 { &ei_mate_undefined_attribute, { "mate.undefined_attribute", PI_PROTOCOL, PI_ERROR, "Undefined attribute", EXPFILL }},
406 expert_module_t* expert_mate;
407 module_t *mate_module;
409 proto_mate = proto_register_protocol("Meta Analysis Tracing Engine", "MATE", "mate");
410 proto_register_field_array(proto_mate, hf, array_length(hf));
411 expert_mate = expert_register_protocol(proto_mate);
412 expert_register_field_array(expert_mate, ei, array_length(ei));
414 mate_handle = register_dissector("mate",mate_tree,proto_mate);
415 mate_module = prefs_register_protocol(proto_mate, proto_reg_handoff_mate);
416 prefs_register_filename_preference(mate_module, "config",
417 "Configuration Filename",
418 "The name of the file containing the mate module's configuration",
419 &pref_mate_config_filename, false);
420 #ifdef _AVP_DEBUGGING
421 prefs_register_uint_preference(mate_module, "avp_debug_general",
422 "AVP Debug general",
423 "General debugging level (0..5)",
425 &pref_avp_debug_general);
426 prefs_register_uint_preference(mate_module, "avp_debug_avp",
427 "Debug AVP",
428 "Attribute Value Pairs debugging level (0..5)",
430 &pref_avp_debug_avp);
431 prefs_register_uint_preference(mate_module, "avp_debug_avp_op",
432 "Debug AVP operations",
433 "Attribute Value Pairs operations debugging level (0..5)",
435 &pref_avp_debug_avp_op);
436 prefs_register_uint_preference(mate_module, "avp_debug_avpl",
437 "Debug AVP list",
438 "Attribute Value Pairs list debugging level (0..5)",
440 &pref_avp_debug_avpl);
441 prefs_register_uint_preference(mate_module, "avp_debug_avpl_op",
442 "Debug AVP list operations",
443 "Attribute Value Pairs list operations debugging level (0..5)",
445 &pref_avp_debug_avpl_op);
446 #endif
448 register_postdissector(mate_handle);
452 * Editor modelines - https://www.wireshark.org/tools/modelines.html
454 * Local variables:
455 * c-basic-offset: 8
456 * tab-width: 8
457 * indent-tabs-mode: t
458 * End:
460 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
461 * :indentSize=8:tabSize=8:noTabs=false: