Verify and fix Ip6Address type field edit

This commit is contained in:
Srivats P 2021-12-08 21:36:39 +05:30
parent 2eab3daa2f
commit 4c6d8f35d6
6 changed files with 116 additions and 21 deletions

View File

@ -46,6 +46,7 @@ void FieldEdit::setType(FieldType type)
break; break;
case kIp6Address: case kIp6Address:
setValidator(&ip6Validator_); setValidator(&ip6Validator_);
setPlaceholderText("::");
break; break;
default: default:
setValidator(nullptr); setValidator(nullptr);

View File

@ -19,9 +19,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "findreplace.h" #include "findreplace.h"
#include "../common/abstractprotocol.h" #include "abstractprotocol.h"
#include "../common/protocolmanager.h" #include "iputils.h"
#include "protocolmanager.h"
#include "stream.h" #include "stream.h"
#include "uint128.h"
#include <QPushButton> #include <QPushButton>
@ -103,6 +105,12 @@ void FindReplaceDialog::on_field_currentIndexChanged(int index)
QRegularExpression::CaseInsensitiveOption)))) { QRegularExpression::CaseInsensitiveOption)))) {
findValue->setType(FieldEdit::kIp4Address); findValue->setType(FieldEdit::kIp4Address);
replaceValue->setType(FieldEdit::kIp4Address); replaceValue->setType(FieldEdit::kIp4Address);
} else if ((fieldAttrib.bitSize == 128)
&& (fieldName.contains(QRegularExpression(
"address|source|destination",
QRegularExpression::CaseInsensitiveOption)))) {
findValue->setType(FieldEdit::kIp6Address);
replaceValue->setType(FieldEdit::kIp6Address);
} else { } else {
qDebug("XXXXXX %s bitSize %d max %llx", qDebug("XXXXXX %s bitSize %d max %llx",
qPrintable(field->currentText()), qPrintable(field->currentText()),
@ -123,30 +131,52 @@ void FindReplaceDialog::on_buttonBox_accepted()
action_->fieldIndex = fieldAttrib.index; action_->fieldIndex = fieldAttrib.index;
action_->fieldBitSize = fieldAttrib.bitSize; action_->fieldBitSize = fieldAttrib.bitSize;
// TODO: Change <= 64 to uint64 instead of string
// XXX: All find/replace value/mask QVariants are set to // XXX: All find/replace value/mask QVariants are set to
// 64-bit decimal number encoded as string // 64-bit decimal number encoded as string
// - The action user is expected to convert to appropriate type // - The action user is expected to convert to appropriate type
// (fieldBitSize is included as a hint) // (fieldBitSize is included as a hint)
// - QVariant can only do decimal conversions (not hex) // - QVariant can only do decimal conversions (not hex)
if (matchAny->isChecked()) { if (fieldAttrib.bitSize == 128) { // IPv6 address
action_->findMask.setValue(QString("0")); if (matchAny->isChecked()) {
action_->findValue.setValue(QString("0")); action_->findMask.setValue(UInt128(0));
} else { action_->findValue.setValue(UInt128(0));
action_->findMask.setValue(QString::number( } else {
useFindMask->isChecked() ? action_->findMask.setValue(
findMask->text().toULongLong(nullptr, BASE_HEX) : useFindMask->isChecked() ?
quint64(~0))); ipUtils::ip6StringToUInt128(findMask->text()) :
action_->findValue.setValue(QString::number( ~UInt128(0));
findValue->text().toULongLong(nullptr, 0))); action_->findValue.setValue(
} ipUtils::ip6StringToUInt128(findValue->text()));
}
action_->replaceMask.setValue(QString::number( action_->replaceMask.setValue(
useReplaceMask->isChecked() ? useReplaceMask->isChecked() ?
replaceMask->text().toULongLong(nullptr, BASE_HEX) : ipUtils::ip6StringToUInt128(replaceMask->text()) :
quint64(~0))); ~UInt128(0));
action_->replaceValue.setValue(QString::number( action_->replaceValue.setValue(
replaceValue->text().toULongLong(nullptr, 0))); ipUtils::ip6StringToUInt128(replaceValue->text()));
} else { // everything else
if (matchAny->isChecked()) {
action_->findMask.setValue(QString("0"));
action_->findValue.setValue(QString("0"));
} else {
action_->findMask.setValue(QString::number(
useFindMask->isChecked() ?
findMask->text().toULongLong(nullptr, BASE_HEX) :
quint64(~0)));
action_->findValue.setValue(QString::number(
findValue->text().toULongLong(nullptr, 0)));
}
action_->replaceMask.setValue(QString::number(
useReplaceMask->isChecked() ?
replaceMask->text().toULongLong(nullptr, BASE_HEX) :
quint64(~0)));
action_->replaceValue.setValue(QString::number(
replaceValue->text().toULongLong(nullptr, 0)));
}
action_->selectedStreamsOnly = selectedStreamsOnly->isChecked(); action_->selectedStreamsOnly = selectedStreamsOnly->isChecked();
} }

View File

@ -354,6 +354,11 @@ QVariant Ip6Protocol::fieldData(int index, FieldAttrib attrib,
case FieldName: case FieldName:
return QString("Source"); return QString("Source");
case FieldValue: case FieldValue:
{
QVariant v;
v.setValue(src);
return v;
}
case FieldFrameValue: case FieldFrameValue:
case FieldTextValue: case FieldTextValue:
{ {
@ -412,6 +417,11 @@ QVariant Ip6Protocol::fieldData(int index, FieldAttrib attrib,
case FieldName: case FieldName:
return QString("Destination"); return QString("Destination");
case FieldValue: case FieldValue:
{
QVariant v;
v.setValue(dst);
return v;
}
case FieldFrameValue: case FieldFrameValue:
case FieldTextValue: case FieldTextValue:
{ {
@ -594,6 +604,14 @@ bool Ip6Protocol::setFieldData(int index, const QVariant &value,
} }
case ip6_srcAddress: case ip6_srcAddress:
{ {
if (value.typeName() == QString("UInt128")) {
UInt128 addr = value.value<UInt128>();
data.set_src_addr_hi(addr.hi64());
data.set_src_addr_lo(addr.lo64());
isOk = true;
break;
}
Q_IPV6ADDR addr = QHostAddress(value.toString()).toIPv6Address(); Q_IPV6ADDR addr = QHostAddress(value.toString()).toIPv6Address();
quint64 x; quint64 x;
@ -620,6 +638,14 @@ bool Ip6Protocol::setFieldData(int index, const QVariant &value,
} }
case ip6_dstAddress: case ip6_dstAddress:
{ {
if (value.typeName() == QString("UInt128")) {
UInt128 addr = value.value<UInt128>();
data.set_dst_addr_hi(addr.hi64());
data.set_dst_addr_lo(addr.lo64());
isOk = true;
break;
}
Q_IPV6ADDR addr = QHostAddress(value.toString()).toIPv6Address(); Q_IPV6ADDR addr = QHostAddress(value.toString()).toIPv6Address();
quint64 x; quint64 x;

View File

@ -20,6 +20,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#ifndef _IP_UTILS_H #ifndef _IP_UTILS_H
#define _IP_UTILS_H #define _IP_UTILS_H
#include "uint128.h"
#include <QHostAddress>
namespace ipUtils { namespace ipUtils {
enum AddrMode { enum AddrMode {
kFixed = 0, kFixed = 0,
@ -118,5 +122,31 @@ void inline ipAddress(quint64 baseIpHi, quint64 baseIpLo, int prefix,
} }
} }
UInt128 inline ip6StringToUInt128(QString ip6Str)
{
Q_IPV6ADDR addr = QHostAddress(ip6Str).toIPv6Address();
quint64 hi, lo;
hi = (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);
lo = (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);
return UInt128(hi, lo);
}
} // namespace ipUtils } // namespace ipUtils
#endif #endif

View File

@ -18,11 +18,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
*/ */
#include "streambase.h" #include "streambase.h"
#include "abstractprotocol.h" #include "abstractprotocol.h"
#include "framevalueattrib.h" #include "framevalueattrib.h"
#include "protocollist.h" #include "protocollist.h"
#include "protocollistiterator.h" #include "protocollistiterator.h"
#include "protocolmanager.h" #include "protocolmanager.h"
#include "uint128.h"
#include <QDebug> #include <QDebug>
@ -628,7 +630,10 @@ int StreamBase::findReplace(quint32 protocolNumber, int fieldIndex,
<< "replaceMask" << hex << replaceMask.value<T>() << dec << "replaceMask" << hex << replaceMask.value<T>() << dec
<< "replaceValue" << replaceValue.value<T>() << "replaceValue" << replaceValue.value<T>()
<< "newValue" << newValue; << "newValue" << newValue;
if (proto->setFieldData(fieldIndex, newValue))
QVariant nv;
nv.setValue(newValue);
if (proto->setFieldData(fieldIndex, nv))
replaceCount++; replaceCount++;
} }
} }
@ -646,7 +651,9 @@ int StreamBase::protocolFieldReplace(quint32 protocolNumber,
return findReplace<qulonglong>(protocolNumber, fieldIndex, return findReplace<qulonglong>(protocolNumber, fieldIndex,
findValue, findMask, replaceValue, replaceMask); findValue, findMask, replaceValue, replaceMask);
// TODO: > 64 (e.g. IPv6 128 bit) if (fieldBitSize == 128)
return findReplace<UInt128>(protocolNumber, fieldIndex,
findValue, findMask, replaceValue, replaceMask);
qWarning("Unknown find/replace type %d", findValue.type()); qWarning("Unknown find/replace type %d", findValue.type());
return 0; return 0;

View File

@ -54,6 +54,7 @@ private:
quint64 lo_; quint64 lo_;
quint8 array_[16]; quint8 array_[16];
}; };
Q_DECLARE_METATYPE(UInt128);
inline UInt128::UInt128() inline UInt128::UInt128()
{ {