Implemented IPv6 protocol; found and fixed a bug in AbstractProtocol::protocolFrameValue() in the process
This commit is contained in:
parent
ed13bba83b
commit
4a70d52e3e
@ -147,8 +147,7 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
|
||||
|
||||
// TODO(MED):
|
||||
|
||||
//! \todo Implement then enable these protocols - IPv6, IGMP
|
||||
rbL3Ipv6->setHidden(true);
|
||||
//! \todo Implement then enable these protocols - IGMP
|
||||
rbL4Igmp->setHidden(true);
|
||||
//! \todo Enable navigation of streams
|
||||
pbPrev->setDisabled(true);
|
||||
@ -200,7 +199,7 @@ void StreamConfigDialog::setupUiExtra()
|
||||
#else
|
||||
bgProto[ProtoL3]->addButton(rbL3None, ButtonIdNone);
|
||||
bgProto[ProtoL3]->addButton(rbL3Ipv4, OstProto::Protocol::kIp4FieldNumber);
|
||||
bgProto[ProtoL3]->addButton(rbL3Ipv6, 0xFFFF);
|
||||
bgProto[ProtoL3]->addButton(rbL3Ipv6, OstProto::Protocol::kIp6FieldNumber);
|
||||
bgProto[ProtoL3]->addButton(rbL3Arp, OstProto::Protocol::kArpFieldNumber);
|
||||
bgProto[ProtoL3]->addButton(rbL3Ip4over4,
|
||||
OstProto::Protocol::kIp4over4FieldNumber);
|
||||
|
@ -249,7 +249,7 @@ AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int /*index*/) const
|
||||
|
||||
\note If a subclass uses any of the below functions to derive
|
||||
FieldFrameValue, the subclass should handle and return a value for
|
||||
FieldBitSize to prevent endless recrusion -
|
||||
FieldBitSize to prevent endless recursion -
|
||||
- protocolFrameCksum()
|
||||
- protocolFramePayloadSize()
|
||||
*/
|
||||
@ -454,7 +454,10 @@ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex, bool forCksum)
|
||||
}
|
||||
else
|
||||
field = fieldData(i, FieldFrameValue, streamIndex).toByteArray();
|
||||
qDebug("<<< %d, %d/%d >>>>", proto.size(), bits, field.size());
|
||||
qDebug("<<< (%d, %db) %s >>>", proto.size(), lastbitpos,
|
||||
QString(proto.toHex()).toAscii().constData());
|
||||
qDebug(" < (%db/%dB) %s >", bits, field.size(),
|
||||
QString(field.toHex()).toAscii().constData());
|
||||
|
||||
if (bits == (uint) field.size() * 8)
|
||||
{
|
||||
@ -465,10 +468,12 @@ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex, bool forCksum)
|
||||
Q_ASSERT(field.size() > 0);
|
||||
|
||||
char c = proto[proto.size() - 1];
|
||||
proto[proto.size() - 1] = c | (field.at(0) >> lastbitpos);
|
||||
proto[proto.size() - 1] =
|
||||
c | ((uchar)field.at(0) >> lastbitpos);
|
||||
for (int j = 0; j < field.size() - 1; j++)
|
||||
proto.append(field.at(j) << lastbitpos |
|
||||
field.at(j+1) >> lastbitpos);
|
||||
(uchar)field.at(j+1) >> lastbitpos);
|
||||
proto.append(field.at(field.size() - 1) << lastbitpos);
|
||||
}
|
||||
}
|
||||
else if (bits < (uint) field.size() * 8)
|
||||
|
939
common/ip6.cpp
Normal file
939
common/ip6.cpp
Normal file
@ -0,0 +1,939 @@
|
||||
/*
|
||||
Copyright (C) 2010 Srivats P.
|
||||
|
||||
This file is part of "Ostinato"
|
||||
|
||||
This is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include "ip6.h"
|
||||
|
||||
#include "ipv6addressvalidator.h"
|
||||
|
||||
#include <QHostAddress>
|
||||
#include <qendian.h>
|
||||
|
||||
Ip6ConfigForm::Ip6ConfigForm(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
version->setValidator(new QIntValidator(0, 0xF, this));
|
||||
payloadLength->setValidator(new QIntValidator(0, 0xFFFF, this));
|
||||
hopLimit->setValidator(new QIntValidator(0, 0xFF, this));
|
||||
|
||||
srcAddr->setValidator(new IPv6AddressValidator(this));
|
||||
srcAddrCount->setValidator(new QIntValidator(this));
|
||||
//srcAddrPrefix->setValidator(new QIntValidator(0, 128, this));
|
||||
|
||||
dstAddr->setValidator(new IPv6AddressValidator(this));
|
||||
dstAddrCount->setValidator(new QIntValidator(this));
|
||||
//dstAddrPrefix->setValidator(new QIntValidator(0, 128, this));
|
||||
}
|
||||
|
||||
void Ip6ConfigForm::on_srcAddr_editingFinished()
|
||||
{
|
||||
srcAddr->setText(QHostAddress(srcAddr->text()).toString());
|
||||
}
|
||||
|
||||
void Ip6ConfigForm::on_dstAddr_editingFinished()
|
||||
{
|
||||
dstAddr->setText(QHostAddress(dstAddr->text()).toString());
|
||||
}
|
||||
|
||||
void Ip6ConfigForm::on_srcAddrModeCombo_currentIndexChanged(int index)
|
||||
{
|
||||
bool enabled = (index > 0);
|
||||
|
||||
srcAddrCount->setEnabled(enabled);
|
||||
srcAddrPrefix->setEnabled(enabled);
|
||||
}
|
||||
|
||||
void Ip6ConfigForm::on_dstAddrModeCombo_currentIndexChanged(int index)
|
||||
{
|
||||
bool enabled = (index > 0);
|
||||
|
||||
dstAddrCount->setEnabled(enabled);
|
||||
dstAddrPrefix->setEnabled(enabled);
|
||||
}
|
||||
|
||||
Ip6Protocol::Ip6Protocol(StreamBase *stream, AbstractProtocol *parent)
|
||||
: AbstractProtocol(stream, parent)
|
||||
{
|
||||
/* The configWidget is created lazily */
|
||||
configForm = NULL;
|
||||
}
|
||||
|
||||
Ip6Protocol::~Ip6Protocol()
|
||||
{
|
||||
delete configForm;
|
||||
}
|
||||
|
||||
AbstractProtocol* Ip6Protocol::createInstance(StreamBase *stream,
|
||||
AbstractProtocol *parent)
|
||||
{
|
||||
return new Ip6Protocol(stream, parent);
|
||||
}
|
||||
|
||||
quint32 Ip6Protocol::protocolNumber() const
|
||||
{
|
||||
return OstProto::Protocol::kIp6FieldNumber;
|
||||
}
|
||||
|
||||
void Ip6Protocol::protoDataCopyInto(OstProto::Protocol &protocol) const
|
||||
{
|
||||
protocol.MutableExtension(OstProto::ip6)->CopyFrom(data);
|
||||
protocol.mutable_protocol_id()->set_id(protocolNumber());
|
||||
}
|
||||
|
||||
void Ip6Protocol::protoDataCopyFrom(const OstProto::Protocol &protocol)
|
||||
{
|
||||
if (protocol.protocol_id().id() == protocolNumber() &&
|
||||
protocol.HasExtension(OstProto::ip6))
|
||||
data.MergeFrom(protocol.GetExtension(OstProto::ip6));
|
||||
}
|
||||
|
||||
QString Ip6Protocol::name() const
|
||||
{
|
||||
return QString("Internet Protocol ver 6");
|
||||
}
|
||||
|
||||
QString Ip6Protocol::shortName() const
|
||||
{
|
||||
return QString("IPv6");
|
||||
}
|
||||
|
||||
AbstractProtocol::ProtocolIdType Ip6Protocol::protocolIdType() const
|
||||
{
|
||||
return ProtocolIdIp;
|
||||
}
|
||||
|
||||
quint32 Ip6Protocol::protocolId(ProtocolIdType type) const
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case ProtocolIdEth: return 0x86dd;
|
||||
case ProtocolIdIp: return 0x29;
|
||||
default:break;
|
||||
}
|
||||
|
||||
return AbstractProtocol::protocolId(type);
|
||||
}
|
||||
|
||||
int Ip6Protocol::fieldCount() const
|
||||
{
|
||||
return ip6_fieldCount;
|
||||
}
|
||||
|
||||
AbstractProtocol::FieldFlags Ip6Protocol::fieldFlags(int index) const
|
||||
{
|
||||
AbstractProtocol::FieldFlags flags;
|
||||
|
||||
flags = AbstractProtocol::fieldFlags(index);
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case ip6_version:
|
||||
case ip6_trafficClass:
|
||||
case ip6_flowLabel:
|
||||
case ip6_payloadLength:
|
||||
case ip6_nextHeader:
|
||||
case ip6_hopLimit:
|
||||
case ip6_srcAddress:
|
||||
case ip6_dstAddress:
|
||||
break;
|
||||
|
||||
case ip6_isOverrideVersion:
|
||||
case ip6_isOverridePayloadLength:
|
||||
case ip6_isOverrideNextHeader:
|
||||
|
||||
case ip6_srcAddrMode:
|
||||
case ip6_srcAddrCount:
|
||||
case ip6_srcAddrPrefix:
|
||||
|
||||
case ip6_dstAddrMode:
|
||||
case ip6_dstAddrCount:
|
||||
case ip6_dstAddrPrefix:
|
||||
flags |= FieldIsMeta;
|
||||
break;
|
||||
|
||||
default:
|
||||
qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__,
|
||||
index);
|
||||
break;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
QVariant Ip6Protocol::fieldData(int index, FieldAttrib attrib,
|
||||
int streamIndex) const
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case ip6_version:
|
||||
{
|
||||
quint8 ver;
|
||||
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldValue:
|
||||
case FieldFrameValue:
|
||||
case FieldTextValue:
|
||||
if (data.is_override_version())
|
||||
ver = data.version() & 0xF;
|
||||
else
|
||||
ver = 0x6;
|
||||
break;
|
||||
default:
|
||||
ver = 0; // avoid the 'maybe used unitialized' warning
|
||||
break;
|
||||
}
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldName:
|
||||
return QString("Version");
|
||||
case FieldValue:
|
||||
return ver;
|
||||
case FieldTextValue:
|
||||
return QString("%1").arg(ver);
|
||||
case FieldFrameValue:
|
||||
return QByteArray(1, char(ver));
|
||||
case FieldBitSize:
|
||||
return 4;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ip6_trafficClass:
|
||||
{
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldName:
|
||||
return QString("Traffic Class");
|
||||
case FieldValue:
|
||||
return data.traffic_class() & 0xFF;
|
||||
case FieldTextValue:
|
||||
return QString("%1").arg(data.traffic_class() & 0xFF,
|
||||
2, BASE_HEX, QChar('0'));
|
||||
case FieldFrameValue:
|
||||
return QByteArray(1, char(data.traffic_class() & 0xFF));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ip6_flowLabel:
|
||||
{
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldName:
|
||||
return QString("Flow Label");
|
||||
case FieldValue:
|
||||
return data.flow_label() & 0xFFFFF;
|
||||
case FieldTextValue:
|
||||
return QString("%1").arg(data.flow_label() & 0xFFFFF,
|
||||
5, BASE_HEX, QChar('0'));
|
||||
case FieldFrameValue:
|
||||
{
|
||||
QByteArray fv;
|
||||
fv.resize(4);
|
||||
qToBigEndian((quint32) data.flow_label() & 0xFFFFF,
|
||||
(uchar*) fv.data());
|
||||
fv = fv.right(3);
|
||||
return fv;
|
||||
}
|
||||
case FieldBitSize:
|
||||
return 20;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ip6_payloadLength:
|
||||
{
|
||||
quint16 len;
|
||||
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldValue:
|
||||
case FieldFrameValue:
|
||||
case FieldTextValue:
|
||||
if (data.is_override_payload_length())
|
||||
len = data.payload_length();
|
||||
else
|
||||
len = protocolFramePayloadSize(streamIndex);
|
||||
break;
|
||||
default:
|
||||
len = 0; // avoid the 'maybe used unitialized' warning
|
||||
break;
|
||||
}
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldName:
|
||||
return QString("Payload Length");
|
||||
case FieldValue:
|
||||
return len;
|
||||
case FieldFrameValue:
|
||||
{
|
||||
QByteArray fv;
|
||||
fv.resize(2);
|
||||
qToBigEndian(len, (uchar*) fv.data());
|
||||
return fv;
|
||||
}
|
||||
case FieldTextValue:
|
||||
return QString("%1").arg(len);
|
||||
case FieldBitSize:
|
||||
return 16;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ip6_nextHeader:
|
||||
{
|
||||
quint8 nextHdr;
|
||||
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldValue:
|
||||
case FieldFrameValue:
|
||||
case FieldTextValue:
|
||||
if (data.is_override_next_header())
|
||||
nextHdr = data.next_header();
|
||||
else
|
||||
nextHdr = payloadProtocolId(ProtocolIdIp);
|
||||
break;
|
||||
default:
|
||||
nextHdr = 0; // avoid the 'maybe used unitialized' warning
|
||||
break;
|
||||
}
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldName:
|
||||
return QString("Next Header");
|
||||
case FieldValue:
|
||||
return nextHdr;
|
||||
case FieldTextValue:
|
||||
return QString("%1").arg(nextHdr, 2, BASE_HEX, QChar('0'));
|
||||
case FieldFrameValue:
|
||||
return QByteArray(1, char(nextHdr));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ip6_hopLimit:
|
||||
{
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldName:
|
||||
return QString("Hop Limit");
|
||||
case FieldValue:
|
||||
return data.hop_limit() & 0xFF;
|
||||
case FieldTextValue:
|
||||
return QString("%1").arg(data.hop_limit() & 0xFF);
|
||||
case FieldFrameValue:
|
||||
return QByteArray(1, char(data.hop_limit() & 0xFF));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ip6_srcAddress:
|
||||
{
|
||||
int u, p, q;
|
||||
quint64 maskHi = 0, maskLo = 0;
|
||||
quint64 prefixHi, prefixLo;
|
||||
quint64 hostHi, hostLo;
|
||||
quint64 srcHi = 0, srcLo = 0;
|
||||
|
||||
switch(data.src_addr_mode())
|
||||
{
|
||||
case OstProto::Ip6::kFixed:
|
||||
srcHi = data.src_addr_hi();
|
||||
srcLo = data.src_addr_lo();
|
||||
break;
|
||||
case OstProto::Ip6::kIncHost:
|
||||
case OstProto::Ip6::kDecHost:
|
||||
case OstProto::Ip6::kRandomHost:
|
||||
u = streamIndex % data.src_addr_count();
|
||||
if (data.src_addr_prefix() > 64) {
|
||||
p = 64;
|
||||
q = data.src_addr_prefix() - 64;
|
||||
} else {
|
||||
p = data.src_addr_prefix();
|
||||
q = 0;
|
||||
}
|
||||
if (p > 0)
|
||||
maskHi = ~((quint64(1) << p) - 1);
|
||||
if (q > 0)
|
||||
maskLo = ~((quint64(1) << q) - 1);
|
||||
prefixHi = data.src_addr_hi() & maskHi;
|
||||
prefixLo = data.src_addr_lo() & maskLo;
|
||||
if (data.src_addr_mode() == OstProto::Ip6::kIncHost) {
|
||||
hostHi = ((data.src_addr_hi() & ~maskHi) + u) & ~maskHi;
|
||||
hostLo = ((data.src_addr_lo() & ~maskLo) + u) & ~maskLo;
|
||||
}
|
||||
else if (data.src_addr_mode() == OstProto::Ip6::kDecHost) {
|
||||
hostHi = ((data.src_addr_hi() & ~maskHi) - u) & ~maskHi;
|
||||
hostLo = ((data.src_addr_lo() & ~maskLo) - u) & ~maskLo;
|
||||
}
|
||||
else if (data.src_addr_mode()==OstProto::Ip6::kRandomHost) {
|
||||
hostHi = qrand() & ~maskHi;
|
||||
hostLo = qrand() & ~maskLo;
|
||||
}
|
||||
srcHi = prefixHi | hostHi;
|
||||
srcLo = prefixLo | hostLo;
|
||||
break;
|
||||
default:
|
||||
qWarning("Unhandled src_addr_mode = %d",
|
||||
data.src_addr_mode());
|
||||
}
|
||||
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldName:
|
||||
return QString("Source");
|
||||
case FieldValue:
|
||||
case FieldFrameValue:
|
||||
case FieldTextValue:
|
||||
{
|
||||
QByteArray fv;
|
||||
fv.resize(16);
|
||||
qToBigEndian(srcHi, (uchar*) fv.data());
|
||||
qToBigEndian(srcLo, (uchar*) (fv.data() + 8));
|
||||
if (attrib == FieldTextValue)
|
||||
return QHostAddress((quint8*)fv.constData()).toString();
|
||||
else
|
||||
return fv;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ip6_dstAddress:
|
||||
{
|
||||
int u, p, q;
|
||||
quint64 maskHi = 0, maskLo = 0;
|
||||
quint64 prefixHi, prefixLo;
|
||||
quint64 hostHi, hostLo;
|
||||
quint64 dstHi = 0, dstLo = 0;
|
||||
|
||||
switch(data.dst_addr_mode())
|
||||
{
|
||||
case OstProto::Ip6::kFixed:
|
||||
dstHi = data.dst_addr_hi();
|
||||
dstLo = data.dst_addr_lo();
|
||||
break;
|
||||
case OstProto::Ip6::kIncHost:
|
||||
case OstProto::Ip6::kDecHost:
|
||||
case OstProto::Ip6::kRandomHost:
|
||||
u = streamIndex % data.dst_addr_count();
|
||||
if (data.dst_addr_prefix() > 64) {
|
||||
p = 64;
|
||||
q = data.dst_addr_prefix() - 64;
|
||||
} else {
|
||||
p = data.dst_addr_prefix();
|
||||
q = 0;
|
||||
}
|
||||
if (p > 0)
|
||||
maskHi = ~((quint64(1) << p) - 1);
|
||||
if (q > 0)
|
||||
maskLo = ~((quint64(1) << q) - 1);
|
||||
prefixHi = data.dst_addr_hi() & maskHi;
|
||||
prefixLo = data.dst_addr_lo() & maskLo;
|
||||
if (data.dst_addr_mode() == OstProto::Ip6::kIncHost) {
|
||||
hostHi = ((data.dst_addr_hi() & ~maskHi) + u) & ~maskHi;
|
||||
hostLo = ((data.dst_addr_lo() & ~maskLo) + u) & ~maskLo;
|
||||
}
|
||||
else if (data.dst_addr_mode() == OstProto::Ip6::kDecHost) {
|
||||
hostHi = ((data.dst_addr_hi() & ~maskHi) - u) & ~maskHi;
|
||||
hostLo = ((data.dst_addr_lo() & ~maskLo) - u) & ~maskLo;
|
||||
}
|
||||
else if (data.dst_addr_mode()==OstProto::Ip6::kRandomHost) {
|
||||
hostHi = qrand() & ~maskHi;
|
||||
hostLo = qrand() & ~maskLo;
|
||||
}
|
||||
dstHi = prefixHi | hostHi;
|
||||
dstLo = prefixLo | hostLo;
|
||||
break;
|
||||
default:
|
||||
qWarning("Unhandled dst_addr_mode = %d",
|
||||
data.dst_addr_mode());
|
||||
}
|
||||
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldName:
|
||||
return QString("Destination");
|
||||
case FieldValue:
|
||||
case FieldFrameValue:
|
||||
case FieldTextValue:
|
||||
{
|
||||
QByteArray fv;
|
||||
fv.resize(16);
|
||||
qToBigEndian(dstHi, (uchar*) fv.data());
|
||||
qToBigEndian(dstLo, (uchar*) (fv.data() + 8));
|
||||
if (attrib == FieldTextValue)
|
||||
return QHostAddress((quint8*)fv.constData()).toString();
|
||||
else
|
||||
return fv;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Meta-Fields
|
||||
case ip6_isOverrideVersion:
|
||||
{
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldValue:
|
||||
return data.is_override_version();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ip6_isOverridePayloadLength:
|
||||
{
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldValue:
|
||||
return data.is_override_payload_length();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ip6_isOverrideNextHeader:
|
||||
{
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldValue:
|
||||
return data.is_override_next_header();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ip6_srcAddrMode:
|
||||
{
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldValue:
|
||||
return data.src_addr_mode();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ip6_srcAddrCount:
|
||||
{
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldValue:
|
||||
return data.src_addr_count();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ip6_srcAddrPrefix:
|
||||
{
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldValue:
|
||||
return data.src_addr_prefix();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ip6_dstAddrMode:
|
||||
{
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldValue:
|
||||
return data.dst_addr_mode();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ip6_dstAddrCount:
|
||||
{
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldValue:
|
||||
return data.dst_addr_count();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ip6_dstAddrPrefix:
|
||||
{
|
||||
switch(attrib)
|
||||
{
|
||||
case FieldValue:
|
||||
return data.dst_addr_prefix();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__,
|
||||
index);
|
||||
break;
|
||||
}
|
||||
|
||||
return AbstractProtocol::fieldData(index, attrib, streamIndex);
|
||||
}
|
||||
|
||||
bool Ip6Protocol::setFieldData(int index, const QVariant &value,
|
||||
FieldAttrib attrib)
|
||||
{
|
||||
bool isOk = false;
|
||||
|
||||
if (attrib != FieldValue)
|
||||
goto _exit;
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case ip6_version:
|
||||
{
|
||||
uint ver = value.toUInt(&isOk);
|
||||
if (isOk)
|
||||
data.set_version(ver & 0xF);
|
||||
break;
|
||||
}
|
||||
case ip6_trafficClass:
|
||||
{
|
||||
uint trfClass = value.toUInt(&isOk);
|
||||
if (isOk)
|
||||
data.set_traffic_class(trfClass & 0xFF);
|
||||
break;
|
||||
}
|
||||
case ip6_flowLabel:
|
||||
{
|
||||
uint fl = value.toUInt(&isOk);
|
||||
if (isOk)
|
||||
data.set_flow_label(fl & 0xFFFFF);
|
||||
break;
|
||||
}
|
||||
case ip6_payloadLength:
|
||||
{
|
||||
uint len = value.toUInt(&isOk);
|
||||
if (isOk)
|
||||
data.set_payload_length(len & 0xFFFF);
|
||||
break;
|
||||
}
|
||||
case ip6_nextHeader:
|
||||
{
|
||||
uint ver = value.toUInt(&isOk);
|
||||
if (isOk)
|
||||
data.set_next_header(ver & 0xFF);
|
||||
break;
|
||||
}
|
||||
case ip6_hopLimit:
|
||||
{
|
||||
uint hl = value.toUInt(&isOk);
|
||||
if (isOk)
|
||||
data.set_hop_limit(hl & 0xFF);
|
||||
break;
|
||||
}
|
||||
case ip6_srcAddress:
|
||||
{
|
||||
Q_IPV6ADDR addr = QHostAddress(value.toString()).toIPv6Address();
|
||||
quint64 x;
|
||||
|
||||
x = (quint64(addr[0]) << 56)
|
||||
| (quint64(addr[1]) << 48)
|
||||
| (quint64(addr[2]) << 40)
|
||||
| (quint64(addr[3]) << 32)
|
||||
| (quint64(addr[4]) << 24)
|
||||
| (quint64(addr[5]) << 16)
|
||||
| (quint64(addr[6]) << 8)
|
||||
| (quint64(addr[7]) << 0);
|
||||
data.set_src_addr_hi(x);
|
||||
|
||||
x = (quint64(addr[ 8]) << 56)
|
||||
| (quint64(addr[ 9]) << 48)
|
||||
| (quint64(addr[10]) << 40)
|
||||
| (quint64(addr[11]) << 32)
|
||||
| (quint64(addr[12]) << 24)
|
||||
| (quint64(addr[13]) << 16)
|
||||
| (quint64(addr[14]) << 8)
|
||||
| (quint64(addr[15]) << 0);
|
||||
data.set_src_addr_lo(x);
|
||||
break;
|
||||
}
|
||||
case ip6_dstAddress:
|
||||
{
|
||||
Q_IPV6ADDR addr = QHostAddress(value.toString()).toIPv6Address();
|
||||
quint64 x;
|
||||
|
||||
x = (quint64(addr[0]) << 56)
|
||||
| (quint64(addr[1]) << 48)
|
||||
| (quint64(addr[2]) << 40)
|
||||
| (quint64(addr[3]) << 32)
|
||||
| (quint64(addr[4]) << 24)
|
||||
| (quint64(addr[5]) << 16)
|
||||
| (quint64(addr[6]) << 8)
|
||||
| (quint64(addr[7]) << 0);
|
||||
data.set_dst_addr_hi(x);
|
||||
|
||||
x = (quint64(addr[ 8]) << 56)
|
||||
| (quint64(addr[ 9]) << 48)
|
||||
| (quint64(addr[10]) << 40)
|
||||
| (quint64(addr[11]) << 32)
|
||||
| (quint64(addr[12]) << 24)
|
||||
| (quint64(addr[13]) << 16)
|
||||
| (quint64(addr[14]) << 8)
|
||||
| (quint64(addr[15]) << 0);
|
||||
data.set_dst_addr_lo(x);
|
||||
break;
|
||||
}
|
||||
|
||||
// Meta-Fields
|
||||
case ip6_isOverrideVersion:
|
||||
{
|
||||
bool ovr = value.toBool();
|
||||
data.set_is_override_version(ovr);
|
||||
isOk = true;
|
||||
break;
|
||||
}
|
||||
case ip6_isOverridePayloadLength:
|
||||
{
|
||||
bool ovr = value.toBool();
|
||||
data.set_is_override_payload_length(ovr);
|
||||
isOk = true;
|
||||
break;
|
||||
}
|
||||
case ip6_isOverrideNextHeader:
|
||||
{
|
||||
bool ovr = value.toBool();
|
||||
data.set_is_override_next_header(ovr);
|
||||
isOk = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case ip6_srcAddrMode:
|
||||
{
|
||||
uint mode = value.toUInt(&isOk);
|
||||
if (isOk && data.AddrMode_IsValid(mode))
|
||||
data.set_src_addr_mode((OstProto::Ip6::AddrMode) mode);
|
||||
else
|
||||
isOk = false;
|
||||
break;
|
||||
}
|
||||
case ip6_srcAddrCount:
|
||||
{
|
||||
uint count = value.toUInt(&isOk);
|
||||
if (isOk)
|
||||
data.set_src_addr_count(count);
|
||||
break;
|
||||
}
|
||||
case ip6_srcAddrPrefix:
|
||||
{
|
||||
uint prefix = value.toUInt(&isOk);
|
||||
if (isOk)
|
||||
data.set_src_addr_prefix(prefix);
|
||||
break;
|
||||
}
|
||||
|
||||
case ip6_dstAddrMode:
|
||||
{
|
||||
uint mode = value.toUInt(&isOk);
|
||||
if (isOk && data.AddrMode_IsValid(mode))
|
||||
data.set_dst_addr_mode((OstProto::Ip6::AddrMode) mode);
|
||||
else
|
||||
isOk = false;
|
||||
break;
|
||||
}
|
||||
case ip6_dstAddrCount:
|
||||
{
|
||||
uint count = value.toUInt(&isOk);
|
||||
if (isOk)
|
||||
data.set_dst_addr_count(count);
|
||||
break;
|
||||
}
|
||||
case ip6_dstAddrPrefix:
|
||||
{
|
||||
uint prefix = value.toUInt(&isOk);
|
||||
if (isOk)
|
||||
data.set_dst_addr_prefix(prefix);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__,
|
||||
index);
|
||||
break;
|
||||
}
|
||||
|
||||
_exit:
|
||||
return isOk;
|
||||
}
|
||||
|
||||
bool Ip6Protocol::isProtocolFrameValueVariable() const
|
||||
{
|
||||
if ((data.src_addr_mode() != OstProto::Ip6::kFixed)
|
||||
|| (data.dst_addr_mode() != OstProto::Ip6::kFixed))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
quint32 Ip6Protocol::protocolFrameCksum(int streamIndex,
|
||||
CksumType cksumType) const
|
||||
{
|
||||
if (cksumType == CksumIpPseudo)
|
||||
{
|
||||
QByteArray addr;
|
||||
quint32 sum = 0;
|
||||
|
||||
addr = fieldData(ip6_srcAddress, FieldFrameValue, streamIndex)
|
||||
.toByteArray();
|
||||
Q_ASSERT(addr.size() == 16);
|
||||
for (int i = 0; i < addr.size(); i+=2)
|
||||
sum += (addr.at(i) << 8) + addr.at(i+1);
|
||||
|
||||
addr = fieldData(ip6_dstAddress, FieldFrameValue, streamIndex)
|
||||
.toByteArray();
|
||||
Q_ASSERT(addr.size() == 16);
|
||||
for (int i = 0; i < addr.size(); i+=2)
|
||||
sum += (addr.at(i) << 8) + addr.at(i+1);
|
||||
|
||||
sum += fieldData(ip6_payloadLength, FieldValue, streamIndex)
|
||||
.toUInt() & 0xFFFF;
|
||||
sum += fieldData(ip6_nextHeader, FieldValue, streamIndex)
|
||||
.toUInt() & 0xFF;
|
||||
|
||||
while(sum>>16)
|
||||
sum = (sum & 0xFFFF) + (sum >> 16);
|
||||
|
||||
return ~sum;
|
||||
}
|
||||
return AbstractProtocol::protocolFrameCksum(streamIndex, cksumType);
|
||||
}
|
||||
|
||||
QWidget* Ip6Protocol::configWidget()
|
||||
{
|
||||
/* Lazy creation of the configWidget */
|
||||
if (configForm == NULL)
|
||||
{
|
||||
configForm = new Ip6ConfigForm;
|
||||
loadConfigWidget();
|
||||
}
|
||||
|
||||
return configForm;
|
||||
}
|
||||
|
||||
void Ip6Protocol::loadConfigWidget()
|
||||
{
|
||||
configWidget();
|
||||
|
||||
configForm->isVersionOverride->setChecked(
|
||||
fieldData(ip6_isOverrideVersion, FieldValue).toBool());
|
||||
configForm->version->setText(
|
||||
fieldData(ip6_version, FieldValue).toString());
|
||||
|
||||
configForm->trafficClass->setText(uintToHexStr(
|
||||
fieldData(ip6_trafficClass, FieldValue).toUInt(), 1));
|
||||
|
||||
configForm->flowLabel->setText(QString("%1").arg(
|
||||
fieldData(ip6_flowLabel, FieldValue).toUInt(),5, BASE_HEX, QChar('0')));
|
||||
|
||||
configForm->isPayloadLengthOverride->setChecked(
|
||||
fieldData(ip6_isOverridePayloadLength, FieldValue).toBool());
|
||||
configForm->payloadLength->setText(
|
||||
fieldData(ip6_payloadLength, FieldValue).toString());
|
||||
|
||||
configForm->isNextHeaderOverride->setChecked(
|
||||
fieldData(ip6_isOverrideNextHeader, FieldValue).toBool());
|
||||
configForm->nextHeader->setText(uintToHexStr(
|
||||
fieldData(ip6_nextHeader, FieldValue).toUInt(), 1));
|
||||
|
||||
configForm->hopLimit->setText(
|
||||
fieldData(ip6_hopLimit, FieldValue).toString());
|
||||
|
||||
configForm->srcAddr->setText(
|
||||
fieldData(ip6_srcAddress, FieldTextValue).toString());
|
||||
configForm->srcAddrModeCombo->setCurrentIndex(
|
||||
fieldData(ip6_srcAddrMode, FieldValue).toUInt());
|
||||
configForm->srcAddrCount->setText(
|
||||
fieldData(ip6_srcAddrCount, FieldValue).toString());
|
||||
configForm->srcAddrPrefix->setText(
|
||||
fieldData(ip6_srcAddrPrefix, FieldValue).toString());
|
||||
|
||||
configForm->dstAddr->setText(
|
||||
fieldData(ip6_dstAddress, FieldTextValue).toString());
|
||||
configForm->dstAddrModeCombo->setCurrentIndex(
|
||||
fieldData(ip6_dstAddrMode, FieldValue).toUInt());
|
||||
configForm->dstAddrCount->setText(
|
||||
fieldData(ip6_dstAddrCount, FieldValue).toString());
|
||||
configForm->dstAddrPrefix->setText(
|
||||
fieldData(ip6_dstAddrPrefix, FieldValue).toString());
|
||||
}
|
||||
|
||||
void Ip6Protocol::storeConfigWidget()
|
||||
{
|
||||
bool isOk;
|
||||
|
||||
configWidget();
|
||||
|
||||
setFieldData(ip6_isOverrideVersion,
|
||||
configForm->isVersionOverride->isChecked());
|
||||
setFieldData(ip6_version, configForm->version->text());
|
||||
|
||||
setFieldData(ip6_trafficClass,
|
||||
configForm->trafficClass->text().remove(QChar(' ')).toUInt(&isOk, BASE_HEX));
|
||||
|
||||
setFieldData(ip6_flowLabel,
|
||||
configForm->flowLabel->text().remove(QChar(' ')).toUInt(&isOk, BASE_HEX));
|
||||
|
||||
setFieldData(ip6_isOverridePayloadLength,
|
||||
configForm->isPayloadLengthOverride->isChecked());
|
||||
setFieldData(ip6_payloadLength, configForm->payloadLength->text());
|
||||
|
||||
setFieldData(ip6_isOverrideNextHeader,
|
||||
configForm->isNextHeaderOverride->isChecked());
|
||||
setFieldData(ip6_nextHeader,
|
||||
configForm->nextHeader->text().remove(QChar(' ')).toUInt(&isOk, BASE_HEX));
|
||||
|
||||
setFieldData(ip6_hopLimit, configForm->hopLimit->text());
|
||||
|
||||
setFieldData(ip6_srcAddress, configForm->srcAddr->text());
|
||||
setFieldData(ip6_srcAddrMode, configForm->srcAddrModeCombo->currentIndex());
|
||||
setFieldData(ip6_srcAddrCount, configForm->srcAddrCount->text());
|
||||
setFieldData(ip6_srcAddrPrefix, configForm->srcAddrPrefix->text());
|
||||
|
||||
setFieldData(ip6_dstAddress, configForm->dstAddr->text());
|
||||
setFieldData(ip6_dstAddrMode, configForm->dstAddrModeCombo->currentIndex());
|
||||
setFieldData(ip6_dstAddrCount, configForm->dstAddrCount->text());
|
||||
setFieldData(ip6_dstAddrPrefix, configForm->dstAddrPrefix->text());
|
||||
}
|
||||
|
130
common/ip6.h
Normal file
130
common/ip6.h
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
Copyright (C) 2010 Srivats P.
|
||||
|
||||
This file is part of "Ostinato"
|
||||
|
||||
This is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef _IP6_H
|
||||
#define _IP6_H
|
||||
|
||||
#include "ip6.pb.h"
|
||||
#include "ui_ip6.h"
|
||||
|
||||
#include "abstractprotocol.h"
|
||||
|
||||
/*
|
||||
IPv6 Protocol Frame Format -
|
||||
+-----+----------+-----------------------+
|
||||
| Ver | TrfClass | FlowLabel |
|
||||
| (4) | (8) | (20) |
|
||||
+-----+-------------+---------+----------+
|
||||
| Payload Length | NextHdr | HopLimit |
|
||||
| (16) | (8) | (8) |
|
||||
+-------------------+---------+----------+
|
||||
| |
|
||||
| Source Address |
|
||||
| (128) |
|
||||
| |
|
||||
+-----+------+------+------+------+------+
|
||||
| |
|
||||
| Destination Address |
|
||||
| (128) |
|
||||
| |
|
||||
+-----+------+------+------+------+------+
|
||||
Figures in brackets represent field width in bits
|
||||
*/
|
||||
|
||||
class Ip6ConfigForm : public QWidget, public Ui::Ip6
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Ip6ConfigForm(QWidget *parent = 0);
|
||||
private slots:
|
||||
void on_srcAddr_editingFinished();
|
||||
void on_dstAddr_editingFinished();
|
||||
void on_srcAddrModeCombo_currentIndexChanged(int index);
|
||||
void on_dstAddrModeCombo_currentIndexChanged(int index);
|
||||
};
|
||||
|
||||
class Ip6Protocol : public AbstractProtocol
|
||||
{
|
||||
private:
|
||||
OstProto::Ip6 data;
|
||||
Ip6ConfigForm *configForm;
|
||||
enum ip6field
|
||||
{
|
||||
// Frame Fields
|
||||
ip6_version = 0,
|
||||
ip6_trafficClass,
|
||||
ip6_flowLabel,
|
||||
ip6_payloadLength,
|
||||
ip6_nextHeader,
|
||||
ip6_hopLimit,
|
||||
ip6_srcAddress,
|
||||
ip6_dstAddress,
|
||||
|
||||
// Meta Fields
|
||||
ip6_isOverrideVersion,
|
||||
ip6_isOverridePayloadLength,
|
||||
ip6_isOverrideNextHeader,
|
||||
|
||||
ip6_srcAddrMode,
|
||||
ip6_srcAddrCount,
|
||||
ip6_srcAddrPrefix,
|
||||
|
||||
ip6_dstAddrMode,
|
||||
ip6_dstAddrCount,
|
||||
ip6_dstAddrPrefix,
|
||||
|
||||
ip6_fieldCount
|
||||
};
|
||||
|
||||
public:
|
||||
Ip6Protocol(StreamBase *stream, AbstractProtocol *parent = 0);
|
||||
virtual ~Ip6Protocol();
|
||||
|
||||
static AbstractProtocol* createInstance(StreamBase *stream,
|
||||
AbstractProtocol *parent = 0);
|
||||
virtual quint32 protocolNumber() const;
|
||||
|
||||
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const;
|
||||
virtual void protoDataCopyFrom(const OstProto::Protocol &protocol);
|
||||
|
||||
virtual ProtocolIdType protocolIdType() const;
|
||||
virtual quint32 protocolId(ProtocolIdType type) const;
|
||||
|
||||
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 bool isProtocolFrameValueVariable() const;
|
||||
|
||||
virtual quint32 protocolFrameCksum(int streamIndex = 0,
|
||||
CksumType cksumType = CksumIp) const;
|
||||
|
||||
virtual QWidget* configWidget();
|
||||
virtual void loadConfigWidget();
|
||||
virtual void storeConfigWidget();
|
||||
};
|
||||
|
||||
#endif
|
61
common/ip6.proto
Normal file
61
common/ip6.proto
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright (C) 2010 Srivats P.
|
||||
|
||||
This file is part of "Ostinato"
|
||||
|
||||
This is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
import "protocol.proto";
|
||||
|
||||
package OstProto;
|
||||
|
||||
// Ip6 Protocol
|
||||
message Ip6 {
|
||||
|
||||
enum AddrMode {
|
||||
kFixed = 0;
|
||||
kIncHost = 1;
|
||||
kDecHost = 2;
|
||||
kRandomHost = 3;
|
||||
}
|
||||
|
||||
optional bool is_override_version = 1;
|
||||
optional bool is_override_payload_length = 2;
|
||||
optional bool is_override_next_header = 3;
|
||||
|
||||
optional uint32 version = 4 [default = 0x6];
|
||||
optional uint32 traffic_class = 5;
|
||||
optional uint32 flow_label = 6;
|
||||
|
||||
optional uint32 payload_length = 7;
|
||||
optional uint32 next_header = 8;
|
||||
optional uint32 hop_limit = 9 [default = 127];
|
||||
|
||||
optional uint64 src_addr_hi = 10;
|
||||
optional uint64 src_addr_lo = 11;
|
||||
optional AddrMode src_addr_mode = 12 [default = kFixed];
|
||||
optional uint32 src_addr_count = 13 [default = 16];
|
||||
optional uint32 src_addr_prefix = 14 [default = 64];
|
||||
|
||||
optional uint64 dst_addr_hi = 15;
|
||||
optional uint64 dst_addr_lo = 16;
|
||||
optional AddrMode dst_addr_mode = 17 [default = kFixed];
|
||||
optional uint32 dst_addr_count = 18 [default = 16];
|
||||
optional uint32 dst_addr_prefix = 19 [default = 64];
|
||||
}
|
||||
|
||||
extend Protocol {
|
||||
optional Ip6 ip6 = 133;
|
||||
}
|
467
common/ip6.ui
Normal file
467
common/ip6.ui
Normal file
@ -0,0 +1,467 @@
|
||||
<ui version="4.0" >
|
||||
<class>Ip6</class>
|
||||
<widget class="QWidget" name="Ip6" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>506</width>
|
||||
<height>233</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<item>
|
||||
<layout class="QGridLayout" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="QCheckBox" name="isVersionOverride" >
|
||||
<property name="text" >
|
||||
<string>Version</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QLineEdit" name="version" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="inputMask" >
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item rowspan="3" row="0" column="2" >
|
||||
<widget class="Line" name="line" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3" >
|
||||
<widget class="QCheckBox" name="isPayloadLengthOverride" >
|
||||
<property name="text" >
|
||||
<string>Payload Length</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4" >
|
||||
<widget class="QLineEdit" name="payloadLength" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QLabel" name="label_22" >
|
||||
<property name="text" >
|
||||
<string>Traffic Class</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>trafficClass</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="QLineEdit" name="trafficClass" >
|
||||
<property name="inputMask" >
|
||||
<string>>HH; </string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3" >
|
||||
<widget class="QCheckBox" name="isNextHeaderOverride" >
|
||||
<property name="text" >
|
||||
<string>Next Header</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4" >
|
||||
<widget class="QLineEdit" name="nextHeader" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="inputMask" >
|
||||
<string>HH; </string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" >
|
||||
<widget class="QLabel" name="label_24" >
|
||||
<property name="text" >
|
||||
<string>Flow Label</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>flowLabel</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" >
|
||||
<widget class="QLineEdit" name="flowLabel" >
|
||||
<property name="inputMask" >
|
||||
<string>>H HH HH; </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3" >
|
||||
<widget class="QLabel" name="label_26" >
|
||||
<property name="text" >
|
||||
<string>Hop Limit</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>hopLimit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4" >
|
||||
<widget class="QLineEdit" name="hopLimit" >
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_7" >
|
||||
<property name="title" >
|
||||
<string/>
|
||||
</property>
|
||||
<property name="flat" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<item row="0" column="0" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>51</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QLabel" name="label" >
|
||||
<property name="text" >
|
||||
<string>Address</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" >
|
||||
<widget class="QLabel" name="label_31" >
|
||||
<property name="text" >
|
||||
<string>Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3" >
|
||||
<widget class="QLabel" name="label_23" >
|
||||
<property name="text" >
|
||||
<string>Count</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4" >
|
||||
<widget class="QLabel" name="label_30" >
|
||||
<property name="text" >
|
||||
<string>Prefix</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QLabel" name="label_20" >
|
||||
<property name="text" >
|
||||
<string>Source</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="QLineEdit" name="srcAddr" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" >
|
||||
<widget class="QComboBox" name="srcAddrModeCombo" >
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Fixed</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Increment Host</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Decrement Host</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Random Host</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3" >
|
||||
<widget class="QLineEdit" name="srcAddrCount" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize" >
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
<property name="maxLength" >
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4" >
|
||||
<widget class="QLineEdit" name="srcAddrPrefix" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize" >
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="inputMask" >
|
||||
<string>/009; </string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>/64</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" >
|
||||
<widget class="QLabel" name="label_21" >
|
||||
<property name="text" >
|
||||
<string>Destination</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" >
|
||||
<widget class="QLineEdit" name="dstAddr" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" >
|
||||
<widget class="QComboBox" name="dstAddrModeCombo" >
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Fixed</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Increment Host</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Decrement Host</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Random Host</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3" >
|
||||
<widget class="QLineEdit" name="dstAddrCount" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize" >
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
<property name="maxLength" >
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4" >
|
||||
<widget class="QLineEdit" name="dstAddrPrefix" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize" >
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="inputMask" >
|
||||
<string>/009; </string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>/64</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>isVersionOverride</tabstop>
|
||||
<tabstop>version</tabstop>
|
||||
<tabstop>trafficClass</tabstop>
|
||||
<tabstop>flowLabel</tabstop>
|
||||
<tabstop>isPayloadLengthOverride</tabstop>
|
||||
<tabstop>payloadLength</tabstop>
|
||||
<tabstop>isNextHeaderOverride</tabstop>
|
||||
<tabstop>nextHeader</tabstop>
|
||||
<tabstop>hopLimit</tabstop>
|
||||
<tabstop>srcAddr</tabstop>
|
||||
<tabstop>srcAddrModeCombo</tabstop>
|
||||
<tabstop>srcAddrCount</tabstop>
|
||||
<tabstop>srcAddrPrefix</tabstop>
|
||||
<tabstop>dstAddr</tabstop>
|
||||
<tabstop>dstAddrModeCombo</tabstop>
|
||||
<tabstop>dstAddrCount</tabstop>
|
||||
<tabstop>dstAddrPrefix</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>isVersionOverride</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>version</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>67</x>
|
||||
<y>22</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>195</x>
|
||||
<y>11</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>isPayloadLengthOverride</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>payloadLength</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>319</x>
|
||||
<y>28</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>493</x>
|
||||
<y>29</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>isNextHeaderOverride</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>nextHeader</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>316</x>
|
||||
<y>41</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>348</x>
|
||||
<y>46</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
75
common/ipv6addressvalidator.h
Normal file
75
common/ipv6addressvalidator.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright (C) 2010 Srivats P.
|
||||
|
||||
This file is part of "Ostinato"
|
||||
|
||||
This is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef _IPV6_ADDRESS_VALIDATOR_H
|
||||
#define _IPV6_ADDRESS_VALIDATOR_H
|
||||
|
||||
#include <QValidator>
|
||||
#include <QHostAddress>
|
||||
|
||||
class IPv6AddressValidator : public QValidator
|
||||
{
|
||||
public:
|
||||
IPv6AddressValidator(QObject *parent = 0)
|
||||
: QValidator(parent)
|
||||
{
|
||||
_ip6ValidChars.setPattern("[0-9a-fA-F]{0,4}(:[0-9a-fA-F]{0,4}){0,7}");
|
||||
}
|
||||
~IPv6AddressValidator() {}
|
||||
|
||||
virtual QValidator::State validate(QString &input, int &pos) const
|
||||
{
|
||||
QValidator::State state;
|
||||
QHostAddress addr(input);
|
||||
|
||||
//qDebug("%s: %s (%d)", __FUNCTION__, input.toAscii().constData(), pos);
|
||||
|
||||
if (addr.protocol() == QAbstractSocket::IPv6Protocol)
|
||||
state = Acceptable;
|
||||
else
|
||||
if (_ip6ValidChars.exactMatch(input))
|
||||
state = Intermediate;
|
||||
else
|
||||
state = Invalid;
|
||||
//qDebug("%s(%d): %s (%d), ", __FUNCTION__, state,
|
||||
//input.toAscii().constData(), pos);
|
||||
return state;
|
||||
}
|
||||
virtual void fixup(QString &input) const
|
||||
{
|
||||
input.append("::");
|
||||
QHostAddress addr(input);
|
||||
int len = input.size();
|
||||
|
||||
//qDebug("%s: %s", __FUNCTION__, input.toAscii().constData());
|
||||
|
||||
while (addr.protocol() != QAbstractSocket::IPv6Protocol)
|
||||
{
|
||||
len--;
|
||||
Q_ASSERT(len >= 0);
|
||||
addr.setAddress(input.left(len));
|
||||
}
|
||||
|
||||
input = addr.toString();
|
||||
}
|
||||
private:
|
||||
QRegExp _ip6ValidChars;
|
||||
};
|
||||
|
||||
#endif
|
@ -13,6 +13,7 @@ FORMS += \
|
||||
vlan.ui \
|
||||
arp.ui \
|
||||
ip4.ui \
|
||||
ip6.ui \
|
||||
icmp.ui \
|
||||
tcp.ui \
|
||||
udp.ui \
|
||||
@ -34,6 +35,7 @@ PROTOS += \
|
||||
vlanstack.proto \
|
||||
arp.proto \
|
||||
ip4.proto \
|
||||
ip6.proto \
|
||||
ip4over4.proto \
|
||||
icmp.proto \
|
||||
tcp.proto \
|
||||
@ -61,6 +63,7 @@ HEADERS += \
|
||||
vlanstack.h \
|
||||
arp.h \
|
||||
ip4.h \
|
||||
ip6.h \
|
||||
ip4over4.h \
|
||||
icmp.h \
|
||||
tcp.h \
|
||||
@ -84,6 +87,7 @@ SOURCES += \
|
||||
svlan.cpp \
|
||||
arp.cpp \
|
||||
ip4.cpp \
|
||||
ip6.cpp \
|
||||
icmp.cpp \
|
||||
tcp.cpp \
|
||||
udp.cpp \
|
||||
|
@ -102,6 +102,7 @@ message Protocol {
|
||||
kIp4FieldNumber = 130;
|
||||
kArpFieldNumber = 131;
|
||||
kIp4over4FieldNumber = 132;
|
||||
kIp6FieldNumber = 133;
|
||||
|
||||
kTcpFieldNumber = 140;
|
||||
kUdpFieldNumber = 141;
|
||||
|
@ -33,6 +33,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#include "vlanstack.h"
|
||||
#include "arp.h"
|
||||
#include "ip4.h"
|
||||
#include "ip6.h"
|
||||
#include "ip4over4.h"
|
||||
#include "icmp.h"
|
||||
#include "tcp.h"
|
||||
@ -75,6 +76,8 @@ ProtocolManager::ProtocolManager()
|
||||
(void*) ArpProtocol::createInstance);
|
||||
registerProtocol(OstProto::Protocol::kIp4FieldNumber,
|
||||
(void*) Ip4Protocol::createInstance);
|
||||
registerProtocol(OstProto::Protocol::kIp6FieldNumber,
|
||||
(void*) Ip6Protocol::createInstance);
|
||||
registerProtocol(OstProto::Protocol::kIp4over4FieldNumber,
|
||||
(void*) Ip4over4Protocol::createInstance);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user