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),
}
}
}