From 55df9ca8923b8afb6021f584e5e049fcfdda29e5 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Thu, 4 Apr 2019 21:38:32 +0800 Subject: [PATCH] Initial support for ioctl SIOCGARP --- kernel/Cargo.toml | 2 +- kernel/src/fs/file_like.rs | 9 ++++++++ kernel/src/net/structs.rs | 43 ++++++++++++++++++++++++++++++++++++++ kernel/src/syscall/fs.rs | 10 +++++++++ kernel/src/syscall/mod.rs | 2 +- kernel/src/syscall/net.rs | 36 ++++++++++++++++++------------- 6 files changed, 85 insertions(+), 17 deletions(-) diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 5c06128..3cf9eee 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -49,7 +49,7 @@ pci = { git = "https://github.com/rcore-os/pci-rs" } device_tree = { git = "https://github.com/rcore-os/device_tree-rs" } isomorphic_drivers = { git = "https://github.com/rcore-os/isomorphic_drivers" } lazy_static = { version = "1.3", features = ["spin_no_std"] } -smoltcp = { version = "0.5.0", default-features = false, features = ["alloc", "log", "proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw"] } +smoltcp = { git = "https://github.com/rcore-os/smoltcp", default-features = false, features = ["alloc", "log", "proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw"] } bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator" } rcore-memory = { path = "../crate/memory" } rcore-thread = { git = "https://github.com/rcore-os/rcore-thread" } diff --git a/kernel/src/fs/file_like.rs b/kernel/src/fs/file_like.rs index d765f2c..bd1f660 100644 --- a/kernel/src/fs/file_like.rs +++ b/kernel/src/fs/file_like.rs @@ -28,6 +28,15 @@ impl FileLike { }; Ok(len) } + pub fn ioctl(&mut self, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult { + match self { + FileLike::File(file) => { + warn!("ioctl not implemented for file"); + Ok(0) + } + FileLike::Socket(socket) => socket.ioctl(request, arg1, arg2, arg3), + } + } } impl fmt::Debug for FileLike { diff --git a/kernel/src/net/structs.rs b/kernel/src/net/structs.rs index 064dfaa..0331219 100644 --- a/kernel/src/net/structs.rs +++ b/kernel/src/net/structs.rs @@ -2,6 +2,7 @@ use crate::arch::rand; use crate::drivers::{NET_DRIVERS, SOCKET_ACTIVITY}; use crate::sync::SpinNoIrqLock as Mutex; use crate::syscall::*; +use crate::util; use alloc::boxed::Box; use smoltcp::socket::*; @@ -54,6 +55,10 @@ pub trait Socket: Send + Sync { warn!("setsockopt is unimplemented"); Ok(0) } + fn ioctl(&mut self, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult { + warn!("ioctl is unimplemented for this socket"); + Ok(0) + } fn box_clone(&self) -> Box; } @@ -384,6 +389,15 @@ impl UdpSocketState { } } +#[repr(C)] +struct ArpReq { + arp_pa: SockAddrPlaceholder, + arp_ha: SockAddrPlaceholder, + arp_flags: u32, + arp_netmask: SockAddrPlaceholder, + arp_dev: [u8; 16], +} + impl Socket for UdpSocketState { fn read(&self, data: &mut [u8]) -> (SysResult, Endpoint) { loop { @@ -486,6 +500,35 @@ impl Socket for UdpSocketState { } } + fn ioctl(&mut self, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult { + match request { + // SIOCGARP + 0x8954 => { + // FIXME: check addr + let req = unsafe { &mut *(request as *mut ArpReq) }; + if let AddressFamily::Internet = AddressFamily::from(req.arp_pa.family) { + let name = req.arp_dev.as_ptr(); + let ifname = unsafe { util::from_cstr(name) }; + let addr = &req.arp_pa as *const SockAddrPlaceholder as *const SockAddr; + let addr = unsafe { + IpAddress::from(Ipv4Address::from_bytes( + &u32::from_be((*addr).payload.addr_in.sin_addr).to_be_bytes()[..], + )) + }; + for iface in NET_DRIVERS.read().iter() { + if iface.get_ifname() == ifname { + debug!("get arp matched ifname {}", ifname); + } + } + Err(SysError::ENOENT) + } else { + Err(SysError::EINVAL) + } + } + _ => Ok(0), + } + } + fn endpoint(&self) -> Option { let mut sockets = SOCKETS.lock(); let socket = sockets.get::(self.handle.0); diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index a2636a2..5f7d547 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -472,6 +472,16 @@ pub fn sys_dup2(fd1: usize, fd2: usize) -> SysResult { Ok(fd2) } +pub fn sys_ioctl(fd: usize, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult { + info!( + "ioctl: fd:{}, request:{}, args: {} {} {}", + fd, request, arg1, arg2, arg3 + ); + let mut proc = process(); + let file_like = proc.get_file_like(fd)?; + file_like.ioctl(request, arg1, arg2, arg3) +} + pub fn sys_chdir(path: *const u8) -> SysResult { let mut proc = process(); let path = unsafe { proc.vm.check_and_clone_cstr(path)? }; diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index d8fc481..658992e 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -19,7 +19,7 @@ use self::custom::*; use self::fs::*; use self::mem::*; use self::misc::*; -use self::net::*; +pub use self::net::*; use self::proc::*; use self::time::*; diff --git a/kernel/src/syscall/net.rs b/kernel/src/syscall/net.rs index a39c55b..ad62598 100644 --- a/kernel/src/syscall/net.rs +++ b/kernel/src/syscall/net.rs @@ -279,38 +279,44 @@ impl Process { // cancel alignment #[repr(packed)] pub struct SockAddrIn { - sin_port: u16, - sin_addr: u32, - sin_zero: [u8; 8], + pub sin_port: u16, + pub sin_addr: u32, + pub sin_zero: [u8; 8], } #[repr(C)] pub struct SockAddrUn { - sun_path: [u8; 108], + pub sun_path: [u8; 108], } // beware of alignment issue #[repr(C, packed)] pub struct SockAddrLl { - sll_protocol: u16, - sll_ifindex: u32, - sll_hatype: u16, - sll_pkttype: u8, - sll_halen: u8, - sll_addr: [u8; 8], + pub sll_protocol: u16, + pub sll_ifindex: u32, + pub sll_hatype: u16, + pub sll_pkttype: u8, + pub sll_halen: u8, + pub sll_addr: [u8; 8], } #[repr(C)] pub union SockAddrPayload { - addr_in: SockAddrIn, - addr_un: SockAddrUn, - addr_ll: SockAddrLl, + pub addr_in: SockAddrIn, + pub addr_un: SockAddrUn, + pub addr_ll: SockAddrLl, } #[repr(C)] pub struct SockAddr { - family: u16, - payload: SockAddrPayload, + pub family: u16, + pub payload: SockAddrPayload, +} + +#[repr(C)] +pub struct SockAddrPlaceholder { + pub family: u16, + pub data: [u8; 14], } impl From for SockAddr {