Skip to main content

libinject/
utils.rs

1use crate::ffi;
2use os_socketaddr::OsSocketAddr;
3use std::mem::{size_of, zeroed};
4use std::net::SocketAddr;
5use winapi::shared::ws2def::{SOCKADDR, SOCKADDR_STORAGE};
6use winapi::um::winsock2::getpeername;
7
8pub trait Boolean {
9    fn as_bool(self: Self) -> bool;
10}
11
12pub trait FromBuf {
13    fn from_buf(buf: Vec<u8>) -> Option<Self>
14    where
15        Self: Sized;
16}
17
18impl FromBuf for std::net::SocketAddr {
19    fn from_buf(buf: Vec<u8>) -> Option<Self> {
20        let sockaddr_ptr = buf.as_ptr() as *const SOCKADDR;
21        // Unsafe block is safe for all `from_buf` inputs, because `socketaddr_ptr` is
22        // guranteed to be a pointer to a valid slice of length `buf.len()`.
23        unsafe { OsSocketAddr::copy_from_raw(sockaddr_ptr, buf.len() as i32).into() }
24    }
25}
26
27pub unsafe fn socketaddr_from_socket_id(socket_id: usize) -> Result<SocketAddr, String> {
28    unsafe {
29        let mut addr: SOCKADDR_STORAGE = zeroed();
30        let mut len = size_of::<SOCKADDR_STORAGE>() as i32;
31
32        match getpeername(socket_id, &mut addr as *mut _ as *mut SOCKADDR, &mut len) {
33            0 => {
34                let ptr = &addr as *const _ as *const SOCKADDR;
35                let socketaddr: Option<SocketAddr> = OsSocketAddr::copy_from_raw(ptr, len).into();
36                socketaddr.ok_or(String::from("Failed converting an os_socketaddr::OsSocketAddr to a std::net::SocketAddr, .sa_family must resolve to AF_INET or AF_INET6."))
37            }
38            _ => Err(String::from("getpeername returned a non-zero exit code")),
39        }
40    }
41}
42
43#[derive(Debug)]
44pub struct ReadError {
45    pub n_bytes_tried: usize,
46    pub n_bytes_read: usize,
47    pub buf: Vec<u8>,
48}
49
50#[derive(Debug)]
51pub struct WriteError {
52    pub data_tried: Vec<u8>,
53    pub n_bytes_tried: usize,
54    pub n_bytes_written: usize,
55}
56
57#[derive(Debug)]
58pub enum Utf8NameError {
59    NullPtr,
60    Malformed(String),
61}
62
63pub const OPSZ_PTR: ffi::opnd_size_t = if cfg!(target_pointer_width = "64") {
64    ffi::OPSZ_8 as u8
65} else {
66    ffi::OPSZ_4 as u8
67};
68
69pub fn opnd_create_uintptr(val: usize) -> ffi::opnd_t {
70    unsafe { ffi::opnd_create_immed_uint(val as ffi::ptr_uint_t, OPSZ_PTR) }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    #[test]
78    fn read_name_error() {
79        let e = Utf8NameError::Malformed(String::from("aMalformedModName"));
80        println!("utf8 parse failed with: {:?}", e);
81    }
82}