Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- Added `orig_country_code` and `resp_country_code` fields to event-related
structs that contain origin and response IP addresses. These fields store
2-letter ISO country codes as `[u8; 2]`, enabling geographic filtering and
analysis of security events.
- Updated `migrate_data_dir` function signature to accept an optional
`ip2location::DB` parameter for resolving country codes during migration
from older database formats.

### Changed

- Changed `Store::network_tag_set` signature to require a `customer_id: u32`
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ data-encoding = "2"
flate2 = "1.0"
ip2location = "0.6.0"
ipnet = { version = "2", features = ["serde"] }
itertools = "0.14"
jiff = "0.2.15"
memchr = "2"
num-derive = "0.4"
Expand Down
2 changes: 2 additions & 0 deletions src/backup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,10 @@ mod tests {
sensor: "collector1".to_string(),
orig_addr: IpAddr::V4(Ipv4Addr::LOCALHOST),
orig_port: 10000,
orig_country_code: *b"XX",
resp_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)),
resp_port: 53,
resp_country_code: *b"XX",
proto: 17,
start_time: Utc
.with_ymd_and_hms(1970, 1, 1, 0, 1, 1)
Expand Down
242 changes: 174 additions & 68 deletions src/event.rs

Large diffs are not rendered by default.

18 changes: 14 additions & 4 deletions src/event/bootp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,25 @@ macro_rules! find_bootp_attr_by_kind {
}};
}

pub type BlocklistBootpFields = BlocklistBootpFieldsV0_42;
pub type BlocklistBootpFields = BlocklistBootpFieldsV0_44;

impl BlocklistBootpFields {
#[must_use]
pub fn syslog_rfc5424(&self) -> String {
let start_time_dt = DateTime::from_timestamp_nanos(self.start_time);
format!(
"category={:?} sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} op={:?} htype={:?} hops={:?} xid={:?} ciaddr={:?} yiaddr={:?} siaddr={:?} giaddr={:?} chaddr={:?} sname={:?} file={:?} confidence={:?}",
"category={:?} sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} op={:?} htype={:?} hops={:?} xid={:?} ciaddr={:?} yiaddr={:?} siaddr={:?} giaddr={:?} chaddr={:?} sname={:?} file={:?} confidence={:?}",
self.category.as_ref().map_or_else(
|| "Unspecified".to_string(),
std::string::ToString::to_string
),
self.sensor,
self.orig_addr.to_string(),
self.orig_port.to_string(),
std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"),
self.resp_addr.to_string(),
self.resp_port.to_string(),
std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"),
self.proto.to_string(),
start_time_dt.to_rfc3339(),
self.duration.to_string(),
Expand All @@ -81,12 +83,14 @@ impl BlocklistBootpFields {
}

#[derive(Serialize, Deserialize)]
pub struct BlocklistBootpFieldsV0_42 {
pub struct BlocklistBootpFieldsV0_44 {
pub sensor: String,
pub orig_addr: IpAddr,
pub orig_port: u16,
pub orig_country_code: [u8; 2],
pub resp_addr: IpAddr,
pub resp_port: u16,
pub resp_country_code: [u8; 2],
pub proto: u8,
/// Timestamp in nanoseconds since the Unix epoch (UTC).
pub start_time: i64,
Expand Down Expand Up @@ -116,8 +120,10 @@ pub struct BlocklistBootp {
pub sensor: String,
pub orig_addr: IpAddr,
pub orig_port: u16,
pub orig_country_code: [u8; 2],
pub resp_addr: IpAddr,
pub resp_port: u16,
pub resp_country_code: [u8; 2],
pub proto: u8,
pub start_time: DateTime<Utc>,
pub duration: i64,
Expand All @@ -144,12 +150,14 @@ impl fmt::Display for BlocklistBootp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"sensor={:?} orig_addr={:?} orig_port={:?} resp_addr={:?} resp_port={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} op={:?} htype={:?} hops={:?} xid={:?} ciaddr={:?} yiaddr={:?} siaddr={:?} giaddr={:?} chaddr={:?} sname={:?} file={:?} triage_scores={:?}",
"sensor={:?} orig_addr={:?} orig_port={:?} orig_country_code={:?} resp_addr={:?} resp_port={:?} resp_country_code={:?} proto={:?} start_time={:?} duration={:?} orig_pkts={:?} resp_pkts={:?} orig_l2_bytes={:?} resp_l2_bytes={:?} op={:?} htype={:?} hops={:?} xid={:?} ciaddr={:?} yiaddr={:?} siaddr={:?} giaddr={:?} chaddr={:?} sname={:?} file={:?} triage_scores={:?}",
self.sensor,
self.orig_addr.to_string(),
self.orig_port.to_string(),
std::str::from_utf8(&self.orig_country_code).unwrap_or("XX"),
self.resp_addr.to_string(),
self.resp_port.to_string(),
std::str::from_utf8(&self.resp_country_code).unwrap_or("XX"),
self.proto.to_string(),
self.start_time.to_rfc3339(),
self.duration.to_string(),
Expand Down Expand Up @@ -180,8 +188,10 @@ impl BlocklistBootp {
sensor: fields.sensor,
orig_addr: fields.orig_addr,
orig_port: fields.orig_port,
orig_country_code: fields.orig_country_code,
resp_addr: fields.resp_addr,
resp_port: fields.resp_port,
resp_country_code: fields.resp_country_code,
proto: fields.proto,
start_time: DateTime::from_timestamp_nanos(fields.start_time),
duration: fields.duration,
Expand Down
Loading