diff options
author | j.novak@netsystem.cz <j.novak@netsystem.cz> | 2022-08-29 19:46:59 +0000 |
---|---|---|
committer | Gerald Combs <gerald@wireshark.org> | 2022-08-29 19:46:59 +0000 |
commit | 90143855af7c0c5ffd2ee5374dd7df17a246299c (patch) | |
tree | 4aed92f776e046b528974240360e55e23f82ec47 | |
parent | 621b94a090173706af429a22335eae8ff4f9e86d (diff) |
extcap: Signal processing unified for C based extcaps
-rw-r--r-- | extcap/ciscodump.c | 70 | ||||
-rw-r--r-- | extcap/dpauxmon.c | 22 | ||||
-rw-r--r-- | extcap/extcap-base.c | 55 | ||||
-rw-r--r-- | extcap/extcap-base.h | 8 | ||||
-rw-r--r-- | extcap/udpdump.c | 24 |
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; |