1use libc::{c_char, c_long, c_ulong};
7use serde::Serialize;
8use std::{
9 fmt::{self, Display, Formatter},
10 vec::Vec,
11};
12
13mod utils;
14use self::utils::{decode_vecs, encode};
15
16mod cfw;
17use cfw::fw_rule_impl;
18
19mod consts;
20pub use self::consts::{Actions, Directions, Protocols};
21
22mod error;
23pub use self::error::Error;
24
25#[derive(Default, Clone, Serialize)]
26#[repr(C)]
27pub struct FwRule {
28 pub name: String,
29 pub description: String,
30 pub app_name: String,
31 pub service_name: String,
32 pub protocol: Protocols,
33 pub icmp_type: String,
34 pub local_ports: String,
35 pub remote_ports: String,
36 pub local_adresses: String,
37 pub remote_addresses: String,
38 pub profile1: String,
39 pub profile2: String,
40 pub profile3: String,
41 pub direction: Directions,
42 pub action: Actions,
43 pub interface_types: String,
44 pub interfaces: String,
45 pub enabled: bool,
46 pub grouping: String,
47 pub edge_traversal: bool,
48}
49
50impl Display for FwRule {
51 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
52 write!(f, "name: {}\ndescription: {}\napplication name: {}\nservice name: {}\nprotocol: {}\nicmp type: {}\nlocal ports: {}\nremote ports: {}\nlocal address: {}\nremote address: {}\nprofiles: {} {} {}\ndirection: {}\naction: {}\ninterfaces types: {}\ninterfaces: {}\nenabled: {}\ngrouping: {}\nedge traversal: {}\n---",
53 self.name,
54 self.description,
55 self.app_name,
56 self.service_name,
57 self.protocol,
58 self.icmp_type,
59 self.local_ports,
60 self.remote_ports,
61 self.local_adresses,
62 self.remote_addresses,
63 self.profile1,
64 self.profile2,
65 self.profile3,
66 self.direction,
67 self.action,
68 self.interfaces,
69 self.interface_types,
70 self.enabled,
71 self.grouping,
72 self.edge_traversal)
73 }
74}
75
76extern "C" {
77 fn getFWRules(
78 rules: &*mut fw_rule_impl,
79 size: *mut c_long,
80 rules_count: *mut c_long,
81 ) -> c_ulong;
82 fn newFWRule(rule: &fw_rule_impl) -> c_ulong;
83 fn delFWRule(rule: *const c_char) -> c_ulong;
84 fn enableFWRule(rule: *const c_char, enabled: c_long) -> c_ulong;
85}
86
87#[no_mangle]
88pub fn get_fw_rules() -> Result<Vec<FwRule>, Error> {
89 let mut required_size = 0;
104 let mut rules_count = 0;
105 let mut rules: *mut fw_rule_impl = std::ptr::null_mut();
106 let mut res = unsafe { getFWRules(&rules, &mut required_size, &mut rules_count) };
107 assert_eq!(res, 8);
108 rules = unsafe { libc::malloc(required_size as usize) } as *mut fw_rule_impl;
109 if rules == std::ptr::null_mut() {
110 return Err(Error(1));
111 }
112 res = unsafe { getFWRules(&rules, &mut required_size, &mut rules_count) };
113 if res != 0 {
114 return Err(Error(1));
115 }
116 let fw_rules_slice = unsafe { std::slice::from_raw_parts_mut(rules, rules_count as usize) };
117 let res = decode_vecs(fw_rules_slice.to_vec());
118 unsafe { libc::free(rules as *mut libc::c_void) };
119 Ok(res)
120}
121
122#[no_mangle]
123pub fn new_fw_rule(rule: &FwRule) -> Result<(), Error> {
124 let fw_rule: fw_rule_impl = rule.into();
146 let res = unsafe { newFWRule(&fw_rule) };
147 if res != 0 {
148 return Err(Error(res));
149 }
150 Ok(())
151}
152
153#[no_mangle]
154pub fn enable_fw_rule(name: &str) -> Result<(), Error> {
155 let mut s: [c_char; 1024] = [0; 1024];
167 encode(name, &mut s);
168 let res = unsafe { enableFWRule(s.as_ptr(), 1) };
169 if res != 0 {
170 return Err(Error(res));
171 }
172 Ok(())
173}
174
175#[no_mangle]
176pub fn del_fw_rule(name: &str) -> Result<(), Error> {
177 let mut s: [c_char; 1024] = [0; 1024];
189 encode(name, &mut s);
190 let res = unsafe { delFWRule(s.as_ptr()) };
191 if res != 0 {
192 return Err(Error(res));
193 }
194 Ok(())
195}
196
197#[no_mangle]
198pub fn disable_fw_rule(name: &str) -> Result<(), Error> {
199 let mut s: [c_char; 1024] = [0; 1024];
211 encode(name, &mut s);
212 let res = unsafe { enableFWRule(s.as_ptr(), 0) };
213 if res != 0 {
214 return Err(Error(res));
215 }
216 Ok(())
217}
218
219#[cfg(test)]
220mod tests {
221 use super::*;
222
223 #[test]
224 fn test_get_fw_rules() {
225 let rules = get_fw_rules();
226 match rules {
227 Err(_) => assert!(false),
228 Ok(_) => {
229 assert!(true)
230 }
231 }
232 }
233}