diff options
Diffstat (limited to '')
-rw-r--r-- | ui/text_import_regex.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/ui/text_import_regex.c b/ui/text_import_regex.c new file mode 100644 index 00000000..928957a7 --- /dev/null +++ b/ui/text_import_regex.c @@ -0,0 +1,115 @@ +/* text_import_regex.c + * Regex based text importer + * March 2021, Paul Weiß <paulniklasweiss@gmail.com> + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * Based on text_import.c by Jaap Keuter <jaap.keuter@xs4all.nl> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> + +#include <glib.h> + +#include "text_import.h" +#include "text_import_regex.h" + +typedef unsigned int uint; + +/*--- Options --------------------------------------------------------------------*/ + +int text_import_regex(const text_import_info_t* info) { + int status = 1; + int parsed_packets = 0; + ws_debug("starting import..."); + + // IO + GMappedFile* file = g_mapped_file_ref(info->regex.import_text_GMappedFile); + GError* gerror = NULL; + gsize f_size = g_mapped_file_get_length(file); + guchar* f_content = g_mapped_file_get_contents(file); + { /* zero terminate the file */ + if (f_content[f_size - 1] != '\n') { + fprintf(stderr, "Error: file did not end on \\n\n"); + g_mapped_file_unref(file); + return -1; + } + f_content[f_size] = 0; + } + + // Regex result dissecting + gboolean re_time, re_dir, re_seqno; + GMatchInfo* match; + gint field_start; + gint field_end; + { /* analyze regex */ + re_time = g_regex_get_string_number(info->regex.format, "time") >= 0; + re_dir = g_regex_get_string_number(info->regex.format, "dir") >= 0; + re_seqno = g_regex_get_string_number(info->regex.format, "seqno") >= 0; + if (g_regex_get_string_number(info->regex.format, "data") < 0) { + /* This should never happen, as the dialog checks for this */ + fprintf(stderr, "Error could not find data in pattern\n"); + g_mapped_file_unref(file); + return -1; + } + } + + ws_debug("regex has %s%s%s", re_dir ? "dir, " : "", + re_time ? "time, " : "", + re_seqno ? "seqno, " : ""); + g_regex_match(info->regex.format, f_content, G_REGEX_MATCH_NOTEMPTY, &match); + while (g_match_info_matches(match)) { + /* parse the data */ + if (!g_match_info_fetch_named_pos(match, "data", &field_start, &field_end)) { + fprintf(stderr, "Warning: could not fetch data on would be packet %d, discarding\n", parsed_packets + 1); + continue; + } + parse_data(f_content + field_start, f_content + field_end, info->regex.encoding); + + /* parse the auxiliary information if present */ + if (re_time && + g_match_info_fetch_named_pos(match, "time", &field_start, &field_end)) { + parse_time(f_content + field_start, f_content + field_end, info->timestamp_format); + } else { + /* No time present, so add a fixed delta. */ + parse_time(NULL, NULL, NULL); + } + + if (re_dir && + g_match_info_fetch_named_pos(match, "dir", &field_start, &field_end)) + parse_dir(f_content + field_start, f_content + field_end, info->regex.in_indication, info->regex.out_indication); + + if (re_seqno && + g_match_info_fetch_named_pos(match, "seqno", &field_start, &field_end)) + parse_seqno(f_content + field_start, f_content + field_end); + + if (ws_log_get_level() == LOG_LEVEL_NOISY) { + g_match_info_fetch_pos(match, 0, &field_start, &field_end); + ws_noisy("Packet %d at %x to %x: %.*s\n", parsed_packets + 1, + field_start, field_end, + field_end - field_start, f_content + field_start); + } + flush_packet(); + + + /* prepare next packet */ + ++parsed_packets; + g_match_info_next(match, &gerror); + if (gerror && gerror->code) { + status = -1; + g_error_free(gerror); + break; + } + } + ws_debug("processed %d packets", parsed_packets); + g_match_info_unref(match); + g_mapped_file_unref(file); + return status * parsed_packets; +} |