#include "Dispatcher.h" #include "DispatcherFactory.h" #include "DissectorFactory.h" #include "Logger/Logger.h" Dispatcher::Dispatcher(std::string sName) :m_sName(sName) { } Dispatcher::~Dispatcher() { } const std::string& Dispatcher::GetName() const { return m_sName; } bool Dispatcher::Dispatch(DispatchInfo & info, ComponentFilter & filter) { // Dissect packet Dissector * pDissector = DissectorFactory::Instance().Create(GetName()); if(!pDissector) { Logger::Instance().LogError("Unable to dispatch packet: No dissector for " + GetName()); // Return what we have so far return false; } DispatchInfo * pUnprocessed = 0; ComponentFilter * pUnprocessedFilter = 0; if (pDissector->CreatesUnprocessedData()) { // create copies (for handling unprocessed data) pUnprocessed = new DispatchInfo(); ProtocolInfo * pProtocolInfo = info.GetProtocolInfo(); if (pProtocolInfo) { int nCount = pProtocolInfo->Count(); for (int i = 0; i < nCount; i++) pUnprocessed->AddProtocolInfo((*pProtocolInfo)[i]->Clone()); } pUnprocessedFilter = new ComponentFilter(filter); } if (!pDissector->Dissect(info.GetData(), info.GetDataSize())) // no information for higher levels { delete pDissector; delete pUnprocessed; delete pUnprocessedFilter; return false; } // Reassembly bool bRes = true; if(pDissector->NeedReassembly()) { ProtocolInfo * pProtocolInfo = info.GetProtocolInfo(); std::list::iterator it; for(it = m_fragments.begin(); (it != m_fragments.end()) && !((*it)->Reassemble(pDissector, pProtocolInfo)); ++it); if(it == m_fragments.end()) { if (!pDissector->FinishDissection()) { // Fragment belongs to a new packet info.DetachProtocolInfo(); pDissector->SetProtocolInfo(pProtocolInfo); m_fragments.push_front(pDissector); pDissector = 0; } // otherwise the fragment has been assembled } else { // Fragment has been assembled. Pending packet may be complete if(!(*it)->NeedReassembly()) { pDissector = (*it); m_fragments.erase(it); } else { pDissector = 0; } } if (pDissector && !pDissector->IsPacketValid()) { delete pDissector; pDissector = 0; bRes = false; } } if(!pDissector) { // Not complete packet or error... delete pUnprocessed; delete pUnprocessedFilter; return bRes; } pDissector->SaveResult(info); // Check filter ProtocolInfoElement * pProtocol = pDissector->GetLayerInfo(); if (pProtocol) { if (!filter.Match(pProtocol)) { Logger::Instance().LogDebug("Message discarded by filter"); delete pDissector; delete pUnprocessed; delete pUnprocessedFilter; return false; } filter.MoveToNextLayer(); } // Transfer to upper layer const EProtocolType upperLayerType = pDissector->GetUpperLayerType(); bRes = false; if (upperLayerType == EProtocolType_None) // all headers have been removed { filter.EnqueueMessage(info.GetData(), info.GetDataSize()); std::stringstream ss; ss << "Captured message enqueued to the TE (len " << info.GetDataSize() << ")"; Logger::Instance().LogInfo(ss.str()); bRes = true; } else { Dispatcher * pUpperLayer = DispatcherFactory::Instance().Get(upperLayerType); if(pUpperLayer) bRes = pUpperLayer->Dispatch(info, filter); } if (bRes && pDissector->ContainsUnprocessedData()) { std::pair res = pDissector->GetUnprocessedData(); pUnprocessed->SetData(res.first, res.second); bRes = Dispatch(*pUnprocessed, *pUnprocessedFilter); } delete pDissector; delete pUnprocessed; delete pUnprocessedFilter; return bRes; } void Dispatcher::AddExplicitUpperLayer(EProtocolType upperLayer/*, Filter */) { Dispatcher * pUpperLayer = DispatcherFactory::Instance().Get(upperLayer); if(pUpperLayer) { // TODO: store Upper Layer Filter m_upperLayers.push_back(pUpperLayer); } else { Logger::Instance().LogWarning("No dispatcher for requested upper layer"); } }