Implementation of the logging module

remotes/origin/master-1.0.x
Anoop Saldanha 16 years ago committed by Victor Julien
parent f658ffbc9c
commit 157d5e8113

@ -88,6 +88,10 @@ util-time.c util-time.h \
util-var.c util-var.h \
util-var-name.c util-var-name.h \
util-byte.c util-byte.h \
util-debug.c util-debug.h \
util-debug-filters.c util-debug-filters.h \
util-error.c util-error.h \
util-enum.c util-enum.h \
tm-modules.c tm-modules.h \
tm-queues.c tm-queues.h \
tm-queuehandlers.c tm-queuehandlers.h \

@ -22,6 +22,7 @@
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-engine-mpm.h"
#include "detect-engine-sigorder.h"
#include "tm-queuehandlers.h"
#include "tm-queues.h"
@ -68,7 +69,7 @@
#include "conf-yaml-loader.h"
#include "runmodes.h"
#include "detect-engine-sigorder.h"
#include "util-debug.h"
/*
* we put this here, because we only use it here in main.
@ -419,6 +420,7 @@ int main(int argc, char **argv)
TmqhFlowRegisterTests();
FlowRegisterTests();
SCSigRegisterSignatureOrderingTests();
SCLogRegisterTests();
uint32_t failed = UtRunTests();
UtCleanup();
if (failed) exit(EXIT_FAILURE);

@ -738,12 +738,15 @@ ThreadVars *TmThreadCreateMgmtThread(char *name, void *(fn_p)(void *),
*/
void TmThreadAppend(ThreadVars *tv, int type)
{
pthread_mutex_lock(&tv_root_lock);
if (tv_root[type] == NULL) {
tv_root[type] = tv;
tv->next = NULL;
tv->prev = NULL;
//printf("TmThreadAppend: thread \'%s\' is the first thread in the list.\n", tv->name);
pthread_mutex_unlock(&tv_root_lock);
return;
}
@ -760,6 +763,7 @@ void TmThreadAppend(ThreadVars *tv, int type)
t = t->next;
}
pthread_mutex_unlock(&tv_root_lock);
//printf("TmThreadAppend: thread \'%s\' is added to the list.\n", tv->name);
}
@ -1114,3 +1118,33 @@ int TmThreadWaitOnThreadInit(void)
"threads initialized, engine started.\n", ppt_num, mgt_num);
return 0;
}
/**
* \brief Returns the TV for the calling thread.
*
* \retval tv Pointer to the ThreadVars instance for the calling thread;
* NULL on no match
*/
ThreadVars *TmThreadsGetCallingThread(void)
{
pthread_t self = pthread_self();
ThreadVars *tv = NULL;
int i = 0;
mutex_lock(&tv_root_lock);
for (i = 0; i < TVT_MAX; i++) {
tv = tv_root[i];
while (tv) {
if (pthread_equal(self, tv->t)) {
mutex_unlock(&tv_root_lock);
return tv;
}
tv = tv->next;
}
}
mutex_unlock(&tv_root_lock);
return NULL;
}

@ -57,5 +57,7 @@ int TmThreadWaitOnThreadInit(void);
inline int TmThreadsCheckFlag(ThreadVars *, uint8_t);
inline void TmThreadsSetFlag(ThreadVars *, uint8_t);
ThreadVars *TmThreadsGetCallingThread(void);
#endif /* __TM_THREADS_H__ */

@ -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…
Cancel
Save