bugtracking mode, performance improvement by earlier caching of inode2pid data
This commit is contained in:
@@ -154,18 +154,33 @@ void Connection::add (Packet * packet)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* finds connection to which this packet belongs.
|
/*
|
||||||
|
* finds connection to which this packet belongs.
|
||||||
* a packet belongs to a connection if it matches
|
* a packet belongs to a connection if it matches
|
||||||
* to its reference packet */
|
* to its reference packet
|
||||||
|
*/
|
||||||
Connection * findConnection (Packet * packet)
|
Connection * findConnection (Packet * packet)
|
||||||
{
|
{
|
||||||
ConnList * current = connections;
|
ConnList * current = connections;
|
||||||
Packet * invertedPacket = packet->newInverted();
|
|
||||||
while (current != NULL)
|
while (current != NULL)
|
||||||
{
|
{
|
||||||
/* the reference packet is always *outgoing* */
|
/* the reference packet is always *outgoing* */
|
||||||
if ((packet->match(current->val->refpacket))
|
if (packet->match(current->val->refpacket))
|
||||||
|| (invertedPacket->match(current->val->refpacket)))
|
{
|
||||||
|
return current->val;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try again, now with the packet inverted:
|
||||||
|
current = connections;
|
||||||
|
Packet * invertedPacket = packet->newInverted();
|
||||||
|
|
||||||
|
while (current != NULL)
|
||||||
|
{
|
||||||
|
/* the reference packet is always *outgoing* */
|
||||||
|
if (invertedPacket->match(current->val->refpacket))
|
||||||
{
|
{
|
||||||
delete invertedPacket;
|
delete invertedPacket;
|
||||||
return current->val;
|
return current->val;
|
||||||
@@ -173,6 +188,7 @@ Connection * findConnection (Packet * packet)
|
|||||||
|
|
||||||
current = current->next;
|
current = current->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete invertedPacket;
|
delete invertedPacket;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
3
cui.cpp
3
cui.cpp
@@ -2,6 +2,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@@ -386,7 +387,7 @@ void do_refresh()
|
|||||||
|
|
||||||
if (viewMode == VIEWMODE_KBPS)
|
if (viewMode == VIEWMODE_KBPS)
|
||||||
{
|
{
|
||||||
std::cout << "kbps viemode" << std::endl;
|
//std::cout << "kbps viemode" << std::endl;
|
||||||
getkbps (curproc->getVal(), &value_recv, &value_sent);
|
getkbps (curproc->getVal(), &value_recv, &value_sent);
|
||||||
}
|
}
|
||||||
else if (viewMode == VIEWMODE_TOTAL_KB)
|
else if (viewMode == VIEWMODE_TOTAL_KB)
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
#include "inode2prog.h"
|
#include "inode2prog.h"
|
||||||
|
|
||||||
|
extern bool bughuntmode;
|
||||||
|
|
||||||
/* maps from inode to program-struct */
|
/* maps from inode to program-struct */
|
||||||
std::map <unsigned long, prg_node *> inodeproc;
|
std::map <unsigned long, prg_node *> inodeproc;
|
||||||
|
|
||||||
@@ -193,11 +195,29 @@ struct prg_node * findPID (unsigned long inode)
|
|||||||
struct prg_node * node = inodeproc[inode];
|
struct prg_node * node = inodeproc[inode];
|
||||||
|
|
||||||
if (node != NULL)
|
if (node != NULL)
|
||||||
|
{
|
||||||
|
if (bughuntmode)
|
||||||
|
{
|
||||||
|
std::cout << ":) Found pid in inodeproc table" << std::endl;
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
reread_mapping();
|
reread_mapping();
|
||||||
|
|
||||||
return inodeproc[inode];
|
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() {};
|
||||||
|
|||||||
@@ -14,3 +14,6 @@ struct prg_node {
|
|||||||
struct prg_node * findPID (unsigned long inode);
|
struct prg_node * findPID (unsigned long inode);
|
||||||
|
|
||||||
void prg_cache_clear();
|
void prg_cache_clear();
|
||||||
|
|
||||||
|
// reread the inode-to-prg_node-mapping
|
||||||
|
void reread_mapping ();
|
||||||
|
|||||||
14
nethogs.cpp
14
nethogs.cpp
@@ -31,6 +31,7 @@ extern Process * unknownudp;
|
|||||||
|
|
||||||
unsigned refreshdelay = 1;
|
unsigned refreshdelay = 1;
|
||||||
bool tracemode = false;
|
bool tracemode = false;
|
||||||
|
bool bughuntmode = false;
|
||||||
bool needrefresh = true;
|
bool needrefresh = true;
|
||||||
//packet_type packettype = packet_ethernet;
|
//packet_type packettype = packet_ethernet;
|
||||||
//dp_link_type linktype = dp_link_ethernet;
|
//dp_link_type linktype = dp_link_ethernet;
|
||||||
@@ -89,7 +90,7 @@ int process_tcp (u_char * userdata, const dp_header * header, const u_char * m_p
|
|||||||
|
|
||||||
curtime = header->ts;
|
curtime = header->ts;
|
||||||
|
|
||||||
/* TODO get info from userdata, then call getPacket */
|
/* get info from userdata, then call getPacket */
|
||||||
Packet * packet;
|
Packet * packet;
|
||||||
switch (args->sa_family)
|
switch (args->sa_family)
|
||||||
{
|
{
|
||||||
@@ -101,9 +102,6 @@ int process_tcp (u_char * userdata, const dp_header * header, const u_char * m_p
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (DEBUG)
|
|
||||||
// std::cout << "Got packet from " << packet->gethashstring() << std::endl;
|
|
||||||
|
|
||||||
Connection * connection = findConnection(packet);
|
Connection * connection = findConnection(packet);
|
||||||
|
|
||||||
if (connection != NULL)
|
if (connection != NULL)
|
||||||
@@ -229,12 +227,13 @@ static void versiondisplay(void)
|
|||||||
|
|
||||||
static void help(void)
|
static void help(void)
|
||||||
{
|
{
|
||||||
//std::cerr << "usage: nethogs [-V] [-d seconds] [-t] [-p] [-f (eth|ppp))] [device [device [device ...]]]\n";
|
//std::cerr << "usage: nethogs [-V] [-b] [-d seconds] [-t] [-p] [-f (eth|ppp))] [device [device [device ...]]]\n";
|
||||||
std::cerr << "usage: nethogs [-V] [-d seconds] [-t] [-p] [device [device [device ...]]]\n";
|
std::cerr << "usage: nethogs [-V] [-b] [-d seconds] [-t] [-p] [device [device [device ...]]]\n";
|
||||||
std::cerr << " -V : prints version.\n";
|
std::cerr << " -V : prints version.\n";
|
||||||
std::cerr << " -d : delay for update refresh rate in seconds. default is 1.\n";
|
std::cerr << " -d : delay for update refresh rate in seconds. default is 1.\n";
|
||||||
std::cerr << " -t : tracemode.\n";
|
std::cerr << " -t : tracemode.\n";
|
||||||
//std::cerr << " -f : format of packets on interface, default is eth.\n";
|
//std::cerr << " -f : format of packets on interface, default is eth.\n";
|
||||||
|
std::cerr << " -b : bughunt mode - implies tracemode.\n";
|
||||||
std::cerr << " -p : sniff in promiscious mode (not recommended).\n";
|
std::cerr << " -p : sniff in promiscious mode (not recommended).\n";
|
||||||
std::cerr << " device : device(s) to monitor. default is eth0\n";
|
std::cerr << " device : device(s) to monitor. default is eth0\n";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
@@ -284,6 +283,9 @@ int main (int argc, char** argv)
|
|||||||
exit(0);
|
exit(0);
|
||||||
case 'h': help();
|
case 'h': help();
|
||||||
exit(0);
|
exit(0);
|
||||||
|
case 'b': bughuntmode = true;
|
||||||
|
tracemode = true;
|
||||||
|
break;
|
||||||
case 't': tracemode = true;
|
case 't': tracemode = true;
|
||||||
break;
|
break;
|
||||||
case 'p': promisc = 1;
|
case 'p': promisc = 1;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ void getLocal (const char *device, bool tracemode)
|
|||||||
}
|
}
|
||||||
strcpy(iFreq.ifr_name, device);
|
strcpy(iFreq.ifr_name, device);
|
||||||
if(ioctl(sock, SIOCGIFADDR, &iFreq)<0){
|
if(ioctl(sock, SIOCGIFADDR, &iFreq)<0){
|
||||||
forceExit("ioctl failed while establishing local IP for device ", device);
|
forceExit("ioctl failed while establishing local IP for selected device ", device);
|
||||||
}
|
}
|
||||||
saddr=(struct sockaddr_in*)&iFreq.ifr_addr;
|
saddr=(struct sockaddr_in*)&iFreq.ifr_addr;
|
||||||
local_addrs = new local_addr (saddr->sin_addr.s_addr, local_addrs);
|
local_addrs = new local_addr (saddr->sin_addr.s_addr, local_addrs);
|
||||||
|
|||||||
46
process.cpp
46
process.cpp
@@ -238,7 +238,11 @@ Process * findProcess (unsigned long inode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check if we have identified any previously unknown
|
/* check if we have identified any previously unknown
|
||||||
* connections are now known */
|
* connections are now known
|
||||||
|
*
|
||||||
|
* When this is the case, something weird is going on.
|
||||||
|
* This function is only called in bughunt-mode
|
||||||
|
*/
|
||||||
void reviewUnknown ()
|
void reviewUnknown ()
|
||||||
{
|
{
|
||||||
ConnList * curr_conn = unknowntcp->connections;
|
ConnList * curr_conn = unknowntcp->connections;
|
||||||
@@ -251,8 +255,8 @@ void reviewUnknown ()
|
|||||||
Process * proc = findProcess (inode);
|
Process * proc = findProcess (inode);
|
||||||
if (proc != unknowntcp && proc != NULL)
|
if (proc != unknowntcp && proc != NULL)
|
||||||
{
|
{
|
||||||
if (DEBUG)
|
if (DEBUG || bughuntmode)
|
||||||
std::cout << "ITP: WARNING: Previously unknown inode " << inode << " now got process...??\n";
|
std::cout << "FIXME: Previously unknown inode " << inode << " now got process - apparently it makes sense to review unknown connections\n";
|
||||||
/* Yay! - but how can this happen? */
|
/* Yay! - but how can this happen? */
|
||||||
if (!ROBUST)
|
if (!ROBUST)
|
||||||
assert(false);
|
assert(false);
|
||||||
@@ -327,7 +331,7 @@ Process * getProcess (unsigned long inode, char * devicename)
|
|||||||
|
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
{
|
{
|
||||||
if (DEBUG)
|
if (DEBUG || bughuntmode)
|
||||||
std::cout << "No PID information for inode " << inode << std::endl;
|
std::cout << "No PID information for inode " << inode << std::endl;
|
||||||
return unknowntcp;
|
return unknowntcp;
|
||||||
}
|
}
|
||||||
@@ -386,11 +390,28 @@ Process * getProcess (Connection * connection, char * devicename)
|
|||||||
if (inode == 0)
|
if (inode == 0)
|
||||||
{
|
{
|
||||||
// no? refresh and check conn/inode table
|
// no? refresh and check conn/inode table
|
||||||
#if DEBUG
|
if (bughuntmode)
|
||||||
std::cout << "LOC: new connection not in connection-to-inode table.\n";
|
{
|
||||||
#endif
|
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).
|
||||||
|
reread_mapping();
|
||||||
refreshconninode();
|
refreshconninode();
|
||||||
inode = conninode[connection->refpacket->gethashstring()];
|
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 REVERSEHACK
|
||||||
if (inode == 0)
|
if (inode == 0)
|
||||||
{
|
{
|
||||||
@@ -406,7 +427,7 @@ Process * getProcess (Connection * connection, char * devicename)
|
|||||||
if (inode == 0)
|
if (inode == 0)
|
||||||
{
|
{
|
||||||
delete reversepacket;
|
delete reversepacket;
|
||||||
if (DEBUG)
|
if (bughuntmode || DEBUG)
|
||||||
std::cout << "LOC: " << connection->refpacket->gethashstring() << " STILL not in connection-to-inode table - adding to the unknown process\n";
|
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);
|
unknowntcp->connections = new ConnList (connection, unknowntcp->connections);
|
||||||
return unknowntcp;
|
return unknowntcp;
|
||||||
@@ -417,6 +438,15 @@ Process * getProcess (Connection * connection, char * devicename)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
else if (bughuntmode)
|
||||||
|
{
|
||||||
|
std::cout << ";) new connection in connection-to-inode table before refresh.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bughuntmode)
|
||||||
|
{
|
||||||
|
std::cout << " inode # " << inode << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
Process * proc;
|
Process * proc;
|
||||||
if (inode == 0) {
|
if (inode == 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user