Merge pull request #175 from azak-azkaran/master
fixes crash on "opening /proc/PID/cmdline" #144,#145
This commit is contained in:
@@ -20,8 +20,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#elif __FreeBSD__
|
#elif __FreeBSD__
|
||||||
@@ -29,8 +29,8 @@
|
|||||||
#else
|
#else
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#endif
|
#endif
|
||||||
#include "nethogs.h"
|
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
#include "nethogs.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
|
|
||||||
ConnList *connections = NULL;
|
ConnList *connections = NULL;
|
||||||
@@ -152,24 +152,21 @@ void Connection::add(Packet *packet) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connection *findConnectionWithMatchingSource(Packet *packet, short int packettype) {
|
Connection *findConnectionWithMatchingSource(Packet *packet,
|
||||||
|
short int packettype) {
|
||||||
assert(packet->Outgoing());
|
assert(packet->Outgoing());
|
||||||
|
|
||||||
ConnList *current = NULL;
|
ConnList *current = NULL;
|
||||||
switch(packettype)
|
switch (packettype) {
|
||||||
{
|
case IPPROTO_TCP: {
|
||||||
case IPPROTO_TCP:
|
|
||||||
{
|
|
||||||
current = connections;
|
current = connections;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPPROTO_UDP:
|
case IPPROTO_UDP: {
|
||||||
{
|
|
||||||
current = unknownudp->connections;
|
current = unknownudp->connections;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (current != NULL) {
|
while (current != NULL) {
|
||||||
@@ -182,25 +179,21 @@ Connection *findConnectionWithMatchingSource(Packet *packet, short int packettyp
|
|||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Connection *findConnectionWithMatchingRefpacketOrSource(Packet *packet, short int packettype) {
|
Connection *findConnectionWithMatchingRefpacketOrSource(Packet *packet,
|
||||||
|
short int packettype) {
|
||||||
|
|
||||||
ConnList *current = NULL;
|
ConnList *current = NULL;
|
||||||
switch(packettype)
|
switch (packettype) {
|
||||||
{
|
case IPPROTO_TCP: {
|
||||||
case IPPROTO_TCP:
|
|
||||||
{
|
|
||||||
current = connections;
|
current = connections;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case IPPROTO_UDP:
|
case IPPROTO_UDP: {
|
||||||
{
|
|
||||||
current = unknownudp->connections;
|
current = unknownudp->connections;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,8 @@
|
|||||||
#ifndef __CONNECTION_H
|
#ifndef __CONNECTION_H
|
||||||
#define __CONNECTION_H
|
#define __CONNECTION_H
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
class PackListNode {
|
class PackListNode {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -20,13 +20,13 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <map>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <map>
|
||||||
|
#include <netinet/in.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "nethogs.h"
|
|
||||||
#include "conninode.h"
|
#include "conninode.h"
|
||||||
|
#include "nethogs.h"
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||||
#ifndef s6_addr32
|
#ifndef s6_addr32
|
||||||
@@ -73,7 +73,8 @@ void addtoconninode(char *buffer) {
|
|||||||
}
|
}
|
||||||
unsigned long inode;
|
unsigned long inode;
|
||||||
|
|
||||||
int matches = sscanf(buffer, "%*d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %*X "
|
int matches = sscanf(buffer,
|
||||||
|
"%*d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %*X "
|
||||||
"%*X:%*X %*X:%*X %*X %*d %*d %ld %*512s\n",
|
"%*X:%*X %*X:%*X %*X %*d %*d %ld %*512s\n",
|
||||||
local_addr, &local_port, rem_addr, &rem_port, &inode);
|
local_addr, &local_port, rem_addr, &rem_port, &inode);
|
||||||
|
|
||||||
@@ -179,9 +180,9 @@ int addprocinfo(const char *filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void refreshconninode() {
|
void refreshconninode() {
|
||||||
/* we don't forget old mappings, just overwrite */
|
/* we don't forget old mappings, just overwrite */
|
||||||
// delete conninode;
|
// delete conninode;
|
||||||
// conninode = new HashTable (256);
|
// conninode = new HashTable (256);
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||||
addprocinfo("net.inet.tcp.pcblist");
|
addprocinfo("net.inet.tcp.pcblist");
|
||||||
|
|||||||
43
src/cui.cpp
43
src/cui.cpp
@@ -21,17 +21,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* NetHogs console UI */
|
/* NetHogs console UI */
|
||||||
#include <string>
|
#include <algorithm>
|
||||||
#include <pwd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <algorithm>
|
#include <pwd.h>
|
||||||
|
#include <string>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <ncurses.h>
|
|
||||||
#include "nethogs.h"
|
#include "nethogs.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
|
#include <ncurses.h>
|
||||||
|
|
||||||
std::string *caption;
|
std::string *caption;
|
||||||
extern const char version[];
|
extern const char version[];
|
||||||
@@ -65,7 +64,8 @@ const char *COLUMN_FORMAT_SENT = "%11.3f";
|
|||||||
const char *COLUMN_FORMAT_RECEIVED = "%11.3f";
|
const char *COLUMN_FORMAT_RECEIVED = "%11.3f";
|
||||||
|
|
||||||
// All descriptions are padded to 6 characters in length with spaces
|
// All descriptions are padded to 6 characters in length with spaces
|
||||||
const char* const desc_view_mode[VIEWMODE_COUNT] = {"KB/sec", "KB ", "B ", "MB ", "MB/sec", "GB/sec"};
|
const char *const desc_view_mode[VIEWMODE_COUNT] = {
|
||||||
|
"KB/sec", "KB ", "B ", "MB ", "MB/sec", "GB/sec"};
|
||||||
|
|
||||||
class Line {
|
class Line {
|
||||||
public:
|
public:
|
||||||
@@ -217,28 +217,27 @@ void Line::log() {
|
|||||||
std::cout << m_name;
|
std::cout << m_name;
|
||||||
if (showcommandline && m_cmdline)
|
if (showcommandline && m_cmdline)
|
||||||
std::cout << ' ' << m_cmdline;
|
std::cout << ' ' << m_cmdline;
|
||||||
std::cout << '/' << m_pid << '/' << m_uid << "\t" << sent_value << "\t" << recv_value << std::endl;
|
std::cout << '/' << m_pid << '/' << m_uid << "\t" << sent_value << "\t"
|
||||||
|
<< recv_value << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_devlen(Line *lines[], int nproc, int rows)
|
int get_devlen(Line *lines[], int nproc, int rows) {
|
||||||
{
|
int devlen = MIN_COLUMN_WIDTH_DEV;
|
||||||
int devlen = MIN_COLUMN_WIDTH_DEV; int curlen;
|
int curlen;
|
||||||
for (int i = 0; i < nproc; i++) {
|
for (int i = 0; i < nproc; i++) {
|
||||||
if (i + 3 < rows)
|
if (i + 3 < rows) {
|
||||||
{
|
|
||||||
curlen = strlen(lines[i]->devicename);
|
curlen = strlen(lines[i]->devicename);
|
||||||
if(curlen > devlen)
|
if (curlen > devlen)
|
||||||
curlen = devlen;
|
curlen = devlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(devlen > MAX_COLUMN_WIDTH_DEV)
|
if (devlen > MAX_COLUMN_WIDTH_DEV)
|
||||||
devlen = MAX_COLUMN_WIDTH_DEV;
|
devlen = MAX_COLUMN_WIDTH_DEV;
|
||||||
|
|
||||||
return devlen;
|
return devlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int GreatestFirst(const void *ma, const void *mb) {
|
int GreatestFirst(const void *ma, const void *mb) {
|
||||||
Line **pa = (Line **)ma;
|
Line **pa = (Line **)ma;
|
||||||
Line **pb = (Line **)mb;
|
Line **pb = (Line **)mb;
|
||||||
@@ -349,8 +348,7 @@ void show_ncurses(Line *lines[], int nproc) {
|
|||||||
if (cols > PROGNAME_WIDTH)
|
if (cols > PROGNAME_WIDTH)
|
||||||
cols = PROGNAME_WIDTH;
|
cols = PROGNAME_WIDTH;
|
||||||
|
|
||||||
|
// issue #110 - maximum devicename length min=5, max=15
|
||||||
//issue #110 - maximum devicename length min=5, max=15
|
|
||||||
int devlen = get_devlen(lines, nproc, rows);
|
int devlen = get_devlen(lines, nproc, rows);
|
||||||
|
|
||||||
proglen = cols - 50 - devlen;
|
proglen = cols - 50 - devlen;
|
||||||
@@ -360,14 +358,14 @@ void show_ncurses(Line *lines[], int nproc) {
|
|||||||
attron(A_REVERSE);
|
attron(A_REVERSE);
|
||||||
mvprintw(2, 0,
|
mvprintw(2, 0,
|
||||||
" PID USER %-*.*s %-*.*s SENT RECEIVED ",
|
" PID USER %-*.*s %-*.*s SENT RECEIVED ",
|
||||||
proglen, proglen, "PROGRAM",devlen,devlen,"DEV");
|
proglen, proglen, "PROGRAM", devlen, devlen, "DEV");
|
||||||
attroff(A_REVERSE);
|
attroff(A_REVERSE);
|
||||||
|
|
||||||
/* print them */
|
/* print them */
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < nproc; i++) {
|
for (i = 0; i < nproc; i++) {
|
||||||
if (i + 3 < rows)
|
if (i + 3 < rows)
|
||||||
lines[i]->show(i + 3, proglen,devlen);
|
lines[i]->show(i + 3, proglen, devlen);
|
||||||
recv_global += lines[i]->recv_value;
|
recv_global += lines[i]->recv_value;
|
||||||
sent_global += lines[i]->sent_value;
|
sent_global += lines[i]->sent_value;
|
||||||
delete lines[i];
|
delete lines[i];
|
||||||
@@ -375,7 +373,7 @@ void show_ncurses(Line *lines[], int nproc) {
|
|||||||
attron(A_REVERSE);
|
attron(A_REVERSE);
|
||||||
int totalrow = std::min(rows - 1, 3 + 1 + i);
|
int totalrow = std::min(rows - 1, 3 + 1 + i);
|
||||||
mvprintw(totalrow, 0, " TOTAL %-*.*s %-*.*s %11.3f %11.3f ",
|
mvprintw(totalrow, 0, " TOTAL %-*.*s %-*.*s %11.3f %11.3f ",
|
||||||
proglen, proglen, "", devlen,devlen, "", sent_global, recv_global);
|
proglen, proglen, "", devlen, devlen, "", sent_global, recv_global);
|
||||||
mvprintw(3 + 1 + i, cols - COLUMN_WIDTH_UNIT, desc_view_mode[viewMode]);
|
mvprintw(3 + 1 + i, cols - COLUMN_WIDTH_UNIT, desc_view_mode[viewMode]);
|
||||||
attroff(A_REVERSE);
|
attroff(A_REVERSE);
|
||||||
mvprintw(totalrow + 1, 0, "");
|
mvprintw(totalrow + 1, 0, "");
|
||||||
@@ -387,7 +385,8 @@ void do_refresh() {
|
|||||||
refreshconninode();
|
refreshconninode();
|
||||||
refreshcount++;
|
refreshcount++;
|
||||||
|
|
||||||
if (viewMode == VIEWMODE_KBPS || viewMode == VIEWMODE_MBPS || viewMode == VIEWMODE_GBPS) {
|
if (viewMode == VIEWMODE_KBPS || viewMode == VIEWMODE_MBPS ||
|
||||||
|
viewMode == VIEWMODE_GBPS) {
|
||||||
remove_timed_out_processes();
|
remove_timed_out_processes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,16 +20,16 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include "decpcap.h"
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#include <netinet/ip6.h>
|
#include <netinet/ip6.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <string.h> // for memcpy
|
|
||||||
#include <pcap.h>
|
#include <pcap.h>
|
||||||
#include "decpcap.h"
|
#include <string.h> // for memcpy
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#define DP_DEBUG 0
|
#define DP_DEBUG 0
|
||||||
bool catchall = false;
|
bool catchall = false;
|
||||||
@@ -92,25 +92,19 @@ struct dp_handle *dp_open_live(const char *device, int snaplen, int promisc,
|
|||||||
pcap_lookupnet(device, &netp, &maskp, errbuf);
|
pcap_lookupnet(device, &netp, &maskp, errbuf);
|
||||||
|
|
||||||
/* Compile the filter */
|
/* Compile the filter */
|
||||||
if(pcap_compile(temp, &fp, filter, 1, netp) == -1) {
|
if (pcap_compile(temp, &fp, filter, 1, netp) == -1) {
|
||||||
fprintf(
|
fprintf(stderr,
|
||||||
stderr,
|
|
||||||
"Error calling pcap_compile for filter on device %s: %s\n",
|
"Error calling pcap_compile for filter on device %s: %s\n",
|
||||||
device, pcap_geterr(temp)
|
device, pcap_geterr(temp));
|
||||||
);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the filter */
|
/* set the filter */
|
||||||
if(pcap_setfilter(temp, &fp) == -1) {
|
if (pcap_setfilter(temp, &fp) == -1) {
|
||||||
fprintf(
|
fprintf(stderr, "Error setting capture filter on device %s: %s\n", device,
|
||||||
stderr,
|
pcap_geterr(temp));
|
||||||
"Error setting capture filter on device %s: %s\n",
|
|
||||||
device, pcap_geterr(temp)
|
|
||||||
);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dp_fillhandle(temp);
|
return dp_fillhandle(temp);
|
||||||
@@ -170,7 +164,7 @@ void dp_parse_ip(struct dp_handle *handle, const dp_header *header,
|
|||||||
dp_parse_tcp(handle, header, payload);
|
dp_parse_tcp(handle, header, payload);
|
||||||
break;
|
break;
|
||||||
case IPPROTO_UDP:
|
case IPPROTO_UDP:
|
||||||
if(catchall)
|
if (catchall)
|
||||||
dp_parse_udp(handle, header, payload);
|
dp_parse_udp(handle, header, payload);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -195,7 +189,7 @@ void dp_parse_ip6(struct dp_handle *handle, const dp_header *header,
|
|||||||
dp_parse_tcp(handle, header, payload);
|
dp_parse_tcp(handle, header, payload);
|
||||||
break;
|
break;
|
||||||
case IPPROTO_UDP:
|
case IPPROTO_UDP:
|
||||||
if(catchall)
|
if (catchall)
|
||||||
dp_parse_udp(handle, header, payload);
|
dp_parse_udp(handle, header, payload);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -22,10 +22,10 @@
|
|||||||
#ifndef __DECPCAP_H
|
#ifndef __DECPCAP_H
|
||||||
#define __DECPCAP_H
|
#define __DECPCAP_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <pcap.h>
|
#include <pcap.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define DP_ERRBUF_SIZE PCAP_ERRBUF_SIZE
|
#define DP_ERRBUF_SIZE PCAP_ERRBUF_SIZE
|
||||||
extern bool catchall;
|
extern bool catchall;
|
||||||
|
|||||||
@@ -22,12 +22,12 @@
|
|||||||
|
|
||||||
#include "devices.h"
|
#include "devices.h"
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <net/if.h>
|
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
bool selected(int devc, char **devicenames, char *devicename) {
|
bool selected(int devc, char **devicenames, char *devicename) {
|
||||||
if (devc == 0)
|
if (devc == 0)
|
||||||
|
|||||||
@@ -20,20 +20,20 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cstring>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "inode2prog.h"
|
#include "inode2prog.h"
|
||||||
|
|
||||||
@@ -121,9 +121,21 @@ std::string getcmdline(pid_t pid) {
|
|||||||
char filename[maxfilenamelen];
|
char filename[maxfilenamelen];
|
||||||
|
|
||||||
std::snprintf(filename, maxfilenamelen, "/proc/%d/cmdline", pid);
|
std::snprintf(filename, maxfilenamelen, "/proc/%d/cmdline", pid);
|
||||||
|
std::string cmdline;
|
||||||
bool replace_null = false;
|
bool replace_null = false;
|
||||||
std::string cmdline = read_file(filename);
|
try {
|
||||||
|
cmdline = read_file(filename);
|
||||||
|
} catch (int e) {
|
||||||
|
std::fprintf(stderr, "An exception occurred. Exception Nr %i \n", e);
|
||||||
|
cmdline = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmdline.empty() || cmdline[cmdline.length() - 1] != '\0') {
|
||||||
|
// invalid content of cmdline file. Add null char to allow further
|
||||||
|
// processing.
|
||||||
|
cmdline.append(1, '\0');
|
||||||
|
return cmdline;
|
||||||
|
}
|
||||||
|
|
||||||
// join parameters, keep prgname separate, don't overwrite trailing null
|
// join parameters, keep prgname separate, don't overwrite trailing null
|
||||||
for (size_t idx = 0; idx < (cmdline.length() - 1); idx++) {
|
for (size_t idx = 0; idx < (cmdline.length() - 1); idx++) {
|
||||||
@@ -134,13 +146,6 @@ std::string getcmdline(pid_t pid) {
|
|||||||
replace_null = true;
|
replace_null = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdline.length() == 0 || (cmdline[cmdline.length() - 1] != 0x00)) {
|
|
||||||
// invalid content of cmdline file. Add null char to allow further
|
|
||||||
// processing.
|
|
||||||
cmdline.append("\0");
|
|
||||||
}
|
|
||||||
|
|
||||||
return cmdline;
|
return cmdline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include "nethogs.cpp"
|
#include "nethogs.cpp"
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
extern ProcList *processes;
|
extern ProcList *processes;
|
||||||
@@ -72,8 +72,8 @@ static bool wait_for_next_trigger() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nethogsmonitor_init(int devc, char **devicenames,
|
static int nethogsmonitor_init(int devc, char **devicenames, bool all,
|
||||||
bool all, char *filter) {
|
char *filter) {
|
||||||
process_init();
|
process_init();
|
||||||
|
|
||||||
device *devices = get_devices(devc, devicenames, all);
|
device *devices = get_devices(devc, devicenames, all);
|
||||||
@@ -100,8 +100,7 @@ static int nethogsmonitor_init(int devc, char **devicenames,
|
|||||||
}
|
}
|
||||||
|
|
||||||
char errbuf[PCAP_ERRBUF_SIZE];
|
char errbuf[PCAP_ERRBUF_SIZE];
|
||||||
dp_handle *newhandle =
|
dp_handle *newhandle = dp_open_live(current_dev->name, BUFSIZ, promiscuous,
|
||||||
dp_open_live(current_dev->name, BUFSIZ, promiscuous,
|
|
||||||
100, filter, errbuf);
|
100, filter, errbuf);
|
||||||
if (newhandle != NULL) {
|
if (newhandle != NULL) {
|
||||||
dp_addcb(newhandle, dp_packet_ip, process_ip);
|
dp_addcb(newhandle, dp_packet_ip, process_ip);
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#define NETHOGS_DSO_VISIBLE __attribute__((visibility("default")))
|
#define NETHOGS_DSO_VISIBLE __attribute__((visibility("default")))
|
||||||
#define NETHOGS_DSO_HIDDEN __attribute__((visibility("hidden")))
|
#define NETHOGS_DSO_HIDDEN __attribute__((visibility("hidden")))
|
||||||
|
|||||||
33
src/main.cpp
33
src/main.cpp
@@ -3,11 +3,11 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
#include <linux/capability.h>
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/xattr.h>
|
#include <sys/xattr.h>
|
||||||
#include <linux/capability.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The self_pipe is used to interrupt the select() in the main loop
|
// The self_pipe is used to interrupt the select() in the main loop
|
||||||
@@ -43,9 +43,11 @@ static void help(bool iserror) {
|
|||||||
output << " -p : sniff in promiscious mode (not recommended).\n";
|
output << " -p : sniff in promiscious mode (not recommended).\n";
|
||||||
output << " -s : sort output by sent column.\n";
|
output << " -s : sort output by sent column.\n";
|
||||||
output << " -l : display command line.\n";
|
output << " -l : display command line.\n";
|
||||||
output << " -a : monitor all devices, even loopback/stopped ones.\n";
|
output << " -a : monitor all devices, even loopback/stopped "
|
||||||
|
"ones.\n";
|
||||||
output << " -C : capture TCP and UDP.\n";
|
output << " -C : capture TCP and UDP.\n";
|
||||||
output << " -f : EXPERIMENTAL: specify string pcap filter (like tcpdump)."
|
output << " -f : EXPERIMENTAL: specify string pcap filter (like "
|
||||||
|
"tcpdump)."
|
||||||
" This may be removed or changed in a future version.\n";
|
" This may be removed or changed in a future version.\n";
|
||||||
output << " device : device(s) to monitor. default is all "
|
output << " device : device(s) to monitor. default is all "
|
||||||
"interfaces up and running excluding loopback\n";
|
"interfaces up and running excluding loopback\n";
|
||||||
@@ -55,7 +57,8 @@ static void help(bool iserror) {
|
|||||||
output << " s: sort by SENT traffic\n";
|
output << " s: sort by SENT traffic\n";
|
||||||
output << " r: sort by RECEIVE traffic\n";
|
output << " r: sort by RECEIVE traffic\n";
|
||||||
output << " l: display command line\n";
|
output << " l: display command line\n";
|
||||||
output << " m: switch between total (KB, B, MB) and throughput (KB/s, MB/s, GB/s) mode\n";
|
output << " m: switch between total (KB, B, MB) and throughput (KB/s, MB/s, "
|
||||||
|
"GB/s) mode\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void quit_cb(int /* i */) {
|
void quit_cb(int /* i */) {
|
||||||
@@ -161,7 +164,7 @@ int main(int argc, char **argv) {
|
|||||||
sortRecv = false;
|
sortRecv = false;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
refreshdelay = (time_t) atoi(optarg);
|
refreshdelay = (time_t)atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
viewMode = atoi(optarg) % VIEWMODE_COUNT;
|
viewMode = atoi(optarg) % VIEWMODE_COUNT;
|
||||||
@@ -201,7 +204,7 @@ int main(int argc, char **argv) {
|
|||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
char exe_path[PATH_MAX];
|
char exe_path[PATH_MAX];
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
unsigned int caps[5] = {0,0,0,0,0};
|
unsigned int caps[5] = {0, 0, 0, 0, 0};
|
||||||
|
|
||||||
if ((len = readlink("/proc/self/exe", exe_path, PATH_MAX)) == -1)
|
if ((len = readlink("/proc/self/exe", exe_path, PATH_MAX)) == -1)
|
||||||
forceExit(false, "Failed to locate nethogs binary.");
|
forceExit(false, "Failed to locate nethogs binary.");
|
||||||
@@ -209,8 +212,11 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
getxattr(exe_path, "security.capability", (char *)caps, sizeof(caps));
|
getxattr(exe_path, "security.capability", (char *)caps, sizeof(caps));
|
||||||
|
|
||||||
if ((((caps[1] >> CAP_NET_ADMIN) & 1) != 1) || (((caps[1] >> CAP_NET_RAW) & 1) != 1))
|
if ((((caps[1] >> CAP_NET_ADMIN) & 1) != 1) ||
|
||||||
forceExit(false, "To run nethogs without being root you need to enable capabilities on the program (cap_net_admin, cap_net_raw), see the documentation for details.");
|
(((caps[1] >> CAP_NET_RAW) & 1) != 1))
|
||||||
|
forceExit(false, "To run nethogs without being root you need to enable "
|
||||||
|
"capabilities on the program (cap_net_admin, "
|
||||||
|
"cap_net_raw), see the documentation for details.");
|
||||||
#else
|
#else
|
||||||
forceExit(false, "You need to be root to run NetHogs!");
|
forceExit(false, "You need to be root to run NetHogs!");
|
||||||
#endif
|
#endif
|
||||||
@@ -298,11 +304,12 @@ int main(int argc, char **argv) {
|
|||||||
int retval = dp_dispatch(current_handle->content, -1, (u_char *)userdata,
|
int retval = dp_dispatch(current_handle->content, -1, (u_char *)userdata,
|
||||||
sizeof(struct dpargs));
|
sizeof(struct dpargs));
|
||||||
if (retval == -1)
|
if (retval == -1)
|
||||||
std::cerr << "Error dispatching for device " << current_handle->devicename <<
|
std::cerr << "Error dispatching for device "
|
||||||
": " << dp_geterr(current_handle->content) << std::endl;
|
<< current_handle->devicename << ": "
|
||||||
|
<< dp_geterr(current_handle->content) << std::endl;
|
||||||
else if (retval < 0)
|
else if (retval < 0)
|
||||||
std::cerr << "Error dispatching for device " << current_handle->devicename <<
|
std::cerr << "Error dispatching for device "
|
||||||
": " << retval << std::endl;
|
<< current_handle->devicename << ": " << retval << std::endl;
|
||||||
else if (retval != 0)
|
else if (retval != 0)
|
||||||
packets_read = true;
|
packets_read = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,16 +22,16 @@
|
|||||||
|
|
||||||
#include "nethogs.h"
|
#include "nethogs.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <cassert>
|
||||||
|
#include <csignal>
|
||||||
|
#include <cstdarg>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cassert>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <csignal>
|
|
||||||
#include <string>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <cstdarg>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#include <netinet/ip6.h>
|
#include <netinet/ip6.h>
|
||||||
@@ -44,10 +44,10 @@ extern "C" {
|
|||||||
#include "decpcap.h"
|
#include "decpcap.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "packet.h"
|
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "process.h"
|
|
||||||
#include "devices.h"
|
#include "devices.h"
|
||||||
|
#include "packet.h"
|
||||||
|
#include "process.h"
|
||||||
|
|
||||||
extern Process *unknownudp;
|
extern Process *unknownudp;
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ int process_udp(u_char *userdata, const dp_header *header,
|
|||||||
/* else: unknown connection, create new */
|
/* else: unknown connection, create new */
|
||||||
connection = new Connection(packet);
|
connection = new Connection(packet);
|
||||||
unknownudp->connections = new ConnList(connection, unknownudp->connections);
|
unknownudp->connections = new ConnList(connection, unknownudp->connections);
|
||||||
//getProcess(connection, args->device);
|
// getProcess(connection, args->device);
|
||||||
}
|
}
|
||||||
delete packet;
|
delete packet;
|
||||||
|
|
||||||
|
|||||||
@@ -23,12 +23,12 @@
|
|||||||
#ifndef __NETHOGS_H
|
#ifndef __NETHOGS_H
|
||||||
#define __NETHOGS_H
|
#define __NETHOGS_H
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#elif __FreeBSD__
|
#elif __FreeBSD__
|
||||||
|
|||||||
@@ -20,12 +20,12 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "packet.h"
|
||||||
#include "nethogs.h"
|
#include "nethogs.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "packet.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <netinet/tcp.h>
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <stdio.h>
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#elif __FreeBSD__
|
#elif __FreeBSD__
|
||||||
@@ -34,12 +34,12 @@
|
|||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#endif
|
#endif
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <net/if.h>
|
#include <ifaddrs.h>
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
|
#include <net/if.h>
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#include <netinet/ip6.h>
|
#include <netinet/ip6.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <ifaddrs.h>
|
|
||||||
// #include "inet6.c"
|
// #include "inet6.c"
|
||||||
|
|
||||||
local_addr *local_addrs = NULL;
|
local_addr *local_addrs = NULL;
|
||||||
|
|||||||
@@ -26,10 +26,10 @@
|
|||||||
#define _BSD_SOURCE 1
|
#define _BSD_SOURCE 1
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include "nethogs.h"
|
#include "nethogs.h"
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
enum direction { dir_unknown, dir_incoming, dir_outgoing };
|
enum direction { dir_unknown, dir_incoming, dir_outgoing };
|
||||||
|
|
||||||
|
|||||||
@@ -21,24 +21,24 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <strings.h>
|
|
||||||
#include <string>
|
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
|
#include <string>
|
||||||
|
#include <strings.h>
|
||||||
#if !defined(__APPLE__) && !defined(__FreeBSD__)
|
#if !defined(__APPLE__) && !defined(__FreeBSD__)
|
||||||
#include <asm/types.h>
|
#include <asm/types.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "process.h"
|
|
||||||
#include "nethogs.h"
|
|
||||||
#include "inode2prog.h"
|
|
||||||
#include "conninode.h"
|
#include "conninode.h"
|
||||||
|
#include "inode2prog.h"
|
||||||
|
#include "nethogs.h"
|
||||||
|
#include "process.h"
|
||||||
|
|
||||||
extern timeval curtime;
|
extern timeval curtime;
|
||||||
extern bool catchall;
|
extern bool catchall;
|
||||||
@@ -80,10 +80,9 @@ void process_init() {
|
|||||||
unknowntcp = new Process(0, "", "unknown TCP");
|
unknowntcp = new Process(0, "", "unknown TCP");
|
||||||
processes = new ProcList(unknowntcp, NULL);
|
processes = new ProcList(unknowntcp, NULL);
|
||||||
|
|
||||||
if(catchall)
|
if (catchall) {
|
||||||
{
|
unknownudp = new Process(0, "", "unknown UDP");
|
||||||
unknownudp = new Process (0, "", "unknown UDP");
|
processes = new ProcList(unknownudp, processes);
|
||||||
processes = new ProcList (unknownudp, processes);
|
|
||||||
// unknownip = new Process (0, "", "unknown IP");
|
// unknownip = new Process (0, "", "unknown IP");
|
||||||
// processes = new ProcList (unknownip, processes);
|
// processes = new ProcList (unknownip, processes);
|
||||||
}
|
}
|
||||||
@@ -103,7 +102,8 @@ int Process::getLastPacket() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** get total values for this process for only active connections */
|
/** get total values for this process for only active connections */
|
||||||
static void sum_active_connections(Process* process_ptr, u_int64_t& sum_sent, u_int64_t& sum_recv) {
|
static void sum_active_connections(Process *process_ptr, u_int64_t &sum_sent,
|
||||||
|
u_int64_t &sum_recv) {
|
||||||
/* walk though all process_ptr process's connections, and sum
|
/* walk though all process_ptr process's connections, and sum
|
||||||
* them up */
|
* them up */
|
||||||
ConnList *curconn = process_ptr->connections;
|
ConnList *curconn = process_ptr->connections;
|
||||||
@@ -313,8 +313,8 @@ Process *getProcess(Connection *connection, const char *devicename) {
|
|||||||
// no? refresh and check conn/inode table
|
// no? refresh and check conn/inode table
|
||||||
if (bughuntmode) {
|
if (bughuntmode) {
|
||||||
std::cout << "? new connection not in connection-to-inode table before "
|
std::cout << "? new connection not in connection-to-inode table before "
|
||||||
"refresh, hash " << connection->refpacket->gethashstring()
|
"refresh, hash "
|
||||||
<< std::endl;
|
<< connection->refpacket->gethashstring() << std::endl;
|
||||||
}
|
}
|
||||||
// refresh the inode->pid table first. Presumably processing the renewed
|
// refresh the inode->pid table first. Presumably processing the renewed
|
||||||
// connection->inode table
|
// connection->inode table
|
||||||
@@ -390,7 +390,8 @@ void procclean() {
|
|||||||
void remove_timed_out_processes() {
|
void remove_timed_out_processes() {
|
||||||
ProcList *previousproc = NULL;
|
ProcList *previousproc = NULL;
|
||||||
|
|
||||||
for (ProcList *curproc = processes; curproc != NULL; curproc = curproc->next) {
|
for (ProcList *curproc = processes; curproc != NULL;
|
||||||
|
curproc = curproc->next) {
|
||||||
if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <=
|
if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <=
|
||||||
curtime.tv_sec) &&
|
curtime.tv_sec) &&
|
||||||
(curproc->getVal() != unknowntcp) &&
|
(curproc->getVal() != unknowntcp) &&
|
||||||
|
|||||||
@@ -23,9 +23,9 @@
|
|||||||
#ifndef __PROCESS_H
|
#ifndef __PROCESS_H
|
||||||
#define __PROCESS_H
|
#define __PROCESS_H
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include "nethogs.h"
|
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
#include "nethogs.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
extern bool tracemode;
|
extern bool tracemode;
|
||||||
extern bool bughuntmode;
|
extern bool bughuntmode;
|
||||||
|
|||||||
Reference in New Issue
Block a user