1use bytes::{Bytes, BytesMut};
13use smallvec::SmallVec;
14
15use crate::error::{PacketError, Result};
16use crate::layer::{
17 DnsLayer, HttpLayer, IcmpLayer, Icmpv6Layer, Ipv6Layer, LayerEnum, LayerIndex, LayerKind,
18 RawLayer, SshLayer, TcpLayer, TlsLayer, UdpLayer,
19 arp::ArpLayer,
20 ethernet::{Dot3Layer, ETHERNET_HEADER_LEN, EthernetLayer},
21 ethertype,
22 ftp::{FTP_CONTROL_PORT, is_ftp_payload},
23 http,
24 http2::{Http2Layer, is_http2_payload},
25 icmp,
26 imap::{IMAP_PORT, is_imap_payload},
27 ip_protocol,
28 ipv4::Ipv4Layer,
29 pop3::{POP3_PORT, is_pop3_payload},
30 smtp::{SMTP_PORT, SMTP_SUBMISSION_PORT, SMTPS_PORT, is_smtp_payload},
31 ssh::{SSH_PORT, is_ssh_payload},
32 tftp::{TFTP_PORT, is_tftp_payload},
33 tls::is_tls_payload,
34};
35
36const INLINE_LAYER_CAPACITY: usize = 4;
38
39#[derive(Debug, Clone)]
49pub struct Packet {
50 data: Bytes,
51 layers: SmallVec<[LayerIndex; INLINE_LAYER_CAPACITY]>,
52 is_dirty: bool,
53}
54
55impl Packet {
56 #[inline]
62 #[must_use]
63 pub fn empty() -> Self {
64 Self {
65 data: Bytes::new(),
66 layers: SmallVec::new(),
67 is_dirty: false,
68 }
69 }
70
71 #[inline]
73 pub fn from_bytes(data: impl Into<Bytes>) -> Self {
74 Self {
75 data: data.into(),
76 layers: SmallVec::new(),
77 is_dirty: false,
78 }
79 }
80
81 #[inline]
83 #[must_use]
84 pub fn from_slice(data: &[u8]) -> Self {
85 Self {
86 data: Bytes::copy_from_slice(data),
87 layers: SmallVec::new(),
88 is_dirty: false,
89 }
90 }
91
92 #[inline]
94 #[must_use]
95 pub fn with_capacity(capacity: usize) -> Self {
96 Self {
97 data: Bytes::from(BytesMut::with_capacity(capacity)),
98 layers: SmallVec::new(),
99 is_dirty: false,
100 }
101 }
102
103 #[inline]
108 pub fn len(&self) -> usize {
109 self.data.len()
110 }
111 #[inline]
112 pub fn is_empty(&self) -> bool {
113 self.data.is_empty()
114 }
115 #[inline]
116 pub fn is_dirty(&self) -> bool {
117 self.is_dirty
118 }
119 #[inline]
120 pub fn layer_count(&self) -> usize {
121 self.layers.len()
122 }
123 #[inline]
124 pub fn is_parsed(&self) -> bool {
125 !self.layers.is_empty()
126 }
127
128 #[inline]
133 pub fn as_bytes(&self) -> &[u8] {
134 &self.data
135 }
136 #[inline]
137 pub fn bytes(&self) -> Bytes {
138 self.data.clone()
139 }
140 #[inline]
141 pub fn into_bytes(self) -> Bytes {
142 self.data
143 }
144
145 #[inline]
150 pub fn layers(&self) -> &[LayerIndex] {
151 &self.layers
152 }
153
154 #[inline]
155 pub fn get_layer(&self, kind: LayerKind) -> Option<&LayerIndex> {
156 self.layers.iter().find(|l| l.kind == kind)
157 }
158
159 pub fn layer_bytes(&self, kind: LayerKind) -> Result<&[u8]> {
161 self.get_layer(kind)
162 .map(|idx| &self.data[idx.range()])
163 .ok_or(PacketError::LayerNotFound(kind))
164 }
165
166 #[inline]
168 pub fn payload(&self) -> &[u8] {
169 self.layers
170 .last()
171 .map_or(&self.data, |l| &self.data[l.end..])
172 }
173
174 pub fn ethernet(&self) -> Option<EthernetLayer> {
180 self.get_layer(LayerKind::Ethernet)
181 .map(|idx| EthernetLayer::new(idx.start, idx.end))
182 }
183
184 pub fn ipv4(&self) -> Option<Ipv4Layer> {
186 self.get_layer(LayerKind::Ipv4)
187 .map(|idx| Ipv4Layer::new(idx.start, idx.end))
188 }
189
190 pub fn arp(&self) -> Option<ArpLayer> {
192 self.get_layer(LayerKind::Arp)
193 .map(|idx| ArpLayer::new(idx.start, idx.end))
194 }
195
196 pub fn icmp(&self) -> Option<IcmpLayer> {
198 self.get_layer(LayerKind::Icmp)
199 .map(|idx| IcmpLayer { index: *idx })
200 }
201
202 pub fn tcp(&self) -> Option<TcpLayer> {
204 self.get_layer(LayerKind::Tcp)
205 .map(|idx| TcpLayer::new(idx.start, idx.end))
206 }
207
208 pub fn udp(&self) -> Option<UdpLayer> {
210 self.get_layer(LayerKind::Udp)
211 .map(|idx| UdpLayer { index: *idx })
212 }
213
214 pub fn dns(&self) -> Option<DnsLayer> {
216 self.get_layer(LayerKind::Dns)
217 .map(|idx| DnsLayer { index: *idx })
218 }
219
220 pub fn tls(&self) -> Option<TlsLayer> {
222 self.get_layer(LayerKind::Tls)
223 .map(|idx| TlsLayer { index: *idx })
224 }
225
226 pub fn mqtt(&self) -> Option<crate::layer::mqtt::MqttLayer> {
228 self.get_layer(LayerKind::Mqtt)
229 .map(|idx| crate::layer::mqtt::MqttLayer::new(*idx))
230 }
231
232 pub fn mqttsn(&self) -> Option<crate::layer::mqttsn::MqttSnLayer> {
234 self.get_layer(LayerKind::MqttSn)
235 .map(|idx| crate::layer::mqttsn::MqttSnLayer::new(*idx))
236 }
237
238 pub fn modbus(&self) -> Option<crate::layer::modbus::ModbusLayer> {
240 self.get_layer(LayerKind::Modbus)
241 .map(|idx| crate::layer::modbus::ModbusLayer::new(*idx))
242 }
243
244 pub fn zwave(&self) -> Option<crate::layer::zwave::ZWaveLayer> {
246 self.get_layer(LayerKind::ZWave)
247 .map(|idx| crate::layer::zwave::ZWaveLayer::new(*idx))
248 }
249
250 pub fn ftp(&self) -> Option<crate::layer::ftp::FtpLayer> {
252 self.get_layer(LayerKind::Ftp)
253 .map(|idx| crate::layer::ftp::FtpLayer::new(*idx))
254 }
255
256 pub fn tftp(&self) -> Option<crate::layer::tftp::TftpLayer> {
258 self.get_layer(LayerKind::Tftp)
259 .map(|idx| crate::layer::tftp::TftpLayer::new(*idx))
260 }
261
262 pub fn smtp(&self) -> Option<crate::layer::smtp::SmtpLayer> {
264 self.get_layer(LayerKind::Smtp)
265 .map(|idx| crate::layer::smtp::SmtpLayer::new(*idx))
266 }
267
268 pub fn pop3(&self) -> Option<crate::layer::pop3::Pop3Layer> {
270 self.get_layer(LayerKind::Pop3)
271 .map(|idx| crate::layer::pop3::Pop3Layer::new(*idx))
272 }
273
274 pub fn imap(&self) -> Option<crate::layer::imap::ImapLayer> {
276 self.get_layer(LayerKind::Imap)
277 .map(|idx| crate::layer::imap::ImapLayer::new(*idx))
278 }
279
280 pub fn layer_enum(&self, idx: &LayerIndex) -> LayerEnum {
282 match idx.kind {
283 LayerKind::Ethernet => LayerEnum::Ethernet(EthernetLayer::new(idx.start, idx.end)),
284 LayerKind::Dot3 => LayerEnum::Dot3(Dot3Layer::new(idx.start, idx.end)),
285 LayerKind::Arp => LayerEnum::Arp(ArpLayer::new(idx.start, idx.end)),
286 LayerKind::Ipv4 => LayerEnum::Ipv4(Ipv4Layer::new(idx.start, idx.end)),
287 LayerKind::Ipv6 => LayerEnum::Ipv6(Ipv6Layer { index: *idx }),
288 LayerKind::Icmp => LayerEnum::Icmp(IcmpLayer { index: *idx }),
289 LayerKind::Icmpv6 => LayerEnum::Icmpv6(Icmpv6Layer { index: *idx }),
290 LayerKind::Tcp => LayerEnum::Tcp(TcpLayer::new(idx.start, idx.end)),
291 LayerKind::Udp => LayerEnum::Udp(UdpLayer { index: *idx }),
292 LayerKind::Dns => LayerEnum::Dns(DnsLayer { index: *idx }),
293 LayerKind::Ssh => LayerEnum::Ssh(SshLayer { index: *idx }),
294 LayerKind::Tls => LayerEnum::Tls(TlsLayer { index: *idx }),
295 LayerKind::Dot15d4 => {
296 LayerEnum::Dot15d4(crate::layer::dot15d4::Dot15d4Layer::new(idx.start, idx.end))
297 },
298 LayerKind::Dot15d4Fcs => LayerEnum::Dot15d4Fcs(
299 crate::layer::dot15d4::Dot15d4FcsLayer::new(idx.start, idx.end),
300 ),
301 LayerKind::Dot11 => {
302 LayerEnum::Dot11(crate::layer::dot11::Dot11Layer::new(idx.start, idx.end))
303 },
304 LayerKind::Http => LayerEnum::Http(HttpLayer { index: *idx }),
305 LayerKind::Http2 => LayerEnum::Http2(Http2Layer::new(idx.start, idx.end, false)),
306 LayerKind::Quic => LayerEnum::Quic(crate::layer::quic::QuicLayer::from_index(*idx)),
307 LayerKind::L2tp => LayerEnum::L2tp(crate::layer::l2tp::L2tpLayer::new(*idx)),
308 LayerKind::Mqtt => LayerEnum::Mqtt(crate::layer::mqtt::MqttLayer::new(*idx)),
309 LayerKind::MqttSn => LayerEnum::MqttSn(crate::layer::mqttsn::MqttSnLayer::new(*idx)),
310 LayerKind::Modbus => LayerEnum::Modbus(crate::layer::modbus::ModbusLayer::new(*idx)),
311 LayerKind::ZWave => LayerEnum::ZWave(crate::layer::zwave::ZWaveLayer::new(*idx)),
312 LayerKind::Ftp => LayerEnum::Ftp(crate::layer::ftp::FtpLayer::new(*idx)),
313 LayerKind::Tftp => LayerEnum::Tftp(crate::layer::tftp::TftpLayer::new(*idx)),
314 LayerKind::Smtp => LayerEnum::Smtp(crate::layer::smtp::SmtpLayer::new(*idx)),
315 LayerKind::Pop3 => LayerEnum::Pop3(crate::layer::pop3::Pop3Layer::new(*idx)),
316 LayerKind::Imap => LayerEnum::Imap(crate::layer::imap::ImapLayer::new(*idx)),
317 LayerKind::Raw
318 | LayerKind::Dot1Q
319 | LayerKind::Dot1AD
320 | LayerKind::Dot1AH
321 | LayerKind::LLC
322 | LayerKind::SNAP
323 | LayerKind::Generic => LayerEnum::Raw(RawLayer { index: *idx }),
324 }
325 }
326
327 pub fn layer_enums(&self) -> Vec<LayerEnum> {
329 self.layers.iter().map(|idx| self.layer_enum(idx)).collect()
330 }
331
332 pub fn parse(&mut self) -> Result<()> {
338 self.layers.clear();
339
340 if self.data.len() < ETHERNET_HEADER_LEN {
341 return Ok(());
342 }
343
344 let eth_end = ETHERNET_HEADER_LEN;
346 self.layers
347 .push(LayerIndex::new(LayerKind::Ethernet, 0, eth_end));
348
349 let etype = u16::from_be_bytes([self.data[12], self.data[13]]);
350
351 match etype {
352 ethertype::IPV4 => self.parse_ipv4(eth_end)?,
353 ethertype::IPV6 => self.parse_ipv6(eth_end)?,
354 ethertype::ARP => self.parse_arp(eth_end)?,
355 _ => {
356 if eth_end < self.data.len() {
357 self.layers
358 .push(LayerIndex::new(LayerKind::Raw, eth_end, self.data.len()));
359 }
360 },
361 }
362
363 Ok(())
364 }
365
366 fn parse_ipv4(&mut self, offset: usize) -> Result<()> {
367 let min_size = 20;
368 if offset + min_size > self.data.len() {
369 return Err(PacketError::BufferTooShort {
370 expected: offset + min_size,
371 actual: self.data.len(),
372 });
373 }
374
375 let ihl = (self.data[offset] & 0x0F) as usize;
376 let header_len = ihl * 4;
377
378 if header_len < min_size {
379 return Err(PacketError::ParseError {
380 offset,
381 message: format!("invalid IHL: {ihl}"),
382 });
383 }
384
385 let ip_end = offset + header_len;
386 if ip_end > self.data.len() {
387 return Err(PacketError::BufferTooShort {
388 expected: ip_end,
389 actual: self.data.len(),
390 });
391 }
392
393 self.layers
394 .push(LayerIndex::new(LayerKind::Ipv4, offset, ip_end));
395
396 let protocol = self.data[offset + 9];
397 match protocol {
398 ip_protocol::TCP => self.parse_tcp(ip_end)?,
399 ip_protocol::UDP => self.parse_udp(ip_end)?,
400 ip_protocol::ICMP => self.parse_icmp(ip_end)?,
401 _ => {
402 if ip_end < self.data.len() {
403 self.layers
404 .push(LayerIndex::new(LayerKind::Raw, ip_end, self.data.len()));
405 }
406 },
407 }
408
409 Ok(())
410 }
411
412 fn parse_ipv6(&mut self, offset: usize) -> Result<()> {
413 let min_size = 40;
414 if offset + min_size > self.data.len() {
415 return Err(PacketError::BufferTooShort {
416 expected: offset + min_size,
417 actual: self.data.len(),
418 });
419 }
420
421 let ip_end = offset + min_size;
422 self.layers
423 .push(LayerIndex::new(LayerKind::Ipv6, offset, ip_end));
424
425 let next_header = self.data[offset + 6];
426 match next_header {
427 ip_protocol::TCP => self.parse_tcp(ip_end)?,
428 ip_protocol::UDP => self.parse_udp(ip_end)?,
429 ip_protocol::ICMPV6 => self.parse_icmpv6(ip_end)?,
430 _ => {
431 if ip_end < self.data.len() {
432 self.layers
433 .push(LayerIndex::new(LayerKind::Raw, ip_end, self.data.len()));
434 }
435 },
436 }
437
438 Ok(())
439 }
440
441 fn parse_arp(&mut self, offset: usize) -> Result<()> {
442 if offset + 5 > self.data.len() {
444 return Err(PacketError::BufferTooShort {
445 expected: offset + 5,
446 actual: self.data.len(),
447 });
448 }
449
450 let hwlen = self.data[offset + 4] as usize;
451 let plen = self.data[offset + 5] as usize;
452 let total_len = 8 + 2 * hwlen + 2 * plen;
453
454 if offset + total_len > self.data.len() {
455 return Err(PacketError::BufferTooShort {
456 expected: offset + total_len,
457 actual: self.data.len(),
458 });
459 }
460
461 let arp_end = offset + total_len;
462 self.layers
463 .push(LayerIndex::new(LayerKind::Arp, offset, arp_end));
464
465 if arp_end < self.data.len() {
466 self.layers
467 .push(LayerIndex::new(LayerKind::Raw, arp_end, self.data.len()));
468 }
469
470 Ok(())
471 }
472
473 fn parse_tcp(&mut self, offset: usize) -> Result<()> {
474 let min_size = 20;
475 if offset + min_size > self.data.len() {
476 return Err(PacketError::BufferTooShort {
477 expected: offset + min_size,
478 actual: self.data.len(),
479 });
480 }
481
482 let data_offset = ((self.data[offset + 12] >> 4) & 0x0F) as usize;
483 let header_len = data_offset * 4;
484
485 let tcp_end = (offset + header_len).min(self.data.len());
486 self.layers
487 .push(LayerIndex::new(LayerKind::Tcp, offset, tcp_end));
488
489 if tcp_end < self.data.len() {
490 let src_port = u16::from_be_bytes([self.data[offset], self.data[offset + 1]]);
492 let dst_port = u16::from_be_bytes([self.data[offset + 2], self.data[offset + 3]]);
493
494 let payload = &self.data[tcp_end..];
495 if (src_port == SSH_PORT || dst_port == SSH_PORT) && is_ssh_payload(payload) {
496 self.parse_ssh(tcp_end)?;
497 } else if (src_port == 502 || dst_port == 502)
498 && crate::layer::modbus::is_modbus_tcp_payload(payload)
499 {
500 self.layers
501 .push(LayerIndex::new(LayerKind::Modbus, tcp_end, self.data.len()));
502 } else if (src_port == 1883 || dst_port == 1883)
503 && crate::layer::mqtt::is_mqtt_payload(payload)
504 {
505 self.layers
506 .push(LayerIndex::new(LayerKind::Mqtt, tcp_end, self.data.len()));
507 } else if (src_port == FTP_CONTROL_PORT || dst_port == FTP_CONTROL_PORT)
508 && is_ftp_payload(payload)
509 {
510 self.layers
511 .push(LayerIndex::new(LayerKind::Ftp, tcp_end, self.data.len()));
512 } else if (src_port == SMTP_PORT
513 || dst_port == SMTP_PORT
514 || src_port == SMTP_SUBMISSION_PORT
515 || dst_port == SMTP_SUBMISSION_PORT
516 || src_port == SMTPS_PORT
517 || dst_port == SMTPS_PORT)
518 && is_smtp_payload(payload)
519 {
520 self.layers
521 .push(LayerIndex::new(LayerKind::Smtp, tcp_end, self.data.len()));
522 } else if (src_port == POP3_PORT || dst_port == POP3_PORT) && is_pop3_payload(payload) {
523 self.layers
524 .push(LayerIndex::new(LayerKind::Pop3, tcp_end, self.data.len()));
525 } else if (src_port == IMAP_PORT || dst_port == IMAP_PORT) && is_imap_payload(payload) {
526 self.layers
527 .push(LayerIndex::new(LayerKind::Imap, tcp_end, self.data.len()));
528 } else if is_tls_payload(payload) {
529 self.parse_tls(tcp_end)?;
530 } else if is_http2_payload(payload) {
531 self.layers
532 .push(LayerIndex::new(LayerKind::Http2, tcp_end, self.data.len()));
533 } else if http::detection::is_http(payload) {
534 self.layers
535 .push(LayerIndex::new(LayerKind::Http, tcp_end, self.data.len()));
536 } else {
537 self.layers
538 .push(LayerIndex::new(LayerKind::Raw, tcp_end, self.data.len()));
539 }
540 }
541
542 Ok(())
543 }
544
545 fn parse_udp(&mut self, offset: usize) -> Result<()> {
546 let min_size = 8;
547 if offset + min_size > self.data.len() {
548 return Err(PacketError::BufferTooShort {
549 expected: offset + min_size,
550 actual: self.data.len(),
551 });
552 }
553
554 let udp_end = offset + min_size;
555 self.layers
556 .push(LayerIndex::new(LayerKind::Udp, offset, udp_end));
557
558 let dst_port = u16::from_be_bytes([self.data[offset + 2], self.data[offset + 3]]);
560 let src_port = u16::from_be_bytes([self.data[offset], self.data[offset + 1]]);
561
562 if (dst_port == 53 || src_port == 53 || dst_port == 5353 || src_port == 5353)
563 && udp_end + 12 <= self.data.len()
564 {
565 self.layers
566 .push(LayerIndex::new(LayerKind::Dns, udp_end, self.data.len()));
567 } else if (dst_port == 443 || src_port == 443 || dst_port == 4433 || src_port == 4433)
568 && udp_end < self.data.len()
569 && is_quic_payload(&self.data[udp_end..])
570 {
571 self.layers
572 .push(LayerIndex::new(LayerKind::Quic, udp_end, self.data.len()));
573 } else if (dst_port == 1701 || src_port == 1701)
574 && udp_end + 2 <= self.data.len()
575 && (self.data[udp_end + 1] & 0x0F) == 2
576 {
577 self.layers
579 .push(LayerIndex::new(LayerKind::L2tp, udp_end, self.data.len()));
580 } else if (dst_port == 1883 || src_port == 1883)
581 && udp_end < self.data.len()
582 && crate::layer::mqttsn::is_mqttsn_payload(&self.data[udp_end..])
583 {
584 self.layers
585 .push(LayerIndex::new(LayerKind::MqttSn, udp_end, self.data.len()));
586 } else if (dst_port == TFTP_PORT || src_port == TFTP_PORT)
587 && udp_end < self.data.len()
588 && is_tftp_payload(&self.data[udp_end..])
589 {
590 self.layers
591 .push(LayerIndex::new(LayerKind::Tftp, udp_end, self.data.len()));
592 } else if udp_end < self.data.len() {
593 self.layers
594 .push(LayerIndex::new(LayerKind::Raw, udp_end, self.data.len()));
595 }
596
597 Ok(())
598 }
599
600 fn parse_icmp(&mut self, offset: usize) -> Result<()> {
601 if offset + 8 > self.data.len() {
602 return Err(PacketError::BufferTooShort {
603 expected: offset + 8,
604 actual: self.data.len(),
605 });
606 }
607
608 self.layers
610 .push(LayerIndex::new(LayerKind::Icmp, offset, self.data.len()));
611
612 if offset < self.data.len() {
615 let icmp_type = self.data[offset];
616 if icmp::is_error_type(icmp_type) {
617 let embedded_offset = offset + 8;
619 if embedded_offset < self.data.len() {
620 let _ = self.parse_ipv4(embedded_offset);
623 }
624 }
625 }
626
627 Ok(())
628 }
629
630 fn parse_icmpv6(&mut self, offset: usize) -> Result<()> {
631 if offset + 8 > self.data.len() {
632 return Err(PacketError::BufferTooShort {
633 expected: offset + 8,
634 actual: self.data.len(),
635 });
636 }
637 self.layers
638 .push(LayerIndex::new(LayerKind::Icmpv6, offset, self.data.len()));
639 Ok(())
640 }
641
642 fn parse_ssh(&mut self, offset: usize) -> Result<()> {
643 let remaining = &self.data[offset..];
644
645 if remaining.len() >= 4 && &remaining[..4] == b"SSH-" {
646 let end = remaining
648 .windows(2)
649 .position(|w| w == b"\r\n")
650 .map_or(self.data.len(), |p| offset + p + 2);
651 self.layers
652 .push(LayerIndex::new(LayerKind::Ssh, offset, end));
653 if end < self.data.len() {
654 self.layers
655 .push(LayerIndex::new(LayerKind::Raw, end, self.data.len()));
656 }
657 } else if remaining.len() >= 5 {
658 let pkt_len =
660 u32::from_be_bytes([remaining[0], remaining[1], remaining[2], remaining[3]])
661 as usize;
662 let end = (offset + 4 + pkt_len).min(self.data.len());
663 self.layers
664 .push(LayerIndex::new(LayerKind::Ssh, offset, end));
665 if end < self.data.len() {
666 self.layers
667 .push(LayerIndex::new(LayerKind::Raw, end, self.data.len()));
668 }
669 } else {
670 self.layers
671 .push(LayerIndex::new(LayerKind::Raw, offset, self.data.len()));
672 }
673
674 Ok(())
675 }
676
677 fn parse_tls(&mut self, offset: usize) -> Result<()> {
678 use crate::layer::tls::TLS_RECORD_HEADER_LEN;
679
680 let remaining = self.data.len() - offset;
681 if remaining < TLS_RECORD_HEADER_LEN {
682 self.layers
683 .push(LayerIndex::new(LayerKind::Raw, offset, self.data.len()));
684 return Ok(());
685 }
686
687 let frag_len = u16::from_be_bytes([self.data[offset + 3], self.data[offset + 4]]) as usize;
689 let record_end = (offset + TLS_RECORD_HEADER_LEN + frag_len).min(self.data.len());
690
691 self.layers
692 .push(LayerIndex::new(LayerKind::Tls, offset, record_end));
693
694 if record_end < self.data.len() {
697 self.layers
698 .push(LayerIndex::new(LayerKind::Raw, record_end, self.data.len()));
699 }
700
701 Ok(())
702 }
703
704 pub fn with_data_mut<F, R>(&mut self, f: F) -> R
710 where
711 F: FnOnce(&mut [u8]) -> R,
712 {
713 let bytes = std::mem::take(&mut self.data);
714 let mut bytes_mut = bytes
715 .try_into_mut()
716 .unwrap_or_else(|b| BytesMut::from(b.as_ref()));
717 let result = f(&mut bytes_mut);
718 self.data = bytes_mut.freeze();
719 self.is_dirty = true;
720 result
721 }
722
723 pub fn set_byte(&mut self, offset: usize, value: u8) {
724 self.with_data_mut(|data| data[offset] = value);
725 }
726
727 pub fn set_bytes(&mut self, offset: usize, values: &[u8]) {
728 self.with_data_mut(|data| data[offset..offset + values.len()].copy_from_slice(values));
729 }
730
731 #[inline]
732 pub fn mark_dirty(&mut self) {
733 self.is_dirty = true;
734 }
735 #[inline]
736 pub fn mark_clean(&mut self) {
737 self.is_dirty = false;
738 }
739
740 pub fn add_layer(&mut self, index: LayerIndex) {
741 self.layers.push(index);
742 }
743
744 pub fn set_data(&mut self, data: BytesMut) {
745 self.data = data.freeze();
746 self.is_dirty = true;
747 }
748}
749
750impl Default for Packet {
751 fn default() -> Self {
752 Self::empty()
753 }
754}
755
756impl From<Vec<u8>> for Packet {
757 fn from(data: Vec<u8>) -> Self {
758 Self::from_bytes(data)
759 }
760}
761
762impl From<&[u8]> for Packet {
763 fn from(data: &[u8]) -> Self {
764 Self::from_slice(data)
765 }
766}
767
768impl AsRef<[u8]> for Packet {
769 fn as_ref(&self) -> &[u8] {
770 self.as_bytes()
771 }
772}
773
774fn is_quic_payload(buf: &[u8]) -> bool {
777 !buf.is_empty() && (buf[0] & 0x40) != 0
778}
779
780#[cfg(test)]
781mod tests {
782 use super::*;
783 use crate::ARP_HEADER_LEN;
784 use crate::layer::field::MacAddress;
785
786 fn sample_arp_packet() -> Vec<u8> {
787 vec![
788 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xc0, 0xa8, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x01, 0x02, ]
802 }
803
804 #[test]
805 fn test_packet_parse_arp() {
806 let data = sample_arp_packet();
807 let mut packet = Packet::from_bytes(data);
808 packet.parse().unwrap();
809
810 assert_eq!(packet.layer_count(), 2); let eth = packet.ethernet().unwrap();
813 assert!(eth.is_broadcast(packet.as_bytes()));
814 assert_eq!(eth.ethertype(packet.as_bytes()).unwrap(), ethertype::ARP);
815
816 let arp = packet.arp().unwrap();
817 assert!(arp.is_request(packet.as_bytes()));
818 }
819
820 #[test]
821 fn test_packet_layer_access() {
822 let data = sample_arp_packet();
823 let mut packet = Packet::from_bytes(data);
824 packet.parse().unwrap();
825
826 let eth_bytes = packet.layer_bytes(LayerKind::Ethernet).unwrap();
827 assert_eq!(eth_bytes.len(), ETHERNET_HEADER_LEN);
828
829 let arp_bytes = packet.layer_bytes(LayerKind::Arp).unwrap();
830 assert_eq!(arp_bytes.len(), ARP_HEADER_LEN);
831 }
832
833 #[test]
834 fn test_packet_modify_through_layer() {
835 let data = sample_arp_packet();
836 let mut packet = Packet::from_bytes(data);
837 packet.parse().unwrap();
838
839 let eth = packet.ethernet().unwrap();
841 packet.with_data_mut(|buf| {
842 eth.set_src(buf, MacAddress::new([0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]))
843 .unwrap();
844 });
845
846 assert!(packet.is_dirty());
847 let eth = packet.ethernet().unwrap();
848 assert_eq!(
849 eth.src(packet.as_bytes()).unwrap(),
850 MacAddress::new([0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff])
851 );
852 }
853
854 #[test]
855 fn test_icmp_error_packet_parsing() {
856 let data = vec![
858 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x08, 0x00, 0x45, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 192, 168, 1, 1, 192, 168, 1, 100, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x1c, 0xab, 0xcd, 0x00, 0x00, 0x40, 0x11, 0x00, 0x00, 192, 168, 1, 100, 8, 8, 8, 8, 0x04, 0xd2, 0x00, 0x35, 0x00, 0x14, 0x00, 0x00, ];
885
886 let mut packet = Packet::from_bytes(data);
887 packet.parse().unwrap();
888
889 assert_eq!(packet.layer_count(), 5);
891
892 assert!(packet.ethernet().is_some());
894 assert!(packet.ipv4().is_some());
895 assert!(packet.icmp().is_some());
896
897 let icmp = packet.icmp().unwrap();
899 let icmp_type = icmp.icmp_type(packet.as_bytes()).unwrap();
900 assert_eq!(icmp_type, 3); let layers = packet.layers();
905 let _embedded_ip_idx = layers
906 .iter()
907 .rposition(|idx| idx.kind == LayerKind::Ipv4)
908 .unwrap();
909
910 assert!(packet.udp().is_some());
912 }
913
914 #[test]
915 fn test_icmp_time_exceeded_with_tcp() {
916 let data = vec![
919 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
921 0x45, 0x00, 0x00, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 10, 0, 0, 1, 192, 168, 1, 100, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x28, 0x12, 0x34, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 192, 168, 1, 100, 93, 184, 216, 34, 0x04, 0xd2, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, ];
944
945 let mut packet = Packet::from_bytes(data);
946 packet.parse().unwrap();
947
948 assert_eq!(packet.layer_count(), 5);
950
951 assert!(packet.icmp().is_some());
953 assert!(packet.tcp().is_some());
954
955 let icmp = packet.icmp().unwrap();
957 assert_eq!(icmp.icmp_type(packet.as_bytes()).unwrap(), 11);
958 }
959
960 #[test]
961 fn test_icmp_with_extensions() {
962 let data = vec![
964 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x08, 0x00, 0x45, 0x00, 0x00, 0xa0, 0x00, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, 0x01, 0x64, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x3c, 0x12, 0x34, 0x40, 0x00, 0x01, 0x11, 0x00, 0x00, 0xc0, 0xa8, 0x01, 0x64, 0x08, 0x08, 0x08, 0x08, 0x04, 0xd2, 0x00, 0x35, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
990 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
991 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
992 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
993 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
994 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
995 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
996 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0xc0, 0xa8, 0x01, 0x01, ];
1007
1008 let mut packet = Packet::from_bytes(data.clone());
1009 packet.parse().unwrap();
1010
1011 assert!(packet.icmp().is_some());
1013 let icmp = packet.icmp().unwrap();
1014
1015 assert_eq!(
1017 icmp.icmp_type(packet.as_bytes()).unwrap(),
1018 crate::layer::icmp::types::types::TIME_EXCEEDED
1019 );
1020
1021 use crate::layer::icmp;
1023 let icmp_offset = packet.layers()[1].end; let icmp_payload = &data[icmp_offset + 8..]; assert!(icmp::has_extensions(
1027 crate::layer::icmp::types::types::TIME_EXCEEDED,
1028 icmp_payload.len()
1029 ));
1030
1031 let ext_offset = icmp_offset + 8 + 128; if let Some((version, _checksum)) = icmp::parse_extension_header(&data, ext_offset) {
1034 assert_eq!(version, 2);
1035
1036 let obj_offset = ext_offset + 4;
1038 if let Some((len, classnum, _classtype, data_offset)) =
1039 icmp::parse_extension_object(&data, obj_offset)
1040 {
1041 assert_eq!(len, 16);
1042 assert_eq!(
1043 classnum,
1044 icmp::extensions::class_nums::INTERFACE_INFORMATION
1045 );
1046
1047 let data_len = (len as usize) - 4; if let Some(info) = icmp::parse_interface_information(&data, data_offset, data_len)
1050 {
1051 assert!(info.flags.has_ifindex);
1052 assert!(info.flags.has_ipaddr);
1053 assert_eq!(info.ifindex, Some(2));
1054 if let Some(icmp::IpAddr::V4(ip)) = info.ip_addr {
1055 assert_eq!(ip.to_string(), "192.168.1.1");
1056 } else {
1057 panic!("Expected IPv4 address");
1058 }
1059 }
1060 }
1061 }
1062 }
1063}