Browse Source

* refactor filter modules for new library interface

master
Alex 'AdUser' Z 4 years ago
parent
commit
d18b383cac
  1. 36
      src/filters/filter.c
  2. 35
      src/filters/filter.h
  3. 26
      src/filters/pcre.c
  4. 24
      src/filters/preg.c

36
src/filters/filter.c

@ -0,0 +1,36 @@
/* Copyright 2016 Alex 'AdUser' Z (ad_user@runbox.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
static void
logcb_stub(enum loglevel lvl, const char *str) {
assert(str != NULL);
(void)(lvl);
(void)(str);
}
__attribute__ ((format (printf, 3, 4)))
static void
log_msg(const cfg_t *cfg, enum loglevel lvl, const char *format, ...) {
char buf[4096] = "";
va_list args;
size_t len;
len = snprintf(buf, sizeof(buf), "filter/%s ", MODNAME);
va_start(args, format);
vsnprintf(buf + len, sizeof(buf) - len, format, args);
va_end(args);
cfg->logcb(lvl, buf);
}
void
logcb(cfg_t *cfg, void (*cb)(enum loglevel lvl, const char *msg)) {
assert(cfg != NULL);
assert(cb != NULL);
cfg->logcb = cb;
}

35
src/filters/filter.h

@ -11,10 +11,20 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include <string.h> #include <string.h>
#include "../strlcpy.h" #include "../strlcpy.h"
enum loglevel {
debug = 0,
info = 1,
notice = 2,
warn = 3,
error = 4,
fatal = 5,
}; /* see log.h */
/** /**
* @file * @file
* This header describes module API of type 'filter' * This header describes module API of type 'filter'
@ -31,16 +41,14 @@
* f2b => filter [label="config(cfg, param, value)"]; * f2b => filter [label="config(cfg, param, value)"];
* f2b << filter [label="true"]; * f2b << filter [label="true"];
* f2b => filter [label="config(cfg, param, value)"]; * f2b => filter [label="config(cfg, param, value)"];
* f2b <<= filter [label="logcb(level, char *msg)"];
* f2b << filter [label="false"]; * f2b << filter [label="false"];
* f2b => filter [label="error(cfg)"];
* f2b << filter [label="const char *error"];
* --- [label="filter is ready for append()"]; * --- [label="filter is ready for append()"];
* f2b => filter [label="append(cfg, pattern)"]; * f2b => filter [label="append(cfg, pattern)"];
* f2b << filter [label="true"]; * f2b << filter [label="true"];
* f2b => filter [label="append(cfg, pattern)"]; * f2b => filter [label="append(cfg, pattern)"];
* f2b <<= filter [label="logcb(level, char *msg)"];
* f2b << filter [label="false"]; * f2b << filter [label="false"];
* f2b => filter [label="error(cfg)"];
* f2b << filter [label="const char *error"];
* ||| [label="more calls of append()"]; * ||| [label="more calls of append()"];
* f2b => filter [label="ready(cfg)"]; * f2b => filter [label="ready(cfg)"];
* f2b << filter [label="true"]; * f2b << filter [label="true"];
@ -92,27 +100,19 @@ typedef struct _config cfg_t;
* @returns Opaque module handler or NULL on failure * @returns Opaque module handler or NULL on failure
*/ */
extern cfg_t *create(const char *id); extern cfg_t *create(const char *id);
/**
* @brief Returns last error description
* @param cfg Module handler
* @returns Pointer to string with description of last error
* @note Returned pointer not marked with const, because libdl complains,
* but contents on pointer should not be modified or written in any way
*/
extern const char *error(cfg_t *cfg);
/** /**
* @brief Contigure module instance * @brief Contigure module instance
* @param cfg Module handler * @param cfg Module handler
* @param key Parameter name * @param key Parameter name
* @param value Parameter value * @param value Parameter value
* @returns true on success, false on error with setting intenal error buffer * @returns true on success, false on error
*/ */
extern bool config(cfg_t *cfg, const char *key, const char *value); extern bool config(cfg_t *cfg, const char *key, const char *value);
/** /**
* @brief Add match pattern * @brief Add match pattern
* @param cfg Module handler * @param cfg Module handler
* @param pattern Regex expression * @param pattern Regex expression
* @returns true on success, false on error with setting intenal error buffer * @returns true on success, false on error
*/ */
extern bool append(cfg_t *cfg, const char *pattern); extern bool append(cfg_t *cfg, const char *pattern);
/** /**
@ -121,6 +121,13 @@ extern bool append(cfg_t *cfg, const char *pattern);
* @returns true if ready, false if not * @returns true if ready, false if not
*/ */
extern bool ready(cfg_t *cfg); extern bool ready(cfg_t *cfg);
/**
* @brief Sets the log callback
* @param cfg Module handler
* @param cb Logging callback
* @note Optional, if this function is not called, warnings/errors of module will be suppressed
*/
extern void logcb(cfg_t *cfg, void (*cb)(enum loglevel l, const char *msg));
/** /**
* @brief Fetch match stats by-pattern * @brief Fetch match stats by-pattern
* @param cfg Module handler * @param cfg Module handler

26
src/filters/pcre.c

@ -4,10 +4,10 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include "filter.h"
#include <pcre.h> #include <pcre.h>
#include "filter.h"
#define MODNAME "pcre"
#define HOST_REGEX "(?<host>[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})" #define HOST_REGEX "(?<host>[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})"
typedef struct f2b_regex_t { typedef struct f2b_regex_t {
@ -20,7 +20,7 @@ typedef struct f2b_regex_t {
struct _config { struct _config {
char id[ID_MAX]; char id[ID_MAX];
char error[256]; void (*logcb)(enum loglevel lvl, const char *msg);
bool icase; bool icase;
bool study; bool study;
bool usejit; bool usejit;
@ -28,6 +28,8 @@ struct _config {
f2b_regex_t *statp; f2b_regex_t *statp;
}; };
#include "filter.c"
cfg_t * cfg_t *
create(const char *id) { create(const char *id) {
cfg_t *cfg = NULL; cfg_t *cfg = NULL;
@ -36,6 +38,7 @@ create(const char *id) {
return NULL; return NULL;
strlcpy(cfg->id, id, sizeof(cfg->id)); strlcpy(cfg->id, id, sizeof(cfg->id));
cfg->logcb = &logcb_stub;
return cfg; return cfg;
} }
@ -58,7 +61,7 @@ config(cfg_t *cfg, const char *key, const char *value) {
#ifndef PCRE_CONFIG_JIT #ifndef PCRE_CONFIG_JIT
if (cfg->usejit) { if (cfg->usejit) {
cfg->usejit = false; cfg->usejit = false;
strlcpy(cfg->error, "seems like your pcre library doesn't support jit") log_msg(cfg, error, "seems like your pcre library doesn't support jit");
return false; return false;
} }
#endif #endif
@ -99,7 +102,7 @@ append(cfg_t *cfg, const char *pattern) {
return false; return false;
if ((regex->regex = pcre_compile(buf, flags, &errptr, &erroffset, NULL)) == NULL) { if ((regex->regex = pcre_compile(buf, flags, &errptr, &erroffset, NULL)) == NULL) {
snprintf(cfg->error, sizeof(cfg->error), "regex compilation failed at %d: %s", erroffset, errptr); log_msg(cfg, error, "regex compilation failed at %d: %s", erroffset, errptr);
free(regex); free(regex);
return false; return false;
} }
@ -111,7 +114,7 @@ append(cfg_t *cfg, const char *pattern) {
flags |= PCRE_STUDY_JIT_COMPILE; flags |= PCRE_STUDY_JIT_COMPILE;
#endif #endif
if ((regex->data = pcre_study(regex->regex, 0, &errptr)) == NULL) { if ((regex->data = pcre_study(regex->regex, 0, &errptr)) == NULL) {
snprintf(cfg->error, sizeof(cfg->error), "regex learn failed: %s", errptr); log_msg(cfg, error, "regex learn failed: %s", errptr);
pcre_free(regex->regex); pcre_free(regex->regex);
free(regex); free(regex);
return false; return false;
@ -149,13 +152,6 @@ stats(cfg_t *cfg, int *matches, char **pattern, bool reset) {
return false; return false;
} }
const char *
error(cfg_t *cfg) {
assert(cfg != NULL);
return cfg->error;
}
bool bool
match(cfg_t *cfg, const char *line, char *buf, size_t buf_size) { match(cfg_t *cfg, const char *line, char *buf, size_t buf_size) {
f2b_regex_t *r = NULL; f2b_regex_t *r = NULL;
@ -173,7 +169,7 @@ match(cfg_t *cfg, const char *line, char *buf, size_t buf_size) {
if (rc < 0 && rc == PCRE_ERROR_NOMATCH) if (rc < 0 && rc == PCRE_ERROR_NOMATCH)
continue; continue;
if (rc < 0) { if (rc < 0) {
snprintf(cfg->error, sizeof(cfg->error), "matched failed with error: %d", rc); log_msg(cfg, error, "matched failed with error: %d", rc);
continue; continue;
} }
/* matched */ /* matched */
@ -181,7 +177,7 @@ match(cfg_t *cfg, const char *line, char *buf, size_t buf_size) {
sc = (rc) ? rc : OVECSIZE / 3; sc = (rc) ? rc : OVECSIZE / 3;
rc = pcre_copy_named_substring(r->regex, line, ovector, sc, "host", buf, buf_size); rc = pcre_copy_named_substring(r->regex, line, ovector, sc, "host", buf, buf_size);
if (rc < 0) { if (rc < 0) {
snprintf(cfg->error, sizeof(cfg->error), "can't copy matched string: %d", rc); log_msg(cfg, error, "can't copy matched string: %d", rc);
continue; continue;
} }
return true; return true;

24
src/filters/preg.c

@ -4,10 +4,11 @@
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include "filter.h"
#include <regex.h> #include <regex.h>
#include "filter.h"
#define MODNAME "preg"
/* draft */ /* draft */
#define HOST_REGEX "([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})" #define HOST_REGEX "([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})"
@ -20,12 +21,14 @@ typedef struct f2b_regex_t {
struct _config { struct _config {
char id[ID_MAX]; char id[ID_MAX];
char error[256];
bool icase; bool icase;
void (*logcb)(enum loglevel lvl, const char *msg);
f2b_regex_t *regexps; f2b_regex_t *regexps;
f2b_regex_t *statp; f2b_regex_t *statp;
}; };
#include "filter.c"
cfg_t * cfg_t *
create(const char *id) { create(const char *id) {
cfg_t *cfg = NULL; cfg_t *cfg = NULL;
@ -34,6 +37,7 @@ create(const char *id) {
return NULL; return NULL;
strlcpy(cfg->id, id, sizeof(cfg->id)); strlcpy(cfg->id, id, sizeof(cfg->id));
cfg->logcb = &logcb_stub;
return cfg; return cfg;
} }
@ -58,6 +62,7 @@ append(cfg_t *cfg, const char *pattern) {
size_t bufsize; size_t bufsize;
char *buf = NULL; char *buf = NULL;
char *token = NULL; char *token = NULL;
int ret;
assert(pattern != NULL); assert(pattern != NULL);
@ -79,11 +84,15 @@ append(cfg_t *cfg, const char *pattern) {
if ((regex = calloc(1, sizeof(f2b_regex_t))) == NULL) if ((regex = calloc(1, sizeof(f2b_regex_t))) == NULL)
return false; return false;
if (regcomp(&regex->regex, buf, flags) == 0) { if ((ret = regcomp(&regex->regex, buf, flags)) == 0) {
regex->next = cfg->regexps; regex->next = cfg->regexps;
cfg->regexps = regex; cfg->regexps = regex;
strlcpy(regex->pattern, pattern, sizeof(regex->pattern)); strlcpy(regex->pattern, pattern, sizeof(regex->pattern));
return true; return true;
} else {
char buf[256] = "";
regerror(ret, &regex->regex, buf, sizeof(buf));
log_msg(cfg, error, "regex compile error: %s", buf);
} }
free(regex); free(regex);
@ -115,13 +124,6 @@ stats(cfg_t *cfg, int *matches, char **pattern, bool reset) {
return false; return false;
} }
const char *
error(cfg_t *cfg) {
assert(cfg != NULL);
return cfg->error;
}
bool bool
match(cfg_t *cfg, const char *line, char *buf, size_t buf_size) { match(cfg_t *cfg, const char *line, char *buf, size_t buf_size) {
f2b_regex_t *r = NULL; f2b_regex_t *r = NULL;

Loading…
Cancel
Save