Browse Source

* move src/regexp* to src/filter/

* reorganize code in src/filter/
master
Alex 'AdUser' Z 8 years ago
parent
commit
7e46c5f848
  1. 7
      src/CMakeLists.txt
  2. 3
      src/filters/CMakeLists.txt
  3. 12
      src/filters/filter.h
  4. 132
      src/filters/preg.c
  5. 0
      src/filters/regexps.h
  6. 85
      src/regexps.c
  7. 78
      src/regexps_posix.c
  8. 4
      t/CMakeLists.txt

7
src/CMakeLists.txt

@ -1,6 +1,6 @@
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES "main.c" "logfile.c" "log.c" "matches.c" "ipaddr.c" "filelist.c" "regexps_posix.c" "config.c" "jail.c" "backend.c")
set(SOURCES "main.c" "logfile.c" "log.c" "matches.c" "ipaddr.c" "filelist.c" "config.c" "jail.c" "backend.c")
add_executable("f2b" ${SOURCES})
target_link_libraries(f2b "dl")
@ -9,10 +9,11 @@ set(SOURCES "backend-test.c" "log.c" "backend.c" "config.c")
add_executable("backend-test" ${SOURCES})
target_link_libraries("backend-test" "dl")
set(SOURCES "filter-test.c" "log.c" "regexps_posix.c")
add_executable("filter-test" ${SOURCES})
#set(SOURCES "filter-test.c" "log.c" "regexps_posix.c")
#add_executable("filter-test" ${SOURCES})
install(TARGETS f2b
RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
add_subdirectory("backends")
add_subdirectory("filters")

3
src/filters/CMakeLists.txt

@ -0,0 +1,3 @@
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_library("f2b_f_preg" SHARED "preg.c")

12
src/filters/filter.h

@ -0,0 +1,12 @@
#include <stdbool.h>
#define HOST_TOKEN "<HOST>"
typedef struct _config cfg_t;
extern cfg_t *create(const char *id);
extern bool config(cfg_t *c, const char *key, const char *value);
extern bool append(cfg_t *c, const char *pattern);
extern bool ready(cfg_t *c);
extern bool match(cfg_t *c, const char *line, char *buf, size_t buf_size);
extern void destroy(cfg_t *c);

132
src/filters/preg.c

@ -0,0 +1,132 @@
#include <alloca.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "filter.h"
#include <regex.h>
/* draft */
#define HOST_REGEX "([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})"
typedef struct f2b_regex_t {
struct f2b_regex_t *next;
int matches;
regex_t regex;
} f2b_regex_t;
struct _config {
char id[32];
bool icase;
f2b_regex_t *regexps;
};
cfg_t *
create(const char *id) {
cfg_t *cfg = NULL;
if ((cfg = calloc(1, sizeof(cfg_t))) == NULL)
return NULL;
strncpy(cfg->id, id, sizeof(cfg->id));
cfg->id[sizeof(cfg->id)] = '\0';
return cfg;
}
bool
config(cfg_t *cfg, const char *key, const char *value) {
assert(cfg != NULL);
assert(key != NULL);
assert(value != NULL);
if (strcmp(key, "icase") == 0) {
cfg->icase = (strcmp(value, "yes") == 0) ? true : false;
return true;
}
return false;
}
bool
append(cfg_t *cfg, const char *pattern) {
f2b_regex_t *regex = NULL;
int flags = REG_EXTENDED;
size_t bufsize;
char *buf = NULL;
char *token = NULL;
assert(pattern != NULL);
if (cfg->icase)
flags |= REG_ICASE;
if ((token = strstr(pattern, HOST_TOKEN)) == NULL)
return false;
bufsize = strlen(pattern) + strlen(HOST_REGEX) + 1;
if ((buf = alloca(bufsize)) == NULL)
return false;
memset(buf, 0x0, bufsize);
strncpy(buf, pattern, token - pattern);
strcat(buf, HOST_REGEX);
strcat(buf, token + strlen(HOST_TOKEN));
if ((regex = calloc(1, sizeof(f2b_regex_t))) == NULL)
return false;
if (regcomp(&regex->regex, buf, flags) == 0) {
regex->next = cfg->regexps;
cfg->regexps = regex;
return true;
}
free(regex);
return false;
}
bool
ready(cfg_t *cfg) {
assert(cfg != NULL);
if (cfg->regexps)
return true;
return false;
}
bool
match(cfg_t *cfg, const char *line, char *buf, size_t buf_size) {
f2b_regex_t *r = NULL;
size_t match_len = 0;
regmatch_t match[2];
assert(cfg != NULL);
assert(line != NULL);
assert(buf != NULL);
for (r = cfg->regexps; r != NULL; r = r->next) {
if (regexec(&r->regex, line, 2, &match[0], 0) != 0)
continue;
/* matched */
r->matches++;
match_len = match[1].rm_eo - match[1].rm_so;
assert(buf_size > match_len);
strncpy(buf, &line[match[1].rm_so], match_len);
buf[match_len] = '\0';
return true;
}
return false;
}
void
destroy(cfg_t *cfg) {
f2b_regex_t *next = NULL, *r = NULL;
for (r = cfg->regexps; r != NULL; r = next) {
next = r->next;
regfree(&r->regex);
free(r);
}
free(cfg);
}

0
src/regexps.h → src/filters/regexps.h

85
src/regexps.c

@ -1,85 +0,0 @@
/* this file should not be used directly, only with `#include "regexps.c"` */
#include "log.h"
f2b_regex_t *
f2b_regexlist_append(f2b_regex_t *list, f2b_regex_t *regex) {
assert(regex != NULL);
regex->next = list;
return regex;
}
bool
f2b_regexlist_match(f2b_regex_t *list, const char *line, char *buf, size_t buf_size) {
for (; list != NULL; list = list->next) {
if (f2b_regex_match(list, line, buf, buf_size))
return true;
}
return false;
}
f2b_regex_t *
f2b_regexlist_from_file(const char *path) {
f2b_regex_t *list = NULL, *regex = NULL;
FILE *f = NULL;
size_t linenum = 0;
char line[REGEX_LINE_MAX] = "";
char *p, *q;
if ((f = fopen(path, "r")) == NULL) {
f2b_log_msg(log_error, "can't open regex list '%s': %s", path, strerror(errno));
return NULL;
}
while (1) {
p = fgets(line, sizeof(line), f);
if (!p && (feof(f) || ferror(f)))
break;
linenum++;
/* strip leading spaces */
while (isblank(*p))
p++;
/* strip trailing spaces */
if ((q = strchr(p, '\r')) || (q = strchr(p, '\n'))) {
while(q > p && isspace(*q)) {
*q = '\0';
q--;
}
}
switch(*p) {
case '\r':
case '\n':
case '\0':
/* empty line */
break;
case ';':
case '#':
/* comment line */
break;
default:
/* TODO: icase */
if ((regex = f2b_regex_create(p, false)) == NULL) {
f2b_log_msg(log_warn, "can't create regex from pattern at %s:%d: %s", path, linenum, p);
continue;
}
list = f2b_regexlist_append(list, regex);
break;
}
}
return list;
}
f2b_regex_t *
f2b_regexlist_destroy(f2b_regex_t *list) {
f2b_regex_t *next;
for (; list != NULL; list = next) {
next = list->next;
f2b_regex_destroy(list);
}
return NULL;
}

78
src/regexps_posix.c

@ -1,78 +0,0 @@
#include "common.h"
#include "regexps.h"
#include <regex.h>
/* draft */
#define HOST_REGEX "([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})"
struct _regex {
struct _regex *next;
int matches;
regex_t regex;
};
f2b_regex_t *
f2b_regex_create(const char *pattern, bool icase) {
f2b_regex_t *regex = NULL;
int flags = REG_EXTENDED;
size_t bufsize;
char *buf = NULL;
char *token = NULL;
assert(pattern != NULL);
if (icase)
flags |= REG_ICASE;
if ((token = strstr(pattern, HOST_TOKEN)) == NULL)
return NULL;
bufsize = strlen(pattern) + strlen(HOST_REGEX) + 1;
if ((buf = alloca(bufsize)) == NULL)
return NULL;
memset(buf, 0x0, bufsize);
strncpy(buf, pattern, token - pattern);
strcat(buf, HOST_REGEX);
strcat(buf, token + strlen(HOST_TOKEN));
if ((regex = calloc(1, sizeof(f2b_regex_t))) == NULL)
return NULL;
if (regcomp(&regex->regex, buf, flags) == 0)
return regex;
FREE(regex);
return NULL;
}
void
f2b_regex_destroy(f2b_regex_t * regex) {
regfree(&regex->regex);
FREE(regex);
}
bool
f2b_regex_match(f2b_regex_t *regex, const char *line, char *buf, size_t buf_size) {
size_t match_len = 0;
regmatch_t match[2];
assert(regex != NULL);
assert(line != NULL);
assert(buf != NULL);
if (regexec(&regex->regex, line, 2, &match[0], 0) != 0)
return false;
regex->matches++;
match_len = match[1].rm_eo - match[1].rm_so;
assert(buf_size > match_len);
strncpy(buf, &line[match[1].rm_so], match_len);
buf[match_len] = '\0';
return true;
}
/* common f2b_regexlist_*() functions */
#include "regexps.c"

4
t/CMakeLists.txt

@ -5,11 +5,11 @@ set(SRC_DIR "../src")
add_executable("t_logfile" "t_logfile.c" "${SRC_DIR}/logfile.c")
add_executable("t_matches" "t_matches.c" "${SRC_DIR}/matches.c")
add_executable("t_ipaddr" "t_ipaddr.c" "${SRC_DIR}/ipaddr.c" "${SRC_DIR}/matches.c")
add_executable("t_rx_posix" "t_rx_posix.c" "${SRC_DIR}/regexps_posix.c" "${SRC_DIR}/log.c")
#add_executable("t_rx_posix" "t_rx_posix.c" "${SRC_DIR}/regexps_posix.c" "${SRC_DIR}/log.c")
add_executable("t_config_param" "t_config_param.c" "${SRC_DIR}/config.c" "${SRC_DIR}/log.c")
add_test("tests/f2b_logfile_*" "t_logfile")
add_test("tests/f2b_matches_*" "t_matches")
add_test("tests/f2b_ipaddr_*" "t_ipaddr")
add_test("tests/f2b_regex_*" "t_rx_posix")
#add_test("tests/f2b_regex_*" "t_rx_posix")
add_test("tests/f2b_config_param*" "t_config_param")

Loading…
Cancel
Save