From: g0dil Date: Sun, 17 May 2009 22:18:20 +0000 (+0000) Subject: Socket/Protocols: Replace uint64 with EUI64 in address classes X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=c5959efa66ac3c393ecd0967b127249210a46f21;p=senf.git Socket/Protocols: Replace uint64 with EUI64 in address classes git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1213 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Socket/Protocols/INet/INet6Address.cci b/Socket/Protocols/INet/INet6Address.cci index 9a71c7b..f94c0d7 100644 --- a/Socket/Protocols/INet/INet6Address.cci +++ b/Socket/Protocols/INet/INet6Address.cci @@ -88,32 +88,25 @@ prefix_ senf::INet6Address senf::INet6Address::from_mac(senf::MACAddress const & 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 { - return - ((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) ); + return senf::INet6Network(*this, 64); } -prefix_ boost::uint64_t senf::INet6Address::id() +prefix_ senf::EUI64 senf::INet6Address::id() const { - return - ((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) ); + return senf::EUI64::from_data(begin()+8); } prefix_ bool senf::INet6Address::universalId() @@ -166,7 +159,7 @@ prefix_ bool senf::INet6Address::unicast() return ! multicast(); } -prefix_ bool senf::INet6Address::hasEuid64() +prefix_ bool senf::INet6Address::hasEUI64() const { return unicast() && ((*this)[0]&0xE0u) != 0u; diff --git a/Socket/Protocols/INet/INet6Address.hh b/Socket/Protocols/INet/INet6Address.hh index 3eb7094..a80e0ad 100644 --- a/Socket/Protocols/INet/INet6Address.hh +++ b/Socket/Protocols/INet/INet6Address.hh @@ -38,6 +38,7 @@ #include "INet4Address.hh" #include "../AddressExceptions.hh" #include "../Raw/MACAddress.hh" +#include "../Raw/EUI64.hh" //#include "INet6Address.mpp" #include "INet6Address.ih" @@ -45,6 +46,8 @@ namespace senf { + class INet6Network; + /** \brief INet6 network address This implementation of an INet6 address is based strictly on @@ -208,6 +211,11 @@ namespace senf { ///< Construct a link-local INet6 address /**< This will construct a link local address of the form fe80::xxxx:xxff:fexx:xxxx. */ + + static INet6Address from_eui64(senf::EUI64 const & eui); + ///< Construct link-local INet6 address + /**< This will construct a link local address of the form + fe80::xxxx:xxxx:xxxx:xxxx. */ in6_addr toin6_addr() const; ///< get the linux in6_addr struct (convinience only) @@ -216,9 +224,9 @@ namespace senf { ///\name Accessors ///@{ - boost::uint64_t network() const; ///< Return 64bit network part - bool hasEuid64() const; ///< \c true, if address is based on an EUID-64 - boost::uint64_t id() const; ///< Return interface id (EUID-64) + INet6Network network() const; ///< Return /64 Network of this address + bool hasEUI64() const; ///< \c true, if address is based on an EUID-64 + EUI64 id() const; ///< Return interface id (EUID-64) 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 diff --git a/Socket/Protocols/INet/INet6Address.test.cc b/Socket/Protocols/INet/INet6Address.test.cc index f56ce6e..241eeda 100644 --- a/Socket/Protocols/INet/INet6Address.test.cc +++ b/Socket/Protocols/INet/INet6Address.test.cc @@ -86,10 +86,11 @@ BOOST_AUTO_UNIT_TEST(inet6Address) { INet6Address addr (INet6Address::from_string("2001:dead:beef::1002:3004")); - BOOST_CHECK_EQUAL( addr.network(), 0x2001deadbeef0000llu ); - BOOST_CHECK_EQUAL( addr.id(), 0x0000000010023004llu ); - BOOST_CHECK( addr.hasEuid64() ); - BOOST_CHECK( ! INet6Address::from_inet4address(INet4Address(0x01020304)).hasEuid64() ); + BOOST_CHECK_EQUAL( addr.network(), senf::INet6Network( + senf::INet6Address(0x2001u,0xdeadu, 0xbeef),64) ); + BOOST_CHECK_EQUAL( addr.id(), senf::EUI64(0x0000000010023004llu) ); + BOOST_CHECK( addr.hasEUI64() ); + BOOST_CHECK( ! INet6Address::from_inet4address(INet4Address(0x01020304)).hasEUI64() ); BOOST_CHECK( ! addr.universalId() ); BOOST_CHECK( ! addr.groupId() ); BOOST_CHECK( addr.unicast() ); diff --git a/Socket/Protocols/Raw/EUI64.cci b/Socket/Protocols/Raw/EUI64.cci index 6b40b7f..6f51aa1 100644 --- a/Socket/Protocols/Raw/EUI64.cci +++ b/Socket/Protocols/Raw/EUI64.cci @@ -68,6 +68,18 @@ prefix_ bool senf::EUI64::isMACCompatible() 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() const { diff --git a/Socket/Protocols/Raw/EUI64.hh b/Socket/Protocols/Raw/EUI64.hh index f1fc844..aa70d01 100644 --- a/Socket/Protocols/Raw/EUI64.hh +++ b/Socket/Protocols/Raw/EUI64.hh @@ -52,7 +52,7 @@ namespace senf { std::string senf::EUI64::from_string("1a:2b:3c:4d-5f:60:71:82")
senf::str(eui64) - raw data + raw data
    (8 bytes) senf::EUI64::from_data(iterator)
eui64.begin() senf::MACAddress
    (aka EUI-48) @@ -60,7 +60,16 @@ namespace senf { senf::MACAddress::from_eui64(eui64) - 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 data; + data.resize(8); + std::copy(eui64.begin(), eui64.end(), data.begin()); // Copy 8 bytes + \endcode + + \see RFC 4291 \ingroup addr_group */ @@ -86,7 +95,8 @@ namespace senf { static EUI64 from_string(std::string const & s); ///< Construct EUI-64 from string representation /**< The string representation consists of 8 octets in - hexadecimal notation spearated by ':' or '-' */ + hexadecimal notation spearated by ':' or '-' + \throws senf::AddressSyntaxException */ template static EUI64 from_data(InputIterator i); ///< Construct EUI-64 from 8 data octets @@ -99,6 +109,13 @@ namespace senf { bool isMACCompatible() const; ///< \c true, if EUI64 is MAC compatible, \c false otherwise /**< An EUI64 is MAC compatible if bytes 4th and 5th byte (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 boost::uint64_t uint64() const; ///< Return EUI64 as integer number }; diff --git a/Socket/Protocols/Raw/EUI64.test.cc b/Socket/Protocols/Raw/EUI64.test.cc index 3c53281..a36051d 100644 --- a/Socket/Protocols/Raw/EUI64.test.cc +++ b/Socket/Protocols/Raw/EUI64.test.cc @@ -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( eui ); BOOST_CHECK( eui.isMACCompatible() ); + BOOST_CHECK( ! eui.local() ); + BOOST_CHECK( ! eui.group() ); BOOST_CHECK_EQUAL( eui.uint64(), 0x102030fffe405060ull ); BOOST_CHECK_EQUAL( eui, senf::EUI64::from_data(data) ); diff --git a/Socket/Protocols/Raw/MACAddress.cc b/Socket/Protocols/Raw/MACAddress.cc index 43a2882..53a96fb 100644 --- a/Socket/Protocols/Raw/MACAddress.cc +++ b/Socket/Protocols/Raw/MACAddress.cc @@ -32,6 +32,7 @@ #include #include #include "ParseString.hh" +#include "EUI64.hh" //#include "MACAddress.mpp" #define prefix_ @@ -47,17 +48,17 @@ prefix_ senf::MACAddress::MACAddress senf::MACAddress::from_string(std::string c 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(); MACAddress mac (senf::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 ); + mac[0] = eui[0]; + mac[1] = eui[1]; + mac[2] = eui[2]; + mac[3] = eui[5]; + mac[4] = eui[6]; + mac[5] = eui[7]; return mac; } diff --git a/Socket/Protocols/Raw/MACAddress.hh b/Socket/Protocols/Raw/MACAddress.hh index 64049dd..cc4a6ba 100644 --- a/Socket/Protocols/Raw/MACAddress.hh +++ b/Socket/Protocols/Raw/MACAddress.hh @@ -41,39 +41,35 @@ namespace senf { + class EUI64; + /** \brief Ethernet MAC address - The Ethernet MAC is modelled as a fixed-size container/sequence of 6 bytes. - - The following statements all create the same MAC address 00:1A:2B:3C:4D:5F - \code - // Used to construct constant MAC addresses - MACAddress(0x001A2B3C4D5Full) - - // Construct a MAC address from it's string representation: - MACAddress::from_string("00:1a:2b:3c:4d:5f") // case is ignored - MACAddress::from_string("00-1A-2B-3C-4D-5F") // '-' as separator is allowed too - - // Construct a MAC address from raw data. 'from_data' takes an arbitrary iterator (e.g. a - // pointer) as argument. Here we use a fixed array but normally you will need this to build - // a MAC address in a packet parser - char rawBytes[] = { 0x00, 0x1A, 0x2B, 0x3C, 0x4D, 0x5F }; - MACAddress::from_data(rawBytes) - - // 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 + The Ethernet MAC is modelled as a fixed-size container/sequence of 6 bytes. A MACAddress can + be converted from/to the following representations + + + + + + + + + + +
boost::uint64_tsenf::MACAddress(0x112233445566ull)
+ mac.uint64()
std::stringsenf::MACAddress::from_string("11:22:33:44:55:66")
+ senf::str(mac)
raw data
    (6 bytes)
senf::MACAddress::from_data(iterator)
+ mac.begin()
senf::EUI64senf::MACAddress::from_eui64(eui64)
+ senf::EUI64::from_mac(mac)
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[]: \code - MACAddress mac = ...; - Packet::iterator i = ...; - - std::copy(mac.begin(), mac.end(), i); // Copies 6 bytes + senf::MACAddress mac (...); + std::vector data; + data.resize(6); + std::copy(mac.begin(), mac.end(), data.begin()); // Copy 6 bytes \endcode \implementation We awkwardly need to use static named constructors (from_ members) @@ -110,7 +106,7 @@ namespace senf { \pre The input range at \a i must have a size of at least 6 elements. */ - static MACAddress from_eui64(boost::uint64_t v); + static MACAddress from_eui64(senf::EUI64 const & eui); ///< 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 @@ -120,7 +116,7 @@ namespace senf { compatible EUI-64. */ 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 boolean_test() const; ///< \c true, if address is not the zero address diff --git a/Socket/Protocols/Raw/MACAddress.test.cc b/Socket/Protocols/Raw/MACAddress.test.cc index 5dd8691..34749b0 100644 --- a/Socket/Protocols/Raw/MACAddress.test.cc +++ b/Socket/Protocols/Raw/MACAddress.test.cc @@ -30,6 +30,7 @@ #include #include "MACAddress.hh" #include "../../../Utils/String.hh" +#include "EUI64.hh" #include "../../../Utils/auto_unit_test.hh" #include @@ -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_EQUAL( mac, MACAddress::from_eui64(0xa1b2c3fffed4e5f6llu) ); - BOOST_CHECK_THROW( MACAddress::from_eui64(0u), AddressSyntaxException ); + BOOST_CHECK_EQUAL( mac, MACAddress::from_eui64(senf::EUI64(0xa1b2c3fffed4e5f6llu)) ); + BOOST_CHECK_THROW( MACAddress::from_eui64(senf::EUI64(0ull)), + AddressSyntaxException ); BOOST_CHECK_EQUAL( MACAddress(0x1a2b3c4d5e6fULL).uint64(), 0x1a2b3c4d5e6fULL); }