263 lines
7.2 KiB
C
263 lines
7.2 KiB
C
/*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#define MAX_INTERFACES 16
|
|
|
|
struct interface_info
|
|
{
|
|
char name[12];
|
|
|
|
unsigned long tx_bytes_old;
|
|
unsigned long rx_bytes_old;
|
|
unsigned long tx_bytes_new;
|
|
unsigned long rx_bytes_new;
|
|
unsigned long tx_kbytes_dif;
|
|
unsigned long rx_kbytes_dif;
|
|
|
|
struct timeval time_old;
|
|
struct timeval time_new;
|
|
|
|
unsigned long time_diff_ms;
|
|
|
|
unsigned long tx_rate_whole;
|
|
unsigned long rx_rate_whole;
|
|
unsigned long tot_rate_whole;
|
|
unsigned tx_rate_part;
|
|
unsigned rx_rate_part;
|
|
unsigned tot_rate_part;
|
|
};
|
|
|
|
unsigned long bwm_calc_remainder(unsigned long num, unsigned long den);
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
FILE *devfile;
|
|
|
|
char filename[256] = "/proc/net/dev";
|
|
char buffer[256];
|
|
char *buffer_pointer;
|
|
|
|
int inum;
|
|
int field_number;
|
|
int total_counter;
|
|
int sleep_time = 2;
|
|
int first_pass = 1;
|
|
|
|
unsigned long int conv_field;
|
|
|
|
struct interface_info interface[MAX_INTERFACES];
|
|
struct timezone tz;
|
|
|
|
unsigned long rx_bw_total_whole = 0;
|
|
unsigned long tx_bw_total_whole = 0;
|
|
unsigned long tot_bw_total_whole = 0;
|
|
unsigned rx_bw_total_part = 0;
|
|
unsigned tx_bw_total_part = 0;
|
|
unsigned tot_bw_total_part = 0;
|
|
|
|
if(argc >= 2) if((sleep_time = atoi(argv[1])) < 1) sleep_time = 1;
|
|
if(argc >= 3) strncpy(filename, argv[2], 255);
|
|
|
|
if(argc > 3)
|
|
{
|
|
printf("\nUsage: %s <update time in seconds> <filename>\n\n", argv[0]);
|
|
printf("Update time defaults to 2 seconds if not specified. Minimum is 1 second.\n");
|
|
printf("Filename defaults to /proc/net/dev if not specified.\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
printf("%c[2J",27);
|
|
|
|
while(1)
|
|
{
|
|
printf("%c[H",27);
|
|
printf("Bandwidth Monitor 1.1.0\n\n");
|
|
printf(" Iface RX(KB/sec) TX(KB/sec) Total(KB/sec)\n\n");
|
|
|
|
inum = -1;
|
|
|
|
if((devfile = fopen(filename, "r")) == NULL)
|
|
{
|
|
perror("fopen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
fgets(buffer, 255, devfile);
|
|
|
|
while(fgets(buffer, 255, devfile) != NULL && inum++ < MAX_INTERFACES - 1)
|
|
{
|
|
interface[inum].time_old = interface[inum].time_new;
|
|
gettimeofday(&interface[inum].time_new, &tz);
|
|
|
|
interface[inum].time_diff_ms =
|
|
(unsigned long)(interface[inum].time_new.tv_sec * 1000 +
|
|
interface[inum].time_new.tv_usec / 1000) -
|
|
(interface[inum].time_old.tv_sec * 1000 +
|
|
interface[inum].time_old.tv_usec / 1000);
|
|
|
|
if(inum > 0)
|
|
{
|
|
buffer_pointer = buffer;
|
|
buffer_pointer = strtok(buffer_pointer, " :");
|
|
strncpy(interface[inum].name, buffer_pointer, 11);
|
|
|
|
field_number = 0;
|
|
|
|
while((buffer_pointer = strtok(NULL, " :")) != NULL)
|
|
{
|
|
conv_field = strtoul(buffer_pointer, NULL, 10);
|
|
|
|
field_number++;
|
|
|
|
switch(field_number)
|
|
{
|
|
case 1:
|
|
{
|
|
interface[inum].rx_bytes_old = interface[inum].rx_bytes_new;
|
|
interface[inum].rx_bytes_new = conv_field;
|
|
|
|
interface[inum].rx_kbytes_dif =
|
|
(interface[inum].rx_bytes_new -
|
|
interface[inum].rx_bytes_old) * 1000 / 1024;
|
|
|
|
interface[inum].rx_rate_whole =
|
|
interface[inum].rx_kbytes_dif /
|
|
interface[inum].time_diff_ms;
|
|
|
|
interface[inum].rx_rate_part =
|
|
bwm_calc_remainder(interface[inum].rx_kbytes_dif,
|
|
interface[inum].time_diff_ms);
|
|
}
|
|
break;
|
|
|
|
case 9:
|
|
{
|
|
interface[inum].tx_bytes_old = interface[inum].tx_bytes_new;
|
|
interface[inum].tx_bytes_new = conv_field;
|
|
|
|
interface[inum].tx_kbytes_dif =
|
|
(interface[inum].tx_bytes_new -
|
|
interface[inum].tx_bytes_old) * 1000 / 1024;
|
|
|
|
interface[inum].tx_rate_whole =
|
|
interface[inum].tx_kbytes_dif /
|
|
interface[inum].time_diff_ms;
|
|
|
|
interface[inum].tx_rate_part =
|
|
bwm_calc_remainder(interface[inum].tx_kbytes_dif,
|
|
interface[inum].time_diff_ms);
|
|
|
|
interface[inum].tot_rate_whole =
|
|
interface[inum].rx_rate_whole +
|
|
interface[inum].tx_rate_whole;
|
|
|
|
interface[inum].tot_rate_part =
|
|
interface[inum].rx_rate_part +
|
|
interface[inum].tx_rate_part;
|
|
|
|
if(interface[inum].tot_rate_part > 1000)
|
|
{
|
|
interface[inum].tot_rate_whole++;
|
|
interface[inum].tot_rate_part -= 1000;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!first_pass)
|
|
{
|
|
printf("%12s %8lu.%03u %8lu.%03u %8lu.%03u\n",
|
|
interface[inum].name,
|
|
interface[inum].rx_rate_whole, interface[inum].rx_rate_part,
|
|
interface[inum].tx_rate_whole, interface[inum].tx_rate_part,
|
|
interface[inum].tot_rate_whole,
|
|
interface[inum].tot_rate_part);
|
|
}
|
|
}
|
|
}
|
|
|
|
fclose(devfile);
|
|
|
|
rx_bw_total_whole = 0;
|
|
tx_bw_total_whole = 0;
|
|
rx_bw_total_part = 0;
|
|
tx_bw_total_part = 0;
|
|
|
|
for(total_counter = 1; total_counter <= inum; total_counter++)
|
|
{
|
|
rx_bw_total_whole += interface[total_counter].rx_rate_whole;
|
|
rx_bw_total_part += interface[total_counter].rx_rate_part;
|
|
|
|
if(rx_bw_total_part > 1000)
|
|
{
|
|
rx_bw_total_whole++;
|
|
rx_bw_total_part -= 1000;
|
|
}
|
|
|
|
tx_bw_total_whole += interface[total_counter].tx_rate_whole;
|
|
tx_bw_total_part += interface[total_counter].tx_rate_part;
|
|
|
|
if(tx_bw_total_part > 1000)
|
|
{
|
|
tx_bw_total_whole++;
|
|
tx_bw_total_part -= 1000;
|
|
}
|
|
|
|
tot_bw_total_whole = rx_bw_total_whole + tx_bw_total_whole;
|
|
tot_bw_total_part = rx_bw_total_part + tx_bw_total_part;
|
|
|
|
if(tot_bw_total_part > 1000)
|
|
{
|
|
tot_bw_total_whole++;
|
|
tot_bw_total_part -= 1000;
|
|
}
|
|
}
|
|
|
|
if(inum < 1) printf("No interfaces!\n\n");
|
|
|
|
if(!first_pass)
|
|
{
|
|
printf("\n Total %8lu.%03u %8lu.%03u %8lu.%03u\n\n",
|
|
rx_bw_total_whole, rx_bw_total_part,
|
|
tx_bw_total_whole, tx_bw_total_part,
|
|
tot_bw_total_whole, tot_bw_total_part);
|
|
|
|
printf("Hit CTRL-C to end this madness.\n");
|
|
}
|
|
|
|
sleep(sleep_time);
|
|
first_pass = 0;
|
|
}
|
|
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
unsigned long bwm_calc_remainder(unsigned long num, unsigned long den)
|
|
{
|
|
unsigned long long n = num;
|
|
unsigned long long d = den;
|
|
|
|
return (((n - (n / d) * d) * 1000) / d);
|
|
}
|