}
const MagicPage* HexBook::find_spell(
- const uint8_t* s, unsigned n, const MagicPage* p, unsigned i) const
+ const uint8_t* s, unsigned n, const MagicPage* p, unsigned i, const MagicPage*& bookmark) const
{
while ( i < n )
{
{
if ( p->any )
{
- if ( const MagicPage* q = find_spell(s, n, p->next[c], i+1) )
+ if ( const MagicPage* q = find_spell(s, n, p->next[c], i+1, bookmark) )
return q;
}
else
}
if ( p->any )
{
- if ( const MagicPage* q = find_spell(s, n, p->any, i+1) )
+ if ( const MagicPage* q = find_spell(s, n, p->any, i+1, bookmark) )
return q;
}
return p->value ? p : nullptr;
}
const char* MagicBook::find_spell(const uint8_t* data, unsigned len,
- const MagicPage*& p) const
+ const MagicPage*& p, const MagicPage*& bookmark) const
{
assert(p);
- p = find_spell(data, len, p, 0);
+ p = find_spell(data, len, p, 0, bookmark);
return p ? p->value : nullptr;
}
MagicBook& operator=(const MagicBook&) = delete;
virtual bool add_spell(const char* key, const char*& val) = 0;
- virtual const char* find_spell(const uint8_t* data, unsigned len, const MagicPage*&) const;
+ virtual const char* find_spell(const uint8_t* data, unsigned len, const MagicPage*& p,
+ const MagicPage*& bookmark) const;
const MagicPage* page1() const
{ return root; }
- virtual void set_bookmark(const MagicPage* page = nullptr) const
- { (void)page; }
- virtual const MagicPage* get_bookmark() const
- { return nullptr; }
-
protected:
MagicBook();
MagicPage* root;
virtual const MagicPage* find_spell(const uint8_t*, unsigned,
- const MagicPage*, unsigned) const = 0;
+ const MagicPage*, unsigned, const MagicPage*&) const = 0;
};
//-------------------------------------------------------------------------
bool add_spell(const char*, const char*&) override;
- void set_bookmark(const MagicPage* page = nullptr) const override
- { glob = page; }
-
- const MagicPage* get_bookmark() const override
- { return glob; }
-
private:
bool translate(const char*, HexVector&);
void add_spell(const char*, const char*, HexVector&, unsigned, MagicPage*);
- const MagicPage* find_spell(const uint8_t*, unsigned, const MagicPage*, unsigned) const override;
-
- mutable const MagicPage* glob;
+ const MagicPage* find_spell(const uint8_t*, unsigned, const MagicPage*, unsigned,
+ const MagicPage*&) const override;
};
//-------------------------------------------------------------------------
private:
bool translate(const char*, HexVector&);
void add_spell(const char*, const char*, HexVector&, unsigned, MagicPage*);
- const MagicPage* find_spell(const uint8_t*, unsigned, const MagicPage*, unsigned) const override;
+ const MagicPage* find_spell(const uint8_t*, unsigned, const MagicPage*, unsigned,
+ const MagicPage*&) const override;
};
#endif
#include "magic.h"
-using namespace snort;
using namespace std;
#define WILD 0x100
-SpellBook::SpellBook() : glob(nullptr)
+SpellBook::SpellBook()
{
// allows skipping leading whitespace only
root->next[(int)' '] = root;
++i;
}
p->key = key;
- p->value = SnortConfig::get_static_name(val);
+ p->value = snort::SnortConfig::get_static_name(val);
}
bool SpellBook::add_spell(const char* key, const char*& val)
}
const MagicPage* SpellBook::find_spell(
- const uint8_t* s, unsigned n, const MagicPage* p, unsigned i) const
+ const uint8_t* s, unsigned n, const MagicPage* p, unsigned i, const MagicPage*& bookmark) const
{
while ( i < n )
{
{
if ( p->any )
{
- if ( const MagicPage* q = find_spell(s, n, p->next[c], i+1) )
+ if ( const MagicPage* q = find_spell(s, n, p->next[c], i+1, bookmark) )
return q;
}
else
{
while ( i < n )
{
- if ( const MagicPage* q = find_spell(s, n, p->any, i) )
+ if ( const MagicPage* q = find_spell(s, n, p->any, i, bookmark) )
{
- glob = q->any ? q : p;
+ bookmark = q->any ? q : p;
return q;
}
++i;
return p;
}
- // If no match but has glob, continue lookup from glob
- if ( !p->value && glob )
+ // If no match but has bookmark, continue lookup from bookmark
+ if ( !p->value && bookmark )
{
- p = glob;
- glob = nullptr;
+ p = bookmark;
+ bookmark = nullptr;
- return find_spell(s, n, p, i);
+ return find_spell(s, n, p, i, bookmark);
}
return p->value ? p : nullptr;
{
const MagicPage* hex;
const MagicPage* spell;
+ const MagicPage* bookmark;
vector<CurseServiceTracker> curse_tracker;
};
Wizard* wizard;
Wand wand;
uint16_t wizard_processed_bytes;
- const MagicPage* bookmark; // pointer to last glob
};
class Wizard : public Inspector
{ return !w.hex && !w.spell && w.curse_tracker.empty(); }
void reset(Wand&, bool tcp, bool c2s);
bool cast_spell(Wand&, Flow*, const uint8_t*, unsigned, uint16_t&);
- bool spellbind(const MagicPage*&, Flow*, const uint8_t*, unsigned);
+ bool spellbind(const MagicPage*&, Flow*, const uint8_t*, unsigned, const MagicPage*&);
bool cursebind(const vector<CurseServiceTracker>&, Flow*, const uint8_t*, unsigned);
public:
//-------------------------------------------------------------------------
MagicSplitter::MagicSplitter(bool c2s, class Wizard* w) :
- StreamSplitter(c2s), wizard_processed_bytes(0), bookmark(nullptr)
+ StreamSplitter(c2s), wizard_processed_bytes(0)
{
wizard = w;
w->add_ref();
Profile profile(wizPerfStats);
count_scan(pkt->flow);
- // setting last glob from current flow
- if ( wand.spell )
- wand.spell->book.set_bookmark(bookmark);
bytes_scanned += len;
if ( wizard->cast_spell(wand, pkt->flow, data, len, wizard_processed_bytes) )
wizard_processed_bytes = 0;
return STOP;
}
-
else if ( wizard->finished(wand) || bytes_scanned >= max(pkt->flow) )
{
count_miss(pkt->flow);
return ABORT;
}
- // saving new last glob from current flow
- if ( wand.spell )
- bookmark = wand.spell->book.get_bookmark();
-
// FIXIT-L Ideally, this event should be raised after wizard aborts its search. However, this
// could take multiple packets because wizard needs wizard.max_search_depth payload bytes before
// it aborts. This is an issue for AppId which consumes this event. AppId is required to declare
void Wizard::reset(Wand& w, bool tcp, bool c2s)
{
+ w.bookmark = nullptr;
+
if ( c2s )
{
w.hex = c2s_hexes->page1();
w.spell = c2s_spells->page1();
- c2s_spells->set_bookmark();
}
else
{
w.hex = s2c_hexes->page1();
w.spell = s2c_spells->page1();
- s2c_spells->set_bookmark();
}
if (w.curse_tracker.empty())
}
bool Wizard::spellbind(
- const MagicPage*& m, Flow* f, const uint8_t* data, unsigned len)
+ const MagicPage*& m, Flow* f, const uint8_t* data, unsigned len, const MagicPage*& bookmark)
{
- f->service = m->book.find_spell(data, len, m);
+ f->service = m->book.find_spell(data, len, m, bookmark);
return f->service != nullptr;
}
wizard_processed_bytes += len;
- if ( w.hex && spellbind(w.hex, f, data, len) )
+ if ( w.hex && spellbind(w.hex, f, data, len, w.bookmark) )
return true;
- if ( w.spell && spellbind(w.spell, f, data, len) )
+ if ( w.spell && spellbind(w.spell, f, data, len, w.bookmark) )
return true;
if (cursebind(w.curse_tracker, f, data, curse_len))