Wireshark  2.9.0-477-g68ec514b
The Wireshark network protocol analyzer
io_graph_item.h
1 /* io_graph_item.h
2  * Definitions and functions for IO graph items
3  *
4  * Copied from gtk/io_stat.c, (c) 2002 Ronnie Sahlberg
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * SPDX-License-Identifier: GPL-2.0-or-later
11  */
12 
13 #ifndef __IO_GRAPH_ITEM_H__
14 #define __IO_GRAPH_ITEM_H__
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif /* __cplusplus */
19 
20 typedef enum {
21  IOG_ITEM_UNIT_FIRST,
22  IOG_ITEM_UNIT_PACKETS = IOG_ITEM_UNIT_FIRST,
23  IOG_ITEM_UNIT_BYTES,
24  IOG_ITEM_UNIT_BITS,
25  IOG_ITEM_UNIT_CALC_SUM,
26  IOG_ITEM_UNIT_CALC_FRAMES,
27  IOG_ITEM_UNIT_CALC_FIELDS,
28  IOG_ITEM_UNIT_CALC_MAX,
29  IOG_ITEM_UNIT_CALC_MIN,
30  IOG_ITEM_UNIT_CALC_AVERAGE,
31  IOG_ITEM_UNIT_CALC_LOAD,
32  IOG_ITEM_UNIT_LAST = IOG_ITEM_UNIT_CALC_LOAD,
33  NUM_IOG_ITEM_UNITS
34 } io_graph_item_unit_t;
35 
36 typedef struct _io_graph_item_t {
37  guint32 frames; /* always calculated, will hold number of frames*/
38  guint64 bytes; /* always calculated, will hold number of bytes*/
39  guint64 fields;
40  gint64 int_max;
41  gint64 int_min;
42  gint64 int_tot;
43  /* XXX - Why do we always use 64-bit ints but split floats between
44  * gfloat and gdouble?
45  */
46  gfloat float_max;
47  gfloat float_min;
48  gfloat float_tot;
49  gdouble double_max;
50  gdouble double_min;
51  gdouble double_tot;
52  nstime_t time_max;
53  nstime_t time_min;
54  nstime_t time_tot;
55  guint32 first_frame_in_invl;
56  guint32 extreme_frame_in_invl; /* frame with min/max value */
57  guint32 last_frame_in_invl;
59 
65 static inline void
66 reset_io_graph_items(io_graph_item_t *items, gsize count) {
67  io_graph_item_t *item;
68  gsize i;
69 
70  for (i = 0; i < count; i++) {
71  item = &items[i];
72 
73  item->frames = 0;
74  item->bytes = 0;
75  item->fields = 0;
76  item->int_max = 0;
77  item->int_min = 0;
78  item->int_tot = 0;
79  item->float_max = 0;
80  item->float_min = 0;
81  item->float_tot = 0;
82  item->double_max = 0;
83  item->double_min = 0;
84  item->double_tot = 0;
85  nstime_set_zero(&item->time_max);
86  nstime_set_zero(&item->time_min);
87  nstime_set_zero(&item->time_tot);
88  item->first_frame_in_invl = 0;
89  item->extreme_frame_in_invl = 0;
90  item->last_frame_in_invl = 0;
91  }
92 }
93 
102 int get_io_graph_index(packet_info *pinfo, int interval);
103 
113 GString *check_field_unit(const char *field_name, int *hf_index, io_graph_item_unit_t item_unit);
114 
129 static inline gboolean
130 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) {
131  io_graph_item_t *item = &items[idx];
132 
133  /* Set the first and last frame num in current interval matching the target field+filter */
134  if (item->first_frame_in_invl == 0) {
135  item->first_frame_in_invl = pinfo->num;
136  }
137  item->last_frame_in_invl = pinfo->num;
138 
139  if (edt && hf_index >= 0) {
140  GPtrArray *gp;
141  guint i;
142 
143  gp = proto_get_finfo_ptr_array(edt->tree, hf_index);
144  if (!gp) {
145  return FALSE;
146  }
147 
148  /* Update the appropriate counters. If fields == 0, this is the first seen
149  * value so set any min/max values accordingly. */
150  for (i=0; i < gp->len; i++) {
151  int new_int;
152  gint64 new_int64;
153  float new_float;
154  double new_double;
155  nstime_t *new_time;
156 
157  switch (proto_registrar_get_ftype(hf_index)) {
158  case FT_UINT8:
159  case FT_UINT16:
160  case FT_UINT24:
161  case FT_UINT32:
162  new_int = fvalue_get_uinteger(&((field_info *)gp->pdata[i])->value);
163 
164  if ((new_int > item->int_max) || (item->fields == 0)) {
165  item->int_max = new_int;
166  if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
167  item->extreme_frame_in_invl = pinfo->num;
168  }
169  }
170  if ((new_int < item->int_min) || (item->fields == 0)) {
171  item->int_min = new_int;
172  if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
173  item->extreme_frame_in_invl = pinfo->num;
174  }
175  }
176  item->int_tot += new_int;
177  item->fields++;
178  break;
179  case FT_INT8:
180  case FT_INT16:
181  case FT_INT24:
182  case FT_INT32:
183  new_int = fvalue_get_sinteger(&((field_info *)gp->pdata[i])->value);
184  if ((new_int > item->int_max) || (item->fields == 0)) {
185  item->int_max = new_int;
186  if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
187  item->extreme_frame_in_invl = pinfo->num;
188  }
189  }
190  if ((new_int < item->int_min) || (item->fields == 0)) {
191  item->int_min = new_int;
192  if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
193  item->extreme_frame_in_invl = pinfo->num;
194  }
195  }
196  item->int_tot += new_int;
197  item->fields++;
198  break;
199  case FT_UINT40:
200  case FT_UINT48:
201  case FT_UINT56:
202  case FT_UINT64:
203  new_int64 = fvalue_get_uinteger64(&((field_info *)gp->pdata[i])->value);
204  if ((new_int64 > item->int_max) || (item->fields == 0)) {
205  item->int_max = 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  if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
213  item->extreme_frame_in_invl = pinfo->num;
214  }
215  }
216  item->int_tot += new_int64;
217  item->fields++;
218  break;
219  case FT_INT40:
220  case FT_INT48:
221  case FT_INT56:
222  case FT_INT64:
223  new_int64 = fvalue_get_sinteger64(&((field_info *)gp->pdata[i])->value);
224  if ((new_int64 > item->int_max) || (item->fields == 0)) {
225  item->int_max = new_int64;
226  if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
227  item->extreme_frame_in_invl = pinfo->num;
228  }
229  }
230  if ((new_int64 < item->int_min) || (item->fields == 0)) {
231  item->int_min = new_int64;
232  if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
233  item->extreme_frame_in_invl = pinfo->num;
234  }
235  }
236  item->int_tot += new_int64;
237  item->fields++;
238  break;
239  case FT_FLOAT:
240  new_float = (gfloat)fvalue_get_floating(&((field_info *)gp->pdata[i])->value);
241  if ((new_float > item->float_max) || (item->fields == 0)) {
242  item->float_max = new_float;
243  if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
244  item->extreme_frame_in_invl = pinfo->num;
245  }
246  }
247  if ((new_float < item->float_min) || (item->fields == 0)) {
248  item->float_min = new_float;
249  if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
250  item->extreme_frame_in_invl = pinfo->num;
251  }
252  }
253  item->float_tot += new_float;
254  item->fields++;
255  break;
256  case FT_DOUBLE:
257  new_double = fvalue_get_floating(&((field_info *)gp->pdata[i])->value);
258  if ((new_double > item->double_max) || (item->fields == 0)) {
259  item->double_max = new_double;
260  if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
261  item->extreme_frame_in_invl = pinfo->num;
262  }
263  }
264  if ((new_double < item->double_min) || (item->fields == 0)) {
265  item->double_min = new_double;
266  if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
267  item->extreme_frame_in_invl = pinfo->num;
268  }
269  }
270  item->double_tot += new_double;
271  item->fields++;
272  break;
273  case FT_RELATIVE_TIME:
274  new_time = (nstime_t *)fvalue_get(&((field_info *)gp->pdata[i])->value);
275 
276  switch (item_unit) {
277  case IOG_ITEM_UNIT_CALC_LOAD:
278  {
279  guint64 t, pt; /* time in us */
280  int j;
281  /*
282  * Add the time this call spanned each interval according to its contribution
283  * to that interval.
284  */
285  t = new_time->secs;
286  t = t * 1000000 + new_time->nsecs / 1000;
287  j = idx;
288  /*
289  * Handle current interval
290  */
291  pt = pinfo->rel_ts.secs * 1000000 + pinfo->rel_ts.nsecs / 1000;
292  pt = pt % (interval * 1000);
293  if (pt > t) {
294  pt = t;
295  }
296  while (t) {
297  io_graph_item_t *load_item;
298 
299  load_item = &items[j];
300  load_item->time_tot.nsecs += (int) (pt * 1000);
301  if (load_item->time_tot.nsecs > 1000000000) {
302  load_item->time_tot.secs++;
303  load_item->time_tot.nsecs -= 1000000000;
304  }
305 
306  if (j == 0) {
307  break;
308  }
309  j--;
310  t -= pt;
311  if (t > (guint64) interval * 1000) {
312  pt = (guint64) interval * 1000;
313  } else {
314  pt = t;
315  }
316  }
317  break;
318  }
319  default:
320  if ( (new_time->secs > item->time_max.secs)
321  || ( (new_time->secs == item->time_max.secs)
322  && (new_time->nsecs > item->time_max.nsecs))
323  || (item->fields == 0)) {
324  item->time_max = *new_time;
325  if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
326  item->extreme_frame_in_invl = pinfo->num;
327  }
328  }
329  if ( (new_time->secs<item->time_min.secs)
330  || ( (new_time->secs == item->time_min.secs)
331  && (new_time->nsecs < item->time_min.nsecs))
332  || (item->fields == 0)) {
333  item->time_min = *new_time;
334  if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
335  item->extreme_frame_in_invl = pinfo->num;
336  }
337  }
338  nstime_add(&item->time_tot, new_time);
339  item->fields++;
340  }
341  break;
342  default:
343  if ((item_unit == IOG_ITEM_UNIT_CALC_FRAMES) ||
344  (item_unit == IOG_ITEM_UNIT_CALC_FIELDS)) {
345  /*
346  * It's not an integeresque type, but
347  * all we want to do is count it, so
348  * that's all right.
349  */
350  item->fields++;
351  }
352  else {
353  /*
354  * "Can't happen"; see the "check that the
355  * type is compatible" check in
356  * filter_callback().
357  */
358  g_assert_not_reached();
359  }
360  break;
361  }
362  }
363  }
364 
365  item->frames++;
366  item->bytes += pinfo->fd->pkt_len;
367 
368  return TRUE;
369 }
370 
371 
372 #ifdef __cplusplus
373 }
374 #endif /* __cplusplus */
375 
376 #endif /* __IO_GRAPH_ITEM_H__ */
377 
378 /*
379  * Editor modelines
380  *
381  * Local Variables:
382  * c-basic-offset: 4
383  * tab-width: 8
384  * indent-tabs-mode: nil
385  * End:
386  *
387  * ex: set shiftwidth=4 tabstop=8 expandtab:
388  * :indentSize=4:tabSize=8:noTabs=true:
389  */
Definition: io_graph_item.h:36
Definition: packet_info.h:44
guint32 pkt_len
Definition: frame_data.h:56
GPtrArray * proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
Definition: proto.c:9442
guint32 num
Definition: packet_info.h:48
Definition: nstime.h:27
Definition: proto.h:673
WS_DLL_PUBLIC void nstime_set_zero(nstime_t *nstime)
Definition: nstime.c:22
nstime_t rel_ts
Definition: packet_info.h:50
enum ftenum proto_registrar_get_ftype(const int n)
Definition: proto.c:9382
Definition: epan_dissect.h:28
#define nstime_add(sum, a)
Definition: nstime.h:74