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