etherparse/
payload_slice.rs

1use crate::*;
2
3/// Payload together with an identifier the type of content.
4#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
5pub enum PayloadSlice<'a> {
6    /// No specific payload (e.g. ARP packet).
7    Empty,
8
9    /// Payload with it's type identified by an ether type number
10    /// (e.g. after an ethernet II or vlan header).
11    Ether(EtherPayloadSlice<'a>),
12
13    /// MACsec encrypted or modified payload.
14    MacsecMod(&'a [u8]),
15
16    /// Payload with is's type identified by an ip number (e.g.
17    /// after an IP header or after an)
18    Ip(IpPayloadSlice<'a>),
19
20    /// UDP payload.
21    Udp(&'a [u8]),
22
23    /// TCP payload.
24    Tcp(&'a [u8]),
25
26    /// Payload part of an ICMP V4 message. Check [`crate::Icmpv4Type`]
27    /// for a description what will be part of the payload.
28    Icmpv4(&'a [u8]),
29
30    /// Payload part of an ICMP V4 message. Check [`crate::Icmpv6Type`]
31    /// for a description what will be part of the payload.
32    Icmpv6(&'a [u8]),
33}
34
35impl<'a> PayloadSlice<'a> {
36    pub fn slice(&self) -> &'a [u8] {
37        match self {
38            PayloadSlice::Empty => &[],
39            PayloadSlice::Ether(s) => s.payload,
40            PayloadSlice::MacsecMod(s) => s,
41            PayloadSlice::Ip(s) => s.payload,
42            PayloadSlice::Udp(s) => s,
43            PayloadSlice::Tcp(s) => s,
44            PayloadSlice::Icmpv4(s) => s,
45            PayloadSlice::Icmpv6(s) => s,
46        }
47    }
48}
49
50#[cfg(test)]
51mod test {
52    use super::*;
53    use alloc::format;
54
55    #[test]
56    fn debug() {
57        assert_eq!(
58            format!("Udp({:?})", &[0u8; 0]),
59            format!("{:?}", PayloadSlice::Udp(&[]))
60        );
61    }
62
63    #[test]
64    fn clone_eq_hash_ord() {
65        let s = PayloadSlice::Udp(&[]);
66        assert_eq!(s.clone(), s);
67
68        use std::collections::hash_map::DefaultHasher;
69        use std::hash::{Hash, Hasher};
70
71        let a_hash = {
72            let mut hasher = DefaultHasher::new();
73            s.hash(&mut hasher);
74            hasher.finish()
75        };
76        let b_hash = {
77            let mut hasher = DefaultHasher::new();
78            s.clone().hash(&mut hasher);
79            hasher.finish()
80        };
81        assert_eq!(a_hash, b_hash);
82
83        use std::cmp::Ordering;
84        assert_eq!(s.clone().cmp(&s), Ordering::Equal);
85        assert_eq!(s.clone().partial_cmp(&s), Some(Ordering::Equal));
86    }
87
88    #[test]
89    fn slice() {
90        let payload = [1, 2, 3, 4];
91
92        use PayloadSlice::*;
93        assert_eq!(
94            Ether(EtherPayloadSlice {
95                ether_type: EtherType::IPV4,
96                len_source: LenSource::Slice,
97                payload: &payload
98            })
99            .slice(),
100            &payload
101        );
102        assert_eq!(
103            Ip(IpPayloadSlice {
104                ip_number: IpNumber::IPV4,
105                fragmented: false,
106                len_source: LenSource::Slice,
107                payload: &payload
108            })
109            .slice(),
110            &payload
111        );
112        assert_eq!(Udp(&payload).slice(), &payload);
113        assert_eq!(Tcp(&payload).slice(), &payload);
114        assert_eq!(Icmpv4(&payload).slice(), &payload);
115        assert_eq!(Icmpv6(&payload).slice(), &payload);
116    }
117}