Wireshark 4.5.0
The Wireshark network protocol analyzer
Loading...
Searching...
No Matches
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#include <epan/epan_dissect.h>
21
22#ifdef __cplusplus
23extern "C" {
24#endif /* __cplusplus */
25
26typedef enum {
27 IOG_ITEM_UNIT_FIRST,
28 IOG_ITEM_UNIT_PACKETS = IOG_ITEM_UNIT_FIRST,
29 IOG_ITEM_UNIT_BYTES,
30 IOG_ITEM_UNIT_BITS,
31 IOG_ITEM_UNIT_CALC_SUM,
32 IOG_ITEM_UNIT_CALC_FRAMES,
33 IOG_ITEM_UNIT_CALC_FIELDS,
34 IOG_ITEM_UNIT_CALC_MAX,
35 IOG_ITEM_UNIT_CALC_MIN,
36 IOG_ITEM_UNIT_CALC_AVERAGE,
37 IOG_ITEM_UNIT_CALC_THROUGHPUT,
38 IOG_ITEM_UNIT_CALC_LOAD,
39 IOG_ITEM_UNIT_LAST = IOG_ITEM_UNIT_CALC_LOAD,
40 NUM_IOG_ITEM_UNITS
41} io_graph_item_unit_t;
42
43typedef struct _io_graph_item_t {
44 uint32_t frames; /* always calculated, will hold number of frames*/
45 uint64_t bytes; /* always calculated, will hold number of bytes*/
46 uint64_t fields;
47 /* We use a double for totals because of overflow. For min and max,
48 * unsigned 64 bit integers larger than 2^53 cannot all be represented
49 * in a double, and this is useful for determining the frame with the
50 * min or max value, even though for plotting it will be converted to a
51 * double.
52 */
53 union {
54 nstime_t time_max;
55 double double_max;
56 int64_t int_max;
57 uint64_t uint_max;
58 };
59 union {
60 nstime_t time_min;
61 double double_min;
62 int64_t int_min;
63 uint64_t uint_min;
64 };
65 union {
66 nstime_t time_tot;
67 double double_tot;
68 };
69 uint32_t first_frame_in_invl;
70 uint32_t min_frame_in_invl;
71 uint32_t max_frame_in_invl;
72 uint32_t last_frame_in_invl;
74
80static inline void
81reset_io_graph_items(io_graph_item_t *items, size_t count, int hf_index _U_) {
82 io_graph_item_t *item;
83 size_t i;
84
85 for (i = 0; i < count; i++) {
86 item = &items[i];
87
88 item->frames = 0;
89 item->bytes = 0;
90 item->fields = 0;
91 item->first_frame_in_invl = 0;
92 item->min_frame_in_invl = 0;
93 item->max_frame_in_invl = 0;
94 item->last_frame_in_invl = 0;
95
96 nstime_set_zero(&item->time_max);
97 nstime_set_zero(&item->time_min);
98 nstime_set_zero(&item->time_tot);
99
100#if 0
101 /* XXX - On C, type punning is explicitly allowed since C99 so
102 * setting the nstime_t values to 0 is always sufficient.
103 * On C++ that appears technically to be undefined behavior (though
104 * I don't know of any compilers for which it doesn't work and I
105 * can't get UBSAN to complain about it) and this would be safer.
106 */
107 if (hf_index > 0) {
108
109 switch (proto_registrar_get_ftype(hf_index)) {
110
111 case FT_INT8:
112 case FT_INT16:
113 case FT_INT24:
114 case FT_INT32:
115 case FT_INT40:
116 case FT_INT48:
117 case FT_INT56:
118 case FT_INT64:
119 item->int_max = 0;
120 item->int_min = 0;
121 item->double_tot = 0;
122 break;
123
124 case FT_UINT8:
125 case FT_UINT16:
126 case FT_UINT24:
127 case FT_UINT32:
128 case FT_UINT40:
129 case FT_UINT48:
130 case FT_UINT56:
131 case FT_UINT64:
132 item->uint_max = 0;
133 item->uint_min = 0;
134 item->double_tot = 0;
135 break;
136
137 case FT_DOUBLE:
138 case FT_FLOAT:
139 item->double_max = 0;
140 item->double_min = 0;
141 item->double_tot = 0;
142 break;
143
144 case FT_RELATIVE_TIME:
145 nstime_set_zero(&item->time_max);
146 nstime_set_zero(&item->time_min);
147 nstime_set_zero(&item->time_tot);
148 break;
149
150 default:
151 break;
152 }
153 }
154#endif
155 }
156}
157
169int64_t get_io_graph_index(packet_info *pinfo, int interval);
170
180GString *check_field_unit(const char *field_name, int *hf_index, io_graph_item_unit_t item_unit);
181
193double 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, bool asAOT);
194
209static inline bool
210update_io_graph_item(io_graph_item_t *items, int idx, packet_info *pinfo, epan_dissect_t *edt, int hf_index, int item_unit, uint32_t interval) {
211 io_graph_item_t *item = &items[idx];
212
213 /* Set the first and last frame num in current interval matching the target field+filter */
214 if (item->first_frame_in_invl == 0) {
215 item->first_frame_in_invl = pinfo->num;
216 }
217 item->last_frame_in_invl = pinfo->num;
218
219 if (edt && hf_index >= 0) {
220 GPtrArray *gp;
221 unsigned i;
222
223 gp = proto_get_finfo_ptr_array(edt->tree, hf_index);
224 if (!gp) {
225 return false;
226 }
227
228 /* Update the appropriate counters. If fields == 0, this is the first seen
229 * value so set any min/max values accordingly. */
230 for (i=0; i < gp->len; i++) {
231 int64_t new_int64;
232 uint64_t new_uint64;
233 float new_float;
234 double new_double;
235 const nstime_t *new_time;
236
237 switch (proto_registrar_get_ftype(hf_index)) {
238 case FT_UINT8:
239 case FT_UINT16:
240 case FT_UINT24:
241 case FT_UINT32:
242 new_uint64 = fvalue_get_uinteger(((field_info *)gp->pdata[i])->value);
243
244 if ((new_uint64 > item->uint_max) || (item->fields == 0)) {
245 item->uint_max = new_uint64;
246 item->max_frame_in_invl = pinfo->num;
247 }
248 if ((new_uint64 < item->uint_min) || (item->fields == 0)) {
249 item->uint_min = new_uint64;
250 item->min_frame_in_invl = pinfo->num;
251 }
252 item->double_tot += (double)new_uint64;
253 item->fields++;
254 break;
255 case FT_INT8:
256 case FT_INT16:
257 case FT_INT24:
258 case FT_INT32:
259 new_int64 = fvalue_get_sinteger(((field_info *)gp->pdata[i])->value);
260 if ((new_int64 > item->int_max) || (item->fields == 0)) {
261 item->int_max = new_int64;
262 item->max_frame_in_invl = pinfo->num;
263 }
264 if ((new_int64 < item->int_min) || (item->fields == 0)) {
265 item->int_min = new_int64;
266 item->min_frame_in_invl = pinfo->num;
267 }
268 item->double_tot += (double)new_int64;
269 item->fields++;
270 break;
271 case FT_UINT40:
272 case FT_UINT48:
273 case FT_UINT56:
274 case FT_UINT64:
275 new_uint64 = fvalue_get_uinteger64(((field_info *)gp->pdata[i])->value);
276 if ((new_uint64 > item->uint_max) || (item->fields == 0)) {
277 item->uint_max = new_uint64;
278 item->max_frame_in_invl = pinfo->num;
279 }
280 if ((new_uint64 < item->uint_min) || (item->fields == 0)) {
281 item->uint_min = new_uint64;
282 item->min_frame_in_invl = pinfo->num;
283 }
284 item->double_tot += (double)new_uint64;
285 item->fields++;
286 break;
287 case FT_INT40:
288 case FT_INT48:
289 case FT_INT56:
290 case FT_INT64:
291 new_int64 = fvalue_get_sinteger64(((field_info *)gp->pdata[i])->value);
292 if ((new_int64 > item->int_max) || (item->fields == 0)) {
293 item->int_max = new_int64;
294 item->max_frame_in_invl = pinfo->num;
295 }
296 if ((new_int64 < item->int_min) || (item->fields == 0)) {
297 item->int_min = new_int64;
298 item->min_frame_in_invl = pinfo->num;
299 }
300 item->double_tot += (double)new_int64;
301 item->fields++;
302 break;
303 case FT_FLOAT:
304 new_float = (float)fvalue_get_floating(((field_info *)gp->pdata[i])->value);
305 if ((new_float > item->double_max) || (item->fields == 0)) {
306 item->double_max = new_float;
307 item->max_frame_in_invl = pinfo->num;
308 }
309 if ((new_float < item->double_min) || (item->fields == 0)) {
310 item->double_min = new_float;
311 item->min_frame_in_invl = pinfo->num;
312 }
313 item->double_tot += new_float;
314 item->fields++;
315 break;
316 case FT_DOUBLE:
317 new_double = fvalue_get_floating(((field_info *)gp->pdata[i])->value);
318 if ((new_double > item->double_max) || (item->fields == 0)) {
319 item->double_max = new_double;
320 item->max_frame_in_invl = pinfo->num;
321 }
322 if ((new_double < item->double_min) || (item->fields == 0)) {
323 item->double_min = new_double;
324 item->min_frame_in_invl = pinfo->num;
325 }
326 item->double_tot += new_double;
327 item->fields++;
328 break;
329 case FT_RELATIVE_TIME:
330 new_time = fvalue_get_time(((field_info *)gp->pdata[i])->value);
331
332 switch (item_unit) {
333 case IOG_ITEM_UNIT_CALC_LOAD:
334 {
335 uint64_t t, pt; /* time in us */
336 int j;
337 /*
338 * Add the time this call spanned each interval according to
339 * its contribution to that interval.
340 * If the call time is negative (unlikely, requires both an
341 * out of order capture file plus retransmission), ignore.
342 */
343 const nstime_t time_zero = NSTIME_INIT_ZERO;
344 if (nstime_cmp(new_time, &time_zero) < 0) {
345 break;
346 }
347 t = new_time->secs;
348 t = t * 1000000 + new_time->nsecs / 1000;
349 j = idx;
350 /*
351 * Handle current interval
352 * This cannot be negative, because get_io_graph_index
353 * returns an invalid interval if so.
354 */
355 pt = pinfo->rel_ts.secs * 1000000 + pinfo->rel_ts.nsecs / 1000;
356 pt = pt % interval;
357 if (pt > t) {
358 pt = t;
359 }
360 while (t) {
361 io_graph_item_t *load_item;
362
363 load_item = &items[j];
364 load_item->time_tot.nsecs += (int) (pt * 1000);
365 if (load_item->time_tot.nsecs > 1000000000) {
366 load_item->time_tot.secs++;
367 load_item->time_tot.nsecs -= 1000000000;
368 }
369 load_item->fields++;
370
371 if (j == 0) {
372 break;
373 }
374 j--;
375 t -= pt;
376 if (t > (uint64_t) interval) {
377 pt = (uint64_t) interval;
378 } else {
379 pt = t;
380 }
381 }
382 break;
383 }
384 default:
385 if ( (nstime_cmp(new_time, &item->time_max) > 0)
386 || (item->fields == 0)) {
387 item->time_max = *new_time;
388 item->max_frame_in_invl = pinfo->num;
389 }
390 if ( (nstime_cmp(new_time, &item->time_min) < 0)
391 || (item->fields == 0)) {
392 item->time_min = *new_time;
393 item->min_frame_in_invl = pinfo->num;
394 }
395 nstime_add(&item->time_tot, new_time);
396 item->fields++;
397 }
398 break;
399 default:
400 if ((item_unit == IOG_ITEM_UNIT_CALC_FRAMES) ||
401 (item_unit == IOG_ITEM_UNIT_CALC_FIELDS)) {
402 /*
403 * It's not an integeresque type, but
404 * all we want to do is count it, so
405 * that's all right.
406 */
407 item->fields++;
408 }
409 else {
410 /*
411 * "Can't happen"; see the "check that the
412 * type is compatible" check in
413 * filter_callback().
414 */
415 ws_assert_not_reached();
416 }
417 break;
418 }
419 }
420 }
421
422 item->frames++;
423 item->bytes += pinfo->fd->pkt_len;
424
425 return true;
426}
427
428
429#ifdef __cplusplus
430}
431#endif /* __cplusplus */
432
433#endif /* __IO_GRAPH_ITEM_H__ */
enum ftenum proto_registrar_get_ftype(const int n)
Definition proto.c:11234
GPtrArray * proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
Definition proto.c:11294
int64_t get_io_graph_index(packet_info *pinfo, int interval)
Definition io_graph_item.c:25
GString * check_field_unit(const char *field_name, int *hf_index, io_graph_item_unit_t item_unit)
Definition io_graph_item.c:44
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, bool asAOT)
Definition io_graph_item.c:143
#define nstime_add(sum, a)
Definition nstime.h:96
Definition cfile.h:67
Definition io_graph_item.h:43
Definition packet_info.h:43
uint32_t num
Definition packet_info.h:47
nstime_t rel_ts
Definition packet_info.h:49
Definition epan_dissect.h:28
Definition proto.h:813
Definition nstime.h:26