1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use std::io::Cursor;
use byteorder::{WriteBytesExt, BigEndian};
use crate::error::*;
use crate::buffer::{self, Buffer};
use crate::builder::{Builder as Build, Finalization};
use crate::packet::{AsPacket, AsPacketMut};
use crate::icmp::builder;
use crate::icmp::Kind;
use crate::icmp::information::Packet;
pub struct Builder<B: Buffer = buffer::Dynamic> {
buffer: B,
finalizer: Finalization,
kind: bool,
}
impl<B: Buffer> Build<B> for Builder<B> {
fn with(mut buffer: B) -> Result<Self> {
buffer.next(8)?;
Ok(Builder {
buffer: buffer,
finalizer: Default::default(),
kind: false,
})
}
fn finalizer(&mut self) -> &mut Finalization {
&mut self.finalizer
}
fn build(mut self) -> Result<B::Inner> {
if !self.kind {
Err(Error::InvalidPacket)?
}
builder::prepare(&mut self.finalizer, &self.buffer);
let mut buffer = self.buffer.into_inner();
self.finalizer.finalize(buffer.as_mut())?;
Ok(buffer)
}
}
impl Default for Builder<buffer::Dynamic> {
fn default() -> Self {
Builder::with(buffer::Dynamic::default()).unwrap()
}
}
impl<'a, B: Buffer> AsPacket<'a, Packet<&'a [u8]>> for Builder<B> {
fn as_packet(&self) -> Result<Packet<&[u8]>> {
Packet::new(self.buffer.data())
}
}
impl<'a, B: Buffer> AsPacketMut<'a, Packet<&'a mut [u8]>> for Builder<B> {
fn as_packet_mut(&mut self) -> Result<Packet<&mut [u8]>> {
Packet::new(self.buffer.data_mut())
}
}
impl<B: Buffer> Builder<B> {
pub fn request(mut self) -> Result<Self> {
self.kind = true;
self.buffer.data_mut()[0] = Kind::InformationRequest.into();
Ok(self)
}
pub fn reply(mut self) -> Result<Self> {
self.kind = true;
self.buffer.data_mut()[0] = Kind::InformationReply.into();
Ok(self)
}
pub fn identifier(mut self, value: u16) -> Result<Self> {
Cursor::new(&mut self.buffer.data_mut()[4 ..])
.write_u16::<BigEndian>(value)?;
Ok(self)
}
pub fn sequence(mut self, value: u16) -> Result<Self> {
Cursor::new(&mut self.buffer.data_mut()[6 ..])
.write_u16::<BigEndian>(value)?;
Ok(self)
}
}