etherparse/transport/
icmp_echo_header.rs

1/// Echo Request & Response common parts between ICMPv4 and ICMPv6.
2///
3/// # RFC 4443 Description (ICMPv6)
4///
5/// Every node MUST implement an ICMPv6 Echo responder function that
6/// receives Echo Requests and originates corresponding Echo Replies.  A
7/// node SHOULD also implement an application-layer interface for
8/// originating Echo Requests and receiving Echo Replies, for diagnostic
9/// purposes.
10#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11pub struct IcmpEchoHeader {
12    /// An identifier to aid in matching Echo Replies to Echo Requests. May be zero.
13    pub id: u16,
14    /// A sequence number to aid in matching Echo Replies to Echo Requests. May be zero.
15    pub seq: u16,
16}
17
18impl IcmpEchoHeader {
19    /// Serialized size of an IcmpEchoHeader header in bytes/octets.
20    pub const LEN: usize = 4;
21
22    /// Return the seq + id encoded to the on the wire format.
23    #[inline]
24    pub fn to_bytes(&self) -> [u8; 4] {
25        let id_be = self.id.to_be_bytes();
26        let seq_be = self.seq.to_be_bytes();
27        [id_be[0], id_be[1], seq_be[0], seq_be[1]]
28    }
29
30    /// Decodes the seq + id from the on the wire format.
31    #[inline]
32    pub fn from_bytes(bytes5to8: [u8; 4]) -> IcmpEchoHeader {
33        IcmpEchoHeader {
34            id: u16::from_be_bytes([bytes5to8[0], bytes5to8[1]]),
35            seq: u16::from_be_bytes([bytes5to8[2], bytes5to8[3]]),
36        }
37    }
38}
39
40#[cfg(test)]
41mod test {
42    use crate::*;
43    use alloc::format;
44    use proptest::prelude::*;
45
46    proptest! {
47        #[test]
48        fn to_bytes(
49            id in any::<u16>(),
50            seq in any::<u16>()
51        ) {
52            let id_bytes = id.to_be_bytes();
53            let seq_bytes = seq.to_be_bytes();
54            assert_eq!(
55                IcmpEchoHeader{ id, seq }.to_bytes(),
56                [
57                    id_bytes[0], id_bytes[1],
58                    seq_bytes[0], seq_bytes[1]
59                ]
60            );
61        }
62
63        #[test]
64        fn from_bytes(
65            bytes in any::<[u8;4]>()
66        ) {
67            assert_eq!(
68                IcmpEchoHeader::from_bytes(bytes),
69                IcmpEchoHeader {
70                    id: u16::from_be_bytes([bytes[0], bytes[1]]),
71                    seq: u16::from_be_bytes([bytes[2], bytes[3]])
72                }
73            );
74        }
75
76        #[test]
77        fn clone_eq(
78            id in any::<u16>(),
79            seq in any::<u16>()
80        ) {
81            let value = IcmpEchoHeader{ id, seq };
82            assert_eq!(value.clone(), value);
83        }
84
85        #[test]
86        fn debug(
87            id in any::<u16>(),
88            seq in any::<u16>()
89        ) {
90            assert_eq!(
91                format!("{:?}", IcmpEchoHeader{ id, seq }),
92                format!("IcmpEchoHeader {{ id: {:?}, seq: {:?} }}", id, seq)
93            );
94        }
95    }
96}