MMAS: Add a preference to dissect as iec61850

This commit is contained in:
Anders Broman 2024-04-06 17:30:05 +02:00
parent c56a81d41c
commit 40c420ab9b
3 changed files with 460 additions and 394 deletions

View File

@ -92,7 +92,9 @@ AlterEventEnrollment-Response/currentState/state ABBREV=alterEventEnrollment-
get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
mms_priv->mms_pdu_type = tag;
}
%(DEFAULT_BODY)s
@ -215,6 +217,7 @@ AlterEventEnrollment-Response/currentState/state ABBREV=alterEventEnrollment-
%(DEFAULT_BODY)s
if (hf_index == hf_mms_invokeID){
mms_actx_private_data_t* mms_priv = (mms_actx_private_data_t*)actx->private_data;
if(mms_priv){
mms_priv->invokeid=val;
private_data_add_preCinfo(actx, val);
conversation = find_or_create_conversation(actx->pinfo);
@ -300,7 +303,7 @@ AlterEventEnrollment-Response/currentState/state ABBREV=alterEventEnrollment-
proto_item_set_generated(it);
}
}
}
}
#.FN_BODY FloatingPoint
@ -315,7 +318,7 @@ AlterEventEnrollment-Response/currentState/state ABBREV=alterEventEnrollment-
if (hf_index == hf_mms_domainId) {
private_data_add_moreCinfo_id(actx,tvb);
}
if (hf_index == hf_mms_objectName_domain_specific_itemId) {
if ((mms_priv) && (hf_index == hf_mms_objectName_domain_specific_itemId)) {
private_data_add_moreCinfo_id(actx,tvb);
const char *itemid_str = tvb_get_string_enc(actx->pinfo->pool, tvb, 0, tvb_reported_length(tvb), ENC_ASCII|ENC_NA);
if(g_str_has_suffix(itemid_str,"$ctlModel")){
@ -325,7 +328,7 @@ AlterEventEnrollment-Response/currentState/state ABBREV=alterEventEnrollment-
}
}
if (hf_index == hf_mms_vmd_specific){
if ((mms_priv) && (hf_index == hf_mms_vmd_specific)){
const char *vmd_specific_str = tvb_get_string_enc(actx->pinfo->pool, tvb, 0, tvb_reported_length(tvb), ENC_ASCII|ENC_NA);
if (strcmp(vmd_specific_str, "RPT") == 0) {
mms_priv->vmd_specific = IEC61850_8_1_RPT;
@ -335,13 +338,15 @@ AlterEventEnrollment-Response/currentState/state ABBREV=alterEventEnrollment-
#.FN_BODY InformationReport/listOfAccessResult
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
mms_priv->listOfAccessResult_cnt = 0;
}
%(DEFAULT_BODY)s
#.FN_BODY AccessResult
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
/* If listOfAccessResult_cnt > 2 we are into the optional data.
* if data is not present increase count.
*/
@ -412,12 +417,14 @@ AlterEventEnrollment-Response/currentState/state ABBREV=alterEventEnrollment-
break;
}
} while(!present);
}
%(DEFAULT_BODY)s
#.FN_BODY Data/visible-string
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
if(mms_priv->vmd_specific == IEC61850_8_1_RPT ){
if(mms_priv->listOfAccessResult_cnt == 1){
/* IEC 61850-8-1 RptID */
@ -426,7 +433,7 @@ AlterEventEnrollment-Response/currentState/state ABBREV=alterEventEnrollment-
/* IEC 61850-8-1 DatSet */
hf_index = hf_mms_iec61850_datset;
}
}
}
%(DEFAULT_BODY)s
@ -453,6 +460,7 @@ static int* const quality_field_bits_oct2[] = {
};
tvbuff_t *parameter_tvb;
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
if(mms_priv->vmd_specific == IEC61850_8_1_RPT ){
if(mms_priv->listOfAccessResult_cnt == 2){
/* IEC 61850-8-1 Reported OptFlds */
@ -465,24 +473,30 @@ static int* const quality_field_bits_oct2[] = {
}else if((mms_priv->mms_trans)&&(mms_priv->mms_trans->itemid == IEC61850_ITEM_ID_Q)){
hf_index = hf_mms_iec61850_quality_bitstring;
}
}
%(DEFAULT_BODY)s
if((parameter_tvb)&&(mms_priv->mms_trans)&&(mms_priv->mms_trans->itemid == IEC61850_ITEM_ID_Q)){
if(mms_priv){
if((parameter_tvb)&&(mms_priv->mms_trans)&&(mms_priv->mms_trans->itemid == IEC61850_ITEM_ID_Q)){
proto_tree *sub_tree;
sub_tree = proto_item_add_subtree(actx->created_item, ett_mms_iec61850_quality_bitstring);
proto_tree_add_bitmask_list(sub_tree, parameter_tvb, 0, 1, quality_field_bits_oct1, ENC_NA);
proto_tree_add_bitmask_list(sub_tree, parameter_tvb, 1, 1, quality_field_bits_oct2, ENC_NA);
}
}
}
#.FN_BODY ReportedOptFlds VAL_PTR= &parameter_tvb
tvbuff_t *parameter_tvb;
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
%(DEFAULT_BODY)s
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
mms_priv->reported_optflds = tvb_get_ntohs(parameter_tvb,0);
}
#.FN_BODY Data/unsigned
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
if(mms_priv->vmd_specific == IEC61850_8_1_RPT ){
if(mms_priv->listOfAccessResult_cnt == 3){
/* IEC 61850-8-1 SeqNum */
@ -492,34 +506,40 @@ if((parameter_tvb)&&(mms_priv->mms_trans)&&(mms_priv->mms_trans->itemid == IEC61
hf_index = hf_mms_iec61850_confrev;
}
}
}
%(DEFAULT_BODY)s
#.FN_BODY Data/boolean
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
if(mms_priv->vmd_specific == IEC61850_8_1_RPT ){
if(mms_priv->listOfAccessResult_cnt == 6){
/* IEC 61850-8-1 BufOvfl */
hf_index = hf_mms_iec61850_bufovfl;
}
}
}
%(DEFAULT_BODY)s
#.FN_BODY Data/binary-time
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
if(mms_priv->vmd_specific == IEC61850_8_1_RPT ){
if(mms_priv->listOfAccessResult_cnt == 4){
/* IEC 61850-8-1 TimeOfEntry */
hf_index = hf_mms_iec61850_timeofentry;
}
}
}
%(DEFAULT_BODY)s
#.FN_BODY Data/integer
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
if((mms_priv->mms_trans)&&(mms_priv->mms_trans->itemid == IEC61850_ITEM_ID_CTLMODEL)){
hf_index = hf_mms_iec61850_ctlModel;
}
}
%(DEFAULT_BODY)s

View File

@ -29,6 +29,8 @@
void proto_register_mms(void);
void proto_reg_handoff_mms(void);
static bool use_iec61850_mapping = TRUE;
/* Initialize the protocol and registered fields */
static int proto_mms;
@ -273,9 +275,13 @@ dissect_mms(tvbuff_t* tvb, packet_info* pinfo, proto_tree* parent_tree, void* da
while (tvb_reported_length_remaining(tvb, offset) > 0) {
old_offset = offset;
if (use_iec61850_mapping) {
asn1_ctx.private_data = (void*)wmem_new0(pinfo->pool, mms_actx_private_data_t);
}
offset = dissect_mms_MMSpdu(FALSE, tvb, offset, &asn1_ctx, tree, -1);
if (asn1_ctx.private_data) {
wmem_free(pinfo->pool, asn1_ctx.private_data);
}
if (offset == old_offset) {
proto_tree_add_expert(tree, pinfo, &ei_mms_zero_pdu, tvb, offset, -1);
break;
@ -436,6 +442,13 @@ void proto_register_mms(void) {
expert_mms = expert_register_protocol(proto_mms);
expert_register_field_array(expert_mms, ei, array_length(ei));
/* Setting to enable/disable the IEC-61850 mapping on MMS */
module_t* mms_module = prefs_register_protocol(proto_mms, proto_reg_handoff_mms);
prefs_register_bool_preference(mms_module, "use_iec61850_mapping",
"Dissect MMS as IEC-61850",
"Enables or disables dsissection as IEC-61850 on top of MMS",
&use_iec61850_mapping);
}

View File

@ -34,6 +34,8 @@
void proto_register_mms(void);
void proto_reg_handoff_mms(void);
static bool use_iec61850_mapping = TRUE;
/* Initialize the protocol and registered fields */
static int proto_mms;
@ -1197,12 +1199,14 @@ static int * const ReportedOptFlds_bits[] = {
static int
dissect_mms_ReportedOptFlds(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
tvbuff_t *parameter_tvb;
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
offset = dissect_ber_bitstring(implicit_tag, actx, tree, tvb, offset,
ReportedOptFlds_bits, 10, hf_index, ett_mms_ReportedOptFlds,
&parameter_tvb);
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
mms_priv->reported_optflds = tvb_get_ntohs(parameter_tvb,0);
}
return offset;
@ -1222,6 +1226,7 @@ dissect_mms_Unsigned32(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_,
if (hf_index == hf_mms_invokeID){
mms_actx_private_data_t* mms_priv = (mms_actx_private_data_t*)actx->private_data;
if(mms_priv){
mms_priv->invokeid=val;
private_data_add_preCinfo(actx, val);
conversation = find_or_create_conversation(actx->pinfo);
@ -1307,7 +1312,7 @@ dissect_mms_Unsigned32(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_,
proto_item_set_generated(it);
}
}
}
}
@ -1328,7 +1333,7 @@ dissect_mms_Identifier(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_,
if (hf_index == hf_mms_domainId) {
private_data_add_moreCinfo_id(actx,tvb);
}
if (hf_index == hf_mms_objectName_domain_specific_itemId) {
if ((mms_priv) && (hf_index == hf_mms_objectName_domain_specific_itemId)) {
private_data_add_moreCinfo_id(actx,tvb);
const char *itemid_str = tvb_get_string_enc(actx->pinfo->pool, tvb, 0, tvb_reported_length(tvb), ENC_ASCII|ENC_NA);
if(g_str_has_suffix(itemid_str,"$ctlModel")){
@ -1338,7 +1343,7 @@ dissect_mms_Identifier(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_,
}
}
if (hf_index == hf_mms_vmd_specific){
if ((mms_priv) && (hf_index == hf_mms_vmd_specific)){
const char *vmd_specific_str = tvb_get_string_enc(actx->pinfo->pool, tvb, 0, tvb_reported_length(tvb), ENC_ASCII|ENC_NA);
if (strcmp(vmd_specific_str, "RPT") == 0) {
mms_priv->vmd_specific = IEC61850_8_1_RPT;
@ -2190,12 +2195,14 @@ dissect_mms_SEQUENCE_OF_Data(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offse
static int
dissect_mms_T_boolean(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
if(mms_priv->vmd_specific == IEC61850_8_1_RPT ){
if(mms_priv->listOfAccessResult_cnt == 6){
/* IEC 61850-8-1 BufOvfl */
hf_index = hf_mms_iec61850_bufovfl;
}
}
}
offset = dissect_ber_boolean(implicit_tag, actx, tree, tvb, offset, hf_index, NULL);
@ -2229,6 +2236,7 @@ static int* const quality_field_bits_oct2[] = {
};
tvbuff_t *parameter_tvb;
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
if(mms_priv->vmd_specific == IEC61850_8_1_RPT ){
if(mms_priv->listOfAccessResult_cnt == 2){
/* IEC 61850-8-1 Reported OptFlds */
@ -2241,18 +2249,21 @@ static int* const quality_field_bits_oct2[] = {
}else if((mms_priv->mms_trans)&&(mms_priv->mms_trans->itemid == IEC61850_ITEM_ID_Q)){
hf_index = hf_mms_iec61850_quality_bitstring;
}
}
offset = dissect_ber_bitstring(implicit_tag, actx, tree, tvb, offset,
NULL, 0, hf_index, -1,
&parameter_tvb);
if((parameter_tvb)&&(mms_priv->mms_trans)&&(mms_priv->mms_trans->itemid == IEC61850_ITEM_ID_Q)){
if(mms_priv){
if((parameter_tvb)&&(mms_priv->mms_trans)&&(mms_priv->mms_trans->itemid == IEC61850_ITEM_ID_Q)){
proto_tree *sub_tree;
sub_tree = proto_item_add_subtree(actx->created_item, ett_mms_iec61850_quality_bitstring);
proto_tree_add_bitmask_list(sub_tree, parameter_tvb, 0, 1, quality_field_bits_oct1, ENC_NA);
proto_tree_add_bitmask_list(sub_tree, parameter_tvb, 1, 1, quality_field_bits_oct2, ENC_NA);
}
}
}
return offset;
@ -2263,10 +2274,11 @@ if((parameter_tvb)&&(mms_priv->mms_trans)&&(mms_priv->mms_trans->itemid == IEC61
static int
dissect_mms_T_integer(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
if((mms_priv->mms_trans)&&(mms_priv->mms_trans->itemid == IEC61850_ITEM_ID_CTLMODEL)){
hf_index = hf_mms_iec61850_ctlModel;
}
}
offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
NULL);
@ -2281,6 +2293,7 @@ dissect_mms_T_integer(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_,
static int
dissect_mms_T_unsigned(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
if(mms_priv->vmd_specific == IEC61850_8_1_RPT ){
if(mms_priv->listOfAccessResult_cnt == 3){
/* IEC 61850-8-1 SeqNum */
@ -2290,6 +2303,7 @@ dissect_mms_T_unsigned(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_,
hf_index = hf_mms_iec61850_confrev;
}
}
}
offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
NULL);
@ -2317,6 +2331,7 @@ static int
dissect_mms_T_data_visible_string(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
if(mms_priv->vmd_specific == IEC61850_8_1_RPT ){
if(mms_priv->listOfAccessResult_cnt == 1){
/* IEC 61850-8-1 RptID */
@ -2325,7 +2340,7 @@ dissect_mms_T_data_visible_string(bool implicit_tag _U_, tvbuff_t *tvb _U_, int
/* IEC 61850-8-1 DatSet */
hf_index = hf_mms_iec61850_datset;
}
}
}
offset = dissect_ber_restricted_string(implicit_tag, BER_UNI_TAG_VisibleString,
actx, tree, tvb, offset, hf_index,
@ -2397,12 +2412,14 @@ dissect_mms_TimeOfDay(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_,
static int
dissect_mms_T_data_binary_time(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
if(mms_priv->vmd_specific == IEC61850_8_1_RPT ){
if(mms_priv->listOfAccessResult_cnt == 4){
/* IEC 61850-8-1 TimeOfEntry */
hf_index = hf_mms_iec61850_timeofentry;
}
}
}
offset = dissect_mms_TimeOfDay(implicit_tag, tvb, offset, actx, tree, hf_index);
@ -5302,7 +5319,7 @@ static const ber_choice_t AccessResult_choice[] = {
static int
dissect_mms_AccessResult(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
/* If listOfAccessResult_cnt > 2 we are into the optional data.
* if data is not present increase count.
*/
@ -5373,6 +5390,7 @@ dissect_mms_AccessResult(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U
break;
}
} while(!present);
}
offset = dissect_ber_choice(actx, tree, tvb, offset,
AccessResult_choice, hf_index, ett_mms_AccessResult,
@ -7142,7 +7160,9 @@ static int
dissect_mms_T_listOfAccessResult(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
mms_priv->listOfAccessResult_cnt = 0;
}
offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
T_listOfAccessResult_sequence_of, hf_index, ett_mms_T_listOfAccessResult);
@ -7864,7 +7884,9 @@ dissect_mms_MMSpdu(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn
get_ber_identifier(tvb, offset, &ber_class, &pc, &tag);
mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data;
if(mms_priv){
mms_priv->mms_pdu_type = tag;
}
offset = dissect_ber_choice(actx, tree, tvb, offset,
@ -7911,9 +7933,13 @@ dissect_mms(tvbuff_t* tvb, packet_info* pinfo, proto_tree* parent_tree, void* da
while (tvb_reported_length_remaining(tvb, offset) > 0) {
old_offset = offset;
if (use_iec61850_mapping) {
asn1_ctx.private_data = (void*)wmem_new0(pinfo->pool, mms_actx_private_data_t);
}
offset = dissect_mms_MMSpdu(FALSE, tvb, offset, &asn1_ctx, tree, -1);
if (asn1_ctx.private_data) {
wmem_free(pinfo->pool, asn1_ctx.private_data);
}
if (offset == old_offset) {
proto_tree_add_expert(tree, pinfo, &ei_mms_zero_pdu, tvb, offset, -1);
break;
@ -11065,6 +11091,13 @@ void proto_register_mms(void) {
expert_mms = expert_register_protocol(proto_mms);
expert_register_field_array(expert_mms, ei, array_length(ei));
/* Setting to enable/disable the IEC-61850 mapping on MMS */
module_t* mms_module = prefs_register_protocol(proto_mms, proto_reg_handoff_mms);
prefs_register_bool_preference(mms_module, "use_iec61850_mapping",
"Dissect MMS as IEC-61850",
"Enables or disables dsissection as IEC-61850 on top of MMS",
&use_iec61850_mapping);
}