Extended ICMP to work for ICMPv6 as well as ICMPv4
This commit is contained in:
parent
069cc16279
commit
fedc4ec5d1
193
common/icmp.cpp
193
common/icmp.cpp
@ -23,45 +23,86 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#include <QSet>
|
||||
#include <qendian.h>
|
||||
|
||||
const int kIcmpEchoReply = 0;
|
||||
const int kIcmpDestinationUnreachable = 3;
|
||||
const int kIcmpSourceQuench = 4;
|
||||
const int kIcmpRedirect = 5;
|
||||
const int kIcmpEchoRequest = 8;
|
||||
const int kIcmpTimeExceeded = 11;
|
||||
const int kIcmpParameterProblem = 12;
|
||||
const int kIcmpTimestampRequest = 13;
|
||||
const int kIcmpTimestampReply = 14;
|
||||
const int kIcmpInformationRequest = 15;
|
||||
const int kIcmpInformationReply = 16;
|
||||
const int kIcmpAddressMaskRequest = 17;
|
||||
const int kIcmpAddressMaskReply = 18;
|
||||
enum IcmpType
|
||||
{
|
||||
kIcmpEchoReply = 0,
|
||||
kIcmpDestinationUnreachable = 3,
|
||||
kIcmpSourceQuench = 4,
|
||||
kIcmpRedirect = 5,
|
||||
kIcmpEchoRequest = 8,
|
||||
kIcmpTimeExceeded = 11,
|
||||
kIcmpParameterProblem = 12,
|
||||
kIcmpTimestampRequest = 13,
|
||||
kIcmpTimestampReply = 14,
|
||||
kIcmpInformationRequest = 15,
|
||||
kIcmpInformationReply = 16,
|
||||
kIcmpAddressMaskRequest = 17,
|
||||
kIcmpAddressMaskReply = 18
|
||||
};
|
||||
|
||||
static QSet<int> idSeqSet = QSet<int>()
|
||||
enum Icmp6Type
|
||||
{
|
||||
kIcmp6DestinationUnreachable = 1,
|
||||
kIcmp6PacketTooBig = 2,
|
||||
kIcmp6TimeExceeded = 3,
|
||||
kIcmp6ParameterProblem = 4,
|
||||
kIcmp6EchoRequest = 128,
|
||||
kIcmp6EchoReply = 129,
|
||||
kIcmp6RouterSolicitation = 133,
|
||||
kIcmp6RouterAdvertisement = 134,
|
||||
kIcmp6NeighbourSolicitation = 135,
|
||||
kIcmp6NeighbourAdvertisement = 136,
|
||||
kIcmp6Redirect = 137,
|
||||
kIcmp6InformationQuery = 139,
|
||||
kIcmp6InformationResponse = 140
|
||||
};
|
||||
|
||||
static QSet<int> icmpIdSeqSet = QSet<int>()
|
||||
<< kIcmpEchoRequest
|
||||
<< kIcmpEchoReply
|
||||
<< kIcmpInformationRequest
|
||||
<< kIcmpInformationReply;
|
||||
|
||||
static QSet<int> icmp6IdSeqSet = QSet<int>()
|
||||
<< kIcmp6EchoRequest
|
||||
<< kIcmp6EchoReply;
|
||||
|
||||
static bool isIdSeqType(OstProto::Icmp::Version ver, int type)
|
||||
{
|
||||
//qDebug("%s: ver = %d, type = %d", __FUNCTION__, ver, type);
|
||||
switch(ver)
|
||||
{
|
||||
case OstProto::Icmp::kIcmp4:
|
||||
return icmpIdSeqSet.contains(type);
|
||||
case OstProto::Icmp::kIcmp6:
|
||||
return icmp6IdSeqSet.contains(type);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Q_ASSERT(false); // unreachable
|
||||
return false;
|
||||
}
|
||||
|
||||
IcmpConfigForm::IcmpConfigForm(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
versionGroup = new QButtonGroup(this);
|
||||
setupUi(this);
|
||||
|
||||
// auto-connect's not working, for some reason I can't figure out!
|
||||
// slot name changed to when_ instead of on_ so that connectSlotsByName()
|
||||
// doesn't complain
|
||||
connect(versionGroup,
|
||||
SIGNAL(buttonClicked(int)),
|
||||
SLOT(when_versionGroup_buttonClicked(int)));
|
||||
|
||||
versionGroup->addButton(icmp4Button, OstProto::Icmp::kIcmp4);
|
||||
versionGroup->addButton(icmp6Button, OstProto::Icmp::kIcmp6);
|
||||
|
||||
typeCombo->setValidator(new QIntValidator(0, 0xFF, this));
|
||||
typeCombo->addItem(kIcmpEchoReply, "Echo Reply");
|
||||
typeCombo->addItem(kIcmpDestinationUnreachable, "Destination Unreachable");
|
||||
typeCombo->addItem(kIcmpSourceQuench, "Source Quench");
|
||||
typeCombo->addItem(kIcmpRedirect, "Redirect");
|
||||
typeCombo->addItem(kIcmpEchoRequest, "Echo Request");
|
||||
typeCombo->addItem(kIcmpTimeExceeded, "Time Exceeded");
|
||||
typeCombo->addItem(kIcmpParameterProblem, "Parameter Problem");
|
||||
typeCombo->addItem(kIcmpTimestampRequest, "Timestamp Request");
|
||||
typeCombo->addItem(kIcmpTimestampReply, "Timestamp Reply");
|
||||
typeCombo->addItem(kIcmpInformationRequest, "Information Request");
|
||||
typeCombo->addItem(kIcmpInformationReply, "Information Reply");
|
||||
typeCombo->addItem(kIcmpAddressMaskRequest, "Address Mask Request");
|
||||
typeCombo->addItem(kIcmpAddressMaskReply, "Address Mask Reply");
|
||||
|
||||
icmp4Button->click();
|
||||
|
||||
idEdit->setValidator(new QIntValidator(0, 0xFFFF, this));
|
||||
seqEdit->setValidator(new QIntValidator(0, 0xFFFF, this));
|
||||
@ -69,7 +110,61 @@ IcmpConfigForm::IcmpConfigForm(QWidget *parent)
|
||||
|
||||
void IcmpConfigForm::on_typeCombo_currentIndexChanged(int /*index*/)
|
||||
{
|
||||
idSeqFrame->setVisible(idSeqSet.contains(typeCombo->currentValue()));
|
||||
idSeqFrame->setVisible(
|
||||
isIdSeqType(
|
||||
OstProto::Icmp::Version(versionGroup->checkedId()),
|
||||
typeCombo->currentValue()));
|
||||
}
|
||||
|
||||
void IcmpConfigForm::when_versionGroup_buttonClicked(int id)
|
||||
{
|
||||
int value = typeCombo->currentValue();
|
||||
|
||||
typeCombo->clear();
|
||||
|
||||
switch(id)
|
||||
{
|
||||
case OstProto::Icmp::kIcmp4:
|
||||
typeCombo->addItem(kIcmpEchoReply, "Echo Reply");
|
||||
typeCombo->addItem(kIcmpDestinationUnreachable,
|
||||
"Destination Unreachable");
|
||||
typeCombo->addItem(kIcmpSourceQuench, "Source Quench");
|
||||
typeCombo->addItem(kIcmpRedirect, "Redirect");
|
||||
typeCombo->addItem(kIcmpEchoRequest, "Echo Request");
|
||||
typeCombo->addItem(kIcmpTimeExceeded, "Time Exceeded");
|
||||
typeCombo->addItem(kIcmpParameterProblem, "Parameter Problem");
|
||||
typeCombo->addItem(kIcmpTimestampRequest, "Timestamp Request");
|
||||
typeCombo->addItem(kIcmpTimestampReply, "Timestamp Reply");
|
||||
typeCombo->addItem(kIcmpInformationRequest, "Information Request");
|
||||
typeCombo->addItem(kIcmpInformationReply, "Information Reply");
|
||||
typeCombo->addItem(kIcmpAddressMaskRequest, "Address Mask Request");
|
||||
typeCombo->addItem(kIcmpAddressMaskReply, "Address Mask Reply");
|
||||
break;
|
||||
|
||||
case OstProto::Icmp::kIcmp6:
|
||||
typeCombo->addItem(kIcmp6DestinationUnreachable,
|
||||
"Destination Unreachable");
|
||||
typeCombo->addItem(kIcmp6PacketTooBig, "Packet Too Big");
|
||||
typeCombo->addItem(kIcmp6TimeExceeded, "Time Exceeded");
|
||||
typeCombo->addItem(kIcmp6ParameterProblem, "Parameter Problem");
|
||||
|
||||
typeCombo->addItem(kIcmp6EchoRequest, "Echo Request");
|
||||
typeCombo->addItem(kIcmp6EchoReply, "Echo Reply");
|
||||
typeCombo->addItem(kIcmp6RouterSolicitation, "Router Solicitation");
|
||||
typeCombo->addItem(kIcmp6RouterAdvertisement, "Router Advertisement");
|
||||
typeCombo->addItem(kIcmp6NeighbourSolicitation,
|
||||
"Neighbour Solicitation");
|
||||
typeCombo->addItem(kIcmp6NeighbourAdvertisement,
|
||||
"Neighbour Advertisement");
|
||||
typeCombo->addItem(kIcmp6Redirect, "Redirect");
|
||||
typeCombo->addItem(kIcmp6InformationQuery, "Information Query");
|
||||
typeCombo->addItem(kIcmp6InformationResponse, "Information Response");
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
typeCombo->setValue(value);
|
||||
}
|
||||
|
||||
IcmpProtocol::IcmpProtocol(StreamBase *stream, AbstractProtocol *parent)
|
||||
@ -121,7 +216,13 @@ quint32 IcmpProtocol::protocolId(ProtocolIdType type) const
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case ProtocolIdIp: return 0x1;
|
||||
case ProtocolIdIp:
|
||||
switch(icmpVersion())
|
||||
{
|
||||
case OstProto::Icmp::kIcmp4: return 0x1;
|
||||
case OstProto::Icmp::kIcmp6: return 0x3A;
|
||||
default:break;
|
||||
}
|
||||
default:break;
|
||||
}
|
||||
|
||||
@ -137,7 +238,7 @@ int IcmpProtocol::frameFieldCount() const
|
||||
{
|
||||
int count;
|
||||
|
||||
if (idSeqSet.contains(fieldData(icmp_type, FieldValue).toUInt()))
|
||||
if (isIdSeqType(icmpVersion(), icmpType()))
|
||||
count = icmp_idSeqFrameFieldCount;
|
||||
else
|
||||
count = icmp_commonFrameFieldCount;
|
||||
@ -164,10 +265,11 @@ AbstractProtocol::FieldFlags IcmpProtocol::fieldFlags(int index) const
|
||||
|
||||
case icmp_identifier:
|
||||
case icmp_sequence:
|
||||
if (!idSeqSet.contains(fieldData(icmp_type, FieldValue).toUInt()))
|
||||
if (!isIdSeqType(icmpVersion(), icmpType()))
|
||||
flags &= ~FrameField;
|
||||
break;
|
||||
|
||||
case icmp_version:
|
||||
case icmp_is_override_checksum:
|
||||
flags &= ~FrameField;
|
||||
flags |= MetaField;
|
||||
@ -249,6 +351,12 @@ QVariant IcmpProtocol::fieldData(int index, FieldAttrib attrib,
|
||||
sum += (quint16) ~cks;
|
||||
cks = protocolFramePayloadCksum(streamIndex, CksumIp);
|
||||
sum += (quint16) ~cks;
|
||||
if (icmpVersion() == OstProto::Icmp::kIcmp6)
|
||||
{
|
||||
cks = protocolFrameHeaderCksum(streamIndex,
|
||||
CksumIpPseudo);
|
||||
sum += (quint16) ~cks;
|
||||
}
|
||||
|
||||
while(sum>>16)
|
||||
sum = (sum & 0xFFFF) + (sum >> 16);
|
||||
@ -333,6 +441,17 @@ QVariant IcmpProtocol::fieldData(int index, FieldAttrib attrib,
|
||||
|
||||
|
||||
// Meta fields
|
||||
case icmp_version:
|
||||
{
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldValue:
|
||||
return data.icmp_version();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case icmp_is_override_checksum:
|
||||
{
|
||||
switch(attrib)
|
||||
@ -398,6 +517,13 @@ bool IcmpProtocol::setFieldData(int index, const QVariant &value,
|
||||
data.set_sequence(seq);
|
||||
break;
|
||||
}
|
||||
case icmp_version:
|
||||
{
|
||||
int ver = value.toUInt(&isOk);
|
||||
if (isOk)
|
||||
data.set_icmp_version(OstProto::Icmp::Version(ver));
|
||||
break;
|
||||
}
|
||||
case icmp_is_override_checksum:
|
||||
{
|
||||
bool ovr = value.toBool();
|
||||
@ -430,6 +556,8 @@ void IcmpProtocol::loadConfigWidget()
|
||||
{
|
||||
configWidget();
|
||||
|
||||
configForm->versionGroup->button(icmpVersion())->click();
|
||||
|
||||
configForm->typeCombo->setValue(fieldData(icmp_type, FieldValue).toUInt());
|
||||
configForm->codeEdit->setText(fieldData(icmp_code, FieldValue).toString());
|
||||
|
||||
@ -450,6 +578,9 @@ void IcmpProtocol::storeConfigWidget()
|
||||
bool isOk;
|
||||
|
||||
configWidget();
|
||||
|
||||
setFieldData(icmp_version, configForm->versionGroup->checkedId());
|
||||
|
||||
setFieldData(icmp_type, configForm->typeCombo->currentValue());
|
||||
setFieldData(icmp_code, configForm->codeEdit->text());
|
||||
|
||||
|
@ -25,6 +25,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
#include "abstractprotocol.h"
|
||||
|
||||
#include <QButtonGroup>
|
||||
|
||||
/*
|
||||
Icmp Protocol Frame Format -
|
||||
+-----+------+------+------+-------+
|
||||
@ -39,9 +41,12 @@ class IcmpConfigForm : public QWidget, public Ui::Icmp
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QButtonGroup *versionGroup;
|
||||
|
||||
IcmpConfigForm(QWidget *parent = 0);
|
||||
private slots:
|
||||
void on_typeCombo_currentIndexChanged(int index);
|
||||
void when_versionGroup_buttonClicked(int id);
|
||||
};
|
||||
|
||||
class IcmpProtocol : public AbstractProtocol
|
||||
@ -63,10 +68,22 @@ private:
|
||||
|
||||
// Meta Fields
|
||||
icmp_is_override_checksum = icmp_idSeqFrameFieldCount,
|
||||
icmp_version,
|
||||
|
||||
icmp_fieldCount
|
||||
};
|
||||
|
||||
OstProto::Icmp::Version icmpVersion() const
|
||||
{
|
||||
return OstProto::Icmp::Version(
|
||||
fieldData(icmp_version, FieldValue).toUInt());
|
||||
}
|
||||
|
||||
int icmpType() const
|
||||
{
|
||||
return fieldData(icmp_type, FieldValue).toInt();
|
||||
}
|
||||
|
||||
public:
|
||||
IcmpProtocol(StreamBase *stream, AbstractProtocol *parent = 0);
|
||||
virtual ~IcmpProtocol();
|
||||
|
@ -24,13 +24,19 @@ package OstProto;
|
||||
// Icmp Protocol
|
||||
message Icmp {
|
||||
|
||||
optional bool is_override_checksum = 1;
|
||||
enum Version {
|
||||
kIcmp4 = 4;
|
||||
kIcmp6 = 6;
|
||||
}
|
||||
|
||||
optional uint32 type = 2 [default = 0x8]; // echo request
|
||||
optional uint32 code = 3;
|
||||
optional uint32 checksum = 4;
|
||||
optional uint32 identifier = 5 [default = 1234];
|
||||
optional uint32 sequence = 6;
|
||||
optional Version icmp_version = 1 [default = kIcmp4];
|
||||
optional bool is_override_checksum = 2;
|
||||
|
||||
optional uint32 type = 6 [default = 0x8]; // echo request
|
||||
optional uint32 code = 7;
|
||||
optional uint32 checksum = 8;
|
||||
optional uint32 identifier = 9 [default = 1234];
|
||||
optional uint32 sequence = 10;
|
||||
}
|
||||
|
||||
extend Protocol {
|
||||
|
@ -5,15 +5,38 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>291</width>
|
||||
<height>190</height>
|
||||
<width>373</width>
|
||||
<height>166</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<item row="0" column="0" >
|
||||
<item rowspan="3" row="0" column="0" >
|
||||
<widget class="QGroupBox" name="versionBox" >
|
||||
<property name="title" >
|
||||
<string>Version</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<item>
|
||||
<widget class="QRadioButton" name="icmp4Button" >
|
||||
<property name="text" >
|
||||
<string>ICMPv4</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="icmp6Button" >
|
||||
<property name="text" >
|
||||
<string>ICMPv6</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QLabel" name="label" >
|
||||
<property name="text" >
|
||||
<string>Type</string>
|
||||
@ -23,10 +46,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<item row="0" column="2" >
|
||||
<widget class="IntComboBox" name="typeCombo" />
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<item row="1" column="1" >
|
||||
<widget class="QLabel" name="label_2" >
|
||||
<property name="text" >
|
||||
<string>Code</string>
|
||||
@ -36,46 +59,43 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<item row="1" column="2" >
|
||||
<widget class="QLineEdit" name="codeEdit" />
|
||||
</item>
|
||||
<item row="2" column="0" >
|
||||
<widget class="QCheckBox" name="overrideCksum" >
|
||||
<property name="text" >
|
||||
<string>Checksum</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" >
|
||||
<widget class="QLineEdit" name="cksumEdit" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" >
|
||||
<item row="1" column="3" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<width>31</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2" >
|
||||
<widget class="QFrame" name="idSeqFrame" >
|
||||
<property name="frameShape" >
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
<item row="2" column="1" >
|
||||
<widget class="QCheckBox" name="overrideCksum" >
|
||||
<property name="text" >
|
||||
<string>Checksum</string>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<enum>QFrame::Plain</enum>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" >
|
||||
<widget class="QLineEdit" name="cksumEdit" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<item row="0" column="0" >
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3" >
|
||||
<widget class="QGroupBox" name="idSeqFrame" >
|
||||
<property name="title" >
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4" >
|
||||
<property name="text" >
|
||||
<string>Identifier</string>
|
||||
@ -85,10 +105,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<item>
|
||||
<widget class="QLineEdit" name="idEdit" />
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5" >
|
||||
<property name="text" >
|
||||
<string>Sequence</string>
|
||||
@ -98,21 +118,21 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<item>
|
||||
<widget class="QLineEdit" name="seqEdit" />
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2" >
|
||||
<item row="4" column="0" colspan="3" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>137</width>
|
||||
<height>16</height>
|
||||
<width>211</width>
|
||||
<height>71</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@ -127,6 +147,8 @@
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>icmp4Button</tabstop>
|
||||
<tabstop>icmp6Button</tabstop>
|
||||
<tabstop>typeCombo</tabstop>
|
||||
<tabstop>codeEdit</tabstop>
|
||||
<tabstop>overrideCksum</tabstop>
|
||||
|
Loading…
Reference in New Issue
Block a user