From 888e5074c46584ae9f9b4621cb9b4ae1084aa100 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Tue, 3 Oct 2017 11:14:33 +0000 Subject: bro-script: pasad-parsed: Implement transaction handling --- bro-script/pasad-parsed.bro | 86 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 18 deletions(-) (limited to 'bro-script/pasad-parsed.bro') diff --git a/bro-script/pasad-parsed.bro b/bro-script/pasad-parsed.bro index 7fcc905..88b1be1 100644 --- a/bro-script/pasad-parsed.bro +++ b/bro-script/pasad-parsed.bro @@ -1,27 +1,72 @@ -## Implementation that outputs pairs of register IDs and values. -## Otherwise, the same restrictions as with pasad-simple apply. Additionally, -## the correct register count is not checked and might lead to indexing errors. +## Implementation that outputs the register identification and the register +## value. The correct register count is not checked and might lead to indexing +## errors. module Pasad; +## DATA STRUCTURES + export { redef enum Log::ID += { LOG }; + type Transaction: record { + start_address: count; + quantity: count; + }; + + type TransactionTable: table[count] of Transaction; + type Info: record { - start_address: count &log; - quantity: count &log; + transactions: TransactionTable &default=TransactionTable(); }; type Entry: record { - address: count &log; - register: count &log; + ip: addr &log; + uid: count &log; + regtype: string &log; + address: count &log; + register: count &log; }; } redef record connection += { - pasad: Info &optional; + pasad: Info &default=Info(); }; +## CUSTOM EVENTS + +event pasad_entry(entry: Entry) + { + Log::write(Pasad::LOG, entry); + } + +event pasad_unmatched(tid: count) + { + print fmt("Unmatched response: tid=%d", tid); + } + +## CUSTOM FUNCTIONS + +function pasad_generate_events(transaction: Transaction, c: connection, headers: ModbusHeaders, registers: ModbusRegisters, regtype: string) + { + # TODO: check registers size + local i = 0; + while ( i < transaction$quantity ) + { + local entry = Entry( + $ip=c$id$orig_h, + $uid=headers$uid, + $regtype=regtype, + $address=transaction$start_address + i, + $register=registers[i] + ); + event pasad_entry(entry); + ++i; + } + } + +## EVENT HANDLERS + event bro_init() &priority=5 { Log::create_stream(Pasad::LOG, [$columns=Entry, $path="pasad-parsed"]); @@ -29,18 +74,23 @@ event bro_init() &priority=5 event modbus_read_holding_registers_request(c: connection, headers: ModbusHeaders, start_address: count, quantity: count) { - c$pasad = [$start_address=start_address, $quantity=quantity]; + local tid = headers$tid; + local transaction = Transaction( + $start_address=start_address, + $quantity=quantity + ); + c$pasad$transactions[tid] = transaction; } event modbus_read_holding_registers_response(c: connection, headers: ModbusHeaders, registers: ModbusRegisters) { - local i = 0; - while ( i < c$pasad$quantity ) - { - local address = c$pasad$start_address + i; - local mb_register = registers[i]; - local entry = Entry($address=address, $register=mb_register); - Log::write(Pasad::LOG, entry); - ++i; - } + local tid = headers$tid; + if ( tid !in c$pasad$transactions ) + { + event pasad_unmatched(tid); + return; + } + local transaction = c$pasad$transactions[tid]; + delete c$pasad$transactions[tid]; + pasad_generate_events(transaction, c, headers, registers, "h"); } -- cgit v1.2.1