Skip to main content

clawdstrike_ocsf/objects/
network_endpoint.rs

1//! OCSF NetworkEndpoint object.
2
3use serde::{Deserialize, Serialize};
4
5/// OCSF Network Endpoint object.
6#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(deny_unknown_fields)]
8pub struct NetworkEndpoint {
9    /// IP address.
10    #[serde(skip_serializing_if = "Option::is_none")]
11    pub ip: Option<String>,
12    /// Port number.
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub port: Option<u16>,
15    /// Domain name.
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub domain: Option<String>,
18    /// Hostname.
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub hostname: Option<String>,
21    /// Subnet UID.
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub subnet_uid: Option<String>,
24}
25
26/// OCSF Network Connection Info object.
27#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
28#[serde(deny_unknown_fields)]
29pub struct ConnectionInfo {
30    /// Protocol name (e.g., "TCP", "UDP").
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub protocol_name: Option<String>,
33    /// Protocol number (6=TCP, 17=UDP).
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub protocol_num: Option<u8>,
36    /// Traffic direction.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub direction: Option<String>,
39    /// Direction ID (0=Unknown, 1=Inbound, 2=Outbound, 3=Lateral).
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub direction_id: Option<u8>,
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47
48    #[test]
49    fn endpoint_roundtrip() {
50        let ep = NetworkEndpoint {
51            ip: Some("10.0.0.1".to_string()),
52            port: Some(443),
53            domain: Some("api.example.com".to_string()),
54            hostname: None,
55            subnet_uid: None,
56        };
57        let json = serde_json::to_string(&ep).unwrap();
58        let ep2: NetworkEndpoint = serde_json::from_str(&json).unwrap();
59        assert_eq!(ep, ep2);
60    }
61
62    #[test]
63    fn connection_info_roundtrip() {
64        let ci = ConnectionInfo {
65            protocol_name: Some("TCP".to_string()),
66            protocol_num: Some(6),
67            direction: Some("Outbound".to_string()),
68            direction_id: Some(2),
69        };
70        let json = serde_json::to_string(&ci).unwrap();
71        let ci2: ConnectionInfo = serde_json::from_str(&json).unwrap();
72        assert_eq!(ci, ci2);
73    }
74}