00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #include "TLVParser.hh"
00027
00028
00029
00030 #include <senf/Utils/hexdump.hh>
00031 #include <senf/Utils/Format.hh>
00032 #include "Exceptions.hh"
00033
00034 #define prefix_
00035
00036
00037 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHFSrcIdTLVParser );
00038 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHFDstIdTLVParser );
00039 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHStatusTLVParser );
00040 SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHValidTimeIntervalTLVParser );
00041
00042
00043
00044
00045 prefix_ void senf::MIHBaseTLVParser::validateType(boost::uint8_t expectedType)
00046 const
00047 {
00048 if (! check( 1 + senf::bytes(length_()) + length()) )
00049 throw InvalidMIHPacketException("truncated TLV.") << " Type: " << unsigned(type());
00050 if (type() != expectedType)
00051 throw InvalidMIHPacketException("wrong TLV type. expected ") << unsigned(expectedType) << " got " << unsigned(type());
00052 }
00053
00054 prefix_ void senf::MIHBaseTLVParser::validateTypeLength(boost::uint8_t expectedType, MIHTLVLengthParser::value_type expectedLength)
00055 const
00056 {
00057 validateType( expectedType);
00058 if (length() != expectedLength)
00059 throw InvalidMIHPacketException("invalid length in TLV.") << " Type: " << unsigned(type());
00060 }
00061
00062
00063
00064
00065 prefix_ void senf::MIHBaseListTLVParser::maxListSize(MIHTLVLengthParser::value_type maxl)
00066 const
00067 {
00068 protect(), listSize_().capacity( maxl);
00069 maxLength( maxl + senf::bytes(listSize_()));
00070 }
00071
00072
00073
00074
00075 prefix_ void senf::MIHFIdTLVParser::dump(std::ostream & os)
00076 const
00077 {
00078 senf::format::IndentHelper indent;
00079 os << indent << "type: " << unsigned (type()) << std::endl
00080 << indent << "length: " << unsigned (length()) << std::endl
00081 << indent << "value:\n";
00082 std::string src_mihfId (valueAsString());
00083 hexdump(src_mihfId.begin(), src_mihfId.end(), os);
00084 }
00085
00086 prefix_ void senf::MIHFIdTLVParser::finalize()
00087 {
00088 protect(), idLength_().finalize();
00089 length_() << idLength() + senf::bytes(idLength_());
00090 MIHBaseTLVParser::finalize();
00091 }
00092
00093 prefix_ void senf::MIHFIdTLVParser::maxIdLength(boost::uint8_t maxl)
00094 const
00095 {
00096
00097 if (maxl > 253)
00098 throw std::length_error("maximum length of a MIHF_ID is 253 octets");
00099 protect(), idLength_().capacity( maxl);
00100 maxLength( maxl + senf::bytes(idLength_()));
00101 }
00102
00103 prefix_ senf::safe_data_iterator senf::MIHFIdTLVParser::resizeValueField(
00104 MIHTLVLengthParser::value_type size)
00105 {
00106 MIHTLVLengthParser::value_type current_length ( idLength());
00107 idLength_() << size;
00108 length_() << size + idLength_().bytes();
00109
00110 safe_data_iterator si (data(), valueBegin());
00111 if (current_length > size)
00112 data().erase( si, boost::next(si, current_length-size));
00113 else
00114 data().insert( si, size-current_length, 0);
00115 return si;
00116 }
00117
00118 prefix_ void senf::MIHFIdTLVParser::value(std::string const & id)
00119 {
00120 size_type str_size (id.size());
00121
00122 if (str_size > 253)
00123 throw std::length_error("maximum length of a MIHF_ID is 253 octets");
00124 safe_data_iterator si = resizeValueField( str_size);
00125 std::copy( id.begin(), id.end(), si);
00126 }
00127
00128 prefix_ void senf::MIHFIdTLVParser::value(senf::MACAddress const & addr)
00129 {
00130 safe_data_iterator si = resizeValueField(6*2);
00131 std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
00132 }
00133
00134 prefix_ void senf::MIHFIdTLVParser::value(senf::INet4Address const & addr)
00135 {
00136 safe_data_iterator si = resizeValueField(4*2);
00137 std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
00138 }
00139
00140 prefix_ void senf::MIHFIdTLVParser::value(senf::INet6Address const & addr)
00141 {
00142 safe_data_iterator si = resizeValueField(16*2);
00143 std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
00144 }
00145
00146 prefix_ void senf::MIHFIdTLVParser::value(senf::EUI64 const & addr)
00147 {
00148 safe_data_iterator si = resizeValueField(8*2);
00149 std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
00150 }
00151
00152 prefix_ void senf::MIHFIdTLVParser::value( MIHFId const & id)
00153 {
00154 boost::apply_visitor( ValueSetterVisitor(*this), id);
00155 }
00156
00157 prefix_ senf::MIHFId senf::MIHFIdTLVParser::valueAs(MIHFId::Type type)
00158 const
00159 {
00160 if (length() == 0) return MIHFId();
00161 switch (type) {
00162 case MIHFId::MulticastType:
00163 return MIHFId();
00164 case MIHFId::MACAddress:
00165 return MIHFId( valueAsMACAddress());
00166 case MIHFId::INet4Address:
00167 return MIHFId( valueAsINet4Address());
00168 case MIHFId::INet6Address:
00169 return MIHFId( valueAsINet6Address());
00170 case MIHFId::String:
00171 return MIHFId( valueAsString());
00172 case MIHFId::EUI64:
00173 return MIHFId( valueAsEUI64());
00174 }
00175 return MIHFId();
00176 }
00177
00178
00179
00180
00181
00182 prefix_ void senf::MIHFSrcIdTLVParser::dump(std::ostream & os)
00183 const
00184 {
00185 senf::format::IndentHelper indent;
00186 os << indent << "source MIHF_Id TLV:\n";
00187 MIHFIdTLVParser::dump(os);
00188 }
00189
00190 prefix_ void senf::MIHFSrcIdTLVParser::validate()
00191 const
00192 {
00193 validateType( typeId);
00194 }
00195
00196
00197
00198
00199
00200 prefix_ void senf::MIHFDstIdTLVParser::dump(std::ostream & os)
00201 const
00202 {
00203 senf::format::IndentHelper indent;
00204 os << indent << "destination MIHF_Id TLV:\n";
00205 MIHFIdTLVParser::dump(os);
00206 }
00207
00208 prefix_ void senf::MIHFDstIdTLVParser::validate()
00209 const
00210 {
00211 validateType( typeId);
00212 }
00213
00214
00215
00216
00217 prefix_ void senf::MIHStatusTLVParser::dump(std::ostream & os)
00218 const
00219 {
00220 senf::format::IndentHelper indent;
00221 os << indent << "Status TLV:" << std::endl;
00222 indent.increase();
00223 os << indent << "type: " << unsigned( type()) << std::endl
00224 << indent << "length: " << unsigned( length()) << " byte(s)" << std::endl
00225 << indent << "value: " << unsigned( value());
00226 switch (value()) {
00227 case Success:
00228 os << " (Success)" << std::endl;
00229 return;
00230 case UnspecifiedFailure:
00231 os << " (Unspecified Failure)" << std::endl;
00232 return;
00233 case Rejected:
00234 os << " (Rejected)" << std::endl;
00235 return;
00236 case AuthorizationFailure:
00237 os << " (Authorization Failure)" << std::endl;
00238 return;
00239 case NetworkError:
00240 os << " (Network Error)" << std::endl;
00241 return;
00242 }
00243 os << " (???; invalid value!)" << std::endl;
00244 }
00245
00246 prefix_ void senf::MIHStatusTLVParser::validate()
00247 const
00248 {
00249 validateTypeLength( typeId, 1);
00250 if (value() >= 4)
00251 throw InvalidMIHPacketException("invalid value in MIHStatusTLV ") << unsigned( value());
00252 }
00253
00254
00255
00256
00257 prefix_ void senf::MIHRegisterReqCodeTLVParser::dump(std::ostream & os)
00258 const
00259 {
00260 senf::format::IndentHelper indent;
00261 os << indent << "Register Request Code TLV:" << std::endl;
00262 indent.increase();
00263 os << indent << "type: " << unsigned( type()) << std::endl
00264 << indent << "length: " << unsigned( length()) << " byte(s)" << std::endl
00265 << indent << "value: " << unsigned( value());
00266 switch (value()) {
00267 case Registration:
00268 os << " (Registration)" << std::endl;
00269 return;
00270 case ReRegistration:
00271 os << " (Re-Registration)" << std::endl;
00272 return;
00273 }
00274 os << " (???; invalid value!)" << std::endl;
00275 }
00276
00277 prefix_ void senf::MIHRegisterReqCodeTLVParser::validate()
00278 const
00279 {
00280 validateTypeLength( typeId, 1);
00281 if (value() >= 2)
00282 throw InvalidMIHPacketException("invalid value in MIHRegisterReqCodeTLV ") << unsigned( value());
00283 }
00284
00285
00286
00287
00288 prefix_ void senf::MIHValidTimeIntervalTLVParser::dump(std::ostream & os)
00289 const
00290 {
00291 senf::format::IndentHelper indent;
00292 os << indent << "Valid Time Interval TLV:" << std::endl;
00293 indent.increase();
00294 os << indent << "type: " << unsigned( type()) << std::endl
00295 << indent << "length: " << unsigned( length()) << " byte(s)" << std::endl
00296 << indent << "value: " << unsigned( value())
00297 << ( value()==0 ? " (infinite)" : " seconds") << std::endl;
00298 }
00299
00300 prefix_ void senf::MIHValidTimeIntervalTLVParser::validate()
00301 const
00302 {
00303 validateTypeLength( typeId, 4);
00304 }
00305
00306
00307
00308
00309 prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::value() const
00310 {
00311 switch (bytes() ) {
00312 case 1:
00313 return length_field().value();
00314 case 2:
00315 return parse<UInt8Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
00316 case 3:
00317 return parse<UInt16Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
00318 case 4:
00319 return parse<UInt24Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
00320 case 5:
00321 return parse<UInt32Parser>( 1 ).value() + (underflow_flag() ? 0 : 128u);
00322 default:
00323 throw( MIHTLVLengthException());
00324 };
00325 }
00326
00327 prefix_ void senf::MIHTLVLengthParser::value(value_type const & v)
00328 {
00329 switch (bytes() ) {
00330 case 1:
00331 if (v > 128) throw( MIHTLVLengthException());
00332 length_field() = v;
00333 return;
00334 case 2:
00335 if (v > UInt8Parser::max_value + 128) throw( MIHTLVLengthException());
00336 parse<UInt8Parser>(1) = v - (v>128 ? 128 : 0);
00337 break;
00338 case 3:
00339 if (v > UInt16Parser::max_value + 128) throw( MIHTLVLengthException());
00340 parse<UInt16Parser>(1) = v - (v>128 ? 128 : 0);
00341 break;;
00342 case 4:
00343 if (v > UInt24Parser::max_value + 128) throw( MIHTLVLengthException());
00344 parse<UInt24Parser>(1) = v - (v>128 ? 128 : 0);
00345 break;
00346 case 5:
00347 parse<UInt32Parser>(1) = v - (v>128 ? 128 : 0);
00348 break;
00349 default:
00350 throw( MIHTLVLengthException());
00351 };
00352 underflow_flag() = (v <= 128);
00353 }
00354
00355 prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::capacity()
00356 const
00357 {
00358 switch (bytes() ) {
00359 case 1:
00360 return 128;
00361 case 2:
00362 return UInt8Parser::max_value + 128;
00363 case 3:
00364 return UInt16Parser::max_value + 128;
00365 case 4:
00366 return UInt24Parser::max_value + 128;
00367 case 5:
00368 return UInt32Parser::max_value;
00369 default:
00370 throw( MIHTLVLengthException());
00371 };
00372 }
00373
00374 prefix_ senf::MIHTLVLengthParser const & senf::MIHTLVLengthParser::operator= (value_type other)
00375 {
00376 value(other);
00377 return *this;
00378 }
00379
00380 prefix_ void senf::MIHTLVLengthParser::init() const
00381 {
00382 defaultInit();
00383 extended_length_flag() = false;
00384 }
00385
00386 prefix_ void senf::MIHTLVLengthParser::finalize()
00387 {
00388 value_type v = value();
00389 size_type b = bytes();
00390 if (v <= 128) {
00391 if (b != 1) resize_(1);
00392 return;
00393 }
00394 if (v <= UInt8Parser::max_value + 128) {
00395 if (b != 2) resize_(2);
00396 return;
00397 }
00398 if (v <= UInt16Parser::max_value + 128) {
00399 if (b != 3) resize_(3);
00400 return;
00401 }
00402 if (v <= UInt24Parser::max_value + 128 ) {
00403 if (b != 4) resize_(4);
00404 return;
00405 }
00406 if (b != 5) resize_(5);
00407 }
00408
00409 prefix_ void senf::MIHTLVLengthParser::capacity(MIHTLVLengthParser::value_type v)
00410 {
00411 if (v <= 128)
00412 return;
00413 size_type b = bytes();
00414 if (v <= UInt8Parser::max_value + 128) {
00415 if (b < 2) resize_(2);
00416 return;
00417 }
00418 if (v <= UInt16Parser::max_value + 128) {
00419 if (b < 3) resize_(3);
00420 return;
00421 }
00422 if (v <= UInt24Parser::max_value + 128) {
00423 if (b < 4) resize_(4);
00424 return;
00425 }
00426 if (b < 5) resize_(5);
00427 }
00428
00429 prefix_ void senf::MIHTLVLengthParser::resize_(size_type size)
00430 {
00431 value_type v = value();
00432 resize(bytes(), size);
00433 if (size > 1) {
00434 extended_length_flag() = true;
00435 fixed_length_field() = size - 1;
00436 } else {
00437 extended_length_flag() = false;
00438 }
00439 value(v);
00440 }
00441
00442
00443
00444 #undef prefix_
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455