FileAnalysis: misc. tweaks/fixes.

- Add a timeout flag to file_analysis.log so it's easy to tell what
  has had at least one timeout trigger happen.

- Fix ftp-data service tag not being set for reused connections.

- Fix HTTP::Incorrect_File_Type because mime types returned by FAF have
  the charset still in them, but the HTTP::mime_types_extensions table
  does not and it requires an exact string match. (still ugly)

- Add TRIGGER_NEW_CONN to track files going over multiple connections.

- Add an initial file/mime type guess for non-linear file transfers.

- Fix a case where file/mime type detection would never be attempted
  if the start of the file was a content gap.

- Improve mime type tracking of HTTP byte-range/partial-content,
  even if the requests are pipelined or over multiple connections.

- I changed the modbus.events test because having the baseline output
  be 80+ MB is nuts and it was sensitive to connection record redefs.
This commit is contained in:
Jon Siwek 2013-03-28 16:59:29 -05:00
parent f0e9cdc30a
commit 3642ecc73e
16 changed files with 79842 additions and 159442 deletions

View file

@ -126,6 +126,7 @@ event bro_init() &priority=5
}
redef record FileAnalysis::Info += {
timedout: bool &log &default=F;
conn_uids: set[string] &log &optional;
actions_taken: set[Action] &log &optional;
extracted_files: set[string] &log &optional;
@ -135,7 +136,14 @@ redef record FileAnalysis::Info += {
};
hook FileAnalysis::policy(trig: FileAnalysis::Trigger, info: FileAnalysis::Info)
&priority=-10
&priority=5
{
if ( trig != FileAnalysis::TRIGGER_TIMEOUT ) return;
info$timedout = T;
}
hook FileAnalysis::policy(trig: FileAnalysis::Trigger, info: FileAnalysis::Info)
&priority=-5
{
if ( trig != FileAnalysis::TRIGGER_EOF &&
trig != FileAnalysis::TRIGGER_DONE ) return;

View file

@ -66,7 +66,7 @@ export {
## Reply message from the server in response to the command.
reply_msg: string &log &optional;
## Arbitrary tags that may indicate a particular attribute of this command.
tags: set[string] &log &default=set();
tags: set[string] &log;
## Expected FTP data channel.
data_channel: ExpectedDataChannel &log &optional;
@ -109,6 +109,7 @@ export {
# Add the state tracking information variable to the connection record
redef record connection += {
ftp: Info &optional;
ftp_data_reuse: bool &default=F;
};
# Configure DPD
@ -337,7 +338,6 @@ event ftp_reply(c: connection, code: count, msg: string, cont_resp: bool) &prior
}
}
event expected_connection_seen(c: connection, a: count) &priority=10
{
local id = c$id;
@ -357,8 +357,15 @@ event file_transferred(c: connection, prefix: string, descr: string,
}
}
event connection_reused(c: connection) &priority=5
{
if ( "ftp-data" in c$service )
c$ftp_data_reuse = T;
}
event connection_state_remove(c: connection) &priority=-5
{
if ( c$ftp_data_reuse ) return;
delete ftp_data_expected[c$id$resp_h, c$id$resp_p];
}

View file

@ -9,7 +9,8 @@ module HTTP;
export {
redef enum Notice::Type += {
## Indicates when the file extension doesn't seem to match the file contents.
## Indicates when the file extension doesn't seem to match the file
## contents.
Incorrect_File_Type,
};
@ -18,9 +19,10 @@ export {
mime_type: string &log &optional;
};
## Mapping between mime types and regular expressions for URLs
## The :bro:enum:`HTTP::Incorrect_File_Type` notice is generated if the pattern
## doesn't match the mime type that was discovered.
## Mapping between mime type strings (without character set) and
## regular expressions for URLs.
## The :bro:enum:`HTTP::Incorrect_File_Type` notice is generated if the
## pattern doesn't match the mime type that was discovered.
const mime_types_extensions: table[string] of pattern = {
["application/x-dosexec"] = /\.([eE][xX][eE]|[dD][lL][lL])/,
} &redef;
@ -49,17 +51,66 @@ hook FileAnalysis::policy(trig: FileAnalysis::Trigger, info: FileAnalysis::Info)
c$http$mime_type = info$mime_type;
if ( info$mime_type !in mime_types_extensions ) next;
local mime_str: string = split1(info$mime_type, /;/)[1];
if ( mime_str !in mime_types_extensions ) next;
if ( ! c$http?$uri ) next;
if ( mime_types_extensions[info$mime_type] in c$http$uri ) next;
if ( mime_types_extensions[mime_str] in c$http$uri ) next;
local url = build_url_http(c$http);
if ( url == ignored_incorrect_file_type_urls ) next;
local message = fmt("%s %s %s", info$mime_type, c$http$method, url);
local message = fmt("%s %s %s", mime_str, c$http$method, url);
NOTICE([$note=Incorrect_File_Type,
$msg=message,
$conn=c]);
}
}
hook FileAnalysis::policy(trig: FileAnalysis::Trigger, info: FileAnalysis::Info)
&priority=5
{
if ( trig != FileAnalysis::TRIGGER_NEW_CONN ) return;
if ( ! info?$mime_type ) return;
if ( ! info?$source ) return;
if ( info$source != "HTTP" ) return;
if ( ! info?$conns ) return;
# Spread the mime around (e.g. for partial content, TRIGGER_TYPE only
# happens once for the first connection, but if there's subsequent
# connections to transfer the same file, they'll be lacking the mime_type
# field if we don't do this).
for ( cid in info$conns )
{
local c: connection = info$conns[cid];
if ( ! c?$http ) next;
c$http$mime_type = info$mime_type;
}
}
# Tracks byte-range request / partial content response mime types, indexed
# by [connection, uri] pairs. This is needed because a person can pipeline
# byte-range requests over multiple connections to the same uri. Without
# the tracking, only the first request in the pipeline for each connection
# would get a mime_type field assigned to it (by the FileAnalysis policy hooks).
global partial_types: table[conn_id, string] of string &read_expire=5mins;
# Priority 4 so that it runs before the handler that will write to http.log.
event http_message_done(c: connection, is_orig: bool, stat: http_message_stat)
&priority=4
{
if ( ! c$http$range_request ) return;
if ( ! c$http?$uri ) return;
if ( c$http?$mime_type )
{
partial_types[c$id, c$http$uri] = c$http$mime_type;
return;
}
if ( [c$id, c$http$uri] in partial_types )
c$http$mime_type = partial_types[c$id, c$http$uri];
}

View file

@ -112,6 +112,7 @@ hook FileAnalysis::policy(trig: FileAnalysis::Trigger, info: FileAnalysis::Info)
local c: connection = info$conns[cid];
if ( ! c?$smtp ) next;
if ( ! c$smtp?$current_entity ) next;
if ( c$smtp$current_entity$extract_file )
{
@ -180,6 +181,7 @@ hook FileAnalysis::policy(trig: FileAnalysis::Trigger, info: FileAnalysis::Info)
local c: connection = info$conns[cid];
if ( ! c?$smtp ) next;
if ( ! c$smtp?$current_entity ) next;
c$smtp$current_entity$mime_type = info$mime_type;
}

View file

@ -16,6 +16,9 @@ type ActionResults: record;
enum Trigger %{
## Raised when any part of a new file is detected.
TRIGGER_NEW,
## Raised when file is detected being transported over a new network
## connection (other than the first).
TRIGGER_NEW_CONN,
## Raised when file analysis has likely seen a complete file. That
## is when a number of bytes indicated by the *total_bytes* field of
## :bro:see:`FileAnalysis::Info` have been processed. Note that

View file

@ -81,7 +81,8 @@ void Info::StaticInit()
Info::Info(const string& unique, Connection* conn, AnalyzerTag::Tag tag)
: file_id(""), unique(unique), val(0), postpone_timeout(false),
need_reassembly(false), done(false), actions(this)
first_chunk(true), need_type(false), need_reassembly(false), done(false),
actions(this)
{
StaticInit();
@ -134,11 +135,23 @@ void Info::UpdateConnectionFields(Connection* conn)
Val* conns = val->Lookup(conns_idx);
bool is_first = false;
if ( ! conns )
{
is_first = true;
val->Assign(conns_idx, conns = empty_connection_table());
}
Val* idx = get_conn_id_val(conn);
if ( ! conns->AsTableVal()->Lookup(idx) )
{
conns->AsTableVal()->Assign(idx, conn->BuildConnVal());
if ( ! is_first )
file_mgr->EvaluatePolicy(BifEnum::FileAnalysis::TRIGGER_NEW_CONN,
this);
}
Unref(idx);
}
@ -162,7 +175,7 @@ int Info::Idx(const string& field)
{
int rval = BifType::Record::FileAnalysis::Info->FieldOffset(field.c_str());
if ( rval < 0 )
reporter->InternalError("Unkown FileAnalysis::Info field: %s",
reporter->InternalError("Unknown FileAnalysis::Info field: %s",
field.c_str());
return rval;
}
@ -254,18 +267,10 @@ bool Info::BufferBOF(const u_char* data, uint64 len)
return true;
}
void Info::ReplayBOF()
bool Info::DetectTypes(const u_char* data, uint64 len)
{
if ( bof_buffer.replayed ) return;
bof_buffer.replayed = true;
if ( bof_buffer.chunks.empty() ) return;
BroString* bs = concatenate(bof_buffer.chunks);
const char* desc = bro_magic_buffer(magic, bs->Bytes(), bs->Len());
const char* mime = bro_magic_buffer(magic_mime, bs->Bytes(), bs->Len());
val->Assign(bof_buffer_idx, new StringVal(bs));
const char* desc = bro_magic_buffer(magic, data, len);
const char* mime = bro_magic_buffer(magic_mime, data, len);
if ( desc )
val->Assign(file_type_idx, new StringVal(desc));
@ -273,10 +278,29 @@ void Info::ReplayBOF()
if ( mime )
val->Assign(mime_type_idx, new StringVal(mime));
return desc || mime;
}
void Info::ReplayBOF()
{
if ( bof_buffer.replayed ) return;
bof_buffer.replayed = true;
if ( bof_buffer.chunks.empty() )
{
// Since we missed the beginning, try file type detect on next data in.
need_type = true;
return;
}
BroString* bs = concatenate(bof_buffer.chunks);
val->Assign(bof_buffer_idx, new StringVal(bs));
bool have_type = DetectTypes(bs->Bytes(), bs->Len());
using BifEnum::FileAnalysis::TRIGGER_BOF_BUFFER;
file_mgr->EvaluatePolicy(TRIGGER_BOF_BUFFER, this);
if ( desc || mime )
if ( have_type )
file_mgr->EvaluatePolicy(BifEnum::FileAnalysis::TRIGGER_TYPE, this);
for ( size_t i = 0; i < bof_buffer.chunks.size(); ++i )
@ -286,7 +310,17 @@ void Info::ReplayBOF()
void Info::DataIn(const u_char* data, uint64 len, uint64 offset)
{
actions.DrainModifications();
// TODO: attempt libmagic stuff here before doing reassembly?
if ( first_chunk )
{
if ( DetectTypes(data, len) )
{
file_mgr->EvaluatePolicy(BifEnum::FileAnalysis::TRIGGER_TYPE, this);
actions.DrainModifications();
}
first_chunk = false;
}
Action* act = 0;
IterCookie* c = actions.InitForIteration();
@ -316,6 +350,17 @@ void Info::DataIn(const u_char* data, uint64 len)
if ( BufferBOF(data, len) ) return;
if ( need_type )
{
if ( DetectTypes(data, len) )
{
file_mgr->EvaluatePolicy(BifEnum::FileAnalysis::TRIGGER_TYPE, this);
actions.DrainModifications();
}
need_type = false;
}
Action* act = 0;
IterCookie* c = actions.InitForIteration();

View file

@ -155,10 +155,19 @@ protected:
*/
void ReplayBOF();
/**
* Does file/mime type detection and assigns types (if available) to
* corresponding fields in #val.
* @return whether a file or mime type was available.
*/
bool DetectTypes(const u_char* data, uint64 len);
FileID file_id; /**< A pretty hash that likely identifies file*/
string unique; /**< A string that uniquely identifies file */
RecordVal* val; /**< \c FileAnalysis::Info from script layer. */
bool postpone_timeout; /**< Whether postponing timeout is requested. */
bool first_chunk; /**< Track first non-linear chunk. */
bool need_type; /**< Flags next data input to be magic typed. */
bool need_reassembly; /**< Whether file stream reassembly is needed. */
bool done; /**< If this object is about to be deleted. */
ActionSet actions;

View file

@ -3,8 +3,8 @@
#empty_field (empty)
#unset_field -
#path http
#open 2013-03-22-14-37-46
#open 2013-03-28-21-35-15
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p trans_depth method host uri referrer user_agent request_body_len response_body_len status_code status_msg info_code info_msg filename tags username password proxied mime_type md5 extraction_file
#types time string addr port addr port count string string string string string count count count string count string string table[enum] string string table[string] string string string
1333458850.375568 arKYeMETxOg 10.131.47.185 1923 79.101.110.141 80 1 GET o-o.preferred.telekomrs-beg1.v2.lscache8.c.youtube.com /videoplayback?upn=MTU2MDY5NzQ5OTM0NTI3NDY4NDc&sparams=algorithm,burst,cp,factor,id,ip,ipbits,itag,source,upn,expire&fexp=912300,907210&algorithm=throttle-factor&itag=34&ip=212.0.0.0&burst=40&sver=3&signature=832FB1042E20780CFCA77A4DB5EA64AC593E8627.D1166C7E8365732E52DAFD68076DAE0146E0AE01&source=youtube&expire=1333484980&key=yt1&ipbits=8&factor=1.25&cp=U0hSSFRTUl9NSkNOMl9MTVZKOjh5eEN2SG8tZF84&id=ebf1e932d4bd1286&cm2=1 http://s.ytimg.com/yt/swfbin/watch_as3-vflqrJwOA.swf Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko; X-SBLSP) Chrome/17.0.963.83 Safari/535.11 0 56320 206 Partial Content - - - (empty) - - - - - -
#close 2013-03-22-14-37-46
1333458850.375568 arKYeMETxOg 10.131.47.185 1923 79.101.110.141 80 1 GET o-o.preferred.telekomrs-beg1.v2.lscache8.c.youtube.com /videoplayback?upn=MTU2MDY5NzQ5OTM0NTI3NDY4NDc&sparams=algorithm,burst,cp,factor,id,ip,ipbits,itag,source,upn,expire&fexp=912300,907210&algorithm=throttle-factor&itag=34&ip=212.0.0.0&burst=40&sver=3&signature=832FB1042E20780CFCA77A4DB5EA64AC593E8627.D1166C7E8365732E52DAFD68076DAE0146E0AE01&source=youtube&expire=1333484980&key=yt1&ipbits=8&factor=1.25&cp=U0hSSFRTUl9NSkNOMl9MTVZKOjh5eEN2SG8tZF84&id=ebf1e932d4bd1286&cm2=1 http://s.ytimg.com/yt/swfbin/watch_as3-vflqrJwOA.swf Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko; X-SBLSP) Chrome/17.0.963.83 Safari/535.11 0 56320 206 Partial Content - - - (empty) - - - application/octet-stream; charset=binary - -
#close 2013-03-28-21-35-15

View file

@ -1,5 +1,8 @@
FileAnalysis::TRIGGER_NEW
oDwT1BbzjM1, 0, 0
FileAnalysis::TRIGGER_TYPE
file type is set
mime type is set
FileAnalysis::TRIGGER_DONE
oDwT1BbzjM1, 1022920, 0
[orig_h=192.168.72.14, orig_p=3254/tcp, resp_h=65.54.95.206, resp_p=80/tcp]
@ -7,6 +10,9 @@ total bytes: 1022920
source: HTTP
FileAnalysis::TRIGGER_NEW
oDwT1BbzjM1, 0, 0
FileAnalysis::TRIGGER_TYPE
file type is set
mime type is set
FileAnalysis::TRIGGER_TIMEOUT
FileAnalysis::TRIGGER_TIMEOUT
FileAnalysis::TRIGGER_EOF

View file

@ -1,5 +1,9 @@
FileAnalysis::TRIGGER_NEW
7gZBKVUgy4l, 0, 0
FileAnalysis::TRIGGER_TYPE
file type is set
mime type is set
FileAnalysis::TRIGGER_NEW_CONN
FileAnalysis::TRIGGER_DONE
7gZBKVUgy4l, 555523, 0
[orig_h=10.101.84.70, orig_p=10978/tcp, resp_h=129.174.93.161, resp_p=80/tcp]

View file

@ -1,5 +1,8 @@
FileAnalysis::TRIGGER_NEW
oDwT1BbzjM1, 0, 0
FileAnalysis::TRIGGER_TYPE
file type is set
mime type is set
FileAnalysis::TRIGGER_DONE
oDwT1BbzjM1, 1022920, 0
[orig_h=192.168.72.14, orig_p=3254/tcp, resp_h=65.54.95.206, resp_p=80/tcp]
@ -7,6 +10,9 @@ total bytes: 1022920
source: HTTP
FileAnalysis::TRIGGER_NEW
oDwT1BbzjM1, 0, 0
FileAnalysis::TRIGGER_TYPE
file type is set
mime type is set
FileAnalysis::TRIGGER_TIMEOUT
FileAnalysis::TRIGGER_EOF
oDwT1BbzjM1, 206024, 0

View file

@ -1,5 +1,9 @@
FileAnalysis::TRIGGER_NEW
uHS14uhRKGe, 0, 0
FileAnalysis::TRIGGER_TYPE
file type is set
mime type is set
FileAnalysis::TRIGGER_NEW_CONN
FileAnalysis::TRIGGER_DONE
uHS14uhRKGe, 498702, 0
[orig_h=10.45.179.94, orig_p=19950/tcp, resp_h=129.174.93.170, resp_p=80/tcp]

View file

@ -3,8 +3,8 @@
#empty_field (empty)
#unset_field -
#path file_analysis
#open 2013-03-26-20-26-26
#fields file_id parent_file_id source last_active seen_bytes total_bytes missing_bytes overflow_bytes timeout_interval bof_buffer_size file_type mime_type conn_uids actions_taken extracted_files md5 sha1 sha256
#types string string string time count count count count interval count string string table[string] table[enum] table[string] string string string
Cx92a0ym5R8 - HTTP 1362692527.009775 4705 4705 0 0 120.000000 1024 set set UWkUyAuUGXf FileAnalysis::ACTION_SHA1,FileAnalysis::ACTION_EXTRACT,FileAnalysis::ACTION_DATA_EVENT,FileAnalysis::ACTION_MD5,FileAnalysis::ACTION_SHA256 Cx92a0ym5R8-file 397168fd09991a0e712254df7bc639ac 1dd7ac0398df6cbc0696445a91ec681facf4dc47 4e7c7ef0984119447e743e3ec77e1de52713e345cde03fe7df753a35849bed18
#close 2013-03-26-20-26-26
#open 2013-03-28-21-35-46
#fields file_id parent_file_id source last_active seen_bytes total_bytes missing_bytes overflow_bytes timeout_interval bof_buffer_size file_type mime_type timedout conn_uids actions_taken extracted_files md5 sha1 sha256
#types string string string time count count count count interval count string string bool table[string] table[enum] table[string] string string string
Cx92a0ym5R8 - HTTP 1362692527.009775 4705 4705 0 0 120.000000 1024 set set F UWkUyAuUGXf FileAnalysis::ACTION_SHA1,FileAnalysis::ACTION_EXTRACT,FileAnalysis::ACTION_DATA_EVENT,FileAnalysis::ACTION_MD5,FileAnalysis::ACTION_SHA256 Cx92a0ym5R8-file 397168fd09991a0e712254df7bc639ac 1dd7ac0398df6cbc0696445a91ec681facf4dc47 4e7c7ef0984119447e743e3ec77e1de52713e345cde03fe7df753a35849bed18
#close 2013-03-28-21-35-46

File diff suppressed because it is too large Load diff

View file

@ -8,141 +8,141 @@
event modbus_message(c: connection, headers: ModbusHeaders, is_orig: bool)
{
print "modbus_message", c, headers, is_orig;
print "modbus_message", c$id, headers, is_orig;
}
event modbus_exception(c: connection, headers: ModbusHeaders, code: count)
{
print "modbus_exception", c, headers, code;
print "modbus_exception", c$id, headers, code;
}
event modbus_read_coils_request(c: connection, headers: ModbusHeaders, start_address: count, quantity: count)
{
print "modbus_read_coils_request", c, headers, start_address, quantity;
print "modbus_read_coils_request", c$id, headers, start_address, quantity;
}
event modbus_read_coils_response(c: connection, headers: ModbusHeaders, coils: ModbusCoils)
{
print "modbus_read_coils_response", c, headers, coils;
print "modbus_read_coils_response", c$id, headers, coils;
}
event modbus_read_discrete_inputs_request(c: connection, headers: ModbusHeaders, start_address: count, quantity: count)
{
print "modbus_read_discrete_inputs_request", c, headers, start_address, quantity;
print "modbus_read_discrete_inputs_request", c$id, headers, start_address, quantity;
}
event modbus_read_discrete_inputs_response(c: connection, headers: ModbusHeaders, coils: ModbusCoils)
{
print "modbus_read_discrete_inputs_response", c, headers, coils;
print "modbus_read_discrete_inputs_response", c$id, headers, coils;
}
event modbus_read_holding_registers_request(c: connection, headers: ModbusHeaders, start_address: count, quantity: count)
{
print "modbus_read_holding_registers_request", c, headers, start_address, quantity;
print "modbus_read_holding_registers_request", c$id, headers, start_address, quantity;
}
event modbus_read_holding_registers_response(c: connection, headers: ModbusHeaders, registers: ModbusRegisters)
{
print "modbus_read_holding_registers_response", c, headers, registers;
print "modbus_read_holding_registers_response", c$id, headers, registers;
}
event modbus_read_input_registers_request(c: connection, headers: ModbusHeaders, start_address: count, quantity: count)
{
print "modbus_read_input_registers_request", c, headers, start_address, quantity;
print "modbus_read_input_registers_request", c$id, headers, start_address, quantity;
}
event modbus_read_input_registers_response(c: connection, headers: ModbusHeaders, registers: ModbusRegisters)
{
print "modbus_read_input_registers_response", c, headers, registers;
print "modbus_read_input_registers_response", c$id, headers, registers;
}
event modbus_write_single_coil_request(c: connection, headers: ModbusHeaders, address: count, value: bool)
{
print "modbus_write_single_coil_request", c, headers, address, value;
print "modbus_write_single_coil_request", c$id, headers, address, value;
}
event modbus_write_single_coil_response(c: connection, headers: ModbusHeaders, address: count, value: bool)
{
print "modbus_write_single_coil_response", c, headers, address, value;
print "modbus_write_single_coil_response", c$id, headers, address, value;
}
event modbus_write_single_register_request(c: connection, headers: ModbusHeaders, address: count, value: count)
{
print "modbus_write_single_register_request", c, headers, address, value;
print "modbus_write_single_register_request", c$id, headers, address, value;
}
event modbus_write_single_register_response(c: connection, headers: ModbusHeaders, address: count, value: count)
{
print "modbus_write_single_register_response", c, headers, address, value;
print "modbus_write_single_register_response", c$id, headers, address, value;
}
event modbus_write_multiple_coils_request(c: connection, headers: ModbusHeaders, start_address: count, coils: ModbusCoils)
{
print "modbus_write_multiple_coils_request", c, headers, start_address, coils;
print "modbus_write_multiple_coils_request", c$id, headers, start_address, coils;
}
event modbus_write_multiple_coils_response(c: connection, headers: ModbusHeaders, start_address: count, quantity: count)
{
print "modbus_write_multiple_coils_response", c, headers, start_address, quantity;
print "modbus_write_multiple_coils_response", c$id, headers, start_address, quantity;
}
event modbus_write_multiple_registers_request(c: connection, headers: ModbusHeaders, start_address: count, registers: ModbusRegisters)
{
print "modbus_write_multiple_registers_request", c, headers, start_address, registers;
print "modbus_write_multiple_registers_request", c$id, headers, start_address, registers;
}
event modbus_write_multiple_registers_response(c: connection, headers: ModbusHeaders, start_address: count, quantity: count)
{
print "modbus_write_multiple_registers_response", c, headers, start_address, quantity;
print "modbus_write_multiple_registers_response", c$id, headers, start_address, quantity;
}
event modbus_read_file_record_request(c: connection, headers: ModbusHeaders)
{
print "modbus_read_file_record_request", c, headers;
print "modbus_read_file_record_request", c$id, headers;
}
event modbus_read_file_record_response(c: connection, headers: ModbusHeaders)
{
print "modbus_read_file_record_response", c, headers;
print "modbus_read_file_record_response", c$id, headers;
}
event modbus_write_file_record_request(c: connection, headers: ModbusHeaders)
{
print "modbus_write_file_record_request", c, headers;
print "modbus_write_file_record_request", c$id, headers;
}
event modbus_write_file_record_response(c: connection, headers: ModbusHeaders)
{
print "modbus_write_file_record_response", c, headers;
print "modbus_write_file_record_response", c$id, headers;
}
event modbus_mask_write_register_request(c: connection, headers: ModbusHeaders, address: count, and_mask: count, or_mask: count)
{
print "modbus_mask_write_register_request", c, headers, address, and_mask, or_mask;
print "modbus_mask_write_register_request", c$id, headers, address, and_mask, or_mask;
}
event modbus_mask_write_register_response(c: connection, headers: ModbusHeaders, address: count, and_mask: count, or_mask: count)
{
print "modbus_mask_write_register_response", c, headers, address, and_mask, or_mask;
print "modbus_mask_write_register_response", c$id, headers, address, and_mask, or_mask;
}
event modbus_read_write_multiple_registers_request(c: connection, headers: ModbusHeaders, read_start_address: count, read_quantity: count, write_start_address: count, write_registers: ModbusRegisters)
{
print "modbus_read_write_multiple_registers_request", c, headers, read_start_address, read_quantity, write_start_address, write_registers;
print "modbus_read_write_multiple_registers_request", c$id, headers, read_start_address, read_quantity, write_start_address, write_registers;
}
event modbus_read_write_multiple_registers_response(c: connection, headers: ModbusHeaders, written_registers: ModbusRegisters)
{
print "modbus_read_write_multiple_registers_response", c, headers, written_registers;
print "modbus_read_write_multiple_registers_response", c$id, headers, written_registers;
}
event modbus_read_fifo_queue_request(c: connection, headers: ModbusHeaders, start_address: count)
{
print "modbus_read_fifo_queue_request", c, headers, start_address;
print "modbus_read_fifo_queue_request", c$id, headers, start_address;
}
event modbus_read_fifo_queue_response(c: connection, headers: ModbusHeaders, fifos: ModbusRegisters)
{
print "modbus_read_fifo_queue_response", c, headers, fifos;
print "modbus_read_fifo_queue_response", c$id, headers, fifos;
}

View file

@ -8,7 +8,7 @@ BEGIN { FS="\t"; OFS="\t"; type_col = -1; desc_col = -1 }
/^#fields/ {
for ( i = 2; i < NF; ++i )
{
if ( $i == "mime_type" )
if ( $i == "mime_type" || $i == "file_type" )
type_col = i-1;
if ( $i == "mime_desc" )
desc_col = i-1;