Search:

SENF Extensible Network Framework

  • Home
  • Download
  • Wiki
  • BerliOS
  • ChangeLog
  • Browse SVN
  • Bug Tracker
  • Overview
  • Examples
  • HowTos
  • Glossary
  • PPI
  • Packets
  • Scheduler
  • Socket
  • Utils
  • Console
  • Daemon
  • Logger
  • Termlib
  • Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

80221Bundle/TLVParser.cc

Go to the documentation of this file.
00001 // $Id: TLVParser.cc 1789 2011-05-19 09:31:33Z tho $
00002 //
00003 // Copyright (C) 2007
00004 // Fraunhofer (FOKUS)
00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY
00006 //     Thorsten Horstmann <tho@berlios.de>
00007 //
00008 // This program is free software; you can redistribute it and/or modify
00009 // it under the terms of the GNU General Public License as published by
00010 // the Free Software Foundation; either version 2 of the License, or
00011 // (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the
00020 // Free Software Foundation, Inc.,
00021 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00026 #include "TLVParser.hh"
00027 //#include "TLVParser.ih"
00028 
00029 // Custom includes
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 // MIHBaseTLVParser
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 // senf::MIHBaseListTLVParser
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 // senf::MIHFIdTLVParser
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     // the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
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     // the maximum length of a MIHF_ID is 253 octets (see F.3.11 in 802.21)
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 // senf::MIHFSrcIdTLVParser
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 // senf::MIHFDstIdTLVParser
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 // senf::MIHStatusTLVParser
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 // senf::MIHRegisterReqCodeTLVParser
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 // senf::MIHValidTimeIntervalTLVParser
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 // senf::MIHTLVLengthParser
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 // Local Variables:
00448 // mode: c++
00449 // fill-column: 100
00450 // c-file-style: "senf"
00451 // indent-tabs-mode: nil
00452 // ispell-local-dictionary: "american"
00453 // compile-command: "scons -u test"
00454 // comment-column: 40
00455 // End:

Contact: senf-dev@lists.berlios.de | © 2006-2010 Fraunhofer Institute for Open Communication Systems, Network Research