use mutnet::arp::{Arp, ArpMethodsMut};
use mutnet::data_buffer::{BufferIntoInner, DataBuffer, PayloadMut};
use mutnet::ethernet::{Eth, EthernetMethodsMut};
use mutnet::ipv4::{Ipv4, Ipv4MethodsMut};
use mutnet::ipv6::{Ipv6, Ipv6MethodsMut};
use mutnet::no_previous_header::NoPreviousHeader;
use mutnet::tcp::{Tcp, TcpMethodsMut};
use mutnet::typed_protocol_headers::{
Dscp, Ecn, EtherType, InternetProtocolNumber, Ipv6ExtensionType, OperationCode,
};
use mutnet::udp::{Udp, UdpMethodsMut};
use rand::{thread_rng, Rng};
use std::net::{Ipv4Addr, Ipv6Addr};
pub fn random_bytes<const SIZE: usize>() -> [u8; SIZE] {
rand::random()
}
#[rustfmt::skip]
pub const ARP_IPV4_REQUEST1: [u8;28] = [
0x00, 0x01,
0x08, 0x00,
0x06,
0x04,
0x00, 0x01,
0x1C, 0xED, 0xA4, 0xE1, 0xD2, 0xA2,
0xC0, 0xA8, 0x0A, 0x01,
0x13, 0xE2, 0xAF, 0xE2, 0xD5, 0xA6,
0xC0, 0xA8, 0x7A, 0x0E,
];
pub fn random_valid_arp() -> [u8; 28] {
let mut rng = thread_rng();
let mut arp =
DataBuffer::<_, Arp<NoPreviousHeader>>::parse_arp_alone(ARP_IPV4_REQUEST1, 0).unwrap();
let operation_code = match rng.gen_range(0..2) {
0_u8 => OperationCode::Reply,
1.. => OperationCode::Request,
};
arp.set_arp_operation_code(operation_code);
arp.set_arp_sender_hardware_address(&rng.gen());
arp.set_arp_sender_protocol_address(&Ipv4Addr::from(rng.gen::<[u8; 4]>()));
arp.set_arp_target_hardware_address(&rng.gen());
arp.set_arp_target_protocol_address(&Ipv4Addr::from(rng.gen::<[u8; 4]>()));
arp.buffer_into_inner()
}
#[rustfmt::skip]
pub const ETHERNET: [u8; 64] = [
0x0, 0x80, 0x41, 0xAE, 0xFD, 0x7E,
0x7E, 0xFD, 0xAE, 0x41, 0x80, 0x0,
0x88, 0x08,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
];
pub fn random_valid_ethernet() -> [u8; 64] {
let mut ethernet = DataBuffer::<_, Eth>::parse_ethernet_layer(ETHERNET, 0).unwrap();
ethernet.set_ethernet_destination(&rand::random());
ethernet.set_ethernet_source(&rand::random());
let ether_type = {
let mut ether_type: u16 = rand::random();
while EtherType::try_from(ether_type).is_err() {
ether_type = rand::random();
}
EtherType::try_from(ether_type).unwrap()
};
ethernet.set_ethernet_ether_type(ether_type);
ethernet
.payload_mut()
.iter_mut()
.for_each(|byte| *byte = rand::random());
ethernet.buffer_into_inner()
}
#[allow(clippy::unusual_byte_groupings)]
#[rustfmt::skip]
pub const IPV4: [u8; 92] = [
0x4F,
0b001010_00,
0x00, 0x48,
0x12, 0x34,
0x00, 0x00,
0x01,
0x06,
0x9F, 0x52,
0x7f, 0x00, 0x00, 0x1,
0x7f, 0x00, 0x00, 0x1,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
];
pub fn random_ipv4() -> [u8; 92] {
let mut rng = thread_rng();
let mut ipv4 =
DataBuffer::<_, Ipv4<NoPreviousHeader>>::parse_ipv4_alone(IPV4, 0, false).unwrap();
ipv4.set_ipv4_ihl(rng.gen_range(0..11) + 5).unwrap();
let dscp = {
let mut dscp: u8 = rng.gen();
while Dscp::try_from(dscp).is_err() {
dscp = rng.gen();
}
Dscp::try_from(dscp).unwrap()
};
ipv4.set_ipv4_dscp(dscp);
let ecn = {
let mut ecn: u8 = rng.gen();
while Ecn::try_from(ecn).is_err() {
ecn = rng.gen();
}
Ecn::try_from(ecn).unwrap()
};
ipv4.set_ipv4_ecn(ecn);
while ipv4.set_ipv4_total_length(rng.gen()).is_err() {}
ipv4.set_ipv4_identification(rng.gen());
ipv4.set_ipv4_flags(rng.gen());
ipv4.set_ipv4_fragment_offset(rng.gen());
ipv4.set_ipv4_time_to_live(rng.gen());
ipv4.set_ipv4_protocol(rng.gen());
ipv4.set_ipv4_header_checksum(rng.gen());
ipv4.set_ipv4_source(Ipv4Addr::from(rng.gen::<[u8; 4]>()));
ipv4.set_ipv4_destination(Ipv4Addr::from(rng.gen::<[u8; 4]>()));
ipv4.ipv4_options_mut()
.iter_mut()
.for_each(|byte| *byte = rng.gen());
ipv4.payload_mut()
.iter_mut()
.for_each(|byte| *byte = rng.gen());
ipv4.buffer_into_inner()
}
#[rustfmt::skip]
pub const IPV6: [u8; 60] = [
0x61, 0x23, 0xFF, 0xFF,
0x00, 0x01,
InternetProtocolNumber::Tcp as u8,
0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
];
pub fn random_ipv6() -> [u8; 60] {
let mut ipv6 = DataBuffer::<_, Ipv6<NoPreviousHeader>>::parse_ipv6_alone(IPV6, 0).unwrap();
ipv6.set_ipv6_traffic_class(rand::random());
ipv6.set_ipv6_flow_label(rand::random());
while ipv6.set_ipv6_payload_length(rand::random()).is_err() {}
ipv6.set_ipv6_next_header(rand::random());
ipv6.set_ipv6_hop_limit(rand::random());
ipv6.set_ipv6_source(Ipv6Addr::from(rand::random::<[u8; 16]>()));
ipv6.set_ipv6_destination(Ipv6Addr::from(rand::random::<[u8; 16]>()));
ipv6.payload_mut()
.iter_mut()
.for_each(|byte| *byte = rand::random());
ipv6.buffer_into_inner()
}
pub const MEM_TO_FILL: usize = 64;
pub const MAX_EXTENSIONS: usize = 16;
pub fn random_valid_ipv6_extensions<const MEM_TO_FILL: usize>(
) -> ([u8; MEM_TO_FILL], Ipv6ExtensionType) {
assert!(MEM_TO_FILL >= 8);
let mut rng = thread_rng();
let mut data_buffer = [0_u8; MEM_TO_FILL];
let mut idx = 0;
let mut next_header;
let mut this_header;
let mut first_extension = Ipv6ExtensionType::HopByHop as u8;
let mut length = rng.gen_range(0..3);
let mut remaining_space = MEM_TO_FILL;
if rng.gen::<bool>() {
while MEM_TO_FILL < idx + (usize::from(length) + 1) * 8 {
length -= 1;
}
remaining_space = remaining_space.saturating_sub((usize::from(length) + 1) * 8);
next_header = match rng.gen_range(0..3) {
0_u8 => Ipv6ExtensionType::Routing as u8,
1 => Ipv6ExtensionType::Fragment as u8,
2.. => Ipv6ExtensionType::DestinationOptions as u8,
};
data_buffer[idx] = next_header;
idx += 1;
data_buffer[idx] = length;
idx += 1;
for _ in 0..((usize::from(length) + 1) * 8 - 2) {
data_buffer[idx] = rng.gen();
idx += 1;
}
this_header = next_header;
} else {
first_extension = match rng.gen_range(0..3) {
0_u8 => Ipv6ExtensionType::Routing as u8,
1 => Ipv6ExtensionType::Fragment as u8,
2.. => Ipv6ExtensionType::DestinationOptions as u8,
};
this_header = first_extension;
next_header = if remaining_space >= 8 {
match rng.gen_range(0..3) {
0_u8 => Ipv6ExtensionType::Routing as u8,
1 => Ipv6ExtensionType::Fragment as u8,
2.. => Ipv6ExtensionType::DestinationOptions as u8,
}
} else {
rng.gen_range(Ipv6ExtensionType::DestinationOptions as u8 + 1..u8::MAX)
};
}
while Ipv6ExtensionType::try_from(next_header).is_ok() {
if this_header == Ipv6ExtensionType::Fragment as u8 {
length = 0;
} else {
length = rng.gen_range(0..3);
}
while MEM_TO_FILL < idx + (usize::from(length) + 1) * 8 {
length -= 1;
}
remaining_space = remaining_space.saturating_sub((usize::from(length) + 1) * 8);
next_header = if remaining_space >= 8 {
match rng.gen_range(0..3) {
0_u8 => Ipv6ExtensionType::Routing as u8,
1 => Ipv6ExtensionType::Fragment as u8,
2.. => Ipv6ExtensionType::DestinationOptions as u8,
}
} else {
rng.gen_range(Ipv6ExtensionType::DestinationOptions as u8 + 1..u8::MAX)
};
data_buffer[idx] = next_header;
idx += 1;
data_buffer[idx] = length;
idx += 1;
this_header = next_header;
for _ in 0..(((usize::from(length) + 1) * 8) - 2) {
data_buffer[idx] = rng.gen();
idx += 1;
}
}
(
data_buffer,
Ipv6ExtensionType::try_from(first_extension).unwrap(),
)
}
#[rustfmt::skip]
pub const UDP: [u8; 14] = [
0x12, 0x34,
0x0, 0x0,
0x00, 0x0C,
0xAB, 0xCD,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
];
pub fn random_udp() -> [u8; 14] {
let mut rng = thread_rng();
let mut udp = DataBuffer::<_, Udp<NoPreviousHeader>>::parse_udp_alone(UDP, 0).unwrap();
udp.set_udp_destination_port(rand::random());
udp.set_udp_source_port(rand::random());
udp.set_udp_checksum(rand::random());
udp.set_udp_length(rng.gen_range(8..14)).unwrap();
udp.payload_mut()
.iter_mut()
.for_each(|byte| *byte = rand::random());
udp.buffer_into_inner()
}
#[allow(clippy::unusual_byte_groupings)]
#[rustfmt::skip]
pub const TCP: [u8;60] = [
0x12, 0x34,
0x45, 0x67,
0x12, 0x34, 0x56, 0x78,
0x09, 0x87, 0x65, 0x43,
0xF0, 0b0101_0101,
0x12, 0x45,
0x12, 0x34,
0x56, 0x78,
0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
];
pub fn random_tcp() -> [u8; 60] {
let mut tcp = DataBuffer::<_, Tcp<NoPreviousHeader>>::parse_tcp_alone(TCP, 0).unwrap();
tcp.set_tcp_source_port(rand::random());
tcp.set_tcp_destination_port(rand::random());
tcp.set_tcp_sequence_number(rand::random());
tcp.set_tcp_acknowledgement_number(rand::random());
tcp.set_tcp_reserved_bits(rand::random());
tcp.set_tcp_flags(rand::random());
tcp.set_tcp_window_size(rand::random());
tcp.set_tcp_checksum(rand::random());
tcp.set_tcp_urgent_pointer(rand::random());
if let Some(options) = tcp.tcp_options_mut() {
options.iter_mut().for_each(|byte| *byte = rand::random());
}
tcp.payload_mut()
.iter_mut()
.for_each(|byte| *byte = rand::random());
let mut buffer = tcp.buffer_into_inner();
buffer[13] = rand::random();
buffer
}
#[allow(clippy::unusual_byte_groupings)]
#[rustfmt::skip]
pub const IPV4_TCP: [u8; 120] = [
0x4F,
0b001010_00,
0x00, 0x78,
0x12, 0x34,
0x00, 0x00,
0x01,
0x06,
0x9F, 0x52,
0x7f, 0x00, 0x00, 0x1,
0x7f, 0x00, 0x00, 0x1,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0x12, 0x34,
0x45, 0x67,
0x12, 0x34, 0x56, 0x78,
0x09, 0x87, 0x65, 0x43,
0xF0, 0b0101_0101,
0x12, 0x45,
0x12, 0x34,
0x56, 0x78,
0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
];
pub fn random_ipv4_tcp() -> [u8; 120] {
let mut rng = thread_rng();
let ipv4 =
DataBuffer::<_, Ipv4<NoPreviousHeader>>::parse_ipv4_alone(IPV4_TCP, 0, false).unwrap();
let mut ipv4_tcp = DataBuffer::<_, _>::parse_tcp_layer(ipv4, false).unwrap();
ipv4_tcp.set_ipv4_ihl(rng.gen_range(0..11) + 5).unwrap();
let dscp = {
let mut dscp: u8 = rng.gen();
while Dscp::try_from(dscp).is_err() {
dscp = rng.gen();
}
Dscp::try_from(dscp).unwrap()
};
ipv4_tcp.set_ipv4_dscp(dscp);
let ecn = {
let mut ecn: u8 = rng.gen();
while Ecn::try_from(ecn).is_err() {
ecn = rng.gen();
}
Ecn::try_from(ecn).unwrap()
};
ipv4_tcp.set_ipv4_ecn(ecn);
while ipv4_tcp.set_ipv4_total_length(rng.gen()).is_err() {}
ipv4_tcp.set_ipv4_identification(rng.gen());
ipv4_tcp.set_ipv4_flags(rng.gen());
ipv4_tcp.set_ipv4_fragment_offset(rng.gen());
ipv4_tcp.set_ipv4_time_to_live(rng.gen());
ipv4_tcp.set_ipv4_protocol(rng.gen());
ipv4_tcp.set_ipv4_header_checksum(rng.gen());
ipv4_tcp.set_ipv4_source(Ipv4Addr::from(rng.gen::<[u8; 4]>()));
ipv4_tcp.set_ipv4_destination(Ipv4Addr::from(rng.gen::<[u8; 4]>()));
ipv4_tcp
.ipv4_options_mut()
.iter_mut()
.for_each(|byte| *byte = rng.gen());
ipv4_tcp.set_tcp_source_port(rand::random());
ipv4_tcp.set_tcp_destination_port(rand::random());
ipv4_tcp.set_tcp_sequence_number(rand::random());
ipv4_tcp.set_tcp_acknowledgement_number(rand::random());
ipv4_tcp.set_tcp_reserved_bits(rand::random());
ipv4_tcp.set_tcp_flags(rand::random());
ipv4_tcp.set_tcp_window_size(rand::random());
ipv4_tcp.set_tcp_checksum(rand::random());
ipv4_tcp.set_tcp_urgent_pointer(rand::random());
if let Some(options) = ipv4_tcp.tcp_options_mut() {
options.iter_mut().for_each(|byte| *byte = rand::random());
}
ipv4_tcp
.payload_mut()
.iter_mut()
.for_each(|byte| *byte = rand::random());
ipv4_tcp.buffer_into_inner()
}
pub const ETH_IPV4_TCP: [u8; 64] = [
0x00,
0x80,
0x41,
0xAE,
0xFD,
0x7E, 0x7E,
0xFD,
0xAE,
0x41,
0x80,
0x00, 0x08,
0x00, 0x46,
0b0010_1000,
0x00,
0x32,
0x12,
0x34,
0b101_00000,
0x03,
0x01,
0x06,
0x06,
0x61,
0x7f,
0x00,
0x00,
0x1,
0x7f,
0x00,
0x00,
0x1,
0x02,
0x04,
0xFF,
0xFF,
0x12,
0x34,
0x45,
0x67,
0x12,
0x34,
0x56,
0x78,
0x09,
0x87,
0x65,
0x43,
0x50,
0b0101_0101,
0x12,
0x45,
0x19,
0xB8,
0x56,
0x78,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF,
];