2 * Routines for H.460.x packet dissection
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <epan/oids.h>
16 #include <epan/asn1.h>
17 #include <wsutil/array.h>
19 #include "packet-per.h"
20 #include "packet-h225.h"
21 #include "packet-h235.h"
22 #include "packet-h245.h"
24 #define PNAME "H.460 Supplementary Services"
25 #define PSNAME "H.460"
28 void proto_register_h460(void);
29 void proto_reg_handoff_h460(void);
31 /* Initialize the protocol and registered fields */
32 static int proto_h460
;
33 #include "packet-h460-hf.c"
35 /* Initialize the subtree pointers */
36 #include "packet-h460-ett.c"
38 /* Main dissector handle */
39 static dissector_handle_t h460_name_handle
;
42 static dissector_handle_t q931_ie_handle
;
43 static dissector_handle_t h225_ras_handle
;
45 #include "packet-h460-fn.c"
48 dissect_ies(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
) {
52 call_dissector(q931_ie_handle
, tvb
, pinfo
, tree
);
53 offset
+= tvb_reported_length_remaining(tvb
, offset
);
59 dissect_ras(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
) {
62 if (h225_ras_handle
) {
63 call_dissector(h225_ras_handle
, tvb
, pinfo
, tree
);
64 offset
+= tvb_reported_length_remaining(tvb
, offset
);
69 typedef struct _h460_feature_t
{
73 dissector_t content_pdu
;
79 dissector_handle_t content_hnd
;
82 /* Fill in the items after content_pdu */
83 #define FFILL NULL, NULL, NULL, NULL, NULL
86 #define GD 0x01 /* present in H.225 GenericData */
87 #define FD 0x02 /* present in H.225 FeatureDescriptor */
88 #define GM 0x04 /* present in H.245 GenericMessage */
89 #define GI 0x08 /* present in H.245 GenericInformation */
91 static h460_feature_t h460_feature_tab
[] = {
93 { GD
|FD
, "2", "Number Portability", NULL
, FFILL
},
94 { GD
|FD
, "2/1", "NumberPortabilityData", dissect_h460_2_NumberPortabilityInfo_PDU
, FFILL
},
96 { GD
|FD
, "3", "Circuit Status", NULL
, FFILL
},
97 { GD
|FD
, "3/1", "Circuit Status Map", dissect_h460_3_CircuitStatus_PDU
, FFILL
},
99 { GD
|FD
, "4", "CallPriorityDesignation", NULL
, FFILL
},
100 { GD
|FD
, "4/1", "CallPriorityRequest", dissect_h460_4_CallPriorityInfo_PDU
, FFILL
},
101 { GD
|FD
, "4/2", "CallPriorityConfirm", dissect_h460_4_CallPriorityInfo_PDU
, FFILL
},
102 { GD
|FD
, "4/3", "Country/InternationalNetworkCallOriginationRequest", dissect_h460_4_CountryInternationalNetworkCallOriginationIdentification_PDU
, FFILL
},
103 { GD
|FD
, "4/4", "Country/InternationalNetworkCallOriginationConfirm", dissect_h460_4_CountryInternationalNetworkCallOriginationIdentification_PDU
, FFILL
},
105 { GD
|FD
, "5", "DuplicateIEs", NULL
, FFILL
},
106 { GD
|FD
, "5/1", "IEsString", dissect_ies
, FFILL
},
108 { GD
|FD
, "6", "Extended Fast Connect", NULL
, FFILL
},
109 { GD
|FD
, "6/1", "EFC Proposal", NULL
, FFILL
},
110 { GD
|FD
, "6/2", "EFC Close All Media Channels", NULL
, FFILL
},
111 { GD
|FD
, "6/3", "EFC Request New Proposals", NULL
, FFILL
},
112 { GD
|FD
, "6/4", "EFC Require Symmetric Operation", NULL
, FFILL
},
114 { GD
|FD
, "7", "Digit Maps", NULL
, FFILL
},
115 { FD
, "7/1", "Digit Maps Length", NULL
, FFILL
},
116 { FD
, "7/2", "Digit Map Length for Overlapped Sending", NULL
, FFILL
},
117 { FD
, "7/3", "HTTP Digit Maps Download Capability", NULL
, FFILL
},
118 { GD
, "7/1", "Start Timer", NULL
, FFILL
},
119 { GD
, "7/2", "Short Timer", NULL
, FFILL
},
120 { GD
, "7/3", "Long Timer", NULL
, FFILL
},
121 { GD
, "7/4", "Digit Map String", NULL
, FFILL
},
122 { GD
, "7/5", "ToN Associated Digit Map", NULL
, FFILL
},
123 { GD
, "7/5/1", "Type of Number", NULL
, FFILL
},
124 { GD
, "7/5/2", "Digit Map Strings for ToN", NULL
, FFILL
},
125 { GD
, "7/6", "Digit Map URL", NULL
, FFILL
},
127 { GD
|FD
, "8", "Querying for Alternate Routes", NULL
, FFILL
},
128 { GD
|FD
, "8/1", "Query Count", NULL
, FFILL
},
129 { GD
|FD
, "8/2", "Call Termination Cause", NULL
, FFILL
},
131 { GD
|FD
, "9", "QoS-monitoring Reporting", NULL
, FFILL
},
132 { GD
|FD
, "9/0", "qosMonitoringFinalOnly", NULL
, FFILL
},
133 { GD
|FD
, "9/1", "qosMonitoringReportData", dissect_h460_9_QosMonitoringReportData_PDU
, FFILL
},
134 { GD
|FD
, "9/2", "qosMonitoringExtendedRTPMetrics", dissect_h460_9_ExtendedRTPMetrics_PDU
, FFILL
},
136 { GD
|FD
, "10", "Call Party Category", NULL
, FFILL
},
137 { GD
|FD
, "10/1", "Call party category info", dissect_h460_10_CallPartyCategoryInfo_PDU
, FFILL
},
139 { GD
|FD
, "11", "Delayed Call Establishment", NULL
, FFILL
},
140 { GD
|FD
, "11/1", "Delay Point Indicator", NULL
, FFILL
},
141 { GD
|FD
, "11/2", "Implicit DCE Release", NULL
, FFILL
},
142 { GD
|FD
, "11/3", "Delay Point Reached", NULL
, FFILL
},
143 { GD
|FD
, "11/4", "DCE Release", NULL
, FFILL
},
145 { GD
|FD
, "12", "Glare Control Indicator", NULL
, FFILL
},
146 { GD
|FD
, "12/1", "Glare Control Indicator Parameter", NULL
, FFILL
},
148 { GD
|FD
, "13", "Called User Release Control", NULL
, FFILL
},
149 { GD
|FD
, "13/1", "Called User Release Control", NULL
, FFILL
},
151 { GD
|FD
, "14", "Multi-Level Precedence and Preemption", NULL
, FFILL
},
152 { GD
|FD
, "14/1", "MLPP Information", dissect_h460_14_MLPPInfo_PDU
, FFILL
},
154 { GD
|FD
, "15", "Call signalling transport channel suspension and redirection", NULL
, FFILL
},
155 { GD
|FD
, "15/1", "Signalling channel suspend and redirect", dissect_h460_15_SignallingChannelData_PDU
, FFILL
},
157 { GD
|FD
, "16", "Multiple-message Release Sequence", NULL
, FFILL
},
158 { GD
|FD
, "16/1", "MMRS use required", NULL
, FFILL
},
159 { GD
|FD
, "16/2", "MMRS procedure", NULL
, FFILL
},
160 { GD
|FD
, "16/3", "MMRS additional IEs", dissect_ies
, FFILL
},
162 { GD
|FD
, "17", "RAS over H.225.0", NULL
, FFILL
},
163 { GD
|FD
, "17/1", "RAS message", dissect_ras
, FFILL
},
165 { GD
|FD
, "18", "Signalling Traversal", NULL
, FFILL
},
166 { GD
|FD
, "18/1", "IncomingCallIndication", dissect_h460_18_IncomingCallIndication_PDU
, FFILL
},
167 { GD
|FD
, "18/2", "LRQKeepAliveData", dissect_h460_18_LRQKeepAliveData_PDU
, FFILL
},
168 { GM
, "0.0.8.460.18.0.1", "Signalling Traversal", NULL
, FFILL
},
169 { GM
, "0.0.8.460.18.0.1-1", "connectionCorrelation", NULL
, FFILL
},
170 { GM
, "0.0.8.460.18.0.1-1/1", "callIdentifier", NULL
, FFILL
},
171 { GM
, "0.0.8.460.18.0.1-1/2", "answerCall", NULL
, FFILL
},
173 { GD
|FD
, "19", "mediaNATFWTraversal", NULL
, FFILL
},
174 { GD
|FD
, "19/1", "supportTransmitMultiplexedMedia", NULL
, FFILL
},
175 { GD
|FD
, "19/2", "mediaTraversalServer", NULL
, FFILL
},
176 { GI
, "0.0.8.460.19.0.1", "mediaNATFWTraversal", NULL
, FFILL
},
177 { GI
, "0.0.8.460.19.0.1/1", "Traversal Parameters", dissect_h460_19_TraversalParameters_PDU
, FFILL
},
179 { GD
|FD
, "20", "LocationSourceAddress", NULL
, FFILL
},
180 { GD
|FD
, "20/1", "LocationSourceAddress", dissect_h225_ExtendedAliasAddress_PDU
, FFILL
},
182 { GD
|FD
, "21", "Message Broadcast", NULL
, FFILL
},
183 { GD
|FD
, "21/1", "MessageBroadcastParameter", dissect_h460_21_CapabilityAdvertisement_PDU
, FFILL
},
185 { GD
|FD
, "22", "securityProtocolNegotiation", NULL
, FFILL
},
186 { GD
|FD
, "22/1", "tlsSecurityProtocol", NULL
, FFILL
},
187 { GD
|FD
, "22/1/1", "priority", NULL
, FFILL
},
188 { GD
|FD
, "22/1/2", "connectionAddress", NULL
, FFILL
},
189 { GD
|FD
, "22/2", "ipsecSecurityProtocol", NULL
, FFILL
},
190 { GD
|FD
, "22/2/1", "priority", NULL
, FFILL
},
191 { 0, NULL
, NULL
, NULL
, FFILL
},
194 static h460_feature_t
*find_ftr(const char *key
) {
195 h460_feature_t
*ftr
= NULL
;
198 for (f
=h460_feature_tab
; f
->id
; f
++) {
199 if (f
->key_gd
&& !strcmp(key
, f
->key_gd
)) { ftr
= f
; break; }
200 if (f
->key_fd
&& !strcmp(key
, f
->key_fd
)) { ftr
= f
; break; }
201 if (f
->key_gm
&& !strcmp(key
, f
->key_gm
)) { ftr
= f
; break; }
202 if (f
->key_gi
&& !strcmp(key
, f
->key_gi
)) { ftr
= f
; break; }
207 /*--- dissect_h460_name -------------------------------------------*/
209 dissect_h460_name(tvbuff_t
*tvb _U_
, packet_info
*pinfo
, proto_tree
*tree
, void *data
) {
214 /* Reject the packet if data is NULL */
217 actx
= get_asn1_ctx(data
);
218 DISSECTOR_ASSERT(actx
);
221 ftr
= find_ftr(pinfo
->match_string
);
223 proto_item_append_text(actx
->created_item
, " - %s", ftr
->name
);
224 proto_item_append_text(proto_item_get_parent(proto_tree_get_parent(tree
)), ": %s", ftr
->name
);
226 proto_item_append_text(actx
->created_item
, " - unknown(%s)", pinfo
->match_string
);
233 /*--- proto_register_h460 ----------------------------------------------*/
234 void proto_register_h460(void) {
238 static hf_register_info hf
[] = {
239 #include "packet-h460-hfarr.c"
242 /* List of subtrees */
243 static int *ett
[] = {
244 #include "packet-h460-ettarr.c"
247 /* Register protocol */
248 proto_h460
= proto_register_protocol(PNAME
, PSNAME
, PFNAME
);
250 /* Register fields and subtrees */
251 proto_register_field_array(proto_h460
, hf
, array_length(hf
));
252 proto_register_subtree_array(ett
, array_length(ett
));
254 h460_name_handle
= register_dissector(PFNAME
, dissect_h460_name
, proto_h460
);
255 for (ftr
=h460_feature_tab
; ftr
->id
; ftr
++) {
256 if (ftr
->opt
& GD
) ftr
->key_gd
= wmem_strdup_printf(wmem_epan_scope(), "GenericData/%s", ftr
->id
);
257 if (ftr
->opt
& FD
) ftr
->key_fd
= wmem_strdup_printf(wmem_epan_scope(), "FeatureDescriptor/%s", ftr
->id
);
258 if (ftr
->opt
& GM
) ftr
->key_gm
= wmem_strdup_printf(wmem_epan_scope(), "GenericMessage/%s", ftr
->id
);
259 if (ftr
->opt
& GI
) ftr
->key_gi
= wmem_strdup_printf(wmem_epan_scope(), "GenericInformation/%s", ftr
->id
);
260 if (ftr
->content_pdu
) ftr
->content_hnd
= create_dissector_handle(ftr
->content_pdu
, proto_h460
);
264 /*--- proto_reg_handoff_h460 -------------------------------------------*/
265 void proto_reg_handoff_h460(void)
269 q931_ie_handle
= find_dissector_add_dependency("q931.ie", proto_h460
);
270 h225_ras_handle
= find_dissector_add_dependency("h225.ras", proto_h460
);
272 for (ftr
=h460_feature_tab
; ftr
->id
; ftr
++) {
273 if (ftr
->key_gd
) dissector_add_string("h225.gef.name", ftr
->key_gd
, h460_name_handle
);
274 if (ftr
->key_fd
) dissector_add_string("h225.gef.name", ftr
->key_fd
, h460_name_handle
);
275 if (ftr
->key_gm
) dissector_add_string("h245.gef.name", ftr
->key_gm
, h460_name_handle
);
276 if (ftr
->key_gi
) dissector_add_string("h245.gef.name", ftr
->key_gi
, h460_name_handle
);
277 if (ftr
->content_hnd
) {
278 if (ftr
->key_gd
) dissector_add_string("h225.gef.content", ftr
->key_gd
, ftr
->content_hnd
);
279 if (ftr
->key_fd
) dissector_add_string("h225.gef.content", ftr
->key_fd
, ftr
->content_hnd
);
280 if (ftr
->key_gm
) dissector_add_string("h245.gef.content", ftr
->key_gm
, ftr
->content_hnd
);
281 if (ftr
->key_gi
) dissector_add_string("h245.gef.content", ftr
->key_gi
, ftr
->content_hnd
);