1
0
mirror of https://github.com/danog/libdvb.git synced 2024-12-02 09:17:54 +01:00

net: read mac on open

This commit is contained in:
Andrey Dyldin 2021-03-04 14:10:54 +02:00
parent 21712ee95e
commit 0b23424405
2 changed files with 44 additions and 32 deletions

View File

@ -22,12 +22,7 @@ fn check_net(path: &Path) -> Result<()> {
dev.add_if(&mut info)?; dev.add_if(&mut info)?;
println!("Interface: {}", dev.get_name()); println!("Interface: {}", dev.get_name());
println!("MAC: {}", dev.get_mac());
let mac = match dev.get_mac() {
Ok(v) => v,
Err(e) => e.to_string(),
};
println!("MAC: {}", mac);
dev.remove_if(&info)?; dev.remove_if(&info)?;

View File

@ -48,6 +48,9 @@ use {
}; };
pub const EMPTY_MAC: &str = "00:00:00:00:00:00";
/// A reference to the network device /// A reference to the network device
#[derive(Debug)] #[derive(Debug)]
pub struct NetDevice { pub struct NetDevice {
@ -55,6 +58,9 @@ pub struct NetDevice {
/// Interface name /// Interface name
name: String, name: String,
/// MAC address
mac: String,
} }
@ -64,6 +70,38 @@ impl AsRawFd for NetDevice {
} }
fn read_interface_name<T: AsRawFd>(file: &T) -> Result<String> {
let s = fstat(file.as_raw_fd())?;
let path = format!("/sys/dev/char/{}:{}", major(s.st_rdev), minor(s.st_rdev));
let name = readlink(path.as_str())?
.to_str()
.unwrap_or_default()
.rsplit('/')
.next()
.unwrap_or_default()
.split(".net")
.collect::<Vec<&str>>()
.join("_");
Ok(name)
}
fn read_mac_address(name: &str) -> Result<String> {
ensure!(name.starts_with("dvb"), "incorrect interface name");
let len = 2 * 6 + 5;
let mut mac = String::with_capacity(len);
let path = format!("/sys/class/net/{}/address", name);
let file = File::open(&path)?;
file.take(len as u64).read_to_string(&mut mac)?;
Ok(mac)
}
impl NetDevice { impl NetDevice {
/// Attempts to open a network device in read-write mode /// Attempts to open a network device in read-write mode
pub fn open<P: AsRef<Path>>(path: P) -> Result<NetDevice> { pub fn open<P: AsRef<Path>>(path: P) -> Result<NetDevice> {
@ -74,25 +112,13 @@ impl NetDevice {
.open(path) .open(path)
.context("NET: open")?; .context("NET: open")?;
let s = fstat(file.as_raw_fd())?; let name = read_interface_name(&file).context("NET: read interface name")?;
let sys_path = format!( let mac = read_mac_address(&name).unwrap_or_else(|_| EMPTY_MAC.to_owned());
"/sys/dev/char/{}:{}",
major(s.st_rdev),
minor(s.st_rdev)
);
let name = readlink(sys_path.as_str())?
.to_str()
.unwrap_or_default()
.rsplit('/')
.next()
.unwrap_or_default()
.split(".net")
.collect::<Vec<&str>>()
.join("_");
let net = NetDevice { let net = NetDevice {
file, file,
name, name,
mac,
}; };
Ok(net) Ok(net)
@ -102,17 +128,8 @@ impl NetDevice {
/// and `{1}` is a device number /// and `{1}` is a device number
pub fn get_name(&self) -> &str { self.name.as_str() } pub fn get_name(&self) -> &str { self.name.as_str() }
/// Reads and returns interface MAC address /// Returns interface MAC address
pub fn get_mac(&self) -> Result<String> { pub fn get_mac(&self) -> &str { self.mac.as_str() }
let path = format!("/sys/class/net/{}/address", self.get_name());
let len = 2 * 6 + 5;
let file = File::open(&path)?;
let mut result = String::with_capacity(len);
file.take(2 * 6 + 5).read_to_string(&mut result)?;
Ok(result)
}
/// Creates a new network interface /// Creates a new network interface
pub fn add_if(&self, data: &mut DvbNetIf) -> Result<()> { pub fn add_if(&self, data: &mut DvbNetIf) -> Result<()> {