use crate::{
Buf, BufError, BufMut, BufResult, Codec, Cursor,
ipv4::{Address, Header},
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Message<'a> {
EchoReply(EchoReply<'a>),
DestinationUnreachable(DestinationUnreachable),
SourceQuench(SourceQuench),
Redirect(Redirect),
Echo(Echo<'a>),
TimeExceeded(TimeExceeded),
ParameterProblem(ParameterProblem),
Timestamp(Timestamp),
TimestampReply(TimestampReply),
InformationRequest(InformationRequest),
InformationReply(InformationReply),
}
impl<'a> Codec for Message<'a> {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
match self {
Message::EchoReply(message) => message.encode(writer, ()),
Message::DestinationUnreachable(message) => message.encode(writer, ()),
Message::SourceQuench(message) => message.encode(writer, ()),
Message::Redirect(message) => message.encode(writer, ()),
Message::Echo(message) => message.encode(writer, ()),
Message::TimeExceeded(message) => message.encode(writer, ()),
Message::ParameterProblem(message) => message.encode(writer, ()),
Message::Timestamp(message) => message.encode(writer, ()),
Message::TimestampReply(message) => message.encode(writer, ()),
Message::InformationRequest(message) => message.encode(writer, ()),
Message::InformationReply(message) => message.encode(writer, ()),
}
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
let typ = Type::decode(&mut Cursor::new(&[(reader.peek_u8()?)]), ())?;
Ok(match typ {
Type::EchoReply => Self::EchoReply(EchoReply::decode(reader, ())?),
Type::DestinationUnreachable => {
Self::DestinationUnreachable(DestinationUnreachable::decode(reader, ())?)
}
Type::SourceQuench => Self::SourceQuench(SourceQuench::decode(reader, ())?),
Type::Redirect => Self::Redirect(Redirect::decode(reader, ())?),
Type::Echo => Self::Echo(Echo::decode(reader, ())?),
Type::TimeExceeded => Self::TimeExceeded(TimeExceeded::decode(reader, ())?),
Type::ParameterProblem => Self::ParameterProblem(ParameterProblem::decode(reader, ())?),
Type::Timestamp => Self::Timestamp(Timestamp::decode(reader, ())?),
Type::TimestampReply => Self::TimestampReply(TimestampReply::decode(reader, ())?),
Type::InformationRequest => {
Self::InformationRequest(InformationRequest::decode(reader, ())?)
}
Type::InformationReply => Self::InformationReply(InformationReply::decode(reader, ())?),
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(u8)]
pub enum Type {
EchoReply = 0,
DestinationUnreachable = 3,
SourceQuench = 4,
Redirect = 5,
Echo = 8,
TimeExceeded = 11,
ParameterProblem = 12,
Timestamp = 13,
TimestampReply = 14,
InformationRequest = 15,
InformationReply = 16,
}
impl Codec for Type {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
(*self as u8).encode(writer, ())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match u8::decode(reader, ())? {
x if x == (Self::EchoReply as u8) => Ok(Self::EchoReply),
x if x == (Self::DestinationUnreachable as u8) => Ok(Self::DestinationUnreachable),
x if x == (Self::SourceQuench as u8) => Ok(Self::SourceQuench),
x if x == (Self::Redirect as u8) => Ok(Self::Redirect),
x if x == (Self::Echo as u8) => Ok(Self::Echo),
x if x == (Self::TimeExceeded as u8) => Ok(Self::TimeExceeded),
x if x == (Self::ParameterProblem as u8) => Ok(Self::ParameterProblem),
x if x == (Self::Timestamp as u8) => Ok(Self::Timestamp),
x if x == (Self::TimestampReply as u8) => Ok(Self::TimestampReply),
x if x == (Self::InformationRequest as u8) => Ok(Self::InformationRequest),
x if x == (Self::InformationReply as u8) => Ok(Self::InformationReply),
_ => Err(BufError::UnexpectedValue),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Code {
EchoReply(EchoReplyCode),
DestinationUnreachable(DestinationUnreachableCode),
SourceQuench(SourceQuenchCode),
Redirect(RedirectCode),
Echo(EchoCode),
TimeExceeded(TimeExceededCode),
ParameterProblem(ParameterProblemCode),
Timestamp(TimestampCode),
TimestampReply(TimestampReplyCode),
InformationRequest(InformationRequestCode),
InformationReply(InformationReplyCode),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(u8)]
pub enum ZeroCode {
Zero = 0,
}
impl Codec for ZeroCode {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
(*self as u8).encode(writer, ())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match u8::decode(reader, ())? {
x if x == Self::Zero as u8 => Ok(Self::Zero),
_ => Err(BufError::UnexpectedValue),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Checksum(pub u16);
impl Checksum {
pub fn calculate() -> Self {
todo!()
}
}
impl Codec for Checksum {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
self.0.encode(writer, ())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
Ok(Self(u16::decode(reader, ())?))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DestinationUnreachable {
pub code: DestinationUnreachableCode,
pub checksum: Checksum,
pub header: Header,
pub bytes: [u8; 8],
}
impl DestinationUnreachable {
pub const TYPE: Type = Type::DestinationUnreachable;
pub const UNUSED: [u8; 4] = [0u8; 4];
}
impl Codec for DestinationUnreachable {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
self.code.encode(writer, ())?;
self.checksum.encode(writer, ())?;
Self::UNUSED.encode(writer, ())?;
self.header.encode(writer, ())?;
self.bytes.encode(writer, ())?;
Ok(())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match Type::decode(reader, ())? {
Type::DestinationUnreachable => (),
_ => return Err(BufError::UnexpectedValue),
}
let code = DestinationUnreachableCode::decode(reader, ())?;
let checksum = Checksum::decode(reader, ())?;
match reader.read_array::<4>()? {
Self::UNUSED => (),
_ => return Err(BufError::UnexpectedValue),
}
let header = Header::decode(reader, ())?;
let bytes = reader.read_array::<8>()?;
Ok(Self {
code,
checksum,
header,
bytes,
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(u8)]
pub enum DestinationUnreachableCode {
NetUreachable = 0,
HostUnreachable = 1,
ProtocolUnreachable = 2,
PortUnreachable = 3,
FragmentationNeededAndDfSet = 4,
SourceRouteFailed = 5,
}
impl Codec for DestinationUnreachableCode {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
(*self as u8).encode(writer, ())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match u8::decode(reader, ())? {
x if x == (Self::NetUreachable as u8) => Ok(Self::NetUreachable),
x if x == (Self::HostUnreachable as u8) => Ok(Self::HostUnreachable),
x if x == (Self::ProtocolUnreachable as u8) => Ok(Self::ProtocolUnreachable),
x if x == (Self::PortUnreachable as u8) => Ok(Self::PortUnreachable),
x if x == (Self::FragmentationNeededAndDfSet as u8) => {
Ok(Self::FragmentationNeededAndDfSet)
}
x if x == (Self::SourceRouteFailed as u8) => Ok(Self::SourceRouteFailed),
_ => Err(BufError::UnexpectedValue),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TimeExceeded {
pub code: TimeExceededCode,
pub checksum: Checksum,
pub header: Header,
pub bytes: [u8; 8],
}
impl TimeExceeded {
pub const TYPE: Type = Type::TimeExceeded;
pub const UNUSED: [u8; 4] = [0u8; 4];
}
impl Codec for TimeExceeded {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
self.code.encode(writer, ())?;
self.checksum.encode(writer, ())?;
Self::UNUSED.encode(writer, ())?;
self.header.encode(writer, ())?;
self.bytes.encode(writer, ())?;
Ok(())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match Type::decode(reader, ())? {
Type::TimeExceeded => (),
_ => return Err(BufError::UnexpectedValue),
}
let code = TimeExceededCode::decode(reader, ())?;
let checksum = Checksum::decode(reader, ())?;
match reader.read_array::<4>()? {
Self::UNUSED => (),
_ => return Err(BufError::UnexpectedValue),
}
let header = Header::decode(reader, ())?;
let bytes = reader.read_array::<8>()?;
Ok(Self {
code,
checksum,
header,
bytes,
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(u8)]
pub enum TimeExceededCode {
TimeToLiveExceedInTransit = 0,
FragmentReassemblyTimeExceeded = 1,
}
impl Codec for TimeExceededCode {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
(*self as u8).encode(writer, ())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match u8::decode(reader, ())? {
x if x == (Self::TimeToLiveExceedInTransit as u8) => {
Ok(Self::TimeToLiveExceedInTransit)
}
x if x == (Self::FragmentReassemblyTimeExceeded as u8) => {
Ok(Self::FragmentReassemblyTimeExceeded)
}
_ => Err(BufError::UnexpectedValue),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ParameterProblem {
pub code: ParameterProblemCode,
pub checksum: Checksum,
pub header: Header,
pub bytes: [u8; 8],
}
impl ParameterProblem {
pub const TYPE: Type = Type::ParameterProblem;
pub const UNUSED: [u8; 3] = [0u8; 3];
}
impl Codec for ParameterProblem {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
self.code.encode(writer, ())?;
self.checksum.encode(writer, ())?;
Self::UNUSED.encode(writer, ())?;
self.header.encode(writer, ())?;
self.bytes.encode(writer, ())?;
Ok(())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match Type::decode(reader, ())? {
Type::ParameterProblem => (),
_ => return Err(BufError::UnexpectedValue),
}
let code = ParameterProblemCode::decode(reader, ())?;
let checksum = Checksum::decode(reader, ())?;
match reader.read_array::<3>()? {
Self::UNUSED => (),
_ => return Err(BufError::UnexpectedValue),
}
let header = Header::decode(reader, ())?;
let bytes = reader.read_array::<8>()?;
Ok(Self {
code,
checksum,
header,
bytes,
})
}
}
pub type ParameterProblemCode = ZeroCode;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SourceQuench {
pub code: SourceQuenchCode,
pub checksum: Checksum,
pub header: Header,
pub bytes: [u8; 8],
}
impl SourceQuench {
pub const TYPE: Type = Type::SourceQuench;
pub const UNUSED: [u8; 4] = [0u8; 4];
}
impl Codec for SourceQuench {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
self.code.encode(writer, ())?;
self.checksum.encode(writer, ())?;
Self::UNUSED.encode(writer, ())?;
self.header.encode(writer, ())?;
self.bytes.encode(writer, ())?;
Ok(())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match Type::decode(reader, ())? {
Type::SourceQuench => (),
_ => return Err(BufError::UnexpectedValue),
}
let code = SourceQuenchCode::decode(reader, ())?;
let checksum = Checksum::decode(reader, ())?;
match reader.read_array::<4>()? {
Self::UNUSED => (),
_ => return Err(BufError::UnexpectedValue),
}
let header = Header::decode(reader, ())?;
let bytes = reader.read_array::<8>()?;
Ok(Self {
code,
checksum,
header,
bytes,
})
}
}
pub type SourceQuenchCode = ZeroCode;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Redirect {
pub code: RedirectCode,
pub checksum: Checksum,
pub gateway_internet_address: Address,
pub header: Header,
pub bytes: [u8; 8],
}
impl Redirect {
pub const TYPE: Type = Type::Redirect;
}
impl Codec for Redirect {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
self.code.encode(writer, ())?;
self.checksum.encode(writer, ())?;
self.gateway_internet_address.encode(writer, ())?;
self.header.encode(writer, ())?;
self.bytes.encode(writer, ())?;
Ok(())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match Type::decode(reader, ())? {
Type::Redirect => (),
_ => return Err(BufError::UnexpectedValue),
}
let code = RedirectCode::decode(reader, ())?;
let checksum = Checksum::decode(reader, ())?;
let gateway_internet_address = Address::decode(reader, ())?;
let header = Header::decode(reader, ())?;
let bytes = reader.read_array::<8>()?;
Ok(Self {
code,
checksum,
gateway_internet_address,
header,
bytes,
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(u8)]
pub enum RedirectCode {
Network = 0,
Host = 1,
TypeOfServiceAndNetwork = 2,
TypeOfServiceAndHost = 3,
}
impl Codec for RedirectCode {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
(*self as u8).encode(writer, ())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match u8::decode(reader, ())? {
x if x == (Self::Network as u8) => Ok(Self::Network),
x if x == (Self::Host as u8) => Ok(Self::Host),
x if x == (Self::TypeOfServiceAndNetwork as u8) => Ok(Self::TypeOfServiceAndNetwork),
x if x == (Self::TypeOfServiceAndHost as u8) => Ok(Self::TypeOfServiceAndHost),
_ => Err(BufError::UnexpectedValue),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Echo<'a> {
pub code: EchoCode,
pub checksum: Checksum,
pub identifier: u16,
pub sequence_number: u16,
pub data: &'a [u8],
}
impl<'a> Echo<'a> {
pub const TYPE: Type = Type::Echo;
}
impl<'a> Codec for Echo<'a> {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
self.code.encode(writer, ())?;
self.checksum.encode(writer, ())?;
self.identifier.encode(writer, ())?;
self.sequence_number.encode(writer, ())?;
Ok(())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match Type::decode(reader, ())? {
Type::Redirect => (),
_ => return Err(BufError::UnexpectedValue),
}
let code = EchoReplyCode::decode(reader, ())?;
let checksum = Checksum::decode(reader, ())?;
let identifier = u16::decode(reader, ())?;
let sequence_number = u16::decode(reader, ())?;
let data = &[0u8];
Ok(Self {
code,
checksum,
identifier,
sequence_number,
data,
})
}
}
pub type EchoCode = ZeroCode;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct EchoReply<'a> {
pub code: EchoCode,
pub checksum: Checksum,
pub identifier: u16,
pub sequence_number: u16,
pub data: &'a [u8],
}
impl<'a> EchoReply<'a> {
pub const TYPE: Type = Type::EchoReply;
}
impl<'a> Codec for EchoReply<'a> {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
self.code.encode(writer, ())?;
self.checksum.encode(writer, ())?;
self.identifier.encode(writer, ())?;
self.sequence_number.encode(writer, ())?;
Ok(())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match Type::decode(reader, ())? {
Type::Redirect => (),
_ => return Err(BufError::UnexpectedValue),
}
let code = EchoReplyCode::decode(reader, ())?;
let checksum = Checksum::decode(reader, ())?;
let identifier = u16::decode(reader, ())?;
let sequence_number = u16::decode(reader, ())?;
let data = &[0u8];
Ok(Self {
code,
checksum,
identifier,
sequence_number,
data,
})
}
}
pub type EchoReplyCode = ZeroCode;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Timestamp {
pub code: TimestampCode,
pub checksum: Checksum,
pub identifier: u16,
pub sequence_number: u16,
pub originate_timestamp: u32,
pub receive_timestamp: u32,
pub transmit_timestamp: u32,
}
impl Timestamp {
pub const TYPE: Type = Type::Timestamp;
}
impl Codec for Timestamp {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
self.code.encode(writer, ())?;
self.checksum.encode(writer, ())?;
self.identifier.encode(writer, ())?;
self.sequence_number.encode(writer, ())?;
self.originate_timestamp.encode(writer, ())?;
self.receive_timestamp.encode(writer, ())?;
self.transmit_timestamp.encode(writer, ())?;
Ok(())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match Type::decode(reader, ())? {
Self::TYPE => (),
_ => return Err(BufError::UnexpectedValue),
}
let code = EchoReplyCode::decode(reader, ())?;
let checksum = Checksum::decode(reader, ())?;
let identifier = u16::decode(reader, ())?;
let sequence_number = u16::decode(reader, ())?;
let originate_timestamp = u32::decode(reader, ())?;
let receive_timestamp = u32::decode(reader, ())?;
let transmit_timestamp = u32::decode(reader, ())?;
Ok(Self {
code,
checksum,
identifier,
sequence_number,
originate_timestamp,
receive_timestamp,
transmit_timestamp,
})
}
}
pub type TimestampCode = ZeroCode;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TimestampReply {
pub code: TimestampCode,
pub checksum: Checksum,
pub identifier: u16,
pub sequence_number: u16,
pub originate_timestamp: u32,
pub receive_timestamp: u32,
pub transmit_timestamp: u32,
}
impl TimestampReply {
pub const TYPE: Type = Type::TimestampReply;
}
impl Codec for TimestampReply {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
self.code.encode(writer, ())?;
self.checksum.encode(writer, ())?;
self.identifier.encode(writer, ())?;
self.sequence_number.encode(writer, ())?;
self.originate_timestamp.encode(writer, ())?;
self.receive_timestamp.encode(writer, ())?;
self.transmit_timestamp.encode(writer, ())?;
Ok(())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match Type::decode(reader, ())? {
Self::TYPE => (),
_ => return Err(BufError::UnexpectedValue),
}
let code = EchoReplyCode::decode(reader, ())?;
let checksum = Checksum::decode(reader, ())?;
let identifier = u16::decode(reader, ())?;
let sequence_number = u16::decode(reader, ())?;
let originate_timestamp = u32::decode(reader, ())?;
let receive_timestamp = u32::decode(reader, ())?;
let transmit_timestamp = u32::decode(reader, ())?;
Ok(Self {
code,
checksum,
identifier,
sequence_number,
originate_timestamp,
receive_timestamp,
transmit_timestamp,
})
}
}
pub type TimestampReplyCode = ZeroCode;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct InformationRequest {
pub code: InformationRequestCode,
pub checksum: Checksum,
pub identifier: u16,
pub sequence_number: u16,
}
impl InformationRequest {
pub const TYPE: Type = Type::InformationRequest;
}
impl Codec for InformationRequest {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
self.code.encode(writer, ())?;
self.checksum.encode(writer, ())?;
self.identifier.encode(writer, ())?;
self.sequence_number.encode(writer, ())?;
Ok(())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match Type::decode(reader, ())? {
Self::TYPE => (),
_ => return Err(BufError::UnexpectedValue),
}
let code = EchoReplyCode::decode(reader, ())?;
let checksum = Checksum::decode(reader, ())?;
let identifier = u16::decode(reader, ())?;
let sequence_number = u16::decode(reader, ())?;
Ok(Self {
code,
checksum,
identifier,
sequence_number,
})
}
}
pub type InformationRequestCode = ZeroCode;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct InformationReply {
pub code: InformationRequestCode,
pub checksum: Checksum,
pub identifier: u16,
pub sequence_number: u16,
}
impl InformationReply {
pub const TYPE: Type = Type::InformationReply;
}
impl Codec for InformationReply {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
Self::TYPE.encode(writer, ())?;
self.code.encode(writer, ())?;
self.checksum.encode(writer, ())?;
self.identifier.encode(writer, ())?;
self.sequence_number.encode(writer, ())?;
Ok(())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
match Type::decode(reader, ())? {
Self::TYPE => (),
_ => return Err(BufError::UnexpectedValue),
}
let code = EchoReplyCode::decode(reader, ())?;
let checksum = Checksum::decode(reader, ())?;
let identifier = u16::decode(reader, ())?;
let sequence_number = u16::decode(reader, ())?;
Ok(Self {
code,
checksum,
identifier,
sequence_number,
})
}
}
pub type InformationReplyCode = ZeroCode;
#[cfg(test)]
mod tests {}