commit 3c02e0e344b31874d588de8d10f031f8fd6d8ded
parent 9625b836b2f59393dcecad714ecd85d7dc7b85f3
Author: Quentin Rameau <quinq@fifth.space>
Date: Fri, 29 Jul 2016 13:25:44 +0200
Print accumulated Rx and Tx traffic amount on SIGINFO
Diffstat:
M | sbm.1 | | | 6 | ++++++ |
M | sbm.c | | | 72 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------- |
2 files changed, 61 insertions(+), 17 deletions(-)
diff --git a/sbm.1 b/sbm.1
@@ -35,5 +35,11 @@ If not provided the first active, non-loopback interface will be used.
Enable terse output. The first pair of values is Rx/Tx in bits per second and the
second pair is Rx/Tx in packets per second.
.El
+.Sh SIGNALS
+If
+.Nm sbm
+receives a SIGINFO (usually set to â^Tâ) signal (or SIGUSR1 on Linux),
+the accumulated amount of data transmitted for Rx and Tx since the program
+started will be printed to the standard output.
.Sh AUTHORS
.An Dimitris Papastamos Aq Mt sin@2f30.org
diff --git a/sbm.c b/sbm.c
@@ -16,6 +16,7 @@
#include <errno.h>
#include <ifaddrs.h>
#include <limits.h>
+#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -23,14 +24,20 @@
#include <time.h>
#include <unistd.h>
+#ifdef __linux__
+#define SIGINFO SIGUSR1
+#endif
+
#include "arg.h"
char *argv0;
+char *ifname;
+uint64_t orxb, otxb, crxb, ctxb;
int Bflag;
int tflag;
void
-scan(char *ifname)
+scan(void)
{
struct ifaddrs *ifas, *ifa;
int found = 0;
@@ -63,7 +70,7 @@ scan(char *ifname)
#ifdef __linux__
void
-sample(char *ifname, uint64_t *rxbytes, uint64_t *txbytes,
+sample(uint64_t *rxbytes, uint64_t *txbytes,
uint64_t *rxpps, uint64_t *txpps)
{
struct ifaddrs *ifas, *ifa;
@@ -91,7 +98,7 @@ sample(char *ifname, uint64_t *rxbytes, uint64_t *txbytes,
}
#else
void
-sample(char *ifname, uint64_t *rxbytes, uint64_t *txbytes,
+sample(uint64_t *rxbytes, uint64_t *txbytes,
uint64_t *rxpps, uint64_t *txpps)
{
int mib[6];
@@ -138,8 +145,8 @@ sample(char *ifname, uint64_t *rxbytes, uint64_t *txbytes,
double
scale(char **suffix, uint64_t bits)
{
- static char *suffixes[][3] = { { "bps", "kbps", "Mbps" },
- { "Bps", "kBps", "MBps" } };
+ static char *suffixes[][5] = { { "b", "kb", "Mb", "Gb", "Tb" },
+ { "B", "kB", "MB", "GB", "TB" } };
double rounded = bits;
if (Bflag)
@@ -151,13 +158,18 @@ scale(char **suffix, uint64_t bits)
} else if (rounded >= 1000 * 1000) {
*suffix = suffixes[Bflag][2];
rounded /= 1000 * 1000;
+ } else if (rounded >= 1000 * 1000 * 1000) {
+ *suffix = suffixes[Bflag][3];
+ rounded /= 1000 * 1000 * 1000;
+ } else if (rounded >= (long)1000 * 1000 * 1000 * 1000) {
+ *suffix = suffixes[Bflag][4];
+ rounded /= (long)1000 * 1000 * 1000 * 1000;
}
return rounded;
}
void
-print(char *ifname, uint64_t rxbits, uint64_t txbits,
- uint64_t rxpps, uint64_t txpps)
+print(uint64_t rxbits, uint64_t txbits, uint64_t rxpps, uint64_t txpps)
{
char *rxsuffix, *txsuffix;
double rxround, txround;
@@ -165,7 +177,7 @@ print(char *ifname, uint64_t rxbits, uint64_t txbits,
if (!tflag) {
rxround = scale(&rxsuffix, rxbits);
txround = scale(&txsuffix, txbits);
- printf("%s: %6.2f %4s Rx %6.2f %4s Tx %5llu pps Rx %5llu pps Tx\n",
+ printf("%s: %6.2f %2sps Rx %6.2f %2sps Tx %5llu pps Rx %5llu pps Tx\n",
ifname,
rxround,
rxsuffix,
@@ -221,7 +233,7 @@ tvsleep(struct timeval *tv)
}
void
-loop(char *ifname, long count, struct timeval *delay)
+loop(long count, struct timeval *delay)
{
struct timeval old, now, diff;
uint64_t oldrxbytes, rxbytes, diffrxbits;
@@ -231,10 +243,12 @@ loop(char *ifname, long count, struct timeval *delay)
long n = 0;
getmonotime(&old);
- sample(ifname, &oldrxbytes, &oldtxbytes, &oldrxpps, &oldtxpps);
+ sample(&oldrxbytes, &oldtxbytes, &oldrxpps, &oldtxpps);
+ orxb = oldrxbytes;
+ otxb = oldtxbytes;
for (;;) {
tvsleep(delay);
- sample(ifname, &rxbytes, &txbytes, &rxpps, &txpps);
+ sample(&rxbytes, &txbytes, &rxpps, &txpps);
getmonotime(&now);
timersub(&now, &old, &diff);
getmonotime(&old);
@@ -244,15 +258,37 @@ loop(char *ifname, long count, struct timeval *delay)
difftxbits = difftxbits * 1000 / tv2ms(&diff);
diffrxpps = (rxpps - oldrxpps) * 1000 / tv2ms(&diff);
difftxpps = (txpps - oldtxpps) * 1000 / tv2ms(&diff);
- print(ifname, diffrxbits, difftxbits, diffrxpps, difftxpps);
+ print(diffrxbits, difftxbits, diffrxpps, difftxpps);
oldrxbytes = rxbytes, oldtxbytes = txbytes;
oldrxpps = rxpps, oldtxpps = txpps;
+ crxb = rxbytes - orxb, ctxb = txbytes - otxb;
if (count && ++n >= count)
break;
}
}
void
+printrxtx(int sig)
+{
+ char *rxsuffix, *txsuffix;
+ double rxround, txround;
+
+ rxround = scale(&rxsuffix, crxb);
+ txround = scale(&txsuffix, ctxb);
+
+ printf("%*s %6.2f %2s Rx %6.2f %2s Tx\n",
+ (int)strlen(ifname) + 1, "",
+ rxround, rxsuffix, txround, txsuffix);
+}
+
+void
+setsiginfo(void)
+{
+ if (signal(SIGINFO, printrxtx) == SIG_ERR)
+ err(1, "signal");
+}
+
+void
usage(void)
{
fprintf(stderr, "usage: %s [-B | -t] [-c count] [-d delay] [-i interface]\n", argv0);
@@ -262,7 +298,7 @@ usage(void)
int
main(int argc, char *argv[])
{
- char ifname[IF_NAMESIZE] = "";
+ char ifn[IF_NAMESIZE] = "";
char *end;
struct timeval tv;
long count = 0, delay = 1000;
@@ -284,8 +320,8 @@ main(int argc, char *argv[])
errx(1, "invalid delay");
break;
case 'i':
- strncpy(ifname, EARGF(usage()), sizeof(ifname));
- ifname[IF_NAMESIZE - 1] = '\0';
+ strncpy(ifn, EARGF(usage()), sizeof(ifn));
+ ifn[IF_NAMESIZE - 1] = '\0';
break;
case 't':
tflag = 1;
@@ -294,8 +330,10 @@ main(int argc, char *argv[])
usage();
} ARGEND
+ ifname = ifn;
+ setsiginfo();
ms2tv(&tv, delay);
- scan(ifname);
- loop(ifname, count, &tv);
+ scan();
+ loop(count, &tv);
return 0;
}