use crate::tcp::TcpHeader;
use std::net::Ipv4Addr;
use std::str::FromStr;
#[derive(Debug)]
pub struct IpHeader {
pub version_ihl: u8,
pub tos: u8,
pub len: u16,
pub id: u16,
pub offset: u16,
pub ttl: u8,
pub protocol: u8,
pub sum: u16,
pub src: u32,
pub dst: u32,
}
impl IpHeader {
pub fn new(source_ip: u32, dest_ip: &str) -> Self {
let mut ip_header = Self {
version_ihl: 69,
tos: 0,
len: 0,
id: 0,
offset: 0,
ttl: 50,
protocol: 6,
sum: 0,
src: source_ip,
dst: Ipv4Addr::from_str(dest_ip).unwrap().into(),
};
ip_header.len = (std::mem::size_of::<IpHeader>() + std::mem::size_of::<TcpHeader>()) as u16;
ip_header
}
pub fn as_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::with_capacity(20);
bytes.push(self.version_ihl);
bytes.push(self.tos);
bytes.extend_from_slice(&self.len.to_be_bytes());
bytes.extend_from_slice(&self.id.to_be_bytes());
bytes.extend_from_slice(&self.offset.to_be_bytes());
bytes.push(self.ttl);
bytes.push(self.protocol);
bytes.extend_from_slice(&self.sum.to_be_bytes());
bytes.extend_from_slice(&self.src.to_be_bytes());
bytes.extend_from_slice(&self.dst.to_be_bytes());
bytes
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ip_header_as_bytes() {
let ip_header = IpHeader {
version_ihl: 0x45,
tos: 0,
len: 20,
id: 0,
offset: 0,
ttl: 64,
protocol: 6,
sum: 0,
src: 0xC0A80001, dst: 0xC0A80002, };
assert_eq!(
ip_header.as_bytes(),
&[69, 0, 0, 20, 0, 0, 0, 0, 64, 6, 0, 0, 192, 168, 0, 1, 192, 168, 0, 2]
);
}
}