Merge pull request #20 from Rudloff/osx

OSX compatibility
This commit is contained in:
Arnout Engelen
2016-01-18 15:18:51 +01:00
8 changed files with 72 additions and 27 deletions

View File

@@ -10,7 +10,8 @@ Introduction
NetHogs is a small 'net top' tool. Instead of breaking the traffic down per protocol or per subnet, like most tools do, it groups bandwidth by process. NetHogs does not rely on a special kernel module to be loaded. If there's suddenly a lot of network traffic, you can fire up NetHogs and immediately see which PID is causing this. This makes it easy to indentify programs that have gone wild and are suddenly taking up your bandwidth.
Since NetHogs heavily relies on /proc, it currently runs on Linux only.
Since NetHogs heavily relies on /proc, some functionalities are only available on Linux.
NetHogs can be built on Mac OS X, but it will only show connections, not processes.
Status
------

View File

@@ -22,7 +22,11 @@
#include <iostream>
#include <cassert>
#include <malloc.h>
#ifdef __APPLE__
#include <sys/malloc.h>
#else
#include <malloc.h>
#endif
#include "nethogs.h"
#include "connection.h"
#include "process.h"

View File

@@ -28,11 +28,17 @@
#include "nethogs.h"
#include "conninode.h"
#if defined __APPLE__
#ifndef s6_addr32
#define s6_addr32 __u6_addr.__u6_addr32
#endif
#endif
extern local_addr * local_addrs;
/*
/*
* 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
* port in format: '1.2.3.4:5-1.2.3.4:5'
*/
std::map <std::string, unsigned long> conninode;
@@ -179,12 +185,16 @@ void refreshconninode ()
//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");
#if defined(__APPLE__)
addprocinfo("net.inet.tcp.pcblist");
#else
if (! addprocinfo ("/proc/net/tcp"))
{
std::cout << "Error: couldn't open /proc/net/tcp\n";
exit(0);
}
addprocinfo ("/proc/net/tcp6");
#endif
//if (DEBUG)
// reviewUnknown();

View File

@@ -225,7 +225,9 @@ struct prg_node * findPID (unsigned long inode)
return node;
}
reread_mapping();
#ifndef __APPLE__
reread_mapping();
#endif
struct prg_node * retval = inodeproc[inode];
if (bughuntmode)

View File

@@ -128,10 +128,18 @@ 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->source), args->ip_dst, ntohs(tcp->dest), header->len, header->ts);
#ifdef __APPLE__
packet = new Packet (args->ip_src, ntohs(tcp->th_sport), args->ip_dst, ntohs(tcp->th_dport), header->len, header->ts);
#else
packet = new Packet (args->ip_src, ntohs(tcp->source), args->ip_dst, ntohs(tcp->dest), header->len, header->ts);
#endif
break;
case (AF_INET6):
packet = new Packet (args->ip6_src, ntohs(tcp->source), args->ip6_dst, ntohs(tcp->dest), header->len, header->ts);
#ifdef __APPLE__
packet = new Packet (args->ip6_src, ntohs(tcp->th_sport), args->ip6_dst, ntohs(tcp->th_dport), header->len, header->ts);
#else
packet = new Packet (args->ip6_src, ntohs(tcp->source), args->ip6_dst, ntohs(tcp->dest), header->len, header->ts);
#endif
break;
}
@@ -162,10 +170,18 @@ int process_udp (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(udp->source), args->ip_dst, ntohs(udp->dest), header->len, header->ts);
#ifdef __APPLE__
packet = new Packet (args->ip_src, ntohs(udp->uh_sport), args->ip_dst, ntohs(udp->uh_dport), header->len, header->ts);
#else
packet = new Packet (args->ip_src, ntohs(udp->source), args->ip_dst, ntohs(udp->dest), header->len, header->ts);
#endif
break;
case (AF_INET6):
packet = new Packet (args->ip6_src, ntohs(udp->source), args->ip6_dst, ntohs(udp->dest), header->len, header->ts);
#ifdef __APPLE__
packet = new Packet (args->ip6_src, ntohs(udp->uh_sport), args->ip6_dst, ntohs(udp->uh_dport), header->len, header->ts);
#else
packet = new Packet (args->ip6_src, ntohs(udp->source), args->ip6_dst, ntohs(udp->dest), header->len, header->ts);
#endif
break;
}

View File

@@ -29,7 +29,11 @@
#include <arpa/inet.h>
#include <cassert>
#include <cstring>
#include <malloc.h>
#ifdef __APPLE__
#include <sys/malloc.h>
#else
#include <malloc.h>
#endif
#include <iostream>
#define _BSD_SOURCE 1

View File

@@ -25,7 +25,11 @@
#include "packet.h"
#include <netinet/tcp.h>
#include <netinet/in.h>
#include <malloc.h>
#ifdef __APPLE__
#include <sys/malloc.h>
#else
#include <malloc.h>
#endif
#include <cassert>
#include <net/if.h>
#include <net/ethernet.h>

View File

@@ -24,7 +24,9 @@
#include <strings.h>
#include <string>
#include <ncurses.h>
#include <asm/types.h>
#ifndef __APPLE__
#include <asm/types.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -215,34 +217,36 @@ Process * getProcess (Connection * connection, const char * devicename)
// no? refresh and check conn/inode table
if (bughuntmode)
{
std::cout << "? new connection not in connection-to-inode table before refresh.\n";
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
// 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
// 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();
#ifndef __APPLE__
reread_mapping();
#endif
refreshconninode();
inode = conninode[connection->refpacket->gethashstring()];
if (bughuntmode)
{
if (inode == 0)
{
std::cout << ":( inode for connection not found after refresh.\n";
std::cout << ":( inode for connection not found after refresh.\n";
}
else
{
std::cout << ":) inode for connection found after refresh.\n";
std::cout << ":) inode for connection found after refresh.\n";
}
}
#if REVERSEHACK
if (inode == 0)
{
/* HACK: the following is a hack for cases where the
* 'local' addresses aren't properly recognised, as is
/* 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
/* we reverse the direction of the stream if
* successful. */
Packet * reversepacket = connection->refpacket->newInverted();
inode = conninode[reversepacket->gethashstring()];