Получите MAC -адрес нажатия устройстваLinux

Ответить
Anonymous
 Получите MAC -адрес нажатия устройства

Сообщение Anonymous »

Я создаю устройство Tap, используя интерфейс Tun/Tap, открыв/dev/net/tun . Однако, когда я пытаюсь получить MAC -адрес, используя siocgifhwaddr ioctl call, я получаю неправильный MAC -адрес. Если я сделаю один и тот же звонок еще один или два раза, я в конечном итоге получу «правильный» MAC -адрес, и он придержится этот Mac. Пример вывода из моей программы показан ниже, а также код, используемый для установки/получения свойств интерфейса TAP. Есть ли правильный способ получить Mac устройства, который я не использую? Есть ли способ узнать, когда я получил «правильный»? или быть уведомленным при его изменении?ip link set dev up
[*] get_tap_address

# produced in a tight loop where we read 1 frame from the tap device
# then get the mac address again using get_tap_address
[2025-09-08T03:13:17Z DEBUG teecee] Created new tap device: TapDevice { name: "teecee0", address: ea:dd:cc:40:d1:00 }
[2025-09-08T03:13:17Z DEBUG teecee] Got new frame:
{
dst_mac: 33:33:00:00:00:16,
src_mac: 0e:58:b2:b1:61:35,
ethertype: 0x0086DD,
}
[2025-09-08T03:13:17Z DEBUG teecee] New tap mac: 0e:58:b2:b1:61:35
[2025-09-08T03:13:17Z DEBUG teecee] Got new frame:
{
dst_mac: 33:33:00:00:00:16,
src_mac: 0e:58:b2:b1:61:35,
ethertype: 0x0086DD,
}
[2025-09-08T03:13:17Z DEBUG teecee] New tap mac: 0e:58:b2:b1:61:35
< /code>
fn set_tap_with_name(fd: libc::c_int, name: &CStr) -> Result {
let mut ifreq = Self::ifreq_with_params(
name.to_bytes(),
(libc::IFF_TAP | libc::IFF_NO_PI) as _
);

unsafe {
if libc::ioctl(fd, libc::TUNSETIFF, &mut ifreq as *mut _) < 0 {
return Err(TapError::IoctlSet(std::io::Error::last_os_error()));
}
};

let name_bytes = ifreq.ifr_name.iter()
.map_while(|c| {
if *c != 0 {
Some(*c as u8)
}
else {
None
}
})
.collect::();

String::from_utf8(name_bytes).map_err(TapError::NameUtf8)
}

fn get_tap_address(fd: libc::c_int, name: &String) -> Result {
let mut ifreq = Self::ifreq_with_params(name.as_bytes(), 0);

unsafe {
if libc::ioctl(fd, libc::SIOCGIFHWADDR, &mut ifreq as *mut _) < 0 {
return Err(TapError::IoctlAddrGet(std::io::Error::last_os_error()));
}
};

let hw_addr = unsafe {
let addr = &ifreq.ifr_ifru.ifru_hwaddr.sa_data[..MacAddr::LEN];
std::slice::from_raw_parts(addr.as_ptr() as _, addr.len())
};

let mut addr = MacAddr::new_zeroed();
addr.as_mut_bytes().copy_from_slice(hw_addr);

Ok(addr)
}

fn ifreq_with_params(name: &[u8], flags: i16) -> libc::ifreq {
const MAX_NAME_LEN: usize = 16;
assert!(name.len() < MAX_NAME_LEN);

let name = unsafe {
std::slice::from_raw_parts(name.as_ptr() as _, name.len())
};

let mut ifreq: libc::ifreq;
unsafe {
ifreq = std::mem::zeroed();
ifreq.ifr_name[..name.len()].copy_from_slice(name);
ifreq.ifr_ifru.ifru_flags = flags;
}

ifreq
}


Подробнее здесь: https://stackoverflow.com/questions/797 ... ac-address
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»