xenet_packet_builder/
tcp.rs1use std::net::{IpAddr, SocketAddr};
2use xenet_packet::ethernet::ETHERNET_HEADER_LEN;
3use xenet_packet::ipv4::IPV4_HEADER_LEN;
4use xenet_packet::ipv6::IPV6_HEADER_LEN;
5use xenet_packet::tcp::TCP_MIN_DATA_OFFSET;
6use xenet_packet::tcp::{MutableTcpPacket, TcpFlags, TcpOption, TCP_HEADER_LEN};
7use xenet_packet::Packet;
8
9pub const TCP_DEFAULT_OPTION_LEN: usize = 12;
11pub const DEFAULT_SRC_PORT: u16 = 53443;
13pub const TCPV4_MINIMUM_PACKET_LEN: usize = ETHERNET_HEADER_LEN + IPV4_HEADER_LEN + TCP_HEADER_LEN;
15pub const TCPV4_DEFAULT_PACKET_LEN: usize =
17 ETHERNET_HEADER_LEN + IPV4_HEADER_LEN + TCP_HEADER_LEN + TCP_DEFAULT_OPTION_LEN;
18pub const TCPV4_MINIMUM_IP_PACKET_LEN: usize = IPV4_HEADER_LEN + TCP_HEADER_LEN;
20pub const TCPV4_DEFAULT_IP_PACKET_LEN: usize =
22 IPV4_HEADER_LEN + TCP_HEADER_LEN + TCP_DEFAULT_OPTION_LEN;
23pub const TCPV6_MINIMUM_PACKET_LEN: usize = ETHERNET_HEADER_LEN + IPV6_HEADER_LEN + TCP_HEADER_LEN;
25pub const TCPV6_DEFAULT_PACKET_LEN: usize =
27 ETHERNET_HEADER_LEN + IPV6_HEADER_LEN + TCP_HEADER_LEN + TCP_DEFAULT_OPTION_LEN;
28pub const TCPV6_MINIMUM_IP_PACKET_LEN: usize = IPV6_HEADER_LEN + TCP_HEADER_LEN;
30pub const TCPV6_DEFAULT_IP_PACKET_LEN: usize =
32 IPV6_HEADER_LEN + TCP_HEADER_LEN + TCP_DEFAULT_OPTION_LEN;
33
34pub fn get_tcp_options_length(data_offset: u8) -> usize {
36 if data_offset > 5 {
37 data_offset as usize * 4 - TCP_HEADER_LEN
38 } else {
39 0
40 }
41}
42
43pub fn get_tcp_data_offset(opstions: Vec<TcpOption>) -> u8 {
45 let mut total_size: u8 = 0;
46 for opt in opstions {
47 total_size += opt.kind().size() as u8;
48 }
49 if total_size % 4 == 0 {
50 total_size / 4 + TCP_MIN_DATA_OFFSET
51 } else {
52 total_size / 4 + TCP_MIN_DATA_OFFSET + 1
53 }
54}
55
56pub(crate) fn build_tcp_packet(
57 tcp_packet: &mut MutableTcpPacket,
58 src_ip: IpAddr,
59 src_port: u16,
60 dst_ip: IpAddr,
61 dst_port: u16,
62) {
63 tcp_packet.set_source(src_port);
64 tcp_packet.set_destination(dst_port);
65 tcp_packet.set_window(64240);
66 tcp_packet.set_data_offset(8);
67 tcp_packet.set_urgent_ptr(0);
68 tcp_packet.set_sequence(0);
69 tcp_packet.set_options(&[
70 TcpOption::mss(1460),
71 TcpOption::sack_perm(),
72 TcpOption::nop(),
73 TcpOption::nop(),
74 TcpOption::wscale(7),
75 ]);
76 tcp_packet.set_flags(TcpFlags::SYN);
77 match src_ip {
78 IpAddr::V4(src_ip) => match dst_ip {
79 IpAddr::V4(dst_ip) => {
80 let checksum =
81 xenet_packet::tcp::ipv4_checksum(&tcp_packet.to_immutable(), &src_ip, &dst_ip);
82 tcp_packet.set_checksum(checksum);
83 }
84 IpAddr::V6(_) => {}
85 },
86 IpAddr::V6(src_ip) => match dst_ip {
87 IpAddr::V4(_) => {}
88 IpAddr::V6(dst_ip) => {
89 let checksum =
90 xenet_packet::tcp::ipv6_checksum(&tcp_packet.to_immutable(), &src_ip, &dst_ip);
91 tcp_packet.set_checksum(checksum);
92 }
93 },
94 }
95}
96
97#[derive(Clone, Debug)]
99pub struct TcpPacketBuilder {
100 pub src_ip: IpAddr,
102 pub src_port: u16,
104 pub dst_ip: IpAddr,
106 pub dst_port: u16,
108 pub window: u16,
110 pub flags: u8,
112 pub options: Vec<TcpOption>,
114 pub payload: Vec<u8>,
116}
117
118impl TcpPacketBuilder {
119 pub fn new(src_addr: SocketAddr, dst_addr: SocketAddr) -> TcpPacketBuilder {
121 TcpPacketBuilder {
122 src_ip: src_addr.ip(),
123 src_port: src_addr.port(),
124 dst_ip: dst_addr.ip(),
125 dst_port: dst_addr.port(),
126 window: 64240,
127 flags: TcpFlags::SYN,
128 options: vec![
129 TcpOption::mss(1460),
130 TcpOption::sack_perm(),
131 TcpOption::nop(),
132 TcpOption::nop(),
133 TcpOption::wscale(7),
134 ],
135 payload: vec![],
136 }
137 }
138 pub fn build(&self) -> Vec<u8> {
140 let data_offset = get_tcp_data_offset(self.options.clone());
141 let tcp_options_len = get_tcp_options_length(data_offset);
142 let mut buffer: Vec<u8> = vec![0; TCP_HEADER_LEN + tcp_options_len + self.payload.len()];
143 let mut tcp_packet = MutableTcpPacket::new(&mut buffer).unwrap();
144 tcp_packet.set_source(self.src_port);
145 tcp_packet.set_destination(self.dst_port);
146 tcp_packet.set_window(self.window);
147 tcp_packet.set_data_offset(data_offset);
148 tcp_packet.set_urgent_ptr(0);
149 tcp_packet.set_sequence(0);
150 tcp_packet.set_flags(self.flags);
151 tcp_packet.set_options(&self.options);
152 if self.payload.len() > 0 {
153 tcp_packet.set_payload(&self.payload);
154 }
155 match self.src_ip {
156 IpAddr::V4(src_ip) => match self.dst_ip {
157 IpAddr::V4(dst_ip) => {
158 let checksum = xenet_packet::tcp::ipv4_checksum(
159 &tcp_packet.to_immutable(),
160 &src_ip,
161 &dst_ip,
162 );
163 tcp_packet.set_checksum(checksum);
164 }
165 IpAddr::V6(_) => {}
166 },
167 IpAddr::V6(src_ip) => match self.dst_ip {
168 IpAddr::V4(_) => {}
169 IpAddr::V6(dst_ip) => {
170 let checksum = xenet_packet::tcp::ipv6_checksum(
171 &tcp_packet.to_immutable(),
172 &src_ip,
173 &dst_ip,
174 );
175 tcp_packet.set_checksum(checksum);
176 }
177 },
178 }
179 tcp_packet.packet().to_vec()
180 }
181}