ostinato/common/protocolmanager.cpp
Srivats P. 17792b8253 Refactoring, optimization et. al.
---------------------------------
	- StreamConfigDialog: Valid subsequent protocol choices for a particular protocol in the simple protocol selection widget is no longer hardcoded - ProtocolManager is queried for validitity of each pair of possible protocols; signal-slot connections are made accordingly. This refactoring makes it easier to add a protocol to the simple protocol selection widget
	- ProtocolManager: populates and maintains a database of valid 'neighbour protocols' and implements a method - isValidNeighbour() to query the same for a pair of protocols
	- AbstractProtocol: new method protocolIdType() introduced to build the above database (in conjunction with the existing method protocolId(ProtocolIdType)); default implementation returns ProtocolIdNone
	- Protocols which include a valid/supported ProtocolIdType (eth/llc/ip) reimplement protocolIdType() to return the apporpirate ProtocolIdType. These are viz.
		- combo
		- eth
		- llc
		- snap
		- ip
	- Speed optimization while populating streamqueues if the protocolFrameValue/Size() does not vary across packets
	- AbstractProtocol: new methods to support the above optimization
		- isProtocolFrameValueVariable()
		- isProtocolFrameSizeVariable()
		- isProtocolFramePayloadValueVariable()
		- isProtocolFramePayloadSizeVariable()
		(each of the default implementations returns false indicating that the protocol frame value or frame size is fixed and not variable)
	- Protocols which support variable values/size (list follows) reimplement the above methods appropriately
		- combo
		- mac
		- dot3
		- ip4
		- tcp
		- udp
		- payload
	- StreamInfo::makePacket() moved to base class as StreamBase::frameValue()
	- StreamBase: all 'get' accessor functions made 'const'
	- class ProtocolManager: while registering a protocol, no need to pass the protocol name; ProtocolManager finds it out internally by using the protocol's shortName() method



Fixes
-----
	- Fixed issue with port capture not starting the first time 'start capture' was clicked
2009-11-13 16:00:57 +00:00

126 lines
3.6 KiB
C++

#include "protocolmanager.h"
#include "abstractprotocol.h"
#include "protocol.pb.h"
#include "mac.h"
#include "payload.h"
#include "eth2.h"
#include "dot3.h"
#include "llc.h"
#include "snap.h"
#include "dot2llc.h"
#include "dot2snap.h"
#include "vlan.h"
#include "vlanstack.h"
#include "ip4.h"
#include "tcp.h"
#include "udp.h"
ProtocolManager OstProtocolManager;
ProtocolManager::ProtocolManager()
{
/*! \todo (LOW) calls to registerProtocol() should be done by the protocols
themselves (once this is done remove the #includes for all the protocols)
*/
registerProtocol(OstProto::Protocol::kMacFieldNumber,
(void*) MacProtocol::createInstance);
registerProtocol(OstProto::Protocol::kPayloadFieldNumber,
(void*) PayloadProtocol::createInstance);
registerProtocol(OstProto::Protocol::kEth2FieldNumber,
(void*) Eth2Protocol::createInstance);
registerProtocol(OstProto::Protocol::kDot3FieldNumber,
(void*) Dot3Protocol::createInstance);
registerProtocol(OstProto::Protocol::kLlcFieldNumber,
(void*) LlcProtocol::createInstance);
registerProtocol(OstProto::Protocol::kSnapFieldNumber,
(void*) SnapProtocol::createInstance);
registerProtocol(OstProto::Protocol::kDot2LlcFieldNumber,
(void*) Dot2LlcProtocol::createInstance);
registerProtocol(OstProto::Protocol::kDot2SnapFieldNumber,
(void*) Dot2SnapProtocol::createInstance);
registerProtocol(OstProto::Protocol::kSvlanFieldNumber,
(void*) SVlanProtocol::createInstance);
registerProtocol(OstProto::Protocol::kVlanFieldNumber,
(void*) VlanProtocol::createInstance);
registerProtocol(OstProto::Protocol::kVlanStackFieldNumber,
(void*) VlanStackProtocol::createInstance);
registerProtocol(OstProto::Protocol::kIp4FieldNumber,
(void*) Ip4Protocol::createInstance);
registerProtocol(OstProto::Protocol::kTcpFieldNumber,
(void*) TcpProtocol::createInstance);
registerProtocol(OstProto::Protocol::kUdpFieldNumber,
(void*) UdpProtocol::createInstance);
populateNeighbourProtocols();
}
void ProtocolManager::registerProtocol(int protoNumber,
void *protoInstanceCreator)
{
AbstractProtocol *p;
//! \todo (MED) validate incoming params for duplicates with existing
factory.insert(protoNumber, protoInstanceCreator);
p = createProtocol(protoNumber, NULL);
protocolList.append(p);
numberToNameMap.insert(protoNumber, p->shortName());
nameToNumberMap.insert(p->shortName(), protoNumber);
}
void ProtocolManager::populateNeighbourProtocols()
{
neighbourProtocols.clear();
foreach(AbstractProtocol *p, protocolList)
{
if (p->protocolIdType() != AbstractProtocol::ProtocolIdNone)
{
foreach(AbstractProtocol *q, protocolList)
{
if (q->protocolId(p->protocolIdType()))
neighbourProtocols.insert(
p->protocolNumber(), q->protocolNumber());
}
}
}
}
AbstractProtocol* ProtocolManager::createProtocol(int protoNumber,
StreamBase *stream, AbstractProtocol *parent)
{
AbstractProtocol* (*pc)(StreamBase*, AbstractProtocol*);
AbstractProtocol* p;
pc = (AbstractProtocol* (*)(StreamBase*, AbstractProtocol*))
factory.value(protoNumber);
Q_ASSERT(pc != NULL);
p = (*pc)(stream, parent);
return p;
}
AbstractProtocol* ProtocolManager::createProtocol(QString protoName,
StreamBase *stream, AbstractProtocol *parent)
{
return createProtocol(nameToNumberMap.value(protoName), stream, parent);
}
bool ProtocolManager::isValidNeighbour(int protoPrefix, int protoSuffix)
{
if (neighbourProtocols.contains(protoPrefix, protoSuffix))
return true;
else
return false;
}
QStringList ProtocolManager::protocolDatabase()
{
return numberToNameMap.values();
}