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<senf::EtherTypes>::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<EthLlcSnapPacket>())
+ p->type_length() << p.next().data().size();
+ else
+ p->type_length() << 0;
}
prefix_ void senf::EthVLanPacketType::dump(packet p, std::ostream & os)
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_
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);
};
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);
};
/** \brief Ethernet VLAN tag typedef */
typedef ConcretePacket<EthVLanPacketType> 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<EthLlcSnapPacketType, EtherTypes>
+ {
+#ifndef DOXYGEN
+ typedef PacketTypeMixin<EthLlcSnapPacketType, EtherTypes> mixin;
+ typedef ConcretePacket<EthLlcSnapPacketType> 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<EthLlcSnapPacketType> EthLlcSnapPacket;
}
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)
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));