77 #define MODBUS_MIN_ADU_LEN 2 78 #define MODBUS_MAX_ADU_LEN 254 81 #define MODBUS_PROTOCOL_VER 0 84 #define MODBUS_MIN_INVALID_UNIT_ID 247 85 #define MODBUS_MAX_INVALID_UNIT_ID 255 88 #define MODBUS_MIN_QUANTITY 0 89 #define MODBUS_MAX_QUANTITY_IN_BIT_ACCESS 2000 90 #define MODBUS_MAX_QUANTITY_IN_WORD_ACCESS 125 93 #define MODBUS_MIN_COUNT 1 94 #define MODBUS_MAX_COUNT 250 97 #define MODBUS_FUNC_READCOILS 0x01 98 #define MODBUS_FUNC_READDISCINPUTS 0x02 99 #define MODBUS_FUNC_READHOLDREGS 0x03 100 #define MODBUS_FUNC_READINPUTREGS 0x04 101 #define MODBUS_FUNC_WRITESINGLECOIL 0x05 102 #define MODBUS_FUNC_WRITESINGLEREG 0x06 103 #define MODBUS_FUNC_READEXCSTATUS 0x07 104 #define MODBUS_FUNC_DIAGNOSTIC 0x08 105 #define MODBUS_FUNC_GETCOMEVTCOUNTER 0x0b 106 #define MODBUS_FUNC_GETCOMEVTLOG 0x0c 107 #define MODBUS_FUNC_WRITEMULTCOILS 0x0f 108 #define MODBUS_FUNC_WRITEMULTREGS 0x10 109 #define MODBUS_FUNC_REPORTSERVERID 0x11 110 #define MODBUS_FUNC_READFILERECORD 0x14 111 #define MODBUS_FUNC_WRITEFILERECORD 0x15 112 #define MODBUS_FUNC_MASKWRITEREG 0x16 113 #define MODBUS_FUNC_READWRITEMULTREGS 0x17 114 #define MODBUS_FUNC_READFIFOQUEUE 0x18 115 #define MODBUS_FUNC_ENCAPINTTRANS 0x2b 116 #define MODBUS_FUNC_MASK 0x7f 117 #define MODBUS_FUNC_ERRORMASK 0x80 120 #define MODBUS_SUBFUNC_QUERY_DATA 0x00 121 #define MODBUS_SUBFUNC_RESTART_COM 0x01 122 #define MODBUS_SUBFUNC_DIAG_REGS 0x02 123 #define MODBUS_SUBFUNC_CHANGE_DELIMITER 0x03 124 #define MODBUS_SUBFUNC_LISTEN_MODE 0x04 125 #define MODBUS_SUBFUNC_CLEAR_REGS 0x0a 126 #define MODBUS_SUBFUNC_BUS_MSG_COUNT 0x0b 127 #define MODBUS_SUBFUNC_COM_ERR_COUNT 0x0c 128 #define MODBUS_SUBFUNC_EXCEPT_ERR_COUNT 0x0d 129 #define MODBUS_SUBFUNC_SERVER_MSG_COUNT 0x0e 130 #define MODBUS_SUBFUNC_SERVER_NO_RSP_COUNT 0x0f 131 #define MODBUS_SUBFUNC_SERVER_NAK_COUNT 0x10 132 #define MODBUS_SUBFUNC_SERVER_BUSY_COUNT 0x11 133 #define MODBUS_SUBFUNC_SERVER_CHAR_COUNT 0x12 134 #define MODBUS_SUBFUNC_CLEAR_COUNT 0x14 137 #define MODBUS_MEI_ENCAPINTTRANS_CAN 0x0d 138 #define MODBUS_MEI_ENCAPINTTRANS_READ 0x0e 141 #define MODBUS_ERROR_CODE_ILLEGAL_FUNCTION 0x01 142 #define MODBUS_ERROR_CODE_ILLEGAL_DATA_ADDRESS 0x02 143 #define MODBUS_ERROR_CODE_ILLEGAL_DATA_VALUE 0x03 144 #define MODBUS_ERROR_CODE_SERVER_DEVICE_FAILURE 0x04 145 #define MODBUS_ERROR_CODE_MEMORY_PARITY_ERROR 0x08 157 #define MODBUS_TYP_WRITE_SINGLE (MODBUS_TYP_WRITE | MODBUS_TYP_SINGLE) 158 #define MODBUS_TYP_WRITE_MULTIPLE (MODBUS_TYP_WRITE | MODBUS_TYP_MULTIPLE) 159 #define MODBUS_TYP_READ_WRITE_MULTIPLE (MODBUS_TYP_READ | MODBUS_TYP_WRITE | MODBUS_TYP_MULTIPLE) 162 #define CEIL(quantity) (((quantity) + 7)>>3) 165 #define MODBUS_CONFIG_DEFAULT_REQUEST_FLOOD 500 168 #define MODBUS_CONFIG_DEFAULT_STREAM_DEPTH 0 177 if (*event_id == -1) {
179 "modbus's enum map table.", event_name);
189 static void ModbusSetEvent(
ModbusState *modbus, uint8_t e)
191 if (modbus && modbus->
curr) {
216 static int ModbusGetAlstateProgress(
void *modbus_tx, uint8_t direction)
234 static int ModbusGetAlstateProgressCompletionStatus(uint8_t direction)
239 static void *ModbusGetTx(
void *alstate, uint64_t
tx_id)
249 if (tx->
tx_num != (tx_id+1))
259 static void ModbusSetTxLogged(
void *alstate,
void *vtx,
LoggerId logged)
265 static LoggerId ModbusGetTxLogged(
void *alstate,
void *vtx)
271 static uint64_t ModbusGetTxCnt(
void *alstate)
273 return ((uint64_t) ((
ModbusState *) alstate)->transaction_max);
289 if (modbus->
curr == NULL)
327 if ((request_flood != 0) && (modbus->
unreplied_cnt > request_flood)) {
351 if (tx->
data != NULL)
366 static void ModbusStateTxFree(
void *state, uint64_t tx_id)
372 SCLogDebug(
"state %p, id %"PRIu64, modbus, tx_id);
375 SCLogDebug(
"tx %p tx->tx_num %"PRIu64
", tx_id %"PRIu64, tx, tx->
tx_num, (tx_id+1));
377 if (tx->
tx_num != (tx_id+1))
380 if (tx == modbus->
curr)
394 (request_flood != 0) &&
419 if (input_len < (uint32_t) (*offset +
sizeof(uint8_t))) {
424 *res = *(input + *
offset);
425 *offset +=
sizeof(uint8_t);
437 static int ModbusExtractUint16(
ModbusState *modbus,
443 if (input_len < (uint32_t) (*offset +
sizeof(uint16_t))) {
449 *offset +=
sizeof(uint16_t);
460 static int ModbusCheckHeaderLength(
ModbusState *modbus,
515 uint8_t exception = 0;
518 if (ModbusExtractUint8(modbus, &exception, input, input_len, offset))
572 if (ModbusExtractUint16(modbus, &(tx->
read.address), input, input_len, offset))
576 if (ModbusExtractUint16(modbus, &(tx->
read.quantity), input, input_len, offset))
578 quantity = tx->
read.quantity;
595 ModbusCheckHeaderLength(modbus, tx->
length, 6);
624 if (ModbusExtractUint8(modbus, &count, input, input_len, offset))
636 (count != (2 * (tx->
read.quantity))))
643 ModbusCheckHeaderLength(modbus, tx->
length, 3 + count);
671 uint16_t quantity = 1, word = 0;
672 uint8_t byte = 0, count = 1,
type = tx->
type;
677 if (ModbusExtractUint16(modbus, &(tx->
write.address), input, input_len, offset))
684 if (ModbusCheckHeaderLength(modbus, tx->
length, 6))
688 if (ModbusExtractUint16(modbus, &quantity, input, input_len, offset))
690 tx->
write.quantity = quantity;
693 if (ModbusExtractUint8(modbus, &count, input, input_len, offset))
695 tx->
write.count = count;
701 (quantity !=
CEIL(count)))
706 if (ModbusCheckHeaderLength(modbus, tx->
length, 7 + count))
712 (count != (2 * quantity)))
719 if (ModbusCheckHeaderLength(modbus, tx->
length, 11 + count))
725 if (ModbusCheckHeaderLength(modbus, tx->
length, 7 + count))
735 if (ModbusCheckHeaderLength(modbus, tx->
length, 8))
741 tx->
data = (uint16_t *)
SCCalloc(1, count *
sizeof(uint16_t));
745 if (
type & MODBUS_TYP_SINGLE) {
747 if (ModbusExtractUint16(modbus, &word, input, input_len, offset))
751 if ((word != 0x00) && (word != 0xFF00))
754 for (i = 0; i < count; i++) {
756 if (ModbusExtractUint8(modbus, &byte, input, input_len, offset))
758 tx->
data[i] = (uint16_t) byte;
763 tx->
data = (uint16_t *)
SCCalloc(1, quantity *
sizeof(uint16_t));
767 for (i = 0; i < quantity; i++) {
769 if (ModbusExtractUint16(modbus, &word, input, input_len, offset))
798 uint16_t
address = 0, quantity = 0, word = 0;
802 if (ModbusExtractUint16(modbus, &address, input, input_len, offset))
805 if (address != tx->
write.address)
810 if (tx->
data != NULL)
813 if (ModbusExtractUint16(modbus, &word, input, input_len, offset))
817 if (word != tx->
data[0])
822 if (ModbusExtractUint16(modbus, &quantity, input, input_len, offset))
837 if (quantity != tx->
write.quantity)
841 if (tx->
data != NULL)
844 if (ModbusExtractUint16(modbus, &word, input, input_len, offset))
848 if (word != tx->
data[0])
852 if (ModbusExtractUint16(modbus, &word, input, input_len, offset))
856 if (word != tx->
data[1])
862 ModbusCheckHeaderLength(modbus, tx->
length, 8);
869 ModbusCheckHeaderLength(modbus, tx->
length, 6);
900 if (ModbusExtractUint16(modbus, &(tx->
subFunction), input, input_len, offset))
904 if (ModbusExtractUint16(modbus, &data, input, input_len, offset))
910 if ((data != 0x00) && (data != 0xFF00))
915 if ((data & 0xFF) != 0x00)
946 ModbusCheckHeaderLength(modbus, tx->
length, 6);
1000 if (ModbusExtractUint8(modbus, &(tx->
function), input, input_len, &offset))
1067 if (ModbusExtractUint8(modbus, &count, input, input_len, &offset))
1071 ModbusCheckHeaderLength(modbus, tx->
length, 2 + count);
1075 if(ModbusParseDiagnosticRequest(tx, modbus, input, input_len, &offset))
1084 ModbusCheckHeaderLength(modbus, tx->
length, 2);
1089 ModbusCheckHeaderLength(modbus, tx->
length, 4);
1094 if (ModbusExtractUint8(modbus, &(tx->
mei), input, input_len, &offset))
1099 ModbusCheckHeaderLength(modbus, tx->
length, 5);
1127 ModbusParseReadRequest(tx, modbus, input, input_len, &offset);
1130 ModbusParseWriteRequest(tx, modbus, input, input_len, &offset);
1152 uint8_t count = 0, error =
FALSE,
function = 0, mei = 0;
1155 if (ModbusExtractUint8(modbus, &
function, input, input_len, &offset))
1167 ModbusExceptionResponse(tx, modbus, input, input_len, &offset);
1172 ModbusCheckHeaderLength(modbus, tx->
length, 3);
1177 ModbusCheckHeaderLength(modbus, tx->
length, 6);
1183 if (ModbusExtractUint8(modbus, &count, input, input_len, &offset))
1187 ModbusCheckHeaderLength(modbus, tx->
length, 2 + count);
1192 if (ModbusExtractUint8(modbus, &mei, input, input_len, &offset))
1201 ModbusParseReadResponse(tx, modbus, input, input_len, &offset);
1204 ModbusParseWriteResponse(tx, modbus, input, input_len, &offset);
1224 uint16_t offset = 0;
1229 uint16_t transaction_id = 0;
1230 uint16_t protocol_id = 0;
1231 uint16_t length = 0;
1232 uint8_t unit_id = 0;
1235 r = ModbusExtractUint16(modbus, &transaction_id, input, input_len, &offset);
1237 r |= ModbusExtractUint16(modbus, &protocol_id, input, input_len, &offset);
1239 r |= ModbusExtractUint16(modbus, &length, input, input_len, &offset);
1241 r |= ModbusExtractUint8(modbus, &unit_id, input, input_len, &offset);
1249 header->
unitId = unit_id;
1264 static int ModbusParseRequest(
Flow *f,
1270 const uint8_t
flags)
1279 }
else if (input == NULL || input_len == 0) {
1283 while (input_len > 0) {
1284 uint32_t adu_len = input_len;
1285 uint8_t *adu = input;
1288 if (ModbusParseHeader(modbus, &header, adu, adu_len))
1293 if (adu_len > input_len)
1297 tx = ModbusTxAlloc(modbus);
1302 ModbusCheckHeader(modbus, &header);
1310 ModbusParseRequestPDU(tx, modbus, adu, adu_len);
1314 input_len -= adu_len;
1329 static int ModbusParseResponse(
Flow *f,
1335 const uint8_t flags)
1344 }
else if (input == NULL || input_len == 0) {
1348 while (input_len > 0) {
1349 uint32_t adu_len = input_len;
1350 uint8_t *adu = input;
1353 if (ModbusParseHeader(modbus, &header, adu, adu_len))
1358 if (adu_len > input_len)
1362 tx = ModbusTxFindByTransaction(modbus, header.
transactionId);
1366 tx = ModbusTxAlloc(modbus);
1370 SCLogDebug(
"MODBUS_DECODER_EVENT_UNSOLICITED_RESPONSE");
1377 ModbusParseResponsePDU(tx, modbus, adu, adu_len);
1381 ModbusCheckHeader(modbus, &header);
1388 input_len -= adu_len;
1397 static void *ModbusStateAlloc(
void)
1407 return (
void *) modbus;
1413 static void ModbusStateFree(
void *state)
1429 static uint16_t ModbusProbingParser(
Flow *f,
1465 const char *proto_name =
"modbus";
1477 ModbusProbingParser, NULL);
1484 ModbusProbingParser, NULL)) {
1485 #ifndef AFLFUZZ_APPLAYER 1492 p =
ConfGetNode(
"app-layer.protocols.modbus.request-flood");
1498 request_flood = value;
1501 SCLogConfig(
"Modbus request flood protection level: %u", request_flood);
1503 p =
ConfGetNode(
"app-layer.protocols.modbus.stream-depth");
1509 stream_depth = value;
1512 SCLogConfig(
"Modbus stream depth: %u", stream_depth);
1514 #ifndef AFLFUZZ_APPLAYER 1515 SCLogConfig(
"Protocol detection and parser disabled for %s protocol.", proto_name);
1526 ModbusGetTxDetectState, ModbusSetTxDetectState);
1536 ModbusGetAlstateProgressCompletionStatus);
1544 SCLogConfig(
"Parsed disabled for %s protocol. Protocol detection" "still on.", proto_name);
1568 static uint8_t invalidFunctionCode[] = { 0x00, 0x00,
1576 static uint8_t readCoilsReq[] = { 0x00, 0x00,
1584 static uint8_t readCoilsRsp[] = { 0x00, 0x00,
1592 static uint8_t readCoilsErrorRsp[] = { 0x00, 0x00,
1601 static uint8_t writeSingleRegisterReq[] = { 0x00, 0x0A,
1609 static uint8_t invalidWriteSingleRegisterReq[] = { 0x00, 0x0A,
1616 static uint8_t writeSingleRegisterRsp[] = { 0x00, 0x0A,
1626 static uint8_t writeMultipleRegistersReq[] = { 0x00, 0x0A,
1637 static uint8_t writeMultipleRegistersRsp[] = { 0x00, 0x0A,
1647 static uint8_t maskWriteRegisterReq[] = { 0x00, 0x0A,
1656 static uint8_t invalidMaskWriteRegisterReq[] = { 0x00, 0x0A,
1664 static uint8_t maskWriteRegisterRsp[] = { 0x00, 0x0A,
1676 static uint8_t readWriteMultipleRegistersReq[] = { 0x12, 0x34,
1691 static uint8_t readWriteMultipleRegistersRsp[] = { 0x12, 0x34,
1706 static uint8_t forceListenOnlyMode[] = { 0x0A, 0x00,
1714 static uint8_t invalidProtocolIdReq[] = { 0x00, 0x00,
1722 static uint8_t invalidLengthWriteMultipleRegistersReq[] = {
1734 static uint8_t exceededLengthWriteMultipleRegistersReq[] = {
1744 static uint8_t invalidLengthPDUWriteMultipleRegistersReq[] = {
1752 static int ModbusParserTest01(
void) {
1759 memset(&f, 0,
sizeof(f));
1760 memset(&ssn, 0,
sizeof(ssn));
1764 f.
proto = IPPROTO_TCP;
1772 sizeof(readCoilsReq));
1787 sizeof(readCoilsRsp));
1800 static int ModbusParserTest02(
void) {
1807 memset(&f, 0,
sizeof(f));
1808 memset(&ssn, 0,
sizeof(ssn));
1812 f.
proto = IPPROTO_TCP;
1820 sizeof(writeMultipleRegistersReq));
1839 sizeof(writeMultipleRegistersRsp));
1852 static int ModbusParserTest03(
void) {
1864 memset(&f, 0,
sizeof(
Flow));
1872 f.
proto = IPPROTO_TCP;
1887 "(msg:\"Modbus Data mismatch\"; " 1889 "modbus.value_mismatch; " 1899 readWriteMultipleRegistersReq,
1900 sizeof(readWriteMultipleRegistersReq));
1922 sizeof(readWriteMultipleRegistersRsp));
1947 static int ModbusParserTest04(
void) {
1954 memset(&f, 0,
sizeof(f));
1955 memset(&ssn, 0,
sizeof(ssn));
1959 f.
proto = IPPROTO_TCP;
1967 sizeof(forceListenOnlyMode));
1986 static int ModbusParserTest05(
void) {
1998 memset(&f, 0,
sizeof(
Flow));
2006 f.
proto = IPPROTO_TCP;
2021 "(msg:\"Modbus invalid Protocol version\"; " 2023 "modbus.invalid_protocol_id; " 2033 sizeof(invalidProtocolIdReq));
2059 static int ModbusParserTest06(
void) {
2071 memset(&f, 0,
sizeof(
Flow));
2079 f.
proto = IPPROTO_TCP;
2094 "(msg:\"Modbus unsolicited response\"; " 2096 "modbus.unsolicited_response; " 2106 sizeof(readCoilsRsp));
2132 static int ModbusParserTest07(
void) {
2144 memset(&f, 0,
sizeof(
Flow));
2152 f.
proto = IPPROTO_TCP;
2167 "(msg:\"Modbus invalid Length\"; " 2169 "modbus.invalid_length; " 2179 invalidLengthWriteMultipleRegistersReq,
2180 sizeof(invalidLengthWriteMultipleRegistersReq));
2206 static int ModbusParserTest08(
void) {
2218 memset(&f, 0,
sizeof(
Flow));
2226 f.
proto = IPPROTO_TCP;
2241 "(msg:\"Modbus Exception code invalid\"; " 2243 "modbus.invalid_exception_code; " 2253 sizeof(readCoilsReq));
2269 sizeof(readCoilsErrorRsp));
2294 static int ModbusParserTest09(
void) {
2299 uint32_t input_len =
sizeof(readCoilsReq), part2_len = 3;
2300 uint8_t *input = readCoilsReq;
2304 memset(&f, 0,
sizeof(f));
2305 memset(&ssn, 0,
sizeof(ssn));
2309 f.
proto = IPPROTO_TCP;
2333 input_len =
sizeof(readCoilsRsp);
2335 input = readCoilsRsp;
2356 static int ModbusParserTest10(
void) {
2357 uint32_t input_len =
sizeof(readCoilsReq) +
sizeof(writeMultipleRegistersReq);
2358 uint8_t *input, *ptr;
2366 input = (uint8_t *)
SCMalloc (input_len *
sizeof(uint8_t));
2369 memcpy(input, readCoilsReq,
sizeof(readCoilsReq));
2370 memcpy(input +
sizeof(readCoilsReq), writeMultipleRegistersReq,
sizeof(writeMultipleRegistersReq));
2372 memset(&f, 0,
sizeof(f));
2373 memset(&ssn, 0,
sizeof(ssn));
2377 f.
proto = IPPROTO_TCP;
2402 input_len =
sizeof(readCoilsRsp) +
sizeof(writeMultipleRegistersRsp);
2404 ptr = (uint8_t *)
SCRealloc (input, input_len *
sizeof(uint8_t));
2408 memcpy(input, readCoilsRsp,
sizeof(readCoilsRsp));
2409 memcpy(input +
sizeof(readCoilsRsp), writeMultipleRegistersRsp,
sizeof(writeMultipleRegistersRsp));
2425 static int ModbusParserTest11(
void) {
2437 memset(&f, 0,
sizeof(
Flow));
2445 f.
proto = IPPROTO_TCP;
2460 "(msg:\"Modbus invalid Length\"; " 2462 "modbus.invalid_length; " 2472 exceededLengthWriteMultipleRegistersReq,
2473 sizeof(exceededLengthWriteMultipleRegistersReq) + 65523 *
sizeof(uint8_t));
2499 static int ModbusParserTest12(
void) {
2511 memset(&f, 0,
sizeof(
Flow));
2519 f.
proto = IPPROTO_TCP;
2534 "(msg:\"Modbus invalid Length\"; " 2536 "modbus.invalid_length; " 2546 invalidLengthPDUWriteMultipleRegistersReq,
2547 sizeof(invalidLengthPDUWriteMultipleRegistersReq));
2573 static int ModbusParserTest13(
void) {
2580 memset(&f, 0,
sizeof(f));
2581 memset(&ssn, 0,
sizeof(ssn));
2585 f.
proto = IPPROTO_TCP;
2593 sizeof(maskWriteRegisterReq));
2609 sizeof(maskWriteRegisterRsp));
2622 static int ModbusParserTest14(
void) {
2629 memset(&f, 0,
sizeof(f));
2630 memset(&ssn, 0,
sizeof(ssn));
2634 f.
proto = IPPROTO_TCP;
2642 sizeof(writeSingleRegisterReq));
2658 sizeof(writeSingleRegisterRsp));
2671 static int ModbusParserTest15(
void) {
2683 memset(&f, 0,
sizeof(f));
2684 memset(&ssn, 0,
sizeof(ssn));
2691 f.
proto = IPPROTO_TCP;
2706 "(msg:\"Modbus invalid Length\"; " 2708 "modbus.invalid_length; " 2718 sizeof(invalidMaskWriteRegisterReq));
2737 sizeof(maskWriteRegisterRsp));
2757 static int ModbusParserTest16(
void) {
2769 memset(&f, 0,
sizeof(f));
2770 memset(&ssn, 0,
sizeof(ssn));
2777 f.
proto = IPPROTO_TCP;
2792 "(msg:\"Modbus invalid Length\"; " 2794 "modbus.invalid_length; " 2804 invalidWriteSingleRegisterReq,
2805 sizeof(invalidWriteSingleRegisterReq));
2825 sizeof(writeSingleRegisterRsp));
2844 static int ModbusParserTest17(
void) {
2851 memset(&f, 0,
sizeof(f));
2852 memset(&ssn, 0,
sizeof(ssn));
2856 f.
proto = IPPROTO_TCP;
2863 readCoilsReq,
sizeof(readCoilsReq));
2873 readCoilsRsp,
sizeof(readCoilsRsp));
2886 static int ModbusParserTest18(
void) {
2891 uint32_t input_len =
sizeof(readCoilsReq), part2_len = 3;
2892 uint8_t *input = readCoilsReq;
2896 memset(&f, 0,
sizeof(f));
2897 memset(&ssn, 0,
sizeof(ssn));
2901 f.
proto = IPPROTO_TCP;
2908 input, input_len - part2_len);
2924 input_len =
sizeof(readCoilsRsp);
2926 input = readCoilsRsp;
2930 input, input_len - part2_len);
2951 static int ModbusParserTest19(
void) {
2963 memset(&f, 0,
sizeof(
Flow));
2971 f.
proto = IPPROTO_TCP;
2986 "(msg:\"Modbus invalid Function code\"; " 2988 "modbus.invalid_function_code; " 2998 invalidFunctionCode,
2999 sizeof(invalidFunctionCode));
3028 ModbusParserTest01);
3029 UtRegisterTest(
"ModbusParserTest02 - Modbus Write Multiple registers request",
3030 ModbusParserTest02);
3031 UtRegisterTest(
"ModbusParserTest03 - Modbus Read/Write Multiple registers request",
3032 ModbusParserTest03);
3033 UtRegisterTest(
"ModbusParserTest04 - Modbus Force Listen Only Mode request",
3034 ModbusParserTest04);
3035 UtRegisterTest(
"ModbusParserTest05 - Modbus invalid Protocol version",
3036 ModbusParserTest05);
3037 UtRegisterTest(
"ModbusParserTest06 - Modbus unsolicited response",
3038 ModbusParserTest06);
3039 UtRegisterTest(
"ModbusParserTest07 - Modbus invalid Length request",
3040 ModbusParserTest07);
3041 UtRegisterTest(
"ModbusParserTest08 - Modbus Exception code invalid",
3042 ModbusParserTest08);
3043 UtRegisterTest(
"ModbusParserTest09 - Modbus fragmentation - 1 ADU in 2 TCP packets",
3044 ModbusParserTest09);
3045 UtRegisterTest(
"ModbusParserTest10 - Modbus fragmentation - 2 ADU in 1 TCP packet",
3046 ModbusParserTest10);
3047 UtRegisterTest(
"ModbusParserTest11 - Modbus exceeded Length request",
3048 ModbusParserTest11);
3050 ModbusParserTest12);
3051 UtRegisterTest(
"ModbusParserTest13 - Modbus Mask Write register request",
3052 ModbusParserTest13);
3053 UtRegisterTest(
"ModbusParserTest14 - Modbus Write single register request",
3054 ModbusParserTest14);
3055 UtRegisterTest(
"ModbusParserTest15 - Modbus invalid Mask Write register request",
3056 ModbusParserTest15);
3057 UtRegisterTest(
"ModbusParserTest16 - Modbus invalid Write single register request",
3058 ModbusParserTest16);
3060 ModbusParserTest17);
3061 UtRegisterTest(
"ModbusParserTest18 - Modbus stream depth in 2 TCP packets",
3062 ModbusParserTest18);
3063 UtRegisterTest(
"ModbusParserTest19 - Modbus invalid Function code",
3064 ModbusParserTest19);
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
#define MODBUS_SUBFUNC_SERVER_BUSY_COUNT
void AppLayerParserSetStreamDepth(uint8_t ipproto, AppProto alproto, uint32_t stream_depth)
struct ModbusState_ * modbus
#define MODBUS_FUNC_ENCAPINTTRANS
enum AppLayerEventType_ AppLayerEventType
#define MODBUS_MIN_QUANTITY
void AppLayerProtoDetectPPRegister(uint8_t ipproto, const char *portstr, AppProto alproto, uint16_t min_depth, uint16_t max_depth, uint8_t direction, ProbingParserFPtr ProbingParser1, ProbingParserFPtr ProbingParser2)
register parser at a port
struct ModbusTransaction_::@18::@20::@22 read
#define TAILQ_FOREACH(var, head, field)
struct HtpBodyChunk_ * next
#define MODBUS_ERROR_CODE_ILLEGAL_FUNCTION
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
void AppLayerParserRegisterGetStateProgressFunc(uint8_t ipproto, AppProto alproto, int(*StateGetProgress)(void *alstate, uint8_t direction))
void ModbusParserRegisterTests(void)
#define MODBUS_TYP_ACCESS_FUNCTION_MASK
#define MODBUS_SUBFUNC_DIAG_REGS
#define FLOWLOCK_UNLOCK(fb)
#define MODBUS_CAT_USER_DEFINED
#define PASS
Pass the test.
int AppLayerProtoDetectConfProtoDetectionEnabled(const char *ipproto, const char *alproto)
Given a protocol name, checks if proto detection is enabled in the conf file.
int AppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint8_t flag)
void AppLayerParserRegisterParserAcceptableDataDirection(uint8_t ipproto, AppProto alproto, uint8_t direction)
void AppLayerParserRegisterDetectStateFuncs(uint8_t ipproto, AppProto alproto, DetectEngineState *(*GetTxDetectState)(void *tx), int(*SetTxDetectState)(void *tx, DetectEngineState *))
#define MODBUS_FUNC_WRITESINGLECOIL
#define MODBUS_SUBFUNC_COM_ERR_COUNT
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
#define MODBUS_PROTOCOL_VER
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
#define MODBUS_FUNC_GETCOMEVTCOUNTER
#define MODBUS_FUNC_MASKWRITEREG
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
#define FLOW_PKT_ESTABLISHED
void SigCleanSignatures(DetectEngineCtx *de_ctx)
#define MODBUS_ERROR_CODE_MEMORY_PARITY_ERROR
AppLayerDecoderEvents * decoder_events
void AppLayerDecoderEventsSetEventRaw(AppLayerDecoderEvents **sevents, uint8_t event)
Set an app layer decoder event.
void StreamTcpFreeConfig(char quiet)
#define MODBUS_FUNC_GETCOMEVTLOG
#define FLOWLOCK_WRLOCK(fb)
#define MODBUS_MEI_ENCAPINTTRANS_READ
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
int SCMapEnumNameToValue(const char *enum_name, SCEnumCharMap *table)
Maps a string name to an enum value from the supplied table. Please specify the last element of any m...
void AppLayerParserRegisterLoggerFuncs(uint8_t ipproto, AppProto alproto, LoggerId(*StateGetTxLogged)(void *, void *), void(*StateSetTxLogged)(void *, void *, LoggerId))
#define MODBUS_TYP_MULTIPLE
#define MODBUS_FUNC_READCOILS
#define MODBUS_FUNC_READDISCINPUTS
#define MODBUS_SUBFUNC_SERVER_NO_RSP_COUNT
#define MODBUS_FUNC_WRITESINGLEREG
main detection engine ctx
#define MODBUS_ERROR_CODE_ILLEGAL_DATA_VALUE
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
#define MODBUS_MAX_INVALID_UNIT_ID
#define MODBUS_TYP_BIT_ACCESS_MASK
SCEnumCharMap modbus_decoder_event_table[]
int AppLayerParserConfParserEnabled(const char *ipproto, const char *alproto_name)
check if a parser is enabled in the config Returns enabled always if: were running unittests and when...
#define MODBUS_MIN_INVALID_UNIT_ID
Data structure to store app layer decoder events.
int AppLayerParserRegisterParser(uint8_t ipproto, AppProto alproto, uint8_t direction, AppLayerParserFPtr Parser)
Register app layer parser for the protocol.
#define MODBUS_FUNC_WRITEFILERECORD
void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto, void *(StateGetTx)(void *alstate, uint64_t tx_id))
#define MODBUS_FUNC_ERRORMASK
#define MODBUS_FUNC_WRITEMULTREGS
int AppLayerProtoDetectPPParseConfPorts(const char *ipproto_name, uint8_t ipproto, const char *alproto_name, AppProto alproto, uint16_t min_depth, uint16_t max_depth, ProbingParserFPtr ProbingParserTs, ProbingParserFPtr ProbingParserTc)
void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto, int(*StateGetEventInfo)(const char *event_name, int *event_id, AppLayerEventType *event_type))
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
#define MODBUS_TYP_DISCRETES
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
#define MODBUS_TYP_SINGLE
#define MODBUS_FUNC_READFIFOQUEUE
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define MODBUS_CAT_PUBLIC_UNASSIGNED
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
#define TAILQ_REMOVE(head, elm, field)
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
#define MODBUS_MIN_ADU_LEN
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
#define FLOW_PKT_TOSERVER
void AppLayerParserRegisterGetStateProgressCompletionStatus(AppProto alproto, int(*StateGetProgressCompletionStatus)(uint8_t direction))
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
void DetectEngineStateFree(DetectEngineState *state)
Frees a DetectEngineState object.
int SigGroupCleanup(DetectEngineCtx *de_ctx)
#define MODBUS_SUBFUNC_CLEAR_REGS
int RunmodeIsUnittests(void)
#define MODBUS_FUNC_READWRITEMULTREGS
#define MODBUS_SUBFUNC_RESTART_COM
#define MODBUS_SUBFUNC_SERVER_CHAR_COUNT
#define MODBUS_MAX_QUANTITY_IN_WORD_ACCESS
#define MODBUS_TYP_HOLDING
#define TAILQ_INSERT_TAIL(head, elm, field)
#define MODBUS_MEI_ENCAPINTTRANS_CAN
void AppLayerDecoderEventsFreeEvents(AppLayerDecoderEvents **events)
#define MODBUS_ERROR_CODE_ILLEGAL_DATA_ADDRESS
struct ModbusFunctionCodeRange_ ModbusFunctionCodeRange
#define MODBUS_FUNC_READFILERECORD
DetectEngineState * de_state
#define MODBUS_MAX_QUANTITY_IN_BIT_ACCESS
#define MODBUS_FUNC_DIAGNOSTIC
#define MODBUS_TYP_WRITE_MULTIPLE
void AppLayerProtoDetectRegisterProtocol(AppProto alproto, const char *alproto_name)
Registers a protocol for protocol detection phase.
#define MODBUS_MAX_ADU_LEN
void AppLayerParserRegisterGetEventsFunc(uint8_t ipproto, AppProto alproto, AppLayerDecoderEvents *(*StateGetEvents)(void *, uint64_t))
void AppLayerParserRegisterProtocolUnittests(uint8_t ipproto, AppProto alproto, void(*RegisterUnittests)(void))
#define MODBUS_TYP_WRITE_SINGLE
#define MODBUS_FUNC_WRITEMULTCOILS
#define MODBUS_FUNC_READEXCSTATUS
int ByteExtractUint16(uint16_t *res, int e, uint16_t len, const uint8_t *bytes)
void RegisterModbusParsers(void)
Function to register the Modbus protocol parsers and other functions.
#define FLOW_INITIALIZE(f)
#define MODBUS_ERROR_CODE_SERVER_DEVICE_FAILURE
#define APP_LAYER_PARSER_EOF
#define MODBUS_SUBFUNC_BUS_MSG_COUNT
#define MODBUS_CONFIG_DEFAULT_REQUEST_FLOOD
#define MODBUS_SUBFUNC_QUERY_DATA
#define MODBUS_SUBFUNC_EXCEPT_ERR_COUNT
ConfNode * ConfGetNode(const char *name)
Get a ConfNode by name.
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
struct ModbusTransaction_::@18::@20::@23 write
#define MODBUS_CONFIG_DEFAULT_STREAM_DEPTH
#define MODBUS_SUBFUNC_SERVER_NAK_COUNT
#define MODBUS_CAT_PUBLIC_ASSIGNED
void AppLayerParserRegisterGetTxCnt(uint8_t ipproto, AppProto alproto, uint64_t(*StateGetTxCnt)(void *alstate))
#define MODBUS_TYP_READ_WRITE_MULTIPLE
void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto, void *(*StateAlloc)(void), void(*StateFree)(void *))
Per thread variable structure.
int ParseSizeStringU32(const char *size, uint32_t *res)
AppProto alproto
application level protocol
#define MODBUS_CAT_RESERVED
#define MODBUS_SUBFUNC_CLEAR_COUNT
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
#define MODBUS_SUBFUNC_SERVER_MSG_COUNT
#define MODBUS_SUBFUNC_CHANGE_DELIMITER
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
#define MODBUS_FUNC_REPORTSERVERID
#define MODBUS_FUNC_READINPUTREGS
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself...
#define MODBUS_FUNC_READHOLDREGS
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, uint8_t *input, uint32_t input_len)
#define MODBUS_SUBFUNC_LISTEN_MODE
struct ModbusHeader_ __attribute__((__packed__))
DNP3 link header.
DetectEngineCtx * DetectEngineCtxInit(void)
void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto, void(*StateTransactionFree)(void *, uint64_t))