use std::net::IpAddr;
use bytes::Bytes;
pub const IPV4_HEADER_SIZE: u16 = 20;
pub const IPV6_HEADER_SIZE: u16 = 40;
pub const UDP_HEADER_SIZE: u16 = 8;
pub const TCP_HEADER_SIZE: u16 = 20;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Packet {
pub src: IpAddr,
pub dst: IpAddr,
pub ttl: u8,
pub payload: Transport,
}
impl Packet {
pub fn size(&self) -> u32 {
let ip_hdr = match self.dst {
IpAddr::V4(_) => IPV4_HEADER_SIZE,
IpAddr::V6(_) => IPV6_HEADER_SIZE,
} as u32;
ip_hdr + self.payload.size()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Transport {
Udp(UdpDatagram),
Tcp(TcpSegment),
}
impl Transport {
pub fn size(&self) -> u32 {
match self {
Transport::Udp(d) => UDP_HEADER_SIZE as u32 + d.payload.len() as u32,
Transport::Tcp(s) => TCP_HEADER_SIZE as u32 + s.payload.len() as u32,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UdpDatagram {
pub src_port: u16,
pub dst_port: u16,
pub payload: Bytes,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TcpSegment {
pub src_port: u16,
pub dst_port: u16,
pub seq: u32,
pub ack: u32,
pub flags: TcpFlags,
pub window: u16,
pub payload: Bytes,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct TcpFlags {
pub syn: bool,
pub ack: bool,
pub fin: bool,
pub rst: bool,
pub psh: bool,
pub urg: bool,
}