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)] 11 pub 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 18 impl 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] to_bytes(&self) -> [u8; 4]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] from_bytes(bytes5to8: [u8; 4]) -> IcmpEchoHeader32 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)] 41 mod 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 } 97