1use pnet::packet::tcp::TcpPacket as pnet_TcpPacket;
2use pnet::packet::Packet;
3use std::ops::{Deref, DerefMut};
4use std::sync::Arc;
5
6#[derive(Debug)]
8pub struct TcpSegment<'a>(pnet_TcpPacket<'a>);
9
10impl<'a> From<pnet_TcpPacket<'a>> for TcpSegment<'a> {
11 fn from(ipv4_packet: pnet_TcpPacket<'a>) -> Self {
12 TcpSegment(ipv4_packet)
13 }
14}
15
16impl<'a> Deref for TcpSegment<'a> {
17 type Target = pnet_TcpPacket<'a>;
18
19 fn deref(&self) -> &Self::Target {
20 &self.0
21 }
22}
23
24impl TcpSegment<'_> {
25 pub fn new<'a>(packet: &'a [u8]) -> Option<TcpSegment<'a>>{
26 pnet_TcpPacket::new(packet).map(TcpSegment::from)
27 }
28
29 pub fn has_payload(&self) -> bool {
31 !&self.payload().is_empty()
32 }
33
34 pub fn create_clone<'a>(&self) -> TcpSegment<'a> {
35 TcpSegment::from(pnet_TcpPacket::owned(self.packet().to_vec()).unwrap())
36 }
37
38 fn is_answered_by(&self, other: &TcpSegment<'_>) -> bool {
39 self.get_source() == other.get_destination()
40 && self.get_destination() == other.get_source()
41 && self.get_sequence() as usize + self.payload().len()
42 == other.get_acknowledgement() as usize
43 }
44}
45
46#[derive(Debug)]
48pub struct TcpSegmentCollection<'a>(Arc<[TcpSegment<'a>]>);
49
50impl<'a> FromIterator<TcpSegment<'a>> for TcpSegmentCollection<'a> {
51 fn from_iter<I: IntoIterator<Item = TcpSegment<'a>>>(iter: I) -> Self {
52 TcpSegmentCollection(iter.into_iter().collect())
53 }
54}
55
56impl<'a> Deref for TcpSegmentCollection<'a> {
57 type Target = Arc<[TcpSegment<'a>]>;
58
59 fn deref(&self) -> &Self::Target {
60 &self.0
61 }
62}
63
64impl<'a> From<crate::Ipv4PacketCollection<'a>> for TcpSegmentCollection<'a> {
65 fn from(ipv4_packet_collection: crate::Ipv4PacketCollection) -> Self {
66 ipv4_packet_collection
67 .iter()
68 .filter(|ipv4_packet| pnet_TcpPacket::new(ipv4_packet.payload()).is_some())
69 .map(|ipv4_packet| {
70 TcpSegment::from(pnet_TcpPacket::owned(ipv4_packet.payload().to_vec()).unwrap())
71 })
72 .collect::<TcpSegmentCollection>()
73 }
74}
75
76impl<'a> TcpSegmentCollection<'a> {
77 pub fn filter_no_payload(&'a self) -> TcpSegmentCollection<'a> {
81 TcpSegmentCollection(
82 self.iter()
83 .filter(|s| s.has_payload())
84 .map(|s| s.create_clone())
85 .collect::<Arc<[TcpSegment]>>(),
86 )
87 }
88
89 pub fn find_challenge_response_pairs(
93 &'a mut self,
94 ) -> (TcpChallengeResponseCollection<'a>, TcpSegmentCollection<'a>) {
95 let mut matched = Vec::new();
96 let mut unmatched = self
97 .iter()
98 .map(|s| s.create_clone())
99 .collect::<Vec<TcpSegment<'a>>>();
100 let mut i = 0;
101 while i < unmatched.len() {
102 let challenge = unmatched[i].create_clone();
103 let mut j = 0;
104 let mut found_match = false;
105 while j < unmatched.len() - 1 {
106 j += 1;
107 let candidate = unmatched[j].create_clone();
108 if challenge.is_answered_by(&candidate) {
109 matched.push(TcpChallengeResponse::new(
110 challenge.create_clone(),
111 candidate.create_clone(),
112 ));
113 if j > i {
114 unmatched.remove(j);
115 unmatched.remove(i);
116 } else {
117 unmatched.remove(i);
118 unmatched.remove(j);
119 }
120 found_match = true;
121 break;
122 }
123 }
124 if !found_match {
125 i += 1;
126 }
127 }
128 (
129 TcpChallengeResponseCollection(matched.into()),
130 TcpSegmentCollection(unmatched.into()),
131 )
132 }
133}
134
135#[derive(Debug)]
137pub struct TcpChallengeResponse<'a> {
138 pub challenge: TcpSegment<'a>,
139 pub response: TcpSegment<'a>,
140}
141
142impl<'a> TcpChallengeResponse<'a> {
143 fn new(challenge: TcpSegment<'a>, response: TcpSegment<'a>) -> TcpChallengeResponse<'a> {
144 TcpChallengeResponse {
145 challenge,
146 response,
147 }
148 }
149}
150
151#[derive(Debug)]
153pub struct TcpChallengeResponseCollection<'a>(Arc<[TcpChallengeResponse<'a>]>);
154
155impl<'a> FromIterator<TcpChallengeResponse<'a>> for TcpChallengeResponseCollection<'a> {
156 fn from_iter<I: IntoIterator<Item = TcpChallengeResponse<'a>>>(iter: I) -> Self {
157 TcpChallengeResponseCollection(iter.into_iter().collect())
158 }
159}
160
161impl<'a> Deref for TcpChallengeResponseCollection<'a> {
162 type Target = Arc<[TcpChallengeResponse<'a>]>;
163
164 fn deref(&self) -> &Self::Target {
165 &self.0
166 }
167}
168
169impl DerefMut for TcpChallengeResponseCollection<'_> {
170 fn deref_mut(&mut self) -> &mut Self::Target {
171 &mut self.0
172 }
173}