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