From ddd780e67a619152eafd4eb6191dde15eb99464f Mon Sep 17 00:00:00 2001
From: tho <tho@wiback.org>
Date: Thu, 26 Mar 2009 16:16:42 +0000
Subject: [PATCH] Socket/Protocols/Raw/PacketSocketHandle: added promisc()
 method

---
 Socket/Protocols/Raw/PacketSocketHandle.cc    | 25 +++++++++++++++----
 Socket/Protocols/Raw/PacketSocketHandle.hh    |  3 +++
 .../Protocols/Raw/PacketSocketHandle.test.cc  |  7 ++++--
 3 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/Socket/Protocols/Raw/PacketSocketHandle.cc b/Socket/Protocols/Raw/PacketSocketHandle.cc
index 224b469b3..f24e0b1b7 100644
--- a/Socket/Protocols/Raw/PacketSocketHandle.cc
+++ b/Socket/Protocols/Raw/PacketSocketHandle.cc
@@ -76,6 +76,7 @@ namespace {
     void do_mc(int fd, std::string const & interface, senf::MACAddress address, bool add)
     {
         struct packet_mreq mreq;
+        ::memset(&mreq, 0, sizeof(mreq));
         mreq.mr_ifindex = ::if_nametoindex(interface.c_str());
         if (mreq.mr_ifindex == 0)
             throw senf::SystemException(EINVAL);
@@ -83,25 +84,39 @@ namespace {
         mreq.mr_alen = 6;
         std::copy(address.begin(), address.end(), &mreq.mr_address[0]);
         if (::setsockopt(fd, SOL_PACKET,
-                         add ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP,
-                         &mreq, sizeof(mreq)) < 0)
+                        add ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP,
+                        &mreq, sizeof(mreq)) < 0)
             throw senf::SystemException();
     }
-
 }
 
 prefix_ void senf::PacketSocketProtocol::mcAdd(std::string const & interface,
                                          MACAddress const & address)
     const
 {
-    do_mc(fd(),interface,address,true);
+    do_mc(fd(), interface, address, true);
 }
 
 prefix_ void senf::PacketSocketProtocol::mcDrop(std::string const & interface,
                                           MACAddress const & address)
     const
 {
-    do_mc(fd(),interface,address,false);
+    do_mc(fd(), interface, address, false);
+}
+
+prefix_ void senf::PacketSocketProtocol::promisc(std::string const & interface, bool mode)
+    const
+{
+    struct packet_mreq mreq;
+    ::memset(&mreq, 0, sizeof(mreq));
+    mreq.mr_ifindex = ::if_nametoindex(interface.c_str());
+    if (mreq.mr_ifindex == 0)
+        throw senf::SystemException(EINVAL);
+    mreq.mr_type = PACKET_MR_PROMISC;
+    if (::setsockopt(fd(), SOL_PACKET,
+                     mode ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP,
+                     &mreq, sizeof(mreq)) < 0)
+        throw senf::SystemException();
 }
 
 ///////////////////////////////cc.e////////////////////////////////////////
diff --git a/Socket/Protocols/Raw/PacketSocketHandle.hh b/Socket/Protocols/Raw/PacketSocketHandle.hh
index 3cae497a0..35898ac11 100644
--- a/Socket/Protocols/Raw/PacketSocketHandle.hh
+++ b/Socket/Protocols/Raw/PacketSocketHandle.hh
@@ -122,6 +122,9 @@ namespace senf {
                                         ///< Disable reception of a multicast group
                                         /**< \see \ref mcAdd() */
 
+        void promisc(std::string const & interface, bool mode) const;  
+                                        ///< enable/disable promiscuous mode
+
         ///@}
 
         ///\name Abstract Interface Implementation
diff --git a/Socket/Protocols/Raw/PacketSocketHandle.test.cc b/Socket/Protocols/Raw/PacketSocketHandle.test.cc
index e83a93ddc..78d547612 100644
--- a/Socket/Protocols/Raw/PacketSocketHandle.test.cc
+++ b/Socket/Protocols/Raw/PacketSocketHandle.test.cc
@@ -56,10 +56,13 @@ BOOST_AUTO_UNIT_TEST(packetSocketHandle)
         // How am I supposed to test read and write .. grmpf ..
 
         SENF_CHECK_NO_THROW( sock.protocol().mcAdd(
-                                  "eth0",senf::MACAddress::from_string("01-02-03-04-05-06")) );
+                "eth0", senf::MACAddress::from_string("01-02-03-04-05-06")) );
         SENF_CHECK_NO_THROW( sock.protocol().mcDrop(
-                                  "eth0",senf::MACAddress::from_string("01-02-03-04-05-06")) );
+                "eth0", senf::MACAddress::from_string("01-02-03-04-05-06")) );
 
+        SENF_CHECK_NO_THROW( sock.protocol().promisc( "eth0", true) );
+        SENF_CHECK_NO_THROW( sock.protocol().promisc( "eth0", false));
+                
         SENF_CHECK_NO_THROW( sock.protocol().available() );
         BOOST_CHECK( ! sock.eof() );
     }
-- 
GitLab