diff options
author | Aitor Garcia <garcia.aitor@gmail.com> | 2020-12-29 00:14:05 +0100 |
---|---|---|
committer | Pascal Quantin <pascal@wireshark.org> | 2020-12-29 20:13:19 +0100 |
commit | 8454674581f6d98473f7870902bd4a42202a69ec (patch) | |
tree | 61087a5abf39b782b633aa81ea1954c0556b803c /epan/dissectors/asn1/goose | |
parent | 71e3969d63d70e1e57b58568926534e963bd3b31 (diff) |
GOOSE: Interpret reserve1 S bit
The simulated mirror bit of the reserve1 field is now interpreted.
New expert info warning: S bit set and simulation attribute clear.
Diffstat (limited to 'epan/dissectors/asn1/goose')
-rw-r--r-- | epan/dissectors/asn1/goose/goose.cnf | 16 | ||||
-rw-r--r-- | epan/dissectors/asn1/goose/packet-goose-template.c | 70 |
2 files changed, 79 insertions, 7 deletions
diff --git a/epan/dissectors/asn1/goose/goose.cnf b/epan/dissectors/asn1/goose/goose.cnf index 750ed29741..6b3ab1131e 100644 --- a/epan/dissectors/asn1/goose/goose.cnf +++ b/epan/dissectors/asn1/goose/goose.cnf @@ -16,6 +16,22 @@ GetReferenceRequestPdu/offset getReferenceRequest_offset #.FIELD_ATTR GetReferenceRequestPdu/offset ABBREV=getReferenceRequest.offset +#.FN_BODY IECGoosePdu/simulation VAL_PTR = &value + gboolean value; + guint32 len = tvb_reported_length_remaining(tvb, offset); + int origin_offset = offset; +%(DEFAULT_BODY)s + if((actx->private_data) && (actx->created_item)){ + goose_chk_data_t *data_chk = (goose_chk_data_t *)actx->private_data; + proto_tree *expert_inf_tree = NULL; + /* S bit set and Simulation attribute clear: reject as invalid GOOSE */ + if((data_chk->s_bit == TRUE) && (value == FALSE)){ + /* It really looks better showed as a new subtree */ + expert_inf_tree = proto_item_add_subtree(actx->created_item, ett_expert_inf_sim); + proto_tree_add_expert(expert_inf_tree, actx->pinfo, &ei_goose_invalid_sim, tvb, origin_offset, len); + } + } +#.END #.FN_BODY UtcTime diff --git a/epan/dissectors/asn1/goose/packet-goose-template.c b/epan/dissectors/asn1/goose/packet-goose-template.c index 197972c51e..5a8360c0b7 100644 --- a/epan/dissectors/asn1/goose/packet-goose-template.c +++ b/epan/dissectors/asn1/goose/packet-goose-template.c @@ -3,8 +3,8 @@ * Martin Lutz 2008 * * Routines for IEC 61850 R-GOOSE packet dissection - * Đorđije Manojlović 2020 - * + * Dordije Manojlovic 2020 + * * Wireshark - Network traffic analyzer * By Gerald Combs <gerald@wireshark.org> * Copyright 1998 Gerald Combs @@ -65,10 +65,21 @@ static int hf_goose_hmac = -1; static int hf_goose_appid = -1; static int hf_goose_length = -1; static int hf_goose_reserve1 = -1; +static int hf_goose_reserve1_s_bit = -1; static int hf_goose_reserve2 = -1; +/* Bit fields in the Reserved fields */ +#define F_RESERVE1_S_BIT 0x8000 + +/* GOOSE stored data for expert info verifications */ +typedef struct _goose_chk_data{ + gboolean s_bit; +}goose_chk_data_t; +#define GOOSE_CHK_DATA_LEN (sizeof(goose_chk_data_t)) + static expert_field ei_goose_mal_utctime = EI_INIT; static expert_field ei_goose_zero_pdu = EI_INIT; +static expert_field ei_goose_invalid_sim = EI_INIT; #include "packet-goose-hf.c" @@ -80,6 +91,8 @@ static int ett_session_user_info = -1; static int ett_payload = -1; static int ett_padding = -1; static int ett_goose = -1; +static int ett_reserve1 = -1; +static int ett_expert_inf_sim = -1; #include "packet-goose-ett.c" @@ -127,11 +140,21 @@ dissect_goose(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, guint32 offset = 0; guint32 old_offset; guint32 length; + guint32 reserve1_val; proto_item *item = NULL; proto_tree *tree = NULL; + goose_chk_data_t *data_chk = NULL; asn1_ctx_t asn1_ctx; asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + static int * const reserve1_flags[] = { + &hf_goose_reserve1_s_bit, + NULL + }; + + asn1_ctx.private_data = wmem_alloc(wmem_packet_scope(), GOOSE_CHK_DATA_LEN); + data_chk = (goose_chk_data_t *)asn1_ctx.private_data; + col_set_str(pinfo->cinfo, COL_PROTOCOL, GOOSE_PNAME); col_clear(pinfo->cinfo, COL_INFO); @@ -147,8 +170,19 @@ dissect_goose(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, ENC_BIG_ENDIAN, &length); /* Reserved 1 */ - proto_tree_add_item(tree, hf_goose_reserve1, tvb, offset + 4, 2, - ENC_BIG_ENDIAN); + reserve1_val = tvb_get_guint16(tvb, offset + 4, ENC_BIG_ENDIAN); + proto_tree_add_bitmask_value(tree, tvb, offset + 4, hf_goose_reserve1, ett_reserve1, + reserve1_flags, reserve1_val); + + /* Store the header sim value for later expert info checks */ + if(data_chk){ + if(reserve1_val & F_RESERVE1_S_BIT){ + data_chk->s_bit = TRUE; + }else{ + data_chk->s_bit = FALSE; + } + } + /* Reserved 2 */ proto_tree_add_item(tree, hf_goose_reserve2, tvb, offset + 6, 2, @@ -177,12 +211,16 @@ dissect_rgoose(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, { guint offset = 0, old_offset = 0; guint32 init_v_length, payload_tag, padding_length, length; - guint32 payload_length, apdu_offset = 0, apdu_length; + guint32 payload_length, apdu_offset = 0, apdu_length, apdu_simulation; proto_item *item = NULL; proto_tree *tree = NULL, *r_goose_tree = NULL, *sess_user_info_tree = NULL; + goose_chk_data_t *data_chk = NULL; asn1_ctx_t asn1_ctx; asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + asn1_ctx.private_data = wmem_alloc(wmem_packet_scope(), GOOSE_CHK_DATA_LEN); + data_chk = (goose_chk_data_t *)asn1_ctx.private_data; + col_set_str(pinfo->cinfo, COL_PROTOCOL, R_GOOSE_PNAME); col_clear(pinfo->cinfo, COL_INFO); @@ -266,8 +304,8 @@ dissect_rgoose(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, proto_tree_add_item_ret_uint(tree, hf_goose_apdu_tag, tvb, offset++, 1, ENC_BIG_ENDIAN, &payload_tag); /* Simulation flag */ - proto_tree_add_item(tree, hf_goose_apdu_simulation, tvb, offset++, 1, - ENC_BIG_ENDIAN); + proto_tree_add_item_ret_uint(tree, hf_goose_apdu_simulation, tvb, offset++, + 1, ENC_BIG_ENDIAN, &apdu_simulation); /* APPID */ proto_tree_add_item(tree, hf_goose_apdu_appid, tvb, offset, 2, ENC_BIG_ENDIAN); @@ -277,6 +315,15 @@ dissect_rgoose(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, return tvb_captured_length(tvb); } + /* Store the header sim value for later expert info checks */ + if(data_chk){ + if(apdu_simulation){ + data_chk->s_bit = TRUE; + }else{ + data_chk->s_bit = FALSE; + } + } + /* APDU length */ proto_tree_add_item_ret_uint(tree, hf_goose_apdu_length, tvb, offset, 2, ENC_BIG_ENDIAN, &apdu_length); @@ -498,6 +545,10 @@ void proto_register_goose(void) { { "Reserved 1", "goose.reserve1", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, + { &hf_goose_reserve1_s_bit, + { "Simulated", "goose.reserve1.s_bit", + FT_BOOLEAN, 16, NULL, F_RESERVE1_S_BIT, "BOOLEAN", HFILL } }, + { &hf_goose_reserve2, { "Reserved 2", "goose.reserve2", FT_UINT16, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }}, @@ -514,6 +565,8 @@ void proto_register_goose(void) { &ett_payload, &ett_padding, &ett_goose, + &ett_reserve1, + &ett_expert_inf_sim, #include "packet-goose-ettarr.c" }; @@ -524,6 +577,9 @@ void proto_register_goose(void) { { &ei_goose_zero_pdu, { "goose.zero_pdu", PI_PROTOCOL, PI_ERROR, "Internal error, zero-byte GOOSE PDU", EXPFILL }}, + { &ei_goose_invalid_sim, + { "goose.invalid_sim", PI_PROTOCOL, PI_WARN, + "Invalid GOOSE: S bit set and Simulation attribute clear", EXPFILL }}, }; expert_module_t* expert_goose; |