diff --git a/src/connection.cpp b/src/connection.cpp index d515192..448d4e7 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -34,6 +34,7 @@ #include "process.h" ConnList *connections = NULL; +extern Process *unknownudp; void PackList::add(Packet *p) { if (content == NULL) { @@ -151,10 +152,26 @@ void Connection::add(Packet *packet) { } } -Connection *findConnectionWithMatchingSource(Packet *packet) { +Connection *findConnectionWithMatchingSource(Packet *packet, short int packettype) { assert(packet->Outgoing()); - ConnList *current = connections; + ConnList *current = NULL; + switch(packettype) + { + case IPPROTO_TCP: + { + current = connections; + break; + } + + case IPPROTO_UDP: + { + current = unknownudp->connections; + break; + } + + } + while (current != NULL) { /* the reference packet is always outgoing */ if (packet->matchSource(current->getVal()->refpacket)) { @@ -163,20 +180,39 @@ Connection *findConnectionWithMatchingSource(Packet *packet) { current = current->getNext(); } + return NULL; + } -Connection *findConnectionWithMatchingRefpacketOrSource(Packet *packet) { - ConnList *current = connections; +Connection *findConnectionWithMatchingRefpacketOrSource(Packet *packet, short int packettype) { + + ConnList *current = NULL; + switch(packettype) + { + case IPPROTO_TCP: + { + current = connections; + break; + } + + case IPPROTO_UDP: + { + current = unknownudp->connections; + break; + + } + } + while (current != NULL) { /* the reference packet is always *outgoing* */ if (packet->match(current->getVal()->refpacket)) { return current->getVal(); } - current = current->getNext(); } - return findConnectionWithMatchingSource(packet); + + return findConnectionWithMatchingSource(packet, packettype); } /* @@ -184,13 +220,13 @@ Connection *findConnectionWithMatchingRefpacketOrSource(Packet *packet) { * a packet belongs to a connection if it matches * to its reference packet */ -Connection *findConnection(Packet *packet) { +Connection *findConnection(Packet *packet, short int packettype) { if (packet->Outgoing()) - return findConnectionWithMatchingRefpacketOrSource(packet); + return findConnectionWithMatchingRefpacketOrSource(packet, packettype); else { Packet *invertedPacket = packet->newInverted(); Connection *result = - findConnectionWithMatchingRefpacketOrSource(invertedPacket); + findConnectionWithMatchingRefpacketOrSource(invertedPacket, packettype); delete invertedPacket; return result; diff --git a/src/connection.h b/src/connection.h index 538ff14..b1b13e1 100644 --- a/src/connection.h +++ b/src/connection.h @@ -101,6 +101,6 @@ private: /* Find the connection this packet belongs to */ /* (the calling code may free the packet afterwards) */ -Connection *findConnection(Packet *packet); +Connection *findConnection(Packet *packet, short int packettype); #endif diff --git a/src/decpcap.c b/src/decpcap.c index 7abc63e..72544a9 100644 --- a/src/decpcap.c +++ b/src/decpcap.c @@ -32,7 +32,7 @@ #include "decpcap.h" #define DP_DEBUG 0 - +bool catchall = false; /* functions to set up a handle (which is basically just a pcap handle) */ struct dp_handle *dp_fillhandle(pcap_t *phandle) { @@ -139,6 +139,18 @@ void dp_parse_tcp(struct dp_handle *handle, const dp_header *header, // TODO: maybe `pass on' payload to lower-level protocol parsing } +void dp_parse_udp(struct dp_handle *handle, const dp_header *header, + const u_char *packet) { + + if (handle->callback[dp_packet_udp] != NULL) { + int done = + (handle->callback[dp_packet_udp])(handle->userdata, header, packet); + if (done) + return; + } + // TODO: maybe `pass on' payload to lower-level protocol parsing +} + void dp_parse_ip(struct dp_handle *handle, const dp_header *header, const u_char *packet) { const struct ip *ip = (struct ip *)packet; @@ -157,6 +169,10 @@ void dp_parse_ip(struct dp_handle *handle, const dp_header *header, case IPPROTO_TCP: dp_parse_tcp(handle, header, payload); break; + case IPPROTO_UDP: + if(catchall) + dp_parse_udp(handle, header, payload); + break; default: // TODO: maybe support for non-tcp IP packets break; @@ -178,6 +194,10 @@ void dp_parse_ip6(struct dp_handle *handle, const dp_header *header, case IPPROTO_TCP: dp_parse_tcp(handle, header, payload); break; + case IPPROTO_UDP: + if(catchall) + dp_parse_udp(handle, header, payload); + break; default: // TODO: maybe support for non-tcp ipv6 packets break; diff --git a/src/decpcap.h b/src/decpcap.h index f5f7a31..a5196bd 100644 --- a/src/decpcap.h +++ b/src/decpcap.h @@ -25,9 +25,10 @@ #include #include #include +#include #define DP_ERRBUF_SIZE PCAP_ERRBUF_SIZE - +extern bool catchall; /* definitions */ enum dp_packet_type { diff --git a/src/main.cpp b/src/main.cpp index 729adc2..f90ae2e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,7 +27,7 @@ static void help(bool iserror) { // output << "usage: nethogs [-V] [-b] [-d seconds] [-t] [-p] [-f (eth|ppp))] // [device [device [device ...]]]\n"; output << "usage: nethogs [-V] [-h] [-b] [-d seconds] [-v mode] [-c count] " - "[-t] [-p] [-s] [-a] [-l] [-f filter] " + "[-t] [-p] [-s] [-a] [-l] [-f filter] [-C]" "[device [device [device ...]]]\n"; output << " -V : prints version.\n"; output << " -h : prints this help.\n"; @@ -44,6 +44,7 @@ static void help(bool iserror) { output << " -s : sort output by sent column.\n"; output << " -l : display command line.\n"; output << " -a : monitor all devices, even loopback/stopped ones.\n"; + output << " -C : capture TCP and UDP.\n"; output << " -f : EXPERIMENTAL: specify string pcap filter (like tcpdump)." " This may be removed or changed in a future version.\n"; output << " device : device(s) to monitor. default is all " @@ -132,14 +133,13 @@ void clean_up() { } int main(int argc, char **argv) { - process_init(); int promisc = 0; bool all = false; char *filter = NULL; int opt; - while ((opt = getopt(argc, argv, "Vhbtpsd:v:c:laf:")) != -1) { + while ((opt = getopt(argc, argv, "Vhbtpsd:v:c:laf:C")) != -1) { switch (opt) { case 'V': versiondisplay(); @@ -178,12 +178,16 @@ int main(int argc, char **argv) { case 'f': filter = optarg; break; + case 'C': + catchall = true; + break; default: help(true); exit(EXIT_FAILURE); } } + process_init(); device *devices = get_devices(argc - optind, argv + optind, all); if (devices == NULL) forceExit(false, "No devices to monitor. Use '-a' to allow monitoring " diff --git a/src/nethogs.cpp b/src/nethogs.cpp index d128ad4..76b3a1c 100644 --- a/src/nethogs.cpp +++ b/src/nethogs.cpp @@ -63,7 +63,6 @@ bool showcommandline = false; // viewMode: kb/s or total int viewMode = VIEWMODE_KBPS; const char version[] = " version " VERSION; - timeval curtime; bool local_addr::contains(const in_addr_t &n_addr) { @@ -143,7 +142,7 @@ int process_tcp(u_char *userdata, const dp_header *header, return true; } - Connection *connection = findConnection(packet); + Connection *connection = findConnection(packet, IPPROTO_TCP); if (connection != NULL) { /* add packet to the connection */ @@ -195,7 +194,7 @@ int process_udp(u_char *userdata, const dp_header *header, // if (DEBUG) // std::cout << "Got packet from " << packet->gethashstring() << std::endl; - Connection *connection = findConnection(packet); + Connection *connection = findConnection(packet, IPPROTO_UDP); if (connection != NULL) { /* add packet to the connection */ @@ -203,7 +202,8 @@ int process_udp(u_char *userdata, const dp_header *header, } else { /* else: unknown connection, create new */ connection = new Connection(packet); - getProcess(connection, args->device); + unknownudp->connections = new ConnList(connection, unknownudp->connections); + //getProcess(connection, args->device); } delete packet; diff --git a/src/process.cpp b/src/process.cpp index 4ebd206..155f31a 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -41,7 +41,7 @@ #include "conninode.h" extern timeval curtime; - +extern bool catchall; /* * connection-inode table. takes information from /proc/net/tcp. * key contains source ip, source port, destination ip, destination @@ -72,11 +72,15 @@ float tokbps(u_int64_t bytes) { return (((double)bytes) / PERIOD) / 1024; } void process_init() { 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); + + if(catchall) + { + unknownudp = new Process (0, "", "unknown UDP"); + processes = new ProcList (unknownudp, processes); + // unknownip = new Process (0, "", "unknown IP"); + // processes = new ProcList (unknownip, processes); + } } int Process::getLastPacket() {