From f220482876104bed3c948886a16e9742b64106c0 Mon Sep 17 00:00:00 2001 From: "Srivats P." Date: Sat, 9 Aug 2008 03:22:13 +0000 Subject: [PATCH] Added Google Protocol Buffers as the serialization format between client and server. Initial Checkin. PB related code not yet complete --- Makefile | 5 + client/hexlineedit.cpp | 3 +- client/ostinato.pro | 8 +- client/packetmodel.cpp | 17 +- client/port.cpp | 74 ++- client/port.h | 71 ++- client/portgroup.cpp | 143 +++++- client/portgroup.h | 45 +- client/portstatsmodel.cpp | 4 + client/portswindow.cpp | 1 - client/stream.cpp | 11 + client/stream.h | 862 +++++++++++++++++++++++----------- client/streamconfigdialog.cpp | 233 +++++---- client/streamconfigdialog.h | 3 +- client/streamconfigdialog.ui | 148 +++--- client/streammodel.cpp | 2 +- common/Makefile | 14 + common/protocol.proto | 302 ++++++++++++ rpc/pbhelper.h | 66 +++ rpc/pbrpc.pro | 13 + rpc/pbrpcchannel.cpp | 189 ++++++++ rpc/pbrpcchannel.h | 74 +++ rpc/pbrpccommon.h | 52 ++ rpc/pbrpccontroller.h | 27 ++ rpc/rpcserver.cpp | 180 +++++++ rpc/rpcserver.h | 44 ++ server/abstracthost.h | 2 + server/drone.cpp | 17 +- server/drone.h | 19 +- server/drone.pro | 10 +- server/myservice.cpp | 290 ++++++++++++ server/myservice.h | 146 ++++++ server/rxtx.cpp | 10 +- server/rxtx.h | 8 + 34 files changed, 2598 insertions(+), 495 deletions(-) create mode 100644 Makefile create mode 100644 common/Makefile create mode 100644 common/protocol.proto create mode 100644 rpc/pbhelper.h create mode 100644 rpc/pbrpc.pro create mode 100644 rpc/pbrpcchannel.cpp create mode 100644 rpc/pbrpcchannel.h create mode 100644 rpc/pbrpccommon.h create mode 100644 rpc/pbrpccontroller.h create mode 100644 rpc/rpcserver.cpp create mode 100644 rpc/rpcserver.h create mode 100644 server/myservice.cpp create mode 100644 server/myservice.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c24ac11 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +all: + $(MAKE) -C rpc install + $(MAKE) -C common + $(MAKE) -C server + $(MAKE) -C client diff --git a/client/hexlineedit.cpp b/client/hexlineedit.cpp index a983bfd..85d5ccf 100644 --- a/client/hexlineedit.cpp +++ b/client/hexlineedit.cpp @@ -1,7 +1,8 @@ #include "hexlineedit.h" #include "qdebug.h" -QString & uintToHexStr(quint32 num, QString &hexStr, quint8 octets); +QString & uintToHexStr(quint64 num, QString &hexStr, quint8 octets); + HexLineEdit::HexLineEdit( QWidget * parent) : QLineEdit(parent) { diff --git a/client/ostinato.pro b/client/ostinato.pro index 07dcdc0..4b1cb69 100644 --- a/client/ostinato.pro +++ b/client/ostinato.pro @@ -1,6 +1,8 @@ TEMPLATE = app CONFIG += qt debug QT += network +INCLUDEPATH += "c:\msys\1.0\local\include" "..\rpc\" +LIBS += -L"c:\msys\1.0\local\lib" -lprotobuf -L"..\rpc\debug" -lpbrpc RESOURCES += ostinato.qrc HEADERS += \ dumpview.h \ @@ -31,7 +33,6 @@ SOURCES += \ hexlineedit.cpp \ main.cpp \ mainwindow.cpp \ - mythread.cpp \ packetmodel.cpp \ port.cpp \ portgroup.cpp \ @@ -44,5 +45,10 @@ SOURCES += \ streamconfigdialog.cpp \ streammodel.cpp +# Protocol Buffer Sources + +SOURCES += \ + ..\common\protocol.pb.cc + # TODO(LOW): Test only include(modeltest.pri) diff --git a/client/packetmodel.cpp b/client/packetmodel.cpp index 9064b1d..8711b53 100644 --- a/client/packetmodel.cpp +++ b/client/packetmodel.cpp @@ -167,6 +167,7 @@ void PacketModel::populatePacketProtocols() // Clear the protocols list mPacketProtocols.clear(); +#if 0 // FIXME: protobuf // Check and populate L2 Protocol switch(mpStream->proto.ft) { @@ -251,6 +252,7 @@ void PacketModel::populatePacketProtocols() _data: mPacketProtocols.append(PTYP_DATA); +#endif } int PacketModel::protoCount() const @@ -373,7 +375,7 @@ QVariant PacketModel::ethField(int field, int role) const FieldInfo info; // FIXME(MED): Mac Addr formatting - +#if 0 // FIXME protobuf switch(field) { case 0: @@ -409,6 +411,7 @@ QVariant PacketModel::ethField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code +#endif return QVariant(); } @@ -416,6 +419,7 @@ QVariant PacketModel::llcField(int field, int role) const { FieldInfo info; +#if 0 // FIXME: protobuf switch(field) { case 0: @@ -449,6 +453,7 @@ QVariant PacketModel::llcField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code +#endif return QVariant(); } @@ -456,6 +461,7 @@ QVariant PacketModel::snapField(int field, int role) const { FieldInfo info; +#if 0 // FIXME: protobuf switch(field) { case 0: @@ -485,6 +491,7 @@ QVariant PacketModel::snapField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code +#endif return QVariant(); } @@ -492,6 +499,7 @@ QVariant PacketModel::svlanField(int field, int role) const { FieldInfo info; +#if 0 // FIXME: protobuf switch(field) { case 0: @@ -530,6 +538,7 @@ QVariant PacketModel::svlanField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code +#endif return QVariant(); } @@ -538,6 +547,7 @@ QVariant PacketModel::ipField(int field, int role) const { FieldInfo info; +#if 0 // FIXME: protobuf switch(field) { case 0: @@ -614,6 +624,7 @@ QVariant PacketModel::ipField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code +#endif return QVariant(); } @@ -622,6 +633,7 @@ QVariant PacketModel::tcpField(int field, int role) const { FieldInfo info; +#if 0 // FIXME: protobuf switch(field) { case 0: @@ -690,6 +702,7 @@ QVariant PacketModel::tcpField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code +#endif return QVariant(); } @@ -698,6 +711,7 @@ QVariant PacketModel::udpField(int field, int role) const { FieldInfo info; +#if 0 // FIXME:protobuf switch(field) { case 0: @@ -736,6 +750,7 @@ QVariant PacketModel::udpField(int field, int role) const } Q_ASSERT(1 == 1); // Unreachable code +#endif return QVariant(); } diff --git a/client/port.cpp b/client/port.cpp index f7122d3..2196e7d 100644 --- a/client/port.cpp +++ b/client/port.cpp @@ -1,17 +1,82 @@ +#include + +#include + #include "port.h" +#include "pbhelper.h" + Port::Port(quint32 id, quint32 portGroupId) { - mPortId = id; + d.set_port_id(id); mPortGroupId = portGroupId; - mAdminStatus = AdminDisable; - mOperStatus = OperDown; - mControlMode = ControlShared; +#if 0 // PB // FIXME(HI): TEST only for(int i = 0; i < 10; i++) mPortStats[i] = mPortGroupId*10000+mPortId*100+i; +#endif +} + +void Port::updatePortConfig(OstProto::PortConfig *portConfig) +{ + + PbHelper pbh; + + pbh.update(&d, portConfig); +#if 0 + const ::google::protobuf::Message::Reflection *ref1; + ::google::protobuf::Message::Reflection *ref2; + std::vector list; + + qDebug("In %s", __FUNCTION__); + + ref1 = portConfig.GetReflection(); + ref1->ListFields(&list); + + ref2 = d.GetReflection(); + + for (uint i=0; i < list.size(); i++) + { + const ::google::protobuf::FieldDescriptor *f1, *f2; + + f1 = list[i]; + f2 = d.GetDescriptor()->FindFieldByName(f1->name()); + switch(f2->type()) + { + case ::google::protobuf::FieldDescriptor::TYPE_UINT32: + ref2->SetUInt32(f2, ref1->GetUInt32(f1)); + break; + case ::google::protobuf::FieldDescriptor::TYPE_BOOL: + ref2->SetBool(f2, ref1->GetBool(f1)); + break; + case ::google::protobuf::FieldDescriptor::TYPE_STRING: + ref2->SetString(f2, ref1->GetString(f1)); + break; + default: + qDebug("unhandled Field Type"); + break; + } + } + + if (msg->GetDescriptor() != OstProto::PortConfig::descriptor()) + { + qDebug("%s: invalid Message Descriptor (%s)", __FUNCTION__, + msg->GetDescriptor()->name()); + goto _error_exit; + } + + portConfig = msg; + + // check for "required" param + if (!portConfig.has_port_id()) + { + qDebug("%s: invalid Message Descriptor (%s)", __FUNCTION__, + msg->GetDescriptor()->name()); + goto _error_exit; + } +#endif } void Port::insertDummyStreams() @@ -24,3 +89,4 @@ void Port::insertDummyStreams() #endif } + diff --git a/client/port.h b/client/port.h index 13795ff..f308b3b 100644 --- a/client/port.h +++ b/client/port.h @@ -6,48 +6,77 @@ #include #include "stream.h" +class StreamModel; + class Port { - - friend class StreamModel; + +#if 0 // PB friend class PortStatsModel; +#endif + friend class StreamModel; + + //friend class PbHelper; + + // FIXME: non-friend mechanism + //friend QList* StreamModel::currentPortStreamList(void); + +private: + OstProto::PortConfig d; + + quint32 mPortId; + quint32 mPortGroupId; + QString mUserAlias; // user defined + + QList mStreams; + +#if 0 // PB + quint32 mPortId; + QString mName; + QString mDescription; + AdminStatus mAdminStatus; + OperStatus mOperStatus; + ControlMode mControlMode; + + quint32 mPortStats[10]; // FIXME(HI):Hardcoding +#endif public: enum AdminStatus { AdminDisable, AdminEnable }; enum OperStatus { OperDown, OperUp }; enum ControlMode { ControlShared, ControlExclusive }; -private: - quint32 mPortId; - quint32 mPortGroupId; - QList mStreams; - QString mName; - QString mDescription; - QString mUserAlias; // user defined - AdminStatus mAdminStatus; - OperStatus mOperStatus; - ControlMode mControlMode; - - quint32 mPortStats[10]; // FIXME(HI):Hardcoding - -public: // FIXME(HIGH): default args is a hack for QList operations on Port Port(quint32 id = 0xFFFFFFFF, quint32 pgId = 0xFFFFFFFF); - quint32 id() const { return mPortId; } quint32 portGroupId() const { return mPortGroupId; } - const QString& name() const { return mName; } - const QString& description() const { return mDescription; } const QString& userAlias() const { return mUserAlias; } - void setName(QString &name) { mName = name; } + quint32 id() const + { return d.port_id(); } + const QString name() const + { return QString().fromStdString(d.name()); } + const QString description() const + { return QString().fromStdString(d.description()); } + AdminStatus adminStatus() + { return (d.is_enabled()?AdminEnable:AdminDisable); } + OperStatus operStatus() + { return (d.is_oper_up()?OperUp:OperDown); } + ControlMode controlMode() + { return (d.is_exclusive_control()?ControlExclusive:ControlShared); } + +#if 0 + void setName(QString &name) { d.name; } void setName(const char* name) { mName = QString(name); } void setDescription(QString &description) { mDescription = description; } void setDescription(const char *description) { mDescription = QString(description); } - +#endif //void setAdminEnable(AdminStatus status) { mAdminStatus = status; } void setAlias(QString &alias) { mUserAlias = alias; } //void setExclusive(bool flag); + + void updatePortConfig(OstProto::PortConfig *portConfig); + // FIXME(HIGH): Only for testing void insertDummyStreams(); }; diff --git a/client/portgroup.cpp b/client/portgroup.cpp index e8a7dfe..fa5fa0e 100644 --- a/client/portgroup.cpp +++ b/client/portgroup.cpp @@ -1,6 +1,8 @@ #include "portgroup.h" #include "../common/protocol.h" +#include + quint32 PortGroup::mPortGroupAllocId = 0; PortGroup::PortGroup(QHostAddress ip, quint16 port) @@ -8,48 +10,67 @@ PortGroup::PortGroup(QHostAddress ip, quint16 port) // Allocate an id for self mPortGroupId = PortGroup::mPortGroupAllocId++; +#if 0 // PB // Init attributes for which we values were passed to us mServerAddress = ip; mServerPort = port; // Init remaining attributes with defaults mpSocket = new QTcpSocket(this); +#endif + rpcChannel = new PbRpcChannel(ip, port); + rpcController = new PbRpcController(); + serviceStub = new OstProto::OstService::Stub(rpcChannel, + OstProto::OstService::STUB_OWNS_CHANNEL); + +#if 0 // PB // TODO: consider using QT's signal-slot autoconnect connect(mpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(on_mpSocket_stateChanged())); connect(mpSocket, SIGNAL(connected()), this, SLOT(when_connected())); connect(mpSocket, SIGNAL(disconnected()), this, SLOT(when_disconnected())); connect(mpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(when_error(QAbstractSocket::SocketError))); connect(mpSocket, SIGNAL(readyRead()), this, SLOT(when_dataAvail())); +#endif + // FIXME:Can't for my life figure out why this ain't working! + //QMetaObject::connectSlotsByName(this); + connect(rpcChannel, SIGNAL(stateChanged(QAbstractSocket::SocketState)), + this, SLOT(on_rpcChannel_stateChanged())); + connect(rpcChannel, SIGNAL(connected()), + this, SLOT(on_rpcChannel_connected())); + connect(rpcChannel, SIGNAL(disconnected()), + this, SLOT(on_rpcChannel_disconnected())); + connect(rpcChannel, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(on_rpcChannel_error(QAbstractSocket::SocketError))); } PortGroup::~PortGroup() { qDebug("PortGroup Destructor"); - // Disconnect and free TCP mpSocketet etc. + // Disconnect and free rpc channel etc. PortGroup::disconnectFromHost(); - delete mpSocket; + delete serviceStub; } +#if 0 // PB void PortGroup::connectToHost(QHostAddress ip, quint16 port) { - mServerAddress = ip; - mServerPort = port; - - PortGroup::connectToHost(); + rpcChannel->establish(ip, port) } void PortGroup::connectToHost() { qDebug("PortGroup::connectToHost()"); - mpSocket->connectToHost(mServerAddress, mServerPort); + rpcChannel->establish() } void PortGroup::disconnectFromHost() { mpSocket->disconnectFromHost(); } +#endif +#if 0 // PB // -------------------------------------------- // Private Methods // -------------------------------------------- @@ -116,22 +137,32 @@ _next: return; } +#endif // ------------------------------------------------ // Slots // ------------------------------------------------ -void PortGroup::on_mpSocket_stateChanged() +void PortGroup::on_rpcChannel_stateChanged() { qDebug("state changed"); emit portGroupDataChanged(this); } -void PortGroup::when_connected() +void PortGroup::on_rpcChannel_connected() { - qDebug("connected\n"); + OstProto::Void void_; + OstProto::PortIdList *portIdList; + qDebug("connected\n"); emit portGroupDataChanged(this); + qDebug("requesting portlist ..."); + portIdList = new OstProto::PortIdList(); + rpcController->Reset(); + serviceStub->getPortIdList(rpcController, &void_, portIdList, + NewCallback(this, &PortGroup::processPortIdList, portIdList)); + +#if 0 // PB // Ask for Port Capability tCommHdr pkt; pkt.ver = 1; @@ -141,9 +172,10 @@ void PortGroup::when_connected() pkt.msgLen = HTONS(8); mpSocket->write((char*) &pkt, sizeof(pkt)); +#endif } -void PortGroup::when_disconnected() +void PortGroup::on_rpcChannel_disconnected() { qDebug("disconnected\n"); emit portListAboutToBeChanged(mPortGroupId); @@ -152,12 +184,13 @@ void PortGroup::when_disconnected() emit portGroupDataChanged(this); } -void PortGroup::when_error(QAbstractSocket::SocketError socketError) +void PortGroup::on_rpcChannel_error(QAbstractSocket::SocketError socketError) { qDebug("error\n"); emit portGroupDataChanged(this); } +#if 0 // PB void PortGroup::when_dataAvail() { qDebug("dataAvail\n"); @@ -165,5 +198,91 @@ void PortGroup::when_dataAvail() QByteArray msg = mpSocket->read(1024); // FIXME: hardcoding ProcessMsg(msg.constData(), msg.size()); } +#endif +void PortGroup::processPortIdList(OstProto::PortIdList *portIdList) +{ + int count; + qDebug("got a portlist ..."); + + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _error_exit; + } + + count = portIdList->port_id_size(); + qDebug("%s: portid count = %d", __FUNCTION__, count); + qDebug("%s: %s", __FUNCTION__, portIdList->DebugString().c_str()); + + emit portListAboutToBeChanged(mPortGroupId); + + for(int i = 0; i < count; i++) + { + Port *p; + + p = new Port(portIdList->port_id(i), mPortGroupId); + //p->setName("name"); + //p->setDescription("Desc"); + p->insertDummyStreams(); // FIXME: only for testing + qDebug("before port append\n"); + mPorts.append(*p); + } + + emit portListChanged(mPortGroupId); + + // Request PortConfigList + { + OstProto::PortConfigList *portConfigList; + + qDebug("requesting port config list ..."); + portConfigList = new OstProto::PortConfigList(); + rpcController->Reset(); + serviceStub->getPortConfig(rpcController, + portIdList, portConfigList, NewCallback(this, + &PortGroup::processPortConfigList, portConfigList)); + } + + goto _exit; + +_error_exit: +_exit: + delete portIdList; +} + +void PortGroup::processPortConfigList(OstProto::PortConfigList *portConfigList) +{ + int count; + + qDebug("In %s", __FUNCTION__); + + if (rpcController->Failed()) + { + qDebug("%s: rpc failed", __FUNCTION__); + goto _error_exit; + } + + count = portConfigList->list_size(); + qDebug("%s: count = %d", __FUNCTION__, count); + qDebug("%s: <%s>", __FUNCTION__, portConfigList->DebugString().c_str()); + + emit portListAboutToBeChanged(mPortGroupId); + + for(int i = 0; i < count; i++) + { + uint id; + + id = portConfigList->list(i).port_id(); + // FIXME: don't mix port id & index into mPorts[] + mPorts[id].updatePortConfig(portConfigList->mutable_list(i)); + } + + emit portListChanged(mPortGroupId); + + // FIXME: check if we need new signals since we are not changing the + // number of ports, just the port data + +_error_exit: + delete portConfigList; +} diff --git a/client/portgroup.h b/client/portgroup.h index 8f5c1e3..528f48b 100644 --- a/client/portgroup.h +++ b/client/portgroup.h @@ -5,6 +5,9 @@ #include #include +#include "../common/protocol.pb.h" +#include "pbrpcchannel.h" + /* TODO HIGH MED @@ -21,10 +24,14 @@ private: quint32 mPortGroupId; static quint32 mPortGroupAllocId; QString mUserAlias; // user defined - +#if 0 // PB QTcpSocket *mpSocket; QHostAddress mServerAddress; quint16 mServerPort; +#endif + PbRpcChannel *rpcChannel; + ::google::protobuf::RpcController *rpcController; + OstProto::OstService::Stub *serviceStub; public: // FIXME(HIGH): member access QList mPorts; @@ -33,34 +40,46 @@ public: quint16 port = DEFAULT_SERVER_PORT); ~PortGroup(); - void connectToHost(); - void connectToHost(QHostAddress ip, quint16 port); - void disconnectFromHost(); + void connectToHost() { rpcChannel->establish(); } + void connectToHost(QHostAddress ip, quint16 port) + { rpcChannel->establish(ip, port); } + void disconnectFromHost() { rpcChannel->tearDown(); } int numPorts() const { return mPorts.size(); } quint32 id() const { return mPortGroupId; } - const QHostAddress& serverAddress() const { return mServerAddress; } - quint16 serverPort() const { return mServerPort; } - const QString& userAlias() const { return mUserAlias; } - QAbstractSocket::SocketState state() const { return mpSocket->state(); } + const QString& userAlias() const { return mUserAlias; } void setUserAlias(QString alias) { mUserAlias = alias; }; + const QHostAddress& serverAddress() const + { return rpcChannel->serverAddress(); } + quint16 serverPort() const + { return rpcChannel->serverPort(); } + QAbstractSocket::SocketState state() const + { return rpcChannel->state(); } + + void processPortIdList(OstProto::PortIdList *portIdList); + void processPortConfigList(OstProto::PortConfigList *portConfigList); + signals: void portGroupDataChanged(PortGroup* portGroup); void portListAboutToBeChanged(quint32 portGroupId); void portListChanged(quint32 portGroupId); private slots: - void on_mpSocket_stateChanged(); - void when_connected(); - void when_disconnected(); - void when_error(QAbstractSocket::SocketError socketError); - void when_dataAvail(); + void on_rpcChannel_stateChanged(); + void on_rpcChannel_connected(); + void on_rpcChannel_disconnected(); + void on_rpcChannel_error(QAbstractSocket::SocketError socketError); +#if 0 // PB + void on_rpcChannel_when_dataAvail(); +#endif private: +#if 0 // PB void ProcessCapabilityInfo(const char *msg, qint32 size); void ProcessMsg(const char *msg, quint32 size); +#endif }; #endif diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp index c67c7e4..435344c 100644 --- a/client/portstatsmodel.cpp +++ b/client/portstatsmodel.cpp @@ -70,7 +70,11 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const // Check role if (role == Qt::DisplayRole) + { +#if 0 // PB return pgl->mPortGroups.at(pgidx)->mPorts.at(pidx).mPortStats[index.row()]; +#endif return 0; //FIXME: Get actual port stats + } else return QVariant(); diff --git a/client/portswindow.cpp b/client/portswindow.cpp index c316b0d..2e6df17 100644 --- a/client/portswindow.cpp +++ b/client/portswindow.cpp @@ -1,5 +1,4 @@ #include "portswindow.h" -#include "streamlistmodel.h" #include "streamconfigdialog.h" #include #include diff --git a/client/stream.cpp b/client/stream.cpp index 980d26c..e153b8e 100644 --- a/client/stream.cpp +++ b/client/stream.cpp @@ -1,15 +1,25 @@ #include +quint32 Stream::mAllocId = 0; + Stream::Stream() { + mId = mAllocId++; + + mCore = new OstProto::StreamCore; + mMac = new MacProtocol; + mIp = new IpProtocol; +#if 0 // Default constructor InitDefaultMeta(); InitDefaultProto(); InitDefaultL2(); InitDefaultL3(); InitDefaultL4(); +#endif } +#if 0 void Stream::InitDefaultMeta() { // TODO(LOW): Use #defines @@ -121,3 +131,4 @@ void Stream::InitDefaultL4Udp() l4.udp.totLen = STREAM_DEF_L4_UDP_TOT_LEN; l4.udp.cksum = STREAM_DEF_L4_UDP_CKSUM; } +#endif diff --git a/client/stream.h b/client/stream.h index 4469065..4b134cb 100644 --- a/client/stream.h +++ b/client/stream.h @@ -3,17 +3,547 @@ #include #include +#include "../common/protocol.pb.h" class StreamConfigDialog; class StreamModel; class PacketModel; +// Convenience Defines FIXME +#define IP_PROTO_ICMP 0x01 +#define IP_PROTO_IGMP 0x02 +#define IP_PROTO_TCP 0x06 +#define IP_PROTO_UDP 0x11 + +#if 0 + // Protocols + struct { + FrameType ft; + + + + quint16 protoMask; +#define PM_L3_PROTO_NONE 0x0001 +#define PM_L3_PROTO_OTHER 0x0002 +#define PM_L4_PROTO_NONE 0x0004 +#define PM_L4_PROTO_OTHER 0x0008 + + quint16 etherType; +#define ETH_TYP_IP 0x0800 +#define ETH_TYP_ARP 0x0806 + + quint16 ipProto; +#define IP_PROTO_ICMP 0x01 +#define IP_PROTO_IGMP 0x02 +#define IP_PROTO_TCP 0x06 +#define IP_PROTO_UDP 0x11 + } proto; + + // L2 + struct { + // Ethernet + + + + + } eth; + } l2; +#endif + +class AbstractProtocol +{ + // TODO +}; + +class MacProtocol : public AbstractProtocol +{ +private: + OstProto::Mac d; + +public: + enum MacAddrMode { + MacAddrFixed, + MacAddrInc, + MacAddrDec + }; + + // Dst Mac + quint64 dstMac() + { return d.dst_mac(); } + + bool setDstMac(quint64 dstMac) + { d.set_dst_mac(dstMac); return true; } + + MacAddrMode dstMacMode() + { return (MacAddrMode) d.dst_mac_mode(); } + bool setDstMacMode(MacAddrMode dstMacMode) + { d.set_dst_mac_mode((OstProto::Mac::MacAddrMode)dstMacMode); return true; } + + quint16 dstMacCount() + { return d.dst_mac_count(); } + bool setDstMacCount(quint16 dstMacCount) + { d.set_dst_mac_count(dstMacCount); return true; } + + quint16 dstMacStep() + { return d.dst_mac_step(); } + bool setDstMacStep(quint16 dstMacStep) + { d.set_dst_mac_step(dstMacStep); return true; } + + // Src Mac + quint64 srcMac() + { return d.src_mac(); } + + bool setSrcMac(quint64 srcMac) + { d.set_src_mac(srcMac); return true; } + + MacAddrMode srcMacMode() + { return (MacAddrMode) d.src_mac_mode(); } + bool setSrcMacMode(MacAddrMode srcMacMode) + { d.set_src_mac_mode((OstProto::Mac::MacAddrMode)srcMacMode); return true; } + + quint16 srcMacCount() + { return d.src_mac_count(); } + bool setSrcMacCount(quint16 srcMacCount) + { d.set_src_mac_count(srcMacCount); return true; } + + quint16 srcMacStep() + { return d.src_mac_step(); } + bool setSrcMacStep(quint16 srcMacStep) + { d.set_src_mac_step(srcMacStep); return true; } +}; + +class LlcProtocol : public AbstractProtocol +{ +private: + OstProto::Llc d; + +public: + quint8 dsap() + { return d.dsap(); } + bool setDsap(quint8 dsap) + { d.set_dsap(dsap); return true; } + + quint8 ssap() + { return d.ssap(); } + bool setSsap(quint8 ssap) + { d.set_ssap(ssap); return true; } + + quint8 ctl() + { return d.ctl(); } + bool setCtl(quint8 ctl) + { d.set_ctl(ctl); return true; } + +}; + +class SnapProtocol : public AbstractProtocol +{ +private: + OstProto::Snap d; + +public: + quint32 oui() + { return d.oui(); } + bool setOui(quint32 oui) + { d.set_oui(oui); return true; } + + quint16 type() + { return d.type(); } + bool setType(quint16 type) + { d.set_type(type); return true; } +}; + +class Eth2Protocol : public AbstractProtocol +{ +private: + OstProto::Eth2 d; + +public: + quint16 type() + { return d.type(); } + bool setType(quint16 type) + { d.set_type(type); return true; } +}; + +class VlanProtocol : public AbstractProtocol +{ +// TODO +#if 0 + quint16 vlanMask; +#define VM_UNTAGGED 0x0000 +#define VM_CVLAN_TAGGED 0x0001 +#define VM_CVLAN_TPID_OVERRIDE 0x0002 +#define VM_SVLAN_TAGGED 0x0100 +#define VM_SVLAN_TPID_OVERRIDE 0x0200 + +#define VM_SINGLE_TAGGED(mask) \ +((mask & VM_CVLAN_TAGGED ) | (mask & VM_SVLAN_TAGGED)) +#define VM_DOUBLE_TAGGED(mask) \ +(mask & (VM_CVLAN_TAGGED | VM_SVLAN_TAGGED)) + + quint16 ctpid; + quint16 cvlanPrio : 3; + quint16 cvlanCfi : 1; + quint16 cvlanId : 13; + quint16 stpid; + quint16 svlanPrio : 3; + quint16 svlanCfi : 1; + quint16 svlanId : 13; +#endif +}; + +// IP +class IpProtocol : public AbstractProtocol +{ +private: + OstProto::Ip d; + +public: + + enum IpAddrMode { + IpAddrFixed, + IpAddrIncHost, + IpAddrDecHost, + IpAddrRandomHost + }; + + enum IpFlag { + IpOverrideVersion = 0x01, + IpOverrideHdrLen = 0x02, + IpOverrideTotLen = 0x03, + IpOverrideCksum = 0x04 + }; + Q_DECLARE_FLAGS(IpFlags, IpFlag); + + IpFlags ipFlags() + { + IpFlags f; + + if (d.is_override_ver()) f|= IpOverrideVersion; + if (d.is_override_hdrlen()) f|= IpOverrideHdrLen; + if (d.is_override_totlen()) f|= IpOverrideTotLen; + if (d.is_override_cksum()) f|= IpOverrideCksum; + + return f; + } + + bool setIpFlags(IpFlags ipFlags) + { + if (ipFlags.testFlag(IpOverrideVersion)) + d.set_is_override_ver(true); + else + d.set_is_override_ver(false); + + if (ipFlags.testFlag(IpOverrideHdrLen)) + d.set_is_override_hdrlen(true); + else + d.set_is_override_hdrlen(false); + + if (ipFlags.testFlag(IpOverrideTotLen)) + d.set_is_override_totlen(true); + else + d.set_is_override_totlen(false); + + if (ipFlags.testFlag(IpOverrideCksum)) + d.set_is_override_cksum(true); + else + d.set_is_override_cksum(false); + + return true; + } + + quint8 ver() + { return (d.ver_hdrlen() >> 4); } + bool setVer(quint8 ver) + { d.set_ver_hdrlen((d.ver_hdrlen() & 0x0F) | (ver << 4)); return true; } + + quint8 hdrLen() + { return (d.ver_hdrlen() & 0xF); } + bool setHdrLen(quint8 hdrLen) + { d.set_ver_hdrlen((d.ver_hdrlen() & 0xF0) | hdrLen); return true; } + + quint8 tos() + { return d.tos(); } + bool setTos(quint8 tos) + { d.set_tos(tos); return true; } + + quint16 totLen() + { return d.tot_len(); } + bool setTotLen(quint16 totLen) + { d.set_tot_len(totLen); return true; } + + quint16 id() + { return d.id(); } + bool setId(quint16 id) + { d.set_id(id); return true; } + + quint16 flags() + { return d.flags(); } + bool setFlags(quint16 flags) + { d.set_flags(flags); return true; } +#define IP_FLAG_UNUSED 0x1 +#define IP_FLAG_DF 0x2 +#define IP_FLAG_MF 0x4 + + quint16 fragOfs() + { return d.frag_ofs(); } + bool setFragOfs(quint16 fragOfs) + { d.set_frag_ofs(fragOfs); return true; } + + quint8 ttl() + { return d.ttl(); } + bool setTtl(quint8 ttl) + { d.set_ttl(ttl); return true; } + + quint8 proto() + { return d.proto(); } + bool setProto(quint8 proto) + { d.set_proto(proto); return true; } + + quint16 cksum() + { return d.cksum(); } + bool setCksum(quint16 cksum) + { d.set_cksum(cksum); return true; } + + // Source IP + quint32 srcIp() + { return d.src_ip(); } + bool setSrcIp(quint32 srcIp) + { d.set_src_ip(srcIp); return true; } + + IpAddrMode srcIpMode() + { return (IpAddrMode) d.src_ip_mode(); } + bool setSrcIpMode(IpAddrMode srcIpMode) + { d.set_src_ip_mode((OstProto::Ip::IpAddrMode)srcIpMode); return true; } + + quint16 srcIpCount() + { return d.src_ip_count(); } + bool setSrcIpCount(quint16 srcIpCount) + { d.set_src_ip_count(srcIpCount); return true; } + + quint32 srcIpMask() + { return d.src_ip_mask(); } + bool setSrcIpMask(quint32 srcIpMask) + { d.set_src_ip_mask(srcIpMask); return true; } + + // Destination IP + quint32 dstIp() + { return d.dst_ip(); } + bool setDstIp(quint32 dstIp) + { d.set_dst_ip(dstIp); return true; } + + IpAddrMode dstIpMode() + { return (IpAddrMode) d.dst_ip_mode(); } + bool setDstIpMode(IpAddrMode dstIpMode) + { d.set_dst_ip_mode((OstProto::Ip::IpAddrMode)dstIpMode); return true; } + + quint16 dstIpCount() + { return d.dst_ip_count(); } + bool setDstIpCount(quint16 dstIpCount) + { d.set_dst_ip_count(dstIpCount); return true; } + + quint32 dstIpMask() + { return d.dst_ip_mask(); } + bool setDstIpMask(quint32 dstIpMask) + { d.set_dst_ip_mask(dstIpMask); return true; } + + // TODO: Options +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(IpProtocol::IpFlags) + +class ArpProtocol: public AbstractProtocol +{ + // TODO: ARP +}; + +// TCP +class TcpProtocol : public AbstractProtocol +{ +private: + OstProto::Tcp d; + +public: + enum TcpFlag + { + TcpOverrideHdrLen = 0x01, + TcpOverrideCksum = 0x02 + }; + Q_DECLARE_FLAGS(TcpFlags, TcpFlag); + + TcpFlags tcpFlags() + { + TcpFlags f; + + if (d.is_override_hdrlen()) f|= TcpOverrideHdrLen; + if (d.is_override_cksum()) f|= TcpOverrideCksum; + + return f; + } + + bool setTcpFlags(TcpFlags tcpFlags) + { + if (tcpFlags.testFlag(TcpOverrideHdrLen)) + d.set_is_override_hdrlen(true); + else + d.set_is_override_hdrlen(false); + + if (tcpFlags.testFlag(TcpOverrideCksum)) + d.set_is_override_cksum(true); + else + d.set_is_override_cksum(false); + + return true; + } + + quint16 srcPort() + { return d.src_port(); } + bool setSrcPort(quint16 srcPort) + { d.set_src_port(srcPort); return true; } + + quint16 dstPort() + { return d.dst_port(); } + bool setdstPort(quint16 dstPort) + { d.set_dst_port(dstPort); return true; } + + quint32 seqNum() + { return d.seq_num(); } + bool setSeqNum(quint32 seqNum) + { d.set_seq_num(seqNum); return true;} + + quint32 ackNum() + { return d.ack_num(); } + bool setAckNum(quint32 ackNum) + { d.set_ack_num(ackNum); return true;} + + quint8 hdrLen() + { return (d.hdrlen_rsvd() >> 4); } + bool setHdrLen(quint8 hdrLen) + { d.set_hdrlen_rsvd((d.hdrlen_rsvd() & 0x0F) | (hdrLen << 4)); return true; } + + quint8 rsvd() + { return (d.hdrlen_rsvd() & 0xF); } + bool setRsvd(quint8 rsvd) + { d.set_hdrlen_rsvd((d.hdrlen_rsvd() & 0xF0) | rsvd); return true; } + + + // TODO: convert to enum maybe? + quint8 flags() + { return d.flags(); } + bool setFlags(quint8 flags) + { d.set_flags(flags); return true; } +#define TCP_FLAG_URG 0x01 +#define TCP_FLAG_ACK 0x02 +#define TCP_FLAG_PSH 0x04 +#define TCP_FLAG_RST 0x08 +#define TCP_FLAG_SYN 0x10 +#define TCP_FLAG_FIN 0x20 + + quint16 window() + { return d.window(); } + bool setWindow(quint16 window) + { d.set_window(window); return true; } + + quint16 cksum() + { return d.cksum(); } + bool setCksum(quint16 cksum) + { d.set_cksum(cksum); return true; } + + quint16 urg_ptr() + { return d.urg_ptr(); } + bool seturg_ptr(quint16 urg_ptr) + { d.set_urg_ptr(urg_ptr); return true; } + +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(TcpProtocol::TcpFlags) + + +// UDP +class UdpProtocol : public AbstractProtocol +{ +private: + OstProto::Udp d; + +public: + enum UdpFlag + { + UdpOverrideTotLen = 0x01, + UdpOverrideCksum = 0x02 + }; + Q_DECLARE_FLAGS(UdpFlags, UdpFlag); + + UdpFlags udpFlags() + { + UdpFlags f; + + if (d.is_override_totlen()) f|= UdpOverrideTotLen; + if (d.is_override_cksum()) f|= UdpOverrideCksum; + + return f; + } + + bool setUdpFlags(UdpFlags udpFlags) + { + if (udpFlags.testFlag(UdpOverrideTotLen)) + d.set_is_override_totlen(true); + else + d.set_is_override_totlen(false); + + if (udpFlags.testFlag(UdpOverrideCksum)) + d.set_is_override_cksum(true); + else + d.set_is_override_cksum(false); + + return true; + } + + quint16 srcPort() + { return d.src_port(); } + bool setSrcPort(quint16 srcPort) + { d.set_src_port(srcPort); return true; } + + quint16 dstPort() + { return d.dst_port(); } + bool setdstPort(quint16 dstPort) + { d.set_dst_port(dstPort); return true; } + + quint16 totLen() + { return d.totlen(); } + bool setTotLen(quint16 totLen) + { d.set_totlen(totLen); return true; } + + quint16 cksum() + { return d.cksum(); } + bool setCksum(quint16 cksum) + { d.set_cksum(cksum); return true; } + +}; + +class IcmpProtocol { +// TODO: ICMP +}; + +class IgmpProtocol { +// TODO: IGMP +}; + + class Stream { + static quint32 mAllocId; + + quint32 mId; + OstProto::StreamCore *mCore; + + MacProtocol *mMac; + IpProtocol *mIp; + +#if 0 friend class StreamConfigDialog; friend class StreamModel; friend class PacketModel; +#endif +public: enum FrameType { e_ft_none, e_ft_eth_2, @@ -36,273 +566,78 @@ class Stream { e_fl_random }; - enum MacAddrMode { - e_mm_fixed, - e_mm_inc, - e_mm_dec, - }; - - enum IpAddrMode { - e_im_fixed, - e_im_inc_host, - e_im_dec_host, - e_im_random_host - }; - - // Meta Data - struct { - // Data Pattern - DataPatternMode patternMode; - quint32 pattern; - quint16 dataStartOfs; - - // Frame Length (includes CRC) - FrameLengthMode lenMode; - quint16 frameLen; - quint16 frameLenMin; - quint16 frameLenMax; - } meta; - - // Protocols - struct { - FrameType ft; - - quint8 dsap; - quint8 ssap; - quint8 ctl; - quint8 ouiMsb; - quint16 ouiLshw; - - quint16 protoMask; -#define PM_L3_PROTO_NONE 0x0001 -#define PM_L3_PROTO_OTHER 0x0002 -#define PM_L4_PROTO_NONE 0x0004 -#define PM_L4_PROTO_OTHER 0x0008 - - quint16 etherType; -#define ETH_TYP_IP 0x0800 -#define ETH_TYP_ARP 0x0806 - - quint16 ipProto; -#define IP_PROTO_ICMP 0x01 -#define IP_PROTO_IGMP 0x02 -#define IP_PROTO_TCP 0x06 -#define IP_PROTO_UDP 0x11 - } proto; - - // L2 - struct { - // Ethernet - struct { - // Dst Mac - quint16 dstMacMshw; - quint32 dstMacLsw; - MacAddrMode dstMacMode; - quint16 dstMacCount; - quint16 dstMacStep; - - // srcMac - quint16 srcMacMshw; - quint32 srcMacLsw; - MacAddrMode srcMacMode; - quint16 srcMacCount; - quint16 srcMacStep; - - - quint16 vlanMask; -#define VM_UNTAGGED 0x0000 -#define VM_CVLAN_TAGGED 0x0001 -#define VM_CVLAN_TPID_OVERRIDE 0x0002 -#define VM_SVLAN_TAGGED 0x0100 -#define VM_SVLAN_TPID_OVERRIDE 0x0200 - -#define VM_SINGLE_TAGGED(mask) \ - ((mask & VM_CVLAN_TAGGED ) | (mask & VM_SVLAN_TAGGED)) -#define VM_DOUBLE_TAGGED(mask) \ - (mask & (VM_CVLAN_TAGGED | VM_SVLAN_TAGGED)) - - - - quint16 ctpid; - quint16 cvlanPrio : 3; - quint16 cvlanCfi : 1; - quint16 cvlanId : 13; - quint16 stpid; - quint16 svlanPrio : 3; - quint16 svlanCfi : 1; - quint16 svlanId : 13; - } eth; - } l2; - - struct { - // IP - struct { - quint8 ipMask; -#define IM_OVERRIDE_VERSION 0x01 -#define IM_OVERRIDE_HDRLEN 0x02 -#define IM_OVERRIDE_TOTLEN 0x04 -#define IM_OVERRIDE_CKSUM 0x08 -#define STREAM_DEF_IP_MASK 0x00 - - quint8 ver : 4; -#define STREAM_DEF_L3_IP_VER 0x4 - - quint8 hdrLen : 4; -#define STREAM_DEF_L3_IP_HDR_LEN 0x5 - - quint8 tos; -#define STREAM_DEF_L3_IP_TOS 0x00 - - quint16 totLen; -#define STREAM_DEF_L3_IP_TOT_LEN 0x00 - - quint16 id; -#define STREAM_DEF_L3_IP_ID 0x1234 - - quint16 flags : 3; -#define IP_FLAG_UNUSED 0x1 -#define IP_FLAG_DF 0x2 -#define IP_FLAG_MF 0x4 -#define STREAM_DEF_L3_IP_FLAGS 0x00 - - quint16 fragOfs : 13; -#define STREAM_DEF_L3_IP_FRAG_OFS 0x0000 - - quint8 ttl; -#define STREAM_DEF_L3_IP_TTL 0x7F - - quint8 proto; -#define STREAM_DEF_L3_IP_PROTO 0x00 - - quint16 cksum; -#define STREAM_DEF_L3_IP_CKSUM 0x0000 - - // Source IP - quint32 srcIp; -#define STREAM_DEF_L3_IP_SRC_IP 0x02020202 - - IpAddrMode srcIpMode; -#define STREAM_DEF_L3_IP_SRC_IP_MODE e_im_fixed - - quint16 srcIpCount; -#define STREAM_DEF_L3_IP_SRC_IP_COUNT 16 - - quint32 srcIpMask; -#define STREAM_DEF_L3_IP_SRC_IP_MASK 0xFFFFFFFF - - // Destination IP - quint32 dstIp; -#define STREAM_DEF_L3_IP_DST_IP 0x01010101 - - IpAddrMode dstIpMode; -#define STREAM_DEF_L3_IP_DST_IP_MODE e_im_fixed - - quint16 dstIpCount; -#define STREAM_DEF_L3_IP_DST_IP_COUNT 16 - - quint32 dstIpMask; -#define STREAM_DEF_L3_IP_DST_IP_MASK 0xFFFFFFFF - - // TODO: Options - } ip; - - // TODO: ARP - struct { - } arp; - } l3; - - // L4 - struct { - // TCP - struct { - quint32 tcpMask; -#define TM_OVERRIDE_HDRLEN 0x1 -#define TM_OVERRIDE_CKSUM 0x2 -#define STREAM_DEF_L4_TCP_TCP_MASK 0x00; - - quint16 srcPort; -#define STREAM_DEF_L4_TCP_SRC_PORT 8902; - - quint16 dstPort; -#define STREAM_DEF_L4_TCP_DST_PORT 80 - - quint32 seqNum; -#define STREAM_DEF_L4_TCP_SEQ_NUM 129018 - - quint32 ackNum; -#define STREAM_DEF_L4_TCP_ACK_NUM 98223 - - quint8 hdrLen : 4; -#define STREAM_DEF_L4_TCP_HDR_LEN 0x5 - - quint8 rsvd : 4; -#define STREAM_DEF_L4_TCP_RSVD 0x0 - - quint8 flags; -#define TCP_FLAG_URG 0x01 -#define TCP_FLAG_ACK 0x02 -#define TCP_FLAG_PSH 0x04 -#define TCP_FLAG_RST 0x08 -#define TCP_FLAG_SYN 0x10 -#define TCP_FLAG_FIN 0x20 -#define STREAM_DEF_L4_TCP_FLAGS 0x00 - - - quint16 window; -#define STREAM_DEF_L4_TCP_WINDOW 1024 - - quint16 cksum; -#define STREAM_DEF_L4_TCP_CKSUM 0x0000 - - quint16 urgPtr; -#define STREAM_DEF_L4_TCP_URG_PTR 0x0000 - } tcp; - - // UDP - struct { - quint32 udpMask; -#define UM_OVERRIDE_TOTLEN 0x01 -#define UM_OVERRIDE_CKSUM 0x02 -#define STREAM_DEF_L4_UDP_UDP_MASK 0x00 - - quint16 srcPort; -#define STREAM_DEF_L4_UDP_SRC_PORT 8902 - - quint16 dstPort; -#define STREAM_DEF_L4_UDP_DST_PORT 80 - - quint16 totLen; -#define STREAM_DEF_L4_UDP_TOT_LEN 0x0000 - - quint16 cksum; -#define STREAM_DEF_L4_UDP_CKSUM 0x0000 - } udp; - - // TODO: ICMP - struct { - } icmp; - - // TODO: IGMP - struct { - } igmp; - } l4; - - QString mName; - bool mIsEnabled; - -// ------------------------------------------------------- -// Methods -// ------------------------------------------------------- -public: + // ------------------------------------------------------- + // Methods + // ------------------------------------------------------- Stream(); - int enable(bool flag); - const QString& name() const { return mName; } - bool isEnabled() const { return mIsEnabled; } - void setName(QString name) { mName = name; } - void setEnabled(bool isEnabled) { mIsEnabled = isEnabled; } + quint32 id() + { return mId;} + + quint32 ordinal() + { return mCore->ordinal();} + bool setOrderdinal(quint32 ordinal) + { mCore->set_ordinal(ordinal); return true; } + + bool isEnabled() const + { return mCore->is_enabled(); } + bool setIsEnabled(bool flag) + { mCore->set_is_enabled(flag); return true; } + + const QString name() const + { return QString().fromStdString(mCore->name()); } + bool setName(QString name) + { mCore->set_name(name.toStdString()); return true; } + + FrameType frameType() + { return (FrameType) mCore->ft(); } + bool setFrameType(FrameType frameType) + { mCore->set_ft((OstProto::StreamCore::FrameType) frameType); return true; } + + // Data Pattern + DataPatternMode patternMode() + { return (DataPatternMode) mCore->pattern_mode(); } + bool setPatternMode(DataPatternMode patternMode) + { mCore->set_pattern_mode( + (OstProto::StreamCore::DataPatternMode) patternMode); return true; } + + quint32 pattern() + { return mCore->pattern(); } + bool setPattern(quint32 pattern) + { mCore->set_pattern(pattern); return true; } + + // Frame Length (includes CRC) + FrameLengthMode lenMode() + { return (FrameLengthMode) mCore->len_mode(); } + bool setLenMode(FrameLengthMode lenMode) + { mCore->set_len_mode( + (OstProto::StreamCore::FrameLengthMode) lenMode); return true; } + + quint16 frameLen() + { return mCore->frame_len(); } + bool setFrameLen(quint16 frameLen) + { mCore->set_frame_len(frameLen); return true; } + + quint16 frameLenMin() + { return mCore->frame_len_min(); } + bool setFrameLenMin(quint16 frameLenMin) + { mCore->set_frame_len_min(frameLenMin); return true; } + + quint16 frameLenMax() + { return mCore->frame_len_max(); } + bool setFrameLenMax(quint16 frameLenMax) + { mCore->set_frame_len_max(frameLenMax); return true; } + +// TODO +#if 0 + quint16 dataStartOfs; +#endif + + MacProtocol* mac() { return mMac; } + IpProtocol* ip() { return mIp; } private: +#if 0 void InitDefaultMeta(); void InitDefaultProto(); void InitDefaultL2(); @@ -311,6 +646,7 @@ private: void InitDefaultL4(); void InitDefaultL4Tcp(); void InitDefaultL4Udp(); +#endif }; #endif diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp index f51c49e..8e6a8a6 100644 --- a/client/streamconfigdialog.cpp +++ b/client/streamconfigdialog.cpp @@ -82,9 +82,29 @@ StreamConfigDialog::~StreamConfigDialog() void StreamConfigDialog::on_cmbDstMacMode_currentIndexChanged(QString mode) { if (mode == "Fixed") + { leDstMacCount->setEnabled(FALSE); + leDstMacStep->setEnabled(FALSE); + } else + { leDstMacCount->setEnabled(TRUE); + leDstMacStep->setEnabled(TRUE); + } +} + +void StreamConfigDialog::on_cmbSrcMacMode_currentIndexChanged(QString mode) +{ + if (mode == "Fixed") + { + leSrcMacCount->setEnabled(FALSE); + leSrcMacStep->setEnabled(FALSE); + } + else + { + leSrcMacCount->setEnabled(TRUE); + leSrcMacStep->setEnabled(TRUE); + } } void StreamConfigDialog::on_pbPrev_clicked() @@ -246,7 +266,7 @@ void StreamConfigDialog::update_NumPacketsAndNumBursts() leNumBursts->setEnabled(false); } -QString & uintToHexStr(quint32 num, QString &hexStr, quint8 octets) +QString & uintToHexStr(quint64 num, QString &hexStr, quint8 octets) { int i; QChar zero('0'); @@ -291,19 +311,19 @@ void StreamConfigDialog::LoadCurrentStream() // Meta Data { - cmbPatternMode->setCurrentIndex(pStream->meta.patternMode); - lePattern->setText(uintToHexStr(pStream->meta.pattern, str, 4)); + cmbPatternMode->setCurrentIndex(pStream->patternMode()); + lePattern->setText(uintToHexStr(pStream->pattern(), str, 4)); - cmbPktLenMode->setCurrentIndex(pStream->meta.lenMode); - lePktLen->setText(str.setNum(pStream->meta.frameLen)); - lePktLenMin->setText(str.setNum(pStream->meta.frameLenMin)); - lePktLenMax->setText(str.setNum(pStream->meta.frameLenMax)); + cmbPktLenMode->setCurrentIndex(pStream->lenMode()); + lePktLen->setText(str.setNum(pStream->frameLen())); + lePktLenMin->setText(str.setNum(pStream->frameLenMin())); + lePktLenMax->setText(str.setNum(pStream->frameLenMax())); } // Protocols { - qDebug("ft = %d\n", pStream->proto.ft); - switch(pStream->proto.ft) + qDebug("ft = %d\n", pStream->frameType()); + switch(pStream->frameType()) { case Stream::e_ft_none: rbFtNone->setChecked(TRUE); @@ -321,6 +341,9 @@ void StreamConfigDialog::LoadCurrentStream() rbFtLlcSnap->setChecked(TRUE); break; } + +// TODO +#if 0 leDsap->setText(uintToHexStr(pStream->proto.dsap, str, 1)); leSsap->setText(uintToHexStr(pStream->proto.ssap, str, 1)); leControl->setText(uintToHexStr(pStream->proto.ctl, str, 1)); @@ -351,24 +374,23 @@ void StreamConfigDialog::LoadCurrentStream() // ... then for None/Other rbL4None->setChecked((pStream->proto.protoMask & PM_L4_PROTO_NONE) > 0); rbL4Other->setChecked((pStream->proto.protoMask & PM_L4_PROTO_OTHER) > 0); +#endif } // L2 { // L2 | Ethernet { - leDstMac->setText(uintToHexStr(pStream->l2.eth.dstMacMshw, str, 2) + - uintToHexStr(pStream->l2.eth.dstMacLsw, str, 4)); - cmbDstMacMode->setCurrentIndex(pStream->l2.eth.dstMacMode); - leDstMacCount->setText(str.setNum(pStream->l2.eth.dstMacCount)); - leDstMacStep->setText(str.setNum(pStream->l2.eth.dstMacStep)); + leDstMac->setText(uintToHexStr(pStream->mac()->dstMac(), str, 6)); + cmbDstMacMode->setCurrentIndex(pStream->mac()->dstMacMode()); + leDstMacCount->setText(str.setNum(pStream->mac()->dstMacCount())); + leDstMacStep->setText(str.setNum(pStream->mac()->dstMacStep())); - leSrcMac->setText(uintToHexStr(pStream->l2.eth.srcMacMshw, str, 2) + - uintToHexStr(pStream->l2.eth.srcMacLsw, str, 4)); - cmbSrcMacMode->setCurrentIndex(pStream->l2.eth.srcMacMode); - leSrcMacCount->setText(str.setNum(pStream->l2.eth.srcMacCount)); - leSrcMacStep->setText(str.setNum(pStream->l2.eth.srcMacStep)); - + leSrcMac->setText(uintToHexStr(pStream->mac()->srcMac(), str, 6)); + cmbSrcMacMode->setCurrentIndex(pStream->mac()->srcMacMode()); + leSrcMacCount->setText(str.setNum(pStream->mac()->srcMacCount())); + leSrcMacStep->setText(str.setNum(pStream->mac()->srcMacStep())); +#if 0 cmbCvlanPrio->setCurrentIndex(pStream->l2.eth.cvlanPrio); cmbCvlanCfi->setCurrentIndex(pStream->l2.eth.cvlanCfi); leCvlanId->setText(str.setNum(pStream->l2.eth.cvlanId)); @@ -382,43 +404,48 @@ void StreamConfigDialog::LoadCurrentStream() leSvlanTpid->setText(str.setNum(pStream->l2.eth.stpid)); cbSvlanTpidOverride->setChecked((pStream->l2.eth.vlanMask & VM_SVLAN_TPID_OVERRIDE) > 0); gbSvlan->setChecked((pStream->l2.eth.vlanMask & VM_SVLAN_TAGGED) > 0); +#endif } } - + // L3 { // L3 | IP { - leIpVersion->setText(str.setNum(pStream->l3.ip.ver)); - cbIpVersionOverride->setChecked((pStream->l3.ip.ipMask & IM_OVERRIDE_VERSION) > 0); - leIpHdrLen->setText(str.setNum(pStream->l3.ip.hdrLen)); - cbIpHdrLenOverride->setChecked((pStream->l3.ip.ipMask & IM_OVERRIDE_HDRLEN) > 0); + leIpVersion->setText(str.setNum(pStream->ip()->ver())); + cbIpVersionOverride->setChecked( + pStream->ip()->ipFlags().testFlag(IpProtocol::IpOverrideVersion)); + leIpHdrLen->setText(str.setNum(pStream->ip()->hdrLen())); + cbIpHdrLenOverride->setChecked( + pStream->ip()->ipFlags().testFlag(IpProtocol::IpOverrideHdrLen)); - leIpTos->setText(uintToHexStr(pStream->l3.ip.tos, str, 1)); + leIpTos->setText(uintToHexStr(pStream->ip()->tos(), str, 1)); - leIpLength->setText(str.setNum(pStream->l3.ip.totLen)); - cbIpLengthOverride->setChecked((pStream->l3.ip.ipMask & IM_OVERRIDE_TOTLEN) > 0); + leIpLength->setText(str.setNum(pStream->ip()->totLen())); + cbIpLengthOverride->setChecked( + pStream->ip()->ipFlags().testFlag(IpProtocol::IpOverrideTotLen)); - leIpId->setText(uintToHexStr(pStream->l3.ip.id, str, 2)); - leIpFragOfs->setText(str.setNum(pStream->l3.ip.fragOfs)); - cbIpFlagsDf->setChecked((pStream->l3.ip.flags & IP_FLAG_DF) > 0); - cbIpFlagsMf->setChecked((pStream->l3.ip.flags & IP_FLAG_MF) > 0); + leIpId->setText(uintToHexStr(pStream->ip()->id(), str, 2)); + leIpFragOfs->setText(str.setNum(pStream->ip()->fragOfs())); + cbIpFlagsDf->setChecked((pStream->ip()->flags() & IP_FLAG_DF) > 0); + cbIpFlagsMf->setChecked((pStream->ip()->flags() & IP_FLAG_MF) > 0); - leIpTtl->setText(str.setNum(pStream->l3.ip.ttl)); - leIpProto->setText(uintToHexStr(pStream->l3.ip.proto, str, 1)); + leIpTtl->setText(str.setNum(pStream->ip()->ttl())); + leIpProto->setText(uintToHexStr(pStream->ip()->proto(), str, 1)); - leIpCksum->setText(uintToHexStr(pStream->l3.ip.cksum, str, 2)); - cbIpCksumOverride->setChecked((pStream->l3.ip.ipMask & IM_OVERRIDE_CKSUM) > 0); + leIpCksum->setText(uintToHexStr(pStream->ip()->cksum(), str, 2)); + cbIpCksumOverride->setChecked( + pStream->ip()->ipFlags().testFlag(IpProtocol::IpOverrideCksum)); - leIpSrcAddr->setText(QHostAddress(pStream->l3.ip.srcIp).toString()); - cmbIpSrcAddrMode->setCurrentIndex(pStream->l3.ip.srcIpMode); - leIpSrcAddrCount->setText(str.setNum(pStream->l3.ip.srcIpCount)); - leIpSrcAddrMask->setText(QHostAddress(pStream->l3.ip.srcIpMask).toString()); + leIpSrcAddr->setText(QHostAddress(pStream->ip()->srcIp()).toString()); + cmbIpSrcAddrMode->setCurrentIndex(pStream->ip()->srcIpMode()); + leIpSrcAddrCount->setText(str.setNum(pStream->ip()->srcIpCount())); + leIpSrcAddrMask->setText(QHostAddress(pStream->ip()->srcIpMask()).toString()); - leIpDstAddr->setText(QHostAddress(pStream->l3.ip.dstIp).toString()); - cmbIpDstAddrMode->setCurrentIndex(pStream->l3.ip.dstIpMode); - leIpDstAddrCount->setText(str.setNum(pStream->l3.ip.dstIpCount)); - leIpDstAddrMask->setText(QHostAddress(pStream->l3.ip.dstIpMask).toString()); + leIpDstAddr->setText(QHostAddress(pStream->ip()->dstIp()).toString()); + cmbIpDstAddrMode->setCurrentIndex(pStream->ip()->dstIpMode()); + leIpDstAddrCount->setText(str.setNum(pStream->ip()->dstIpCount())); + leIpDstAddrMask->setText(QHostAddress(pStream->ip()->dstIpMask()).toString()); } // L3 | ARP @@ -427,6 +454,7 @@ void StreamConfigDialog::LoadCurrentStream() } } +#if 0 // L4 { // L4 | TCP @@ -477,6 +505,7 @@ void StreamConfigDialog::LoadCurrentStream() // TODO } } +#endif } void StreamConfigDialog::StoreCurrentStream() @@ -487,30 +516,31 @@ void StreamConfigDialog::StoreCurrentStream() qDebug("storing pStream %p", pStream); +#if 1 // FIXME: Temp till we use protobuff accessors // Meta Data - pStream->meta.patternMode = (Stream::DataPatternMode) cmbPatternMode->currentIndex(); - pStream->meta.pattern = lePattern->text().remove(QChar(' ')).toULong(&isOk, 16); - - pStream->meta.lenMode = (Stream::FrameLengthMode) cmbPktLenMode->currentIndex(); - pStream->meta.frameLen = lePktLen->text().toULong(&isOk); - pStream->meta.frameLenMin = lePktLenMin->text().toULong(&isOk); - pStream->meta.frameLenMax = lePktLenMax->text().toULong(&isOk); + pStream->setPatternMode((Stream::DataPatternMode) cmbPatternMode->currentIndex()); + pStream->setPattern(lePattern->text().remove(QChar(' ')).toULong(&isOk, 16)); + pStream->setLenMode((Stream::FrameLengthMode) cmbPktLenMode->currentIndex()); + pStream->setFrameLen(lePktLen->text().toULong(&isOk)); + pStream->setFrameLenMin(lePktLenMin->text().toULong(&isOk)); + pStream->setFrameLenMax(lePktLenMax->text().toULong(&isOk)); +#endif // Protocols { if (rbFtNone->isChecked()) - pStream->proto.ft = Stream::e_ft_none; + pStream->setFrameType(Stream::e_ft_none); else if (rbFtEthernet2->isChecked()) - pStream->proto.ft = Stream::e_ft_eth_2; + pStream->setFrameType(Stream::e_ft_eth_2); else if (rbFt802Dot3Raw->isChecked()) - pStream->proto.ft = Stream::e_ft_802_3_raw; + pStream->setFrameType(Stream::e_ft_802_3_raw); else if (rbFt802Dot3Llc->isChecked()) - pStream->proto.ft = Stream::e_ft_802_3_llc; + pStream->setFrameType(Stream::e_ft_802_3_llc); else if (rbFtLlcSnap->isChecked()) - pStream->proto.ft = Stream::e_ft_snap; - - qDebug("store ft = %d\n", pStream->proto.ft); + pStream->setFrameType(Stream::e_ft_snap); + qDebug("store ft(%d)\n", pStream->frameType()); +#if 0 pStream->proto.dsap = leDsap->text().remove(QChar(' ')).toULong(&isOk, 16); pStream->proto.ssap = leSsap->text().remove(QChar(' ')).toULong(&isOk, 16); pStream->proto.ctl = leControl->text().remove(QChar(' ')).toULong(&isOk, 16); @@ -531,24 +561,33 @@ void StreamConfigDialog::StoreCurrentStream() pStream->proto.protoMask |= PM_L4_PROTO_NONE; else if (rbL4Other->isChecked()) pStream->proto.protoMask |= PM_L4_PROTO_OTHER; +#endif } // L2 { // L2 | Ethernet { - pStream->l2.eth.dstMacMshw = leDstMac->text().remove(QChar(' ')).left(4).toULong(&isOk, 16); - pStream->l2.eth.dstMacLsw = leDstMac->text().remove(QChar(' ')).right(8).toULong(&isOk, 16); - pStream->l2.eth.dstMacMode = (Stream::MacAddrMode) cmbDstMacMode->currentIndex(); - pStream->l2.eth.dstMacCount = leDstMacCount->text().toULong(&isOk); - pStream->l2.eth.dstMacStep = leDstMacStep->text().toULong(&isOk); + pStream->mac()->setDstMac( + leDstMac->text().remove(QChar(' ')).toULongLong(&isOk, 16)); + pStream->mac()->setDstMacMode( + (MacProtocol::MacAddrMode) cmbDstMacMode->currentIndex()); + pStream->mac()->setDstMacCount( + leDstMacCount->text().toULong(&isOk)); + pStream->mac()->setDstMacStep( + leDstMacStep->text().toULong(&isOk)); - pStream->l2.eth.srcMacMshw = leSrcMac->text().remove(QChar(' ')).left(4).toULong(&isOk, 16); - pStream->l2.eth.srcMacLsw = leSrcMac->text().remove(QChar(' ')).right(8).toULong(&isOk, 16); - pStream->l2.eth.srcMacMode = (Stream::MacAddrMode) cmbSrcMacMode->currentIndex(); - pStream->l2.eth.srcMacCount = leSrcMacCount->text().toULong(&isOk); - pStream->l2.eth.srcMacStep = leSrcMacStep->text().toULong(&isOk); + pStream->mac()->setSrcMac( + leSrcMac->text().remove(QChar(' ')).toULongLong(&isOk, 16)); + pStream->mac()->setSrcMacMode( + (MacProtocol::MacAddrMode) cmbSrcMacMode->currentIndex()); + pStream->mac()->setSrcMacCount( + leSrcMacCount->text().toULong(&isOk)); + pStream->mac()->setSrcMacStep( + leSrcMacStep->text().toULong(&isOk)); + +#if 0 pStream->l2.eth.vlanMask = 0; pStream->l2.eth.cvlanPrio = cmbCvlanPrio->currentIndex(); @@ -568,6 +607,7 @@ void StreamConfigDialog::StoreCurrentStream() pStream->l2.eth.vlanMask |= VM_SVLAN_TPID_OVERRIDE; if (gbSvlan->isChecked()) pStream->l2.eth.vlanMask |= VM_SVLAN_TAGGED; +#endif } } @@ -575,42 +615,48 @@ void StreamConfigDialog::StoreCurrentStream() { // L3 | IP { - pStream->l3.ip.ipMask = 0; + IpProtocol *ip = pStream->ip(); + IpProtocol::IpFlags f; - pStream->l3.ip.ver = leIpVersion->text().toULong(&isOk); + ip->setVer(leIpVersion->text().toULong(&isOk)); if (cbIpVersionOverride->isChecked()) - pStream->l3.ip.ipMask |= IM_OVERRIDE_VERSION; - pStream->l3.ip.hdrLen = leIpHdrLen->text().toULong(&isOk); + f |= IpProtocol::IpOverrideVersion; + ip->setHdrLen(leIpHdrLen->text().toULong(&isOk)); if (cbIpHdrLenOverride->isChecked()) - pStream->l3.ip.ipMask |= IM_OVERRIDE_HDRLEN; + f |= IpProtocol::IpOverrideHdrLen; - pStream->l3.ip.tos = leIpTos->text().toULong(&isOk, 16); + ip->setTos(leIpTos->text().toULong(&isOk, 16)); - pStream->l3.ip.totLen = leIpLength->text().toULong(&isOk); + ip->setTotLen(leIpLength->text().toULong(&isOk)); if (cbIpLengthOverride->isChecked()) - pStream->l3.ip.ipMask |= IM_OVERRIDE_TOTLEN; + f |= IpProtocol::IpOverrideHdrLen; - pStream->l3.ip.id = leIpId->text().remove(QChar(' ')).toULong(&isOk, 16); - pStream->l3.ip.fragOfs = leIpFragOfs->text().toULong(&isOk); - if (cbIpFlagsDf->isChecked()) pStream->l3.ip.ipMask |= IP_FLAG_DF; - if (cbIpFlagsMf->isChecked()) pStream->l3.ip.ipMask |= IP_FLAG_MF; + ip->setId(leIpId->text().remove(QChar(' ')).toULong(&isOk, 16)); + ip->setFragOfs(leIpFragOfs->text().toULong(&isOk)); - pStream->l3.ip.ttl = leIpTtl->text().toULong(&isOk); - pStream->l3.ip.proto = leIpProto->text().remove(QChar(' ')).toULong(&isOk, 16); + int ff; + if (cbIpFlagsDf->isChecked()) ff |= IP_FLAG_DF; + if (cbIpFlagsMf->isChecked()) ff |= IP_FLAG_MF; + ip->setFlags(ff); + + ip->setTtl(leIpTtl->text().toULong(&isOk)); + ip->setProto(leIpProto->text().remove(QChar(' ')).toULong(&isOk, 16)); - pStream->l3.ip.cksum = leIpCksum->text().remove(QChar(' ')).toULong(&isOk); + ip->setCksum(leIpCksum->text().remove(QChar(' ')).toULong(&isOk)); if (cbIpCksumOverride->isChecked()) - pStream->l3.ip.ipMask |= IM_OVERRIDE_CKSUM; + f |= IpProtocol::IpOverrideCksum; - pStream->l3.ip.srcIp = QHostAddress(leIpSrcAddr->text()).toIPv4Address(); - pStream->l3.ip.srcIpMode = (Stream::IpAddrMode) cmbIpSrcAddrMode->currentIndex(); - pStream->l3.ip.srcIpCount = leIpSrcAddrCount->text().toULong(&isOk); - pStream->l3.ip.srcIpMask = QHostAddress(leIpSrcAddrMask->text()).toIPv4Address(); + ip->setSrcIp(QHostAddress(leIpSrcAddr->text()).toIPv4Address()); + ip->setSrcIpMode((IpProtocol::IpAddrMode) cmbIpSrcAddrMode->currentIndex()); + ip->setSrcIpCount(leIpSrcAddrCount->text().toULong(&isOk)); + ip->setSrcIpMask(QHostAddress(leIpSrcAddrMask->text()).toIPv4Address()); - pStream->l3.ip.dstIp = QHostAddress(leIpDstAddr->text()).toIPv4Address(); - pStream->l3.ip.dstIpMode = (Stream::IpAddrMode) cmbIpDstAddrMode->currentIndex(); - pStream->l3.ip.dstIpCount = leIpDstAddrCount->text().toULong(&isOk); - pStream->l3.ip.dstIpMask = QHostAddress(leIpDstAddrMask->text()).toIPv4Address(); + ip->setDstIp(QHostAddress(leIpDstAddr->text()).toIPv4Address()); + ip->setDstIpMode((IpProtocol::IpAddrMode) cmbIpDstAddrMode->currentIndex()); + ip->setDstIpCount(leIpDstAddrCount->text().toULong(&isOk)); + ip->setDstIpMask(QHostAddress(leIpDstAddrMask->text()).toIPv4Address()); + + ip->setIpFlags(f); } // L3 | ARP @@ -619,6 +665,8 @@ void StreamConfigDialog::StoreCurrentStream() } } +// TODO +#if 0 // L4 { // L4 | TCP @@ -676,6 +724,7 @@ void StreamConfigDialog::StoreCurrentStream() // TODO } } +#endif } void StreamConfigDialog::on_pbOk_clicked() { diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h index 6ccf074..1d3c99b 100644 --- a/client/streamconfigdialog.h +++ b/client/streamconfigdialog.h @@ -37,6 +37,7 @@ private: private slots: void on_cmbDstMacMode_currentIndexChanged(QString mode); + void on_cmbSrcMacMode_currentIndexChanged(QString mode); void on_pbPrev_clicked(); void on_pbNext_clicked(); @@ -56,7 +57,7 @@ private slots: void on_pbOk_clicked(); }; -QString & uintToHexStr(quint32 num, QString &hexStr, quint8 octets); +QString & uintToHexStr(quint64 num, QString &hexStr, quint8 octets); #endif diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui index 7e7efe1..a9c1ba4 100644 --- a/client/streamconfigdialog.ui +++ b/client/streamconfigdialog.ui @@ -33,7 +33,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - 2 + 0 @@ -191,7 +191,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff - 2 + 1 @@ -2145,12 +2145,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 147 - 238 + 252 + 288 - 147 - 238 + 252 + 317 @@ -2161,12 +2161,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 147 - 238 + 252 + 388 - 147 - 238 + 252 + 417 @@ -2177,12 +2177,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 259 - 101 - 238 + 41 + 317 @@ -2193,12 +2193,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 259 - 101 - 238 + 81 + 317 @@ -2209,12 +2209,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 259 - 133 - 238 + 120 + 317 @@ -2225,12 +2225,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 259 - 147 - 238 + 252 + 288 @@ -2241,12 +2241,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 359 - 101 - 238 + 41 + 417 @@ -2257,12 +2257,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 359 - 101 - 238 + 120 + 417 @@ -2273,12 +2273,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 359 - 147 - 238 + 252 + 388 @@ -2289,12 +2289,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 238 + 31 + 359 - 101 - 238 + 81 + 417 @@ -2305,12 +2305,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 276 + 123 + 305 - 101 - 276 + 123 + 305 @@ -2321,12 +2321,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 276 + 123 + 305 - 101 - 276 + 123 + 305 @@ -2401,12 +2401,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 276 + 123 + 305 - 101 - 276 + 123 + 305 @@ -2417,12 +2417,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 101 - 276 + 123 + 305 - 101 - 276 + 123 + 305 @@ -3121,12 +3121,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 224 - 207 + 381 + 140 - 224 - 209 + 381 + 174 @@ -3137,12 +3137,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 125 - 207 + 30 + 69 - 191 - 236 + 85 + 285 @@ -3153,12 +3153,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 125 - 207 + 30 + 94 - 173 - 236 + 67 + 331 @@ -3169,12 +3169,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff setEnabled(bool) - 125 - 207 + 30 + 94 - 224 - 216 + 222 + 189 diff --git a/client/streammodel.cpp b/client/streammodel.cpp index 21588b7..d56f4ee 100644 --- a/client/streammodel.cpp +++ b/client/streammodel.cpp @@ -125,7 +125,7 @@ bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int r return true; break; case StreamStatus: - mCurrentPort->mStreams[index.row()].setEnabled(value.toBool()); + mCurrentPort->mStreams[index.row()].setIsEnabled(value.toBool()); return true; break; diff --git a/common/Makefile b/common/Makefile new file mode 100644 index 0000000..7c95f2b --- /dev/null +++ b/common/Makefile @@ -0,0 +1,14 @@ +RM=del +PROTOC=protoc + +#-#-# + +all: protocol.pb.cc + +protocol.pb.cc: protocol.proto + $(PROTOC) --cpp_out=. $< + +clean: + $(RM) *.pb.h *.pb.cc + +distclean: clean diff --git a/common/protocol.proto b/common/protocol.proto new file mode 100644 index 0000000..4fa777d --- /dev/null +++ b/common/protocol.proto @@ -0,0 +1,302 @@ +// stream.proto + +// FIXME: Re-evaluate Tag Values + +package OstProto; + +// Ethernet +message Mac { + + enum MacAddrMode { + e_mm_fixed = 0; + e_mm_inc = 1; + e_mm_dec = 2; + } + + // Dst Mac + optional uint64 dst_mac = 1; + optional MacAddrMode dst_mac_mode = 2 [default = e_mm_fixed]; + optional uint32 dst_mac_count = 3 [default = 16]; + optional uint32 dst_mac_step = 4 [default = 1]; + + // Src Mac + optional uint32 src_mac = 5; + optional MacAddrMode src_mac_mode = 6 [default = e_mm_fixed]; + optional uint32 src_mac_count = 7 [default = 16]; + optional uint32 src_mac_step = 8 [default = 1]; +} + +message Llc { + optional uint32 dsap = 1; + optional uint32 ssap = 2; + optional uint32 ctl = 3; +} + +message Snap { + optional uint32 oui = 1; + optional uint32 type = 2; +} + +message Eth2 { + optional uint32 type = 1; +} + +message Vlan { + // VLAN presence/absence + optional bool is_cvlan_tagged = 9; + optional bool is_ctpid_override = 10; + optional bool is_svlan_tagged = 11; + optional bool is_stpid_override = 12; + + // VLAN values + optional uint32 ctpid = 13; + optional uint32 cvlan_tag = 14; // includes prio, cfi and cvlanid + optional uint32 stpid = 15; + optional uint32 svlan_tag = 16; // includes pcp, de and svlanid +} + +// IP +message Ip { + + enum IpAddrMode { + e_im_fixed = 0; + e_im_inc_host = 1; + e_im_dec_host = 2; + e_im_random_host = 3; + } + + optional bool is_override_ver = 1; + optional bool is_override_hdrlen = 2; + optional bool is_override_totlen = 3; + optional bool is_override_cksum = 4; + + optional uint32 ver_hdrlen = 5 [default = 0x45]; + optional uint32 tos = 6; + optional uint32 tot_len = 7; + optional uint32 id = 8 [default = 1234]; + // TODO: rename flags to frag_flags + optional uint32 flags = 9; + optional uint32 frag_ofs = 10; + optional uint32 ttl = 11 [default = 127]; + optional uint32 proto = 12; + optional uint32 cksum = 13; + + // Source IP + optional fixed32 src_ip = 14; + optional IpAddrMode src_ip_mode = 15 [default = e_im_fixed]; + optional uint32 src_ip_count = 16 [default = 16]; + optional fixed32 src_ip_mask = 17 [default = 0xFFFFFFFF]; + + // Destination IP + optional fixed32 dst_ip = 18; + optional IpAddrMode dst_ip_mode = 19 [default = e_im_fixed]; + optional uint32 dst_ip_count = 20 [default = 16]; + optional fixed32 dst_ip_mask = 21 [default = 0xFFFFFFFF]; + + // TODO: Options +} + +message Arp { +// TODO: ARP +} + +message Tcp { + + optional bool is_override_hdrlen = 1; + optional bool is_override_cksum = 2; + + optional uint32 src_port = 3 [default = 8902]; + optional uint32 dst_port = 4 [default = 80]; + + optional uint32 seq_num = 5 [default = 129018]; + optional uint32 ack_num = 6 [default = 98223]; + + optional uint32 hdrlen_rsvd = 7 [default = 0x50]; + optional uint32 flags = 8; + + optional uint32 window = 9 [default = 1024]; + optional uint32 cksum = 10; + optional uint32 urg_ptr = 11; +} + +// UDP +message Udp { + optional bool is_override_totlen = 1; + optional bool is_override_cksum = 2; + + optional uint32 src_port = 3 [default = 8902]; + optional uint32 dst_port = 4 [default = 80]; + optional uint32 totLen = 5; + optional uint32 cksum = 6; +} + +// TODO: ICMP +message Icmp { +} + +// TODO: IGMP +message Igmp { +} + + +message StreamCore { + + enum FrameType { + e_ft_none = 0; + e_ft_eth_2 = 1; + e_ft_802_3_raw = 2; + e_ft_802_3_llc = 3; + e_ft_snap = 4; + } + + enum L3Proto { + e_l3_none = 0; + e_l3_other = 1; + e_l3_ip = 2; + e_l3_arp = 3; + } + + enum L4Proto { + e_l4_none = 0; + e_l4_other = 1; + e_l4_tcp = 2; + e_l4_udp = 3; + e_l4_icmp = 4; + e_l4_igmp = 5; + } + + enum DataPatternMode { + e_dp_fixed = 0; + e_dp_inc = 1; + e_dp_dec = 2; + e_dp_random = 3; + } + + enum FrameLengthMode { + e_fl_fixed = 0; + e_fl_inc = 1; + e_fl_dec = 2; + e_fl_random = 3; + } + + // Basics + optional string name = 1; + optional bool is_enabled = 2; + optional uint32 ordinal = 3; + + // Data Pattern + optional DataPatternMode pattern_mode = 11; + optional uint32 pattern = 12; + optional uint32 data_start_ofs = 13; + + // Frame Length (includes CRC) + optional FrameLengthMode len_mode = 14; + optional uint32 frame_len = 15; + optional uint32 frame_len_min = 16; + optional uint32 frame_len_max = 17; + + // Currently Selected Protocols + optional FrameType ft = 21 [default = e_ft_none]; + optional L3Proto l3_proto = 22; + optional L4Proto l4_proto = 23; +} + +message StreamId { + required uint32 port_id = 1; + required uint32 stream_id = 2; +} + +message Stream { + + required StreamId id = 1; + optional StreamCore core = 2; + + // Protocol data - L2 + optional Mac mac = 51; + optional Llc llc = 52; + optional Snap snap = 53; + optional Eth2 eth2 = 54; + + // Protocol data - L3 + optional Ip ip = 61; + optional Arp arp = 62; + + // Protocol data - L4 + optional Tcp tcp = 71; + optional Udp udp = 72; + optional Icmp icmp = 73; + optional Igmp igmp = 74; + +} + +message Void { + // nothing! +} + +message Ack { + // TODO +} + +message PortIdList { + repeated uint32 port_id = 1; +} + +message StreamIdList { + repeated StreamId id = 1; +} + + +message PortConfig { + required uint32 port_id = 1; + optional string name = 2; + optional string description = 3; + optional bool is_enabled = 4; + optional bool is_oper_up = 5; + optional bool is_exclusive_control = 6; +} + +message PortConfigList { + repeated PortConfig list = 1; +} + +message StreamConfigList { + repeated Stream stream = 1; +} + +message CaptureBuffer { + // TODO +} + +message CaptureBufferList { + repeated CaptureBuffer list = 1; +} + +message PortStats { + // TODO +} + +message PortStatsList { + repeated PortStats list = 1; +} + +service OstService { + rpc getPortIdList(Void) returns (PortIdList); + rpc getPortConfig(PortIdList) returns (PortConfigList); + + rpc getStreamIdList(PortIdList) returns (StreamIdList); + rpc getStreamConfig(StreamIdList) returns (StreamConfigList); + rpc addStream(StreamIdList) returns (Ack); + rpc deleteStream(StreamIdList) returns (Ack); + rpc modifyStream(StreamConfigList) returns (Ack); + + rpc startTx(PortIdList) returns (Ack); + rpc stopTx(PortIdList) returns (Ack); + + rpc startCapture(PortIdList) returns (Ack); + rpc stopCapture(PortIdList) returns (Ack); + rpc getCaptureBuffer(PortIdList) returns (CaptureBufferList); + + rpc getStats(PortIdList) returns (PortStatsList); + rpc clearStats(PortIdList) returns (Ack); +} + diff --git a/rpc/pbhelper.h b/rpc/pbhelper.h new file mode 100644 index 0000000..19e3daf --- /dev/null +++ b/rpc/pbhelper.h @@ -0,0 +1,66 @@ +#ifndef _PB_HELPER_H +#define _PB_HELPER_H + +#include +#include + +#include + +class PbHelper +{ +public: + bool update( + ::google::protobuf::Message *target, + ::google::protobuf::Message *source) + { + ::google::protobuf::Message::Reflection *sourceRef; + ::google::protobuf::Message::Reflection *targetRef; + std::vector srcFieldList; + + qDebug("In %s", __FUNCTION__); + + if (source->GetDescriptor()->full_name() != + target->GetDescriptor()->full_name()) + goto _error_exit; + + sourceRef = source->GetReflection(); + targetRef = target->GetReflection(); + + sourceRef->ListFields(&srcFieldList); + for (uint i=0; i < srcFieldList.size(); i++) + { + const ::google::protobuf::FieldDescriptor *srcField, *targetField; + + srcField = srcFieldList[i]; + targetField = target->GetDescriptor()->FindFieldByName( + srcField->name()); + + switch(targetField->type()) + { + case ::google::protobuf::FieldDescriptor::TYPE_UINT32: + targetRef->SetUInt32(targetField, + sourceRef->GetUInt32(srcField)); + break; + case ::google::protobuf::FieldDescriptor::TYPE_BOOL: + targetRef->SetBool(targetField, + sourceRef->GetBool(srcField)); + break; + case ::google::protobuf::FieldDescriptor::TYPE_STRING: + targetRef->SetString(targetField, + sourceRef->GetString(srcField)); + break; + default: + qDebug("unhandled Field Type"); + break; + } + } + + return true; + + _error_exit: + qDebug("%s: error!", __FUNCTION__); + return false; + } + +}; +#endif diff --git a/rpc/pbrpc.pro b/rpc/pbrpc.pro new file mode 100644 index 0000000..79c0e08 --- /dev/null +++ b/rpc/pbrpc.pro @@ -0,0 +1,13 @@ +TEMPLATE = lib +CONFIG += qt +QT += network +DEFINES += HAVE_REMOTE +INCLUDEPATH += "c:\msys\1.0\local\include" +LIBS += -L"C:\msys\1.0\local\lib" -lprotobuf +HEADERS += rpcserver.h pbrpccontroller.h pbrpcchannel.h +SOURCES += rpcserver.cpp pbrpcchannel.cpp +client.path = ..\client\debug +client.files = debug\libpbrpc.a debug\pbrpc.dll +server.path = ..\server\debug +server.files = debug\libpbrpc.a debug\pbrpc.dll +INSTALLS += client server diff --git a/rpc/pbrpcchannel.cpp b/rpc/pbrpcchannel.cpp new file mode 100644 index 0000000..0d6226b --- /dev/null +++ b/rpc/pbrpcchannel.cpp @@ -0,0 +1,189 @@ +#include "pbrpcchannel.h" + +//#include "../common/protocol.pb.h" + +PbRpcChannel::PbRpcChannel(QHostAddress ip, quint16 port) +{ + isPending = false; + pendingMethodId = -1; // don't care as long as isPending is false + + controller = NULL; + done = NULL; + response = NULL; + + mServerAddress = ip; + mServerPort = port; + mpSocket = new QTcpSocket(this); + + // FIXME: Not quite sure why this ain't working! + // QMetaObject::connectSlotsByName(this); + + connect(mpSocket, SIGNAL(connected()), + this, SLOT(on_mpSocket_connected())); + connect(mpSocket, SIGNAL(disconnected()), + this, SLOT(on_mpSocket_disconnected())); + connect(mpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), + this, SLOT(on_mpSocket_stateChanged(QAbstractSocket::SocketState))); + connect(mpSocket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(on_mpSocket_error(QAbstractSocket::SocketError))); + + connect(mpSocket, SIGNAL(readyRead()), + this, SLOT(on_mpSocket_readyRead())); + +} + +PbRpcChannel::~PbRpcChannel() +{ + delete mpSocket; +} + +void PbRpcChannel::establish() +{ + qDebug("In %s", __FUNCTION__); + + mpSocket->connectToHost(mServerAddress, mServerPort); +} + +void PbRpcChannel::establish(QHostAddress ip, quint16 port) +{ + mServerAddress = ip; + mServerPort = port; + establish(); +} + +void PbRpcChannel::tearDown() +{ + qDebug("In %s", __FUNCTION__); + + mpSocket->disconnectFromHost(); +} + +void PbRpcChannel::CallMethod( + const ::google::protobuf::MethodDescriptor *method, + ::google::protobuf::RpcController *controller, + const ::google::protobuf::Message *req, + ::google::protobuf::Message *response, + ::google::protobuf::Closure* done) +{ + char msg[1024]; // FIXME: hardcoding + char *p = (char *)&msg; + int len; + + qDebug("In %s", __FUNCTION__); + + pendingMethodId = method->index(); + this->controller=controller; + this->done=done; + this->response=response; + isPending = true; + + *((quint16*)(p+0)) = HTONS(PB_MSG_TYPE_REQUEST); // type + qDebug("CLi:GET16 = %d/%d, type = %d", GET16(p+0), NTOHS(GET16(p+0)), + PB_MSG_TYPE_REQUEST); + *((quint16*)(p+2)) = HTONS(method->index()); // method id + // (p+4) len later after serialization + *((quint16*)(p+6)) = HTONS(0); // rsvd + + // SerialData is at offset 8 + req->SerializeToArray((void*) (p+8), sizeof(msg)); + + len = req->ByteSize(); + *((quint16*)(p+4)) = HTONS(len); // len + + qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__, len+8, + req->ShortDebugString().c_str()); + BUFDUMP(msg, len+8); + + mpSocket->write(msg, len + 8); +} + +void PbRpcChannel::on_mpSocket_readyRead() +{ + char msg[1024]; // FIXME: hardcoding; + char *p = (char*)&msg; + int msgLen; + quint16 type, method, len, rsvd; + PbRpcController *controller; + + qDebug("In %s", __FUNCTION__); + + msgLen = mpSocket->read(msg, sizeof(msg)); + + qDebug("client(%s) rcvd %d bytes", __FUNCTION__, msgLen); + BUFDUMP(msg, msgLen); + + type = NTOHS(GET16(p+0)); + method = NTOHS(GET16(p+2)); + len = NTOHS(GET16(p+4)); + rsvd = NTOHS(GET16(p+6)); + + if (!isPending) + { + qDebug("not waiting for response"); + + goto _error_exit; + } + + if (type != PB_MSG_TYPE_RESPONSE) + { + qDebug("invalid msgType %d (expected = %d)", type, + PB_MSG_TYPE_RESPONSE); + + goto _error_exit; + } + + if (pendingMethodId != method) + { + qDebug("invalid method id %d (expected = %d)", method, + pendingMethodId); + + goto _error_exit; + } + + + // Serialized data starts from offset 8 + response->ParseFromArray((void*) &msg[8], len); + qDebug("client(%s): Parsed as %s", __FUNCTION__, + response->DebugString().c_str()); + + + pendingMethodId = -1; + controller = NULL; + //done = NULL; + response = NULL; + isPending = false; + + done->Run(); + + return; + +_error_exit: + qDebug("client(%s) discarding received msg", __FUNCTION__); + return; +} + +void PbRpcChannel::on_mpSocket_stateChanged( + QAbstractSocket::SocketState socketState) +{ + qDebug("In %s", __FUNCTION__); + emit stateChanged(socketState); +} + +void PbRpcChannel::on_mpSocket_connected() +{ + qDebug("In %s", __FUNCTION__); + emit connected(); +} + +void PbRpcChannel::on_mpSocket_disconnected() +{ + qDebug("In %s", __FUNCTION__); + emit disconnected(); +} + +void PbRpcChannel::on_mpSocket_error(QAbstractSocket::SocketError socketError) +{ + qDebug("In %s", __FUNCTION__); + emit error(socketError); +} + diff --git a/rpc/pbrpcchannel.h b/rpc/pbrpcchannel.h new file mode 100644 index 0000000..657b095 --- /dev/null +++ b/rpc/pbrpcchannel.h @@ -0,0 +1,74 @@ +#ifndef _PB_RPC_CHANNEL_H +#define _PB_RPC_CHANNEL_H + +#include +#include + +#include +#include +#include + +#include "pbrpccommon.h" +#include "pbrpccontroller.h" + +class PbRpcChannel : public QObject, public ::google::protobuf::RpcChannel +{ + Q_OBJECT + + // If isPending is TRUE, then controller, done, response + // and pendingMethodId correspond to the last method called by + // the service stub + bool isPending; + int pendingMethodId; + + // controller, done, response are set to the corresponding values + // passed by the stub to CallMethod(). They are reset to NULL when + // we get a response back from the server in on_mpSocket_readyRead() + // after calling done->Run(). + // + // TODO(?): change controller, done and response to references + // instead of pointers? + ::google::protobuf::RpcController *controller; + ::google::protobuf::Closure *done; + ::google::protobuf::Message *response; + + QHostAddress mServerAddress; + quint16 mServerPort; + QTcpSocket *mpSocket; + +public: + PbRpcChannel(QHostAddress ip, quint16 port); + ~PbRpcChannel(); + + void establish(); + void establish(QHostAddress ip, quint16 port); + void tearDown(); + + const QHostAddress& serverAddress() const { return mServerAddress; } + quint16 serverPort() const { return mServerPort; } + + QAbstractSocket::SocketState state() const + { return mpSocket->state(); } + + void CallMethod(const ::google::protobuf::MethodDescriptor *method, + ::google::protobuf::RpcController *controller, + const ::google::protobuf::Message *req, + ::google::protobuf::Message *response, + ::google::protobuf::Closure* done); + +signals: + void connected(); + void disconnected(); + void error(QAbstractSocket::SocketError socketError); + void stateChanged(QAbstractSocket::SocketState socketState); + +private slots: + void on_mpSocket_connected(); + void on_mpSocket_disconnected(); + void on_mpSocket_stateChanged(QAbstractSocket::SocketState socketState); + void on_mpSocket_error(QAbstractSocket::SocketError socketError); + + void on_mpSocket_readyRead(); +}; + +#endif diff --git a/rpc/pbrpccommon.h b/rpc/pbrpccommon.h new file mode 100644 index 0000000..5407602 --- /dev/null +++ b/rpc/pbrpccommon.h @@ -0,0 +1,52 @@ +#ifndef _PB_RPC_COMMON_H +#define _PB_RPC_COMMON_H + +// FIXME: check which one is right - wrong one seems to be working!!!!! +#if 0 +#define GET16(p) (quint16)( \ + (*((quint8*)(p)+0) << 8 ) \ + | (*((quint8*)(p)+1))) +#else +#define GET16(p) (quint16)( \ + (*((quint8*)(p)+1) << 8 ) \ + | (*((quint8*)(p)+0))) +#endif + +#define BYTESWAP4(x) \ + (((x & 0xFF000000) >> 24) | \ + ((x & 0x00FF0000) >> 8) | \ + ((x & 0x0000FF00) << 8) | \ + ((x & 0x000000FF) << 24)) + +#define BYTESWAP2(x) \ + (((x & 0xFF00) >> 8) | \ + ((x & 0x00FF) << 8)) + +// TODO: portability +#if 1 +#define HTONL(x) BYTESWAP4(x) +#define NTOHL(x) BYTESWAP4(x) +#define HTONS(x) BYTESWAP2(x) +#define NTOHS(x) BYTESWAP2(x) +#else +#define HTONL(x) (x) +#define NTOHL(x) (x) +#define HTONS(x) (x) +#define NTOHS(x) (x) +#endif + +// Print a HexDump +#define BUFDUMP(ptr, len) qDebug("%s", QString(QByteArray((char*)(ptr), \ + (len)).toHex()).toAscii().data()); + +/* +** RPC Header (8) +** - MSG_TYPE (2) +** - METHOD_ID (2) +** - LEN (2) [not including this header] +** - RSVD (2) +*/ +#define PB_MSG_TYPE_REQUEST 1 +#define PB_MSG_TYPE_RESPONSE 2 + +#endif diff --git a/rpc/pbrpccontroller.h b/rpc/pbrpccontroller.h new file mode 100644 index 0000000..0b67ded --- /dev/null +++ b/rpc/pbrpccontroller.h @@ -0,0 +1,27 @@ +#ifndef _PB_RPC_CONTROLLER_H +#define _PB_RPC_CONTROLLER_H + +#include + +class PbRpcController : public ::google::protobuf::RpcController +{ + bool failed; + std::string errStr; + +public: + PbRpcController() { failed = false; } + + // Client Side Methods + void Reset() { failed=false;} + bool Failed() const { return failed; } + void StartCancel() { /* TODO */} + std::string ErrorText() const { return errStr; } + + // Server Side Methods + void SetFailed(const std::string &reason) + { failed = true; errStr = reason; } + bool IsCanceled() const { return false; }; + void NotifyOnCancel(::google::protobuf::Closure *callback) { /*TODO*/ } +}; + +#endif diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp new file mode 100644 index 0000000..45555bf --- /dev/null +++ b/rpc/rpcserver.cpp @@ -0,0 +1,180 @@ +#include "pbhelper.h" +#include "rpcserver.h" + +RpcServer::RpcServer() +{ + server = NULL; + clientSock = NULL; + + service = NULL; + + isPending = false; + pendingMethodId = -1; // don't care as long as isPending is false +} + +RpcServer::~RpcServer() +{ + if (server) + delete server; +} + +bool RpcServer::registerService(::google::protobuf::Service *service, + quint16 tcpPortNum) +{ + this->service = service; + + server = new QTcpServer(); + connect(server, SIGNAL(newConnection()), this, SLOT(when_newConnection())); + if (!server->listen(QHostAddress::Any, tcpPortNum)) + { + LogInt(tr("Unable to start the server: %1").arg(server->errorString())); + return false; + } + + LogInt(tr("The server is running on %1:%2").arg(server->serverAddress().toString()).arg(server->serverPort())); + return true; +} + +void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcController) +{ + char msg[1024]; // FIXME: hardcoding + char *p = (char *)&msg; + int len; + + qDebug("In RpcServer::done"); + + // TODO: check PbRpcController to see if method failed + if (PbRpcController->Failed()) + { + qDebug("rpc failed"); + goto _exit; + } + + *((quint16*)(p+0)) = HTONS(PB_MSG_TYPE_RESPONSE); // type TODO:RESPONSE + *((quint16*)(p+2)) = HTONS(pendingMethodId); // method + *((quint16*)(p+6)) = HTONS(0); // rsvd + + // SerialData is at offset 8 + resp->SerializeToArray((void*) (p+8), sizeof(msg)); + + len = resp->ByteSize(); + (*(quint16*)(p+4)) = HTONS(len); // len + + qDebug("Server(%s): sending %d bytest to client encoding <%s>", + __FUNCTION__, len + 8, resp->DebugString().c_str()); + BUFDUMP(msg, len + 8); + + clientSock->write(msg, len + 8); + +_exit: + delete PbRpcController; + isPending = false; +} + +void RpcServer::when_newConnection() +{ + if (clientSock) + { + QTcpSocket *sock; + + LogInt(tr("already connected, no new connections will be accepted\n")); + + // Accept and close connection + // TODO: Send reason msg to client + sock = server->nextPendingConnection(); + sock->disconnectFromHost(); + sock->deleteLater(); + goto _exit; + } + + clientSock = server->nextPendingConnection(); + LogInt(tr("accepting new connection from %1:%2").arg(clientSock->peerAddress().toString()).arg(clientSock->peerPort())); + + connect(clientSock, SIGNAL(readyRead()), + this, SLOT(when_dataAvail())); + connect(clientSock, SIGNAL(disconnected()), + this, SLOT(when_disconnected())); + connect(clientSock, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(when_error(QAbstractSocket::SocketError))); + +_exit: + return; +} + +void RpcServer::when_disconnected() +{ + LogInt(tr("connection closed from %1:%2").arg(clientSock->peerAddress().toString()).arg(clientSock->peerPort())); + + clientSock->deleteLater(); + clientSock = NULL; +} + +void RpcServer::when_error(QAbstractSocket::SocketError socketError) +{ + LogInt(clientSock->errorString()); +} + +void RpcServer::when_dataAvail() +{ + char msg[1024]; // FIXME: hardcoding; + int msgLen; + char *p = (char*) &msg; + quint16 type, method, len, rsvd; + const ::google::protobuf::MethodDescriptor *methodDesc; + ::google::protobuf::Message *req, *resp; + PbRpcController *controller; + + msgLen = clientSock->read(msg, sizeof(msg)); + LogInt(QString(QByteArray(msg, msgLen).toHex())); + + qDebug("Server %s: rcvd %d bytes", __FUNCTION__, msgLen); + BUFDUMP(msg, msgLen); + + type = NTOHS(GET16(p+0)); + qDebug("GET16 = %d/%d, type = %d", GET16(p+0), NTOHS(GET16(p+0)), type); + method = NTOHS(GET16(p+2)); + len = NTOHS(GET16(p+4)); + rsvd = NTOHS(GET16(p+6)); + + if (type != PB_MSG_TYPE_REQUEST) + { + qDebug("server(%s): unexpected msg type %d (expected %d)", __FUNCTION__, + type, PB_MSG_TYPE_REQUEST); + goto _error_exit; + } + + + methodDesc = service->GetDescriptor()->method(method); + if (!methodDesc) + { + qDebug("server(%s): invalid method id %d", __FUNCTION__, method); + goto _error_exit; // TODO: Return Error to client + } + + if (isPending) + { + qDebug("server(%s): rpc pending, try again", __FUNCTION__); + goto _error_exit; // TODO: Return Error to client + } + + pendingMethodId = method; + isPending = true; + + req = service->GetRequestPrototype(methodDesc).New(); + resp = service->GetResponsePrototype(methodDesc).New(); + + // Serialized data starts from offset 8 + req->ParseFromArray((void*) (msg+8), len); + + controller = new PbRpcController; + + service->CallMethod(methodDesc, controller, req, resp, + NewCallback(this, &RpcServer::done, resp, controller)); + + return; + +_error_exit: + qDebug("server(%s): discarding msg from client", __FUNCTION__); + return; +} + diff --git a/rpc/rpcserver.h b/rpc/rpcserver.h new file mode 100644 index 0000000..9e21587 --- /dev/null +++ b/rpc/rpcserver.h @@ -0,0 +1,44 @@ +#ifndef _RPC_SERVER_H +#define _RPC_SERVER_H + +#include +#include +#include + +#include +#include + +#include "pbrpccommon.h" +#include "pbrpccontroller.h" + + +class RpcServer : public QObject +{ + Q_OBJECT + + QTcpServer *server; + QTcpSocket *clientSock; + + ::google::protobuf::Service *service; + + bool isPending; + int pendingMethodId; + + void LogInt (QString log) {qDebug("%s", log.toAscii().data());} + +public: + RpcServer(); // TODO: use 'parent' param + virtual ~RpcServer(); + + bool registerService(::google::protobuf::Service *service, + quint16 tcpPortNum); + void done(::google::protobuf::Message *resp, PbRpcController *controller); + +private slots: + void when_newConnection(); + void when_disconnected(); + void when_dataAvail(); + void when_error(QAbstractSocket::SocketError socketError); +}; + +#endif diff --git a/server/abstracthost.h b/server/abstracthost.h index 38e266c..862666c 100644 --- a/server/abstracthost.h +++ b/server/abstracthost.h @@ -5,7 +5,9 @@ class AbstractHost { public: virtual void Log(const char* str) = 0; +#if 0 // PB virtual int SendMsg(const void* msg, int size) = 0; +#endif }; #endif diff --git a/server/drone.cpp b/server/drone.cpp index 54bf9cf..98300ee 100644 --- a/server/drone.cpp +++ b/server/drone.cpp @@ -6,13 +6,19 @@ Drone::Drone(QDialog *parent) : QDialog(parent) { ui.setupUi(this); +#if 0 // PB + rxtx = new RxTx(this); +#endif + rpcServer = new RpcServer(); + service = new MyService(this); + rpcServer->registerService(service, myport?myport:7878); + +#if 0 // PB serverPortNum = DRONE_PORT; clientSock = NULL; if (myport) - serverPortNum = myport; - - rxtx = new RxTx(this); + serverPortNum = myport); server = new QTcpServer(this); connect(server, SIGNAL(newConnection()), this, SLOT(when_newConnection())); @@ -21,6 +27,7 @@ Drone::Drone(QDialog *parent) LogInt(tr("Unable to start the server: %1").arg(server->errorString())); else LogInt(tr("The server is running on %1:%2").arg(server->serverAddress().toString()).arg(server->serverPort())); +#endif } void Drone::Log(const char* str) @@ -28,17 +35,20 @@ void Drone::Log(const char* str) ui.teLog->append(QString(str)); } +#if 0 // PB int Drone::SendMsg(const void* msg, int size) { qDebug("Inside SendMsg\n"); clientSock->write((char*) msg, size); } +#endif void Drone::LogInt(const QString &str) { ui.teLog->append(str); } +#if 0 // PB void Drone::when_newConnection() { if (clientSock) @@ -83,3 +93,4 @@ void Drone::when_error(QAbstractSocket::SocketError socketError) { LogInt(clientSock->errorString()); } +#endif diff --git a/server/drone.h b/server/drone.h index f99255b..3c4adba 100644 --- a/server/drone.h +++ b/server/drone.h @@ -5,7 +5,11 @@ #include #include "ui_drone.h" #include "abstracthost.h" +#if 0 // PB #include "rxtx.h" +#endif +#include "rpcserver.h" +#include "myservice.h" class Drone : public QDialog, AbstractHost @@ -13,24 +17,31 @@ class Drone : public QDialog, AbstractHost Q_OBJECT public: + Ui::Drone ui; Drone(QDialog *parent = 0); void Log(const char *msg); +#if 0 // PB int SendMsg(const void* msg, int msgLen); +#endif - Ui::Drone ui; private: +#if 0 // PB RxTx *rxtx; +#endif + RpcServer *rpcServer; + OstProto::OstService *service; + void LogInt(const QString &msg); +#if 0 // PB QTcpServer *server; QTcpSocket *clientSock; #define DRONE_PORT 7878 quint16 serverPortNum; - // Ui::Drone ui; - void LogInt(const QString &msg); + private slots: void when_newConnection(); void when_disconnected(); void when_dataAvail(); void when_error(QAbstractSocket::SocketError socketError); +#endif }; #endif - diff --git a/server/drone.pro b/server/drone.pro index 1fd8862..df79396 100644 --- a/server/drone.pro +++ b/server/drone.pro @@ -2,8 +2,14 @@ TEMPLATE = app CONFIG += qt QT += network DEFINES += HAVE_REMOTE +INCLUDEPATH += "c:\msys\1.0\local\include" INCLUDEPATH += "C:\DevelLibs\WpdPack\Include" +INCLUDEPATH += "..\rpc" LIBS += -L"C:\DevelLibs\WpdPack\Lib" -lwpcap -HEADERS += drone.h +LIBS += -L"..\rpc\debug" -lpbrpc +HEADERS += drone.h FORMS += drone.ui -SOURCES += drone_main.cpp drone.cpp rxtx.cpp +SOURCES += drone_main.cpp drone.cpp +SOURCES += myservice.cpp + +SOURCES += "..\common\protocol.pb.cc" diff --git a/server/myservice.cpp b/server/myservice.cpp new file mode 100644 index 0000000..93e625c --- /dev/null +++ b/server/myservice.cpp @@ -0,0 +1,290 @@ +#include "myservice.h" +#include "qdebug.h" + +#define LOG(...) {sprintf(logStr, __VA_ARGS__); host->Log(logStr);} + +MyService::MyService(AbstractHost *host) +{ + pcap_if_t *dev; + int i=0; + char errbuf[PCAP_ERRBUF_SIZE]; + + // Init Data + this->host = host; + numPorts = 0; + alldevs = NULL; + + LOG("Retrieving the device list from the local machine\n"); + if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) + { + LOG("Error in pcap_findalldevs_ex: %s\n", errbuf); + goto _fail; + } + + /* Count number of local ports */ + for(dev = alldevs; dev != NULL; dev = dev->next) + numPorts++; + + portInfo = new PortInfo[numPorts]; + + /* Populate and Print the list */ + for(i=0, dev=alldevs; dev!=NULL; i++, dev=dev->next) + { +#if 0 // PB + //portInfo[i].portId = i; + //portInfo[i].dev = dev; + //portInfo[i].streamHead = NULL; + //portInfo[i].streamTail = NULL; +#endif + portInfo[i].setId(i); + portInfo[i].setPcapDev(dev); +#if 1 + LOG("%d. %s", i, dev->name); + if (dev->description) + { + LOG(" (%s)\n", dev->description); + } + else + LOG(" (No description available)\n"); +#endif + } + + if (i == 0) + { + LOG("\nNo interfaces found! Make sure WinPcap is installed.\n"); + goto _fail; + } + +_fail: + return; +} + +MyService::~MyService() +{ + unsigned int i; +#if 0 // PB????? + for (i = 0; i < numPorts; i++) + DeleteAllStreams(i); +#endif + pcap_freealldevs(alldevs); +} + +void MyService::getPortIdList( + ::google::protobuf::RpcController* controller, + const ::OstProto::Void* request, + ::OstProto::PortIdList* response, + ::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + + for (uint i = 0; i < numPorts; i++) + response->add_port_id(portInfo[i].d.port_id()); + + qDebug("Server(%s): portid count = %d", __FUNCTION__, response->port_id_size()); + + qDebug("Server(%s): %s", __FUNCTION__, response->DebugString().c_str()); + + done->Run(); +} + +void MyService::getPortConfig(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::PortConfigList* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + + for (int i=0; i < request->port_id_size(); i++) + { + unsigned int id; + + id = request->port_id(i); + if (id < numPorts) + { + OstProto::PortConfig *p; + + p = response->add_list(); + p->CopyFrom(portInfo[request->port_id(i)].d); + } + } + + done->Run(); +} + +void MyService::getStreamIdList(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::StreamIdList* response, +::google::protobuf::Closure* done) +{ + + for (int i = 0; i < request->port_id_size(); i++) + { + unsigned int portId; + + portId = request->port_id(i); + if (portId >= numPorts) + { + qDebug("%s: Invalid port id %d", __FUNCTION__, portId); + continue; // TODO: Partial status of RPC + } + + for (int j = 0; j < portInfo[portId].streamList.size(); j++) + { + OstProto::StreamId *s, *q; + + q = portInfo[portId].streamList[j].d.mutable_id(); + assert(q->port_id() == portId); + + s = response->add_id(); + s->set_port_id(portId); + s->set_stream_id(q->stream_id()); + } + } + done->Run(); +} + +void MyService::getStreamConfig(::google::protobuf::RpcController* controller, +const ::OstProto::StreamIdList* request, +::OstProto::StreamConfigList* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + + for (int i = 0; i < request->id_size(); i++) + { + unsigned int portId; + unsigned int streamId; + + portId = request->id(i).port_id(); + if (portId >= numPorts) + { + qDebug("%s: Invalid port id %d", __FUNCTION__, portId); + continue; // TODO: Partial status of RPC + } + + streamId = request->id(i).stream_id(); + if (streamId >= numPorts) + { + qDebug("%s: Invalid port id %d", __FUNCTION__, portId); + continue; // TODO: Partial status of RPC + } + + for (int j = 0; j < portInfo[portId].streamList.size(); j++) + { + OstProto::Stream *s, *q; + +#if 0 + q = portInfo[portId].streamList[j].d.e_stream(); + assert(q->port_id() == portId); + + s = response->add_stream(); + s->set_port_id(portId); + s->set_stream_id(q->stream_id()); +#endif + // TODO: more params + } + } + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::addStream(::google::protobuf::RpcController* controller, +const ::OstProto::StreamIdList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::deleteStream(::google::protobuf::RpcController* controller, +const ::OstProto::StreamIdList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::modifyStream(::google::protobuf::RpcController* controller, +const ::OstProto::StreamConfigList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::startTx(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::stopTx(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::startCapture(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::stopCapture(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::getCaptureBuffer(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::CaptureBufferList* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::getStats(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::PortStatsList* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + +void MyService::clearStats(::google::protobuf::RpcController* controller, +const ::OstProto::PortIdList* request, +::OstProto::Ack* response, +::google::protobuf::Closure* done) +{ + qDebug("In %s", __FUNCTION__); + controller->SetFailed("Not Implemented"); + done->Run(); +} + diff --git a/server/myservice.h b/server/myservice.h new file mode 100644 index 0000000..83ebc0f --- /dev/null +++ b/server/myservice.h @@ -0,0 +1,146 @@ +#ifndef _MY_SERVICE_H +#define _MY_SERVICE_H + + +#if 0 +#include +#include +#endif + +#include "../common/protocol.pb.h" +#include "abstracthost.h" +#include +#include + +#define MAX_PKT_HDR_SIZE 1536 +#define MAX_STREAM_NAME_SIZE 64 + +class MyService; + +class StreamInfo +{ + friend class MyService; + + OstProto::Stream d; + +#if 0 // PB + unsigned int id; + + char name[MAX_STREAM_NAME_SIZE]; + unsigned char pktHdr[MAX_PKT_HDR_SIZE]; + unsigned short hdrLen; + unsigned short pktLen; + unsigned int dataPattern; + unsigned int flags; +#define STREAM_FLAG_MASK_STATUS 0x00000001 +#define STREAM_FLAG_VALUE_STATUS_DISABLED 0x00000000 +#define STREAM_FLAG_VALUE_STATUS_ENABLED 0x00000001 + + struct _Stream *next; +#endif +}; + + +class PortInfo +{ + friend class MyService; + + OstProto::PortConfig d; + pcap_if_t *dev; + + QList streamList; + +#if 0 // PB + unsigned int portId; // FIXME:need? + Stream *streamHead; + Stream *streamTail; +#endif + +public: + // TODO(LOW): Both setId and setPcapDev() should together form the ctor + void setId(unsigned int id) { d.set_port_id(id); } + void setPcapDev(pcap_if_t *dev) + { + this->dev = dev; + d.set_name("eth"); // FIXME: suffix portid + d.set_description(dev->description); + d.set_is_enabled(true); // FIXME:check + d.set_is_oper_up(true); // FIXME:check + d.set_is_exclusive_control(false); // FIXME: check + } +}; + +class MyService: public OstProto::OstService +{ + AbstractHost *host; + char logStr[1024]; + + unsigned numPorts; + PortInfo *portInfo; + pcap_if_t *alldevs; + +public: + MyService(AbstractHost* host); + virtual ~MyService(); + + //static const ::google::protobuf::ServiceDescriptor* descriptor(); + + virtual void getPortIdList(::google::protobuf::RpcController* controller, + const ::OstProto::Void* request, + ::OstProto::PortIdList* response, + ::google::protobuf::Closure* done); + virtual void getPortConfig(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::PortConfigList* response, + ::google::protobuf::Closure* done); + virtual void getStreamIdList(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::StreamIdList* response, + ::google::protobuf::Closure* done); + virtual void getStreamConfig(::google::protobuf::RpcController* controller, + const ::OstProto::StreamIdList* request, + ::OstProto::StreamConfigList* response, + ::google::protobuf::Closure* done); + virtual void addStream(::google::protobuf::RpcController* controller, + const ::OstProto::StreamIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void deleteStream(::google::protobuf::RpcController* controller, + const ::OstProto::StreamIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void modifyStream(::google::protobuf::RpcController* controller, + const ::OstProto::StreamConfigList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void startTx(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void stopTx(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void startCapture(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void stopCapture(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); + virtual void getCaptureBuffer(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::CaptureBufferList* response, + ::google::protobuf::Closure* done); + virtual void getStats(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::PortStatsList* response, + ::google::protobuf::Closure* done); + virtual void clearStats(::google::protobuf::RpcController* controller, + const ::OstProto::PortIdList* request, + ::OstProto::Ack* response, + ::google::protobuf::Closure* done); +}; + +#endif diff --git a/server/rxtx.cpp b/server/rxtx.cpp index 2eab59b..f4b5308 100644 --- a/server/rxtx.cpp +++ b/server/rxtx.cpp @@ -1,6 +1,12 @@ + +File Not used anymore + +#if 0 #include "qtglobal" // FIXME: needed only for qdebug #include "rxtx.h" +#if 0 // PB #include "../common/protocol.h" +#endif @@ -157,7 +163,9 @@ void RxTx::SendCapabilityInfo(void) } host->Log("Sending msg\n"); host->Log(logStr); +#if 0 // PB host->SendMsg(pktBuff, msgLen); +#endif } void RxTx::ProcessPortConfig(const char* msg, int len) @@ -503,4 +511,4 @@ Stream* RxTx::GetStream(unsigned int port, unsigned int streamId) return NULL; } - +#endif diff --git a/server/rxtx.h b/server/rxtx.h index 986b978..fac9331 100644 --- a/server/rxtx.h +++ b/server/rxtx.h @@ -1,9 +1,16 @@ + +File not used anymore + +#if 0 + #ifndef _RXTX_H #define _RXTX_H #include "pcap.h" #include "abstracthost.h" +#include "../common/protocol.h" + #define GET16(x) (UINT16)( \ (*((UINT8*)x+0) << 16 ) \ | (*((UINT8*)x+1))) @@ -74,3 +81,4 @@ class RxTx }; #endif +#endif