From 0094f618d34683dbb3844da646115c1584b6f52b Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Wed, 14 Oct 2009 15:16:56 +0000 Subject: [PATCH] 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) --- client/packetmodel.cpp | 5 +- client/portgroup.cpp | 108 +++++ client/portgroup.h | 7 + client/portstatswindow.cpp | 36 ++ client/streamconfigdialog.cpp | 711 +++++++++----------------------- client/streamconfigdialog.h | 34 +- client/streamconfigdialog.ui | 224 ++++++---- common/abstractprotocol.cpp | 101 ++--- common/abstractprotocol.h | 15 +- common/comboprotocol.h | 87 ++-- common/dot2llc.h | 11 + common/dot2llc.proto | 14 + common/dot2snap.h | 11 + common/dot2snap.proto | 12 + common/dot3.cpp | 20 +- common/dot3.h | 5 +- common/eth2.cpp | 9 +- common/eth2.h | 5 +- common/ip4.cpp | 11 +- common/ip4.h | 5 +- common/llc.cpp | 9 +- common/llc.h | 5 +- common/mac.cpp | 9 +- common/mac.h | 5 +- common/ostproto.pro | 6 + common/payload.cpp | 9 +- common/payload.h | 5 +- common/protocol.proto | 4 + common/protocollistiterator.cpp | 31 +- common/protocollistiterator.h | 4 +- common/protocolmanager.cpp | 51 ++- common/protocolmanager.h | 6 +- common/sample.cpp | 9 +- common/sample.h | 5 +- common/snap.cpp | 9 +- common/snap.h | 5 +- common/streambase.cpp | 18 +- common/tcp.cpp | 9 +- common/tcp.h | 5 +- common/udp.cpp | 9 +- common/udp.h | 5 +- common/vlan.cpp | 9 +- common/vlan.h | 5 +- common/vlanstack.h | 10 + common/vlanstack.proto | 12 + server/myservice.cpp | 109 ++++- server/myservice.h | 21 + 47 files changed, 1029 insertions(+), 786 deletions(-) create mode 100644 common/dot2llc.h create mode 100644 common/dot2llc.proto create mode 100644 common/dot2snap.h create mode 100644 common/dot2snap.proto create mode 100644 common/vlanstack.h create mode 100644 common/vlanstack.proto diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index 7d9df3d..908de63 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -46,7 +46,7 @@ int PacketModel::rowCount(const QModelIndex &parent) const 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__); return 0; // catch all } @@ -86,13 +86,14 @@ QModelIndex PacketModel::index(int row, int col, const QModelIndex &parent) cons goto _exit; case ITYP_FIELD: + Q_ASSERT(1 == 0); // Unreachable code goto _exit; default: qWarning("%s: Unhandled ItemType", __FUNCTION__); } - Q_ASSERT(1 == 1); // Unreachable code + Q_ASSERT(1 == 0); // Unreachable code _exit: return index; diff --git a/client/portgroup.cpp b/client/portgroup.cpp index f9f84d2..4614528 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -479,6 +479,93 @@ _exit: return; } +void PortGroup::startCapture(QList *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 *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 *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) { qDebug("In %s", __FUNCTION__); @@ -493,6 +580,27 @@ void PortGroup::processStopTxAck(OstProto::Ack *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() { OstProto::PortStatsList *portStatsList; diff --git a/client/portgroup.h b/client/portgroup.h index 2ffcbaf..c297674 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -75,6 +75,13 @@ public: void stopTx(QList *portList = NULL); void processStopTxAck(OstProto::Ack *ack); + void startCapture(QList *portList = NULL); + void processStartCaptureAck(OstProto::Ack *ack); + void stopCapture(QList *portList = NULL); + void processStopCaptureAck(OstProto::Ack *ack); + void viewCapture(QList *portList = NULL); + void processViewCaptureAck(OstProto::CaptureBufferList *bufList); + void getPortStats(); void processPortStatsList(OstProto::PortStatsList *portStatsList); void clearPortStats(QList *portList = NULL); diff --git a/client/portstatswindow.cpp b/client/portstatswindow.cpp index d1340a6..26e2b10 100644 --- a/client/portstatswindow.cpp +++ b/client/portstatswindow.cpp @@ -61,16 +61,52 @@ void PortStatsWindow::on_tbStopTransmit_clicked() void PortStatsWindow::on_tbStartCapture_clicked() { // TODO(MED) + QList 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() { // TODO(MED) + QList 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() { // TODO(MED) + QList 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() diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index 9bdae53..30649b3 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -27,18 +27,13 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, setupUi(this); setupUiExtra(); - connect(bgL1Proto, SIGNAL(buttonClicked(int)), - this, SLOT(updateL1Protocol(int))); - connect(bgL2Proto, SIGNAL(buttonClicked(int)), - this, SLOT(updateFrameTypeProtocol(int))); - connect(bgVlan, SIGNAL(buttonClicked(int)), - this, SLOT(updateVlanProtocol(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))); + for (int i = ProtoMin; i < ProtoMax; i++) + { + bgProto[i]->setProperty("ProtocolLevel", i); + bgProto[i]->setProperty("ProtocolId", ButtonIdNone); + connect(bgProto[i], SIGNAL(buttonClicked(int)), + this, SLOT(updateProtocol(int))); + } //! \todo causes a crash! #if 0 @@ -48,35 +43,16 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, // Time to play match the signals and slots! - // Enable VLAN Choices only if FT = Eth2 or SNAP -#if 0 - connect(rbFtNone, SIGNAL(toggled(bool)), gbVlan, SLOT(setDisabled(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))); + // If L1/FT = None, force subsequent protocol level(s) also to None + connect(rbL1None, SIGNAL(toggled(bool)), this, SLOT(forceProtocolNone(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), this, SLOT(forceProtocolNone(bool))); // 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)), rbL3Arp, SLOT(setEnabled(bool))); // Force L3 = None if FT = 802.3 Raw 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)), rbL3Arp, SLOT(setDisabled(bool))); @@ -84,12 +60,10 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, connect(rbFt802Dot3Llc, SIGNAL(clicked(bool)), rbL3None, SLOT(click())); // 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)), rbL3Arp, SLOT(setDisabled(bool))); // 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)), 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)), gbL3Proto, SLOT(setDisabled(bool))); - // Enable/Disable L4 Protocol Choices for L3 Protocol None - connect(rbL3None, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(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())); + // If L3 = None, force subsequent protocol level also to None + connect(rbL3None, SIGNAL(toggled(bool)), this, SLOT(forceProtocolNone(bool))); // 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)), rbL4Igmp, SLOT(setEnabled(bool))); connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setEnabled(bool))); connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setEnabled(bool))); // 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)), rbL4Igmp, 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}"); // ---- Setup default stuff that cannot be done in designer ---- -#if 0 - gbVlan->setDisabled(true); -#endif + bgProto[ProtoL1] = new QButtonGroup(); + bgProto[ProtoL1]->addButton(rbL1None, ButtonIdNone); + bgProto[ProtoL1]->addButton(rbL1Mac, OstProto::Protocol::kMacFieldNumber); + bgProto[ProtoL1]->addButton(rbL1Other, ButtonIdOther); - bgL1Proto = new QButtonGroup(); - bgL1Proto->addButton(rbL1None, ButtonIdNone); - bgL1Proto->addButton(rbL1Mac, OstProto::Protocol::kMacFieldNumber); - bgL1Proto->addButton(rbL1Other, ButtonIdOther); - - bgL2Proto = new QButtonGroup(); + bgProto[ProtoL2] = new QButtonGroup(); #if 0 foreach(QRadioButton *btn, gbFrameType->findChildren()) bgL2Proto->addButton(btn); #else - bgL2Proto->addButton(rbFtNone, ButtonIdNone); - bgL2Proto->addButton(rbFtEthernet2, OstProto::Protocol::kEth2FieldNumber); - bgL2Proto->addButton(rbFt802Dot3Raw, OstProto::Protocol::kDot3FieldNumber); - bgL2Proto->addButton(rbFt802Dot3Llc, OstProto::Protocol::kDot2LlcFieldNumber); - bgL2Proto->addButton(rbFtLlcSnap, OstProto::Protocol::kDot2SnapFieldNumber); - bgL2Proto->addButton(rbFtOther, ButtonIdOther); + bgProto[ProtoL2]->addButton(rbFtNone, ButtonIdNone); + bgProto[ProtoL2]->addButton(rbFtEthernet2, OstProto::Protocol::kEth2FieldNumber); + bgProto[ProtoL2]->addButton(rbFt802Dot3Raw, OstProto::Protocol::kDot3FieldNumber); + bgProto[ProtoL2]->addButton(rbFt802Dot3Llc, OstProto::Protocol::kDot2LlcFieldNumber); + bgProto[ProtoL2]->addButton(rbFtLlcSnap, OstProto::Protocol::kDot2SnapFieldNumber); + bgProto[ProtoL2]->addButton(rbFtOther, ButtonIdOther); #endif - bgVlan = new QButtonGroup(); - bgVlan->addButton(rbVlanNone, ButtonIdNone); - bgVlan->addButton(rbVlanSingle, OstProto::Protocol::kVlanFieldNumber); - bgVlan->addButton(rbVlanDouble, OstProto::Protocol::kVlanStackFieldNumber); + bgProto[ProtoVlan] = new QButtonGroup(); + bgProto[ProtoVlan]->addButton(rbVlanNone, ButtonIdNone); + bgProto[ProtoVlan]->addButton(rbVlanSingle, OstProto::Protocol::kVlanFieldNumber); + bgProto[ProtoVlan]->addButton(rbVlanDouble, OstProto::Protocol::kVlanStackFieldNumber); - bgL3Proto = new QButtonGroup(); + bgProto[ProtoL3] = new QButtonGroup(); #if 0 foreach(QRadioButton *btn, gbL3Proto->findChildren()) - bgL3Proto->addButton(btn); + bgProto[ProtoL3]->addButton(btn); #else - bgL3Proto->addButton(rbL3None, ButtonIdNone); - bgL3Proto->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber); - bgL3Proto->addButton(rbL3Ipv6, 0xFFFF); - bgL3Proto->addButton(rbL3Arp, 0xFFFF); - bgL3Proto->addButton(rbL3Other, ButtonIdOther); + bgProto[ProtoL3]->addButton(rbL3None, ButtonIdNone); + bgProto[ProtoL3]->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber); + bgProto[ProtoL3]->addButton(rbL3Ipv6, 0xFFFF); + bgProto[ProtoL3]->addButton(rbL3Arp, 0xFFFF); + bgProto[ProtoL3]->addButton(rbL3Other, ButtonIdOther); #endif - bgL4Proto = new QButtonGroup(); + bgProto[ProtoL4] = new QButtonGroup(); #if 0 foreach(QRadioButton *btn, gbL4Proto->findChildren()) - bgL4Proto->addButton(btn); + bgProto[ProtoL4]->addButton(btn); #else - bgL4Proto->addButton(rbL4None, 0); - bgL4Proto->addButton(rbL4Tcp, OstProto::Protocol::kTcpFieldNumber); - bgL4Proto->addButton(rbL4Udp, OstProto::Protocol::kUdpFieldNumber); - bgL4Proto->addButton(rbL4Icmp, 0xFFFF); - bgL4Proto->addButton(rbL4Igmp, 0xFFFF); - bgL4Proto->addButton(rbL4Other, ButtonIdOther); + bgProto[ProtoL4]->addButton(rbL4None, 0); + bgProto[ProtoL4]->addButton(rbL4Tcp, OstProto::Protocol::kTcpFieldNumber); + bgProto[ProtoL4]->addButton(rbL4Udp, OstProto::Protocol::kUdpFieldNumber); + bgProto[ProtoL4]->addButton(rbL4Icmp, 0xFFFF); + bgProto[ProtoL4]->addButton(rbL4Igmp, 0xFFFF); + bgProto[ProtoL4]->addButton(rbL4Other, ButtonIdOther); #endif - bgPayloadProto = new QButtonGroup(); + bgProto[ProtoPayload] = new QButtonGroup(); #if 0 foreach(QRadioButton *btn, gbPayloadProto->findChildren()) - bgPayloadProto->addButton(btn); + bgProto[ProtoPayload]->addButton(btn); #else - bgPayloadProto->addButton(rbPayloadNone, ButtonIdNone); - bgPayloadProto->addButton(rbPayloadPattern, OstProto::Protocol::kPayloadFieldNumber); - bgPayloadProto->addButton(rbPayloadOther, ButtonIdOther); + bgProto[ProtoPayload]->addButton(rbPayloadNone, ButtonIdNone); + bgProto[ProtoPayload]->addButton(rbPayloadPattern, OstProto::Protocol::kPayloadFieldNumber); + bgProto[ProtoPayload]->addButton(rbPayloadOther, ButtonIdOther); #endif /* ** Setup Validators @@ -270,12 +231,8 @@ StreamConfigDialog::~StreamConfigDialog() delete mpPacketModelTester; delete mpPacketModel; - delete bgL1Proto; - delete bgL2Proto; - delete bgVlan; - delete bgL3Proto; - delete bgL4Proto; - delete bgPayloadProto; + for (int i = ProtoMin; i < ProtoMax; i++) + delete bgProto[i]; delete _iter; delete mpStream; @@ -594,149 +551,122 @@ void StreamConfigDialog::on_lePattern_editingFinished() /*! 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) { - int id; - QAbstractButton *btn; - _iter->toFront(); - // Skip L1 - if (_iter->hasNext()) + for (int i = ProtoMin; i <= layer; i++) { - id = _iter->next()->protocolNumber(); - btn = bgL1Proto->button(id); - if (btn == NULL) - _iter->previous(); + if(_iter->hasNext()) + { + int id; + 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; } -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:old id = %d new id = %d upd? = %d", __FUNCTION__, oldId, newId, - isUpdateInProgress); - - if (oldId == newId) - return; // Nothing to be done - - if (!isUpdateInProgress) + qDebug("%s: btnGrp = %p, chk? = %d", __FUNCTION__, protocolGroup, checked); + foreach(QAbstractButton *btn, protocolGroup->buttons()) { - AbstractProtocol *p; + int id = protocolGroup->id(btn); - _iter->toFront(); - - 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; - } + if ((id != ButtonIdNone) && (id != ButtonIdOther)) + btn->setDisabled(checked); } - - 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, - isUpdateInProgress); + btn = sender(); + Q_ASSERT(btn != NULL); - if (oldId == newId) - return; // Nothing to be done + qDebug("%s: chk? = %d, btn = %p, L1 = %p, L2 = %p, L3 = %p", __FUNCTION__, + 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(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) { int ret; AbstractProtocol *p; - ret = skipProtocols(0); - + ret = skipProtocols(level-1); Q_ASSERT(ret == true); - Q_ASSERT(oldId != ButtonIdOther); + + Q_ASSERT(oldId != newId); Q_ASSERT(newId != ButtonIdOther); switch (oldId) @@ -757,347 +687,96 @@ void StreamConfigDialog::updateVlanProtocol(int newId) else _iter->remove(); delete p; - break; - } - } - - 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()) + if (level == ProtoPayload) { - - p = _iter->next(); - _iter->remove(); - delete p; + while (_iter->hasNext()) + { + p = _iter->next(); + _iter->remove(); + delete p; + } } break; } } - oldId = newId; + btnGrp->setProperty("ProtocolId", newId); return; } void StreamConfigDialog::updateSelectProtocolsSimpleWidget() { - quint32 id; + int i; + quint32 id; QAbstractButton *btn; qDebug("%s", __FUNCTION__); isUpdateInProgress = true; - // Reset to default state - rbL1None->setChecked(true); - rbVlanNone->setChecked(true); - rbFtNone->setChecked(true); - rbL3None->setChecked(true); - rbL4None->setChecked(true); - rbPayloadNone->setChecked(true); + // Reset to default state ... + for (i = ProtoMin; i < ProtoMax; i++) + bgProto[i]->button(ButtonIdNone)->click(); + // ... now iterate and update _iter->toFront(); - // L1 (optional if followed by Payload) - if (!_iter->hasNext()) // No protocols at all? - goto _done; - - id = _iter->next()->protocolNumber(); - btn = bgL1Proto->button(id); - - if (btn && btn->isEnabled()) - btn->click(); - else + for (i = ProtoMin; i < ProtoMax; i++) { - btn = bgPayloadProto->button(id); + if (!_iter->hasNext()) + goto _done; + + id = _iter->next()->protocolNumber(); + btn = bgProto[i]->button(id); + if (btn && btn->isEnabled()) - goto _payload; + btn->click(); 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 (_iter->hasNext()) - goto _otherPayload; + { + i = ProtoPayload; + goto _other; + } goto _done; -_otherL1: - bgL1Proto->button(ButtonIdOther)->setChecked(true); - updateL1Protocol(ButtonIdOther); -_otherL2: - bgL2Proto->button(ButtonIdOther)->setChecked(true); - updateFrameTypeProtocol(ButtonIdOther); -_otherL3: - bgL3Proto->button(ButtonIdOther)->setChecked(true); - updateL3Protocol(ButtonIdOther); -_otherL4: - bgL4Proto->button(ButtonIdOther)->setChecked(true); - updateL4Protocol(ButtonIdOther); -_otherPayload: - bgPayloadProto->button(ButtonIdOther)->setChecked(true); - updatePayloadProtocol(ButtonIdOther); +_other: + for (int j = i; j < ProtoMax; j++) + { + // VLAN doesn't have a "Other" button + if (j == ProtoVlan) + continue; + + bgProto[j]->button(ButtonIdOther)->setChecked(true); + __updateProtocol(j, ButtonIdOther); + } _done: isUpdateInProgress = false; - - return; } void StreamConfigDialog::LoadCurrentStream() diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index 4b774f7..5909e8e 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -28,11 +28,25 @@ public: private: - QButtonGroup *bgFrameType; - QButtonGroup *bgVlan; - QButtonGroup *bgL3Proto; - QButtonGroup *bgL4Proto; - QButtonGroup *bgPayloadProto; + enum ButtonId + { + ButtonIdNone = 0, + ButtonIdOther = -2 + }; + + enum ProtoButtonGroup + { + ProtoMin, + ProtoL1 = 0, + ProtoVlan = 1, + ProtoL2 = 2, + ProtoL3 = 3, + ProtoL4 = 4, + ProtoPayload = 5, + ProtoMax + }; + + QButtonGroup *bgProto[ProtoMax]; QStringListModel *mpAvailableProtocolsModel; QStringListModel *mpSelectedProtocolsModel; @@ -68,11 +82,11 @@ private slots: // "Simple" Protocol Selection related bool skipProtocols(int layer); - void updateFrameTypeProtocol(int id); - void updateVlanProtocol(int id); - void updateL3Protocol(int id); - void updateL4Protocol(int id); - void updatePayloadProtocol(int id); + void disableProtocols(QButtonGroup *protocolGroup, bool checked); + void forceProtocolNone(bool checked); + + void updateProtocol(int newId); + void __updateProtocol(int level, int newId); void updateSelectProtocolsSimpleWidget(); diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index 6e15d3b..07457e6 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -8,8 +8,8 @@ 0 0 - 524 - 458 + 569 + 464 @@ -173,7 +173,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff 0 0 - 465 + 527 226 @@ -181,16 +181,58 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff Simple - - + + - Frame Type + L1 + + + + + + None + + + true + + + + + + + Mac + + + false + + + + + + + false + + + Other + + + + + + + + + + true + + + L2 - None (Mac Only) + None true @@ -244,50 +286,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - + + true - - VLAN - - - false - - - false - - - - - - None - - - true - - - - - - - Single Tag - - - - - - - Double Tag - - - - - - - - L3 @@ -348,8 +351,95 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + + + + true + + + Payload + + + + + + None + + + true + + + + + + + Pattern + + + false + + + + + + + false + + + Other + + + + + + + + + + true + + + VLAN + + + false + + + false + + + + + + Untagged + + + true + + + + + + + Tagged + + + + + + + Stacked + + + + + + + + + true + L4 @@ -417,44 +507,15 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - - - - Payload - - - - - - Pattern - - - true - - - - - - - false - - - Other - - - - - - - + Qt::Vertical - 107 - 24 + 20 + 21 @@ -1084,7 +1145,6 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff lePktLen lePktLenMin lePktLenMax - rbFtNone rbFtEthernet2 rbFt802Dot3Raw rbFt802Dot3Llc diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index 2bac712..24355f2 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -22,9 +22,12 @@ - metaFieldCount() - isMetaField() */ -AbstractProtocol::AbstractProtocol(StreamBase *stream) +AbstractProtocol::AbstractProtocol(StreamBase *stream, AbstractProtocol *parent) { + //qDebug("%s: &prev = %p &next = %p", __FUNCTION__, &prev, &next); mpStream = stream; + this->parent = parent; + prev = next = NULL; metaCount = -1; protoSize = -1; } @@ -33,7 +36,8 @@ AbstractProtocol::~AbstractProtocol() { } -AbstractProtocol* AbstractProtocol::createInstance(StreamBase *stream) +AbstractProtocol* AbstractProtocol::createInstance(StreamBase *stream, + AbstractProtocol *parent) { return NULL; } @@ -139,6 +143,7 @@ AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int index) const FieldFrameValue, the subclass should handle and return a value for FieldBitSize to prevent endless recrusion - - protocolFrameCksum() + - protocolFramePayloadSize() */ QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const @@ -184,17 +189,16 @@ quint32 AbstractProtocol::protocolId(ProtocolIdType type) const quint32 AbstractProtocol::payloadProtocolId(ProtocolIdType type) const { - quint32 id = 0xFFFFFFFF; - ProtocolListIterator *iter = mpStream->createProtocolListIterator(); + quint32 id; - if (iter->findNext(this)) - { - if (iter->hasNext()) - id = iter->next()->protocolId(type); - } - delete iter; + if (next) + id = next->protocolId(type); + else if (parent) + id = parent->payloadProtocolId(type); + else + id = 0xFFFFFFFF; - qDebug("%s: payloadProtocolId = %u", __FUNCTION__, id); + qDebug("%s: payloadProtocolId = 0x%x", __FUNCTION__, id); return id; } @@ -219,17 +223,15 @@ int AbstractProtocol::protocolFrameSize() const int AbstractProtocol::protocolFrameOffset() const { int size = 0; - ProtocolListIterator *iter = mpStream->createProtocolListIterator(); - - if (iter->findNext(this)) + AbstractProtocol *p = prev; + while (p) { - iter->previous(); - while (iter->hasPrevious()) - size += iter->previous()->protocolFrameSize(); + size += p->protocolFrameSize(); + p = p->prev; } - else - return -1; - delete iter; + + if (parent) + size += parent->protocolFrameOffset(); qDebug("%s: ofs = %d", __FUNCTION__, size); return size; @@ -238,17 +240,14 @@ int AbstractProtocol::protocolFrameOffset() const int AbstractProtocol::protocolFramePayloadSize() const { int size = 0; - - ProtocolListIterator *iter = mpStream->createProtocolListIterator(); - - if (iter->findNext(this)) + AbstractProtocol *p = next; + while (p) { - while (iter->hasNext()) - size += iter->next()->protocolFrameSize(); + size += p->protocolFrameSize(); + p = p->next; } - else - return -1; - delete iter; + if (parent) + size += parent->protocolFramePayloadSize(); qDebug("%s: payloadSize = %d", __FUNCTION__, size); return size; @@ -361,7 +360,7 @@ quint32 AbstractProtocol::protocolFrameCksum(int streamIndex, CksumType cksumType) const { static int recursionCount = 0; - quint32 cksum = 0; + quint32 cksum = 0xFFFFFFFF; recursionCount++; 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, CksumType cksumType) const { - quint32 sum = 0xFFFF; - ProtocolListIterator *iter = mpStream->createProtocolListIterator(); + quint32 sum = 0; + quint16 cksum; + AbstractProtocol *p = prev; Q_ASSERT(cksumType == CksumIpPseudo); - if (iter->findNext(this)) + while (p) { - iter->previous(); - if (iter->hasPrevious()) - sum = iter->previous()->protocolFrameCksum(streamIndex, - CksumIpPseudo); + cksum = p->protocolFrameCksum(streamIndex, cksumType); + sum += (quint16) ~cksum; + p = p->prev; + qDebug("%s: sum = %u, cksum = %u", __FUNCTION__, sum, cksum); + } + if (parent) + { + cksum = parent->protocolFrameHeaderCksum(streamIndex, cksumType); + sum += (quint16) ~cksum; } - delete iter; while(sum>>16) sum = (sum & 0xFFFF) + (sum >> 16); @@ -451,21 +455,22 @@ quint32 AbstractProtocol::protocolFramePayloadCksum(int streamIndex, { quint32 sum = 0; quint16 cksum; - ProtocolListIterator *iter = mpStream->createProtocolListIterator(); + AbstractProtocol *p = next; Q_ASSERT(cksumType == CksumIp); - if (iter->findNext(this)) + while (p) { - while (iter->hasNext()) - { - cksum = iter->next()->protocolFrameCksum(streamIndex, CksumIp); - sum += (quint16) ~cksum; - } + cksum = p->protocolFrameCksum(streamIndex, cksumType); + sum += (quint16) ~cksum; + p = p->next; + } + + if (parent) + { + cksum = parent->protocolFramePayloadCksum(streamIndex, cksumType); + sum += (quint16) ~cksum; } - else - return 0; - delete iter; while(sum>>16) sum = (sum & 0xFFFF) + (sum >> 16); diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index aca2d2d..13db703 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -20,16 +20,24 @@ QString("%1").arg(num, bytes*2, BASE_HEX, QChar('0')) class StreamBase; +class ProtocolListIterator; class AbstractProtocol { + template + friend class ComboProtocol; + friend class ProtocolListIterator; + private: mutable int metaCount; mutable int protoSize; mutable QString protoAbbr; protected: - StreamBase *mpStream; + StreamBase *mpStream; + AbstractProtocol *parent; + AbstractProtocol *prev; + AbstractProtocol *next; public: enum FieldFlag { @@ -61,10 +69,11 @@ public: CksumMax }; - AbstractProtocol(StreamBase *stream); + AbstractProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~AbstractProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const = 0; diff --git a/common/comboprotocol.h b/common/comboprotocol.h index 62828cb..34cba86 100644 --- a/common/comboprotocol.h +++ b/common/comboprotocol.h @@ -3,7 +3,7 @@ #include "abstractprotocol.h" -template +template class ComboProtocol : public AbstractProtocol { private: @@ -12,36 +12,67 @@ private: QWidget *configForm; public: - ComboProtocol(StreamBase *stream) + ComboProtocol(StreamBase *stream, AbstractProtocol *parent = 0) + : AbstractProtocol(stream, parent) { - protoA = new ProtoA(stream); - protoB = new ProtoB(stream); + protoA = new ProtoA(stream, this); + protoB = new ProtoB(stream, this); + protoA->next = protoB; + protoB->prev = protoA; configForm = NULL; - } - virtual ~ComboProtocol() - { - delete protoA; - delete protoB; - delete configForm; + + qDebug("%s: protoNumber = %d, %p <--> %p", __FUNCTION__, + protoNumber, protoA, protoB); } - static ComboProtocol* createInstance(StreamBase *stream) + virtual ~ComboProtocol() { - return new ComboProtocol(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(stream, parent); } virtual quint32 protocolNumber() const { - return 0; //FIXME + return protoNumber; } 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) { - // 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 @@ -68,26 +99,32 @@ public: virtual FieldFlags fieldFlags(int index) const { - if (index < protoA->fieldCount()) + int cnt = protoA->fieldCount(); + + if (index < cnt) return protoA->fieldFlags(index); else - return protoB->fieldFlags(index); + return protoB->fieldFlags(index - cnt); } virtual QVariant fieldData(int index, FieldAttrib attrib, int streamIndex = 0) const { - if (index < protoA->fieldCount()) - return protoA->fieldData(index); + int cnt = protoA->fieldCount(); + + if (index < cnt) + return protoA->fieldData(index, attrib, streamIndex); else - return protoB->fieldData(index); + return protoB->fieldData(index - cnt, attrib, streamIndex); } virtual bool setFieldData(int index, const QVariant &value, FieldAttrib attrib = FieldValue) { - if (index < protoA->fieldCount()) - return protoA->fieldData(index); + int cnt = protoA->fieldCount(); + + if (index < cnt) + return protoA->setFieldData(index, value, attrib); else - return protoB->fieldData(index); + return protoB->setFieldData(index - cnt, value, attrib); } #if 0 @@ -109,11 +146,13 @@ public: { if (configForm == NULL) { - QVBoxLayout *layout = new VBoxLayout; + QVBoxLayout *layout = new QVBoxLayout; configForm = new QWidget; layout->addWidget(protoA->configWidget()); layout->addWidget(protoB->configWidget()); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); configForm->setLayout(layout); } return configForm; diff --git a/common/dot2llc.h b/common/dot2llc.h new file mode 100644 index 0000000..1553549 --- /dev/null +++ b/common/dot2llc.h @@ -0,0 +1,11 @@ +#ifndef _DOT2_LLC_H +#define _DOT2_LLC_H + +#include "comboprotocol.h" +#include "dot3.h" +#include "llc.h" + +typedef ComboProtocol Dot2LlcProtocol; + +#endif diff --git a/common/dot2llc.proto b/common/dot2llc.proto new file mode 100644 index 0000000..3aa1ca4 --- /dev/null +++ b/common/dot2llc.proto @@ -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; +} diff --git a/common/dot2snap.h b/common/dot2snap.h new file mode 100644 index 0000000..3eee505 --- /dev/null +++ b/common/dot2snap.h @@ -0,0 +1,11 @@ +#ifndef _DOT2_SNAP_H +#define _DOT2_SNAP_H + +#include "comboprotocol.h" +#include "dot2llc.h" +#include "snap.h" + +typedef ComboProtocol Dot2SnapProtocol; + +#endif diff --git a/common/dot2snap.proto b/common/dot2snap.proto new file mode 100644 index 0000000..b9a03f5 --- /dev/null +++ b/common/dot2snap.proto @@ -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; +} diff --git a/common/dot3.cpp b/common/dot3.cpp index f020b6e..cae0012 100644 --- a/common/dot3.cpp +++ b/common/dot3.cpp @@ -12,8 +12,8 @@ Dot3ConfigForm::Dot3ConfigForm(QWidget *parent) setupUi(this); } -Dot3Protocol::Dot3Protocol(StreamBase *stream) - : AbstractProtocol(stream) +Dot3Protocol::Dot3Protocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -23,9 +23,10 @@ Dot3Protocol::~Dot3Protocol() 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 @@ -75,14 +76,16 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, { quint16 len; - len = mpStream->frameLen() - SZ_FCS; + //len = mpStream->frameLen() - SZ_FCS; + len = protocolFramePayloadSize(); return len; } case FieldTextValue: { quint16 len; - len = mpStream->frameLen() - SZ_FCS; + //len = mpStream->frameLen() - SZ_FCS; + len = protocolFramePayloadSize(); return QString("%1").arg(len); } case FieldFrameValue: @@ -90,11 +93,14 @@ QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib, quint16 len; QByteArray fv; - len = mpStream->frameLen() - SZ_FCS; + //len = mpStream->frameLen() - SZ_FCS; + len = protocolFramePayloadSize(); fv.resize(2); qToBigEndian(len, (uchar*) fv.data()); return fv; } + case FieldBitSize: + return 16; default: break; } diff --git a/common/dot3.h b/common/dot3.h index 268e61d..def1031 100644 --- a/common/dot3.h +++ b/common/dot3.h @@ -26,10 +26,11 @@ private: }; public: - Dot3Protocol(StreamBase *stream); + Dot3Protocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~Dot3Protocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/eth2.cpp b/common/eth2.cpp index d1c4b9c..7a6f7b5 100644 --- a/common/eth2.cpp +++ b/common/eth2.cpp @@ -9,8 +9,8 @@ Eth2ConfigForm::Eth2ConfigForm(QWidget *parent) setupUi(this); } -Eth2Protocol::Eth2Protocol(StreamBase *stream) - : AbstractProtocol(stream) +Eth2Protocol::Eth2Protocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -20,9 +20,10 @@ Eth2Protocol::~Eth2Protocol() 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 diff --git a/common/eth2.h b/common/eth2.h index a99efbf..0555d65 100644 --- a/common/eth2.h +++ b/common/eth2.h @@ -26,10 +26,11 @@ private: }; public: - Eth2Protocol(StreamBase *stream); + Eth2Protocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~Eth2Protocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/ip4.cpp b/common/ip4.cpp index 296f09b..4fd594b 100644 --- a/common/ip4.cpp +++ b/common/ip4.cpp @@ -49,8 +49,8 @@ void Ip4ConfigForm::on_cmbIpDstAddrMode_currentIndexChanged(int index) } } -Ip4Protocol::Ip4Protocol(StreamBase *stream) - : AbstractProtocol(stream) +Ip4Protocol::Ip4Protocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -60,9 +60,10 @@ Ip4Protocol::~Ip4Protocol() 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 @@ -592,7 +593,7 @@ quint32 Ip4Protocol::protocolFrameCksum(int streamIndex, // Above calculation done assuming 'big endian' // - so convert to host order //return qFromBigEndian(sum); - return sum; + return ~sum; } default: break; diff --git a/common/ip4.h b/common/ip4.h index a539e71..e378755 100644 --- a/common/ip4.h +++ b/common/ip4.h @@ -59,10 +59,11 @@ private: }; public: - Ip4Protocol(StreamBase *stream); + Ip4Protocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~Ip4Protocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/llc.cpp b/common/llc.cpp index 8fe57af..b352cab 100644 --- a/common/llc.cpp +++ b/common/llc.cpp @@ -9,8 +9,8 @@ LlcConfigForm::LlcConfigForm(QWidget *parent) setupUi(this); } -LlcProtocol::LlcProtocol(StreamBase *stream) - : AbstractProtocol(stream) +LlcProtocol::LlcProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -20,9 +20,10 @@ LlcProtocol::~LlcProtocol() 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 diff --git a/common/llc.h b/common/llc.h index 9fe5d28..3555e92 100644 --- a/common/llc.h +++ b/common/llc.h @@ -31,10 +31,11 @@ private: }; public: - LlcProtocol(StreamBase *stream); + LlcProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~LlcProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/mac.cpp b/common/mac.cpp index 7f87a5b..ae80905 100644 --- a/common/mac.cpp +++ b/common/mac.cpp @@ -49,8 +49,8 @@ void MacConfigForm::on_cmbSrcMacMode_currentIndexChanged(int index) } -MacProtocol::MacProtocol(StreamBase *stream) - : AbstractProtocol(stream) +MacProtocol::MacProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -60,9 +60,10 @@ MacProtocol::~MacProtocol() 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 diff --git a/common/mac.h b/common/mac.h index a71e7cc..a493bd6 100644 --- a/common/mac.h +++ b/common/mac.h @@ -40,10 +40,11 @@ private: }; public: - MacProtocol(StreamBase *stream); + MacProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~MacProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/ostproto.pro b/common/ostproto.pro index 0e095a1..9945212 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -22,7 +22,10 @@ PROTOS += \ dot3.proto \ llc.proto \ snap.proto \ + dot2llc.proto \ + dot2snap.proto \ vlan.proto \ + vlanstack.proto \ ip4.proto \ tcp.proto \ udp.proto @@ -39,7 +42,10 @@ HEADERS += \ dot3.h \ llc.h \ snap.h \ + dot2llc.h \ + dot2snap.h \ vlan.h \ + vlanstack.h \ ip4.h \ tcp.h \ udp.h diff --git a/common/payload.cpp b/common/payload.cpp index 6c93cb3..a83817c 100644 --- a/common/payload.cpp +++ b/common/payload.cpp @@ -30,8 +30,8 @@ void PayloadConfigForm::on_cmbPatternMode_currentIndexChanged(int index) } } -PayloadProtocol::PayloadProtocol(StreamBase *stream) - : AbstractProtocol(stream) +PayloadProtocol::PayloadProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -41,9 +41,10 @@ PayloadProtocol::~PayloadProtocol() 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 diff --git a/common/payload.h b/common/payload.h index 46c1d70..cb93006 100644 --- a/common/payload.h +++ b/common/payload.h @@ -31,10 +31,11 @@ private: }; public: - PayloadProtocol(StreamBase *stream); + PayloadProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~PayloadProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/protocol.proto b/common/protocol.proto index 9788735..372ad54 100644 --- a/common/protocol.proto +++ b/common/protocol.proto @@ -81,8 +81,12 @@ message Protocol { kLlcFieldNumber = 123; kSnapFieldNumber = 124; + kVlanStackFieldNumber = 125; kVlanFieldNumber = 126; + kDot2LlcFieldNumber = 127; + kDot2SnapFieldNumber = 128; + kIp4FieldNumber = 130; kArpFieldNumber = 131; diff --git a/common/protocollistiterator.cpp b/common/protocollistiterator.cpp index 20a08ec..268e2d6 100644 --- a/common/protocollistiterator.cpp +++ b/common/protocollistiterator.cpp @@ -1,5 +1,6 @@ #include "protocollistiterator.h" #include "protocollist.h" +#include "abstractprotocol.h" ProtocolListIterator::ProtocolListIterator(ProtocolList &list) { @@ -31,8 +32,24 @@ bool ProtocolListIterator::hasPrevious() const 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)); } @@ -58,11 +75,21 @@ AbstractProtocol* ProtocolListIterator::previous() 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(); } -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)); } diff --git a/common/protocollistiterator.h b/common/protocollistiterator.h index c2dffd3..8ad4168 100644 --- a/common/protocollistiterator.h +++ b/common/protocollistiterator.h @@ -15,13 +15,13 @@ public: bool findPrevious(const AbstractProtocol* value); bool hasNext() const; bool hasPrevious() const; - void insert(const AbstractProtocol* value); + void insert(AbstractProtocol* value); AbstractProtocol* next(); AbstractProtocol* peekNext() const; AbstractProtocol* peekPrevious() const; AbstractProtocol* previous(); void remove(); - void setValue(const AbstractProtocol* value) const; + void setValue(AbstractProtocol* value) const; void toBack(); void toFront(); const AbstractProtocol* value() const; diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index a353796..9010354 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -11,7 +11,10 @@ #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" @@ -20,16 +23,32 @@ ProtocolManager OstProtocolManager; ProtocolManager::ProtocolManager() { - registerProtocol(51, QString("mac"), (void*) MacProtocol::createInstance); - registerProtocol(52, QString("payload"), (void*) PayloadProtocol::createInstance); - registerProtocol(121, QString("eth2"), (void*) Eth2Protocol::createInstance); - registerProtocol(122, QString("dot3"), (void*) Dot3Protocol::createInstance); - registerProtocol(123, QString("llc"), (void*) LlcProtocol::createInstance); - registerProtocol(124, QString("snap"), (void*) SnapProtocol::createInstance); - registerProtocol(126, QString("vlan"), (void*) VlanProtocol::createInstance); - registerProtocol(130, QString("ip4"), (void*) Ip4Protocol::createInstance); - registerProtocol(140, QString("tcp"), (void*) TcpProtocol::createInstance); - registerProtocol(141, QString("udp"), (void*) UdpProtocol::createInstance); + registerProtocol(OstProto::Protocol::kMacFieldNumber, + QString("mac"), (void*) MacProtocol::createInstance); + registerProtocol(OstProto::Protocol::kPayloadFieldNumber, + QString("payload"), (void*) PayloadProtocol::createInstance); + registerProtocol(OstProto::Protocol::kEth2FieldNumber, + QString("eth2"), (void*) Eth2Protocol::createInstance); + registerProtocol(OstProto::Protocol::kDot3FieldNumber, + QString("dot3"), (void*) Dot3Protocol::createInstance); + registerProtocol(OstProto::Protocol::kLlcFieldNumber, + 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, @@ -42,25 +61,25 @@ void ProtocolManager::registerProtocol(int protoNumber, QString protoName, } AbstractProtocol* ProtocolManager::createProtocol(int protoNumber, - StreamBase *stream) + StreamBase *stream, AbstractProtocol *parent) { - AbstractProtocol* (*pc)(StreamBase*); + AbstractProtocol* (*pc)(StreamBase*, AbstractProtocol*); AbstractProtocol* p; - pc = (AbstractProtocol* (*)(StreamBase*)) + pc = (AbstractProtocol* (*)(StreamBase*, AbstractProtocol*)) factory.value(protoNumber); Q_ASSERT(pc != NULL); - p = (*pc)(stream); + p = (*pc)(stream, parent); return p; } 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() diff --git a/common/protocolmanager.h b/common/protocolmanager.h index ef0a605..985253b 100644 --- a/common/protocolmanager.h +++ b/common/protocolmanager.h @@ -19,8 +19,10 @@ public: void registerProtocol(int protoNumber, QString protoName, void *protoCreator); - AbstractProtocol* createProtocol(int protoNumber, StreamBase *stream); - AbstractProtocol* createProtocol(QString protoName, StreamBase *stream); + AbstractProtocol* createProtocol(int protoNumber, StreamBase *stream, + AbstractProtocol *parent = 0); + AbstractProtocol* createProtocol(QString protoName, StreamBase *stream, + AbstractProtocol *parent = 0); QStringList protocolDatabase(); }; diff --git a/common/sample.cpp b/common/sample.cpp index 9dbb81e..3076e6c 100644 --- a/common/sample.cpp +++ b/common/sample.cpp @@ -9,8 +9,8 @@ SampleConfigForm::SampleConfigForm(QWidget *parent) setupUi(this); } -SampleProtocol::SampleProtocol(StreamBase *stream); - : AbstractProtocol(stream) +SampleProtocol::SampleProtocol(StreamBase *stream, AbstractProtocol *parent); + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -20,9 +20,10 @@ SampleProtocol::~SampleProtocol() 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 diff --git a/common/sample.h b/common/sample.h index e02b6bc..6075262 100644 --- a/common/sample.h +++ b/common/sample.h @@ -26,10 +26,11 @@ private: }; public: - SampleProtocol(StreamBase *stream); + SampleProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~SampleProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/snap.cpp b/common/snap.cpp index 26f5c6c..c651bb1 100644 --- a/common/snap.cpp +++ b/common/snap.cpp @@ -9,8 +9,8 @@ SnapConfigForm::SnapConfigForm(QWidget *parent) setupUi(this); } -SnapProtocol::SnapProtocol(StreamBase *stream) - : AbstractProtocol(stream) +SnapProtocol::SnapProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -20,9 +20,10 @@ SnapProtocol::~SnapProtocol() 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 diff --git a/common/snap.h b/common/snap.h index 79e2780..a2531f6 100644 --- a/common/snap.h +++ b/common/snap.h @@ -27,10 +27,11 @@ private: }; public: - SnapProtocol(StreamBase *stream); + SnapProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~SnapProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/streambase.cpp b/common/streambase.cpp index b98c6c6..ecfc07c 100644 --- a/common/streambase.cpp +++ b/common/streambase.cpp @@ -12,22 +12,23 @@ StreamBase::StreamBase() : mControl(new OstProto::StreamControl) { AbstractProtocol *proto; + ProtocolListIterator *iter; mStreamId->set_id(0xFFFFFFFF); currentFrameProtocols = new ProtocolList; + iter = createProtocolListIterator(); // By default newly created streams have the mac and payload protocols proto = OstProtocolManager.createProtocol("mac", this); - currentFrameProtocols->append(proto); + iter->insert(proto); qDebug("stream: mac = %p", proto); proto = OstProtocolManager.createProtocol("payload", this); - currentFrameProtocols->append(proto); + iter->insert(proto); qDebug("stream: payload = %p", proto); { - ProtocolListIterator *iter = createProtocolListIterator(); iter->toFront(); while (iter->hasNext()) { @@ -40,8 +41,9 @@ StreamBase::StreamBase() : qDebug("{[%d]}", iter->next()->protocolNumber()); // qDebug("{{%p}: %d}", iter->peekNext(), iter->next()->protocolNumber()); } - delete iter; } + + delete iter; } StreamBase::~StreamBase() @@ -53,20 +55,24 @@ StreamBase::~StreamBase() void StreamBase::protoDataCopyFrom(const OstProto::Stream &stream) { - AbstractProtocol *proto; + AbstractProtocol *proto; + ProtocolListIterator *iter; mStreamId->CopyFrom(stream.stream_id()); mCore->CopyFrom(stream.core()); mControl->CopyFrom(stream.control()); currentFrameProtocols->destroy(); + iter = createProtocolListIterator(); for (int i=0; i < stream.protocol_size(); i++) { proto = OstProtocolManager.createProtocol( stream.protocol(i).protocol_id().id(), this); proto->protoDataCopyFrom(stream.protocol(i)); - currentFrameProtocols->append(proto); + iter->insert(proto); } + + delete iter; } void StreamBase::protoDataCopyInto(OstProto::Stream &stream) const diff --git a/common/tcp.cpp b/common/tcp.cpp index 279efc1..dc461b6 100644 --- a/common/tcp.cpp +++ b/common/tcp.cpp @@ -9,8 +9,8 @@ TcpConfigForm::TcpConfigForm(QWidget *parent) setupUi(this); } -TcpProtocol::TcpProtocol(StreamBase *stream) - : AbstractProtocol(stream) +TcpProtocol::TcpProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -20,9 +20,10 @@ TcpProtocol::~TcpProtocol() 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 diff --git a/common/tcp.h b/common/tcp.h index 36edba8..cfd43a6 100644 --- a/common/tcp.h +++ b/common/tcp.h @@ -45,10 +45,11 @@ private: }; public: - TcpProtocol(StreamBase *stream); + TcpProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~TcpProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/udp.cpp b/common/udp.cpp index 7564d2a..c722b54 100644 --- a/common/udp.cpp +++ b/common/udp.cpp @@ -9,8 +9,8 @@ UdpConfigForm::UdpConfigForm(QWidget *parent) setupUi(this); } -UdpProtocol::UdpProtocol(StreamBase *stream) - : AbstractProtocol(stream) +UdpProtocol::UdpProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -20,9 +20,10 @@ UdpProtocol::~UdpProtocol() 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 diff --git a/common/udp.h b/common/udp.h index a2abbed..278809a 100644 --- a/common/udp.h +++ b/common/udp.h @@ -32,10 +32,11 @@ private: }; public: - UdpProtocol(StreamBase *stream); + UdpProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~UdpProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/vlan.cpp b/common/vlan.cpp index 2f60601..49b9a27 100644 --- a/common/vlan.cpp +++ b/common/vlan.cpp @@ -8,8 +8,8 @@ VlanConfigForm::VlanConfigForm(QWidget *parent) setupUi(this); } -VlanProtocol::VlanProtocol(StreamBase *stream) - : AbstractProtocol(stream) +VlanProtocol::VlanProtocol(StreamBase *stream, AbstractProtocol *parent) + : AbstractProtocol(stream, parent) { configForm = NULL; } @@ -19,9 +19,10 @@ VlanProtocol::~VlanProtocol() 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 diff --git a/common/vlan.h b/common/vlan.h index fedf315..c5655da 100644 --- a/common/vlan.h +++ b/common/vlan.h @@ -32,10 +32,11 @@ private: }; public: - VlanProtocol(StreamBase *stream); + VlanProtocol(StreamBase *stream, AbstractProtocol *parent = 0); virtual ~VlanProtocol(); - static AbstractProtocol* createInstance(StreamBase *stream); + static AbstractProtocol* createInstance(StreamBase *stream, + AbstractProtocol *parent = 0); virtual quint32 protocolNumber() const; virtual void protoDataCopyInto(OstProto::Protocol &protocol) const; diff --git a/common/vlanstack.h b/common/vlanstack.h new file mode 100644 index 0000000..5202729 --- /dev/null +++ b/common/vlanstack.h @@ -0,0 +1,10 @@ +#ifndef _VLAN_STACK_H +#define _VLAN_STACK_H + +#include "comboprotocol.h" +#include "vlan.h" + +typedef ComboProtocol VlanStackProtocol; + +#endif diff --git a/common/vlanstack.proto b/common/vlanstack.proto new file mode 100644 index 0000000..4c3d06d --- /dev/null +++ b/common/vlanstack.proto @@ -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; +} diff --git a/server/myservice.cpp b/server/myservice.cpp index 6d9d2ae..ff01e17 100644 --- a/server/myservice.cpp +++ b/server/myservice.cpp @@ -2,6 +2,7 @@ #include #include #include "qdebug.h" +#include #include "myservice.h" #include "../common/protocollist.h" @@ -86,7 +87,7 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n) // ------------------ PortInfo -------------------- // 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]; @@ -333,6 +334,21 @@ void PortInfo::stopTransmit() transmitter.stop(); } +void PortInfo::startCapture() +{ + capturer.start(); +} + +void PortInfo::stopCapture() +{ + capturer.stop(); +} + +void PortInfo::viewCapture() +{ + capturer.view(); +} + void PortInfo::resetStats() { memcpy((void*) &epochStats, (void*) &stats, sizeof(stats)); @@ -714,6 +730,59 @@ void PortInfo::PortTransmitter::stop() 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 include also + QProcess::execute("C:/Program Files/Wireshark/wireshark.exe", + QStringList() << capFile.fileName()); +} + /*--------------- MyService ---------------*/ @@ -1067,7 +1136,18 @@ const ::OstProto::PortIdList* request, ::google::protobuf::Closure* done) { 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(); } @@ -1077,7 +1157,17 @@ const ::OstProto::PortIdList* request, ::google::protobuf::Closure* done) { 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(); } @@ -1087,6 +1177,19 @@ const ::OstProto::PortIdList* request, ::google::protobuf::Closure* done) { 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"); done->Run(); } diff --git a/server/myservice.h b/server/myservice.h index 7a4f331..270bfba 100644 --- a/server/myservice.h +++ b/server/myservice.h @@ -14,6 +14,7 @@ #include #include #include +#include #include "../rpc/pbhelper.h" #include "pcapextra.h" @@ -92,6 +93,22 @@ class PortInfo void run(); 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; @@ -136,6 +153,7 @@ class PortInfo PortMonitorRx monitorRx; PortMonitorTx monitorTx; PortTransmitter transmitter; + PortCapture capturer; struct PortStats epochStats; struct PortStats stats; @@ -153,6 +171,9 @@ public: void update(); void startTransmit(); void stopTransmit(); + void startCapture(); + void stopCapture(); + void viewCapture(); void resetStats(); };