diff options
| -rw-r--r-- | Makefile | 10 | ||||
| -rw-r--r-- | cbm.cpp | 133 | ||||
| -rw-r--r-- | fsbm.c | 202 | ||||
| -rw-r--r-- | fsbm.cpp | 133 | ||||
| -rw-r--r-- | statistics.cpp | 160 | ||||
| -rw-r--r-- | statistics.hpp | 52 | 
6 files changed, 207 insertions, 483 deletions
| @@ -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; -} @@ -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(×tamp, &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 | 
