1 /* packet-componentstatus.c
2 * Routines for the Component Status Protocol of the
3 * RSPLIB RSerPool implementation
4 * https://www.uni-due.de/~be0001/rserpool/
6 * Copyright 2006-2021 by Thomas Dreibholz <dreibh [AT] iem.uni-due.de>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * Copied from README.developer
14 * SPDX-License-Identifier: GPL-2.0-or-later
19 #include <epan/packet.h>
20 #include <epan/ipproto.h>
21 #include <epan/sctpppids.h>
22 #include <epan/stat_tap_ui.h>
24 #include <wsutil/array.h>
27 void proto_register_componentstatusprotocol(void);
28 void proto_reg_handoff_componentstatusprotocol(void);
30 static dissector_handle_t componentstatusprotocol_handle
;
32 /* Initialize the protocol and registered fields */
33 static int proto_componentstatusprotocol
;
34 static int tap_componentstatusprotocol
= -1;
36 /* Initialize the subtree pointers */
37 static int ett_componentstatusprotocol
;
38 static int ett_message_flags
;
39 static int ett_message_sender_id
;
40 static int ett_cspreport_association_receiver_id
;
41 static int ett_association
;
44 #define COMPONENTSTATUSPROTOCOL_PORT 2960 /* Not IANA registered */
45 #define COMPONENTSTATUSPROTOCOL_VERSION 0x0200
47 static int hf_message_type
;
48 static int hf_message_flags
;
49 static int hf_message_flags_final_bit
;
50 static int hf_message_length
;
51 static int hf_message_version
;
52 static int hf_message_sender_id
;
53 static int hf_message_sender_id_group
;
54 static int hf_message_sender_id_object
;
55 static int hf_message_sender_timestamp
;
57 static uint64_t componentstatusprotocol_total_msgs
;
58 static uint64_t componentstatusprotocol_total_bytes
;
61 #define COMPONENTSTATUS_REPORT 0x01
63 static const value_string message_type_values
[] = {
64 { COMPONENTSTATUS_REPORT
, "ComponentStatus Report" },
69 static int hf_cspreport_report_interval
;
70 static int hf_cspreport_location
;
71 static int hf_cspreport_status
;
72 static int hf_cspreport_workload
;
73 static int hf_cspreport_associations
;
75 #define CSPF_FINAL (1 << 0)
76 static const true_false_string message_flags_final_bit
= {
81 #define CID_GROUP_UNKNOWN 0x0000
82 #define CID_GROUP_REGISTRAR 0x0001
83 #define CID_GROUP_POOLELEMENT 0x0002
84 #define CID_GROUP_POOLUSER 0x0003
85 #define CID_GROUP(id) (((uint64_t) id >> 56) & (0xffffULL)
86 #define CID_OBJECT(id) (((uint64_t) id & 0xffffffffffffffULL)
87 static const value_string group_values
[] = {
88 { CID_GROUP_UNKNOWN
, "Unknown" },
89 { CID_GROUP_REGISTRAR
, "Registrar" },
90 { CID_GROUP_POOLELEMENT
, "Pool Element" },
91 { CID_GROUP_POOLUSER
, "Pool User" },
95 #define CSR_GET_WORKLOAD(w) ((w == 0xffff) ? -1.0 : (float)(w / (float)0xfffe))
97 static int hf_cspreport_association_receiver_id
;
98 static int hf_cspreport_association_receiver_id_group
;
99 static int hf_cspreport_association_receiver_id_object
;
100 static int hf_cspreport_association_duration
;
101 static int hf_cspreport_association_flags
;
102 static int hf_cspreport_association_protocolid
;
103 static int hf_cspreport_association_ppid
;
106 /* Setup list of header fields */
107 static hf_register_info hf
[] = {
108 { &hf_message_type
, { "Type", "componentstatusprotocol.message_type", FT_UINT8
, BASE_DEC
, VALS(message_type_values
), 0x0, NULL
, HFILL
} },
109 { &hf_message_flags
, { "Flags", "componentstatusprotocol.message_flags", FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
110 { &hf_message_flags_final_bit
, { "F-Bit", "componentstatusprotocol.message_final_bit", FT_BOOLEAN
, 8, TFS(&message_flags_final_bit
), CSPF_FINAL
, NULL
, HFILL
} },
111 { &hf_message_length
, { "Length", "componentstatusprotocol.message_length", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
112 { &hf_message_version
, { "Version", "componentstatusprotocol.message_version", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
113 { &hf_message_sender_id
, { "SenderID", "componentstatusprotocol.message_sender_id", FT_UINT64
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
114 { &hf_message_sender_id_group
, { "Group", "componentstatusprotocol.message_sender_id.group", FT_UINT16
, BASE_HEX
, VALS(group_values
), 0x0, NULL
, HFILL
} },
115 { &hf_message_sender_id_object
, { "Object", "componentstatusprotocol.message_sender_id.object", FT_UINT64
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
116 { &hf_message_sender_timestamp
, { "SenderTimeStamp", "componentstatusprotocol.message_sendertimestamp", FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
118 { &hf_cspreport_report_interval
, { "ReportInterval", "componentstatusprotocol.componentstatusreport_reportinterval", FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
119 { &hf_cspreport_location
, { "Location", "componentstatusprotocol.componentstatusreport_location", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
120 { &hf_cspreport_status
, { "Status", "componentstatusprotocol.componentstatusreport_status", FT_STRING
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
121 { &hf_cspreport_workload
, { "Workload", "componentstatusprotocol.componentstatusreport_workload", FT_FLOAT
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
122 { &hf_cspreport_associations
, { "Associations", "componentstatusprotocol.componentstatusreport_associations", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
124 { &hf_cspreport_association_receiver_id
, { "ReceiverID", "componentstatusprotocol.componentassociation_receiver_id", FT_UINT64
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
125 { &hf_cspreport_association_receiver_id_group
, { "Group", "componentstatusprotocol.componentassociation_receiver_id.group", FT_UINT16
, BASE_HEX
, VALS(group_values
), 0x0, NULL
, HFILL
} },
126 { &hf_cspreport_association_receiver_id_object
, { "Object", "componentstatusprotocol.componentassociation_receiver_id.object", FT_UINT64
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
} },
127 { &hf_cspreport_association_duration
, { "Duration", "componentstatusprotocol.componentassociation_duration", FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
} },
128 { &hf_cspreport_association_flags
, { "Flags", "componentstatusprotocol.componentassociation_flags", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
129 { &hf_cspreport_association_protocolid
, { "ProtocolID", "componentstatusprotocol.componentassociation_protocolid", FT_UINT16
, BASE_DEC
|BASE_EXT_STRING
, &ipproto_val_ext
, 0x0, NULL
, HFILL
} },
130 { &hf_cspreport_association_ppid
, { "PPID", "componentstatusprotocol.componentassociation_ppid", FT_UINT32
, BASE_DEC
|BASE_EXT_STRING
, &sctpppid_val_ext
, 0x0, NULL
, HFILL
} },
134 typedef struct _tap_componentstatusprotocol_rec_t
{
137 const char* type_string
;
138 } tap_componentstatusprotocol_rec_t
;
142 dissect_componentstatusprotocol_cspreport_association(tvbuff_t
*message_tvb
, proto_tree
*message_tree
)
144 proto_item
* receiver_id_item
;
145 proto_tree
* receiver_id_tree
;
149 receiver_id_item
= proto_tree_add_item(message_tree
, hf_cspreport_association_receiver_id
, message_tvb
, 0, 8, ENC_BIG_ENDIAN
);
150 receiver_id_tree
= proto_item_add_subtree(receiver_id_item
, ett_cspreport_association_receiver_id
);
151 proto_tree_add_item(receiver_id_tree
, hf_cspreport_association_receiver_id_group
, message_tvb
, 0, 1, ENC_BIG_ENDIAN
);
152 proto_tree_add_item(receiver_id_tree
, hf_cspreport_association_receiver_id_object
, message_tvb
, 1, 7, ENC_BIG_ENDIAN
);
154 timestamp
= tvb_get_ntoh64(message_tvb
, 8);
155 t
.secs
= (time_t)(timestamp
/ 1000000);
156 t
.nsecs
= (int)((timestamp
- 1000000 * t
.secs
) * 1000);
157 if(timestamp
== 0xffffffffffffffffULL
) {
158 proto_tree_add_time_format(message_tree
, hf_cspreport_association_duration
, message_tvb
, 8, 8, &t
, "Duration: unknown");
161 proto_tree_add_time(message_tree
, hf_cspreport_association_duration
, message_tvb
, 8, 8, &t
);
164 proto_tree_add_item(message_tree
, hf_cspreport_association_flags
, message_tvb
, 16, 2, ENC_BIG_ENDIAN
);
165 proto_tree_add_item(message_tree
, hf_cspreport_association_protocolid
, message_tvb
, 18, 2, ENC_BIG_ENDIAN
);
166 proto_tree_add_item(message_tree
, hf_cspreport_association_ppid
, message_tvb
, 20, 4, ENC_BIG_ENDIAN
);
171 dissect_componentstatusprotocol_cspreport_message(tvbuff_t
*message_tvb
, proto_tree
*message_tree
)
173 tvbuff_t
*association_tvb
;
174 proto_tree
*association_tree
;
181 interval
= tvb_get_ntohl(message_tvb
, 24);
182 t
.secs
= (time_t)(interval
/ 1000000);
183 t
.nsecs
= (int)((interval
- 1000000 * t
.secs
) * 1000);
184 proto_tree_add_time(message_tree
, hf_cspreport_report_interval
, message_tvb
, 24, 4, &t
);
185 proto_tree_add_item(message_tree
, hf_cspreport_location
, message_tvb
, 28, 128, ENC_UTF_8
);
186 proto_tree_add_item(message_tree
, hf_cspreport_status
, message_tvb
, 156, 128, ENC_UTF_8
);
188 workload
= (float)(100.0 * CSR_GET_WORKLOAD(tvb_get_ntohs(message_tvb
, 284)));
189 if(workload
< 0.0) { /* Special value 0xffff -> -1.0 means "no load provided"! */
190 proto_tree_add_float_format(message_tree
, hf_cspreport_workload
, message_tvb
, 284, 2,
191 workload
, "Workload: N/A");
194 proto_tree_add_float_format_value(message_tree
, hf_cspreport_workload
, message_tvb
, 284, 2,
195 workload
, "%1.2f%%", workload
);
197 proto_tree_add_item(message_tree
, hf_cspreport_associations
, message_tvb
, 286, 2, ENC_BIG_ENDIAN
);
201 while(tvb_reported_length_remaining(message_tvb
, offset
) >= 24) {
202 association_tree
= proto_tree_add_subtree_format(message_tree
, message_tvb
, offset
, 24,
203 ett_association
, NULL
, "Association #%d", association
++);
204 association_tvb
= tvb_new_subset_length_caplen(message_tvb
, offset
,
205 MIN(24, tvb_reported_length_remaining(message_tvb
, offset
)),
208 dissect_componentstatusprotocol_cspreport_association(association_tvb
, association_tree
);
215 dissect_componentstatusprotocol_message(tvbuff_t
*message_tvb
, packet_info
*pinfo
, proto_tree
*componentstatusprotocol_tree
)
217 proto_item
* flags_item
;
218 proto_tree
* flags_tree
;
219 proto_item
* sender_id_item
;
220 proto_tree
* sender_id_tree
;
224 tap_componentstatusprotocol_rec_t
* tap_rec
= wmem_new0(pinfo
->pool
, tap_componentstatusprotocol_rec_t
);
225 tap_rec
->type
= tvb_get_uint8(message_tvb
, 0);
226 tap_rec
->size
= tvb_get_ntohs(message_tvb
, 2);
227 tap_rec
->type_string
= val_to_str_const(tap_rec
->type
, message_type_values
, "Unknown ComponentStatusProtocol message type");
228 tap_queue_packet(tap_componentstatusprotocol
, pinfo
, tap_rec
);
230 proto_tree_add_item(componentstatusprotocol_tree
, hf_message_type
, message_tvb
, 0, 1, ENC_BIG_ENDIAN
);
231 flags_item
= proto_tree_add_item(componentstatusprotocol_tree
, hf_message_flags
, message_tvb
, 1, 1, ENC_BIG_ENDIAN
);
232 flags_tree
= proto_item_add_subtree(flags_item
, ett_message_flags
);
233 proto_tree_add_item(flags_tree
, hf_message_flags_final_bit
, message_tvb
, 1, 1, ENC_BIG_ENDIAN
);
234 proto_tree_add_item(componentstatusprotocol_tree
, hf_message_length
, message_tvb
, 2, 2, ENC_BIG_ENDIAN
);
236 proto_tree_add_item(componentstatusprotocol_tree
, hf_message_version
, message_tvb
, 4, 4, ENC_BIG_ENDIAN
);
237 sender_id_item
= proto_tree_add_item(componentstatusprotocol_tree
, hf_message_sender_id
, message_tvb
, 8, 8, ENC_BIG_ENDIAN
);
238 sender_id_tree
= proto_item_add_subtree(sender_id_item
, ett_message_sender_id
);
239 proto_tree_add_item(sender_id_tree
, hf_message_sender_id_group
, message_tvb
, 8, 1, ENC_BIG_ENDIAN
);
240 proto_tree_add_item(sender_id_tree
, hf_message_sender_id_object
, message_tvb
, 9, 7, ENC_BIG_ENDIAN
);
242 timestamp
= tvb_get_ntoh64(message_tvb
, 16);
243 t
.secs
= (time_t)(timestamp
/ 1000000);
244 t
.nsecs
= (int)((timestamp
- 1000000 * t
.secs
) * 1000);
245 proto_tree_add_time(componentstatusprotocol_tree
, hf_message_sender_timestamp
, message_tvb
, 16, 8, &t
);
247 switch (tap_rec
->type
) {
248 case COMPONENTSTATUS_REPORT
:
249 dissect_componentstatusprotocol_cspreport_message(message_tvb
, componentstatusprotocol_tree
);
256 dissect_componentstatusprotocol(tvbuff_t
*message_tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
258 proto_item
*componentstatusprotocol_item
;
259 proto_tree
*componentstatusprotocol_tree
;
263 if (tvb_reported_length(message_tvb
) < 4 + 4)
266 /* Check, if this packet really contains a ComponentStatusProtocol message */
267 type
= tvb_get_uint8(message_tvb
, 0);
268 if (type
!= COMPONENTSTATUS_REPORT
) {
271 version
= tvb_get_ntohl(message_tvb
, 4);
272 if (version
!= COMPONENTSTATUSPROTOCOL_VERSION
) {
276 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ComponentStatusProtocol");
278 /* create the componentstatusprotocol protocol tree */
279 componentstatusprotocol_item
= proto_tree_add_item(tree
, proto_componentstatusprotocol
, message_tvb
, 0, -1, ENC_NA
);
280 componentstatusprotocol_tree
= proto_item_add_subtree(componentstatusprotocol_item
, ett_componentstatusprotocol
);
282 /* dissect the message */
283 dissect_componentstatusprotocol_message(message_tvb
, pinfo
, componentstatusprotocol_tree
);
284 return tvb_reported_length(message_tvb
);
291 MESSAGE_TYPE_COLUMN
= 0,
293 MESSAGES_SHARE_COLUMN
,
301 } componentstatusprotocol_stat_columns
;
303 static stat_tap_table_item componentstatusprotocol_stat_fields
[] = {
304 { TABLE_ITEM_STRING
, TAP_ALIGN_LEFT
, "ComponentStatusProtocol Message Type", "%-25s" },
305 { TABLE_ITEM_UINT
, TAP_ALIGN_RIGHT
, "Messages ", "%u" },
306 { TABLE_ITEM_UINT
, TAP_ALIGN_RIGHT
, "Messages Share (%)" , "%1.3f %%" },
307 { TABLE_ITEM_UINT
, TAP_ALIGN_RIGHT
, "Bytes (B)", "%u" },
308 { TABLE_ITEM_UINT
, TAP_ALIGN_RIGHT
, "Bytes Share (%) ", "%1.3f %%" },
309 { TABLE_ITEM_FLOAT
, TAP_ALIGN_LEFT
, "First Seen (s)", "%1.6f" },
310 { TABLE_ITEM_FLOAT
, TAP_ALIGN_LEFT
, "Last Seen (s)", "%1.6f" },
311 { TABLE_ITEM_FLOAT
, TAP_ALIGN_LEFT
, "Interval (s)", "%1.6f" },
312 { TABLE_ITEM_FLOAT
, TAP_ALIGN_LEFT
, "Message Rate (Msg/s)", "%1.2f" },
313 { TABLE_ITEM_FLOAT
, TAP_ALIGN_LEFT
, "Byte Rate (B/s)", "%1.2f" }
316 static void componentstatusprotocol_stat_init(stat_tap_table_ui
* new_stat
)
318 const char *table_name
= "ComponentStatusProtocol Statistics";
319 int num_fields
= array_length(componentstatusprotocol_stat_fields
);
320 stat_tap_table
*table
;
322 stat_tap_table_item_type items
[array_length(componentstatusprotocol_stat_fields
)];
324 table
= stat_tap_find_table(new_stat
, table_name
);
326 if (new_stat
->stat_tap_reset_table_cb
) {
327 new_stat
->stat_tap_reset_table_cb(table
);
332 table
= stat_tap_init_table(table_name
, num_fields
, 0, NULL
);
333 stat_tap_add_table(new_stat
, table
);
335 memset(items
, 0x0, sizeof(items
));
336 /* Add a row for each value type */
337 while (message_type_values
[i
].strptr
) {
338 items
[MESSAGE_TYPE_COLUMN
].type
= TABLE_ITEM_STRING
;
339 items
[MESSAGE_TYPE_COLUMN
].value
.string_value
= message_type_values
[i
].strptr
;
340 items
[MESSAGES_COLUMN
].type
= TABLE_ITEM_UINT
;
341 items
[MESSAGES_COLUMN
].value
.uint_value
= 0;
342 items
[MESSAGES_SHARE_COLUMN
].type
= TABLE_ITEM_NONE
;
343 items
[MESSAGES_SHARE_COLUMN
].value
.float_value
= -1.0;
344 items
[BYTES_COLUMN
].type
= TABLE_ITEM_UINT
;
345 items
[BYTES_COLUMN
].value
.uint_value
= 0;
346 items
[BYTES_SHARE_COLUMN
].type
= TABLE_ITEM_NONE
;
347 items
[BYTES_SHARE_COLUMN
].value
.float_value
= -1.0;
348 items
[FIRST_SEEN_COLUMN
].type
= TABLE_ITEM_NONE
;
349 items
[FIRST_SEEN_COLUMN
].value
.float_value
= DBL_MAX
;
350 items
[LAST_SEEN_COLUMN
].type
= TABLE_ITEM_NONE
;
351 items
[LAST_SEEN_COLUMN
].value
.float_value
= DBL_MIN
;
352 items
[INTERVAL_COLUMN
].type
= TABLE_ITEM_NONE
;
353 items
[INTERVAL_COLUMN
].value
.float_value
= -1.0;
354 items
[MESSAGE_RATE_COLUMN
].type
= TABLE_ITEM_NONE
;
355 items
[MESSAGE_RATE_COLUMN
].value
.float_value
= -1.0;
356 items
[BYTE_RATE_COLUMN
].type
= TABLE_ITEM_NONE
;
357 items
[BYTE_RATE_COLUMN
].value
.float_value
= -1.0;
358 stat_tap_init_table_row(table
, i
, num_fields
, items
);
363 static tap_packet_status
364 componentstatusprotocol_stat_packet(void* tapdata
, packet_info
* pinfo _U_
, epan_dissect_t
* edt _U_
, const void* data
, tap_flags_t flags _U_
)
366 stat_data_t
* stat_data
= (stat_data_t
*)tapdata
;
367 const tap_componentstatusprotocol_rec_t
* tap_rec
= (const tap_componentstatusprotocol_rec_t
*)data
;
368 stat_tap_table
* table
;
369 stat_tap_table_item_type
* msg_data
;
374 double firstSeen
= -1.0;
375 double lastSeen
= -1.0;
377 idx
= str_to_val_idx(tap_rec
->type_string
, message_type_values
);
379 return TAP_PACKET_DONT_REDRAW
;
381 table
= g_array_index(stat_data
->stat_tap_data
->tables
, stat_tap_table
*, 0);
383 /* Update packets counter */
384 componentstatusprotocol_total_msgs
++;
385 msg_data
= stat_tap_get_field_data(table
, idx
, MESSAGES_COLUMN
);
386 msg_data
->value
.uint_value
++;
387 messages
= msg_data
->value
.uint_value
;
388 stat_tap_set_field_data(table
, idx
, MESSAGES_COLUMN
, msg_data
);
390 /* Update bytes counter */
391 componentstatusprotocol_total_bytes
+= tap_rec
->size
;
392 msg_data
= stat_tap_get_field_data(table
, idx
, BYTES_COLUMN
);
393 msg_data
->value
.uint_value
+= tap_rec
->size
;
394 bytes
= msg_data
->value
.uint_value
;
395 stat_tap_set_field_data(table
, idx
, BYTES_COLUMN
, msg_data
);
397 /* Update messages and bytes share */
398 while (message_type_values
[i
].strptr
) {
399 msg_data
= stat_tap_get_field_data(table
, i
, MESSAGES_COLUMN
);
400 const unsigned m
= msg_data
->value
.uint_value
;
401 msg_data
= stat_tap_get_field_data(table
, i
, BYTES_COLUMN
);
402 const unsigned b
= msg_data
->value
.uint_value
;
404 msg_data
= stat_tap_get_field_data(table
, i
, MESSAGES_SHARE_COLUMN
);
405 msg_data
->type
= TABLE_ITEM_FLOAT
;
406 msg_data
->value
.float_value
= 100.0 * m
/ (double)componentstatusprotocol_total_msgs
;
407 stat_tap_set_field_data(table
, i
, MESSAGES_SHARE_COLUMN
, msg_data
);
409 msg_data
= stat_tap_get_field_data(table
, i
, BYTES_SHARE_COLUMN
);
410 msg_data
->type
= TABLE_ITEM_FLOAT
;
411 msg_data
->value
.float_value
= 100.0 * b
/ (double)componentstatusprotocol_total_bytes
;
412 stat_tap_set_field_data(table
, i
, BYTES_SHARE_COLUMN
, msg_data
);
416 /* Update first seen time */
417 if (pinfo
->presence_flags
& PINFO_HAS_TS
) {
418 msg_data
= stat_tap_get_field_data(table
, idx
, FIRST_SEEN_COLUMN
);
419 msg_data
->type
= TABLE_ITEM_FLOAT
;
420 msg_data
->value
.float_value
= MIN(msg_data
->value
.float_value
, nstime_to_sec(&pinfo
->rel_ts
));
421 firstSeen
= msg_data
->value
.float_value
;
422 stat_tap_set_field_data(table
, idx
, FIRST_SEEN_COLUMN
, msg_data
);
425 /* Update last seen time */
426 if (pinfo
->presence_flags
& PINFO_HAS_TS
) {
427 msg_data
= stat_tap_get_field_data(table
, idx
, LAST_SEEN_COLUMN
);
428 msg_data
->type
= TABLE_ITEM_FLOAT
;
429 msg_data
->value
.float_value
= MAX(msg_data
->value
.float_value
, nstime_to_sec(&pinfo
->rel_ts
));
430 lastSeen
= msg_data
->value
.float_value
;
431 stat_tap_set_field_data(table
, idx
, LAST_SEEN_COLUMN
, msg_data
);
434 if ((lastSeen
- firstSeen
) > 0.0) {
435 /* Update interval */
436 msg_data
= stat_tap_get_field_data(table
, idx
, INTERVAL_COLUMN
);
437 msg_data
->type
= TABLE_ITEM_FLOAT
;
438 msg_data
->value
.float_value
= lastSeen
- firstSeen
;
439 stat_tap_set_field_data(table
, idx
, INTERVAL_COLUMN
, msg_data
);
441 /* Update message rate */
442 msg_data
= stat_tap_get_field_data(table
, idx
, MESSAGE_RATE_COLUMN
);
443 msg_data
->type
= TABLE_ITEM_FLOAT
;
444 msg_data
->value
.float_value
= messages
/ (lastSeen
- firstSeen
);
445 stat_tap_set_field_data(table
, idx
, MESSAGE_RATE_COLUMN
, msg_data
);
447 /* Update byte rate */
448 msg_data
= stat_tap_get_field_data(table
, idx
, BYTE_RATE_COLUMN
);
449 msg_data
->type
= TABLE_ITEM_FLOAT
;
450 msg_data
->value
.float_value
= bytes
/ (lastSeen
- firstSeen
);
451 stat_tap_set_field_data(table
, idx
, BYTE_RATE_COLUMN
, msg_data
);
454 return TAP_PACKET_REDRAW
;
458 componentstatusprotocol_stat_reset(stat_tap_table
* table
)
461 stat_tap_table_item_type
* item_data
;
463 for (element
= 0; element
< table
->num_elements
; element
++) {
464 item_data
= stat_tap_get_field_data(table
, element
, MESSAGES_COLUMN
);
465 item_data
->value
.uint_value
= 0;
466 stat_tap_set_field_data(table
, element
, MESSAGES_COLUMN
, item_data
);
468 item_data
= stat_tap_get_field_data(table
, element
, MESSAGES_SHARE_COLUMN
);
469 item_data
->type
= TABLE_ITEM_NONE
;
470 item_data
->value
.float_value
= -1.0;
471 stat_tap_set_field_data(table
, element
, MESSAGES_SHARE_COLUMN
, item_data
);
473 item_data
= stat_tap_get_field_data(table
, element
, BYTES_COLUMN
);
474 item_data
->value
.uint_value
= 0;
475 stat_tap_set_field_data(table
, element
, BYTES_COLUMN
, item_data
);
477 item_data
= stat_tap_get_field_data(table
, element
, BYTES_SHARE_COLUMN
);
478 item_data
->type
= TABLE_ITEM_NONE
;
479 item_data
->value
.float_value
= -1.0;
480 stat_tap_set_field_data(table
, element
, BYTES_SHARE_COLUMN
, item_data
);
482 item_data
= stat_tap_get_field_data(table
, element
, FIRST_SEEN_COLUMN
);
483 item_data
->type
= TABLE_ITEM_NONE
;
484 item_data
->value
.float_value
= DBL_MAX
;
485 stat_tap_set_field_data(table
, element
, FIRST_SEEN_COLUMN
, item_data
);
487 item_data
= stat_tap_get_field_data(table
, element
, LAST_SEEN_COLUMN
);
488 item_data
->type
= TABLE_ITEM_NONE
;
489 item_data
->value
.float_value
= DBL_MIN
;
490 stat_tap_set_field_data(table
, element
, LAST_SEEN_COLUMN
, item_data
);
492 item_data
= stat_tap_get_field_data(table
, element
, INTERVAL_COLUMN
);
493 item_data
->type
= TABLE_ITEM_NONE
;
494 item_data
->value
.float_value
= -1.0;
495 stat_tap_set_field_data(table
, element
, INTERVAL_COLUMN
, item_data
);
497 item_data
= stat_tap_get_field_data(table
, element
, MESSAGE_RATE_COLUMN
);
498 item_data
->type
= TABLE_ITEM_NONE
;
499 item_data
->value
.float_value
= -1.0;
500 stat_tap_set_field_data(table
, element
, MESSAGE_RATE_COLUMN
, item_data
);
502 item_data
= stat_tap_get_field_data(table
, element
, BYTE_RATE_COLUMN
);
503 item_data
->type
= TABLE_ITEM_NONE
;
504 item_data
->value
.float_value
= -1.0;
505 stat_tap_set_field_data(table
, element
, BYTE_RATE_COLUMN
, item_data
);
507 componentstatusprotocol_total_msgs
= 0;
508 componentstatusprotocol_total_bytes
= 0;
512 /* Register the protocol with Wireshark */
514 proto_register_componentstatusprotocol(void)
516 /* Setup protocol subtree array */
517 static int *ett
[] = {
518 &ett_componentstatusprotocol
,
520 &ett_message_sender_id
,
521 &ett_cspreport_association_receiver_id
,
525 static tap_param componentstatusprotocol_stat_params
[] = {
526 { PARAM_FILTER
, "filter", "Filter", NULL
, true }
529 static stat_tap_table_ui componentstatusprotocol_stat_table
= {
530 REGISTER_STAT_GROUP_RSERPOOL
,
531 "ComponentStatusProtocol Statistics",
532 "componentstatusprotocol",
533 "componentstatusprotocol,stat",
534 componentstatusprotocol_stat_init
,
535 componentstatusprotocol_stat_packet
,
536 componentstatusprotocol_stat_reset
,
539 array_length(componentstatusprotocol_stat_fields
), componentstatusprotocol_stat_fields
,
540 array_length(componentstatusprotocol_stat_params
), componentstatusprotocol_stat_params
,
545 /* Register the protocol name and description */
546 proto_componentstatusprotocol
= proto_register_protocol("Component Status Protocol", "ComponentStatusProtocol", "componentstatusprotocol");
548 /* Required function calls to register the header fields and subtrees used */
549 proto_register_field_array(proto_componentstatusprotocol
, hf
, array_length(hf
));
550 proto_register_subtree_array(ett
, array_length(ett
));
551 tap_componentstatusprotocol
= register_tap("componentstatusprotocol");
553 /* Register the dissector */
554 componentstatusprotocol_handle
= register_dissector("componentstatusprotocol", dissect_componentstatusprotocol
, proto_componentstatusprotocol
);
556 register_stat_tap_table_ui(&componentstatusprotocol_stat_table
);
560 proto_reg_handoff_componentstatusprotocol(void)
562 dissector_add_uint_with_preference("udp.port", COMPONENTSTATUSPROTOCOL_PORT
, componentstatusprotocol_handle
);
571 * indent-tabs-mode: nil
574 * ex: set shiftwidth=2 tabstop=8 expandtab:
575 * :indentSize=2:tabSize=8:noTabs=true: