sums, not eating 100% cpu :)
This commit is contained in:
8
Makefile
8
Makefile
@@ -8,10 +8,10 @@ DESTDIR := /usr/local
|
||||
bin := $(DESTDIR)/bin
|
||||
man8 := $(DESTDIR)/share/man/man8/
|
||||
|
||||
all: nethogs decpcap_test
|
||||
all: nethogs decpcap_test nethogs_testsum
|
||||
|
||||
#CFLAGS=-g -Wall
|
||||
CFLAGS=-O2
|
||||
CFLAGS=-g -Wall
|
||||
#CFLAGS=-O2
|
||||
OBJS=packet.o connection.o process.o refresh.o decpcap.o cui.o inode2prog.o
|
||||
.PHONY: tgz
|
||||
|
||||
@@ -28,6 +28,8 @@ install: nethogs nethogs.8
|
||||
|
||||
nethogs: nethogs.cpp $(OBJS)
|
||||
$(CXX) $(CFLAGS) nethogs.cpp $(OBJS) -o nethogs -lpcap -lm -lncurses -DVERSION=\"$(VERSION)\" -DSUBVERSION=\"$(SUBVERSION)\" -DMINORVERSION=\"$(MINORVERSION)\"
|
||||
nethogs_testsum: nethogs_testsum.cpp $(OBJS)
|
||||
$(CXX) $(CFLAGS) -g nethogs_testsum.cpp $(OBJS) -o nethogs_testsum -lpcap -lm -lncurses -DVERSION=\"$(VERSION)\" -DSUBVERSION=\"$(SUBVERSION)\" -DMINORVERSION=\"$(MINORVERSION)\"
|
||||
|
||||
decpcap_test: decpcap_test.cpp decpcap.o
|
||||
$(CXX) $(CFLAGS) decpcap_test.cpp decpcap.o -o decpcap_test -lpcap -lm
|
||||
|
||||
@@ -69,19 +69,25 @@ Connection::Connection (Packet * packet)
|
||||
connections = new ConnList (this, connections);
|
||||
sent_packets = new PackList ();
|
||||
recv_packets = new PackList ();
|
||||
sumSent = 0;
|
||||
sumRecv = 0;
|
||||
if (DEBUG)
|
||||
{
|
||||
std::cout << "New connection, with package len " << packet->len << std::endl;
|
||||
}
|
||||
if (packet->Outgoing())
|
||||
{
|
||||
sumSent += packet->len;
|
||||
sent_packets->add(packet);
|
||||
refpacket = new Packet (*packet);
|
||||
} else {
|
||||
sumRecv += packet->len;
|
||||
recv_packets->add(packet);
|
||||
refpacket = packet->newInverted();
|
||||
}
|
||||
lastpacket = packet->time.tv_sec;
|
||||
if (DEBUG)
|
||||
std::cout << "New reference packet created at " << refpacket << std::endl;
|
||||
sumSent = 0;
|
||||
sumRecv = 0;
|
||||
}
|
||||
|
||||
Connection::~Connection ()
|
||||
@@ -126,12 +132,21 @@ void Connection::add (Packet * packet)
|
||||
lastpacket = packet->time.tv_sec;
|
||||
if (packet->Outgoing())
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
std::cout << "Outgoing: " << packet->len << std::endl;
|
||||
}
|
||||
sumSent += packet->len;
|
||||
sent_packets->add (packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
std::cout << "Incoming: " << packet->len << std::endl;
|
||||
}
|
||||
sumRecv += packet->len;
|
||||
std::cout << "sumRecv now: " << sumRecv << std::endl;
|
||||
recv_packets->add (packet);
|
||||
}
|
||||
}
|
||||
@@ -168,7 +183,7 @@ Connection * findConnection (Packet * packet)
|
||||
* Returns sum of sent packages (by address)
|
||||
* sum of recieved packages (by address)
|
||||
*/
|
||||
void Connection::sumanddel (timeval t, u_int32_t * sent, u_int32_t * recv)
|
||||
void Connection::sumanddel (timeval t, u_int32_t * recv, u_int32_t * sent)
|
||||
{
|
||||
(*sent)=(*recv)=0;
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
|
||||
/* sums up the total bytes used
|
||||
* and removes 'old' packets. */
|
||||
void sumanddel(timeval curtime, u_int32_t * sent, u_int32_t * recv);
|
||||
void sumanddel(timeval curtime, u_int32_t * recv, u_int32_t * sent);
|
||||
|
||||
/* for checking if a packet is part of this connection */
|
||||
/* the reference packet is always *outgoing*. */
|
||||
|
||||
83
cui.cpp
83
cui.cpp
@@ -20,15 +20,17 @@ extern Process * unknownip;
|
||||
// sort on sent or received?
|
||||
bool sortRecv = true;
|
||||
// viewMode: kb/s or total
|
||||
int viewMode = 0;
|
||||
int VIEWMODE_KBPS = 0;
|
||||
int VIEWMODE_TOTAL_KB = 1;
|
||||
int nViewModes = 2;
|
||||
int VIEWMODE_TOTAL_B = 2;
|
||||
int VIEWMODE_TOTAL_MB = 3;
|
||||
int viewMode = VIEWMODE_TOTAL_B;
|
||||
int nViewModes = 4;
|
||||
|
||||
class Line
|
||||
{
|
||||
public:
|
||||
Line (const char * name, double n_sent_value, double n_recv_value, pid_t pid, uid_t uid, const char * n_devicename)
|
||||
Line (const char * name, double n_recv_value, double n_sent_value, pid_t pid, uid_t uid, const char * n_devicename)
|
||||
{
|
||||
if (!ROBUST)
|
||||
{
|
||||
@@ -116,10 +118,18 @@ void Line::show (int row)
|
||||
{
|
||||
mvprintw (3+row, 6 + 9 + PROGNAME_WIDTH + 2 + 6 + 9 + 3 + 11, "KB/sec");
|
||||
}
|
||||
else if (viewMode == VIEWMODE_TOTAL_MB)
|
||||
{
|
||||
mvprintw (3+row, 6 + 9 + PROGNAME_WIDTH + 2 + 6 + 9 + 3 + 11, "MB ");
|
||||
}
|
||||
else if (viewMode == VIEWMODE_TOTAL_KB)
|
||||
{
|
||||
mvprintw (3+row, 6 + 9 + PROGNAME_WIDTH + 2 + 6 + 9 + 3 + 11, "KB ");
|
||||
}
|
||||
else if (viewMode == VIEWMODE_TOTAL_B)
|
||||
{
|
||||
mvprintw (3+row, 6 + 9 + PROGNAME_WIDTH + 2 + 6 + 9 + 3 + 11, "B ");
|
||||
}
|
||||
}
|
||||
|
||||
int GreatestFirst (const void * ma, const void * mb)
|
||||
@@ -200,6 +210,14 @@ void ui_tick ()
|
||||
}
|
||||
}
|
||||
|
||||
float tomb (u_int32_t bytes)
|
||||
{
|
||||
return ((double)bytes) / 1024 / 1024;
|
||||
}
|
||||
float tokb (u_int32_t bytes)
|
||||
{
|
||||
return ((double)bytes) / 1024;
|
||||
}
|
||||
float tokbps (u_int32_t bytes)
|
||||
{
|
||||
return (((double)bytes) / PERIOD) / 1024;
|
||||
@@ -233,7 +251,7 @@ void getkbps (Process * curproc, float * recvd, float * sent)
|
||||
else
|
||||
{
|
||||
u_int32_t sent = 0, recv = 0;
|
||||
curconn->getVal()->sumanddel(curtime, &sent, &recv);
|
||||
curconn->getVal()->sumanddel(curtime, &recv, &sent);
|
||||
sum_sent += sent;
|
||||
sum_recv += recv;
|
||||
previous = curconn;
|
||||
@@ -245,7 +263,7 @@ void getkbps (Process * curproc, float * recvd, float * sent)
|
||||
}
|
||||
|
||||
/** get total values for this process */
|
||||
void gettotal(Process * curproc, float * recvd, float * sent)
|
||||
void gettotal(Process * curproc, u_int32_t * recvd, u_int32_t * sent)
|
||||
{
|
||||
u_int32_t sum_sent = 0,
|
||||
sum_recv = 0;
|
||||
@@ -257,8 +275,39 @@ void gettotal(Process * curproc, float * recvd, float * sent)
|
||||
sum_recv += conn->sumRecv;
|
||||
curconn = curconn->getNext();
|
||||
}
|
||||
*recvd = tokbps(sum_recv);
|
||||
*sent = tokbps(sum_sent);
|
||||
//std::cout << "Sum sent: " << sum_sent << std::endl;
|
||||
//std::cout << "Sum recv: " << sum_recv << std::endl;
|
||||
*recvd = sum_recv;
|
||||
*sent = sum_sent;
|
||||
}
|
||||
|
||||
void gettotalmb(Process * curproc, float * recvd, float * sent)
|
||||
{
|
||||
u_int32_t sum_sent = 0,
|
||||
sum_recv = 0;
|
||||
gettotal(curproc, &sum_recv, &sum_sent);
|
||||
*recvd = tomb(sum_recv);
|
||||
*sent = tomb(sum_sent);
|
||||
}
|
||||
|
||||
/** get total values for this process */
|
||||
void gettotalkb(Process * curproc, float * recvd, float * sent)
|
||||
{
|
||||
u_int32_t sum_sent = 0,
|
||||
sum_recv = 0;
|
||||
gettotal(curproc, &sum_recv, &sum_sent);
|
||||
*recvd = tokb(sum_recv);
|
||||
*sent = tokb(sum_sent);
|
||||
}
|
||||
|
||||
void gettotalb(Process * curproc, float * recvd, float * sent)
|
||||
{
|
||||
u_int32_t sum_sent = 0,
|
||||
sum_recv = 0;
|
||||
gettotal(curproc, &sum_recv, &sum_sent);
|
||||
//std::cout << "Total sent: " << sum_sent << std::endl;
|
||||
*sent = sum_sent;
|
||||
*recvd = sum_recv;
|
||||
}
|
||||
|
||||
// Display all processes and relevant network traffic using show function
|
||||
@@ -335,11 +384,23 @@ void do_refresh()
|
||||
|
||||
if (viewMode == VIEWMODE_KBPS)
|
||||
{
|
||||
std::cout << "kbps viemode" << std::endl;
|
||||
getkbps (curproc->getVal(), &value_recv, &value_sent);
|
||||
}
|
||||
else if (viewMode == VIEWMODE_TOTAL_KB)
|
||||
{
|
||||
gettotal(curproc->getVal(), &value_recv, &value_sent);
|
||||
//std::cout << "total viemode" << std::endl;
|
||||
gettotalkb(curproc->getVal(), &value_recv, &value_sent);
|
||||
}
|
||||
else if (viewMode == VIEWMODE_TOTAL_MB)
|
||||
{
|
||||
//std::cout << "total viemode" << std::endl;
|
||||
gettotalmb(curproc->getVal(), &value_recv, &value_sent);
|
||||
}
|
||||
else if (viewMode == VIEWMODE_TOTAL_B)
|
||||
{
|
||||
//std::cout << "total viemode" << std::endl;
|
||||
gettotalb(curproc->getVal(), &value_recv, &value_sent);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -354,7 +415,7 @@ void do_refresh()
|
||||
assert (curproc->getVal()->pid >= 0);
|
||||
assert (n < nproc);
|
||||
}
|
||||
lines[n] = new Line (curproc->getVal()->name, value_sent, value_recv,
|
||||
lines[n] = new Line (curproc->getVal()->name, value_recv, value_sent,
|
||||
curproc->getVal()->pid, uid, curproc->getVal()->devicename);
|
||||
previousproc = curproc;
|
||||
curproc = curproc->next;
|
||||
@@ -399,8 +460,12 @@ void do_refresh()
|
||||
if (viewMode == VIEWMODE_KBPS)
|
||||
{
|
||||
mvprintw (3+1+i, 73, "KB/sec ");
|
||||
} else if (viewMode == VIEWMODE_TOTAL_B) {
|
||||
mvprintw (3+1+i, 73, "B ");
|
||||
} else if (viewMode == VIEWMODE_TOTAL_KB) {
|
||||
mvprintw (3+1+i, 73, "KB ");
|
||||
} else if (viewMode == VIEWMODE_TOTAL_MB) {
|
||||
mvprintw (3+1+i, 73, "MB ");
|
||||
}
|
||||
attroff(A_REVERSE);
|
||||
mvprintw (4+1+i, 0, "");
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include <pcap.h>
|
||||
#include "decpcap.h"
|
||||
|
||||
#define DP_DEBUG 0
|
||||
|
||||
/* functions to set up a handle (which is basically just a pcap handle) */
|
||||
|
||||
struct dp_handle * dp_fillhandle(pcap_t * phandle)
|
||||
@@ -92,6 +94,10 @@ void dp_parse_tcp (struct dp_handle * handle, const dp_header * header, const u_
|
||||
void dp_parse_ip (struct dp_handle * handle, const dp_header * header, const u_char * packet)
|
||||
{
|
||||
const struct ip * ip = (struct ip *) packet;
|
||||
if (DP_DEBUG)
|
||||
{
|
||||
fprintf(stdout, "Looking at packet with length %ud\n", header->len);
|
||||
}
|
||||
u_char * payload = (u_char *) packet + sizeof (struct ip);
|
||||
|
||||
if (handle->callback[dp_packet_ip] != NULL)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <stdio.h>
|
||||
#include <pcap.h>
|
||||
|
||||
#define DP_ERRBUFF_SIZE PCAP_ERRBUF_SIZE
|
||||
#define DP_ERRBUF_SIZE PCAP_ERRBUF_SIZE
|
||||
|
||||
/* definitions */
|
||||
|
||||
@@ -24,6 +24,7 @@ enum dp_packet_type {
|
||||
};*/
|
||||
|
||||
/*struct dp_header {
|
||||
* pcap
|
||||
};*/
|
||||
typedef struct pcap_pkthdr dp_header;
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@ extern "C" {
|
||||
|
||||
int process_tcp (u_char * userdata, const dp_header * header, const u_char * m_packet) {
|
||||
std::cout << "Callback for processing TCP packet called" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
@@ -16,7 +16,7 @@ int main (int argc, char ** argv)
|
||||
std::cout << "Please, enter a filename" << std::endl;
|
||||
}
|
||||
|
||||
char* errbuf = new char[DP_ERRBUFF_SIZE];
|
||||
char* errbuf = new char[DP_ERRBUF_SIZE];
|
||||
|
||||
dp_handle * newhandle = dp_open_offline(argv[1], errbuf);
|
||||
dp_addcb (newhandle, dp_packet_tcp, process_tcp);
|
||||
@@ -25,5 +25,4 @@ int main (int argc, char ** argv)
|
||||
{
|
||||
std::cout << "Error dispatching: " << dp_geterr(newhandle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ void get_info_by_linkname (char * pid, char * linkname) {
|
||||
|
||||
/* updates the `inodeproc' inode-to-prg_node
|
||||
* for all inodes belonging to this PID
|
||||
* (/proc/pid/fd/*)
|
||||
* (/proc/pid/fd/42)
|
||||
* */
|
||||
void get_info_for_pid(char * pid) {
|
||||
size_t dirlen = 10 + strlen(pid);
|
||||
|
||||
32
nethogs.cpp
32
nethogs.cpp
@@ -345,7 +345,8 @@ int main (int argc, char** argv)
|
||||
if (newhandle != NULL)
|
||||
{
|
||||
/* The following code solves sf.net bug 1019381, but is only available
|
||||
* in newer versions (from 0.8 it seems) of libpcap */
|
||||
* in newer versions (from 0.8 it seems) of libpcap
|
||||
*/
|
||||
if (dp_setnonblock (newhandle, 1, errbuf) == -1)
|
||||
{
|
||||
// ERROR
|
||||
@@ -359,29 +360,54 @@ int main (int argc, char** argv)
|
||||
signal (SIGALRM, &alarm_cb);
|
||||
signal (SIGINT, &quit_cb);
|
||||
alarm (refreshdelay);
|
||||
|
||||
fprintf(stderr, "Waiting for first packet to arrive (see sourceforge.net bug 1019381)\n");
|
||||
|
||||
// Main loop:
|
||||
//
|
||||
// Walks though the 'handles' list, which contains handles opened in non-blocking mode.
|
||||
// This causes the CPU utilisation to go up to 100%. This is tricky:
|
||||
while (1)
|
||||
{
|
||||
bool packets_read = false;
|
||||
|
||||
handle * current_handle = handles;
|
||||
while (current_handle != NULL)
|
||||
{
|
||||
struct dpargs * userdata = (dpargs *) malloc (sizeof (struct dpargs));
|
||||
userdata->sa_family = AF_UNSPEC;
|
||||
currentdevice = current_handle->devicename;
|
||||
dp_dispatch (current_handle->content, -1, (u_char *)userdata, sizeof (struct dpargs));
|
||||
int retval = dp_dispatch (current_handle->content, -1, (u_char *)userdata, sizeof (struct dpargs));
|
||||
if (retval == -1 || retval == -2)
|
||||
{
|
||||
std::cerr << "Error dispatching" << std::endl;
|
||||
}
|
||||
else if (retval != 0)
|
||||
{
|
||||
packets_read = true;
|
||||
}
|
||||
free (userdata);
|
||||
current_handle = current_handle->next;
|
||||
}
|
||||
|
||||
if ((!DEBUG)&&(!tracemode)) {
|
||||
if ((!DEBUG)&&(!tracemode))
|
||||
{
|
||||
// handle user input
|
||||
ui_tick();
|
||||
}
|
||||
|
||||
if (needrefresh)
|
||||
{
|
||||
do_refresh();
|
||||
needrefresh = false;
|
||||
}
|
||||
|
||||
// If no packets were read at all this iteration, pause to prevent 100%
|
||||
// CPU utilisation;
|
||||
if (!packets_read)
|
||||
{
|
||||
usleep(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
/* the process makes a copy of the device name and name. */
|
||||
Process (unsigned long m_inode, char * m_devicename, char * m_name = NULL)
|
||||
{
|
||||
//std::cout << "ARN: Process created with dev " << m_devicename << std::endl;
|
||||
if (DEBUG)
|
||||
std::cout << "PROC: Process created at " << this << std::endl;
|
||||
inode = m_inode;
|
||||
|
||||
Reference in New Issue
Block a user