mirror of
https://github.com/zeek/zeek.git
synced 2025-10-09 18:18:19 +00:00
Merge remote-tracking branch 'origin/master' into topic/bernhard/file-analysis-x509
Conflicts: src/analyzer/protocol/ssl/events.bif src/analyzer/protocol/ssl/ssl-analyzer.pac
This commit is contained in:
commit
30860e4226
87 changed files with 1120 additions and 382 deletions
|
@ -1 +1 @@
|
|||
Subproject commit 42a4c9694a2b2677b050fbb7cbae26bc5ec4605a
|
||||
Subproject commit e96d95a130a572b611fe70b3c3ede2b4727aaa22
|
|
@ -48,6 +48,7 @@ int tcp_max_above_hole_without_any_acks;
|
|||
int tcp_excessive_data_without_further_acks;
|
||||
|
||||
RecordType* x509_type;
|
||||
RecordType* x509_extension_type;
|
||||
|
||||
RecordType* socks_address;
|
||||
|
||||
|
@ -356,6 +357,7 @@ void init_net_var()
|
|||
opt_internal_int("tcp_excessive_data_without_further_acks");
|
||||
|
||||
x509_type = internal_type("X509")->AsRecordType();
|
||||
x509_extension_type = internal_type("X509_extension_info")->AsRecordType();
|
||||
|
||||
socks_address = internal_type("SOCKS::Address")->AsRecordType();
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ extern int tcp_max_above_hole_without_any_acks;
|
|||
extern int tcp_excessive_data_without_further_acks;
|
||||
|
||||
extern RecordType* x509_type;
|
||||
extern RecordType* x509_extension_type;
|
||||
|
||||
extern RecordType* socks_address;
|
||||
|
||||
|
|
|
@ -229,12 +229,21 @@ void PktSrc::Process()
|
|||
{
|
||||
// MPLS carried over the ethernet frame.
|
||||
case 0x8847:
|
||||
// Remove the data link layer and denote a
|
||||
// header size of zero before the IP header.
|
||||
have_mpls = true;
|
||||
data += get_link_header_size(datalink);
|
||||
pkt_hdr_size = 0;
|
||||
break;
|
||||
|
||||
// VLAN carried over the ethernet frame.
|
||||
case 0x8100:
|
||||
data += get_link_header_size(datalink);
|
||||
|
||||
// Check for MPLS in VLAN.
|
||||
if ( ((data[2] << 8) + data[3]) == 0x8847 )
|
||||
have_mpls = true;
|
||||
|
||||
data += 4; // Skip the vlan header
|
||||
pkt_hdr_size = 0;
|
||||
|
||||
|
@ -274,8 +283,13 @@ void PktSrc::Process()
|
|||
protocol = (data[2] << 8) + data[3];
|
||||
|
||||
if ( protocol == 0x0281 )
|
||||
// MPLS Unicast
|
||||
{
|
||||
// MPLS Unicast. Remove the data link layer and
|
||||
// denote a header size of zero before the IP header.
|
||||
have_mpls = true;
|
||||
data += get_link_header_size(datalink);
|
||||
pkt_hdr_size = 0;
|
||||
}
|
||||
|
||||
else if ( protocol != 0x0021 && protocol != 0x0057 )
|
||||
{
|
||||
|
@ -290,12 +304,6 @@ void PktSrc::Process()
|
|||
|
||||
if ( have_mpls )
|
||||
{
|
||||
// Remove the data link layer
|
||||
data += get_link_header_size(datalink);
|
||||
|
||||
// Denote a header size of zero before the IP header
|
||||
pkt_hdr_size = 0;
|
||||
|
||||
// Skip the MPLS label stack.
|
||||
bool end_of_stack = false;
|
||||
|
||||
|
|
|
@ -137,18 +137,6 @@ int DNS_Interpreter::ParseQuestions(DNS_MsgInfo* msg,
|
|||
{
|
||||
int n = msg->qdcount;
|
||||
|
||||
if ( n == 0 )
|
||||
{
|
||||
// Generate event here because we won't go into ParseQuestion.
|
||||
EventHandlerPtr dns_event =
|
||||
msg->rcode == DNS_CODE_OK ?
|
||||
dns_query_reply : dns_rejected;
|
||||
BroString* question_name = new BroString("<no query>");
|
||||
|
||||
SendReplyOrRejectEvent(msg, dns_event, data, len, question_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while ( n > 0 && ParseQuestion(msg, data, len, msg_start) )
|
||||
--n;
|
||||
return n == 0;
|
||||
|
@ -299,6 +287,16 @@ int DNS_Interpreter::ParseAnswer(DNS_MsgInfo* msg,
|
|||
break;
|
||||
|
||||
default:
|
||||
|
||||
if ( dns_unknown_reply && ! msg->skip_event )
|
||||
{
|
||||
val_list* vl = new val_list;
|
||||
vl->append(analyzer->BuildConnVal());
|
||||
vl->append(msg->BuildHdrVal());
|
||||
vl->append(msg->BuildAnswerVal());
|
||||
analyzer->ConnectionEvent(dns_unknown_reply, vl);
|
||||
}
|
||||
|
||||
analyzer->Weird("DNS_RR_unknown_type");
|
||||
data += rdlength;
|
||||
len -= rdlength;
|
||||
|
|
|
@ -50,7 +50,7 @@ event dns_message%(c: connection, is_orig: bool, msg: dns_msg, len: count%);
|
|||
event dns_request%(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count%);
|
||||
|
||||
## Generated for DNS replies that reject a query. This event is raised if a DNS
|
||||
## reply either indicates failure via its status code or does not pass on any
|
||||
## reply indicates failure because it does not pass on any
|
||||
## answers to a query. Note that all of the event's parameters are parsed out of
|
||||
## the reply; there's no stateful correlation with the query.
|
||||
##
|
||||
|
@ -78,7 +78,7 @@ event dns_request%(c: connection, msg: dns_msg, query: string, qtype: count, qcl
|
|||
## dns_skip_all_addl dns_skip_all_auth dns_skip_auth
|
||||
event dns_rejected%(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count%);
|
||||
|
||||
## Generated for DNS replies with an *ok* status code but no question section.
|
||||
## Generated for each entry in the Question section of a DNS reply.
|
||||
##
|
||||
## See `Wikipedia <http://en.wikipedia.org/wiki/Domain_Name_System>`__ for more
|
||||
## information about the DNS protocol. Bro analyzes both UDP and TCP DNS
|
||||
|
@ -401,6 +401,22 @@ event dns_TXT_reply%(c: connection, msg: dns_msg, ans: dns_answer, str: string%)
|
|||
## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth
|
||||
event dns_SRV_reply%(c: connection, msg: dns_msg, ans: dns_answer%);
|
||||
|
||||
## Generated on DNS reply resource records when the type of record is not one
|
||||
## that Bro knows how to parse and generate another more specific specific
|
||||
## event.
|
||||
##
|
||||
## c: The connection, which may be UDP or TCP depending on the type of the
|
||||
## transport-layer session being analyzed.
|
||||
##
|
||||
## msg: The parsed DNS message header.
|
||||
##
|
||||
## ans: The type-independent part of the parsed answer record.
|
||||
##
|
||||
## .. bro:see:: dns_AAAA_reply dns_A_reply dns_CNAME_reply dns_EDNS_addl
|
||||
## dns_HINFO_reply dns_MX_reply dns_NS_reply dns_PTR_reply dns_SOA_reply
|
||||
## dns_TSIG_addl dns_TXT_reply dns_WKS_reply dns_SRV_reply dns_end
|
||||
event dns_unknown_reply%(c: connection, msg: dns_msg, ans: dns_answer%);
|
||||
|
||||
## Generated for DNS replies of type *EDNS*. For replies with multiple answers,
|
||||
## an individual event of the corresponding type is raised for each.
|
||||
##
|
||||
|
|
|
@ -242,10 +242,17 @@ int HTTP_Entity::Undelivered(int64_t len)
|
|||
if ( end_of_data && in_header )
|
||||
return 0;
|
||||
|
||||
file_mgr->Gap(body_length, len,
|
||||
http_message->MyHTTP_Analyzer()->GetAnalyzerTag(),
|
||||
http_message->MyHTTP_Analyzer()->Conn(),
|
||||
http_message->IsOrig());
|
||||
if ( is_partial_content )
|
||||
file_mgr->Gap(body_length, len,
|
||||
http_message->MyHTTP_Analyzer()->GetAnalyzerTag(),
|
||||
http_message->MyHTTP_Analyzer()->Conn(),
|
||||
http_message->IsOrig());
|
||||
else
|
||||
precomputed_file_id = file_mgr->Gap(body_length, len,
|
||||
http_message->MyHTTP_Analyzer()->GetAnalyzerTag(),
|
||||
http_message->MyHTTP_Analyzer()->Conn(),
|
||||
http_message->IsOrig(),
|
||||
precomputed_file_id);
|
||||
|
||||
if ( chunked_transfer_state != NON_CHUNKED_TRANSFER )
|
||||
{
|
||||
|
@ -314,15 +321,18 @@ void HTTP_Entity::SubmitData(int len, const char* buf)
|
|||
else
|
||||
{
|
||||
if ( send_size && content_length > 0 )
|
||||
file_mgr->SetSize(content_length,
|
||||
precomputed_file_id = file_mgr->SetSize(content_length,
|
||||
http_message->MyHTTP_Analyzer()->GetAnalyzerTag(),
|
||||
http_message->MyHTTP_Analyzer()->Conn(),
|
||||
http_message->IsOrig());
|
||||
http_message->IsOrig(),
|
||||
precomputed_file_id);
|
||||
|
||||
file_mgr->DataIn(reinterpret_cast<const u_char*>(buf), len,
|
||||
precomputed_file_id = file_mgr->DataIn(reinterpret_cast<const u_char*>(buf),
|
||||
len,
|
||||
http_message->MyHTTP_Analyzer()->GetAnalyzerTag(),
|
||||
http_message->MyHTTP_Analyzer()->Conn(),
|
||||
http_message->IsOrig());
|
||||
http_message->IsOrig(),
|
||||
precomputed_file_id);
|
||||
}
|
||||
|
||||
send_size = false;
|
||||
|
|
|
@ -64,6 +64,7 @@ protected:
|
|||
uint64_t offset;
|
||||
int64_t instance_length; // total length indicated by content-range
|
||||
bool send_size; // whether to send size indication to FAF
|
||||
std::string precomputed_file_id;
|
||||
|
||||
MIME_Entity* NewChildEntity() { return new HTTP_Entity(http_message, this, 1); }
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
%header{
|
||||
VectorVal* bytestring_to_coils(bytestring coils, uint quantity);
|
||||
RecordVal* HeaderToBro(ModbusTCP_TransportHeader *header);
|
||||
VectorVal* create_vector_of_count();
|
||||
%}
|
||||
|
||||
%code{
|
||||
|
@ -30,6 +31,14 @@
|
|||
return modbus_header;
|
||||
}
|
||||
|
||||
VectorVal* create_vector_of_count()
|
||||
{
|
||||
VectorType* vt = new VectorType(base_type(TYPE_COUNT));
|
||||
VectorVal* vv = new VectorVal(vt);
|
||||
Unref(vt);
|
||||
return vv;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
refine flow ModbusTCP_Flow += {
|
||||
|
@ -367,7 +376,7 @@ refine flow ModbusTCP_Flow += {
|
|||
if ( ::modbus_read_file_record_request )
|
||||
{
|
||||
//TODO: this need to be a vector of some Reference Request record type
|
||||
//VectorVal *t = new VectorVal(new VectorType(base_type(TYPE_COUNT)));
|
||||
//VectorVal *t = create_vector_of_count();
|
||||
//for ( unsigned int i = 0; i < (${message.references}->size()); ++i )
|
||||
// {
|
||||
// Val* r = new Val((${message.references[i].ref_type}), TYPE_COUNT);
|
||||
|
@ -393,7 +402,7 @@ refine flow ModbusTCP_Flow += {
|
|||
%{
|
||||
if ( ::modbus_read_file_record_response )
|
||||
{
|
||||
//VectorVal *t = new VectorVal(new VectorType(base_type(TYPE_COUNT)));
|
||||
//VectorVal *t = create_vector_of_count();
|
||||
//for ( unsigned int i = 0; i < ${message.references}->size(); ++i )
|
||||
// {
|
||||
// //TODO: work the reference type in here somewhere
|
||||
|
@ -414,7 +423,7 @@ refine flow ModbusTCP_Flow += {
|
|||
%{
|
||||
if ( ::modbus_write_file_record_request )
|
||||
{
|
||||
//VectorVal* t = new VectorVal(new VectorType(base_type(TYPE_COUNT)));
|
||||
//VectorVal* t = create_vector_of_count();
|
||||
//for ( unsigned int i = 0; i < (${message.references}->size()); ++i )
|
||||
// {
|
||||
// Val* r = new Val((${message.references[i].ref_type}), TYPE_COUNT);
|
||||
|
@ -447,7 +456,7 @@ refine flow ModbusTCP_Flow += {
|
|||
%{
|
||||
if ( ::modbus_write_file_record_response )
|
||||
{
|
||||
//VectorVal* t = new VectorVal(new VectorType(base_type(TYPE_COUNT)));
|
||||
//VectorVal* t = create_vector_of_count();
|
||||
//for ( unsigned int i = 0; i < (${messages.references}->size()); ++i )
|
||||
// {
|
||||
// Val* r = new Val((${message.references[i].ref_type}), TYPE_COUNT);
|
||||
|
@ -589,7 +598,7 @@ refine flow ModbusTCP_Flow += {
|
|||
|
||||
if ( ::modbus_read_fifo_queue_response )
|
||||
{
|
||||
VectorVal* t = new VectorVal(new VectorType(base_type(TYPE_COUNT)));
|
||||
VectorVal* t = create_vector_of_count();
|
||||
for ( unsigned int i = 0; i < (${message.register_data})->size(); ++i )
|
||||
{
|
||||
Val* r = new Val(${message.register_data[i]}, TYPE_COUNT);
|
||||
|
|
|
@ -192,14 +192,13 @@ void POP3_Analyzer::ProcessRequest(int length, const char* line)
|
|||
|
||||
case AUTH_CRAM_MD5:
|
||||
{ // Format: "user<space>password-hash"
|
||||
char* s;
|
||||
char* str = (char*) decoded->CheckString();
|
||||
const char* s;
|
||||
const char* str = (char*) decoded->CheckString();
|
||||
|
||||
for ( s = str; *s && *s != '\t' && *s != ' '; ++s )
|
||||
;
|
||||
*s = '\0';
|
||||
|
||||
user = str;
|
||||
user = std::string(str, s);
|
||||
password = "";
|
||||
|
||||
break;
|
||||
|
|
|
@ -62,6 +62,14 @@ refine connection SOCKS_Conn += {
|
|||
if ( ${request.reserved} != 0 )
|
||||
{
|
||||
bro_analyzer()->ProtocolViolation(fmt("invalid value in reserved field: %d", ${request.reserved}));
|
||||
bro_analyzer()->SetSkip(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( (${request.command} == 0) || (${request.command} > 3) )
|
||||
{
|
||||
bro_analyzer()->ProtocolViolation(fmt("undefined value in command field: %d", ${request.command}));
|
||||
bro_analyzer()->SetSkip(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -105,7 +113,7 @@ refine connection SOCKS_Conn += {
|
|||
function socks5_reply(reply: SOCKS5_Reply): bool
|
||||
%{
|
||||
RecordVal* sa = new RecordVal(socks_address);
|
||||
|
||||
|
||||
// This is dumb and there must be a better way (checking for presence of a field)...
|
||||
switch ( ${reply.bound.addr_type} )
|
||||
{
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
## :bro:id:`SSL::cipher_desc` table maps them to descriptive names.
|
||||
##
|
||||
## .. bro:see:: ssl_alert ssl_established ssl_extension ssl_server_hello
|
||||
event ssl_client_hello%(c: connection, version: count, possible_ts: time, session_id: string, ciphers: count_set%);
|
||||
## ssl_session_ticket_handshake x509_certificate x509_error x509_extension
|
||||
event ssl_client_hello%(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec%);
|
||||
|
||||
|
|
|
@ -194,7 +194,7 @@ refine connection SSL_Conn += {
|
|||
|
||||
BifEvent::generate_ssl_server_hello(bro_analyzer(),
|
||||
bro_analyzer()->Conn(),
|
||||
version, ts, new StringVal(server_random.length(),
|
||||
version, ts, new StringVal(server_random.length(),
|
||||
(const char*) server_random.data()),
|
||||
to_string_val(session_id),
|
||||
ciphers->size()==0 ? 0 : ciphers->at(0), comp_method);
|
||||
|
|
|
@ -373,14 +373,11 @@ void TCP_Analyzer::ProcessSYN(const IP_Hdr* ip, const struct tcphdr* tp,
|
|||
void TCP_Analyzer::ProcessFIN(double t, TCP_Endpoint* endpoint,
|
||||
int& seq_len, uint32 base_seq)
|
||||
{
|
||||
if ( endpoint->FIN_cnt == 0 )
|
||||
{
|
||||
++seq_len; // FIN consumes a byte of sequence space
|
||||
++endpoint->FIN_cnt; // remember that we've seen a FIN
|
||||
}
|
||||
++seq_len; // FIN consumes a byte of sequence space.
|
||||
++endpoint->FIN_cnt; // remember that we've seen a FIN
|
||||
|
||||
else if ( t < endpoint->last_time + tcp_storm_interarrival_thresh &&
|
||||
++endpoint->FIN_cnt == tcp_storm_thresh )
|
||||
if ( t < endpoint->last_time + tcp_storm_interarrival_thresh &&
|
||||
endpoint->FIN_cnt == tcp_storm_thresh )
|
||||
Weird("FIN_storm");
|
||||
|
||||
// Remember the relative seq in FIN_seq.
|
||||
|
|
|
@ -161,6 +161,13 @@ void TCP_Endpoint::SetState(EndpointState new_state)
|
|||
|
||||
bro_int_t TCP_Endpoint::Size() const
|
||||
{
|
||||
if ( prev_state == TCP_ENDPOINT_SYN_SENT && state == TCP_ENDPOINT_RESET &&
|
||||
peer->state == TCP_ENDPOINT_INACTIVE && ! NoDataAcked() )
|
||||
// This looks like a half-open connection was discovered and aborted.
|
||||
// Sequence numbers could be misleading if used in context of data size
|
||||
// and there was never a chance for this endpoint to send data anyway.
|
||||
return 0;
|
||||
|
||||
bro_int_t size;
|
||||
|
||||
uint64 last_seq_64 = (uint64(last_seq_high) << 32) | last_seq;
|
||||
|
|
|
@ -178,7 +178,7 @@ void TCP_Reassembler::Undelivered(int up_to_seq)
|
|||
// to this method and only if this condition is not true).
|
||||
reporter->InternalError("Calling Undelivered for data that has already been delivered (or has already been marked as undelivered");
|
||||
|
||||
if ( last_reassem_seq == 1 &&
|
||||
if ( BifConst::detect_filtered_trace && last_reassem_seq == 1 &&
|
||||
(endpoint->FIN_cnt > 0 || endpoint->RST_cnt > 0 ||
|
||||
peer->FIN_cnt > 0 || peer->RST_cnt > 0) )
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
const ignore_keep_alive_rexmit: bool;
|
||||
const skip_http_data: bool;
|
||||
const use_conn_size_analyzer: bool;
|
||||
const detect_filtered_trace: bool;
|
||||
const report_gaps_for_partial: bool;
|
||||
const exit_only_after_terminate: bool;
|
||||
|
||||
|
|
|
@ -103,7 +103,6 @@ File::~File()
|
|||
DBG_LOG(DBG_FILE_ANALYSIS, "Destroying File object %s", id.c_str());
|
||||
Unref(val);
|
||||
|
||||
// Queue may not be empty in the case where only content gaps were seen.
|
||||
while ( ! fonc_queue.empty() )
|
||||
{
|
||||
delete_vals(fonc_queue.front().second);
|
||||
|
@ -460,20 +459,27 @@ void File::FileEvent(EventHandlerPtr h)
|
|||
FileEvent(h, vl);
|
||||
}
|
||||
|
||||
static void flush_file_event_queue(queue<pair<EventHandlerPtr, val_list*> >& q)
|
||||
{
|
||||
while ( ! q.empty() )
|
||||
{
|
||||
pair<EventHandlerPtr, val_list*> p = q.front();
|
||||
mgr.QueueEvent(p.first, p.second);
|
||||
q.pop();
|
||||
}
|
||||
}
|
||||
|
||||
void File::FileEvent(EventHandlerPtr h, val_list* vl)
|
||||
{
|
||||
if ( h == file_state_remove )
|
||||
flush_file_event_queue(fonc_queue);
|
||||
|
||||
mgr.QueueEvent(h, vl);
|
||||
|
||||
if ( h == file_new )
|
||||
{
|
||||
did_file_new_event = true;
|
||||
|
||||
while ( ! fonc_queue.empty() )
|
||||
{
|
||||
pair<EventHandlerPtr, val_list*> p = fonc_queue.front();
|
||||
mgr.QueueEvent(p.first, p.second);
|
||||
fonc_queue.pop();
|
||||
}
|
||||
flush_file_event_queue(fonc_queue);
|
||||
}
|
||||
|
||||
if ( h == file_new || h == file_timeout || h == file_extraction_limit )
|
||||
|
|
|
@ -75,36 +75,47 @@ void Manager::SetHandle(const string& handle)
|
|||
current_file_id = HashHandle(handle);
|
||||
}
|
||||
|
||||
void Manager::DataIn(const u_char* data, uint64 len, uint64 offset,
|
||||
analyzer::Tag tag, Connection* conn, bool is_orig)
|
||||
string Manager::DataIn(const u_char* data, uint64 len, uint64 offset,
|
||||
analyzer::Tag tag, Connection* conn, bool is_orig,
|
||||
const string& precomputed_id)
|
||||
{
|
||||
GetFileHandle(tag, conn, is_orig);
|
||||
File* file = GetFile(current_file_id, conn, tag, is_orig);
|
||||
string id = precomputed_id.empty() ? GetFileID(tag, conn, is_orig) : precomputed_id;
|
||||
File* file = GetFile(id, conn, tag, is_orig);
|
||||
|
||||
if ( ! file )
|
||||
return;
|
||||
return "";
|
||||
|
||||
file->DataIn(data, len, offset);
|
||||
|
||||
if ( file->IsComplete() )
|
||||
{
|
||||
RemoveFile(file->GetID());
|
||||
return "";
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void Manager::DataIn(const u_char* data, uint64 len, analyzer::Tag tag,
|
||||
Connection* conn, bool is_orig)
|
||||
string Manager::DataIn(const u_char* data, uint64 len, analyzer::Tag tag,
|
||||
Connection* conn, bool is_orig, const string& precomputed_id)
|
||||
{
|
||||
GetFileHandle(tag, conn, is_orig);
|
||||
string id = precomputed_id.empty() ? GetFileID(tag, conn, is_orig) : precomputed_id;
|
||||
// Sequential data input shouldn't be going over multiple conns, so don't
|
||||
// do the check to update connection set.
|
||||
File* file = GetFile(current_file_id, conn, tag, is_orig, false);
|
||||
File* file = GetFile(id, conn, tag, is_orig, false);
|
||||
|
||||
if ( ! file )
|
||||
return;
|
||||
return "";
|
||||
|
||||
file->DataIn(data, len);
|
||||
|
||||
if ( file->IsComplete() )
|
||||
{
|
||||
RemoveFile(file->GetID());
|
||||
return "";
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void Manager::DataIn(const u_char* data, uint64 len, const string& file_id,
|
||||
|
@ -133,8 +144,7 @@ void Manager::EndOfFile(analyzer::Tag tag, Connection* conn)
|
|||
void Manager::EndOfFile(analyzer::Tag tag, Connection* conn, bool is_orig)
|
||||
{
|
||||
// Don't need to create a file if we're just going to remove it right away.
|
||||
GetFileHandle(tag, conn, is_orig);
|
||||
RemoveFile(current_file_id);
|
||||
RemoveFile(GetFileID(tag, conn, is_orig));
|
||||
}
|
||||
|
||||
void Manager::EndOfFile(const string& file_id)
|
||||
|
@ -142,31 +152,37 @@ void Manager::EndOfFile(const string& file_id)
|
|||
RemoveFile(file_id);
|
||||
}
|
||||
|
||||
void Manager::Gap(uint64 offset, uint64 len, analyzer::Tag tag,
|
||||
Connection* conn, bool is_orig)
|
||||
string Manager::Gap(uint64 offset, uint64 len, analyzer::Tag tag,
|
||||
Connection* conn, bool is_orig, const string& precomputed_id)
|
||||
{
|
||||
GetFileHandle(tag, conn, is_orig);
|
||||
File* file = GetFile(current_file_id, conn, tag, is_orig);
|
||||
string id = precomputed_id.empty() ? GetFileID(tag, conn, is_orig) : precomputed_id;
|
||||
File* file = GetFile(id, conn, tag, is_orig);
|
||||
|
||||
if ( ! file )
|
||||
return;
|
||||
return "";
|
||||
|
||||
file->Gap(offset, len);
|
||||
return id;
|
||||
}
|
||||
|
||||
void Manager::SetSize(uint64 size, analyzer::Tag tag, Connection* conn,
|
||||
bool is_orig)
|
||||
string Manager::SetSize(uint64 size, analyzer::Tag tag, Connection* conn,
|
||||
bool is_orig, const string& precomputed_id)
|
||||
{
|
||||
GetFileHandle(tag, conn, is_orig);
|
||||
File* file = GetFile(current_file_id, conn, tag, is_orig);
|
||||
string id = precomputed_id.empty() ? GetFileID(tag, conn, is_orig) : precomputed_id;
|
||||
File* file = GetFile(id, conn, tag, is_orig);
|
||||
|
||||
if ( ! file )
|
||||
return;
|
||||
return "";
|
||||
|
||||
file->SetTotalBytes(size);
|
||||
|
||||
if ( file->IsComplete() )
|
||||
{
|
||||
RemoveFile(file->GetID());
|
||||
return "";
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
bool Manager::SetTimeoutInterval(const string& file_id, double interval) const
|
||||
|
@ -317,15 +333,15 @@ bool Manager::IsIgnored(const string& file_id)
|
|||
return ignored.find(file_id) != ignored.end();
|
||||
}
|
||||
|
||||
void Manager::GetFileHandle(analyzer::Tag tag, Connection* c, bool is_orig)
|
||||
string Manager::GetFileID(analyzer::Tag tag, Connection* c, bool is_orig)
|
||||
{
|
||||
current_file_id.clear();
|
||||
|
||||
if ( IsDisabled(tag) )
|
||||
return;
|
||||
return "";
|
||||
|
||||
if ( ! get_file_handle )
|
||||
return;
|
||||
return "";
|
||||
|
||||
EnumVal* tagval = tag.AsEnumVal();
|
||||
Ref(tagval);
|
||||
|
@ -337,6 +353,7 @@ void Manager::GetFileHandle(analyzer::Tag tag, Connection* c, bool is_orig)
|
|||
|
||||
mgr.QueueEvent(get_file_handle, vl);
|
||||
mgr.Drain(); // need file handle immediately so we don't have to buffer data
|
||||
return current_file_id;
|
||||
}
|
||||
|
||||
bool Manager::IsDisabled(analyzer::Tag tag)
|
||||
|
|
|
@ -82,9 +82,17 @@ public:
|
|||
* @param conn network connection over which the file data is transferred.
|
||||
* @param is_orig true if the file is being sent from connection originator
|
||||
* or false if is being sent in the opposite direction.
|
||||
* @param precomputed_file_id may be set to a previous return value in order to
|
||||
* bypass costly file handle lookups.
|
||||
* @return a unique file ID string which, in certain contexts, may be
|
||||
* cached and passed back in to a subsequent function call in order
|
||||
* to avoid costly file handle lookups (which have to go through
|
||||
* the \c get_file_handle script-layer event). An empty string
|
||||
* indicates the associate file is not going to be analyzed further.
|
||||
*/
|
||||
void DataIn(const u_char* data, uint64 len, uint64 offset,
|
||||
analyzer::Tag tag, Connection* conn, bool is_orig);
|
||||
std::string DataIn(const u_char* data, uint64 len, uint64 offset,
|
||||
analyzer::Tag tag, Connection* conn, bool is_orig,
|
||||
const std::string& precomputed_file_id = "");
|
||||
|
||||
/**
|
||||
* Pass in sequential file data.
|
||||
|
@ -94,9 +102,17 @@ public:
|
|||
* @param conn network connection over which the file data is transferred.
|
||||
* @param is_orig true if the file is being sent from connection originator
|
||||
* or false if is being sent in the opposite direction.
|
||||
* @param precomputed_file_id may be set to a previous return value in order to
|
||||
* bypass costly file handle lookups.
|
||||
* @return a unique file ID string which, in certain contexts, may be
|
||||
* cached and passed back in to a subsequent function call in order
|
||||
* to avoid costly file handle lookups (which have to go through
|
||||
* the \c get_file_handle script-layer event). An empty string
|
||||
* indicates the associate file is not going to be analyzed further.
|
||||
*/
|
||||
void DataIn(const u_char* data, uint64 len, analyzer::Tag tag,
|
||||
Connection* conn, bool is_orig);
|
||||
std::string DataIn(const u_char* data, uint64 len, analyzer::Tag tag,
|
||||
Connection* conn, bool is_orig,
|
||||
const std::string& precomputed_file_id = "");
|
||||
|
||||
/**
|
||||
* Pass in sequential file data from external source (e.g. input framework).
|
||||
|
@ -140,9 +156,17 @@ public:
|
|||
* @param conn network connection over which the file data is transferred.
|
||||
* @param is_orig true if the file is being sent from connection originator
|
||||
* or false if is being sent in the opposite direction.
|
||||
* @param precomputed_file_id may be set to a previous return value in order to
|
||||
* bypass costly file handle lookups.
|
||||
* @return a unique file ID string which, in certain contexts, may be
|
||||
* cached and passed back in to a subsequent function call in order
|
||||
* to avoid costly file handle lookups (which have to go through
|
||||
* the \c get_file_handle script-layer event). An empty string
|
||||
* indicates the associate file is not going to be analyzed further.
|
||||
*/
|
||||
void Gap(uint64 offset, uint64 len, analyzer::Tag tag, Connection* conn,
|
||||
bool is_orig);
|
||||
std::string Gap(uint64 offset, uint64 len, analyzer::Tag tag,
|
||||
Connection* conn, bool is_orig,
|
||||
const std::string& precomputed_file_id = "");
|
||||
|
||||
/**
|
||||
* Provide the expected number of bytes that comprise a file.
|
||||
|
@ -151,9 +175,16 @@ public:
|
|||
* @param conn network connection over which the file data is transferred.
|
||||
* @param is_orig true if the file is being sent from connection originator
|
||||
* or false if is being sent in the opposite direction.
|
||||
* @param precomputed_file_id may be set to a previous return value in order to
|
||||
* bypass costly file handle lookups.
|
||||
* @return a unique file ID string which, in certain contexts, may be
|
||||
* cached and passed back in to a subsequent function call in order
|
||||
* to avoid costly file handle lookups (which have to go through
|
||||
* the \c get_file_handle script-layer event). An empty string
|
||||
* indicates the associate file is not going to be analyzed further.
|
||||
*/
|
||||
void SetSize(uint64 size, analyzer::Tag tag, Connection* conn,
|
||||
bool is_orig);
|
||||
std::string SetSize(uint64 size, analyzer::Tag tag, Connection* conn,
|
||||
bool is_orig, const std::string& precomputed_file_id = "");
|
||||
|
||||
/**
|
||||
* Starts ignoring a file, which will finally be removed from internal
|
||||
|
@ -283,8 +314,10 @@ protected:
|
|||
* @param conn network connection over which the file is transferred.
|
||||
* @param is_orig true if the file is being sent from connection originator
|
||||
* or false if is being sent in the opposite direction.
|
||||
* @return #current_file_id, which is a hash of a unique file handle string
|
||||
* set by a \c get_file_handle event handler.
|
||||
*/
|
||||
void GetFileHandle(analyzer::Tag tag, Connection* c, bool is_orig);
|
||||
std::string GetFileID(analyzer::Tag tag, Connection* c, bool is_orig);
|
||||
|
||||
/**
|
||||
* Check if analysis is available for files transferred over a given
|
||||
|
|
|
@ -397,7 +397,9 @@ bool Manager::CreateEventStream(RecordVal* fval)
|
|||
string stream_name = name_val->AsString()->CheckString();
|
||||
Unref(name_val);
|
||||
|
||||
RecordType *fields = fval->Lookup("fields", true)->AsType()->AsTypeType()->Type()->AsRecordType();
|
||||
Val* fields_val = fval->Lookup("fields", true);
|
||||
RecordType *fields = fields_val->AsType()->AsTypeType()->Type()->AsRecordType();
|
||||
Unref(fields_val);
|
||||
|
||||
Val *want_record = fval->Lookup("want_record", true);
|
||||
|
||||
|
@ -548,13 +550,17 @@ bool Manager::CreateTableStream(RecordVal* fval)
|
|||
|
||||
Val* pred = fval->Lookup("pred", true);
|
||||
|
||||
RecordType *idx = fval->Lookup("idx", true)->AsType()->AsTypeType()->Type()->AsRecordType();
|
||||
Val* idx_val = fval->Lookup("idx", true);
|
||||
RecordType *idx = idx_val->AsType()->AsTypeType()->Type()->AsRecordType();
|
||||
Unref(idx_val);
|
||||
|
||||
RecordType *val = 0;
|
||||
|
||||
if ( fval->Lookup("val", true) != 0 )
|
||||
Val* val_val = fval->Lookup("val", true);
|
||||
if ( val_val )
|
||||
{
|
||||
val = fval->Lookup("val", true)->AsType()->AsTypeType()->Type()->AsRecordType();
|
||||
Unref(val); // The lookupwithdefault in the if-clause ref'ed val.
|
||||
val = val_val->AsType()->AsTypeType()->Type()->AsRecordType();
|
||||
Unref(val_val);
|
||||
}
|
||||
|
||||
TableVal *dst = fval->Lookup("destination", true)->AsTableVal();
|
||||
|
@ -729,7 +735,7 @@ bool Manager::CreateTableStream(RecordVal* fval)
|
|||
stream->pred = pred ? pred->AsFunc() : 0;
|
||||
stream->num_idx_fields = idxfields;
|
||||
stream->num_val_fields = valfields;
|
||||
stream->tab = dst->AsTableVal();
|
||||
stream->tab = dst->AsTableVal(); // ref'd by lookupwithdefault
|
||||
stream->rtype = val ? val->AsRecordType() : 0;
|
||||
stream->itype = idx->AsRecordType();
|
||||
stream->event = event ? event_registry->Lookup(event->Name()) : 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue