Skip to content
Snippets Groups Projects
Commit 4c4fa2f0 authored by g0dil's avatar g0dil
Browse files

Socket: Moved PacketSocketHandle and related stuff into 'Raw' subdir

Socket: Added complete MACAddress class
Packets/DefaultBundle: Make EthernetPacket use the MACAddress class
parent c34aad6a
No related branches found
No related tags found
No related merge requests found
Showing
with 467 additions and 100 deletions
......@@ -29,7 +29,7 @@
#include <string>
#include <iostream>
#include <iomanip>
#include "Socket/Protocols/PacketSocketHandle.hh"
#include "Socket/Protocols/Raw/PacketSocketHandle.hh"
#include "Scheduler/Scheduler.hh"
#include "Utils/membind.hh"
#include "Packets/DefaultBundle/EthernetPacket.hh"
......
......@@ -29,7 +29,6 @@
// Custom includes
#include <iomanip>
#include <boost/io/ios_state.hpp>
#include <boost/tokenizer.hpp>
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
......@@ -39,72 +38,12 @@ namespace {
registerEthVLanPacket(0x8100);
}
///////////////////////////////////////////////////////////////////////////
// senf::MACAddress
namespace {
senf::PacketParserBase::byte hexToNibble(char c)
{
if (c<'0')
throw senf::MACAddress::SyntaxException();
else if (c<='9')
return c-'-';
else if (c<'A')
throw senf::MACAddress::SyntaxException();
else if (c<='F')
return c-'A'+10;
else if (c<'a')
throw senf::MACAddress::SyntaxException();
else if (c<='f')
return c-'a'+10;
else
throw senf::MACAddress::SyntaxException();
}
template <class Range>
senf::PacketParserBase::byte hexToByte(Range const & range)
{
if (boost::size(range) != 2)
throw senf::MACAddress::SyntaxException();
typename boost::range_const_iterator<Range>::type i (boost::begin(range));
return hexToNibble(i[0])*16+hexToNibble(i[1]);
}
}
prefix_ senf::MACAddress::MACAddress(std::string addr)
{
typedef boost::char_separator<char> separator;
typedef boost::tokenizer<separator> tokenizer;
separator sep (":");
tokenizer tok (addr,sep);
tokenizer::iterator i (tok.begin());
tokenizer::iterator i_end (tok.end());
iterator j (begin());
iterator j_end (end());
for (; i!=i_end && j!=j_end; ++i, ++j)
*j = hexToByte(*i);
if (i!=i_end || j!=j_end)
throw SyntaxException();
}
///////////////////////////////////////////////////////////////////////////
// senf::EthernetPacketType
namespace {
void dumpmac(std::ostream & os, senf::MACAddress mac)
{
boost::io::ios_all_saver ias(os);
for (unsigned i = 0; i < 6; ++i) {
if (i > 0)
os << ':';
os << std::hex << std::setw(2) << std::setfill('0')
<< unsigned(mac[i]);
}
}
}
prefix_ void senf::EthernetPacketType::dump(packet p, std::ostream & os)
{
boost::io::ios_all_saver ias(os);
if (p->type() <= 1500)
os << "Ethernet 802.3";
else if (p->type() >= 0x600)
......@@ -112,24 +51,21 @@ prefix_ void senf::EthernetPacketType::dump(packet p, std::ostream & os)
else
os << "Ethernet 802.3 (bad ethertype >1500 and <1536)";
os << ": \n"
<< " destination : ";
dumpmac(os,p->destination());
os << "\n"
<< " source : ";
dumpmac(os,p->source());
os << "\n"
<< " ethertype : " << std::hex << std::setw(4) << std::setfill('0')
<< unsigned(p->type()) << "\n" << std::dec;
<< " destination : " << p->destination() << "\n"
<< " source : " << p->source() << "\n"
<< " ethertype : "
<< std::hex << std::setw(4) << std::setfill('0') << p->type() << "\n";
}
prefix_ void senf::EthVLanPacketType::dump(packet p, std::ostream & os)
{
boost::io::ios_all_saver ias(os);
os << "Ethernet 802.1q (VLAN):\n"
<< " priority : " << p->priority() << "\n"
<< " cfi : " << p->cfi() << "\n"
<< " vlan-ID : " << p->vlanId() << "\n"
<< " ethertype : " << std::hex << std::setw(4) << std::setfill('0')
<< p->type() << "\n" << std::dec;
<< " ethertype : "
<< std::hex << std::setw(4) << std::setfill('0') << p->type() << "\n";
}
///////////////////////////////cc.e////////////////////////////////////////
......
......@@ -28,7 +28,7 @@
// Custom includes
#include <algorithm>
#include <boost/array.hpp>
#include "Socket/Protocols/Raw/MACAddress.hh"
#include "Packets/Packets.hh"
//#include "EthernetPacket.mpp"
......@@ -36,23 +36,6 @@
namespace senf {
/** \brief Ethernet MAC address
The Ethernet MAC is modelled as a fixed-size container/sequence of 6 bytes.
\todo Move to someplace else when implementing the addressing classes
*/
struct MACAddress
: boost::array<PacketParserBase::byte,6>
{
MACAddress(std::string addr);
template <class InputIterator>
MACAddress(InputIterator i);
struct SyntaxException : public std::exception
{ virtual char const * what() const throw() { return "invalid mac address syntax"; } };
};
/** \brief Parse an Ethernet MAC address
The ethernet MAC is returned by value as a 6-byte sequence
......@@ -69,7 +52,7 @@ namespace senf {
typedef MACAddress value_type;
static const size_type fixed_bytes = 6u;
value_type value() const { return MACAddress(i()); }
value_type value() const { return MACAddress::from_data(i()); }
void value(value_type const & v) { std::copy(v.begin(), v.end(), i()); }
operator value_type () { return value(); }
byte & operator[](size_type index) { return *boost::next(i(),index); }
......@@ -230,7 +213,7 @@ namespace senf {
#endif
#ifndef SENF_PACKETS_DECL_ONLY
//#include "EthernetPacket.cci"
#include "EthernetPacket.ct"
//#include "EthernetPacket.ct"
//#include "EthernetPacket.cti"
#endif
......
......@@ -37,7 +37,7 @@
#include "Socket/SocketPolicy.hh"
#include "Socket/FileHandle.hh"
#include "GenericAddressingPolicy.hh"
#include "Socket/Protocols/GenericAddressingPolicy.hh"
//#include "LLAddressing.mpp"
#include "LLAddressing.ih"
......
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// 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
// 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 MACAddress non-inline non-template implementation */
#include "MACAddress.hh"
//#include "MACAddress.ih"
// Custom includes
#include <iomanip>
#include <boost/tokenizer.hpp>
#include <boost/io/ios_state.hpp>
#include <boost/range.hpp>
//#include "MACAddress.mpp"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
namespace {
boost::uint8_t hexToNibble(char c)
{
if (c<'0')
throw senf::MACAddress::SyntaxException();
else if (c<='9')
return c-'0';
else if (c<'A')
throw senf::MACAddress::SyntaxException();
else if (c<='F')
return c-'A'+10;
else if (c<'a')
throw senf::MACAddress::SyntaxException();
else if (c<='f')
return c-'a'+10;
else
throw senf::MACAddress::SyntaxException();
}
template <class Range>
boost::uint8_t hexToByte(Range const & range)
{
if (boost::size(range) != 2)
throw senf::MACAddress::SyntaxException();
typename boost::range_const_iterator<Range>::type i (boost::begin(range));
return hexToNibble(i[0])*16+hexToNibble(i[1]);
}
}
///////////////////////////////////////////////////////////////////////////
// senf::MACAddress
prefix_ senf::MACAddress::MACAddress senf::MACAddress::from_string(std::string const & s)
{
MACAddress mac (MACAddress::noinit);
typedef boost::char_separator<char> separator;
typedef boost::tokenizer<separator> tokenizer;
separator sep (":-");
tokenizer tok (s,sep);
tokenizer::iterator i (tok.begin());
tokenizer::iterator const i_end (tok.end());
iterator j (mac.begin());
iterator const j_end (mac.end());
for (; i!=i_end && j!=j_end; ++i, ++j)
*j = hexToByte(*i);
if (i!=i_end || j!=j_end)
throw SyntaxException();
return mac;
}
prefix_ senf::MACAddress senf::MACAddress::from_eui64(boost::uint64_t v)
{
if ( boost::uint16_t(v>>24) != 0xfffe )
throw SyntaxException();
MACAddress mac (MACAddress::noinit);
mac[0] = boost::uint8_t( v>>56 );
mac[1] = boost::uint8_t( v>>48 );
mac[2] = boost::uint8_t( v>>40 );
mac[3] = boost::uint8_t( v>>16 );
mac[4] = boost::uint8_t( v>> 8 );
mac[5] = boost::uint8_t( v );
return mac;
}
///////////////////////////////////////////////////////////////////////////
// namespace members
prefix_ std::ostream & senf::operator<<(std::ostream & os, MACAddress const & mac)
{
boost::io::ios_all_saver ias(os);
os << std::hex << std::setfill('0');
for (MACAddress::const_iterator i (mac.begin()); i != mac.end(); ++i) {
if (i != mac.begin())
os << ':';
os << std::setw(2) << unsigned(*i);
}
return os;
}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "MACAddress.mpp"
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// 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
// 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 MACAddress inline non-template implementation */
// Custom includes
#include <algorithm>
#include <boost/lambda/lambda.hpp>
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::MACAddress
prefix_ senf::MACAddress::MACAddress()
{
std::fill(begin(),end(),0u);
}
prefix_ senf::MACAddress::MACAddress(NoInit_t)
{}
prefix_ bool senf::MACAddress::local()
const
{
return (*this)[0] & 0x02;
}
prefix_ bool senf::MACAddress::group()
const
{
return (*this)[0] & 0x01;
}
prefix_ bool senf::MACAddress::broadcast()
const
{
using boost::lambda::_1;
return std::find_if(begin(),end(), _1 != 0xffu) == end();
}
prefix_ bool senf::MACAddress::boolean_test()
const
{
using boost::lambda::_1;
return std::find_if(begin(),end(), _1 != 0x00u) != end();
}
prefix_ boost::uint32_t senf::MACAddress::oui()
const
{
return
(boost::uint32_t((*this)[0])<<16) |
(boost::uint32_t((*this)[1])<<8) |
(*this)[2];
}
prefix_ boost::uint32_t senf::MACAddress::nic()
const
{
return
(boost::uint32_t((*this)[3])<<16) |
(boost::uint32_t((*this)[4])<<8) |
(*this)[5];
}
prefix_ boost::uint64_t senf::MACAddress::eui64()
const
{
return
(boost::uint64_t( (*this)[0] ) << 56) |
(boost::uint64_t( (*this)[1] ) << 48) |
(boost::uint64_t( (*this)[2] ) << 40) |
(boost::uint64_t( 0xfffe ) << 24) |
(boost::uint64_t( (*this)[3] ) << 16) |
(boost::uint64_t( (*this)[4] ) << 8) |
(boost::uint64_t( (*this)[5] ) );
}
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
......@@ -19,22 +19,27 @@
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief EthernetPacket non-inline template implementation */
\brief MACAddress non-inline template implementation */
//#include "EthernetPacket.ih"
//#include "MACAddress.ih"
// Custom includes
#define prefix_
///////////////////////////////ct.p////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::MACAddress
template <class InputIterator>
prefix_ senf::MACAddress::MACAddress(InputIterator i)
prefix_ senf::MACAddress::MACAddress senf::MACAddress::from_data(InputIterator i)
{
iterator j (begin());
iterator j_end (end());
MACAddress mac (MACAddress::noinit);
iterator j (mac.begin());
iterator j_end (mac.end());
for (;j!=j_end;++j,++i)
*j = *i;
return mac;
}
///////////////////////////////ct.e////////////////////////////////////////
......
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// 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
// 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 MACAddress public header */
#ifndef HH_MACAddress_
#define HH_MACAddress_ 1
// Custom includes
#include <iostream>
#include <boost/cstdint.hpp>
#include <boost/array.hpp>
#include <boost/utility.hpp>
#include <boost/type_traits.hpp>
#include "Utils/SafeBool.hh"
//#include "MACAddress.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
/** \brief Ethernet MAC address
The Ethernet MAC is modelled as a fixed-size container/sequence of 6 bytes.
*/
struct MACAddress
: public boost::array<boost::uint8_t,6>,
public ComparableSafeBool<MACAddress>
{
enum NoInit_t { noinit };
MACAddress(); ///< Construct zero-initialized address
MACAddress(NoInit_t); ///< Construct uninitialized (!) address
static MACAddress from_string(std::string const & s);
///< Construct address from string representation
/**< The string representation must exactly match the form
<tt>dd:dd:dd:dd:dd:dd</tt> where <tt>d</tt> is any
hexadecimal digit. In place of ':', '-' is also
accepted as a delimiter. */
template <class InputIterator>
static MACAddress from_data(InputIterator i);
///< Construct address from raw data
/**< Copies the data from \a i into the MAC address.
\pre The input range at \a i must have a size of at
least 6 elements. */
static MACAddress from_eui64(boost::uint64_t v);
///< Construct address from EUI-64
/**< This constructor takes an EUI-64 value and converts it
to a MAC address. This conversion is only possible, if
the EUI-64 is MAC compatible: the 4th/5th byte (in
transmission order) must be 0xFFFE.
\throws SyntaxException if \a v is not a MAC compatible
EUI-64. */
bool local() const; ///< \c true, if address is locally administered
bool group() const; ///< \c true, if address is a group/multicast address
bool broadcast() const; ///< \c true, if address is the broadcast address
bool boolean_test() const; ///< \c true, if address is the zero address
boost::uint32_t oui() const; ///< Return first 3 bytes of the address
boost::uint32_t nic() const; ///< Return last 3 bytes of the address
boost::uint64_t eui64() const; ///< Build EUI-64 from the MAC address
/** \brief Bad MAC address syntax or conversion */
struct SyntaxException : public std::exception
{ virtual char const * what() const throw() { return "invalid MAC address syntax"; } };
};
/** \brief Write MAC address
\related MACAddress
*/
std::ostream & operator<<(std::ostream & os, MACAddress const & mac);
}
///////////////////////////////hh.e////////////////////////////////////////
#include "MACAddress.cci"
#include "MACAddress.ct"
//#include "MACAddress.cti"
#endif
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// 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
// 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 MACAddress.test unit tests */
//#include "MACAddress.test.hh"
//#include "MACAddress.test.ih"
// Custom includes
#include <sstream>
#include <boost/lexical_cast.hpp>
#include "MACAddress.hh"
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_tools.hpp>
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
BOOST_AUTO_UNIT_TEST(macAddress)
{
senf::MACAddress mac (senf::MACAddress::from_string("A1-b2-C3:d4:E5:f6"));
std::stringstream str;
str << mac;
BOOST_CHECK_EQUAL( str.str(), "a1:b2:c3:d4:e5:f6" );
BOOST_CHECK( ! mac.local() );
BOOST_CHECK( mac.group() );
BOOST_CHECK( ! mac.broadcast() );
BOOST_CHECK( mac );
BOOST_CHECK_EQUAL( mac.oui(), 0xa1b2c3u );
BOOST_CHECK_EQUAL( mac.nic(), 0xd4e5f6u );
BOOST_CHECK_EQUAL( mac.eui64(), 0xa1b2c3fffed4e5f6llu );
senf::MACAddress mac2;
BOOST_CHECK( ! mac2 );
mac2 = senf::MACAddress::from_string("ff:ff:ff:ff:ff:ff");
BOOST_CHECK( mac2.broadcast() );
char data[] = { 0x01,0x02,0x03,0x04,0x05,0x06 };
mac2 = senf::MACAddress::from_data(data);
BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(mac2), "01:02:03:04:05:06" );
BOOST_CHECK( mac != mac2 );
mac2 = mac;
BOOST_CHECK( mac == mac2 );
BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(mac2), "a1:b2:c3:d4:e5:f6" );
BOOST_CHECK_THROW( senf::MACAddress::from_string("1:2:3:4:5:6"),
senf::MACAddress::SyntaxException );
BOOST_CHECK_THROW( senf::MACAddress::from_string("01:02:03:04:05"),
senf::MACAddress::SyntaxException );
BOOST_CHECK_THROW( senf::MACAddress::from_string("01:02:03:04:05:z6"),
senf::MACAddress::SyntaxException );
BOOST_CHECK_EQUAL( mac, senf::MACAddress::from_eui64(0xa1b2c3fffed4e5f6llu) );
BOOST_CHECK_THROW( senf::MACAddress::from_eui64(0u), senf::MACAddress::SyntaxException );
}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
......@@ -37,8 +37,8 @@
#include "Socket/CommunicationPolicy.hh"
#include "Socket/ReadWritePolicy.hh"
#include "Socket/BufferingPolicy.hh"
#include "Socket/Protocols/BSDSocketProtocol.hh"
#include "LLAddressing.hh"
#include "BSDSocketProtocol.hh"
//#include "PacketSocketHandle.mpp"
#include "PacketSocketHandle.ih"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment