]>
Commit | Line | Data |
---|---|---|
5532af46 | 1 | /* Copyright (C) 2007-2013 Open Information Security Foundation |
ce019275 WM |
2 | * |
3 | * You can copy, redistribute or modify this Program under the terms of | |
4 | * the GNU General Public License version 2 as published by the Free | |
5 | * Software Foundation. | |
6 | * | |
7 | * This program is distributed in the hope that it will be useful, | |
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
10 | * GNU General Public License for more details. | |
11 | * | |
12 | * You should have received a copy of the GNU General Public License | |
13 | * version 2 along with this program; if not, write to the Free Software | |
14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |
15 | * 02110-1301, USA. | |
157d5e81 | 16 | */ |
ce019275 WM |
17 | |
18 | /** | |
19 | * \file | |
20 | * | |
420befb1 | 21 | * \author Anoop Saldanha <anoopsaldanha@gmail.com> |
ce019275 WM |
22 | * |
23 | * Debug filter utility functions | |
24 | */ | |
25 | ||
ecf86f9c | 26 | #include "suricata-common.h" |
157d5e81 AS |
27 | |
28 | /* both of these are defined in util-debug.c */ | |
29 | extern int sc_log_module_initialized; | |
30 | extern int sc_log_module_cleaned; | |
31 | ||
bc42aebd AS |
32 | /* used to indicate if any FG filters are registered */ |
33 | int sc_log_fg_filters_present = 0; | |
34 | ||
35 | /* used to indicate if any FD filters are registered */ | |
36 | int sc_log_fd_filters_present = 0; | |
37 | ||
157d5e81 AS |
38 | /** |
39 | * \brief Holds the fine-grained filters | |
40 | */ | |
3212a75c | 41 | SCLogFGFilterFile *sc_log_fg_filters[SC_LOG_FILTER_MAX] = { NULL, NULL }; |
157d5e81 AS |
42 | |
43 | /** | |
44 | * \brief Mutex for accessing the fine-grained fiters sc_log_fg_filters | |
45 | */ | |
5532af46 KS |
46 | static SCMutex sc_log_fg_filters_m[SC_LOG_FILTER_MAX] = { SCMUTEX_INITIALIZER, |
47 | SCMUTEX_INITIALIZER }; | |
157d5e81 AS |
48 | |
49 | /** | |
50 | * \brief Holds the function-dependent filters | |
51 | */ | |
52 | static SCLogFDFilter *sc_log_fd_filters = NULL; | |
53 | ||
54 | /** | |
55 | * \brief Mutex for accessing the function-dependent filters sc_log_fd_filters | |
56 | */ | |
5532af46 | 57 | static SCMutex sc_log_fd_filters_m = SCMUTEX_INITIALIZER; |
157d5e81 AS |
58 | |
59 | /** | |
60 | * \brief Holds the thread_list required by function-dependent filters | |
61 | */ | |
62 | static SCLogFDFilterThreadList *sc_log_fd_filters_tl = NULL; | |
63 | ||
64 | /** | |
65 | * \brief Mutex for accessing the FD thread_list sc_log_fd_filters_tl | |
66 | */ | |
5532af46 | 67 | static SCMutex sc_log_fd_filters_tl_m = SCMUTEX_INITIALIZER; |
157d5e81 | 68 | |
157d5e81 AS |
69 | /** |
70 | * \brief Helper function used internally to add a FG filter | |
71 | * | |
72 | * \param file File_name of the filter | |
73 | * \param function Function_name of the filter | |
74 | * \param line Line number of the filter | |
75 | * \param listtype The filter listtype. Can be either a blacklist or whitelist | |
76 | * filter listtype(SC_LOG_FILTER_BL or SC_LOG_FILTER_WL) | |
77 | * | |
78 | * \retval 0 on successfully adding the filter; | |
79 | * \retval -1 on failure | |
80 | */ | |
ab1200fb | 81 | static int SCLogAddFGFilter(const char *file, const char *function, |
157d5e81 AS |
82 | int line, int listtype) |
83 | { | |
84 | SCLogFGFilterFile *fgf_file = NULL; | |
85 | SCLogFGFilterFile *prev_fgf_file = NULL; | |
86 | ||
87 | SCLogFGFilterFunc *fgf_func = NULL; | |
88 | SCLogFGFilterFunc *prev_fgf_func = NULL; | |
89 | ||
90 | SCLogFGFilterLine *fgf_line = NULL; | |
91 | SCLogFGFilterLine *prev_fgf_line = NULL; | |
92 | ||
93 | int found = 0; | |
94 | ||
95 | if (sc_log_module_initialized != 1) { | |
96 | printf("Logging module not initialized. Call SCLogInitLogModule() " | |
97 | "first before using the debug API\n"); | |
98 | return -1 ; | |
99 | } | |
100 | ||
101 | if (file == NULL && function == NULL && line < 0) { | |
102 | printf("Error: Invalid arguments supplied to SCLogAddFGFilter\n"); | |
103 | return -1; | |
104 | } | |
105 | ||
e26833be | 106 | SCMutex *m = &sc_log_fg_filters_m[listtype]; |
769022f4 | 107 | |
e26833be | 108 | SCMutexLock(m); |
769022f4 | 109 | |
157d5e81 AS |
110 | fgf_file = sc_log_fg_filters[listtype]; |
111 | ||
112 | prev_fgf_file = fgf_file; | |
113 | while (fgf_file != NULL) { | |
114 | prev_fgf_file = fgf_file; | |
115 | if (file == NULL && fgf_file->file == NULL) | |
116 | found = 1; | |
117 | else if (file != NULL && fgf_file->file != NULL) | |
118 | found = (strcmp(file, fgf_file->file) == 0); | |
119 | else | |
120 | found = 0; | |
121 | ||
122 | if (found == 1) | |
123 | break; | |
124 | ||
125 | fgf_file = fgf_file->next; | |
126 | } | |
127 | ||
128 | if (found == 0) { | |
129 | SCLogAddToFGFFileList(prev_fgf_file, file, function, line, listtype); | |
130 | goto done; | |
131 | } | |
132 | ||
133 | found = 0; | |
134 | fgf_func = fgf_file->func; | |
135 | prev_fgf_func = fgf_func; | |
136 | while (fgf_func != NULL) { | |
137 | prev_fgf_func = fgf_func; | |
138 | if (function == NULL && fgf_func->func == NULL) | |
139 | found = 1; | |
140 | else if (function != NULL && fgf_func->func != NULL) | |
141 | found = (strcmp(function, fgf_func->func) == 0); | |
142 | else | |
143 | found = 0; | |
144 | ||
145 | if (found == 1) | |
146 | break; | |
147 | ||
148 | fgf_func = fgf_func->next; | |
149 | } | |
150 | ||
151 | if (found == 0) { | |
152 | SCLogAddToFGFFuncList(fgf_file, prev_fgf_func, function, line); | |
153 | goto done; | |
154 | } | |
155 | ||
156 | found = 0; | |
157 | fgf_line = fgf_func->line; | |
158 | prev_fgf_line = fgf_line; | |
159 | while(fgf_line != NULL) { | |
160 | prev_fgf_line = fgf_line; | |
161 | if (line == fgf_line->line) { | |
162 | found = 1; | |
163 | break; | |
164 | } | |
165 | ||
166 | fgf_line = fgf_line->next; | |
167 | } | |
168 | ||
169 | if (found == 0) { | |
170 | SCLogAddToFGFLineList(fgf_func, prev_fgf_line, line); | |
171 | goto done; | |
172 | } | |
173 | ||
174 | done: | |
e26833be | 175 | SCMutexUnlock(&sc_log_fg_filters_m[listtype]); |
bc42aebd AS |
176 | sc_log_fg_filters_present = 1; |
177 | ||
157d5e81 AS |
178 | return 0; |
179 | } | |
180 | ||
181 | /** | |
182 | * \brief Internal function used to check for matches against registered FG | |
183 | * filters. Checks if there is a match for the incoming log_message with | |
184 | * any of the FG filters. Based on whether the filter type is whitelist | |
185 | * or blacklist, the function allows the message to be logged or not. | |
186 | * | |
187 | * \param file File_name from where the log_message originated | |
188 | * \param function Function_name from where the log_message originated | |
189 | * \param line Line number from where the log_message originated | |
190 | * \param listtype The filter listtype. Can be either a blacklist or whitelist | |
191 | * filter listtype(SC_LOG_FILTER_BL or SC_LOG_FILTER_WL) | |
192 | * | |
193 | * \retval 1 if there is a match | |
194 | * \retval 0 on no match | |
195 | * \retval -1 on failure | |
196 | */ | |
197 | static int SCLogMatchFGFilter(const char *file, const char *function, int line, | |
198 | int listtype) | |
199 | { | |
200 | SCLogFGFilterFile *fgf_file = NULL; | |
201 | SCLogFGFilterFunc *fgf_func = NULL; | |
202 | SCLogFGFilterLine *fgf_line = NULL; | |
203 | int match = 1; | |
204 | ||
205 | if (sc_log_module_initialized != 1) { | |
206 | printf("Logging module not initialized. Call SCLogInitLogModule() " | |
207 | "first before using the debug API\n"); | |
208 | return -1; | |
209 | } | |
210 | ||
e26833be | 211 | SCMutexLock(&sc_log_fg_filters_m[listtype]); |
157d5e81 AS |
212 | |
213 | fgf_file = sc_log_fg_filters[listtype]; | |
214 | ||
215 | if (fgf_file == NULL) { | |
e26833be | 216 | SCMutexUnlock(&sc_log_fg_filters_m[listtype]); |
157d5e81 AS |
217 | return 1; |
218 | } | |
219 | ||
220 | while(fgf_file != NULL) { | |
221 | match = 1; | |
222 | ||
223 | match &= (fgf_file->file != NULL)? !strcmp(file, fgf_file->file): 1; | |
224 | ||
225 | if (match == 0) { | |
226 | fgf_file = fgf_file->next; | |
227 | continue; | |
228 | } | |
229 | ||
230 | fgf_func = fgf_file->func; | |
231 | while (fgf_func != NULL) { | |
232 | match = 1; | |
233 | ||
234 | match &= (fgf_func->func != NULL)? !strcmp(function, fgf_func->func): 1; | |
235 | ||
236 | if (match == 0) { | |
237 | fgf_func = fgf_func->next; | |
238 | continue; | |
239 | } | |
240 | ||
241 | fgf_line = fgf_func->line; | |
242 | while (fgf_line != NULL) { | |
243 | match = 1; | |
244 | ||
245 | match &= (fgf_line->line != -1)? (line == fgf_line->line): 1; | |
246 | ||
247 | if (match == 1) | |
248 | break; | |
249 | ||
250 | fgf_line = fgf_line->next; | |
251 | } | |
252 | ||
253 | if (match == 1) | |
254 | break; | |
255 | ||
256 | fgf_func = fgf_func->next; | |
257 | } | |
258 | ||
259 | if (match == 1) { | |
e26833be | 260 | SCMutexUnlock(&sc_log_fg_filters_m[listtype]); |
157d5e81 AS |
261 | if (listtype == SC_LOG_FILTER_WL) |
262 | return 1; | |
263 | else | |
264 | return 0; | |
265 | } | |
266 | ||
267 | fgf_file = fgf_file->next; | |
268 | } | |
269 | ||
e26833be | 270 | SCMutexUnlock(&sc_log_fg_filters_m[listtype]); |
157d5e81 AS |
271 | |
272 | if (listtype == SC_LOG_FILTER_WL) | |
273 | return 0; | |
274 | else | |
275 | return 1; | |
276 | } | |
277 | ||
278 | /** | |
279 | * \brief Checks if there is a match for the incoming log_message with any | |
280 | * of the FG filters. If there is a match, it allows the message | |
281 | * to be logged, else it rejects that message. | |
282 | * | |
283 | * \param file File_name from where the log_message originated | |
284 | * \param function Function_name from where the log_message originated | |
285 | * \param line Line number from where the log_message originated | |
286 | * | |
287 | * \retval 1 if there is a match | |
288 | * \retval 0 on no match | |
289 | * \retval -1 on failure | |
290 | */ | |
291 | int SCLogMatchFGFilterWL(const char *file, const char *function, int line) | |
292 | { | |
293 | return SCLogMatchFGFilter(file, function, line, SC_LOG_FILTER_WL); | |
294 | } | |
295 | ||
296 | /** | |
297 | * \brief Checks if there is a match for the incoming log_message with any | |
298 | * of the FG filters. If there is a match it rejects the logging | |
299 | * for that messages, else it allows that message to be logged | |
300 | * | |
301 | * \praram file File_name from where the log_message originated | |
302 | * \param function Function_name from where the log_message originated | |
303 | * \param line Line number from where the log_message originated | |
304 | * | |
305 | * \retval 1 if there is a match | |
306 | * \retval 0 on no match | |
307 | * \retval -1 on failure | |
308 | */ | |
309 | int SCLogMatchFGFilterBL(const char *file, const char *function, int line) | |
310 | { | |
311 | return SCLogMatchFGFilter(file, function, line, SC_LOG_FILTER_BL); | |
312 | } | |
313 | ||
314 | /** | |
315 | * \brief Adds a Whitelist(WL) fine-grained(FG) filter. A FG filter WL filter | |
316 | * allows messages that match this filter, to be logged, while the filter | |
317 | * is defined using a file_name, function_name and line_number. | |
318 | * | |
319 | * If a particular paramter in the fg-filter(file, function and line), | |
320 | * shouldn't be considered while logging the message, one can supply | |
321 | * NULL for the file_name or function_name and a negative line_no. | |
322 | * | |
323 | * \param file File_name of the filter | |
324 | * \param function Function_name of the filter | |
325 | * \param line Line number of the filter | |
326 | * | |
327 | * \retval 0 on successfully adding the filter; | |
328 | * \retval -1 on failure | |
329 | */ | |
330 | int SCLogAddFGFilterWL(const char *file, const char *function, int line) | |
331 | { | |
332 | return SCLogAddFGFilter(file, function, line, SC_LOG_FILTER_WL); | |
333 | } | |
334 | ||
335 | /** | |
336 | * \brief Adds a Blacklist(BL) fine-grained(FG) filter. A FG filter BL filter | |
337 | * allows messages that don't match this filter, to be logged, while the | |
338 | * filter is defined using a file_name, function_name and line_number | |
339 | * | |
340 | * If a particular paramter in the fg-filter(file, function and line), | |
341 | * shouldn't be considered while logging the message, one can supply | |
342 | * NULL for the file_name or function_name and a negative line_no. | |
343 | * | |
344 | * \param file File_name of the filter | |
345 | * \param function Function_name of the filter | |
346 | * \param line Line number of the filter | |
347 | * | |
348 | * \retval 0 on successfully adding the filter | |
349 | * \retval -1 on failure | |
350 | */ | |
351 | int SCLogAddFGFilterBL(const char *file, const char *function, int line) | |
352 | { | |
353 | return SCLogAddFGFilter(file, function, line, SC_LOG_FILTER_BL); | |
354 | } | |
355 | ||
356 | void SCLogReleaseFGFilters(void) | |
357 | { | |
358 | SCLogFGFilterFile *fgf_file = NULL; | |
359 | SCLogFGFilterFunc *fgf_func = NULL; | |
360 | SCLogFGFilterLine *fgf_line = NULL; | |
361 | ||
362 | void *temp = NULL; | |
363 | ||
364 | int i = 0; | |
365 | ||
366 | for (i = 0; i < SC_LOG_FILTER_MAX; i++) { | |
e26833be | 367 | SCMutexLock(&sc_log_fg_filters_m[i]); |
157d5e81 AS |
368 | |
369 | fgf_file = sc_log_fg_filters[i]; | |
370 | while (fgf_file != NULL) { | |
371 | ||
372 | fgf_func = fgf_file->func; | |
373 | while (fgf_func != NULL) { | |
374 | ||
375 | fgf_line = fgf_func->line; | |
376 | while(fgf_line != NULL) { | |
377 | temp = fgf_line; | |
378 | fgf_line = fgf_line->next; | |
25a3a5c6 | 379 | SCFree(temp); |
157d5e81 AS |
380 | } |
381 | ||
382 | if (fgf_func->func != NULL) | |
25a3a5c6 | 383 | SCFree(fgf_func->func); |
157d5e81 AS |
384 | temp = fgf_func; |
385 | fgf_func = fgf_func->next; | |
25a3a5c6 | 386 | SCFree(temp); |
157d5e81 AS |
387 | } |
388 | ||
389 | if (fgf_file->file != NULL) | |
25a3a5c6 | 390 | SCFree(fgf_file->file); |
157d5e81 AS |
391 | temp = fgf_file; |
392 | fgf_file = fgf_file->next; | |
25a3a5c6 | 393 | SCFree(temp); |
157d5e81 AS |
394 | } |
395 | ||
e26833be | 396 | SCMutexUnlock(&sc_log_fg_filters_m[i]); |
157d5e81 AS |
397 | sc_log_fg_filters[i] = NULL; |
398 | } | |
399 | ||
400 | return; | |
401 | } | |
402 | ||
403 | /** | |
404 | * \brief Prints the FG filters(both WL and BL). Used for debugging purposes. | |
405 | * | |
406 | * \retval count The no of FG filters | |
407 | */ | |
408 | int SCLogPrintFGFilters() | |
409 | { | |
410 | SCLogFGFilterFile *fgf_file = NULL; | |
411 | SCLogFGFilterFunc *fgf_func = NULL; | |
412 | SCLogFGFilterLine *fgf_line = NULL; | |
413 | ||
414 | int count = 0; | |
415 | int i = 0; | |
416 | ||
417 | if (sc_log_module_initialized != 1) { | |
418 | printf("Logging module not initialized. Call SCLogInitLogModule() " | |
419 | "first before using the debug API\n"); | |
420 | return 0; | |
421 | } | |
422 | ||
423 | #ifdef DEBUG | |
424 | printf("Fine grained filters:\n"); | |
425 | #endif | |
426 | ||
427 | for (i = 0; i < SC_LOG_FILTER_MAX; i++) { | |
e26833be | 428 | SCMutexLock(&sc_log_fg_filters_m[i]); |
157d5e81 AS |
429 | |
430 | fgf_file = sc_log_fg_filters[i]; | |
431 | while (fgf_file != NULL) { | |
432 | ||
433 | fgf_func = fgf_file->func; | |
434 | while (fgf_func != NULL) { | |
435 | ||
436 | fgf_line = fgf_func->line; | |
437 | while(fgf_line != NULL) { | |
438 | #ifdef DEBUG | |
439 | printf("%s - ", fgf_file->file); | |
440 | printf("%s - ", fgf_func->func); | |
441 | printf("%d\n", fgf_line->line); | |
442 | #endif | |
443 | ||
444 | count++; | |
445 | ||
446 | fgf_line = fgf_line->next; | |
447 | } | |
448 | ||
449 | fgf_func = fgf_func->next; | |
450 | } | |
451 | ||
452 | fgf_file = fgf_file->next; | |
453 | } | |
e26833be | 454 | SCMutexUnlock(&sc_log_fg_filters_m[i]); |
157d5e81 AS |
455 | } |
456 | ||
457 | return count; | |
458 | } | |
459 | ||
460 | ||
461 | ||
462 | /* --------------------------------------------------|-------------------------- | |
463 | * -------------------------- Code for the FD Filter |-------------------------- | |
464 | * --------------------------------------------------V-------------------------- | |
465 | */ | |
466 | ||
157d5e81 AS |
467 | /** |
468 | * \brief Checks if there is a match for the incoming log_message with any | |
469 | * of the FD filters | |
470 | * | |
471 | * \param function Function_name from where the log_message originated | |
472 | * | |
473 | * \retval 1 if there is a match | |
474 | * \retval 0 on no match; | |
475 | */ | |
476 | int SCLogMatchFDFilter(const char *function) | |
477 | { | |
c4b34e6e VJ |
478 | #ifndef DEBUG |
479 | return 1; | |
480 | #else | |
157d5e81 AS |
481 | SCLogFDFilterThreadList *thread_list = NULL; |
482 | ||
b7bac140 | 483 | pthread_t self = pthread_self(); |
157d5e81 | 484 | |
157d5e81 AS |
485 | if (sc_log_module_initialized != 1) { |
486 | printf("Logging module not initialized. Call SCLogInitLogModule() " | |
487 | "first before using the debug API\n"); | |
488 | return 0; | |
489 | } | |
490 | ||
e26833be | 491 | SCMutexLock(&sc_log_fd_filters_tl_m); |
157d5e81 AS |
492 | |
493 | if (sc_log_fd_filters_tl == NULL) { | |
e26833be | 494 | SCMutexUnlock(&sc_log_fd_filters_tl_m); |
157d5e81 AS |
495 | if (sc_log_fd_filters != NULL) |
496 | return 0; | |
497 | return 1; | |
498 | } | |
499 | ||
500 | thread_list = sc_log_fd_filters_tl; | |
501 | while (thread_list != NULL) { | |
b7bac140 | 502 | if (pthread_equal(self, thread_list->t)) { |
157d5e81 | 503 | if (thread_list->entered > 0) { |
e26833be | 504 | SCMutexUnlock(&sc_log_fd_filters_tl_m); |
157d5e81 AS |
505 | return 1; |
506 | } | |
e26833be | 507 | SCMutexUnlock(&sc_log_fd_filters_tl_m); |
157d5e81 AS |
508 | return 0; |
509 | } | |
510 | ||
511 | thread_list = thread_list->next; | |
512 | } | |
513 | ||
e26833be | 514 | SCMutexUnlock(&sc_log_fd_filters_tl_m); |
157d5e81 AS |
515 | |
516 | return 0; | |
c4b34e6e | 517 | #endif |
157d5e81 AS |
518 | } |
519 | ||
520 | /** | |
521 | * \brief Updates a FD filter, based on whether the function that calls this | |
522 | * function, is registered as a FD filter or not. This is called by | |
523 | * a function only on its entry | |
524 | * | |
525 | * \param function Function_name from where the log_message originated | |
526 | * | |
527 | * \retval 1 Since it is a hack to get things working inside the macros | |
528 | */ | |
529 | int SCLogCheckFDFilterEntry(const char *function) | |
530 | { | |
531 | SCLogFDFilter *curr = NULL; | |
532 | ||
533 | SCLogFDFilterThreadList *thread_list = NULL; | |
157d5e81 AS |
534 | SCLogFDFilterThreadList *thread_list_temp = NULL; |
535 | ||
b7bac140 VJ |
536 | //pid_t self = syscall(SYS_gettid); |
537 | pthread_t self = pthread_self(); | |
157d5e81 AS |
538 | |
539 | if (sc_log_module_initialized != 1) { | |
540 | printf("Logging module not initialized. Call SCLogInitLogModule() " | |
541 | "first before using the debug API\n"); | |
542 | return 0; | |
543 | } | |
544 | ||
e26833be | 545 | SCMutexLock(&sc_log_fd_filters_m); |
157d5e81 AS |
546 | |
547 | curr = sc_log_fd_filters; | |
548 | ||
549 | while (curr != NULL) { | |
550 | if (strcmp(function, curr->func) == 0) | |
551 | break; | |
552 | ||
553 | curr = curr->next; | |
554 | } | |
555 | ||
556 | if (curr == NULL) { | |
e26833be | 557 | SCMutexUnlock(&sc_log_fd_filters_m); |
157d5e81 AS |
558 | return 1; |
559 | } | |
560 | ||
e26833be | 561 | SCMutexUnlock(&sc_log_fd_filters_m); |
157d5e81 | 562 | |
e26833be | 563 | SCMutexLock(&sc_log_fd_filters_tl_m); |
157d5e81 AS |
564 | |
565 | thread_list = sc_log_fd_filters_tl; | |
157d5e81 | 566 | while (thread_list != NULL) { |
b7bac140 | 567 | if (pthread_equal(self, thread_list->t)) |
157d5e81 AS |
568 | break; |
569 | ||
570 | thread_list = thread_list->next; | |
571 | } | |
572 | ||
573 | if (thread_list != NULL) { | |
574 | thread_list->entered++; | |
e26833be | 575 | SCMutexUnlock(&sc_log_fd_filters_tl_m); |
157d5e81 AS |
576 | return 1; |
577 | } | |
578 | ||
bff2866a AS |
579 | if ( (thread_list_temp = SCMalloc(sizeof(SCLogFDFilterThreadList))) == NULL) { |
580 | SCMutexUnlock(&sc_log_fd_filters_tl_m); | |
9f4fae5b | 581 | return 0; |
bff2866a | 582 | } |
157d5e81 AS |
583 | memset(thread_list_temp, 0, sizeof(SCLogFDFilterThreadList)); |
584 | ||
585 | thread_list_temp->t = self; | |
586 | thread_list_temp->entered++; | |
587 | ||
f862de2e | 588 | sc_log_fd_filters_tl = thread_list_temp; |
157d5e81 | 589 | |
e26833be | 590 | SCMutexUnlock(&sc_log_fd_filters_tl_m); |
157d5e81 AS |
591 | |
592 | return 1; | |
593 | } | |
594 | ||
595 | /** | |
596 | * \brief Updates a FD filter, based on whether the function that calls this | |
597 | * function, is registered as a FD filter or not. This is called by | |
598 | * a function only before its exit. | |
599 | * | |
600 | * \param function Function_name from where the log_message originated | |
601 | * | |
602 | */ | |
603 | void SCLogCheckFDFilterExit(const char *function) | |
604 | { | |
605 | SCLogFDFilter *curr = NULL; | |
606 | ||
607 | SCLogFDFilterThreadList *thread_list = NULL; | |
608 | ||
b7bac140 VJ |
609 | //pid_t self = syscall(SYS_gettid); |
610 | pthread_t self = pthread_self(); | |
157d5e81 AS |
611 | |
612 | if (sc_log_module_initialized != 1) { | |
613 | printf("Logging module not initialized. Call SCLogInitLogModule() " | |
614 | "first before using the debug API\n"); | |
615 | return; | |
616 | } | |
617 | ||
e26833be | 618 | SCMutexLock(&sc_log_fd_filters_m); |
157d5e81 AS |
619 | |
620 | curr = sc_log_fd_filters; | |
621 | ||
622 | while (curr != NULL) { | |
623 | if (strcmp(function, curr->func) == 0) | |
624 | break; | |
625 | ||
626 | curr = curr->next; | |
627 | } | |
628 | ||
629 | if (curr == NULL) { | |
e26833be | 630 | SCMutexUnlock(&sc_log_fd_filters_m); |
157d5e81 AS |
631 | return; |
632 | } | |
633 | ||
e26833be | 634 | SCMutexUnlock(&sc_log_fd_filters_m); |
157d5e81 | 635 | |
e26833be | 636 | SCMutexLock(&sc_log_fd_filters_tl_m); |
157d5e81 AS |
637 | |
638 | thread_list = sc_log_fd_filters_tl; | |
639 | while (thread_list != NULL) { | |
b7bac140 | 640 | if (pthread_equal(self, thread_list->t)) |
157d5e81 AS |
641 | break; |
642 | ||
643 | thread_list = thread_list->next; | |
644 | } | |
645 | ||
e26833be | 646 | SCMutexUnlock(&sc_log_fd_filters_tl_m); |
157d5e81 | 647 | |
69a4fee7 GS |
648 | if (thread_list != NULL) |
649 | thread_list->entered--; | |
157d5e81 AS |
650 | |
651 | return; | |
652 | } | |
653 | ||
654 | /** | |
655 | * \brief Adds a Function-Dependent(FD) filter | |
656 | * | |
657 | * \param Name of the function for which a FD filter has to be registered | |
658 | * | |
659 | * \retval 0 on success | |
660 | * \retval -1 on failure | |
661 | */ | |
662 | int SCLogAddFDFilter(const char *function) | |
663 | { | |
664 | SCLogFDFilter *curr = NULL; | |
665 | SCLogFDFilter *prev = NULL; | |
666 | SCLogFDFilter *temp = NULL; | |
667 | ||
668 | if (sc_log_module_initialized != 1) { | |
669 | printf("Logging module not initialized. Call SCLogInitLogModule() " | |
670 | "first before using the debug API\n"); | |
671 | return -1; | |
672 | } | |
673 | ||
674 | if (function == NULL) { | |
675 | printf("Invalid argument supplied to SCLogAddFDFilter\n"); | |
676 | return -1; | |
677 | } | |
678 | ||
e26833be | 679 | SCMutexLock(&sc_log_fd_filters_m); |
157d5e81 AS |
680 | |
681 | curr = sc_log_fd_filters; | |
682 | while (curr != NULL) { | |
683 | prev = curr; | |
684 | ||
685 | if (strcmp(function, curr->func) == 0) { | |
769022f4 | 686 | |
e26833be | 687 | SCMutexUnlock(&sc_log_fd_filters_m); |
157d5e81 AS |
688 | return 0; |
689 | } | |
690 | ||
691 | curr = curr->next; | |
692 | } | |
693 | ||
2c6f9aba VJ |
694 | if ( (temp = SCMalloc(sizeof(SCLogFDFilter))) == NULL) { |
695 | printf("Error Allocating memory (SCMalloc)\n"); | |
696 | exit(EXIT_FAILURE); | |
697 | } | |
157d5e81 AS |
698 | memset(temp, 0, sizeof(SCLogFDFilter)); |
699 | ||
25a3a5c6 | 700 | if ( (temp->func = SCStrdup(function)) == NULL) { |
2c6f9aba | 701 | printf("Error Allocating memory (SCStrdup)\n"); |
157d5e81 AS |
702 | exit(EXIT_FAILURE); |
703 | } | |
704 | ||
f862de2e PR |
705 | if (sc_log_fd_filters == NULL) |
706 | sc_log_fd_filters = temp; | |
2c6f9aba VJ |
707 | /* clang thinks prev can be NULL, but it can't be unless |
708 | * sc_log_fd_filters is also NULL which is handled here. | |
709 | * Doing this "fix" to shut clang up. */ | |
710 | else if (prev != NULL) | |
f862de2e | 711 | prev->next = temp; |
157d5e81 | 712 | |
e26833be | 713 | SCMutexUnlock(&sc_log_fd_filters_m); |
bc42aebd | 714 | sc_log_fd_filters_present = 1; |
157d5e81 AS |
715 | |
716 | return 0; | |
717 | } | |
718 | ||
719 | /** | |
720 | * \brief Releases all the FD filters added to the logging module | |
721 | */ | |
722 | void SCLogReleaseFDFilters(void) | |
723 | { | |
724 | SCLogFDFilter *fdf = NULL; | |
725 | SCLogFDFilter *temp = NULL; | |
726 | ||
e26833be | 727 | SCMutexLock(&sc_log_fd_filters_m); |
157d5e81 AS |
728 | |
729 | fdf = sc_log_fd_filters; | |
730 | while (fdf != NULL) { | |
731 | temp = fdf; | |
732 | fdf = fdf->next; | |
733 | SCLogReleaseFDFilter(temp); | |
734 | } | |
735 | ||
736 | sc_log_fd_filters = NULL; | |
737 | ||
e26833be | 738 | SCMutexUnlock( &sc_log_fd_filters_m ); |
157d5e81 AS |
739 | |
740 | return; | |
741 | } | |
742 | ||
743 | /** | |
744 | * \brief Removes a Function-Dependent(FD) filter | |
745 | * | |
746 | * \param Name of the function for which a FD filter has to be unregistered | |
747 | * | |
748 | * \retval 0 on success(the filter was removed or the filter was not present) | |
749 | * \retval -1 on failure/error | |
750 | */ | |
751 | int SCLogRemoveFDFilter(const char *function) | |
752 | { | |
753 | SCLogFDFilter *curr = NULL; | |
754 | SCLogFDFilter *prev = NULL; | |
755 | ||
756 | if (sc_log_module_initialized != 1) { | |
757 | printf("Logging module not initialized. Call SCLogInitLogModule() " | |
758 | "first before using the debug API\n"); | |
759 | return -1 ; | |
760 | } | |
761 | ||
762 | if (function == NULL) { | |
763 | printf("Invalid argument(s) supplied to SCLogRemoveFDFilter\n"); | |
764 | return -1; | |
765 | } | |
766 | ||
e26833be | 767 | SCMutexLock(&sc_log_fd_filters_m); |
157d5e81 AS |
768 | |
769 | if (sc_log_fd_filters == NULL) { | |
e26833be | 770 | SCMutexUnlock(&sc_log_fd_filters_m); |
157d5e81 AS |
771 | return 0; |
772 | } | |
773 | ||
774 | curr = sc_log_fd_filters; | |
775 | prev = curr; | |
776 | while (curr != NULL) { | |
777 | if (strcmp(function, curr->func) == 0) | |
778 | break; | |
779 | ||
780 | prev = curr; | |
781 | curr = curr->next; | |
782 | } | |
783 | ||
784 | if (curr == NULL) { | |
769022f4 | 785 | |
e26833be | 786 | SCMutexUnlock(&sc_log_fd_filters_m); |
769022f4 | 787 | |
157d5e81 AS |
788 | return 0; |
789 | } | |
790 | ||
791 | if (sc_log_fd_filters == curr) | |
792 | sc_log_fd_filters = curr->next; | |
793 | else | |
794 | prev->next = curr->next; | |
795 | ||
796 | SCLogReleaseFDFilter(curr); | |
797 | ||
e26833be | 798 | SCMutexUnlock(&sc_log_fd_filters_m); |
157d5e81 | 799 | |
bc42aebd AS |
800 | if (sc_log_fd_filters == NULL) |
801 | sc_log_fd_filters_present = 0; | |
802 | ||
157d5e81 AS |
803 | return 0; |
804 | } | |
805 | ||
806 | /** | |
807 | * \brief Prints the FG filters(both WL and BL). Used for debugging purposes. | |
808 | * | |
809 | * \retval count The no of FG filters | |
810 | */ | |
811 | int SCLogPrintFDFilters(void) | |
812 | { | |
813 | SCLogFDFilter *fdf = NULL; | |
814 | int count = 0; | |
815 | ||
816 | if (sc_log_module_initialized != 1) { | |
817 | printf("Logging module not initialized. Call SCLogInitLogModule() " | |
818 | "first before using the debug API\n"); | |
819 | return 0; | |
820 | } | |
821 | ||
822 | #ifdef DEBUG | |
823 | printf("FD filters:\n"); | |
824 | #endif | |
825 | ||
2d16abcf | 826 | SCMutexLock(&sc_log_fd_filters_m); |
157d5e81 AS |
827 | |
828 | fdf = sc_log_fd_filters; | |
829 | while (fdf != NULL) { | |
830 | #ifdef DEBUG | |
831 | printf("%s \n", fdf->func); | |
832 | #endif | |
833 | fdf = fdf->next; | |
834 | count++; | |
835 | } | |
836 | ||
2d16abcf | 837 | SCMutexUnlock(&sc_log_fd_filters_m); |
157d5e81 AS |
838 | |
839 | return count; | |
840 | } | |
3212a75c PR |
841 | |
842 | /** | |
843 | * \brief Helper function used internally to add a FG filter. This function is | |
844 | * called when the file component of the incoming filter has no entry | |
845 | * in the filter list. | |
846 | * | |
847 | * \param fgf_file The file component(basically the position in the list) from | |
848 | * the filter list, after which the new filter has to be added | |
849 | * \param file File_name of the filter | |
850 | * \param function Function_name of the filter | |
851 | * \param line Line number of the filter | |
852 | * \param listtype The filter listtype. Can be either a blacklist or whitelist | |
853 | * filter listtype(SC_LOG_FILTER_BL or SC_LOG_FILTER_WL) | |
854 | */ | |
855 | void SCLogAddToFGFFileList(SCLogFGFilterFile *fgf_file, | |
856 | const char *file, | |
857 | const char *function, int line, | |
858 | int listtype) | |
859 | { | |
860 | SCLogFGFilterFile *fgf_file_temp = NULL; | |
861 | SCLogFGFilterFunc *fgf_func_temp = NULL; | |
862 | SCLogFGFilterLine *fgf_line_temp = NULL; | |
863 | ||
864 | if ( (fgf_file_temp = SCMalloc(sizeof(SCLogFGFilterFile))) == NULL) { | |
6f7d8e50 SB |
865 | FatalError(SC_ERR_FATAL, |
866 | "Fatal error encountered in SCLogAddToFGFFileList. Exiting..."); | |
3212a75c PR |
867 | } |
868 | memset(fgf_file_temp, 0, sizeof(SCLogFGFilterFile)); | |
869 | ||
870 | if ( file != NULL && (fgf_file_temp->file = SCStrdup(file)) == NULL) { | |
871 | printf("Error Allocating memory\n"); | |
872 | exit(EXIT_FAILURE); | |
873 | } | |
874 | ||
875 | if ( (fgf_func_temp = SCMalloc(sizeof(SCLogFGFilterFunc))) == NULL) { | |
6f7d8e50 SB |
876 | FatalError(SC_ERR_FATAL, |
877 | "Fatal error encountered in SCLogAddToFGFFileList. Exiting..."); | |
3212a75c PR |
878 | } |
879 | memset(fgf_func_temp, 0, sizeof(SCLogFGFilterFunc)); | |
880 | ||
881 | if ( function != NULL && (fgf_func_temp->func = SCStrdup(function)) == NULL) { | |
882 | printf("Error Allocating memory\n"); | |
883 | exit(EXIT_FAILURE); | |
884 | } | |
885 | ||
886 | if ( (fgf_line_temp = SCMalloc(sizeof(SCLogFGFilterLine))) == NULL) { | |
6f7d8e50 SB |
887 | FatalError(SC_ERR_FATAL, |
888 | "Fatal error encountered in SCLogAddToFGFFileList. Exiting..."); | |
3212a75c PR |
889 | } |
890 | memset(fgf_line_temp, 0, sizeof(SCLogFGFilterLine)); | |
891 | ||
892 | fgf_line_temp->line = line; | |
893 | ||
894 | /* add to the lists */ | |
895 | fgf_func_temp->line = fgf_line_temp; | |
896 | ||
897 | fgf_file_temp->func = fgf_func_temp; | |
898 | ||
899 | if (fgf_file == NULL) | |
900 | sc_log_fg_filters[listtype] = fgf_file_temp; | |
901 | else | |
902 | fgf_file->next = fgf_file_temp; | |
903 | ||
904 | return; | |
905 | } | |
906 | ||
907 | /** | |
908 | * \brief Helper function used internally to add a FG filter. This function is | |
909 | * called when the file component of the incoming filter has an entry | |
910 | * in the filter list, but the function component doesn't have an entry | |
911 | * for the corresponding file component | |
912 | * | |
913 | * \param fgf_file The file component from the filter list to which the new | |
914 | * filter has to be added | |
915 | * \param fgf_func The function component(basically the position in the list), | |
916 | * from the filter list, after which the new filter has to be | |
917 | * added | |
918 | * \param function Function_name of the filter | |
919 | * \param line Line number of the filter | |
920 | */ | |
921 | void SCLogAddToFGFFuncList(SCLogFGFilterFile *fgf_file, | |
922 | SCLogFGFilterFunc *fgf_func, | |
923 | const char *function, int line) | |
924 | { | |
925 | SCLogFGFilterFunc *fgf_func_temp = NULL; | |
926 | SCLogFGFilterLine *fgf_line_temp = NULL; | |
927 | ||
928 | if ( (fgf_func_temp = SCMalloc(sizeof(SCLogFGFilterFunc))) == NULL) { | |
6f7d8e50 SB |
929 | FatalError(SC_ERR_FATAL, |
930 | "Fatal error encountered in SCLogAddToFGFFuncList. Exiting..."); | |
3212a75c PR |
931 | } |
932 | memset(fgf_func_temp, 0, sizeof(SCLogFGFilterFunc)); | |
933 | ||
934 | if ( function != NULL && (fgf_func_temp->func = SCStrdup(function)) == NULL) { | |
935 | printf("Error Allocating memory\n"); | |
936 | exit(EXIT_FAILURE); | |
937 | } | |
938 | ||
939 | if ( (fgf_line_temp = SCMalloc(sizeof(SCLogFGFilterLine))) == NULL) { | |
6f7d8e50 SB |
940 | FatalError(SC_ERR_FATAL, |
941 | "Fatal error encountered in SCLogAddToFGFFuncList. Exiting..."); | |
3212a75c PR |
942 | } |
943 | memset(fgf_line_temp, 0, sizeof(SCLogFGFilterLine)); | |
944 | ||
945 | fgf_line_temp->line = line; | |
946 | ||
947 | /* add to the lists */ | |
948 | fgf_func_temp->line = fgf_line_temp; | |
949 | ||
950 | if (fgf_func == NULL) | |
951 | fgf_file->func = fgf_func_temp; | |
952 | else | |
953 | fgf_func->next = fgf_func_temp; | |
954 | ||
955 | return; | |
956 | } | |
957 | ||
958 | /** | |
959 | * \brief Helper function used internally to add a FG filter. This function is | |
960 | * called when the file and function components of the incoming filter | |
961 | * have an entry in the filter list, but the line component doesn't have | |
962 | * an entry for the corresponding function component | |
963 | * | |
964 | * \param fgf_func The function component from the filter list to which the new | |
965 | * filter has to be added | |
966 | * \param fgf_line The function component(basically the position in the list), | |
967 | * from the filter list, after which the new filter has to be | |
968 | * added | |
969 | * \param line Line number of the filter | |
970 | */ | |
971 | void SCLogAddToFGFLineList(SCLogFGFilterFunc *fgf_func, | |
972 | SCLogFGFilterLine *fgf_line, | |
973 | int line) | |
974 | { | |
975 | SCLogFGFilterLine *fgf_line_temp = NULL; | |
976 | ||
977 | if ( (fgf_line_temp = SCMalloc(sizeof(SCLogFGFilterLine))) == NULL) { | |
6f7d8e50 SB |
978 | FatalError(SC_ERR_FATAL, |
979 | "Fatal error encountered in SCLogAddToFGFLineList. Exiting..."); | |
3212a75c PR |
980 | } |
981 | memset(fgf_line_temp, 0, sizeof(SCLogFGFilterLine)); | |
982 | ||
983 | fgf_line_temp->line = line; | |
984 | ||
985 | /* add to the lists */ | |
986 | if (fgf_line == NULL) | |
987 | fgf_func->line = fgf_line_temp; | |
988 | else | |
989 | fgf_line->next = fgf_line_temp; | |
990 | ||
991 | return; | |
992 | } | |
993 | ||
994 | /** | |
995 | * \brief Releases the memory alloted to a FD filter | |
996 | * | |
997 | * \param Pointer to the FD filter that has to be freed | |
998 | */ | |
999 | void SCLogReleaseFDFilter(SCLogFDFilter *fdf) | |
1000 | { | |
1001 | if (fdf != NULL) { | |
1002 | if (fdf->func != NULL) | |
1003 | SCFree(fdf->func); | |
1004 | SCFree(fdf); | |
1005 | } | |
1006 | ||
1007 | return; | |
1008 | } | |
1009 |