diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
commit | e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch) | |
tree | 68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/dissectors/asn1/h248 | |
parent | Initial commit. (diff) | |
download | wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip |
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/asn1/h248')
-rw-r--r-- | epan/dissectors/asn1/h248/CMakeLists.txt | 36 | ||||
-rw-r--r-- | epan/dissectors/asn1/h248/MEGACO.asn | 987 | ||||
-rw-r--r-- | epan/dissectors/asn1/h248/h248.cnf | 413 | ||||
-rw-r--r-- | epan/dissectors/asn1/h248/h248v1support.asn | 45 | ||||
-rw-r--r-- | epan/dissectors/asn1/h248/h248v3.asn | 1101 | ||||
-rw-r--r-- | epan/dissectors/asn1/h248/packet-h248-template.c | 2397 | ||||
-rw-r--r-- | epan/dissectors/asn1/h248/packet-h248-template.h | 284 |
7 files changed, 5263 insertions, 0 deletions
diff --git a/epan/dissectors/asn1/h248/CMakeLists.txt b/epan/dissectors/asn1/h248/CMakeLists.txt new file mode 100644 index 00000000..31fd389c --- /dev/null +++ b/epan/dissectors/asn1/h248/CMakeLists.txt @@ -0,0 +1,36 @@ +# CMakeLists.txt +# +# Wireshark - Network traffic analyzer +# By Gerald Combs <gerald@wireshark.org> +# Copyright 1998 Gerald Combs +# +# SPDX-License-Identifier: GPL-2.0-or-later +# + +set( PROTOCOL_NAME h248 ) + +set( PROTO_OPT ) + +set( EXT_ASN_FILE_LIST +) + +set( ASN_FILE_LIST + h248v3.asn + h248v1support.asn +) + +set( EXTRA_DIST + ${ASN_FILE_LIST} + packet-${PROTOCOL_NAME}-template.c + packet-${PROTOCOL_NAME}-template.h + ${PROTOCOL_NAME}.cnf +) + +set( SRC_FILES + ${EXTRA_DIST} + ${EXT_ASN_FILE_LIST} +) + +set( A2W_FLAGS -b ) + +ASN2WRS() diff --git a/epan/dissectors/asn1/h248/MEGACO.asn b/epan/dissectors/asn1/h248/MEGACO.asn new file mode 100644 index 00000000..aab13234 --- /dev/null +++ b/epan/dissectors/asn1/h248/MEGACO.asn @@ -0,0 +1,987 @@ +-- This ASN definition is taken from +-- http://132.151.1.19/internet-drafts/draft-ietf-megaco-h248v2-04.txt +-- +-- and has been modified to pass through the ASN2ETH compiler +-- (we dont support automatic tags yet so the tags had to be added by +-- hand) + +MEDIA-GATEWAY-CONTROL {itu-t(0) recommendation(0) h(8) h248(248) +modules(0) media-gateway-control(0) version2(2)} +DEFINITIONS AUTOMATIC TAGS ::= +BEGIN + + MegacoMessage ::= SEQUENCE + { + authHeader [0] IMPLICIT AuthenticationHeader OPTIONAL, + mess [1] IMPLICIT Message + } + + AuthenticationHeader ::= SEQUENCE + { + secParmIndex [0] IMPLICIT SecurityParmIndex, + seqNum [1] IMPLICIT SequenceNum, + ad [2] IMPLICIT AuthData + } + + SecurityParmIndex ::= OCTET STRING(SIZE(4)) + + SequenceNum ::= OCTET STRING(SIZE(4)) + + AuthData ::= OCTET STRING (SIZE (12..32)) + + Message ::= SEQUENCE + { + version [0] IMPLICIT INTEGER(0..99), + -- The version of the protocol defined here is equal to 2. + mId [1] MId, -- Name/address of message originator + messageBody [2] CHOICE + { + messageError [0] IMPLICIT ErrorDescriptor, + transactions [1] IMPLICIT SEQUENCE OF Transaction + }, + ... + } + + MId ::= CHOICE + { + ip4Address [0] IMPLICIT IP4Address, + ip6Address [1] IMPLICIT IP6Address, + domainName [2] IMPLICIT DomainName, + deviceName [3] IMPLICIT PathName, + mtpAddress [4] IMPLICIT MtpAddress, + -- Addressing structure of mtpAddress: + -- 25 - 15 0 + -- | PC | NI | + -- 24 - 14 bits 2 bits + -- Note: 14 bits are defined for international use. + -- Two national options exist where the point code is 16 or 24 + -- bits. + -- To octet align the mtpAddress, the MSBs shall be encoded as 0s. + ... + } + + MtpAddress ::= OCTET STRING(SIZE(2..4)) + + DomainName ::= SEQUENCE + { + name [0] IMPLICIT IA5String, + -- The name starts with an alphanumeric digit followed by a + -- sequence of alphanumeric digits, hyphens and dots. No two + -- dots shall occur consecutively. + portNumber [1] IMPLICIT INTEGER(0..65535) OPTIONAL + } + + IP4Address ::= SEQUENCE + { + address [0] IMPLICIT OCTET STRING (SIZE(4)), + portNumber [1] IMPLICIT INTEGER(0..65535) OPTIONAL + } + + IP6Address ::= SEQUENCE + { + address [0] IMPLICIT OCTET STRING (SIZE(16)), + portNumber [1] IMPLICIT INTEGER(0..65535) OPTIONAL + } + + PathName ::= IA5String(SIZE (1..64)) + -- See A.3 + + Transaction ::= CHOICE + { + transactionRequest [0] IMPLICIT TransactionRequest, + transactionPending [1] IMPLICIT TransactionPending, + transactionReply [2] IMPLICIT TransactionReply, + transactionResponseAck [3] IMPLICIT TransactionResponseAck, + -- use of response acks is dependent on underlying transport + ... + } + + TransactionId ::= INTEGER(0..4294967295) -- 32-bit unsigned integer + + TransactionRequest ::= SEQUENCE + { + transactionId [0] IMPLICIT TransactionId, + actions [1] IMPLICIT SEQUENCE OF ActionRequest, + ... + } + + TransactionPending ::= SEQUENCE + { + transactionId [0] IMPLICIT TransactionId, + ... + } + + TransactionReply ::= SEQUENCE + { + transactionId [0] IMPLICIT TransactionId, + immAckRequired [1] IMPLICIT NULL OPTIONAL, + transactionResult [2] CHOICE + { + transactionError [0] IMPLICIT ErrorDescriptor, + actionReplies [1] IMPLICIT SEQUENCE OF ActionReply + }, + ... + } + + TransactionResponseAck ::= SEQUENCE OF TransactionAck + TransactionAck ::= SEQUENCE + { + firstAck [0] IMPLICIT TransactionId, + lastAck [1] IMPLICIT TransactionId OPTIONAL + } + + ErrorDescriptor ::= SEQUENCE + { + errorCode [0] IMPLICIT ErrorCode, + errorText [1] IMPLICIT ErrorText OPTIONAL + } + + ErrorCode ::= INTEGER(0..65535) + -- See clause 14 for IANA considerations with respect to error codes + + ErrorText ::= IA5String + + ContextID ::= INTEGER(0..4294967295) + + -- Context NULL Value: 0 + -- Context CHOOSE Value: 4294967294 (0xFFFFFFFE) + -- Context ALL Value: 4294967295 (0xFFFFFFFF) + + + ActionRequest ::= SEQUENCE + { + contextId [0] IMPLICIT ContextID, + contextRequest [1] IMPLICIT ContextRequest OPTIONAL, + contextAttrAuditReq [2] IMPLICIT ContextAttrAuditRequest OPTIONAL, + commandRequests [3] IMPLICIT SEQUENCE OF CommandRequest + } + + ActionReply ::= SEQUENCE + { + contextId [0] IMPLICIT ContextID, + errorDescriptor [1] IMPLICIT ErrorDescriptor OPTIONAL, + contextReply [2] IMPLICIT ContextRequest OPTIONAL, + commandReply [3] IMPLICIT SEQUENCE OF CommandReply + } + + ContextRequest ::= SEQUENCE + { + priority [0] IMPLICIT INTEGER(0..15) OPTIONAL, + emergency [1] IMPLICIT BOOLEAN OPTIONAL, + topologyReq [2] IMPLICIT SEQUENCE OF TopologyRequest OPTIONAL, + ... + } + + ContextAttrAuditRequest ::= SEQUENCE + { + topology [0] IMPLICIT NULL OPTIONAL, + emergency [1] IMPLICIT NULL OPTIONAL, + priority [2] IMPLICIT NULL OPTIONAL, + ... + } + + CommandRequest ::= SEQUENCE + { + command [0] Command, + optional [1] IMPLICIT NULL OPTIONAL, + wildcardReturn [2] IMPLICIT NULL OPTIONAL, + ... + } + + Command ::= CHOICE + { + addReq [0] IMPLICIT AmmRequest, + moveReq [1] IMPLICIT AmmRequest, + modReq [2] IMPLICIT AmmRequest, + -- Add, Move, Modify requests have the same parameters + subtractReq [3] IMPLICIT SubtractRequest, + auditCapRequest [4] IMPLICIT AuditRequest, + auditValueRequest [5] IMPLICIT AuditRequest, + notifyReq [6] IMPLICIT NotifyRequest, + serviceChangeReq [7] IMPLICIT ServiceChangeRequest, + ... + } + + CommandReply ::= CHOICE + { + addReply [0] IMPLICIT AmmsReply, + moveReply [1] IMPLICIT AmmsReply, + modReply [2] IMPLICIT AmmsReply, + subtractReply [3] IMPLICIT AmmsReply, + -- Add, Move, Modify, Subtract replies have the same parameters + auditCapReply [4] AuditReply, + auditValueReply [5] AuditReply, + notifyReply [6] IMPLICIT NotifyReply, + serviceChangeReply [7] IMPLICIT ServiceChangeReply, + ... + } + + TopologyRequest ::= SEQUENCE + { + terminationFrom [0] IMPLICIT TerminationID, + terminationTo [1] IMPLICIT TerminationID, + topologyDirection [2] IMPLICIT ENUMERATED + { + bothway(0), + isolate(1), + oneway(2) + }, + ..., + streamID [3] IMPLICIT StreamID OPTIONAL + } + + AmmRequest ::= SEQUENCE + { + terminationID [0] IMPLICIT TerminationIDList, + descriptors [1] IMPLICIT SEQUENCE OF AmmDescriptor, + -- At most one descriptor of each type (see AmmDescriptor) + -- allowed in the sequence. + ... + } + + AmmDescriptor ::= CHOICE + { + mediaDescriptor [0] IMPLICIT MediaDescriptor, + modemDescriptor [1] IMPLICIT ModemDescriptor, + muxDescriptor [2] IMPLICIT MuxDescriptor, + eventsDescriptor [3] IMPLICIT EventsDescriptor, + eventBufferDescriptor [4] IMPLICIT EventBufferDescriptor, + signalsDescriptor [5] IMPLICIT SignalsDescriptor, + digitMapDescriptor [6] IMPLICIT DigitMapDescriptor, + auditDescriptor [7] IMPLICIT AuditDescriptor, + ... + } + + + AmmsReply ::= SEQUENCE + { + terminationID [0] IMPLICIT TerminationIDList, + terminationAudit [1] IMPLICIT TerminationAudit OPTIONAL, + ... + } + + SubtractRequest ::= SEQUENCE + { + terminationID [0] IMPLICIT TerminationIDList, + auditDescriptor [1] IMPLICIT AuditDescriptor OPTIONAL, + ... + } + + AuditRequest ::= SEQUENCE + { + terminationID [0] IMPLICIT TerminationID, + auditDescriptor [1] IMPLICIT AuditDescriptor, + ... + } + + AuditReply ::= CHOICE + { + contextAuditResult [0] IMPLICIT TerminationIDList, + error [1] IMPLICIT ErrorDescriptor, + auditResult [2] IMPLICIT AuditResult, + ... + } + + AuditResult ::= SEQUENCE + { + + terminationID [0] IMPLICIT TerminationID, + terminationAuditResult [1] IMPLICIT TerminationAudit + } + + + + TerminationAudit ::= SEQUENCE OF AuditReturnParameter + + AuditReturnParameter ::= CHOICE + { + errorDescriptor [0] IMPLICIT ErrorDescriptor, + mediaDescriptor [1] IMPLICIT MediaDescriptor, + modemDescriptor [2] IMPLICIT ModemDescriptor, + muxDescriptor [3] IMPLICIT MuxDescriptor, + eventsDescriptor [4] IMPLICIT EventsDescriptor, + eventBufferDescriptor [5] IMPLICIT EventBufferDescriptor, + signalsDescriptor [6] IMPLICIT SignalsDescriptor, + digitMapDescriptor [7] IMPLICIT DigitMapDescriptor, + observedEventsDescriptor [8] IMPLICIT ObservedEventsDescriptor, + statisticsDescriptor [9] IMPLICIT StatisticsDescriptor, + packagesDescriptor [10] IMPLICIT PackagesDescriptor, + emptyDescriptors [11] IMPLICIT AuditDescriptor, + ... + } + + AuditDescriptor ::= SEQUENCE + { + auditToken [0] IMPLICIT BIT STRING + { + muxToken(0), modemToken(1), mediaToken(2), + eventsToken(3), signalsToken(4), + digitMapToken(5), statsToken(6), + observedEventsToken(7), + packagesToken(8), eventBufferToken(9) + } OPTIONAL, + ..., + auditPropertyToken [1] IMPLICIT SEQUENCE OF IndAuditParameter OPTIONAL + } + + IndAuditParameter ::= CHOICE + { + indaudmediaDescriptor [0] IMPLICIT IndAudMediaDescriptor, + indaudeventsDescriptor [1] IMPLICIT IndAudEventsDescriptor, + indaudeventBufferDescriptor [2] IMPLICIT IndAudEventBufferDescriptor, + indaudsignalsDescriptor [3] IndAudSignalsDescriptor, + indauddigitMapDescriptor [4] IMPLICIT IndAudDigitMapDescriptor, + indaudstatisticsDescriptor [5] IMPLICIT IndAudStatisticsDescriptor, + indaudpackagesDescriptor [6] IMPLICIT IndAudPackagesDescriptor, + ... + } + + IndAudMediaDescriptor ::= SEQUENCE + { + + termStateDescr [0] IMPLICIT IndAudTerminationStateDescriptor OPTIONAL, + streams [1] CHOICE + { + oneStream [0] IMPLICIT IndAudStreamParms, + multiStream [1] IMPLICIT SEQUENCE OF IndAudStreamDescriptor + } OPTIONAL, + ... + } + + IndAudStreamDescriptor ::= SEQUENCE + { + streamID [0] IMPLICIT StreamID, + streamParms [1] IMPLICIT IndAudStreamParms + } + + IndAudStreamParms ::= SEQUENCE + { + localControlDescriptor [0] IMPLICIT IndAudLocalControlDescriptor OPTIONAL, + localDescriptor [1] IMPLICIT IndAudLocalRemoteDescriptor OPTIONAL, + remoteDescriptor [2] IMPLICIT IndAudLocalRemoteDescriptor OPTIONAL, + ... + } + + IndAudLocalControlDescriptor ::= SEQUENCE + { + streamMode [0] IMPLICIT NULL OPTIONAL, + reserveValue [1] IMPLICIT NULL OPTIONAL, + reserveGroup [2] IMPLICIT NULL OPTIONAL, + propertyParms [3] IMPLICIT IndAudPropertyParms OPTIONAL, + ... + } + + IndAudPropertyParm ::= SEQUENCE + { + name [0] IMPLICIT PkgdName, + ... + } + + IndAudPropertyParms ::= SEQUENCE OF IndAudPropertyParm + + IndAudLocalRemoteDescriptor ::= SEQUENCE + { + propGroupID [0] IMPLICIT INTEGER(0..65535) OPTIONAL, + propGrps [1] IMPLICIT IndAudPropertyGroup, + ... + } + + IndAudPropertyGroup ::= SEQUENCE OF IndAudPropertyParm + + IndAudTerminationStateDescriptor ::= SEQUENCE + { + propertyParms [0] IMPLICIT IndAudPropertyParms, + eventBufferControl [1] IMPLICIT NULL OPTIONAL, + serviceState [2] IMPLICIT NULL OPTIONAL, + ... + } + + IndAudEventsDescriptor ::= SEQUENCE + { + requestID [0] IMPLICIT RequestID OPTIONAL, + pkgdName [1] IMPLICIT PkgdName, + streamID [2] IMPLICIT StreamID OPTIONAL, + ... + } + + IndAudEventBufferDescriptor ::= SEQUENCE + { + eventName [0] IMPLICIT PkgdName, + streamID [1] IMPLICIT StreamID OPTIONAL, + ... + } + + IndAudSignalsDescriptor ::=CHOICE + { + signal [0] IMPLICIT IndAudSignal, + seqSigList [1] IMPLICIT IndAudSeqSigList, + ... + } + + IndAudSeqSigList ::= SEQUENCE + { + id [0] IMPLICIT INTEGER(0..65535), + signalList [1] IMPLICIT IndAudSignal OPTIONAL + } + + IndAudSignal ::= SEQUENCE + { + signalName [0] IMPLICIT PkgdName, + streamID [1] IMPLICIT StreamID OPTIONAL, + ... + } + + IndAudDigitMapDescriptor ::= SEQUENCE + { + digitMapName [0] IMPLICIT DigitMapName OPTIONAL + } + + IndAudStatisticsDescriptor ::= SEQUENCE + { + statName [0] IMPLICIT PkgdName + } + + IndAudPackagesDescriptor ::= SEQUENCE + { + packageName [0] IMPLICIT Name, + packageVersion [1] IMPLICIT INTEGER(0..99), + ... + } + + NotifyRequest ::= SEQUENCE + { + terminationID [0] IMPLICIT TerminationIDList, + observedEventsDescriptor [1] IMPLICIT ObservedEventsDescriptor, + errorDescriptor [2] IMPLICIT ErrorDescriptor OPTIONAL, + ... + } + + NotifyReply ::= SEQUENCE + { + terminationID [0] IMPLICIT TerminationIDList, + errorDescriptor [1] IMPLICIT ErrorDescriptor OPTIONAL, + ... + } + + ObservedEventsDescriptor ::= SEQUENCE + { + requestId [0] IMPLICIT RequestID, + observedEventLst [1] IMPLICIT SEQUENCE OF ObservedEvent + } + + ObservedEvent ::= SEQUENCE + { + eventName [0] IMPLICIT EventName, + streamID [1] IMPLICIT StreamID OPTIONAL, + eventParList [2] IMPLICIT EventParameters, + timeNotation [3] IMPLICIT TimeNotation OPTIONAL, + ... + } + + EventName ::= OCTET STRING + + ExtraInfo ::= CHOICE + { + relation [0] IMPLICIT Relation, + range [1] IMPLICIT BOOLEAN, + sublist [2] IMPLICIT BOOLEAN + } + + EventParameter ::= SEQUENCE + { + eventParameterName [0] IMPLICIT EventParameterName, + eventParamValue [1] IMPLICIT EventParamValues, + + -- For use of extraInfo see the comment related to PropertyParm + extraInfo [2] ExtraInfo OPTIONAL, + ... + + } + + EventParameterName ::= Name + + EventParamValues ::= SEQUENCE OF EventParamValue + + EventParamValue ::= OCTET STRING + + EventParameters ::= SEQUENCE OF EventParameter + + ServiceChangeRequest ::= SEQUENCE + { + terminationID [0] IMPLICIT TerminationIDList, + serviceChangeParms [1] IMPLICIT ServiceChangeParm, + ... + } + + ServiceChangeReply ::= SEQUENCE + { + terminationID [0] IMPLICIT TerminationIDList, + serviceChangeResult [1] ServiceChangeResult, + ... + } + + -- For ServiceChangeResult, no parameters are mandatory. Hence the + -- distinction between ServiceChangeParm and ServiceChangeResParm. + + ServiceChangeResult ::= CHOICE + { + errorDescriptor [0] IMPLICIT ErrorDescriptor, + serviceChangeResParms [1] IMPLICIT ServiceChangeResParm + } + + WildcardField ::= OCTET STRING(SIZE(1)) + + TerminationID ::= SEQUENCE + { + wildcard [0] IMPLICIT SEQUENCE OF WildcardField, + id [1] IMPLICIT OCTET STRING(SIZE(1..8)), + ... + } + -- See A.1 for explanation of wildcarding mechanism. + -- Termination ID 0xFFFFFFFFFFFFFFFF indicates the ROOT Termination. + + TerminationIDList ::= SEQUENCE OF TerminationID + + + MediaDescriptor ::= SEQUENCE + { + termStateDescr [0] IMPLICIT TerminationStateDescriptor OPTIONAL, + streams [1] CHOICE + { + oneStream [0] IMPLICIT StreamParms, + multiStream [1] IMPLICIT SEQUENCE OF StreamDescriptor + } OPTIONAL, + ... + } + + StreamDescriptor ::= SEQUENCE + { + streamID [0] IMPLICIT StreamID, + streamParms [1] IMPLICIT StreamParms + } + + StreamParms ::= SEQUENCE + { + localControlDescriptor [0] IMPLICIT LocalControlDescriptor OPTIONAL, + localDescriptor [1] IMPLICIT LocalRemoteDescriptor OPTIONAL, + remoteDescriptor [2] IMPLICIT LocalRemoteDescriptor OPTIONAL, + ... + } + + LocalControlDescriptor ::= SEQUENCE + { + streamMode [0] IMPLICIT StreamMode OPTIONAL, + reserveValue [1] IMPLICIT BOOLEAN OPTIONAL, + reserveGroup [2] IMPLICIT BOOLEAN OPTIONAL, + propertyParms [3] IMPLICIT PropertyParms, + ... + } + + StreamMode ::= ENUMERATED + { + sendOnly(0), + recvOnly(1), + sendRecv(2), + inactive(3), + loopBack(4), + ... + } + + -- In PropertyParm, value is a SEQUENCE OF octet string. When sent + -- by an MGC the interpretation is as follows: + -- empty sequence means CHOOSE + -- one element sequence specifies value + -- If the sublist field is not selected, a longer sequence means + -- "choose one of the values" (i.e. value1 OR value2 OR ...) + -- If the sublist field is selected, + -- a sequence with more than one element encodes the value of a + -- list-valued property (i.e. value1 AND value2 AND ...). + -- The relation field may only be selected if the value sequence + -- has length 1. It indicates that the MG has to choose a value + -- for the property. E.g. x > 3 (using the greaterThan + -- value for relation) instructs the MG to choose any value larger + -- than 3 for property x. + -- The range field may only be selected if the value sequence + -- has length 2. It indicates that the MG has to choose a value + -- in the range between the first octet in the value sequence and + -- the trailing octet in the value sequence, including the + -- boundary values. + -- When sent by the MG, only responses to an AuditCapability request + -- may contain multiple values, a range, or a relation field. + + PropertyParm ::= SEQUENCE + { + propertyName [0] IMPLICIT PkgdName, + value [1] IMPLICIT SEQUENCE OF PropertyID, + extraInfo [2] ExtraInfo OPTIONAL, + ... + } + + PropertyParms ::= SEQUENCE OF PropertyParm + + Name ::= OCTET STRING(SIZE(2)) + + PkgdName ::= OCTET STRING(SIZE(4)) + -- represents Package Name (2 octets) plus Property, Event, + -- Signal Names or Statistics ID. (2 octets) + -- To wildcard a package use 0xFFFF for first two octets, choose + -- is not allowed. To reference native property tag specified in + -- Annex C, use 0x0000 as first two octets. + -- To wildcard a Property, Event, Signal, or Statistics ID, use + -- 0xFFFF for last two octets, choose is not allowed. + -- Wildcarding of Package Name is permitted only if Property, + -- Event, Signal, or Statistics ID are + -- also wildcarded. + PropertyID ::= OCTET STRING + + Relation ::= ENUMERATED + { + greaterThan(0), + smallerThan(1), + unequalTo(2), + ... + } + + LocalRemoteDescriptor ::= SEQUENCE + { + propGrps [0] IMPLICIT SEQUENCE OF PropertyGroup, + ... + } + + PropertyGroup ::= SEQUENCE OF PropertyParm + + TerminationStateDescriptor ::= SEQUENCE + { + propertyParms [0] IMPLICIT PropertyParms, + eventBufferControl [1] IMPLICIT EventBufferControl OPTIONAL, + serviceState [2] IMPLICIT ServiceState OPTIONAL, + ... + } + + EventBufferControl ::= ENUMERATED + { + off(0), + lockStep(1), + ... + } + + ServiceState ::= ENUMERATED + { + test(0), + outOfSvc(1), + inSvc(2), + ... + } + + MuxDescriptor ::= SEQUENCE + { + muxType [0] IMPLICIT MuxType, + termList [1] IMPLICIT SEQUENCE OF TerminationID, + nonStandardData [2] IMPLICIT NonStandardData OPTIONAL, + ... + } + + MuxType ::= ENUMERATED + { + h221(0), + h223(1), + h226(2), + v76(3), + ..., + nx64k(4) + } + + StreamID ::= INTEGER(0..65535) -- 16-bit unsigned integer + + EventsDescriptor ::= SEQUENCE + { + requestID [0] IMPLICIT RequestID OPTIONAL, + -- RequestID must be present if eventList + -- is non empty + eventList [1] IMPLICIT RequestedEvents, + ... + } + + RequestedEvent ::= SEQUENCE + { + pkgdName [0] IMPLICIT EventName, + streamID [1] IMPLICIT StreamID OPTIONAL, + eventAction [2] IMPLICIT RequestedActions OPTIONAL, + evParList [3] IMPLICIT EventParameters, + ... + } + + RequestedEvents ::= SEQUENCE OF RequestedEvent + + RequestedActions ::= SEQUENCE + { + keepActive [0] IMPLICIT BOOLEAN OPTIONAL, + eventDM [1] EventDM OPTIONAL, + secondEvent [2] IMPLICIT SecondEventsDescriptor OPTIONAL, + signalsDescriptor [3] IMPLICIT SignalsDescriptor OPTIONAL, + ... + } + + EventDM ::= CHOICE + { + digitMapName [0] IMPLICIT DigitMapName, + digitMapValue [1] IMPLICIT DigitMapValue + } + + SecondEventsDescriptor ::= SEQUENCE + { + requestID [0] IMPLICIT RequestID OPTIONAL, + eventList [1] IMPLICIT SEQUENCE OF SecondRequestedEvent, + ... + } + + SecondRequestedEvent ::= SEQUENCE + { + pkgdName [0] IMPLICIT EventName, + streamID [1] IMPLICIT StreamID OPTIONAL, + eventAction [2] IMPLICIT SecondRequestedActions OPTIONAL, + evParList [3] IMPLICIT EventParameters, + ... + } + + SecondRequestedActions ::= SEQUENCE + { + keepActive [0] IMPLICIT BOOLEAN OPTIONAL, + eventDM [1] EventDM OPTIONAL, + signalsDescriptor [2] IMPLICIT SignalsDescriptor OPTIONAL, + ... + } + + EventBufferDescriptor ::= SEQUENCE OF EventSpec + + EventSpec ::= SEQUENCE + { + eventName [0] IMPLICIT EventName, + streamID [1] IMPLICIT StreamID OPTIONAL, + eventParList [2] IMPLICIT EventParameters, + ... + } + + + SignalsDescriptor ::= SEQUENCE OF SignalRequest + + SignalRequest ::= CHOICE + { + signal [0] IMPLICIT Signal, + seqSigList [1] IMPLICIT SeqSigList, + ... + } + + SeqSigList ::= SEQUENCE + { + id [0] IMPLICIT INTEGER(0..65535), + signalList [1] IMPLICIT SEQUENCE OF Signal + } + + Signal ::= SEQUENCE + { + signalName [0] IMPLICIT SignalName, + streamID [1] IMPLICIT StreamID OPTIONAL, + sigType [2] IMPLICIT SignalType OPTIONAL, + duration [3] IMPLICIT INTEGER (0..65535) OPTIONAL, + notifyCompletion [4] IMPLICIT NotifyCompletion OPTIONAL, + keepActive [5] IMPLICIT BOOLEAN OPTIONAL, + sigParList [6] IMPLICIT SEQUENCE OF SigParameter, + ... + } + + SignalType ::= ENUMERATED + { + brief(0), + onOff(1), + timeOut(2), + ... + } + + SignalName ::= OCTET STRING + + NotifyCompletion ::= BIT STRING + { + onTimeOut(0), onInterruptByEvent(1), + onInterruptByNewSignalDescr(2), otherReason(3) + } + + SigParameter ::= SEQUENCE + { + sigParameterName [0] IMPLICIT SigParameterName, + sigParameterValue [1] IMPLICIT SigParamValues, + -- For use of extraInfo see the comment related to PropertyParm + extraInfo [2] ExtraInfo OPTIONAL, + ... + } + + SigParameterName ::= Name + + SigParamValues ::= SEQUENCE OF SigParamValue + + SigParamValue ::= OCTET STRING + + -- For an AuditCapReply with all events, the RequestID SHALL be ALL. + -- ALL is represented by 0xffffffff. + + RequestID ::= INTEGER(0..4294967295) -- 32-bit unsigned integer + + ModemDescriptor ::= SEQUENCE + { + mtl [0] IMPLICIT SEQUENCE OF ModemType, + mpl [1] IMPLICIT PropertyParms, + nonStandardData [2] IMPLICIT NonStandardData OPTIONAL + } + + ModemType ::= ENUMERATED + { + v18(0), + v22(1), + v22bis(2), + v32(3), + v32bis(4), + v34(5), + v90(6), + v91(7), + synchISDN(8), + ... + } + + DigitMapDescriptor ::= SEQUENCE + { + digitMapName [0] IMPLICIT DigitMapName OPTIONAL, + digitMapValue [1] IMPLICIT DigitMapValue OPTIONAL + } + + DigitMapName ::= Name + + DigitMapValue ::= SEQUENCE + { + startTimer [0] IMPLICIT INTEGER(0..99) OPTIONAL, + shortTimer [1] IMPLICIT INTEGER(0..99) OPTIONAL, + longTimer [2] IMPLICIT INTEGER(0..99) OPTIONAL, + digitMapBody [3] IMPLICIT IA5String, + -- Units are seconds for start, short and long timers, and + -- hundreds of milliseconds for duration timer. Thus start, + -- short, and long range from 1 to 99 seconds and duration + -- from 100 ms to 9.9 s + -- See A.3 for explanation of digit map syntax + ..., + durationTimer [4] IMPLICIT INTEGER (0..99) OPTIONAL + } + + ServiceChangeParm ::= SEQUENCE + { + serviceChangeMethod [0] IMPLICIT ServiceChangeMethod, + serviceChangeAddress [1] ServiceChangeAddress OPTIONAL, + serviceChangeVersion [2] IMPLICIT INTEGER(0..99) OPTIONAL, + serviceChangeProfile [3] IMPLICIT ServiceChangeProfile OPTIONAL, + serviceChangeReason [4] IMPLICIT Value, + -- A serviceChangeReason consists of a numeric reason code + -- and an optional text description. + -- The serviceChangeReason SHALL be a string consisting of + -- a decimal reason code, optionally followed by a single + -- space character and a textual description string. + -- This string is first BER-encoded as an IA5String. + -- The result of this BER-encoding is then encoded as + -- an ASN.1 OCTET STRING type, "double wrapping" the + -- value + -- as was done for package elements. + serviceChangeDelay [5] IMPLICIT INTEGER(0..4294967295) OPTIONAL, + -- 32-bit unsigned integer + serviceChangeMgcId [6] MId OPTIONAL, + timeStamp [7] IMPLICIT TimeNotation OPTIONAL, + nonStandardData [8] IMPLICIT NonStandardData OPTIONAL, + ..., + serviceChangeInfo [9] IMPLICIT AuditDescriptor OPTIONAL + } + + ServiceChangeAddress ::= CHOICE + { + portNumber [0] IMPLICIT INTEGER(0..65535), -- TCP/UDP port number + ip4Address [1] IMPLICIT IP4Address, + ip6Address [2] IMPLICIT IP6Address, + domainName [3] IMPLICIT DomainName, + deviceName [4] IMPLICIT PathName, + mtpAddress [5] IMPLICIT MtpAddress, + ... + } + + ServiceChangeResParm ::= SEQUENCE + { + serviceChangeMgcId [0] MId OPTIONAL, + serviceChangeAddress [1] ServiceChangeAddress OPTIONAL, + serviceChangeVersion [2] IMPLICIT INTEGER(0..99) OPTIONAL, + serviceChangeProfile [3] IMPLICIT ServiceChangeProfile OPTIONAL, + timestamp [4] IMPLICIT TimeNotation OPTIONAL, + ... + } + + ServiceChangeMethod ::= ENUMERATED + { + failover(0), + forced(1), + graceful(2), + restart(3), + disconnected(4), + handOff(5), + ... + } + + ServiceChangeProfile ::= SEQUENCE + { + profileName [0] IMPLICIT IA5String(SIZE (1..67)) + + -- 64 characters for name, 1 for "/", 2 for version to match ABNF + } + + PackagesDescriptor ::= SEQUENCE OF PackagesItem + + PackagesItem ::= SEQUENCE + { + packageName [0] IMPLICIT Name, + packageVersion [1] IMPLICIT INTEGER(0..99), + ... + } + + StatisticsDescriptor ::= SEQUENCE OF StatisticsParameter + + StatisticsParameter ::= SEQUENCE + { + statName [0] IMPLICIT PkgdName, + statValue [1] IMPLICIT Value OPTIONAL + } + + NonStandardData ::= SEQUENCE + { + nonStandardIdentifier [0] NonStandardIdentifier, + data [1] IMPLICIT OCTET STRING + } + + NonStandardIdentifier ::= CHOICE + { + object [0] IMPLICIT OBJECT IDENTIFIER, + h221NonStandard [1] IMPLICIT H221NonStandard, + experimental [2] IMPLICIT IA5String(SIZE(8)), + -- first two characters SHOULD be "X-" or "X+" + ... + } + + H221NonStandard ::= SEQUENCE + { t35CountryCode1 [0] IMPLICIT INTEGER(0..255), + t35CountryCode2 [1] IMPLICIT INTEGER(0..255), -- country, as per T.35 + t35Extension [2] IMPLICIT INTEGER(0..255), -- assigned nationally + manufacturerCode [3] IMPLICIT INTEGER(0..65535), -- assigned nationally + ... + } + + TimeNotation ::= SEQUENCE + { + date [0] IMPLICIT IA5String(SIZE(8)), -- yyyymmdd format + time [1] IMPLICIT IA5String(SIZE(8)) -- hhmmssss format + -- per ISO 8601:1988 + } + + Value ::= SEQUENCE OF OCTET STRING + + END diff --git a/epan/dissectors/asn1/h248/h248.cnf b/epan/dissectors/asn1/h248/h248.cnf new file mode 100644 index 00000000..de117b7a --- /dev/null +++ b/epan/dissectors/asn1/h248/h248.cnf @@ -0,0 +1,413 @@ +# h248.cnf +# H.248 conformation file + +#.MODULE_IMPORT + +#.EXPORTS + +#.PDU + +#.NO_EMIT +MtpAddress +PkgdName +ErrorCode +PropertyID +SignalName +SigParameterName +SigParamValue +EventName +EventParameterName +EventParamValue +ContextID +EventParamValueV1 +SigParamValueV1 + +#.TYPE_RENAME +IndAudMediaDescriptor/streams IndAudMediaDescriptorStreams +ActionRequest/contextId ContextId +ActionReply/contextId ContextId +StatisticsParameter/statName StatName +StatisticsParameter/statValue StatValue +PropertyParm/propertyName PropertyName +EventParameter/extraInfo EventPar_extraInfo +PropertyParm/extraInfo PropParm_extraInfo +ContextRequest/iepscallind Iepscallind_BOOL + +#.FIELD_RENAME +IP4Address/address iP4Address +IP6Address/address iP6Address +ContextAttrAuditRequest/emergency cAAREmergency +ContextAttrAuditRequest/priority cAARPriority +SecondRequestedEvent/eventAction secondaryEventAction +TerminationStateDescriptor/eventBufferControl tSEventBufferControl +SecondEventsDescriptor/eventList secondaryEventList +IndAudEventBufferDescriptor/eventName iAEBDEventName +TerminationID/id terminationId +IndAudStreamParms/localControlDescriptor iASPLocalControlDescriptor +IndAudStreamParms/localDescriptor iASPLocalDescriptor +LocalControlDescriptor/propertyParms lCDpropertyParms +TerminationStateDescriptor/propertyParms tSDpropertyParms +MediaDescriptor/streams/oneStream mediaDescriptorOneStream +MediaDescriptor/streams/multiStream mediaDescriptorMultiStream +MediaDescriptor/streams/multiStream/_item mediaDescriptorMultiStream_item +DomainName/name domName +IndAudEventsDescriptor/pkgdName iAEDPkgdName +IndAudLocalRemoteDescriptor/propGrps iAPropertyGroup +IndAudLocalControlDescriptor/propertyParms indAudPropertyParms +IndAudTerminationStateDescriptor/propertyParms indAudPropertyParms +IndAudLocalControlDescriptor/reserveGroup iALCDReserveGroup +IndAudLocalControlDescriptor/reserveValue iALCDReserveValue +IndAudLocalControlDescriptor/streamMode iALCDStreamMode +IndAudStreamDescriptor/streamParms indAudStreamParms +IndAudMediaDescriptor/termStateDescr indAudTerminationStateDescriptor +IndAudSignal/signalName iASignalName +IndAudSeqSigList/signalList iASignalList +IndAudSignalsDescriptor/signal indAudSignal +IndAudSignalsDescriptor/seqSigList indAudSeqSigList +IndAudTerminationStateDescriptor/serviceState iATSDServiceState +IndAudStreamParms/remoteDescriptor iASPRemoteDescriptor +PropertyParm/value propertyParamValue +IndAudMediaDescriptor/streams indAudMediaDescriptorStreams +AmmRequest/terminationID terminationIDList +AmmsReply/terminationID terminationIDList +AmmDescriptor/statisticsDescriptor aDstatisticsDescriptor +AuditReturnParameter/statisticsDescriptor aRPstatisticsDescriptor +StreamParms/statisticsDescriptor sPstatisticsDescriptor +SubtractRequest/terminationID terminationIDList +NotifyRequest/terminationID terminationIDList +NotifyReply/terminationID terminationIDList +ServiceChangeRequest/terminationID terminationIDList +ServiceChangeReply/terminationID terminationIDList +IndAudStatisticsDescriptor/statName iAStatName +EventParameter/extraInfo eventPar_extraInfo +PropertyParm/extraInfo propParm_extraInfo +ContextRequest/iepscallind iepscallind_BOOL +TransactionRequest/transactionId transactionId +SegmentReply/transactionId seg_rep_transactionId +TransactionReply/transactionId trep_transactionId +TransactionPending/transactionId tpend_transactionId +EventParameterV1/value event_param_value +SigParameterV1/value sig_param_value +AuditReplyV1/auditResult audit_result + +#.FIELD_ATTR +IP4Address/address ABBREV=iP4Address +IP6Address/address ABBREV=iP6Address +TransactionRequest/transactionId ABBREV=transactionRequest.transactionId +SegmentReply/transactionId ABBREV=segmentreply.transactionId +TransactionReply/transactionId ABBREV=transactionreply.transactionId +TransactionPending/transactionId ABBREV=transactionpending.transactionId +DomainName/name ABBREV=domainname +TerminationID/id ABBREV=terminationId +PropertyParm/value ABBREV=propertyParamValue +EventParameterV1/value ABBREV=event_param_value +SigParameterV1/value ABBREV=sig_param_value + +#.FN_HDR Message + curr_info.msg = gcp_msg(actx->pinfo,tvb_raw_offset(tvb),keep_persistent_data); +#.END + +#.FN_FTR Message + col_add_str(actx->pinfo->cinfo, COL_INFO, gcp_msg_to_str(curr_info.msg,actx->pinfo->pool,keep_persistent_data)); + + if (keep_persistent_data) + gcp_analyze_msg(h248_tree, actx->pinfo, tvb, curr_info.msg, &h248_arrel, &ei_h248_errored_command); +#.END + +#.FN_BODY Message/version VAL_PTR = &h248_version + %(DEFAULT_BODY)s +#.END + +#.FN_BODY TransactionRequest/transactionId + guint32 trx_id = 0; + offset = dissect_h248_trx_id(implicit_tag, actx->pinfo, tree, tvb, offset, &trx_id); + curr_info.trx = gcp_trx(curr_info.msg, trx_id, GCP_TRX_REQUEST, actx->pinfo, keep_persistent_data); + error_code = 0; +#.END + +#.FN_BODY TransactionPending/transactionId + guint32 trx_id = 0; + offset = dissect_h248_trx_id(implicit_tag, actx->pinfo, tree, tvb, offset, &trx_id); + curr_info.trx = gcp_trx(curr_info.msg, trx_id, GCP_TRX_PENDING, actx->pinfo, keep_persistent_data); + error_code = 0; + +#.FN_BODY TransactionReply/transactionId + guint32 trx_id = 0; + offset = dissect_h248_trx_id(implicit_tag, actx->pinfo, tree, tvb, offset, &trx_id); + curr_info.trx = gcp_trx(curr_info.msg, trx_id, GCP_TRX_REPLY, actx->pinfo, keep_persistent_data); + error_code = 0; + +#.FN_BODY SegmentReply/transactionId + guint32 trx_id = 0; + offset = dissect_h248_trx_id(implicit_tag, actx->pinfo, tree, tvb, offset, &trx_id); + curr_info.trx = gcp_trx(curr_info.msg, trx_id, GCP_TRX_ACK, actx->pinfo, keep_persistent_data); + error_code = 0; + +#.FN_BODY ActionRequest/contextId + guint32 ctx_id = 0; + offset = dissect_h248_ctx_id(implicit_tag, actx->pinfo, tree, tvb, offset, &ctx_id); + curr_info.ctx = gcp_ctx(curr_info.msg,curr_info.trx,ctx_id,actx->pinfo,keep_persistent_data); + curr_info.cmd = NULL; + curr_info.term = NULL; +#.END + + +#.FN_FTR ActionReply + if (!curr_info.cmd) { + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_REPLY,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); + } +#.END + +#.FN_HDR Command/addReq + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_ADD_REQ,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END + +#.FN_FTR Command/addReq + curr_info.cmd = NULL; +#.END + +#.FN_HDR Command/moveReq + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_MOVE_REQ,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); + +#.END + +#.FN_FTR Command/moveReq + curr_info.cmd = NULL; +#.END + +#.FN_HDR Command/modReq + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_MOD_REQ,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END +#.FN_FTR Command/modReq + curr_info.cmd = NULL; +#.END + +#.FN_HDR Command/subtractReq + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_SUB_REQ,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END +#.FN_FTR Command/subtractReq + curr_info.cmd = NULL; +#.END + +#.FN_HDR Command/auditCapRequest + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_AUDITCAP_REQ,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END +#.FN_FTR Command/auditCapRequest + curr_info.cmd = NULL; +#.END + +#.FN_HDR Command/auditValueRequest + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_AUDITVAL_REQ,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END +#.FN_FTR Command/auditValueRequest + curr_info.cmd = NULL; +#.END + +#.FN_HDR Command/notifyReq + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_NOTIFY_REQ,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END +#.FN_FTR Command/notifyReq + curr_info.cmd = NULL; +#.END + +#.FN_HDR ServiceChangeRequest + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_SVCCHG_REQ,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END +#.FN_FTR ServiceChangeRequest + curr_info.cmd = NULL; +#.END + +#.FN_HDR ContextRequest/topologyReq + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_TOPOLOGY_REQ,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END +#.FN_FTR ContextRequest/topologyReq + curr_info.cmd = NULL; +#.END + +#.FN_HDR ActionRequest/contextAttrAuditReq + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_CTX_ATTR_AUDIT_REQ,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END +#.FN_FTR ActionRequest/contextAttrAuditReq + curr_info.cmd = NULL; +#.END + +#.FN_HDR CommandReply/addReply + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_ADD_REPLY,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END + +#.FN_HDR CommandReply/moveReply + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_MOVE_REPLY,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END + +#.FN_HDR CommandReply/modReply + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_MOD_REPLY,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END + +#.FN_HDR CommandReply/subtractReply + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_SUB_REPLY,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END + +#.FN_HDR CommandReply/notifyReply + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_NOTIFY_REPLY,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END + +#.FN_HDR ServiceChangeReply + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_SVCCHG_REPLY,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END + +#.FN_HDR CommandReply/auditCapReply + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_AUDITCAP_REPLY,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END + +#.FN_BODY CommandReply/auditCapReply +/* h248v1 support */ + if(h248_version > 1) { + %(DEFAULT_BODY)s +} else { + /* call V1 of the dissector */ + offset = dissect_h248_AuditReplyV1(implicit_tag, tvb, offset, actx, tree, hf_index); +} +#.END + +#.FN_HDR CommandReply/auditValueReply + curr_info.cmd = gcp_cmd(curr_info.msg,curr_info.trx,curr_info.ctx,GCP_CMD_AUDITVAL_REPLY,offset,actx->pinfo,keep_persistent_data); + H248_TAP(); +#.END + +#.FN_BODY CommandReply/auditValueReply +/* h248v1 support */ + if(h248_version > 1) { + %(DEFAULT_BODY)s +} else { + /* call V1 of the dissector */ + offset = dissect_h248_AuditReplyV1(implicit_tag, tvb, offset, actx, tree, hf_index); +} +#.END + +#.FN_BODY AuditReplyV1 +/* h248v1 support */ + offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, + AuditReplyV1_sequence, hf_h248_auditValueReplyV1, ett_h248_AuditReplyV1); +#.END + +#.FN_BODY ErrorDescriptor/errorCode + offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index, &error_code); + expert_add_info(actx->pinfo, actx->created_item, &ei_h248_errored_command); + + if (curr_info.cmd) { + gcp_cmd_set_error(curr_info.cmd,error_code); + } else if (curr_info.trx) { + gcp_trx_set_error(curr_info.trx,error_code); + } +#.END + +#.FN_HDR TerminationID + curr_info.term = wmem_new0(actx->pinfo->pool, gcp_term_t); + wild_term = GCP_WILDCARD_NONE; +#.END + +#.FN_BODY WildcardField + tvbuff_t* new_tvb; + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &new_tvb); + tree = proto_item_add_subtree(actx->created_item,ett_wildcard); + proto_tree_add_item(tree,hf_h248_term_wild_type,new_tvb,0,1,ENC_BIG_ENDIAN); + proto_tree_add_item(tree,hf_h248_term_wild_level,new_tvb,0,1,ENC_BIG_ENDIAN); + proto_tree_add_item(tree,hf_h248_term_wild_position,new_tvb,0,1,ENC_BIG_ENDIAN); + + wild_term = tvb_get_guint8(new_tvb,0) & 0x80 ? GCP_WILDCARD_CHOOSE : GCP_WILDCARD_ALL; + /* limitation: assume only one wildcard is used */ + wild_card = tvb_get_guint8(new_tvb,0); + +#.END + +#.FN_BODY TerminationID/id + tvbuff_t* new_tvb; + h248_term_info_t term_info; + + term_info.wild_card = wild_card; + term_info.str = NULL; + + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &new_tvb); + + if (new_tvb) { + curr_info.term->len = tvb_reported_length(new_tvb); + curr_info.term->type = 0; /* unknown */ + + if (h248_term_handle) { + call_dissector_with_data(h248_term_handle, new_tvb, actx->pinfo, tree, &term_info); + wild_card = 0xFF; + } + + if (curr_info.term->len) { + curr_info.term->buffer = (guint8 *)tvb_memdup(actx->pinfo->pool,new_tvb,0,curr_info.term->len); + if(term_info.str){ + curr_info.term->str = wmem_strdup_printf(actx->pinfo->pool, "%s %s", + bytes_to_str_punct(actx->pinfo->pool,curr_info.term->buffer,curr_info.term->len, 0), + term_info.str); + }else{ + curr_info.term->str = bytes_to_str_punct(actx->pinfo->pool,curr_info.term->buffer,curr_info.term->len, 0); + } + } + + + curr_info.term = gcp_cmd_add_term(curr_info.msg, curr_info.trx, curr_info.cmd, curr_info.term, wild_term, actx->pinfo, keep_persistent_data); + + } else { + curr_info.term->len = 0; + curr_info.term->buffer = (guint8*)wmem_strdup(actx->pinfo->pool, ""); + curr_info.term->str = wmem_strdup(actx->pinfo->pool, "?"); + } +#.END + +#.FN_BODY SCreasonValueOctetStr VAL_PTR = ¶meter_tvb + tvbuff_t *parameter_tvb; + %(DEFAULT_BODY)s + + if (!parameter_tvb) + return offset; + + dissect_h248_ServiceChangeReasonStr(FALSE, parameter_tvb, 0, actx, tree, hf_h248_serviceChangeReasonStr); +#.END + +#.FN_BODY EventParameter +/* H248 v1 support */ + if (h248_version > 1) { + %(DEFAULT_BODY)s +} else { + offset = dissect_h248_EventParameterV1( implicit_tag, tvb, offset, actx, tree, hf_index); +} +#.END + +#.FN_BODY SigParameter +/* H248 v1 support */ + if (h248_version > 1) { + %(DEFAULT_BODY)s +} else { + offset = dissect_h248_SigParameterV1( implicit_tag, tvb, offset, actx, tree, hf_index); +} +#.END + +#.TYPE_ATTR +IP4Address/address TYPE = FT_IPv4 DISPLAY = BASE_NONE STRINGS = NULL +IP6Address/address TYPE = FT_IPv6 DISPLAY = BASE_NONE STRINGS = NULL +ActionRequest/contextId TYPE = FT_UINT32 DISPLAY = BASE_HEX STRINGS = NULL +ActionReply/contextId TYPE = FT_UINT32 DISPLAY = BASE_HEX STRINGS = NULL +ErrorDescriptor/errorCode TYPE = FT_UINT32 DISPLAY = BASE_DEC|BASE_EXT_STRING STRINGS = &h248_reasons_ext diff --git a/epan/dissectors/asn1/h248/h248v1support.asn b/epan/dissectors/asn1/h248/h248v1support.asn new file mode 100644 index 00000000..093b3549 --- /dev/null +++ b/epan/dissectors/asn1/h248/h248v1support.asn @@ -0,0 +1,45 @@ +-- Required for support for h248v1 +-- +-- This file represents the differences between h248v1 and the h248v3, the current version +-- This file is included in the Makefile generate_dissectors and related tasks necessary +-- to generate epan/dissectors/packet-h248.[ch] + +H238V1-SUPPORT DEFINITIONS IMPLICIT TAGS ::= +BEGIN + + -- V1 version of AuditReply + AuditReplyV1 ::= SEQUENCE + { + terminationID [0] TerminationID, + auditResult [1] AuditResultV1 + } + + -- V1 Version of AuditResult + AuditResultV1 ::= CHOICE + { + contectAuditResult [0] TerminationID, + terminationAuditResult [1] TerminationAudit + } + + -- V1 + EventParameterV1 ::= SEQUENCE + { + eventParamterName [0] EventParameterName, + value [1] EventParamValueV1 + } + + -- V1 + + SigParameterV1 ::= SEQUENCE + { + sigParameterName [0] SigParameterName, + value [1] SigParamValueV1 +-- value [1] ValueV1 + + } + +-- ValueV1 ::= OCTET STRING + EventParamValueV1 ::= OCTET STRING + SigParamValueV1 ::= OCTET STRING + +END
\ No newline at end of file diff --git a/epan/dissectors/asn1/h248/h248v3.asn b/epan/dissectors/asn1/h248/h248v3.asn new file mode 100644 index 00000000..4b64834f --- /dev/null +++ b/epan/dissectors/asn1/h248/h248v3.asn @@ -0,0 +1,1101 @@ +MEDIA-GATEWAY-CONTROL {itu-t(0) recommendation(0) h(8) h248(248) modules(0) +media-gateway-control(0) version3(3)} +-- +-- Module MEDIA-GATEWAY-CONTROL (H.248.1:09/2005) +-- See also ITU-T H.248.1 v3 (2005) Amend. 1 (05/2008) +-- +--DEFINITIONS AUTOMATIC TAGS ::= +--BEGIN +-- Has been modified to pass through the ASN2ETH compiler +-- (we dont support automatic tags yet so the tags had to be added by +-- hand) +DEFINITIONS IMPLICIT TAGS ::= +BEGIN + MegacoMessage ::= SEQUENCE + { + authHeader [0] AuthenticationHeader OPTIONAL, + mess [1] Message + } + + AuthenticationHeader ::= SEQUENCE + { + secParmIndex [0] SecurityParmIndex, + seqNum [1] SequenceNum, + ad [2] AuthData + } + + SecurityParmIndex ::= OCTET STRING(SIZE(4)) + + SequenceNum ::= OCTET STRING(SIZE(4)) + + AuthData ::= OCTET STRING (SIZE (12..32)) + + Message ::= SEQUENCE + { + version [0] INTEGER(0..99), + -- The version of the protocol defined here is equal to 3. + mId [1] MId, -- Name/address of message originator + messageBody [2] CHOICE + { + messageError [0] ErrorDescriptor, + transactions [1] SEQUENCE OF Transaction + }, + ... + } + + MId ::= CHOICE + { + ip4Address [0] IP4Address, + ip6Address [1] IP6Address, + domainName [2] DomainName, + deviceName [3] PathName, + mtpAddress [4] MtpAddress, + -- Addressing structure of mtpAddress: + -- 25 - 15 0 + -- | PC | NI | + -- 24 - 14 bits 2 bits + -- NOTE - 14 bits are defined for international use. + -- Two national options exist where the point code is 16 or 24 bits. + -- To octet align the mtpAddress, the MSBs shall be encoded as 0s. + ... + } +-- Wireshark specific + MtpAddress ::= OCTET STRING(SIZE(2..4)) + + DomainName ::= SEQUENCE + { + name [0] IA5String, + -- The name starts with an alphanumeric digit followed by a sequence + -- of alphanumeric digits, hyphens and dots. No two dots shall occur + -- consecutively. + + portNumber [1] INTEGER(0..65535) OPTIONAL + } + + IP4Address ::= SEQUENCE + { + address [0] OCTET STRING (SIZE(4)), + portNumber [1] INTEGER(0..65535) OPTIONAL + } + + IP6Address ::= SEQUENCE + { + address [0] OCTET STRING (SIZE(16)), + portNumber [1] INTEGER(0..65535) OPTIONAL + } + + PathName ::= IA5String(SIZE (1..64)) + -- See A.3 + + Transaction ::= CHOICE + { + transactionRequest [0] TransactionRequest, + transactionPending [1] TransactionPending, + transactionReply [2] TransactionReply, + transactionResponseAck [3] TransactionResponseAck, + -- use of response acks is dependent on underlying transport + ..., + segmentReply [4] SegmentReply + } + + TransactionId ::= INTEGER(0..4294967295) -- 32-bit unsigned integer + + TransactionRequest ::= SEQUENCE + { + transactionId [0] TransactionId, + actions [1] SEQUENCE OF ActionRequest, + ... + } + + TransactionPending ::= SEQUENCE + { + transactionId [0] TransactionId, + ... + } + + TransactionReply ::= SEQUENCE + { + transactionId [0] TransactionId, + immAckRequired [1] NULL OPTIONAL, + transactionResult [2] CHOICE + { + transactionError [0]ErrorDescriptor, + actionReplies [1] SEQUENCE OF ActionReply + }, + ..., + segmentNumber [3] SegmentNumber OPTIONAL, + segmentationComplete [4] NULL OPTIONAL + } + + SegmentReply ::= SEQUENCE + { + transactionId [0] TransactionId, + segmentNumber [1] SegmentNumber, + segmentationComplete [2] NULL OPTIONAL, + ... + } + + SegmentNumber ::= INTEGER(0..65535) + + TransactionResponseAck ::= SEQUENCE OF TransactionAck + + TransactionAck ::= SEQUENCE + { + firstAck [0] TransactionId, + lastAck [1] TransactionId OPTIONAL + } + + ErrorDescriptor ::= SEQUENCE + { + errorCode [0] ErrorCode, + errorText [1] ErrorText OPTIONAL + } + + ErrorCode ::= INTEGER(0..65535) + -- See clause 14 for IANA considerations with respect to error codes + + ErrorText ::= IA5String + + ContextID ::= INTEGER(0..4294967295) + -- Context NULL Value: 0 + -- Context CHOOSE Value: 4294967294 (0xFFFFFFFE) + -- Context ALL Value: 4294967295 (0xFFFFFFFF) + + ActionRequest ::= SEQUENCE + { + contextId [0] ContextID, + contextRequest [1] ContextRequest OPTIONAL, + contextAttrAuditReq [2] ContextAttrAuditRequest OPTIONAL, + commandRequests [3] SEQUENCE OF CommandRequest + } + + ActionReply ::= SEQUENCE + { + contextId [0] ContextID, + errorDescriptor [1] ErrorDescriptor OPTIONAL, + contextReply [2] ContextRequest OPTIONAL, + commandReply [3] SEQUENCE OF CommandReply + } + + -- Wireshark Specific + ContextIDinList ::= INTEGER(0..4294967295) + + ContextRequest ::= SEQUENCE + { + priority [0] INTEGER(0..15) OPTIONAL, + emergency [1] BOOLEAN OPTIONAL, + topologyReq [2] SEQUENCE OF TopologyRequest OPTIONAL, + ..., + iepscallind [3] BOOLEAN OPTIONAL, + contextProp [4] SEQUENCE OF PropertyParm OPTIONAL, + + -- Wireshark Specific + -- contextList [5] SEQUENCE OF ContextID OPTIONAL + contextList [5] SEQUENCE OF ContextIDinList OPTIONAL + -- Currently the way that WS tracing code's persistent data is + -- organized disallows to relate a request to multiple contexts + } + +-- When returning a contextList, the contextId in the ActionReply construct will +-- return the contextId from the associated ActionRequest. + + ContextAttrAuditRequest ::= SEQUENCE + { + topology [0] NULL OPTIONAL, + emergency [1] NULL OPTIONAL, + priority [2] NULL OPTIONAL, + ..., + iepscallind [3] NULL OPTIONAL, + contextPropAud [4] SEQUENCE OF IndAudPropertyParm OPTIONAL, + selectpriority [5] INTEGER(0..15) OPTIONAL, + -- to select given priority + selectemergency [6] BOOLEAN OPTIONAL, + -- to select if emergency set/not set (T/F) + selectiepscallind [7] BOOLEAN OPTIONAL, + -- to select if IEPS set/not set (T/F) + selectLogic [8] SelectLogic OPTIONAL -- default is AND + } + + SelectLogic ::= CHOICE + { + andAUDITSelect [0] NULL, -- all filter conditions satisfied + orAUDITSelect [1] NULL, -- at least one filter condition satisfied + ... + } + + CommandRequest ::= SEQUENCE + { + command [0] Command, + optional [1] NULL OPTIONAL, + wildcardReturn [2] NULL OPTIONAL, + ... + } + + Command ::= CHOICE + { + addReq [0] AmmRequest, + moveReq [1] AmmRequest, + modReq [2] AmmRequest, + -- Add, Move, Modify requests have the same parameters + subtractReq [3] SubtractRequest, + auditCapRequest [4] AuditRequest, + auditValueRequest [5] AuditRequest, + notifyReq [6] NotifyRequest, + serviceChangeReq [7] ServiceChangeRequest, + ... + } + + CommandReply ::= CHOICE + { + addReply [0] AmmsReply, + moveReply [1] AmmsReply, + modReply [2] AmmsReply, + subtractReply [3] AmmsReply, + -- Add, Move, Modify, Subtract replies have the same parameters + auditCapReply [4] AuditReply, + auditValueReply [5] AuditReply, + notifyReply [6] NotifyReply, + serviceChangeReply [7] ServiceChangeReply, + ... + } + + TopologyRequest ::= SEQUENCE + { + terminationFrom [0] TerminationID, + terminationTo [1] TerminationID, + topologyDirection [2] ENUMERATED + { + bothway(0), + isolate(1), + oneway(2) + }, + ..., + streamID [3]StreamID OPTIONAL, + topologyDirectionExtension [4] ENUMERATED + { + onewayexternal(0), + onewayboth(1), + ... + } OPTIONAL + } + + AmmRequest ::= SEQUENCE + { + terminationID [0] TerminationIDList, + descriptors [1] SEQUENCE OF AmmDescriptor, + -- At most one descriptor of each type (see AmmDescriptor) + -- allowed in the sequence. + ... + } + + AmmDescriptor ::= CHOICE + { + mediaDescriptor [0] MediaDescriptor, + modemDescriptor [1] ModemDescriptor, + muxDescriptor [2] MuxDescriptor, + eventsDescriptor [3] EventsDescriptor, + eventBufferDescriptor [4] EventBufferDescriptor, + signalsDescriptor [5] SignalsDescriptor, + digitMapDescriptor [6] DigitMapDescriptor, + auditDescriptor [7] AuditDescriptor, + ..., + statisticsDescriptor [8] StatisticsDescriptor + } + + AmmsReply ::= SEQUENCE + { + terminationID [0] TerminationIDList, + terminationAudit [1]TerminationAudit OPTIONAL, + ... + } + + SubtractRequest ::= SEQUENCE + { + terminationID [0] TerminationIDList, + auditDescriptor [1] AuditDescriptor OPTIONAL, + ... + } + + AuditRequest ::= SEQUENCE + { + terminationID [0] TerminationID, + auditDescriptor [1] AuditDescriptor, + ..., + terminationIDList [3] TerminationIDList OPTIONAL + } + -- terminationID shall contain the first termination in the + -- list when using the terminationIDList construct in AuditRequest + + AuditReply ::= CHOICE + { + contextAuditResult [0] TerminationIDList, + error [1] ErrorDescriptor, + auditResult [2] AuditResult, + ..., + auditResultTermList [3] TermListAuditResult + } + + AuditResult ::= SEQUENCE + { + terminationID [0] TerminationID, + terminationAuditResult [1] TerminationAudit + } + + TermListAuditResult ::= SEQUENCE + { + terminationIDList [0] TerminationIDList, + terminationAuditResult [1] TerminationAudit, + ... + } + + TerminationAudit ::= SEQUENCE OF AuditReturnParameter + + AuditReturnParameter ::= CHOICE + { + errorDescriptor [0] ErrorDescriptor, + mediaDescriptor [1] MediaDescriptor, + modemDescriptor [2] ModemDescriptor, + muxDescriptor [3] MuxDescriptor, + eventsDescriptor [4] EventsDescriptor, + eventBufferDescriptor [5] EventBufferDescriptor, + signalsDescriptor [6] SignalsDescriptor, + digitMapDescriptor [7] DigitMapDescriptor, + observedEventsDescriptor [8] ObservedEventsDescriptor, + statisticsDescriptor [9] StatisticsDescriptor, + packagesDescriptor [10] PackagesDescriptor, + emptyDescriptors [11] AuditDescriptor, + ... + } + + AuditDescriptor ::= SEQUENCE + { + auditToken [0] BIT STRING + { + muxToken(0), + modemToken(1), + mediaToken(2), + eventsToken(3), + signalsToken(4), + digitMapToken(5), + statsToken(6), + observedEventsToken(7), + packagesToken(8), + eventBufferToken(9) + } OPTIONAL, + ..., + auditPropertyToken [1] SEQUENCE OF IndAuditParameter OPTIONAL + } + + IndAuditParameter ::= CHOICE + { + indaudmediaDescriptor [0] IndAudMediaDescriptor, + indaudeventsDescriptor [1] IndAudEventsDescriptor, + indaudeventBufferDescriptor [2] IndAudEventBufferDescriptor, + indaudsignalsDescriptor [3] IndAudSignalsDescriptor, + indauddigitMapDescriptor [4] IndAudDigitMapDescriptor, + indaudstatisticsDescriptor [5] IndAudStatisticsDescriptor, + indaudpackagesDescriptor [6] IndAudPackagesDescriptor, + ... + } + + IndAudMediaDescriptor ::= SEQUENCE + { + termStateDescr [0] IndAudTerminationStateDescriptor OPTIONAL, + streams [1] CHOICE + { + oneStream [0] IndAudStreamParms, + multiStream [1] SEQUENCE OF IndAudStreamDescriptor + } OPTIONAL, + ... + } + + IndAudStreamDescriptor ::= SEQUENCE + { + streamID [0] StreamID, + streamParms [1] IndAudStreamParms + } + + IndAudStreamParms ::= SEQUENCE + { + localControlDescriptor [0] IndAudLocalControlDescriptor OPTIONAL, + localDescriptor [1] IndAudLocalRemoteDescriptor OPTIONAL, + remoteDescriptor [2] IndAudLocalRemoteDescriptor OPTIONAL, + ..., + statisticsDescriptor [3] IndAudStatisticsDescriptor OPTIONAL + } + + IndAudLocalControlDescriptor ::= SEQUENCE + { + streamMode [0] NULL OPTIONAL, + reserveValue [1] NULL OPTIONAL, + reserveGroup [2] NULL OPTIONAL, + propertyParms [3] SEQUENCE OF IndAudPropertyParm OPTIONAL, + ..., + streamModeSel [4] StreamMode OPTIONAL + } + -- must not have both streamMode and streamModeSel + -- if both are present only streamModeSel shall be honoured + + IndAudPropertyParm ::= SEQUENCE + { + name [0] PkgdName, + ..., + propertyParms [1] PropertyParm OPTIONAL + } + -- to select based on property values + -- AND/OR selection logic is specified at context level + + IndAudLocalRemoteDescriptor ::= SEQUENCE + { + propGroupID [0] INTEGER(0..65535) OPTIONAL, + propGrps [1] IndAudPropertyGroup, + ... + } + + IndAudPropertyGroup ::= SEQUENCE OF IndAudPropertyParm + + IndAudTerminationStateDescriptor ::= SEQUENCE + { + propertyParms [0] SEQUENCE OF IndAudPropertyParm, + eventBufferControl [1] NULL OPTIONAL, + serviceState [2] NULL OPTIONAL, + ..., + serviceStateSel [3] ServiceState OPTIONAL + } + -- must not have both serviceState and serviceStateSel + -- if both are present only serviceStateSel shall be honoured + + IndAudEventsDescriptor ::= SEQUENCE + { + requestID [0] RequestID OPTIONAL, + pkgdName [1] PkgdName, + streamID [2] StreamID OPTIONAL, + ... + } + + IndAudEventBufferDescriptor ::= SEQUENCE + { + eventName [0] PkgdName, + streamID [1] StreamID OPTIONAL, + ... + } + + IndAudSignalsDescriptor ::=CHOICE + { + signal [0] IndAudSignal, + seqSigList [1] IndAudSeqSigList, + ... + } + + IndAudSeqSigList ::= SEQUENCE + { + id [0] INTEGER(0..65535), + signalList [1] IndAudSignal OPTIONAL + } + + IndAudSignal ::= SEQUENCE + { + signalName [0] PkgdName, + streamID [1] StreamID OPTIONAL, + ..., + signalRequestID [2] RequestID OPTIONAL + } + + IndAudDigitMapDescriptor ::= SEQUENCE + { + digitMapName [0] DigitMapName OPTIONAL + } + + IndAudStatisticsDescriptor ::= SEQUENCE + { + statName [0] PkgdName + } + + IndAudPackagesDescriptor ::= SEQUENCE + { + packageName [0] Name, + packageVersion [1] INTEGER(0..99), + ... + } + + NotifyRequest ::= SEQUENCE + { + terminationID [0] TerminationIDList, + observedEventsDescriptor [1] ObservedEventsDescriptor, + errorDescriptor [2] ErrorDescriptor OPTIONAL, + ... + } + + NotifyReply ::= SEQUENCE + { + terminationID [0] TerminationIDList, + errorDescriptor [1] ErrorDescriptor OPTIONAL, + ... + } + + ObservedEventsDescriptor ::= SEQUENCE + { + requestId [0] RequestID, + observedEventLst [1] SEQUENCE OF ObservedEvent + } + + ObservedEvent ::= SEQUENCE + { + eventName [0] EventName, + streamID [1] StreamID OPTIONAL, + eventParList [2] SEQUENCE OF EventParameter, + timeNotation [3] TimeNotation OPTIONAL, + ... + } + +-- EventName ::= PkgdName + EventName ::= OCTET STRING + + EventParameter ::= SEQUENCE + { +-- Wireshark specific +-- eventParameterName [0] Name, +-- value [1] Value, + eventParameterName [0] EventParameterName, + eventParamValue [1] EventParamValues, +-- end + -- For use of extraInfos see the comment related to PropertyParm + extraInfo [2] CHOICE + { + relation [0] Relation, + range [1] BOOLEAN, + sublist [2] BOOLEAN + } OPTIONAL, + ... + } +-- Wireshark specific + EventParameterName ::= Name + + EventParamValues ::= SEQUENCE OF EventParamValue + + EventParamValue ::= OCTET STRING +-- end + ServiceChangeRequest ::= SEQUENCE + { + terminationID [0] TerminationIDList, + serviceChangeParms [1] ServiceChangeParm, + ... + } + + ServiceChangeReply ::= SEQUENCE + { + terminationID [0] TerminationIDList, + serviceChangeResult [1] ServiceChangeResult, + ... + } + -- For ServiceChangeResult, no parameters are mandatory. Hence the + -- distinction between ServiceChangeParm and ServiceChangeResParm. + + ServiceChangeResult ::= CHOICE + { + errorDescriptor [0] ErrorDescriptor, + serviceChangeResParms [1] ServiceChangeResParm + } + + WildcardField ::= OCTET STRING(SIZE(1)) + + TerminationID ::= SEQUENCE + { + wildcard [0] SEQUENCE OF WildcardField, + id [1] OCTET STRING(SIZE(1..8)), + ... + } + -- See A.1 for explanation of wildcarding mechanism. + -- TerminationID 0xFFFFFFFFFFFFFFFF indicates the Root Termination. + + TerminationIDList ::= SEQUENCE OF TerminationID + + MediaDescriptor ::= SEQUENCE + { + termStateDescr [0] TerminationStateDescriptor OPTIONAL, + streams [1] CHOICE + { + oneStream [0] StreamParms, + multiStream [1] SEQUENCE OF StreamDescriptor + } OPTIONAL, + ... + } + + StreamDescriptor ::= SEQUENCE + { + streamID [0] StreamID, + streamParms [1] StreamParms + } + + StreamParms ::= SEQUENCE + { + localControlDescriptor [0] LocalControlDescriptor OPTIONAL, + localDescriptor [1] LocalRemoteDescriptor OPTIONAL, + remoteDescriptor [2] LocalRemoteDescriptor OPTIONAL, + ..., + statisticsDescriptor [3] StatisticsDescriptor OPTIONAL + } + + LocalControlDescriptor ::= SEQUENCE + { + streamMode [0] StreamMode OPTIONAL, + reserveValue [1] BOOLEAN OPTIONAL, + reserveGroup [2] BOOLEAN OPTIONAL, + propertyParms [3] SEQUENCE OF PropertyParm, + ... + } + + StreamMode ::= ENUMERATED + { + sendOnly(0), + recvOnly(1), + sendRecv(2), + inactive(3), + loopBack(4), + ... + } +-- In PropertyParm, value is a SEQUENCE OF octet string. When sent +-- by an MGC the interpretation is as follows: +-- empty sequence means CHOOSE +-- one element sequence specifies value +-- If the sublist field is not selected, a longer sequence means +-- "choose one of the values" (i.e., value1 OR value2 OR ...) +-- If the sublist field is selected, +-- a sequence with more than one element encodes the value of a +-- list-valued property (i.e., value1 AND value2 AND ...). +-- The relation field may only be selected if the value sequence +-- has length 1. It indicates that the MG has to choose a value +-- for the property. E.g., x > 3 (using the greaterThan +-- value for relation) instructs the MG to choose any value larger +-- than 3 for property x. +-- The range field may only be selected if the value sequence +-- has length 2. It indicates that the MG has to choose a value +-- in the range between the first octet in the value sequence and +-- the trailing octet in the value sequence, including the +-- boundary values. +-- When sent by the MG, only responses to an AuditCapability request +-- may contain multiple values, a range, or a relation field. + PropertyParm ::= SEQUENCE + { +-- name [0] PkgdName, + propertyName [0] PkgdName, +-- value [1] SEQUENCE OF OCTET STRING, + value [1] SEQUENCE OF PropertyID, + extraInfo [2] CHOICE + { + relation [0] Relation, + range [1] BOOLEAN, + sublist [2] BOOLEAN + } OPTIONAL, + ... + } + + Name ::= OCTET STRING(SIZE(2)) + + PkgdName ::= OCTET STRING(SIZE(4)) + -- represents Package Name (2 octets) plus property, event, + -- signal names or StatisticsID. (2 octets) + -- To wildcard a package use 0xFFFF for first two octets, CHOOSE + -- is not allowed. To reference native property tag specified in + -- Annex C, use 0x0000 as first two octets. + -- To wildcard a PropertyID, EventID, SignalID, or StatisticsID, use + -- 0xFFFF for last two octets, CHOOSE is not allowed. + -- Wildcarding of Package Name is permitted only if PropertyID, + -- EventID, SignalID, or StatisticsID are also wildcarded. +-- Wireshark specific + PropertyID ::= OCTET STRING + + Relation ::= ENUMERATED + { + greaterThan(0), + smallerThan(1), + unequalTo(2), + ... + } + + LocalRemoteDescriptor ::= SEQUENCE + { + propGrps [0] SEQUENCE OF PropertyGroup, + ... + } + + PropertyGroup ::= SEQUENCE OF PropertyParm + + TerminationStateDescriptor ::= SEQUENCE + { + propertyParms [0] SEQUENCE OF PropertyParm, + eventBufferControl [1] EventBufferControl OPTIONAL, + serviceState [2] ServiceState OPTIONAL, + ... + } + + EventBufferControl ::= ENUMERATED + { + off(0), + lockStep(1), + ... + } + + ServiceState ::= ENUMERATED + { + test(0), + outOfSvc(1), + inSvc(2), + ... + } + + MuxDescriptor ::= SEQUENCE + { + muxType [0] MuxType, + termList [1] SEQUENCE OF TerminationID, + nonStandardData [2] NonStandardData OPTIONAL, + ... + } + + MuxType ::= ENUMERATED + { + h221(0), + h223(1), + h226(2), + v76(3), + ..., + nx64k(4) + } + + StreamID ::= INTEGER(0..65535) -- 16-bit unsigned integer + + EventsDescriptor ::= SEQUENCE + { + requestID [0] RequestID OPTIONAL, + -- RequestID must be present if eventList + -- is non empty + eventList [1] SEQUENCE OF RequestedEvent, + ... + } + + RequestedEvent ::= SEQUENCE + { +-- pkgdName [0] PkgdName, + eventName [0] EventName, + streamID [1] StreamID OPTIONAL, + eventAction [2] RequestedActions OPTIONAL, + evParList [3] SEQUENCE OF EventParameter, + ... + } + + RegulatedEmbeddedDescriptor ::= SEQUENCE + { + secondEvent [0] SecondEventsDescriptor OPTIONAL, + signalsDescriptor [1] SignalsDescriptor OPTIONAL, + ... + } + + NotifyBehaviour ::= CHOICE + { + notifyImmediate [0] NULL, + notifyRegulated [1] RegulatedEmbeddedDescriptor, + neverNotify [2] NULL, + ... + } + + RequestedActions ::= SEQUENCE + { + keepActive [0] BOOLEAN OPTIONAL, + eventDM [1] EventDM OPTIONAL, + secondEvent [2] SecondEventsDescriptor OPTIONAL, + signalsDescriptor [3] SignalsDescriptor OPTIONAL, + ..., + notifyBehaviour [4] NotifyBehaviour OPTIONAL, + resetEventsDescriptor [5] NULL OPTIONAL + } + + EventDM ::= CHOICE + { + digitMapName [0] DigitMapName, + digitMapValue [1] DigitMapValue + } + + SecondEventsDescriptor ::= SEQUENCE + { + requestID [0] RequestID OPTIONAL, + eventList [1] SEQUENCE OF SecondRequestedEvent, + ... + } + + SecondRequestedEvent ::= SEQUENCE + { + pkgdName [0] PkgdName, + streamID [1] StreamID OPTIONAL, + eventAction [2] SecondRequestedActions OPTIONAL, + evParList [3] SEQUENCE OF EventParameter, + ... + } + + SecondRequestedActions ::= SEQUENCE + { + keepActive [0] BOOLEAN OPTIONAL, + eventDM [1] EventDM OPTIONAL, + signalsDescriptor [2] SignalsDescriptor OPTIONAL, + ..., + notifyBehaviour [3] NotifyBehaviour OPTIONAL, + resetEventsDescriptor [4] NULL OPTIONAL + } + + EventBufferDescriptor ::= SEQUENCE OF EventSpec + + EventSpec ::= SEQUENCE + { + eventName [0] EventName, + streamID [1] StreamID OPTIONAL, + eventParList [2] SEQUENCE OF EventParameter, + ... + } + + SignalsDescriptor ::= SEQUENCE OF SignalRequest + + SignalRequest ::=CHOICE + { + signal [0] Signal, + seqSigList [1] SeqSigList, + ... + } + + SeqSigList ::= SEQUENCE + { + id [0] INTEGER(0..65535), + signalList [1] SEQUENCE OF Signal + } + + Signal ::= SEQUENCE + { + signalName [0] SignalName, + streamID [1] StreamID OPTIONAL, + sigType [2] SignalType OPTIONAL, + duration [3] INTEGER (0..65535) OPTIONAL, + notifyCompletion [4] NotifyCompletion OPTIONAL, + keepActive [5] BOOLEAN OPTIONAL, + sigParList [6] SEQUENCE OF SigParameter, + ..., + direction [7] SignalDirection OPTIONAL, + requestID [8] RequestID OPTIONAL, + intersigDelay [9] INTEGER (0..65535) OPTIONAL + } + + SignalType ::= ENUMERATED + { + brief(0), + onOff(1), + timeOut(2), + ... + } + + SignalDirection ::= ENUMERATED + { + internal(0), + external(1), + both(2), + ... + } + +-- SignalName ::= PkgdName + SignalName ::= OCTET STRING + + NotifyCompletion ::= BIT STRING + { + onTimeOut(0), onInterruptByEvent(1), + onInterruptByNewSignalDescr(2), otherReason(3), onIteration(4) + } + + SigParameter ::= SEQUENCE + { +-- sigParameterName [0] Name, +-- value [1] Value, + sigParameterName [0] SigParameterName, + value [1] SigParamValues, + -- For use of extraInfo see the comment related to PropertyParm + extraInfo [2] CHOICE + { + relation [0] Relation, + range [1] BOOLEAN, + sublist [2] BOOLEAN + } OPTIONAL, + ... + } +-- Wireshark specific + SigParameterName ::= Name + + SigParamValues ::= SEQUENCE OF SigParamValue + + SigParamValue ::= OCTET STRING +-- end + -- For an AuditCapReply with all events, the RequestID shall be ALL. + -- ALL is represented by 0xffffffff. + RequestID ::= INTEGER(0..4294967295) -- 32-bit unsigned integer + + ModemDescriptor ::= SEQUENCE + { + mtl [0] SEQUENCE OF ModemType, + mpl [1] SEQUENCE OF PropertyParm, + nonStandardData [2] NonStandardData OPTIONAL + } + + ModemType ::= ENUMERATED + { + v18(0), + v22(1), + v22bis(2), + v32(3), + v32bis(4), + v34(5), + v90(6), + v91(7), + synchISDN(8), + ... + } + + DigitMapDescriptor ::= SEQUENCE + { + digitMapName [0] DigitMapName OPTIONAL, + digitMapValue [1] DigitMapValue OPTIONAL + } + + DigitMapName ::= Name + + DigitMapValue ::= SEQUENCE + { + startTimer [0] INTEGER(0..99) OPTIONAL, + shortTimer [1] INTEGER(0..99) OPTIONAL, + longTimer [2] INTEGER(0..99) OPTIONAL, + digitMapBody [3] IA5String, + -- Units are seconds for start, short and long timers, and hundreds + -- of milliseconds for duration timer. Thus start, short, and long + -- range from 1 to 99 seconds and duration from 100 ms to 9.9 s + -- See A.3 for explanation of DigitMap syntax + ..., + durationTimer [4] INTEGER (0..99) OPTIONAL + } + + ServiceChangeParm ::= SEQUENCE + { + serviceChangeMethod [0] ServiceChangeMethod, + serviceChangeAddress [1] ServiceChangeAddress OPTIONAL, + serviceChangeVersion [2] INTEGER(0..99) OPTIONAL, + serviceChangeProfile [3] ServiceChangeProfile OPTIONAL, +-- serviceChangeReason [4] Value, + serviceChangeReason [4] SCreasonValue, + -- A serviceChangeReason consists of a numeric reason code + -- and an optional text description. + -- The serviceChangeReason shall be a string consisting of + -- a decimal reason code, optionally followed by a single + -- space character and a textual description string. + -- This string is first BER-encoded as an IA5String. + -- The result of this BER-encoding is then encoded as + -- an ASN.1 OCTET STRING type, "double wrapping" the + -- value as was done for package elements. + + serviceChangeDelay [5] INTEGER(0..4294967295) OPTIONAL, + -- 32-bit unsigned integer + serviceChangeMgcId [6] MId OPTIONAL, + timeStamp [7] TimeNotation OPTIONAL, + nonStandardData [8] NonStandardData OPTIONAL, + ..., + serviceChangeInfo [9] AuditDescriptor OPTIONAL, + serviceChangeIncompleteFlag [10] NULL OPTIONAL + } + +-- Wireshark extension to decode serviceChangeReason + SCreasonValue ::= SEQUENCE OF SCreasonValueOctetStr + SCreasonValueOctetStr ::= OCTET STRING + ServiceChangeReasonStr ::= IA5String +-- end + + ServiceChangeAddress ::= CHOICE + { + portNumber [0] INTEGER(0..65535), -- TCP/UDP port number + ip4Address [1] IP4Address, + ip6Address [2] IP6Address, + domainName [3] DomainName, + deviceName [4] PathName, + mtpAddress [5] MtpAddress, + ... + } + + ServiceChangeResParm ::= SEQUENCE + { + serviceChangeMgcId [0] MId OPTIONAL, + serviceChangeAddress [1] ServiceChangeAddress OPTIONAL, + serviceChangeVersion [2] INTEGER(0..99) OPTIONAL, + serviceChangeProfile [3] ServiceChangeProfile OPTIONAL, + timestamp [4] TimeNotation OPTIONAL, + ... + } + + ServiceChangeMethod ::= ENUMERATED + { + failover(0), + forced(1), + graceful(2), + restart(3), + disconnected(4), + handOff(5), + ... + } + + ServiceChangeProfile ::= SEQUENCE + { + profileName [0] IA5String(SIZE (1..67)) + -- 64 characters for name, 1 for "/", 2 for version to match ABNF + } + + PackagesDescriptor ::= SEQUENCE OF PackagesItem + + PackagesItem ::= SEQUENCE + { + packageName [0] Name, + packageVersion [1] INTEGER(0..99), + ... + } + + StatisticsDescriptor ::= SEQUENCE OF StatisticsParameter + + StatisticsParameter ::= SEQUENCE + { + statName [0] PkgdName, + statValue [1] Value OPTIONAL + } + -- If statistic consists of a sub-lists there will be more than + -- one octetstring in statValue. + NonStandardData ::= SEQUENCE + { + nonStandardIdentifier [0] NonStandardIdentifier, + data [1] OCTET STRING + } + + NonStandardIdentifier ::= CHOICE + { + object [0] OBJECT IDENTIFIER, + h221NonStandard [1] H221NonStandard, + experimental [2] IA5String(SIZE(8)), + -- first two characters should be "X-" or "X+" + ... + } + + H221NonStandard ::= SEQUENCE + { + t35CountryCode1 [0] INTEGER(0..255), + t35CountryCode2 [1] INTEGER(0..255), -- country, as per T.35 + t35Extension [2] INTEGER(0..255), -- assigned nationally + manufacturerCode [3] INTEGER(0..65535), -- assigned nationally + ... + } + + TimeNotation ::= SEQUENCE + { + date [0] IA5String(SIZE(8)), -- yyyymmdd format + time [1] IA5String(SIZE(8)) -- hhmmssss format + -- per ISO 8601:2004 + } + + Value ::= SEQUENCE OF OCTET STRING + +END diff --git a/epan/dissectors/asn1/h248/packet-h248-template.c b/epan/dissectors/asn1/h248/packet-h248-template.c new file mode 100644 index 00000000..f4397124 --- /dev/null +++ b/epan/dissectors/asn1/h248/packet-h248-template.c @@ -0,0 +1,2397 @@ +/* packet-h248.c + * Routines for H.248/MEGACO packet dissection + * + * Ronnie Sahlberg 2004 + * + * Luis Ontanon 2005 - Context and Transaction Tracing + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#include <epan/packet.h> +#include <epan/exceptions.h> +#include <epan/tap.h> +#include <epan/asn1.h> +#include <epan/proto_data.h> +#include <epan/prefs.h> +#include <epan/exported_pdu.h> +#include <epan/address_types.h> +#include "packet-alcap.h" +#include "packet-ber.h" +#include "packet-tpkt.h" +#include "packet-mtp3.h" +#include "packet-h248.h" + +#define PNAME "H.248 MEGACO" +#define PSNAME "H.248" +#define PFNAME "h248" + +void proto_register_h248(void); + +/* Initialize the protocol and registered fields */ +static int proto_h248 = -1; +static int hf_248_magic_num = -1; +static int hf_h248_mtpaddress_ni = -1; +static int hf_h248_mtpaddress_pc = -1; +static int hf_h248_pkg_name = -1; +static int hf_248_pkg_param = -1; +static int hf_h248_event_name = -1; +static int hf_h248_signal_name = -1; +static int hf_h248_signal_code = -1; +static int hf_h248_event_code = -1; +static int hf_h248_pkg_bcp_BNCChar_PDU = -1; + + + +static int hf_h248_context_id = -1; +static int hf_h248_term_wild_type = -1; +static int hf_h248_term_wild_level = -1; +static int hf_h248_term_wild_position = -1; + +static int hf_h248_no_pkg = -1; +static int hf_h248_no_sig = -1; +static int hf_h248_no_evt = -1; +static int hf_h248_param = -1; + +static int hf_h248_serviceChangeReasonStr = -1; +static int hf_h248_transactionId64 = -1; +static int hf_h248_context_id64 = -1; + +/* h248v1 support */ +static int hf_h248_auditValueReplyV1 = -1; + +#include "packet-h248-hf.c" + +/* Initialize the subtree pointers */ +static gint ett_h248 = -1; +static gint ett_mtpaddress = -1; +static gint ett_packagename = -1; +static gint ett_codec = -1; +static gint ett_wildcard = -1; + +static gint ett_h248_no_pkg = -1; +static gint ett_h248_no_sig = -1; +static gint ett_h248_no_evt = -1; + +static int h248_tap = -1; + +static gcp_hf_ett_t h248_arrel = {{-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1}}; + +static gint exported_pdu_tap = -1; + + +#include "packet-h248-ett.c" + +static expert_field ei_h248_errored_command = EI_INIT; +static expert_field ei_h248_transactionId64 = EI_INIT; +static expert_field ei_h248_context_id64 = EI_INIT; +static expert_field ei_h248_octet_string_expected = EI_INIT; + +static dissector_table_t subdissector_table; + +static int ss7pc_address_type = -1; + +/* Gateway Control Protocol -- Context Tracking */ + +const value_string gcp_cmd_type[] = { + { GCP_CMD_NONE, "NoCommand"}, + { GCP_CMD_ADD_REQ, "addReq"}, + { GCP_CMD_MOVE_REQ, "moveReq"}, + { GCP_CMD_MOD_REQ, "modReq"}, + { GCP_CMD_SUB_REQ, "subtractReq"}, + { GCP_CMD_AUDITCAP_REQ, "auditCapRequest"}, + { GCP_CMD_AUDITVAL_REQ, "auditValueRequest"}, + { GCP_CMD_NOTIFY_REQ, "notifyReq"}, + { GCP_CMD_SVCCHG_REQ, "serviceChangeReq"}, + { GCP_CMD_TOPOLOGY_REQ, "topologyReq"}, + { GCP_CMD_CTX_ATTR_AUDIT_REQ, "ctxAttrAuditReq"}, + { GCP_CMD_ADD_REPLY, "addReply"}, + { GCP_CMD_MOVE_REPLY, "moveReply"}, + { GCP_CMD_MOD_REPLY, "modReply"}, + { GCP_CMD_SUB_REPLY, "subtractReply"}, + { GCP_CMD_AUDITCAP_REPLY, "auditCapReply"}, + { GCP_CMD_AUDITVAL_REPLY, "auditValReply"}, + { GCP_CMD_NOTIFY_REPLY, "notifyReply"}, + { GCP_CMD_SVCCHG_REPLY, "serviceChangeReply"}, + { GCP_CMD_TOPOLOGY_REPLY, "topologyReply"}, + { 0, NULL } +}; + +const value_string gcp_term_types[] = { + { GCP_TERM_TYPE_AAL1, "aal1" }, + { GCP_TERM_TYPE_AAL2, "aal2" }, + { GCP_TERM_TYPE_AAL1_STRUCT, "aal1struct" }, + { GCP_TERM_TYPE_IP_RTP, "ipRtp" }, + { GCP_TERM_TYPE_TDM, "tdm" }, + { 0, NULL } +}; + +static wmem_tree_t* gcp_msgs = NULL; +static wmem_tree_t* gcp_trxs = NULL; +static wmem_tree_t* gcp_ctxs_by_trx = NULL; +static wmem_tree_t* gcp_ctxs = NULL; + +gcp_msg_t* gcp_msg(packet_info* pinfo, int o, gboolean keep_persistent_data) { + gcp_msg_t* m; + guint32 framenum = (guint32)pinfo->num; + guint32 offset = (guint32)o; + address* src = &(pinfo->src); + address* dst = &(pinfo->dst); + address* lo_addr; + address* hi_addr; + + if (keep_persistent_data) { + wmem_tree_key_t key[3]; + + key[0].length = 1; + key[0].key = &(framenum); + key[1].length = 1; + key[1].key = &offset; + key[2].length = 0; + key[2].key =NULL; + + if (( m = (gcp_msg_t *)wmem_tree_lookup32_array(gcp_msgs,key) )) { + m->committed = TRUE; + return m; + } else { + m = wmem_new(wmem_file_scope(), gcp_msg_t); + m->framenum = framenum; + m->frametime = pinfo->abs_ts; + m->trxs = NULL; + m->committed = FALSE; + + wmem_tree_insert32_array(gcp_msgs,key,m); + } + } else { + m = wmem_new0(pinfo->pool, gcp_msg_t); + m->framenum = framenum; + m->trxs = NULL; + m->committed = FALSE; + } + + if (cmp_address(src, dst) < 0) { + lo_addr = src; + hi_addr = dst; + } else { + lo_addr = dst; + hi_addr = src; + } + + switch(lo_addr->type) { + case AT_NONE: + m->lo_addr = 0; + m->hi_addr = 0; + break; + case AT_IPv4: + memcpy((guint8*)&(m->hi_addr),hi_addr->data,4); + memcpy((guint8*)&(m->lo_addr),lo_addr->data,4); + break; + default: + if (lo_addr->type == ss7pc_address_type) { + m->hi_addr = mtp3_pc_hash((const mtp3_addr_pc_t *)hi_addr->data); + m->lo_addr = mtp3_pc_hash((const mtp3_addr_pc_t *)lo_addr->data); + } + else { + /* XXX: heuristic and error prone */ + m->hi_addr = g_str_hash(address_to_str(pinfo->pool, hi_addr)); + m->lo_addr = g_str_hash(address_to_str(pinfo->pool, lo_addr)); + } + break; + } + + return m; +} + +gcp_trx_t* gcp_trx(gcp_msg_t* m ,guint32 t_id , gcp_trx_type_t type, packet_info *pinfo, gboolean keep_persistent_data) { + gcp_trx_t* t = NULL; + gcp_trx_msg_t* trxmsg; + + if ( !m ) return NULL; + + if (keep_persistent_data) { + if (m->committed) { + + for ( trxmsg = m->trxs; trxmsg; trxmsg = trxmsg->next) { + if (trxmsg->trx && trxmsg->trx->id == t_id) { + return trxmsg->trx; + } + } + DISSECTOR_ASSERT_NOT_REACHED(); + } else { + wmem_tree_key_t key[4]; + + key[0].length = 1; + key[0].key = &(m->hi_addr); + key[1].length = 1; + key[1].key = &(m->lo_addr); + key[2].length = 1; + key[2].key = &(t_id); + key[3].length = 0; + key[3].key = NULL; + + trxmsg = wmem_new(wmem_file_scope(), gcp_trx_msg_t); + t = (gcp_trx_t *)wmem_tree_lookup32_array(gcp_trxs,key); + + if (!t) { + t = wmem_new(wmem_file_scope(), gcp_trx_t); + t->initial = m; + t->id = t_id; + t->type = type; + t->pendings = 0; + t->error = 0; + t->cmds = NULL; + + wmem_tree_insert32_array(gcp_trxs,key,t); + } + + /* XXX: request, reply and ack + point to frames where they are */ + switch ( type ) { + case GCP_TRX_PENDING: + t->pendings++; + break; + default: + break; + } + + } + } else { + t = wmem_new(pinfo->pool, gcp_trx_t); + trxmsg = wmem_new(pinfo->pool, gcp_trx_msg_t); + t->initial = NULL; + t->id = t_id; + t->type = type; + t->pendings = 0; + t->error = 0; + t->cmds = NULL; + } + + DISSECTOR_ASSERT(trxmsg); + + trxmsg->trx = t; + trxmsg->next = NULL; + trxmsg->last = trxmsg; + + if (m->trxs) { + m->trxs->last = m->trxs->last->next = trxmsg; + } else { + m->trxs = trxmsg; + } + + return t; +} + + +gcp_ctx_t* gcp_ctx(gcp_msg_t* m, gcp_trx_t* t, guint32 c_id, packet_info *pinfo, gboolean persistent) { + gcp_ctx_t* context = NULL; + gcp_ctx_t** context_p = NULL; + + if ( !m || !t ) return NULL; + + if (persistent) { + + wmem_tree_key_t ctx_key[4]; + wmem_tree_key_t trx_key[4]; + + ctx_key[0].length = 1; + ctx_key[0].key = &(m->hi_addr); + ctx_key[1].length = 1; + ctx_key[1].key = &(m->lo_addr); + ctx_key[2].length = 1; + ctx_key[2].key = &(c_id); + ctx_key[3].length = 0; + ctx_key[3].key = NULL; + + trx_key[0].length = 1; + trx_key[0].key = &(m->hi_addr); + trx_key[1].length = 1; + trx_key[1].key = &(m->lo_addr); + trx_key[2].length = 1; + trx_key[2].key = &(t->id); + trx_key[3].length = 0; + trx_key[3].key = NULL; + + if (m->committed) { + if (( context = (gcp_ctx_t *)wmem_tree_lookup32_array(gcp_ctxs_by_trx,trx_key) )) { + return context; + } if ((context_p = (gcp_ctx_t **)wmem_tree_lookup32_array(gcp_ctxs,ctx_key))) { + context = *context_p; + + do { + if (context->initial->framenum <= m->framenum) { + return context; + } + } while(( context = context->prev )); + + DISSECTOR_ASSERT(! "a context should exist"); + } + } else { + if (c_id == CHOOSE_CONTEXT) { + if (! ( context = (gcp_ctx_t *)wmem_tree_lookup32_array(gcp_ctxs_by_trx,trx_key))) { + context = wmem_new(wmem_file_scope(), gcp_ctx_t); + context->initial = m; + context->cmds = NULL; + context->id = c_id; + context->terms.last = &(context->terms); + context->terms.next = NULL; + context->terms.term = NULL; + + wmem_tree_insert32_array(gcp_ctxs_by_trx,trx_key,context); + } + } else { + if (( context = (gcp_ctx_t *)wmem_tree_lookup32_array(gcp_ctxs_by_trx,trx_key) )) { + if (( context_p = (gcp_ctx_t **)wmem_tree_lookup32_array(gcp_ctxs,ctx_key) )) { + if (context != *context_p) { + if(context->id != CHOOSE_CONTEXT) { + context = wmem_new(wmem_file_scope(), gcp_ctx_t); + } + context->initial = m; + context->id = c_id; + context->cmds = NULL; + context->terms.last = &(context->terms); + context->terms.next = NULL; + context->terms.term = NULL; + + context->prev = *context_p; + *context_p = context; + } + } else { + context_p = wmem_new(wmem_file_scope(), gcp_ctx_t*); + *context_p = context; + context->initial = m; + context->id = c_id; + wmem_tree_insert32_array(gcp_ctxs,ctx_key,context_p); + } + } else if (! ( context_p = (gcp_ctx_t**)wmem_tree_lookup32_array(gcp_ctxs,ctx_key) )) { + context = wmem_new(wmem_file_scope(), gcp_ctx_t); + context->initial = m; + context->id = c_id; + context->cmds = NULL; + context->terms.last = &(context->terms); + context->terms.next = NULL; + context->terms.term = NULL; + + context_p = wmem_new(wmem_file_scope(), gcp_ctx_t*); + *context_p = context; + wmem_tree_insert32_array(gcp_ctxs,ctx_key,context_p); + } else { + context = *context_p; + } + } + } + } else { + context = wmem_new(pinfo->pool, gcp_ctx_t); + context->initial = m; + context->cmds = NULL; + context->id = c_id; + context->terms.last = &(context->terms); + context->terms.next = NULL; + context->terms.term = NULL; + } + + return context; +} + +gcp_cmd_t* gcp_cmd(gcp_msg_t* m, gcp_trx_t* t, gcp_ctx_t* c, gcp_cmd_type_t type, guint offset, packet_info *pinfo, gboolean persistent) { + gcp_cmd_t* cmd; + gcp_cmd_msg_t* cmdtrx; + gcp_cmd_msg_t* cmdctx; + + if ( !m || !t || !c ) return NULL; + + if (persistent) { + if (m->committed) { + DISSECTOR_ASSERT(t->cmds != NULL); + + for (cmdctx = t->cmds; cmdctx; cmdctx = cmdctx->next) { + cmd = cmdctx->cmd; + if (cmd->msg == m && cmd->offset == offset) { + return cmd; + } + } + + DISSECTOR_ASSERT(!"called for a command that does not exist!"); + + return NULL; + } else { + cmd = wmem_new(wmem_file_scope(), gcp_cmd_t); + cmdtrx = wmem_new(wmem_file_scope(), gcp_cmd_msg_t); + cmdctx = wmem_new(wmem_file_scope(), gcp_cmd_msg_t); + } + } else { + cmd = wmem_new(pinfo->pool, gcp_cmd_t); + cmdtrx = wmem_new(pinfo->pool, gcp_cmd_msg_t); + cmdctx = wmem_new(pinfo->pool, gcp_cmd_msg_t); + } + + cmd->type = type; + cmd->offset = offset; + cmd->terms.term = NULL; + cmd->terms.next = NULL; + cmd->terms.last = &(cmd->terms); + cmd->str = NULL; + cmd->msg = m; + if ((type != GCP_CMD_NONE) && (!persistent)){ + cmd->str = val_to_str_const(type, gcp_cmd_type, "Unknown"); + } + cmd->trx = t; + cmd->ctx = c; + cmd->error = 0; + + cmdctx->cmd = cmdtrx->cmd = cmd; + cmdctx->next = cmdtrx->next = NULL; + cmdctx->last = cmdtrx->last = NULL; + + if (t->cmds) { + t->cmds->last->next = cmdtrx; + t->cmds->last = cmdtrx; + } else { + t->cmds = cmdtrx; + t->cmds->last = cmdtrx; + } + + if (c->cmds) { + c->cmds->last->next = cmdctx; + c->cmds->last = cmdctx; + } else { + c->cmds = cmdctx; + c->cmds->last = cmdctx; + } + + return cmd; +} + +gcp_term_t* gcp_cmd_add_term(gcp_msg_t* m, gcp_trx_t* tr, gcp_cmd_t* c, gcp_term_t* t, gcp_wildcard_t wildcard, packet_info *pinfo, gboolean persistent) { + gcp_terms_t* ct; + gcp_terms_t* ct2; + + static gcp_term_t all_terms = {"$",(const guint8*)"",1,GCP_TERM_TYPE_UNKNOWN,NULL,NULL,NULL}; + + if ( !c ) return NULL; + + if ( wildcard == GCP_WILDCARD_CHOOSE) { + return &all_terms; + } + + if (persistent) { + if ( c->msg->committed ) { + if (wildcard == GCP_WILDCARD_ALL) { + for (ct = c->ctx->terms.next; ct; ct = ct->next) { + /* XXX not handling more wilcards in one msg */ + if ( ct->term->start == m ) { + return ct->term; + } + } + return NULL; + } else { + for (ct = c->ctx->terms.next; ct; ct = ct->next) { + if ( g_str_equal(ct->term->str,t->str) ) { + return ct->term; + } + } + return NULL; + } + } else { + + for (ct = c->ctx->terms.next; ct; ct = ct->next) { + if ( g_str_equal(ct->term->str,t->str) || ct->term->start == m) { + break; + } + } + + if ( ! ct ) { + + if (wildcard == GCP_WILDCARD_ALL) { + ct = wmem_new(wmem_file_scope(), gcp_terms_t); + ct->next = NULL; + ct->term = wmem_new0(wmem_file_scope(), gcp_term_t); + + ct->term->start = m; + ct->term->str = "*"; + ct->term->buffer = NULL; + ct->term->len = 0; + + c->terms.last = c->terms.last->next = ct; + + ct2 = wmem_new0(wmem_file_scope(), gcp_terms_t); + ct2->term = ct->term; + + c->ctx->terms.last->next = ct2; + c->ctx->terms.last = ct2; + + return ct->term; + } else { + for (ct = c->ctx->terms.next; ct; ct = ct->next) { + /* XXX not handling more wilcards in one msg */ + if ( ct->term->buffer == NULL && tr->cmds->cmd->msg == ct->term->start ) { + ct->term->str = wmem_strdup(wmem_file_scope(), t->str); + ct->term->buffer = (const guint8 *)wmem_memdup(wmem_file_scope(), t->buffer,t->len); + ct->term->len = t->len; + + ct2 = wmem_new0(wmem_file_scope(), gcp_terms_t); + ct2->term = ct->term; + + c->terms.last = c->terms.last->next = ct2; + + return ct->term; + } + + if ( g_str_equal(ct->term->str,t->str) ) { + ct2 = wmem_new0(wmem_file_scope(), gcp_terms_t); + ct2->term = ct->term; + + c->terms.last = c->terms.last->next = ct2; + + return ct->term; + } + } + + ct = wmem_new(wmem_file_scope(), gcp_terms_t); + ct->next = NULL; + ct->term = wmem_new0(wmem_file_scope(), gcp_term_t); + + ct->term->start = m; + ct->term->str = wmem_strdup(wmem_file_scope(), t->str); + ct->term->buffer = (const guint8 *)wmem_memdup(wmem_file_scope(), t->buffer,t->len); + ct->term->len = t->len; + + ct2 = wmem_new0(wmem_file_scope(), gcp_terms_t); + ct2->term = ct->term; + + c->terms.last = c->terms.last->next = ct2; + + ct2 = wmem_new0(wmem_file_scope(), gcp_terms_t); + ct2->term = ct->term; + + c->ctx->terms.last = c->ctx->terms.last->next = ct2; + + return ct->term; + } + } else { + ct2 = wmem_new0(wmem_file_scope(), gcp_terms_t); + ct2->term = ct->term; + + c->terms.last = c->terms.last->next = ct2; + return ct->term; + } + + DISSECTOR_ASSERT_NOT_REACHED(); + } + } else { + ct = wmem_new(pinfo->pool, gcp_terms_t); + ct->term = t; + ct->next = NULL; + c->terms.last = c->terms.last->next = ct; + + return t; + } + +} + +static const gchar* gcp_cmd_to_str(gcp_cmd_t* c, wmem_allocator_t *scope, gboolean persistent) { + const gchar* s; + gcp_terms_t* term; + + if ( !c ) return "-"; + + switch (c->type) { + case GCP_CMD_NONE: + return "-"; + case GCP_CMD_ADD_REQ: + s = "AddReq {"; + break; + case GCP_CMD_MOVE_REQ: + s = "MoveReq {"; + break; + case GCP_CMD_MOD_REQ: + s = "ModReq {"; + break; + case GCP_CMD_SUB_REQ: + s = "SubReq {"; + break; + case GCP_CMD_AUDITCAP_REQ: + s = "AuditCapReq {"; + break; + case GCP_CMD_AUDITVAL_REQ: + s = "AuditValReq {"; + break; + case GCP_CMD_NOTIFY_REQ: + s = "NotifyReq {"; + break; + case GCP_CMD_SVCCHG_REQ: + s = "SvcChgReq {"; + break; + case GCP_CMD_TOPOLOGY_REQ: + s = "TopologyReq {"; + break; + case GCP_CMD_CTX_ATTR_AUDIT_REQ: + s = "CtxAttribAuditReq {"; + break; + case GCP_CMD_ADD_REPLY: + s = "AddReply {"; + break; + case GCP_CMD_MOVE_REPLY: + s = "MoveReply {"; + break; + case GCP_CMD_MOD_REPLY: + s = "ModReply {"; + break; + case GCP_CMD_SUB_REPLY: + s = "SubReply {"; + break; + case GCP_CMD_AUDITCAP_REPLY: + s = "AuditCapReply {"; + break; + case GCP_CMD_AUDITVAL_REPLY: + s = "AuditValReply {"; + break; + case GCP_CMD_NOTIFY_REPLY: + s = "NotifyReply {"; + break; + case GCP_CMD_SVCCHG_REPLY: + s = "SvcChgReply {"; + break; + case GCP_CMD_TOPOLOGY_REPLY: + s = "TopologyReply {"; + break; + case GCP_CMD_REPLY: + s = "ActionReply {"; + break; + case GCP_CMD_OTHER_REQ: + s = "Request {"; + break; + default: + s = "-"; + break; + } + + for (term = c->terms.next; term; term = term->next) { + s = wmem_strdup_printf(scope, "%s %s", s, term->term->str); + } + + if (c->error) { + s = wmem_strdup_printf(scope, "%s Error=%i", s, c->error); + } + + s = wmem_strdup_printf(scope, "%s }", s); + + if (persistent) { + /* FIXME: this method has a side-effect but is buried deep within an apparently side-effect free string helper */ + if (! c->str) c->str = wmem_strdup(wmem_file_scope(), s); + } else { + c->str = s; + } + + return s; +} + +static const gchar * gcp_trx_to_str(gcp_msg_t* m, gcp_trx_t* t, wmem_allocator_t *scope, gboolean persistent) { + wmem_strbuf_t *s; + gcp_cmd_msg_t* c; + + if ( !m || !t ) return "-"; + + s = wmem_strbuf_new(scope, NULL); + wmem_strbuf_append_printf(s, "T %x { ", t->id); + + if (t->cmds) { + if (t->cmds->cmd->ctx) { + wmem_strbuf_append_printf(s, " C %x {", t->cmds->cmd->ctx->id); + + for (c = t->cmds; c; c = c->next) { + if (c->cmd->msg == m) { + wmem_strbuf_append_c(s, ' '); + wmem_strbuf_append(s, gcp_cmd_to_str(c->cmd, scope, persistent)); + } + } + + wmem_strbuf_append(s, " }"); + } + } + + if (t->error) { + wmem_strbuf_append_printf(s, " Error=%i", t->error); + } + + wmem_strbuf_append(s, " }"); + + return wmem_strbuf_finalize(s); +} + +const gchar* gcp_msg_to_str(gcp_msg_t* m, wmem_allocator_t *scope, gboolean persistent) { + gcp_trx_msg_t* t; + wmem_strbuf_t *s; + + if ( !m ) return "-"; + + s = wmem_strbuf_new(scope, NULL); + for (t = m->trxs; t; t = t->next) { + wmem_strbuf_append_c(s, ' '); + wmem_strbuf_append(s, gcp_trx_to_str(m, t->trx, scope, persistent)); + } + + return wmem_strbuf_finalize(s); +} + +typedef struct _gcp_ctxs_t { + struct _gcp_ctx_t* ctx; + struct _gcp_ctxs_t* next; +} gcp_ctxs_t; + +/*static const gchar* trx_types[] = {"None","Req","Reply","Pending","Ack"};*/ + +void gcp_analyze_msg(proto_tree* gcp_tree, packet_info* pinfo, tvbuff_t* gcp_tvb, gcp_msg_t* m, gcp_hf_ett_t* ids, expert_field* command_err) { + gcp_trx_msg_t* t; + gcp_ctxs_t contexts = {NULL,NULL}; + gcp_ctxs_t* ctx_node; + gcp_cmd_msg_t* c; + + + for (t = m->trxs; t; t = t->next) { + for (c = t->trx->cmds; c; c = c->next) { + gcp_ctx_t* ctx = c->cmd->ctx; + + for (ctx_node = contexts.next; ctx_node; ctx_node = ctx_node->next) { + if (ctx_node->ctx->id == ctx->id) { + break; + } + } + + if (! ctx_node) { + ctx_node = wmem_new(pinfo->pool, gcp_ctxs_t); + ctx_node->ctx = ctx; + ctx_node->next = contexts.next; + contexts.next = ctx_node; + } + } + } + + for (ctx_node = contexts.next; ctx_node; ctx_node = ctx_node->next) { + gcp_ctx_t* ctx = ctx_node->ctx; + proto_item* ctx_item = proto_tree_add_uint(gcp_tree,ids->hf.ctx,gcp_tvb,0,0,ctx->id); + proto_tree* ctx_tree = proto_item_add_subtree(ctx_item,ids->ett.ctx); + gcp_terms_t *ctx_term; + + proto_item_set_generated(ctx_item); + + if (ctx->cmds) { + proto_tree* history_tree = proto_tree_add_subtree(ctx_tree,gcp_tvb,0,0,ids->ett.ctx_cmds,NULL,"[ Command History ]"); + + for (c = ctx->cmds; c; c = c->next) { + proto_item* cmd_item = proto_tree_add_uint(history_tree,ids->hf.ctx_cmd,gcp_tvb,0,0,c->cmd->msg->framenum); + if (c->cmd->str) proto_item_append_text(cmd_item," %s ",c->cmd->str); + proto_item_set_generated(cmd_item); + if (c->cmd->error) { + expert_add_info(pinfo, cmd_item, command_err); + } + } + } + + if (( ctx_term = ctx->terms.next )) { + proto_tree* terms_tree = proto_tree_add_subtree(ctx_tree,gcp_tvb,0,0,ids->ett.ctx_terms,NULL,"[ Terminations Used ]"); + + for (; ctx_term; ctx_term = ctx_term->next ) { + if ( ctx_term->term && ctx_term->term->str) { + proto_item* pi = proto_tree_add_string(terms_tree,ids->hf.ctx_term,gcp_tvb,0,0,ctx_term->term->str); + proto_tree* term_tree = proto_item_add_subtree(pi,ids->ett.ctx_term); + + proto_item_set_generated(pi); + + if (ctx_term->term->type) { + pi = proto_tree_add_uint(term_tree,ids->hf.ctx_term_type,gcp_tvb,0,0,ctx_term->term->type); + proto_item_set_generated(pi); + } + + if (ctx_term->term->bir) { + pi = proto_tree_add_string(term_tree,ids->hf.ctx_term_bir,gcp_tvb,0,0,ctx_term->term->bir); + proto_item_set_generated(pi); + } + + if (ctx_term->term->nsap) { + pi = proto_tree_add_string(term_tree,ids->hf.ctx_term_nsap,gcp_tvb,0,0,ctx_term->term->nsap); + proto_item_set_generated(pi); + } + + if (ctx_term->term->bir && ctx_term->term->nsap) { + gchar* tmp_key = wmem_strdup_printf(pinfo->pool, "%s:%s",ctx_term->term->nsap,ctx_term->term->bir); + gchar* key = g_ascii_strdown(tmp_key, -1); + alcap_tree_from_bearer_key(term_tree, gcp_tvb, pinfo, key); + g_free(key); + } + } + } + } + } +} + +/* END Gateway Control Protocol -- Context Tracking */ + +#define H248_PORT 2945 +static gboolean keep_persistent_data = FALSE; +static gboolean h248_desegment = TRUE; + + + +static proto_tree *h248_tree; + +static dissector_handle_t h248_handle; +static dissector_handle_t h248_term_handle; +static dissector_handle_t h248_tpkt_handle; + +/* Forward declarations */ +static int dissect_h248_ServiceChangeReasonStr(bool implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index); + +/* h248v1 support */ +static int dissect_h248_AuditReplyV1(bool implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index); + +static int dissect_h248_EventParameterV1(bool implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index); +static int dissect_h248_SigParameterV1(bool implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index); +static int dissect_h248_SigParamValueV1(bool implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index); + +#if 0 +static const value_string context_id_type[] = { + {NULL_CONTEXT,"0 (Null Context)"}, + {CHOOSE_CONTEXT,"$ (Choose Context)"}, + {ALL_CONTEXTS,"* (All Contexts)"}, + {0,NULL} +}; +#endif + +/* the following value_strings are used to build defalut packages. + To add additional detail to a package, build a register a h248_package_t structure + */ + +static const value_string base_package_name_vals[] = { + { 0x0000, "Media stream properties H.248.1 Annex C" }, + { 0x0001, "Generic H.248.1 Annex E" }, + { 0x0002, "root H.248.1 Annex E" }, + { 0x0003, "tonegen H.248.1 Annex E" }, + { 0x0004, "tonedet H.248.1 Annex E" }, + { 0x0005, "dg H.248.1 Annex E" }, + { 0x0006, "dd H.248.1 Annex E" }, + { 0x0007, "cg H.248.1 Annex E" }, + { 0x0008, "cd H.248.1 Annex E" }, + { 0x0009, "al H.248.1 Annex E" }, + { 0x000a, "ct H.248.1 Annex E" }, + { 0x000b, "nt H.248.1 Annex E" }, + { 0x000c, "rtp H.248.1 Annex E" }, + { 0x000d, "tdmc H.248.1 Annex E" }, + { 0x000e, "ftmd H.248.1 Annex E" }, + { 0x000f, "txc H.248.2" }, /* H.248.2 */ + { 0x0010, "txp H.248.2" }, + { 0x0011, "ctyp H.248.2" }, + { 0x0012, "fax H.248.2" }, + { 0x0013, "ipfax H.248.2" }, + { 0x0014, "dis H.248.3" }, /* H.248.3 */ + { 0x0015, "key H.248.3" }, + { 0x0016, "kp H.248.3" }, + { 0x0017, "labelkey H.248.3" }, + { 0x0018, "kf H.248.3" }, + { 0x0019, "ind H.248.3" }, + { 0x001a, "ks H.248.3" }, + { 0x001b, "anci H.248.3" }, + { 0x001c, "dtd H.248.6" }, /* H.248.6 */ + { 0x001d, "an H.248.7" }, /* H.248.7 */ + { 0x001e, "Bearer Characteristics Q.1950 Annex A" }, /* Q.1950 Annex A */ + { 0x001f, "Bearer Network Connection Cut Q.1950 Annex A" }, + { 0x0020, "Reuse Idle Q.1950 Annex A" }, + { 0x0021, "Generic Bearer Connection Q.1950 Annex A" }, + { 0x0022, "Bearer Control Tunnelling Q.1950 Annex A" }, + { 0x0023, "Basic Call Progress Tones Q.1950 Annex A" }, + { 0x0024, "Expanded Call Progress Tones Q.1950 Annex A" }, + { 0x0025, "Basic Services Tones Q.1950 Annex A" }, + { 0x0026, "Expanded Services Tones Q.1950 Annex A" }, + { 0x0027, "Intrusion Tones Q.1950 Annex A" }, + { 0x0028, "Business Tones Q.1950 Annex A" }, + { 0x0029, "Media Gateway Resource Congestion Handling H.248.10" }, /* H.248.10 */ + { 0x002a, "H245 package H.248.12" }, /* H.248.12 */ + { 0x002b, "H323 bearer control package H.248.12" }, /* H.248.12 */ + { 0x002c, "H324 package H.248.12" }, /* H.248.12 */ + { 0x002d, "H245 command package H.248.12" }, /* H.248.12 */ + { 0x002e, "H245 indication package H.248.12" }, /* H.248.12 */ + { 0x002f, "3G User Plane" }, /* 3GPP TS 29.232 v4.1.0 */ + { 0x0030, "3G Circuit Switched Data" }, + { 0x0031, "3G TFO Control" }, + { 0x0032, "3G Expanded Call Progress Tones" }, + { 0x0033, "Advanced Audio Server (AAS Base)" }, /* H.248.9 */ + { 0x0034, "AAS Digit Collection" }, /* H.248.9 */ + { 0x0035, "AAS Recording" }, /* H.248.9 */ + { 0x0036, "AAS Segment Management" }, /* H.248.9 */ + { 0x0037, "Quality Alert Ceasing" }, /* H.248.13 */ + { 0x0038, "Conferencing Tones Generation" }, /* H.248.27 */ + { 0x0039, "Diagnostic Tones Generation" }, /* H.248.27 */ + { 0x003a, "Carrier Tones Generation Package H.248.23" }, /* H.248.27 */ + { 0x003b, "Enhanced Alerting Package H.248.23" }, /* H.248.23 */ + { 0x003c, "Analog Display Signalling Package H.248.23" }, /* H.248.23 */ + { 0x003d, "Multi-Frequency Tone Generation Package H.248.24" }, /* H.248.24 */ + { 0x003e, "H.248.23Multi-Frequency Tone Detection Package H.248.24" }, /* H.248.24 */ + { 0x003f, "Basic CAS Package H.248.25" }, /* H.248.25 */ + { 0x0040, "Robbed Bit Signalling Package H.248.25" }, /* H.248.25 */ + { 0x0041, "Operator Services and Emergency Services Package H.248.25" }, + { 0x0042, "Operator Services Extension Package H.248.25" }, + { 0x0043, "Extended Analog Line Supervision Package H.248.26" }, + { 0x0044, "Automatic Metering Package H.248.26" }, + { 0x0045, "Inactivity Timer Package H.248.14" }, + { 0x0046, "3G Modification of Link Characteristics Bearer Capability" }, /* 3GPP TS 29.232 v4.4.0 */ + { 0x0047, "Base Announcement Syntax H.248.9" }, + { 0x0048, "Voice Variable Syntax H.248.9" }, + { 0x0049, "Announcement Set Syntax H.248.9" }, + { 0x004a, "Phrase Variable Syntax H.248.9" }, + { 0x004b, "Basic NAS package" }, + { 0x004c, "NAS incoming package" }, + { 0x004d, "NAS outgoing package" }, + { 0x004e, "NAS control package" }, + { 0x004f, "NAS root package" }, + { 0x0050, "Profile Handling Package H.248.18" }, + { 0x0051, "Media Gateway Overload Control Package H.248.11" }, + { 0x0052, "Extended DTMF Detection Package H.248.16" }, + { 0x0053, "Quiet Termination Line Test" }, + { 0x0054, "Loopback Line Test Response" }, /* H.248.17 */ + { 0x0055, "ITU 404Hz Line Test" }, /* H.248.17 */ + { 0x0056, "ITU 816Hz Line Test" }, /* H.248.17 */ + { 0x0057, "ITU 1020Hz Line Test" }, /* H.248.17 */ + { 0x0058, "ITU 2100Hz Disable Tone Line Test" }, /* H.248.17 */ + { 0x0059, "ITU 2100Hz Disable Echo Canceller Tone Line Test" }, /* H.248.17 */ + { 0x005a, "ITU 2804Hz Tone Line Test" }, /* H.248.17 */ + { 0x005b, "ITU Noise Test Tone Line Test" }, /* H.248.17 */ + { 0x005c, "ITU Digital Pseudo Random Test Line Test" }, /* H.248.17 */ + { 0x005d, "ITU ATME No.2 Test Line Response" }, /* H.248.17 */ + { 0x005e, "ANSI 1004Hz Test Tone Line Test" }, /* H.248.17 */ + { 0x005f, "ANSI Test Responder Line Test" }, /* H.248.17 */ + { 0x0060, "ANSI 2225Hz Test Progress Tone Line Test" }, /* H.248.17 */ + { 0x0061, "ANSI Digital Test Signal Line Test" }, /* H.248.17 */ + { 0x0062, "ANSI Inverting Loopback Line Test Response" }, /* H.248.17 */ + { 0x0063, "Extended H.324 Packages H.248.12 Annex A" }, + { 0x0064, "Extended H.245 Command Package H.248.12 Annex A" }, + { 0x0065, "Extended H.245 Indication Package H.248.12 Annex A" }, + { 0x0066, "Enhanced DTMF Detection Package H.248.16" }, + { 0x0067, "Connection Group Identity Package Q.1950 Annex E" }, + { 0x0068, "CTM Text Transport 3GPP TS 29.232 v5.2.0" }, + { 0x0069, "SPNE Control Package Q.115.0" }, + { 0x006a, "Semi-permanent Connection Package H.248.21" }, + { 0x006b, "Shared Risk Group Package H.248.22" }, + { 0x006c, "isuptn Annex B of ITU-T Rec. J.171" }, + { 0x006d, "Basic CAS Addressing Package H.248.25" }, + { 0x006e, "Floor Control Package H.248.19" }, + { 0x006f, "Indication of Being Viewed Package H.248.19" }, + { 0x0070, "Volume Control Package H.248.19" }, + { 0x0071, "UNASSIGNED" }, + { 0x0072, "Volume Detection Package H.248.19" }, + { 0x0073, "Volume Level Mixing Package H.248.19" }, + { 0x0074, "Mixing Volume Level Control Package H.248.19" }, + { 0x0075, "Voice Activated Video Switch Package H.248.19" }, + { 0x0076, "Lecture Video Mode Package H.248.19" }, + { 0x0077, "Contributing Video Source Package H.248.19" }, + { 0x0078, "Video Window Package H.248.19" }, + { 0x0079, "Tiled Window Package H.248.19" }, + { 0x007a, "Adaptive Jitter Buffer Package H.248.31" }, + { 0x007b, "International CAS Package H.248.28" }, + { 0x007c, "CAS Blocking Package H.248.28" }, + { 0x007d, "International CAS Compelled Package H.248.29" }, + { 0x007e, "International CAS Compelled with Overlap Package H.248.29" }, + { 0x007f, "International CAS Compelled with End-to-end Package H.248.29" }, + { 0x0080, "RTCP XR Package H.248.30" }, + { 0x0081, "RTCP XR Burst Metrics Package H.248.30" }, + { 0x0082, "threegcsden 3G Circuit Switched Data" }, /* 3GPP TS 29.232 v5.6.0 */ + { 0x0083, "threegiptra 3G Circuit Switched Data" }, /* 3GPP TS 29.232 v5.6.0 */ + { 0x0084, "threegflex 3G Circuit Switched Data" }, /* 3GPP TS 29.232 v5.6.0 */ + { 0x0085, "H.248 PCMSB" }, + { 0x008a, "TIPHON Extended H.248/MEGACO Package" }, /* ETSI specification TS 101 3 */ + { 0x008b, "Differentiated Services Package" }, /* Annex A of ETSI TS 102 333 */ + { 0x008c, "Gate Management Package" }, /* Annex B of ETSI TS 102 333 */ + { 0x008d, "Traffic Management Package" }, /* Annex C of ETSI TS 102 333 */ + { 0x008e, "Gate Recovery Information Package" }, /* Annex D of ETSI TS 102 333 */ + { 0x008f, "NAT Traversal Package" }, /* Annex E of ETSI TS 102 333 */ + { 0x0090, "MPLS Package" }, /* Annex F of ETSI TS 102 333 */ + { 0x0091, "VLAN Package" }, /* Annex G of ETSI TS 102 333 */ + { 0x0092, "Detailed Congestion Reporting Package" }, /* H.248.32 */ + { 0x0093, "Stimulus Analogue Lines Package" }, /* H.248.34 */ + { 0x0094, "icascgen" }, /* H.248.29 Annex B */ + { 0x0095, "Coin Operated Phone Control Package" }, /* H.248.35 */ + { 0x0096, "Metering Pulse Detection Package" }, /* H.248.26 Amendment 1 */ + { 0x0097, "Trace Package" }, /* 3GPP TS 29.232 v6.3.0 */ + { 0x0098, "Hanging Termination Package" }, /* H.248.36 */ + { 0x0099, "IP NAPT Traversal Package" }, /* H.248.37 */ + { 0x009a, "Notification Behaviour Package" }, /* H.248.1v3 */ + { 0x009b, "Base Context Package" }, /* H.248.38 */ + { 0x009c, "Application Data Inactivity Detection Package" }, /* H.248.40 */ + { 0x009d, "Domain Connection Package " }, /* H.248.41 */ + { 0x009e, "Digital Circuit Multiplication Equipment Package" }, /* H.248.42 */ + { 0x009f, "Multi-level Precedence and Pre-emption Package" }, /* H.248.44 */ + { 0x00a0, "MGC Information Package" }, /* H.248.45 */ + { 0x00a1, "Text Overlay Package" }, /* H.248.19 Amendment 1 */ + { 0x00a2, "Border and Background Package" }, /* H.248.19 Amendment 1 */ + { 0x00a3, "Segmentation Package" }, /* H.248.1v3 */ + { 0x00a4, "ETSI notification behaviour package" }, /* ETSI ES 283 039-3 */ + { 0x00a5, "ETSI notification rate package" }, /* ETSI ES 283 039-4 */ + { 0x00a6, "Automatic Speech Recognition Package" }, /* H.248.9 Amendment 1 */ + { 0x00a7, "Set extension to basic syntax for TTS enhancement Package" },/* H.248.9 Amendment 1 */ + { 0x00a8, "Advanced audio server base package for TTS enhancement" }, /* H.248.9 Amendment 1 */ + { 0x00a9, "Multimedia Play Package" }, /* H.248.9 Amendment 1 */ + { 0x00aa, "Floor Status Detection Package" }, /* H.248.19 Amendment 2 */ + { 0x00ab, "Floor Control Policy Package" }, /* H.248.19 Amendment 2 */ + { 0x00ac, "Address Reporting Package" }, /* H.248.37 Amendment 1 */ + { 0x00ad, "Connection Capability Control Package" }, /* H.248.46 */ + { 0x00ae, "Statistic Conditional Reporting Package" }, /* H.248.47 Amendment 1 */ + { 0x00af, "RTCP HR QoS Statistics Package" }, /* H.248.48 */ + { 0x00b0, "Received RTCP XR Package" }, /* H.248.30 (01/2007) */ + { 0x00b1, "Received RTCP XR Burst Metrics Package" }, /* H.248.30 (01/2007) */ + { 0x00b2, "ASCI Group call package" }, /* 3GPP TS 29.232 v7.4.0 */ + { 0x00b3, "Multimedia Recording Package" }, /* H.248.9 Amendment 1 */ + { 0x00b4, "H.245 Transport Package" }, /* H.248.12 Amendment 2 */ + { 0x00b5, "RTCP Handling package" }, /* H.248.57 */ + { 0x00b6, "Gate Management - Outgoing Destination Address/Port Filtering Package" },/* H.248.43 */ + { 0x00b7, "Gate Management - Incoming Protocol Filtering Package" }, /* H.248.43 */ + { 0x00b8, "Gate Management - Outgoing Protocol Filtering Package" }, /* H.248.43 */ + { 0x00b9, "Gate Management - Incoming Filtering Behaviour Package" }, /* H.248.43 */ + { 0x00ba, "Gate Management - Outgoing Filtering Behaviour Package" }, /* H.248.43 */ + { 0x00bb, "Session Description Protocol RFC Package" }, /* H.248.49 */ + { 0x00bc, "Session Description Protocol Capabilities Package" }, /* H.248.49 */ + { 0x00bd, "NAT Traversal Toolkit - STUN Base Package" }, /* H.248.50 */ + { 0x00be, "NAT Traversal Toolkit - MG STUN Client Package" }, /* H.248.50 */ + { 0x00bf, "NAT Traversal Toolkit - MG TURN Client Package" }, /* H.248.50 */ + { 0x00c0, "NAT Traversal Toolkit - MGC STUN Client Package" }, /* H.248.50 */ + { 0x00c1, "NAT Traversal Toolkit - STUN Information Package" }, /* H.248.50 */ + { 0x00c2, "NAT Traversal Toolkit - MG Act-as STUN Server Package" }, /* H.248.50 */ + { 0x00c3, "NAT Traversal Toolkit - Originate STUN Continuity Check Package" }, /* H.248.50 */ + { 0x00c4, "NAT Traversal Toolkit - MGC Originated STUN Request Package" }, /* H.248.50 */ + { 0x00c5, "NAT Traversal Toolkit - RTP NOOP Request Package" }, /* H.248.50 */ + { 0x00c6, "Termination Connection Model Package" }, /* H.248.51 */ + { 0x00c7, "QoS Class Package" }, /* H.248.52 */ + { 0x00c8, "Traffic Policing Statistics Package" }, /* H.248.53 */ + { 0x00c9, "Packet Size Package" }, /* H.248.53 */ + { 0x00ca, "Pull Mode Package" }, /* H.248.55 */ + { 0x00cb, "RTP Application Data Package" }, /* H.248.58 */ + { 0x00cc, "Event Timestamp Notification Package" }, /* H.248.59 */ + { 0x00cd, "Resource Management Rules Package" }, /* H.248.63 */ + { 0x00ce, "Resource Management Configuration Package" }, /* H.248.63 */ + { 0x00cf, "Abstract Resource Management Packages" }, /* H.248.63 */ + { 0x00d0, "IP layer octets count statistics Package" }, /* H.248.61 */ + { 0x00d1, "Content of Communication Identity Package" }, /* H.248.60 */ + { 0x00d2, "RSVP extension package" }, /* H.248.65 */ + { 0x00d3, "GCP Transport Mode Indication Package" }, /* H.248.67 */ + { 0x00d4, "IP Router Package" }, /* H.248.64 */ + { 0x00d5, "Media Resource Identification Package" }, /* H.248.66 */ + { 0x00d6, "Range Format Support Package" }, /* H.248.66 */ + { 0x00d7, "Media Resource Description Expiry Package" }, /* H.248.66 */ + { 0x00d8, "Media Block Size Package" }, /* H.248.66 */ + { 0x00d9, "RTSP Media Resource Syntax Package" }, /* H.248.66 */ + { 0x00da, "RTSP Play Package" }, /* H.248.66 */ + { 0x00db, "Signal Pause Package" }, /* H.248.66 */ + { 0x00dc, "Data Delivery Speed Adjustme Package" }, /* H.248.66 */ + { 0x00dd, "Playback Relative Scale Adjustment Package" }, /* H.248.66 */ + { 0x00de, "RTP Information Package" }, /* H.248.66 */ + { 0x00df, "RTP Interleaving Package" }, /* H.248.66 */ + { 0x00e0, "IP Realm Availability Package" }, /* H.248.41 Amendment 1 */ + { 0x00e1, "General IP Header QoS Octet Package" }, /* H.248.52 */ + { 0x00e2, "Re-answer Package" }, /* H.248.62 */ + { 0x00e3, "3G Interface Type package" }, /* 3GPP TS 29.232 v8.4.0 */ + { 0x00e4, "Latch Statistics Package" }, /* H.248.37 */ + { 0x00e5, "Floor Control Signalling Package" }, /* H.248.19 Amendment 2 */ + { 0x00e6, "Include Participant in Mix Package" }, /* H.248.19 Amendment 2 */ + { 0x00e7, "Speaker Reporting Package" }, /* H.248.19 Amendment 2 */ + { 0x00e8, "IP Layer Packet Count Statistics Package" }, /* H.248.61 */ + { 0x00e9, "Removal of Digits and Tones Package" }, /* H.248.68 */ + { 0x00ea, "MSRP Statistics Package" }, /* H.248.69 */ + { 0x00eb, "MSRP Connection Status Package" }, /* H.248.69 */ + { 0x00ec, "Play Message Package" }, /* H.248.69 */ + { 0x00ed, "Delete Stored Message Package" }, /* H.248.69 */ + { 0x00ee, "Message Session Information Package" }, /* H.248.69 */ + { 0x00ef, "Message Filtering Package" }, /* H.248.69 */ + { 0x00f0, "Stored Message Information Package" }, /* H.248.69 */ + { 0x00f1, "Record Message Package" }, /* H.248.69 */ + { 0x00f2, "Digit Dialling Method Information Package" }, /* H.248.70 */ + { 0x00f3, "Digit Dialling Method Information for Extended Digitmap Detection Package" }, /* H.248.70 */ + { 0x00f4, "Digit Dialling Method Information for Enhanced Digitmap Detection Package" }, /* H.248.70 */ + { 0x00f5, "Received RTCP Package " }, /* H.248.71 */ + { 0x00f6, "RTP Cumulative Loss Package" }, /* H.248.71 */ + { 0x00f7, "H.245 Transport Package for SPC use" }, /* H.248.72 */ + { 0x00f8, "MONA Preference Package" }, /* H.248.72 */ + { 0x00f9, "TDM Gain Control Package" }, /* H.248.73 */ + { 0x00fa, "Media Start Package" }, /* H.248.74 */ + { 0x00fb, "Trim Package" }, /* H.248.74 */ + { 0x00fc, "Enhanced Recording Package" }, /* H.248.74 */ + { 0x00fd, "Enhanced ASR Package" }, /* H.248.74 */ + { 0x00fe, "Enhanced TTS Package" }, /* H.248.74 */ + { 0x00ff, "Play Offset Control Package" }, /* H.248.74 */ + { 0x0100, "Enhanced DTMF Detection Package" }, /* H.248.9 Revised 2009 */ + { 0x0101, "IP Router NAT Package" }, /* H.248.64 */ + { 0x0102, "Voice Enrolled Grammar Package" }, /* H.248.74 */ + { 0x0103, "Filter Group Package" }, /* H.248.76 */ + { 0x0104, "RTCP Source Description Package" }, /* H.248.71 */ + { 0x0105, "Speaker Verification and Identification Package" }, /* H.248.74 */ + { 0x0106, "Package Identifier Publishing and Application Package" }, /* H.248 */ + { 0x0107, "Secure RTP Package " }, /* H.248.77 */ + { 0x0108, "MGC Controlled Bearer Level ALG Package" }, /* H.248.78 */ + { 0x0109, "Enhanced Revised Offer/Answer SDP Support Package" }, /* H.248.80 */ + { 0x010a, "Enhanced SDP Media Capabilities Negotiation Support Package" }, /* H.248.80 */ + { 0x8000, "Ericsson IU" }, + { 0x8001, "Ericsson UMTS and GSM Circuit" }, + { 0x8002, "Ericsson Tone Generator Package" }, + { 0x8003, "Ericsson Line Test Package" }, + { 0x8004, "Nokia Advanced TFO Package" }, + { 0x8005, "Nokia IWF Package" }, + { 0x8006, "Nokia Root Package" }, + { 0x8007, "Nokia Trace Package" }, + { 0x8008, "Ericsson V5.2 Layer" }, + { 0x8009, "Ericsson Detailed Termination Information Package" }, + { 0x800a, "Nokia Bearer Characteristics Package" }, + { 0x800b, "Nokia Test Call Package" }, + { 0x800c, "Nokia Extended Continuity Package" }, + { 0x800d, "Nokia IPnwR Package" }, + { 0x800e, "Ericsson Tracing Enhancements Package" }, + { 0x800f, "Ericsson Partially Wildcarded TerminationID Package" }, + { 0x8010, "SCTP Stream Handling Package" }, + {0, NULL} +}; + +/* + * This table consist of PackageName + EventName and its corresponding string + * + */ +static const value_string base_event_name_vals[] = { + { 0x00000000, "Media stream properties H.248.1 Annex C" }, + { 0x00010000, "g H.248.1 Annex E" }, + { 0x00010001, "g/Cause" }, + { 0x00010002, "g/Signal Completion" }, + { 0x00040000, "tonedet H.248.1 Annex E" }, + { 0x00040001, "tonedet/std(Start tone detected)" }, + { 0x00040002, "tonedet/etd(End tone detected)" }, + { 0x00040003, "tonedet/ltd(Long tone detected)" }, + { 0x00060000, "dd H.248.1 Annex E" }, + { 0x00060001, "dd/std" }, + { 0x00060002, "dd/etd" }, + { 0x00060003, "dd/ltd" }, + { 0x00060004, "dd, DigitMap Completion Event" }, + { 0x00060010, "dd/d0, DTMF character 0" }, + { 0x00060011, "dd/d1, DTMF character 1" }, + { 0x00060012, "dd/d2, DTMF character 2" }, + { 0x00060013, "dd/d3, DTMF character 3" }, + { 0x00060014, "dd/d4, DTMF character 4" }, + { 0x00060015, "dd/d5, DTMF character 5" }, + { 0x00060016, "dd/d6, DTMF character 6" }, + { 0x00060017, "dd/d7, DTMF character 7" }, + { 0x00060018, "dd/d8, DTMF character 8" }, + { 0x00060019, "dd/d9, DTMF character 9" }, + { 0x0006001a, "dd/a, DTMF character A" }, + { 0x0006001b, "dd/b, DTMF character B" }, + { 0x0006001c, "dd/c, DTMF character C" }, + { 0x0006001d, "dd/d, DTMF character D" }, + { 0x00060020, "dd/" "*, DTMF character *" }, /* XXX: hack so checkAPIs & etc won't see a 'start of comment' */ + { 0x00060021, "dd/#, DTMF character #" }, + { 0x00080030, "cd, Dial Tone" }, + { 0x00080031, "cd, Ringing Tone" }, + { 0x00080032, "cd, Busy Tone" }, + { 0x00080033, "cd, Congestion Tone" }, + { 0x00080034, "cd, Special Information Tone" }, + { 0x00080035, "cd, (Recording) Warning Tone" }, + { 0x00080036, "cd, Payphone Recognition Tone" }, + { 0x00080037, "cd, Call Waiting Tone" }, + { 0x00080038, "cd, Caller Waiting Tone" }, + { 0x00090004, "al, onhook" }, + { 0x00090005, "al, offhook" }, + { 0x00090006, "al, flashhook" }, + { 0x0009ffff, "al, *" }, + { 0x000a0005, "ct, Completion of Continuity test" }, + { 0x000b0005, "nt, network failure" }, + { 0x000b0006, "nt, quality alert" }, + { 0x000c0001, "rtp, Payload Transition" }, + { 0x00210000, "Generic Bearer Connection Q.1950 Annex A" }, + { 0x00210001, "GB/BNCChange" }, + { 0x00220001, "BT/TIND (Tunnel Indication)" }, + { 0x002a0001, "H.245/h245msg (Incoming H.245 Message)" }, + { 0x002a0004, "H.245/h245ChC (H.245 Channel Closed)" }, + { 0x00450000, "Inactivity Timer H.248.14" }, + { 0x00450001, "it/ito" }, + { 0x00450002, "it/ito" }, + { 0x00460001, "threegmlc/mod_link_supp (Bearer Modification Support Event)" }, + { 0x00980000, "Hanging Termination Package" }, + { 0x00980001, "Termination Heartbeat" }, + { 0x800a0000, "Nokia Bearer Characteristics Package" }, + {0, NULL} +}; + +/* + * This table consist of PackageName + SignalName and its corresponding string + */ +static const value_string base_signal_name_vals[] = { + { 0x00000000, "Media stream properties H.248.1 Annex C" }, + { 0x00010000, "g H.248.1 Annex E" }, + { 0x00030001, "tonegen/pt(Play tone)" }, + { 0x00050010, "dg, DTMF character 0" }, + { 0x00050011, "dg, DTMF character 1" }, + { 0x00050012, "dg, DTMF character 2" }, + { 0x00050013, "dg, DTMF character 3" }, + { 0x00050014, "dg, DTMF character 4" }, + { 0x00050015, "dg, DTMF character 5" }, + { 0x00050016, "dg, DTMF character 6" }, + { 0x00050017, "dg, DTMF character 7" }, + { 0x00050018, "dg, DTMF character 8" }, + { 0x00050019, "dg, DTMF character 9" }, + { 0x0005001a, "dg, DTMF character A" }, + { 0x0005001b, "dg, DTMF character B" }, + { 0x0005001c, "dg, DTMF character C" }, + { 0x0005001d, "dg, DTMF character D" }, + { 0x00050020, "dg, DTMF character *" }, + { 0x00050021, "dg, DTMF character #" }, + { 0x00070030, "cg, Dial Tone" }, + { 0x00070031, "cg/rt (Ringing Tone)" }, + { 0x00070032, "cg, Busy Tone" }, + { 0x00070033, "cg, Congestion Tone" }, + { 0x00070034, "cg, Special Information Tone" }, + { 0x00070035, "cg, (Recording) Warning Tone" }, + { 0x00070036, "cg, Payphone Recognition Tone" }, + { 0x00070037, "cg, Call Waiting Tone" }, + { 0x00070038, "cg, Caller Waiting Tone" }, + { 0x00090002, "al, ring" }, + { 0x0009ffff, "al, *" }, + { 0x000a0003, "ct, Continuity test" }, + { 0x000a0004, "ct, Continuity respond" }, + { 0x00210000, "GB Generic Bearer Connection Q.1950 Annex A" }, + { 0x00210001, "GB/EstBNC(Establish BNC)" }, + { 0x00210002, "GB/ModBNC (Modify BNC)" }, + { 0x00210003, "GB/RelBNC(Release BNC)" }, + { 0x002a0001, "H.245/cs (channel state)" }, + { 0x002a0002, "H.245/termtype (Terminal Type)" }, + { 0x002c0001, "H.324/cmod (Communication mode)" }, + { 0x002c0002, "H.324/muxlv (Highest Multiplexing level)" }, + { 0x002c0003, "H.324/demux (Demultiplex)" }, + { 0x002c0004, "H.324/h223capr (Remote H.223 capability)" }, + { 0x002c0005, "H.324/muxtbl_in (Incoming Multiplex Table)" }, + { 0x002c0006, "H.324/muxtbl_out (Outgoing Multiplex Table)" }, + { 0x800a0000, "Nokia Bearer Characteristics Package" }, + {0, NULL} +}; + + +static const value_string h248_reasons[] = { + { 400, "Syntax error in message"}, + { 401, "Protocol Error"}, + { 402, "Unauthorized"}, + { 403, "Syntax error in transaction request"}, + { 406, "Version Not Supported"}, + { 410, "Incorrect identifier"}, + { 411, "The transaction refers to an unknown ContextId"}, + { 412, "No ContextIDs available"}, + { 413, "Number of transactions in message exceeds maximum"}, /* [H.248.8 (08/07)] */ + { 421, "Unknown action or illegal combination of actions"}, + { 422, "Syntax Error in Action"}, + { 430, "Unknown TerminationID"}, + { 431, "No TerminationID matched a wildcard"}, + { 432, "Out of TerminationIDs or No TerminationID available"}, + { 433, "TerminationID is already in a Context"}, + { 434, "Max number of Terminations in a Context exceeded"}, + { 435, "Termination ID is not in specified Context"}, + { 440, "Unsupported or unknown Package"}, + { 441, "Missing Remote or Local Descriptor"}, + { 442, "Syntax Error in Command"}, + { 443, "Unsupported or Unknown Command"}, + { 444, "Unsupported or Unknown Descriptor"}, + { 445, "Unsupported or Unknown Property"}, + { 446, "Unsupported or Unknown Parameter"}, + { 447, "Descriptor not legal in this command"}, + { 448, "Descriptor appears twice in a command"}, + { 449, "Unsupported or Unknown Parameter or Property Value"}, + { 450, "No such property in this package"}, + { 451, "No such event in this package"}, + { 452, "No such signal in this package"}, + { 453, "No such statistic in this package"}, + { 454, "No such parameter value in this package"}, + { 455, "Property illegal in this Descriptor"}, + { 456, "Property appears twice in this Descriptor"}, + { 457, "Missing parameter in signal or event"}, + { 458, "Unexpected Event/Request ID"}, + { 459, "Unsupported or Unknown Profile"}, + { 460, "Unable to set statistic on stream"}, + { 461, "Unsupported or Unknown Profile"}, /*[H.248.18] */ + + { 471, "Implied Add for Multiplex failure"}, + { 472, "Required Information Missing"}, /*[H.248.8 (08/07)] */ + { 473, "Conflicting Property Values"}, /*[H.248.8 (08/07)] */ + { 474, "Invalid SDP Syntax"}, /*[H.248.49] */ + { 475, "Unable to pause the playout of the signal"}, /*[H.248.66] */ + { 476, "Unable to adjust the data delivery speed of the Signal"}, /*[H.248.66] */ + + { 477, "Unable to adjust the playback relative scale of the signal"}, /*[H.248.66] */ + + { 478, "Behaviour Contradicts Resource Rule"}, /*[H.248.63] */ + + { 500, "Internal software Failure in MG"}, + { 501, "Not Implemented"}, + { 502, "Not ready"}, + { 503, "Service Unavailable"}, + { 504, "Command Received from unauthorized entity"}, + { 505, "Transaction Request Received before a Service Change Reply has been received"}, + { 506, "Number of Transaction Pendings Exceeded"}, + { 510, "Insufficient resources"}, + { 511, "Temporarily Busy"}, /* [H.248.8 (08/07)] */ + { 512, "Media Gateway unequipped to detect requested Event"}, + { 513, "Media Gateway unequipped to generate requested Signals"}, + { 514, "Media Gateway cannot send the specified announcement"}, + { 515, "Unsupported Media Type"}, + { 517, "Unsupported or invalid mode"}, + { 518, "Event buffer full"}, + { 519, "Out of space to store digit map"}, + { 520, "Digit Map undefined in the MG"}, + { 521, "Termination is ServiceChanging"}, + { 522, "Functionality Requested in Topology Triple Not Supported"}, + { 526, "Insufficient bandwidth"}, + { 529, "Internal hardware failure in MG"}, + { 530, "Temporary Network failure"}, + { 531, "Permanent Network failure"}, + { 532, "Audited Property, Statistic, Event or Signal does not exist"}, + { 533, "Response exceeds maximum transport PDU size"}, + { 534, "Illegal write or read only property"}, + { 540, "Unexpected initial hook state"}, + { 541, "Unexpected Spare Bit State"}, /* [H.248.33] */ + { 542, "Command is not allowed on this termination"}, + { 543, "MGC requested event detection timestamp not supported"}, /* [H.248.8 (08/07)] */ + { 581, "Does Not Exist"}, + { 600, "Illegal syntax within an announcement specification"}, + { 601, "Variable type not supported"}, + { 602, "Variable value out of range"}, + { 603, "Category not supported"}, + { 604, "Selector type not supported"}, + { 605, "Selector value not supported"}, + { 606, "Unknown segment ID"}, + { 607, "Mismatch between play specification and provisioned data"}, + { 608, "Provisioning error"}, + { 609, "Invalid offset"}, + { 610, "No free segment IDs"}, + { 611, "Temporary segment not found"}, + { 612, "Segment in use"}, + { 613, "ISP port limit overrun"}, + { 614, "No modems available"}, + { 615, "Calling number unacceptable"}, + { 616, "Called number unacceptable"}, + { 617, "Reserved for H.248.9 return code"}, /* [H.248.9] */ + { 618, "Reserved for H.248.9 return code"}, /* [H.248.9] */ + { 622, "Reserved for H.248.9 return code"}, /* [H.248.9] */ + { 623, "Reserved for H.248.9 return code"}, /* [H.248.9] */ + { 624, "Reserved for H.248.9 return code"}, /* [H.248.9] */ + { 625, "Reserved for H.248.9 return code"}, /* [H.248.9 Amendment 1] */ + { 626, "Reserved for H.248.9 return code"}, /* [H.248.9 Amendment 1] */ + { 627, "Reserved for H.248.9 return code"}, /* [H.248.9 Amendment 1] */ + { 628, "Reserved for H.248.9 return code"}, /* [H.248.9 Amendment 1] */ + { 629, "Reserved for H.248.9 return code"}, /* [H.248.9 Amendment 1] */ + { 700, "Sieve Script Syntax Error"}, /* [H.248.69] */ + { 701, "Unsupported Sieve Require Error"}, /* [H.248.69] */ + { 702, "Sieve Actions Exceeded Error"}, /* [H.248.69] */ + + { 900, "Service Restored"}, + { 901, "Cold Boot"}, + { 902, "Warm Boot"}, + { 903, "MGC Directed Change"}, + { 904, "Termination malfunctioning"}, + { 905, "Termination taken out of service"}, + { 906, "Loss of lower layer connectivity (e.g. downstream sync)"}, + { 907, "Transmission Failure"}, + { 908, "MG Impending Failure"}, + { 909, "MGC Impending Failure"}, + { 910, "Media Capability Failure"}, + { 911, "Modem Capability Failure"}, + { 912, "Mux Capability Failure"}, + { 913, "Signal Capability Failure"}, + { 914, "Event Capability Failure"}, + { 915, "State Loss"}, + { 916, "Packages Change"}, + { 917, "Capabilities Change"}, + { 918, "Cancel Graceful"}, + { 919, "Warm Failover"}, + { 920, "Cold Failover"}, + {0,NULL} +}; +static value_string_ext h248_reasons_ext = VALUE_STRING_EXT_INIT(h248_reasons); + +static const value_string wildcard_modes[] = { + { 0, "Choose" }, + { 1, "All" }, + { 0, NULL } +}; + +static const value_string wildcard_levels[] = { + { 0, "This One Level" }, + { 1, "This Level and those below" }, + { 0, NULL } +}; + +static h248_curr_info_t curr_info = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; +static guint32 error_code; +static guint32 h248_version = 0; /* h248v1 support */ +static gcp_wildcard_t wild_term; +static guint8 wild_card = 0xFF; /* place to store wildcardField */ + + /* Call the export PDU tap with relevant data */ +static void +export_h248_pdu(packet_info *pinfo, tvbuff_t *tvb) +{ + if (have_tap_listener(exported_pdu_tap)) { + exp_pdu_data_t *exp_pdu_data = export_pdu_create_common_tags(pinfo, "h248", EXP_PDU_TAG_DISSECTOR_NAME); + + exp_pdu_data->tvb_captured_length = tvb_captured_length(tvb); + exp_pdu_data->tvb_reported_length = tvb_reported_length(tvb); + exp_pdu_data->pdu_tvb = tvb; + + tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data); + } +} + +extern void h248_param_ber_integer(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, int hfid, h248_curr_info_t* u _U_, void* implicit) { + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + dissect_ber_integer(implicit ? *((bool*)implicit) : FALSE, &asn1_ctx, tree, tvb, 0, hfid, NULL); +} + +extern void h248_param_ber_octetstring(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, int hfid, h248_curr_info_t* u _U_, void* implicit) { + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + dissect_ber_octet_string(implicit ? *((bool*)implicit) : FALSE, &asn1_ctx, tree, tvb, 0, hfid, NULL); +} + +extern void h248_param_ber_boolean(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, int hfid, h248_curr_info_t* u _U_, void* implicit) { + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + dissect_ber_boolean(implicit ? *((bool*)implicit) : FALSE, &asn1_ctx, tree, tvb, 0, hfid, NULL); +} + +extern void h248_param_bytes_item(proto_tree* tree, + tvbuff_t* tvb, + packet_info* pinfo _U_, + int hfid, + h248_curr_info_t* h248_info _U_, + void* lenp ) { + int len = lenp ? *((int*)lenp) : -1; + proto_tree_add_item(tree,hfid,tvb,0,len,ENC_NA); +} + +extern void h248_param_uint_item(proto_tree* tree, + tvbuff_t* tvb, + packet_info* pinfo _U_, + int hfid, + h248_curr_info_t* h248_info _U_, + void* lenp ) { + int len = lenp ? *((int*)lenp) : -1; + proto_tree_add_item(tree,hfid,tvb,0,len,ENC_BIG_ENDIAN); +} + +extern void h248_param_external_dissector(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo , int hfid _U_, h248_curr_info_t* u _U_, void* dissector_hdl) { + call_dissector((dissector_handle_t) dissector_hdl,tvb,pinfo,tree); +} + + +static const h248_package_t no_package = { 0xffff, &hf_h248_no_pkg, &ett_h248_no_pkg, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; +static const h248_pkg_sig_t no_signal = { 0, &hf_h248_no_sig, &ett_h248_no_sig, NULL, NULL }; +static const h248_pkg_param_t no_param = { 0, &hf_h248_param, h248_param_uint_item, NULL }; +static const h248_pkg_evt_t no_event = { 0, &hf_h248_no_evt, &ett_h248_no_evt, NULL, NULL }; + +const h248_package_t *find_package_id(guint16 pkgid); +static wmem_tree_t* packages = NULL; + +extern void h248_param_PkgdName(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo , int hfid _U_, h248_curr_info_t* u1 _U_, void* u2 _U_) { + tvbuff_t *new_tvb = NULL; + proto_tree *package_tree=NULL; + guint16 name_major, name_minor; + const h248_package_t* pkg = NULL; + int offset = 0; + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + + offset = dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, offset, hfid , &new_tvb); + + if (new_tvb) { + /* this field is always 4 bytes so just read it into two integers */ + name_major=tvb_get_ntohs(new_tvb, 0); + name_minor=tvb_get_ntohs(new_tvb, 2); + pkg = find_package_id(name_major); + /* do the prettification */ + proto_item_append_text(asn1_ctx.created_item, " %s (%04x)", + val_to_str_const(0, pkg->param_names, "Unknown Package"), + name_major); + + if(tree){ + proto_item* pi; + const gchar* strval; + + package_tree = proto_item_add_subtree(asn1_ctx.created_item, ett_packagename); + proto_tree_add_uint_format(package_tree, hf_h248_pkg_name, tvb, offset-4, 2, name_major, + "%s (0x%04x)", val_to_str_const(0, pkg->param_names, "Unknown Package"), name_major); + + pi = proto_tree_add_uint(package_tree, hf_248_pkg_param, tvb, offset-2, 2, name_minor); + + if (pkg->signal_names && ( strval = try_val_to_str(name_minor, pkg->signal_names) )) { + strval = wmem_strdup_printf(pinfo->pool, "%s (%d)",strval,name_minor); + } else { + strval = wmem_strdup_printf(pinfo->pool, "Unknown (%d)",name_minor); + } + + proto_item_set_text(pi,"Signal ID: %s", strval); + } + + } +} + + +static int dissect_h248_trx_id(bool implicit_tag, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, guint32* trx_id_p) { + guint64 trx_id = 0; + gint8 ber_class; + bool pc; + gint32 tag; + guint32 len; + guint32 i; + + if(!implicit_tag){ + offset=dissect_ber_identifier(pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL); + } else { + len=tvb_reported_length_remaining(tvb, offset); + } + + + if (len > 8 || len < 1) { + THROW(BoundsError); + } else { + for(i=1;i<=len;i++){ + trx_id=(trx_id<<8)|tvb_get_guint8(tvb, offset); + offset++; + } + if (trx_id > 0xffffffff) { + proto_item* pi = proto_tree_add_uint64(tree, hf_h248_transactionId64, tvb, offset-len, len, trx_id); + expert_add_info(pinfo, pi, &ei_h248_transactionId64); + + *trx_id_p = 0; + + } else { + proto_tree_add_uint(tree, hf_h248_transactionId, tvb, offset-len, len, (guint32)trx_id); + *trx_id_p = (guint32)trx_id; + } + } + + return offset; +} + +static int dissect_h248_ctx_id(bool implicit_tag, packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, guint32* ctx_id_p) { + gint8 ber_class; + bool pc; + gint32 tag; + guint32 len; + guint64 ctx_id = 0; + guint32 i; + + if(!implicit_tag){ + offset=dissect_ber_identifier(pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL); + } else { + len=tvb_reported_length_remaining(tvb, offset); + } + + + if (len > 8 || len < 1) { + THROW(BoundsError); + } else { + for(i=1;i<=len;i++){ + ctx_id=(ctx_id<<8)|tvb_get_guint8(tvb, offset); + offset++; + } + + if (ctx_id > 0xffffffff) { + proto_item* pi = proto_tree_add_uint64(tree, hf_h248_context_id64, tvb, offset-len, len, ctx_id); + expert_add_info(pinfo, pi, &ei_h248_context_id64); + + *ctx_id_p = 0xfffffffd; + + } else { + proto_item* pi = proto_tree_add_uint(tree, hf_h248_context_id, tvb, offset-len, len, (guint32)ctx_id); + + if ( ctx_id == NULL_CONTEXT ) { + proto_item_set_text(pi,"contextId: Null Context(0)"); + } else if ( ctx_id == CHOOSE_CONTEXT ) { + proto_item_set_text(pi,"contextId: $ (Choose Context = 0xfffffffe)"); + } else if ( ctx_id == ALL_CONTEXTS ) { + proto_item_set_text(pi,"contextId: * (All Contexts = 0xffffffff)"); + } + + *ctx_id_p = (guint32) ctx_id; + } + } + + return offset; +} + +static s_h248_package_t *s_find_package_id(guint16 pkgid) { + s_h248_package_t *s_pkg = NULL; + s_pkg = (s_h248_package_t *)wmem_tree_lookup32(packages, (guint32)(pkgid)); + return s_pkg; +} + +const h248_package_t *find_package_id(guint16 pkgid) { + s_h248_package_t *s_pkg = NULL; + s_pkg = s_find_package_id(pkgid); /*(packages, GUINT_TO_POINTER((guint32)(pkgid))); */ + if (! s_pkg ) return &no_package; + return s_pkg->pkg; +} + +static gboolean is_pkg_default(guint16 pkgid) { + s_h248_package_t *s_pkg = NULL; + s_pkg = (s_h248_package_t *)wmem_tree_lookup32(packages, (guint32)(pkgid)); + if(! s_pkg ) return TRUE; + return s_pkg->is_default; +} + +void h248_register_package(h248_package_t* pkg, pkg_reg_action reg_action) { + h248_package_t *pkg_found = NULL, *pkg_high = NULL, *pkg_low = NULL; + s_h248_package_t *s_pkg = NULL; + value_string *vst; + gboolean pkg_default = FALSE; + gint j = 0, idx = 0, i = 0, k = 0; + if (! packages) { + /* no packaegs are yet registerd so create tree and add default packages to tree + */ + packages = wmem_tree_new(wmem_epan_scope()); /* init tree if no entries */ + while (base_package_name_vals[i].strptr != NULL) { + pkg_found = wmem_new0(wmem_epan_scope(), h248_package_t); /* create a h248 package structure */ + pkg_found->id = base_package_name_vals[i].value; + vst = (value_string *)wmem_alloc0(wmem_epan_scope(), sizeof(value_string)*2); + vst[0].strptr = base_package_name_vals[i].strptr; + pkg_found->param_names = vst; + pkg_found->hfid = &hf_h248_pkg_name; + pkg_found->ett = &ett_packagename; + try_val_to_str_idx((pkg_found->id)<<16,base_event_name_vals, &j); + /* now look for events and signals that may be defined for package. If found, create value_strings */ + if (j != -1) { + j++; idx=j; + while((base_event_name_vals[j].strptr!=NULL) && (((base_event_name_vals[j].value)>>16) == (pkg_found->id))) { + j++; + }; + if (idx < j) { + vst = (value_string *)wmem_alloc0(wmem_epan_scope(), sizeof(value_string)*(j-idx+1)); + for (k=0;idx<j;k++) { + vst[k].strptr = base_event_name_vals[idx].strptr; + vst[k].value = (base_event_name_vals[idx].value & 0xffff); + idx++; + }; + pkg_found->event_names = vst; + } + } + /* now look at signals */ + if (!try_val_to_str_idx((pkg_found->id)<<16, base_signal_name_vals, &j)) { + j++; idx=j; + while((base_signal_name_vals[j].strptr != NULL) && ((base_signal_name_vals[j].value>>16) == (pkg_found->id))) { + j++; + }; + if (idx < j) { + vst = (value_string *)wmem_alloc0(wmem_epan_scope(), sizeof(value_string)*(j-idx+1)); + for (k=0;idx<j;k++) { + vst[k].strptr = base_signal_name_vals[idx].strptr; + vst[k].value = (base_signal_name_vals[idx].value &0xffff); + idx++; + }; + pkg_found->signal_names = vst; + } + }; + s_pkg = wmem_new0(wmem_epan_scope(), s_h248_package_t); + s_pkg->is_default = TRUE; + s_pkg->pkg = pkg_found; + wmem_tree_insert32(packages, pkg_found->id, s_pkg); + i++; + }; + pkg_found = NULL; /* reset pointer */ + }; + pkg_default = is_pkg_default(pkg->id); + if (((reg_action==REPLACE_PKG) || (reg_action==ADD_PKG)) && pkg_default) { + /* add/replace in tree */ + s_pkg = wmem_new0(wmem_epan_scope(), s_h248_package_t); + s_pkg->is_default = FALSE; + s_pkg->pkg = (h248_package_t *)pkg; + wmem_tree_insert32(packages, pkg->id, s_pkg); + return; + }; + if(pkg_default) reg_action = MERGE_PKG_HIGH; /* always make new package overide default */ + s_pkg = s_find_package_id(pkg->id); + if (s_pkg == NULL) { /* no need to merge - package not in tree */ + s_pkg = wmem_new0(wmem_epan_scope(), s_h248_package_t); + s_pkg->is_default = FALSE; + s_pkg->pkg = (h248_package_t *)pkg; + wmem_tree_insert32(packages, pkg->id, s_pkg); + return; + } + pkg_found = s_pkg->pkg; + if (reg_action==MERGE_PKG_HIGH) { + pkg_high = (h248_package_t *)pkg; + pkg_low = pkg_found; + }; + if (reg_action==MERGE_PKG_LOW) { + pkg_high = pkg_found; + pkg_low = (h248_package_t *)pkg; + }; + if(pkg_high) { + /* if h248_package_t High Priority value !NULL, replace it in the found tree entry else use current entry */ + (pkg_high->hfid ? (pkg_found->hfid=pkg_high->hfid) : (pkg_found->hfid=pkg_low->hfid)); + (pkg_high->ett ? (pkg_found->ett=pkg_high->ett ):( pkg_found->ett=pkg_low->ett)); + (pkg_high->param_names ? (pkg_found->param_names=pkg_high->param_names ):( pkg_found->param_names=pkg_low->param_names)); + (pkg_high->signal_names ? (pkg_found->signal_names=pkg_high->signal_names ):( pkg_found->signal_names=pkg_low->signal_names)); + (pkg_high->event_names ? (pkg_found->event_names=pkg_high->event_names ):( pkg_found->event_names=pkg_low->event_names)); + (pkg_high->stats_names ? (pkg_found->stats_names=pkg_high->stats_names ):( pkg_found->stats_names=pkg_low->stats_names)); + (pkg_high->properties ? (pkg_found->properties=pkg_high->properties ):( pkg_found->properties=pkg_low->properties)); + (pkg_high->signals ? (pkg_found->signals=pkg_high->signals ):( pkg_found->signals=pkg_low->signals)); + (pkg_high->events ? (pkg_found->events=pkg_high->events ):( pkg_found->events=pkg_low->events)); + (pkg_high->statistics ? (pkg_found->statistics=pkg_high->statistics ):( pkg_found->statistics=pkg_low->statistics)); + s_pkg->pkg = pkg_found; + s_pkg->is_default = FALSE; + } +} + + +static guint32 packageandid; + +static int dissect_h248_PkgdName(bool implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) { + tvbuff_t *new_tvb = NULL; + proto_tree *package_tree=NULL; + guint16 name_major, name_minor; + const h248_package_t* pkg = NULL; + + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &new_tvb); + + if (new_tvb) { + /* this field is always 4 bytes so just read it into two integers */ + name_major=tvb_get_ntohs(new_tvb, 0); + name_minor=tvb_get_ntohs(new_tvb, 2); + packageandid=(name_major<<16)|name_minor; + + pkg = find_package_id(name_major); + /* do the prettification */ + proto_item_append_text(actx->created_item, " %s (%04x)", + val_to_str_const(0, pkg->param_names, "Unknown Package"), + name_major); + + if(tree){ + package_tree = proto_item_add_subtree(actx->created_item, ett_packagename); + proto_tree_add_uint_format(package_tree, hf_h248_pkg_name, tvb, offset-4, 2, name_major, + "PkgName: %s (0x%04x)", val_to_str_const(0, pkg->param_names, "Unknown Package"), name_major); + } + + { + proto_item* pi = proto_tree_add_uint(package_tree, hf_248_pkg_param, tvb, offset-2, 2, name_minor); + const gchar* strval; + + if (pkg->param_names && ( strval = try_val_to_str(name_minor, pkg->param_names) )) { + strval = wmem_strdup_printf(actx->pinfo->pool, "%s (%d)",strval,name_minor); + } else { + strval = wmem_strdup_printf(actx->pinfo->pool, "Unknown (%d)",name_minor); + } + + proto_item_set_text(pi,"Parameter: %s", strval); + } + } else { + pkg = &no_package; + } + + curr_info.pkg = pkg; + + return offset; +} + +static int dissect_h248_EventName(bool implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) { + tvbuff_t *new_tvb; + proto_tree *package_tree=NULL; + guint16 name_major, name_minor; + const h248_package_t* pkg = NULL; + const h248_pkg_evt_t* evt = NULL; + + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &new_tvb); + + if (new_tvb) { + /* this field is always 4 bytes so just read it into two integers */ + name_major=tvb_get_ntohs(new_tvb, 0); + name_minor=tvb_get_ntohs(new_tvb, 2); + packageandid=(name_major<<16)|name_minor; + + pkg = find_package_id(name_major); + /* do the prettification */ + proto_item_append_text(actx->created_item, " %s (%04x)", + val_to_str_const(0, pkg->param_names, "Unknown Package"), + name_major); + if(tree){ + package_tree = proto_item_add_subtree(actx->created_item, ett_packagename); + } + proto_tree_add_uint_format(package_tree, hf_h248_pkg_name, tvb, offset-4, 2, name_major, + "%s (0x%04x)", val_to_str_const(0, pkg->param_names, "Unknown Package"), name_major); + + curr_info.pkg = pkg; + + if (pkg->events) { + for (evt = pkg->events; evt->hfid; evt++) { + if (name_minor == evt->id) { + break; + } + } + + if (! evt->hfid) evt = &no_event; + } else { + evt = &no_event; + } + + curr_info.evt = evt; + + { + proto_item* pi = proto_tree_add_uint(package_tree, hf_h248_event_code, tvb, offset-2, 2, name_minor); + const gchar* strval; + + if (pkg->event_names && ( strval = try_val_to_str(name_minor, pkg->event_names) )) { + strval = wmem_strdup_printf(actx->pinfo->pool, "%s (%d)",strval,name_minor); + } else { + strval = wmem_strdup_printf(actx->pinfo->pool, "Unknown (%d)",name_minor); + } + + proto_item_set_text(pi,"Event ID: %s", strval); + } + + } else { + curr_info.pkg = &no_package; + curr_info.evt = &no_event; + } + + return offset; +} + + + +static int dissect_h248_SignalName(bool implicit_tag , tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) { + tvbuff_t *new_tvb; + proto_tree *package_tree=NULL; + guint16 name_major, name_minor; + const h248_package_t* pkg = NULL; + const h248_pkg_sig_t* sig; + + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &new_tvb); + + if (new_tvb) { + /* this field is always 4 bytes so just read it into two integers */ + name_major=tvb_get_ntohs(new_tvb, 0); + name_minor=tvb_get_ntohs(new_tvb, 2); + packageandid=(name_major<<16)|name_minor; + + pkg = find_package_id(name_major); + /* do the prettification */ + proto_item_append_text(actx->created_item, " %s (%04x)", + val_to_str_const(0, pkg->param_names, "Unknown Package"), + name_major); + if(tree){ + package_tree = proto_item_add_subtree(actx->created_item, ett_packagename); + } + proto_tree_add_uint_format(package_tree, hf_h248_pkg_name, tvb, offset-4, 2, name_major, + "%s (0x%04x)", val_to_str_const(0, pkg->param_names, "Unknown Package"), name_major); + + if (pkg->signals) { + for (sig = pkg->signals; sig->hfid; sig++) { + if (name_minor == sig->id) { + break; + } + } + + if (! sig->hfid) sig = &no_signal; + + curr_info.pkg = pkg; + curr_info.sig = sig; + } else { + curr_info.pkg = &no_package; + curr_info.sig = &no_signal; + } + + { + proto_item* pi = proto_tree_add_uint(package_tree, hf_h248_signal_code, tvb, offset-2, 2, name_minor); + const gchar* strval; + + if (pkg->signal_names && ( strval = try_val_to_str(name_minor, pkg->signal_names) )) { + strval = wmem_strdup_printf(actx->pinfo->pool, "%s (%d)",strval,name_minor); + } else { + strval = wmem_strdup_printf(actx->pinfo->pool, "Unknown (%d)",name_minor); + } + + proto_item_set_text(pi,"Signal ID: %s", strval); + } + + } else { + curr_info.pkg = &no_package; + curr_info.sig = &no_signal; + } + + return offset; +} + +static int dissect_h248_PropertyID(bool implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_) { + + gint8 ber_class; + bool pc, ind; + gint32 tag; + guint32 len; + guint16 name_minor; + int end_offset; + const h248_package_t* pkg; + const h248_pkg_param_t* prop; + tvbuff_t *next_tvb = NULL; + + offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind); + end_offset=offset+len; + + if( (ber_class!=BER_CLASS_UNI) + ||(tag!=BER_UNI_TAG_OCTETSTRING) ){ + proto_tree_add_expert_format(tree, actx->pinfo, &ei_h248_octet_string_expected, tvb, offset-2, 2, + "H.248 BER Error: OctetString expected but Class:%d PC:%d Tag:%d was unexpected", ber_class, pc, tag); + return end_offset; + } + + next_tvb = tvb_new_subset_length(tvb,offset,len); + + name_minor = packageandid & 0xffff; + + pkg = (curr_info.pkg) ? curr_info.pkg : &no_package; + + if (pkg->properties) { + for (prop = pkg->properties; prop && prop->hfid; prop++) { + if (name_minor == prop->id) { + break; + } + } + } else { + prop = &no_param; + } + if (prop && prop->hfid && prop->dissector) { + prop->dissector(tree, next_tvb, actx->pinfo, *(prop->hfid), &curr_info, prop->data); + } + + return end_offset; +} + + + +static int dissect_h248_SigParameterName(bool implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_) { + tvbuff_t *next_tvb; + guint32 param_id = 0xffffffff; + const h248_pkg_param_t* sigpar; + const gchar* strval; + proto_item* pi; + + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &next_tvb); + pi = actx->created_item; + + switch(tvb_reported_length(next_tvb)) { + case 4: param_id = tvb_get_ntohl(next_tvb,0); break; + case 3: param_id = tvb_get_ntoh24(next_tvb,0); break; + case 2: param_id = tvb_get_ntohs(next_tvb,0); break; + case 1: param_id = tvb_get_guint8(next_tvb,0); break; + default: break; + } + + curr_info.par = &no_param; + + if (curr_info.sig && curr_info.sig->parameters) { + for(sigpar = curr_info.sig->parameters; sigpar->hfid; sigpar++) { + if (sigpar->id == param_id) { + curr_info.par = sigpar; + break; + } + } + } + + if (curr_info.sig && curr_info.sig->param_names && ( strval = try_val_to_str(param_id, curr_info.sig->param_names) )) { + strval = wmem_strdup_printf(actx->pinfo->pool, "%s (%d)",strval,param_id); + } else { + strval = wmem_strdup_printf(actx->pinfo->pool, "Unknown (%d)",param_id); + } + + proto_item_set_text(pi,"Parameter: %s", strval); + + return offset; +} + +static int dissect_h248_SigParamValue(bool implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_) { + int end_offset; + gint8 ber_class; + bool pc, ind; + gint32 tag; + guint32 len; + tvbuff_t *next_tvb = NULL; + + offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind); + end_offset=offset+len; + + if( (ber_class!=BER_CLASS_UNI) + ||(tag!=BER_UNI_TAG_OCTETSTRING) ){ + proto_tree_add_expert_format(tree, actx->pinfo, &ei_h248_octet_string_expected, tvb, offset-2, 2, + "H.248 BER Error: OctetString expected but Class:%d PC:%d Tag:%d was unexpected", ber_class, pc, tag); + return end_offset; + } + + next_tvb = tvb_new_subset_length(tvb,offset,len); + + if ( curr_info.par && curr_info.par->dissector) { + curr_info.par->dissector(tree, next_tvb, actx->pinfo, *(curr_info.par->hfid), &curr_info, curr_info.par->data); + } + + return end_offset; +} + +static int dissect_h248_SigParamValueV1(bool implicit_tag _U_, tvbuff_t *tvb, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_) { + return dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, NULL); +} + + +static int dissect_h248_EventParameterName(bool implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_) { + tvbuff_t *next_tvb; + guint32 param_id = 0xffffffff; + const h248_pkg_param_t* evtpar; + const gchar* strval; + proto_item* pi; + + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &next_tvb); + pi = actx->created_item; + + if (next_tvb) { + switch(tvb_reported_length(next_tvb)) { + case 4: param_id = tvb_get_ntohl(next_tvb,0); break; + case 3: param_id = tvb_get_ntoh24(next_tvb,0); break; + case 2: param_id = tvb_get_ntohs(next_tvb,0); break; + case 1: param_id = tvb_get_guint8(next_tvb,0); break; + default: break; + } + } + + + curr_info.par = &no_param; + + if (curr_info.evt && curr_info.evt->parameters) { + for(evtpar = curr_info.evt->parameters; evtpar->hfid; evtpar++) { + if (evtpar->id == param_id) { + curr_info.par = evtpar; + break; + } + } + } else { + curr_info.par = &no_param; + } + + if (curr_info.evt && curr_info.evt->param_names && ( strval = try_val_to_str(param_id, curr_info.evt->param_names) )) { + strval = wmem_strdup_printf(actx->pinfo->pool, "%s (%d)",strval,param_id); + } else { + strval = wmem_strdup_printf(actx->pinfo->pool, "Unknown (%d)",param_id); + } + + proto_item_set_text(pi,"Parameter: %s", strval); + + + return offset; +} + +static int dissect_h248_EventParamValue(bool implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_) { + tvbuff_t *next_tvb; + int end_offset; + gint8 ber_class; + bool pc, ind; + gint32 tag; + guint32 len; + + offset=dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &ber_class, &pc, &tag); + offset=dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind); + end_offset=offset+len; + + if( (ber_class!=BER_CLASS_UNI) + ||(tag!=BER_UNI_TAG_OCTETSTRING) ){ + proto_tree_add_expert_format(tree, actx->pinfo, &ei_h248_octet_string_expected, tvb, offset-2, 2, + "H.248 BER Error: OctetString expected but Class:%d PC:%d Tag:%d was unexpected", ber_class, pc, tag); + return end_offset; + } + + next_tvb = tvb_new_subset_length(tvb,offset,len); + + if ( curr_info.par && curr_info.par->dissector) { + curr_info.par->dissector(tree, next_tvb, actx->pinfo, *(curr_info.par->hfid), &curr_info, curr_info.par->data); + } + + return end_offset; +} + +static int dissect_h248_EventParamValueV1(bool implicit_tag _U_, tvbuff_t *tvb, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_) { + return dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &tvb); +} + + +static int dissect_h248_MtpAddress(bool implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) { + tvbuff_t *new_tvb; + proto_tree *mtp_tree=NULL; + guint32 val; + int i, len, old_offset; + + old_offset=offset; + offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, &new_tvb); + + if (new_tvb) { + /* this field is either 2 or 4 bytes so just read it into an integer */ + val=0; + len=tvb_reported_length(new_tvb); + for(i=0;i<len;i++){ + val= (val<<8)|tvb_get_guint8(new_tvb, i); + } + + /* do the prettification */ + proto_item_append_text(actx->created_item, " NI = %d, PC = %d ( %d-%d )", val&0x03,val>>2,val&0x03,val>>2); + if(tree){ + mtp_tree = proto_item_add_subtree(actx->created_item, ett_mtpaddress); + } + proto_tree_add_uint(mtp_tree, hf_h248_mtpaddress_ni, tvb, old_offset, offset-old_offset, val&0x03); + proto_tree_add_uint(mtp_tree, hf_h248_mtpaddress_pc, tvb, old_offset, offset-old_offset, val>>2); + } + + return offset; +} + +#define H248_TAP() do { if (keep_persistent_data && curr_info.cmd) tap_queue_packet(h248_tap, actx->pinfo, curr_info.cmd); } while(0) + +#include "packet-h248-fn.c" + +static int dissect_h248_tpkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { + dissect_tpkt_encap(tvb, pinfo, tree, h248_desegment, h248_handle); + return tvb_captured_length(tvb); +} + +static int +dissect_h248(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) +{ + proto_item *h248_item; + asn1_ctx_t asn1_ctx; + h248_tree = NULL; + + asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); + + curr_info.msg = NULL; + curr_info.trx = NULL; + curr_info.ctx = NULL; + curr_info.cmd = NULL; + curr_info.term = NULL; + curr_info.pkg = NULL; + curr_info.evt = NULL; + curr_info.sig = NULL; + curr_info.stat = NULL; + curr_info.par = NULL; + + /* Check if it is actually a text-based H.248 encoding, which we + dissect with the "megaco" dissector in Wireshark. (Both + encodings are MEGACO (RFC 3015) and both are H.248.) + */ + if(tvb_captured_length(tvb)>=6){ + if(!tvb_strneql(tvb, 0, "MEGACO", 6)){ + static dissector_handle_t megaco_handle=NULL; + if(!megaco_handle){ + megaco_handle = find_dissector("megaco"); + } + if(megaco_handle){ + call_dissector(megaco_handle, tvb, pinfo, tree); + return tvb_captured_length(tvb); + } + } + { + proto_item *hidden_item = NULL; + guint32 magic_num = 0, offset = 0; + magic_num = tvb_get_ntohl(tvb, offset); + hidden_item = proto_tree_add_uint(tree, hf_248_magic_num, tvb, offset, 4, magic_num); + proto_item_set_hidden(hidden_item); + if( dissector_try_uint(subdissector_table, magic_num, tvb, pinfo, tree) ) { + return tvb_captured_length(tvb); + } + } + } + + export_h248_pdu(pinfo, tvb); + + /* Make entry in the Protocol column on summary display */ + col_set_str(pinfo->cinfo, COL_PROTOCOL, "H.248"); + + if (tree) { + h248_item = proto_tree_add_item(tree, proto_h248, tvb, 0, -1, ENC_NA); + h248_tree = proto_item_add_subtree(h248_item, ett_h248); + } + + dissect_h248_MegacoMessage(FALSE, tvb, 0, &asn1_ctx, h248_tree, -1); + + return tvb_captured_length(tvb); +} + +/*--- proto_register_h248 ----------------------------------------------*/ +void proto_reg_handoff_h248(void); + +void proto_register_h248(void) { + + /* List of fields */ + static hf_register_info hf[] = { + { &hf_248_magic_num, + { "Magic Number for Avaya H.248", "h248.magic_num", + FT_UINT32, BASE_HEX, NULL, 0, + NULL, HFILL}}, + { &hf_h248_mtpaddress_ni, + { "NI", "h248.mtpaddress.ni", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL }}, + { &hf_h248_mtpaddress_pc, + { "PC", "h248.mtpaddress.pc", + FT_UINT32, BASE_DEC, NULL, 0, + NULL, HFILL }}, + { &hf_h248_pkg_name, + { "Package", "h248.package_name", + FT_UINT16, BASE_HEX, NULL, 0, + NULL, HFILL }}, + { &hf_248_pkg_param, + { "Parameter ID", "h248.package_paramid", + FT_UINT16, BASE_HEX, NULL, 0, + NULL, HFILL }}, + { &hf_h248_signal_code, + { "Signal ID", "h248.package_signalid", + FT_UINT16, BASE_HEX, NULL, 0, + NULL, HFILL }}, + { &hf_h248_event_code, + { "Event ID", "h248.package_eventid", + FT_UINT16, BASE_HEX, NULL, 0, + NULL, HFILL }}, + { &hf_h248_event_name, + { "Package and Event name", "h248.event_name", + FT_UINT32, BASE_HEX, NULL, 0, + NULL, HFILL }}, + { &hf_h248_signal_name, + { "Package and Signal name", "h248.signal_name", + FT_UINT32, BASE_HEX, NULL, 0, + NULL, HFILL }}, + { &hf_h248_pkg_bcp_BNCChar_PDU, + { "BNCChar", "h248.package_bcp.BNCChar", + FT_UINT32, BASE_DEC, VALS(gcp_term_types), 0, + NULL, HFILL }}, + { &hf_h248_context_id, + { "contextId", "h248.contextId", + FT_UINT32, BASE_HEX, NULL, 0, + "Context ID", HFILL }}, + { &hf_h248_term_wild_type, + { "Wildcard Mode", "h248.term.wildcard.mode", + FT_UINT8, BASE_DEC, VALS(wildcard_modes), 0x80, + NULL, HFILL }}, + { &hf_h248_term_wild_level, + { "Wildcarding Level", "h248.term.wildcard.level", + FT_UINT8, BASE_DEC, VALS(wildcard_levels), 0x40, + NULL, HFILL }}, + { &hf_h248_term_wild_position, + { "Wildcarding Position", "h248.term.wildcard.pos", + FT_UINT8, BASE_DEC, NULL, 0x3F, + NULL, HFILL }}, + + { &hf_h248_no_pkg, + { "Unknown Package", "h248.pkg.unknown", + FT_BYTES, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_h248_no_sig, + { "Unknown Signal", "h248.pkg.unknown.sig", + FT_BYTES, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_h248_no_evt, + { "Unknown Event", "h248.pkg.unknown.evt", + FT_BYTES, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_h248_param, + { "Parameter", "h248.pkg.unknown.param", + FT_BYTES, BASE_NONE, NULL, 0, + NULL, HFILL }}, + { &hf_h248_serviceChangeReasonStr, + { "ServiceChangeReasonStr", "h248.serviceChangeReasonstr", + FT_STRING, BASE_NONE, NULL, 0, + "h248.IA5String", HFILL }}, + { &hf_h248_context_id64, + { "contextId", "h248.contextId64", + FT_UINT64, BASE_HEX, NULL, 0, + "Context ID", HFILL }}, + { &hf_h248_transactionId64, + { "transactionId", "h248.transactionId", + FT_UINT64, BASE_DEC, NULL, 0, + NULL, HFILL }}, + +/* h248v1 support */ + { &hf_h248_auditValueReplyV1, + { "auditValueReplyV1", "h248.auditValueReplyV1", + FT_NONE, BASE_NONE, NULL, 0, + NULL, HFILL }}, + +#include "packet-h248-hfarr.c" + + GCP_HF_ARR_ELEMS("h248",h248_arrel) + + }; + + /* List of subtrees */ + static gint *ett[] = { + &ett_h248, + &ett_mtpaddress, + &ett_packagename, + &ett_codec, + &ett_wildcard, + &ett_h248_no_pkg, + &ett_h248_no_sig, + &ett_h248_no_evt, + GCP_ETT_ARR_ELEMS(h248_arrel), + +#include "packet-h248-ettarr.c" + }; + + static ei_register_info ei[] = { + { &ei_h248_errored_command, { "h248.errored_command", PI_RESPONSE_CODE, PI_WARN, "Errored Command", EXPFILL }}, + { &ei_h248_transactionId64, { "h248.transactionId.error", PI_MALFORMED, PI_WARN, "Transaction ID invalid", EXPFILL }}, + { &ei_h248_context_id64, { "h248.contextId.error", PI_MALFORMED, PI_WARN, "Context ID invalid", EXPFILL }}, + { &ei_h248_octet_string_expected, { "h248.octet_string_expected", PI_PROTOCOL, PI_WARN, "H.248 BER Error: OctetString expected", EXPFILL }}, + }; + + expert_module_t* expert_h248; + module_t *h248_module; + + /* Register protocol */ + proto_h248 = proto_register_protocol(PNAME, PSNAME, PFNAME); + h248_handle = register_dissector("h248", dissect_h248, proto_h248); + h248_tpkt_handle = register_dissector("h248.tpkt", dissect_h248_tpkt, proto_h248); + + /* Register fields and subtrees */ + proto_register_field_array(proto_h248, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + expert_h248 = expert_register_protocol(proto_h248); + expert_register_field_array(expert_h248, ei, array_length(ei)); + + subdissector_table = register_dissector_table("h248.magic_num", "H.248 Magic Num", proto_h248, FT_UINT32, BASE_HEX); + + h248_module = prefs_register_protocol(proto_h248, NULL); + prefs_register_bool_preference(h248_module, "ctx_info", + "Track Context", + "Maintain relationships between transactions and contexts and display an extra tree showing context data", + &keep_persistent_data); + prefs_register_bool_preference(h248_module, "desegment", + "Desegment H.248 over TCP", + "Desegment H.248 messages that span more TCP segments", + &h248_desegment); + + gcp_msgs = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); + gcp_trxs = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); + gcp_ctxs_by_trx = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); + gcp_ctxs = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); + + h248_tap = register_tap("h248"); +} + +/*--- proto_reg_handoff_h248 -------------------------------------------*/ +void proto_reg_handoff_h248(void) { + + dissector_add_uint("mtp3.service_indicator", MTP_SI_GCP, h248_handle); + h248_term_handle = find_dissector_add_dependency("h248term", proto_h248); + dissector_add_uint_with_preference("tcp.port", H248_PORT, h248_tpkt_handle); + dissector_add_uint_with_preference("udp.port", H248_PORT, h248_handle); + + ss7pc_address_type = address_type_get_by_name("AT_SS7PC"); + exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_7); +} + diff --git a/epan/dissectors/asn1/h248/packet-h248-template.h b/epan/dissectors/asn1/h248/packet-h248-template.h new file mode 100644 index 00000000..ac32c704 --- /dev/null +++ b/epan/dissectors/asn1/h248/packet-h248-template.h @@ -0,0 +1,284 @@ +/* packet-h248.h + * Definitions for H.248/MEGACO packet dissection + * + * Ronnie Sahlberg 2004 + * Luis Ontanon 2005 + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef PACKET_H248_H +#define PACKET_H248_H + +#include "ws_symbol_export.h" + +#include <epan/packet.h> +#include <epan/expert.h> +#include <wsutil/nstime.h> + +/* Gateway Control Protocol -- Context Tracking */ + +typedef struct _gcp_hf_ett_t { + struct { + int ctx; + int ctx_cmd; + int ctx_term; + int ctx_term_type; + int ctx_term_bir; + int ctx_term_nsap; + } hf; + + struct { + gint ctx; + gint ctx_cmds; + gint ctx_terms; + gint ctx_term; + } ett; +} gcp_hf_ett_t; + +#define NULL_CONTEXT 0 +#define CHOOSE_CONTEXT 0xFFFFFFFE +#define ALL_CONTEXTS 0xFFFFFFFF + + +typedef enum { + GCP_CMD_NONE, + GCP_CMD_ADD_REQ, + GCP_CMD_MOVE_REQ, + GCP_CMD_MOD_REQ, + GCP_CMD_SUB_REQ, + GCP_CMD_AUDITCAP_REQ, + GCP_CMD_AUDITVAL_REQ, + GCP_CMD_NOTIFY_REQ, + GCP_CMD_SVCCHG_REQ, + GCP_CMD_TOPOLOGY_REQ, + GCP_CMD_CTX_ATTR_AUDIT_REQ, + GCP_CMD_OTHER_REQ, + GCP_CMD_ADD_REPLY, + GCP_CMD_MOVE_REPLY, + GCP_CMD_MOD_REPLY, + GCP_CMD_SUB_REPLY, + GCP_CMD_AUDITCAP_REPLY, + GCP_CMD_AUDITVAL_REPLY, + GCP_CMD_NOTIFY_REPLY, + GCP_CMD_SVCCHG_REPLY, + GCP_CMD_TOPOLOGY_REPLY, + GCP_CMD_REPLY +} gcp_cmd_type_t; + +typedef enum { + GCP_TRX_NONE, + GCP_TRX_REQUEST, + GCP_TRX_PENDING, + GCP_TRX_REPLY, + GCP_TRX_ACK +} gcp_trx_type_t; + + +typedef struct _gcp_msg_t { + guint32 lo_addr; + guint32 hi_addr; + guint32 framenum; + nstime_t frametime; + struct _gcp_trx_msg_t* trxs; + gboolean committed; +} gcp_msg_t; + +typedef struct _gcp_trx_msg_t { + struct _gcp_trx_t* trx; + struct _gcp_trx_msg_t* next; + struct _gcp_trx_msg_t* last; +} gcp_trx_msg_t; + +typedef struct _gcp_cmd_msg_t { + struct _gcp_cmd_t* cmd; + struct _gcp_cmd_msg_t* next; + struct _gcp_cmd_msg_t* last; +} gcp_cmd_msg_t; + +typedef struct _gcp_trx_t { + gcp_msg_t* initial; + guint32 id; + gcp_trx_type_t type; + guint pendings; + struct _gcp_cmd_msg_t* cmds; + struct _gcp_trx_ctx_t* ctxs; + guint error; +} gcp_trx_t; + +#define GCP_TERM_TYPE_UNKNOWN 0 +#define GCP_TERM_TYPE_AAL1 1 +#define GCP_TERM_TYPE_AAL2 2 +#define GCP_TERM_TYPE_AAL1_STRUCT 3 +#define GCP_TERM_TYPE_IP_RTP 4 +#define GCP_TERM_TYPE_TDM 5 + +typedef enum _gcp_wildcard_t { + GCP_WILDCARD_NONE, + GCP_WILDCARD_CHOOSE, + GCP_WILDCARD_ALL +} gcp_wildcard_t; + +typedef struct _gcp_term_t { + const gchar* str; + + const guint8* buffer; + guint len; + + guint type; + gchar* bir; + gchar* nsap; + + gcp_msg_t* start; + +} gcp_term_t; + +typedef struct _gcp_terms_t { + gcp_term_t* term; + struct _gcp_terms_t* next; + struct _gcp_terms_t* last; +} gcp_terms_t; + +typedef struct _gcp_cmd_t { + guint offset; + const gchar* str; + gcp_cmd_type_t type; + gcp_terms_t terms; + struct _gcp_msg_t* msg; + struct _gcp_trx_t* trx; + struct _gcp_ctx_t* ctx; + guint error; +} gcp_cmd_t; + + +typedef struct _gcp_ctx_t { + gcp_msg_t* initial; + guint32 id; + struct _gcp_cmd_msg_t* cmds; + struct _gcp_ctx_t* prev; + gcp_terms_t terms; +} gcp_ctx_t; + +extern gcp_msg_t* gcp_msg(packet_info* pinfo, int o, gboolean persistent); +extern gcp_trx_t* gcp_trx(gcp_msg_t* m ,guint32 t_id , gcp_trx_type_t type, packet_info *pinfo, gboolean persistent); +extern gcp_ctx_t* gcp_ctx(gcp_msg_t* m, gcp_trx_t* t, guint32 c_id, packet_info *pinfo, gboolean persistent); +extern gcp_cmd_t* gcp_cmd(gcp_msg_t* m, gcp_trx_t* t, gcp_ctx_t* c, gcp_cmd_type_t type, guint offset, packet_info *pinfo, gboolean persistent); +extern gcp_term_t* gcp_cmd_add_term(gcp_msg_t* m, gcp_trx_t* tr, gcp_cmd_t* c, gcp_term_t* t, gcp_wildcard_t wildcard, packet_info *pinfo, gboolean persistent); +extern void gcp_analyze_msg(proto_tree* gcp_tree, packet_info* pinfo, tvbuff_t* gcp_tvb, gcp_msg_t* m, gcp_hf_ett_t* ids, expert_field* command_err); + +#define GCP_ETT_ARR_ELEMS(gi) &(gi.ett.ctx),&(gi.ett.ctx_cmds),&(gi.ett.ctx_terms),&(gi.ett.ctx_term) + +#define GCP_HF_ARR_ELEMS(n,gi) \ + { &(gi.hf.ctx), { "Context", n ".ctx", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, \ + { &(gi.hf.ctx_term), { "Termination", n ".ctx.term", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }}, \ + { &(gi.hf.ctx_term_type), { "Type", n ".ctx.term.type", FT_UINT32, BASE_HEX, VALS(gcp_term_types), 0, NULL, HFILL }}, \ + { &(gi.hf.ctx_term_bir), { "BIR", n ".ctx.term.bir", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }}, \ + { &(gi.hf.ctx_term_nsap), { "NSAP", n ".ctx.term.nsap", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }}, \ + { &(gi.hf.ctx_cmd), { "Command in Frame", n ".ctx.cmd", FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL }} + +WS_DLL_PUBLIC const value_string gcp_cmd_type[]; +WS_DLL_PUBLIC const value_string gcp_term_types[]; + +extern const gchar* gcp_msg_to_str(gcp_msg_t* m, wmem_allocator_t *scope, gboolean persistent); + +#define gcp_cmd_set_error(c,e) (c->error = e) +#define gcp_trx_set_error(t,e) (t->error = e) + +/* END Gateway Control Protocol -- Context Tracking */ + +typedef struct _h248_curr_info_t h248_curr_info_t; + +typedef void (*h248_pkg_param_dissector_t)(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo _U_, int hfid, h248_curr_info_t*, void*); + +extern void h248_param_bytes_item(proto_tree*, tvbuff_t*, packet_info* , int, h248_curr_info_t*,void* ignored); +extern void h248_param_uint_item(proto_tree*, tvbuff_t*, packet_info* , int, h248_curr_info_t*,void* ignored); +WS_DLL_PUBLIC void h248_param_ber_integer(proto_tree*, tvbuff_t*, packet_info* , int, h248_curr_info_t*,void* ignored); +extern void h248_param_ber_octetstring(proto_tree*, tvbuff_t*, packet_info* , int, h248_curr_info_t*,void* ignored); +extern void h248_param_ber_boolean(proto_tree*, tvbuff_t*, packet_info* , int, h248_curr_info_t*,void* ignored); +extern void external_dissector(proto_tree*, tvbuff_t*, packet_info* , int, h248_curr_info_t*,void* dissector_handle); +extern void h248_param_PkgdName(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo , int hfid _U_, h248_curr_info_t* u _U_, void* dissector_hdl); +extern void h248_param_external_dissector(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo , int hfid _U_, h248_curr_info_t* u _U_, void* dissector_hdl); + +typedef enum { + ADD_PKG, /* add package at registration ONLY if no matching package ID */ + REPLACE_PKG, /* replace/add package at registration */ + MERGE_PKG_HIGH, /* merge h248_package_t at registration favor new package */ + MERGE_PKG_LOW /* merge h248_package_t at registration favor current package */ +} pkg_reg_action; + +typedef struct _h248_pkg_param_t { + guint32 id; + int* hfid; + h248_pkg_param_dissector_t dissector; + void* data; +} h248_pkg_param_t; + +typedef struct _h248_pkg_sig_t { + guint32 id; + int* hfid; + gint* ett; + const h248_pkg_param_t* parameters; + const value_string* param_names; +} h248_pkg_sig_t; + +typedef struct _h248_pkg_evt_t { + guint32 id; + int* hfid; + gint* ett; + const h248_pkg_param_t* parameters; + const value_string* param_names; +} h248_pkg_evt_t; + +typedef struct _h248_pkg_stat_t { + guint32 id; + int* hfid; + gint* ett; + const h248_pkg_param_t* parameters; + const value_string* param_names; +} h248_pkg_stat_t; + +typedef struct _h248_package_t { + guint32 id; /**< Package ID */ + int* hfid; /**< hfid that will display the package name */ + gint* ett; /**< The ett for this item */ + const value_string* param_names; /**< The parameter names, Value 00000 should be the package name */ + const value_string* signal_names; + const value_string* event_names; + const value_string* stats_names; + const h248_pkg_param_t* properties; + const h248_pkg_sig_t* signals; + const h248_pkg_evt_t* events; + const h248_pkg_stat_t* statistics; +} h248_package_t; + +typedef struct _save_h248_package_t { + h248_package_t *pkg; + gboolean is_default; +} s_h248_package_t; + +struct _h248_curr_info_t { + gcp_ctx_t* ctx; + gcp_trx_t* trx; + gcp_msg_t* msg; + gcp_term_t* term; + gcp_cmd_t* cmd; + const h248_package_t* pkg; + const h248_pkg_evt_t* evt; + const h248_pkg_sig_t* sig; + const h248_pkg_stat_t* stat; + const h248_pkg_param_t* par; +}; + +typedef struct h248_term_info { + guint8 wild_card; + gchar *str; +} h248_term_info_t; + +WS_DLL_PUBLIC +void h248_register_package(h248_package_t* pkg, pkg_reg_action reg_action); + +#endif /* PACKET_H248_H */ |