summaryrefslogtreecommitdiff
path: root/ui/cli/tap-iostat.c
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2013-07-10 18:41:24 +0000
committerAnders Broman <anders.broman@ericsson.com>2013-07-10 18:41:24 +0000
commitbdd8e5bb57c90067e7e1247a2e1441128520a143 (patch)
tree0c9417f33a5321d098a49c88b4eab100e8a97ad8 /ui/cli/tap-iostat.c
parentb4d8a3727f68d8a4ac0696ea11ea06903d0e6c45 (diff)
downloadwireshark-bdd8e5bb57c90067e7e1247a2e1441128520a143.tar.gz
From Cal Turney:
- tshark -q -z io,stat,1 causes core dump for files larger than ~2MB (with this fix it will still overflow on 32-bits for frame time > 4294s) - In tshark's "io,stat" eliminate the unrequested "Frames and bytes" col, fix formatting, and add "Duration" From me: Added casts to squelch compiler warnings on win7 64bit https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8839 svn path=/trunk/; revision=50488
Diffstat (limited to 'ui/cli/tap-iostat.c')
-rw-r--r--ui/cli/tap-iostat.c175
1 files changed, 113 insertions, 62 deletions
diff --git a/ui/cli/tap-iostat.c b/ui/cli/tap-iostat.c
index 62819f17a9..bc15e5e38e 100644
--- a/ui/cli/tap-iostat.c
+++ b/ui/cli/tap-iostat.c
@@ -66,7 +66,7 @@ static calc_type_ent_t calc_type_table[] = {
typedef struct _io_stat_t {
guint64 interval; /* The user-specified time interval (us) */
guint invl_prec; /* Decimal precision of the time interval (1=10s, 2=100s etc) */
- guint32 num_cols; /* The number of columns of statistics in the table */
+ int num_cols; /* The number of columns of stats in the table */
struct _io_stat_item_t *items; /* Each item is a single cell in the table */
time_t start_time; /* Time of first frame matching the filter */
const char **filters; /* 'io,stat' cmd strings (e.g., "AVG(smb.time)smb.time") */
@@ -89,7 +89,7 @@ typedef struct _io_stat_item_t {
gdouble double_counter;
} io_stat_item_t;
-#define NANOSECS_PER_SEC 1000000000
+#define NANOSECS_PER_SEC 1000000000ULL
static int
iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *dummy _U_)
@@ -105,7 +105,8 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
mit = (io_stat_item_t *) arg;
parent = mit->parent;
- relative_time = (guint64)((pinfo->fd->rel_ts.secs*1000000) + ((pinfo->fd->rel_ts.nsecs+500)/1000));
+ relative_time = ((guint64)pinfo->fd->rel_ts.secs * 1000000ULL) +
+ ((guint64)((pinfo->fd->rel_ts.nsecs+500)/1000));
if (mit->parent->start_time == 0) {
mit->parent->start_time = pinfo->fd->abs_ts.secs - pinfo->fd->rel_ts.secs;
}
@@ -190,7 +191,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
break;
case FT_RELATIVE_TIME:
new_time = (nstime_t *)fvalue_get(&((field_info *)gp->pdata[i])->value);
- val = (guint64)((new_time->secs * NANOSECS_PER_SEC) + new_time->nsecs);
+ val = ((guint64)new_time->secs * NANOSECS_PER_SEC) + (guint64)new_time->nsecs;
it->counter += val;
break;
default:
@@ -258,7 +259,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
break;
case FT_RELATIVE_TIME:
new_time = (nstime_t *)fvalue_get(&((field_info *)gp->pdata[i])->value);
- val = (guint64)new_time->secs * NANOSECS_PER_SEC + new_time->nsecs;
+ val = ((guint64)new_time->secs * NANOSECS_PER_SEC) + (guint64)new_time->nsecs;
if((it->frames==1 && i==0) || (val < it->counter)) {
it->counter=val;
}
@@ -322,7 +323,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
break;
case FT_RELATIVE_TIME:
new_time = (nstime_t *)fvalue_get(&((field_info *)gp->pdata[i])->value);
- val = (guint64)((new_time->secs * NANOSECS_PER_SEC) + new_time->nsecs);
+ val = ((guint64)new_time->secs * NANOSECS_PER_SEC) + (guint64)new_time->nsecs;
if (val>it->counter)
it->counter=val;
break;
@@ -373,7 +374,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
break;
case FT_RELATIVE_TIME:
new_time = (nstime_t *)fvalue_get(&((field_info *)gp->pdata[i])->value);
- val = (guint64)((new_time->secs * NANOSECS_PER_SEC) + new_time->nsecs);
+ val = ((guint64)new_time->secs * NANOSECS_PER_SEC) + (guint64)new_time->nsecs;
it->counter += val;
break;
default:
@@ -402,7 +403,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
io_stat_item_t *pit;
new_time = (nstime_t *)fvalue_get(&((field_info *)gp->pdata[i])->value);
- val = (guint64)((new_time->secs*1000000) + (new_time->nsecs/1000));
+ val = ((guint64)new_time->secs*1000000ULL) + (guint64)(new_time->nsecs/1000);
tival = (int)(val % parent->interval);
it->counter += tival;
val -= tival;
@@ -479,7 +480,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du
break;
case FT_RELATIVE_TIME:
parent->max_vals[it->colnum] =
- MAX(parent->max_vals[it->colnum], ((it->counter/it->num) + 500000000) / NANOSECS_PER_SEC);
+ MAX(parent->max_vals[it->colnum], ((it->counter/(guint64)it->num) + 500000000ULL) / NANOSECS_PER_SEC);
break;
default:
/* UINT16-64 and INT8-64 */
@@ -535,9 +536,10 @@ static void
iostat_draw(void *arg)
{
guint32 num;
- guint64 interval, duration, t, invl_end;
- int i, j, k, num_cols, num_rows, dv, dur_secs, dur_mag, invl_mag, invl_prec, tabrow_w,
- borderlen, invl_col_w, numpad=1, namelen, len_filt, type, maxfltr_w, ftype;
+ guint64 interval, duration, t, invl_end, dv;
+ int i, j, k, num_cols, num_rows, dur_secs_orig, dur_nsecs_orig, dur_secs, dur_nsecs, dur_mag,
+ invl_mag, invl_prec, tabrow_w, borderlen, invl_col_w, numpad=1, namelen, len_filt, type,
+ maxfltr_w, ftype;
int fr_mag; /* The magnitude of the max frame number in this column */
int val_mag; /* The magnitude of the max value in this column */
char *spaces, *spaces_s, *filler_s=NULL, **fmts, *fmt=NULL;
@@ -555,7 +557,8 @@ iostat_draw(void *arg)
num_cols = iot->num_cols;
col_w = (column_width *)g_malloc(sizeof(column_width) * num_cols);
fmts = (char **)g_malloc(sizeof(char *) * num_cols);
- duration = (guint64)((cfile.elapsed_time.secs*1000000) + ((cfile.elapsed_time.nsecs+500)/1000));
+ duration = ((guint64)cfile.elapsed_time.secs * 1000000ULL) +
+ (guint64)((cfile.elapsed_time.nsecs + 500) / 1000);
/* Store the pointer to each stat column */
stat_cols = (io_stat_item_t **) g_malloc(sizeof(io_stat_item_t *) * num_cols);
@@ -572,12 +575,15 @@ iostat_draw(void *arg)
}
/* Calc the capture duration's magnitude (dur_mag) */
- dur_secs = (int)duration/1000000;
+ dur_secs = (int)(duration/1000000ULL);
+ dur_secs_orig = dur_secs;
+ dur_nsecs = (int)(duration%1000000ULL);
+ dur_nsecs_orig = dur_nsecs;
dur_mag = magnitude((guint64)dur_secs, 5);
g_snprintf(dur_mag_s, 3, "%u", dur_mag);
/* Calc the interval's magnitude */
- invl_mag = magnitude((guint64)interval/1000000, 5);
+ invl_mag = magnitude(interval/1000000ULL, 5);
/* Set or get the interval precision */
if (interval==duration) {
@@ -601,14 +607,18 @@ iostat_draw(void *arg)
dv=1000000;
for (i=0; i<invl_prec; i++)
dv /= 10;
- duration = duration + (5*(dv/10));
+ if ((duration%dv) > 5*(dv/10)) {
+ duration += 5*(dv/10);
+ duration = (duration/dv) * dv;
+ dur_secs = (int)(duration/1000000ULL);
+ dur_nsecs = (int)(duration%1000000ULL);
+ /*
+ * Recalc dur_mag in case rounding has increased its magnitude */
+ dur_mag = magnitude((guint64)dur_secs, 5);
+ }
if (iot->interval==G_MAXINT32)
interval = duration;
- /* Recalc the dur_mag in case rounding has increased its magnitude */
- dur_secs = (int)duration/1000000;
- dur_mag = magnitude((guint64)dur_secs, 5);
-
/* Calc the width of the time interval column (incl borders and padding). */
if (invl_prec==0)
invl_col_w = (2*dur_mag) + 8;
@@ -687,7 +697,7 @@ iostat_draw(void *arg)
if (type==CALC_TYPE_LOAD) {
iot->max_vals[j] /= interval;
} else if (type != CALC_TYPE_AVG) {
- iot->max_vals[j] = (iot->max_vals[j] + 500000000) / NANOSECS_PER_SEC;
+ iot->max_vals[j] = (iot->max_vals[j] + 500000000ULL) / NANOSECS_PER_SEC;
}
val_mag = magnitude(iot->max_vals[j], 15);
g_snprintf(val_mag_s, 3, "%u", val_mag);
@@ -764,35 +774,35 @@ iostat_draw(void *arg)
spaces_s = &spaces[2];
printf("|%s|\n", spaces_s);
- g_snprintf(invl_mag_s, 3, "%u", invl_mag);
- if (invl_prec > 0) {
- g_snprintf(invl_prec_s, 3, "%u", invl_prec);
- invl_fmt = g_strconcat("%", invl_mag_s, "u.%0", invl_prec_s, "u", NULL);
- if (interval==duration) {
- full_fmt = g_strconcat("| Interval size: ", invl_fmt, " secs (dur)%s", NULL);
- spaces_s = &spaces[30+invl_mag+invl_prec];
- } else {
- full_fmt = g_strconcat("| Interval size: ", invl_fmt, " secs%s", NULL);
- spaces_s = &spaces[24+invl_mag+invl_prec];
- }
- printf(full_fmt, (guint32)interval/1000000,
- (guint32)((interval%1000000)/dv), spaces_s);
+ if (invl_prec==0) {
+ invl_fmt = g_strconcat("%", dur_mag_s, "u", NULL);
+ full_fmt = g_strconcat("| Duration: ", invl_fmt, ".%6u secs%s|\n", NULL);
+ spaces_s = &spaces[25 + dur_mag];
+ printf(full_fmt, dur_secs_orig, dur_nsecs_orig, spaces_s);
+ g_free(full_fmt);
+ full_fmt = g_strconcat("| Interval: ", invl_fmt, " secs%s|\n", NULL);
+ spaces_s = &spaces[18 + dur_mag];
+ printf(full_fmt, (guint32)(interval/1000000ULL), spaces_s);
} else {
- invl_fmt = g_strconcat("%", invl_mag_s, "u", NULL);
- full_fmt = g_strconcat("| Interval size: ", invl_fmt, " secs%s", NULL);
- spaces_s = &spaces[23 + invl_mag];
- printf(full_fmt, (guint32)interval/1000000, spaces_s);
+ g_snprintf(invl_prec_s, 3, "%u", invl_prec);
+ invl_fmt = g_strconcat("%", dur_mag_s, "u.%0", invl_prec_s, "u", NULL);
+ full_fmt = g_strconcat("| Duration: ", invl_fmt, " secs%s|\n", NULL);
+ spaces_s = &spaces[19 + dur_mag + invl_prec];
+ printf(full_fmt, dur_secs, dur_nsecs/(int)dv, spaces_s);
+ g_free(full_fmt);
+
+ full_fmt = g_strconcat("| Interval: ", invl_fmt, " secs%s|\n", NULL);
+ spaces_s = &spaces[19 + dur_mag + invl_prec];
+ printf(full_fmt, (guint32)(interval/1000000ULL),
+ (guint32)((interval%1000000ULL)/dv), spaces_s);
}
- g_free(invl_fmt);
g_free(full_fmt);
- if (invl_prec > 0)
- invl_fmt = g_strconcat("%", dur_mag_s, "u.%0", invl_prec_s, "u", NULL);
- else
- invl_fmt = g_strconcat("%", dur_mag_s, "u", NULL);
+ spaces_s = &spaces[2];
+ printf("|%s|\n", spaces_s);
/* Display the list of filters and their column numbers vertically */
- printf("|\n| Col");
+ printf("| Col");
for(j=0; j<num_cols; j++){
printf((j==0 ? "%2u: " : "| %2u: "), j+1);
if (!iot->filters[j] || (iot->filters[j]==0)) {
@@ -923,8 +933,11 @@ iostat_draw(void *arg)
printf("\n");
t=0;
- full_fmt = g_strconcat("| ", invl_fmt, " <> ", invl_fmt, " |", NULL);
- num_rows = (int)(duration/interval) + (((duration%interval+500000)/1000000) > 0 ? 1 : 0);
+ if (invl_prec==0 && dur_mag==1)
+ full_fmt = g_strconcat("| ", invl_fmt, " <> ", invl_fmt, " |", NULL);
+ else
+ full_fmt = g_strconcat("| ", invl_fmt, " <> ", invl_fmt, " |", NULL);
+ num_rows = (int)(duration/interval) + (duration%interval > 0 ? 1 : 0);
/* Load item_in_column with the first item in each column */
item_in_column = (io_stat_item_t **) g_malloc(sizeof(io_stat_item_t *) * num_cols);
@@ -948,7 +961,10 @@ iostat_draw(void *arg)
}
/* Patch for Absolute Time */
- the_time=iot->start_time+(guint32)(t/1000000);
+ if (sizeof(time_t) == 8)
+ the_time = iot->start_time + (t/1000000ULL);
+ else
+ the_time = iot->start_time + (guint32)(t/1000000ULL);
tm_time = localtime(&the_time);
/* Display the interval for this row */
@@ -974,13 +990,23 @@ iostat_draw(void *arg)
case TS_NOT_SET:
if (invl_prec==0) {
- printf(full_fmt, (guint32)(t/1000000),
- (guint32)(invl_end/1000000));
+ if(last_row) {
+ int maxw;
+ maxw = dur_mag >= 3 ? dur_mag+1 : 3;
+ g_free(full_fmt);
+ g_snprintf(dur_mag_s, 3, "%u", maxw);
+ full_fmt = g_strconcat( dur_mag==1 ? "| " : "| ",
+ invl_fmt, " <> ", g_strconcat("%-", dur_mag_s, "s|"), NULL);
+ printf(full_fmt, (guint32)(t/1000000ULL), "Dur");
+ } else {
+ printf(full_fmt, (guint32)(t/1000000ULL),
+ (guint32)(invl_end/1000000ULL));
+ }
} else {
- printf(full_fmt, (guint32)(t/1000000),
- (guint32)(t%1000000) / dv,
- (guint32) (invl_end/1000000),
- (guint32)((invl_end%1000000) / dv));
+ printf(full_fmt, (guint32)(t/1000000ULL),
+ (guint32)(t%1000000ULL / dv),
+ (guint32)(invl_end/1000000ULL),
+ (guint32)(invl_end%1000000ULL / dv));
}
break;
/* case TS_DELTA:
@@ -1023,8 +1049,8 @@ iostat_draw(void *arg)
printf(fmt, item->double_counter);
break;
case FT_RELATIVE_TIME:
- item->counter = (item->counter + 500) / 1000;
- printf(fmt, (int)(item->counter/1000000), (int)(item->counter%1000000));
+ item->counter = (item->counter + 500ULL) / 1000ULL;
+ printf(fmt, (int)(item->counter/1000000ULL), (int)(item->counter%1000000ULL));
break;
default:
printf(fmt, item->counter);
@@ -1045,12 +1071,12 @@ iostat_draw(void *arg)
printf(fmt, item->double_counter/num);
break;
case FT_RELATIVE_TIME:
- item->counter = ((item->counter/num) + 500) / 1000;
+ item->counter = ((item->counter / (guint64)num) + 500ULL) / 1000ULL;
printf(fmt,
- (int)(item->counter/1000000), (int)(item->counter%1000000));
+ (int)(item->counter/1000000ULL), (int)(item->counter%1000000ULL));
break;
default:
- printf(fmt, item->counter/num);
+ printf(fmt, item->counter / (guint64)num);
break;
}
break;
@@ -1062,11 +1088,11 @@ iostat_draw(void *arg)
if (!last_row) {
printf(fmt,
(int) (item->counter/interval),
- (int)((item->counter%interval)*1000000 / interval));
+ (int)((item->counter%interval)*1000000ULL / interval));
} else {
printf(fmt,
(int) (item->counter/(invl_end-t)),
- (int)((item->counter%(invl_end-t))*1000000 / (invl_end-t)));
+ (int)((item->counter%(invl_end-t))*1000000ULL / (invl_end-t)));
}
break;
}
@@ -1272,7 +1298,8 @@ static void
iostat_init(const char *optarg, void* userdata _U_)
{
gdouble interval_float;
- guint32 idx=0, i;
+ guint32 idx=0;
+ int i;
io_stat_t *io;
const gchar *filters, *str, *pos;
@@ -1318,7 +1345,7 @@ iostat_init(const char *optarg, void* userdata _U_)
io->invl_prec = 0;
} else {
/* Set interval to the number of us rounded to the nearest integer */
- io->interval = (gint64)(interval_float*1000000.0+0.5);
+ io->interval = (guint64)(interval_float * 1000000.0 + 0.5);
/*
* Determine what interval precision the user has specified */
io->invl_prec = 6;
@@ -1327,6 +1354,28 @@ iostat_init(const char *optarg, void* userdata _U_)
break;
io->invl_prec--;
}
+ if (io->invl_prec==0) {
+ /* The precision is zero but if the user specified one of more zeros after the decimal point,
+ they want that many decimal places shown in the table for all time intervals except
+ response time values such as smb.time which always have 6 decimal places of precision.
+ This feature is useful in cases where for example the duration is 9.1, you specify an
+ interval of 1 and the last interval becomes "9 <> 9". If the interval is instead set to
+ 1.1, the last interval becomes
+ last interval is rounded up to value that is greater than the duration. */
+ const gchar *invl_start = optarg+8;
+ gchar *intv_end;
+ int invl_len;
+
+ intv_end = g_strstr_len(invl_start, -1, ",");
+ invl_len = (int)(intv_end - invl_start);
+ invl_start = g_strstr_len(invl_start, invl_len, ".");
+
+ if (invl_start > 0) {
+ invl_len = (int)(intv_end - invl_start - 1);
+ if (invl_len)
+ io->invl_prec = MIN(invl_len, 6);
+ }
+ }
}
if (io->interval < 1){
fprintf(stderr,
@@ -1339,6 +1388,8 @@ iostat_init(const char *optarg, void* userdata _U_)
io->start_time=0;
if (filters && (*filters != '\0')) {
+ /* Eliminate the first comma. */
+ filters++;
str = filters;
while((str = strchr(str, ','))) {
io->num_cols++;