1extern crate byteorder;
2
3use std::error;
4use std::fmt;
5use std::io;
6use std::result;
7
8use super::options::Options;
9use super::packetreader;
10use super::packetwriter;
11
12
13#[derive(Debug,PartialEq)]
15pub enum Error {
16 InvalidOpCode(u16),
18 InvalidTransferMode(String),
20 InvalidErrorCode(u16),
22 InvalidOptions(String),
30 ReadError(packetreader::Error),
32 WriteError(packetwriter::Error),
34}
35
36
37impl fmt::Display for Error {
38 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39 match *self {
40 Error::InvalidOpCode(opcode) =>
41 write!(f, "invalid operation: {}", opcode),
42 Error::InvalidTransferMode(ref txmode) =>
43 write!(f, "invalid transfer mode: {:?}", txmode),
44 Error::InvalidErrorCode(errcode) =>
45 write!(f, "invalid error code: {}", errcode),
46 Error::InvalidOptions(ref options) =>
47 write!(f, "invalid options: {:?}", options),
48 Error::ReadError(ref error) =>
49 write!(f, "packet could not be read: {:?}", error),
50 Error::WriteError(ref error) =>
51 write!(f, "packet could not be written: {:?}", error),
52 }
53 }
54}
55
56
57impl error::Error for Error {
58 fn description(&self) -> &str {
59 "tftp packet error"
60 }
61
62 fn cause(&self) -> Option<&error::Error> {
63 match *self {
64 Error::ReadError(ref error) => Some(error),
65 Error::WriteError(ref error) => Some(error),
66 _ => None,
67 }
68 }
69}
70
71
72impl From<packetreader::Error> for Error {
73 fn from(error: packetreader::Error) -> Error {
74 Error::ReadError(error)
75 }
76}
77
78
79impl From<packetwriter::Error> for Error {
80 fn from(error: packetwriter::Error) -> Error {
81 Error::WriteError(error)
82 }
83}
84
85
86impl From<Error> for io::Error {
87 fn from(error: Error) -> io::Error {
88 io::Error::new(io::ErrorKind::Other, error)
89 }
90}
91
92
93pub type Result<T> = result::Result<T, Error>;
94
95
96#[derive(Debug)]
98pub enum OpCode {
99 RRQ = 1,
101 WRQ = 2,
103 DATA = 3,
105 ACK = 4,
107 ERROR = 5,
109 OACK = 6,
111}
112
113impl OpCode {
114 fn read(buffer: &mut packetreader::PacketReader) -> Result<Self> {
115 let code = buffer.take_u16()?;
116 match Self::from(code) {
117 Some(opcode) => Ok(opcode),
118 None => Err(Error::InvalidOpCode(code)),
119 }
120 }
121
122 pub fn write(self, writer: &mut packetwriter::PacketWriter) -> Result<()> {
123 writer.put_u16(self as u16)?;
124 Ok(())
125 }
126
127 fn from(opcode: u16) -> Option<Self> {
128 use self::OpCode::*;
129 match opcode {
130 1 => Some(RRQ),
131 2 => Some(WRQ),
132 3 => Some(DATA),
133 4 => Some(ACK),
134 5 => Some(ERROR),
135 6 => Some(OACK),
136 _ => None,
137 }
138 }
139}
140
141
142#[derive(Debug)]
154pub struct Filename(pub String);
155
156impl Filename {
157 fn read(buffer: &mut packetreader::PacketReader) -> Result<Self> {
158 Ok(Filename(buffer.take_string()?))
159 }
160
161 pub fn write(self, writer: &mut packetwriter::PacketWriter) -> Result<()> {
162 writer.put_string(&self.0)?;
163 Ok(())
164 }
165}
166
167
168#[derive(Debug)]
170pub enum TransferMode {
171 NetASCII,
173 Octet,
175}
176
177impl TransferMode {
178 fn read(buffer: &mut packetreader::PacketReader) -> Result<Self> {
179 let mode = buffer.take_string()?;
180 match TransferMode::parse(&mode.as_bytes()) {
181 Some(txmode) => Ok(txmode),
182 None => Err(Error::InvalidTransferMode(mode)),
183 }
184 }
185
186 pub fn write(self, writer: &mut packetwriter::PacketWriter) -> Result<()> {
187 writer.put_string(match self {
188 TransferMode::NetASCII => "netascii",
189 TransferMode::Octet => "octet",
190 })?;
191 Ok(())
192 }
193
194 fn parse(buffer: &[u8]) -> Option<Self> {
195 if buffer.eq_ignore_ascii_case("netascii".as_bytes()) {
196 Some(TransferMode::NetASCII)
197 }
198 else if buffer.eq_ignore_ascii_case("octet".as_bytes()) {
199 Some(TransferMode::Octet)
200 }
201 else {
202 None
203 }
204 }
205}
206
207
208#[derive(Debug)]
210pub struct BlockNum(pub u16);
211
212impl BlockNum {
213 fn read(buffer: &mut packetreader::PacketReader) -> Result<Self> {
214 let blocknum = buffer.take_u16()?;
215 Ok(BlockNum(blocknum))
216 }
217
218 pub fn write(self, writer: &mut packetwriter::PacketWriter) -> Result<()> {
219 writer.put_u16(self.0)?;
220 Ok(())
221 }
222}
223
224
225#[derive(Debug)]
227pub struct Data<'a>(pub &'a [u8]);
228
229impl<'a> Data<'a> {
230 fn read(buffer: &mut packetreader::PacketReader<'a>) -> Result<Self> {
231 let data = buffer.take_remaining()?;
232 Ok(Data(data))
233 }
234
235 pub fn write(self, writer: &mut packetwriter::PacketWriter) -> Result<()> {
236 writer.put_bytes(&self.0)?;
237 Ok(())
238 }
239}
240
241
242#[derive(Debug)]
246pub enum ErrorCode {
247 NotDefined = 0,
249 FileNotFound = 1,
251 AccessViolation = 2,
253 DiskFull = 3,
255 IllegalOperation = 4,
257 UnknownTransferId = 5,
259 FileAlreadyExists = 6,
261 NoSuchUser = 7,
263 BadOptions = 8,
265}
266
267impl ErrorCode {
268 fn read(buffer: &mut packetreader::PacketReader) -> Result<Self> {
269 let code = buffer.take_u16()?;
270 match Self::from(code) {
271 Some(errorcode) => Ok(errorcode),
272 None => Err(Error::InvalidErrorCode(code)),
273 }
274 }
275
276 pub fn write(self, writer: &mut packetwriter::PacketWriter) -> Result<()> {
277 writer.put_u16(self as u16)?;
278 Ok(())
279 }
280
281 fn from(code: u16) -> Option<Self> {
282 use self::ErrorCode::*;
283 match code {
284 0 => Some(NotDefined),
285 1 => Some(FileNotFound),
286 2 => Some(AccessViolation),
287 3 => Some(DiskFull),
288 4 => Some(IllegalOperation),
289 5 => Some(UnknownTransferId),
290 6 => Some(FileAlreadyExists),
291 7 => Some(NoSuchUser),
292 8 => Some(BadOptions),
293 _ => None,
294 }
295 }
296}
297
298
299#[derive(Debug)]
301pub struct ErrorMessage(pub String);
302
303impl ErrorMessage {
304 fn read(buffer: &mut packetreader::PacketReader) -> Result<Self> {
305 Ok(ErrorMessage(buffer.take_string()?))
306 }
307
308 pub fn write(self, writer: &mut packetwriter::PacketWriter) -> Result<()> {
309 writer.put_string(&self.0)?;
310 Ok(())
311 }
312}
313
314
315#[derive(Debug)]
317pub enum Packet<'a> {
318 Read(Filename, TransferMode, Options),
319 Write(Filename, TransferMode, Options),
320 Data(BlockNum, Data<'a>),
321 Ack(BlockNum),
322 Error(ErrorCode, ErrorMessage),
323 OAck(Options),
324}
325
326impl<'a> Packet<'a> {
327 pub fn parse(buffer: &'a [u8]) -> Result<Self>
328 where Self: 'a
329 {
330 let mut buffer = packetreader::PacketReader::new(&buffer);
331 match OpCode::read(&mut buffer)? {
332 OpCode::RRQ => Ok(Packet::Read(
333 Filename::read(&mut buffer)?,
334 TransferMode::read(&mut buffer)?,
335 Options::read(&mut buffer)?,
336 )),
337 OpCode::WRQ => Ok(Packet::Write(
338 Filename::read(&mut buffer)?,
339 TransferMode::read(&mut buffer)?,
340 Options::read(&mut buffer)?,
341 )),
342 OpCode::DATA => Ok(Packet::Data(
343 BlockNum::read(&mut buffer)?,
344 Data::read(&mut buffer)?,
345 )),
346 OpCode::ACK => Ok(Packet::Ack(
347 BlockNum::read(&mut buffer)?,
348 )),
349 OpCode::ERROR => Ok(Packet::Error(
350 ErrorCode::read(&mut buffer)?,
351 ErrorMessage::read(&mut buffer)?,
352 )),
353 OpCode::OACK => Ok(Packet::OAck(
354 Options::read(&mut buffer)?,
355 )),
356 }
357 }
358
359 pub fn opcode(&self) -> OpCode {
360 match *self {
361 Packet::Read(..) => OpCode::RRQ,
362 Packet::Write(..) => OpCode::WRQ,
363 Packet::Data(..) => OpCode::DATA,
364 Packet::Ack(..) => OpCode::ACK,
365 Packet::Error(..) => OpCode::ERROR,
366 Packet::OAck(..) => OpCode::OACK,
367 }
368 }
369
370 pub fn write(self, mut buffer: &'a mut [u8]) -> Result<usize> {
371 let mut buffer = packetwriter::PacketWriter::new(&mut buffer);
372 self.opcode().write(&mut buffer)?;
373 match self {
374 Packet::Read(filename, mode, options) => {
375 filename.write(&mut buffer)?;
376 mode.write(&mut buffer)?;
377 options.write(&mut buffer)?;
378 },
379 Packet::Write(filename, mode, options) => {
380 filename.write(&mut buffer)?;
381 mode.write(&mut buffer)?;
382 options.write(&mut buffer)?;
383 },
384 Packet::Data(block, data) => {
385 block.write(&mut buffer)?;
386 data.write(&mut buffer)?;
387 },
388 Packet::Ack(block) => {
389 block.write(&mut buffer)?;
390 },
391 Packet::Error(code, message) => {
392 code.write(&mut buffer)?;
393 message.write(&mut buffer)?;
394 },
395 Packet::OAck(options) => {
396 options.write(&mut buffer)?;
397 },
398 };
399 Ok(buffer.pos())
400 }
401}