From: g0dil Date: Wed, 25 Jul 2007 16:13:59 +0000 (+0000) Subject: Socket/Protocols/Raw: Migrate LLSocketAddress to use MACAddress X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=cd019de7e5d80122a302577c1907e2a952249260;p=senf.git Socket/Protocols/Raw: Migrate LLSocketAddress to use MACAddress git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@353 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Socket/Protocols/Raw/LLAddressing.cc b/Socket/Protocols/Raw/LLAddressing.cc index c5d5c00..13038c3 100644 --- a/Socket/Protocols/Raw/LLAddressing.cc +++ b/Socket/Protocols/Raw/LLAddressing.cc @@ -25,7 +25,7 @@ */ #include "LLAddressing.hh" -#include "LLAddressing.ih" +//#include "LLAddressing.ih" // Custom includes #include @@ -40,17 +40,6 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -prefix_ unsigned char senf::detail::hexnibble(char c) -{ - if (c>='0' && c<='9') - return c - '0'; - if (c>='A' && c<='F') - return c - 'A' + 10; - if (c>='a' && c<='f') - return c - 'a' + 10; - throw InvalidLLSocketAddressException(); -} - prefix_ std::string senf::LLSocketAddress::interface() const { @@ -62,63 +51,17 @@ prefix_ std::string senf::LLSocketAddress::interface() return std::string(name); } -/* -{ - if (addr_.sll_halen == 0) - return std::string(); - std::stringstream s; - - unsigned char const * i = &addr_.sll_addr[0]; - while (1) { - s << std::hex << std::setw(2) << std::setfill('0') << unsigned(*i); - ++i; - if (i == &addr_.sll_addr[addr_.sll_halen]) break; - s << '-'; - } - return s.str(); -} -*/ - - -/* -prefix_ void senf::LLSocketAddress::address(std::string address) -{ - typedef boost::split_iterator StringSplitIterator; - StringSplitIterator i = boost::make_split_iterator(address, boost::token_finder(boost::is_any_of("-: "))); - unsigned char * j = &addr_.sll_addr[0]; - for (; ! i.eof() && addr_.sll_halen<8; ++i, ++j, ++addr_.sll_halen) { - if ( i->size() != 2 || ! boost::all(*i, boost::is_xdigit()) ) - throw InvalidLLSocketAddressException(); - *j = hex(*i); - } - if (! i.eof()) - throw InvalidLLSocketAddressException(); -} -*/ - -prefix_ void senf::LLSocketAddress::interface(std::string interface) +prefix_ void senf::LLSocketAddress::interface(std::string iface) { - if (! interface.empty()) { - addr_.sll_ifindex = if_nametoindex(interface.c_str()); + if (iface.empty()) + addr_.sll_ifindex = 0; + else { + addr_.sll_ifindex = if_nametoindex(iface.c_str()); if (addr_.sll_ifindex == 0) throw InvalidLLSocketAddressException(); } } - -prefix_ senf::detail::LLAddressFromStringRange -senf::llAddress(std::string address) -{ - detail::StringSplitIterator i = - boost::make_split_iterator(address, boost::token_finder(boost::is_any_of("-: "))); - detail::StringSplitIterator i_end; - - detail::HexSplitIterator j (i,detail::HexConverter()); - detail::HexSplitIterator j_end (i_end); - - return detail::LLAddressFromStringRange(j,j_end); -} - ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "LLAddressing.mpp" diff --git a/Socket/Protocols/Raw/LLAddressing.cci b/Socket/Protocols/Raw/LLAddressing.cci index 93deeb3..0084c20 100644 --- a/Socket/Protocols/Raw/LLAddressing.cci +++ b/Socket/Protocols/Raw/LLAddressing.cci @@ -36,17 +36,25 @@ prefix_ senf::LLSocketAddress::LLSocketAddress() clear(); } -prefix_ senf::LLSocketAddress::LLSocketAddress(unsigned protocol, std::string interface) +prefix_ senf::LLSocketAddress::LLSocketAddress(unsigned prot, std::string const & iface) { clear(); - this->protocol(protocol); - this->interface(interface); + protocol(prot); + interface(iface); } -prefix_ senf::LLSocketAddress::LLSocketAddress(std::string interface) +prefix_ senf::LLSocketAddress::LLSocketAddress(std::string const &iface) { clear(); - this->interface(interface); + interface(iface); +} + +prefix_ senf::LLSocketAddress::LLSocketAddress(MACAddress const & addr, + std::string const & iface) +{ + clear(); + address(addr); + interface(iface); } prefix_ void senf::LLSocketAddress::clear() @@ -64,28 +72,29 @@ prefix_ unsigned senf::LLSocketAddress::protocol() prefix_ unsigned senf::LLSocketAddress::arptype() const { - /** \todo make sure, that the value really is in network byte - order */ return ntohs(addr_.sll_hatype); } -prefix_ unsigned senf::LLSocketAddress::pkttype() +prefix_ senf::LLSocketAddress::PktType senf::LLSocketAddress::pkttype() const { - /** \todo make sure, that the value really is in network byte - order */ - return ntohs(addr_.sll_pkttype); + return PktType(ntohs(addr_.sll_pkttype)); } -prefix_ senf::LLSocketAddress::LLAddress senf::LLSocketAddress::address() +prefix_ senf::MACAddress senf::LLSocketAddress::address() const { - return LLAddress(&addr_.sll_addr[0], &addr_.sll_addr[addr_.sll_halen]); + return MACAddress::from_data(&addr_.sll_addr[0]); +} + +prefix_ void senf::LLSocketAddress::address(MACAddress const & addr) +{ + std::copy(addr.begin(), addr.end(),&addr_.sll_addr[0]); } -prefix_ void senf::LLSocketAddress::protocol(unsigned protocol) +prefix_ void senf::LLSocketAddress::protocol(unsigned prot) { - addr_.sll_protocol = htons(protocol); + addr_.sll_protocol = htons(prot); } prefix_ struct sockaddr * senf::LLSocketAddress::sockaddr_p() diff --git a/Socket/Protocols/Raw/LLAddressing.ct b/Socket/Protocols/Raw/LLAddressing.ct deleted file mode 100644 index 52130e3..0000000 --- a/Socket/Protocols/Raw/LLAddressing.ct +++ /dev/null @@ -1,93 +0,0 @@ -// $Id$ -// -// Copyright (C) 2006 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund -// -// 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 -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -/** \file - \brief LLSocketAddress and LLAddressingPolicy non-inline template implementation - */ - -#include "LLAddressing.ih" - -// Custom includes -#include -#include -#include - -#define prefix_ -///////////////////////////////ct.p//////////////////////////////////////// - -template -prefix_ void senf::LLSocketAddress::address(ForwardRange const & address) -{ - if (boost::size(address) > sizeof(addr_.sll_addr)) - throw InvalidLLSocketAddressException(); - typename boost::range_const_iterator::type i (boost::begin(address)); - ::memset(&addr_.sll_addr[0],sizeof(addr_.sll_addr),0); - addr_.sll_halen = 0; - for (; i != boost::end(address) && addr_.sll_halen<8; ++i, ++addr_.sll_halen) - addr_.sll_addr[addr_.sll_halen] = *i; - if (i != boost::end(address)) - throw InvalidLLSocketAddressException(); -} - -template -prefix_ std::string -senf::llAddress(ForwardRange const & address, - typename boost::enable_if< boost::is_class >::type *) -{ - if (boost::empty(address)) - return std::string(); - std::stringstream s; - typename boost::range_const_iterator< ForwardRange >::type i (boost::begin(address)); - while (1) { - s << std::hex << std::setw(2) << std::setfill('0') << unsigned(*i); - ++ i; - if (i == boost::end(address)) - break; - s << '-'; - } - return s.str(); -} - -template -prefix_ unsigned char senf::detail::HexConverter::operator()(ForwardRange const & v) - const -{ - if (boost::size(v) != 2) - throw InvalidLLSocketAddressException(); - typename boost::range_iterator< ForwardRange >::type i (boost::begin(v)); - unsigned char n1 = hexnibble(*i) << 4; - return n1 + hexnibble(*(++i)); -} - -///////////////////////////////ct.e//////////////////////////////////////// -#undef prefix_ - - -// Local Variables: -// mode: c++ -// fill-column: 100 -// c-file-style: "senf" -// indent-tabs-mode: nil -// ispell-local-dictionary: "american" -// compile-command: "scons -u test" -// comment-column: 40 -// End: diff --git a/Socket/Protocols/Raw/LLAddressing.cti b/Socket/Protocols/Raw/LLAddressing.cti deleted file mode 100644 index c401343..0000000 --- a/Socket/Protocols/Raw/LLAddressing.cti +++ /dev/null @@ -1,64 +0,0 @@ -// $Id$ -// -// Copyright (C) 2006 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund -// -// 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 -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -/** \file - \brief LLSocketAddress and LLAddressingPolicy inline template implementation - */ - -#include "LLAddressing.ih" - -// Custom includes -#include // for std::copy - -#define prefix_ inline -///////////////////////////////cti.p/////////////////////////////////////// - -#ifndef DOXYGEN -template -prefix_ senf::LLSocketAddress:: -LLSocketAddress(ForwardRange const & address, std::string interface, - typename boost::enable_if_c::value >::type *) -{ - clear(); - this->address(address); - this->interface(interface); -} -#else -template -prefix_ senf::LLSocketAddress:: -LLSocketAddress(ForwardRange const & address, std::string interface) -{} -#endif - -///////////////////////////////cti.e/////////////////////////////////////// -#undef prefix_ - - -// Local Variables: -// mode: c++ -// fill-column: 100 -// c-file-style: "senf" -// indent-tabs-mode: nil -// ispell-local-dictionary: "american" -// compile-command: "scons -u test" -// comment-column: 40 -// End: diff --git a/Socket/Protocols/Raw/LLAddressing.hh b/Socket/Protocols/Raw/LLAddressing.hh index 9e1cf68..bed2c13 100644 --- a/Socket/Protocols/Raw/LLAddressing.hh +++ b/Socket/Protocols/Raw/LLAddressing.hh @@ -28,19 +28,15 @@ #define HH_LLAddressing_ 1 // Custom includes -#include -#include -#include - #include #include - #include "Socket/SocketPolicy.hh" #include "Socket/FileHandle.hh" #include "Socket/Protocols/GenericAddressingPolicy.hh" +#include "MACAddress.hh" //#include "LLAddressing.mpp" -#include "LLAddressing.ih" +//#include "LLAddressing.ih" ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { @@ -50,102 +46,78 @@ namespace senf { /** \brief Link local address - LLSocketAddress wraps the standard sockaddr_ll datatype. - - \todo I don't think the current implementation is - sensible. I'll have to reimplement this class probably - from scratch. - - \implementation The class relies uses a very flexible - 'ForwardRange' representation for a raw ll - address (See Boost.Range). - This representation allows zero-copy implementations of - many operations, however it is probably not worth the - effort since the ll address is restricted to a max of 8 - bytes. Therefore this will be changed and the concrete - implementation is not documented very well ... + LLSocketAddress wraps the standard sockaddr_ll data type. An LLSocketAddress provides quite + some information, only part of which is necessary for sending packets. The LLSocketAddress + class only allows changing those fields which need to be changed. The other fields are + read-only. They are filled by the operating system when receiving a packet + */ class LLSocketAddress { public: - // Right now we use an arbitrary ForwardRange (see Boost.Range) - // as the representation for a hardware address. The restrictions - // for the range are: - // a) the range must never be larger than 8 elements - // b) the value_type must be convertible to unsigned char - // and really we need only a single-pass range. - // - // Since a hardware address is so short (a maximum of 8 - // bytes), in the aftermath I think a simple container holding - // a maximum of 8 unsigned chars (e.g. Boost.Array with - // additional length parameter) will be much simpler and - // probably even more efficient. This should have a conversion - // constructor from an arbitrary ForwardRange to make it - // compatible e.g. with the Packet library. - // - // However, since I have implemented it already as it is now, - // I'll leave it as it is ... - - typedef boost::iterator_range LLAddress; - - LLSocketAddress(); - // And this is for bind - explicit LLSocketAddress(unsigned protocol, std::string interface=""); - explicit LLSocketAddress(std::string interface); - // This is for sending packets .. - // We must use enable_if here, so this constructor will not hide - // above constructor if passed a plain int or short argument -# ifndef DOXYGEN - template - explicit LLSocketAddress(ForwardRange const & address, std::string interface="", - typename boost::enable_if_c::value >::type * = 0); -# else - template - explicit LLSocketAddress(ForwardRange const & address, std::string interface=""); -# endif - - void clear(); - - unsigned protocol() const; - std::string interface() const; - unsigned arptype() const; - unsigned pkttype() const; - LLAddress address() const; + /** \brief Valid pkttype() values + + These are the possible values returned by arptype() + */ + enum PktType { Undefined = 0 + , Host = PACKET_HOST /**< Packet destined for this host */ + , Broadcast = PACKET_BROADCAST /**< Packet sent to the broadcast address */ + , Multicast = PACKET_MULTICAST /**< Packet sent to a (link local) multicast + address */ + , OtherHost = PACKET_OTHERHOST /**< Packet sent to another host (promisc) */ + , Outgoing = PACKET_OUTGOING /**< Packet sent out from this host */ + }; + + LLSocketAddress(); ///< Create empty address + explicit LLSocketAddress(unsigned proto, std::string const & iface=""); + ///< Create address for \c bind() + /**< This constructs an LLSocketAddress valid for calling + PacketSocketHandle::bind() with. + \param[in] prot Protocol (Ethertype) to listen for + \param[in] iface Interface name to bind to */ + explicit LLSocketAddress(std::string const &iface); + ///< Create address for \c bind() + /**< This constructs an LLSocketAddress valid for calling + \c PacketSocketHandle::bind() with. + \param[in] iface Interface name to bind to */ + + // This constructor is for sending packets + explicit LLSocketAddress(MACAddress const & addr, std::string const & iface=""); + ///< Create address valid to send raw packets + /**< Addresses created with this constructor are valid for + use with \c PacketSocketHandle::sendto() on a \c + SOCK_DGRAM packet socket. + \param addr Address to send data to + \param iface Interface to send packet from */ + + void clear(); ///< Clear the address + + unsigned protocol() const; ///< Return address protocol (ethertype) + std::string interface() const; ///< Return interface name + unsigned arptype() const; ///< Return the hatype field (ARP hardware type) + PktType pkttype() const; ///< Return type of packet + MACAddress address() const; ///< Return address // The mutating interface is purposely restricted to allow only // changing those members, which are sensible to be changed. - template - void address(ForwardRange const & address); - void interface(std::string interface); - void protocol(unsigned protocol); + void address(MACAddress const & addr); ///< Change address + void interface(std::string iface); ///< Change interface + void protocol(unsigned prot); ///< Change protocol + + ///\name Generic SocketAddress interface + ///@{ struct sockaddr * sockaddr_p(); struct sockaddr const * sockaddr_p() const; unsigned sockaddr_len() const; + ///@} + private: struct ::sockaddr_ll addr_; }; - /** \brief - \related LLSocketAddress - */ - detail::LLAddressFromStringRange llAddress(std::string address); - - // The enable_if condition here allows only for classes as range. - // However, excluding zero-terminated strings (which we want to - // pass to above) I cannot think of a non-class ForwardRange - // except for academic cases - // STOP: ... how about std::vector<...>::iterator ?? isn't that a ..pointer ? - /** \brief Convert raw link-local address into printable form - \related LLSocketAddress - */ - template - std::string llAddress(ForwardRange const & address, - typename boost::enable_if< boost::is_class >::type * = 0); - /** \brief Signal invalid link local address syntax \related LLSocketAddress */ @@ -185,8 +157,8 @@ namespace senf { ///////////////////////////////hh.e//////////////////////////////////////// #include "LLAddressing.cci" -#include "LLAddressing.ct" -#include "LLAddressing.cti" +//#include "LLAddressing.ct" +//#include "LLAddressing.cti" //#include "LLAddressing.mpp" #endif diff --git a/Socket/Protocols/Raw/LLAddressing.ih b/Socket/Protocols/Raw/LLAddressing.ih deleted file mode 100644 index a5d7397..0000000 --- a/Socket/Protocols/Raw/LLAddressing.ih +++ /dev/null @@ -1,70 +0,0 @@ -// $Id$ -// -// Copyright (C) 2006 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund -// -// 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 -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -/** \file - \brief LLSocketAddress and LLAddressingPolicy internal header - */ -#ifndef IH_LLAddressing_ -#define IH_LLAddressing_ 1 - -// Custom includes -#include - -///////////////////////////////ih.p//////////////////////////////////////// - -namespace senf { - -namespace detail { - - /** \brief Convert two-char hexbyte representation to numeric value - \internal - */ - struct HexConverter { - typedef unsigned char result_type; - template - result_type operator()(ForwardRange const & v) const; - }; - - typedef boost::split_iterator StringSplitIterator; - typedef boost::transform_iterator< HexConverter, StringSplitIterator > HexSplitIterator; - typedef boost::iterator_range LLAddressFromStringRange; - - /** \brief convert single hex digit to numeric value - \internal - */ - unsigned char hexnibble(char c); - -}} - -///////////////////////////////ih.e//////////////////////////////////////// -#endif - - -// Local Variables: -// mode: c++ -// fill-column: 100 -// c-file-style: "senf" -// indent-tabs-mode: nil -// ispell-local-dictionary: "american" -// compile-command: "scons -u test" -// comment-column: 40 -// End: diff --git a/Socket/Protocols/Raw/LLAddressing.test.cc b/Socket/Protocols/Raw/LLAddressing.test.cc index 7e1a060..32e4d31 100644 --- a/Socket/Protocols/Raw/LLAddressing.test.cc +++ b/Socket/Protocols/Raw/LLAddressing.test.cc @@ -26,6 +26,7 @@ //#include "LLAddressing.test.ih" // Custom includes +#include #include "LLAddressing.hh" #include @@ -42,11 +43,11 @@ BOOST_AUTO_UNIT_TEST(llAddress) BOOST_CHECK_EQUAL( a.protocol(), 0u ); BOOST_CHECK_EQUAL( a.interface(), "" ); BOOST_CHECK_EQUAL( a.arptype(), 0u ); - BOOST_CHECK_EQUAL( a.pkttype(), 0u ); - BOOST_CHECK_EQUAL( a.address(), "" ); + BOOST_CHECK_EQUAL( a.pkttype(), senf::LLSocketAddress::Undefined ); + BOOST_CHECK( ! a.address() ); - a.address(senf::llAddress("05-10-1A-2f-25-30")); - BOOST_CHECK_EQUAL( senf::llAddress(a.address()), "05-10-1a-2f-25-30" ); + a.address(senf::MACAddress::from_string("05-10-1A-2f-25-30")); + BOOST_CHECK_EQUAL( boost::lexical_cast(a.address()), "05:10:1a:2f:25:30" ); a.interface("lo"); BOOST_CHECK_EQUAL( a.interface(), "lo" ); a.protocol(123); @@ -55,13 +56,13 @@ BOOST_AUTO_UNIT_TEST(llAddress) { senf::LLSocketAddress a ( - senf::llAddress("11-12-13-14-15-16"), "lo"); + senf::MACAddress::from_string("11-12-13-14-15-16"), "lo"); BOOST_CHECK_EQUAL( a.protocol(), 0u ); BOOST_CHECK_EQUAL( a.interface(), "lo" ); BOOST_CHECK_EQUAL( a.arptype(), 0u ); - BOOST_CHECK_EQUAL( a.pkttype(), 0u ); - BOOST_CHECK_EQUAL( senf::llAddress(a.address()), "11-12-13-14-15-16" ); + BOOST_CHECK_EQUAL( a.pkttype(), senf::LLSocketAddress::Undefined ); + BOOST_CHECK_EQUAL( boost::lexical_cast(a.address()), "11:12:13:14:15:16" ); } { @@ -71,7 +72,7 @@ BOOST_AUTO_UNIT_TEST(llAddress) BOOST_CHECK_EQUAL( a.interface(), "lo" ); BOOST_CHECK_EQUAL( a.arptype(), 0u ); BOOST_CHECK_EQUAL( a.pkttype(), 0u ); - BOOST_CHECK_EQUAL( senf::llAddress(a.address()), "" ); + BOOST_CHECK( ! a.address() ); } } diff --git a/Socket/Protocols/Raw/MACAddress.hh b/Socket/Protocols/Raw/MACAddress.hh index 0e26960..4f91297 100644 --- a/Socket/Protocols/Raw/MACAddress.hh +++ b/Socket/Protocols/Raw/MACAddress.hh @@ -40,6 +40,12 @@ namespace senf { /** \brief Ethernet MAC address The Ethernet MAC is modelled as a fixed-size container/sequence of 6 bytes. + + \implementation We awkwardly need to use static named constructors (from_ members) + instead of ordinarily overloaded constructors for one simple reason: char * + doubles as string literal and as arbitrary data iterator. The iterator constructor can + therefore not be distinguished from initialization with a string literal. Therefore we + need to disambiguate using the named constructors. */ struct MACAddress : public boost::array, diff --git a/Socket/Protocols/Raw/PacketSocketHandle.cc b/Socket/Protocols/Raw/PacketSocketHandle.cc index 7250c8c..45473d9 100644 --- a/Socket/Protocols/Raw/PacketSocketHandle.cc +++ b/Socket/Protocols/Raw/PacketSocketHandle.cc @@ -25,7 +25,7 @@ */ #include "PacketSocketHandle.hh" -#include "PacketSocketHandle.ih" +//#include "PacketSocketHandle.ih" // Custom includes #include @@ -77,20 +77,37 @@ prefix_ bool senf::PacketProtocol::eof() 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 interface, senf::MACAddress address, bool add) + { + struct packet_mreq 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(errno); + } + +} + +prefix_ void senf::PacketProtocol::mcAdd(std::string const & interface, + MACAddress const & address) const { - struct packet_mreq 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, - &mreq, sizeof(mreq)) < 0) - throw SystemException(errno); + do_mc(body().fd(),interface,address,true); +} + +prefix_ void senf::PacketProtocol::mcDrop(std::string const & interface, + MACAddress const & address) + const +{ + do_mc(body().fd(),interface,address,false); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Socket/Protocols/Raw/PacketSocketHandle.ct b/Socket/Protocols/Raw/PacketSocketHandle.ct deleted file mode 100644 index 5a6eb0c..0000000 --- a/Socket/Protocols/Raw/PacketSocketHandle.ct +++ /dev/null @@ -1,60 +0,0 @@ -// $Id$ -// -// Copyright (C) 2006 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund -// -// 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 -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -/** \file - \brief PacketProtocol and PacketSocketHandle non-inline template implementation - */ - -#include "PacketSocketHandle.ih" - -// Custom includes - -#define prefix_ -///////////////////////////////ct.p//////////////////////////////////////// - -template -prefix_ unsigned -senf::detail::Range_LLAddressCopier::operator()(unsigned char * target) - const -{ - std::size_t len (0); - typename boost::range_const_iterator::type i (boost::begin(range_)); - for (; i != boost::end(range_) && len<8; ++i, ++len, ++target) - *target = *i; - if (i != boost::end(range_)) - throw InvalidLLSocketAddressException(); - return len; -} - -///////////////////////////////ct.e//////////////////////////////////////// -#undef prefix_ - - -// Local Variables: -// mode: c++ -// fill-column: 100 -// c-file-style: "senf" -// indent-tabs-mode: nil -// ispell-local-dictionary: "american" -// compile-command: "scons -u test" -// comment-column: 40 -// End: diff --git a/Socket/Protocols/Raw/PacketSocketHandle.cti b/Socket/Protocols/Raw/PacketSocketHandle.cti deleted file mode 100644 index d22e077..0000000 --- a/Socket/Protocols/Raw/PacketSocketHandle.cti +++ /dev/null @@ -1,77 +0,0 @@ -// $Id$ -// -// Copyright (C) 2006 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund -// -// 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 -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -/** \file - \brief PacketProtocol and PacketSocketHandle inline template implementation - */ - -#include "PacketSocketHandle.ih" - -// Custom includes - -#define prefix_ inline -///////////////////////////////cti.p/////////////////////////////////////// - -template -prefix_ void senf::PacketProtocol::mcAdd(std::string interface, - ForwardRange const & address) - const -{ - do_mc(interface,address,true); -} - -template -prefix_ void senf::PacketProtocol::mcDrop(std::string interface, - ForwardRange const & address) - const -{ - do_mc(interface,address,false); -} - -template -prefix_ senf::detail::Range_LLAddressCopier:: -Range_LLAddressCopier(ForwardRange const & range) - : range_ (range) -{} - -template -prefix_ void senf::PacketProtocol::do_mc(std::string interface, - ForwardRange const & address, bool add) - const -{ - detail::Range_LLAddressCopier copier (address); - do_mc_i(interface, copier, add); -} - -///////////////////////////////cti.e/////////////////////////////////////// -#undef prefix_ - - -// Local Variables: -// mode: c++ -// fill-column: 100 -// c-file-style: "senf" -// indent-tabs-mode: nil -// ispell-local-dictionary: "american" -// compile-command: "scons -u test" -// comment-column: 40 -// End: diff --git a/Socket/Protocols/Raw/PacketSocketHandle.hh b/Socket/Protocols/Raw/PacketSocketHandle.hh index 873b7ef..95c9980 100644 --- a/Socket/Protocols/Raw/PacketSocketHandle.hh +++ b/Socket/Protocols/Raw/PacketSocketHandle.hh @@ -41,7 +41,7 @@ #include "LLAddressing.hh" //#include "PacketSocketHandle.mpp" -#include "PacketSocketHandle.ih" +//#include "PacketSocketHandle.ih" ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { @@ -114,24 +114,15 @@ namespace senf { ///\name Protocol Interface ///@{ - // See LLSocketAddress for a discussion/rationale for ForwardRange here - template - void mcAdd(std::string interface, ForwardRange const & address) const; + void mcAdd(std::string const & interface, MACAddress const & address) const; ///< Enable reception of a multicast group - /**< mcAdd will join a new multicast group. The address - parameter is specified as an arbitrary forward range - (see Boost.Range) - of up to 8 bytes. This allows to initialize the - address from an arbitrary sources without excessive - copying. + /**< mcAdd will join a new multicast group. \param[in] interface interface with which to join \param[in] address multicast address to join \see \ref LLSocketAddress */ - template - void mcDrop(std::string interface, ForwardRange const & address) const; + void mcDrop(std::string const & interface, MACAddress const & address) const; ///< Disable reception of a multicast group /**< \see \ref mcAdd() */ ///@} @@ -144,11 +135,6 @@ namespace senf { bool eof() const; ///@} - - private: - template - void do_mc(std::string interface, ForwardRange const & address, bool add) const; - void do_mc_i(std::string interface, detail::LLAddressCopier const & copier, bool add) const; }; typedef ProtocolClientSocketHandle PacketSocketHandle; @@ -160,8 +146,8 @@ namespace senf { ///////////////////////////////hh.e//////////////////////////////////////// //#include "PacketSocketHandle.cci" -#include "PacketSocketHandle.ct" -#include "PacketSocketHandle.cti" +//#include "PacketSocketHandle.ct" +//#include "PacketSocketHandle.cti" //#include "PacketSocketHandle.mpp" #endif diff --git a/Socket/Protocols/Raw/PacketSocketHandle.ih b/Socket/Protocols/Raw/PacketSocketHandle.ih deleted file mode 100644 index 58ab1a9..0000000 --- a/Socket/Protocols/Raw/PacketSocketHandle.ih +++ /dev/null @@ -1,85 +0,0 @@ -// $Id$ -// -// Copyright (C) 2006 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund -// -// 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 -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -/** \file - \brief PacketProtocol and PacketSocketHandle internal header - */ - -#ifndef IH_PacketSocketHandle_ -#define IH_PacketSocketHandle_ 1 - -// Custom includes - -///////////////////////////////ih.p//////////////////////////////////////// - -namespace senf { - -namespace detail { - - /** \brief Abstract address copier - \internal - - This class provides the abstract interface to copy a - link-local address to a destination address. - */ - struct LLAddressCopier - { - virtual ~LLAddressCopier() {} - virtual unsigned operator()(unsigned char * target) const = 0; - }; - - /** \brief Implementation of LLAddressCopier to copy arbitrary Range - \internal - - This implementation of the LLAddressCopier interface will copy - an arbitrary range to the target address. This class is used, - to convert the compile-time polymorphism of templates - (provided by the \c ForwardRange template argument) into - runtime polymorphism (provided by the abstract LLAddressCopier - interface). - */ - template - struct Range_LLAddressCopier - : public LLAddressCopier - { - Range_LLAddressCopier(ForwardRange const & range); - - unsigned operator()(unsigned char * target) const; - - ForwardRange const & range_; - }; - -}} - -///////////////////////////////ih.e//////////////////////////////////////// -#endif - - -// Local Variables: -// mode: c++ -// fill-column: 100 -// c-file-style: "senf" -// indent-tabs-mode: nil -// ispell-local-dictionary: "american" -// compile-command: "scons -u test" -// comment-column: 40 -// End: diff --git a/Socket/Protocols/Raw/PacketSocketHandle.test.cc b/Socket/Protocols/Raw/PacketSocketHandle.test.cc index f579885..79dbde0 100644 --- a/Socket/Protocols/Raw/PacketSocketHandle.test.cc +++ b/Socket/Protocols/Raw/PacketSocketHandle.test.cc @@ -56,9 +56,9 @@ BOOST_AUTO_UNIT_TEST(packetSocketHandle) // How am I supposed to test read and write .. grmpf .. BOOST_CHECK_NO_THROW( sock.protocol().mcAdd( - "eth0",senf::llAddress("01-02-03-04-05-06")) ); + "eth0",senf::MACAddress::from_string("01-02-03-04-05-06")) ); BOOST_CHECK_NO_THROW( sock.protocol().mcDrop( - "eth0",senf::llAddress("01-02-03-04-05-06")) ); + "eth0",senf::MACAddress::from_string("01-02-03-04-05-06")) ); BOOST_CHECK_NO_THROW( sock.protocol().available() ); BOOST_CHECK( ! sock.eof() ); diff --git a/Socket/ServerSocketHandle.hh b/Socket/ServerSocketHandle.hh index 879416b..bb97b2d 100644 --- a/Socket/ServerSocketHandle.hh +++ b/Socket/ServerSocketHandle.hh @@ -125,7 +125,7 @@ namespace senf { For addressable protocols (AddressingPolicy is not NoAddressingPolicy), bind() will set the local address of the socket. - \param[in] addr Local socket address to asign + \param[in] addr Local socket address to assign \throws senf::SystemException */ @@ -170,6 +170,8 @@ namespace senf { This variant ... \returns handle of new client connection + + \fixme Make this accept()-variant work with unspecified addressing policy */ ClientSocketHandle accept (); diff --git a/senf.dict b/senf.dict index e1596ec..2cd85e5 100644 --- a/senf.dict +++ b/senf.dict @@ -1,4 +1,8 @@ +acceptfrom accessor +addr +AddressingPolicy +AddressingPolicyBase addtogroup aListCollection alloc @@ -10,7 +14,11 @@ bund callbacks cerr cfi +ClientSocketHandle +CommunicationPolicy +CommunicationPolicyBase ConcretePacket +ConnectedCommunicationPolicy const createAfter createBefore @@ -41,13 +49,16 @@ filebody FileHandle findNext findPrev +fixme fokus FooParser fraunhofer fuer hh hideinitializer +Hmm href +htm html http ih @@ -83,6 +94,7 @@ NextPacket nextPacketKey nextPacketRange nextPacketType +NoAddressingPolicy noinit nothrow offene @@ -134,6 +146,7 @@ SafePacketParser SatCom Satelitenkommunikation senf +ServerSocketHandle setBegin setEnd setFromPosition @@ -141,6 +154,7 @@ SimplePacketType SimpleVectorSizer SizeParser skipline +SocketHandle someField someOtherField SomePacket @@ -157,8 +171,10 @@ struct structors SyntaxException SystemException +td templated todo +tr TruncatedPacketException tt ttl