#define prefix_
//-/////////////////////////////////////////////////////////////////////////////////////////////////
-using namespace senf;
-namespace {
+// we cannot put these test classes into the anonymous namespace because of a g++ bug
+// see https://svn.boost.org/trac/boost/ticket/3729
+
+namespace senf {
+namespace test {
class TestMessagePacketParser
: public senf::PacketParserBase
static const boost::uint16_t MESSAGE_ID;
static std::pair<bool, std::string> validate(packet message) {
- return std::make_pair(message->registerRequestCodeTLV().value() == 1, "");
+ return message->registerRequestCodeTLV().validate();
}
};
const boost::uint16_t TestMessagePacketType::MESSAGE_ID = 42;
const boost::uint16_t ValidatedTestMessagePacketType::MESSAGE_ID = 43;
-
- SENF_MIH_PACKET_REGISTRY_REGISTER( TestMessagePacket );
- SENF_MIH_PACKET_REGISTRY_REGISTER( ValidatedTestMessagePacket );
}
+}
+
+using namespace senf;
+
+SENF_MIH_PACKET_REGISTRY_REGISTER( test::TestMessagePacket );
+SENF_MIH_PACKET_REGISTRY_REGISTER( test::ValidatedTestMessagePacket );
SENF_AUTO_UNIT_TEST(MIHMessageRegistry_validate)
BOOST_CHECK( MIHPacketType::validate( mihPacket).first);
{
- TestMessagePacket testMessage (TestMessagePacket::createAfter(mihPacket));
+ test::TestMessagePacket testMessage (test::TestMessagePacket::createAfter(mihPacket));
mihPacket.finalizeAll();
BOOST_CHECK( MIHPacketType::validate( mihPacket).first);
}
{
- ValidatedTestMessagePacket testMessage (ValidatedTestMessagePacket::createAfter(mihPacket));
+ test::ValidatedTestMessagePacket testMessage (test::ValidatedTestMessagePacket::createAfter(mihPacket));
mihPacket.finalizeAll();
+ testMessage->registerRequestCodeTLV().value() << 3;
BOOST_CHECK(! MIHPacketType::validate( mihPacket).first);
testMessage->registerRequestCodeTLV().value() << 1;
BOOST_CHECK( MIHPacketType::validate( mihPacket).first);
prefix_ std::pair<bool, std::string> senf::MIHPacketType::validate(packet p)
{
- if (p.data().size() < initSize())
+ try {
+ if (p.data().size() < initSize())
+ return std::make_pair(false, "truncated MIH message");
+ if (p->version() != 1)
+ return std::make_pair(false, "invalid MIH version: " + senf::str(p->version()) );
+ if (p->payloadLength() != p.size()-8)
+ return std::make_pair(false, "wrong MIH length: " + senf::str(p->payloadLength()) );
+ if (p.next(senf::nothrow))
+ return MIHMessageRegistry::instance().validate( p->messageId(), p.next());
+ } catch (senf::TruncatedPacketException e) {
return std::make_pair(false, "truncated MIH message");
- if (p->version() != 1)
- return std::make_pair(false, "invalid MIH version: " + senf::str(p->version()) );
- if (p->payloadLength() != p.size()-8)
- return std::make_pair(false, "wrong MIH length: " + senf::str(p->payloadLength()) );
- if (p.next(senf::nothrow))
- return MIHMessageRegistry::instance().validate( p->messageId(), p.next());
+ }
return std::make_pair(true, "");
}
//#include "TLVParser.ih"
// Custom includes
-#include <iomanip>
#include <senf/Utils/hexdump.hh>
#include <senf/Utils/Format.hh>
#include <senf/Utils/String.hh>
SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHValidTimeIntervalTLVParser );
//-/////////////////////////////////////////////////////////////////////////////////////////////////
+// MIHBaseTLVParser
+
+prefix_ std::pair<bool, std::string> senf::MIHBaseTLVParser::validateTL(boost::uint8_t expectedType, MIHTLVLengthParser::value_type expectedLength)
+ const
+{
+ if (! check( 1 + senf::bytes(length_()) + length()) )
+ return std::make_pair(false, "truncated TLV. Type: " + senf::str(type()));
+ if (type() != expectedType)
+ return std::make_pair(false, "invalid TLV type: " + senf::str(type()));
+ if (length() != expectedLength)
+ return std::make_pair(false, "invalid length in TLV. Type: " + senf::str(type()));
+ return std::make_pair(true, "");
+}
+
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
// senf::MIHBaseListTLVParser
prefix_ void senf::MIHBaseListTLVParser::maxListSize(MIHTLVLengthParser::value_type maxl)
maxLength( maxl + senf::bytes(listSize_()));
}
+
//-/////////////////////////////////////////////////////////////////////////////////////////////////
// senf::MIHFIdTLVParser
MIHFIdTLVParser::dump(os);
}
+prefix_ std::pair<bool, std::string> senf::MIHFSrcIdTLVParser::validate()
+ const
+{
+ if (! check( 1 + senf::bytes(length_()) + length()) )
+ return std::make_pair(false, "truncated TLV. Type: " + senf::str(type()));
+ if (type() != typeId)
+ return std::make_pair(false, "invalid TLV type: " + senf::str(type()));
+ return std::make_pair(true, "");
+}
+
+
//-/////////////////////////////////////////////////////////////////////////////////////////////////
// senf::MIHFDstIdTLVParser
MIHFIdTLVParser::dump(os);
}
+prefix_ std::pair<bool, std::string> senf::MIHFDstIdTLVParser::validate()
+ const
+{
+ if (! check( 1 + senf::bytes(length_()) + length()) )
+ return std::make_pair(false, "truncated TLV. Type: " + senf::str(type()));
+ if (type() != typeId)
+ return std::make_pair(false, "invalid TLV type: " + senf::str(type()));
+ return std::make_pair(true, "");
+}
+
//-/////////////////////////////////////////////////////////////////////////////////////////////////
// senf::MIHStatusTLVParser
os << " (???; invalid value!)" << std::endl;
}
+prefix_ std::pair<bool, std::string> senf::MIHStatusTLVParser::validate()
+ const
+{
+ if (! validateTL( typeId, 1).first)
+ return validateTL( typeId, 1);
+ if (value() >= 4)
+ return std::make_pair(false, "invalid value in MIHStatusTLV " + senf::str(value()));
+ return std::make_pair(true, "");
+}
+
//-/////////////////////////////////////////////////////////////////////////////////////////////////
// senf::MIHRegisterReqCodeTLVParser
prefix_ std::pair<bool, std::string> senf::MIHRegisterReqCodeTLVParser::validate()
const
{
- if (length() != 1) return std::make_pair(false, "invalid length in MIHRegisterReqCodeTLV " + senf::str(length()));
- if (value() >= 2) return std::make_pair(false, "invalid value in MIHRegisterReqCodeTLV " + senf::str(value()));
+ if (! validateTL( typeId, 1).first)
+ return validateTL( typeId, 1);
+ if (value() >= 2)
+ return std::make_pair(false, "invalid value in MIHRegisterReqCodeTLV " + senf::str(value()));
return std::make_pair(true, "");
}
prefix_ std::pair<bool, std::string> senf::MIHValidTimeIntervalTLVParser::validate()
const
{
- if (length() != 4) return std::make_pair(false, "invalid length in MIHValidTimeIntervalTLV " + senf::str(length()));
+ if (! validateTL( typeId, 4).first) return validateTL( typeId, 4);
return std::make_pair(true, "");
}
\param v maximum value of length field
*/
void maxLength(MIHTLVLengthParser::value_type maxl) const;
+
+ std::pair<bool, std::string> validateTL(boost::uint8_t type, MIHTLVLengthParser::value_type length) const;
};
}
static type_t::value_type const typeId = 1;
void dump(std::ostream & os) const;
+ std::pair<bool, std::string> validate() const;
};
/** \brief Parser for 802.21 destination MIHF_ID TLV
}
static type_t::value_type const typeId = 2;
void dump(std::ostream & os) const;
+ std::pair<bool, std::string> validate() const;
};
/** \brief Parser for 802.21 Status TLV
}
static type_t::value_type const typeId = 3;
void dump(std::ostream & os) const; ///< dump string representation to given stream
+ std::pair<bool, std::string> validate() const;
enum StatusCode {
Success, UnspecifiedFailure, Rejected, AuthorizationFailure, NetworkError };