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
170int64_t get_io_graph_index(packet_info *pinfo, int interval);
171
181GString *check_field_unit(const char *field_name, int *hf_index, io_graph_item_unit_t item_unit);
182
194double 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);
195
210static inline bool
211update_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) {
212 io_graph_item_t *item = &items[idx];
213
214 /* Set the first and last frame num in current interval matching the target field+filter */
215 if (item->first_frame_in_invl == 0) {
216 item->first_frame_in_invl = pinfo->num;
217 }
218 item->last_frame_in_invl = pinfo->num;
219
220 if (edt && hf_index >= 0) {
221 GPtrArray *gp;
222 unsigned i;
223
224 gp = proto_get_finfo_ptr_array(edt->tree, hf_index);
225 if (!gp) {
226 return false;
227 }
228
229 /* Update the appropriate counters. If fields == 0, this is the first seen
230 * value so set any min/max values accordingly. */
231 for (i=0; i < gp->len; i++) {
232 int64_t new_int64;
233 uint64_t new_uint64;
234 float new_float;
235 double new_double;
236 const nstime_t *new_time;
237
238 switch (proto_registrar_get_ftype(hf_index)) {
239 case FT_UINT8:
240 case FT_UINT16:
241 case FT_UINT24:
242 case FT_UINT32:
243 new_uint64 = fvalue_get_uinteger(((field_info *)gp->pdata[i])->value);
244
245 if ((new_uint64 > item->uint_max) || (item->fields == 0)) {
246 item->uint_max = new_uint64;
247 item->max_frame_in_invl = pinfo->num;
248 }
249 if ((new_uint64 < item->uint_min) || (item->fields == 0)) {
250 item->uint_min = new_uint64;
251 item->min_frame_in_invl = pinfo->num;
252 }
253 item->double_tot += (double)new_uint64;
254 item->fields++;
255 break;
256 case FT_INT8:
257 case FT_INT16:
258 case FT_INT24:
259 case FT_INT32:
260 new_int64 = fvalue_get_sinteger(((field_info *)gp->pdata[i])->value);
261 if ((new_int64 > item->int_max) || (item->fields == 0)) {
262 item->int_max = new_int64;
263 item->max_frame_in_invl = pinfo->num;
264 }
265 if ((new_int64 < item->int_min) || (item->fields == 0)) {
266 item->int_min = new_int64;
267 item->min_frame_in_invl = pinfo->num;
268 }
269 item->double_tot += (double)new_int64;
270 item->fields++;
271 break;
272 case FT_UINT40:
273 case FT_UINT48:
274 case FT_UINT56:
275 case FT_UINT64:
276 new_uint64 = fvalue_get_uinteger64(((field_info *)gp->pdata[i])->value);
277 if ((new_uint64 > item->uint_max) || (item->fields == 0)) {
278 item->uint_max = new_uint64;
279 item->max_frame_in_invl = pinfo->num;
280 }
281 if ((new_uint64 < item->uint_min) || (item->fields == 0)) {
282 item->uint_min = new_uint64;
283 item->min_frame_in_invl = pinfo->num;
284 }
285 item->double_tot += (double)new_uint64;
286 item->fields++;
287 break;
288 case FT_INT40:
289 case FT_INT48:
290 case FT_INT56:
291 case FT_INT64:
292 new_int64 = fvalue_get_sinteger64(((field_info *)gp->pdata[i])->value);
293 if ((new_int64 > item->int_max) || (item->fields == 0)) {
294 item->int_max = new_int64;
295 item->max_frame_in_invl = pinfo->num;
296 }
297 if ((new_int64 < item->int_min) || (item->fields == 0)) {
298 item->int_min = new_int64;
299 item->min_frame_in_invl = pinfo->num;
300 }
301 item->double_tot += (double)new_int64;
302 item->fields++;
303 break;
304 case FT_FLOAT:
305 new_float = (float)fvalue_get_floating(((field_info *)gp->pdata[i])->value);
306 if ((new_float > item->double_max) || (item->fields == 0)) {
307 item->double_max = new_float;
308 item->max_frame_in_invl = pinfo->num;
309 }
310 if ((new_float < item->double_min) || (item->fields == 0)) {
311 item->double_min = new_float;
312 item->min_frame_in_invl = pinfo->num;
313 }
314 item->double_tot += new_float;
315 item->fields++;
316 break;
317 case FT_DOUBLE:
318 new_double = fvalue_get_floating(((field_info *)gp->pdata[i])->value);
319 if ((new_double > item->double_max) || (item->fields == 0)) {
320 item->double_max = new_double;
321 item->max_frame_in_invl = pinfo->num;
322 }
323 if ((new_double < item->double_min) || (item->fields == 0)) {
324 item->double_min = new_double;
325 item->min_frame_in_invl = pinfo->num;
326 }
327 item->double_tot += new_double;
328 item->fields++;
329 break;
330 case FT_RELATIVE_TIME:
331 new_time = fvalue_get_time(((field_info *)gp->pdata[i])->value);
332
333 switch (item_unit) {
334 case IOG_ITEM_UNIT_CALC_LOAD:
335 {
336 uint64_t t, pt; /* time in us */
337 int j;
338 /*
339 * Add the time this call spanned each interval according to
340 * its contribution to that interval.
341 * If the call time is negative (unlikely, requires both an
342 * out of order capture file plus retransmission), ignore.
343 */
344 const nstime_t time_zero = NSTIME_INIT_ZERO;
345 if (nstime_cmp(new_time, &time_zero) < 0) {
346 break;
347 }
348 t = new_time->secs;
349 t = t * 1000000 + new_time->nsecs / 1000;
350 j = idx;
351 /*
352 * Handle current interval
353 * This cannot be negative, because get_io_graph_index
354 * returns an invalid interval if so.
355 */
356 pt = pinfo->rel_ts.secs * 1000000 + pinfo->rel_ts.nsecs / 1000;
357 pt = pt % interval;
358 if (pt > t) {
359 pt = t;
360 }
361 while (t) {
362 io_graph_item_t *load_item;
363
364 load_item = &items[j];
365 load_item->time_tot.nsecs += (int) (pt * 1000);
366 if (load_item->time_tot.nsecs > 1000000000) {
367 load_item->time_tot.secs++;
368 load_item->time_tot.nsecs -= 1000000000;
369 }
370 load_item->fields++;
371
372 if (j == 0) {
373 break;
374 }
375 j--;
376 t -= pt;
377 if (t > (uint64_t) interval) {
378 pt = (uint64_t) interval;
379 } else {
380 pt = t;
381 }
382 }
383 break;
384 }
385 default:
386 if ( (nstime_cmp(new_time, &item->time_max) > 0)
387 || (item->fields == 0)) {
388 item->time_max = *new_time;
389 item->max_frame_in_invl = pinfo->num;
390 }
391 if ( (nstime_cmp(new_time, &item->time_min) < 0)
392 || (item->fields == 0)) {
393 item->time_min = *new_time;
394 item->min_frame_in_invl = pinfo->num;
395 }
396 nstime_add(&item->time_tot, new_time);
397 item->fields++;
398 }
399 break;
400 default:
401 if ((item_unit == IOG_ITEM_UNIT_CALC_FRAMES) ||
402 (item_unit == IOG_ITEM_UNIT_CALC_FIELDS)) {
403 /*
404 * It's not an integeresque type, but
405 * all we want to do is count it, so
406 * that's all right.
407 */
408 item->fields++;
409 }
410 else {
411 /*
412 * "Can't happen"; see the "check that the
413 * type is compatible" check in
414 * filter_callback().
415 */
416 ws_assert_not_reached();
417 }
418 break;
419 }
420 }
421 }
422
423 item->frames++;
424 item->bytes += pinfo->fd->pkt_len;
425
426 return true;
427}
428
429
430#ifdef __cplusplus
431}
432#endif /* __cplusplus */
433
434#endif /* __IO_GRAPH_ITEM_H__ */
enum ftenum proto_registrar_get_ftype(const int n)
Definition proto.c:11213
GPtrArray * proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
Definition proto.c:11273
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