diff --git a/src/config.rs b/src/config.rs index 586917d..32ee90d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,8 +1,7 @@ use std::error::Error; -use std::net::{AddrParseError, Ipv4Addr}; -use std::num::ParseIntError; +use std::net::Ipv4Addr; use std::path::{Path, PathBuf}; -use std::{env, fmt, process}; +use std::{env, process}; pub struct Config { pub ip_address: Ipv4Addr, @@ -11,7 +10,7 @@ pub struct Config { } impl Config { - pub fn new(mut args: T) -> Result + pub fn new(mut args: T) -> Result> where T: Iterator, { @@ -69,53 +68,6 @@ impl Config { } } -#[derive(Debug)] -pub struct ConfigError { - description: String, -} - -impl Error for ConfigError { - fn description(&self) -> &str { - self.description.as_str() - } -} - -impl fmt::Display for ConfigError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.description) - } -} - -impl From for ConfigError { - fn from(value: AddrParseError) -> Self { - ConfigError { - description: value.to_string(), - } - } -} - -impl From for ConfigError { - fn from(value: ParseIntError) -> Self { - ConfigError { - description: value.to_string(), - } - } -} - -impl From for ConfigError { - fn from(value: String) -> Self { - ConfigError { description: value } - } -} - -impl From<&str> for ConfigError { - fn from(value: &str) -> Self { - ConfigError { - description: value.to_string(), - } - } -} - #[cfg(test)] mod tests { use std::str::FromStr; diff --git a/src/convert.rs b/src/convert.rs new file mode 100644 index 0000000..715f14a --- /dev/null +++ b/src/convert.rs @@ -0,0 +1,22 @@ +use std::error::Error; + +pub struct Convert; + +impl Convert { + pub fn to_u16(buf: &[u8]) -> Result { + if buf.len() < 2 { + Err("error when converting to u16") + } else { + Ok(((buf[0] as u16) << 8) + buf[1] as u16) + } + } + + pub fn to_string(buf: &[u8]) -> Result<(String, usize), Box> { + let zero_index = match buf[2..].iter().position(|&b| b == 0x00) { + Some(index) => index, + None => return Err("invalid string".into()), + }; + + Ok((String::from_utf8(buf[2..zero_index].to_vec())?, zero_index)) + } +} diff --git a/src/lib.rs b/src/lib.rs index 86ef2b1..b3f8e16 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,8 @@ -pub mod config; +mod config; +mod convert; +mod packet; +mod server; + pub use config::Config; +pub use convert::Convert; +pub use server::Server; diff --git a/src/main.rs b/src/main.rs index 533ce17..ab31ba9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use std::{env, process}; -use tftpd::Config; +use tftpd::{Config, Server}; fn main() { let config = Config::new(env::args()).unwrap_or_else(|err| { @@ -7,8 +7,18 @@ fn main() { process::exit(1) }); + let server = Server::new(&config).unwrap_or_else(|err| { + eprintln!( + "Problem creating server on {}:{}: {}", + config.ip_address, config.port, err + ); + process::exit(1) + }); + println!( "Running TFTP Server on {}:{}", config.ip_address, config.port ); + + server.listen(); } diff --git a/src/packet.rs b/src/packet.rs new file mode 100644 index 0000000..7085710 --- /dev/null +++ b/src/packet.rs @@ -0,0 +1,141 @@ +use crate::Convert; +use std::error::Error; + +pub enum Packet<'a> { + Rrq { + filename: String, + mode: String, + options: Vec