xref: /DragonOS/kernel/src/net/syscall.rs (revision cde5492f725681ed89abe1e6eb088e05d943d793)
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