Skip to content

Instantly share code, notes, and snippets.

@LuoZijun
Created September 1, 2019 11:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LuoZijun/095937109781ea7a85473894ac51eb3d to your computer and use it in GitHub Desktop.
Save LuoZijun/095937109781ea7a85473894ac51eb3d to your computer and use it in GitHub Desktop.
#![allow(non_camel_case_types, unused_variables, non_snake_case)]
pub type c_void = ();
pub type ULONG = u64;
pub type LONG = i64;
pub type HANDLE = *mut c_void;
pub type TUN_RING_PTR = *mut u8;
pub const TUN_RING_DEFAULT_CAPACITY: usize = 8388608; // 2**23 = 8MB
pub const TUN_RING_LEN: usize = std::mem::size_of::<TUN_RING_HEADER>() + TUN_RING_DEFAULT_CAPACITY + 0x10000;
#[repr(C)]
pub struct TUN_RING_HEADER {
pub Head: ULONG,
pub Tail: ULONG,
pub Alertable: LONG, // Bool
}
pub struct TUN_RING {
inner: Vec<u8>,
}
impl TUN_RING {
pub fn new(header: TUN_RING_HEADER) -> Self {
let size = TUN_RING_LEN;
let mut inner = Vec::with_capacity(size);
inner.resize(size, 0u8);
let header_len = std::mem::size_of::<TUN_RING_HEADER>();
let header_ptr = &header as *const TUN_RING_HEADER as *const u8;
let header_bytes = unsafe { std::slice::from_raw_parts(header_ptr, header_len) };
(&mut inner[..header_len]).copy_from_slice(header_bytes);
Self { inner }
}
pub fn as_ptr(&self) -> *const u8 {
self.inner.as_ptr()
}
pub fn as_mut_ptr(&mut self) -> *mut u8 {
self.inner.as_mut_ptr()
}
pub fn header(&self) -> &TUN_RING_HEADER {
let header_len = std::mem::size_of::<TUN_RING_HEADER>();
let header_bytes = &self.inner[..header_len];
unsafe { std::mem::transmute::<*const u8, &TUN_RING_HEADER>(header_bytes.as_ptr()) }
}
pub fn head(&self) -> ULONG {
self.header().Head
}
pub fn tail(&self) -> ULONG {
self.header().Tail
}
pub fn alertable(&self) -> LONG {
self.header().Alertable
}
}
pub struct TUN_REGISTER_RING {
pub RingSize: ULONG,
pub Ring: TUN_RING_PTR, // *mut TUN_RING
pub TailMoved: HANDLE,
}
pub struct TUN_REGISTER_RINGS {
pub Send: TUN_REGISTER_RING,
pub Receive: TUN_REGISTER_RING,
}
// for (;;) {
// TUN_PACKET *Next = PopFromRing(Rings->Send.Ring);
// if (!Next) {
// Rings->Send.Ring->Alertable = TRUE;
// Next = PopFromRing(Rings->Send.Ring);
// if (!Next) {
// WaitForSingleObject(Rings->Send.TailMoved, INFINITE);
// Rings->Send.Ring->Alertable = FALSE;
// continue;
// }
// Rings->Send.Ring->Alertable = FALSE;
// ResetEvent(Rings->Send.TailMoved);
// }
// SendToClientProgram(Next);
// }
fn main() {
let mut a = TUN_RING::new(TUN_RING_HEADER { Head: 100, Tail: 200, Alertable: 1});
let mut b = TUN_RING::new(TUN_RING_HEADER { Head: 100, Tail: 200, Alertable: 1});
let a_ptr = a.as_mut_ptr();
let b_ptr = b.as_mut_ptr();
// NOTE: 如果有必要
// std::mem::forget(a);
// std::mem::forget(b);
let register = TUN_REGISTER_RINGS {
Send: TUN_REGISTER_RING {
RingSize: 100,
Ring: a_ptr,
TailMoved: std::ptr::null_mut::<()>() as HANDLE,
},
Receive: TUN_REGISTER_RING {
RingSize: 100,
Ring: b_ptr,
TailMoved: std::ptr::null_mut::<()>() as HANDLE,
},
};
let f = || -> *mut u8 {
unreachable!()
};
// NOTE: 从 C 代码那边接收 TUN_RING 指针
let ring_ptr = f();
let ring_inner = unsafe { Vec::from_raw_parts(ring_ptr, TUN_RING_LEN, TUN_RING_LEN) };
let ring = TUN_RING { inner: ring_inner };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment