Skip to content

Commit 30d18f3

Browse files
committed
FW-1087: provide wirefilter.h C header file and add ffi/tests/ctests 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.
1 parent bbc62a7 commit 30d18f3

File tree

8 files changed

+501
-0
lines changed

8 files changed

+501
-0
lines changed

Cargo.lock

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ffi/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ path = "../engine"
2525
[dev-dependencies]
2626
regex = "1.0.1"
2727
indoc = "0.3.0"
28+
wirefilter-ffi-ctests = {path = "tests/ctests"}

ffi/include/wirefilter.h

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#ifndef _WIREFILTER_H_
2+
#define _WIREFILTER_H_
3+
4+
#include <stdlib.h>
5+
#include <stdint.h>
6+
7+
#ifdef __cplusplus
8+
extern "C" {
9+
#endif
10+
11+
typedef struct wirefilter_scheme wirefilter_scheme_t;
12+
typedef struct wirefilter_execution_context wirefilter_execution_context_t;
13+
typedef struct wirefilter_filter_ast wirefilter_filter_ast_t;
14+
typedef struct wirefilter_filter wirefilter_filter_t;
15+
16+
typedef struct {
17+
const char *data;
18+
size_t length;
19+
} wirefilter_rust_allocated_str_t;
20+
21+
typedef struct {
22+
const char *data;
23+
size_t length;
24+
} wirefilter_static_rust_allocated_str_t;
25+
26+
typedef struct {
27+
const char *data;
28+
size_t length;
29+
} wirefilter_externally_allocated_str_t;
30+
31+
typedef struct {
32+
const unsigned char *data;
33+
size_t length;
34+
} wirefilter_externally_allocated_byte_arr_t;
35+
36+
typedef union {
37+
union {
38+
uint8_t success;
39+
struct {
40+
uint8_t _res1;
41+
wirefilter_rust_allocated_str_t msg;
42+
} err;
43+
struct {
44+
uint8_t _res2;
45+
wirefilter_filter_ast_t *ast;
46+
} ok;
47+
};
48+
} wirefilter_parsing_result_t;
49+
50+
typedef enum {
51+
WIREFILTER_TYPE_IP,
52+
WIREFILTER_TYPE_BYTES,
53+
WIREFILTER_TYPE_INT,
54+
WIREFILTER_TYPE_BOOL,
55+
} wirefilter_type_t;
56+
57+
wirefilter_scheme_t *wirefilter_create_scheme();
58+
void wirefilter_free_scheme(wirefilter_scheme_t *scheme);
59+
60+
void wirefilter_add_type_field_to_scheme(
61+
wirefilter_scheme_t *scheme,
62+
wirefilter_externally_allocated_str_t name,
63+
wirefilter_type_t type
64+
);
65+
66+
wirefilter_parsing_result_t wirefilter_parse_filter(
67+
wirefilter_scheme_t *scheme,
68+
wirefilter_externally_allocated_str_t input
69+
);
70+
71+
void wirefilter_free_parsing_result(wirefilter_parsing_result_t result);
72+
73+
wirefilter_filter_t *wirefilter_compile_filter(wirefilter_filter_ast_t *ast);
74+
void wirefilter_free_compiled_filter(wirefilter_filter_t *filter);
75+
76+
wirefilter_execution_context_t *wirefilter_create_execution_context(
77+
wirefilter_scheme_t *scheme
78+
);
79+
void wirefilter_free_execution_context(
80+
wirefilter_execution_context_t *exec_ctx
81+
);
82+
83+
void wirefilter_add_int_value_to_execution_context(
84+
wirefilter_execution_context_t *exec_ctx,
85+
wirefilter_externally_allocated_str_t name,
86+
int32_t value
87+
);
88+
89+
void wirefilter_add_bytes_value_to_execution_context(
90+
wirefilter_execution_context_t *exec_ctx,
91+
wirefilter_externally_allocated_str_t name,
92+
wirefilter_externally_allocated_byte_arr_t value
93+
);
94+
95+
void wirefilter_add_ipv6_value_to_execution_context(
96+
wirefilter_execution_context_t *exec_ctx,
97+
wirefilter_externally_allocated_str_t name,
98+
uint8_t value[16]
99+
);
100+
101+
void wirefilter_add_ipv4_value_to_execution_context(
102+
wirefilter_execution_context_t *exec_ctx,
103+
wirefilter_externally_allocated_str_t name,
104+
uint8_t value[4]
105+
);
106+
107+
void wirefilter_add_bool_value_to_execution_context(
108+
wirefilter_execution_context_t *exec_ctx,
109+
wirefilter_externally_allocated_str_t name,
110+
bool value
111+
);
112+
113+
bool wirefilter_match(
114+
wirefilter_filter_t *filter,
115+
wirefilter_execution_context_t *exec_ctx
116+
);
117+
118+
bool wirefilter_filter_uses(
119+
wirefilter_filter_t *filter,
120+
wirefilter_externally_allocated_str_t field_name
121+
);
122+
123+
wirefilter_static_rust_allocated_str_t wirefilter_get_version();
124+
125+
#ifdef __cplusplus
126+
}
127+
#endif
128+
129+
#endif // _WIREFILTER_H_

ffi/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ pub extern "C" fn wirefilter_parse_filter<'s, 'i>(
9292
}
9393
}
9494

95+
#[no_mangle]
96+
pub extern "C" fn wirefilter_free_parsing_result(r: ParsingResult<'_>) {
97+
drop(r);
98+
}
99+
95100
/// Wrapper for Hasher that allows using Write API (e.g. with serializer).
96101
#[derive(Default)]
97102
struct HasherWrite<H: Hasher>(H);

ffi/tests/ctests/Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
authors = ["Elie ROUDNINSKI <[email protected]>"]
3+
name = "wirefilter-ffi-ctests"
4+
version = "0.1.0"
5+
description = "C based tests for FFI bindings of the Wirefilter engine"
6+
publish = false
7+
8+
[dependencies]
9+
wirefilter-ffi = {path = "../.."}
10+
11+
[build-dependencies]
12+
cc = "1.0"

ffi/tests/ctests/build.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
extern crate cc;
2+
3+
fn main() {
4+
cc::Build::new()
5+
.include("../../include")
6+
.file("src/tests.c")
7+
.flag("-Wall")
8+
.flag("-Wextra")
9+
.flag("-Werror")
10+
.compile("wirefilter_ffi_ctests");
11+
}

ffi/tests/ctests/src/lib.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#[no_mangle]
2+
unsafe extern "C" fn rust_assert(check: bool, msg: *const std::os::raw::c_char) {
3+
assert!(check, "{}", std::ffi::CStr::from_ptr(msg).to_str().unwrap());
4+
}
5+
6+
macro_rules! ffi_ctest {
7+
(@inner $($name:ident => $link_name:expr,)*) => {
8+
$(
9+
#[test]
10+
pub fn $name() {
11+
#[link(name = "wirefilter_ffi")]
12+
extern "C" {
13+
#[link_name = $link_name]
14+
fn ctest();
15+
}
16+
17+
unsafe { ctest() }
18+
}
19+
)*
20+
};
21+
22+
($($name:ident,)*) => {
23+
ffi_ctest! { @inner
24+
$($name => concat!("wirefilter_ffi_ctest_", stringify!($name)),)*
25+
}
26+
};
27+
}
28+
29+
mod ffi_ctest {
30+
ffi_ctest!(
31+
create_scheme,
32+
add_fields_to_scheme,
33+
parse_good_filter,
34+
parse_bad_filter,
35+
compile_filter,
36+
create_execution_context,
37+
add_values_to_execution_context,
38+
match_filter,
39+
);
40+
}

0 commit comments

Comments
 (0)