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