2 * Definitions and functions for IO graph items
4 * Copied from gtk/io_stat.c, (c) 2002 Ronnie Sahlberg
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later*/
12 #ifndef __IO_GRAPH_ITEM_H__
13 #define __IO_GRAPH_ITEM_H__
17 #endif /* __cplusplus */
21 IOG_ITEM_UNIT_PACKETS = IOG_ITEM_UNIT_FIRST,
24 IOG_ITEM_UNIT_CALC_SUM,
25 IOG_ITEM_UNIT_CALC_FRAMES,
26 IOG_ITEM_UNIT_CALC_FIELDS,
27 IOG_ITEM_UNIT_CALC_MAX,
28 IOG_ITEM_UNIT_CALC_MIN,
29 IOG_ITEM_UNIT_CALC_AVERAGE,
30 IOG_ITEM_UNIT_CALC_LOAD,
31 IOG_ITEM_UNIT_LAST = IOG_ITEM_UNIT_CALC_LOAD,
33 } io_graph_item_unit_t;
35 typedef struct _io_graph_item_t {
36 guint32 frames; /* always calculated, will hold number of frames*/
37 guint64 bytes; /* always calculated, will hold number of bytes*/
42 /* XXX - Why do we always use 64-bit ints but split floats between
54 guint32 first_frame_in_invl;
55 guint32 extreme_frame_in_invl; /* frame with min/max value */
56 guint32 last_frame_in_invl;
59 /** Reset (zero) an io_graph_item_t.
61 * @param items [in,out] Array containing the items to reset.
62 * @param count [in] The number of items in the array.
65 reset_io_graph_items(io_graph_item_t *items, gsize count) {
66 io_graph_item_t *item;
69 for (i = 0; i < count; i++) {
84 nstime_set_zero(&item->time_max);
85 nstime_set_zero(&item->time_min);
86 nstime_set_zero(&item->time_tot);
87 item->first_frame_in_invl = 0;
88 item->extreme_frame_in_invl = 0;
89 item->last_frame_in_invl = 0;
93 /** Get the interval (array index) for a packet
95 * It is up to the caller to determine if the return value is valid.
97 * @param [in] pinfo Packet of interest.
98 * @param [in] interval Time interval in milliseconds.
99 * @return Array index on success, -1 on failure.
101 int get_io_graph_index(packet_info *pinfo, int interval);
103 /** Check field and item unit compatibility
105 * @param field_name [in] Header field name to check
106 * @param hf_index [out] Assigned the header field index corresponding to field_name if valid.
108 * @param item_unit [in] The type of unit to calculate. From IOG_ITEM_UNITS.
109 * @return NULL if compatible, otherwise an error string. The string must
110 * be freed by the caller.
112 GString *check_field_unit(const char *field_name, int *hf_index, io_graph_item_unit_t item_unit);
114 /** Update the values of an io_graph_item_t.
116 * Frame and byte counts are always calculated. If edt is non-NULL advanced
117 * statistics are calculated using hfindex.
119 * @param items [in,out] Array containing the item to update.
120 * @param idx [in] Index of the item to update.
121 * @param pinfo [in] Packet containing update information.
122 * @param edt [in] Dissection information for advanced statistics. May be NULL.
123 * @param hf_index [in] Header field index for advanced statistics.
124 * @param item_unit [in] The type of unit to calculate. From IOG_ITEM_UNITS.
125 * @param interval [in] Timing interval in ms.
126 * @return TRUE if the update was successful, otherwise FALSE.
128 static inline gboolean
129 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) {
130 io_graph_item_t *item = &items[idx];
132 /* Set the first and last frame num in current interval matching the target field+filter */
133 if (item->first_frame_in_invl == 0) {
134 item->first_frame_in_invl = pinfo->num;
136 item->last_frame_in_invl = pinfo->num;
138 if (edt && hf_index >= 0) {
142 gp = proto_get_finfo_ptr_array(edt->tree, hf_index);
147 /* Update the appropriate counters. If fields == 0, this is the first seen
148 * value so set any min/max values accordingly. */
149 for (i=0; i < gp->len; i++) {
156 switch (proto_registrar_get_ftype(hf_index)) {
161 new_int = fvalue_get_uinteger(&((field_info *)gp->pdata[i])->value);
163 if ((new_int > item->int_max) || (item->fields == 0)) {
164 item->int_max = new_int;
165 if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
166 item->extreme_frame_in_invl = pinfo->num;
169 if ((new_int < item->int_min) || (item->fields == 0)) {
170 item->int_min = new_int;
171 if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
172 item->extreme_frame_in_invl = pinfo->num;
175 item->int_tot += new_int;
182 new_int = fvalue_get_sinteger(&((field_info *)gp->pdata[i])->value);
183 if ((new_int > item->int_max) || (item->fields == 0)) {
184 item->int_max = new_int;
185 if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
186 item->extreme_frame_in_invl = pinfo->num;
189 if ((new_int < item->int_min) || (item->fields == 0)) {
190 item->int_min = new_int;
191 if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
192 item->extreme_frame_in_invl = pinfo->num;
195 item->int_tot += new_int;
202 new_int64 = fvalue_get_uinteger64(&((field_info *)gp->pdata[i])->value);
203 if ((new_int64 > item->int_max) || (item->fields == 0)) {
204 item->int_max = new_int64;
205 if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
206 item->extreme_frame_in_invl = pinfo->num;
209 if ((new_int64 < item->int_min) || (item->fields == 0)) {
210 item->int_min = new_int64;
211 if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
212 item->extreme_frame_in_invl = pinfo->num;
215 item->int_tot += new_int64;
222 new_int64 = fvalue_get_sinteger64(&((field_info *)gp->pdata[i])->value);
223 if ((new_int64 > item->int_max) || (item->fields == 0)) {
224 item->int_max = new_int64;
225 if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
226 item->extreme_frame_in_invl = pinfo->num;
229 if ((new_int64 < item->int_min) || (item->fields == 0)) {
230 item->int_min = new_int64;
231 if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
232 item->extreme_frame_in_invl = pinfo->num;
235 item->int_tot += new_int64;
239 new_float = (gfloat)fvalue_get_floating(&((field_info *)gp->pdata[i])->value);
240 if ((new_float > item->float_max) || (item->fields == 0)) {
241 item->float_max = new_float;
242 if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
243 item->extreme_frame_in_invl = pinfo->num;
246 if ((new_float < item->float_min) || (item->fields == 0)) {
247 item->float_min = new_float;
248 if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
249 item->extreme_frame_in_invl = pinfo->num;
252 item->float_tot += new_float;
256 new_double = fvalue_get_floating(&((field_info *)gp->pdata[i])->value);
257 if ((new_double > item->double_max) || (item->fields == 0)) {
258 item->double_max = new_double;
259 if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
260 item->extreme_frame_in_invl = pinfo->num;
263 if ((new_double < item->double_min) || (item->fields == 0)) {
264 item->double_min = new_double;
265 if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
266 item->extreme_frame_in_invl = pinfo->num;
269 item->double_tot += new_double;
272 case FT_RELATIVE_TIME:
273 new_time = (nstime_t *)fvalue_get(&((field_info *)gp->pdata[i])->value);
276 case IOG_ITEM_UNIT_CALC_LOAD:
278 guint64 t, pt; /* time in us */
281 * Add the time this call spanned each interval according to its contribution
285 t = t * 1000000 + new_time->nsecs / 1000;
288 * Handle current interval
290 pt = pinfo->rel_ts.secs * 1000000 + pinfo->rel_ts.nsecs / 1000;
291 pt = pt % (interval * 1000);
296 io_graph_item_t *load_item;
298 load_item = &items[j];
299 load_item->time_tot.nsecs += (int) (pt * 1000);
300 if (load_item->time_tot.nsecs > 1000000000) {
301 load_item->time_tot.secs++;
302 load_item->time_tot.nsecs -= 1000000000;
310 if (t > (guint64) interval * 1000) {
311 pt = (guint64) interval * 1000;
319 if ( (new_time->secs > item->time_max.secs)
320 || ( (new_time->secs == item->time_max.secs)
321 && (new_time->nsecs > item->time_max.nsecs))
322 || (item->fields == 0)) {
323 item->time_max = *new_time;
324 if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
325 item->extreme_frame_in_invl = pinfo->num;
328 if ( (new_time->secs<item->time_min.secs)
329 || ( (new_time->secs == item->time_min.secs)
330 && (new_time->nsecs < item->time_min.nsecs))
331 || (item->fields == 0)) {
332 item->time_min = *new_time;
333 if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
334 item->extreme_frame_in_invl = pinfo->num;
337 nstime_add(&item->time_tot, new_time);
342 if ((item_unit == IOG_ITEM_UNIT_CALC_FRAMES) ||
343 (item_unit == IOG_ITEM_UNIT_CALC_FIELDS)) {
345 * It's not an integeresque type, but
346 * all we want to do is count it, so
353 * "Can't happen"; see the "check that the
354 * type is compatible" check in
357 g_assert_not_reached();
365 item->bytes += pinfo->fd->pkt_len;
373 #endif /* __cplusplus */
375 #endif /* __IO_GRAPH_ITEM_H__ */
383 * indent-tabs-mode: nil
386 * ex: set shiftwidth=4 tabstop=8 expandtab:
387 * :indentSize=4:tabSize=8:noTabs=true: