1use std::net::IpAddr;
2
3use crate::{EchoRequest as ER2, IcmpV4, IpV4Packet, ER1};
4
5use crate::error::{Error, Result};
6
7#[derive(Debug)]
8pub struct EchoRequest {
9 pub destination: IpAddr,
10 pub ident: u16,
11 pub seq_cnt: u16,
12 pub size: usize,
13}
14
15impl EchoRequest {
16 pub fn new(destination: IpAddr, ident: u16, seq_cnt: u16, size: usize) -> Self {
17 EchoRequest {
18 destination,
19 ident,
20 seq_cnt,
21 size,
22 }
23 }
24
25 pub fn encode(&self) -> Result<Vec<u8>> {
26 match self.destination {
27 IpAddr::V4(_) => self.encode_icmp_v4(),
28 IpAddr::V6(_) => self.encode_icmp_v6(),
29 }
30 }
31
32 fn encode_icmp_v4(&self) -> Result<Vec<u8>> {
34 let req = ER2 {
35 ident: self.ident,
36 seq_cnt: self.seq_cnt,
37 };
38 let mut buffer = vec![0; 8 + self.size]; let payload = vec![0; self.size];
40 req.encode::<IcmpV4>(&mut buffer, &payload)
41 }
42
43 fn encode_icmp_v6(&self) -> Result<Vec<u8>> {
45 Err(Error::Unimplemented)
46 }
47}
48
49#[derive(Debug)]
51pub struct EchoReply {
52 pub ttl: Option<u8>,
55 pub source: IpAddr,
57 pub sequence: u16,
59 pub identifier: u16,
61 pub size: usize,
63}
64
65impl EchoReply {
66 pub fn decode(addr: IpAddr, buf: &[u8]) -> Result<EchoReply> {
68 match addr {
69 IpAddr::V4(_) => decode_icmpv4(addr, buf),
70 IpAddr::V6(_) => decode_icmpv6(addr, buf),
71 }
72 }
73}
74
75fn decode_icmpv4(addr: IpAddr, buf: &[u8]) -> Result<EchoReply> {
77 let ipv4_decoded = IpV4Packet::decode(buf)?;
78 let icmp_decoded = ER1::decode::<IcmpV4>(ipv4_decoded.data)?;
79 Ok(EchoReply {
80 ttl: None,
81 source: addr,
82 sequence: icmp_decoded.seq_cnt,
83 identifier: icmp_decoded.ident,
84 size: icmp_decoded.payload.len(),
85 })
86}
87
88fn decode_icmpv6(_addr: IpAddr, _buf: &[u8]) -> Result<EchoReply> {
90 Err(Error::Unimplemented)
91}