From: tho Date: Wed, 16 Dec 2009 15:20:36 +0000 (+0000) Subject: Packets/80221Bundle: fixed error in MIHF_ID-TLV; restructured TLV finalize() X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=33adfa86c0b25cb6eeda0fa12d47e077e488375a;p=senf.git Packets/80221Bundle: fixed error in MIHF_ID-TLV; restructured TLV finalize() git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1539 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/Packets/80221Bundle/MIHPacket.cc b/senf/Packets/80221Bundle/MIHPacket.cc index 7f88528..e7fba5c 100644 --- a/senf/Packets/80221Bundle/MIHPacket.cc +++ b/senf/Packets/80221Bundle/MIHPacket.cc @@ -62,8 +62,8 @@ prefix_ void senf::MIHPacketType::dump(packet p, std::ostream &os) prefix_ void senf::MIHPacketType::finalize(packet p) { - p->src_mihfId().finalizeLength(); - p->dst_mihfId().finalizeLength(); + p->src_mihfId().finalize(); + p->dst_mihfId().finalize(); p->payloadLength_() << p.size() - 8; p->messageId() << key(p.next(nothrow)); } @@ -94,7 +94,7 @@ prefix_ void senf::MIHGenericPayloadPacketType::finalize(packet p) typedef parser::tlvList_t::container tlvContainer_t; tlvContainer_t tlvs (p->tlvList() ); for (tlvContainer_t::iterator i (tlvs.begin()); i != tlvs.end(); ++i) - i->finalizeLength(); + i->finalize(); } diff --git a/senf/Packets/80221Bundle/MIHPacket.test.cc b/senf/Packets/80221Bundle/MIHPacket.test.cc index 444f576..2227b30 100644 --- a/senf/Packets/80221Bundle/MIHPacket.test.cc +++ b/senf/Packets/80221Bundle/MIHPacket.test.cc @@ -37,17 +37,6 @@ ///////////////////////////////cc.p//////////////////////////////////////// using namespace senf; -BOOST_AUTO_UNIT_TEST(MIHPacket_MIHFId) -{ - MIHFId id ( MACAddress::from_string("01:02:03:04:05:06")); - BOOST_CHECK_EQUAL( id.type(), MIHFId::MACAddress); - BOOST_CHECK_EQUAL( id, MIHFId( MACAddress::from_string("01:02:03:04:05:06"))); - BOOST_CHECK( id != MIHFId( MACAddress::from_string("01:02:03:04:05:07"))); - BOOST_CHECK( id != MIHFId( INet4Address::from_string("128.129.130.131"))); - BOOST_CHECK( id < MIHFId( MACAddress::from_string("01:02:03:04:05:07"))); - BOOST_CHECK( id < MIHFId( INet4Address::from_string("128.129.130.131"))); -} - BOOST_AUTO_UNIT_TEST(MIHPacket_msgId) { MIHPacket mihPacket (MIHPacket::create()); @@ -76,34 +65,54 @@ BOOST_AUTO_UNIT_TEST(MIHPacket_create_string) mihPacket->src_mihfId().value( "senf@berlios.de"); mihPacket->dst_mihfId().value( "test"); mihPacket.finalizeThis(); - + unsigned char data[] = { // MIH header - 0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x17, + 0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19, // source MIHF_ID TLV: - 0x01, 0x0f, // type, length + 0x01, 0x10, // type, length + 0x0f, // value-length 0x73, 0x65, 0x6e, 0x66, 0x40, 0x62, 0x65, 0x72, 0x6c, 0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65, // value // destination MIHF_ID TLV: - 0x02, 0x04, 0x74, 0x65, 0x73, 0x74 + 0x02, 0x05, 0x04, 0x74, 0x65, 0x73, 0x74 }; - BOOST_CHECK(equal( mihPacket.data().begin(), mihPacket.data().end(), data )); + SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data), + mihPacket.data().begin(), mihPacket.data().end() ); BOOST_CHECK_EQUAL( mihPacket->src_mihfId().valueAsString(), "senf@berlios.de"); BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().valueAsString(), "test"); // the maximum length of a MIHF_ID is 253 octets BOOST_CHECK_THROW( mihPacket->dst_mihfId().value( std::string(254, 'x')), std::length_error); - // now expand a MIHF_ID - mihPacket->dst_mihfId().maxLengthValue(253); - mihPacket->dst_mihfId().value( std::string(200, 'x')); + // first the tricky one: when setting the maximum id length to 128 the TLV length field + // is set to 129 and therefore expanded to 2 bytes; the id-length field is still 1 byte long + mihPacket->dst_mihfId().maxIdLength(128); + mihPacket->dst_mihfId().value( std::string(128, 'x')); mihPacket.finalizeThis(); - - BOOST_CHECK_EQUAL( mihPacket.size(), unsigned(8 + 17 + 203)); - BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 17 + 203); - BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().length(), 200u); - BOOST_CHECK_EQUAL( senf::bytes(mihPacket->dst_mihfId()), 203u); - + // packet size is now MIH header (8 bytes) + src MIHIFId TLV (18 bytes) + + // dst MIHIFId TLV (1 byte type + 2 byte TLV length + 1 byte id length + 128 id value) + BOOST_CHECK_EQUAL( mihPacket.size(), unsigned(8 + 18 + 1+2+1+128)); + BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 18 + 1+2+1+128); + BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().length(), 1+128); + BOOST_CHECK_EQUAL( senf::bytes(mihPacket->dst_mihfId()), 1+2+1+128); + // now we extend the dst id to 129 bytes; than we have 2 bytes tlv length and 2 bytes + // id-length field + mihPacket->dst_mihfId().maxIdLength(129); + mihPacket->dst_mihfId().value( std::string(129, 'x')); + mihPacket.finalizeThis(); + // packet size is now MIH header (8 bytes) + src MIHIFId TLV (18 bytes) + + // dst MIHIFId TLV (1 byte type + 2 byte TLV length + 2 byte id length + 128 id value) + BOOST_CHECK_EQUAL( mihPacket.size(), unsigned(8 + 18 + 1+2+2+129)); + BOOST_CHECK_EQUAL( mihPacket->payloadLength(), 18 + 1+2+2+129); + BOOST_CHECK_EQUAL( mihPacket->dst_mihfId().length(), 2+129); + BOOST_CHECK_EQUAL( senf::bytes(mihPacket->dst_mihfId()), 1+2+2+129); + // finally we shrink to dst id field + mihPacket->dst_mihfId().value( "test"); + mihPacket.finalizeThis(); + SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data), + mihPacket.data().begin(), mihPacket.data().end() ); + std::ostringstream oss (std::ostringstream::out); SENF_CHECK_NO_THROW( mihPacket.dump( oss)); } @@ -123,12 +132,14 @@ BOOST_AUTO_UNIT_TEST(MIHPacket_create_mac) unsigned char data[] = { // MIH header - 0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x1c, + 0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x1e, // source MIHF_ID TLV: - 0x01, 0x0c, // type, length + 0x01, 0x0d, // type, length + 0x0c, // value-length 0x5c, 0x01, 0x5c, 0x02, 0x5c, 0x03, 0x5c, 0x04, 0x5c, 0x05, 0x5c, 0x06, // value (nai-encoded) // destination MIHF_ID TLV: - 0x02, 0x0c, // type, length + 0x02, 0x0d, // type, length + 0x0c, // value-length 0x5c, 0x07, 0x5c, 0x08, 0x5c, 0x09, 0x5c, 0x0a, 0x5c, 0x0b, 0x5c, 0x0c // value (nai-encoded) }; SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data), @@ -152,12 +163,14 @@ BOOST_AUTO_UNIT_TEST(MIHPacket_create_inet4) unsigned char data[] = { // MIH header - 0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x14, + 0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x16, // source MIHF_ID TLV: - 0x01, 0x08, // type, length + 0x01, 0x09, // type, length + 0x08, // value-length 0x5c, 0x80, 0x5c, 0x81, 0x5c, 0x82, 0x5c, 0x83, // value (nai-encoded) // destination MIHF_ID TLV: - 0x02, 0x08, // type, length + 0x02, 0x09, // type, length + 0x08, // value-length 0x5c, 0x84, 0x5c, 0x85, 0x5c, 0x86, 0x5c, 0x87 // value (nai-encoded) }; SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data), @@ -183,16 +196,18 @@ BOOST_AUTO_UNIT_TEST(MIHPacket_create_inet6) unsigned char data[] = { // MIH header - 0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x44, + 0x10, 0x54, 0x00, 0x00, 0x00, 0x15, 0x00, 0x46, // source MIHF_ID TLV: - 0x01, 0x20, // type, length + 0x01, 0x21, // type, length + 0x20, // value-length // value (nai-encoded): 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0xff, 0x5c, 0xff, 0x5c, 0x01, 0x5c, 0x02, 0x5c, 0x03, 0x5c, 0x04, // destination MIHF_ID TLV: - 0x02, 0x20, // type, length + 0x02, 0x21, // type, length + 0x20, // value-length // value (nai-encoded): 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, @@ -218,11 +233,12 @@ BOOST_AUTO_UNIT_TEST(MIHPayload_parse) // variable payload length: 0x00, 0x29, // source MIHF_ID TLV: - 0x01, 0x0f, // type, length + 0x01, 0x10, // type, length + 0x0f, // value-length 0x73, 0x65, 0x6e, 0x66, 0x40, 0x62, 0x65, 0x72, 0x6c, - 0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65, // value ("senf@berlios.de") + 0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65, // value // destination MIHF_ID TLV: - 0x02, 0x04, 0x74, 0x65, 0x73, 0x74, // type, length, value ("test") + 0x02, 0x05, 0x04, 0x74, 0x65, 0x73, 0x74, // MIH Payload (two test tlvs) // first test tlv 0x42, // type @@ -289,13 +305,14 @@ BOOST_AUTO_UNIT_TEST(MIHPayload_create) // MIH header 0x10, 0x54, 0x00, 0x00, 0x00, 0x15, // variable payload length: - 0x00, 0x29, + 0x00, 0x2b, // source MIHF_ID TLV: - 0x01, 0x0f, // type, length + 0x01, 0x10, // type, length + 0x0f, // value-length 0x73, 0x65, 0x6e, 0x66, 0x40, 0x62, 0x65, 0x72, 0x6c, - 0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65, // value ("senf@berlios.de") + 0x69, 0x6f, 0x73, 0x2e, 0x64, 0x65, // value // destination MIHF_ID TLV: - 0x02, 0x04, 0x74, 0x65, 0x73, 0x74, // type, length, value ("test") + 0x02, 0x05, 0x04, 0x74, 0x65, 0x73, 0x74, // MIH Payload (two test tlvs) // first test tlv 0x42, // type diff --git a/senf/Packets/80221Bundle/MIHTypes.test.cc b/senf/Packets/80221Bundle/MIHTypes.test.cc new file mode 100644 index 0000000..4f2c71d --- /dev/null +++ b/senf/Packets/80221Bundle/MIHTypes.test.cc @@ -0,0 +1,62 @@ +// $Id$ +// +// Copyright (C) 2009 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Thorsten Horstmann +// +// 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 MIHTypes unit tests */ + +//#include "MIHTypes.test.hh" +//#include "MIHTypes.test.ih" + +// Custom includes +#include "MIHTypes.hh" + +#include +#include + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// +using namespace senf; + +BOOST_AUTO_UNIT_TEST(mihfId) +{ + MIHFId id ( MACAddress::from_string("01:02:03:04:05:06")); + BOOST_CHECK_EQUAL( id.type(), MIHFId::MACAddress); + BOOST_CHECK_EQUAL( id, MIHFId( MACAddress::from_string("01:02:03:04:05:06"))); + BOOST_CHECK( id != MIHFId( MACAddress::from_string("01:02:03:04:05:07"))); + BOOST_CHECK( id != MIHFId( INet4Address::from_string("128.129.130.131"))); + BOOST_CHECK( id < MIHFId( MACAddress::from_string("01:02:03:04:05:07"))); + BOOST_CHECK( id < MIHFId( INet4Address::from_string("128.129.130.131"))); +} + +///////////////////////////////cc.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/senf/Packets/80221Bundle/TLVParser.cc b/senf/Packets/80221Bundle/TLVParser.cc index 80d2ce7..db7ef8b 100644 --- a/senf/Packets/80221Bundle/TLVParser.cc +++ b/senf/Packets/80221Bundle/TLVParser.cc @@ -53,6 +53,37 @@ prefix_ void senf::MIHFIdTLVParser::dump(std::ostream & os) hexdump(src_mihfId.begin(), src_mihfId.end(), os); } +prefix_ void senf::MIHFIdTLVParser::finalize() +{ + protect(), idLength_().finalize(); + length_() << idLength() + idLength_().bytes(); + MIHBaseTLVParser::finalize(); +} + +prefix_ void senf::MIHFIdTLVParser::maxIdLength(boost::uint8_t maxLength) +{ + // the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21) + if (maxLength > 253) + throw std::length_error("maximum length of a MIHF_ID is 253 octets"); + protect(), idLength_().maxValue( maxLength); + maxLengthValue( maxLength + senf::bytes(idLength_())); +} + +prefix_ senf::safe_data_iterator senf::MIHFIdTLVParser::resizeValueField( + MIHTLVLengthParser::value_type size) +{ + MIHTLVLengthParser::value_type current_length ( idLength()); + idLength_() << size; + length_() << size + idLength_().bytes(); + + safe_data_iterator si (data(), valueBegin()); + if (current_length > size) + data().erase( si, boost::next(si, current_length-size)); + else + data().insert( si, size-current_length, 0); + return si; +} + prefix_ void senf::MIHFIdTLVParser::value(std::string const & id) { size_type str_size (id.size()); @@ -65,25 +96,25 @@ prefix_ void senf::MIHFIdTLVParser::value(std::string const & id) prefix_ void senf::MIHFIdTLVParser::value(senf::MACAddress const & addr) { - safe_data_iterator si = resizeValueField(12); + safe_data_iterator si = resizeValueField(6*2); std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si)); } prefix_ void senf::MIHFIdTLVParser::value(senf::INet4Address const & addr) { - safe_data_iterator si = resizeValueField(8); + safe_data_iterator si = resizeValueField(4*2); std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si)); } prefix_ void senf::MIHFIdTLVParser::value(senf::INet6Address const & addr) { - safe_data_iterator si = resizeValueField(32); + safe_data_iterator si = resizeValueField(16*2); std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si)); } prefix_ void senf::MIHFIdTLVParser::value(senf::EUI64 const & addr) { - safe_data_iterator si = resizeValueField(16); + safe_data_iterator si = resizeValueField(8*2); std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si)); } @@ -206,25 +237,6 @@ prefix_ void senf::MIHValidTimeIntervalTLVParser::dump(std::ostream & os) << ( value()==0 ? " (infinite)" : " seconds") << std::endl; } - -/////////////////////////////////////////////////////////////////////////// -// senf::MIHBaseTLVParser - -prefix_ senf::safe_data_iterator senf::MIHBaseTLVParser::resizeValueField( - MIHTLVLengthParser::value_type size) -{ - MIHTLVLengthParser::value_type current_length ( length()); - length_() << size; - - safe_data_iterator si (data(), boost::next(i(), 1 + length_().bytes() )); - if (current_length > size) - data().erase( si, boost::next(si, current_length-size)); - else - data().insert( si, size-current_length, 0); - return si; -} - - /////////////////////////////////////////////////////////////////////////// // senf::MIHTLVLengthParser @@ -328,7 +340,7 @@ prefix_ void senf::MIHTLVLengthParser::finalize() if (b != 5) resize_(5); } -prefix_ void senf::MIHTLVLengthParser:: maxValue(MIHTLVLengthParser::value_type v) +prefix_ void senf::MIHTLVLengthParser::maxValue(MIHTLVLengthParser::value_type v) { if (v <= 128) return; diff --git a/senf/Packets/80221Bundle/TLVParser.cci b/senf/Packets/80221Bundle/TLVParser.cci index 6a893be..b7bc869 100644 --- a/senf/Packets/80221Bundle/TLVParser.cci +++ b/senf/Packets/80221Bundle/TLVParser.cci @@ -54,38 +54,54 @@ prefix_ bool senf::MIHFIdTLVParser::binaryNAIDecoder::operator()(boost::uint8_t /////////////////////////////////////////////////////////////////////////// // MIHFIdTLVParser +prefix_ senf::PacketParserBase::data_iterator senf::MIHFIdTLVParser::valueBegin() + const +{ + return i( idValue_offset()); +} + +prefix_ senf::PacketParserBase::data_iterator senf::MIHFIdTLVParser::valueEnd() + const +{ + return i( idValue_offset() + idLength()); +} + prefix_ std::string senf::MIHFIdTLVParser::valueAsString() const { - return std::string( i(1+length_().bytes()), i(1+length_().bytes()+length()) ); + return std::string( valueBegin(), valueEnd()); } prefix_ senf::MACAddress senf::MIHFIdTLVParser::valueAsMACAddress() const { - return MACAddress::from_data( - getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+12) )); + if (idLength() != 6*2) throw WrapException(std::bad_cast()) + << "length of MIHF_ID does not match for a MAC address"; + return MACAddress::from_data( getNAIDecodedIterator( valueBegin(), valueEnd())); } prefix_ senf::INet4Address senf::MIHFIdTLVParser::valueAsINet4Address() const { - return INet4Address::from_data( - getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+8) )); + if (idLength() != 4*2) throw WrapException(std::bad_cast()) + << "length of MIHF_ID does not match for a INet4 address"; + return INet4Address::from_data( getNAIDecodedIterator( valueBegin(), valueEnd())); } prefix_ senf::INet6Address senf::MIHFIdTLVParser::valueAsINet6Address() const { - return INet6Address::from_data( - getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+32) )); + if (idLength() != 16*2) throw WrapException(std::bad_cast()) + << "length of MIHF_ID does not match for a INet6 address"; + return INet6Address::from_data( getNAIDecodedIterator( valueBegin(), valueEnd())); } prefix_ senf::EUI64 senf::MIHFIdTLVParser::valueAsEUI64() const { - return EUI64::from_data( - getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+16) )); + if (idLength() != 8*2) throw WrapException(std::bad_cast()) + << "length of MIHF_ID does not match for a EUI64 address"; + return EUI64::from_data( getNAIDecodedIterator( valueBegin(), valueEnd())); } prefix_ bool senf::MIHFIdTLVParser::valueEquals( std::string const &id) @@ -97,25 +113,25 @@ prefix_ bool senf::MIHFIdTLVParser::valueEquals( std::string const &id) prefix_ bool senf::MIHFIdTLVParser::valueEquals( senf::MACAddress const & addr) const { - return length()==12 && addr==valueAsMACAddress(); + return idLength()==12 && addr==valueAsMACAddress(); } prefix_ bool senf::MIHFIdTLVParser::valueEquals( senf::INet4Address const & addr) const { - return length()==8 && addr==valueAsINet4Address(); + return idLength()==8 && addr==valueAsINet4Address(); } prefix_ bool senf::MIHFIdTLVParser::valueEquals( senf::INet6Address const & addr) const { - return length()==32 && addr==valueAsINet6Address(); + return idLength()==32 && addr==valueAsINet6Address(); } prefix_ bool senf::MIHFIdTLVParser::valueEquals( senf::EUI64 const & addr) const { - return length()==16 && addr==valueAsEUI64(); + return idLength()==16 && addr==valueAsEUI64(); } prefix_ bool senf::MIHFIdTLVParser::valueEquals( MIHFId const & id) diff --git a/senf/Packets/80221Bundle/TLVParser.hh b/senf/Packets/80221Bundle/TLVParser.hh index 2df7440..f04adff 100644 --- a/senf/Packets/80221Bundle/TLVParser.hh +++ b/senf/Packets/80221Bundle/TLVParser.hh @@ -97,9 +97,9 @@ namespace senf { \endcode You have to adjust the maximum length value with the \ref maxLengthValue function - before the length value is set. The default maximum value is 127. So, in the above + before the length value is set. The default maximum value is 128. So, in the above example adding more than 21 MACAddresses to the vector will throw a TLVLengthException - if you don't call \c macAddressesTLVPacket->maxLengthValue( \e some_value) before. + if you don't call \c maxLengthValue( \e some_value) before. \see MIHTLVLengthParser \n MIHGenericTLVParser \n @@ -126,17 +126,14 @@ namespace senf { The size of the length field will be decreased to minimum necessary to hold the current length value. */ - void finalizeLength() { + void finalize() { protect(), length_().finalize(); }; typedef GenericTLVParserRegistry Registry; - - protected: - /// resize the packet after the length field to given size - senf::safe_data_iterator resizeValueField(MIHTLVLengthParser::value_type size); }; + /** \brief Parser for a generic TLV packet */ @@ -156,22 +153,26 @@ namespace senf { /** \brief Parse a MIHF_ID - the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21) - we could set maxLengthValue in init(), but for the most MIHF_IDs the default - maximum length of 127 should be enough. + Note that the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21) + We could set maxLengthValue in init(), but for the most MIHF_IDs the default + maximum length of 128 should be enough. - \note you must call mihfIdPacket.maxLengthValue( 253) *before* - setting longer MIHF_IDs values. + \note you must call maxIdLength( 253) *before* setting MIHF_IDs values longer + than 128. + + \see MIHFId */ class MIHFIdTLVParser : public MIHBaseTLVParser { # include SENF_PARSER() SENF_PARSER_INHERIT ( MIHBaseTLVParser ); - SENF_PARSER_SKIP ( length(), 0 ); + SENF_PARSER_FIELD_RO ( idLength, MIHTLVLengthParser ); + SENF_PARSER_LABEL ( idValue ); + SENF_PARSER_SKIP ( idLength(), 0 ); SENF_PARSER_FINALIZE ( MIHFIdTLVParser ); public: - ///\name value setters + ///\name Value setters ///@{ void value( MIHFId const & id); @@ -182,7 +183,7 @@ namespace senf { void value( senf::EUI64 const & addr); ///@} - ///\name value getters + ///\name Value getters ///@{ MIHFId valueAs( MIHFId::Type type) const; @@ -193,7 +194,7 @@ namespace senf { senf::EUI64 valueAsEUI64() const; ///@} - ///\name value comparisons + ///\name Value comparisons ///@{ bool valueEquals( MIHFId const & id) const; @@ -205,8 +206,16 @@ namespace senf { ///@} void dump(std::ostream & os) const; + void maxIdLength(boost::uint8_t maxLength); + void finalize(); private: + /// resize the packet after the length field to given size + senf::safe_data_iterator resizeValueField(MIHTLVLengthParser::value_type size); + + data_iterator valueBegin() const; + data_iterator valueEnd() const; + template struct binaryNAIEncoder { binaryNAIEncoder(OutputIterator & i); @@ -253,6 +262,8 @@ namespace senf { }; }; + /** \brief Parser for 802.21 source MIHF_ID TLV + */ struct MIHFSrcIdTLVParser : public MIHFIdTLVParser { MIHFSrcIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {} @@ -265,6 +276,8 @@ namespace senf { void dump(std::ostream & os) const; }; + /** \brief Parser for 802.21 destination MIHF_ID TLV + */ struct MIHFDstIdTLVParser : public MIHFIdTLVParser { MIHFDstIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {} diff --git a/senf/Packets/80221Bundle/TLVParser.test.cc b/senf/Packets/80221Bundle/TLVParser.test.cc index 5270580..4b949b7 100644 --- a/senf/Packets/80221Bundle/TLVParser.test.cc +++ b/senf/Packets/80221Bundle/TLVParser.test.cc @@ -41,7 +41,8 @@ using namespace senf; namespace { struct VoidPacket : public PacketTypeBase {}; - +} + #define CHECK_TLVParser(tlvParser, ptype, plength) \ { \ BOOST_CHECK_EQUAL( tlvParser.type(), ptype ); \ @@ -53,7 +54,6 @@ namespace { dataIterator++; \ } \ } -} BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_parse_with_simple_length) @@ -106,7 +106,7 @@ BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_with_simple_length) MIHGenericTLVParser tlvParser( p->data().begin(), &p->data()); tlvParser.type() = 42u; tlvParser.value( value); - tlvParser.finalizeLength(); + tlvParser.finalize(); CHECK_TLVParser( tlvParser, 42u, 0x0Au ); @@ -131,7 +131,7 @@ BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_with_extended_length) tlvParser.maxLengthValue( MIHTLVLengthParser::max_value); tlvParser.type() = 42u; tlvParser.value( value); - tlvParser.finalizeLength(); + tlvParser.finalize(); CHECK_TLVParser( tlvParser, 42u, sizeof(value) ); @@ -152,7 +152,7 @@ BOOST_AUTO_UNIT_TEST(MIHGenericTLVParser_create_invalid) senf::PacketInterpreterBase::size_type(2u))); MIHGenericTLVParser tlvParser( p->data().begin(), &p->data()); tlvParser.type() = 42u; - tlvParser.finalizeLength(); + tlvParser.finalize(); PacketInterpreterBase::byte value[255]; for (unsigned i=0; i p) { - p->finalizeLength(); + p->finalize(); } }; typedef ConcretePacket TestMacAddressTLVPacket;