mirror of
https://github.com/OISF/suricata.git
synced 2026-10-12 02:07:10 +00:00
@@ -98,8 +98,32 @@ fn log_eve_wrapped(
|
||||
jb.set_string("example", "eve-callback")?;
|
||||
jb.set_string("has_flow", if f.is_some() { "true" } else { "false" })?;
|
||||
|
||||
// If we have a flow, log something from flow storage.
|
||||
// If we have a flow, show the `Flow` wrapper accessors and log something
|
||||
// from flow storage.
|
||||
if let Some(f) = f {
|
||||
let src_ip = f
|
||||
.source_address()
|
||||
.map(|addr| addr.to_string())
|
||||
.unwrap_or_else(|| "<unknown>".to_string());
|
||||
let dst_ip = f
|
||||
.destination_address()
|
||||
.map(|addr| addr.to_string())
|
||||
.unwrap_or_else(|| "<unknown>".to_string());
|
||||
let toserver = f.to_server_packet_count();
|
||||
let toclient = f.to_client_packet_count();
|
||||
|
||||
jb.open_object("flow_accessors")?;
|
||||
jb.set_string("src_ip", &src_ip)?;
|
||||
jb.set_uint("src_port", f.source_port() as u64)?;
|
||||
jb.set_string("dest_ip", &dst_ip)?;
|
||||
jb.set_uint("dest_port", f.destination_port() as u64)?;
|
||||
jb.set_uint("ip_proto", f.ip_protocol() as u64)?;
|
||||
jb.set_uint("app_proto", f.app_protocol() as u64)?;
|
||||
jb.set_uint("toserver_pkts", toserver as u64)?;
|
||||
jb.set_uint("toclient_pkts", toclient as u64)?;
|
||||
jb.set_uint("last_seen", f.last_time().as_secs())?;
|
||||
jb.close()?;
|
||||
|
||||
if let Some(state) = flow_storage.get(f) {
|
||||
jb.set_uint("flow_packets", state.packets)?;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::marker::PhantomData;
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
use std::os::raw::c_void;
|
||||
use std::time::Duration;
|
||||
|
||||
use suricata_sys::sys::{
|
||||
self, Packet, SCFlowGetStorageById, SCFlowRegisterFinishCallback, SCFlowRegisterInitCallback,
|
||||
@@ -58,6 +60,92 @@ impl<'a> Flow<'a> {
|
||||
fn as_mut_ptr(&mut self) -> *mut sys::Flow {
|
||||
self.flow
|
||||
}
|
||||
|
||||
/// Return the time of the last flow update as a `Duration` since the epoch.
|
||||
pub fn last_time(&self) -> Duration {
|
||||
let mut secs: u64 = 0;
|
||||
let mut usecs: u64 = 0;
|
||||
unsafe {
|
||||
sys::SCFlowGetLastTimeAsParts(self.as_ptr(), &mut secs, &mut usecs);
|
||||
}
|
||||
Duration::new(secs, usecs as u32 * 1000)
|
||||
}
|
||||
|
||||
/// Return the flow flags.
|
||||
pub fn flags(&self) -> u64 {
|
||||
unsafe { sys::SCFlowGetFlags(self.as_ptr()) }
|
||||
}
|
||||
|
||||
/// Return true if the flow is IPv4.
|
||||
pub fn is_ipv4(&self) -> bool {
|
||||
unsafe { sys::SCFlowIsIPv4(self.as_ptr()) }
|
||||
}
|
||||
|
||||
/// Return true if the flow is IPv6.
|
||||
pub fn is_ipv6(&self) -> bool {
|
||||
unsafe { sys::SCFlowIsIPv6(self.as_ptr()) }
|
||||
}
|
||||
|
||||
/// Return the flow IP protocol.
|
||||
pub fn ip_protocol(&self) -> u8 {
|
||||
unsafe { sys::SCFlowGetIPProtocol(self.as_ptr()) }
|
||||
}
|
||||
|
||||
/// Return the flow app-layer protocol.
|
||||
pub fn app_protocol(&self) -> sys::AppProto {
|
||||
unsafe { sys::SCFlowGetAppProtocol(self.as_ptr()) }
|
||||
}
|
||||
|
||||
/// Return the flow source port.
|
||||
pub fn source_port(&self) -> u16 {
|
||||
unsafe { sys::SCFlowGetSourcePort(self.as_ptr()) }
|
||||
}
|
||||
|
||||
/// Return the flow destination port.
|
||||
pub fn destination_port(&self) -> u16 {
|
||||
unsafe { sys::SCFlowGetDestinationPort(self.as_ptr()) }
|
||||
}
|
||||
|
||||
/// Return an owned copy the flow's source address.
|
||||
pub fn source_address(&self) -> Option<IpAddr> {
|
||||
let ptr = unsafe { sys::SCFlowGetSourceAddressAsRawPtr(self.as_ptr()) };
|
||||
self.address_from_ptr(ptr)
|
||||
}
|
||||
|
||||
/// Return an owned copy the flow's destination address.
|
||||
pub fn destination_address(&self) -> Option<IpAddr> {
|
||||
let ptr = unsafe { sys::SCFlowGetDestinationAddressAsRawPtr(self.as_ptr()) };
|
||||
self.address_from_ptr(ptr)
|
||||
}
|
||||
|
||||
/// Return the number of packets seen to-server.
|
||||
pub fn to_server_packet_count(&self) -> u32 {
|
||||
unsafe { sys::SCFlowGetToServerPacketCount(self.as_ptr()) }
|
||||
}
|
||||
|
||||
/// Return the number of packets seen to-client.
|
||||
pub fn to_client_packet_count(&self) -> u32 {
|
||||
unsafe { sys::SCFlowGetToClientPacketCount(self.as_ptr()) }
|
||||
}
|
||||
|
||||
fn address_from_ptr(&self, ptr: *const u8) -> Option<IpAddr> {
|
||||
if ptr.is_null() {
|
||||
return None;
|
||||
}
|
||||
if self.is_ipv4() {
|
||||
let bytes = unsafe { std::slice::from_raw_parts(ptr, 4) };
|
||||
Some(IpAddr::V4(Ipv4Addr::new(
|
||||
bytes[0], bytes[1], bytes[2], bytes[3],
|
||||
)))
|
||||
} else if self.is_ipv6() {
|
||||
let bytes = unsafe { std::slice::from_raw_parts(ptr, 16) };
|
||||
let mut addr = [0; 16];
|
||||
addr.copy_from_slice(bytes);
|
||||
Some(IpAddr::V6(Ipv6Addr::from(addr)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A typed handle to a per-flow storage slot.
|
||||
|
||||
Reference in New Issue
Block a user