falco_event/types/net/
sockaddr.rs

1use crate::ffi::{PPM_AF_INET, PPM_AF_INET6, PPM_AF_LOCAL, PPM_AF_UNSPEC};
2use crate::fields::{FromBytes, FromBytesError, ToBytes};
3use crate::types::{EndpointV4, EndpointV6};
4use std::fmt::{Debug, Formatter};
5use std::io::Write;
6use typed_path::UnixPath;
7
8/// A socket address
9#[derive(Clone, Copy, PartialEq, Eq, Hash)]
10pub enum SockAddr<'a> {
11    /// Unix sockets
12    Unix(&'a UnixPath),
13
14    /// IPv4 sockets
15    V4(EndpointV4),
16
17    /// IPv6 socket
18    V6(EndpointV6),
19
20    /// any other address family is represented as the number (`PPM_AF_*` constant) and the raw data
21    Other(u8, &'a [u8]),
22}
23
24impl ToBytes for SockAddr<'_> {
25    fn binary_size(&self) -> usize {
26        match self {
27            Self::Unix(p) => 1 + p.binary_size(),
28            Self::V4(addr) => 1 + addr.binary_size(),
29            Self::V6(addr) => 1 + addr.binary_size(),
30            Self::Other(_, buf) => 1 + buf.len(),
31        }
32    }
33
34    fn write<W: Write>(&self, mut writer: W) -> std::io::Result<()> {
35        match self {
36            Self::Unix(p) => {
37                writer.write_all(&[PPM_AF_LOCAL as u8])?;
38                p.write(writer)
39            }
40            Self::V4(addr) => {
41                writer.write_all(&[PPM_AF_INET as u8])?;
42                addr.write(writer)
43            }
44            Self::V6(addr) => {
45                writer.write_all(&[PPM_AF_INET6 as u8])?;
46                addr.write(writer)
47            }
48            Self::Other(af, addr) => {
49                writer.write_all(&[*af])?;
50                ToBytes::write(addr, writer)
51            }
52        }
53    }
54
55    fn default_repr() -> impl ToBytes {
56        PPM_AF_UNSPEC as u8
57    }
58}
59
60impl<'a> FromBytes<'a> for SockAddr<'a> {
61    fn from_bytes(buf: &mut &'a [u8]) -> Result<Self, FromBytesError> {
62        let variant = buf.split_off_first().ok_or(FromBytesError::InvalidLength)?;
63
64        match *variant as u32 {
65            PPM_AF_LOCAL => {
66                let path: &UnixPath = FromBytes::from_bytes(buf)?;
67                Ok(Self::Unix(path))
68            }
69            PPM_AF_INET => {
70                let addr = EndpointV4::from_bytes(buf)?;
71                Ok(Self::V4(addr))
72            }
73            PPM_AF_INET6 => {
74                let addr = EndpointV6::from_bytes(buf)?;
75                Ok(Self::V6(addr))
76            }
77            _ => Ok(Self::Other(*variant, std::mem::take(buf))),
78        }
79    }
80}
81
82impl Debug for SockAddr<'_> {
83    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
84        match self {
85            SockAddr::Unix(u) => write!(f, "unix://{}", u.display()),
86            SockAddr::V4(v4) => write!(f, "{}:{}", v4.0, v4.1 .0),
87            SockAddr::V6(v6) => write!(f, "[{}]:{}", v6.0, v6.1 .0),
88            SockAddr::Other(af, raw) => write!(f, "<af={}>{:02x?}", af, raw),
89        }
90    }
91}