diff --git a/rust/src/json.rs b/rust/src/json.rs deleted file mode 100644 index b4e772307c..0000000000 --- a/rust/src/json.rs +++ /dev/null @@ -1,172 +0,0 @@ -/* Copyright (C) 2017 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -//! Expose portions of the libjansson API to Rust so Rust code can -//! populate a json_t and return it for logging by Suricata. - -use std::ffi::CString; -use std::os::raw::c_char; -use std::os::raw::c_int; - -/// The Rust place holder for the json_t pointer. -pub enum JsonT {} - -/// Expose the jansson functions we need. -extern { - fn json_object() -> *mut JsonT; - fn json_object_set_new(js: *mut JsonT, key: *const c_char, - val: *mut JsonT) -> u32; - - fn json_array() -> *mut JsonT; - fn json_array_append_new(array: *mut JsonT, value: *mut JsonT); - - fn json_string(value: *const c_char) -> *mut JsonT; - fn json_integer(val: u64) -> *mut JsonT; - fn SCJsonDecref(value: *mut JsonT); - fn SCJsonBool(val: bool) -> *mut JsonT; - pub fn json_dumps(js: *mut JsonT, flags: c_int) -> *const c_char; -} - -pub struct Json { - pub js: *mut JsonT, -} - -impl Json { - - pub fn decref(val: Json) { - unsafe{SCJsonDecref(val.js)}; - } - - pub fn object() -> Json { - return Json{ - js: unsafe{json_object()}, - } - } - - pub fn array() -> Json { - return Json{ - js: unsafe{json_array()}, - } - } - - pub fn string(val: &str) -> Json { - return Json{ - js: unsafe{json_string(to_cstring(val.as_bytes()).as_ptr())} - }; - } - - pub fn string_from_bytes(val: &[u8]) -> Json { - return Json{ - js: unsafe{json_string(to_cstring(val).as_ptr())} - }; - } - - pub fn unwrap(&self) -> *mut JsonT { - return self.js; - } - - pub fn set(&self, key: &str, val: Json) { - unsafe { - json_object_set_new(self.js, - CString::new(key).unwrap().as_ptr(), - val.js); - } - } - - pub fn set_string_from_bytes(&self, key: &str, val: &[u8]) { - unsafe { - json_object_set_new(self.js, - CString::new(key).unwrap().as_ptr(), - json_string(to_cstring(val).as_ptr())); - } - } - - pub fn set_string(&self, key: &str, val: &str) { - unsafe { - json_object_set_new(self.js, - CString::new(key).unwrap().as_ptr(), - json_string(to_cstring(val.as_bytes()).as_ptr())); - } - } - - pub fn set_integer(&self, key: &str, val: u64) { - unsafe { - json_object_set_new(self.js, - CString::new(key).unwrap().as_ptr(), - json_integer(val)); - } - } - - pub fn set_boolean(&self, key: &str, val: bool) { - unsafe { - json_object_set_new(self.js, - CString::new(key).unwrap().as_ptr(), - SCJsonBool(val)); - } - } - - pub fn array_append(&self, val: Json) { - unsafe { - json_array_append_new(self.js, val.js); - } - } - pub fn array_append_string(&self, val: &str) { - unsafe { - json_array_append_new(self.js, json_string(to_cstring(val.as_bytes()).as_ptr())); - } - } -} - -/// Convert an array of bytes into an ascii printable string replacing -/// non-printable characters (including NULL) with hex value. -/// -/// Newer versions of Jansson have a json_stringn that will allow us -/// to create a string out of a byte array of unicode compliant bytes, -/// but until we can use it across all platforms this is probably the -/// best we can do. -fn to_cstring(val: &[u8]) -> CString { - let mut safe = Vec::with_capacity(val.len()); - for c in val { - if *c < 0x20 || *c > 0x7e { - safe.extend(format!("\\x{:02x}", *c).as_bytes()); - } else { - safe.push(*c); - } - } - match CString::new(safe) { - Ok(cstr) => cstr, - _ => { - CString::new("").unwrap() - } - } -} - -#[cfg(test)] -mod tests { - - use crate::json::to_cstring; - - #[test] - fn test_to_string() { - assert_eq!("A\\x00A", - to_cstring(&[0x41, 0x00, 0x41]).into_string().unwrap()); - assert_eq!("", to_cstring(&[]).into_string().unwrap()); - assert_eq!("\\x80\\xf1\\xf2\\xf3", - to_cstring(&[0x80, 0xf1, 0xf2, 0xf3]).into_string().unwrap()); - } - -} diff --git a/rust/src/jsonbuilder.rs b/rust/src/jsonbuilder.rs index cef8d80e08..f8549af34b 100644 --- a/rust/src/jsonbuilder.rs +++ b/rust/src/jsonbuilder.rs @@ -17,7 +17,6 @@ #![allow(clippy::missing_safety_doc)] -use crate::json; use std::ffi::CStr; use std::os::raw::c_char; use std::str::Utf8Error; @@ -388,34 +387,6 @@ impl JsonBuilder { Ok(self) } - pub fn set_jsont( - &mut self, key: &str, jsont: &mut json::JsonT, - ) -> Result<&mut Self, JsonError> { - match self.current_state() { - State::ObjectNth => self.buf.push(','), - State::ObjectFirst => self.set_state(State::ObjectNth), - _ => { - debug_validate_fail!("invalid state"); - return Err(JsonError::InvalidState); - } - } - self.buf.push('"'); - self.buf.push_str(key); - self.buf.push_str("\":"); - self.append_jsont(jsont)?; - Ok(self) - } - - fn append_jsont(&mut self, jsont: &mut json::JsonT) -> Result<&mut Self, JsonError> { - unsafe { - let raw = json::json_dumps(jsont, 0); - let rendered = std::ffi::CStr::from_ptr(raw).to_str()?; - self.buf.push_str(rendered); - libc::free(raw as *mut std::os::raw::c_void); - Ok(self) - } - } - /// Set a key and string value type on an object. #[inline(always)] pub fn set_string(&mut self, key: &str, val: &str) -> Result<&mut Self, JsonError> { @@ -699,16 +670,6 @@ pub unsafe extern "C" fn jb_set_formatted(js: &mut JsonBuilder, formatted: *cons return false; } -#[no_mangle] -pub unsafe extern "C" fn jb_set_jsont( - jb: &mut JsonBuilder, key: *const c_char, jsont: &mut json::JsonT, -) -> bool { - if let Ok(key) = CStr::from_ptr(key).to_str() { - return jb.set_jsont(key, jsont).is_ok(); - } - return false; -} - #[no_mangle] pub unsafe extern "C" fn jb_append_object(jb: &mut JsonBuilder, obj: &JsonBuilder) -> bool { jb.append_object(obj).is_ok() diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 7e742b5d39..11dc569dc0 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -50,7 +50,6 @@ pub mod core; #[macro_use] pub mod common; pub mod conf; -pub mod json; pub mod jsonbuilder; #[macro_use] pub mod applayer; diff --git a/src/output-json.c b/src/output-json.c index 01f82d00c6..bfca393faf 100644 --- a/src/output-json.c +++ b/src/output-json.c @@ -618,139 +618,6 @@ void JsonAddrInfoInit(const Packet *p, enum OutputJsonLogDirection dir, JsonAddr } } -/** - * \brief Add five tuple from packet to JSON object - * - * \param p Packet - * \param dir log direction (packet or flow) - * \param js JSON object - */ -void JsonFiveTuple(const Packet *p, enum OutputJsonLogDirection dir, json_t *js) -{ - char srcip[46] = {0}, dstip[46] = {0}; - Port sp, dp; - - switch (dir) { - case LOG_DIR_PACKET: - if (PKT_IS_IPV4(p)) { - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), - srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), - dstip, sizeof(dstip)); - } else if (PKT_IS_IPV6(p)) { - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), - srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), - dstip, sizeof(dstip)); - } else { - /* Not an IP packet so don't do anything */ - return; - } - sp = p->sp; - dp = p->dp; - break; - case LOG_DIR_FLOW: - case LOG_DIR_FLOW_TOSERVER: - if ((PKT_IS_TOSERVER(p))) { - if (PKT_IS_IPV4(p)) { - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), - srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), - dstip, sizeof(dstip)); - } else if (PKT_IS_IPV6(p)) { - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), - srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), - dstip, sizeof(dstip)); - } - sp = p->sp; - dp = p->dp; - } else { - if (PKT_IS_IPV4(p)) { - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), - srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), - dstip, sizeof(dstip)); - } else if (PKT_IS_IPV6(p)) { - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), - srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), - dstip, sizeof(dstip)); - } - sp = p->dp; - dp = p->sp; - } - break; - case LOG_DIR_FLOW_TOCLIENT: - if ((PKT_IS_TOCLIENT(p))) { - if (PKT_IS_IPV4(p)) { - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), - srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), - dstip, sizeof(dstip)); - } else if (PKT_IS_IPV6(p)) { - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), - srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), - dstip, sizeof(dstip)); - } - sp = p->sp; - dp = p->dp; - } else { - if (PKT_IS_IPV4(p)) { - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), - srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), - dstip, sizeof(dstip)); - } else if (PKT_IS_IPV6(p)) { - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), - srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), - dstip, sizeof(dstip)); - } - sp = p->dp; - dp = p->sp; - } - break; - default: - DEBUG_VALIDATE_BUG_ON(1); - return; - } - - - json_object_set_new(js, "src_ip", json_string(srcip)); - - switch(p->proto) { - case IPPROTO_ICMP: - break; - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_SCTP: - json_object_set_new(js, "src_port", json_integer(sp)); - break; - } - - json_object_set_new(js, "dest_ip", json_string(dstip)); - - switch(p->proto) { - case IPPROTO_ICMP: - break; - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_SCTP: - json_object_set_new(js, "dest_port", json_integer(dp)); - break; - } - - if (SCProtoNameValid(IP_GET_IPPROTO(p))) { - json_object_set_new(js, "proto", json_string(known_proto[IP_GET_IPPROTO(p)])); - } else { - char proto[4]; - snprintf(proto, sizeof(proto), "%"PRIu32"", IP_GET_IPPROTO(p)); - json_object_set_new(js, "proto", json_string(proto)); - } -} - #define COMMUNITY_ID_BUF_SIZE 64 static bool CalculateCommunityFlowIdv4(const Flow *f, @@ -879,17 +746,6 @@ static void CreateEveCommunityFlowId(JsonBuilder *js, const Flow *f, const uint1 } } -void CreateJSONFlowId(json_t *js, const Flow *f) -{ - if (f == NULL) - return; - int64_t flow_id = FlowGetId(f); - json_object_set_new(js, "flow_id", json_integer(flow_id)); - if (f->parent_id) { - json_object_set_new(js, "parent_id", json_integer(f->parent_id)); - } -} - void CreateEveFlowId(JsonBuilder *js, const Flow *f) { if (f == NULL) { @@ -902,88 +758,6 @@ void CreateEveFlowId(JsonBuilder *js, const Flow *f) } } -json_t *CreateJSONHeader(const Packet *p, enum OutputJsonLogDirection dir, - const char *event_type, JsonAddrInfo *addr) -{ - char timebuf[64]; - const Flow *f = (const Flow *)p->flow; - - json_t *js = json_object(); - if (unlikely(js == NULL)) - return NULL; - - CreateIsoTimeString(&p->ts, timebuf, sizeof(timebuf)); - - /* time & tx */ - json_object_set_new(js, "timestamp", json_string(timebuf)); - - CreateJSONFlowId(js, f); - - /* sensor id */ - if (sensor_id >= 0) - json_object_set_new(js, "sensor_id", json_integer(sensor_id)); - - /* input interface */ - if (p->livedev) { - json_object_set_new(js, "in_iface", json_string(p->livedev->dev)); - } - - /* pcap_cnt */ - if (p->pcap_cnt != 0) { - json_object_set_new(js, "pcap_cnt", json_integer(p->pcap_cnt)); - } - - if (event_type) { - json_object_set_new(js, "event_type", json_string(event_type)); - } - - /* vlan */ - if (p->vlan_idx > 0) { - json_t *js_vlan = json_array(); - if (js_vlan) { - json_array_append_new(js_vlan, json_integer(p->vlan_id[0])); - if (p->vlan_idx > 1) { - json_array_append_new(js_vlan, json_integer(p->vlan_id[1])); - } - json_object_set_new(js, "vlan", js_vlan); - } - } - - /* 5-tuple */ - JsonAddrInfo addr_info = json_addr_info_zero; - if (addr == NULL) { - JsonAddrInfoInit(p, dir, &addr_info); - addr = &addr_info; - } - json_object_set_new(js, "src_ip", json_string(addr->src_ip)); - json_object_set_new(js, "src_port", json_integer(addr->sp)); - json_object_set_new(js, "dest_ip", json_string(addr->dst_ip)); - json_object_set_new(js, "dest_port", json_integer(addr->dp)); - json_object_set_new(js, "proto", json_string(addr->proto)); - - /* icmp */ - switch (p->proto) { - case IPPROTO_ICMP: - if (p->icmpv4h) { - json_object_set_new(js, "icmp_type", - json_integer(p->icmpv4h->type)); - json_object_set_new(js, "icmp_code", - json_integer(p->icmpv4h->code)); - } - break; - case IPPROTO_ICMPV6: - if (p->icmpv6h) { - json_object_set_new(js, "icmp_type", - json_integer(p->icmpv6h->type)); - json_object_set_new(js, "icmp_code", - json_integer(p->icmpv6h->code)); - } - break; - } - - return js; -} - JsonBuilder *CreateEveHeader(const Packet *p, enum OutputJsonLogDirection dir, const char *event_type, JsonAddrInfo *addr) { diff --git a/src/output-json.h b/src/output-json.h index 63d0406d04..86bcc074b0 100644 --- a/src/output-json.h +++ b/src/output-json.h @@ -69,15 +69,10 @@ typedef struct OutputJSONMemBufferWrapper_ { int OutputJSONMemBufferCallback(const char *str, size_t size, void *data); -void CreateJSONFlowId(json_t *js, const Flow *f); void CreateEveFlowId(JsonBuilder *js, const Flow *f); void EveFileInfo(JsonBuilder *js, const File *file, const bool stored); void EveTcpFlags(uint8_t flags, JsonBuilder *js); void EvePacket(const Packet *p, JsonBuilder *js, unsigned long max_length); -void JsonFiveTuple(const Packet *, enum OutputJsonLogDirection, json_t *); -json_t *CreateJSONHeader(const Packet *p, - enum OutputJsonLogDirection dir, const char *event_type, - JsonAddrInfo *addr); JsonBuilder *CreateEveHeader(const Packet *p, enum OutputJsonLogDirection dir, const char *event_type, JsonAddrInfo *addr);