123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- use alloc::{
- boxed::Box,
- slice,
- sync::{Arc, Weak},
- vec::Vec,
- };
- use system_error::SystemError;
- use crate::libs::mutex::Mutex;
- use core::mem;
- use super::af_netlink::{
- netlink_insert, Listeners, NetlinkFlags, NetlinkSock, NetlinkSocket, NL_TABLE,
- };
- pub const NETLINK_ROUTE: usize = 0;
- pub const NETLINK_UNUSED: usize = 1;
- pub const NETLINK_USERSOCK: usize = 2;
- pub const NETLINK_FIREWALL: usize = 3;
- pub const NETLINK_SOCK_DIAG: usize = 4;
- pub const NETLINK_NFLOG: usize = 5;
- pub const NETLINK_XFRM: usize = 6;
- pub const NETLINK_SELINUX: usize = 7;
- pub const NETLINK_ISCSI: usize = 8;
- pub const NETLINK_AUDIT: usize = 9;
- pub const NETLINK_FIB_LOOKUP: usize = 10;
- pub const NETLINK_CONNECTOR: usize = 11;
- pub const NETLINK_NETFILTER: usize = 12;
- pub const NETLINK_IP6_FW: usize = 13;
- pub const NETLINK_DNRTMSG: usize = 14;
- pub const NETLINK_KOBJECT_UEVENT: usize = 15;
- pub const NETLINK_GENERIC: usize = 16;
- pub const NETLINK_SCSITRANSPORT: usize = 18;
- pub const NETLINK_ECRYPTFS: usize = 19;
- pub const NETLINK_RDMA: usize = 20;
- pub const NETLINK_CRYPTO: usize = 21;
- pub const NETLINK_SMC: usize = 22;
- pub const NETLINK_INET_DIAG: usize = 4;
- pub const MAX_LINKS: usize = 32;
- pub const NL_CFG_F_NONROOT_RECV: u32 = 1 << 0;
- pub const NL_CFG_F_NONROOT_SEND: u32 = 1 << 1;
- bitflags! {
- pub struct NLmsgType: u8 {
-
- const NLMSG_NOOP = 0x1;
-
- const NLMSG_ERROR = 0x2;
-
- const NLMSG_DONE = 0x3;
-
- const NLMSG_OVERRUN = 0x4;
- }
- pub struct NLmsgFlags: u16 {
-
- const NLM_F_REQUEST = 0x01;
- const NLM_F_MULTI = 0x02;
- const NLM_F_ACK = 0x04;
- const NLM_F_ECHO = 0x08;
- const NLM_F_DUMP_INTR = 0x10;
- const NLM_F_DUMP_FILTERED = 0x20;
-
- const NLM_F_ROOT = 0x100;
- const NLM_F_MATCH = 0x200;
- const NLM_F_ATOMIC = 0x400;
-
- const NLM_F_DUMP = 0x100 | 0x200;
-
- const NLM_F_REPLACE = 0x100;
- const NLM_F_EXCL = 0x200;
- const NLM_F_CREATE = 0x400;
- const NLM_F_APPEND = 0x800;
-
- const NLM_F_NONREC = 0x100;
-
- const NLM_F_CAPPED = 0x100;
- const NLM_F_ACK_TLVS = 0x200;
- }
- }
- pub struct NLmsghdr {
- pub nlmsg_len: usize,
- pub nlmsg_type: NLmsgType,
- pub nlmsg_flags: NLmsgFlags,
- pub nlmsg_seq: u32,
- pub nlmsg_pid: u32,
- }
- const NLMSG_ALIGNTO: usize = 4;
- #[derive(Debug, PartialEq, Copy, Clone)]
- pub enum NetlinkState {
- NetlinkUnconnected = 0,
- NetlinkConnected,
- NETLINK_S_CONGESTED = 2,
- }
- fn nlmsg_align(len: usize) -> usize {
- (len + NLMSG_ALIGNTO - 1) & !(NLMSG_ALIGNTO - 1)
- }
- fn nlmsg_hdrlen() -> usize {
- nlmsg_align(mem::size_of::<NLmsghdr>())
- }
- fn nlmsg_length(len: usize) -> usize {
- len + nlmsg_hdrlen()
- }
- fn nlmsg_space(len: usize) -> usize {
- nlmsg_align(nlmsg_length(len))
- }
- unsafe fn nlmsg_data(nlh: &NLmsghdr) -> *mut u8 {
- ((nlh as *const NLmsghdr) as *mut u8).add(nlmsg_length(0))
- }
- unsafe fn nlmsg_next(nlh: *mut NLmsghdr, len: usize) -> *mut NLmsghdr {
- let nlmsg_len = (*nlh).nlmsg_len;
- let new_len = len - nlmsg_align(nlmsg_len);
- nlh.add(nlmsg_align(nlmsg_len))
- }
- fn nlmsg_ok(nlh: &NLmsghdr, len: usize) -> bool {
- len >= nlmsg_hdrlen() && nlh.nlmsg_len >= nlmsg_hdrlen() && nlh.nlmsg_len <= len
- }
- fn nlmsg_payload(nlh: &NLmsghdr, len: usize) -> usize {
- nlh.nlmsg_len - nlmsg_space(len)
- }
- type InputCallback = Arc<dyn FnMut() + Send + Sync>;
- type BindCallback = Arc<dyn Fn(i32) -> i32 + Send + Sync>;
- type UnbindCallback = Arc<dyn Fn(i32) -> i32 + Send + Sync>;
- type CompareCallback = Arc<dyn Fn(&NetlinkSock) -> bool + Send + Sync>;
- #[derive(Default)]
- pub struct NetlinkKernelCfg {
- pub groups: u32,
- pub flags: u32,
- pub input: Option<InputCallback>,
- pub bind: Option<BindCallback>,
- pub unbind: Option<UnbindCallback>,
- pub compare: Option<CompareCallback>,
- }
- impl NetlinkKernelCfg {
- pub fn new() -> Self {
- NetlinkKernelCfg {
- groups: 32,
- flags: 0,
- input: None,
- bind: None,
- unbind: None,
- compare: None,
- }
- }
- pub fn set_input<F>(&mut self, callback: F)
- where
- F: FnMut() + Send + Sync + 'static,
- {
- self.input = Some(Arc::new(callback));
- }
- pub fn set_bind<F>(&mut self, callback: F)
- where
- F: Fn(i32) -> i32 + Send + Sync + 'static,
- {
- self.bind = Some(Arc::new(callback));
- }
- pub fn set_unbind<F>(&mut self, callback: F)
- where
- F: Fn(i32) -> i32 + Send + Sync + 'static,
- {
- self.unbind = Some(Arc::new(callback));
- }
- pub fn set_compare<F>(&mut self, callback: F)
- where
- F: Fn(&NetlinkSock) -> bool + Send + Sync + 'static,
- {
- self.compare = Some(Arc::new(callback));
- }
- }
- struct NLattr {
- nla_len: u16,
- nla_type: u16,
- }
- pub trait VecExt {
- fn align4(&mut self);
- fn push_ext<T: Sized>(&mut self, data: T);
- fn set_ext<T: Sized>(&mut self, offset: usize, data: T);
- }
- impl VecExt for Vec<u8> {
- fn align4(&mut self) {
- let len = (self.len() + 3) & !3;
- if len > self.len() {
- self.resize(len, 0);
- }
- }
- fn push_ext<T: Sized>(&mut self, data: T) {
- #[allow(unsafe_code)]
- let bytes =
- unsafe { slice::from_raw_parts(&data as *const T as *const u8, size_of::<T>()) };
- for byte in bytes {
- self.push(*byte);
- }
- }
- fn set_ext<T: Sized>(&mut self, offset: usize, data: T) {
- if self.len() < offset + size_of::<T>() {
- self.resize(offset + size_of::<T>(), 0);
- }
- #[allow(unsafe_code)]
- let bytes =
- unsafe { slice::from_raw_parts(&data as *const T as *const u8, size_of::<T>()) };
- self[offset..(bytes.len() + offset)].copy_from_slice(bytes);
- }
- }
- pub fn netlink_kernel_create(
- unit: usize,
- cfg: Option<NetlinkKernelCfg>,
- ) -> Result<NetlinkSock, SystemError> {
-
- let mut nlk: NetlinkSock = NetlinkSock::new();
- let sk: Arc<Mutex<Box<dyn NetlinkSocket>>> = Arc::new(Mutex::new(Box::new(nlk.clone())));
- let groups: u32;
- if unit >= MAX_LINKS {
- return Err(SystemError::EINVAL);
- }
- __netlink_create(&mut nlk, unit, 1).expect("__netlink_create failed");
- if let Some(cfg) = cfg.as_ref() {
- if cfg.groups < 32 {
- groups = 32;
- } else {
- groups = cfg.groups;
- }
- } else {
- groups = 32;
- }
- let listeners = Listeners::new();
-
-
-
-
-
- netlink_insert(sk, 0).expect("netlink_insert failed");
- nlk.flags |= NetlinkFlags::NETLINK_F_KERNEL_SOCKET.bits();
- let mut nl_table = NL_TABLE.write();
- if nl_table[unit].get_registered() == 0 {
- nl_table[unit].set_groups(groups);
- if let Some(cfg) = cfg.as_ref() {
- nl_table[unit].bind = cfg.bind.clone();
- nl_table[unit].unbind = cfg.unbind.clone();
- nl_table[unit].set_flags(cfg.flags);
- if cfg.compare.is_some() {
- nl_table[unit].compare = cfg.compare.clone();
- }
- nl_table[unit].set_registered(1);
- } else {
- drop(listeners);
- let registered = nl_table[unit].get_registered();
- nl_table[unit].set_registered(registered + 1);
- }
- }
- return Ok(nlk);
- }
- fn __netlink_create(nlk: &mut NetlinkSock, unit: usize, kern: usize) -> Result<i32, SystemError> {
-
- nlk.flags = kern as u32;
- nlk.protocol = unit;
- return Ok(0);
- }
- pub fn sk_data_ready(nlk: Arc<NetlinkSock>) -> Result<(), SystemError> {
-
- return Ok(());
- }
|