/* Copyright (C) 2010, 2014 Srivats P. This file is part of "Ostinato" This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see */ #include "protocolmanager.h" #include "abstractprotocol.h" #include "protocol.pb.h" #include "mac.h" #include "vlan.h" #include "svlan.h" #include "vlanstack.h" // L2 Protos #include "dot3.h" #include "llc.h" #include "dot2llc.h" #include "snap.h" #include "dot2snap.h" #include "eth2.h" #include "stp.h" // L3 Protos #include "arp.h" #include "ip4.h" #include "ip6.h" #include "ip4over4.h" #include "ip4over6.h" #include "ip6over4.h" #include "ip6over6.h" // L4 Protos #include "icmp.h" #include "igmp.h" #include "mld.h" #include "tcp.h" #include "udp.h" // L5 Protos #include "textproto.h" // Special Protos #include "hexdump.h" #include "payload.h" #include "sample.h" #include "sign.h" #include "userscript.h" ProtocolManager *OstProtocolManager; ProtocolManager::ProtocolManager() { /*! \todo (LOW) calls to registerProtocol() should be done by the protocols themselves (once this is done remove the #includes for all the protocols) */ registerProtocol(OstProto::Protocol::kMacFieldNumber, (void*) MacProtocol::createInstance); registerProtocol(OstProto::Protocol::kVlanFieldNumber, (void*) VlanProtocol::createInstance); registerProtocol(OstProto::Protocol::kSvlanFieldNumber, (void*) SVlanProtocol::createInstance); registerProtocol(OstProto::Protocol::kVlanStackFieldNumber, (void*) VlanStackProtocol::createInstance); registerProtocol(OstProto::Protocol::kEth2FieldNumber, (void*) Eth2Protocol::createInstance); registerProtocol(OstProto::Protocol::kDot3FieldNumber, (void*) Dot3Protocol::createInstance); registerProtocol(OstProto::Protocol::kLlcFieldNumber, (void*) LlcProtocol::createInstance); registerProtocol(OstProto::Protocol::kDot2LlcFieldNumber, (void*) Dot2LlcProtocol::createInstance); registerProtocol(OstProto::Protocol::kSnapFieldNumber, (void*) SnapProtocol::createInstance); registerProtocol(OstProto::Protocol::kDot2SnapFieldNumber, (void*) Dot2SnapProtocol::createInstance); registerProtocol(OstProto::Protocol::kStpFieldNumber, (void*) StpProtocol::createInstance); // Layer 3 Protocols registerProtocol(OstProto::Protocol::kArpFieldNumber, (void*) ArpProtocol::createInstance); registerProtocol(OstProto::Protocol::kIp4FieldNumber, (void*) Ip4Protocol::createInstance); registerProtocol(OstProto::Protocol::kIp6FieldNumber, (void*) Ip6Protocol::createInstance); registerProtocol(OstProto::Protocol::kIp4over4FieldNumber, (void*) Ip4over4Protocol::createInstance); registerProtocol(OstProto::Protocol::kIp4over6FieldNumber, (void*) Ip4over6Protocol::createInstance); registerProtocol(OstProto::Protocol::kIp6over4FieldNumber, (void*) Ip6over4Protocol::createInstance); registerProtocol(OstProto::Protocol::kIp6over6FieldNumber, (void*) Ip6over6Protocol::createInstance); // Layer 4 Protocols registerProtocol(OstProto::Protocol::kIcmpFieldNumber, (void*) IcmpProtocol::createInstance); registerProtocol(OstProto::Protocol::kIgmpFieldNumber, (void*) IgmpProtocol::createInstance); registerProtocol(OstProto::Protocol::kMldFieldNumber, (void*) MldProtocol::createInstance); registerProtocol(OstProto::Protocol::kTcpFieldNumber, (void*) TcpProtocol::createInstance); registerProtocol(OstProto::Protocol::kUdpFieldNumber, (void*) UdpProtocol::createInstance); // Layer 5 Protocols registerProtocol(OstProto::Protocol::kTextProtocolFieldNumber, (void*) TextProtocol::createInstance); // Special Protocols registerProtocol(OstProto::Protocol::kHexDumpFieldNumber, (void*) HexDumpProtocol::createInstance); registerProtocol(OstProto::Protocol::kPayloadFieldNumber, (void*) PayloadProtocol::createInstance); registerProtocol(OstProto::Protocol::kSampleFieldNumber, (void*) SampleProtocol::createInstance); registerProtocol(OstProto::Protocol::kSignFieldNumber, (void*) SignProtocol::createInstance); registerProtocol(OstProto::Protocol::kUserScriptFieldNumber, (void*) UserScriptProtocol::createInstance); populateNeighbourProtocols(); } ProtocolManager::~ProtocolManager() { numberToNameMap.clear(); nameToNumberMap.clear(); neighbourProtocols.clear(); factory.clear(); QList pl = protocolList.values(); while (!pl.isEmpty()) delete pl.takeFirst(); } void ProtocolManager::registerProtocol(int protoNumber, void *protoInstanceCreator) { AbstractProtocol *p; Q_ASSERT(!factory.contains(protoNumber)); factory.insert(protoNumber, protoInstanceCreator); p = createProtocol(protoNumber, NULL); protocolList.insert(protoNumber, p); numberToNameMap.insert(protoNumber, p->shortName()); nameToNumberMap.insert(p->shortName(), protoNumber); } void ProtocolManager::populateNeighbourProtocols() { neighbourProtocols.clear(); foreach(AbstractProtocol *p, protocolList) { if (p->protocolIdType() != AbstractProtocol::ProtocolIdNone) { foreach(AbstractProtocol *q, protocolList) { if (q->protocolId(p->protocolIdType())) neighbourProtocols.insert( p->protocolNumber(), q->protocolNumber()); } } } } bool ProtocolManager::isRegisteredProtocol(int protoNumber) { return factory.contains(protoNumber); } AbstractProtocol* ProtocolManager::createProtocol(int protoNumber, StreamBase *stream, AbstractProtocol *parent) { AbstractProtocol* (*pc)(StreamBase*, AbstractProtocol*); AbstractProtocol* p; pc = (AbstractProtocol* (*)(StreamBase*, AbstractProtocol*)) factory.value(protoNumber); Q_ASSERT_X(pc != NULL, __FUNCTION__, qPrintable(QString("No Protocol Creator registered for protocol %1") .arg(protoNumber))); p = (*pc)(stream, parent); return p; } AbstractProtocol* ProtocolManager::createProtocol(QString protoName, StreamBase *stream, AbstractProtocol *parent) { return createProtocol(nameToNumberMap.value(protoName), stream, parent); } bool ProtocolManager::isValidNeighbour(int protoPrefix, int protoSuffix) { if (neighbourProtocols.contains(protoPrefix, protoSuffix)) return true; else return false; } bool ProtocolManager::protocolHasPayload(int protoNumber) { Q_ASSERT(protocolList.contains(protoNumber)); return protocolList.value(protoNumber)->protocolHasPayload(); } QStringList ProtocolManager::protocolDatabase() { return numberToNameMap.values(); } #if 0 void ProtocolManager::showFieldAttribs() { QStringList protocolList = protocolDatabase(); Stream stream; foreach(QString name, protocolList) { if (name.contains("/")) // assume combo continue; AbstractProtocol *protocol = OstProtocolManager->createProtocol(name, &stream); int count = protocol->fieldCount(); for (int i = 0; i < count; i++) { if (!protocol->fieldFlags(i).testFlag(AbstractProtocol::FrameField)) continue; uint bitSize = protocol->fieldData(i, AbstractProtocol::FieldBitSize) .toInt(); qDebug("$$$$, %s, %d, %s, %u, %x, %llu", qPrintable(name), i, qPrintable(protocol->fieldData(i, AbstractProtocol::FieldName).toString()), bitSize, 0, // min (1 << bitSize) - 1); } delete protocol; } } #endif