use pnet::{
datalink::{channel, Channel, DataLinkReceiver, DataLinkSender, MacAddr, NetworkInterface},
packet::{
ethernet::{EtherTypes, MutableEthernetPacket},
ip::IpNextHeaderProtocols,
ipv4::{checksum as ipv4_checksum, Ipv4Flags, MutableIpv4Packet},
tcp::{ipv4_checksum as tcp_checksum, MutableTcpPacket, TcpFlags},
},
transport::{transport_channel, TransportChannelType, TransportProtocol, TransportReceiver, TransportSender},
};
use python_comm::raise_error_use::*;
use rand::{rngs::ThreadRng, Rng};
use std::net::Ipv4Addr;
pub fn build_l2_tcp_packet(
tx_packet: &mut [u8],
body_size: usize,
src_mac: &MacAddr,
dst_mac: &MacAddr,
src_ip: &Ipv4Addr,
dst_ip: &Ipv4Addr,
src_port: u16,
dst_port: u16,
seq: u32,
rng: &mut ThreadRng,
) {
if let Some(mut eth_header) = MutableEthernetPacket::new(&mut tx_packet[..14]) {
eth_header.set_destination(*dst_mac);
eth_header.set_source(*src_mac);
eth_header.set_ethertype(EtherTypes::Ipv4);
}
if let Some(mut ip_header) = MutableIpv4Packet::new(&mut tx_packet[14..(14 + 20)]) {
ip_header.set_header_length(69);
ip_header.set_total_length(40 + body_size as u16);
ip_header.set_next_level_protocol(IpNextHeaderProtocols::Tcp);
ip_header.set_source(*src_ip);
ip_header.set_destination(*dst_ip);
ip_header.set_identification(rng.gen::<u16>());
ip_header.set_ttl(64);
ip_header.set_version(4);
ip_header.set_flags(Ipv4Flags::DontFragment);
let checksum = ipv4_checksum(&ip_header.to_immutable());
ip_header.set_checksum(checksum);
}
if let Some(mut tcp_header) = MutableTcpPacket::new(&mut tx_packet[(14 + 20)..]) {
build_l4_tcp_packet(&mut tcp_header, src_ip, dst_ip, src_port, dst_port, seq, rng);
}
}
pub fn build_l4_tcp_packet(
tx_packet: &mut MutableTcpPacket,
src_ip: &Ipv4Addr,
dst_ip: &Ipv4Addr,
src_port: u16,
dst_port: u16,
seq: u32,
rng: &mut ThreadRng,
) {
tx_packet.set_source(src_port);
tx_packet.set_destination(dst_port);
tx_packet.set_sequence(seq);
tx_packet.set_acknowledgement(0);
tx_packet.set_flags(TcpFlags::SYN);
tx_packet.set_window(30000 + (rng.gen::<u8>() as u16 * 17));
tx_packet.set_data_offset(5);
tx_packet.set_urgent_ptr(0);
let checksum = tcp_checksum(&tx_packet.to_immutable(), src_ip, dst_ip);
tx_packet.set_checksum(checksum);
}
#[auto_func_name]
pub fn create_l2_channel(
iface: &NetworkInterface,
) -> Result<(Box<dyn DataLinkSender>, Box<dyn DataLinkReceiver>), anyhow::Error> {
match channel(&iface, Default::default()) {
Ok(Channel::Ethernet(tx, rx)) => Ok((tx, rx)),
Ok(_) => raise_error!(__func__, "不支持的通道类型"),
Err(err) => raise_error!(__func__, "\n", err),
}
}
#[auto_func_name]
pub fn create_l4_channel() -> Result<(TransportSender, TransportReceiver), anyhow::Error> {
let protocol = TransportChannelType::Layer4(TransportProtocol::Ipv4(IpNextHeaderProtocols::Tcp));
transport_channel(256, protocol).or_else(|err| {
let text = format!("{:?}", err);
if text.contains("code: 10013,") {
raise_error!(__func__, "权限不足")
} else {
raise_error!(__func__, "\n", err)
}
})
}
#[auto_func_name]
pub fn send_tcp<F>(
tx: &mut Box<dyn DataLinkSender>,
body_size: usize,
src_mac: &MacAddr,
dst_mac: &MacAddr,
src_ip: &Ipv4Addr,
dst_ip: &Ipv4Addr,
src_port: u16,
dst_port: u16,
seq: u32,
rng: &mut ThreadRng,
modify_packet_func: F,
) -> Result<(), anyhow::Error>
where
F: Fn(&mut [u8]) -> bool,
{
if let None = tx.build_and_send(1, 14 + 20 + 20 + body_size, &mut |tx_packet: &mut [u8]| {
build_l2_tcp_packet(
tx_packet, body_size, src_mac, dst_mac, src_ip, dst_ip, src_port, dst_port, seq, rng,
);
if modify_packet_func(tx_packet) {
set_l2_tcp_packet_checksum(tx_packet, src_ip, dst_ip);
}
}) {
return raise_error!(__func__, "创建或发送失败");
}
Ok(())
}
fn set_l2_tcp_packet_checksum(tx_packet: &mut [u8], src_ip: &Ipv4Addr, dst_ip: &Ipv4Addr) {
if let Some(mut tcp_header) = MutableTcpPacket::new(&mut tx_packet[(14 + 20)..]) {
tcp_header.set_checksum(0);
let checksum = tcp_checksum(&tcp_header.to_immutable(), src_ip, dst_ip);
tcp_header.set_checksum(checksum);
}
}