Browse Source

phy: Use right protocol on RawSocket based on the medium.

Dario Nieuwenhuis 3 years ago
parent
commit
f35e76068b
3 changed files with 20 additions and 19 deletions
  1. 4 2
      src/phy/raw_socket.rs
  2. 2 1
      src/phy/sys/bpf.rs
  3. 14 16
      src/phy/sys/raw_socket.rs

+ 4 - 2
src/phy/raw_socket.rs

@@ -11,6 +11,7 @@ use crate::Result;
 /// A socket that captures or transmits the complete frame.
 #[derive(Debug)]
 pub struct RawSocket {
+    medium: Medium,
     lower: Rc<RefCell<sys::RawSocketDesc>>,
     mtu: usize,
 }
@@ -27,7 +28,7 @@ impl RawSocket {
     /// This requires superuser privileges or a corresponding capability bit
     /// set on the executable.
     pub fn new(name: &str, medium: Medium) -> io::Result<RawSocket> {
-        let mut lower = sys::RawSocketDesc::new(name)?;
+        let mut lower = sys::RawSocketDesc::new(name, medium)?;
         lower.bind_interface()?;
 
         let mut mtu = lower.interface_mtu()?;
@@ -40,6 +41,7 @@ impl RawSocket {
         }
 
         Ok(RawSocket {
+            medium,
             lower: Rc::new(RefCell::new(lower)),
             mtu: mtu,
         })
@@ -53,7 +55,7 @@ impl<'a> Device<'a> for RawSocket {
     fn capabilities(&self) -> DeviceCapabilities {
         DeviceCapabilities {
             max_transmission_unit: self.mtu,
-            medium: Medium::Ethernet,
+            medium: self.medium,
             ..DeviceCapabilities::default()
         }
     }

+ 2 - 1
src/phy/sys/bpf.rs

@@ -5,6 +5,7 @@ use std::os::unix::io::{AsRawFd, RawFd};
 use libc;
 
 use super::{ifreq, ifreq_for};
+use crate::phy::Medium;
 use crate::wire::ETHERNET_HEADER_LEN;
 
 /// set interface
@@ -67,7 +68,7 @@ fn open_device() -> io::Result<libc::c_int> {
 }
 
 impl BpfDevice {
-    pub fn new(name: &str) -> io::Result<BpfDevice> {
+    pub fn new(name: &str, _medium: Medium) -> io::Result<BpfDevice> {
         Ok(BpfDevice {
             fd: open_device()?,
             ifreq: ifreq_for(name),

+ 14 - 16
src/phy/sys/raw_socket.rs

@@ -1,10 +1,12 @@
 use super::*;
+use crate::phy::Medium;
 use crate::wire::EthernetFrame;
 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,
 }
@@ -16,15 +18,17 @@ impl AsRawFd for RawSocketDesc {
 }
 
 impl RawSocketDesc {
-    pub fn new(name: &str) -> io::Result<RawSocketDesc> {
-        let lower = unsafe {
-            // TODO(thvdveld)
-            //#[cfg(feature = "medium-ieee802154")]
-            //let protocol = imp::ETH_P_IEEE802154;
-
+    pub fn new(name: &str, medium: Medium) -> io::Result<RawSocketDesc> {
+        let protocol = match medium {
             #[cfg(feature = "medium-ethernet")]
-            let protocol = imp::ETH_P_ALL;
+            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,
@@ -37,7 +41,8 @@ impl RawSocketDesc {
         };
 
         Ok(RawSocketDesc {
-            lower: lower,
+            protocol,
+            lower,
             ifreq: ifreq_for(name),
         })
     }
@@ -51,16 +56,9 @@ impl RawSocketDesc {
     }
 
     pub fn bind_interface(&mut self) -> io::Result<()> {
-        // TODO(thvdveld)
-        //#[cfg(feature = "medium-ieee802154")]
-        //let protocol = imp::ETH_P_IEEE802154;
-
-        #[cfg(feature = "medium-ethernet")]
-        let protocol = imp::ETH_P_ALL;
-
         let sockaddr = libc::sockaddr_ll {
             sll_family: libc::AF_PACKET as u16,
-            sll_protocol: protocol.to_be() 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,