use std::net::{Ipv4Addr, SocketAddr};
#[allow(dead_code)]
#[derive(Hash, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Debug, Default)]
pub(crate) enum IpProtocol {
#[default]
Tcp,
Udp,
Icmp,
Other(u8),
}
impl std::fmt::Display for IpProtocol {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
IpProtocol::Tcp => write!(f, "TCP"),
IpProtocol::Udp => write!(f, "UDP"),
IpProtocol::Icmp => write!(f, "ICMP"),
IpProtocol::Other(v) => write!(f, "Other(0x{v:02X})"),
}
}
}
#[derive(Hash, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Debug)]
pub(crate) struct SessionInfo {
pub(crate) src: SocketAddr,
pub(crate) dst: SocketAddr,
pub(crate) protocol: IpProtocol,
id: u64,
}
impl Default for SessionInfo {
fn default() -> Self {
let src = SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0);
let dst = SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0);
Self::new(src, dst, IpProtocol::Tcp)
}
}
static SESSION_ID: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
impl SessionInfo {
pub fn new(src: SocketAddr, dst: SocketAddr, protocol: IpProtocol) -> Self {
let id = SESSION_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
Self { src, dst, protocol, id }
}
}
impl std::fmt::Display for SessionInfo {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "#{} {} {} -> {}", self.id, self.protocol, self.src, self.dst)
}
}