feature: packet I/O suppport dumpfile list mode
This commit is contained in:
@@ -25,9 +25,9 @@
|
||||
|
||||
struct dumpfile_io
|
||||
{
|
||||
enum packet_io_mode mode;
|
||||
uint16_t nr_threads;
|
||||
char work_dir[256];
|
||||
char directory[256];
|
||||
char dumpfile_path[256];
|
||||
|
||||
pcap_t *pcap;
|
||||
struct lock_free_queue *queue[MAX_THREAD_NUM];
|
||||
@@ -47,69 +47,6 @@ struct pcap_pkt
|
||||
* Private API
|
||||
******************************************************************************/
|
||||
|
||||
typedef int file_handle(const char *file, void *arg);
|
||||
|
||||
static int scan_directory(const char *dir, file_handle *handler, void *arg)
|
||||
{
|
||||
struct stat statbuf;
|
||||
struct dirent *entry;
|
||||
|
||||
DIR *dp = opendir(dir);
|
||||
if (NULL == dp)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("opendir %s failed, %s", dir, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (chdir(dir) == -1)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("chdir %s failed, %s", dir, strerror(errno));
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
while ((entry = readdir(dp)))
|
||||
{
|
||||
if (lstat(entry->d_name, &statbuf) == -1)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("lstat %s failed, %s", entry->d_name, strerror(errno));
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if (S_IFDIR & statbuf.st_mode)
|
||||
{
|
||||
if (!strcmp(".", entry->d_name) || !strcmp("..", entry->d_name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (scan_directory(entry->d_name, handler, arg) == -1)
|
||||
{
|
||||
goto error_out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (handler(entry->d_name, arg) == -1)
|
||||
{
|
||||
goto error_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chdir("..") == -1)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("chdir .. failed, %s", strerror(errno));
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
closedir(dp);
|
||||
return 0;
|
||||
|
||||
error_out:
|
||||
closedir(dp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void pcap_packet_handler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
|
||||
{
|
||||
struct dumpfile_io *handle = (struct dumpfile_io *)user;
|
||||
@@ -152,16 +89,15 @@ static void pcap_packet_handler(u_char *user, const struct pcap_pkthdr *h, const
|
||||
}
|
||||
}
|
||||
|
||||
static int dumpfile_handler(const char *file, void *arg)
|
||||
static int dumpfile_handler(struct dumpfile_io *handle, const char *pcap_file)
|
||||
{
|
||||
char resolved_path[256];
|
||||
char pcap_errbuf[PCAP_ERRBUF_SIZE];
|
||||
struct dumpfile_io *handle = (struct dumpfile_io *)arg;
|
||||
|
||||
realpath(file, resolved_path);
|
||||
realpath(pcap_file, resolved_path);
|
||||
PACKET_IO_LOG_STATE("dumpfile %s in-processing", resolved_path)
|
||||
|
||||
handle->pcap = pcap_open_offline(file, pcap_errbuf);
|
||||
handle->pcap = pcap_open_offline(resolved_path, pcap_errbuf);
|
||||
if (handle->pcap == NULL)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("unable to open pcap file: %s, %s", resolved_path, pcap_errbuf);
|
||||
@@ -194,7 +130,39 @@ static void *dumpfile_thread(void *arg)
|
||||
ATOMIC_SET(&handle->io_thread_is_runing, 1);
|
||||
PACKET_IO_LOG_STATE("dumpfile io thread is running");
|
||||
|
||||
scan_directory(handle->directory, dumpfile_handler, arg);
|
||||
if (handle->mode == PACKET_IO_DUMPFILE)
|
||||
{
|
||||
dumpfile_handler(handle, handle->dumpfile_path);
|
||||
}
|
||||
else // PACKET_IO_DUMPFILELIST
|
||||
{
|
||||
FILE *fp = fopen(handle->dumpfile_path, "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("unable to open dumpfile list: %s", handle->dumpfile_path);
|
||||
goto erro_out;
|
||||
}
|
||||
|
||||
char line[PATH_MAX];
|
||||
while (fgets(line, sizeof(line), fp))
|
||||
{
|
||||
if (line[0] == '#')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
char *pos = strchr(line, '\n');
|
||||
if (pos)
|
||||
{
|
||||
*pos = '\0';
|
||||
}
|
||||
|
||||
dumpfile_handler(handle, line);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
erro_out:
|
||||
PACKET_IO_LOG_STATE("dumpfile io thread processed all pcap files");
|
||||
|
||||
while (ATOMIC_READ(&handle->io_thread_need_exit) == 0)
|
||||
@@ -217,7 +185,7 @@ static void *dumpfile_thread(void *arg)
|
||||
* Public API
|
||||
******************************************************************************/
|
||||
|
||||
struct dumpfile_io *dumpfile_io_new(const char *directory, uint16_t nr_threads)
|
||||
struct dumpfile_io *dumpfile_io_new(const char *dumpfile_path, enum packet_io_mode mode, uint16_t nr_threads)
|
||||
{
|
||||
pthread_t tid;
|
||||
struct dumpfile_io *handle = (struct dumpfile_io *)calloc(1, sizeof(struct dumpfile_io));
|
||||
@@ -226,14 +194,10 @@ struct dumpfile_io *dumpfile_io_new(const char *directory, uint16_t nr_threads)
|
||||
PACKET_IO_LOG_ERROR("unable to allocate memory for dumpfile_io");
|
||||
return NULL;
|
||||
}
|
||||
if (getcwd(handle->work_dir, sizeof(handle->work_dir)) == NULL)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("unable to get current work directory");
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
handle->mode = mode;
|
||||
handle->nr_threads = nr_threads;
|
||||
strncpy(handle->directory, directory, MIN(strlen(directory), sizeof(handle->directory)));
|
||||
strncpy(handle->dumpfile_path, dumpfile_path, MIN(strlen(dumpfile_path), sizeof(handle->dumpfile_path)));
|
||||
|
||||
for (uint16_t i = 0; i < handle->nr_threads; i++)
|
||||
{
|
||||
@@ -419,7 +383,7 @@ int dumpfile_io_inject(struct dumpfile_io *handle, uint16_t thr_idx, struct pack
|
||||
inet_ntop(AF_INET6, &tuple.src_addr.v6, src_addr, INET6_ADDRSTRLEN);
|
||||
inet_ntop(AF_INET6, &tuple.dst_addr.v6, dst_addr, INET6_ADDRSTRLEN);
|
||||
}
|
||||
snprintf(file, sizeof(file), "%s/inject-%s:%u-%s:%u-%lu.pcap", handle->work_dir, src_addr, ntohs(tuple.src_port), dst_addr, ntohs(tuple.dst_port), stat->pkts_injected);
|
||||
snprintf(file, sizeof(file), "inject-%s:%u-%s:%u-%lu.pcap", src_addr, ntohs(tuple.src_port), dst_addr, ntohs(tuple.dst_port), stat->pkts_injected);
|
||||
|
||||
if (packet_dump_pcap(pkt, file) == -1)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user