Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-componentstatus.c
Line
Count
Source
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/
5
 *
6
 * Copyright 2006-2021 by Thomas Dreibholz <dreibh [AT] iem.uni-due.de>
7
 *
8
 * Wireshark - Network traffic analyzer
9
 * By Gerald Combs <gerald@wireshark.org>
10
 * Copyright 1998 Gerald Combs
11
 *
12
 * Copied from README.developer
13
 *
14
 * SPDX-License-Identifier: GPL-2.0-or-later
15
 */
16
17
#include "config.h"
18
19
#include <epan/packet.h>
20
#include <epan/stat_tap_ui.h>
21
#include <epan/tfs.h>
22
#include <wsutil/array.h>
23
#include "packet-sctp.h"
24
#include <epan/iana-info.h>
25
26
27
void proto_register_componentstatusprotocol(void);
28
void proto_reg_handoff_componentstatusprotocol(void);
29
30
static dissector_handle_t componentstatusprotocol_handle;
31
32
/* Initialize the protocol and registered fields */
33
static int proto_componentstatusprotocol;
34
static int tap_componentstatusprotocol   = -1;
35
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;
42
43
44
16
#define COMPONENTSTATUSPROTOCOL_PORT    2960   /* Not IANA registered */
45
0
#define COMPONENTSTATUSPROTOCOL_VERSION 0x0200
46
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;
56
57
static uint64_t componentstatusprotocol_total_msgs;
58
static uint64_t componentstatusprotocol_total_bytes;
59
60
61
0
#define COMPONENTSTATUS_REPORT 0x01
62
63
static const value_string message_type_values[] = {
64
  { COMPONENTSTATUS_REPORT, "ComponentStatus Report" },
65
  { 0, NULL }
66
};
67
68
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;
74
75
#define CSPF_FINAL (1 << 0)
76
static const true_false_string message_flags_final_bit = {
77
  "Final message",
78
  "Not final message"
79
};
80
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" },
92
  { 0, NULL }
93
};
94
95
0
#define CSR_GET_WORKLOAD(w) ((w == 0xffff) ? -1.0 : (float)(w / (float)0xfffe))
96
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;
104
105
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 } },
117
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 } },
123
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 } },
131
};
132
133
134
typedef struct _tap_componentstatusprotocol_rec_t {
135
  uint8_t     type;
136
  uint16_t    size;
137
  const char* type_string;
138
} tap_componentstatusprotocol_rec_t;
139
140
141
static void
142
dissect_componentstatusprotocol_cspreport_association(tvbuff_t *message_tvb, proto_tree *message_tree)
143
0
{
144
0
  proto_item* receiver_id_item;
145
0
  proto_tree* receiver_id_tree;
146
0
  uint64_t    timestamp;
147
0
  nstime_t    t;
148
149
0
  receiver_id_item = proto_tree_add_item(message_tree, hf_cspreport_association_receiver_id, message_tvb, 0, 8, ENC_BIG_ENDIAN);
150
0
  receiver_id_tree = proto_item_add_subtree(receiver_id_item, ett_cspreport_association_receiver_id);
151
0
  proto_tree_add_item(receiver_id_tree, hf_cspreport_association_receiver_id_group,  message_tvb, 0, 1, ENC_BIG_ENDIAN);
152
0
  proto_tree_add_item(receiver_id_tree, hf_cspreport_association_receiver_id_object, message_tvb, 1, 7, ENC_BIG_ENDIAN);
153
154
0
  timestamp = tvb_get_ntoh64(message_tvb, 8);
155
0
  t.secs  = (time_t)(timestamp / 1000000);
156
0
  t.nsecs = (int)((timestamp - 1000000 * t.secs) * 1000);
157
0
  if(timestamp == 0xffffffffffffffffULL) {
158
0
    proto_tree_add_time_format_value(message_tree, hf_cspreport_association_duration, message_tvb, 8, 8, &t, "Unknown");
159
0
  }
160
0
  else {
161
0
    proto_tree_add_time(message_tree, hf_cspreport_association_duration, message_tvb, 8, 8, &t);
162
0
  }
163
164
0
  proto_tree_add_item(message_tree, hf_cspreport_association_flags,      message_tvb, 16, 2, ENC_BIG_ENDIAN);
165
0
  proto_tree_add_item(message_tree, hf_cspreport_association_protocolid, message_tvb, 18, 2, ENC_BIG_ENDIAN);
166
0
  proto_tree_add_item(message_tree, hf_cspreport_association_ppid,       message_tvb, 20, 4, ENC_BIG_ENDIAN);
167
0
}
168
169
170
static void
171
dissect_componentstatusprotocol_cspreport_message(tvbuff_t *message_tvb, proto_tree *message_tree)
172
0
{
173
0
  tvbuff_t   *association_tvb;
174
0
  proto_tree *association_tree;
175
0
  int         association;
176
0
  int         offset;
177
0
  float       workload;
178
0
  uint64_t    interval;
179
0
  nstime_t    t;
180
181
0
  interval = tvb_get_ntohl(message_tvb, 24);
182
0
  t.secs  = (time_t)(interval / 1000000);
183
0
  t.nsecs = (int)((interval - 1000000 * t.secs) * 1000);
184
0
  proto_tree_add_time(message_tree, hf_cspreport_report_interval, message_tvb,  24,   4, &t);
185
0
  proto_tree_add_item(message_tree, hf_cspreport_location,        message_tvb,  28, 128, ENC_UTF_8);
186
0
  proto_tree_add_item(message_tree, hf_cspreport_status,          message_tvb, 156, 128, ENC_UTF_8);
187
188
0
  workload = (float)(100.0 * CSR_GET_WORKLOAD(tvb_get_ntohs(message_tvb, 284)));
189
0
  if(workload < 0.0) {   /* Special value 0xffff -> -1.0 means "no load provided"! */
190
0
     proto_tree_add_float_format_value(message_tree, hf_cspreport_workload, message_tvb, 284, 2,
191
0
                                workload, "N/A");
192
0
  }
193
0
  else {
194
0
     proto_tree_add_float_format_value(message_tree, hf_cspreport_workload, message_tvb, 284, 2,
195
0
                                       workload, "%1.2f%%", workload);
196
0
  }
197
0
  proto_tree_add_item(message_tree, hf_cspreport_associations, message_tvb, 286, 2, ENC_BIG_ENDIAN);
198
199
0
  association = 1;
200
0
  offset      = 288;
201
0
  while(tvb_reported_length_remaining(message_tvb, offset) >= 24) {
202
0
     association_tree = proto_tree_add_subtree_format(message_tree, message_tvb, offset, 24,
203
0
         ett_association, NULL, "Association #%d", association++);
204
0
     association_tvb  = tvb_new_subset_length(message_tvb, offset, 24);
205
206
0
     dissect_componentstatusprotocol_cspreport_association(association_tvb, association_tree);
207
0
     offset += 24;
208
0
  }
209
0
}
210
211
212
static void
213
dissect_componentstatusprotocol_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *componentstatusprotocol_tree)
214
0
{
215
0
  proto_item* flags_item;
216
0
  proto_tree* flags_tree;
217
0
  proto_item* sender_id_item;
218
0
  proto_tree* sender_id_tree;
219
0
  uint64_t    timestamp;
220
0
  nstime_t    t;
221
222
0
  tap_componentstatusprotocol_rec_t* tap_rec = wmem_new0(pinfo->pool, tap_componentstatusprotocol_rec_t);
223
0
  tap_rec->type        = tvb_get_uint8(message_tvb, 0);
224
0
  tap_rec->size        = tvb_get_ntohs(message_tvb, 2);
225
0
  tap_rec->type_string = val_to_str_const(tap_rec->type, message_type_values, "Unknown ComponentStatusProtocol message type");
226
0
  tap_queue_packet(tap_componentstatusprotocol, pinfo, tap_rec);
227
228
0
  proto_tree_add_item(componentstatusprotocol_tree, hf_message_type, message_tvb, 0, 1, ENC_BIG_ENDIAN);
229
0
  flags_item = proto_tree_add_item(componentstatusprotocol_tree, hf_message_flags, message_tvb, 1, 1, ENC_BIG_ENDIAN);
230
0
  flags_tree = proto_item_add_subtree(flags_item, ett_message_flags);
231
0
  proto_tree_add_item(flags_tree, hf_message_flags_final_bit, message_tvb, 1, 1, ENC_BIG_ENDIAN);
232
0
  proto_tree_add_item(componentstatusprotocol_tree, hf_message_length, message_tvb, 2, 2, ENC_BIG_ENDIAN);
233
234
0
  proto_tree_add_item(componentstatusprotocol_tree, hf_message_version, message_tvb, 4, 4, ENC_BIG_ENDIAN);
235
0
  sender_id_item = proto_tree_add_item(componentstatusprotocol_tree, hf_message_sender_id, message_tvb, 8, 8, ENC_BIG_ENDIAN);
236
0
  sender_id_tree = proto_item_add_subtree(sender_id_item, ett_message_sender_id);
237
0
  proto_tree_add_item(sender_id_tree, hf_message_sender_id_group,  message_tvb, 8, 1, ENC_BIG_ENDIAN);
238
0
  proto_tree_add_item(sender_id_tree, hf_message_sender_id_object, message_tvb, 9, 7, ENC_BIG_ENDIAN);
239
240
0
  timestamp = tvb_get_ntoh64(message_tvb, 16);
241
0
  t.secs  = (time_t)(timestamp / 1000000);
242
0
  t.nsecs = (int)((timestamp - 1000000 * t.secs) * 1000);
243
0
  proto_tree_add_time(componentstatusprotocol_tree, hf_message_sender_timestamp, message_tvb, 16, 8, &t);
244
245
0
  switch (tap_rec->type) {
246
0
    case COMPONENTSTATUS_REPORT:
247
0
      dissect_componentstatusprotocol_cspreport_message(message_tvb, componentstatusprotocol_tree);
248
0
     break;
249
0
  }
250
0
}
251
252
253
static int
254
dissect_componentstatusprotocol(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
255
0
{
256
0
  proto_item *componentstatusprotocol_item;
257
0
  proto_tree *componentstatusprotocol_tree;
258
0
  int8_t type;
259
0
  int32_t version;
260
261
0
  if (tvb_reported_length(message_tvb) < 4 + 4)
262
0
    return 0;
263
264
  /* Check, if this packet really contains a ComponentStatusProtocol message */
265
0
  type = tvb_get_uint8(message_tvb, 0);
266
0
  if (type != COMPONENTSTATUS_REPORT) {
267
0
    return 0;
268
0
  }
269
0
  version = tvb_get_ntohl(message_tvb, 4);
270
0
  if (version != COMPONENTSTATUSPROTOCOL_VERSION) {
271
0
    return 0;
272
0
  }
273
274
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "ComponentStatusProtocol");
275
276
  /* create the componentstatusprotocol protocol tree */
277
0
  componentstatusprotocol_item = proto_tree_add_item(tree, proto_componentstatusprotocol, message_tvb, 0, -1, ENC_NA);
278
0
  componentstatusprotocol_tree = proto_item_add_subtree(componentstatusprotocol_item, ett_componentstatusprotocol);
279
280
  /* dissect the message */
281
0
  dissect_componentstatusprotocol_message(message_tvb, pinfo, componentstatusprotocol_tree);
282
0
  return tvb_reported_length(message_tvb);
283
0
}
284
285
286
/* TAP STAT INFO */
287
typedef enum
288
{
289
  MESSAGE_TYPE_COLUMN = 0,
290
  MESSAGES_COLUMN,
291
  MESSAGES_SHARE_COLUMN,
292
  BYTES_COLUMN,
293
  BYTES_SHARE_COLUMN,
294
  FIRST_SEEN_COLUMN,
295
  LAST_SEEN_COLUMN,
296
  INTERVAL_COLUMN,
297
  MESSAGE_RATE_COLUMN,
298
  BYTE_RATE_COLUMN
299
} componentstatusprotocol_stat_columns;
300
301
static stat_tap_table_item componentstatusprotocol_stat_fields[] = {
302
  { TABLE_ITEM_STRING, TAP_ALIGN_LEFT,  "ComponentStatusProtocol Message Type", "%-25s" },
303
  { TABLE_ITEM_UINT,   TAP_ALIGN_RIGHT, "Messages ",            "%u"       },
304
  { TABLE_ITEM_FLOAT,  TAP_ALIGN_RIGHT, "Messages Share (%)"  , "%1.3f %%" },
305
  { TABLE_ITEM_UINT,   TAP_ALIGN_RIGHT, "Bytes (B)",            "%u"       },
306
  { TABLE_ITEM_FLOAT,  TAP_ALIGN_RIGHT, "Bytes Share (%) ",     "%1.3f %%" },
307
  { TABLE_ITEM_FLOAT,  TAP_ALIGN_LEFT,  "First Seen (s)",       "%1.6f"    },
308
  { TABLE_ITEM_FLOAT,  TAP_ALIGN_LEFT,  "Last Seen (s)",        "%1.6f"    },
309
  { TABLE_ITEM_FLOAT,  TAP_ALIGN_LEFT,  "Interval (s)",         "%1.6f"    },
310
  { TABLE_ITEM_FLOAT,  TAP_ALIGN_LEFT,  "Message Rate (Msg/s)", "%1.2f"    },
311
  { TABLE_ITEM_FLOAT,  TAP_ALIGN_LEFT,  "Byte Rate (B/s)",      "%1.2f"    }
312
};
313
314
static void componentstatusprotocol_stat_init(stat_tap_table_ui* new_stat)
315
0
{
316
0
  const char *table_name = "ComponentStatusProtocol Statistics";
317
0
  int num_fields = array_length(componentstatusprotocol_stat_fields);
318
0
  stat_tap_table *table;
319
0
  int i = 0;
320
0
  stat_tap_table_item_type items[array_length(componentstatusprotocol_stat_fields)];
321
322
0
  table = stat_tap_find_table(new_stat, table_name);
323
0
  if (table) {
324
0
    if (new_stat->stat_tap_reset_table_cb) {
325
0
      new_stat->stat_tap_reset_table_cb(table);
326
0
    }
327
0
    return;
328
0
  }
329
330
0
  table = stat_tap_init_table(table_name, num_fields, 0, NULL);
331
0
  stat_tap_add_table(new_stat, table);
332
333
0
  memset(items, 0x0, sizeof(items));
334
  /* Add a row for each value type */
335
0
  while (message_type_values[i].strptr) {
336
0
    items[MESSAGE_TYPE_COLUMN].type                = TABLE_ITEM_STRING;
337
0
    items[MESSAGE_TYPE_COLUMN].value.string_value  = message_type_values[i].strptr;
338
0
    items[MESSAGES_COLUMN].type                    = TABLE_ITEM_UINT;
339
0
    items[MESSAGES_COLUMN].value.uint_value        = 0;
340
0
    items[MESSAGES_SHARE_COLUMN].type              = TABLE_ITEM_NONE;
341
0
    items[MESSAGES_SHARE_COLUMN].value.float_value = -1.0;
342
0
    items[BYTES_COLUMN].type                       = TABLE_ITEM_UINT;
343
0
    items[BYTES_COLUMN].value.uint_value           = 0;
344
0
    items[BYTES_SHARE_COLUMN].type                 = TABLE_ITEM_NONE;
345
0
    items[BYTES_SHARE_COLUMN].value.float_value    = -1.0;
346
0
    items[FIRST_SEEN_COLUMN].type                  = TABLE_ITEM_NONE;
347
0
    items[FIRST_SEEN_COLUMN].value.float_value     = DBL_MAX;
348
0
    items[LAST_SEEN_COLUMN].type                   = TABLE_ITEM_NONE;
349
0
    items[LAST_SEEN_COLUMN].value.float_value      = DBL_MIN;
350
0
    items[INTERVAL_COLUMN].type                    = TABLE_ITEM_NONE;
351
0
    items[INTERVAL_COLUMN].value.float_value       = -1.0;
352
0
    items[MESSAGE_RATE_COLUMN].type                = TABLE_ITEM_NONE;
353
0
    items[MESSAGE_RATE_COLUMN].value.float_value   = -1.0;
354
0
    items[BYTE_RATE_COLUMN].type                   = TABLE_ITEM_NONE;
355
0
    items[BYTE_RATE_COLUMN].value.float_value      = -1.0;
356
0
    stat_tap_init_table_row(table, i, num_fields, items);
357
0
    i++;
358
0
  }
359
0
}
360
361
static tap_packet_status
362
componentstatusprotocol_stat_packet(void* tapdata, packet_info* pinfo _U_, epan_dissect_t* edt _U_, const void* data, tap_flags_t flags _U_)
363
0
{
364
0
  stat_data_t*              stat_data = (stat_data_t*)tapdata;
365
0
  const tap_componentstatusprotocol_rec_t*      tap_rec   = (const tap_componentstatusprotocol_rec_t*)data;
366
0
  stat_tap_table*           table;
367
0
  stat_tap_table_item_type* msg_data;
368
0
  int                       idx;
369
0
  uint64_t                  messages;
370
0
  uint64_t                  bytes;
371
0
  int                       i         = 0;
372
0
  double                    firstSeen = -1.0;
373
0
  double                    lastSeen  = -1.0;
374
375
0
  idx = str_to_val_idx(tap_rec->type_string, message_type_values);
376
0
  if (idx < 0)
377
0
    return TAP_PACKET_DONT_REDRAW;
378
379
0
  table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table*, 0);
380
381
  /* Update packets counter */
382
0
  componentstatusprotocol_total_msgs++;
383
0
  msg_data = stat_tap_get_field_data(table, idx, MESSAGES_COLUMN);
384
0
  msg_data->value.uint_value++;
385
0
  messages = msg_data->value.uint_value;
386
0
  stat_tap_set_field_data(table, idx, MESSAGES_COLUMN, msg_data);
387
388
  /* Update bytes counter */
389
0
  componentstatusprotocol_total_bytes += tap_rec->size;
390
0
  msg_data = stat_tap_get_field_data(table, idx, BYTES_COLUMN);
391
0
  msg_data->value.uint_value += tap_rec->size;
392
0
  bytes = msg_data->value.uint_value;
393
0
  stat_tap_set_field_data(table, idx, BYTES_COLUMN, msg_data);
394
395
  /* Update messages and bytes share */
396
0
  while (message_type_values[i].strptr) {
397
0
    msg_data = stat_tap_get_field_data(table, i, MESSAGES_COLUMN);
398
0
    const unsigned m = msg_data->value.uint_value;
399
0
    msg_data = stat_tap_get_field_data(table, i, BYTES_COLUMN);
400
0
    const unsigned b = msg_data->value.uint_value;
401
402
0
    msg_data = stat_tap_get_field_data(table, i, MESSAGES_SHARE_COLUMN);
403
0
    msg_data->type = TABLE_ITEM_FLOAT;
404
0
    msg_data->value.float_value = 100.0 * m / (double)componentstatusprotocol_total_msgs;
405
0
    stat_tap_set_field_data(table, i, MESSAGES_SHARE_COLUMN, msg_data);
406
407
0
    msg_data = stat_tap_get_field_data(table, i, BYTES_SHARE_COLUMN);
408
0
    msg_data->type = TABLE_ITEM_FLOAT;
409
0
    msg_data->value.float_value = componentstatusprotocol_total_bytes ? 100.0 * b / (double)componentstatusprotocol_total_bytes : 0.0;
410
0
    stat_tap_set_field_data(table, i, BYTES_SHARE_COLUMN, msg_data);
411
0
    i++;
412
0
  }
413
414
  /* Update first seen time */
415
0
  if (pinfo->presence_flags & PINFO_HAS_TS) {
416
0
    msg_data = stat_tap_get_field_data(table, idx, FIRST_SEEN_COLUMN);
417
0
    msg_data->type = TABLE_ITEM_FLOAT;
418
0
    msg_data->value.float_value = MIN(msg_data->value.float_value, nstime_to_sec(&pinfo->rel_ts));
419
0
    firstSeen = msg_data->value.float_value;
420
0
    stat_tap_set_field_data(table, idx, FIRST_SEEN_COLUMN, msg_data);
421
0
  }
422
423
  /* Update last seen time */
424
0
  if (pinfo->presence_flags & PINFO_HAS_TS) {
425
0
    msg_data = stat_tap_get_field_data(table, idx, LAST_SEEN_COLUMN);
426
0
    msg_data->type = TABLE_ITEM_FLOAT;
427
0
    msg_data->value.float_value = MAX(msg_data->value.float_value, nstime_to_sec(&pinfo->rel_ts));
428
0
    lastSeen = msg_data->value.float_value;
429
0
    stat_tap_set_field_data(table, idx, LAST_SEEN_COLUMN, msg_data);
430
0
  }
431
432
0
  if ((lastSeen - firstSeen) > 0.0) {
433
    /* Update interval */
434
0
    msg_data = stat_tap_get_field_data(table, idx, INTERVAL_COLUMN);
435
0
    msg_data->type = TABLE_ITEM_FLOAT;
436
0
    msg_data->value.float_value = lastSeen - firstSeen;
437
0
    stat_tap_set_field_data(table, idx, INTERVAL_COLUMN, msg_data);
438
439
    /* Update message rate */
440
0
    msg_data = stat_tap_get_field_data(table, idx, MESSAGE_RATE_COLUMN);
441
0
    msg_data->type = TABLE_ITEM_FLOAT;
442
0
    msg_data->value.float_value = messages / (lastSeen - firstSeen);
443
0
    stat_tap_set_field_data(table, idx, MESSAGE_RATE_COLUMN, msg_data);
444
445
    /* Update byte rate */
446
0
    msg_data = stat_tap_get_field_data(table, idx, BYTE_RATE_COLUMN);
447
0
    msg_data->type = TABLE_ITEM_FLOAT;
448
0
    msg_data->value.float_value = bytes / (lastSeen - firstSeen);
449
0
    stat_tap_set_field_data(table, idx, BYTE_RATE_COLUMN, msg_data);
450
0
  }
451
452
0
  return TAP_PACKET_REDRAW;
453
0
}
454
455
static void
456
componentstatusprotocol_stat_reset(stat_tap_table* table)
457
0
{
458
0
  unsigned element;
459
0
  stat_tap_table_item_type* item_data;
460
461
0
  for (element = 0; element < table->num_elements; element++) {
462
0
    item_data = stat_tap_get_field_data(table, element, MESSAGES_COLUMN);
463
0
    item_data->value.uint_value = 0;
464
0
    stat_tap_set_field_data(table, element, MESSAGES_COLUMN, item_data);
465
466
0
    item_data = stat_tap_get_field_data(table, element, MESSAGES_SHARE_COLUMN);
467
0
    item_data->type = TABLE_ITEM_NONE;
468
0
    item_data->value.float_value = -1.0;
469
0
    stat_tap_set_field_data(table, element, MESSAGES_SHARE_COLUMN, item_data);
470
471
0
    item_data = stat_tap_get_field_data(table, element, BYTES_COLUMN);
472
0
    item_data->value.uint_value = 0;
473
0
    stat_tap_set_field_data(table, element, BYTES_COLUMN, item_data);
474
475
0
    item_data = stat_tap_get_field_data(table, element, BYTES_SHARE_COLUMN);
476
0
    item_data->type = TABLE_ITEM_NONE;
477
0
    item_data->value.float_value = -1.0;
478
0
    stat_tap_set_field_data(table, element, BYTES_SHARE_COLUMN, item_data);
479
480
0
    item_data = stat_tap_get_field_data(table, element, FIRST_SEEN_COLUMN);
481
0
    item_data->type = TABLE_ITEM_NONE;
482
0
    item_data->value.float_value = DBL_MAX;
483
0
    stat_tap_set_field_data(table, element, FIRST_SEEN_COLUMN, item_data);
484
485
0
    item_data = stat_tap_get_field_data(table, element, LAST_SEEN_COLUMN);
486
0
    item_data->type = TABLE_ITEM_NONE;
487
0
    item_data->value.float_value = DBL_MIN;
488
0
    stat_tap_set_field_data(table, element, LAST_SEEN_COLUMN, item_data);
489
490
0
    item_data = stat_tap_get_field_data(table, element, INTERVAL_COLUMN);
491
0
    item_data->type = TABLE_ITEM_NONE;
492
0
    item_data->value.float_value = -1.0;
493
0
    stat_tap_set_field_data(table, element, INTERVAL_COLUMN, item_data);
494
495
0
    item_data = stat_tap_get_field_data(table, element, MESSAGE_RATE_COLUMN);
496
0
    item_data->type = TABLE_ITEM_NONE;
497
0
    item_data->value.float_value = -1.0;
498
0
    stat_tap_set_field_data(table, element, MESSAGE_RATE_COLUMN, item_data);
499
500
0
    item_data = stat_tap_get_field_data(table, element, BYTE_RATE_COLUMN);
501
0
    item_data->type = TABLE_ITEM_NONE;
502
0
    item_data->value.float_value = -1.0;
503
0
    stat_tap_set_field_data(table, element, BYTE_RATE_COLUMN, item_data);
504
0
  }
505
0
  componentstatusprotocol_total_msgs  = 0;
506
0
  componentstatusprotocol_total_bytes = 0;
507
0
}
508
509
510
/* Register the protocol with Wireshark */
511
void
512
proto_register_componentstatusprotocol(void)
513
16
{
514
  /* Setup protocol subtree array */
515
16
  static int *ett[] = {
516
16
    &ett_componentstatusprotocol,
517
16
    &ett_message_flags,
518
16
    &ett_message_sender_id,
519
16
    &ett_cspreport_association_receiver_id,
520
16
    &ett_association
521
16
  };
522
523
16
  static tap_param componentstatusprotocol_stat_params[] = {
524
16
    { PARAM_FILTER, "filter", "Filter", NULL, true }
525
16
  };
526
527
16
  static stat_tap_table_ui componentstatusprotocol_stat_table = {
528
16
    REGISTER_STAT_GROUP_RSERPOOL,
529
16
    "ComponentStatusProtocol Statistics",
530
16
    "componentstatusprotocol",
531
16
    "componentstatusprotocol,stat",
532
16
    componentstatusprotocol_stat_init,
533
16
    componentstatusprotocol_stat_packet,
534
16
    componentstatusprotocol_stat_reset,
535
16
    NULL,
536
16
    NULL,
537
16
    array_length(componentstatusprotocol_stat_fields), componentstatusprotocol_stat_fields,
538
16
    array_length(componentstatusprotocol_stat_params), componentstatusprotocol_stat_params,
539
16
    NULL,
540
16
    0
541
16
  };
542
543
  /* Register the protocol name and description */
544
16
  proto_componentstatusprotocol = proto_register_protocol("Component Status Protocol", "ComponentStatusProtocol", "componentstatusprotocol");
545
546
  /* Required function calls to register the header fields and subtrees used */
547
16
  proto_register_field_array(proto_componentstatusprotocol, hf, array_length(hf));
548
16
  proto_register_subtree_array(ett, array_length(ett));
549
16
  tap_componentstatusprotocol = register_tap("componentstatusprotocol");
550
551
  /* Register the dissector */
552
16
  componentstatusprotocol_handle = register_dissector("componentstatusprotocol", dissect_componentstatusprotocol, proto_componentstatusprotocol);
553
554
16
  register_stat_tap_table_ui(&componentstatusprotocol_stat_table);
555
16
}
556
557
void
558
proto_reg_handoff_componentstatusprotocol(void)
559
16
{
560
16
  dissector_add_uint_with_preference("udp.port", COMPONENTSTATUSPROTOCOL_PORT, componentstatusprotocol_handle);
561
16
}
562
563
/*
564
 * Editor modelines
565
 *
566
 * Local Variables:
567
 * c-basic-offset: 2
568
 * tab-width: 8
569
 * indent-tabs-mode: nil
570
 * End:
571
 *
572
 * ex: set shiftwidth=2 tabstop=8 expandtab:
573
 * :indentSize=2:tabSize=8:noTabs=true:
574
 */