123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- use super::*;
- use crate::phy::Medium;
- use std::os::unix::io::{AsRawFd, RawFd};
- use std::{io, mem};
- #[derive(Debug)]
- pub struct RawSocketDesc {
- protocol: libc::c_short,
- lower: libc::c_int,
- ifreq: ifreq,
- }
- impl AsRawFd for RawSocketDesc {
- fn as_raw_fd(&self) -> RawFd {
- self.lower
- }
- }
- impl RawSocketDesc {
- pub fn new(name: &str, medium: Medium) -> io::Result<RawSocketDesc> {
- let protocol = match medium {
- #[cfg(feature = "medium-ethernet")]
- Medium::Ethernet => imp::ETH_P_ALL,
- #[cfg(feature = "medium-ip")]
- Medium::Ip => imp::ETH_P_ALL,
- #[cfg(feature = "medium-ieee802154")]
- Medium::Ieee802154 => imp::ETH_P_IEEE802154,
- };
- let lower = unsafe {
- let lower = libc::socket(
- libc::AF_PACKET,
- libc::SOCK_RAW | libc::SOCK_NONBLOCK,
- protocol.to_be() as i32,
- );
- if lower == -1 {
- return Err(io::Error::last_os_error());
- }
- lower
- };
- Ok(RawSocketDesc {
- protocol,
- lower,
- ifreq: ifreq_for(name),
- })
- }
- pub fn interface_mtu(&mut self) -> io::Result<usize> {
- ifreq_ioctl(self.lower, &mut self.ifreq, imp::SIOCGIFMTU).map(|mtu| mtu as usize)
- }
- pub fn bind_interface(&mut self) -> io::Result<()> {
- let sockaddr = libc::sockaddr_ll {
- sll_family: libc::AF_PACKET as u16,
- sll_protocol: self.protocol.to_be() as u16,
- sll_ifindex: ifreq_ioctl(self.lower, &mut self.ifreq, imp::SIOCGIFINDEX)?,
- sll_hatype: 1,
- sll_pkttype: 0,
- sll_halen: 6,
- sll_addr: [0; 8],
- };
- unsafe {
- let res = libc::bind(
- self.lower,
- &sockaddr as *const libc::sockaddr_ll as *const libc::sockaddr,
- mem::size_of::<libc::sockaddr_ll>() as libc::socklen_t,
- );
- if res == -1 {
- return Err(io::Error::last_os_error());
- }
- }
- Ok(())
- }
- pub fn recv(&mut self, buffer: &mut [u8]) -> io::Result<usize> {
- unsafe {
- let len = libc::recv(
- self.lower,
- buffer.as_mut_ptr() as *mut libc::c_void,
- buffer.len(),
- 0,
- );
- if len == -1 {
- return Err(io::Error::last_os_error());
- }
- Ok(len as usize)
- }
- }
- pub fn send(&mut self, buffer: &[u8]) -> io::Result<usize> {
- unsafe {
- let len = libc::send(
- self.lower,
- buffer.as_ptr() as *const libc::c_void,
- buffer.len(),
- 0,
- );
- if len == -1 {
- return Err(io::Error::last_os_error());
- }
- Ok(len as usize)
- }
- }
- }
- impl Drop for RawSocketDesc {
- fn drop(&mut self) {
- unsafe {
- libc::close(self.lower);
- }
- }
- }
|