Remove byte count parameter from modbus events carrying register arrays

Instead of these events being generated for invalid byte count values
(they should always be even, not odd), a protocol_violation is raised.

    modbus_read_holding_registers_response
    modbus_read_input_registers_response
    modbus_write_multiple_registers_request
    modbus_read_write_multiple_registers_request
    modbus_read_write_multiple_registers_response
    modbus_read_fifo_queue_respons
This commit is contained in:
Jon Siwek 2012-11-13 12:09:14 -06:00
parent c911d03c30
commit fd5eb23fa6
6 changed files with 64 additions and 38 deletions

View file

@ -6623,10 +6623,8 @@ event modbus_read_holding_registers_request%(c: connection, headers: ModbusHeade
##
## headers: The headers for the modbus function.
##
## byte_count: The number of bytes in the message that comprise register values.
##
## registers: The register values returned from the device.
event modbus_read_holding_registers_response%(c: connection, headers: ModbusHeaders, byte_count: count, registers: ModbusRegisters%);
event modbus_read_holding_registers_response%(c: connection, headers: ModbusHeaders, registers: ModbusRegisters%);
## Generated for a Modbus read input registers request.
##
@ -6645,10 +6643,8 @@ event modbus_read_input_registers_request%(c: connection, headers: ModbusHeaders
##
## headers: The headers for the modbus function.
##
## byte_count: The number of bytes in the message that comprise register values.
##
## registers: The register values returned from the device.
event modbus_read_input_registers_response%(c: connection, headers: ModbusHeaders, byte_count: count, registers: ModbusRegisters%);
event modbus_read_input_registers_response%(c: connection, headers: ModbusHeaders, registers: ModbusRegisters%);
## Generated for a Modbus write single coil request.
##
@ -6724,10 +6720,8 @@ event modbus_write_multiple_coils_response%(c: connection, headers: ModbusHeader
##
## start_address: The memory address of the first register to be written.
##
## byte_count: The number of bytes in the message that comprise register values.
##
## registers: The values to be written to the registers.
event modbus_write_multiple_registers_request%(c: connection, headers: ModbusHeaders, start_address: count, byte_count: count, registers: ModbusRegisters%);
event modbus_write_multiple_registers_request%(c: connection, headers: ModbusHeaders, start_address: count, registers: ModbusRegisters%);
## Generated for a Modbus write multiple registers response.
##
@ -6818,10 +6812,8 @@ event modbus_mask_write_register_response%(c: connection, headers: ModbusHeaders
##
## write_start_address: The memory address of the first register to be written.
##
## write_byte_count: Number of bytes in message that comprise register values.
##
## write_registers: The values to be written to the registers.
event modbus_read_write_multiple_registers_request%(c: connection, headers: ModbusHeaders, read_start_address: count, read_quantity: count, write_start_address: count, write_byte_count: count, write_registers: ModbusRegisters%);
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%);
## Generated for a Modbus read/write multiple registers response.
##
@ -6829,10 +6821,8 @@ event modbus_read_write_multiple_registers_request%(c: connection, headers: Modb
##
## headers: The headers for the modbus function.
##
## byte_count: The number of bytes in the message that comprise register values.
##
## written_registers: The register values read from the registers specified in the request.
event modbus_read_write_multiple_registers_response%(c: connection, headers: ModbusHeaders, byte_count: count, written_registers: ModbusRegisters%);
event modbus_read_write_multiple_registers_response%(c: connection, headers: ModbusHeaders, written_registers: ModbusRegisters%);
## Generated for a Modbus read FIFO queue request.
##
@ -6849,10 +6839,8 @@ event modbus_read_fifo_queue_request%(c: connection, headers: ModbusHeaders, sta
##
## headers: The headers for the modbus function.
##
## byte_count: The number of bytes in the message that comprise register values.
##
## fifos: The register values read from the FIFO queue on the device.
event modbus_read_fifo_queue_response%(c: connection, headers: ModbusHeaders, byte_count: count, fifos: ModbusRegisters%);
event modbus_read_fifo_queue_response%(c: connection, headers: ModbusHeaders, fifos: ModbusRegisters%);
## Raised for informational messages reported via Bro's reporter framework. Such
## messages may be generated internally by the event engine and also by other

View file

@ -135,8 +135,16 @@ refine flow ModbusTCP_Flow += {
# RESPONSE FC=3
function deliver_ReadHoldingRegistersResponse(header: ModbusTCP_TransportHeader, message: ReadHoldingRegistersResponse): bool
%{
if ( ${message.byte_count} % 2 != 0 )
{
connection()->bro_analyzer()->ProtocolViolation(
fmt("invalid value for modbus read holding register response byte count %d", ${message.byte_count}));
return false;
}
if ( ::modbus_read_holding_registers_response )
{
VectorVal* t = new VectorVal(BifType::Vector::ModbusRegisters);
for ( unsigned int i=0; i < ${message.registers}->size(); ++i )
{
@ -147,7 +155,6 @@ refine flow ModbusTCP_Flow += {
BifEvent::generate_modbus_read_holding_registers_response(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
HeaderToBro(header),
${message.byte_count},
t);
}
@ -172,6 +179,13 @@ refine flow ModbusTCP_Flow += {
# RESPONSE FC=4
function deliver_ReadInputRegistersResponse(header: ModbusTCP_TransportHeader, message: ReadInputRegistersResponse): bool
%{
if ( ${message.byte_count} % 2 != 0 )
{
connection()->bro_analyzer()->ProtocolViolation(
fmt("invalid value for modbus read input register response byte count %d", ${message.byte_count}));
return false;
}
if ( ::modbus_read_input_registers_response )
{
VectorVal* t = new VectorVal(BifType::Vector::ModbusRegisters);
@ -184,7 +198,6 @@ refine flow ModbusTCP_Flow += {
BifEvent::generate_modbus_read_input_registers_response(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
HeaderToBro(header),
${message.byte_count},
t);
}
@ -309,6 +322,13 @@ refine flow ModbusTCP_Flow += {
# REQUEST FC=16
function deliver_WriteMultipleRegistersRequest(header: ModbusTCP_TransportHeader, message: WriteMultipleRegistersRequest): bool
%{
if ( ${message.byte_count} % 2 != 0 )
{
connection()->bro_analyzer()->ProtocolViolation(
fmt("invalid value for modbus write multiple registers request byte count %d", ${message.byte_count}));
return false;
}
if ( ::modbus_write_multiple_registers_request )
{
VectorVal * t = new VectorVal(BifType::Vector::ModbusRegisters);
@ -321,7 +341,7 @@ refine flow ModbusTCP_Flow += {
BifEvent::generate_modbus_write_multiple_registers_request(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
HeaderToBro(header),
${message.start_address}, ${message.byte_count}, t);
${message.start_address}, t);
}
return true;
@ -486,6 +506,13 @@ refine flow ModbusTCP_Flow += {
# REQUEST FC=23
function deliver_ReadWriteMultipleRegistersRequest(header: ModbusTCP_TransportHeader, message: ReadWriteMultipleRegistersRequest): bool
%{
if ( ${message.write_byte_count} % 2 != 0 )
{
connection()->bro_analyzer()->ProtocolViolation(
fmt("invalid value for modbus read write multiple registers request write byte count %d", ${message.write_byte_count}));
return false;
}
if ( ::modbus_read_write_multiple_registers_request )
{
VectorVal* t = new VectorVal(BifType::Vector::ModbusRegisters);
@ -501,7 +528,6 @@ refine flow ModbusTCP_Flow += {
${message.read_start_address},
${message.read_quantity},
${message.write_start_address},
${message.write_byte_count},
t);
}
@ -511,6 +537,13 @@ refine flow ModbusTCP_Flow += {
# RESPONSE FC=23
function deliver_ReadWriteMultipleRegistersResponse(header: ModbusTCP_TransportHeader, message: ReadWriteMultipleRegistersResponse): bool
%{
if ( ${message.byte_count} % 2 != 0 )
{
connection()->bro_analyzer()->ProtocolViolation(
fmt("invalid value for modbus read write multiple registers response byte count %d", ${message.byte_count}));
return false;
}
if ( ::modbus_read_write_multiple_registers_response )
{
VectorVal* t = new VectorVal(BifType::Vector::ModbusRegisters);
@ -523,7 +556,6 @@ refine flow ModbusTCP_Flow += {
BifEvent::generate_modbus_read_write_multiple_registers_response(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
HeaderToBro(header),
${message.byte_count},
t);
}
@ -548,6 +580,13 @@ refine flow ModbusTCP_Flow += {
# RESPONSE FC=24
function deliver_ReadFIFOQueueResponse(header: ModbusTCP_TransportHeader, message: ReadFIFOQueueResponse): bool
%{
if ( ${message.byte_count} % 2 != 0 )
{
connection()->bro_analyzer()->ProtocolViolation(
fmt("invalid value for modbus read FIFO queue response byte count %d", ${message.byte_count}));
return false;
}
if ( ::modbus_read_fifo_queue_response )
{
VectorVal* t = new VectorVal(new VectorType(base_type(TYPE_COUNT)));
@ -560,7 +599,6 @@ refine flow ModbusTCP_Flow += {
BifEvent::generate_modbus_read_fifo_queue_response(connection()->bro_analyzer(),
connection()->bro_analyzer()->Conn(),
HeaderToBro(header),
${message.byte_count},
t);
}