1extern crate byteorder;
2use std::io::{Cursor, Write};
3
4use crate::custom_module::manycastr::{Address, address};
5pub(crate) use crate::net::icmp::ICMPPacket;
6pub(crate) use crate::net::tcp::TCPPacket;
7pub(crate) use crate::net::udp::{DNSAnswer, DNSRecord, TXTRecord, UDPPacket};
8use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};
9
10mod icmp;
11pub(crate) mod packet;
12mod tcp;
13mod udp;
14
15#[derive(Debug)]
17pub struct IPv4Packet {
18 pub length: u16, pub ttl: u8, pub src: u32, pub dst: u32, pub payload: PacketPayload, pub identifier: u16, }
25
26impl From<&[u8]> for IPv4Packet {
28 fn from(data: &[u8]) -> Self {
29 let mut cursor = Cursor::new(data);
30 let ihl: usize = ((cursor.read_u8().unwrap() & 0xF) * 4).into(); let identifier = cursor.read_u16::<NetworkEndian>().unwrap(); cursor.set_position(8); let ttl = cursor.read_u8().unwrap();
36 let packet_type = cursor.read_u8().unwrap(); cursor.set_position(12); let src = cursor.read_u32::<NetworkEndian>().unwrap(); let dst = cursor.read_u32::<NetworkEndian>().unwrap(); if ihl > data.len() {
43 return IPv4Packet {
44 length: ihl as u16,
45 ttl,
46 src,
47 dst,
48 payload: PacketPayload::Unimplemented,
49 identifier,
50 };
51 }
52
53 let payload_bytes = &data[ihl..];
55
56 let payload = match packet_type {
57 1 => {
58 if payload_bytes.len() < 8 {
59 PacketPayload::Unimplemented
60 } else {
61 PacketPayload::Icmp {
62 value: ICMPPacket::from(payload_bytes),
63 }
64 }
65 }
66 17 => {
67 if payload_bytes.len() < 8 {
68 PacketPayload::Unimplemented
69 } else {
70 PacketPayload::Udp {
71 value: UDPPacket::from(payload_bytes),
72 }
73 }
74 }
75 6 => {
76 if payload_bytes.len() < 20 {
77 PacketPayload::Unimplemented
78 } else {
79 PacketPayload::Tcp {
80 value: TCPPacket::from(payload_bytes),
81 }
82 }
83 }
84 _ => PacketPayload::Unimplemented,
85 };
86
87 IPv4Packet {
88 length: ihl as u16,
89 ttl,
90 src,
91 dst,
92 payload,
93 identifier,
94 }
95 }
96}
97
98impl From<&IPv4Packet> for Vec<u8> {
100 fn from(packet: &IPv4Packet) -> Self {
101 let (payload_type, payload) = match &packet.payload {
102 PacketPayload::Icmp { value } => (1, value.into()),
103 PacketPayload::Udp { value } => (17, value.into()),
104 PacketPayload::Tcp { value } => (6, value.into()),
105 PacketPayload::Unimplemented => (0, vec![]),
106 };
107
108 const TOTAL_HEADER_LENGTH: usize = 20; let ihl = (TOTAL_HEADER_LENGTH / 4) as u8;
110
111 let mut wtr = Vec::with_capacity(TOTAL_HEADER_LENGTH);
112 wtr.write_u8((4 << 4) | ihl)
113 .expect("Unable to write to byte buffer for IPv4 packet"); wtr.write_u8(0x00)
115 .expect("Unable to write to byte buffer for IPv4 packet"); wtr.write_u16::<NetworkEndian>(packet.length)
117 .expect("Unable to write to byte buffer for IPv4 packet"); wtr.write_u16::<NetworkEndian>(packet.identifier)
119 .expect("Unable to write to byte buffer for IPv4 packet"); wtr.write_u16::<NetworkEndian>(0x0000)
121 .expect("Unable to write to byte buffer for IPv4 packet"); wtr.write_u8(packet.ttl)
123 .expect("Unable to write to byte buffer for IPv4 packet"); wtr.write_u8(payload_type)
125 .expect("Unable to write to byte buffer for IPv4 packet"); wtr.write_u16::<NetworkEndian>(0x0000)
127 .expect("Unable to write to byte buffer for IPv4 packet"); wtr.write_u32::<NetworkEndian>(packet.src)
129 .expect("Unable to write to byte buffer for IPv4 packet"); wtr.write_u32::<NetworkEndian>(packet.dst)
131 .expect("Unable to write to byte buffer for IPv4 packet"); let checksum = ICMPPacket::calc_checksum(&wtr);
135 let mut cursor = Cursor::new(wtr);
136 cursor.set_position(10); cursor.write_u16::<NetworkEndian>(checksum).unwrap();
138
139 cursor.set_position(TOTAL_HEADER_LENGTH as u64); cursor
143 .write_all(&payload)
144 .expect("Unable to write to byte buffer for IPv4 packet"); cursor.into_inner()
147 }
148}
149
150#[derive(Debug)]
152pub struct IPv6Packet {
153 pub flow_label: u32, pub payload_length: u16, pub next_header: u8, pub hop_limit: u8, pub src: u128, pub dst: u128, pub payload: PacketPayload, }
163
164impl From<&[u8]> for IPv6Packet {
166 fn from(data: &[u8]) -> Self {
167 let mut cursor = Cursor::new(data);
168 let _version_traffic_flow: u32 = cursor.read_u32::<NetworkEndian>().unwrap();
169 let flow_label = _version_traffic_flow & 0x000FFFFF; let payload_length = cursor.read_u16::<NetworkEndian>().unwrap();
171 let next_header = cursor.read_u8().unwrap();
172 let hop_limit = cursor.read_u8().unwrap();
173
174 let src = cursor.read_u128::<NetworkEndian>().unwrap(); let dst = cursor.read_u128::<NetworkEndian>().unwrap(); let payload = &cursor.into_inner()[40..]; let payload = match next_header {
180 58 => {
181 PacketPayload::Icmp {
183 value: ICMPPacket::from(payload),
184 }
185 }
186 17 => {
187 if payload.len() < 8 {
189 PacketPayload::Unimplemented
190 } else {
191 PacketPayload::Udp {
192 value: UDPPacket::from(payload),
193 }
194 }
195 }
196 6 => {
197 if payload.len() < 20 {
199 PacketPayload::Unimplemented
200 } else {
201 PacketPayload::Tcp {
202 value: TCPPacket::from(payload),
203 }
204 }
205 }
206 _ => PacketPayload::Unimplemented, };
208
209 IPv6Packet {
210 flow_label,
213 payload_length,
214 next_header,
215 hop_limit,
216 src,
217 dst,
218 payload,
219 }
220 }
221}
222
223impl From<&IPv6Packet> for Vec<u8> {
225 fn from(packet: &IPv6Packet) -> Self {
226 let mut wtr = vec![];
227 let vtf = 0x6000_0000u32 | (packet.flow_label & 0x000F_FFFF);
229 wtr.write_u32::<NetworkEndian>(vtf)
230 .expect("Unable to write to byte buffer for IPv6Packet");
231 wtr.write_u16::<NetworkEndian>(packet.payload_length)
232 .expect("Unable to write to byte buffer for IPv6Packet");
233 wtr.write_u8(packet.next_header)
234 .expect("Unable to write to byte buffer for IPv6Packet");
235 wtr.write_u8(packet.hop_limit)
236 .expect("Unable to write to byte buffer for IPv6Packet");
237 wtr.write_u128::<NetworkEndian>(packet.src)
238 .expect("Unable to write source address to byte buffer for IPv6Packet");
239 wtr.write_u128::<NetworkEndian>(packet.dst)
240 .expect("Unable to write destination address to byte buffer for IPv6Packet");
241
242 let payload = match &packet.payload {
243 PacketPayload::Icmp { value } => value.into(),
244 PacketPayload::Udp { value } => value.into(),
245 PacketPayload::Tcp { value } => value.into(),
246 PacketPayload::Unimplemented => vec![],
247 };
248
249 wtr.write_all(&payload)
250 .expect("Unable to write payload to byte buffer for IPv6Packet");
251
252 wtr
253 }
254}
255
256#[derive(Debug)]
258pub enum PacketPayload {
259 Icmp { value: ICMPPacket },
260 Udp { value: UDPPacket },
261 Tcp { value: TCPPacket },
262 Unimplemented,
263}
264
265impl From<PacketPayload> for Vec<u8> {
267 fn from(payload: PacketPayload) -> Self {
268 match payload {
269 PacketPayload::Icmp { value } => (&value).into(),
270 PacketPayload::Udp { value } => (&value).into(),
271 PacketPayload::Tcp { value } => (&value).into(),
272 PacketPayload::Unimplemented => vec![],
273 }
274 }
275}
276
277pub(crate) fn build_ip_packet(
288 src: &Address,
289 dst: &Address,
290 ttl: u8,
291 identifier: u16,
292 payload: PacketPayload,
293) -> Vec<u8> {
294 let (l4_len, next_header) = match &payload {
296 PacketPayload::Icmp { value } => (Vec::<u8>::from(value).len(), 58u8), PacketPayload::Udp { value } => (Vec::<u8>::from(value).len(), 17u8),
298 PacketPayload::Tcp { value } => (Vec::<u8>::from(value).len(), 6u8),
299 PacketPayload::Unimplemented => (0usize, 0u8),
300 };
301 let l4_len = l4_len as u16;
302
303 match (&src.value, &dst.value) {
304 (Some(address::Value::V6(_)), Some(address::Value::V6(_))) => (&IPv6Packet {
305 payload_length: l4_len,
306 flow_label: identifier as u32,
307 next_header,
308 hop_limit: ttl,
309 src: src.into(),
310 dst: dst.into(),
311 payload,
312 })
313 .into(),
314 (Some(address::Value::V4(_)), Some(address::Value::V4(_))) => (&IPv4Packet {
315 length: 20 + l4_len,
317 identifier,
318 ttl,
319 src: src.into(),
320 dst: dst.into(),
321 payload,
322 })
323 .into(),
324 (s, d) => panic!("IP version mismatch or unset address: src={s:?}, dst={d:?}"),
325 }
326}
327
328#[derive(Debug)]
330pub struct PseudoHeaderV4 {
331 pub src: u32,
332 pub dst: u32,
333 pub protocol: u8,
334 pub length: u16,
335}
336
337impl From<&PseudoHeaderV4> for Vec<u8> {
339 fn from(header: &PseudoHeaderV4) -> Self {
340 let mut wtr = vec![];
341 wtr.write_u32::<NetworkEndian>(header.src)
342 .expect("Unable to write to byte buffer for PseudoHeader");
343 wtr.write_u32::<NetworkEndian>(header.dst)
344 .expect("Unable to write to byte buffer for PseudoHeader");
345 wtr.write_u8(0) .expect("Unable to write to byte buffer for PseudoHeader");
347 wtr.write_u8(header.protocol)
348 .expect("Unable to write to byte buffer for PseudoHeader");
349 wtr.write_u16::<NetworkEndian>(header.length)
350 .expect("Unable to write to byte buffer for PseudoHeader");
351
352 wtr
353 }
354}
355
356#[derive(Debug)]
358pub struct PseudoHeaderV6 {
359 pub src: u128,
360 pub dst: u128,
361 pub upper_layer_packet_length: u32,
362 pub next_header: u8,
363}
364
365impl From<&PseudoHeaderV6> for Vec<u8> {
367 fn from(header: &PseudoHeaderV6) -> Self {
368 let mut wtr = vec![];
369 wtr.write_u128::<NetworkEndian>(header.src)
370 .expect("Unable to write to byte buffer for PseudoHeader");
371 wtr.write_u128::<NetworkEndian>(header.dst)
372 .expect("Unable to write to byte buffer for PseudoHeader");
373 wtr.write_u32::<NetworkEndian>(header.upper_layer_packet_length)
374 .expect("Unable to write to byte buffer for PseudoHeader");
375 wtr.write_u24::<NetworkEndian>(0) .expect("Unable to write to byte buffer for PseudoHeader");
377 wtr.write_u8(header.next_header)
378 .expect("Unable to write to byte buffer for PseudoHeader");
379
380 wtr
381 }
382}
383
384#[derive(Debug)]
386pub enum PseudoHeader {
387 V4(PseudoHeaderV4),
388 V6(PseudoHeaderV6),
389}
390
391impl PseudoHeader {
392 pub fn new(src_addr: &Address, dst_addr: &Address, protocol: u8, packet_length: u32) -> Self {
393 match (&src_addr.value, &dst_addr.value) {
394 (Some(address::Value::V6(_)), Some(address::Value::V6(_))) => {
395 Self::V6(PseudoHeaderV6 {
396 src: src_addr.into(),
397 dst: dst_addr.into(),
398 upper_layer_packet_length: packet_length,
399 next_header: protocol,
400 })
401 }
402 (Some(address::Value::V4(_)), Some(address::Value::V4(_))) => {
403 Self::V4(PseudoHeaderV4 {
404 src: src_addr.into(),
405 dst: dst_addr.into(),
406 protocol,
407 length: packet_length as u16,
408 })
409 }
410 (s, d) => panic!(
411 "IP version mismatch or invalid address type: src={:?}, dst={:?}",
412 s, d
413 ),
414 }
415 }
416}
417
418impl From<&PseudoHeader> for Vec<u8> {
420 fn from(header: &PseudoHeader) -> Self {
421 match header {
422 PseudoHeader::V4(header) => header.into(),
423 PseudoHeader::V6(header) => header.into(),
424 }
425 }
426}
427
428pub fn calculate_checksum(buffer: &[u8], pseudo_header: &PseudoHeader) -> u16 {
435 let mut sum = 0u32;
436 let mut packet: Vec<u8> = pseudo_header.into();
437 packet.extend_from_slice(buffer);
438
439 let packet_len = packet.len();
441 for chunk in packet.as_chunks::<2>().0 {
442 let word = u16::from_be_bytes(*chunk);
443 sum += u32::from(word);
444 }
445
446 if !packet_len.is_multiple_of(2) {
448 sum += u32::from(packet[packet_len - 1]) << 8;
449 }
450
451 while (sum >> 16) != 0 {
453 sum = (sum & 0xffff) + (sum >> 16);
454 }
455
456 !(sum as u16)
458}