X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senf%2FPackets%2F80221Bundle%2FTLVParser.cc;h=729b1ece583706b2247f715f54a849d628afe42b;hb=57daeae6f2e924ce3f16f9677c3474f531cba9e5;hp=43ba4c2d66c0f6c1ba2b9f70305724767f3d68b3;hpb=f723d7852a8195072eee387ea9ca77156b58438b;p=senf.git diff --git a/senf/Packets/80221Bundle/TLVParser.cc b/senf/Packets/80221Bundle/TLVParser.cc index 43ba4c2..729b1ec 100644 --- a/senf/Packets/80221Bundle/TLVParser.cc +++ b/senf/Packets/80221Bundle/TLVParser.cc @@ -27,22 +27,86 @@ //#include "TLVParser.ih" // Custom includes -#include #include +#include #define prefix_ -///////////////////////////////cc.p//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// +SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHFSrcIdTLVParser ); +SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHFDstIdTLVParser ); +SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHStatusTLVParser ); +SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHValidTimeIntervalTLVParser ); + +//-///////////////////////////////////////////////////////////////////////////////////////////////// // MIHBaseTLVParser -prefix_ senf::safe_data_iterator senf::MIHBaseTLVParser::resizeValueField( - MIHTLVLengthParser::value_type size) +prefix_ void senf::MIHBaseTLVParser::validateType(boost::uint8_t expectedType) + const +{ + if (! check( 1 + senf::bytes(length_()) + length()) ) + throw InvalidMIHPacketException("truncated TLV.") << " Type: " << unsigned(type()); + if (type() != expectedType) + throw InvalidMIHPacketException("wrong TLV type. expected ") << unsigned(expectedType) << " got " << unsigned(type()); +} + +prefix_ void senf::MIHBaseTLVParser::validateTypeLength(boost::uint8_t expectedType, MIHTLVLengthParser::value_type expectedLength) + const +{ + validateType( expectedType); + if (length() != expectedLength) + throw InvalidMIHPacketException("invalid length in TLV.") << " Type: " << unsigned(type()); +} + +//-///////////////////////////////////////////////////////////////////////////////////////////////// +// senf::MIHBaseListTLVParser + +prefix_ void senf::MIHBaseListTLVParser::maxListSize(MIHTLVLengthParser::value_type maxl) + const +{ + protect(), listSize_().capacity( maxl); + maxLength( maxl + senf::bytes(listSize_())); +} + +//-///////////////////////////////////////////////////////////////////////////////////////////////// +// senf::MIHFIdTLVParser + +prefix_ void senf::MIHFIdTLVParser::dump(std::ostream & os) + const +{ + senf::format::IndentHelper indent; + os << indent << "type: " << unsigned (type()) << std::endl + << indent << "length: " << unsigned (length()) << std::endl + << indent << "value:\n"; + std::string src_mihfId (valueAsString()); + hexdump(src_mihfId.begin(), src_mihfId.end(), os); +} + +prefix_ void senf::MIHFIdTLVParser::finalize() +{ + protect(), idLength_().finalize(); + length_() << idLength() + senf::bytes(idLength_()); + MIHBaseTLVParser::finalize(); +} + +prefix_ void senf::MIHFIdTLVParser::maxIdLength(boost::uint8_t maxl) + const { - MIHTLVLengthParser::value_type current_length ( length()); - length_() << size; + // the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21) + if (maxl > 253) + throw std::length_error("maximum length of a MIHF_ID is 253 octets"); + protect(), idLength_().capacity( maxl); + maxLength( maxl + senf::bytes(idLength_())); +} - safe_data_iterator si (data(), boost::next(i(), 1 + length_().bytes() )); +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 @@ -50,11 +114,198 @@ prefix_ senf::safe_data_iterator senf::MIHBaseTLVParser::resizeValueField( return si; } +prefix_ void senf::MIHFIdTLVParser::value(std::string const & id) +{ + size_type str_size (id.size()); + // the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21) + if (str_size > 253) + throw std::length_error("maximum length of a MIHF_ID is 253 octets"); + safe_data_iterator si = resizeValueField( str_size); + std::copy( id.begin(), id.end(), si); +} + +prefix_ void senf::MIHFIdTLVParser::value(senf::MACAddress const & addr) +{ + 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(4*2); + std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si)); +} + +prefix_ void senf::MIHFIdTLVParser::value(senf::INet6Address const & addr) +{ + 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(8*2); + std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si)); +} + +prefix_ void senf::MIHFIdTLVParser::value( MIHFId const & id) +{ + boost::apply_visitor( ValueSetterVisitor(*this), id); +} + +prefix_ senf::MIHFId senf::MIHFIdTLVParser::valueAs(MIHFId::Type type) + const +{ + if (length() == 0) return MIHFId(); + switch (type) { + case MIHFId::MulticastType: + return MIHFId(); + case MIHFId::MACAddress: + return MIHFId( valueAsMACAddress()); + case MIHFId::INet4Address: + return MIHFId( valueAsINet4Address()); + case MIHFId::INet6Address: + return MIHFId( valueAsINet6Address()); + case MIHFId::String: + return MIHFId( valueAsString()); + case MIHFId::EUI64: + return MIHFId( valueAsEUI64()); + } + return MIHFId(); +} + -/////////////////////////////////////////////////////////////////////////// -// MIHTLVLengthParser +//-///////////////////////////////////////////////////////////////////////////////////////////////// +// senf::MIHFSrcIdTLVParser -prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::value() const +prefix_ void senf::MIHFSrcIdTLVParser::dump(std::ostream & os) + const +{ + senf::format::IndentHelper indent; + os << indent << "source MIHF_Id TLV:\n"; + MIHFIdTLVParser::dump(os); +} + +prefix_ void senf::MIHFSrcIdTLVParser::validate() + const +{ + validateType( typeId); +} + + +//-///////////////////////////////////////////////////////////////////////////////////////////////// +// senf::MIHFDstIdTLVParser + +prefix_ void senf::MIHFDstIdTLVParser::dump(std::ostream & os) + const +{ + senf::format::IndentHelper indent; + os << indent << "destination MIHF_Id TLV:\n"; + MIHFIdTLVParser::dump(os); +} + +prefix_ void senf::MIHFDstIdTLVParser::validate() + const +{ + validateType( typeId); +} + +//-///////////////////////////////////////////////////////////////////////////////////////////////// +// senf::MIHStatusTLVParser + +prefix_ void senf::MIHStatusTLVParser::dump(std::ostream & os) + const +{ + senf::format::IndentHelper indent; + os << indent << "Status TLV:" << std::endl; + indent.increase(); + os << indent << "type: " << unsigned( type()) << std::endl + << indent << "length: " << unsigned( length()) << " byte(s)" << std::endl + << indent << "value: " << unsigned( value()); + switch (value()) { + case Success: + os << " (Success)" << std::endl; + return; + case UnspecifiedFailure: + os << " (Unspecified Failure)" << std::endl; + return; + case Rejected: + os << " (Rejected)" << std::endl; + return; + case AuthorizationFailure: + os << " (Authorization Failure)" << std::endl; + return; + case NetworkError: + os << " (Network Error)" << std::endl; + return; + } + os << " (???; invalid value!)" << std::endl; +} + +prefix_ void senf::MIHStatusTLVParser::validate() + const +{ + validateTypeLength( typeId, 1); + if (value() >= 4) + throw InvalidMIHPacketException("invalid value in MIHStatusTLV ") << unsigned( value()); +} + +//-///////////////////////////////////////////////////////////////////////////////////////////////// +// senf::MIHRegisterReqCodeTLVParser + +prefix_ void senf::MIHRegisterReqCodeTLVParser::dump(std::ostream & os) + const +{ + senf::format::IndentHelper indent; + os << indent << "Register Request Code TLV:" << std::endl; + indent.increase(); + os << indent << "type: " << unsigned( type()) << std::endl + << indent << "length: " << unsigned( length()) << " byte(s)" << std::endl + << indent << "value: " << unsigned( value()); + switch (value()) { + case Registration: + os << " (Registration)" << std::endl; + return; + case ReRegistration: + os << " (Re-Registration)" << std::endl; + return; + } + os << " (???; invalid value!)" << std::endl; +} + +prefix_ void senf::MIHRegisterReqCodeTLVParser::validate() + const +{ + validateTypeLength( typeId, 1); + if (value() >= 2) + throw InvalidMIHPacketException("invalid value in MIHRegisterReqCodeTLV ") << unsigned( value()); +} + +//-///////////////////////////////////////////////////////////////////////////////////////////////// +// senf::MIHValidTimeIntervalTLVParser + +prefix_ void senf::MIHValidTimeIntervalTLVParser::dump(std::ostream & os) + const +{ + senf::format::IndentHelper indent; + os << indent << "Valid Time Interval TLV:" << std::endl; + indent.increase(); + os << indent << "type: " << unsigned( type()) << std::endl + << indent << "length: " << unsigned( length()) << " byte(s)" << std::endl + << indent << "value: " << unsigned( value()) + << ( value()==0 ? " (infinite)" : " seconds") << std::endl; +} + +prefix_ void senf::MIHValidTimeIntervalTLVParser::validate() + const +{ + validateTypeLength( typeId, 4); +} + +//-///////////////////////////////////////////////////////////////////////////////////////////////// +// senf::MIHTLVLengthParser + +prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::value() const { switch (bytes() ) { case 1: @@ -72,8 +323,7 @@ prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::value() c }; } - -prefix_ void senf::MIHTLVLengthParser::value(value_type const & v) +prefix_ void senf::MIHTLVLengthParser::value(value_type const & v) { switch (bytes() ) { case 1: @@ -101,8 +351,7 @@ prefix_ void senf::MIHTLVLengthParser::value(value_type const & v) underflow_flag() = (v <= 128); } - -prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::maxValue() +prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::capacity() const { switch (bytes() ) { @@ -115,27 +364,24 @@ prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::maxValue( case 4: return UInt24Parser::max_value + 128; case 5: - return UInt32Parser::max_value; + return UInt32Parser::max_value; default: throw( MIHTLVLengthException()); }; } - -prefix_ senf::MIHTLVLengthParser const & senf::MIHTLVLengthParser::operator= (value_type other) +prefix_ senf::MIHTLVLengthParser const & senf::MIHTLVLengthParser::operator= (value_type other) { value(other); - return *this; + return *this; } - -prefix_ void senf::MIHTLVLengthParser::init() const +prefix_ void senf::MIHTLVLengthParser::init() const { defaultInit(); extended_length_flag() = false; } - prefix_ void senf::MIHTLVLengthParser::finalize() { value_type v = value(); @@ -159,8 +405,7 @@ prefix_ void senf::MIHTLVLengthParser::finalize() if (b != 5) resize_(5); } - -prefix_ void senf::MIHTLVLengthParser:: maxValue(MIHTLVLengthParser::value_type v) +prefix_ void senf::MIHTLVLengthParser::capacity(MIHTLVLengthParser::value_type v) { if (v <= 128) return; @@ -180,7 +425,6 @@ prefix_ void senf::MIHTLVLengthParser:: maxValue(MIHTLVLengthParser::value_type if (b < 5) resize_(5); } - prefix_ void senf::MIHTLVLengthParser::resize_(size_type size) { value_type v = value(); @@ -195,7 +439,7 @@ prefix_ void senf::MIHTLVLengthParser::resize_(size_type size) } -///////////////////////////////cc.e//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// #undef prefix_