From: tho Date: Wed, 14 Nov 2007 21:18:46 +0000 (+0000) Subject: first prototype for the new Ethernet LLC/SNAP Packet X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=6a3a31fb7b2d2a5e8ae6d67d50797700274fb34e;p=senf.git first prototype for the new Ethernet LLC/SNAP Packet todo: add tests & documentation git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@518 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Packets/DefaultBundle/EthernetPacket.cc b/Packets/DefaultBundle/EthernetPacket.cc index 907d4bf..eced314 100644 --- a/Packets/DefaultBundle/EthernetPacket.cc +++ b/Packets/DefaultBundle/EthernetPacket.cc @@ -44,22 +44,41 @@ namespace { prefix_ void senf::EthernetPacketType::dump(packet p, std::ostream & os) { boost::io::ios_all_saver ias(os); - if (p->type() <= 1500) + if (p->type_length() <= 1500) os << "Ethernet 802.3"; - else if (p->type() >= 0x600) + else if (p->type_length() >= 0x600) os << "Ethernet II (DIX)"; else os << "Ethernet 802.3 (bad ethertype >1500 and <1536)"; os << ": \n" - << " destination : " << p->destination() << "\n" - << " source : " << p->source() << "\n" - << " ethertype : 0x" - << std::hex << std::setw(4) << std::setfill('0') << p->type() << "\n"; + << " destination : " << p->destination() << "\n" + << " source : " << p->source() << "\n" + << " type/length : 0x" + << std::hex << std::setw(4) << std::setfill('0') << p->type_length() << "\n"; +} + +prefix_ senf::PacketInterpreterBase::factory_t senf::EthernetPacketType::nextPacketType(packet p) +{ + if (p->type_length() >= 1536) { + PkReg_Entry const * e; + e = PacketRegistry::lookup( p->type_length(), nothrow ); + return e ? e->factory() : no_factory(); + } + if (p->type_length() <= 1500) + return EthLlcSnapPacket::factory(); + return no_factory(); } prefix_ void senf::EthernetPacketType::finalize(packet p) { - p->type() << key(p.next()); + optional_registry_key_t k = key(p.next()); + if (k) + p->type_length() << k; + else + if (p.next().is()) + p->type_length() << p.next().data().size(); + else + p->type_length() << 0; } prefix_ void senf::EthVLanPacketType::dump(packet p, std::ostream & os) @@ -78,6 +97,25 @@ prefix_ void senf::EthVLanPacketType::finalize(packet p) p->type() << key(p.next()); } +prefix_ void senf::EthLlcSnapPacketType::dump(packet p, std::ostream & os) +{ + boost::io::ios_all_saver ias(os); + os << "Ethernet LLC/SNAP" + << " LLC\n" + << " DSAP: " << p->dsap() << "\n" + << " SSAP: " << p->ssap() << "\n" + << " SNAP\n" + << " ProtocolId: " << p->protocolId() << "\n" + << " type : 0x" + << std::hex << std::setw(4) << std::setfill('0') << p->type() << "\n"; +} + +prefix_ void senf::EthLlcSnapPacketType::finalize(packet p) +{ + p->type() << key(p.next()); +} + + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ diff --git a/Packets/DefaultBundle/EthernetPacket.hh b/Packets/DefaultBundle/EthernetPacket.hh index 98d09ab..3dcddc6 100644 --- a/Packets/DefaultBundle/EthernetPacket.hh +++ b/Packets/DefaultBundle/EthernetPacket.hh @@ -72,7 +72,7 @@ namespace senf { SENF_PARSER_FIELD( destination, Parse_MAC ); SENF_PARSER_FIELD( source, Parse_MAC ); - SENF_PARSER_FIELD( type, Parse_UInt16 ); + SENF_PARSER_FIELD( type_length, Parse_UInt16 ); SENF_PARSER_FINALIZE(Parse_Ethernet); }; @@ -115,15 +115,11 @@ namespace senf { typedef Parse_Ethernet parser; #endif using mixin::nextPacketRange; - using mixin::nextPacketType; + // using mixin::nextPacketType; using mixin::initSize; using mixin::init; - /** \todo Add LLC/SNAP support -> only use the registry - for type() values >=1536, otherwise expect an LLC header */ - static registry_key_t nextPacketKey(packet p) - { return p->type(); } - + static factory_t nextPacketType(packet p); static void dump(packet p, std::ostream & os); static void finalize(packet p); }; @@ -191,6 +187,69 @@ namespace senf { /** \brief Ethernet VLAN tag typedef */ typedef ConcretePacket EthVLanPacket; + + + /** \brief Parse an ethernet LLC/SNAP header + + \todo document me + + \see EthVLanPacketType + */ + struct Parse_EthLlcSnapPacket : public PacketParserBase + { +# include SENF_FIXED_PARSER() + + SENF_PARSER_FIELD( dsap, Parse_UInt8 ); + SENF_PARSER_FIELD( ssap, Parse_UInt8 ); + SENF_PARSER_FIELD( ctrl, Parse_UInt8 ); + + SENF_PARSER_FIELD( protocolId, Parse_UInt24 ); + SENF_PARSER_FIELD( type, Parse_UInt24 ); + + SENF_PARSER_FINALIZE(Parse_EthLlcSnapPacket); + }; + + /** \brief Ethernet LLC/SNAP header + + \todo document me + + \par Packet type (typedef): + \ref EthLlcSnapPacketType + + \par Fields: + \ref Parse_EthLlcSnapPacket + + \par Associated registries: + \ref EtherTypes + + \par Finalize action: + XXXX + + \ingroup protocolbundle_default + */ + struct EthLlcSnapPacketType + : public PacketTypeBase, + public PacketTypeMixin + { +#ifndef DOXYGEN + typedef PacketTypeMixin mixin; + typedef ConcretePacket packet; + typedef Parse_EthLlcSnapPacket parser; +#endif + using mixin::nextPacketRange; + using mixin::nextPacketType; + using mixin::initSize; + using mixin::init; + + static registry_key_t nextPacketKey(packet p) + { return p->type(); } + + static void dump(packet p, std::ostream & os); + static void finalize(packet p); + }; + + /** \brief Ethernet VLAN tag typedef */ + typedef ConcretePacket EthLlcSnapPacket; } diff --git a/Packets/DefaultBundle/EthernetPacket.test.cc b/Packets/DefaultBundle/EthernetPacket.test.cc index 06e2acb..78d0ae9 100644 --- a/Packets/DefaultBundle/EthernetPacket.test.cc +++ b/Packets/DefaultBundle/EthernetPacket.test.cc @@ -45,7 +45,7 @@ BOOST_AUTO_UNIT_TEST(ethernetPacket_packet) BOOST_CHECK_EQUAL( p->destination()[3], 0x04 ); BOOST_CHECK_EQUAL( p->source()[0], 0x07 ); - BOOST_CHECK_EQUAL( p->type(), 0x1011 ); + BOOST_CHECK_EQUAL( p->type_length(), 0x1011 ); } BOOST_AUTO_UNIT_TEST(ethernetPacket_chain) @@ -81,7 +81,7 @@ BOOST_AUTO_UNIT_TEST(ethernetPacket_create) vlan->vlanId() = 0x234u; eth.finalize(); - BOOST_CHECK_EQUAL(eth->type(), 0x8100u); + BOOST_CHECK_EQUAL(eth->type_length(), 0x8100u); BOOST_CHECK_EQUAL(vlan->type(), 0u); senf::IpV4Packet ip (senf::IpV4Packet::createAfter(vlan));