Skip to content

Commit

Permalink
FW-1087: provide wirefilter.h C header file and add ffi/tests/ctests …
Browse files Browse the repository at this point in the history
…crate

This new crate is here to provide a set of C based tests that will
serve two purposes:
* Provide some examples how to use the FFI bindings
* Test that those bindings are actually working as intended

Internally, it relies on ffi/tests/ctests/src/tests.c file which contains
tests written in C and that is compiled at cargo configuration time
through the use of a build.rs file. This produces a wirefilter_ffi_ctests.a
static library that is later used in the ffi/tests/ctests/src/lib.rs file
to call the different tests functions. All of this is done in order to try
to integrate somehow properly with cargo test.
  • Loading branch information
marmeladema committed Mar 28, 2019
1 parent c449e9c commit 39978b2
Show file tree
Hide file tree
Showing 8 changed files with 415 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ path = "../engine"
[dev-dependencies]
regex = "1.0.1"
indoc = "0.3.0"
wirefilter-ffi-ctests = {"path" = "tests/ctests"}
129 changes: 129 additions & 0 deletions ffi/include/wirefilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#ifndef _WIREFILTER_H_
#define _WIREFILTER_H_

#include <stdlib.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct wirefilter_scheme wirefilter_scheme_t;
typedef struct wirefilter_execution_context wirefilter_execution_context_t;
typedef struct wirefilter_filter_ast wirefilter_filter_ast_t;
typedef struct wirefilter_filter wirefilter_filter_t;

typedef struct {
const unsigned char *data;
size_t length;
} wirefilter_rust_allocated_str_t;

typedef struct {
const unsigned char *data;
size_t length;
} wirefilter_static_rust_allocated_str_t;

typedef struct {
const unsigned char *data;
size_t length;
} wirefilter_externally_allocated_str_t;

typedef struct {
const unsigned char *data;
size_t length;
} wirefilter_externally_allocated_byte_arr_t;

typedef union {
union {
uint8_t success;
struct {
uint8_t _res1;
wirefilter_rust_allocated_str_t msg;
} err;
struct {
uint8_t _res2;
wirefilter_filter_ast_t *ast;
} ok;
};
} wirefilter_parsing_result_t;

typedef enum {
WIREFILTER_TYPE_IP,
WIREFILTER_TYPE_BYTES,
WIREFILTER_TYPE_INT,
WIREFILTER_TYPE_BOOL,
} wirefilter_type_t;

wirefilter_scheme_t *wirefilter_create_scheme();
void wirefilter_free_scheme(wirefilter_scheme_t *scheme);

void wirefilter_add_type_field_to_scheme(
wirefilter_scheme_t *scheme,
wirefilter_externally_allocated_str_t name,
wirefilter_type_t type
);

wirefilter_parsing_result_t wirefilter_parse_filter(
wirefilter_scheme_t *scheme,
wirefilter_externally_allocated_str_t input
);

void wirefilter_free_parsing_result(wirefilter_parsing_result_t result);

wirefilter_filter_t *wirefilter_compile_filter(wirefilter_filter_ast_t *ast);
void wirefilter_free_compiled_filter(wirefilter_filter_t *filter);

wirefilter_execution_context_t *wirefilter_create_execution_context(
wirefilter_scheme_t *scheme
);
void wirefilter_free_execution_context(
wirefilter_execution_context_t *exec_ctx
);

void wirefilter_add_int_value_to_execution_context(
wirefilter_execution_context_t *exec_ctx,
wirefilter_externally_allocated_str_t name,
int32_t value
);

void wirefilter_add_bytes_value_to_execution_context(
wirefilter_execution_context_t *exec_ctx,
wirefilter_externally_allocated_str_t name,
wirefilter_externally_allocated_byte_arr_t value
);

void wirefilter_add_ipv6_value_to_execution_context(
wirefilter_execution_context_t *exec_ctx,
wirefilter_externally_allocated_str_t name,
uint8_t value[16]
);

void wirefilter_add_ipv4_value_to_execution_context(
wirefilter_execution_context_t *exec_ctx,
wirefilter_externally_allocated_str_t name,
uint8_t value[4]
);

void wirefilter_add_bool_value_to_execution_context(
wirefilter_execution_context_t *exec_ctx,
wirefilter_externally_allocated_str_t name,
bool value
);

bool wirefilter_match(
wirefilter_filter_t *filter,
wirefilter_execution_context_t *exec_ctx
);

bool wirefilter_filter_uses(
wirefilter_filter_t *filter,
wirefilter_externally_allocated_str_t field_name
);

wirefilter_static_rust_allocated_str_t wirefilter_get_version();

#ifdef __cplusplus
}
#endif

#endif // _WIREFILTER_H_
5 changes: 5 additions & 0 deletions ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ pub extern "C" fn wirefilter_parse_filter<'s, 'i>(
}
}

#[no_mangle]
pub extern "C" fn wirefilter_free_parsing_result(r: ParsingResult<'_>) {
drop(r);
}

/// Wrapper for Hasher that allows using Write API (e.g. with serializer).
#[derive(Default)]
struct HasherWrite<H: Hasher>(H);
Expand Down
12 changes: 12 additions & 0 deletions ffi/tests/ctests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
authors = ["Elie ROUDNINSKI <[email protected]>"]
name = "wirefilter-ffi-ctests"
version = "0.1.0"
description = "C based tests for FFI bindings of the Wirefilter engine"
publish = false

[dependencies]
wirefilter-ffi = {"path" = "../.."}

[build-dependencies]
cc = "1.0"
8 changes: 8 additions & 0 deletions ffi/tests/ctests/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
extern crate cc;

fn main() {
cc::Build::new()
.include("../../include")
.file("src/tests.c")
.compile("wirefilter_ffi_ctests");
}
30 changes: 30 additions & 0 deletions ffi/tests/ctests/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#[test]
fn test() {
#[link(name = "wirefilter_ffi")]
extern "C" {
fn test_wirefilter_ffi_01();
fn test_wirefilter_ffi_02();
fn test_wirefilter_ffi_03();
fn test_wirefilter_ffi_04();
fn test_wirefilter_ffi_05();
fn test_wirefilter_ffi_06();
fn test_wirefilter_ffi_07();
fn test_wirefilter_ffi_08();
}

unsafe { test_wirefilter_ffi_01() };

unsafe { test_wirefilter_ffi_02() };

unsafe { test_wirefilter_ffi_03() };

unsafe { test_wirefilter_ffi_04() };

unsafe { test_wirefilter_ffi_05() };

unsafe { test_wirefilter_ffi_06() };

unsafe { test_wirefilter_ffi_07() };

unsafe { test_wirefilter_ffi_08() };
}
Loading

0 comments on commit 39978b2

Please sign in to comment.