121 lines
3.4 KiB
Rust
121 lines
3.4 KiB
Rust
use core::{
|
|
ffi::{c_int, c_void},
|
|
net::SocketAddr,
|
|
};
|
|
|
|
use crate::{error::EResult, headers::errno::Errno, util::PointerExt};
|
|
|
|
use super::{
|
|
netinet_in::{sockaddr_in, sockaddr_in6},
|
|
sys_uio::__ygg_iovec_t,
|
|
};
|
|
|
|
mod io;
|
|
mod option;
|
|
mod socket;
|
|
|
|
pub type socklen_t = usize;
|
|
pub type sa_family_t = u16;
|
|
|
|
pub const __SS_SIZE: usize = 256;
|
|
// __SS_SIZE - sizeof(sa_samily_t)
|
|
pub const __SOCKADDR_LEN: usize = __SS_SIZE - 2;
|
|
// __SS_SIZE - sizeof(sa_family_t) - sizeof(__ss_aligntype)
|
|
pub const __SS_PADSIZE: usize = __SS_SIZE - 6;
|
|
|
|
pub type __ss_aligntype = u32;
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
#[repr(C)]
|
|
pub struct sockaddr {
|
|
pub sa_family: sa_family_t,
|
|
pub sa_data: [u8; __SOCKADDR_LEN],
|
|
}
|
|
|
|
// TODO struct sockaddr_storage
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
#[repr(C)]
|
|
pub struct msghdr {
|
|
pub msg_name: *mut c_void,
|
|
pub msg_namelen: socklen_t,
|
|
pub msg_iov: *mut __ygg_iovec_t,
|
|
pub msg_iovlen: c_int,
|
|
pub msg_control: *mut c_void,
|
|
pub msg_controllen: socklen_t,
|
|
pub msg_flags: c_int,
|
|
}
|
|
|
|
// TODO struct cmsghdr
|
|
|
|
// socket() parameters
|
|
pub const SOCK_DGRAM: c_int = 1;
|
|
pub const SOCK_RAW: c_int = 2;
|
|
pub const SOCK_SEQPACKET: c_int = 3;
|
|
pub const SOCK_STREAM: c_int = 4;
|
|
|
|
// setsockopt() parameters
|
|
pub const SOL_SOCKET: c_int = 1 << 24;
|
|
pub const SOL_SOCKOPT_TCP: c_int = 2 << 24;
|
|
pub const SOL_SOCKOPT_IPV4: c_int = 4 << 24;
|
|
pub const SOL_SOCKOPT_IPV6: c_int = 6 << 24;
|
|
|
|
pub const SO_ACCEPTCONN: c_int = 1 | SOL_SOCKET;
|
|
pub const SO_BROADCAST: c_int = 2 | SOL_SOCKET;
|
|
pub const SO_DEBUG: c_int = 3 | SOL_SOCKET;
|
|
pub const SO_DONTROUTE: c_int = 4 | SOL_SOCKET;
|
|
pub const SO_ERROR: c_int = 5 | SOL_SOCKET;
|
|
pub const SO_KEEPALIVE: c_int = 6 | SOL_SOCKET;
|
|
pub const SO_LINGER: c_int = 7 | SOL_SOCKET;
|
|
pub const SO_OOBINLINE: c_int = 8 | SOL_SOCKET;
|
|
pub const SO_RCVBUF: c_int = 9 | SOL_SOCKET;
|
|
pub const SO_RCVLOWAT: c_int = 10 | SOL_SOCKET;
|
|
pub const SO_RCVTIMEO: c_int = 11 | SOL_SOCKET;
|
|
pub const SO_REUSEADDR: c_int = 12 | SOL_SOCKET;
|
|
pub const SO_SNDBUF: c_int = 13 | SOL_SOCKET;
|
|
pub const SO_SNDLOWAT: c_int = 14 | SOL_SOCKET;
|
|
pub const SO_SNDTIMEO: c_int = 15 | SOL_SOCKET;
|
|
pub const SO_TYPE: c_int = 16 | SOL_SOCKET;
|
|
|
|
pub const SOMAXCONN: usize = 64;
|
|
|
|
// TODO msg_flags values
|
|
|
|
pub const AF_INET: c_int = 1;
|
|
pub const AF_INET6: c_int = 2;
|
|
pub const AF_UNIX: c_int = 3;
|
|
pub const AF_UNSPEC: c_int = 0;
|
|
|
|
pub const SHUT_RD: c_int = 1 << 0;
|
|
pub const SHUT_WR: c_int = 1 << 1;
|
|
pub const SHUT_RDWR: c_int = SHUT_RD | SHUT_WR;
|
|
|
|
pub(crate) trait SocketAddrExt<T> {
|
|
fn to_c(&self, storage: *mut T, len: socklen_t) -> EResult<socklen_t>;
|
|
}
|
|
|
|
impl sockaddr {
|
|
pub unsafe fn to_rust(self: *const Self, len: socklen_t) -> EResult<SocketAddr> {
|
|
let family = self.ensure().sa_family as c_int;
|
|
match family {
|
|
AF_INET if len == size_of::<sockaddr_in>() => {
|
|
self.cast::<sockaddr_in>().to_rust().map(SocketAddr::V4)
|
|
}
|
|
AF_INET6 if len == size_of::<sockaddr_in6>() => {
|
|
self.cast::<sockaddr_in6>().to_rust().map(SocketAddr::V6)
|
|
}
|
|
_ => EResult::Err(Errno::ENOTSUPP),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl SocketAddrExt<sockaddr> for SocketAddr {
|
|
fn to_c(&self, storage: *mut sockaddr, len: socklen_t) -> EResult<socklen_t> {
|
|
match self {
|
|
Self::V4(v4) if len >= size_of::<sockaddr_in>() => v4.to_c(storage.cast(), len),
|
|
Self::V6(v6) if len >= size_of::<sockaddr_in6>() => v6.to_c(storage.cast(), len),
|
|
_ => EResult::Err(Errno::EINVAL),
|
|
}
|
|
}
|
|
}
|