Skip to content
Snippets Groups Projects
Commit 296d7075 authored by g0dil's avatar g0dil
Browse files

Socket/Protocols: Replace uint64 with EUI64 in address classes

parent 9b43bcb5
No related branches found
No related tags found
No related merge requests found
...@@ -88,32 +88,25 @@ prefix_ senf::INet6Address senf::INet6Address::from_mac(senf::MACAddress const & ...@@ -88,32 +88,25 @@ prefix_ senf::INet6Address senf::INet6Address::from_mac(senf::MACAddress const &
return addr; return addr;
} }
prefix_ boost::uint64_t senf::INet6Address::network() prefix_ senf::INet6Address senf::INet6Address::from_eui64(senf::EUI64 const & eui)
{
INet6Address addr;
addr[0] = 0xfe;
addr[1] = 0x80;
std::copy(eui.begin(), eui.end(), addr.begin()+8);
return addr;
}
prefix_ senf::INet6Network senf::INet6Address::network()
const const
{ {
return return senf::INet6Network(*this, 64);
((boost::uint64_t((*this)[0]) & 0xff) << 56 ) |
((boost::uint64_t((*this)[1]) & 0xff) << 48 ) |
((boost::uint64_t((*this)[2]) & 0xff) << 40 ) |
((boost::uint64_t((*this)[3]) & 0xff) << 32 ) |
((boost::uint64_t((*this)[4]) & 0xff) << 24 ) |
((boost::uint64_t((*this)[5]) & 0xff) << 16 ) |
((boost::uint64_t((*this)[6]) & 0xff) << 8 ) |
((boost::uint64_t((*this)[7]) & 0xff) );
} }
prefix_ boost::uint64_t senf::INet6Address::id() prefix_ senf::EUI64 senf::INet6Address::id()
const const
{ {
return return senf::EUI64::from_data(begin()+8);
((boost::uint64_t((*this)[ 8]) & 0xff) << 56 ) |
((boost::uint64_t((*this)[ 9]) & 0xff) << 48 ) |
((boost::uint64_t((*this)[10]) & 0xff) << 40 ) |
((boost::uint64_t((*this)[11]) & 0xff) << 32 ) |
((boost::uint64_t((*this)[12]) & 0xff) << 24 ) |
((boost::uint64_t((*this)[13]) & 0xff) << 16 ) |
((boost::uint64_t((*this)[14]) & 0xff) << 8 ) |
((boost::uint64_t((*this)[15]) & 0xff) );
} }
prefix_ bool senf::INet6Address::universalId() prefix_ bool senf::INet6Address::universalId()
...@@ -166,7 +159,7 @@ prefix_ bool senf::INet6Address::unicast() ...@@ -166,7 +159,7 @@ prefix_ bool senf::INet6Address::unicast()
return ! multicast(); return ! multicast();
} }
prefix_ bool senf::INet6Address::hasEuid64() prefix_ bool senf::INet6Address::hasEUI64()
const const
{ {
return unicast() && ((*this)[0]&0xE0u) != 0u; return unicast() && ((*this)[0]&0xE0u) != 0u;
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "INet4Address.hh" #include "INet4Address.hh"
#include "../AddressExceptions.hh" #include "../AddressExceptions.hh"
#include "../Raw/MACAddress.hh" #include "../Raw/MACAddress.hh"
#include "../Raw/EUI64.hh"
//#include "INet6Address.mpp" //#include "INet6Address.mpp"
#include "INet6Address.ih" #include "INet6Address.ih"
...@@ -45,6 +46,8 @@ ...@@ -45,6 +46,8 @@
namespace senf { namespace senf {
class INet6Network;
/** \brief INet6 network address /** \brief INet6 network address
This implementation of an INet6 address is based strictly on This implementation of an INet6 address is based strictly on
...@@ -208,6 +211,11 @@ namespace senf { ...@@ -208,6 +211,11 @@ namespace senf {
///< Construct a link-local INet6 address ///< Construct a link-local INet6 address
/**< This will construct a link local address of the form /**< This will construct a link local address of the form
<tt>fe80::xxxx:xxff:fexx:xxxx</tt>. */ <tt>fe80::xxxx:xxff:fexx:xxxx</tt>. */
static INet6Address from_eui64(senf::EUI64 const & eui);
///< Construct link-local INet6 address
/**< This will construct a link local address of the form
<tt>fe80::xxxx:xxxx:xxxx:xxxx</tt>. */
in6_addr toin6_addr() const; ///< get the linux in6_addr struct (convinience only) in6_addr toin6_addr() const; ///< get the linux in6_addr struct (convinience only)
...@@ -216,9 +224,9 @@ namespace senf { ...@@ -216,9 +224,9 @@ namespace senf {
///\name Accessors ///\name Accessors
///@{ ///@{
boost::uint64_t network() const; ///< Return 64bit network part INet6Network network() const; ///< Return <tt>/64</tt> Network of this address
bool hasEuid64() const; ///< \c true, if address is based on an EUID-64 bool hasEUI64() const; ///< \c true, if address is based on an EUID-64
boost::uint64_t id() const; ///< Return interface id (EUID-64) EUI64 id() const; ///< Return interface id (EUID-64)
bool universalId() const; ///< \c true, if the id() is universally assigned bool universalId() const; ///< \c true, if the id() is universally assigned
bool groupId() const; ///< \c true, if the id()'s \a group bit is set bool groupId() const; ///< \c true, if the id()'s \a group bit is set
......
...@@ -86,10 +86,11 @@ BOOST_AUTO_UNIT_TEST(inet6Address) ...@@ -86,10 +86,11 @@ BOOST_AUTO_UNIT_TEST(inet6Address)
{ {
INet6Address addr (INet6Address::from_string("2001:dead:beef::1002:3004")); INet6Address addr (INet6Address::from_string("2001:dead:beef::1002:3004"));
BOOST_CHECK_EQUAL( addr.network(), 0x2001deadbeef0000llu ); BOOST_CHECK_EQUAL( addr.network(), senf::INet6Network(
BOOST_CHECK_EQUAL( addr.id(), 0x0000000010023004llu ); senf::INet6Address(0x2001u,0xdeadu, 0xbeef),64) );
BOOST_CHECK( addr.hasEuid64() ); BOOST_CHECK_EQUAL( addr.id(), senf::EUI64(0x0000000010023004llu) );
BOOST_CHECK( ! INet6Address::from_inet4address(INet4Address(0x01020304)).hasEuid64() ); BOOST_CHECK( addr.hasEUI64() );
BOOST_CHECK( ! INet6Address::from_inet4address(INet4Address(0x01020304)).hasEUI64() );
BOOST_CHECK( ! addr.universalId() ); BOOST_CHECK( ! addr.universalId() );
BOOST_CHECK( ! addr.groupId() ); BOOST_CHECK( ! addr.groupId() );
BOOST_CHECK( addr.unicast() ); BOOST_CHECK( addr.unicast() );
......
...@@ -68,6 +68,18 @@ prefix_ bool senf::EUI64::isMACCompatible() ...@@ -68,6 +68,18 @@ prefix_ bool senf::EUI64::isMACCompatible()
return (*this)[3] == 0xffu && (*this)[4] == 0xfeu; return (*this)[3] == 0xffu && (*this)[4] == 0xfeu;
} }
prefix_ bool senf::EUI64::local()
const
{
return (*this)[0]&0x02;
}
prefix_ bool senf::EUI64::group()
const
{
return (*this)[0]&0x01;
}
prefix_ bool senf::EUI64::boolean_test() prefix_ bool senf::EUI64::boolean_test()
const const
{ {
......
...@@ -52,7 +52,7 @@ namespace senf { ...@@ -52,7 +52,7 @@ namespace senf {
<tr><td><tt>std::string</tt></td> <tr><td><tt>std::string</tt></td>
<td><tt>senf::EUI64::from_string("1a:2b:3c:4d-5f:60:71:82")</tt><br/> <td><tt>senf::EUI64::from_string("1a:2b:3c:4d-5f:60:71:82")</tt><br/>
<tt>senf::str(</tt><i>eui64</i><tt>)</tt></td></tr> <tt>senf::str(</tt><i>eui64</i><tt>)</tt></td></tr>
<tr><td><i>raw data</i></td> <tr><td><i>raw data</i><br/>&nbsp;&nbsp;&nbsp;&nbsp;(8 bytes)</td>
<td><tt>senf::EUI64::from_data(</tt><i>iterator</i><tt>)</tt><br/> <td><tt>senf::EUI64::from_data(</tt><i>iterator</i><tt>)</tt><br/>
<i>eui64</i><tt>.begin()</tt></td></tr> <i>eui64</i><tt>.begin()</tt></td></tr>
<tr><td>senf::MACAddress<br/>&nbsp;&nbsp;&nbsp;&nbsp;(aka EUI-48)</td> <tr><td>senf::MACAddress<br/>&nbsp;&nbsp;&nbsp;&nbsp;(aka EUI-48)</td>
...@@ -60,7 +60,16 @@ namespace senf { ...@@ -60,7 +60,16 @@ namespace senf {
<tt>senf::MACAddress::from_eui64(</tt><i>eui64</i><tt>)</tt></td></tr> <tt>senf::MACAddress::from_eui64(</tt><i>eui64</i><tt>)</tt></td></tr>
</table> </table>
Additionally, a senf::MACAddress can be converted into an EUI64 and vice versa. Since senf::EUI64 is based on \c boost::array, you can access the raw data bytes of the
address using \c begin(), \c end() or \c operator[]:
\code
senf::EUI64 eui64 (...);
std::vector<char> data;
data.resize(8);
std::copy(eui64.begin(), eui64.end(), data.begin()); // Copy 8 bytes
\endcode
\see <a href="http://tools.ietf.org/html/rfc4291">RFC 4291</a>
\ingroup addr_group \ingroup addr_group
*/ */
...@@ -86,7 +95,8 @@ namespace senf { ...@@ -86,7 +95,8 @@ namespace senf {
static EUI64 from_string(std::string const & s); static EUI64 from_string(std::string const & s);
///< Construct EUI-64 from string representation ///< Construct EUI-64 from string representation
/**< The string representation consists of 8 octets in /**< The string representation consists of 8 octets in
hexadecimal notation spearated by ':' or '-' */ hexadecimal notation spearated by ':' or '-'
\throws senf::AddressSyntaxException */
template <class InputIterator> template <class InputIterator>
static EUI64 from_data(InputIterator i); static EUI64 from_data(InputIterator i);
///< Construct EUI-64 from 8 data octets ///< Construct EUI-64 from 8 data octets
...@@ -99,6 +109,13 @@ namespace senf { ...@@ -99,6 +109,13 @@ namespace senf {
bool isMACCompatible() const; ///< \c true, if EUI64 is MAC compatible, \c false otherwise bool isMACCompatible() const; ///< \c true, if EUI64 is MAC compatible, \c false otherwise
/**< An EUI64 is MAC compatible if bytes 4th and 5th byte /**< An EUI64 is MAC compatible if bytes 4th and 5th byte
(in network byte order) are 0xfffe. */ (in network byte order) are 0xfffe. */
bool local() const; ///< \c true if the \e local bit is set, \c false otherwise
/**< The \e local bit is the second least significant bit of
the first octet (bit 6 in standard RFC bit numbering).
*/
bool group() const; ///< \c true if the \e group bit is set, \c false otherwise
/**< The \e group bit is the least significant bit of the
first octed (bit 7 in standard RFC bit numbering). */
bool boolean_test() const; ///< \c true, if EUI64 is != 0, \c false otherwise bool boolean_test() const; ///< \c true, if EUI64 is != 0, \c false otherwise
boost::uint64_t uint64() const; ///< Return EUI64 as integer number boost::uint64_t uint64() const; ///< Return EUI64 as integer number
}; };
......
...@@ -46,6 +46,8 @@ BOOST_AUTO_UNIT_TEST(eui64) ...@@ -46,6 +46,8 @@ BOOST_AUTO_UNIT_TEST(eui64)
BOOST_CHECK_EQUAL_COLLECTIONS( eui.begin(), eui.end(), data, data+sizeof(data)/sizeof(data[0]) ); BOOST_CHECK_EQUAL_COLLECTIONS( eui.begin(), eui.end(), data, data+sizeof(data)/sizeof(data[0]) );
BOOST_CHECK( eui ); BOOST_CHECK( eui );
BOOST_CHECK( eui.isMACCompatible() ); BOOST_CHECK( eui.isMACCompatible() );
BOOST_CHECK( ! eui.local() );
BOOST_CHECK( ! eui.group() );
BOOST_CHECK_EQUAL( eui.uint64(), 0x102030fffe405060ull ); BOOST_CHECK_EQUAL( eui.uint64(), 0x102030fffe405060ull );
BOOST_CHECK_EQUAL( eui, senf::EUI64::from_data(data) ); BOOST_CHECK_EQUAL( eui, senf::EUI64::from_data(data) );
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <sstream> #include <sstream>
#include <boost/io/ios_state.hpp> #include <boost/io/ios_state.hpp>
#include "ParseString.hh" #include "ParseString.hh"
#include "EUI64.hh"
//#include "MACAddress.mpp" //#include "MACAddress.mpp"
#define prefix_ #define prefix_
...@@ -47,17 +48,17 @@ prefix_ senf::MACAddress::MACAddress senf::MACAddress::from_string(std::string c ...@@ -47,17 +48,17 @@ prefix_ senf::MACAddress::MACAddress senf::MACAddress::from_string(std::string c
return mac; return mac;
} }
prefix_ senf::MACAddress senf::MACAddress::from_eui64(boost::uint64_t v) prefix_ senf::MACAddress senf::MACAddress::from_eui64(senf::EUI64 const & eui)
{ {
if ( boost::uint16_t(v>>24) != 0xfffe ) if (eui[3] != 0xffu || eui[4] != 0xfeu)
throw AddressSyntaxException(); throw AddressSyntaxException();
MACAddress mac (senf::noinit); MACAddress mac (senf::noinit);
mac[0] = boost::uint8_t( v>>56 ); mac[0] = eui[0];
mac[1] = boost::uint8_t( v>>48 ); mac[1] = eui[1];
mac[2] = boost::uint8_t( v>>40 ); mac[2] = eui[2];
mac[3] = boost::uint8_t( v>>16 ); mac[3] = eui[5];
mac[4] = boost::uint8_t( v>> 8 ); mac[4] = eui[6];
mac[5] = boost::uint8_t( v ); mac[5] = eui[7];
return mac; return mac;
} }
......
...@@ -41,39 +41,35 @@ ...@@ -41,39 +41,35 @@
namespace senf { namespace senf {
class EUI64;
/** \brief Ethernet MAC address /** \brief Ethernet MAC address
The Ethernet MAC is modelled as a fixed-size container/sequence of 6 bytes. The Ethernet MAC is modelled as a fixed-size container/sequence of 6 bytes. A MACAddress can
be converted from/to the following representations
The following statements all create the same MAC address <code>00:1A:2B:3C:4D:5F</code>
\code <table class="senf">
// Used to construct constant MAC addresses <tr><td><tt>boost::uint64_t</tt></td>
MACAddress(0x001A2B3C4D5Full) <td><tt>senf::MACAddress(0x112233445566ull)</tt><br/>
<i>mac</i><tt>.uint64()</tt></td></tr>
// Construct a MAC address from it's string representation: <tr><td><tt>std::string</tt></td>
MACAddress::from_string("00:1a:2b:3c:4d:5f") // case is ignored <td><tt>senf::MACAddress::from_string("11:22:33:44:55:66")</tt><br/>
MACAddress::from_string("00-1A-2B-3C-4D-5F") // '-' as separator is allowed too <tt>senf::str(</tt><i>mac</i><tt>)</tt></td></tr>
<tr><td><i>raw data</i><br/>&nbsp;&nbsp;&nbsp;&nbsp;(6 bytes)</td>
// Construct a MAC address from raw data. 'from_data' takes an arbitrary iterator (e.g. a <td><tt>senf::MACAddress::from_data(</tt><i>iterator</i><tt>)</tt><br/>
// pointer) as argument. Here we use a fixed array but normally you will need this to build <i>mac</i><tt>.begin()</tt></td></tr>
// a MAC address in a packet parser <tr><td>senf::EUI64</td>
char rawBytes[] = { 0x00, 0x1A, 0x2B, 0x3C, 0x4D, 0x5F }; <td><tt>senf::MACAddress::from_eui64(</tt><i>eui64</i><tt>)</tt><br/>
MACAddress::from_data(rawBytes) <tt>senf::EUI64::from_mac(</tt><i>mac</i><tt>)</tt></td></tr>
</table>
// Construct a MAC from the EUID64 as used by INet6 interfaces. The eui64 will come from an
// INet6 address:
MACAddress::from_eui64(0x001A2BFFFE3C4D5Full)
MACAddress::from_eui64(
INet6Address(0x2001u,0xDB8u,0x1u,0x0u,0x001Au,0x2BFFu,0xFE3Cu,0x3D5Fu).id())
\endcode
Since MACAddress is based on \c boost::array, you can access the raw data bytes of the Since MACAddress is based on \c boost::array, you can access the raw data bytes of the
address using \c begin(), \c end() or \c operator[]: address using \c begin(), \c end() or \c operator[]:
\code \code
MACAddress mac = ...; senf::MACAddress mac (...);
Packet::iterator i = ...; std::vector<char> data;
data.resize(6);
std::copy(mac.begin(), mac.end(), i); // Copies 6 bytes std::copy(mac.begin(), mac.end(), data.begin()); // Copy 6 bytes
\endcode \endcode
\implementation We awkwardly need to use static named constructors (<tt>from_</tt> members) \implementation We awkwardly need to use static named constructors (<tt>from_</tt> members)
...@@ -110,7 +106,7 @@ namespace senf { ...@@ -110,7 +106,7 @@ namespace senf {
\pre The input range at \a i must have a size of at \pre The input range at \a i must have a size of at
least 6 elements. */ least 6 elements. */
static MACAddress from_eui64(boost::uint64_t v); static MACAddress from_eui64(senf::EUI64 const & eui);
///< Construct address from EUI-64 ///< Construct address from EUI-64
/**< This constructor takes an EUI-64 value and converts it /**< This constructor takes an EUI-64 value and converts it
to a MAC address. This conversion is only possible, if to a MAC address. This conversion is only possible, if
...@@ -120,7 +116,7 @@ namespace senf { ...@@ -120,7 +116,7 @@ namespace senf {
compatible EUI-64. */ compatible EUI-64. */
bool local() const; ///< \c true, if address is locally administered bool local() const; ///< \c true, if address is locally administered
bool multicast() const; ///< \c true, if address is a group/multicast address bool multicast() const; ///< \c true, if address is a group/multicast address
bool broadcast() const; ///< \c true, if address is the broadcast address bool broadcast() const; ///< \c true, if address is the broadcast address
bool boolean_test() const; ///< \c true, if address is not the zero address bool boolean_test() const; ///< \c true, if address is not the zero address
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <sstream> #include <sstream>
#include "MACAddress.hh" #include "MACAddress.hh"
#include "../../../Utils/String.hh" #include "../../../Utils/String.hh"
#include "EUI64.hh"
#include "../../../Utils/auto_unit_test.hh" #include "../../../Utils/auto_unit_test.hh"
#include <boost/test/test_tools.hpp> #include <boost/test/test_tools.hpp>
...@@ -100,8 +101,9 @@ BOOST_AUTO_UNIT_TEST(macAddress) ...@@ -100,8 +101,9 @@ BOOST_AUTO_UNIT_TEST(macAddress)
BOOST_CHECK_THROW( MACAddress::from_string("01:02:03:04:05:@6"), AddressSyntaxException ); BOOST_CHECK_THROW( MACAddress::from_string("01:02:03:04:05:@6"), AddressSyntaxException );
BOOST_CHECK_THROW( MACAddress::from_string("01:02:03:04:05:[6"), AddressSyntaxException ); BOOST_CHECK_THROW( MACAddress::from_string("01:02:03:04:05:[6"), AddressSyntaxException );
BOOST_CHECK_EQUAL( mac, MACAddress::from_eui64(0xa1b2c3fffed4e5f6llu) ); BOOST_CHECK_EQUAL( mac, MACAddress::from_eui64(senf::EUI64(0xa1b2c3fffed4e5f6llu)) );
BOOST_CHECK_THROW( MACAddress::from_eui64(0u), AddressSyntaxException ); BOOST_CHECK_THROW( MACAddress::from_eui64(senf::EUI64(0ull)),
AddressSyntaxException );
BOOST_CHECK_EQUAL( MACAddress(0x1a2b3c4d5e6fULL).uint64(), 0x1a2b3c4d5e6fULL); BOOST_CHECK_EQUAL( MACAddress(0x1a2b3c4d5e6fULL).uint64(), 0x1a2b3c4d5e6fULL);
} }
......
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