dumpcap: Make capture child logging work

Distinguish log messages from SP_ERROR_MSG; log messages don't
necessarily represent a failure, and they have a level. This
doesn't affect logging while capturing much, as SP_ERROR_MSGs
are just printed to the console, but it makes it possible to log
while retrieving interface information or the stats, where SP_ERROR_MSG
indicates that the command failed.
This commit is contained in:
John Thacker 2023-12-31 16:38:37 -05:00
parent 2bf14f5fe6
commit 3fbefe9c36
3 changed files with 63 additions and 22 deletions

View File

@ -218,6 +218,23 @@ sync_pipe_add_arg(char **args, int *argc, const char *arg)
return args;
}
/* Take a buffer from an SP_LOG_MSG from dumpcap and send it to our
* current logger. Keep this in sync with the format used in
* dumpcap_log_writer. (We might want to do more proper serialization
* of more than just the log level.)
*/
static void
sync_pipe_handle_log_msg(const char *buffer) {
const char *log_msg = NULL;
const char* end;
uint32_t level = 0;
if (ws_strtou32(buffer, &end, &level) && end[0] == ':') {
log_msg = end + 1;
}
ws_log(LOG_DOMAIN_CAPCHILD, level, "%s", log_msg);
}
/* Initialize an argument list and add dumpcap to it. */
static char **
init_pipe_args(int *argc) {
@ -1140,6 +1157,13 @@ sync_pipe_run_command_actual(char **argv, char **data, char **primary_msg,
*data = NULL;
break;
case SP_LOG_MSG:
/*
* Log from dumpcap; pass to our log
*/
sync_pipe_handle_log_msg(buffer);
break;
case SP_SUCCESS:
/* read the output from the command */
data_buf = g_string_new("");
@ -1566,6 +1590,13 @@ sync_interface_stats_open(int *data_read_fd, ws_process_id *fork_child, char **d
}
return ret;
case SP_LOG_MSG:
/*
* Log from dumpcap; pass to our log
*/
sync_pipe_handle_log_msg(buffer);
break;
case SP_IFACE_LIST:
/*
* Dumpcap giving us the interface list
@ -1910,6 +1941,12 @@ sync_pipe_input_cb(GIOChannel *pipe_io, capture_session *cap_session)
/* the capture child will close the sync_pipe, nothing to do for now */
/* (an error message doesn't mean we have to stop capturing) */
break;
case SP_LOG_MSG:
/*
* Log from dumpcap; pass to our log
*/
sync_pipe_handle_log_msg(buffer);
break;
case SP_BAD_FILTER: {
const char *message=NULL;
uint32_t indx = 0;

View File

@ -5980,18 +5980,36 @@ dumpcap_log_writer(const char *domain, enum ws_log_level level,
const char *user_format, va_list user_ap,
void *user_data _U_)
{
/* DEBUG & INFO msgs (if we're debugging today) */
#if defined(DEBUG_DUMPCAP) || defined(DEBUG_CHILD_DUMPCAP)
if (level <= LOG_LEVEL_INFO && ws_log_msg_is_active(domain, level)) {
#ifdef DEBUG_DUMPCAP
if (ws_log_msg_is_active(domain, level)) {
/* log messages go to stderr or */
/* to parent especially formatted if dumpcap running as child. */
#ifdef DEBUG_CHILD_DUMPCAP
va_list user_ap_copy;
va_copy(user_ap_copy, user_ap);
#endif
if (capture_child) {
gchar *msg = ws_strdup_vprintf(user_format, user_ap);
sync_pipe_write_errmsgs_to_parent(sync_pipe_fd, msg, "");
g_free(msg);
/* Format the log mesage as the numeric level, followed
* by a colon and then a string matching the standard log
* string. In the future perhaps we serialize file, line,
* and func (which can be NULL) instead.
*/
GString *msg = g_string_new(NULL);
g_string_append_printf(msg, "%u:", level);
if (file != NULL) {
g_string_append_printf(msg, "%s", file);
if (line >= 0) {
g_string_append_printf(msg, ":%ld", line);
}
}
g_string_append(msg, " --");
if (func != NULL) {
g_string_append_printf(msg, " %s():", func);
}
g_string_append_c(msg, ' ');
g_string_append_vprintf(msg, user_format, user_ap);
sync_pipe_write_string_msg(sync_pipe_fd, SP_LOG_MSG, msg->str);
g_string_free(msg, TRUE);
} else {
ws_log_console_writer(domain, level, file, line, func, mft, user_format, user_ap);
}
@ -5999,21 +6017,6 @@ dumpcap_log_writer(const char *domain, enum ws_log_level level,
ws_log_file_writer(debug_log, domain, level, file, line, func, mft, user_format, user_ap_copy);
va_end(user_ap_copy);
#endif
#elif defined(DEBUG_CHILD_DUMPCAP)
ws_log_file_writer(debug_log, domain, level, file, line, func, mft, user_format, user_ap);
#endif
return;
}
#endif
/* ERROR, CRITICAL, WARNING, MESSAGE messages goto stderr or */
/* to parent especially formatted if dumpcap running as child. */
if (capture_child) {
gchar *msg = ws_strdup_vprintf(user_format, user_ap);
sync_pipe_write_errmsgs_to_parent(sync_pipe_fd, msg, "");
g_free(msg);
} else if(ws_log_msg_is_active(domain, level)) {
ws_log_console_writer(domain, level, file, line, func, mft, user_format, user_ap);
}
}

View File

@ -42,6 +42,7 @@
#define SP_EXEC_FAILED 'X' /* errno value for the exec failing */
#define SP_FILE 'F' /* the name of the recently opened file */
#define SP_ERROR_MSG 'E' /* error message */
#define SP_LOG_MSG 'L' /* log message */
#define SP_BAD_FILTER 'B' /* error message for bad capture filter */
#define SP_PACKET_COUNT 'P' /* count of packets captured since last message */
#define SP_DROPS 'D' /* count of packets dropped in capture */