Add 'unflatten' to doxygen/dot processing
[senf.git] / Socket / Protocols / Raw / PacketSocketHandle.cc
index 7250c8c..f24e0b1 100644 (file)
@@ -1,9 +1,9 @@
 // $Id$
 //
 // Copyright (C) 2006
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
-//     Stefan Bund <stefan.bund@fokus.fraunhofer.de>
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Bund <g0dil@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /** \file
-    \brief PacketProtocol and PacketSocketHandle non-inline non-template implementation
+    \brief PacketSocketProtocol and PacketSocketHandle non-inline non-template implementation
  */
 
 #include "PacketSocketHandle.hh"
-#include "PacketSocketHandle.ih"
+//#include "PacketSocketHandle.ih"
 
 // Custom includes
 #include <sys/types.h>
@@ -40,7 +40,7 @@
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-prefix_ void senf::PacketProtocol::init_client(SocketType type, int protocol)
+prefix_ void senf::PacketSocketProtocol::init_client(SocketType type, int protocol)
     const
 {
     int socktype = SOCK_RAW;
@@ -50,47 +50,73 @@ prefix_ void senf::PacketProtocol::init_client(SocketType type, int protocol)
         protocol = ETH_P_ALL;
     int sock = ::socket(PF_PACKET, socktype, htons(protocol));
     if (sock < 0)
-        throw SystemException(errno);
-    body().fd(sock);
+        SENF_THROW_SYSTEM_EXCEPTION("::socket(...) failed.");
+    fd(sock);
 }
 
-prefix_ std::auto_ptr<senf::SocketProtocol> senf::PacketProtocol::clone()
+prefix_ unsigned senf::PacketSocketProtocol::available()
     const
 {
-    return std::auto_ptr<SocketProtocol>(new PacketProtocol());
-}
-
-prefix_ unsigned senf::PacketProtocol::available()
-    const
-{
-    if (! body().readable())
+    if (! fh().readable())
         return 0;
-    ssize_t l = ::recv(body().fd(),0,0,MSG_PEEK | MSG_TRUNC);
+    ssize_t l = ::recv(fd(),0,0,MSG_PEEK | MSG_TRUNC);
     if (l < 0)
-        throw SystemException(errno);
+        SENF_THROW_SYSTEM_EXCEPTION("::recv(socket_fd) failed.");
     return l;
 }
 
-prefix_ bool senf::PacketProtocol::eof()
+prefix_ bool senf::PacketSocketProtocol::eof()
     const
 {
     return false;
 }
 
-prefix_ void senf::PacketProtocol::do_mc_i(std::string interface,
-                                                  detail::LLAddressCopier const & copier, bool add)
+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);
+        mreq.mr_type = PACKET_MR_MULTICAST;
+        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)
+            throw senf::SystemException();
+    }
+}
+
+prefix_ void senf::PacketSocketProtocol::mcAdd(std::string const & interface,
+                                         MACAddress const & address)
+    const
+{
+    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);
+}
+
+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 SystemException(EINVAL);
-    mreq.mr_type = PACKET_MR_MULTICAST;
-    mreq.mr_alen = copier(&mreq.mr_address[0]);
-    if (::setsockopt(body().fd(),SOL_PACKET,
-                     add ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP,
+        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 SystemException(errno);
+        throw senf::SystemException();
 }
 
 ///////////////////////////////cc.e////////////////////////////////////////