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, http,
22 http2::{Http2Layer, is_http2_payload},
23 icmp, ip_protocol,
24 ipv4::Ipv4Layer,
25 ssh::{SSH_PORT, is_ssh_payload},
26 tls::is_tls_payload,
27};
28
29const INLINE_LAYER_CAPACITY: usize = 4;
31
32#[derive(Debug, Clone)]
42pub struct Packet {
43 data: Bytes,
44 layers: SmallVec<[LayerIndex; INLINE_LAYER_CAPACITY]>,
45 is_dirty: bool,
46}
47
48impl Packet {
49 #[inline]
55 pub fn empty() -> Self {
56 Self {
57 data: Bytes::new(),
58 layers: SmallVec::new(),
59 is_dirty: false,
60 }
61 }
62
63 #[inline]
65 pub fn from_bytes(data: impl Into<Bytes>) -> Self {
66 Self {
67 data: data.into(),
68 layers: SmallVec::new(),
69 is_dirty: false,
70 }
71 }
72
73 #[inline]
75 pub fn from_slice(data: &[u8]) -> Self {
76 Self {
77 data: Bytes::copy_from_slice(data),
78 layers: SmallVec::new(),
79 is_dirty: false,
80 }
81 }
82
83 #[inline]
85 pub fn with_capacity(capacity: usize) -> Self {
86 Self {
87 data: Bytes::from(BytesMut::with_capacity(capacity)),
88 layers: SmallVec::new(),
89 is_dirty: false,
90 }
91 }
92
93 #[inline]
98 pub fn len(&self) -> usize {
99 self.data.len()
100 }
101 #[inline]
102 pub fn is_empty(&self) -> bool {
103 self.data.is_empty()
104 }
105 #[inline]
106 pub fn is_dirty(&self) -> bool {
107 self.is_dirty
108 }
109 #[inline]
110 pub fn layer_count(&self) -> usize {
111 self.layers.len()
112 }
113 #[inline]
114 pub fn is_parsed(&self) -> bool {
115 !self.layers.is_empty()
116 }
117
118 #[inline]
123 pub fn as_bytes(&self) -> &[u8] {
124 &self.data
125 }
126 #[inline]
127 pub fn bytes(&self) -> Bytes {
128 self.data.clone()
129 }
130 #[inline]
131 pub fn into_bytes(self) -> Bytes {
132 self.data
133 }
134
135 #[inline]
140 pub fn layers(&self) -> &[LayerIndex] {
141 &self.layers
142 }
143
144 #[inline]
145 pub fn get_layer(&self, kind: LayerKind) -> Option<&LayerIndex> {
146 self.layers.iter().find(|l| l.kind == kind)
147 }
148
149 pub fn layer_bytes(&self, kind: LayerKind) -> Result<&[u8]> {
151 self.get_layer(kind)
152 .map(|idx| &self.data[idx.range()])
153 .ok_or(PacketError::LayerNotFound(kind))
154 }
155
156 #[inline]
158 pub fn payload(&self) -> &[u8] {
159 self.layers
160 .last()
161 .map(|l| &self.data[l.end..])
162 .unwrap_or(&self.data)
163 }
164
165 pub fn ethernet(&self) -> Option<EthernetLayer> {
171 self.get_layer(LayerKind::Ethernet)
172 .map(|idx| EthernetLayer::new(idx.start, idx.end))
173 }
174
175 pub fn ipv4(&self) -> Option<Ipv4Layer> {
177 self.get_layer(LayerKind::Ipv4)
178 .map(|idx| Ipv4Layer::new(idx.start, idx.end))
179 }
180
181 pub fn arp(&self) -> Option<ArpLayer> {
183 self.get_layer(LayerKind::Arp)
184 .map(|idx| ArpLayer::new(idx.start, idx.end))
185 }
186
187 pub fn icmp(&self) -> Option<IcmpLayer> {
189 self.get_layer(LayerKind::Icmp)
190 .map(|idx| IcmpLayer { index: *idx })
191 }
192
193 pub fn tcp(&self) -> Option<TcpLayer> {
195 self.get_layer(LayerKind::Tcp)
196 .map(|idx| TcpLayer::new(idx.start, idx.end))
197 }
198
199 pub fn udp(&self) -> Option<UdpLayer> {
201 self.get_layer(LayerKind::Udp)
202 .map(|idx| UdpLayer { index: *idx })
203 }
204
205 pub fn dns(&self) -> Option<DnsLayer> {
207 self.get_layer(LayerKind::Dns)
208 .map(|idx| DnsLayer { index: *idx })
209 }
210
211 pub fn tls(&self) -> Option<TlsLayer> {
213 self.get_layer(LayerKind::Tls)
214 .map(|idx| TlsLayer { index: *idx })
215 }
216
217 pub fn layer_enum(&self, idx: &LayerIndex) -> LayerEnum {
219 match idx.kind {
220 LayerKind::Ethernet => LayerEnum::Ethernet(EthernetLayer::new(idx.start, idx.end)),
221 LayerKind::Dot3 => LayerEnum::Dot3(Dot3Layer::new(idx.start, idx.end)),
222 LayerKind::Arp => LayerEnum::Arp(ArpLayer::new(idx.start, idx.end)),
223 LayerKind::Ipv4 => LayerEnum::Ipv4(Ipv4Layer::new(idx.start, idx.end)),
224 LayerKind::Ipv6 => LayerEnum::Ipv6(Ipv6Layer { index: *idx }),
225 LayerKind::Icmp => LayerEnum::Icmp(IcmpLayer { index: *idx }),
226 LayerKind::Icmpv6 => LayerEnum::Icmpv6(Icmpv6Layer { index: *idx }),
227 LayerKind::Tcp => LayerEnum::Tcp(TcpLayer::new(idx.start, idx.end)),
228 LayerKind::Udp => LayerEnum::Udp(UdpLayer { index: *idx }),
229 LayerKind::Dns => LayerEnum::Dns(DnsLayer { index: *idx }),
230 LayerKind::Ssh => LayerEnum::Ssh(SshLayer { index: *idx }),
231 LayerKind::Tls => LayerEnum::Tls(TlsLayer { index: *idx }),
232 LayerKind::Dot15d4 => {
233 LayerEnum::Dot15d4(crate::layer::dot15d4::Dot15d4Layer::new(idx.start, idx.end))
234 }
235 LayerKind::Dot15d4Fcs => LayerEnum::Dot15d4Fcs(
236 crate::layer::dot15d4::Dot15d4FcsLayer::new(idx.start, idx.end),
237 ),
238 LayerKind::Dot11 => {
239 LayerEnum::Dot11(crate::layer::dot11::Dot11Layer::new(idx.start, idx.end))
240 }
241 LayerKind::Http => LayerEnum::Http(HttpLayer { index: *idx }),
242 LayerKind::Http2 => LayerEnum::Http2(Http2Layer::new(idx.start, idx.end, false)),
243 LayerKind::Quic => LayerEnum::Quic(crate::layer::quic::QuicLayer::from_index(*idx)),
244 LayerKind::L2tp => LayerEnum::L2tp(crate::layer::l2tp::L2tpLayer::new(*idx)),
245 LayerKind::Raw
246 | LayerKind::Dot1Q
247 | LayerKind::Dot1AD
248 | LayerKind::Dot1AH
249 | LayerKind::LLC
250 | LayerKind::SNAP
251 | LayerKind::Generic => LayerEnum::Raw(RawLayer { index: *idx }),
252 }
253 }
254
255 pub fn layer_enums(&self) -> Vec<LayerEnum> {
257 self.layers.iter().map(|idx| self.layer_enum(idx)).collect()
258 }
259
260 pub fn parse(&mut self) -> Result<()> {
266 self.layers.clear();
267
268 if self.data.len() < ETHERNET_HEADER_LEN {
269 return Ok(());
270 }
271
272 let eth_end = ETHERNET_HEADER_LEN;
274 self.layers
275 .push(LayerIndex::new(LayerKind::Ethernet, 0, eth_end));
276
277 let etype = u16::from_be_bytes([self.data[12], self.data[13]]);
278
279 match etype {
280 ethertype::IPV4 => self.parse_ipv4(eth_end)?,
281 ethertype::IPV6 => self.parse_ipv6(eth_end)?,
282 ethertype::ARP => self.parse_arp(eth_end)?,
283 _ => {
284 if eth_end < self.data.len() {
285 self.layers
286 .push(LayerIndex::new(LayerKind::Raw, eth_end, self.data.len()));
287 }
288 }
289 }
290
291 Ok(())
292 }
293
294 fn parse_ipv4(&mut self, offset: usize) -> Result<()> {
295 let min_size = 20;
296 if offset + min_size > self.data.len() {
297 return Err(PacketError::BufferTooShort {
298 expected: offset + min_size,
299 actual: self.data.len(),
300 });
301 }
302
303 let ihl = (self.data[offset] & 0x0F) as usize;
304 let header_len = ihl * 4;
305
306 if header_len < min_size {
307 return Err(PacketError::ParseError {
308 offset,
309 message: format!("invalid IHL: {}", ihl),
310 });
311 }
312
313 let ip_end = offset + header_len;
314 if ip_end > self.data.len() {
315 return Err(PacketError::BufferTooShort {
316 expected: ip_end,
317 actual: self.data.len(),
318 });
319 }
320
321 self.layers
322 .push(LayerIndex::new(LayerKind::Ipv4, offset, ip_end));
323
324 let protocol = self.data[offset + 9];
325 match protocol {
326 ip_protocol::TCP => self.parse_tcp(ip_end)?,
327 ip_protocol::UDP => self.parse_udp(ip_end)?,
328 ip_protocol::ICMP => self.parse_icmp(ip_end)?,
329 _ => {
330 if ip_end < self.data.len() {
331 self.layers
332 .push(LayerIndex::new(LayerKind::Raw, ip_end, self.data.len()));
333 }
334 }
335 }
336
337 Ok(())
338 }
339
340 fn parse_ipv6(&mut self, offset: usize) -> Result<()> {
341 let min_size = 40;
342 if offset + min_size > self.data.len() {
343 return Err(PacketError::BufferTooShort {
344 expected: offset + min_size,
345 actual: self.data.len(),
346 });
347 }
348
349 let ip_end = offset + min_size;
350 self.layers
351 .push(LayerIndex::new(LayerKind::Ipv6, offset, ip_end));
352
353 let next_header = self.data[offset + 6];
354 match next_header {
355 ip_protocol::TCP => self.parse_tcp(ip_end)?,
356 ip_protocol::UDP => self.parse_udp(ip_end)?,
357 ip_protocol::ICMPV6 => self.parse_icmpv6(ip_end)?,
358 _ => {
359 if ip_end < self.data.len() {
360 self.layers
361 .push(LayerIndex::new(LayerKind::Raw, ip_end, self.data.len()));
362 }
363 }
364 }
365
366 Ok(())
367 }
368
369 fn parse_arp(&mut self, offset: usize) -> Result<()> {
370 if offset + 5 > self.data.len() {
372 return Err(PacketError::BufferTooShort {
373 expected: offset + 5,
374 actual: self.data.len(),
375 });
376 }
377
378 let hwlen = self.data[offset + 4] as usize;
379 let plen = self.data[offset + 5] as usize;
380 let total_len = 8 + 2 * hwlen + 2 * plen;
381
382 if offset + total_len > self.data.len() {
383 return Err(PacketError::BufferTooShort {
384 expected: offset + total_len,
385 actual: self.data.len(),
386 });
387 }
388
389 let arp_end = offset + total_len;
390 self.layers
391 .push(LayerIndex::new(LayerKind::Arp, offset, arp_end));
392
393 if arp_end < self.data.len() {
394 self.layers
395 .push(LayerIndex::new(LayerKind::Raw, arp_end, self.data.len()));
396 }
397
398 Ok(())
399 }
400
401 fn parse_tcp(&mut self, offset: usize) -> Result<()> {
402 let min_size = 20;
403 if offset + min_size > self.data.len() {
404 return Err(PacketError::BufferTooShort {
405 expected: offset + min_size,
406 actual: self.data.len(),
407 });
408 }
409
410 let data_offset = ((self.data[offset + 12] >> 4) & 0x0F) as usize;
411 let header_len = data_offset * 4;
412
413 let tcp_end = (offset + header_len).min(self.data.len());
414 self.layers
415 .push(LayerIndex::new(LayerKind::Tcp, offset, tcp_end));
416
417 if tcp_end < self.data.len() {
418 let src_port = u16::from_be_bytes([self.data[offset], self.data[offset + 1]]);
420 let dst_port = u16::from_be_bytes([self.data[offset + 2], self.data[offset + 3]]);
421
422 let payload = &self.data[tcp_end..];
423 if (src_port == SSH_PORT || dst_port == SSH_PORT) && is_ssh_payload(payload) {
424 self.parse_ssh(tcp_end)?;
425 } else if is_tls_payload(payload) {
426 self.parse_tls(tcp_end)?;
427 } else if is_http2_payload(payload) {
428 self.layers
429 .push(LayerIndex::new(LayerKind::Http2, tcp_end, self.data.len()));
430 } else if http::detection::is_http(payload) {
431 self.layers
432 .push(LayerIndex::new(LayerKind::Http, tcp_end, self.data.len()));
433 } else {
434 self.layers
435 .push(LayerIndex::new(LayerKind::Raw, tcp_end, self.data.len()));
436 }
437 }
438
439 Ok(())
440 }
441
442 fn parse_udp(&mut self, offset: usize) -> Result<()> {
443 let min_size = 8;
444 if offset + min_size > self.data.len() {
445 return Err(PacketError::BufferTooShort {
446 expected: offset + min_size,
447 actual: self.data.len(),
448 });
449 }
450
451 let udp_end = offset + min_size;
452 self.layers
453 .push(LayerIndex::new(LayerKind::Udp, offset, udp_end));
454
455 let dst_port = u16::from_be_bytes([self.data[offset + 2], self.data[offset + 3]]);
457 let src_port = u16::from_be_bytes([self.data[offset], self.data[offset + 1]]);
458
459 if (dst_port == 53 || src_port == 53 || dst_port == 5353 || src_port == 5353)
460 && udp_end + 12 <= self.data.len()
461 {
462 self.layers
463 .push(LayerIndex::new(LayerKind::Dns, udp_end, self.data.len()));
464 } else if (dst_port == 443 || src_port == 443 || dst_port == 4433 || src_port == 4433)
465 && udp_end < self.data.len()
466 && is_quic_payload(&self.data[udp_end..])
467 {
468 self.layers
469 .push(LayerIndex::new(LayerKind::Quic, udp_end, self.data.len()));
470 } else if (dst_port == 1701 || src_port == 1701)
471 && udp_end + 2 <= self.data.len()
472 && (self.data[udp_end + 1] & 0x0F) == 2
473 {
474 self.layers
476 .push(LayerIndex::new(LayerKind::L2tp, udp_end, self.data.len()));
477 } else if udp_end < self.data.len() {
478 self.layers
479 .push(LayerIndex::new(LayerKind::Raw, udp_end, self.data.len()));
480 }
481
482 Ok(())
483 }
484
485 fn parse_icmp(&mut self, offset: usize) -> Result<()> {
486 if offset + 8 > self.data.len() {
487 return Err(PacketError::BufferTooShort {
488 expected: offset + 8,
489 actual: self.data.len(),
490 });
491 }
492
493 self.layers
495 .push(LayerIndex::new(LayerKind::Icmp, offset, self.data.len()));
496
497 if offset < self.data.len() {
500 let icmp_type = self.data[offset];
501 if icmp::is_error_type(icmp_type) {
502 let embedded_offset = offset + 8;
504 if embedded_offset < self.data.len() {
505 let _ = self.parse_ipv4(embedded_offset);
508 }
509 }
510 }
511
512 Ok(())
513 }
514
515 fn parse_icmpv6(&mut self, offset: usize) -> Result<()> {
516 if offset + 8 > self.data.len() {
517 return Err(PacketError::BufferTooShort {
518 expected: offset + 8,
519 actual: self.data.len(),
520 });
521 }
522 self.layers
523 .push(LayerIndex::new(LayerKind::Icmpv6, offset, self.data.len()));
524 Ok(())
525 }
526
527 fn parse_ssh(&mut self, offset: usize) -> Result<()> {
528 let remaining = &self.data[offset..];
529
530 if remaining.len() >= 4 && &remaining[..4] == b"SSH-" {
531 let end = remaining
533 .windows(2)
534 .position(|w| w == b"\r\n")
535 .map(|p| offset + p + 2)
536 .unwrap_or(self.data.len());
537 self.layers
538 .push(LayerIndex::new(LayerKind::Ssh, offset, end));
539 if end < self.data.len() {
540 self.layers
541 .push(LayerIndex::new(LayerKind::Raw, end, self.data.len()));
542 }
543 } else if remaining.len() >= 5 {
544 let pkt_len =
546 u32::from_be_bytes([remaining[0], remaining[1], remaining[2], remaining[3]])
547 as usize;
548 let end = (offset + 4 + pkt_len).min(self.data.len());
549 self.layers
550 .push(LayerIndex::new(LayerKind::Ssh, offset, end));
551 if end < self.data.len() {
552 self.layers
553 .push(LayerIndex::new(LayerKind::Raw, end, self.data.len()));
554 }
555 } else {
556 self.layers
557 .push(LayerIndex::new(LayerKind::Raw, offset, self.data.len()));
558 }
559
560 Ok(())
561 }
562
563 fn parse_tls(&mut self, offset: usize) -> Result<()> {
564 use crate::layer::tls::TLS_RECORD_HEADER_LEN;
565
566 let remaining = self.data.len() - offset;
567 if remaining < TLS_RECORD_HEADER_LEN {
568 self.layers
569 .push(LayerIndex::new(LayerKind::Raw, offset, self.data.len()));
570 return Ok(());
571 }
572
573 let frag_len = u16::from_be_bytes([self.data[offset + 3], self.data[offset + 4]]) as usize;
575 let record_end = (offset + TLS_RECORD_HEADER_LEN + frag_len).min(self.data.len());
576
577 self.layers
578 .push(LayerIndex::new(LayerKind::Tls, offset, record_end));
579
580 if record_end < self.data.len() {
583 self.layers
584 .push(LayerIndex::new(LayerKind::Raw, record_end, self.data.len()));
585 }
586
587 Ok(())
588 }
589
590 pub fn with_data_mut<F, R>(&mut self, f: F) -> R
596 where
597 F: FnOnce(&mut [u8]) -> R,
598 {
599 let bytes = std::mem::take(&mut self.data);
600 let mut bytes_mut = bytes
601 .try_into_mut()
602 .unwrap_or_else(|b| BytesMut::from(b.as_ref()));
603 let result = f(&mut bytes_mut);
604 self.data = bytes_mut.freeze();
605 self.is_dirty = true;
606 result
607 }
608
609 pub fn set_byte(&mut self, offset: usize, value: u8) {
610 self.with_data_mut(|data| data[offset] = value);
611 }
612
613 pub fn set_bytes(&mut self, offset: usize, values: &[u8]) {
614 self.with_data_mut(|data| data[offset..offset + values.len()].copy_from_slice(values));
615 }
616
617 #[inline]
618 pub fn mark_dirty(&mut self) {
619 self.is_dirty = true;
620 }
621 #[inline]
622 pub fn mark_clean(&mut self) {
623 self.is_dirty = false;
624 }
625
626 pub fn add_layer(&mut self, index: LayerIndex) {
627 self.layers.push(index);
628 }
629
630 pub fn set_data(&mut self, data: BytesMut) {
631 self.data = data.freeze();
632 self.is_dirty = true;
633 }
634}
635
636impl Default for Packet {
637 fn default() -> Self {
638 Self::empty()
639 }
640}
641
642impl From<Vec<u8>> for Packet {
643 fn from(data: Vec<u8>) -> Self {
644 Self::from_bytes(data)
645 }
646}
647
648impl From<&[u8]> for Packet {
649 fn from(data: &[u8]) -> Self {
650 Self::from_slice(data)
651 }
652}
653
654impl AsRef<[u8]> for Packet {
655 fn as_ref(&self) -> &[u8] {
656 self.as_bytes()
657 }
658}
659
660fn is_quic_payload(buf: &[u8]) -> bool {
663 !buf.is_empty() && (buf[0] & 0x40) != 0
664}
665
666#[cfg(test)]
667mod tests {
668 use super::*;
669 use crate::ARP_HEADER_LEN;
670 use crate::layer::field::MacAddress;
671
672 fn sample_arp_packet() -> Vec<u8> {
673 vec![
674 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, ]
688 }
689
690 #[test]
691 fn test_packet_parse_arp() {
692 let data = sample_arp_packet();
693 let mut packet = Packet::from_bytes(data);
694 packet.parse().unwrap();
695
696 assert_eq!(packet.layer_count(), 2); let eth = packet.ethernet().unwrap();
699 assert!(eth.is_broadcast(packet.as_bytes()));
700 assert_eq!(eth.ethertype(packet.as_bytes()).unwrap(), ethertype::ARP);
701
702 let arp = packet.arp().unwrap();
703 assert!(arp.is_request(packet.as_bytes()));
704 }
705
706 #[test]
707 fn test_packet_layer_access() {
708 let data = sample_arp_packet();
709 let mut packet = Packet::from_bytes(data);
710 packet.parse().unwrap();
711
712 let eth_bytes = packet.layer_bytes(LayerKind::Ethernet).unwrap();
713 assert_eq!(eth_bytes.len(), ETHERNET_HEADER_LEN);
714
715 let arp_bytes = packet.layer_bytes(LayerKind::Arp).unwrap();
716 assert_eq!(arp_bytes.len(), ARP_HEADER_LEN);
717 }
718
719 #[test]
720 fn test_packet_modify_through_layer() {
721 let data = sample_arp_packet();
722 let mut packet = Packet::from_bytes(data);
723 packet.parse().unwrap();
724
725 let eth = packet.ethernet().unwrap();
727 packet.with_data_mut(|buf| {
728 eth.set_src(buf, MacAddress::new([0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]))
729 .unwrap();
730 });
731
732 assert!(packet.is_dirty());
733 let eth = packet.ethernet().unwrap();
734 assert_eq!(
735 eth.src(packet.as_bytes()).unwrap(),
736 MacAddress::new([0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff])
737 );
738 }
739
740 #[test]
741 fn test_icmp_error_packet_parsing() {
742 let data = vec![
744 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, ];
771
772 let mut packet = Packet::from_bytes(data);
773 packet.parse().unwrap();
774
775 assert_eq!(packet.layer_count(), 5);
777
778 assert!(packet.ethernet().is_some());
780 assert!(packet.ipv4().is_some());
781 assert!(packet.icmp().is_some());
782
783 let icmp = packet.icmp().unwrap();
785 let icmp_type = icmp.icmp_type(packet.as_bytes()).unwrap();
786 assert_eq!(icmp_type, 3); let layers = packet.layers();
791 let _embedded_ip_idx = layers
792 .iter()
793 .rposition(|idx| idx.kind == LayerKind::Ipv4)
794 .unwrap();
795
796 assert!(packet.udp().is_some());
798 }
799
800 #[test]
801 fn test_icmp_time_exceeded_with_tcp() {
802 let data = vec![
805 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
807 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, ];
830
831 let mut packet = Packet::from_bytes(data);
832 packet.parse().unwrap();
833
834 assert_eq!(packet.layer_count(), 5);
836
837 assert!(packet.icmp().is_some());
839 assert!(packet.tcp().is_some());
840
841 let icmp = packet.icmp().unwrap();
843 assert_eq!(icmp.icmp_type(packet.as_bytes()).unwrap(), 11);
844 }
845
846 #[test]
847 fn test_icmp_with_extensions() {
848 let data = vec![
850 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,
876 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
877 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
878 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
879 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
880 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
881 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
882 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0xc0, 0xa8, 0x01, 0x01, ];
893
894 let mut packet = Packet::from_bytes(data.clone());
895 packet.parse().unwrap();
896
897 assert!(packet.icmp().is_some());
899 let icmp = packet.icmp().unwrap();
900
901 assert_eq!(
903 icmp.icmp_type(packet.as_bytes()).unwrap(),
904 crate::layer::icmp::types::types::TIME_EXCEEDED
905 );
906
907 use crate::layer::icmp;
909 let icmp_offset = packet.layers()[1].end; let icmp_payload = &data[icmp_offset + 8..]; assert!(icmp::has_extensions(
913 crate::layer::icmp::types::types::TIME_EXCEEDED,
914 icmp_payload.len()
915 ));
916
917 let ext_offset = icmp_offset + 8 + 128; if let Some((version, _checksum)) = icmp::parse_extension_header(&data, ext_offset) {
920 assert_eq!(version, 2);
921
922 let obj_offset = ext_offset + 4;
924 if let Some((len, classnum, _classtype, data_offset)) =
925 icmp::parse_extension_object(&data, obj_offset)
926 {
927 assert_eq!(len, 16);
928 assert_eq!(
929 classnum,
930 icmp::extensions::class_nums::INTERFACE_INFORMATION
931 );
932
933 let data_len = (len as usize) - 4; if let Some(info) = icmp::parse_interface_information(&data, data_offset, data_len)
936 {
937 assert!(info.flags.has_ifindex);
938 assert!(info.flags.has_ipaddr);
939 assert_eq!(info.ifindex, Some(2));
940 if let Some(icmp::IpAddr::V4(ip)) = info.ip_addr {
941 assert_eq!(ip.to_string(), "192.168.1.1");
942 } else {
943 panic!("Expected IPv4 address");
944 }
945 }
946 }
947 }
948 }
949}