xref: /DragonOS/kernel/src/net/syscall.rs (revision 09836e1b395fb56a0fe9534809e2cd3cd664dd3c)
16046f775S裕依 use core::{cmp::min, ffi::CStr};
2cde5492fSlogin 
3cde5492fSlogin use alloc::{boxed::Box, sync::Arc};
4cde5492fSlogin use num_traits::{FromPrimitive, ToPrimitive};
5cde5492fSlogin use smoltcp::wire;
691e9d4abSLoGin use system_error::SystemError;
7cde5492fSlogin 
8cde5492fSlogin use crate::{
9cde5492fSlogin     filesystem::vfs::{
10cde5492fSlogin         file::{File, FileMode},
11cde5492fSlogin         syscall::{IoVec, IoVecs},
126046f775S裕依         FileType,
13cde5492fSlogin     },
14ab5c8ca4Slogin     libs::spinlock::SpinLockGuard,
154fda81ceSLoGin     mm::{verify_area, VirtAddr},
16cde5492fSlogin     net::socket::{AddressFamily, SOL_SOCKET},
171496ba7bSLoGin     process::ProcessManager,
1891e9d4abSLoGin     syscall::Syscall,
19cde5492fSlogin };
20cde5492fSlogin 
21cde5492fSlogin use super::{
22d623e902SGnoCiYeH     socket::{new_socket, PosixSocketType, Socket, SocketInode},
234ad52e57S裕依2439     Endpoint, Protocol, ShutdownType,
24cde5492fSlogin };
25cde5492fSlogin 
26c47fe904SLoGin /// Flags for socket, socketpair, accept4
27c47fe904SLoGin const SOCK_CLOEXEC: FileMode = FileMode::O_CLOEXEC;
28c47fe904SLoGin const SOCK_NONBLOCK: FileMode = FileMode::O_NONBLOCK;
29c47fe904SLoGin 
30ab5c8ca4Slogin impl Syscall {
31cde5492fSlogin     /// @brief sys_socket系统调用的实际执行函数
32cde5492fSlogin     ///
33cde5492fSlogin     /// @param address_family 地址族
34cde5492fSlogin     /// @param socket_type socket类型
35cde5492fSlogin     /// @param protocol 传输协议
socket( address_family: usize, socket_type: usize, protocol: usize, ) -> Result<usize, SystemError>36ab5c8ca4Slogin     pub fn socket(
37cde5492fSlogin         address_family: usize,
38cde5492fSlogin         socket_type: usize,
39cde5492fSlogin         protocol: usize,
40ab5c8ca4Slogin     ) -> Result<usize, SystemError> {
41cde5492fSlogin         let address_family = AddressFamily::try_from(address_family as u16)?;
42cde5492fSlogin         let socket_type = PosixSocketType::try_from((socket_type & 0xf) as u8)?;
434ad52e57S裕依2439         let protocol = Protocol::from(protocol as u8);
444ad52e57S裕依2439 
454ad52e57S裕依2439         let socket = new_socket(address_family, socket_type, protocol)?;
464ad52e57S裕依2439 
47cde5492fSlogin         let socketinode: Arc<SocketInode> = SocketInode::new(socket);
48cde5492fSlogin         let f = File::new(socketinode, FileMode::O_RDWR)?;
49cde5492fSlogin         // 把socket添加到当前进程的文件描述符表中
501496ba7bSLoGin         let binding = ProcessManager::current_pcb().fd_table();
511496ba7bSLoGin         let mut fd_table_guard = binding.write();
521496ba7bSLoGin         let fd = fd_table_guard.alloc_fd(f, None).map(|x| x as usize);
531496ba7bSLoGin         drop(fd_table_guard);
54cde5492fSlogin         return fd;
55cde5492fSlogin     }
56cde5492fSlogin 
574ad52e57S裕依2439     /// # sys_socketpair系统调用的实际执行函数
584ad52e57S裕依2439     ///
594ad52e57S裕依2439     /// ## 参数
604ad52e57S裕依2439     /// - `address_family`: 地址族
614ad52e57S裕依2439     /// - `socket_type`: socket类型
624ad52e57S裕依2439     /// - `protocol`: 传输协议
634ad52e57S裕依2439     /// - `fds`: 用于返回文件描述符的数组
socketpair( address_family: usize, socket_type: usize, protocol: usize, fds: &mut [i32], ) -> Result<usize, SystemError>644ad52e57S裕依2439     pub fn socketpair(
654ad52e57S裕依2439         address_family: usize,
664ad52e57S裕依2439         socket_type: usize,
674ad52e57S裕依2439         protocol: usize,
684ad52e57S裕依2439         fds: &mut [i32],
694ad52e57S裕依2439     ) -> Result<usize, SystemError> {
704ad52e57S裕依2439         let address_family = AddressFamily::try_from(address_family as u16)?;
714ad52e57S裕依2439         let socket_type = PosixSocketType::try_from((socket_type & 0xf) as u8)?;
724ad52e57S裕依2439         let protocol = Protocol::from(protocol as u8);
734ad52e57S裕依2439 
744ad52e57S裕依2439         let binding = ProcessManager::current_pcb().fd_table();
754ad52e57S裕依2439         let mut fd_table_guard = binding.write();
764ad52e57S裕依2439 
776046f775S裕依         // 创建一对socket
786046f775S裕依         let inode0 = SocketInode::new(new_socket(address_family, socket_type, protocol)?);
796046f775S裕依         let inode1 = SocketInode::new(new_socket(address_family, socket_type, protocol)?);
804ad52e57S裕依2439 
816046f775S裕依         // 进行pair
826046f775S裕依         unsafe {
836046f775S裕依             inode0
846046f775S裕依                 .inner_no_preempt()
856046f775S裕依                 .connect(Endpoint::Inode(Some(inode1.clone())))?;
866046f775S裕依             inode1
876046f775S裕依                 .inner_no_preempt()
886046f775S裕依                 .connect(Endpoint::Inode(Some(inode0.clone())))?;
896046f775S裕依         }
906046f775S裕依 
916046f775S裕依         fds[0] = fd_table_guard.alloc_fd(File::new(inode0, FileMode::O_RDWR)?, None)?;
926046f775S裕依         fds[1] = fd_table_guard.alloc_fd(File::new(inode1, FileMode::O_RDWR)?, None)?;
934ad52e57S裕依2439 
944ad52e57S裕依2439         drop(fd_table_guard);
954ad52e57S裕依2439         Ok(0)
964ad52e57S裕依2439     }
974ad52e57S裕依2439 
98cde5492fSlogin     /// @brief sys_setsockopt系统调用的实际执行函数
99cde5492fSlogin     ///
100cde5492fSlogin     /// @param fd 文件描述符
101cde5492fSlogin     /// @param level 选项级别
102cde5492fSlogin     /// @param optname 选项名称
103cde5492fSlogin     /// @param optval 选项值
104cde5492fSlogin     /// @param optlen optval缓冲区长度
setsockopt( fd: usize, level: usize, optname: usize, optval: &[u8], ) -> Result<usize, SystemError>105ab5c8ca4Slogin     pub fn setsockopt(
106cde5492fSlogin         fd: usize,
107cde5492fSlogin         level: usize,
108cde5492fSlogin         optname: usize,
109ab5c8ca4Slogin         optval: &[u8],
110ab5c8ca4Slogin     ) -> Result<usize, SystemError> {
1111496ba7bSLoGin         let socket_inode: Arc<SocketInode> = ProcessManager::current_pcb()
112cde5492fSlogin             .get_socket(fd as i32)
113cde5492fSlogin             .ok_or(SystemError::EBADF)?;
114cde5492fSlogin         // 获取内层的socket(真正的数据)
115ab5c8ca4Slogin         let socket: SpinLockGuard<Box<dyn Socket>> = socket_inode.inner();
116ab5c8ca4Slogin         return socket.setsockopt(level, optname, optval).map(|_| 0);
117cde5492fSlogin     }
118cde5492fSlogin 
119cde5492fSlogin     /// @brief sys_getsockopt系统调用的实际执行函数
120cde5492fSlogin     ///
121cde5492fSlogin     /// 参考:https://man7.org/linux/man-pages/man2/setsockopt.2.html
122cde5492fSlogin     ///
123cde5492fSlogin     /// @param fd 文件描述符
124cde5492fSlogin     /// @param level 选项级别
125cde5492fSlogin     /// @param optname 选项名称
126cde5492fSlogin     /// @param optval 返回的选项值
127cde5492fSlogin     /// @param optlen 返回的optval缓冲区长度
getsockopt( fd: usize, level: usize, optname: usize, optval: *mut u8, optlen: *mut u32, ) -> Result<usize, SystemError>128ab5c8ca4Slogin     pub fn getsockopt(
129cde5492fSlogin         fd: usize,
130cde5492fSlogin         level: usize,
131cde5492fSlogin         optname: usize,
132cde5492fSlogin         optval: *mut u8,
133cde5492fSlogin         optlen: *mut u32,
134ab5c8ca4Slogin     ) -> Result<usize, SystemError> {
135cde5492fSlogin         // 获取socket
136cde5492fSlogin         let optval = optval as *mut u32;
1371496ba7bSLoGin         let binding: Arc<SocketInode> = ProcessManager::current_pcb()
138cde5492fSlogin             .get_socket(fd as i32)
139cde5492fSlogin             .ok_or(SystemError::EBADF)?;
140cde5492fSlogin         let socket = binding.inner();
141cde5492fSlogin 
142cde5492fSlogin         if level as u8 == SOL_SOCKET {
143ab5c8ca4Slogin             let optname = PosixSocketOption::try_from(optname as i32)
144ab5c8ca4Slogin                 .map_err(|_| SystemError::ENOPROTOOPT)?;
145cde5492fSlogin             match optname {
146cde5492fSlogin                 PosixSocketOption::SO_SNDBUF => {
147cde5492fSlogin                     // 返回发送缓冲区大小
148cde5492fSlogin                     unsafe {
1496046f775S裕依                         *optval = socket.metadata().tx_buf_size as u32;
150cde5492fSlogin                         *optlen = core::mem::size_of::<u32>() as u32;
151cde5492fSlogin                     }
152cde5492fSlogin                     return Ok(0);
153cde5492fSlogin                 }
154cde5492fSlogin                 PosixSocketOption::SO_RCVBUF => {
155cde5492fSlogin                     // 返回默认的接收缓冲区大小
156cde5492fSlogin                     unsafe {
1576046f775S裕依                         *optval = socket.metadata().rx_buf_size as u32;
158cde5492fSlogin                         *optlen = core::mem::size_of::<u32>() as u32;
159cde5492fSlogin                     }
160cde5492fSlogin                     return Ok(0);
161cde5492fSlogin                 }
162cde5492fSlogin                 _ => {
163cde5492fSlogin                     return Err(SystemError::ENOPROTOOPT);
164cde5492fSlogin                 }
165cde5492fSlogin             }
166cde5492fSlogin         }
167cde5492fSlogin         drop(socket);
168cde5492fSlogin 
169cde5492fSlogin         // To manipulate options at any other level the
170cde5492fSlogin         // protocol number of the appropriate protocol controlling the
171cde5492fSlogin         // option is supplied.  For example, to indicate that an option is
172cde5492fSlogin         // to be interpreted by the TCP protocol, level should be set to the
173cde5492fSlogin         // protocol number of TCP.
174cde5492fSlogin 
175cde5492fSlogin         let posix_protocol =
176cde5492fSlogin             PosixIpProtocol::try_from(level as u16).map_err(|_| SystemError::ENOPROTOOPT)?;
177cde5492fSlogin         if posix_protocol == PosixIpProtocol::TCP {
178cde5492fSlogin             let optname = PosixTcpSocketOptions::try_from(optname as i32)
179cde5492fSlogin                 .map_err(|_| SystemError::ENOPROTOOPT)?;
180cde5492fSlogin             match optname {
181cde5492fSlogin                 PosixTcpSocketOptions::Congestion => return Ok(0),
182cde5492fSlogin                 _ => {
183cde5492fSlogin                     return Err(SystemError::ENOPROTOOPT);
184cde5492fSlogin                 }
185cde5492fSlogin             }
186cde5492fSlogin         }
187cde5492fSlogin         return Err(SystemError::ENOPROTOOPT);
188cde5492fSlogin     }
189cde5492fSlogin 
190cde5492fSlogin     /// @brief sys_connect系统调用的实际执行函数
191cde5492fSlogin     ///
192cde5492fSlogin     /// @param fd 文件描述符
193cde5492fSlogin     /// @param addr SockAddr
194cde5492fSlogin     /// @param addrlen 地址长度
195cde5492fSlogin     ///
196cde5492fSlogin     /// @return 成功返回0,失败返回错误码
connect(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<usize, SystemError>197ab5c8ca4Slogin     pub fn connect(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<usize, SystemError> {
198cde5492fSlogin         let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?;
1991496ba7bSLoGin         let socket: Arc<SocketInode> = ProcessManager::current_pcb()
200cde5492fSlogin             .get_socket(fd as i32)
201cde5492fSlogin             .ok_or(SystemError::EBADF)?;
2022f6f547aSGnoCiYeH         let mut socket = unsafe { socket.inner_no_preempt() };
203cde5492fSlogin         socket.connect(endpoint)?;
2046046f775S裕依         Ok(0)
205cde5492fSlogin     }
206cde5492fSlogin 
207cde5492fSlogin     /// @brief sys_bind系统调用的实际执行函数
208cde5492fSlogin     ///
209cde5492fSlogin     /// @param fd 文件描述符
210cde5492fSlogin     /// @param addr SockAddr
211cde5492fSlogin     /// @param addrlen 地址长度
212cde5492fSlogin     ///
213cde5492fSlogin     /// @return 成功返回0,失败返回错误码
bind(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<usize, SystemError>214ab5c8ca4Slogin     pub fn bind(fd: usize, addr: *const SockAddr, addrlen: usize) -> Result<usize, SystemError> {
215cde5492fSlogin         let endpoint: Endpoint = SockAddr::to_endpoint(addr, addrlen)?;
2161496ba7bSLoGin         let socket: Arc<SocketInode> = ProcessManager::current_pcb()
217cde5492fSlogin             .get_socket(fd as i32)
218cde5492fSlogin             .ok_or(SystemError::EBADF)?;
2192f6f547aSGnoCiYeH         let mut socket = unsafe { socket.inner_no_preempt() };
220cde5492fSlogin         socket.bind(endpoint)?;
2216046f775S裕依         Ok(0)
222cde5492fSlogin     }
223cde5492fSlogin 
224cde5492fSlogin     /// @brief sys_sendto系统调用的实际执行函数
225cde5492fSlogin     ///
226cde5492fSlogin     /// @param fd 文件描述符
227cde5492fSlogin     /// @param buf 发送缓冲区
228cde5492fSlogin     /// @param flags 标志
229cde5492fSlogin     /// @param addr SockAddr
230cde5492fSlogin     /// @param addrlen 地址长度
231cde5492fSlogin     ///
232cde5492fSlogin     /// @return 成功返回发送的字节数,失败返回错误码
sendto( fd: usize, buf: &[u8], _flags: u32, addr: *const SockAddr, addrlen: usize, ) -> Result<usize, SystemError>233ab5c8ca4Slogin     pub fn sendto(
234cde5492fSlogin         fd: usize,
235ab5c8ca4Slogin         buf: &[u8],
236ab5c8ca4Slogin         _flags: u32,
237cde5492fSlogin         addr: *const SockAddr,
238cde5492fSlogin         addrlen: usize,
239ab5c8ca4Slogin     ) -> Result<usize, SystemError> {
240cde5492fSlogin         let endpoint = if addr.is_null() {
241cde5492fSlogin             None
242cde5492fSlogin         } else {
243cde5492fSlogin             Some(SockAddr::to_endpoint(addr, addrlen)?)
244cde5492fSlogin         };
245cde5492fSlogin 
2461496ba7bSLoGin         let socket: Arc<SocketInode> = ProcessManager::current_pcb()
247cde5492fSlogin             .get_socket(fd as i32)
248cde5492fSlogin             .ok_or(SystemError::EBADF)?;
2492f6f547aSGnoCiYeH         let socket = unsafe { socket.inner_no_preempt() };
250ab5c8ca4Slogin         return socket.write(buf, endpoint);
251cde5492fSlogin     }
252cde5492fSlogin 
253cde5492fSlogin     /// @brief sys_recvfrom系统调用的实际执行函数
254cde5492fSlogin     ///
255cde5492fSlogin     /// @param fd 文件描述符
256cde5492fSlogin     /// @param buf 接收缓冲区
257cde5492fSlogin     /// @param flags 标志
258cde5492fSlogin     /// @param addr SockAddr
259cde5492fSlogin     /// @param addrlen 地址长度
260cde5492fSlogin     ///
261cde5492fSlogin     /// @return 成功返回接收的字节数,失败返回错误码
recvfrom( fd: usize, buf: &mut [u8], _flags: u32, addr: *mut SockAddr, addrlen: *mut u32, ) -> Result<usize, SystemError>262ab5c8ca4Slogin     pub fn recvfrom(
263cde5492fSlogin         fd: usize,
264ab5c8ca4Slogin         buf: &mut [u8],
265ab5c8ca4Slogin         _flags: u32,
266cde5492fSlogin         addr: *mut SockAddr,
267cde5492fSlogin         addrlen: *mut u32,
268ab5c8ca4Slogin     ) -> Result<usize, SystemError> {
2691496ba7bSLoGin         let socket: Arc<SocketInode> = ProcessManager::current_pcb()
270cde5492fSlogin             .get_socket(fd as i32)
271cde5492fSlogin             .ok_or(SystemError::EBADF)?;
2726046f775S裕依         let socket = unsafe { socket.inner_no_preempt() };
273cde5492fSlogin 
274cde5492fSlogin         let (n, endpoint) = socket.read(buf);
275cde5492fSlogin         drop(socket);
276cde5492fSlogin 
277cde5492fSlogin         let n: usize = n?;
278cde5492fSlogin 
279cde5492fSlogin         // 如果有地址信息,将地址信息写入用户空间
280cde5492fSlogin         if !addr.is_null() {
281cde5492fSlogin             let sockaddr_in = SockAddr::from(endpoint);
282cde5492fSlogin             unsafe {
283cde5492fSlogin                 sockaddr_in.write_to_user(addr, addrlen)?;
284cde5492fSlogin             }
285cde5492fSlogin         }
286ab5c8ca4Slogin         return Ok(n);
287cde5492fSlogin     }
288cde5492fSlogin 
289cde5492fSlogin     /// @brief sys_recvmsg系统调用的实际执行函数
290cde5492fSlogin     ///
291cde5492fSlogin     /// @param fd 文件描述符
292cde5492fSlogin     /// @param msg MsgHdr
293ab5c8ca4Slogin     /// @param flags 标志,暂时未使用
294cde5492fSlogin     ///
295cde5492fSlogin     /// @return 成功返回接收的字节数,失败返回错误码
recvmsg(fd: usize, msg: &mut MsgHdr, _flags: u32) -> Result<usize, SystemError>296ab5c8ca4Slogin     pub fn recvmsg(fd: usize, msg: &mut MsgHdr, _flags: u32) -> Result<usize, SystemError> {
297cde5492fSlogin         // 检查每个缓冲区地址是否合法,生成iovecs
298cde5492fSlogin         let mut iovs = unsafe { IoVecs::from_user(msg.msg_iov, msg.msg_iovlen, true)? };
299cde5492fSlogin 
3001496ba7bSLoGin         let socket: Arc<SocketInode> = ProcessManager::current_pcb()
301cde5492fSlogin             .get_socket(fd as i32)
302cde5492fSlogin             .ok_or(SystemError::EBADF)?;
3036046f775S裕依         let socket = unsafe { socket.inner_no_preempt() };
304cde5492fSlogin 
305cde5492fSlogin         let mut buf = iovs.new_buf(true);
306cde5492fSlogin         // 从socket中读取数据
307cde5492fSlogin         let (n, endpoint) = socket.read(&mut buf);
308cde5492fSlogin         drop(socket);
309cde5492fSlogin 
310cde5492fSlogin         let n: usize = n?;
311cde5492fSlogin 
312cde5492fSlogin         // 将数据写入用户空间的iovecs
313cde5492fSlogin         iovs.scatter(&buf[..n]);
314cde5492fSlogin 
315cde5492fSlogin         let sockaddr_in = SockAddr::from(endpoint);
316cde5492fSlogin         unsafe {
317cde5492fSlogin             sockaddr_in.write_to_user(msg.msg_name, &mut msg.msg_namelen)?;
318cde5492fSlogin         }
319ab5c8ca4Slogin         return Ok(n);
320cde5492fSlogin     }
321cde5492fSlogin 
322cde5492fSlogin     /// @brief sys_listen系统调用的实际执行函数
323cde5492fSlogin     ///
324cde5492fSlogin     /// @param fd 文件描述符
325ab5c8ca4Slogin     /// @param backlog 队列最大连接数
326cde5492fSlogin     ///
327cde5492fSlogin     /// @return 成功返回0,失败返回错误码
listen(fd: usize, backlog: usize) -> Result<usize, SystemError>328ab5c8ca4Slogin     pub fn listen(fd: usize, backlog: usize) -> Result<usize, SystemError> {
3291496ba7bSLoGin         let socket: Arc<SocketInode> = ProcessManager::current_pcb()
330cde5492fSlogin             .get_socket(fd as i32)
331cde5492fSlogin             .ok_or(SystemError::EBADF)?;
3322f6f547aSGnoCiYeH         let mut socket = unsafe { socket.inner_no_preempt() };
333cde5492fSlogin         socket.listen(backlog)?;
334cde5492fSlogin         return Ok(0);
335cde5492fSlogin     }
336cde5492fSlogin 
337cde5492fSlogin     /// @brief sys_shutdown系统调用的实际执行函数
338cde5492fSlogin     ///
339cde5492fSlogin     /// @param fd 文件描述符
340cde5492fSlogin     /// @param how 关闭方式
341cde5492fSlogin     ///
342cde5492fSlogin     /// @return 成功返回0,失败返回错误码
shutdown(fd: usize, how: usize) -> Result<usize, SystemError>343ab5c8ca4Slogin     pub fn shutdown(fd: usize, how: usize) -> Result<usize, SystemError> {
3441496ba7bSLoGin         let socket: Arc<SocketInode> = ProcessManager::current_pcb()
345cde5492fSlogin             .get_socket(fd as i32)
346cde5492fSlogin             .ok_or(SystemError::EBADF)?;
34740609970SGnoCiYeH         let mut socket = unsafe { socket.inner_no_preempt() };
348*09836e1bSSamuel Dai         socket.shutdown(ShutdownType::from_bits_truncate((how + 1) as u8))?;
349cde5492fSlogin         return Ok(0);
350cde5492fSlogin     }
351cde5492fSlogin 
352cde5492fSlogin     /// @brief sys_accept系统调用的实际执行函数
353cde5492fSlogin     ///
354cde5492fSlogin     /// @param fd 文件描述符
355cde5492fSlogin     /// @param addr SockAddr
356cde5492fSlogin     /// @param addrlen 地址长度
357cde5492fSlogin     ///
358cde5492fSlogin     /// @return 成功返回新的文件描述符,失败返回错误码
accept(fd: usize, addr: *mut SockAddr, addrlen: *mut u32) -> Result<usize, SystemError>359ab5c8ca4Slogin     pub fn accept(fd: usize, addr: *mut SockAddr, addrlen: *mut u32) -> Result<usize, SystemError> {
360c47fe904SLoGin         return Self::do_accept(fd, addr, addrlen, 0);
361c47fe904SLoGin     }
362c47fe904SLoGin 
363c47fe904SLoGin     /// sys_accept4 - accept a connection on a socket
364c47fe904SLoGin     ///
365c47fe904SLoGin     ///
366c47fe904SLoGin     /// If flags is 0, then accept4() is the same as accept().  The
367c47fe904SLoGin     ///    following values can be bitwise ORed in flags to obtain different
368c47fe904SLoGin     ///    behavior:
369c47fe904SLoGin     ///
370c47fe904SLoGin     /// - SOCK_NONBLOCK
371c47fe904SLoGin     ///     Set the O_NONBLOCK file status flag on the open file
372c47fe904SLoGin     ///     description (see open(2)) referred to by the new file
373c47fe904SLoGin     ///     descriptor.  Using this flag saves extra calls to fcntl(2)
374c47fe904SLoGin     ///     to achieve the same result.
375c47fe904SLoGin     ///
376c47fe904SLoGin     /// - SOCK_CLOEXEC
377c47fe904SLoGin     ///     Set the close-on-exec (FD_CLOEXEC) flag on the new file
378c47fe904SLoGin     ///     descriptor.  See the description of the O_CLOEXEC flag in
379c47fe904SLoGin     ///     open(2) for reasons why this may be useful.
accept4( fd: usize, addr: *mut SockAddr, addrlen: *mut u32, mut flags: u32, ) -> Result<usize, SystemError>380c47fe904SLoGin     pub fn accept4(
381c47fe904SLoGin         fd: usize,
382c47fe904SLoGin         addr: *mut SockAddr,
383c47fe904SLoGin         addrlen: *mut u32,
384c47fe904SLoGin         mut flags: u32,
385c47fe904SLoGin     ) -> Result<usize, SystemError> {
386c47fe904SLoGin         // 如果flags不合法,返回错误
387c47fe904SLoGin         if (flags & (!(SOCK_CLOEXEC | SOCK_NONBLOCK)).bits()) != 0 {
388c47fe904SLoGin             return Err(SystemError::EINVAL);
389c47fe904SLoGin         }
390c47fe904SLoGin 
391c47fe904SLoGin         if SOCK_NONBLOCK != FileMode::O_NONBLOCK && ((flags & SOCK_NONBLOCK.bits()) != 0) {
3924ad52e57S裕依2439             flags = (flags & !FileMode::O_NONBLOCK.bits()) | FileMode::O_NONBLOCK.bits();
393c47fe904SLoGin         }
394c47fe904SLoGin 
395c47fe904SLoGin         return Self::do_accept(fd, addr, addrlen, flags);
396c47fe904SLoGin     }
397c47fe904SLoGin 
do_accept( fd: usize, addr: *mut SockAddr, addrlen: *mut u32, flags: u32, ) -> Result<usize, SystemError>398c47fe904SLoGin     fn do_accept(
399c47fe904SLoGin         fd: usize,
400c47fe904SLoGin         addr: *mut SockAddr,
401c47fe904SLoGin         addrlen: *mut u32,
402c47fe904SLoGin         flags: u32,
403c47fe904SLoGin     ) -> Result<usize, SystemError> {
4041496ba7bSLoGin         let socket: Arc<SocketInode> = ProcessManager::current_pcb()
405cde5492fSlogin             .get_socket(fd as i32)
406cde5492fSlogin             .ok_or(SystemError::EBADF)?;
4072eab6dd7S曾俊         // debug!("accept: socket={:?}", socket);
4082f6f547aSGnoCiYeH         let mut socket = unsafe { socket.inner_no_preempt() };
409cde5492fSlogin         // 从socket中接收连接
410cde5492fSlogin         let (new_socket, remote_endpoint) = socket.accept()?;
411cde5492fSlogin         drop(socket);
412cde5492fSlogin 
4132eab6dd7S曾俊         // debug!("accept: new_socket={:?}", new_socket);
414cde5492fSlogin         // Insert the new socket into the file descriptor vector
415cde5492fSlogin         let new_socket: Arc<SocketInode> = SocketInode::new(new_socket);
416c47fe904SLoGin 
417c47fe904SLoGin         let mut file_mode = FileMode::O_RDWR;
4184ad52e57S裕依2439         if flags & SOCK_NONBLOCK.bits() != 0 {
419c47fe904SLoGin             file_mode |= FileMode::O_NONBLOCK;
420c47fe904SLoGin         }
4214ad52e57S裕依2439         if flags & SOCK_CLOEXEC.bits() != 0 {
422c47fe904SLoGin             file_mode |= FileMode::O_CLOEXEC;
423c47fe904SLoGin         }
424c47fe904SLoGin 
4251496ba7bSLoGin         let new_fd = ProcessManager::current_pcb()
4261496ba7bSLoGin             .fd_table()
4271496ba7bSLoGin             .write()
428c47fe904SLoGin             .alloc_fd(File::new(new_socket, file_mode)?, None)?;
4292eab6dd7S曾俊         // debug!("accept: new_fd={}", new_fd);
430cde5492fSlogin         if !addr.is_null() {
4312eab6dd7S曾俊             // debug!("accept: write remote_endpoint to user");
432cde5492fSlogin             // 将对端地址写入用户空间
433cde5492fSlogin             let sockaddr_in = SockAddr::from(remote_endpoint);
434cde5492fSlogin             unsafe {
435cde5492fSlogin                 sockaddr_in.write_to_user(addr, addrlen)?;
436cde5492fSlogin             }
437cde5492fSlogin         }
438ab5c8ca4Slogin         return Ok(new_fd as usize);
439cde5492fSlogin     }
440cde5492fSlogin 
441cde5492fSlogin     /// @brief sys_getsockname系统调用的实际执行函数
442cde5492fSlogin     ///
443cde5492fSlogin     ///  Returns the current address to which the socket
444cde5492fSlogin     ///     sockfd is bound, in the buffer pointed to by addr.
445cde5492fSlogin     ///
446cde5492fSlogin     /// @param fd 文件描述符
447cde5492fSlogin     /// @param addr SockAddr
448cde5492fSlogin     /// @param addrlen 地址长度
449cde5492fSlogin     ///
450cde5492fSlogin     /// @return 成功返回0,失败返回错误码
getsockname( fd: usize, addr: *mut SockAddr, addrlen: *mut u32, ) -> Result<usize, SystemError>451ab5c8ca4Slogin     pub fn getsockname(
452cde5492fSlogin         fd: usize,
453cde5492fSlogin         addr: *mut SockAddr,
454cde5492fSlogin         addrlen: *mut u32,
455ab5c8ca4Slogin     ) -> Result<usize, SystemError> {
456cde5492fSlogin         if addr.is_null() {
457cde5492fSlogin             return Err(SystemError::EINVAL);
458cde5492fSlogin         }
4591496ba7bSLoGin         let socket: Arc<SocketInode> = ProcessManager::current_pcb()
460cde5492fSlogin             .get_socket(fd as i32)
461cde5492fSlogin             .ok_or(SystemError::EBADF)?;
462cde5492fSlogin         let socket = socket.inner();
463cde5492fSlogin         let endpoint: Endpoint = socket.endpoint().ok_or(SystemError::EINVAL)?;
464cde5492fSlogin         drop(socket);
465cde5492fSlogin 
466cde5492fSlogin         let sockaddr_in = SockAddr::from(endpoint);
467cde5492fSlogin         unsafe {
468cde5492fSlogin             sockaddr_in.write_to_user(addr, addrlen)?;
469cde5492fSlogin         }
470cde5492fSlogin         return Ok(0);
471cde5492fSlogin     }
472cde5492fSlogin 
473cde5492fSlogin     /// @brief sys_getpeername系统调用的实际执行函数
474cde5492fSlogin     ///
475cde5492fSlogin     /// @param fd 文件描述符
476cde5492fSlogin     /// @param addr SockAddr
477cde5492fSlogin     /// @param addrlen 地址长度
478cde5492fSlogin     ///
479cde5492fSlogin     /// @return 成功返回0,失败返回错误码
getpeername( fd: usize, addr: *mut SockAddr, addrlen: *mut u32, ) -> Result<usize, SystemError>480ab5c8ca4Slogin     pub fn getpeername(
481cde5492fSlogin         fd: usize,
482cde5492fSlogin         addr: *mut SockAddr,
483cde5492fSlogin         addrlen: *mut u32,
484ab5c8ca4Slogin     ) -> Result<usize, SystemError> {
485cde5492fSlogin         if addr.is_null() {
486cde5492fSlogin             return Err(SystemError::EINVAL);
487cde5492fSlogin         }
488cde5492fSlogin 
4891496ba7bSLoGin         let socket: Arc<SocketInode> = ProcessManager::current_pcb()
490cde5492fSlogin             .get_socket(fd as i32)
491cde5492fSlogin             .ok_or(SystemError::EBADF)?;
492cde5492fSlogin         let socket = socket.inner();
493cde5492fSlogin         let endpoint: Endpoint = socket.peer_endpoint().ok_or(SystemError::EINVAL)?;
494cde5492fSlogin         drop(socket);
495cde5492fSlogin 
496cde5492fSlogin         let sockaddr_in = SockAddr::from(endpoint);
497cde5492fSlogin         unsafe {
498cde5492fSlogin             sockaddr_in.write_to_user(addr, addrlen)?;
499cde5492fSlogin         }
500cde5492fSlogin         return Ok(0);
501cde5492fSlogin     }
502ab5c8ca4Slogin }
503cde5492fSlogin 
504cde5492fSlogin // 参考资料: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html#tag_13_32
505cde5492fSlogin #[repr(C)]
506cde5492fSlogin #[derive(Debug, Clone, Copy)]
507cde5492fSlogin pub struct SockAddrIn {
508cde5492fSlogin     pub sin_family: u16,
509cde5492fSlogin     pub sin_port: u16,
510cde5492fSlogin     pub sin_addr: u32,
511cde5492fSlogin     pub sin_zero: [u8; 8],
512cde5492fSlogin }
513cde5492fSlogin 
514cde5492fSlogin #[repr(C)]
515cde5492fSlogin #[derive(Debug, Clone, Copy)]
516cde5492fSlogin pub struct SockAddrUn {
517cde5492fSlogin     pub sun_family: u16,
518cde5492fSlogin     pub sun_path: [u8; 108],
519cde5492fSlogin }
520cde5492fSlogin 
521cde5492fSlogin #[repr(C)]
522cde5492fSlogin #[derive(Debug, Clone, Copy)]
523cde5492fSlogin pub struct SockAddrLl {
524cde5492fSlogin     pub sll_family: u16,
525cde5492fSlogin     pub sll_protocol: u16,
526cde5492fSlogin     pub sll_ifindex: u32,
527cde5492fSlogin     pub sll_hatype: u16,
528cde5492fSlogin     pub sll_pkttype: u8,
529cde5492fSlogin     pub sll_halen: u8,
530cde5492fSlogin     pub sll_addr: [u8; 8],
531cde5492fSlogin }
532cde5492fSlogin 
533cde5492fSlogin #[repr(C)]
534cde5492fSlogin #[derive(Debug, Clone, Copy)]
535cde5492fSlogin pub struct SockAddrNl {
536cde5492fSlogin     nl_family: u16,
537cde5492fSlogin     nl_pad: u16,
538cde5492fSlogin     nl_pid: u32,
539cde5492fSlogin     nl_groups: u32,
540cde5492fSlogin }
541cde5492fSlogin 
542cde5492fSlogin #[repr(C)]
543cde5492fSlogin #[derive(Debug, Clone, Copy)]
544cde5492fSlogin pub struct SockAddrPlaceholder {
545cde5492fSlogin     pub family: u16,
546cde5492fSlogin     pub data: [u8; 14],
547cde5492fSlogin }
548cde5492fSlogin 
549cde5492fSlogin #[repr(C)]
550cde5492fSlogin #[derive(Clone, Copy)]
551cde5492fSlogin pub union SockAddr {
552cde5492fSlogin     pub family: u16,
553cde5492fSlogin     pub addr_in: SockAddrIn,
554cde5492fSlogin     pub addr_un: SockAddrUn,
555cde5492fSlogin     pub addr_ll: SockAddrLl,
556cde5492fSlogin     pub addr_nl: SockAddrNl,
557cde5492fSlogin     pub addr_ph: SockAddrPlaceholder,
558cde5492fSlogin }
559cde5492fSlogin 
560cde5492fSlogin impl SockAddr {
561cde5492fSlogin     /// @brief 把用户传入的SockAddr转换为Endpoint结构体
to_endpoint(addr: *const SockAddr, len: usize) -> Result<Endpoint, SystemError>562cde5492fSlogin     pub fn to_endpoint(addr: *const SockAddr, len: usize) -> Result<Endpoint, SystemError> {
563cde5492fSlogin         verify_area(
5644fda81ceSLoGin             VirtAddr::new(addr as usize),
5654fda81ceSLoGin             core::mem::size_of::<SockAddr>(),
566cde5492fSlogin         )
5674fda81ceSLoGin         .map_err(|_| SystemError::EFAULT)?;
568cde5492fSlogin 
569cde5492fSlogin         let addr = unsafe { addr.as_ref() }.ok_or(SystemError::EFAULT)?;
570cde5492fSlogin         unsafe {
571cde5492fSlogin             match AddressFamily::try_from(addr.family)? {
572cde5492fSlogin                 AddressFamily::INet => {
5736046f775S裕依                     if len < addr.len()? {
5746046f775S裕依                         return Err(SystemError::EINVAL);
5756046f775S裕依                     }
5766046f775S裕依 
577cde5492fSlogin                     let addr_in: SockAddrIn = addr.addr_in;
578cde5492fSlogin 
579cde5492fSlogin                     let ip: wire::IpAddress = wire::IpAddress::from(wire::Ipv4Address::from_bytes(
580cde5492fSlogin                         &u32::from_be(addr_in.sin_addr).to_be_bytes()[..],
581cde5492fSlogin                     ));
582cde5492fSlogin                     let port = u16::from_be(addr_in.sin_port);
583cde5492fSlogin 
584cde5492fSlogin                     return Ok(Endpoint::Ip(Some(wire::IpEndpoint::new(ip, port))));
585cde5492fSlogin                 }
5866046f775S裕依                 AddressFamily::Unix => {
5876046f775S裕依                     let addr_un: SockAddrUn = addr.addr_un;
5886046f775S裕依 
5896046f775S裕依                     let path = CStr::from_bytes_until_nul(&addr_un.sun_path)
5906046f775S裕依                         .map_err(|_| SystemError::EINVAL)?
5916046f775S裕依                         .to_str()
5926046f775S裕依                         .map_err(|_| SystemError::EINVAL)?;
5936046f775S裕依 
5946046f775S裕依                     let fd = Syscall::open(path.as_ptr(), FileMode::O_RDWR.bits(), 0o755, true)?;
5956046f775S裕依 
5966046f775S裕依                     let binding = ProcessManager::current_pcb().fd_table();
5976046f775S裕依                     let fd_table_guard = binding.read();
5986046f775S裕依 
599dfe53cf0SGnoCiYeH                     let file = fd_table_guard.get_file_by_fd(fd as i32).unwrap();
6006046f775S裕依                     if file.file_type() != FileType::Socket {
6016046f775S裕依                         return Err(SystemError::ENOTSOCK);
6026046f775S裕依                     }
6036046f775S裕依                     let inode = file.inode();
6046046f775S裕依                     let socketinode = inode.as_any_ref().downcast_ref::<Arc<SocketInode>>();
6056046f775S裕依 
6066046f775S裕依                     return Ok(Endpoint::Inode(socketinode.cloned()));
6076046f775S裕依                 }
608cde5492fSlogin                 AddressFamily::Packet => {
609cde5492fSlogin                     // TODO: support packet socket
610cde5492fSlogin                     return Err(SystemError::EINVAL);
611cde5492fSlogin                 }
612cde5492fSlogin                 AddressFamily::Netlink => {
613cde5492fSlogin                     // TODO: support netlink socket
614cde5492fSlogin                     return Err(SystemError::EINVAL);
615cde5492fSlogin                 }
616cde5492fSlogin                 _ => {
617cde5492fSlogin                     return Err(SystemError::EINVAL);
618cde5492fSlogin                 }
619cde5492fSlogin             }
620cde5492fSlogin         }
621cde5492fSlogin     }
622cde5492fSlogin 
623cde5492fSlogin     /// @brief 获取地址长度
len(&self) -> Result<usize, SystemError>624cde5492fSlogin     pub fn len(&self) -> Result<usize, SystemError> {
625cde5492fSlogin         let ret = match AddressFamily::try_from(unsafe { self.family })? {
626cde5492fSlogin             AddressFamily::INet => Ok(core::mem::size_of::<SockAddrIn>()),
627cde5492fSlogin             AddressFamily::Packet => Ok(core::mem::size_of::<SockAddrLl>()),
628cde5492fSlogin             AddressFamily::Netlink => Ok(core::mem::size_of::<SockAddrNl>()),
629cde5492fSlogin             AddressFamily::Unix => Err(SystemError::EINVAL),
630cde5492fSlogin             _ => Err(SystemError::EINVAL),
631cde5492fSlogin         };
632cde5492fSlogin 
633cde5492fSlogin         return ret;
634cde5492fSlogin     }
635cde5492fSlogin 
636cde5492fSlogin     /// @brief 把SockAddr的数据写入用户空间
637cde5492fSlogin     ///
638cde5492fSlogin     /// @param addr 用户空间的SockAddr的地址
639cde5492fSlogin     /// @param len 要写入的长度
640cde5492fSlogin     ///
641cde5492fSlogin     /// @return 成功返回写入的长度,失败返回错误码
write_to_user( &self, addr: *mut SockAddr, addr_len: *mut u32, ) -> Result<usize, SystemError>642cde5492fSlogin     pub unsafe fn write_to_user(
643cde5492fSlogin         &self,
644cde5492fSlogin         addr: *mut SockAddr,
645cde5492fSlogin         addr_len: *mut u32,
646cde5492fSlogin     ) -> Result<usize, SystemError> {
647cde5492fSlogin         // 当用户传入的地址或者长度为空时,直接返回0
648cde5492fSlogin         if addr.is_null() || addr_len.is_null() {
649cde5492fSlogin             return Ok(0);
650cde5492fSlogin         }
6514fda81ceSLoGin 
652cde5492fSlogin         // 检查用户传入的地址是否合法
6534fda81ceSLoGin         verify_area(
6544fda81ceSLoGin             VirtAddr::new(addr as usize),
6554fda81ceSLoGin             core::mem::size_of::<SockAddr>(),
6564fda81ceSLoGin         )
6574fda81ceSLoGin         .map_err(|_| SystemError::EFAULT)?;
6584fda81ceSLoGin 
6594fda81ceSLoGin         verify_area(
6604fda81ceSLoGin             VirtAddr::new(addr_len as usize),
6614fda81ceSLoGin             core::mem::size_of::<u32>(),
6624fda81ceSLoGin         )
6634fda81ceSLoGin         .map_err(|_| SystemError::EFAULT)?;
664cde5492fSlogin 
665cde5492fSlogin         let to_write = min(self.len()?, *addr_len as usize);
666cde5492fSlogin         if to_write > 0 {
667cde5492fSlogin             let buf = core::slice::from_raw_parts_mut(addr as *mut u8, to_write);
668cde5492fSlogin             buf.copy_from_slice(core::slice::from_raw_parts(
669cde5492fSlogin                 self as *const SockAddr as *const u8,
670cde5492fSlogin                 to_write,
671cde5492fSlogin             ));
672cde5492fSlogin         }
673cde5492fSlogin         *addr_len = self.len()? as u32;
674cde5492fSlogin         return Ok(to_write);
675cde5492fSlogin     }
676cde5492fSlogin }
677cde5492fSlogin 
678cde5492fSlogin impl From<Endpoint> for SockAddr {
from(value: Endpoint) -> Self679cde5492fSlogin     fn from(value: Endpoint) -> Self {
680cde5492fSlogin         match value {
681cde5492fSlogin             Endpoint::Ip(ip_endpoint) => {
682cde5492fSlogin                 // 未指定地址
683b5b571e0SLoGin                 if ip_endpoint.is_none() {
684cde5492fSlogin                     return SockAddr {
685cde5492fSlogin                         addr_ph: SockAddrPlaceholder {
686cde5492fSlogin                             family: AddressFamily::Unspecified as u16,
687cde5492fSlogin                             data: [0; 14],
688cde5492fSlogin                         },
689cde5492fSlogin                     };
690cde5492fSlogin                 }
691cde5492fSlogin                 // 指定了地址
692cde5492fSlogin                 let ip_endpoint = ip_endpoint.unwrap();
693cde5492fSlogin                 match ip_endpoint.addr {
694cde5492fSlogin                     wire::IpAddress::Ipv4(ipv4_addr) => {
695cde5492fSlogin                         let addr_in = SockAddrIn {
696cde5492fSlogin                             sin_family: AddressFamily::INet as u16,
697cde5492fSlogin                             sin_port: ip_endpoint.port.to_be(),
698cde5492fSlogin                             sin_addr: u32::from_be_bytes(ipv4_addr.0).to_be(),
699cde5492fSlogin                             sin_zero: [0; 8],
700cde5492fSlogin                         };
701cde5492fSlogin 
702cde5492fSlogin                         return SockAddr { addr_in };
703cde5492fSlogin                     }
704cde5492fSlogin                     _ => {
705cde5492fSlogin                         unimplemented!("not support ipv6");
706cde5492fSlogin                     }
707cde5492fSlogin                 }
708cde5492fSlogin             }
709cde5492fSlogin 
710cde5492fSlogin             Endpoint::LinkLayer(link_endpoint) => {
711cde5492fSlogin                 let addr_ll = SockAddrLl {
712cde5492fSlogin                     sll_family: AddressFamily::Packet as u16,
713cde5492fSlogin                     sll_protocol: 0,
714cde5492fSlogin                     sll_ifindex: link_endpoint.interface as u32,
715cde5492fSlogin                     sll_hatype: 0,
716cde5492fSlogin                     sll_pkttype: 0,
717cde5492fSlogin                     sll_halen: 0,
718cde5492fSlogin                     sll_addr: [0; 8],
719cde5492fSlogin                 };
720cde5492fSlogin 
721cde5492fSlogin                 return SockAddr { addr_ll };
7224ad52e57S裕依2439             }
7236046f775S裕依 
7244ad52e57S裕依2439             _ => {
7254ad52e57S裕依2439                 // todo: support other endpoint, like Netlink...
7264ad52e57S裕依2439                 unimplemented!("not support {value:?}");
7274ad52e57S裕依2439             }
728cde5492fSlogin         }
729cde5492fSlogin     }
730cde5492fSlogin }
731cde5492fSlogin 
732cde5492fSlogin #[repr(C)]
733cde5492fSlogin #[derive(Debug, Clone, Copy)]
734cde5492fSlogin pub struct MsgHdr {
735cde5492fSlogin     /// 指向一个SockAddr结构体的指针
736cde5492fSlogin     pub msg_name: *mut SockAddr,
737cde5492fSlogin     /// SockAddr结构体的大小
738cde5492fSlogin     pub msg_namelen: u32,
739cde5492fSlogin     /// scatter/gather array
740cde5492fSlogin     pub msg_iov: *mut IoVec,
741cde5492fSlogin     /// elements in msg_iov
742cde5492fSlogin     pub msg_iovlen: usize,
743cde5492fSlogin     /// 辅助数据
744cde5492fSlogin     pub msg_control: *mut u8,
745cde5492fSlogin     /// 辅助数据长度
746cde5492fSlogin     pub msg_controllen: usize,
747cde5492fSlogin     /// 接收到的消息的标志
748cde5492fSlogin     pub msg_flags: u32,
749cde5492fSlogin }
750cde5492fSlogin 
751cde5492fSlogin #[derive(Debug, Clone, Copy, FromPrimitive, ToPrimitive, PartialEq, Eq)]
752cde5492fSlogin pub enum PosixIpProtocol {
753cde5492fSlogin     /// Dummy protocol for TCP.
754cde5492fSlogin     IP = 0,
755cde5492fSlogin     /// Internet Control Message Protocol.
756cde5492fSlogin     ICMP = 1,
757cde5492fSlogin     /// Internet Group Management Protocol.
758cde5492fSlogin     IGMP = 2,
759cde5492fSlogin     /// IPIP tunnels (older KA9Q tunnels use 94).
760cde5492fSlogin     IPIP = 4,
761cde5492fSlogin     /// Transmission Control Protocol.
762cde5492fSlogin     TCP = 6,
763cde5492fSlogin     /// Exterior Gateway Protocol.
764cde5492fSlogin     EGP = 8,
765cde5492fSlogin     /// PUP protocol.
766cde5492fSlogin     PUP = 12,
767cde5492fSlogin     /// User Datagram Protocol.
768cde5492fSlogin     UDP = 17,
769cde5492fSlogin     /// XNS IDP protocol.
770cde5492fSlogin     IDP = 22,
771cde5492fSlogin     /// SO Transport Protocol Class 4.
772cde5492fSlogin     TP = 29,
773cde5492fSlogin     /// Datagram Congestion Control Protocol.
774cde5492fSlogin     DCCP = 33,
775cde5492fSlogin     /// IPv6-in-IPv4 tunnelling.
776cde5492fSlogin     IPv6 = 41,
777cde5492fSlogin     /// RSVP Protocol.
778cde5492fSlogin     RSVP = 46,
779cde5492fSlogin     /// Generic Routing Encapsulation. (Cisco GRE) (rfc 1701, 1702)
780cde5492fSlogin     GRE = 47,
781cde5492fSlogin     /// Encapsulation Security Payload protocol
782cde5492fSlogin     ESP = 50,
783cde5492fSlogin     /// Authentication Header protocol
784cde5492fSlogin     AH = 51,
785cde5492fSlogin     /// Multicast Transport Protocol.
786cde5492fSlogin     MTP = 92,
787cde5492fSlogin     /// IP option pseudo header for BEET
788cde5492fSlogin     BEETPH = 94,
789cde5492fSlogin     /// Encapsulation Header.
790cde5492fSlogin     ENCAP = 98,
791cde5492fSlogin     /// Protocol Independent Multicast.
792cde5492fSlogin     PIM = 103,
793cde5492fSlogin     /// Compression Header Protocol.
794cde5492fSlogin     COMP = 108,
795cde5492fSlogin     /// Stream Control Transport Protocol
796cde5492fSlogin     SCTP = 132,
797cde5492fSlogin     /// UDP-Lite protocol (RFC 3828)
798cde5492fSlogin     UDPLITE = 136,
799cde5492fSlogin     /// MPLS in IP (RFC 4023)
800cde5492fSlogin     MPLSINIP = 137,
801cde5492fSlogin     /// Ethernet-within-IPv6 Encapsulation
802cde5492fSlogin     ETHERNET = 143,
803cde5492fSlogin     /// Raw IP packets
804cde5492fSlogin     RAW = 255,
805cde5492fSlogin     /// Multipath TCP connection
806cde5492fSlogin     MPTCP = 262,
807cde5492fSlogin }
808cde5492fSlogin 
809cde5492fSlogin impl TryFrom<u16> for PosixIpProtocol {
810cde5492fSlogin     type Error = SystemError;
811cde5492fSlogin 
try_from(value: u16) -> Result<Self, Self::Error>812cde5492fSlogin     fn try_from(value: u16) -> Result<Self, Self::Error> {
813cde5492fSlogin         match <Self as FromPrimitive>::from_u16(value) {
814cde5492fSlogin             Some(p) => Ok(p),
815cde5492fSlogin             None => Err(SystemError::EPROTONOSUPPORT),
816cde5492fSlogin         }
817cde5492fSlogin     }
818cde5492fSlogin }
819cde5492fSlogin 
820b5b571e0SLoGin impl From<PosixIpProtocol> for u16 {
from(value: PosixIpProtocol) -> Self821b5b571e0SLoGin     fn from(value: PosixIpProtocol) -> Self {
822b5b571e0SLoGin         <PosixIpProtocol as ToPrimitive>::to_u16(&value).unwrap()
823cde5492fSlogin     }
824cde5492fSlogin }
825cde5492fSlogin 
826cde5492fSlogin #[allow(non_camel_case_types)]
827cde5492fSlogin #[derive(Debug, Clone, Copy, FromPrimitive, ToPrimitive, PartialEq, Eq)]
828cde5492fSlogin pub enum PosixSocketOption {
829cde5492fSlogin     SO_DEBUG = 1,
830cde5492fSlogin     SO_REUSEADDR = 2,
831cde5492fSlogin     SO_TYPE = 3,
832cde5492fSlogin     SO_ERROR = 4,
833cde5492fSlogin     SO_DONTROUTE = 5,
834cde5492fSlogin     SO_BROADCAST = 6,
835cde5492fSlogin     SO_SNDBUF = 7,
836cde5492fSlogin     SO_RCVBUF = 8,
837cde5492fSlogin     SO_SNDBUFFORCE = 32,
838cde5492fSlogin     SO_RCVBUFFORCE = 33,
839cde5492fSlogin     SO_KEEPALIVE = 9,
840cde5492fSlogin     SO_OOBINLINE = 10,
841cde5492fSlogin     SO_NO_CHECK = 11,
842cde5492fSlogin     SO_PRIORITY = 12,
843cde5492fSlogin     SO_LINGER = 13,
844cde5492fSlogin     SO_BSDCOMPAT = 14,
845cde5492fSlogin     SO_REUSEPORT = 15,
846cde5492fSlogin     SO_PASSCRED = 16,
847cde5492fSlogin     SO_PEERCRED = 17,
848cde5492fSlogin     SO_RCVLOWAT = 18,
849cde5492fSlogin     SO_SNDLOWAT = 19,
850cde5492fSlogin     SO_RCVTIMEO_OLD = 20,
851cde5492fSlogin     SO_SNDTIMEO_OLD = 21,
852cde5492fSlogin 
853cde5492fSlogin     SO_SECURITY_AUTHENTICATION = 22,
854cde5492fSlogin     SO_SECURITY_ENCRYPTION_TRANSPORT = 23,
855cde5492fSlogin     SO_SECURITY_ENCRYPTION_NETWORK = 24,
856cde5492fSlogin 
857cde5492fSlogin     SO_BINDTODEVICE = 25,
858cde5492fSlogin 
859cde5492fSlogin     /// 与SO_GET_FILTER相同
860cde5492fSlogin     SO_ATTACH_FILTER = 26,
861cde5492fSlogin     SO_DETACH_FILTER = 27,
862cde5492fSlogin 
863cde5492fSlogin     SO_PEERNAME = 28,
864cde5492fSlogin 
865cde5492fSlogin     SO_ACCEPTCONN = 30,
866cde5492fSlogin 
867cde5492fSlogin     SO_PEERSEC = 31,
868cde5492fSlogin     SO_PASSSEC = 34,
869cde5492fSlogin 
870cde5492fSlogin     SO_MARK = 36,
871cde5492fSlogin 
872cde5492fSlogin     SO_PROTOCOL = 38,
873cde5492fSlogin     SO_DOMAIN = 39,
874cde5492fSlogin 
875cde5492fSlogin     SO_RXQ_OVFL = 40,
876cde5492fSlogin 
877cde5492fSlogin     /// 与SCM_WIFI_STATUS相同
878cde5492fSlogin     SO_WIFI_STATUS = 41,
879cde5492fSlogin     SO_PEEK_OFF = 42,
880cde5492fSlogin 
881cde5492fSlogin     /* Instruct lower device to use last 4-bytes of skb data as FCS */
882cde5492fSlogin     SO_NOFCS = 43,
883cde5492fSlogin 
884cde5492fSlogin     SO_LOCK_FILTER = 44,
885cde5492fSlogin     SO_SELECT_ERR_QUEUE = 45,
886cde5492fSlogin     SO_BUSY_POLL = 46,
887cde5492fSlogin     SO_MAX_PACING_RATE = 47,
888cde5492fSlogin     SO_BPF_EXTENSIONS = 48,
889cde5492fSlogin     SO_INCOMING_CPU = 49,
890cde5492fSlogin     SO_ATTACH_BPF = 50,
891cde5492fSlogin     // SO_DETACH_BPF = SO_DETACH_FILTER,
892cde5492fSlogin     SO_ATTACH_REUSEPORT_CBPF = 51,
893cde5492fSlogin     SO_ATTACH_REUSEPORT_EBPF = 52,
894cde5492fSlogin 
895cde5492fSlogin     SO_CNX_ADVICE = 53,
896cde5492fSlogin     SCM_TIMESTAMPING_OPT_STATS = 54,
897cde5492fSlogin     SO_MEMINFO = 55,
898cde5492fSlogin     SO_INCOMING_NAPI_ID = 56,
899cde5492fSlogin     SO_COOKIE = 57,
900cde5492fSlogin     SCM_TIMESTAMPING_PKTINFO = 58,
901cde5492fSlogin     SO_PEERGROUPS = 59,
902cde5492fSlogin     SO_ZEROCOPY = 60,
903cde5492fSlogin     /// 与SCM_TXTIME相同
904cde5492fSlogin     SO_TXTIME = 61,
905cde5492fSlogin 
906cde5492fSlogin     SO_BINDTOIFINDEX = 62,
907cde5492fSlogin 
908cde5492fSlogin     SO_TIMESTAMP_OLD = 29,
909cde5492fSlogin     SO_TIMESTAMPNS_OLD = 35,
910cde5492fSlogin     SO_TIMESTAMPING_OLD = 37,
911cde5492fSlogin     SO_TIMESTAMP_NEW = 63,
912cde5492fSlogin     SO_TIMESTAMPNS_NEW = 64,
913cde5492fSlogin     SO_TIMESTAMPING_NEW = 65,
914cde5492fSlogin 
915cde5492fSlogin     SO_RCVTIMEO_NEW = 66,
916cde5492fSlogin     SO_SNDTIMEO_NEW = 67,
917cde5492fSlogin 
918cde5492fSlogin     SO_DETACH_REUSEPORT_BPF = 68,
919cde5492fSlogin 
920cde5492fSlogin     SO_PREFER_BUSY_POLL = 69,
921cde5492fSlogin     SO_BUSY_POLL_BUDGET = 70,
922cde5492fSlogin 
923cde5492fSlogin     SO_NETNS_COOKIE = 71,
924cde5492fSlogin     SO_BUF_LOCK = 72,
925cde5492fSlogin     SO_RESERVE_MEM = 73,
926cde5492fSlogin     SO_TXREHASH = 74,
927cde5492fSlogin     SO_RCVMARK = 75,
928cde5492fSlogin }
929cde5492fSlogin 
930cde5492fSlogin impl TryFrom<i32> for PosixSocketOption {
931cde5492fSlogin     type Error = SystemError;
932cde5492fSlogin 
try_from(value: i32) -> Result<Self, Self::Error>933cde5492fSlogin     fn try_from(value: i32) -> Result<Self, Self::Error> {
934cde5492fSlogin         match <Self as FromPrimitive>::from_i32(value) {
935cde5492fSlogin             Some(p) => Ok(p),
936cde5492fSlogin             None => Err(SystemError::EINVAL),
937cde5492fSlogin         }
938cde5492fSlogin     }
939cde5492fSlogin }
940cde5492fSlogin 
941b5b571e0SLoGin impl From<PosixSocketOption> for i32 {
from(value: PosixSocketOption) -> Self942b5b571e0SLoGin     fn from(value: PosixSocketOption) -> Self {
943b5b571e0SLoGin         <PosixSocketOption as ToPrimitive>::to_i32(&value).unwrap()
944cde5492fSlogin     }
945cde5492fSlogin }
946cde5492fSlogin 
947cde5492fSlogin #[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)]
948cde5492fSlogin pub enum PosixTcpSocketOptions {
949cde5492fSlogin     /// Turn off Nagle's algorithm.
950cde5492fSlogin     NoDelay = 1,
951cde5492fSlogin     /// Limit MSS.
952cde5492fSlogin     MaxSegment = 2,
953cde5492fSlogin     /// Never send partially complete segments.
954cde5492fSlogin     Cork = 3,
955cde5492fSlogin     /// Start keeplives after this period.
956cde5492fSlogin     KeepIdle = 4,
957cde5492fSlogin     /// Interval between keepalives.
958cde5492fSlogin     KeepIntvl = 5,
959cde5492fSlogin     /// Number of keepalives before death.
960cde5492fSlogin     KeepCnt = 6,
961cde5492fSlogin     /// Number of SYN retransmits.
962cde5492fSlogin     Syncnt = 7,
963cde5492fSlogin     /// Lifetime for orphaned FIN-WAIT-2 state.
964cde5492fSlogin     Linger2 = 8,
965cde5492fSlogin     /// Wake up listener only when data arrive.
966cde5492fSlogin     DeferAccept = 9,
967cde5492fSlogin     /// Bound advertised window
968cde5492fSlogin     WindowClamp = 10,
969cde5492fSlogin     /// Information about this connection.
970cde5492fSlogin     Info = 11,
971cde5492fSlogin     /// Block/reenable quick acks.
972cde5492fSlogin     QuickAck = 12,
973cde5492fSlogin     /// Congestion control algorithm.
974cde5492fSlogin     Congestion = 13,
975cde5492fSlogin     /// TCP MD5 Signature (RFC2385).
976cde5492fSlogin     Md5Sig = 14,
977cde5492fSlogin     /// Use linear timeouts for thin streams
978cde5492fSlogin     ThinLinearTimeouts = 16,
979cde5492fSlogin     /// Fast retrans. after 1 dupack.
980cde5492fSlogin     ThinDupack = 17,
981cde5492fSlogin     /// How long for loss retry before timeout.
982cde5492fSlogin     UserTimeout = 18,
983cde5492fSlogin     /// TCP sock is under repair right now.
984cde5492fSlogin     Repair = 19,
985cde5492fSlogin     RepairQueue = 20,
986cde5492fSlogin     QueueSeq = 21,
987cde5492fSlogin     RepairOptions = 22,
988cde5492fSlogin     /// Enable FastOpen on listeners
989cde5492fSlogin     FastOpen = 23,
990cde5492fSlogin     Timestamp = 24,
991cde5492fSlogin     /// Limit number of unsent bytes in write queue.
992cde5492fSlogin     NotSentLowat = 25,
993cde5492fSlogin     /// Get Congestion Control (optional) info.
994cde5492fSlogin     CCInfo = 26,
995cde5492fSlogin     /// Record SYN headers for new connections.
996cde5492fSlogin     SaveSyn = 27,
997cde5492fSlogin     /// Get SYN headers recorded for connection.
998cde5492fSlogin     SavedSyn = 28,
999cde5492fSlogin     /// Get/set window parameters.
1000cde5492fSlogin     RepairWindow = 29,
1001cde5492fSlogin     /// Attempt FastOpen with connect.
1002cde5492fSlogin     FastOpenConnect = 30,
1003cde5492fSlogin     /// Attach a ULP to a TCP connection.
1004cde5492fSlogin     ULP = 31,
1005cde5492fSlogin     /// TCP MD5 Signature with extensions.
1006cde5492fSlogin     Md5SigExt = 32,
1007cde5492fSlogin     /// Set the key for Fast Open(cookie).
1008cde5492fSlogin     FastOpenKey = 33,
1009cde5492fSlogin     /// Enable TFO without a TFO cookie.
1010cde5492fSlogin     FastOpenNoCookie = 34,
1011cde5492fSlogin     ZeroCopyReceive = 35,
1012cde5492fSlogin     /// Notify bytes available to read as a cmsg on read.
1013cde5492fSlogin     /// 与TCP_CM_INQ相同
1014cde5492fSlogin     INQ = 36,
1015cde5492fSlogin     /// delay outgoing packets by XX usec
1016cde5492fSlogin     TxDelay = 37,
1017cde5492fSlogin }
1018cde5492fSlogin 
1019cde5492fSlogin impl TryFrom<i32> for PosixTcpSocketOptions {
1020cde5492fSlogin     type Error = SystemError;
1021cde5492fSlogin 
try_from(value: i32) -> Result<Self, Self::Error>1022cde5492fSlogin     fn try_from(value: i32) -> Result<Self, Self::Error> {
1023cde5492fSlogin         match <Self as FromPrimitive>::from_i32(value) {
1024cde5492fSlogin             Some(p) => Ok(p),
1025cde5492fSlogin             None => Err(SystemError::EINVAL),
1026cde5492fSlogin         }
1027cde5492fSlogin     }
1028cde5492fSlogin }
1029cde5492fSlogin 
1030b5b571e0SLoGin impl From<PosixTcpSocketOptions> for i32 {
from(val: PosixTcpSocketOptions) -> Self1031b5b571e0SLoGin     fn from(val: PosixTcpSocketOptions) -> Self {
1032b5b571e0SLoGin         <PosixTcpSocketOptions as ToPrimitive>::to_i32(&val).unwrap()
1033cde5492fSlogin     }
1034cde5492fSlogin }
1035