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