1use alloc::string::String;
41use alloc::sync::Arc;
42use alloc::vec;
43use alloc::vec::Vec;
44
45use crate::arch::Trapframe;
46use crate::network::{
47 Inet4SocketAddress, Ipv4Address, LocalSocketAddress, NetworkManager, ShutdownHow,
48 SocketAddress, SocketDomain, SocketObject, SocketProtocol, SocketType, local::LocalSocket,
49};
50use crate::object::KernelObject;
51use crate::object::handle::{AccessMode, HandleMetadata, HandleType};
52use crate::task::mytask;
53
54#[repr(C)]
55#[derive(Clone, Copy)]
56struct NetworkSetIpv4Request {
57 iface_ptr: usize,
58 iface_len: usize,
59 addr: [u8; 4],
60}
61
62fn read_user_string(ptr: usize, len: usize) -> Option<String> {
63 let task = mytask()?;
64 if len == 0 {
65 return None;
66 }
67 let addr = task.vm_manager.translate_vaddr(ptr)? as *const u8;
68 if len > 256 {
69 return None;
70 }
71 let mut bytes = Vec::with_capacity(len);
72 unsafe {
73 for i in 0..len {
74 bytes.push(*addr.add(i));
75 }
76 }
77 String::from_utf8(bytes).ok()
78}
79
80fn read_user_ipv4(ptr: usize) -> Option<Ipv4Address> {
81 let task = mytask()?;
82 let addr = task.vm_manager.translate_vaddr(ptr)? as *const u8;
83 unsafe {
84 let bytes = [*addr, *addr.add(1), *addr.add(2), *addr.add(3)];
85 Some(Ipv4Address::from_bytes(bytes))
86 }
87}
88
89pub fn sys_network_set_ipv4(tf: &mut Trapframe) -> usize {
90 let task = match mytask() {
91 Some(task) => task,
92 None => return usize::MAX,
93 };
94 tf.increment_pc_next(task);
95
96 let req_ptr = tf.get_arg(0);
97 let req_addr = match task.vm_manager.translate_vaddr(req_ptr) {
98 Some(addr) => addr as *const NetworkSetIpv4Request,
99 None => return usize::MAX,
100 };
101
102 let req = unsafe { *req_addr };
103 let iface = match read_user_string(req.iface_ptr, req.iface_len) {
104 Some(name) => name,
105 None => return usize::MAX,
106 };
107 let ip = Ipv4Address::from_bytes(req.addr);
108
109 if crate::network::get_network_manager()
110 .get_interface(&iface)
111 .is_none()
112 {
113 return usize::MAX;
114 }
115
116 match crate::network::config::set_interface_ip(&iface, ip) {
117 Ok(()) => 0,
118 Err(_) => usize::MAX,
119 }
120}
121
122pub fn sys_network_set_gateway(tf: &mut Trapframe) -> usize {
123 let task = match mytask() {
124 Some(task) => task,
125 None => return usize::MAX,
126 };
127 tf.increment_pc_next(task);
128
129 let addr_ptr = tf.get_arg(0);
130 let gateway = match read_user_ipv4(addr_ptr) {
131 Some(addr) => addr,
132 None => return usize::MAX,
133 };
134 crate::network::get_network_manager().set_default_gateway(gateway);
135 0
136}
137
138pub fn sys_network_set_dns(tf: &mut Trapframe) -> usize {
139 let task = match mytask() {
140 Some(task) => task,
141 None => return usize::MAX,
142 };
143 tf.increment_pc_next(task);
144
145 let addr_ptr = tf.get_arg(0);
146 let dns = match read_user_ipv4(addr_ptr) {
147 Some(addr) => addr,
148 None => return usize::MAX,
149 };
150 let manager = crate::network::get_network_manager();
151 let mut config = manager.get_config();
152 config.dns_server = Some(dns);
153 manager.set_config(config);
154 0
155}
156
157pub fn sys_network_set_netmask(tf: &mut Trapframe) -> usize {
158 let task = match mytask() {
159 Some(task) => task,
160 None => return usize::MAX,
161 };
162 tf.increment_pc_next(task);
163
164 let addr_ptr = tf.get_arg(0);
165 let mask = match read_user_ipv4(addr_ptr) {
166 Some(addr) => addr,
167 None => return usize::MAX,
168 };
169 let manager = crate::network::get_network_manager();
170 let mut config = manager.get_config();
171 config.subnet_mask = mask;
172 manager.set_config(config);
173 0
174}
175
176pub fn sys_network_list_interfaces(tf: &mut Trapframe) -> usize {
177 let task = match mytask() {
178 Some(task) => task,
179 None => return usize::MAX,
180 };
181 tf.increment_pc_next(task);
182
183 let buf_ptr = tf.get_arg(0);
184 let buf_len = tf.get_arg(1);
185 if buf_ptr == 0 || buf_len == 0 {
186 return usize::MAX;
187 }
188
189 let buf_addr = match task.vm_manager.translate_vaddr(buf_ptr) {
190 Some(addr) => addr as *mut u8,
191 None => return usize::MAX,
192 };
193
194 let interfaces = crate::network::get_network_manager().list_interfaces();
195 let mut output = String::new();
196 for (idx, name) in interfaces.iter().enumerate() {
197 if idx > 0 {
198 output.push('\n');
199 }
200 output.push_str(name);
201 }
202
203 let bytes = output.as_bytes();
204 let copy_len = bytes.len().min(buf_len);
205 unsafe {
206 core::ptr::copy_nonoverlapping(bytes.as_ptr(), buf_addr, copy_len);
207 }
208 copy_len
209}
210
211pub fn sys_socket_create(tf: &mut Trapframe) -> usize {
231 let task = match mytask() {
232 Some(task) => task,
233 None => return usize::MAX,
234 };
235
236 tf.increment_pc_next(task);
237
238 let domain = tf.get_arg(0) as u32;
239 let socket_type = tf.get_arg(1) as u32;
240 let protocol = tf.get_arg(2) as u32;
241
242 let domain = match domain {
243 0 | 1 => SocketDomain::Local,
244 2 => SocketDomain::Inet4,
245 3 => SocketDomain::Inet6,
246 _ => return usize::MAX,
247 };
248
249 let socket_type = match socket_type {
250 0 | 1 => SocketType::Stream,
251 2 => SocketType::Datagram,
252 3 => SocketType::Raw,
253 4 => SocketType::SeqPacket,
254 _ => return usize::MAX,
255 };
256
257 let protocol = match protocol {
258 0 => SocketProtocol::Default,
259 1 => SocketProtocol::Icmp,
260 6 => SocketProtocol::Tcp,
261 17 => SocketProtocol::Udp,
262 value => SocketProtocol::Raw(value as u16),
263 };
264
265 let protocol = match (socket_type, protocol) {
266 (SocketType::Stream, SocketProtocol::Default) => SocketProtocol::Tcp,
267 (SocketType::Datagram, SocketProtocol::Default) => SocketProtocol::Udp,
268 (SocketType::Raw, SocketProtocol::Default) => SocketProtocol::Raw(0),
269 _ => protocol,
270 };
271
272 let socket = match domain {
273 SocketDomain::Local => {
274 let socket = Arc::new(LocalSocket::new(socket_type, protocol));
275 LocalSocket::init_self_weak(&socket);
276 socket as Arc<dyn SocketObject>
277 }
278 SocketDomain::Inet4 | SocketDomain::Inet6 => {
279 let manager = NetworkManager::get_manager();
280 let socket = match protocol {
281 SocketProtocol::Tcp => manager.get_layer("tcp").map(|layer| {
282 let tcp = layer
283 .as_any()
284 .downcast_ref::<crate::network::tcp::TcpLayer>()
285 .expect("tcp layer type mismatch");
286 tcp.create_socket() as Arc<dyn SocketObject>
287 }),
288 SocketProtocol::Udp => manager.get_layer("udp").map(|layer| {
289 let udp = layer
290 .as_any()
291 .downcast_ref::<crate::network::udp::UdpLayer>()
292 .expect("udp layer type mismatch");
293 udp.create_socket() as Arc<dyn SocketObject>
294 }),
295 SocketProtocol::Icmp => manager.get_layer("icmp").map(|layer| {
296 let icmp = layer
297 .as_any()
298 .downcast_ref::<crate::network::icmp::IcmpLayer>()
299 .expect("icmp layer type mismatch");
300 icmp.create_socket() as Arc<dyn SocketObject>
301 }),
302 _ => None,
303 };
304
305 match socket {
306 Some(socket) => socket,
307 None => return usize::MAX,
308 }
309 }
310 SocketDomain::Packet => return usize::MAX,
311 };
312
313 let socket_id = match NetworkManager::get_manager().allocate_socket_id(socket.clone()) {
315 Ok(id) => id,
316 Err(_) => return usize::MAX,
317 };
318
319 let kernel_obj = KernelObject::Socket(socket);
321
322 let metadata = HandleMetadata {
324 handle_type: HandleType::IpcChannel,
325 access_mode: AccessMode::ReadWrite,
326 special_semantics: None,
327 };
328
329 let handle_id = match task.handle_table.insert_with_metadata(kernel_obj, metadata) {
331 Ok(id) => id as usize,
332 Err(_) => {
333 NetworkManager::get_manager().remove_socket(socket_id);
335 return usize::MAX;
336 }
337 };
338
339 handle_id
340}
341
342pub fn sys_socket_bind(tf: &mut Trapframe) -> usize {
365 let task = match mytask() {
366 Some(task) => task,
367 None => return usize::MAX,
368 };
369
370 tf.increment_pc_next(task);
371
372 let handle_id = tf.get_arg(0) as u32;
373 let path_ptr = tf.get_arg(1);
374 let path_len = tf.get_arg(2);
375
376 let socket_arc = match task.handle_table.get(handle_id) {
378 Some(KernelObject::Socket(socket)) => socket.clone(),
379 _ => return usize::MAX,
380 };
381
382 let path_physical = match task.vm_manager.translate_vaddr(path_ptr) {
384 Some(addr) => addr as *const u8,
385 None => return usize::MAX,
386 };
387
388 if path_len == core::mem::size_of::<Inet4SocketAddress>() {
389 let addr = unsafe { *(path_physical as *const Inet4SocketAddress) };
390 if socket_arc.bind(&SocketAddress::Inet(addr)).is_err() {
391 return usize::MAX;
392 }
393 return 0;
394 }
395
396 let path = unsafe {
398 let mut bytes = alloc::vec::Vec::with_capacity(path_len.min(108)); for i in 0..path_len.min(108) {
400 let byte = *path_physical.add(i);
401 if byte == 0 {
402 break;
403 }
404 bytes.push(byte);
405 }
406 match alloc::string::String::from_utf8(bytes) {
407 Ok(s) => s,
408 Err(_) => return usize::MAX,
409 }
410 };
411
412 let local_addr = match LocalSocketAddress::from_path(path.clone()) {
414 Ok(addr) => addr,
415 Err(_) => return usize::MAX,
416 };
417
418 if socket_arc.bind(&SocketAddress::Local(local_addr)).is_err() {
420 return usize::MAX;
421 }
422
423 if NetworkManager::get_manager()
426 .register_named_socket(&path, socket_arc.clone())
427 .is_err()
428 {
429 return usize::MAX;
430 }
431
432 let socket_id = match NetworkManager::get_manager().get_socket_id(&socket_arc) {
434 Some(id) => id,
435 None => return usize::MAX, };
437
438 let vfs_guard = task.vfs.read();
441 let vfs = match vfs_guard.as_ref() {
442 Some(vfs) => vfs.clone(),
443 None => {
444 crate::fs::vfs_v2::manager::get_global_vfs_manager()
446 }
447 };
448
449 let socket_file_type = crate::fs::FileType::Socket(crate::fs::SocketFileInfo { socket_id });
450
451 if let Err(e) = vfs.create_file(&path, socket_file_type) {
460 crate::early_println!(
462 "[socket_bind] Warning: Failed to create VFS socket file at '{}': {:?}",
463 path,
464 e
465 );
466 }
467
468 0
469}
470
471pub fn sys_socket_listen(tf: &mut Trapframe) -> usize {
491 let task = match mytask() {
492 Some(task) => task,
493 None => return usize::MAX,
494 };
495
496 tf.increment_pc_next(task);
497
498 let handle_id = tf.get_arg(0) as u32;
499 let backlog = tf.get_arg(1);
500
501 let socket = match task.handle_table.get(handle_id) {
503 Some(KernelObject::Socket(socket)) => socket.clone(),
504 _ => {
505 crate::println!("[sys_socket_listen] Invalid handle {}", handle_id);
506 return usize::MAX;
507 }
508 };
509
510 match socket.listen(backlog) {
512 Ok(()) => {
513 crate::println!("[sys_socket_listen] Socket {} now listening", handle_id);
514 0
515 }
516 Err(e) => {
517 crate::println!("[sys_socket_listen] listen() failed: {:?}", e);
518 usize::MAX
519 }
520 }
521}
522
523pub fn sys_socket_connect(tf: &mut Trapframe) -> usize {
545 let task = match mytask() {
546 Some(task) => task,
547 None => return usize::MAX,
548 };
549
550 tf.increment_pc_next(task);
551
552 let handle_id = tf.get_arg(0) as u32;
553 let path_ptr = tf.get_arg(1);
554 let path_len = tf.get_arg(2);
555
556 let socket = match task.handle_table.get(handle_id) {
558 Some(KernelObject::Socket(socket)) => socket.clone(),
559 _ => return usize::MAX,
560 };
561
562 let path_physical = match task.vm_manager.translate_vaddr(path_ptr) {
564 Some(addr) => addr as *const u8,
565 None => return usize::MAX,
566 };
567
568 if path_len == core::mem::size_of::<Inet4SocketAddress>() {
569 let addr = unsafe { *(path_physical as *const Inet4SocketAddress) };
570 if socket.connect(&SocketAddress::Inet(addr)).is_err() {
571 return usize::MAX;
572 }
573 return 0;
574 }
575
576 let path = unsafe {
578 let mut bytes = alloc::vec::Vec::with_capacity(path_len.min(108)); for i in 0..path_len.min(108) {
580 let byte = *path_physical.add(i);
581 if byte == 0 {
582 break;
583 }
584 bytes.push(byte);
585 }
586 match alloc::string::String::from_utf8(bytes) {
587 Ok(s) => s,
588 Err(_) => return usize::MAX,
589 }
590 };
591
592 let peer_addr = match LocalSocketAddress::from_path(&path) {
594 Ok(addr) => addr,
595 Err(_) => return usize::MAX,
596 };
597
598 if socket.connect(&SocketAddress::Local(peer_addr)).is_err() {
600 return usize::MAX;
601 }
602
603 0
604}
605
606pub fn sys_socket_accept(tf: &mut Trapframe) -> usize {
628 let task = match mytask() {
629 Some(task) => task,
630 None => return usize::MAX,
631 };
632
633 tf.increment_pc_next(task);
634
635 let handle_id = tf.get_arg(0) as u32;
636
637 let socket_obj = match task.handle_table.get(handle_id) {
639 Some(KernelObject::Socket(socket)) => socket.clone(),
640 Some(_) => return usize::MAX,
641 None => return usize::MAX,
642 };
643
644 use crate::network::local::LocalSocket;
646
647 let accepted_socket = if let Some(local_socket) = LocalSocket::from_socket_object(&socket_obj) {
648 match local_socket.accept_blocking(task.get_id(), tf) {
650 Ok(socket) => socket,
651 Err(e) => {
652 crate::println!(
653 "[sys_socket_accept] LocalSocket accept_blocking failed: {:?}",
654 e
655 );
656 return usize::MAX;
657 }
658 }
659 } else if let Some(tcp_socket) = crate::network::tcp::TcpSocket::from_socket_object(&socket_obj)
660 {
661 match tcp_socket.accept_blocking(task.get_id(), tf) {
663 Ok(socket) => socket,
664 Err(_) => return usize::MAX,
665 }
666 } else {
667 crate::println!("[sys_socket_accept] Not a supported socket type");
668 return usize::MAX;
669 };
670
671 let kernel_obj = KernelObject::Socket(accepted_socket);
673 let metadata = HandleMetadata {
674 handle_type: HandleType::IpcChannel,
675 access_mode: AccessMode::ReadWrite,
676 special_semantics: None,
677 };
678
679 match task.handle_table.insert_with_metadata(kernel_obj, metadata) {
680 Ok(id) => id as usize,
681 Err(_) => usize::MAX,
682 }
683}
684
685pub fn sys_socketpair(tf: &mut Trapframe) -> usize {
706 let task = match mytask() {
707 Some(task) => task,
708 None => return usize::MAX,
709 };
710
711 tf.increment_pc_next(task);
712
713 let array_ptr = tf.get_arg(0);
714
715 let array_vaddr = match task.vm_manager.translate_vaddr(array_ptr) {
717 Some(addr) => addr as *mut usize,
718 None => return usize::MAX,
719 };
720
721 let (socket1, socket2) = LocalSocket::create_connected_pair(
723 String::from("socketpair:0"),
724 String::from("socketpair:1"),
725 );
726
727 let kernel_obj1 = KernelObject::Socket(socket1);
729 let metadata = HandleMetadata {
730 handle_type: HandleType::IpcChannel,
731 access_mode: AccessMode::ReadWrite,
732 special_semantics: None,
733 };
734
735 let handle1 = match task
736 .handle_table
737 .insert_with_metadata(kernel_obj1, metadata.clone())
738 {
739 Ok(id) => id as usize,
740 Err(_) => return usize::MAX,
741 };
742
743 let kernel_obj2 = KernelObject::Socket(socket2);
744 let handle2 = match task
745 .handle_table
746 .insert_with_metadata(kernel_obj2, metadata)
747 {
748 Ok(id) => id as usize,
749 Err(_) => {
750 let _ = task.handle_table.remove(handle1 as u32);
752 return usize::MAX;
753 }
754 };
755
756 unsafe {
758 array_vaddr.write(handle1);
759 array_vaddr.add(1).write(handle2);
760 }
761
762 0
763}
764
765pub fn sys_socket_shutdown(tf: &mut Trapframe) -> usize {
785 let task = match mytask() {
786 Some(task) => task,
787 None => return usize::MAX,
788 };
789
790 tf.increment_pc_next(task);
791
792 let handle_id = tf.get_arg(0) as u32;
793 let how_value = tf.get_arg(1);
794
795 let socket = match task.handle_table.get(handle_id) {
797 Some(KernelObject::Socket(socket)) => socket.clone(),
798 _ => return usize::MAX,
799 };
800
801 let how = match how_value {
803 0 => ShutdownHow::Read,
804 1 => ShutdownHow::Write,
805 2 => ShutdownHow::Both,
806 _ => return usize::MAX,
807 };
808
809 if socket.shutdown(how).is_err() {
811 return usize::MAX;
812 }
813
814 0
815}
816
817pub fn sys_socket_recvfrom(tf: &mut Trapframe) -> usize {
840 let task = match mytask() {
841 Some(task) => task,
842 None => return usize::MAX,
843 };
844
845 tf.increment_pc_next(task);
846
847 let handle_id = tf.get_arg(0) as u32;
848 let buf_ptr = tf.get_arg(1);
849 let buf_len = tf.get_arg(2);
850 let addr_ptr = tf.get_arg(3);
851
852 let buf_vaddr = match task.vm_manager.translate_vaddr(buf_ptr) {
854 Some(addr) => addr as *mut u8,
855 None => return usize::MAX,
856 };
857
858 let socket = match task.handle_table.get(handle_id) {
860 Some(KernelObject::Socket(socket)) => socket.clone(),
861 _ => return usize::MAX,
862 };
863
864 let mut temp_buf = vec![0u8; buf_len];
866
867 match socket.recvfrom(&mut temp_buf, 0) {
869 Ok((len, addr)) => {
870 unsafe {
872 core::ptr::copy_nonoverlapping(temp_buf.as_ptr(), buf_vaddr, len);
873 }
874
875 if addr_ptr != 0 {
877 if let Some(addr_vaddr) = task.vm_manager.translate_vaddr(addr_ptr) {
878 unsafe {
879 match addr {
880 SocketAddress::Inet(inet) => {
881 let addr_bytes = inet.addr;
882 let port_bytes = inet.port.to_be_bytes();
883 let ptr = addr_vaddr as *mut u8;
884 *ptr = 2; *ptr.add(1) = 0;
886 core::ptr::copy_nonoverlapping(addr_bytes.as_ptr(), ptr.add(2), 4);
887 core::ptr::copy_nonoverlapping(port_bytes.as_ptr(), ptr.add(6), 2);
888 }
889 _ => {}
890 }
891 }
892 }
893 }
894
895 len
896 }
897 Err(crate::network::socket::SocketError::WouldBlock) => (-(11i32)) as usize,
898 Err(_) => usize::MAX,
899 }
900}
901
902pub fn sys_socket_sendto(tf: &mut Trapframe) -> usize {
926 let task = match mytask() {
927 Some(task) => task,
928 None => return usize::MAX,
929 };
930
931 tf.increment_pc_next(task);
932
933 let handle_id = tf.get_arg(0) as u32;
934 let buf_ptr = tf.get_arg(1);
935 let buf_len = tf.get_arg(2);
936 let addr_ptr = tf.get_arg(3);
937
938 let buf_vaddr = match task.vm_manager.translate_vaddr(buf_ptr) {
940 Some(addr) => addr as *const u8,
941 None => return usize::MAX,
942 };
943
944 let data: Vec<u8> = unsafe { core::slice::from_raw_parts(buf_vaddr, buf_len).to_vec() };
946
947 let socket = match task.handle_table.get(handle_id) {
949 Some(KernelObject::Socket(socket)) => socket.clone(),
950 _ => return usize::MAX,
951 };
952
953 let addr = if addr_ptr != 0 {
955 match task.vm_manager.translate_vaddr(addr_ptr) {
956 Some(addr_vaddr) => {
957 unsafe {
958 let ptr = addr_vaddr as *const u8;
959 let family = *ptr;
960 match family {
961 2 => {
962 let ip_bytes = [*ptr.add(2), *ptr.add(3), *ptr.add(4), *ptr.add(5)];
964 let port = u16::from_be_bytes([*ptr.add(6), *ptr.add(7)]);
965 SocketAddress::Inet(Inet4SocketAddress::new(ip_bytes, port))
966 }
967 _ => return usize::MAX,
968 }
969 }
970 }
971 None => return usize::MAX,
972 }
973 } else {
974 return usize::MAX;
975 };
976
977 match socket.sendto(&data, &addr, 0) {
979 Ok(len) => len,
980 Err(_) => usize::MAX,
981 }
982}