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