bbk47_toolbox/
socks5.rs

1use std::error::Error;
2use std::fmt::{self, Display, Formatter};
3use std::net::{Ipv4Addr, Ipv6Addr};
4use std::str::FromStr;
5
6#[derive(Debug)]
7struct InvalidAddressType;
8
9impl Display for InvalidAddressType {
10    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
11        write!(f, "invalid address type")
12    }
13}
14
15impl Error for InvalidAddressType {}
16
17#[derive(Debug, PartialEq)]
18pub struct AddrInfo {
19    pub host: String,
20    pub port: u16,
21}
22
23impl AddrInfo {
24    pub fn from_buffer(buffer: &[u8]) -> Result<Self, Box<dyn Error>> {
25        match buffer.first() {
26            Some(&1) => {
27                let mut ip = [0; 4];
28                ip.copy_from_slice(&buffer[1..=4]);
29                let host = Ipv4Addr::from(ip).to_string();
30                let port = u16::from_be_bytes([buffer[buffer.len() - 2], buffer.last().copied().unwrap_or(0x00)]);
31                Ok(AddrInfo { host, port })
32            }
33
34            Some(&3) => {
35                let domain_length: usize = buffer[1] as usize;
36                // println!("domain_length:{}",&domain_length);
37                let domain_end = 2 + domain_length;
38                let host: String = String::from_utf8_lossy(&buffer[2..domain_end]).to_string();
39                let port = u16::from_be_bytes([buffer[buffer.len() - 2], buffer.last().copied().unwrap_or(0x00)]);
40                // println!("parse socks5 addr:{},{}",host,port);
41                Ok(AddrInfo { host, port })
42            }
43
44            Some(&4) => {
45                let mut ip = [0; 16];
46                ip.copy_from_slice(&buffer[1..=16]);
47                let host = Ipv6Addr::from(ip).to_string();
48                let port = u16::from_be_bytes([buffer[buffer.len() - 2], buffer.last().copied().unwrap_or(0x00)]);
49                Ok(AddrInfo { host, port })
50            }
51
52            _ => Err(Box::new(InvalidAddressType)),
53        }
54    }
55}
56
57pub fn build_socks5_buffer(host: &str, port: u16) -> Result<Vec<u8>, Box<dyn Error>> {
58    if let Ok(ipv4_host) = Ipv4Addr::from_str(host) {
59        Ok(vec![1].into_iter().chain(ipv4_host.octets().iter().copied()).chain(port.to_be_bytes().iter().copied()).collect())
60    } else if let Ok(ipv6_host) = Ipv6Addr::from_str(host) {
61        Ok(vec![4].into_iter().chain(ipv6_host.octets().iter().copied()).chain(port.to_be_bytes().iter().copied()).collect())
62    } else {
63        let domain_length = host.len();
64        let mut buffer = vec![3, domain_length as u8];
65        buffer.extend_from_slice(host.as_bytes());
66        buffer.extend_from_slice(&port.to_be_bytes());
67        Ok(buffer)
68    }
69}