Packets/80221Bundle: integrated GenericTLVRegistry
tho [Mon, 19 Oct 2009 09:04:23 +0000 (09:04 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1501 270642c3-0616-0410-b53a-bc976706d245

senf/Packets/80211Bundle/WLANBeaconPacket.cc
senf/Packets/80221Bundle/MIHPacket.cc
senf/Packets/80221Bundle/MIHPacket.hh
senf/Packets/80221Bundle/MIHPacket.test.cc
senf/Packets/80221Bundle/TLVParser.cc
senf/Packets/80221Bundle/TLVParser.cci
senf/Packets/80221Bundle/TLVParser.hh

index ad49dbc..ade514e 100644 (file)
@@ -44,7 +44,7 @@ prefix_ void senf::WLANBeaconPacketType::dump(packet p, std::ostream &os)
     typedef parser::ieList_t::container ieListContainer_t;
     ieListContainer_t ieListContainer (p->ieList());
     for (ieListContainer_t::iterator i = ieListContainer.begin(); i != ieListContainer.end(); ++i)
-        (*i).dump( os);
+        i->dump( os);
 }
 
 ///////////////////////////////cc.e////////////////////////////////////////
index 409f9b8..619b58d 100644 (file)
 //#include "MIHPacket.ih"
 
 // Custom includes
-#include <senf/Utils/hexdump.hh>
 #include <boost/io/ios_state.hpp>
 #include <senf/Packets/DefaultBundle/EthernetPacket.hh>
 
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-namespace {
-    SENF_PACKET_REGISTRY_REGISTER( senf::EtherTypes, 0x8917, senf::MIHPacket);
-}
-
-///////////////////////////////////////////////////////////////////////////
-// MIHFId_TLVParser
-
-prefix_ void senf::MIHFId_TLVParser::setString(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::MIHFId_TLVParser::setMACAddress(senf::MACAddress const &mac)
-{
-    safe_data_iterator si = resizeValueField(12);
-    std::copy( mac.begin(), mac.end(), getNAIEncodedOutputIterator(si));
-}
-
-prefix_ void senf::MIHFId_TLVParser::setINet4Address(senf::INet4Address const &addr)
-{
-    safe_data_iterator si = resizeValueField(8);
-    std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
-}
-
-prefix_ void senf::MIHFId_TLVParser::setINet6Address(senf::INet6Address const &addr)
-{
-    safe_data_iterator si = resizeValueField(32);
-    std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
-}
-
-prefix_ void senf::MIHFId_TLVParser::setEUI64(senf::EUI64 const &addr)
-{
-    safe_data_iterator si = resizeValueField(16);
-    std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
-}
-
-prefix_ senf::MIHFId senf::MIHFId_TLVParser::valueAs(MIHFId::Type type)
-    const
-{
-    if (length() == 0) return MIHFId();
-    switch (type) {
-    case MIHFId::Empty:
-        return MIHFId();
-    case MIHFId::MACAddress:
-        return MIHFId( asMACAddress());
-    case MIHFId::INet4Address:
-        return MIHFId( asINet4Address());
-    case MIHFId::INet6Address:
-        return MIHFId( asINet6Address());
-    case MIHFId::String:
-        return MIHFId( asINet6Address());
-    case MIHFId::EUI64:
-        return MIHFId( asINet6Address());
-    }
-    return MIHFId();
-}
+SENF_PACKET_REGISTRY_REGISTER( senf::EtherTypes, 0x8917, senf::MIHPacket);
 
 
 ///////////////////////////////////////////////////////////////////////////
@@ -105,30 +44,20 @@ prefix_ void senf::MIHPacketType::dump(packet p, std::ostream &os)
     boost::io::ios_all_saver ias(os);
     os << "MIH Packet:\n"
        << "  protocol header:\n"
-       << senf::fieldName("  version")                 << unsigned( p->version()) << "\n"
-       << senf::fieldName("  ack request")             << p->ackRequest() << "\n"
-       << senf::fieldName("  ack response")            << p->ackResponse() << "\n"
-       << senf::fieldName("  UIR")                     << p->uir() << "\n"
-       << senf::fieldName("  more fragments")          << p->moreFragment() << "\n"
-       << senf::fieldName("  fragment number")         << p->fragmentNr() << "\n"
-       << senf::fieldName("  message ID (MID)")        << unsigned( p->messageId()) << "\n"
-       << senf::fieldName("    sid")                   << unsigned( p->sid()) << "\n"        
-       << senf::fieldName("    opcode")                << unsigned( p->opcode()) << "\n"
-       << senf::fieldName("    aid")                   << unsigned( p->aid()) << "\n"      
-       << senf::fieldName("  transaction id")          << unsigned( p->transactionId()) << "\n"
-       << senf::fieldName("  payload length")          << unsigned( p->payloadLength()) << "\n"
-       << "  source MIHF_Id TLV:\n"
-       << senf::fieldName("  type")                    << unsigned (p->src_mihfId().type()) << "\n"
-       << senf::fieldName("  length")                  << unsigned (p->src_mihfId().length()) << "\n"
-       << "    value:\n";
-    std::string src_mihfId (p->src_mihfId().asString());
-    hexdump(src_mihfId.begin(), src_mihfId.end(), os);
-    os << "  destination MIHF_Id TLV:\n"
-       << senf::fieldName("  type")                    << unsigned (p->dst_mihfId().type()) << "\n"
-       << senf::fieldName("  length")                  << unsigned (p->dst_mihfId().length()) << "\n"
-       << "    value:\n";
-    std::string dst_mihfId (p->dst_mihfId().asString());
-    hexdump(dst_mihfId.begin(), dst_mihfId.end(), os);
+       << senf::fieldName("  version")           << unsigned( p->version()) << "\n"
+       << senf::fieldName("  ack request")       << p->ackRequest() << "\n"
+       << senf::fieldName("  ack response")      << p->ackResponse() << "\n"
+       << senf::fieldName("  UIR")               << p->uir() << "\n"
+       << senf::fieldName("  more fragments")    << p->moreFragment() << "\n"
+       << senf::fieldName("  fragment number")   << p->fragmentNr() << "\n"
+       << senf::fieldName("  message ID (MID)")  << unsigned( p->messageId()) << "\n"
+       << senf::fieldName("    sid")             << unsigned( p->sid()) << "\n"        
+       << senf::fieldName("    opcode")          << unsigned( p->opcode()) << "\n"
+       << senf::fieldName("    aid")             << unsigned( p->aid()) << "\n"      
+       << senf::fieldName("  transaction id")    << unsigned( p->transactionId()) << "\n"
+       << senf::fieldName("  payload length")    << unsigned( p->payloadLength()) << "\n";
+    p->src_mihfId().dump( os);
+    p->dst_mihfId().dump( os);
 }
 
 prefix_ void senf::MIHPacketType::finalize(packet p)
@@ -153,14 +82,17 @@ prefix_ senf::PacketInterpreterBase::factory_t senf::MIHPacketType::nextPacketTy
 prefix_ void senf::MIHGenericPayloadPacketType::dump(packet p, std::ostream &os)
 {
     boost::io::ios_all_saver ias(os);
-    os << "MIH Payload (service specific TLVs):\n"
-       << "  ToDo!\n";
+    os << "MIH Payload (service specific TLVs):\n";
+    typedef parser::tlvList_t::container tlvListContainer_t;
+    tlvListContainer_t tlvListContainer (p->tlvList());
+    for (tlvListContainer_t::iterator i = tlvListContainer.begin(); i != tlvListContainer.end(); ++i)
+        i->dump( os);
 }
 
 prefix_ void senf::MIHGenericPayloadPacketType::finalize(packet p)
 {
-    typedef parser::tlv_list_t::container tlvContainer_t;
-    tlvContainer_t tlvs (p->tlv_list() );
+    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();
 }
index e9f6f3c..e051bfb 100644 (file)
@@ -78,16 +78,15 @@ namespace senf {
         SENF_PARSER_GOTO_OFFSET( 8, 8); // just to limit the offset calculation
         
         // Source MIHF Id
-        SENF_PARSER_FIELD ( src_mihfId, MIHFId_TLVParser );
+        SENF_PARSER_FIELD ( src_mihfId, MIHFSrcIdTLVParser );
         // Destination MIHF Id
-        SENF_PARSER_FIELD ( dst_mihfId, MIHFId_TLVParser );
+        SENF_PARSER_FIELD ( dst_mihfId, MIHFDstIdTLVParser );
 
         SENF_PARSER_FINALIZE ( MIHPacketParser );
 
         SENF_PARSER_INIT() {
+            defaultInit();
             version_() = 1;
-            src_mihfId().type() = 1;
-            dst_mihfId().type() = 2;
         }
 
         friend class MIHPacketType;
@@ -132,7 +131,7 @@ namespace senf {
     struct MIHGenericPayloadPacketParser : public PacketParserBase
     {
     #   include SENF_PARSER()
-        SENF_PARSER_LIST ( tlv_list, packetSize(), MIHGenericTLVParser );
+        SENF_PARSER_LIST ( tlvList, packetSize(), MIHGenericTLVParser );
         SENF_PARSER_FINALIZE ( MIHGenericPayloadPacketParser );
     };
 
index 1a84a82..1ba5e0e 100644 (file)
@@ -129,7 +129,8 @@ BOOST_AUTO_UNIT_TEST(MIHPacket_create_mac)
             0x02, 0x0c,  // type, length
             0x5c, 0x07, 0x5c, 0x08, 0x5c, 0x09, 0x5c, 0x0a, 0x5c, 0x0b, 0x5c, 0x0c  // value (nai-encoded)
     };
-    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().asMACAddress(),
             MACAddress::from_string("01:02:03:04:05:06"));
@@ -159,7 +160,8 @@ BOOST_AUTO_UNIT_TEST(MIHPacket_create_inet4)
             0x02, 0x08, // type, length
             0x5c, 0x84, 0x5c, 0x85, 0x5c, 0x86, 0x5c, 0x87  // value (nai-encoded)
     };
-    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().asINet4Address(),
             INet4Address::from_string("128.129.130.131"));
@@ -197,7 +199,8 @@ BOOST_AUTO_UNIT_TEST(MIHPacket_create_inet6)
             0x5c, 0x00, 0x5c, 0x00, 0x5c, 0xff, 0x5c, 0xff,
             0x5c, 0x05, 0x5c, 0x06, 0x5c, 0x07, 0x5c, 0x08
     };
-    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().asINet6Address(),
             INet6Address::from_string("::ffff:1.2.3.4"));
@@ -237,19 +240,22 @@ BOOST_AUTO_UNIT_TEST(MIHPayload_parse)
     BOOST_REQUIRE( mihPacket.next().is<MIHGenericPayloadPacket>() );
     MIHGenericPayloadPacket mihPayload (mihPacket.next().as<MIHGenericPayloadPacket>());
 
-    BOOST_CHECK_EQUAL( mihPayload->tlv_list().size(), 2u);
-    MIHGenericPayloadPacket::Parser::tlv_list_t::container tlv_list_container (
-            mihPayload->tlv_list());
+    BOOST_CHECK_EQUAL( mihPayload->tlvList().size(), 2u);
+    MIHGenericPayloadPacket::Parser::tlvList_t::container tlvListContainer (
+            mihPayload->tlvList());
 
-    MIHGenericTLVParser tlv1 = *tlv_list_container.begin();
+    MIHGenericTLVParser tlv1 = *tlvListContainer.begin();
     BOOST_CHECK_EQUAL( tlv1.type(), 0x42);
     BOOST_CHECK_EQUAL( tlv1.length(), 0x0au);
     BOOST_CHECK_EQUAL( tlv1.value().size(), 0x0a);
 
-    MIHGenericTLVParser tlv2 = *boost::next(tlv_list_container.begin());
+    MIHGenericTLVParser tlv2 = *boost::next(tlvListContainer.begin());
     BOOST_CHECK_EQUAL( tlv2.type(), 0x43);
     BOOST_CHECK_EQUAL( tlv2.length(), 0x05u);
     BOOST_CHECK_EQUAL( tlv2.value().size(), 0x05);
+    
+    std::ostringstream oss (std::ostringstream::out);
+    SENF_CHECK_NO_THROW( mihPayload.dump( oss));
 }
 
 
@@ -262,18 +268,18 @@ BOOST_AUTO_UNIT_TEST(MIHPayload_create)
     mihPacket->dst_mihfId().setString( "test");
 
     MIHGenericPayloadPacket mihPayload (MIHGenericPayloadPacket::createAfter(mihPacket));
-    MIHGenericPayloadPacket::Parser::tlv_list_t::container tlvContainer (
-            mihPayload->tlv_list() );
+    MIHGenericPayloadPacket::Parser::tlvList_t::container tlvListContainer (
+            mihPayload->tlvList() );
     
     unsigned char tlv1_value[] = {
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
-    MIHGenericTLVParser tlv1 ( tlvContainer.push_back_space());
+    MIHGenericTLVParser tlv1 ( tlvListContainer.push_back_space());
     tlv1.type() = 0x42;
     tlv1.value( tlv1_value);
 
     unsigned char tlv2_value[] = {
             0x1a, 0x2b, 0x3c, 0x4d, 0x5e };
-    MIHGenericTLVParser tlv2 ( tlvContainer.push_back_space());
+    MIHGenericTLVParser tlv2 ( tlvListContainer.push_back_space());
     tlv2.type() = 0x43;
     tlv2.value( tlv2_value);
 
@@ -300,7 +306,6 @@ BOOST_AUTO_UNIT_TEST(MIHPayload_create)
             0x05, // first bit not set, length=5
             0x1a, 0x2b, 0x3c, 0x4d, 0x5e // value
     };
-
     SENF_CHECK_EQUAL_COLLECTIONS( data, data+sizeof(data),
             mihPacket.data().begin(), mihPacket.data().end() );    
 }
index 43ba4c2..8f9d942 100644 (file)
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
+SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHFSrcIdTLVParser );
+SENF_PACKET_TLV_REGISTRY_REGISTER( senf::MIHFDstIdTLVParser );
+
+///////////////////////////////////////////////////////////////////////////
+// senf::MIHFIdTLVParser
+
+prefix_ void senf::MIHFIdTLVParser::dump(std::ostream & os)
+    const
+{
+    os << senf::fieldName("  type")   << unsigned (type())   << "\n"
+       << senf::fieldName("  length") << unsigned (length()) << "\n"
+       << "    value:\n";
+    std::string src_mihfId (asString());
+    hexdump(src_mihfId.begin(), src_mihfId.end(), os);
+}
+
+prefix_ void senf::MIHFIdTLVParser::setString(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::setMACAddress(senf::MACAddress const &mac)
+{
+    safe_data_iterator si = resizeValueField(12);
+    std::copy( mac.begin(), mac.end(), getNAIEncodedOutputIterator(si));
+}
+
+prefix_ void senf::MIHFIdTLVParser::setINet4Address(senf::INet4Address const &addr)
+{
+    safe_data_iterator si = resizeValueField(8);
+    std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
+}
+
+prefix_ void senf::MIHFIdTLVParser::setINet6Address(senf::INet6Address const &addr)
+{
+    safe_data_iterator si = resizeValueField(32);
+    std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
+}
+
+prefix_ void senf::MIHFIdTLVParser::setEUI64(senf::EUI64 const &addr)
+{
+    safe_data_iterator si = resizeValueField(16);
+    std::copy( addr.begin(), addr.end(), getNAIEncodedOutputIterator(si));
+}
+
+prefix_ senf::MIHFId senf::MIHFIdTLVParser::valueAs(MIHFId::Type type)
+    const
+{
+    if (length() == 0) return MIHFId();
+    switch (type) {
+    case MIHFId::Empty:
+        return MIHFId();
+    case MIHFId::MACAddress:
+        return MIHFId( asMACAddress());
+    case MIHFId::INet4Address:
+        return MIHFId( asINet4Address());
+    case MIHFId::INet6Address:
+        return MIHFId( asINet6Address());
+    case MIHFId::String:
+        return MIHFId( asINet6Address());
+    case MIHFId::EUI64:
+        return MIHFId( asINet6Address());
+    }
+    return MIHFId();
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+// senf::MIHFSrcIdTLVParser
+
+prefix_ void senf::MIHFSrcIdTLVParser::dump(std::ostream & os)
+    const
+{
+    os << "  source MIHF_Id TLV:\n";
+    MIHFIdTLVParser::dump(os);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::MIHFDstIdTLVParser
+
+prefix_ void senf::MIHFDstIdTLVParser::dump(std::ostream & os)
+    const
+{
+    os << "  destination MIHF_Id TLV:\n";
+    MIHFIdTLVParser::dump(os);
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // MIHBaseTLVParser
 
@@ -52,7 +144,7 @@ prefix_ senf::safe_data_iterator senf::MIHBaseTLVParser::resizeValueField(
 
 
 ///////////////////////////////////////////////////////////////////////////
-// MIHTLVLengthParser
+// senf::MIHTLVLengthParser
 
 prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::value() const 
 {
@@ -72,7 +164,6 @@ prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::value() c
     };
 }
 
-
 prefix_ void senf::MIHTLVLengthParser::value(value_type const & v) 
 {
     switch (bytes() ) {
@@ -101,7 +192,6 @@ prefix_ void senf::MIHTLVLengthParser::value(value_type const & v)
     underflow_flag() = (v <= 128);
 }
 
-
 prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::maxValue()
     const
 {
@@ -121,21 +211,18 @@ prefix_ senf::MIHTLVLengthParser::value_type senf::MIHTLVLengthParser::maxValue(
     };
 }
 
-
 prefix_ senf::MIHTLVLengthParser const & senf::MIHTLVLengthParser::operator= (value_type other) 
 {
     value(other);
     return *this; 
 }
 
-
 prefix_ void senf::MIHTLVLengthParser::init() const 
 {
     defaultInit();
     extended_length_flag() = false;
 }
 
-
 prefix_ void senf::MIHTLVLengthParser::finalize()
 {
     value_type v = value();
@@ -159,7 +246,6 @@ prefix_ void senf::MIHTLVLengthParser::finalize()
     if (b != 5) resize_(5);
 }
 
-
 prefix_ void senf::MIHTLVLengthParser:: maxValue(MIHTLVLengthParser::value_type v)
 {
     if (v <= 128)
@@ -180,7 +266,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();
index 467a732..be724df 100644 (file)
@@ -39,36 +39,36 @@ prefix_ senf::MIHTLVLengthParser::size_type senf::MIHTLVLengthParser::bytes() co
 }
 
 ///////////////////////////////////////////////////////////////////////////
-// MIHFId_TLVParser
+// MIHFIdTLVParser
 
-prefix_ std::string senf::MIHFId_TLVParser::asString()
+prefix_ std::string senf::MIHFIdTLVParser::asString()
     const
 {
     return std::string( i(1+length_().bytes()), i(1+length_().bytes()+length()) );
 }
 
-prefix_ senf::MACAddress senf::MIHFId_TLVParser::asMACAddress()
+prefix_ senf::MACAddress senf::MIHFIdTLVParser::asMACAddress()
     const
 {
     return MACAddress::from_data( 
             getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+12) ));
 }
 
-prefix_ senf::INet4Address senf::MIHFId_TLVParser::asINet4Address()
+prefix_ senf::INet4Address senf::MIHFIdTLVParser::asINet4Address()
     const
 {
     return INet4Address::from_data( 
             getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+8) ));
 }
 
-prefix_ senf::INet6Address senf::MIHFId_TLVParser::asINet6Address()
+prefix_ senf::INet6Address senf::MIHFIdTLVParser::asINet6Address()
     const
 {
     return INet6Address::from_data( 
             getNAIDecodedIterator( i(1+length_().bytes()), i(1+length_().bytes()+32) ));
 }
 
-prefix_ senf::EUI64 senf::MIHFId_TLVParser::asEUI64()
+prefix_ senf::EUI64 senf::MIHFIdTLVParser::asEUI64()
     const
 {
     return EUI64::from_data( 
index 1ee9bfa..e6caf9c 100644 (file)
@@ -127,8 +127,10 @@ namespace senf {
             the current length value.
          */
         void finalizeLength() { 
-            protect(), length_().finalize(); 
+            protect(), length_().finalize();
         };
+    
+    typedef GenericTLVParserRegistry<MIHBaseTLVParser> Registry;
         
     protected:
         /// resize the packet after the length field to given size
@@ -161,12 +163,12 @@ namespace senf {
          \note you must call mihfIdPacket.maxLengthValue( 253) *before*
          setting longer MIHF_IDs values.
     */
-    class MIHFId_TLVParser : public MIHBaseTLVParser
+    class MIHFIdTLVParser : public MIHBaseTLVParser
     {
     #   include SENF_PARSER()
         SENF_PARSER_INHERIT  ( MIHBaseTLVParser );
         SENF_PARSER_SKIP     ( length(), 0      );
-        SENF_PARSER_FINALIZE ( MIHFId_TLVParser );
+        SENF_PARSER_FINALIZE ( MIHFIdTLVParser  );
         
     public:
         std::string asString() const;
@@ -186,6 +188,8 @@ namespace senf {
 
         MIHFId valueAs(MIHFId::Type type) const;
         
+        void dump(std::ostream & os) const;
+
     private:
         template <class OutputIterator>
         struct binaryNAIEncoder {
@@ -215,7 +219,31 @@ namespace senf {
         }
     };
 
-
+    struct MIHFSrcIdTLVParser : public MIHFIdTLVParser
+    {
+        MIHFSrcIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
+        
+        void init() const {
+            defaultInit();
+            type() << typeId+0;
+        }
+        static type_t::value_type const typeId = 1;
+        
+        void dump(std::ostream & os) const;
+    };
+    
+    struct MIHFDstIdTLVParser : public MIHFIdTLVParser
+    {
+        MIHFDstIdTLVParser(data_iterator i, state_type s) : MIHFIdTLVParser(i,s) {}
+        
+        void init() const {
+            defaultInit();
+            type() << typeId+0;
+        }
+        static type_t::value_type const typeId = 2;
+        
+        void dump(std::ostream & os) const;
+    };
 }