# mms.cnf # mms conformation file #.MODULE_IMPORT ISO-8650-ACSE-1 acse #.IMPORT ../acse/acse-exp.cnf #.EXPORTS MMSpdu #.PDU #.NO_EMIT #.TYPE_RENAME ObjectName/domain-specific/itemId ObjectName_domain_specific_itemid #.TYPE_ATTR TimeOfDay TYPE = FT_STRING DISPLAY = BASE_NONE UtcTime TYPE = FT_STRING DISPLAY = BASE_NONE #.FIELD_RENAME ConfirmedServiceRequest/deleteEventCondition confirmedServiceRequest_deleteEventCondition ConfirmedServiceResponse/deleteEventCondition confirmedServiceResponse_deleteEventCondition ConfirmedServiceRequest/deleteEventAction confirmedServiceRequest_deleteEventAction ConfirmedServiceResponse/deleteEventAction confirmedServiceRequest_deleteEventAction ConfirmedServiceRequest/deleteEventEnrollment confirmedServiceRequest_deleteEventEnrollment ConfirmedServiceResponse/deleteEventEnrollment confirmedServiceResponse_deleteEventEnrollment TypeSpecification/bit-string typeSpecification_bit-string Data/bit-string data_bit-string TypeSpecification/octet-string typeSpecification_octet-string Data/octet-string data_octet-string TypeSpecification/visible-string typeSpecification_visible-string Data/visible-string data_visible-string TypeSpecification/binary-time typeSpecification_binary-time Data/binary-time data_binary-time GetNameList-Request/continueAfter getNameList-Request_continueAfter GetCapabilityList-Request/continueAfter getCapabilityList-Request_continueAfter GetEventEnrollmentAttributes-Request/continueAfter getEventEnrollmentAttributes-Request_continueAfter GetAlarmEnrollmentSummary-Request/continueAfter getAlarmEnrollmentSummary-Request_continueAfter FileDirectory-Request/continueAfter fileDirectory-Request_continueAfter GetDomainAttributes-Response/state getDomainAttributes-Response_state GetProgramInvocationAttributes-Response/state getProgramInvocationAttributes-Response_state ReportSemaphoreEntryStatus-Request/state reportSemaphoreEntryStatus-Request_state AlterEventEnrollment-Response/currentState/state alterEventEnrollment-Response_currentState_state ObjectName/domain-specific/itemId objectName-domain-specific-itemId #.FIELD_ATTR ConfirmedServiceRequest/deleteEventCondition ABBREV=confirmedServiceRequest.deleteEventCondition ConfirmedServiceResponse/deleteEventCondition ABBREV=confirmedServiceResponse.deleteEventCondition ConfirmedServiceRequest/deleteEventAction ABBREV=confirmedServiceRequest.deleteEventAction ConfirmedServiceResponse/deleteEventAction ABBREV=confirmedServiceRequest.deleteEventAction ConfirmedServiceRequest/deleteEventEnrollment ABBREV=confirmedServiceRequest.deleteEventEnrollment ConfirmedServiceResponse/deleteEventEnrollment ABBREV=confirmedServiceResponse.deleteEventEnrollment TypeSpecification/bit-string ABBREV=typeSpecification_bit-string Data/bit-string ABBREV=data_bit-string TypeSpecification/octet-string ABBREV=typeSpecification.octet-string Data/octet-string ABBREV=data.octet-string TypeSpecification/visible-string ABBREV=typeSpecification.visible-string Data/visible-string ABBREV=data.visible-string TypeSpecification/binary-time ABBREV=typeSpecification.binary-time Data/binary-time ABBREV=data.binary-time GetNameList-Request/continueAfter ABBREV=getNameList-Request_continueAfter GetCapabilityList-Request/continueAfter ABBREV=getCapabilityList-Request_continueAfter GetEventEnrollmentAttributes-Request/continueAfter ABBREV=getEventEnrollmentAttributes-Request_continueAfter GetAlarmEnrollmentSummary-Request/continueAfter ABBREV=getAlarmEnrollmentSummary-Request_continueAfter FileDirectory-Request/continueAfter ABBREV=fileDirectory-Request_continueAfter GetDomainAttributes-Response/state ABBREV=getDomainAttributes-Response_state GetProgramInvocationAttributes-Response/state ABBREV=getProgramInvocationAttributes-Response_state ReportSemaphoreEntryStatus-Request/state ABBREV=reportSemaphoreEntryStatus-Request_state AlterEventEnrollment-Response/currentState/state ABBREV=alterEventEnrollment-Response_currentState_state #.FN_BODY ApplicationReference/ap-title offset=dissect_acse_AP_title(false, tvb, offset, actx, tree, hf_mms_ap_title); #.FN_BODY ApplicationReference/ap-invocation-id offset=dissect_acse_AP_invocation_identifier(false, tvb, offset, actx, tree, hf_mms_ap_invocation_id); #.FN_BODY ApplicationReference/ae-qualifier offset=dissect_acse_AE_qualifier(false, tvb, offset, actx, tree, hf_mms_ae_qualifier); #.FN_BODY ApplicationReference/ae-invocation-id offset=dissect_acse_AE_invocation_identifier(false, tvb, offset, actx, tree, hf_mms_ae_invocation_id); #.FN_BODY MMSpdu VAL_PTR=&branch_taken int branch_taken; int8_t ber_class; bool pc; int32_t tag; 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 if( (branch_taken!=-1) && mms_MMSpdu_vals[branch_taken].strptr ){ if(mms_priv){ switch(mms_priv->mms_pdu_type){ case MMS_UNCONFIRMED_PDU: if(mms_priv->vmd_specific==IEC61850_8_1_RPT){ col_append_str(actx->pinfo->cinfo, COL_INFO, "Unconfirmed "); proto_item_append_text(mms_priv->pdu_item, " [RPT]"); }else if((mms_priv->mms_trans_p)&&(mms_priv->mms_trans_p->itemid==IEC61850_ITEM_ID_OPER)){ col_append_str(actx->pinfo->cinfo, COL_INFO, "Unconfirmed-CommandTermination"); proto_item_append_text(mms_priv->pdu_item, " [Unconfirmed-CommandTermination]"); } break; case MMS_INITIATE_REQUEST_PDU: col_append_str(actx->pinfo->cinfo, COL_INFO, "Associate Request"); proto_item_append_text(mms_priv->pdu_item, " [Associate Request]"); break; case MMS_INITIATE_RESPONSE_PDU: col_append_str(actx->pinfo->cinfo, COL_INFO, "Associate Response"); proto_item_append_text(mms_priv->pdu_item, " [Associate Response]"); break; case MMS_CONFIRMED_REQUEST_PDU: if(mms_priv->mms_trans_p){ if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_GET_SERV_DIR){ col_append_str(actx->pinfo->cinfo, COL_INFO, "GetServerDirectoryRequest"); proto_item_append_text(mms_priv->pdu_item, " [GetServerDirectoryRequest]"); }else if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_GETLOGICALDEVICEDIRECTORY){ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "GetLogicalDeviceDirectoryRequest %%s", mms_priv->itemid_str); proto_item_append_text(mms_priv->pdu_item, " [GetLogicalDeviceDirectoryRequest ]"); }else if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_GETDATASETDIRECTORY){ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "GetDataSetDirectoryRequest %%s", mms_priv->itemid_str); proto_item_append_text(mms_priv->pdu_item, " [GetDataSetDirectoryRequest]"); }else if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_GETDATADIRECTORY){ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "GetDataDirectoryRequest%%s", private_data_get_moreCinfo(actx)); proto_item_append_text(mms_priv->pdu_item, " [GetDataDirectoryRequest]"); } else if (mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_READ){ if(mms_priv->mms_trans_p->itemid == IEC61850_ITEM_ID_$BR$_OR_$RP$){ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "GetRCBValuesRequest %%s", private_data_get_moreCinfo(actx)); proto_item_append_text(mms_priv->pdu_item, " [GetRCBValuesRequest]"); }else{ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "GetDataValueRequest %%s", private_data_get_moreCinfo(actx)); proto_item_append_text(mms_priv->pdu_item, " [GetDataValueRequest]"); } } else if (mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_WRITE){ if(mms_priv->mms_trans_p->itemid == IEC61850_ITEM_ID_$BR$_OR_$RP$){ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "SetRCBValuesRequest %%s", private_data_get_moreCinfo(actx)); proto_item_append_text(mms_priv->pdu_item, " [SetRCBValuesRequest]"); }else{ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "SetDataValueRequest %%s", private_data_get_moreCinfo(actx)); proto_item_append_text(mms_priv->pdu_item, " [SetDataValueRequest]"); } }else if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_SELECTWITHVALUE){ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "SelectWithValueRequest %%s", private_data_get_moreCinfo(actx)); proto_item_append_text(mms_priv->pdu_item, " [SelectWithValueRequest]"); } }else if (mms_has_private_data(actx)){ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "%%s%%s%%s", private_data_get_preCinfo(actx), mms_MMSpdu_vals[branch_taken].strptr, private_data_get_moreCinfo(actx)); } break; case MMS_CONFIRMED_RESPONSE_PDU: if(mms_priv->mms_trans_p){ if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_GET_SERV_DIR){ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "GetServerDirectoryResponse %%s", mms_priv->itemid_str); proto_item_append_text(mms_priv->pdu_item, " [GetServerDirectoryResponse ]"); }else if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_GETLOGICALDEVICEDIRECTORY){ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "GetLogicalDeviceDirectoryResponse%%s", private_data_get_moreCinfo(actx)); proto_item_append_text(mms_priv->pdu_item, " [GetLogicalDeviceDirectoryResponse ]"); }else if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_GETDATASETDIRECTORY){ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "GetDataSetDirectoryResponse%%s", private_data_get_moreCinfo(actx)); proto_item_append_text(mms_priv->pdu_item, " [GetDataSetDirectoryResponse ]"); }else if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_GETDATADIRECTORY){ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "GetDataDirectoryResponse%%s", private_data_get_moreCinfo(actx)); proto_item_append_text(mms_priv->pdu_item, " [GetDataDirectoryResponse ]"); }else if (mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_READ){ if(mms_priv->mms_trans_p->itemid == IEC61850_ITEM_ID_$BR$_OR_$RP$){ col_append_str(actx->pinfo->cinfo, COL_INFO, "GetRCBValuesResponse"); proto_item_append_text(mms_priv->pdu_item, " [GetRCBValuesResponse]"); }else{ col_append_str(actx->pinfo->cinfo, COL_INFO, "GetDataValueResponse"); proto_item_append_text(mms_priv->pdu_item, " [GetDataValueResponse ]"); } if(mms_priv->success == 1){ col_append_str(actx->pinfo->cinfo, COL_INFO, " success"); }else{ col_append_str(actx->pinfo->cinfo, COL_INFO, " failure"); } } else if (mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_WRITE){ if(mms_priv->mms_trans_p->itemid == IEC61850_ITEM_ID_$BR$_OR_$RP$){ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "SetRCBValuesResponse %%s", private_data_get_moreCinfo(actx)); proto_item_append_text(mms_priv->pdu_item, " [SetRCBValuesResponse]"); }else{ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "SetDataValueResponse %%s", private_data_get_moreCinfo(actx)); proto_item_append_text(mms_priv->pdu_item, " [SetDataValueResponse]"); } }else if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_SELECTWITHVALUE){ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "SelectWithValueResponse %%s", private_data_get_moreCinfo(actx)); proto_item_append_text(mms_priv->pdu_item, " [SelectWithValueResponse]"); } }else if(mms_has_private_data(actx)){ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "%%s%%s%%s", private_data_get_preCinfo(actx), mms_MMSpdu_vals[branch_taken].strptr, private_data_get_moreCinfo(actx)); } break; default: col_append_fstr(actx->pinfo->cinfo, COL_INFO, "%%s%%s%%s", private_data_get_preCinfo(actx), mms_MMSpdu_vals[branch_taken].strptr, private_data_get_moreCinfo(actx)); break; } }else if (mms_has_private_data(actx)){ col_append_fstr(actx->pinfo->cinfo, COL_INFO, "%%s%%s%%s", private_data_get_preCinfo(actx), mms_MMSpdu_vals[branch_taken].strptr, private_data_get_moreCinfo(actx)); }else{ col_append_str(actx->pinfo->cinfo, COL_INFO, mms_MMSpdu_vals[branch_taken].strptr); } } #.FN_BODY Initiate-RequestPDU %(DEFAULT_BODY)s mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data; if(tree){ mms_priv->pdu_item = (proto_item*)tree->last_child; } #.FN_BODY Initiate-ResponsePDU %(DEFAULT_BODY)s mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data; if(tree){ mms_priv->pdu_item = (proto_item*)tree->last_child; } #.FN_BODY Unconfirmed-PDU mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data; if (!mms_priv->mms_trans_p) { /* create a "fake" mms_trans structure */ mms_priv->mms_trans_p=wmem_new0(actx->pinfo->pool, mms_transaction_t); mms_priv->mms_trans_p->req_time = actx->pinfo->fd->abs_ts; } %(DEFAULT_BODY)s if(tree){ mms_priv->pdu_item = (proto_item*)tree->last_child; } #.FN_BODY Confirmed-RequestPDU %(DEFAULT_BODY)s mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data; if(tree){ mms_priv->pdu_item = (proto_item*)tree->last_child; } #.FN_BODY Confirmed-ResponsePDU %(DEFAULT_BODY)s mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data; if(tree){ mms_priv->pdu_item = (proto_item*)tree->last_child; } #.FN_BODY ConfirmedServiceRequest int8_t ber_class; bool pc; int32_t tag; 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->confirmedservice_type = tag; } %(DEFAULT_BODY)s if(mms_priv && mms_priv->mms_trans_p){ if(mms_priv->confirmedservice_type == MMS_CONFIRMEDSERVICE_GETNAMELIST){ if(mms_priv->objectclass == MMS_OBJECTCLASS_DOMAIN){ if(mms_priv->objectscope == MMS_OBJECTSCOPE_VMDSPECIFIC){ mms_priv->mms_trans_p->conf_serv_pdu_type_req = MMS_IEC_61850_CONF_SERV_PDU_GET_SERV_DIR; } }else if(mms_priv->objectclass == MMS_OBJECTCLASS_NAMMEDVARIABLE){ mms_priv->mms_trans_p->conf_serv_pdu_type_req = MMS_IEC_61850_CONF_SERV_PDU_GETLOGICALDEVICEDIRECTORY; }else if(mms_priv->objectclass == MMS_OBJECTCLASS_NAMEDVARIABLELIST){ mms_priv->mms_trans_p->conf_serv_pdu_type_req = MMS_IEC_61850_CONF_SERV_PDU_GETDATASETDIRECTORY; } }else if(mms_priv->confirmedservice_type == MMS_CONFIRMEDSERVICE_GETNAMEDVARIABLELISTATTRIBUTES){ mms_priv->mms_trans_p->conf_serv_pdu_type_req = MMS_IEC_61850_CONF_SERV_PDU_GETDATASETDIRECTORY; }else if(mms_priv->confirmedservice_type == MMS_CONFIRMEDSERVICE_READ){ mms_priv->mms_trans_p->conf_serv_pdu_type_req = MMS_IEC_61850_CONF_SERV_PDU_READ; }else if(mms_priv->confirmedservice_type == MMS_CONFIRMEDSERVICE_WRITE){ mms_priv->mms_trans_p->conf_serv_pdu_type_req = MMS_IEC_61850_CONF_SERV_PDU_WRITE; }else if(mms_priv->confirmedservice_type == MMS_CONFIRMEDSERVICE_GETVARIABLEACCESSATTRIBUTES){ mms_priv->mms_trans_p->conf_serv_pdu_type_req = MMS_IEC_61850_CONF_SERV_PDU_GETDATADIRECTORY; } } #.FN_BODY ConfirmedServiceResponse int8_t ber_class; bool pc; int32_t tag; 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->confirmedservice_type = tag; } %(DEFAULT_BODY)s #.FN_BODY ObjectClass VAL_PTR=&val uint32_t val; %(DEFAULT_BODY)s mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data; if(mms_priv){ mms_priv->objectclass = val; } #.FN_BODY ObjectScope VAL_PTR=&val int val; %(DEFAULT_BODY)s mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data; if(mms_priv){ mms_priv->objectscope = val; } #.FN_BODY TimeOfDay uint32_t len; uint32_t milliseconds; uint16_t days; char * ptime; nstime_t ts; len = tvb_reported_length_remaining(tvb, offset); if(len == 4) { milliseconds = tvb_get_ntohl(tvb, offset); ptime = signed_time_msecs_to_str(actx->pinfo->pool, milliseconds); if(hf_index > 0) { proto_tree_add_string(tree, hf_index, tvb, offset, len, ptime); } return offset; } if(len == 6) { milliseconds = tvb_get_ntohl(tvb, offset); days = tvb_get_ntohs(tvb, offset+4); /* 5113 days between 01-01-1970 and 01-01-1984 */ /* 86400 seconds in one day */ ts.secs = (days + 5113) * 86400 + milliseconds / 1000; ts.nsecs = (milliseconds %% 1000) * 1000000U; ptime = abs_time_to_str(actx->pinfo->pool, &ts, ABSOLUTE_TIME_UTC, true); if(hf_index > 0) { proto_tree_add_string(tree, hf_index, tvb, offset, len, ptime); } return offset; } proto_tree_add_expert_format(tree, actx->pinfo, &ei_mms_mal_timeofday_encoding, tvb, offset, len, "BER Error: malformed TimeOfDay encoding, length must be 4 or 6 bytes"); if(hf_index > 0) { proto_tree_add_string(tree, hf_index, tvb, offset, len, "????"); } #.FN_BODY UtcTime uint32_t len; uint32_t seconds; uint32_t fraction; uint32_t nanoseconds; nstime_t ts; char * ptime; static int * const TimeQuality_bits[] = { &hf_mms_iec61850_timequality80, &hf_mms_iec61850_timequality40, &hf_mms_iec61850_timequality20, &hf_mms_iec61850_timequality1F, NULL }; len = tvb_reported_length_remaining(tvb, offset); if(len != 8) { /* The octet format shall be (using ASN.1 bstring notation): * ‘ssssssssssssssssssssssssssssssssffffffffffffffffffffffffqqqqqqqq’B * q stands for TimeQuality, i.e. reserved to represent TimeQuality based upon the referencing standard. */ proto_tree_add_expert_format(tree, actx->pinfo, &ei_mms_mal_utctime_encoding, tvb, offset, len, "BER Error: malformed IEC61850 UTCTime encoding, length must be 8 bytes"); if(hf_index > 0) { proto_tree_add_string(tree, hf_index, tvb, offset, len, "????"); } return offset; } seconds = tvb_get_ntohl(tvb, offset); fraction = tvb_get_ntoh24(tvb, offset+4) * 0x100; /* Only 3 bytes are recommended */ nanoseconds = (uint32_t )( ((uint64_t)fraction * UINT64_C(1000000000)) / UINT64_C(0x100000000) ) ; ts.secs = seconds; ts.nsecs = nanoseconds; ptime = abs_time_to_str(actx->pinfo->pool, &ts, ABSOLUTE_TIME_UTC, true); if(hf_index > 0) { mms_actx_private_data_t* mms_priv = (mms_actx_private_data_t*)actx->private_data; if((mms_priv)&& (mms_priv->mms_trans_p)){ if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_SELECTWITHVALUE){ if(mms_priv->data_cnt == 8){ hf_index = hf_mms_iec61850_T; } } } proto_tree_add_string(tree, hf_index, tvb, offset, len, ptime); proto_tree_add_bitmask_list(tree, tvb, offset+7, 1, TimeQuality_bits, ENC_BIG_ENDIAN); } #.FN_BODY Unsigned32 VAL_PTR=&val uint32_t val; conversation_t *conversation; mms_conv_info_t *mms_info; mms_transaction_t *mms_trans; %(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); mms_info = (mms_conv_info_t *)conversation_get_proto_data(conversation, proto_mms); if (!mms_info) { /* * No. Attach that information to the conversation, and add * it to the list of information structures. */ mms_info = wmem_new(wmem_file_scope(), mms_conv_info_t); mms_info->pdus=wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal); conversation_add_proto_data(conversation, proto_mms, mms_info); } /* Request or response? */ bool is_request; switch(mms_priv->mms_pdu_type){ case 0: /* Confirmed-RequestPDU */ is_request = true; break; case 1: /* confirmed-ResponsePDU */ is_request = false; break; case 2: /* Confirmed-ErrorPDU */ is_request = false; break; default: is_request = false; break; } if (!PINFO_FD_VISITED(actx->pinfo)) { if (is_request==true) { /* This is a request */ mms_trans=wmem_new0(wmem_file_scope(), mms_transaction_t); mms_trans->req_frame = actx->pinfo->num; mms_trans->req_time = actx->pinfo->fd->abs_ts; wmem_map_insert(mms_info->pdus, GUINT_TO_POINTER(mms_priv->invokeid), (void *)mms_trans); } else { mms_trans=(mms_transaction_t *)wmem_map_lookup(mms_info->pdus, GUINT_TO_POINTER(mms_priv->invokeid)); if (mms_trans) { mms_trans->rep_frame = actx->pinfo->num; } } } else { mms_trans=(mms_transaction_t *)wmem_map_lookup(mms_info->pdus, GUINT_TO_POINTER(mms_priv->invokeid)); } if (!mms_trans) { /* create a "fake" mms_trans structure */ mms_trans=wmem_new0(actx->pinfo->pool, mms_transaction_t); mms_trans->req_frame = 0; mms_trans->rep_frame = 0; mms_trans->req_time = actx->pinfo->fd->abs_ts; } mms_priv->mms_trans_p = mms_trans; /* print state tracking in the tree */ if (is_request) { /* This is a request */ if (mms_trans->rep_frame) { proto_item *it; it = proto_tree_add_uint(actx->subtree.top_tree, hf_mms_response_in, tvb, 0, 0, mms_trans->rep_frame); proto_item_set_generated(it); } } else { /* This is a reply */ if (mms_trans->req_frame) { proto_item *it; nstime_t ns; it = proto_tree_add_uint(actx->subtree.top_tree, hf_mms_response_to, tvb, 0, 0, mms_trans->req_frame); proto_item_set_generated(it); nstime_delta(&ns, &actx->pinfo->fd->abs_ts, &mms_trans->req_time); it = proto_tree_add_time(actx->subtree.top_tree, hf_mms_response_time, tvb, 0, 0, &ns); proto_item_set_generated(it); } } } } #.FN_BODY FloatingPoint %(DEFAULT_BODY)s private_data_add_moreCinfo_float(actx, tvb); #.FN_BODY Identifier VAL_PTR= ¶meter_tvb tvbuff_t *parameter_tvb = NULL; mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data; %(DEFAULT_BODY)s if (parameter_tvb) { if (hf_index == hf_mms_domainId) { private_data_add_moreCinfo_id(actx,parameter_tvb); } if ((mms_priv) && ((hf_index == hf_mms_objectName_domain_specific_itemId)|| (hf_index ==hf_mms_listOfIdentifier_item))) { private_data_add_moreCinfo_id(actx,parameter_tvb); if((mms_priv->mms_trans_p)&&(parameter_tvb)){ mms_priv->itemid_str = tvb_get_string_enc(actx->pinfo->pool, parameter_tvb, 0, tvb_reported_length(parameter_tvb), ENC_ASCII|ENC_NA); if(g_str_has_suffix(mms_priv->itemid_str,"$ctlModel")){ mms_priv->mms_trans_p->itemid = IEC61850_ITEM_ID_CTLMODEL; }else if(g_str_has_suffix(mms_priv->itemid_str,"$q")){ mms_priv->mms_trans_p->itemid = IEC61850_ITEM_ID_Q; }else if(g_str_has_suffix(mms_priv->itemid_str,"$Oper")){ mms_priv->mms_trans_p->itemid = IEC61850_ITEM_ID_OPER; }else if((g_str_has_suffix(mms_priv->itemid_str,"$Oper$Check")) || (g_str_has_suffix(mms_priv->itemid_str,"$SBOw$Check"))){ mms_priv->mms_trans_p->itemid = IEC61850_ITEM_ID_CHECK; }else if(g_str_has_suffix(mms_priv->itemid_str,"$orCat")){ mms_priv->mms_trans_p->itemid = IEC61850_ITEM_ID_OR_CAT; }else if(g_str_has_suffix(mms_priv->itemid_str,"Beh$stVal")){ mms_priv->mms_trans_p->itemid = IEC61850_ITEM_ID_BEH$STVAL; }else if(g_str_has_suffix(mms_priv->itemid_str,"Mod$stVal")){ mms_priv->mms_trans_p->itemid = IEC61850_ITEM_ID_MOD$STVAL; }else if(g_str_has_suffix(mms_priv->itemid_str,"Health$stVal")){ mms_priv->mms_trans_p->itemid = IEC61850_ITEM_ID_HEALTH$STVAL; }else if((g_strrstr(mms_priv->itemid_str,"$BR$") || g_strrstr(mms_priv->itemid_str,"$RP$"))){ //GetBRCBValues,GetURCBValues,) mms_priv->mms_trans_p->itemid = IEC61850_ITEM_ID_$BR$_OR_$RP$; }else if(g_str_has_suffix(mms_priv->itemid_str,"$SBOw")){ mms_priv->mms_trans_p->itemid = IEC61850_ITEM_ID_$SBOW; mms_priv->mms_trans_p->conf_serv_pdu_type_req = MMS_IEC_61850_CONF_SERV_PDU_SELECTWITHVALUE; } } } if ((mms_priv) && (hf_index == hf_mms_vmd_specific)){ const char *vmd_specific_str = tvb_get_string_enc(actx->pinfo->pool, parameter_tvb, 0, tvb_reported_length(parameter_tvb), ENC_ASCII|ENC_NA); if (strcmp(vmd_specific_str, "RPT") == 0) { mms_priv->vmd_specific = IEC61850_8_1_RPT; } } } #.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 VAL_PTR=&branch_taken int branch_taken; 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. */ bool present; do { mms_priv->listOfAccessResult_cnt+=1; present = true; switch(mms_priv->listOfAccessResult_cnt){ case 1: /*RptID*/ break; case 2: /* Reported OptFlds */ break; case 3: /* SeqNum Shall be present if OptFlds.sequence-number is true */ if((mms_priv->reported_optflds & 0x4000) != 0x4000){ present = false; } break; case 4: /*TimeOfEntry Shall be present if OptFlds.report-time-stamp is true */ if((mms_priv->reported_optflds & 0x2000) != 0x2000){ present = false; } break; case 5: /*DatSet Shall be present if OptFlds.data-set-name is true */ if((mms_priv->reported_optflds & 0x0800) !=0x0800){ present = false; } break; case 6: /*BufOvfl Shall be present if OptFlds.buffer-overflow is true */ if((mms_priv->reported_optflds & 0x0200) !=0x0200){ present = false; } break; case 7: /*EntryID Shall be present if OptFlds.entryID is true */ if((mms_priv->reported_optflds & 0x0100) !=0x0100){ present = false; } break; case 8: /*ConfRev Shall be present if OptFlds.conf-rev is true */ if((mms_priv->reported_optflds & 0x0080) !=0x0080){ present = false; } break; case 9: /*SubSeqNum Shall be present if OptFlds.segmentation is true */ if((mms_priv->reported_optflds & 0x0040) !=0x0040){ present = false; } break; case 10: /*MoreSegmentsFollow Shall be present if OptFlds.segmentation is true */ if((mms_priv->reported_optflds & 0x0040) !=0x0040){ present = false; } break; case 11: /*Inclusion-bitstring Shall be present */ break; case 12: /*data-reference(s) Shall be present if OptFlds.data-reference is true */ if((mms_priv->reported_optflds & 0x0400) !=0x0400){ present = false; } break; case 13: /*value(s) See AccessResult for value(s) */ break; case 14: /*ReasonCode(s) Shall be present if OptFlds OptFlds.reason-for-inclusion is true */ if((mms_priv->reported_optflds & 0x1000) !=0x1000){ present = false; } break; default: break; } } while(!present); } %(DEFAULT_BODY)s if(mms_priv){ mms_priv->success = branch_taken; } #.FN_BODY Write-Request/listOfData mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data; if(mms_priv){ mms_priv->data_cnt = 0; } %(DEFAULT_BODY)s if(mms_priv){ mms_priv->data_cnt = 0; } #.FN_BODY Data mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data; if(mms_priv){ mms_priv->data_cnt += 1; } %(DEFAULT_BODY)s #.FN_BODY Data/structure mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data; if((mms_priv)&& (mms_priv->mms_trans_p)){ if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_SELECTWITHVALUE){ if(mms_priv->data_cnt == 3){ /* IEC 61850-8-1 origin, if we hgave a struct here Tm was not there */ hf_index = hf_mms_iec61850_origin; mms_priv->data_cnt++; }else if(mms_priv->data_cnt == 4){ /* IEC 61850-8-1 origin, if we hgave a struct here Tm was not there */ hf_index = hf_mms_iec61850_origin; } } } %(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 */ hf_index = hf_mms_iec61850_rptid; }else if(mms_priv->listOfAccessResult_cnt == 5){ /* IEC 61850-8-1 DatSet */ hf_index = hf_mms_iec61850_datset; } } } %(DEFAULT_BODY)s #.FN_BODY Data/octet-string mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data; if((mms_priv)&& (mms_priv->mms_trans_p)){ if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_SELECTWITHVALUE){ if(mms_priv->data_cnt == 6){ hf_index = hf_mms_iec61850_origin_orident; } } } %(DEFAULT_BODY)s #.FN_BODY Data/bit-string VAL_PTR= ¶meter_tvb static int* const quality_field_bits_oct1[] = { &hf_mms_iec61850_QualityC0, &hf_mms_iec61850_Quality20, &hf_mms_iec61850_Quality10, &hf_mms_iec61850_Quality8, &hf_mms_iec61850_Quality4, &hf_mms_iec61850_Quality2, &hf_mms_iec61850_Quality1, NULL }; static int* const quality_field_bits_oct2[] = { &hf_mms_iec61850_Quality0080, &hf_mms_iec61850_Quality0040, &hf_mms_iec61850_Quality0020, &hf_mms_iec61850_Quality0010, &hf_mms_iec61850_Quality0008, NULL }; static int * const mms_iec61850_chec_bits[] = { &hf_mms_iec61850_check_b1, &hf_mms_iec61850_check_b0, NULL }; tvbuff_t *parameter_tvb = NULL; proto_tree *sub_tree; mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data; if((mms_priv)&&(mms_priv->mms_trans_p)){ if(mms_priv->vmd_specific == IEC61850_8_1_RPT ){ if(mms_priv->listOfAccessResult_cnt == 2){ /* IEC 61850-8-1 Reported OptFlds */ return dissect_mms_ReportedOptFlds(implicit_tag, tvb, offset, actx, tree, hf_mms_iec61850_reported_optflds); }else{ if(mms_priv->listOfAccessResult_cnt == 11){ hf_index = hf_mms_iec61850_inclusion_bitstring; } } }else if (mms_priv->mms_trans_p->itemid == IEC61850_ITEM_ID_Q){ hf_index = hf_mms_iec61850_quality_bitstring; }else if (mms_priv->mms_trans_p->itemid == IEC61850_ITEM_ID_CHECK){ hf_index = hf_mms_iec61850_check_bitstring; }else if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_SELECTWITHVALUE){ if(mms_priv->data_cnt == 10){ hf_index = hf_mms_iec61850_check_bitstring; } } } %(DEFAULT_BODY)s if((mms_priv)&&(parameter_tvb) && (mms_priv->mms_trans_p)){ if(mms_priv->mms_trans_p->itemid == IEC61850_ITEM_ID_Q){ 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); }else if (mms_priv->mms_trans_p->itemid == IEC61850_ITEM_ID_CHECK){ sub_tree = proto_item_add_subtree(actx->created_item, ett_mms_iec61850_check_bitstring); proto_tree_add_bitmask_list(sub_tree, parameter_tvb, 0, 1, mms_iec61850_chec_bits, ENC_NA); }else if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_SELECTWITHVALUE){ if(mms_priv->data_cnt == 10){ sub_tree = proto_item_add_subtree(actx->created_item, ett_mms_iec61850_check_bitstring); proto_tree_add_bitmask_list(sub_tree, parameter_tvb, 0, 1, mms_iec61850_chec_bits, ENC_NA); } } } #.FN_BODY ReportedOptFlds VAL_PTR= ¶meter_tvb tvbuff_t *parameter_tvb = NULL; %(DEFAULT_BODY)s mms_actx_private_data_t *mms_priv = (mms_actx_private_data_t *)actx->private_data; if(mms_priv && parameter_tvb){ 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) && (mms_priv->mms_trans_p)){ if(mms_priv->vmd_specific == IEC61850_8_1_RPT ){ if(mms_priv->listOfAccessResult_cnt == 3){ /* IEC 61850-8-1 SeqNum */ hf_index = hf_mms_iec61850_seqnum; }else if(mms_priv->listOfAccessResult_cnt == 8){ /* IEC 61850-8-1 ConfRev */ hf_index = hf_mms_iec61850_confrev; } } if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_SELECTWITHVALUE){ if(mms_priv->data_cnt == 7){ hf_index = hf_mms_iec61850_ctlNum; } } } %(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) && (mms_priv->mms_trans_p)){ 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; } }else if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_SELECTWITHVALUE){ if(mms_priv->data_cnt == 2){ /* IEC 61850-8-1 ctlVal */ hf_index = hf_mms_iec61850_ctlval; }else if(mms_priv->data_cnt == 9){ /* IEC 61850-8-1 Test */ hf_index = hf_mms_iec61850_test; } } } %(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) && (mms_priv->mms_trans_p)){ if(mms_priv->mms_trans_p->itemid == IEC61850_ITEM_ID_CTLMODEL){ hf_index = hf_mms_iec61850_ctlModel; }else if(mms_priv->mms_trans_p->itemid == IEC61850_ITEM_ID_OR_CAT){ hf_index = hf_mms_iec61850_orcategory; }else if(mms_priv->mms_trans_p->itemid == IEC61850_ITEM_ID_BEH$STVAL){ hf_index = hf_mms_iec61850_beh$stval; }else if(mms_priv->mms_trans_p->itemid == IEC61850_ITEM_ID_MOD$STVAL){ hf_index = hf_mms_iec61850_beh$stval; }else if(mms_priv->mms_trans_p->itemid == IEC61850_ITEM_ID_HEALTH$STVAL){ hf_index = hf_mms_iec61850_health$stval; }else if(mms_priv->mms_trans_p->conf_serv_pdu_type_req == MMS_IEC_61850_CONF_SERV_PDU_SELECTWITHVALUE){ if(mms_priv->data_cnt == 5){ /* IEC 61850-8-1 Origin Catagory */ hf_index = hf_mms_iec61850_origin_orcat; } } } %(DEFAULT_BODY)s