os/kernel/syscall/
network.rs

1//! 网络相关的系统调用实现
2
3use core::ffi::{CStr, c_char};
4
5macro_rules! set_sockopt_bool {
6    ($optval:expr, $optlen:expr, $field:expr) => {
7        if $optlen >= 4 {
8            let val = *($optval as *const i32);
9            $field = val != 0;
10        }
11    };
12}
13
14macro_rules! set_sockopt_int {
15    ($optval:expr, $optlen:expr, $field:expr) => {
16        if $optlen >= 4 {
17            let val = *($optval as *const i32);
18            if val < 0 {
19                return -(EINVAL as isize);
20            }
21            $field = val as usize;
22        }
23    };
24}
25
26macro_rules! get_sockopt_bool {
27    ($optval:expr, $avail:expr, $field:expr, $written:expr) => {
28        if $avail >= 4 {
29            *($optval as *mut i32) = if $field { 1 } else { 0 };
30            $written = 4;
31        }
32    };
33}
34
35macro_rules! get_sockopt_int {
36    ($optval:expr, $avail:expr, $field:expr, $written:expr) => {
37        if $avail >= 4 {
38            *($optval as *mut i32) = $field as i32;
39            $written = 4;
40        }
41    };
42}
43
44use crate::{
45    arch::trap::SumGuard,
46    kernel::current_cpu,
47    net::{
48        config::NetworkConfigManager,
49        interface::NETWORK_INTERFACE_MANAGER,
50        socket::{
51            SOCKET_SET, SocketFile, SocketHandle, create_tcp_socket, create_udp_socket,
52            get_socket_handle, parse_sockaddr_in, register_socket_fd, unregister_socket_fd,
53            write_sockaddr_in,
54        },
55    },
56    println,
57};
58use alloc::sync::Arc;
59use smoltcp::socket::{tcp, udp};
60use smoltcp::wire::{IpAddress, IpEndpoint, Ipv4Address};
61
62/// 获取网络接口列表
63pub fn get_network_interfaces() -> isize {
64    0
65}
66
67/// 设置网络接口配置
68pub fn set_network_interface_config(
69    ifname: *const c_char,
70    ip: *const c_char,
71    gateway: *const c_char,
72    mask: *const c_char,
73) -> isize {
74    // 解析参数
75    unsafe {
76        let _guard = SumGuard::new();
77
78        let ifname_str = match get_c_str_safe(ifname) {
79            Some(s) => s,
80            None => {
81                return -1;
82            }
83        };
84
85        let ip_str = match get_c_str_safe(ip) {
86            Some(s) => s,
87            None => {
88                return -2;
89            }
90        };
91
92        let gateway_str = match get_c_str_safe(gateway) {
93            Some(s) => s,
94            None => {
95                return -3;
96            }
97        };
98
99        let mask_str = match get_c_str_safe(mask) {
100            Some(s) => s,
101            None => {
102                return -4;
103            }
104        };
105
106        // 设置网络配置
107        match NetworkConfigManager::set_interface_config(ifname_str, ip_str, gateway_str, mask_str)
108        {
109            Ok(_) => 0,
110            Err(e) => {
111                println!("Network config error: {:?}", e);
112                -5
113            }
114        }
115    }
116}
117
118/// 创建套接字
119pub fn socket(domain: i32, socket_type: i32, _protocol: i32) -> isize {
120    if domain != 2 {
121        return -97;
122    } // EAFNOSUPPORT
123
124    let handle = match socket_type {
125        1 => match create_tcp_socket() {
126            Ok(h) => h,
127            Err(_) => return -12, // ENOMEM
128        },
129        2 => match create_udp_socket() {
130            Ok(h) => h,
131            Err(_) => return -12, // ENOMEM
132        },
133        _ => return -94, // ESOCKTNOSUPPORT
134    };
135
136    let socket_file = Arc::new(SocketFile::new(handle));
137    let task = current_cpu().lock().current_task.as_ref().unwrap().clone();
138
139    let mut task_lock = task.lock();
140    match task_lock.fd_table.alloc(socket_file) {
141        Ok(fd) => {
142            register_socket_fd(task_lock.tid as usize, fd, handle);
143            fd as isize
144        }
145        Err(_) => -24, // EMFILE
146    }
147}
148
149/// 绑定套接字
150pub fn bind(sockfd: i32, addr: *const u8, addrlen: u32) -> isize {
151    let endpoint = unsafe {
152        let _guard = SumGuard::new();
153        let ep = parse_sockaddr_in(addr, addrlen);
154        match ep {
155            Ok(e) => e,
156            Err(_) => return -22, // EINVAL
157        }
158    };
159
160    let task = current_cpu().lock().current_task.as_ref().unwrap().clone();
161    let task_lock = task.lock();
162    let tid = task_lock.tid as usize;
163
164    let handle = match get_socket_handle(tid, sockfd as usize) {
165        Some(h) => h,
166        None => return -88, // ENOTSOCK
167    };
168
169    let file = match task_lock.fd_table.get(sockfd as usize) {
170        Ok(f) => f,
171        Err(_) => return -9, // EBADF
172    };
173    drop(task_lock);
174
175    // For TCP: just save the endpoint, listen() will call smoltcp's listen()
176    // For UDP: bind immediately
177    match handle {
178        SocketHandle::Tcp(_) => {
179            use crate::net::socket::set_socket_local_endpoint;
180            if set_socket_local_endpoint(&file, endpoint).is_err() {
181                return -22; // EINVAL
182            }
183        }
184        SocketHandle::Udp(h) => {
185            let mut sockets = SOCKET_SET.lock();
186            let socket = sockets.get_mut::<udp::Socket>(h);
187            if socket.bind(endpoint).is_err() {
188                return -98; // EADDRINUSE
189            }
190        }
191    }
192
193    0
194}
195
196/// 监听连接
197pub fn listen(sockfd: i32, backlog: i32) -> isize {
198    if backlog < 0 {
199        return -22; // EINVAL
200    }
201
202    let task = current_cpu().lock().current_task.as_ref().unwrap().clone();
203    let task_lock = task.lock();
204    let tid = task_lock.tid as usize;
205
206    let handle = match get_socket_handle(tid, sockfd as usize) {
207        Some(h) => h,
208        None => return -88, // ENOTSOCK
209    };
210
211    let file = match task_lock.fd_table.get(sockfd as usize) {
212        Ok(f) => f,
213        Err(_) => return -9, // EBADF
214    };
215    drop(task_lock);
216
217    match handle {
218        SocketHandle::Tcp(h) => {
219            use crate::net::socket::get_socket_local_endpoint;
220            let endpoint = match get_socket_local_endpoint(&file) {
221                Some(ep) => ep,
222                None => return -22, // EINVAL - must bind first
223            };
224
225            let mut sockets = SOCKET_SET.lock();
226            let socket = sockets.get_mut::<tcp::Socket>(h);
227            if socket.listen(endpoint).is_err() {
228                return -98; // EADDRINUSE
229            }
230            0
231        }
232        SocketHandle::Udp(_) => -95, // EOPNOTSUPP - UDP doesn't support listen
233    }
234}
235
236/// 接受连接
237pub fn accept(sockfd: i32, addr: *mut u8, addrlen: *mut u32) -> isize {
238    let task = current_cpu().lock().current_task.as_ref().unwrap().clone();
239    let tid = task.lock().tid;
240
241    let listen_handle = match get_socket_handle(tid as usize, sockfd as usize) {
242        Some(SocketHandle::Tcp(h)) => h,
243        Some(SocketHandle::Udp(_)) => return -95, // EOPNOTSUPP
244        None => return -88,                       // ENOTSOCK
245    };
246
247    let mut sockets = SOCKET_SET.lock();
248    let listen_socket = sockets.get_mut::<tcp::Socket>(listen_handle);
249
250    if !listen_socket.is_listening() {
251        return -22; // EINVAL - not in listening state
252    }
253
254    if !listen_socket.is_active() {
255        return -11; // EAGAIN - no pending connection
256    }
257
258    // Get remote endpoint and local endpoint
259    let remote_endpoint = match listen_socket.remote_endpoint() {
260        Some(ep) => ep,
261        None => return -11, // EAGAIN
262    };
263    let local_endpoint = listen_socket.local_endpoint().unwrap();
264
265    // Create new listening socket to replace the old one
266    let new_listen_handle = match create_tcp_socket() {
267        Ok(SocketHandle::Tcp(h)) => h,
268        _ => return -12, // ENOMEM
269    };
270
271    // Set new socket to listen on the same address
272    let new_listen_socket = sockets.get_mut::<tcp::Socket>(new_listen_handle);
273    if new_listen_socket.listen(local_endpoint).is_err() {
274        sockets.remove(new_listen_handle);
275        return -12; // ENOMEM or other error
276    }
277
278    // The old listen_handle is now the established connection
279    // Update the mapping to point to the new listening socket
280    use crate::net::socket::{update_socket_file_handle, update_socket_handle};
281    update_socket_handle(
282        tid as usize,
283        sockfd as usize,
284        SocketHandle::Tcp(new_listen_handle),
285    );
286
287    // Also update the SocketFile's internal handle
288    let file = match task.lock().fd_table.get(sockfd as usize) {
289        Ok(f) => f,
290        Err(_) => return -9, // EBADF
291    };
292    update_socket_file_handle(&file, SocketHandle::Tcp(new_listen_handle)).unwrap();
293
294    drop(sockets);
295
296    // Write address info if requested
297    if !addr.is_null() && !addrlen.is_null() {
298        let _guard = SumGuard::new();
299        unsafe {
300            let _ = write_sockaddr_in(addr, addrlen, remote_endpoint);
301        }
302    }
303
304    // Return the established connection as a new fd
305    let conn_handle = SocketHandle::Tcp(listen_handle);
306    let socket_file = Arc::new(SocketFile::new(conn_handle));
307    match task.lock().fd_table.alloc(socket_file) {
308        Ok(fd) => {
309            register_socket_fd(tid as usize, fd, conn_handle);
310            fd as isize
311        }
312        Err(_) => -24, // EMFILE
313    }
314}
315
316/// 连接到远程地址
317pub fn connect(sockfd: i32, addr: *const u8, addrlen: u32) -> isize {
318    let endpoint = unsafe {
319        let _guard = SumGuard::new();
320        let ep = parse_sockaddr_in(addr, addrlen);
321        match ep {
322            Ok(e) => e,
323            Err(_) => return -22, // EINVAL
324        }
325    };
326
327    let task = current_cpu().lock().current_task.as_ref().unwrap().clone();
328    let task_lock = task.lock();
329    let tid = task_lock.tid as usize;
330
331    let handle = match get_socket_handle(tid, sockfd as usize) {
332        Some(h) => h,
333        None => return -88, // ENOTSOCK
334    };
335
336    let file = match task_lock.fd_table.get(sockfd as usize) {
337        Ok(f) => f,
338        Err(_) => return -9, // EBADF
339    };
340    drop(task_lock);
341
342    use crate::net::socket::set_socket_remote_endpoint;
343    set_socket_remote_endpoint(&file, endpoint).unwrap();
344
345    let is_nonblock = file
346        .flags()
347        .contains(crate::uapi::fcntl::OpenFlags::O_NONBLOCK);
348
349    match handle {
350        SocketHandle::Tcp(h) => {
351            let sockets = SOCKET_SET.lock();
352            let socket = sockets.get::<tcp::Socket>(h);
353            if socket.is_open() {
354                return -106; // EISCONN
355            }
356            let local_endpoint = socket.local_endpoint().unwrap_or(IpEndpoint::new(
357                IpAddress::Ipv4(Ipv4Address::UNSPECIFIED),
358                0,
359            ));
360            drop(sockets);
361
362            use crate::net::socket::tcp_connect;
363            if let Err(_) = tcp_connect(h, endpoint, local_endpoint) {
364                return -22; // EINVAL or connection error
365            }
366
367            if is_nonblock {
368                return -115; // EINPROGRESS
369            }
370        }
371        SocketHandle::Udp(_) => {}
372    }
373
374    0
375}
376
377/// 发送数据
378pub fn send(sockfd: i32, buf: *const u8, len: usize, _flags: i32) -> isize {
379    let data = unsafe {
380        let _guard = SumGuard::new();
381        let slice = core::slice::from_raw_parts(buf, len);
382        slice
383    };
384
385    let task = current_cpu().lock().current_task.as_ref().unwrap().clone();
386    let file = match task.lock().fd_table.get(sockfd as usize) {
387        Ok(f) => f,
388        Err(_) => return -9,
389    };
390
391    match file.write(data) {
392        Ok(n) => n as isize,
393        Err(_) => -11, // EAGAIN
394    }
395}
396
397/// 接收数据
398pub fn recv(sockfd: i32, buf: *mut u8, len: usize, _flags: i32) -> isize {
399    let task = current_cpu().lock().current_task.as_ref().unwrap().clone();
400    let file = match task.lock().fd_table.get(sockfd as usize) {
401        Ok(f) => f,
402        Err(_) => return -9,
403    };
404
405    let data = unsafe {
406        let _guard = SumGuard::new();
407        let slice = core::slice::from_raw_parts_mut(buf, len);
408        slice
409    };
410
411    match file.read(data) {
412        Ok(n) => n as isize,
413        Err(_) => -11, // EAGAIN
414    }
415}
416
417/// 关闭套接字
418pub fn close_sock(sockfd: i32) -> isize {
419    let task = current_cpu().lock().current_task.as_ref().unwrap().clone();
420    let mut task_lock = task.lock();
421    let tid = task_lock.tid;
422
423    unregister_socket_fd(tid as usize, sockfd as usize);
424
425    match task_lock.fd_table.close(sockfd as usize) {
426        Ok(_) => 0,
427        Err(_) => -9,
428    }
429}
430
431/// 安全地获取C字符串
432unsafe fn get_c_str_safe(ptr: *const c_char) -> Option<&'static str> {
433    if ptr.is_null() {
434        return None;
435    }
436
437    match CStr::from_ptr(ptr).to_str() {
438        Ok(s) => Some(s),
439        Err(_) => None,
440    }
441}
442
443/// 获取网络接口统计信息
444fn get_interface_stats(ifname: *const c_char, stats: *mut u8, size: usize) -> isize {
445    // TODO: 实现统计信息获取
446    0 // 返回0表示成功
447}
448
449pub fn init_network_syscalls() {
450    println!("Network syscalls initialized");
451}
452
453/// 获取网络接口地址列表 (Linux标准系统调用)
454pub fn getifaddrs(ifap: *mut *mut u8) -> isize {
455    unsafe {
456        let _guard = SumGuard::new();
457
458        // 获取所有网络接口
459        let interfaces = NETWORK_INTERFACE_MANAGER.lock().get_interfaces().to_vec();
460
461        if interfaces.is_empty() {
462            return -1; // ENOENT
463        }
464
465        // 简化实现:返回成功,但不填充实际数据
466        // 在实际实现中,需要分配内存并填充ifaddrs结构
467        0 // 成功
468    }
469}
470
471// 释放获取网络接口列表分配的内存
472pub fn freeifaddrs(ifa: *mut u8) -> isize {
473    unsafe {
474        let _guard = SumGuard::new();
475
476        // 简化实现:不执行任何操作
477        // 在实际实现中,需要释放getifaddrs分配的内存
478
479        0
480    }
481}
482
483// 设置网络接口配置
484pub fn setsockopt(sockfd: i32, level: i32, optname: i32, optval: *const u8, optlen: u32) -> isize {
485    use crate::arch::trap::SumGuard;
486    use crate::kernel::current_cpu;
487    use crate::uapi::errno::{EBADF, EINVAL, ENOPROTOOPT, ENOTSOCK};
488    use crate::uapi::socket::*;
489
490    if sockfd < 0 || optval.is_null() {
491        return -(EINVAL as isize);
492    }
493
494    let task = current_cpu().lock().current_task.as_ref().unwrap().clone();
495    let file = match task.lock().fd_table.get(sockfd as usize) {
496        Ok(f) => f,
497        Err(_) => return -(EBADF as isize),
498    };
499
500    let socket_file = match file
501        .as_any()
502        .downcast_ref::<crate::net::socket::SocketFile>()
503    {
504        Some(sf) => sf,
505        None => return -(ENOTSOCK as isize),
506    };
507
508    let mut opts = socket_file.get_socket_options();
509
510    {
511        let _guard = SumGuard::new();
512        unsafe {
513            match level {
514                SOL_SOCKET => match optname {
515                    SO_REUSEADDR => set_sockopt_bool!(optval, optlen, opts.reuse_addr),
516                    SO_REUSEPORT => set_sockopt_bool!(optval, optlen, opts.reuse_port),
517                    SO_KEEPALIVE => set_sockopt_bool!(optval, optlen, opts.keepalive),
518                    SO_SNDBUF => set_sockopt_int!(optval, optlen, opts.send_buffer_size),
519                    SO_RCVBUF => set_sockopt_int!(optval, optlen, opts.recv_buffer_size),
520                    _ => return -(ENOPROTOOPT as isize),
521                },
522                IPPROTO_TCP => match optname {
523                    TCP_NODELAY => set_sockopt_bool!(optval, optlen, opts.tcp_nodelay),
524                    _ => return -(ENOPROTOOPT as isize),
525                },
526                _ => return -(ENOPROTOOPT as isize),
527            }
528        }
529    }
530
531    socket_file.set_socket_options(opts);
532    0
533}
534
535// 获取网络接口配置
536pub fn getsockopt(
537    sockfd: i32,
538    level: i32,
539    optname: i32,
540    optval: *mut u8,
541    optlen: *mut u32,
542) -> isize {
543    use crate::arch::trap::SumGuard;
544    use crate::kernel::current_cpu;
545    use crate::uapi::errno::{EBADF, EINVAL, ENOPROTOOPT, ENOTSOCK};
546    use crate::uapi::socket::*;
547
548    if sockfd < 0 || optval.is_null() || optlen.is_null() {
549        return -(EINVAL as isize);
550    }
551
552    let task = current_cpu().lock().current_task.as_ref().unwrap().clone();
553    let file = match task.lock().fd_table.get(sockfd as usize) {
554        Ok(f) => f,
555        Err(_) => return -(EBADF as isize),
556    };
557
558    let socket_file = match file
559        .as_any()
560        .downcast_ref::<crate::net::socket::SocketFile>()
561    {
562        Some(sf) => sf,
563        None => return -(ENOTSOCK as isize),
564    };
565
566    let opts = socket_file.get_socket_options();
567
568    {
569        let _guard = SumGuard::new();
570        unsafe {
571            let available_len = *optlen as usize;
572            let mut written_len = 0usize;
573
574            match level {
575                SOL_SOCKET => match optname {
576                    SO_REUSEADDR => {
577                        get_sockopt_bool!(optval, available_len, opts.reuse_addr, written_len)
578                    }
579                    SO_REUSEPORT => {
580                        get_sockopt_bool!(optval, available_len, opts.reuse_port, written_len)
581                    }
582                    SO_KEEPALIVE => {
583                        get_sockopt_bool!(optval, available_len, opts.keepalive, written_len)
584                    }
585                    SO_SNDBUF => {
586                        get_sockopt_int!(optval, available_len, opts.send_buffer_size, written_len)
587                    }
588                    SO_RCVBUF => {
589                        get_sockopt_int!(optval, available_len, opts.recv_buffer_size, written_len)
590                    }
591                    _ => return -(ENOPROTOOPT as isize),
592                },
593                IPPROTO_TCP => match optname {
594                    TCP_NODELAY => {
595                        get_sockopt_bool!(optval, available_len, opts.tcp_nodelay, written_len)
596                    }
597                    _ => return -(ENOPROTOOPT as isize),
598                },
599                _ => return -(ENOPROTOOPT as isize),
600            }
601
602            *optlen = written_len as u32;
603        }
604    }
605
606    0
607}
608
609// 接受连接(非阻塞)
610pub fn accept4(sockfd: i32, addr: *mut u8, addrlen: *mut u32, flags: i32) -> isize {
611    unsafe {
612        let _guard = SumGuard::new();
613
614        // TODO: 实现接受连接逻辑
615        // 检查套接字是否有效
616        if sockfd < 0 {
617            return -1; // EBADF
618        }
619
620        // 暂时返回一个虚拟的文件描述符
621        4
622    }
623}
624
625// 发送数据到指定地址
626pub fn sendto(
627    sockfd: i32,
628    buf: *const u8,
629    len: usize,
630    _flags: i32,
631    dest_addr: *const u8,
632    addrlen: u32,
633) -> isize {
634    // If dest_addr is null, behave like send()
635    if dest_addr.is_null() {
636        return send(sockfd, buf, len, 0);
637    }
638
639    let endpoint = unsafe {
640        let _guard = SumGuard::new();
641        let ep = parse_sockaddr_in(dest_addr, addrlen);
642        match ep {
643            Ok(e) => e,
644            Err(_) => return -22, // EINVAL
645        }
646    };
647
648    let data = unsafe {
649        let _guard = SumGuard::new();
650        let slice = core::slice::from_raw_parts(buf, len);
651        slice
652    };
653
654    let task = current_cpu().lock().current_task.as_ref().unwrap().clone();
655    let tid = task.lock().tid as usize;
656
657    let handle = match get_socket_handle(tid, sockfd as usize) {
658        Some(h) => h,
659        None => return -88, // ENOTSOCK
660    };
661
662    use crate::net::socket::socket_sendto;
663    match socket_sendto(handle, data, endpoint) {
664        Ok(n) => n as isize,
665        Err(e) => e.to_errno(),
666    }
667}
668
669// Linux 标准: ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
670pub fn recvfrom(
671    sockfd: i32,
672    buf: *mut u8,
673    len: usize,
674    _flags: i32,
675    src_addr: *mut u8,
676    addrlen: *mut u32,
677) -> isize {
678    let task = current_cpu().lock().current_task.as_ref().unwrap().clone();
679    let file = match task.lock().fd_table.get(sockfd as usize) {
680        Ok(f) => f,
681        Err(_) => return -9, // EBADF
682    };
683
684    let data = unsafe {
685        let _guard = SumGuard::new();
686        let slice = core::slice::from_raw_parts_mut(buf, len);
687        slice
688    };
689
690    match file.recvfrom(data) {
691        Ok((n, Some(addr_buf))) => {
692            if !src_addr.is_null() && !addrlen.is_null() {
693                unsafe {
694                    let _guard = SumGuard::new();
695                    let len = (*addrlen as usize).min(addr_buf.len());
696                    core::ptr::copy_nonoverlapping(addr_buf.as_ptr(), src_addr, len);
697                    *addrlen = len as u32;
698                }
699            }
700            n as isize
701        }
702        Ok((n, None)) => n as isize,
703        Err(_) => -11, // EAGAIN
704    }
705}
706
707// 关闭套接字
708pub fn shutdown(sockfd: i32, how: i32) -> isize {
709    const SHUT_RD: i32 = 0;
710    const SHUT_WR: i32 = 1;
711    const SHUT_RDWR: i32 = 2;
712
713    if how < 0 || how > 2 {
714        return -22; // EINVAL
715    }
716
717    let task = current_cpu().lock().current_task.as_ref().unwrap().clone();
718    let task_lock = task.lock();
719    let tid = task_lock.tid as usize;
720
721    let handle = match get_socket_handle(tid, sockfd as usize) {
722        Some(h) => h,
723        None => return -88, // ENOTSOCK
724    };
725
726    let file = match task_lock.fd_table.get(sockfd as usize) {
727        Ok(f) => f,
728        Err(_) => return -9, // EBADF
729    };
730    drop(task_lock);
731
732    use crate::net::socket::{socket_shutdown_read, socket_shutdown_write};
733
734    let should_close_tcp = match how {
735        SHUT_RD => {
736            socket_shutdown_read(&file);
737            false
738        }
739        SHUT_WR | SHUT_RDWR => {
740            if how == SHUT_RDWR {
741                socket_shutdown_read(&file);
742            }
743            socket_shutdown_write(&file);
744            true
745        }
746        _ => unreachable!(), // 这里是不可到达的到达即意味着有问题
747    };
748
749    if should_close_tcp {
750        if let SocketHandle::Tcp(h) = handle {
751            let mut sockets = SOCKET_SET.lock();
752            let socket = sockets.get_mut::<tcp::Socket>(h);
753            socket.close();
754        }
755    }
756
757    0
758}
759
760// 获取套接字地址
761pub fn getsockname(sockfd: i32, addr: *mut u8, addrlen: *mut u32) -> isize {
762    let task = current_cpu().lock().current_task.as_ref().unwrap().clone();
763    let tid = task.lock().tid as usize;
764
765    let handle = match get_socket_handle(tid, sockfd as usize) {
766        Some(h) => h,
767        None => return -88, // ENOTSOCK
768    };
769
770    let sockets = SOCKET_SET.lock();
771    let local_endpoint = match handle {
772        SocketHandle::Tcp(h) => {
773            let socket = sockets.get::<tcp::Socket>(h);
774            socket.local_endpoint()
775        }
776        SocketHandle::Udp(h) => {
777            let socket = sockets.get::<udp::Socket>(h);
778            let listen_ep = socket.endpoint();
779            listen_ep
780                .addr
781                .map(|addr| IpEndpoint::new(addr, listen_ep.port))
782        }
783    };
784
785    drop(sockets);
786
787    if let Some(ep) = local_endpoint {
788        {
789            let _guard = SumGuard::new();
790            unsafe {
791                let _ = write_sockaddr_in(addr, addrlen, ep);
792            }
793        }
794        0
795    } else {
796        -22 // EINVAL
797    }
798}
799
800// 获取对端套接字地址
801pub fn getpeername(sockfd: i32, addr: *mut u8, addrlen: *mut u32) -> isize {
802    let task = current_cpu().lock().current_task.as_ref().unwrap().clone();
803    let tid = task.lock().tid as usize;
804
805    let handle = match get_socket_handle(tid, sockfd as usize) {
806        Some(h) => h,
807        None => return -88, // ENOTSOCK
808    };
809
810    let sockets = SOCKET_SET.lock();
811    let remote_endpoint = match handle {
812        SocketHandle::Tcp(h) => {
813            let socket = sockets.get::<tcp::Socket>(h);
814            socket.remote_endpoint()
815        }
816        SocketHandle::Udp(_) => {
817            // UDP doesn't have a peer, use stored endpoint
818            drop(sockets);
819            let file = match task.lock().fd_table.get(sockfd as usize) {
820                Ok(f) => f,
821                Err(_) => return -9, // EBADF
822            };
823            use crate::net::socket::get_socket_remote_endpoint;
824            get_socket_remote_endpoint(&file)
825        }
826    };
827
828    if let Some(ep) = remote_endpoint {
829        {
830            let _guard = SumGuard::new();
831            unsafe {
832                let _ = write_sockaddr_in(addr, addrlen, ep);
833            }
834        }
835        0
836    } else {
837        -107 // ENOTCONN
838    }
839}