From: pug Date: Fri, 4 Sep 2009 13:32:16 +0000 (+0000) Subject: updated ListOptionTypeParser and unittests, fixed error in ICMP packet X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=17b707d5ed5741bcbeba233eeb1efacecd990176;p=senf.git updated ListOptionTypeParser and unittests, fixed error in ICMP packet git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1383 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/Packets/DefaultBundle/ICMPv6Packet.cc b/senf/Packets/DefaultBundle/ICMPv6Packet.cc index 42a48bd..8692539 100644 --- a/senf/Packets/DefaultBundle/ICMPv6Packet.cc +++ b/senf/Packets/DefaultBundle/ICMPv6Packet.cc @@ -74,9 +74,9 @@ prefix_ void senf::ICMPv6PacketType::dump(packet p, std::ostream &os) { boost::io::ios_all_saver ias(os); os << "ICMPv6 protocol:\n" - << " type : " << p->type() <<"\n" - << " code : " << p->code() <<"\n" - << " checksum : " << p->checksum() << "\n"; + << " type : " << (unsigned) p->type() <<"\n" + << " code : " << (unsigned) p->code() <<"\n" + << " checksum : " << (unsigned) p->checksum() << "\n"; } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/senf/Packets/DefaultBundle/IPv6ExtOptionType.ct b/senf/Packets/DefaultBundle/IPv6ExtOptionType.ct index 3aa4f2a..cc5f9f2 100644 --- a/senf/Packets/DefaultBundle/IPv6ExtOptionType.ct +++ b/senf/Packets/DefaultBundle/IPv6ExtOptionType.ct @@ -30,8 +30,22 @@ template prefix_ void senf::GenericOptTypeTLVPacketParser::value(ForwardReadableRange const &range) { - safe_data_iterator si = resizeValueField( boost::size(range) ); - std::copy( boost::begin(range), boost::end(range), si); + safe_data_iterator si( data(), boost::next(data().begin()+2) ); + unsigned int rangeSize = boost::size(range); +// std::cout << "tmpl. method - optLength =" << (unsigned) optionLength() +// << ", rangeSize: " << rangeSize +// << ", optionType: " << (unsigned) optionType() << std::endl; + if ( rangeSize > optionLength() ){ +// std::cout << "rangeSize > optionLength()" << std::endl; + data().insert(si, rangeSize - optionLength(),0 ); + } + if (rangeSize < optionLength() ){ +// std::cout << "rangeSize < optionLength()" << std::endl; + data().erase(si, si + (optionLength() - rangeSize)); + } + std::copy(( boost::begin(range)), boost::end(range), si); + optionLength() = 2u; +// std::cout << "optLength AFTER =" << (unsigned) optionLength() << ", rangeSize: " << rangeSize << std::endl; } ///////////////////////////////ct.e//////////////////////////////////////// diff --git a/senf/Packets/DefaultBundle/IPv6ExtOptionType.hh b/senf/Packets/DefaultBundle/IPv6ExtOptionType.hh index ab8adf6..5feed04 100644 --- a/senf/Packets/DefaultBundle/IPv6ExtOptionType.hh +++ b/senf/Packets/DefaultBundle/IPv6ExtOptionType.hh @@ -33,9 +33,10 @@ namespace senf { class OptTypeTLVPacketParser: public PacketParserBase { public: # include SENF_PARSER() - SENF_PARSER_BITFIELD (altAction, 2, unsigned); - SENF_PARSER_BITFIELD (changeFlag, 1, unsigned); - SENF_PARSER_BITFIELD (optionType, 5, unsigned); +// SENF_PARSER_BITFIELD (altAction, 2, unsigned); +// SENF_PARSER_BITFIELD (changeFlag, 1, unsigned); +// SENF_PARSER_BITFIELD (optionType, 5, unsigned); + SENF_PARSER_FIELD (optionType, UInt8Parser); SENF_PARSER_FIELD (optionLength, UInt8Parser); SENF_PARSER_FINALIZE (OptTypeTLVPacketParser); @@ -47,10 +48,12 @@ struct GenericOptTypeTLVPacketParser: public OptTypeTLVPacketParser { SENF_PARSER_SKIP ( optionLength(), 0 ); SENF_PARSER_FINALIZE ( GenericOptTypeTLVPacketParser ); + senf::PacketInterpreterBase::range value() const; template void value(ForwardReadableRange const &range); + }; } //namespace senf diff --git a/senf/Packets/DefaultBundle/IPv6Extensions.cc b/senf/Packets/DefaultBundle/IPv6Extensions.cc index 0e39c65..ca4b9d7 100644 --- a/senf/Packets/DefaultBundle/IPv6Extensions.cc +++ b/senf/Packets/DefaultBundle/IPv6Extensions.cc @@ -72,6 +72,12 @@ prefix_ void senf::IPv6ExtensionType_HopByHop::dump(packet p, std::ostream & os) os << "Internet protocol Version 6 Hop-By-Hop extension:\n" << " next header : " << unsigned (p->nextHeader()) << "\n" << " header length : " << unsigned (p->headerLength()) << "\n"; + os << "OptionTypes:\n"; + IPv6Extension_HopByHop::Parser::options_t::container options (p->options()); + IPv6Extension_HopByHop::Parser::options_t::container::iterator optIter(options.begin()); + for(;optIter != options.end(); ++ optIter) + os << "Option Type:\t" << (unsigned) optIter->optionType() + << "\nOptionLength:\t" << (unsigned) optIter->optionLength() <<"\n"; } prefix_ void senf::IPv6ExtensionType_Destination::dump(packet p, std::ostream & os) diff --git a/senf/Packets/DefaultBundle/IPv6Extensions.test.cc b/senf/Packets/DefaultBundle/IPv6Extensions.test.cc index 4fcd159..55563a4 100644 --- a/senf/Packets/DefaultBundle/IPv6Extensions.test.cc +++ b/senf/Packets/DefaultBundle/IPv6Extensions.test.cc @@ -149,9 +149,66 @@ BOOST_AUTO_UNIT_TEST(ipv6Extensions) } //============================================================================================== - /* - no unittests for Hop by Hop - and Destination - Options extension Header yet. No real implementation there, only IPv6 extension skeleton implemented. - */ +BOOST_AUTO_UNIT_TEST(ipv6Extensions_hopByHop) +{ + unsigned char HopByHop_packetData[] = { + 0x60, 0x00, 0x00, 0x00, //IP version, class, flow label + 0x00, 0x24, //payload length + 0x00, //next header: IPv6 hop-by-hop option (0) + 0x01, //hop limit (1) + 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //IPv6 Source address (fe80::219:b9ff:feeb:b226) + 0x02, 0x19, 0xb9, 0xff, 0xfe, 0xeb, 0xb2, 0x26, + + 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //IPv6 Destination address ff02::16 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, + //HopByHop option + 0x3a, //next Header (ICMPv6) + 0x00, //Length (0 = 8Bytes) + + //option Header + 0x05, //option type + 0x02, //option Length (= 2 byte) + 0x00, 0x00, //data (zero data here ...) + + 0x02, //option type (2, set for testing purposes only) + 0x00, //option Type length (=0, no data field needed here) + + //ICMPv6 + 0x8f, //type 143 + 0x00, //code 0, should always be 0 + 0x50, 0xcc, //checksum + }; + + std::ostringstream oss (std::ostringstream::out); + + senf::IPv6Packet pHop_packet (senf::IPv6Packet::create(HopByHop_packetData)); + BOOST_CHECK_EQUAL( pHop_packet->version(), 6u ); + BOOST_CHECK_EQUAL( pHop_packet->length(), 36u ); + BOOST_CHECK_EQUAL( pHop_packet->nextHeader(), 0u ); + BOOST_CHECK_EQUAL( pHop_packet->source().value(), senf::INet6Address::from_string("fe80::219:b9ff:feeb:b226") ); + BOOST_CHECK_EQUAL( pHop_packet->destination().value(), senf::INet6Address::from_string("ff02::16") ); + + SENF_CHECK_NO_THROW( pHop_packet.dump( oss )); + BOOST_REQUIRE( pHop_packet.next().is() ); + + //hopByHop extension header + senf::IPv6Extension_HopByHop pHop_extension (pHop_packet.next().as()); + BOOST_CHECK_EQUAL( pHop_extension->nextHeader(), 58u ); + BOOST_CHECK_EQUAL( pHop_extension->headerLength(), 0x00 ); + + SENF_CHECK_NO_THROW( pHop_extension.dump( oss )); + pHop_extension.dump(std::cout); + senf::IPv6Extension_HopByHop::Parser::options_t::container optC(pHop_extension->options() ); + senf::IPv6Extension_HopByHop::Parser::options_t::container::iterator listIter (optC.begin()); + BOOST_CHECK_EQUAL( listIter->optionType(), 5u); + BOOST_CHECK_EQUAL( listIter->optionLength(), 2u); + std::cout << listIter->value() << std::endl; + ++listIter; + BOOST_CHECK_EQUAL( listIter->optionType(), 2u); + BOOST_CHECK_EQUAL( listIter->optionLength(), 0); +// pHop_extension.dump(std::cout); //( no optiontype output ... sth wrong here! ) +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ diff --git a/senf/Packets/ListOptionTypeParser.cti b/senf/Packets/ListOptionTypeParser.cti index 317c2cd..adf88ca 100644 --- a/senf/Packets/ListOptionTypeParser.cti +++ b/senf/Packets/ListOptionTypeParser.cti @@ -53,7 +53,7 @@ senf::detail::ListOptionTypeParser_Policy::bytes(data_i state_type s) const { - return AuxPolicy::aux(i, s) + AuxPolicy::aux_bytes; + return ((AuxPolicy::aux(i, s) * 8 + 6) + AuxPolicy::aux_bytes); } template @@ -73,6 +73,10 @@ senf::detail::ListOptionTypeParser_Policy::init(data_it state_type s) const { + i[0] = 1u; + i[1] = 4u; + for (unsigned int n = 2;n < 6; ++n) + i[n] = 0u; AuxPolicy::aux(0, i, s); } @@ -100,17 +104,20 @@ prefix_ void senf::detail::ListOptionTypeParser_Policy::container_policy:: construct(container_type & c) { - data_iterator i = c.i(); + safe_data_iterator i (c.data(), c.i()) ; realAux_ = (AuxPolicy::aux(i, c.state()) * 8) + 6; - data_iterator e = i + realAux_; - for (n_ = 0; i != e; ++n_) { + safe_data_iterator e = i + realAux_; + for (n_ = 0; i != e;) { unsigned int elByte = senf::bytes(ElementParser(i, c.state())); if (((i + elByte) == e) && (i[0] == 0u || i[0] == 1u)) { //check wether last element is padding or not realAux_ -= std::distance(i, e); + container_size_ -= std::distance(i, e); c.data().erase(i, e); //delete padding e = i; //set end iterator - } else + } else{ + ++n_; std::advance(i, elByte); + } } // container_size_ = std::distance(i,e); container_size_ = c.data().size(); //set actual size without padding @@ -123,20 +130,25 @@ senf::detail::ListOptionTypeParser_Policy::container_po destruct(container_type & c) { // data_iterator i (AuxPolicy::adjust(parser_type::get(p).i(), parser_type::get(p).state())); - data_iterator i = c.i(); - data_iterator const e = i + realAux_; - unsigned int padBytes = (realAux_ % 8); - c.data().insert(e, padBytes, 0u); + safe_data_iterator i (c.data(), c.i()) ; + safe_data_iterator const e = i + realAux_; + unsigned int padBytes = 0; + if (realAux_ == 0) //if list is empty, 6 padding bytes required! + padBytes = 6; + else + padBytes = ( (realAux_+2) % 8); if (padBytes > 0) { + c.data().insert(e, padBytes, 0u); if (padBytes > 1) { - e[0] = 1; + e[0] = 1u; e[1] = padBytes - 2; } else e[0] = 0; container_size_ += padBytes; + realAux_ += padBytes; ++n_; } - AuxPolicy::aux((realAux_ / 8 - 1), i, c.state()); + AuxPolicy::aux(( (realAux_ + 2)/ 8 - 1), i, c.state()); } //bytes() @@ -147,7 +159,7 @@ senf::detail::ListOptionTypeParser_Policy::container_po bytes(data_iterator i, state_type s) const { - return (realAux_ + 2); + return (realAux_ ); } //size() @@ -167,6 +179,9 @@ prefix_ void senf::detail::ListOptionTypeParser_Policy::container_policy:: init(data_iterator i, state_type s) { +// i[0] = 1u; + // for (unsigned int n = 1;n < 6; ++n) +// i[n] = 0u; n_ = 0; container_size_ = s->size(); AuxPolicy::aux(0, i, s); @@ -186,7 +201,7 @@ erase(container_type & c, data_iterator p) realAux_ -= b; --n_; // The container will be reduced by b bytes directly after this call - container_size_ = c.data().size() - b; + container_size_ -= b; } //insert() diff --git a/senf/Packets/ListOptionTypeParser.ih b/senf/Packets/ListOptionTypeParser.ih index 207bc76..d85995a 100644 --- a/senf/Packets/ListOptionTypeParser.ih +++ b/senf/Packets/ListOptionTypeParser.ih @@ -52,7 +52,7 @@ namespace senf { typedef ListParser< ListOptionTypeParser_Policy > parser_type; typedef ListParser_Container< container_policy > container_type; - static const size_type init_bytes = AuxPolicy::aux_bytes; + static const size_type init_bytes = 6 + AuxPolicy::aux_bytes; ListOptionTypeParser_Policy(); template ListOptionTypeParser_Policy(Arg const & arg);