use {
std::net::IpAddr,
crate::error::{Error, Socks5ErrorKind}
};
pub const SOCKS5: u8 = 0x05;
pub const RESERVED: u8 = 0x00;
#[derive(Debug)]
pub enum DestAddr {
IP(IpAddr),
FQDN(Vec<u8>),
}
#[derive(Debug)]
pub struct Request {
pub dest_addr: DestAddr,
pub dest_port: u16,
}
impl Request {
pub fn new(dest_addr: DestAddr, dest_port: u16) -> Self {
Self{ dest_addr, dest_port }
}
}
pub mod addrtype {
use super::*;
pub const V4: u8 = 0x01;
pub const FQDN: u8 = 0x03;
pub const V6: u8 = 0x04;
#[repr(u8)]
#[derive(Debug)]
pub enum AddrType {
V4 = V4,
FQDN = FQDN,
V6 = V6,
}
impl TryFrom<u8> for AddrType {
type Error = Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
V4 => Ok(AddrType::V4),
FQDN => Ok(AddrType::FQDN),
V6 => Ok(AddrType::V6),
_ => Err(Error::from(Socks5ErrorKind::AddressTypeNotSupported)),
}
}
}
}
pub mod command {
use super::*;
pub const CONNECT: u8 = 0x01;
pub const BIND: u8 = 0x02;
pub const ASSOCIATE: u8 = 0x03;
#[repr(u8)]
#[derive(Debug)]
pub enum CommandKind {
Connect = CONNECT,
Bind = BIND,
Associate = ASSOCIATE,
}
impl TryFrom<u8> for CommandKind {
type Error = Error;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
CONNECT => Ok(CommandKind::Connect),
BIND => Ok(CommandKind::Bind),
ASSOCIATE => Ok(CommandKind::Associate),
_ => Err(Error::from(Socks5ErrorKind::CommandNotSupported)),
}
}
}
#[derive(Debug)]
pub enum Command {
Connect(Request),
Bind(Request),
Associate(Request),
}
}
pub mod method {
pub const NO_AUTH: u8 = 0x00;
pub const GSSAPI: u8 = 0x01;
pub const USER_PASS: u8 = 0x02;
pub const NO_ACCEPTABLE_METHODS: u8 = 0xff;
#[repr(u8)]
#[derive(Debug)]
pub enum Method {
NoAuth = NO_AUTH,
GSSAPI = GSSAPI,
UserPass = USER_PASS,
NoAcceptableMethods = NO_ACCEPTABLE_METHODS,
}
}
pub const fn check_buffer_length(buffer: &[u8], min_length: usize) -> crate::error::Result<()> {
if buffer.len() < min_length {
return Err(crate::error::Error::SHORT_BUFFER_ERROR);
}
Ok(())
}