1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-22 16:16:16 +04:00

Enable user to send to iface directly via packet socket

This commit is contained in:
Jiajie Chen 2019-04-04 20:31:46 +08:00
parent 77f8afa30c
commit c944d2269d
4 changed files with 47 additions and 7 deletions

View File

@ -66,6 +66,11 @@ pub trait Driver: Send + Sync {
unimplemented!("not a net driver") unimplemented!("not a net driver")
} }
// send an ethernet frame, only use it when necessary
fn send(&self, data: &[u8]) -> Option<usize> {
unimplemented!("not a net driver")
}
// block related drivers should implement these // block related drivers should implement these
fn read_block(&self, block_id: usize, buf: &mut [u8]) -> bool { fn read_block(&self, block_id: usize, buf: &mut [u8]) -> bool {
unimplemented!("not a block driver") unimplemented!("not a block driver")

View File

@ -149,6 +149,23 @@ impl Driver for E1000Interface {
} }
} }
} }
// send an ethernet frame, only use it when necessary
fn send(&self, data: &[u8]) -> Option<usize> {
use smoltcp::phy::TxToken;
let token = E1000TxToken(self.driver.clone());
if token
.consume(Instant::from_millis(0), data.len(), |buffer| {
buffer.copy_from_slice(&data);
Ok(())
})
.is_ok()
{
Some(data.len())
} else {
None
}
}
} }
#[repr(C)] #[repr(C)]

View File

@ -8,7 +8,17 @@ use smoltcp::socket::*;
use smoltcp::wire::*; use smoltcp::wire::*;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct LinkLevelEndpoint {} pub struct LinkLevelEndpoint {
interface_index: usize,
}
impl LinkLevelEndpoint {
pub fn new(ifindex: usize) -> Self {
LinkLevelEndpoint {
interface_index: ifindex,
}
}
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Endpoint { pub enum Endpoint {
@ -633,8 +643,12 @@ impl Socket for PacketSocketState {
} }
fn write(&self, data: &[u8], sendto_endpoint: Option<Endpoint>) -> SysResult { fn write(&self, data: &[u8], sendto_endpoint: Option<Endpoint>) -> SysResult {
if let Some(endpoint) = sendto_endpoint { if let Some(Endpoint::LinkLevel(endpoint)) = sendto_endpoint {
unimplemented!() let ifaces = NET_DRIVERS.read();
match ifaces[endpoint.interface_index].send(data) {
Some(len) => Ok(len),
None => Err(SysError::ENOBUFS),
}
} else { } else {
Err(SysError::ENOTCONN) Err(SysError::ENOTCONN)
} }

View File

@ -4,7 +4,8 @@ use super::*;
use crate::drivers::SOCKET_ACTIVITY; use crate::drivers::SOCKET_ACTIVITY;
use crate::fs::FileLike; use crate::fs::FileLike;
use crate::net::{ use crate::net::{
Endpoint, PacketSocketState, RawSocketState, Socket, TcpSocketState, UdpSocketState, SOCKETS, Endpoint, LinkLevelEndpoint, PacketSocketState, RawSocketState, Socket, TcpSocketState,
UdpSocketState, SOCKETS,
}; };
use crate::sync::{MutexGuard, SpinNoIrq, SpinNoIrqLock as Mutex}; use crate::sync::{MutexGuard, SpinNoIrq, SpinNoIrqLock as Mutex};
use alloc::boxed::Box; use alloc::boxed::Box;
@ -288,14 +289,15 @@ pub struct SockAddrUn {
sun_path: [u8; 108], sun_path: [u8; 108],
} }
#[repr(C)] // beware of alignment issue
#[repr(C, packed)]
pub struct SockAddrLl { pub struct SockAddrLl {
sll_protocol: u16, sll_protocol: u16,
sll_ifindex: u32, sll_ifindex: u32,
sll_hatype: u16, sll_hatype: u16,
sll_pkttype: u8, sll_pkttype: u8,
sll_halen: u8, sll_halen: u8,
sll_addr: u8, sll_addr: [u8; 8],
} }
#[repr(C)] #[repr(C)]
@ -361,7 +363,9 @@ fn sockaddr_to_endpoint(
if len < size_of::<u16>() + size_of::<SockAddrLl>() { if len < size_of::<u16>() + size_of::<SockAddrLl>() {
return Err(SysError::EINVAL); return Err(SysError::EINVAL);
} }
unimplemented!() Ok(Endpoint::LinkLevel(LinkLevelEndpoint::new(
(*addr).payload.addr_ll.sll_ifindex as usize,
)))
} }
_ => Err(SysError::EINVAL), _ => Err(SysError::EINVAL),
} }