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