* when a packet's owner cannot be found (for example if it has already disappeared,

which can happen with for example small fast HTTP requests), show the source and
  destination ports and ip's
* support UDP packets (which never have owners)
* nicely truncate oversized program names
This commit is contained in:
Arnout Engelen
2005-08-27 11:49:16 +00:00
parent c4ac4e55eb
commit 4182fc0b17
5 changed files with 138 additions and 30 deletions

32
cui.cpp
View File

@@ -12,7 +12,10 @@ std::string * caption;
const char version[] = " version " VERSION "." SUBVERSION "." MINORVERSION;
extern ProcList * processes;
extern timeval curtime;
extern Process * unknownproc;
extern Process * unknowntcp;
extern Process * unknownudp;
extern Process * unknownip;
class Line
{
@@ -74,6 +77,7 @@ void Line::show (int row)
{
assert (m_uid >= 0);
assert (m_pid >= 0);
assert (m_pid <= 100000);
}
if (DEBUG || tracemode)
@@ -86,7 +90,17 @@ void Line::show (int row)
char * username = uid2username(m_uid);
mvprintw (3+row, 6, "%s", username);
free (username);
mvprintw (3+row, 6 + 9, "%s", m_name);
if (strlen (m_name) > PROGNAME_WIDTH) {
// truncate oversized names
char * tmp = strdup(m_name);
char * start = tmp + strlen (m_name) - PROGNAME_WIDTH;
start[0] = '.';
start[1] = '.';
mvprintw (3+row, 6 + 9, "%s", start);
free (tmp);
} else {
mvprintw (3+row, 6 + 9, "%s", m_name);
}
mvprintw (3+row, 6 + 9 + PROGNAME_WIDTH + 2, "%s", devicename);
mvprintw (3+row, 6 + 9 + PROGNAME_WIDTH + 2 + 6, "%10.3f", sent_kbps);
mvprintw (3+row, 6 + 9 + PROGNAME_WIDTH + 2 + 6 + 9 + 3, "%10.3f", recv_kbps);
@@ -193,10 +207,12 @@ void do_refresh()
assert (curproc->getVal() != NULL);
assert (nproc == processes->size());
}
/* do not remove the unknown process */
if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <= curtime.tv_sec) && (curproc->getVal() != unknownproc))
/* remove timed-out processes (unless it's the unknown process) */
if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <= curtime.tv_sec)
&& (curproc->getVal() != unknowntcp)
&& (curproc->getVal() != unknownudp)
&& (curproc->getVal() != unknownip))
{
/* remove process */
if (DEBUG)
std::cout << "PROC: Deleting process\n";
ProcList * todelete = curproc;
@@ -220,8 +236,8 @@ void do_refresh()
u_int32_t sum_sent = 0,
sum_recv = 0;
/* walk though all this process's connections, and sum them
* up */
/* walk though all this process's connections, and sum
* them up */
ConnList * curconn = curproc->getVal()->connections;
ConnList * previous = NULL;
while (curconn != NULL)
@@ -286,7 +302,7 @@ void do_refresh()
}
if (tracemode || DEBUG) {
/* print the 'unknown' connections, for debugging */
ConnList * curr_unknownconn = unknownproc->connections;
ConnList * curr_unknownconn = unknowntcp->connections;
while (curr_unknownconn != NULL) {
std::cout << "Unknown connection: " <<
curr_unknownconn->getVal()->refpacket->gethashstring() << std::endl;

View File

@@ -68,12 +68,16 @@ char * getprogname (char * pid) {
if (length < bufsize - 1)
buffer[length]='\0';
char * retval;
char * retval = buffer;
/* this removed directory names, but that malfunctions
* when the program name is like "sshd: arnouten@pts/8"
if ((retval = strrchr(buffer, '/')))
retval++;
else
retval = buffer;
*/
// truncating is now done where it should be, in cui.cpp
return strdup(retval);
}
@@ -105,12 +109,16 @@ void get_info_by_linkname (char * pid, char * linkname) {
}
}
/* updates the `inodeproc' inode-to-prg_node
* for all inodes belonging to this PID
* (/proc/pid/fd/*)
* */
void get_info_for_pid(char * pid) {
size_t dirlen = 10 + strlen(pid);
char * dirname = (char *) malloc (dirlen * sizeof(char));
snprintf(dirname, dirlen, "/proc/%s/fd", pid);
//std::cout << "Entering directory " << dirname << std::endl;
//std::cout << "Getting info for pid " << pid << std::endl;
DIR * dir = opendir(dirname);
@@ -153,11 +161,13 @@ void get_info_for_pid(char * pid) {
free (dirname);
}
/* updates the `inodeproc' inode-to-prg_node mapping
* for all processes in /proc */
void reread_mapping () {
DIR * proc = opendir ("/proc");
if (proc == 0) {
std::cerr << "Error getting inode-to-pid mapping\n";
std::cerr << "Error reading /proc, neede to get inode-to-pid-maping\n";
exit(1);
}

View File

@@ -14,6 +14,7 @@
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include "cui.h"
@@ -26,6 +27,8 @@ extern "C" {
#include "process.h"
#include "refresh.h"
extern Process * unknownudp;
unsigned refreshdelay = 1;
bool tracemode = false;
bool needrefresh = true;
@@ -124,6 +127,51 @@ int process_tcp (u_char * userdata, const dp_header * header, const u_char * m_p
return true;
}
int process_udp (u_char * userdata, const dp_header * header, const u_char * m_packet) {
struct dpargs * args = (struct dpargs *) userdata;
//struct tcphdr * tcp = (struct tcphdr *) m_packet;
struct udphdr * udp = (struct udphdr *) m_packet;
curtime = header->ts;
/* TODO get info from userdata, then call getPacket */
Packet * packet;
switch (args->sa_family)
{
case (AF_INET):
packet = new Packet (args->ip_src, ntohs(udp->source), args->ip_dst, ntohs(udp->dest), header->len, header->ts);
break;
case (AF_INET6):
packet = new Packet (args->ip6_src, ntohs(udp->source), args->ip6_dst, ntohs(udp->dest), header->len, header->ts);
break;
}
//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, currentdevice);
}
delete packet;
if (needrefresh)
{
do_refresh();
needrefresh = false;
}
/* we're done now. */
return true;
}
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;
@@ -275,6 +323,7 @@ int main (int argc, char** argv)
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_tcp, process_udp);
if (newhandle != NULL)
{
/* The following code solves sf.net bug 1019381, but is only available

View File

@@ -36,7 +36,9 @@
// assertions. good for finding bugs
// at an early stage of development.
// for production, should be 1.
#define ROBUST 1
#define ROBUST 0
#define REVERSEHACK 0
// 2 times: 32 characters, 7 ':''s, a ':12345'.
// 1 '-'
@@ -88,8 +90,8 @@ public:
address[37] = m_address[30]; address[38] = m_address[31];
address[39] = 0;
string = strdup(address);
if (DEBUG)
std::cout << "Converting address " << address << std::endl;
//if (DEBUG)
// std::cout << "Converting address " << address << std::endl;
int result = inet_pton (AF_INET6, address, &addr6);

View File

@@ -31,16 +31,31 @@ extern local_addr * local_addrs;
std::map <std::string, unsigned long> conninode;
/*
* Initialise the global process-list with `the' unknown process
* Initialise the global process-list with some special processes:
* * unknown TCP traffic
* * UDP traffic
* * unknown IP traffic
* We must take care this one never gets removed from the list.
*/
Process * unknownproc;
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 <std::string, Process*> unknownprocs;
void process_init ()
{
unknownproc = new Process (0, "", "unknown");
processes = new ProcList (unknownproc, NULL);
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()
@@ -226,7 +241,7 @@ Process * findProcess (unsigned long inode)
* connections are now known */
void reviewUnknown ()
{
ConnList * curr_conn = unknownproc->connections;
ConnList * curr_conn = unknowntcp->connections;
ConnList * previous_conn = NULL;
while (curr_conn != NULL) {
@@ -234,12 +249,13 @@ void reviewUnknown ()
if (inode != 0)
{
Process * proc = findProcess (inode);
if (proc != unknownproc && proc != NULL)
if (proc != unknowntcp && proc != NULL)
{
if (DEBUG)
std::cout << "ITP: WARNING: Previously unknown inode " << inode << " now got process...??\n";
/* Yay! - but how could this happen? */
//assert(false);
/* Yay! - but how can this happen? */
if (!ROBUST)
assert(false);
if (previous_conn != NULL)
{
previous_conn->setNext (curr_conn->getNext());
@@ -249,10 +265,10 @@ void reviewUnknown ()
}
else
{
unknownproc->connections = curr_conn->getNext();
unknowntcp->connections = curr_conn->getNext();
proc->connections = new ConnList (curr_conn->getVal(), proc->connections);
delete curr_conn;
curr_conn = unknownproc->connections;
curr_conn = unknowntcp->connections;
}
}
}
@@ -275,7 +291,8 @@ void refreshconninode ()
}
addprocinfo ("/proc/net/tcp6");
reviewUnknown();
if (DEBUG)
reviewUnknown();
}
@@ -309,7 +326,11 @@ Process * getProcess (unsigned long inode, char * devicename)
struct prg_node * node = findPID(inode);
if (node == NULL)
return unknownproc;
{
if (DEBUG)
std::cout << "No PID information for inode " << inode << std::endl;
return unknowntcp;
}
Process * proc = findProcess (node);
@@ -370,6 +391,7 @@ Process * getProcess (Connection * connection, char * devicename)
#endif
refreshconninode();
inode = conninode[connection->refpacket->gethashstring()];
#if REVERSEHACK
if (inode == 0)
{
/* HACK: the following is a hack for cases where the
@@ -378,7 +400,6 @@ Process * getProcess (Connection * connection, char * devicename)
/* we reverse the direction of the stream if
* successful. */
Packet * reversepacket = connection->refpacket->newInverted();
inode = conninode[reversepacket->gethashstring()];
@@ -387,16 +408,26 @@ Process * getProcess (Connection * connection, char * devicename)
delete reversepacket;
if (DEBUG)
std::cout << "LOC: " << connection->refpacket->gethashstring() << " STILL not in connection-to-inode table - adding to the unknown process\n";
unknownproc->connections = new ConnList (connection, unknownproc->connections);
return unknownproc;
unknowntcp->connections = new ConnList (connection, unknowntcp->connections);
return unknowntcp;
}
delete connection->refpacket;
connection->refpacket = reversepacket;
}
#endif
}
Process * proc;
if (inode == 0) {
proc = new Process (0, "", connection->refpacket->gethashstring());
processes = new ProcList (proc, processes);
}
else
{
proc = getProcess(inode, devicename);
}
Process * proc = getProcess(inode, devicename);
proc->connections = new ConnList (connection, proc->connections);
return proc;
}