156 lines
4.6 KiB
C
156 lines
4.6 KiB
C
|
#ifndef _SMACK_H
|
||
|
#define _SMACK_H
|
||
|
#include <stdio.h>
|
||
|
|
||
|
#define SMACK_NOT_FOUND ((size_t)(~0))
|
||
|
|
||
|
/**
|
||
|
* "Anchor" flags are specified only for patterns that must
|
||
|
* match at the start of input, at the end, or both.
|
||
|
* These are equivalent to the regex specifiers "^" and "$"
|
||
|
* respectively.
|
||
|
*/
|
||
|
enum {
|
||
|
SMACK_ANCHOR_BEGIN = 0x01,
|
||
|
SMACK_ANCHOR_END = 0x02,
|
||
|
SMACK_SNMP_HACK = 0x04,
|
||
|
SMACK_WILDCARDS = 0x08,
|
||
|
};
|
||
|
|
||
|
enum {
|
||
|
SMACK_CASE_SENSITIVE = 0,
|
||
|
SMACK_CASE_INSENSITIVE = 1,
|
||
|
};
|
||
|
|
||
|
|
||
|
/**
|
||
|
* This is the function that will be called whenever SMACK
|
||
|
* finds a pattern.
|
||
|
*/
|
||
|
typedef int (*FOUND_CALLBACK)(size_t id, int offset, void *data);
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Create the Aho-Corasick search object. After creation, you can start
|
||
|
* adding patterns, but you cannot use it for searching until you've
|
||
|
* compiled the patterns.
|
||
|
*/
|
||
|
struct SMACK *
|
||
|
smack_create(const char *name, unsigned nocase);
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Cleans up and frees an object created with smack_create().
|
||
|
*/
|
||
|
void
|
||
|
smack_destroy(struct SMACK *smack);
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Registers a pattern with the search engine. The 'smack' object
|
||
|
* must have been created with 'smack_create()', but you must not
|
||
|
* have yet called 'smack_compile()' to compile the patterns. The
|
||
|
* "id" field can contain a pointer (size_t is 64-bit on 64-bit
|
||
|
* systems).
|
||
|
*/
|
||
|
void
|
||
|
smack_add_pattern( struct SMACK * smack,
|
||
|
const void * pattern,
|
||
|
unsigned pattern_length,
|
||
|
size_t id,
|
||
|
unsigned flags);
|
||
|
|
||
|
/**
|
||
|
* You call this function after you have registered all the patterns
|
||
|
* using 'smack_add_pattern()' in order to compile the state-machine.
|
||
|
* Don't use the state-machine with 'smack_search()' until you have
|
||
|
* compiled all the patterns with this function.
|
||
|
*/
|
||
|
void
|
||
|
smack_compile(struct SMACK *smack);
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Run the state-machine, searching for the compiled patterns within
|
||
|
* a block of data/text. This can only be called after "smack_compile()"
|
||
|
* has created the state-machine.
|
||
|
*
|
||
|
* If the input is fragmented, this function can be called repeatedly
|
||
|
* for each fragment. Patterns that cross fragments will still be
|
||
|
* detected.
|
||
|
*
|
||
|
* The caller must initialize "*state" to zero "0" before running this
|
||
|
* function on the first fragment, but must thereafter leave it
|
||
|
* unchanged between fragments. (If the caller resets the *state variable
|
||
|
* to zero between each fragment, then patterns that cross fragment
|
||
|
* boundaries cannot be detected).
|
||
|
*/
|
||
|
unsigned
|
||
|
smack_search( struct SMACK * smack,
|
||
|
const void * px,
|
||
|
unsigned length,
|
||
|
FOUND_CALLBACK cb_found,
|
||
|
void * cb_data,
|
||
|
unsigned * state);
|
||
|
|
||
|
size_t
|
||
|
smack_search_next( struct SMACK * smack,
|
||
|
unsigned * state,
|
||
|
const void * px,
|
||
|
unsigned * offset,
|
||
|
unsigned length
|
||
|
);
|
||
|
|
||
|
/**
|
||
|
* Called to terminate a search (after multiple calls to `smack_search_next()`.
|
||
|
* This triggers any patterns that SMACK_ANCHOR_END attribute on them.
|
||
|
* If more than one pattern can match at the end of the search text, then
|
||
|
* this should be called multiple times until SMACK_NOT_FOUND is
|
||
|
* returned.
|
||
|
* @return The 'id' field of a pattenr registered with the SMACK_ANCHOR_END
|
||
|
* attribute if that was found in the searched buffer, or SMACK_NOT_FOUND.
|
||
|
*/
|
||
|
size_t
|
||
|
smack_search_next_end( struct SMACK * smack,
|
||
|
unsigned * state
|
||
|
);
|
||
|
|
||
|
#define smack_search_start(state) (*(state)) = 0
|
||
|
|
||
|
/**
|
||
|
* If there are multiple matches at the current state, returns the next
|
||
|
* one. Otherwise, returns NOT_FOUND. Used with "smack_search_next()".
|
||
|
*/
|
||
|
size_t
|
||
|
smack_next_match( struct SMACK * smack,
|
||
|
unsigned * state);
|
||
|
|
||
|
/**
|
||
|
* Call this after search is done. This is not generally necessary.
|
||
|
* It's only purpose is to detect patterns that have the
|
||
|
* SMACK_ANCHOR_END flag set. If no pattern has that flag, then
|
||
|
* this function will do nothing.
|
||
|
*/
|
||
|
unsigned
|
||
|
smack_search_end( struct SMACK * smack,
|
||
|
FOUND_CALLBACK cb_found,
|
||
|
void * cb_data,
|
||
|
unsigned * state);
|
||
|
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Runs a regression test on the module to make sure it's compiled
|
||
|
* correctly for the current platform.
|
||
|
*
|
||
|
* @return
|
||
|
* zero if regression test succeeds, non-zero on failure
|
||
|
*/
|
||
|
int
|
||
|
smack_selftest(void);
|
||
|
|
||
|
int
|
||
|
smack_benchmark(void);
|
||
|
|
||
|
#endif /*_SMACK_H*/
|