1*cde5492fSlogin use core::cmp::min; 2*cde5492fSlogin 3*cde5492fSlogin use alloc::{boxed::Box, sync::Arc}; 4*cde5492fSlogin use num_traits::{FromPrimitive, ToPrimitive}; 5*cde5492fSlogin use smoltcp::wire; 6*cde5492fSlogin 7*cde5492fSlogin use crate::{ 8*cde5492fSlogin arch::asm::current::current_pcb, 9*cde5492fSlogin filesystem::vfs::{ 10*cde5492fSlogin file::{File, FileMode}, 11*cde5492fSlogin syscall::{IoVec, IoVecs}, 12*cde5492fSlogin }, 13*cde5492fSlogin include::bindings::bindings::{pt_regs, verify_area}, 14*cde5492fSlogin net::socket::{AddressFamily, SOL_SOCKET}, 15*cde5492fSlogin syscall::SystemError, 16*cde5492fSlogin }; 17*cde5492fSlogin 18*cde5492fSlogin use super::{ 19*cde5492fSlogin socket::{PosixSocketType, RawSocket, SocketInode, SocketOptions, TcpSocket, UdpSocket}, 20*cde5492fSlogin Endpoint, Protocol, ShutdownType, Socket, 21*cde5492fSlogin }; 22*cde5492fSlogin 23*cde5492fSlogin #[no_mangle] 24*cde5492fSlogin pub extern "C" fn sys_socket(regs: &pt_regs) -> u64 { 25*cde5492fSlogin let address_family = regs.r8 as usize; 26*cde5492fSlogin let socket_type = regs.r9 as usize; 27*cde5492fSlogin let protocol: usize = regs.r10 as usize; 28*cde5492fSlogin // kdebug!("sys_socket: address_family: {address_family}, socket_type: {socket_type}, protocol: {protocol}"); 29*cde5492fSlogin return do_socket(address_family, socket_type, protocol) 30*cde5492fSlogin .map(|x| x as u64) 31*cde5492fSlogin .unwrap_or_else(|e| e.to_posix_errno() as u64); 32*cde5492fSlogin } 33*cde5492fSlogin 34*cde5492fSlogin /// @brief sys_socket系统调用的实际执行函数 35*cde5492fSlogin /// 36*cde5492fSlogin /// @param address_family 地址族 37*cde5492fSlogin /// @param socket_type socket类型 38*cde5492fSlogin /// @param protocol 传输协议 39*cde5492fSlogin pub fn do_socket( 40*cde5492fSlogin address_family: usize, 41*cde5492fSlogin socket_type: usize, 42*cde5492fSlogin protocol: usize, 43*cde5492fSlogin ) -> Result<i64, SystemError> { 44*cde5492fSlogin let address_family = AddressFamily::try_from(address_family as u16)?; 45*cde5492fSlogin let socket_type = PosixSocketType::try_from((socket_type & 0xf) as u8)?; 46*cde5492fSlogin // kdebug!("do_socket: address_family: {address_family:?}, socket_type: {socket_type:?}, protocol: {protocol}"); 47*cde5492fSlogin // 根据地址族和socket类型创建socket 48*cde5492fSlogin let socket: Box<dyn Socket> = match address_family { 49*cde5492fSlogin AddressFamily::Unix | AddressFamily::INet => match socket_type { 50*cde5492fSlogin PosixSocketType::Stream => Box::new(TcpSocket::new(SocketOptions::default())), 51*cde5492fSlogin PosixSocketType::Datagram => Box::new(UdpSocket::new(SocketOptions::default())), 52*cde5492fSlogin PosixSocketType::Raw => Box::new(RawSocket::new( 53*cde5492fSlogin Protocol::from(protocol as u8), 54*cde5492fSlogin SocketOptions::default(), 55*cde5492fSlogin )), 56*cde5492fSlogin _ => { 57*cde5492fSlogin // kdebug!("do_socket: EINVAL"); 58*cde5492fSlogin return Err(SystemError::EINVAL); 59*cde5492fSlogin } 60*cde5492fSlogin }, 61*cde5492fSlogin _ => { 62*cde5492fSlogin // kdebug!("do_socket: EAFNOSUPPORT"); 63*cde5492fSlogin return Err(SystemError::EAFNOSUPPORT); 64*cde5492fSlogin } 65*cde5492fSlogin }; 66*cde5492fSlogin // kdebug!("do_socket: socket: {socket:?}"); 67*cde5492fSlogin let socketinode: Arc<SocketInode> = SocketInode::new(socket); 68*cde5492fSlogin let f = File::new(socketinode, FileMode::O_RDWR)?; 69*cde5492fSlogin // kdebug!("do_socket: f: {f:?}"); 70*cde5492fSlogin // 把socket添加到当前进程的文件描述符表中 71*cde5492fSlogin let fd = current_pcb().alloc_fd(f, None).map(|x| x as i64); 72*cde5492fSlogin // kdebug!("do_socket: fd: {fd:?}"); 73*cde5492fSlogin return fd; 74*cde5492fSlogin } 75*cde5492fSlogin 76*cde5492fSlogin #[no_mangle] 77*cde5492fSlogin pub extern "C" fn sys_setsockopt(regs: &pt_regs) -> u64 { 78*cde5492fSlogin let fd = regs.r8 as usize; 79*cde5492fSlogin let level = regs.r9 as usize; 80*cde5492fSlogin let optname = regs.r10 as usize; 81*cde5492fSlogin let optval = regs.r11 as usize; 82*cde5492fSlogin let optlen = regs.r12 as usize; 83*cde5492fSlogin return do_setsockopt(fd, level, optname, optval as *const u8, optlen) 84*cde5492fSlogin .map(|x| x as u64) 85*cde5492fSlogin .unwrap_or_else(|e| e.to_posix_errno() as u64); 86*cde5492fSlogin } 87*cde5492fSlogin 88*cde5492fSlogin /// @brief sys_setsockopt系统调用的实际执行函数 89*cde5492fSlogin /// 90*cde5492fSlogin /// @param fd 文件描述符 91*cde5492fSlogin /// @param level 选项级别 92*cde5492fSlogin /// @param optname 选项名称 93*cde5492fSlogin /// @param optval 选项值 94*cde5492fSlogin /// @param optlen optval缓冲区长度 95*cde5492fSlogin pub fn do_setsockopt( 96*cde5492fSlogin fd: usize, 97*cde5492fSlogin level: usize, 98*cde5492fSlogin optname: usize, 99*cde5492fSlogin optval: *const u8, 100*cde5492fSlogin optlen: usize, 101*cde5492fSlogin ) -> Result<i64, SystemError> { 102*cde5492fSlogin // 验证optval的地址是否合法 103*cde5492fSlogin if unsafe { verify_area(optval as u64, optlen as u64) } == false { 104*cde5492fSlogin // 地址空间超出了用户空间的范围,不合法 105*cde5492fSlogin return Err(SystemError::EFAULT); 106*cde5492fSlogin } 107*cde5492fSlogin 108*cde5492fSlogin let socket_inode: Arc<SocketInode> = current_pcb() 109*cde5492fSlogin .get_socket(fd as i32) 110*cde5492fSlogin .ok_or(SystemError::EBADF)?; 111*cde5492fSlogin let data: &[u8] = unsafe { core::slice::from_raw_parts(optval, optlen) }; 112*cde5492fSlogin // 获取内层的socket(真正的数据) 113*cde5492fSlogin let socket = socket_inode.inner(); 114*cde5492fSlogin return socket.setsockopt(level, optname, data).map(|_| 0); 115*cde5492fSlogin } 116*cde5492fSlogin 117*cde5492fSlogin #[no_mangle] 118*cde5492fSlogin pub extern "C" fn sys_getsockopt(regs: &pt_regs) -> u64 { 119*cde5492fSlogin let fd = regs.r8 as usize; 120*cde5492fSlogin let level = regs.r9 as usize; 121*cde5492fSlogin let optname = regs.r10 as usize; 122*cde5492fSlogin let optval = regs.r11 as usize; 123*cde5492fSlogin let optlen = regs.r12 as usize; 124*cde5492fSlogin return do_getsockopt(fd, level, optname, optval as *mut u8, optlen as *mut u32) 125*cde5492fSlogin .map(|x| x as u64) 126*cde5492fSlogin .unwrap_or_else(|e| e.to_posix_errno() as u64); 127*cde5492fSlogin } 128*cde5492fSlogin 129*cde5492fSlogin /// @brief sys_getsockopt系统调用的实际执行函数 130*cde5492fSlogin /// 131*cde5492fSlogin /// 参考:https://man7.org/linux/man-pages/man2/setsockopt.2.html 132*cde5492fSlogin /// 133*cde5492fSlogin /// @param fd 文件描述符 134*cde5492fSlogin /// @param level 选项级别 135*cde5492fSlogin /// @param optname 选项名称 136*cde5492fSlogin /// @param optval 返回的选项值 137*cde5492fSlogin /// @param optlen 返回的optval缓冲区长度 138*cde5492fSlogin pub fn do_getsockopt( 139*cde5492fSlogin fd: usize, 140*cde5492fSlogin level: usize, 141*cde5492fSlogin optname: usize, 142*cde5492fSlogin optval: *mut u8, 143*cde5492fSlogin optlen: *mut u32, 144*cde5492fSlogin ) -> Result<i64, SystemError> { 145*cde5492fSlogin // 验证optval的地址是否合法 146*cde5492fSlogin if unsafe { verify_area(optval as u64, core::mem::size_of::<u8>() as u64) } == false { 147*cde5492fSlogin // 地址空间超出了用户空间的范围,不合法 148*cde5492fSlogin return Err(SystemError::EFAULT); 149*cde5492fSlogin } 150*cde5492fSlogin 151*cde5492fSlogin // 验证optlen的地址是否合法 152*cde5492fSlogin if unsafe { verify_area(optlen as u64, core::mem::size_of::<u32>() as u64) } == false { 153*cde5492fSlogin // 地址空间超出了用户空间的范围,不合法 154*cde5492fSlogin return Err(SystemError::EFAULT); 155*cde5492fSlogin } 156*cde5492fSlogin 157*cde5492fSlogin // 获取socket 158*cde5492fSlogin let optval = optval as *mut u32; 159*cde5492fSlogin let binding: Arc<SocketInode> = current_pcb() 160*cde5492fSlogin .get_socket(fd as i32) 161*cde5492fSlogin .ok_or(SystemError::EBADF)?; 162*cde5492fSlogin let socket = binding.inner(); 163*cde5492fSlogin 164*cde5492fSlogin if level as u8 == SOL_SOCKET { 165*cde5492fSlogin let optname = 166*cde5492fSlogin PosixSocketOption::try_from(optname as i32).map_err(|_| SystemError::ENOPROTOOPT)?; 167*cde5492fSlogin match optname { 168*cde5492fSlogin PosixSocketOption::SO_SNDBUF => { 169*cde5492fSlogin // 返回发送缓冲区大小 170*cde5492fSlogin unsafe { 171*cde5492fSlogin *optval = socket.metadata()?.send_buf_size as u32; 172*cde5492fSlogin *optlen = core::mem::size_of::<u32>() as u32; 173*cde5492fSlogin } 174*cde5492fSlogin return Ok(0); 175*cde5492fSlogin } 176*cde5492fSlogin PosixSocketOption::SO_RCVBUF => { 177*cde5492fSlogin let optval = optval as *mut u32; 178*cde5492fSlogin // 返回默认的接收缓冲区大小 179*cde5492fSlogin unsafe { 180*cde5492fSlogin *optval = socket.metadata()?.recv_buf_size as u32; 181*cde5492fSlogin *optlen = core::mem::size_of::<u32>() as u32; 182*cde5492fSlogin } 183*cde5492fSlogin return Ok(0); 184*cde5492fSlogin } 185*cde5492fSlogin _ => { 186*cde5492fSlogin return Err(SystemError::ENOPROTOOPT); 187*cde5492fSlogin } 188*cde5492fSlogin } 189*cde5492fSlogin } 190*cde5492fSlogin drop(socket); 191*cde5492fSlogin 192*cde5492fSlogin // To manipulate options at any other level the 193*cde5492fSlogin // protocol number of the appropriate protocol controlling the 194*cde5492fSlogin // option is supplied. For example, to indicate that an option is 195*cde5492fSlogin // to be interpreted by the TCP protocol, level should be set to the 196*cde5492fSlogin // protocol number of TCP. 197*cde5492fSlogin 198*cde5492fSlogin let posix_protocol = 199*cde5492fSlogin PosixIpProtocol::try_from(level as u16).map_err(|_| SystemError::ENOPROTOOPT)?; 200*cde5492fSlogin if posix_protocol == PosixIpProtocol::TCP { 201*cde5492fSlogin let optname = PosixTcpSocketOptions::try_from(optname as i32) 202*cde5492fSlogin .map_err(|_| SystemError::ENOPROTOOPT)?; 203*cde5492fSlogin match optname { 204*cde5492fSlogin PosixTcpSocketOptions::Congestion => return Ok(0), 205*cde5492fSlogin _ => { 206*cde5492fSlogin return Err(SystemError::ENOPROTOOPT); 207*cde5492fSlogin } 208*cde5492fSlogin } 209*cde5492fSlogin } 210*cde5492fSlogin return Err(SystemError::ENOPROTOOPT); 211*cde5492fSlogin } 212*cde5492fSlogin 213*cde5492fSlogin #[no_mangle] 214*cde5492fSlogin pub extern "C" fn sys_connect(regs: &pt_regs) -> u64 { 215*cde5492fSlogin let fd = regs.r8 as usize; 216*cde5492fSlogin let addr = regs.r9 as usize; 217*cde5492fSlogin let addrlen = regs.r10 as usize; 218*cde5492fSlogin return do_connect(fd, addr as *const SockAddr, addrlen) 219*cde5492fSlogin .map(|x| x as u64) 220*cde5492fSlogin .unwrap_or_else(|e| e.to_posix_errno() as u64); 221*cde5492fSlogin } 222*cde5492fSlogin 223*cde5492fSlogin /// @brief sys_connect系统调用的实际执行函数 224*cde5492fSlogin /// 225*cde5492fSlogin /// @param fd 文件描述符 226*cde5492fSlogin /// @param addr SockAddr 227*cde5492fSlogin /// @param addrlen 地址长度 228*cde5492fSlogin /// 229*cde5492fSlogin /// @return 成功返回0,失败返回错误码 230*cde5492fSlogin pub fn do_connect(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<i64, SystemError> { 231*cde5492fSlogin let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?; 232*cde5492fSlogin let socket: Arc<SocketInode> = current_pcb() 233*cde5492fSlogin .get_socket(fd as i32) 234*cde5492fSlogin .ok_or(SystemError::EBADF)?; 235*cde5492fSlogin let mut socket = socket.inner(); 236*cde5492fSlogin // kdebug!("connect to {:?}...", endpoint); 237*cde5492fSlogin socket.connect(endpoint)?; 238*cde5492fSlogin return Ok(0); 239*cde5492fSlogin } 240*cde5492fSlogin 241*cde5492fSlogin #[no_mangle] 242*cde5492fSlogin pub extern "C" fn sys_bind(regs: &pt_regs) -> u64 { 243*cde5492fSlogin let fd = regs.r8 as usize; 244*cde5492fSlogin let addr = regs.r9 as usize; 245*cde5492fSlogin let addrlen = regs.r10 as usize; 246*cde5492fSlogin return do_bind(fd, addr as *const SockAddr, addrlen) 247*cde5492fSlogin .map(|x| x as u64) 248*cde5492fSlogin .unwrap_or_else(|e| e.to_posix_errno() as u64); 249*cde5492fSlogin } 250*cde5492fSlogin 251*cde5492fSlogin /// @brief sys_bind系统调用的实际执行函数 252*cde5492fSlogin /// 253*cde5492fSlogin /// @param fd 文件描述符 254*cde5492fSlogin /// @param addr SockAddr 255*cde5492fSlogin /// @param addrlen 地址长度 256*cde5492fSlogin /// 257*cde5492fSlogin /// @return 成功返回0,失败返回错误码 258*cde5492fSlogin pub fn do_bind(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<i64, SystemError> { 259*cde5492fSlogin let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?; 260*cde5492fSlogin let socket: Arc<SocketInode> = current_pcb() 261*cde5492fSlogin .get_socket(fd as i32) 262*cde5492fSlogin .ok_or(SystemError::EBADF)?; 263*cde5492fSlogin let mut socket = socket.inner(); 264*cde5492fSlogin socket.bind(endpoint)?; 265*cde5492fSlogin return Ok(0); 266*cde5492fSlogin } 267*cde5492fSlogin 268*cde5492fSlogin #[no_mangle] 269*cde5492fSlogin pub extern "C" fn sys_sendto(regs: &pt_regs) -> u64 { 270*cde5492fSlogin let fd = regs.r8 as usize; 271*cde5492fSlogin let buf = regs.r9 as usize; 272*cde5492fSlogin let len = regs.r10 as usize; 273*cde5492fSlogin let flags = regs.r11 as usize; 274*cde5492fSlogin let addr = regs.r12 as usize; 275*cde5492fSlogin let addrlen = regs.r13 as usize; 276*cde5492fSlogin return do_sendto( 277*cde5492fSlogin fd, 278*cde5492fSlogin buf as *const u8, 279*cde5492fSlogin len, 280*cde5492fSlogin flags, 281*cde5492fSlogin addr as *const SockAddr, 282*cde5492fSlogin addrlen, 283*cde5492fSlogin ) 284*cde5492fSlogin .map(|x| x as u64) 285*cde5492fSlogin .unwrap_or_else(|e| e.to_posix_errno() as u64); 286*cde5492fSlogin } 287*cde5492fSlogin 288*cde5492fSlogin /// @brief sys_sendto系统调用的实际执行函数 289*cde5492fSlogin /// 290*cde5492fSlogin /// @param fd 文件描述符 291*cde5492fSlogin /// @param buf 发送缓冲区 292*cde5492fSlogin /// @param len 发送缓冲区长度 293*cde5492fSlogin /// @param flags 标志 294*cde5492fSlogin /// @param addr SockAddr 295*cde5492fSlogin /// @param addrlen 地址长度 296*cde5492fSlogin /// 297*cde5492fSlogin /// @return 成功返回发送的字节数,失败返回错误码 298*cde5492fSlogin pub fn do_sendto( 299*cde5492fSlogin fd: usize, 300*cde5492fSlogin buf: *const u8, 301*cde5492fSlogin len: usize, 302*cde5492fSlogin _flags: usize, 303*cde5492fSlogin addr: *const SockAddr, 304*cde5492fSlogin addrlen: usize, 305*cde5492fSlogin ) -> Result<i64, SystemError> { 306*cde5492fSlogin if unsafe { verify_area(buf as usize as u64, len as u64) } == false { 307*cde5492fSlogin return Err(SystemError::EFAULT); 308*cde5492fSlogin } 309*cde5492fSlogin let buf = unsafe { core::slice::from_raw_parts(buf, len) }; 310*cde5492fSlogin let endpoint = if addr.is_null() { 311*cde5492fSlogin None 312*cde5492fSlogin } else { 313*cde5492fSlogin Some(SockAddr::to_endpoint(addr, addrlen)?) 314*cde5492fSlogin }; 315*cde5492fSlogin 316*cde5492fSlogin let socket: Arc<SocketInode> = current_pcb() 317*cde5492fSlogin .get_socket(fd as i32) 318*cde5492fSlogin .ok_or(SystemError::EBADF)?; 319*cde5492fSlogin let socket = socket.inner(); 320*cde5492fSlogin return socket.write(buf, endpoint).map(|n| n as i64); 321*cde5492fSlogin } 322*cde5492fSlogin 323*cde5492fSlogin #[no_mangle] 324*cde5492fSlogin pub extern "C" fn sys_recvfrom(regs: &pt_regs) -> u64 { 325*cde5492fSlogin let fd = regs.r8 as usize; 326*cde5492fSlogin let buf = regs.r9 as usize; 327*cde5492fSlogin let len = regs.r10 as usize; 328*cde5492fSlogin let flags = regs.r11 as usize; 329*cde5492fSlogin let addr = regs.r12 as usize; 330*cde5492fSlogin let addrlen = regs.r13 as usize; 331*cde5492fSlogin return do_recvfrom( 332*cde5492fSlogin fd, 333*cde5492fSlogin buf as *mut u8, 334*cde5492fSlogin len, 335*cde5492fSlogin flags, 336*cde5492fSlogin addr as *mut SockAddr, 337*cde5492fSlogin addrlen as *mut u32, 338*cde5492fSlogin ) 339*cde5492fSlogin .map(|x| x as u64) 340*cde5492fSlogin .unwrap_or_else(|e| e.to_posix_errno() as u64); 341*cde5492fSlogin } 342*cde5492fSlogin 343*cde5492fSlogin /// @brief sys_recvfrom系统调用的实际执行函数 344*cde5492fSlogin /// 345*cde5492fSlogin /// @param fd 文件描述符 346*cde5492fSlogin /// @param buf 接收缓冲区 347*cde5492fSlogin /// @param len 接收缓冲区长度 348*cde5492fSlogin /// @param flags 标志 349*cde5492fSlogin /// @param addr SockAddr 350*cde5492fSlogin /// @param addrlen 地址长度 351*cde5492fSlogin /// 352*cde5492fSlogin /// @return 成功返回接收的字节数,失败返回错误码 353*cde5492fSlogin pub fn do_recvfrom( 354*cde5492fSlogin fd: usize, 355*cde5492fSlogin buf: *mut u8, 356*cde5492fSlogin len: usize, 357*cde5492fSlogin _flags: usize, 358*cde5492fSlogin addr: *mut SockAddr, 359*cde5492fSlogin addrlen: *mut u32, 360*cde5492fSlogin ) -> Result<i64, SystemError> { 361*cde5492fSlogin if unsafe { verify_area(buf as usize as u64, len as u64) } == false { 362*cde5492fSlogin return Err(SystemError::EFAULT); 363*cde5492fSlogin } 364*cde5492fSlogin // kdebug!( 365*cde5492fSlogin // "do_recvfrom: fd: {}, buf: {:x}, len: {}, addr: {:x}, addrlen: {:x}", 366*cde5492fSlogin // fd, 367*cde5492fSlogin // buf as usize, 368*cde5492fSlogin // len, 369*cde5492fSlogin // addr as usize, 370*cde5492fSlogin // addrlen as usize 371*cde5492fSlogin // ); 372*cde5492fSlogin 373*cde5492fSlogin let buf = unsafe { core::slice::from_raw_parts_mut(buf, len) }; 374*cde5492fSlogin let socket: Arc<SocketInode> = current_pcb() 375*cde5492fSlogin .get_socket(fd as i32) 376*cde5492fSlogin .ok_or(SystemError::EBADF)?; 377*cde5492fSlogin let socket = socket.inner(); 378*cde5492fSlogin 379*cde5492fSlogin let (n, endpoint) = socket.read(buf); 380*cde5492fSlogin drop(socket); 381*cde5492fSlogin 382*cde5492fSlogin let n: usize = n?; 383*cde5492fSlogin 384*cde5492fSlogin // 如果有地址信息,将地址信息写入用户空间 385*cde5492fSlogin if !addr.is_null() { 386*cde5492fSlogin let sockaddr_in = SockAddr::from(endpoint); 387*cde5492fSlogin unsafe { 388*cde5492fSlogin sockaddr_in.write_to_user(addr, addrlen)?; 389*cde5492fSlogin } 390*cde5492fSlogin } 391*cde5492fSlogin return Ok(n as i64); 392*cde5492fSlogin } 393*cde5492fSlogin 394*cde5492fSlogin #[no_mangle] 395*cde5492fSlogin pub extern "C" fn sys_recvmsg(regs: &pt_regs) -> i64 { 396*cde5492fSlogin let fd = regs.r8 as usize; 397*cde5492fSlogin let msg = regs.r9 as usize; 398*cde5492fSlogin let flags = regs.r10 as usize; 399*cde5492fSlogin return do_recvmsg(fd, msg as *mut MsgHdr, flags) 400*cde5492fSlogin .map(|x| x as i64) 401*cde5492fSlogin .unwrap_or_else(|e| e.to_posix_errno() as i64); 402*cde5492fSlogin } 403*cde5492fSlogin 404*cde5492fSlogin /// @brief sys_recvmsg系统调用的实际执行函数 405*cde5492fSlogin /// 406*cde5492fSlogin /// @param fd 文件描述符 407*cde5492fSlogin /// @param msg MsgHdr 408*cde5492fSlogin /// @param flags 标志 409*cde5492fSlogin /// 410*cde5492fSlogin /// @return 成功返回接收的字节数,失败返回错误码 411*cde5492fSlogin pub fn do_recvmsg(fd: usize, msg: *mut MsgHdr, _flags: usize) -> Result<i64, SystemError> { 412*cde5492fSlogin // 检查指针是否合法 413*cde5492fSlogin if unsafe { verify_area(msg as usize as u64, core::mem::size_of::<MsgHdr>() as u64) } == false { 414*cde5492fSlogin return Err(SystemError::EFAULT); 415*cde5492fSlogin } 416*cde5492fSlogin let msg: &mut MsgHdr = unsafe { msg.as_mut() }.ok_or(SystemError::EFAULT)?; 417*cde5492fSlogin // 检查每个缓冲区地址是否合法,生成iovecs 418*cde5492fSlogin let mut iovs = unsafe { IoVecs::from_user(msg.msg_iov, msg.msg_iovlen, true)? }; 419*cde5492fSlogin 420*cde5492fSlogin let socket: Arc<SocketInode> = current_pcb() 421*cde5492fSlogin .get_socket(fd as i32) 422*cde5492fSlogin .ok_or(SystemError::EBADF)?; 423*cde5492fSlogin let socket = socket.inner(); 424*cde5492fSlogin 425*cde5492fSlogin let mut buf = iovs.new_buf(true); 426*cde5492fSlogin // 从socket中读取数据 427*cde5492fSlogin let (n, endpoint) = socket.read(&mut buf); 428*cde5492fSlogin drop(socket); 429*cde5492fSlogin 430*cde5492fSlogin let n: usize = n?; 431*cde5492fSlogin 432*cde5492fSlogin // 将数据写入用户空间的iovecs 433*cde5492fSlogin iovs.scatter(&buf[..n]); 434*cde5492fSlogin 435*cde5492fSlogin let sockaddr_in = SockAddr::from(endpoint); 436*cde5492fSlogin unsafe { 437*cde5492fSlogin sockaddr_in.write_to_user(msg.msg_name, &mut msg.msg_namelen)?; 438*cde5492fSlogin } 439*cde5492fSlogin return Ok(n as i64); 440*cde5492fSlogin } 441*cde5492fSlogin 442*cde5492fSlogin #[no_mangle] 443*cde5492fSlogin pub extern "C" fn sys_listen(regs: &pt_regs) -> i64 { 444*cde5492fSlogin let fd = regs.r8 as usize; 445*cde5492fSlogin let backlog = regs.r9 as usize; 446*cde5492fSlogin return do_listen(fd, backlog) 447*cde5492fSlogin .map(|x| x as i64) 448*cde5492fSlogin .unwrap_or_else(|e| e.to_posix_errno() as i64); 449*cde5492fSlogin } 450*cde5492fSlogin 451*cde5492fSlogin /// @brief sys_listen系统调用的实际执行函数 452*cde5492fSlogin /// 453*cde5492fSlogin /// @param fd 文件描述符 454*cde5492fSlogin /// @param backlog 最大连接数 455*cde5492fSlogin /// 456*cde5492fSlogin /// @return 成功返回0,失败返回错误码 457*cde5492fSlogin pub fn do_listen(fd: usize, backlog: usize) -> Result<i64, SystemError> { 458*cde5492fSlogin let socket: Arc<SocketInode> = current_pcb() 459*cde5492fSlogin .get_socket(fd as i32) 460*cde5492fSlogin .ok_or(SystemError::EBADF)?; 461*cde5492fSlogin let mut socket = socket.inner(); 462*cde5492fSlogin socket.listen(backlog)?; 463*cde5492fSlogin return Ok(0); 464*cde5492fSlogin } 465*cde5492fSlogin 466*cde5492fSlogin #[no_mangle] 467*cde5492fSlogin pub extern "C" fn sys_shutdown(regs: &pt_regs) -> u64 { 468*cde5492fSlogin let fd = regs.r8 as usize; 469*cde5492fSlogin let how = regs.r9 as usize; 470*cde5492fSlogin return do_shutdown(fd, how) 471*cde5492fSlogin .map(|x| x as u64) 472*cde5492fSlogin .unwrap_or_else(|e| e.to_posix_errno() as u64); 473*cde5492fSlogin } 474*cde5492fSlogin 475*cde5492fSlogin /// @brief sys_shutdown系统调用的实际执行函数 476*cde5492fSlogin /// 477*cde5492fSlogin /// @param fd 文件描述符 478*cde5492fSlogin /// @param how 关闭方式 479*cde5492fSlogin /// 480*cde5492fSlogin /// @return 成功返回0,失败返回错误码 481*cde5492fSlogin pub fn do_shutdown(fd: usize, how: usize) -> Result<i64, SystemError> { 482*cde5492fSlogin let socket: Arc<SocketInode> = current_pcb() 483*cde5492fSlogin .get_socket(fd as i32) 484*cde5492fSlogin .ok_or(SystemError::EBADF)?; 485*cde5492fSlogin let socket = socket.inner(); 486*cde5492fSlogin socket.shutdown(ShutdownType::try_from(how as i32)?)?; 487*cde5492fSlogin return Ok(0); 488*cde5492fSlogin } 489*cde5492fSlogin 490*cde5492fSlogin #[no_mangle] 491*cde5492fSlogin pub extern "C" fn sys_accept(regs: &pt_regs) -> u64 { 492*cde5492fSlogin let fd = regs.r8 as usize; 493*cde5492fSlogin let addr = regs.r9 as usize; 494*cde5492fSlogin let addrlen = regs.r10 as usize; 495*cde5492fSlogin return do_accept(fd, addr as *mut SockAddr, addrlen as *mut u32) 496*cde5492fSlogin .map(|x| x as u64) 497*cde5492fSlogin .unwrap_or_else(|e| e.to_posix_errno() as u64); 498*cde5492fSlogin } 499*cde5492fSlogin 500*cde5492fSlogin /// @brief sys_accept系统调用的实际执行函数 501*cde5492fSlogin /// 502*cde5492fSlogin /// @param fd 文件描述符 503*cde5492fSlogin /// @param addr SockAddr 504*cde5492fSlogin /// @param addrlen 地址长度 505*cde5492fSlogin /// 506*cde5492fSlogin /// @return 成功返回新的文件描述符,失败返回错误码 507*cde5492fSlogin pub fn do_accept(fd: usize, addr: *mut SockAddr, addrlen: *mut u32) -> Result<i64, SystemError> { 508*cde5492fSlogin let socket: Arc<SocketInode> = current_pcb() 509*cde5492fSlogin .get_socket(fd as i32) 510*cde5492fSlogin .ok_or(SystemError::EBADF)?; 511*cde5492fSlogin // kdebug!("accept: socket={:?}", socket); 512*cde5492fSlogin let mut socket = socket.inner(); 513*cde5492fSlogin // 从socket中接收连接 514*cde5492fSlogin let (new_socket, remote_endpoint) = socket.accept()?; 515*cde5492fSlogin drop(socket); 516*cde5492fSlogin 517*cde5492fSlogin // kdebug!("accept: new_socket={:?}", new_socket); 518*cde5492fSlogin // Insert the new socket into the file descriptor vector 519*cde5492fSlogin let new_socket: Arc<SocketInode> = SocketInode::new(new_socket); 520*cde5492fSlogin let new_fd = current_pcb().alloc_fd(File::new(new_socket, FileMode::O_RDWR)?, None)?; 521*cde5492fSlogin // kdebug!("accept: new_fd={}", new_fd); 522*cde5492fSlogin if !addr.is_null() { 523*cde5492fSlogin // kdebug!("accept: write remote_endpoint to user"); 524*cde5492fSlogin // 将对端地址写入用户空间 525*cde5492fSlogin let sockaddr_in = SockAddr::from(remote_endpoint); 526*cde5492fSlogin unsafe { 527*cde5492fSlogin sockaddr_in.write_to_user(addr, addrlen)?; 528*cde5492fSlogin } 529*cde5492fSlogin } 530*cde5492fSlogin return Ok(new_fd as i64); 531*cde5492fSlogin } 532*cde5492fSlogin 533*cde5492fSlogin #[no_mangle] 534*cde5492fSlogin pub extern "C" fn sys_getsockname(regs: &pt_regs) -> i64 { 535*cde5492fSlogin let fd = regs.r8 as usize; 536*cde5492fSlogin let addr = regs.r9 as usize; 537*cde5492fSlogin let addrlen = regs.r10 as usize; 538*cde5492fSlogin return do_getsockname(fd, addr as *mut SockAddr, addrlen as *mut u32) 539*cde5492fSlogin .map(|x| x as i64) 540*cde5492fSlogin .unwrap_or_else(|e| e.to_posix_errno() as i64); 541*cde5492fSlogin } 542*cde5492fSlogin 543*cde5492fSlogin /// @brief sys_getsockname系统调用的实际执行函数 544*cde5492fSlogin /// 545*cde5492fSlogin /// Returns the current address to which the socket 546*cde5492fSlogin /// sockfd is bound, in the buffer pointed to by addr. 547*cde5492fSlogin /// 548*cde5492fSlogin /// @param fd 文件描述符 549*cde5492fSlogin /// @param addr SockAddr 550*cde5492fSlogin /// @param addrlen 地址长度 551*cde5492fSlogin /// 552*cde5492fSlogin /// @return 成功返回0,失败返回错误码 553*cde5492fSlogin pub fn do_getsockname( 554*cde5492fSlogin fd: usize, 555*cde5492fSlogin addr: *mut SockAddr, 556*cde5492fSlogin addrlen: *mut u32, 557*cde5492fSlogin ) -> Result<i64, SystemError> { 558*cde5492fSlogin if addr.is_null() { 559*cde5492fSlogin return Err(SystemError::EINVAL); 560*cde5492fSlogin } 561*cde5492fSlogin let socket: Arc<SocketInode> = current_pcb() 562*cde5492fSlogin .get_socket(fd as i32) 563*cde5492fSlogin .ok_or(SystemError::EBADF)?; 564*cde5492fSlogin let socket = socket.inner(); 565*cde5492fSlogin let endpoint: Endpoint = socket.endpoint().ok_or(SystemError::EINVAL)?; 566*cde5492fSlogin drop(socket); 567*cde5492fSlogin 568*cde5492fSlogin let sockaddr_in = SockAddr::from(endpoint); 569*cde5492fSlogin unsafe { 570*cde5492fSlogin sockaddr_in.write_to_user(addr, addrlen)?; 571*cde5492fSlogin } 572*cde5492fSlogin return Ok(0); 573*cde5492fSlogin } 574*cde5492fSlogin 575*cde5492fSlogin #[no_mangle] 576*cde5492fSlogin pub extern "C" fn sys_getpeername(regs: &pt_regs) -> u64 { 577*cde5492fSlogin let fd = regs.r8 as usize; 578*cde5492fSlogin let addr = regs.r9 as usize; 579*cde5492fSlogin let addrlen = regs.r10 as usize; 580*cde5492fSlogin return do_getpeername(fd, addr as *mut SockAddr, addrlen as *mut u32) 581*cde5492fSlogin .map(|x| x as u64) 582*cde5492fSlogin .unwrap_or_else(|e| e.to_posix_errno() as u64); 583*cde5492fSlogin } 584*cde5492fSlogin 585*cde5492fSlogin /// @brief sys_getpeername系统调用的实际执行函数 586*cde5492fSlogin /// 587*cde5492fSlogin /// @param fd 文件描述符 588*cde5492fSlogin /// @param addr SockAddr 589*cde5492fSlogin /// @param addrlen 地址长度 590*cde5492fSlogin /// 591*cde5492fSlogin /// @return 成功返回0,失败返回错误码 592*cde5492fSlogin pub fn do_getpeername( 593*cde5492fSlogin fd: usize, 594*cde5492fSlogin addr: *mut SockAddr, 595*cde5492fSlogin addrlen: *mut u32, 596*cde5492fSlogin ) -> Result<i64, SystemError> { 597*cde5492fSlogin if addr.is_null() { 598*cde5492fSlogin return Err(SystemError::EINVAL); 599*cde5492fSlogin } 600*cde5492fSlogin 601*cde5492fSlogin let socket: Arc<SocketInode> = current_pcb() 602*cde5492fSlogin .get_socket(fd as i32) 603*cde5492fSlogin .ok_or(SystemError::EBADF)?; 604*cde5492fSlogin let socket = socket.inner(); 605*cde5492fSlogin let endpoint: Endpoint = socket.peer_endpoint().ok_or(SystemError::EINVAL)?; 606*cde5492fSlogin drop(socket); 607*cde5492fSlogin 608*cde5492fSlogin let sockaddr_in = SockAddr::from(endpoint); 609*cde5492fSlogin unsafe { 610*cde5492fSlogin sockaddr_in.write_to_user(addr, addrlen)?; 611*cde5492fSlogin } 612*cde5492fSlogin return Ok(0); 613*cde5492fSlogin } 614*cde5492fSlogin 615*cde5492fSlogin // 参考资料: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html#tag_13_32 616*cde5492fSlogin #[repr(C)] 617*cde5492fSlogin #[derive(Debug, Clone, Copy)] 618*cde5492fSlogin pub struct SockAddrIn { 619*cde5492fSlogin pub sin_family: u16, 620*cde5492fSlogin pub sin_port: u16, 621*cde5492fSlogin pub sin_addr: u32, 622*cde5492fSlogin pub sin_zero: [u8; 8], 623*cde5492fSlogin } 624*cde5492fSlogin 625*cde5492fSlogin #[repr(C)] 626*cde5492fSlogin #[derive(Debug, Clone, Copy)] 627*cde5492fSlogin pub struct SockAddrUn { 628*cde5492fSlogin pub sun_family: u16, 629*cde5492fSlogin pub sun_path: [u8; 108], 630*cde5492fSlogin } 631*cde5492fSlogin 632*cde5492fSlogin #[repr(C)] 633*cde5492fSlogin #[derive(Debug, Clone, Copy)] 634*cde5492fSlogin pub struct SockAddrLl { 635*cde5492fSlogin pub sll_family: u16, 636*cde5492fSlogin pub sll_protocol: u16, 637*cde5492fSlogin pub sll_ifindex: u32, 638*cde5492fSlogin pub sll_hatype: u16, 639*cde5492fSlogin pub sll_pkttype: u8, 640*cde5492fSlogin pub sll_halen: u8, 641*cde5492fSlogin pub sll_addr: [u8; 8], 642*cde5492fSlogin } 643*cde5492fSlogin 644*cde5492fSlogin #[repr(C)] 645*cde5492fSlogin #[derive(Debug, Clone, Copy)] 646*cde5492fSlogin pub struct SockAddrNl { 647*cde5492fSlogin nl_family: u16, 648*cde5492fSlogin nl_pad: u16, 649*cde5492fSlogin nl_pid: u32, 650*cde5492fSlogin nl_groups: u32, 651*cde5492fSlogin } 652*cde5492fSlogin 653*cde5492fSlogin #[repr(C)] 654*cde5492fSlogin #[derive(Debug, Clone, Copy)] 655*cde5492fSlogin pub struct SockAddrPlaceholder { 656*cde5492fSlogin pub family: u16, 657*cde5492fSlogin pub data: [u8; 14], 658*cde5492fSlogin } 659*cde5492fSlogin 660*cde5492fSlogin #[repr(C)] 661*cde5492fSlogin #[derive(Clone, Copy)] 662*cde5492fSlogin pub union SockAddr { 663*cde5492fSlogin pub family: u16, 664*cde5492fSlogin pub addr_in: SockAddrIn, 665*cde5492fSlogin pub addr_un: SockAddrUn, 666*cde5492fSlogin pub addr_ll: SockAddrLl, 667*cde5492fSlogin pub addr_nl: SockAddrNl, 668*cde5492fSlogin pub addr_ph: SockAddrPlaceholder, 669*cde5492fSlogin } 670*cde5492fSlogin 671*cde5492fSlogin impl SockAddr { 672*cde5492fSlogin /// @brief 把用户传入的SockAddr转换为Endpoint结构体 673*cde5492fSlogin pub fn to_endpoint(addr: *const SockAddr, len: usize) -> Result<Endpoint, SystemError> { 674*cde5492fSlogin if unsafe { 675*cde5492fSlogin verify_area( 676*cde5492fSlogin addr as usize as u64, 677*cde5492fSlogin core::mem::size_of::<SockAddr>() as u64, 678*cde5492fSlogin ) 679*cde5492fSlogin } == false 680*cde5492fSlogin { 681*cde5492fSlogin return Err(SystemError::EFAULT); 682*cde5492fSlogin } 683*cde5492fSlogin 684*cde5492fSlogin let addr = unsafe { addr.as_ref() }.ok_or(SystemError::EFAULT)?; 685*cde5492fSlogin if len < addr.len()? { 686*cde5492fSlogin return Err(SystemError::EINVAL); 687*cde5492fSlogin } 688*cde5492fSlogin unsafe { 689*cde5492fSlogin match AddressFamily::try_from(addr.family)? { 690*cde5492fSlogin AddressFamily::INet => { 691*cde5492fSlogin let addr_in: SockAddrIn = addr.addr_in; 692*cde5492fSlogin 693*cde5492fSlogin let ip: wire::IpAddress = wire::IpAddress::from(wire::Ipv4Address::from_bytes( 694*cde5492fSlogin &u32::from_be(addr_in.sin_addr).to_be_bytes()[..], 695*cde5492fSlogin )); 696*cde5492fSlogin let port = u16::from_be(addr_in.sin_port); 697*cde5492fSlogin 698*cde5492fSlogin return Ok(Endpoint::Ip(Some(wire::IpEndpoint::new(ip, port)))); 699*cde5492fSlogin } 700*cde5492fSlogin AddressFamily::Packet => { 701*cde5492fSlogin // TODO: support packet socket 702*cde5492fSlogin return Err(SystemError::EINVAL); 703*cde5492fSlogin } 704*cde5492fSlogin AddressFamily::Netlink => { 705*cde5492fSlogin // TODO: support netlink socket 706*cde5492fSlogin return Err(SystemError::EINVAL); 707*cde5492fSlogin } 708*cde5492fSlogin AddressFamily::Unix => { 709*cde5492fSlogin return Err(SystemError::EINVAL); 710*cde5492fSlogin } 711*cde5492fSlogin _ => { 712*cde5492fSlogin return Err(SystemError::EINVAL); 713*cde5492fSlogin } 714*cde5492fSlogin } 715*cde5492fSlogin } 716*cde5492fSlogin } 717*cde5492fSlogin 718*cde5492fSlogin /// @brief 获取地址长度 719*cde5492fSlogin pub fn len(&self) -> Result<usize, SystemError> { 720*cde5492fSlogin let ret = match AddressFamily::try_from(unsafe { self.family })? { 721*cde5492fSlogin AddressFamily::INet => Ok(core::mem::size_of::<SockAddrIn>()), 722*cde5492fSlogin AddressFamily::Packet => Ok(core::mem::size_of::<SockAddrLl>()), 723*cde5492fSlogin AddressFamily::Netlink => Ok(core::mem::size_of::<SockAddrNl>()), 724*cde5492fSlogin AddressFamily::Unix => Err(SystemError::EINVAL), 725*cde5492fSlogin _ => Err(SystemError::EINVAL), 726*cde5492fSlogin }; 727*cde5492fSlogin 728*cde5492fSlogin return ret; 729*cde5492fSlogin } 730*cde5492fSlogin 731*cde5492fSlogin /// @brief 把SockAddr的数据写入用户空间 732*cde5492fSlogin /// 733*cde5492fSlogin /// @param addr 用户空间的SockAddr的地址 734*cde5492fSlogin /// @param len 要写入的长度 735*cde5492fSlogin /// 736*cde5492fSlogin /// @return 成功返回写入的长度,失败返回错误码 737*cde5492fSlogin pub unsafe fn write_to_user( 738*cde5492fSlogin &self, 739*cde5492fSlogin addr: *mut SockAddr, 740*cde5492fSlogin addr_len: *mut u32, 741*cde5492fSlogin ) -> Result<usize, SystemError> { 742*cde5492fSlogin // 当用户传入的地址或者长度为空时,直接返回0 743*cde5492fSlogin if addr.is_null() || addr_len.is_null() { 744*cde5492fSlogin return Ok(0); 745*cde5492fSlogin } 746*cde5492fSlogin // 检查用户传入的地址是否合法 747*cde5492fSlogin if !verify_area( 748*cde5492fSlogin addr as usize as u64, 749*cde5492fSlogin core::mem::size_of::<SockAddr>() as u64, 750*cde5492fSlogin ) || !verify_area(addr_len as usize as u64, core::mem::size_of::<u32>() as u64) 751*cde5492fSlogin { 752*cde5492fSlogin return Err(SystemError::EFAULT); 753*cde5492fSlogin } 754*cde5492fSlogin 755*cde5492fSlogin let to_write = min(self.len()?, *addr_len as usize); 756*cde5492fSlogin if to_write > 0 { 757*cde5492fSlogin let buf = core::slice::from_raw_parts_mut(addr as *mut u8, to_write); 758*cde5492fSlogin buf.copy_from_slice(core::slice::from_raw_parts( 759*cde5492fSlogin self as *const SockAddr as *const u8, 760*cde5492fSlogin to_write, 761*cde5492fSlogin )); 762*cde5492fSlogin } 763*cde5492fSlogin *addr_len = self.len()? as u32; 764*cde5492fSlogin return Ok(to_write); 765*cde5492fSlogin } 766*cde5492fSlogin } 767*cde5492fSlogin 768*cde5492fSlogin impl From<Endpoint> for SockAddr { 769*cde5492fSlogin fn from(value: Endpoint) -> Self { 770*cde5492fSlogin match value { 771*cde5492fSlogin Endpoint::Ip(ip_endpoint) => { 772*cde5492fSlogin // 未指定地址 773*cde5492fSlogin if let None = ip_endpoint { 774*cde5492fSlogin return SockAddr { 775*cde5492fSlogin addr_ph: SockAddrPlaceholder { 776*cde5492fSlogin family: AddressFamily::Unspecified as u16, 777*cde5492fSlogin data: [0; 14], 778*cde5492fSlogin }, 779*cde5492fSlogin }; 780*cde5492fSlogin } 781*cde5492fSlogin // 指定了地址 782*cde5492fSlogin let ip_endpoint = ip_endpoint.unwrap(); 783*cde5492fSlogin match ip_endpoint.addr { 784*cde5492fSlogin wire::IpAddress::Ipv4(ipv4_addr) => { 785*cde5492fSlogin let addr_in = SockAddrIn { 786*cde5492fSlogin sin_family: AddressFamily::INet as u16, 787*cde5492fSlogin sin_port: ip_endpoint.port.to_be(), 788*cde5492fSlogin sin_addr: u32::from_be_bytes(ipv4_addr.0).to_be(), 789*cde5492fSlogin sin_zero: [0; 8], 790*cde5492fSlogin }; 791*cde5492fSlogin 792*cde5492fSlogin return SockAddr { addr_in }; 793*cde5492fSlogin } 794*cde5492fSlogin _ => { 795*cde5492fSlogin unimplemented!("not support ipv6"); 796*cde5492fSlogin } 797*cde5492fSlogin } 798*cde5492fSlogin } 799*cde5492fSlogin 800*cde5492fSlogin Endpoint::LinkLayer(link_endpoint) => { 801*cde5492fSlogin let addr_ll = SockAddrLl { 802*cde5492fSlogin sll_family: AddressFamily::Packet as u16, 803*cde5492fSlogin sll_protocol: 0, 804*cde5492fSlogin sll_ifindex: link_endpoint.interface as u32, 805*cde5492fSlogin sll_hatype: 0, 806*cde5492fSlogin sll_pkttype: 0, 807*cde5492fSlogin sll_halen: 0, 808*cde5492fSlogin sll_addr: [0; 8], 809*cde5492fSlogin }; 810*cde5492fSlogin 811*cde5492fSlogin return SockAddr { addr_ll }; 812*cde5492fSlogin } // _ => { 813*cde5492fSlogin // // todo: support other endpoint, like Netlink... 814*cde5492fSlogin // unimplemented!("not support {value:?}"); 815*cde5492fSlogin // } 816*cde5492fSlogin } 817*cde5492fSlogin } 818*cde5492fSlogin } 819*cde5492fSlogin 820*cde5492fSlogin #[repr(C)] 821*cde5492fSlogin #[derive(Debug, Clone, Copy)] 822*cde5492fSlogin pub struct MsgHdr { 823*cde5492fSlogin /// 指向一个SockAddr结构体的指针 824*cde5492fSlogin pub msg_name: *mut SockAddr, 825*cde5492fSlogin /// SockAddr结构体的大小 826*cde5492fSlogin pub msg_namelen: u32, 827*cde5492fSlogin /// scatter/gather array 828*cde5492fSlogin pub msg_iov: *mut IoVec, 829*cde5492fSlogin /// elements in msg_iov 830*cde5492fSlogin pub msg_iovlen: usize, 831*cde5492fSlogin /// 辅助数据 832*cde5492fSlogin pub msg_control: *mut u8, 833*cde5492fSlogin /// 辅助数据长度 834*cde5492fSlogin pub msg_controllen: usize, 835*cde5492fSlogin /// 接收到的消息的标志 836*cde5492fSlogin pub msg_flags: u32, 837*cde5492fSlogin } 838*cde5492fSlogin 839*cde5492fSlogin #[derive(Debug, Clone, Copy, FromPrimitive, ToPrimitive, PartialEq, Eq)] 840*cde5492fSlogin pub enum PosixIpProtocol { 841*cde5492fSlogin /// Dummy protocol for TCP. 842*cde5492fSlogin IP = 0, 843*cde5492fSlogin /// Internet Control Message Protocol. 844*cde5492fSlogin ICMP = 1, 845*cde5492fSlogin /// Internet Group Management Protocol. 846*cde5492fSlogin IGMP = 2, 847*cde5492fSlogin /// IPIP tunnels (older KA9Q tunnels use 94). 848*cde5492fSlogin IPIP = 4, 849*cde5492fSlogin /// Transmission Control Protocol. 850*cde5492fSlogin TCP = 6, 851*cde5492fSlogin /// Exterior Gateway Protocol. 852*cde5492fSlogin EGP = 8, 853*cde5492fSlogin /// PUP protocol. 854*cde5492fSlogin PUP = 12, 855*cde5492fSlogin /// User Datagram Protocol. 856*cde5492fSlogin UDP = 17, 857*cde5492fSlogin /// XNS IDP protocol. 858*cde5492fSlogin IDP = 22, 859*cde5492fSlogin /// SO Transport Protocol Class 4. 860*cde5492fSlogin TP = 29, 861*cde5492fSlogin /// Datagram Congestion Control Protocol. 862*cde5492fSlogin DCCP = 33, 863*cde5492fSlogin /// IPv6-in-IPv4 tunnelling. 864*cde5492fSlogin IPv6 = 41, 865*cde5492fSlogin /// RSVP Protocol. 866*cde5492fSlogin RSVP = 46, 867*cde5492fSlogin /// Generic Routing Encapsulation. (Cisco GRE) (rfc 1701, 1702) 868*cde5492fSlogin GRE = 47, 869*cde5492fSlogin /// Encapsulation Security Payload protocol 870*cde5492fSlogin ESP = 50, 871*cde5492fSlogin /// Authentication Header protocol 872*cde5492fSlogin AH = 51, 873*cde5492fSlogin /// Multicast Transport Protocol. 874*cde5492fSlogin MTP = 92, 875*cde5492fSlogin /// IP option pseudo header for BEET 876*cde5492fSlogin BEETPH = 94, 877*cde5492fSlogin /// Encapsulation Header. 878*cde5492fSlogin ENCAP = 98, 879*cde5492fSlogin /// Protocol Independent Multicast. 880*cde5492fSlogin PIM = 103, 881*cde5492fSlogin /// Compression Header Protocol. 882*cde5492fSlogin COMP = 108, 883*cde5492fSlogin /// Stream Control Transport Protocol 884*cde5492fSlogin SCTP = 132, 885*cde5492fSlogin /// UDP-Lite protocol (RFC 3828) 886*cde5492fSlogin UDPLITE = 136, 887*cde5492fSlogin /// MPLS in IP (RFC 4023) 888*cde5492fSlogin MPLSINIP = 137, 889*cde5492fSlogin /// Ethernet-within-IPv6 Encapsulation 890*cde5492fSlogin ETHERNET = 143, 891*cde5492fSlogin /// Raw IP packets 892*cde5492fSlogin RAW = 255, 893*cde5492fSlogin /// Multipath TCP connection 894*cde5492fSlogin MPTCP = 262, 895*cde5492fSlogin } 896*cde5492fSlogin 897*cde5492fSlogin impl TryFrom<u16> for PosixIpProtocol { 898*cde5492fSlogin type Error = SystemError; 899*cde5492fSlogin 900*cde5492fSlogin fn try_from(value: u16) -> Result<Self, Self::Error> { 901*cde5492fSlogin match <Self as FromPrimitive>::from_u16(value) { 902*cde5492fSlogin Some(p) => Ok(p), 903*cde5492fSlogin None => Err(SystemError::EPROTONOSUPPORT), 904*cde5492fSlogin } 905*cde5492fSlogin } 906*cde5492fSlogin } 907*cde5492fSlogin 908*cde5492fSlogin impl Into<u16> for PosixIpProtocol { 909*cde5492fSlogin fn into(self) -> u16 { 910*cde5492fSlogin <Self as ToPrimitive>::to_u16(&self).unwrap() 911*cde5492fSlogin } 912*cde5492fSlogin } 913*cde5492fSlogin 914*cde5492fSlogin #[allow(non_camel_case_types)] 915*cde5492fSlogin #[derive(Debug, Clone, Copy, FromPrimitive, ToPrimitive, PartialEq, Eq)] 916*cde5492fSlogin pub enum PosixSocketOption { 917*cde5492fSlogin SO_DEBUG = 1, 918*cde5492fSlogin SO_REUSEADDR = 2, 919*cde5492fSlogin SO_TYPE = 3, 920*cde5492fSlogin SO_ERROR = 4, 921*cde5492fSlogin SO_DONTROUTE = 5, 922*cde5492fSlogin SO_BROADCAST = 6, 923*cde5492fSlogin SO_SNDBUF = 7, 924*cde5492fSlogin SO_RCVBUF = 8, 925*cde5492fSlogin SO_SNDBUFFORCE = 32, 926*cde5492fSlogin SO_RCVBUFFORCE = 33, 927*cde5492fSlogin SO_KEEPALIVE = 9, 928*cde5492fSlogin SO_OOBINLINE = 10, 929*cde5492fSlogin SO_NO_CHECK = 11, 930*cde5492fSlogin SO_PRIORITY = 12, 931*cde5492fSlogin SO_LINGER = 13, 932*cde5492fSlogin SO_BSDCOMPAT = 14, 933*cde5492fSlogin SO_REUSEPORT = 15, 934*cde5492fSlogin SO_PASSCRED = 16, 935*cde5492fSlogin SO_PEERCRED = 17, 936*cde5492fSlogin SO_RCVLOWAT = 18, 937*cde5492fSlogin SO_SNDLOWAT = 19, 938*cde5492fSlogin SO_RCVTIMEO_OLD = 20, 939*cde5492fSlogin SO_SNDTIMEO_OLD = 21, 940*cde5492fSlogin 941*cde5492fSlogin SO_SECURITY_AUTHENTICATION = 22, 942*cde5492fSlogin SO_SECURITY_ENCRYPTION_TRANSPORT = 23, 943*cde5492fSlogin SO_SECURITY_ENCRYPTION_NETWORK = 24, 944*cde5492fSlogin 945*cde5492fSlogin SO_BINDTODEVICE = 25, 946*cde5492fSlogin 947*cde5492fSlogin /// 与SO_GET_FILTER相同 948*cde5492fSlogin SO_ATTACH_FILTER = 26, 949*cde5492fSlogin SO_DETACH_FILTER = 27, 950*cde5492fSlogin 951*cde5492fSlogin SO_PEERNAME = 28, 952*cde5492fSlogin 953*cde5492fSlogin SO_ACCEPTCONN = 30, 954*cde5492fSlogin 955*cde5492fSlogin SO_PEERSEC = 31, 956*cde5492fSlogin SO_PASSSEC = 34, 957*cde5492fSlogin 958*cde5492fSlogin SO_MARK = 36, 959*cde5492fSlogin 960*cde5492fSlogin SO_PROTOCOL = 38, 961*cde5492fSlogin SO_DOMAIN = 39, 962*cde5492fSlogin 963*cde5492fSlogin SO_RXQ_OVFL = 40, 964*cde5492fSlogin 965*cde5492fSlogin /// 与SCM_WIFI_STATUS相同 966*cde5492fSlogin SO_WIFI_STATUS = 41, 967*cde5492fSlogin SO_PEEK_OFF = 42, 968*cde5492fSlogin 969*cde5492fSlogin /* Instruct lower device to use last 4-bytes of skb data as FCS */ 970*cde5492fSlogin SO_NOFCS = 43, 971*cde5492fSlogin 972*cde5492fSlogin SO_LOCK_FILTER = 44, 973*cde5492fSlogin SO_SELECT_ERR_QUEUE = 45, 974*cde5492fSlogin SO_BUSY_POLL = 46, 975*cde5492fSlogin SO_MAX_PACING_RATE = 47, 976*cde5492fSlogin SO_BPF_EXTENSIONS = 48, 977*cde5492fSlogin SO_INCOMING_CPU = 49, 978*cde5492fSlogin SO_ATTACH_BPF = 50, 979*cde5492fSlogin // SO_DETACH_BPF = SO_DETACH_FILTER, 980*cde5492fSlogin SO_ATTACH_REUSEPORT_CBPF = 51, 981*cde5492fSlogin SO_ATTACH_REUSEPORT_EBPF = 52, 982*cde5492fSlogin 983*cde5492fSlogin SO_CNX_ADVICE = 53, 984*cde5492fSlogin SCM_TIMESTAMPING_OPT_STATS = 54, 985*cde5492fSlogin SO_MEMINFO = 55, 986*cde5492fSlogin SO_INCOMING_NAPI_ID = 56, 987*cde5492fSlogin SO_COOKIE = 57, 988*cde5492fSlogin SCM_TIMESTAMPING_PKTINFO = 58, 989*cde5492fSlogin SO_PEERGROUPS = 59, 990*cde5492fSlogin SO_ZEROCOPY = 60, 991*cde5492fSlogin /// 与SCM_TXTIME相同 992*cde5492fSlogin SO_TXTIME = 61, 993*cde5492fSlogin 994*cde5492fSlogin SO_BINDTOIFINDEX = 62, 995*cde5492fSlogin 996*cde5492fSlogin SO_TIMESTAMP_OLD = 29, 997*cde5492fSlogin SO_TIMESTAMPNS_OLD = 35, 998*cde5492fSlogin SO_TIMESTAMPING_OLD = 37, 999*cde5492fSlogin SO_TIMESTAMP_NEW = 63, 1000*cde5492fSlogin SO_TIMESTAMPNS_NEW = 64, 1001*cde5492fSlogin SO_TIMESTAMPING_NEW = 65, 1002*cde5492fSlogin 1003*cde5492fSlogin SO_RCVTIMEO_NEW = 66, 1004*cde5492fSlogin SO_SNDTIMEO_NEW = 67, 1005*cde5492fSlogin 1006*cde5492fSlogin SO_DETACH_REUSEPORT_BPF = 68, 1007*cde5492fSlogin 1008*cde5492fSlogin SO_PREFER_BUSY_POLL = 69, 1009*cde5492fSlogin SO_BUSY_POLL_BUDGET = 70, 1010*cde5492fSlogin 1011*cde5492fSlogin SO_NETNS_COOKIE = 71, 1012*cde5492fSlogin SO_BUF_LOCK = 72, 1013*cde5492fSlogin SO_RESERVE_MEM = 73, 1014*cde5492fSlogin SO_TXREHASH = 74, 1015*cde5492fSlogin SO_RCVMARK = 75, 1016*cde5492fSlogin } 1017*cde5492fSlogin 1018*cde5492fSlogin impl TryFrom<i32> for PosixSocketOption { 1019*cde5492fSlogin type Error = SystemError; 1020*cde5492fSlogin 1021*cde5492fSlogin fn try_from(value: i32) -> Result<Self, Self::Error> { 1022*cde5492fSlogin match <Self as FromPrimitive>::from_i32(value) { 1023*cde5492fSlogin Some(p) => Ok(p), 1024*cde5492fSlogin None => Err(SystemError::EINVAL), 1025*cde5492fSlogin } 1026*cde5492fSlogin } 1027*cde5492fSlogin } 1028*cde5492fSlogin 1029*cde5492fSlogin impl Into<i32> for PosixSocketOption { 1030*cde5492fSlogin fn into(self) -> i32 { 1031*cde5492fSlogin <Self as ToPrimitive>::to_i32(&self).unwrap() 1032*cde5492fSlogin } 1033*cde5492fSlogin } 1034*cde5492fSlogin 1035*cde5492fSlogin #[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)] 1036*cde5492fSlogin pub enum PosixTcpSocketOptions { 1037*cde5492fSlogin /// Turn off Nagle's algorithm. 1038*cde5492fSlogin NoDelay = 1, 1039*cde5492fSlogin /// Limit MSS. 1040*cde5492fSlogin MaxSegment = 2, 1041*cde5492fSlogin /// Never send partially complete segments. 1042*cde5492fSlogin Cork = 3, 1043*cde5492fSlogin /// Start keeplives after this period. 1044*cde5492fSlogin KeepIdle = 4, 1045*cde5492fSlogin /// Interval between keepalives. 1046*cde5492fSlogin KeepIntvl = 5, 1047*cde5492fSlogin /// Number of keepalives before death. 1048*cde5492fSlogin KeepCnt = 6, 1049*cde5492fSlogin /// Number of SYN retransmits. 1050*cde5492fSlogin Syncnt = 7, 1051*cde5492fSlogin /// Lifetime for orphaned FIN-WAIT-2 state. 1052*cde5492fSlogin Linger2 = 8, 1053*cde5492fSlogin /// Wake up listener only when data arrive. 1054*cde5492fSlogin DeferAccept = 9, 1055*cde5492fSlogin /// Bound advertised window 1056*cde5492fSlogin WindowClamp = 10, 1057*cde5492fSlogin /// Information about this connection. 1058*cde5492fSlogin Info = 11, 1059*cde5492fSlogin /// Block/reenable quick acks. 1060*cde5492fSlogin QuickAck = 12, 1061*cde5492fSlogin /// Congestion control algorithm. 1062*cde5492fSlogin Congestion = 13, 1063*cde5492fSlogin /// TCP MD5 Signature (RFC2385). 1064*cde5492fSlogin Md5Sig = 14, 1065*cde5492fSlogin /// Use linear timeouts for thin streams 1066*cde5492fSlogin ThinLinearTimeouts = 16, 1067*cde5492fSlogin /// Fast retrans. after 1 dupack. 1068*cde5492fSlogin ThinDupack = 17, 1069*cde5492fSlogin /// How long for loss retry before timeout. 1070*cde5492fSlogin UserTimeout = 18, 1071*cde5492fSlogin /// TCP sock is under repair right now. 1072*cde5492fSlogin Repair = 19, 1073*cde5492fSlogin RepairQueue = 20, 1074*cde5492fSlogin QueueSeq = 21, 1075*cde5492fSlogin RepairOptions = 22, 1076*cde5492fSlogin /// Enable FastOpen on listeners 1077*cde5492fSlogin FastOpen = 23, 1078*cde5492fSlogin Timestamp = 24, 1079*cde5492fSlogin /// Limit number of unsent bytes in write queue. 1080*cde5492fSlogin NotSentLowat = 25, 1081*cde5492fSlogin /// Get Congestion Control (optional) info. 1082*cde5492fSlogin CCInfo = 26, 1083*cde5492fSlogin /// Record SYN headers for new connections. 1084*cde5492fSlogin SaveSyn = 27, 1085*cde5492fSlogin /// Get SYN headers recorded for connection. 1086*cde5492fSlogin SavedSyn = 28, 1087*cde5492fSlogin /// Get/set window parameters. 1088*cde5492fSlogin RepairWindow = 29, 1089*cde5492fSlogin /// Attempt FastOpen with connect. 1090*cde5492fSlogin FastOpenConnect = 30, 1091*cde5492fSlogin /// Attach a ULP to a TCP connection. 1092*cde5492fSlogin ULP = 31, 1093*cde5492fSlogin /// TCP MD5 Signature with extensions. 1094*cde5492fSlogin Md5SigExt = 32, 1095*cde5492fSlogin /// Set the key for Fast Open(cookie). 1096*cde5492fSlogin FastOpenKey = 33, 1097*cde5492fSlogin /// Enable TFO without a TFO cookie. 1098*cde5492fSlogin FastOpenNoCookie = 34, 1099*cde5492fSlogin ZeroCopyReceive = 35, 1100*cde5492fSlogin /// Notify bytes available to read as a cmsg on read. 1101*cde5492fSlogin /// 与TCP_CM_INQ相同 1102*cde5492fSlogin INQ = 36, 1103*cde5492fSlogin /// delay outgoing packets by XX usec 1104*cde5492fSlogin TxDelay = 37, 1105*cde5492fSlogin } 1106*cde5492fSlogin 1107*cde5492fSlogin impl TryFrom<i32> for PosixTcpSocketOptions { 1108*cde5492fSlogin type Error = SystemError; 1109*cde5492fSlogin 1110*cde5492fSlogin fn try_from(value: i32) -> Result<Self, Self::Error> { 1111*cde5492fSlogin match <Self as FromPrimitive>::from_i32(value) { 1112*cde5492fSlogin Some(p) => Ok(p), 1113*cde5492fSlogin None => Err(SystemError::EINVAL), 1114*cde5492fSlogin } 1115*cde5492fSlogin } 1116*cde5492fSlogin } 1117*cde5492fSlogin 1118*cde5492fSlogin impl Into<i32> for PosixTcpSocketOptions { 1119*cde5492fSlogin fn into(self) -> i32 { 1120*cde5492fSlogin <Self as ToPrimitive>::to_i32(&self).unwrap() 1121*cde5492fSlogin } 1122*cde5492fSlogin } 1123