Created
December 8, 2022 02:13
-
-
Save luqmana/710a4461ffeb1905372cba7182ee0db0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(dead_code)] | |
use std::os::fd::AsRawFd; | |
extern "C" { | |
pub fn ioctl(fildes: i32, request: i32, ...) -> i32; | |
} | |
const VNIC_IOC_INFO: i32 = 0x1710003; | |
const MAXMACADDRLEN: usize = 20; | |
const MAXPATHLEN: usize = 1024; | |
const MPT_MAXCID: usize = 32; | |
const MPT_MAXIPADDR: usize = 32; | |
const MPT_MAXCIDLEN: usize = 256; | |
const MRP_NCPUS: usize = 256; | |
#[derive(Copy, Clone, Debug, Default)] | |
#[repr(C)] | |
struct VnicInfoIoc { | |
pub vnic_id: u32, | |
pub link_id: u32, | |
pub mac_addr_type: VnicMacAddrType, | |
pub mac_len: u32, | |
pub mac_addr: [u8; MAXMACADDRLEN], | |
pub mac_slot: u32, | |
pub mac_prefix_len: u32, | |
pub vid: u16, | |
pub vrid: u32, | |
pub af: u32, | |
pub force: bool, | |
pub resource_props: MacResourceProps, | |
} | |
#[derive(Copy, Clone, Debug, Default)] | |
#[repr(i32)] | |
enum VnicMacAddrType { | |
#[default] | |
Unknown = -1, | |
Fixed, | |
Random, | |
Factory, | |
Auto, | |
Primary, | |
Vrid, | |
} | |
#[derive(Copy, Clone, Debug)] | |
#[repr(C, packed(4))] | |
struct MacResourceProps { | |
pub mask: u32, | |
pub maxbw: u64, | |
pub priority: MacPriorityLevel, | |
pub cpus: MacCPUsProps, | |
pub protect: MacProtect, | |
pub nrxrings: u32, | |
pub ntxrings: u32, | |
pub pool: [u8; MAXPATHLEN], | |
} | |
impl Default for MacResourceProps { | |
fn default() -> Self { | |
Self { | |
mask: 0, | |
maxbw: 0, | |
priority: MacPriorityLevel::Low, | |
cpus: MacCPUsProps::default(), | |
protect: MacProtect::default(), | |
nrxrings: 0, | |
ntxrings: 0, | |
pool: [0; MAXPATHLEN], | |
} | |
} | |
} | |
#[derive(Copy, Clone, Debug)] | |
#[repr(i32)] | |
enum MacPriorityLevel { | |
Low, | |
Medium, | |
High, | |
Reset, | |
} | |
#[derive(Copy, Clone, Debug)] | |
#[repr(C)] | |
struct MacCPUsProps { | |
pub ncpus: u32, | |
pub cpus: [u32; MRP_NCPUS], | |
pub rx_fanout_cnt: u32, | |
pub rx_fanout_cpus: [u32; MRP_NCPUS], | |
pub rx_pollid: u32, | |
pub rx_workerid: u32, | |
pub rx_intr_cpu: i32, | |
pub tx_fanout_cpus: [i32; MRP_NCPUS], | |
pub tx_intr_cpus: MacTxIntrCPUs, | |
pub fanout_mode: MacCpuMode, | |
} | |
impl Default for MacCPUsProps { | |
fn default() -> Self { | |
Self { | |
ncpus: 0, | |
cpus: [0; MRP_NCPUS], | |
rx_fanout_cnt: 0, | |
rx_fanout_cpus: [0; MRP_NCPUS], | |
rx_pollid: 0, | |
rx_workerid: 0, | |
rx_intr_cpu: 0, | |
tx_fanout_cpus: [0; MRP_NCPUS], | |
tx_intr_cpus: MacTxIntrCPUs::default(), | |
fanout_mode: MacCpuMode::Fanout, | |
} | |
} | |
} | |
#[derive(Copy, Clone, Debug)] | |
#[repr(C)] | |
struct MacTxIntrCPUs { | |
pub mtc_intr_cpu: [i32; MRP_NCPUS], | |
pub mtc_retargeted_cpu: [i32; MRP_NCPUS], | |
} | |
impl Default for MacTxIntrCPUs { | |
fn default() -> Self { | |
Self { | |
mtc_intr_cpu: [0; MRP_NCPUS], | |
mtc_retargeted_cpu: [0; MRP_NCPUS], | |
} | |
} | |
} | |
#[derive(Copy, Clone, Debug)] | |
#[repr(i32)] | |
enum MacCpuMode { | |
Fanout = 1, | |
Cpus, | |
} | |
#[derive(Copy, Clone, Debug)] | |
#[repr(C)] | |
struct MacProtect { | |
pub types: u32, | |
pub ipaddrcnt: u32, | |
pub ipaddrs: [MacIpaddr; MPT_MAXIPADDR], | |
pub cidcnt: u32, | |
pub cids: [MacDhcpCid; MPT_MAXCID], | |
} | |
impl Default for MacProtect { | |
fn default() -> Self { | |
Self { | |
types: 0, | |
ipaddrcnt: 0, | |
ipaddrs: [MacIpaddr::default(); MPT_MAXIPADDR], | |
cidcnt: 0, | |
cids: [MacDhcpCid::default(); MPT_MAXCID], | |
} | |
} | |
} | |
#[derive(Copy, Clone, Debug, Default)] | |
#[repr(C)] | |
struct MacIpaddr { | |
pub version: u32, | |
pub addr: In6Addr, | |
pub netmask: u8, | |
} | |
#[derive(Copy, Clone, Debug)] | |
#[repr(C)] | |
struct In6Addr { | |
pub data: In6Data, | |
} | |
impl Default for In6Addr { | |
fn default() -> Self { | |
Self { | |
data: In6Data { parts: [0; 8] }, | |
} | |
} | |
} | |
#[repr(C)] | |
union In6Data { | |
pub parts: [u16; 8], | |
pub align: u32, | |
} | |
impl Copy for In6Data {} | |
impl Clone for In6Data { | |
fn clone(&self) -> Self { | |
unsafe { | |
let mut c = In6Data { parts: [0; 8] }; | |
for (i, x) in self.parts.iter().enumerate() { | |
c.parts[i] = *x; | |
} | |
c | |
} | |
} | |
} | |
impl std::fmt::Debug for In6Data { | |
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | |
write!(f, "In6Data {{ parts: {:?} }}", unsafe { self.parts }) | |
} | |
} | |
#[derive(Copy, Clone, Debug)] | |
#[repr(C)] | |
struct MacDhcpCid { | |
pub id: [u8; MPT_MAXCIDLEN], | |
pub len: u32, | |
pub form: MacDhcpCidFrom, | |
} | |
impl Default for MacDhcpCid { | |
fn default() -> Self { | |
Self { | |
id: [0; MPT_MAXCIDLEN], | |
len: 0, | |
form: MacDhcpCidFrom::Typed, | |
} | |
} | |
} | |
#[derive(Copy, Clone, Debug)] | |
#[repr(i32)] | |
enum MacDhcpCidFrom { | |
Typed = 1, | |
Hex, | |
Str, | |
} | |
fn dld_fd() -> Result<std::fs::File, std::io::Error> { | |
std::fs::OpenOptions::new() | |
.read(true) | |
.write(true) | |
.open("/dev/dld") | |
} | |
fn get_vnic_info(link_id: u32) -> Result<VnicInfoIoc, std::io::Error> { | |
let fd = dld_fd()?; | |
unsafe { | |
let arg = VnicInfoIoc { | |
vnic_id: link_id, | |
..Default::default() | |
}; | |
let res = ioctl(fd.as_raw_fd(), VNIC_IOC_INFO, &arg); | |
eprintln!("ioctl returned {res}"); | |
if res == -1 { | |
let err = std::io::Error::last_os_error(); | |
eprintln!("ioctl failed: {err}"); | |
return Err(err); | |
} | |
Ok(arg) | |
} | |
} | |
fn main() { | |
let Some(link) = std::env::args().nth(1) else { | |
eprintln!("Usage: linkinfo <link id>"); | |
std::process::exit(1); | |
}; | |
let Ok(link_id) = link.parse::<u32>() else { | |
eprintln!("invalid link id"); | |
std::process::exit(1); | |
}; | |
match get_vnic_info(link_id) { | |
Ok(info) => { | |
println!("{info:?}"); | |
} | |
Err(err) => { | |
eprintln!("Failed to get vnic info: {err}"); | |
} | |
} | |
} |
Author
luqmana
commented
Dec 8, 2022
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment