diff options
Diffstat (limited to 'epan')
-rw-r--r-- | epan/crc16-tvb.c | 11 | ||||
-rw-r--r-- | epan/crc16-tvb.h | 16 | ||||
-rw-r--r-- | epan/dissectors/packet-mbtcp.c | 22 | ||||
-rw-r--r-- | epan/libwireshark.def | 1 |
4 files changed, 46 insertions, 4 deletions
diff --git a/epan/crc16-tvb.c b/epan/crc16-tvb.c index ea86e4b12a..ee77803a31 100644 --- a/epan/crc16-tvb.c +++ b/epan/crc16-tvb.c @@ -102,3 +102,14 @@ guint16 crc16_plain_tvb_offset(tvbuff_t *tvb, guint offset, guint len) return crc16_plain_finalize(crc); } +guint16 crc16_plain_tvb_offset_seed(tvbuff_t *tvb, guint offset, guint len, guint16 crc) +{ + const guint8 *buf; + + tvb_ensure_bytes_exist(tvb, offset, len); /* len == -1 not allowed */ + buf = tvb_get_ptr(tvb, offset, len); + + crc = crc16_plain_update(crc, buf, len); + + return crc16_plain_finalize(crc); +} diff --git a/epan/crc16-tvb.h b/epan/crc16-tvb.h index 0a49bda326..bad28217e3 100644 --- a/epan/crc16-tvb.h +++ b/epan/crc16-tvb.h @@ -86,6 +86,22 @@ extern guint16 crc16_ccitt_tvb_offset_seed(tvbuff_t *tvb, guint offset, @return The CRC16 checksum. */ extern guint16 crc16_plain_tvb_offset(tvbuff_t *tvb, guint offset, guint len); +/** Compute the "plain" CRC16 checksum of a tv buffer using the following + * parameters: + * Width = 16 + * Poly = 0x8005 + * XorIn = 0x0000 + * ReflectIn = True + * XorOut = 0x0000 + * ReflectOut = True + * Algorithm = table-driven + * Direct = True + @param tvb The tv buffer containing the data. + @param offset The offset into the tv buffer. + @param len The number of bytes to include in the computation. + @param crc Starting CRC value + @return The CRC16 checksum. */ +extern guint16 crc16_plain_tvb_offset_seed(tvbuff_t *tvb, guint offset, guint len, guint16 crc); #ifdef __cplusplus } diff --git a/epan/dissectors/packet-mbtcp.c b/epan/dissectors/packet-mbtcp.c index d0c13224d0..4605f58196 100644 --- a/epan/dissectors/packet-mbtcp.c +++ b/epan/dissectors/packet-mbtcp.c @@ -77,6 +77,7 @@ #include "packet-mbtcp.h" #include <epan/prefs.h> #include <epan/expert.h> +#include <epan/crc16-tvb.h> /* For CRC verification */\ /* Initialize the protocol and registered fields */ static int proto_mbtcp = -1; @@ -172,6 +173,7 @@ static gboolean mbrtu_desegment = TRUE; static guint global_mbus_rtu_port = PORT_MBRTU; /* 0, by default */ static gint global_mbus_rtu_register_format = MBTCP_PREF_REGISTER_FORMAT_UINT16; static gint global_mbus_rtu_register_addr_type = MBTCP_PREF_REGISTER_ADDR_RAW; +static gboolean mbrtu_crc = FALSE; static int classify_mbtcp_packet(packet_info *pinfo) @@ -474,14 +476,14 @@ static void dissect_mbrtu_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Set up structures needed to add the protocol subtree and manage it */ - proto_item *mi; + proto_item *mi, *crc_item; proto_tree *mbrtu_tree; gint offset, packet_type; tvbuff_t *next_tvb; const char *func_string = ""; const char *pkt_type_str = ""; const char *err_str = ""; - guint16 len, crc16; + guint16 len, crc16, calc_crc16; guint8 unit_id, function_code, exception_code, subfunction_code; void *p_save_proto_data; modbus_request_info_t *request_info; @@ -578,9 +580,15 @@ dissect_mbrtu_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* Add items to protocol tree specific to Modbus RTU */ proto_tree_add_uint(mbrtu_tree, hf_mbrtu_unitid, tvb, offset, 1, unit_id); - proto_tree_add_uint(mbrtu_tree, hf_mbrtu_crc16, tvb, len-2, 2, crc16); + crc_item = proto_tree_add_uint(mbrtu_tree, hf_mbrtu_crc16, tvb, len-2, 2, crc16); - /* XXX - TODO CRC validation */ + /* CRC validation */ + if (mbrtu_crc) + { + calc_crc16 = crc16_plain_tvb_offset_seed(tvb, offset, len-2, 0xFFFF); + if (g_htons(calc_crc16) != crc16) + expert_add_info_format(pinfo, crc_item, PI_PROTOCOL, PI_WARN, "Incorrect CRC - should be 0x%04x", g_htons(calc_crc16)); + } /* make sure to ignore the CRC-16 footer bytes */ len = len - 2; @@ -1736,6 +1744,12 @@ proto_register_modbus(void) "Whether the Modbus RTU dissector should desegment all messages spanning multiple TCP segments", &mbrtu_desegment); + /* Modbus RTU Preference - CRC verification, defaults to FALSE (not do verification)*/ + prefs_register_bool_preference(mbrtu_module, "crc_verification", + "Validate CRC", + "Whether to validate the CRC", + &mbrtu_crc); + /* Modbus RTU Preference - Default TCP Port, defaults to zero, allows custom user port. */ prefs_register_uint_preference(mbrtu_module, "tcp.port", "Modbus RTU Port", "Set the TCP port for encapsulated Modbus RTU packets", diff --git a/epan/libwireshark.def b/epan/libwireshark.def index 28eaadad69..ffffe1b042 100644 --- a/epan/libwireshark.def +++ b/epan/libwireshark.def @@ -116,6 +116,7 @@ copy_file_binary_mode copy_persconffile_profile crc16_ccitt_tvb crc16_plain_tvb_offset +crc16_plain_tvb_offset_seed crc16_ccitt_tvb_offset crc16_ccitt_tvb_offset_seed crc16_ccitt_tvb_seed |