forked from osmocom/wireshark
extcap: Signal processing unified for C based extcaps
parent
621b94a090
commit
90143855af
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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, ...);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue