Packet capture support for the Flowgrind daemon.
More...
#include "config.h"
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <stdbool.h>
#include <string.h>
#include <syslog.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <pcap.h>
#include <netdb.h>
#include "debug.h"
#include "fg_socket.h"
#include "fg_time.h"
#include "fg_string.h"
#include "fg_log.h"
#include "daemon.h"
#include "fg_pcap.h"
Go to the source code of this file.
Packet capture support for the Flowgrind daemon.
Definition in file fg_pcap.c.
◆ PCAP_FILTER
#define PCAP_FILTER "tcp" |
◆ PCAP_PROMISC
◆ PCAP_SNAPLEN
◆ fg_pcap_cleanup()
void fg_pcap_cleanup |
( |
void * |
arg | ) |
|
Cleanup method to be called after dumping of the specified flow has finished.
It closes the handle to the savefile and the handle to the device whose traffic was captured.
- Parameters
-
[in] | arg | pointer to the flow whose dumping finished |
Definition at line 125 of file fg_pcap.c.
134 DEBUG_MSG(LOG_DEBUG,
"fg_pcap_cleanup() called for flow %d",
flow->
id);
◆ fg_pcap_go()
void fg_pcap_go |
( |
struct flow * |
flow | ) |
|
Start a tcpdump to capture traffic of the provided flow.
If the flow was not configured for tcp dumping or dumping is already in progress the method will do nothing and return immediately. Otherwise the method blocks until the actual capturing starts. In case an error occurs a log message is created.
- Parameters
-
[in] | flow | the flow whose traffic should be captured |
Definition at line 314 of file fg_pcap.c.
320 logging(LOG_WARNING,
"pcap: dumping already in progress on "
335 logging(LOG_WARNING,
"could not start pcap thread: %s",
◆ fg_pcap_init()
int fg_pcap_init |
( |
void |
| ) |
|
Initialize flowgrind's pcap library.
This method fills internal structures on which other methods of this library depend. It is therefore crucial to call it before any call to other methods of this library.
- Returns
- return 0 for success, or -1 for failure
Definition at line 84 of file fg_pcap.c.
88 logging(LOG_WARNING,
"error in pcap_findalldevs: %s\n",
errbuf);
93 for (pcap_if_t *d =
alldevs; d; d = d->next) {
95 if (asprintf(&devdes,
"%s: ", d->name) == -1)
98 for (pcap_addr_t *a = d->addresses; a; a = a->next) {
104 sizeof(
struct sockaddr)));
108 DEBUG_MSG(LOG_ERR,
"pcap: found pcapable device (%s)", devdes);
◆ fg_pcap_work()
static void* fg_pcap_work |
( |
void * |
arg | ) |
|
|
static |
Worker method performing actual packet capturing for the provided flow.
It prepares the flow for packet capturing by figuring out the correct device, constructing the pcap filter, etc. and finally starts capturing. Synchronizes with fg_pcap_go() after initialization before starting capturing.
- Parameters
-
[in] | arg | pointer to the flow whose traffic should be captured |
Definition at line 155 of file fg_pcap.c.
170 struct addrinfo *ainf = NULL;
173 logging(LOG_WARNING,
"getaddrinfo() failed (%s). Eliding "
174 "packet capture for flow", gai_strerror(rc));
181 for (d =
alldevs; d; d = d->next) {
182 for (pcap_addr_t *a = d->addresses; a; a = a->next) {
186 DEBUG_MSG(LOG_NOTICE,
"pcap: data connection "
187 "inbound from %s (%s)", d->name,
189 sizeof(
struct sockaddr)));
199 logging(LOG_WARNING,
"failed to determine interface for data "
200 "connection. No pcap support");
209 logging(LOG_WARNING,
"failed to init pcap on device %s: %s",
214 uint32_t net = 0, mask = 0;
215 if (pcap_lookupnet(d->name, &net, &mask,
errbuf) < 0) {
216 logging(LOG_WARNING,
"pcap: netmask lookup failed: %s",
errbuf);
222 logging(LOG_WARNING,
"pcap: failed to set non-blocking: %s",
228 struct bpf_program pcap_program;
231 logging(LOG_WARNING,
"pcap: failed compiling filter '%s': %s",
238 &pcap_program) < 0) {
239 logging(LOG_WARNING,
"pcap: failed to set filter: %s",
245 char *dump_filename = NULL;
254 char timestamp[30] =
"";
255 ctimenow_r(timestamp,
sizeof(timestamp),
false);
259 char hostname[128] =
"";
260 if (!gethostname(hostname,
sizeof(hostname)))
266 DEBUG_MSG(LOG_NOTICE,
"dumping to \"%s\"", dump_filename);
273 logging(LOG_WARNING,
"pcap: failed to open dump file writing: %s",
286 logging(LOG_WARNING,
"pcap_dispatch() failed. Packet "
287 "dumping stopped for flow %d",
flow->
id);
292 struct pcap_stat p_stats;
295 DEBUG_MSG(LOG_NOTICE,
"pcap: finished dumping %d packets for "
297 DEBUG_MSG(LOG_NOTICE,
"pcap: %d packets received by filter for "
298 "flow %d", p_stats.ps_recv,
flow->
id);
299 DEBUG_MSG(LOG_NOTICE,
"pcap: %d packets dropped by kernel for "
300 "flow %d", p_stats.ps_drop,
flow->
id);
303 pthread_testcancel();
308 pthread_cleanup_pop(1);
◆ alldevs
◆ dumping
◆ errbuf
char errbuf[PCAP_ERRBUF_SIZE] = "" |
|
static |
◆ pcap_barrier