Fix Build-Depends in debian/control
[senf.git] / Socket / Protocols / Raw / PacketSocketHandle.cc
index 54345f1..f24e0b1 100644 (file)
@@ -50,7 +50,7 @@ prefix_ void senf::PacketSocketProtocol::init_client(SocketType type, int protoc
         protocol = ETH_P_ALL;
     int sock = ::socket(PF_PACKET, socktype, htons(protocol));
     if (sock < 0)
-        throw SystemException();
+        SENF_THROW_SYSTEM_EXCEPTION("::socket(...) failed.");
     fd(sock);
 }
 
@@ -61,7 +61,7 @@ prefix_ unsigned senf::PacketSocketProtocol::available()
         return 0;
     ssize_t l = ::recv(fd(),0,0,MSG_PEEK | MSG_TRUNC);
     if (l < 0)
-        throw SystemException();
+        SENF_THROW_SYSTEM_EXCEPTION("::recv(socket_fd) failed.");
     return l;
 }
 
@@ -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////////////////////////////////////////