fixes #119 - add support for pcap capture filters
This commit is contained in:
@@ -77,13 +77,42 @@ struct dp_handle *dp_open_offline(char *fname, char *ebuf) {
|
||||
}
|
||||
|
||||
struct dp_handle *dp_open_live(const char *device, int snaplen, int promisc,
|
||||
int to_ms, char *errbuf) {
|
||||
int to_ms, char *filter, char *errbuf) {
|
||||
struct bpf_program fp; // compiled filter program
|
||||
bpf_u_int32 maskp; // subnet mask
|
||||
bpf_u_int32 netp; // interface IP
|
||||
|
||||
pcap_t *temp = pcap_open_live(device, snaplen, promisc, to_ms, errbuf);
|
||||
|
||||
if (temp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (filter != NULL) {
|
||||
pcap_lookupnet(device, &netp, &maskp, errbuf);
|
||||
|
||||
/* Compile the filter */
|
||||
if(pcap_compile(temp, &fp, filter, 1, netp) == -1) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Error calling pcap_compile for filter on device %s: %s\n",
|
||||
device, pcap_geterr(temp)
|
||||
);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set the filter */
|
||||
if(pcap_setfilter(temp, &fp) == -1) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Error setting capture filter on device %s: %s\n",
|
||||
device, pcap_geterr(temp)
|
||||
);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return dp_fillhandle(temp);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ struct dp_handle {
|
||||
/* functions to set up a handle (which is basically just a pcap handle) */
|
||||
|
||||
struct dp_handle *dp_open_live(const char *device, int snaplen, int promisc,
|
||||
int to_ms, char *errbuf);
|
||||
int to_ms, char *filter, char *errbuf);
|
||||
struct dp_handle *dp_open_offline(char *fname, char *ebuf);
|
||||
|
||||
/* functions to add callbacks */
|
||||
|
||||
@@ -72,7 +72,8 @@ static bool wait_for_next_trigger() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int nethogsmonitor_init(int devc, char **devicenames, bool all) {
|
||||
static int nethogsmonitor_init(int devc, char **devicenames,
|
||||
bool all, char *filter) {
|
||||
process_init();
|
||||
|
||||
device *devices = get_devices(devc, devicenames, all);
|
||||
@@ -100,7 +101,8 @@ static int nethogsmonitor_init(int devc, char **devicenames, bool all) {
|
||||
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
dp_handle *newhandle =
|
||||
dp_open_live(current_dev->name, BUFSIZ, promiscuous, 100, errbuf);
|
||||
dp_open_live(current_dev->name, BUFSIZ, promiscuous,
|
||||
100, filter, errbuf);
|
||||
if (newhandle != NULL) {
|
||||
dp_addcb(newhandle, dp_packet_ip, process_ip);
|
||||
dp_addcb(newhandle, dp_packet_ip6, process_ip6);
|
||||
@@ -271,17 +273,17 @@ static void nethogsmonitor_clean_up() {
|
||||
procclean();
|
||||
}
|
||||
|
||||
int nethogsmonitor_loop(NethogsMonitorCallback cb) {
|
||||
return nethogsmonitor_loop_devices(cb, 0, NULL, false);
|
||||
int nethogsmonitor_loop(NethogsMonitorCallback cb, char *filter) {
|
||||
return nethogsmonitor_loop_devices(cb, filter, 0, NULL, false);
|
||||
}
|
||||
|
||||
int nethogsmonitor_loop_devices(NethogsMonitorCallback cb,
|
||||
int nethogsmonitor_loop_devices(NethogsMonitorCallback cb, char *filter,
|
||||
int devc, char **devicenames, bool all) {
|
||||
if (monitor_run_flag) {
|
||||
return NETHOGS_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
int return_value = nethogsmonitor_init(devc, devicenames, all);
|
||||
int return_value = nethogsmonitor_init(devc, devicenames, all, filter);
|
||||
if (return_value != NETHOGS_STATUS_OK) {
|
||||
return return_value;
|
||||
}
|
||||
|
||||
@@ -53,9 +53,13 @@ typedef void (*NethogsMonitorCallback)(int action,
|
||||
* occurs.
|
||||
* @param cb A pointer to a callback function following the
|
||||
* NethogsMonitorCallback definition
|
||||
* @param filter A string (char array) pcap filter to restrict what packets
|
||||
* are captured, or NULL. The filter string format is the same as that of
|
||||
* tcpdump(1); for full details, see the man page for pcap-filter(7).
|
||||
*/
|
||||
|
||||
NETHOGS_DSO_VISIBLE int nethogsmonitor_loop(NethogsMonitorCallback cb);
|
||||
NETHOGS_DSO_VISIBLE int nethogsmonitor_loop(NethogsMonitorCallback cb,
|
||||
char *filter);
|
||||
|
||||
/**
|
||||
* @brief Enter the process monitoring loop and reports updates using the
|
||||
@@ -65,6 +69,9 @@ NETHOGS_DSO_VISIBLE int nethogsmonitor_loop(NethogsMonitorCallback cb);
|
||||
* occurs.
|
||||
* @param cb A pointer to a callback function following the
|
||||
* NethogsMonitorCallback definition
|
||||
* @param filter A string (char array) pcap filter to restrict what packets
|
||||
* are captured, or NULL. The filter string format is the same as that of
|
||||
* tcpdump(1); for full details, see the man page for pcap-filter(7).
|
||||
* @param devc number of values in devicenames array
|
||||
* @param devicenames pointer to array of devicenames (char arrays)
|
||||
* @param all when false, loopback interface and down/not running interfaces
|
||||
@@ -72,7 +79,8 @@ NETHOGS_DSO_VISIBLE int nethogsmonitor_loop(NethogsMonitorCallback cb);
|
||||
*/
|
||||
|
||||
NETHOGS_DSO_VISIBLE int nethogsmonitor_loop_devices(NethogsMonitorCallback cb,
|
||||
int devc, char **devicenames,
|
||||
char *filter, int devc,
|
||||
char **devicenames,
|
||||
bool all);
|
||||
|
||||
/**
|
||||
|
||||
21
src/main.cpp
21
src/main.cpp
@@ -27,7 +27,8 @@ 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] [device [device [device ...]]]\n";
|
||||
"[-t] [-p] [-s] [-a] [-l] [-f filter] "
|
||||
"[device [device [device ...]]]\n";
|
||||
output << " -V : prints version.\n";
|
||||
output << " -h : prints this help.\n";
|
||||
output << " -b : bughunt mode - implies tracemode.\n";
|
||||
@@ -45,6 +46,7 @@ static void help(bool iserror) {
|
||||
output << " -a : monitor all devices, even loopback/stopped ones.\n";
|
||||
output << " device : device(s) to monitor. default is all "
|
||||
"interfaces up and running excluding loopback\n";
|
||||
output << " -f : specify string pcap filter (like tcpdump).\n";
|
||||
output << std::endl;
|
||||
output << "When nethogs is running, press:\n";
|
||||
output << " q: quit\n";
|
||||
@@ -133,9 +135,10 @@ int main(int argc, char **argv) {
|
||||
|
||||
int promisc = 0;
|
||||
bool all = false;
|
||||
char *filter = NULL;
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "Vhbtpsd:v:c:la")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "Vhbtpsd:v:c:laf:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'V':
|
||||
versiondisplay();
|
||||
@@ -171,6 +174,9 @@ int main(int argc, char **argv) {
|
||||
case 'a':
|
||||
all = true;
|
||||
break;
|
||||
case 'f':
|
||||
filter = optarg;
|
||||
break;
|
||||
default:
|
||||
help(true);
|
||||
exit(EXIT_FAILURE);
|
||||
@@ -216,16 +222,20 @@ int main(int argc, char **argv) {
|
||||
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
|
||||
int nb_devices = 0;
|
||||
int nb_failed_devices = 0;
|
||||
|
||||
handle *handles = NULL;
|
||||
device *current_dev = devices;
|
||||
while (current_dev != NULL) {
|
||||
++nb_devices;
|
||||
|
||||
if (!getLocal(current_dev->name, tracemode)) {
|
||||
forceExit(false, "getifaddrs failed while establishing local IP.");
|
||||
}
|
||||
|
||||
dp_handle *newhandle =
|
||||
dp_open_live(current_dev->name, BUFSIZ, promisc, 100, errbuf);
|
||||
dp_open_live(current_dev->name, BUFSIZ, promisc, 100, filter, errbuf);
|
||||
if (newhandle != NULL) {
|
||||
dp_addcb(newhandle, dp_packet_ip, process_ip);
|
||||
dp_addcb(newhandle, dp_packet_ip6, process_ip6);
|
||||
@@ -258,11 +268,16 @@ int main(int argc, char **argv) {
|
||||
} else {
|
||||
fprintf(stderr, "Error opening handler for device %s\n",
|
||||
current_dev->name);
|
||||
++nb_failed_devices;
|
||||
}
|
||||
|
||||
current_dev = current_dev->next;
|
||||
}
|
||||
|
||||
if (nb_devices == nb_failed_devices) {
|
||||
forceExit(false, "Error opening pcap handlers for all devices.\n");
|
||||
}
|
||||
|
||||
signal(SIGINT, &quit_cb);
|
||||
|
||||
struct dpargs *userdata = (dpargs *)malloc(sizeof(struct dpargs));
|
||||
|
||||
Reference in New Issue
Block a user