Add read and write functions for TunInterface

This adds read and write functionality for TunInterface.
This commit is contained in:
JettChenT 2023-05-29 10:36:10 +08:00 committed by Conrad Kramer
parent 9aa1951575
commit 82c4d218d7
5 changed files with 105 additions and 4 deletions

View file

@ -1,9 +1,14 @@
use byteorder::{ByteOrder, NetworkEndian};
use fehler::throws;
use libc::c_char;
use libc::{c_char, iovec, writev, AF_INET, AF_INET6};
use socket2::{Domain, SockAddr, Socket, Type};
use std::io::{IoSlice, Write};
use std::net::{Ipv4Addr, SocketAddrV4};
use std::os::fd::{AsRawFd, RawFd};
use std::{io::Error, mem};
use std::{
io::{Error, Read},
mem,
};
mod kern_control;
mod sys;
@ -122,6 +127,36 @@ impl TunInterface {
}
}
impl Write for TunInterface {
#[throws]
fn write(&mut self, buf: &[u8]) -> usize {
use std::io::ErrorKind;
let proto = match buf[0] >> 4 {
6 => Ok(AF_INET6),
4 => Ok(AF_INET),
_ => Err(Error::new(ErrorKind::InvalidInput, "Invalid IP version")),
}?;
let mut pbuf = [0; 4];
NetworkEndian::write_i32(&mut pbuf, proto);
let bufs = [IoSlice::new(&pbuf), IoSlice::new(buf)];
let bytes_written: isize = unsafe {
writev(
self.as_raw_fd(),
bufs.as_ptr() as *const iovec,
bufs.len() as i32,
)
};
bytes_written
.try_into()
.map_err(|_| Error::new(ErrorKind::Other, "Conversion error"))?
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
#[cfg(test)]
mod test {
use super::*;