** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
// packet_manager.cc author Josh Rosenbaum <jorosenba@cisco.com>
--#include "packet_manager.h"
-
#include <list>
-using namespace std;
-
+#include <vector>
+#include <cstring>
- #include "framework/codec.h"
+#include "packet_manager.h"
+ #include "framework/codec.h"
#include "snort.h"
#include "thread.h"
#include "log/messages.h"
#include "protocols/packet.h"
#include "protocols/undefined_protocols.h"
+#include "time/profiler.h"
-#include "time/profiler.h"
+namespace
+{
+struct CdGenPegs{
+ PegCount total_processed = 0;
+ PegCount other_codecs = 0;
+ PegCount discards = 0;
+};
- } // anonymous namespace
+std::vector<const char*> CdGenPegNames =
+{
+ "total",
+ "other",
+ "discards"
+};
+
++} // anonymous
-//static list<const CodecApi*> s_codecs;
-//static THREAD_LOCAL decode_f grinder;
#ifdef PERF_PROFILING
THREAD_LOCAL PreprocStats decodePerfStats;
p->pkt = pkt;
len = pkthdr->caplen;
curr_prot_id = GRINDER_ID;
+ pkt_cnt.total_processed++;
- // The boolean check in this order so
- while(curr_prot_id >= 0 &&
- curr_prot_id < max_protocol_id &&
- s_protocols[curr_prot_id] != 0 &&
- s_protocols[curr_prot_id]->decode(pkt, len, p, lyr_len, next_prot_id))
+ // loop until the protocol id is no longer valid
+ while(curr_prot_id >= 0 && curr_prot_id < max_protocol_id)
{
+ if (s_protocols[curr_prot_id] == 0)
+ {
+ pkt_cnt.other_codecs++;
+ break;
+ }
+ else if( !s_protocols[curr_prot_id]->decode(pkt, len, p, lyr_len, next_prot_id))
+ {
+ pkt_cnt.discards++;
+ break;
+ }
-
- // if we have succesfully decoded this layer, push the layer
PacketClass::PushLayer(p, s_protocols[curr_prot_id], pkt, lyr_len);
curr_prot_id = next_prot_id;
+ next_prot_id = -1;
len -= lyr_len;
pkt += lyr_len;
- next_prot_id = -1;
lyr_len = 0;
}
if (!codec_registered)
WarningMessage("The Codec %s is never used\n", cd->get_name());
- // ERRRO: If multiple correct grinders found.
}
+}
-
+void PacketManager::dump_stats()
+{
+ sum_stats((PegCount*)&gpkt_cnt, (PegCount*)&pkt_cnt, array_size(CdGenPegNames));
+ for ( auto* cd : s_codecs )
+ if (cd->sum != nullptr)
+ cd->sum();
-// FatalError("Codec installation checking!!");
-}
+ std::vector<const char*> pegNames(CdGenPegNames);
+ std::vector<PegCount> pegs;
+ std::memcpy(&pegs[0], &gpkt_cnt, sizeof(gpkt_cnt));
-void PacketManager::dump_stats()
-{
-// for ( auto* cd : s_codecs )
-// cd->sum();
+// pegs.push_back(gpkt_cnt.total_processed);
+// pegs.push_back(gpkt_cnt.other_codecs);
+// pegs.push_back(gpkt_cnt.discards);
+
+ // using two temporary vectors to ensure codecs cannot
+ // see any other codecs statistics
+ std::vector<const char*> tmpNames;
+ std::vector<PegCount> tmpPegs;
+
+ for ( auto* cd : s_codecs )
+ {
+ if (cd->stats != nullptr)
+ {
+ tmpPegs.clear();
+ tmpNames.clear();
+ if(cd->stats)
+ cd->stats(tmpPegs, tmpNames);
+ if (tmpNames.size() == tmpPegs.size())
+ {
+ pegs.insert(pegs.end(), tmpPegs.begin(), tmpPegs.end());
+ pegNames.insert(pegNames.end(), tmpNames.begin(), tmpNames.end());
+ }
+ else
+ {
+ WarningMessage("The %s Codecs stats function returned a "
+ "different %d PegCounts and %d PegNames. the two "
+ "values must be equal\n",
+ cd->base.name, pegs.size(), pegNames.size());
+ }
+ }
+ }
+ show_percent_stats(&pegs[0], &pegNames[0], pegNames.size(),
+ "codecs");
}
bool PacketManager::has_codec(uint16_t cd_id)