X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FDefaultBundle%2FUDPPacket.cc;h=a985f24b4ec47ba9a9b3370d1eafcbdbf9f7bfaf;hb=e375d44dd7db1d9c27c3d788dc3ccdbfa9d68ce8;hp=ce7da558c3086e6f96ba65427e2fb6c948868926;hpb=145f6a7d0f3a6aaa77b3625351c952d24cb0b8a1;p=senf.git diff --git a/Packets/DefaultBundle/UDPPacket.cc b/Packets/DefaultBundle/UDPPacket.cc index ce7da55..a985f24 100644 --- a/Packets/DefaultBundle/UDPPacket.cc +++ b/Packets/DefaultBundle/UDPPacket.cc @@ -1,9 +1,9 @@ // $Id$ // // Copyright (C) 2006 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) -// Stefan Bund +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -20,14 +20,19 @@ // Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// Definition of non-inline non-template functions +/** \file + \brief UDPPacket non-inline non-template implementation */ #include "UDPPacket.hh" //#include "UDPPacket.ih" -#include "IpV4Packet.hh" // Custom includes -#include "Packets/DataPacket.hh" +#include +#include +#include "../../Packets/Packets.hh" +#include "../../Utils/IpChecksum.hh" +#include "IPv4Packet.hh" +#include "IPv6Packet.hh" #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// @@ -37,23 +42,75 @@ namespace { registerUDPPacket (17); } -prefix_ void senf::UDPPacket::v_nextInterpreter() +/////////////////////////////////////////////////////////////////////////// +// senf::UDPPacketParser + +prefix_ boost::uint16_t senf::UDPPacketParser::calcChecksum() const { - registerInterpreter(begin()+bytes(),end()); + IpChecksum summer; + // first on to the awkward part: the IP pseudo header + IPv4Packet ipv4 (packet().rfind(nothrow)); + if (ipv4) { + // Pseudo header defined in RFC768 + summer.feed( ipv4->source().i(), + ipv4->source().i() + IPv4Packet::Parser::source_t::fixed_bytes ); + ///\fixme What about a hop-by-hop routing option? Which destination is used in IPv4 ? + summer.feed( ipv4->destination().i(), + ipv4->destination().i() + IPv4PacketParser::destination_t::fixed_bytes ); + summer.feed( 0u ); + ///\fixme May there be another header between the IPv4 header and UDP? if so, we + /// need to hack the correct protocol number here ... + summer.feed( 17u ); + summer.feed( i() + length_offset, i() + length_offset + 2 ); + } + else { + // Pseudo header defined in RFC2460 + IPv6Packet ipv6 (packet().rfind(nothrow)); + if (ipv6) { + summer.feed( ipv6->source().i(), + ipv6->source().i() + IPv6Packet::Parser::source_t::fixed_bytes ); + ///\todo Implement routing header support + // The destination used here must be the *final* destination ... + summer.feed( ipv6->destination().i(), + ipv6->destination().i() + IPv6PacketParser::destination_t::fixed_bytes ); + // 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() + length_offset, i() + length_offset + 2 ); + // RFC2460 specifies, that this must always be 17, not the value used in the ipv6 + // header + summer.feed( 0u ); + summer.feed( 17u ); + } + } + + // 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. + summer.feed( i(), i()+checksum_offset ); + summer.feed( i()+checksum_offset+2, data().end() ); + + boost::uint16_t rv (summer.sum()); + return rv ? rv : 0xffffu; } -prefix_ void senf::UDPPacket::v_finalize() -{} +/////////////////////////////////////////////////////////////////////////// +// senf::UDPPacketType -prefix_ void senf::UDPPacket::v_dump(std::ostream & os) - const +prefix_ void senf::UDPPacketType::dump(packet p, std::ostream & os) { + boost::io::ios_all_saver ias(os); os << "UDP:\n" - << " source port : " << source() << "\n" - << " dest port : " << destination() << "\n" - << " length : " << length() << "\n" - << " crc : " << std::hex << crc() << std::dec << "\n"; + << " source port : " << p->source() << "\n" + << " dest port : " << p->destination() << "\n" + << " length : " << p->length() << "\n" + << " checksum : " + << std::hex << std::setw(4) << std::setfill('0') << p->checksum() << "\n"; +} + +prefix_ void senf::UDPPacketType::finalize(packet p) +{ + p->length() << p.size(); + p->checksum() << p->calcChecksum(); } ///////////////////////////////cc.e////////////////////////////////////////