### Bug Summary

File: | builds/wireshark/wireshark/epan/dissectors/packet-mcdata.c
Warning: | line 442, column 13 Value stored to 'offset' is never read

### Annotated Source Code

Press '?' to see keyboard shortcuts

Show analyzer invocation
clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name packet-mcdata.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-21/lib/clang/21 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan/dissectors -isystem /builds/wireshark/wireshark/build/epan/dissectors -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /builds/wireshark/wireshark/epan -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2026-02-26-100416-3624-1 -x c /builds/wireshark/wireshark/epan/dissectors/packet-mcdata.c

Keyboard shortcuts:

- Use 'j/k' keys for keyboard navigation
- Use 'Shift+S' to show/hide relevant lines
- Use '?' to toggle this window

Close
Show only relevant lines Show control flow arrows

1 | /* packet-mcdata.c
2 | * Routines for MCData dissection.
3 | * 3GPP TS 24.282 V18.8.0 MCData
4 | *
5 | * TODO:
6 | * Add support for OFF-NETWORK message and notification
7 | * Add support for DEFERRED LIST ACCESS messages
8 | * Add support for FD NETWORK NOTIFICATION message
9 | * Add support for GROUP EMERGENCY ALERT messages
10 | * Add support for COMMUNICATION RELEASE message
11 | *
12 | * Copyright 2026, Stefan Wenk
13 | *
14 | * SPDX-License-Identifier: GPL-2.0-or-later
15 | *
16 | */
17 |
18 | #include <epan/expert.h>
19 | #include <epan/packet.h>
20 | #include <epan/proto.h>
21 | #include <gmodule.h>
22 |
23 | /* Protocol and Field Handles */
24 | static int proto_mcdata = -1;
25 | static int hf_mcdata_message_auth;
26 | static int hf_mcdata_message_protected;
27 | static int hf_mcdata_message_type;
28 | static int hf_mcdata_num_payloads;
29 | static int hf_mcdata_payload_len;
30 | static int hf_mcdata_payload_cont_type;
31 | static int hf_mcdata_payload_val_text;
32 | static int hf_mcdata_payload_val_bytes;
33 | static int hf_mcdata_status_val;
34 | static int hf_mcdata_date_time;
35 | static int hf_mcdata_conv_id;
36 | static int hf_mcdata_message_id;
37 | static int hf_mcdata_sds_disposition_req_iei;
38 | static int hf_mcdata_sds_disposition_req_type;
39 | static int hf_mcdata_fd_disposition_req_iei;
40 | static int hf_mcdata_fd_disposition_req_type;
41 | static int hf_mcdata_mandatory_download_iei;
42 | static int hf_mcdata_mandatory_download_value;
43 | static int hf_mcdata_general_iei;
44 | static int hf_mcdata_in_reply_to_message_id;
45 | static int hf_mcdata_application_id;
46 | static int hf_mcdata_sds_disp_not_type;
47 | static int hf_mcdata_fd_disp_not_type;
48 | static int hf_mcdata_metadata;
49 | static int hf_mcdata_ext_app_id_cont_type;
50 | static int hf_mcdata_ext_app_id_data;
51 | static int hf_mcdata_user_location;
52 | static int hf_mcdata_org_name;
53 | static int hf_mcdata_deffered_fd_sig_payload;
54 | static int hf_mcdata_user_ID;
55 | static int hf_mcdata_termination_info_type;
56 | static int hf_mcdata_ext_response_type_iei;
57 | static int hf_mcdata_ext_response_type_value;
58 | static int hf_mcdata_release_response_type_iei;
59 | static int hf_mcdata_release_response_type_val;
60 | static int hf_mcdata_notification_type;
61 | static int hf_mcdata_app_metadata_container;
62 | static int hf_mcdata_group_id;
63 |
64 | static int ett_mcdata = -1;
65 |
66 | static expert_field ei_malformed_length;
67 |
68 | static ei_register_info expertitems[] = {
69 | {&ei_malformed_length, {"mcdata.malformed.length", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Malformed length", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}}},
70 | };
71 |
72 | // Table 15.2.2-1
73 | static const value_string message_type_vals[] = {
74 | { 1, "SDS SIGNALLING PAYLOAD" },
75 | { 2, "FD SIGNALLING PAYLOAD" },
76 | { 3, "DATA PAYLOAD" },
77 | { 5, "SDS NOTIFICATION" },
78 | { 6, "FD NOTIFICATION" },
79 | { 7, "SDS OFF-NETWORK MESSAGE" },
80 | { 8, "SDS OFF-NETWORK NOTIFICATION" },
81 | { 9, "FD NETWORK NOTIFICATION" },
82 | { 10, "COMMUNICATION RELEASE" },
83 | { 11, "DEFERRED LIST ACCESS REQUEST" },
84 | { 12, "DEFERRED LIST ACCESS RESPONSE" },
85 | { 13, "FD HTTP TERMINATION" },
86 | { 17, "GROUP EMERGENCY ALERT" },
87 | { 18, "GROUP EMERGENCY ALERT ACK" },
88 | { 19, "GROUP EMERGENCY ALERT CANCEL" },
89 | { 20, "GROUP EMERGENCY ALERT CANCEL ACK" },
90 | { 0, NULL((void*)0) }
91 | };
92 |
93 | //
94 | static const value_string payload_content_type_vals[] = {
95 | { 1, "TEXT" },
96 | { 2, "BINARY" },
97 | { 3, "HYPERLINKS" },
98 | { 4, "FILEURL" },
99 | { 5, "LOCATION" },
100 | { 6, "ENHANCED STATUS" },
101 | { 7, "Value allocated for use in interworking" },
102 | { 8, "LOCATION ALTITUDE" },
103 | { 9, "LOCATION TIMESTAMP" },
104 | { 10, "CODED TEXT" },
105 | { 0, NULL((void*)0) }
106 | };
107 |
108 | // Table 15.2.3-1
109 | static const value_string sds_disposition_req_type_vals[] = {
110 | { 1, "DELIVERY" },
111 | { 2, "READ" },
112 | { 3, "DELIVERY AND READ" },
113 | { 0, NULL((void*)0) }
114 | };
115 |
116 | // Table 15.2.4-1
117 | static const value_string fd_disposition_req_type_vals[] = {
118 | { 1, "FILE DOWNLOAD COMPLETED UPDATE" },
119 | { 0, NULL((void*)0) }
120 | };
121 |
122 | // Table 15.2.16-1
123 | static const value_string mand_download_vals[] = {
124 | { 1, "MANDATORY DOWNLOAD" },
125 | { 0, NULL((void*)0) }
126 | };
127 |
128 | // Table 15.2.24-2
129 | static const value_string ext_app_id_content_type_vals[] = {
130 | { 1, "TEXT" },
131 | { 2, "URI" },
132 | { 0, NULL((void*)0) }
133 | };
134 |
135 | static const value_string mcdata_general_iei_vals[] = {
136 | // TV IEIs
137 | { 0x21, "InReplyTo message ID" },
138 | { 0x22, "Application ID" },
139 | { 0x51, "Sender MCData user ID" },
140 | { 0x52, "Deferred FD signalling payload" },
141 | { 0x53, "Application metadata container" },
142 | // TLV IEIs
143 | { 0x78, "Payload" },
144 | { 0x79, "Metadata" },
145 | { 0x7B, "MCData group ID" },
146 | { 0x7C, "Recipient MCData user ID" },
147 | { 0x7D, "Extended application ID" },
148 | { 0x7E, "User location" },
149 | { 0x7F, "Organization name" },
150 | { 0, NULL((void*)0) }
151 | };
152 |
153 | static const value_string application_id_value_vals[] = {
154 | { 1, "BROADBAND CALLOUT" },
155 | { 0, NULL((void*)0) }
156 | };
157 |
158 | // Table 15.2.5-1
159 | static const value_string sds_disp_not_type_vals[] = {
160 | { 1, "UNDELIVERED" },
161 | { 2, "DELIVERED" },
162 | { 3, "READ" },
163 | { 4, "DELIVERED AND READ" },
164 | { 5, "DISPOSITION PREVENTED BY SYSTEM" },
165 | { 0, NULL((void*)0) }
166 | };
167 |
168 | // Table 15.2.6-1
169 | static const value_string fd_disp_not_type_vals[] = {
170 | { 1, "FILE DOWNLOAD REQUEST ACCEPTED" },
171 | { 2, "FILE DOWNLOAD REQUEST REJECTED" },
172 | { 3, "FILE DOWNLOAD COMPLETED" },
173 | { 4, "FILE DOWNLOAD DEFERRED" },
174 | { 0, NULL((void*)0) }
175 | };
176 |
177 | // Table 15.2.22-1
178 | static const value_string term_info_type_vals[] = {
179 | { 1, "TERMINATION REQUEST" },
180 | { 2, "TERMINATION RESPONSE" },
181 | { 3, "TRANSMISSION STOPPED" },
182 | { 4, "INTENT TO RELEASE COMM OVER HTTP" },
183 | { 5, "EXTENSION REQUEST FOR COMM OVER HTTP" },
184 | { 6, "EXTENSION RESPONSE FOR COMM OVER HTTP" },
185 | { 7, "AUTH USER TERMINATION REQUEST FOR COMM OVER HTTP" },
186 | { 0, NULL((void*)0) }
187 | };
188 |
189 | // Table 15.2.21-1
190 | static const value_string ext_respone_type_value_vals[] = {
191 | { 1, "ACCEPTED" },
192 | { 2, "REJECTED" },
193 | { 0, NULL((void*)0) }
194 | };
195 |
196 | // Table 15.2.23-1
197 | static const value_string rel_respone_type_vals[] = {
198 | { 1, "RELEASE SUCCESS" },
199 | { 2, "RELEASE FAILED" },
200 | { 0, NULL((void*)0) }
201 | };
202 |
203 | // Table 15.2.18-1
204 | static const value_string notification_type_vals[] = {
205 | { 1, "FILE EXPIRED UNAVAILABLE TO DOWNLOAD" },
206 | { 2, "FILE DELETED UNAVAILABLE TO DOWNLOAD" },
207 | { 0, NULL((void*)0) }
208 | };
209 |
210 |
211 | static unsigned dissect_payload(unsigned offset, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
212 | uint16_t len;
213 | proto_tree_add_item_ret_uint16(tree, hf_mcdata_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &len);
214 | offset += 2;
215 | if ((tvb_reported_length_remaining(tvb, offset) < len) || len < 1) {
216 | expert_add_info(pinfo, tree, &ei_malformed_length);
217 | return len;
218 | }
219 | uint8_t payload_cont_type;
220 | proto_tree_add_item_ret_uint8(tree, hf_mcdata_payload_cont_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &payload_cont_type);
221 | offset += 1;
222 | switch (payload_cont_type) {
223 | case 1: // TEXT
224 | case 3: // HYPERLINKS
225 | case 4: // FILEURL
226 | case 10: // CODED TEXT
227 | proto_tree_add_item(tree, hf_mcdata_payload_val_text, tvb, offset, len - 1, ENC_UTF_80x00000002);
228 | break;
229 | case 6: // ENHANCED STATUS
230 | proto_tree_add_item(tree, hf_mcdata_status_val, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
231 | break;
232 | case 7: // Value allocated for use in interworking
233 | //Todo: Usage of this value is described in 3GPP TS 29.582
234 | proto_tree_add_item(tree, hf_mcdata_payload_val_bytes, tvb, offset, len - 1, ENC_NA0x00000000);
235 | break;
236 | case 8: // LOCATION ALTITUDE
237 | //Todo: The length of the location altitude payload content is 2 bytes coded as in clause 6.3 in 3GPP TS 23.032
238 | proto_tree_add_item(tree, hf_mcdata_payload_val_bytes, tvb, offset, len - 1, ENC_NA0x00000000);
239 | break;
240 | case 9: // LOCATION TIMESTAMP
241 | //Todo: The length of location timestamp is contained as a binary value in the first octet of the payload
242 | proto_tree_add_item(tree, hf_mcdata_payload_val_bytes, tvb, offset, len - 1, ENC_NA0x00000000);
243 | break;
244 | default:
245 | proto_tree_add_item(tree, hf_mcdata_payload_val_bytes, tvb, offset, len - 1, ENC_NA0x00000000);
246 | break;
247 | }
248 | return len + 2;
249 | }
250 |
251 | static int dissect_signalling_payload(uint8_t message_type, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned decoded_len ) {
252 | unsigned offset = 0;
253 |
254 | proto_tree_add_item(tree, hf_mcdata_message_auth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
255 | proto_tree_add_item(tree, hf_mcdata_message_protected, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
256 | proto_tree_add_item(tree, hf_mcdata_message_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
257 | offset += 1;
258 | if (message_type == 5){ // SDS NOTIFICATION
259 | proto_tree_add_item(tree, hf_mcdata_sds_disp_not_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
260 | offset += 1;
261 | }
262 | if (message_type == 6) { // FD NOTIFICATION
263 | proto_tree_add_item(tree, hf_mcdata_fd_disp_not_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
264 | offset += 1;
265 | }
266 | if (message_type == 9) { // FD NETWORK NOTIFICATION
267 | proto_tree_add_item(tree, hf_mcdata_notification_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
268 | offset += 1;
269 | }
270 | if (message_type !=13 ) { // FD HTTP TERMINATION
271 | proto_tree_add_item(tree, hf_mcdata_date_time, tvb, offset, 5, ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000);
272 | offset += 5;
273 | }
274 | proto_tree_add_item(tree, hf_mcdata_conv_id, tvb, offset, FT_GUID_LEN16, ENC_BIG_ENDIAN0x00000000);
275 | offset += FT_GUID_LEN16;
276 | proto_tree_add_item(tree, hf_mcdata_message_id, tvb, offset, FT_GUID_LEN16, ENC_BIG_ENDIAN0x00000000);
277 | offset += FT_GUID_LEN16;
278 | if (message_type ==13 ) { // FD HTTP TERMINATION
279 | proto_tree_add_item(tree, hf_mcdata_termination_info_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
280 | offset += 1;
281 | }
282 |
283 | while (offset < decoded_len) {
284 | unsigned iei = tvb_get_uint8(tvb, offset);
285 | if ((iei & 0xF0) == 0x80) { // SDS disposition request type
286 | proto_tree_add_item(tree, hf_mcdata_sds_disposition_req_iei, tvb, offset, 1, ENC_NA0x00000000);
287 | proto_tree_add_item(tree, hf_mcdata_sds_disposition_req_type, tvb, offset, 1, ENC_NA0x00000000);
288 | offset += 1;
289 | }
290 | else if ((iei & 0xF0) == 0x90) { // FD disposition request type
291 | proto_tree_add_item(tree, hf_mcdata_fd_disposition_req_iei, tvb, offset, 1, ENC_NA0x00000000);
292 | proto_tree_add_item(tree, hf_mcdata_fd_disposition_req_type, tvb, offset, 1, ENC_NA0x00000000);
293 | offset += 1;
294 | }
295 | else if ((iei & 0xF0) == 0xA0) { // Mandatory download
296 | proto_tree_add_item(tree, hf_mcdata_mandatory_download_iei, tvb, offset, 1, ENC_NA0x00000000);
297 | proto_tree_add_item(tree, hf_mcdata_mandatory_download_value, tvb, offset, 1, ENC_NA0x00000000);
298 | offset += 1;
299 | }
300 | else if ((iei & 0xF0) == 0xC0) { // Extension Response Type
301 | proto_tree_add_item(tree, hf_mcdata_ext_response_type_iei, tvb, offset, 1, ENC_NA0x00000000);
302 | proto_tree_add_item(tree, hf_mcdata_ext_response_type_value, tvb, offset, 1, ENC_NA0x00000000);
303 | offset += 1;
304 | }
305 | else if ((iei & 0xF0) == 0xD0) { // Release Response Type
306 | proto_tree_add_item(tree, hf_mcdata_release_response_type_iei, tvb, offset, 1, ENC_NA0x00000000);
307 | proto_tree_add_item(tree, hf_mcdata_release_response_type_val, tvb, offset, 1, ENC_NA0x00000000);
308 | offset += 1;
309 | }
310 | else {
311 | proto_tree_add_item(tree, hf_mcdata_general_iei, tvb, offset, 1, ENC_NA0x00000000);
312 | offset += 1;
313 | uint16_t len;
314 | switch (iei) {
315 | case 0x21: { // InReplyTo message ID
316 | proto_tree_add_item(tree, hf_mcdata_in_reply_to_message_id, tvb, offset, FT_GUID_LEN16, ENC_BIG_ENDIAN0x00000000);
317 | offset += FT_GUID_LEN16;
318 | break;
319 | }
320 | case 0x22: { // Application ID
321 | proto_tree_add_item(tree, hf_mcdata_application_id, tvb, offset, 1, ENC_NA0x00000000);
322 | offset += 1;
323 | break;
324 | }
325 | case 0x51: { // Sender MCData user ID
326 | proto_tree_add_item_ret_uint16 (tree, hf_mcdata_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &len) ;
327 | if (tvb_reported_length_remaining(tvb, offset + 2) < (unsigned) len) {
328 | expert_add_info(pinfo, tree, &ei_malformed_length);
329 | return len;
330 | }
331 | proto_tree_add_item(tree, hf_mcdata_user_ID, tvb, offset + 2, len , ENC_UTF_80x00000002);
332 | offset += len + 2;
333 | break;
334 | }
335 | case 0x52: { // Deferred FD signalling payload
336 | proto_tree_add_item_ret_uint16 (tree, hf_mcdata_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &len);
337 | if (tvb_reported_length_remaining(tvb, offset + 2) < (unsigned) len) {
338 | expert_add_info(pinfo, tree, &ei_malformed_length);
339 | return len;
340 | }
341 | proto_tree_add_item(tree, hf_mcdata_deffered_fd_sig_payload, tvb, offset + 2, len , ENC_NA0x00000000);
342 | offset += len + 2;
343 | break;
344 | }
345 | case 0x53: { // Application metadata container
346 | proto_tree_add_item_ret_uint16 (tree, hf_mcdata_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &len);
347 | if (tvb_reported_length_remaining(tvb, offset + 2) < (unsigned) len) {
348 | expert_add_info(pinfo, tree, &ei_malformed_length);
349 | return len;
350 | }
351 | proto_tree_add_item(tree, hf_mcdata_app_metadata_container, tvb, offset + 2, len , ENC_UTF_80x00000002);
352 | offset += len + 2;
353 | break;
354 | }
355 | case 0x78: { // Payload
356 | offset += dissect_payload(offset, tvb, pinfo, tree);
357 | break;
358 | }
359 | case 0x79: { // Metadata
360 | proto_tree_add_item_ret_uint16 (tree, hf_mcdata_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &len);
361 | if (tvb_reported_length_remaining(tvb, offset + 2) < (unsigned) len) {
362 | expert_add_info(pinfo, tree, &ei_malformed_length);
363 | return len;
364 | }
365 | proto_tree_add_item(tree, hf_mcdata_metadata, tvb, offset + 2, len , ENC_UTF_80x00000002);
366 | offset += len + 2;
367 | break;
368 | }
369 | case 0x7B: { // MCData group ID
370 | proto_tree_add_item_ret_uint16 (tree, hf_mcdata_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &len);
371 | if (tvb_reported_length_remaining(tvb, offset + 2) < (unsigned) len) {
372 | expert_add_info(pinfo, tree, &ei_malformed_length);
373 | return len;
374 | }
375 | proto_tree_add_item(tree, hf_mcdata_group_id, tvb, offset + 2, len , ENC_NA0x00000000);
376 | offset += len + 2;
377 | break;
378 | }
379 | case 0x7C: { // Recipient MCData user ID
380 | proto_tree_add_item_ret_uint16 (tree, hf_mcdata_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &len);
381 | if (tvb_reported_length_remaining(tvb, offset + 2) < (unsigned) len) {
382 | expert_add_info(pinfo, tree, &ei_malformed_length);
383 | return len;
384 | }
385 | proto_tree_add_item(tree, hf_mcdata_user_ID, tvb, offset + 2, len , ENC_UTF_80x00000002);
386 | offset += len + 2;
387 | break;
388 | }
389 | case 0x7D: { // Extended application ID
390 | proto_tree_add_item_ret_uint16 (tree, hf_mcdata_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &len);
391 | if (tvb_reported_length_remaining(tvb, offset + 3) < (unsigned) len) {
392 | expert_add_info(pinfo, tree, &ei_malformed_length);
393 | return len;
394 | }
395 | proto_tree_add_item(tree, hf_mcdata_ext_app_id_cont_type, tvb, offset + 2, 1, ENC_BIG_ENDIAN0x00000000);
396 | proto_tree_add_item(tree, hf_mcdata_ext_app_id_data, tvb, offset + 3, len - 1, ENC_UTF_80x00000002);
397 | offset += len + 3;
398 | break;
399 | }
400 | case 0x7E: { // User location
401 | proto_tree_add_item_ret_uint16 (tree, hf_mcdata_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &len);
402 | if (tvb_reported_length_remaining(tvb, offset + 2) < (unsigned) len) {
403 | expert_add_info(pinfo, tree, &ei_malformed_length);
404 | return len;
405 | }
406 | // Todo: The User location information element contains the LocationInfo structure defined in clause 7.4 of 3GPP TS 29.199-09
407 | proto_tree_add_item(tree, hf_mcdata_user_location, tvb, offset + 2, len , ENC_NA0x00000000);
408 | offset += len + 2;
409 | break;
410 | }
411 | case 0x7F: { // Organization name
412 | proto_tree_add_item_ret_uint16 (tree, hf_mcdata_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &len);
413 | if (tvb_reported_length_remaining(tvb, offset + 2) < (unsigned) len) {
414 | expert_add_info(pinfo, tree, &ei_malformed_length);
415 | return len;
416 | }
417 | proto_tree_add_item(tree, hf_mcdata_org_name, tvb, offset + 2, len , ENC_UTF_80x00000002);
418 | offset += len + 2;
419 | break;
420 | }
421 | }
422 | }
423 |
424 | }
425 |
426 | return offset;
427 | }
428 |
429 | /* Dissector Implementation */
430 | static int dissect_mcdata(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U___attribute__((unused))) {
431 | unsigned offset = 0;
432 | unsigned decoded_len = tvb_captured_length(tvb);
433 | uint8_t message_type = tvb_get_uint8(tvb, offset) & 0x3F;
434 |
435 | add_new_data_source(pinfo, tvb, "MCData");
436 | proto_item *ti = proto_tree_add_item(tree, proto_mcdata, tvb, 0, -1, ENC_NA0x00000000);
437 | proto_tree *mcdata_tree = proto_item_add_subtree(ti, ett_mcdata);
438 |
439 | switch (message_type) {
440 | case 1: // SDS SIGNALLING PAYLOAD
441 | col_append_str(pinfo->cinfo, COL_INFO, "| SDS Signalling Payload");
442 | offset += dissect_signalling_payload(message_type, tvb, pinfo, mcdata_tree, decoded_len);
| Value stored to 'offset' is never read
443 | break;
444 | case 2: // FD SIGNALLING PAYLOAD
445 | col_append_str(pinfo->cinfo, COL_INFO, "| FD Signalling Payload");
446 | offset += dissect_signalling_payload(message_type, tvb, pinfo, mcdata_tree, decoded_len);
447 | break;
448 | case 3: // DATA PAYLOAD
449 | col_append_str(pinfo->cinfo, COL_INFO, "| Data Payload");
450 | proto_tree_add_item(mcdata_tree, hf_mcdata_message_auth, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
451 | proto_tree_add_item(mcdata_tree, hf_mcdata_message_protected, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
452 | proto_tree_add_item(mcdata_tree, hf_mcdata_message_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
453 | offset += 1;
454 | proto_tree_add_item(mcdata_tree, hf_mcdata_num_payloads, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
455 | uint8_t num_payload = tvb_get_uint8(tvb, offset);
456 | offset += 1;
457 | for (uint8_t i=1; i<=num_payload; i++) {
458 | proto_tree_add_item(mcdata_tree, hf_mcdata_general_iei, tvb, offset, 1, ENC_NA0x00000000);
459 | offset += 1;
460 | offset += dissect_payload(offset, tvb, pinfo, mcdata_tree);
461 | }
462 | break;
463 | case 5: // SDS NOTIFICATION
464 | col_append_str(pinfo->cinfo, COL_INFO, "| SDS Notification");
465 | offset += dissect_signalling_payload(message_type, tvb, pinfo, mcdata_tree, decoded_len);
466 | break;
467 | case 6: // FD NOTIFICATION
468 | col_append_str(pinfo->cinfo, COL_INFO, "| FD Notification");
469 | offset += dissect_signalling_payload(message_type, tvb, pinfo, mcdata_tree, decoded_len);
470 | break;
471 | case 7: // SDS OFF-NETWORK MESSAGE
472 | col_append_str(pinfo->cinfo, COL_INFO, "| SDS Off-Network Message");
473 | break;
474 | case 8: // SDS OFF-NETWORK NOTIFICATION
475 | col_append_str(pinfo->cinfo, COL_INFO, "| SDS Off-Network Notification");
476 | break;
477 | case 9: // FD NETWORK NOTIFICATION
478 | col_append_str(pinfo->cinfo, COL_INFO, "| FD Network Notification");
479 | offset += dissect_signalling_payload(message_type, tvb, pinfo, mcdata_tree, decoded_len);
480 | break;
481 | case 10: // COMMUNICATION RELEASE
482 | col_append_str(pinfo->cinfo, COL_INFO, "| Communication Release");
483 | break;
484 | case 11: // DEFERRED LIST ACCESS REQUEST
485 | col_append_str(pinfo->cinfo, COL_INFO, "| Deferred list access request");
486 | break;
487 | case 12: // DEFERRED LIST ACCESS RESPONSE
488 | col_append_str(pinfo->cinfo, COL_INFO, "| Deferred list access response");
489 | break;
490 | case 13: // FD HTTP TERMINATION
491 | col_append_str(pinfo->cinfo, COL_INFO, "| FD HTTP termination");
492 | offset += dissect_signalling_payload(message_type, tvb, pinfo, mcdata_tree, decoded_len);
493 | break;
494 | case 17: // GROUP EMERGENCY ALERT
495 | col_append_str(pinfo->cinfo, COL_INFO, "| Group emergency alert");
496 | break;
497 | case 18: // GROUP EMERGENCY ALERT ACK
498 | col_append_str(pinfo->cinfo, COL_INFO, "| Group emergency alert ack");
499 | break;
500 | case 19: // GROUP EMERGENCY ALERT CANCEL
501 | col_append_str(pinfo->cinfo, COL_INFO, "| Group emergency alert cancel");
502 | break;
503 | case 20: // GROUP EMERGENCY ALERT CANCEL ACK
504 | col_append_str(pinfo->cinfo, COL_INFO, "| Group emergency alert cancel ack");
505 | break;
506 | default:
507 | col_append_str(pinfo->cinfo, COL_INFO, "| Unknown Message Type");
508 | break;
509 | }
510 |
511 | return tvb_captured_length(tvb);
512 | }
513 |
514 | /* Registration */
515 | void proto_register_mcdata(void) {
516 | static hf_register_info hf[] = {
517 | { &hf_mcdata_message_auth, { "Message authenticated", "mcdata.message.authenticated", FT_BOOLEAN, 8, NULL((void*)0), 0x80, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
518 | { &hf_mcdata_message_protected, { "Message protected", "mcdata.message.protected", FT_BOOLEAN, 8, NULL((void*)0), 0x40, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
519 | { &hf_mcdata_message_type, { "Message type", "mcdata.message.type", FT_UINT8, BASE_DEC, VALS(message_type_vals)((0 ? (const struct _value_string*)0 : ((message_type_vals))) ), 0x3F, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
520 | { &hf_mcdata_num_payloads, { "Number of payloads", "mcdata.pl.num.payloads", FT_UINT8, BASE_DEC, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
521 | { &hf_mcdata_payload_len, { "Payload length", "mcdata.pl.payload.len", FT_UINT16, BASE_DEC, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
522 | { &hf_mcdata_payload_cont_type, { "Payload content type", "mcdata.pl.payload.content.type", FT_UINT8, BASE_DEC, VALS(payload_content_type_vals)((0 ? (const struct _value_string*)0 : ((payload_content_type_vals )))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
523 | { &hf_mcdata_payload_val_text, { "Payload text value", "mcdata.pl.payload.text.val", FT_STRING, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
524 | { &hf_mcdata_payload_val_bytes, { "Payload value", "mcdata.pl.payload.val", FT_BYTES, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
525 | { &hf_mcdata_status_val, { "Enhanced status value", "mcdata.pl.status.val", FT_UINT16, BASE_DEC, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
526 | { &hf_mcdata_date_time, { "Date and time", "mcdata.sig.date.and.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL((void*)0), 0x0,NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
527 | { &hf_mcdata_conv_id, { "Conversation ID", "mcdata.sig.conv.id", FT_GUID, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
528 | { &hf_mcdata_message_id, { "Message ID", "mcdata.sig.message.id", FT_GUID, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
529 | { &hf_mcdata_sds_disposition_req_iei, { "SDS disposition request IEI", "mcdata.sig.sds.disp.req.iei", FT_UINT8, BASE_HEX, NULL((void*)0), 0xF0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
530 | { &hf_mcdata_sds_disposition_req_type, { "SDS disposition request type", "mcdata.sig.sds.disp.req.type", FT_UINT8, BASE_DEC, VALS(sds_disposition_req_type_vals)((0 ? (const struct _value_string*)0 : ((sds_disposition_req_type_vals )))), 0x0F, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
531 | { &hf_mcdata_fd_disposition_req_iei, { "FD disposition request IEI", "mcdata.sig.fd.disp.req.iei", FT_UINT8, BASE_HEX, NULL((void*)0), 0xF0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
532 | { &hf_mcdata_fd_disposition_req_type, { "FD disposition request type", "mcdata.sig.fd.disp.req.type", FT_UINT8, BASE_DEC, VALS(fd_disposition_req_type_vals)((0 ? (const struct _value_string*)0 : ((fd_disposition_req_type_vals )))), 0x0F, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
533 | { &hf_mcdata_mandatory_download_iei, { "Mandatory download IEI", "mcdata.sig.mand.download.iei", FT_UINT8, BASE_HEX, NULL((void*)0), 0xF0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
534 | { &hf_mcdata_mandatory_download_value, { "Mandatory download value", "mcdata.sig.mand.download.value", FT_UINT8, BASE_DEC, VALS(mand_download_vals)((0 ? (const struct _value_string*)0 : ((mand_download_vals)) )), 0x0F, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
535 | { &hf_mcdata_general_iei, { "MCData general IEI", "mcdata.general.iei", FT_UINT8, BASE_HEX, VALS(mcdata_general_iei_vals)((0 ? (const struct _value_string*)0 : ((mcdata_general_iei_vals )))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
536 | { &hf_mcdata_in_reply_to_message_id, { "In reply to message ID", "mcdata.sig.in.reply.to.message.id", FT_GUID, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
537 | { &hf_mcdata_application_id, { "Application ID value", "mcdata.sig.appl.id.value", FT_UINT8, BASE_DEC, VALS(application_id_value_vals)((0 ? (const struct _value_string*)0 : ((application_id_value_vals )))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
538 | { &hf_mcdata_sds_disp_not_type, { "SDS disposition notification type", "mcdata.sig.sds.disp.not.type", FT_UINT8, BASE_DEC, VALS(sds_disp_not_type_vals)((0 ? (const struct _value_string*)0 : ((sds_disp_not_type_vals )))), 0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
539 | { &hf_mcdata_fd_disp_not_type, { "FD disposition notification type", "mcdata.sig.fd.disp.not.type", FT_UINT8, BASE_DEC, VALS(fd_disp_not_type_vals)((0 ? (const struct _value_string*)0 : ((fd_disp_not_type_vals )))), 0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
540 | { &hf_mcdata_metadata, { "Metadata", "mcdata.sig.metadata", FT_STRING, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
541 | { &hf_mcdata_ext_app_id_cont_type, { "Extended application id content type", "mcdata.sig.ext.app.id.cont.type", FT_UINT8, BASE_HEX, VALS(ext_app_id_content_type_vals)((0 ? (const struct _value_string*)0 : ((ext_app_id_content_type_vals )))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
542 | { &hf_mcdata_ext_app_id_data, { "Extended application id data", "mcdata.sig.ext.app.id.data", FT_STRING, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
543 | { &hf_mcdata_user_location, { "User location", "mcdata.sig.user.location", FT_BYTES, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
544 | { &hf_mcdata_org_name, { "Organization name", "mcdata.org.name", FT_STRING, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
545 | { &hf_mcdata_deffered_fd_sig_payload, { "Deferred FD signalling payload", "mcdata.sig.def.fd.sig.payload", FT_BYTES, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
546 | { &hf_mcdata_user_ID, { "MCData user ID", "mcdata.sig.user.id", FT_STRING, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
547 | { &hf_mcdata_termination_info_type, { "Termination information type", "mcdata.sig.term.info.type", FT_UINT8, BASE_DEC, VALS(term_info_type_vals)((0 ? (const struct _value_string*)0 : ((term_info_type_vals) ))), 0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
548 | { &hf_mcdata_ext_response_type_iei, { "Extension response type IEI", "mcdata.sig.ext.resp.type.iei", FT_UINT8, BASE_HEX, NULL((void*)0), 0xF0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
549 | { &hf_mcdata_ext_response_type_value, { "Extension response type value", "mcdata.sig.ext.resp.type.value", FT_UINT8, BASE_HEX, VALS(ext_respone_type_value_vals)((0 ? (const struct _value_string*)0 : ((ext_respone_type_value_vals )))), 0xF0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
550 | { &hf_mcdata_release_response_type_iei, { "Release response type IEI", "mcdata.sig.rel.resp.type.iei", FT_UINT8, BASE_HEX, NULL((void*)0), 0xF0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
551 | { &hf_mcdata_release_response_type_val, { "Release response type value", "mcdata.sig.rel.resp.type.value", FT_UINT8, BASE_HEX, VALS(rel_respone_type_vals)((0 ? (const struct _value_string*)0 : ((rel_respone_type_vals )))), 0xF0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
552 | { &hf_mcdata_notification_type, { "Notification type", "mcdata.sig.notification.type", FT_UINT8, BASE_DEC, VALS(notification_type_vals)((0 ? (const struct _value_string*)0 : ((notification_type_vals )))), 0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
553 | { &hf_mcdata_app_metadata_container, { "Application metadata container", "mcdata.sig.metadata.container", FT_STRING, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
554 | { &hf_mcdata_group_id, { "MCData group id", "mcdata.sig.mcdata.group.id", FT_BYTES, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
555 | };
556 | static int *ett[] = { &ett_mcdata };
557 |
558 | proto_mcdata = proto_register_protocol("Mission critical data", "MCData", "mcdata");
559 | proto_register_field_array(proto_mcdata, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
560 | proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
561 | expert_module_t *expert = expert_register_protocol(proto_mcdata);
562 | expert_register_field_array(expert, expertitems, array_length(expertitems)(sizeof (expertitems) / sizeof (expertitems)[0]));
563 |
564 | }
565 |
566 | void proto_reg_handoff_mcdata(void) {
567 | static dissector_handle_t mcdata_handle;
568 | mcdata_handle = create_dissector_handle(dissect_mcdata, proto_mcdata);
569 | dissector_add_string("media_type", "application/vnd.3gpp.mcdata-payload", mcdata_handle);
570 | dissector_add_string("media_type", "application/vnd.3gpp.mcdata-signalling", mcdata_handle);
571 | // The protocol never appears on top of UDP in the wild, but we allow it for testing purposes using "Decode As":
572 | dissector_add_for_decode_as_with_preference("udp.port", mcdata_handle);
573 | }