From 7561b09c1e4a3a488f519651614d39cc50ad271a Mon Sep 17 00:00:00 2001 From: Srivats P Date: Mon, 14 Mar 2016 21:16:46 +0530 Subject: [PATCH] Device Emulation (contd.): Implemented display of NDP Cache Device Detail; also fixed missing clear of NDP cache on server --- client/devicemodel.cpp | 5 +- client/devicemodel.h | 2 + client/ndpstatusmodel.cpp | 155 ++++++++++++++++++++++++++++++++++++++ client/ndpstatusmodel.h | 55 ++++++++++++++ client/ostinato.pro | 2 + server/device.cpp | 1 + 6 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 client/ndpstatusmodel.cpp create mode 100644 client/ndpstatusmodel.h diff --git a/client/devicemodel.cpp b/client/devicemodel.cpp index a261b4a..d917e80 100644 --- a/client/devicemodel.cpp +++ b/client/devicemodel.cpp @@ -20,6 +20,7 @@ along with this program. If not, see #include "devicemodel.h" #include "arpstatusmodel.h" +#include "ndpstatusmodel.h" #include "port.h" #include "emulproto.pb.h" @@ -57,6 +58,7 @@ DeviceModel::DeviceModel(QObject *parent) { port_ = NULL; arpStatusModel_ = new ArpStatusModel(this); + ndpStatusModel_ = new NdpStatusModel(this); } int DeviceModel::rowCount(const QModelIndex &parent) const @@ -236,7 +238,6 @@ QVariant DeviceModel::data(const QModelIndex &index, int role) const qWarning("%s: Unsupported field #%d", __FUNCTION__, field); -_exit: return QVariant(); } @@ -258,6 +259,8 @@ QAbstractItemModel* DeviceModel::detailModel(const QModelIndex &index) arpStatusModel_->setDeviceIndex(port_, index.row()); return arpStatusModel_; case kNdpInfo: + ndpStatusModel_->setDeviceIndex(port_, index.row()); + return ndpStatusModel_; default: return NULL; } diff --git a/client/devicemodel.h b/client/devicemodel.h index 78637d5..a16a77d 100644 --- a/client/devicemodel.h +++ b/client/devicemodel.h @@ -23,6 +23,7 @@ along with this program. If not, see #include class ArpStatusModel; +class NdpStatusModel; class Port; class DeviceModel: public QAbstractTableModel @@ -49,6 +50,7 @@ private: Port *port_; ArpStatusModel *arpStatusModel_; + NdpStatusModel *ndpStatusModel_; }; #endif diff --git a/client/ndpstatusmodel.cpp b/client/ndpstatusmodel.cpp new file mode 100644 index 0000000..4a48694 --- /dev/null +++ b/client/ndpstatusmodel.cpp @@ -0,0 +1,155 @@ +/* +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 +*/ + +#include "ndpstatusmodel.h" + +#include "port.h" + +#include "emulproto.pb.h" + +#include "uint128.h" +#include + +enum { + kIp4Address, + kMacAddress, + kStatus, + kFieldCount +}; + +static QStringList columns_ = QStringList() + << "IPv6 Address" + << "Mac Address" + << "Status"; + +NdpStatusModel::NdpStatusModel(QObject *parent) + : QAbstractTableModel(parent) +{ + port_ = NULL; + deviceIndex_ = -1; + neighbors_ = NULL; +} + +int NdpStatusModel::rowCount(const QModelIndex &parent) const +{ + if (!port_ || deviceIndex_ < 0 || parent.isValid()) + return 0; + + return port_->numNdp(deviceIndex_); +} + +int NdpStatusModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + + return columns_.size(); +} + +QVariant NdpStatusModel::headerData( + int section, + Qt::Orientation orientation, + int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + switch (orientation) { + case Qt::Horizontal: + return columns_[section]; + case Qt::Vertical: + return QString("%1").arg(section + 1); + default: + Q_ASSERT(false); // Unreachable + } + + return QVariant(); +} + +QVariant NdpStatusModel::data(const QModelIndex &index, int role) const +{ + QString str; + + if (!port_ || deviceIndex_ < 0 || !index.isValid()) + return QVariant(); + + int ndpIdx = index.row(); + int field = index.column(); + + Q_ASSERT(ndpIdx < port_->numNdp(deviceIndex_)); + Q_ASSERT(field < kFieldCount); + + const OstEmul::NdpEntry &ndp = neighbors_->ndp(ndpIdx); + + switch (field) { + case kIp4Address: + switch (role) { + case Qt::DisplayRole: + return QHostAddress( + UInt128(ndp.ip6().hi(), + ndp.ip6().lo()).toArray()) + .toString(); + default: + break; + } + return QVariant(); + + case kMacAddress: + switch (role) { + case Qt::DisplayRole: + return QString("%1").arg(ndp.mac(), 6*2, 16, QChar('0')) + .replace(QRegExp("([0-9a-fA-F]{2}\\B)"), "\\1:") + .toUpper(); + default: + break; + } + return QVariant(); + + case kStatus: + switch (role) { + case Qt::DisplayRole: + return ndp.mac() ? + QString("Resolved") : QString("Failed"); + default: + break; + } + return QVariant(); + + default: + Q_ASSERT(false); // unreachable! + break; + } + + qWarning("%s: Unsupported field #%d", __FUNCTION__, field); + return QVariant(); +} + +void NdpStatusModel::setDeviceIndex(Port *port, int deviceIndex) +{ + port_ = port; + deviceIndex_ = deviceIndex; + if (port_) + neighbors_ = port_->deviceNeighbors(deviceIndex); + reset(); +} + +void NdpStatusModel::updateNdpStatus() +{ + reset(); +} diff --git a/client/ndpstatusmodel.h b/client/ndpstatusmodel.h new file mode 100644 index 0000000..c00c6b0 --- /dev/null +++ b/client/ndpstatusmodel.h @@ -0,0 +1,55 @@ +/* +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 +*/ + +#ifndef _NDP_STATUS_MODEL_H +#define _NDP_STATUS_MODEL_H + +#include + +class Port; +namespace OstEmul { + class DeviceNeighborList; +} + +class NdpStatusModel: public QAbstractTableModel +{ + Q_OBJECT +public: + NdpStatusModel(QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + QVariant data(const QModelIndex &index, int role) const; + + void setDeviceIndex(Port *port, int deviceIndex); + +public slots: + void updateNdpStatus(); + +private: + Port *port_; + int deviceIndex_; + const OstEmul::DeviceNeighborList *neighbors_; +}; + +#endif + diff --git a/client/ostinato.pro b/client/ostinato.pro index 75f0604..e644f62 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -41,6 +41,7 @@ HEADERS += \ dumpview.h \ hexlineedit.h \ mainwindow.h \ + ndpstatusmodel.h \ packetmodel.h \ port.h \ portconfigdialog.h \ @@ -84,6 +85,7 @@ SOURCES += \ hexlineedit.cpp \ main.cpp \ mainwindow.cpp \ + ndpstatusmodel.cpp \ packetmodel.cpp \ port.cpp \ portconfigdialog.cpp \ diff --git a/server/device.cpp b/server/device.cpp index 656531c..34ea989 100644 --- a/server/device.cpp +++ b/server/device.cpp @@ -268,6 +268,7 @@ void Device::resolveGateway() void Device::clearNeighbors() { arpTable_.clear(); + ndpTable_.clear(); } // Resolve the Neighbor IP address for this to-be-transmitted pktBuf