several bugfixes, including some memory management

This commit is contained in:
Arnout Engelen
2004-09-14 16:14:23 +00:00
parent a695b7db2a
commit cf2f473cd1
7 changed files with 82 additions and 51 deletions

7
DESIGN
View File

@@ -21,3 +21,10 @@ the unknownproc's connections whenever the connection-to-inode table is
refreshed. refreshed.
And maybe, while there are still unknown connections, the connection-to-inode And maybe, while there are still unknown connections, the connection-to-inode
table should be updated regularly. table should be updated regularly.
There are some global data structures:
connection.cpp:
connections. 'ConnList' list containting all currently known connections.
A connection removes itself from the global 'connections' list in its
destructor.

View File

@@ -43,7 +43,8 @@ bpf_u_int32 PackList::sumanddel (timeval t)
while (current != NULL) while (current != NULL)
{ {
if (current->val->isOlderThan(t)) //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) if (current == content)
content = NULL; content = NULL;
@@ -83,11 +84,36 @@ Connection::~Connection ()
{ {
if (DEBUG) if (DEBUG)
std::cout << "Deleting connection" << std::endl; std::cout << "Deleting connection" << std::endl;
delete refpacket; /* refpacket is a pointer to one of the packets in the lists,
* so not deleted */
//delete refpacket;
if (sent_packets != NULL) if (sent_packets != NULL)
delete sent_packets; delete sent_packets;
if (recv_packets != NULL) if (recv_packets != NULL)
delete recv_packets; delete recv_packets;
ConnList * curr_conn = connections;
ConnList * prev_conn = NULL;
while (curr_conn != NULL)
{
if (curr_conn->val == this)
{
ConnList * todelete = curr_conn;
curr_conn = curr_conn->next;
if (prev_conn == NULL)
{
connections = curr_conn;
} else {
prev_conn->next = curr_conn;
}
delete (todelete);
}
else
{
prev_conn = curr_conn;
curr_conn = curr_conn->next;
}
}
} }
void Connection::add (Packet * packet) void Connection::add (Packet * packet)

View File

@@ -5,6 +5,7 @@
#include <ctype.h> #include <ctype.h>
#include <unistd.h> #include <unistd.h>
#include <malloc.h> #include <malloc.h>
#include <assert.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>

View File

@@ -19,6 +19,10 @@
* after which a process is removed */ * after which a process is removed */
#define PROCESSTIMEOUT 150 #define PROCESSTIMEOUT 150
/* the amount of time after the last packet was recieved
* after which a connection is removed */
#define CONNTIMEOUT 50
/* Set to '0' when compiling for a system that uses Linux Capabilities, /* Set to '0' when compiling for a system that uses Linux Capabilities,
* like www.adamantix.org: in that case nethogs shouldn't check if it's * like www.adamantix.org: in that case nethogs shouldn't check if it's
* running as root. Take care to give it sufficient privileges though. */ * running as root. Take care to give it sufficient privileges though. */

View File

@@ -218,7 +218,8 @@ bool sameinaddr(in_addr one, in_addr other)
} }
bool Packet::isOlderThan (timeval t) { bool Packet::isOlderThan (timeval t) {
return (time.tv_sec + PERIOD <= t.tv_sec); std::cout << "Comparing " << time.tv_sec << " <= " << t.tv_sec << endl;
return (time.tv_sec <= t.tv_sec);
} }
bool Packet::Outgoing () { bool Packet::Outgoing () {

View File

@@ -19,22 +19,6 @@ extern timeval curtime;
extern std::string * caption; extern std::string * caption;
extern local_addr * local_addrs; extern local_addr * local_addrs;
/* takes the text in bufp, and uses it to fill the sockaddr *sap. */
/*static int INET6_getsock(char *bufp, struct sockaddr *sap)
{
struct sockaddr_in6 *sin6;
sin6 = (struct sockaddr_in6 *) sap;
sin6->sin6_family = AF_INET6;
sin6->sin6_port = 0;
if (inet_pton(AF_INET6, bufp, sin6->sin6_addr.s6_addr) <= 0)
return (-1);
return 16;
}
*/
class ProcList class ProcList
{ {
public: public:
@@ -51,25 +35,6 @@ private:
Process * val; Process * val;
}; };
struct aftype {
char *name;
char *title;
int af;
int alen;
char *(*print) (unsigned char *);
char *(*sprint) (struct sockaddr *, int numeric);
int (*input) (int type, char *bufp, struct sockaddr *);
void (*herror) (char *text);
int (*rprint) (int options);
int (*rinput) (int typ, int ext, char **argv);
/* may modify src */
int (*getmask) (char *src, struct sockaddr * mask, char *name);
int fd;
char *flag_file;
};
/* /*
* connection-inode table. takes information from /proc/net/tcp. * connection-inode table. takes information from /proc/net/tcp.
* key contains source ip, source port, destination ip, destination * key contains source ip, source port, destination ip, destination
@@ -103,11 +68,9 @@ void addtoconninode (char * buffer)
char addr6[INET6_ADDRSTRLEN]; char addr6[INET6_ADDRSTRLEN];
struct in6_addr in6_local; struct in6_addr in6_local;
struct in6_addr in6_remote; struct in6_addr in6_remote;
extern struct aftype inet6_aftype; // the following line might leak memory.
// the following line leaks memory.
unsigned long * inode = (unsigned long *) malloc (sizeof(unsigned long)); unsigned long * inode = (unsigned long *) malloc (sizeof(unsigned long));
// TODO check it matched
int matches = sscanf(buffer, "%*d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %*X %*lX:%*lX %*X:%*lX %*lX %*d %*d %ld %*512s\n", int matches = sscanf(buffer, "%*d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %*X %*lX:%*lX %*X:%*lX %*lX %*d %*d %ld %*512s\n",
local_addr, &local_port, rem_addr, &rem_port, inode); local_addr, &local_port, rem_addr, &rem_port, inode);
@@ -216,6 +179,13 @@ struct prg_node * findPID (unsigned long inode)
{ {
/* find PID */ /* find PID */
struct prg_node * node = prg_cache_get(inode); struct prg_node * node = prg_cache_get(inode);
if (node != NULL && node->pid == 1)
{
prg_cache_clear();
prg_cache_load();
node = prg_cache_get(inode);
assert (node->pid != 1);
}
if (node == NULL) if (node == NULL)
{ {
@@ -329,7 +299,6 @@ char * uid2username (int uid)
} }
} }
class Line class Line
{ {
public: public:
@@ -436,6 +405,7 @@ void do_refresh()
assert (curproc != NULL); assert (curproc != NULL);
assert (curproc->getVal() != NULL); assert (curproc->getVal() != NULL);
} }
/* do not remove the unknown process */
if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <= curtime.tv_sec) && (curproc->getVal() != unknownproc)) if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <= curtime.tv_sec) && (curproc->getVal() != unknownproc))
{ {
/* remove connection */ /* remove connection */
@@ -455,22 +425,39 @@ void do_refresh()
continue; continue;
} }
bpf_u_int32 sum = 0, bpf_u_int32 sum_sent = 0,
sum_local = 0, sum_recv = 0;
sum_conn = 0,
sum_connLocal = 0;
/* walk though all this process's connections, and sum them /* walk though all this process's connections, and sum them
* up */ * up */
ConnList * curconn = curproc->getVal()->connections; ConnList * curconn = curproc->getVal()->connections;
ConnList * previous = NULL;
while (curconn != NULL) while (curconn != NULL)
{ {
curconn->getVal()->sumanddel(curtime, &sum, &sum_local); if (curconn->getVal()->getLastPacket() <= curtime.tv_sec - CONNTIMEOUT)
sum_connLocal += sum_local; {
sum_conn += sum; /* stalled connection, remove. */
ConnList * todelete = curconn;
Connection * conn_todelete = curconn->getVal();
curconn = curconn->getNext();
if (todelete == curproc->getVal()->connections)
curproc->getVal()->connections = curconn;
if (previous != NULL)
previous->setNext(curconn);
delete (todelete);
delete (conn_todelete);
}
else
{
bpf_u_int32 sent = 0, recv = 0;
curconn->getVal()->sumanddel(curtime, &sent, &recv);
sum_sent += sent;
sum_recv += recv;
previous = curconn;
curconn = curconn->getNext(); curconn = curconn->getNext();
} }
lines[n] = new Line (curproc->getVal()->name, tokbps(sum_conn), tokbps(sum_connLocal), curproc->getVal()->pid, curproc->getVal()->uid, curproc->getVal()->devicename); }
lines[n] = new Line (curproc->getVal()->name, tokbps(sum_sent), tokbps(sum_recv), curproc->getVal()->pid, curproc->getVal()->uid, curproc->getVal()->devicename);
previousproc = curproc; previousproc = curproc;
curproc = curproc->next; curproc = curproc->next;
n++; n++;

View File

@@ -16,6 +16,11 @@ public:
assert (m_val != NULL); assert (m_val != NULL);
val = m_val; next = m_next; 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 () Connection * getVal ()
{ {
return val; return val;