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