Wireshark  4.3.0
The Wireshark network protocol analyzer
io_graph_item.h
Go to the documentation of this file.
1 
14 #ifndef __IO_GRAPH_ITEM_H__
15 #define __IO_GRAPH_ITEM_H__
16 
17 #include "cfile.h"
18 #include <wsutil/ws_assert.h>
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif /* __cplusplus */
23 
24 typedef enum {
25  IOG_ITEM_UNIT_FIRST,
26  IOG_ITEM_UNIT_PACKETS = IOG_ITEM_UNIT_FIRST,
27  IOG_ITEM_UNIT_BYTES,
28  IOG_ITEM_UNIT_BITS,
29  IOG_ITEM_UNIT_CALC_SUM,
30  IOG_ITEM_UNIT_CALC_FRAMES,
31  IOG_ITEM_UNIT_CALC_FIELDS,
32  IOG_ITEM_UNIT_CALC_MAX,
33  IOG_ITEM_UNIT_CALC_MIN,
34  IOG_ITEM_UNIT_CALC_AVERAGE,
35  IOG_ITEM_UNIT_CALC_LOAD,
36  IOG_ITEM_UNIT_LAST = IOG_ITEM_UNIT_CALC_LOAD,
37  NUM_IOG_ITEM_UNITS
38 } io_graph_item_unit_t;
39 
40 typedef struct _io_graph_item_t {
41  guint32 frames; /* always calculated, will hold number of frames*/
42  guint64 bytes; /* always calculated, will hold number of bytes*/
43  guint64 fields;
44  gint64 int_max;
45  gint64 int_min;
46  gint64 int_tot;
47  /* XXX - Why do we always use 64-bit ints but split floats between
48  * gfloat and gdouble?
49  */
50  gfloat float_max;
51  gfloat float_min;
52  gfloat float_tot;
53  gdouble double_max;
54  gdouble double_min;
55  gdouble double_tot;
56  nstime_t time_max;
57  nstime_t time_min;
58  nstime_t time_tot;
59  guint32 first_frame_in_invl;
60  guint32 extreme_frame_in_invl; /* frame with min/max value */
61  guint32 last_frame_in_invl;
63 
69 static inline void
70 reset_io_graph_items(io_graph_item_t *items, gsize count) {
71  io_graph_item_t *item;
72  gsize i;
73 
74  for (i = 0; i < count; i++) {
75  item = &items[i];
76 
77  item->frames = 0;
78  item->bytes = 0;
79  item->fields = 0;
80  item->int_max = 0;
81  item->int_min = 0;
82  item->int_tot = 0;
83  item->float_max = 0;
84  item->float_min = 0;
85  item->float_tot = 0;
86  item->double_max = 0;
87  item->double_min = 0;
88  item->double_tot = 0;
89  nstime_set_zero(&item->time_max);
90  nstime_set_zero(&item->time_min);
91  nstime_set_zero(&item->time_tot);
92  item->first_frame_in_invl = 0;
93  item->extreme_frame_in_invl = 0;
94  item->last_frame_in_invl = 0;
95  }
96 }
97 
106 int get_io_graph_index(packet_info *pinfo, int interval);
107 
117 GString *check_field_unit(const char *field_name, int *hf_index, io_graph_item_unit_t item_unit);
118 
129 double get_io_graph_item(const io_graph_item_t *items, io_graph_item_unit_t val_units, int idx, int hf_index, const capture_file *cap_file, int interval, int cur_idx);
130 
145 static inline gboolean
146 update_io_graph_item(io_graph_item_t *items, int idx, packet_info *pinfo, epan_dissect_t *edt, int hf_index, int item_unit, guint32 interval) {
147  io_graph_item_t *item = &items[idx];
148 
149  /* Set the first and last frame num in current interval matching the target field+filter */
150  if (item->first_frame_in_invl == 0) {
151  item->first_frame_in_invl = pinfo->num;
152  }
153  item->last_frame_in_invl = pinfo->num;
154 
155  if (edt && hf_index >= 0) {
156  GPtrArray *gp;
157  guint i;
158 
159  gp = proto_get_finfo_ptr_array(edt->tree, hf_index);
160  if (!gp) {
161  return FALSE;
162  }
163 
164  /* Update the appropriate counters. If fields == 0, this is the first seen
165  * value so set any min/max values accordingly. */
166  for (i=0; i < gp->len; i++) {
167  gint64 new_int64;
168  guint64 new_uint64;
169  float new_float;
170  double new_double;
171  const nstime_t *new_time;
172 
173  switch (proto_registrar_get_ftype(hf_index)) {
174  case FT_UINT8:
175  case FT_UINT16:
176  case FT_UINT24:
177  case FT_UINT32:
178  new_uint64 = fvalue_get_uinteger(((field_info *)gp->pdata[i])->value);
179 
180  if ((new_uint64 > (guint64)item->int_max) || (item->fields == 0)) {
181  item->int_max = new_uint64;
182  item->double_max = (gdouble)new_uint64;
183  if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
184  item->extreme_frame_in_invl = pinfo->num;
185  }
186  }
187  if ((new_uint64 < (guint64)item->int_min) || (item->fields == 0)) {
188  item->int_min = new_uint64;
189  item->double_min = (gdouble)new_uint64;
190  if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
191  item->extreme_frame_in_invl = pinfo->num;
192  }
193  }
194  item->int_tot += new_uint64;
195  item->double_tot += (gdouble)new_uint64;
196  item->fields++;
197  break;
198  case FT_INT8:
199  case FT_INT16:
200  case FT_INT24:
201  case FT_INT32:
202  new_int64 = fvalue_get_sinteger(((field_info *)gp->pdata[i])->value);
203  if ((new_int64 > item->int_max) || (item->fields == 0)) {
204  item->int_max = new_int64;
205  item->double_max = (gdouble)new_int64;
206  if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
207  item->extreme_frame_in_invl = pinfo->num;
208  }
209  }
210  if ((new_int64 < item->int_min) || (item->fields == 0)) {
211  item->int_min = new_int64;
212  item->double_min = (gdouble)new_int64;
213  if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
214  item->extreme_frame_in_invl = pinfo->num;
215  }
216  }
217  item->int_tot += new_int64;
218  item->double_tot += (gdouble)new_int64;
219  item->fields++;
220  break;
221  case FT_UINT40:
222  case FT_UINT48:
223  case FT_UINT56:
224  case FT_UINT64:
225  new_uint64 = fvalue_get_uinteger64(((field_info *)gp->pdata[i])->value);
226  if ((new_uint64 > (guint64)item->int_max) || (item->fields == 0)) {
227  item->int_max = new_uint64;
228  item->double_max = (gdouble)new_uint64;
229  if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
230  item->extreme_frame_in_invl = pinfo->num;
231  }
232  }
233  if ((new_uint64 < (guint64)item->int_min) || (item->fields == 0)) {
234  item->int_min = new_uint64;
235  item->double_min = (gdouble)new_uint64;
236  if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
237  item->extreme_frame_in_invl = pinfo->num;
238  }
239  }
240  item->int_tot += new_uint64;
241  item->double_tot += (gdouble)new_uint64;
242  item->fields++;
243  break;
244  case FT_INT40:
245  case FT_INT48:
246  case FT_INT56:
247  case FT_INT64:
248  new_int64 = fvalue_get_sinteger64(((field_info *)gp->pdata[i])->value);
249  if ((new_int64 > item->int_max) || (item->fields == 0)) {
250  item->int_max = new_int64;
251  item->double_max = (gdouble)new_int64;
252  if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
253  item->extreme_frame_in_invl = pinfo->num;
254  }
255  }
256  if ((new_int64 < item->int_min) || (item->fields == 0)) {
257  item->int_min = new_int64;
258  item->double_min = (gdouble)new_int64;
259  if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
260  item->extreme_frame_in_invl = pinfo->num;
261  }
262  }
263  item->int_tot += new_int64;
264  item->double_tot += (gdouble)new_int64;
265  item->fields++;
266  break;
267  case FT_FLOAT:
268  new_float = (gfloat)fvalue_get_floating(((field_info *)gp->pdata[i])->value);
269  if ((new_float > item->float_max) || (item->fields == 0)) {
270  item->float_max = new_float;
271  if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
272  item->extreme_frame_in_invl = pinfo->num;
273  }
274  }
275  if ((new_float < item->float_min) || (item->fields == 0)) {
276  item->float_min = new_float;
277  if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
278  item->extreme_frame_in_invl = pinfo->num;
279  }
280  }
281  item->float_tot += new_float;
282  item->fields++;
283  break;
284  case FT_DOUBLE:
285  new_double = fvalue_get_floating(((field_info *)gp->pdata[i])->value);
286  if ((new_double > item->double_max) || (item->fields == 0)) {
287  item->double_max = new_double;
288  if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
289  item->extreme_frame_in_invl = pinfo->num;
290  }
291  }
292  if ((new_double < item->double_min) || (item->fields == 0)) {
293  item->double_min = new_double;
294  if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
295  item->extreme_frame_in_invl = pinfo->num;
296  }
297  }
298  item->double_tot += new_double;
299  item->fields++;
300  break;
301  case FT_RELATIVE_TIME:
302  new_time = fvalue_get_time(((field_info *)gp->pdata[i])->value);
303 
304  switch (item_unit) {
305  case IOG_ITEM_UNIT_CALC_LOAD:
306  {
307  guint64 t, pt; /* time in us */
308  int j;
309  /*
310  * Add the time this call spanned each interval according to its contribution
311  * to that interval.
312  */
313  t = new_time->secs;
314  t = t * 1000000 + new_time->nsecs / 1000;
315  j = idx;
316  /*
317  * Handle current interval
318  */
319  pt = pinfo->rel_ts.secs * 1000000 + pinfo->rel_ts.nsecs / 1000;
320  pt = pt % (interval * 1000);
321  if (pt > t) {
322  pt = t;
323  }
324  while (t) {
325  io_graph_item_t *load_item;
326 
327  load_item = &items[j];
328  load_item->time_tot.nsecs += (int) (pt * 1000);
329  if (load_item->time_tot.nsecs > 1000000000) {
330  load_item->time_tot.secs++;
331  load_item->time_tot.nsecs -= 1000000000;
332  }
333 
334  if (j == 0) {
335  break;
336  }
337  j--;
338  t -= pt;
339  if (t > (guint64) interval * 1000) {
340  pt = (guint64) interval * 1000;
341  } else {
342  pt = t;
343  }
344  }
345  break;
346  }
347  default:
348  if ( (new_time->secs > item->time_max.secs)
349  || ( (new_time->secs == item->time_max.secs)
350  && (new_time->nsecs > item->time_max.nsecs))
351  || (item->fields == 0)) {
352  item->time_max = *new_time;
353  if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
354  item->extreme_frame_in_invl = pinfo->num;
355  }
356  }
357  if ( (new_time->secs<item->time_min.secs)
358  || ( (new_time->secs == item->time_min.secs)
359  && (new_time->nsecs < item->time_min.nsecs))
360  || (item->fields == 0)) {
361  item->time_min = *new_time;
362  if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
363  item->extreme_frame_in_invl = pinfo->num;
364  }
365  }
366  nstime_add(&item->time_tot, new_time);
367  item->fields++;
368  }
369  break;
370  default:
371  if ((item_unit == IOG_ITEM_UNIT_CALC_FRAMES) ||
372  (item_unit == IOG_ITEM_UNIT_CALC_FIELDS)) {
373  /*
374  * It's not an integeresque type, but
375  * all we want to do is count it, so
376  * that's all right.
377  */
378  item->fields++;
379  }
380  else {
381  /*
382  * "Can't happen"; see the "check that the
383  * type is compatible" check in
384  * filter_callback().
385  */
386  ws_assert_not_reached();
387  }
388  break;
389  }
390  }
391  }
392 
393  item->frames++;
394  item->bytes += pinfo->fd->pkt_len;
395 
396  return TRUE;
397 }
398 
399 
400 #ifdef __cplusplus
401 }
402 #endif /* __cplusplus */
403 
404 #endif /* __IO_GRAPH_ITEM_H__ */
enum ftenum proto_registrar_get_ftype(const int n)
Definition: proto.c:10865
GPtrArray * proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
Definition: proto.c:10925
double get_io_graph_item(const io_graph_item_t *items, io_graph_item_unit_t val_units, int idx, int hf_index, const capture_file *cap_file, int interval, int cur_idx)
Definition: io_graph_item.c:130
GString * check_field_unit(const char *field_name, int *hf_index, io_graph_item_unit_t item_unit)
Definition: io_graph_item.c:37
int get_io_graph_index(packet_info *pinfo, int interval)
Definition: io_graph_item.c:20
#define nstime_add(sum, a)
Definition: nstime.h:96
WS_DLL_PUBLIC void nstime_set_zero(nstime_t *nstime)
Definition: nstime.c:28
Definition: cfile.h:67
Definition: io_graph_item.h:40
Definition: packet_info.h:44
nstime_t rel_ts
Definition: packet_info.h:50
guint32 num
Definition: packet_info.h:48
Definition: epan_dissect.h:28
Definition: proto.h:809
Definition: nstime.h:26