From 010369601604bdb7d921eabcb3cca6a9b8e26e22 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sun, 24 May 2009 14:54:11 +0000 Subject: [PATCH] - AbstractProtocol - new method: fieldFlags() - isCksum, isMeta; Note: isMeta is a flag now not a attrib - fieldData() bit fields are now in lsb not msb - protocolFrameValue() and subclasses changed accordingly - protocolFrameValue() now takes an additional bool param indicating whether the frameValue is being requested for a checksum calculation; if so fields which are checksum fields are assumed to be zero and their value is not fetched to prevent infinite recursion - Other Protocols - mac: srcMac/dstMac modes is now working - vlan: implemented VLAN protocol - ip4: src/dst Addr modes is now working - udp/tcp: checksum done - Basic testing done for MAC, VLAN, IPv4, UDP and TCP protocols - sample protocol: .cpp/.h added to repos - need to be made compilable - StreamConfigDialog - Redesigned the protocol selection tab to accomodate "Advanced Protocol Selection" - L2 Tab config widgets are now in 2 columns - Packet Tree View is no longer collapsed if selected protocols don't change --- client/packetmodel.cpp | 7 +- client/portstatswindow.ui | 2 +- client/streamconfigdialog.cpp | 119 +++++-- client/streamconfigdialog.h | 6 +- client/streamconfigdialog.ui | 568 ++++++++++++++++++++++------------ common/abstractprotocol.cpp | 208 +++++++++---- common/abstractprotocol.h | 37 ++- common/dot3.ui | 4 +- common/ip4.cpp | 230 +++++++++++--- common/ip4.h | 7 +- common/ip4.ui | 6 +- common/mac.cpp | 98 ++++-- common/mac.h | 1 + common/mac.ui | 100 +++--- common/ostproto.pro | 4 + common/payload.cpp | 35 ++- common/payload.h | 3 + common/protocolmanager.cpp | 2 + common/protocolmanager.h | 1 + common/sample.cpp | 170 ++++++++++ common/sample.h | 56 ++++ common/snap.ui | 34 +- common/tcp.cpp | 105 +++++-- common/tcp.h | 13 +- common/udp.cpp | 73 ++++- common/udp.h | 1 + common/vlan.cpp | 229 ++++++++++++++ common/vlan.h | 62 ++++ common/vlan.proto | 8 +- common/vlan.ui | 311 ++++++++++--------- 30 files changed, 1862 insertions(+), 638 deletions(-) create mode 100644 common/sample.cpp create mode 100644 common/sample.h create mode 100644 common/vlan.cpp create mode 100644 common/vlan.h diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index f48f713..4dc4a31 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -10,8 +10,11 @@ PacketModel::PacketModel(const QList &selectedProtocols, void PacketModel::setSelectedProtocols( const QList &selectedProtocols) { - mSelectedProtocols = selectedProtocols; - reset(); + if (mSelectedProtocols != selectedProtocols) + { + mSelectedProtocols = selectedProtocols; + reset(); + } } int PacketModel::rowCount(const QModelIndex &parent) const diff --git a/client/portstatswindow.ui b/client/portstatswindow.ui index 07fe1b2..8c6aed4 100644 --- a/client/portstatswindow.ui +++ b/client/portstatswindow.ui @@ -16,7 +16,7 @@ - QFrame::StyledPanel + QFrame::Panel QFrame::Raised diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index b69ef67..eb6f76c 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -19,14 +19,24 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, setupUi(this); setupUiExtra(); - connect(bgFrameType, SIGNAL(buttonClicked(int)), - this, SLOT(updateSelectedProtocols())); + connect(bgFrameType, SIGNAL(buttonClicked(int)), + this, SLOT(updateContents())); connect(bgL3Proto, SIGNAL(buttonClicked(int)), - this, SLOT(updateSelectedProtocols())); + this, SLOT(updateContents())); connect(bgL4Proto, SIGNAL(buttonClicked(int)), - this, SLOT(updateSelectedProtocols())); + this, SLOT(updateContents())); + //! \todo causes a crash! +#if 0 + connect(lePktLen, SIGNAL(textEdited(QString)), + this, SLOT(updateContents())); +#endif + // Time to play match the signals and slots! + + // Enable VLAN Choices only if FT = Eth2 or SNAP + connect(rbFtNone, SIGNAL(toggled(bool)), gbVlan, SLOT(setDisabled(bool))); + connect(rbFtNone, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool))); // Enable/Disable L3 Protocol Choices for FT None @@ -96,8 +106,11 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex, vwPacketDump->setSelectionModel(tvPacketTree->selectionModel()); // TODO(MED): - //! \todo Implement then enable these protocols + + //! \todo Implement then enable these protocols - SVLAN, ARP, ICMP, IGMP + cbSVlan->setHidden(true); rbL3Arp->setHidden(true); + rbL3Ipv6->setHidden(true); rbL4Icmp->setHidden(true); rbL4Igmp->setHidden(true); //! \todo Enable navigation of streams @@ -132,6 +145,8 @@ void StreamConfigDialog::setupUiExtra() } // ---- Setup default stuff that cannot be done in designer ---- + gbVlan->setDisabled(true); + bgFrameType = new QButtonGroup(); foreach(QRadioButton *btn, gbFrameType->findChildren()) bgFrameType->addButton(btn); @@ -151,7 +166,8 @@ void StreamConfigDialog::setupUiExtra() ** Setup Validators */ // Meta Data - lePktLen->setValidator(new QIntValidator(MIN_PKT_LEN, MAX_PKT_LEN, this)); + //! \todo - doesn't seem to work - range validator needs a spinbox? + //lePktLen->setValidator(new QIntValidator(MIN_PKT_LEN, MAX_PKT_LEN, this)); // L2 Ethernet #if 0 // Proto FW @@ -228,6 +244,9 @@ void StreamConfigDialog::updateSelectedProtocols() // Mac mSelectedProtocols.append(51); + if (cbCVlan->isEnabled() && cbCVlan->isChecked()) + mSelectedProtocols.append(126); + if (rbFtEthernet2->isChecked()) mSelectedProtocols.append(121); else if (rbFt802Dot3Raw->isChecked()) @@ -260,12 +279,13 @@ void StreamConfigDialog::updateSelectedProtocols() // Payload mSelectedProtocols.append(52); - - mpStream->setFrameProtocol(mSelectedProtocols); - mpStream->storeProtocolWidgets(); - mpStream->loadProtocolWidgets(); } +void StreamConfigDialog::updateContents() +{ + StoreCurrentStream(); + LoadCurrentStream(); +} void StreamConfigDialog::on_cmbPktLenMode_currentIndexChanged(QString mode) { @@ -331,13 +351,12 @@ void StreamConfigDialog::on_twTopLevel_currentChanged(int index) if (index != 2) return; - updateSelectedProtocols(); + updateContents(); foreach(int i, mSelectedProtocols) if (mpStream->protocol(i)) protoList.append(mpStream->protocol(i)); mpPacketModel->setSelectedProtocols(protoList); - StoreCurrentStream(mpStream); } void StreamConfigDialog::on_twProto_currentChanged(int index) @@ -368,6 +387,8 @@ void StreamConfigDialog::on_twProto_currentChanged(int index) { case 1: // L2 wl.append(mpStream->protocol("mac")->configWidget()); + if (cbCVlan->isEnabled() && cbCVlan->isChecked()) + wl.append(mpStream->protocol("vlan")->configWidget()); if (rbFtEthernet2->isChecked()) wl.append(mpStream->protocol("eth2")->configWidget()); else if (rbFt802Dot3Raw->isChecked()) @@ -383,28 +404,63 @@ void StreamConfigDialog::on_twProto_currentChanged(int index) wl.append(mpStream->protocol("llc")->configWidget()); wl.append(mpStream->protocol("snap")->configWidget()); } + + { + int i, r = 0, c = 0; + QGridLayout *layout = new QGridLayout; + + Q_ASSERT(wl.size() > 0); + + // We use a 2 column layout for the L2 Tab + + layout->addWidget(wl.at(0), r, c, 1, -1); + r++; + for (i=1; i < wl.size(); i++) + { + layout->addWidget(wl.at(i), r, c); + if ((i % 2) == 0) + r++; + c = (c+1) % 2; + + } + if ((i % 2) == 0) + r++; + layout->setRowStretch(r, 10); + + twProto->widget(index)->setLayout(layout); + } break; case 2: // L3 if (rbL3Ipv4->isChecked()) wl.append(mpStream->protocol("ip4")->configWidget()); + + if (wl.size()) + { + QVBoxLayout *layout = new QVBoxLayout; + + for (int i=0; i < wl.size(); i++) + layout->addWidget(wl.at(i)); + + twProto->widget(index)->setLayout(layout); + } break; case 3: // L4 if (rbL4Tcp->isChecked()) wl.append(mpStream->protocol("tcp")->configWidget()); else if (rbL4Udp->isChecked()) wl.append(mpStream->protocol("udp")->configWidget()); + + if (wl.size()) + { + QVBoxLayout *layout = new QVBoxLayout; + + for (int i=0; i < wl.size(); i++) + layout->addWidget(wl.at(i)); + + twProto->widget(index)->setLayout(layout); + } break; } - - if (wl.size()) - { - layout = new QVBoxLayout; - - for (int i=0; i < wl.size(); i++) - layout->addWidget(wl.at(i)); - - twProto->widget(index)->setLayout(layout); - } } void StreamConfigDialog::update_NumPacketsAndNumBursts() @@ -464,6 +520,13 @@ void StreamConfigDialog::LoadCurrentStream() Q_ASSERT(mSelectedProtocols.at(i) == 51); // Mac i++; + // VLAN + if (mSelectedProtocols.at(i) == 126) // VLAN + { + cbCVlan->setChecked(true); + i++; + } + if (mSelectedProtocols.at(i) == 52) // Payload { i++; @@ -500,6 +563,7 @@ void StreamConfigDialog::LoadCurrentStream() else rbFtNone->setChecked(true); + // L3 if (mSelectedProtocols.at(i) == 52) // Payload { @@ -611,10 +675,11 @@ _proto_parse_done: } } -void StreamConfigDialog::StoreCurrentStream(Stream *pStream) +void StreamConfigDialog::StoreCurrentStream() { QString str; bool isOk; + Stream *pStream = mpStream; qDebug("storing pStream %p", pStream); @@ -660,9 +725,15 @@ void StreamConfigDialog::StoreCurrentStream(Stream *pStream) void StreamConfigDialog::on_pbOk_clicked() { + OstProto::Stream s; + // Store dialog contents into stream - StoreCurrentStream(mPort.streamByIndex(mCurrentStreamIndex)); + //updateSelectedProtocols(); + StoreCurrentStream(); + mpStream->protoDataCopyInto(s); + mPort.streamByIndex(mCurrentStreamIndex)->protoDataCopyFrom(s);; qDebug("stream stored"); + lastTopLevelTabIndex = twTopLevel->currentIndex(); lastProtoTabIndex = twProto->currentIndex(); } diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index 75cae99..fa4aa82 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -49,15 +49,17 @@ private: static int lastProtoTabIndex; void setupUiExtra(); + void updateSelectedProtocols(); void LoadCurrentStream(); - void StoreCurrentStream(Stream *pStream); + void StoreCurrentStream(); private slots: void on_cmbPktLenMode_currentIndexChanged(QString mode); void on_pbPrev_clicked(); void on_pbNext_clicked(); - void updateSelectedProtocols(); + void updateContents(); + void on_twTopLevel_currentChanged(int index); void on_twProto_currentChanged(int index); diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index 9eba69a..d803e44 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -8,8 +8,8 @@ 0 0 - 590 - 517 + 636 + 589 @@ -29,8 +29,8 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff true - - + + @@ -98,11 +98,14 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff false + + 0099; + - 64 + - 32767 + 4 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -111,8 +114,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + + - 64 + 32767 @@ -134,11 +140,14 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff false + + 0099; + - 64 + - 32767 + 4 Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -157,187 +166,337 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff Protocols - - - - - Frame Type - - - - - - None - - - true - - - - - - - Ethernet II - - - false - - - - - - - 802.3 Raw - - - - - - - 802.3 LLC - - - false - - - - - - - LLC SNAP - - - - - + + + + + + + Frame Type + + + + + + None + + + true + + + + + + + Ethernet II + + + false + + + + + + + 802.3 Raw + + + + + + + 802.3 LLC + + + false + + + + + + + LLC SNAP + + + + + + + + + + true + + + VLAN + + + false + + + false + + + + + + true + + + CVLAN + + + + + + + true + + + SVLAN + + + + + + + + + + L3 + + + + + + None + + + true + + + + + + + false + + + IPv4 + + + false + + + + + + + false + + + IPv6 + + + + + + + false + + + ARP + + + + + + + false + + + Other + + + + + + + + + + L4 + + + + + + None + + + true + + + + + + + false + + + ICMP + + + + + + + false + + + IGMP + + + + + + + false + + + TCP + + + + + + + false + + + UDP + + + + + + + false + + + Other + + + + + + + + + + Qt::Vertical + + + + 182 + 16 + + + + + - - + + - L3 + Advanced Protocol Selection + + + true + + + false - - - None - - - true - - - - - - - false - - - IPv4 - - - false - - - - - - - false - - - ARP - - + + + + + + + Available Protocols + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + > + + + + + + + < + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Selected Protocols + + + + + + + + + - - - - L4 - - - - - - None - - - true - - - - - - - false - - - ICMP - - - - - - - false - - - IGMP - - - - - - - false - - - TCP - - - - - - - false - - - UDP - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -410,8 +569,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff + + + - 1 + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -743,7 +905,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - + @@ -820,8 +982,8 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff accept() - 440 - 466 + 496 + 552 533 @@ -836,8 +998,8 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff reject() - 523 - 466 + 579 + 552 533 @@ -852,12 +1014,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 281 - 137 + 158 + 149 - 281 - 169 + 158 + 149 @@ -868,12 +1030,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 30 - 66 + 59 + 120 - 30 - 266 + 59 + 149 @@ -884,12 +1046,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 30 - 91 + 59 + 123 - 30 - 312 + 59 + 149 @@ -900,12 +1062,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 30 - 91 + 59 + 123 - 134 - 177 + 145 + 149 diff --git a/common/abstractprotocol.cpp b/common/abstractprotocol.cpp index 04d0d67..b48f5b1 100644 --- a/common/abstractprotocol.cpp +++ b/common/abstractprotocol.cpp @@ -92,7 +92,7 @@ int AbstractProtocol::fieldCount() const /*! Returns the number of meta fields \n The default implementation counts and returns the number of fields for which - fieldData(index, FieldIsMeta) return true\n + the FieldIsMeta flag is set\n The default implementation caches the count on its first invocation and subsequently returns the cached count */ int AbstractProtocol::metaFieldCount() const @@ -101,7 +101,7 @@ int AbstractProtocol::metaFieldCount() const { int c = 0; for (int i = 0; i < fieldCount() ; i++) - if (fieldData(i, FieldIsMeta).toBool()) + if (fieldFlags(i).testFlag(FieldIsMeta)) c++; metaCount = c; } @@ -117,6 +117,11 @@ int AbstractProtocol::frameFieldCount() const return (fieldCount() - metaFieldCount()); } +AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int index) const +{ + return FieldIsNormal; +} + /*! Returns the requested field attribute data \n Protocols which have meta fields that vary a frame field across streams may use the streamIndex to return the appropriate field value \n @@ -140,6 +145,9 @@ QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib, case FieldName: return QString(); case FieldBitSize: + Q_ASSERT_X(!fieldFlags(index).testFlag(FieldIsCksum), + "AbstractProtocol::fieldData()", + "FieldBitSize for checksum fields need to be handled by the subclass"); return fieldData(index, FieldFrameValue, streamIndex). toByteArray().size() * 8; case FieldValue: @@ -148,8 +156,6 @@ QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib, return QByteArray(); case FieldTextValue: return QString(); - case FieldIsMeta: - return false; default: qFatal("%s:%d: unhandled case %d\n", __FUNCTION__, __LINE__, @@ -196,7 +202,7 @@ int AbstractProtocol::protocolFrameSize() const for (int i = 0; i < fieldCount(); i++) { - if (!fieldData(i, FieldIsMeta).toBool()) + if (!fieldFlags(i).testFlag(FieldIsMeta)) bitsize += fieldData(i, FieldBitSize).toUInt(); } protoSize = (bitsize+7)/8; @@ -248,23 +254,30 @@ int AbstractProtocol::protocolFramePayloadSize() const The default implementation forms and returns an ordered concatenation of the FrameValue of all the 'frame' fields of the protocol taking care of fields which are not an integral number of bytes\n */ -QByteArray AbstractProtocol::protocolFrameValue(int streamIndex) const +QByteArray AbstractProtocol::protocolFrameValue(int streamIndex, bool forCksum) const { QByteArray proto, field; - int bits, lastbitpos = 0; + uint bits, lastbitpos = 0; + FieldFlags flags; for (int i=0; i < fieldCount() ; i++) { - if (!fieldData(i, FieldIsMeta).toBool()) + flags = fieldFlags(i); + if (!flags.testFlag(FieldIsMeta)) { - field = fieldData(i, FieldFrameValue, streamIndex).toByteArray(); bits = fieldData(i, FieldBitSize, streamIndex).toUInt(); - if (bits == 0) - continue; + Q_ASSERT(bits > 0); - qDebug("<<< %d, %d >>>>", proto.size(), field.size()); + if (forCksum && flags.testFlag(FieldIsCksum)) + { + field.resize((bits+7)/8); + field.fill('\0'); + } + else + field = fieldData(i, FieldFrameValue, streamIndex).toByteArray(); + qDebug("<<< %d, %d/%d >>>>", proto.size(), bits, field.size()); - if (bits == field.size() * 8) + if (bits == (uint) field.size() * 8) { if (lastbitpos == 0) proto.append(field); @@ -279,28 +292,44 @@ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex) const field.at(j+1) >> lastbitpos); } } - else if (bits < field.size() * 8) + else if (bits < (uint) field.size() * 8) { - int u, v; + uchar c; + uint v; + + v = (field.size()*8) - bits; + + Q_ASSERT(v < 8); - u = bits / 8; - v = bits % 8; if (lastbitpos == 0) { - proto.append(field.left(u+1)); - char c = proto[proto.size() - 1]; - proto[proto.size() - 1] = c & (0xFF << (8 - v)); - lastbitpos = v; + for (int j = 0; j < field.size(); j++) + { + c = field.at(j) << v; + if ((j+1) < field.size()) + c |= ((uchar)field.at(j+1) >> (8-v)); + proto.append(c); + } + + lastbitpos = (lastbitpos + bits) % 8; } else { - char c = proto[proto.size() - 1]; - proto[proto.size() - 1] = c | (field.at(0) >> lastbitpos); - for (int j = 0; j < (u - 1); j++) - proto.append(field.at(j) << lastbitpos | - field.at(j+1) >> lastbitpos); - if (u) - proto.append( field.at(u) & (0xFF << (8 - v)) ); + Q_ASSERT(proto.size() > 0); + + for (int j = 0; j < field.size(); j++) + { + uchar d; + + c = field.at(j) << v; + if ((j+1) < field.size()) + c |= ((uchar) field.at(j+1) >> (8-v)); + d = proto[proto.size() - 1]; + proto[proto.size() - 1] = d | ((uchar) c >> lastbitpos); + if (bits > (8*j + (8 - v))) + proto.append(c << (8-lastbitpos)); + } + lastbitpos = (lastbitpos + bits) % 8; } } @@ -315,53 +344,124 @@ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex) const return proto; } -QVariant AbstractProtocol::protocolFrameCksum() const +/*! + \note If a subclass uses protocolFrameCksum() from within fieldData() to + derive a cksum field, it MUST handle and return the 'FieldBitSize' + attribute also for that particular field instead of using the default + AbstractProtocol implementation for 'FieldBitSize' - this is required + to prevent infinite recursion + */ +quint32 AbstractProtocol::protocolFrameCksum(int streamIndex, + CksumType cksumType) const { - QByteArray fv; - quint16 *ip; - quint32 len, sum = 0; + static int recursionCount = 0; + quint32 cksum = 0; - fv = protocolFrameValue(-1); - ip = (quint16*) fv.constData(); - len = fv.size(); + recursionCount++; + Q_ASSERT_X(recursionCount < 10, "protocolFrameCksum", "potential infinite recursion - does a protocol checksum field not implement FieldBitSize?"); - while(len > 1) + switch(cksumType) { - sum += *ip; - if(sum & 0x80000000) - sum = (sum & 0xFFFF) + (sum >> 16); - ip++; - len -= 2; + case CksumIp: + { + QByteArray fv; + quint16 *ip; + quint32 len, sum = 0; + + fv = protocolFrameValue(streamIndex, true); + ip = (quint16*) fv.constData(); + len = fv.size(); + + while(len > 1) + { + sum += *ip; + if(sum & 0x80000000) + sum = (sum & 0xFFFF) + (sum >> 16); + ip++; + len -= 2; + } + + if (len) + sum += (unsigned short) *(unsigned char *)ip; + + while(sum>>16) + sum = (sum & 0xFFFF) + (sum >> 16); + + cksum = qFromBigEndian((quint16) ~sum); + break; + } + + case CksumTcpUdp: + { + quint16 cks; + quint32 sum = 0; + + cks = protocolFrameCksum(streamIndex, CksumIp); + sum += (quint16) ~cks; + cks = protocolFramePayloadCksum(streamIndex, CksumIp); + sum += (quint16) ~cks; + cks = protocolFrameHeaderCksum(streamIndex, CksumIpPseudo); + sum += (quint16) ~cks; + + while(sum>>16) + sum = (sum & 0xFFFF) + (sum >> 16); + + cksum = (~sum) & 0xFFFF; + break; + } + default: + break; } - if (len) - sum += (unsigned short) *(unsigned char *)ip; + recursionCount--; + return cksum; +} + +quint32 AbstractProtocol::protocolFrameHeaderCksum(int streamIndex, + CksumType cksumType) const +{ + quint32 sum = 0xFFFF; + QLinkedListIterator iter(frameProtocols); + + Q_ASSERT(cksumType == CksumIpPseudo); + + if (iter.findNext(this)) + { + iter.previous(); + if (iter.hasPrevious()) + sum = iter.previous()->protocolFrameCksum(streamIndex, + CksumIpPseudo); + } while(sum>>16) sum = (sum & 0xFFFF) + (sum >> 16); - return qFromBigEndian((quint16) ~sum); + return (quint16) ~sum; } -QVariant AbstractProtocol::protocolFramePayloadCksum() const +quint32 AbstractProtocol::protocolFramePayloadCksum(int streamIndex, + CksumType cksumType) const { - int cksum = 0; + quint32 sum = 0; + quint16 cksum; QLinkedListIterator iter(frameProtocols); + Q_ASSERT(cksumType == CksumIp); + if (iter.findNext(this)) { while (iter.hasNext()) - cksum += iter.next()->protocolFrameCksum().toUInt(); // TODO: chg to partial + { + cksum = iter.next()->protocolFrameCksum(streamIndex, CksumIp); + sum += (quint16) ~cksum; + } } else - return -1; -#if 0 - while(cksum>>16) - cksum = (cksum & 0xFFFF) + (cksum >> 16); + return 0; - return (quint16) ~cksum; -#endif + while(sum>>16) + sum = (sum & 0xFFFF) + (sum >> 16); - return cksum; + return (quint16) ~sum; } diff --git a/common/abstractprotocol.h b/common/abstractprotocol.h index ec0584b..bbe8325 100644 --- a/common/abstractprotocol.h +++ b/common/abstractprotocol.h @@ -6,6 +6,7 @@ #include #include #include +#include //#include "../rpc/pbhelper.h" #include "../common/protocol.pb.h" @@ -35,13 +36,19 @@ protected: ProtocolList &frameProtocols; public: + enum FieldFlag { + FieldIsNormal = 0x0, + FieldIsMeta = 0x1, + FieldIsCksum = 0x2 + }; + Q_DECLARE_FLAGS(FieldFlags, FieldFlag); + enum FieldAttrib { FieldName, //! name FieldValue, //! value in host byte order (user editable) FieldTextValue, //! value as text FieldFrameValue, //! frame encoded value in network byte order FieldBitSize, //! size in bits - FieldIsMeta //! bool indicating if field is meta }; enum ProtocolIdType { @@ -50,6 +57,14 @@ public: ProtocolIdIp, }; + enum CksumType { + CksumIp, + CksumIpPseudo, + CksumTcpUdp, + + CksumMax + }; + AbstractProtocol(ProtocolList &frameProtoList, OstProto::StreamCore *parent = 0); virtual ~AbstractProtocol(); @@ -71,22 +86,30 @@ public: virtual int metaFieldCount() const; int frameFieldCount() const; + virtual FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, - int streamIndex = 0) const; + int streamIndex = 0) const; virtual bool setFieldData(int index, const QVariant &value, - FieldAttrib attrib = FieldValue); + FieldAttrib attrib = FieldValue); - QByteArray protocolFrameValue(int streamIndex = 0) const; - int protocolFrameSize() const; + QByteArray protocolFrameValue(int streamIndex = 0, + bool forCksum = false) const; + virtual int protocolFrameSize() const; int protocolFrameOffset() const; int protocolFramePayloadSize() const; - virtual QVariant protocolFrameCksum() const; - QVariant protocolFramePayloadCksum() const; + virtual quint32 protocolFrameCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; + quint32 protocolFrameHeaderCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; + quint32 protocolFramePayloadCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; virtual QWidget* configWidget() = 0; virtual void loadConfigWidget() = 0; virtual void storeConfigWidget() = 0; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractProtocol::FieldFlags); + #endif diff --git a/common/dot3.ui b/common/dot3.ui index d452bd0..7473ee2 100644 --- a/common/dot3.ui +++ b/common/dot3.ui @@ -46,8 +46,8 @@ - 40 - 20 + 16 + 54 diff --git a/common/ip4.cpp b/common/ip4.cpp index 260c720..59a6773 100644 --- a/common/ip4.cpp +++ b/common/ip4.cpp @@ -10,10 +10,12 @@ Ip4ConfigForm::Ip4ConfigForm(QWidget *parent) { setupUi(this); + leIpVersion->setValidator(new QIntValidator(0, 15, this)); + connect(cmbIpSrcAddrMode, SIGNAL(currentIndexChanged(int)), - this, SLOT(on_cmbIpSrcAddrMode_currentIndexChanged(int))); + this, SLOT(on_cmbIpSrcAddrMode_currentIndexChanged(int))); connect(cmbIpDstAddrMode, SIGNAL(currentIndexChanged(int)), - this, SLOT(on_cmbIpDstAddrMode_currentIndexChanged(int))); + this, SLOT(on_cmbIpDstAddrMode_currentIndexChanged(int))); } void Ip4ConfigForm::on_cmbIpSrcAddrMode_currentIndexChanged(int index) @@ -110,45 +112,104 @@ int Ip4Protocol::fieldCount() const return ip4_fieldCount; } +AbstractProtocol::FieldFlags Ip4Protocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case ip4_ver: + case ip4_hdrLen: + case ip4_tos: + case ip4_totLen: + case ip4_id: + case ip4_flags: + case ip4_fragOfs: + case ip4_ttl: + case ip4_proto: + break; + + case ip4_cksum: + flags |= FieldIsCksum; + break; + + case ip4_srcAddr: + case ip4_dstAddr: + break; + + case ip4_isOverrideVer: + case ip4_isOverrideHdrLen: + case ip4_isOverrideTotLen: + case ip4_isOverrideCksum: + case ip4_srcAddrMode: + case ip4_srcAddrCount: + case ip4_srcAddrMask: + case ip4_dstAddrMode: + case ip4_dstAddrCount: + case ip4_dstAddrMask: + flags |= FieldIsMeta; + break; + + default: + break; + } + + return flags; +} + QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const { switch (index) { case ip4_ver: + { + int ver; + + ver = data.is_override_ver() ? (data.ver_hdrlen() >> 4) & 0x0F : 4; + switch(attrib) { case FieldName: return QString("Version"); case FieldValue: - return (data.ver_hdrlen() >> 4) & 0x0F; + return ver; case FieldTextValue: - return QString("%1").arg((data.ver_hdrlen() >> 4) & 0x0F); + return QString("%1").arg(ver, 1, BASE_HEX, QChar('0')); case FieldFrameValue: - return QByteArray(1, (char)(data.ver_hdrlen() & 0xF0)); + return QByteArray(1, (char) ver); case FieldBitSize: return 4; default: break; } break; + } case ip4_hdrLen: + { + int hdrlen; + + hdrlen = data.is_override_hdrlen() ? data.ver_hdrlen() & 0x0F : 5; + switch(attrib) { case FieldName: return QString("Header Length"); case FieldValue: - return data.ver_hdrlen() & 0x0F; + return hdrlen; case FieldTextValue: - return QString("%1").arg(data.ver_hdrlen() & 0x0F); + return QString("%1").arg(hdrlen, 1, BASE_HEX, QChar('0')); case FieldFrameValue: - return QByteArray(1, (char)(data.ver_hdrlen() << 4)); + return QByteArray(1, (char) hdrlen); case FieldBitSize: return 4; default: break; } break; + } case ip4_tos: switch(attrib) { @@ -261,11 +322,12 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, QByteArray fv; // FIXME need to shift for 13 bits fv.resize(2); - qToBigEndian((quint16) data.frag_ofs(), (uchar*) fv.data()); + qToBigEndian((quint16) (data.frag_ofs()), + (uchar*) fv.data()); return fv; } case FieldTextValue: - return QString("%1").arg(data.frag_ofs()); + return QString("%1").arg(data.frag_ofs()*8); case FieldBitSize: return 13; default: @@ -316,7 +378,6 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, } case ip4_cksum: { - switch(attrib) { case FieldName: @@ -325,12 +386,10 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, { quint16 cksum; - if (streamIndex < 0) - cksum = 0; - else if (data.is_override_cksum()) + if (data.is_override_cksum()) cksum = data.cksum(); else - cksum = protocolFrameCksum().toUInt(); + cksum = protocolFrameCksum(streamIndex, CksumIp); return cksum; } case FieldFrameValue: @@ -338,12 +397,11 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, QByteArray fv; quint16 cksum; - if (streamIndex < 0) - cksum = 0; - else if (data.is_override_cksum()) + if (data.is_override_cksum()) cksum = data.cksum(); else - cksum = protocolFrameCksum().toUInt(); + cksum = protocolFrameCksum(streamIndex, CksumIp); + fv.resize(2); qToBigEndian((quint16) cksum, (uchar*) fv.data()); return fv; @@ -352,12 +410,10 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, { quint16 cksum; - if (streamIndex < 0) - cksum = 0; - else if (data.is_override_cksum()) + if (data.is_override_cksum()) cksum = data.cksum(); else - cksum = protocolFrameCksum().toUInt(); + cksum = protocolFrameCksum(streamIndex, CksumIp); return QString("0x%1"). arg(cksum, 4, BASE_HEX, QChar('0'));; } @@ -369,46 +425,111 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, break; } case ip4_srcAddr: + { + int u; + quint32 subnet, host, srcIp = 0; + + switch(data.src_ip_mode()) + { + case OstProto::Ip4::e_im_fixed: + srcIp = data.src_ip(); + break; + case OstProto::Ip4::e_im_inc_host: + u = streamIndex % data.src_ip_count(); + subnet = data.src_ip() & data.src_ip_mask(); + host = (((data.src_ip() & ~data.src_ip_mask()) + u) & + ~data.src_ip_mask()); + srcIp = subnet | host; + break; + case OstProto::Ip4::e_im_dec_host: + u = streamIndex % data.src_ip_count(); + subnet = data.src_ip() & data.src_ip_mask(); + host = (((data.src_ip() & ~data.src_ip_mask()) - u) & + ~data.src_ip_mask()); + srcIp = subnet | host; + break; + case OstProto::Ip4::e_im_random_host: + subnet = data.src_ip() & data.src_ip_mask(); + host = (qrand() & ~data.src_ip_mask()); + srcIp = subnet | host; + break; + default: + qWarning("Unhandled src_ip_mode = %d", data.src_ip_mode()); + } + switch(attrib) { case FieldName: return QString("Source"); case FieldValue: - return data.src_ip(); + return srcIp; case FieldFrameValue: { QByteArray fv; fv.resize(4); - qToBigEndian((quint32) data.src_ip(), (uchar*) fv.data()); + qToBigEndian(srcIp, (uchar*) fv.data()); return fv; } case FieldTextValue: - return QHostAddress(data.src_ip()).toString(); + return QHostAddress(srcIp).toString(); default: break; } break; + } case ip4_dstAddr: + { + int u; + quint32 subnet, host, dstIp = 0; + + switch(data.dst_ip_mode()) + { + case OstProto::Ip4::e_im_fixed: + dstIp = data.dst_ip(); + break; + case OstProto::Ip4::e_im_inc_host: + u = streamIndex % data.dst_ip_count(); + subnet = data.dst_ip() & data.dst_ip_mask(); + host = (((data.dst_ip() & ~data.dst_ip_mask()) + u) & + ~data.dst_ip_mask()); + dstIp = subnet | host; + break; + case OstProto::Ip4::e_im_dec_host: + u = streamIndex % data.dst_ip_count(); + subnet = data.dst_ip() & data.dst_ip_mask(); + host = (((data.dst_ip() & ~data.dst_ip_mask()) - u) & + ~data.dst_ip_mask()); + dstIp = subnet | host; + break; + case OstProto::Ip4::e_im_random_host: + subnet = data.dst_ip() & data.dst_ip_mask(); + host = (qrand() & ~data.dst_ip_mask()); + dstIp = subnet | host; + break; + default: + qWarning("Unhandled dst_ip_mode = %d", data.dst_ip_mode()); + } + switch(attrib) { case FieldName: return QString("Destination"); case FieldValue: - return data.dst_ip(); + return dstIp; case FieldFrameValue: { QByteArray fv; fv.resize(4); - qToBigEndian((quint32) data.dst_ip(), (uchar*) fv.data()); + qToBigEndian((quint32) dstIp, (uchar*) fv.data()); return fv; } case FieldTextValue: - return QHostAddress(data.dst_ip()).toString(); + return QHostAddress(dstIp).toString(); default: break; } break; - + } // Meta fields case ip4_isOverrideVer: @@ -423,15 +544,6 @@ QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib, case ip4_dstAddrMode: case ip4_dstAddrCount: case ip4_dstAddrMask: - switch(attrib) - { - case FieldIsMeta: - return true; - default: - break; - } - break; - default: break; } @@ -461,6 +573,34 @@ bool Ip4Protocol::setFieldData(int index, const QVariant &value, return isOk; } +quint32 Ip4Protocol::protocolFrameCksum(int streamIndex, + CksumType cksumType) const +{ + switch (cksumType) + { + case CksumIpPseudo: + { + quint32 sum; + + sum = fieldData(ip4_srcAddr, FieldValue, streamIndex).toUInt() >> 16; + sum += fieldData(ip4_srcAddr, FieldValue, streamIndex).toUInt() & 0xFFFF; + sum += fieldData(ip4_dstAddr, FieldValue, streamIndex).toUInt() >> 16; + sum += fieldData(ip4_dstAddr, FieldValue, streamIndex).toUInt() & 0xFFFF; + + sum += fieldData(ip4_proto, FieldValue, streamIndex).toUInt() & 0x00FF; + sum += (fieldData(ip4_totLen, FieldValue, streamIndex).toUInt() & 0xFFFF) - 20; + + // Above calculation done assuming 'big endian' + // - so convert to host order + //return qFromBigEndian(sum); + return sum; + } + default: + break; + } + + return AbstractProtocol::protocolFrameCksum(streamIndex, cksumType); +} QWidget* Ip4Protocol::configWidget() { @@ -469,15 +609,16 @@ QWidget* Ip4Protocol::configWidget() void Ip4Protocol::loadConfigWidget() { - configForm->leIpVersion->setText(QString().setNum(data.ver_hdrlen() >> 4)); configForm->cbIpVersionOverride->setChecked(data.is_override_ver()); + configForm->leIpVersion->setText(fieldData(ip4_ver, FieldValue).toString()); - configForm->leIpHdrLen->setText(QString().setNum(data.ver_hdrlen() & 0x0F)); configForm->cbIpHdrLenOverride->setChecked(data.is_override_hdrlen()); + configForm->leIpHdrLen->setText(fieldData(ip4_hdrLen, FieldValue).toString()); configForm->leIpTos->setText(uintToHexStr(data.tos(), 1)); - configForm->leIpLength->setText(fieldData(ip4_totLen, FieldValue).toString()); + configForm->cbIpLengthOverride->setChecked(data.is_override_totlen()); + configForm->leIpLength->setText(fieldData(ip4_totLen, FieldValue).toString()); configForm->leIpId->setText(uintToHexStr(data.id(), 2)); configForm->leIpFragOfs->setText(QString().setNum(data.frag_ofs())); @@ -488,9 +629,9 @@ void Ip4Protocol::loadConfigWidget() configForm->leIpProto->setText(uintToHexStr( fieldData(ip4_proto, FieldValue).toUInt(), 1)); + configForm->cbIpCksumOverride->setChecked(data.is_override_cksum()); configForm->leIpCksum->setText(uintToHexStr( fieldData(ip4_cksum, FieldValue).toUInt(), 2)); - configForm->cbIpCksumOverride->setChecked(data.is_override_cksum()); configForm->leIpSrcAddr->setText(QHostAddress(data.src_ip()).toString()); configForm->cmbIpSrcAddrMode->setCurrentIndex(data.src_ip_mode()); @@ -528,8 +669,8 @@ void Ip4Protocol::storeConfigWidget() data.set_ttl(configForm->leIpTtl->text().toULong(&isOk)); data.set_proto(configForm->leIpProto->text().remove(QChar(' ')).toULong(&isOk, 16)); - data.set_cksum(configForm->leIpCksum->text().remove(QChar(' ')).toULong(&isOk)); data.set_is_override_cksum(configForm->cbIpCksumOverride->isChecked()); + data.set_cksum(configForm->leIpCksum->text().remove(QChar(' ')).toULong(&isOk)); data.set_src_ip(QHostAddress(configForm->leIpSrcAddr->text()).toIPv4Address()); data.set_src_ip_mode((OstProto::Ip4_IpAddrMode)configForm->cmbIpSrcAddrMode->currentIndex()); @@ -539,5 +680,6 @@ void Ip4Protocol::storeConfigWidget() data.set_dst_ip(QHostAddress(configForm->leIpDstAddr->text()).toIPv4Address()); data.set_dst_ip_mode((OstProto::Ip4_IpAddrMode)configForm->cmbIpDstAddrMode->currentIndex()); data.set_dst_ip_count(configForm->leIpDstAddrCount->text().toULong(&isOk)); + data.set_dst_ip_mask(QHostAddress(configForm->leIpDstAddrMask->text()).toIPv4Address()); } diff --git a/common/ip4.h b/common/ip4.h index 1bf8ccc..9c20936 100644 --- a/common/ip4.h +++ b/common/ip4.h @@ -6,9 +6,9 @@ #include "ip4.pb.h" #include "ui_ip4.h" -#define IP_FLAG_UNUSED 0x1 +#define IP_FLAG_MF 0x1 #define IP_FLAG_DF 0x2 -#define IP_FLAG_MF 0x4 +#define IP_FLAG_UNUSED 0x4 class Ip4ConfigForm : public QWidget, public Ui::ip4 @@ -74,10 +74,13 @@ public: virtual quint32 protocolId(ProtocolIdType type) const; virtual int fieldCount() const; + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, int streamIndex = 0) const; virtual bool setFieldData(int index, const QVariant &value, FieldAttrib attrib = FieldValue); + virtual quint32 protocolFrameCksum(int streamIndex = 0, + CksumType cksumType = CksumIp) const; virtual QWidget* configWidget(); virtual void loadConfigWidget(); diff --git a/common/ip4.ui b/common/ip4.ui index 785e7e3..a3135e7 100644 --- a/common/ip4.ui +++ b/common/ip4.ui @@ -5,7 +5,7 @@ 0 0 - 504 + 527 296 @@ -35,7 +35,7 @@ - Override Header Length + Override Header Length (x4) @@ -118,7 +118,7 @@ - Fragment Offset + Fragment Offset (x8) diff --git a/common/mac.cpp b/common/mac.cpp index 53defa7..1adc9ca 100644 --- a/common/mac.cpp +++ b/common/mac.cpp @@ -94,26 +94,73 @@ int MacProtocol::fieldCount() const return mac_fieldCount; } +AbstractProtocol::FieldFlags MacProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case mac_dstAddr: + case mac_srcAddr: + break; + + case mac_dstMacMode: + case mac_dstMacCount: + case mac_dstMacStep: + case mac_srcMacMode: + case mac_srcMacCount: + case mac_srcMacStep: + flags |= FieldIsMeta; + break; + } + + return flags; +} + QVariant MacProtocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const { switch (index) { case mac_dstAddr: + { + int u; + quint64 dstMac = 0; + + switch (data.dst_mac_mode()) + { + case OstProto::Mac::e_mm_fixed: + dstMac = data.dst_mac(); + break; + case OstProto::Mac::e_mm_inc: + u = (streamIndex % data.dst_mac_count()) * + data.dst_mac_step(); + dstMac = data.dst_mac() + u; + break; + case OstProto::Mac::e_mm_dec: + u = (streamIndex % data.dst_mac_count()) * + data.dst_mac_step(); + dstMac = data.dst_mac() - u; + break; + default: + qWarning("Unhandled dstMac_mode %d", data.dst_mac_mode()); + } + switch(attrib) { case FieldName: return QString("Desination"); case FieldValue: - return data.dst_mac(); + return dstMac; case FieldTextValue: - return QString("%1").arg(data.dst_mac(), 12, BASE_HEX, - QChar('0')); + return uintToHexStr(dstMac, 6); case FieldFrameValue: { QByteArray fv; fv.resize(8); - qToBigEndian((quint64) data.dst_mac(), (uchar*) fv.data()); + qToBigEndian(dstMac, (uchar*) fv.data()); fv.remove(0, 2); return fv; } @@ -121,22 +168,44 @@ QVariant MacProtocol::fieldData(int index, FieldAttrib attrib, break; } break; - + } case mac_srcAddr: + { + int u; + quint64 srcMac = 0; + + switch (data.src_mac_mode()) + { + case OstProto::Mac::e_mm_fixed: + srcMac = data.src_mac(); + break; + case OstProto::Mac::e_mm_inc: + u = (streamIndex % data.src_mac_count()) * + data.src_mac_step(); + srcMac = data.src_mac() + u; + break; + case OstProto::Mac::e_mm_dec: + u = (streamIndex % data.src_mac_count()) * + data.src_mac_step(); + srcMac = data.src_mac() - u; + break; + default: + qWarning("Unhandled srcMac_mode %d", data.src_mac_mode()); + } + switch(attrib) { case FieldName: return QString("Source"); case FieldValue: - return data.src_mac(); + return srcMac; case FieldTextValue: - return QString("%1").arg(data.src_mac(), 12, BASE_HEX, - QChar('0')); + return uintToHexStr(srcMac, 6); case FieldFrameValue: { QByteArray fv; fv.resize(8); - qToBigEndian((quint64) data.src_mac(), (uchar*) fv.data()); + qToBigEndian(srcMac, (uchar*) fv.data()); fv.remove(0, 2); return fv; } @@ -144,7 +213,7 @@ QVariant MacProtocol::fieldData(int index, FieldAttrib attrib, break; } break; - + } // Meta fields case mac_dstMacMode: case mac_dstMacCount: @@ -152,15 +221,6 @@ QVariant MacProtocol::fieldData(int index, FieldAttrib attrib, case mac_srcMacMode: case mac_srcMacCount: case mac_srcMacStep: - switch(attrib) - { - case FieldIsMeta: - return true; - default: - break; - } - break; - default: break; } diff --git a/common/mac.h b/common/mac.h index 575b9b1..84199a5 100644 --- a/common/mac.h +++ b/common/mac.h @@ -55,6 +55,7 @@ public: virtual int fieldCount() const; + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, int streamIndex = 0) const; virtual bool setFieldData(int index, const QVariant &value, diff --git a/common/mac.ui b/common/mac.ui index 9afb006..ca1350e 100644 --- a/common/mac.ui +++ b/common/mac.ui @@ -5,8 +5,8 @@ 0 0 - 423 - 144 + 512 + 98 @@ -19,28 +19,14 @@ MAC - - - - Mode - - - - - - - Step - - - - + Destination - + @@ -56,7 +42,14 @@ - + + + + Mode + + + + @@ -75,7 +68,14 @@ - + + + + Count + + + + false @@ -88,7 +88,14 @@ - + + + + Step + + + + false @@ -101,14 +108,14 @@ - + Source - + >HH HH HH HH HH HH; @@ -118,7 +125,14 @@ - + + + + Mode + + + + @@ -137,7 +151,14 @@ - + + + + Count + + + + false @@ -147,7 +168,14 @@ - + + + + Step + + + + false @@ -160,29 +188,9 @@ - - - - Count - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - diff --git a/common/ostproto.pro b/common/ostproto.pro index 59b2453..192049f 100644 --- a/common/ostproto.pro +++ b/common/ostproto.pro @@ -10,6 +10,7 @@ FORMS += \ dot3.ui \ llc.ui \ snap.ui \ + vlan.ui \ ip4.ui \ tcp.ui \ udp.ui @@ -21,6 +22,7 @@ PROTOS += \ dot3.proto \ llc.proto \ snap.proto \ + vlan.proto \ ip4.proto \ tcp.proto \ udp.proto @@ -35,6 +37,7 @@ HEADERS += \ dot3.h \ llc.h \ snap.h \ + vlan.h \ ip4.h \ tcp.h \ udp.h @@ -49,6 +52,7 @@ SOURCES += \ dot3.cpp \ llc.cpp \ snap.cpp \ + vlan.cpp \ ip4.cpp \ tcp.cpp \ udp.cpp diff --git a/common/payload.cpp b/common/payload.cpp index 8e79c7d..ecaef9b 100644 --- a/common/payload.cpp +++ b/common/payload.cpp @@ -74,11 +74,36 @@ QString PayloadProtocol::shortName() const return QString("DATA"); } +int PayloadProtocol::protocolFrameSize() const +{ + return (stream->frame_len() - protocolFrameOffset() - SZ_FCS); +} + int PayloadProtocol::fieldCount() const { return payload_fieldCount; } +AbstractProtocol::FieldFlags PayloadProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case payload_dataPattern: + break; + + // Meta fields + case payload_dataPatternMode: + flags |= FieldIsMeta; + break; + } + + return flags; +} + QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const { @@ -118,6 +143,7 @@ QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib, fv[i] = 0xFF - (i % (0xFF + 1)); break; case OstProto::Payload::e_dp_random: + //! \todo cksum will be incorrect for random pattern for (int i = 0; i < dataLen; i++) fv[i] = qrand() % (0xFF + 1); break; @@ -136,15 +162,6 @@ QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib, // Meta fields case payload_dataPatternMode: - switch(attrib) - { - case FieldIsMeta: - return true; - default: - break; - } - break; - default: break; } diff --git a/common/payload.h b/common/payload.h index 4a1dc03..34e9a01 100644 --- a/common/payload.h +++ b/common/payload.h @@ -45,8 +45,11 @@ public: virtual QString name() const; virtual QString shortName() const; + virtual int protocolFrameSize() const; + virtual int fieldCount() const; + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, int streamIndex = 0) const; virtual bool setFieldData(int index, const QVariant &value, diff --git a/common/protocolmanager.cpp b/common/protocolmanager.cpp index 7b49e33..9041adc 100644 --- a/common/protocolmanager.cpp +++ b/common/protocolmanager.cpp @@ -7,6 +7,7 @@ #include "dot3.h" #include "llc.h" #include "snap.h" +#include "vlan.h" #include "ip4.h" #include "tcp.h" #include "udp.h" @@ -24,6 +25,7 @@ ProtocolManager::ProtocolManager() 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); diff --git a/common/protocolmanager.h b/common/protocolmanager.h index 5d8e1ca..de602fc 100644 --- a/common/protocolmanager.h +++ b/common/protocolmanager.h @@ -6,6 +6,7 @@ class ProtocolManager { public: + //! \todo Make these data structures private/protected static QMap nameToNumberMap; static QMap factory; diff --git a/common/sample.cpp b/common/sample.cpp new file mode 100644 index 0000000..e92c9fc --- /dev/null +++ b/common/sample.cpp @@ -0,0 +1,170 @@ +#include +#include + +#include "sample.h" + +SampleConfigForm *SampleProtocol::configForm = NULL; + +SampleConfigForm::SampleConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + +} + +SampleProtocol::SampleProtocol( + ProtocolList &frameProtoList, + OstProto::StreamCore *parent) + : AbstractProtocol(frameProtoList, parent) +{ + if (configForm == NULL) + configForm = new SampleConfigForm; +} + +SampleProtocol::~SampleProtocol() +{ +} + +AbstractProtocol* SampleProtocol::createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore) +{ + return new SampleProtocol(frameProtoList, streamCore); +} + +void SampleProtocol::protoDataCopyInto(OstProto::Stream &stream) +{ + // FIXME: multiple headers + stream.MutableExtension(OstProto::sample)->CopyFrom(data); +} + +void SampleProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +{ + // FIXME: multiple headers + if (stream.HasExtension(OstProto::sample)) + data.MergeFrom(stream.GetExtension(OstProto::sample)); +} + +QString SampleProtocol::name() const +{ + return QString("Sample"); +} + +QString SampleProtocol::shortName() const +{ + return QString("Sample"); +} + +int SampleProtocol::fieldCount() const +{ + return sample_fieldCount; +} + +AbstractProtocol::FieldFlags SampleProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case sample_normal: + break; + + case sample_cksum: + flags |= FieldIsCksum; + break; + + case sample_meta: + flags |= FieldIsMeta; + break; + + default: + break; + } + + return flags; +} + +QVariant SampleProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case sample_FIXME: + { + switch(attrib) + { + case FieldName: + return QString("FIXME"); + case FieldValue: + return data.FIXME(); + case FieldTextValue: + return QString("%1").arg(data.FIXME()); + case FieldFrameValue: + return QByteArray(1, (char)(data.FIXME() & 0xF0)); + case FieldBitSize: + return 4; + default: + break; + } + break; + + } + case sample_FIXME: + { + switch(attrib) + { + case FieldName: + return QString("FIXME"); + case FieldValue: + return FIXME; + case FieldTextValue: + return QString("%1").arg(FIXME); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(0); + qToBigEndian(FIXME, (uchar*) fv.data()); + return fv; + } + return QByteArray(1, (char)(FIXME() & 0xF0)); + case FieldBitSize: + return 4; + default: + break; + } + break; + } + // Meta fields + + case sample_FIXME: + default: + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool SampleProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + // FIXME + return false; +} + + +QWidget* SampleProtocol::configWidget() +{ + return configForm; +} + +void SampleProtocol::loadConfigWidget() +{ +} + +void SampleProtocol::storeConfigWidget() +{ + bool isOk; +} + diff --git a/common/sample.h b/common/sample.h new file mode 100644 index 0000000..9da187d --- /dev/null +++ b/common/sample.h @@ -0,0 +1,56 @@ +#ifndef _SAMPLE_H +#define _SAMPLE_H + +#include "abstractprotocol.h" + +#include "sample.pb.h" +#include "ui_sample.h" + +class SampleConfigForm : public QWidget, public Ui::Sample +{ + Q_OBJECT +public: + SampleConfigForm(QWidget *parent = 0); +private slots: +}; + +class SampleProtocol : public AbstractProtocol +{ +private: + OstProto::Sample data; + static SampleConfigForm *configForm; + enum samplefield + { + + sample_fieldCount + }; + +public: + SampleProtocol(ProtocolList &frameProtoList, + OstProto::StreamCore *parent = 0); + virtual ~SampleProtocol(); + + static AbstractProtocol* createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore = 0); + + virtual void protoDataCopyInto(OstProto::Stream &stream); + virtual void protoDataCopyFrom(const OstProto::Stream &stream); + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/snap.ui b/common/snap.ui index 9d0e4a5..80997bd 100644 --- a/common/snap.ui +++ b/common/snap.ui @@ -5,15 +5,15 @@ 0 0 - 293 - 98 + 194 + 72 Form - - + + SNAP @@ -56,32 +56,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - diff --git a/common/tcp.cpp b/common/tcp.cpp index 26b14c0..ab13d54 100644 --- a/common/tcp.cpp +++ b/common/tcp.cpp @@ -70,6 +70,43 @@ int TcpProtocol::fieldCount() const return tcp_fieldCount; } +AbstractProtocol::FieldFlags TcpProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case tcp_src_port: + case tcp_dst_port: + case tcp_seq_num: + case tcp_ack_num: + case tcp_hdrlen: + case tcp_rsvd: + case tcp_flags: + case tcp_window: + break; + + case tcp_cksum: + flags |= FieldIsCksum; + break; + + case tcp_urg_ptr: + break; + + case tcp_is_override_hdrlen: + case tcp_is_override_cksum: + flags |= FieldIsMeta; + break; + + default: + break; + } + + return flags; +} + QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const { @@ -142,7 +179,7 @@ QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, switch(attrib) { case FieldName: - return QString("Sequence Number"); + return QString("Acknowledgement Number"); case FieldValue: return data.ack_num(); case FieldTextValue: @@ -165,11 +202,22 @@ QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, case FieldName: return QString("Header Length"); case FieldValue: - return ((data.hdrlen_rsvd() >> 4) & 0x0F); + if (data.is_override_hdrlen()) + return ((data.hdrlen_rsvd() >> 4) & 0x0F); + else + return 5; case FieldTextValue: - return QString("%1").arg((data.hdrlen_rsvd() >> 4) & 0x0F); + if (data.is_override_hdrlen()) + return QString("%1 bytes").arg( + 4 * ((data.hdrlen_rsvd() >> 4) & 0x0F)); + else + return QString("20 bytes"); case FieldFrameValue: - return QByteArray(1, (char)(data.hdrlen_rsvd() & 0xF0)); + if (data.is_override_hdrlen()) + return QByteArray(1, + (char)((data.hdrlen_rsvd() >> 4) & 0x0F)); + else + return QByteArray(1, (char) 0x05); case FieldBitSize: return 4; default: @@ -253,16 +301,43 @@ QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, case FieldName: return QString("Checksum"); case FieldValue: - return data.cksum(); + { + quint16 cksum; + + if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); + + return cksum; + } case FieldTextValue: - return QString("%1").arg(data.cksum()); + { + quint16 cksum; + + if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); + + return QString("0x%1").arg(cksum, 4, BASE_HEX, QChar('0')); + } case FieldFrameValue: { + quint16 cksum; + + if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); + QByteArray fv; fv.resize(2); - qToBigEndian((quint16) data.cksum(), (uchar*) fv.data()); + qToBigEndian(cksum, (uchar*) fv.data()); return fv; } + case FieldBitSize: + return 16; default: break; } @@ -292,15 +367,6 @@ QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib, // Meta fields case tcp_is_override_hdrlen: case tcp_is_override_cksum: - switch(attrib) - { - case FieldIsMeta: - return true; - default: - break; - } - break; - default: break; } @@ -329,12 +395,13 @@ void TcpProtocol::loadConfigWidget() configForm->leTcpSeqNum->setText(QString().setNum(data.seq_num())); configForm->leTcpAckNum->setText(QString().setNum(data.ack_num())); - configForm->leTcpHdrLen->setText(QString().setNum((data.hdrlen_rsvd() >> 4) & 0x0F)); + configForm->leTcpHdrLen->setText(fieldData(tcp_hdrlen, FieldValue).toString()); configForm->cbTcpHdrLenOverride->setChecked(data.is_override_hdrlen()); configForm->leTcpWindow->setText(QString().setNum(data.window())); - configForm->leTcpCksum->setText(QString().setNum(data.cksum())); + configForm->leTcpCksum->setText(QString("%1").arg( + fieldData(tcp_cksum, FieldValue).toUInt(), 4, BASE_HEX, QChar('0'))); configForm->cbTcpCksumOverride->setChecked(data.is_override_cksum()); configForm->leTcpUrgentPointer->setText(QString().setNum(data.urg_ptr())); @@ -363,7 +430,7 @@ void TcpProtocol::storeConfigWidget() data.set_window(configForm->leTcpWindow->text().toULong(&isOk)); - data.set_cksum(configForm->leTcpCksum->text().remove(QChar(' ')).toULong(&isOk)); + data.set_cksum(configForm->leTcpCksum->text().remove(QChar(' ')).toULong(&isOk, BASE_HEX)); data.set_is_override_cksum(configForm->cbTcpCksumOverride->isChecked()); data.set_urg_ptr(configForm->leTcpUrgentPointer->text().toULong(&isOk)); diff --git a/common/tcp.h b/common/tcp.h index 0637fc1..bfe165b 100644 --- a/common/tcp.h +++ b/common/tcp.h @@ -6,12 +6,12 @@ #include "tcp.pb.h" #include "ui_tcp.h" -#define TCP_FLAG_URG 0x01 -#define TCP_FLAG_ACK 0x02 -#define TCP_FLAG_PSH 0x04 -#define TCP_FLAG_RST 0x08 -#define TCP_FLAG_SYN 0x10 -#define TCP_FLAG_FIN 0x20 +#define TCP_FLAG_URG 0x20 +#define TCP_FLAG_ACK 0x10 +#define TCP_FLAG_PSH 0x08 +#define TCP_FLAG_RST 0x04 +#define TCP_FLAG_SYN 0x02 +#define TCP_FLAG_FIN 0x01 class TcpConfigForm : public QWidget, public Ui::tcp { @@ -62,6 +62,7 @@ public: virtual int fieldCount() const; + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, int streamIndex = 0) const; virtual bool setFieldData(int index, const QVariant &value, diff --git a/common/udp.cpp b/common/udp.cpp index 4d8585a..4c642c2 100644 --- a/common/udp.cpp +++ b/common/udp.cpp @@ -70,6 +70,35 @@ int UdpProtocol::fieldCount() const return udp_fieldCount; } +AbstractProtocol::FieldFlags UdpProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case udp_srcPort: + case udp_dstPort: + case udp_totLen: + break; + + case udp_cksum: + flags |= FieldIsCksum; + break; + + case udp_isOverrideTotLen: + case udp_isOverrideCksum: + flags |= FieldIsMeta; + break; + + default: + break; + } + + return flags; +} + QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const { @@ -160,26 +189,49 @@ QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib, break; } case udp_cksum: + { + quint16 cksum; + + switch(attrib) + { + case FieldValue: + case FieldFrameValue: + case FieldTextValue: + { + if (data.is_override_cksum()) + cksum = data.cksum(); + else + cksum = protocolFrameCksum(streamIndex, CksumTcpUdp); + qDebug("UDP cksum = %hu", cksum); + } + default: + break; + } + switch(attrib) { case FieldName: return QString("Checksum"); case FieldValue: - return data.cksum(); - case FieldTextValue: - return QString("%1").arg(data.cksum()); + return cksum; case FieldFrameValue: { QByteArray fv; + fv.resize(2); - qToBigEndian((quint16) data.cksum(), (uchar*) fv.data()); + qToBigEndian(cksum, (uchar*) fv.data()); return fv; } + case FieldTextValue: + return QString("0x%1"). + arg(cksum, 4, BASE_HEX, QChar('0'));; + case FieldBitSize: + return 16; default: break; } break; - + } // Meta fields case udp_isOverrideTotLen: case udp_isOverrideCksum: @@ -214,13 +266,14 @@ QWidget* UdpProtocol::configWidget() void UdpProtocol::loadConfigWidget() { - configForm->leUdpSrcPort->setText(QString().setNum(data.src_port())); - configForm->leUdpDstPort->setText(QString().setNum(data.dst_port())); + configForm->leUdpSrcPort->setText(fieldData(udp_srcPort, FieldValue).toString()); + configForm->leUdpDstPort->setText(fieldData(udp_dstPort, FieldValue).toString()); - configForm->leUdpLength->setText(QString().setNum(data.totlen())); + configForm->leUdpLength->setText(fieldData(udp_totLen, FieldValue).toString()); configForm->cbUdpLengthOverride->setChecked(data.is_override_totlen()); - configForm->leUdpCksum->setText(QString().setNum(data.cksum())); + configForm->leUdpCksum->setText(QString("%1").arg( + fieldData(udp_cksum, FieldValue).toUInt(), 4, BASE_HEX, QChar('0'))); configForm->cbUdpCksumOverride->setChecked(data.is_override_cksum()); } @@ -234,7 +287,7 @@ void UdpProtocol::storeConfigWidget() data.set_totlen(configForm->leUdpLength->text().toULong(&isOk)); data.set_is_override_totlen(configForm->cbUdpLengthOverride->isChecked()); - data.set_cksum(configForm->leUdpCksum->text().remove(QChar(' ')).toULong(&isOk)); + data.set_cksum(configForm->leUdpCksum->text().remove(QChar(' ')).toULong(&isOk, BASE_HEX)); data.set_is_override_cksum(configForm->cbUdpCksumOverride->isChecked()); } diff --git a/common/udp.h b/common/udp.h index 5c40330..0fea509 100644 --- a/common/udp.h +++ b/common/udp.h @@ -49,6 +49,7 @@ public: virtual int fieldCount() const; + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual QVariant fieldData(int index, FieldAttrib attrib, int streamIndex = 0) const; virtual bool setFieldData(int index, const QVariant &value, diff --git a/common/vlan.cpp b/common/vlan.cpp new file mode 100644 index 0000000..7908e8e --- /dev/null +++ b/common/vlan.cpp @@ -0,0 +1,229 @@ +#include + +#include "vlan.h" + +VlanConfigForm *VlanProtocol::configForm = NULL; + +VlanConfigForm::VlanConfigForm(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); +} + +VlanProtocol::VlanProtocol( + ProtocolList &frameProtoList, + OstProto::StreamCore *parent) + : AbstractProtocol(frameProtoList, parent) +{ + if (configForm == NULL) + configForm = new VlanConfigForm; +} + +VlanProtocol::~VlanProtocol() +{ +} + +AbstractProtocol* VlanProtocol::createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore) +{ + return new VlanProtocol(frameProtoList, streamCore); +} + +void VlanProtocol::protoDataCopyInto(OstProto::Stream &stream) +{ + // FIXME: multiple headers + stream.MutableExtension(OstProto::vlan)->CopyFrom(data); +} + +void VlanProtocol::protoDataCopyFrom(const OstProto::Stream &stream) +{ + // FIXME: multiple headers + if (stream.HasExtension(OstProto::vlan)) + data.MergeFrom(stream.GetExtension(OstProto::vlan)); +} + +QString VlanProtocol::name() const +{ + return QString("Vlan"); +} + +QString VlanProtocol::shortName() const +{ + return QString("Vlan"); +} + +int VlanProtocol::fieldCount() const +{ + return vlan_fieldCount; +} + +AbstractProtocol::FieldFlags VlanProtocol::fieldFlags(int index) const +{ + AbstractProtocol::FieldFlags flags; + + flags = AbstractProtocol::fieldFlags(index); + + switch (index) + { + case vlan_tpid: + case vlan_prio: + case vlan_cfiDei: + case vlan_vlanId: + break; + + // meta-fields + case vlan_isOverrideTpid: + flags |= FieldIsMeta; + break; + } + + return flags; +} + +QVariant VlanProtocol::fieldData(int index, FieldAttrib attrib, + int streamIndex) const +{ + switch (index) + { + case vlan_tpid: + { + quint16 tpid; + + tpid = data.is_override_tpid() ? data.tpid() : 0x8100; + + switch(attrib) + { + case FieldName: + return QString("Tag Protocol Id"); + case FieldValue: + return tpid; + case FieldTextValue: + return QString("0x%1").arg(tpid, 2, BASE_HEX, QChar('0')); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian(tpid, (uchar*) fv.data()); + return fv; + } + default: + break; + } + break; + } + + case vlan_prio: + { + uint prio = ((data.vlan_tag() >> 13) & 0x07); + + switch(attrib) + { + case FieldName: + return QString("Priority"); + case FieldValue: + return prio; + case FieldTextValue: + return QString("%1").arg(prio); + case FieldFrameValue: + return QByteArray(1, (char) prio); + case FieldBitSize: + return 3; + default: + break; + } + break; + } + + case vlan_cfiDei: + { + uint cfiDei = ((data.vlan_tag() >> 12) & 0x01); + + switch(attrib) + { + case FieldName: + return QString("CFI/DEI"); + case FieldValue: + return cfiDei; + case FieldTextValue: + return QString("%1").arg(cfiDei); + case FieldFrameValue: + return QByteArray(1, (char) cfiDei); + case FieldBitSize: + return 1; + default: + break; + } + break; + } + + case vlan_vlanId: + { + quint16 vlanId = (data.vlan_tag() & 0x0FFF); + + switch(attrib) + { + case FieldName: + return QString("VLAN Id"); + case FieldValue: + return vlanId; + case FieldTextValue: + return QString("%1").arg(vlanId); + case FieldFrameValue: + { + QByteArray fv; + fv.resize(2); + qToBigEndian((quint16) vlanId, (uchar*) fv.data()); + return fv; + } + case FieldBitSize: + return 12; + default: + break; + } + break; + } + // Meta fields + + case vlan_isOverrideTpid: + default: + break; + } + + return AbstractProtocol::fieldData(index, attrib, streamIndex); +} + +bool VlanProtocol::setFieldData(int index, const QVariant &value, + FieldAttrib attrib) +{ + // FIXME + return false; +} + + +QWidget* VlanProtocol::configWidget() +{ + return configForm; +} + +void VlanProtocol::loadConfigWidget() +{ + configForm->leTpid->setText(uintToHexStr(fieldData(vlan_tpid, FieldValue).toUInt(), 2)); + configForm->cmbPrio->setCurrentIndex(fieldData(vlan_prio, FieldValue).toUInt()); + configForm->cmbCfiDei->setCurrentIndex(fieldData(vlan_cfiDei, FieldValue).toUInt()); + configForm->leVlanId->setText(fieldData(vlan_vlanId, FieldValue).toString()); + +} + +void VlanProtocol::storeConfigWidget() +{ + bool isOk; + + data.set_is_override_tpid(configForm->cbTpidOverride->isChecked()); + data.set_tpid(configForm->leTpid->text().remove(QChar(' ')).toULong(&isOk, BASE_HEX)); + data.set_vlan_tag( + ((configForm->cmbPrio->currentIndex() & 0x07) << 13) | + ((configForm->cmbCfiDei->currentIndex() & 0x01) << 12) | + (configForm->leVlanId->text().toULong(&isOk) & 0x0FFF)); +} + diff --git a/common/vlan.h b/common/vlan.h new file mode 100644 index 0000000..23edf44 --- /dev/null +++ b/common/vlan.h @@ -0,0 +1,62 @@ +#ifndef _Vlan_H +#define _Vlan_H + +#include "abstractprotocol.h" + +#include "vlan.pb.h" +#include "ui_vlan.h" + +class VlanConfigForm : public QWidget, public Ui::Vlan +{ + Q_OBJECT +public: + VlanConfigForm(QWidget *parent = 0); +}; + +class VlanProtocol : public AbstractProtocol +{ +private: + OstProto::Vlan data; + static VlanConfigForm *configForm; + enum Vlanfield + { + vlan_tpid, + vlan_prio, + vlan_cfiDei, + vlan_vlanId, + + // meta-fields + vlan_isOverrideTpid, + + vlan_fieldCount + }; + +public: + VlanProtocol(ProtocolList &frameProtoList, + OstProto::StreamCore *parent = 0); + virtual ~VlanProtocol(); + + static AbstractProtocol* createInstance( + ProtocolList &frameProtoList, + OstProto::StreamCore *streamCore = 0); + + virtual void protoDataCopyInto(OstProto::Stream &stream); + virtual void protoDataCopyFrom(const OstProto::Stream &stream); + + virtual QString name() const; + virtual QString shortName() const; + + virtual int fieldCount() const; + + virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; + virtual QVariant fieldData(int index, FieldAttrib attrib, + int streamIndex = 0) const; + virtual bool setFieldData(int index, const QVariant &value, + FieldAttrib attrib = FieldValue); + + virtual QWidget* configWidget(); + virtual void loadConfigWidget(); + virtual void storeConfigWidget(); +}; + +#endif diff --git a/common/vlan.proto b/common/vlan.proto index d5ac773..6703dbc 100644 --- a/common/vlan.proto +++ b/common/vlan.proto @@ -3,13 +3,11 @@ import "protocol.proto"; package OstProto; message Vlan { // VLAN presence/absence - optional bool is_tpid_override = 10; + optional bool is_override_tpid = 1; // VLAN values - optional uint32 ctpid = 13; - optional uint32 cvlan_tag = 14; // includes prio, cfi and cvlanid - optional uint32 stpid = 15; - optional uint32 svlan_tag = 16; // includes pcp, de and svlanid + optional uint32 tpid = 2; + optional uint32 vlan_tag = 3; // includes prio, cfi and vlanid } extend Stream { diff --git a/common/vlan.ui b/common/vlan.ui index c35dc89..3e0326d 100644 --- a/common/vlan.ui +++ b/common/vlan.ui @@ -1,168 +1,179 @@ - Form - + Vlan + 0 0 - 271 - 90 + 268 + 96 Form - - - - - - - Priority - - - - - - - CFI - - - - - - - VLAN - - - - - - - true - - - Override TPID - - - - - - - true - - + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + VLAN + + + + + + true + + + Override TPID + + + + + + + Priority + + + + + + + CFI/DEI + + + + + + + VLAN + + + + + + + false + + + >HH HH; + + + + + + + + + + true + + + + 0 + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + + + + true + + + + 0 + + + + + 1 + + + + + + + + true + 0 - - - - 1 - - - - - 2 - - - - - 3 - - - - - 4 - - - - - 5 - - - - - 6 - - - - - 7 - - - - - - - - true - - - - 0 - - - - - 1 - - - - - - - - true - - - 0 - - - - - - - true - - - >HH HH; - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - + + + + - + + + cbTpidOverride + toggled(bool) + leTpid + setEnabled(bool) + + + 59 + 41 + + + 59 + 57 + + + +