1use pnet::packet::Packet;
2use std::net::{IpAddr, SocketAddr};
3use crate::packet::ethernet::ETHERNET_HEADER_LEN;
4use crate::packet::ipv4::IPV4_HEADER_LEN;
5use crate::packet::ipv6::IPV6_HEADER_LEN;
6
7pub const TCP_HEADER_LEN: usize = pnet::packet::tcp::MutableTcpPacket::minimum_packet_size();
9pub const TCP_MIN_DATA_OFFSET: u8 = 5;
11pub const TCP_OPTION_MAX_LEN: usize = 40;
13pub const TCP_HEADER_MAX_LEN: usize = TCP_HEADER_LEN + TCP_OPTION_MAX_LEN;
15pub const TCP_DEFAULT_OPTION_LEN: usize = 12;
17pub const DEFAULT_SRC_PORT: u16 = 53443;
19
20pub const TCPV4_MINIMUM_PACKET_LEN: usize = ETHERNET_HEADER_LEN + IPV4_HEADER_LEN + TCP_HEADER_LEN;
22pub const TCPV4_DEFAULT_PACKET_LEN: usize = ETHERNET_HEADER_LEN + IPV4_HEADER_LEN + TCP_HEADER_LEN + TCP_DEFAULT_OPTION_LEN;
24pub const TCPV4_MINIMUM_IP_PACKET_LEN: usize = IPV4_HEADER_LEN + TCP_HEADER_LEN;
26pub const TCPV4_DEFAULT_IP_PACKET_LEN: usize = IPV4_HEADER_LEN + TCP_HEADER_LEN + TCP_DEFAULT_OPTION_LEN;
28pub const TCPV6_MINIMUM_PACKET_LEN: usize = ETHERNET_HEADER_LEN + IPV6_HEADER_LEN + TCP_HEADER_LEN;
30pub const TCPV6_DEFAULT_PACKET_LEN: usize = ETHERNET_HEADER_LEN + IPV6_HEADER_LEN + TCP_HEADER_LEN + TCP_DEFAULT_OPTION_LEN;
32pub const TCPV6_MINIMUM_IP_PACKET_LEN: usize = IPV6_HEADER_LEN + TCP_HEADER_LEN;
34pub const TCPV6_DEFAULT_IP_PACKET_LEN: usize = IPV6_HEADER_LEN + TCP_HEADER_LEN + TCP_DEFAULT_OPTION_LEN;
36
37#[derive(Clone, Copy, Debug, PartialEq)]
40pub enum TcpOptionKind {
41 Eol,
42 Nop,
43 Mss,
44 Wscale,
45 SackParmitted,
46 Sack,
47 Timestamp,
48}
49
50impl TcpOptionKind {
51 pub fn from_u8(n: u8) -> TcpOptionKind {
52 match n {
53 0 => TcpOptionKind::Eol,
54 1 => TcpOptionKind::Nop,
55 2 => TcpOptionKind::Mss,
56 3 => TcpOptionKind::Wscale,
57 4 => TcpOptionKind::SackParmitted,
58 5 => TcpOptionKind::Sack,
59 8 => TcpOptionKind::Timestamp,
60 _ => panic!("Unknown TCP option kind: {}", n),
61 }
62 }
63 pub fn number(&self) -> u8 {
65 match *self {
66 TcpOptionKind::Eol => 0,
67 TcpOptionKind::Nop => 1,
68 TcpOptionKind::Mss => 2,
69 TcpOptionKind::Wscale => 3,
70 TcpOptionKind::SackParmitted => 4,
71 TcpOptionKind::Sack => 5,
72 TcpOptionKind::Timestamp => 8,
73 }
74 }
75 pub fn id(&self) -> String {
77 match *self {
78 TcpOptionKind::Eol => String::from("EOL"),
79 TcpOptionKind::Nop => String::from("NOP"),
80 TcpOptionKind::Mss => String::from("MSS"),
81 TcpOptionKind::Wscale => String::from("WSCALE"),
82 TcpOptionKind::SackParmitted => String::from("SACK_PERMITTED"),
83 TcpOptionKind::Sack => String::from("SACK"),
84 TcpOptionKind::Timestamp => String::from("TIMESTAMPS"),
85 }
86 }
87 pub fn name(&self) -> String {
89 match *self {
90 TcpOptionKind::Eol => String::from("EOL"),
91 TcpOptionKind::Nop => String::from("NOP"),
92 TcpOptionKind::Mss => String::from("MSS"),
93 TcpOptionKind::Wscale => String::from("WSCALE"),
94 TcpOptionKind::SackParmitted => String::from("SACK_PERMITTED"),
95 TcpOptionKind::Sack => String::from("SACK"),
96 TcpOptionKind::Timestamp => String::from("TIMESTAMPS"),
97 }
98 }
99 pub fn size(&self) -> usize {
101 match *self {
102 TcpOptionKind::Eol => 1,
103 TcpOptionKind::Nop => 1,
104 TcpOptionKind::Mss => 4,
105 TcpOptionKind::Wscale => 3,
106 TcpOptionKind::SackParmitted => 2,
107 TcpOptionKind::Sack => 10,
108 TcpOptionKind::Timestamp => 10,
109 }
110 }
111}
112
113#[derive(Clone, Debug, PartialEq)]
115pub struct TcpOption {
116 pub kind: TcpOptionKind,
118 pub data: Vec<u8>,
120}
121
122impl TcpOption {
123 pub fn nop() -> Self {
125 TcpOption {
126 kind: TcpOptionKind::Nop,
127 data: vec![],
128 }
129 }
130 pub fn timestamp(my: u32, their: u32) -> Self {
132 let mut data = vec![];
133 data.extend_from_slice(&my.to_be_bytes());
134 data.extend_from_slice(&their.to_be_bytes());
135
136 TcpOption {
137 kind: TcpOptionKind::Timestamp,
138 data: data,
139 }
140 }
141 pub fn get_timestamp(&self) -> (u32, u32) {
143 let mut my: [u8; 4] = [0; 4];
144 my.copy_from_slice(&self.data[0..4]);
145 let mut their: [u8; 4] = [0; 4];
146 their.copy_from_slice(&self.data[4..8]);
147 (u32::from_be_bytes(my), u32::from_be_bytes(their))
148 }
149 pub fn mss(val: u16) -> Self {
151 let mut data = vec![];
152 data.extend_from_slice(&val.to_be_bytes());
153
154 TcpOption {
155 kind: TcpOptionKind::Mss,
156 data: data,
157 }
158 }
159 pub fn get_mss(&self) -> u16 {
161 let mut mss: [u8; 2] = [0; 2];
162 mss.copy_from_slice(&self.data[0..2]);
163 u16::from_be_bytes(mss)
164 }
165 pub fn wscale(val: u8) -> Self {
167 TcpOption {
168 kind: TcpOptionKind::Wscale,
169 data: vec![val],
170 }
171 }
172 pub fn get_wscale(&self) -> u8 {
174 self.data[0]
175 }
176 pub fn sack_perm() -> Self {
178 TcpOption {
179 kind: TcpOptionKind::SackParmitted,
180 data: vec![],
181 }
182 }
183 pub fn selective_ack(acks: &[u32]) -> Self {
185 let mut data = vec![];
186 for ack in acks {
187 data.extend_from_slice(&ack.to_be_bytes());
188 }
189 TcpOption {
190 kind: TcpOptionKind::Sack,
191 data: data,
192 }
193 }
194
195 pub(crate) fn from_pnet_type(opt: pnet::packet::tcp::TcpOptionPacket) -> TcpOption {
196 TcpOption {
197 kind: TcpOptionKind::from_u8(opt.get_number().0),
198 data: opt.payload().to_vec(),
199 }
200 }
201
202 pub(crate) fn to_pnet_type(&self) -> pnet::packet::tcp::TcpOption {
203 match self.kind {
204 TcpOptionKind::Nop => pnet::packet::tcp::TcpOption::nop(),
205 TcpOptionKind::Mss => pnet::packet::tcp::TcpOption::mss(self.get_mss()),
206 TcpOptionKind::Wscale => pnet::packet::tcp::TcpOption::wscale(self.get_wscale()),
207 TcpOptionKind::SackParmitted => pnet::packet::tcp::TcpOption::sack_perm(),
208 TcpOptionKind::Sack => {
209 let mut acks: Vec<u32> = vec![];
210 for i in 0..self.data.len() / 4 {
211 let mut ack: [u8; 4] = [0; 4];
212 ack.copy_from_slice(&self.data[i * 4..i * 4 + 4]);
213 acks.push(u32::from_be_bytes(ack));
214 }
215 pnet::packet::tcp::TcpOption::selective_ack(&acks)
216 }
217 TcpOptionKind::Timestamp => {
218 let (my, their) = self.get_timestamp();
219 pnet::packet::tcp::TcpOption::timestamp(my, their)
220 }
221 _ => pnet::packet::tcp::TcpOption::nop(),
222 }
223 }
224}
225
226#[derive(Clone, Copy, Debug, PartialEq)]
228pub enum TcpFlag {
229 Syn,
230 Fin,
231 Rst,
232 Psh,
233 Ack,
234 Urg,
235 Ece,
236 Cwr,
237 Unknown(u8),
238}
239
240impl TcpFlag {
241 pub fn from_u8(n: u8) -> TcpFlag {
243 match n {
244 pnet::packet::tcp::TcpFlags::SYN => TcpFlag::Syn,
245 pnet::packet::tcp::TcpFlags::FIN => TcpFlag::Fin,
246 pnet::packet::tcp::TcpFlags::RST => TcpFlag::Rst,
247 pnet::packet::tcp::TcpFlags::PSH => TcpFlag::Psh,
248 pnet::packet::tcp::TcpFlags::ACK => TcpFlag::Ack,
249 pnet::packet::tcp::TcpFlags::URG => TcpFlag::Urg,
250 pnet::packet::tcp::TcpFlags::ECE => TcpFlag::Ece,
251 pnet::packet::tcp::TcpFlags::CWR => TcpFlag::Cwr,
252 _ => TcpFlag::Unknown(n),
253 }
254 }
255 pub fn number(&self) -> u8 {
257 match *self {
258 TcpFlag::Syn => pnet::packet::tcp::TcpFlags::SYN,
259 TcpFlag::Fin => pnet::packet::tcp::TcpFlags::FIN,
260 TcpFlag::Rst => pnet::packet::tcp::TcpFlags::RST,
261 TcpFlag::Psh => pnet::packet::tcp::TcpFlags::PSH,
262 TcpFlag::Ack => pnet::packet::tcp::TcpFlags::ACK,
263 TcpFlag::Urg => pnet::packet::tcp::TcpFlags::URG,
264 TcpFlag::Ece => pnet::packet::tcp::TcpFlags::ECE,
265 TcpFlag::Cwr => pnet::packet::tcp::TcpFlags::CWR,
266 TcpFlag::Unknown(n) => n,
267 }
268 }
269 pub fn id(&self) -> String {
271 match *self {
272 TcpFlag::Syn => String::from("SYN"),
273 TcpFlag::Fin => String::from("FIN"),
274 TcpFlag::Rst => String::from("RST"),
275 TcpFlag::Psh => String::from("PSH"),
276 TcpFlag::Ack => String::from("ACK"),
277 TcpFlag::Urg => String::from("URG"),
278 TcpFlag::Ece => String::from("ECE"),
279 TcpFlag::Cwr => String::from("CWR"),
280 TcpFlag::Unknown(n) => format!("UNKNOWN_{}", n),
281 }
282 }
283 pub fn name(&self) -> String {
285 match *self {
286 TcpFlag::Syn => String::from("SYN"),
287 TcpFlag::Fin => String::from("FIN"),
288 TcpFlag::Rst => String::from("RST"),
289 TcpFlag::Psh => String::from("PSH"),
290 TcpFlag::Ack => String::from("ACK"),
291 TcpFlag::Urg => String::from("URG"),
292 TcpFlag::Ece => String::from("ECE"),
293 TcpFlag::Cwr => String::from("CWR"),
294 TcpFlag::Unknown(n) => format!("Unknown({})", n),
295 }
296 }
297}
298
299pub fn get_tcp_options_length(data_offset: u8) -> usize {
301 if data_offset > 5 {
302 data_offset as usize * 4 - TCP_HEADER_LEN
303 } else {
304 0
305 }
306}
307
308pub fn get_tcp_data_offset(opstions: Vec<TcpOption>) -> u8 {
310 let mut total_size: u8 = 0;
311 for opt in opstions {
312 total_size += opt.kind.size() as u8;
313 }
314 if total_size % 4 == 0 {
315 total_size / 4 + TCP_MIN_DATA_OFFSET
316 } else {
317 total_size / 4 + TCP_MIN_DATA_OFFSET + 1
318 }
319}
320
321#[derive(Clone, Debug, PartialEq)]
323pub struct TcpPacket {
324 pub source: u16,
326 pub destination: u16,
328 pub sequence: u32,
330 pub acknowledgement: u32,
332 pub data_offset: u8,
334 pub reserved: u8,
336 pub flags: Vec<TcpFlag>,
338 pub window: u16,
340 pub checksum: u16,
342 pub urgent_ptr: u16,
344 pub options: Vec<TcpOption>,
346 pub payload: Vec<u8>,
348}
349
350impl TcpPacket {
351 pub(crate) fn from_pnet_packet(packet: &pnet::packet::tcp::TcpPacket) -> TcpPacket {
352 let mut tcp_options: Vec<TcpOption> = vec![];
353 for opt in packet.get_options_iter() {
354 tcp_options.push(TcpOption::from_pnet_type(opt));
355 }
356 let mut tcp_flags: Vec<TcpFlag> = vec![];
357 if packet.get_flags() & TcpFlag::Syn.number() == TcpFlag::Syn.number() {
358 tcp_flags.push(TcpFlag::Syn);
359 }
360 if packet.get_flags() & TcpFlag::Fin.number() == TcpFlag::Fin.number() {
361 tcp_flags.push(TcpFlag::Fin);
362 }
363 if packet.get_flags() & TcpFlag::Rst.number() == TcpFlag::Rst.number() {
364 tcp_flags.push(TcpFlag::Rst);
365 }
366 if packet.get_flags() & TcpFlag::Psh.number() == TcpFlag::Psh.number() {
367 tcp_flags.push(TcpFlag::Psh);
368 }
369 if packet.get_flags() & TcpFlag::Ack.number() == TcpFlag::Ack.number() {
370 tcp_flags.push(TcpFlag::Ack);
371 }
372 if packet.get_flags() & TcpFlag::Urg.number() == TcpFlag::Urg.number() {
373 tcp_flags.push(TcpFlag::Urg);
374 }
375 if packet.get_flags() & TcpFlag::Ece.number() == TcpFlag::Ece.number() {
376 tcp_flags.push(TcpFlag::Ece);
377 }
378 if packet.get_flags() & TcpFlag::Cwr.number() == TcpFlag::Cwr.number() {
379 tcp_flags.push(TcpFlag::Cwr);
380 }
381 TcpPacket {
382 source: packet.get_source(),
383 destination: packet.get_destination(),
384 sequence: packet.get_sequence(),
385 acknowledgement: packet.get_acknowledgement(),
386 data_offset: packet.get_data_offset(),
387 reserved: packet.get_reserved(),
388 flags: tcp_flags,
389 window: packet.get_window(),
390 checksum: packet.get_checksum(),
391 urgent_ptr: packet.get_urgent_ptr(),
392 options: tcp_options,
393 payload: packet.payload().to_vec(),
394 }
395 }
396 pub fn from_bytes(packet: &[u8]) -> TcpPacket {
397 let tcp_packet = pnet::packet::tcp::TcpPacket::new(packet).unwrap();
398 TcpPacket::from_pnet_packet(&tcp_packet)
399 }
400}
401
402pub(crate) fn build_tcp_packet(
403 tcp_packet: &mut pnet::packet::tcp::MutableTcpPacket,
404 src_ip: IpAddr,
405 src_port: u16,
406 dst_ip: IpAddr,
407 dst_port: u16,
408) {
409 tcp_packet.set_source(src_port);
410 tcp_packet.set_destination(dst_port);
411 tcp_packet.set_window(64240);
412 tcp_packet.set_data_offset(8);
413 tcp_packet.set_urgent_ptr(0);
414 tcp_packet.set_sequence(0);
415 tcp_packet.set_options(&[
416 pnet::packet::tcp::TcpOption::mss(1460),
417 pnet::packet::tcp::TcpOption::sack_perm(),
418 pnet::packet::tcp::TcpOption::nop(),
419 pnet::packet::tcp::TcpOption::nop(),
420 pnet::packet::tcp::TcpOption::wscale(7),
421 ]);
422 tcp_packet.set_flags(pnet::packet::tcp::TcpFlags::SYN);
423 match src_ip {
424 IpAddr::V4(src_ip) => match dst_ip {
425 IpAddr::V4(dst_ip) => {
426 let checksum =
427 pnet::packet::tcp::ipv4_checksum(&tcp_packet.to_immutable(), &src_ip, &dst_ip);
428 tcp_packet.set_checksum(checksum);
429 }
430 IpAddr::V6(_) => {}
431 },
432 IpAddr::V6(src_ip) => match dst_ip {
433 IpAddr::V4(_) => {}
434 IpAddr::V6(dst_ip) => {
435 let checksum =
436 pnet::packet::tcp::ipv6_checksum(&tcp_packet.to_immutable(), &src_ip, &dst_ip);
437 tcp_packet.set_checksum(checksum);
438 }
439 },
440 }
441}
442
443#[derive(Clone, Debug)]
445pub struct TcpPacketBuilder {
446 pub src_ip: IpAddr,
448 pub src_port: u16,
450 pub dst_ip: IpAddr,
452 pub dst_port: u16,
454 pub window: u16,
456 pub flags: Vec<TcpFlag>,
458 pub options: Vec<TcpOption>,
460 pub payload: Vec<u8>,
462}
463
464impl TcpPacketBuilder {
465 pub fn new(src_addr: SocketAddr, dst_addr: SocketAddr) -> TcpPacketBuilder {
467 TcpPacketBuilder {
468 src_ip: src_addr.ip(),
469 src_port: src_addr.port(),
470 dst_ip: dst_addr.ip(),
471 dst_port: dst_addr.port(),
472 window: 64240,
473 flags: vec![TcpFlag::Syn],
474 options: vec![
475 TcpOption::mss(1460),
476 TcpOption::sack_perm(),
477 TcpOption::nop(),
478 TcpOption::nop(),
479 TcpOption::wscale(7),
480 ],
481 payload: vec![],
482 }
483 }
484 pub fn build(&self) -> Vec<u8> {
486 let data_offset = get_tcp_data_offset(self.options.clone());
487 let tcp_options_len = get_tcp_options_length(data_offset);
488 let mut buffer: Vec<u8> = vec![0; TCP_HEADER_LEN + tcp_options_len + self.payload.len()];
489 let mut tcp_packet = pnet::packet::tcp::MutableTcpPacket::new(&mut buffer).unwrap();
490 tcp_packet.set_source(self.src_port);
491 tcp_packet.set_destination(self.dst_port);
492 tcp_packet.set_window(self.window);
493 tcp_packet.set_data_offset(data_offset);
494 tcp_packet.set_urgent_ptr(0);
495 tcp_packet.set_sequence(0);
496 let mut tcp_flags: u8 = 0;
497 for flag in &self.flags {
498 if tcp_flags == 0 {
499 tcp_flags = flag.number();
500 } else {
501 tcp_flags |= flag.number();
502 }
503 }
504 tcp_packet.set_flags(tcp_flags);
505 let mut tcp_options: Vec<pnet::packet::tcp::TcpOption> = vec![];
506 for opt in &self.options {
507 tcp_options.push(opt.to_pnet_type());
508 }
509 tcp_packet.set_options(&tcp_options);
510 if self.payload.len() > 0 {
511 tcp_packet.set_payload(&self.payload);
512 }
513 match self.src_ip {
514 IpAddr::V4(src_ip) => match self.dst_ip {
515 IpAddr::V4(dst_ip) => {
516 let checksum = pnet::packet::tcp::ipv4_checksum(
517 &tcp_packet.to_immutable(),
518 &src_ip,
519 &dst_ip,
520 );
521 tcp_packet.set_checksum(checksum);
522 }
523 IpAddr::V6(_) => {}
524 },
525 IpAddr::V6(src_ip) => match self.dst_ip {
526 IpAddr::V4(_) => {}
527 IpAddr::V6(dst_ip) => {
528 let checksum = pnet::packet::tcp::ipv6_checksum(
529 &tcp_packet.to_immutable(),
530 &src_ip,
531 &dst_ip,
532 );
533 tcp_packet.set_checksum(checksum);
534 }
535 },
536 }
537 tcp_packet.packet().to_vec()
538 }
539}