/src/wireshark/epan/dissectors/packet-cdt.c
Line | Count | Source |
1 | | /* Do not modify this file. Changes will be overwritten. */ |
2 | | /* Generated automatically by the ASN.1 to Wireshark dissector compiler */ |
3 | | /* packet-cdt.c */ |
4 | | /* asn2wrs.py -b -q -L -p cdt -c ./cdt.cnf -s ./packet-cdt-template -D . -O ../.. cdt.asn */ |
5 | | |
6 | | /* packet-cdt.c |
7 | | * |
8 | | * Routines for Compressed Data Type packet dissection. |
9 | | * |
10 | | * Copyright 2005, Stig Bjorlykke <stig@bjorlykke.org>, Thales Norway AS |
11 | | * |
12 | | * Wireshark - Network traffic analyzer |
13 | | * By Gerald Combs <gerald@wireshark.org> |
14 | | * Copyright 1998 Gerald Combs |
15 | | * |
16 | | * SPDX-License-Identifier: GPL-2.0-or-later |
17 | | * |
18 | | * Ref: STANAG 4406 Annex E |
19 | | */ |
20 | | |
21 | | #include "config.h" |
22 | | |
23 | | #include <epan/packet.h> |
24 | | #include <epan/oids.h> |
25 | | #include <epan/expert.h> |
26 | | #include <epan/asn1.h> |
27 | | #include <wsutil/array.h> |
28 | | #include "packet-ber.h" |
29 | | #include "packet-p1.h" |
30 | | |
31 | | #include "packet-cdt.h" |
32 | | |
33 | 0 | #define CDT_UNDEFINED 0 |
34 | 0 | #define CDT_EXTERNAL 1 |
35 | 0 | #define CDT_P1 2 |
36 | | #define CDT_P3 3 |
37 | | #define CDT_P7 4 |
38 | | |
39 | | void proto_register_cdt(void); |
40 | | void proto_reg_handoff_cdt(void); |
41 | | |
42 | | static proto_tree *top_tree; |
43 | | static proto_item *cdt_item; |
44 | | |
45 | | static uint32_t content_type; |
46 | | |
47 | | /* Initialize the protocol and registered fields */ |
48 | | static int proto_cdt; |
49 | | static int hf_cdt_CompressedData_PDU; /* CompressedData */ |
50 | | static int hf_cdt_compressionAlgorithm; /* CompressionAlgorithmIdentifier */ |
51 | | static int hf_cdt_compressedContentInfo; /* CompressedContentInfo */ |
52 | | static int hf_cdt_algorithmID_ShortForm; /* AlgorithmID_ShortForm */ |
53 | | static int hf_cdt_algorithmID_OID; /* OBJECT_IDENTIFIER */ |
54 | | static int hf_cdt_contentType; /* T_contentType */ |
55 | | static int hf_cdt_contentType_ShortForm; /* ContentType_ShortForm */ |
56 | | static int hf_cdt_contentType_OID; /* T_contentType_OID */ |
57 | | static int hf_cdt_compressedContent; /* CompressedContent */ |
58 | | |
59 | | /* Initialize the subtree pointers */ |
60 | | static int ett_cdt_CompressedData; |
61 | | static int ett_cdt_CompressionAlgorithmIdentifier; |
62 | | static int ett_cdt_CompressedContentInfo; |
63 | | static int ett_cdt_T_contentType; |
64 | | |
65 | | static expert_field ei_cdt_unable_compress_content; |
66 | | static expert_field ei_cdt_unable_uncompress_content; |
67 | | |
68 | | |
69 | | static const value_string cdt_AlgorithmID_ShortForm_vals[] = { |
70 | | { 0, "zlibCompress" }, |
71 | | { 0, NULL } |
72 | | }; |
73 | | |
74 | | |
75 | | static unsigned |
76 | 0 | dissect_cdt_AlgorithmID_ShortForm(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
77 | 0 | uint32_t value; |
78 | |
|
79 | 0 | offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index, |
80 | 0 | &value); |
81 | |
|
82 | 0 | proto_item_append_text (cdt_item, ", %s", |
83 | 0 | val_to_str_const(value, cdt_AlgorithmID_ShortForm_vals, |
84 | 0 | "unknown")); |
85 | |
|
86 | 0 | col_append_fstr (actx->pinfo->cinfo, COL_INFO, "%s ", |
87 | 0 | val_to_str_const(value, cdt_AlgorithmID_ShortForm_vals, |
88 | 0 | "unknown")); |
89 | | |
90 | |
|
91 | 0 | return offset; |
92 | 0 | } |
93 | | |
94 | | |
95 | | |
96 | | static unsigned |
97 | 0 | dissect_cdt_OBJECT_IDENTIFIER(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
98 | 0 | offset = dissect_ber_object_identifier(implicit_tag, actx, tree, tvb, offset, hf_index, NULL); |
99 | |
|
100 | 0 | return offset; |
101 | 0 | } |
102 | | |
103 | | |
104 | | static const value_string cdt_CompressionAlgorithmIdentifier_vals[] = { |
105 | | { 0, "algorithmID-ShortForm" }, |
106 | | { 1, "algorithmID-OID" }, |
107 | | { 0, NULL } |
108 | | }; |
109 | | |
110 | | static const ber_choice_t CompressionAlgorithmIdentifier_choice[] = { |
111 | | { 0, &hf_cdt_algorithmID_ShortForm, BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_cdt_AlgorithmID_ShortForm }, |
112 | | { 1, &hf_cdt_algorithmID_OID , BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_cdt_OBJECT_IDENTIFIER }, |
113 | | { 0, NULL, 0, 0, 0, NULL } |
114 | | }; |
115 | | |
116 | | static unsigned |
117 | 0 | dissect_cdt_CompressionAlgorithmIdentifier(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
118 | 0 | offset = dissect_ber_choice(actx, tree, tvb, offset, |
119 | 0 | CompressionAlgorithmIdentifier_choice, hf_index, ett_cdt_CompressionAlgorithmIdentifier, |
120 | 0 | NULL); |
121 | |
|
122 | 0 | return offset; |
123 | 0 | } |
124 | | |
125 | | |
126 | | static const value_string cdt_ContentType_ShortForm_vals[] = { |
127 | | { 0, "unidentified" }, |
128 | | { 1, "external" }, |
129 | | { 2, "p1" }, |
130 | | { 3, "p3" }, |
131 | | { 4, "p7" }, |
132 | | { 0, NULL } |
133 | | }; |
134 | | |
135 | | |
136 | | static unsigned |
137 | 0 | dissect_cdt_ContentType_ShortForm(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
138 | |
|
139 | 0 | offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index, |
140 | 0 | &content_type); |
141 | |
|
142 | 0 | proto_item_append_text (cdt_item, ", %s", |
143 | 0 | val_to_str_const(content_type, cdt_ContentType_ShortForm_vals, |
144 | 0 | "unknown")); |
145 | |
|
146 | 0 | col_append_fstr (actx->pinfo->cinfo, COL_INFO, "%s ", |
147 | 0 | val_to_str_const(content_type, cdt_ContentType_ShortForm_vals, |
148 | 0 | "unknown")); |
149 | | |
150 | |
|
151 | 0 | return offset; |
152 | 0 | } |
153 | | |
154 | | |
155 | | |
156 | | static unsigned |
157 | 0 | dissect_cdt_T_contentType_OID(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
158 | 0 | const char *obj_id = NULL; |
159 | |
|
160 | 0 | offset = dissect_ber_object_identifier_str(implicit_tag, actx, tree, tvb, offset, hf_index, &obj_id); |
161 | |
|
162 | 0 | if (obj_id) { |
163 | 0 | const char *name = oid_resolved_from_string (actx->pinfo->pool, obj_id); |
164 | |
|
165 | 0 | if (!name) { |
166 | 0 | name = obj_id; |
167 | 0 | } |
168 | |
|
169 | 0 | proto_item_append_text (cdt_item, ", %s", name); |
170 | |
|
171 | 0 | col_append_fstr (actx->pinfo->cinfo, COL_INFO, "%s ", name); |
172 | 0 | } |
173 | | |
174 | |
|
175 | 0 | return offset; |
176 | 0 | } |
177 | | |
178 | | |
179 | | static const value_string cdt_T_contentType_vals[] = { |
180 | | { 0, "contentType-ShortForm" }, |
181 | | { 1, "contentType-OID" }, |
182 | | { 0, NULL } |
183 | | }; |
184 | | |
185 | | static const ber_choice_t T_contentType_choice[] = { |
186 | | { 0, &hf_cdt_contentType_ShortForm, BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_cdt_ContentType_ShortForm }, |
187 | | { 1, &hf_cdt_contentType_OID , BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_cdt_T_contentType_OID }, |
188 | | { 0, NULL, 0, 0, 0, NULL } |
189 | | }; |
190 | | |
191 | | static unsigned |
192 | 0 | dissect_cdt_T_contentType(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
193 | 0 | offset = dissect_ber_choice(actx, tree, tvb, offset, |
194 | 0 | T_contentType_choice, hf_index, ett_cdt_T_contentType, |
195 | 0 | NULL); |
196 | |
|
197 | 0 | return offset; |
198 | 0 | } |
199 | | |
200 | | |
201 | | |
202 | | static unsigned |
203 | 0 | dissect_cdt_CompressedContent(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
204 | 0 | tvbuff_t *next_tvb = NULL, *compr_tvb = NULL; |
205 | 0 | unsigned save_offset = offset; |
206 | |
|
207 | 0 | offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index, |
208 | 0 | &compr_tvb); |
209 | |
|
210 | 0 | if (compr_tvb == NULL) { |
211 | 0 | proto_tree_add_expert_remaining(top_tree, actx->pinfo, &ei_cdt_unable_compress_content, |
212 | 0 | tvb, save_offset); |
213 | 0 | col_append_str (actx->pinfo->cinfo, COL_INFO, |
214 | 0 | "[Error: Unable to get compressed content]"); |
215 | 0 | return offset; |
216 | 0 | } |
217 | | |
218 | 0 | next_tvb = tvb_child_uncompress_zlib(tvb, compr_tvb, 0, tvb_reported_length (compr_tvb)); |
219 | |
|
220 | 0 | if (next_tvb == NULL) { |
221 | 0 | proto_tree_add_expert_remaining(top_tree, actx->pinfo, &ei_cdt_unable_uncompress_content, |
222 | 0 | tvb, save_offset); |
223 | 0 | col_append_str (actx->pinfo->cinfo, COL_INFO, |
224 | 0 | "[Error: Unable to uncompress content]"); |
225 | 0 | return offset; |
226 | 0 | } |
227 | | |
228 | 0 | add_new_data_source (actx->pinfo, next_tvb, "Uncompressed Content"); |
229 | |
|
230 | 0 | switch (content_type) { |
231 | 0 | case CDT_UNDEFINED: |
232 | 0 | call_data_dissector(next_tvb, actx->pinfo, top_tree); |
233 | 0 | break; |
234 | 0 | case CDT_EXTERNAL: |
235 | 0 | dissect_unknown_ber (actx->pinfo, next_tvb, 0, top_tree); |
236 | 0 | break; |
237 | 0 | case CDT_P1: |
238 | 0 | dissect_p1_mts_apdu (next_tvb, actx->pinfo, top_tree, NULL); |
239 | 0 | break; |
240 | 0 | default: |
241 | 0 | call_data_dissector(next_tvb, actx->pinfo, top_tree); |
242 | 0 | break; |
243 | 0 | } |
244 | | |
245 | | |
246 | 0 | return offset; |
247 | 0 | } |
248 | | |
249 | | |
250 | | static const ber_sequence_t CompressedContentInfo_sequence[] = { |
251 | | { &hf_cdt_contentType , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_cdt_T_contentType }, |
252 | | { &hf_cdt_compressedContent, BER_CLASS_CON, 0, 0, dissect_cdt_CompressedContent }, |
253 | | { NULL, 0, 0, 0, NULL } |
254 | | }; |
255 | | |
256 | | static unsigned |
257 | 0 | dissect_cdt_CompressedContentInfo(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
258 | 0 | offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, |
259 | 0 | CompressedContentInfo_sequence, hf_index, ett_cdt_CompressedContentInfo); |
260 | |
|
261 | 0 | return offset; |
262 | 0 | } |
263 | | |
264 | | |
265 | | static const ber_sequence_t CompressedData_sequence[] = { |
266 | | { &hf_cdt_compressionAlgorithm, BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_cdt_CompressionAlgorithmIdentifier }, |
267 | | { &hf_cdt_compressedContentInfo, BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_cdt_CompressedContentInfo }, |
268 | | { NULL, 0, 0, 0, NULL } |
269 | | }; |
270 | | |
271 | | unsigned |
272 | 0 | dissect_cdt_CompressedData(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
273 | 0 | content_type = 0; |
274 | |
|
275 | 0 | offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, |
276 | 0 | CompressedData_sequence, hf_index, ett_cdt_CompressedData); |
277 | | |
278 | | |
279 | |
|
280 | 0 | return offset; |
281 | 0 | } |
282 | | |
283 | | /*--- PDUs ---*/ |
284 | | |
285 | 0 | static int dissect_CompressedData_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_) { |
286 | 0 | unsigned offset = 0; |
287 | 0 | asn1_ctx_t asn1_ctx; |
288 | 0 | asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo); |
289 | 0 | offset = dissect_cdt_CompressedData(false, tvb, offset, &asn1_ctx, tree, hf_cdt_CompressedData_PDU); |
290 | 0 | return offset; |
291 | 0 | } |
292 | | |
293 | | |
294 | | |
295 | | /*--- proto_register_cdt -------------------------------------------*/ |
296 | | |
297 | | /* |
298 | | ** Dissect Compressed Data Type |
299 | | */ |
300 | | void dissect_cdt (tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) |
301 | 0 | { |
302 | 0 | proto_tree *tree = NULL; |
303 | | |
304 | | /* save parent_tree so subdissectors can create new top nodes */ |
305 | 0 | top_tree = parent_tree; |
306 | |
|
307 | 0 | if (parent_tree) { |
308 | 0 | cdt_item = proto_tree_add_item (parent_tree, proto_cdt, tvb, 0, -1, ENC_NA); |
309 | 0 | tree = proto_item_add_subtree (cdt_item, ett_cdt_CompressedData); |
310 | 0 | } else { |
311 | 0 | cdt_item = NULL; |
312 | 0 | } |
313 | |
|
314 | 0 | col_set_str (pinfo->cinfo, COL_PROTOCOL, "CDT"); |
315 | 0 | col_clear (pinfo->cinfo, COL_INFO); |
316 | |
|
317 | 0 | dissect_CompressedData_PDU (tvb, pinfo, tree, NULL); |
318 | 0 | } |
319 | | |
320 | 14 | void proto_register_cdt (void) { |
321 | | |
322 | | /* List of fields */ |
323 | 14 | static hf_register_info hf[] = { |
324 | 14 | { &hf_cdt_CompressedData_PDU, |
325 | 14 | { "CompressedData", "cdt.CompressedData_element", |
326 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
327 | 14 | NULL, HFILL }}, |
328 | 14 | { &hf_cdt_compressionAlgorithm, |
329 | 14 | { "compressionAlgorithm", "cdt.compressionAlgorithm", |
330 | 14 | FT_UINT32, BASE_DEC, VALS(cdt_CompressionAlgorithmIdentifier_vals), 0, |
331 | 14 | "CompressionAlgorithmIdentifier", HFILL }}, |
332 | 14 | { &hf_cdt_compressedContentInfo, |
333 | 14 | { "compressedContentInfo", "cdt.compressedContentInfo_element", |
334 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
335 | 14 | NULL, HFILL }}, |
336 | 14 | { &hf_cdt_algorithmID_ShortForm, |
337 | 14 | { "algorithmID-ShortForm", "cdt.algorithmID_ShortForm", |
338 | 14 | FT_INT32, BASE_DEC, VALS(cdt_AlgorithmID_ShortForm_vals), 0, |
339 | 14 | NULL, HFILL }}, |
340 | 14 | { &hf_cdt_algorithmID_OID, |
341 | 14 | { "algorithmID-OID", "cdt.algorithmID_OID", |
342 | 14 | FT_OID, BASE_NONE, NULL, 0, |
343 | 14 | "OBJECT_IDENTIFIER", HFILL }}, |
344 | 14 | { &hf_cdt_contentType, |
345 | 14 | { "contentType", "cdt.contentType", |
346 | 14 | FT_UINT32, BASE_DEC, VALS(cdt_T_contentType_vals), 0, |
347 | 14 | NULL, HFILL }}, |
348 | 14 | { &hf_cdt_contentType_ShortForm, |
349 | 14 | { "contentType-ShortForm", "cdt.contentType_ShortForm", |
350 | 14 | FT_INT32, BASE_DEC, VALS(cdt_ContentType_ShortForm_vals), 0, |
351 | 14 | NULL, HFILL }}, |
352 | 14 | { &hf_cdt_contentType_OID, |
353 | 14 | { "contentType-OID", "cdt.contentType_OID", |
354 | 14 | FT_OID, BASE_NONE, NULL, 0, |
355 | 14 | NULL, HFILL }}, |
356 | 14 | { &hf_cdt_compressedContent, |
357 | 14 | { "compressedContent", "cdt.compressedContent", |
358 | 14 | FT_BYTES, BASE_NONE, NULL, 0, |
359 | 14 | NULL, HFILL }}, |
360 | 14 | }; |
361 | | |
362 | | /* List of subtrees */ |
363 | 14 | static int *ett[] = { |
364 | 14 | &ett_cdt_CompressedData, |
365 | 14 | &ett_cdt_CompressionAlgorithmIdentifier, |
366 | 14 | &ett_cdt_CompressedContentInfo, |
367 | 14 | &ett_cdt_T_contentType, |
368 | 14 | }; |
369 | | |
370 | 14 | static ei_register_info ei[] = { |
371 | 14 | { &ei_cdt_unable_compress_content, { "cdt.unable_compress_content", PI_UNDECODED, PI_ERROR, "Unable to get compressed content", EXPFILL }}, |
372 | 14 | { &ei_cdt_unable_uncompress_content, { "cdt.unable_uncompress_content", PI_UNDECODED, PI_ERROR, "Unable to get uncompressed content", EXPFILL }}, |
373 | 14 | }; |
374 | | |
375 | 14 | expert_module_t* expert_cdt; |
376 | | |
377 | | /* Register protocol */ |
378 | 14 | proto_cdt = proto_register_protocol ("Compressed Data Type", "CDT", "cdt"); |
379 | | |
380 | | /* Register fields and subtrees */ |
381 | 14 | proto_register_field_array (proto_cdt, hf, array_length(hf)); |
382 | 14 | proto_register_subtree_array (ett, array_length(ett)); |
383 | 14 | expert_cdt = expert_register_protocol(proto_cdt); |
384 | 14 | expert_register_field_array(expert_cdt, ei, array_length(ei)); |
385 | 14 | } |
386 | | |
387 | | |
388 | | /*--- proto_reg_handoff_cdt ---------------------------------------*/ |
389 | 14 | void proto_reg_handoff_cdt (void) { |
390 | 14 | register_ber_oid_dissector("1.3.26.0.4406.0.4.2", dissect_CompressedData_PDU, proto_cdt, "cdt"); |
391 | | |
392 | 14 | } |