net_wire/ipv6/
dispatch.rs1use super::error::Ipv6DispatchError;
4use super::extensions;
5use super::next_header::Ipv6NextHeader;
6use super::packet::{Ipv6Packet, Ipv6PacketMut};
7#[cfg(feature = "icmpv6")]
8use crate::icmpv6::message::{Icmpv6Message, Icmpv6MessageMut};
9#[cfg(feature = "tcp")]
10use crate::tcp::segment::{TcpSegment, TcpSegmentMut};
11#[cfg(feature = "udp")]
12use crate::udp::datagram::{UdpDatagram, UdpDatagramMut};
13
14impl<'a> Ipv6Packet<'a> {
15 #[cfg(feature = "icmpv6")]
17 #[inline]
18 pub fn icmpv6(&self) -> Result<Option<Icmpv6Message<'a>>, Ipv6DispatchError> {
19 let traversal = extensions::traverse(
20 self.next_header(),
21 self.raw_payload_length(),
22 self.payload(),
23 )
24 .map_err(Ipv6DispatchError::Traversal)?;
25 if traversal.non_atomic_fragment || traversal.next_header != Ipv6NextHeader::ICMPV6.raw() {
26 return Ok(None);
27 }
28 Icmpv6Message::parse(&self.payload()[traversal.upper_offset..])
29 .map(Some)
30 .map_err(Ipv6DispatchError::UpperLayer)
31 }
32
33 #[cfg(feature = "udp")]
35 #[inline]
36 pub fn udp(&self) -> Result<Option<UdpDatagram<'a>>, Ipv6DispatchError> {
37 let traversal = extensions::traverse(
38 self.next_header(),
39 self.raw_payload_length(),
40 self.payload(),
41 )
42 .map_err(Ipv6DispatchError::Traversal)?;
43 if traversal.non_atomic_fragment || traversal.next_header != Ipv6NextHeader::UDP.raw() {
44 return Ok(None);
45 }
46 UdpDatagram::parse(&self.payload()[traversal.upper_offset..])
47 .map(Some)
48 .map_err(Ipv6DispatchError::UpperLayer)
49 }
50
51 #[cfg(feature = "tcp")]
53 #[inline]
54 pub fn tcp(&self) -> Result<Option<TcpSegment<'a>>, Ipv6DispatchError> {
55 let traversal = extensions::traverse(
56 self.next_header(),
57 self.raw_payload_length(),
58 self.payload(),
59 )
60 .map_err(Ipv6DispatchError::Traversal)?;
61 if traversal.non_atomic_fragment || traversal.next_header != Ipv6NextHeader::TCP.raw() {
62 return Ok(None);
63 }
64 TcpSegment::parse(&self.payload()[traversal.upper_offset..])
65 .map(Some)
66 .map_err(Ipv6DispatchError::UpperLayer)
67 }
68}
69
70impl<'a> Ipv6PacketMut<'a> {
71 #[cfg(feature = "icmpv6")]
73 #[inline]
74 pub fn icmpv6_mut(&mut self) -> Result<Option<Icmpv6MessageMut<'_>>, Ipv6DispatchError> {
75 let traversal = extensions::traverse(
76 self.next_header(),
77 self.raw_payload_length(),
78 self.payload(),
79 )
80 .map_err(Ipv6DispatchError::Traversal)?;
81 if traversal.non_atomic_fragment || traversal.next_header != Ipv6NextHeader::ICMPV6.raw() {
82 return Ok(None);
83 }
84 Icmpv6MessageMut::parse(&mut self.payload_mut()[traversal.upper_offset..])
85 .map(Some)
86 .map_err(Ipv6DispatchError::UpperLayer)
87 }
88
89 #[cfg(feature = "udp")]
91 #[inline]
92 pub fn udp_mut(&mut self) -> Result<Option<UdpDatagramMut<'_>>, Ipv6DispatchError> {
93 let traversal = extensions::traverse(
94 self.next_header(),
95 self.raw_payload_length(),
96 self.payload(),
97 )
98 .map_err(Ipv6DispatchError::Traversal)?;
99 if traversal.non_atomic_fragment || traversal.next_header != Ipv6NextHeader::UDP.raw() {
100 return Ok(None);
101 }
102 UdpDatagramMut::parse(&mut self.payload_mut()[traversal.upper_offset..])
103 .map(Some)
104 .map_err(Ipv6DispatchError::UpperLayer)
105 }
106
107 #[cfg(feature = "tcp")]
109 #[inline]
110 pub fn tcp_mut(&mut self) -> Result<Option<TcpSegmentMut<'_>>, Ipv6DispatchError> {
111 let traversal = extensions::traverse(
112 self.next_header(),
113 self.raw_payload_length(),
114 self.payload(),
115 )
116 .map_err(Ipv6DispatchError::Traversal)?;
117 if traversal.non_atomic_fragment || traversal.next_header != Ipv6NextHeader::TCP.raw() {
118 return Ok(None);
119 }
120 TcpSegmentMut::parse(&mut self.payload_mut()[traversal.upper_offset..])
121 .map(Some)
122 .map_err(Ipv6DispatchError::UpperLayer)
123 }
124}