2 * Routines for the mate Facility's Pseudo-Protocol dissection
4 * Copyright 2004, Luis E. Garcia Ontanon <gopo@webflies.org>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 /**************************************************************************
29 * This is the pseudo protocol dissector for the mate module. ***
30 * It is intended for this to be just the user interface to the module. ***
31 **************************************************************************/
35 static int mate_tap_data
= 0;
36 static mate_config
* mc
= NULL
;
38 static int proto_mate
= -1;
40 static const gchar
* pref_mate_config_filename
= "";
41 static const gchar
* current_mate_config_filename
= NULL
;
43 static proto_item
*mate_i
= NULL
;
45 static void pdu_attrs_tree(proto_tree
* tree
, tvbuff_t
*tvb
, mate_pdu
* pdu
) {
51 avpl_i
= proto_tree_add_text(tree
,tvb
,0,0,"%s Attributes",pdu
->cfg
->name
);
52 avpl_t
= proto_item_add_subtree(avpl_i
, pdu
->cfg
->ett_attr
);
54 for ( c
= pdu
->avpl
->null
.next
; c
->avp
; c
= c
->next
) {
55 hfi_p
= (int *)g_hash_table_lookup(pdu
->cfg
->my_hfids
,(char*)c
->avp
->n
);
58 proto_tree_add_string(avpl_t
,*hfi_p
,tvb
,0,0,c
->avp
->v
);
60 g_warning("MATE: error: undefined attribute: mate.%s.%s",pdu
->cfg
->name
,c
->avp
->n
);
61 proto_tree_add_text(avpl_t
,tvb
,0,0,"Undefined attribute: %s=%s",c
->avp
->n
, c
->avp
->v
);
66 static void gop_attrs_tree(proto_tree
* tree
, tvbuff_t
*tvb
, mate_gop
* gop
) {
72 avpl_i
= proto_tree_add_text(tree
,tvb
,0,0,"%s Attributes",gop
->cfg
->name
);
73 avpl_t
= proto_item_add_subtree(avpl_i
, gop
->cfg
->ett_attr
);
75 for ( c
= gop
->avpl
->null
.next
; c
->avp
; c
= c
->next
) {
76 hfi_p
= (int *)g_hash_table_lookup(gop
->cfg
->my_hfids
,(char*)c
->avp
->n
);
79 proto_tree_add_string(avpl_t
,*hfi_p
,tvb
,0,0,c
->avp
->v
);
81 g_warning("MATE: error: undefined attribute: mate.%s.%s",gop
->cfg
->name
,c
->avp
->n
);
82 proto_tree_add_text(avpl_t
,tvb
,0,0,"Undefined attribute: %s=%s",c
->avp
->n
, c
->avp
->v
);
87 static void gog_attrs_tree(proto_tree
* tree
, tvbuff_t
*tvb
, mate_gog
* gog
) {
93 avpl_i
= proto_tree_add_text(tree
,tvb
,0,0,"%s Attributes",gog
->cfg
->name
);
94 avpl_t
= proto_item_add_subtree(avpl_i
, gog
->cfg
->ett_attr
);
96 for ( c
= gog
->avpl
->null
.next
; c
->avp
; c
= c
->next
) {
97 hfi_p
= (int *)g_hash_table_lookup(gog
->cfg
->my_hfids
,(char*)c
->avp
->n
);
100 proto_tree_add_string(avpl_t
,*hfi_p
,tvb
,0,0,c
->avp
->v
);
102 g_warning("MATE: error: undefined attribute: mate.%s.%s",gog
->cfg
->name
,c
->avp
->n
);
103 proto_tree_add_text(avpl_t
,tvb
,0,0,"Undefined attribute: %s=%s",c
->avp
->n
, c
->avp
->v
);
108 static void mate_gop_tree(proto_tree
* pdu_tree
, tvbuff_t
*tvb
, mate_gop
* gop
);
110 static void mate_gog_tree(proto_tree
* tree
, tvbuff_t
*tvb
, mate_gog
* gog
, mate_gop
* gop
) {
111 proto_item
*gog_item
;
112 proto_tree
*gog_tree
;
113 proto_item
*gog_time_item
;
114 proto_tree
*gog_time_tree
;
115 proto_item
*gog_gops_item
;
116 proto_tree
*gog_gops_tree
;
118 proto_item
*gog_gop_item
;
119 proto_tree
*gog_gop_tree
;
122 gog_item
= proto_tree_add_uint(tree
,gog
->cfg
->hfid
,tvb
,0,0,gog
->id
);
123 gog_tree
= proto_item_add_subtree(gog_item
,gog
->cfg
->ett
);
125 gog_attrs_tree(gog_tree
,tvb
,gog
);
127 if (gog
->cfg
->show_times
) {
128 gog_time_item
= proto_tree_add_text(gog_tree
,tvb
,0,0,"%s Times",gog
->cfg
->name
);
129 gog_time_tree
= proto_item_add_subtree(gog_time_item
, gog
->cfg
->ett_times
);
131 proto_tree_add_float(gog_time_tree
, gog
->cfg
->hfid_start_time
, tvb
, 0, 0, gog
->start_time
);
132 proto_tree_add_float(gog_time_tree
, gog
->cfg
->hfid_last_time
, tvb
, 0, 0, gog
->last_time
- gog
->start_time
);
135 gog_gops_item
= proto_tree_add_uint(gog_tree
, gog
->cfg
->hfid_gog_num_of_gops
,
136 tvb
, 0, 0, gog
->num_of_gops
);
138 gog_gops_tree
= proto_item_add_subtree(gog_gops_item
, gog
->cfg
->ett_children
);
140 for (gog_gops
= gog
->gops
; gog_gops
; gog_gops
= gog_gops
->next
) {
142 if (gop
!= gog_gops
) {
143 if (gog
->cfg
->gop_tree_mode
== GOP_FULL_TREE
) {
144 mate_gop_tree(gog_gops_tree
, tvb
, gog_gops
);
146 gog_gop_item
= proto_tree_add_uint(gog_gops_tree
,gog_gops
->cfg
->hfid
,tvb
,0,0,gog_gops
->id
);
148 if (gog
->cfg
->gop_tree_mode
== GOP_BASIC_TREE
) {
149 gog_gop_tree
= proto_item_add_subtree(gog_gop_item
, gog
->cfg
->ett_gog_gop
);
151 proto_tree_add_text(gog_gop_tree
, tvb
,0,0, "Started at: %f", gog_gops
->start_time
);
154 proto_tree_add_text(gog_gop_tree
, tvb
,0,0, "%s Duration: %f",
155 gog_gops
->cfg
->name
, gog_gops
->last_time
- gog_gops
->start_time
);
157 if (gog_gops
->released
)
158 proto_tree_add_text(gog_gop_tree
, tvb
,0,0, "%s has been released, Time: %f",
159 gog_gops
->cfg
->name
, gog_gops
->release_time
- gog_gops
->start_time
);
161 proto_tree_add_text(gog_gop_tree
, tvb
,0,0, "Number of Pdus: %u",gog_gops
->num_of_pdus
);
163 if (gop
->pdus
&& gop
->cfg
->pdu_tree_mode
!= GOP_NO_TREE
) {
164 proto_tree_add_uint(gog_gop_tree
,gog
->cfg
->hfid_gog_gopstart
,tvb
,0,0,gog_gops
->pdus
->frame
);
166 for (pdu
= gog_gops
->pdus
->next
; pdu
; pdu
= pdu
->next
) {
168 proto_tree_add_uint(gog_gop_tree
,gog
->cfg
->hfid_gog_gopstop
,tvb
,0,0,pdu
->frame
);
177 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
);
182 static void mate_gop_tree(proto_tree
* tree
, tvbuff_t
*tvb
, mate_gop
* gop
) {
183 proto_item
*gop_item
;
184 proto_tree
*gop_time_tree
;
185 proto_item
*gop_time_item
;
186 proto_tree
*gop_tree
;
187 proto_item
*gop_pdu_item
;
188 proto_tree
*gop_pdu_tree
;
192 const gchar
* pdu_str
;
193 const gchar
* type_str
;
196 gop_item
= proto_tree_add_uint(tree
,gop
->cfg
->hfid
,tvb
,0,0,gop
->id
);
197 gop_tree
= proto_item_add_subtree(gop_item
, gop
->cfg
->ett
);
199 if (gop
->gop_key
) proto_tree_add_text(gop_tree
,tvb
,0,0,"GOP Key: %s",gop
->gop_key
);
201 gop_attrs_tree(gop_tree
,tvb
,gop
);
203 if (gop
->cfg
->show_times
) {
204 gop_time_item
= proto_tree_add_text(gop_tree
,tvb
,0,0,"%s Times",gop
->cfg
->name
);
205 gop_time_tree
= proto_item_add_subtree(gop_time_item
, gop
->cfg
->ett_times
);
207 proto_tree_add_float(gop_time_tree
, gop
->cfg
->hfid_start_time
, tvb
, 0, 0, gop
->start_time
);
210 proto_tree_add_float(gop_time_tree
, gop
->cfg
->hfid_stop_time
, tvb
, 0, 0, gop
->release_time
- gop
->start_time
);
211 proto_tree_add_float(gop_time_tree
, gop
->cfg
->hfid_last_time
, tvb
, 0, 0, gop
->last_time
- gop
->start_time
);
213 proto_tree_add_float(gop_time_tree
, gop
->cfg
->hfid_last_time
, tvb
, 0, 0, gop
->last_time
- gop
->start_time
);
217 gop_pdu_item
= proto_tree_add_uint(gop_tree
, gop
->cfg
->hfid_gop_num_pdus
, tvb
, 0, 0,gop
->num_of_pdus
);
219 if (gop
->cfg
->pdu_tree_mode
!= GOP_NO_TREE
) {
221 gop_pdu_tree
= proto_item_add_subtree(gop_pdu_item
, gop
->cfg
->ett_children
);
223 rel_time
= gop
->start_time
;
225 type_str
= (gop
->cfg
->pdu_tree_mode
== GOP_FRAME_TREE
) ? "in frame:" : "id:";
227 for (gop_pdus
= gop
->pdus
; gop_pdus
; gop_pdus
= gop_pdus
->next
) {
229 pdu_item
= (gop
->cfg
->pdu_tree_mode
== GOP_FRAME_TREE
) ? gop_pdus
->frame
: gop_pdus
->id
;
231 if (gop_pdus
->is_start
) {
233 } else if (gop_pdus
->is_stop
) {
235 } else if (gop_pdus
->after_release
) {
236 pdu_str
= "After stop ";
241 pdu_rel_time
= gop_pdus
->time_in_gop
!= 0.0 ? gop_pdus
->time_in_gop
- rel_time
: (float) 0.0;
243 proto_tree_add_uint_format(gop_pdu_tree
,gop
->cfg
->hfid_gop_pdu
,tvb
,0,0,pdu_item
,
244 "%sPDU: %s %i (%f : %f)",pdu_str
, type_str
,
245 pdu_item
, gop_pdus
->time_in_gop
,
248 rel_time
= gop_pdus
->time_in_gop
;
255 static void mate_pdu_tree(mate_pdu
*pdu
, tvbuff_t
*tvb
, proto_tree
* tree
) {
256 proto_item
*pdu_item
;
257 proto_tree
*pdu_tree
;
261 if (pdu
->gop
&& pdu
->gop
->gog
) {
262 proto_item_append_text(mate_i
," %s:%d->%s:%d->%s:%d",
263 pdu
->cfg
->name
,pdu
->id
,
264 pdu
->gop
->cfg
->name
,pdu
->gop
->id
,
265 pdu
->gop
->gog
->cfg
->name
,pdu
->gop
->gog
->id
);
266 } else if (pdu
->gop
) {
267 proto_item_append_text(mate_i
," %s:%d->%s:%d",
268 pdu
->cfg
->name
,pdu
->id
,
269 pdu
->gop
->cfg
->name
,pdu
->gop
->id
);
271 proto_item_append_text(mate_i
," %s:%d",pdu
->cfg
->name
,pdu
->id
);
274 pdu_item
= proto_tree_add_uint(tree
,pdu
->cfg
->hfid
,tvb
,0,0,pdu
->id
);
275 pdu_tree
= proto_item_add_subtree(pdu_item
, pdu
->cfg
->ett
);
276 proto_tree_add_float(pdu_tree
,pdu
->cfg
->hfid_pdu_rel_time
, tvb
, 0, 0, pdu
->rel_time
);
279 proto_tree_add_float(pdu_tree
,pdu
->cfg
->hfid_pdu_time_in_gop
, tvb
, 0, 0, pdu
->time_in_gop
);
280 mate_gop_tree(tree
,tvb
,pdu
->gop
);
283 mate_gog_tree(tree
,tvb
,pdu
->gop
->gog
,pdu
->gop
);
287 pdu_attrs_tree(pdu_tree
,tvb
,pdu
);
291 static void mate_tree(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
) {
295 if ( ! mc
|| ! tree
) return;
297 mate_analyze_frame(pinfo
,tree
);
299 if (( pdus
= mate_get_pdus(pinfo
->fd
->num
) )) {
300 for ( ; pdus
; pdus
= pdus
->next_in_frame
) {
301 mate_i
= proto_tree_add_protocol_format(tree
,mc
->hfid_mate
,tvb
,0,0,"MATE");
302 mate_t
= proto_item_add_subtree(mate_i
, mc
->ett_root
);
303 mate_pdu_tree(pdus
,tvb
,mate_t
);
308 static int mate_packet(void *prs _U_
, packet_info
* tree _U_
, epan_dissect_t
*edt _U_
, const void *dummy _U_
) {
309 /* nothing to do yet */
315 proto_reg_handoff_mate(void)
317 GString
* tap_error
= NULL
;
319 if ( *pref_mate_config_filename
!= '\0' ) {
321 if (current_mate_config_filename
) {
322 report_failure("Mate cannot reconfigure itself.\n"
323 "for changes to be applied you have to restart wireshark\n");
328 mc
= mate_make_config(pref_mate_config_filename
,proto_mate
);
331 /* XXX: alignment warnings, what do they mean? */
332 proto_register_field_array(proto_mate
, (hf_register_info
*)(void *)mc
->hfrs
->data
, mc
->hfrs
->len
);
333 proto_register_subtree_array((gint
**)(void*)mc
->ett
->data
, mc
->ett
->len
);
334 register_init_routine(initialize_mate_runtime
);
336 tap_error
= register_tap_listener("frame", &mate_tap_data
,
337 (char*) mc
->tap_filter
,
344 g_warning("mate: couldn't (re)register tap: %s",tap_error
->str
);
345 g_string_free(tap_error
, TRUE
);
350 initialize_mate_runtime();
353 current_mate_config_filename
= pref_mate_config_filename
;
361 proto_register_mate(void)
363 module_t
*mate_module
;
364 dissector_handle_t mate_handle
;
366 proto_mate
= proto_register_protocol("Meta Analysis Tracing Engine", "MATE", "mate");
367 register_dissector("mate",mate_tree
,proto_mate
);
368 mate_module
= prefs_register_protocol(proto_mate
, proto_reg_handoff_mate
);
369 prefs_register_filename_preference(mate_module
, "config",
370 "Configuration Filename",
371 "The name of the file containing the mate module's configuration",
372 &pref_mate_config_filename
);
374 mate_handle
= find_dissector("mate");
375 register_postdissector(mate_handle
);