aboutsummaryrefslogtreecommitdiffstats
path: root/extcap
diff options
context:
space:
mode:
authorj.novak@netsystem.cz <j.novak@netsystem.cz>2022-08-29 19:46:59 +0000
committerGerald Combs <gerald@wireshark.org>2022-08-29 19:46:59 +0000
commit90143855af7c0c5ffd2ee5374dd7df17a246299c (patch)
tree4aed92f776e046b528974240360e55e23f82ec47 /extcap
parent621b94a090173706af429a22335eae8ff4f9e86d (diff)
extcap: Signal processing unified for C based extcaps
Diffstat (limited to 'extcap')
-rw-r--r--extcap/ciscodump.c70
-rw-r--r--extcap/dpauxmon.c22
-rw-r--r--extcap/extcap-base.c55
-rw-r--r--extcap/extcap-base.h8
-rw-r--r--extcap/udpdump.c24
5 files changed, 94 insertions, 85 deletions
diff --git a/extcap/ciscodump.c b/extcap/ciscodump.c
index 7f5067d270..5e826f33d7 100644
--- a/extcap/ciscodump.c
+++ b/extcap/ciscodump.c
@@ -105,8 +105,6 @@ enum {
static char prompt_str[SSH_READ_BLOCK_SIZE + 1];
static gint32 prompt_len = -1;
-static gboolean end_application = FALSE;
-
static struct ws_option longopts[] = {
EXTCAP_BASE_OPTIONS,
{ "help", ws_no_argument, NULL, OPT_HELP},
@@ -115,24 +113,6 @@ static struct ws_option longopts[] = {
{ 0, 0, 0, 0}
};
-#ifdef _WIN32
-static BOOL WINAPI
-exit_from_loop(DWORD dwCtrlType _U_)
-#else
-static void exit_from_loop(int signo _U_)
-#endif /* _WIN32 */
-{
-#ifndef _WIN32
- /* Disable signal reception after first signal to avoid signal storms */
- signal(signo, SIG_IGN);
-#endif /* _WIN32 */
- ws_warning("Exiting from main loop");
- end_application = TRUE;
-#ifdef _WIN32
- return TRUE;
-#endif /* _WIN32 */
-}
-
/* Replaces needle with rep in line */
static char* str_replace_char(char *line, char needle, char rep)
{
@@ -315,7 +295,7 @@ static int ssh_channel_read_prompt(ssh_channel channel, char *line, guint32 *len
return READ_PROMPT_ERROR;
}
}
- } while (!end_application && (*len < max_len));
+ } while (!extcap_end_application && (*len < max_len));
line[*len] = '\0';
return READ_PROMPT_TOO_LONG;
@@ -388,7 +368,7 @@ static void ciscodump_cleanup_ios(ssh_channel channel, const char* iface, const
int wscp_cnt = 1;
gchar* wscp_str = NULL;
- end_application = FALSE;
+ extcap_end_application = FALSE;
if (channel) {
ws_debug("Removing configuration...");
read_output_bytes(channel, -1, NULL);
@@ -878,8 +858,8 @@ static int process_buffer_response_ios(ssh_channel channel, guint8* packet, FILE
return FALSE;
}
len = 0;
- ws_debug("loop end detection %d %d %d %d", end_application, loop_end, *processed_packets, count);
- } while ((!end_application) && (!loop_end) && (*processed_packets < count));
+ ws_debug("loop end detection %d %d %d %d", extcap_end_application, loop_end, *processed_packets, count);
+ } while ((!extcap_end_application) && (!loop_end) && (*processed_packets < count));
return TRUE;
}
@@ -934,7 +914,7 @@ static void ssh_loop_read_ios(ssh_channel channel, FILE* fp, const guint32 count
g_free(packet);
return;
}
- } while (!end_application && running && (processed_packets < count));
+ } while (!extcap_end_application && running && (processed_packets < count));
g_free(packet);
@@ -993,8 +973,8 @@ static int process_buffer_response_ios_xe(ssh_channel channel, guint8* packet, F
return FALSE;
}
len = 0;
- ws_debug("loop end detection %d %d %d %d", end_application, loop_end, *processed_packets, count);
- } while ((!end_application) && (!loop_end) && (*processed_packets < count));
+ ws_debug("loop end detection %d %d %d %d", extcap_end_application, loop_end, *processed_packets, count);
+ } while ((!extcap_end_application) && (!loop_end) && (*processed_packets < count));
return TRUE;
}
@@ -1049,7 +1029,7 @@ static void ssh_loop_read_ios_xe(ssh_channel channel, FILE* fp, const guint32 co
g_free(packet);
return;
}
- } while (!end_application && running && (processed_packets < count));
+ } while (!extcap_end_application && running && (processed_packets < count));
g_free(packet);
@@ -1116,9 +1096,9 @@ static int process_buffer_response_asa(ssh_channel channel, guint8* packet, FILE
}
len = 0;
ws_debug("loop end detection1 %d %d", *processed_packets, count);
- } while (!end_application && !loop_end);
- ws_debug("loop end detection2 %d %d %d", end_application, *processed_packets, count);
- } while (!end_application && (*processed_packets < *current_max) && ((*processed_packets < count)));
+ } while (!extcap_end_application && !loop_end);
+ ws_debug("loop end detection2 %d %d %d", extcap_end_application, *processed_packets, count);
+ } while (!extcap_end_application && (*processed_packets < *current_max) && ((*processed_packets < count)));
return TRUE;
}
@@ -1167,7 +1147,7 @@ static void ssh_loop_read_asa(ssh_channel channel, FILE* fp, const guint32 count
g_free(packet);
return;
}
- } while (!end_application && running && (processed_packets < count));
+ } while (!extcap_end_application && running && (processed_packets < count));
g_free(packet);
@@ -1847,27 +1827,6 @@ static int ssh_open_remote_connection(const ssh_params_t* ssh_params, const char
}
}
-#ifdef _WIN32
- if (!SetConsoleCtrlHandler(exit_from_loop, TRUE)) {
- ws_warning("Can't set console handler");
- goto cleanup;
- }
-#else
- /* Catch signals to be able to cleanup config later */
- if (signal(SIGINT, exit_from_loop) == SIG_ERR) {
- ws_warning("Can't set SIGINT signal handler");
- goto cleanup;
- }
- if (signal(SIGTERM, exit_from_loop) == SIG_ERR) {
- ws_warning("Can't set SIGTERM signal handler");
- goto cleanup;
- }
- if (signal(SIGPIPE, exit_from_loop) == SIG_ERR) {
- ws_warning("Can't set SIGPIPE signal handler");
- goto cleanup;
- }
-#endif /* _WIN32 */
-
if (!libpcap_write_file_header(fp, 1, PCAP_SNAPLEN, FALSE, &bytes_written, &err)) {
ws_warning("Can't write pcap file header");
goto cleanup;
@@ -2028,6 +1987,10 @@ int main(int argc, char *argv[])
add_libssh_info(extcap_conf);
g_free(help_url);
extcap_base_register_interface(extcap_conf, CISCODUMP_EXTCAP_INTERFACE, "Cisco remote capture", 147, "Remote capture dependent DLT");
+ if (!extcap_base_register_graceful_shutdown_cb(extcap_conf, NULL)) {
+ ret = EXIT_FAILURE;
+ goto end;
+ }
help_header = ws_strdup_printf(
" %s --extcap-interfaces\n"
@@ -2062,7 +2025,6 @@ int main(int argc, char *argv[])
goto end;
}
- ws_log_set_level(LOG_LEVEL_DEBUG);
while ((result = ws_getopt_long(argc, argv, ":", longopts, &option_idx)) != -1) {
switch (result) {
diff --git a/extcap/dpauxmon.c b/extcap/dpauxmon.c
index b443103cd6..fc68b8b508 100644
--- a/extcap/dpauxmon.c
+++ b/extcap/dpauxmon.c
@@ -29,7 +29,6 @@
#include <netlink/genl/ctrl.h>
#include <netlink/genl/mngt.h>
-#include <signal.h>
#include <errno.h>
#include <linux/genetlink.h>
@@ -43,7 +42,6 @@
#define DPAUXMON_VERSION_MINOR "1"
#define DPAUXMON_VERSION_RELEASE "0"
-static gboolean run_loop = TRUE;
FILE* pcap_fp = NULL;
enum {
@@ -97,11 +95,6 @@ static int list_config(char *interface)
return EXIT_SUCCESS;
}
-static void exit_from_loop(int signo _U_)
-{
- run_loop = FALSE;
-}
-
static int setup_dumpfile(const char* fifo, FILE** fp)
{
guint64 bytes_written = 0;
@@ -357,7 +350,7 @@ static int handle_data(struct nl_cache_ops *unused _U_, struct genl_cmd *cmd _U_
memcpy(&packet[2], data, data_size);
if (dump_packet(pcap_fp, packet, data_size + 2, ts) == EXIT_FAILURE)
- run_loop = FALSE;
+ extcap_end_application = FALSE;
return NL_OK;
}
@@ -407,14 +400,8 @@ static void run_listener(const char* fifo, unsigned int interface_id)
{
int err;
int grp;
- struct sigaction int_handler = { .sa_handler = exit_from_loop };
struct nl_cb *socket_cb;
- if (sigaction(SIGINT, &int_handler, 0)) {
- ws_warning("Can't set signal handler");
- return;
- }
-
if (setup_dumpfile(fifo, &pcap_fp) == EXIT_FAILURE) {
if (pcap_fp)
goto close_out;
@@ -469,7 +456,7 @@ static void run_listener(const char* fifo, unsigned int interface_id)
ws_debug("DisplayPort AUX monitor running on interface %u", interface_id);
- while(run_loop == TRUE) {
+ while(!extcap_end_application) {
if ((err = nl_recvmsgs_default(sock)) < 0)
ws_warning("Unable to receive message: %s", nl_geterror(err));
}
@@ -581,6 +568,11 @@ int main(int argc, char *argv[])
goto end;
}
+ if (!extcap_base_register_graceful_shutdown_cb(extcap_conf, NULL)) {
+ ret = EXIT_SUCCESS;
+ goto end;
+ }
+
if (extcap_conf->show_config) {
ret = list_config(extcap_conf->interface);
goto end;
diff --git a/extcap/extcap-base.c b/extcap/extcap-base.c
index 2a1cb7c1f6..bb4615d47b 100644
--- a/extcap/extcap-base.c
+++ b/extcap/extcap-base.c
@@ -46,8 +46,31 @@ typedef struct _extcap_option {
static FILE *custom_log = NULL;
+/* used to inform to extcap application that end of application is requested */
+gboolean extcap_end_application = FALSE;
+/* graceful shutdown callback, can be null */
+void (*extcap_graceful_shutdown_cb)(void) = NULL;
+
static void extcap_init_log_file(const char *filename);
+/* Called from signals */
+#ifdef _WIN32
+static BOOL WINAPI
+extcap_exit_from_loop(DWORD dwCtrlType _U_)
+#else
+static void extcap_exit_from_loop(int signo _U_)
+#endif /* _WIN32 */
+{
+ ws_debug("Exiting from main loop by signal");
+ extcap_end_application = TRUE;
+ if (extcap_graceful_shutdown_cb != NULL) {
+ extcap_graceful_shutdown_cb();
+ }
+#ifdef _WIN32
+ return TRUE;
+#endif /* _WIN32 */
+}
+
void extcap_base_register_interface(extcap_parameters * extcap, const char * interface, const char * ifdescription, uint16_t dlt, const char * dltdescription )
{
extcap_base_register_interface_ext(extcap, interface, ifdescription, dlt, NULL, dltdescription );
@@ -73,6 +96,38 @@ void extcap_base_register_interface_ext(extcap_parameters * extcap,
extcap->interfaces = g_list_append(extcap->interfaces, (gpointer) iface);
}
+gboolean extcap_base_register_graceful_shutdown_cb(extcap_parameters * extcap _U_, void (*callback)(void))
+{
+#ifndef _WIN32
+ struct sigaction sig_handler = { .sa_handler = extcap_exit_from_loop };
+#endif
+
+ extcap_end_application = FALSE;
+ extcap_graceful_shutdown_cb = callback;
+#ifdef _WIN32
+ if (!SetConsoleCtrlHandler(extcap_exit_from_loop, TRUE)) {
+ ws_warning("Can't set console handler");
+ return FALSE;
+ }
+#else
+ /* Catch signals to be able to cleanup config later */
+ if (sigaction(SIGINT, &sig_handler, NULL)) {
+ ws_warning("Can't set SIGINT signal handler");
+ return FALSE;
+ }
+ if (sigaction(SIGTERM, &sig_handler, NULL)) {
+ ws_warning("Can't set SIGTERM signal handler");
+ return FALSE;
+ }
+ if (sigaction(SIGPIPE, &sig_handler, NULL)) {
+ ws_warning("Can't set SIGPIPE signal handler");
+ return FALSE;
+ }
+#endif /* _WIN32 */
+
+ return TRUE;
+}
+
void extcap_base_set_util_info(extcap_parameters * extcap, const char * exename, const char * major,
const char * minor, const char * release, const char * helppage)
{
diff --git a/extcap/extcap-base.h b/extcap/extcap-base.h
index b3b23e1f50..567a691770 100644
--- a/extcap/extcap-base.h
+++ b/extcap/extcap-base.h
@@ -79,8 +79,16 @@ typedef struct _extcap_parameters
gboolean debug;
} extcap_parameters;
+/* used to inform to extcap application that end of application is requested */
+extern gboolean extcap_end_application;
+
void extcap_base_register_interface(extcap_parameters * extcap, const char * interface, const char * ifdescription, uint16_t dlt, const char * dltdescription );
void extcap_base_register_interface_ext(extcap_parameters * extcap, const char * interface, const char * ifdescription, uint16_t dlt, const char * dltname, const char * dltdescription );
+
+/* used to inform extcap framework that graceful shutdown supported by the extcap
+ */
+gboolean extcap_base_register_graceful_shutdown_cb(extcap_parameters * extcap, void (*callback)(void));
+
void extcap_base_set_util_info(extcap_parameters * extcap, const char * exename, const char * major, const char * minor, const char * release, const char * helppage);
void extcap_base_set_compiled_with(extcap_parameters * extcap, const char *fmt, ...);
void extcap_base_set_running_with(extcap_parameters * extcap, const char *fmt, ...);
diff --git a/extcap/udpdump.c b/extcap/udpdump.c
index 39eb737beb..18d79dd4d9 100644
--- a/extcap/udpdump.c
+++ b/extcap/udpdump.c
@@ -62,8 +62,6 @@
#define UDPDUMP_EXPORT_HEADER_LEN 40
-static gboolean run_loop = TRUE;
-
enum {
EXTCAP_BASE_OPTIONS_ENUM,
OPT_HELP,
@@ -150,12 +148,6 @@ cleanup_setup_listener:
}
-static void exit_from_loop(int signo _U_)
-{
- ws_warning("Exiting from main loop");
- run_loop = FALSE;
-}
-
static int setup_dumpfile(const char* fifo, FILE** fp)
{
guint64 bytes_written = 0;
@@ -289,11 +281,6 @@ static void run_listener(const char* fifo, const guint16 port, const char* proto
ssize_t buflen;
FILE* fp = NULL;
- if (signal(SIGINT, exit_from_loop) == SIG_ERR) {
- ws_warning("Can't set signal handler");
- return;
- }
-
if (setup_dumpfile(fifo, &fp) == EXIT_FAILURE) {
if (fp)
fclose(fp);
@@ -306,7 +293,7 @@ static void run_listener(const char* fifo, const guint16 port, const char* proto
ws_debug("Listener running on port %u", port);
buf = (char*)g_malloc(PKT_BUF_SIZE);
- while(run_loop == TRUE) {
+ while(!extcap_end_application) {
memset(buf, 0x0, PKT_BUF_SIZE);
buflen = recvfrom(sock, buf, PKT_BUF_SIZE, 0, (struct sockaddr *)&clientaddr, &clientlen);
@@ -330,12 +317,12 @@ static void run_listener(const char* fifo, const guint16 port, const char* proto
#else
ws_warning("Error in recvfrom: %s (errno=%d)", strerror(errno), errno);
#endif
- run_loop = FALSE;
+ extcap_end_application = FALSE;
break;
}
} else {
if (dump_packet(proto_name, port, buf, buflen, clientaddr, fp) == EXIT_FAILURE)
- run_loop = FALSE;
+ extcap_end_application = FALSE;
}
}
@@ -453,6 +440,11 @@ int main(int argc, char *argv[])
goto end;
}
+ if (!extcap_base_register_graceful_shutdown_cb(extcap_conf, NULL)) {
+ ret = EXIT_SUCCESS;
+ goto end;
+ }
+
if (extcap_conf->show_config) {
ret = list_config(extcap_conf->interface);
goto end;