diff options
author | Graham Bloice <graham.bloice@trihedral.com> | 2014-07-17 22:28:21 +0100 |
---|---|---|
committer | Graham Bloice <graham.bloice@trihedral.com> | 2014-07-27 17:41:30 +0000 |
commit | ec08f3458ef90cee125e4fca3014e4b662d05770 (patch) | |
tree | de99f438f5443fdcc9e3cf7b369b98b874b73f6b /epan/dissectors/packet-dnp.c | |
parent | b9183b908ab199d5f88cea7b5451a3bd7fc12eef (diff) |
Added function dnp3_header_check() to check the validity of a DNP3
packet as far as possible, called from both dissect_dnp3_tcp and dissect_dnp3_udp.
Bug: 10287
Change-Id: Iaa988258b3614cb1b408dec41a987fbd61c9727c
Reviewed-on: https://code.wireshark.org/review/3096
Petri-Dish: Graham Bloice <graham.bloice@trihedral.com>
Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
Reviewed-by: Graham Bloice <graham.bloice@trihedral.com>
Diffstat (limited to 'epan/dissectors/packet-dnp.c')
-rw-r--r-- | epan/dissectors/packet-dnp.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/epan/dissectors/packet-dnp.c b/epan/dissectors/packet-dnp.c index 9670b34d09..e9dbda5cdf 100644 --- a/epan/dissectors/packet-dnp.c +++ b/epan/dissectors/packet-dnp.c @@ -3381,6 +3381,44 @@ dissect_dnp3_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* return tvb_length(tvb); } +static gboolean +check_dnp3_header(tvbuff_t *tvb) +{ + /* Assume the CRC will be bad */ + gboolean goodCRC = FALSE; + + /* How big is the actual buffer */ + gint length = tvb_captured_length(tvb); + + /* Calculate the header CRC if the bytes are available */ + if (length >= DNP_HDR_LEN) { + guint16 calc_crc = calculateCRC(tvb_get_ptr(tvb, 0, DNP_HDR_LEN - 2), DNP_HDR_LEN - 2); + goodCRC = (calc_crc == tvb_get_letohs(tvb, 8)); + } + + /* For a heuristic match we must have at least a header, beginning with 0x0564 + and a valid header CRC */ + if (dnp3_heuristics) { + if ( !goodCRC || (tvb_get_ntohs(tvb, 0) != 0x0564)) { + return FALSE; + } + } + else { + /* For a non-heuristic match, at least the first byte is 0x05 and if available + the second byte is 64 and if available the CRC is valid */ + if (tvb_get_guint8(tvb, 0) != 0x05) { + return FALSE; + } + if ((length > 1) && (tvb_get_guint8(tvb, 1) != 0x64)) { + return FALSE; + } + if ((length >= DNP_HDR_LEN) && !goodCRC) { + return FALSE; + } + } + return TRUE; +} + static guint get_dnp3_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset) { @@ -3403,11 +3441,7 @@ get_dnp3_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset) static gboolean dissect_dnp3_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { - gint length = tvb_length(tvb); - - /* If heuristics are enabled check it looks like a dnp packet. It should begin with 0x0564 */ - if (dnp3_heuristics && ((length < 2) || (tvb_get_ntohs(tvb, 0) != 0x0564))) { - /* Not a DNP 3.0 packet, just happened to use the same port */ + if (!check_dnp3_header(tvb)) { return FALSE; } @@ -3420,11 +3454,7 @@ dissect_dnp3_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data static gboolean dissect_dnp3_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { - gint length = tvb_length(tvb); - - /* Check for a dnp packet. It should begin with 0x0564 */ - if ((length < 2) || (tvb_get_ntohs(tvb, 0) != 0x0564)) { - /* Not a DNP 3.0 packet, just happened to use the same port */ + if (!check_dnp3_header(tvb)) { return FALSE; } |