fixed some bugs, cleaned a lot of code,

re-added support for PPP
automatic detection of link-layer protocol
This commit is contained in:
Arnout Engelen
2004-09-14 11:23:59 +00:00
parent 23a56f95a6
commit a695b7db2a
8 changed files with 279 additions and 354 deletions

23
DESIGN Normal file
View File

@@ -0,0 +1,23 @@
Rough design notitions:
decpcap handles pcap. nethogs.cpp asks to be notified of all IPv4 or IPv6
TCP packets.
the IP callbacks store the source and destination addresses into the user
data. The TCP callback makes a Packet out of it, finds the Connection
corresponding to that packet, and adds the packet to the connection.
If no connection is found, a new one is constructed, and the process
related to that connection is found though getProcess.
If needed, the screen is refreshed.
If, in getProcess, no corresponding process is found, the connection is
added to the 'unknown' process.
To prevent connections from accidentally ending up in the 'unknown' process,
and then staying there indefinitely, we should maybe walk though
the unknownproc's connections whenever the connection-to-inode table is
refreshed.
And maybe, while there are still unknown connections, the connection-to-inode
table should be updated regularly.

View File

@@ -10,7 +10,7 @@
/* functions to set up a handle (which is basically just a pcap handle) */
struct dp_handle * dp_open_live(char * device, enum dp_link_type link, int snaplen, int promisc, int to_ms, char * ebuf)
struct dp_handle * dp_open_live(char * device, int snaplen, int promisc, int to_ms, char * ebuf)
{
struct dp_handle * retval = (struct dp_handle *) malloc (sizeof (struct dp_handle));
pcap_t * temp = pcap_open_live(device, snaplen, promisc, to_ms, ebuf);
@@ -27,7 +27,8 @@ struct dp_handle * dp_open_live(char * device, enum dp_link_type link, int snapl
{
retval->callback[i] = NULL;
}
retval->linktype = link;
retval->linktype = pcap_datalink(retval->pcap_handle);
return retval;
}
@@ -186,11 +187,11 @@ void dp_pcap_callback (u_char * u_handle, const struct pcap_pkthdr * header, con
memcpy (userdata_copy, handle->userdata, handle->userdata_size);
switch (handle->linktype) {
case (dp_link_ethernet):
case (DLT_EN10MB):
dp_parse_ethernet (handle, header, packet);
break;
case (dp_link_ppp):
// TODO
case (DLT_PPP):
dp_parse_ppp (handle, header, packet);
break;
default:
// TODO maybe error? or 'other' callback?

View File

@@ -14,11 +14,11 @@ enum dp_packet_type {
dp_n_packet_types
};
enum dp_link_type {
/*enum dp_link_type {
dp_link_ethernet,
dp_link_ppp,
dp_n_link_types
};
};*/
/*struct dp_header {
};*/
@@ -29,14 +29,14 @@ 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];
enum dp_link_type linktype;
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(char * device, enum dp_link_type link, int snaplen, int promisc, int to_ms, char * ebuf);
struct dp_handle * dp_open_live(char * device, int snaplen, int promisc, int to_ms, char * ebuf);
/* functions to add callbacks */
@@ -49,3 +49,7 @@ 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);
/* functions that simply call libpcap */
int dp_datalink(struct dp_handle * handle);

View File

@@ -67,7 +67,7 @@ HashNode * HashTable::newHashNode(char * key, void * content, HashNode * next)
void HashTable::add(char * key, void * content)
{
unsigned int hkey = HashString (key);
//cout << "Adding node: " << key << " key " << hkey << endl;
//std::cout << "(STILL)Adding node: " << key << " key " << hkey << endl;
table[hkey] = newHashNode(key, content, table[hkey]);
}

169
inet6.c
View File

@@ -1,169 +0,0 @@
/*
* lib/inet6.c This file contains an implementation of the "INET6"
* support functions for the net-tools.
* (most of it copied from lib/inet.c 1.26).
*
* Version: $Id$
*
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
* Copyright 1993 MicroWalt Corporation
*
* Modified:
*960808 {0.01} Frank Strauss : adapted for IPv6 support
*980701 {0.02} Arnaldo C. Melo: GNU gettext instead of catgets
*990824 Bernd Eckenfels: clear members for selecting v6 address
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
* Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at
* your option) any later version.
*/
#include <asm/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
/*
#include "version.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"
*/
extern int h_errno; /* some netdb.h versions don't export this */
static int INET6_resolve(char *name, struct sockaddr_in6 *sin6)
{
struct addrinfo req, *ai;
int s;
memset (&req, '\0', sizeof req);
req.ai_family = AF_INET6;
if ((s = getaddrinfo(name, NULL, &req, &ai))) {
fprintf(stderr, "getaddrinfo: %s: %d\n", name, s);
return -1;
}
memcpy(sin6, ai->ai_addr, sizeof(struct sockaddr_in6));
freeaddrinfo(ai);
return (0);
}
#ifndef IN6_IS_ADDR_UNSPECIFIED
#define IN6_IS_ADDR_UNSPECIFIED(a) \
(((__u32 *) (a))[0] == 0 && ((__u32 *) (a))[1] == 0 && \
((__u32 *) (a))[2] == 0 && ((__u32 *) (a))[3] == 0)
#endif
static int INET6_rresolve(char *name, struct sockaddr_in6 *sin6, int numeric)
{
int s;
/* Grmpf. -FvK */
if (sin6->sin6_family != AF_INET6) {
#ifdef DEBUG
fprintf(stderr, "rresolve: unsupport address family %d !\n",
sin6->sin6_family);
#endif
errno = EAFNOSUPPORT;
return (-1);
}
if (numeric & 0x7FFF) {
inet_ntop(AF_INET6, &sin6->sin6_addr, name, 80);
return (0);
}
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
if (numeric & 0x8000)
strcpy(name, "default");
else
strcpy(name, "*");
return (0);
}
if ((s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6),
name, 255 /* !! */ , NULL, 0, 0))) {
fputs("getnameinfo failed\n", stderr);
return -1;
}
return (0);
}
static void INET6_reserror(char *text)
{
herror(text);
}
/* Display an Internet socket address. */
static char *INET6_print(unsigned char *ptr)
{
static char name[80];
inet_ntop(AF_INET6, (struct in6_addr *) ptr, name, 80);
return name;
}
/* Display an Internet socket address. */
/* dirty! struct sockaddr usually doesn't suffer for inet6 addresses, fst. */
static char *INET6_sprint(struct sockaddr *sap, int numeric)
{
static char buff[128];
if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
return safe_strncpy(buff, "[NONE SET]", sizeof(buff));
if (INET6_rresolve(buff, (struct sockaddr_in6 *) sap, numeric) != 0)
return safe_strncpy(buff, "[UNKNOWN]", sizeof(buff));
return (buff);
}
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; /* ?;) */
}
static int INET6_input(int type, char *bufp, struct sockaddr *sap)
{
switch (type) {
case 1:
return (INET6_getsock(bufp, sap));
default:
return (INET6_resolve(bufp, (struct sockaddr_in6 *) sap));
}
}
struct aftype inet6_aftype =
{
"inet6", NULL, /*"IPv6", */ AF_INET6, sizeof(struct in6_addr),
INET6_print, INET6_sprint, INET6_input, INET6_reserror,
INET6_rprint, INET6_rinput, NULL,
-1,
"/proc/net/if_inet6"
};

View File

@@ -30,7 +30,7 @@ unsigned refreshdelay = 1;
bool tracemode = false;
bool needrefresh = true;
//packet_type packettype = packet_ethernet;
dp_link_type linktype = dp_link_ethernet;
//dp_link_type linktype = dp_link_ethernet;
char * currentdevice = NULL;
@@ -74,34 +74,6 @@ bool local_addr::contains(const struct in6_addr & n_addr) {
return next->contains(n_addr);
}
/* deprecated by process_tcp
* void process (u_char * args, const struct pcap_pkthdr * header, const u_char * m_packet)
{
curtime = header->ts;
Packet * packet = getPacket (header, m_packet, packettype);
if (packet == NULL)
return;
Connection * connection = findConnection(packet);
if (connection != NULL)
{
connection->add(packet);
} else {
connection = new Connection (packet);
if (DEBUG)
std::cerr << "Getting process by connection\n";
Process * process = getProcess(connection, currentdevice);
}
if (needrefresh)
{
do_refresh();
needrefresh = false;
}
}*/
struct dpargs {
int sa_family;
in_addr ip_src;
@@ -138,8 +110,8 @@ int process_tcp (u_char * userdata, const dp_header * header, const u_char * m_p
} else {
/* else: unknown connection, create new */
connection = new Connection (packet);
if (DEBUG)
std::cerr << "Getting process by connection\n";
//if (DEBUG)
// std::cerr << "Getting process by connection\n";
Process * process = getProcess(connection, currentdevice);
}
@@ -201,11 +173,12 @@ static void versiondisplay(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] [-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 << " -V : prints version.\n";
std::cerr << " -d : delay for update refresh rate in seconds. default is 1.\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 << " -p : sniff in promiscious mode (not recommended).\n";
std::cerr << " device : device(s) to monitor. default is eth0\n";
}
@@ -222,7 +195,8 @@ public:
class handle {
public:
handle (dp_handle * m_handle, char * m_devicename = NULL, handle * m_next = NULL) {
handle (dp_handle * m_handle, char * m_devicename = NULL,
handle * m_next = NULL) {
content = m_handle; next = m_next; devicename = m_devicename;
}
dp_handle * content;
@@ -257,7 +231,7 @@ int main (int argc, char** argv)
refreshdelay=atoi(*argv);
}
break;
case 'f': if (argv[1])
/*case 'f': if (argv[1])
{
argv++;
if (strcmp (*argv, "ppp") == 0)
@@ -266,6 +240,7 @@ int main (int argc, char** argv)
linktype = dp_link_ethernet;
}
break;
*/
default : help();
exit(0);
}
@@ -304,7 +279,7 @@ int main (int argc, char** argv)
caption->append(" ");
}
dp_handle * newhandle = dp_open_live(current_dev->name, linktype, BUFSIZ, promisc, 100, errbuf);
dp_handle * newhandle = dp_open_live(current_dev->name, BUFSIZ, promisc, 100, errbuf);
dp_addcb (newhandle, dp_packet_ip, process_ip);
dp_addcb (newhandle, dp_packet_ip6, process_ip6);
dp_addcb (newhandle, dp_packet_tcp, process_tcp);

View File

@@ -19,7 +19,8 @@ extern timeval curtime;
extern std::string * caption;
extern local_addr * local_addrs;
static int INET6_getsock(char *bufp, struct sockaddr *sap)
/* 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;
@@ -30,13 +31,26 @@ static int INET6_getsock(char *bufp, struct sockaddr *sap)
if (inet_pton(AF_INET6, bufp, sin6->sin6_addr.s6_addr) <= 0)
return (-1);
return 16; /* ?;) */
return 16;
}
*/
static int INET6_input(int type, char *bufp, struct sockaddr *sap)
class ProcList
{
return (INET6_getsock(bufp, sap));
}
public:
ProcList (Process * m_val, ProcList * m_next)
{
if (DEBUG)
assert (m_val != NULL);
val = m_val; next = m_next;
}
Process * getVal () { return val; }
ProcList * getNext () { return next; }
ProcList * next;
private:
Process * val;
};
struct aftype {
char *name;
@@ -63,6 +77,9 @@ struct aftype {
*/
HashTable * conninode = new HashTable (256);
Process * unknownproc = new Process (0, "", "unknown");
ProcList * processes = new ProcList (unknownproc, NULL);
/*
* 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
@@ -98,12 +115,12 @@ void addtoconninode (char * buffer)
fprintf(stderr,"Unexpected buffer: '%s'\n",buffer);
exit(0);
}
/*if (*inode == 0) {
// This sometimes happens due to what I think is a bug in the
// kernel. See http://lkml.org/lkml/2004/9/10/193.
fprintf(stderr,"Inode zero: '%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 (strlen(local_addr) > 8)
{
@@ -126,12 +143,12 @@ void addtoconninode (char * buffer)
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;
//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;
@@ -157,7 +174,7 @@ void addtoconninode (char * buffer)
//if (DEBUG)
// fprintf (stderr, "Hashkey: %s\n", hashkey);
conninode->add(hashkey, (void *)inode);
//std::cout << "Adding to conninode\n" << std::endl;
/* 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
@@ -165,6 +182,7 @@ void addtoconninode (char * buffer)
* interfaces */
struct local_addr * current_local_addr = local_addrs;
while (current_local_addr != NULL) {
/* TODO maybe only add the ones with the same sa_family */
hashkey = (char *) malloc (HASHKEYSIZE * sizeof(char));
snprintf(hashkey, HASHKEYSIZE * sizeof(char), "%s:%d-%s:%d", current_local_addr->string, local_port, remote_string, rem_port);
conninode->add(hashkey, (void *)inode);
@@ -173,62 +191,125 @@ void addtoconninode (char * buffer)
free (remote_string);
}
void refreshconninode ()
{
delete conninode;
conninode = new HashTable (256);
int addprocinfo (const char * filename) {
FILE * procinfo = fopen (filename, "r");
char buffer[8192];
FILE * procinfo = fopen ("/proc/net/tcp", "r");
if (procinfo == NULL)
return 0;
// TODO use helper function
if (procinfo)
{
fgets(buffer, sizeof(buffer), procinfo);
do
{
if (fgets(buffer, sizeof(buffer), procinfo))
addtoconninode(buffer);
} while (!feof(procinfo));
fclose(procinfo);
return 1;
}
struct prg_node * findPID (unsigned long inode)
{
/* find PID */
struct prg_node * node = prg_cache_get(inode);
if (node == NULL)
{
prg_cache_clear();
prg_cache_load();
node = prg_cache_get(inode);
if (node == NULL)
{
if (DEBUG)
std::cout << "inode " << inode << " STILL not in inode-to-pid-mapping." << endl;
return NULL;
}
}
return node;
}
Process * findProcess (struct prg_node * node)
{
ProcList * current = processes;
while (current != NULL)
{
if (node->pid == current->getVal()->pid)
return current->getVal();
current = current->next;
}
return NULL;
}
/* finds process based on inode, if any */
Process * findProcess (unsigned long inode)
{
struct prg_node * node = findPID(inode);
if (node == NULL)
return NULL;
return findProcess (node);
}
/* check if we have identified any previously unknown
* connections are now known */
void reviewUnknown ()
{
ConnList * curr_conn = unknownproc->connections;
ConnList * previous_conn = NULL;
while (curr_conn != NULL) {
unsigned long * inode = (unsigned long *)
conninode->get(curr_conn->getVal()->refpacket->gethashstring());
if (inode != NULL)
{
Process * proc = findProcess (*inode);
if (proc != unknownproc && proc != NULL)
{
/* Yay! - but how could this happen? */
if (previous_conn != NULL)
{
previous_conn->setNext (curr_conn->getNext());
proc->connections = new ConnList (curr_conn->getVal(), proc->connections);
delete curr_conn;
curr_conn = previous_conn;
}
else
{
unknownproc->connections = curr_conn->getNext();
proc->connections = new ConnList (curr_conn->getVal(), proc->connections);
delete curr_conn;
curr_conn = unknownproc->connections;
}
}
}
previous_conn = curr_conn;
if (curr_conn != NULL)
curr_conn = curr_conn->getNext();
}
}
void refreshconninode ()
{
/* we don't forget old mappings, just overwrite */
//delete conninode;
//conninode = new HashTable (256);
if (! addprocinfo ("/proc/net/tcp"))
{
std::cout << "Error: couldn't open /proc/net/tcp\n";
exit(0);
}
addprocinfo ("/proc/net/tcp6");
reviewUnknown();
procinfo = fopen ("/proc/net/tcp6", "r");
if (procinfo != NULL) {
fgets(buffer, sizeof(buffer), procinfo);
do {
if (fgets(buffer, sizeof(buffer), procinfo))
addtoconninode(buffer);
} while (!feof(procinfo));
fclose (procinfo);
}
}
class ProcList
{
public:
ProcList (Process * m_val, ProcList * m_next)
{
if (DEBUG)
assert (m_val != NULL);
val = m_val; next = m_next;
}
Process * getVal () { return val; }
ProcList * getNext () { return next; }
ProcList * next;
private:
Process * val;
};
Process * unknownproc = new Process (0, "", "unknown");
ProcList * processes = new ProcList (unknownproc, NULL);
float tokbps (bpf_u_int32 bytes)
{
return (((double)bytes) / PERIOD) / 1024;
@@ -262,8 +343,19 @@ public:
m_uid = uid;
}
void show (int row)
{
void show (int row);
double sent_kbps;
double recv_kbps;
private:
const char * m_name;
const char * devicename;
int m_pid;
int m_uid;
};
void Line::show (int row)
{
if (DEBUG || tracemode)
{
std::cout << m_name << "\t" << sent_kbps << "\t" << recv_kbps << std::endl;
@@ -279,16 +371,7 @@ public:
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);
mvprintw (3+row, 6 + 9 + PROGNAME_WIDTH + 2 + 6 + 9 + 3 + 11, "KB/sec", recv_kbps);
}
double sent_kbps;
double recv_kbps;
private:
const char * m_name;
const char * devicename;
int m_pid;
int m_uid;
};
}
int GreatestFirst (const void * ma, const void * mb)
{
@@ -322,9 +405,10 @@ int count_processes()
// Display all processes and relevant network traffic using show function
void do_refresh()
{
refreshconninode();
if (DEBUG || tracemode)
{
std::cout << "Refreshing:\n";
std::cout << "\n\nRefreshing:\n";
}
else
{
@@ -335,7 +419,7 @@ void do_refresh()
attroff(A_REVERSE);
}
ProcList * curproc = processes;
ProcList * lastproc = NULL;
ProcList * previousproc = NULL;
int nproc = count_processes();
Line * lines [nproc];
int n = 0, i = 0;
@@ -344,9 +428,9 @@ void do_refresh()
while (curproc != NULL)
{
// walk though its connections, summing up
// their data, and throwing away old stuff.
// if the last packet is older than PROCESSTIMEOUT seconds, discard.
// walk though its connections, summing up their data, and
// throwing away connections that haven't received a package
// in the last PROCESSTIMEOUT seconds.
if (DEBUG)
{
assert (curproc != NULL);
@@ -354,9 +438,10 @@ void do_refresh()
}
if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <= curtime.tv_sec) && (curproc->getVal() != unknownproc))
{
if (lastproc)
/* remove connection */
if (previousproc)
{
lastproc->next = curproc->next;
previousproc->next = curproc->next;
ProcList * newcur = curproc->next;
delete curproc;
curproc = newcur;
@@ -367,28 +452,34 @@ void do_refresh()
curproc = processes;
nproc--;
}
continue;
}
else
{
bpf_u_int32 sum = 0,
sum_local = 0,
sum_conn = 0,
sum_connLocal = 0;
/* walk though all this process's connections, and sum them
* up */
ConnList * curconn = curproc->getVal()->connections;
while (curconn != NULL)
{
curconn->getVal()->sumanddel(curtime, &sum, &sum_local);
sum_connLocal+=sum_local;
sum_conn+=sum;
sum_connLocal += sum_local;
sum_conn += sum;
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);
lastproc = curproc;
previousproc = curproc;
curproc = curproc->next;
n++;
}
}
/* sort the accumulated lines */
qsort (lines, nproc, sizeof(Line *), GreatestFirst);
/* print them */
for (i=0; i<nproc; i++)
{
lines[i]->show(i);
@@ -396,6 +487,16 @@ void do_refresh()
sent_global += lines[i]->sent_kbps;
delete lines[i];
}
if (tracemode || DEBUG) {
/* print the 'unknown' connections, for debugging */
ConnList * curr_unknownconn = unknownproc->connections;
while (curr_unknownconn != NULL) {
std::cout << "Unknown connection: " <<
curr_unknownconn->getVal()->refpacket->gethashstring() << std::endl;
curr_unknownconn = curr_unknownconn->getNext();
}
}
if ((!tracemode) && (!DEBUG)){
attron(A_REVERSE);
@@ -406,34 +507,22 @@ void do_refresh()
}
}
/* returns the process from proclist with matching pid
/*
* returns the process from proclist with matching pid
* if the inode is not associated with any PID, return the unknown process
* if the process is not yet in the proclist, add it
*/
Process * getProcess (unsigned long inode, char * devicename)
{
struct prg_node * node = prg_cache_get(inode);
struct prg_node * node = findPID(inode);
if (node == NULL)
{
prg_cache_clear();
prg_cache_load();
node = prg_cache_get(inode);
if (node == NULL)
{
if (DEBUG)
std::cerr << "inode " << inode << " STILL not in inode-to-program-mapping." << endl;
return unknownproc;
}
}
ProcList * current = processes;
while (current != NULL)
{
if (node->pid == current->getVal()->pid)
return current->getVal();
current = current->next;
}
Process * proc = findProcess (node);
if (proc != NULL)
return proc;
Process * newproc = new Process (inode, strdup(devicename));
newproc->name = strdup(node->name);
@@ -459,38 +548,36 @@ Process * getProcess (Connection * connection, char * devicename)
{
ProcList * curproc = processes;
// see if we already know the inode for this connection
if (DEBUG)
{
std::cout << "New connection reference packet.. ";
std::cout << connection->refpacket << std::endl;
}
unsigned long * inode = (unsigned long *) conninode->get(connection->refpacket->gethashstring());
unsigned long * inode = (unsigned long *)
conninode->get(connection->refpacket->gethashstring());
if (inode == NULL)
{
// no? refresh and check conn/inode table
#if DEBUG
std::cerr << "Not in table, refreshing table from /proc/net/tcp.\n";
std::cerr << "new connection not in connection-to-inode table.\n";
#endif
refreshconninode();
inode = (unsigned long *) conninode->get(connection->refpacket->gethashstring());
inode = (unsigned long *)
conninode->get(connection->refpacket->gethashstring());
if (inode == NULL)
{
/* HACK: the following is a hack for cases where the 'local' addresses
* aren't properly recognised, as is currently the case for IPv6 */
/* 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. */
/* we reverse the direction of the stream if
* successful. */
Packet * reversepacket = connection->refpacket->newInverted();
//inode = (unsigned long *) conninode->get(reversepacket->gethashstring());
inode = (unsigned long *)
conninode->get(reversepacket->gethashstring());
if (inode == NULL)
{
delete reversepacket;
if (DEBUG)
std::cerr << connection->refpacket->gethashstring() << " STILL not in connection-to-inode table - adding to the unknown process\n";
std::cout << 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;
}

View File

@@ -20,6 +20,10 @@ public:
{
return val;
}
ConnList * setNext (ConnList * m_next)
{
next = m_next;
}
ConnList * getNext ()
{
return next;