Precalculate mask and subnet for use during emulation rx/tx

This commit is contained in:
Srivats P 2016-09-17 14:34:44 +05:30
parent f86ce2603d
commit 523258442c
2 changed files with 24 additions and 38 deletions

View File

@ -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);
}

View File

@ -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_;