Skip to content

Commit

Permalink
socket: fake netlink msg to send
Browse files Browse the repository at this point in the history
Signed-off-by: rayylee <[email protected]>
  • Loading branch information
hbuxiaofei committed Apr 7, 2024
1 parent efd46be commit 92b6174
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 15 deletions.
27 changes: 25 additions & 2 deletions modules/axnet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,33 @@ use axdriver::{prelude::*, AxDeviceContainer};
pub struct SocketAddr {
pub addr: IpAddr,
pub port: u16,
pub nl_groups: u32,
}

impl Default for SocketAddr {
fn default() -> Self {
SocketAddr {
addr: IpAddr::v4(0, 0, 0, 0),
port: 0,
nl_groups: 0, // RTNLGRP_NONE
}
}
}

impl SocketAddr {
pub fn new(addr: IpAddr, port: u16) -> Self {
SocketAddr { addr, port }
pub fn new_ipv4(addr: IpAddr, port: u16) -> Self {
SocketAddr {
addr,
port,
..Default::default()
}
}

pub fn new_netlink(groups: u32) -> Self {
SocketAddr {
nl_groups: groups,
..Default::default()
}
}
}

Expand All @@ -70,6 +92,7 @@ impl From<IpEndpoint> for SocketAddr {
SocketAddr {
addr: ie.addr,
port: ie.port,
..Default::default()
}
}
}
Expand Down
77 changes: 76 additions & 1 deletion modules/axnet/src/netlink.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,87 @@
extern crate alloc;
use alloc::sync::Arc;
use alloc::collections::VecDeque;
use core::cmp::min;

use axsync::Mutex;
use axerrno::AxResult;

struct NetlinkBuffer<T> {
buffer: VecDeque<T>,
capacity: usize,
}

impl<T> NetlinkBuffer<T> {
fn new(capacity: usize) -> Self {
NetlinkBuffer {
buffer: VecDeque::with_capacity(capacity),
capacity,
}
}

fn push(&mut self, element: T) {
if self.buffer.len() == self.capacity {
self.buffer.pop_front();
}
self.buffer.push_back(element);
}

fn pop(&mut self) -> Option<T> {
self.buffer.pop_front()
}

fn len(&self) -> usize {
self.buffer.len()
}

fn capacity(&self) -> usize {
self.capacity
}
}

pub struct NlSocket {
rx_buffer: Arc<Mutex<NetlinkBuffer<u8>>>,
tx_buffer: Arc<Mutex<NetlinkBuffer<u8>>>,
pub nl_groups: u32,
}

impl NlSocket {
pub fn new() -> Self {
NlSocket {}
NlSocket {
rx_buffer: Arc::new(Mutex::new(NetlinkBuffer::new(1024))),
tx_buffer: Arc::new(Mutex::new(NetlinkBuffer::new(1024))),
nl_groups: 0,
}
}

pub fn bind(&mut self, groups: u32) -> AxResult {
self.nl_groups = groups;
Ok(())
}

pub fn send(&self, buf: &[u8]) -> AxResult<usize> {
let mut rx = self.rx_buffer.lock();
for byte in buf.iter() {
rx.push(*byte);
}
Ok(buf.len())
}

pub fn fill_tx(&self, buf: &[u8]) -> AxResult<usize> {
let mut tx = self.tx_buffer.lock();
let length = min(buf.len(), tx.capacity() - tx.len());
for i in 0..length {
tx.push(buf[i]);
}
Ok(length)
}

pub fn recv_from(&self, buf: &mut [u8]) -> AxResult<usize> {
let mut tx = self.tx_buffer.lock();
let length = min(buf.len(), tx.len());
for i in 0..length {
buf[i] = tx.pop().unwrap();
}
Ok(length)
}
}
4 changes: 2 additions & 2 deletions modules/axnet/src/smoltcp_impl/loopback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ fn snoop_tcp_from_ip(buffer: &[u8], sockets: &mut SocketSet) -> Result<(), smolt

if ipv4_packet.next_header() == IpProtocol::Tcp {
let tcp_packet = TcpPacket::new_checked(ipv4_packet.payload())?;
let src_addr = SocketAddr::new(ipv4_packet.src_addr().into(), tcp_packet.src_port());
let dst_addr = SocketAddr::new(ipv4_packet.dst_addr().into(), tcp_packet.dst_port());
let src_addr = SocketAddr::new_ipv4(ipv4_packet.src_addr().into(), tcp_packet.src_port());
let dst_addr = SocketAddr::new_ipv4(ipv4_packet.dst_addr().into(), tcp_packet.dst_port());
let is_first = tcp_packet.syn() && !tcp_packet.ack();
if is_first {
// create a socket for the first incoming TCP packet, as the later accept() returns.
Expand Down
6 changes: 3 additions & 3 deletions ulib/axstarry/src/syscall_net/imp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ pub fn syscall_sendto(args: [usize; 6]) -> SyscallResult {
SocketInner::Udp(s) => {
// udp socket not bound
if s.local_addr().is_err() {
s.bind(into_core_sockaddr(SocketAddr::new(
s.bind(into_core_sockaddr(SocketAddr::new_ipv4(
IpAddr::v4(0, 0, 0, 0),
0,
).into()))
Expand Down Expand Up @@ -349,8 +349,8 @@ pub fn syscall_sendto(args: [usize; 6]) -> SyscallResult {

s.send(buf)
}
SocketInner::Netlink(_) => {
todo!()
SocketInner::Netlink(s) => {
s.send(buf)
}
};

Expand Down
3 changes: 3 additions & 0 deletions ulib/axstarry/src/syscall_net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ pub use socket::Socket;
mod net_syscall_id;
pub use net_syscall_id::NetSyscallId::{self, *};

mod netlink;
pub use netlink::netlink_unicast;

/// 进行 syscall 的分发
pub fn net_syscall(syscall_id: net_syscall_id::NetSyscallId, args: [usize; 6]) -> SyscallResult {
match syscall_id {
Expand Down
36 changes: 36 additions & 0 deletions ulib/axstarry/src/syscall_net/netlink.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use axprocess::current_process;
use super::socket::{Socket, SocketInner};

pub fn netlink_unicast()
{
let process = current_process();
let fd_table = process.fd_manager.fd_table.lock();

// # define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \
// (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \
// (nlh)->nlmsg_len <= (len))

let mut buffer: [u8; 20] = [0; 20];
buffer[0] = 16; // nlmsg_len: sizeof(struct nlmsghdr)
buffer[4] = 16; // nlmsg_type: RTM_NEWLINK
buffer[6] = 65; // 'A'
buffer[7] = 66; // 'B'
buffer[8] = 67; // 'C'
buffer[9] = 68; // 'D'
buffer[10] = 69; // 'E'

for i in 0..fd_table.len() {
if let Some(file) = fd_table[i].as_ref() {
if let Some(s_file) = file.as_any().downcast_ref::<Socket>() {
let inner = s_file.inner.lock();
if let SocketInner::Netlink(s) = &*inner {
let _ = s.fill_tx(&buffer);
}
}
}
}

}



23 changes: 16 additions & 7 deletions ulib/axstarry/src/syscall_net/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use alloc::string::String;
use axerrno::{AxError, AxResult};
use axfs::api::{FileIO, FileIOType, OpenFlags, Read, Write};

use axlog::warn;
use axlog::{warn, error};
use axnet::{
from_core_sockaddr, into_core_sockaddr, poll_interfaces, IpAddr, SocketAddr, TcpSocket,
UdpSocket, NlSocket,
Expand All @@ -20,6 +20,8 @@ use num_enum::TryFromPrimitive;

use crate::TimeVal;

use super::netlink::netlink_unicast;

pub const SOCKET_TYPE_MASK: usize = 0xFF;

#[derive(TryFromPrimitive, Clone)]
Expand Down Expand Up @@ -522,11 +524,11 @@ impl Socket {

/// Bind the socket to the given address.
pub fn bind(&self, addr: SocketAddr) -> AxResult {
let inner = self.inner.lock();
match &*inner {
let mut inner = self.inner.lock();
match &mut *inner {
SocketInner::Tcp(s) => s.bind(into_core_sockaddr(addr.into())),
SocketInner::Udp(s) => s.bind(into_core_sockaddr(addr.into())),
SocketInner::Netlink(_) => todo!(),
SocketInner::Netlink(s) => s.bind(addr.nl_groups),
}
}

Expand Down Expand Up @@ -614,6 +616,7 @@ impl Socket {

/// let the socket receive data and write it to the given buffer
pub fn recv_from(&self, buf: &mut [u8]) -> AxResult<(usize, SocketAddr)> {
netlink_unicast();
let inner = self.inner.lock();
match &*inner {
SocketInner::Tcp(s) => {
Expand All @@ -636,7 +639,10 @@ impl Socket {
.map(|(val, addr)| (val, from_core_sockaddr(addr)))
.map(|(val, sa)| (val, SocketAddr::from(sa))),
},
SocketInner::Netlink(_) => todo!(),
SocketInner::Netlink(s) => {
s.recv_from(buf)
.map(|val| (val, SocketAddr::new_netlink(s.nl_groups)))
},
}
}

Expand Down Expand Up @@ -762,9 +768,12 @@ pub unsafe fn socket_address_from(addr: *const u8) -> SocketAddr {
let a = (*(addr.add(2) as *const u32)).to_le_bytes();

let addr = IpAddr::v4(a[0], a[1], a[2], a[3]);
SocketAddr { addr, port }
SocketAddr::new_ipv4(addr, port)
}
Domain::AF_NETLINK => {
let groups = *(addr.add(4) as *const u32);
SocketAddr::new_netlink(groups)
}
Domain::AF_NETLINK => unimplemented!(),
}
}
/// Only support INET (ipv4)
Expand Down

0 comments on commit 92b6174

Please sign in to comment.