diff options
Diffstat (limited to '')
-rw-r--r-- | ui/io_graph_item.c | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/ui/io_graph_item.c b/ui/io_graph_item.c new file mode 100644 index 00000000..b4047a98 --- /dev/null +++ b/ui/io_graph_item.c @@ -0,0 +1,265 @@ +/* io_graph_item.h + * 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 "ui/io_graph_item.h" + +int get_io_graph_index(packet_info *pinfo, int interval) { + nstime_t time_delta; + + /* + * 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 (int) ((time_delta.secs*1000 + time_delta.nsecs/1000000) / 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", + "LOAD", + NULL + }; + + /* There was no field specified */ + if ((field_name == NULL) || (field_name[0] == 0)) { + err_str = g_string_new("You didn't specify a field name."); + return err_str; + } + + /* The field could not be found */ + 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; + + /* Check that the type is compatible */ + 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: + /* These values support all calculations except LOAD */ + switch (item_unit) { + case IOG_ITEM_UNIT_CALC_LOAD: + err_str = g_string_new("LOAD is only supported for relative-time fields."); + default: + break; + } + /* These types support all calculations */ + break; + case FT_RELATIVE_TIME: + /* This type only supports COUNT, MAX, MIN, AVG */ + 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_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; +} + +// Adapted from get_it_value in gtk/io_stat.c. +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; /* FIXME: loss of precision, visible on the graph for small values */ + int adv_type; + const io_graph_item_t *item; + guint32 interval; + + item = &items_[idx]; + + // Basic units + 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: + /* If it's COUNT_TYPE_ADVANCED but not one of the + * generic ones we'll get it when we switch on the + * adv_type below. */ + break; + } + + if (hf_index_ < 0) { + return 0; + } + // Advanced units + 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: + case FT_UINT8: + case FT_UINT16: + case FT_UINT24: + case FT_UINT32: + case FT_UINT40: + case FT_UINT48: + case FT_UINT56: + case FT_UINT64: + case FT_DOUBLE: + 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_FLOAT: + switch (val_units_) { + case IOG_ITEM_UNIT_CALC_SUM: + value = item->float_tot; + break; + case IOG_ITEM_UNIT_CALC_MAX: + value = item->float_max; + break; + case IOG_ITEM_UNIT_CALC_MIN: + value = item->float_min; + break; + case IOG_ITEM_UNIT_CALC_AVERAGE: + if (item->fields) { + value = (double)item->float_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: + // "LOAD graphs plot the QUEUE-depth of the connection over time" + // (for response time fields such as smb.time, rpc.time, etc.) + // This interval is expressed in milliseconds. + if (idx == cur_idx_ && cap_file) { + interval = (guint32)(nstime_to_msec(&cap_file->elapsed_time) + 0.5); + interval -= (interval_ * idx); + } else { + interval = interval_; + } + value = nstime_to_msec(&item->time_tot) / interval; + break; + default: + break; + } + break; + default: + break; + } + return value; +} |