diff --git a/Packets/EthernetPacket.hh b/Packets/EthernetPacket.hh index 53d1dca962a91ba0dfa65838346c54dadf226cd6..56b1f49607bf8907d23a2506c8cb328b4c93e0f9 100644 --- a/Packets/EthernetPacket.hh +++ b/Packets/EthernetPacket.hh @@ -58,6 +58,7 @@ namespace senf { }; struct EtherTypes { + // See http://www.iana.org/assignments/ethernet-numbers typedef boost::uint16_t key_t; }; diff --git a/Packets/IpV4Packet.cti b/Packets/IpV4Packet.cti index 423be2f485286a8825972fa48c88b4f02529c9f9..a7a5cf8d7e2cc4894a335922c2974b77a72c395d 100644 --- a/Packets/IpV4Packet.cti +++ b/Packets/IpV4Packet.cti @@ -34,8 +34,6 @@ prefix_ senf::IpV4Packet::IpV4Packet(Arg const & arg) : Packet(arg) {} - - ///////////////////////////////cti.e/////////////////////////////////////// #undef prefix_ diff --git a/Packets/IpV4Packet.hh b/Packets/IpV4Packet.hh index 0d126282c92289dec841422c845209ce1a4eaa9b..b801426d726022ff8593839e234a18e24ba17d76 100644 --- a/Packets/IpV4Packet.hh +++ b/Packets/IpV4Packet.hh @@ -75,16 +75,18 @@ namespace senf { Parse_32bit destination() const { return Parse_32bit (this->i() + 16 ); } }; - struct IpV4Types { + struct IpTypes { + // See http://www.iana.org/assignments/protocol-numbers + // Also used by IPv6 typedef boost::uint16_t key_t; }; class IpV4Packet : public Packet, public Parse_IpV4<Packet::iterator,IpV4Packet>, - public PacketRegistryMixin<IpV4Types,IpV4Packet> + public PacketRegistryMixin<IpTypes,IpV4Packet> { - using PacketRegistryMixin<IpV4Types,IpV4Packet>::registerInterpreter; + using PacketRegistryMixin<IpTypes,IpV4Packet>::registerInterpreter; public: /////////////////////////////////////////////////////////////////////////// // Types diff --git a/Packets/IpV6Packet.cc b/Packets/IpV6Packet.cc new file mode 100644 index 0000000000000000000000000000000000000000..b511d02aff0c1db04cb211ff7f5ef7c2899bc13f --- /dev/null +++ b/Packets/IpV6Packet.cc @@ -0,0 +1,73 @@ +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <g0dil@berlios.de> +// +// 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 +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief IpV6Packet non-inline non-template implementation */ + +#include "IpV6Packet.hh" +//#include "IpV6Packet.ih" + +// Custom includes +#include "EthernetPacket.hh" +#include "Socket/INetAddressing.hh" + +//#include "IpV6Packet.mpp" +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +namespace { + senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::IpV6Packet> + registerIpV6Packet(0x86dd); +} + +prefix_ void senf::IpV6Packet::v_nextInterpreter() + const +{ + registerInterpreter(nextHeader(),begin()+bytes(),end()); +} + +prefix_ void senf::IpV6Packet::v_finalize() +{} + +prefix_ void senf::IpV6Packet::v_dump(std::ostream & os) + const +{ + os << "Internet protocol Version 6:\n" + << " version : " << unsigned(version()) << "\n" + << " traffic class : " << std::hex << unsigned(trafficClass()) << "\n" + << " flow label : " << std::hex << unsigned(flowLabel()) << "\n" + << " length : " << std::dec << unsigned(length()) << "\n" + << " next header : " << unsigned(nextHeader()) << "\n" + << " hop limit : " << unsigned(hopLimit()) << "\n" + << " source : " << INet6Address(source().range()) << "\n" + << " destination : " << INet6Address(destination().range()) << "\n"; +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ +//#include "IpV6Packet.mpp" + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// c-file-style: "senf" +// ispell-local-dictionary: "american" +// End: diff --git a/Packets/IpV6Packet.cti b/Packets/IpV6Packet.cti new file mode 100644 index 0000000000000000000000000000000000000000..a78167b0126ab9dfb6b9afa84ea8fad554147e1b --- /dev/null +++ b/Packets/IpV6Packet.cti @@ -0,0 +1,45 @@ +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <g0dil@berlios.de> +// +// 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 +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief IpV6Packet inline template implementation */ + +//#include "IpV6Packet.ih" + +// Custom includes + +#define prefix_ inline +///////////////////////////////cti.p/////////////////////////////////////// + +template <class Arg> +prefix_ senf::IpV6Packet::IpV6Packet(Arg const & arg) + : Packet(arg) +{} + +///////////////////////////////cti.e/////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// c-file-style: "senf" +// ispell-local-dictionary: "american" +// End: diff --git a/Packets/IpV6Packet.hh b/Packets/IpV6Packet.hh new file mode 100644 index 0000000000000000000000000000000000000000..99d247678bda0250272e7defd70131344a0a28b0 --- /dev/null +++ b/Packets/IpV6Packet.hh @@ -0,0 +1,110 @@ +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <g0dil@berlios.de> +// +// 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 +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief IpV6Packet public header */ + +#ifndef HH_IpV6Packet_ +#define HH_IpV6Packet_ 1 + +// Custom includes +#include "Packet.hh" +#include "ParseInt.hh" +#include "ParseArray.hh" +#include "PacketRegistry.hh" +#include "IpV4Packet.hh" + +//#include "IpV6Packet.mpp" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace senf { + + template <class Iterator=nil, class IpV6Packet=nil> + struct Parse_IpV6 : public ParserBase<Iterator,IpV6Packet> + { + template <class I, class P=nil> + struct rebind { typedef Parse_IpV6<I,P> parser; }; + typedef Iterator byte_iterator; + + Parse_IpV6() {} + Parse_IpV6(Iterator const & i) : ParserBase<Iterator,IpV6Packet>(i) {} + + static unsigned bytes() { return 40; } + + /////////////////////////////////////////////////////////////////////////// + + typedef Parse_UIntField < 0, 4, Iterator > Parse_Version; + typedef Parse_UIntField < 4, 12, Iterator > Parse_Class; + typedef Parse_UIntField < 12, 32, Iterator > Parse_FlowLabel; + typedef Parse_UInt8 < Iterator > Parse_8bit; + typedef Parse_UInt16 < Iterator > Parse_16bit; + + typedef Parse_Array < 16, Parse_8bit, Iterator > Parse_Addr; + + Parse_Version version() const { return Parse_Version (this->i() ); } + Parse_Class trafficClass() const { return Parse_Class (this->i() ); } + Parse_FlowLabel flowLabel() const { return Parse_FlowLabel (this->i() ); } + Parse_16bit length() const { return Parse_16bit (this->i() + 4 ); } + Parse_8bit nextHeader() const { return Parse_8bit (this->i() + 6 ); } + Parse_8bit hopLimit() const { return Parse_8bit (this->i() + 7 ); } + Parse_Addr source() const { return Parse_Addr (this->i() + 8 ); } + Parse_Addr destination() const { return Parse_Addr (this->i() + 24 ); } + }; + + class IpV6Packet + : public Packet, + public Parse_IpV6<Packet::iterator, IpV6Packet>, + public PacketRegistryMixin<IpTypes, IpV6Packet> + { + using PacketRegistryMixin<IpTypes,IpV6Packet>::registerInterpreter; + public: + /////////////////////////////////////////////////////////////////////////// + // Types + + typedef ptr_t<IpV6Packet>::ptr ptr; + + /////////////////////////////////////////////////////////////////////////// + + private: + template <class Arg> + IpV6Packet(Arg const & arg); + + virtual void v_nextInterpreter() const; + virtual void v_finalize(); + virtual void v_dump(std::ostream & os) const; + + friend class Packet; + }; + +} + +///////////////////////////////hh.e//////////////////////////////////////// +//#include "IpV6Packet.cci" +//#include "IpV6Packet.ct" +#include "IpV6Packet.cti" +#endif + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// c-file-style: "senf" +// ispell-local-dictionary: "american" +// End: diff --git a/Packets/IpV6Packet.test.cc b/Packets/IpV6Packet.test.cc new file mode 100644 index 0000000000000000000000000000000000000000..70008a46e30b0410e67454f50b53f27b1ef64805 --- /dev/null +++ b/Packets/IpV6Packet.test.cc @@ -0,0 +1,72 @@ +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <g0dil@berlios.de> +// +// 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 +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief IpV6Packet unit tests */ + +//#include "IpV6Packet.test.hh" +//#include "IpV6Packet.test.ih" + +// Custom includes +#include "IpV6Packet.hh" +#include "Socket/INetAddressing.hh" + +#include <boost/test/auto_unit_test.hpp> +#include <boost/test/test_tools.hpp> + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +using namespace senf; + +BOOST_AUTO_UNIT_TEST(ipV6Packet_parser) +{ + unsigned char data[] = { 0x60, 0x12, 0x20, 0x30, + 0x01, 0x02, 0x03, 0x04, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f }; + + typedef unsigned char * iterator; + Parse_IpV6<iterator> p(data); + + BOOST_CHECK_EQUAL( unsigned(p.version()), 0x06u ); + BOOST_CHECK_EQUAL( unsigned(p.trafficClass()), 0x01u ); + BOOST_CHECK_EQUAL( unsigned(p.flowLabel()), 0x22030u ); + BOOST_CHECK_EQUAL( unsigned(p.length()), 0x0102u ); + BOOST_CHECK_EQUAL( unsigned(p.nextHeader()), 0x03u ); + BOOST_CHECK_EQUAL( unsigned(p.hopLimit()), 0x04u ); + BOOST_CHECK_EQUAL( INet6Address(p.source().range()).address() , + "1011:1213:1415:1617:1819:1a1b:1c1d:1e1f" ); + BOOST_CHECK_EQUAL( INet6Address(p.destination().range()).address() , + "2021:2223:2425:2627:2829:2a2b:2c2d:2e2f" ); +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// c-file-style: "senf" +// ispell-local-dictionary: "american" +// End: diff --git a/Packets/SConscript b/Packets/SConscript index 9db975b9269bfb6d725788133db7beec34f8f1fb..b39aa6539a75d2274e07c1940818ca506f2f608f 100644 --- a/Packets/SConscript +++ b/Packets/SConscript @@ -6,8 +6,14 @@ import SENFSCons ########################################################################### sources = SENFSCons.GlobSources() + SENFSCons.StandardTargets(env) -SENFSCons.Lib(env, 'Packets', sources, ) + +SENFSCons.Lib(env, + library = 'Packets', + sources = sources, + LIBS = [ 'Socket', 'Utils' ]) + SENFSCons.Doxygen(env, extra_sources = [ env.Dia2Png("structure.dia") - ]) +]) diff --git a/Packets/UDPPacket.cc b/Packets/UDPPacket.cc index e4a48b6f21a710a44d17f96fba71f316e5d3587b..c9c2a22d7071f8cd0280a9520d84b521193bd98d 100644 --- a/Packets/UDPPacket.cc +++ b/Packets/UDPPacket.cc @@ -31,8 +31,9 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// + namespace { - senf::PacketRegistry<senf::IpV4Types>::RegistrationProxy<senf::UDPPacket> + senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::UDPPacket> registerUDPPacket(17); } diff --git a/Packets/UDPPacket.hh b/Packets/UDPPacket.hh index 54cea7fb2e1d7e97633139496481cdb37aeb5c8b..e94f9c4ab8824505b978ee75af78e718b7a55c0e 100644 --- a/Packets/UDPPacket.hh +++ b/Packets/UDPPacket.hh @@ -33,7 +33,6 @@ ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { - template <class Iterator=nil, class IPacket=nil> struct Parse_UDP : public ParserBase<Iterator,IPacket> diff --git a/Socket/INetAddressing.ct b/Socket/INetAddressing.ct new file mode 100644 index 0000000000000000000000000000000000000000..8e682b0904b6652ca33168d9c11fb6e2e6b9ad60 --- /dev/null +++ b/Socket/INetAddressing.ct @@ -0,0 +1,54 @@ +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund <g0dil@berlios.de> +// +// 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 +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief INetAddressing non-inline template implementation */ + +//#include "INetAddressing.ih" + +// Custom includes +#include <boost/range.hpp> + +#define prefix_ +///////////////////////////////ct.p//////////////////////////////////////// + +template <class Range> +prefix_ senf::INet6Address::INet6Address(Range const & range) +{ + typename boost::range_const_iterator<Range>::type i ( boost::const_begin(range) ); + typename boost::range_const_iterator<Range>::type const i_end ( boost::const_end(range) ); + unsigned char * p (&addr_.s6_addr[0]); + unsigned char * p_end (p+sizeof(addr_.s6_addr)); + for (; p!=p_end && i!=i_end; ++p, ++i) + *p = *i; + if (p!=p_end || i!=i_end) + throw InvalidINetAddressException(); +} + +///////////////////////////////ct.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// c-file-style: "senf" +// ispell-local-dictionary: "american" +// End: diff --git a/Socket/INetAddressing.hh b/Socket/INetAddressing.hh index 4a8deca6221ffdc9f888ec3d83d269253fd6dfc6..923389294ecec2d2b9489d5b7f06463001fa04d3 100644 --- a/Socket/INetAddressing.hh +++ b/Socket/INetAddressing.hh @@ -128,10 +128,20 @@ namespace senf { ///\name Structors and default members ///@{ - INet6Address(); - INet6Address(std::string const & addr); - INet6Address(char const * addr); - INet6Address(struct in6_addr const & addr); + INet6Address(); ///< Create empty address + INet6Address(std::string const & addr); ///< Create address from string representation + INet6Address(char const * addr); ///< Create address from string representation + INet6Address(struct in6_addr const & addr); ///< Create address from in6_addr + template <class Range> + explicit INet6Address(Range const & range); ///< Create address from arbitrary raw data + /**< This constructor will copy 16 bytes from the given + range and interpret them as a IPv6 address in network + byte order. This constructor is used to read an + arbitrary address from it's binary representation. + + \param range arbitrary range, see <a + href="http://www.boost.org/libs/range/index.html">Boost.Range</a> + */ ///@} /////////////////////////////////////////////////////////////////////////// @@ -326,7 +336,7 @@ namespace senf { ///////////////////////////////hh.e//////////////////////////////////////// #include "INetAddressing.cci" -//#include "INetAddressing.ct" +#include "INetAddressing.ct" //#include "INetAddressing.cti" //#include "INetAddressing.mpp" #endif diff --git a/Socket/INetAddressing.test.cc b/Socket/INetAddressing.test.cc index b19990a2fab5af779c879279a20ba990bfebb279..f649914a8923bed8ccac349007a5748b453887c7 100644 --- a/Socket/INetAddressing.test.cc +++ b/Socket/INetAddressing.test.cc @@ -111,6 +111,13 @@ BOOST_AUTO_UNIT_TEST(inet6Address) BOOST_CHECK_EQUAL( addr1, addr2 ); BOOST_CHECK_THROW( addr1 = "", InvalidINetAddressException ); BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(addr1), "::" ); + unsigned char data[] = { 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x21, 0 }; + INet6Address addr3 (std::make_pair(&data[0],&data[0]+sizeof(data)-1)); + BOOST_CHECK_EQUAL( addr3, "1200::21" ); + BOOST_CHECK_THROW( INet6Address(std::make_pair(&data[0],&data[0]+sizeof(data))), + InvalidINetAddressException ); + BOOST_CHECK_THROW( INet6Address(std::make_pair(&data[0],&data[0]+sizeof(data)-2)), + InvalidINetAddressException ); } {