From: g0dil Date: Thu, 24 Sep 2009 12:51:11 +0000 (+0000) Subject: Packets/DefaultBundle: Fix ICMPv5Packet::calcChecksum() and finalize() X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=d70c73b66dbc60224d373f7a97cada419fe57c05;p=senf.git Packets/DefaultBundle: Fix ICMPv5Packet::calcChecksum() and finalize() git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1442 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/.gitignore b/.gitignore index d210c44..ba35e05 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ *.png *.o *.a +*.os +*.so *.test.checked .sconsign* *~ diff --git a/senf/Packets/DefaultBundle/ICMPv6Packet.cc b/senf/Packets/DefaultBundle/ICMPv6Packet.cc index 8c41023..8023f3e 100644 --- a/senf/Packets/DefaultBundle/ICMPv6Packet.cc +++ b/senf/Packets/DefaultBundle/ICMPv6Packet.cc @@ -35,35 +35,41 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -namespace { - SENF_PACKET_REGISTRY_REGISTER( senf::IpTypes, 58, senf::ICMPv6Packet); -} +SENF_PACKET_REGISTRY_REGISTER( senf::IpTypes, 58, senf::ICMPv6Packet); prefix_ boost::uint16_t senf::ICMPv6PacketParser::calcChecksum() const { - - senf::IpChecksum summer; senf::IPv6Packet ipv6 (packet().rfind(senf::nothrow)); - - if (! ipv6) - return 0u; + if (! ipv6) return 0u; - summer.feed( ipv6->source().i(), - ipv6->source().i() + senf::IPv6Packet::Parser::source_t::fixed_bytes ); - // The destination used here must be the *final* destination ... - summer.feed( ipv6->destination().i(), ipv6->destination().i() + senf::IPv6PacketParser::destination_t::fixed_bytes ); + senf::IpChecksum summer; - // This is a simplification. The value is really 32bit to support UDP Jumbograms - // (RFC2147). However, skipping an even number of 0 bytes does not change the checksum - summer.feed( i() + ipv6->length(), i() + ipv6->length() + 2 ); - // --> http://www.iana.org/assignments/protocol-numbers - // need to insert the correct protocol number here, NOT static 17!! + //////////////////////////////////////// + // IPv6 pseudo header + summer.feed( ipv6->source().i(), + ipv6->source().i() + senf::IPv6Packet::Parser::source_t::fixed_bytes ); + // need support for HopByHop routing header -> the destination used here must be the *final* + // destination ... + summer.feed( ipv6->destination().i(), + ipv6->destination().i() + senf::IPv6PacketParser::destination_t::fixed_bytes ); + // packet length + boost::uint32_t size (data().size()); + summer.feed((size>>24)&0xff); + summer.feed((size>>16)&0xff); + summer.feed((size>> 8)&0xff); + summer.feed((size )&0xff); + // protocol number + // summer.feed( 0u ); + // summer.feed( 0u ); summer.feed( 0u ); summer.feed( 58u ); - // since header are 16 / even 32bit aligned we don't have to care for padding. since IpChecksum - // cares for padding at the final summing we don't have to care is the payload is 16nbit-aligned, too. + + //////////////////////////////////////// + // ICMP Packet summer.feed( i(), i()+checksum_offset ); + // checksum + // summer.feed(0); summer.feed(0); summer.feed( i()+checksum_offset+2, data().end() ); boost::uint16_t rv (summer.sum()); diff --git a/senf/Packets/DefaultBundle/ICMPv6Packet.hh b/senf/Packets/DefaultBundle/ICMPv6Packet.hh index 0c8586b..aff2010 100644 --- a/senf/Packets/DefaultBundle/ICMPv6Packet.hh +++ b/senf/Packets/DefaultBundle/ICMPv6Packet.hh @@ -84,8 +84,8 @@ namespace senf } static void finalize(packet p) { - p->checksum() << p->calcChecksum(); p->type() << key(p.next(senf::nothrow)); + p->checksum() << p->calcChecksum(); } }; diff --git a/senf/Packets/DefaultBundle/ICMPv6Packet.test.cc b/senf/Packets/DefaultBundle/ICMPv6Packet.test.cc index 9b61d53..2ee67f1 100644 --- a/senf/Packets/DefaultBundle/ICMPv6Packet.test.cc +++ b/senf/Packets/DefaultBundle/ICMPv6Packet.test.cc @@ -193,28 +193,42 @@ BOOST_AUTO_UNIT_TEST(ICMPv6Packet_create) ip.finalizeAll(); - std::stringstream ss; - ip.dump(ss); - BOOST_CHECK_EQUAL( ss.str(), - "Internet protocol Version 6:\n" - " version : 6\n" - " traffic class : 0x00\n" - " flow label : 0x00000\n" - " payload length : 64\n" - " next header : 58\n" - " hop limit : 64\n" - " source : ::1\n" - " destination : ::1\n" - "ICMPv6 protocol:\n" - " type : 128\n" - " code : 0\n" - " checksum : 0xdae0\n" - "ICMPv6 Echo Request:\n" - " identifier : 40830\n" - " sequence nr. : 9\n" - "Payload data (56 bytes)\n" ); + std::string dump ( + "Internet protocol Version 6:\n" + " version : 6\n" + " traffic class : 0x00\n" + " flow label : 0x00000\n" + " payload length : 64\n" + " next header : 58\n" + " hop limit : 64\n" + " source : ::1\n" + " destination : ::1\n" + "ICMPv6 protocol:\n" + " type : 128\n" + " code : 0\n" + " checksum : 0xdae0\n" + "ICMPv6 Echo Request:\n" + " identifier : 40830\n" + " sequence nr. : 9\n" + "Payload data (56 bytes)\n" + ); + + { + std::stringstream ss; + ip.dump(ss); + BOOST_CHECK_EQUAL( ss.str(), dump ); + } + SENF_CHECK_EQUAL_COLLECTIONS( ip.data().begin(), ip.data().end(), ping, ping+sizeof(ping) ); + + senf::IPv6Packet orig (senf::IPv6Packet::create(ping)); + + { + std::stringstream ss; + orig.dump(ss); + BOOST_CHECK_EQUAL( ss.str(), dump ); + } } // Local Variables: