Precalculate mask and subnet for use during emulation rx/tx
This commit is contained in:
parent
f86ce2603d
commit
523258442c
@ -111,6 +111,10 @@ void Device::setIp4(quint32 address, int prefixLength, quint32 gateway)
|
||||
ip4PrefixLength_ = prefixLength;
|
||||
ip4Gateway_ = gateway;
|
||||
hasIp4_ = true;
|
||||
|
||||
// Precalculate our mask 'n subnet to avoid doing so at pkt rx/tx time
|
||||
ip4Mask_ = ~0 << (32 - ip4PrefixLength_);
|
||||
ip4Subnet_ = ip4_ & ip4Mask_;
|
||||
}
|
||||
|
||||
void Device::setIp6(UInt128 address, int prefixLength, UInt128 gateway)
|
||||
@ -119,6 +123,10 @@ void Device::setIp6(UInt128 address, int prefixLength, UInt128 gateway)
|
||||
ip6PrefixLength_ = prefixLength;
|
||||
ip6Gateway_ = gateway;
|
||||
hasIp6_ = true;
|
||||
|
||||
// Precalculate our mask 'n subnet to avoid doing so at pkt rx/tx time
|
||||
ip6Mask_ = ~UInt128(0, 0) << (128 - ip6PrefixLength_);
|
||||
ip6Subnet_ = ip6_ & ip6Mask_;
|
||||
}
|
||||
|
||||
void Device::getConfig(OstEmul::Device *deviceConfig)
|
||||
@ -405,7 +413,7 @@ quint64 Device::neighborMac(const PacketBuffer *pktBuf)
|
||||
// We know only about IP packets
|
||||
if ((ethType == 0x0800) && hasIp4_) { // IPv4
|
||||
int ipHdrLen = (pktData[0] & 0x0F) << 2;
|
||||
quint32 dstIp, tgtIp, mask;
|
||||
quint32 dstIp, tgtIp;
|
||||
|
||||
if (pktBuf->length() < ipHdrLen) {
|
||||
qDebug("incomplete IPv4 header: expected %d, actual %d",
|
||||
@ -418,14 +426,12 @@ quint64 Device::neighborMac(const PacketBuffer *pktBuf)
|
||||
qDebug("mcast dst %x", dstIp);
|
||||
return (quint64(0x01005e) << 24) | (dstIp & 0x7FFFFF);
|
||||
}
|
||||
mask = ~0 << (32 - ip4PrefixLength_);
|
||||
qDebug("dst %x mask %x self %x", dstIp, mask, ip4_);
|
||||
tgtIp = ((dstIp & mask) == (ip4_ & mask)) ? dstIp : ip4Gateway_;
|
||||
tgtIp = ((dstIp & ip4Mask_) == ip4Subnet_) ? dstIp : ip4Gateway_;
|
||||
|
||||
return arpTable_.value(tgtIp);
|
||||
}
|
||||
else if ((ethType == kEthTypeIp6) && hasIp6_) { // IPv6
|
||||
UInt128 dstIp, tgtIp, mask;
|
||||
UInt128 dstIp, tgtIp;
|
||||
|
||||
if (pktBuf->length() < (kIp6HdrLen+2)) {
|
||||
qDebug("incomplete IPv6 header: expected %d, actual %d",
|
||||
@ -439,12 +445,7 @@ quint64 Device::neighborMac(const PacketBuffer *pktBuf)
|
||||
qPrintable(QHostAddress(dstIp.toArray()).toString()));
|
||||
return (quint64(0x3333) << 32) | (dstIp.lo64() & 0xFFFFFFFF);
|
||||
}
|
||||
mask = ~UInt128(0, 0) << (128 - ip6PrefixLength_);
|
||||
qDebug("dst %s mask %s self %s",
|
||||
qPrintable(QHostAddress(dstIp.toArray()).toString()),
|
||||
qPrintable(QHostAddress(mask.toArray()).toString()),
|
||||
qPrintable(QHostAddress(ip6_.toArray()).toString()));
|
||||
tgtIp = ((dstIp & mask) == (ip6_ & mask)) ? dstIp : ip6Gateway_;
|
||||
tgtIp = ((dstIp & ip6Mask_) == ip6Subnet_) ? dstIp : ip6Gateway_;
|
||||
|
||||
return ndpTable_.value(tgtIp);
|
||||
}
|
||||
@ -568,7 +569,7 @@ void Device::sendArpRequest(PacketBuffer *pktBuf)
|
||||
{
|
||||
uchar *pktData = pktBuf->data();
|
||||
int ipHdrLen = (pktData[0] & 0x0F) << 2;
|
||||
quint32 srcIp = ip4_, dstIp, mask, tgtIp;
|
||||
quint32 dstIp, tgtIp;
|
||||
|
||||
if (pktBuf->length() < ipHdrLen) {
|
||||
qDebug("incomplete IPv4 header: expected %d, actual %d",
|
||||
@ -578,9 +579,7 @@ void Device::sendArpRequest(PacketBuffer *pktBuf)
|
||||
|
||||
dstIp = qFromBigEndian<quint32>(pktData + ipHdrLen - 4);
|
||||
|
||||
mask = ~0 << (32 - ip4PrefixLength_);
|
||||
qDebug("dst %x src %x mask %x", dstIp, srcIp, mask);
|
||||
tgtIp = ((dstIp & mask) == (srcIp & mask)) ? dstIp : ip4Gateway_;
|
||||
tgtIp = ((dstIp & ip4Mask_) == ip4Subnet_) ? dstIp : ip4Gateway_;
|
||||
|
||||
sendArpRequest(tgtIp);
|
||||
|
||||
@ -691,9 +690,7 @@ void Device::sendIp4Reply(PacketBuffer *pktBuf)
|
||||
dstIp = qFromBigEndian<quint32>(pktData + 12); // srcIp in original pkt
|
||||
srcIp = qFromBigEndian<quint32>(pktData + 16); // dstIp in original pkt
|
||||
|
||||
mask = ~0 << (32 - ip4PrefixLength_);
|
||||
qDebug("dst %x mask %x self %x", dstIp, mask, ip4_);
|
||||
tgtIp = ((dstIp & mask) == (ip4_ & mask)) ? dstIp : ip4Gateway_;
|
||||
tgtIp = ((dstIp & ip4Mask_) == ip4Subnet_) ? dstIp : ip4Gateway_;
|
||||
|
||||
if (!arpTable_.contains(tgtIp)) {
|
||||
qWarning("%s: mac not found for %s; unable to send IPv4 packet",
|
||||
@ -812,12 +809,7 @@ bool Device::sendIp6(PacketBuffer *pktBuf, UInt128 dstIp, quint8 protocol)
|
||||
if ((dstIp.hi64() >> 56) == 0xff)
|
||||
dstMac = (quint64(0x3333) << 32) | (dstIp.lo64() & 0xffffffff);
|
||||
else {
|
||||
UInt128 mask = ~UInt128(0, 0) << (128 - ip6PrefixLength_);
|
||||
UInt128 tgtIp = ((dstIp & mask) == (ip6_ & mask)) ? dstIp : ip6Gateway_;
|
||||
qDebug("dst %s mask %s self %s",
|
||||
qPrintable(QHostAddress(dstIp.toArray()).toString()),
|
||||
qPrintable(QHostAddress(mask.toArray()).toString()),
|
||||
qPrintable(QHostAddress(ip6_.toArray()).toString()));
|
||||
UInt128 tgtIp = ((dstIp & ip6Mask_) == ip6Subnet_)? dstIp : ip6Gateway_;
|
||||
dstMac = ndpTable_.value(tgtIp);
|
||||
}
|
||||
|
||||
@ -854,18 +846,13 @@ _error_exit:
|
||||
void Device::sendIp6Reply(PacketBuffer *pktBuf)
|
||||
{
|
||||
uchar *pktData = pktBuf->push(kIp6HdrLen);
|
||||
UInt128 srcIp, dstIp, tgtIp, mask;
|
||||
UInt128 srcIp, dstIp, tgtIp;
|
||||
|
||||
// Swap src/dst IP addresses
|
||||
dstIp = qFromBigEndian<UInt128>(pktData + 8); // srcIp in original pkt
|
||||
srcIp = qFromBigEndian<UInt128>(pktData + 24); // dstIp in original pkt
|
||||
|
||||
mask = ~UInt128(0, 0) << (128 - ip6PrefixLength_);
|
||||
qDebug("dst %s mask %s self %s",
|
||||
qPrintable(QHostAddress(dstIp.toArray()).toString()),
|
||||
qPrintable(QHostAddress(mask.toArray()).toString()),
|
||||
qPrintable(QHostAddress(ip6_.toArray()).toString()));
|
||||
tgtIp = ((dstIp & mask) == (ip6_ & mask)) ? dstIp : ip6Gateway_;
|
||||
tgtIp = ((dstIp & ip6Mask_) == ip6Subnet_) ? dstIp : ip6Gateway_;
|
||||
if (!ndpTable_.contains(tgtIp)) {
|
||||
qWarning("%s: mac not found for %s; unable to send IPv6 packet",
|
||||
__FUNCTION__,
|
||||
@ -969,7 +956,7 @@ _invalid_exit:
|
||||
void Device::sendNeighborSolicit(PacketBuffer *pktBuf)
|
||||
{
|
||||
uchar *pktData = pktBuf->data();
|
||||
UInt128 srcIp = ip6_, dstIp, mask, tgtIp;
|
||||
UInt128 dstIp, tgtIp;
|
||||
|
||||
if (pktBuf->length() < kIp6HdrLen) {
|
||||
qDebug("incomplete IPv6 header: expected %d, actual %d",
|
||||
@ -979,12 +966,7 @@ void Device::sendNeighborSolicit(PacketBuffer *pktBuf)
|
||||
|
||||
dstIp = qFromBigEndian<UInt128>(pktData + 24);
|
||||
|
||||
mask = ~UInt128(0, 0) << (128 - ip6PrefixLength_);
|
||||
qDebug("%s: dst %s src %s mask %s", __FUNCTION__,
|
||||
qPrintable(QHostAddress(dstIp.toArray()).toString()),
|
||||
qPrintable(QHostAddress(srcIp.toArray()).toString()),
|
||||
qPrintable(QHostAddress(mask.toArray()).toString()));
|
||||
tgtIp = ((dstIp & mask) == (srcIp & mask)) ? dstIp : ip6Gateway_;
|
||||
tgtIp = ((dstIp & ip6Mask_) == ip6Subnet_) ? dstIp : ip6Gateway_;
|
||||
|
||||
sendNeighborSolicit(tgtIp);
|
||||
}
|
||||
|
@ -107,11 +107,15 @@ private: // data
|
||||
quint32 ip4_;
|
||||
int ip4PrefixLength_;
|
||||
quint32 ip4Gateway_;
|
||||
quint32 ip4Mask_;
|
||||
quint32 ip4Subnet_;
|
||||
|
||||
bool hasIp6_;
|
||||
UInt128 ip6_;
|
||||
int ip6PrefixLength_;
|
||||
UInt128 ip6Gateway_;
|
||||
UInt128 ip6Mask_;
|
||||
UInt128 ip6Subnet_;
|
||||
|
||||
DeviceKey key_;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user