feature: packet I/O suppport dumpfile list mode

This commit is contained in:
luwenpeng
2024-08-19 18:40:49 +08:00
parent 520eb085b8
commit 29cbe532ef
8 changed files with 72 additions and 98 deletions

View File

@@ -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)
{