mirror of https://github.com/OISF/suricata
Implementation of the logging module
parent
f658ffbc9c
commit
157d5e8113
@ -0,0 +1,983 @@
|
||||
/** Copyright (c) 2009 Open Information Security Foundation.
|
||||
* \author Anoop Saldanha <poonaatsoc@gmail.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include "util-debug-filters.h"
|
||||
#include "util-error.h"
|
||||
#include "util-enum.h"
|
||||
#include "threads.h"
|
||||
|
||||
/* both of these are defined in util-debug.c */
|
||||
extern int sc_log_module_initialized;
|
||||
extern int sc_log_module_cleaned;
|
||||
|
||||
/**
|
||||
* \brief Holds the fine-grained filters
|
||||
*/
|
||||
static SCLogFGFilterFile *sc_log_fg_filters[SC_LOG_FILTER_MAX] = { NULL, NULL };
|
||||
|
||||
/**
|
||||
* \brief Mutex for accessing the fine-grained fiters sc_log_fg_filters
|
||||
*/
|
||||
static pthread_mutex_t sc_log_fg_filters_m[SC_LOG_FILTER_MAX] = { PTHREAD_MUTEX_INITIALIZER,
|
||||
PTHREAD_MUTEX_INITIALIZER };
|
||||
|
||||
/**
|
||||
* \brief Holds the function-dependent filters
|
||||
*/
|
||||
static SCLogFDFilter *sc_log_fd_filters = NULL;
|
||||
|
||||
/**
|
||||
* \brief Mutex for accessing the function-dependent filters sc_log_fd_filters
|
||||
*/
|
||||
static pthread_mutex_t sc_log_fd_filters_m = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/**
|
||||
* \brief Holds the thread_list required by function-dependent filters
|
||||
*/
|
||||
static SCLogFDFilterThreadList *sc_log_fd_filters_tl = NULL;
|
||||
|
||||
/**
|
||||
* \brief Mutex for accessing the FD thread_list sc_log_fd_filters_tl
|
||||
*/
|
||||
static pthread_mutex_t sc_log_fd_filters_tl_m = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Helper function used internally to add a FG filter. This function is
|
||||
* called when the file component of the incoming filter has no entry
|
||||
* in the filter list.
|
||||
*
|
||||
* \param fgf_file The file component(basically the position in the list) from
|
||||
* the filter list, after which the new filter has to be added
|
||||
* \param file File_name of the filter
|
||||
* \param function Function_name of the filter
|
||||
* \param line Line number of the filter
|
||||
* \param listtype The filter listtype. Can be either a blacklist or whitelist
|
||||
* filter listtype(SC_LOG_FILTER_BL or SC_LOG_FILTER_WL)
|
||||
*/
|
||||
static inline void SCLogAddToFGFFileList(SCLogFGFilterFile *fgf_file,
|
||||
const char *file,
|
||||
const char *function, int line,
|
||||
int listtype)
|
||||
{
|
||||
SCLogFGFilterFile *fgf_file_temp = NULL;
|
||||
SCLogFGFilterFunc *fgf_func_temp = NULL;
|
||||
SCLogFGFilterLine *fgf_line_temp = NULL;
|
||||
|
||||
if ( (fgf_file_temp = malloc(sizeof(SCLogFGFilterFile))) == NULL) {
|
||||
printf("Error Allocating memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memset(fgf_file_temp, 0, sizeof(SCLogFGFilterFile));
|
||||
|
||||
if ( file != NULL && (fgf_file_temp->file = strdup(file)) == NULL) {
|
||||
printf("Error Allocating memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if ( (fgf_func_temp = malloc(sizeof(SCLogFGFilterFunc))) == NULL) {
|
||||
printf("Error Allocating memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memset(fgf_func_temp, 0, sizeof(SCLogFGFilterFunc));
|
||||
|
||||
if ( function != NULL && (fgf_func_temp->func = strdup(function)) == NULL) {
|
||||
printf("Error Allocating memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if ( (fgf_line_temp = malloc(sizeof(SCLogFGFilterLine))) == NULL) {
|
||||
printf("Error Allocating memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memset(fgf_line_temp, 0, sizeof(SCLogFGFilterLine));
|
||||
|
||||
fgf_line_temp->line = line;
|
||||
|
||||
/* add to the lists */
|
||||
fgf_func_temp->line = fgf_line_temp;
|
||||
|
||||
fgf_file_temp->func = fgf_func_temp;
|
||||
|
||||
if (fgf_file == NULL)
|
||||
sc_log_fg_filters[listtype] = fgf_file_temp;
|
||||
else
|
||||
fgf_file->next = fgf_file_temp;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Helper function used internally to add a FG filter. This function is
|
||||
* called when the file component of the incoming filter has an entry
|
||||
* in the filter list, but the function component doesn't have an entry
|
||||
* for the corresponding file component
|
||||
*
|
||||
* \param fgf_file The file component from the filter list to which the new
|
||||
* filter has to be added
|
||||
* \param fgf_func The function component(basically the position in the list),
|
||||
* from the filter list, after which the new filter has to be
|
||||
* added
|
||||
* \param function Function_name of the filter
|
||||
* \param line Line number of the filter
|
||||
*/
|
||||
static inline void SCLogAddToFGFFuncList(SCLogFGFilterFile *fgf_file,
|
||||
SCLogFGFilterFunc *fgf_func,
|
||||
const char *function, int line)
|
||||
{
|
||||
SCLogFGFilterFunc *fgf_func_temp = NULL;
|
||||
SCLogFGFilterLine *fgf_line_temp = NULL;
|
||||
|
||||
if ( (fgf_func_temp = malloc(sizeof(SCLogFGFilterFunc))) == NULL) {
|
||||
printf("Error Allocating memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memset(fgf_func_temp, 0, sizeof(SCLogFGFilterFunc));
|
||||
|
||||
if ( function != NULL && (fgf_func_temp->func = strdup(function)) == NULL) {
|
||||
printf("Error Allocating memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if ( (fgf_line_temp = malloc(sizeof(SCLogFGFilterLine))) == NULL) {
|
||||
printf("Error Allocating memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memset(fgf_line_temp, 0, sizeof(SCLogFGFilterLine));
|
||||
|
||||
fgf_line_temp->line = line;
|
||||
|
||||
/* add to the lists */
|
||||
fgf_func_temp->line = fgf_line_temp;
|
||||
|
||||
if (fgf_func == NULL)
|
||||
fgf_file->func = fgf_func_temp;
|
||||
else
|
||||
fgf_func->next = fgf_func_temp;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Helper function used internally to add a FG filter. This function is
|
||||
* called when the file and function components of the incoming filter
|
||||
* have an entry in the filter list, but the line component doesn't have
|
||||
* an entry for the corresponding function component
|
||||
*
|
||||
* \param fgf_func The function component from the filter list to which the new
|
||||
* filter has to be added
|
||||
* \param fgf_line The function component(basically the position in the list),
|
||||
* from the filter list, after which the new filter has to be
|
||||
* added
|
||||
* \param line Line number of the filter
|
||||
*/
|
||||
static inline void SCLogAddToFGFLineList(SCLogFGFilterFunc *fgf_func,
|
||||
SCLogFGFilterLine *fgf_line,
|
||||
int line)
|
||||
{
|
||||
SCLogFGFilterLine *fgf_line_temp = NULL;
|
||||
|
||||
if ( (fgf_line_temp = malloc(sizeof(SCLogFGFilterLine))) == NULL) {
|
||||
printf("Error Allocating memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memset(fgf_line_temp, 0, sizeof(SCLogFGFilterLine));
|
||||
|
||||
fgf_line_temp->line = line;
|
||||
|
||||
/* add to the lists */
|
||||
if (fgf_line == NULL)
|
||||
fgf_func->line = fgf_line_temp;
|
||||
else
|
||||
fgf_line->next = fgf_line_temp;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Helper function used internally to add a FG filter
|
||||
*
|
||||
* \param file File_name of the filter
|
||||
* \param function Function_name of the filter
|
||||
* \param line Line number of the filter
|
||||
* \param listtype The filter listtype. Can be either a blacklist or whitelist
|
||||
* filter listtype(SC_LOG_FILTER_BL or SC_LOG_FILTER_WL)
|
||||
*
|
||||
* \retval 0 on successfully adding the filter;
|
||||
* \retval -1 on failure
|
||||
*/
|
||||
static inline int SCLogAddFGFilter(const char *file, const char *function,
|
||||
int line, int listtype)
|
||||
{
|
||||
SCLogFGFilterFile *fgf_file = NULL;
|
||||
SCLogFGFilterFile *prev_fgf_file = NULL;
|
||||
|
||||
SCLogFGFilterFunc *fgf_func = NULL;
|
||||
SCLogFGFilterFunc *prev_fgf_func = NULL;
|
||||
|
||||
SCLogFGFilterLine *fgf_line = NULL;
|
||||
SCLogFGFilterLine *prev_fgf_line = NULL;
|
||||
|
||||
int found = 0;
|
||||
|
||||
if (sc_log_module_initialized != 1) {
|
||||
printf("Logging module not initialized. Call SCLogInitLogModule() "
|
||||
"first before using the debug API\n");
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
if (file == NULL && function == NULL && line < 0) {
|
||||
printf("Error: Invalid arguments supplied to SCLogAddFGFilter\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mutex_lock(&sc_log_fg_filters_m[listtype]);
|
||||
fgf_file = sc_log_fg_filters[listtype];
|
||||
|
||||
prev_fgf_file = fgf_file;
|
||||
while (fgf_file != NULL) {
|
||||
prev_fgf_file = fgf_file;
|
||||
if (file == NULL && fgf_file->file == NULL)
|
||||
found = 1;
|
||||
else if (file != NULL && fgf_file->file != NULL)
|
||||
found = (strcmp(file, fgf_file->file) == 0);
|
||||
else
|
||||
found = 0;
|
||||
|
||||
if (found == 1)
|
||||
break;
|
||||
|
||||
fgf_file = fgf_file->next;
|
||||
}
|
||||
|
||||
if (found == 0) {
|
||||
SCLogAddToFGFFileList(prev_fgf_file, file, function, line, listtype);
|
||||
goto done;
|
||||
}
|
||||
|
||||
found = 0;
|
||||
fgf_func = fgf_file->func;
|
||||
prev_fgf_func = fgf_func;
|
||||
while (fgf_func != NULL) {
|
||||
prev_fgf_func = fgf_func;
|
||||
if (function == NULL && fgf_func->func == NULL)
|
||||
found = 1;
|
||||
else if (function != NULL && fgf_func->func != NULL)
|
||||
found = (strcmp(function, fgf_func->func) == 0);
|
||||
else
|
||||
found = 0;
|
||||
|
||||
if (found == 1)
|
||||
break;
|
||||
|
||||
fgf_func = fgf_func->next;
|
||||
}
|
||||
|
||||
if (found == 0) {
|
||||
SCLogAddToFGFFuncList(fgf_file, prev_fgf_func, function, line);
|
||||
goto done;
|
||||
}
|
||||
|
||||
found = 0;
|
||||
fgf_line = fgf_func->line;
|
||||
prev_fgf_line = fgf_line;
|
||||
while(fgf_line != NULL) {
|
||||
prev_fgf_line = fgf_line;
|
||||
if (line == fgf_line->line) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
fgf_line = fgf_line->next;
|
||||
}
|
||||
|
||||
if (found == 0) {
|
||||
SCLogAddToFGFLineList(fgf_func, prev_fgf_line, line);
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
mutex_unlock(&sc_log_fg_filters_m[listtype]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Internal function used to check for matches against registered FG
|
||||
* filters. Checks if there is a match for the incoming log_message with
|
||||
* any of the FG filters. Based on whether the filter type is whitelist
|
||||
* or blacklist, the function allows the message to be logged or not.
|
||||
*
|
||||
* \param file File_name from where the log_message originated
|
||||
* \param function Function_name from where the log_message originated
|
||||
* \param line Line number from where the log_message originated
|
||||
* \param listtype The filter listtype. Can be either a blacklist or whitelist
|
||||
* filter listtype(SC_LOG_FILTER_BL or SC_LOG_FILTER_WL)
|
||||
*
|
||||
* \retval 1 if there is a match
|
||||
* \retval 0 on no match
|
||||
* \retval -1 on failure
|
||||
*/
|
||||
static int SCLogMatchFGFilter(const char *file, const char *function, int line,
|
||||
int listtype)
|
||||
{
|
||||
SCLogFGFilterFile *fgf_file = NULL;
|
||||
SCLogFGFilterFunc *fgf_func = NULL;
|
||||
SCLogFGFilterLine *fgf_line = NULL;
|
||||
int match = 1;
|
||||
|
||||
if (sc_log_module_initialized != 1) {
|
||||
printf("Logging module not initialized. Call SCLogInitLogModule() "
|
||||
"first before using the debug API\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mutex_lock(&sc_log_fg_filters_m[listtype]);
|
||||
|
||||
fgf_file = sc_log_fg_filters[listtype];
|
||||
|
||||
if (fgf_file == NULL) {
|
||||
mutex_unlock(&sc_log_fg_filters_m[listtype]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while(fgf_file != NULL) {
|
||||
match = 1;
|
||||
|
||||
match &= (fgf_file->file != NULL)? !strcmp(file, fgf_file->file): 1;
|
||||
|
||||
if (match == 0) {
|
||||
fgf_file = fgf_file->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
fgf_func = fgf_file->func;
|
||||
while (fgf_func != NULL) {
|
||||
match = 1;
|
||||
|
||||
match &= (fgf_func->func != NULL)? !strcmp(function, fgf_func->func): 1;
|
||||
|
||||
if (match == 0) {
|
||||
fgf_func = fgf_func->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
fgf_line = fgf_func->line;
|
||||
while (fgf_line != NULL) {
|
||||
match = 1;
|
||||
|
||||
match &= (fgf_line->line != -1)? (line == fgf_line->line): 1;
|
||||
|
||||
if (match == 1)
|
||||
break;
|
||||
|
||||
fgf_line = fgf_line->next;
|
||||
}
|
||||
|
||||
if (match == 1)
|
||||
break;
|
||||
|
||||
fgf_func = fgf_func->next;
|
||||
}
|
||||
|
||||
if (match == 1) {
|
||||
mutex_unlock(&sc_log_fg_filters_m[listtype]);
|
||||
if (listtype == SC_LOG_FILTER_WL)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
fgf_file = fgf_file->next;
|
||||
}
|
||||
|
||||
mutex_unlock(&sc_log_fg_filters_m[listtype]);
|
||||
|
||||
if (listtype == SC_LOG_FILTER_WL)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Checks if there is a match for the incoming log_message with any
|
||||
* of the FG filters. If there is a match, it allows the message
|
||||
* to be logged, else it rejects that message.
|
||||
*
|
||||
* \param file File_name from where the log_message originated
|
||||
* \param function Function_name from where the log_message originated
|
||||
* \param line Line number from where the log_message originated
|
||||
*
|
||||
* \retval 1 if there is a match
|
||||
* \retval 0 on no match
|
||||
* \retval -1 on failure
|
||||
*/
|
||||
int SCLogMatchFGFilterWL(const char *file, const char *function, int line)
|
||||
{
|
||||
return SCLogMatchFGFilter(file, function, line, SC_LOG_FILTER_WL);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Checks if there is a match for the incoming log_message with any
|
||||
* of the FG filters. If there is a match it rejects the logging
|
||||
* for that messages, else it allows that message to be logged
|
||||
*
|
||||
* \praram file File_name from where the log_message originated
|
||||
* \param function Function_name from where the log_message originated
|
||||
* \param line Line number from where the log_message originated
|
||||
*
|
||||
* \retval 1 if there is a match
|
||||
* \retval 0 on no match
|
||||
* \retval -1 on failure
|
||||
*/
|
||||
int SCLogMatchFGFilterBL(const char *file, const char *function, int line)
|
||||
{
|
||||
return SCLogMatchFGFilter(file, function, line, SC_LOG_FILTER_BL);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Adds a Whitelist(WL) fine-grained(FG) filter. A FG filter WL filter
|
||||
* allows messages that match this filter, to be logged, while the filter
|
||||
* is defined using a file_name, function_name and line_number.
|
||||
*
|
||||
* If a particular paramter in the fg-filter(file, function and line),
|
||||
* shouldn't be considered while logging the message, one can supply
|
||||
* NULL for the file_name or function_name and a negative line_no.
|
||||
*
|
||||
* \param file File_name of the filter
|
||||
* \param function Function_name of the filter
|
||||
* \param line Line number of the filter
|
||||
*
|
||||
* \retval 0 on successfully adding the filter;
|
||||
* \retval -1 on failure
|
||||
*/
|
||||
int SCLogAddFGFilterWL(const char *file, const char *function, int line)
|
||||
{
|
||||
return SCLogAddFGFilter(file, function, line, SC_LOG_FILTER_WL);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Adds a Blacklist(BL) fine-grained(FG) filter. A FG filter BL filter
|
||||
* allows messages that don't match this filter, to be logged, while the
|
||||
* filter is defined using a file_name, function_name and line_number
|
||||
*
|
||||
* If a particular paramter in the fg-filter(file, function and line),
|
||||
* shouldn't be considered while logging the message, one can supply
|
||||
* NULL for the file_name or function_name and a negative line_no.
|
||||
*
|
||||
* \param file File_name of the filter
|
||||
* \param function Function_name of the filter
|
||||
* \param line Line number of the filter
|
||||
*
|
||||
* \retval 0 on successfully adding the filter
|
||||
* \retval -1 on failure
|
||||
*/
|
||||
int SCLogAddFGFilterBL(const char *file, const char *function, int line)
|
||||
{
|
||||
return SCLogAddFGFilter(file, function, line, SC_LOG_FILTER_BL);
|
||||
}
|
||||
|
||||
void SCLogReleaseFGFilters(void)
|
||||
{
|
||||
SCLogFGFilterFile *fgf_file = NULL;
|
||||
SCLogFGFilterFunc *fgf_func = NULL;
|
||||
SCLogFGFilterLine *fgf_line = NULL;
|
||||
|
||||
void *temp = NULL;
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < SC_LOG_FILTER_MAX; i++) {
|
||||
mutex_lock(&sc_log_fg_filters_m[i]);
|
||||
|
||||
fgf_file = sc_log_fg_filters[i];
|
||||
while (fgf_file != NULL) {
|
||||
|
||||
fgf_func = fgf_file->func;
|
||||
while (fgf_func != NULL) {
|
||||
|
||||
fgf_line = fgf_func->line;
|
||||
while(fgf_line != NULL) {
|
||||
temp = fgf_line;
|
||||
fgf_line = fgf_line->next;
|
||||
free(temp);
|
||||
}
|
||||
|
||||
if (fgf_func->func != NULL)
|
||||
free(fgf_func->func);
|
||||
temp = fgf_func;
|
||||
fgf_func = fgf_func->next;
|
||||
free(temp);
|
||||
}
|
||||
|
||||
if (fgf_file->file != NULL)
|
||||
free(fgf_file->file);
|
||||
temp = fgf_file;
|
||||
fgf_file = fgf_file->next;
|
||||
free(temp);
|
||||
}
|
||||
|
||||
mutex_unlock(&sc_log_fg_filters_m[i]);
|
||||
sc_log_fg_filters[i] = NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Prints the FG filters(both WL and BL). Used for debugging purposes.
|
||||
*
|
||||
* \retval count The no of FG filters
|
||||
*/
|
||||
int SCLogPrintFGFilters()
|
||||
{
|
||||
SCLogFGFilterFile *fgf_file = NULL;
|
||||
SCLogFGFilterFunc *fgf_func = NULL;
|
||||
SCLogFGFilterLine *fgf_line = NULL;
|
||||
|
||||
int count = 0;
|
||||
int i = 0;
|
||||
|
||||
if (sc_log_module_initialized != 1) {
|
||||
printf("Logging module not initialized. Call SCLogInitLogModule() "
|
||||
"first before using the debug API\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Fine grained filters:\n");
|
||||
#endif
|
||||
|
||||
for (i = 0; i < SC_LOG_FILTER_MAX; i++) {
|
||||
mutex_lock(&sc_log_fg_filters_m[i]);
|
||||
|
||||
fgf_file = sc_log_fg_filters[i];
|
||||
while (fgf_file != NULL) {
|
||||
|
||||
fgf_func = fgf_file->func;
|
||||
while (fgf_func != NULL) {
|
||||
|
||||
fgf_line = fgf_func->line;
|
||||
while(fgf_line != NULL) {
|
||||
#ifdef DEBUG
|
||||
printf("%s - ", fgf_file->file);
|
||||
printf("%s - ", fgf_func->func);
|
||||
printf("%d\n", fgf_line->line);
|
||||
#endif
|
||||
|
||||
count++;
|
||||
|
||||
fgf_line = fgf_line->next;
|
||||
}
|
||||
|
||||
fgf_func = fgf_func->next;
|
||||
}
|
||||
|
||||
fgf_file = fgf_file->next;
|
||||
}
|
||||
mutex_unlock(&sc_log_fg_filters_m[i]);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* --------------------------------------------------|--------------------------
|
||||
* -------------------------- Code for the FD Filter |--------------------------
|
||||
* --------------------------------------------------V--------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Releases the memory alloted to a FD filter
|
||||
*
|
||||
* \param Pointer to the FD filter that has to be freed
|
||||
*/
|
||||
static inline void SCLogReleaseFDFilter(SCLogFDFilter *fdf)
|
||||
{
|
||||
if (fdf != NULL) {
|
||||
if (fdf->func != NULL)
|
||||
free(fdf->func);
|
||||
free(fdf);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Checks if there is a match for the incoming log_message with any
|
||||
* of the FD filters
|
||||
*
|
||||
* \param function Function_name from where the log_message originated
|
||||
*
|
||||
* \retval 1 if there is a match
|
||||
* \retval 0 on no match;
|
||||
*/
|
||||
int SCLogMatchFDFilter(const char *function)
|
||||
{
|
||||
SCLogFDFilterThreadList *thread_list = NULL;
|
||||
|
||||
pthread_t self = syscall(SYS_gettid);
|
||||
|
||||
#ifndef DEBUG
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
if (sc_log_module_initialized != 1) {
|
||||
printf("Logging module not initialized. Call SCLogInitLogModule() "
|
||||
"first before using the debug API\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_lock(&sc_log_fd_filters_tl_m);
|
||||
|
||||
if (sc_log_fd_filters_tl == NULL) {
|
||||
mutex_unlock(&sc_log_fd_filters_tl_m);
|
||||
if (sc_log_fd_filters != NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
thread_list = sc_log_fd_filters_tl;
|
||||
while (thread_list != NULL) {
|
||||
if (self == thread_list->t) {
|
||||
if (thread_list->entered > 0) {
|
||||
mutex_unlock(&sc_log_fd_filters_tl_m);
|
||||
return 1;
|
||||
}
|
||||
mutex_unlock(&sc_log_fd_filters_tl_m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
thread_list = thread_list->next;
|
||||
}
|
||||
|
||||
mutex_unlock(&sc_log_fd_filters_tl_m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Updates a FD filter, based on whether the function that calls this
|
||||
* function, is registered as a FD filter or not. This is called by
|
||||
* a function only on its entry
|
||||
*
|
||||
* \param function Function_name from where the log_message originated
|
||||
*
|
||||
* \retval 1 Since it is a hack to get things working inside the macros
|
||||
*/
|
||||
int SCLogCheckFDFilterEntry(const char *function)
|
||||
{
|
||||
SCLogFDFilter *curr = NULL;
|
||||
|
||||
SCLogFDFilterThreadList *thread_list = NULL;
|
||||
SCLogFDFilterThreadList *thread_list_prev = NULL;
|
||||
SCLogFDFilterThreadList *thread_list_temp = NULL;
|
||||
|
||||
pthread_t self = syscall(SYS_gettid);
|
||||
|
||||
if (sc_log_module_initialized != 1) {
|
||||
printf("Logging module not initialized. Call SCLogInitLogModule() "
|
||||
"first before using the debug API\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_lock(&sc_log_fd_filters_m);
|
||||
|
||||
curr = sc_log_fd_filters;
|
||||
|
||||
while (curr != NULL) {
|
||||
if (strcmp(function, curr->func) == 0)
|
||||
break;
|
||||
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
if (curr == NULL) {
|
||||
mutex_unlock(&sc_log_fd_filters_m);
|
||||
return 1;
|
||||
}
|
||||
|
||||
mutex_unlock(&sc_log_fd_filters_m);
|
||||
|
||||
mutex_lock(&sc_log_fd_filters_tl_m);
|
||||
|
||||
thread_list = sc_log_fd_filters_tl;
|
||||
thread_list_temp = thread_list;
|
||||
while (thread_list != NULL) {
|
||||
thread_list_temp = thread_list;
|
||||
|
||||
if (self == thread_list->t)
|
||||
break;
|
||||
|
||||
thread_list = thread_list->next;
|
||||
}
|
||||
|
||||
if (thread_list != NULL) {
|
||||
thread_list->entered++;
|
||||
mutex_unlock(&sc_log_fd_filters_tl_m);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( (thread_list_temp = malloc(sizeof(SCLogFDFilterThreadList))) == NULL) {
|
||||
printf("Error allocating memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memset(thread_list_temp, 0, sizeof(SCLogFDFilterThreadList));
|
||||
|
||||
thread_list_temp->t = self;
|
||||
thread_list_temp->entered++;
|
||||
|
||||
if (thread_list_prev == NULL)
|
||||
sc_log_fd_filters_tl = thread_list_temp;
|
||||
else
|
||||
thread_list_prev->next = thread_list_temp;
|
||||
|
||||
mutex_unlock(&sc_log_fd_filters_tl_m);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Updates a FD filter, based on whether the function that calls this
|
||||
* function, is registered as a FD filter or not. This is called by
|
||||
* a function only before its exit.
|
||||
*
|
||||
* \param function Function_name from where the log_message originated
|
||||
*
|
||||
*/
|
||||
void SCLogCheckFDFilterExit(const char *function)
|
||||
{
|
||||
SCLogFDFilter *curr = NULL;
|
||||
|
||||
SCLogFDFilterThreadList *thread_list = NULL;
|
||||
|
||||
pthread_t self = syscall(SYS_gettid);
|
||||
|
||||
if (sc_log_module_initialized != 1) {
|
||||
printf("Logging module not initialized. Call SCLogInitLogModule() "
|
||||
"first before using the debug API\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&sc_log_fd_filters_m);
|
||||
|
||||
curr = sc_log_fd_filters;
|
||||
|
||||
while (curr != NULL) {
|
||||
if (strcmp(function, curr->func) == 0)
|
||||
break;
|
||||
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
if (curr == NULL) {
|
||||
mutex_unlock(&sc_log_fd_filters_m);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_unlock(&sc_log_fd_filters_m);
|
||||
|
||||
mutex_lock(&sc_log_fd_filters_tl_m);
|
||||
|
||||
thread_list = sc_log_fd_filters_tl;
|
||||
while (thread_list != NULL) {
|
||||
if (self == thread_list->t)
|
||||
break;
|
||||
|
||||
thread_list = thread_list->next;
|
||||
}
|
||||
|
||||
mutex_unlock(&sc_log_fd_filters_tl_m);
|
||||
|
||||
thread_list->entered--;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Adds a Function-Dependent(FD) filter
|
||||
*
|
||||
* \param Name of the function for which a FD filter has to be registered
|
||||
*
|
||||
* \retval 0 on success
|
||||
* \retval -1 on failure
|
||||
*/
|
||||
int SCLogAddFDFilter(const char *function)
|
||||
{
|
||||
SCLogFDFilter *curr = NULL;
|
||||
SCLogFDFilter *prev = NULL;
|
||||
SCLogFDFilter *temp = NULL;
|
||||
|
||||
if (sc_log_module_initialized != 1) {
|
||||
printf("Logging module not initialized. Call SCLogInitLogModule() "
|
||||
"first before using the debug API\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (function == NULL) {
|
||||
printf("Invalid argument supplied to SCLogAddFDFilter\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mutex_lock(&sc_log_fd_filters_m);
|
||||
|
||||
curr = sc_log_fd_filters;
|
||||
while (curr != NULL) {
|
||||
prev = curr;
|
||||
|
||||
if (strcmp(function, curr->func) == 0) {
|
||||
mutex_unlock(&sc_log_fd_filters_m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
if ( (temp = malloc(sizeof(SCLogFDFilter))) == NULL) {
|
||||
printf("Error allocating memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memset(temp, 0, sizeof(SCLogFDFilter));
|
||||
|
||||
if ( (temp->func = strdup(function)) == NULL) {
|
||||
printf("Error Allocating memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (curr == NULL) {
|
||||
if (sc_log_fd_filters == NULL)
|
||||
sc_log_fd_filters = temp;
|
||||
else
|
||||
prev->next = temp;
|
||||
}
|
||||
|
||||
mutex_unlock(&sc_log_fd_filters_m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Releases all the FD filters added to the logging module
|
||||
*/
|
||||
void SCLogReleaseFDFilters(void)
|
||||
{
|
||||
SCLogFDFilter *fdf = NULL;
|
||||
SCLogFDFilter *temp = NULL;
|
||||
|
||||
mutex_lock(&sc_log_fd_filters_m);
|
||||
|
||||
fdf = sc_log_fd_filters;
|
||||
while (fdf != NULL) {
|
||||
temp = fdf;
|
||||
fdf = fdf->next;
|
||||
SCLogReleaseFDFilter(temp);
|
||||
}
|
||||
|
||||
sc_log_fd_filters = NULL;
|
||||
|
||||
mutex_unlock(&sc_log_fd_filters_m);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Removes a Function-Dependent(FD) filter
|
||||
*
|
||||
* \param Name of the function for which a FD filter has to be unregistered
|
||||
*
|
||||
* \retval 0 on success(the filter was removed or the filter was not present)
|
||||
* \retval -1 on failure/error
|
||||
*/
|
||||
int SCLogRemoveFDFilter(const char *function)
|
||||
{
|
||||
SCLogFDFilter *curr = NULL;
|
||||
SCLogFDFilter *prev = NULL;
|
||||
|
||||
if (sc_log_module_initialized != 1) {
|
||||
printf("Logging module not initialized. Call SCLogInitLogModule() "
|
||||
"first before using the debug API\n");
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
if (function == NULL) {
|
||||
printf("Invalid argument(s) supplied to SCLogRemoveFDFilter\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mutex_lock(&sc_log_fd_filters_m);
|
||||
|
||||
if (sc_log_fd_filters == NULL) {
|
||||
mutex_unlock(&sc_log_fd_filters_m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
curr = sc_log_fd_filters;
|
||||
prev = curr;
|
||||
while (curr != NULL) {
|
||||
if (strcmp(function, curr->func) == 0)
|
||||
break;
|
||||
|
||||
prev = curr;
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
if (curr == NULL) {
|
||||
mutex_unlock(&sc_log_fd_filters_m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sc_log_fd_filters == curr)
|
||||
sc_log_fd_filters = curr->next;
|
||||
else
|
||||
prev->next = curr->next;
|
||||
|
||||
SCLogReleaseFDFilter(curr);
|
||||
|
||||
mutex_unlock(&sc_log_fd_filters_m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Prints the FG filters(both WL and BL). Used for debugging purposes.
|
||||
*
|
||||
* \retval count The no of FG filters
|
||||
*/
|
||||
int SCLogPrintFDFilters(void)
|
||||
{
|
||||
SCLogFDFilter *fdf = NULL;
|
||||
int count = 0;
|
||||
|
||||
if (sc_log_module_initialized != 1) {
|
||||
printf("Logging module not initialized. Call SCLogInitLogModule() "
|
||||
"first before using the debug API\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("FD filters:\n");
|
||||
#endif
|
||||
|
||||
mutex_lock(&sc_log_fd_filters_m);
|
||||
|
||||
fdf = sc_log_fd_filters;
|
||||
while (fdf != NULL) {
|
||||
#ifdef DEBUG
|
||||
printf("%s \n", fdf->func);
|
||||
#endif
|
||||
fdf = fdf->next;
|
||||
count++;
|
||||
}
|
||||
|
||||
mutex_unlock(&sc_log_fd_filters_m);
|
||||
|
||||
return count;
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/** Copyright (c) 2009 Open Information Security Foundation.
|
||||
* \author Anoop Saldanha <poonaatsoc@gmail.com>
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#ifndef __DEBUG_FILTERS_H__
|
||||
#define __DEBUG_FILTERS_H__
|
||||
|
||||
|
||||
/**
|
||||
* \brief Enum that holds the different kinds of filters available
|
||||
*/
|
||||
enum {
|
||||
SC_LOG_FILTER_BL = 0,
|
||||
SC_LOG_FILTER_WL = 1,
|
||||
SC_LOG_FILTER_MAX = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Structure used to hold the line_no details of a FG filter
|
||||
*/
|
||||
typedef struct SCLogFGFilterLine_ {
|
||||
int line;
|
||||
|
||||
struct SCLogFGFilterLine_ *next;
|
||||
} SCLogFGFilterLine;
|
||||
|
||||
/**
|
||||
* \brief structure used to hold the function details of a FG filter
|
||||
*/
|
||||
typedef struct SCLogFGFilterFunc_ {
|
||||
char *func;
|
||||
SCLogFGFilterLine *line;
|
||||
|
||||
struct SCLogFGFilterFunc_ *next;
|
||||
} SCLogFGFilterFunc;
|
||||
|
||||
/**
|
||||
* \brief Structure used to hold FG filters. Encapsulates filename details,
|
||||
* func details, which inturn encapsulates the line_no details
|
||||
*/
|
||||
typedef struct SCLogFGFilterFile_ {
|
||||
char *file;
|
||||
SCLogFGFilterFunc *func;
|
||||
|
||||
struct SCLogFGFilterFile_ *next;
|
||||
} SCLogFGFilterFile;
|
||||
|
||||
/**
|
||||
* \brief Structure used to hold the thread_list used by FD filters
|
||||
*/
|
||||
typedef struct SCLogFDFilterThreadList_ {
|
||||
int entered;
|
||||
pthread_t t;
|
||||
|
||||
struct SCLogFDFilterThreadList_ *next;
|
||||
} SCLogFDFilterThreadList;
|
||||
|
||||
/**
|
||||
* \brief Structure that holds the FD filters
|
||||
*/
|
||||
typedef struct SCLogFDFilter_ {
|
||||
char *func;
|
||||
|
||||
struct SCLogFDFilter_ *next;
|
||||
} SCLogFDFilter;
|
||||
|
||||
int SCLogAddFGFilterWL(const char *, const char *, int);
|
||||
|
||||
int SCLogAddFGFilterBL(const char *, const char *, int);
|
||||
|
||||
int SCLogMatchFGFilterBL(const char *, const char *, int);
|
||||
|
||||
int SCLogMatchFGFilterWL(const char *, const char *, int);
|
||||
|
||||
void SCLogReleaseFGFilters(void);
|
||||
|
||||
int SCLogAddFDFilter(const char *);
|
||||
|
||||
int SCLogPrintFDFilters(void);
|
||||
|
||||
void SCLogReleaseFDFilters(void);
|
||||
|
||||
int SCLogRemoveFDFilter(const char *);
|
||||
|
||||
int SCLogCheckFDFilterEntry(const char *);
|
||||
|
||||
void SCLogCheckFDFilterExit(const char *);
|
||||
|
||||
int SCLogMatchFDFilter(const char *);
|
||||
|
||||
int SCLogPrintFGFilters(void);
|
||||
|
||||
#endif /* __DEBUG_H__ */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,511 @@
|
||||
/** Copyright (c) 2009 Open Information Security Foundation.
|
||||
* \author Anoop Saldanha <poonaatsoc@gmail.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "util-enum.h"
|
||||
#include "util-error.h"
|
||||
#include "pcre.h"
|
||||
#include "util-debug-filters.h"
|
||||
|
||||
#ifndef __UTIL_DEBUG_H__
|
||||
#define __UTIL_DEBUG_H__
|
||||
|
||||
/**
|
||||
* \brief ENV vars that can be used to set the properties for the logging module
|
||||
*/
|
||||
#define SC_ENV_LOG_LEVEL "SC_LOG_LEVEL"
|
||||
#define SC_ENV_LOG_OP_IFACE "SC_LOG_OP_IFACE"
|
||||
#define SC_ENV_LOG_FILE "SC_LOG_FILE"
|
||||
#define SC_ENV_LOG_FACILITY "SC_LOG_FACILITY"
|
||||
#define SC_ENV_LOG_FORMAT "SC_LOG_FORMAT"
|
||||
#define SC_ENV_LOG_OP_FILTER "SC_LOG_OP_FILTER"
|
||||
|
||||
/**
|
||||
* \brief The various log levels
|
||||
*/
|
||||
typedef enum {
|
||||
SC_LOG_NONE = 0,
|
||||
SC_LOG_EMERGENCY,
|
||||
SC_LOG_ALERT,
|
||||
SC_LOG_CRITICAL,
|
||||
SC_LOG_ERROR,
|
||||
SC_LOG_WARNING,
|
||||
SC_LOG_NOTICE,
|
||||
SC_LOG_INFO,
|
||||
SC_LOG_DEBUG,
|
||||
SC_LOG_LEVEL_MAX,
|
||||
} SCLogLevel;
|
||||
|
||||
/**
|
||||
* \brief The various output interfaces supported
|
||||
*/
|
||||
typedef enum {
|
||||
SC_LOG_OP_IFACE_CONSOLE,
|
||||
SC_LOG_OP_IFACE_FILE,
|
||||
SC_LOG_OP_IFACE_SYSLOG,
|
||||
SC_LOG_OP_IFACE_MAX,
|
||||
} SCLogOPIface;
|
||||
|
||||
/* The default log_format, if it is not supplied by the user */
|
||||
#define SC_DEF_LOG_FORMAT "<%d> - <%t>"
|
||||
|
||||
/* The maximum length of the log message */
|
||||
#define SC_MAX_LOG_MSG_LEN 1024
|
||||
|
||||
/* The maximum length of the log format */
|
||||
#define SC_MAX_LOG_FORMAT_LEN 128
|
||||
|
||||
/* The default log level, if it is not supplied by the user */
|
||||
#define SC_DEF_LOG_LEVEL SC_LOG_ERROR
|
||||
|
||||
/* The default output interface to be used */
|
||||
#define SC_DEF_LOG_OP_IFACE SC_LOG_OP_IFACE_FILE
|
||||
|
||||
/* The default log file to be used */
|
||||
#define SC_DEF_LOG_FILE "/var/log/eidps/sc_ids_log.log"
|
||||
|
||||
/* The default syslog facility to be used */
|
||||
#define SC_DEF_SYSLOG_FACILITY_STR "local0"
|
||||
#define SC_DEF_SYSLOG_FACILITY LOG_LOCAL0
|
||||
|
||||
/**
|
||||
* \brief Structure to be used when log_level override support would be provided
|
||||
* by the logging module
|
||||
*/
|
||||
typedef struct SCLogOPBuffer_ {
|
||||
char msg[SC_MAX_LOG_MSG_LEN];
|
||||
char *temp;
|
||||
const char *log_format;
|
||||
} SCLogOPBuffer;
|
||||
|
||||
/**
|
||||
* \brief The output interface context for the logging module
|
||||
*/
|
||||
typedef struct SCLogOPIfaceCtx_ {
|
||||
SCLogOPIface iface;
|
||||
|
||||
/* the output file to be used if the interface is SC_LOG_IFACE_FILE */
|
||||
const char *file;
|
||||
/* the output file descriptor for the above file */
|
||||
FILE * file_d;
|
||||
|
||||
/* the facility code if the interface is SC_LOG_IFACE_SYSLOG */
|
||||
int facility;
|
||||
|
||||
/* override for the global_log_format(currently not used) */
|
||||
const char *log_format;
|
||||
|
||||
/* override for the global_log_level */
|
||||
SCLogLevel log_level;
|
||||
|
||||
struct SCLogOPIfaceCtx_ *next;
|
||||
} SCLogOPIfaceCtx;
|
||||
|
||||
/**
|
||||
* \brief Structure containing init data, that would be passed to
|
||||
* SCInitDebugModule()
|
||||
*/
|
||||
typedef struct SCLogInitData_ {
|
||||
/* startup message */
|
||||
char *startup_message;
|
||||
|
||||
/* the log level */
|
||||
SCLogLevel global_log_level;
|
||||
|
||||
/* the log format */
|
||||
char *global_log_format;
|
||||
|
||||
/* output filter */
|
||||
char *op_filter;
|
||||
|
||||
/* list of output interfaces to be used */
|
||||
SCLogOPIfaceCtx *op_ifaces;
|
||||
/* no of op ifaces */
|
||||
uint8_t op_ifaces_cnt;
|
||||
} SCLogInitData;
|
||||
|
||||
/**
|
||||
* \brief Holds the config state used by the logging api
|
||||
*/
|
||||
typedef struct SCLogConfig_ {
|
||||
char *startup_message;
|
||||
SCLogLevel log_level;
|
||||
char *log_format;
|
||||
|
||||
/* compiled pcre filter expression */
|
||||
pcre *op_filter_regex;
|
||||
pcre_extra *op_filter_regex_study;
|
||||
|
||||
/* op ifaces used */
|
||||
SCLogOPIfaceCtx *op_ifaces;
|
||||
/* no of op ifaces */
|
||||
uint8_t op_ifaces_cnt;
|
||||
} SCLogConfig;
|
||||
|
||||
/* The different log format specifiers supported by the API */
|
||||
#define SC_LOG_FMT_TIME 't' /* Timestamp in standard format */
|
||||
#define SC_LOG_FMT_PID 'p' /* PID */
|
||||
#define SC_LOG_FMT_TID 'i' /* Thread ID */
|
||||
#define SC_LOG_FMT_TM 'm' /* Thread module name */
|
||||
#define SC_LOG_FMT_LOG_LEVEL 'd' /* Log level */
|
||||
#define SC_LOG_FMT_FILE_NAME 'f' /* File name */
|
||||
#define SC_LOG_FMT_LINE 'l' /* Line number */
|
||||
#define SC_LOG_FMT_FUNCTION 'n' /* Function */
|
||||
|
||||
/* The log format prefix for the format specifiers */
|
||||
#define SC_LOG_FMT_PREFIX '%'
|
||||
|
||||
extern SCLogLevel sc_global_log_level;
|
||||
|
||||
extern int sc_log_module_initialized;
|
||||
|
||||
extern int sc_log_module_cleaned;
|
||||
|
||||
|
||||
#define SCLog(x, ...) do { \
|
||||
char msg[SC_MAX_LOG_MSG_LEN]; \
|
||||
char *temp = msg; \
|
||||
if ( !( \
|
||||
(sc_global_log_level >= x) && \
|
||||
SCLogMessage(x, &temp, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__FUNCTION__) \
|
||||
== SC_OK) ) \
|
||||
{ } else { \
|
||||
snprintf(temp, \
|
||||
(SC_MAX_LOG_MSG_LEN - \
|
||||
(msg - temp)), \
|
||||
__VA_ARGS__); \
|
||||
SCLogOutputBuffer(x, msg); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define SCLogErr(x, err, ...) do { \
|
||||
char msg[SC_MAX_LOG_MSG_LEN]; \
|
||||
char *temp = msg; \
|
||||
if ( !( \
|
||||
(sc_global_log_level >= x) && \
|
||||
SCLogMessage(x, &temp, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__FUNCTION__) \
|
||||
== SC_OK) ) \
|
||||
{ } else { \
|
||||
temp = temp + snprintf(temp, \
|
||||
(SC_MAX_LOG_MSG_LEN - \
|
||||
(msg - temp)), \
|
||||
"[ERRCODE: %s(%d)] - ",\
|
||||
SCErrorToString(err), \
|
||||
err); \
|
||||
snprintf(temp, \
|
||||
(SC_MAX_LOG_MSG_LEN - \
|
||||
(msg - temp)), \
|
||||
__VA_ARGS__); \
|
||||
SCLogOutputBuffer(x, msg); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* \brief Macro used to log INFORMATIONAL messages.
|
||||
*
|
||||
* \retval ... Takes as argument(s), a printf style format message
|
||||
*/
|
||||
#define SCInfo(...) SCLog(SC_LOG_INFO, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* \brief Macro used to log NOTICE messages.
|
||||
*
|
||||
* \retval ... Takes as argument(s), a printf style format message
|
||||
*/
|
||||
#define SCNotice(...) SCLog(SC_LOG_NOTICE, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* \brief Macro used to log WARNING messages.
|
||||
*
|
||||
* \retval err_code Error code that has to be logged along with the
|
||||
* warning message
|
||||
* \retval ... Takes as argument(s), a printf style format message
|
||||
*/
|
||||
#define SCWarning(err_code, ...) SCLogErr(SC_LOG_WARNING, err_code, \
|
||||
__VA_ARGS__)
|
||||
/**
|
||||
* \brief Macro used to log ERROR messages.
|
||||
*
|
||||
* \retval err_code Error code that has to be logged along with the
|
||||
* error message
|
||||
* \retval ... Takes as argument(s), a printf style format message
|
||||
*/
|
||||
#define SCErrorLog(err_code, ...) SCLogErr(SC_LOG_ERROR, err_code, \
|
||||
__VA_ARGS__)
|
||||
/**
|
||||
* \brief Macro used to log CRITICAL messages.
|
||||
*
|
||||
* \retval err_code Error code that has to be logged along with the
|
||||
* critical message
|
||||
* \retval ... Takes as argument(s), a printf style format message
|
||||
*/
|
||||
#define SCCritical(err_code, ...) SCLogErr(SC_LOG_CRITICAL, err_code, \
|
||||
__VA_ARGS__)
|
||||
/**
|
||||
* \brief Macro used to log ALERT messages.
|
||||
*
|
||||
* \retval err_code Error code that has to be logged along with the
|
||||
* alert message
|
||||
* \retval ... Takes as argument(s), a printf style format message
|
||||
*/
|
||||
#define SCAlert(err_code, ...) SCLogErr(SC_LOG_ALERT, err_code, \
|
||||
__VA_ARGS__)
|
||||
/**
|
||||
* \brief Macro used to log EMERGENCY messages.
|
||||
*
|
||||
* \retval err_code Error code that has to be logged along with the
|
||||
* emergency message
|
||||
* \retval ... Takes as argument(s), a printf style format message
|
||||
*/
|
||||
#define SCEmerg(err_code, ...) SCLogErr(SC_LOG_EMERGENCY, err_code, \
|
||||
__VA_ARGS__)
|
||||
|
||||
|
||||
/* Avoid the overhead of using the debugging subsystem, in production mode */
|
||||
#ifndef DEBUG
|
||||
|
||||
#define SCDebug(...)
|
||||
|
||||
#define SCEnter(...)
|
||||
|
||||
#define SCReturn return
|
||||
|
||||
#define SCReturnInt(x) return x
|
||||
|
||||
#define SCReturnUInt(x) return x
|
||||
|
||||
#define SCReturnDbl(x) return x
|
||||
|
||||
#define SCReturnChar(x) return x
|
||||
|
||||
#define SCReturnCharPtr(x) return x
|
||||
|
||||
#define SCReturnCT(x, type) return x
|
||||
|
||||
#define SCReturnPtr(x, type) return x
|
||||
|
||||
/* Please use it only for debugging purposes */
|
||||
#else
|
||||
|
||||
|
||||
/**
|
||||
* \brief Macro used to log DEBUG messages. Comes under the debugging subsystem,
|
||||
* and hence will be enabled only in the presence of the DEBUG macro.
|
||||
*
|
||||
* \retval ... Takes as argument(s), a printf style format message
|
||||
*/
|
||||
#define SCDebug(...) SCLog(SC_LOG_DEBUG, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* \brief Macro used to log debug messages on function entry. Comes under the
|
||||
* debugging subsystem, and hence will be enabled only in the presence
|
||||
* of the DEBUG macro. Apart from logging function_entry logs, it also
|
||||
* processes the FD filters, if any FD filters are registered.
|
||||
*
|
||||
* \retval f An argument can be supplied, although it is not used
|
||||
*/
|
||||
#define SCEnter(f) do { \
|
||||
char msg[SC_MAX_LOG_MSG_LEN]; \
|
||||
char *temp = msg; \
|
||||
if (sc_global_log_level >= SC_LOG_DEBUG && \
|
||||
SCLogCheckFDFilterEntry(__FUNCTION__) &&\
|
||||
SCLogMessage(SC_LOG_DEBUG, &temp, \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
__FUNCTION__) == SC_OK) { \
|
||||
snprintf(temp, (SC_MAX_LOG_MSG_LEN - \
|
||||
(msg - temp)), \
|
||||
"%s", "Entering ... >>"); \
|
||||
SCLogOutputBuffer(SC_LOG_DEBUG, msg); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
/**
|
||||
* \brief Macro used to log debug messages on function exit. Comes under the
|
||||
* debugging sybsystem, and hence will be enabled only in the presence
|
||||
* of the DEBUG macro. Apart from logging function_exit logs, it also
|
||||
* processes the FD filters, if any FD filters are registered. This
|
||||
* function_exit macro should be used for functions that don't return
|
||||
* a value.
|
||||
*/
|
||||
#define SCReturn do { \
|
||||
if (sc_global_log_level >= SC_LOG_DEBUG) { \
|
||||
SCDebug("Returning ... <<" ); \
|
||||
SCLogCheckFDFilterExit(__FUNCTION__); \
|
||||
} \
|
||||
return; \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* \brief Macro used to log debug messages on function exit. Comes under the
|
||||
* debugging sybsystem, and hence will be enabled only in the presence
|
||||
* of the DEBUG macro. Apart from logging function_exit logs, it also
|
||||
* processes the FD filters, if any FD filters are registered. This
|
||||
* function_exit macro should be used for functions that returns an
|
||||
* integer value.
|
||||
*
|
||||
* \retval x Variable of type 'integer' that has to be returned
|
||||
*/
|
||||
#define SCReturnInt(x) do { \
|
||||
if (sc_global_log_level >= SC_LOG_DEBUG) { \
|
||||
SCDebug("Returning: %d ... <<", x); \
|
||||
SCLogCheckFDFilterExit(__FUNCTION__); \
|
||||
} \
|
||||
return x; \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* \brief Macro used to log debug messages on function exit. Comes under the
|
||||
* debugging sybsystem, and hence will be enabled only in the presence
|
||||
* of the DEBUG macro. Apart from logging function_exit logs, it also
|
||||
* processes the FD filters, if any FD filters are registered. This
|
||||
* function_exit macro should be used for functions that returns an
|
||||
* unsigned integer value.
|
||||
*
|
||||
* \retval x Variable of type 'unsigned integer' that has to be returned
|
||||
*/
|
||||
#define SCReturnUInt(x) do { \
|
||||
if (sc_global_log_level >= SC_LOG_DEBUG) { \
|
||||
SCDebug("Returning: %u ... <<", x); \
|
||||
SCLogCheckFDFilterExit(__FUNCTION__); \
|
||||
} \
|
||||
return x; \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* \brief Macro used to log debug messages on function exit. Comes under the
|
||||
* debugging sybsystem, and hence will be enabled only in the presence
|
||||
* of the DEBUG macro. Apart from logging function_exit logs, it also
|
||||
* processes the FD filters, if any FD filters are registered. This
|
||||
* function_exit macro should be used for functions that returns a
|
||||
* float/double value.
|
||||
*
|
||||
* \retval x Variable of type 'float/double' that has to be returned
|
||||
*/
|
||||
#define SCReturnDbl(x) do { \
|
||||
if (sc_global_log_level >= SC_LOG_DEBUG) { \
|
||||
SCDebug("Returning: %f ... <<", x); \
|
||||
SCLogCheckFDFilterExit(__FUNCTION__); \
|
||||
} \
|
||||
return x; \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* \brief Macro used to log debug messages on function exit. Comes under the
|
||||
* debugging sybsystem, and hence will be enabled only in the presence
|
||||
* of the DEBUG macro. Apart from logging function_exit logs, it also
|
||||
* processes the FD filters, if any FD filters are registered. This
|
||||
* function_exit macro should be used for functions that returns a var
|
||||
* of character type.
|
||||
*
|
||||
* \retval x Variable of type 'char' that has to be returned
|
||||
*/
|
||||
#define SCReturnChar(x) do { \
|
||||
if (sc_global_log_level >= SC_LOG_DEBUG) { \
|
||||
SCDebug("Returning: %c ... <<", x); \
|
||||
SCLogCheckFDFilterExit(__FUNCTION__); \
|
||||
} \
|
||||
return x; \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* \brief Macro used to log debug messages on function exit. Comes under the
|
||||
* debugging sybsystem, and hence will be enabled only in the presence
|
||||
* of the DEBUG macro. Apart from logging function_exit logs, it also
|
||||
* processes the FD filters, if any FD filters are registered. This
|
||||
* function_exit macro should be used for functions that returns a
|
||||
* character string.
|
||||
*
|
||||
* \retval x Pointer to the char string that has to be returned
|
||||
*/
|
||||
#define SCReturnCharPtr(x) do { \
|
||||
if (sc_global_log_level >= SC_LOG_DEBUG) { \
|
||||
SCDebug("Returning: %s ... <<", x); \
|
||||
SCLogCheckFDFilterExit(__FUNCTION__); \
|
||||
} \
|
||||
return x; \
|
||||
} while(0)
|
||||
|
||||
|
||||
/**
|
||||
* \brief Macro used to log debug messages on function exit. Comes under the
|
||||
* debugging sybsystem, and hence will be enabled only in the presence
|
||||
* of the DEBUG macro. Apart from logging function_exit logs, it also
|
||||
* processes the FD filters, if any FD filters are registered. This
|
||||
* function_exit macro should be used for functions that returns a var
|
||||
* of custom type
|
||||
*
|
||||
* \retval x Variable instance of a custom type that has to be returned
|
||||
* \retval type Pointer to a character string holding the name of the custom
|
||||
* type(the argument x) that has to be returned
|
||||
*/
|
||||
#define SCReturnCT(x, type) do { \
|
||||
if (sc_global_log_level >= SC_LOG_DEBUG) { \
|
||||
SCDebug("Returning var of " \
|
||||
"type %s ... <<", type); \
|
||||
SCLogCheckFDFilterExit(__FUNCTION__); \
|
||||
} \
|
||||
return x; \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* \brief Macro used to log debug messages on function exit. Comes under the
|
||||
* debugging sybsystem, and hence will be enabled only in the presence
|
||||
* of the DEBUG macro. Apart from logging function_exit logs, it also
|
||||
* processes the FD filters, if any FD filters are registered. This
|
||||
* function_exit macro should be used for functions that returns a
|
||||
* pointer to a custom type
|
||||
*
|
||||
* \retval x Pointer to a variable instance of a custom type that has to be
|
||||
* returned
|
||||
* \retval type Pointer to a character string holding the name of the custom
|
||||
* type(the argument x) that has to be returned
|
||||
*/
|
||||
#define SCReturnPtr(x, type) do { \
|
||||
if (sc_global_log_level >= SC_LOG_DEBUG) { \
|
||||
SCDebug("Returning pointer of " \
|
||||
"type %s ... <<", type); \
|
||||
SCLogCheckFDFilterExit(__FUNCTION__); \
|
||||
} \
|
||||
return x; \
|
||||
} while(0)
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
||||
SCLogInitData *SCLogAllocLogInitData(void);
|
||||
|
||||
SCLogOPIfaceCtx *SCLogInitOPIfaceCtx(const char *, const char *, int,
|
||||
const char *);
|
||||
|
||||
void SCLogAppendOPIfaceCtx(SCLogOPIfaceCtx *, SCLogInitData *);
|
||||
|
||||
void SCLogInitLogModule(SCLogInitData *);
|
||||
|
||||
void SCLogInitLogModuleIfEnvSet(void);
|
||||
|
||||
void SCLogDeInitLogModule(void);
|
||||
|
||||
SCError SCLogMessage(SCLogLevel, char **, const char *, unsigned, const char *);
|
||||
|
||||
void SCLogOutputBuffer(SCLogLevel, char *);
|
||||
|
||||
SCLogOPBuffer *SCLogAllocLogOPBuffer(void);
|
||||
|
||||
int SCLogAddFGFilter(const char *, const char *, unsigned, int);
|
||||
|
||||
void SCLogRegisterTests(void);
|
||||
|
||||
#endif /* __UTIL_DEBUG_H__ */
|
@ -0,0 +1,63 @@
|
||||
/** Copyright (c) 2009 Open Information Security Foundation.
|
||||
* \author Anoop Saldanha <poonaatsoc@gmail.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util-enum.h"
|
||||
|
||||
/**
|
||||
* \brief Maps a string name to an enum value from the supplied table
|
||||
*
|
||||
* \param enum_name Character string that has to be mapped to an enum value
|
||||
* from the table
|
||||
* \param table Enum-Char table, from which the mapping is retrieved
|
||||
*
|
||||
* \retval result The enum_value for the enum_name string or -1 on failure
|
||||
*/
|
||||
int SCMapEnumNameToValue(const char *enum_name, SCEnumCharMap *table)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (enum_name == NULL || table == NULL) {
|
||||
printf("Invalid argument(s) passed into SCMapEnumNameToValue\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (; table->enum_name != NULL; table++) {
|
||||
if (strcasecmp(table->enum_name, enum_name) == 0) {
|
||||
result = table->enum_value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Maps an enum value to a string name, from the supplied table
|
||||
*
|
||||
* \param enum_value Enum_value that has to be mapped to a string_value
|
||||
* from the table
|
||||
* \param table Enum-Char table, from which the mapping is retrieved
|
||||
*
|
||||
* \retval result The enum_name for the enum_value supplied or NULL on failure
|
||||
*/
|
||||
const char * SCMapEnumValueToName(int enum_value, SCEnumCharMap *table)
|
||||
{
|
||||
if (table == NULL) {
|
||||
printf("Invalid argument(s) passed into SCMapEnumValueToName\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (; table->enum_name != NULL; table++) {
|
||||
if (table->enum_value == enum_value) {
|
||||
return table->enum_name;
|
||||
}
|
||||
}
|
||||
|
||||
printf("A enum by the value %d doesn't exist in this table\n", enum_value);
|
||||
|
||||
return NULL;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
/** Copyright (c) 2009 Open Information Security Foundation.
|
||||
* \author Anoop Saldanha <poonaatsoc@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __ENUM_H__
|
||||
#define __ENUM_H__
|
||||
|
||||
typedef struct _SCEnumCharMap {
|
||||
char *enum_name;
|
||||
int enum_value;
|
||||
} SCEnumCharMap;
|
||||
|
||||
int SCMapEnumNameToValue(const char *, SCEnumCharMap *);
|
||||
|
||||
const char * SCMapEnumValueToName(int, SCEnumCharMap *);
|
||||
|
||||
#endif /* __ENUM_H__ */
|
@ -0,0 +1,26 @@
|
||||
/** Copyright (c) 2009 Open Information Security Foundation.
|
||||
* \author Anoop Saldanha <poonaatsoc@gmail.com>
|
||||
*/
|
||||
|
||||
#include "util-error.h"
|
||||
|
||||
#define CASE_CODE(E) case E: return #E
|
||||
|
||||
/**
|
||||
* \brief Maps the error code, to its string equivalent
|
||||
*
|
||||
* \param The error code
|
||||
*
|
||||
* \retval The string equivalent for the error code
|
||||
*/
|
||||
const char * SCErrorToString(SCError err)
|
||||
{
|
||||
switch (err) {
|
||||
CASE_CODE (SC_ERR_MEM_ALLOC);
|
||||
CASE_CODE (SC_OK);
|
||||
CASE_CODE (SC_PCRE_MATCH_FAILED);
|
||||
CASE_CODE (SC_LOG_MODULE_NOT_INIT);
|
||||
default:
|
||||
return "UNKNOWN_ERROR";
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
/** Copyright (c) 2009 Open Information Security Foundation.
|
||||
* \author Anoop Saldanha <poonaatsoc@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __ERROR_H__
|
||||
#define __ERROR_H__
|
||||
|
||||
|
||||
/* different error types */
|
||||
typedef enum {
|
||||
SC_OK,
|
||||
SC_ERR_MEM_ALLOC,
|
||||
SC_PCRE_MATCH_FAILED,
|
||||
SC_LOG_MODULE_NOT_INIT,
|
||||
SC_LOG_FG_FILTER_MATCH_FAILED,
|
||||
SC_COUNTER_EXCEEDED,
|
||||
SC_INVALID_CHECKSUM,
|
||||
SC_SPRINTF_ERROR,
|
||||
} SCError;
|
||||
|
||||
const char *SCErrorToString(SCError);
|
||||
|
||||
|
||||
#endif /* __ERROR_H__ */
|
Loading…
Reference in New Issue