cleanups. mainly memory leak fixes
This commit is contained in:
4
Makefile
4
Makefile
@@ -13,7 +13,7 @@ GCC=g++
|
||||
.PHONY: tgz
|
||||
|
||||
tgz: clean
|
||||
cd .. ; tar czvf nethogs-$(VERSION).$(SUBVERSION).$(MINORVERSION).tar.gz nethogs-$(VERSION).$(SUBVERSION)/*
|
||||
cd .. ; tar czvf nethogs-$(VERSION).$(SUBVERSION).$(MINORVERSION).tar.gz nethogs/*
|
||||
|
||||
.PHONY: check
|
||||
check:
|
||||
@@ -24,7 +24,7 @@ install: nethogs nethogs.8
|
||||
cp nethogs.8 $(man8)
|
||||
|
||||
nethogs: nethogs.cpp $(OBJS)
|
||||
$(GCC) $(CFLAGS) nethogs.cpp $(OBJS) -o nethogs -lpcap -lncurses -DVERSION=\"$(VERSION)\" -DSUBVERSION=\"$(SUBVERSION)\" -DMINORVERSION=\"$(MINORVERSION)\"
|
||||
$(GCC) $(CFLAGS) nethogs.cpp $(OBJS) -o nethogs -lpcap -lm -lncurses -DVERSION=\"$(VERSION)\" -DSUBVERSION=\"$(SUBVERSION)\" -DMINORVERSION=\"$(MINORVERSION)\"
|
||||
|
||||
#-lefence
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ void PackList::add (Packet * p)
|
||||
{
|
||||
if (content == NULL)
|
||||
{
|
||||
content = new PackListNode (p);
|
||||
content = new PackListNode (new Packet (*p));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -31,13 +31,13 @@ void PackList::add (Packet * p)
|
||||
return;
|
||||
}
|
||||
|
||||
content = new PackListNode(p, content);
|
||||
content = new PackListNode(new Packet (*p), content);
|
||||
}
|
||||
|
||||
/* sums up the total bytes used and removes 'old' packets */
|
||||
bpf_u_int32 PackList::sumanddel (timeval t)
|
||||
u_int32_t PackList::sumanddel (timeval t)
|
||||
{
|
||||
bpf_u_int32 retval = 0;
|
||||
u_int32_t retval = 0;
|
||||
PackListNode * current = content;
|
||||
PackListNode * previous = NULL;
|
||||
|
||||
@@ -84,9 +84,9 @@ Connection::~Connection ()
|
||||
{
|
||||
if (DEBUG)
|
||||
std::cout << "Deleting connection" << std::endl;
|
||||
/* refpacket is a pointer to one of the packets in the lists,
|
||||
* so not deleted */
|
||||
//delete refpacket;
|
||||
/* 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)
|
||||
@@ -116,6 +116,7 @@ Connection::~Connection ()
|
||||
}
|
||||
}
|
||||
|
||||
/* the packet will be freed by the calling code */
|
||||
void Connection::add (Packet * packet)
|
||||
{
|
||||
lastpacket = packet->time.tv_sec;
|
||||
@@ -139,10 +140,14 @@ Connection * findConnection (Packet * packet)
|
||||
/* the reference packet is always *outgoing* */
|
||||
if ((packet->match(current->val->refpacket))
|
||||
|| (invertedPacket->match(current->val->refpacket)))
|
||||
{
|
||||
delete invertedPacket;
|
||||
return current->val;
|
||||
}
|
||||
|
||||
current = current->next;
|
||||
}
|
||||
delete invertedPacket;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -155,7 +160,7 @@ Connection * findConnection (Packet * packet)
|
||||
* Returns sum of sent packages (by address)
|
||||
* sum of recieved packages (by address)
|
||||
*/
|
||||
void Connection::sumanddel (timeval t, bpf_u_int32 * sent, bpf_u_int32 * recv)
|
||||
void Connection::sumanddel (timeval t, u_int32_t * sent, u_int32_t * recv)
|
||||
{
|
||||
(*sent)=(*recv)=0;
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
}
|
||||
|
||||
/* sums up the total bytes used and removes 'old' packets */
|
||||
bpf_u_int32 sumanddel (timeval t);
|
||||
u_int32_t sumanddel (timeval t);
|
||||
|
||||
void add (Packet * p);
|
||||
private:
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
|
||||
/* sums up the total bytes used
|
||||
* and removes 'old' packets. */
|
||||
void sumanddel(timeval curtime, bpf_u_int32 * sent, bpf_u_int32 * recv);
|
||||
void sumanddel(timeval curtime, u_int32_t * sent, u_int32_t * recv);
|
||||
|
||||
/* for checking if a packet is part of this connection */
|
||||
/* the reference packet is always *outgoing*. */
|
||||
|
||||
@@ -66,9 +66,10 @@ HashNode * HashTable::newHashNode(char * key, void * content, HashNode * next)
|
||||
|
||||
void HashTable::add(char * key, void * content)
|
||||
{
|
||||
unsigned int hkey = HashString (key);
|
||||
//std::cout << "(STILL)Adding node: " << key << " key " << hkey << endl;
|
||||
table[hkey] = newHashNode(key, content, table[hkey]);
|
||||
char * localkey = strdup(key);
|
||||
unsigned int hkey = HashString (localkey);
|
||||
//std::cout << "(STILL)Adding node: " << localkey << " key " << hkey << endl;
|
||||
table[hkey] = newHashNode(localkey, content, table[hkey]);
|
||||
}
|
||||
|
||||
void * HashTable::get(char * key)
|
||||
|
||||
@@ -16,6 +16,9 @@ class HashTable
|
||||
public:
|
||||
HashTable(int n_size);
|
||||
~HashTable();
|
||||
|
||||
/* after calling 'add', the calling application
|
||||
* must free the string */
|
||||
void add(char * key, void * content);
|
||||
void * get(char * key);
|
||||
|
||||
|
||||
10
nethogs.cpp
10
nethogs.cpp
@@ -93,13 +93,14 @@ int process_tcp (u_char * userdata, const dp_header * header, const u_char * m_p
|
||||
switch (args->sa_family)
|
||||
{
|
||||
case (AF_INET):
|
||||
//packet = new Packet (args->ip_src, ntohs(tcp->th_sport), args->ip_dst, ntohs(tcp->th_dport), header->len, header->ts);
|
||||
packet = new Packet (args->ip_src, ntohs(tcp->source), args->ip_dst, ntohs(tcp->dest), header->len, header->ts);
|
||||
break;
|
||||
case (AF_INET6):
|
||||
packet = new Packet (args->ip6_src, ntohs(tcp->source), args->ip6_dst, ntohs(tcp->dest), header->len, header->ts);
|
||||
break;
|
||||
}
|
||||
//if (DEBUG)
|
||||
// std::cout << "Got packet from " << packet->gethashstring() << std::endl;
|
||||
|
||||
Connection * connection = findConnection(packet);
|
||||
|
||||
@@ -107,11 +108,10 @@ int process_tcp (u_char * userdata, const dp_header * header, const u_char * m_p
|
||||
{
|
||||
/* add packet to the connection */
|
||||
connection->add(packet);
|
||||
delete packet;
|
||||
} else {
|
||||
/* else: unknown connection, create new */
|
||||
connection = new Connection (packet);
|
||||
//if (DEBUG)
|
||||
// std::cerr << "Getting process by connection\n";
|
||||
Process * process = getProcess(connection, currentdevice);
|
||||
}
|
||||
|
||||
@@ -152,6 +152,7 @@ void quit_cb (int i)
|
||||
procclean();
|
||||
clear();
|
||||
endwin();
|
||||
delete caption;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -310,9 +311,8 @@ int main (int argc, char** argv)
|
||||
struct dpargs * userdata = (dpargs *) malloc (sizeof (struct dpargs));
|
||||
userdata->sa_family = AF_UNSPEC;
|
||||
currentdevice = current_handle->devicename;
|
||||
/* TODO maybe userdata needs be reset every now and then? */
|
||||
dp_dispatch (current_handle->content, -1, (u_char *)userdata, sizeof (struct dpargs));
|
||||
/* dp_dispatch handles deletion of the userdata */
|
||||
free (userdata);
|
||||
current_handle = current_handle->next;
|
||||
}
|
||||
|
||||
|
||||
99
packet.cpp
99
packet.cpp
@@ -10,6 +10,7 @@
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdio.h>
|
||||
// #include "inet6.c"
|
||||
|
||||
local_addr * local_addrs = NULL;
|
||||
@@ -124,77 +125,22 @@ struct tcp_hdr {
|
||||
u_short th_sum; /* checksum */
|
||||
u_short th_urp; /* urgent pointer */
|
||||
};
|
||||
/* Packet 'Constructor' - but returns NULL on failure */
|
||||
/* deprecated by decpcap
|
||||
Packet * getPacket (const struct pcap_pkthdr * header, const u_char * packet, packet_type headertype)
|
||||
{
|
||||
int packettype;
|
||||
int headersize;
|
||||
|
||||
switch (headertype)
|
||||
{
|
||||
case (packet_ethernet):
|
||||
{
|
||||
const struct ether_header * ethernet = (struct ether_header *)packet;
|
||||
packettype = ethernet->ether_type;
|
||||
headersize = sizeof (struct ether_header);
|
||||
}; break;
|
||||
case (packet_ppp):
|
||||
{
|
||||
const struct ppp_header * ppp = (struct ppp_header *)packet;
|
||||
packettype = ppp->packettype;
|
||||
headersize = sizeof (struct ppp_header);
|
||||
}; break;
|
||||
}
|
||||
if (packettype == 0x0008)
|
||||
{
|
||||
const struct ip * ip = (struct ip *)(packet + headersize);
|
||||
if (ip->ip_p != 6)
|
||||
{
|
||||
#if DEBUG
|
||||
std::cerr << "Dropped non-tcp IPv4 packet of type " << (int)(ip->ip_p) << std::endl;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
const struct tcp_hdr * tcp = (struct tcp_hdr *)(packet + headersize + sizeof(struct ip));
|
||||
return new Packet (ip->ip_src, ntohs(tcp->th_sport), ip->ip_dst, ntohs(tcp->th_dport), header->len, header->ts);
|
||||
} else if (packettype == 0xDD86) {
|
||||
const struct ip6_hdr * ip6 = (struct ip6_hdr *)(packet + headersize);
|
||||
if ((ip6->ip6_ctlun).ip6_un1.ip6_un1_nxt != 0x06)
|
||||
{
|
||||
// TODO maybe we need to skip over some headers?
|
||||
#if DEBUG
|
||||
std::cerr << "Dropped non-tcp IPv6 header of type " << (int)((ip6->ip6_ctlun).ip6_un1.ip6_un1_nxt) << std::endl;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
const struct tcp_hdr * tcp = (struct tcp_hdr *)(packet + headersize + sizeof(ip6_hdr));
|
||||
|
||||
return new Packet (ip6->ip6_src, ntohs(tcp->th_sport),
|
||||
ip6->ip6_dst, ntohs(tcp->th_dport), header->len, header->ts);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
std::cerr << "Dropped non-ip packet of type " << packettype << std::endl;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
|
||||
Packet::Packet (in_addr m_sip, unsigned short m_sport, in_addr m_dip, unsigned short m_dport, bpf_u_int32 m_len, timeval m_time, direction m_dir)
|
||||
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, bpf_u_int32 m_len, timeval m_time, direction m_dir)
|
||||
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::newInverted () {
|
||||
@@ -206,11 +152,19 @@ Packet * Packet::newInverted () {
|
||||
}
|
||||
|
||||
/* constructs returns a new Packet() structure with the same contents as this one */
|
||||
/*Packet::Packet (const Packet &old_packet) {
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
bool sameinaddr(in_addr one, in_addr other)
|
||||
{
|
||||
@@ -266,11 +220,20 @@ bool Packet::Outgoing () {
|
||||
|
||||
/* 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 ()
|
||||
{
|
||||
char * retval = (char *) malloc (HASHKEYSIZE * sizeof(char));
|
||||
char * local_string = (char*) malloc (50);
|
||||
char * remote_string = (char*) malloc (50);
|
||||
if (hashstring != NULL)
|
||||
{
|
||||
if (DEBUG)
|
||||
std::cout << "Returning cached hash string: " << hashstring << std::endl;
|
||||
return hashstring;
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -279,13 +242,15 @@ char * Packet::gethashstring ()
|
||||
inet_ntop(sa_family, &dip6, remote_string, 49);
|
||||
}
|
||||
if (Outgoing()) {
|
||||
snprintf(retval, HASHKEYSIZE * sizeof(char), "%s:%d-%s:%d", local_string, sport, remote_string, dport);
|
||||
snprintf(hashstring, HASHKEYSIZE * sizeof(char), "%s:%d-%s:%d", local_string, sport, remote_string, dport);
|
||||
} else {
|
||||
snprintf(retval, HASHKEYSIZE * sizeof(char), "%s:%d-%s:%d", remote_string, dport, local_string, sport);
|
||||
snprintf(hashstring, HASHKEYSIZE * sizeof(char), "%s:%d-%s:%d", remote_string, dport, local_string, sport);
|
||||
}
|
||||
free (local_string);
|
||||
free (remote_string);
|
||||
return retval;
|
||||
if (DEBUG)
|
||||
std::cout << "Returning newly created hash string: " << hashstring << std::endl;
|
||||
return hashstring;
|
||||
}
|
||||
|
||||
/* 2 packets match if they have the same
|
||||
|
||||
25
packet.h
25
packet.h
@@ -9,11 +9,6 @@
|
||||
#include <arpa/inet.h>
|
||||
#include "nethogs.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <pcap.h>
|
||||
}
|
||||
|
||||
enum direction {
|
||||
dir_unknown,
|
||||
dir_incoming,
|
||||
@@ -33,12 +28,21 @@ public:
|
||||
in_addr dip;
|
||||
unsigned short sport;
|
||||
unsigned short dport;
|
||||
bpf_u_int32 len;
|
||||
u_int32_t len;
|
||||
timeval time;
|
||||
|
||||
Packet (in_addr m_sip, unsigned short m_sport, in_addr m_dip, unsigned short m_dport, bpf_u_int32 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, bpf_u_int32 m_len, timeval m_time, direction dir = dir_unknown);
|
||||
/* using default copy constructor */
|
||||
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 ();
|
||||
@@ -53,8 +57,7 @@ public:
|
||||
private:
|
||||
direction dir;
|
||||
short int sa_family;
|
||||
char * hashstring;
|
||||
};
|
||||
|
||||
//Packet * getPacket (const struct pcap_pkthdr * header, const u_char * packet, packet_type packettype);
|
||||
|
||||
#endif
|
||||
|
||||
18
process.cpp
18
process.cpp
@@ -68,7 +68,8 @@ void addtoconninode (char * buffer)
|
||||
char addr6[INET6_ADDRSTRLEN];
|
||||
struct in6_addr in6_local;
|
||||
struct in6_addr in6_remote;
|
||||
// the following line might leak memory.
|
||||
|
||||
// the following leaks some memory.
|
||||
unsigned long * inode = (unsigned long *) malloc (sizeof(unsigned long));
|
||||
|
||||
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",
|
||||
@@ -139,6 +140,8 @@ void addtoconninode (char * buffer)
|
||||
|
||||
//std::cout << "Adding to conninode\n" << std::endl;
|
||||
|
||||
conninode->add(hashkey, (void *)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
|
||||
@@ -146,11 +149,11 @@ void addtoconninode (char * buffer)
|
||||
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);
|
||||
current_local_addr = current_local_addr->next;
|
||||
}
|
||||
free (hashkey);
|
||||
free (remote_string);
|
||||
}
|
||||
|
||||
@@ -184,7 +187,8 @@ struct prg_node * findPID (unsigned long inode)
|
||||
prg_cache_clear();
|
||||
prg_cache_load();
|
||||
node = prg_cache_get(inode);
|
||||
assert (node->pid != 1);
|
||||
// this still happens sometimes...
|
||||
//assert (node->pid != 1);
|
||||
}
|
||||
|
||||
if (node == NULL)
|
||||
@@ -280,7 +284,7 @@ void refreshconninode ()
|
||||
|
||||
}
|
||||
|
||||
float tokbps (bpf_u_int32 bytes)
|
||||
float tokbps (u_int32_t bytes)
|
||||
{
|
||||
return (((double)bytes) / PERIOD) / 1024;
|
||||
}
|
||||
@@ -327,7 +331,7 @@ void Line::show (int row)
|
||||
{
|
||||
if (DEBUG || tracemode)
|
||||
{
|
||||
std::cout << m_name << "\t" << sent_kbps << "\t" << recv_kbps << std::endl;
|
||||
std::cout << m_name << '/' << m_pid << '/' << m_uid << "\t" << sent_kbps << "\t" << recv_kbps << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -425,7 +429,7 @@ void do_refresh()
|
||||
continue;
|
||||
}
|
||||
|
||||
bpf_u_int32 sum_sent = 0,
|
||||
u_int32_t sum_sent = 0,
|
||||
sum_recv = 0;
|
||||
|
||||
/* walk though all this process's connections, and sum them
|
||||
@@ -449,7 +453,7 @@ void do_refresh()
|
||||
}
|
||||
else
|
||||
{
|
||||
bpf_u_int32 sent = 0, recv = 0;
|
||||
u_int32_t sent = 0, recv = 0;
|
||||
curconn->getVal()->sumanddel(curtime, &sent, &recv);
|
||||
sum_sent += sent;
|
||||
sum_recv += recv;
|
||||
|
||||
Reference in New Issue
Block a user