Device Emulation (contd.) - added intelligence for single or dual ip stack; fixed pktBuf memory leak
This commit is contained in:
parent
aaf6dbcbf2
commit
0b573d572e
@ -29,6 +29,8 @@ public:
|
||||
UInt128();
|
||||
UInt128(quint64 hi, quint64 lo);
|
||||
|
||||
quint64 hi64() const;
|
||||
quint64 lo64() const;
|
||||
quint8* toArray() const;
|
||||
|
||||
UInt128 operator+(const UInt128 &other);
|
||||
@ -51,6 +53,16 @@ inline UInt128::UInt128(quint64 hi, quint64 lo)
|
||||
lo_ = lo;
|
||||
}
|
||||
|
||||
inline quint64 UInt128::hi64() const
|
||||
{
|
||||
return hi_;
|
||||
}
|
||||
|
||||
inline quint64 UInt128::lo64() const
|
||||
{
|
||||
return lo_;
|
||||
}
|
||||
|
||||
inline quint8* UInt128::toArray() const
|
||||
{
|
||||
*(quint64*)(array_ + 0) = qToBigEndian<quint64>(hi_);
|
||||
|
@ -46,11 +46,8 @@ Device::Device(DeviceManager *deviceManager)
|
||||
numVlanTags_ = 0;
|
||||
mac_ = 0;
|
||||
|
||||
ip4_ = ip4Gateway_ = 0;
|
||||
ip4PrefixLength_ = 0;
|
||||
|
||||
ip6_ = ip6Gateway_ = UInt128(0, 0);
|
||||
ip6PrefixLength_ = 0;
|
||||
hasIp4_ = false;
|
||||
hasIp6_ = false;
|
||||
|
||||
clearKey();
|
||||
}
|
||||
@ -93,6 +90,7 @@ void Device::setIp4(quint32 address, int prefixLength, quint32 gateway)
|
||||
ip4_ = address;
|
||||
ip4PrefixLength_ = prefixLength;
|
||||
ip4Gateway_ = gateway;
|
||||
hasIp4_ = true;
|
||||
}
|
||||
|
||||
void Device::setIp6(UInt128 address, int prefixLength, UInt128 gateway)
|
||||
@ -100,6 +98,7 @@ void Device::setIp6(UInt128 address, int prefixLength, UInt128 gateway)
|
||||
ip6_ = address;
|
||||
ip6PrefixLength_ = prefixLength;
|
||||
ip6Gateway_ = gateway;
|
||||
hasIp6_ = true;
|
||||
}
|
||||
|
||||
void Device::getConfig(OstEmul::Device *deviceConfig)
|
||||
@ -108,49 +107,48 @@ void Device::getConfig(OstEmul::Device *deviceConfig)
|
||||
deviceConfig->add_vlan(vlan_[i]);
|
||||
deviceConfig->set_mac(mac_);
|
||||
|
||||
if (hasIp4_) {
|
||||
deviceConfig->set_ip4(ip4_);
|
||||
deviceConfig->set_ip4_prefix_length(ip4PrefixLength_);
|
||||
deviceConfig->set_ip4_default_gateway(ip4Gateway_);
|
||||
}
|
||||
|
||||
#if 0 // FIXME
|
||||
deviceConfig->set_ip6(ip6_);
|
||||
if (hasIp6_) {
|
||||
deviceConfig->mutable_ip6()->set_hi(ip6_.hi64());
|
||||
deviceConfig->mutable_ip6()->set_lo(ip6_.lo64());
|
||||
deviceConfig->set_ip6_prefix_length(ip6PrefixLength_);
|
||||
deviceConfig->set_ip6_default_gateway(ip6Gateway_);
|
||||
#endif
|
||||
deviceConfig->mutable_ip6_default_gateway()->set_hi(ip6Gateway_.hi64());
|
||||
deviceConfig->mutable_ip6_default_gateway()->set_lo(ip6Gateway_.lo64());
|
||||
}
|
||||
}
|
||||
|
||||
QString Device::config()
|
||||
{
|
||||
return QString("<vlans=%1/%2/%3/%4 mac=%5 ip4=%6/%7 ip6=%8/%9>")
|
||||
.arg((vlan_[0] >> 16) != kVlanTpid ?
|
||||
QString config;
|
||||
|
||||
for (int i = 0; i < numVlanTags_; i++) {
|
||||
config.append(i == 0 ? "vlans=" : "|");
|
||||
config.append(
|
||||
(vlan_[i] >> 16) != kVlanTpid ?
|
||||
QString("0x%1-%2")
|
||||
.arg(vlan_[0] >> 16, 4, kBaseHex, QChar('0'))
|
||||
.arg(vlan_[0] & 0xFFFF) :
|
||||
.arg(vlan_[i] >> 16, 4, kBaseHex, QChar('0'))
|
||||
.arg(vlan_[i] & 0xFFFF) :
|
||||
QString("%1")
|
||||
.arg(vlan_[0] & 0xFFFF))
|
||||
.arg((vlan_[1] >> 16) != kVlanTpid ?
|
||||
QString("0x%1-%2")
|
||||
.arg(vlan_[1] >> 16, 4, kBaseHex, QChar('0'))
|
||||
.arg(vlan_[1] & 0xFFFF) :
|
||||
QString("%1")
|
||||
.arg(vlan_[1] & 0xFFFF))
|
||||
.arg((vlan_[2] >> 16) != kVlanTpid ?
|
||||
QString("0x%1-%2")
|
||||
.arg(vlan_[2] >> 16, 4, kBaseHex, QChar('0'))
|
||||
.arg(vlan_[2] & 0xFFFF) :
|
||||
QString("%1")
|
||||
.arg(vlan_[2] & 0xFFFF))
|
||||
.arg((vlan_[3] >> 16) != kVlanTpid ?
|
||||
QString("0x%1-%2")
|
||||
.arg(vlan_[3] >> 16, 4, kBaseHex, QChar('0'))
|
||||
.arg(vlan_[3] & 0xFFFF) :
|
||||
QString("%1")
|
||||
.arg(vlan_[3] & 0xFFFF))
|
||||
.arg(mac_, 12, kBaseHex, QChar('0'))
|
||||
.arg(vlan_[i] & 0xFFFF));
|
||||
}
|
||||
|
||||
config.append(QString(" mac=%1")
|
||||
.arg(mac_, 12, kBaseHex, QChar('0')));
|
||||
if (hasIp4_)
|
||||
config.append(QString(" ip4=%1/%2")
|
||||
.arg(QHostAddress(ip4_).toString())
|
||||
.arg(ip4PrefixLength_)
|
||||
.arg(ip4PrefixLength_));
|
||||
if (hasIp6_)
|
||||
config.append(QString(" ip6=%1/%2")
|
||||
.arg(QHostAddress(ip6_.toArray()).toString())
|
||||
.arg(ip6PrefixLength_);
|
||||
.arg(ip6PrefixLength_));
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
DeviceKey Device::key()
|
||||
@ -212,10 +210,12 @@ void Device::receivePacket(PacketBuffer *pktBuf)
|
||||
switch(ethType)
|
||||
{
|
||||
case 0x0806: // ARP
|
||||
if (hasIp4_)
|
||||
receiveArp(pktBuf);
|
||||
break;
|
||||
|
||||
case 0x0800: // IPv4
|
||||
if (hasIp4_)
|
||||
receiveIp4(pktBuf);
|
||||
break;
|
||||
|
||||
@ -249,10 +249,12 @@ void Device::resolveNeighbor(PacketBuffer *pktBuf)
|
||||
switch(ethType)
|
||||
{
|
||||
case 0x0800: // IPv4
|
||||
if (hasIp4_)
|
||||
sendArpRequest(pktBuf);
|
||||
break;
|
||||
|
||||
case 0x86dd: // IPv6
|
||||
if (hasIp6_)
|
||||
sendNeighborSolicit(pktBuf);
|
||||
break;
|
||||
|
||||
@ -278,6 +280,7 @@ void Device::getNeighbors(OstEmul::DeviceNeighborList *neighbors)
|
||||
}
|
||||
}
|
||||
|
||||
// Are we the source of the given packet?
|
||||
// We expect pktBuf to point to EthType on entry
|
||||
bool Device::isOrigin(const PacketBuffer *pktBuf)
|
||||
{
|
||||
@ -288,7 +291,7 @@ bool Device::isOrigin(const PacketBuffer *pktBuf)
|
||||
pktData += 2;
|
||||
|
||||
// We know only about IP packets
|
||||
if (ethType == 0x0800) { // IPv4
|
||||
if ((ethType == 0x0800) && hasIp4_) { // IPv4
|
||||
int ipHdrLen = (pktData[0] & 0x0F) << 2;
|
||||
quint32 srcIp;
|
||||
|
||||
@ -306,6 +309,7 @@ bool Device::isOrigin(const PacketBuffer *pktBuf)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return the mac address corresponding to the dstIp of the given packet
|
||||
// We expect pktBuf to point to EthType on entry
|
||||
quint64 Device::neighborMac(const PacketBuffer *pktBuf)
|
||||
{
|
||||
@ -316,7 +320,7 @@ quint64 Device::neighborMac(const PacketBuffer *pktBuf)
|
||||
pktData += 2;
|
||||
|
||||
// We know only about IP packets
|
||||
if (ethType == 0x0800) { // IPv4
|
||||
if ((ethType == 0x0800) && hasIp4_) { // IPv4
|
||||
int ipHdrLen = (pktData[0] & 0x0F) << 2;
|
||||
quint32 dstIp, tgtIp, mask;
|
||||
|
||||
|
@ -87,10 +87,12 @@ private: // data
|
||||
quint32 vlan_[kMaxVlan];
|
||||
quint64 mac_;
|
||||
|
||||
bool hasIp4_;
|
||||
quint32 ip4_;
|
||||
int ip4PrefixLength_;
|
||||
quint32 ip4Gateway_;
|
||||
|
||||
bool hasIp6_;
|
||||
UInt128 ip6_;
|
||||
int ip6PrefixLength_;
|
||||
UInt128 ip6Gateway_;
|
||||
|
@ -188,7 +188,7 @@ void DeviceManager::receivePacket(PacketBuffer *pktBuf)
|
||||
// All frames we are interested in should be at least 32 bytes
|
||||
if (pktBuf->length() < 32) {
|
||||
qWarning("short frame of %d bytes, skipping ...", pktBuf->length());
|
||||
return;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
// Extract dstMac
|
||||
@ -241,7 +241,7 @@ _eth_type:
|
||||
device->receivePacket(pktBuf);
|
||||
|
||||
_exit:
|
||||
return;
|
||||
delete pktBuf;
|
||||
}
|
||||
|
||||
void DeviceManager::transmitPacket(PacketBuffer *pktBuf)
|
||||
@ -343,6 +343,8 @@ void DeviceManager::enumerateDevices(
|
||||
int n = 1;
|
||||
QList<int> vlanCount;
|
||||
|
||||
bool hasIp4 = deviceGroup->HasExtension(OstEmul::ip4);
|
||||
bool hasIp6 = deviceGroup->HasExtension(OstEmul::ip6);
|
||||
OstEmul::MacEmulation mac = deviceGroup->GetExtension(OstEmul::mac);
|
||||
OstEmul::Ip4Emulation ip4 = deviceGroup->GetExtension(OstEmul::ip4);
|
||||
OstEmul::Ip6Emulation ip6 = deviceGroup->GetExtension(OstEmul::ip6);
|
||||
@ -430,9 +432,11 @@ void DeviceManager::enumerateDevices(
|
||||
UInt128 ip6Add = UINT128(ip6.step()) * k;
|
||||
|
||||
dk.setMac(mac.address() + macAdd);
|
||||
if (hasIp4)
|
||||
dk.setIp4(ip4.address() + ip4Add,
|
||||
ip4.prefix_length(),
|
||||
ip4.default_gateway());
|
||||
if (hasIp6)
|
||||
dk.setIp6(UINT128(ip6.address()) + ip6Add,
|
||||
ip6.prefix_length(),
|
||||
UINT128(ip6.default_gateway()));
|
||||
|
Loading…
Reference in New Issue
Block a user