Device Emulation (contd.): Use a default Mac address as per RFC 4814; define and use new MacEdit class

This commit is contained in:
Srivats P 2016-02-29 20:12:02 +05:30
parent a4a654fb02
commit 9619439e6a
4 changed files with 82 additions and 18 deletions

View File

@ -24,15 +24,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "emulproto.pb.h" #include "emulproto.pb.h"
#include "uint128.h" #include "uint128.h"
#include "macedit.h"
#include <QHeaderView> #include <QHeaderView>
#include <QHostAddress> #include <QHostAddress>
#define uintToMacStr(num) \
QString("%1").arg(num, 6*2, 16, QChar('0')) \
.replace(QRegExp("([0-9a-fA-F]{2}\\B)"), "\\1:").toUpper()
#define macStrToUInt(str) \
str.remove(QChar(' ')).toULongLong()
enum { kIpNone, kIp4, kIp6, kIpDual }; enum { kIpNone, kIp4, kIp6, kIpDual };
static QStringList ipStackItems = QStringList() static QStringList ipStackItems = QStringList()
<< "None" << "IPv4" << "IPv6" << "Dual"; << "None" << "IPv4" << "IPv6" << "Dual";
@ -59,8 +54,6 @@ DeviceGroupDialog::DeviceGroupDialog(
Qt::WindowFlags flags) Qt::WindowFlags flags)
: QDialog(parent, flags), port_(port), index_(deviceGroupIndex) : QDialog(parent, flags), port_(port), index_(deviceGroupIndex)
{ {
QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}");
// Setup the Dialog // Setup the Dialog
setupUi(this); setupUi(this);
vlanTagCount->setRange(0, kMaxVlanTags); vlanTagCount->setRange(0, kMaxVlanTags);
@ -72,8 +65,6 @@ DeviceGroupDialog::DeviceGroupDialog(
qDebug("vlan def size: %d", vlans->verticalHeader()->defaultSectionSize()); qDebug("vlan def size: %d", vlans->verticalHeader()->defaultSectionSize());
qDebug("vlan min size: %d", vlans->verticalHeader()->minimumSectionSize()); qDebug("vlan min size: %d", vlans->verticalHeader()->minimumSectionSize());
#endif #endif
macAddress->setValidator(new QRegExpValidator(reMac, this));
macStep->setValidator(new QRegExpValidator(reMac, this));
ipStack->insertItems(0, ipStackItems); ipStack->insertItems(0, ipStackItems);
layout()->setSizeConstraint(QLayout::SetFixedSize); layout()->setSizeConstraint(QLayout::SetFixedSize);
@ -145,8 +136,23 @@ void DeviceGroupDialog::loadDeviceGroup()
QString::number(totalVlans * devGrp->device_count())); QString::number(totalVlans * devGrp->device_count()));
OstEmul::MacEmulation mac = devGrp->GetExtension(OstEmul::mac); OstEmul::MacEmulation mac = devGrp->GetExtension(OstEmul::mac);
macAddress->setText(uintToMacStr(mac.address())); if (!mac.has_address()) {
macStep->setText(uintToMacStr(mac.step())); // Mac address as per RFC 4814 Sec 4.2
// (RR & 0xFC):PP:PP:RR:RR:RR
// where RR is a random number, PP:PP is 1-indexed port index
// NOTE: although qrand() return type is a int, the max value
// is RAND_MAX (stdlib.h) which is often 16-bit only, so we
// use two random numbers
quint32 r1 = qrand(), r2 = qrand();
quint64 mac;
mac = quint64(r1 & 0xfc00) << 32
| quint64(port_->id() + 1) << 24
| quint64((r1 & 0xff) << 16 | (r2 & 0xffff));
macAddress->setValue(mac);
}
else
macAddress->setValue(mac.address());
macStep->setValue(mac.step());
OstEmul::Ip4Emulation ip4 = devGrp->GetExtension(OstEmul::ip4); OstEmul::Ip4Emulation ip4 = devGrp->GetExtension(OstEmul::ip4);
ip4Address->setText(IP4STR(ip4.address())); ip4Address->setText(IP4STR(ip4.address()));
@ -184,8 +190,8 @@ void DeviceGroupDialog::storeDeviceGroup()
devGrp->set_device_count(devicePerVlanCount->value()); devGrp->set_device_count(devicePerVlanCount->value());
OstEmul::MacEmulation *mac = devGrp->MutableExtension(OstEmul::mac); OstEmul::MacEmulation *mac = devGrp->MutableExtension(OstEmul::mac);
mac->set_address(macStrToUInt(macAddress->text())); mac->set_address(macAddress->value());
mac->set_step(macStrToUInt(macStep->text())); mac->set_step(macStep->value());
if (ipStack->currentIndex() == kIp4 if (ipStack->currentIndex() == kIp4
|| ipStack->currentIndex() == kIpDual) { || ipStack->currentIndex() == kIpDual) {

View File

@ -140,7 +140,7 @@
</widget> </widget>
</item> </item>
<item row="1" column="1" > <item row="1" column="1" >
<widget class="QLineEdit" name="macAddress" /> <widget class="MacEdit" name="macAddress" />
</item> </item>
<item row="1" column="2" > <item row="1" column="2" >
<widget class="QLabel" name="label_5" > <widget class="QLabel" name="label_5" >
@ -150,7 +150,7 @@
</widget> </widget>
</item> </item>
<item row="1" column="3" colspan="2" > <item row="1" column="3" colspan="2" >
<widget class="QLineEdit" name="macStep" /> <widget class="MacEdit" name="macStep" />
</item> </item>
<item row="1" column="5" > <item row="1" column="5" >
<widget class="QLabel" name="label_4" > <widget class="QLabel" name="label_4" >
@ -341,6 +341,13 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>MacEdit</class>
<extends>QLineEdit</extends>
<header>macedit.h</header>
</customwidget>
</customwidgets>
<tabstops> <tabstops>
<tabstop>name</tabstop> <tabstop>name</tabstop>
<tabstop>vlanTagCount</tabstop> <tabstop>vlanTagCount</tabstop>

View File

@ -46,8 +46,7 @@ extend OstProto.EncapEmulation {
// Protocols // Protocols
// =========== // ===========
message MacEmulation { message MacEmulation {
optional uint64 address = 1; // FIXME: default value optional uint64 address = 1; // no default - need unique value
optional uint64 step = 10 [default = 1]; optional uint64 step = 10 [default = 1];
} }

52
common/macedit.h Normal file
View File

@ -0,0 +1,52 @@
/*
Copyright (C) 2016 Srivats P.
This file is part of "Ostinato"
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef _MAC_EDIT_H
#define _MAC_EDIT_H
class MacEdit: public QLineEdit
{
public:
MacEdit(QWidget *parent = 0);
quint64 value();
void setValue(quint64 val);
};
inline MacEdit::MacEdit(QWidget *parent)
: QLineEdit(parent)
{
QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}");
setValidator(new QRegExpValidator(reMac, this));
}
inline quint64 MacEdit::value()
{
return text().remove(QChar(':')).toULongLong(NULL, 16);
}
inline void MacEdit::setValue(quint64 val)
{
setText(QString("%1").arg(val, 6*2, 16, QChar('0'))
.replace(QRegExp("([0-9a-fA-F]{2}\\B)"), "\\1:").toUpper());
}
#endif