* Definitions and functions for I/O graph items
*
* Copied from gtk/io_stat.c, (c) 2002 Ronnie Sahlberg
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
#include <epan/epan_dissect.h>
#include <wsutil/filesystem.h>
#include "ui/io_graph_item.h"
int64_t get_io_graph_index(packet_info *pinfo, int interval) {
nstime_t time_delta;
ws_return_val_if(interval <= 0, -1);
* Find in which interval this is supposed to go and store the interval index as idx
*/
time_delta = pinfo->rel_ts;
if (time_delta.nsecs<0) {
time_delta.secs--;
time_delta.nsecs += 1000000000;
}
if (time_delta.secs<0) {
return -1;
}
return ((time_delta.secs*INT64_C(1000000) + time_delta.nsecs/1000) / interval);
}
GString *check_field_unit(const char *field_name, int *hf_index, io_graph_item_unit_t item_unit)
{
GString *err_str = NULL;
if (item_unit >= IOG_ITEM_UNIT_CALC_SUM) {
header_field_info *hfi;
const char *item_unit_names[NUM_IOG_ITEM_UNITS+1] = {
"Packets",
"Bytes",
"Bits",
"SUM",
"COUNT FRAMES",
"COUNT FIELDS",
"MAX",
"MIN",
"AVG",
"THROUGHPUT",
"LOAD",
NULL
};
if (!is_packet_configuration_namespace()) {
item_unit_names[0] = "Events";
}
if ((field_name == NULL) || (field_name[0] == 0)) {
err_str = g_string_new("You didn't specify a field name.");
return err_str;
}
hfi = proto_registrar_get_byname(field_name);
if (hfi == NULL) {
err_str = g_string_new("");
g_string_printf(err_str, "There is no field named '%s'.", field_name);
return err_str;
}
if (hf_index) *hf_index = hfi->id;
switch (hfi->type) {
case FT_UINT8:
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
case FT_UINT64:
case FT_INT8:
case FT_INT16:
case FT_INT24:
case FT_INT32:
case FT_INT64:
case FT_FLOAT:
case FT_DOUBLE:
switch (item_unit) {
case IOG_ITEM_UNIT_CALC_LOAD:
err_str = g_string_new("LOAD is only supported for relative-time fields.");
default:
break;
}
break;
case FT_RELATIVE_TIME:
switch (item_unit) {
case IOG_ITEM_UNIT_CALC_SUM:
case IOG_ITEM_UNIT_CALC_FRAMES:
case IOG_ITEM_UNIT_CALC_FIELDS:
case IOG_ITEM_UNIT_CALC_MAX:
case IOG_ITEM_UNIT_CALC_MIN:
case IOG_ITEM_UNIT_CALC_AVERAGE:
case IOG_ITEM_UNIT_CALC_THROUGHPUT:
case IOG_ITEM_UNIT_CALC_LOAD:
break;
default:
ws_assert(item_unit < NUM_IOG_ITEM_UNITS);
err_str = g_string_new("");
g_string_printf(err_str, "\"%s\" is a relative-time field. %s calculations are not supported on it.",
field_name,
item_unit_names[item_unit]);
}
break;
default:
if ((item_unit != IOG_ITEM_UNIT_CALC_FRAMES) &&
(item_unit != IOG_ITEM_UNIT_CALC_FIELDS)) {
err_str = g_string_new("");
g_string_printf(err_str, "\"%s\" doesn't have integral or float values. %s calculations are not supported on it.",
field_name,
item_unit_names[item_unit]);
}
break;
}
}
return err_str;
}
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_)
{
double value = 0;
int adv_type;
const io_graph_item_t *item;
uint32_t interval;
ws_return_val_if(idx < 0, 0);
item = &items_[idx];
switch (val_units_) {
case IOG_ITEM_UNIT_PACKETS:
return item->frames;
case IOG_ITEM_UNIT_BYTES:
return (double) item->bytes;
case IOG_ITEM_UNIT_BITS:
return (double) (item->bytes * 8);
case IOG_ITEM_UNIT_CALC_FRAMES:
return item->frames;
case IOG_ITEM_UNIT_CALC_FIELDS:
return (double) item->fields;
default:
* generic ones we'll get it when we switch on the
* adv_type below. */
break;
}
if (hf_index_ < 0) {
return 0;
}
adv_type = proto_registrar_get_ftype(hf_index_);
switch (adv_type) {
case FT_INT8:
case FT_INT16:
case FT_INT24:
case FT_INT32:
case FT_INT40:
case FT_INT48:
case FT_INT56:
case FT_INT64:
switch (val_units_) {
case IOG_ITEM_UNIT_CALC_SUM:
value = item->double_tot;
break;
case IOG_ITEM_UNIT_CALC_MAX:
value = (double)item->int_max;
break;
case IOG_ITEM_UNIT_CALC_MIN:
value = (double)item->int_min;
break;
case IOG_ITEM_UNIT_CALC_THROUGHPUT:
value = item->double_tot*(8*1000000/interval_);
break;
case IOG_ITEM_UNIT_CALC_AVERAGE:
if (item->fields) {
value = item->double_tot / item->fields;
} else {
value = 0;
}
break;
default:
break;
}
break;
case FT_UINT8:
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
case FT_UINT40:
case FT_UINT48:
case FT_UINT56:
case FT_UINT64:
switch (val_units_) {
case IOG_ITEM_UNIT_CALC_SUM:
value = item->double_tot;
break;
case IOG_ITEM_UNIT_CALC_MAX:
value = (double)item->uint_max;
break;
case IOG_ITEM_UNIT_CALC_MIN:
value = (double)item->uint_min;
break;
case IOG_ITEM_UNIT_CALC_THROUGHPUT:
value = item->double_tot*(8*1000000/interval_);
break;
case IOG_ITEM_UNIT_CALC_AVERAGE:
if (item->fields) {
value = item->double_tot / item->fields;
} else {
value = 0;
}
break;
default:
break;
}
break;
case FT_DOUBLE:
case FT_FLOAT:
switch (val_units_) {
case IOG_ITEM_UNIT_CALC_SUM:
value = item->double_tot;
break;
case IOG_ITEM_UNIT_CALC_MAX:
value = item->double_max;
break;
case IOG_ITEM_UNIT_CALC_MIN:
value = item->double_min;
break;
case IOG_ITEM_UNIT_CALC_AVERAGE:
if (item->fields) {
value = item->double_tot / item->fields;
} else {
value = 0;
}
break;
default:
break;
}
break;
case FT_RELATIVE_TIME:
switch (val_units_) {
case IOG_ITEM_UNIT_CALC_MAX:
value = nstime_to_sec(&item->time_max);
break;
case IOG_ITEM_UNIT_CALC_MIN:
value = nstime_to_sec(&item->time_min);
break;
case IOG_ITEM_UNIT_CALC_SUM:
value = nstime_to_sec(&item->time_tot);
break;
case IOG_ITEM_UNIT_CALC_AVERAGE:
if (item->fields) {
value = nstime_to_sec(&item->time_tot) / item->fields;
} else {
value = 0;
}
break;
case IOG_ITEM_UNIT_CALC_LOAD:
if (idx == cur_idx_ && cap_file) {
uint64_t start_us = (uint64_t)interval_ * idx;
nstime_t timediff = NSTIME_INIT_SECS_USECS(start_us / 1000000, start_us % 1000000);
nstime_delta(&timediff, &cap_file->elapsed_time, &timediff);
interval = (uint32_t)(1000*nstime_to_msec(&timediff) + 0.5);
} else {
interval = interval_;
}
value = (1000 * nstime_to_msec(&item->time_tot)) / interval;
break;
default:
break;
}
break;
default:
break;
}
return value;
}