mirror of https://github.com/OISF/suricata
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1010 lines
28 KiB
C
1010 lines
28 KiB
C
/* Copyright (C) 2007-2013 Open Information Security Foundation
|
|
*
|
|
* You can copy, redistribute or modify this Program under the terms of
|
|
* the GNU General Public License version 2 as published by the Free
|
|
* Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* version 2 along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301, USA.
|
|
*/
|
|
|
|
/**
|
|
* \file
|
|
*
|
|
* \author Anoop Saldanha <anoopsaldanha@gmail.com>
|
|
*
|
|
* Debug filter utility functions
|
|
*/
|
|
|
|
#include "suricata-common.h"
|
|
|
|
/* both of these are defined in util-debug.c */
|
|
extern int sc_log_module_initialized;
|
|
extern int sc_log_module_cleaned;
|
|
|
|
/* used to indicate if any FG filters are registered */
|
|
int sc_log_fg_filters_present = 0;
|
|
|
|
/* used to indicate if any FD filters are registered */
|
|
int sc_log_fd_filters_present = 0;
|
|
|
|
/**
|
|
* \brief Holds the fine-grained filters
|
|
*/
|
|
SCLogFGFilterFile *sc_log_fg_filters[SC_LOG_FILTER_MAX] = { NULL, NULL };
|
|
|
|
/**
|
|
* \brief Mutex for accessing the fine-grained fiters sc_log_fg_filters
|
|
*/
|
|
static SCMutex sc_log_fg_filters_m[SC_LOG_FILTER_MAX] = { SCMUTEX_INITIALIZER,
|
|
SCMUTEX_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 SCMutex sc_log_fd_filters_m = SCMUTEX_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 SCMutex sc_log_fd_filters_tl_m = SCMUTEX_INITIALIZER;
|
|
|
|
/**
|
|
* \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
|
|
*/
|
|
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;
|
|
}
|
|
|
|
SCMutex *m = &sc_log_fg_filters_m[listtype];
|
|
|
|
SCMutexLock(m);
|
|
|
|
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:
|
|
SCMutexUnlock(&sc_log_fg_filters_m[listtype]);
|
|
sc_log_fg_filters_present = 1;
|
|
|
|
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;
|
|
}
|
|
|
|
SCMutexLock(&sc_log_fg_filters_m[listtype]);
|
|
|
|
fgf_file = sc_log_fg_filters[listtype];
|
|
|
|
if (fgf_file == NULL) {
|
|
SCMutexUnlock(&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) {
|
|
SCMutexUnlock(&sc_log_fg_filters_m[listtype]);
|
|
if (listtype == SC_LOG_FILTER_WL)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
fgf_file = fgf_file->next;
|
|
}
|
|
|
|
SCMutexUnlock(&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++) {
|
|
SCMutexLock(&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;
|
|
SCFree(temp);
|
|
}
|
|
|
|
if (fgf_func->func != NULL)
|
|
SCFree(fgf_func->func);
|
|
temp = fgf_func;
|
|
fgf_func = fgf_func->next;
|
|
SCFree(temp);
|
|
}
|
|
|
|
if (fgf_file->file != NULL)
|
|
SCFree(fgf_file->file);
|
|
temp = fgf_file;
|
|
fgf_file = fgf_file->next;
|
|
SCFree(temp);
|
|
}
|
|
|
|
SCMutexUnlock(&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++) {
|
|
SCMutexLock(&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;
|
|
}
|
|
SCMutexUnlock(&sc_log_fg_filters_m[i]);
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------|--------------------------
|
|
* -------------------------- Code for the FD Filter |--------------------------
|
|
* --------------------------------------------------V--------------------------
|
|
*/
|
|
|
|
/**
|
|
* \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)
|
|
{
|
|
#ifndef DEBUG
|
|
return 1;
|
|
#else
|
|
SCLogFDFilterThreadList *thread_list = NULL;
|
|
|
|
pthread_t self = pthread_self();
|
|
|
|
if (sc_log_module_initialized != 1) {
|
|
printf("Logging module not initialized. Call SCLogInitLogModule() "
|
|
"first before using the debug API\n");
|
|
return 0;
|
|
}
|
|
|
|
SCMutexLock(&sc_log_fd_filters_tl_m);
|
|
|
|
if (sc_log_fd_filters_tl == NULL) {
|
|
SCMutexUnlock(&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 (pthread_equal(self, thread_list->t)) {
|
|
if (thread_list->entered > 0) {
|
|
SCMutexUnlock(&sc_log_fd_filters_tl_m);
|
|
return 1;
|
|
}
|
|
SCMutexUnlock(&sc_log_fd_filters_tl_m);
|
|
return 0;
|
|
}
|
|
|
|
thread_list = thread_list->next;
|
|
}
|
|
|
|
SCMutexUnlock(&sc_log_fd_filters_tl_m);
|
|
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* \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_temp = NULL;
|
|
|
|
//pid_t self = syscall(SYS_gettid);
|
|
pthread_t self = pthread_self();
|
|
|
|
if (sc_log_module_initialized != 1) {
|
|
printf("Logging module not initialized. Call SCLogInitLogModule() "
|
|
"first before using the debug API\n");
|
|
return 0;
|
|
}
|
|
|
|
SCMutexLock(&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) {
|
|
SCMutexUnlock(&sc_log_fd_filters_m);
|
|
return 1;
|
|
}
|
|
|
|
SCMutexUnlock(&sc_log_fd_filters_m);
|
|
|
|
SCMutexLock(&sc_log_fd_filters_tl_m);
|
|
|
|
thread_list = sc_log_fd_filters_tl;
|
|
while (thread_list != NULL) {
|
|
if (pthread_equal(self, thread_list->t))
|
|
break;
|
|
|
|
thread_list = thread_list->next;
|
|
}
|
|
|
|
if (thread_list != NULL) {
|
|
thread_list->entered++;
|
|
SCMutexUnlock(&sc_log_fd_filters_tl_m);
|
|
return 1;
|
|
}
|
|
|
|
if ( (thread_list_temp = SCMalloc(sizeof(SCLogFDFilterThreadList))) == NULL) {
|
|
SCMutexUnlock(&sc_log_fd_filters_tl_m);
|
|
return 0;
|
|
}
|
|
memset(thread_list_temp, 0, sizeof(SCLogFDFilterThreadList));
|
|
|
|
thread_list_temp->t = self;
|
|
thread_list_temp->entered++;
|
|
|
|
sc_log_fd_filters_tl = thread_list_temp;
|
|
|
|
SCMutexUnlock(&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;
|
|
|
|
//pid_t self = syscall(SYS_gettid);
|
|
pthread_t self = pthread_self();
|
|
|
|
if (sc_log_module_initialized != 1) {
|
|
printf("Logging module not initialized. Call SCLogInitLogModule() "
|
|
"first before using the debug API\n");
|
|
return;
|
|
}
|
|
|
|
SCMutexLock(&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) {
|
|
SCMutexUnlock(&sc_log_fd_filters_m);
|
|
return;
|
|
}
|
|
|
|
SCMutexUnlock(&sc_log_fd_filters_m);
|
|
|
|
SCMutexLock(&sc_log_fd_filters_tl_m);
|
|
|
|
thread_list = sc_log_fd_filters_tl;
|
|
while (thread_list != NULL) {
|
|
if (pthread_equal(self, thread_list->t))
|
|
break;
|
|
|
|
thread_list = thread_list->next;
|
|
}
|
|
|
|
SCMutexUnlock(&sc_log_fd_filters_tl_m);
|
|
|
|
if (thread_list != NULL)
|
|
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;
|
|
}
|
|
|
|
SCMutexLock(&sc_log_fd_filters_m);
|
|
|
|
curr = sc_log_fd_filters;
|
|
while (curr != NULL) {
|
|
prev = curr;
|
|
|
|
if (strcmp(function, curr->func) == 0) {
|
|
|
|
SCMutexUnlock(&sc_log_fd_filters_m);
|
|
return 0;
|
|
}
|
|
|
|
curr = curr->next;
|
|
}
|
|
|
|
if ( (temp = SCMalloc(sizeof(SCLogFDFilter))) == NULL) {
|
|
printf("Error Allocating memory (SCMalloc)\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
memset(temp, 0, sizeof(SCLogFDFilter));
|
|
|
|
if ( (temp->func = SCStrdup(function)) == NULL) {
|
|
printf("Error Allocating memory (SCStrdup)\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (sc_log_fd_filters == NULL)
|
|
sc_log_fd_filters = temp;
|
|
/* clang thinks prev can be NULL, but it can't be unless
|
|
* sc_log_fd_filters is also NULL which is handled here.
|
|
* Doing this "fix" to shut clang up. */
|
|
else if (prev != NULL)
|
|
prev->next = temp;
|
|
|
|
SCMutexUnlock(&sc_log_fd_filters_m);
|
|
sc_log_fd_filters_present = 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* \brief Releases all the FD filters added to the logging module
|
|
*/
|
|
void SCLogReleaseFDFilters(void)
|
|
{
|
|
SCLogFDFilter *fdf = NULL;
|
|
SCLogFDFilter *temp = NULL;
|
|
|
|
SCMutexLock(&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;
|
|
|
|
SCMutexUnlock( &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;
|
|
}
|
|
|
|
SCMutexLock(&sc_log_fd_filters_m);
|
|
|
|
if (sc_log_fd_filters == NULL) {
|
|
SCMutexUnlock(&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) {
|
|
|
|
SCMutexUnlock(&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);
|
|
|
|
SCMutexUnlock(&sc_log_fd_filters_m);
|
|
|
|
if (sc_log_fd_filters == NULL)
|
|
sc_log_fd_filters_present = 0;
|
|
|
|
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
|
|
|
|
SCMutexLock(&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++;
|
|
}
|
|
|
|
SCMutexUnlock(&sc_log_fd_filters_m);
|
|
|
|
return count;
|
|
}
|
|
|
|
/**
|
|
* \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)
|
|
*/
|
|
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 = SCMalloc(sizeof(SCLogFGFilterFile))) == NULL) {
|
|
SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogAddToFGFFileList. Exiting...");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
memset(fgf_file_temp, 0, sizeof(SCLogFGFilterFile));
|
|
|
|
if ( file != NULL && (fgf_file_temp->file = SCStrdup(file)) == NULL) {
|
|
printf("Error Allocating memory\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if ( (fgf_func_temp = SCMalloc(sizeof(SCLogFGFilterFunc))) == NULL) {
|
|
SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogAddToFGFFileList. Exiting...");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
memset(fgf_func_temp, 0, sizeof(SCLogFGFilterFunc));
|
|
|
|
if ( function != NULL && (fgf_func_temp->func = SCStrdup(function)) == NULL) {
|
|
printf("Error Allocating memory\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if ( (fgf_line_temp = SCMalloc(sizeof(SCLogFGFilterLine))) == NULL) {
|
|
SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogAddToFGFFileList. Exiting...");
|
|
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
|
|
*/
|
|
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 = SCMalloc(sizeof(SCLogFGFilterFunc))) == NULL) {
|
|
SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogAddToFGFFuncList. Exiting...");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
memset(fgf_func_temp, 0, sizeof(SCLogFGFilterFunc));
|
|
|
|
if ( function != NULL && (fgf_func_temp->func = SCStrdup(function)) == NULL) {
|
|
printf("Error Allocating memory\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if ( (fgf_line_temp = SCMalloc(sizeof(SCLogFGFilterLine))) == NULL) {
|
|
SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogAddToFGFFuncList. Exiting...");
|
|
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
|
|
*/
|
|
void SCLogAddToFGFLineList(SCLogFGFilterFunc *fgf_func,
|
|
SCLogFGFilterLine *fgf_line,
|
|
int line)
|
|
{
|
|
SCLogFGFilterLine *fgf_line_temp = NULL;
|
|
|
|
if ( (fgf_line_temp = SCMalloc(sizeof(SCLogFGFilterLine))) == NULL) {
|
|
SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogAddToFGFLineList. Exiting...");
|
|
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 Releases the memory alloted to a FD filter
|
|
*
|
|
* \param Pointer to the FD filter that has to be freed
|
|
*/
|
|
void SCLogReleaseFDFilter(SCLogFDFilter *fdf)
|
|
{
|
|
if (fdf != NULL) {
|
|
if (fdf->func != NULL)
|
|
SCFree(fdf->func);
|
|
SCFree(fdf);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|