Skip to main content

stix_rs/observables/
network_traffic.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4/// Network traffic observable (STIX 2.1) - core fields
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6#[serde(rename_all = "snake_case")]
7pub struct NetworkTraffic {
8    pub start: Option<DateTime<Utc>>,
9    pub end: Option<DateTime<Utc>>,
10    pub protocols: Option<Vec<String>>,
11    pub src_ref: Option<String>,
12    pub dst_ref: Option<String>,
13    pub src_port: Option<u16>,
14    pub dst_port: Option<u16>,
15    #[serde(flatten)]
16    pub custom_properties: std::collections::HashMap<String, serde_json::Value>,
17}
18
19impl NetworkTraffic {
20    pub fn builder() -> NetworkTrafficBuilder { NetworkTrafficBuilder::default() }
21}
22
23#[derive(Debug, Default)]
24pub struct NetworkTrafficBuilder {
25    start: Option<DateTime<Utc>>,
26    end: Option<DateTime<Utc>>,
27    protocols: Option<Vec<String>>,
28    src_ref: Option<String>,
29    dst_ref: Option<String>,
30    src_port: Option<u16>,
31    dst_port: Option<u16>,
32    custom_properties: std::collections::HashMap<String, serde_json::Value>,
33}
34
35impl NetworkTrafficBuilder {
36    pub fn start(mut self, t: DateTime<Utc>) -> Self { self.start = Some(t); self }
37    pub fn end(mut self, t: DateTime<Utc>) -> Self { self.end = Some(t); self }
38    pub fn protocols(mut self, p: Vec<String>) -> Self { self.protocols = Some(p); self }
39    pub fn src_ref(mut self, r: impl Into<String>) -> Self { self.src_ref = Some(r.into()); self }
40    pub fn dst_ref(mut self, r: impl Into<String>) -> Self { self.dst_ref = Some(r.into()); self }
41    pub fn src_port(mut self, p: u16) -> Self { self.src_port = Some(p); self }
42    pub fn dst_port(mut self, p: u16) -> Self { self.dst_port = Some(p); self }
43    pub fn property(mut self, k: impl Into<String>, v: impl Into<serde_json::Value>) -> Self { self.custom_properties.insert(k.into(), v.into()); self }
44    pub fn build(self) -> NetworkTraffic {
45        NetworkTraffic { start: self.start, end: self.end, protocols: self.protocols, src_ref: self.src_ref, dst_ref: self.dst_ref, src_port: self.src_port, dst_port: self.dst_port, custom_properties: self.custom_properties }
46    }
47}
48
49impl From<NetworkTraffic> for crate::StixObjectEnum { fn from(n: NetworkTraffic) -> Self { crate::StixObjectEnum::NetworkTraffic(n) } }
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54    use chrono::Utc;
55
56    #[test]
57    fn network_traffic_serde() {
58        let nt = NetworkTraffic::builder().src_ref("ipv4-1").dst_ref("ipv4-2").src_port(1234).dst_port(80).start(Utc::now()).build();
59        let s = serde_json::to_string(&nt).unwrap();
60        let de: NetworkTraffic = serde_json::from_str(&s).unwrap();
61        assert_eq!(de.src_port, Some(1234));
62    }
63}