extcap: Signal processing unified for C based extcaps

pespin/osmux-wip
j.novak@netsystem.cz 2022-08-29 19:46:59 +00:00 committed by Gerald Combs
parent 621b94a090
commit 90143855af
5 changed files with 94 additions and 85 deletions

View File

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

View File

@ -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;

View File

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

View File

@ -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, ...);

View File

@ -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;