IGMP/MLD msg types have been moved into the IGMP/MLD subclasses from GMP. Packet is now correctly padded with zero rather than garbage. Implemented AbstractProtocol::protocolHasPayload() method to force payload to None for IGMP/MLD/ARP etc.
This commit is contained in:
parent
a465e926a5
commit
790e1cb383
@ -113,6 +113,15 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
|
|||||||
if (validProtocolCount == 0)
|
if (validProtocolCount == 0)
|
||||||
connect(btn1, SIGNAL(clicked(bool)),
|
connect(btn1, SIGNAL(clicked(bool)),
|
||||||
bgProto[i+1]->button(ButtonIdNone), SLOT(click()));
|
bgProto[i+1]->button(ButtonIdNone), SLOT(click()));
|
||||||
|
|
||||||
|
// If the id1 protocol doesn't have a payload (e.g. IGMP)
|
||||||
|
// force payload protocol to 'None'
|
||||||
|
if (!OstProtocolManager->protocolHasPayload(id1))
|
||||||
|
{
|
||||||
|
connect(btn1, SIGNAL(clicked(bool)),
|
||||||
|
bgProto[ProtoPayload]->button(ButtonIdNone),
|
||||||
|
SLOT(click()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,7 @@ AbstractProtocol::AbstractProtocol(StreamBase *stream, AbstractProtocol *parent)
|
|||||||
_metaFieldCount = -1;
|
_metaFieldCount = -1;
|
||||||
_frameFieldCount = -1;
|
_frameFieldCount = -1;
|
||||||
protoSize = -1;
|
protoSize = -1;
|
||||||
|
_hasPayload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -614,6 +615,18 @@ bool AbstractProtocol::isProtocolFramePayloadSizeVariable() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns true if the protocol typically contains a payload or other protocols
|
||||||
|
following it e.g. TCP, UDP have payloads, while ARP, IGMP do not
|
||||||
|
|
||||||
|
The default implementation returns true. If a subclass does not have a
|
||||||
|
payload, it should set the _hasPayload data member to false
|
||||||
|
*/
|
||||||
|
bool AbstractProtocol::protocolHasPayload() const
|
||||||
|
{
|
||||||
|
return _hasPayload;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the checksum (of the requested type) of the protocol's contents
|
Returns the checksum (of the requested type) of the protocol's contents
|
||||||
|
|
||||||
|
@ -59,6 +59,9 @@ protected:
|
|||||||
AbstractProtocol *prev; //!< Protocol preceding this protocol
|
AbstractProtocol *prev; //!< Protocol preceding this protocol
|
||||||
AbstractProtocol *next; //!< Protocol succeeding this protocol
|
AbstractProtocol *next; //!< Protocol succeeding this protocol
|
||||||
|
|
||||||
|
//! Is protocol typically followed by payload or another protocol
|
||||||
|
bool _hasPayload;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Properties of a field, can be OR'd
|
//! Properties of a field, can be OR'd
|
||||||
enum FieldFlag {
|
enum FieldFlag {
|
||||||
@ -139,6 +142,8 @@ public:
|
|||||||
bool isProtocolFramePayloadValueVariable() const;
|
bool isProtocolFramePayloadValueVariable() const;
|
||||||
bool isProtocolFramePayloadSizeVariable() const;
|
bool isProtocolFramePayloadSizeVariable() const;
|
||||||
|
|
||||||
|
bool protocolHasPayload() const;
|
||||||
|
|
||||||
virtual quint32 protocolFrameCksum(int streamIndex = 0,
|
virtual quint32 protocolFrameCksum(int streamIndex = 0,
|
||||||
CksumType cksumType = CksumIp) const;
|
CksumType cksumType = CksumIp) const;
|
||||||
quint32 protocolFrameHeaderCksum(int streamIndex = 0,
|
quint32 protocolFrameHeaderCksum(int streamIndex = 0,
|
||||||
|
@ -88,6 +88,7 @@ void ArpConfigForm::on_targetProtoAddrMode_currentIndexChanged(int index)
|
|||||||
ArpProtocol::ArpProtocol(StreamBase *stream, AbstractProtocol *parent)
|
ArpProtocol::ArpProtocol(StreamBase *stream, AbstractProtocol *parent)
|
||||||
: AbstractProtocol(stream, parent)
|
: AbstractProtocol(stream, parent)
|
||||||
{
|
{
|
||||||
|
_hasPayload = false;
|
||||||
configForm = NULL;
|
configForm = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,16 +29,6 @@ GmpConfigForm::GmpConfigForm(QWidget *parent)
|
|||||||
{
|
{
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
// TODO: this should be in subclass
|
|
||||||
msgTypeCombo->setValueMask(0xFF);
|
|
||||||
msgTypeCombo->addItem(kIgmpV1Query, "IGMPv1 Query");
|
|
||||||
msgTypeCombo->addItem(kIgmpV1Report, "IGMPv1 Report");
|
|
||||||
msgTypeCombo->addItem(kIgmpV2Query, "IGMPv2 Query");
|
|
||||||
msgTypeCombo->addItem(kIgmpV2Report, "IGMPv2 Report");
|
|
||||||
msgTypeCombo->addItem(kIgmpV2Leave, "IGMPv2 Leave");
|
|
||||||
msgTypeCombo->addItem(kIgmpV3Query, "IGMPv3 Query");
|
|
||||||
msgTypeCombo->addItem(kIgmpV3Report, "IGMPv3 Report");
|
|
||||||
|
|
||||||
auxData->setValidator(new QRegExpValidator(
|
auxData->setValidator(new QRegExpValidator(
|
||||||
QRegExp("[0-9A-Fa-f]*"), this));
|
QRegExp("[0-9A-Fa-f]*"), this));
|
||||||
}
|
}
|
||||||
@ -54,43 +44,6 @@ void GmpConfigForm::update()
|
|||||||
groupList->currentItem());
|
groupList->currentItem());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GmpConfigForm::on_msgTypeCombo_currentIndexChanged(int /*index*/)
|
|
||||||
{
|
|
||||||
switch(msgTypeCombo->currentValue())
|
|
||||||
{
|
|
||||||
case kIgmpV1Query:
|
|
||||||
case kIgmpV1Report:
|
|
||||||
case kIgmpV2Query:
|
|
||||||
case kIgmpV2Report:
|
|
||||||
case kIgmpV2Leave:
|
|
||||||
case kMldV1Query:
|
|
||||||
case kMldV1Report:
|
|
||||||
case kMldV1Done:
|
|
||||||
asmGroup->show();
|
|
||||||
ssmWidget->hide();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kIgmpV3Query:
|
|
||||||
case kMldV2Query:
|
|
||||||
asmGroup->hide();
|
|
||||||
ssmWidget->setCurrentIndex(kSsmQueryPage);
|
|
||||||
ssmWidget->show();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kIgmpV3Report:
|
|
||||||
case kMldV2Report:
|
|
||||||
asmGroup->hide();
|
|
||||||
ssmWidget->setCurrentIndex(kSsmReportPage);
|
|
||||||
ssmWidget->show();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
asmGroup->hide();
|
|
||||||
ssmWidget->hide();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GmpConfigForm::on_groupMode_currentIndexChanged(int index)
|
void GmpConfigForm::on_groupMode_currentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
bool disabled = (index == 0);
|
bool disabled = (index == 0);
|
||||||
|
60
common/gmp.h
60
common/gmp.h
@ -27,31 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
|||||||
|
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
|
||||||
// Both IGMP and MLD use the same msg type value for 'Query' message
|
|
||||||
// across versions despite the fields being different. To distinguish
|
|
||||||
// Query messages of different versions, we use an additional upper byte
|
|
||||||
enum GmpMsgType
|
|
||||||
{
|
|
||||||
// IGMP
|
|
||||||
kIgmpV1Query = 0x11,
|
|
||||||
kIgmpV1Report = 0x12,
|
|
||||||
|
|
||||||
kIgmpV2Query = 0xFF11,
|
|
||||||
kIgmpV2Report = 0x16,
|
|
||||||
kIgmpV2Leave = 0x17,
|
|
||||||
|
|
||||||
kIgmpV3Query = 0xFE11,
|
|
||||||
kIgmpV3Report = 0x22,
|
|
||||||
|
|
||||||
// MLD
|
|
||||||
kMldV1Query = 0x82,
|
|
||||||
kMldV1Report = 0x83,
|
|
||||||
kMldV1Done = 0x84,
|
|
||||||
|
|
||||||
kMldV2Query = 0xFF82,
|
|
||||||
kMldV2Report = 0x8F
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Gmp Protocol Frame Format - TODO: for now see the respective RFCs
|
Gmp Protocol Frame Format - TODO: for now see the respective RFCs
|
||||||
*/
|
*/
|
||||||
@ -67,13 +42,11 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
QString _defaultGroupIp;
|
QString _defaultGroupIp;
|
||||||
QString _defaultSourceIp;
|
QString _defaultSourceIp;
|
||||||
private:
|
|
||||||
enum {
|
enum {
|
||||||
kSsmQueryPage = 0,
|
kSsmQueryPage = 0,
|
||||||
kSsmReportPage = 1
|
kSsmReportPage = 1
|
||||||
};
|
};
|
||||||
private slots:
|
private slots:
|
||||||
void on_msgTypeCombo_currentIndexChanged(int index);
|
|
||||||
void on_groupMode_currentIndexChanged(int index);
|
void on_groupMode_currentIndexChanged(int index);
|
||||||
void on_addSource_clicked();
|
void on_addSource_clicked();
|
||||||
void on_deleteSource_clicked();
|
void on_deleteSource_clicked();
|
||||||
@ -163,11 +136,11 @@ protected:
|
|||||||
OstProto::Gmp data;
|
OstProto::Gmp data;
|
||||||
GmpConfigForm *configForm;
|
GmpConfigForm *configForm;
|
||||||
|
|
||||||
GmpMsgType msgType() const;
|
int msgType() const;
|
||||||
|
|
||||||
virtual bool isSsmReport() const;
|
virtual bool isSsmReport() const = 0;
|
||||||
virtual bool isQuery() const;
|
virtual bool isQuery() const = 0;
|
||||||
virtual bool isSsmQuery() const;
|
virtual bool isSsmQuery() const = 0;
|
||||||
|
|
||||||
int qqic(int value) const;
|
int qqic(int value) const;
|
||||||
|
|
||||||
@ -176,30 +149,9 @@ private:
|
|||||||
static QHash<int, int> frameFieldCountMap;
|
static QHash<int, int> frameFieldCountMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline GmpMsgType GmpProtocol::msgType() const
|
inline int GmpProtocol::msgType() const
|
||||||
{
|
{
|
||||||
return GmpMsgType(fieldData(kType, FieldValue).toUInt());
|
return fieldData(kType, FieldValue).toInt();
|
||||||
}
|
|
||||||
|
|
||||||
inline bool GmpProtocol::isSsmReport() const
|
|
||||||
{
|
|
||||||
return ((msgType() == kIgmpV3Report)
|
|
||||||
|| (msgType() == kMldV2Report ));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool GmpProtocol::isQuery() const
|
|
||||||
{
|
|
||||||
return ((msgType() == kIgmpV1Query)
|
|
||||||
|| (msgType() == kIgmpV2Query)
|
|
||||||
|| (msgType() == kIgmpV3Query)
|
|
||||||
|| (msgType() == kMldV1Query )
|
|
||||||
|| (msgType() == kMldV2Query ));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool GmpProtocol::isSsmQuery() const
|
|
||||||
{
|
|
||||||
return ((msgType() == kIgmpV3Query)
|
|
||||||
|| (msgType() == kMldV2Query ));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int GmpProtocol::qqic(int value) const
|
inline int GmpProtocol::qqic(int value) const
|
||||||
|
@ -28,6 +28,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
|||||||
IgmpConfigForm::IgmpConfigForm(QWidget *parent)
|
IgmpConfigForm::IgmpConfigForm(QWidget *parent)
|
||||||
: GmpConfigForm(parent)
|
: GmpConfigForm(parent)
|
||||||
{
|
{
|
||||||
|
connect(msgTypeCombo, SIGNAL(currentIndexChanged(int)),
|
||||||
|
SLOT(on_msgTypeCombo_currentIndexChanged(int)));
|
||||||
|
|
||||||
|
msgTypeCombo->setValueMask(0xFF);
|
||||||
|
msgTypeCombo->addItem(kIgmpV1Query, "IGMPv1 Query");
|
||||||
|
msgTypeCombo->addItem(kIgmpV1Report, "IGMPv1 Report");
|
||||||
|
msgTypeCombo->addItem(kIgmpV2Query, "IGMPv2 Query");
|
||||||
|
msgTypeCombo->addItem(kIgmpV2Report, "IGMPv2 Report");
|
||||||
|
msgTypeCombo->addItem(kIgmpV2Leave, "IGMPv2 Leave");
|
||||||
|
msgTypeCombo->addItem(kIgmpV3Query, "IGMPv3 Query");
|
||||||
|
msgTypeCombo->addItem(kIgmpV3Report, "IGMPv3 Report");
|
||||||
|
|
||||||
_defaultGroupIp = "0.0.0.0";
|
_defaultGroupIp = "0.0.0.0";
|
||||||
_defaultSourceIp = "0.0.0.0";
|
_defaultSourceIp = "0.0.0.0";
|
||||||
|
|
||||||
@ -37,9 +49,43 @@ IgmpConfigForm::IgmpConfigForm(QWidget *parent)
|
|||||||
groupRecordSourceList->setItemDelegate(new IPv4AddressDelegate(this));
|
groupRecordSourceList->setItemDelegate(new IPv4AddressDelegate(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IgmpConfigForm::on_msgTypeCombo_currentIndexChanged(int /*index*/)
|
||||||
|
{
|
||||||
|
switch(msgTypeCombo->currentValue())
|
||||||
|
{
|
||||||
|
case kIgmpV1Query:
|
||||||
|
case kIgmpV1Report:
|
||||||
|
case kIgmpV2Query:
|
||||||
|
case kIgmpV2Report:
|
||||||
|
case kIgmpV2Leave:
|
||||||
|
asmGroup->show();
|
||||||
|
ssmWidget->hide();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kIgmpV3Query:
|
||||||
|
asmGroup->hide();
|
||||||
|
ssmWidget->setCurrentIndex(kSsmQueryPage);
|
||||||
|
ssmWidget->show();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kIgmpV3Report:
|
||||||
|
asmGroup->hide();
|
||||||
|
ssmWidget->setCurrentIndex(kSsmReportPage);
|
||||||
|
ssmWidget->show();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
asmGroup->hide();
|
||||||
|
ssmWidget->hide();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IgmpProtocol::IgmpProtocol(StreamBase *stream, AbstractProtocol *parent)
|
IgmpProtocol::IgmpProtocol(StreamBase *stream, AbstractProtocol *parent)
|
||||||
: GmpProtocol(stream, parent)
|
: GmpProtocol(stream, parent)
|
||||||
{
|
{
|
||||||
|
_hasPayload = false;
|
||||||
|
|
||||||
data.set_type(kIgmpV2Query);
|
data.set_type(kIgmpV2Query);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,7 +434,7 @@ quint16 IgmpProtocol::checksum(int streamIndex) const
|
|||||||
{
|
{
|
||||||
quint16 cks;
|
quint16 cks;
|
||||||
quint32 sum = 0;
|
quint32 sum = 0;
|
||||||
#if 1 // FIXME
|
|
||||||
// TODO: add as a new CksumType (CksumIgmp?) and implement in AbsProto
|
// TODO: add as a new CksumType (CksumIgmp?) and implement in AbsProto
|
||||||
cks = protocolFrameCksum(streamIndex, CksumIp);
|
cks = protocolFrameCksum(streamIndex, CksumIp);
|
||||||
sum += (quint16) ~cks;
|
sum += (quint16) ~cks;
|
||||||
@ -398,6 +444,6 @@ quint16 IgmpProtocol::checksum(int streamIndex) const
|
|||||||
sum = (sum & 0xFFFF) + (sum >> 16);
|
sum = (sum & 0xFFFF) + (sum >> 16);
|
||||||
|
|
||||||
cks = (~sum) & 0xFFFF;
|
cks = (~sum) & 0xFFFF;
|
||||||
#endif
|
|
||||||
return cks;
|
return cks;
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,30 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
|||||||
#include "igmp.pb.h"
|
#include "igmp.pb.h"
|
||||||
#include "gmp.h"
|
#include "gmp.h"
|
||||||
|
|
||||||
|
// IGMP uses the same msg type value for 'Query' messages across
|
||||||
|
// versions despite the fields being different. To distinguish
|
||||||
|
// Query messages of different versions, we use an additional
|
||||||
|
// upper byte
|
||||||
|
enum IgmpMsgType
|
||||||
|
{
|
||||||
|
kIgmpV1Query = 0x11,
|
||||||
|
kIgmpV1Report = 0x12,
|
||||||
|
|
||||||
|
kIgmpV2Query = 0xFF11,
|
||||||
|
kIgmpV2Report = 0x16,
|
||||||
|
kIgmpV2Leave = 0x17,
|
||||||
|
|
||||||
|
kIgmpV3Query = 0xFE11,
|
||||||
|
kIgmpV3Report = 0x22,
|
||||||
|
};
|
||||||
|
|
||||||
class IgmpConfigForm : public GmpConfigForm
|
class IgmpConfigForm : public GmpConfigForm
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
IgmpConfigForm(QWidget *parent = 0);
|
IgmpConfigForm(QWidget *parent = 0);
|
||||||
private slots:
|
private slots:
|
||||||
|
void on_msgTypeCombo_currentIndexChanged(int index);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IgmpProtocol : public GmpProtocol
|
class IgmpProtocol : public GmpProtocol
|
||||||
@ -57,11 +76,32 @@ public:
|
|||||||
virtual void storeConfigWidget();
|
virtual void storeConfigWidget();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual bool isSsmReport() const;
|
||||||
|
virtual bool isQuery() const;
|
||||||
|
virtual bool isSsmQuery() const;
|
||||||
|
|
||||||
virtual quint16 checksum(int streamIndex) const;
|
virtual quint16 checksum(int streamIndex) const;
|
||||||
private:
|
private:
|
||||||
int mrc(int value) const;
|
int mrc(int value) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool IgmpProtocol::isSsmReport() const
|
||||||
|
{
|
||||||
|
return (msgType() == kIgmpV3Report);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IgmpProtocol::isQuery() const
|
||||||
|
{
|
||||||
|
return ((msgType() == kIgmpV1Query)
|
||||||
|
|| (msgType() == kIgmpV2Query)
|
||||||
|
|| (msgType() == kIgmpV3Query));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IgmpProtocol::isSsmQuery() const
|
||||||
|
{
|
||||||
|
return (msgType() == kIgmpV3Query);
|
||||||
|
}
|
||||||
|
|
||||||
inline int IgmpProtocol::mrc(int value) const
|
inline int IgmpProtocol::mrc(int value) const
|
||||||
{
|
{
|
||||||
return quint8(value); // TODO: if value > 128, convert to mantissa/exp form
|
return quint8(value); // TODO: if value > 128, convert to mantissa/exp form
|
||||||
|
@ -49,11 +49,44 @@ public:
|
|||||||
MldConfigForm::MldConfigForm(QWidget *parent)
|
MldConfigForm::MldConfigForm(QWidget *parent)
|
||||||
: GmpConfigForm(parent)
|
: GmpConfigForm(parent)
|
||||||
{
|
{
|
||||||
|
connect(msgTypeCombo, SIGNAL(currentIndexChanged(int)),
|
||||||
|
SLOT(on_msgTypeCombo_currentIndexChanged(int)));
|
||||||
|
|
||||||
_defaultSourceIp = "::";
|
_defaultSourceIp = "::";
|
||||||
sourceList->setItemDelegate(new IpAddressDelegate(this));
|
sourceList->setItemDelegate(new IpAddressDelegate(this));
|
||||||
groupRecordSourceList->setItemDelegate(new IpAddressDelegate(this));
|
groupRecordSourceList->setItemDelegate(new IpAddressDelegate(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MldConfigForm::on_msgTypeCombo_currentIndexChanged(int /*index*/)
|
||||||
|
{
|
||||||
|
switch(msgTypeCombo->currentValue())
|
||||||
|
{
|
||||||
|
case kMldV1Query:
|
||||||
|
case kMldV1Report:
|
||||||
|
case kMldV1Done:
|
||||||
|
asmGroup->show();
|
||||||
|
ssmWidget->hide();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kMldV2Query:
|
||||||
|
asmGroup->hide();
|
||||||
|
ssmWidget->setCurrentIndex(kSsmQueryPage);
|
||||||
|
ssmWidget->show();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kMldV2Report:
|
||||||
|
asmGroup->hide();
|
||||||
|
ssmWidget->setCurrentIndex(kSsmReportPage);
|
||||||
|
ssmWidget->show();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
asmGroup->hide();
|
||||||
|
ssmWidget->hide();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MldProtocol::MldProtocol(StreamBase *stream, AbstractProtocol *parent)
|
MldProtocol::MldProtocol(StreamBase *stream, AbstractProtocol *parent)
|
||||||
: GmpProtocol(stream, parent)
|
: GmpProtocol(stream, parent)
|
||||||
{
|
{
|
||||||
|
37
common/mld.h
37
common/mld.h
@ -25,11 +25,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
|||||||
|
|
||||||
#include "abstractprotocol.h"
|
#include "abstractprotocol.h"
|
||||||
|
|
||||||
|
// MLD uses the same msg type value for 'Query' messages across
|
||||||
|
// versions despite the fields being different. To distinguish
|
||||||
|
// Query messages of different versions, we use an additional
|
||||||
|
// upper byte
|
||||||
|
enum MldMsgType
|
||||||
|
{
|
||||||
|
kMldV1Query = 0x82,
|
||||||
|
kMldV1Report = 0x83,
|
||||||
|
kMldV1Done = 0x84,
|
||||||
|
|
||||||
|
kMldV2Query = 0xFF82,
|
||||||
|
kMldV2Report = 0x8F
|
||||||
|
};
|
||||||
|
|
||||||
class MldConfigForm : public GmpConfigForm
|
class MldConfigForm : public GmpConfigForm
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
MldConfigForm(QWidget *parent = 0);
|
MldConfigForm(QWidget *parent = 0);
|
||||||
private slots:
|
private slots:
|
||||||
|
void on_msgTypeCombo_currentIndexChanged(int index);
|
||||||
};
|
};
|
||||||
|
|
||||||
class MldProtocol : public GmpProtocol
|
class MldProtocol : public GmpProtocol
|
||||||
@ -60,7 +76,28 @@ public:
|
|||||||
virtual void loadConfigWidget();
|
virtual void loadConfigWidget();
|
||||||
virtual void storeConfigWidget();
|
virtual void storeConfigWidget();
|
||||||
protected:
|
protected:
|
||||||
|
virtual bool isSsmReport() const;
|
||||||
|
virtual bool isQuery() const;
|
||||||
|
virtual bool isSsmQuery() const;
|
||||||
|
|
||||||
virtual quint16 checksum(int streamIndex) const;
|
virtual quint16 checksum(int streamIndex) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool MldProtocol::isSsmReport() const
|
||||||
|
{
|
||||||
|
return (msgType() == kMldV2Report);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool MldProtocol::isQuery() const
|
||||||
|
{
|
||||||
|
return ((msgType() == kMldV1Query)
|
||||||
|
|| (msgType() == kMldV2Query));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool MldProtocol::isSsmQuery() const
|
||||||
|
{
|
||||||
|
return (msgType() == kMldV2Query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -122,8 +122,9 @@ ProtocolManager::~ProtocolManager()
|
|||||||
nameToNumberMap.clear();
|
nameToNumberMap.clear();
|
||||||
neighbourProtocols.clear();
|
neighbourProtocols.clear();
|
||||||
factory.clear();
|
factory.clear();
|
||||||
while (!protocolList.isEmpty())
|
QList<AbstractProtocol*> pl = protocolList.values();
|
||||||
delete protocolList.takeFirst();
|
while (!pl.isEmpty())
|
||||||
|
delete pl.takeFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolManager::registerProtocol(int protoNumber,
|
void ProtocolManager::registerProtocol(int protoNumber,
|
||||||
@ -136,7 +137,7 @@ void ProtocolManager::registerProtocol(int protoNumber,
|
|||||||
factory.insert(protoNumber, protoInstanceCreator);
|
factory.insert(protoNumber, protoInstanceCreator);
|
||||||
|
|
||||||
p = createProtocol(protoNumber, NULL);
|
p = createProtocol(protoNumber, NULL);
|
||||||
protocolList.append(p);
|
protocolList.insert(protoNumber, p);
|
||||||
|
|
||||||
numberToNameMap.insert(protoNumber, p->shortName());
|
numberToNameMap.insert(protoNumber, p->shortName());
|
||||||
nameToNumberMap.insert(p->shortName(), protoNumber);
|
nameToNumberMap.insert(p->shortName(), protoNumber);
|
||||||
@ -190,6 +191,13 @@ bool ProtocolManager::isValidNeighbour(int protoPrefix, int protoSuffix)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ProtocolManager::protocolHasPayload(int protoNumber)
|
||||||
|
{
|
||||||
|
Q_ASSERT(protocolList.contains(protoNumber));
|
||||||
|
|
||||||
|
return protocolList.value(protoNumber)->protocolHasPayload();
|
||||||
|
}
|
||||||
|
|
||||||
QStringList ProtocolManager::protocolDatabase()
|
QStringList ProtocolManager::protocolDatabase()
|
||||||
{
|
{
|
||||||
return numberToNameMap.values();
|
return numberToNameMap.values();
|
||||||
|
@ -32,7 +32,7 @@ class ProtocolManager
|
|||||||
QMap<QString, int> nameToNumberMap;
|
QMap<QString, int> nameToNumberMap;
|
||||||
QMultiMap<int, int> neighbourProtocols;
|
QMultiMap<int, int> neighbourProtocols;
|
||||||
QMap<int, void*> factory;
|
QMap<int, void*> factory;
|
||||||
QList<AbstractProtocol*> protocolList;
|
QMap<int, AbstractProtocol*> protocolList;
|
||||||
|
|
||||||
void populateNeighbourProtocols();
|
void populateNeighbourProtocols();
|
||||||
|
|
||||||
@ -48,6 +48,7 @@ public:
|
|||||||
AbstractProtocol *parent = 0);
|
AbstractProtocol *parent = 0);
|
||||||
|
|
||||||
bool isValidNeighbour(int protoPrefix, int protoSuffix);
|
bool isValidNeighbour(int protoPrefix, int protoSuffix);
|
||||||
|
bool protocolHasPayload(int protoNumber);
|
||||||
|
|
||||||
QStringList protocolDatabase();
|
QStringList protocolDatabase();
|
||||||
};
|
};
|
||||||
|
@ -444,6 +444,10 @@ int StreamBase::frameValue(uchar *buf, int bufMaxSize, int frameIndex) const
|
|||||||
}
|
}
|
||||||
delete iter;
|
delete iter;
|
||||||
|
|
||||||
|
// Pad with zero, if required
|
||||||
|
if (len < pktLen)
|
||||||
|
memset(buf+len, 0, pktLen-len);
|
||||||
|
|
||||||
return pktLen;
|
return pktLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user