Protocol Framework related

--------------------------
	- AbstractProtocol Constructor and Factory function now take an optional (default NULL) "parent" abstract protocol in addition to the stream; this "parent" protocol is non-NULL for protocols which are aggregated in a ComboProtocol
	- All subclasses of AbstractProtocol modified as per the above interface change
	- ProtocolManager also modifed as per the above interface change
	- new data members in AbstractProtocol - prev, next; the AbstractProtocol implementation now uses these members to traverse protocols on the list instead of ProtocolListIterator; this change required for ComboProtocol
	- ProtocolListIterator updates these new members - prev/next on insert/remove/replace
	- ComboProtocol and ProtocolListIterator classes made friends of AbstractProtocol
	- ComboProtocol implemented as a template class (completed)
	- Dot2LLc implemented as a combo of Dot3Raw and LLC
	- Dot2Snap implemented as a combo of Dot2Llc and SNAP
	- VlanStack implemented as a combo of VLAN + VLAN
	- ProtocolManager now uses the ProtocolId enums rather than hardcoded values

Stream Config Dialog
--------------------
	- "None" radio button added to all protocol levels
	- Protocol Level 1 added with 'mac' as the only valid protocol in the "simple" mode widget
	- With Dot2Llc, Dot2Snap and VlanStack implemented as "combo" protocols, the protocol choice radiobuttons in the "simple" mode are now 1:1 with a protocol; this has the following implications/advantages:
		- Updates of the "simple" mode widget from/to stream's protocolList is simpler; this code has now been rewritten to take advantage of 1:1
		- This paves the way for exporting tunneled protocols 4over4, 4over6, 6over4 etc. in the "simple" mode
		- This should also (hopefully) require less changes when adding a new protocol; more work needs to be done to reach this goal

Fixes
-----
	- Dot3Protocol now derives "length" correctly for VLAN tagged packets
	- StreamBase now uses the ProtocolListIterator to append the default protocols in a stream instead of directly manipulating ProtocolList; also in protoDataCopyFrom()

Others (Client/Server)
----------------------
	- Port Packet Capture implemented; "view capture" is pending (hack put in place now for testing)
This commit is contained in:
Srivats P. 2009-10-14 15:16:56 +00:00
parent a937112e63
commit 0094f618d3
47 changed files with 1029 additions and 786 deletions

View File

@ -46,7 +46,7 @@ int PacketModel::rowCount(const QModelIndex &parent) const
qWarning("%s: Unhandled ItemType", __FUNCTION__); qWarning("%s: Unhandled ItemType", __FUNCTION__);
} }
Q_ASSERT(1 == 1); // Unreachable code Q_ASSERT(1 == 0); // Unreachable code
qWarning("%s: Catch all - need to investigate", __FUNCTION__); qWarning("%s: Catch all - need to investigate", __FUNCTION__);
return 0; // catch all return 0; // catch all
} }
@ -86,13 +86,14 @@ QModelIndex PacketModel::index(int row, int col, const QModelIndex &parent) cons
goto _exit; goto _exit;
case ITYP_FIELD: case ITYP_FIELD:
Q_ASSERT(1 == 0); // Unreachable code
goto _exit; goto _exit;
default: default:
qWarning("%s: Unhandled ItemType", __FUNCTION__); qWarning("%s: Unhandled ItemType", __FUNCTION__);
} }
Q_ASSERT(1 == 1); // Unreachable code Q_ASSERT(1 == 0); // Unreachable code
_exit: _exit:
return index; return index;

View File

@ -479,6 +479,93 @@ _exit:
return; return;
} }
void PortGroup::startCapture(QList<uint> *portList)
{
OstProto::PortIdList portIdList;
OstProto::Ack *ack;
qDebug("In %s", __FUNCTION__);
if (state() != QAbstractSocket::ConnectedState)
return;
ack = new OstProto::Ack;
if (portList == NULL)
goto _exit;
else
{
for (int i = 0; i < portList->size(); i++)
{
OstProto::PortId *portId;
portId = portIdList.add_port_id();
portId->set_id(portList->at(i));
}
}
serviceStub->startCapture(rpcController, &portIdList, ack,
NewCallback(this, &PortGroup::processStartCaptureAck, ack));
_exit:
return;
}
void PortGroup::stopCapture(QList<uint> *portList)
{
OstProto::PortIdList portIdList;
OstProto::Ack *ack;
qDebug("In %s", __FUNCTION__);
if (state() != QAbstractSocket::ConnectedState)
return;
ack = new OstProto::Ack;
if (portList == NULL)
goto _exit;
else
{
for (int i = 0; i < portList->size(); i++)
{
OstProto::PortId *portId;
portId = portIdList.add_port_id();
portId->set_id(portList->at(i));
}
}
serviceStub->stopCapture(rpcController, &portIdList, ack,
NewCallback(this, &PortGroup::processStopCaptureAck, ack));
_exit:
return;
}
void PortGroup::viewCapture(QList<uint> *portList)
{
OstProto::PortIdList portIdList;
OstProto::CaptureBufferList *bufList;
qDebug("In %s", __FUNCTION__);
if (state() != QAbstractSocket::ConnectedState)
return;
bufList = new OstProto::CaptureBufferList;
if (portList == NULL)
goto _exit;
else
{
for (int i = 0; i < portList->size(); i++)
{
OstProto::PortId *portId;
portId = portIdList.add_port_id();
portId->set_id(portList->at(i));
}
}
serviceStub->getCaptureBuffer(rpcController, &portIdList, bufList,
NewCallback(this, &PortGroup::processViewCaptureAck, bufList));
_exit:
return;
}
void PortGroup::processStartTxAck(OstProto::Ack *ack) void PortGroup::processStartTxAck(OstProto::Ack *ack)
{ {
qDebug("In %s", __FUNCTION__); qDebug("In %s", __FUNCTION__);
@ -493,6 +580,27 @@ void PortGroup::processStopTxAck(OstProto::Ack *ack)
delete ack; delete ack;
} }
void PortGroup::processStartCaptureAck(OstProto::Ack *ack)
{
qDebug("In %s", __FUNCTION__);
delete ack;
}
void PortGroup::processStopCaptureAck(OstProto::Ack *ack)
{
qDebug("In %s", __FUNCTION__);
delete ack;
}
void PortGroup::processViewCaptureAck(OstProto::CaptureBufferList *bufList)
{
qDebug("In %s", __FUNCTION__);
delete bufList;
}
void PortGroup::getPortStats() void PortGroup::getPortStats()
{ {
OstProto::PortStatsList *portStatsList; OstProto::PortStatsList *portStatsList;

View File

@ -75,6 +75,13 @@ public:
void stopTx(QList<uint> *portList = NULL); void stopTx(QList<uint> *portList = NULL);
void processStopTxAck(OstProto::Ack *ack); void processStopTxAck(OstProto::Ack *ack);
void startCapture(QList<uint> *portList = NULL);
void processStartCaptureAck(OstProto::Ack *ack);
void stopCapture(QList<uint> *portList = NULL);
void processStopCaptureAck(OstProto::Ack *ack);
void viewCapture(QList<uint> *portList = NULL);
void processViewCaptureAck(OstProto::CaptureBufferList *bufList);
void getPortStats(); void getPortStats();
void processPortStatsList(OstProto::PortStatsList *portStatsList); void processPortStatsList(OstProto::PortStatsList *portStatsList);
void clearPortStats(QList<uint> *portList = NULL); void clearPortStats(QList<uint> *portList = NULL);

View File

@ -61,16 +61,52 @@ void PortStatsWindow::on_tbStopTransmit_clicked()
void PortStatsWindow::on_tbStartCapture_clicked() void PortStatsWindow::on_tbStartCapture_clicked()
{ {
// TODO(MED) // TODO(MED)
QList<PortStatsModel::PortGroupAndPortList> pgpl;
// Get selected ports
model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
pgpl);
// Clear selected ports, portgroup by portgroup
for (int i = 0; i < pgpl.size(); i++)
{
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
startCapture(&pgpl[i].portList);
}
} }
void PortStatsWindow::on_tbStopCapture_clicked() void PortStatsWindow::on_tbStopCapture_clicked()
{ {
// TODO(MED) // TODO(MED)
QList<PortStatsModel::PortGroupAndPortList> pgpl;
// Get selected ports
model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
pgpl);
// Clear selected ports, portgroup by portgroup
for (int i = 0; i < pgpl.size(); i++)
{
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
stopCapture(&pgpl[i].portList);
}
} }
void PortStatsWindow::on_tbViewCapture_clicked() void PortStatsWindow::on_tbViewCapture_clicked()
{ {
// TODO(MED) // TODO(MED)
QList<PortStatsModel::PortGroupAndPortList> pgpl;
// Get selected ports
model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
pgpl);
// Clear selected ports, portgroup by portgroup
for (int i = 0; i < pgpl.size(); i++)
{
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
viewCapture(&pgpl[i].portList);
}
} }
void PortStatsWindow::on_tbClear_clicked() void PortStatsWindow::on_tbClear_clicked()

View File

@ -27,18 +27,13 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
setupUi(this); setupUi(this);
setupUiExtra(); setupUiExtra();
connect(bgL1Proto, SIGNAL(buttonClicked(int)), for (int i = ProtoMin; i < ProtoMax; i++)
this, SLOT(updateL1Protocol(int))); {
connect(bgL2Proto, SIGNAL(buttonClicked(int)), bgProto[i]->setProperty("ProtocolLevel", i);
this, SLOT(updateFrameTypeProtocol(int))); bgProto[i]->setProperty("ProtocolId", ButtonIdNone);
connect(bgVlan, SIGNAL(buttonClicked(int)), connect(bgProto[i], SIGNAL(buttonClicked(int)),
this, SLOT(updateVlanProtocol(int))); this, SLOT(updateProtocol(int)));
connect(bgL3Proto, SIGNAL(buttonClicked(int)), }
this, SLOT(updateL3Protocol(int)));
connect(bgL4Proto, SIGNAL(buttonClicked(int)),
this, SLOT(updateL4Protocol(int)));
connect(bgPayloadProto, SIGNAL(buttonClicked(int)),
this, SLOT(updatePayloadProtocol(int)));
//! \todo causes a crash! //! \todo causes a crash!
#if 0 #if 0
@ -48,35 +43,16 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
// Time to play match the signals and slots! // Time to play match the signals and slots!
// Enable VLAN Choices only if FT = Eth2 or SNAP // If L1/FT = None, force subsequent protocol level(s) also to None
#if 0 connect(rbL1None, SIGNAL(toggled(bool)), this, SLOT(forceProtocolNone(bool)));
connect(rbFtNone, SIGNAL(toggled(bool)), gbVlan, SLOT(setDisabled(bool))); connect(rbFtNone, SIGNAL(toggled(bool)), this, SLOT(forceProtocolNone(bool)));
connect(rbFtOther, SIGNAL(toggled(bool)), gbVlan, SLOT(setDisabled(bool)));
connect(rbFtNone, SIGNAL(clicked(bool)), rbVlanNone, SLOT(click()));
#endif
// Force all protocols = None if L1 = None
connect(rbL1None, SIGNAL(clicked(bool)), rbVlanNone, SLOT(click()));
connect(rbL1None, SIGNAL(clicked(bool)), rbFtNone, SLOT(click()));
connect(rbL1None, SIGNAL(clicked(bool)), rbPayloadNone, SLOT(click()));
connect(rbFtNone, SIGNAL(clicked(bool)), rbL3None, SLOT(click()));
// Enable/Disable L3 Protocol Choices for FT None
connect(rbFtNone, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool)));
connect(rbFtNone, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setDisabled(bool)));
connect(rbFtNone, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool)));
// Enable/Disable L3 Protocol Choices for FT Ethernet2 // Enable/Disable L3 Protocol Choices for FT Ethernet2
connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool)));
connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool)));
connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(bool))); connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(bool)));
// Force L3 = None if FT = 802.3 Raw // Force L3 = None if FT = 802.3 Raw
connect(rbFt802Dot3Raw, SIGNAL(clicked(bool)), rbL3None, SLOT(click())); connect(rbFt802Dot3Raw, SIGNAL(clicked(bool)), rbL3None, SLOT(click()));
// Enable/Disable L3 Protocol Choices for FT 802Dot3Raw
connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool)));
connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setDisabled(bool))); connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setDisabled(bool)));
connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool))); connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool)));
@ -84,12 +60,10 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
connect(rbFt802Dot3Llc, SIGNAL(clicked(bool)), rbL3None, SLOT(click())); connect(rbFt802Dot3Llc, SIGNAL(clicked(bool)), rbL3None, SLOT(click()));
// Enable/Disable L3 Protocol Choices for FT 802Dot3Llc // Enable/Disable L3 Protocol Choices for FT 802Dot3Llc
connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool)));
connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool)));
connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool))); connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(bool)));
// Enable/Disable L3 Protocol Choices for FT 802.3 LLC SNAP // Enable/Disable L3 Protocol Choices for FT 802.3 LLC SNAP
connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool)));
connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool))); connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool)));
connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(bool))); connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(bool)));
@ -97,25 +71,16 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
connect(rbFtOther, SIGNAL(toggled(bool)), rbL3Other, SLOT(setChecked(bool))); connect(rbFtOther, SIGNAL(toggled(bool)), rbL3Other, SLOT(setChecked(bool)));
connect(rbFtOther, SIGNAL(toggled(bool)), gbL3Proto, SLOT(setDisabled(bool))); connect(rbFtOther, SIGNAL(toggled(bool)), gbL3Proto, SLOT(setDisabled(bool)));
// Enable/Disable L4 Protocol Choices for L3 Protocol None // If L3 = None, force subsequent protocol level also to None
connect(rbL3None, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool))); connect(rbL3None, SIGNAL(toggled(bool)), this, SLOT(forceProtocolNone(bool)));
connect(rbL3None, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setDisabled(bool)));
connect(rbL3None, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setDisabled(bool)));
connect(rbL3None, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setDisabled(bool)));
connect(rbL3None, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setDisabled(bool)));
// Force L4 Protocol = None if L3 Protocol is set to None
connect(rbL3None, SIGNAL(clicked(bool)), rbL4None, SLOT(click()));
// Enable/Disable L4 Protocol Choices for L3 Protocol IPv4 // Enable/Disable L4 Protocol Choices for L3 Protocol IPv4
connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool)));
connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setEnabled(bool))); connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setEnabled(bool)));
connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setEnabled(bool))); connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setEnabled(bool)));
connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setEnabled(bool))); connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setEnabled(bool)));
connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setEnabled(bool))); connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setEnabled(bool)));
// Enable/Disable L4 Protocol Choices for L3 Protocol ARP // Enable/Disable L4 Protocol Choices for L3 Protocol ARP
connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool)));
connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setDisabled(bool))); connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setDisabled(bool)));
connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setDisabled(bool))); connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setDisabled(bool)));
connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setDisabled(bool))); connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setDisabled(bool)));
@ -183,66 +148,62 @@ void StreamConfigDialog::setupUiExtra()
QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}"); QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}");
// ---- Setup default stuff that cannot be done in designer ---- // ---- Setup default stuff that cannot be done in designer ----
#if 0 bgProto[ProtoL1] = new QButtonGroup();
gbVlan->setDisabled(true); bgProto[ProtoL1]->addButton(rbL1None, ButtonIdNone);
#endif bgProto[ProtoL1]->addButton(rbL1Mac, OstProto::Protocol::kMacFieldNumber);
bgProto[ProtoL1]->addButton(rbL1Other, ButtonIdOther);
bgL1Proto = new QButtonGroup(); bgProto[ProtoL2] = new QButtonGroup();
bgL1Proto->addButton(rbL1None, ButtonIdNone);
bgL1Proto->addButton(rbL1Mac, OstProto::Protocol::kMacFieldNumber);
bgL1Proto->addButton(rbL1Other, ButtonIdOther);
bgL2Proto = new QButtonGroup();
#if 0 #if 0
foreach(QRadioButton *btn, gbFrameType->findChildren<QRadioButton*>()) foreach(QRadioButton *btn, gbFrameType->findChildren<QRadioButton*>())
bgL2Proto->addButton(btn); bgL2Proto->addButton(btn);
#else #else
bgL2Proto->addButton(rbFtNone, ButtonIdNone); bgProto[ProtoL2]->addButton(rbFtNone, ButtonIdNone);
bgL2Proto->addButton(rbFtEthernet2, OstProto::Protocol::kEth2FieldNumber); bgProto[ProtoL2]->addButton(rbFtEthernet2, OstProto::Protocol::kEth2FieldNumber);
bgL2Proto->addButton(rbFt802Dot3Raw, OstProto::Protocol::kDot3FieldNumber); bgProto[ProtoL2]->addButton(rbFt802Dot3Raw, OstProto::Protocol::kDot3FieldNumber);
bgL2Proto->addButton(rbFt802Dot3Llc, OstProto::Protocol::kDot2LlcFieldNumber); bgProto[ProtoL2]->addButton(rbFt802Dot3Llc, OstProto::Protocol::kDot2LlcFieldNumber);
bgL2Proto->addButton(rbFtLlcSnap, OstProto::Protocol::kDot2SnapFieldNumber); bgProto[ProtoL2]->addButton(rbFtLlcSnap, OstProto::Protocol::kDot2SnapFieldNumber);
bgL2Proto->addButton(rbFtOther, ButtonIdOther); bgProto[ProtoL2]->addButton(rbFtOther, ButtonIdOther);
#endif #endif
bgVlan = new QButtonGroup(); bgProto[ProtoVlan] = new QButtonGroup();
bgVlan->addButton(rbVlanNone, ButtonIdNone); bgProto[ProtoVlan]->addButton(rbVlanNone, ButtonIdNone);
bgVlan->addButton(rbVlanSingle, OstProto::Protocol::kVlanFieldNumber); bgProto[ProtoVlan]->addButton(rbVlanSingle, OstProto::Protocol::kVlanFieldNumber);
bgVlan->addButton(rbVlanDouble, OstProto::Protocol::kVlanStackFieldNumber); bgProto[ProtoVlan]->addButton(rbVlanDouble, OstProto::Protocol::kVlanStackFieldNumber);
bgL3Proto = new QButtonGroup(); bgProto[ProtoL3] = new QButtonGroup();
#if 0 #if 0
foreach(QRadioButton *btn, gbL3Proto->findChildren<QRadioButton*>()) foreach(QRadioButton *btn, gbL3Proto->findChildren<QRadioButton*>())
bgL3Proto->addButton(btn); bgProto[ProtoL3]->addButton(btn);
#else #else
bgL3Proto->addButton(rbL3None, ButtonIdNone); bgProto[ProtoL3]->addButton(rbL3None, ButtonIdNone);
bgL3Proto->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber); bgProto[ProtoL3]->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber);
bgL3Proto->addButton(rbL3Ipv6, 0xFFFF); bgProto[ProtoL3]->addButton(rbL3Ipv6, 0xFFFF);
bgL3Proto->addButton(rbL3Arp, 0xFFFF); bgProto[ProtoL3]->addButton(rbL3Arp, 0xFFFF);
bgL3Proto->addButton(rbL3Other, ButtonIdOther); bgProto[ProtoL3]->addButton(rbL3Other, ButtonIdOther);
#endif #endif
bgL4Proto = new QButtonGroup(); bgProto[ProtoL4] = new QButtonGroup();
#if 0 #if 0
foreach(QRadioButton *btn, gbL4Proto->findChildren<QRadioButton*>()) foreach(QRadioButton *btn, gbL4Proto->findChildren<QRadioButton*>())
bgL4Proto->addButton(btn); bgProto[ProtoL4]->addButton(btn);
#else #else
bgL4Proto->addButton(rbL4None, 0); bgProto[ProtoL4]->addButton(rbL4None, 0);
bgL4Proto->addButton(rbL4Tcp, OstProto::Protocol::kTcpFieldNumber); bgProto[ProtoL4]->addButton(rbL4Tcp, OstProto::Protocol::kTcpFieldNumber);
bgL4Proto->addButton(rbL4Udp, OstProto::Protocol::kUdpFieldNumber); bgProto[ProtoL4]->addButton(rbL4Udp, OstProto::Protocol::kUdpFieldNumber);
bgL4Proto->addButton(rbL4Icmp, 0xFFFF); bgProto[ProtoL4]->addButton(rbL4Icmp, 0xFFFF);
bgL4Proto->addButton(rbL4Igmp, 0xFFFF); bgProto[ProtoL4]->addButton(rbL4Igmp, 0xFFFF);
bgL4Proto->addButton(rbL4Other, ButtonIdOther); bgProto[ProtoL4]->addButton(rbL4Other, ButtonIdOther);
#endif #endif
bgPayloadProto = new QButtonGroup(); bgProto[ProtoPayload] = new QButtonGroup();
#if 0 #if 0
foreach(QRadioButton *btn, gbPayloadProto->findChildren<QRadioButton*>()) foreach(QRadioButton *btn, gbPayloadProto->findChildren<QRadioButton*>())
bgPayloadProto->addButton(btn); bgProto[ProtoPayload]->addButton(btn);
#else #else
bgPayloadProto->addButton(rbPayloadNone, ButtonIdNone); bgProto[ProtoPayload]->addButton(rbPayloadNone, ButtonIdNone);
bgPayloadProto->addButton(rbPayloadPattern, OstProto::Protocol::kPayloadFieldNumber); bgProto[ProtoPayload]->addButton(rbPayloadPattern, OstProto::Protocol::kPayloadFieldNumber);
bgPayloadProto->addButton(rbPayloadOther, ButtonIdOther); bgProto[ProtoPayload]->addButton(rbPayloadOther, ButtonIdOther);
#endif #endif
/* /*
** Setup Validators ** Setup Validators
@ -270,12 +231,8 @@ StreamConfigDialog::~StreamConfigDialog()
delete mpPacketModelTester; delete mpPacketModelTester;
delete mpPacketModel; delete mpPacketModel;
delete bgL1Proto; for (int i = ProtoMin; i < ProtoMax; i++)
delete bgL2Proto; delete bgProto[i];
delete bgVlan;
delete bgL3Proto;
delete bgL4Proto;
delete bgPayloadProto;
delete _iter; delete _iter;
delete mpStream; delete mpStream;
@ -594,149 +551,122 @@ void StreamConfigDialog::on_lePattern_editingFinished()
/*! /*!
Skip protocols upto and including the layer specified. Skip protocols upto and including the layer specified.
0 - L1
1 - VLAN
2 - L2
3 - L3
4 - L4
TODO: Convert the above values to enum??
*/ */
bool StreamConfigDialog::skipProtocols(int layer) bool StreamConfigDialog::skipProtocols(int layer)
{ {
int id;
QAbstractButton *btn;
_iter->toFront(); _iter->toFront();
// Skip L1 for (int i = ProtoMin; i <= layer; i++)
if (_iter->hasNext())
{ {
id = _iter->next()->protocolNumber(); if(_iter->hasNext())
btn = bgL1Proto->button(id); {
if (btn == NULL) int id;
_iter->previous(); QAbstractButton *btn;
id = _iter->peekNext()->protocolNumber();
btn = bgProto[i]->button(id);
if (btn)
_iter->next();
}
} }
if (layer == 0)
goto _done;
// Skip VLAN
if(_iter->hasNext())
{
id = _iter->next()->protocolNumber();
btn = bgVlan->button(id);
if (btn == NULL)
_iter->previous();
}
if (layer == 1)
goto _done;
// Skip L2
if(_iter->hasNext())
{
id = _iter->next()->protocolNumber();
btn = bgL2Proto->button(id);
if (btn == NULL)
_iter->previous();
}
if (layer == 2)
goto _done;
// Skip L3
if (_iter->hasNext())
{
id = _iter->next()->protocolNumber();
btn = bgL3Proto->button(id);
if (btn == NULL)
_iter->previous();
}
if (layer == 3)
goto _done;
// Skip L4
if(_iter->hasNext())
{
id = _iter->next()->protocolNumber();
btn = bgL4Proto->button(id);
if (btn == NULL)
_iter->previous();
}
if (layer == 4)
goto _done;
return false;
_done:
return true; return true;
} }
void StreamConfigDialog::updateL1Protocol(int newId) /*!
Protocol choices (except "None" and "Other") for a protocol button group are disabled if checked is true, else they are enabled
*/
void StreamConfigDialog::disableProtocols(QButtonGroup *protocolGroup, bool checked)
{ {
static int oldId; qDebug("%s: btnGrp = %p, chk? = %d", __FUNCTION__, protocolGroup, checked);
foreach(QAbstractButton *btn, protocolGroup->buttons())
qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId,
isUpdateInProgress);
if (oldId == newId)
return; // Nothing to be done
if (!isUpdateInProgress)
{ {
AbstractProtocol *p; int id = protocolGroup->id(btn);
_iter->toFront(); if ((id != ButtonIdNone) && (id != ButtonIdOther))
btn->setDisabled(checked);
Q_ASSERT(newId != ButtonIdOther);
switch (oldId)
{
case ButtonIdNone:
_iter->insert(OstProtocolManager.createProtocol(
newId, mpStream));
break;
case ButtonIdOther:
default:
Q_ASSERT(_iter->hasNext());
p =_iter->next();
if (newId)
_iter->setValue(OstProtocolManager.createProtocol(
newId, mpStream));
else
_iter->remove();
delete p;
break;
}
} }
oldId = newId;
return;
} }
void StreamConfigDialog::updateVlanProtocol(int newId) void StreamConfigDialog::forceProtocolNone(bool checked)
{ {
static int oldId; QObject *btn;
qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, btn = sender();
isUpdateInProgress); Q_ASSERT(btn != NULL);
if (oldId == newId) qDebug("%s: chk? = %d, btn = %p, L1 = %p, L2 = %p, L3 = %p", __FUNCTION__,
return; // Nothing to be done checked, btn, rbL1None, rbFtNone, rbL3None);
if (btn == rbL1None)
{
if (checked)
{
bgProto[ProtoVlan]->button(ButtonIdNone)->click();
bgProto[ProtoL2]->button(ButtonIdNone)->click();
bgProto[ProtoPayload]->button(ButtonIdNone)->click();
}
disableProtocols(bgProto[ProtoVlan], checked);
disableProtocols(bgProto[ProtoL2], checked);
disableProtocols(bgProto[ProtoPayload], checked);
}
else if (btn == rbFtNone)
{
if (checked)
bgProto[ProtoL3]->button(ButtonIdNone)->click();
disableProtocols(bgProto[ProtoL3], checked);
}
else if (btn == rbL3None)
{
if (checked)
bgProto[ProtoL4]->button(ButtonIdNone)->click();
disableProtocols(bgProto[ProtoL4], checked);
}
else
{
Q_ASSERT(1 == 0); // Unreachable code!
}
}
void StreamConfigDialog::updateProtocol(int newId)
{
int level;
QButtonGroup *btnGrp;
btnGrp = static_cast<QButtonGroup*>(sender());
Q_ASSERT(btnGrp != NULL);
level = btnGrp->property("ProtocolLevel").toInt();
Q_ASSERT(btnGrp == bgProto[level]);
__updateProtocol(level, newId);
}
void StreamConfigDialog::__updateProtocol(int level, int newId)
{
int oldId;
QButtonGroup *btnGrp;
Q_ASSERT((level >= ProtoMin) && (level <= ProtoMax));
btnGrp = bgProto[level];
oldId = btnGrp->property("ProtocolId").toInt();
qDebug("%s: level = %d old id = %d new id = %d upd? = %d", __FUNCTION__,
level, oldId, newId, isUpdateInProgress);
if (newId == oldId)
return;
if (!isUpdateInProgress) if (!isUpdateInProgress)
{ {
int ret; int ret;
AbstractProtocol *p; AbstractProtocol *p;
ret = skipProtocols(0); ret = skipProtocols(level-1);
Q_ASSERT(ret == true); Q_ASSERT(ret == true);
Q_ASSERT(oldId != ButtonIdOther);
Q_ASSERT(oldId != newId);
Q_ASSERT(newId != ButtonIdOther); Q_ASSERT(newId != ButtonIdOther);
switch (oldId) switch (oldId)
@ -757,347 +687,96 @@ void StreamConfigDialog::updateVlanProtocol(int newId)
else else
_iter->remove(); _iter->remove();
delete p; delete p;
break; if (level == ProtoPayload)
}
}
oldId = newId;
return;
}
void StreamConfigDialog::updateFrameTypeProtocol(int newId)
{
static int oldId;
qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId,
isUpdateInProgress);
if (oldId == newId)
return; // Nothing to be done
if (!isUpdateInProgress)
{
int ret;
AbstractProtocol *p;
ret = skipProtocols(1);
Q_ASSERT(ret == true);
Q_ASSERT(newId != ButtonIdOther);
switch (oldId)
{
case ButtonIdNone:
_iter->insert(OstProtocolManager.createProtocol(
newId, mpStream));
break;
case ButtonIdOther:
default:
Q_ASSERT(_iter->hasNext());
p =_iter->next();
if (newId)
_iter->setValue(OstProtocolManager.createProtocol(
newId, mpStream));
else
_iter->remove();
delete p;
break;
}
}
oldId = newId;
return;
}
void StreamConfigDialog::updateL3Protocol(int newId)
{
static int oldId;
qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId,
isUpdateInProgress);
if (oldId == newId)
return; // Nothing to be done
if (!isUpdateInProgress)
{
int ret;
AbstractProtocol *p;
ret = skipProtocols(2);
Q_ASSERT(ret == true);
Q_ASSERT(newId != ButtonIdOther);
switch (oldId)
{
case ButtonIdNone:
_iter->insert(OstProtocolManager.createProtocol(
newId, mpStream));
break;
case ButtonIdOther:
default:
Q_ASSERT(_iter->hasNext());
p =_iter->next();
if (newId)
_iter->setValue(OstProtocolManager.createProtocol(
newId, mpStream));
else
_iter->remove();
delete p;
break;
}
}
oldId = newId;
return;
}
void StreamConfigDialog::updateL4Protocol(int newId)
{
static int oldId;
qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId,
isUpdateInProgress);
if (oldId == newId)
return; // Nothing to be done
if (!isUpdateInProgress)
{
int ret;
AbstractProtocol *p;
ret = skipProtocols(3);
Q_ASSERT(ret == true);
Q_ASSERT(newId != ButtonIdOther);
switch (oldId)
{
case ButtonIdNone:
_iter->insert(OstProtocolManager.createProtocol(
newId, mpStream));
break;
case ButtonIdOther:
default:
Q_ASSERT(_iter->hasNext());
p =_iter->next();
if (newId)
_iter->setValue(OstProtocolManager.createProtocol(
newId, mpStream));
else
_iter->remove();
delete p;
break;
}
}
oldId = newId;
return;
}
void StreamConfigDialog::updatePayloadProtocol(int newId)
{
static int oldId;
qDebug("%s:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId,
isUpdateInProgress);
if (oldId == newId)
return; // Nothing to be done
if (!isUpdateInProgress)
{
int ret;
AbstractProtocol *p;
ret = skipProtocols(4);
Q_ASSERT(ret == true);
Q_ASSERT(newId != ButtonIdOther);
switch (oldId)
{
case ButtonIdNone:
_iter->insert(OstProtocolManager.createProtocol(
newId, mpStream));
break;
case ButtonIdOther:
default:
Q_ASSERT(_iter->hasNext());
p =_iter->next();
if (newId)
_iter->setValue(OstProtocolManager.createProtocol(
newId, mpStream));
else
_iter->remove();
delete p;
while (_iter->hasNext())
{ {
while (_iter->hasNext())
p = _iter->next(); {
_iter->remove(); p = _iter->next();
delete p; _iter->remove();
delete p;
}
} }
break; break;
} }
} }
oldId = newId; btnGrp->setProperty("ProtocolId", newId);
return; return;
} }
void StreamConfigDialog::updateSelectProtocolsSimpleWidget() void StreamConfigDialog::updateSelectProtocolsSimpleWidget()
{ {
quint32 id; int i;
quint32 id;
QAbstractButton *btn; QAbstractButton *btn;
qDebug("%s", __FUNCTION__); qDebug("%s", __FUNCTION__);
isUpdateInProgress = true; isUpdateInProgress = true;
// Reset to default state // Reset to default state ...
rbL1None->setChecked(true); for (i = ProtoMin; i < ProtoMax; i++)
rbVlanNone->setChecked(true); bgProto[i]->button(ButtonIdNone)->click();
rbFtNone->setChecked(true);
rbL3None->setChecked(true);
rbL4None->setChecked(true);
rbPayloadNone->setChecked(true);
// ... now iterate and update
_iter->toFront(); _iter->toFront();
// L1 (optional if followed by Payload) for (i = ProtoMin; i < ProtoMax; i++)
if (!_iter->hasNext()) // No protocols at all?
goto _done;
id = _iter->next()->protocolNumber();
btn = bgL1Proto->button(id);
if (btn && btn->isEnabled())
btn->click();
else
{ {
btn = bgPayloadProto->button(id); if (!_iter->hasNext())
goto _done;
id = _iter->next()->protocolNumber();
btn = bgProto[i]->button(id);
if (btn && btn->isEnabled()) if (btn && btn->isEnabled())
goto _payload; btn->click();
else else
goto _otherL1; {
switch (i)
{
case ProtoVlan:
_iter->previous();
break;
case ProtoPayload:
goto _other;
default:
btn = bgProto[ProtoPayload]->button(id);
if (btn && btn->isEnabled())
{
btn->click();
break;
}
else
goto _other;
}
}
} }
// VLAN (optional)
if (!_iter->hasNext())
goto _done;
id = _iter->next()->protocolNumber();
btn = bgVlan->button(id);
if (btn && btn->isEnabled())
btn->click();
else
_iter->previous();
// L2 (optional if followed by Payload)
if (!_iter->hasNext())
goto _done;
id = _iter->next()->protocolNumber();
btn = bgL2Proto->button(id);
if (btn && btn->isEnabled())
btn->click();
else
{
btn = bgPayloadProto->button(id);
if (btn && btn->isEnabled())
goto _payload;
else
goto _otherL2;
}
// L3 (optional if followed by Payload)
if (!_iter->hasNext())
goto _done;
id = _iter->next()->protocolNumber();
btn = bgL3Proto->button(id);
if (btn && btn->isEnabled())
btn->click();
else
{
btn = bgPayloadProto->button(id);
if (btn && btn->isEnabled())
goto _payload;
else
goto _otherL3;
}
// L4 (optional if followed by Payload)
if (!_iter->hasNext())
goto _done;
id = _iter->next()->protocolNumber();
btn = bgL4Proto->button(id);
if (btn && btn->isEnabled())
btn->click();
else
{
btn = bgPayloadProto->button(id);
if (btn && btn->isEnabled())
goto _payload;
else
goto _otherL4;
}
// Payload Data
if (!_iter->hasNext())
goto _done;
id = _iter->next()->protocolNumber();
btn = bgPayloadProto->button(id);
_payload:
if (btn && btn->isEnabled())
btn->click();
else
goto _otherPayload;
// If more protocol(s) beyond payload ... // If more protocol(s) beyond payload ...
if (_iter->hasNext()) if (_iter->hasNext())
goto _otherPayload; {
i = ProtoPayload;
goto _other;
}
goto _done; goto _done;
_otherL1: _other:
bgL1Proto->button(ButtonIdOther)->setChecked(true); for (int j = i; j < ProtoMax; j++)
updateL1Protocol(ButtonIdOther); {
_otherL2: // VLAN doesn't have a "Other" button
bgL2Proto->button(ButtonIdOther)->setChecked(true); if (j == ProtoVlan)
updateFrameTypeProtocol(ButtonIdOther); continue;
_otherL3:
bgL3Proto->button(ButtonIdOther)->setChecked(true); bgProto[j]->button(ButtonIdOther)->setChecked(true);
updateL3Protocol(ButtonIdOther); __updateProtocol(j, ButtonIdOther);
_otherL4: }
bgL4Proto->button(ButtonIdOther)->setChecked(true);
updateL4Protocol(ButtonIdOther);
_otherPayload:
bgPayloadProto->button(ButtonIdOther)->setChecked(true);
updatePayloadProtocol(ButtonIdOther);
_done: _done:
isUpdateInProgress = false; isUpdateInProgress = false;
return;
} }
void StreamConfigDialog::LoadCurrentStream() void StreamConfigDialog::LoadCurrentStream()

View File

@ -28,11 +28,25 @@ public:
private: private:
QButtonGroup *bgFrameType; enum ButtonId
QButtonGroup *bgVlan; {
QButtonGroup *bgL3Proto; ButtonIdNone = 0,
QButtonGroup *bgL4Proto; ButtonIdOther = -2
QButtonGroup *bgPayloadProto; };
enum ProtoButtonGroup
{
ProtoMin,
ProtoL1 = 0,
ProtoVlan = 1,
ProtoL2 = 2,
ProtoL3 = 3,
ProtoL4 = 4,
ProtoPayload = 5,
ProtoMax
};
QButtonGroup *bgProto[ProtoMax];
QStringListModel *mpAvailableProtocolsModel; QStringListModel *mpAvailableProtocolsModel;
QStringListModel *mpSelectedProtocolsModel; QStringListModel *mpSelectedProtocolsModel;
@ -68,11 +82,11 @@ private slots:
// "Simple" Protocol Selection related // "Simple" Protocol Selection related
bool skipProtocols(int layer); bool skipProtocols(int layer);
void updateFrameTypeProtocol(int id); void disableProtocols(QButtonGroup *protocolGroup, bool checked);
void updateVlanProtocol(int id); void forceProtocolNone(bool checked);
void updateL3Protocol(int id);
void updateL4Protocol(int id); void updateProtocol(int newId);
void updatePayloadProtocol(int id); void __updateProtocol(int level, int newId);
void updateSelectProtocolsSimpleWidget(); void updateSelectProtocolsSimpleWidget();

View File

@ -8,8 +8,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>524</width> <width>569</width>
<height>458</height> <height>464</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy" > <property name="sizePolicy" >
@ -173,7 +173,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>465</width> <width>527</width>
<height>226</height> <height>226</height>
</rect> </rect>
</property> </property>
@ -181,16 +181,58 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
<string>Simple</string> <string>Simple</string>
</attribute> </attribute>
<layout class="QGridLayout" > <layout class="QGridLayout" >
<item rowspan="2" row="0" column="0" > <item row="0" column="0" >
<widget class="QGroupBox" name="gbFrameType" > <widget class="QGroupBox" name="gbL1Proto" >
<property name="title" > <property name="title" >
<string>Frame Type</string> <string>L1</string>
</property>
<layout class="QVBoxLayout" >
<item>
<widget class="QRadioButton" name="rbL1None" >
<property name="text" >
<string>None</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbL1Mac" >
<property name="text" >
<string>Mac</string>
</property>
<property name="checked" >
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbL1Other" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>Other</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item rowspan="3" row="0" column="1" >
<widget class="QGroupBox" name="gbFrameType" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="title" >
<string>L2</string>
</property> </property>
<layout class="QVBoxLayout" > <layout class="QVBoxLayout" >
<item> <item>
<widget class="QRadioButton" name="rbFtNone" > <widget class="QRadioButton" name="rbFtNone" >
<property name="text" > <property name="text" >
<string>None (Mac Only)</string> <string>None</string>
</property> </property>
<property name="checked" > <property name="checked" >
<bool>true</bool> <bool>true</bool>
@ -244,50 +286,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="0" column="1" > <item row="0" column="2" >
<widget class="QGroupBox" name="gbVlan" > <widget class="QGroupBox" name="gbL3Proto" >
<property name="enabled" > <property name="enabled" >
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="title" >
<string>VLAN</string>
</property>
<property name="checkable" >
<bool>false</bool>
</property>
<property name="checked" >
<bool>false</bool>
</property>
<layout class="QVBoxLayout" >
<item>
<widget class="QRadioButton" name="rbVlanNone" >
<property name="text" >
<string>None</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbVlanSingle" >
<property name="text" >
<string>Single Tag</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbVlanDouble" >
<property name="text" >
<string>Double Tag</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="2" colspan="2" >
<widget class="QGroupBox" name="gbL3Proto" >
<property name="title" > <property name="title" >
<string>L3</string> <string>L3</string>
</property> </property>
@ -348,8 +351,95 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="1" column="1" colspan="2" > <item row="0" column="3" >
<widget class="QGroupBox" name="gbPayloadProto" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="title" >
<string>Payload</string>
</property>
<layout class="QVBoxLayout" >
<item>
<widget class="QRadioButton" name="rbPayloadNone" >
<property name="text" >
<string>None</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbPayloadPattern" >
<property name="text" >
<string>Pattern</string>
</property>
<property name="checked" >
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbPayloadOther" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>Other</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item rowspan="2" row="1" column="0" >
<widget class="QGroupBox" name="gbVlan" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="title" >
<string>VLAN</string>
</property>
<property name="checkable" >
<bool>false</bool>
</property>
<property name="checked" >
<bool>false</bool>
</property>
<layout class="QVBoxLayout" >
<item>
<widget class="QRadioButton" name="rbVlanNone" >
<property name="text" >
<string>Untagged</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbVlanSingle" >
<property name="text" >
<string>Tagged</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbVlanDouble" >
<property name="text" >
<string>Stacked</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="2" >
<widget class="QGroupBox" name="gbL4Proto" > <widget class="QGroupBox" name="gbL4Proto" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="title" > <property name="title" >
<string>L4</string> <string>L4</string>
</property> </property>
@ -417,44 +507,15 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="1" column="3" > <item row="2" column="2" >
<widget class="QGroupBox" name="gbPayloadProto" >
<property name="title" >
<string>Payload</string>
</property>
<layout class="QVBoxLayout" >
<item>
<widget class="QRadioButton" name="rbPayloadPattern" >
<property name="text" >
<string>Pattern</string>
</property>
<property name="checked" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbPayloadOther" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>Other</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="1" >
<spacer> <spacer>
<property name="orientation" > <property name="orientation" >
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeHint" > <property name="sizeHint" >
<size> <size>
<width>107</width> <width>20</width>
<height>24</height> <height>21</height>
</size> </size>
</property> </property>
</spacer> </spacer>
@ -1084,7 +1145,6 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
<tabstop>lePktLen</tabstop> <tabstop>lePktLen</tabstop>
<tabstop>lePktLenMin</tabstop> <tabstop>lePktLenMin</tabstop>
<tabstop>lePktLenMax</tabstop> <tabstop>lePktLenMax</tabstop>
<tabstop>rbFtNone</tabstop>
<tabstop>rbFtEthernet2</tabstop> <tabstop>rbFtEthernet2</tabstop>
<tabstop>rbFt802Dot3Raw</tabstop> <tabstop>rbFt802Dot3Raw</tabstop>
<tabstop>rbFt802Dot3Llc</tabstop> <tabstop>rbFt802Dot3Llc</tabstop>

View File

@ -22,9 +22,12 @@
- metaFieldCount() - metaFieldCount()
- isMetaField() - isMetaField()
*/ */
AbstractProtocol::AbstractProtocol(StreamBase *stream) AbstractProtocol::AbstractProtocol(StreamBase *stream, AbstractProtocol *parent)
{ {
//qDebug("%s: &prev = %p &next = %p", __FUNCTION__, &prev, &next);
mpStream = stream; mpStream = stream;
this->parent = parent;
prev = next = NULL;
metaCount = -1; metaCount = -1;
protoSize = -1; protoSize = -1;
} }
@ -33,7 +36,8 @@ AbstractProtocol::~AbstractProtocol()
{ {
} }
AbstractProtocol* AbstractProtocol::createInstance(StreamBase *stream) AbstractProtocol* AbstractProtocol::createInstance(StreamBase *stream,
AbstractProtocol *parent)
{ {
return NULL; return NULL;
} }
@ -139,6 +143,7 @@ AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int index) const
FieldFrameValue, the subclass should handle and return a value for FieldFrameValue, the subclass should handle and return a value for
FieldBitSize to prevent endless recrusion - FieldBitSize to prevent endless recrusion -
- protocolFrameCksum() - protocolFrameCksum()
- protocolFramePayloadSize()
*/ */
QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib, QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib,
int streamIndex) const int streamIndex) const
@ -184,17 +189,16 @@ quint32 AbstractProtocol::protocolId(ProtocolIdType type) const
quint32 AbstractProtocol::payloadProtocolId(ProtocolIdType type) const quint32 AbstractProtocol::payloadProtocolId(ProtocolIdType type) const
{ {
quint32 id = 0xFFFFFFFF; quint32 id;
ProtocolListIterator *iter = mpStream->createProtocolListIterator();
if (iter->findNext(this)) if (next)
{ id = next->protocolId(type);
if (iter->hasNext()) else if (parent)
id = iter->next()->protocolId(type); id = parent->payloadProtocolId(type);
} else
delete iter; id = 0xFFFFFFFF;
qDebug("%s: payloadProtocolId = %u", __FUNCTION__, id); qDebug("%s: payloadProtocolId = 0x%x", __FUNCTION__, id);
return id; return id;
} }
@ -219,17 +223,15 @@ int AbstractProtocol::protocolFrameSize() const
int AbstractProtocol::protocolFrameOffset() const int AbstractProtocol::protocolFrameOffset() const
{ {
int size = 0; int size = 0;
ProtocolListIterator *iter = mpStream->createProtocolListIterator(); AbstractProtocol *p = prev;
while (p)
if (iter->findNext(this))
{ {
iter->previous(); size += p->protocolFrameSize();
while (iter->hasPrevious()) p = p->prev;
size += iter->previous()->protocolFrameSize();
} }
else
return -1; if (parent)
delete iter; size += parent->protocolFrameOffset();
qDebug("%s: ofs = %d", __FUNCTION__, size); qDebug("%s: ofs = %d", __FUNCTION__, size);
return size; return size;
@ -238,17 +240,14 @@ int AbstractProtocol::protocolFrameOffset() const
int AbstractProtocol::protocolFramePayloadSize() const int AbstractProtocol::protocolFramePayloadSize() const
{ {
int size = 0; int size = 0;
AbstractProtocol *p = next;
ProtocolListIterator *iter = mpStream->createProtocolListIterator(); while (p)
if (iter->findNext(this))
{ {
while (iter->hasNext()) size += p->protocolFrameSize();
size += iter->next()->protocolFrameSize(); p = p->next;
} }
else if (parent)
return -1; size += parent->protocolFramePayloadSize();
delete iter;
qDebug("%s: payloadSize = %d", __FUNCTION__, size); qDebug("%s: payloadSize = %d", __FUNCTION__, size);
return size; return size;
@ -361,7 +360,7 @@ quint32 AbstractProtocol::protocolFrameCksum(int streamIndex,
CksumType cksumType) const CksumType cksumType) const
{ {
static int recursionCount = 0; static int recursionCount = 0;
quint32 cksum = 0; quint32 cksum = 0xFFFFFFFF;
recursionCount++; recursionCount++;
Q_ASSERT_X(recursionCount < 10, "protocolFrameCksum", "potential infinite recursion - does a protocol checksum field not implement FieldBitSize?"); Q_ASSERT_X(recursionCount < 10, "protocolFrameCksum", "potential infinite recursion - does a protocol checksum field not implement FieldBitSize?");
@ -426,19 +425,24 @@ quint32 AbstractProtocol::protocolFrameCksum(int streamIndex,
quint32 AbstractProtocol::protocolFrameHeaderCksum(int streamIndex, quint32 AbstractProtocol::protocolFrameHeaderCksum(int streamIndex,
CksumType cksumType) const CksumType cksumType) const
{ {
quint32 sum = 0xFFFF; quint32 sum = 0;
ProtocolListIterator *iter = mpStream->createProtocolListIterator(); quint16 cksum;
AbstractProtocol *p = prev;
Q_ASSERT(cksumType == CksumIpPseudo); Q_ASSERT(cksumType == CksumIpPseudo);
if (iter->findNext(this)) while (p)
{ {
iter->previous(); cksum = p->protocolFrameCksum(streamIndex, cksumType);
if (iter->hasPrevious()) sum += (quint16) ~cksum;
sum = iter->previous()->protocolFrameCksum(streamIndex, p = p->prev;
CksumIpPseudo); qDebug("%s: sum = %u, cksum = %u", __FUNCTION__, sum, cksum);
}
if (parent)
{
cksum = parent->protocolFrameHeaderCksum(streamIndex, cksumType);
sum += (quint16) ~cksum;
} }
delete iter;
while(sum>>16) while(sum>>16)
sum = (sum & 0xFFFF) + (sum >> 16); sum = (sum & 0xFFFF) + (sum >> 16);
@ -451,21 +455,22 @@ quint32 AbstractProtocol::protocolFramePayloadCksum(int streamIndex,
{ {
quint32 sum = 0; quint32 sum = 0;
quint16 cksum; quint16 cksum;
ProtocolListIterator *iter = mpStream->createProtocolListIterator(); AbstractProtocol *p = next;
Q_ASSERT(cksumType == CksumIp); Q_ASSERT(cksumType == CksumIp);
if (iter->findNext(this)) while (p)
{ {
while (iter->hasNext()) cksum = p->protocolFrameCksum(streamIndex, cksumType);
{ sum += (quint16) ~cksum;
cksum = iter->next()->protocolFrameCksum(streamIndex, CksumIp); p = p->next;
sum += (quint16) ~cksum; }
}
if (parent)
{
cksum = parent->protocolFramePayloadCksum(streamIndex, cksumType);
sum += (quint16) ~cksum;
} }
else
return 0;
delete iter;
while(sum>>16) while(sum>>16)
sum = (sum & 0xFFFF) + (sum >> 16); sum = (sum & 0xFFFF) + (sum >> 16);

View File

@ -20,16 +20,24 @@
QString("%1").arg(num, bytes*2, BASE_HEX, QChar('0')) QString("%1").arg(num, bytes*2, BASE_HEX, QChar('0'))
class StreamBase; class StreamBase;
class ProtocolListIterator;
class AbstractProtocol class AbstractProtocol
{ {
template <int protoNumber, class ProtoA, class ProtoB>
friend class ComboProtocol;
friend class ProtocolListIterator;
private: private:
mutable int metaCount; mutable int metaCount;
mutable int protoSize; mutable int protoSize;
mutable QString protoAbbr; mutable QString protoAbbr;
protected: protected:
StreamBase *mpStream; StreamBase *mpStream;
AbstractProtocol *parent;
AbstractProtocol *prev;
AbstractProtocol *next;
public: public:
enum FieldFlag { enum FieldFlag {
@ -61,10 +69,11 @@ public:
CksumMax CksumMax
}; };
AbstractProtocol(StreamBase *stream); AbstractProtocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~AbstractProtocol(); virtual ~AbstractProtocol();
static AbstractProtocol* createInstance(StreamBase *stream); static AbstractProtocol* createInstance(StreamBase *stream,
AbstractProtocol *parent = 0);
virtual quint32 protocolNumber() const; virtual quint32 protocolNumber() const;
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const = 0; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const = 0;

View File

@ -3,7 +3,7 @@
#include "abstractprotocol.h" #include "abstractprotocol.h"
template <class ProtoA, class ProtoB> template <int protoNumber, class ProtoA, class ProtoB>
class ComboProtocol : public AbstractProtocol class ComboProtocol : public AbstractProtocol
{ {
private: private:
@ -12,36 +12,67 @@ private:
QWidget *configForm; QWidget *configForm;
public: public:
ComboProtocol(StreamBase *stream) ComboProtocol(StreamBase *stream, AbstractProtocol *parent = 0)
: AbstractProtocol(stream, parent)
{ {
protoA = new ProtoA(stream); protoA = new ProtoA(stream, this);
protoB = new ProtoB(stream); protoB = new ProtoB(stream, this);
protoA->next = protoB;
protoB->prev = protoA;
configForm = NULL; configForm = NULL;
}
virtual ~ComboProtocol() qDebug("%s: protoNumber = %d, %p <--> %p", __FUNCTION__,
{ protoNumber, protoA, protoB);
delete protoA;
delete protoB;
delete configForm;
} }
static ComboProtocol* createInstance(StreamBase *stream) virtual ~ComboProtocol()
{ {
return new ComboProtocol<ProtoA, ProtoB>(stream); if (configForm)
{
protoA->configWidget()->setParent(0);
protoB->configWidget()->setParent(0);
delete configForm;
}
delete protoA;
delete protoB;
}
static ComboProtocol* createInstance(StreamBase *stream,
AbstractProtocol *parent)
{
return new ComboProtocol<protoNumber, ProtoA, ProtoB>(stream, parent);
} }
virtual quint32 protocolNumber() const virtual quint32 protocolNumber() const
{ {
return 0; //FIXME return protoNumber;
} }
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const virtual void protoDataCopyInto(OstProto::Protocol &protocol) const
{ {
// FIXME protoA->protoDataCopyInto(protocol);
protoB->protoDataCopyInto(protocol);
protocol.mutable_protocol_id()->set_id(protocolNumber());
} }
virtual void protoDataCopyFrom(const OstProto::Protocol &protocol) virtual void protoDataCopyFrom(const OstProto::Protocol &protocol)
{ {
// FIXME if (protocol.protocol_id().id() == protocolNumber())
{
OstProto::Protocol proto;
// NOTE: To use protoX->protoDataCopyFrom() we need to arrange
// so that it sees its own protocolNumber() - but since the
// input param 'protocol' is 'const', we make a copy first
proto.CopyFrom(protocol);
proto.mutable_protocol_id()->set_id(protoA->protocolNumber());
protoA->protoDataCopyFrom(proto);
proto.mutable_protocol_id()->set_id(protoB->protocolNumber());
protoB->protoDataCopyFrom(proto);
}
} }
virtual QString name() const virtual QString name() const
@ -68,26 +99,32 @@ public:
virtual FieldFlags fieldFlags(int index) const virtual FieldFlags fieldFlags(int index) const
{ {
if (index < protoA->fieldCount()) int cnt = protoA->fieldCount();
if (index < cnt)
return protoA->fieldFlags(index); return protoA->fieldFlags(index);
else else
return protoB->fieldFlags(index); return protoB->fieldFlags(index - cnt);
} }
virtual QVariant fieldData(int index, FieldAttrib attrib, virtual QVariant fieldData(int index, FieldAttrib attrib,
int streamIndex = 0) const int streamIndex = 0) const
{ {
if (index < protoA->fieldCount()) int cnt = protoA->fieldCount();
return protoA->fieldData(index);
if (index < cnt)
return protoA->fieldData(index, attrib, streamIndex);
else else
return protoB->fieldData(index); return protoB->fieldData(index - cnt, attrib, streamIndex);
} }
virtual bool setFieldData(int index, const QVariant &value, virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue) FieldAttrib attrib = FieldValue)
{ {
if (index < protoA->fieldCount()) int cnt = protoA->fieldCount();
return protoA->fieldData(index);
if (index < cnt)
return protoA->setFieldData(index, value, attrib);
else else
return protoB->fieldData(index); return protoB->setFieldData(index - cnt, value, attrib);
} }
#if 0 #if 0
@ -109,11 +146,13 @@ public:
{ {
if (configForm == NULL) if (configForm == NULL)
{ {
QVBoxLayout *layout = new VBoxLayout; QVBoxLayout *layout = new QVBoxLayout;
configForm = new QWidget; configForm = new QWidget;
layout->addWidget(protoA->configWidget()); layout->addWidget(protoA->configWidget());
layout->addWidget(protoB->configWidget()); layout->addWidget(protoB->configWidget());
layout->setSpacing(0);
layout->setContentsMargins(0, 0, 0, 0);
configForm->setLayout(layout); configForm->setLayout(layout);
} }
return configForm; return configForm;

11
common/dot2llc.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef _DOT2_LLC_H
#define _DOT2_LLC_H
#include "comboprotocol.h"
#include "dot3.h"
#include "llc.h"
typedef ComboProtocol<OstProto::Protocol::kDot2LlcFieldNumber,
Dot3Protocol, LlcProtocol> Dot2LlcProtocol;
#endif

14
common/dot2llc.proto Normal file
View File

@ -0,0 +1,14 @@
import "protocol.proto";
import "dot3.proto";
import "llc.proto";
package OstProto;
// 802.2 LLC
message Dot2Llc {
// Empty since this is a 'combo' protocol
}
extend Protocol {
optional Dot2Llc dot2Llc = 127;
}

11
common/dot2snap.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef _DOT2_SNAP_H
#define _DOT2_SNAP_H
#include "comboprotocol.h"
#include "dot2llc.h"
#include "snap.h"
typedef ComboProtocol<OstProto::Protocol::kDot2SnapFieldNumber,
Dot2LlcProtocol, SnapProtocol> Dot2SnapProtocol;
#endif

12
common/dot2snap.proto Normal file
View File

@ -0,0 +1,12 @@
import "protocol.proto";
package OstProto;
// 802.2 SNAP
message Dot2Snap {
// Empty since this is a 'combo' protocol
}
extend Protocol {
optional Dot2Snap dot2Snap = 128;
}

View File

@ -12,8 +12,8 @@ Dot3ConfigForm::Dot3ConfigForm(QWidget *parent)
setupUi(this); setupUi(this);
} }
Dot3Protocol::Dot3Protocol(StreamBase *stream) Dot3Protocol::Dot3Protocol(StreamBase *stream, AbstractProtocol *parent)
: AbstractProtocol(stream) : AbstractProtocol(stream, parent)
{ {
configForm = NULL; configForm = NULL;
} }
@ -23,9 +23,10 @@ Dot3Protocol::~Dot3Protocol()
delete configForm; delete configForm;
} }
AbstractProtocol* Dot3Protocol::createInstance(StreamBase *stream) AbstractProtocol* Dot3Protocol::createInstance(StreamBase *stream,
AbstractProtocol *parent)
{ {
return new Dot3Protocol(stream); return new Dot3Protocol(stream, parent);
} }
quint32 Dot3Protocol::protocolNumber() const quint32 Dot3Protocol::protocolNumber() const
@ -75,14 +76,16 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib,
{ {
quint16 len; quint16 len;
len = mpStream->frameLen() - SZ_FCS; //len = mpStream->frameLen() - SZ_FCS;
len = protocolFramePayloadSize();
return len; return len;
} }
case FieldTextValue: case FieldTextValue:
{ {
quint16 len; quint16 len;
len = mpStream->frameLen() - SZ_FCS; //len = mpStream->frameLen() - SZ_FCS;
len = protocolFramePayloadSize();
return QString("%1").arg(len); return QString("%1").arg(len);
} }
case FieldFrameValue: case FieldFrameValue:
@ -90,11 +93,14 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib,
quint16 len; quint16 len;
QByteArray fv; QByteArray fv;
len = mpStream->frameLen() - SZ_FCS; //len = mpStream->frameLen() - SZ_FCS;
len = protocolFramePayloadSize();
fv.resize(2); fv.resize(2);
qToBigEndian(len, (uchar*) fv.data()); qToBigEndian(len, (uchar*) fv.data());
return fv; return fv;
} }
case FieldBitSize:
return 16;
default: default:
break; break;
} }

View File

@ -26,10 +26,11 @@ private:
}; };
public: public:
Dot3Protocol(StreamBase *stream); Dot3Protocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~Dot3Protocol(); virtual ~Dot3Protocol();
static AbstractProtocol* createInstance(StreamBase *stream); static AbstractProtocol* createInstance(StreamBase *stream,
AbstractProtocol *parent = 0);
virtual quint32 protocolNumber() const; virtual quint32 protocolNumber() const;
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const;

View File

@ -9,8 +9,8 @@ Eth2ConfigForm::Eth2ConfigForm(QWidget *parent)
setupUi(this); setupUi(this);
} }
Eth2Protocol::Eth2Protocol(StreamBase *stream) Eth2Protocol::Eth2Protocol(StreamBase *stream, AbstractProtocol *parent)
: AbstractProtocol(stream) : AbstractProtocol(stream, parent)
{ {
configForm = NULL; configForm = NULL;
} }
@ -20,9 +20,10 @@ Eth2Protocol::~Eth2Protocol()
delete configForm; delete configForm;
} }
AbstractProtocol* Eth2Protocol::createInstance(StreamBase *stream) AbstractProtocol* Eth2Protocol::createInstance(StreamBase *stream,
AbstractProtocol *parent)
{ {
return new Eth2Protocol(stream); return new Eth2Protocol(stream, parent);
} }
quint32 Eth2Protocol::protocolNumber() const quint32 Eth2Protocol::protocolNumber() const

View File

@ -26,10 +26,11 @@ private:
}; };
public: public:
Eth2Protocol(StreamBase *stream); Eth2Protocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~Eth2Protocol(); virtual ~Eth2Protocol();
static AbstractProtocol* createInstance(StreamBase *stream); static AbstractProtocol* createInstance(StreamBase *stream,
AbstractProtocol *parent = 0);
virtual quint32 protocolNumber() const; virtual quint32 protocolNumber() const;
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const;

View File

@ -49,8 +49,8 @@ void Ip4ConfigForm::on_cmbIpDstAddrMode_currentIndexChanged(int index)
} }
} }
Ip4Protocol::Ip4Protocol(StreamBase *stream) Ip4Protocol::Ip4Protocol(StreamBase *stream, AbstractProtocol *parent)
: AbstractProtocol(stream) : AbstractProtocol(stream, parent)
{ {
configForm = NULL; configForm = NULL;
} }
@ -60,9 +60,10 @@ Ip4Protocol::~Ip4Protocol()
delete configForm; delete configForm;
} }
AbstractProtocol* Ip4Protocol::createInstance(StreamBase *stream) AbstractProtocol* Ip4Protocol::createInstance(StreamBase *stream,
AbstractProtocol *parent)
{ {
return new Ip4Protocol(stream); return new Ip4Protocol(stream, parent);
} }
quint32 Ip4Protocol::protocolNumber() const quint32 Ip4Protocol::protocolNumber() const
@ -592,7 +593,7 @@ quint32 Ip4Protocol::protocolFrameCksum(int streamIndex,
// Above calculation done assuming 'big endian' // Above calculation done assuming 'big endian'
// - so convert to host order // - so convert to host order
//return qFromBigEndian(sum); //return qFromBigEndian(sum);
return sum; return ~sum;
} }
default: default:
break; break;

View File

@ -59,10 +59,11 @@ private:
}; };
public: public:
Ip4Protocol(StreamBase *stream); Ip4Protocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~Ip4Protocol(); virtual ~Ip4Protocol();
static AbstractProtocol* createInstance(StreamBase *stream); static AbstractProtocol* createInstance(StreamBase *stream,
AbstractProtocol *parent = 0);
virtual quint32 protocolNumber() const; virtual quint32 protocolNumber() const;
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const;

View File

@ -9,8 +9,8 @@ LlcConfigForm::LlcConfigForm(QWidget *parent)
setupUi(this); setupUi(this);
} }
LlcProtocol::LlcProtocol(StreamBase *stream) LlcProtocol::LlcProtocol(StreamBase *stream, AbstractProtocol *parent)
: AbstractProtocol(stream) : AbstractProtocol(stream, parent)
{ {
configForm = NULL; configForm = NULL;
} }
@ -20,9 +20,10 @@ LlcProtocol::~LlcProtocol()
delete configForm; delete configForm;
} }
AbstractProtocol* LlcProtocol::createInstance(StreamBase *stream) AbstractProtocol* LlcProtocol::createInstance(StreamBase *stream,
AbstractProtocol *parent)
{ {
return new LlcProtocol(stream); return new LlcProtocol(stream, parent);
} }
quint32 LlcProtocol::protocolNumber() const quint32 LlcProtocol::protocolNumber() const

View File

@ -31,10 +31,11 @@ private:
}; };
public: public:
LlcProtocol(StreamBase *stream); LlcProtocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~LlcProtocol(); virtual ~LlcProtocol();
static AbstractProtocol* createInstance(StreamBase *stream); static AbstractProtocol* createInstance(StreamBase *stream,
AbstractProtocol *parent = 0);
virtual quint32 protocolNumber() const; virtual quint32 protocolNumber() const;
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const;

View File

@ -49,8 +49,8 @@ void MacConfigForm::on_cmbSrcMacMode_currentIndexChanged(int index)
} }
MacProtocol::MacProtocol(StreamBase *stream) MacProtocol::MacProtocol(StreamBase *stream, AbstractProtocol *parent)
: AbstractProtocol(stream) : AbstractProtocol(stream, parent)
{ {
configForm = NULL; configForm = NULL;
} }
@ -60,9 +60,10 @@ MacProtocol::~MacProtocol()
delete configForm; delete configForm;
} }
AbstractProtocol* MacProtocol::createInstance(StreamBase *stream) AbstractProtocol* MacProtocol::createInstance(StreamBase *stream
, AbstractProtocol *parent)
{ {
return new MacProtocol(stream); return new MacProtocol(stream, parent);
} }
quint32 MacProtocol::protocolNumber() const quint32 MacProtocol::protocolNumber() const

View File

@ -40,10 +40,11 @@ private:
}; };
public: public:
MacProtocol(StreamBase *stream); MacProtocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~MacProtocol(); virtual ~MacProtocol();
static AbstractProtocol* createInstance(StreamBase *stream); static AbstractProtocol* createInstance(StreamBase *stream,
AbstractProtocol *parent = 0);
virtual quint32 protocolNumber() const; virtual quint32 protocolNumber() const;
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const;

View File

@ -22,7 +22,10 @@ PROTOS += \
dot3.proto \ dot3.proto \
llc.proto \ llc.proto \
snap.proto \ snap.proto \
dot2llc.proto \
dot2snap.proto \
vlan.proto \ vlan.proto \
vlanstack.proto \
ip4.proto \ ip4.proto \
tcp.proto \ tcp.proto \
udp.proto udp.proto
@ -39,7 +42,10 @@ HEADERS += \
dot3.h \ dot3.h \
llc.h \ llc.h \
snap.h \ snap.h \
dot2llc.h \
dot2snap.h \
vlan.h \ vlan.h \
vlanstack.h \
ip4.h \ ip4.h \
tcp.h \ tcp.h \
udp.h udp.h

View File

@ -30,8 +30,8 @@ void PayloadConfigForm::on_cmbPatternMode_currentIndexChanged(int index)
} }
} }
PayloadProtocol::PayloadProtocol(StreamBase *stream) PayloadProtocol::PayloadProtocol(StreamBase *stream, AbstractProtocol *parent)
: AbstractProtocol(stream) : AbstractProtocol(stream, parent)
{ {
configForm = NULL; configForm = NULL;
} }
@ -41,9 +41,10 @@ PayloadProtocol::~PayloadProtocol()
delete configForm; delete configForm;
} }
AbstractProtocol* PayloadProtocol::createInstance(StreamBase *stream) AbstractProtocol* PayloadProtocol::createInstance(StreamBase *stream,
AbstractProtocol *parent)
{ {
return new PayloadProtocol(stream); return new PayloadProtocol(stream, parent);
} }
quint32 PayloadProtocol::protocolNumber() const quint32 PayloadProtocol::protocolNumber() const

View File

@ -31,10 +31,11 @@ private:
}; };
public: public:
PayloadProtocol(StreamBase *stream); PayloadProtocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~PayloadProtocol(); virtual ~PayloadProtocol();
static AbstractProtocol* createInstance(StreamBase *stream); static AbstractProtocol* createInstance(StreamBase *stream,
AbstractProtocol *parent = 0);
virtual quint32 protocolNumber() const; virtual quint32 protocolNumber() const;
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const;

View File

@ -81,8 +81,12 @@ message Protocol {
kLlcFieldNumber = 123; kLlcFieldNumber = 123;
kSnapFieldNumber = 124; kSnapFieldNumber = 124;
kVlanStackFieldNumber = 125;
kVlanFieldNumber = 126; kVlanFieldNumber = 126;
kDot2LlcFieldNumber = 127;
kDot2SnapFieldNumber = 128;
kIp4FieldNumber = 130; kIp4FieldNumber = 130;
kArpFieldNumber = 131; kArpFieldNumber = 131;

View File

@ -1,5 +1,6 @@
#include "protocollistiterator.h" #include "protocollistiterator.h"
#include "protocollist.h" #include "protocollist.h"
#include "abstractprotocol.h"
ProtocolListIterator::ProtocolListIterator(ProtocolList &list) ProtocolListIterator::ProtocolListIterator(ProtocolList &list)
{ {
@ -31,8 +32,24 @@ bool ProtocolListIterator::hasPrevious() const
return _iter->hasPrevious(); return _iter->hasPrevious();
} }
void ProtocolListIterator::insert(const AbstractProtocol* value) void ProtocolListIterator::insert(AbstractProtocol* value)
{ {
if (_iter->hasPrevious())
{
value->prev = _iter->peekPrevious();
value->prev->next = value;
}
else
value->prev = NULL;
if (_iter->hasNext())
{
value->next = _iter->peekNext();
value->next->prev = value;
}
else
value->next = NULL;
_iter->insert((AbstractProtocol*)((uint)value)); _iter->insert((AbstractProtocol*)((uint)value));
} }
@ -58,11 +75,21 @@ AbstractProtocol* ProtocolListIterator::previous()
void ProtocolListIterator::remove() void ProtocolListIterator::remove()
{ {
if (_iter->value()->prev)
_iter->value()->prev->next = _iter->value()->next;
if (_iter->value()->next)
_iter->value()->next->prev = _iter->value()->prev;
_iter->remove(); _iter->remove();
} }
void ProtocolListIterator::setValue(const AbstractProtocol* value) const void ProtocolListIterator::setValue(AbstractProtocol* value) const
{ {
if (_iter->value()->prev)
_iter->value()->prev->next = value;
if (_iter->value()->next)
_iter->value()->next->prev = value;
value->prev = _iter->value()->prev;
value->next = _iter->value()->next;
_iter->setValue((AbstractProtocol*)((uint)value)); _iter->setValue((AbstractProtocol*)((uint)value));
} }

View File

@ -15,13 +15,13 @@ public:
bool findPrevious(const AbstractProtocol* value); bool findPrevious(const AbstractProtocol* value);
bool hasNext() const; bool hasNext() const;
bool hasPrevious() const; bool hasPrevious() const;
void insert(const AbstractProtocol* value); void insert(AbstractProtocol* value);
AbstractProtocol* next(); AbstractProtocol* next();
AbstractProtocol* peekNext() const; AbstractProtocol* peekNext() const;
AbstractProtocol* peekPrevious() const; AbstractProtocol* peekPrevious() const;
AbstractProtocol* previous(); AbstractProtocol* previous();
void remove(); void remove();
void setValue(const AbstractProtocol* value) const; void setValue(AbstractProtocol* value) const;
void toBack(); void toBack();
void toFront(); void toFront();
const AbstractProtocol* value() const; const AbstractProtocol* value() const;

View File

@ -11,7 +11,10 @@
#include "dot3.h" #include "dot3.h"
#include "llc.h" #include "llc.h"
#include "snap.h" #include "snap.h"
#include "dot2llc.h"
#include "dot2snap.h"
#include "vlan.h" #include "vlan.h"
#include "vlanstack.h"
#include "ip4.h" #include "ip4.h"
#include "tcp.h" #include "tcp.h"
#include "udp.h" #include "udp.h"
@ -20,16 +23,32 @@ ProtocolManager OstProtocolManager;
ProtocolManager::ProtocolManager() ProtocolManager::ProtocolManager()
{ {
registerProtocol(51, QString("mac"), (void*) MacProtocol::createInstance); registerProtocol(OstProto::Protocol::kMacFieldNumber,
registerProtocol(52, QString("payload"), (void*) PayloadProtocol::createInstance); QString("mac"), (void*) MacProtocol::createInstance);
registerProtocol(121, QString("eth2"), (void*) Eth2Protocol::createInstance); registerProtocol(OstProto::Protocol::kPayloadFieldNumber,
registerProtocol(122, QString("dot3"), (void*) Dot3Protocol::createInstance); QString("payload"), (void*) PayloadProtocol::createInstance);
registerProtocol(123, QString("llc"), (void*) LlcProtocol::createInstance); registerProtocol(OstProto::Protocol::kEth2FieldNumber,
registerProtocol(124, QString("snap"), (void*) SnapProtocol::createInstance); QString("eth2"), (void*) Eth2Protocol::createInstance);
registerProtocol(126, QString("vlan"), (void*) VlanProtocol::createInstance); registerProtocol(OstProto::Protocol::kDot3FieldNumber,
registerProtocol(130, QString("ip4"), (void*) Ip4Protocol::createInstance); QString("dot3"), (void*) Dot3Protocol::createInstance);
registerProtocol(140, QString("tcp"), (void*) TcpProtocol::createInstance); registerProtocol(OstProto::Protocol::kLlcFieldNumber,
registerProtocol(141, QString("udp"), (void*) UdpProtocol::createInstance); QString("llc"), (void*) LlcProtocol::createInstance);
registerProtocol(OstProto::Protocol::kSnapFieldNumber,
QString("snap"), (void*) SnapProtocol::createInstance);
registerProtocol(OstProto::Protocol::kDot2LlcFieldNumber,
QString("dot2Llc"), (void*) Dot2LlcProtocol::createInstance);
registerProtocol(OstProto::Protocol::kDot2SnapFieldNumber,
QString("dot2Snap"), (void*) Dot2SnapProtocol::createInstance);
registerProtocol(OstProto::Protocol::kVlanFieldNumber,
QString("vlan"), (void*) VlanProtocol::createInstance);
registerProtocol(OstProto::Protocol::kVlanStackFieldNumber,
QString("vlanstack"), (void*) VlanStackProtocol::createInstance);
registerProtocol(OstProto::Protocol::kIp4FieldNumber,
QString("ip4"), (void*) Ip4Protocol::createInstance);
registerProtocol(OstProto::Protocol::kTcpFieldNumber,
QString("tcp"), (void*) TcpProtocol::createInstance);
registerProtocol(OstProto::Protocol::kUdpFieldNumber,
QString("udp"), (void*) UdpProtocol::createInstance);
} }
void ProtocolManager::registerProtocol(int protoNumber, QString protoName, void ProtocolManager::registerProtocol(int protoNumber, QString protoName,
@ -42,25 +61,25 @@ void ProtocolManager::registerProtocol(int protoNumber, QString protoName,
} }
AbstractProtocol* ProtocolManager::createProtocol(int protoNumber, AbstractProtocol* ProtocolManager::createProtocol(int protoNumber,
StreamBase *stream) StreamBase *stream, AbstractProtocol *parent)
{ {
AbstractProtocol* (*pc)(StreamBase*); AbstractProtocol* (*pc)(StreamBase*, AbstractProtocol*);
AbstractProtocol* p; AbstractProtocol* p;
pc = (AbstractProtocol* (*)(StreamBase*)) pc = (AbstractProtocol* (*)(StreamBase*, AbstractProtocol*))
factory.value(protoNumber); factory.value(protoNumber);
Q_ASSERT(pc != NULL); Q_ASSERT(pc != NULL);
p = (*pc)(stream); p = (*pc)(stream, parent);
return p; return p;
} }
AbstractProtocol* ProtocolManager::createProtocol(QString protoName, AbstractProtocol* ProtocolManager::createProtocol(QString protoName,
StreamBase *stream) StreamBase *stream, AbstractProtocol *parent)
{ {
return createProtocol(nameToNumberMap.value(protoName), stream); return createProtocol(nameToNumberMap.value(protoName), stream, parent);
} }
QStringList ProtocolManager::protocolDatabase() QStringList ProtocolManager::protocolDatabase()

View File

@ -19,8 +19,10 @@ public:
void registerProtocol(int protoNumber, QString protoName, void registerProtocol(int protoNumber, QString protoName,
void *protoCreator); void *protoCreator);
AbstractProtocol* createProtocol(int protoNumber, StreamBase *stream); AbstractProtocol* createProtocol(int protoNumber, StreamBase *stream,
AbstractProtocol* createProtocol(QString protoName, StreamBase *stream); AbstractProtocol *parent = 0);
AbstractProtocol* createProtocol(QString protoName, StreamBase *stream,
AbstractProtocol *parent = 0);
QStringList protocolDatabase(); QStringList protocolDatabase();
}; };

View File

@ -9,8 +9,8 @@ SampleConfigForm::SampleConfigForm(QWidget *parent)
setupUi(this); setupUi(this);
} }
SampleProtocol::SampleProtocol(StreamBase *stream); SampleProtocol::SampleProtocol(StreamBase *stream, AbstractProtocol *parent);
: AbstractProtocol(stream) : AbstractProtocol(stream, parent)
{ {
configForm = NULL; configForm = NULL;
} }
@ -20,9 +20,10 @@ SampleProtocol::~SampleProtocol()
delete configForm; delete configForm;
} }
AbstractProtocol* SampleProtocol::createInstance(StreamBase *stream) AbstractProtocol* SampleProtocol::createInstance(StreamBase *stream,
AbstractProtocol *parent)
{ {
return new SampleProtocol(frameProtoList, streamCore); return new SampleProtocol(stream, parent);
} }
quint32 SampleProtocol::protocolNumber() const quint32 SampleProtocol::protocolNumber() const

View File

@ -26,10 +26,11 @@ private:
}; };
public: public:
SampleProtocol(StreamBase *stream); SampleProtocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~SampleProtocol(); virtual ~SampleProtocol();
static AbstractProtocol* createInstance(StreamBase *stream); static AbstractProtocol* createInstance(StreamBase *stream,
AbstractProtocol *parent = 0);
virtual quint32 protocolNumber() const; virtual quint32 protocolNumber() const;
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const;

View File

@ -9,8 +9,8 @@ SnapConfigForm::SnapConfigForm(QWidget *parent)
setupUi(this); setupUi(this);
} }
SnapProtocol::SnapProtocol(StreamBase *stream) SnapProtocol::SnapProtocol(StreamBase *stream, AbstractProtocol *parent)
: AbstractProtocol(stream) : AbstractProtocol(stream, parent)
{ {
configForm = NULL; configForm = NULL;
} }
@ -20,9 +20,10 @@ SnapProtocol::~SnapProtocol()
delete configForm; delete configForm;
} }
AbstractProtocol* SnapProtocol::createInstance(StreamBase *stream) AbstractProtocol* SnapProtocol::createInstance(StreamBase *stream,
AbstractProtocol *parent)
{ {
return new SnapProtocol(stream); return new SnapProtocol(stream, parent);
} }
quint32 SnapProtocol::protocolNumber() const quint32 SnapProtocol::protocolNumber() const

View File

@ -27,10 +27,11 @@ private:
}; };
public: public:
SnapProtocol(StreamBase *stream); SnapProtocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~SnapProtocol(); virtual ~SnapProtocol();
static AbstractProtocol* createInstance(StreamBase *stream); static AbstractProtocol* createInstance(StreamBase *stream,
AbstractProtocol *parent = 0);
virtual quint32 protocolNumber() const; virtual quint32 protocolNumber() const;
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const;

View File

@ -12,22 +12,23 @@ StreamBase::StreamBase() :
mControl(new OstProto::StreamControl) mControl(new OstProto::StreamControl)
{ {
AbstractProtocol *proto; AbstractProtocol *proto;
ProtocolListIterator *iter;
mStreamId->set_id(0xFFFFFFFF); mStreamId->set_id(0xFFFFFFFF);
currentFrameProtocols = new ProtocolList; currentFrameProtocols = new ProtocolList;
iter = createProtocolListIterator();
// By default newly created streams have the mac and payload protocols // By default newly created streams have the mac and payload protocols
proto = OstProtocolManager.createProtocol("mac", this); proto = OstProtocolManager.createProtocol("mac", this);
currentFrameProtocols->append(proto); iter->insert(proto);
qDebug("stream: mac = %p", proto); qDebug("stream: mac = %p", proto);
proto = OstProtocolManager.createProtocol("payload", this); proto = OstProtocolManager.createProtocol("payload", this);
currentFrameProtocols->append(proto); iter->insert(proto);
qDebug("stream: payload = %p", proto); qDebug("stream: payload = %p", proto);
{ {
ProtocolListIterator *iter = createProtocolListIterator();
iter->toFront(); iter->toFront();
while (iter->hasNext()) while (iter->hasNext())
{ {
@ -40,8 +41,9 @@ StreamBase::StreamBase() :
qDebug("{[%d]}", iter->next()->protocolNumber()); qDebug("{[%d]}", iter->next()->protocolNumber());
// qDebug("{{%p}: %d}", iter->peekNext(), iter->next()->protocolNumber()); // qDebug("{{%p}: %d}", iter->peekNext(), iter->next()->protocolNumber());
} }
delete iter;
} }
delete iter;
} }
StreamBase::~StreamBase() StreamBase::~StreamBase()
@ -53,20 +55,24 @@ StreamBase::~StreamBase()
void StreamBase::protoDataCopyFrom(const OstProto::Stream &stream) void StreamBase::protoDataCopyFrom(const OstProto::Stream &stream)
{ {
AbstractProtocol *proto; AbstractProtocol *proto;
ProtocolListIterator *iter;
mStreamId->CopyFrom(stream.stream_id()); mStreamId->CopyFrom(stream.stream_id());
mCore->CopyFrom(stream.core()); mCore->CopyFrom(stream.core());
mControl->CopyFrom(stream.control()); mControl->CopyFrom(stream.control());
currentFrameProtocols->destroy(); currentFrameProtocols->destroy();
iter = createProtocolListIterator();
for (int i=0; i < stream.protocol_size(); i++) for (int i=0; i < stream.protocol_size(); i++)
{ {
proto = OstProtocolManager.createProtocol( proto = OstProtocolManager.createProtocol(
stream.protocol(i).protocol_id().id(), this); stream.protocol(i).protocol_id().id(), this);
proto->protoDataCopyFrom(stream.protocol(i)); proto->protoDataCopyFrom(stream.protocol(i));
currentFrameProtocols->append(proto); iter->insert(proto);
} }
delete iter;
} }
void StreamBase::protoDataCopyInto(OstProto::Stream &stream) const void StreamBase::protoDataCopyInto(OstProto::Stream &stream) const

View File

@ -9,8 +9,8 @@ TcpConfigForm::TcpConfigForm(QWidget *parent)
setupUi(this); setupUi(this);
} }
TcpProtocol::TcpProtocol(StreamBase *stream) TcpProtocol::TcpProtocol(StreamBase *stream, AbstractProtocol *parent)
: AbstractProtocol(stream) : AbstractProtocol(stream, parent)
{ {
configForm = NULL; configForm = NULL;
} }
@ -20,9 +20,10 @@ TcpProtocol::~TcpProtocol()
delete configForm; delete configForm;
} }
AbstractProtocol* TcpProtocol::createInstance(StreamBase *stream) AbstractProtocol* TcpProtocol::createInstance(StreamBase *stream,
AbstractProtocol *parent)
{ {
return new TcpProtocol(stream); return new TcpProtocol(stream, parent);
} }
quint32 TcpProtocol::protocolNumber() const quint32 TcpProtocol::protocolNumber() const

View File

@ -45,10 +45,11 @@ private:
}; };
public: public:
TcpProtocol(StreamBase *stream); TcpProtocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~TcpProtocol(); virtual ~TcpProtocol();
static AbstractProtocol* createInstance(StreamBase *stream); static AbstractProtocol* createInstance(StreamBase *stream,
AbstractProtocol *parent = 0);
virtual quint32 protocolNumber() const; virtual quint32 protocolNumber() const;
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const;

View File

@ -9,8 +9,8 @@ UdpConfigForm::UdpConfigForm(QWidget *parent)
setupUi(this); setupUi(this);
} }
UdpProtocol::UdpProtocol(StreamBase *stream) UdpProtocol::UdpProtocol(StreamBase *stream, AbstractProtocol *parent)
: AbstractProtocol(stream) : AbstractProtocol(stream, parent)
{ {
configForm = NULL; configForm = NULL;
} }
@ -20,9 +20,10 @@ UdpProtocol::~UdpProtocol()
delete configForm; delete configForm;
} }
AbstractProtocol* UdpProtocol::createInstance(StreamBase *stream) AbstractProtocol* UdpProtocol::createInstance(StreamBase *stream,
AbstractProtocol *parent)
{ {
return new UdpProtocol(stream); return new UdpProtocol(stream, parent);
} }
quint32 UdpProtocol::protocolNumber() const quint32 UdpProtocol::protocolNumber() const

View File

@ -32,10 +32,11 @@ private:
}; };
public: public:
UdpProtocol(StreamBase *stream); UdpProtocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~UdpProtocol(); virtual ~UdpProtocol();
static AbstractProtocol* createInstance(StreamBase *stream); static AbstractProtocol* createInstance(StreamBase *stream,
AbstractProtocol *parent = 0);
virtual quint32 protocolNumber() const; virtual quint32 protocolNumber() const;
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const;

View File

@ -8,8 +8,8 @@ VlanConfigForm::VlanConfigForm(QWidget *parent)
setupUi(this); setupUi(this);
} }
VlanProtocol::VlanProtocol(StreamBase *stream) VlanProtocol::VlanProtocol(StreamBase *stream, AbstractProtocol *parent)
: AbstractProtocol(stream) : AbstractProtocol(stream, parent)
{ {
configForm = NULL; configForm = NULL;
} }
@ -19,9 +19,10 @@ VlanProtocol::~VlanProtocol()
delete configForm; delete configForm;
} }
AbstractProtocol* VlanProtocol::createInstance(StreamBase *stream) AbstractProtocol* VlanProtocol::createInstance(StreamBase *stream,
AbstractProtocol *parent)
{ {
return new VlanProtocol(stream); return new VlanProtocol(stream, parent);
} }
quint32 VlanProtocol::protocolNumber() const quint32 VlanProtocol::protocolNumber() const

View File

@ -32,10 +32,11 @@ private:
}; };
public: public:
VlanProtocol(StreamBase *stream); VlanProtocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~VlanProtocol(); virtual ~VlanProtocol();
static AbstractProtocol* createInstance(StreamBase *stream); static AbstractProtocol* createInstance(StreamBase *stream,
AbstractProtocol *parent = 0);
virtual quint32 protocolNumber() const; virtual quint32 protocolNumber() const;
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const;

10
common/vlanstack.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef _VLAN_STACK_H
#define _VLAN_STACK_H
#include "comboprotocol.h"
#include "vlan.h"
typedef ComboProtocol<OstProto::Protocol::kVlanStackFieldNumber,
VlanProtocol, VlanProtocol> VlanStackProtocol;
#endif

12
common/vlanstack.proto Normal file
View File

@ -0,0 +1,12 @@
import "protocol.proto";
package OstProto;
// Stacked VLAN (2 tags)
message VlanStack {
// Empty since this is a 'combo' protocol
}
extend Protocol {
optional VlanStack vlanStack = 125;
}

View File

@ -2,6 +2,7 @@
#include <qglobal.h> #include <qglobal.h>
#include <qendian.h> #include <qendian.h>
#include "qdebug.h" #include "qdebug.h"
#include <QProcess>
#include "myservice.h" #include "myservice.h"
#include "../common/protocollist.h" #include "../common/protocollist.h"
@ -86,7 +87,7 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n)
// ------------------ PortInfo -------------------- // ------------------ PortInfo --------------------
// //
PortInfo::PortInfo(uint id, pcap_if_t *dev) PortInfo::PortInfo(uint id, pcap_if_t *dev)
: monitorRx(this), monitorTx(this), transmitter(this) : monitorRx(this), monitorTx(this), transmitter(this), capturer(this)
{ {
char errbuf[PCAP_ERRBUF_SIZE]; char errbuf[PCAP_ERRBUF_SIZE];
@ -333,6 +334,21 @@ void PortInfo::stopTransmit()
transmitter.stop(); transmitter.stop();
} }
void PortInfo::startCapture()
{
capturer.start();
}
void PortInfo::stopCapture()
{
capturer.stop();
}
void PortInfo::viewCapture()
{
capturer.view();
}
void PortInfo::resetStats() void PortInfo::resetStats()
{ {
memcpy((void*) &epochStats, (void*) &stats, sizeof(stats)); memcpy((void*) &epochStats, (void*) &stats, sizeof(stats));
@ -714,6 +730,59 @@ void PortInfo::PortTransmitter::stop()
m_stop = 1; m_stop = 1;
} }
/*--------------- PortCapture ---------------*/
PortInfo::PortCapture::PortCapture(PortInfo *port)
{
this->port = port;
capHandle = NULL;
dumpHandle = NULL;
}
void PortInfo::PortCapture::run()
{
if (capHandle == NULL)
{
char errbuf[PCAP_ERRBUF_SIZE];
capHandle = pcap_open_live(port->dev->name, 0,
PCAP_OPENFLAG_PROMISCUOUS, 1000 /*ms*/, errbuf);
if (capHandle == NULL)
{
qDebug("Error opening port %s: %s\n",
port->dev->name, pcap_geterr(capHandle));
}
}
if (!capFile.isOpen())
{
if (!capFile.open())
qFatal("Unable to open temp cap file");
qDebug("cap file = %s", capFile.fileName().toAscii().constData());
}
dumpHandle = pcap_dump_open(capHandle,
capFile.fileName().toAscii().constData());
pcap_loop(capHandle, -1, pcap_dump, (uchar*) dumpHandle);
}
void PortInfo::PortCapture::stop()
{
pcap_breakloop(capHandle);
if (dumpHandle)
{
pcap_dump_flush(dumpHandle);
pcap_dump_close(dumpHandle);
dumpHandle = NULL;
}
}
void PortInfo::PortCapture::view()
{
// FIXME: hack - when correcting this remove the <QProcess> include also
QProcess::execute("C:/Program Files/Wireshark/wireshark.exe",
QStringList() << capFile.fileName());
}
/*--------------- MyService ---------------*/ /*--------------- MyService ---------------*/
@ -1067,7 +1136,18 @@ const ::OstProto::PortIdList* request,
::google::protobuf::Closure* done) ::google::protobuf::Closure* done)
{ {
qDebug("In %s", __PRETTY_FUNCTION__); qDebug("In %s", __PRETTY_FUNCTION__);
controller->SetFailed("Not Implemented");
for (int i=0; i < request->port_id_size(); i++)
{
uint portIdx;
portIdx = request->port_id(i).id();
if (portIdx >= numPorts)
continue; // TODO(LOW): partial RPC?
portInfo[portIdx]->startCapture();
}
done->Run(); done->Run();
} }
@ -1077,7 +1157,17 @@ const ::OstProto::PortIdList* request,
::google::protobuf::Closure* done) ::google::protobuf::Closure* done)
{ {
qDebug("In %s", __PRETTY_FUNCTION__); qDebug("In %s", __PRETTY_FUNCTION__);
controller->SetFailed("Not Implemented"); for (int i=0; i < request->port_id_size(); i++)
{
uint portIdx;
portIdx = request->port_id(i).id();
if (portIdx >= numPorts)
continue; // TODO(LOW): partial RPC?
portInfo[portIdx]->stopCapture();
}
done->Run(); done->Run();
} }
@ -1087,6 +1177,19 @@ const ::OstProto::PortIdList* request,
::google::protobuf::Closure* done) ::google::protobuf::Closure* done)
{ {
qDebug("In %s", __PRETTY_FUNCTION__); qDebug("In %s", __PRETTY_FUNCTION__);
// FIXME: BAD BAD VERY BAD !!!!!!
for (int i=0; i < request->port_id_size(); i++)
{
uint portIdx;
portIdx = request->port_id(i).id();
if (portIdx >= numPorts)
continue; // TODO(LOW): partial RPC?
portInfo[portIdx]->viewCapture();
}
controller->SetFailed("Not Implemented"); controller->SetFailed("Not Implemented");
done->Run(); done->Run();
} }

View File

@ -14,6 +14,7 @@
#include <QtGlobal> #include <QtGlobal>
#include <QList> #include <QList>
#include <QThread> #include <QThread>
#include <QTemporaryFile>
#include "../rpc/pbhelper.h" #include "../rpc/pbhelper.h"
#include "pcapextra.h" #include "pcapextra.h"
@ -92,6 +93,22 @@ class PortInfo
void run(); void run();
void stop(); void stop();
}; };
class PortCapture: public QThread
{
friend class PortInfo;
PortInfo *port;
pcap_t *capHandle;
pcap_dumper_t *dumpHandle;
QTemporaryFile capFile;
public:
PortCapture(PortInfo *port);
void run();
void stop();
void view();
};
OstProto::Port d; OstProto::Port d;
@ -136,6 +153,7 @@ class PortInfo
PortMonitorRx monitorRx; PortMonitorRx monitorRx;
PortMonitorTx monitorTx; PortMonitorTx monitorTx;
PortTransmitter transmitter; PortTransmitter transmitter;
PortCapture capturer;
struct PortStats epochStats; struct PortStats epochStats;
struct PortStats stats; struct PortStats stats;
@ -153,6 +171,9 @@ public:
void update(); void update();
void startTransmit(); void startTransmit();
void stopTransmit(); void stopTransmit();
void startCapture();
void stopCapture();
void viewCapture();
void resetStats(); void resetStats();
}; };