aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile10
-rw-r--r--cbm.cpp133
-rw-r--r--fsbm.c202
-rw-r--r--fsbm.cpp133
-rw-r--r--statistics.cpp160
-rw-r--r--statistics.hpp52
6 files changed, 207 insertions, 483 deletions
diff --git a/Makefile b/Makefile
index 8dd5347..1a12155 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,9 @@
-CPPC=g++
-CPPFLAGS=-O2 -Wall -Wextra -mtune=native
+CC=gcc
+CFLAGS=-O2 -Wall -Wextra -mtune=native
all: fsbm
-fsbm: fsbm.cpp
- $(CPPC) fsbm.cpp statistics.cpp -o fsbm $(CPPFLAGS)
+fsbm: fsbm.c
+ $(CC) fsbm.c -o fsbm $(CFLAGS)
clean:
- @rm fsbm \ No newline at end of file
+ @rm fsbm
diff --git a/cbm.cpp b/cbm.cpp
deleted file mode 100644
index 4668534..0000000
--- a/cbm.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-#include "config.h"
-#include "statistics.hpp"
-#include <algorithm>
-#include <cstdlib>
-#include <cstring>
-#include <iomanip>
-#include <iostream>
-#include <sstream>
-
-#include <curses.h>
-#include <getopt.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <unistd.h>
-
-#define PACKAGE "yo"
-#define PACKAGE_STRING "yo mamma"
-
-// Externs
-extern int optind, opterr, optopt;
-
-volatile bool quit = false;
-
-void endHandler(int signum) {
- quit = true;
-}
-
-void formatBandwidth(double bytesPerSecond, bool showBits) {
- const char* prefixes[] = { "", "k", "M", "G", "T", "P", "E", "Z", "Y" };
-
- // Calculate the value
- double value;
- const char* unit;
- if (showBits){
- value = bytesPerSecond * 8;
- unit = "b/s";
- }
- else {
- value = bytesPerSecond;
- unit = "B/s";
- }
-
- // Choose the prefix
- unsigned prefix = 0;
- while (prefix < (sizeof(prefixes) / sizeof(const char*)) && value > 1000.) {
- value /= 1000.;
- ++prefix;
- }
-
- // Format the string
- std::cout << std::setprecision(2) << value << " " << prefixes[prefix] << unit;
-
-}
-
-int main(int argc, char **argv) {
- int retval = EXIT_SUCCESS;
-
- // parse the command line
- int c;
-
- bool useBits = false;
- int interval = 10 * 100000;
-
- while ((c = getopt (argc, argv, "bi:hv")) != -1)
- switch (c)
- {
- case 'b':
- useBits = true;
- break;
- case 'i':
- // Magic numbers? fuck it that's not a magic number, that's a 'real' number.
- interval = atoi(optarg) * 100000;
- break;
- case 'h':
- std::cout << "USAGE: fsbm, -b specifies bits, -i sets interval in 10ths of seconds, 1 sec default\n";
- exit(EXIT_SUCCESS);
- break;
- case 'v':
- std::cout << "Version 1\n";
- exit(EXIT_SUCCESS);
- break;
- case '?':
- std::cerr << "bad flag\n";
- break;
- default:
- exit(EXIT_FAILURE);
- }
-
- // Catch SIGINT
- signal(SIGINT, endHandler);
-
-
-
- // Create a socket (for ioctls)
- int sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (!sock) {
- std::cerr ("cannot open socket");
- exit(EXIT_FAILURE);
- }
-
- // Initialize curses
-
- statistics::Reader statisticsReader;
- statisticsReader.update();
- while (!quit) {
-
- // Update the statistics
- statisticsReader.update();
-
- for (statistics::Reader::Interfaces::const_iterator
- interface = statisticsReader.getInterfaces().begin();
- interface != statisticsReader.getInterfaces().end();
- ++interface) {
-
- std::cout << interface->getName() << " (";
- formatBandwidth(interface->getReceiveSpeed(), useBits);
- std::cout << ", ";
- formatBandwidth(interface->getTransmitSpeed(), useBits);
- std::cout << ")";
-
- }
- std::cout << "\n";
- usleep(interval);
-
-
-
- }
- return retval;
-}
diff --git a/fsbm.c b/fsbm.c
new file mode 100644
index 0000000..1769370
--- /dev/null
+++ b/fsbm.c
@@ -0,0 +1,202 @@
+#include <getopt.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+
+#define PROC_NET_DEV "/proc/net/dev"
+
+struct iface {
+ char interface[IFNAMSIZ];
+ struct timeval timestamp;
+ unsigned long long rx_bytes;
+ unsigned long long tx_bytes;
+};
+
+
+volatile bool q = false;
+bool use_bits = false;
+struct iface *interfaces = NULL;
+size_t no_iface = 0;
+
+void endHandler(int signum) {
+ q = true;
+}
+
+void print_bps(double bytesPerSecond) {
+ const char* prefixes[] = { "", "k", "M", "G", "T", "P", "E", "Z", "Y" };
+
+ // Calculate the value
+ double value;
+ const char* unit;
+ if(use_bits) {
+ value = bytesPerSecond * 8;
+ unit = "b/s";
+ }
+ else {
+ value = bytesPerSecond;
+ unit = "B/s";
+ }
+
+ // Choose the prefix
+ unsigned prefix = 0;
+ while (prefix < (sizeof(prefixes) / sizeof(const char*)) && value > 1000.) {
+ value /= 1000.;
+ ++prefix;
+ }
+
+ // Format the string
+ printf("%.2f %s%s", value, prefixes[prefix], unit);
+
+}
+
+void print_stats() {
+ // Open /proc/net/dev
+ FILE *dev = fopen(PROC_NET_DEV, "r");
+ if (!dev) {
+ fprintf(stderr, "cannot open %s - %s\n", PROC_NET_DEV, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ // Read /proc/dev/net
+ while (!feof(dev)) {
+ char buf[512];
+ char *name, *statistics_string;
+ long long unsigned rx_bytes, tx_bytes;
+ struct timezone unused_timezone;
+ struct timeval timestamp;
+
+ // Read a line
+ fgets(buf, sizeof(buf), dev);
+
+ // get timestamp
+ gettimeofday(&timestamp, &unused_timezone);
+
+ // Find the colon separating the name from the statistics
+ statistics_string = strchr(buf, ':');
+ if (!statistics_string) continue;
+
+ // Get a pointer to the statistics
+ *statistics_string = 0;
+ ++statistics_string;
+
+ // Remove leading whitespace from the name
+ name = buf;
+ ptrdiff_t len = 0;
+ while (*name == ' ' || *name == '\t') {
+ ++name;
+ }
+ len = name - buf;
+
+ // Parse the statistics, alls well, then get this shit going, otherwise f it.
+ if (sscanf(statistics_string, "%Lu %*Lu %*Lu %*Lu %*Lu %*Lu %*Lu %*Lu %Lu",
+ &rx_bytes, &tx_bytes) == 2) {
+
+ size_t i = 0;
+ bool found = false;
+ if(interfaces == NULL) {
+ goto skip;
+ }
+ for(i = 0; i < no_iface; i++) {
+ // if it exists in our interfaces, great. reuse the iface struct
+ if(strncmp(name, interfaces[i].interface, len) == 0) {
+ found = true;
+ break;
+ }
+ }
+ skip:
+ if(found) {
+ double timeDelta, rx_speed, tx_speed = 0;
+
+ // print our new speeds
+ timeDelta = (timestamp.tv_sec - interfaces[i].timestamp.tv_sec) * 1.0 +
+ (timestamp.tv_usec - interfaces[i].timestamp.tv_usec) * .000001;
+
+ rx_speed = (rx_bytes - interfaces[i].rx_bytes) / timeDelta;
+ tx_speed = (tx_bytes - interfaces[i].tx_bytes) / timeDelta;
+
+ printf("%s (", interfaces[i].interface);
+ print_bps(rx_speed);
+ printf(", ");
+ print_bps(tx_speed);
+ printf(")\t");
+
+ // update our interface
+ strcpy(interfaces[i].interface, name);
+ interfaces[i].rx_bytes = rx_bytes;
+ interfaces[i].timestamp = timestamp;
+ interfaces[i].tx_bytes = tx_bytes;
+ }
+ else {
+ interfaces = realloc(interfaces, sizeof(struct iface) * (no_iface + 1));
+ if(interfaces == NULL) {
+ fprintf(stderr, "Error: %s\n", strerror(errno));
+ exit(1);
+ }
+ strcpy(interfaces[no_iface].interface, name);
+ interfaces[no_iface].rx_bytes = rx_bytes;
+ interfaces[no_iface].tx_bytes = tx_bytes;
+ no_iface++;
+ }
+
+ }
+
+ }
+ // Close the file
+ fclose(dev);
+
+}
+
+int main(int argc, char **argv) {
+
+ // parse the command line
+ int c;
+
+ int interval = 10 * 100000;
+
+ while ((c = getopt (argc, argv, "bi:hv")) != -1)
+ switch (c)
+ {
+ case 'b':
+ use_bits = true;
+ break;
+ case 'i':
+ // Magic numbers? fuck it that's not a magic number, that's a 'real' number.
+ interval = atoi(optarg) * 100000;
+ break;
+ case 'h':
+ printf("USAGE: fsbm, -b specifies bits, -i sets interval in 10ths of seconds, 1 sec default\n");
+ exit(EXIT_SUCCESS);
+ break;
+ case 'v':
+ printf("Version 1\n");
+ exit(EXIT_SUCCESS);
+ break;
+ case '?':
+ fprintf(stderr,"bad flag\n");
+ break;
+ default:
+ exit(EXIT_FAILURE);
+ }
+
+ // Catch SIGINT
+ signal(SIGINT, endHandler);
+
+ // populate first.
+ print_stats();
+ while (!q) {
+ print_stats();
+ printf("\n");
+ usleep(interval);
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/fsbm.cpp b/fsbm.cpp
deleted file mode 100644
index 1daa239..0000000
--- a/fsbm.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-#include "config.h"
-#include "statistics.hpp"
-#include <algorithm>
-#include <cstdlib>
-#include <cstring>
-#include <iomanip>
-#include <iostream>
-#include <sstream>
-
-#include <curses.h>
-#include <getopt.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <unistd.h>
-
-#define PACKAGE "yo"
-#define PACKAGE_STRING "yo mamma"
-
-// Externs
-extern int optind, opterr, optopt;
-
-volatile bool quit = false;
-
-void endHandler(int signum) {
- quit = true;
-}
-
-void formatBandwidth(double bytesPerSecond, bool showBits) {
- const char* prefixes[] = { "", "k", "M", "G", "T", "P", "E", "Z", "Y" };
-
- // Calculate the value
- double value;
- const char* unit;
- if (showBits){
- value = bytesPerSecond * 8;
- unit = "b/s";
- }
- else {
- value = bytesPerSecond;
- unit = "B/s";
- }
-
- // Choose the prefix
- unsigned prefix = 0;
- while (prefix < (sizeof(prefixes) / sizeof(const char*)) && value > 1000.) {
- value /= 1000.;
- ++prefix;
- }
-
- // Format the string
- std::cout << std::setprecision(2) << value << " " << prefixes[prefix] << unit;
-
-}
-
-int main(int argc, char **argv) {
- int retval = EXIT_SUCCESS;
-
- // parse the command line
- int c;
-
- bool useBits = false;
- int interval = 10 * 100000;
-
- while ((c = getopt (argc, argv, "bi:hv")) != -1)
- switch (c)
- {
- case 'b':
- useBits = true;
- break;
- case 'i':
- // Magic numbers? fuck it that's not a magic number, that's a 'real' number.
- interval = atoi(optarg) * 100000;
- break;
- case 'h':
- std::cout << "USAGE: fsbm, -b specifies bits, -i sets interval in 10ths of seconds, 1 sec default\n";
- exit(EXIT_SUCCESS);
- break;
- case 'v':
- std::cout << "Version 1\n";
- exit(EXIT_SUCCESS);
- break;
- case '?':
- std::cerr << "bad flag\n";
- break;
- default:
- exit(EXIT_FAILURE);
- }
-
- // Catch SIGINT
- signal(SIGINT, endHandler);
-
-
-
- // Create a socket (for ioctls)
- int sock = socket(AF_INET, SOCK_DGRAM, 0);
- if (!sock) {
- std::cerr << "cannot open socket\n";
- exit(EXIT_FAILURE);
- }
-
- // Initialize curses
-
- statistics::Reader statisticsReader;
- statisticsReader.update();
- while (!quit) {
-
- // Update the statistics
- statisticsReader.update();
-
- for (statistics::Reader::Interfaces::const_iterator
- interface = statisticsReader.getInterfaces().begin();
- interface != statisticsReader.getInterfaces().end();
- ++interface) {
-
- std::cout << interface->getName() << " (";
- formatBandwidth(interface->getReceiveSpeed(), useBits);
- std::cout << ", ";
- formatBandwidth(interface->getTransmitSpeed(), useBits);
- std::cout << ")";
-
- }
- std::cout << "\n";
- usleep(interval);
-
-
-
- }
- return retval;
-}
diff --git a/statistics.cpp b/statistics.cpp
deleted file mode 100644
index 800a4e5..0000000
--- a/statistics.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-#include "config.h"
-#include "statistics.hpp"
-#include <algorithm>
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include <sys/time.h>
-
-#include <iostream>
-#include <sstream>
-
-#define PROC_NET_DEV "/proc/net/dev"
-
-namespace statistics {
-
-Interface::Interface(const std::string& name) : name_(name), updated_(false) {}
-
-class InterfaceNameMatchesPredicate {
- public:
- InterfaceNameMatchesPredicate(const std::string& name) : name_(name) {}
-
- bool operator() (const Interface& interface) const {
- return name_ == interface.getName();
- }
- private:
- std::string name_;
-};
-
-class InterfaceNotUpdatedPredicate {
- public:
- bool operator() (const Interface& interface) const {
- return !interface.getUpdated();
- }
-};
-
-void Interface::update(const Statistics& statistics) {
- memcpy(statistics_ + 1, statistics_ + 0, sizeof(Statistics));
- memcpy(statistics_, &statistics, sizeof(Statistics));
-
- const Statistics& x0 = statistics_[1];
- const Statistics& x1 = statistics_[0];
-
- double timeDelta =
- (x1.timestamp.tv_sec - x0.timestamp.tv_sec) * 1.
- + (x1.timestamp.tv_usec - x0.timestamp.tv_usec) * .000001;
-
- receiveSpeed_ = (x1.rx_bytes - x0.rx_bytes) / timeDelta;
- transmitSpeed_ = (x1.tx_bytes - x0.tx_bytes) / timeDelta;
-
- updated_ = true;
-}
-
-void Reader::update() {
- // Open /proc/net/dev
- FILE *dev = fopen(PROC_NET_DEV, "r");
- if (!dev) {
- std::cerr << "cannot open " << PROC_NET_DEV << "\n";
- exit(EXIT_FAILURE);
- }
-
- try {
- // Clear the 'updated' flag for all interfaces
- for (Interfaces::iterator interface = interfaces_.begin();
- interface != interfaces_.end(); ++interface)
- interface->setUpdated(false);
-
- // Read /proc/dev/net
- while (!feof(dev)) {
- char buf[500];
- char *name, *statistics_string;
- Statistics stats;
- struct timezone unused_timezone;
-
- // Read a line
- fgets(buf, sizeof(buf), dev);
- gettimeofday(&stats.timestamp, &unused_timezone);
-
- // Find the colon separating the name from the statistics
- statistics_string = strchr(buf, ':');
- if (!statistics_string) continue;
-
- // Get a pointer to the statistics
- *statistics_string = 0;
- ++statistics_string;
-
- // Remove leading whitespace from the name
- name = buf;
- while (*name == ' ' || *name == '\t') ++name;
-
- // Parse the statistics
- if (sscanf(statistics_string, "%Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu "
- "%Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
- &stats.rx_bytes, &stats.rx_packets,
- &stats.rx_errs, &stats.rx_drop,
- &stats.rx_fifo, &stats.rx_frame,
- &stats.rx_compressed, &stats.rx_multicast,
- &stats.tx_bytes, &stats.tx_packets,
- &stats.tx_errs, &stats.tx_drop,
- &stats.tx_fifo, &stats.tx_frame,
- &stats.tx_compressed, &stats.tx_multicast)
- == 16) {
-
- // Find the interface with the same name
- Interfaces::iterator interface
- = std::find_if(interfaces_.begin(), interfaces_.end(),
- InterfaceNameMatchesPredicate(name));
-
- if (interface == interfaces_.end()) {
- // This is a new interface; add it to the list
- interfaces_.push_back(Interface(name));
- interface = interfaces_.end();
- --interface;
- }
-
- // Update the interface
- interface->update(stats);
- }
- }
-
- // Remove all interfaces for which the updated flag was not set
- interfaces_.remove_if(InterfaceNotUpdatedPredicate());
-
- // Close the file
- fclose(dev);
- }
- catch (...) {
- fclose(dev);
- throw;
- }
-}
-
-void Interface::setUpdated(bool updated) {
- updated_ = updated;
-}
-
-bool Interface::getUpdated() const {
- return updated_;
-}
-
-const std::string& Interface::getName() const {
- return name_;
-}
-
-double Interface::getReceiveSpeed() const {
- return receiveSpeed_;
-}
-
-double Interface::getTransmitSpeed() const {
- return transmitSpeed_;
-}
-
-const Reader::Interfaces& Reader::getInterfaces() const {
- return interfaces_;
-}
-
-} // namespace statistics
diff --git a/statistics.hpp b/statistics.hpp
deleted file mode 100644
index c916ecb..0000000
--- a/statistics.hpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef CBM_STATISTICS_H
-#define CBM_STATISTICS_H
-
-#include <list>
-#include <string>
-#include <sys/time.h>
-
-namespace statistics {
-
-struct Statistics {
- struct timeval timestamp;
- unsigned long long rx_bytes, rx_packets, rx_errs, rx_drop, rx_fifo,
- rx_frame, rx_compressed, rx_multicast,
- tx_bytes, tx_packets, tx_errs, tx_drop, tx_fifo,
- tx_frame, tx_compressed, tx_multicast;
-};
-
-class Interface {
- public:
- Interface(const std::string& name);
-
- const std::string& getName() const;
-
- void setUpdated(bool updated);
- bool getUpdated() const;
-
- void update(const Statistics& statistics);
-
- double getReceiveSpeed() const;
- double getTransmitSpeed() const;
-
- private:
- std::string name_;
- bool updated_;
- Statistics statistics_[2];
- double receiveSpeed_, transmitSpeed_;
-};
-
-class Reader {
- public:
- void update();
-
- typedef std::list<Interface> Interfaces;
- const Interfaces& getInterfaces() const;
-
- private:
- Interfaces interfaces_;
-};
-
-} // namespace statistics
-
-#endif