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 "uint128.h"
#include "macedit.h"
#include <QHeaderView>
#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 };
static QStringList ipStackItems = QStringList()
<< "None" << "IPv4" << "IPv6" << "Dual";
@ -59,8 +54,6 @@ DeviceGroupDialog::DeviceGroupDialog(
Qt::WindowFlags flags)
: 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
setupUi(this);
vlanTagCount->setRange(0, kMaxVlanTags);
@ -72,8 +65,6 @@ DeviceGroupDialog::DeviceGroupDialog(
qDebug("vlan def size: %d", vlans->verticalHeader()->defaultSectionSize());
qDebug("vlan min size: %d", vlans->verticalHeader()->minimumSectionSize());
#endif
macAddress->setValidator(new QRegExpValidator(reMac, this));
macStep->setValidator(new QRegExpValidator(reMac, this));
ipStack->insertItems(0, ipStackItems);
layout()->setSizeConstraint(QLayout::SetFixedSize);
@ -145,8 +136,23 @@ void DeviceGroupDialog::loadDeviceGroup()
QString::number(totalVlans * devGrp->device_count()));
OstEmul::MacEmulation mac = devGrp->GetExtension(OstEmul::mac);
macAddress->setText(uintToMacStr(mac.address()));
macStep->setText(uintToMacStr(mac.step()));
if (!mac.has_address()) {
// 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);
ip4Address->setText(IP4STR(ip4.address()));
@ -184,8 +190,8 @@ void DeviceGroupDialog::storeDeviceGroup()
devGrp->set_device_count(devicePerVlanCount->value());
OstEmul::MacEmulation *mac = devGrp->MutableExtension(OstEmul::mac);
mac->set_address(macStrToUInt(macAddress->text()));
mac->set_step(macStrToUInt(macStep->text()));
mac->set_address(macAddress->value());
mac->set_step(macStep->value());
if (ipStack->currentIndex() == kIp4
|| ipStack->currentIndex() == kIpDual) {

View File

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

View File

@ -46,8 +46,7 @@ extend OstProto.EncapEmulation {
// Protocols
// ===========
message MacEmulation {
optional uint64 address = 1; // FIXME: default value
optional uint64 address = 1; // no default - need unique value
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