diff options
Diffstat (limited to 'epan/dissectors/asn1/mms')
-rw-r--r-- | epan/dissectors/asn1/mms/mms.asn | 483 | ||||
-rw-r--r-- | epan/dissectors/asn1/mms/mms.cnf | 888 | ||||
-rw-r--r-- | epan/dissectors/asn1/mms/packet-mms-template.c | 775 |
3 files changed, 1676 insertions, 470 deletions
diff --git a/epan/dissectors/asn1/mms/mms.asn b/epan/dissectors/asn1/mms/mms.asn index 3f72c10f..dd52432c 100644 --- a/epan/dissectors/asn1/mms/mms.asn +++ b/epan/dissectors/asn1/mms/mms.asn @@ -25,30 +25,47 @@ IMPORTS FROM ISO-8650-ACSE-1; +-- WS additions for IEC 61850 + +ReportedOptFlds ::= BIT STRING { + reserved(0), + sequence-number(1), + report-time-stamp(2), + reason-for-inclusion(3), + data-set-name(4), + data-reference(5), + buffer-overflow(6), + entryID(7), + conf-revision(8), + segmentation(9) + } + +-- End WS additions for IEC 61850 + MMSpdu ::= CHOICE { - confirmed-RequestPDU [0] IMPLICIT Confirmed-RequestPDU, - confirmed-ResponsePDU [1] IMPLICIT Confirmed-ResponsePDU, + confirmed-RequestPDU [0] IMPLICIT Confirmed-RequestPDU, + confirmed-ResponsePDU [1] IMPLICIT Confirmed-ResponsePDU, confirmed-ErrorPDU [2] IMPLICIT Confirmed-ErrorPDU, unconfirmed-PDU [3] IMPLICIT Unconfirmed-PDU, - rejectPDU [4] IMPLICIT RejectPDU, + rejectPDU [4] IMPLICIT RejectPDU, cancel-RequestPDU [5] IMPLICIT Cancel-RequestPDU, cancel-ResponsePDU [6] IMPLICIT Cancel-ResponsePDU, cancel-ErrorPDU [7] IMPLICIT Cancel-ErrorPDU, initiate-RequestPDU [8] IMPLICIT Initiate-RequestPDU, - initiate-ResponsePDU [9] IMPLICIT Initiate-ResponsePDU, + initiate-ResponsePDU [9] IMPLICIT Initiate-ResponsePDU, initiate-ErrorPDU [10] IMPLICIT Initiate-ErrorPDU, conclude-RequestPDU [11] IMPLICIT Conclude-RequestPDU, - conclude-ResponsePDU [12] IMPLICIT Conclude-ResponsePDU, + conclude-ResponsePDU [12] IMPLICIT Conclude-ResponsePDU, conclude-ErrorPDU [13] IMPLICIT Conclude-ErrorPDU } Confirmed-RequestPDU ::= SEQUENCE { - invokeID Unsigned32, + invokeID Unsigned32, listOfModifier SEQUENCE OF Modifier OPTIONAL, - confirmedServiceRequest ConfirmedServiceRequest, + confirmedServiceRequest ConfirmedServiceRequest, cs-request-detail [79] CS-Request-Detail OPTIONAL } @@ -71,8 +88,8 @@ Confirmed-ResponsePDU ::= SEQUENCE Confirmed-ErrorPDU ::= SEQUENCE { invokeID [0] IMPLICIT Unsigned32, - modifierPosition [1] IMPLICIT Unsigned32 OPTIONAL, - serviceError [2] IMPLICIT ServiceError + modifierPosition [1] IMPLICIT Unsigned32 OPTIONAL, + serviceError [2] IMPLICIT ServiceError } @@ -88,93 +105,93 @@ UnconfirmedService ::= CHOICE Modifier ::= CHOICE { - attach-To-Event-Condition [0] IMPLICIT AttachToEventCondition, + attach-To-Event-Condition [0] IMPLICIT AttachToEventCondition, attach-To-Semaphore [1] IMPLICIT AttachToSemaphore } ConfirmedServiceRequest ::= CHOICE { - status [0] IMPLICIT Status-Request, - getNameList [1] IMPLICIT GetNameList-Request, - identify [2] IMPLICIT Identify-Request, - rename [3] IMPLICIT Rename-Request, - read [4] IMPLICIT Read-Request, - write [5] IMPLICIT Write-Request, - getVariableAccessAttributes [6] GetVariableAccessAttributes-Request, - defineNamedVariable [7] IMPLICIT DefineNamedVariable-Request, - defineScatteredAccess [8] IMPLICIT DefineScatteredAccess-Request, - getScatteredAccessAttributes [9] IMPLICIT GetScatteredAccessAttributes-Request, - deleteVariableAccess [10] IMPLICIT DeleteVariableAccess-Request, + status [0] IMPLICIT Status-Request, + getNameList [1] IMPLICIT GetNameList-Request, + identify [2] IMPLICIT Identify-Request, + rename [3] IMPLICIT Rename-Request, + read [4] IMPLICIT Read-Request, + write [5] IMPLICIT Write-Request, + getVariableAccessAttributes [6] GetVariableAccessAttributes-Request, + defineNamedVariable [7] IMPLICIT DefineNamedVariable-Request, + defineScatteredAccess [8] IMPLICIT DefineScatteredAccess-Request, + getScatteredAccessAttributes [9] IMPLICIT GetScatteredAccessAttributes-Request, + deleteVariableAccess [10] IMPLICIT DeleteVariableAccess-Request, defineNamedVariableList [11] IMPLICIT DefineNamedVariableList-Request, - getNamedVariableListAttributes [12] IMPLICIT GetNamedVariableListAttributes-Request, + getNamedVariableListAttributes [12] IMPLICIT GetNamedVariableListAttributes-Request, deleteNamedVariableList [13] IMPLICIT DeleteNamedVariableList-Request, - defineNamedType [14] IMPLICIT DefineNamedType-Request, + defineNamedType [14] IMPLICIT DefineNamedType-Request, getNamedTypeAttributes [15] IMPLICIT GetNamedTypeAttributes-Request, - deleteNamedType [16] IMPLICIT DeleteNamedType-Request, - input [17] IMPLICIT Input-Request, - output [18] IMPLICIT Output-Request, - takeControl [19] IMPLICIT TakeControl-Request, - relinquishControl [20] IMPLICIT RelinquishControl-Request, - defineSemaphore [21] IMPLICIT DefineSemaphore-Request, - deleteSemaphore [22] IMPLICIT DeleteSemaphore-Request, + deleteNamedType [16] IMPLICIT DeleteNamedType-Request, + input [17] IMPLICIT Input-Request, + output [18] IMPLICIT Output-Request, + takeControl [19] IMPLICIT TakeControl-Request, + relinquishControl [20] IMPLICIT RelinquishControl-Request, + defineSemaphore [21] IMPLICIT DefineSemaphore-Request, + deleteSemaphore [22] IMPLICIT DeleteSemaphore-Request, reportSemaphoreStatus [23] IMPLICIT ReportSemaphoreStatus-Request, reportPoolSemaphoreStatus [24] IMPLICIT ReportPoolSemaphoreStatus-Request, reportSemaphoreEntryStatus [25] IMPLICIT ReportSemaphoreEntryStatus-Request, initiateDownloadSequence [26] IMPLICIT InitiateDownloadSequence-Request, - downloadSegment [27] IMPLICIT DownloadSegment-Request, + downloadSegment [27] IMPLICIT DownloadSegment-Request, terminateDownloadSequence [28] IMPLICIT TerminateDownloadSequence-Request, initiateUploadSequence [29] IMPLICIT InitiateUploadSequence-Request, - uploadSegment [30] IMPLICIT UploadSegment-Request, + uploadSegment [30] IMPLICIT UploadSegment-Request, terminateUploadSequence [31] IMPLICIT TerminateUploadSequence-Request, requestDomainDownload [32] IMPLICIT RequestDomainDownload-Request, - requestDomainUpload [33] IMPLICIT RequestDomainUpload-Request, - loadDomainContent [34] IMPLICIT LoadDomainContent-Request, - storeDomainContent [35] IMPLICIT StoreDomainContent-Request, - deleteDomain [36] IMPLICIT DeleteDomain-Request, - getDomainAttributes [37] IMPLICIT GetDomainAttributes-Request, + requestDomainUpload [33] IMPLICIT RequestDomainUpload-Request, + loadDomainContent [34] IMPLICIT LoadDomainContent-Request, + storeDomainContent [35] IMPLICIT StoreDomainContent-Request, + deleteDomain [36] IMPLICIT DeleteDomain-Request, + getDomainAttributes [37] IMPLICIT GetDomainAttributes-Request, createProgramInvocation [38] IMPLICIT CreateProgramInvocation-Request, deleteProgramInvocation [39] IMPLICIT DeleteProgramInvocation-Request, - start [40] IMPLICIT Start-Request, - stop [41] IMPLICIT Stop-Request, - resume [42] IMPLICIT Resume-Request, - reset [43] IMPLICIT Reset-Request, - kill [44] IMPLICIT Kill-Request, - getProgramInvocationAttributes [45] IMPLICIT GetProgramInvocationAttributes-Request, - obtainFile [46] IMPLICIT ObtainFile-Request, + start [40] IMPLICIT Start-Request, + stop [41] IMPLICIT Stop-Request, + resume [42] IMPLICIT Resume-Request, + reset [43] IMPLICIT Reset-Request, + kill [44] IMPLICIT Kill-Request, + getProgramInvocationAttributes [45] IMPLICIT GetProgramInvocationAttributes-Request, + obtainFile [46] IMPLICIT ObtainFile-Request, defineEventCondition [47] IMPLICIT DefineEventCondition-Request, deleteEventCondition [48] DeleteEventCondition-Request, getEventConditionAttributes [49] GetEventConditionAttributes-Request, reportEventConditionStatus [50] ReportEventConditionStatus-Request, - alterEventConditionMonitoring [51] IMPLICIT AlterEventConditionMonitoring-Request, - triggerEvent [52] IMPLICIT TriggerEvent-Request, - defineEventAction [53] IMPLICIT DefineEventAction-Request, - deleteEventAction [54] DeleteEventAction-Request, + alterEventConditionMonitoring [51] IMPLICIT AlterEventConditionMonitoring-Request, + triggerEvent [52] IMPLICIT TriggerEvent-Request, + defineEventAction [53] IMPLICIT DefineEventAction-Request, + deleteEventAction [54] DeleteEventAction-Request, getEventActionAttributes [55] GetEventActionAttributes-Request, reportEventActionStatus [56] ReportEventActionStatus-Request, defineEventEnrollment [57] IMPLICIT DefineEventEnrollment-Request, deleteEventEnrollment [58] DeleteEventEnrollment-Request, alterEventEnrollment [59] IMPLICIT AlterEventEnrollment-Request, reportEventEnrollmentStatus [60] ReportEventEnrollmentStatus-Request, - getEventEnrollmentAttributes [61] IMPLICIT GetEventEnrollmentAttributes-Request, - acknowledgeEventNotification [62] IMPLICIT AcknowledgeEventNotification-Request, - getAlarmSummary [63] IMPLICIT GetAlarmSummary-Request, + getEventEnrollmentAttributes [61] IMPLICIT GetEventEnrollmentAttributes-Request, + acknowledgeEventNotification [62] IMPLICIT AcknowledgeEventNotification-Request, + getAlarmSummary [63] IMPLICIT GetAlarmSummary-Request, getAlarmEnrollmentSummary [64] IMPLICIT GetAlarmEnrollmentSummary-Request, - readJournal [65] IMPLICIT ReadJournal-Request, - writeJournal [66] IMPLICIT WriteJournal-Request, - initializeJournal [67] IMPLICIT InitializeJournal-Request, - reportJournalStatus [68] IMPLICIT ReportJournalStatus-Request, - createJournal [69] IMPLICIT CreateJournal-Request, - deleteJournal [70] IMPLICIT DeleteJournal-Request, - getCapabilityList [71] IMPLICIT GetCapabilityList-Request, - fileOpen [72] IMPLICIT FileOpen-Request, - fileRead [73] IMPLICIT FileRead-Request, - fileClose [74] IMPLICIT FileClose-Request, - fileRename [75] IMPLICIT FileRename-Request, - fileDelete [76] IMPLICIT FileDelete-Request, - fileDirectory [77] IMPLICIT FileDirectory-Request + readJournal [65] IMPLICIT ReadJournal-Request, + writeJournal [66] IMPLICIT WriteJournal-Request, + initializeJournal [67] IMPLICIT InitializeJournal-Request, + reportJournalStatus [68] IMPLICIT ReportJournalStatus-Request, + createJournal [69] IMPLICIT CreateJournal-Request, + deleteJournal [70] IMPLICIT DeleteJournal-Request, + getCapabilityList [71] IMPLICIT GetCapabilityList-Request, + fileOpen [72] IMPLICIT FileOpen-Request, + fileRead [73] IMPLICIT FileRead-Request, + fileClose [74] IMPLICIT FileClose-Request, + fileRename [75] IMPLICIT FileRename-Request, + fileDelete [76] IMPLICIT FileDelete-Request, + fileDirectory [77] IMPLICIT FileDirectory-Request -- XXX this one is neither in this ASN nor in the IMPORTS --- additionalService [78] AdditionalService-Request +-- additionalService [78] AdditionalService-Request } CS-Request-Detail ::= CHOICE { @@ -186,86 +203,86 @@ CS-Request-Detail ::= CHOICE { ConfirmedServiceResponse ::= CHOICE { - status [0] IMPLICIT Status-Response, - getNameList [1] IMPLICIT GetNameList-Response, - identify [2] IMPLICIT Identify-Response, - rename [3] IMPLICIT Rename-Response, - read [4] IMPLICIT Read-Response, - write [5] IMPLICIT Write-Response, + status [0] IMPLICIT Status-Response, + getNameList [1] IMPLICIT GetNameList-Response, + identify [2] IMPLICIT Identify-Response, + rename [3] IMPLICIT Rename-Response, + read [4] IMPLICIT Read-Response, + write [5] IMPLICIT Write-Response, getVariableAccessAttributes [6] IMPLICIT GetVariableAccessAttributes-Response, - defineNamedVariable [7] IMPLICIT DefineNamedVariable-Response, + defineNamedVariable [7] IMPLICIT DefineNamedVariable-Response, defineScatteredAccess [8] IMPLICIT DefineScatteredAccess-Response, - getScatteredAccessAttributes [9] IMPLICIT GetScatteredAccessAttributes-Response, - deleteVariableAccess [10] IMPLICIT DeleteVariableAccess-Response, + getScatteredAccessAttributes [9] IMPLICIT GetScatteredAccessAttributes-Response, + deleteVariableAccess [10] IMPLICIT DeleteVariableAccess-Response, defineNamedVariableList [11] IMPLICIT DefineNamedVariableList-Response, - getNamedVariableListAttributes [12] IMPLICIT GetNamedVariableListAttributes-Response, + getNamedVariableListAttributes [12] IMPLICIT GetNamedVariableListAttributes-Response, deleteNamedVariableList [13] IMPLICIT DeleteNamedVariableList-Response, - defineNamedType [14] IMPLICIT DefineNamedType-Response, + defineNamedType [14] IMPLICIT DefineNamedType-Response, getNamedTypeAttributes [15] IMPLICIT GetNamedTypeAttributes-Response, - deleteNamedType [16] IMPLICIT DeleteNamedType-Response, - input [17] IMPLICIT Input-Response, - output [18] IMPLICIT Output-Response, - takeControl [19] TakeControl-Response, - relinquishControl [20] IMPLICIT RelinquishControl-Response, - defineSemaphore [21] IMPLICIT DefineSemaphore-Response, - deleteSemaphore [22] IMPLICIT DeleteSemaphore-Response, + deleteNamedType [16] IMPLICIT DeleteNamedType-Response, + input [17] IMPLICIT Input-Response, + output [18] IMPLICIT Output-Response, + takeControl [19] TakeControl-Response, + relinquishControl [20] IMPLICIT RelinquishControl-Response, + defineSemaphore [21] IMPLICIT DefineSemaphore-Response, + deleteSemaphore [22] IMPLICIT DeleteSemaphore-Response, reportSemaphoreStatus [23] IMPLICIT ReportSemaphoreStatus-Response, reportPoolSemaphoreStatus [24] IMPLICIT ReportPoolSemaphoreStatus-Response, reportSemaphoreEntryStatus [25] IMPLICIT ReportSemaphoreEntryStatus-Response, initiateDownloadSequence [26] IMPLICIT InitiateDownloadSequence-Response, - downloadSegment [27] IMPLICIT DownloadSegment-Response, + downloadSegment [27] IMPLICIT DownloadSegment-Response, terminateDownloadSequence [28] IMPLICIT TerminateDownloadSequence-Response, initiateUploadSequence [29] IMPLICIT InitiateUploadSequence-Response, - uploadSegment [30] IMPLICIT UploadSegment-Response, + uploadSegment [30] IMPLICIT UploadSegment-Response, terminateUploadSequence [31] IMPLICIT TerminateUploadSequence-Response, requestDomainDownLoad [32] IMPLICIT RequestDomainDownload-Response, - requestDomainUpload [33] IMPLICIT RequestDomainUpload-Response, - loadDomainContent [34] IMPLICIT LoadDomainContent-Response, - storeDomainContent [35] IMPLICIT StoreDomainContent-Response, - deleteDomain [36] IMPLICIT DeleteDomain-Response, - getDomainAttributes [37] IMPLICIT GetDomainAttributes-Response, + requestDomainUpload [33] IMPLICIT RequestDomainUpload-Response, + loadDomainContent [34] IMPLICIT LoadDomainContent-Response, + storeDomainContent [35] IMPLICIT StoreDomainContent-Response, + deleteDomain [36] IMPLICIT DeleteDomain-Response, + getDomainAttributes [37] IMPLICIT GetDomainAttributes-Response, createProgramInvocation [38] IMPLICIT CreateProgramInvocation-Response, deleteProgramInvocation [39] IMPLICIT DeleteProgramInvocation-Response, - start [40] IMPLICIT Start-Response, - stop [41] IMPLICIT Stop-Response, - resume [42] IMPLICIT Resume-Response, - reset [43] IMPLICIT Reset-Response, - kill [44] IMPLICIT Kill-Response, - getProgramInvocationAttributes [45] IMPLICIT GetProgramInvocationAttributes-Response, - obtainFile [46] IMPLICIT ObtainFile-Response, - fileOpen [72] IMPLICIT FileOpen-Response, + start [40] IMPLICIT Start-Response, + stop [41] IMPLICIT Stop-Response, + resume [42] IMPLICIT Resume-Response, + reset [43] IMPLICIT Reset-Response, + kill [44] IMPLICIT Kill-Response, + getProgramInvocationAttributes [45] IMPLICIT GetProgramInvocationAttributes-Response, + obtainFile [46] IMPLICIT ObtainFile-Response, + fileOpen [72] IMPLICIT FileOpen-Response, defineEventCondition [47] IMPLICIT DefineEventCondition-Response, deleteEventCondition [48] IMPLICIT DeleteEventCondition-Response, getEventConditionAttributes [49] IMPLICIT GetEventConditionAttributes-Response, reportEventConditionStatus [50] IMPLICIT ReportEventConditionStatus-Response, - alterEventConditionMonitoring [51] IMPLICIT AlterEventConditionMonitoring-Response, - triggerEvent [52] IMPLICIT TriggerEvent-Response, - defineEventAction [53] IMPLICIT DefineEventAction-Response, - deleteEventAction [54] IMPLICIT DeleteEventAction-Response, + alterEventConditionMonitoring [51] IMPLICIT AlterEventConditionMonitoring-Response, + triggerEvent [52] IMPLICIT TriggerEvent-Response, + defineEventAction [53] IMPLICIT DefineEventAction-Response, + deleteEventAction [54] IMPLICIT DeleteEventAction-Response, getEventActionAttributes [55] IMPLICIT GetEventActionAttributes-Response, - reportActionStatus [56] IMPLICIT ReportEventActionStatus-Response, + reportActionStatus [56] IMPLICIT ReportEventActionStatus-Response, defineEventEnrollment [57] IMPLICIT DefineEventEnrollment-Response, deleteEventEnrollment [58] IMPLICIT DeleteEventEnrollment-Response, alterEventEnrollment [59] IMPLICIT AlterEventEnrollment-Response, reportEventEnrollmentStatus [60] IMPLICIT ReportEventEnrollmentStatus-Response, - getEventEnrollmentAttributes [61] IMPLICIT GetEventEnrollmentAttributes-Response, - acknowledgeEventNotification [62] IMPLICIT AcknowledgeEventNotification-Response, - getAlarmSummary [63] IMPLICIT GetAlarmSummary-Response, + getEventEnrollmentAttributes [61] IMPLICIT GetEventEnrollmentAttributes-Response, + acknowledgeEventNotification [62] IMPLICIT AcknowledgeEventNotification-Response, + getAlarmSummary [63] IMPLICIT GetAlarmSummary-Response, getAlarmEnrollmentSummary [64] IMPLICIT GetAlarmEnrollmentSummary-Response, - readJournal [65] IMPLICIT ReadJournal-Response, - writeJournal [66] IMPLICIT WriteJournal-Response, - initializeJournal [67] IMPLICIT InitializeJournal-Response, - reportJournalStatus [68] IMPLICIT ReportJournalStatus-Response, - createJournal [69] IMPLICIT CreateJournal-Response, - deleteJournal [70] IMPLICIT DeleteJournal-Response, - getCapabilityList [71] IMPLICIT GetCapabilityList-Response, - fileRead [73] IMPLICIT FileRead-Response, - fileClose [74] IMPLICIT FileClose-Response, - fileRename [75] IMPLICIT FileRename-Response, - fileDelete [76] IMPLICIT FileDelete-Response, - fileDirectory [77] IMPLICIT FileDirectory-Response + readJournal [65] IMPLICIT ReadJournal-Response, + writeJournal [66] IMPLICIT WriteJournal-Response, + initializeJournal [67] IMPLICIT InitializeJournal-Response, + reportJournalStatus [68] IMPLICIT ReportJournalStatus-Response, + createJournal [69] IMPLICIT CreateJournal-Response, + deleteJournal [70] IMPLICIT DeleteJournal-Response, + getCapabilityList [71] IMPLICIT GetCapabilityList-Response, + fileRead [73] IMPLICIT FileRead-Response, + fileClose [74] IMPLICIT FileClose-Response, + fileRename [75] IMPLICIT FileRename-Response, + fileDelete [76] IMPLICIT FileDelete-Response, + fileDirectory [77] IMPLICIT FileDirectory-Response -- XXX this one is neither in this ASN nor in the IMPORTS --- additionalService [78] AdditionalService-Response +-- additionalService [78] AdditionalService-Response } --********************************** COMMON MMS TYPES *********************************** @@ -291,7 +308,7 @@ Unsigned32 ::= INTEGER ObjectName ::= CHOICE { vmd-specific [0] IMPLICIT Identifier, - domain-specific [1] IMPLICIT SEQUENCE + domain-specific [1] IMPLICIT SEQUENCE { domainId Identifier, itemId Identifier @@ -302,7 +319,7 @@ ObjectName ::= CHOICE ApplicationReference ::= SEQUENCE { - ap-title [0] AP-title OPTIONAL, + ap-title [0] AP-title OPTIONAL, ap-invocation-id [1] AP-invocation-identifier OPTIONAL, ae-qualifier [2] AE-qualifier OPTIONAL, ae-invocation-id [3] AE-invocation-identifier OPTIONAL @@ -323,11 +340,11 @@ Initiate-ErrorPDU ::= ServiceError Initiate-RequestPDU ::= SEQUENCE { - localDetailCalling [0] IMPLICIT Integer32 OPTIONAL, + localDetailCalling [0] IMPLICIT Integer32 OPTIONAL, proposedMaxServOutstandingCalling [1] IMPLICIT Integer16, proposedMaxServOutstandingCalled [2] IMPLICIT Integer16, proposedDataStructureNestingLevel [3] IMPLICIT Integer8 OPTIONAL, - mmsInitRequestDetail [4] IMPLICIT InitRequestDetail + mmsInitRequestDetail [4] IMPLICIT InitRequestDetail } InitRequestDetail ::= SEQUENCE @@ -339,7 +356,7 @@ InitRequestDetail ::= SEQUENCE Initiate-ResponsePDU ::= SEQUENCE { - localDetailCalled [0] IMPLICIT Integer32 OPTIONAL, + localDetailCalled [0] IMPLICIT Integer32 OPTIONAL, negociatedMaxServOutstandingCalling [1] IMPLICIT Integer16, negociatedMaxServOutstandingCalled [2] IMPLICIT Integer16, negociatedDataStructureNestingLevel [3] IMPLICIT Integer8 OPTIONAL, @@ -370,84 +387,84 @@ ParameterSupportOptions ::= BIT STRING { ServiceSupportOptions ::= BIT STRING { - status (0), + status (0), getNameList (1), identify (2), - rename (3), - read (4), - write (5), - getVariableAccessAttributes (6), - defineNamedVariable (7), - defineScatteredAccess (8), - getScatteredAccessAttributes (9), - deleteVariableAccess (10), - defineNamedVariableList (11), - getNamedVariableListAttributes (12), - deleteNamedVariableList (13), - defineNamedType (14), - getNamedTypeAttributes (15), - deleteNamedType (16), - input (17), - output (18), - takeControl (19), - relinquishControl (20), - defineSemaphore (21), - deleteSemaphore (22), - reportSemaphoreStatus (23), - reportPoolSemaphoreStatus (24), - reportSemaphoreEntryStatus (25), - initiateDownloadSequence (26), - downloadSegment (27), - terminateDownloadSequence (28), + rename (3), + read (4), + write (5), + getVariableAccessAttributes (6), + defineNamedVariable (7), + defineScatteredAccess (8), + getScatteredAccessAttributes (9), + deleteVariableAccess (10), + defineNamedVariableList (11), + getNamedVariableListAttributes (12), + deleteNamedVariableList (13), + defineNamedType (14), + getNamedTypeAttributes (15), + deleteNamedType (16), + input (17), + output (18), + takeControl (19), + relinquishControl (20), + defineSemaphore (21), + deleteSemaphore (22), + reportSemaphoreStatus (23), + reportPoolSemaphoreStatus (24), + reportSemaphoreEntryStatus (25), + initiateDownloadSequence (26), + downloadSegment (27), + terminateDownloadSequence (28), initiateUploadSequence (29), - uploadSegment (30), - terminateUploadSequence (31), - requestDomainDownload (32), - requestDomainUpload (33), - loadDomainContent (34), - storeDomainContent (35), - deleteDomain (36), - getDomainAttributes (37), - createProgramInvocation (38), - deleteProgramInvocation (39), - start (40), - stop (41), - resume (42), - reset (43), - kill (44), - getProgramInvocationAttributes (45), - obtainFile (46), - defineEventCondition (47), - deleteEventCondition (48), - getEventConditionAttributes (49), - reportEventConditionStatus (50), - alterEventConditionMonitoring (51), - triggerEvent (52), - defineEventAction (53), - deleteEventAction (54), - getEventActionAttributes (55), - reportActionStatus (56), - defineEventEnrollment (57), - deleteEventEnrollment (58), - alterEventEnrollment (59), - reportEventEnrollmentStatus (60), - getEventEnrollmentAttributes (61), - acknowledgeEventNotification (62), - getAlarmSummary (63), - getAlarmEnrollmentSummary (64), - readJournal (65), - writeJournal (66), - initializeJournal (67), - reportJournalStatus (68), - createJournal (69), - deleteJournal (70), - getCapabilityList (71), - fileOpen (72), - fileRead (73), - fileClose (74), - fileRename (75), - fileDelete (76), - fileDirectory (77), + uploadSegment (30), + terminateUploadSequence (31), + requestDomainDownload (32), + requestDomainUpload (33), + loadDomainContent (34), + storeDomainContent (35), + deleteDomain (36), + getDomainAttributes (37), + createProgramInvocation (38), + deleteProgramInvocation (39), + start (40), + stop (41), + resume (42), + reset (43), + kill (44), + getProgramInvocationAttributes (45), + obtainFile (46), + defineEventCondition (47), + deleteEventCondition (48), + getEventConditionAttributes (49), + reportEventConditionStatus (50), + alterEventConditionMonitoring (51), + triggerEvent (52), + defineEventAction (53), + deleteEventAction (54), + getEventActionAttributes (55), + reportActionStatus (56), + defineEventEnrollment (57), + deleteEventEnrollment (58), + alterEventEnrollment (59), + reportEventEnrollmentStatus (60), + getEventEnrollmentAttributes (61), + acknowledgeEventNotification (62), + getAlarmSummary (63), + getAlarmEnrollmentSummary (64), + readJournal (65), + writeJournal (66), + initializeJournal (67), + reportJournalStatus (68), + createJournal (69), + deleteJournal (70), + getCapabilityList (71), + fileOpen (72), + fileRead (73), + fileClose (74), + fileRename (75), + fileDelete (76), + fileDirectory (77), unsolicitedStatus (78), informationReport (79), eventNotification (80), @@ -485,10 +502,10 @@ ServiceError ::= SEQUENCE { vmd-state [0] IMPLICIT INTEGER { - other (0), - vmd-state-conflict (1), + other (0), + vmd-state-conflict (1), vmd-operational-problem (2), - domain-transfer-problem (3), + domain-transfer-problem (3), state-machine-id-invalid (4) }, application-reference [1] IMPLICIT INTEGER @@ -686,7 +703,7 @@ RejectPDU ::= SEQUENCE invalid-result (3), max-recursion-exceeded (5), value-out-of-range (6) - }, + }, confirmed-errorPDU [3] IMPLICIT INTEGER { @@ -695,7 +712,7 @@ RejectPDU ::= SEQUENCE invalid-invokeID (2), invalid-serviceError (3), value-out-of-range (4) - } , + } , unconfirmedPDU [4] IMPLICIT INTEGER { @@ -717,7 +734,7 @@ RejectPDU ::= SEQUENCE { other (0), invalid-invokeID (1) - }, + }, cancel-responsePDU [7] IMPLICIT INTEGER { @@ -737,7 +754,7 @@ RejectPDU ::= SEQUENCE { other (0), invalid-argument (1) - }, + }, conclude-responsePDU [10] IMPLICIT INTEGER { @@ -782,34 +799,38 @@ Status-Response ::= SEQUENCE { UnsolicitedStatus ::= Status-Response -- GETNAMELIST +ObjectClass ::= INTEGER + { + nammedVariable (0), + scatteredAccess (1), + namedVariableList (2), + namedType (3), + semaphore (4), + eventCondition (5), + eventAction (6), + eventEnrollment (7), + journal (8), + domain (9), + programInvocation (10), + operatorStation (11) + } + +ObjectScope ::= CHOICE + { + vmdSpecific [0] IMPLICIT NULL, + domainSpecific [1] IMPLICIT Identifier, + aaSpecific [2] IMPLICIT NULL + } + GetNameList-Request ::= SEQUENCE { extendedObjectClass [0] CHOICE { - objectClass [0] IMPLICIT INTEGER - { - nammedVariable (0), - scatteredAccess (1), - namedVariableList (2), - namedType (3), - semaphore (4), - eventCondition (5), - eventAction (6), - eventEnrollment (7), - journal (8), - domain (9), - programInvocation (10), - operatorStation (11) - } + objectClass [0] IMPLICIT ObjectClass }, - objectScope [1] CHOICE - { - vmdSpecific [0] IMPLICIT NULL, - domainSpecific [1] IMPLICIT Identifier, - aaSpecific [2] IMPLICIT NULL - }, - continueAfter [2] IMPLICIT Identifier OPTIONAL + objectScope [1] ObjectScope, + continueAfter [2] IMPLICIT Identifier OPTIONAL } GetNameList-Response ::= SEQUENCE @@ -1112,7 +1133,7 @@ GetProgramInvocationAttributes-Request ::= Identifier -- Program Invocation Name GetProgramInvocationAttributes-Response ::= SEQUENCE { state [0] IMPLICIT ProgramInvocationState, - listOfDomainNames [1] IMPLICIT SEQUENCE OF Identifier, + listOfDomainNames [1] IMPLICIT SEQUENCE OF Identifier, mmsDeletable [2] IMPLICIT BOOLEAN, reusable [3] IMPLICIT BOOLEAN, monitor [4] IMPLICIT BOOLEAN, @@ -1465,7 +1486,7 @@ Data ::= CHOICE -- context tag 0 is reserved for AccessResult array [1] IMPLICIT SEQUENCE OF Data, structure [2] IMPLICIT SEQUENCE OF Data, - boolean [3] IMPLICIT BOOLEAN, + boolean [3] IMPLICIT BOOLEAN, bit-string [4] IMPLICIT BIT STRING, integer [5] IMPLICIT INTEGER, unsigned [6] IMPLICIT INTEGER, @@ -2295,7 +2316,5 @@ FileAttributes ::= SEQUENCE { lastModified [1] IMPLICIT GeneralizedTime OPTIONAL } - - END diff --git a/epan/dissectors/asn1/mms/mms.cnf b/epan/dissectors/asn1/mms/mms.cnf index 68190ade..4c8c35d7 100644 --- a/epan/dissectors/asn1/mms/mms.cnf +++ b/epan/dissectors/asn1/mms/mms.cnf @@ -14,6 +14,7 @@ MMSpdu #.NO_EMIT #.TYPE_RENAME +ObjectName/domain-specific/itemId ObjectName_domain_specific_itemid #.TYPE_ATTR TimeOfDay TYPE = FT_STRING DISPLAY = BASE_NONE @@ -23,7 +24,7 @@ UtcTime TYPE = FT_STRING DISPLAY = BASE_NONE ConfirmedServiceRequest/deleteEventCondition confirmedServiceRequest_deleteEventCondition ConfirmedServiceResponse/deleteEventCondition confirmedServiceResponse_deleteEventCondition ConfirmedServiceRequest/deleteEventAction confirmedServiceRequest_deleteEventAction -ConfirmedServiceRequest/deleteEventAction confirmedServiceRequest_deleteEventAction +ConfirmedServiceResponse/deleteEventAction confirmedServiceRequest_deleteEventAction ConfirmedServiceRequest/deleteEventEnrollment confirmedServiceRequest_deleteEventEnrollment ConfirmedServiceResponse/deleteEventEnrollment confirmedServiceResponse_deleteEventEnrollment TypeSpecification/bit-string typeSpecification_bit-string @@ -43,12 +44,13 @@ GetDomainAttributes-Response/state getDomainAttributes-Response 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 -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 @@ -71,131 +73,817 @@ AlterEventEnrollment-Response/currentState/state ABBREV=alterEventEnrollment- #.FN_BODY ApplicationReference/ap-title - offset=dissect_acse_AP_title(FALSE, tvb, offset, actx, tree, hf_mms_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); + 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); + 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); + offset=dissect_acse_AE_invocation_identifier(false, tvb, offset, actx, tree, hf_mms_ae_invocation_id); #.FN_BODY MMSpdu VAL_PTR=&branch_taken - gint 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_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_fstr(actx->pinfo->cinfo, COL_INFO, "%%s", - mms_MMSpdu_vals[branch_taken].strptr); - } + 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 <RPT>"); + 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 -#.FN_BODY TimeOfDay +%(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; + } - guint32 len; - guint32 milliseconds; - guint16 days; - gchar * 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 +#.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 - guint32 len; - guint32 seconds; - guint32 fraction; - guint32 nanoseconds; - nstime_t ts; - gchar * ptime; +%(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; - len = tvb_reported_length_remaining(tvb, offset); +%(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; + } - if(len != 8) - { - 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; - } +#.FN_BODY ObjectScope VAL_PTR=&val + int val; - seconds = tvb_get_ntohl(tvb, offset); - fraction = tvb_get_ntoh24(tvb, offset+4) * 0x100; /* Only 3 bytes are recommended */ - nanoseconds = (guint32)( ((guint64)fraction * G_GUINT64_CONSTANT(1000000000)) / G_GUINT64_CONSTANT(0x100000000) ) ; +%(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; + } - ts.secs = seconds; - ts.nsecs = nanoseconds; +#.FN_BODY TimeOfDay - ptime = abs_time_to_str(actx->pinfo->pool, &ts, ABSOLUTE_TIME_UTC, TRUE); + 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); + } - if(hf_index >= 0) - { - proto_tree_add_string(tree, hf_index, tvb, offset, len, ptime); - } #.FN_BODY Unsigned32 VAL_PTR=&val - guint32 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) - private_data_add_preCinfo(actx, val); + 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); + private_data_add_moreCinfo_float(actx, tvb); -#.FN_BODY Identifier - int offset_id = offset; +#.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 - if ((hf_index == hf_mms_domainId) || (hf_index == hf_mms_itemId)) { - if (tvb_get_guint8(tvb, offset_id) == 0x1a) - private_data_add_moreCinfo_id(actx,tvb); - } + +#.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 + diff --git a/epan/dissectors/asn1/mms/packet-mms-template.c b/epan/dissectors/asn1/mms/packet-mms-template.c index 2706003d..5de53ca9 100644 --- a/epan/dissectors/asn1/mms/packet-mms-template.c +++ b/epan/dissectors/asn1/mms/packet-mms-template.c @@ -16,6 +16,8 @@ #include <epan/asn1.h> #include <epan/expert.h> #include <epan/proto_data.h> +#include <epan/conversation.h> +#include <wsutil/array.h> #include "packet-ber.h" #include "packet-acse.h" @@ -28,18 +30,70 @@ 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 = -1; +static int proto_mms; + +/* Conversation */ +static int hf_mms_response_in; +static int hf_mms_response_to; +static int hf_mms_response_time; + +/* IEC 61850-8-1 filters */ +static int hf_mms_iec61850_rptid; +static int hf_mms_iec61850_reported_optflds; +static int hf_mms_iec61850_seqnum; +static int hf_mms_iec61850_timeofentry; +static int hf_mms_iec61850_datset; +static int hf_mms_iec61850_bufovfl; +static int hf_mms_iec61850_confrev; +static int hf_mms_iec61850_inclusion_bitstring; +static int hf_mms_iec61850_ctlModel; + +static int hf_mms_iec61850_QualityC0; +static int hf_mms_iec61850_Quality20; +static int hf_mms_iec61850_Quality10; +static int hf_mms_iec61850_Quality8; +static int hf_mms_iec61850_Quality4; +static int hf_mms_iec61850_Quality2; +static int hf_mms_iec61850_Quality1; +static int hf_mms_iec61850_Quality0080; +static int hf_mms_iec61850_Quality0040; +static int hf_mms_iec61850_Quality0020; +static int hf_mms_iec61850_Quality0010; +static int hf_mms_iec61850_Quality0008; +static int hf_mms_iec61850_quality_bitstring; +static int hf_mms_iec61850_timequality80; +static int hf_mms_iec61850_timequality40; +static int hf_mms_iec61850_timequality20; +static int hf_mms_iec61850_timequality1F; +static int hf_mms_iec61850_check_bitstring; +static int hf_mms_iec61850_check_b1; +static int hf_mms_iec61850_check_b0; +static int hf_mms_iec61850_orcategory; +static int hf_mms_iec61850_beh$stval; +static int hf_mms_iec61850_mod$stval; +static int hf_mms_iec61850_health$stval; +static int hf_mms_iec61850_ctlval; +static int hf_mms_iec61850_origin; +static int hf_mms_iec61850_origin_orcat; +static int hf_mms_iec61850_origin_orident; +static int hf_mms_iec61850_ctlNum; +static int hf_mms_iec61850_T; +static int hf_mms_iec61850_test; #include "packet-mms-hf.c" /* Initialize the subtree pointers */ -static gint ett_mms = -1; +static int ett_mms; +static int ett_mms_iec61850_quality_bitstring; +static int ett_mms_iec61850_check_bitstring; #include "packet-mms-ett.c" -static expert_field ei_mms_mal_timeofday_encoding = EI_INIT; -static expert_field ei_mms_mal_utctime_encoding = EI_INIT; -static expert_field ei_mms_zero_pdu = EI_INIT; +static expert_field ei_mms_mal_timeofday_encoding; +static expert_field ei_mms_mal_utctime_encoding; +static expert_field ei_mms_zero_pdu; /*****************************************************************************/ /* Packet private data */ @@ -50,72 +104,321 @@ static expert_field ei_mms_zero_pdu = EI_INIT; #define BUFFER_SIZE_PRE 10 #define BUFFER_SIZE_MORE 1024 +typedef enum _iec61850_8_1_vmd_specific { + IEC61850_8_1_NOT_SET = 0, + IEC61850_8_1_RPT +} iec61850_8_1_vmd_specific; + +typedef enum _itemid_type { + IEC61850_ITEM_ID_NOT_SET = 0, + IEC61850_ITEM_ID_CTLMODEL, + IEC61850_ITEM_ID_Q, + IEC61850_ITEM_ID_OPER, + IEC61850_ITEM_ID_CHECK, + IEC61850_ITEM_ID_OR_CAT, + IEC61850_ITEM_ID_BEH$STVAL, + IEC61850_ITEM_ID_MOD$STVAL, + IEC61850_ITEM_ID_HEALTH$STVAL, + IEC61850_ITEM_ID_$BR$_OR_$RP$, + IEC61850_ITEM_ID_$SBOW +} itemid_type; + +typedef struct _mms_transaction_t { + uint32_t req_frame; + uint32_t rep_frame; + nstime_t req_time; + /* Request info*/ + itemid_type itemid; /* Numeric representation of ItemId substring */ + int conf_serv_pdu_type_req; +} mms_transaction_t; + +typedef struct _mms_conv_info_t { + wmem_map_t* pdus; +} mms_conv_info_t; + typedef struct mms_private_data_t { - char preCinfo[BUFFER_SIZE_PRE]; - char moreCinfo[BUFFER_SIZE_MORE]; + char preCinfo[BUFFER_SIZE_PRE]; + char moreCinfo[BUFFER_SIZE_MORE]; } mms_private_data_t; +#define MMS_CONFIRMED_REQUEST_PDU 0 +#define MMS_CONFIRMED_RESPONSE_PDU 1 +#define MMS_CONFIRMED_ERROR_PDU 2 +#define MMS_UNCONFIRMED_PDU 3 +#define MMS_REJECT_PDU 4 +#define MMS_CANCEL_REQUEST_PDU 5 +#define MMS_CANCEL_RESPONSE_PDU 6 +#define MMS_CANCEL_ERROR_PDU 7 +#define MMS_INITIATE_REQUEST_PDU 8 +#define MMS_INITIATE_RESPONSE_PDU 9 +#define MMS_INITIATE_ERROR_PDU 10 +#define MMS_CONCLUDE_REQUEST_PDU 11 +#define MMS_CONCLUDE_RESPONSE_PDU 12 +#define MMS_CONCLUDE_ERROR_PDU 13 + +#define MMS_CONFIRMEDSERVICE_STATUS 0 +#define MMS_CONFIRMEDSERVICE_GETNAMELIST 1 +#define MMS_CONFIRMEDSERVICE_IDENTIFY 2 +#define MMS_CONFIRMEDSERVICE_RENAME 3 +#define MMS_CONFIRMEDSERVICE_READ 4 +#define MMS_CONFIRMEDSERVICE_WRITE 5 +#define MMS_CONFIRMEDSERVICE_GETVARIABLEACCESSATTRIBUTES 6 +#define MMS_CONFIRMEDSERVICE_DEFINENAMEDVARIABLE 7 +#define MMS_CONFIRMEDSERVICE_DEFINESCATTEREDACCESS 8 +#define MMS_CONFIRMEDSERVICE_GETSCATTEREDACCESSATTRIBUTES 9 +#define MMS_CONFIRMEDSERVICE_DELETEVARIABLEACCESS 10 +#define MMS_CONFIRMEDSERVICE_DEFINENAMEDVARIABLELIST 11 +#define MMS_CONFIRMEDSERVICE_GETNAMEDVARIABLELISTATTRIBUTES 12 +#define MMS_CONFIRMEDSERVICE_DELETENAMEDVARIABLELIST 13 +#define MMS_CONFIRMEDSERVICE_DEFINENAMEDTYPE 14 +#define MMS_CONFIRMEDSERVICE_GETNAMEDTYPEATTRIBUTES 15 +#define MMS_CONFIRMEDSERVICE_DELETENAMEDTYPE 16 +#define MMS_CONFIRMEDSERVICE_INPUT 17 +#define MMS_CONFIRMEDSERVICE_OUTPUT 18 +#define MMS_CONFIRMEDSERVICE_TAKECONTROL 19 +#define MMS_CONFIRMEDSERVICE_RELINQUISHCONTROL 20 +#define MMS_CONFIRMEDSERVICE_DEFINESEMAPHORE 21 +#define MMS_CONFIRMEDSERVICE_DELETESEMAPHORE 22 +#define MMS_CONFIRMEDSERVICE_REPORTSEMAPHORESTATUS 23 +#define MMS_CONFIRMEDSERVICE_REPORTPOOLSEMAPHORESTATUS 24 +#define MMS_CONFIRMEDSERVICE_REPORTSEMAPHOREENTRYSTATUS 25 +#define MMS_CONFIRMEDSERVICE_INITIATEDOWNLOADSEQUENCE 26 +#define MMS_CONFIRMEDSERVICE_DOWNLOADSEGMENT 27 +#define MMS_CONFIRMEDSERVICE_TERMINATEDOWNLOADSEQUENCE 28 +#define MMS_CONFIRMEDSERVICE_INITIATEUPLOADSEQUENCE 29 +#define MMS_CONFIRMEDSERVICE_UPLOADSEGMENT 30 +#define MMS_CONFIRMEDSERVICE_TERMINATEUPLOADSEQUENCE 31 +#define MMS_CONFIRMEDSERVICE_REQUESTDOMAINDOWNLOAD 32 +#define MMS_CONFIRMEDSERVICE_REQUESTDOMAINUPLOAD 33 +#define MMS_CONFIRMEDSERVICE_LOADDOMAINCONTENT 34 +#define MMS_CONFIRMEDSERVICE_STOREDOMAINCONTENT 35 +#define MMS_CONFIRMEDSERVICE_DELETEDOMAIN 36 +#define MMS_CONFIRMEDSERVICE_GETDOMAINATTRIBUTES 37 +#define MMS_CONFIRMEDSERVICE_CREATEPROGRAMINVOCATION 38 +#define MMS_CONFIRMEDSERVICE_DELETEPROGRAMINVOCATION 39 +#define MMS_CONFIRMEDSERVICE_START 40 +#define MMS_CONFIRMEDSERVICE_STOP 41 +#define MMS_CONFIRMEDSERVICE_RESUME 42 +#define MMS_CONFIRMEDSERVICE_RESET 43 +#define MMS_CONFIRMEDSERVICE_KILL 44 +#define MMS_CONFIRMEDSERVICE_GETPROGRAMINVOCATIONATTRIBUTES 45 +#define MMS_CONFIRMEDSERVICE_OBTAINFILE 46 +#define MMS_CONFIRMEDSERVICE_DEFINEEVENTCONDITION 47 +#define MMS_CONFIRMEDSERVICE_DELETEEVENTCONDITION 48 +#define MMS_CONFIRMEDSERVICE_GETEVENTCONDITIONATTRIBUTES 49 +#define MMS_CONFIRMEDSERVICE_REPORTEVENTCONDITIONSTATUS 50 +#define MMS_CONFIRMEDSERVICE_ALTEREVENTCONDITIONMONITORING 51 +#define MMS_CONFIRMEDSERVICE_TRIGGEREVENT 52 +#define MMS_CONFIRMEDSERVICE_DEFINEEVENTACTION 53 +#define MMS_CONFIRMEDSERVICE_DELETEEVENTACTION 54 +#define MMS_CONFIRMEDSERVICE_GETEVENTACTIONATTRIBUTES 55 +#define MMS_CONFIRMEDSERVICE_REPORTEVENTACTIONSTATUS 56 +#define MMS_CONFIRMEDSERVICE_DEFINEEVENTENROLLMENT 57 +#define MMS_CONFIRMEDSERVICE_DELETEEVENTENROLLMENT 58 +#define MMS_CONFIRMEDSERVICE_ALTEREVENTENROLLMENT 59 +#define MMS_CONFIRMEDSERVICE_REPORTEVENTENROLLMENTSTATUS 60 +#define MMS_CONFIRMEDSERVICE_GETEVENTENROLLMENTATTRIBUTES 61 +#define MMS_CONFIRMEDSERVICE_ACKNOWLEDGEEVENTNOTIFICATION 62 +#define MMS_CONFIRMEDSERVICE_GETALARMSUMMARY 63 +#define MMS_CONFIRMEDSERVICE_GETALARMENROLLMENTSUMMARY 64 +#define MMS_CONFIRMEDSERVICE_READJOURNAL 65 +#define MMS_CONFIRMEDSERVICE_WRITEJOURNAL 66 +#define MMS_CONFIRMEDSERVICE_INITIALIZEJOURNAL 67 +#define MMS_CONFIRMEDSERVICE_REPORTJOURNALSTATUS 68 +#define MMS_CONFIRMEDSERVICE_CREATEJOURNAL 69 +#define MMS_CONFIRMEDSERVICE_DELETEJOURNAL 70 +#define MMS_CONFIRMEDSERVICE_GETCAPABILITYLIST 71 +#define MMS_CONFIRMEDSERVICE_FILEOPEN 72 +#define MMS_FILEREAD 73 +#define MMS_FILECLOSE 74 +#define MMS_FILERENAME 75 +#define MMS_FILEDELETE 76 +#define MMS_FILEDIRECTORY 77 + +#define MMS_OBJECTCLASS_NAMMEDVARIABLE 0 +#define MMS_OBJECTCLASS_NAMEDVARIABLELIST 2 +#define MMS_OBJECTCLASS_DOMAIN 9 + +#define MMS_OBJECTSCOPE_VMDSPECIFIC 0 +#define MMS_OBJECTSCOPE_DOMAINSPECIFIC 1 + +#define MMS_IEC_61850_CONF_SERV_PDU_NOT_SET 0 +#define MMS_IEC_61850_CONF_SERV_PDU_GET_SERV_DIR 1 +#define MMS_IEC_61850_CONF_SERV_PDU_GETLOGICALDEVICEDIRECTORY 2 +#define MMS_IEC_61850_CONF_SERV_PDU_GETDATASETDIRECTORY 3 +#define MMS_IEC_61850_CONF_SERV_PDU_GETDATADIRECTORY 4 +#define MMS_IEC_61850_CONF_SERV_PDU_SELECTWITHVALUE 5 +#define MMS_IEC_61850_CONF_SERV_PDU_READ 6 +#define MMS_IEC_61850_CONF_SERV_PDU_WRITE 7 + +typedef struct mms_actx_private_data_t +{ + int mms_pdu_type; /* MMSpdu type taken from MMSpdu CHOICE branch_taken */ + int invokeid; + iec61850_8_1_vmd_specific vmd_specific; /* Numeric representation of decode vmd_specific strings */ + int listOfAccessResult_cnt; /* Position in the list, 1 count */ + int data_cnt; /* Number of times data occurred(depth)*/ + uint16_t reported_optflds; /* Bitmap over included fields */ + proto_item* pdu_item; /* The item to append PDU info to */ + int confirmedservice_type; /* Requested service */ + int objectclass; + int objectscope; + mms_transaction_t* mms_trans_p; /* Pointer to the transaction record */ + char* itemid_str; + int success; /* If variable access succeeded or not */ +} mms_actx_private_data_t; + + +static const value_string mms_iec6150_cntmodel_vals[] = { + {0, "status-only"}, + {1, "direct-with-normal-security"}, + {2, "sbo-with-normal-security"}, + {3, "direct-with-enhanced-security"}, + {4, "sbo-with-enhanced-security"}, + {0, NULL} +}; + +static const value_string mms_iec6150_validity_vals[] = { + {0, "Good"}, + {1, "Invalid"}, + {2, "Reserved"}, + {3, "Questionable"}, + {0, NULL} +}; + +static const value_string mms_iec6150_source_vals[] = { + {0, "Process"}, + {1, "Substituted"}, + {0, NULL} +}; + +static const value_string mms_iec6150_timeaccuracy_vals[] = { + {0, "0 bits accuracy"}, + {1, "1 bits accuracy"}, + {2, "2 bits accuracy"}, + {3, "3 bits accuracy"}, + {4, "4 bits accuracy"}, + {5, "5 bits accuracy"}, + {6, "6 bits accuracy"}, + {7, "7 bits accuracy"}, + {8, "8 bits accuracy"}, + {9, "9 bits accuracy"}, + {10, "10 bits accuracy"}, + {11, "11 bits accuracy"}, + {12, "12 bits accuracy"}, + {13, "13 bits accuracy"}, + {14, "14 bits accuracy"}, + {15, "15 bits accuracy"}, + {16, "16 bits accuracy"}, + {17, "17 bits accuracy"}, + {18, "18 bits accuracy"}, + {19, "19 bits accuracy"}, + {20, "20 bits accuracy"}, + {21, "21 bits accuracy"}, + {22, "22 bits accuracy"}, + {23, "23 bits accuracy"}, + {24, "24 bits accuracy"}, + {25, "25 bits accuracy"}, + {26, "26 bits accuracy"}, + {27, "27 bits accuracy"}, + {28, "28 bits accuracy"}, + {29, "29 bits accuracy"}, + {30, "Invalid"}, + {31, "Unspecified"}, + {0, NULL} +}; + +static const value_string mms_iec6150_orcategory_vals[] = { + {0, "not-supported"}, + {1, "bay-control"}, + {2, "station-control"}, + {3, "remote-control"}, + {4, "automatic-bay"}, + {5, "automatic-station"}, + {6, "automatic-station"}, + {7, "maintenance"}, + {8, "process"}, + {0, NULL} +}; + +static const value_string mms_iec6150_beh_vals[] = { + {0,"Uninitialised"}, + {1, "on"}, + {2, "blocked"}, + {3, "test"}, + {4, "test/blocked"}, + {5, "off"}, + {0, NULL} +}; + +static const value_string mms_iec6150_health_vals[] = { + {0,"Uninitialised"}, + {1,"Ok"}, + {2,"Warning"}, + {3,"Alarm"}, + {0, NULL} +}; /* Helper function to get or create the private data struct */ static -mms_private_data_t* mms_get_private_data(asn1_ctx_t *actx) +mms_private_data_t* mms_get_private_data(asn1_ctx_t* actx) { - packet_info *pinfo = actx->pinfo; - mms_private_data_t *private_data = (mms_private_data_t *)p_get_proto_data(pinfo->pool, pinfo, proto_mms, pinfo->curr_layer_num); - if(private_data != NULL ) - return private_data; - else { - private_data = wmem_new0(pinfo->pool, mms_private_data_t); - p_add_proto_data(pinfo->pool, pinfo, proto_mms, pinfo->curr_layer_num, private_data); - return private_data; - } + packet_info* pinfo = actx->pinfo; + mms_private_data_t* private_data = (mms_private_data_t*)p_get_proto_data(pinfo->pool, pinfo, proto_mms, pinfo->curr_layer_num); + if (private_data != NULL) { + return private_data; + } else { + private_data = wmem_new0(pinfo->pool, mms_private_data_t); + p_add_proto_data(pinfo->pool, pinfo, proto_mms, pinfo->curr_layer_num, private_data); + return private_data; + } } /* Helper function to test presence of private data struct */ -static gboolean -mms_has_private_data(asn1_ctx_t *actx) +static bool +mms_has_private_data(asn1_ctx_t* actx) { - packet_info *pinfo = actx->pinfo; - return (p_get_proto_data(pinfo->pool, pinfo, proto_mms, pinfo->curr_layer_num) != NULL); + packet_info* pinfo = actx->pinfo; + return (p_get_proto_data(pinfo->pool, pinfo, proto_mms, pinfo->curr_layer_num) != NULL); } static void -private_data_add_preCinfo(asn1_ctx_t *actx, guint32 val) +private_data_add_preCinfo(asn1_ctx_t* actx, uint32_t val) { - mms_private_data_t *private_data = (mms_private_data_t*)mms_get_private_data(actx); - snprintf(private_data->preCinfo, BUFFER_SIZE_PRE, "%02d ", val); + mms_private_data_t* private_data = (mms_private_data_t*)mms_get_private_data(actx); + snprintf(private_data->preCinfo, BUFFER_SIZE_PRE, "%02d ", val); } static char* -private_data_get_preCinfo(asn1_ctx_t *actx) +private_data_get_preCinfo(asn1_ctx_t* actx) { - mms_private_data_t *private_data = (mms_private_data_t*)mms_get_private_data(actx); - return private_data->preCinfo; + mms_private_data_t* private_data = (mms_private_data_t*)mms_get_private_data(actx); + return private_data->preCinfo; } static void -private_data_add_moreCinfo_id(asn1_ctx_t *actx, tvbuff_t *tvb) +private_data_add_moreCinfo_id(asn1_ctx_t* actx, tvbuff_t* tvb) { - mms_private_data_t *private_data = (mms_private_data_t*)mms_get_private_data(actx); - (void) g_strlcat(private_data->moreCinfo, " ", BUFFER_SIZE_MORE); - (void) g_strlcat(private_data->moreCinfo, tvb_get_string_enc(actx->pinfo->pool, - tvb, 2, tvb_get_guint8(tvb, 1), ENC_STRING), BUFFER_SIZE_MORE); + mms_private_data_t* private_data = (mms_private_data_t*)mms_get_private_data(actx); + (void)g_strlcat(private_data->moreCinfo, " ", BUFFER_SIZE_MORE); + (void)g_strlcat(private_data->moreCinfo, tvb_get_string_enc(actx->pinfo->pool, tvb, + 0, tvb_reported_length(tvb), ENC_ASCII | ENC_NA), BUFFER_SIZE_MORE); } static void -private_data_add_moreCinfo_float(asn1_ctx_t *actx, tvbuff_t *tvb) +private_data_add_moreCinfo_float(asn1_ctx_t* actx, tvbuff_t* tvb) { - mms_private_data_t *private_data = (mms_private_data_t*)mms_get_private_data(actx); - snprintf(private_data->moreCinfo, BUFFER_SIZE_MORE, - " %f", tvb_get_ieee_float(tvb, 1, ENC_BIG_ENDIAN)); + mms_private_data_t* private_data = (mms_private_data_t*)mms_get_private_data(actx); + snprintf(private_data->moreCinfo, BUFFER_SIZE_MORE, + " %f", tvb_get_ieee_float(tvb, 1, ENC_BIG_ENDIAN)); } static char* -private_data_get_moreCinfo(asn1_ctx_t *actx) +private_data_get_moreCinfo(asn1_ctx_t* actx) { - mms_private_data_t *private_data = (mms_private_data_t*)mms_get_private_data(actx); - return private_data->moreCinfo; + mms_private_data_t* private_data = (mms_private_data_t*)mms_get_private_data(actx); + return private_data->moreCinfo; } /*****************************************************************************/ @@ -127,122 +430,318 @@ private_data_get_moreCinfo(asn1_ctx_t *actx) * Dissect MMS PDUs inside a PPDU. */ static int -dissect_mms(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_) +dissect_mms(tvbuff_t* tvb, packet_info* pinfo, proto_tree* parent_tree, void* data _U_) { - int offset = 0; - int old_offset; - proto_item *item=NULL; - proto_tree *tree=NULL; - asn1_ctx_t asn1_ctx; - asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); - - if(parent_tree){ - item = proto_tree_add_item(parent_tree, proto_mms, tvb, 0, -1, ENC_NA); - tree = proto_item_add_subtree(item, ett_mms); - } - col_set_str(pinfo->cinfo, COL_PROTOCOL, "MMS"); - col_clear(pinfo->cinfo, COL_INFO); - - while (tvb_reported_length_remaining(tvb, offset) > 0){ - old_offset=offset; - offset=dissect_mms_MMSpdu(FALSE, tvb, offset, &asn1_ctx , tree, -1); - if(offset == old_offset){ - proto_tree_add_expert(tree, pinfo, &ei_mms_zero_pdu, tvb, offset, -1); - break; - } - } - return tvb_captured_length(tvb); + int offset = 0; + int old_offset; + proto_item* item = NULL; + proto_tree* tree = NULL; + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo); + + if (parent_tree) { + item = proto_tree_add_item(parent_tree, proto_mms, tvb, 0, -1, ENC_NA); + tree = proto_item_add_subtree(item, ett_mms); + asn1_ctx.subtree.top_tree = parent_tree; + } + if (use_iec61850_mapping) { + col_set_str(pinfo->cinfo, COL_PROTOCOL, "MMS/IEC61850"); + } + else { + col_set_str(pinfo->cinfo, COL_PROTOCOL, "MMS"); + } + col_clear(pinfo->cinfo, COL_INFO); + + 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; + } + } + return tvb_captured_length(tvb); } /*--- proto_register_mms -------------------------------------------*/ void proto_register_mms(void) { - /* List of fields */ - static hf_register_info hf[] = - { + /* List of fields */ + static hf_register_info hf[] = + { + { &hf_mms_response_in, + { "Response In", "mms.response_in", + FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0, + "The response to this mms request is in this frame", HFILL } + }, + { &hf_mms_response_to, + { "Request In", "mms.response_to", + FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0, + "This is a response to the mms request in this frame", HFILL } + }, + { &hf_mms_response_time, + { "Response Time", "mms.response_time", + FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, + "The time between the Call and the Reply", HFILL } + }, + { &hf_mms_iec61850_rptid, + { "RptID", "mms.iec61850.rptid", + FT_STRING, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_mms_iec61850_reported_optflds, + { "Reported OptFlds", "mms.iec61850.reported_optfld", + FT_BYTES, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_mms_iec61850_seqnum, + { "SeqNum", "mms.iec61850.seqnum", + FT_INT32, BASE_DEC, NULL, 0, + NULL, HFILL }}, + { &hf_mms_iec61850_timeofentry, + { "TimeOfEntry", "mms.iec61850.timeofentry", + FT_STRING, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_mms_iec61850_datset, + { "DatSet", "mms.iec61850.datset", + FT_STRING, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_mms_iec61850_bufovfl, + { "BufOvfl", "mms.iec61850.bufovfl", + FT_BOOLEAN, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_mms_iec61850_confrev, + { "ConfRev", "mms.iec61850.confrev", + FT_INT32, BASE_DEC, NULL, 0, + NULL, HFILL }}, + { &hf_mms_iec61850_inclusion_bitstring, + { "Inclusion-bitstring", "mms.iec61850.inclusion_bitstring", + FT_BYTES, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_mms_iec61850_ctlModel, + { "ctlModel", "mms.iec61850.ctlmodel", + FT_UINT8, BASE_DEC, VALS(mms_iec6150_cntmodel_vals), 0, + NULL, HFILL }}, + { &hf_mms_iec61850_QualityC0, + { "Validity", "mms.iec61850.validity", + FT_UINT8, BASE_HEX, VALS(mms_iec6150_validity_vals), 0xC0, + NULL, HFILL }}, + { &hf_mms_iec61850_Quality20, + { "Overflow", "mms.iec61850.overflow", + FT_BOOLEAN, 8, NULL, 0x20, + NULL, HFILL }}, + { &hf_mms_iec61850_Quality10, + { "OutofRange", "mms.iec61850.outofrange", + FT_BOOLEAN, 8, NULL, 0x10, + NULL, HFILL }}, + { &hf_mms_iec61850_Quality8, + { "BadReference", "mms.iec61850.badreference", + FT_BOOLEAN, 8, NULL, 0x08, + NULL, HFILL }}, + { &hf_mms_iec61850_Quality4, + { "Oscillatory", "mms.iec61850.oscillatory", + FT_BOOLEAN, 8, NULL, 0x04, + NULL, HFILL }}, + { &hf_mms_iec61850_Quality2, + { "Failure", "mms.iec61850.failure", + FT_BOOLEAN, 8, NULL, 0x02, + NULL, HFILL }}, + { &hf_mms_iec61850_Quality1, + { "OldData", "mms.iec61850.oldData", + FT_BOOLEAN, 8, NULL, 0x01, + NULL, HFILL }}, + { &hf_mms_iec61850_Quality0080, + { "Inconsistent", "mms.iec61850.inconsistent", + FT_BOOLEAN, 8, NULL, 0x80, + NULL, HFILL }}, + { &hf_mms_iec61850_Quality0040, + { "Inaccurate", "mms.iec61850.inaccurate", + FT_BOOLEAN, 8, NULL, 0x40, + NULL, HFILL }}, + { &hf_mms_iec61850_Quality0020, + { "Source", "mms.iec61850.source", + FT_UINT8, BASE_HEX, VALS(mms_iec6150_source_vals), 0x20, + NULL, HFILL }}, + { &hf_mms_iec61850_Quality0010, + { "Test", "mms.iec61850.test", + FT_BOOLEAN, 8, NULL, 0x10, + NULL, HFILL }}, + { &hf_mms_iec61850_Quality0008, + { "OperatorBlocked", "mms.iec61850.operatorblocked", + FT_BOOLEAN, 8, NULL, 0x08, + NULL, HFILL }}, + { &hf_mms_iec61850_quality_bitstring, + { "Quality", "mms.iec61850.quality_bitstring", + FT_BYTES, BASE_NONE, NULL, 0, + NULL, HFILL } }, + { &hf_mms_iec61850_timequality80, + { "Leap Second Known", "mms.iec61850.leapsecondknown", + FT_BOOLEAN, 8, NULL, 0x80, + NULL, HFILL } }, + { &hf_mms_iec61850_timequality40, + { "ClockFailure", "mms.iec61850.clockfailure", + FT_BOOLEAN, 8, NULL, 0x40, + NULL, HFILL } }, + { &hf_mms_iec61850_timequality20, + { "Clock not synchronized", "mms.iec61850.clocknotsynchronized", + FT_BOOLEAN, 8, NULL, 0x20, + NULL, HFILL } }, + { &hf_mms_iec61850_timequality1F, + { "Time Accuracy", "mms.iec61850.timeaccuracy", + FT_UINT8, BASE_HEX, VALS(mms_iec6150_timeaccuracy_vals), 0x1F, + NULL, HFILL } }, + { &hf_mms_iec61850_check_bitstring, + { "Check", "mms.iec61850.check_bitstring", + FT_BYTES, BASE_NONE, NULL, 0, + NULL, HFILL } }, + { &hf_mms_iec61850_check_b1, + { "Synchrocheck", "mms.iec61850.synchrocheck", + FT_BOOLEAN, 2, NULL, 0x2, + NULL, HFILL } }, + { &hf_mms_iec61850_check_b0, + { "Interlock-check", "mms.iec61850.interlockcheck", + FT_BOOLEAN, 2, NULL, 0x1, + NULL, HFILL } }, + { &hf_mms_iec61850_orcategory, + { "orCategory", "mms.iec61850.orcategory", + FT_UINT8, BASE_DEC, VALS(mms_iec6150_orcategory_vals), 0, + NULL, HFILL } }, + { &hf_mms_iec61850_beh$stval, + { "beh", "mms.iec61850.beh", + FT_UINT8, BASE_DEC, VALS(mms_iec6150_beh_vals), 0, + NULL, HFILL } }, + { &hf_mms_iec61850_mod$stval, + { "mod", "mms.iec61850.mod", + FT_UINT8, BASE_DEC, VALS(mms_iec6150_beh_vals), 0, + NULL, HFILL } }, + { &hf_mms_iec61850_health$stval, + { "health", "mms.iec61850.health", + FT_UINT8, BASE_DEC, VALS(mms_iec6150_health_vals), 0, + NULL, HFILL } }, + { &hf_mms_iec61850_ctlval, + { "ctlVal", "mms.iec61850.ctlval", + FT_BOOLEAN, BASE_NONE, NULL, 0, + NULL, HFILL } }, + { &hf_mms_iec61850_origin, + { "Origin", "mms.iec61850.origin", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL } }, + { &hf_mms_iec61850_origin_orcat, + { "Origin Category", "mms.iec61850.orcat", + FT_UINT8, BASE_DEC, NULL, 0, + NULL, HFILL } }, + { &hf_mms_iec61850_origin_orident, + { "Origin Identifier", "mms.iec61850.orident", + FT_BYTES, BASE_NONE, NULL, 0, + NULL, HFILL } }, + { &hf_mms_iec61850_ctlNum, + { "ctlNum", "mms.iec61850.ctlnum", + FT_INT8, BASE_DEC, NULL, 0, + NULL, HFILL } }, + { &hf_mms_iec61850_T, + { "T(Timestamp)", "mms.iec61850.timestamp", + FT_STRING, BASE_NONE, NULL, 0, + NULL, HFILL } }, + { &hf_mms_iec61850_test, + { "Test", "mms.iec61850.test", + FT_BOOLEAN, BASE_NONE, NULL, 0, + NULL, HFILL }}, #include "packet-mms-hfarr.c" - }; + }; - /* List of subtrees */ - static gint *ett[] = { - &ett_mms, + /* List of subtrees */ + static int* ett[] = { + &ett_mms, + &ett_mms_iec61850_quality_bitstring, + &ett_mms_iec61850_check_bitstring, #include "packet-mms-ettarr.c" - }; - - static ei_register_info ei[] = { - { &ei_mms_mal_timeofday_encoding, { "mms.malformed.timeofday_encoding", PI_MALFORMED, PI_WARN, "BER Error: malformed TimeOfDay encoding", EXPFILL }}, - { &ei_mms_mal_utctime_encoding, { "mms.malformed.utctime", PI_MALFORMED, PI_WARN, "BER Error: malformed IEC61850 UTCTime encoding", EXPFILL }}, - { &ei_mms_zero_pdu, { "mms.zero_pdu", PI_PROTOCOL, PI_ERROR, "Internal error, zero-byte MMS PDU", EXPFILL }}, - }; - - expert_module_t* expert_mms; - - /* Register protocol */ - proto_mms = proto_register_protocol(PNAME, PSNAME, PFNAME); - register_dissector("mms", dissect_mms, proto_mms); - /* Register fields and subtrees */ - proto_register_field_array(proto_mms, hf, array_length(hf)); - proto_register_subtree_array(ett, array_length(ett)); - expert_mms = expert_register_protocol(proto_mms); - expert_register_field_array(expert_mms, ei, array_length(ei)); - + }; + + static ei_register_info ei[] = { + { &ei_mms_mal_timeofday_encoding, { "mms.malformed.timeofday_encoding", PI_MALFORMED, PI_WARN, "BER Error: malformed TimeOfDay encoding", EXPFILL }}, + { &ei_mms_mal_utctime_encoding, { "mms.malformed.utctime", PI_MALFORMED, PI_WARN, "BER Error: malformed IEC61850 UTCTime encoding", EXPFILL }}, + { &ei_mms_zero_pdu, { "mms.zero_pdu", PI_PROTOCOL, PI_ERROR, "Internal error, zero-byte MMS PDU", EXPFILL }}, + }; + + expert_module_t* expert_mms; + + /* Register protocol */ + proto_mms = proto_register_protocol(PNAME, PSNAME, PFNAME); + register_dissector("mms", dissect_mms, proto_mms); + /* Register fields and subtrees */ + proto_register_field_array(proto_mms, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + 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 dissection as IEC-61850 on top of MMS", + &use_iec61850_mapping); } -static gboolean -dissect_mms_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_) +static bool +dissect_mms_heur(tvbuff_t* tvb, packet_info* pinfo, proto_tree* parent_tree, void* data) { - /* must check that this really is an mms packet */ - int offset = 0; - guint32 length = 0 ; - guint32 oct; - gint idx = 0 ; - - gint8 tmp_class; - bool tmp_pc; - gint32 tmp_tag; - - /* first, check do we have at least 2 bytes (pdu) */ - if (!tvb_bytes_exist(tvb, 0, 2)) - return FALSE; /* no */ - - /* can we recognize MMS PDU ? Return FALSE if not */ - /* get MMS PDU type */ - offset = get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag); - - /* check MMS type */ - - /* Class should be constructed */ - if (tmp_class!=BER_CLASS_CON) - return FALSE; - - /* see if the tag is a valid MMS PDU */ - try_val_to_str_idx(tmp_tag, mms_MMSpdu_vals, &idx); - if (idx == -1) { - return FALSE; /* no, it isn't an MMS PDU */ - } - - /* check MMS length */ - oct = tvb_get_guint8(tvb, offset)& 0x7F; - if (oct==0) - /* MMS requires length after tag so not MMS if indefinite length*/ - return FALSE; - - offset = get_ber_length(tvb, offset, &length, NULL); - /* do we have enough bytes? */ - if (!tvb_bytes_exist(tvb, offset, length)) - return FALSE; - - dissect_mms(tvb, pinfo, parent_tree, data); - return TRUE; + /* must check that this really is an mms packet */ + int offset = 0; + uint32_t length = 0; + uint32_t oct; + int idx = 0; + + int8_t tmp_class; + bool tmp_pc; + int32_t tmp_tag; + + /* first, check do we have at least 2 bytes (pdu) */ + if (!tvb_bytes_exist(tvb, 0, 2)) + return false; /* no */ + + /* can we recognize MMS PDU ? Return false if not */ + /* get MMS PDU type */ + offset = get_ber_identifier(tvb, offset, &tmp_class, &tmp_pc, &tmp_tag); + + /* check MMS type */ + + /* Class should be constructed */ + if (tmp_class != BER_CLASS_CON) + return false; + + /* see if the tag is a valid MMS PDU */ + try_val_to_str_idx(tmp_tag, mms_MMSpdu_vals, &idx); + if (idx == -1) { + return false; /* no, it isn't an MMS PDU */ + } + + /* check MMS length */ + oct = tvb_get_uint8(tvb, offset) & 0x7F; + if (oct == 0) + /* MMS requires length after tag so not MMS if indefinite length*/ + return false; + + offset = get_ber_length(tvb, offset, &length, NULL); + /* do we have enough bytes? */ + if (!tvb_bytes_exist(tvb, offset, length)) + return false; + + dissect_mms(tvb, pinfo, parent_tree, data); + return true; } /*--- proto_reg_handoff_mms --- */ void proto_reg_handoff_mms(void) { - register_ber_oid_dissector("1.0.9506.2.3", dissect_mms, proto_mms,"MMS"); - register_ber_oid_dissector("1.0.9506.2.1", dissect_mms, proto_mms,"mms-abstract-syntax-version1(1)"); - heur_dissector_add("cotp", dissect_mms_heur, "MMS over COTP", "mms_cotp", proto_mms, HEURISTIC_ENABLE); - heur_dissector_add("cotp_is", dissect_mms_heur, "MMS over COTP (inactive subset)", "mms_cotp_is", proto_mms, HEURISTIC_ENABLE); + register_ber_oid_dissector("1.0.9506.2.3", dissect_mms, proto_mms, "MMS"); + register_ber_oid_dissector("1.0.9506.2.1", dissect_mms, proto_mms, "mms-abstract-syntax-version1(1)"); + heur_dissector_add("cotp", dissect_mms_heur, "MMS over COTP", "mms_cotp", proto_mms, HEURISTIC_ENABLE); + heur_dissector_add("cotp_is", dissect_mms_heur, "MMS over COTP (inactive subset)", "mms_cotp_is", proto_mms, HEURISTIC_ENABLE); } |