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:
parent
77f8afa30c
commit
c944d2269d
@ -66,6 +66,11 @@ pub trait Driver: Send + Sync {
|
||||
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
|
||||
fn read_block(&self, block_id: usize, buf: &mut [u8]) -> bool {
|
||||
unimplemented!("not a block driver")
|
||||
|
@ -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)]
|
||||
|
@ -8,7 +8,17 @@ use smoltcp::socket::*;
|
||||
use smoltcp::wire::*;
|
||||
|
||||
#[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)]
|
||||
pub enum Endpoint {
|
||||
@ -633,8 +643,12 @@ impl Socket for PacketSocketState {
|
||||
}
|
||||
|
||||
fn write(&self, data: &[u8], sendto_endpoint: Option<Endpoint>) -> SysResult {
|
||||
if let Some(endpoint) = sendto_endpoint {
|
||||
unimplemented!()
|
||||
if let Some(Endpoint::LinkLevel(endpoint)) = sendto_endpoint {
|
||||
let ifaces = NET_DRIVERS.read();
|
||||
match ifaces[endpoint.interface_index].send(data) {
|
||||
Some(len) => Ok(len),
|
||||
None => Err(SysError::ENOBUFS),
|
||||
}
|
||||
} else {
|
||||
Err(SysError::ENOTCONN)
|
||||
}
|
||||
|
@ -4,7 +4,8 @@ use super::*;
|
||||
use crate::drivers::SOCKET_ACTIVITY;
|
||||
use crate::fs::FileLike;
|
||||
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 alloc::boxed::Box;
|
||||
@ -288,14 +289,15 @@ pub struct SockAddrUn {
|
||||
sun_path: [u8; 108],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
// 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,
|
||||
sll_addr: [u8; 8],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@ -361,7 +363,9 @@ fn sockaddr_to_endpoint(
|
||||
if len < size_of::<u16>() + size_of::<SockAddrLl>() {
|
||||
return Err(SysError::EINVAL);
|
||||
}
|
||||
unimplemented!()
|
||||
Ok(Endpoint::LinkLevel(LinkLevelEndpoint::new(
|
||||
(*addr).payload.addr_ll.sll_ifindex as usize,
|
||||
)))
|
||||
}
|
||||
_ => Err(SysError::EINVAL),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user