pub mod ethernet;
pub mod ip;
pub mod tcp;
pub mod udp;
pub mod icmp;
pub mod arp;
pub mod dhcp;
pub mod error;
pub mod socket;
pub use error::PacketError;
pub trait PacketBuilder {
fn build(&self) -> Result<Vec<u8>, PacketError>;
fn length(&self) -> usize;
fn validate(&self) -> Result<(), PacketError>;
}
pub trait Checksumable {
fn calculate_checksum(&self) -> u16;
fn verify_checksum(&self) -> bool;
}
pub trait PacketHeader {
fn header_length(&self) -> usize;
fn as_bytes(&self) -> Result<Vec<u8>, PacketError>;
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ethernet::{EthernetPacket, MacAddress, EtherType};
use crate::ip::{Ipv4Packet, Ipv4Address, IpProtocol};
use crate::tcp::{TcpPacket, TcpFlags};
use crate::udp::UdpPacket;
use crate::icmp::{IcmpPacket, IcmpType};
use crate::arp::{ArpPacket, Operation as ArpOperation};
use crate::dhcp::DhcpPacket;
#[test]
fn test_ethernet_packet() {
let src_mac = MacAddress::new([0x00, 0x11, 0x22, 0x33, 0x44, 0x55]);
let dst_mac = MacAddress::new([0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB]);
let packet = EthernetPacket::builder()
.src_mac(src_mac)
.dst_mac(dst_mac)
.ether_type(EtherType::IPv4)
.payload(vec![1, 2, 3, 4])
.build()
.unwrap();
assert!(packet.validate().is_ok());
let bytes = packet.build().unwrap();
assert_eq!(bytes.len(), 60); }
#[test]
fn test_ipv4_packet() {
let src_ip = Ipv4Address::new([192, 168, 1, 1]);
let dst_ip = Ipv4Address::new([192, 168, 1, 2]);
let packet = Ipv4Packet::builder()
.protocol(IpProtocol::TCP)
.src_addr(src_ip)
.dst_addr(dst_ip)
.payload(vec![1, 2, 3, 4])
.build()
.unwrap();
assert!(packet.validate().is_ok());
let bytes = packet.build().unwrap();
assert_eq!(bytes.len(), 24); }
#[test]
fn test_tcp_packet() {
let mut flags = TcpFlags::new();
flags.syn = true;
let packet = TcpPacket::builder()
.src_port(12345)
.dst_port(80)
.sequence(1000)
.flags(flags)
.payload(vec![1, 2, 3, 4])
.build()
.unwrap();
assert!(packet.validate().is_ok());
let bytes = packet.build().unwrap();
assert_eq!(bytes.len(), 24); }
#[test]
fn test_udp_packet() {
let packet = UdpPacket::builder()
.src_port(12345)
.dst_port(53)
.payload(vec![1, 2, 3, 4])
.build()
.unwrap();
assert!(packet.validate().is_ok());
let bytes = packet.build().unwrap();
assert_eq!(bytes.len(), 12); }
#[test]
fn test_icmp_packet() {
let packet = IcmpPacket::echo_request(1, 1, b"Hello, World!".to_vec()).unwrap();
assert!(packet.validate().is_ok());
assert_eq!(packet.header.message_type as u8, IcmpType::EchoRequest as u8);
}
#[test]
fn test_arp_packet() {
let src_mac = MacAddress::new([0x00, 0x11, 0x22, 0x33, 0x44, 0x55]);
let src_ip = Ipv4Address::new([192, 168, 1, 1]);
let target_ip = Ipv4Address::new([192, 168, 1, 2]);
let packet = ArpPacket::request(src_mac, src_ip, target_ip).unwrap();
assert!(packet.validate().is_ok());
assert_eq!(packet.header.operation as u16, ArpOperation::Request as u16);
}
#[test]
fn test_dhcp_packet() {
let chaddr = MacAddress::new([0x00, 0x11, 0x22, 0x33, 0x44, 0x55]);
let xid = 0x12345678;
let packet = DhcpPacket::discover(xid, chaddr).unwrap();
assert!(packet.validate().is_ok());
assert_eq!(packet.header.op, 1); }
}