commit b1cc4843e941f5cc44243bb547baa00a21a7a651
parent f66a43898ddc9ebff38ccc3a297e1013a192a43c
Author: sin <sin@2f30.org>
Date: Mon, 22 Feb 2016 12:31:08 +0000
Add delay support
Diffstat:
M | sbm.1 | | | 15 | ++++++++++----- |
M | sbm.c | | | 79 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
2 files changed, 73 insertions(+), 21 deletions(-)
diff --git a/sbm.1 b/sbm.1
@@ -6,23 +6,28 @@
.Nd simple bandwidth monitor
.Sh SYNOPSIS
.Nm sbm
-.Op Fl i Ar interface
.Op Fl c Ar count
+.Op Fl d Ar delay
+.Op Fl i Ar interface
.Sh DESCRIPTION
.Nm
is a simple bandwidth monitor.
.Sh OPTIONS
.Bl -tag -width "-i interface"
-.It Fl i Ar interface
-Monitor the selected
-.Ar interface .
-If not provided the first active, non-loopback interface will be used.
.It Fl c Ar count
Stop monitoring after
.Ar count
samples. If
.Ar count
is 0, it will loop forever. This is the default.
+.It Fl d Ar delay
+Sample interface statistics every
+.Ar delay
+ms. The default is 1000 ms.
+.It Fl i Ar interface
+Monitor the selected
+.Ar interface .
+If not provided the first active, non-loopback interface will be used.
.El
.Sh AUTHORS
.An Dimitris Papastamos Aq Mt sin@2f30.org
diff --git a/sbm.c b/sbm.c
@@ -15,6 +15,7 @@
*/
#include <sys/types.h>
+#include <sys/time.h>
#include <sys/socket.h>
#include <net/if.h>
@@ -33,6 +34,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include <unistd.h>
#include "arg.h"
@@ -176,37 +178,74 @@ print(char *ifname, unsigned long long rxbits, unsigned long long txbits,
ifname, rxbits, rxsuffix, txbits, txsuffix, rxpps, txpps);
}
+int
+clock_gettime_tv(clockid_t clock_id, struct timeval *tv)
+{
+ struct timespec ts;
+ int ret;
+
+ ret = clock_gettime(clock_id, &ts);
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = ts.tv_nsec / 1000;
+ return ret;
+}
+
+void
+ms2tv(struct timeval *tv, long ms)
+{
+ tv->tv_sec = ms / 1000;
+ tv->tv_usec = (ms % 1000) * 1000;
+}
+
+long
+tv2ms(struct timeval *tv)
+{
+ return (tv->tv_sec * 1000) + ((tv->tv_usec + 500) / 1000);
+}
+
void
-loop(char *ifname, long count)
+loop(char *ifname, long count, struct timeval *delay)
{
+ struct timeval old, now, diff;
unsigned long long oldrxbytes, rxbytes;
unsigned long long oldtxbytes, txbytes;
unsigned long long oldrxpps, rxpps;
unsigned long long oldtxpps, txpps;
+ unsigned long long diffrxbits, difftxbits;
+ unsigned long long diffrxpps, difftxpps;
long n = 0;
+ clock_gettime_tv(CLOCK_MONOTONIC, &old);
sample(ifname, &oldrxbytes, &oldtxbytes, &oldrxpps, &oldtxpps);
for (;;) {
- sleep(1);
+ usleep(1000); /* sleep for 1ms */
sample(ifname, &rxbytes, &txbytes, &rxpps, &txpps);
- print(ifname,
- (rxbytes - oldrxbytes) * 8,
- (txbytes - oldtxbytes) * 8,
- rxpps - oldrxpps,
- txpps - oldtxpps);
- oldrxbytes = rxbytes;
- oldtxbytes = txbytes;
- oldrxpps = rxpps;
- oldtxpps = txpps;
- if (count && ++n >= count)
- break;
+ clock_gettime_tv(CLOCK_MONOTONIC, &now);
+ timersub(&now, &old, &diff);
+ if (timercmp(&diff, delay, >=)) {
+ clock_gettime_tv(CLOCK_MONOTONIC, &old);
+ diffrxbits = (rxbytes - oldrxbytes) * 8;
+ difftxbits = (txbytes - oldtxbytes) * 8;
+ diffrxbits = diffrxbits * 1000 / tv2ms(&diff);
+ difftxbits = difftxbits * 1000 / tv2ms(&diff);
+ diffrxpps = (rxpps - oldrxpps) * 1000 / tv2ms(&diff);
+ difftxpps = (txpps - txpps) * 1000 / tv2ms(&diff);
+ print(ifname, diffrxbits, difftxbits,
+ diffrxpps, difftxpps);
+ oldrxbytes = rxbytes;
+ oldtxbytes = txbytes;
+ oldrxpps = rxpps;
+ oldtxpps = txpps;
+ if (count && ++n >= count)
+ break;
+ }
}
}
void
usage(void)
{
- fprintf(stderr, "usage: %s [-c count] [-i interface]\n", argv0);
+ fprintf(stderr, "usage: %s [-c count] [-d delay] [-i interface]\n", argv0);
exit(1);
}
@@ -215,7 +254,8 @@ main(int argc, char *argv[])
{
char ifname[IF_NAMESIZE] = "";
char *end;
- long count = 0;
+ struct timeval tv;
+ long count = 0, delay = 1000;
ARGBEGIN {
case 'c':
@@ -224,6 +264,12 @@ main(int argc, char *argv[])
if (*end != '\0' || errno)
errx(1, "invalid count");
break;
+ case 'd':
+ errno = 0;
+ delay = strtol(EARGF(usage()), &end, 10);
+ if (*end != '\0' || errno)
+ errx(1, "invalid delay");
+ break;
case 'i':
strncpy(ifname, EARGF(usage()), sizeof(ifname));
ifname[IF_NAMESIZE - 1] = '\0';
@@ -232,7 +278,8 @@ main(int argc, char *argv[])
usage();
} ARGEND
+ ms2tv(&tv, delay);
scan(ifname);
- loop(ifname, count);
+ loop(ifname, count, &tv);
return 0;
}