From e74935da1f7b57835053e09afc07d16de86f1f28 Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Mon, 21 Mar 2016 00:31:48 +0100 Subject: [PATCH] Use clang-format to format (somewhat) LLVM-style (fixes #44) --- Makefile | 4 +- README.md | 24 +- connection.cpp | 314 +++++++++++------------ connection.h | 124 +++++---- conninode.cpp | 255 +++++++++--------- conninode.h | 5 +- cui.cpp | 654 +++++++++++++++++++++++------------------------ cui.h | 11 +- decpcap.c | 460 ++++++++++++++++----------------- decpcap.h | 55 ++-- decpcap_test.cpp | 40 ++- devices.cpp | 91 ++++--- devices.h | 19 +- inode2prog.cpp | 296 +++++++++++---------- inode2prog.h | 13 +- libnethogs.cpp | 542 ++++++++++++++++++--------------------- libnethogs.h | 59 +++-- main.cpp | 477 ++++++++++++++++------------------ nethogs.cpp | 313 ++++++++++++----------- nethogs.h | 70 +++-- packet.cpp | 356 +++++++++++++------------- packet.h | 86 +++---- process.cpp | 486 ++++++++++++++++------------------- process.h | 176 ++++++------- 24 files changed, 2369 insertions(+), 2561 deletions(-) diff --git a/Makefile b/Makefile index 766c960..84a09bd 100644 --- a/Makefile +++ b/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 diff --git a/README.md b/README.md index 21f031d..795931a 100644 --- a/README.md +++ b/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 ---------- diff --git a/connection.cpp b/connection.cpp index 2e0120f..ce4f76a 100644 --- a/connection.cpp +++ b/connection.cpp @@ -1,4 +1,4 @@ -/* +/* * connection.cpp * * Copyright (c) 2004-2006,2008 Arnout Engelen @@ -15,224 +15,198 @@ * * 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 #include #ifdef __APPLE__ - #include +#include #else - #include +#include #endif #include "nethogs.h" #include "connection.h" #include "process.h" -ConnList * connections = NULL; +ConnList *connections = NULL; -void PackList::add (Packet * p) -{ - if (content == NULL) - { - content = new PackListNode (new Packet (*p)); - return; - } +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) - { - content->val->len += p->len; - return; - } + if (content->val->time.tv_sec == p->time.tv_sec) { + content->val->len += p->len; + return; + } - /* store copy of packet, so that original may be freed */ - content = new PackListNode(new Packet (*p), content); + /* store copy of packet, so that original may be freed */ + content = new PackListNode(new Packet(*p), content); } /* sums up the total bytes used and removes 'old' packets */ -u_int32_t PackList::sumanddel (timeval t) -{ - u_int32_t retval = 0; - PackListNode * current = content; - PackListNode * previous = NULL; +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) - { - if (current == content) - content = NULL; - else if (previous != NULL) - previous->next = NULL; - delete current; - return retval; - } - retval += current->val->len; - previous = current; - current = current->next; - } - return retval; + 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) + previous->next = NULL; + delete current; + return retval; + } + retval += current->val->len; + previous = current; + current = current->next; + } + return retval; } /* packet may be deleted by caller */ -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 (packet->Outgoing()) - { - sumSent += packet->len; - sent_packets->add(packet); - refpacket = new Packet (*packet); - } else { - sumRecv += packet->len; - recv_packets->add(packet); - refpacket = packet->newInverted(); - } - lastpacket = packet->time.tv_sec; - if (DEBUG) - std::cout << "New reference packet created at " << refpacket << std::endl; +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 (packet->Outgoing()) { + sumSent += packet->len; + sent_packets->add(packet); + refpacket = new Packet(*packet); + } else { + sumRecv += packet->len; + recv_packets->add(packet); + refpacket = packet->newInverted(); + } + lastpacket = packet->time.tv_sec; + if (DEBUG) + std::cout << "New reference packet created at " << refpacket << std::endl; } -Connection::~Connection () -{ - if (DEBUG) - std::cout << "Deleting connection" << std::endl; - /* refpacket is not a pointer to one of the packets in the lists - * so deleted */ - delete (refpacket); - if (sent_packets != NULL) - delete sent_packets; - if (recv_packets != NULL) - delete recv_packets; +Connection::~Connection() { + if (DEBUG) + std::cout << "Deleting connection" << std::endl; + /* refpacket is not a pointer to one of the packets in the lists + * so deleted */ + delete (refpacket); + if (sent_packets != NULL) + delete sent_packets; + if (recv_packets != NULL) + delete recv_packets; - ConnList * curr_conn = connections; - ConnList * prev_conn = NULL; - while (curr_conn != NULL) - { - if (curr_conn->getVal() == this) - { - ConnList * todelete = curr_conn; - curr_conn = curr_conn->getNext(); - if (prev_conn == NULL) - { - connections = curr_conn; - } else { - prev_conn->setNext(curr_conn); - } - delete (todelete); - } - else - { - prev_conn = curr_conn; - curr_conn = curr_conn->getNext(); - } - } + ConnList *curr_conn = connections; + ConnList *prev_conn = NULL; + while (curr_conn != NULL) { + if (curr_conn->getVal() == this) { + ConnList *todelete = curr_conn; + curr_conn = curr_conn->getNext(); + if (prev_conn == NULL) { + connections = curr_conn; + } else { + prev_conn->setNext(curr_conn); + } + delete (todelete); + } else { + prev_conn = curr_conn; + curr_conn = curr_conn->getNext(); + } + } } /* the packet will be freed by the calling code */ -void Connection::add (Packet * packet) -{ - lastpacket = packet->time.tv_sec; - if (packet->Outgoing()) - { - if (DEBUG) - { - std::cout << "Outgoing: " << packet->len << std::endl; - } - sumSent += packet->len; - sent_packets->add (packet); - } - else - { - if (DEBUG) - { - std::cout << "Incoming: " << packet->len << std::endl; - } - sumRecv += packet->len; - if (DEBUG) - { - std::cout << "sumRecv now: " << sumRecv << std::endl; - } - recv_packets->add (packet); - } +void Connection::add(Packet *packet) { + lastpacket = packet->time.tv_sec; + if (packet->Outgoing()) { + if (DEBUG) { + std::cout << "Outgoing: " << packet->len << std::endl; + } + sumSent += packet->len; + sent_packets->add(packet); + } else { + if (DEBUG) { + std::cout << "Incoming: " << packet->len << std::endl; + } + sumRecv += packet->len; + if (DEBUG) { + std::cout << "sumRecv now: " << sumRecv << std::endl; + } + recv_packets->add(packet); + } } -Connection * findConnectionWithMatchingSource(Packet * packet) { - assert(packet->Outgoing()); +Connection *findConnectionWithMatchingSource(Packet *packet) { + assert(packet->Outgoing()); - ConnList * current = connections; - while (current != NULL) - { - /* the reference packet is always outgoing */ - if (packet->matchSource(current->getVal()->refpacket)) - { - return current->getVal(); - } + ConnList *current = connections; + while (current != NULL) { + /* the reference packet is always outgoing */ + if (packet->matchSource(current->getVal()->refpacket)) { + return current->getVal(); + } - current = current->getNext(); - } - return NULL; + current = current->getNext(); + } + return NULL; } -Connection * findConnectionWithMatchingRefpacketOrSource(Packet * packet) { - ConnList * current = connections; - while (current != NULL) - { - /* the reference packet is always *outgoing* */ - if (packet->match(current->getVal()->refpacket)) - { - return current->getVal(); - } +Connection *findConnectionWithMatchingRefpacketOrSource(Packet *packet) { + ConnList *current = connections; + while (current != NULL) { + /* the reference packet is always *outgoing* */ + if (packet->match(current->getVal()->refpacket)) { + return current->getVal(); + } - current = current->getNext(); - } - return findConnectionWithMatchingSource(packet); + current = current->getNext(); + } + return findConnectionWithMatchingSource(packet); } -/* +/* * finds connection to which this packet belongs. * a packet belongs to a connection if it matches - * to its reference packet + * to its reference packet */ -Connection * findConnection (Packet * packet) -{ - if (packet->Outgoing()) - return findConnectionWithMatchingRefpacketOrSource(packet); - else - { - Packet * invertedPacket = packet->newInverted(); - Connection * result = findConnectionWithMatchingRefpacketOrSource(invertedPacket); +Connection *findConnection(Packet *packet) { + if (packet->Outgoing()) + return findConnectionWithMatchingRefpacketOrSource(packet); + else { + Packet *invertedPacket = packet->newInverted(); + Connection *result = + findConnectionWithMatchingRefpacketOrSource(invertedPacket); - delete invertedPacket; - return result; - } + delete invertedPacket; + return result; + } } /* * Connection::sumanddel - * + * * sums up the total bytes used - * and removes 'old' packets. + * and removes 'old' packets. * * 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) -{ - (*sent)=(*recv)=0; +void Connection::sumanddel(timeval t, u_int32_t *recv, u_int32_t *sent) { + (*sent) = (*recv) = 0; - *sent = sent_packets->sumanddel(t); - *recv = recv_packets->sumanddel(t); + *sent = sent_packets->sumanddel(t); + *recv = recv_packets->sumanddel(t); } diff --git a/connection.h b/connection.h index 23b7bcf..27f3eac 100644 --- a/connection.h +++ b/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,91 +25,82 @@ #include #include "packet.h" -class PackListNode -{ +class PackListNode { public: - PackListNode (Packet * m_val, PackListNode * m_next = NULL) - { - val = m_val; - next = m_next; - } - ~PackListNode () - { - delete val; - if (next != NULL) - delete next; - } - PackListNode * next; - Packet * val; + PackListNode(Packet *m_val, PackListNode *m_next = NULL) { + val = m_val; + next = m_next; + } + ~PackListNode() { + delete val; + if (next != NULL) + delete next; + } + PackListNode *next; + Packet *val; }; -class PackList -{ +class PackList { public: - PackList () - { - content = NULL; - } - PackList (Packet * m_val) - { - assert (m_val != NULL); - content = new PackListNode(m_val); - } - ~PackList () - { - if (content != NULL) - delete content; - } + PackList() { content = NULL; } + PackList(Packet *m_val) { + assert(m_val != NULL); + content = new PackListNode(m_val); + } + ~PackList() { + if (content != NULL) + delete content; + } - /* sums up the total bytes used and removes 'old' packets */ - u_int32_t sumanddel (timeval t); + /* sums up the total bytes used and removes 'old' packets */ + u_int32_t sumanddel(timeval t); + + /* calling code may delete packet */ + void add(Packet *p); - /* calling code may delete packet */ - void add (Packet * p); private: - PackListNode * content; + PackListNode *content; }; -class Connection -{ +class Connection { public: - /* constructs a connection, makes a copy of - * the packet as 'refpacket', and adds the - * packet to the packlist */ - /* packet may be deleted by caller */ - Connection (Packet * packet); + /* constructs a connection, makes a copy of + * the packet as 'refpacket', and adds the + * packet to the packlist */ + /* packet may be deleted by caller */ + Connection(Packet *packet); - ~Connection(); + ~Connection(); - /* add a packet to the packlist - * will delete the packet structure - * when it is 'merged with' (added to) another - * packet - */ - void add (Packet * packet); + /* add a packet to the packlist + * will delete the packet structure + * when it is 'merged with' (added to) another + * packet + */ + void add(Packet *packet); - int getLastPacket () - { return lastpacket; } + int getLastPacket() { return lastpacket; } - /* sums up the total bytes used - * and removes 'old' packets. */ - void sumanddel(timeval curtime, u_int32_t * recv, u_int32_t * sent); + /* sums up the total bytes used + * and removes 'old' packets. */ + void sumanddel(timeval curtime, u_int32_t *recv, u_int32_t *sent); - /* for checking if a packet is part of this connection */ - /* the reference packet is always *outgoing*. */ - Packet * refpacket; + /* for checking if a packet is part of this connection */ + /* the reference packet is always *outgoing*. */ + Packet *refpacket; + + /* total sum or sent/received bytes */ + u_int32_t sumSent; + u_int32_t sumRecv; - /* total sum or sent/received bytes */ - u_int32_t sumSent; - u_int32_t sumRecv; private: - PackList * sent_packets; - PackList * recv_packets; - int lastpacket; + PackList *sent_packets; + PackList *recv_packets; + int lastpacket; }; /* Find the connection this packet belongs to */ /* (the calling code may free the packet afterwards) */ -Connection * findConnection (Packet * packet); +Connection *findConnection(Packet *packet); #endif diff --git a/conninode.cpp b/conninode.cpp index 6cd7ddb..79649a9 100644 --- a/conninode.cpp +++ b/conninode.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 #include #include @@ -29,173 +29,168 @@ #include "conninode.h" #if defined __APPLE__ - #ifndef s6_addr32 - #define s6_addr32 __u6_addr.__u6_addr32 - #endif +#ifndef s6_addr32 +#define s6_addr32 __u6_addr.__u6_addr32 +#endif #endif -extern local_addr * local_addrs; +extern local_addr *local_addrs; /* * connection-inode table. takes information from /proc/net/tcp. * key contains source ip, source port, destination ip, destination * port in format: '1.2.3.4:5-1.2.3.4:5' */ -std::map conninode; - +std::map 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) -{ - short int sa_family; - struct in6_addr result_addr_local; - struct in6_addr result_addr_remote; +void addtoconninode(char *buffer) { + short int sa_family; + struct in6_addr result_addr_local; + struct in6_addr result_addr_remote; - char rem_addr[128], local_addr[128]; - int local_port, rem_port; - struct in6_addr in6_local; - struct in6_addr in6_remote; + char rem_addr[128], local_addr[128]; + int local_port, rem_port; + struct in6_addr in6_local; + struct in6_addr in6_remote; - // this leaked memory - //unsigned long * inode = (unsigned long *) malloc (sizeof(unsigned long)); - unsigned long inode; + // this leaked memory + // 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", - local_addr, &local_port, rem_addr, &rem_port, &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", + local_addr, &local_port, rem_addr, &rem_port, &inode); - if (matches != 5) { - fprintf(stderr,"Unexpected buffer: '%s'\n",buffer); - exit(0); - } + if (matches != 5) { + fprintf(stderr, "Unexpected buffer: '%s'\n", buffer); + exit(0); + } - if (inode == 0) { - /* connection is in TIME_WAIT state. We rely on - * the old data still in the table. */ - return; - } + if (inode == 0) { + /* connection is in TIME_WAIT state. We rely on + * the old data still in the table. */ + return; + } - if (strlen(local_addr) > 8) - { - /* this is an IPv6-style row */ + 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]); + /* 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]); - 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])); - sa_family = AF_INET; - } else { - /* real IPv6 address */ - //inet_ntop(AF_INET6, &in6_local, addr6, sizeof(addr6)); - //INET6_getsock(addr6, (struct sockaddr *) &localaddr); - //inet_ntop(AF_INET6, &in6_remote, addr6, sizeof(addr6)); - //INET6_getsock(addr6, (struct sockaddr *) &remaddr); - //localaddr.sin6_family = AF_INET6; - //remaddr.sin6_family = AF_INET6; - result_addr_local = in6_local; - result_addr_remote = in6_remote; - sa_family = AF_INET6; - } - } - 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); - sa_family = AF_INET; - } + 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])); + sa_family = AF_INET; + } else { + /* real IPv6 address */ + // inet_ntop(AF_INET6, &in6_local, addr6, sizeof(addr6)); + // INET6_getsock(addr6, (struct sockaddr *) &localaddr); + // inet_ntop(AF_INET6, &in6_remote, addr6, sizeof(addr6)); + // INET6_getsock(addr6, (struct sockaddr *) &remaddr); + // localaddr.sin6_family = AF_INET6; + // remaddr.sin6_family = AF_INET6; + result_addr_local = in6_local; + result_addr_remote = in6_remote; + sa_family = AF_INET6; + } + } 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); + sa_family = AF_INET; + } - char * hashkey = (char *) malloc (HASHKEYSIZE * sizeof(char)); - char * local_string = (char*) malloc (50); - char * remote_string = (char*) malloc (50); - inet_ntop(sa_family, &result_addr_local, local_string, 49); - inet_ntop(sa_family, &result_addr_remote, remote_string, 49); + char *hashkey = (char *)malloc(HASHKEYSIZE * sizeof(char)); + char *local_string = (char *)malloc(50); + char *remote_string = (char *)malloc(50); + 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); - free (local_string); + snprintf(hashkey, HASHKEYSIZE * sizeof(char), "%s:%d-%s:%d", local_string, + local_port, remote_string, rem_port); + free(local_string); - //if (DEBUG) - // fprintf (stderr, "Hashkey: %s\n", hashkey); + // if (DEBUG) + // fprintf (stderr, "Hashkey: %s\n", hashkey); - //std::cout << "Adding to conninode\n" << std::endl; + // std::cout << "Adding to conninode\n" << std::endl; - conninode[hashkey] = inode; + conninode[hashkey] = inode; - /* workaround: sometimes, when a connection is actually from 172.16.3.1 to - * 172.16.3.3, packages arrive from 195.169.216.157 to 172.16.3.3, where - * 172.16.3.1 and 195.169.216.157 are the local addresses of different - * interfaces */ - for (class local_addr *current_local_addr = local_addrs; - 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); - conninode[hashkey] = inode; - } - free (hashkey); - free (remote_string); + /* workaround: sometimes, when a connection is actually from 172.16.3.1 to + * 172.16.3.3, packages arrive from 195.169.216.157 to 172.16.3.3, where + * 172.16.3.1 and 195.169.216.157 are the local addresses of different + * interfaces */ + for (class local_addr *current_local_addr = local_addrs; + 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); + conninode[hashkey] = inode; + } + free(hashkey); + free(remote_string); } /* opens /proc/net/tcp[6] and adds its contents line by line */ -int addprocinfo (const char * filename) { - FILE * procinfo = fopen (filename, "r"); +int addprocinfo(const char *filename) { + FILE *procinfo = fopen(filename, "r"); - char buffer[8192]; + char buffer[8192]; - if (procinfo == NULL) - return 0; + if (procinfo == NULL) + return 0; - fgets(buffer, sizeof(buffer), procinfo); + fgets(buffer, sizeof(buffer), procinfo); - do - { - if (fgets(buffer, sizeof(buffer), procinfo)) - addtoconninode(buffer); - } while (!feof(procinfo)); + do { + if (fgets(buffer, sizeof(buffer), procinfo)) + addtoconninode(buffer); + } while (!feof(procinfo)); - fclose(procinfo); + fclose(procinfo); - return 1; + return 1; } +void refreshconninode() { +/* we don't forget old mappings, just overwrite */ +// delete conninode; +// conninode = new HashTable (256); +#if defined(__APPLE__) + addprocinfo("net.inet.tcp.pcblist"); +#else + if (!addprocinfo("/proc/net/tcp")) { + std::cout << "Error: couldn't open /proc/net/tcp\n"; + exit(0); + } + addprocinfo("/proc/net/tcp6"); +#endif - -void refreshconninode () -{ - /* we don't forget old mappings, just overwrite */ - //delete conninode; - //conninode = new HashTable (256); - - #if defined(__APPLE__) - addprocinfo("net.inet.tcp.pcblist"); - #else - if (! addprocinfo ("/proc/net/tcp")) - { - std::cout << "Error: couldn't open /proc/net/tcp\n"; - exit(0); - } - addprocinfo ("/proc/net/tcp6"); - #endif - - //if (DEBUG) - // reviewUnknown(); - + // if (DEBUG) + // reviewUnknown(); } diff --git a/conninode.h b/conninode.h index 438947c..386a80f 100644 --- a/conninode.h +++ b/conninode.h @@ -15,8 +15,9 @@ * * 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 -void refreshconninode (); +void refreshconninode(); diff --git a/cui.cpp b/cui.cpp index ca7aa90..7c9c693 100644 --- a/cui.cpp +++ b/cui.cpp @@ -1,4 +1,4 @@ -/* +/* * cui.cpp * * Copyright (c) 2004-2006,2008,2010,2011 Arnout Engelen @@ -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 #include @@ -33,14 +33,14 @@ #include "nethogs.h" #include "process.h" -std::string * caption; +std::string *caption; extern const char version[]; -extern ProcList * processes; +extern ProcList *processes; extern timeval curtime; -extern Process * unknowntcp; -extern Process * unknownudp; -extern Process * unknownip; +extern Process *unknowntcp; +extern Process *unknownudp; +extern Process *unknownip; extern bool sortRecv; @@ -51,414 +51,392 @@ extern unsigned refreshcount; #define PID_MAX 4194303 -const int COLUMN_WIDTH_PID = 7; -const int COLUMN_WIDTH_USER = 8; -const int COLUMN_WIDTH_DEV = 5; +const int COLUMN_WIDTH_PID = 7; +const int COLUMN_WIDTH_USER = 8; +const int COLUMN_WIDTH_DEV = 5; const int COLUMN_WIDTH_SENT = 11; const int COLUMN_WIDTH_RECEIVED = 11; const int COLUMN_WIDTH_UNIT = 6; -const char * COLUMN_FORMAT_PID = "%7d"; -const char * COLUMN_FORMAT_SENT = "%11.3f"; -const char * COLUMN_FORMAT_RECEIVED = "%11.3f"; +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) - { - assert (pid >= 0); - assert (pid <= PID_MAX); - m_name = name; - sent_value = n_sent_value; - recv_value = n_recv_value; - devicename = n_devicename; - m_pid = pid; - m_uid = uid; - assert (m_pid >= 0); - } + 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; + sent_value = n_sent_value; + recv_value = n_recv_value; + devicename = n_devicename; + m_pid = pid; + m_uid = uid; + assert(m_pid >= 0); + } - void show (int row, unsigned int proglen); - void log (); + void show(int row, unsigned int proglen); + void log(); + + double sent_value; + double recv_value; - double sent_value; - double recv_value; private: - const char * m_name; - const char * devicename; - pid_t m_pid; - uid_t m_uid; + const char *m_name; + const char *devicename; + pid_t m_pid; + uid_t m_uid; }; #include -std::string itoa(int i) -{ - std::stringstream out; - out << i; - return out.str(); +std::string itoa(int i) { + std::stringstream out; + out << i; + return out.str(); } /** - * @returns the username that corresponds to this uid + * @returns the username that corresponds to this uid */ -std::string uid2username (uid_t uid) -{ - struct passwd * pwd = NULL; - errno = 0; +std::string uid2username(uid_t uid) { + struct passwd *pwd = NULL; + errno = 0; - /* points to a static memory area, should not be freed */ - pwd = getpwuid(uid); + /* points to a static memory area, should not be freed */ + pwd = getpwuid(uid); - if (pwd == NULL) - if (errno == 0) - return itoa(uid); - else - forceExit(false, "Error calling getpwuid(3) for uid %d: %d %s", uid, errno, strerror(errno)); - else - return std::string(pwd->pw_name); + if (pwd == NULL) + if (errno == 0) + return itoa(uid); + else + 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) -{ - if (str_len < max_len) { - mvaddstr(row, col, str); - } else { - mvaddstr(row, col, ".."); - addnstr(str + 2, max_len - 2); - } +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 { + mvaddstr(row, col, ".."); + addnstr(str + 2, max_len - 2); + } } /** - * 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) -{ - if (str_len < max_len) { - mvaddstr(row, col, str); - } else { - mvaddnstr(row, col, str, max_len - 2); - addstr(".."); - } +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 { + mvaddnstr(row, col, str, max_len - 2); + addstr(".."); + } } -void Line::show (int row, unsigned int proglen) -{ - assert (m_pid >= 0); - assert (m_pid <= PID_MAX); +void Line::show(int row, unsigned int proglen) { + assert(m_pid >= 0); + assert(m_pid <= PID_MAX); - const int column_offset_pid = 0; - const int column_offset_user = column_offset_pid + COLUMN_WIDTH_PID + 1; - const int column_offset_program = column_offset_user + COLUMN_WIDTH_USER + 1; - 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_pid = 0; + const int column_offset_user = column_offset_pid + COLUMN_WIDTH_PID + 1; + const int column_offset_program = column_offset_user + COLUMN_WIDTH_USER + 1; + 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; - // PID column - if (m_pid == 0) - mvaddch (row, column_offset_pid + COLUMN_WIDTH_PID - 1, '?'); - else - mvprintw (row, column_offset_pid, COLUMN_FORMAT_PID, m_pid); + // PID column + if (m_pid == 0) + mvaddch(row, column_offset_pid + COLUMN_WIDTH_PID - 1, '?'); + else + 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); + std::string username = uid2username(m_uid); + 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); + mvaddstr(row, column_offset_dev, devicename); - mvprintw (row, column_offset_sent, COLUMN_FORMAT_SENT, sent_value); + mvprintw(row, column_offset_sent, COLUMN_FORMAT_SENT, sent_value); - mvprintw (row, column_offset_received, COLUMN_FORMAT_RECEIVED, recv_value); - if (viewMode == VIEWMODE_KBPS) - { - mvaddstr (row, column_offset_unit, "KB/sec"); - } - else if (viewMode == VIEWMODE_TOTAL_MB) - { - mvaddstr (row, column_offset_unit, "MB "); - } - else if (viewMode == VIEWMODE_TOTAL_KB) - { - mvaddstr (row, column_offset_unit, "KB "); - } - else if (viewMode == VIEWMODE_TOTAL_B) - { - mvaddstr (row, column_offset_unit, "B "); - } + mvprintw(row, column_offset_received, COLUMN_FORMAT_RECEIVED, recv_value); + if (viewMode == VIEWMODE_KBPS) { + mvaddstr(row, column_offset_unit, "KB/sec"); + } else if (viewMode == VIEWMODE_TOTAL_MB) { + mvaddstr(row, column_offset_unit, "MB "); + } else if (viewMode == VIEWMODE_TOTAL_KB) { + mvaddstr(row, column_offset_unit, "KB "); + } 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) -{ - Line ** pa = (Line **)ma; - Line ** pb = (Line **)mb; - Line * a = *pa; - Line * b = *pb; - double aValue; - if (sortRecv) - { - aValue = a->recv_value; - } - else - { - aValue = a->sent_value; - } +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) { + aValue = a->recv_value; + } else { + aValue = a->sent_value; + } - double bValue; - if (sortRecv) - { - bValue = b->recv_value; - } - else - { - bValue = b->sent_value; - } + double bValue; + if (sortRecv) { + bValue = b->recv_value; + } else { + bValue = b->sent_value; + } - if (aValue > bValue) - { - return -1; - } - if (aValue == bValue) - { - return 0; - } - return 1; + if (aValue > bValue) { + return -1; + } + if (aValue == bValue) { + return 0; + } + return 1; } -void init_ui () -{ - WINDOW * screen = initscr(); - raw(); - noecho(); - cbreak(); - nodelay(screen, TRUE); - caption = new std::string ("NetHogs"); - caption->append(getVersion()); - //caption->append(", running at "); +void init_ui() { + WINDOW *screen = initscr(); + raw(); + noecho(); + cbreak(); + nodelay(screen, TRUE); + caption = new std::string("NetHogs"); + caption->append(getVersion()); + // caption->append(", running at "); } -void exit_ui () -{ - clear(); - endwin(); - delete caption; +void exit_ui() { + clear(); + endwin(); + delete caption; } -void ui_tick () -{ - switch (getch()) { - case 'q': - /* quit */ - quit_cb(0); - break; - case 's': - /* sort on 'sent' */ - sortRecv = false; - break; - case 'r': - /* sort on 'received' */ - sortRecv = true; - break; - case 'm': - /* switch mode: total vs kb/s */ - viewMode = (viewMode + 1) % VIEWMODE_COUNT; - break; - } +void ui_tick() { + switch (getch()) { + case 'q': + /* quit */ + quit_cb(0); + break; + case 's': + /* sort on 'sent' */ + sortRecv = false; + break; + case 'r': + /* sort on 'received' */ + sortRecv = true; + break; + case 'm': + /* switch mode: total vs kb/s */ + viewMode = (viewMode + 1) % VIEWMODE_COUNT; + break; + } } -void show_trace(Line * lines[], int nproc) { - std::cout << "\nRefreshing:\n"; +void show_trace(Line *lines[], int nproc) { + std::cout << "\nRefreshing:\n"; - /* print them */ - for (int i=0; ilog(); - delete lines[i]; - } + /* print them */ + for (int i = 0; i < nproc; i++) { + lines[i]->log(); + delete lines[i]; + } - /* 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; + /* 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; - curr_unknownconn = curr_unknownconn->getNext(); - } + curr_unknownconn = curr_unknownconn->getNext(); + } } -void show_ncurses(Line * lines[], int nproc) { - int rows; // number of terminal rows - int cols; // number of terminal columns - unsigned int proglen; // max length of the "PROGRAM" column +void show_ncurses(Line *lines[], int nproc) { + int rows; // number of terminal rows + int cols; // number of terminal columns + unsigned int proglen; // max length of the "PROGRAM" column - double sent_global = 0; - double recv_global = 0; + double sent_global = 0; + double recv_global = 0; - getmaxyx(stdscr, rows, cols); /* find the boundaries of the screeen */ + getmaxyx(stdscr, rows, cols); /* find the boundaries of the screeen */ - if (cols < 62) { - clear(); - mvprintw(0,0, "The terminal is too narrow! Please make it wider.\nI'll wait..."); - return; - } + if (cols < 62) { + clear(); + 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; + 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"); - attroff(A_REVERSE); + clear(); + mvprintw(0, 0, "%s", caption->c_str()); + attron(A_REVERSE); + mvprintw(2, 0, + " PID USER %-*.*s DEV SENT RECEIVED ", + proglen, proglen, "PROGRAM"); + attroff(A_REVERSE); - /* print them */ - int i; - for (i=0; ishow(i+3, proglen); - recv_global += lines[i]->recv_value; - sent_global += lines[i]->sent_value; - delete lines[i]; - } + /* print them */ + int i; + for (i = 0; i < nproc; i++) { + if (i + 3 < rows) + lines[i]->show(i + 3, proglen); + recv_global += lines[i]->recv_value; + sent_global += lines[i]->sent_value; + delete lines[i]; + } - 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 (3+1+i, cols - COLUMN_WIDTH_UNIT, "KB/sec "); - } else if (viewMode == VIEWMODE_TOTAL_B) { - mvprintw (3+1+i, cols - COLUMN_WIDTH_UNIT, "B "); - } else if (viewMode == VIEWMODE_TOTAL_KB) { - mvprintw (3+1+i, cols - COLUMN_WIDTH_UNIT, "KB "); - } else if (viewMode == VIEWMODE_TOTAL_MB) { - mvprintw (3+1+i, cols - COLUMN_WIDTH_UNIT, "MB "); - } - attroff(A_REVERSE); - mvprintw (totalrow+1, 0, ""); - refresh(); + 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(3 + 1 + i, cols - COLUMN_WIDTH_UNIT, "KB/sec "); + } else if (viewMode == VIEWMODE_TOTAL_B) { + mvprintw(3 + 1 + i, cols - COLUMN_WIDTH_UNIT, "B "); + } else if (viewMode == VIEWMODE_TOTAL_KB) { + mvprintw(3 + 1 + i, cols - COLUMN_WIDTH_UNIT, "KB "); + } else if (viewMode == VIEWMODE_TOTAL_MB) { + mvprintw(3 + 1 + i, cols - COLUMN_WIDTH_UNIT, "MB "); + } + attroff(A_REVERSE); + mvprintw(totalrow + 1, 0, ""); + refresh(); } // Display all processes and relevant network traffic using show function -void do_refresh() -{ - refreshconninode(); - refreshcount++; +void do_refresh() { + refreshconninode(); + refreshcount++; - ProcList * curproc = processes; - ProcList * previousproc = NULL; - int nproc = processes->size(); - /* initialise to null pointers */ - Line * lines [nproc]; - int n = 0; + ProcList *curproc = processes; + ProcList *previousproc = NULL; + int nproc = processes->size(); + /* initialise to null pointers */ + Line *lines[nproc]; + int n = 0; #ifndef NDEBUG - // initialise to null pointers - for (int i = 0; i < nproc; i++) - lines[i] = NULL; + // initialise to null pointers + for (int i = 0; i < nproc; i++) + lines[i] = NULL; #endif - 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. - assert (curproc != NULL); - assert (curproc->getVal() != NULL); - assert (nproc == processes->size()); + 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. + assert(curproc != NULL); + 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)) - { - if (DEBUG) - std::cout << "PROC: Deleting process\n"; - ProcList * todelete = curproc; - Process * p_todelete = curproc->getVal(); - if (previousproc) - { - previousproc->next = curproc->next; - curproc = curproc->next; - } else { - processes = curproc->getNext(); - curproc = processes; - } - delete todelete; - delete p_todelete; - nproc--; - //continue; - } - else - { - // add a non-timed-out process to the list of stuff to show - float value_sent = 0, - value_recv = 0; + /* 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) { + previousproc->next = curproc->next; + curproc = curproc->next; + } else { + processes = curproc->getNext(); + curproc = processes; + } + delete todelete; + delete p_todelete; + nproc--; + // continue; + } else { + // add a non-timed-out process to the list of stuff to show + float value_sent = 0, value_recv = 0; - if (viewMode == VIEWMODE_KBPS) - { - //std::cout << "kbps viemode" << std::endl; - curproc->getVal()->getkbps (&value_recv, &value_sent); - } - 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) - { - //std::cout << "total viemode" << std::endl; - curproc->getVal()->gettotalmb(&value_recv, &value_sent); - } - else if (viewMode == VIEWMODE_TOTAL_B) - { - //std::cout << "total viemode" << std::endl; - curproc->getVal()->gettotalb(&value_recv, &value_sent); - } - else - { - forceExit(false, "Invalid viewMode: %d", viewMode); - } - uid_t uid = curproc->getVal()->getUid(); - assert (curproc->getVal()->pid >= 0); - assert (n < nproc); + if (viewMode == VIEWMODE_KBPS) { + // std::cout << "kbps viemode" << std::endl; + curproc->getVal()->getkbps(&value_recv, &value_sent); + } 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) { + // std::cout << "total viemode" << std::endl; + curproc->getVal()->gettotalmb(&value_recv, &value_sent); + } else if (viewMode == VIEWMODE_TOTAL_B) { + // std::cout << "total viemode" << std::endl; + curproc->getVal()->gettotalb(&value_recv, &value_sent); + } 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, - curproc->getVal()->pid, uid, curproc->getVal()->devicename); - previousproc = curproc; - curproc = curproc->next; - n++; + lines[n] = + new Line(curproc->getVal()->name, value_recv, value_sent, + curproc->getVal()->pid, uid, curproc->getVal()->devicename); + previousproc = curproc; + curproc = curproc->next; + n++; #ifndef NDEBUG - assert (nproc == processes->size()); - if (curproc == NULL) - assert (n-1 < nproc); - else - assert (n < nproc); + assert(nproc == processes->size()); + if (curproc == NULL) + assert(n - 1 < nproc); + else + assert(n < nproc); #endif - } - } + } + } - /* sort the accumulated lines */ - qsort (lines, nproc, sizeof(Line *), GreatestFirst); + /* sort the accumulated lines */ + qsort(lines, nproc, sizeof(Line *), GreatestFirst); - if (tracemode || DEBUG) - show_trace(lines, nproc); - else - show_ncurses(lines, nproc); + if (tracemode || DEBUG) + show_trace(lines, nproc); + else + show_ncurses(lines, nproc); - if (refreshlimit != 0 && refreshcount >= refreshlimit) - quit_cb(0); + if (refreshlimit != 0 && refreshcount >= refreshlimit) + quit_cb(0); } diff --git a/cui.h b/cui.h index 74e7dcf..4395b75 100644 --- a/cui.h +++ b/cui.h @@ -15,15 +15,16 @@ * * 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 */ -void do_refresh (); -void init_ui (); -void exit_ui (); +void do_refresh(); +void init_ui(); +void exit_ui(); /* periodically gives some CPU-time to the UI */ -void ui_tick (); +void ui_tick(); diff --git a/decpcap.c b/decpcap.c index b4c20e3..a829e71 100644 --- a/decpcap.c +++ b/decpcap.c @@ -1,4 +1,4 @@ -/* +/* * decpcap.c * * Copyright (c) 2004-2006,2011 Arnout Engelen @@ -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 #include #include @@ -34,304 +34,288 @@ /* 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)); - int i; - retval->pcap_handle = phandle; +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++) - { - retval->callback[i] = NULL; - } + for (i = 0; i < dp_n_packet_types; i++) { + retval->callback[i] = NULL; + } - retval->linktype = pcap_datalink(retval->pcap_handle); + retval->linktype = pcap_datalink(retval->pcap_handle); - switch (retval->linktype) { - case (DLT_EN10MB): - fprintf(stdout, "Ethernet link detected\n"); - break; - case (DLT_PPP): - fprintf(stdout, "PPP link detected\n"); - break; - case (DLT_LINUX_SLL): - fprintf(stdout, "Linux Cooked Socket link detected\n"); - break; - default: - fprintf(stdout, "No PPP or Ethernet link: %d\n", retval->linktype); - // TODO maybe error? or 'other' callback? - break; - } + switch (retval->linktype) { + case (DLT_EN10MB): + fprintf(stdout, "Ethernet link detected\n"); + break; + case (DLT_PPP): + fprintf(stdout, "PPP link detected\n"); + break; + case (DLT_LINUX_SLL): + fprintf(stdout, "Linux Cooked Socket link detected\n"); + break; + default: + fprintf(stdout, "No PPP or Ethernet link: %d\n", retval->linktype); + // TODO maybe error? or 'other' callback? + break; + } - return retval; + return retval; } -struct dp_handle * dp_open_offline(char * fname, char * ebuf) -{ - pcap_t * temp = pcap_open_offline(fname, ebuf); +struct dp_handle *dp_open_offline(char *fname, char *ebuf) { + pcap_t *temp = pcap_open_offline(fname, ebuf); - if (temp == NULL) - { - return NULL; - } + if (temp == NULL) { + return NULL; + } - return dp_fillhandle(temp); + return dp_fillhandle(temp); } -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); +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) - { - return NULL; - } + if (temp == NULL) { + return NULL; + } - return dp_fillhandle(temp); + return dp_fillhandle(temp); } /* functions to add callbacks */ -void dp_addcb (struct dp_handle * handle, enum dp_packet_type type, dp_callback callback) -{ - handle->callback[type] = 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) -{ - //const struct tcphdr * tcp = (struct tcphdr *) packet; - //u_char * payload = (u_char *) packet + sizeof (struct tcphdr); +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 (done) - return; - } - // TODO: maybe `pass on' payload to lower-level protocol parsing + 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) -{ - const struct ip * ip = (struct ip *) packet; - if (DP_DEBUG) - { - fprintf(stdout, "Looking at packet with length %ud\n", header->len); - } - u_char * payload = (u_char *) packet + sizeof (struct ip); +void dp_parse_ip(struct dp_handle *handle, const dp_header *header, + const u_char *packet) { + const struct ip *ip = (struct ip *)packet; + if (DP_DEBUG) { + fprintf(stdout, "Looking at packet with length %ud\n", header->len); + } + u_char *payload = (u_char *)packet + sizeof(struct ip); - if (handle->callback[dp_packet_ip] != NULL) - { - int done = (handle->callback[dp_packet_ip]) - (handle->userdata, header, packet); - if (done) - return; - } - switch (ip->ip_p) - { - case IPPROTO_TCP: - dp_parse_tcp (handle, header, payload); - break; - default: - // TODO: maybe support for non-tcp IP packets - break; - } + 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) { + case IPPROTO_TCP: + dp_parse_tcp(handle, header, payload); + break; + default: + // TODO: maybe support for non-tcp IP packets + break; + } } -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); +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 (done) - return; - } - switch ((ip6->ip6_ctlun).ip6_un1.ip6_un1_nxt) - { - case IPPROTO_TCP: - dp_parse_tcp (handle, header, payload); - break; - default: - // TODO: maybe support for non-tcp ipv6 packets - break; - } + 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) { + case IPPROTO_TCP: + dp_parse_tcp(handle, header, payload); + break; + default: + // TODO: maybe support for non-tcp ipv6 packets + break; + } } -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; +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); + /* call handle if it exists */ + 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) - return; - } + /* return if handle decides we're done */ + if (done) + return; + } - /* parse payload */ - protocol = ntohs(ethernet->ether_type); - switch (protocol) - { - case ETHERTYPE_IP: - dp_parse_ip (handle, header, payload); - break; - case ETHERTYPE_IPV6: - dp_parse_ip6 (handle, header, payload); - break; - default: - // TODO: maybe support for other protocols apart from IPv4 and IPv6 - break; - } + /* parse payload */ + protocol = ntohs(ethernet->ether_type); + switch (protocol) { + case ETHERTYPE_IP: + dp_parse_ip(handle, header, payload); + break; + case ETHERTYPE_IPV6: + dp_parse_ip6(handle, header, payload); + break; + default: + // TODO: maybe support for other protocols apart from IPv4 and IPv6 + break; + } } /* ppp header, i hope ;) */ /* glanced from ethereal, it's 16 bytes, and the payload packet type is * in the last 2 bytes... */ struct ppp_header { - u_int16_t dummy1; - u_int16_t dummy2; - u_int16_t dummy3; - u_int16_t dummy4; - u_int16_t dummy5; - u_int16_t dummy6; - u_int16_t dummy7; + u_int16_t dummy1; + u_int16_t dummy2; + u_int16_t dummy3; + u_int16_t dummy4; + u_int16_t dummy5; + u_int16_t dummy6; + u_int16_t dummy7; - u_int16_t packettype; + u_int16_t packettype; }; -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; +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); + /* call handle if it exists */ + 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) - return; - } + /* return if handle decides we're done */ + if (done) + return; + } - /* parse payload */ - protocol = ntohs(ppp->packettype); - switch (protocol) - { - case ETHERTYPE_IP: - dp_parse_ip (handle, header, payload); - break; - case ETHERTYPE_IPV6: - dp_parse_ip6 (handle, header, payload); - break; - default: - // TODO: support for other than IPv4 and IPv6 - break; - } + /* parse payload */ + protocol = ntohs(ppp->packettype); + switch (protocol) { + case ETHERTYPE_IP: + dp_parse_ip(handle, header, payload); + break; + case ETHERTYPE_IPV6: + dp_parse_ip6(handle, header, payload); + break; + default: + // TODO: support for other than IPv4 and IPv6 + break; + } } /* linux cooked header, i hope ;) */ /* glanced from libpcap/ssl.h */ -#define SLL_ADDRLEN 8 /* length of address field */ +#define SLL_ADDRLEN 8 /* length of address field */ struct sll_header { - u_int16_t sll_pkttype; /* packet type */ - u_int16_t sll_hatype; /* link-layer address type */ - u_int16_t sll_halen; /* link-layer address length */ - u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ - u_int16_t sll_protocol; /* protocol */ + u_int16_t sll_pkttype; /* packet type */ + u_int16_t sll_hatype; /* link-layer address type */ + u_int16_t sll_halen; /* link-layer address length */ + u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ + u_int16_t sll_protocol; /* protocol */ }; -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; +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); + /* call handle if it exists */ + 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) - return; - } + /* return if handle decides we're done */ + if (done) + return; + } - /* parse payload */ - protocol = ntohs(sll->sll_protocol); - switch (protocol) - { - case ETHERTYPE_IP: - dp_parse_ip (handle, header, payload); - break; - case ETHERTYPE_IPV6: - dp_parse_ip6 (handle, header, payload); - break; - default: - // TODO: support for other than IPv4 / IPv6 - break; - } + /* parse payload */ + protocol = ntohs(sll->sll_protocol); + switch (protocol) { + case ETHERTYPE_IP: + dp_parse_ip(handle, header, payload); + break; + case ETHERTYPE_IPV6: + dp_parse_ip6(handle, header, payload); + break; + default: + // TODO: support for other than IPv4 / IPv6 + break; + } } /* functions to do the monitoring */ -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; +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; - /* make a copy of the userdata for every packet */ - u_char * userdata_copy = (u_char *) malloc (handle->userdata_size); - memcpy (userdata_copy, handle->userdata, handle->userdata_size); + /* make a copy of the userdata for every packet */ + u_char *userdata_copy = (u_char *)malloc(handle->userdata_size); + memcpy(userdata_copy, handle->userdata, handle->userdata_size); - switch (handle->linktype) { - case (DLT_EN10MB): - dp_parse_ethernet (handle, header, packet); - break; - case (DLT_PPP): - dp_parse_ppp (handle, header, packet); - break; - case (DLT_LINUX_SLL): - dp_parse_linux_cooked (handle, header, packet); - break; - case (DLT_RAW): - case (DLT_NULL): - // hope for the best - dp_parse_ip (handle, header, packet); - break; - default: - fprintf(stdout, "Unknown linktype %d", handle->linktype); - break; - } - free (userdata_copy); + switch (handle->linktype) { + case (DLT_EN10MB): + dp_parse_ethernet(handle, header, packet); + break; + case (DLT_PPP): + dp_parse_ppp(handle, header, packet); + break; + case (DLT_LINUX_SLL): + dp_parse_linux_cooked(handle, header, packet); + break; + case (DLT_RAW): + case (DLT_NULL): + // hope for the best + dp_parse_ip(handle, header, packet); + break; + default: + fprintf(stdout, "Unknown linktype %d", handle->linktype); + break; + } + free(userdata_copy); } -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); +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); } -int dp_setnonblock (struct dp_handle * handle, int i, char * errbuf) { - return pcap_setnonblock (handle->pcap_handle, i, errbuf); +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) -{ - return pcap_geterr (handle->pcap_handle); +char *dp_geterr(struct dp_handle *handle) { + return pcap_geterr(handle->pcap_handle); } diff --git a/decpcap.h b/decpcap.h index e0a9614..b23de5c 100644 --- a/decpcap.h +++ b/decpcap.h @@ -1,4 +1,4 @@ -/* +/* * decpcap.h * * Copyright (c) 2004-2006,2011 Arnout Engelen @@ -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 @@ -30,20 +31,20 @@ /* definitions */ enum dp_packet_type { - dp_packet_ethernet, - dp_packet_ppp, - dp_packet_sll, - dp_packet_ip, - dp_packet_ip6, - dp_packet_tcp, - dp_packet_udp, - dp_n_packet_types + dp_packet_ethernet, + dp_packet_ppp, + dp_packet_sll, + dp_packet_ip, + dp_packet_ip6, + dp_packet_tcp, + dp_packet_udp, + dp_n_packet_types }; /*enum dp_link_type { - dp_link_ethernet, - dp_link_ppp, - dp_n_link_types + dp_link_ethernet, + dp_link_ppp, + dp_n_link_types };*/ /*struct dp_header { @@ -54,36 +55,38 @@ typedef struct pcap_pkthdr dp_header; typedef int (*dp_callback)(u_char *, const dp_header *, const u_char *); struct dp_handle { - pcap_t * pcap_handle; - dp_callback callback [dp_n_packet_types]; - int linktype; - u_char * userdata; - int userdata_size; + pcap_t *pcap_handle; + dp_callback callback[dp_n_packet_types]; + int linktype; + u_char *userdata; + int userdata_size; }; /* 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_offline(char * fname, char * ebuf); +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 */ -void dp_parse (enum dp_packet_type type, void * packet); +void dp_parse(enum dp_packet_type type, void *packet); /* functions to start monitoring */ -int dp_dispatch (struct dp_handle * handler, int count, u_char *user, int size); +int dp_dispatch(struct dp_handle *handler, int count, u_char *user, int size); /* functions that simply call libpcap */ -int dp_datalink(struct dp_handle * handle); +int dp_datalink(struct dp_handle *handle); -int dp_setnonblock (struct dp_handle * handle, int i, char * errbuf); +int dp_setnonblock(struct dp_handle *handle, int i, char *errbuf); -char * dp_geterr (struct dp_handle * handle); +char *dp_geterr(struct dp_handle *handle); #endif diff --git a/decpcap_test.cpp b/decpcap_test.cpp index c6d85e9..5e7923a 100644 --- a/decpcap_test.cpp +++ b/decpcap_test.cpp @@ -1,4 +1,4 @@ -/* +/* * decpcap_test.cpp * * Copyright (c) 2006,2011 Arnout Engelen @@ -15,36 +15,34 @@ * * 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 extern "C" { - #include "decpcap.h" +#include "decpcap.h" } -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 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) - { - std::cout << "Please, enter a filename" << std::endl; - } +int main(int argc, char **argv) { + if (argc < 2) { + std::cout << "Please, enter a filename" << std::endl; + } - char* errbuf = new char[DP_ERRBUF_SIZE]; + char *errbuf = new char[DP_ERRBUF_SIZE]; - dp_handle * newhandle = dp_open_offline(argv[1], errbuf); - dp_addcb (newhandle, dp_packet_tcp, process_tcp); - int ret = dp_dispatch (newhandle, -1, NULL, 0); - if (ret == -1) - { - std::cout << "Error dispatching: " << dp_geterr(newhandle); - } + 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) { + std::cout << "Error dispatching: " << dp_geterr(newhandle); + } } diff --git a/devices.cpp b/devices.cpp index a314c34..5c48927 100644 --- a/devices.cpp +++ b/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. * */ @@ -28,69 +29,63 @@ #include #include -bool selected(int devc, char** devicenames, char* devicename) { - if (devc == 0) - return true; +bool selected(int devc, char **devicenames, char *devicename) { + if (devc == 0) + return true; - for (int i = 0; i < devc; i++) - if (strcmp(devicenames[i], devicename) == 0) - return true; + for (int i = 0; i < devc; i++) + if (strcmp(devicenames[i], devicename) == 0) + return true; - return false; + return false; } -bool already_seen(device* devices, char* devicename) { - for (class device* current_device = devices; - current_device != NULL; - current_device = current_device->next) { - if (strcmp(current_device->name, devicename) == 0) - return true; - } - return false; +bool already_seen(device *devices, char *devicename) { + for (class device *current_device = devices; current_device != NULL; + current_device = current_device->next) { + if (strcmp(current_device->name, devicename) == 0) + return true; + } + return false; } // 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) && - (ifa_flags & IFF_RUNNING); + std::cout << "up: " << (ifa_flags & IFF_UP) << std::endl; + 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) -{ - struct ifaddrs *ifaddr, *ifa; +device *get_devices(int devc, char **devicenames, bool all) { + struct ifaddrs *ifaddr, *ifa; - if (getifaddrs(&ifaddr) == -1) - { - std::cerr << "Fail to get interface addresses" << std::endl; - // perror("getifaddrs"); - return NULL; - } + 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) - { - if (ifa->ifa_addr == NULL) - continue; - if (!selected(devc, devicenames, ifa->ifa_name)) - continue; - if (already_seen(devices, ifa->ifa_name)) - continue; - if (!all && !up_running(ifa->ifa_flags)) - continue; + device *devices = NULL; + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) + continue; + if (!selected(devc, devicenames, ifa->ifa_name)) + continue; + if (already_seen(devices, ifa->ifa_name)) + continue; + if (!all && !up_running(ifa->ifa_flags)) + continue; - devices = new device(strdup(ifa->ifa_name),devices); - } + devices = new device(strdup(ifa->ifa_name), devices); + } - freeifaddrs(ifaddr); - return devices; + freeifaddrs(ifaddr); + return devices; } -device * get_default_devices() { - return get_devices(0, NULL, false); -} +device *get_default_devices() { return get_devices(0, NULL, false); } diff --git a/devices.h b/devices.h index 27a6ffc..46cd891 100644 --- a/devices.h +++ b/devices.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. * */ @@ -26,16 +27,16 @@ class device { public: - device (const char * m_name, device * m_next = NULL) - { - name = m_name; next = m_next; - } - const char * name; - device * next; + device(const char *m_name, device *m_next = NULL) { + name = m_name; + next = m_next; + } + const char *name; + device *next; }; /** get all devices that are up, running and not loopback */ -device * get_default_devices(); +device *get_default_devices(); /** * Get all specified devices. @@ -44,6 +45,6 @@ device * get_default_devices(); * when 'all' is set, also return loopback interfaces and interfaces * that are down or not running */ -device * get_devices(int devc, char** devv, bool all); +device *get_devices(int devc, char **devv, bool all); #endif diff --git a/inode2prog.cpp b/inode2prog.cpp index 50bf27f..0da8484 100644 --- a/inode2prog.cpp +++ b/inode2prog.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 #include #include @@ -42,212 +42,208 @@ 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//fd/*. These are numeric, so 10 digits seems like a safe assumption. +// Max length of filenames in /proc//fd/*. These are numeric, so 10 digits +// seems like a safe assumption. const int MAX_FDLINK = 10; /* maps from inode to program-struct */ -std::map inodeproc; +std::map inodeproc; -bool is_number (const char * string) { - while (*string) { - if (!isdigit (*string)) - return false; - string++; - } - return true; +bool is_number(const char *string) { + while (*string) { + if (!isdigit(*string)) + return false; + string++; + } + return true; } -unsigned long str2ulong (const char * ptr) { - unsigned long retval = 0; +unsigned long str2ulong(const char *ptr) { + unsigned long retval = 0; - while ((*ptr >= '0') && (*ptr <= '9')) { - retval *= 10; - retval += *ptr - '0'; - ptr++; - } - return retval; + while ((*ptr >= '0') && (*ptr <= '9')) { + retval *= 10; + retval += *ptr - '0'; + ptr++; + } + return retval; } -int str2int (const char * ptr) { - int retval = 0; +int str2int(const char *ptr) { + int retval = 0; - while ((*ptr >= '0') && (*ptr <= '9')) { - retval *= 10; - retval += *ptr - '0'; - ptr++; - } - return retval; + while ((*ptr >= '0') && (*ptr <= '9')) { + retval *= 10; + retval += *ptr - '0'; + ptr++; + } + return retval; } -static std::string read_file (int fd) { - char buf[255]; - std::string content; +static std::string read_file(int fd) { + char buf[255]; + std::string content; - for (int length; (length = read(fd, buf, sizeof(buf))) > 0;) { - if (length < 0) { - std::fprintf(stderr, "Error reading file: %s\n", std::strerror(errno)); - std::exit(34); - } - content.append(buf, length); - } + for (int length; (length = read(fd, buf, sizeof(buf))) > 0;) { + if (length < 0) { + std::fprintf(stderr, "Error reading file: %s\n", std::strerror(errno)); + std::exit(34); + } + content.append(buf, length); + } - return content; + return content; } -static std::string read_file (const char* filepath) { - int fd = open(filepath, O_RDONLY); +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::exit(3); - return NULL; - } + if (fd < 0) { + std::fprintf(stderr, "Error opening %s: %s\n", filepath, + std::strerror(errno)); + std::exit(3); + return NULL; + } - std::string contents = read_file(fd); + std::string contents = read_file(fd); - if (close(fd)) { - std::fprintf(stderr, "Error opening %s: %s\n", filepath, std::strerror(errno)); - std::exit(34); - } + if (close(fd)) { + std::fprintf(stderr, "Error opening %s: %s\n", filepath, + std::strerror(errno)); + std::exit(34); + } - return contents; + return contents; } -std::string getprogname (pid_t pid) { - const int maxfilenamelen = 14 + MAX_PID_LENGTH + 1; - char filename[maxfilenamelen]; +std::string getprogname(pid_t pid) { + const int maxfilenamelen = 14 + MAX_PID_LENGTH + 1; + char filename[maxfilenamelen]; - std::snprintf(filename, maxfilenamelen, "/proc/%d/cmdline", pid); - return read_file(filename); + std::snprintf(filename, maxfilenamelen, "/proc/%d/cmdline", pid); + return read_file(filename); } -void setnode (unsigned long inode, pid_t pid) { - prg_node * current_value = inodeproc[inode]; +void setnode(unsigned long inode, pid_t pid) { + prg_node *current_value = inodeproc[inode]; - if (current_value == NULL || current_value->pid != pid) { - prg_node * newnode = new prg_node; - newnode->inode = inode; - newnode->pid = pid; - newnode->name = getprogname(pid); + if (current_value == NULL || current_value->pid != pid) { + prg_node *newnode = new prg_node; + newnode->inode = inode; + newnode->pid = pid; + newnode->name = getprogname(pid); - inodeproc[inode] = newnode; - delete current_value; - } + inodeproc[inode] = newnode; + delete current_value; + } } -void get_info_by_linkname (const char * pid, const char * linkname) { - if (strncmp(linkname, "socket:[", 8) == 0) { - setnode(str2ulong(linkname + 8), str2int(pid)); - } +void get_info_by_linkname(const char *pid, const char *linkname) { + if (strncmp(linkname, "socket:[", 8) == 0) { + setnode(str2ulong(linkname + 8), str2int(pid)); + } } /* updates the `inodeproc' inode-to-prg_node * for all inodes belonging to this PID * (/proc/pid/fd/42) * */ -void get_info_for_pid(const char * pid) { - char dirname[10 + MAX_PID_LENGTH]; +void get_info_for_pid(const char *pid) { + char dirname[10 + MAX_PID_LENGTH]; - size_t dirlen = 10 + strlen(pid); - snprintf(dirname, dirlen, "/proc/%s/fd", pid); + size_t dirlen = 10 + strlen(pid); + snprintf(dirname, dirlen, "/proc/%s/fd", pid); - DIR * dir = opendir(dirname); + DIR *dir = opendir(dirname); - if (!dir) - { - if (bughuntmode) - { - std::cout << "Couldn't open dir " << dirname << ": " << strerror(errno) << "\n"; - } - return; - } + if (!dir) { + if (bughuntmode) { + std::cout << "Couldn't open dir " << dirname << ": " << strerror(errno) + << "\n"; + } + return; + } - /* walk through /proc/%s/fd/... */ - dirent * entry; - while ((entry = readdir(dir))) { - if (entry->d_type != DT_LNK) - continue; - //std::cout << "Looking at: " << entry->d_name << std::endl; + /* walk through /proc/%s/fd/... */ + dirent *entry; + while ((entry = readdir(dir))) { + if (entry->d_type != DT_LNK) + continue; + // std::cout << "Looking at: " << entry->d_name << std::endl; - size_t fromlen = dirlen + strlen(entry->d_name) + 1; - char fromname[10 + MAX_PID_LENGTH + 1 + MAX_FDLINK]; - snprintf (fromname, fromlen, "%s/%s", dirname, entry->d_name); + size_t fromlen = dirlen + strlen(entry->d_name) + 1; + char fromname[10 + MAX_PID_LENGTH + 1 + MAX_FDLINK]; + snprintf(fromname, fromlen, "%s/%s", dirname, entry->d_name); - //std::cout << "Linking from: " << fromname << std::endl; + // std::cout << "Linking from: " << fromname << std::endl; - int linklen = 80; - char linkname [linklen]; - int usedlen = readlink(fromname, linkname, linklen-1); - if (usedlen == -1) - { - continue; - } - assert (usedlen < linklen); - linkname[usedlen] = '\0'; - get_info_by_linkname (pid, linkname); - } - closedir(dir); + int linklen = 80; + char linkname[linklen]; + int usedlen = readlink(fromname, linkname, linklen - 1); + if (usedlen == -1) { + continue; + } + assert(usedlen < linklen); + linkname[usedlen] = '\0'; + get_info_by_linkname(pid, linkname); + } + closedir(dir); } /* updates the `inodeproc' inode-to-prg_node mapping * for all processes in /proc */ -void reread_mapping () { - DIR * proc = opendir ("/proc"); +void reread_mapping() { + DIR *proc = opendir("/proc"); - if (proc == 0) { - std::cerr << "Error reading /proc, neede to get inode-to-pid-maping\n"; - exit(1); - } + if (proc == 0) { + std::cerr << "Error reading /proc, neede to get inode-to-pid-maping\n"; + exit(1); + } - dirent * entry; + dirent *entry; - while ((entry = readdir(proc))) { - if (entry->d_type != DT_DIR) continue; + while ((entry = readdir(proc))) { + 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); + get_info_for_pid(entry->d_name); + } + closedir(proc); } -struct prg_node * findPID (unsigned long inode) -{ - /* we first look in inodeproc */ - struct prg_node * node = inodeproc[inode]; +struct prg_node *findPID(unsigned long inode) { + /* we first look in inodeproc */ + struct prg_node *node = inodeproc[inode]; - if (node != NULL) - { - if (bughuntmode) - { - std::cout << ":) Found pid in inodeproc table" << std::endl; - } - return node; - } + if (node != NULL) { + if (bughuntmode) { + std::cout << ":) Found pid in inodeproc table" << std::endl; + } + return node; + } - #ifndef __APPLE__ - reread_mapping(); - #endif +#ifndef __APPLE__ + reread_mapping(); +#endif - struct prg_node * retval = inodeproc[inode]; - if (bughuntmode) - { - if (retval == NULL) - { - std::cout << ":( No pid after inodeproc refresh" << std::endl; - } - else - { - std::cout << ":) Found pid after inodeproc refresh" << std::endl; - } - } - return retval; + struct prg_node *retval = inodeproc[inode]; + if (bughuntmode) { + if (retval == NULL) { + std::cout << ":( No pid after inodeproc refresh" << std::endl; + } else { + std::cout << ":) Found pid after inodeproc refresh" << std::endl; + } + } + return retval; } -void prg_cache_clear() {}; +void prg_cache_clear(){}; /*void main () { - std::cout << "Fooo\n"; - reread_mapping(); - std::cout << "Haihai\n"; + std::cout << "Fooo\n"; + reread_mapping(); + std::cout << "Haihai\n"; }*/ diff --git a/inode2prog.h b/inode2prog.h index e66443d..2a3ad8f 100644 --- a/inode2prog.h +++ b/inode2prog.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 __INODE2PROG_h @@ -28,16 +29,16 @@ #include "nethogs.h" struct prg_node { - long inode; - pid_t pid; - std::string name; + long inode; + pid_t pid; + std::string name; }; -struct prg_node * findPID (unsigned long inode); +struct prg_node *findPID(unsigned long inode); void prg_cache_clear(); // reread the inode-to-prg_node-mapping -void reread_mapping (); +void reread_mapping(); #endif diff --git a/libnethogs.cpp b/libnethogs.cpp index 4f6bc9d..51e8cae 100644 --- a/libnethogs.cpp +++ b/libnethogs.cpp @@ -1,6 +1,5 @@ -extern "C" -{ - #include "libnethogs.h" +extern "C" { +#include "libnethogs.h" } #include "nethogs.cpp" @@ -13,359 +12,318 @@ extern "C" #include ////////////////////////////// -extern ProcList * processes; -extern Process * unknowntcp; -extern Process * unknownudp; -extern Process * unknownip; +extern ProcList *processes; +extern Process *unknowntcp; +extern Process *unknownudp; +extern Process *unknownip; ////////////////////////////// -//The self_pipe is used to interrupt the select() in the main loop -static std::pair self_pipe = std::make_pair(-1, -1); +// The self_pipe is used to interrupt the select() in the main loop +static std::pair self_pipe = std::make_pair(-1, -1); static bool monitor_run_flag = false; -typedef std::map NethogsRecordMap; +typedef std::map NethogsRecordMap; static NethogsRecordMap monitor_record_map; static int monitor_refresh_delay = 1; static time_t monitor_last_refresh_time = 0; -//selectable file descriptors for the main loop +// selectable file descriptors for the main loop static fd_set pc_loop_fd_set; static std::vector pc_loop_fd_list; static bool pc_loop_use_select = true; -static handle * handles = NULL; +static handle *handles = NULL; -static std::pair create_self_pipe() -{ - int pfd[2]; - if (pipe(pfd) == -1) - return std::make_pair(-1, -1); +static std::pair create_self_pipe() { + int pfd[2]; + if (pipe(pfd) == -1) + return std::make_pair(-1, -1); - if (fcntl(pfd[0], F_SETFL, fcntl(pfd[0], F_GETFL) | O_NONBLOCK) == -1) - return std::make_pair(-1, -1); + if (fcntl(pfd[0], F_SETFL, fcntl(pfd[0], F_GETFL) | O_NONBLOCK) == -1) + return std::make_pair(-1, -1); - if (fcntl(pfd[1], F_SETFL, fcntl(pfd[1], F_GETFL) | O_NONBLOCK) == -1) - return std::make_pair(-1, -1); + if (fcntl(pfd[1], F_SETFL, fcntl(pfd[1], F_GETFL) | O_NONBLOCK) == -1) + return std::make_pair(-1, -1); - return std::make_pair(pfd[0], pfd[1]); + return std::make_pair(pfd[0], pfd[1]); } -static bool wait_for_next_trigger() -{ - if( pc_loop_use_select ) - { - FD_ZERO(&pc_loop_fd_set); - int nfds = 0; - for(std::vector::const_iterator it=pc_loop_fd_list.begin(); - 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) ) - { - return false; - } - } - } - else - { - // If select() not possible, pause to prevent 100% - usleep(1000); - } - return true; +static bool wait_for_next_trigger() { + if (pc_loop_use_select) { + FD_ZERO(&pc_loop_fd_set); + int nfds = 0; + for (std::vector::const_iterator it = pc_loop_fd_list.begin(); + 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)) { + return false; + } + } + } else { + // If select() not possible, pause to prevent 100% + usleep(1000); + } + return true; } -static int nethogsmonitor_init() -{ - process_init(); +static int nethogsmonitor_init() { + process_init(); - device * devices = get_default_devices(); - if ( devices == NULL ) - { - std::cerr << "No devices to monitor" << std::endl; - return NETHOGS_STATUS_NO_DEVICE; - } + device *devices = get_default_devices(); + if (devices == NULL) { + std::cerr << "No devices to monitor" << std::endl; + return NETHOGS_STATUS_NO_DEVICE; + } - device * current_dev = devices; + device *current_dev = devices; - bool promiscuous = false; + bool promiscuous = false; - int nb_devices = 0; - int nb_failed_devices = 0; + int nb_devices = 0; + int nb_failed_devices = 0; - while (current_dev != NULL) - { - ++nb_devices; + while (current_dev != NULL) { + ++nb_devices; - if( !getLocal(current_dev->name, false) ) - { - std::cerr << "getifaddrs failed while establishing local IP." << std::endl; - ++nb_failed_devices; - continue; - } + 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_addcb (newhandle, dp_packet_ip, process_ip); - dp_addcb (newhandle, dp_packet_ip6, process_ip6); - dp_addcb (newhandle, dp_packet_tcp, process_tcp); - dp_addcb (newhandle, dp_packet_udp, process_udp); + char errbuf[PCAP_ERRBUF_SIZE]; + 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); + dp_addcb(newhandle, dp_packet_udp, process_udp); - /* The following code solves sf.net bug 1019381, but is only available - * in newer versions (from 0.8 it seems) of libpcap - * - * update: version 0.7.2, which is in debian stable now, should be ok - * also. - */ - if (dp_setnonblock (newhandle, 1, errbuf) == -1) - { - fprintf(stderr, "Error putting libpcap in nonblocking mode\n"); - } - handles = new handle (newhandle, current_dev->name, handles); + /* The following code solves sf.net bug 1019381, but is only available + * in newer versions (from 0.8 it seems) of libpcap + * + * update: version 0.7.2, which is in debian stable now, should be ok + * also. + */ + 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 ) - { - //some devices may not support pcap_get_selectable_fd - int const fd = pcap_get_selectable_fd(newhandle->pcap_handle); - if( fd != -1 ) - { - pc_loop_fd_list.push_back(fd); - } - else - { - pc_loop_use_select = false; - pc_loop_fd_list.clear(); - 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)); - ++nb_failed_devices; - } + 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) { + pc_loop_fd_list.push_back(fd); + } else { + pc_loop_use_select = false; + pc_loop_fd_list.clear(); + 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)); + ++nb_failed_devices; + } - current_dev = current_dev->next; - } + current_dev = current_dev->next; + } - if(nb_devices == nb_failed_devices) - { - return NETHOGS_STATUS_FAILURE; - } + 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 ) - { - self_pipe = create_self_pipe(); - if( self_pipe.first == -1 || self_pipe.second == -1 ) - { - std::cerr << "Error creating pipe file descriptors\n"; - pc_loop_use_select = false; - } - else - { - pc_loop_fd_list.push_back(self_pipe.first); - } - } + // use the Self-Pipe trick to interrupt the select() in the main loop + if (pc_loop_use_select) { + self_pipe = create_self_pipe(); + if (self_pipe.first == -1 || self_pipe.second == -1) { + std::cerr << "Error creating pipe file descriptors\n"; + pc_loop_use_select = false; + } else { + pc_loop_fd_list.push_back(self_pipe.first); + } + } - return NETHOGS_STATUS_OK; + return NETHOGS_STATUS_OK; } -static void nethogsmonitor_handle_update(NethogsMonitorCallback cb) -{ - refreshconninode(); - refreshcount++; +static void nethogsmonitor_handle_update(NethogsMonitorCallback cb) { + refreshconninode(); + refreshcount++; - ProcList * curproc = processes; - ProcList * previousproc = NULL; - int nproc = processes->size(); + ProcList *curproc = processes; + ProcList *previousproc = NULL; + int nproc = processes->size(); - 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. - assert (curproc != NULL); - assert (curproc->getVal() != NULL); - assert (nproc == processes->size()); + 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. + assert(curproc != NULL); + 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)) - { - if (DEBUG) - std::cout << "PROC: Deleting process\n"; + /* 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() ) - { - NethogsMonitorRecord& data = it->second; - (*cb)(NETHOGS_APP_ACTION_REMOVE, &data); - monitor_record_map.erase(curproc); - } + NethogsRecordMap::iterator it = monitor_record_map.find(curproc); + if (it != monitor_record_map.end()) { + NethogsMonitorRecord &data = it->second; + (*cb)(NETHOGS_APP_ACTION_REMOVE, &data); + monitor_record_map.erase(curproc); + } - ProcList * todelete = curproc; - Process * p_todelete = curproc->getVal(); - if (previousproc) - { - previousproc->next = curproc->next; - curproc = curproc->next; - } else - { - processes = curproc->getNext(); - curproc = processes; - } - delete todelete; - delete p_todelete; - nproc--; - //continue; - } - else - { - const u_int32_t uid = curproc->getVal()->getUid(); - u_int32_t sent_bytes; - u_int32_t recv_bytes; - float sent_kbs; - float recv_kbs; - curproc->getVal()->getkbps (&recv_kbs, &sent_kbs); - curproc->getVal()->gettotal (&recv_bytes, &sent_bytes); + ProcList *todelete = curproc; + Process *p_todelete = curproc->getVal(); + if (previousproc) { + previousproc->next = curproc->next; + curproc = curproc->next; + } else { + processes = curproc->getNext(); + curproc = processes; + } + delete todelete; + delete p_todelete; + nproc--; + // continue; + } else { + const u_int32_t uid = curproc->getVal()->getUid(); + u_int32_t sent_bytes; + u_int32_t recv_bytes; + float sent_kbs; + float recv_kbs; + curproc->getVal()->getkbps(&recv_kbs, &sent_kbs); + curproc->getVal()->gettotal(&recv_bytes, &sent_bytes); - //notify update - bool const new_data = (monitor_record_map.find(curproc) == monitor_record_map.end()); - NethogsMonitorRecord &data = monitor_record_map[curproc]; + // notify update + 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 ) - { - data_change = true; - static int record_id = 0; - ++record_id; - memset(&data, 0, sizeof(data)); - data.record_id = record_id; - data.name = curproc->getVal()->name; - data.pid = curproc->getVal()->pid; - } + bool data_change = false; + if (new_data) { + data_change = true; + static int record_id = 0; + ++record_id; + memset(&data, 0, sizeof(data)); + data.record_id = record_id; + data.name = curproc->getVal()->name; + data.pid = curproc->getVal()->pid; + } - data.device_name = curproc->getVal()->devicename; + 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 ) - NHM_UPDATE_ONE_FIELD( data.recv_bytes, recv_bytes ) - NHM_UPDATE_ONE_FIELD( data.sent_kbs, sent_kbs ) - NHM_UPDATE_ONE_FIELD( data.recv_kbs, recv_kbs ) + NHM_UPDATE_ONE_FIELD(data.uid, uid) + NHM_UPDATE_ONE_FIELD(data.sent_bytes, sent_bytes) + NHM_UPDATE_ONE_FIELD(data.recv_bytes, recv_bytes) + NHM_UPDATE_ONE_FIELD(data.sent_kbs, sent_kbs) + NHM_UPDATE_ONE_FIELD(data.recv_kbs, recv_kbs) - #undef NHM_UPDATE_ONE_FIELD +#undef NHM_UPDATE_ONE_FIELD - if( data_change ) - { - (*cb)(NETHOGS_APP_ACTION_SET, &data); - } + if (data_change) { + (*cb)(NETHOGS_APP_ACTION_SET, &data); + } - //next - previousproc = curproc; - curproc = curproc->next; - } - } + // next + previousproc = curproc; + curproc = curproc->next; + } + } } -static void nethogsmonitor_clean_up() -{ - //clean up - handle * current_handle = handles; - while (current_handle != NULL) - { - pcap_close(current_handle->content->pcap_handle); - current_handle = current_handle->next; - } +static void nethogsmonitor_clean_up() { + // clean up + handle *current_handle = handles; + while (current_handle != NULL) { + pcap_close(current_handle->content->pcap_handle); + current_handle = current_handle->next; + } - //close file descriptors - for(std::vector::const_iterator it=pc_loop_fd_list.begin(); - it != pc_loop_fd_list.end(); ++it) - { - close(*it); - } + // close file descriptors + for (std::vector::const_iterator it = pc_loop_fd_list.begin(); + it != pc_loop_fd_list.end(); ++it) { + close(*it); + } - procclean(); + procclean(); } -int nethogsmonitor_loop(NethogsMonitorCallback cb) -{ - if( monitor_run_flag ) - { - return NETHOGS_STATUS_FAILURE; - } +int nethogsmonitor_loop(NethogsMonitorCallback cb) { + if (monitor_run_flag) { + return NETHOGS_STATUS_FAILURE; + } - int return_value = nethogsmonitor_init(); - if( return_value != NETHOGS_STATUS_OK ) - { - return return_value; - } + int return_value = nethogsmonitor_init(); + if (return_value != NETHOGS_STATUS_OK) { + return return_value; + } - monitor_run_flag = true; + monitor_run_flag = true; - struct dpargs * userdata = (dpargs *) malloc (sizeof (struct dpargs)); + struct dpargs *userdata = (dpargs *)malloc(sizeof(struct dpargs)); - // Main loop - while (monitor_run_flag) - { - bool packets_read = false; + // Main loop + while (monitor_run_flag) { + bool packets_read = false; - handle * current_handle = handles; - 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) - { - std::cerr << "Error dispatching: " << retval << std::endl; - } - else if (retval != 0) - { - packets_read = true; - } - else - { - gettimeofday(&curtime, NULL); - } - current_handle = current_handle->next; - } + handle *current_handle = handles; + 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) { + std::cerr << "Error dispatching: " << retval << std::endl; + } else if (retval != 0) { + packets_read = true; + } else { + gettimeofday(&curtime, NULL); + } + current_handle = current_handle->next; + } - time_t const now = ::time(NULL); - if( monitor_last_refresh_time + monitor_refresh_delay <= now ) - { - monitor_last_refresh_time = now; - nethogsmonitor_handle_update(cb); - } + time_t const now = ::time(NULL); + 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() ) - { - break; - } - } - } + if (!packets_read) { + if (!wait_for_next_trigger()) { + break; + } + } + } - nethogsmonitor_clean_up(); + nethogsmonitor_clean_up(); - return NETHOGS_STATUS_OK; + return NETHOGS_STATUS_OK; } -void nethogsmonitor_breakloop() -{ - monitor_run_flag = false; - write(self_pipe.second, "x", 1); +void nethogsmonitor_breakloop() { + monitor_run_flag = false; + write(self_pipe.second, "x", 1); } diff --git a/libnethogs.h b/libnethogs.h index afde2a4..868019d 100644 --- a/libnethogs.h +++ b/libnethogs.h @@ -8,46 +8,51 @@ extern "C" { #include #include -#define NETHOGS_DSO_VISIBLE __attribute__ ((visibility ("default"))) -#define NETHOGS_DSO_HIDDEN __attribute__ ((visibility ("hidden"))) +#define NETHOGS_DSO_VISIBLE __attribute__((visibility("default"))) +#define NETHOGS_DSO_HIDDEN __attribute__((visibility("hidden"))) -#define NETHOGS_APP_ACTION_SET 1 +#define NETHOGS_APP_ACTION_SET 1 #define NETHOGS_APP_ACTION_REMOVE 2 -#define NETHOGS_STATUS_OK 0 -#define NETHOGS_STATUS_FAILURE 1 //generic error -#define NETHOGS_STATUS_NO_DEVICE 2 //no device foundr +#define NETHOGS_STATUS_OK 0 +#define NETHOGS_STATUS_FAILURE 1 // generic error +#define NETHOGS_STATUS_NO_DEVICE 2 // no device foundr -typedef struct NethogsMonitorRecord -{ - int record_id; - const char* name; - int pid; - uint32_t uid; - const char* device_name; - uint32_t sent_bytes; - uint32_t recv_bytes; - float sent_kbs; - float recv_kbs; +typedef struct NethogsMonitorRecord { + int record_id; + const char *name; + int pid; + uint32_t uid; + const char *device_name; + uint32_t sent_bytes; + uint32_t recv_bytes; + float sent_kbs; + 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 + * @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); diff --git a/main.cpp b/main.cpp index e5b67ff..4fdab2e 100644 --- a/main.cpp +++ b/main.cpp @@ -2,302 +2,277 @@ #include #include -//The self_pipe is used to interrupt the select() in the main loop -static std::pair self_pipe = std::make_pair(-1, -1); +// The self_pipe is used to interrupt the select() in the main loop +static std::pair self_pipe = std::make_pair(-1, -1); static time_t last_refresh_time = 0; -//selectable file descriptors for the main loop +// selectable file descriptors for the main loop static fd_set pc_loop_fd_set; static std::vector 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) { + std::ostream &output = (iserror ? std::cerr : std::cout); -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 << " -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 << " -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 << " -p : sniff in promiscious mode (not recommended).\n"; - output << " -s : sort output by sent column.\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 << " -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 << " -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 << std::endl; - output << "When nethogs is running, press:\n"; - output << " q: quit\n"; - output << " s: sort by SENT traffic\n"; - output << " r: sort by RECEIVE traffic\n"; - output << " m: switch between total (KB, B, MB) and KB/s mode\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"; + output << " s: sort by SENT traffic\n"; + output << " r: sort by RECEIVE traffic\n"; + output << " m: switch between total (KB, B, MB) and KB/s mode\n"; } - -void quit_cb (int /* i */) -{ - if( self_pipe.second != -1 ) - { - write(self_pipe.second, "x", 1); - } - else - { - exit(0); - } +void quit_cb(int /* i */) { + if (self_pipe.second != -1) { + write(self_pipe.second, "x", 1); + } else { + exit(0); + } } -void forceExit(bool success, const char *msg, ...) -{ - if ((!tracemode)&&(!DEBUG)){ - exit_ui(); - } +void forceExit(bool success, const char *msg, ...) { + if ((!tracemode) && (!DEBUG)) { + exit_ui(); + } - va_list argp; - va_start(argp, msg); - vfprintf(stderr, msg, argp); - va_end(argp); - std::cerr << std::endl; + va_list argp; + va_start(argp, msg); + vfprintf(stderr, msg, argp); + va_end(argp); + std::cerr << std::endl; - if (success) - exit(EXIT_SUCCESS); - else - exit(EXIT_FAILURE); + if (success) + exit(EXIT_SUCCESS); + else + exit(EXIT_FAILURE); } -std::pair create_self_pipe() -{ - int pfd[2]; - if (pipe(pfd) == -1) - return std::make_pair(-1, -1); +std::pair create_self_pipe() { + int pfd[2]; + if (pipe(pfd) == -1) + return std::make_pair(-1, -1); - if (fcntl(pfd[0], F_SETFL, fcntl(pfd[0], F_GETFL) | O_NONBLOCK) == -1) - return std::make_pair(-1, -1); + if (fcntl(pfd[0], F_SETFL, fcntl(pfd[0], F_GETFL) | O_NONBLOCK) == -1) + return std::make_pair(-1, -1); - if (fcntl(pfd[1], F_SETFL, fcntl(pfd[1], F_GETFL) | O_NONBLOCK) == -1) - return std::make_pair(-1, -1); + if (fcntl(pfd[1], F_SETFL, fcntl(pfd[1], F_GETFL) | O_NONBLOCK) == -1) + return std::make_pair(-1, -1); - return std::make_pair(pfd[0], pfd[1]); + return std::make_pair(pfd[0], pfd[1]); } -bool wait_for_next_trigger() -{ - if( pc_loop_use_select ) - { - FD_ZERO(&pc_loop_fd_set); - int nfds = 0; - for(std::vector::const_iterator it=pc_loop_fd_list.begin(); - 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) ) - { - return false; - } - } - } - else - { - // If select() not possible, pause to prevent 100% - usleep(1000); - } - return true; +bool wait_for_next_trigger() { + if (pc_loop_use_select) { + FD_ZERO(&pc_loop_fd_set); + int nfds = 0; + for (std::vector::const_iterator it = pc_loop_fd_list.begin(); + 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)) { + return false; + } + } + } else { + // If select() not possible, pause to prevent 100% + usleep(1000); + } + return true; } +void clean_up() { + // close file descriptors + for (std::vector::const_iterator it = pc_loop_fd_list.begin(); + it != pc_loop_fd_list.end(); ++it) { + close(*it); + } -void clean_up() -{ - //close file descriptors - for(std::vector::const_iterator it=pc_loop_fd_list.begin(); - it != pc_loop_fd_list.end(); ++it) - { - close(*it); - } - - procclean(); - if ((!tracemode) && (!DEBUG)) - exit_ui(); + procclean(); + if ((!tracemode) && (!DEBUG)) + exit_ui(); } -int main (int argc, char** argv) -{ - process_init(); +int main(int argc, char **argv) { + process_init(); - int promisc = 0; - bool all = false; + int promisc = 0; + bool all = false; - int opt; - while ((opt = getopt(argc, argv, "Vahbtpd:v:c:sa")) != -1) { - switch(opt) { - case 'V': - versiondisplay(); - exit(0); - case 'h': - help(false); - exit(0); - case 'b': - bughuntmode = true; - tracemode = true; - break; - case 't': - tracemode = true; - break; - case 'p': - promisc = 1; - break; - case 's': - sortRecv = false; - break; - case 'd': - refreshdelay = atoi(optarg); - break; - case 'v': - viewMode = atoi(optarg) % VIEWMODE_COUNT; - break; - case 'c': - refreshlimit = atoi(optarg); - break; - case 'a': - all = true; - break; - default: - help(true); - exit(EXIT_FAILURE); - } - } + int opt; + while ((opt = getopt(argc, argv, "Vahbtpd:v:c:sa")) != -1) { + switch (opt) { + case 'V': + versiondisplay(); + exit(0); + case 'h': + help(false); + exit(0); + case 'b': + bughuntmode = true; + tracemode = true; + break; + case 't': + tracemode = true; + break; + case 'p': + promisc = 1; + break; + case 's': + sortRecv = false; + break; + case 'd': + refreshdelay = atoi(optarg); + break; + case 'v': + viewMode = atoi(optarg) % VIEWMODE_COUNT; + break; + case 'c': + refreshlimit = atoi(optarg); + break; + case 'a': + all = true; + break; + default: + help(true); + exit(EXIT_FAILURE); + } + } - 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"); + 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"); - if ((!tracemode) && (!DEBUG)){ - init_ui(); - } + if ((!tracemode) && (!DEBUG)) { + init_ui(); + } - if (NEEDROOT && (geteuid() != 0)) - forceExit(false, "You need to be root to run NetHogs!"); + if (NEEDROOT && (geteuid() != 0)) + forceExit(false, "You need to be root to run NetHogs!"); - //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 ) - { - forceExit(false, "Error creating pipe file descriptors\n"); - } - else - { - //add the self-pipe to allow interrupting select() - pc_loop_fd_list.push_back(self_pipe.first); - } + // 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) { + forceExit(false, "Error creating pipe file descriptors\n"); + } else { + // add the self-pipe to allow interrupting select() + pc_loop_fd_list.push_back(self_pipe.first); + } - char errbuf[PCAP_ERRBUF_SIZE]; + char errbuf[PCAP_ERRBUF_SIZE]; - handle * handles = NULL; - device * current_dev = devices; - while (current_dev != NULL) { + handle *handles = NULL; + device *current_dev = devices; + while (current_dev != NULL) { - if( !getLocal(current_dev->name, tracemode) ) - { - forceExit(false, "getifaddrs failed while establishing local IP."); - } + 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_addcb (newhandle, dp_packet_ip, process_ip); - dp_addcb (newhandle, dp_packet_ip6, process_ip6); - dp_addcb (newhandle, dp_packet_tcp, process_tcp); - dp_addcb (newhandle, dp_packet_udp, process_udp); + 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); + dp_addcb(newhandle, dp_packet_udp, process_udp); - /* The following code solves sf.net bug 1019381, but is only available - * in newer versions (from 0.8 it seems) of libpcap - * - * update: version 0.7.2, which is in debian stable now, should be ok - * also. - */ - if (dp_setnonblock (newhandle, 1, errbuf) == -1) - { - fprintf(stderr, "Error putting libpcap in nonblocking mode\n"); - } - handles = new handle (newhandle, current_dev->name, handles); + /* The following code solves sf.net bug 1019381, but is only available + * in newer versions (from 0.8 it seems) of libpcap + * + * update: version 0.7.2, which is in debian stable now, should be ok + * also. + */ + 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 ) - { - //some devices may not support pcap_get_selectable_fd - int const fd = pcap_get_selectable_fd(newhandle->pcap_handle); - if( fd != -1 ) - { - pc_loop_fd_list.push_back(fd); - } - else - { - pc_loop_use_select = false; - pc_loop_fd_list.clear(); - 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); - } + 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) { + pc_loop_fd_list.push_back(fd); + } else { + pc_loop_use_select = false; + pc_loop_fd_list.clear(); + 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); + } - current_dev = current_dev->next; - } + current_dev = current_dev->next; + } - signal (SIGINT, &quit_cb); + signal(SIGINT, &quit_cb); - fprintf(stderr, "Waiting for first packet to arrive (see sourceforge.net bug 1019381)\n"); - struct dpargs * userdata = (dpargs *) malloc (sizeof (struct dpargs)); + 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) - { - bool packets_read = false; + // Main loop: + while (1) { + bool packets_read = false; - 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)); - if (retval < 0) - std::cerr << "Error dispatching: " << retval << std::endl; - else if (retval != 0) - packets_read = true; - } + 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)); + if (retval < 0) + std::cerr << "Error dispatching: " << retval << std::endl; + else if (retval != 0) + packets_read = true; + } - time_t const now = ::time(NULL); - if( last_refresh_time + refreshdelay <= now ) - { - last_refresh_time = now; - if ((!DEBUG)&&(!tracemode)) - { - // handle user input - ui_tick(); - } - do_refresh(); - } + time_t const now = ::time(NULL); + if (last_refresh_time + refreshdelay <= now) { + last_refresh_time = now; + if ((!DEBUG) && (!tracemode)) { + // handle user input + ui_tick(); + } + do_refresh(); + } - // if not packets, do a select() until next packet - if (!packets_read) - if( !wait_for_next_trigger() ) - // Shutdown requested - exit the loop - break; - } + // if not packets, do a select() until next packet + if (!packets_read) + if (!wait_for_next_trigger()) + // Shutdown requested - exit the loop + break; + } - clean_up(); + clean_up(); } diff --git a/nethogs.cpp b/nethogs.cpp index 824a168..682c790 100644 --- a/nethogs.cpp +++ b/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. * */ @@ -40,7 +41,7 @@ #include "cui.h" extern "C" { - #include "decpcap.h" +#include "decpcap.h" } #include "packet.h" @@ -48,7 +49,7 @@ extern "C" { #include "process.h" #include "devices.h" -extern Process * unknownudp; +extern Process *unknownudp; unsigned refreshdelay = 1; unsigned refreshlimit = 0; @@ -64,178 +65,184 @@ 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)) - return true; - if (next == NULL) - return false; - return next->contains(n_addr); +bool local_addr::contains(const in_addr_t &n_addr) { + if ((sa_family == AF_INET) && (n_addr == addr)) + return true; + if (next == NULL) + return false; + return next->contains(n_addr); } -bool local_addr::contains(const struct in6_addr & n_addr) { - if (sa_family == AF_INET6) - { - /* - if (DEBUG) { - char addy [50]; - std::cerr << "Comparing: "; - inet_ntop (AF_INET6, &n_addr, addy, 49); - std::cerr << addy << " and "; - inet_ntop (AF_INET6, &addr6, addy, 49); - std::cerr << addy << std::endl; - } - */ - //if (addr6.s6_addr == n_addr.s6_addr) - if (memcmp (&addr6, &n_addr, sizeof(struct in6_addr)) == 0) - { - if (DEBUG) - std::cerr << "Match!" << std::endl; - return true; - } - } - if (next == NULL) - return false; - return next->contains(n_addr); +bool local_addr::contains(const struct in6_addr &n_addr) { + if (sa_family == AF_INET6) { + /* + if (DEBUG) { + char addy [50]; + std::cerr << "Comparing: "; + inet_ntop (AF_INET6, &n_addr, addy, 49); + std::cerr << addy << " and "; + inet_ntop (AF_INET6, &addr6, addy, 49); + std::cerr << addy << std::endl; + } + */ + // if (addr6.s6_addr == n_addr.s6_addr) + if (memcmp(&addr6, &n_addr, sizeof(struct in6_addr)) == 0) { + if (DEBUG) + std::cerr << "Match!" << std::endl; + return true; + } + } + if (next == NULL) + return false; + return next->contains(n_addr); } struct dpargs { - const char * device; - int sa_family; - in_addr ip_src; - in_addr ip_dst; - in6_addr ip6_src; - in6_addr ip6_dst; + const char *device; + int sa_family; + in_addr ip_src; + in_addr ip_dst; + in6_addr ip6_src; + 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) { + struct dpargs *args = (struct dpargs *)userdata; + struct tcphdr *tcp = (struct tcphdr *)m_packet; + + curtime = header->ts; + + /* get info from userdata, then call getPacket */ + Packet *packet; + 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); +#else + 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); +#else + 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; + return true; + } + + Connection *connection = findConnection(packet); + + if (connection != NULL) { + /* add packet to the connection */ + connection->add(packet); + } else { + /* else: unknown connection, create new */ + connection = new Connection(packet); + getProcess(connection, args->device); + } + delete packet; + + /* we're done now. */ + return true; } -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; +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; + curtime = header->ts; - /* get info from userdata, then call getPacket */ - Packet * packet; - 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); - #else - 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); - #else - 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; - return true; - } + Packet *packet; + 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); +#else + 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); +#else + 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; + return true; + } - Connection * connection = findConnection(packet); + // if (DEBUG) + // std::cout << "Got packet from " << packet->gethashstring() << std::endl; - if (connection != NULL) - { - /* add packet to the connection */ - connection->add(packet); - } else { - /* else: unknown connection, create new */ - connection = new Connection (packet); - getProcess(connection, args->device); - } - delete packet; + Connection *connection = findConnection(packet); - /* we're done now. */ - return true; + if (connection != NULL) { + /* add packet to the connection */ + connection->add(packet); + } else { + /* else: unknown connection, create new */ + connection = new Connection(packet); + getProcess(connection, args->device); + } + delete packet; + + /* we're done now. */ + return true; } -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; +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; + args->ip_src = ip->ip_src; + args->ip_dst = ip->ip_dst; - curtime = header->ts; - - Packet * packet; - 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); - #else - 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); - #else - 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; - return true; - } - - //if (DEBUG) - // std::cout << "Got packet from " << packet->gethashstring() << std::endl; - - Connection * connection = findConnection(packet); - - if (connection != NULL) - { - /* add packet to the connection */ - connection->add(packet); - } else { - /* else: unknown connection, create new */ - connection = new Connection (packet); - getProcess(connection, args->device); - } - delete packet; - - /* we're done now. */ - return true; + /* we're not done yet - also parse tcp :) */ + return false; } -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; - args->ip_src = ip->ip_src; - args->ip_dst = ip->ip_dst; +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; + args->ip6_src = ip6->ip6_src; + args->ip6_dst = ip6->ip6_dst; - /* we're not done yet - also parse tcp :) */ - return false; -} - -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; - args->ip6_src = ip6->ip6_src; - args->ip6_dst = ip6->ip6_dst; - - /* we're not done yet - also parse tcp :) */ - return false; + /* we're not done yet - also parse tcp :) */ + return false; } 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; - } - dp_handle * content; - const char * devicename; - handle * next; + handle(dp_handle *m_handle, const char *m_devicename = NULL, + handle *m_next = NULL) { + content = m_handle; + next = m_next; + devicename = m_devicename; + } + dp_handle *content; + const char *devicename; + handle *next; }; diff --git a/nethogs.h b/nethogs.h index 28b3fcd..08f1add 100644 --- a/nethogs.h +++ b/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 @@ -30,9 +30,9 @@ #include #include #ifdef __APPLE__ - #include +#include #else - #include +#include #endif #include @@ -68,50 +68,48 @@ #define PROGNAME_WIDTH 512 // viewMode: how to represent numbers -#define VIEWMODE_KBPS 0 +#define VIEWMODE_KBPS 0 #define VIEWMODE_TOTAL_KB 1 -#define VIEWMODE_TOTAL_B 2 +#define VIEWMODE_TOTAL_B 2 #define VIEWMODE_TOTAL_MB 3 -#define VIEWMODE_COUNT 4 +#define VIEWMODE_COUNT 4 -#define NORETURN __attribute__ ((__noreturn__)) +#define NORETURN __attribute__((__noreturn__)) 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) - { - addr = m_addr; - next = m_next; - sa_family = AF_INET; - string = (char*) malloc (16); - 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) - { - addr6 = *m_addr; - next = m_next; - sa_family = AF_INET6; - string = (char*) malloc (64); - inet_ntop (AF_INET6, &m_addr, string, 63); - } + /* ipv4 constructor takes an in_addr_t */ + local_addr(in_addr_t m_addr, local_addr *m_next = NULL) { + addr = m_addr; + next = m_next; + sa_family = AF_INET; + string = (char *)malloc(16); + 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) { + addr6 = *m_addr; + next = m_next; + sa_family = AF_INET6; + string = (char *)malloc(64); + inet_ntop(AF_INET6, &m_addr, string, 63); + } + + bool contains(const in_addr_t &n_addr); + bool contains(const struct in6_addr &n_addr); + char *string; + local_addr *next; - bool contains (const in_addr_t & n_addr); - bool contains (const struct in6_addr & n_addr); - char * string; - local_addr * next; private: - - in_addr_t addr; - struct in6_addr addr6; - short int sa_family; + in_addr_t addr; + struct in6_addr addr6; + short int sa_family; }; -void quit_cb (int i); +void quit_cb(int i); -const char* getVersion(); +const char *getVersion(); #endif diff --git a/packet.cpp b/packet.cpp index 7e37aad..615b163 100644 --- a/packet.cpp +++ b/packet.cpp @@ -15,20 +15,20 @@ * * 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 #include "packet.h" #include #include #ifdef __APPLE__ - #include +#include #else - #include +#include #endif #include #include @@ -39,7 +39,7 @@ #include // #include "inet6.c" -local_addr * local_addrs = NULL; +local_addr *local_addrs = NULL; /* * getLocal @@ -48,40 +48,39 @@ 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) -{ - struct ifaddrs *ifaddr, *ifa; - if(getifaddrs(&ifaddr) == -1) { - return false; - } +bool getLocal(const char *device, bool tracemode) { + struct ifaddrs *ifaddr, *ifa; + if (getifaddrs(&ifaddr) == -1) { + return false; + } - for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { - if(ifa->ifa_addr == NULL) - continue; + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) + continue; - if(strcmp(ifa->ifa_name, device) != 0) - continue; + if (strcmp(ifa->ifa_name, device) != 0) + continue; - int family = ifa->ifa_addr->sa_family; + int family = ifa->ifa_addr->sa_family; - if(family == AF_INET){ - struct sockaddr_in *addr = (struct sockaddr_in*)ifa->ifa_addr; - local_addrs = new local_addr(addr->sin_addr.s_addr, local_addrs); + if (family == AF_INET) { + struct sockaddr_in *addr = (struct sockaddr_in *)ifa->ifa_addr; + local_addrs = new local_addr(addr->sin_addr.s_addr, local_addrs); - if (tracemode || DEBUG) { - printf("Adding local address: %s\n", inet_ntoa(addr->sin_addr)); - } - }else if(family == AF_INET6){ - struct sockaddr_in6 *addr = (struct sockaddr_in6*)ifa->ifa_addr; - local_addrs = new local_addr(&addr->sin6_addr, local_addrs); - if (tracemode || DEBUG) { - char host[512]; - printf("Adding local address: %s\n", - inet_ntop(AF_INET6, &addr->sin6_addr, host, sizeof(host))); - } - } - } - return true; + if (tracemode || DEBUG) { + printf("Adding local address: %s\n", inet_ntoa(addr->sin_addr)); + } + } else if (family == AF_INET6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)ifa->ifa_addr; + local_addrs = new local_addr(&addr->sin6_addr, local_addrs); + if (tracemode || DEBUG) { + char host[512]; + printf("Adding local address: %s\n", + inet_ntop(AF_INET6, &addr->sin6_addr, host, sizeof(host))); + } + } + } + return true; } typedef u_int32_t tcp_seq; @@ -90,33 +89,33 @@ typedef u_int32_t tcp_seq; /* glanced from ethereal, it's 16 bytes, and the payload packet type is * in the last 2 bytes... */ struct ppp_header { - u_int16_t dummy1; - u_int16_t dummy2; - u_int16_t dummy3; - u_int16_t dummy4; - u_int16_t dummy5; - u_int16_t dummy6; - u_int16_t dummy7; + u_int16_t dummy1; + u_int16_t dummy2; + u_int16_t dummy3; + u_int16_t dummy4; + u_int16_t dummy5; + u_int16_t dummy6; + u_int16_t dummy7; - u_int16_t packettype; + u_int16_t packettype; }; /* TCP header */ // TODO take from elsewhere. struct tcp_hdr { - u_short th_sport; /* source port */ - u_short th_dport; /* destination port */ - tcp_seq th_seq; /* sequence number */ - tcp_seq th_ack; /* acknowledgement number */ + u_short th_sport; /* source port */ + u_short th_dport; /* destination port */ + tcp_seq th_seq; /* sequence number */ + tcp_seq th_ack; /* acknowledgement number */ #if BYTE_ORDER == LITTLE_ENDIAN - u_int th_x2:4, /* (unused) */ - th_off:4; /* data offset */ + u_int th_x2 : 4, /* (unused) */ + th_off : 4; /* data offset */ #endif #if BYTE_ORDER == BIG_ENDIAN - u_int th_off:4, /* data offset */ - th_x2:4; /* (unused) */ + u_int th_off : 4, /* data offset */ + th_x2 : 4; /* (unused) */ #endif - u_char th_flags; + u_char th_flags; #define TH_FIN 0x01 #define TH_SYN 0x02 #define TH_RST 0x04 @@ -125,157 +124,170 @@ struct tcp_hdr { #define TH_URG 0x20 #define TH_ECE 0x40 #define TH_CWR 0x80 -#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR) - u_short th_win; /* window */ - u_short th_sum; /* checksum */ - u_short th_urp; /* urgent pointer */ +#define TH_FLAGS (TH_FIN | TH_SYN | TH_RST | TH_ACK | TH_URG | TH_ECE | TH_CWR) + u_short th_win; /* window */ + 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; - hashstring = NULL; +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; - 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; + hashstring = NULL; } direction invert(direction dir) { - if (dir == dir_incoming) - return dir_outgoing; - else if (dir == dir_outgoing) - return dir_incoming; - else - return dir_unknown; + if (dir == dir_incoming) + return dir_outgoing; + else if (dir == dir_outgoing) + return dir_incoming; + else + return dir_unknown; } -Packet * Packet::newInverted () { - direction new_direction = invert(dir); +Packet *Packet::newInverted() { + direction new_direction = invert(dir); - if (sa_family == AF_INET) - return new Packet (dip, dport, sip, sport, len, time, new_direction); - else - return new Packet (dip6, dport, sip6, sport, len, time, new_direction); + if (sa_family == AF_INET) + return new Packet(dip, dport, sip, sport, len, time, new_direction); + else + return new Packet(dip6, dport, sip6, sport, len, time, new_direction); } -/* 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; - sip6 = old_packet.sip6; - dip6 = old_packet.dip6; - 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; - else - hashstring = strdup(old_packet.hashstring); - dir = old_packet.dir; +/* 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; + sip6 = old_packet.sip6; + dip6 = old_packet.dip6; + 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; + else + hashstring = strdup(old_packet.hashstring); + dir = old_packet.dir; } -bool sameinaddr(in_addr one, in_addr other) -{ - return one.s_addr == other.s_addr; +bool sameinaddr(in_addr one, in_addr other) { + return one.s_addr == other.s_addr; } -bool Packet::isOlderThan (timeval t) { - std::cout << "Comparing " << time.tv_sec << " <= " << t.tv_sec << std::endl; - return (time.tv_sec <= t.tv_sec); +bool Packet::isOlderThan(timeval t) { + std::cout << "Comparing " << time.tv_sec << " <= " << t.tv_sec << std::endl; + return (time.tv_sec <= t.tv_sec); } -bool Packet::Outgoing () { - /* must be initialised with getLocal("eth0:1");) */ - assert (local_addrs != NULL); +bool Packet::Outgoing() { + /* must be initialised with getLocal("eth0:1");) */ + assert(local_addrs != NULL); - switch (dir) { - case dir_outgoing: - return true; - case dir_incoming: - return false; - case dir_unknown: - bool islocal; - if (sa_family == AF_INET) - islocal = local_addrs->contains(sip.s_addr); - else - islocal = local_addrs->contains(sip6); - if (islocal) { - dir = dir_outgoing; - return true; - } else { - if (DEBUG) { - if (sa_family == AF_INET) - islocal = local_addrs->contains(dip.s_addr); - else - islocal = local_addrs->contains(dip6); + switch (dir) { + case dir_outgoing: + return true; + case dir_incoming: + return false; + case dir_unknown: + bool islocal; + if (sa_family == AF_INET) + islocal = local_addrs->contains(sip.s_addr); + else + islocal = local_addrs->contains(sip6); + if (islocal) { + dir = dir_outgoing; + return true; + } else { + if (DEBUG) { + if (sa_family == AF_INET) + islocal = local_addrs->contains(dip.s_addr); + else + islocal = local_addrs->contains(dip6); - if (!islocal) { - std::cerr << "Neither dip nor sip are local: "; - char addy [50]; - inet_ntop (AF_INET6, &sip6, addy, 49); - std::cerr << addy << std::endl; - inet_ntop (AF_INET6, &dip6, addy, 49); - std::cerr << addy << std::endl; + if (!islocal) { + std::cerr << "Neither dip nor sip are local: "; + char addy[50]; + inet_ntop(AF_INET6, &sip6, addy, 49); + std::cerr << addy << std::endl; + inet_ntop(AF_INET6, &dip6, addy, 49); + std::cerr << addy << std::endl; - return false; - } - } - dir = dir_incoming; - return false; - } - } - return false; + return false; + } + } + dir = dir_incoming; + return false; + } + } + 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) - { - return hashstring; - } +char *Packet::gethashstring() { + if (hashstring != NULL) { + return hashstring; + } - hashstring = (char *) malloc (HASHKEYSIZE * sizeof(char)); + hashstring = (char *)malloc(HASHKEYSIZE * sizeof(char)); - char * local_string = (char *) malloc (50); - char * remote_string = (char *) malloc (50); - if (sa_family == AF_INET) { - inet_ntop(sa_family, &sip, local_string, 49); - inet_ntop(sa_family, &dip, remote_string, 49); - } else { - inet_ntop(sa_family, &sip6, local_string, 49); -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); - } else { - 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; - return hashstring; + char *local_string = (char *)malloc(50); + char *remote_string = (char *)malloc(50); + if (sa_family == AF_INET) { + inet_ntop(sa_family, &sip, local_string, 49); + inet_ntop(sa_family, &dip, remote_string, 49); + } else { + inet_ntop(sa_family, &sip6, local_string, 49); + 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); + } else { + 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; + 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) -{ - return (sport == other->sport) && (sameinaddr(sip, other->sip)); +bool Packet::matchSource(Packet *other) { + return (sport == other->sport) && (sameinaddr(sip, other->sip)); } diff --git a/packet.h b/packet.h index dc497d7..b3c86d9 100644 --- a/packet.h +++ b/packet.h @@ -1,4 +1,4 @@ -/* +/* * packet.h * * Copyright (c) 2004,2006 Arnout Engelen @@ -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,56 +31,54 @@ #include #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); +bool getLocal(const char *device, bool tracemode); -class Packet -{ +class Packet { public: - in6_addr sip6; - in6_addr dip6; - in_addr sip; - in_addr dip; - unsigned short sport; - unsigned short dport; - u_int32_t len; - timeval time; + in6_addr sip6; + in6_addr dip6; + in_addr sip; + in_addr dip; + unsigned short sport; + unsigned short dport; + 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); - /* copy constructor */ - Packet (const Packet &old); - ~Packet () - { - if (hashstring != NULL) - { - free (hashstring); - hashstring = NULL; - } - } - /* Packet (const Packet &old_packet); */ - /* copy constructor that turns the packet around */ - Packet * newInverted (); + 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) { + free(hashstring); + hashstring = NULL; + } + } + /* Packet (const Packet &old_packet); */ + /* copy constructor that turns the packet around */ + Packet *newInverted(); - bool isOlderThan(timeval t); - /* is this packet coming from the local host? */ - bool Outgoing (); + bool isOlderThan(timeval t); + /* is this packet coming from the local host? */ + bool Outgoing(); + + bool match(Packet *other); + bool matchSource(Packet *other); + /* returns '1.2.3.4:5-1.2.3.4:6'-style string */ + char *gethashstring(); - bool match (Packet * other); - 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; - char * hashstring; + direction dir; + short int sa_family; + char *hashstring; }; #endif diff --git a/process.cpp b/process.cpp index 196f803..8ca571a 100644 --- a/process.cpp +++ b/process.cpp @@ -15,17 +15,17 @@ * * 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 #include #include #include #ifndef __APPLE__ - #include +#include #endif #include #include @@ -47,8 +47,7 @@ extern timeval curtime; * key contains source ip, source port, destination ip, destination * port in format: '1.2.3.4:5-1.2.3.4:5' */ -extern std::map conninode; - +extern std::map conninode; /* this file includes: * - calls to inodeproc to get the pid that belongs to that inode @@ -61,186 +60,155 @@ extern std::map conninode; * * unknown IP traffic * We must take care these never get removed from the list. */ -Process * unknowntcp; -Process * unknownudp; -Process * unknownip; -ProcList * processes; +Process *unknowntcp; +Process *unknownudp; +Process *unknownip; +ProcList *processes; /* We're migrating to having several `unknown' processes that are added as * normal processes, instead of hard-wired unknown processes. * This mapping maps from unknown processes descriptions to processes */ -std::map unknownprocs; +std::map 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; } + +void process_init() { + unknowntcp = new Process(0, "", "unknown TCP"); + // unknownudp = new Process (0, "", "unknown UDP"); + // unknownip = new Process (0, "", "unknown IP"); + processes = new ProcList(unknowntcp, NULL); + // processes = new ProcList (unknownudp, processes); + // processes = new ProcList (unknownip, processes); } -float tokbps (u_int32_t bytes) -{ - return (((double)bytes) / PERIOD) / 1024; -} - - -void process_init () -{ - unknowntcp = new Process (0, "", "unknown TCP"); - //unknownudp = new Process (0, "", "unknown UDP"); - //unknownip = new Process (0, "", "unknown IP"); - processes = new ProcList (unknowntcp, NULL); - //processes = new ProcList (unknownudp, processes); - //processes = new ProcList (unknownip, processes); -} - -int Process::getLastPacket() -{ - int lastpacket=0; - ConnList * curconn=connections; - while (curconn != NULL) - { - assert (curconn != NULL); - assert (curconn->getVal() != NULL); - if (curconn->getVal()->getLastPacket() > lastpacket) - lastpacket = curconn->getVal()->getLastPacket(); - curconn = curconn->getNext(); - } - return lastpacket; +int Process::getLastPacket() { + int lastpacket = 0; + ConnList *curconn = connections; + while (curconn != NULL) { + assert(curconn != NULL); + assert(curconn->getVal() != NULL); + if (curconn->getVal()->getLastPacket() > lastpacket) + lastpacket = curconn->getVal()->getLastPacket(); + curconn = curconn->getNext(); + } + return lastpacket; } /** Get the kb/s values for this process */ -void Process::getkbps (float * recvd, float * sent) -{ - u_int32_t sum_sent = 0, sum_recv = 0; +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) - { - /* stalled connection, remove. */ - ConnList * todelete = curconn; - Connection * conn_todelete = curconn->getVal(); - curconn = curconn->getNext(); - if (todelete == this->connections) - this->connections = curconn; - if (previous != NULL) - previous->setNext(curconn); - delete (todelete); - delete (conn_todelete); - } - else - { - u_int32_t sent = 0, recv = 0; - curconn->getVal()->sumanddel(curtime, &recv, &sent); - sum_sent += sent; - sum_recv += recv; - previous = curconn; - curconn = curconn->getNext(); - } - } - *recvd = tokbps(sum_recv); - *sent = tokbps(sum_sent); + /* 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) { + /* stalled connection, remove. */ + ConnList *todelete = curconn; + Connection *conn_todelete = curconn->getVal(); + curconn = curconn->getNext(); + if (todelete == this->connections) + this->connections = curconn; + if (previous != NULL) + previous->setNext(curconn); + delete (todelete); + delete (conn_todelete); + } else { + u_int32_t sent = 0, recv = 0; + curconn->getVal()->sumanddel(curtime, &recv, &sent); + sum_sent += sent; + sum_recv += recv; + previous = curconn; + curconn = curconn->getNext(); + } + } + *recvd = tokbps(sum_recv); + *sent = tokbps(sum_sent); } /** get total values for this process */ -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) - { - Connection * conn = curconn->getVal(); - sum_sent += conn->sumSent; - sum_recv += conn->sumRecv; - curconn = curconn->getNext(); - } - //std::cout << "Sum sent: " << sum_sent << std::endl; - //std::cout << "Sum recv: " << sum_recv << std::endl; - *recvd = sum_recv; - *sent = sum_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) { + Connection *conn = curconn->getVal(); + sum_sent += conn->sumSent; + sum_recv += conn->sumRecv; + curconn = curconn->getNext(); + } + // std::cout << "Sum sent: " << sum_sent << std::endl; + // std::cout << "Sum recv: " << sum_recv << std::endl; + *recvd = sum_recv; + *sent = sum_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); - *sent = tomb(sum_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); + *sent = tomb(sum_sent); } /** get total values for this process */ -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::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) -{ - u_int32_t sum_sent = 0, sum_recv = 0; - gettotal(&sum_recv, &sum_sent); - //std::cout << "Total sent: " << sum_sent << std::endl; - *sent = sum_sent; - *recvd = sum_recv; +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; + *sent = sum_sent; + *recvd = sum_recv; } +Process *findProcess(struct prg_node *node) { + ProcList *current = processes; + while (current != NULL) { + Process *currentproc = current->getVal(); + assert(currentproc != NULL); -Process * findProcess (struct prg_node * node) -{ - ProcList * current = processes; - while (current != NULL) - { - Process * currentproc = current->getVal(); - assert (currentproc != NULL); - - if (node->pid == currentproc->pid) - return current->getVal(); - current = current->next; - } - return NULL; + if (node->pid == currentproc->pid) + return current->getVal(); + current = current->next; + } + return NULL; } /* 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) -{ - struct prg_node * node = findPID(inode); +Process *findProcess(unsigned long inode) { + struct prg_node *node = findPID(inode); - if (node == NULL) - return NULL; + if (node == NULL) + return NULL; - return findProcess (node); + return findProcess(node); } -int ProcList::size () -{ - int i=1; +int ProcList::size() { + int i = 1; - if (next != NULL) - i += next->size(); + if (next != NULL) + i += next->size(); - return i; + return i; } -void check_all_procs () -{ - ProcList * curproc = processes; - while (curproc != NULL) - { - curproc->getVal()->check(); - curproc = curproc->getNext(); - } +void check_all_procs() { + ProcList *curproc = processes; + while (curproc != NULL) { + curproc->getVal()->check(); + curproc = curproc->getNext(); + } } /* @@ -248,54 +216,52 @@ 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) -{ - struct prg_node * node = findPID(inode); +Process *getProcess(unsigned long inode, const char *devicename) { + struct prg_node *node = findPID(inode); - if (node == NULL) - { - if (DEBUG || bughuntmode) - std::cout << "No PID information for inode " << inode << std::endl; - return NULL; - } + if (node == NULL) { + if (DEBUG || bughuntmode) + std::cout << "No PID information for inode " << inode << std::endl; + return NULL; + } - Process * proc = findProcess (node); + Process *proc = findProcess(node); - if (proc != NULL) - return proc; + if (proc != NULL) + return proc; - Process * newproc = new Process (inode, devicename, node->name.c_str()); - newproc->pid = node->pid; + Process *newproc = new Process(inode, devicename, node->name.c_str()); + newproc->pid = node->pid; - char procdir [100]; - sprintf(procdir , "/proc/%d", node->pid); - struct stat stats; - int retval = stat(procdir, &stats); + char procdir[100]; + sprintf(procdir, "/proc/%d", node->pid); + struct stat stats; + int retval = stat(procdir, &stats); - /* 0 seems a proper default. - * used in case the PID disappeared while nethogs was running - * TODO we can store node->uid this while info on the inodes, - * right? */ - /* - if (!ROBUST && (retval != 0)) - { - std::cerr << "Couldn't stat " << procdir << std::endl; - assert (false); - } - */ + /* 0 seems a proper default. + * used in case the PID disappeared while nethogs was running + * TODO we can store node->uid this while info on the inodes, + * right? */ + /* + if (!ROBUST && (retval != 0)) + { + std::cerr << "Couldn't stat " << procdir << std::endl; + assert (false); + } + */ - if (retval != 0) - newproc->setUid(0); - else - newproc->setUid(stats.st_uid); + if (retval != 0) + newproc->setUid(0); + else + newproc->setUid(stats.st_uid); - /*if (getpwuid(stats.st_uid) == NULL) { - std::stderr << "uid for inode - if (!ROBUST) - assert(false); - }*/ - processes = new ProcList (newproc, processes); - return newproc; + /*if (getpwuid(stats.st_uid) == NULL) { + std::stderr << "uid for inode + if (!ROBUST) + assert(false); + }*/ + processes = new ProcList(newproc, processes); + return newproc; } /* @@ -305,88 +271,82 @@ 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) -{ - unsigned long inode = conninode[connection->refpacket->gethashstring()]; +Process *getProcess(Connection *connection, const char *devicename) { + unsigned long inode = conninode[connection->refpacket->gethashstring()]; - 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"; - } - // 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 - // haven't seen the connection->inode yet though). - #ifndef __APPLE__ - reread_mapping(); - #endif - refreshconninode(); - inode = conninode[connection->refpacket->gethashstring()]; - if (bughuntmode) - { - if (inode == 0) - { - std::cout << ":( inode for connection not found after refresh.\n"; - } - else - { - std::cout << ":) inode for connection found after refresh.\n"; - } - } -#if REVERSEHACK - 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 */ - - /* we reverse the direction of the stream if - * successful. */ - Packet * reversepacket = connection->refpacket->newInverted(); - inode = conninode[reversepacket->gethashstring()]; - - 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); - return unknowntcp; - } - - delete connection->refpacket; - connection->refpacket = reversepacket; - } + 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"; + } +// 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 +// haven't seen the connection->inode yet though). +#ifndef __APPLE__ + reread_mapping(); #endif - } - else if (bughuntmode) - { - std::cout << ";) new connection in connection-to-inode table before refresh.\n"; - } + refreshconninode(); + inode = conninode[connection->refpacket->gethashstring()]; + if (bughuntmode) { + if (inode == 0) { + std::cout << ":( inode for connection not found after refresh.\n"; + } else { + std::cout << ":) inode for connection found after refresh.\n"; + } + } +#if REVERSEHACK + 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 */ - if (bughuntmode) - { - std::cout << " inode # " << inode << std::endl; - } + /* we reverse the direction of the stream if + * successful. */ + Packet *reversepacket = connection->refpacket->newInverted(); + inode = conninode[reversepacket->gethashstring()]; - Process * proc = NULL; - if (inode != 0) - proc = getProcess(inode, devicename); + 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); + return unknowntcp; + } - if (proc == NULL) { - proc = new Process (inode, "", connection->refpacket->gethashstring()); - processes = new ProcList (proc, processes); - } + delete connection->refpacket; + connection->refpacket = reversepacket; + } +#endif + } else if (bughuntmode) { + std::cout + << ";) new connection in connection-to-inode table before refresh.\n"; + } - proc->connections = new ConnList (connection, proc->connections); - return proc; + if (bughuntmode) { + std::cout << " inode # " << inode << std::endl; + } + + Process *proc = NULL; + if (inode != 0) + proc = getProcess(inode, devicename); + + if (proc == NULL) { + proc = new Process(inode, "", connection->refpacket->gethashstring()); + processes = new ProcList(proc, processes); + } + + proc->connections = new ConnList(connection, proc->connections); + return proc; } -void procclean () -{ - //delete conninode; - prg_cache_clear(); +void procclean() { + // delete conninode; + prg_cache_clear(); } diff --git a/process.h b/process.h index 3783928..f2e7ecf 100644 --- a/process.h +++ b/process.h @@ -1,4 +1,4 @@ -/* +/* * process.h * * Copyright (c) 2004-2006,2008,2011 Arnout Engelen @@ -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 @@ -30,123 +30,103 @@ extern bool tracemode; extern bool bughuntmode; -void check_all_procs (); +void check_all_procs(); -class ConnList -{ +class ConnList { public: - ConnList (Connection * m_val, ConnList * m_next) - { - assert (m_val != NULL); - val = m_val; next = m_next; - } - ~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; - } + ConnList(Connection *m_val, ConnList *m_next) { + assert(m_val != NULL); + val = m_val; + next = m_next; + } + ~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; } + private: - Connection * val; - ConnList * next; + 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; - if (DEBUG) - std::cout << "PROC: Process created at " << this << 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; - if (m_name == NULL) - name = NULL; - else - name = strdup(m_name); + if (m_name == NULL) + name = NULL; + else + name = strdup(m_name); - devicename = m_devicename; - connections = NULL; - pid = 0; - uid = 0; - } - void check () { - assert (pid >= 0); - } - - ~Process () - { - free (name); - if (DEBUG) - std::cout << "PROC: Process deleted at " << this << std::endl; - } - int getLastPacket (); + devicename = m_devicename; + connections = NULL; + pid = 0; + uid = 0; + } + void check() { assert(pid >= 0); } - void gettotal( u_int32_t * recvd, u_int32_t * sent); - void getkbps (float * recvd, float * sent); - void gettotalmb(float * recvd, float * sent); - void gettotalkb(float * recvd, float * sent); - void gettotalb (float * recvd, float * sent); + ~Process() { + free(name); + if (DEBUG) + std::cout << "PROC: Process deleted at " << this << std::endl; + } + int getLastPacket(); - char * name; - const char * devicename; - int pid; + void gettotal(u_int32_t *recvd, u_int32_t *sent); + void getkbps(float *recvd, float *sent); + void gettotalmb(float *recvd, float *sent); + void gettotalkb(float *recvd, float *sent); + void gettotalb(float *recvd, float *sent); - ConnList * connections; - uid_t getUid() - { - return uid; - } + char *name; + const char *devicename; + int pid; - void setUid(uid_t m_uid) - { - uid = m_uid; - } + ConnList *connections; + uid_t getUid() { return 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; + const unsigned long inode; + uid_t uid; }; -class ProcList -{ +class ProcList { public: - ProcList (Process * m_val, ProcList * m_next) - { - assert (m_val != NULL); - val = m_val; next = m_next; - } - int size (); - Process * getVal () { return val; } - ProcList * getNext () { return next; } - ProcList * next; + ProcList(Process *m_val, ProcList *m_next) { + assert(m_val != NULL); + val = m_val; + next = m_next; + } + int size(); + Process *getVal() { return val; } + ProcList *getNext() { return next; } + ProcList *next; + private: - Process * val; + Process *val; }; -Process * getProcess (Connection * connection, const char * devicename = NULL); +Process *getProcess(Connection *connection, const char *devicename = NULL); -void process_init (); +void process_init(); -void refreshconninode (); +void refreshconninode(); -void procclean (); +void procclean(); #endif