Use clang-format to format (somewhat) LLVM-style (fixes #44)
This commit is contained in:
4
Makefile
4
Makefile
@@ -30,7 +30,9 @@ nethogs:
|
||||
decpcap_test:
|
||||
$(MAKE) -f MakeApp.mk $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(MAKE) -f MakeApp.mk $@
|
||||
$(MAKE) -f MakeLib.mk $@
|
||||
|
||||
format:
|
||||
clang-format -i *.c *.cpp *.h
|
||||
|
||||
24
README.md
24
README.md
@@ -44,22 +44,16 @@ After that, simply
|
||||
Coding standards
|
||||
----------------
|
||||
|
||||
Can anyone recommend a sensible set? :)
|
||||
We use the [http://llvm.org/docs/CodingStandards.html](LLVM coding standards),
|
||||
with the exception that we do allow 'return' after 'else' if it makes the code
|
||||
more readable.
|
||||
|
||||
For now:
|
||||
* '{'
|
||||
* on a new line for function definitions
|
||||
* on a new line for enums
|
||||
* on the same line for conditionals/loops
|
||||
* omitted when possible
|
||||
* use tab for indentation
|
||||
* use doxygen/javadoc-style comments.
|
||||
* for multiline doxygen docs, add a newline after '/**'
|
||||
* case
|
||||
* classes: camelcased, start uppercase
|
||||
* enums: camelcased, start uppercase
|
||||
* functions: camelcased, start lowercase
|
||||
* local variables: camelcased, start lowercase
|
||||
Not all code currently adheres to this standard. Pull requests fixing style
|
||||
are welcome, and do write new code in the proper style, but please do not
|
||||
mix style fixes and new functionality in one pull request.
|
||||
|
||||
When writing new code, at least run 'make format' to have clang-format fix
|
||||
some superficial style aspects.
|
||||
|
||||
libnethogs
|
||||
----------
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#ifdef __APPLE__
|
||||
@@ -33,16 +33,13 @@
|
||||
|
||||
ConnList *connections = NULL;
|
||||
|
||||
void PackList::add (Packet * p)
|
||||
{
|
||||
if (content == NULL)
|
||||
{
|
||||
void PackList::add(Packet *p) {
|
||||
if (content == NULL) {
|
||||
content = new PackListNode(new Packet(*p));
|
||||
return;
|
||||
}
|
||||
|
||||
if (content->val->time.tv_sec == p->time.tv_sec)
|
||||
{
|
||||
if (content->val->time.tv_sec == p->time.tv_sec) {
|
||||
content->val->len += p->len;
|
||||
return;
|
||||
}
|
||||
@@ -52,17 +49,15 @@ void PackList::add (Packet * p)
|
||||
}
|
||||
|
||||
/* sums up the total bytes used and removes 'old' packets */
|
||||
u_int32_t PackList::sumanddel (timeval t)
|
||||
{
|
||||
u_int32_t PackList::sumanddel(timeval t) {
|
||||
u_int32_t retval = 0;
|
||||
PackListNode *current = content;
|
||||
PackListNode *previous = NULL;
|
||||
|
||||
while (current != NULL)
|
||||
{
|
||||
//std::cout << "Comparing " << current->val->time.tv_sec << " <= " << t.tv_sec - PERIOD << endl;
|
||||
if (current->val->time.tv_sec <= t.tv_sec - PERIOD)
|
||||
{
|
||||
while (current != NULL) {
|
||||
// std::cout << "Comparing " << current->val->time.tv_sec << " <= " <<
|
||||
// t.tv_sec - PERIOD << endl;
|
||||
if (current->val->time.tv_sec <= t.tv_sec - PERIOD) {
|
||||
if (current == content)
|
||||
content = NULL;
|
||||
else if (previous != NULL)
|
||||
@@ -78,20 +73,18 @@ u_int32_t PackList::sumanddel (timeval t)
|
||||
}
|
||||
|
||||
/* packet may be deleted by caller */
|
||||
Connection::Connection (Packet * packet)
|
||||
{
|
||||
Connection::Connection(Packet *packet) {
|
||||
assert(packet != NULL);
|
||||
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 (DEBUG) {
|
||||
std::cout << "New connection, with package len " << packet->len
|
||||
<< std::endl;
|
||||
}
|
||||
if (packet->Outgoing())
|
||||
{
|
||||
if (packet->Outgoing()) {
|
||||
sumSent += packet->len;
|
||||
sent_packets->add(packet);
|
||||
refpacket = new Packet(*packet);
|
||||
@@ -105,8 +98,7 @@ Connection::Connection (Packet * packet)
|
||||
std::cout << "New reference packet created at " << refpacket << std::endl;
|
||||
}
|
||||
|
||||
Connection::~Connection ()
|
||||
{
|
||||
Connection::~Connection() {
|
||||
if (DEBUG)
|
||||
std::cout << "Deleting connection" << std::endl;
|
||||
/* refpacket is not a pointer to one of the packets in the lists
|
||||
@@ -119,22 +111,17 @@ Connection::~Connection ()
|
||||
|
||||
ConnList *curr_conn = connections;
|
||||
ConnList *prev_conn = NULL;
|
||||
while (curr_conn != NULL)
|
||||
{
|
||||
if (curr_conn->getVal() == this)
|
||||
{
|
||||
while (curr_conn != NULL) {
|
||||
if (curr_conn->getVal() == this) {
|
||||
ConnList *todelete = curr_conn;
|
||||
curr_conn = curr_conn->getNext();
|
||||
if (prev_conn == NULL)
|
||||
{
|
||||
if (prev_conn == NULL) {
|
||||
connections = curr_conn;
|
||||
} else {
|
||||
prev_conn->setNext(curr_conn);
|
||||
}
|
||||
delete (todelete);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
prev_conn = curr_conn;
|
||||
curr_conn = curr_conn->getNext();
|
||||
}
|
||||
@@ -142,27 +129,20 @@ Connection::~Connection ()
|
||||
}
|
||||
|
||||
/* the packet will be freed by the calling code */
|
||||
void Connection::add (Packet * packet)
|
||||
{
|
||||
void Connection::add(Packet *packet) {
|
||||
lastpacket = packet->time.tv_sec;
|
||||
if (packet->Outgoing())
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
if (packet->Outgoing()) {
|
||||
if (DEBUG) {
|
||||
std::cout << "Outgoing: " << packet->len << std::endl;
|
||||
}
|
||||
sumSent += packet->len;
|
||||
sent_packets->add(packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
std::cout << "Incoming: " << packet->len << std::endl;
|
||||
}
|
||||
sumRecv += packet->len;
|
||||
if (DEBUG)
|
||||
{
|
||||
if (DEBUG) {
|
||||
std::cout << "sumRecv now: " << sumRecv << std::endl;
|
||||
}
|
||||
recv_packets->add(packet);
|
||||
@@ -173,11 +153,9 @@ Connection * findConnectionWithMatchingSource(Packet * packet) {
|
||||
assert(packet->Outgoing());
|
||||
|
||||
ConnList *current = connections;
|
||||
while (current != NULL)
|
||||
{
|
||||
while (current != NULL) {
|
||||
/* the reference packet is always outgoing */
|
||||
if (packet->matchSource(current->getVal()->refpacket))
|
||||
{
|
||||
if (packet->matchSource(current->getVal()->refpacket)) {
|
||||
return current->getVal();
|
||||
}
|
||||
|
||||
@@ -188,11 +166,9 @@ Connection * findConnectionWithMatchingSource(Packet * packet) {
|
||||
|
||||
Connection *findConnectionWithMatchingRefpacketOrSource(Packet *packet) {
|
||||
ConnList *current = connections;
|
||||
while (current != NULL)
|
||||
{
|
||||
while (current != NULL) {
|
||||
/* the reference packet is always *outgoing* */
|
||||
if (packet->match(current->getVal()->refpacket))
|
||||
{
|
||||
if (packet->match(current->getVal()->refpacket)) {
|
||||
return current->getVal();
|
||||
}
|
||||
|
||||
@@ -206,14 +182,13 @@ Connection * findConnectionWithMatchingRefpacketOrSource(Packet * packet) {
|
||||
* a packet belongs to a connection if it matches
|
||||
* to its reference packet
|
||||
*/
|
||||
Connection * findConnection (Packet * packet)
|
||||
{
|
||||
Connection *findConnection(Packet *packet) {
|
||||
if (packet->Outgoing())
|
||||
return findConnectionWithMatchingRefpacketOrSource(packet);
|
||||
else
|
||||
{
|
||||
else {
|
||||
Packet *invertedPacket = packet->newInverted();
|
||||
Connection * result = findConnectionWithMatchingRefpacketOrSource(invertedPacket);
|
||||
Connection *result =
|
||||
findConnectionWithMatchingRefpacketOrSource(invertedPacket);
|
||||
|
||||
delete invertedPacket;
|
||||
return result;
|
||||
@@ -229,8 +204,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 * recv, u_int32_t * sent)
|
||||
{
|
||||
void Connection::sumanddel(timeval t, u_int32_t *recv, u_int32_t *sent) {
|
||||
(*sent) = (*recv) = 0;
|
||||
|
||||
*sent = sent_packets->sumanddel(t);
|
||||
|
||||
34
connection.h
34
connection.h
@@ -15,7 +15,8 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __CONNECTION_H
|
||||
@@ -24,16 +25,13 @@
|
||||
#include <iostream>
|
||||
#include "packet.h"
|
||||
|
||||
class PackListNode
|
||||
{
|
||||
class PackListNode {
|
||||
public:
|
||||
PackListNode (Packet * m_val, PackListNode * m_next = NULL)
|
||||
{
|
||||
PackListNode(Packet *m_val, PackListNode *m_next = NULL) {
|
||||
val = m_val;
|
||||
next = m_next;
|
||||
}
|
||||
~PackListNode ()
|
||||
{
|
||||
~PackListNode() {
|
||||
delete val;
|
||||
if (next != NULL)
|
||||
delete next;
|
||||
@@ -42,20 +40,14 @@ public:
|
||||
Packet *val;
|
||||
};
|
||||
|
||||
class PackList
|
||||
{
|
||||
class PackList {
|
||||
public:
|
||||
PackList ()
|
||||
{
|
||||
content = NULL;
|
||||
}
|
||||
PackList (Packet * m_val)
|
||||
{
|
||||
PackList() { content = NULL; }
|
||||
PackList(Packet *m_val) {
|
||||
assert(m_val != NULL);
|
||||
content = new PackListNode(m_val);
|
||||
}
|
||||
~PackList ()
|
||||
{
|
||||
~PackList() {
|
||||
if (content != NULL)
|
||||
delete content;
|
||||
}
|
||||
@@ -65,12 +57,12 @@ public:
|
||||
|
||||
/* calling code may delete packet */
|
||||
void add(Packet *p);
|
||||
|
||||
private:
|
||||
PackListNode *content;
|
||||
};
|
||||
|
||||
class Connection
|
||||
{
|
||||
class Connection {
|
||||
public:
|
||||
/* constructs a connection, makes a copy of
|
||||
* the packet as 'refpacket', and adds the
|
||||
@@ -87,8 +79,7 @@ public:
|
||||
*/
|
||||
void add(Packet *packet);
|
||||
|
||||
int getLastPacket ()
|
||||
{ return lastpacket; }
|
||||
int getLastPacket() { return lastpacket; }
|
||||
|
||||
/* sums up the total bytes used
|
||||
* and removes 'old' packets. */
|
||||
@@ -101,6 +92,7 @@ public:
|
||||
/* total sum or sent/received bytes */
|
||||
u_int32_t sumSent;
|
||||
u_int32_t sumRecv;
|
||||
|
||||
private:
|
||||
PackList *sent_packets;
|
||||
PackList *recv_packets;
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <map>
|
||||
#include <cstdio>
|
||||
@@ -42,19 +42,22 @@ extern local_addr * local_addrs;
|
||||
*/
|
||||
std::map<std::string, unsigned long> conninode;
|
||||
|
||||
|
||||
/*
|
||||
* parses a /proc/net/tcp-line of the form:
|
||||
* sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
|
||||
* 10: 020310AC:1770 9DD8A9C3:A525 01 00000000:00000000 00:00000000 00000000 0 0 2119 1 c0f4f0c0 206 40 10 3 -1
|
||||
* 11: 020310AC:0404 936B2ECF:0747 01 00000000:00000000 00:00000000 00000000 1000 0 2109 1 c0f4fc00 368 40 20 2 -1
|
||||
* sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt
|
||||
*uid timeout inode
|
||||
* 10: 020310AC:1770 9DD8A9C3:A525 01 00000000:00000000 00:00000000 00000000
|
||||
*0 0 2119 1 c0f4f0c0 206 40 10 3 -1
|
||||
* 11: 020310AC:0404 936B2ECF:0747 01 00000000:00000000 00:00000000 00000000
|
||||
*1000 0 2109 1 c0f4fc00 368 40 20 2 -1
|
||||
*
|
||||
* and of the form:
|
||||
* 2: 0000000000000000FFFF0000020310AC:0016 0000000000000000FFFF00009DD8A9C3:A526 01 00000000:00000000 02:000A7214 00000000 0 0 2525 2 c732eca0 201 40 1 2 -1
|
||||
* 2: 0000000000000000FFFF0000020310AC:0016
|
||||
*0000000000000000FFFF00009DD8A9C3:A526 01 00000000:00000000 02:000A7214
|
||||
*00000000 0 0 2525 2 c732eca0 201 40 1 2 -1
|
||||
*
|
||||
*/
|
||||
void addtoconninode (char * buffer)
|
||||
{
|
||||
void addtoconninode(char *buffer) {
|
||||
short int sa_family;
|
||||
struct in6_addr result_addr_local;
|
||||
struct in6_addr result_addr_remote;
|
||||
@@ -68,7 +71,8 @@ void addtoconninode (char * buffer)
|
||||
// unsigned long * inode = (unsigned long *) malloc (sizeof(unsigned long));
|
||||
unsigned long inode;
|
||||
|
||||
int matches = sscanf(buffer, "%*d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %*X %*X:%*X %*X:%*X %*X %*d %*d %ld %*512s\n",
|
||||
int matches = sscanf(buffer, "%*d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %*X "
|
||||
"%*X:%*X %*X:%*X %*X %*d %*d %ld %*512s\n",
|
||||
local_addr, &local_port, rem_addr, &rem_port, &inode);
|
||||
|
||||
if (matches != 5) {
|
||||
@@ -82,21 +86,19 @@ void addtoconninode (char * buffer)
|
||||
return;
|
||||
}
|
||||
|
||||
if (strlen(local_addr) > 8)
|
||||
{
|
||||
if (strlen(local_addr) > 8) {
|
||||
/* this is an IPv6-style row */
|
||||
|
||||
/* Demangle what the kernel gives us */
|
||||
sscanf(local_addr, "%08X%08X%08X%08X",
|
||||
&in6_local.s6_addr32[0], &in6_local.s6_addr32[1],
|
||||
&in6_local.s6_addr32[2], &in6_local.s6_addr32[3]);
|
||||
sscanf(rem_addr, "%08X%08X%08X%08X",
|
||||
&in6_remote.s6_addr32[0], &in6_remote.s6_addr32[1],
|
||||
&in6_remote.s6_addr32[2], &in6_remote.s6_addr32[3]);
|
||||
sscanf(local_addr, "%08X%08X%08X%08X", &in6_local.s6_addr32[0],
|
||||
&in6_local.s6_addr32[1], &in6_local.s6_addr32[2],
|
||||
&in6_local.s6_addr32[3]);
|
||||
sscanf(rem_addr, "%08X%08X%08X%08X", &in6_remote.s6_addr32[0],
|
||||
&in6_remote.s6_addr32[1], &in6_remote.s6_addr32[2],
|
||||
&in6_remote.s6_addr32[3]);
|
||||
|
||||
if ((in6_local.s6_addr32[0] == 0x0) && (in6_local.s6_addr32[1] == 0x0)
|
||||
&& (in6_local.s6_addr32[2] == 0xFFFF0000))
|
||||
{
|
||||
if ((in6_local.s6_addr32[0] == 0x0) && (in6_local.s6_addr32[1] == 0x0) &&
|
||||
(in6_local.s6_addr32[2] == 0xFFFF0000)) {
|
||||
/* IPv4-compatible address */
|
||||
result_addr_local = *((struct in6_addr *)&(in6_local.s6_addr32[3]));
|
||||
result_addr_remote = *((struct in6_addr *)&(in6_remote.s6_addr32[3]));
|
||||
@@ -113,9 +115,7 @@ void addtoconninode (char * buffer)
|
||||
result_addr_remote = in6_remote;
|
||||
sa_family = AF_INET6;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* this is an IPv4-style row */
|
||||
sscanf(local_addr, "%X", (unsigned int *)&result_addr_local);
|
||||
sscanf(rem_addr, "%X", (unsigned int *)&result_addr_remote);
|
||||
@@ -128,7 +128,8 @@ void addtoconninode (char * buffer)
|
||||
inet_ntop(sa_family, &result_addr_local, local_string, 49);
|
||||
inet_ntop(sa_family, &result_addr_remote, remote_string, 49);
|
||||
|
||||
snprintf(hashkey, HASHKEYSIZE * sizeof(char), "%s:%d-%s:%d", local_string, local_port, remote_string, rem_port);
|
||||
snprintf(hashkey, HASHKEYSIZE * sizeof(char), "%s:%d-%s:%d", local_string,
|
||||
local_port, remote_string, rem_port);
|
||||
free(local_string);
|
||||
|
||||
// if (DEBUG)
|
||||
@@ -146,7 +147,8 @@ void addtoconninode (char * buffer)
|
||||
current_local_addr != NULL;
|
||||
current_local_addr = current_local_addr->next) {
|
||||
/* TODO maybe only add the ones with the same sa_family */
|
||||
snprintf(hashkey, HASHKEYSIZE * sizeof(char), "%s:%d-%s:%d", current_local_addr->string, local_port, remote_string, rem_port);
|
||||
snprintf(hashkey, HASHKEYSIZE * sizeof(char), "%s:%d-%s:%d",
|
||||
current_local_addr->string, local_port, remote_string, rem_port);
|
||||
conninode[hashkey] = inode;
|
||||
}
|
||||
free(hashkey);
|
||||
@@ -164,8 +166,7 @@ int addprocinfo (const char * filename) {
|
||||
|
||||
fgets(buffer, sizeof(buffer), procinfo);
|
||||
|
||||
do
|
||||
{
|
||||
do {
|
||||
if (fgets(buffer, sizeof(buffer), procinfo))
|
||||
addtoconninode(buffer);
|
||||
} while (!feof(procinfo));
|
||||
@@ -175,11 +176,7 @@ int addprocinfo (const char * filename) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void refreshconninode ()
|
||||
{
|
||||
void refreshconninode() {
|
||||
/* we don't forget old mappings, just overwrite */
|
||||
// delete conninode;
|
||||
// conninode = new HashTable (256);
|
||||
@@ -187,8 +184,7 @@ void refreshconninode ()
|
||||
#if defined(__APPLE__)
|
||||
addprocinfo("net.inet.tcp.pcblist");
|
||||
#else
|
||||
if (! addprocinfo ("/proc/net/tcp"))
|
||||
{
|
||||
if (!addprocinfo("/proc/net/tcp")) {
|
||||
std::cout << "Error: couldn't open /proc/net/tcp\n";
|
||||
exit(0);
|
||||
}
|
||||
@@ -197,5 +193,4 @@ void refreshconninode ()
|
||||
|
||||
// if (DEBUG)
|
||||
// reviewUnknown();
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
// handling the connection->inode mapping
|
||||
|
||||
182
cui.cpp
182
cui.cpp
@@ -15,11 +15,11 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* NetHogs console UI */
|
||||
#include <string>
|
||||
#include <pwd.h>
|
||||
@@ -62,11 +62,10 @@ const char * COLUMN_FORMAT_PID = "%7d";
|
||||
const char *COLUMN_FORMAT_SENT = "%11.3f";
|
||||
const char *COLUMN_FORMAT_RECEIVED = "%11.3f";
|
||||
|
||||
class Line
|
||||
{
|
||||
class Line {
|
||||
public:
|
||||
Line (const char * name, double n_recv_value, double n_sent_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) {
|
||||
assert(pid >= 0);
|
||||
assert(pid <= PID_MAX);
|
||||
m_name = name;
|
||||
@@ -83,6 +82,7 @@ public:
|
||||
|
||||
double sent_value;
|
||||
double recv_value;
|
||||
|
||||
private:
|
||||
const char *m_name;
|
||||
const char *devicename;
|
||||
@@ -92,8 +92,7 @@ private:
|
||||
|
||||
#include <sstream>
|
||||
|
||||
std::string itoa(int i)
|
||||
{
|
||||
std::string itoa(int i) {
|
||||
std::stringstream out;
|
||||
out << i;
|
||||
return out.str();
|
||||
@@ -102,8 +101,7 @@ std::string itoa(int i)
|
||||
/**
|
||||
* @returns the username that corresponds to this uid
|
||||
*/
|
||||
std::string uid2username (uid_t uid)
|
||||
{
|
||||
std::string uid2username(uid_t uid) {
|
||||
struct passwd *pwd = NULL;
|
||||
errno = 0;
|
||||
|
||||
@@ -114,17 +112,21 @@ std::string uid2username (uid_t uid)
|
||||
if (errno == 0)
|
||||
return itoa(uid);
|
||||
else
|
||||
forceExit(false, "Error calling getpwuid(3) for uid %d: %d %s", uid, errno, strerror(errno));
|
||||
forceExit(false, "Error calling getpwuid(3) for uid %d: %d %s", uid,
|
||||
errno, strerror(errno));
|
||||
else
|
||||
return std::string(pwd->pw_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the provided text at the specified location, truncating if the length of the text exceeds a maximum. If the
|
||||
* text must be truncated, the string ".." will be rendered, followed by max_len - 2 characters of the provided text.
|
||||
* Render the provided text at the specified location, truncating if the length
|
||||
* of the text exceeds a maximum. If the
|
||||
* text must be truncated, the string ".." will be rendered, followed by max_len
|
||||
* - 2 characters of the provided text.
|
||||
*/
|
||||
static void mvaddstr_truncate_leading(int row, int col, const char* str, std::size_t str_len, std::size_t max_len)
|
||||
{
|
||||
static void mvaddstr_truncate_leading(int row, int col, const char *str,
|
||||
std::size_t str_len,
|
||||
std::size_t max_len) {
|
||||
if (str_len < max_len) {
|
||||
mvaddstr(row, col, str);
|
||||
} else {
|
||||
@@ -134,11 +136,14 @@ static void mvaddstr_truncate_leading(int row, int col, const char* str, std::si
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the provided text at the specified location, truncating if the length of the text exceeds a maximum. If the
|
||||
* text must be truncated, the text will be rendered up to max_len - 2 characters and then ".." will be rendered.
|
||||
* Render the provided text at the specified location, truncating if the length
|
||||
* of the text exceeds a maximum. If the
|
||||
* text must be truncated, the text will be rendered up to max_len - 2
|
||||
* characters and then ".." will be rendered.
|
||||
*/
|
||||
static void mvaddstr_truncate_trailing(int row, int col, const char* str, std::size_t str_len, std::size_t max_len)
|
||||
{
|
||||
static void mvaddstr_truncate_trailing(int row, int col, const char *str,
|
||||
std::size_t str_len,
|
||||
std::size_t max_len) {
|
||||
if (str_len < max_len) {
|
||||
mvaddstr(row, col, str);
|
||||
} else {
|
||||
@@ -147,8 +152,7 @@ static void mvaddstr_truncate_trailing(int row, int col, const char* str, std::s
|
||||
}
|
||||
}
|
||||
|
||||
void Line::show (int row, unsigned int proglen)
|
||||
{
|
||||
void Line::show(int row, unsigned int proglen) {
|
||||
assert(m_pid >= 0);
|
||||
assert(m_pid <= PID_MAX);
|
||||
|
||||
@@ -158,7 +162,8 @@ void Line::show (int row, unsigned int proglen)
|
||||
const int column_offset_dev = column_offset_program + proglen + 2;
|
||||
const int column_offset_sent = column_offset_dev + COLUMN_WIDTH_DEV + 1;
|
||||
const int column_offset_received = column_offset_sent + COLUMN_WIDTH_SENT + 1;
|
||||
const int column_offset_unit = column_offset_received + COLUMN_WIDTH_RECEIVED + 1;
|
||||
const int column_offset_unit =
|
||||
column_offset_received + COLUMN_WIDTH_RECEIVED + 1;
|
||||
|
||||
// PID column
|
||||
if (m_pid == 0)
|
||||
@@ -167,76 +172,62 @@ void Line::show (int row, unsigned int proglen)
|
||||
mvprintw(row, column_offset_pid, COLUMN_FORMAT_PID, m_pid);
|
||||
|
||||
std::string username = uid2username(m_uid);
|
||||
mvaddstr_truncate_trailing (row, column_offset_user, username.c_str(), username.size(), COLUMN_WIDTH_USER);
|
||||
mvaddstr_truncate_trailing(row, column_offset_user, username.c_str(),
|
||||
username.size(), COLUMN_WIDTH_USER);
|
||||
|
||||
mvaddstr_truncate_leading (row, column_offset_program, m_name, strlen (m_name), proglen);
|
||||
mvaddstr_truncate_leading(row, column_offset_program, m_name, strlen(m_name),
|
||||
proglen);
|
||||
|
||||
mvaddstr(row, column_offset_dev, devicename);
|
||||
|
||||
mvprintw(row, column_offset_sent, COLUMN_FORMAT_SENT, sent_value);
|
||||
|
||||
mvprintw(row, column_offset_received, COLUMN_FORMAT_RECEIVED, recv_value);
|
||||
if (viewMode == VIEWMODE_KBPS)
|
||||
{
|
||||
if (viewMode == VIEWMODE_KBPS) {
|
||||
mvaddstr(row, column_offset_unit, "KB/sec");
|
||||
}
|
||||
else if (viewMode == VIEWMODE_TOTAL_MB)
|
||||
{
|
||||
} else if (viewMode == VIEWMODE_TOTAL_MB) {
|
||||
mvaddstr(row, column_offset_unit, "MB ");
|
||||
}
|
||||
else if (viewMode == VIEWMODE_TOTAL_KB)
|
||||
{
|
||||
} else if (viewMode == VIEWMODE_TOTAL_KB) {
|
||||
mvaddstr(row, column_offset_unit, "KB ");
|
||||
}
|
||||
else if (viewMode == VIEWMODE_TOTAL_B)
|
||||
{
|
||||
} else if (viewMode == VIEWMODE_TOTAL_B) {
|
||||
mvaddstr(row, column_offset_unit, "B ");
|
||||
}
|
||||
}
|
||||
|
||||
void Line::log() {
|
||||
std::cout << m_name << '/' << m_pid << '/' << m_uid << "\t" << sent_value << "\t" << recv_value << std::endl;
|
||||
std::cout << m_name << '/' << m_pid << '/' << m_uid << "\t" << sent_value
|
||||
<< "\t" << recv_value << std::endl;
|
||||
}
|
||||
|
||||
int GreatestFirst (const void * ma, const void * mb)
|
||||
{
|
||||
int GreatestFirst(const void *ma, const void *mb) {
|
||||
Line **pa = (Line **)ma;
|
||||
Line **pb = (Line **)mb;
|
||||
Line *a = *pa;
|
||||
Line *b = *pb;
|
||||
double aValue;
|
||||
if (sortRecv)
|
||||
{
|
||||
if (sortRecv) {
|
||||
aValue = a->recv_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
aValue = a->sent_value;
|
||||
}
|
||||
|
||||
double bValue;
|
||||
if (sortRecv)
|
||||
{
|
||||
if (sortRecv) {
|
||||
bValue = b->recv_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
bValue = b->sent_value;
|
||||
}
|
||||
|
||||
if (aValue > bValue)
|
||||
{
|
||||
if (aValue > bValue) {
|
||||
return -1;
|
||||
}
|
||||
if (aValue == bValue)
|
||||
{
|
||||
if (aValue == bValue) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void init_ui ()
|
||||
{
|
||||
void init_ui() {
|
||||
WINDOW *screen = initscr();
|
||||
raw();
|
||||
noecho();
|
||||
@@ -247,15 +238,13 @@ void init_ui ()
|
||||
// caption->append(", running at ");
|
||||
}
|
||||
|
||||
void exit_ui ()
|
||||
{
|
||||
void exit_ui() {
|
||||
clear();
|
||||
endwin();
|
||||
delete caption;
|
||||
}
|
||||
|
||||
void ui_tick ()
|
||||
{
|
||||
void ui_tick() {
|
||||
switch (getch()) {
|
||||
case 'q':
|
||||
/* quit */
|
||||
@@ -280,8 +269,7 @@ void show_trace(Line * lines[], int nproc) {
|
||||
std::cout << "\nRefreshing:\n";
|
||||
|
||||
/* print them */
|
||||
for (int i=0; i<nproc; i++)
|
||||
{
|
||||
for (int i = 0; i < nproc; i++) {
|
||||
lines[i]->log();
|
||||
delete lines[i];
|
||||
}
|
||||
@@ -289,8 +277,9 @@ void show_trace(Line * lines[], int nproc) {
|
||||
/* print the 'unknown' connections, for debugging */
|
||||
ConnList *curr_unknownconn = unknowntcp->connections;
|
||||
while (curr_unknownconn != NULL) {
|
||||
std::cout << "Unknown connection: " <<
|
||||
curr_unknownconn->getVal()->refpacket->gethashstring() << std::endl;
|
||||
std::cout << "Unknown connection: "
|
||||
<< curr_unknownconn->getVal()->refpacket->gethashstring()
|
||||
<< std::endl;
|
||||
|
||||
curr_unknownconn = curr_unknownconn->getNext();
|
||||
}
|
||||
@@ -308,24 +297,27 @@ void show_ncurses(Line * lines[], int nproc) {
|
||||
|
||||
if (cols < 62) {
|
||||
clear();
|
||||
mvprintw(0,0, "The terminal is too narrow! Please make it wider.\nI'll wait...");
|
||||
mvprintw(0, 0,
|
||||
"The terminal is too narrow! Please make it wider.\nI'll wait...");
|
||||
return;
|
||||
}
|
||||
|
||||
if (cols > PROGNAME_WIDTH) cols = PROGNAME_WIDTH;
|
||||
if (cols > PROGNAME_WIDTH)
|
||||
cols = PROGNAME_WIDTH;
|
||||
|
||||
proglen = cols - 55;
|
||||
|
||||
clear();
|
||||
mvprintw(0, 0, "%s", caption->c_str());
|
||||
attron(A_REVERSE);
|
||||
mvprintw (2, 0, " PID USER %-*.*s DEV SENT RECEIVED ", proglen, proglen, "PROGRAM");
|
||||
mvprintw(2, 0,
|
||||
" PID USER %-*.*s DEV SENT RECEIVED ",
|
||||
proglen, proglen, "PROGRAM");
|
||||
attroff(A_REVERSE);
|
||||
|
||||
/* print them */
|
||||
int i;
|
||||
for (i=0; i<nproc; i++)
|
||||
{
|
||||
for (i = 0; i < nproc; i++) {
|
||||
if (i + 3 < rows)
|
||||
lines[i]->show(i + 3, proglen);
|
||||
recv_global += lines[i]->recv_value;
|
||||
@@ -335,9 +327,9 @@ void show_ncurses(Line * lines[], int nproc) {
|
||||
|
||||
attron(A_REVERSE);
|
||||
int totalrow = std::min(rows - 1, 3 + 1 + i);
|
||||
mvprintw (totalrow, 0, " TOTAL %-*.*s %11.3f %11.3f ", proglen, proglen, " ", sent_global, recv_global);
|
||||
if (viewMode == VIEWMODE_KBPS)
|
||||
{
|
||||
mvprintw(totalrow, 0, " TOTAL %-*.*s %11.3f %11.3f ",
|
||||
proglen, proglen, " ", sent_global, recv_global);
|
||||
if (viewMode == VIEWMODE_KBPS) {
|
||||
mvprintw(3 + 1 + i, cols - COLUMN_WIDTH_UNIT, "KB/sec ");
|
||||
} else if (viewMode == VIEWMODE_TOTAL_B) {
|
||||
mvprintw(3 + 1 + i, cols - COLUMN_WIDTH_UNIT, "B ");
|
||||
@@ -352,8 +344,7 @@ void show_ncurses(Line * lines[], int nproc) {
|
||||
}
|
||||
|
||||
// Display all processes and relevant network traffic using show function
|
||||
void do_refresh()
|
||||
{
|
||||
void do_refresh() {
|
||||
refreshconninode();
|
||||
refreshcount++;
|
||||
|
||||
@@ -370,8 +361,7 @@ void do_refresh()
|
||||
lines[i] = NULL;
|
||||
#endif
|
||||
|
||||
while (curproc != NULL)
|
||||
{
|
||||
while (curproc != NULL) {
|
||||
// walk though its connections, summing up their data, and
|
||||
// throwing away connections that haven't received a package
|
||||
// in the last PROCESSTIMEOUT seconds.
|
||||
@@ -379,18 +369,17 @@ void do_refresh()
|
||||
assert(curproc->getVal() != NULL);
|
||||
assert(nproc == processes->size());
|
||||
|
||||
/* remove timed-out processes (unless it's one of the the unknown process) */
|
||||
if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <= curtime.tv_sec)
|
||||
&& (curproc->getVal() != unknowntcp)
|
||||
&& (curproc->getVal() != unknownudp)
|
||||
&& (curproc->getVal() != unknownip))
|
||||
{
|
||||
/* remove timed-out processes (unless it's one of the the unknown process)
|
||||
*/
|
||||
if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <=
|
||||
curtime.tv_sec) &&
|
||||
(curproc->getVal() != unknowntcp) &&
|
||||
(curproc->getVal() != unknownudp) && (curproc->getVal() != unknownip)) {
|
||||
if (DEBUG)
|
||||
std::cout << "PROC: Deleting process\n";
|
||||
ProcList *todelete = curproc;
|
||||
Process *p_todelete = curproc->getVal();
|
||||
if (previousproc)
|
||||
{
|
||||
if (previousproc) {
|
||||
previousproc->next = curproc->next;
|
||||
curproc = curproc->next;
|
||||
} else {
|
||||
@@ -401,42 +390,31 @@ void do_refresh()
|
||||
delete p_todelete;
|
||||
nproc--;
|
||||
// continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// add a non-timed-out process to the list of stuff to show
|
||||
float value_sent = 0,
|
||||
value_recv = 0;
|
||||
float value_sent = 0, value_recv = 0;
|
||||
|
||||
if (viewMode == VIEWMODE_KBPS)
|
||||
{
|
||||
if (viewMode == VIEWMODE_KBPS) {
|
||||
// std::cout << "kbps viemode" << std::endl;
|
||||
curproc->getVal()->getkbps(&value_recv, &value_sent);
|
||||
}
|
||||
else if (viewMode == VIEWMODE_TOTAL_KB)
|
||||
{
|
||||
} else if (viewMode == VIEWMODE_TOTAL_KB) {
|
||||
// std::cout << "total viemode" << std::endl;
|
||||
curproc->getVal()->gettotalkb(&value_recv, &value_sent);
|
||||
}
|
||||
else if (viewMode == VIEWMODE_TOTAL_MB)
|
||||
{
|
||||
} else if (viewMode == VIEWMODE_TOTAL_MB) {
|
||||
// std::cout << "total viemode" << std::endl;
|
||||
curproc->getVal()->gettotalmb(&value_recv, &value_sent);
|
||||
}
|
||||
else if (viewMode == VIEWMODE_TOTAL_B)
|
||||
{
|
||||
} else if (viewMode == VIEWMODE_TOTAL_B) {
|
||||
// std::cout << "total viemode" << std::endl;
|
||||
curproc->getVal()->gettotalb(&value_recv, &value_sent);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
forceExit(false, "Invalid viewMode: %d", viewMode);
|
||||
}
|
||||
uid_t uid = curproc->getVal()->getUid();
|
||||
assert(curproc->getVal()->pid >= 0);
|
||||
assert(n < nproc);
|
||||
|
||||
lines[n] = new Line (curproc->getVal()->name, value_recv, value_sent,
|
||||
lines[n] =
|
||||
new Line(curproc->getVal()->name, value_recv, value_sent,
|
||||
curproc->getVal()->pid, uid, curproc->getVal()->devicename);
|
||||
previousproc = curproc;
|
||||
curproc = curproc->next;
|
||||
|
||||
3
cui.h
3
cui.h
@@ -15,7 +15,8 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
124
decpcap.c
124
decpcap.c
@@ -15,11 +15,11 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
@@ -34,14 +34,13 @@
|
||||
|
||||
/* functions to set up a handle (which is basically just a pcap handle) */
|
||||
|
||||
struct dp_handle * dp_fillhandle(pcap_t * phandle)
|
||||
{
|
||||
struct dp_handle * retval = (struct dp_handle *) malloc (sizeof (struct dp_handle));
|
||||
struct dp_handle *dp_fillhandle(pcap_t *phandle) {
|
||||
struct dp_handle *retval =
|
||||
(struct dp_handle *)malloc(sizeof(struct dp_handle));
|
||||
int i;
|
||||
retval->pcap_handle = phandle;
|
||||
|
||||
for (i = 0; i < dp_n_packet_types; i++)
|
||||
{
|
||||
for (i = 0; i < dp_n_packet_types; i++) {
|
||||
retval->callback[i] = NULL;
|
||||
}
|
||||
|
||||
@@ -66,24 +65,21 @@ struct dp_handle * dp_fillhandle(pcap_t * phandle)
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct dp_handle * dp_open_offline(char * fname, char * ebuf)
|
||||
{
|
||||
struct dp_handle *dp_open_offline(char *fname, char *ebuf) {
|
||||
pcap_t *temp = pcap_open_offline(fname, ebuf);
|
||||
|
||||
if (temp == NULL)
|
||||
{
|
||||
if (temp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dp_fillhandle(temp);
|
||||
}
|
||||
|
||||
struct dp_handle * dp_open_live(const char * device, int snaplen, int promisc, int to_ms, char * errbuf)
|
||||
{
|
||||
struct dp_handle *dp_open_live(const char *device, int snaplen, int promisc,
|
||||
int to_ms, char *errbuf) {
|
||||
pcap_t *temp = pcap_open_live(device, snaplen, promisc, to_ms, errbuf);
|
||||
|
||||
if (temp == NULL)
|
||||
{
|
||||
if (temp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -92,46 +88,42 @@ struct dp_handle * dp_open_live(const char * device, int snaplen, int promisc, i
|
||||
|
||||
/* functions to add callbacks */
|
||||
|
||||
void dp_addcb (struct dp_handle * handle, enum dp_packet_type type, dp_callback callback)
|
||||
{
|
||||
void dp_addcb(struct dp_handle *handle, enum dp_packet_type type,
|
||||
dp_callback callback) {
|
||||
handle->callback[type] = callback;
|
||||
}
|
||||
|
||||
/* functions for parsing the payloads */
|
||||
|
||||
void dp_parse_tcp (struct dp_handle * handle, const dp_header * header, const u_char * packet)
|
||||
{
|
||||
void dp_parse_tcp(struct dp_handle *handle, const dp_header *header,
|
||||
const u_char *packet) {
|
||||
// const struct tcphdr * tcp = (struct tcphdr *) packet;
|
||||
// u_char * payload = (u_char *) packet + sizeof (struct tcphdr);
|
||||
|
||||
if (handle->callback[dp_packet_tcp] != NULL)
|
||||
{
|
||||
int done = (handle->callback[dp_packet_tcp])
|
||||
(handle->userdata, header, packet);
|
||||
if (handle->callback[dp_packet_tcp] != NULL) {
|
||||
int done =
|
||||
(handle->callback[dp_packet_tcp])(handle->userdata, header, packet);
|
||||
if (done)
|
||||
return;
|
||||
}
|
||||
// TODO: maybe `pass on' payload to lower-level protocol parsing
|
||||
}
|
||||
|
||||
void dp_parse_ip (struct dp_handle * handle, const dp_header * header, const u_char * packet)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
int done = (handle->callback[dp_packet_ip])
|
||||
(handle->userdata, header, packet);
|
||||
if (handle->callback[dp_packet_ip] != NULL) {
|
||||
int done =
|
||||
(handle->callback[dp_packet_ip])(handle->userdata, header, packet);
|
||||
if (done)
|
||||
return;
|
||||
}
|
||||
switch (ip->ip_p)
|
||||
{
|
||||
switch (ip->ip_p) {
|
||||
case IPPROTO_TCP:
|
||||
dp_parse_tcp(handle, header, payload);
|
||||
break;
|
||||
@@ -141,20 +133,18 @@ void dp_parse_ip (struct dp_handle * handle, const dp_header * header, const u_c
|
||||
}
|
||||
}
|
||||
|
||||
void dp_parse_ip6 (struct dp_handle * handle, const dp_header * header, const u_char * packet)
|
||||
{
|
||||
void dp_parse_ip6(struct dp_handle *handle, const dp_header *header,
|
||||
const u_char *packet) {
|
||||
const struct ip6_hdr *ip6 = (struct ip6_hdr *)packet;
|
||||
u_char *payload = (u_char *)packet + sizeof(struct ip6_hdr);
|
||||
|
||||
if (handle->callback[dp_packet_ip6] != NULL)
|
||||
{
|
||||
int done = (handle->callback[dp_packet_ip6])
|
||||
(handle->userdata, header, packet);
|
||||
if (handle->callback[dp_packet_ip6] != NULL) {
|
||||
int done =
|
||||
(handle->callback[dp_packet_ip6])(handle->userdata, header, packet);
|
||||
if (done)
|
||||
return;
|
||||
}
|
||||
switch ((ip6->ip6_ctlun).ip6_un1.ip6_un1_nxt)
|
||||
{
|
||||
switch ((ip6->ip6_ctlun).ip6_un1.ip6_un1_nxt) {
|
||||
case IPPROTO_TCP:
|
||||
dp_parse_tcp(handle, header, payload);
|
||||
break;
|
||||
@@ -164,17 +154,16 @@ void dp_parse_ip6 (struct dp_handle * handle, const dp_header * header, const u_
|
||||
}
|
||||
}
|
||||
|
||||
void dp_parse_ethernet (struct dp_handle * handle, const dp_header * header, const u_char * packet)
|
||||
{
|
||||
void dp_parse_ethernet(struct dp_handle *handle, const dp_header *header,
|
||||
const u_char *packet) {
|
||||
const struct ether_header *ethernet = (struct ether_header *)packet;
|
||||
u_char *payload = (u_char *)packet + sizeof(struct ether_header);
|
||||
u_int16_t protocol = 0;
|
||||
|
||||
/* call handle if it exists */
|
||||
if (handle->callback[dp_packet_ethernet] != NULL)
|
||||
{
|
||||
int done = (handle->callback[dp_packet_ethernet])
|
||||
(handle->userdata, header, packet);
|
||||
if (handle->callback[dp_packet_ethernet] != NULL) {
|
||||
int done = (handle->callback[dp_packet_ethernet])(handle->userdata, header,
|
||||
packet);
|
||||
|
||||
/* return if handle decides we're done */
|
||||
if (done)
|
||||
@@ -183,8 +172,7 @@ void dp_parse_ethernet (struct dp_handle * handle, const dp_header * header, con
|
||||
|
||||
/* parse payload */
|
||||
protocol = ntohs(ethernet->ether_type);
|
||||
switch (protocol)
|
||||
{
|
||||
switch (protocol) {
|
||||
case ETHERTYPE_IP:
|
||||
dp_parse_ip(handle, header, payload);
|
||||
break;
|
||||
@@ -212,17 +200,16 @@ struct ppp_header {
|
||||
u_int16_t packettype;
|
||||
};
|
||||
|
||||
void dp_parse_ppp (struct dp_handle * handle, const dp_header * header, const u_char * packet)
|
||||
{
|
||||
void dp_parse_ppp(struct dp_handle *handle, const dp_header *header,
|
||||
const u_char *packet) {
|
||||
const struct ppp_header *ppp = (struct ppp_header *)packet;
|
||||
u_char *payload = (u_char *)packet + sizeof(struct ppp_header);
|
||||
u_int16_t protocol = 0;
|
||||
|
||||
/* call handle if it exists */
|
||||
if (handle->callback[dp_packet_ppp] != NULL)
|
||||
{
|
||||
int done = (handle->callback[dp_packet_ppp])
|
||||
(handle->userdata, header, packet);
|
||||
if (handle->callback[dp_packet_ppp] != NULL) {
|
||||
int done =
|
||||
(handle->callback[dp_packet_ppp])(handle->userdata, header, packet);
|
||||
|
||||
/* return if handle decides we're done */
|
||||
if (done)
|
||||
@@ -231,8 +218,7 @@ void dp_parse_ppp (struct dp_handle * handle, const dp_header * header, const u_
|
||||
|
||||
/* parse payload */
|
||||
protocol = ntohs(ppp->packettype);
|
||||
switch (protocol)
|
||||
{
|
||||
switch (protocol) {
|
||||
case ETHERTYPE_IP:
|
||||
dp_parse_ip(handle, header, payload);
|
||||
break;
|
||||
@@ -256,17 +242,16 @@ struct sll_header {
|
||||
u_int16_t sll_protocol; /* protocol */
|
||||
};
|
||||
|
||||
void dp_parse_linux_cooked (struct dp_handle * handle, const dp_header * header, const u_char * packet)
|
||||
{
|
||||
void dp_parse_linux_cooked(struct dp_handle *handle, const dp_header *header,
|
||||
const u_char *packet) {
|
||||
const struct sll_header *sll = (struct sll_header *)packet;
|
||||
u_char *payload = (u_char *)packet + sizeof(struct sll_header);
|
||||
u_int16_t protocol = 0;
|
||||
|
||||
/* call handle if it exists */
|
||||
if (handle->callback[dp_packet_sll] != NULL)
|
||||
{
|
||||
int done = (handle->callback[dp_packet_sll])
|
||||
(handle->userdata, header, packet);
|
||||
if (handle->callback[dp_packet_sll] != NULL) {
|
||||
int done =
|
||||
(handle->callback[dp_packet_sll])(handle->userdata, header, packet);
|
||||
|
||||
/* return if handle decides we're done */
|
||||
if (done)
|
||||
@@ -275,8 +260,7 @@ void dp_parse_linux_cooked (struct dp_handle * handle, const dp_header * header,
|
||||
|
||||
/* parse payload */
|
||||
protocol = ntohs(sll->sll_protocol);
|
||||
switch (protocol)
|
||||
{
|
||||
switch (protocol) {
|
||||
case ETHERTYPE_IP:
|
||||
dp_parse_ip(handle, header, payload);
|
||||
break;
|
||||
@@ -290,8 +274,8 @@ void dp_parse_linux_cooked (struct dp_handle * handle, const dp_header * header,
|
||||
}
|
||||
|
||||
/* functions to do the monitoring */
|
||||
void dp_pcap_callback (u_char * u_handle, const struct pcap_pkthdr * header, const u_char * packet)
|
||||
{
|
||||
void dp_pcap_callback(u_char *u_handle, const struct pcap_pkthdr *header,
|
||||
const u_char *packet) {
|
||||
struct dp_handle *handle = (struct dp_handle *)u_handle;
|
||||
struct dp_header;
|
||||
|
||||
@@ -324,14 +308,14 @@ void dp_pcap_callback (u_char * u_handle, const struct pcap_pkthdr * header, con
|
||||
int dp_dispatch(struct dp_handle *handle, int count, u_char *user, int size) {
|
||||
handle->userdata = user;
|
||||
handle->userdata_size = size;
|
||||
return pcap_dispatch (handle->pcap_handle, count, dp_pcap_callback, (u_char *)handle);
|
||||
return pcap_dispatch(handle->pcap_handle, count, dp_pcap_callback,
|
||||
(u_char *)handle);
|
||||
}
|
||||
|
||||
int dp_setnonblock(struct dp_handle *handle, int i, char *errbuf) {
|
||||
return pcap_setnonblock(handle->pcap_handle, i, errbuf);
|
||||
}
|
||||
|
||||
char * dp_geterr (struct dp_handle * handle)
|
||||
{
|
||||
char *dp_geterr(struct dp_handle *handle) {
|
||||
return pcap_geterr(handle->pcap_handle);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __DECPCAP_H
|
||||
@@ -63,12 +64,14 @@ struct dp_handle {
|
||||
|
||||
/* functions to set up a handle (which is basically just a pcap handle) */
|
||||
|
||||
struct dp_handle * dp_open_live(const char * device, int snaplen, int promisc, int to_ms, char * errbuf);
|
||||
struct dp_handle *dp_open_live(const char *device, int snaplen, int promisc,
|
||||
int to_ms, char *errbuf);
|
||||
struct dp_handle *dp_open_offline(char *fname, char *ebuf);
|
||||
|
||||
/* functions to add callbacks */
|
||||
|
||||
void dp_addcb (struct dp_handle * handle, enum dp_packet_type type, dp_callback callback);
|
||||
void dp_addcb(struct dp_handle *handle, enum dp_packet_type type,
|
||||
dp_callback callback);
|
||||
|
||||
/* functions to parse payloads */
|
||||
|
||||
|
||||
@@ -15,26 +15,25 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
extern "C" {
|
||||
#include "decpcap.h"
|
||||
}
|
||||
|
||||
int process_tcp (u_char * /* userdata */, const dp_header * /* header */, const u_char * /* m_packet */) {
|
||||
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)
|
||||
{
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
std::cout << "Please, enter a filename" << std::endl;
|
||||
}
|
||||
|
||||
@@ -43,8 +42,7 @@ int main (int argc, char ** argv)
|
||||
dp_handle *newhandle = dp_open_offline(argv[1], errbuf);
|
||||
dp_addcb(newhandle, dp_packet_tcp, process_tcp);
|
||||
int ret = dp_dispatch(newhandle, -1, NULL, 0);
|
||||
if (ret == -1)
|
||||
{
|
||||
if (ret == -1) {
|
||||
std::cout << "Error dispatching: " << dp_geterr(newhandle);
|
||||
}
|
||||
}
|
||||
|
||||
25
devices.cpp
25
devices.cpp
@@ -15,7 +15,8 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -40,8 +41,7 @@ bool selected(int devc, char** devicenames, char* devicename) {
|
||||
}
|
||||
|
||||
bool already_seen(device *devices, char *devicename) {
|
||||
for (class device* current_device = devices;
|
||||
current_device != NULL;
|
||||
for (class device *current_device = devices; current_device != NULL;
|
||||
current_device = current_device->next) {
|
||||
if (strcmp(current_device->name, devicename) == 0)
|
||||
return true;
|
||||
@@ -52,29 +52,26 @@ bool already_seen(device* devices, char* devicename) {
|
||||
// The interface is up, not a loopback and running?
|
||||
bool up_running(int ifa_flags) {
|
||||
std::cout << "up: " << (ifa_flags & IFF_UP) << std::endl;
|
||||
return !(ifa_flags & IFF_LOOPBACK) &&
|
||||
(ifa_flags & IFF_UP) &&
|
||||
return !(ifa_flags & IFF_LOOPBACK) && (ifa_flags & IFF_UP) &&
|
||||
(ifa_flags & IFF_RUNNING);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function can return null, if no good interface is found
|
||||
* When 'all' is set to 'false', the function avoids loopback interface and down/not running interfaces
|
||||
* When 'all' is set to 'false', the function avoids loopback interface and
|
||||
* down/not running interfaces
|
||||
*/
|
||||
device * get_devices(int devc, char** devicenames, bool all)
|
||||
{
|
||||
device *get_devices(int devc, char **devicenames, bool all) {
|
||||
struct ifaddrs *ifaddr, *ifa;
|
||||
|
||||
if (getifaddrs(&ifaddr) == -1)
|
||||
{
|
||||
if (getifaddrs(&ifaddr) == -1) {
|
||||
std::cerr << "Fail to get interface addresses" << std::endl;
|
||||
// perror("getifaddrs");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device *devices = NULL;
|
||||
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
|
||||
{
|
||||
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr == NULL)
|
||||
continue;
|
||||
if (!selected(devc, devicenames, ifa->ifa_name))
|
||||
@@ -91,6 +88,4 @@ device * get_devices(int devc, char** devicenames, bool all)
|
||||
return devices;
|
||||
}
|
||||
|
||||
device * get_default_devices() {
|
||||
return get_devices(0, NULL, false);
|
||||
}
|
||||
device *get_default_devices() { return get_devices(0, NULL, false); }
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -26,9 +27,9 @@
|
||||
|
||||
class device {
|
||||
public:
|
||||
device (const char * m_name, device * m_next = NULL)
|
||||
{
|
||||
name = m_name; next = m_next;
|
||||
device(const char *m_name, device *m_next = NULL) {
|
||||
name = m_name;
|
||||
next = m_next;
|
||||
}
|
||||
const char *name;
|
||||
device *next;
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
@@ -42,7 +42,8 @@ extern bool bughuntmode;
|
||||
// Not sure, but assuming there's no more PID's than go into 64 unsigned bits..
|
||||
const int MAX_PID_LENGTH = 20;
|
||||
|
||||
// Max length of filenames in /proc/<pid>/fd/*. These are numeric, so 10 digits seems like a safe assumption.
|
||||
// Max length of filenames in /proc/<pid>/fd/*. These are numeric, so 10 digits
|
||||
// seems like a safe assumption.
|
||||
const int MAX_FDLINK = 10;
|
||||
|
||||
/* maps from inode to program-struct */
|
||||
@@ -98,7 +99,8 @@ static std::string read_file (const char* filepath) {
|
||||
int fd = open(filepath, O_RDONLY);
|
||||
|
||||
if (fd < 0) {
|
||||
std::fprintf(stderr, "Error opening %s: %s\n", filepath, std::strerror(errno));
|
||||
std::fprintf(stderr, "Error opening %s: %s\n", filepath,
|
||||
std::strerror(errno));
|
||||
std::exit(3);
|
||||
return NULL;
|
||||
}
|
||||
@@ -106,7 +108,8 @@ static std::string read_file (const char* filepath) {
|
||||
std::string contents = read_file(fd);
|
||||
|
||||
if (close(fd)) {
|
||||
std::fprintf(stderr, "Error opening %s: %s\n", filepath, std::strerror(errno));
|
||||
std::fprintf(stderr, "Error opening %s: %s\n", filepath,
|
||||
std::strerror(errno));
|
||||
std::exit(34);
|
||||
}
|
||||
|
||||
@@ -153,11 +156,10 @@ void get_info_for_pid(const char * pid) {
|
||||
|
||||
DIR *dir = opendir(dirname);
|
||||
|
||||
if (!dir)
|
||||
{
|
||||
if (bughuntmode)
|
||||
{
|
||||
std::cout << "Couldn't open dir " << dirname << ": " << strerror(errno) << "\n";
|
||||
if (!dir) {
|
||||
if (bughuntmode) {
|
||||
std::cout << "Couldn't open dir " << dirname << ": " << strerror(errno)
|
||||
<< "\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -178,8 +180,7 @@ void get_info_for_pid(const char * pid) {
|
||||
int linklen = 80;
|
||||
char linkname[linklen];
|
||||
int usedlen = readlink(fromname, linkname, linklen - 1);
|
||||
if (usedlen == -1)
|
||||
{
|
||||
if (usedlen == -1) {
|
||||
continue;
|
||||
}
|
||||
assert(usedlen < linklen);
|
||||
@@ -202,24 +203,23 @@ void reread_mapping () {
|
||||
dirent *entry;
|
||||
|
||||
while ((entry = readdir(proc))) {
|
||||
if (entry->d_type != DT_DIR) continue;
|
||||
if (entry->d_type != DT_DIR)
|
||||
continue;
|
||||
|
||||
if (! is_number (entry->d_name)) continue;
|
||||
if (!is_number(entry->d_name))
|
||||
continue;
|
||||
|
||||
get_info_for_pid(entry->d_name);
|
||||
}
|
||||
closedir(proc);
|
||||
}
|
||||
|
||||
struct prg_node * findPID (unsigned long inode)
|
||||
{
|
||||
struct prg_node *findPID(unsigned long inode) {
|
||||
/* we first look in inodeproc */
|
||||
struct prg_node *node = inodeproc[inode];
|
||||
|
||||
if (node != NULL)
|
||||
{
|
||||
if (bughuntmode)
|
||||
{
|
||||
if (node != NULL) {
|
||||
if (bughuntmode) {
|
||||
std::cout << ":) Found pid in inodeproc table" << std::endl;
|
||||
}
|
||||
return node;
|
||||
@@ -230,14 +230,10 @@ struct prg_node * findPID (unsigned long inode)
|
||||
#endif
|
||||
|
||||
struct prg_node *retval = inodeproc[inode];
|
||||
if (bughuntmode)
|
||||
{
|
||||
if (retval == NULL)
|
||||
{
|
||||
if (bughuntmode) {
|
||||
if (retval == NULL) {
|
||||
std::cout << ":( No pid after inodeproc refresh" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::cout << ":) Found pid after inodeproc refresh" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
#ifndef __INODE2PROG_h
|
||||
|
||||
178
libnethogs.cpp
178
libnethogs.cpp
@@ -1,5 +1,4 @@
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#include "libnethogs.h"
|
||||
}
|
||||
|
||||
@@ -36,8 +35,7 @@ static bool pc_loop_use_select = true;
|
||||
|
||||
static handle *handles = NULL;
|
||||
|
||||
static std::pair<int, int> create_self_pipe()
|
||||
{
|
||||
static std::pair<int, int> create_self_pipe() {
|
||||
int pfd[2];
|
||||
if (pipe(pfd) == -1)
|
||||
return std::make_pair(-1, -1);
|
||||
@@ -51,43 +49,34 @@ static std::pair<int, int> create_self_pipe()
|
||||
return std::make_pair(pfd[0], pfd[1]);
|
||||
}
|
||||
|
||||
static bool wait_for_next_trigger()
|
||||
{
|
||||
if( pc_loop_use_select )
|
||||
{
|
||||
static bool wait_for_next_trigger() {
|
||||
if (pc_loop_use_select) {
|
||||
FD_ZERO(&pc_loop_fd_set);
|
||||
int nfds = 0;
|
||||
for (std::vector<int>::const_iterator it = pc_loop_fd_list.begin();
|
||||
it != pc_loop_fd_list.end(); ++it)
|
||||
{
|
||||
it != pc_loop_fd_list.end(); ++it) {
|
||||
int const fd = *it;
|
||||
nfds = std::max(nfds, *it + 1);
|
||||
FD_SET(fd, &pc_loop_fd_set);
|
||||
}
|
||||
timeval timeout = {monitor_refresh_delay, 0};
|
||||
if( select(nfds, &pc_loop_fd_set, 0, 0, &timeout) != -1 )
|
||||
{
|
||||
if( FD_ISSET(self_pipe.first, &pc_loop_fd_set) )
|
||||
{
|
||||
if (select(nfds, &pc_loop_fd_set, 0, 0, &timeout) != -1) {
|
||||
if (FD_ISSET(self_pipe.first, &pc_loop_fd_set)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// If select() not possible, pause to prevent 100%
|
||||
usleep(1000);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int nethogsmonitor_init()
|
||||
{
|
||||
static int nethogsmonitor_init() {
|
||||
process_init();
|
||||
|
||||
device *devices = get_default_devices();
|
||||
if ( devices == NULL )
|
||||
{
|
||||
if (devices == NULL) {
|
||||
std::cerr << "No devices to monitor" << std::endl;
|
||||
return NETHOGS_STATUS_NO_DEVICE;
|
||||
}
|
||||
@@ -99,21 +88,20 @@ static int nethogsmonitor_init()
|
||||
int nb_devices = 0;
|
||||
int nb_failed_devices = 0;
|
||||
|
||||
while (current_dev != NULL)
|
||||
{
|
||||
while (current_dev != NULL) {
|
||||
++nb_devices;
|
||||
|
||||
if( !getLocal(current_dev->name, false) )
|
||||
{
|
||||
std::cerr << "getifaddrs failed while establishing local IP." << std::endl;
|
||||
if (!getLocal(current_dev->name, false)) {
|
||||
std::cerr << "getifaddrs failed while establishing local IP."
|
||||
<< std::endl;
|
||||
++nb_failed_devices;
|
||||
continue;
|
||||
}
|
||||
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
dp_handle * newhandle = dp_open_live(current_dev->name, BUFSIZ, promiscuous, 100, errbuf);
|
||||
if (newhandle != NULL)
|
||||
{
|
||||
dp_handle *newhandle =
|
||||
dp_open_live(current_dev->name, BUFSIZ, promiscuous, 100, errbuf);
|
||||
if (newhandle != NULL) {
|
||||
dp_addcb(newhandle, dp_packet_ip, process_ip);
|
||||
dp_addcb(newhandle, dp_packet_ip6, process_ip6);
|
||||
dp_addcb(newhandle, dp_packet_tcp, process_tcp);
|
||||
@@ -125,53 +113,43 @@ static int nethogsmonitor_init()
|
||||
* update: version 0.7.2, which is in debian stable now, should be ok
|
||||
* also.
|
||||
*/
|
||||
if (dp_setnonblock (newhandle, 1, errbuf) == -1)
|
||||
{
|
||||
if (dp_setnonblock(newhandle, 1, errbuf) == -1) {
|
||||
fprintf(stderr, "Error putting libpcap in nonblocking mode\n");
|
||||
}
|
||||
handles = new handle(newhandle, current_dev->name, handles);
|
||||
|
||||
if( pc_loop_use_select )
|
||||
{
|
||||
if (pc_loop_use_select) {
|
||||
// some devices may not support pcap_get_selectable_fd
|
||||
int const fd = pcap_get_selectable_fd(newhandle->pcap_handle);
|
||||
if( fd != -1 )
|
||||
{
|
||||
if (fd != -1) {
|
||||
pc_loop_fd_list.push_back(fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
pc_loop_use_select = false;
|
||||
pc_loop_fd_list.clear();
|
||||
fprintf(stderr, "failed to get selectable_fd for %s\n", current_dev->name);
|
||||
fprintf(stderr, "failed to get selectable_fd for %s\n",
|
||||
current_dev->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "ERROR: opening handler for device %s: %s\n", current_dev->name, strerror(errno));
|
||||
} else {
|
||||
fprintf(stderr, "ERROR: opening handler for device %s: %s\n",
|
||||
current_dev->name, strerror(errno));
|
||||
++nb_failed_devices;
|
||||
}
|
||||
|
||||
current_dev = current_dev->next;
|
||||
}
|
||||
|
||||
if(nb_devices == nb_failed_devices)
|
||||
{
|
||||
if (nb_devices == nb_failed_devices) {
|
||||
return NETHOGS_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
// use the Self-Pipe trick to interrupt the select() in the main loop
|
||||
if( pc_loop_use_select )
|
||||
{
|
||||
if (pc_loop_use_select) {
|
||||
self_pipe = create_self_pipe();
|
||||
if( self_pipe.first == -1 || self_pipe.second == -1 )
|
||||
{
|
||||
if (self_pipe.first == -1 || self_pipe.second == -1) {
|
||||
std::cerr << "Error creating pipe file descriptors\n";
|
||||
pc_loop_use_select = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
pc_loop_fd_list.push_back(self_pipe.first);
|
||||
}
|
||||
}
|
||||
@@ -179,8 +157,7 @@ static int nethogsmonitor_init()
|
||||
return NETHOGS_STATUS_OK;
|
||||
}
|
||||
|
||||
static void nethogsmonitor_handle_update(NethogsMonitorCallback cb)
|
||||
{
|
||||
static void nethogsmonitor_handle_update(NethogsMonitorCallback cb) {
|
||||
refreshconninode();
|
||||
refreshcount++;
|
||||
|
||||
@@ -188,8 +165,7 @@ static void nethogsmonitor_handle_update(NethogsMonitorCallback cb)
|
||||
ProcList *previousproc = NULL;
|
||||
int nproc = processes->size();
|
||||
|
||||
while (curproc != NULL)
|
||||
{
|
||||
while (curproc != NULL) {
|
||||
// walk though its connections, summing up their data, and
|
||||
// throwing away connections that haven't received a package
|
||||
// in the last PROCESSTIMEOUT seconds.
|
||||
@@ -197,18 +173,17 @@ static void nethogsmonitor_handle_update(NethogsMonitorCallback cb)
|
||||
assert(curproc->getVal() != NULL);
|
||||
assert(nproc == processes->size());
|
||||
|
||||
/* remove timed-out processes (unless it's one of the the unknown process) */
|
||||
if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <= curtime.tv_sec)
|
||||
&& (curproc->getVal() != unknowntcp)
|
||||
&& (curproc->getVal() != unknownudp)
|
||||
&& (curproc->getVal() != unknownip))
|
||||
{
|
||||
/* remove timed-out processes (unless it's one of the the unknown process)
|
||||
*/
|
||||
if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <=
|
||||
curtime.tv_sec) &&
|
||||
(curproc->getVal() != unknowntcp) &&
|
||||
(curproc->getVal() != unknownudp) && (curproc->getVal() != unknownip)) {
|
||||
if (DEBUG)
|
||||
std::cout << "PROC: Deleting process\n";
|
||||
|
||||
NethogsRecordMap::iterator it = monitor_record_map.find(curproc);
|
||||
if( it != monitor_record_map.end() )
|
||||
{
|
||||
if (it != monitor_record_map.end()) {
|
||||
NethogsMonitorRecord &data = it->second;
|
||||
(*cb)(NETHOGS_APP_ACTION_REMOVE, &data);
|
||||
monitor_record_map.erase(curproc);
|
||||
@@ -216,12 +191,10 @@ static void nethogsmonitor_handle_update(NethogsMonitorCallback cb)
|
||||
|
||||
ProcList *todelete = curproc;
|
||||
Process *p_todelete = curproc->getVal();
|
||||
if (previousproc)
|
||||
{
|
||||
if (previousproc) {
|
||||
previousproc->next = curproc->next;
|
||||
curproc = curproc->next;
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
processes = curproc->getNext();
|
||||
curproc = processes;
|
||||
}
|
||||
@@ -229,9 +202,7 @@ static void nethogsmonitor_handle_update(NethogsMonitorCallback cb)
|
||||
delete p_todelete;
|
||||
nproc--;
|
||||
// continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
const u_int32_t uid = curproc->getVal()->getUid();
|
||||
u_int32_t sent_bytes;
|
||||
u_int32_t recv_bytes;
|
||||
@@ -241,12 +212,12 @@ static void nethogsmonitor_handle_update(NethogsMonitorCallback cb)
|
||||
curproc->getVal()->gettotal(&recv_bytes, &sent_bytes);
|
||||
|
||||
// notify update
|
||||
bool const new_data = (monitor_record_map.find(curproc) == monitor_record_map.end());
|
||||
bool const new_data =
|
||||
(monitor_record_map.find(curproc) == monitor_record_map.end());
|
||||
NethogsMonitorRecord &data = monitor_record_map[curproc];
|
||||
|
||||
bool data_change = false;
|
||||
if( new_data )
|
||||
{
|
||||
if (new_data) {
|
||||
data_change = true;
|
||||
static int record_id = 0;
|
||||
++record_id;
|
||||
@@ -258,7 +229,11 @@ static void nethogsmonitor_handle_update(NethogsMonitorCallback cb)
|
||||
|
||||
data.device_name = curproc->getVal()->devicename;
|
||||
|
||||
#define NHM_UPDATE_ONE_FIELD(TO,FROM) if((TO)!=(FROM)) { TO = FROM; data_change = true; }
|
||||
#define NHM_UPDATE_ONE_FIELD(TO, FROM) \
|
||||
if ((TO) != (FROM)) { \
|
||||
TO = FROM; \
|
||||
data_change = true; \
|
||||
}
|
||||
|
||||
NHM_UPDATE_ONE_FIELD(data.uid, uid)
|
||||
NHM_UPDATE_ONE_FIELD(data.sent_bytes, sent_bytes)
|
||||
@@ -268,8 +243,7 @@ static void nethogsmonitor_handle_update(NethogsMonitorCallback cb)
|
||||
|
||||
#undef NHM_UPDATE_ONE_FIELD
|
||||
|
||||
if( data_change )
|
||||
{
|
||||
if (data_change) {
|
||||
(*cb)(NETHOGS_APP_ACTION_SET, &data);
|
||||
}
|
||||
|
||||
@@ -280,36 +254,30 @@ static void nethogsmonitor_handle_update(NethogsMonitorCallback cb)
|
||||
}
|
||||
}
|
||||
|
||||
static void nethogsmonitor_clean_up()
|
||||
{
|
||||
static void nethogsmonitor_clean_up() {
|
||||
// clean up
|
||||
handle *current_handle = handles;
|
||||
while (current_handle != NULL)
|
||||
{
|
||||
while (current_handle != NULL) {
|
||||
pcap_close(current_handle->content->pcap_handle);
|
||||
current_handle = current_handle->next;
|
||||
}
|
||||
|
||||
// close file descriptors
|
||||
for (std::vector<int>::const_iterator it = pc_loop_fd_list.begin();
|
||||
it != pc_loop_fd_list.end(); ++it)
|
||||
{
|
||||
it != pc_loop_fd_list.end(); ++it) {
|
||||
close(*it);
|
||||
}
|
||||
|
||||
procclean();
|
||||
}
|
||||
|
||||
int nethogsmonitor_loop(NethogsMonitorCallback cb)
|
||||
{
|
||||
if( monitor_run_flag )
|
||||
{
|
||||
int nethogsmonitor_loop(NethogsMonitorCallback cb) {
|
||||
if (monitor_run_flag) {
|
||||
return NETHOGS_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
int return_value = nethogsmonitor_init();
|
||||
if( return_value != NETHOGS_STATUS_OK )
|
||||
{
|
||||
if (return_value != NETHOGS_STATUS_OK) {
|
||||
return return_value;
|
||||
}
|
||||
|
||||
@@ -318,42 +286,33 @@ int nethogsmonitor_loop(NethogsMonitorCallback cb)
|
||||
struct dpargs *userdata = (dpargs *)malloc(sizeof(struct dpargs));
|
||||
|
||||
// Main loop
|
||||
while (monitor_run_flag)
|
||||
{
|
||||
while (monitor_run_flag) {
|
||||
bool packets_read = false;
|
||||
|
||||
handle *current_handle = handles;
|
||||
while (current_handle != NULL)
|
||||
{
|
||||
while (current_handle != NULL) {
|
||||
userdata->device = current_handle->devicename;
|
||||
userdata->sa_family = AF_UNSPEC;
|
||||
int retval = dp_dispatch (current_handle->content, -1, (u_char *)userdata, sizeof (struct dpargs));
|
||||
if (retval < 0)
|
||||
{
|
||||
int retval = dp_dispatch(current_handle->content, -1, (u_char *)userdata,
|
||||
sizeof(struct dpargs));
|
||||
if (retval < 0) {
|
||||
std::cerr << "Error dispatching: " << retval << std::endl;
|
||||
}
|
||||
else if (retval != 0)
|
||||
{
|
||||
} else if (retval != 0) {
|
||||
packets_read = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
gettimeofday(&curtime, NULL);
|
||||
}
|
||||
current_handle = current_handle->next;
|
||||
}
|
||||
|
||||
time_t const now = ::time(NULL);
|
||||
if( monitor_last_refresh_time + monitor_refresh_delay <= now )
|
||||
{
|
||||
if (monitor_last_refresh_time + monitor_refresh_delay <= now) {
|
||||
monitor_last_refresh_time = now;
|
||||
nethogsmonitor_handle_update(cb);
|
||||
}
|
||||
|
||||
if (!packets_read)
|
||||
{
|
||||
if( !wait_for_next_trigger() )
|
||||
{
|
||||
if (!packets_read) {
|
||||
if (!wait_for_next_trigger()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -364,8 +323,7 @@ int nethogsmonitor_loop(NethogsMonitorCallback cb)
|
||||
return NETHOGS_STATUS_OK;
|
||||
}
|
||||
|
||||
void nethogsmonitor_breakloop()
|
||||
{
|
||||
void nethogsmonitor_breakloop() {
|
||||
monitor_run_flag = false;
|
||||
write(self_pipe.second, "x", 1);
|
||||
}
|
||||
|
||||
25
libnethogs.h
25
libnethogs.h
@@ -18,8 +18,7 @@ extern "C" {
|
||||
#define NETHOGS_STATUS_FAILURE 1 // generic error
|
||||
#define NETHOGS_STATUS_NO_DEVICE 2 // no device foundr
|
||||
|
||||
typedef struct NethogsMonitorRecord
|
||||
{
|
||||
typedef struct NethogsMonitorRecord {
|
||||
int record_id;
|
||||
const char *name;
|
||||
int pid;
|
||||
@@ -31,23 +30,29 @@ typedef struct NethogsMonitorRecord
|
||||
float recv_kbs;
|
||||
} NethogsMonitorRecord;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Defines a callback to handle updates about applications
|
||||
* @param action NETHOGS_APP_ACTION_SET if data is beeing added or updated,
|
||||
* NETHOGS_APP_ACTION_REMOVE if data is beeing removed.
|
||||
* the record_id member is used to uniquely identify the data beeing update or removed.
|
||||
* @param data a pointer to an application usage data. the pointer remains valid until
|
||||
* the callback is called with NETHOGS_APP_ACTION_REMOVE for the same pointer.
|
||||
* the user should not modify the content of the structure pointed by data.
|
||||
* the record_id member is used to uniquely identify the data beeing
|
||||
* update or removed.
|
||||
* @param data a pointer to an application usage data. the pointer remains valid
|
||||
* until
|
||||
* the callback is called with NETHOGS_APP_ACTION_REMOVE for the same
|
||||
* pointer.
|
||||
* the user should not modify the content of the structure pointed by
|
||||
* data.
|
||||
*/
|
||||
typedef void(*NethogsMonitorCallback)(int action, NethogsMonitorRecord const* data);
|
||||
typedef void (*NethogsMonitorCallback)(int action,
|
||||
NethogsMonitorRecord const *data);
|
||||
|
||||
/**
|
||||
* @brief Enter the process monitoring loop and reports updates using the
|
||||
* callback provided as parameter.
|
||||
* This call will block until nethogsmonitor_breakloop() is called or a failure occurs.
|
||||
* @param cb A pointer to a callback function following the NethogsMonitorCallback definition
|
||||
* This call will block until nethogsmonitor_breakloop() is called or a failure
|
||||
* occurs.
|
||||
* @param cb A pointer to a callback function following the
|
||||
* NethogsMonitorCallback definition
|
||||
*/
|
||||
|
||||
NETHOGS_DSO_VISIBLE int nethogsmonitor_loop(NethogsMonitorCallback cb);
|
||||
|
||||
135
main.cpp
135
main.cpp
@@ -11,30 +11,31 @@ static fd_set pc_loop_fd_set;
|
||||
static std::vector<int> pc_loop_fd_list;
|
||||
static bool pc_loop_use_select = true;
|
||||
|
||||
static void versiondisplay(void) { std::cout << version << "\n"; }
|
||||
|
||||
static void versiondisplay(void)
|
||||
{
|
||||
std::cout << version << "\n";
|
||||
}
|
||||
|
||||
static void help(bool iserror)
|
||||
{
|
||||
static void help(bool iserror) {
|
||||
std::ostream &output = (iserror ? std::cerr : std::cout);
|
||||
|
||||
//output << "usage: nethogs [-V] [-b] [-d seconds] [-t] [-p] [-f (eth|ppp))] [device [device [device ...]]]\n";
|
||||
output << "usage: nethogs [-V] [-h] [-b] [-d seconds] [-v mode] [-c count] [-t] [-p] [-s] [device [device [device ...]]]\n";
|
||||
// output << "usage: nethogs [-V] [-b] [-d seconds] [-t] [-p] [-f (eth|ppp))]
|
||||
// [device [device [device ...]]]\n";
|
||||
output << "usage: nethogs [-V] [-h] [-b] [-d seconds] [-v mode] [-c count] "
|
||||
"[-t] [-p] [-s] [device [device [device ...]]]\n";
|
||||
output << " -V : prints version.\n";
|
||||
output << " -h : prints this help.\n";
|
||||
output << " -b : bughunt mode - implies tracemode.\n";
|
||||
output << " -d : delay for update refresh rate in seconds. default is 1.\n";
|
||||
output << " -v : view mode (0 = KB/s, 1 = total KB, 2 = total B, 3 = total MB). default is 0.\n";
|
||||
output << " -d : delay for update refresh rate in seconds. default "
|
||||
"is 1.\n";
|
||||
output << " -v : view mode (0 = KB/s, 1 = total KB, 2 = total B, 3 "
|
||||
"= total MB). default is 0.\n";
|
||||
output << " -c : number of updates. default is 0 (unlimited).\n";
|
||||
output << " -t : tracemode.\n";
|
||||
//output << " -f : format of packets on interface, default is eth.\n";
|
||||
// output << " -f : format of packets on interface, default is
|
||||
// eth.\n";
|
||||
output << " -p : sniff in promiscious mode (not recommended).\n";
|
||||
output << " -s : sort output by sent column.\n";
|
||||
output << " -a : monitor all devices, even loopback/stopped ones.\n";
|
||||
output << " device : device(s) to monitor. default is all interfaces up and running excluding loopback\n";
|
||||
output << " device : device(s) to monitor. default is all "
|
||||
"interfaces up and running excluding loopback\n";
|
||||
output << std::endl;
|
||||
output << "When nethogs is running, press:\n";
|
||||
output << " q: quit\n";
|
||||
@@ -43,21 +44,15 @@ static void help(bool iserror)
|
||||
output << " m: switch between total (KB, B, MB) and KB/s mode\n";
|
||||
}
|
||||
|
||||
|
||||
void quit_cb (int /* i */)
|
||||
{
|
||||
if( self_pipe.second != -1 )
|
||||
{
|
||||
void quit_cb(int /* i */) {
|
||||
if (self_pipe.second != -1) {
|
||||
write(self_pipe.second, "x", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void forceExit(bool success, const char *msg, ...)
|
||||
{
|
||||
void forceExit(bool success, const char *msg, ...) {
|
||||
if ((!tracemode) && (!DEBUG)) {
|
||||
exit_ui();
|
||||
}
|
||||
@@ -74,8 +69,7 @@ void forceExit(bool success, const char *msg, ...)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
std::pair<int, int> create_self_pipe()
|
||||
{
|
||||
std::pair<int, int> create_self_pipe() {
|
||||
int pfd[2];
|
||||
if (pipe(pfd) == -1)
|
||||
return std::make_pair(-1, -1);
|
||||
@@ -89,43 +83,33 @@ std::pair<int, int> create_self_pipe()
|
||||
return std::make_pair(pfd[0], pfd[1]);
|
||||
}
|
||||
|
||||
bool wait_for_next_trigger()
|
||||
{
|
||||
if( pc_loop_use_select )
|
||||
{
|
||||
bool wait_for_next_trigger() {
|
||||
if (pc_loop_use_select) {
|
||||
FD_ZERO(&pc_loop_fd_set);
|
||||
int nfds = 0;
|
||||
for (std::vector<int>::const_iterator it = pc_loop_fd_list.begin();
|
||||
it != pc_loop_fd_list.end(); ++it)
|
||||
{
|
||||
it != pc_loop_fd_list.end(); ++it) {
|
||||
int const fd = *it;
|
||||
nfds = std::max(nfds, *it + 1);
|
||||
FD_SET(fd, &pc_loop_fd_set);
|
||||
}
|
||||
timeval timeout = {refreshdelay, 0};
|
||||
if( select(nfds, &pc_loop_fd_set, 0, 0, &timeout) != -1 )
|
||||
{
|
||||
if( FD_ISSET(self_pipe.first, &pc_loop_fd_set) )
|
||||
{
|
||||
if (select(nfds, &pc_loop_fd_set, 0, 0, &timeout) != -1) {
|
||||
if (FD_ISSET(self_pipe.first, &pc_loop_fd_set)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// If select() not possible, pause to prevent 100%
|
||||
usleep(1000);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void clean_up()
|
||||
{
|
||||
void clean_up() {
|
||||
// close file descriptors
|
||||
for (std::vector<int>::const_iterator it = pc_loop_fd_list.begin();
|
||||
it != pc_loop_fd_list.end(); ++it)
|
||||
{
|
||||
it != pc_loop_fd_list.end(); ++it) {
|
||||
close(*it);
|
||||
}
|
||||
|
||||
@@ -134,8 +118,7 @@ void clean_up()
|
||||
exit_ui();
|
||||
}
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
int main(int argc, char **argv) {
|
||||
process_init();
|
||||
|
||||
int promisc = 0;
|
||||
@@ -183,7 +166,8 @@ int main (int argc, char** argv)
|
||||
|
||||
device *devices = get_devices(argc - optind, argv + optind, all);
|
||||
if (devices == NULL)
|
||||
forceExit(false, "No devices to monitor. Use '-a' to allow monitoring loopback interfaces or devices that are not up/running");
|
||||
forceExit(false, "No devices to monitor. Use '-a' to allow monitoring "
|
||||
"loopback interfaces or devices that are not up/running");
|
||||
|
||||
if ((!tracemode) && (!DEBUG)) {
|
||||
init_ui();
|
||||
@@ -194,12 +178,9 @@ int main (int argc, char** argv)
|
||||
|
||||
// use the Self-Pipe trick to interrupt the select() in the main loop
|
||||
self_pipe = create_self_pipe();
|
||||
if( self_pipe.first == -1 || self_pipe.second == -1 )
|
||||
{
|
||||
if (self_pipe.first == -1 || self_pipe.second == -1) {
|
||||
forceExit(false, "Error creating pipe file descriptors\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// add the self-pipe to allow interrupting select()
|
||||
pc_loop_fd_list.push_back(self_pipe.first);
|
||||
}
|
||||
@@ -210,14 +191,13 @@ int main (int argc, char** argv)
|
||||
device *current_dev = devices;
|
||||
while (current_dev != NULL) {
|
||||
|
||||
if( !getLocal(current_dev->name, tracemode) )
|
||||
{
|
||||
if (!getLocal(current_dev->name, tracemode)) {
|
||||
forceExit(false, "getifaddrs failed while establishing local IP.");
|
||||
}
|
||||
|
||||
dp_handle * newhandle = dp_open_live(current_dev->name, BUFSIZ, promisc, 100, errbuf);
|
||||
if (newhandle != NULL)
|
||||
{
|
||||
dp_handle *newhandle =
|
||||
dp_open_live(current_dev->name, BUFSIZ, promisc, 100, errbuf);
|
||||
if (newhandle != NULL) {
|
||||
dp_addcb(newhandle, dp_packet_ip, process_ip);
|
||||
dp_addcb(newhandle, dp_packet_ip6, process_ip6);
|
||||
dp_addcb(newhandle, dp_packet_tcp, process_tcp);
|
||||
@@ -229,31 +209,26 @@ int main (int argc, char** argv)
|
||||
* update: version 0.7.2, which is in debian stable now, should be ok
|
||||
* also.
|
||||
*/
|
||||
if (dp_setnonblock (newhandle, 1, errbuf) == -1)
|
||||
{
|
||||
if (dp_setnonblock(newhandle, 1, errbuf) == -1) {
|
||||
fprintf(stderr, "Error putting libpcap in nonblocking mode\n");
|
||||
}
|
||||
handles = new handle(newhandle, current_dev->name, handles);
|
||||
|
||||
if( pc_loop_use_select )
|
||||
{
|
||||
if (pc_loop_use_select) {
|
||||
// some devices may not support pcap_get_selectable_fd
|
||||
int const fd = pcap_get_selectable_fd(newhandle->pcap_handle);
|
||||
if( fd != -1 )
|
||||
{
|
||||
if (fd != -1) {
|
||||
pc_loop_fd_list.push_back(fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
pc_loop_use_select = false;
|
||||
pc_loop_fd_list.clear();
|
||||
fprintf(stderr, "failed to get selectable_fd for %s\n", current_dev->name);
|
||||
fprintf(stderr, "failed to get selectable_fd for %s\n",
|
||||
current_dev->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Error opening handler for device %s\n", current_dev->name);
|
||||
} else {
|
||||
fprintf(stderr, "Error opening handler for device %s\n",
|
||||
current_dev->name);
|
||||
}
|
||||
|
||||
current_dev = current_dev->next;
|
||||
@@ -261,19 +236,21 @@ int main (int argc, char** argv)
|
||||
|
||||
signal(SIGINT, &quit_cb);
|
||||
|
||||
fprintf(stderr, "Waiting for first packet to arrive (see sourceforge.net bug 1019381)\n");
|
||||
fprintf(
|
||||
stderr,
|
||||
"Waiting for first packet to arrive (see sourceforge.net bug 1019381)\n");
|
||||
struct dpargs *userdata = (dpargs *)malloc(sizeof(struct dpargs));
|
||||
|
||||
// Main loop:
|
||||
while (1)
|
||||
{
|
||||
while (1) {
|
||||
bool packets_read = false;
|
||||
|
||||
for (handle * current_handle = handles; current_handle != NULL; current_handle = current_handle->next)
|
||||
{
|
||||
for (handle *current_handle = handles; current_handle != NULL;
|
||||
current_handle = current_handle->next) {
|
||||
userdata->device = current_handle->devicename;
|
||||
userdata->sa_family = AF_UNSPEC;
|
||||
int retval = 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 < 0)
|
||||
std::cerr << "Error dispatching: " << retval << std::endl;
|
||||
else if (retval != 0)
|
||||
@@ -281,11 +258,9 @@ int main (int argc, char** argv)
|
||||
}
|
||||
|
||||
time_t const now = ::time(NULL);
|
||||
if( last_refresh_time + refreshdelay <= now )
|
||||
{
|
||||
if (last_refresh_time + refreshdelay <= now) {
|
||||
last_refresh_time = now;
|
||||
if ((!DEBUG)&&(!tracemode))
|
||||
{
|
||||
if ((!DEBUG) && (!tracemode)) {
|
||||
// handle user input
|
||||
ui_tick();
|
||||
}
|
||||
|
||||
75
nethogs.cpp
75
nethogs.cpp
@@ -15,7 +15,8 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -65,8 +66,7 @@ const char version[] = " version " VERSION "." SUBVERSION "." MINORVERSION;
|
||||
timeval curtime;
|
||||
|
||||
bool local_addr::contains(const in_addr_t &n_addr) {
|
||||
if ((sa_family == AF_INET)
|
||||
&& (n_addr == addr))
|
||||
if ((sa_family == AF_INET) && (n_addr == addr))
|
||||
return true;
|
||||
if (next == NULL)
|
||||
return false;
|
||||
@@ -74,8 +74,7 @@ bool local_addr::contains (const in_addr_t & n_addr) {
|
||||
}
|
||||
|
||||
bool local_addr::contains(const struct in6_addr &n_addr) {
|
||||
if (sa_family == AF_INET6)
|
||||
{
|
||||
if (sa_family == AF_INET6) {
|
||||
/*
|
||||
if (DEBUG) {
|
||||
char addy [50];
|
||||
@@ -87,8 +86,7 @@ bool local_addr::contains(const struct in6_addr & n_addr) {
|
||||
}
|
||||
*/
|
||||
// if (addr6.s6_addr == n_addr.s6_addr)
|
||||
if (memcmp (&addr6, &n_addr, sizeof(struct in6_addr)) == 0)
|
||||
{
|
||||
if (memcmp(&addr6, &n_addr, sizeof(struct in6_addr)) == 0) {
|
||||
if (DEBUG)
|
||||
std::cerr << "Match!" << std::endl;
|
||||
return true;
|
||||
@@ -108,12 +106,10 @@ struct dpargs {
|
||||
in6_addr ip6_dst;
|
||||
};
|
||||
|
||||
const char* getVersion()
|
||||
{
|
||||
return version;
|
||||
}
|
||||
const char *getVersion() { return version; }
|
||||
|
||||
int process_tcp (u_char * userdata, const dp_header * header, const u_char * m_packet) {
|
||||
int process_tcp(u_char *userdata, const dp_header *header,
|
||||
const u_char *m_packet) {
|
||||
struct dpargs *args = (struct dpargs *)userdata;
|
||||
struct tcphdr *tcp = (struct tcphdr *)m_packet;
|
||||
|
||||
@@ -121,31 +117,34 @@ int process_tcp (u_char * userdata, const dp_header * header, const u_char * m_p
|
||||
|
||||
/* get info from userdata, then call getPacket */
|
||||
Packet *packet;
|
||||
switch (args->sa_family)
|
||||
{
|
||||
switch (args->sa_family) {
|
||||
case AF_INET:
|
||||
#ifdef __APPLE__
|
||||
packet = new Packet (args->ip_src, ntohs(tcp->th_sport), args->ip_dst, ntohs(tcp->th_dport), header->len, header->ts);
|
||||
packet = new Packet(args->ip_src, ntohs(tcp->th_sport), args->ip_dst,
|
||||
ntohs(tcp->th_dport), header->len, header->ts);
|
||||
#else
|
||||
packet = new Packet (args->ip_src, ntohs(tcp->source), args->ip_dst, ntohs(tcp->dest), header->len, header->ts);
|
||||
packet = new Packet(args->ip_src, ntohs(tcp->source), args->ip_dst,
|
||||
ntohs(tcp->dest), header->len, header->ts);
|
||||
#endif
|
||||
break;
|
||||
case AF_INET6:
|
||||
#ifdef __APPLE__
|
||||
packet = new Packet (args->ip6_src, ntohs(tcp->th_sport), args->ip6_dst, ntohs(tcp->th_dport), header->len, header->ts);
|
||||
packet = new Packet(args->ip6_src, ntohs(tcp->th_sport), args->ip6_dst,
|
||||
ntohs(tcp->th_dport), header->len, header->ts);
|
||||
#else
|
||||
packet = new Packet (args->ip6_src, ntohs(tcp->source), args->ip6_dst, ntohs(tcp->dest), header->len, header->ts);
|
||||
packet = new Packet(args->ip6_src, ntohs(tcp->source), args->ip6_dst,
|
||||
ntohs(tcp->dest), header->len, header->ts);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Invalid address family for TCP packet: " << args->sa_family << std::endl;
|
||||
std::cerr << "Invalid address family for TCP packet: " << args->sa_family
|
||||
<< std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
Connection *connection = findConnection(packet);
|
||||
|
||||
if (connection != NULL)
|
||||
{
|
||||
if (connection != NULL) {
|
||||
/* add packet to the connection */
|
||||
connection->add(packet);
|
||||
} else {
|
||||
@@ -159,31 +158,36 @@ int process_tcp (u_char * userdata, const dp_header * header, const u_char * m_p
|
||||
return true;
|
||||
}
|
||||
|
||||
int process_udp (u_char * userdata, const dp_header * header, const u_char * m_packet) {
|
||||
int process_udp(u_char *userdata, const dp_header *header,
|
||||
const u_char *m_packet) {
|
||||
struct dpargs *args = (struct dpargs *)userdata;
|
||||
struct udphdr *udp = (struct udphdr *)m_packet;
|
||||
|
||||
curtime = header->ts;
|
||||
|
||||
Packet *packet;
|
||||
switch (args->sa_family)
|
||||
{
|
||||
switch (args->sa_family) {
|
||||
case AF_INET:
|
||||
#ifdef __APPLE__
|
||||
packet = new Packet (args->ip_src, ntohs(udp->uh_sport), args->ip_dst, ntohs(udp->uh_dport), header->len, header->ts);
|
||||
packet = new Packet(args->ip_src, ntohs(udp->uh_sport), args->ip_dst,
|
||||
ntohs(udp->uh_dport), header->len, header->ts);
|
||||
#else
|
||||
packet = new Packet (args->ip_src, ntohs(udp->source), args->ip_dst, ntohs(udp->dest), header->len, header->ts);
|
||||
packet = new Packet(args->ip_src, ntohs(udp->source), args->ip_dst,
|
||||
ntohs(udp->dest), header->len, header->ts);
|
||||
#endif
|
||||
break;
|
||||
case AF_INET6:
|
||||
#ifdef __APPLE__
|
||||
packet = new Packet (args->ip6_src, ntohs(udp->uh_sport), args->ip6_dst, ntohs(udp->uh_dport), header->len, header->ts);
|
||||
packet = new Packet(args->ip6_src, ntohs(udp->uh_sport), args->ip6_dst,
|
||||
ntohs(udp->uh_dport), header->len, header->ts);
|
||||
#else
|
||||
packet = new Packet (args->ip6_src, ntohs(udp->source), args->ip6_dst, ntohs(udp->dest), header->len, header->ts);
|
||||
packet = new Packet(args->ip6_src, ntohs(udp->source), args->ip6_dst,
|
||||
ntohs(udp->dest), header->len, header->ts);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Invalid address family for UDP packet: " << args->sa_family << std::endl;
|
||||
std::cerr << "Invalid address family for UDP packet: " << args->sa_family
|
||||
<< std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -192,8 +196,7 @@ int process_udp (u_char * userdata, const dp_header * header, const u_char * m_p
|
||||
|
||||
Connection *connection = findConnection(packet);
|
||||
|
||||
if (connection != NULL)
|
||||
{
|
||||
if (connection != NULL) {
|
||||
/* add packet to the connection */
|
||||
connection->add(packet);
|
||||
} else {
|
||||
@@ -207,7 +210,8 @@ int process_udp (u_char * userdata, const dp_header * header, const u_char * m_p
|
||||
return true;
|
||||
}
|
||||
|
||||
int process_ip (u_char * userdata, const dp_header * /* header */, const u_char * m_packet) {
|
||||
int process_ip(u_char *userdata, const dp_header * /* header */,
|
||||
const u_char *m_packet) {
|
||||
struct dpargs *args = (struct dpargs *)userdata;
|
||||
struct ip *ip = (struct ip *)m_packet;
|
||||
args->sa_family = AF_INET;
|
||||
@@ -218,7 +222,8 @@ int process_ip (u_char * userdata, const dp_header * /* header */, const u_char
|
||||
return false;
|
||||
}
|
||||
|
||||
int process_ip6 (u_char * userdata, const dp_header * /* header */, const u_char * m_packet) {
|
||||
int process_ip6(u_char *userdata, const dp_header * /* header */,
|
||||
const u_char *m_packet) {
|
||||
struct dpargs *args = (struct dpargs *)userdata;
|
||||
const struct ip6_hdr *ip6 = (struct ip6_hdr *)m_packet;
|
||||
args->sa_family = AF_INET6;
|
||||
@@ -233,7 +238,9 @@ class handle {
|
||||
public:
|
||||
handle(dp_handle *m_handle, const char *m_devicename = NULL,
|
||||
handle *m_next = NULL) {
|
||||
content = m_handle; next = m_next; devicename = m_devicename;
|
||||
content = m_handle;
|
||||
next = m_next;
|
||||
devicename = m_devicename;
|
||||
}
|
||||
dp_handle *content;
|
||||
const char *devicename;
|
||||
|
||||
12
nethogs.h
12
nethogs.h
@@ -15,11 +15,11 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __NETHOGS_H
|
||||
#define __NETHOGS_H
|
||||
|
||||
@@ -81,8 +81,7 @@ void forceExit(bool success, const char *msg, ...) NORETURN;
|
||||
class local_addr {
|
||||
public:
|
||||
/* ipv4 constructor takes an in_addr_t */
|
||||
local_addr (in_addr_t m_addr, local_addr * m_next = NULL)
|
||||
{
|
||||
local_addr(in_addr_t m_addr, local_addr *m_next = NULL) {
|
||||
addr = m_addr;
|
||||
next = m_next;
|
||||
sa_family = AF_INET;
|
||||
@@ -90,8 +89,7 @@ public:
|
||||
inet_ntop(AF_INET, &m_addr, string, 15);
|
||||
}
|
||||
/* this constructor takes an char address[33] */
|
||||
local_addr (struct in6_addr *m_addr, local_addr * m_next = NULL)
|
||||
{
|
||||
local_addr(struct in6_addr *m_addr, local_addr *m_next = NULL) {
|
||||
addr6 = *m_addr;
|
||||
next = m_next;
|
||||
sa_family = AF_INET6;
|
||||
@@ -103,8 +101,8 @@ public:
|
||||
bool contains(const struct in6_addr &n_addr);
|
||||
char *string;
|
||||
local_addr *next;
|
||||
private:
|
||||
|
||||
private:
|
||||
in_addr_t addr;
|
||||
struct in6_addr addr6;
|
||||
short int sa_family;
|
||||
|
||||
84
packet.cpp
84
packet.cpp
@@ -15,11 +15,11 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "nethogs.h"
|
||||
#include <iostream>
|
||||
#include "packet.h"
|
||||
@@ -48,8 +48,7 @@ local_addr * local_addrs = NULL;
|
||||
* uses getifaddrs to get addresses of this device, and adds them to the
|
||||
* local_addrs-list.
|
||||
*/
|
||||
bool getLocal (const char *device, bool tracemode)
|
||||
{
|
||||
bool getLocal(const char *device, bool tracemode) {
|
||||
struct ifaddrs *ifaddr, *ifa;
|
||||
if (getifaddrs(&ifaddr) == -1) {
|
||||
return false;
|
||||
@@ -130,21 +129,31 @@ struct tcp_hdr {
|
||||
u_short th_sum; /* checksum */
|
||||
u_short th_urp; /* urgent pointer */
|
||||
};
|
||||
Packet::Packet (in_addr m_sip, unsigned short m_sport, in_addr m_dip, unsigned short m_dport, u_int32_t m_len, timeval m_time, direction m_dir)
|
||||
{
|
||||
sip = m_sip; sport = m_sport;
|
||||
dip = m_dip; dport = m_dport;
|
||||
len = m_len; time = m_time;
|
||||
dir = m_dir; sa_family = AF_INET;
|
||||
Packet::Packet(in_addr m_sip, unsigned short m_sport, in_addr m_dip,
|
||||
unsigned short m_dport, u_int32_t m_len, timeval m_time,
|
||||
direction m_dir) {
|
||||
sip = m_sip;
|
||||
sport = m_sport;
|
||||
dip = m_dip;
|
||||
dport = m_dport;
|
||||
len = m_len;
|
||||
time = m_time;
|
||||
dir = m_dir;
|
||||
sa_family = AF_INET;
|
||||
hashstring = NULL;
|
||||
}
|
||||
|
||||
Packet::Packet (in6_addr m_sip, unsigned short m_sport, in6_addr m_dip, unsigned short m_dport, u_int32_t m_len, timeval m_time, direction m_dir)
|
||||
{
|
||||
sip6 = m_sip; sport = m_sport;
|
||||
dip6 = m_dip; dport = m_dport;
|
||||
len = m_len; time = m_time;
|
||||
dir = m_dir; sa_family = AF_INET6;
|
||||
Packet::Packet(in6_addr m_sip, unsigned short m_sport, in6_addr m_dip,
|
||||
unsigned short m_dport, u_int32_t m_len, timeval m_time,
|
||||
direction m_dir) {
|
||||
sip6 = m_sip;
|
||||
sport = m_sport;
|
||||
dip6 = m_dip;
|
||||
dport = m_dport;
|
||||
len = m_len;
|
||||
time = m_time;
|
||||
dir = m_dir;
|
||||
sa_family = AF_INET6;
|
||||
hashstring = NULL;
|
||||
}
|
||||
|
||||
@@ -166,13 +175,17 @@ Packet * Packet::newInverted () {
|
||||
return new Packet(dip6, dport, sip6, sport, len, time, new_direction);
|
||||
}
|
||||
|
||||
/* constructs returns a new Packet() structure with the same contents as this one */
|
||||
/* constructs returns a new Packet() structure with the same contents as this
|
||||
* one */
|
||||
Packet::Packet(const Packet &old_packet) {
|
||||
sip = old_packet.sip; sport = old_packet.sport;
|
||||
sip = old_packet.sip;
|
||||
sport = old_packet.sport;
|
||||
sip6 = old_packet.sip6;
|
||||
dip6 = old_packet.dip6;
|
||||
dip = old_packet.dip; dport = old_packet.dport;
|
||||
len = old_packet.len; time = old_packet.time;
|
||||
dip = old_packet.dip;
|
||||
dport = old_packet.dport;
|
||||
len = old_packet.len;
|
||||
time = old_packet.time;
|
||||
sa_family = old_packet.sa_family;
|
||||
if (old_packet.hashstring == NULL)
|
||||
hashstring = NULL;
|
||||
@@ -181,8 +194,7 @@ Packet::Packet (const Packet &old_packet) {
|
||||
dir = old_packet.dir;
|
||||
}
|
||||
|
||||
bool sameinaddr(in_addr one, in_addr other)
|
||||
{
|
||||
bool sameinaddr(in_addr one, in_addr other) {
|
||||
return one.s_addr == other.s_addr;
|
||||
}
|
||||
|
||||
@@ -234,13 +246,12 @@ bool Packet::Outgoing () {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* returns the packet in '1.2.3.4:5-1.2.3.4:5'-form, for use in the 'conninode' table */
|
||||
/* returns the packet in '1.2.3.4:5-1.2.3.4:5'-form, for use in the 'conninode'
|
||||
* table */
|
||||
/* '1.2.3.4' should be the local address. */
|
||||
/* the calling code should take care of deletion of the hash string */
|
||||
char * Packet::gethashstring ()
|
||||
{
|
||||
if (hashstring != NULL)
|
||||
{
|
||||
char *Packet::gethashstring() {
|
||||
if (hashstring != NULL) {
|
||||
return hashstring;
|
||||
}
|
||||
|
||||
@@ -256,26 +267,27 @@ char * Packet::gethashstring ()
|
||||
inet_ntop(sa_family, &dip6, remote_string, 49);
|
||||
}
|
||||
if (Outgoing()) {
|
||||
snprintf(hashstring, HASHKEYSIZE * sizeof(char), "%s:%d-%s:%d", local_string, sport, remote_string, dport);
|
||||
snprintf(hashstring, HASHKEYSIZE * sizeof(char), "%s:%d-%s:%d",
|
||||
local_string, sport, remote_string, dport);
|
||||
} else {
|
||||
snprintf(hashstring, HASHKEYSIZE * sizeof(char), "%s:%d-%s:%d", remote_string, dport, local_string, sport);
|
||||
snprintf(hashstring, HASHKEYSIZE * sizeof(char), "%s:%d-%s:%d",
|
||||
remote_string, dport, local_string, sport);
|
||||
}
|
||||
free(local_string);
|
||||
free(remote_string);
|
||||
// if (DEBUG)
|
||||
// std::cout << "Returning newly created hash string: " << hashstring << std::endl;
|
||||
// std::cout << "Returning newly created hash string: " << hashstring <<
|
||||
//std::endl;
|
||||
return hashstring;
|
||||
}
|
||||
|
||||
/* 2 packets match if they have the same
|
||||
* source and destination ports and IP's. */
|
||||
bool Packet::match (Packet * other)
|
||||
{
|
||||
return (sport == other->sport) && (dport == other->dport)
|
||||
&& (sameinaddr(sip, other->sip)) && (sameinaddr(dip, other->dip));
|
||||
bool Packet::match(Packet *other) {
|
||||
return (sport == other->sport) && (dport == other->dport) &&
|
||||
(sameinaddr(sip, other->sip)) && (sameinaddr(dip, other->dip));
|
||||
}
|
||||
|
||||
bool Packet::matchSource (Packet * other)
|
||||
{
|
||||
bool Packet::matchSource(Packet *other) {
|
||||
return (sport == other->sport) && (sameinaddr(sip, other->sip));
|
||||
}
|
||||
|
||||
28
packet.h
28
packet.h
@@ -15,11 +15,11 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __PACKET_H
|
||||
#define __PACKET_H
|
||||
|
||||
@@ -31,18 +31,13 @@
|
||||
#include <arpa/inet.h>
|
||||
#include "nethogs.h"
|
||||
|
||||
enum direction {
|
||||
dir_unknown,
|
||||
dir_incoming,
|
||||
dir_outgoing
|
||||
};
|
||||
enum direction { dir_unknown, dir_incoming, dir_outgoing };
|
||||
|
||||
/* To initialise this module, call getLocal with the currently
|
||||
* monitored device (e.g. "eth0:1") */
|
||||
bool getLocal(const char *device, bool tracemode);
|
||||
|
||||
class Packet
|
||||
{
|
||||
class Packet {
|
||||
public:
|
||||
in6_addr sip6;
|
||||
in6_addr dip6;
|
||||
@@ -53,14 +48,16 @@ public:
|
||||
u_int32_t len;
|
||||
timeval time;
|
||||
|
||||
Packet (in_addr m_sip, unsigned short m_sport, in_addr m_dip, unsigned short m_dport, u_int32_t m_len, timeval m_time, direction dir = dir_unknown);
|
||||
Packet (in6_addr m_sip, unsigned short m_sport, in6_addr m_dip, unsigned short m_dport, u_int32_t m_len, timeval m_time, direction dir = dir_unknown);
|
||||
Packet(in_addr m_sip, unsigned short m_sport, in_addr m_dip,
|
||||
unsigned short m_dport, u_int32_t m_len, timeval m_time,
|
||||
direction dir = dir_unknown);
|
||||
Packet(in6_addr m_sip, unsigned short m_sport, in6_addr m_dip,
|
||||
unsigned short m_dport, u_int32_t m_len, timeval m_time,
|
||||
direction dir = dir_unknown);
|
||||
/* copy constructor */
|
||||
Packet(const Packet &old);
|
||||
~Packet ()
|
||||
{
|
||||
if (hashstring != NULL)
|
||||
{
|
||||
~Packet() {
|
||||
if (hashstring != NULL) {
|
||||
free(hashstring);
|
||||
hashstring = NULL;
|
||||
}
|
||||
@@ -77,6 +74,7 @@ public:
|
||||
bool matchSource(Packet *other);
|
||||
/* returns '1.2.3.4:5-1.2.3.4:6'-style string */
|
||||
char *gethashstring();
|
||||
|
||||
private:
|
||||
direction dir;
|
||||
short int sa_family;
|
||||
|
||||
138
process.cpp
138
process.cpp
@@ -15,11 +15,11 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <strings.h>
|
||||
#include <string>
|
||||
@@ -49,7 +49,6 @@ extern timeval curtime;
|
||||
*/
|
||||
extern std::map<std::string, unsigned long> conninode;
|
||||
|
||||
|
||||
/* this file includes:
|
||||
* - calls to inodeproc to get the pid that belongs to that inode
|
||||
*/
|
||||
@@ -71,24 +70,12 @@ ProcList * processes;
|
||||
* This mapping maps from unknown processes descriptions to processes */
|
||||
std::map<std::string, Process *> unknownprocs;
|
||||
|
||||
float tomb(u_int32_t bytes) { return ((double)bytes) / 1024 / 1024; }
|
||||
float tokb(u_int32_t bytes) { return ((double)bytes) / 1024; }
|
||||
|
||||
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; }
|
||||
|
||||
float tokbps (u_int32_t bytes)
|
||||
{
|
||||
return (((double)bytes) / PERIOD) / 1024;
|
||||
}
|
||||
|
||||
|
||||
void process_init ()
|
||||
{
|
||||
void process_init() {
|
||||
unknowntcp = new Process(0, "", "unknown TCP");
|
||||
// unknownudp = new Process (0, "", "unknown UDP");
|
||||
// unknownip = new Process (0, "", "unknown IP");
|
||||
@@ -97,12 +84,10 @@ void process_init ()
|
||||
// processes = new ProcList (unknownip, processes);
|
||||
}
|
||||
|
||||
int Process::getLastPacket()
|
||||
{
|
||||
int Process::getLastPacket() {
|
||||
int lastpacket = 0;
|
||||
ConnList *curconn = connections;
|
||||
while (curconn != NULL)
|
||||
{
|
||||
while (curconn != NULL) {
|
||||
assert(curconn != NULL);
|
||||
assert(curconn->getVal() != NULL);
|
||||
if (curconn->getVal()->getLastPacket() > lastpacket)
|
||||
@@ -113,18 +98,15 @@ int Process::getLastPacket()
|
||||
}
|
||||
|
||||
/** Get the kb/s values for this process */
|
||||
void Process::getkbps (float * recvd, float * sent)
|
||||
{
|
||||
void Process::getkbps(float *recvd, float *sent) {
|
||||
u_int32_t sum_sent = 0, sum_recv = 0;
|
||||
|
||||
/* walk though all this process's connections, and sum
|
||||
* them up */
|
||||
ConnList *curconn = this->connections;
|
||||
ConnList *previous = NULL;
|
||||
while (curconn != NULL)
|
||||
{
|
||||
if (curconn->getVal()->getLastPacket() <= curtime.tv_sec - CONNTIMEOUT)
|
||||
{
|
||||
while (curconn != NULL) {
|
||||
if (curconn->getVal()->getLastPacket() <= curtime.tv_sec - CONNTIMEOUT) {
|
||||
/* stalled connection, remove. */
|
||||
ConnList *todelete = curconn;
|
||||
Connection *conn_todelete = curconn->getVal();
|
||||
@@ -135,9 +117,7 @@ void Process::getkbps (float * recvd, float * sent)
|
||||
previous->setNext(curconn);
|
||||
delete (todelete);
|
||||
delete (conn_todelete);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
u_int32_t sent = 0, recv = 0;
|
||||
curconn->getVal()->sumanddel(curtime, &recv, &sent);
|
||||
sum_sent += sent;
|
||||
@@ -151,12 +131,10 @@ void Process::getkbps (float * recvd, float * sent)
|
||||
}
|
||||
|
||||
/** get total values for this process */
|
||||
void Process::gettotal( u_int32_t * recvd, u_int32_t * sent)
|
||||
{
|
||||
void Process::gettotal(u_int32_t *recvd, u_int32_t *sent) {
|
||||
u_int32_t sum_sent = 0, sum_recv = 0;
|
||||
ConnList *curconn = this->connections;
|
||||
while (curconn != NULL)
|
||||
{
|
||||
while (curconn != NULL) {
|
||||
Connection *conn = curconn->getVal();
|
||||
sum_sent += conn->sumSent;
|
||||
sum_recv += conn->sumRecv;
|
||||
@@ -168,8 +146,7 @@ void Process::gettotal( u_int32_t * recvd, u_int32_t * sent)
|
||||
*sent = sum_sent;
|
||||
}
|
||||
|
||||
void Process::gettotalmb(float * recvd, float * sent)
|
||||
{
|
||||
void Process::gettotalmb(float *recvd, float *sent) {
|
||||
u_int32_t sum_sent = 0, sum_recv = 0;
|
||||
gettotal(&sum_recv, &sum_sent);
|
||||
*recvd = tomb(sum_recv);
|
||||
@@ -177,16 +154,14 @@ void Process::gettotalmb(float * recvd, float * sent)
|
||||
}
|
||||
|
||||
/** get total values for this process */
|
||||
void Process::gettotalkb(float * recvd, float * sent)
|
||||
{
|
||||
void Process::gettotalkb(float *recvd, float *sent) {
|
||||
u_int32_t sum_sent = 0, sum_recv = 0;
|
||||
gettotal(&sum_recv, &sum_sent);
|
||||
*recvd = tokb(sum_recv);
|
||||
*sent = tokb(sum_sent);
|
||||
}
|
||||
|
||||
void Process::gettotalb(float * recvd, float * sent)
|
||||
{
|
||||
void Process::gettotalb(float *recvd, float *sent) {
|
||||
u_int32_t sum_sent = 0, sum_recv = 0;
|
||||
gettotal(&sum_recv, &sum_sent);
|
||||
// std::cout << "Total sent: " << sum_sent << std::endl;
|
||||
@@ -194,12 +169,9 @@ void Process::gettotalb(float * recvd, float * sent)
|
||||
*recvd = sum_recv;
|
||||
}
|
||||
|
||||
|
||||
Process * findProcess (struct prg_node * node)
|
||||
{
|
||||
Process *findProcess(struct prg_node *node) {
|
||||
ProcList *current = processes;
|
||||
while (current != NULL)
|
||||
{
|
||||
while (current != NULL) {
|
||||
Process *currentproc = current->getVal();
|
||||
assert(currentproc != NULL);
|
||||
|
||||
@@ -213,8 +185,7 @@ Process * findProcess (struct prg_node * node)
|
||||
/* finds process based on inode, if any */
|
||||
/* should be done quickly after arrival of the packet,
|
||||
* otherwise findPID will be outdated */
|
||||
Process * findProcess (unsigned long inode)
|
||||
{
|
||||
Process *findProcess(unsigned long inode) {
|
||||
struct prg_node *node = findPID(inode);
|
||||
|
||||
if (node == NULL)
|
||||
@@ -223,8 +194,7 @@ Process * findProcess (unsigned long inode)
|
||||
return findProcess(node);
|
||||
}
|
||||
|
||||
int ProcList::size ()
|
||||
{
|
||||
int ProcList::size() {
|
||||
int i = 1;
|
||||
|
||||
if (next != NULL)
|
||||
@@ -233,11 +203,9 @@ int ProcList::size ()
|
||||
return i;
|
||||
}
|
||||
|
||||
void check_all_procs ()
|
||||
{
|
||||
void check_all_procs() {
|
||||
ProcList *curproc = processes;
|
||||
while (curproc != NULL)
|
||||
{
|
||||
while (curproc != NULL) {
|
||||
curproc->getVal()->check();
|
||||
curproc = curproc->getNext();
|
||||
}
|
||||
@@ -248,12 +216,10 @@ void check_all_procs ()
|
||||
* if the inode is not associated with any PID, return NULL
|
||||
* if the process is not yet in the proclist, add it
|
||||
*/
|
||||
Process * getProcess (unsigned long inode, const char * devicename)
|
||||
{
|
||||
Process *getProcess(unsigned long inode, const char *devicename) {
|
||||
struct prg_node *node = findPID(inode);
|
||||
|
||||
if (node == NULL)
|
||||
{
|
||||
if (node == NULL) {
|
||||
if (DEBUG || bughuntmode)
|
||||
std::cout << "No PID information for inode " << inode << std::endl;
|
||||
return NULL;
|
||||
@@ -305,40 +271,35 @@ Process * getProcess (unsigned long inode, const char * devicename)
|
||||
* is made. If no process can be found even then, it's added to the
|
||||
* 'unknown' process.
|
||||
*/
|
||||
Process * getProcess (Connection * connection, const char * devicename)
|
||||
{
|
||||
Process *getProcess(Connection *connection, const char *devicename) {
|
||||
unsigned long inode = conninode[connection->refpacket->gethashstring()];
|
||||
|
||||
if (inode == 0)
|
||||
{
|
||||
if (inode == 0) {
|
||||
// no? refresh and check conn/inode table
|
||||
if (bughuntmode)
|
||||
{
|
||||
std::cout << "? new connection not in connection-to-inode table before refresh.\n";
|
||||
if (bughuntmode) {
|
||||
std::cout << "? new connection not in connection-to-inode table before "
|
||||
"refresh.\n";
|
||||
}
|
||||
// refresh the inode->pid table first. Presumably processing the renewed connection->inode table
|
||||
// refresh the inode->pid table first. Presumably processing the renewed
|
||||
// connection->inode table
|
||||
// is slow, making this worthwhile.
|
||||
// We take the fact for granted that we might already know the inode->pid (unlikely anyway if we
|
||||
// We take the fact for granted that we might already know the inode->pid
|
||||
// (unlikely anyway if we
|
||||
// haven't seen the connection->inode yet though).
|
||||
#ifndef __APPLE__
|
||||
reread_mapping();
|
||||
#endif
|
||||
refreshconninode();
|
||||
inode = conninode[connection->refpacket->gethashstring()];
|
||||
if (bughuntmode)
|
||||
{
|
||||
if (inode == 0)
|
||||
{
|
||||
if (bughuntmode) {
|
||||
if (inode == 0) {
|
||||
std::cout << ":( inode for connection not found after refresh.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::cout << ":) inode for connection found after refresh.\n";
|
||||
}
|
||||
}
|
||||
#if REVERSEHACK
|
||||
if (inode == 0)
|
||||
{
|
||||
if (inode == 0) {
|
||||
/* HACK: the following is a hack for cases where the
|
||||
* 'local' addresses aren't properly recognised, as is
|
||||
* currently the case for IPv6 */
|
||||
@@ -348,12 +309,14 @@ Process * getProcess (Connection * connection, const char * devicename)
|
||||
Packet *reversepacket = connection->refpacket->newInverted();
|
||||
inode = conninode[reversepacket->gethashstring()];
|
||||
|
||||
if (inode == 0)
|
||||
{
|
||||
if (inode == 0) {
|
||||
delete reversepacket;
|
||||
if (bughuntmode || DEBUG)
|
||||
std::cout << "LOC: " << connection->refpacket->gethashstring() << " STILL not in connection-to-inode table - adding to the unknown process\n";
|
||||
unknowntcp->connections = new ConnList (connection, unknowntcp->connections);
|
||||
std::cout << "LOC: " << connection->refpacket->gethashstring()
|
||||
<< " STILL not in connection-to-inode table - adding to "
|
||||
"the unknown process\n";
|
||||
unknowntcp->connections =
|
||||
new ConnList(connection, unknowntcp->connections);
|
||||
return unknowntcp;
|
||||
}
|
||||
|
||||
@@ -361,14 +324,12 @@ Process * getProcess (Connection * connection, const char * devicename)
|
||||
connection->refpacket = reversepacket;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (bughuntmode)
|
||||
{
|
||||
std::cout << ";) new connection in connection-to-inode table before refresh.\n";
|
||||
} else if (bughuntmode) {
|
||||
std::cout
|
||||
<< ";) new connection in connection-to-inode table before refresh.\n";
|
||||
}
|
||||
|
||||
if (bughuntmode)
|
||||
{
|
||||
if (bughuntmode) {
|
||||
std::cout << " inode # " << inode << std::endl;
|
||||
}
|
||||
|
||||
@@ -385,8 +346,7 @@ Process * getProcess (Connection * connection, const char * devicename)
|
||||
return proc;
|
||||
}
|
||||
|
||||
void procclean ()
|
||||
{
|
||||
void procclean() {
|
||||
// delete conninode;
|
||||
prg_cache_clear();
|
||||
}
|
||||
|
||||
80
process.h
80
process.h
@@ -15,11 +15,11 @@
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
*USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __PROCESS_H
|
||||
#define __PROCESS_H
|
||||
|
||||
@@ -32,44 +32,35 @@ extern bool bughuntmode;
|
||||
|
||||
void check_all_procs();
|
||||
|
||||
class ConnList
|
||||
{
|
||||
class ConnList {
|
||||
public:
|
||||
ConnList (Connection * m_val, ConnList * m_next)
|
||||
{
|
||||
ConnList(Connection *m_val, ConnList *m_next) {
|
||||
assert(m_val != NULL);
|
||||
val = m_val; next = m_next;
|
||||
val = m_val;
|
||||
next = m_next;
|
||||
}
|
||||
~ConnList ()
|
||||
{
|
||||
~ConnList() {
|
||||
/* does not delete its value, to allow a connection to
|
||||
* remove itself from the global connlist in its destructor */
|
||||
}
|
||||
Connection * getVal ()
|
||||
{
|
||||
return val;
|
||||
}
|
||||
void setNext (ConnList * m_next)
|
||||
{
|
||||
next = m_next;
|
||||
}
|
||||
ConnList * getNext ()
|
||||
{
|
||||
return next;
|
||||
}
|
||||
Connection *getVal() { return val; }
|
||||
void setNext(ConnList *m_next) { next = m_next; }
|
||||
ConnList *getNext() { return next; }
|
||||
|
||||
private:
|
||||
Connection *val;
|
||||
ConnList *next;
|
||||
};
|
||||
|
||||
class Process
|
||||
{
|
||||
class Process {
|
||||
public:
|
||||
/* the process makes a copy of the name. the device name needs to be stable. */
|
||||
Process (const unsigned long m_inode, const char * m_devicename, const char * m_name = NULL)
|
||||
: inode (m_inode)
|
||||
{
|
||||
//std::cout << "ARN: Process created with dev " << m_devicename << std::endl;
|
||||
/* the process makes a copy of the name. the device name needs to be stable.
|
||||
*/
|
||||
Process(const unsigned long m_inode, const char *m_devicename,
|
||||
const char *m_name = NULL)
|
||||
: inode(m_inode) {
|
||||
// std::cout << "ARN: Process created with dev " << m_devicename <<
|
||||
// std::endl;
|
||||
if (DEBUG)
|
||||
std::cout << "PROC: Process created at " << this << std::endl;
|
||||
|
||||
@@ -83,12 +74,9 @@ public:
|
||||
pid = 0;
|
||||
uid = 0;
|
||||
}
|
||||
void check () {
|
||||
assert (pid >= 0);
|
||||
}
|
||||
void check() { assert(pid >= 0); }
|
||||
|
||||
~Process ()
|
||||
{
|
||||
~Process() {
|
||||
free(name);
|
||||
if (DEBUG)
|
||||
std::cout << "PROC: Process deleted at " << this << std::endl;
|
||||
@@ -106,37 +94,29 @@ public:
|
||||
int pid;
|
||||
|
||||
ConnList *connections;
|
||||
uid_t getUid()
|
||||
{
|
||||
return uid;
|
||||
}
|
||||
uid_t getUid() { return uid; }
|
||||
|
||||
void setUid(uid_t m_uid)
|
||||
{
|
||||
uid = m_uid;
|
||||
}
|
||||
void setUid(uid_t m_uid) { uid = m_uid; }
|
||||
|
||||
unsigned long getInode() { return inode; }
|
||||
|
||||
unsigned long getInode()
|
||||
{
|
||||
return inode;
|
||||
}
|
||||
private:
|
||||
const unsigned long inode;
|
||||
uid_t uid;
|
||||
};
|
||||
|
||||
class ProcList
|
||||
{
|
||||
class ProcList {
|
||||
public:
|
||||
ProcList (Process * m_val, ProcList * m_next)
|
||||
{
|
||||
ProcList(Process *m_val, ProcList *m_next) {
|
||||
assert(m_val != NULL);
|
||||
val = m_val; next = m_next;
|
||||
val = m_val;
|
||||
next = m_next;
|
||||
}
|
||||
int size();
|
||||
Process *getVal() { return val; }
|
||||
ProcList *getNext() { return next; }
|
||||
ProcList *next;
|
||||
|
||||
private:
|
||||
Process *val;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user