1pub type Result<T> = std::result::Result<T, Error>;
2
3#[derive(Debug)]
5pub enum Error {
6 Io(std::io::Error),
7 IncorrectBufferSize,
8 NotIpv4Packet,
9 NotIcmpPacket,
10 NotIcmpv6Packet,
11 PayloadTooShort { got: usize, want: usize },
12 IOError(String),
13 NotEchoReply,
14 NotV6EchoReply,
15 Timeout,
16 OtherICMP,
17 InvalidSize,
18 InvalidPacket,
19 TooSmallHeader,
20 InvalidHeaderSize,
21 InvalidVersion,
22 UnknownProtocol,
23 Unimplemented,
24 UnsupportedSocketType,
25}
26
27impl From<std::io::Error> for Error {
28 fn from(error: std::io::Error) -> Self {
29 Self::Io(error)
30 }
31}
32
33impl std::fmt::Display for Error {
34 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35 match self {
36 Error::Io(error) => write!(f, "io error: {error}"),
37 Error::IncorrectBufferSize => write!(f, "incorrect buffer size"),
38 Error::NotIpv4Packet => write!(f, "not an IPv4 packet"),
39 Error::NotIcmpPacket => write!(f, "not an ICMP packet"),
40 Error::NotIcmpv6Packet => write!(f, "not an ICMPv6 packet"),
41 Error::PayloadTooShort { got, want } => {
42 write!(f, "payload too short: got {got} bytes, want {want}")
43 }
44 Error::IOError(error) => write!(f, "io error: {error}"),
45 Error::NotEchoReply => write!(f, "not an ICMP echo reply"),
46 Error::NotV6EchoReply => write!(f, "not an ICMPv6 echo reply"),
47 Error::Timeout => write!(f, "ping timed out"),
48 Error::OtherICMP => write!(f, "received a non-echo ICMP packet"),
49 Error::InvalidSize => write!(f, "invalid packet size"),
50 Error::InvalidPacket => write!(f, "invalid packet"),
51 Error::TooSmallHeader => write!(f, "packet header is too small"),
52 Error::InvalidHeaderSize => write!(f, "invalid IP header size"),
53 Error::InvalidVersion => write!(f, "invalid IP version"),
54 Error::UnknownProtocol => write!(f, "unknown IP protocol"),
55 Error::Unimplemented => write!(f, "operation is not implemented"),
56 Error::UnsupportedSocketType => write!(f, "unsupported socket type"),
57 }
58 }
59}
60
61impl std::error::Error for Error {
62 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
63 match self {
64 Error::Io(error) => Some(error),
65 _ => None,
66 }
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn display_messages_are_not_empty() {
76 let errors = [
77 Error::Timeout,
78 Error::InvalidPacket,
79 Error::InvalidHeaderSize,
80 Error::UnsupportedSocketType,
81 ];
82
83 for error in errors {
84 assert!(!error.to_string().is_empty());
85 }
86 }
87}