Merge pull request #218 from sgtcortez/feat-process-filter

Add process filter
This commit is contained in:
Arnout Engelen
2022-03-02 14:11:58 +01:00
committed by GitHub
3 changed files with 32 additions and 3 deletions

View File

@@ -21,6 +21,7 @@ nethogs \- Net top tool grouping bandwidth per process
.RB [ "\-C" ]
.RB [ "\-b" ]
.RB [ "\-g period" ]
.RB [ "\-P pid" ]
.RI [device(s)]
.SH DESCRIPTION
NetHogs is a small 'net top' tool. Instead of breaking the traffic down per protocol or per subnet, like most such tools do, it groups bandwidth by process - and does not rely on a special kernel module to be loaded. So if there's suddenly a lot of network traffic, you can fire up NetHogs and immediately see which PID is causing this, and if it's some kind of spinning process, kill it.
@@ -69,6 +70,9 @@ Display the program basename.
\fB-g\fP
garbage collection period in number of refresh. default is 50.
.TP
\fB-P\fP
Show only processes with the specified pid(s).
.TP
\fB-f\fP
EXPERIMENTAL: specify string pcap filter (like tcpdump). This may be removed or changed in a future version.
.TP
@@ -113,7 +117,9 @@ command, as follows:
sudo setcap "cap_net_admin,cap_net_raw+pe" /usr/local/sbin/nethogs
.EE
.in
.SH "Notes"
1. When using the -P <pid> option, in a case where a process exited (normally or abruptly), Nethogs does not track that it exited. So, the operating system might create
a new process (for another program) with the same pid. In this case, this new process will be shown by Nethogs.
.SH "SEE ALSO"
.I netstat(8) tcpdump(1) pcap(3)
.SH AUTHOR

View File

@@ -1,5 +1,6 @@
#include "nethogs.cpp"
#include <fcntl.h>
#include <set>
#include <vector>
#ifdef __linux__
@@ -14,6 +15,8 @@
static std::pair<int, int> self_pipe = std::make_pair(-1, -1);
static time_t last_refresh_time = 0;
std::set<pid_t> pidsToWatch;
// selectable file descriptors for the main loop
static fd_set pc_loop_fd_set;
static std::vector<int> pc_loop_fd_list;
@@ -27,7 +30,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] [-x] [-d seconds] [-v mode] [-c count] "
"[-t] [-p] [-s] [-a] [-l] [-f filter] [-C] [-b]"
"[-t] [-p] [-s] [-a] [-l] [-f filter] [-C] [-b] [-P pid] "
"[device [device [device ...]]]\n";
output << " -V : prints version.\n";
output << " -h : prints this help.\n";
@@ -54,6 +57,7 @@ static void help(bool iserror) {
" This may be removed or changed in a future version.\n";
output << " device : device(s) to monitor. default is all "
"interfaces up and running excluding loopback\n";
output << " -P : Show only processes.\n";
output << std::endl;
output << "When nethogs is running, press:\n";
output << " q: quit\n";
@@ -146,8 +150,9 @@ int main(int argc, char **argv) {
char *filter = NULL;
int garbage_collection_period = 50;
int opt;
while ((opt = getopt(argc, argv, "Vhxtpsd:v:c:laf:Cbg:")) != -1) {
while ((opt = getopt(argc, argv, "Vhxtpsd:v:c:laf:Cbg:P:")) != -1) {
switch (opt) {
case 'V':
versiondisplay();
@@ -195,6 +200,9 @@ int main(int argc, char **argv) {
case 'g':
garbage_collection_period = (time_t)atoi(optarg);
break;
case 'P':
pidsToWatch.insert((pid_t) atoi(optarg));
break;
default:
help(true);
exit(EXIT_FAILURE);

View File

@@ -22,6 +22,7 @@
#include <iostream>
#include <ncurses.h>
#include <set>
#include <string>
#include <strings.h>
#if !defined(__APPLE__) && !defined(__FreeBSD__)
@@ -34,6 +35,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include "conninode.h"
#include "inode2prog.h"
@@ -66,6 +68,8 @@ Process *unknownudp;
Process *unknownip;
ProcList *processes;
extern std::set<pid_t> pidsToWatch;
#define KB (1UL << 10)
#define MB (1UL << 20)
#define GB (1UL << 30)
@@ -77,6 +81,7 @@ float tokbps(u_int64_t bytes) { return (((double)bytes) / PERIOD) / KB; }
float tombps(u_int64_t bytes) { return (((double)bytes) / PERIOD) / MB; }
float togbps(u_int64_t bytes) { return (((double)bytes) / PERIOD) / GB; }
void process_init() {
unknowntcp = new Process(0, "", "unknown TCP");
processes = new ProcList(unknowntcp, NULL);
@@ -87,6 +92,7 @@ void process_init() {
// unknownip = new Process (0, "", "unknown IP");
// processes = new ProcList (unknownip, processes);
}
}
int Process::getLastPacket() {
@@ -262,6 +268,10 @@ Process *getProcess(unsigned long inode, const char *devicename) {
if (proc != NULL)
return proc;
if ( !(pidsToWatch.empty()) && pidsToWatch.find(node->pid) == pidsToWatch.end() ) {
return NULL;
}
// extract program name and command line from data read from cmdline file
const char *prgname = node->cmdline.c_str();
const char *cmdline = prgname + strlen(prgname) + 1;
@@ -384,6 +394,10 @@ Process *getProcess(Connection *connection, const char *devicename,
}
}
if (!(pidsToWatch.empty()) && proc == NULL) {
proc = (packettype == IPPROTO_TCP) ? unknowntcp : unknownudp;
}
if (proc == NULL) {
proc = new Process(inode, "", connection->refpacket->gethashstring());
processes = new ProcList(proc, processes);
@@ -426,3 +440,4 @@ void remove_timed_out_processes() {
}
void garbage_collect_processes() { garbage_collect_inodeproc(); }