mirror of
https://github.com/zeek/zeek.git
synced 2025-10-17 14:08:20 +00:00
Merge remote-tracking branch 'origin/master' into topic/johanna/tls-more-data
This commit is contained in:
commit
b1dbd757a6
1468 changed files with 41493 additions and 19065 deletions
|
@ -1 +1 @@
|
|||
Subproject commit 5d03436d9db8a6cbaee1f459d654f977ce722467
|
||||
Subproject commit 6cdefdd1d45465ca09aba9e05c7ca12e1484ccc0
|
|
@ -82,7 +82,8 @@ int AnonymizeIPAddr::PreserveNet(ipaddr32_t input)
|
|||
|
||||
ipaddr32_t AnonymizeIPAddr_Seq::anonymize(ipaddr32_t /* input */)
|
||||
{
|
||||
return htonl(seq++);
|
||||
++seq;
|
||||
return htonl(seq);
|
||||
}
|
||||
|
||||
ipaddr32_t AnonymizeIPAddr_RandomMD5::anonymize(ipaddr32_t input)
|
||||
|
|
12
src/Anon.h
12
src/Anon.h
|
@ -66,7 +66,7 @@ protected:
|
|||
class AnonymizeIPAddr_Seq : public AnonymizeIPAddr {
|
||||
public:
|
||||
AnonymizeIPAddr_Seq() { seq = 1; }
|
||||
ipaddr32_t anonymize(ipaddr32_t addr);
|
||||
ipaddr32_t anonymize(ipaddr32_t addr) override;
|
||||
|
||||
protected:
|
||||
ipaddr32_t seq;
|
||||
|
@ -74,12 +74,12 @@ protected:
|
|||
|
||||
class AnonymizeIPAddr_RandomMD5 : public AnonymizeIPAddr {
|
||||
public:
|
||||
ipaddr32_t anonymize(ipaddr32_t addr);
|
||||
ipaddr32_t anonymize(ipaddr32_t addr) override;
|
||||
};
|
||||
|
||||
class AnonymizeIPAddr_PrefixMD5 : public AnonymizeIPAddr {
|
||||
public:
|
||||
ipaddr32_t anonymize(ipaddr32_t addr);
|
||||
ipaddr32_t anonymize(ipaddr32_t addr) override;
|
||||
|
||||
protected:
|
||||
struct anon_prefix {
|
||||
|
@ -91,10 +91,10 @@ protected:
|
|||
class AnonymizeIPAddr_A50 : public AnonymizeIPAddr {
|
||||
public:
|
||||
AnonymizeIPAddr_A50() { init(); }
|
||||
~AnonymizeIPAddr_A50();
|
||||
~AnonymizeIPAddr_A50() override;
|
||||
|
||||
ipaddr32_t anonymize(ipaddr32_t addr);
|
||||
int PreservePrefix(ipaddr32_t input, int num_bits);
|
||||
ipaddr32_t anonymize(ipaddr32_t addr) override;
|
||||
int PreservePrefix(ipaddr32_t input, int num_bits) override;
|
||||
|
||||
protected:
|
||||
struct Node {
|
||||
|
|
|
@ -40,8 +40,8 @@ typedef enum {
|
|||
|
||||
class Attr : public BroObj {
|
||||
public:
|
||||
Attr(attr_tag t, Expr* e = 0);
|
||||
~Attr();
|
||||
explicit Attr(attr_tag t, Expr* e = 0);
|
||||
~Attr() override;
|
||||
|
||||
attr_tag Tag() const { return tag; }
|
||||
Expr* AttrExpr() const { return expr; }
|
||||
|
@ -56,7 +56,7 @@ public:
|
|||
int RedundantAttrOkay() const
|
||||
{ return tag == ATTR_REDEF || tag == ATTR_OPTIONAL; }
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
void Describe(ODesc* d) const override;
|
||||
void DescribeReST(ODesc* d) const;
|
||||
|
||||
bool operator==(const Attr& other) const
|
||||
|
@ -84,7 +84,7 @@ protected:
|
|||
class Attributes : public BroObj {
|
||||
public:
|
||||
Attributes(attr_list* a, BroType* t, bool in_record);
|
||||
~Attributes();
|
||||
~Attributes() override;
|
||||
|
||||
void AddAttr(Attr* a);
|
||||
void AddAttrs(Attributes* a); // Unref's 'a' when done
|
||||
|
|
|
@ -18,7 +18,7 @@ public:
|
|||
// encode_base64()), encoding-errors will go to Reporter instead of
|
||||
// Weird. Usage errors go to Reporter in any case. Empty alphabet
|
||||
// indicates the default base64 alphabet.
|
||||
Base64Converter(Connection* conn, const string& alphabet = "");
|
||||
explicit Base64Converter(Connection* conn, const string& alphabet = "");
|
||||
~Base64Converter();
|
||||
|
||||
// A note on Decode():
|
||||
|
|
|
@ -166,17 +166,19 @@ void BroString::Set(const BroString& str)
|
|||
|
||||
const char* BroString::CheckString() const
|
||||
{
|
||||
void *nulTerm;
|
||||
if ( n == 0 )
|
||||
return "";
|
||||
|
||||
if ( memchr(b, '\0', n + final_NUL) != &b[n] )
|
||||
nulTerm = memchr(b, '\0', n + final_NUL);
|
||||
if ( nulTerm != &b[n] )
|
||||
{
|
||||
// Either an embedded NUL, or no final NUL.
|
||||
char* exp_s = Render();
|
||||
if ( b[n-1] != '\0' )
|
||||
reporter->Error("string without NUL terminator: \"%s\"", exp_s);
|
||||
else
|
||||
if ( nulTerm )
|
||||
reporter->Error("string with embedded NUL: \"%s\"", exp_s);
|
||||
else
|
||||
reporter->Error("string without NUL terminator: \"%s\"", exp_s);
|
||||
|
||||
delete [] exp_s;
|
||||
return "<string-with-NUL>";
|
||||
|
|
|
@ -36,8 +36,8 @@ public:
|
|||
|
||||
// Constructors creating internal copies of the data passed in.
|
||||
BroString(const u_char* str, int arg_n, int add_NUL);
|
||||
BroString(const char* str);
|
||||
BroString(const string& str);
|
||||
explicit BroString(const char* str);
|
||||
explicit BroString(const string& str);
|
||||
BroString(const BroString& bs);
|
||||
|
||||
// Constructor that takes owernship of the vector passed in.
|
||||
|
@ -158,7 +158,7 @@ protected:
|
|||
//
|
||||
class BroStringLenCmp {
|
||||
public:
|
||||
BroStringLenCmp(bool increasing = true) { _increasing = increasing; }
|
||||
explicit BroStringLenCmp(bool increasing = true) { _increasing = increasing; }
|
||||
bool operator()(BroString*const& bst1, BroString*const& bst2);
|
||||
|
||||
private:
|
||||
|
|
|
@ -50,10 +50,18 @@ bool Brofiler::WriteStats()
|
|||
char* bf = getenv("BRO_PROFILER_FILE");
|
||||
if ( ! bf ) return false;
|
||||
|
||||
FILE* f;
|
||||
const char* p = strstr(bf, ".XXXXXX");
|
||||
SafeDirname dirname{bf};
|
||||
|
||||
if ( p && ! p[7] )
|
||||
if ( ! ensure_intermediate_dirs(dirname.result.data()) )
|
||||
{
|
||||
reporter->Error("Failed to open BRO_PROFILER_FILE destination '%s' for writing", bf);
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE* f;
|
||||
const char* p = strstr(bf, "XXXXXX");
|
||||
|
||||
if ( p && ! p[6] )
|
||||
{
|
||||
mode_t old_umask = umask(S_IXUSR | S_IRWXO | S_IRWXG);
|
||||
int fd = mkstemp(bf);
|
||||
|
|
|
@ -52,6 +52,7 @@ bison_target(BIFParser builtin-func.y
|
|||
COMPILE_FLAGS "${BISON_FLAGS}")
|
||||
flex_target(BIFScanner builtin-func.l ${CMAKE_CURRENT_BINARY_DIR}/bif_lex.cc)
|
||||
add_flex_bison_dependency(BIFScanner BIFParser)
|
||||
set_property(SOURCE bif_lex.cc APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-sign-compare")
|
||||
|
||||
# Rule parser/scanner
|
||||
bison_target(RuleParser rule-parse.y
|
||||
|
@ -67,6 +68,7 @@ replace_yy_prefix_target(${CMAKE_CURRENT_BINARY_DIR}/rup.h
|
|||
rules_ rules_)
|
||||
flex_target(RuleScanner rule-scan.l ${CMAKE_CURRENT_BINARY_DIR}/rule-scan.cc
|
||||
COMPILE_FLAGS "-Prules_")
|
||||
set_property(SOURCE rule-scan.cc APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-sign-compare")
|
||||
|
||||
# RE parser/scanner
|
||||
bison_target(REParser re-parse.y
|
||||
|
@ -80,6 +82,7 @@ replace_yy_prefix_target(${CMAKE_CURRENT_BINARY_DIR}/rep.cc
|
|||
flex_target(REScanner re-scan.l ${CMAKE_CURRENT_BINARY_DIR}/re-scan.cc
|
||||
COMPILE_FLAGS "-Pre_")
|
||||
add_flex_bison_dependency(REScanner REParser)
|
||||
set_property(SOURCE re-scan.cc APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-sign-compare")
|
||||
|
||||
# Parser/Scanner
|
||||
bison_target(Parser parse.y
|
||||
|
@ -92,24 +95,7 @@ replace_yy_prefix_target(${CMAKE_CURRENT_BINARY_DIR}/p.cc
|
|||
bro yy)
|
||||
flex_target(Scanner scan.l ${CMAKE_CURRENT_BINARY_DIR}/scan.cc
|
||||
COMPILE_FLAGS "-Pbro")
|
||||
|
||||
########################################################################
|
||||
## bifcl (BIF compiler) target
|
||||
|
||||
set(bifcl_SRCS
|
||||
${BISON_BIFParser_INPUT}
|
||||
${FLEX_BIFScanner_INPUT}
|
||||
${BISON_BIFParser_OUTPUTS}
|
||||
${FLEX_BIFScanner_OUTPUTS}
|
||||
bif_arg.cc
|
||||
module_util.cc
|
||||
bif_arg.h
|
||||
module_util.h
|
||||
)
|
||||
|
||||
add_executable(bifcl ${bifcl_SRCS})
|
||||
|
||||
target_link_libraries(bifcl)
|
||||
set_property(SOURCE scan.cc APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-sign-compare")
|
||||
|
||||
########################################################################
|
||||
## bifcl-dependent targets
|
||||
|
@ -124,6 +110,7 @@ set(BIF_SRCS
|
|||
types.bif
|
||||
strings.bif
|
||||
reporter.bif
|
||||
option.bif
|
||||
)
|
||||
|
||||
foreach (bift ${BIF_SRCS})
|
||||
|
@ -155,6 +142,7 @@ set(bro_SUBDIR_LIBS CACHE INTERNAL "subdir libraries" FORCE)
|
|||
set(bro_PLUGIN_LIBS CACHE INTERNAL "plugin libraries" FORCE)
|
||||
|
||||
add_subdirectory(analyzer)
|
||||
add_subdirectory(broker)
|
||||
add_subdirectory(broxygen)
|
||||
add_subdirectory(file_analysis)
|
||||
add_subdirectory(input)
|
||||
|
@ -162,14 +150,6 @@ add_subdirectory(iosource)
|
|||
add_subdirectory(logging)
|
||||
add_subdirectory(probabilistic)
|
||||
|
||||
if ( ENABLE_BROKER )
|
||||
add_subdirectory(broker)
|
||||
else ()
|
||||
# Just to satisfy coverage unit tests until new Broker-based
|
||||
# communication is enabled by default.
|
||||
add_subdirectory(broker-dummy)
|
||||
endif ()
|
||||
|
||||
set(bro_SUBDIRS
|
||||
# Order is important here.
|
||||
${bro_PLUGIN_LIBS}
|
||||
|
@ -433,3 +413,24 @@ install(CODE "
|
|||
${BRO_SCRIPT_INSTALL_PATH}/policy/tuning/logs-to-elasticsearch.bro
|
||||
)
|
||||
")
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
DESTINATION include/bro
|
||||
FILES_MATCHING
|
||||
PATTERN "*.h"
|
||||
PATTERN "*.pac"
|
||||
PATTERN "3rdparty/*" EXCLUDE
|
||||
)
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/
|
||||
DESTINATION include/bro
|
||||
FILES_MATCHING
|
||||
PATTERN "*.bif.func_h"
|
||||
PATTERN "*.bif.netvar_h"
|
||||
PATTERN "*.bif.h"
|
||||
PATTERN "CMakeFiles" EXCLUDE
|
||||
)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/sqlite3.h
|
||||
DESTINATION include/bro/3rdparty
|
||||
)
|
||||
|
|
|
@ -167,21 +167,21 @@ public:
|
|||
// messages, and pid gives a pid to monitor (if the process dies, we
|
||||
// return EOF).
|
||||
ChunkedIOFd(int fd, const char* tag, pid_t pid = 0);
|
||||
virtual ~ChunkedIOFd();
|
||||
~ChunkedIOFd() override;
|
||||
|
||||
virtual bool Read(Chunk** chunk, bool may_block = false);
|
||||
virtual bool Write(Chunk* chunk);
|
||||
virtual bool Flush();
|
||||
virtual const char* Error();
|
||||
virtual bool CanRead();
|
||||
virtual bool CanWrite();
|
||||
virtual bool IsIdle();
|
||||
virtual bool IsFillingUp();
|
||||
virtual void Clear();
|
||||
virtual bool Eof() { return eof; }
|
||||
virtual int Fd() { return fd; }
|
||||
virtual iosource::FD_Set ExtraReadFDs() const;
|
||||
virtual void Stats(char* buffer, int length);
|
||||
bool Read(Chunk** chunk, bool may_block = false) override;
|
||||
bool Write(Chunk* chunk) override;
|
||||
bool Flush() override;
|
||||
const char* Error() override;
|
||||
bool CanRead() override;
|
||||
bool CanWrite() override;
|
||||
bool IsIdle() override;
|
||||
bool IsFillingUp() override;
|
||||
void Clear() override;
|
||||
bool Eof() override { return eof; }
|
||||
int Fd() override { return fd; }
|
||||
iosource::FD_Set ExtraReadFDs() const override;
|
||||
void Stats(char* buffer, int length) override;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -252,22 +252,22 @@ public:
|
|||
// Argument is an open socket and a flag indicating whether we are the
|
||||
// server side of the connection.
|
||||
ChunkedIOSSL(int socket, bool server);
|
||||
virtual ~ChunkedIOSSL();
|
||||
~ChunkedIOSSL() override;
|
||||
|
||||
virtual bool Init();
|
||||
virtual bool Read(Chunk** chunk, bool mayblock = false);
|
||||
virtual bool Write(Chunk* chunk);
|
||||
virtual bool Flush();
|
||||
virtual const char* Error();
|
||||
virtual bool CanRead();
|
||||
virtual bool CanWrite();
|
||||
virtual bool IsIdle();
|
||||
virtual bool IsFillingUp();
|
||||
virtual void Clear();
|
||||
virtual bool Eof() { return eof; }
|
||||
virtual int Fd() { return socket; }
|
||||
virtual iosource::FD_Set ExtraReadFDs() const;
|
||||
virtual void Stats(char* buffer, int length);
|
||||
bool Init() override;
|
||||
bool Read(Chunk** chunk, bool mayblock = false) override;
|
||||
bool Write(Chunk* chunk) override;
|
||||
bool Flush() override;
|
||||
const char* Error() override;
|
||||
bool CanRead() override;
|
||||
bool CanWrite() override;
|
||||
bool IsIdle() override;
|
||||
bool IsFillingUp() override;
|
||||
void Clear() override;
|
||||
bool Eof() override { return eof; }
|
||||
int Fd() override { return socket; }
|
||||
iosource::FD_Set ExtraReadFDs() const override;
|
||||
void Stats(char* buffer, int length) override;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -315,27 +315,27 @@ private:
|
|||
// Wrapper class around a another ChunkedIO which the (un-)compresses data.
|
||||
class CompressedChunkedIO : public ChunkedIO {
|
||||
public:
|
||||
CompressedChunkedIO(ChunkedIO* arg_io) // takes ownership
|
||||
explicit CompressedChunkedIO(ChunkedIO* arg_io) // takes ownership
|
||||
: io(arg_io), zin(), zout(), error(), compress(), uncompress(),
|
||||
uncompressed_bytes_read(), uncompressed_bytes_written() {}
|
||||
virtual ~CompressedChunkedIO() { delete io; }
|
||||
~CompressedChunkedIO() override { delete io; }
|
||||
|
||||
virtual bool Init(); // does *not* call arg_io->Init()
|
||||
virtual bool Read(Chunk** chunk, bool may_block = false);
|
||||
virtual bool Write(Chunk* chunk);
|
||||
virtual bool Flush() { return io->Flush(); }
|
||||
virtual const char* Error() { return error ? error : io->Error(); }
|
||||
virtual bool CanRead() { return io->CanRead(); }
|
||||
virtual bool CanWrite() { return io->CanWrite(); }
|
||||
virtual bool IsIdle() { return io->IsIdle(); }
|
||||
virtual bool IsFillingUp() { return io->IsFillingUp(); }
|
||||
virtual void Clear() { return io->Clear(); }
|
||||
bool Init() override; // does *not* call arg_io->Init()
|
||||
bool Read(Chunk** chunk, bool may_block = false) override;
|
||||
bool Write(Chunk* chunk) override;
|
||||
bool Flush() override { return io->Flush(); }
|
||||
const char* Error() override { return error ? error : io->Error(); }
|
||||
bool CanRead() override { return io->CanRead(); }
|
||||
bool CanWrite() override { return io->CanWrite(); }
|
||||
bool IsIdle() override { return io->IsIdle(); }
|
||||
bool IsFillingUp() override { return io->IsFillingUp(); }
|
||||
void Clear() override { return io->Clear(); }
|
||||
bool Eof() override { return io->Eof(); }
|
||||
|
||||
virtual bool Eof() { return io->Eof(); }
|
||||
virtual int Fd() { return io->Fd(); }
|
||||
virtual iosource::FD_Set ExtraReadFDs() const
|
||||
int Fd() override { return io->Fd(); }
|
||||
iosource::FD_Set ExtraReadFDs() const override
|
||||
{ return io->ExtraReadFDs(); }
|
||||
virtual void Stats(char* buffer, int length);
|
||||
void Stats(char* buffer, int length) override;
|
||||
|
||||
void EnableCompression(int level)
|
||||
{ deflateInit(&zout, level); compress = true; }
|
||||
|
|
|
@ -703,7 +703,7 @@ const char* CompositeHash::RecoverOneVal(const HashKey* k, const char* kp0,
|
|||
break;
|
||||
|
||||
case TYPE_PORT:
|
||||
pval = new PortVal(*kp);
|
||||
pval = port_mgr->Get(*kp);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -10,7 +10,7 @@ class ListVal;
|
|||
|
||||
class CompositeHash {
|
||||
public:
|
||||
CompositeHash(TypeList* composite_type);
|
||||
explicit CompositeHash(TypeList* composite_type);
|
||||
~CompositeHash();
|
||||
|
||||
// Compute the hash corresponding to the given index val,
|
||||
|
|
48
src/Conn.cc
48
src/Conn.cc
|
@ -289,6 +289,50 @@ bool Connection::IsReuse(double t, const u_char* pkt)
|
|||
return root_analyzer && root_analyzer->IsReuse(t, pkt);
|
||||
}
|
||||
|
||||
bool Connection::ScaledHistoryEntry(char code, uint32& counter,
|
||||
uint32& scaling_threshold,
|
||||
uint32 scaling_base)
|
||||
{
|
||||
if ( ++counter == scaling_threshold )
|
||||
{
|
||||
AddHistory(code);
|
||||
|
||||
auto new_threshold = scaling_threshold * scaling_base;
|
||||
|
||||
if ( new_threshold <= scaling_threshold )
|
||||
// This can happen due to wrap-around. In that
|
||||
// case, reset the counter but leave the threshold
|
||||
// unchanged.
|
||||
counter = 0;
|
||||
|
||||
else
|
||||
scaling_threshold = new_threshold;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Connection::HistoryThresholdEvent(EventHandlerPtr e, bool is_orig,
|
||||
uint32 threshold)
|
||||
{
|
||||
if ( ! e )
|
||||
return;
|
||||
|
||||
if ( threshold == 1 )
|
||||
// This will be far and away the most common case,
|
||||
// and at this stage it's not a *multiple* instance.
|
||||
return;
|
||||
|
||||
val_list* vl = new val_list;
|
||||
vl->append(BuildConnVal());
|
||||
vl->append(new Val(is_orig, TYPE_BOOL));
|
||||
vl->append(new Val(threshold, TYPE_COUNT));
|
||||
|
||||
ConnectionEvent(e, 0, vl);
|
||||
}
|
||||
|
||||
void Connection::DeleteTimer(double /* t */)
|
||||
{
|
||||
if ( is_active )
|
||||
|
@ -364,9 +408,9 @@ RecordVal* Connection::BuildConnVal()
|
|||
|
||||
RecordVal* id_val = new RecordVal(conn_id);
|
||||
id_val->Assign(0, new AddrVal(orig_addr));
|
||||
id_val->Assign(1, new PortVal(ntohs(orig_port), prot_type));
|
||||
id_val->Assign(1, port_mgr->Get(ntohs(orig_port), prot_type));
|
||||
id_val->Assign(2, new AddrVal(resp_addr));
|
||||
id_val->Assign(3, new PortVal(ntohs(resp_port), prot_type));
|
||||
id_val->Assign(3, port_mgr->Get(ntohs(resp_port), prot_type));
|
||||
|
||||
RecordVal *orig_endp = new RecordVal(endpoint);
|
||||
orig_endp->Assign(0, new Val(0, TYPE_COUNT));
|
||||
|
|
17
src/Conn.h
17
src/Conn.h
|
@ -57,7 +57,7 @@ class Connection : public BroObj {
|
|||
public:
|
||||
Connection(NetSessions* s, HashKey* k, double t, const ConnID* id,
|
||||
uint32 flow, const Packet* pkt, const EncapsulationStack* arg_encap);
|
||||
virtual ~Connection();
|
||||
~Connection() override;
|
||||
|
||||
// Invoked when an encapsulation is discovered. It records the
|
||||
// encapsulation with the connection and raises a "tunnel_changed"
|
||||
|
@ -240,6 +240,17 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
// Increments the passed counter and adds it as a history
|
||||
// code if it has crossed the next scaling threshold. Scaling
|
||||
// is done in terms of powers of the third argument.
|
||||
// Returns true if the threshold was crossed, false otherwise.
|
||||
bool ScaledHistoryEntry(char code, uint32& counter,
|
||||
uint32& scaling_threshold,
|
||||
uint32 scaling_base = 10);
|
||||
|
||||
void HistoryThresholdEvent(EventHandlerPtr e, bool is_orig,
|
||||
uint32 threshold);
|
||||
|
||||
void AddHistory(char code) { history += code; }
|
||||
|
||||
void DeleteTimer(double t);
|
||||
|
@ -252,7 +263,7 @@ public:
|
|||
// Sets the transport protocol in use.
|
||||
void SetTransport(TransportProto arg_proto) { proto = arg_proto; }
|
||||
|
||||
void SetUID(Bro::UID arg_uid) { uid = arg_uid; }
|
||||
void SetUID(const Bro::UID &arg_uid) { uid = arg_uid; }
|
||||
|
||||
Bro::UID GetUID() const { return uid; }
|
||||
|
||||
|
@ -336,7 +347,7 @@ public:
|
|||
double arg_t, int arg_do_expire, TimerType arg_type)
|
||||
: Timer(arg_t, arg_type)
|
||||
{ Init(arg_conn, arg_timer, arg_do_expire); }
|
||||
virtual ~ConnectionTimer();
|
||||
~ConnectionTimer() override;
|
||||
|
||||
void Dispatch(double t, int is_expire) override;
|
||||
|
||||
|
|
10
src/DFA.h
10
src/DFA.h
|
@ -23,7 +23,7 @@ class DFA_State : public BroObj {
|
|||
public:
|
||||
DFA_State(int state_num, const EquivClass* ec,
|
||||
NFA_state_list* nfa_states, AcceptingSet* accept);
|
||||
~DFA_State();
|
||||
~DFA_State() override;
|
||||
|
||||
int StateNum() const { return state_num; }
|
||||
int NFAStateNum() const { return nfa_states->length(); }
|
||||
|
@ -44,7 +44,7 @@ public:
|
|||
// Returns the equivalence classes of ec's corresponding to this state.
|
||||
const EquivClass* MetaECs() const { return meta_ec; }
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
void Describe(ODesc* d) const override;
|
||||
void Dump(FILE* f, DFA_Machine* m);
|
||||
void Stats(unsigned int* computed, unsigned int* uncomputed);
|
||||
unsigned int Size();
|
||||
|
@ -117,9 +117,7 @@ typedef PList(DFA_State) DFA_state_list;
|
|||
class DFA_Machine : public BroObj {
|
||||
public:
|
||||
DFA_Machine(NFA_Machine* n, EquivClass* ec);
|
||||
DFA_Machine(int** xtion_ptrs, int num_states, int num_ecs,
|
||||
int* acc_array);
|
||||
~DFA_Machine();
|
||||
~DFA_Machine() override;
|
||||
|
||||
DFA_State* StartState() const { return start_state; }
|
||||
|
||||
|
@ -129,7 +127,7 @@ public:
|
|||
|
||||
int Rep(int sym);
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
void Describe(ODesc* d) const override;
|
||||
void Dump(FILE* f);
|
||||
|
||||
unsigned int MemoryAllocation() const;
|
||||
|
|
|
@ -112,7 +112,7 @@ public:
|
|||
IPAddr ReqAddr() const { return req_addr; }
|
||||
string ReqStr() const
|
||||
{
|
||||
return req_host ? req_host : req_addr;
|
||||
return req_host ? req_host : req_addr.AsString();
|
||||
}
|
||||
|
||||
ListVal* Addrs();
|
||||
|
|
|
@ -42,8 +42,8 @@ enum DNS_MgrMode {
|
|||
|
||||
class DNS_Mgr : public iosource::IOSource {
|
||||
public:
|
||||
DNS_Mgr(DNS_MgrMode mode);
|
||||
virtual ~DNS_Mgr();
|
||||
explicit DNS_Mgr(DNS_MgrMode mode);
|
||||
~DNS_Mgr() override;
|
||||
|
||||
void InitPostScript();
|
||||
void Flush();
|
||||
|
@ -132,11 +132,11 @@ protected:
|
|||
void DoProcess(bool flush);
|
||||
|
||||
// IOSource interface.
|
||||
virtual void GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
|
||||
iosource::FD_Set* except);
|
||||
virtual double NextTimestamp(double* network_time);
|
||||
virtual void Process();
|
||||
virtual const char* Tag() { return "DNS_Mgr"; }
|
||||
void GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
|
||||
iosource::FD_Set* except) override;
|
||||
double NextTimestamp(double* network_time) override;
|
||||
void Process() override;
|
||||
const char* Tag() override { return "DNS_Mgr"; }
|
||||
|
||||
DNS_MgrMode mode;
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
class DbgWatch {
|
||||
public:
|
||||
DbgWatch(BroObj* var_to_watch);
|
||||
DbgWatch(Expr* expr_to_watch);
|
||||
explicit DbgWatch(BroObj* var_to_watch);
|
||||
explicit DbgWatch(Expr* expr_to_watch);
|
||||
~DbgWatch();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -19,7 +19,8 @@ DebugLogger::Stream DebugLogger::streams[NUM_DBGS] = {
|
|||
{ "logging", 0, false }, {"input", 0, false },
|
||||
{ "threading", 0, false }, { "file_analysis", 0, false },
|
||||
{ "plugins", 0, false }, { "broxygen", 0, false },
|
||||
{ "pktio", 0, false }, { "broker", 0, false }
|
||||
{ "pktio", 0, false }, { "broker", 0, false },
|
||||
{ "scripts", 0, false}
|
||||
};
|
||||
|
||||
DebugLogger::DebugLogger()
|
||||
|
|
|
@ -33,6 +33,7 @@ enum DebugStream {
|
|||
DBG_BROXYGEN, // Broxygen
|
||||
DBG_PKTIO, // Packet sources and dumpers.
|
||||
DBG_BROKER, // Broker communication
|
||||
DBG_SCRIPTS, // Script initialization
|
||||
|
||||
NUM_DBGS // Has to be last
|
||||
};
|
||||
|
|
|
@ -145,7 +145,9 @@ void ODesc::Add(double d, bool no_exp)
|
|||
AddBytes(&d, sizeof(d));
|
||||
else
|
||||
{
|
||||
char tmp[256];
|
||||
// Buffer needs enough chars to store max. possible "double" value
|
||||
// of 1.79e308 without using scientific notation.
|
||||
char tmp[350];
|
||||
|
||||
if ( no_exp )
|
||||
modp_dtoa3(d, tmp, sizeof(tmp), IsReadable() ? 6 : 8);
|
||||
|
|
|
@ -27,7 +27,7 @@ class BroType;
|
|||
|
||||
class ODesc {
|
||||
public:
|
||||
ODesc(desc_type t=DESC_READABLE, BroFile* f=0);
|
||||
explicit ODesc(desc_type t=DESC_READABLE, BroFile* f=0);
|
||||
|
||||
~ODesc();
|
||||
|
||||
|
|
10
src/Dict.h
10
src/Dict.h
|
@ -29,7 +29,7 @@ extern void generic_delete_func(void*);
|
|||
|
||||
class Dictionary {
|
||||
public:
|
||||
Dictionary(dict_order ordering = UNORDERED,
|
||||
explicit Dictionary(dict_order ordering = UNORDERED,
|
||||
int initial_size = DEFAULT_DICT_SIZE);
|
||||
virtual ~Dictionary();
|
||||
|
||||
|
@ -109,8 +109,6 @@ public:
|
|||
// which should be delete'd when no longer needed.
|
||||
IterCookie* InitForIteration() const;
|
||||
void* NextEntry(HashKey*& h, IterCookie*& cookie, int return_hash) const;
|
||||
void* NextEntry(const void*& key, int& key_len, IterCookie*& cookie)
|
||||
const;
|
||||
void StopIteration(IterCookie* cookie) const;
|
||||
|
||||
void SetDeleteFunc(dict_delete_func f) { delete_func = f; }
|
||||
|
@ -143,8 +141,8 @@ private:
|
|||
int NextPrime(int n) const;
|
||||
int IsPrime(int n) const;
|
||||
void StartChangeSize(int new_size);
|
||||
void FinishChangeSize(void);
|
||||
void MoveChains(void);
|
||||
void FinishChangeSize();
|
||||
void MoveChains();
|
||||
|
||||
// The following get and set the "density" threshold - if the
|
||||
// average hash chain length exceeds this threshold, the
|
||||
|
@ -197,7 +195,7 @@ private:
|
|||
#define PDictdeclare(type) \
|
||||
class PDict(type) : public Dictionary { \
|
||||
public: \
|
||||
PDict(type)(dict_order ordering = UNORDERED, \
|
||||
explicit PDict(type)(dict_order ordering = UNORDERED, \
|
||||
int initial_size = DEFAULT_DICT_SIZE) : \
|
||||
Dictionary(ordering, initial_size) {} \
|
||||
type* Lookup(const char* key) const \
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
class EquivClass {
|
||||
public:
|
||||
EquivClass(int size);
|
||||
explicit EquivClass(int size);
|
||||
~EquivClass();
|
||||
|
||||
void UniqueChar(int sym);
|
||||
|
|
34
src/Event.cc
34
src/Event.cc
|
@ -54,6 +54,38 @@ void Event::Describe(ODesc* d) const
|
|||
d->Add("(");
|
||||
}
|
||||
|
||||
void Event::Dispatch(bool no_remote)
|
||||
{
|
||||
if ( src == SOURCE_BROKER )
|
||||
no_remote = true;
|
||||
|
||||
if ( event_serializer )
|
||||
{
|
||||
SerialInfo info(event_serializer);
|
||||
event_serializer->Serialize(&info, handler->Name(), args);
|
||||
}
|
||||
|
||||
if ( handler->ErrorHandler() )
|
||||
reporter->BeginErrorHandler();
|
||||
|
||||
try
|
||||
{
|
||||
handler->Call(args, no_remote);
|
||||
}
|
||||
|
||||
catch ( InterpreterException& e )
|
||||
{
|
||||
// Already reported.
|
||||
}
|
||||
|
||||
if ( obj )
|
||||
// obj->EventDone();
|
||||
Unref(obj);
|
||||
|
||||
if ( handler->ErrorHandler() )
|
||||
reporter->EndErrorHandler();
|
||||
}
|
||||
|
||||
EventMgr::EventMgr()
|
||||
{
|
||||
head = tail = 0;
|
||||
|
@ -166,7 +198,7 @@ RecordVal* EventMgr::GetLocalPeerVal()
|
|||
src_val = new RecordVal(peer);
|
||||
src_val->Assign(0, new Val(0, TYPE_COUNT));
|
||||
src_val->Assign(1, new AddrVal("127.0.0.1"));
|
||||
src_val->Assign(2, new PortVal(0));
|
||||
src_val->Assign(2, port_mgr->Get(0));
|
||||
src_val->Assign(3, new Val(true, TYPE_BOOL));
|
||||
|
||||
Ref(peer_description);
|
||||
|
|
39
src/Event.h
39
src/Event.h
|
@ -16,7 +16,7 @@ public:
|
|||
Event(EventHandlerPtr handler, val_list* args,
|
||||
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
||||
TimerMgr* mgr = 0, BroObj* obj = 0);
|
||||
~Event();
|
||||
~Event() override;
|
||||
|
||||
void SetNext(Event* n) { next_event = n; }
|
||||
Event* NextEvent() const { return next_event; }
|
||||
|
@ -27,41 +27,14 @@ public:
|
|||
EventHandlerPtr Handler() const { return handler; }
|
||||
val_list* Args() const { return args; }
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
void Describe(ODesc* d) const override;
|
||||
|
||||
protected:
|
||||
friend class EventMgr;
|
||||
|
||||
// This method is protected to make sure that everybody goes through
|
||||
// EventMgr::Dispatch().
|
||||
void Dispatch(bool no_remote = false)
|
||||
{
|
||||
if ( event_serializer )
|
||||
{
|
||||
SerialInfo info(event_serializer);
|
||||
event_serializer->Serialize(&info, handler->Name(), args);
|
||||
}
|
||||
|
||||
if ( handler->ErrorHandler() )
|
||||
reporter->BeginErrorHandler();
|
||||
|
||||
try
|
||||
{
|
||||
handler->Call(args, no_remote);
|
||||
}
|
||||
|
||||
catch ( InterpreterException& e )
|
||||
{
|
||||
// Already reported.
|
||||
}
|
||||
|
||||
if ( obj )
|
||||
// obj->EventDone();
|
||||
Unref(obj);
|
||||
|
||||
if ( handler->ErrorHandler() )
|
||||
reporter->EndErrorHandler();
|
||||
}
|
||||
void Dispatch(bool no_remote = false);
|
||||
|
||||
EventHandlerPtr handler;
|
||||
val_list* args;
|
||||
|
@ -78,9 +51,9 @@ extern uint64 num_events_dispatched;
|
|||
class EventMgr : public BroObj {
|
||||
public:
|
||||
EventMgr();
|
||||
~EventMgr();
|
||||
~EventMgr() override;
|
||||
|
||||
void QueueEvent(EventHandlerPtr h, val_list* vl,
|
||||
void QueueEvent(const EventHandlerPtr &h, val_list* vl,
|
||||
SourceID src = SOURCE_LOCAL, analyzer::ID aid = 0,
|
||||
TimerMgr* mgr = 0, BroObj* obj = 0)
|
||||
{
|
||||
|
@ -118,7 +91,7 @@ public:
|
|||
// Returns a peer record describing the local Bro.
|
||||
RecordVal* GetLocalPeerVal();
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
void Describe(ODesc* d) const override;
|
||||
|
||||
protected:
|
||||
void QueueEvent(Event* event);
|
||||
|
|
|
@ -5,10 +5,8 @@
|
|||
#include "RemoteSerializer.h"
|
||||
#include "NetVar.h"
|
||||
|
||||
#ifdef ENABLE_BROKER
|
||||
#include "broker/Manager.h"
|
||||
#include "broker/Data.h"
|
||||
#endif
|
||||
|
||||
EventHandler::EventHandler(const char* arg_name)
|
||||
{
|
||||
|
@ -32,19 +30,16 @@ EventHandler::operator bool() const
|
|||
return enabled && ((local && local->HasBodies())
|
||||
|| receivers.length()
|
||||
|| generate_always
|
||||
#ifdef ENABLE_BROKER
|
||||
|| ! auto_remote_send.empty()
|
||||
// TODO: and require a subscriber interested in a topic or unsolicited flags?
|
||||
#endif
|
||||
);
|
||||
|| ! auto_publish.empty());
|
||||
}
|
||||
|
||||
FuncType* EventHandler::FType()
|
||||
FuncType* EventHandler::FType(bool check_export)
|
||||
{
|
||||
if ( type )
|
||||
return type;
|
||||
|
||||
ID* id = lookup_ID(name, current_module.c_str());
|
||||
ID* id = lookup_ID(name, current_module.c_str(), false, false,
|
||||
check_export);
|
||||
|
||||
if ( ! id )
|
||||
return 0;
|
||||
|
@ -84,14 +79,11 @@ void EventHandler::Call(val_list* vl, bool no_remote)
|
|||
remote_serializer->SendCall(&info, receivers[i], name, vl);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BROKER
|
||||
|
||||
if ( ! auto_remote_send.empty() )
|
||||
if ( ! auto_publish.empty() )
|
||||
{
|
||||
// TODO: also short-circuit based on interested subscribers/flags?
|
||||
broker::message msg;
|
||||
msg.reserve(vl->length() + 1);
|
||||
msg.emplace_back(Name());
|
||||
// Send event in form [name, xs...] where xs represent the arguments.
|
||||
broker::vector xs;
|
||||
xs.reserve(vl->length());
|
||||
bool valid_args = true;
|
||||
|
||||
for ( auto i = 0; i < vl->length(); ++i )
|
||||
|
@ -99,30 +91,33 @@ void EventHandler::Call(val_list* vl, bool no_remote)
|
|||
auto opt_data = bro_broker::val_to_data((*vl)[i]);
|
||||
|
||||
if ( opt_data )
|
||||
msg.emplace_back(move(*opt_data));
|
||||
xs.emplace_back(move(*opt_data));
|
||||
else
|
||||
{
|
||||
valid_args = false;
|
||||
auto_remote_send.clear();
|
||||
reporter->Error("failed auto-remote event '%s', disabled",
|
||||
Name());
|
||||
auto_publish.clear();
|
||||
reporter->Error("failed auto-remote event '%s', disabled", Name());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( valid_args )
|
||||
{
|
||||
for ( auto it = auto_remote_send.begin();
|
||||
it != auto_remote_send.end(); ++it )
|
||||
for ( auto it = auto_publish.begin(); ; )
|
||||
{
|
||||
if ( std::next(it) == auto_remote_send.end() )
|
||||
broker_mgr->Event(it->first, move(msg), it->second);
|
||||
const auto& topic = *it;
|
||||
++it;
|
||||
|
||||
if ( it != auto_publish.end() )
|
||||
broker_mgr->PublishEvent(topic, Name(), xs);
|
||||
else
|
||||
broker_mgr->Event(it->first, msg, it->second);
|
||||
{
|
||||
broker_mgr->PublishEvent(topic, Name(), std::move(xs));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( local )
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#define EVENTHANDLER
|
||||
|
||||
#include <assert.h>
|
||||
#include <map>
|
||||
#include <unordered_set>
|
||||
#include <string>
|
||||
#include "List.h"
|
||||
#include "BroList.h"
|
||||
|
@ -17,34 +17,32 @@ class UnserialInfo;
|
|||
|
||||
class EventHandler {
|
||||
public:
|
||||
EventHandler(const char* name);
|
||||
explicit EventHandler(const char* name);
|
||||
~EventHandler();
|
||||
|
||||
const char* Name() { return name; }
|
||||
Func* LocalHandler() { return local; }
|
||||
FuncType* FType();
|
||||
FuncType* FType(bool check_export = true);
|
||||
|
||||
void SetLocalHandler(Func* f);
|
||||
|
||||
void AddRemoteHandler(SourceID peer);
|
||||
void RemoveRemoteHandler(SourceID peer);
|
||||
|
||||
#ifdef ENABLE_BROKER
|
||||
void AutoRemote(std::string topic, int flags)
|
||||
void AutoPublish(std::string topic)
|
||||
{
|
||||
auto_remote_send[std::move(topic)] = flags;
|
||||
auto_publish.insert(std::move(topic));
|
||||
}
|
||||
|
||||
void AutoRemoteStop(const std::string& topic)
|
||||
void AutoUnpublish(const std::string& topic)
|
||||
{
|
||||
auto_remote_send.erase(topic);
|
||||
auto_publish.erase(topic);
|
||||
}
|
||||
#endif
|
||||
|
||||
void Call(val_list* vl, bool no_remote = false);
|
||||
|
||||
// Returns true if there is at least one local or remote handler.
|
||||
operator bool() const;
|
||||
explicit operator bool() const;
|
||||
|
||||
void SetUsed() { used = true; }
|
||||
bool Used() { return used; }
|
||||
|
@ -81,9 +79,7 @@ private:
|
|||
typedef List(SourceID) receiver_list;
|
||||
receiver_list receivers;
|
||||
|
||||
#ifdef ENABLE_BROKER
|
||||
std::map<std::string, int> auto_remote_send; // topic -> flags
|
||||
#endif
|
||||
std::unordered_set<std::string> auto_publish;
|
||||
};
|
||||
|
||||
// Encapsulates a ptr to an event handler to overload the boolean operator.
|
||||
|
@ -102,7 +98,7 @@ public:
|
|||
|
||||
EventHandler* Ptr() { return handler; }
|
||||
|
||||
operator bool() const { return handler && *handler; }
|
||||
explicit operator bool() const { return handler && *handler; }
|
||||
EventHandler* operator->() { return handler; }
|
||||
const EventHandler* operator->() const { return handler; }
|
||||
|
||||
|
|
494
src/Expr.cc
494
src/Expr.cc
|
@ -16,22 +16,24 @@
|
|||
#include "Trigger.h"
|
||||
#include "IPAddr.h"
|
||||
|
||||
#include "broker/Data.h"
|
||||
|
||||
const char* expr_name(BroExprTag t)
|
||||
{
|
||||
static char errbuf[512];
|
||||
|
||||
static const char* expr_names[int(NUM_EXPRS)] = {
|
||||
"name", "const",
|
||||
"(*)",
|
||||
"++", "--", "!", "+", "-",
|
||||
"+", "-", "+=", "-=", "*", "/", "%", "&&", "||",
|
||||
"++", "--", "!", "~", "+", "-",
|
||||
"+", "-", "+=", "-=", "*", "/", "%",
|
||||
"&", "|", "^",
|
||||
"&&", "||",
|
||||
"<", "<=", "==", "!=", ">=", ">", "?:", "ref",
|
||||
"=", "~", "[]", "$", "?$", "[=]",
|
||||
"table()", "set()", "vector()",
|
||||
"$=", "in", "<<>>",
|
||||
"()", "event", "schedule",
|
||||
"coerce", "record_coerce", "table_coerce",
|
||||
"sizeof", "flatten"
|
||||
"sizeof", "flatten", "cast", "is"
|
||||
};
|
||||
|
||||
if ( int(t) >= NUM_EXPRS )
|
||||
|
@ -283,6 +285,9 @@ Expr* NameExpr::MakeLvalue()
|
|||
if ( id->IsConst() && ! in_const_init )
|
||||
ExprError("const is not a modifiable lvalue");
|
||||
|
||||
if ( id->IsOption() && ! in_const_init )
|
||||
ExprError("option is not a modifiable lvalue");
|
||||
|
||||
return new RefExpr(this);
|
||||
}
|
||||
|
||||
|
@ -453,7 +458,13 @@ Val* UnaryExpr::Eval(Frame* f) const
|
|||
if ( is_vector(v) )
|
||||
{
|
||||
VectorVal* v_op = v->AsVectorVal();
|
||||
VectorVal* result = new VectorVal(Type()->AsVectorType());
|
||||
VectorType* out_t;
|
||||
if ( Type()->Tag() == TYPE_ANY )
|
||||
out_t = v->Type()->AsVectorType();
|
||||
else
|
||||
out_t = Type()->AsVectorType();
|
||||
|
||||
VectorVal* result = new VectorVal(out_t);
|
||||
|
||||
for ( unsigned int i = 0; i < v_op->Size(); ++i )
|
||||
{
|
||||
|
@ -660,6 +671,12 @@ Val* BinaryExpr::Fold(Val* v1, Val* v2) const
|
|||
if ( it == TYPE_INTERNAL_STRING )
|
||||
return StringFold(v1, v2);
|
||||
|
||||
if ( v1->Type()->Tag() == TYPE_PATTERN )
|
||||
return PatternFold(v1, v2);
|
||||
|
||||
if ( v1->Type()->IsSet() )
|
||||
return SetFold(v1, v2);
|
||||
|
||||
if ( it == TYPE_INTERNAL_ADDR )
|
||||
return AddrFold(v1, v2);
|
||||
|
||||
|
@ -701,6 +718,12 @@ Val* BinaryExpr::Fold(Val* v1, Val* v2) const
|
|||
else \
|
||||
Internal("bad type in BinaryExpr::Fold");
|
||||
|
||||
#define DO_UINT_FOLD(op) \
|
||||
if ( is_unsigned ) \
|
||||
u3 = u1 op u2; \
|
||||
else \
|
||||
Internal("bad type in BinaryExpr::Fold");
|
||||
|
||||
#define DO_FOLD(op) \
|
||||
if ( is_integral ) \
|
||||
i3 = i1 op i2; \
|
||||
|
@ -774,8 +797,12 @@ Val* BinaryExpr::Fold(Val* v1, Val* v2) const
|
|||
|
||||
break;
|
||||
|
||||
case EXPR_AND: DO_INT_FOLD(&&); break;
|
||||
case EXPR_OR: DO_INT_FOLD(||); break;
|
||||
case EXPR_AND: DO_UINT_FOLD(&); break;
|
||||
case EXPR_OR: DO_UINT_FOLD(|); break;
|
||||
case EXPR_XOR: DO_UINT_FOLD(^); break;
|
||||
|
||||
case EXPR_AND_AND: DO_INT_FOLD(&&); break;
|
||||
case EXPR_OR_OR: DO_INT_FOLD(||); break;
|
||||
|
||||
case EXPR_LT: DO_INT_VAL_FOLD(<); break;
|
||||
case EXPR_LE: DO_INT_VAL_FOLD(<=); break;
|
||||
|
@ -836,6 +863,77 @@ Val* BinaryExpr::StringFold(Val* v1, Val* v2) const
|
|||
return new Val(result, TYPE_BOOL);
|
||||
}
|
||||
|
||||
|
||||
Val* BinaryExpr::PatternFold(Val* v1, Val* v2) const
|
||||
{
|
||||
const RE_Matcher* re1 = v1->AsPattern();
|
||||
const RE_Matcher* re2 = v2->AsPattern();
|
||||
|
||||
if ( tag != EXPR_AND && tag != EXPR_OR )
|
||||
BadTag("BinaryExpr::PatternFold");
|
||||
|
||||
RE_Matcher* res = tag == EXPR_AND ?
|
||||
RE_Matcher_conjunction(re1, re2) :
|
||||
RE_Matcher_disjunction(re1, re2);
|
||||
|
||||
return new PatternVal(res);
|
||||
}
|
||||
|
||||
Val* BinaryExpr::SetFold(Val* v1, Val* v2) const
|
||||
{
|
||||
TableVal* tv1 = v1->AsTableVal();
|
||||
TableVal* tv2 = v2->AsTableVal();
|
||||
TableVal* result;
|
||||
bool res = false;
|
||||
|
||||
switch ( tag ) {
|
||||
case EXPR_AND:
|
||||
return tv1->Intersect(tv2);
|
||||
|
||||
case EXPR_OR:
|
||||
result = v1->Clone()->AsTableVal();
|
||||
|
||||
if ( ! tv2->AddTo(result, false, false) )
|
||||
reporter->InternalError("set union failed to type check");
|
||||
return result;
|
||||
|
||||
case EXPR_SUB:
|
||||
result = v1->Clone()->AsTableVal();
|
||||
|
||||
if ( ! tv2->RemoveFrom(result) )
|
||||
reporter->InternalError("set difference failed to type check");
|
||||
return result;
|
||||
|
||||
case EXPR_EQ:
|
||||
res = tv1->EqualTo(tv2);
|
||||
break;
|
||||
|
||||
case EXPR_NE:
|
||||
res = ! tv1->EqualTo(tv2);
|
||||
break;
|
||||
|
||||
case EXPR_LT:
|
||||
res = tv1->IsSubsetOf(tv2) && tv1->Size() < tv2->Size();
|
||||
break;
|
||||
|
||||
case EXPR_LE:
|
||||
res = tv1->IsSubsetOf(tv2);
|
||||
break;
|
||||
|
||||
case EXPR_GE:
|
||||
case EXPR_GT:
|
||||
// These should't happen due to canonicalization.
|
||||
reporter->InternalError("confusion over canonicalization in set comparison");
|
||||
break;
|
||||
|
||||
default:
|
||||
BadTag("BinaryExpr::SetFold", expr_name(tag));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return new Val(res, TYPE_BOOL);
|
||||
}
|
||||
|
||||
Val* BinaryExpr::AddrFold(Val* v1, Val* v2) const
|
||||
{
|
||||
IPAddr a1 = v1->AsAddr();
|
||||
|
@ -896,11 +994,17 @@ void BinaryExpr::PromoteOps(TypeTag t)
|
|||
TypeTag bt1 = op1->Type()->Tag();
|
||||
TypeTag bt2 = op2->Type()->Tag();
|
||||
|
||||
if ( IsVector(bt1) )
|
||||
bool is_vec1 = IsVector(bt1);
|
||||
bool is_vec2 = IsVector(bt2);
|
||||
|
||||
if ( is_vec1 )
|
||||
bt1 = op1->Type()->AsVectorType()->YieldType()->Tag();
|
||||
if ( IsVector(bt2) )
|
||||
if ( is_vec2 )
|
||||
bt2 = op2->Type()->AsVectorType()->YieldType()->Tag();
|
||||
|
||||
if ( (is_vec1 || is_vec2) && ! (is_vec1 && is_vec2) )
|
||||
reporter->Warning("mixing vector and scalar operands is deprecated");
|
||||
|
||||
if ( bt1 != t )
|
||||
op1 = new ArithCoerceExpr(op1, t);
|
||||
if ( bt2 != t )
|
||||
|
@ -990,7 +1094,10 @@ IncrExpr::IncrExpr(BroExprTag arg_tag, Expr* arg_op)
|
|||
if ( ! IsIntegral(t->AsVectorType()->YieldType()->Tag()) )
|
||||
ExprError("vector elements must be integral for increment operator");
|
||||
else
|
||||
{
|
||||
reporter->Warning("increment/decrement operations for vectors deprecated");
|
||||
SetType(t->Ref());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1076,6 +1183,39 @@ bool IncrExpr::DoUnserialize(UnserialInfo* info)
|
|||
return true;
|
||||
}
|
||||
|
||||
ComplementExpr::ComplementExpr(Expr* arg_op) : UnaryExpr(EXPR_COMPLEMENT, arg_op)
|
||||
{
|
||||
if ( IsError() )
|
||||
return;
|
||||
|
||||
BroType* t = op->Type();
|
||||
TypeTag bt = t->Tag();
|
||||
|
||||
if ( bt != TYPE_COUNT )
|
||||
ExprError("requires \"count\" operand");
|
||||
else
|
||||
SetType(base_type(TYPE_COUNT));
|
||||
}
|
||||
|
||||
Val* ComplementExpr::Fold(Val* v) const
|
||||
{
|
||||
return new Val(~ v->InternalUnsigned(), type->Tag());
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIAL(ComplementExpr, SER_COMPLEMENT_EXPR);
|
||||
|
||||
bool ComplementExpr::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
DO_SERIALIZE(SER_COMPLEMENT_EXPR, UnaryExpr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ComplementExpr::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
DO_UNSERIALIZE(UnaryExpr);
|
||||
return true;
|
||||
}
|
||||
|
||||
NotExpr::NotExpr(Expr* arg_op) : UnaryExpr(EXPR_NOT, arg_op)
|
||||
{
|
||||
if ( IsError() )
|
||||
|
@ -1311,7 +1451,8 @@ bool AddExpr::DoUnserialize(UnserialInfo* info)
|
|||
}
|
||||
|
||||
AddToExpr::AddToExpr(Expr* arg_op1, Expr* arg_op2)
|
||||
: BinaryExpr(EXPR_ADD_TO, arg_op1->MakeLvalue(), arg_op2)
|
||||
: BinaryExpr(EXPR_ADD_TO,
|
||||
is_vector(arg_op1) ? arg_op1 : arg_op1->MakeLvalue(), arg_op2)
|
||||
{
|
||||
if ( IsError() )
|
||||
return;
|
||||
|
@ -1325,6 +1466,32 @@ AddToExpr::AddToExpr(Expr* arg_op1, Expr* arg_op2)
|
|||
SetType(base_type(bt1));
|
||||
else if ( BothInterval(bt1, bt2) )
|
||||
SetType(base_type(bt1));
|
||||
|
||||
else if ( IsVector(bt1) )
|
||||
{
|
||||
bt1 = op1->Type()->AsVectorType()->YieldType()->Tag();
|
||||
|
||||
if ( IsArithmetic(bt1) )
|
||||
{
|
||||
if ( IsArithmetic(bt2) )
|
||||
{
|
||||
if ( bt2 != bt1 )
|
||||
op2 = new ArithCoerceExpr(op2, bt1);
|
||||
|
||||
SetType(op1->Type()->Ref());
|
||||
}
|
||||
|
||||
else
|
||||
ExprError("appending non-arithmetic to arithmetic vector");
|
||||
}
|
||||
|
||||
else if ( bt1 != bt2 )
|
||||
ExprError("incompatible vector append");
|
||||
|
||||
else
|
||||
SetType(op1->Type()->Ref());
|
||||
}
|
||||
|
||||
else
|
||||
ExprError("requires two arithmetic or two string operands");
|
||||
}
|
||||
|
@ -1342,6 +1509,14 @@ Val* AddToExpr::Eval(Frame* f) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
if ( is_vector(v1) )
|
||||
{
|
||||
VectorVal* vv = v1->AsVectorVal();
|
||||
if ( ! vv->Assign(vv->Size(), v2) )
|
||||
reporter->Error("type-checking failed in vector append");
|
||||
return v1;
|
||||
}
|
||||
|
||||
Val* result = Fold(v1, v2);
|
||||
Unref(v1);
|
||||
Unref(v2);
|
||||
|
@ -1375,24 +1550,39 @@ SubExpr::SubExpr(Expr* arg_op1, Expr* arg_op2)
|
|||
if ( IsError() )
|
||||
return;
|
||||
|
||||
TypeTag bt1 = op1->Type()->Tag();
|
||||
if ( IsVector(bt1) )
|
||||
bt1 = op1->Type()->AsVectorType()->YieldType()->Tag();
|
||||
const BroType* t1 = op1->Type();
|
||||
const BroType* t2 = op2->Type();
|
||||
|
||||
TypeTag bt2 = op2->Type()->Tag();
|
||||
TypeTag bt1 = t1->Tag();
|
||||
if ( IsVector(bt1) )
|
||||
bt1 = t1->AsVectorType()->YieldType()->Tag();
|
||||
|
||||
TypeTag bt2 = t2->Tag();
|
||||
if ( IsVector(bt2) )
|
||||
bt2 = op2->Type()->AsVectorType()->YieldType()->Tag();
|
||||
bt2 = t2->AsVectorType()->YieldType()->Tag();
|
||||
|
||||
BroType* base_result_type = 0;
|
||||
|
||||
if ( bt1 == TYPE_TIME && bt2 == TYPE_INTERVAL )
|
||||
base_result_type = base_type(bt1);
|
||||
|
||||
else if ( bt1 == TYPE_TIME && bt2 == TYPE_TIME )
|
||||
SetType(base_type(TYPE_INTERVAL));
|
||||
|
||||
else if ( bt1 == TYPE_INTERVAL && bt2 == TYPE_INTERVAL )
|
||||
base_result_type = base_type(bt1);
|
||||
|
||||
else if ( t1->IsSet() && t2->IsSet() )
|
||||
{
|
||||
if ( same_type(t1, t2) )
|
||||
SetType(op1->Type()->Ref());
|
||||
else
|
||||
ExprError("incompatible \"set\" operands");
|
||||
}
|
||||
|
||||
else if ( BothArithmetic(bt1, bt2) )
|
||||
PromoteType(max_type(bt1, bt2), is_vector(op1) || is_vector(op2));
|
||||
|
||||
else
|
||||
ExprError("requires arithmetic operands");
|
||||
|
||||
|
@ -1643,13 +1833,20 @@ BoolExpr::BoolExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
|
|||
if ( BothBool(bt1, bt2) )
|
||||
{
|
||||
if ( is_vector(op1) || is_vector(op2) )
|
||||
{
|
||||
if ( ! (is_vector(op1) && is_vector(op2)) )
|
||||
reporter->Warning("mixing vector and scalar operands is deprecated");
|
||||
SetType(new VectorType(base_type(TYPE_BOOL)));
|
||||
}
|
||||
else
|
||||
SetType(base_type(TYPE_BOOL));
|
||||
}
|
||||
|
||||
else if ( bt1 == TYPE_PATTERN && bt2 == bt1 )
|
||||
{
|
||||
reporter->Warning("&& and || operators deprecated for pattern operands");
|
||||
SetType(base_type(TYPE_PATTERN));
|
||||
}
|
||||
|
||||
else
|
||||
ExprError("requires boolean operands");
|
||||
|
@ -1660,23 +1857,7 @@ Val* BoolExpr::DoSingleEval(Frame* f, Val* v1, Expr* op2) const
|
|||
if ( ! v1 )
|
||||
return 0;
|
||||
|
||||
if ( Type()->Tag() == TYPE_PATTERN )
|
||||
{
|
||||
Val* v2 = op2->Eval(f);
|
||||
if ( ! v2 )
|
||||
return 0;
|
||||
|
||||
RE_Matcher* re1 = v1->AsPattern();
|
||||
RE_Matcher* re2 = v2->AsPattern();
|
||||
|
||||
RE_Matcher* res = tag == EXPR_AND ?
|
||||
RE_Matcher_conjunction(re1, re2) :
|
||||
RE_Matcher_disjunction(re1, re2);
|
||||
|
||||
return new PatternVal(res);
|
||||
}
|
||||
|
||||
if ( tag == EXPR_AND )
|
||||
if ( tag == EXPR_AND_AND )
|
||||
{
|
||||
if ( v1->IsZero() )
|
||||
return v1;
|
||||
|
@ -1740,8 +1921,8 @@ Val* BoolExpr::Eval(Frame* f) const
|
|||
|
||||
VectorVal* result = 0;
|
||||
|
||||
// It's either and EXPR_AND or an EXPR_OR.
|
||||
bool is_and = (tag == EXPR_AND);
|
||||
// It's either an EXPR_AND_AND or an EXPR_OR_OR.
|
||||
bool is_and = (tag == EXPR_AND_AND);
|
||||
|
||||
if ( scalar_v->IsZero() == is_and )
|
||||
{
|
||||
|
@ -1782,7 +1963,7 @@ Val* BoolExpr::Eval(Frame* f) const
|
|||
Val* op2 = vec_v2->Lookup(i);
|
||||
if ( op1 && op2 )
|
||||
{
|
||||
bool local_result = (tag == EXPR_AND) ?
|
||||
bool local_result = (tag == EXPR_AND_AND) ?
|
||||
(! op1->IsZero() && ! op2->IsZero()) :
|
||||
(! op1->IsZero() || ! op2->IsZero());
|
||||
|
||||
|
@ -1812,6 +1993,70 @@ bool BoolExpr::DoUnserialize(UnserialInfo* info)
|
|||
return true;
|
||||
}
|
||||
|
||||
BitExpr::BitExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
|
||||
: BinaryExpr(arg_tag, arg_op1, arg_op2)
|
||||
{
|
||||
if ( IsError() )
|
||||
return;
|
||||
|
||||
const BroType* t1 = op1->Type();
|
||||
const BroType* t2 = op2->Type();
|
||||
|
||||
TypeTag bt1 = t1->Tag();
|
||||
if ( IsVector(bt1) )
|
||||
bt1 = t1->AsVectorType()->YieldType()->Tag();
|
||||
|
||||
TypeTag bt2 = t2->Tag();
|
||||
if ( IsVector(bt2) )
|
||||
bt2 = t2->AsVectorType()->YieldType()->Tag();
|
||||
|
||||
if ( (bt1 == TYPE_COUNT || bt1 == TYPE_COUNTER) &&
|
||||
(bt2 == TYPE_COUNT || bt2 == TYPE_COUNTER) )
|
||||
{
|
||||
if ( bt1 == TYPE_COUNTER && bt2 == TYPE_COUNTER )
|
||||
ExprError("cannot apply a bitwise operator to two \"counter\" operands");
|
||||
else if ( is_vector(op1) || is_vector(op2) )
|
||||
SetType(new VectorType(base_type(TYPE_COUNT)));
|
||||
else
|
||||
SetType(base_type(TYPE_COUNT));
|
||||
}
|
||||
|
||||
else if ( bt1 == TYPE_PATTERN )
|
||||
{
|
||||
if ( bt2 != TYPE_PATTERN )
|
||||
ExprError("cannot mix pattern and non-pattern operands");
|
||||
else if ( tag == EXPR_XOR )
|
||||
ExprError("'^' operator does not apply to patterns");
|
||||
else
|
||||
SetType(base_type(TYPE_PATTERN));
|
||||
}
|
||||
|
||||
else if ( t1->IsSet() && t2->IsSet() )
|
||||
{
|
||||
if ( same_type(t1, t2) )
|
||||
SetType(op1->Type()->Ref());
|
||||
else
|
||||
ExprError("incompatible \"set\" operands");
|
||||
}
|
||||
|
||||
else
|
||||
ExprError("requires \"count\" or compatible \"set\" operands");
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIAL(BitExpr, SER_BIT_EXPR);
|
||||
|
||||
bool BitExpr::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
DO_SERIALIZE(SER_BIT_EXPR, BinaryExpr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BitExpr::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
DO_UNSERIALIZE(BinaryExpr);
|
||||
return true;
|
||||
}
|
||||
|
||||
EqExpr::EqExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
|
||||
: BinaryExpr(arg_tag, arg_op1, arg_op2)
|
||||
{
|
||||
|
@ -1820,13 +2065,16 @@ EqExpr::EqExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
|
|||
|
||||
Canonicize();
|
||||
|
||||
TypeTag bt1 = op1->Type()->Tag();
|
||||
if ( IsVector(bt1) )
|
||||
bt1 = op1->Type()->AsVectorType()->YieldType()->Tag();
|
||||
const BroType* t1 = op1->Type();
|
||||
const BroType* t2 = op2->Type();
|
||||
|
||||
TypeTag bt2 = op2->Type()->Tag();
|
||||
TypeTag bt1 = t1->Tag();
|
||||
if ( IsVector(bt1) )
|
||||
bt1 = t1->AsVectorType()->YieldType()->Tag();
|
||||
|
||||
TypeTag bt2 = t2->Tag();
|
||||
if ( IsVector(bt2) )
|
||||
bt2 = op2->Type()->AsVectorType()->YieldType()->Tag();
|
||||
bt2 = t2->AsVectorType()->YieldType()->Tag();
|
||||
|
||||
if ( is_vector(op1) || is_vector(op2) )
|
||||
SetType(new VectorType(base_type(TYPE_BOOL)));
|
||||
|
@ -1856,10 +2104,20 @@ EqExpr::EqExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
|
|||
break;
|
||||
|
||||
case TYPE_ENUM:
|
||||
if ( ! same_type(op1->Type(), op2->Type()) )
|
||||
if ( ! same_type(t1, t2) )
|
||||
ExprError("illegal enum comparison");
|
||||
break;
|
||||
|
||||
case TYPE_TABLE:
|
||||
if ( t1->IsSet() && t2->IsSet() )
|
||||
{
|
||||
if ( ! same_type(t1, t2) )
|
||||
ExprError("incompatible sets in comparison");
|
||||
break;
|
||||
}
|
||||
|
||||
// FALL THROUGH
|
||||
|
||||
default:
|
||||
ExprError("illegal comparison");
|
||||
}
|
||||
|
@ -1922,13 +2180,16 @@ RelExpr::RelExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
|
|||
|
||||
Canonicize();
|
||||
|
||||
TypeTag bt1 = op1->Type()->Tag();
|
||||
if ( IsVector(bt1) )
|
||||
bt1 = op1->Type()->AsVectorType()->YieldType()->Tag();
|
||||
const BroType* t1 = op1->Type();
|
||||
const BroType* t2 = op2->Type();
|
||||
|
||||
TypeTag bt2 = op2->Type()->Tag();
|
||||
TypeTag bt1 = t1->Tag();
|
||||
if ( IsVector(bt1) )
|
||||
bt1 = t1->AsVectorType()->YieldType()->Tag();
|
||||
|
||||
TypeTag bt2 = t2->Tag();
|
||||
if ( IsVector(bt2) )
|
||||
bt2 = op2->Type()->AsVectorType()->YieldType()->Tag();
|
||||
bt2 = t2->AsVectorType()->YieldType()->Tag();
|
||||
|
||||
if ( is_vector(op1) || is_vector(op2) )
|
||||
SetType(new VectorType(base_type(TYPE_BOOL)));
|
||||
|
@ -1938,6 +2199,12 @@ RelExpr::RelExpr(BroExprTag arg_tag, Expr* arg_op1, Expr* arg_op2)
|
|||
if ( BothArithmetic(bt1, bt2) )
|
||||
PromoteOps(max_type(bt1, bt2));
|
||||
|
||||
else if ( t1->IsSet() && t2->IsSet() )
|
||||
{
|
||||
if ( ! same_type(t1, t2) )
|
||||
ExprError("incompatible sets in comparison");
|
||||
}
|
||||
|
||||
else if ( bt1 != bt2 )
|
||||
ExprError("operands must be of the same type");
|
||||
|
||||
|
@ -4351,9 +4618,8 @@ Val* InExpr::Fold(Val* v1, Val* v2) const
|
|||
const BroString* s1 = v1->AsString();
|
||||
const BroString* s2 = v2->AsString();
|
||||
|
||||
// Could do better here - either roll our own, to deal with
|
||||
// NULs, and/or Boyer-Moore if done repeatedly.
|
||||
return new Val(strstr(s2->CheckString(), s1->CheckString()) != 0, TYPE_BOOL);
|
||||
// Could do better here e.g. Boyer-Moore if done repeatedly.
|
||||
return new Val(strstr_n(s2->Len(), s2->Bytes(), s1->Len(), reinterpret_cast<const unsigned char*>(s1->CheckString())) != -1, TYPE_BOOL);
|
||||
}
|
||||
|
||||
if ( v1->Type()->Tag() == TYPE_ADDR &&
|
||||
|
@ -4535,13 +4801,21 @@ Val* CallExpr::Eval(Frame* f) const
|
|||
if ( func_val && v )
|
||||
{
|
||||
const ::Func* func = func_val->AsFunc();
|
||||
calling_expr = this;
|
||||
const CallExpr* current_call = f ? f->GetCall() : 0;
|
||||
call_stack.emplace_back(CallInfo{this, func});
|
||||
|
||||
if ( f )
|
||||
f->SetCall(this);
|
||||
|
||||
ret = func->Call(v, f); // No try/catch here; we pass exceptions upstream.
|
||||
try
|
||||
{
|
||||
ret = func->Call(v, f);
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
call_stack.pop_back();
|
||||
throw;
|
||||
}
|
||||
|
||||
if ( f )
|
||||
f->SetCall(current_call);
|
||||
|
@ -4549,7 +4823,7 @@ Val* CallExpr::Eval(Frame* f) const
|
|||
// Don't Unref() the arguments, as Func::Call already did that.
|
||||
delete v;
|
||||
|
||||
calling_expr = 0;
|
||||
call_stack.pop_back();
|
||||
}
|
||||
else
|
||||
delete_vals(v);
|
||||
|
@ -4870,7 +5144,7 @@ Val* ListExpr::InitVal(const BroType* t, Val* aggr) const
|
|||
Unref(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
v->Append(vi);
|
||||
}
|
||||
return v;
|
||||
|
@ -5201,6 +5475,117 @@ bool RecordAssignExpr::DoUnserialize(UnserialInfo* info)
|
|||
return true;
|
||||
}
|
||||
|
||||
CastExpr::CastExpr(Expr* arg_op, BroType* t) : UnaryExpr(EXPR_CAST, arg_op)
|
||||
{
|
||||
auto stype = Op()->Type();
|
||||
|
||||
::Ref(t);
|
||||
SetType(t);
|
||||
|
||||
if ( ! can_cast_value_to_type(stype, t) )
|
||||
ExprError("cast not supported");
|
||||
}
|
||||
|
||||
Val* CastExpr::Eval(Frame* f) const
|
||||
{
|
||||
if ( IsError() )
|
||||
return 0;
|
||||
|
||||
Val* v = op->Eval(f);
|
||||
|
||||
if ( ! v )
|
||||
return 0;
|
||||
|
||||
Val* nv = cast_value_to_type(v, Type());
|
||||
|
||||
if ( nv )
|
||||
{
|
||||
Unref(v);
|
||||
return nv;
|
||||
}
|
||||
|
||||
ODesc d;
|
||||
d.Add("invalid cast of value with type '");
|
||||
v->Type()->Describe(&d);
|
||||
d.Add("' to type '");
|
||||
Type()->Describe(&d);
|
||||
d.Add("'");
|
||||
|
||||
if ( same_type(v->Type(), bro_broker::DataVal::ScriptDataType()) &&
|
||||
! v->AsRecordVal()->Lookup(0) )
|
||||
d.Add(" (nil $data field)");
|
||||
|
||||
Unref(v);
|
||||
reporter->ExprRuntimeError(this, "%s", d.Description());
|
||||
return 0; // not reached.
|
||||
}
|
||||
|
||||
void CastExpr::ExprDescribe(ODesc* d) const
|
||||
{
|
||||
Op()->Describe(d);
|
||||
d->Add(" as ");
|
||||
Type()->Describe(d);
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIAL(CastExpr, SER_CAST_EXPR);
|
||||
|
||||
bool CastExpr::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
DO_SERIALIZE(SER_CAST_EXPR, UnaryExpr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CastExpr::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
DO_UNSERIALIZE(UnaryExpr);
|
||||
return true;
|
||||
}
|
||||
|
||||
IsExpr::IsExpr(Expr* arg_op, BroType* arg_t) : UnaryExpr(EXPR_IS, arg_op)
|
||||
{
|
||||
t = arg_t;
|
||||
::Ref(t);
|
||||
|
||||
SetType(base_type(TYPE_BOOL));
|
||||
}
|
||||
|
||||
IsExpr::~IsExpr()
|
||||
{
|
||||
Unref(t);
|
||||
}
|
||||
|
||||
Val* IsExpr::Fold(Val* v) const
|
||||
{
|
||||
if ( IsError() )
|
||||
return 0;
|
||||
|
||||
if ( can_cast_value_to_type(v, t) )
|
||||
return new Val(1, TYPE_BOOL);
|
||||
else
|
||||
return new Val(0, TYPE_BOOL);
|
||||
}
|
||||
|
||||
void IsExpr::ExprDescribe(ODesc* d) const
|
||||
{
|
||||
Op()->Describe(d);
|
||||
d->Add(" is ");
|
||||
t->Describe(d);
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIAL(IsExpr, SER_IS_EXPR_ /* sic */);
|
||||
|
||||
bool IsExpr::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
DO_SERIALIZE(SER_IS_EXPR_, UnaryExpr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsExpr::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
DO_UNSERIALIZE(UnaryExpr);
|
||||
return true;
|
||||
}
|
||||
|
||||
Expr* get_assign_expr(Expr* op1, Expr* op2, int is_init)
|
||||
{
|
||||
if ( op1->Type()->Tag() == TYPE_RECORD &&
|
||||
|
@ -5210,7 +5595,6 @@ Expr* get_assign_expr(Expr* op1, Expr* op2, int is_init)
|
|||
return new AssignExpr(op1, op2, is_init);
|
||||
}
|
||||
|
||||
|
||||
int check_and_promote_expr(Expr*& e, BroType* t)
|
||||
{
|
||||
BroType* et = e->Type();
|
||||
|
|
142
src/Expr.h
142
src/Expr.h
|
@ -17,10 +17,13 @@ typedef enum {
|
|||
EXPR_ANY = -1,
|
||||
EXPR_NAME, EXPR_CONST,
|
||||
EXPR_CLONE,
|
||||
EXPR_INCR, EXPR_DECR, EXPR_NOT, EXPR_POSITIVE, EXPR_NEGATE,
|
||||
EXPR_INCR, EXPR_DECR,
|
||||
EXPR_NOT, EXPR_COMPLEMENT,
|
||||
EXPR_POSITIVE, EXPR_NEGATE,
|
||||
EXPR_ADD, EXPR_SUB, EXPR_ADD_TO, EXPR_REMOVE_FROM,
|
||||
EXPR_TIMES, EXPR_DIVIDE, EXPR_MOD,
|
||||
EXPR_AND, EXPR_OR,
|
||||
EXPR_AND, EXPR_OR, EXPR_XOR,
|
||||
EXPR_AND_AND, EXPR_OR_OR,
|
||||
EXPR_LT, EXPR_LE, EXPR_EQ, EXPR_NE, EXPR_GE, EXPR_GT,
|
||||
EXPR_COND,
|
||||
EXPR_REF,
|
||||
|
@ -44,7 +47,9 @@ typedef enum {
|
|||
EXPR_VECTOR_COERCE,
|
||||
EXPR_SIZE,
|
||||
EXPR_FLATTEN,
|
||||
#define NUM_EXPRS (int(EXPR_FLATTEN) + 1)
|
||||
EXPR_CAST,
|
||||
EXPR_IS,
|
||||
#define NUM_EXPRS (int(EXPR_IS) + 1)
|
||||
} BroExprTag;
|
||||
|
||||
extern const char* expr_name(BroExprTag t);
|
||||
|
@ -63,7 +68,7 @@ public:
|
|||
BroType* Type() const { return type; }
|
||||
BroExprTag Tag() const { return tag; }
|
||||
|
||||
virtual ~Expr();
|
||||
~Expr() override;
|
||||
|
||||
Expr* Ref() { ::Ref(this); return this; }
|
||||
|
||||
|
@ -182,7 +187,7 @@ public:
|
|||
return (AssignExpr*) this;
|
||||
}
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
void Describe(ODesc* d) const override;
|
||||
|
||||
bool Serialize(SerialInfo* info) const;
|
||||
static Expr* Unserialize(UnserialInfo* info, BroExprTag want = EXPR_ANY);
|
||||
|
@ -191,7 +196,7 @@ public:
|
|||
|
||||
protected:
|
||||
Expr() { type = 0; }
|
||||
Expr(BroExprTag arg_tag);
|
||||
explicit Expr(BroExprTag arg_tag);
|
||||
|
||||
virtual void ExprDescribe(ODesc* d) const = 0;
|
||||
void AddTag(ODesc* d) const;
|
||||
|
@ -215,8 +220,8 @@ protected:
|
|||
|
||||
class NameExpr : public Expr {
|
||||
public:
|
||||
NameExpr(ID* id, bool const_init = false);
|
||||
~NameExpr();
|
||||
explicit NameExpr(ID* id, bool const_init = false);
|
||||
~NameExpr() override;
|
||||
|
||||
ID* Id() const { return id; }
|
||||
|
||||
|
@ -241,8 +246,8 @@ protected:
|
|||
|
||||
class ConstExpr : public Expr {
|
||||
public:
|
||||
ConstExpr(Val* val);
|
||||
~ConstExpr();
|
||||
explicit ConstExpr(Val* val);
|
||||
~ConstExpr() override;
|
||||
|
||||
Val* Value() const { return val; }
|
||||
|
||||
|
@ -278,7 +283,7 @@ protected:
|
|||
UnaryExpr() { op = 0; }
|
||||
|
||||
UnaryExpr(BroExprTag arg_tag, Expr* arg_op);
|
||||
virtual ~UnaryExpr();
|
||||
~UnaryExpr() override;
|
||||
|
||||
void ExprDescribe(ODesc* d) const override;
|
||||
|
||||
|
@ -316,7 +321,7 @@ protected:
|
|||
if ( op1->IsError() || op2->IsError() )
|
||||
SetError();
|
||||
}
|
||||
virtual ~BinaryExpr();
|
||||
~BinaryExpr() override;
|
||||
|
||||
// Returns the expression folded using the given constants.
|
||||
virtual Val* Fold(Val* v1, Val* v2) const;
|
||||
|
@ -324,6 +329,12 @@ protected:
|
|||
// Same for when the constants are strings.
|
||||
virtual Val* StringFold(Val* v1, Val* v2) const;
|
||||
|
||||
// Same for when the constants are patterns.
|
||||
virtual Val* PatternFold(Val* v1, Val* v2) const;
|
||||
|
||||
// Same for when the constants are sets.
|
||||
virtual Val* SetFold(Val* v1, Val* v2) const;
|
||||
|
||||
// Same for when the constants are addresses or subnets.
|
||||
virtual Val* AddrFold(Val* v1, Val* v2) const;
|
||||
virtual Val* SubNetFold(Val* v1, Val* v2) const;
|
||||
|
@ -350,7 +361,7 @@ protected:
|
|||
|
||||
class CloneExpr : public UnaryExpr {
|
||||
public:
|
||||
CloneExpr(Expr* op);
|
||||
explicit CloneExpr(Expr* op);
|
||||
Val* Eval(Frame* f) const override;
|
||||
|
||||
protected:
|
||||
|
@ -377,9 +388,22 @@ protected:
|
|||
DECLARE_SERIAL(IncrExpr);
|
||||
};
|
||||
|
||||
class ComplementExpr : public UnaryExpr {
|
||||
public:
|
||||
explicit ComplementExpr(Expr* op);
|
||||
|
||||
protected:
|
||||
friend class Expr;
|
||||
ComplementExpr() { }
|
||||
|
||||
Val* Fold(Val* v) const override;
|
||||
|
||||
DECLARE_SERIAL(ComplementExpr);
|
||||
};
|
||||
|
||||
class NotExpr : public UnaryExpr {
|
||||
public:
|
||||
NotExpr(Expr* op);
|
||||
explicit NotExpr(Expr* op);
|
||||
|
||||
protected:
|
||||
friend class Expr;
|
||||
|
@ -392,7 +416,7 @@ protected:
|
|||
|
||||
class PosExpr : public UnaryExpr {
|
||||
public:
|
||||
PosExpr(Expr* op);
|
||||
explicit PosExpr(Expr* op);
|
||||
|
||||
protected:
|
||||
friend class Expr;
|
||||
|
@ -405,7 +429,7 @@ protected:
|
|||
|
||||
class NegExpr : public UnaryExpr {
|
||||
public:
|
||||
NegExpr(Expr* op);
|
||||
explicit NegExpr(Expr* op);
|
||||
|
||||
protected:
|
||||
friend class Expr;
|
||||
|
@ -418,7 +442,7 @@ protected:
|
|||
|
||||
class SizeExpr : public UnaryExpr {
|
||||
public:
|
||||
SizeExpr(Expr* op);
|
||||
explicit SizeExpr(Expr* op);
|
||||
Val* Eval(Frame* f) const override;
|
||||
|
||||
protected:
|
||||
|
@ -530,6 +554,17 @@ protected:
|
|||
DECLARE_SERIAL(BoolExpr);
|
||||
};
|
||||
|
||||
class BitExpr : public BinaryExpr {
|
||||
public:
|
||||
BitExpr(BroExprTag tag, Expr* op1, Expr* op2);
|
||||
|
||||
protected:
|
||||
friend class Expr;
|
||||
BitExpr() { }
|
||||
|
||||
DECLARE_SERIAL(BitExpr);
|
||||
};
|
||||
|
||||
class EqExpr : public BinaryExpr {
|
||||
public:
|
||||
EqExpr(BroExprTag tag, Expr* op1, Expr* op2);
|
||||
|
@ -559,7 +594,7 @@ protected:
|
|||
class CondExpr : public Expr {
|
||||
public:
|
||||
CondExpr(Expr* op1, Expr* op2, Expr* op3);
|
||||
~CondExpr();
|
||||
~CondExpr() override;
|
||||
|
||||
const Expr* Op1() const { return op1; }
|
||||
const Expr* Op2() const { return op2; }
|
||||
|
@ -585,7 +620,7 @@ protected:
|
|||
|
||||
class RefExpr : public UnaryExpr {
|
||||
public:
|
||||
RefExpr(Expr* op);
|
||||
explicit RefExpr(Expr* op);
|
||||
|
||||
void Assign(Frame* f, Val* v, Opcode op = OP_ASSIGN) override;
|
||||
Expr* MakeLvalue() override;
|
||||
|
@ -602,7 +637,7 @@ public:
|
|||
// If val is given, evaluating this expression will always yield the val
|
||||
// yet still perform the assignment. Used for triggers.
|
||||
AssignExpr(Expr* op1, Expr* op2, int is_init, Val* val = 0, attr_list* attrs = 0);
|
||||
virtual ~AssignExpr() { Unref(val); }
|
||||
~AssignExpr() override { Unref(val); }
|
||||
|
||||
Val* Eval(Frame* f) const override;
|
||||
void EvalIntoAggregate(const BroType* t, Val* aggr, Frame* f) const override;
|
||||
|
@ -657,7 +692,7 @@ protected:
|
|||
class FieldExpr : public UnaryExpr {
|
||||
public:
|
||||
FieldExpr(Expr* op, const char* field_name);
|
||||
~FieldExpr();
|
||||
~FieldExpr() override;
|
||||
|
||||
int Field() const { return field; }
|
||||
const char* FieldName() const { return field_name; }
|
||||
|
@ -689,7 +724,7 @@ protected:
|
|||
class HasFieldExpr : public UnaryExpr {
|
||||
public:
|
||||
HasFieldExpr(Expr* op, const char* field_name);
|
||||
~HasFieldExpr();
|
||||
~HasFieldExpr() override;
|
||||
|
||||
const char* FieldName() const { return field_name; }
|
||||
|
||||
|
@ -709,8 +744,8 @@ protected:
|
|||
|
||||
class RecordConstructorExpr : public UnaryExpr {
|
||||
public:
|
||||
RecordConstructorExpr(ListExpr* constructor_list);
|
||||
~RecordConstructorExpr();
|
||||
explicit RecordConstructorExpr(ListExpr* constructor_list);
|
||||
~RecordConstructorExpr() override;
|
||||
|
||||
protected:
|
||||
friend class Expr;
|
||||
|
@ -728,7 +763,7 @@ class TableConstructorExpr : public UnaryExpr {
|
|||
public:
|
||||
TableConstructorExpr(ListExpr* constructor_list, attr_list* attrs,
|
||||
BroType* arg_type = 0);
|
||||
~TableConstructorExpr() { Unref(attrs); }
|
||||
~TableConstructorExpr() override { Unref(attrs); }
|
||||
|
||||
Attributes* Attrs() { return attrs; }
|
||||
|
||||
|
@ -751,7 +786,7 @@ class SetConstructorExpr : public UnaryExpr {
|
|||
public:
|
||||
SetConstructorExpr(ListExpr* constructor_list, attr_list* attrs,
|
||||
BroType* arg_type = 0);
|
||||
~SetConstructorExpr() { Unref(attrs); }
|
||||
~SetConstructorExpr() override { Unref(attrs); }
|
||||
|
||||
Attributes* Attrs() { return attrs; }
|
||||
|
||||
|
@ -772,7 +807,7 @@ protected:
|
|||
|
||||
class VectorConstructorExpr : public UnaryExpr {
|
||||
public:
|
||||
VectorConstructorExpr(ListExpr* constructor_list, BroType* arg_type = 0);
|
||||
explicit VectorConstructorExpr(ListExpr* constructor_list, BroType* arg_type = 0);
|
||||
|
||||
Val* Eval(Frame* f) const override;
|
||||
|
||||
|
@ -824,7 +859,7 @@ protected:
|
|||
class RecordCoerceExpr : public UnaryExpr {
|
||||
public:
|
||||
RecordCoerceExpr(Expr* op, RecordType* r);
|
||||
~RecordCoerceExpr();
|
||||
~RecordCoerceExpr() override;
|
||||
|
||||
protected:
|
||||
friend class Expr;
|
||||
|
@ -844,7 +879,7 @@ protected:
|
|||
class TableCoerceExpr : public UnaryExpr {
|
||||
public:
|
||||
TableCoerceExpr(Expr* op, TableType* r);
|
||||
~TableCoerceExpr();
|
||||
~TableCoerceExpr() override;
|
||||
|
||||
protected:
|
||||
friend class Expr;
|
||||
|
@ -858,7 +893,7 @@ protected:
|
|||
class VectorCoerceExpr : public UnaryExpr {
|
||||
public:
|
||||
VectorCoerceExpr(Expr* op, VectorType* v);
|
||||
~VectorCoerceExpr();
|
||||
~VectorCoerceExpr() override;
|
||||
|
||||
protected:
|
||||
friend class Expr;
|
||||
|
@ -873,7 +908,7 @@ protected:
|
|||
// into a list of individual values.
|
||||
class FlattenExpr : public UnaryExpr {
|
||||
public:
|
||||
FlattenExpr(Expr* op);
|
||||
explicit FlattenExpr(Expr* op);
|
||||
|
||||
protected:
|
||||
friend class Expr;
|
||||
|
@ -892,9 +927,9 @@ class ScheduleTimer : public Timer {
|
|||
public:
|
||||
ScheduleTimer(EventHandlerPtr event, val_list* args, double t,
|
||||
TimerMgr* tmgr);
|
||||
~ScheduleTimer();
|
||||
~ScheduleTimer() override;
|
||||
|
||||
void Dispatch(double t, int is_expire);
|
||||
void Dispatch(double t, int is_expire) override;
|
||||
|
||||
protected:
|
||||
EventHandlerPtr event;
|
||||
|
@ -905,7 +940,7 @@ protected:
|
|||
class ScheduleExpr : public Expr {
|
||||
public:
|
||||
ScheduleExpr(Expr* when, EventExpr* event);
|
||||
~ScheduleExpr();
|
||||
~ScheduleExpr() override;
|
||||
|
||||
int IsPure() const override;
|
||||
|
||||
|
@ -945,7 +980,7 @@ protected:
|
|||
class CallExpr : public Expr {
|
||||
public:
|
||||
CallExpr(Expr* func, ListExpr* args, bool in_hook = false);
|
||||
~CallExpr();
|
||||
~CallExpr() override;
|
||||
|
||||
Expr* Func() const { return func; }
|
||||
ListExpr* Args() const { return args; }
|
||||
|
@ -971,7 +1006,7 @@ protected:
|
|||
class EventExpr : public Expr {
|
||||
public:
|
||||
EventExpr(const char* name, ListExpr* args);
|
||||
~EventExpr();
|
||||
~EventExpr() override;
|
||||
|
||||
const char* Name() const { return name.c_str(); }
|
||||
ListExpr* Args() const { return args; }
|
||||
|
@ -997,8 +1032,8 @@ protected:
|
|||
class ListExpr : public Expr {
|
||||
public:
|
||||
ListExpr();
|
||||
ListExpr(Expr* e);
|
||||
~ListExpr();
|
||||
explicit ListExpr(Expr* e);
|
||||
~ListExpr() override;
|
||||
|
||||
void Append(Expr* e);
|
||||
|
||||
|
@ -1044,6 +1079,37 @@ protected:
|
|||
DECLARE_SERIAL(RecordAssignExpr);
|
||||
};
|
||||
|
||||
class CastExpr : public UnaryExpr {
|
||||
public:
|
||||
CastExpr(Expr* op, BroType* t);
|
||||
|
||||
protected:
|
||||
friend class Expr;
|
||||
CastExpr() { }
|
||||
|
||||
Val* Eval(Frame* f) const override;
|
||||
void ExprDescribe(ODesc* d) const override;
|
||||
|
||||
DECLARE_SERIAL(CastExpr);
|
||||
};
|
||||
|
||||
class IsExpr : public UnaryExpr {
|
||||
public:
|
||||
IsExpr(Expr* op, BroType* t);
|
||||
virtual ~IsExpr();
|
||||
|
||||
protected:
|
||||
friend class Expr;
|
||||
IsExpr() { }
|
||||
|
||||
Val* Fold(Val* v) const override;
|
||||
void ExprDescribe(ODesc* d) const override;
|
||||
DECLARE_SERIAL(IsExpr);
|
||||
|
||||
private:
|
||||
BroType* t;
|
||||
};
|
||||
|
||||
inline Val* Expr::ExprVal() const
|
||||
{
|
||||
if ( ! IsConst() )
|
||||
|
|
12
src/File.cc
12
src/File.cc
|
@ -302,7 +302,7 @@ FILE* BroFile::BringIntoCache()
|
|||
|
||||
if ( ! f )
|
||||
{
|
||||
strerror_r(errno, buf, sizeof(buf));
|
||||
bro_strerror_r(errno, buf, sizeof(buf));
|
||||
reporter->Error("can't open %s: %s", name, buf);
|
||||
|
||||
f = fopen("/dev/null", "w");
|
||||
|
@ -313,7 +313,7 @@ FILE* BroFile::BringIntoCache()
|
|||
return f;
|
||||
}
|
||||
|
||||
strerror_r(errno, buf, sizeof(buf));
|
||||
bro_strerror_r(errno, buf, sizeof(buf));
|
||||
reporter->Error("can't open /dev/null: %s", buf);
|
||||
return 0;
|
||||
}
|
||||
|
@ -323,7 +323,7 @@ FILE* BroFile::BringIntoCache()
|
|||
|
||||
if ( fseek(f, position, SEEK_SET) < 0 )
|
||||
{
|
||||
strerror_r(errno, buf, sizeof(buf));
|
||||
bro_strerror_r(errno, buf, sizeof(buf));
|
||||
reporter->Error("reopen seek failed: %s", buf);
|
||||
}
|
||||
|
||||
|
@ -413,7 +413,7 @@ void BroFile::Suspend()
|
|||
if ( (position = ftell(f)) < 0 )
|
||||
{
|
||||
char buf[256];
|
||||
strerror_r(errno, buf, sizeof(buf));
|
||||
bro_strerror_r(errno, buf, sizeof(buf));
|
||||
reporter->Error("ftell failed: %s", buf);
|
||||
position = 0;
|
||||
}
|
||||
|
@ -692,7 +692,7 @@ void BroFile::InitEncrypt(const char* keyfile)
|
|||
// Depending on the OpenSSL version, EVP_*_cbc()
|
||||
// returns a const or a non-const.
|
||||
EVP_CIPHER* cipher_type = (EVP_CIPHER*) EVP_bf_cbc();
|
||||
cipher_ctx = new EVP_CIPHER_CTX;
|
||||
cipher_ctx = EVP_CIPHER_CTX_new();
|
||||
|
||||
unsigned char secret[EVP_PKEY_size(pub_key)];
|
||||
unsigned char* psecret = secret;
|
||||
|
@ -747,7 +747,7 @@ void BroFile::FinishEncrypt()
|
|||
return;
|
||||
}
|
||||
|
||||
delete cipher_ctx;
|
||||
EVP_CIPHER_CTX_free(cipher_ctx);
|
||||
cipher_ctx = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,10 +22,10 @@ class RotateTimer;
|
|||
|
||||
class BroFile : public BroObj {
|
||||
public:
|
||||
BroFile(FILE* arg_f);
|
||||
explicit BroFile(FILE* arg_f);
|
||||
BroFile(FILE* arg_f, const char* filename, const char* access);
|
||||
BroFile(const char* filename, const char* access, BroType* arg_t = 0);
|
||||
virtual ~BroFile();
|
||||
~BroFile() override;
|
||||
|
||||
const char* Name() const;
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ Flare::Flare()
|
|||
static void bad_pipe_op(const char* which)
|
||||
{
|
||||
char buf[256];
|
||||
strerror_r(errno, buf, sizeof(buf));
|
||||
bro_strerror_r(errno, buf, sizeof(buf));
|
||||
reporter->FatalErrorWithCore("unexpected pipe %s failure: %s", which, buf);
|
||||
}
|
||||
|
||||
|
|
10
src/Frag.h
10
src/Frag.h
|
@ -21,7 +21,7 @@ class FragReassembler : public Reassembler {
|
|||
public:
|
||||
FragReassembler(NetSessions* s, const IP_Hdr* ip, const u_char* pkt,
|
||||
HashKey* k, double t);
|
||||
~FragReassembler();
|
||||
~FragReassembler() override;
|
||||
|
||||
void AddFragment(double t, const IP_Hdr* ip, const u_char* pkt);
|
||||
|
||||
|
@ -33,8 +33,8 @@ public:
|
|||
HashKey* Key() const { return key; }
|
||||
|
||||
protected:
|
||||
void BlockInserted(DataBlock* start_block);
|
||||
void Overlap(const u_char* b1, const u_char* b2, uint64 n);
|
||||
void BlockInserted(DataBlock* start_block) override;
|
||||
void Overlap(const u_char* b1, const u_char* b2, uint64 n) override;
|
||||
void Weird(const char* name) const;
|
||||
|
||||
u_char* proto_hdr;
|
||||
|
@ -53,9 +53,9 @@ public:
|
|||
FragTimer(FragReassembler* arg_f, double arg_t)
|
||||
: Timer(arg_t, TIMER_FRAG)
|
||||
{ f = arg_f; }
|
||||
~FragTimer();
|
||||
~FragTimer() override;
|
||||
|
||||
void Dispatch(double t, int is_expire);
|
||||
void Dispatch(double t, int is_expire) override;
|
||||
|
||||
// Break the association between this timer and its creator.
|
||||
void ClearReassembler() { f = 0; }
|
||||
|
|
|
@ -33,6 +33,15 @@ Frame::~Frame()
|
|||
Release();
|
||||
}
|
||||
|
||||
void Frame::Reset(int startIdx)
|
||||
{
|
||||
for ( int i = startIdx; i < size; ++i )
|
||||
{
|
||||
Unref(frame[i]);
|
||||
frame[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Frame::Release()
|
||||
{
|
||||
for ( int i = 0; i < size; ++i )
|
||||
|
|
|
@ -15,7 +15,7 @@ class CallExpr;
|
|||
class Frame : public BroObj {
|
||||
public:
|
||||
Frame(int size, const BroFunc* func, const val_list *fn_args);
|
||||
~Frame();
|
||||
~Frame() override;
|
||||
|
||||
Val* NthElement(int n) { return frame[n]; }
|
||||
void SetElement(int n, Val* v)
|
||||
|
@ -24,9 +24,10 @@ public:
|
|||
frame[n] = v;
|
||||
}
|
||||
|
||||
void Reset(int startIdx);
|
||||
void Release();
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
void Describe(ODesc* d) const override;
|
||||
|
||||
// For which function is this stack frame.
|
||||
const BroFunc* GetFunction() const { return function; }
|
||||
|
|
86
src/Func.cc
86
src/Func.cc
|
@ -50,7 +50,7 @@
|
|||
|
||||
extern RETSIGTYPE sig_handler(int signo);
|
||||
|
||||
const Expr* calling_expr = 0;
|
||||
vector<CallInfo> call_stack;
|
||||
bool did_builtin_init = false;
|
||||
|
||||
vector<Func*> Func::unique_ids;
|
||||
|
@ -383,11 +383,7 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
|
|||
FType()->FlavorString().c_str(), d.Description());
|
||||
}
|
||||
|
||||
loop_over_list(*args, i)
|
||||
f->SetElement(i, (*args)[i]);
|
||||
|
||||
stmt_flow_type flow = FLOW_NEXT;
|
||||
|
||||
Val* result = 0;
|
||||
|
||||
for ( size_t i = 0; i < bodies.size(); ++i )
|
||||
|
@ -398,6 +394,21 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
|
|||
|
||||
Unref(result);
|
||||
|
||||
loop_over_list(*args, j)
|
||||
{
|
||||
Val* arg = (*args)[j];
|
||||
|
||||
if ( f->NthElement(j) != arg )
|
||||
{
|
||||
// Either not yet set, or somebody reassigned
|
||||
// the frame slot.
|
||||
Ref(arg);
|
||||
f->SetElement(j, arg);
|
||||
}
|
||||
}
|
||||
|
||||
f->Reset(args->length());
|
||||
|
||||
try
|
||||
{
|
||||
result = bodies[i].stmts->Exec(f, flow);
|
||||
|
@ -433,6 +444,11 @@ Val* BroFunc::Call(val_list* args, Frame* parent) const
|
|||
}
|
||||
}
|
||||
|
||||
// We have an extra Ref for each argument (so that they don't get
|
||||
// deleted between bodies), release that.
|
||||
loop_over_list(*args, k)
|
||||
Unref((*args)[k]);
|
||||
|
||||
if ( Flavor() == FUNC_FLAVOR_HOOK )
|
||||
{
|
||||
if ( ! result )
|
||||
|
@ -621,21 +637,73 @@ bool BuiltinFunc::DoUnserialize(UnserialInfo* info)
|
|||
|
||||
void builtin_error(const char* msg, BroObj* arg)
|
||||
{
|
||||
if ( calling_expr )
|
||||
calling_expr->Error(msg, arg);
|
||||
else
|
||||
if ( call_stack.empty() )
|
||||
{
|
||||
reporter->Error(msg, arg);
|
||||
return;
|
||||
}
|
||||
|
||||
auto last_call = call_stack.back();
|
||||
|
||||
if ( call_stack.size() < 2 )
|
||||
{
|
||||
// Don't need to check for wrapper function like "<module>::__<func>"
|
||||
last_call.call->Error(msg, arg);
|
||||
return;
|
||||
}
|
||||
|
||||
auto starts_with_double_underscore = [](const std::string& name) -> bool
|
||||
{ return name.size() > 2 && name[0] == '_' && name[1] == '_'; };
|
||||
auto last_loc = last_call.call->GetLocationInfo();
|
||||
std::string last_func = last_call.func->Name();
|
||||
|
||||
auto pos = last_func.find_first_of("::");
|
||||
std::string wrapper_func;
|
||||
|
||||
if ( pos == std::string::npos )
|
||||
{
|
||||
if ( ! starts_with_double_underscore(last_func) )
|
||||
{
|
||||
last_call.call->Error(msg, arg);
|
||||
return;
|
||||
}
|
||||
|
||||
wrapper_func = last_func.substr(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto module_name = last_func.substr(0, pos);
|
||||
auto func_name = last_func.substr(pos + 2);
|
||||
|
||||
if ( ! starts_with_double_underscore(func_name) )
|
||||
{
|
||||
last_call.call->Error(msg, arg);
|
||||
return;
|
||||
}
|
||||
|
||||
wrapper_func = module_name + "::" + func_name.substr(2);
|
||||
}
|
||||
|
||||
auto parent_call = call_stack[call_stack.size() - 2];
|
||||
auto parent_func = parent_call.func->Name();
|
||||
|
||||
if ( wrapper_func == parent_func )
|
||||
parent_call.call->Error(msg, arg);
|
||||
else
|
||||
last_call.call->Error(msg, arg);
|
||||
}
|
||||
|
||||
#include "bro.bif.func_h"
|
||||
#include "stats.bif.func_h"
|
||||
#include "reporter.bif.func_h"
|
||||
#include "strings.bif.func_h"
|
||||
#include "option.bif.func_h"
|
||||
|
||||
#include "bro.bif.func_def"
|
||||
#include "stats.bif.func_def"
|
||||
#include "reporter.bif.func_def"
|
||||
#include "strings.bif.func_def"
|
||||
#include "option.bif.func_def"
|
||||
|
||||
#include "__all__.bif.cc" // Autogenerated for compiling in the bif_target() code.
|
||||
#include "__all__.bif.register.cc" // Autogenerated for compiling in the bif_target() code.
|
||||
|
@ -653,6 +721,7 @@ void init_builtin_funcs()
|
|||
TimerStats = internal_type("TimerStats")->AsRecordType();
|
||||
FileAnalysisStats = internal_type("FileAnalysisStats")->AsRecordType();
|
||||
ThreadStats = internal_type("ThreadStats")->AsRecordType();
|
||||
BrokerStats = internal_type("BrokerStats")->AsRecordType();
|
||||
|
||||
var_sizes = internal_type("var_sizes")->AsTableType();
|
||||
|
||||
|
@ -660,6 +729,7 @@ void init_builtin_funcs()
|
|||
#include "stats.bif.func_init"
|
||||
#include "reporter.bif.func_init"
|
||||
#include "strings.bif.func_init"
|
||||
#include "option.bif.func_init"
|
||||
|
||||
did_builtin_init = true;
|
||||
}
|
||||
|
|
20
src/Func.h
20
src/Func.h
|
@ -22,9 +22,9 @@ public:
|
|||
|
||||
enum Kind { BRO_FUNC, BUILTIN_FUNC };
|
||||
|
||||
Func(Kind arg_kind);
|
||||
explicit Func(Kind arg_kind);
|
||||
|
||||
virtual ~Func();
|
||||
~Func() override;
|
||||
|
||||
virtual int IsPure() const = 0;
|
||||
function_flavor Flavor() const { return FType()->Flavor(); }
|
||||
|
@ -56,7 +56,7 @@ public:
|
|||
const char* Name() const { return name.c_str(); }
|
||||
void SetName(const char* arg_name) { name = arg_name; }
|
||||
|
||||
virtual void Describe(ODesc* d) const = 0;
|
||||
void Describe(ODesc* d) const override = 0;
|
||||
virtual void DescribeDebug(ODesc* d, const val_list* args) const;
|
||||
|
||||
// This (un-)serializes only a single body (as given in SerialInfo).
|
||||
|
@ -90,7 +90,7 @@ protected:
|
|||
class BroFunc : public Func {
|
||||
public:
|
||||
BroFunc(ID* id, Stmt* body, id_list* inits, int frame_size, int priority);
|
||||
~BroFunc();
|
||||
~BroFunc() override;
|
||||
|
||||
int IsPure() const override;
|
||||
Val* Call(val_list* args, Frame* parent) const override;
|
||||
|
@ -116,7 +116,7 @@ typedef Val* (*built_in_func)(Frame* frame, val_list* args);
|
|||
class BuiltinFunc : public Func {
|
||||
public:
|
||||
BuiltinFunc(built_in_func func, const char* name, int is_pure);
|
||||
~BuiltinFunc();
|
||||
~BuiltinFunc() override;
|
||||
|
||||
int IsPure() const override;
|
||||
Val* Call(val_list* args, Frame* parent) const override;
|
||||
|
@ -140,10 +140,12 @@ extern void init_builtin_funcs_subdirs();
|
|||
|
||||
extern bool check_built_in_call(BuiltinFunc* f, CallExpr* call);
|
||||
|
||||
// This global is set prior to the interpreter making a function call.
|
||||
// It's there so that built-in functions can access the location information
|
||||
// associated with a call when reporting error messages.
|
||||
extern const Expr* calling_expr;
|
||||
struct CallInfo {
|
||||
const CallExpr* call;
|
||||
const Func* func;
|
||||
};
|
||||
|
||||
extern vector<CallInfo> call_stack;
|
||||
|
||||
// This is set to true after the built-in functions have been initialized.
|
||||
extern bool did_builtin_init;
|
||||
|
|
14
src/Hash.h
14
src/Hash.h
|
@ -20,14 +20,14 @@ typedef enum {
|
|||
|
||||
class HashKey {
|
||||
public:
|
||||
HashKey(bro_int_t i);
|
||||
HashKey(bro_uint_t u);
|
||||
HashKey(uint32 u);
|
||||
explicit HashKey(bro_int_t i);
|
||||
explicit HashKey(bro_uint_t u);
|
||||
explicit HashKey(uint32 u);
|
||||
HashKey(const uint32 u[], int n);
|
||||
HashKey(double d);
|
||||
HashKey(const void* p);
|
||||
HashKey(const char* s);
|
||||
HashKey(const BroString* s);
|
||||
explicit HashKey(double d);
|
||||
explicit HashKey(const void* p);
|
||||
explicit HashKey(const char* s);
|
||||
explicit HashKey(const BroString* s);
|
||||
~HashKey()
|
||||
{
|
||||
if ( is_our_dynamic )
|
||||
|
|
41
src/ID.cc
41
src/ID.cc
|
@ -21,12 +21,13 @@ ID::ID(const char* arg_name, IDScope arg_scope, bool arg_is_export)
|
|||
name = copy_string(arg_name);
|
||||
scope = arg_scope;
|
||||
is_export = arg_is_export;
|
||||
is_option = false;
|
||||
type = 0;
|
||||
val = 0;
|
||||
attrs = 0;
|
||||
is_const = 0;
|
||||
is_enum_const = 0;
|
||||
is_type = 0;
|
||||
is_const = false;
|
||||
is_enum_const = false;
|
||||
is_type = false;
|
||||
offset = 0;
|
||||
|
||||
infer_return_type = false;
|
||||
|
@ -41,6 +42,9 @@ ID::~ID()
|
|||
Unref(type);
|
||||
Unref(attrs);
|
||||
|
||||
for ( auto element : option_handlers )
|
||||
Unref(element.second);
|
||||
|
||||
if ( ! weak_ref )
|
||||
Unref(val);
|
||||
}
|
||||
|
@ -290,6 +294,22 @@ void ID::RemoveAttr(attr_tag a)
|
|||
}
|
||||
}
|
||||
|
||||
void ID::SetOption()
|
||||
{
|
||||
if ( is_option )
|
||||
return;
|
||||
|
||||
is_option = true;
|
||||
|
||||
// option implied redefinable
|
||||
if ( ! IsRedefinable() )
|
||||
{
|
||||
attr_list* attr = new attr_list;
|
||||
attr->append(new Attr(ATTR_REDEF));
|
||||
AddAttrs(new Attributes(attr, Type(), false));
|
||||
}
|
||||
}
|
||||
|
||||
void ID::EvalFunc(Expr* ef, Expr* ev)
|
||||
{
|
||||
Expr* arg1 = new ConstExpr(val->Ref());
|
||||
|
@ -772,3 +792,18 @@ void ID::UpdateValID()
|
|||
}
|
||||
#endif
|
||||
|
||||
void ID::AddOptionHandler(Func* callback, int priority)
|
||||
{
|
||||
option_handlers.insert({priority, callback});
|
||||
}
|
||||
|
||||
vector<Func*> ID::GetOptionHandlers() const
|
||||
{
|
||||
// multimap is sorted
|
||||
// It might be worth caching this if we expect it to be called
|
||||
// a lot...
|
||||
vector<Func*> v;
|
||||
for ( auto& element : option_handlers )
|
||||
v.push_back(element.second);
|
||||
return v;
|
||||
}
|
||||
|
|
37
src/ID.h
37
src/ID.h
|
@ -11,6 +11,7 @@
|
|||
|
||||
class Val;
|
||||
class SerialInfo;
|
||||
class Func;
|
||||
|
||||
typedef enum { INIT_NONE, INIT_FULL, INIT_EXTRA, INIT_REMOVE, } init_class;
|
||||
typedef enum { SCOPE_FUNCTION, SCOPE_MODULE, SCOPE_GLOBAL } IDScope;
|
||||
|
@ -18,7 +19,7 @@ typedef enum { SCOPE_FUNCTION, SCOPE_MODULE, SCOPE_GLOBAL } IDScope;
|
|||
class ID : public BroObj {
|
||||
public:
|
||||
ID(const char* name, IDScope arg_scope, bool arg_is_export);
|
||||
~ID();
|
||||
~ID() override;
|
||||
|
||||
const char* Name() const { return name; }
|
||||
|
||||
|
@ -34,7 +35,7 @@ public:
|
|||
BroType* Type() { return type; }
|
||||
const BroType* Type() const { return type; }
|
||||
|
||||
void MakeType() { is_type = 1; }
|
||||
void MakeType() { is_type = true; }
|
||||
BroType* AsType() { return is_type ? Type() : 0; }
|
||||
const BroType* AsType() const { return is_type ? Type() : 0; }
|
||||
|
||||
|
@ -51,21 +52,24 @@ public:
|
|||
void SetVal(Val* v, init_class c);
|
||||
void SetVal(Expr* ev, init_class c);
|
||||
|
||||
int HasVal() const { return val != 0; }
|
||||
bool HasVal() const { return val != 0; }
|
||||
Val* ID_Val() { return val; }
|
||||
const Val* ID_Val() const { return val; }
|
||||
void ClearVal();
|
||||
|
||||
void SetConst() { is_const = 1; }
|
||||
int IsConst() const { return is_const; }
|
||||
void SetConst() { is_const = true; }
|
||||
bool IsConst() const { return is_const; }
|
||||
|
||||
void SetEnumConst() { is_enum_const = 1; }
|
||||
int IsEnumConst() const { return is_enum_const; }
|
||||
void SetOption();
|
||||
bool IsOption() const { return is_option; }
|
||||
|
||||
void SetEnumConst() { is_enum_const = true; }
|
||||
bool IsEnumConst() const { return is_enum_const; }
|
||||
|
||||
void SetOffset(int arg_offset) { offset = arg_offset; }
|
||||
int Offset() const { return offset; }
|
||||
|
||||
int IsRedefinable() const { return FindAttr(ATTR_REDEF) != 0; }
|
||||
bool IsRedefinable() const { return FindAttr(ATTR_REDEF) != 0; }
|
||||
|
||||
// Returns true if ID is one of those internal globally unique IDs
|
||||
// to which MutableVals are bound (there name start with a '#').
|
||||
|
@ -97,16 +101,23 @@ public:
|
|||
bool Serialize(SerialInfo* info) const;
|
||||
static ID* Unserialize(UnserialInfo* info);
|
||||
|
||||
bool DoInferReturnType() { return infer_return_type; }
|
||||
bool DoInferReturnType() const
|
||||
{ return infer_return_type; }
|
||||
void SetInferReturnType(bool infer)
|
||||
{ infer_return_type = infer; }
|
||||
{ infer_return_type = infer; }
|
||||
|
||||
virtual TraversalCode Traverse(TraversalCallback* cb) const;
|
||||
|
||||
bool HasOptionHandlers() const
|
||||
{ return !option_handlers.empty(); }
|
||||
|
||||
// Takes ownership of callback.
|
||||
void AddOptionHandler(Func* callback, int priority);
|
||||
vector<Func*> GetOptionHandlers() const;
|
||||
|
||||
protected:
|
||||
ID() { name = 0; type = 0; val = 0; attrs = 0; }
|
||||
|
||||
void CheckAttr(Attr* attr);
|
||||
void EvalFunc(Expr* ef, Expr* ev);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -119,10 +130,12 @@ protected:
|
|||
IDScope scope;
|
||||
bool is_export;
|
||||
BroType* type;
|
||||
int is_const, is_enum_const, is_type;
|
||||
bool is_const, is_enum_const, is_type, is_option;
|
||||
int offset;
|
||||
Val* val;
|
||||
Attributes* attrs;
|
||||
// contains list of functions that are called when an option changes
|
||||
std::multimap<int, Func*> option_handlers;
|
||||
|
||||
bool infer_return_type;
|
||||
bool weak_ref;
|
||||
|
|
|
@ -370,8 +370,8 @@ RecordVal* IP_Hdr::BuildPktHdrVal(RecordVal* pkt_hdr, int sindex) const
|
|||
int tcp_hdr_len = tp->th_off * 4;
|
||||
int data_len = PayloadLen() - tcp_hdr_len;
|
||||
|
||||
tcp_hdr->Assign(0, new PortVal(ntohs(tp->th_sport), TRANSPORT_TCP));
|
||||
tcp_hdr->Assign(1, new PortVal(ntohs(tp->th_dport), TRANSPORT_TCP));
|
||||
tcp_hdr->Assign(0, port_mgr->Get(ntohs(tp->th_sport), TRANSPORT_TCP));
|
||||
tcp_hdr->Assign(1, port_mgr->Get(ntohs(tp->th_dport), TRANSPORT_TCP));
|
||||
tcp_hdr->Assign(2, new Val(uint32(ntohl(tp->th_seq)), TYPE_COUNT));
|
||||
tcp_hdr->Assign(3, new Val(uint32(ntohl(tp->th_ack)), TYPE_COUNT));
|
||||
tcp_hdr->Assign(4, new Val(tcp_hdr_len, TYPE_COUNT));
|
||||
|
@ -388,8 +388,8 @@ RecordVal* IP_Hdr::BuildPktHdrVal(RecordVal* pkt_hdr, int sindex) const
|
|||
const struct udphdr* up = (const struct udphdr*) data;
|
||||
RecordVal* udp_hdr = new RecordVal(udp_hdr_type);
|
||||
|
||||
udp_hdr->Assign(0, new PortVal(ntohs(up->uh_sport), TRANSPORT_UDP));
|
||||
udp_hdr->Assign(1, new PortVal(ntohs(up->uh_dport), TRANSPORT_UDP));
|
||||
udp_hdr->Assign(0, port_mgr->Get(ntohs(up->uh_sport), TRANSPORT_UDP));
|
||||
udp_hdr->Assign(1, port_mgr->Get(ntohs(up->uh_dport), TRANSPORT_UDP));
|
||||
udp_hdr->Assign(2, new Val(ntohs(up->uh_ulen), TYPE_COUNT));
|
||||
|
||||
pkt_hdr->Assign(sindex + 3, udp_hdr);
|
||||
|
|
|
@ -88,7 +88,7 @@ public:
|
|||
* @param s String containing an IP address as either a dotted IPv4
|
||||
* address or a hex IPv6 address.
|
||||
*/
|
||||
IPAddr(const BroString& s)
|
||||
explicit IPAddr(const BroString& s)
|
||||
{
|
||||
Init(s.CheckString());
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
class IntSet {
|
||||
public:
|
||||
// n is a hint for the value of the largest integer.
|
||||
IntSet(unsigned int n = 1);
|
||||
explicit IntSet(unsigned int n = 1);
|
||||
~IntSet();
|
||||
|
||||
void Insert(unsigned int i);
|
||||
|
|
10
src/List.h
10
src/List.h
|
@ -42,7 +42,7 @@ public:
|
|||
{ return padded_sizeof(*this) + pad_size(max_entries * sizeof(ent)); }
|
||||
|
||||
protected:
|
||||
BaseList(int = 0);
|
||||
explicit BaseList(int = 0);
|
||||
BaseList(BaseList&);
|
||||
|
||||
void insert(ent); // add at head of list
|
||||
|
@ -102,9 +102,9 @@ protected:
|
|||
#define Listdeclare(type) \
|
||||
struct List(type) : BaseList \
|
||||
{ \
|
||||
List(type)(type ...); \
|
||||
explicit List(type)(type ...); \
|
||||
List(type)() : BaseList(0) {} \
|
||||
List(type)(int sz) : BaseList(sz) {} \
|
||||
explicit List(type)(int sz) : BaseList(sz) {} \
|
||||
List(type)(List(type)& l) : BaseList((BaseList&)l) {} \
|
||||
\
|
||||
void operator=(List(type)& l) \
|
||||
|
@ -143,9 +143,9 @@ List(type)::List(type)(type e1 ...) : BaseList() \
|
|||
#define PListdeclare(type) \
|
||||
struct PList(type) : BaseList \
|
||||
{ \
|
||||
PList(type)(type* ...); \
|
||||
explicit PList(type)(type* ...); \
|
||||
PList(type)() : BaseList(0) {} \
|
||||
PList(type)(int sz) : BaseList(sz) {} \
|
||||
explicit PList(type)(int sz) : BaseList(sz) {} \
|
||||
PList(type)(PList(type)& l) : BaseList((BaseList&)l) {} \
|
||||
\
|
||||
void operator=(PList(type)& l) \
|
||||
|
|
20
src/NFA.cc
20
src/NFA.cc
|
@ -12,6 +12,7 @@ NFA_State::NFA_State(int arg_sym, EquivClass* ec)
|
|||
sym = arg_sym;
|
||||
ccl = 0;
|
||||
accept = NO_ACCEPT;
|
||||
first_trans_is_back_ref = false;
|
||||
mark = 0;
|
||||
epsclosure = 0;
|
||||
id = ++nfa_state_id;
|
||||
|
@ -33,6 +34,7 @@ NFA_State::NFA_State(CCL* arg_ccl)
|
|||
sym = SYM_CCL;
|
||||
ccl = arg_ccl;
|
||||
accept = NO_ACCEPT;
|
||||
first_trans_is_back_ref = false;
|
||||
mark = 0;
|
||||
id = ++nfa_state_id;
|
||||
epsclosure = 0;
|
||||
|
@ -41,7 +43,8 @@ NFA_State::NFA_State(CCL* arg_ccl)
|
|||
NFA_State::~NFA_State()
|
||||
{
|
||||
for ( int i = 0; i < xtions.length(); ++i )
|
||||
Unref(xtions[i]);
|
||||
if ( i > 0 || ! first_trans_is_back_ref )
|
||||
Unref(xtions[i]);
|
||||
|
||||
delete epsclosure;
|
||||
}
|
||||
|
@ -55,7 +58,10 @@ void NFA_State::AddXtionsTo(NFA_state_list* ns)
|
|||
NFA_State* NFA_State::DeepCopy()
|
||||
{
|
||||
if ( mark )
|
||||
{
|
||||
Ref(mark);
|
||||
return mark;
|
||||
}
|
||||
|
||||
NFA_State* copy = ccl ? new NFA_State(ccl) : new NFA_State(sym, 0);
|
||||
SetMark(copy);
|
||||
|
@ -244,7 +250,10 @@ void NFA_Machine::MakePositiveClosure()
|
|||
{
|
||||
AppendEpsilon();
|
||||
final_state->AddXtion(first_state);
|
||||
Ref(first_state);
|
||||
|
||||
// Don't Ref the state the final epsilon points to, otherwise we'll
|
||||
// have reference cycles that lead to leaks.
|
||||
final_state->SetFirstTransIsBackRef();
|
||||
}
|
||||
|
||||
void NFA_Machine::MakeRepl(int lower, int upper)
|
||||
|
@ -304,6 +313,13 @@ NFA_Machine* make_alternate(NFA_Machine* m1, NFA_Machine* m2)
|
|||
m2->AppendState(last);
|
||||
Ref(last);
|
||||
|
||||
// Keep these around.
|
||||
Ref(m1->FirstState());
|
||||
Ref(m2->FirstState());
|
||||
|
||||
Unref(m1);
|
||||
Unref(m2);
|
||||
|
||||
return new NFA_Machine(first, last);
|
||||
}
|
||||
|
||||
|
|
20
src/NFA.h
20
src/NFA.h
|
@ -27,8 +27,8 @@ typedef PList(NFA_State) NFA_state_list;
|
|||
class NFA_State : public BroObj {
|
||||
public:
|
||||
NFA_State(int sym, EquivClass* ec);
|
||||
NFA_State(CCL* ccl);
|
||||
~NFA_State();
|
||||
explicit NFA_State(CCL* ccl);
|
||||
~NFA_State() override;
|
||||
|
||||
void AddXtion(NFA_State* next_state) { xtions.append(next_state); }
|
||||
NFA_state_list* Transitions() { return &xtions; }
|
||||
|
@ -46,13 +46,15 @@ public:
|
|||
NFA_State* Mark() const { return mark; }
|
||||
void ClearMarks();
|
||||
|
||||
void SetFirstTransIsBackRef() { first_trans_is_back_ref = true; }
|
||||
|
||||
int TransSym() const { return sym; }
|
||||
CCL* TransCCL() const { return ccl; }
|
||||
int ID() const { return id; }
|
||||
|
||||
NFA_state_list* EpsilonClosure();
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
void Describe(ODesc* d) const override;
|
||||
void Dump(FILE* f);
|
||||
|
||||
// Recursivly count all the reachable states.
|
||||
|
@ -62,7 +64,13 @@ protected:
|
|||
int sym; // if SYM_CCL, then use ccl
|
||||
CCL* ccl; // if nil, then use sym
|
||||
int accept;
|
||||
|
||||
// Whether the first transition points backwards. Used
|
||||
// to avoid reference-counting loops.
|
||||
bool first_trans_is_back_ref;
|
||||
|
||||
int id; // number that uniquely identifies this state
|
||||
|
||||
NFA_state_list xtions;
|
||||
NFA_state_list* epsclosure;
|
||||
NFA_State* mark;
|
||||
|
@ -75,8 +83,8 @@ public:
|
|||
|
||||
class NFA_Machine : public BroObj {
|
||||
public:
|
||||
NFA_Machine(NFA_State* first, NFA_State* final = 0);
|
||||
~NFA_Machine();
|
||||
explicit NFA_Machine(NFA_State* first, NFA_State* final = 0);
|
||||
~NFA_Machine() override;
|
||||
|
||||
NFA_State* FirstState() const { return first_state; }
|
||||
|
||||
|
@ -103,7 +111,7 @@ public:
|
|||
void AppendState(NFA_State* new_state);
|
||||
void AppendMachine(NFA_Machine* new_mach);
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
void Describe(ODesc* d) const override;
|
||||
void Dump(FILE* f);
|
||||
|
||||
unsigned int MemoryAllocation() const
|
||||
|
|
31
src/Net.cc
31
src/Net.cc
|
@ -33,10 +33,7 @@
|
|||
#include "iosource/PktSrc.h"
|
||||
#include "iosource/PktDumper.h"
|
||||
#include "plugin/Manager.h"
|
||||
|
||||
#ifdef ENABLE_BROKER
|
||||
#include "broker/Manager.h"
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
#include "setsignal.h"
|
||||
|
@ -61,6 +58,7 @@ double bro_start_time = 0.0; // time Bro started.
|
|||
double bro_start_network_time; // timestamp of first packet
|
||||
double last_watchdog_proc_time = 0.0; // value of above during last watchdog
|
||||
bool terminating = false; // whether we're done reading and finishing up
|
||||
bool is_parsing = false;
|
||||
|
||||
const Packet *current_pkt = 0;
|
||||
int current_dispatched = 0;
|
||||
|
@ -311,11 +309,7 @@ void net_run()
|
|||
}
|
||||
#endif
|
||||
current_iosrc = src;
|
||||
bool communication_enabled = using_communication;
|
||||
|
||||
#ifdef ENABLE_BROKER
|
||||
communication_enabled |= broker_mgr->Enabled();
|
||||
#endif
|
||||
auto communication_enabled = using_communication || broker_mgr->Active();
|
||||
|
||||
if ( src )
|
||||
src->Process(); // which will call net_packet_dispatch()
|
||||
|
@ -333,7 +327,8 @@ void net_run()
|
|||
}
|
||||
}
|
||||
|
||||
else if ( (have_pending_timers || communication_enabled) &&
|
||||
else if ( (have_pending_timers || communication_enabled ||
|
||||
BifConst::exit_only_after_terminate) &&
|
||||
! pseudo_realtime )
|
||||
{
|
||||
// Take advantage of the lull to get up to
|
||||
|
@ -386,6 +381,24 @@ void net_run()
|
|||
// Check whether we have timers scheduled for
|
||||
// the future on which we need to wait.
|
||||
have_pending_timers = timer_mgr->Size() > 0;
|
||||
|
||||
if ( pseudo_realtime && communication_enabled )
|
||||
{
|
||||
auto have_active_packet_source = false;
|
||||
|
||||
for ( auto& ps : iosource_mgr->GetPktSrcs() )
|
||||
{
|
||||
if ( ps->IsOpen() )
|
||||
{
|
||||
have_active_packet_source = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! have_active_packet_source )
|
||||
// Can turn off pseudo realtime now
|
||||
pseudo_realtime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the final statistics now, and not when net_finish() is
|
||||
|
|
|
@ -70,6 +70,9 @@ extern bool terminating;
|
|||
// True if the remote serializer is to be activated.
|
||||
extern bool using_communication;
|
||||
|
||||
// True if Bro is currently parsing scripts.
|
||||
extern bool is_parsing;
|
||||
|
||||
extern const Packet* current_pkt;
|
||||
extern int current_dispatched;
|
||||
extern double current_timestamp;
|
||||
|
@ -80,6 +83,8 @@ extern iosource::PktDumper* pkt_dumper; // where to save packets
|
|||
|
||||
extern char* writefile;
|
||||
|
||||
extern int old_comm_usage_count;
|
||||
|
||||
// Script file we have already scanned (or are in the process of scanning).
|
||||
// They are identified by inode number.
|
||||
struct ScannedFile {
|
||||
|
|
|
@ -110,9 +110,6 @@ RecordType* geo_location;
|
|||
|
||||
RecordType* entropy_test_result;
|
||||
|
||||
TableType* dhcp_router_list;
|
||||
RecordType* dhcp_msg;
|
||||
|
||||
RecordType* dns_msg;
|
||||
RecordType* dns_answer;
|
||||
RecordType* dns_soa;
|
||||
|
@ -426,9 +423,6 @@ void init_net_var()
|
|||
|
||||
entropy_test_result = internal_type("entropy_test_result")->AsRecordType();
|
||||
|
||||
dhcp_router_list = internal_type("dhcp_router_list")->AsTableType();
|
||||
dhcp_msg = internal_type("dhcp_msg")->AsRecordType();
|
||||
|
||||
dns_msg = internal_type("dns_msg")->AsRecordType();
|
||||
dns_answer = internal_type("dns_answer")->AsRecordType();
|
||||
dns_soa = internal_type("dns_soa")->AsRecordType();
|
||||
|
|
|
@ -113,9 +113,6 @@ extern RecordType* geo_location;
|
|||
|
||||
extern RecordType* entropy_test_result;
|
||||
|
||||
extern TableType* dhcp_router_list;
|
||||
extern RecordType* dhcp_msg;
|
||||
|
||||
extern RecordType* dns_msg;
|
||||
extern RecordType* dns_answer;
|
||||
extern RecordType* dns_soa;
|
||||
|
|
|
@ -81,7 +81,7 @@ enum FingerprintMode {
|
|||
|
||||
class OSFingerprint {
|
||||
public:
|
||||
OSFingerprint(FingerprintMode mode);
|
||||
explicit OSFingerprint(FingerprintMode mode);
|
||||
~OSFingerprint() {}
|
||||
|
||||
bool Error() const { return err; }
|
||||
|
@ -90,13 +90,6 @@ public:
|
|||
uint8 TTL, uint16 WSS, uint8 ocnt, uint8* op, uint16 MSS,
|
||||
uint8 win_scale, uint32 tstamp, uint32 quirks, uint8 ECN) const;
|
||||
bool CacheMatch(const IPAddr& addr, int id);
|
||||
|
||||
int Get_OS_From_SYN(struct os_type* retval,
|
||||
uint16 tot, uint8 DF_flag, uint8 TTL, uint16 WSS,
|
||||
uint8 ocnt, uint8* op, uint16 MSS, uint8 win_scale,
|
||||
uint32 tstamp, /* uint8 TOS, */ uint32 quirks,
|
||||
uint8 ecn) const;
|
||||
|
||||
void load_config(const char* file);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
text = 0;
|
||||
}
|
||||
|
||||
virtual ~Location()
|
||||
~Location() override
|
||||
{
|
||||
if ( delete_data )
|
||||
delete [] filename;
|
||||
|
@ -112,7 +112,7 @@ public:
|
|||
SetLocationInfo(&start_location, &end_location);
|
||||
}
|
||||
|
||||
virtual ~BroObj();
|
||||
~BroObj() override;
|
||||
|
||||
// Report user warnings/errors. If obj2 is given, then it's
|
||||
// included in the message, though if pinpoint_only is non-zero,
|
||||
|
|
|
@ -23,7 +23,8 @@ public:
|
|||
|
||||
protected:
|
||||
HashVal() { };
|
||||
HashVal(OpaqueType* t);
|
||||
explicit HashVal(OpaqueType* t);
|
||||
|
||||
virtual bool DoInit();
|
||||
virtual bool DoFeed(const void* data, size_t size);
|
||||
virtual StringVal* DoGet();
|
||||
|
@ -48,9 +49,9 @@ public:
|
|||
protected:
|
||||
friend class Val;
|
||||
|
||||
virtual bool DoInit() override;
|
||||
virtual bool DoFeed(const void* data, size_t size) override;
|
||||
virtual StringVal* DoGet() override;
|
||||
bool DoInit() override;
|
||||
bool DoFeed(const void* data, size_t size) override;
|
||||
StringVal* DoGet() override;
|
||||
|
||||
DECLARE_SERIAL(MD5Val);
|
||||
|
||||
|
@ -67,9 +68,9 @@ public:
|
|||
protected:
|
||||
friend class Val;
|
||||
|
||||
virtual bool DoInit() override;
|
||||
virtual bool DoFeed(const void* data, size_t size) override;
|
||||
virtual StringVal* DoGet() override;
|
||||
bool DoInit() override;
|
||||
bool DoFeed(const void* data, size_t size) override;
|
||||
StringVal* DoGet() override;
|
||||
|
||||
DECLARE_SERIAL(SHA1Val);
|
||||
|
||||
|
@ -86,9 +87,9 @@ public:
|
|||
protected:
|
||||
friend class Val;
|
||||
|
||||
virtual bool DoInit() override;
|
||||
virtual bool DoFeed(const void* data, size_t size) override;
|
||||
virtual StringVal* DoGet() override;
|
||||
bool DoInit() override;
|
||||
bool DoFeed(const void* data, size_t size) override;
|
||||
StringVal* DoGet() override;
|
||||
|
||||
DECLARE_SERIAL(SHA256Val);
|
||||
|
||||
|
@ -106,7 +107,6 @@ public:
|
|||
|
||||
protected:
|
||||
friend class Val;
|
||||
EntropyVal(OpaqueType* t);
|
||||
|
||||
DECLARE_SERIAL(EntropyVal);
|
||||
|
||||
|
@ -117,7 +117,7 @@ private:
|
|||
class BloomFilterVal : public OpaqueVal {
|
||||
public:
|
||||
explicit BloomFilterVal(probabilistic::BloomFilter* bf);
|
||||
virtual ~BloomFilterVal();
|
||||
~BloomFilterVal() override;
|
||||
|
||||
BroType* Type() const;
|
||||
bool Typify(BroType* type);
|
||||
|
@ -134,7 +134,7 @@ public:
|
|||
protected:
|
||||
friend class Val;
|
||||
BloomFilterVal();
|
||||
BloomFilterVal(OpaqueType* t);
|
||||
explicit BloomFilterVal(OpaqueType* t);
|
||||
|
||||
DECLARE_SERIAL(BloomFilterVal);
|
||||
|
||||
|
@ -152,7 +152,7 @@ private:
|
|||
class CardinalityVal: public OpaqueVal {
|
||||
public:
|
||||
explicit CardinalityVal(probabilistic::CardinalityCounter*);
|
||||
virtual ~CardinalityVal();
|
||||
~CardinalityVal() override;
|
||||
|
||||
void Add(const Val* val);
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ using namespace std;
|
|||
|
||||
class PacketDumper {
|
||||
public:
|
||||
PacketDumper(pcap_dumper_t* pkt_dump);
|
||||
explicit PacketDumper(pcap_dumper_t* pkt_dump);
|
||||
|
||||
void DumpPacket(const struct pcap_pkthdr* hdr,
|
||||
const u_char* pkt, int len);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
class PacketFilter {
|
||||
public:
|
||||
PacketFilter(bool arg_default) { default_match = arg_default; }
|
||||
explicit PacketFilter(bool arg_default) { default_match = arg_default; }
|
||||
~PacketFilter() {}
|
||||
|
||||
// Drops all packets from a particular source (which may be given
|
||||
|
|
|
@ -191,7 +191,7 @@ void PersistenceSerializer::RaiseFinishedSendState()
|
|||
{
|
||||
val_list* vl = new val_list;
|
||||
vl->append(new AddrVal(htonl(remote_host)));
|
||||
vl->append(new PortVal(remote_port));
|
||||
vl->append(port_mgr->Get(remote_port));
|
||||
|
||||
mgr.QueueEvent(finished_send_state, vl);
|
||||
reporter->Log("Serialization done.");
|
||||
|
|
|
@ -11,7 +11,8 @@ class StateAccess;
|
|||
class PersistenceSerializer : public FileSerializer {
|
||||
public:
|
||||
PersistenceSerializer();
|
||||
virtual ~PersistenceSerializer();
|
||||
|
||||
~PersistenceSerializer() override;
|
||||
|
||||
// Define the directory where to store the data.
|
||||
void SetDir(const char* arg_dir) { dir = copy_string(arg_dir); }
|
||||
|
@ -59,15 +60,15 @@ protected:
|
|||
friend class RemoteSerializer;
|
||||
friend class IncrementalWriteTimer;
|
||||
|
||||
virtual void GotID(ID* id, Val* val);
|
||||
virtual void GotEvent(const char* name, double time,
|
||||
EventHandlerPtr event, val_list* args);
|
||||
virtual void GotFunctionCall(const char* name, double time,
|
||||
Func* func, val_list* args) ;
|
||||
virtual void GotStateAccess(StateAccess* s);
|
||||
virtual void GotTimer(Timer* t);
|
||||
virtual void GotConnection(Connection* c);
|
||||
virtual void GotPacket(Packet* packet);
|
||||
void GotID(ID* id, Val* val) override;
|
||||
void GotEvent(const char* name, double time,
|
||||
EventHandlerPtr event, val_list* args) override;
|
||||
void GotFunctionCall(const char* name, double time,
|
||||
Func* func, val_list* args) override;
|
||||
void GotStateAccess(StateAccess* s) override;
|
||||
void GotTimer(Timer* t) override;
|
||||
void GotConnection(Connection* c) override;
|
||||
void GotPacket(Packet* packet) override;
|
||||
|
||||
// If file has changed since last check, read it.
|
||||
bool CheckForFile(UnserialInfo* info, const char* file,
|
||||
|
|
|
@ -12,7 +12,7 @@ using namespace bro;
|
|||
static void pipe_fail(int eno)
|
||||
{
|
||||
char tmp[256];
|
||||
strerror_r(eno, tmp, sizeof(tmp));
|
||||
bro_strerror_r(eno, tmp, sizeof(tmp));
|
||||
reporter->FatalError("Pipe failure: %s", tmp);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ public:
|
|||
* @param status_flags0 descriptor status flags to set on read end of pipe.
|
||||
* @param status_flags1 descriptor status flags to set on write end of pipe.
|
||||
*/
|
||||
Pipe(int flags0 = 0, int flags1 = 0, int status_flags0 = 0,
|
||||
explicit Pipe(int flags0 = 0, int flags1 = 0, int status_flags0 = 0,
|
||||
int status_flags1 = 0);
|
||||
|
||||
/**
|
||||
|
|
|
@ -84,7 +84,7 @@ bool LoadPolicyFileText(const char* policy_filename)
|
|||
if ( fstat(fileno(f), &st) != 0 )
|
||||
{
|
||||
char buf[256];
|
||||
strerror_r(errno, buf, sizeof(buf));
|
||||
bro_strerror_r(errno, buf, sizeof(buf));
|
||||
reporter->Error("fstat failed on %s: %s", policy_filename, buf);
|
||||
fclose(f);
|
||||
return false;
|
||||
|
|
|
@ -10,7 +10,7 @@ class PriorityQueue;
|
|||
|
||||
class PQ_Element {
|
||||
public:
|
||||
PQ_Element(double t) { time = t; offset = -1; }
|
||||
explicit PQ_Element(double t) { time = t; offset = -1; }
|
||||
virtual ~PQ_Element() { }
|
||||
|
||||
double Time() const { return time; }
|
||||
|
@ -28,7 +28,7 @@ protected:
|
|||
|
||||
class PriorityQueue {
|
||||
public:
|
||||
PriorityQueue(int initial_size = 16);
|
||||
explicit PriorityQueue(int initial_size = 16);
|
||||
~PriorityQueue();
|
||||
|
||||
// Returns the top of queue, or nil if the queue is empty.
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
void incr(int& index) { index < max_entries ? ++index : index = 0; }
|
||||
|
||||
protected:
|
||||
BaseQueue(int = 0);
|
||||
explicit BaseQueue(int = 0);
|
||||
|
||||
void push_front(ent); // add in front of queue
|
||||
void push_back(ent); // add at end of queue
|
||||
|
@ -73,7 +73,7 @@ protected:
|
|||
struct Queue(type) : BaseQueue \
|
||||
{ \
|
||||
Queue(type)() : BaseQueue(0) {} \
|
||||
Queue(type)(int sz) : BaseQueue(sz) {} \
|
||||
explicit Queue(type)(int sz) : BaseQueue(sz) {} \
|
||||
\
|
||||
void push_front(type a) { BaseQueue::push_front(ent(a)); } \
|
||||
void push_back(type a) { BaseQueue::push_back(ent(a)); } \
|
||||
|
@ -88,7 +88,7 @@ struct Queue(type) : BaseQueue \
|
|||
struct PQueue(type) : BaseQueue \
|
||||
{ \
|
||||
PQueue(type)() : BaseQueue(0) {} \
|
||||
PQueue(type)(int sz) : BaseQueue(sz) {} \
|
||||
explicit PQueue(type)(int sz) : BaseQueue(sz) {} \
|
||||
\
|
||||
void push_front(type* a){ BaseQueue::push_front(ent(a)); } \
|
||||
void push_back(type* a) { BaseQueue::push_back(ent(a)); } \
|
||||
|
|
48
src/RE.cc
48
src/RE.cc
|
@ -19,6 +19,7 @@ int case_insensitive = 0;
|
|||
|
||||
extern int RE_parse(void);
|
||||
extern void RE_set_input(const char* str);
|
||||
extern void RE_done_with_scan();
|
||||
|
||||
Specific_RE_Matcher::Specific_RE_Matcher(match_type arg_mt, int arg_multiline)
|
||||
: equiv_class(NUM_SYM)
|
||||
|
@ -101,6 +102,19 @@ void Specific_RE_Matcher::AddPat(const char* new_pat,
|
|||
pattern_text = s;
|
||||
}
|
||||
|
||||
void Specific_RE_Matcher::MakeCaseInsensitive()
|
||||
{
|
||||
const char fmt[] = "(?i:%s)";
|
||||
int n = strlen(pattern_text) + strlen(fmt);
|
||||
|
||||
char* s = new char[n + 5 /* slop */];
|
||||
|
||||
safe_snprintf(s, n + 5, fmt, pattern_text);
|
||||
|
||||
delete [] pattern_text;
|
||||
pattern_text = s;
|
||||
}
|
||||
|
||||
int Specific_RE_Matcher::Compile(int lazy)
|
||||
{
|
||||
if ( ! pattern_text )
|
||||
|
@ -108,9 +122,15 @@ int Specific_RE_Matcher::Compile(int lazy)
|
|||
|
||||
rem = this;
|
||||
RE_set_input(pattern_text);
|
||||
if ( RE_parse() )
|
||||
|
||||
int parse_status = RE_parse();
|
||||
RE_done_with_scan();
|
||||
|
||||
if ( parse_status )
|
||||
{
|
||||
reporter->Error("error compiling pattern /%s/", pattern_text);
|
||||
Unref(nfa);
|
||||
nfa = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -139,9 +159,19 @@ int Specific_RE_Matcher::CompileSet(const string_list& set, const int_list& idx)
|
|||
loop_over_list(set, i)
|
||||
{
|
||||
RE_set_input(set[i]);
|
||||
if ( RE_parse() )
|
||||
int parse_status = RE_parse();
|
||||
RE_done_with_scan();
|
||||
|
||||
if ( parse_status )
|
||||
{
|
||||
reporter->Error("error compiling pattern /%s/", set[i]);
|
||||
|
||||
if ( set_nfa && set_nfa != nfa )
|
||||
Unref(set_nfa);
|
||||
else
|
||||
Unref(nfa);
|
||||
|
||||
nfa = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -408,6 +438,14 @@ RE_Matcher::RE_Matcher(const char* pat)
|
|||
AddPat(pat);
|
||||
}
|
||||
|
||||
RE_Matcher::RE_Matcher(const char* exact_pat, const char* anywhere_pat)
|
||||
{
|
||||
re_anywhere = new Specific_RE_Matcher(MATCH_ANYWHERE);
|
||||
re_anywhere->SetPat(anywhere_pat);
|
||||
re_exact = new Specific_RE_Matcher(MATCH_EXACTLY);
|
||||
re_exact->SetPat(exact_pat);
|
||||
}
|
||||
|
||||
RE_Matcher::~RE_Matcher()
|
||||
{
|
||||
delete re_anywhere;
|
||||
|
@ -420,6 +458,12 @@ void RE_Matcher::AddPat(const char* new_pat)
|
|||
re_exact->AddPat(new_pat);
|
||||
}
|
||||
|
||||
void RE_Matcher::MakeCaseInsensitive()
|
||||
{
|
||||
re_anywhere->MakeCaseInsensitive();
|
||||
re_exact->MakeCaseInsensitive();
|
||||
}
|
||||
|
||||
int RE_Matcher::Compile(int lazy)
|
||||
{
|
||||
return re_anywhere->Compile(lazy) && re_exact->Compile(lazy);
|
||||
|
|
15
src/RE.h
15
src/RE.h
|
@ -49,11 +49,13 @@ typedef enum { MATCH_ANYWHERE, MATCH_EXACTLY, } match_type;
|
|||
|
||||
class Specific_RE_Matcher {
|
||||
public:
|
||||
Specific_RE_Matcher(match_type mt, int multiline=0);
|
||||
explicit Specific_RE_Matcher(match_type mt, int multiline=0);
|
||||
~Specific_RE_Matcher();
|
||||
|
||||
void AddPat(const char* pat);
|
||||
|
||||
void MakeCaseInsensitive();
|
||||
|
||||
void SetPat(const char* pat) { pattern_text = copy_string(pat); }
|
||||
|
||||
int Compile(int lazy = 0);
|
||||
|
@ -133,7 +135,7 @@ protected:
|
|||
|
||||
class RE_Match_State {
|
||||
public:
|
||||
RE_Match_State(Specific_RE_Matcher* matcher)
|
||||
explicit RE_Match_State(Specific_RE_Matcher* matcher)
|
||||
{
|
||||
dfa = matcher->DFA() ? matcher->DFA() : 0;
|
||||
ecs = matcher->EC()->EquivClasses();
|
||||
|
@ -172,12 +174,15 @@ protected:
|
|||
class RE_Matcher : SerialObj {
|
||||
public:
|
||||
RE_Matcher();
|
||||
RE_Matcher(const char* pat);
|
||||
virtual ~RE_Matcher();
|
||||
explicit RE_Matcher(const char* pat);
|
||||
RE_Matcher(const char* exact_pat, const char* anywhere_pat);
|
||||
virtual ~RE_Matcher() override;
|
||||
|
||||
void AddDef(const char* defn_name, const char* defn_val);
|
||||
void AddPat(const char* pat);
|
||||
|
||||
// Makes the matcher as specified to date case-insensitive.
|
||||
void MakeCaseInsensitive();
|
||||
|
||||
int Compile(int lazy = 0);
|
||||
|
||||
// Returns true if s exactly matches the pattern, false otherwise.
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
static const bool DEBUG_reassem = false;
|
||||
|
||||
DataBlock::DataBlock(const u_char* data, uint64 size, uint64 arg_seq,
|
||||
DataBlock* arg_prev, DataBlock* arg_next,
|
||||
ReassemblerType reassem_type)
|
||||
DataBlock::DataBlock(Reassembler* reass, const u_char* data,
|
||||
uint64 size, uint64 arg_seq, DataBlock* arg_prev,
|
||||
DataBlock* arg_next, ReassemblerType reassem_type)
|
||||
{
|
||||
seq = arg_seq;
|
||||
upper = seq + size;
|
||||
|
@ -28,6 +28,9 @@ DataBlock::DataBlock(const u_char* data, uint64 size, uint64 arg_seq,
|
|||
if ( next )
|
||||
next->prev = this;
|
||||
|
||||
reassembler = reass;
|
||||
reassembler->size_of_all_blocks += size;
|
||||
|
||||
rtype = reassem_type;
|
||||
Reassembler::sizes[rtype] += pad_size(size) + padded_sizeof(DataBlock);
|
||||
Reassembler::total_size += pad_size(size) + padded_sizeof(DataBlock);
|
||||
|
@ -37,12 +40,11 @@ uint64 Reassembler::total_size = 0;
|
|||
uint64 Reassembler::sizes[REASSEM_NUM];
|
||||
|
||||
Reassembler::Reassembler(uint64 init_seq, ReassemblerType reassem_type)
|
||||
: blocks(), last_block(), old_blocks(), last_old_block(),
|
||||
last_reassem_seq(init_seq), trim_seq(init_seq),
|
||||
max_old_blocks(0), total_old_blocks(0), size_of_all_blocks(0),
|
||||
rtype(reassem_type)
|
||||
{
|
||||
blocks = last_block = 0;
|
||||
old_blocks = last_old_block = 0;
|
||||
total_old_blocks = max_old_blocks = 0;
|
||||
trim_seq = last_reassem_seq = init_seq;
|
||||
rtype = reassem_type;
|
||||
}
|
||||
|
||||
Reassembler::~Reassembler()
|
||||
|
@ -57,6 +59,10 @@ void Reassembler::CheckOverlap(DataBlock *head, DataBlock *tail,
|
|||
if ( ! head || ! tail )
|
||||
return;
|
||||
|
||||
if ( seq == tail->upper )
|
||||
// Special case check for common case of appending to the end.
|
||||
return;
|
||||
|
||||
uint64 upper = (seq + len);
|
||||
|
||||
for ( DataBlock* b = head; b; b = b->next )
|
||||
|
@ -116,7 +122,7 @@ void Reassembler::NewBlock(double t, uint64 seq, uint64 len, const u_char* data)
|
|||
|
||||
if ( ! blocks )
|
||||
blocks = last_block = start_block =
|
||||
new DataBlock(data, len, seq, 0, 0, rtype);
|
||||
new DataBlock(this, data, len, seq, 0, 0, rtype);
|
||||
else
|
||||
start_block = AddAndCheck(blocks, seq, upper_seq, data);
|
||||
|
||||
|
@ -249,12 +255,7 @@ void Reassembler::ClearOldBlocks()
|
|||
|
||||
uint64 Reassembler::TotalSize() const
|
||||
{
|
||||
uint64 size = 0;
|
||||
|
||||
for ( DataBlock* b = blocks; b; b = b->next )
|
||||
size += b->Size();
|
||||
|
||||
return size;
|
||||
return size_of_all_blocks;
|
||||
}
|
||||
|
||||
void Reassembler::Describe(ODesc* d) const
|
||||
|
@ -280,8 +281,8 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper,
|
|||
// Special check for the common case of appending to the end.
|
||||
if ( last_block && seq == last_block->upper )
|
||||
{
|
||||
last_block = new DataBlock(data, upper - seq, seq,
|
||||
last_block, 0, rtype);
|
||||
last_block = new DataBlock(this, data, upper - seq,
|
||||
seq, last_block, 0, rtype);
|
||||
return last_block;
|
||||
}
|
||||
|
||||
|
@ -294,7 +295,8 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper,
|
|||
{
|
||||
// b is the last block, and it comes completely before
|
||||
// the new block.
|
||||
last_block = new DataBlock(data, upper - seq, seq, b, 0, rtype);
|
||||
last_block = new DataBlock(this, data, upper - seq,
|
||||
seq, b, 0, rtype);
|
||||
return last_block;
|
||||
}
|
||||
|
||||
|
@ -303,7 +305,8 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper,
|
|||
if ( upper <= b->seq )
|
||||
{
|
||||
// The new block comes completely before b.
|
||||
new_b = new DataBlock(data, upper - seq, seq, b->prev, b, rtype);
|
||||
new_b = new DataBlock(this, data, upper - seq, seq,
|
||||
b->prev, b, rtype);
|
||||
if ( b == blocks )
|
||||
blocks = new_b;
|
||||
return new_b;
|
||||
|
@ -314,7 +317,8 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper,
|
|||
{
|
||||
// The new block has a prefix that comes before b.
|
||||
uint64 prefix_len = b->seq - seq;
|
||||
new_b = new DataBlock(data, prefix_len, seq, b->prev, b, rtype);
|
||||
new_b = new DataBlock(this, data, prefix_len, seq,
|
||||
b->prev, b, rtype);
|
||||
if ( b == blocks )
|
||||
blocks = new_b;
|
||||
|
||||
|
|
|
@ -18,11 +18,14 @@ enum ReassemblerType {
|
|||
REASSEM_NUM,
|
||||
};
|
||||
|
||||
class Reassembler;
|
||||
|
||||
class DataBlock {
|
||||
public:
|
||||
DataBlock(const u_char* data, uint64 size, uint64 seq,
|
||||
DataBlock* prev, DataBlock* next,
|
||||
ReassemblerType reassem_type = REASSEM_UNKNOWN);
|
||||
DataBlock(Reassembler* reass, const u_char* data,
|
||||
uint64 size, uint64 seq,
|
||||
DataBlock* prev, DataBlock* next,
|
||||
ReassemblerType reassem_type = REASSEM_UNKNOWN);
|
||||
|
||||
~DataBlock();
|
||||
|
||||
|
@ -33,12 +36,14 @@ public:
|
|||
uint64 seq, upper;
|
||||
u_char* block;
|
||||
ReassemblerType rtype;
|
||||
|
||||
Reassembler* reassembler; // Non-owning pointer back to parent.
|
||||
};
|
||||
|
||||
class Reassembler : public BroObj {
|
||||
public:
|
||||
Reassembler(uint64 init_seq, ReassemblerType reassem_type = REASSEM_UNKNOWN);
|
||||
virtual ~Reassembler();
|
||||
~Reassembler() override;
|
||||
|
||||
void NewBlock(double t, uint64 seq, uint64 len, const u_char* data);
|
||||
|
||||
|
@ -55,7 +60,7 @@ public:
|
|||
|
||||
uint64 TotalSize() const; // number of bytes buffered up
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
void Describe(ODesc* d) const override;
|
||||
|
||||
bool Serialize(SerialInfo* info) const;
|
||||
static Reassembler* Unserialize(UnserialInfo* info);
|
||||
|
@ -96,6 +101,7 @@ protected:
|
|||
uint64 trim_seq; // how far we've trimmed
|
||||
uint32 max_old_blocks;
|
||||
uint32 total_old_blocks;
|
||||
uint64 size_of_all_blocks;
|
||||
|
||||
ReassemblerType rtype;
|
||||
|
||||
|
@ -105,6 +111,7 @@ protected:
|
|||
|
||||
inline DataBlock::~DataBlock()
|
||||
{
|
||||
reassembler->size_of_all_blocks -= Size();
|
||||
Reassembler::total_size -= pad_size(upper - seq) + padded_sizeof(DataBlock);
|
||||
Reassembler::sizes[rtype] -= pad_size(upper - seq) + padded_sizeof(DataBlock);
|
||||
delete [] block;
|
||||
|
|
|
@ -255,7 +255,7 @@ struct ping_args {
|
|||
# define DEBUG_COMM(msg)
|
||||
#endif
|
||||
|
||||
#define READ_CHUNK(i, c, do_if_eof) \
|
||||
#define READ_CHUNK(i, c, do_if_eof, kill_me) \
|
||||
{ \
|
||||
if ( ! i->Read(&c) ) \
|
||||
{ \
|
||||
|
@ -264,7 +264,7 @@ struct ping_args {
|
|||
do_if_eof; \
|
||||
} \
|
||||
else \
|
||||
Error(fmt("can't read data chunk: %s", io->Error()), i == io); \
|
||||
Error(fmt("can't read data chunk: %s", io->Error()), kill_me); \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
|
@ -1809,7 +1809,7 @@ RecordVal* RemoteSerializer::MakePeerVal(Peer* peer)
|
|||
v->Assign(0, new Val(uint32(peer->id), TYPE_COUNT));
|
||||
// Sic! Network order for AddrVal, host order for PortVal.
|
||||
v->Assign(1, new AddrVal(peer->ip));
|
||||
v->Assign(2, new PortVal(peer->port, TRANSPORT_TCP));
|
||||
v->Assign(2, port_mgr->Get(peer->port, TRANSPORT_TCP));
|
||||
v->Assign(3, new Val(false, TYPE_BOOL));
|
||||
v->Assign(4, new StringVal("")); // set when received
|
||||
v->Assign(5, peer->peer_class.size() ?
|
||||
|
@ -2730,10 +2730,10 @@ bool RemoteSerializer::ProcessLogCreateWriter()
|
|||
id_val = new EnumVal(id, internal_type("Log::ID")->AsEnumType());
|
||||
writer_val = new EnumVal(writer, internal_type("Log::Writer")->AsEnumType());
|
||||
|
||||
if ( ! log_mgr->CreateWriter(id_val, writer_val, info, num_fields, fields,
|
||||
true, false, true) )
|
||||
if ( ! log_mgr->CreateWriterForRemoteLog(id_val, writer_val, info, num_fields, fields) )
|
||||
{
|
||||
delete_fields_up_to = num_fields;
|
||||
info = 0;
|
||||
fields = 0;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -2803,7 +2803,7 @@ bool RemoteSerializer::ProcessLogWrite()
|
|||
id_val = new EnumVal(id, internal_type("Log::ID")->AsEnumType());
|
||||
writer_val = new EnumVal(writer, internal_type("Log::Writer")->AsEnumType());
|
||||
|
||||
success = log_mgr->Write(id_val, writer_val, path, num_fields, vals);
|
||||
success = log_mgr->WriteFromRemote(id_val, writer_val, path, num_fields, vals);
|
||||
|
||||
Unref(id_val);
|
||||
Unref(writer_val);
|
||||
|
@ -3586,7 +3586,7 @@ bool SocketComm::ProcessParentMessage()
|
|||
{
|
||||
// Argument chunk follows.
|
||||
ChunkedIO::Chunk* c = 0;
|
||||
READ_CHUNK(io, c, Error("parent died", true));
|
||||
READ_CHUNK(io, c, Error("parent died", true), true);
|
||||
parent_args = c;
|
||||
parent_msgstate = TYPE;
|
||||
bool result = DoParentMessage();
|
||||
|
@ -3872,7 +3872,7 @@ bool SocketComm::ProcessRemoteMessage(SocketComm::Peer* peer)
|
|||
{ // CMsg follows
|
||||
ChunkedIO::Chunk* c;
|
||||
READ_CHUNK(peer->io, c,
|
||||
(CloseConnection(peer, true), peer))
|
||||
(CloseConnection(peer, true), peer), false)
|
||||
|
||||
CMsg* msg = (CMsg*) c->data;
|
||||
|
||||
|
@ -3907,7 +3907,7 @@ bool SocketComm::ProcessRemoteMessage(SocketComm::Peer* peer)
|
|||
// forward to our parent.
|
||||
ChunkedIO::Chunk* c;
|
||||
READ_CHUNK(peer->io, c,
|
||||
(CloseConnection(peer, true), peer))
|
||||
(CloseConnection(peer, true), peer), false)
|
||||
|
||||
// Set time3.
|
||||
ping_args* args = (ping_args*) c->data;
|
||||
|
@ -3921,7 +3921,7 @@ bool SocketComm::ProcessRemoteMessage(SocketComm::Peer* peer)
|
|||
// forward to our parent.
|
||||
ChunkedIO::Chunk* c;
|
||||
READ_CHUNK(peer->io, c,
|
||||
(CloseConnection(peer, true), peer))
|
||||
(CloseConnection(peer, true), peer), false)
|
||||
|
||||
// Calculate time delta.
|
||||
ping_args* args = (ping_args*) c->data;
|
||||
|
@ -3944,7 +3944,7 @@ bool SocketComm::ProcessRemoteMessage(SocketComm::Peer* peer)
|
|||
// forward to our parent.
|
||||
ChunkedIO::Chunk* c;
|
||||
READ_CHUNK(peer->io, c,
|
||||
(CloseConnection(peer, true), peer))
|
||||
(CloseConnection(peer, true), peer), false)
|
||||
|
||||
return ForwardChunkToParent(peer, c);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace threading {
|
|||
class RemoteSerializer : public Serializer, public iosource::IOSource {
|
||||
public:
|
||||
RemoteSerializer();
|
||||
virtual ~RemoteSerializer();
|
||||
~RemoteSerializer() override;
|
||||
|
||||
// Initialize the remote serializer (calling this will fork).
|
||||
void Enable();
|
||||
|
@ -140,12 +140,12 @@ public:
|
|||
void Finish();
|
||||
|
||||
// Overidden from IOSource:
|
||||
virtual void GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
|
||||
iosource::FD_Set* except);
|
||||
virtual double NextTimestamp(double* local_network_time);
|
||||
virtual void Process();
|
||||
virtual TimerMgr::Tag* GetCurrentTag();
|
||||
virtual const char* Tag() { return "RemoteSerializer"; }
|
||||
void GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
|
||||
iosource::FD_Set* except) override;
|
||||
double NextTimestamp(double* local_network_time) override;
|
||||
void Process() override;
|
||||
TimerMgr::Tag* GetCurrentTag() override;
|
||||
const char* Tag() override { return "RemoteSerializer"; }
|
||||
|
||||
// Gracefully finishes communication by first making sure that all
|
||||
// remaining data (parent & child) has been sent out.
|
||||
|
@ -246,17 +246,17 @@ protected:
|
|||
|
||||
static void Log(LogLevel level, const char* msg, Peer* peer, LogSrc src = LogParent);
|
||||
|
||||
virtual void ReportError(const char* msg);
|
||||
void ReportError(const char* msg) override;
|
||||
|
||||
virtual void GotEvent(const char* name, double time,
|
||||
EventHandlerPtr event, val_list* args);
|
||||
virtual void GotFunctionCall(const char* name, double time,
|
||||
Func* func, val_list* args);
|
||||
virtual void GotID(ID* id, Val* val);
|
||||
virtual void GotStateAccess(StateAccess* s);
|
||||
virtual void GotTimer(Timer* t);
|
||||
virtual void GotConnection(Connection* c);
|
||||
virtual void GotPacket(Packet* packet);
|
||||
void GotEvent(const char* name, double time,
|
||||
EventHandlerPtr event, val_list* args) override;
|
||||
void GotFunctionCall(const char* name, double time,
|
||||
Func* func, val_list* args) override;
|
||||
void GotID(ID* id, Val* val) override;
|
||||
void GotStateAccess(StateAccess* s) override;
|
||||
void GotTimer(Timer* t) override;
|
||||
void GotConnection(Connection* c) override;
|
||||
void GotPacket(Packet* packet) override;
|
||||
|
||||
void Fork();
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "NetVar.h"
|
||||
#include "Net.h"
|
||||
#include "Conn.h"
|
||||
#include "plugin/Plugin.h"
|
||||
#include "plugin/Manager.h"
|
||||
|
||||
#ifdef SYSLOG_INT
|
||||
extern "C" {
|
||||
|
@ -323,7 +325,24 @@ void Reporter::DoLog(const char* prefix, EventHandlerPtr event, FILE* out,
|
|||
// buffer size above.
|
||||
safe_snprintf(buffer + strlen(buffer), size - strlen(buffer), " [%s]", postfix);
|
||||
|
||||
if ( event && via_events && ! in_error_handler )
|
||||
bool raise_event = true;
|
||||
|
||||
if ( via_events && ! in_error_handler )
|
||||
{
|
||||
if ( locations.size() )
|
||||
{
|
||||
auto locs = locations.back();
|
||||
raise_event = PLUGIN_HOOK_WITH_RESULT(HOOK_REPORTER,
|
||||
HookReporter(prefix, event, conn, addl, location,
|
||||
locs.first, locs.second, time, buffer), true);
|
||||
}
|
||||
else
|
||||
raise_event = PLUGIN_HOOK_WITH_RESULT(HOOK_REPORTER,
|
||||
HookReporter(prefix, event, conn, addl, location,
|
||||
nullptr, nullptr, time, buffer), true);
|
||||
}
|
||||
|
||||
if ( raise_event && event && via_events && ! in_error_handler )
|
||||
{
|
||||
val_list* vl = new val_list;
|
||||
|
||||
|
|
|
@ -66,11 +66,11 @@ public:
|
|||
|
||||
// Report a runtime error in evaluating a Bro script expression. This
|
||||
// function will not return but raise an InterpreterException.
|
||||
void ExprRuntimeError(const Expr* expr, const char* fmt, ...);
|
||||
void ExprRuntimeError(const Expr* expr, const char* fmt, ...) __attribute__((format(printf, 3, 4)));
|
||||
|
||||
// Report a runtime error in evaluating a Bro script expression. This
|
||||
// function will not return but raise an InterpreterException.
|
||||
void RuntimeError(const Location* location, const char* fmt, ...);
|
||||
void RuntimeError(const Location* location, const char* fmt, ...) __attribute__((format(printf, 3, 4)));
|
||||
|
||||
// Report a traffic weirdness, i.e., an unexpected protocol situation
|
||||
// that may lead to incorrectly processing a connnection.
|
||||
|
@ -123,7 +123,7 @@ public:
|
|||
private:
|
||||
void DoLog(const char* prefix, EventHandlerPtr event, FILE* out,
|
||||
Connection* conn, val_list* addl, bool location, bool time,
|
||||
const char* postfix, const char* fmt, va_list ap);
|
||||
const char* postfix, const char* fmt, va_list ap) __attribute__((format(printf, 10, 0)));
|
||||
|
||||
// The order if addl, name needs to be like that since fmt_name can
|
||||
// contain format specifiers
|
||||
|
|
|
@ -24,13 +24,13 @@ public:
|
|||
// Implements the "event" keyword.
|
||||
class RuleActionEvent : public RuleAction {
|
||||
public:
|
||||
RuleActionEvent(const char* arg_msg) { msg = copy_string(arg_msg); }
|
||||
virtual ~RuleActionEvent() { delete [] msg; }
|
||||
explicit RuleActionEvent(const char* arg_msg) { msg = copy_string(arg_msg); }
|
||||
~RuleActionEvent() override { delete [] msg; }
|
||||
|
||||
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len);
|
||||
void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len) override;
|
||||
|
||||
virtual void PrintDebug();
|
||||
void PrintDebug() override;
|
||||
|
||||
private:
|
||||
const char* msg;
|
||||
|
@ -38,17 +38,17 @@ private:
|
|||
|
||||
class RuleActionMIME : public RuleAction {
|
||||
public:
|
||||
RuleActionMIME(const char* arg_mime, int arg_strength = 0)
|
||||
explicit RuleActionMIME(const char* arg_mime, int arg_strength = 0)
|
||||
{ mime = copy_string(arg_mime); strength = arg_strength; }
|
||||
|
||||
virtual ~RuleActionMIME()
|
||||
~RuleActionMIME() override
|
||||
{ delete [] mime; }
|
||||
|
||||
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len)
|
||||
void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len) override
|
||||
{ }
|
||||
|
||||
virtual void PrintDebug();
|
||||
void PrintDebug() override;
|
||||
|
||||
string GetMIME() const
|
||||
{ return mime; }
|
||||
|
@ -64,12 +64,12 @@ private:
|
|||
// Base class for enable/disable actions.
|
||||
class RuleActionAnalyzer : public RuleAction {
|
||||
public:
|
||||
RuleActionAnalyzer(const char* analyzer);
|
||||
explicit RuleActionAnalyzer(const char* analyzer);
|
||||
|
||||
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len) = 0;
|
||||
void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len) override = 0;
|
||||
|
||||
virtual void PrintDebug();
|
||||
void PrintDebug() override;
|
||||
|
||||
analyzer::Tag Analyzer() const { return analyzer; }
|
||||
analyzer::Tag ChildAnalyzer() const { return child_analyzer; }
|
||||
|
@ -81,22 +81,22 @@ private:
|
|||
|
||||
class RuleActionEnable : public RuleActionAnalyzer {
|
||||
public:
|
||||
RuleActionEnable(const char* analyzer) : RuleActionAnalyzer(analyzer) {}
|
||||
explicit RuleActionEnable(const char* analyzer) : RuleActionAnalyzer(analyzer) {}
|
||||
|
||||
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len);
|
||||
void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len) override;
|
||||
|
||||
virtual void PrintDebug();
|
||||
void PrintDebug() override;
|
||||
};
|
||||
|
||||
class RuleActionDisable : public RuleActionAnalyzer {
|
||||
public:
|
||||
RuleActionDisable(const char* analyzer) : RuleActionAnalyzer(analyzer) {}
|
||||
explicit RuleActionDisable(const char* analyzer) : RuleActionAnalyzer(analyzer) {}
|
||||
|
||||
virtual void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len);
|
||||
void DoAction(const Rule* parent, RuleEndpointState* state,
|
||||
const u_char* data, int len) override;
|
||||
|
||||
virtual void PrintDebug();
|
||||
void PrintDebug() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -175,8 +175,14 @@ bool RuleConditionEval::DoMatch(Rule* rule, RuleEndpointState* state,
|
|||
try
|
||||
{
|
||||
Val* val = id->ID_Val()->AsFunc()->Call(&args);
|
||||
result = val->AsBool();
|
||||
Unref(val);
|
||||
|
||||
if ( val )
|
||||
{
|
||||
result = val->AsBool();
|
||||
Unref(val);
|
||||
}
|
||||
else
|
||||
result = false;
|
||||
}
|
||||
|
||||
catch ( InterpreterException& e )
|
||||
|
|
|
@ -31,15 +31,15 @@ public:
|
|||
STATE_STATELESS = 8
|
||||
};
|
||||
|
||||
RuleConditionTCPState(int arg_tcpstates)
|
||||
explicit RuleConditionTCPState(int arg_tcpstates)
|
||||
{ tcpstates = arg_tcpstates; }
|
||||
|
||||
virtual ~RuleConditionTCPState() { }
|
||||
~RuleConditionTCPState() override { }
|
||||
|
||||
virtual bool DoMatch(Rule* rule, RuleEndpointState* state,
|
||||
const u_char* data, int len);
|
||||
bool DoMatch(Rule* rule, RuleEndpointState* state,
|
||||
const u_char* data, int len) override;
|
||||
|
||||
virtual void PrintDebug();
|
||||
void PrintDebug() override;
|
||||
|
||||
private:
|
||||
int tcpstates;
|
||||
|
@ -56,13 +56,15 @@ public:
|
|||
OPT_SSRR = 8,
|
||||
};
|
||||
|
||||
RuleConditionIPOptions(int arg_options) { options = arg_options; }
|
||||
virtual ~RuleConditionIPOptions() { }
|
||||
explicit RuleConditionIPOptions(int arg_options) { options = arg_options; }
|
||||
|
||||
virtual bool DoMatch(Rule* rule, RuleEndpointState* state,
|
||||
const u_char* data, int len);
|
||||
~RuleConditionIPOptions() override
|
||||
{ }
|
||||
|
||||
virtual void PrintDebug();
|
||||
bool DoMatch(Rule* rule, RuleEndpointState* state,
|
||||
const u_char* data, int len) override;
|
||||
|
||||
void PrintDebug() override;
|
||||
|
||||
private:
|
||||
int options;
|
||||
|
@ -72,12 +74,12 @@ private:
|
|||
class RuleConditionSameIP : public RuleCondition {
|
||||
public:
|
||||
RuleConditionSameIP() { }
|
||||
virtual ~RuleConditionSameIP() {}
|
||||
~RuleConditionSameIP() override {}
|
||||
|
||||
virtual bool DoMatch(Rule* rule, RuleEndpointState* state,
|
||||
const u_char* data, int len);
|
||||
bool DoMatch(Rule* rule, RuleEndpointState* state,
|
||||
const u_char* data, int len) override;
|
||||
|
||||
virtual void PrintDebug();
|
||||
void PrintDebug() override;
|
||||
};
|
||||
|
||||
// Implements "payload-size".
|
||||
|
@ -88,12 +90,12 @@ public:
|
|||
RuleConditionPayloadSize(uint32 arg_val, Comp arg_comp)
|
||||
{ val = arg_val; comp = arg_comp; }
|
||||
|
||||
virtual ~RuleConditionPayloadSize() {}
|
||||
~RuleConditionPayloadSize() override {}
|
||||
|
||||
virtual bool DoMatch(Rule* rule, RuleEndpointState* state,
|
||||
const u_char* data, int len);
|
||||
bool DoMatch(Rule* rule, RuleEndpointState* state,
|
||||
const u_char* data, int len) override;
|
||||
|
||||
virtual void PrintDebug();
|
||||
void PrintDebug() override;
|
||||
|
||||
private:
|
||||
uint32 val;
|
||||
|
@ -103,13 +105,13 @@ private:
|
|||
// Implements "eval" which evaluates the given Bro identifier.
|
||||
class RuleConditionEval : public RuleCondition {
|
||||
public:
|
||||
RuleConditionEval(const char* func);
|
||||
virtual ~RuleConditionEval() {}
|
||||
explicit RuleConditionEval(const char* func);
|
||||
~RuleConditionEval() override {}
|
||||
|
||||
virtual bool DoMatch(Rule* rule, RuleEndpointState* state,
|
||||
const u_char* data, int len);
|
||||
bool DoMatch(Rule* rule, RuleEndpointState* state,
|
||||
const u_char* data, int len) override;
|
||||
|
||||
virtual void PrintDebug();
|
||||
void PrintDebug() override;
|
||||
private:
|
||||
ID* id;
|
||||
};
|
||||
|
|
|
@ -113,13 +113,13 @@ TraversalCode Scope::Traverse(TraversalCallback* cb) const
|
|||
|
||||
|
||||
ID* lookup_ID(const char* name, const char* curr_module, bool no_global,
|
||||
bool same_module_only)
|
||||
bool same_module_only, bool check_export)
|
||||
{
|
||||
string fullname = make_full_var_name(curr_module, name);
|
||||
|
||||
string ID_module = extract_module_name(fullname.c_str());
|
||||
bool need_export = ID_module != GLOBAL_MODULE_NAME &&
|
||||
ID_module != curr_module;
|
||||
bool need_export = check_export && (ID_module != GLOBAL_MODULE_NAME &&
|
||||
ID_module != curr_module);
|
||||
|
||||
for ( int i = scopes.length() - 1; i >= 0; --i )
|
||||
{
|
||||
|
|
|
@ -19,8 +19,8 @@ declare(PDict,ID);
|
|||
|
||||
class Scope : public BroObj {
|
||||
public:
|
||||
Scope(ID* id);
|
||||
~Scope();
|
||||
explicit Scope(ID* id);
|
||||
~Scope() override;
|
||||
|
||||
ID* Lookup(const char* name) const { return local->Lookup(name); }
|
||||
void Insert(const char* name, ID* id) { local->Insert(name, id); }
|
||||
|
@ -47,7 +47,7 @@ public:
|
|||
// Adds a variable to the list.
|
||||
void AddInit(ID* id) { inits->append(id); }
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
void Describe(ODesc* d) const override;
|
||||
|
||||
TraversalCode Traverse(TraversalCallback* cb) const;
|
||||
|
||||
|
@ -64,7 +64,8 @@ extern bool in_debug;
|
|||
// If no_global is true, don't search in the default "global" namespace.
|
||||
// This passed ownership of a ref'ed ID to the caller.
|
||||
extern ID* lookup_ID(const char* name, const char* module,
|
||||
bool no_global = false, bool same_module_only=false);
|
||||
bool no_global = false, bool same_module_only = false,
|
||||
bool check_export = true);
|
||||
extern ID* install_ID(const char* name, const char* module_name,
|
||||
bool is_global, bool is_export);
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// How to make objects of class Foo serializable:
|
||||
//
|
||||
// 1. Derive Foo (directly or indirectly) from SerialObj.
|
||||
// 2. Add a SER_FOO constant to SerialTypes below.
|
||||
// 2. Add a SER_FOO constant to SerialTypes in SerialTypes.h.
|
||||
// 3. Add DECLARE_SERIAL(Foo) into class definition.
|
||||
// 4. Add a (preferably protected) default ctor if it doesn't already exist.
|
||||
// 5. For non-abstract classes, add IMPLEMENT_SERIAL(Foo, SER_FOO) to *.cc
|
||||
|
@ -163,16 +163,16 @@ public:
|
|||
// Macro helpers.
|
||||
|
||||
#define DECLARE_ABSTRACT_SERIAL(classname) \
|
||||
virtual bool DoSerialize(SerialInfo*) const; \
|
||||
virtual bool DoUnserialize(UnserialInfo*); \
|
||||
bool DoSerialize(SerialInfo*) const override; \
|
||||
bool DoUnserialize(UnserialInfo*) override; \
|
||||
|
||||
#define DECLARE_SERIAL(classname) \
|
||||
static classname* Instantiate(); \
|
||||
static SerialTypeRegistrator register_type; \
|
||||
virtual bool DoSerialize(SerialInfo*) const override; \
|
||||
virtual bool DoUnserialize(UnserialInfo*) override; \
|
||||
virtual const TransientID* GetTID() const override { return &tid; } \
|
||||
virtual SerialType GetSerialType() const override; \
|
||||
bool DoSerialize(SerialInfo*) const override; \
|
||||
bool DoUnserialize(UnserialInfo*) override; \
|
||||
const TransientID* GetTID() const override { return &tid; } \
|
||||
SerialType GetSerialType() const override; \
|
||||
TransientID tid;
|
||||
|
||||
// Only needed (and usable) for non-abstract classes.
|
||||
|
|
|
@ -115,6 +115,7 @@ SERIAL_VAL(CARDINALITY_VAL, 22)
|
|||
SERIAL_VAL(X509_VAL, 23)
|
||||
SERIAL_VAL(COMM_STORE_HANDLE_VAL, 24)
|
||||
SERIAL_VAL(COMM_DATA_VAL, 25)
|
||||
SERIAL_VAL(OCSP_RESP_VAL, 26)
|
||||
|
||||
#define SERIAL_EXPR(name, val) SERIAL_CONST(name, val, EXPR)
|
||||
SERIAL_EXPR(EXPR, 1)
|
||||
|
@ -161,6 +162,10 @@ SERIAL_EXPR(SET_CONSTRUCTOR_EXPR, 41)
|
|||
SERIAL_EXPR(VECTOR_CONSTRUCTOR_EXPR, 42)
|
||||
SERIAL_EXPR(TABLE_COERCE_EXPR, 43)
|
||||
SERIAL_EXPR(VECTOR_COERCE_EXPR, 44)
|
||||
SERIAL_EXPR(CAST_EXPR, 45)
|
||||
SERIAL_EXPR(IS_EXPR_, 46) // Name conflict with internal SER_IS_EXPR constant.
|
||||
SERIAL_EXPR(BIT_EXPR, 47)
|
||||
SERIAL_EXPR(COMPLEMENT_EXPR, 48)
|
||||
|
||||
#define SERIAL_STMT(name, val) SERIAL_CONST(name, val, STMT)
|
||||
SERIAL_STMT(STMT, 1)
|
||||
|
|
|
@ -18,7 +18,7 @@ SerializationFormat::~SerializationFormat()
|
|||
free(output);
|
||||
}
|
||||
|
||||
void SerializationFormat::StartRead(char* data, uint32 arg_len)
|
||||
void SerializationFormat::StartRead(const char* data, uint32 arg_len)
|
||||
{
|
||||
input = data;
|
||||
input_len = arg_len;
|
||||
|
|
|
@ -19,7 +19,7 @@ public:
|
|||
virtual ~SerializationFormat();
|
||||
|
||||
// Unserialization.
|
||||
virtual void StartRead(char* data, uint32 len);
|
||||
virtual void StartRead(const char* data, uint32 len);
|
||||
virtual void EndRead();
|
||||
|
||||
virtual bool Read(int* v, const char* tag) = 0;
|
||||
|
@ -87,7 +87,7 @@ protected:
|
|||
uint32 output_size;
|
||||
uint32 output_pos;
|
||||
|
||||
char* input;
|
||||
const char* input;
|
||||
uint32 input_len;
|
||||
uint32 input_pos;
|
||||
|
||||
|
@ -98,40 +98,40 @@ protected:
|
|||
class BinarySerializationFormat : public SerializationFormat {
|
||||
public:
|
||||
BinarySerializationFormat();
|
||||
virtual ~BinarySerializationFormat();
|
||||
~BinarySerializationFormat() override;
|
||||
|
||||
virtual bool Read(int* v, const char* tag);
|
||||
virtual bool Read(uint16* v, const char* tag);
|
||||
virtual bool Read(uint32* v, const char* tag);
|
||||
virtual bool Read(int64* v, const char* tag);
|
||||
virtual bool Read(uint64* v, const char* tag);
|
||||
virtual bool Read(char* v, const char* tag);
|
||||
virtual bool Read(bool* v, const char* tag);
|
||||
virtual bool Read(double* d, const char* tag);
|
||||
virtual bool Read(char** str, int* len, const char* tag);
|
||||
virtual bool Read(string* s, const char* tag);
|
||||
virtual bool Read(IPAddr* addr, const char* tag);
|
||||
virtual bool Read(IPPrefix* prefix, const char* tag);
|
||||
virtual bool Read(struct in_addr* addr, const char* tag);
|
||||
virtual bool Read(struct in6_addr* addr, const char* tag);
|
||||
virtual bool Write(int v, const char* tag);
|
||||
virtual bool Write(uint16 v, const char* tag);
|
||||
virtual bool Write(uint32 v, const char* tag);
|
||||
virtual bool Write(int64 v, const char* tag);
|
||||
virtual bool Write(uint64 v, const char* tag);
|
||||
virtual bool Write(char v, const char* tag);
|
||||
virtual bool Write(bool v, const char* tag);
|
||||
virtual bool Write(double d, const char* tag);
|
||||
virtual bool Write(const char* s, const char* tag);
|
||||
virtual bool Write(const char* buf, int len, const char* tag);
|
||||
virtual bool Write(const string& s, const char* tag);
|
||||
virtual bool Write(const IPAddr& addr, const char* tag);
|
||||
virtual bool Write(const IPPrefix& prefix, const char* tag);
|
||||
virtual bool Write(const struct in_addr& addr, const char* tag);
|
||||
virtual bool Write(const struct in6_addr& addr, const char* tag);
|
||||
virtual bool WriteOpenTag(const char* tag);
|
||||
virtual bool WriteCloseTag(const char* tag);
|
||||
virtual bool WriteSeparator();
|
||||
bool Read(int* v, const char* tag) override;
|
||||
bool Read(uint16* v, const char* tag) override;
|
||||
bool Read(uint32* v, const char* tag) override;
|
||||
bool Read(int64* v, const char* tag) override;
|
||||
bool Read(uint64* v, const char* tag) override;
|
||||
bool Read(char* v, const char* tag) override;
|
||||
bool Read(bool* v, const char* tag) override;
|
||||
bool Read(double* d, const char* tag) override;
|
||||
bool Read(char** str, int* len, const char* tag) override;
|
||||
bool Read(string* s, const char* tag) override;
|
||||
bool Read(IPAddr* addr, const char* tag) override;
|
||||
bool Read(IPPrefix* prefix, const char* tag) override;
|
||||
bool Read(struct in_addr* addr, const char* tag) override;
|
||||
bool Read(struct in6_addr* addr, const char* tag) override;
|
||||
bool Write(int v, const char* tag) override;
|
||||
bool Write(uint16 v, const char* tag) override;
|
||||
bool Write(uint32 v, const char* tag) override;
|
||||
bool Write(int64 v, const char* tag) override;
|
||||
bool Write(uint64 v, const char* tag) override;
|
||||
bool Write(char v, const char* tag) override;
|
||||
bool Write(bool v, const char* tag) override;
|
||||
bool Write(double d, const char* tag) override;
|
||||
bool Write(const char* s, const char* tag) override;
|
||||
bool Write(const char* buf, int len, const char* tag) override;
|
||||
bool Write(const string& s, const char* tag) override;
|
||||
bool Write(const IPAddr& addr, const char* tag) override;
|
||||
bool Write(const IPPrefix& prefix, const char* tag) override;
|
||||
bool Write(const struct in_addr& addr, const char* tag) override;
|
||||
bool Write(const struct in6_addr& addr, const char* tag) override;
|
||||
bool WriteOpenTag(const char* tag) override;
|
||||
bool WriteCloseTag(const char* tag) override;
|
||||
bool WriteSeparator() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1017,7 +1017,7 @@ double EventPlayer::NextTimestamp(double* local_network_time)
|
|||
return ne_time;
|
||||
|
||||
if ( ! io )
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
// Read next event if we don't have one waiting.
|
||||
if ( ! ne_time )
|
||||
|
@ -1028,7 +1028,7 @@ double EventPlayer::NextTimestamp(double* local_network_time)
|
|||
}
|
||||
|
||||
if ( ! ne_time )
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
if ( ! network_time )
|
||||
{
|
||||
|
|
|
@ -96,7 +96,7 @@ public:
|
|||
|
||||
protected:
|
||||
// Format defaults to binary serialization.
|
||||
Serializer(SerializationFormat* format = 0);
|
||||
explicit Serializer(SerializationFormat* format = 0);
|
||||
virtual ~Serializer();
|
||||
|
||||
// Reads next object.
|
||||
|
@ -159,7 +159,7 @@ public:
|
|||
|
||||
// If max_cache_size is greater than zero, we'll remove old entries
|
||||
// automatically if limit is reached (LRU expiration).
|
||||
SerializationCache(unsigned int max_cache_size = 0);
|
||||
explicit SerializationCache(unsigned int max_cache_size = 0);
|
||||
~SerializationCache();
|
||||
|
||||
PermanentID Register(const SerialObj* obj, PermanentID pid,
|
||||
|
@ -261,27 +261,27 @@ private:
|
|||
// minimal implementation of Serializer!
|
||||
class CloneSerializer : public Serializer {
|
||||
public:
|
||||
CloneSerializer(SerializationFormat* format = 0) : Serializer(format) { }
|
||||
virtual ~CloneSerializer() { }
|
||||
explicit CloneSerializer(SerializationFormat* format = 0) : Serializer(format) { }
|
||||
~CloneSerializer() override
|
||||
{ }
|
||||
|
||||
protected:
|
||||
virtual void ReportError(const char* msg) { reporter->Error("%s", msg); }
|
||||
virtual void GotID(ID* id, Val* val) { }
|
||||
virtual void GotEvent(const char* name, double time,
|
||||
EventHandlerPtr event, val_list* args) { }
|
||||
virtual void GotFunctionCall(const char* name, double time,
|
||||
Func* func, val_list* args) { }
|
||||
virtual void GotStateAccess(StateAccess* s) { delete s; }
|
||||
virtual void GotTimer(Timer* t) { }
|
||||
virtual void GotConnection(Connection* c) { }
|
||||
virtual void GotPacket(Packet* packet) { }
|
||||
void ReportError(const char* msg) override { reporter->Error("%s", msg); }
|
||||
void GotID(ID* id, Val* val) override { }
|
||||
void GotEvent(const char* name, double time, EventHandlerPtr event, val_list* args) override { }
|
||||
void GotFunctionCall(const char* name, double time,
|
||||
Func* func, val_list* args) override { }
|
||||
void GotStateAccess(StateAccess* s) override { delete s; }
|
||||
void GotTimer(Timer* t) override { }
|
||||
void GotConnection(Connection* c) override { }
|
||||
void GotPacket(Packet* packet) override { }
|
||||
};
|
||||
|
||||
// Write values/events to file or fd.
|
||||
class FileSerializer : public Serializer {
|
||||
public:
|
||||
FileSerializer(SerializationFormat* format = 0);
|
||||
virtual ~FileSerializer();
|
||||
explicit FileSerializer(SerializationFormat* format = 0);
|
||||
~FileSerializer() override;
|
||||
|
||||
// Opens the file for serialization.
|
||||
bool Open(const char* file, bool pure = false);
|
||||
|
@ -291,16 +291,16 @@ public:
|
|||
bool Read(UnserialInfo* info, const char* file, bool header = true);
|
||||
|
||||
protected:
|
||||
virtual void ReportError(const char* msg);
|
||||
virtual void GotID(ID* id, Val* val);
|
||||
virtual void GotEvent(const char* name, double time,
|
||||
EventHandlerPtr event, val_list* args);
|
||||
virtual void GotFunctionCall(const char* name, double time,
|
||||
Func* func, val_list* args);
|
||||
virtual void GotStateAccess(StateAccess* s);
|
||||
virtual void GotTimer(Timer* t);
|
||||
virtual void GotConnection(Connection* c);
|
||||
virtual void GotPacket(Packet* packet);
|
||||
void ReportError(const char* msg) override;
|
||||
void GotID(ID* id, Val* val) override;
|
||||
void GotEvent(const char* name, double time,
|
||||
EventHandlerPtr event, val_list* args) override;
|
||||
void GotFunctionCall(const char* name, double time,
|
||||
Func* func, val_list* args) override;
|
||||
void GotStateAccess(StateAccess* s) override;
|
||||
void GotTimer(Timer* t) override;
|
||||
void GotConnection(Connection* c) override;
|
||||
void GotPacket(Packet* packet) override;
|
||||
|
||||
bool OpenFile(const char* file, bool readonly, bool should_exist = false);
|
||||
void CloseFile();
|
||||
|
@ -331,21 +331,21 @@ public:
|
|||
// Plays a file of events back.
|
||||
class EventPlayer : public FileSerializer, public iosource::IOSource {
|
||||
public:
|
||||
EventPlayer(const char* file);
|
||||
virtual ~EventPlayer();
|
||||
explicit EventPlayer(const char* file);
|
||||
~EventPlayer() override;
|
||||
|
||||
virtual void GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
|
||||
iosource::FD_Set* except);
|
||||
virtual double NextTimestamp(double* local_network_time);
|
||||
virtual void Process();
|
||||
virtual const char* Tag() { return "EventPlayer"; }
|
||||
void GetFds(iosource::FD_Set* read, iosource::FD_Set* write,
|
||||
iosource::FD_Set* except) override;
|
||||
double NextTimestamp(double* local_network_time) override;
|
||||
void Process() override;
|
||||
const char* Tag() override { return "EventPlayer"; }
|
||||
|
||||
protected:
|
||||
virtual void GotID(ID* id, Val* val) {}
|
||||
virtual void GotEvent(const char* name, double time,
|
||||
EventHandlerPtr event, val_list* args);
|
||||
virtual void GotFunctionCall(const char* name, double time,
|
||||
Func* func, val_list* args);
|
||||
void GotID(ID* id, Val* val) override {}
|
||||
void GotEvent(const char* name, double time,
|
||||
EventHandlerPtr event, val_list* args) override;
|
||||
void GotFunctionCall(const char* name, double time,
|
||||
Func* func, val_list* args) override;
|
||||
|
||||
double stream_time; // time of first captured event
|
||||
double replay_time; // network time of replay start
|
||||
|
|
|
@ -337,11 +337,25 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
|
|||
return;
|
||||
}
|
||||
|
||||
// For both of these it is safe to pass ip_hdr because the presence
|
||||
// is guaranteed for the functions that pass data to us.
|
||||
uint16 ip_hdr_len = ip_hdr->HdrLen();
|
||||
if ( ip_hdr_len > len )
|
||||
{
|
||||
Weird("invalid_IP_header_size", ip_hdr, encapsulation);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ip_hdr_len > caplen )
|
||||
{
|
||||
Weird("internally_truncated_header", ip_hdr, encapsulation);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore if packet matches packet filter.
|
||||
if ( packet_filter && packet_filter->Match(ip_hdr, len, caplen) )
|
||||
return;
|
||||
|
||||
int ip_hdr_len = ip_hdr->HdrLen();
|
||||
if ( ! ignore_checksums && ip4 &&
|
||||
ones_complement_checksum((void*) ip4, ip_hdr_len, 0) != 0xffff )
|
||||
{
|
||||
|
@ -381,6 +395,12 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
|
|||
|
||||
caplen = len = ip_hdr->TotalLen();
|
||||
ip_hdr_len = ip_hdr->HdrLen();
|
||||
|
||||
if ( ip_hdr_len > len )
|
||||
{
|
||||
Weird("invalid_IP_header_size", ip_hdr, encapsulation);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -431,7 +451,6 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
int proto = ip_hdr->NextProto();
|
||||
|
||||
if ( CheckHeaderTrunc(proto, len, caplen, pkt, encapsulation) )
|
||||
|
@ -510,6 +529,11 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
|
|||
uint16 proto_typ = ntohs(*((uint16*)(data + 2)));
|
||||
int gre_version = flags_ver & 0x0007;
|
||||
|
||||
// If a carried packet has ethernet, this will help skip it.
|
||||
unsigned int eth_len = 0;
|
||||
unsigned int gre_len = gre_header_len(flags_ver);
|
||||
unsigned int ppp_len = gre_version == 1 ? 4 : 0;
|
||||
|
||||
if ( gre_version != 0 && gre_version != 1 )
|
||||
{
|
||||
Weird(fmt("unknown_gre_version_%d", gre_version), ip_hdr,
|
||||
|
@ -519,7 +543,18 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
|
|||
|
||||
if ( gre_version == 0 )
|
||||
{
|
||||
if ( proto_typ != 0x0800 && proto_typ != 0x86dd )
|
||||
if ( proto_typ == 0x6558 && len > gre_len + 14 )
|
||||
{
|
||||
// transparent ethernet bridging
|
||||
eth_len = 14;
|
||||
proto_typ = ntohs(*((uint16*)(data + gre_len + 12)));
|
||||
}
|
||||
|
||||
if ( proto_typ == 0x0800 )
|
||||
proto = IPPROTO_IPV4;
|
||||
else if ( proto_typ == 0x86dd )
|
||||
proto = IPPROTO_IPV6;
|
||||
else
|
||||
{
|
||||
// Not IPv4/IPv6 payload.
|
||||
Weird(fmt("unknown_gre_protocol_%" PRIu16, proto_typ), ip_hdr,
|
||||
|
@ -527,7 +562,6 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
|
|||
return;
|
||||
}
|
||||
|
||||
proto = (proto_typ == 0x0800) ? IPPROTO_IPV4 : IPPROTO_IPV6;
|
||||
}
|
||||
|
||||
else // gre_version == 1
|
||||
|
@ -556,10 +590,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
|
|||
return;
|
||||
}
|
||||
|
||||
unsigned int gre_len = gre_header_len(flags_ver);
|
||||
unsigned int ppp_len = gre_version == 1 ? 1 : 0;
|
||||
|
||||
if ( len < gre_len + ppp_len || caplen < gre_len + ppp_len )
|
||||
if ( len < gre_len + ppp_len + eth_len || caplen < gre_len + ppp_len + eth_len )
|
||||
{
|
||||
Weird("truncated_GRE", ip_hdr, encapsulation);
|
||||
return;
|
||||
|
@ -567,7 +598,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
|
|||
|
||||
if ( gre_version == 1 )
|
||||
{
|
||||
int ppp_proto = *((uint8*)(data + gre_len));
|
||||
uint16 ppp_proto = ntohs(*((uint16*)(data + gre_len + 2)));
|
||||
|
||||
if ( ppp_proto != 0x0021 && ppp_proto != 0x0057 )
|
||||
{
|
||||
|
@ -578,9 +609,9 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
|
|||
proto = (ppp_proto == 0x0021) ? IPPROTO_IPV4 : IPPROTO_IPV6;
|
||||
}
|
||||
|
||||
data += gre_len + ppp_len;
|
||||
len -= gre_len + ppp_len;
|
||||
caplen -= gre_len + ppp_len;
|
||||
data += gre_len + ppp_len + eth_len;
|
||||
len -= gre_len + ppp_len + eth_len;
|
||||
caplen -= gre_len + ppp_len + eth_len;
|
||||
|
||||
// Treat GRE tunnel like IP tunnels, fallthrough to logic below now
|
||||
// that GRE header is stripped and only payload packet remains.
|
||||
|
@ -607,10 +638,10 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
|
|||
// Check for a valid inner packet first.
|
||||
IP_Hdr* inner = 0;
|
||||
int result = ParseIPPacket(caplen, data, proto, inner);
|
||||
|
||||
if ( result < 0 )
|
||||
if ( result == -2 )
|
||||
Weird("invalid_inner_IP_version", ip_hdr, encapsulation);
|
||||
else if ( result < 0 )
|
||||
Weird("truncated_inner_IP", ip_hdr, encapsulation);
|
||||
|
||||
else if ( result > 0 )
|
||||
Weird("inner_IP_payload_length_mismatch", ip_hdr, encapsulation);
|
||||
|
||||
|
@ -794,6 +825,7 @@ void NetSessions::DoNextInnerPacket(double t, const Packet* pkt,
|
|||
// Construct fake packet for DoNextPacket
|
||||
Packet p;
|
||||
p.Init(DLT_RAW, &ts, caplen, len, data, false, "");
|
||||
|
||||
DoNextPacket(t, &p, inner, outer);
|
||||
|
||||
delete inner;
|
||||
|
@ -808,7 +840,10 @@ int NetSessions::ParseIPPacket(int caplen, const u_char* const pkt, int proto,
|
|||
if ( caplen < (int)sizeof(struct ip6_hdr) )
|
||||
return -1;
|
||||
|
||||
inner = new IP_Hdr((const struct ip6_hdr*) pkt, false, caplen);
|
||||
const struct ip6_hdr* ip6 = (const struct ip6_hdr*) pkt;
|
||||
inner = new IP_Hdr(ip6, false, caplen);
|
||||
if ( ( ip6->ip6_ctlun.ip6_un2_vfc & 0xF0 ) != 0x60 )
|
||||
return -2;
|
||||
}
|
||||
|
||||
else if ( proto == IPPROTO_IPV4 )
|
||||
|
@ -816,7 +851,10 @@ int NetSessions::ParseIPPacket(int caplen, const u_char* const pkt, int proto,
|
|||
if ( caplen < (int)sizeof(struct ip) )
|
||||
return -1;
|
||||
|
||||
inner = new IP_Hdr((const struct ip*) pkt, false);
|
||||
const struct ip* ip4 = (const struct ip*) pkt;
|
||||
inner = new IP_Hdr(ip4, false);
|
||||
if ( ip4->ip_v != 4 )
|
||||
return -2;
|
||||
}
|
||||
|
||||
else
|
||||
|
@ -1212,28 +1250,11 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
|
|||
if ( ! WantConnection(src_h, dst_h, tproto, flags, flip) )
|
||||
return 0;
|
||||
|
||||
ConnID flip_id = *id;
|
||||
|
||||
if ( flip )
|
||||
{
|
||||
// Make a guess that we're seeing the tail half of
|
||||
// an analyzable connection.
|
||||
const IPAddr ta = flip_id.src_addr;
|
||||
flip_id.src_addr = flip_id.dst_addr;
|
||||
flip_id.dst_addr = ta;
|
||||
|
||||
uint32 t = flip_id.src_port;
|
||||
flip_id.src_port = flip_id.dst_port;
|
||||
flip_id.dst_port = t;
|
||||
|
||||
id = &flip_id;
|
||||
}
|
||||
|
||||
Connection* conn = new Connection(this, k, t, id, flow_label, pkt, encapsulation);
|
||||
conn->SetTransport(tproto);
|
||||
|
||||
if ( flip )
|
||||
conn->AddHistory('^');
|
||||
conn->FlipRoles();
|
||||
|
||||
if ( ! analyzer_mgr->BuildInitialAnalyzerTree(conn) )
|
||||
{
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
: Timer(t, TIMER_TIMERMGR_EXPIRE), mgr(arg_mgr)
|
||||
{ }
|
||||
|
||||
virtual void Dispatch(double t, int is_expire);
|
||||
void Dispatch(double t, int is_expire) override;
|
||||
|
||||
protected:
|
||||
TimerMgr* mgr;
|
||||
|
@ -151,8 +151,9 @@ public:
|
|||
|
||||
/**
|
||||
* Returns a wrapper IP_Hdr object if \a pkt appears to be a valid IPv4
|
||||
* or IPv6 header based on whether it's long enough to contain such a header
|
||||
* and also that the payload length field of that header matches the actual
|
||||
* or IPv6 header based on whether it's long enough to contain such a header,
|
||||
* if version given in the header matches the proto argument, and also checks
|
||||
* that the payload length field of that header matches the actual
|
||||
* length of \a pkt given by \a caplen.
|
||||
*
|
||||
* @param caplen The length of \a pkt in bytes.
|
||||
|
@ -163,7 +164,8 @@ public:
|
|||
* if \a pkt looks like a valid IP packet or at least long enough
|
||||
* to hold an IP header.
|
||||
* @return 0 If the inner IP packet appeared valid, else -1 if \a caplen
|
||||
* is greater than the supposed IP packet's payload length field or
|
||||
* is greater than the supposed IP packet's payload length field, -2
|
||||
* if the version of the inner header does not match proto or
|
||||
* 1 if \a caplen is less than the supposed packet's payload length.
|
||||
* In the -1 case, \a inner may still be non-null if \a caplen was
|
||||
* long enough to be an IP header, and \a inner is always non-null
|
||||
|
@ -258,9 +260,9 @@ public:
|
|||
: Timer(t + BifConst::Tunnel::ip_tunnel_timeout,
|
||||
TIMER_IP_TUNNEL_INACTIVITY), tunnel_idx(p) {}
|
||||
|
||||
~IPTunnelTimer() {}
|
||||
~IPTunnelTimer() override {}
|
||||
|
||||
void Dispatch(double t, int is_expire);
|
||||
void Dispatch(double t, int is_expire) override;
|
||||
|
||||
protected:
|
||||
NetSessions::IPPair tunnel_idx;
|
||||
|
|
|
@ -41,10 +41,10 @@ public:
|
|||
typedef BSSAlignVec::iterator BSSAlignVecIt;
|
||||
typedef BSSAlignVec::const_iterator BSSAlignVecCIt;
|
||||
|
||||
BroSubstring(const string& string)
|
||||
explicit BroSubstring(const string& string)
|
||||
: BroString(string), _num(), _new(false) { }
|
||||
|
||||
BroSubstring(const BroString& string)
|
||||
explicit BroSubstring(const BroString& string)
|
||||
: BroString(string), _num(), _new(false) { }
|
||||
|
||||
BroSubstring(const BroSubstring& bst);
|
||||
|
@ -97,7 +97,7 @@ private:
|
|||
//
|
||||
class BroSubstringCmp {
|
||||
public:
|
||||
BroSubstringCmp(unsigned int index) { _index = index; }
|
||||
explicit BroSubstringCmp(unsigned int index) { _index = index; }
|
||||
bool operator()(const BroSubstring* bst1, const BroSubstring* bst2) const;
|
||||
|
||||
private:
|
||||
|
@ -119,7 +119,7 @@ enum SWVariant {
|
|||
// Parameters for Smith-Waterman are stored in this simple record.
|
||||
//
|
||||
struct SWParams {
|
||||
SWParams(unsigned int min_toklen = 3, SWVariant sw_variant = SW_SINGLE)
|
||||
explicit SWParams(unsigned int min_toklen = 3, SWVariant sw_variant = SW_SINGLE)
|
||||
{
|
||||
_min_toklen = min_toklen;
|
||||
_sw_variant = sw_variant;
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
|
||||
StateAccess(const StateAccess& sa);
|
||||
|
||||
virtual ~StateAccess();
|
||||
~StateAccess() override;
|
||||
|
||||
// Replays this access in the our environment.
|
||||
void Replay();
|
||||
|
|
31
src/Stats.cc
31
src/Stats.cc
|
@ -9,10 +9,7 @@
|
|||
#include "DNS_Mgr.h"
|
||||
#include "Trigger.h"
|
||||
#include "threading/Manager.h"
|
||||
|
||||
#ifdef ENABLE_BROKER
|
||||
#include "broker/Manager.h"
|
||||
#endif
|
||||
|
||||
uint64 killed_by_inactivity = 0;
|
||||
|
||||
|
@ -226,25 +223,19 @@ void ProfileLogger::Log()
|
|||
));
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BROKER
|
||||
auto cs = broker_mgr->ConsumeStatistics();
|
||||
auto cs = broker_mgr->GetStatistics();
|
||||
|
||||
file->Write(fmt("%0.6f Comm: peers=%zu stores=%zu "
|
||||
"store_queries=%zu store_responses=%zu "
|
||||
"outgoing_conn_status=%zu incoming_conn_status=%zu "
|
||||
"reports=%zu\n",
|
||||
network_time, cs.outgoing_peer_count, cs.data_store_count,
|
||||
cs.pending_query_count, cs.response_count,
|
||||
cs.outgoing_conn_status_count, cs.incoming_conn_status_count,
|
||||
cs.report_count));
|
||||
|
||||
for ( const auto& s : cs.print_count )
|
||||
file->Write(fmt(" %-25s prints dequeued=%zu\n", s.first.data(), s.second));
|
||||
for ( const auto& s : cs.event_count )
|
||||
file->Write(fmt(" %-25s events dequeued=%zu\n", s.first.data(), s.second));
|
||||
for ( const auto& s : cs.log_count )
|
||||
file->Write(fmt(" %-25s logs dequeued=%zu\n", s.first.data(), s.second));
|
||||
#endif
|
||||
"pending_queries=%zu "
|
||||
"events_in=%zu events_out=%zu "
|
||||
"logs_in=%zu logs_out=%zu "
|
||||
"ids_in=%zu ids_out=%zu ",
|
||||
network_time, cs.num_peers, cs.num_stores,
|
||||
cs.num_pending_queries,
|
||||
cs.num_events_incoming, cs.num_events_outgoing,
|
||||
cs.num_logs_incoming, cs.num_logs_outgoing,
|
||||
cs.num_ids_incoming, cs.num_ids_outgoing
|
||||
));
|
||||
|
||||
// Script-level state.
|
||||
unsigned int size, mem = 0;
|
||||
|
|
|
@ -63,14 +63,14 @@ protected:
|
|||
class ProfileLogger : public SegmentStatsReporter {
|
||||
public:
|
||||
ProfileLogger(BroFile* file, double interval);
|
||||
~ProfileLogger();
|
||||
~ProfileLogger() override;
|
||||
|
||||
void Log();
|
||||
BroFile* File() { return file; }
|
||||
|
||||
protected:
|
||||
void SegmentProfile(const char* name, const Location* loc,
|
||||
double dtime, int dmem);
|
||||
double dtime, int dmem) override;
|
||||
|
||||
private:
|
||||
BroFile* file;
|
||||
|
@ -82,7 +82,7 @@ private:
|
|||
class SampleLogger : public SegmentStatsReporter {
|
||||
public:
|
||||
SampleLogger();
|
||||
~SampleLogger();
|
||||
~SampleLogger() override;
|
||||
|
||||
// These are called to report that a given function or location
|
||||
// has been seen during the sampling.
|
||||
|
@ -91,7 +91,7 @@ public:
|
|||
|
||||
protected:
|
||||
void SegmentProfile(const char* name, const Location* loc,
|
||||
double dtime, int dmem);
|
||||
double dtime, int dmem) override;
|
||||
|
||||
TableVal* load_samples;
|
||||
};
|
||||
|
|
237
src/Stmt.cc
237
src/Stmt.cc
|
@ -546,8 +546,8 @@ static BroStmtTag get_last_stmt_tag(const Stmt* stmt)
|
|||
return get_last_stmt_tag(stmts->Stmts()[len - 1]);
|
||||
}
|
||||
|
||||
Case::Case(ListExpr* c, Stmt* arg_s)
|
||||
: cases(c), s(arg_s)
|
||||
Case::Case(ListExpr* arg_expr_cases, id_list* arg_type_cases, Stmt* arg_s)
|
||||
: expr_cases(arg_expr_cases), type_cases(arg_type_cases), s(arg_s)
|
||||
{
|
||||
BroStmtTag t = get_last_stmt_tag(Body());
|
||||
|
||||
|
@ -557,13 +557,18 @@ Case::Case(ListExpr* c, Stmt* arg_s)
|
|||
|
||||
Case::~Case()
|
||||
{
|
||||
Unref(cases);
|
||||
Unref(expr_cases);
|
||||
Unref(s);
|
||||
|
||||
loop_over_list((*type_cases), i)
|
||||
Unref((*type_cases)[i]);
|
||||
|
||||
delete type_cases;
|
||||
}
|
||||
|
||||
void Case::Describe(ODesc* d) const
|
||||
{
|
||||
if ( ! Cases() )
|
||||
if ( ! (expr_cases || type_cases) )
|
||||
{
|
||||
if ( ! d->IsBinary() )
|
||||
d->Add("default:");
|
||||
|
@ -578,20 +583,49 @@ void Case::Describe(ODesc* d) const
|
|||
return;
|
||||
}
|
||||
|
||||
const expr_list& e = Cases()->Exprs();
|
||||
|
||||
if ( ! d->IsBinary() )
|
||||
d->Add("case");
|
||||
|
||||
d->AddCount(e.length());
|
||||
|
||||
loop_over_list(e, j)
|
||||
if ( expr_cases )
|
||||
{
|
||||
if ( j > 0 && ! d->IsReadable() )
|
||||
d->Add(",");
|
||||
const expr_list& e = expr_cases->Exprs();
|
||||
|
||||
d->SP();
|
||||
e[j]->Describe(d);
|
||||
d->AddCount(e.length());
|
||||
|
||||
loop_over_list(e, i)
|
||||
{
|
||||
if ( i > 0 && d->IsReadable() )
|
||||
d->Add(",");
|
||||
|
||||
d->SP();
|
||||
e[i]->Describe(d);
|
||||
}
|
||||
}
|
||||
|
||||
if ( type_cases )
|
||||
{
|
||||
const id_list& t = *type_cases;
|
||||
|
||||
d->AddCount(t.length());
|
||||
|
||||
loop_over_list(t, i)
|
||||
{
|
||||
if ( i > 0 && d->IsReadable() )
|
||||
d->Add(",");
|
||||
|
||||
d->SP();
|
||||
d->Add("type");
|
||||
d->SP();
|
||||
t[i]->Type()->Describe(d);
|
||||
|
||||
if ( t[i]->Name() )
|
||||
{
|
||||
d->SP();
|
||||
d->Add("as");
|
||||
d->SP();
|
||||
d->Add(t[i]->Name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( d->IsReadable() )
|
||||
|
@ -607,12 +641,17 @@ TraversalCode Case::Traverse(TraversalCallback* cb) const
|
|||
{
|
||||
TraversalCode tc;
|
||||
|
||||
if ( cases )
|
||||
if ( expr_cases )
|
||||
{
|
||||
tc = cases->Traverse(cb);
|
||||
tc = expr_cases->Traverse(cb);
|
||||
HANDLE_TC_STMT_PRE(tc);
|
||||
}
|
||||
|
||||
if ( type_cases )
|
||||
{
|
||||
// No traverse support for types.
|
||||
}
|
||||
|
||||
tc = s->Traverse(cb);
|
||||
HANDLE_TC_STMT_PRE(tc);
|
||||
|
||||
|
@ -634,17 +673,48 @@ IMPLEMENT_SERIAL(Case, SER_CASE);
|
|||
bool Case::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
DO_SERIALIZE(SER_CASE, BroObj);
|
||||
return cases->Serialize(info) && this->s->Serialize(info);
|
||||
|
||||
if ( ! expr_cases->Serialize(info) )
|
||||
return false;
|
||||
|
||||
id_list empty;
|
||||
id_list* types = (type_cases ? type_cases : &empty);
|
||||
|
||||
if ( ! SERIALIZE(types->length()) )
|
||||
return false;
|
||||
|
||||
loop_over_list((*types), i)
|
||||
{
|
||||
if ( ! (*types)[i]->Serialize(info) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return this->s->Serialize(info);
|
||||
}
|
||||
|
||||
bool Case::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
DO_UNSERIALIZE(BroObj);
|
||||
|
||||
cases = (ListExpr*) Expr::Unserialize(info, EXPR_LIST);
|
||||
if ( ! cases )
|
||||
expr_cases = (ListExpr*) Expr::Unserialize(info, EXPR_LIST);
|
||||
if ( ! expr_cases )
|
||||
return false;
|
||||
|
||||
int len;
|
||||
if ( ! UNSERIALIZE(&len) )
|
||||
return false;
|
||||
|
||||
type_cases = new id_list;
|
||||
|
||||
while ( len-- )
|
||||
{
|
||||
ID* id = ID::Unserialize(info);
|
||||
if ( ! id )
|
||||
return false;
|
||||
|
||||
type_cases->append(id);
|
||||
}
|
||||
|
||||
this->s = Stmt::Unserialize(info);
|
||||
return this->s != 0;
|
||||
}
|
||||
|
@ -661,7 +731,7 @@ void SwitchStmt::Init()
|
|||
comp_hash = new CompositeHash(t);
|
||||
Unref(t);
|
||||
|
||||
case_label_map.SetDeleteFunc(int_del_func);
|
||||
case_label_value_map.SetDeleteFunc(int_del_func);
|
||||
}
|
||||
|
||||
SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) :
|
||||
|
@ -669,16 +739,22 @@ SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) :
|
|||
{
|
||||
Init();
|
||||
|
||||
if ( ! is_atomic_type(e->Type()) )
|
||||
e->Error("switch expression must be of an atomic type");
|
||||
bool have_exprs = false;
|
||||
bool have_types = false;
|
||||
|
||||
loop_over_list(*cases, i)
|
||||
{
|
||||
Case* c = (*cases)[i];
|
||||
ListExpr* le = c->Cases();
|
||||
ListExpr* le = c->ExprCases();
|
||||
id_list* tl = c->TypeCases();
|
||||
|
||||
if ( le )
|
||||
{
|
||||
have_exprs = true;
|
||||
|
||||
if ( ! is_atomic_type(e->Type()) )
|
||||
e->Error("switch expression must be of an atomic type when cases are expressions");
|
||||
|
||||
if ( ! le->Type()->AsTypeList()->AllMatch(e->Type(), false) )
|
||||
{
|
||||
le->Error("case expression type differs from switch type", e);
|
||||
|
@ -736,12 +812,34 @@ SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) :
|
|||
exprs[j]->Error("case label expression isn't constant");
|
||||
else
|
||||
{
|
||||
if ( ! AddCaseLabelMapping(exprs[j]->ExprVal(), i) )
|
||||
if ( ! AddCaseLabelValueMapping(exprs[j]->ExprVal(), i) )
|
||||
exprs[j]->Error("duplicate case label");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if ( tl )
|
||||
{
|
||||
have_types = true;
|
||||
|
||||
loop_over_list((*tl), j)
|
||||
{
|
||||
BroType* ct = (*tl)[j]->Type();
|
||||
|
||||
if ( ! can_cast_value_to_type(e->Type(), ct) )
|
||||
{
|
||||
c->Error("cannot cast switch expression to case type");
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! AddCaseLabelTypeMapping((*tl)[j], i) )
|
||||
{
|
||||
c->Error("duplicate case label");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if ( default_case_idx != -1 )
|
||||
|
@ -750,6 +848,10 @@ SwitchStmt::SwitchStmt(Expr* index, case_list* arg_cases) :
|
|||
default_case_idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
if ( have_exprs && have_types )
|
||||
Error("cannot mix cases with expressions and types");
|
||||
|
||||
}
|
||||
|
||||
SwitchStmt::~SwitchStmt()
|
||||
|
@ -761,7 +863,7 @@ SwitchStmt::~SwitchStmt()
|
|||
delete comp_hash;
|
||||
}
|
||||
|
||||
bool SwitchStmt::AddCaseLabelMapping(const Val* v, int idx)
|
||||
bool SwitchStmt::AddCaseLabelValueMapping(const Val* v, int idx)
|
||||
{
|
||||
HashKey* hk = comp_hash->ComputeHash(v, 1);
|
||||
|
||||
|
@ -772,7 +874,7 @@ bool SwitchStmt::AddCaseLabelMapping(const Val* v, int idx)
|
|||
type_name(v->Type()->Tag()), type_name(e->Type()->Tag()));
|
||||
}
|
||||
|
||||
int* label_idx = case_label_map.Lookup(hk);
|
||||
int* label_idx = case_label_value_map.Lookup(hk);
|
||||
|
||||
if ( label_idx )
|
||||
{
|
||||
|
@ -780,38 +882,76 @@ bool SwitchStmt::AddCaseLabelMapping(const Val* v, int idx)
|
|||
return false;
|
||||
}
|
||||
|
||||
case_label_map.Insert(hk, new int(idx));
|
||||
case_label_value_map.Insert(hk, new int(idx));
|
||||
delete hk;
|
||||
return true;
|
||||
}
|
||||
|
||||
int SwitchStmt::FindCaseLabelMatch(const Val* v) const
|
||||
bool SwitchStmt::AddCaseLabelTypeMapping(ID* t, int idx)
|
||||
{
|
||||
HashKey* hk = comp_hash->ComputeHash(v, 1);
|
||||
|
||||
if ( ! hk )
|
||||
for ( auto i : case_label_type_list )
|
||||
{
|
||||
reporter->PushLocation(e->GetLocationInfo());
|
||||
reporter->Error("switch expression type mismatch (%s/%s)",
|
||||
type_name(v->Type()->Tag()), type_name(e->Type()->Tag()));
|
||||
return -1;
|
||||
if ( same_type(i.first->Type(), t->Type()) )
|
||||
return false;
|
||||
}
|
||||
|
||||
int* label_idx = case_label_map.Lookup(hk);
|
||||
auto e = std::make_pair(t, idx);
|
||||
case_label_type_list.push_back(e);
|
||||
|
||||
delete hk;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( ! label_idx )
|
||||
return default_case_idx;
|
||||
std::pair<int, ID*> SwitchStmt::FindCaseLabelMatch(const Val* v) const
|
||||
{
|
||||
int label_idx = -1;
|
||||
ID* label_id = 0;
|
||||
|
||||
// Find matching expression cases.
|
||||
if ( case_label_value_map.Length() )
|
||||
{
|
||||
HashKey* hk = comp_hash->ComputeHash(v, 1);
|
||||
|
||||
if ( ! hk )
|
||||
{
|
||||
reporter->PushLocation(e->GetLocationInfo());
|
||||
reporter->Error("switch expression type mismatch (%s/%s)",
|
||||
type_name(v->Type()->Tag()), type_name(e->Type()->Tag()));
|
||||
return std::make_pair(-1, nullptr);
|
||||
}
|
||||
|
||||
if ( auto i = case_label_value_map.Lookup(hk) )
|
||||
label_idx = *i;
|
||||
|
||||
delete hk;
|
||||
}
|
||||
|
||||
// Find matching type cases.
|
||||
for ( auto i : case_label_type_list )
|
||||
{
|
||||
auto id = i.first;
|
||||
auto type = id->Type();
|
||||
|
||||
if ( can_cast_value_to_type(v, type) )
|
||||
{
|
||||
label_idx = i.second;
|
||||
label_id = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( label_idx < 0 )
|
||||
return std::make_pair(default_case_idx, nullptr);
|
||||
else
|
||||
return *label_idx;
|
||||
return std::make_pair(label_idx, label_id);
|
||||
}
|
||||
|
||||
Val* SwitchStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
|
||||
{
|
||||
Val* rval = 0;
|
||||
|
||||
int matching_label_idx = FindCaseLabelMatch(v);
|
||||
auto m = FindCaseLabelMatch(v);
|
||||
int matching_label_idx = m.first;
|
||||
ID* matching_id = m.second;
|
||||
|
||||
if ( matching_label_idx == -1 )
|
||||
return 0;
|
||||
|
@ -820,6 +960,12 @@ Val* SwitchStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
|
|||
{
|
||||
const Case* c = (*cases)[i];
|
||||
|
||||
if ( matching_id )
|
||||
{
|
||||
auto cv = cast_value_to_type(v, matching_id->Type());
|
||||
f->SetElement(matching_id->Offset(), cv);
|
||||
}
|
||||
|
||||
flow = FLOW_NEXT;
|
||||
rval = c->Body()->Exec(f, flow);
|
||||
|
||||
|
@ -841,7 +987,7 @@ int SwitchStmt::IsPure() const
|
|||
loop_over_list(*cases, i)
|
||||
{
|
||||
Case* c = (*cases)[i];
|
||||
if ( ! c->Cases()->IsPure() || ! c->Body()->IsPure() )
|
||||
if ( ! c->ExprCases()->IsPure() || ! c->Body()->IsPure() )
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -928,7 +1074,7 @@ bool SwitchStmt::DoUnserialize(UnserialInfo* info)
|
|||
|
||||
loop_over_list(*cases, i)
|
||||
{
|
||||
const ListExpr* le = (*cases)[i]->Cases();
|
||||
const ListExpr* le = (*cases)[i]->ExprCases();
|
||||
|
||||
if ( ! le )
|
||||
continue;
|
||||
|
@ -937,7 +1083,7 @@ bool SwitchStmt::DoUnserialize(UnserialInfo* info)
|
|||
|
||||
loop_over_list(exprs, j)
|
||||
{
|
||||
if ( ! AddCaseLabelMapping(exprs[j]->ExprVal(), i) )
|
||||
if ( ! AddCaseLabelValueMapping(exprs[j]->ExprVal(), i) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1293,6 +1439,9 @@ Val* ForStmt::DoExec(Frame* f, Val* v, stmt_flow_type& flow) const
|
|||
TableVal* tv = v->AsTableVal();
|
||||
const PDict(TableEntryVal)* loop_vals = tv->AsTable();
|
||||
|
||||
if ( ! loop_vals->Length() )
|
||||
return 0;
|
||||
|
||||
HashKey* k;
|
||||
IterCookie* c = loop_vals->InitForIteration();
|
||||
while ( loop_vals->NextEntry(k, c) )
|
||||
|
@ -1387,7 +1536,7 @@ void ForStmt::Describe(ODesc* d) const
|
|||
if ( i > 0 )
|
||||
d->Add(",");
|
||||
}
|
||||
|
||||
|
||||
if ( loop_vars->length() )
|
||||
d->Add("]");
|
||||
|
||||
|
|
85
src/Stmt.h
85
src/Stmt.h
|
@ -23,15 +23,15 @@ class Stmt : public BroObj {
|
|||
public:
|
||||
BroStmtTag Tag() const { return tag; }
|
||||
|
||||
virtual ~Stmt();
|
||||
~Stmt() override;
|
||||
|
||||
virtual Val* Exec(Frame* f, stmt_flow_type& flow) const = 0;
|
||||
|
||||
Stmt* Ref() { ::Ref(this); return this; }
|
||||
|
||||
bool SetLocationInfo(const Location* loc)
|
||||
bool SetLocationInfo(const Location* loc) override
|
||||
{ return Stmt::SetLocationInfo(loc, loc); }
|
||||
bool SetLocationInfo(const Location* start, const Location* end);
|
||||
bool SetLocationInfo(const Location* start, const Location* end) override;
|
||||
|
||||
// True if the statement has no side effects, false otherwise.
|
||||
virtual int IsPure() const;
|
||||
|
@ -58,7 +58,7 @@ public:
|
|||
void AccessStats(ODesc* d) const;
|
||||
uint32 GetAccessCount() const { return access_count; }
|
||||
|
||||
virtual void Describe(ODesc* d) const;
|
||||
void Describe(ODesc* d) const override;
|
||||
|
||||
virtual void IncrBPCount() { ++breakpoint_count; }
|
||||
virtual void DecrBPCount()
|
||||
|
@ -78,7 +78,7 @@ public:
|
|||
|
||||
protected:
|
||||
Stmt() {}
|
||||
Stmt(BroStmtTag arg_tag);
|
||||
explicit Stmt(BroStmtTag arg_tag);
|
||||
|
||||
void AddTag(ODesc* d) const;
|
||||
void DescribeDone(ODesc* d) const;
|
||||
|
@ -97,18 +97,18 @@ class ExprListStmt : public Stmt {
|
|||
public:
|
||||
const ListExpr* ExprList() const { return l; }
|
||||
|
||||
TraversalCode Traverse(TraversalCallback* cb) const;
|
||||
TraversalCode Traverse(TraversalCallback* cb) const override;
|
||||
|
||||
protected:
|
||||
ExprListStmt() { l = 0; }
|
||||
ExprListStmt(BroStmtTag t, ListExpr* arg_l);
|
||||
|
||||
virtual ~ExprListStmt();
|
||||
~ExprListStmt() override;
|
||||
|
||||
Val* Exec(Frame* f, stmt_flow_type& flow) const;
|
||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||
virtual Val* DoExec(val_list* vals, stmt_flow_type& flow) const = 0;
|
||||
|
||||
void Describe(ODesc* d) const;
|
||||
void Describe(ODesc* d) const override;
|
||||
void PrintVals(ODesc* d, val_list* vals, int offset) const;
|
||||
|
||||
DECLARE_ABSTRACT_SERIAL(ExprListStmt);
|
||||
|
@ -118,7 +118,7 @@ protected:
|
|||
|
||||
class PrintStmt : public ExprListStmt {
|
||||
public:
|
||||
PrintStmt(ListExpr* l) : ExprListStmt(STMT_PRINT, l) { }
|
||||
explicit PrintStmt(ListExpr* l) : ExprListStmt(STMT_PRINT, l) { }
|
||||
|
||||
protected:
|
||||
friend class Stmt;
|
||||
|
@ -131,8 +131,8 @@ protected:
|
|||
|
||||
class ExprStmt : public Stmt {
|
||||
public:
|
||||
ExprStmt(Expr* e);
|
||||
virtual ~ExprStmt();
|
||||
explicit ExprStmt(Expr* e);
|
||||
~ExprStmt() override;
|
||||
|
||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||
|
||||
|
@ -159,7 +159,7 @@ protected:
|
|||
class IfStmt : public ExprStmt {
|
||||
public:
|
||||
IfStmt(Expr* test, Stmt* s1, Stmt* s2);
|
||||
~IfStmt();
|
||||
~IfStmt() override;
|
||||
|
||||
const Stmt* TrueBranch() const { return s1; }
|
||||
const Stmt* FalseBranch() const { return s2; }
|
||||
|
@ -183,11 +183,14 @@ protected:
|
|||
|
||||
class Case : public BroObj {
|
||||
public:
|
||||
Case(ListExpr* c, Stmt* arg_s);
|
||||
~Case();
|
||||
Case(ListExpr* c, id_list* types, Stmt* arg_s);
|
||||
~Case() override;
|
||||
|
||||
const ListExpr* Cases() const { return cases; }
|
||||
ListExpr* Cases() { return cases; }
|
||||
const ListExpr* ExprCases() const { return expr_cases; }
|
||||
ListExpr* ExprCases() { return expr_cases; }
|
||||
|
||||
const id_list* TypeCases() const { return type_cases; }
|
||||
id_list* TypeCases() { return type_cases; }
|
||||
|
||||
const Stmt* Body() const { return s; }
|
||||
Stmt* Body() { return s; }
|
||||
|
@ -201,18 +204,19 @@ public:
|
|||
|
||||
protected:
|
||||
friend class Stmt;
|
||||
Case() { cases = 0; s = 0; }
|
||||
Case() { expr_cases = 0; type_cases = 0; s = 0; }
|
||||
|
||||
DECLARE_SERIAL(Case);
|
||||
|
||||
ListExpr* cases;
|
||||
ListExpr* expr_cases;
|
||||
id_list* type_cases;
|
||||
Stmt* s;
|
||||
};
|
||||
|
||||
class SwitchStmt : public ExprStmt {
|
||||
public:
|
||||
SwitchStmt(Expr* index, case_list* cases);
|
||||
~SwitchStmt();
|
||||
~SwitchStmt() override;
|
||||
|
||||
const case_list* Cases() const { return cases; }
|
||||
|
||||
|
@ -232,25 +236,32 @@ protected:
|
|||
// Initialize composite hash and case label map.
|
||||
void Init();
|
||||
|
||||
// Adds an entry in case_label_map for the given value to associate it
|
||||
// Adds an entry in case_label_value_map for the given value to associate it
|
||||
// with the given index in the cases list. If the entry already exists,
|
||||
// returns false, else returns true.
|
||||
bool AddCaseLabelMapping(const Val* v, int idx);
|
||||
bool AddCaseLabelValueMapping(const Val* v, int idx);
|
||||
|
||||
// Returns index of a case label that's equal to the value, or
|
||||
// default_case_idx if no case label matches (which may be -1 if there's
|
||||
// no default label).
|
||||
int FindCaseLabelMatch(const Val* v) const;
|
||||
// Adds an entry in case_label_type_map for the given type (w/ ID) to
|
||||
// associate it with the given index in the cases list. If an entry
|
||||
// for the type already exists, returns false; else returns true.
|
||||
bool AddCaseLabelTypeMapping(ID* t, int idx);
|
||||
|
||||
// Returns index of a case label that matches the value, or
|
||||
// default_case_idx if no case label matches (which may be -1 if
|
||||
// there's no default label). The second tuple element is the ID of
|
||||
// the matching type-based case if it defines one.
|
||||
std::pair<int, ID*> FindCaseLabelMatch(const Val* v) const;
|
||||
|
||||
case_list* cases;
|
||||
int default_case_idx;
|
||||
CompositeHash* comp_hash;
|
||||
PDict(int) case_label_map;
|
||||
PDict(int) case_label_value_map;
|
||||
std::vector<std::pair<ID*, int>> case_label_type_list;
|
||||
};
|
||||
|
||||
class AddStmt : public ExprStmt {
|
||||
public:
|
||||
AddStmt(Expr* e);
|
||||
explicit AddStmt(Expr* e);
|
||||
|
||||
int IsPure() const override;
|
||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||
|
@ -266,7 +277,7 @@ protected:
|
|||
|
||||
class DelStmt : public ExprStmt {
|
||||
public:
|
||||
DelStmt(Expr* e);
|
||||
explicit DelStmt(Expr* e);
|
||||
|
||||
int IsPure() const override;
|
||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||
|
@ -282,7 +293,7 @@ protected:
|
|||
|
||||
class EventStmt : public ExprStmt {
|
||||
public:
|
||||
EventStmt(EventExpr* e);
|
||||
explicit EventStmt(EventExpr* e);
|
||||
|
||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||
|
||||
|
@ -301,7 +312,7 @@ class WhileStmt : public Stmt {
|
|||
public:
|
||||
|
||||
WhileStmt(Expr* loop_condition, Stmt* body);
|
||||
~WhileStmt();
|
||||
~WhileStmt() override;
|
||||
|
||||
int IsPure() const override;
|
||||
|
||||
|
@ -326,7 +337,7 @@ protected:
|
|||
class ForStmt : public ExprStmt {
|
||||
public:
|
||||
ForStmt(id_list* loop_vars, Expr* loop_expr);
|
||||
~ForStmt();
|
||||
~ForStmt() override;
|
||||
|
||||
void AddBody(Stmt* arg_body) { body = arg_body; }
|
||||
|
||||
|
@ -399,7 +410,7 @@ protected:
|
|||
|
||||
class ReturnStmt : public ExprStmt {
|
||||
public:
|
||||
ReturnStmt(Expr* e);
|
||||
explicit ReturnStmt(Expr* e);
|
||||
|
||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||
|
||||
|
@ -415,7 +426,7 @@ protected:
|
|||
class StmtList : public Stmt {
|
||||
public:
|
||||
StmtList();
|
||||
~StmtList();
|
||||
~StmtList() override;
|
||||
|
||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||
|
||||
|
@ -456,14 +467,14 @@ protected:
|
|||
|
||||
class InitStmt : public Stmt {
|
||||
public:
|
||||
InitStmt(id_list* arg_inits) : Stmt(STMT_INIT)
|
||||
explicit InitStmt(id_list* arg_inits) : Stmt(STMT_INIT)
|
||||
{
|
||||
inits = arg_inits;
|
||||
if ( arg_inits && arg_inits->length() )
|
||||
SetLocationInfo((*arg_inits)[0]->GetLocationInfo());
|
||||
}
|
||||
|
||||
~InitStmt();
|
||||
~InitStmt() override;
|
||||
|
||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||
|
||||
|
@ -501,7 +512,7 @@ class WhenStmt : public Stmt {
|
|||
public:
|
||||
// s2 is null if no timeout block given.
|
||||
WhenStmt(Expr* cond, Stmt* s1, Stmt* s2, Expr* timeout, bool is_return);
|
||||
~WhenStmt();
|
||||
~WhenStmt() override;
|
||||
|
||||
Val* Exec(Frame* f, stmt_flow_type& flow) const override;
|
||||
int IsPure() const override;
|
||||
|
|
|
@ -132,7 +132,7 @@ protected:
|
|||
*
|
||||
* @param val An enum value of script type \c Analyzer::Tag.
|
||||
*/
|
||||
Tag(EnumVal* val);
|
||||
explicit Tag(EnumVal* val);
|
||||
|
||||
private:
|
||||
type_t type; // Main type.
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "Timer.h"
|
||||
#include "Desc.h"
|
||||
#include "Serializer.h"
|
||||
#include "broker/Manager.h"
|
||||
|
||||
// Names of timers in same order than in TimerType.
|
||||
const char* TimerNames[] = {
|
||||
|
@ -103,6 +104,7 @@ int TimerMgr::Advance(double arg_t, int max_expire)
|
|||
last_timestamp = 0;
|
||||
num_expired = 0;
|
||||
last_advance = timer_mgr->Time();
|
||||
broker_mgr->AdvanceTime(arg_t);
|
||||
|
||||
return DoAdvance(t, max_expire);
|
||||
}
|
||||
|
|
41
src/Timer.h
41
src/Timer.h
|
@ -56,7 +56,7 @@ class Timer : public SerialObj, public PQ_Element {
|
|||
public:
|
||||
Timer(double t, TimerType arg_type) : PQ_Element(t)
|
||||
{ type = (char) arg_type; }
|
||||
virtual ~Timer() { }
|
||||
~Timer() override { }
|
||||
|
||||
TimerType Type() const { return (TimerType) type; }
|
||||
|
||||
|
@ -118,7 +118,7 @@ public:
|
|||
static unsigned int* CurrentTimers() { return current_timers; }
|
||||
|
||||
protected:
|
||||
TimerMgr(const Tag& arg_tag)
|
||||
explicit TimerMgr(const Tag& arg_tag)
|
||||
{
|
||||
t = 0.0;
|
||||
num_expired = 0;
|
||||
|
@ -141,20 +141,19 @@ protected:
|
|||
|
||||
class PQ_TimerMgr : public TimerMgr {
|
||||
public:
|
||||
PQ_TimerMgr(const Tag& arg_tag);
|
||||
~PQ_TimerMgr();
|
||||
explicit PQ_TimerMgr(const Tag& arg_tag);
|
||||
~PQ_TimerMgr() override;
|
||||
|
||||
void Add(Timer* timer);
|
||||
void Expire();
|
||||
void Add(Timer* timer) override;
|
||||
void Expire() override;
|
||||
|
||||
int Size() const { return q->Size(); }
|
||||
int PeakSize() const { return q->PeakSize(); }
|
||||
uint64 CumulativeNum() const { return q->CumulativeNum(); }
|
||||
unsigned int MemoryUsage() const;
|
||||
int Size() const override { return q->Size(); }
|
||||
int PeakSize() const override { return q->PeakSize(); }
|
||||
uint64 CumulativeNum() const override { return q->CumulativeNum(); }
|
||||
|
||||
protected:
|
||||
int DoAdvance(double t, int max_expire);
|
||||
void Remove(Timer* timer);
|
||||
int DoAdvance(double t, int max_expire) override;
|
||||
void Remove(Timer* timer) override;
|
||||
|
||||
Timer* Remove() { return (Timer*) q->Remove(); }
|
||||
Timer* Top() { return (Timer*) q->Top(); }
|
||||
|
@ -164,20 +163,20 @@ protected:
|
|||
|
||||
class CQ_TimerMgr : public TimerMgr {
|
||||
public:
|
||||
CQ_TimerMgr(const Tag& arg_tag);
|
||||
~CQ_TimerMgr();
|
||||
explicit CQ_TimerMgr(const Tag& arg_tag);
|
||||
~CQ_TimerMgr() override;
|
||||
|
||||
void Add(Timer* timer);
|
||||
void Expire();
|
||||
void Add(Timer* timer) override;
|
||||
void Expire() override;
|
||||
|
||||
int Size() const { return cq_size(cq); }
|
||||
int PeakSize() const { return cq_max_size(cq); }
|
||||
uint64 CumulativeNum() const { return cq_cumulative_num(cq); }
|
||||
int Size() const override { return cq_size(cq); }
|
||||
int PeakSize() const override { return cq_max_size(cq); }
|
||||
uint64 CumulativeNum() const override { return cq_cumulative_num(cq); }
|
||||
unsigned int MemoryUsage() const;
|
||||
|
||||
protected:
|
||||
int DoAdvance(double t, int max_expire);
|
||||
void Remove(Timer* timer);
|
||||
int DoAdvance(double t, int max_expire) override;
|
||||
void Remove(Timer* timer) override;
|
||||
|
||||
struct cq_handle *cq;
|
||||
};
|
||||
|
|
|
@ -9,6 +9,10 @@ TraversalCode traverse_all(TraversalCallback* cb)
|
|||
if ( ! global_scope() )
|
||||
return TC_CONTINUE;
|
||||
|
||||
if ( ! stmts )
|
||||
// May be null when parsing fails.
|
||||
return TC_CONTINUE;
|
||||
|
||||
cb->current_scope = global_scope();
|
||||
|
||||
TraversalCode tc = global_scope()->Traverse(cb);
|
||||
|
|
|
@ -136,12 +136,12 @@ Trigger::Trigger(Expr* arg_cond, Stmt* arg_body, Stmt* arg_timeout_stmts,
|
|||
|
||||
if ( timeout_val )
|
||||
{
|
||||
Unref(timeout_val);
|
||||
timeout_value = timeout_val->AsInterval();
|
||||
Unref(timeout_val);
|
||||
}
|
||||
|
||||
// Make sure we don't get deleted if somebody calls a method like
|
||||
// Timeout() while evaluating the trigger.
|
||||
// Timeout() while evaluating the trigger.
|
||||
Ref(this);
|
||||
|
||||
if ( ! Eval() && timeout_value >= 0 )
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
// right away.
|
||||
Trigger(Expr* cond, Stmt* body, Stmt* timeout_stmts, Expr* timeout,
|
||||
Frame* f, bool is_return, const Location* loc);
|
||||
~Trigger();
|
||||
~Trigger() override;
|
||||
|
||||
// Evaluates the condition. If true, executes the body and deletes
|
||||
// the object deleted.
|
||||
|
@ -57,16 +57,16 @@ public:
|
|||
|
||||
bool Disabled() const { return disabled; }
|
||||
|
||||
virtual void Describe(ODesc* d) const { d->Add("<trigger>"); }
|
||||
|
||||
void Describe(ODesc* d) const override
|
||||
{ d->Add("<trigger>"); }
|
||||
// Overidden from Notifier. We queue the trigger and evaluate it
|
||||
// later to avoid race conditions.
|
||||
virtual void Access(ID* id, const StateAccess& sa)
|
||||
void Access(ID* id, const StateAccess& sa) override
|
||||
{ QueueTrigger(this); }
|
||||
virtual void Access(Val* val, const StateAccess& sa)
|
||||
void Access(Val* val, const StateAccess& sa) override
|
||||
{ QueueTrigger(this); }
|
||||
|
||||
virtual const char* Name() const;
|
||||
const char* Name() const override;
|
||||
|
||||
static void QueueTrigger(Trigger* trigger);
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ RecordVal* EncapsulatingConn::GetRecordVal() const
|
|||
|
||||
RecordVal* id_val = new RecordVal(conn_id);
|
||||
id_val->Assign(0, new AddrVal(src_addr));
|
||||
id_val->Assign(1, new PortVal(ntohs(src_port), proto));
|
||||
id_val->Assign(1, port_mgr->Get(ntohs(src_port), proto));
|
||||
id_val->Assign(2, new AddrVal(dst_addr));
|
||||
id_val->Assign(3, new PortVal(ntohs(dst_port), proto));
|
||||
id_val->Assign(3, port_mgr->Get(ntohs(dst_port), proto));
|
||||
rv->Assign(0, id_val);
|
||||
rv->Assign(1, new EnumVal(type, BifType::Enum::Tunnel::Type));
|
||||
|
||||
|
|
15
src/Type.cc
15
src/Type.cc
|
@ -545,7 +545,7 @@ bool IndexType::DoUnserialize(UnserialInfo* info)
|
|||
DO_UNSERIALIZE(BroType);
|
||||
|
||||
UNSERIALIZE_OPTIONAL(yield_type, BroType::Unserialize(info));
|
||||
indices = (TypeList*) BroType::Unserialize(info, TYPE_LIST);
|
||||
indices = (TypeList*) BroType::Unserialize(info);
|
||||
return indices != 0;
|
||||
}
|
||||
|
||||
|
@ -865,11 +865,11 @@ bool FuncType::DoUnserialize(UnserialInfo* info)
|
|||
|
||||
UNSERIALIZE_OPTIONAL(yield, BroType::Unserialize(info));
|
||||
|
||||
args = (RecordType*) BroType::Unserialize(info, TYPE_RECORD);
|
||||
args = (RecordType*) BroType::Unserialize(info);
|
||||
if ( ! args )
|
||||
return false;
|
||||
|
||||
arg_types = (TypeList*) BroType::Unserialize(info, TYPE_LIST);
|
||||
arg_types = (TypeList*) BroType::Unserialize(info);
|
||||
if ( ! arg_types )
|
||||
return false;
|
||||
|
||||
|
@ -1185,7 +1185,14 @@ void RecordType::DescribeFieldsReST(ODesc* d, bool func_args) const
|
|||
if ( d->FindType(td->type) )
|
||||
d->Add("<recursion>");
|
||||
else
|
||||
td->DescribeReST(d);
|
||||
{
|
||||
if ( num_fields == 1 && streq(td->id, "va_args") &&
|
||||
td->type->Tag() == TYPE_ANY )
|
||||
// This was a BIF using variable argument list
|
||||
d->Add("...");
|
||||
else
|
||||
td->DescribeReST(d);
|
||||
}
|
||||
|
||||
if ( func_args )
|
||||
continue;
|
||||
|
|
45
src/Type.h
45
src/Type.h
|
@ -82,8 +82,8 @@ const int MATCHES_INDEX_VECTOR = 2;
|
|||
|
||||
class BroType : public BroObj {
|
||||
public:
|
||||
BroType(TypeTag tag, bool base_type = false);
|
||||
~BroType() { }
|
||||
explicit BroType(TypeTag tag, bool base_type = false);
|
||||
~BroType() override { }
|
||||
|
||||
BroType* Clone() const;
|
||||
|
||||
|
@ -249,7 +249,7 @@ public:
|
|||
|
||||
BroType* Ref() { ::Ref(this); return this; }
|
||||
|
||||
virtual void Describe(ODesc* d) const override;
|
||||
void Describe(ODesc* d) const override;
|
||||
virtual void DescribeReST(ODesc* d, bool roles_only = false) const;
|
||||
|
||||
virtual unsigned MemoryAllocation() const;
|
||||
|
@ -265,7 +265,7 @@ public:
|
|||
static std::set<BroType*> GetAliases(const std::string& type_name)
|
||||
{ return BroType::type_aliases[type_name]; }
|
||||
|
||||
static void AddAlias(const std::string type_name, BroType* type)
|
||||
static void AddAlias(const std::string &type_name, BroType* type)
|
||||
{ BroType::type_aliases[type_name].insert(type); }
|
||||
|
||||
protected:
|
||||
|
@ -287,13 +287,13 @@ private:
|
|||
|
||||
class TypeList : public BroType {
|
||||
public:
|
||||
TypeList(BroType* arg_pure_type = 0) : BroType(TYPE_LIST)
|
||||
explicit TypeList(BroType* arg_pure_type = 0) : BroType(TYPE_LIST)
|
||||
{
|
||||
pure_type = arg_pure_type;
|
||||
if ( pure_type )
|
||||
pure_type->Ref();
|
||||
}
|
||||
~TypeList();
|
||||
~TypeList() override;
|
||||
|
||||
const type_list* Types() const { return &types; }
|
||||
type_list* Types() { return &types; }
|
||||
|
@ -352,7 +352,7 @@ protected:
|
|||
indices = arg_indices;
|
||||
yield_type = arg_yield_type;
|
||||
}
|
||||
~IndexType();
|
||||
~IndexType() override;
|
||||
|
||||
DECLARE_SERIAL(IndexType)
|
||||
|
||||
|
@ -379,7 +379,7 @@ protected:
|
|||
class SetType : public TableType {
|
||||
public:
|
||||
SetType(TypeList* ind, ListExpr* arg_elements);
|
||||
~SetType();
|
||||
~SetType() override;
|
||||
|
||||
ListExpr* SetElements() const { return elements; }
|
||||
|
||||
|
@ -395,7 +395,7 @@ class FuncType : public BroType {
|
|||
public:
|
||||
FuncType(RecordType* args, BroType* yield, function_flavor f);
|
||||
|
||||
~FuncType();
|
||||
~FuncType() override;
|
||||
|
||||
RecordType* Args() const { return args; }
|
||||
BroType* YieldType() override;
|
||||
|
@ -428,8 +428,8 @@ protected:
|
|||
|
||||
class TypeType : public BroType {
|
||||
public:
|
||||
TypeType(BroType* t) : BroType(TYPE_TYPE) { type = t->Ref(); }
|
||||
~TypeType() { Unref(type); }
|
||||
explicit TypeType(BroType* t) : BroType(TYPE_TYPE) { type = t->Ref(); }
|
||||
~TypeType() override { Unref(type); }
|
||||
|
||||
BroType* Type() { return type; }
|
||||
|
||||
|
@ -460,9 +460,9 @@ public:
|
|||
|
||||
class RecordType : public BroType {
|
||||
public:
|
||||
RecordType(type_decl_list* types);
|
||||
explicit RecordType(type_decl_list* types);
|
||||
|
||||
~RecordType();
|
||||
~RecordType() override;
|
||||
|
||||
int HasField(const char* field) const override;
|
||||
BroType* FieldType(const char* field) const override;
|
||||
|
@ -512,8 +512,8 @@ protected:
|
|||
|
||||
class FileType : public BroType {
|
||||
public:
|
||||
FileType(BroType* yield_type);
|
||||
~FileType();
|
||||
explicit FileType(BroType* yield_type);
|
||||
~FileType() override;
|
||||
|
||||
BroType* YieldType() override;
|
||||
|
||||
|
@ -529,8 +529,8 @@ protected:
|
|||
|
||||
class OpaqueType : public BroType {
|
||||
public:
|
||||
OpaqueType(const string& name);
|
||||
virtual ~OpaqueType() { };
|
||||
explicit OpaqueType(const string& name);
|
||||
~OpaqueType() override { };
|
||||
|
||||
const string& Name() const { return name; }
|
||||
|
||||
|
@ -549,9 +549,9 @@ class EnumType : public BroType {
|
|||
public:
|
||||
typedef std::list<std::pair<string, bro_int_t> > enum_name_list;
|
||||
|
||||
EnumType(EnumType* e);
|
||||
EnumType(const string& arg_name);
|
||||
~EnumType();
|
||||
explicit EnumType(EnumType* e);
|
||||
explicit EnumType(const string& arg_name);
|
||||
~EnumType() override;
|
||||
|
||||
// The value of this name is next internal counter value, starting
|
||||
// with zero. The internal counter is incremented.
|
||||
|
@ -598,8 +598,8 @@ protected:
|
|||
|
||||
class VectorType : public BroType {
|
||||
public:
|
||||
VectorType(BroType* t);
|
||||
virtual ~VectorType();
|
||||
explicit VectorType(BroType* t);
|
||||
~VectorType() override;
|
||||
BroType* YieldType() override;
|
||||
const BroType* YieldType() const;
|
||||
|
||||
|
@ -628,6 +628,7 @@ extern OpaqueType* cardinality_type;
|
|||
extern OpaqueType* topk_type;
|
||||
extern OpaqueType* bloomfilter_type;
|
||||
extern OpaqueType* x509_opaque_type;
|
||||
extern OpaqueType* ocsp_resp_opaque_type;
|
||||
|
||||
// Returns the Bro basic (non-parameterized) type with the given type.
|
||||
// The reference count of the type is not increased.
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
* Construct a UID of a given bit-length, optionally from given values.
|
||||
* @see UID::Set
|
||||
*/
|
||||
UID(bro_uint_t bits, const uint64* v = 0, size_t n = 0)
|
||||
explicit UID(bro_uint_t bits, const uint64* v = 0, size_t n = 0)
|
||||
{ Set(bits, v, n); }
|
||||
|
||||
/**
|
||||
|
@ -59,9 +59,8 @@ public:
|
|||
/**
|
||||
* @return false if the UID instance was created via the default ctor
|
||||
* and not yet initialized w/ Set().
|
||||
* TODO: this would be better as an "explicit" conversion operator (C++11)
|
||||
*/
|
||||
operator bool() const
|
||||
explicit operator bool() const
|
||||
{ return initialized; }
|
||||
|
||||
/**
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue