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;
case kIp6Address:
setValidator(&ip6Validator_);
setPlaceholderText("::");
break;
default:
setValidator(nullptr);

View File

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

View File

@ -354,6 +354,11 @@ QVariant Ip6Protocol::fieldData(int index, FieldAttrib attrib,
case FieldName:
return QString("Source");
case FieldValue:
{
QVariant v;
v.setValue(src);
return v;
}
case FieldFrameValue:
case FieldTextValue:
{
@ -412,6 +417,11 @@ QVariant Ip6Protocol::fieldData(int index, FieldAttrib attrib,
case FieldName:
return QString("Destination");
case FieldValue:
{
QVariant v;
v.setValue(dst);
return v;
}
case FieldFrameValue:
case FieldTextValue:
{
@ -594,6 +604,14 @@ bool Ip6Protocol::setFieldData(int index, const QVariant &value,
}
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();
quint64 x;
@ -620,6 +638,14 @@ bool Ip6Protocol::setFieldData(int index, const QVariant &value,
}
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();
quint64 x;

View File

@ -20,6 +20,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#ifndef _IP_UTILS_H
#define _IP_UTILS_H
#include "uint128.h"
#include <QHostAddress>
namespace ipUtils {
enum AddrMode {
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
#endif

View File

@ -18,11 +18,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "streambase.h"
#include "abstractprotocol.h"
#include "framevalueattrib.h"
#include "protocollist.h"
#include "protocollistiterator.h"
#include "protocolmanager.h"
#include "uint128.h"
#include <QDebug>
@ -628,7 +630,10 @@ int StreamBase::findReplace(quint32 protocolNumber, int fieldIndex,
<< "replaceMask" << hex << replaceMask.value<T>() << dec
<< "replaceValue" << replaceValue.value<T>()
<< "newValue" << newValue;
if (proto->setFieldData(fieldIndex, newValue))
QVariant nv;
nv.setValue(newValue);
if (proto->setFieldData(fieldIndex, nv))
replaceCount++;
}
}
@ -646,7 +651,9 @@ int StreamBase::protocolFieldReplace(quint32 protocolNumber,
return findReplace<qulonglong>(protocolNumber, fieldIndex,
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());
return 0;

View File

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