Comparing sensitive data, confidential files or internal emails?

Most legal and privacy policies prohibit uploading sensitive data online. Diffchecker Desktop ensures your confidential information never leaves your computer. Work offline and compare documents securely.

Untitled diff

Created Diff never expires
224 removals
255 lines
281 additions
321 lines
/*
/* opyright (C) 2010 Ciriaco Garcia de Celis
* Copyright (C) 2010 Ciriaco Garcia de Celis
*
*
* This program is free software: you can redistribute it and/or
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
* the License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License (GPL) for more details.
* GNU General Public License (GPL) for more details.
*
*
* You should have received a copy of the GNU GPL along with this
* You should have received a copy of the GNU GPL along with this
* program. If not, see <http://www.gnu.org/licenses/>.
* program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
// compile with "g++ -O3 -lrt netmon.cpp -o netmon"
// compile with "g++ -O3 -lrt netmon.cpp -o netmon"
#include <sys/stat.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <fcntl.h>
#include <unistd.h>
#include <unistd.h>
#include <cstdio>
#include <cstdio>
#include <cstring>
#include <cstring>
#include <cstdlib>
#include <cstdlib>
#include <ctime>
#include <ctime>
#include <climits>
#include <climits>
#include <cctype>
#define STATE_FILE_BASE "/dev/shm/netmon"
#define STATE_FILE_BASE "/dev/shm/netmon"
int exitapp(int exitcode)
{
int exitapp(int exitcode) {
char errmsg[64];
char errmsg[64];
sprintf(errmsg, "ERROR code %d", exitcode);
sprintf(errmsg, "ERROR code %d", exitcode);
write(1, errmsg, strlen(errmsg));
write(1, errmsg, strlen(errmsg));
return exitcode;
exit(exitcode);
return exitcode;
}
}
int main(int argc, char** argv)
const int BLOCK_SIZE = 512;
{
if (argc < 2)
struct disk_stat {
{
long long read, write;
printf("usage: %s <network_interface> [CPU]\n", argv[0]);
double r_rate, w_rate;
return 1;
char name[16];
};
const int MAX_STAT = 32;
class disk_stats {
disk_stat stat[MAX_STAT];
int total;
public:
disk_stats() : total(0) {}
const char* parse(const char* line, double seconds) {
if(total>=MAX_STAT) exitapp(11);
static char cad[256], buffer[256];
long long dummy;
disk_stat &ds = stat[total];
sscanf(line,"%lld %lld %s %lld %lld %lld %lld %lld %lld %lld",
&dummy,&dummy,ds.name,&dummy,&dummy,&ds.read,&dummy,&dummy,&dummy,&ds.write);
int len = strlen(ds.name);
if(!dummy) return 0;
if(isdigit(ds.name[len-1])) return 0;
long long prev_read = 0, prev_write = 0;
sprintf(cad,"%s.%s.%d",STATE_FILE_BASE,ds.name,getuid());
int fd = open(cad, O_RDWR | O_CREAT, 0664);
if (fd < 0) exitapp(9);
int bytes = read(fd, buffer, sizeof(buffer)-1);
if (bytes < 0) exitapp(10);
buffer[bytes] = 0;
sscanf(buffer,"%lld %lld",&prev_read,&prev_write);
lseek(fd, 0, SEEK_SET);
sprintf(buffer,"%lld %lld",ds.read,ds.write);
write(fd, buffer, 64);
close(fd);
ds.r_rate = (ds.read-prev_read)/seconds*BLOCK_SIZE/1024/1024;
ds.w_rate = (ds.write-prev_write)/seconds*BLOCK_SIZE/1024/1024;
if(ds.r_rate>0) {
if(ds.w_rate>0) sprintf(buffer," | %s: %3.0lf %3.0lf",ds.name,ds.r_rate,ds.w_rate);
else sprintf(buffer," | %s: %3.0lf .",ds.name,ds.r_rate);
} else {
if(ds.w_rate>0) sprintf(buffer," | %s: . %3.0lf",ds.name,ds.w_rate);
else sprintf(buffer," | %s: . .",ds.name);
}
++total;
return buffer;
}
}
};
bool reportCPU = (argc > 2) && (strcmp(argv[2], "CPU") == 0);
char buffer[4096], cad[256], *ni, *nf;
int main(int argc, char** argv) {
if (argc < 2) {
// read network information
printf("usage: %s <network_interface>\n", argv[0]);
int fd = open("/proc/net/dev", O_RDONLY);
return 1;
if (fd < 0) return exitapp(2);
}
int bytes = read(fd, buffer, sizeof(buffer)-1);
close(fd);
if (bytes < 0) return exitapp(3);
buffer[bytes] = 0;
timespec tp;
char buffer[4096], cad[256], *ni, *nf;
clock_gettime(CLOCK_MONOTONIC, &tp);
long long nanoseconds = tp.tv_sec * 1000000000LL + tp.tv_nsec;
long long recv_bytes=LLONG_MAX, sent_bytes=LLONG_MAX;
// read network information
bool networkAvailable = false;
int fd = open("/proc/net/dev", O_RDONLY);
if (fd < 0) return exitapp(2);
int bytes = read(fd, buffer, sizeof(buffer)-1);
close(fd);
if (bytes < 0) return exitapp(3);
buffer[bytes] = 0;
// search for the proper network interface
timespec tp;
strcpy(cad, argv[1]);
clock_gettime(CLOCK_MONOTONIC, &tp);
strcat(cad, ":");
long long nanoseconds = tp.tv_sec * 1000000000LL + tp.tv_nsec;
char *pif = strstr(buffer, cad);
if (pif != NULL)
{
networkAvailable = true;
// jump to the received bytes field
long long recv_bytes=LLONG_MAX, sent_bytes=LLONG_MAX;
ni = pif + strlen(cad);
bool networkAvailable = false;
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
*nf++ = 0;
// get the received bytes
// search for the proper network interface
recv_bytes = atoll(ni);
strcpy(cad, argv[1]);
strcat(cad, ":");
char *pif = strstr(buffer, cad);
if (pif) {
networkAvailable = true;
// jump to the sent bytes field
// jump to the received bytes field
for (int skip = 0; skip < 8; skip++)
ni = pif + strlen(cad);
{
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
ni = nf;
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
*nf++ = 0;
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
if (!*nf) break;
*nf++ = 0;
}
// get the sent bytes
// get the received bytes
sent_bytes = atoll(ni);
recv_bytes = atoll(ni);
// jump to the sent bytes field
for (int skip = 0; skip < 8; skip++) {
ni = nf;
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
if (!*nf) break;
*nf++ = 0;
}
}
long long user_mode_time=0, user_mode_nice_time=0, system_mode_time=0, idle_time=0;
// get the sent bytes
sent_bytes = atoll(ni);
}
if (reportCPU)
long long user_mode_time=0, user_mode_nice_time=0, system_mode_time=0, idle_time=0;
{
// read CPU information
fd = open("/proc/stat", O_RDONLY);
if (fd < 0) return exitapp(4);
bytes = read(fd, buffer, sizeof(buffer)-1);
close(fd);
if (bytes < 0) return exitapp(5);
buffer[bytes] = 0;
pif = strstr(buffer, "cpu ");
// read CPU information
if (pif != NULL)
fd = open("/proc/stat", O_RDONLY);
{
if (fd < 0) return exitapp(4);
ni = pif + 3;
bytes = read(fd, buffer, sizeof(buffer)-1);
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
close(fd);
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
if (bytes < 0) return exitapp(5);
*nf++ = 0;
buffer[bytes] = 0;
// get the user mode time
pif = strstr(buffer, "cpu ");
user_mode_time = atoll(ni);
if (pif) {
ni = pif + 3;
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
*nf++ = 0;
ni = nf;
// get the user mode time
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
user_mode_time = atoll(ni);
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
*nf++ = 0;
// get the user mode nice time
ni = nf;
user_mode_nice_time = atoll(ni);
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
*nf++ = 0;
ni = nf;
// get the user mode nice time
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
user_mode_nice_time = atoll(ni);
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
*nf++ = 0;
// get the system mode time
ni = nf;
system_mode_time = atoll(ni);
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
*nf++ = 0;
ni = nf;
// get the system mode time
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
system_mode_time = atoll(ni);
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
*nf++ = 0;
// get the idle time
ni = nf;
idle_time = atoll(ni);
while (*ni && ((*ni == ' ') || (*ni == '\t'))) ni++;
}
for (nf = ni; *nf && (*nf != ' ') && (*nf != '\t'); nf++);
}
*nf++ = 0;
// read the received/sent bytes, date and CPU usage stored by a previous execution
// get the idle time
sprintf(cad, "%s.%s.%d", STATE_FILE_BASE, argv[1], getuid());
idle_time = atoll(ni);
fd = open(cad, O_RDWR | O_CREAT, 0664);
}
if (fd < 0) return exitapp(6);
bytes = read(fd, buffer, sizeof(buffer)-1);
if (bytes < 0)
{
close(fd);
return exitapp(7);
}
long long prev_recv_bytes, prev_sent_bytes, prev_nanoseconds = -1;
long long prev_user_mode_time, prev_user_mode_nice_time, prev_system_mode_time, prev_idle_time = -1;
if (bytes > 0)
{
prev_recv_bytes = atoll(buffer);
prev_sent_bytes = atoll(buffer+20);
prev_nanoseconds = atoll(buffer+40);
prev_user_mode_time = atoll(buffer+60);
prev_user_mode_nice_time = atoll(buffer+80);
prev_system_mode_time = atoll(buffer+100);
prev_idle_time = atoll(buffer+120);
}
// store in the file the current values for later use
// read the received/sent bytes, date and CPU usage stored by a previous execution
sprintf(buffer, "%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n",
sprintf(cad, "%s.%s.%d", STATE_FILE_BASE, argv[1], getuid());
recv_bytes, sent_bytes, nanoseconds,
fd = open(cad, O_RDWR | O_CREAT, 0664);
user_mode_time, user_mode_nice_time, system_mode_time, idle_time);
if (fd < 0) return exitapp(6);
lseek(fd, 0, SEEK_SET);
bytes = read(fd, buffer, sizeof(buffer)-1);
write(fd, buffer, 140);
if (bytes < 0) {
close(fd);
close(fd);
return exitapp(7);
}
long long prev_recv_bytes = 0, prev_sent_bytes = 0, prev_nanoseconds = -1;
long long prev_user_mode_time = 0, prev_user_mode_nice_time = 0, prev_system_mode_time = 0, prev_idle_time = -1;
if (bytes > 0) {
prev_recv_bytes = atoll(buffer);
prev_sent_bytes = atoll(buffer+20);
prev_nanoseconds = atoll(buffer+40);
prev_user_mode_time = atoll(buffer+60);
prev_user_mode_nice_time = atoll(buffer+80);
prev_system_mode_time = atoll(buffer+100);
prev_idle_time = atoll(buffer+120);
}
// generate the result
// store in the file the current values for later use
sprintf(buffer, "%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n%019lld\n",
recv_bytes, sent_bytes, nanoseconds,
user_mode_time, user_mode_nice_time, system_mode_time, idle_time);
lseek(fd, 0, SEEK_SET);
write(fd, buffer, 140);
close(fd);
strcpy(buffer, "<txt>");
// generate the result
bool hasNet = networkAvailable && (prev_nanoseconds >= 0) && (recv_bytes >= prev_recv_bytes) && (sent_bytes >= prev_sent_bytes);
strcpy(buffer, "<txt>");
long long elapsed = nanoseconds - prev_nanoseconds;
if (elapsed < 1) elapsed = 1;
double seconds = elapsed / 1000000000.0;
if (!networkAvailable)
// NETWORK
{
bool hasNet = networkAvailable && (prev_nanoseconds >= 0) && (recv_bytes >= prev_recv_bytes) && (sent_bytes >= prev_sent_bytes);
sprintf(cad, " %s is down", argv[1]);
strcat(buffer, cad);
}
else if (!hasNet)
{
strcat(buffer, " ? kbps IN \n ? kbps OUT");
}
else
{
long long elapsed = nanoseconds - prev_nanoseconds;
if (elapsed < 1) elapsed = 1;
double seconds = elapsed / 1000000000.0;
long long sent = sent_bytes - prev_sent_bytes;
long long received = recv_bytes - prev_recv_bytes;
long inbps = (long) (8 * received / seconds + 999); // adding 999 ensures "1" for any rate above 0
long outbps = (long) (8 * sent / seconds + 999);
if (inbps < 1000000)
sprintf(cad, "%6d kbps IN \n", inbps/1000);
else
sprintf(cad, "%6.3f Mbps IN \n", inbps/1000000.0);
strcat(buffer, cad);
if (outbps < 1000000)
if (!networkAvailable) {
sprintf(cad, "%6d kbps OUT", outbps/1000);
sprintf(cad, " %s is down", argv[1]);
else
strcat(buffer, cad);
sprintf(cad, "%6.3f Mbps OUT", outbps/1000000.0);
} else if (!hasNet) {
strcat(buffer, cad);
strcat(buffer, "D: - U: - ");
} else {
}
long long sent = sent_bytes - prev_sent_bytes;
long long received = recv_bytes - prev_recv_bytes;
long inbps = (long) (8 * received / seconds + 999) / 8 / 1024; // adding 999 ensures "1" for any rate above 0
long outbps = (long) (8 * sent / seconds + 999) / 8 / 1024;
long long cpu_used = user_mode_time + user_mode_nice_time + system_mode_time
if (inbps < 1024) sprintf(cad, "D: %5ld KB/s ", inbps);
else sprintf(cad, "D: %5.0lf MB/s ", inbps/1024.0);
strcat(buffer, cad);
if (outbps < 1024) sprintf(cad, " | U: %5ld KB/s ", outbps);
else sprintf(cad, " | U: %5.0lf MB/s ", outbps/1024.0);
strcat(buffer, cad);
}
long long cpu_used = user_mode_time + user_mode_nice_time + system_mode_time
- (prev_user_mode_time + prev_user_mode_nice_time + prev_system_mode_time);
- (prev_user_mode_time + prev_user_mode_nice_time + prev_system_mode_time);
long long total_cpu = cpu_used + (idle_time - prev_idle_time);
long long total_cpu = cpu_used + (idle_time - prev_idle_time);
bool hasCPU = (prev_idle_time >= 0) && (total_cpu > 0);
int total_ram = 0, ram_used = 0;
if (reportCPU)
bool hasCPU = (prev_idle_time >= 0) && (total_cpu > 0);
{
if (!hasCPU)
{
strcat(buffer, "\n ? % CPU");
}
else
{
sprintf(cad, "\n %5.1f%% CPU", cpu_used * 100.0 / total_cpu);
strcat(buffer, cad);
}
}
strcat(buffer, "</txt><tool>");
// CPU
if (!hasCPU) sprintf(cad, " | CPU: %3lld",total_cpu);
else sprintf(cad, " | CPU: %3.0lf%%", cpu_used * 100.0 / total_cpu);
strcat(buffer, cad);
if (networkAvailable && hasNet)
// RAM
{
FILE *meminfo = fopen("/proc/meminfo", "r");
sprintf(cad, " %s:\n %.2f MB received \n %.2f MB sent ",
if(meminfo) {
argv[1], recv_bytes/1000000.0, sent_bytes/1000000.0);
char line[256];
strcat(buffer, cad);
while(fgets(line, sizeof(line), meminfo)) {
if(!total_ram && sscanf(line, "MemTotal: %d kB", &total_ram));
if(sscanf(line, "Active: %d kB", &ram_used) == 1) {
sprintf(cad," | RAM: %5d MB",ram_used/1024);
break;
}
}
}
fclose(meminfo);
if(!ram_used) sprintf(cad, " RAM: %5d MB",total_ram);
strcat(buffer,cad);
}
if (reportCPU && hasCPU)
// DISK
{
FILE *diskstat = fopen("/proc/diskstats","rt");
if (networkAvailable && hasNet) strcat(buffer, "\n");
disk_stats dss;
long long total_used_cpu = user_mode_time + user_mode_nice_time + system_mode_time;
if(diskstat) {
sprintf(cad, " CPU usage:\n %5.1f%% since boot ",
char line[512];
total_used_cpu * 100.0 / (total_used_cpu + idle_time));
while(fgets(line,sizeof(line),diskstat)) {
strcat(buffer, cad);
const char *cad = dss.parse(line,seconds);
if(!cad) continue;
strcat(buffer, cad);
}
}
fclose(diskstat);
}
strcat(buffer, "</tool>");
strcat(buffer, "</txt><tool>");
write(1, buffer, strlen(buffer));
return 0;
// TOOLTIPS
bool useNet = networkAvailable && hasNet;
if (useNet) {
sprintf(cad, " %s:\n %.2f MB received \n %.2f MB sent ",
argv[1], recv_bytes/1024.0/1024, sent_bytes/1024.0/1024);
strcat(buffer, cad);
}
if (hasCPU) {
if (useNet) strcat(buffer, "\n");
long long total_used_cpu = user_mode_time + user_mode_nice_time + system_mode_time;
sprintf(cad, " CPU usage:\n %5.1f%% since boot \n",
total_used_cpu * 100.0 / (total_used_cpu + idle_time));
strcat(buffer, cad);
}
sprintf(cad, " RAM usage:\n %5.1f%% of %d MB",
ram_used * 100.0 / total_ram, total_ram / 1024 );
strcat(buffer, cad);
strcat(buffer, "</tool>");
write(1, buffer, strlen(buffer));
return 0;
}
}