Bug Summary

File:builds/wireshark/wireshark/epan/dissectors/packet-mqtt.c
Warning:line 1227, column 29
Access to field 'topic' results in a dereference of a null pointer (loaded from variable 'pdu_data')

Annotated Source Code

Press '?' to see keyboard shortcuts

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-mqtt.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-22/lib/clang/22 -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 /builds/wireshark/wireshark/epan -isystem /usr/include/libxml2 -D CARES_NO_DEPRECATED -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-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../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=gnu17 -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 -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-11-13-100306-3661-1 -x c /builds/wireshark/wireshark/epan/dissectors/packet-mqtt.c
1/* packet-mqtt.c
2 * Routines for MQTT Protocol dissection
3 *
4 * MQTT v5.0 support sponsored by 1byt3 <customers at 1byt3.com>
5 *
6 * By Lakshmi Narayana Madala <[email protected]>
7 * Stig Bjorlykke <[email protected]>
8 *
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <[email protected]>
11 * Copyright 1998 Gerald Combs
12 *
13 * SPDX-License-Identifier: GPL-2.0-or-later
14 */
15
16/*
17 * Protocol description:
18 *
19 * MQTT is a Client Server publish/subscribe messaging transport
20 * protocol. The protocol runs over TCP/IP, or over other network
21 * protocols that provide ordered, lossless, bi-directional
22 * connections.
23 *
24 * MQTT v3.1 specification:
25 * http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html
26 *
27 * MQTT v3.1.1 specification:
28 * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/
29 *
30 * MQTT v5.0 specification:
31 * http://docs.oasis-open.org/mqtt/mqtt/v5.0/
32 *
33 */
34
35#include "config.h"
36#include <epan/expert.h>
37#include <epan/packet.h>
38#include <epan/proto_data.h>
39#include <epan/tfs.h>
40#include <wsutil/array.h>
41#include <epan/uat.h>
42#include "packet-tcp.h"
43#include "packet-tls.h"
44
45#define MQTT_DEFAULT_PORT1883 1883 /* IANA registered under service name as mqtt */
46#define MQTT_SSL_DEFAULT_PORT8883 8883 /* IANA registered under service name secure-mqtt */
47
48/* MQTT Protocol Versions */
49#define MQTT_PROTO_V313 3
50#define MQTT_PROTO_V3114 4
51#define MQTT_PROTO_V505 5
52
53#define MQTT_HDR_SIZE_BEFORE_LEN1 1
54
55/* MQTT Message Types */
56#define MQTT_RESERVED0 0
57#define MQTT_CONNECT1 1
58#define MQTT_CONNACK2 2
59#define MQTT_PUBLISH3 3
60#define MQTT_PUBACK4 4
61#define MQTT_PUBREC5 5
62#define MQTT_PUBREL6 6
63#define MQTT_PUBCOMP7 7
64#define MQTT_SUBSCRIBE8 8
65#define MQTT_SUBACK9 9
66#define MQTT_UNSUBSCRIBE10 10
67#define MQTT_UNSUBACK11 11
68#define MQTT_PINGREQ12 12
69#define MQTT_PINGRESP13 13
70#define MQTT_DISCONNECT14 14
71#define MQTT_AUTH15 15
72#define MQTT_RESERVED_1616 16
73
74/* Flag Values to extract fields */
75#define MQTT_MASK_MSG_TYPE0xF0 0xF0
76#define MQTT_MASK_HDR_RESERVED0x0F 0x0F
77#define MQTT_MASK_HDR_DUP_RESERVED0x07 0x07
78#define MQTT_MASK_QOS0x06 0x06
79#define MQTT_MASK_DUP_FLAG0x08 0x08
80#define MQTT_MASK_RETAIN0x01 0x01
81
82/* MQTT v5.0 Flag Values for the Subscription Options @ Subscribe Packet */
83#define MQTT_MASK_SUBS_QOS0x03 0x03
84#define MQTT_MASK_SUBS_NL0x04 0x04
85#define MQTT_MASK_SUBS_RAP0x08 0x08
86#define MQTT_MASK_SUBS_RETAIN0x30 0x30
87#define MQTT_MASK_SUBS_RESERVED0xC0 0xC0
88
89void proto_register_mqtt(void);
90void proto_reg_handoff_mqtt(void);
91
92static dissector_table_t media_type_dissector_table;
93
94static const value_string mqtt_protocol_version_vals[] = {
95 { MQTT_PROTO_V313, "MQTT v3.1" },
96 { MQTT_PROTO_V3114, "MQTT v3.1.1" },
97 { MQTT_PROTO_V505, "MQTT v5.0" },
98 { 0, NULL((void*)0) }
99};
100
101static const enum_val_t mqtt_protocol_version_enumvals[] = {
102 { "none", "None", 0 },
103 { "v31", "MQTT v3.1", MQTT_PROTO_V313 },
104 { "v311", "MQTT v3.1.1", MQTT_PROTO_V3114 },
105 { "v50", "MQTT v5.0", MQTT_PROTO_V505 },
106 { NULL((void*)0), NULL((void*)0), 0 }
107};
108
109static const value_string mqtt_msgtype_vals[] = {
110 { MQTT_RESERVED0, "Reserved" },
111 { MQTT_CONNECT1, "Connect Command" },
112 { MQTT_CONNACK2, "Connect Ack" },
113 { MQTT_PUBLISH3, "Publish Message" },
114 { MQTT_PUBACK4, "Publish Ack" },
115 { MQTT_PUBREC5, "Publish Received" },
116 { MQTT_PUBREL6, "Publish Release" },
117 { MQTT_PUBCOMP7, "Publish Complete" },
118 { MQTT_SUBSCRIBE8, "Subscribe Request" },
119 { MQTT_SUBACK9, "Subscribe Ack" },
120 { MQTT_UNSUBSCRIBE10, "Unsubscribe Request" },
121 { MQTT_UNSUBACK11, "Unsubscribe Ack" },
122 { MQTT_PINGREQ12, "Ping Request" },
123 { MQTT_PINGRESP13, "Ping Response" },
124 { MQTT_DISCONNECT14, "Disconnect Req" },
125 { MQTT_AUTH15, "Authentication Exchange" },
126 { MQTT_RESERVED_1616, "Reserved" },
127 { 0, NULL((void*)0) }
128};
129static value_string_ext mqtt_msgtype_vals_ext = VALUE_STRING_EXT_INIT(mqtt_msgtype_vals){ _try_val_to_str_ext_init, 0, (sizeof (mqtt_msgtype_vals) / sizeof
((mqtt_msgtype_vals)[0]))-1, mqtt_msgtype_vals, "mqtt_msgtype_vals"
, ((void*)0) }
;
130
131#define MQTT_QOS_ATMOST_ONCE0 0
132#define MQTT_QOS_ATLEAST_ONCE1 1
133#define MQTT_QOS_EXACTLY_ONCE2 2
134#define MQTT_QOS_RESERVED3 3
135
136static const value_string mqtt_qos_vals[] = {
137 { MQTT_QOS_ATMOST_ONCE0, "At most once delivery (Fire and Forget)" },
138 { MQTT_QOS_ATLEAST_ONCE1, "At least once delivery (Acknowledged deliver)" },
139 { MQTT_QOS_EXACTLY_ONCE2, "Exactly once delivery (Assured Delivery)" },
140 { MQTT_QOS_RESERVED3, "Reserved" },
141 { 0, NULL((void*)0) }
142};
143
144#define MQTT_SUBACK_FAILURE128 128
145
146static const value_string mqtt_subqos_vals[] = {
147 { MQTT_QOS_ATMOST_ONCE0, "At most once delivery (Fire and Forget)" },
148 { MQTT_QOS_ATLEAST_ONCE1, "At least once delivery (Acknowledged deliver)" },
149 { MQTT_QOS_EXACTLY_ONCE2, "Exactly once delivery (Assured Delivery)" },
150 { MQTT_QOS_RESERVED3, "Reserved" },
151 { MQTT_SUBACK_FAILURE128, "Failure" },
152 { 0, NULL((void*)0) }
153};
154
155#define MQTT_CON_ACCEPTED0 0
156#define MQTT_CON_REFUSED_VERSION_MISMATCH1 1
157#define MQTT_CON_REFUSED_ID_REJECTED2 2
158#define MQTT_CON_REFUSED_SERVER_UNAVAILABLE3 3
159#define MQTT_CON_REFUSED_BAD_USER_PASSWD4 4
160#define MQTT_CON_REFUSED_UNAUTHORIZED5 5
161
162static const value_string mqtt_conack_vals[] = {
163 { MQTT_CON_ACCEPTED0, "Connection Accepted" },
164 { MQTT_CON_REFUSED_VERSION_MISMATCH1, "Connection Refused: unacceptable protocol version" },
165 { MQTT_CON_REFUSED_ID_REJECTED2, "Connection Refused: identifier rejected" },
166 { MQTT_CON_REFUSED_SERVER_UNAVAILABLE3, "Connection Refused: server unavailable" },
167 { MQTT_CON_REFUSED_BAD_USER_PASSWD4, "Connection Refused: bad user name or password" },
168 { MQTT_CON_REFUSED_UNAUTHORIZED5, "Connection Refused: not authorized" },
169 { 0, NULL((void*)0) }
170};
171
172#define MQTT_CONMASK_USER0x80 0x80
173#define MQTT_CONMASK_PASSWD0x40 0x40
174#define MQTT_CONMASK_RETAIN0x20 0x20
175#define MQTT_CONMASK_QOS0x18 0x18
176#define MQTT_CONMASK_WILLFLAG0x04 0x04
177#define MQTT_CONMASK_CLEANSESS0x02 0x02
178#define MQTT_CONMASK_RESERVED0x01 0x01
179
180#define MQTT_CONACKMASK_RESERVED0xFE 0xFE
181#define MQTT_CONACKMASK_SP0x01 0x01
182
183/* The protocol version is present in the CONNECT message. */
184typedef struct {
185 uint8_t runtime_proto_version;
186 wmem_map_t *topic_alias_map;
187} mqtt_conv_t;
188
189typedef struct _mqtt_message_decode_t {
190 unsigned match_criteria;
191 char *topic_pattern;
192 GRegex *topic_regex;
193 unsigned msg_decoding;
194 char *payload_proto_name;
195 dissector_handle_t payload_proto;
196} mqtt_message_decode_t;
197
198typedef struct _mqtt_properties_t {
199 const char *content_type;
200 uint32_t topic_alias;
201} mqtt_properties_t;
202
203#define MATCH_CRITERIA_EQUAL0 0
204#define MATCH_CRITERIA_CONTAINS1 1
205#define MATCH_CRITERIA_STARTS_WITH2 2
206#define MATCH_CRITERIA_ENDS_WITH3 3
207#define MATCH_CRITERIA_REGEX4 4
208
209static const value_string match_criteria[] = {
210 { MATCH_CRITERIA_EQUAL0, "Equal to" },
211 { MATCH_CRITERIA_CONTAINS1, "Contains" },
212 { MATCH_CRITERIA_STARTS_WITH2, "Starts with" },
213 { MATCH_CRITERIA_ENDS_WITH3, "Ends with" },
214 { MATCH_CRITERIA_REGEX4, "Regular Expression" },
215 { 0, NULL((void*)0) }
216};
217
218#define MSG_DECODING_NONE0 0
219#define MSG_DECODING_COMPRESSED1 1
220
221static const value_string msg_decoding[] = {
222 { MSG_DECODING_NONE0, "none" },
223 { MSG_DECODING_COMPRESSED1, "compressed" },
224 { 0, NULL((void*)0) }
225};
226
227#define PROP_PAYLOAD_FORMAT_INDICATOR0x01 0x01
228#define PROP_PUBLICATION_EXPIRY_INTERVAL0x02 0x02
229#define PROP_CONTENT_TYPE0x03 0x03
230#define PROP_RESPONSE_TOPIC0x08 0x08
231#define PROP_CORRELATION_DATA0x09 0x09
232#define PROP_SUBSCRIPTION_IDENTIFIER0x0B 0x0B
233#define PROP_SESSION_EXPIRY_INTERVAL0x11 0x11
234#define PROP_ASSIGNED_CLIENT_IDENTIFIER0x12 0x12
235#define PROP_SERVER_KEEP_ALIVE0x13 0x13
236#define PROP_AUTH_METHOD0x15 0x15
237#define PROP_AUTH_DATA0x16 0x16
238#define PROP_REQUEST_PROBLEM_INFORMATION0x17 0x17
239#define PROP_WILL_DELAY_INTERVAL0x18 0x18
240#define PROP_REQUEST_RESPONSE_INFORMATION0x19 0x19
241#define PROP_RESPONSE_INFORMATION0x1A 0x1A
242#define PROP_SERVER_REFERENCE0x1C 0x1C
243#define PROP_REASON_STRING0x1F 0x1F
244#define PROP_RECEIVE_MAXIMUM0x21 0x21
245#define PROP_TOPIC_ALIAS_MAXIMUM0x22 0x22
246#define PROP_TOPIC_ALIAS0x23 0x23
247#define PROP_MAXIMUM_QOS0x24 0x24
248#define PROP_RETAIN_AVAILABLE0x25 0x25
249#define PROP_USER_PROPERTY0x26 0x26
250#define PROP_MAXIMUM_PACKET_SIZE0x27 0x27
251#define PROP_WILDCARD_SUBSCRIPTION_AVAILABLE0x28 0x28
252#define PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE0x29 0x29
253#define PROP_SHARED_SUBSCRIPTION_AVAILABLE0x2A 0x2A
254
255static const value_string mqtt_property_vals[] = {
256 { PROP_PAYLOAD_FORMAT_INDICATOR0x01, "Payload Format Indicator" },
257 { PROP_PUBLICATION_EXPIRY_INTERVAL0x02, "Publication Expiry Interval" },
258 { PROP_CONTENT_TYPE0x03, "Content Type" },
259 { PROP_RESPONSE_TOPIC0x08, "Response Topic" },
260 { PROP_CORRELATION_DATA0x09, "Correlation Data" },
261 { PROP_SUBSCRIPTION_IDENTIFIER0x0B, "Subscription Identifier" },
262 { PROP_SESSION_EXPIRY_INTERVAL0x11, "Session Expiry Interval" },
263 { PROP_ASSIGNED_CLIENT_IDENTIFIER0x12, "Assigned Client Identifier" },
264 { PROP_SERVER_KEEP_ALIVE0x13, "Server Keep Alive" },
265 { PROP_AUTH_METHOD0x15, "Authentication Method" },
266 { PROP_AUTH_DATA0x16, "Authentication Data" },
267 { PROP_REQUEST_PROBLEM_INFORMATION0x17, "Request Problem Information" },
268 { PROP_WILL_DELAY_INTERVAL0x18, "Will Delay Interval" },
269 { PROP_REQUEST_RESPONSE_INFORMATION0x19, "Request Response Information" },
270 { PROP_RESPONSE_INFORMATION0x1A, "Response Information" },
271 { PROP_SERVER_REFERENCE0x1C, "Server Reference" },
272 { PROP_REASON_STRING0x1F, "Reason String" },
273 { PROP_RECEIVE_MAXIMUM0x21, "Receive Maximum" },
274 { PROP_TOPIC_ALIAS_MAXIMUM0x22, "Topic Alias Maximum" },
275 { PROP_TOPIC_ALIAS0x23, "Topic Alias" },
276 { PROP_MAXIMUM_QOS0x24, "Maximum QoS" },
277 { PROP_RETAIN_AVAILABLE0x25, "Retain Available" },
278 { PROP_USER_PROPERTY0x26, "User Property" },
279 { PROP_MAXIMUM_PACKET_SIZE0x27, "Maximum Packet Size" },
280 { PROP_WILDCARD_SUBSCRIPTION_AVAILABLE0x28, "Wildcard Subscription Available" },
281 { PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE0x29, "Subscription Identifier Available" },
282 { PROP_SHARED_SUBSCRIPTION_AVAILABLE0x2A, "Shared Subscription Available" },
283 { 0, NULL((void*)0) }
284};
285
286/* MQTT v5.0 Subscription Options, Retain Handling option */
287#define SUBSCRIPTION_RETAIN_SEND0x00 0x00
288#define SUBSCRIPTION_RETAIN_SEND_DONT_EXIST0x01 0x01
289#define SUBSCRIPTION_RETAIN_DONT_SEND0x02 0x02
290#define SUBSCRIPTION_RETAIN_RESERVED0x03 0x03
291
292static const value_string mqtt_subscription_retain_handling[] = {
293 { SUBSCRIPTION_RETAIN_SEND0x00, "Send msgs at subscription time" },
294 { SUBSCRIPTION_RETAIN_SEND_DONT_EXIST0x01, "Send msgs if subscription does not exist" },
295 { SUBSCRIPTION_RETAIN_DONT_SEND0x02, "Do not send msgs at subscription time" },
296 { SUBSCRIPTION_RETAIN_RESERVED0x03, "Reserved" },
297 { 0, NULL((void*)0) }
298};
299
300/* MQTT v5.0 Reason Codes */
301#define RC_SUCCESS0x00 0x00
302#define RC_NORMAL_DISCONNECTION0x00 0x00
303#define RC_GRANTED_QOS00x00 0x00
304#define RC_GRANTED_QOS10x01 0x01
305#define RC_GRANTED_QOS20x02 0x02
306#define RC_DISCONNECT_WILL0x04 0x04
307#define RC_NO_MATCHING_SUBSCRIBERS0x10 0x10
308#define RC_NO_SUBSCRIPTION_EXISTED0x11 0x11
309#define RC_CONTINUE_AUTHENTICATION0x18 0x18
310#define RC_RE_AUTHENTICATE0x19 0x19
311#define RC_UNSPECIFIED_ERROR0x80 0x80
312#define RC_MALFORMED_PACKET0x81 0x81
313#define RC_PROTOCOL_ERROR0x82 0x82
314#define RC_IMPLEMENTATION_SPECIFIC_ERROR0x83 0x83
315#define RC_UNSUPPORTED_PROTOCOL_VERSION0x84 0x84
316#define RC_CLIENT_IDENTIFIER_NOT_VALID0x85 0x85
317#define RC_BAD_USER_NAME_OR_PASSWORD0x86 0x86
318#define RC_NOT_AUTHORIZED0x87 0x87
319#define RC_SERVER_UNAVAILABLE0x88 0x88
320#define RC_SERVER_BUSY0x89 0x89
321#define RC_BANNED0x8A 0x8A
322#define RC_SERVER_SHUTTING_DOWN0x8B 0x8B
323#define RC_BAD_AUTHENTICATION_METHOD0x8C 0x8C
324#define RC_KEEP_ALIVE_TIMEOUT0x8D 0x8D
325#define RC_SESSION_TAKEN_OVER0x8E 0x8E
326#define RC_TOPIC_FILTER_INVALID0x8F 0x8F
327#define RC_TOPIC_NAME_INVALID0x90 0x90
328#define RC_PACKET_IDENTIFIER_IN_USE0x91 0x91
329#define RC_PACKET_IDENTIFIER_NOT_FOUND0x92 0x92
330#define RC_RECEIVE_MAXIMUM_EXCEEDED0x93 0x93
331#define RC_TOPIC_ALIAS_INVALID0x94 0x94
332#define RC_PACKET_TOO_LARGE0x95 0x95
333#define RC_MESSAGE_RATE_TOO_HIGH0x96 0x96
334#define RC_QUOTA_EXCEEDED0x97 0x97
335#define RC_ADMINISTRATIVE_ACTION0x98 0x98
336#define RC_PAYLOAD_FORMAT_INVALID0x99 0x99
337#define RC_RETAIN_NOT_SUPPORTED0x9A 0x9A
338#define RC_QOS_NOT_SUPPORTED0x9B 0x9B
339#define RC_USE_ANOTHER_SERVER0x9C 0x9C
340#define RC_SERVER_MOVED0x9D 0x9D
341#define RC_SHARED_SUBSCRIPTION_NOT_SUPPORTED0x9E 0x9E
342#define RC_CONNECTION_RATE_EXCEEDED0x9F 0x9F
343#define RC_MAXIMUM_CONNECT_TIME0xA0 0xA0
344#define RC_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED0xA1 0xA1
345#define RC_WILDCARD_SUBSCRIPTION_NOT_SUPPORTED0xA2 0xA2
346
347#define RC_SUCCESS_STR"Success" "Success"
348#define RC_NORMAL_DISCONNECTION_STR"Normal disconnection" "Normal disconnection"
349#define RC_GRANTED_QOS0_STR"Granted QoS 0" "Granted QoS 0"
350#define RC_GRANTED_QOS1_STR"Granted QoS 1" "Granted QoS 1"
351#define RC_GRANTED_QOS2_STR"Granted QoS 2" "Granted QoS 2"
352#define RC_DISCONNECT_WILL_STR"Disconnect with Will Message" "Disconnect with Will Message"
353#define RC_NO_MATCHING_SUBSCRIBERS_STR"No matching subscribers" "No matching subscribers"
354#define RC_NO_SUBSCRIPTION_EXISTED_STR"No subscription existed" "No subscription existed"
355#define RC_CONTINUE_AUTHENTICATION_STR"Continue authentication" "Continue authentication"
356#define RC_RE_AUTHENTICATE_STR"Re-authenticate" "Re-authenticate"
357#define RC_UNSPECIFIED_ERROR_STR"Unspecified error" "Unspecified error"
358#define RC_MALFORMED_PACKET_STR"Malformed Packet" "Malformed Packet"
359#define RC_PROTOCOL_ERROR_STR"Protocol Error" "Protocol Error"
360#define RC_IMPLEMENTATION_SPECIFIC_ERROR_STR"Implementation specific error" "Implementation specific error"
361#define RC_UNSUPPORTED_PROTOCOL_VERSION_STR"Unsupported Protocol Version" "Unsupported Protocol Version"
362#define RC_CLIENT_IDENTIFIER_NOT_VALID_STR"Client Identifier not valid" "Client Identifier not valid"
363#define RC_BAD_USER_NAME_OR_PASSWORD_STR"Bad User Name or Password" "Bad User Name or Password"
364#define RC_NOT_AUTHORIZED_STR"Not authorized" "Not authorized"
365#define RC_SERVER_UNAVAILABLE_STR"Server unavailable" "Server unavailable"
366#define RC_SERVER_BUSY_STR"Server busy" "Server busy"
367#define RC_BANNED_STR"Banned" "Banned"
368#define RC_SERVER_SHUTTING_DOWN_STR"Server shutting down" "Server shutting down"
369#define RC_BAD_AUTHENTICATION_METHOD_STR"Bad authentication method" "Bad authentication method"
370#define RC_KEEP_ALIVE_TIMEOUT_STR"Keep Alive timeout" "Keep Alive timeout"
371#define RC_SESSION_TAKEN_OVER_STR"Session taken over" "Session taken over"
372#define RC_TOPIC_FILTER_INVALID_STR"Topic Filter invalid" "Topic Filter invalid"
373#define RC_TOPIC_NAME_INVALID_STR"Topic Name invalid" "Topic Name invalid"
374#define RC_PACKET_IDENTIFIER_IN_USE_STR"Packet Identifier in use" "Packet Identifier in use"
375#define RC_PACKET_IDENTIFIER_NOT_FOUND_STR"Packet Identifier not found" "Packet Identifier not found"
376#define RC_RECEIVE_MAXIMUM_EXCEEDED_STR"Receive Maximum exceeded" "Receive Maximum exceeded"
377#define RC_TOPIC_ALIAS_INVALID_STR"Topic Alias invalid" "Topic Alias invalid"
378#define RC_PACKET_TOO_LARGE_STR"Packet too large" "Packet too large"
379#define RC_MESSAGE_RATE_TOO_HIGH_STR"Message rate too high" "Message rate too high"
380#define RC_QUOTA_EXCEEDED_STR"Quota exceeded" "Quota exceeded"
381#define RC_ADMINISTRATIVE_ACTION_STR"Administrative action" "Administrative action"
382#define RC_PAYLOAD_FORMAT_INVALID_STR"Payload format invalid" "Payload format invalid"
383#define RC_RETAIN_NOT_SUPPORTED_STR"Retain not supported" "Retain not supported"
384#define RC_QOS_NOT_SUPPORTED_STR"QoS not supported" "QoS not supported"
385#define RC_USE_ANOTHER_SERVER_STR"Use another server" "Use another server"
386#define RC_SERVER_MOVED_STR"Server moved" "Server moved"
387#define RC_SHARED_SUBSCRIPTION_NOT_SUPPORTED_STR"Shared Subscription not supported" "Shared Subscription not supported"
388#define RC_CONNECTION_RATE_EXCEEDED_STR"Connection rate exceeded" "Connection rate exceeded"
389#define RC_MAXIMUM_CONNECT_TIME_STR"Maximum connect time" "Maximum connect time"
390#define RC_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED_STR"Subscription Identifiers not supported" "Subscription Identifiers not supported"
391#define RC_WILDCARD_SUBSCRIPTION_NOT_SUPPORTED_STR"Wildcard Subscription not supported" "Wildcard Subscription not supported"
392
393static const value_string mqtt_reason_code_connack_vals[] = {
394 { RC_SUCCESS0x00, RC_SUCCESS_STR"Success" },
395 { RC_UNSPECIFIED_ERROR0x80, RC_UNSPECIFIED_ERROR_STR"Unspecified error" },
396 { RC_MALFORMED_PACKET0x81, RC_MALFORMED_PACKET_STR"Malformed Packet" },
397 { RC_PROTOCOL_ERROR0x82, RC_PROTOCOL_ERROR_STR"Protocol Error" },
398 { RC_IMPLEMENTATION_SPECIFIC_ERROR0x83, RC_IMPLEMENTATION_SPECIFIC_ERROR_STR"Implementation specific error" },
399 { RC_UNSUPPORTED_PROTOCOL_VERSION0x84, RC_UNSUPPORTED_PROTOCOL_VERSION_STR"Unsupported Protocol Version" },
400 { RC_CLIENT_IDENTIFIER_NOT_VALID0x85, RC_CLIENT_IDENTIFIER_NOT_VALID_STR"Client Identifier not valid" },
401 { RC_BAD_USER_NAME_OR_PASSWORD0x86, RC_BAD_USER_NAME_OR_PASSWORD_STR"Bad User Name or Password" },
402 { RC_NOT_AUTHORIZED0x87, RC_NOT_AUTHORIZED_STR"Not authorized" },
403 { RC_SERVER_UNAVAILABLE0x88, RC_SERVER_UNAVAILABLE_STR"Server unavailable" },
404 { RC_SERVER_BUSY0x89, RC_SERVER_BUSY_STR"Server busy" },
405 { RC_BANNED0x8A, RC_BANNED_STR"Banned" },
406 { RC_BAD_AUTHENTICATION_METHOD0x8C, RC_BAD_AUTHENTICATION_METHOD_STR"Bad authentication method" },
407 { RC_TOPIC_NAME_INVALID0x90, RC_TOPIC_NAME_INVALID_STR"Topic Name invalid" },
408 { RC_PACKET_TOO_LARGE0x95, RC_PACKET_TOO_LARGE_STR"Packet too large" },
409 { RC_QUOTA_EXCEEDED0x97, RC_QUOTA_EXCEEDED_STR"Quota exceeded" },
410 { RC_RETAIN_NOT_SUPPORTED0x9A, RC_RETAIN_NOT_SUPPORTED_STR"Retain not supported" },
411 { RC_QOS_NOT_SUPPORTED0x9B, RC_QOS_NOT_SUPPORTED_STR"QoS not supported" },
412 { RC_USE_ANOTHER_SERVER0x9C, RC_USE_ANOTHER_SERVER_STR"Use another server" },
413 { RC_SERVER_MOVED0x9D, RC_SERVER_MOVED_STR"Server moved" },
414 { RC_CONNECTION_RATE_EXCEEDED0x9F, RC_CONNECTION_RATE_EXCEEDED_STR"Connection rate exceeded" },
415 { 0, NULL((void*)0) }
416};
417
418static const value_string mqtt_reason_code_puback_vals[] = {
419 { RC_SUCCESS0x00, RC_SUCCESS_STR"Success" },
420 { RC_NO_MATCHING_SUBSCRIBERS0x10, RC_NO_MATCHING_SUBSCRIBERS_STR"No matching subscribers" },
421 { RC_UNSPECIFIED_ERROR0x80, RC_UNSPECIFIED_ERROR_STR"Unspecified error" },
422 { RC_IMPLEMENTATION_SPECIFIC_ERROR0x83, RC_IMPLEMENTATION_SPECIFIC_ERROR_STR"Implementation specific error" },
423 { RC_NOT_AUTHORIZED0x87, RC_NOT_AUTHORIZED_STR"Not authorized" },
424 { RC_TOPIC_NAME_INVALID0x90, RC_TOPIC_NAME_INVALID_STR"Topic Name invalid" },
425 { RC_PACKET_IDENTIFIER_IN_USE0x91, RC_PACKET_IDENTIFIER_IN_USE_STR"Packet Identifier in use" },
426 { RC_QUOTA_EXCEEDED0x97, RC_QUOTA_EXCEEDED_STR"Quota exceeded" },
427 { RC_PAYLOAD_FORMAT_INVALID0x99, RC_PAYLOAD_FORMAT_INVALID_STR"Payload format invalid" },
428 { 0, NULL((void*)0) }
429};
430
431static const value_string mqtt_reason_code_pubrel_vals[] = {
432 { RC_SUCCESS0x00, RC_SUCCESS_STR"Success" },
433 { RC_PACKET_IDENTIFIER_NOT_FOUND0x92, RC_PACKET_IDENTIFIER_NOT_FOUND_STR"Packet Identifier not found" },
434 { 0, NULL((void*)0) }
435};
436
437static const value_string mqtt_reason_code_suback_vals[] = {
438 { RC_GRANTED_QOS00x00, RC_GRANTED_QOS0_STR"Granted QoS 0" },
439 { RC_GRANTED_QOS10x01, RC_GRANTED_QOS1_STR"Granted QoS 1" },
440 { RC_GRANTED_QOS20x02, RC_GRANTED_QOS2_STR"Granted QoS 2" },
441 { RC_UNSPECIFIED_ERROR0x80, RC_UNSPECIFIED_ERROR_STR"Unspecified error" },
442 { RC_IMPLEMENTATION_SPECIFIC_ERROR0x83, RC_IMPLEMENTATION_SPECIFIC_ERROR_STR"Implementation specific error" },
443 { RC_NOT_AUTHORIZED0x87, RC_NOT_AUTHORIZED_STR"Not authorized" },
444 { RC_TOPIC_FILTER_INVALID0x8F, RC_TOPIC_FILTER_INVALID_STR"Topic Filter invalid" },
445 { RC_PACKET_IDENTIFIER_IN_USE0x91, RC_PACKET_IDENTIFIER_IN_USE_STR"Packet Identifier in use" },
446 { RC_QUOTA_EXCEEDED0x97, RC_QUOTA_EXCEEDED_STR"Quota exceeded" },
447 { RC_SHARED_SUBSCRIPTION_NOT_SUPPORTED0x9E, RC_SHARED_SUBSCRIPTION_NOT_SUPPORTED_STR"Shared Subscription not supported" },
448 { RC_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED0xA1, RC_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED_STR"Subscription Identifiers not supported" },
449 { RC_WILDCARD_SUBSCRIPTION_NOT_SUPPORTED0xA2, RC_WILDCARD_SUBSCRIPTION_NOT_SUPPORTED_STR"Wildcard Subscription not supported" },
450 { 0, NULL((void*)0) }
451};
452
453static const value_string mqtt_reason_code_unsuback_vals[] = {
454 { RC_SUCCESS0x00, RC_SUCCESS_STR"Success" },
455 { RC_NO_SUBSCRIPTION_EXISTED0x11, RC_NO_SUBSCRIPTION_EXISTED_STR"No subscription existed" },
456 { RC_IMPLEMENTATION_SPECIFIC_ERROR0x83, RC_IMPLEMENTATION_SPECIFIC_ERROR_STR"Implementation specific error" },
457 { RC_NOT_AUTHORIZED0x87, RC_NOT_AUTHORIZED_STR"Not authorized" },
458 { RC_TOPIC_FILTER_INVALID0x8F, RC_TOPIC_FILTER_INVALID_STR"Topic Filter invalid" },
459 { RC_PACKET_IDENTIFIER_IN_USE0x91, RC_PACKET_IDENTIFIER_IN_USE_STR"Packet Identifier in use" },
460 { 0, NULL((void*)0) }
461};
462
463static const value_string mqtt_reason_code_disconnect_vals[] = {
464 { RC_NORMAL_DISCONNECTION0x00, RC_NORMAL_DISCONNECTION_STR"Normal disconnection" },
465 { RC_DISCONNECT_WILL0x04, RC_DISCONNECT_WILL_STR"Disconnect with Will Message" },
466 { RC_UNSPECIFIED_ERROR0x80, RC_UNSPECIFIED_ERROR_STR"Unspecified error" },
467 { RC_MALFORMED_PACKET0x81, RC_MALFORMED_PACKET_STR"Malformed Packet" },
468 { RC_PROTOCOL_ERROR0x82, RC_PROTOCOL_ERROR_STR"Protocol Error" },
469 { RC_IMPLEMENTATION_SPECIFIC_ERROR0x83, RC_IMPLEMENTATION_SPECIFIC_ERROR_STR"Implementation specific error" },
470 { RC_NOT_AUTHORIZED0x87, RC_NOT_AUTHORIZED_STR"Not authorized" },
471 { RC_SERVER_BUSY0x89, RC_SERVER_BUSY_STR"Server busy" },
472 { RC_SERVER_SHUTTING_DOWN0x8B, RC_SERVER_SHUTTING_DOWN_STR"Server shutting down" },
473 /* Bad authentication method: check Table 2.6 and Table 3.13 */
474 { RC_BAD_AUTHENTICATION_METHOD0x8C, RC_BAD_AUTHENTICATION_METHOD_STR"Bad authentication method" },
475 { RC_KEEP_ALIVE_TIMEOUT0x8D, RC_KEEP_ALIVE_TIMEOUT_STR"Keep Alive timeout" },
476 { RC_SESSION_TAKEN_OVER0x8E, RC_SESSION_TAKEN_OVER_STR"Session taken over" },
477 { RC_TOPIC_FILTER_INVALID0x8F, RC_TOPIC_FILTER_INVALID_STR"Topic Filter invalid" },
478 { RC_TOPIC_NAME_INVALID0x90, RC_TOPIC_NAME_INVALID_STR"Topic Name invalid" },
479 { RC_RECEIVE_MAXIMUM_EXCEEDED0x93, RC_RECEIVE_MAXIMUM_EXCEEDED_STR"Receive Maximum exceeded" },
480 { RC_TOPIC_ALIAS_INVALID0x94, RC_TOPIC_ALIAS_INVALID_STR"Topic Alias invalid" },
481 { RC_PACKET_TOO_LARGE0x95, RC_PACKET_TOO_LARGE_STR"Packet too large" },
482 { RC_MESSAGE_RATE_TOO_HIGH0x96, RC_MESSAGE_RATE_TOO_HIGH_STR"Message rate too high" },
483 { RC_QUOTA_EXCEEDED0x97, RC_QUOTA_EXCEEDED_STR"Quota exceeded" },
484 { RC_ADMINISTRATIVE_ACTION0x98, RC_ADMINISTRATIVE_ACTION_STR"Administrative action" },
485 { RC_PAYLOAD_FORMAT_INVALID0x99, RC_PAYLOAD_FORMAT_INVALID_STR"Payload format invalid" },
486 { RC_RETAIN_NOT_SUPPORTED0x9A, RC_RETAIN_NOT_SUPPORTED_STR"Retain not supported" },
487 { RC_QOS_NOT_SUPPORTED0x9B, RC_QOS_NOT_SUPPORTED_STR"QoS not supported" },
488 { RC_USE_ANOTHER_SERVER0x9C, RC_USE_ANOTHER_SERVER_STR"Use another server" },
489 { RC_SERVER_MOVED0x9D, RC_SERVER_MOVED_STR"Server moved" },
490 { RC_SHARED_SUBSCRIPTION_NOT_SUPPORTED0x9E, RC_SHARED_SUBSCRIPTION_NOT_SUPPORTED_STR"Shared Subscription not supported" },
491 { RC_CONNECTION_RATE_EXCEEDED0x9F, RC_CONNECTION_RATE_EXCEEDED_STR"Connection rate exceeded" },
492 { RC_MAXIMUM_CONNECT_TIME0xA0, RC_MAXIMUM_CONNECT_TIME_STR"Maximum connect time" },
493 { RC_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED0xA1, RC_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED_STR"Subscription Identifiers not supported" },
494 { RC_WILDCARD_SUBSCRIPTION_NOT_SUPPORTED0xA2, RC_WILDCARD_SUBSCRIPTION_NOT_SUPPORTED_STR"Wildcard Subscription not supported" },
495 { 0, NULL((void*)0) }
496};
497
498static const value_string mqtt_reason_code_auth_vals[] = {
499 { RC_SUCCESS0x00, RC_SUCCESS_STR"Success" },
500 { RC_CONTINUE_AUTHENTICATION0x18, RC_CONTINUE_AUTHENTICATION_STR"Continue authentication" },
501 { RC_RE_AUTHENTICATE0x19, RC_RE_AUTHENTICATE_STR"Re-authenticate" },
502 { 0, NULL((void*)0) }
503};
504
505static mqtt_message_decode_t *mqtt_message_decodes;
506static unsigned num_mqtt_message_decodes;
507static int default_protocol_version;
508
509static dissector_handle_t mqtt_handle;
510
511static heur_dissector_list_t mqtt_topic_subdissector;
512
513/* Initialize the protocol and registered fields */
514typedef struct {
515 uint8_t version;
516 char *topic;
517} mqtt_pdu_data_t;
518
519static int proto_mqtt;
520
521/* Message */
522static int hf_mqtt_hdrflags;
523static int hf_mqtt_msg_len;
524static int hf_mqtt_msg_type;
525static int hf_mqtt_reserved;
526static int hf_mqtt_dup_flag;
527static int hf_mqtt_qos_level;
528static int hf_mqtt_retain;
529static int hf_mqtt_retain_reserved;
530static int hf_mqtt_conack_reserved;
531static int hf_mqtt_conack_flags;
532static int hf_mqtt_conackflag_reserved;
533static int hf_mqtt_conackflag_sp;
534static int hf_mqtt_conack_code;
535static int hf_mqtt_msgid;
536static int hf_mqtt_sub_qos;
537static int hf_mqtt_suback_qos;
538static int hf_mqtt_topic_len;
539static int hf_mqtt_topic;
540static int hf_mqtt_will_topic_len;
541static int hf_mqtt_will_topic;
542static int hf_mqtt_will_msg_len;
543static int hf_mqtt_will_msg;
544static int hf_mqtt_will_msg_text;
545static int hf_mqtt_username_len;
546static int hf_mqtt_username;
547static int hf_mqtt_passwd_len;
548static int hf_mqtt_passwd;
549static int hf_mqtt_pubmsg;
550static int hf_mqtt_pubmsg_text;
551static int hf_mqtt_pubmsg_decoded;
552static int hf_mqtt_proto_len;
553static int hf_mqtt_proto_name;
554static int hf_mqtt_client_id_len;
555static int hf_mqtt_client_id;
556static int hf_mqtt_proto_ver;
557static int hf_mqtt_conflags;
558static int hf_mqtt_conflag_user;
559static int hf_mqtt_conflag_passwd;
560static int hf_mqtt_conflag_will_retain;
561static int hf_mqtt_conflag_will_qos;
562static int hf_mqtt_conflag_will_flag;
563static int hf_mqtt_conflag_clean_sess;
564static int hf_mqtt_conflag_reserved;
565static int hf_mqtt_keep_alive;
566static int hf_mqtt_subscription_options;
567
568/* MQTT v5.0 Reason Codes */
569static int hf_mqtt_reason_code_connack;
570static int hf_mqtt_reason_code_puback;
571static int hf_mqtt_reason_code_pubrec;
572static int hf_mqtt_reason_code_pubrel;
573static int hf_mqtt_reason_code_pubcomp;
574static int hf_mqtt_reason_code_suback;
575static int hf_mqtt_reason_code_unsuback;
576static int hf_mqtt_reason_code_disconnect;
577static int hf_mqtt_reason_code_auth;
578
579/* MQTT v5.0 Subscribe Options */
580static int hf_mqtt_subscription_qos;
581static int hf_mqtt_subscription_nl;
582static int hf_mqtt_subscription_rap;
583static int hf_mqtt_subscription_retain;
584static int hf_mqtt_subscription_reserved;
585
586/* MQTT v5.0 Properties */
587static int hf_mqtt_property_len;
588static int hf_mqtt_property;
589static int hf_mqtt_will_property;
590static int hf_mqtt_property_id;
591static int hf_mqtt_prop_num;
592static int hf_mqtt_prop_content_type;
593static int hf_mqtt_prop_max_qos;
594static int hf_mqtt_prop_topic_alias;
595static int hf_mqtt_prop_unknown;
596static int hf_mqtt_prop_string_len;
597static int hf_mqtt_prop_string;
598static int hf_mqtt_prop_key_len;
599static int hf_mqtt_prop_key;
600static int hf_mqtt_prop_value_len;
601static int hf_mqtt_prop_value;
602
603/* Initialize the subtree pointers */
604static int ett_mqtt_hdr;
605static int ett_mqtt_msg;
606static int ett_mqtt_hdr_flags;
607static int ett_mqtt_con_flags;
608static int ett_mqtt_conack_flags;
609static int ett_mqtt_property;
610static int ett_mqtt_subscription_flags;
611
612/* Initialize the expert fields */
613static expert_field ei_illegal_length;
614static expert_field ei_unknown_version;
615static expert_field ei_unknown_topic_alias;
616
617/* Reassemble SMPP TCP segments */
618static bool_Bool reassemble_mqtt_over_tcp = true1;
619
620/* Show Publish Message as text */
621static bool_Bool show_msg_as_text;
622
623static unsigned get_mqtt_pdu_len(packet_info *pinfo _U___attribute__((unused)), tvbuff_t *tvb,
624 int offset, void *data _U___attribute__((unused)))
625{
626 uint64_t msg_len;
627 unsigned len_offset;
628
629 len_offset = tvb_get_varint(tvb, (offset + MQTT_HDR_SIZE_BEFORE_LEN1), FT_VARINT_MAX_LEN10, &msg_len, ENC_VARINT_PROTOBUF0x00000002);
630
631 /* Explicitly downcast the value, because the length can never be more than 4 bytes */
632 return (unsigned)(msg_len + len_offset + MQTT_HDR_SIZE_BEFORE_LEN1);
633}
634
635static void *mqtt_message_decode_copy_cb(void *dest, const void *orig, size_t len _U___attribute__((unused)))
636{
637 const mqtt_message_decode_t *o = (const mqtt_message_decode_t *)orig;
638 mqtt_message_decode_t *d = (mqtt_message_decode_t *)dest;
639
640 d->match_criteria = o->match_criteria;
641 d->topic_pattern = g_strdup(o->topic_pattern)g_strdup_inline (o->topic_pattern);
642 d->msg_decoding = o->msg_decoding;
643 d->payload_proto_name = g_strdup(o->payload_proto_name)g_strdup_inline (o->payload_proto_name);
644 d->payload_proto = o->payload_proto;
645
646 return d;
647}
648
649static bool_Bool mqtt_message_decode_update_cb(void *record, char **error)
650{
651 mqtt_message_decode_t *u = (mqtt_message_decode_t *)record;
652
653 if (u->topic_pattern == NULL((void*)0) || strlen(u->topic_pattern) == 0)
654 {
655 *error = g_strdup("Missing topic pattern")g_strdup_inline ("Missing topic pattern");
656 return false0;
657 }
658
659 if (u->payload_proto_name == NULL((void*)0) || strlen(u->payload_proto_name) == 0)
660 {
661 *error = g_strdup("Missing payload protocol")g_strdup_inline ("Missing payload protocol");
662 return false0;
663 }
664
665 if (u->match_criteria == MATCH_CRITERIA_REGEX4)
666 {
667 u->topic_regex = g_regex_new(u->topic_pattern, (GRegexCompileFlags) G_REGEX_OPTIMIZE, (GRegexMatchFlags) 0, NULL((void*)0));
668 if (!u->topic_regex)
669 {
670 *error = ws_strdup_printf("Invalid regex: %s", u->topic_pattern)wmem_strdup_printf(((void*)0), "Invalid regex: %s", u->topic_pattern
)
;
671 return false0;
672 }
673 }
674
675 return true1;
676}
677
678static void mqtt_message_decode_free_cb(void *record)
679{
680 mqtt_message_decode_t *u = (mqtt_message_decode_t *)record;
681
682 g_free(u->topic_pattern)(__builtin_object_size ((u->topic_pattern), 0) != ((size_t
) - 1)) ? g_free_sized (u->topic_pattern, __builtin_object_size
((u->topic_pattern), 0)) : (g_free) (u->topic_pattern)
;
683 if (u->topic_regex)
684 {
685 g_regex_unref(u->topic_regex);
686 }
687 g_free(u->payload_proto_name)(__builtin_object_size ((u->payload_proto_name), 0) != ((size_t
) - 1)) ? g_free_sized (u->payload_proto_name, __builtin_object_size
((u->payload_proto_name), 0)) : (g_free) (u->payload_proto_name
)
;
688}
689
690UAT_VS_DEF(message_decode, match_criteria, mqtt_message_decode_t, unsigned, MATCH_CRITERIA_EQUAL, "Equal to")static void message_decode_match_criteria_set_cb(void* rec, const
char* buf, unsigned len, const void* vs, const void* u2 __attribute__
((unused))) { unsigned i; char* str = g_strndup(buf,len); const
char* cstr; ((mqtt_message_decode_t*)rec)->match_criteria
= 0; for(i=0; ( cstr = ((const value_string*)vs)[i].strptr )
;i++) { if ((strcmp ((const char *) (cstr), (const char *) (
str)) == 0)) { ((mqtt_message_decode_t*)rec)->match_criteria
= (unsigned)((const value_string*)vs)[i].value; (__builtin_object_size
((str), 0) != ((size_t) - 1)) ? g_free_sized (str, __builtin_object_size
((str), 0)) : (g_free) (str); return; } } (__builtin_object_size
((str), 0) != ((size_t) - 1)) ? g_free_sized (str, __builtin_object_size
((str), 0)) : (g_free) (str); } static void message_decode_match_criteria_tostr_cb
(void* rec, char** out_ptr, unsigned* out_len, const void* vs
, const void* u2 __attribute__((unused))) { unsigned i; for(i
=0;((const value_string*)vs)[i].strptr;i++) { if ( ((const value_string
*)vs)[i].value == ((mqtt_message_decode_t*)rec)->match_criteria
) { *out_ptr = g_strdup_inline (((const value_string*)vs)[i]
.strptr); *out_len = (unsigned)strlen(*out_ptr); return; } } *
out_ptr = g_strdup_inline ("Equal to"); *out_len = (unsigned)
strlen("Equal to"); }
691UAT_CSTRING_CB_DEF(message_decode, topic_pattern, mqtt_message_decode_t)static void message_decode_topic_pattern_set_cb(void* rec, const
char* buf, unsigned len, const void* u1 __attribute__((unused
)), const void* u2 __attribute__((unused))) { char* new_buf =
g_strndup(buf,len); (__builtin_object_size (((((mqtt_message_decode_t
*)rec)->topic_pattern)), 0) != ((size_t) - 1)) ? g_free_sized
((((mqtt_message_decode_t*)rec)->topic_pattern), __builtin_object_size
(((((mqtt_message_decode_t*)rec)->topic_pattern)), 0)) : (
g_free) ((((mqtt_message_decode_t*)rec)->topic_pattern)); (
((mqtt_message_decode_t*)rec)->topic_pattern) = new_buf; }
static void message_decode_topic_pattern_tostr_cb(void* rec,
char** out_ptr, unsigned* out_len, const void* u1 __attribute__
((unused)), const void* u2 __attribute__((unused))) { if (((mqtt_message_decode_t
*)rec)->topic_pattern ) { *out_ptr = g_strdup_inline ((((mqtt_message_decode_t
*)rec)->topic_pattern)); *out_len = (unsigned)strlen((((mqtt_message_decode_t
*)rec)->topic_pattern)); } else { *out_ptr = g_strdup_inline
(""); *out_len = 0; } }
692UAT_VS_DEF(message_decode, msg_decoding, mqtt_message_decode_t, unsigned, MSG_DECODING_NONE, "none")static void message_decode_msg_decoding_set_cb(void* rec, const
char* buf, unsigned len, const void* vs, const void* u2 __attribute__
((unused))) { unsigned i; char* str = g_strndup(buf,len); const
char* cstr; ((mqtt_message_decode_t*)rec)->msg_decoding =
0; for(i=0; ( cstr = ((const value_string*)vs)[i].strptr ) ;
i++) { if ((strcmp ((const char *) (cstr), (const char *) (str
)) == 0)) { ((mqtt_message_decode_t*)rec)->msg_decoding = (
unsigned)((const value_string*)vs)[i].value; (__builtin_object_size
((str), 0) != ((size_t) - 1)) ? g_free_sized (str, __builtin_object_size
((str), 0)) : (g_free) (str); return; } } (__builtin_object_size
((str), 0) != ((size_t) - 1)) ? g_free_sized (str, __builtin_object_size
((str), 0)) : (g_free) (str); } static void message_decode_msg_decoding_tostr_cb
(void* rec, char** out_ptr, unsigned* out_len, const void* vs
, const void* u2 __attribute__((unused))) { unsigned i; for(i
=0;((const value_string*)vs)[i].strptr;i++) { if ( ((const value_string
*)vs)[i].value == ((mqtt_message_decode_t*)rec)->msg_decoding
) { *out_ptr = g_strdup_inline (((const value_string*)vs)[i]
.strptr); *out_len = (unsigned)strlen(*out_ptr); return; } } *
out_ptr = g_strdup_inline ("none"); *out_len = (unsigned)strlen
("none"); }
693UAT_DISSECTOR_DEF(message_decode, payload_proto, payload_proto, payload_proto_name, mqtt_message_decode_t)static void message_decode_payload_proto_set_cb(void* rec, const
char* buf, unsigned len, const void* u1 __attribute__((unused
)), const void* u2 __attribute__((unused))) { if (len) { ((mqtt_message_decode_t
*)rec)->payload_proto_name = g_strndup(buf, len); g_strchomp
(g_strchug (((mqtt_message_decode_t*)rec)->payload_proto_name
)); ((mqtt_message_decode_t*)rec)->payload_proto = find_dissector
(((mqtt_message_decode_t*)rec)->payload_proto_name); } else
{ ((mqtt_message_decode_t*)rec)->payload_proto = find_dissector
("data"); ((mqtt_message_decode_t*)rec)->payload_proto_name
= ((void*)0); } } static void message_decode_payload_proto_tostr_cb
(void* rec, char** out_ptr, unsigned* out_len, const void* u1
__attribute__((unused)), const void* u2 __attribute__((unused
))) { if ( ((mqtt_message_decode_t*)rec)->payload_proto_name
) { *out_ptr = g_strdup_inline ((((mqtt_message_decode_t*)rec
)->payload_proto_name)); *out_len = (unsigned)strlen(*out_ptr
); } else { *out_ptr = g_strdup_inline (""); *out_len = 0; } }
694
695static bool_Bool mqtt_user_decode_message(proto_tree *tree, proto_tree *mqtt_tree, packet_info *pinfo, const char *topic_str, tvbuff_t *msg_tvb)
696{
697 mqtt_message_decode_t *message_decode_entry = NULL((void*)0);
698 size_t topic_str_len = strlen(topic_str);
699 size_t topic_pattern_len;
700 bool_Bool match_found = false0;
701
702 if (topic_str_len == 0)
703 {
704 /* No topic to match */
705 return false0;
706 }
707
708 for (unsigned i = 0; i < num_mqtt_message_decodes && !match_found; i++)
709 {
710 message_decode_entry = &mqtt_message_decodes[i];
711 switch (message_decode_entry->match_criteria)
712 {
713 case MATCH_CRITERIA_EQUAL0:
714 match_found = (strcmp(topic_str, message_decode_entry->topic_pattern) == 0);
715 break;
716 case MATCH_CRITERIA_CONTAINS1:
717 match_found = (strstr(topic_str, message_decode_entry->topic_pattern) != NULL((void*)0));
718 break;
719 case MATCH_CRITERIA_STARTS_WITH2:
720 topic_pattern_len = strlen(message_decode_entry->topic_pattern);
721 match_found = ((topic_str_len >= topic_pattern_len) &&
722 (strncmp(topic_str, message_decode_entry->topic_pattern, topic_pattern_len) == 0));
723 break;
724 case MATCH_CRITERIA_ENDS_WITH3:
725 topic_pattern_len = strlen(message_decode_entry->topic_pattern);
726 match_found = ((topic_str_len >= topic_pattern_len) &&
727 (strcmp(topic_str + (topic_str_len - topic_pattern_len), message_decode_entry->topic_pattern) == 0));
728 break;
729 case MATCH_CRITERIA_REGEX4:
730 if (message_decode_entry->topic_regex)
731 {
732 GMatchInfo *match_info = NULL((void*)0);
733 /* DISSECTOR_ASSERT(g_utf8_validate(topic_str, -1, NULL)); */
734 g_regex_match(message_decode_entry->topic_regex, topic_str, (GRegexMatchFlags) 0, &match_info);
735 match_found = g_match_info_matches(match_info);
736 g_match_info_free(match_info);
737 }
738 break;
739 default:
740 /* Unknown match criteria */
741 break;
742 }
743 }
744
745 if (match_found)
746 {
747 if (message_decode_entry->msg_decoding == MSG_DECODING_COMPRESSED1)
748 {
749 msg_tvb = tvb_child_uncompress_zlib(msg_tvb, msg_tvb, 0, tvb_reported_length(msg_tvb));
750 if (msg_tvb)
751 {
752 add_new_data_source(pinfo, msg_tvb, "Uncompressed Message");
753 }
754 }
755
756 if (msg_tvb)
757 {
758 proto_item *ti = proto_tree_add_string(mqtt_tree, hf_mqtt_pubmsg_decoded, msg_tvb, 0, -1,
759 message_decode_entry->payload_proto_name);
760 proto_item_set_generated(ti);
761
762 call_dissector(message_decode_entry->payload_proto, msg_tvb, pinfo, tree);
763 }
764 }
765
766 return match_found;
767}
768
769static unsigned dissect_string(tvbuff_t *tvb, proto_tree *tree, unsigned offset, int hf_len, int hf_value)
770{
771 uint32_t prop_len;
772
773 proto_tree_add_item_ret_uint(tree, hf_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &prop_len);
774 proto_tree_add_item(tree, hf_value, tvb, offset + 2, prop_len, ENC_UTF_80x00000002|ENC_NA0x00000000);
775
776 return 2 + prop_len;
777}
778
779/* MQTT v5.0: Reason Codes */
780static void dissect_mqtt_reason_code(proto_tree *mqtt_tree, tvbuff_t *tvb, unsigned offset, uint8_t mqtt_msg_type)
781{
782 static int * const hf_rcode[] = {
783 NULL((void*)0), /* RESERVED */
784 NULL((void*)0), /* CONNECT */
785 &hf_mqtt_reason_code_connack,
786 NULL((void*)0), /* PUBLISH */
787 &hf_mqtt_reason_code_puback,
788 &hf_mqtt_reason_code_pubrec,
789 &hf_mqtt_reason_code_pubrel,
790 &hf_mqtt_reason_code_pubcomp,
791 NULL((void*)0), /* SUBSCRIBE */
792 &hf_mqtt_reason_code_suback,
793 NULL((void*)0), /* UNSUBSCRIBE */
794 &hf_mqtt_reason_code_unsuback,
795 NULL((void*)0), /* PINGREQ */
796 NULL((void*)0), /* PINGRESP */
797 &hf_mqtt_reason_code_disconnect,
798 &hf_mqtt_reason_code_auth
799 };
800
801 if (mqtt_msg_type < array_length(hf_rcode)(sizeof (hf_rcode) / sizeof (hf_rcode)[0]))
802 {
803 const int *hfindex = hf_rcode[mqtt_msg_type];
804 if (hfindex)
805 {
806 proto_tree_add_item(mqtt_tree, *hfindex, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
807 }
808 }
809}
810
811/* MQTT v5.0: dissect the MQTT properties */
812static unsigned dissect_mqtt_properties(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mqtt_tree, unsigned offset, int hf_property, mqtt_properties_t *mqtt_properties)
813{
814 proto_tree *mqtt_prop_tree;
815 proto_item *ti;
816 uint64_t vbi;
817
818 const unsigned mqtt_prop_offset = tvb_get_varint(tvb, offset, FT_VARINT_MAX_LEN10, &vbi, ENC_VARINT_PROTOBUF0x00000002);
819 /* Property Length field can be stored in uint32 */
820 unsigned mqtt_prop_len = (unsigned)vbi;
821 const unsigned remaining = tvb_reported_length_remaining(tvb, offset + mqtt_prop_offset);
822 if (vbi > remaining)
823 {
824 mqtt_prop_len = remaining;
825 expert_add_info(pinfo, mqtt_tree, &ei_illegal_length);
826 }
827
828 /* Add the MQTT branch to the main tree */
829 /* hf_property is usually hf_mqtt_property, but can also be
830 * hf_mqtt_will_property when a Will is provided in a CONNECT packet */
831 ti = proto_tree_add_item(mqtt_tree, hf_property, tvb, offset, mqtt_prop_offset + mqtt_prop_len, ENC_NA0x00000000);
832 mqtt_prop_tree = proto_item_add_subtree(ti, ett_mqtt_property);
833
834 proto_tree_add_item(mqtt_prop_tree, hf_mqtt_property_len, tvb, offset, mqtt_prop_offset, ENC_VARINT_PROTOBUF0x00000002);
835 offset += mqtt_prop_offset;
836
837 const unsigned bytes_to_read = offset + mqtt_prop_len;
838 while (offset < bytes_to_read)
839 {
840 uint32_t prop_id;
841 proto_tree_add_item_ret_uint(mqtt_prop_tree, hf_mqtt_property_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &prop_id);
842 offset += 1;
843
844 switch (prop_id)
845 {
846 case PROP_PAYLOAD_FORMAT_INDICATOR0x01:
847 case PROP_REQUEST_PROBLEM_INFORMATION0x17:
848 case PROP_REQUEST_RESPONSE_INFORMATION0x19:
849 case PROP_RETAIN_AVAILABLE0x25:
850 case PROP_WILDCARD_SUBSCRIPTION_AVAILABLE0x28:
851 case PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE0x29:
852 case PROP_SHARED_SUBSCRIPTION_AVAILABLE0x2A:
853 proto_tree_add_item(mqtt_prop_tree, hf_mqtt_prop_num, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
854 offset += 1;
855 break;
856
857 case PROP_MAXIMUM_QOS0x24:
858 proto_tree_add_item(mqtt_prop_tree, hf_mqtt_prop_max_qos, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
859 offset += 1;
860 break;
861
862 case PROP_TOPIC_ALIAS0x23:
863 proto_tree_add_item_ret_uint(mqtt_prop_tree, hf_mqtt_prop_topic_alias, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_properties->topic_alias);
864 offset += 2;
865 break;
866
867 case PROP_SERVER_KEEP_ALIVE0x13:
868 case PROP_RECEIVE_MAXIMUM0x21:
869 case PROP_TOPIC_ALIAS_MAXIMUM0x22:
870 proto_tree_add_item(mqtt_prop_tree, hf_mqtt_prop_num, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
871 offset += 2;
872 break;
873
874 case PROP_PUBLICATION_EXPIRY_INTERVAL0x02:
875 case PROP_SESSION_EXPIRY_INTERVAL0x11:
876 case PROP_WILL_DELAY_INTERVAL0x18:
877 case PROP_MAXIMUM_PACKET_SIZE0x27:
878 proto_tree_add_item(mqtt_prop_tree, hf_mqtt_prop_num, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
879 offset += 4;
880 break;
881
882 case PROP_SUBSCRIPTION_IDENTIFIER0x0B:
883 {
884 unsigned vbi_len;
885 proto_tree_add_item_ret_length(mqtt_prop_tree, hf_mqtt_prop_num, tvb, offset, -1, ENC_LITTLE_ENDIAN0x80000000|ENC_VARINT_PROTOBUF0x00000002, &vbi_len);
886 offset += vbi_len;
887 break;
888 }
889
890 case PROP_CONTENT_TYPE0x03:
891 {
892 unsigned length;
893 proto_tree_add_item_ret_string_and_length(mqtt_prop_tree, hf_mqtt_prop_content_type, tvb, offset, 2, ENC_UTF_80x00000002, pinfo->pool, (const uint8_t**)&mqtt_properties->content_type, &length);
894 offset += length;
895 break;
896 }
897
898 case PROP_RESPONSE_TOPIC0x08:
899 case PROP_CORRELATION_DATA0x09:
900 case PROP_ASSIGNED_CLIENT_IDENTIFIER0x12:
901 case PROP_AUTH_METHOD0x15:
902 case PROP_AUTH_DATA0x16:
903 case PROP_RESPONSE_INFORMATION0x1A:
904 case PROP_SERVER_REFERENCE0x1C:
905 case PROP_REASON_STRING0x1F:
906 offset += dissect_string(tvb, mqtt_prop_tree, offset, hf_mqtt_prop_string_len, hf_mqtt_prop_string);
907 break;
908
909 case PROP_USER_PROPERTY0x26:
910 offset += dissect_string(tvb, mqtt_prop_tree, offset, hf_mqtt_prop_key_len, hf_mqtt_prop_key);
911 offset += dissect_string(tvb, mqtt_prop_tree, offset, hf_mqtt_prop_value_len, hf_mqtt_prop_value);
912 break;
913
914 default:
915 proto_tree_add_item(mqtt_prop_tree, hf_mqtt_prop_unknown, tvb, offset, bytes_to_read - offset, ENC_UTF_80x00000002);
916 offset += (bytes_to_read - offset);
917 break;
918 }
919 }
920
921 return mqtt_prop_offset + mqtt_prop_len;
922}
923
924/* Dissect the MQTT message */
925static int dissect_mqtt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U___attribute__((unused)))
926{
927 uint8_t mqtt_fixed_hdr;
928 uint8_t mqtt_msg_type;
929 proto_item *ti;
930 const char *topic_str = "";
931 proto_item *mqtt_ti;
932 proto_tree *mqtt_tree;
933 uint64_t mqtt_con_flags;
934 uint64_t msg_len = 0;
935 int mqtt_msg_len = 0;
936 uint32_t mqtt_str_len;
937 uint16_t mqtt_len_offset;
938 int mqtt_payload_len;
939 uint32_t mqtt_msgid;
940 conversation_t *conv;
941 mqtt_conv_t *mqtt;
942 mqtt_conv_t saved_mqtt;
943 mqtt_pdu_data_t *pdu_data;
944 unsigned pdu_idx = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_mqtt, 0))((guint) (gulong) (p_get_proto_data(pinfo->pool, pinfo, proto_mqtt
, 0)))
;
945 mqtt_properties_t mqtt_properties = { 0 };
946 mqtt_properties_t mqtt_will_properties = { 0 };
947 unsigned offset = 0;
948 bool_Bool msg_handled = false0;
949
950 static int * const publish_fields[] = {
951 &hf_mqtt_msg_type,
952 &hf_mqtt_dup_flag,
953 &hf_mqtt_qos_level,
954 &hf_mqtt_retain,
955 NULL((void*)0)
956 };
957
958 static int * const v31_pubrel_sub_unsub_fields[] = {
959 &hf_mqtt_msg_type,
960 &hf_mqtt_dup_flag,
961 &hf_mqtt_qos_level,
962 &hf_mqtt_retain_reserved,
963 NULL((void*)0)
964 };
965
966 static int * const other_fields[] = {
967 &hf_mqtt_msg_type,
968 &hf_mqtt_reserved,
969 NULL((void*)0)
970 };
971
972 static int * const connect_flags[] = {
973 &hf_mqtt_conflag_user,
974 &hf_mqtt_conflag_passwd,
975 &hf_mqtt_conflag_will_retain,
976 &hf_mqtt_conflag_will_qos,
977 &hf_mqtt_conflag_will_flag,
978 &hf_mqtt_conflag_clean_sess,
979 &hf_mqtt_conflag_reserved,
980 NULL((void*)0)
981 };
982
983 static int * const connack_flags[] = {
984 &hf_mqtt_conackflag_reserved,
985 &hf_mqtt_conackflag_sp,
986 NULL((void*)0)
987 };
988
989 static int * const v50_subscription_flags[] = {
990 &hf_mqtt_subscription_reserved,
991 &hf_mqtt_subscription_retain,
992 &hf_mqtt_subscription_rap,
993 &hf_mqtt_subscription_nl,
994 &hf_mqtt_subscription_qos,
995 NULL((void*)0)
996 };
997
998 /* Extract the message ID */
999 /* A TCP frame may contain several PDUs, including reassembled PDUs. */
1000 p_set_proto_data(pinfo->pool, pinfo, proto_mqtt, 0, GUINT_TO_POINTER(pdu_idx + 1)((gpointer) (gulong) (pdu_idx + 1)));
1001
1002 mqtt_fixed_hdr = tvb_get_uint8(tvb, offset);
1003 mqtt_msg_type = mqtt_fixed_hdr >> 4;
1004
1005 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MQTT");
1006 col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", val_to_str_ext(pinfo->pool, mqtt_msg_type, &mqtt_msgtype_vals_ext, "Unknown (0x%02x)"));
1007
1008 /* Add the MQTT branch to the main tree */
1009 mqtt_ti = proto_tree_add_item(tree, proto_mqtt, tvb, 0, -1, ENC_NA0x00000000);
1010 mqtt_tree = proto_item_add_subtree(mqtt_ti, ett_mqtt_hdr);
1011
1012 conv = find_or_create_conversation(pinfo);
1013 mqtt = (mqtt_conv_t *)conversation_get_proto_data(conv, proto_mqtt);
1014 if (mqtt == NULL((void*)0))
1
Assuming 'mqtt' is equal to NULL
2
Taking true branch
1015 {
1016 mqtt = wmem_new0(wmem_file_scope(), mqtt_conv_t)((mqtt_conv_t*)wmem_alloc0((wmem_file_scope()), sizeof(mqtt_conv_t
)))
;
1017 mqtt->runtime_proto_version = default_protocol_version;
1018 conversation_add_proto_data(conv, proto_mqtt, mqtt);
1019 mqtt->topic_alias_map = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
1020 }
1021
1022 mqtt_len_offset = tvb_get_varint(tvb, (offset + MQTT_HDR_SIZE_BEFORE_LEN1), FT_VARINT_MAX_LEN10, &msg_len, ENC_VARINT_PROTOBUF0x00000002);
1023
1024 /* Explicit downcast, typically maximum length of message could be 4 bytes */
1025 mqtt_msg_len = (int) msg_len;
1026
1027 /* Add the type to the MQTT tree item */
1028 proto_item_append_text(mqtt_tree, ", %s", val_to_str_ext(pinfo->pool, mqtt_msg_type, &mqtt_msgtype_vals_ext, "Unknown (0x%02x)"));
1029
1030 /* Save each PDU's initial state, including an unresolved topic alias. */
1031 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited))
3
Assuming field 'visited' is not equal to 0
4
Taking false branch
1032 {
1033 pdu_data = wmem_new0(wmem_file_scope(), mqtt_pdu_data_t)((mqtt_pdu_data_t*)wmem_alloc0((wmem_file_scope()), sizeof(mqtt_pdu_data_t
)))
;
1034 pdu_data->version = mqtt->runtime_proto_version;
1035 p_add_proto_data(wmem_file_scope(), pinfo, proto_mqtt, pdu_idx, pdu_data);
1036 }
1037 else
1038 {
1039 pdu_data = (mqtt_pdu_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mqtt, pdu_idx);
5
Value assigned to 'pdu_data'
1040 saved_mqtt = *mqtt;
1041 mqtt = &saved_mqtt;
1042 if (pdu_data != NULL((void*)0))
6
Assuming 'pdu_data' is equal to NULL
1043 mqtt->runtime_proto_version = pdu_data->version;
1044 }
1045
1046 if ((mqtt_msg_type != MQTT_CONNECT1) && (mqtt->runtime_proto_version == 0))
7
Assuming 'mqtt_msg_type' is not equal to MQTT_CONNECT
8
Assuming field 'runtime_proto_version' is not equal to 0
9
Taking false branch
1047 {
1048 expert_add_info(pinfo, mqtt_ti, &ei_unknown_version);
1049 }
1050
1051 if (mqtt_msg_type == MQTT_PUBLISH3)
10
Assuming 'mqtt_msg_type' is equal to MQTT_PUBLISH
11
Taking true branch
1052 {
1053 proto_tree_add_bitmask(mqtt_tree, tvb, offset, hf_mqtt_hdrflags, ett_mqtt_hdr_flags, publish_fields, ENC_BIG_ENDIAN0x00000000);
1054 }
1055 else if (mqtt->runtime_proto_version == MQTT_PROTO_V313 &&
1056 (mqtt_msg_type == MQTT_PUBREL6 ||
1057 mqtt_msg_type == MQTT_SUBSCRIBE8 ||
1058 mqtt_msg_type == MQTT_UNSUBSCRIBE10))
1059 {
1060 proto_tree_add_bitmask(mqtt_tree, tvb, offset, hf_mqtt_hdrflags, ett_mqtt_hdr_flags, v31_pubrel_sub_unsub_fields, ENC_BIG_ENDIAN0x00000000);
1061 }
1062 else
1063 {
1064 proto_tree_add_bitmask(mqtt_tree, tvb, offset, hf_mqtt_hdrflags, ett_mqtt_hdr_flags, other_fields, ENC_BIG_ENDIAN0x00000000);
1065 }
1066
1067 offset += 1;
1068
1069 /* Add the MQTT message length */
1070 proto_tree_add_uint64(mqtt_tree, hf_mqtt_msg_len, tvb, offset, mqtt_len_offset, msg_len);
1071 offset += mqtt_len_offset;
1072
1073 switch (mqtt_msg_type)
12
Control jumps to 'case 3:' at line 1188
1074 {
1075 case MQTT_CONNECT1:
1076 proto_tree_add_item_ret_uint(mqtt_tree, hf_mqtt_proto_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_str_len);
1077 offset += 2;
1078
1079 proto_tree_add_item(mqtt_tree, hf_mqtt_proto_name, tvb, offset, mqtt_str_len, ENC_UTF_80x00000002);
1080 offset += mqtt_str_len;
1081
1082 mqtt->runtime_proto_version = tvb_get_uint8(tvb, offset);
1083
1084 proto_tree_add_item(mqtt_tree, hf_mqtt_proto_ver, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1085 offset += 1;
1086
1087 proto_tree_add_bitmask_ret_uint64(mqtt_tree, tvb, offset, hf_mqtt_conflags,
1088 ett_mqtt_con_flags, connect_flags, ENC_BIG_ENDIAN0x00000000, &mqtt_con_flags);
1089 offset += 1;
1090
1091 proto_tree_add_item(mqtt_tree, hf_mqtt_keep_alive, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
1092 offset += 2;
1093
1094 if (mqtt->runtime_proto_version == MQTT_PROTO_V505)
1095 {
1096 offset += dissect_mqtt_properties(tvb, pinfo, mqtt_tree, offset, hf_mqtt_property, &mqtt_properties);
1097 }
1098
1099 proto_tree_add_item_ret_uint(mqtt_tree, hf_mqtt_client_id_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_str_len);
1100 offset += 2;
1101
1102 proto_tree_add_item(mqtt_tree, hf_mqtt_client_id, tvb, offset, mqtt_str_len, ENC_UTF_80x00000002);
1103 offset += mqtt_str_len;
1104
1105 if (mqtt_con_flags & MQTT_CONMASK_WILLFLAG0x04)
1106 {
1107 if (mqtt->runtime_proto_version == MQTT_PROTO_V505)
1108 {
1109 offset += dissect_mqtt_properties(tvb, pinfo, mqtt_tree, offset, hf_mqtt_will_property, &mqtt_will_properties);
1110 }
1111
1112 ti = proto_tree_add_item_ret_uint(mqtt_tree, hf_mqtt_will_topic_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_str_len);
1113 offset += 2;
1114
1115 if (mqtt_str_len > 0)
1116 {
1117 proto_tree_add_item(mqtt_tree, hf_mqtt_will_topic, tvb, offset, mqtt_str_len, ENC_UTF_80x00000002);
1118 offset += mqtt_str_len;
1119 }
1120 else
1121 {
1122 expert_add_info(pinfo, ti, &ei_illegal_length);
1123 }
1124
1125 proto_tree_add_item_ret_uint(mqtt_tree, hf_mqtt_will_msg_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_str_len);
1126 offset += 2;
1127
1128 if (show_msg_as_text)
1129 {
1130 proto_tree_add_item(mqtt_tree, hf_mqtt_will_msg_text, tvb, offset, mqtt_str_len, ENC_UTF_80x00000002);
1131 }
1132 else
1133 {
1134 proto_tree_add_item(mqtt_tree, hf_mqtt_will_msg, tvb, offset, mqtt_str_len, ENC_NA0x00000000);
1135 }
1136 offset += mqtt_str_len;
1137 }
1138
1139 if ((mqtt_con_flags & MQTT_CONMASK_USER0x80) && (tvb_reported_length_remaining(tvb, offset) > 0))
1140 {
1141 proto_tree_add_item_ret_uint(mqtt_tree, hf_mqtt_username_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_str_len);
1142 offset += 2;
1143
1144 proto_tree_add_item(mqtt_tree, hf_mqtt_username, tvb, offset, mqtt_str_len, ENC_UTF_80x00000002);
1145 offset += mqtt_str_len;
1146 }
1147
1148 if ((mqtt_con_flags & MQTT_CONMASK_PASSWD0x40) && (tvb_reported_length_remaining(tvb, offset) > 0))
1149 {
1150 proto_tree_add_item_ret_uint(mqtt_tree, hf_mqtt_passwd_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_str_len);
1151 offset += 2;
1152
1153 proto_tree_add_item(mqtt_tree, hf_mqtt_passwd, tvb, offset, mqtt_str_len, ENC_UTF_80x00000002);
1154 }
1155 break;
1156
1157 case MQTT_CONNACK2:
1158 if (mqtt->runtime_proto_version == MQTT_PROTO_V313)
1159 {
1160 /* v3.1 Connection Ack only contains a reserved byte and the Return Code. */
1161 proto_tree_add_item(mqtt_tree, hf_mqtt_conack_reserved, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1162 }
1163 else
1164 {
1165 /* v3.1.1 Conn Ack contains the Conn Ack Flags and the Return Code. */
1166 proto_tree_add_bitmask(mqtt_tree, tvb, offset, hf_mqtt_conack_flags,
1167 ett_mqtt_conack_flags, connack_flags, ENC_BIG_ENDIAN0x00000000);
1168 }
1169 offset += 1;
1170
1171 if ((mqtt->runtime_proto_version == MQTT_PROTO_V313) ||
1172 (mqtt->runtime_proto_version == MQTT_PROTO_V3114))
1173 {
1174 proto_tree_add_item(mqtt_tree, hf_mqtt_conack_code, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1175 }
1176 else
1177 {
1178 dissect_mqtt_reason_code(mqtt_tree, tvb, offset, mqtt_msg_type);
1179 }
1180 offset += 1;
1181
1182 if (mqtt->runtime_proto_version == MQTT_PROTO_V505)
1183 {
1184 offset += dissect_mqtt_properties(tvb, pinfo, mqtt_tree, offset, hf_mqtt_property, &mqtt_properties);
1185 }
1186 break;
1187
1188 case MQTT_PUBLISH3:
1189 /* TopicName|MsgID|Message| */
1190 ti = proto_tree_add_item_ret_uint(mqtt_tree, hf_mqtt_topic_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_str_len);
1191 offset += 2;
1192
1193 if (mqtt_str_len > 0)
13
Assuming 'mqtt_str_len' is <= 0
14
Taking false branch
1194 {
1195 /* 'topic_regex' requires topic_str to be valid UTF-8. */
1196 proto_tree_add_item_ret_string(mqtt_tree, hf_mqtt_topic, tvb, offset, mqtt_str_len, ENC_UTF_80x00000002|ENC_NA0x00000000,
1197 pinfo->pool, (const uint8_t**)&topic_str);
1198 offset += mqtt_str_len;
1199 }
1200
1201 /* Message ID is included only when QoS > 0 */
1202 if (mqtt_fixed_hdr & MQTT_MASK_QOS0x06)
15
Assuming the condition is false
16
Taking false branch
1203 {
1204 proto_tree_add_item_ret_uint(mqtt_tree, hf_mqtt_msgid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_msgid);
1205 offset += 2;
1206 col_append_fstr(pinfo->cinfo, COL_INFO, " (id=%u)", mqtt_msgid);
1207 }
1208
1209 if (mqtt->runtime_proto_version == MQTT_PROTO_V505)
17
Assuming field 'runtime_proto_version' is equal to MQTT_PROTO_V50
18
Taking true branch
1210 {
1211 offset += dissect_mqtt_properties(tvb, pinfo, mqtt_tree, offset, hf_mqtt_property, &mqtt_properties);
1212
1213 if (mqtt_properties.topic_alias != 0)
19
Assuming field 'topic_alias' is not equal to 0
20
Taking true branch
1214 {
1215 char *topic = NULL((void*)0);
1216 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited))
21
Assuming field 'visited' is 0
22
Taking true branch
1217 {
1218 if (mqtt_str_len
22.1
'mqtt_str_len' is <= 0
> 0)
23
Taking false branch
1219 {
1220 topic = wmem_strdup(wmem_file_scope(), topic_str);
1221 wmem_map_insert(mqtt->topic_alias_map, GUINT_TO_POINTER(mqtt_properties.topic_alias)((gpointer) (gulong) (mqtt_properties.topic_alias)), topic);
1222 }
1223 else
1224 {
1225 topic = (char *)wmem_map_lookup(mqtt->topic_alias_map, GUINT_TO_POINTER(mqtt_properties.topic_alias)((gpointer) (gulong) (mqtt_properties.topic_alias)));
1226 }
1227 pdu_data->topic = topic;
24
Access to field 'topic' results in a dereference of a null pointer (loaded from variable 'pdu_data')
1228 }
1229 else if (pdu_data != NULL((void*)0))
1230 {
1231 topic = pdu_data->topic;
1232 }
1233
1234 if (mqtt_str_len == 0)
1235 {
1236 if (topic != NULL((void*)0))
1237 {
1238 topic_str = topic;
1239 }
1240
1241 ti = proto_tree_add_string(mqtt_tree, hf_mqtt_topic, tvb, offset, 0, topic_str);
1242 proto_item_set_generated(ti);
1243
1244 if (topic == NULL((void*)0))
1245 {
1246 expert_add_info(pinfo, ti, &ei_unknown_topic_alias);
1247 }
1248 }
1249 }
1250 }
1251
1252 if ((mqtt_str_len == 0) && (mqtt_properties.topic_alias == 0))
1253 {
1254 expert_add_info(pinfo, ti, &ei_illegal_length);
1255 }
1256
1257 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", topic_str);
1258
1259 mqtt_payload_len = tvb_reported_length(tvb) - offset;
1260 if (show_msg_as_text)
1261 {
1262 proto_tree_add_item(mqtt_tree, hf_mqtt_pubmsg_text, tvb, offset, mqtt_payload_len, ENC_UTF_80x00000002);
1263 }
1264 else
1265 {
1266 proto_tree_add_item(mqtt_tree, hf_mqtt_pubmsg, tvb, offset, mqtt_payload_len, ENC_NA0x00000000);
1267 }
1268
1269 if (num_mqtt_message_decodes > 0)
1270 {
1271 tvbuff_t *msg_tvb = tvb_new_subset_length(tvb, offset, mqtt_payload_len);
1272 msg_handled = mqtt_user_decode_message(tree, mqtt_tree, pinfo, topic_str, msg_tvb);
1273 }
1274
1275 if (mqtt_properties.content_type)
1276 {
1277 tvbuff_t *msg_tvb = tvb_new_subset_length(tvb, offset, mqtt_payload_len);
1278 int bytes_read = dissector_try_string_with_data(media_type_dissector_table, mqtt_properties.content_type,
1279 msg_tvb, pinfo, tree, true1, NULL((void*)0));
1280
1281 msg_handled = msg_handled | (bytes_read != 0);
1282 }
1283
1284 /* No UAT or content property match, try the heuristic dissectors, pass the topic string as data */
1285 if (!msg_handled) {
1286 heur_dtbl_entry_t *hdtbl_entry;
1287 tvbuff_t *msg_tvb = tvb_new_subset_length(tvb, offset, mqtt_payload_len);
1288 char *sub_data = wmem_strdup(pinfo->pool, (const char*)topic_str);
1289 (void) dissector_try_heuristic(mqtt_topic_subdissector, msg_tvb, pinfo, tree, &hdtbl_entry, sub_data);
1290 }
1291 break;
1292
1293 case MQTT_SUBSCRIBE8:
1294 /* After the Message Id field is found, the following fields must appear
1295 * at least once:
1296 * |TopicName|QoS|
1297 */
1298 proto_tree_add_item_ret_uint(mqtt_tree, hf_mqtt_msgid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_msgid);
1299 offset += 2;
1300 col_append_fstr(pinfo->cinfo, COL_INFO, " (id=%u)", mqtt_msgid);
1301
1302 if (mqtt->runtime_proto_version == MQTT_PROTO_V505)
1303 {
1304 offset += dissect_mqtt_properties(tvb, pinfo, mqtt_tree, offset, hf_mqtt_property, &mqtt_properties);
1305 }
1306
1307 while (offset < tvb_reported_length(tvb))
1308 {
1309 ti = proto_tree_add_item_ret_uint(mqtt_tree, hf_mqtt_topic_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_str_len);
1310 offset += 2;
1311
1312 if (mqtt_str_len > 0)
1313 {
1314 proto_tree_add_item_ret_string(mqtt_tree, hf_mqtt_topic, tvb, offset, mqtt_str_len, ENC_UTF_80x00000002|ENC_NA0x00000000,
1315 pinfo->pool, (const uint8_t**)&topic_str);
1316 offset += mqtt_str_len;
1317 }
1318 else
1319 {
1320 expert_add_info(pinfo, ti, &ei_illegal_length);
1321 }
1322
1323 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", topic_str);
1324
1325 if (mqtt->runtime_proto_version == MQTT_PROTO_V505)
1326 {
1327 proto_tree_add_bitmask(mqtt_tree, tvb, offset, hf_mqtt_subscription_options,
1328 ett_mqtt_subscription_flags, v50_subscription_flags, ENC_BIG_ENDIAN0x00000000);
1329 }
1330 else
1331 {
1332 proto_tree_add_item(mqtt_tree, hf_mqtt_sub_qos, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1333 }
1334 offset += 1;
1335 }
1336 break;
1337
1338 case MQTT_UNSUBSCRIBE10:
1339 /* After the Message Id field is found, the following fields must appear
1340 * at least once:
1341 * |TopicName|
1342 */
1343 proto_tree_add_item_ret_uint(mqtt_tree, hf_mqtt_msgid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_msgid);
1344 offset += 2;
1345 col_append_fstr(pinfo->cinfo, COL_INFO, " (id=%u)", mqtt_msgid);
1346
1347 if (mqtt->runtime_proto_version == MQTT_PROTO_V505)
1348 {
1349 offset += dissect_mqtt_properties(tvb, pinfo, mqtt_tree, offset, hf_mqtt_property, &mqtt_properties);
1350 }
1351
1352 while (offset < tvb_reported_length(tvb))
1353 {
1354 ti = proto_tree_add_item_ret_uint(mqtt_tree, hf_mqtt_topic_len, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_str_len);
1355 offset += 2;
1356
1357 if (mqtt_str_len > 0)
1358 {
1359 proto_tree_add_item(mqtt_tree, hf_mqtt_topic, tvb, offset, mqtt_str_len, ENC_UTF_80x00000002);
1360 offset += mqtt_str_len;
1361 }
1362 else
1363 {
1364 expert_add_info(pinfo, ti, &ei_illegal_length);
1365 }
1366 }
1367 break;
1368
1369 case MQTT_SUBACK9:
1370 /* The SUBACK message contains a list of granted QoS levels that come
1371 * after the Message Id field. The size of each QoS entry is 1 byte.
1372 */
1373 proto_tree_add_item_ret_uint(mqtt_tree, hf_mqtt_msgid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_msgid);
1374 offset += 2;
1375 col_append_fstr(pinfo->cinfo, COL_INFO, " (id=%u)", mqtt_msgid);
1376
1377 if (mqtt->runtime_proto_version == MQTT_PROTO_V505)
1378 {
1379 offset += dissect_mqtt_properties(tvb, pinfo, mqtt_tree, offset, hf_mqtt_property, &mqtt_properties);
1380 }
1381
1382 while (offset < tvb_reported_length(tvb))
1383 {
1384 if ((mqtt->runtime_proto_version == MQTT_PROTO_V313) ||
1385 (mqtt->runtime_proto_version == MQTT_PROTO_V3114))
1386 {
1387 proto_tree_add_item(mqtt_tree, hf_mqtt_suback_qos, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1388 }
1389 else
1390 {
1391 dissect_mqtt_reason_code(mqtt_tree, tvb, offset, mqtt_msg_type);
1392 }
1393 offset += 1;
1394 }
1395 break;
1396
1397 case MQTT_PUBACK4:
1398 case MQTT_PUBREC5:
1399 case MQTT_PUBREL6:
1400 case MQTT_PUBCOMP7:
1401 proto_tree_add_item_ret_uint(mqtt_tree, hf_mqtt_msgid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_msgid);
1402 offset += 2;
1403 col_append_fstr(pinfo->cinfo, COL_INFO, " (id=%u)", mqtt_msgid);
1404
1405 /* MQTT v5.0: The Reason Code and Property Length can be omitted if the
1406 * Reason Code is 0x00 and there are no Properties.
1407 * In this case, the PUB* has a Remaining Length of 2.
1408 */
1409 if (mqtt->runtime_proto_version == MQTT_PROTO_V505 && mqtt_msg_len > 2)
1410 {
1411 dissect_mqtt_reason_code(mqtt_tree, tvb, offset, mqtt_msg_type);
1412 offset += 1;
1413
1414 /* If the Remaining Length is less than 4, the Property Length is not
1415 * present and has a value of 0.
1416 */
1417 if (mqtt_msg_len > 3)
1418 {
1419 offset += dissect_mqtt_properties(tvb, pinfo, mqtt_tree, offset, hf_mqtt_property, &mqtt_properties);
1420 }
1421 }
1422 break;
1423
1424 case MQTT_UNSUBACK11:
1425 proto_tree_add_item_ret_uint(mqtt_tree, hf_mqtt_msgid, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000, &mqtt_msgid);
1426 offset += 2;
1427 col_append_fstr(pinfo->cinfo, COL_INFO, " (id=%u)", mqtt_msgid);
1428
1429 if (mqtt->runtime_proto_version == MQTT_PROTO_V505)
1430 {
1431 offset += dissect_mqtt_properties(tvb, pinfo, mqtt_tree, offset, hf_mqtt_property, &mqtt_properties);
1432
1433 while (offset < tvb_reported_length(tvb))
1434 {
1435 dissect_mqtt_reason_code(mqtt_tree, tvb, offset, mqtt_msg_type);
1436 offset += 1;
1437 }
1438 }
1439 break;
1440
1441 /* The following messages don't have variable header */
1442 case MQTT_PINGREQ12:
1443 case MQTT_PINGRESP13:
1444 break;
1445
1446 case MQTT_DISCONNECT14:
1447 /* MQTT v5.0: Byte 1 in the Variable Header is the Disconnect Reason Code.
1448 * If the Remaining Length is less than 1 the value of 0x00
1449 * (Normal disconnection) is used.
1450 */
1451 /* FALLTHROUGH */
1452 case MQTT_AUTH15:
1453 /* MQTT v5.0: The Reason Code and Property Length can be omitted if
1454 * the Reason Code is 0x00 (Success) and there are no Properties.
1455 * In this case the AUTH has a Remaining Length of 0.
1456 */
1457 if (mqtt->runtime_proto_version == MQTT_PROTO_V505 && mqtt_msg_len > 0)
1458 {
1459 dissect_mqtt_reason_code(mqtt_tree, tvb, offset, mqtt_msg_type);
1460 offset += 1;
1461
1462 /* 3.14.2.2 DISCONNECT Properties:
1463 * If the Remaining Length is less than 2, a value of 0 is used.
1464 * Let's assume that it also applies to AUTH, why? DISCONNECT and AUTH
1465 * share the same structure with no payload.
1466 */
1467 if (mqtt_msg_len >= 2)
1468 {
1469 offset += dissect_mqtt_properties(tvb, pinfo, mqtt_tree, offset, hf_mqtt_property, &mqtt_properties);
1470 }
1471 }
1472 break;
1473 }
1474
1475 return offset;
1476}
1477
1478/**
1479"The minimum size of MQTT Packet is 2 bytes(Ping Req, Ping Rsp,
1480Disconnect), and the maximum size is 256MB. Hence minimum fixed
1481length should be 2 bytes for tcp_dissect_pdu.
1482
1483If the length field is spread across two TCP segments, then we have a
1484problem, because exception will be raised. So long as MQTT length
1485field(although spread over 4 bytes) is present within single TCP
1486segment we shouldn't have any issue by calling tcp_dissect_pdu with
1487minimum length set to 2."
1488
1489XXX: ToDo: Commit a fix for the case of the length field spread across TCP segments.
1490**/
1491
1492static int dissect_mqtt_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1493{
1494 col_clear(pinfo->cinfo, COL_INFO);
1495
1496 tcp_dissect_pdus(tvb, pinfo, tree,
1497 reassemble_mqtt_over_tcp,
1498 2, /* Length can be determined within 5 bytes */
1499 get_mqtt_pdu_len,
1500 dissect_mqtt, data);
1501
1502 return tvb_captured_length(tvb);
1503}
1504
1505/*
1506 * Register the protocol with Wireshark
1507 */
1508void proto_register_mqtt(void)
1509{
1510 static hf_register_info hf_mqtt[] = {
1511 { &hf_mqtt_msg_len,
1512 { "Msg Len", "mqtt.len",
1513 FT_UINT64, BASE_DEC, NULL((void*)0), 0,
1514 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1515 { &hf_mqtt_hdrflags,
1516 { "Header Flags", "mqtt.hdrflags",
1517 FT_UINT8, BASE_HEX, NULL((void*)0), 0,
1518 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1519 { &hf_mqtt_msg_type,
1520 { "Message Type", "mqtt.msgtype",
1521 FT_UINT8, BASE_DEC | BASE_EXT_STRING0x00000200, &mqtt_msgtype_vals_ext, MQTT_MASK_MSG_TYPE0xF0,
1522 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1523 { &hf_mqtt_reserved,
1524 { "Reserved", "mqtt.hdr_reserved",
1525 FT_UINT8, BASE_DEC, NULL((void*)0), MQTT_MASK_HDR_RESERVED0x0F,
1526 "Fixed Header Reserved Field", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1527 { &hf_mqtt_retain_reserved,
1528 { "Reserved", "mqtt.retain_reserved",
1529 FT_UINT8, BASE_DEC, NULL((void*)0), MQTT_MASK_RETAIN0x01,
1530 "Fixed Header Reserved Field", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1531 { &hf_mqtt_dup_flag,
1532 { "DUP Flag", "mqtt.dupflag",
1533 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, MQTT_MASK_DUP_FLAG0x08,
1534 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1535 { &hf_mqtt_qos_level,
1536 { "QoS Level", "mqtt.qos",
1537 FT_UINT8, BASE_DEC, VALS(mqtt_qos_vals)((0 ? (const struct _value_string*)0 : ((mqtt_qos_vals)))), MQTT_MASK_QOS0x06,
1538 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1539 { &hf_mqtt_retain,
1540 { "Retain", "mqtt.retain",
1541 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, MQTT_MASK_RETAIN0x01,
1542 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1543 /* Conn-Ack */
1544 { &hf_mqtt_conack_reserved,
1545 { "Reserved", "mqtt.conack.flags.reserved",
1546 FT_BOOLEAN, BASE_NONE, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, 0,
1547 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1548 { &hf_mqtt_conack_flags,
1549 { "Acknowledge Flags", "mqtt.conack.flags",
1550 FT_UINT8, BASE_HEX, NULL((void*)0), 0,
1551 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1552 { &hf_mqtt_conackflag_reserved,
1553 { "Reserved", "mqtt.conack.flags.reserved",
1554 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, MQTT_CONACKMASK_RESERVED0xFE,
1555 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1556 { &hf_mqtt_conackflag_sp,
1557 { "Session Present", "mqtt.conack.flags.sp",
1558 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, MQTT_CONACKMASK_SP0x01,
1559 "Session Present (version 3.1.1)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1560 { &hf_mqtt_conack_code,
1561 { "Return Code", "mqtt.conack.val",
1562 FT_UINT8, BASE_DEC, VALS(mqtt_conack_vals)((0 ? (const struct _value_string*)0 : ((mqtt_conack_vals)))), 0,
1563 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1564 /* Publish-Ack / Publish-Rec / Publish-Rel / Publish-Comp / Unsubscribe-Ack */
1565 { &hf_mqtt_msgid,
1566 { "Message Identifier", "mqtt.msgid",
1567 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
1568 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1569 { &hf_mqtt_sub_qos,
1570 { "Requested QoS", "mqtt.sub.qos",
1571 FT_UINT8, BASE_DEC, VALS(mqtt_qos_vals)((0 ? (const struct _value_string*)0 : ((mqtt_qos_vals)))), 0,
1572 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1573 { &hf_mqtt_suback_qos,
1574 { "Granted QoS", "mqtt.suback.qos",
1575 FT_UINT8, BASE_DEC, VALS(mqtt_subqos_vals)((0 ? (const struct _value_string*)0 : ((mqtt_subqos_vals)))), 0,
1576 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1577 { &hf_mqtt_topic_len,
1578 { "Topic Length", "mqtt.topic_len",
1579 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
1580 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1581 { &hf_mqtt_topic,
1582 { "Topic", "mqtt.topic",
1583 FT_STRING, BASE_NONE, NULL((void*)0), 0,
1584 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1585 { &hf_mqtt_will_topic_len,
1586 { "Will Topic Length", "mqtt.willtopic_len",
1587 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
1588 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1589 { &hf_mqtt_will_topic,
1590 { "Will Topic", "mqtt.willtopic",
1591 FT_STRING, BASE_NONE, NULL((void*)0), 0,
1592 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1593 { &hf_mqtt_will_msg,
1594 { "Will Message", "mqtt.willmsg",
1595 FT_BYTES, BASE_NONE, NULL((void*)0), 0,
1596 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1597 { &hf_mqtt_will_msg_text,
1598 { "Will Message", "mqtt.willmsg_text",
1599 FT_STRING, BASE_NONE, NULL((void*)0), 0,
1600 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1601 { &hf_mqtt_will_msg_len,
1602 { "Will Message Length", "mqtt.willmsg_len",
1603 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
1604 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1605 { &hf_mqtt_username_len,
1606 { "User Name Length", "mqtt.username_len",
1607 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
1608 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1609 { &hf_mqtt_username,
1610 { "User Name", "mqtt.username",
1611 FT_STRING, BASE_NONE, NULL((void*)0), 0,
1612 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1613 { &hf_mqtt_passwd_len,
1614 { "Password Length", "mqtt.passwd_len",
1615 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
1616 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1617 { &hf_mqtt_passwd,
1618 { "Password", "mqtt.passwd",
1619 FT_STRING, BASE_NONE, NULL((void*)0), 0,
1620 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1621 { &hf_mqtt_pubmsg,
1622 { "Message", "mqtt.msg",
1623 FT_BYTES, BASE_NONE, NULL((void*)0), 0,
1624 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1625 { &hf_mqtt_pubmsg_text,
1626 { "Message", "mqtt.msg_text",
1627 FT_STRING, BASE_NONE, NULL((void*)0), 0,
1628 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1629 { &hf_mqtt_pubmsg_decoded,
1630 { "Message decoded as", "mqtt.msg_decoded_as",
1631 FT_STRING, BASE_NONE, NULL((void*)0), 0,
1632 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1633 { &hf_mqtt_proto_len,
1634 { "Protocol Name Length", "mqtt.proto_len",
1635 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
1636 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1637 { &hf_mqtt_proto_name,
1638 { "Protocol Name", "mqtt.protoname",
1639 FT_STRING, BASE_NONE, NULL((void*)0), 0,
1640 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1641 { &hf_mqtt_client_id_len,
1642 { "Client ID Length", "mqtt.clientid_len",
1643 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
1644 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1645 { &hf_mqtt_client_id,
1646 { "Client ID", "mqtt.clientid",
1647 FT_STRING, BASE_NONE, NULL((void*)0), 0,
1648 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1649 { &hf_mqtt_proto_ver,
1650 { "Version", "mqtt.ver",
1651 FT_UINT8, BASE_DEC, VALS(mqtt_protocol_version_vals)((0 ? (const struct _value_string*)0 : ((mqtt_protocol_version_vals
))))
, 0,
1652 "MQTT version", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1653 /* Connect Flags */
1654 { &hf_mqtt_conflags,
1655 { "Connect Flags", "mqtt.conflags",
1656 FT_UINT8, BASE_HEX, NULL((void*)0), 0,
1657 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1658 { &hf_mqtt_conflag_user,
1659 { "User Name Flag", "mqtt.conflag.uname",
1660 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, MQTT_CONMASK_USER0x80,
1661 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1662 { &hf_mqtt_conflag_passwd,
1663 { "Password Flag", "mqtt.conflag.passwd",
1664 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, MQTT_CONMASK_PASSWD0x40,
1665 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1666 { &hf_mqtt_conflag_will_retain,
1667 { "Will Retain", "mqtt.conflag.retain",
1668 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, MQTT_CONMASK_RETAIN0x20,
1669 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1670 { &hf_mqtt_conflag_will_qos,
1671 { "QoS Level", "mqtt.conflag.qos",
1672 FT_UINT8, BASE_DEC, VALS(mqtt_qos_vals)((0 ? (const struct _value_string*)0 : ((mqtt_qos_vals)))), MQTT_CONMASK_QOS0x18,
1673 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1674 { &hf_mqtt_conflag_will_flag,
1675 { "Will Flag", "mqtt.conflag.willflag",
1676 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, MQTT_CONMASK_WILLFLAG0x04,
1677 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1678 { &hf_mqtt_conflag_clean_sess,
1679 { "Clean Session Flag", "mqtt.conflag.cleansess",
1680 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, MQTT_CONMASK_CLEANSESS0x02,
1681 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1682 { &hf_mqtt_conflag_reserved,
1683 { "(Reserved)", "mqtt.conflag.reserved",
1684 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, MQTT_CONMASK_RESERVED0x01,
1685 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1686 { &hf_mqtt_keep_alive,
1687 { "Keep Alive", "mqtt.kalive",
1688 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
1689 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1690 { &hf_mqtt_subscription_options,
1691 { "Subscription Options", "mqtt.subscription_options",
1692 FT_UINT8, BASE_HEX, NULL((void*)0), 0,
1693 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1694 { &hf_mqtt_subscription_qos,
1695 { "QoS", "mqtt.subscription_options_qos",
1696 FT_UINT8, BASE_DEC, VALS(mqtt_qos_vals)((0 ? (const struct _value_string*)0 : ((mqtt_qos_vals)))), MQTT_MASK_SUBS_QOS0x03,
1697 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1698 { &hf_mqtt_subscription_nl,
1699 { "No Local", "mqtt.subscription_options_nl",
1700 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, MQTT_MASK_SUBS_NL0x04,
1701 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1702 { &hf_mqtt_subscription_rap,
1703 { "Retain As Published", "mqtt.subscription_options_rap",
1704 FT_BOOLEAN, 8, TFS(&tfs_set_notset)((0 ? (const struct true_false_string*)0 : ((&tfs_set_notset
))))
, MQTT_MASK_SUBS_RAP0x08,
1705 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1706 { &hf_mqtt_subscription_retain,
1707 { "Retain Handling", "mqtt.subscription_options_retain",
1708 FT_UINT8, BASE_DEC, VALS(mqtt_subscription_retain_handling)((0 ? (const struct _value_string*)0 : ((mqtt_subscription_retain_handling
))))
, MQTT_MASK_SUBS_RETAIN0x30,
1709 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1710 { &hf_mqtt_subscription_reserved,
1711 { "Reserved", "mqtt.subscription_options_reserved",
1712 FT_UINT8, BASE_HEX, NULL((void*)0), MQTT_MASK_SUBS_RESERVED0xC0,
1713 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1714
1715 /* v5.0 Reason Codes */
1716 { &hf_mqtt_reason_code_connack,
1717 { "Reason Code", "mqtt.connack.reason_code",
1718 FT_UINT8, BASE_DEC, VALS(mqtt_reason_code_connack_vals)((0 ? (const struct _value_string*)0 : ((mqtt_reason_code_connack_vals
))))
, 0,
1719 "MQTT Reason Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1720 { &hf_mqtt_reason_code_puback,
1721 { "Reason Code", "mqtt.puback.reason_code",
1722 FT_UINT8, BASE_DEC, VALS(mqtt_reason_code_puback_vals)((0 ? (const struct _value_string*)0 : ((mqtt_reason_code_puback_vals
))))
, 0,
1723 "MQTT Reason Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1724 { &hf_mqtt_reason_code_pubrec,
1725 { "Reason Code", "mqtt.pubrec.reason_code",
1726 FT_UINT8, BASE_DEC, VALS(mqtt_reason_code_puback_vals)((0 ? (const struct _value_string*)0 : ((mqtt_reason_code_puback_vals
))))
, 0,
1727 "MQTT Reason Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1728 { &hf_mqtt_reason_code_pubrel,
1729 { "Reason Code", "mqtt.pubrel.reason_code",
1730 FT_UINT8, BASE_DEC, VALS(mqtt_reason_code_pubrel_vals)((0 ? (const struct _value_string*)0 : ((mqtt_reason_code_pubrel_vals
))))
, 0,
1731 "MQTT Reason Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1732 { &hf_mqtt_reason_code_pubcomp,
1733 { "Reason Code", "mqtt.pubcomp.reason_code",
1734 FT_UINT8, BASE_DEC, VALS(mqtt_reason_code_pubrel_vals)((0 ? (const struct _value_string*)0 : ((mqtt_reason_code_pubrel_vals
))))
, 0,
1735 "MQTT Reason Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1736 { &hf_mqtt_reason_code_suback,
1737 { "Reason Code", "mqtt.suback.reason_code",
1738 FT_UINT8, BASE_DEC, VALS(mqtt_reason_code_suback_vals)((0 ? (const struct _value_string*)0 : ((mqtt_reason_code_suback_vals
))))
, 0,
1739 "MQTT Reason Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1740 { &hf_mqtt_reason_code_unsuback,
1741 { "Reason Code", "mqtt.unsuback.reason_code",
1742 FT_UINT8, BASE_DEC, VALS(mqtt_reason_code_unsuback_vals)((0 ? (const struct _value_string*)0 : ((mqtt_reason_code_unsuback_vals
))))
, 0,
1743 "MQTT Reason Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1744 { &hf_mqtt_reason_code_disconnect,
1745 { "Reason Code", "mqtt.disconnect.reason_code",
1746 FT_UINT8, BASE_DEC, VALS(mqtt_reason_code_disconnect_vals)((0 ? (const struct _value_string*)0 : ((mqtt_reason_code_disconnect_vals
))))
, 0,
1747 "MQTT Reason Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1748 { &hf_mqtt_reason_code_auth,
1749 { "Reason Code", "mqtt.auth.reason_code",
1750 FT_UINT8, BASE_DEC, VALS(mqtt_reason_code_auth_vals)((0 ? (const struct _value_string*)0 : ((mqtt_reason_code_auth_vals
))))
, 0,
1751 "MQTT Reason Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1752
1753 /* Properties */
1754 { &hf_mqtt_property,
1755 { "Properties", "mqtt.properties",
1756 FT_NONE, BASE_NONE, NULL((void*)0), 0,
1757 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1758 { &hf_mqtt_will_property,
1759 { "Will Properties", "mqtt.will_properties",
1760 FT_NONE, BASE_NONE, NULL((void*)0), 0,
1761 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1762 { &hf_mqtt_property_len,
1763 { "Total Length", "mqtt.property_len",
1764 FT_UINT64, BASE_DEC, NULL((void*)0), 0,
1765 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1766 { &hf_mqtt_property_id,
1767 { "ID", "mqtt.property_id",
1768 FT_UINT8, BASE_HEX, VALS(mqtt_property_vals)((0 ? (const struct _value_string*)0 : ((mqtt_property_vals))
))
, 0,
1769 "Property Id", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1770 { &hf_mqtt_prop_num,
1771 { "Value", "mqtt.prop_number",
1772 FT_UINT32, BASE_DEC, NULL((void*)0), 0,
1773 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1774 { &hf_mqtt_prop_content_type,
1775 { "Content Type", "mqtt.property.content_type",
1776 FT_UINT_STRING, BASE_NONE, NULL((void*)0), 0,
1777 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1778 { &hf_mqtt_prop_max_qos,
1779 { "QoS", "mqtt.property.max_qos",
1780 FT_UINT8, BASE_DEC, VALS(mqtt_qos_vals)((0 ? (const struct _value_string*)0 : ((mqtt_qos_vals)))), 0,
1781 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1782 { &hf_mqtt_prop_topic_alias,
1783 { "Topic Alias", "mqtt.property.topic_alias",
1784 FT_UINT16, BASE_DEC, NULL((void*)0), 0,
1785 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1786 { &hf_mqtt_prop_unknown,
1787 { "Unknown Property", "mqtt.prop_unknown",
1788 FT_STRING, BASE_NONE, NULL((void*)0), 0,
1789 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1790 { &hf_mqtt_prop_string_len,
1791 { "Length", "mqtt.prop_string_len",
1792 FT_UINT32, BASE_DEC, NULL((void*)0), 0,
1793 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1794 { &hf_mqtt_prop_string,
1795 { "Value", "mqtt.prop_string",
1796 FT_STRING, BASE_NONE, NULL((void*)0), 0,
1797 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1798 { &hf_mqtt_prop_key_len,
1799 { "Key Length", "mqtt.prop_key_len",
1800 FT_UINT32, BASE_DEC, NULL((void*)0), 0,
1801 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1802 { &hf_mqtt_prop_key,
1803 { "Key", "mqtt.prop_key",
1804 FT_STRING, BASE_NONE, NULL((void*)0), 0,
1805 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1806 { &hf_mqtt_prop_value_len,
1807 { "Value Length", "mqtt.prop_value_len",
1808 FT_UINT32, BASE_DEC, NULL((void*)0), 0,
1809 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1810 { &hf_mqtt_prop_value,
1811 { "Value", "mqtt.prop_value",
1812 FT_STRING, BASE_NONE, NULL((void*)0), 0,
1813 NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
1814 };
1815
1816 /* Setup protocol subtree arrays */
1817 static int* ett_mqtt[] = {
1818 &ett_mqtt_hdr,
1819 &ett_mqtt_msg,
1820 &ett_mqtt_hdr_flags,
1821 &ett_mqtt_con_flags,
1822 &ett_mqtt_conack_flags,
1823 &ett_mqtt_property,
1824 &ett_mqtt_subscription_flags,
1825 };
1826
1827 static ei_register_info ei[] = {
1828 { &ei_illegal_length,
1829 { "mqtt.illegal_topic_length", PI_PROTOCOL0x09000000, PI_WARN0x00600000, "Length cannot be 0", 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)}}
} },
1830 { &ei_unknown_version,
1831 { "mqtt.unknown_version", PI_PROTOCOL0x09000000, PI_NOTE0x00400000, "Unknown version (missing the CONNECT packet?)", 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)}}
} },
1832 { &ei_unknown_topic_alias,
1833 { "mqtt.unknown_topic_alias", PI_PROTOCOL0x09000000, PI_NOTE0x00400000, "Unknown topic alias", 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)}}
} }
1834 };
1835
1836 static uat_field_t mqtt_message_decode_flds[] = {
1837 UAT_FLD_VS(message_decode, match_criteria, "Match criteria", match_criteria, "Match criteria"){"match_criteria", "Match criteria", PT_TXTMOD_ENUM,{uat_fld_chk_enum
,message_decode_match_criteria_set_cb,message_decode_match_criteria_tostr_cb
},{&(match_criteria),&(match_criteria),&(match_criteria
)},&(match_criteria),"Match criteria",((void*)0)}
,
1838 UAT_FLD_CSTRING(message_decode, topic_pattern, "Topic pattern", "Pattern to match for the topic"){"topic_pattern", "Topic pattern", PT_TXTMOD_STRING,{uat_fld_chk_str
,message_decode_topic_pattern_set_cb,message_decode_topic_pattern_tostr_cb
},{0,0,0},0,"Pattern to match for the topic",((void*)0)}
,
1839 UAT_FLD_VS(message_decode, msg_decoding, "Decoding", msg_decoding, "Decode message before dissecting as protocol"){"msg_decoding", "Decoding", PT_TXTMOD_ENUM,{uat_fld_chk_enum
,message_decode_msg_decoding_set_cb,message_decode_msg_decoding_tostr_cb
},{&(msg_decoding),&(msg_decoding),&(msg_decoding
)},&(msg_decoding),"Decode message before dissecting as protocol"
,((void*)0)}
,
1840 UAT_FLD_DISSECTOR(message_decode, payload_proto, "Payload dissector",{"payload_proto", "Payload dissector", PT_TXTMOD_DISSECTOR,{uat_fld_chk_proto
,message_decode_payload_proto_set_cb,message_decode_payload_proto_tostr_cb
},{0,0,0},0,"Dissector to be used for the message part of the matching topic"
,((void*)0)}
1841 "Dissector to be used for the message part of the matching topic"){"payload_proto", "Payload dissector", PT_TXTMOD_DISSECTOR,{uat_fld_chk_proto
,message_decode_payload_proto_set_cb,message_decode_payload_proto_tostr_cb
},{0,0,0},0,"Dissector to be used for the message part of the matching topic"
,((void*)0)}
,
1842 UAT_END_FIELDS{((void*)0),((void*)0),PT_TXTMOD_NONE,{0,0,0},{0,0,0},0,0,((void
*)0)}
1843 };
1844
1845 uat_t *message_uat = uat_new("Message Decoding",
1846 sizeof(mqtt_message_decode_t),
1847 "mqtt_message_decoding",
1848 true1,
1849 &mqtt_message_decodes,
1850 &num_mqtt_message_decodes,
1851 UAT_AFFECTS_DISSECTION0x00000001, /* affects dissection of packets, but not set of named fields */
1852 NULL((void*)0),
1853 mqtt_message_decode_copy_cb,
1854 mqtt_message_decode_update_cb,
1855 mqtt_message_decode_free_cb,
1856 NULL((void*)0),
1857 NULL((void*)0),
1858 mqtt_message_decode_flds);
1859
1860 module_t *mqtt_module;
1861 expert_module_t* expert_mqtt;
1862
1863 /* Register protocol names and descriptions */
1864 proto_mqtt = proto_register_protocol("MQ Telemetry Transport Protocol", "MQTT", "mqtt");
1865
1866 /* Register the dissector */
1867 mqtt_handle = register_dissector("mqtt", dissect_mqtt_data, proto_mqtt);
1868
1869 proto_register_field_array(proto_mqtt, hf_mqtt, array_length(hf_mqtt)(sizeof (hf_mqtt) / sizeof (hf_mqtt)[0]));
1870 proto_register_subtree_array(ett_mqtt, array_length(ett_mqtt)(sizeof (ett_mqtt) / sizeof (ett_mqtt)[0]));
1871
1872 mqtt_topic_subdissector = register_heur_dissector_list_with_description("mqtt.topic", "MQTT message topic", proto_mqtt);
1873
1874 expert_mqtt = expert_register_protocol(proto_mqtt);
1875 expert_register_field_array(expert_mqtt, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
1876
1877 mqtt_module = prefs_register_protocol(proto_mqtt, NULL((void*)0));
1878
1879 prefs_register_uat_preference(mqtt_module, "message_decode_table",
1880 "Message Decoding",
1881 "A table that enumerates custom message decodes to be used for a certain topic",
1882 message_uat);
1883
1884 prefs_register_enum_preference(mqtt_module, "default_version",
1885 "Default Version",
1886 "Select the MQTT version to use as protocol version if the CONNECT packet is not captured",
1887 &default_protocol_version, mqtt_protocol_version_enumvals, false0);
1888
1889 prefs_register_bool_preference(mqtt_module, "show_msg_as_text",
1890 "Show Message as text",
1891 "Show Publish Message as text",
1892 &show_msg_as_text);
1893
1894}
1895
1896/*
1897 * Dissector Handoff
1898 */
1899void proto_reg_handoff_mqtt(void)
1900{
1901 dissector_add_uint_with_preference("tcp.port", MQTT_DEFAULT_PORT1883, mqtt_handle);
1902 ssl_dissector_add(MQTT_SSL_DEFAULT_PORT8883, mqtt_handle);
1903
1904 media_type_dissector_table = find_dissector_table("media_type");
1905 dissector_add_string("quic.proto", "mqtt", mqtt_handle);
1906}
1907
1908/*
1909 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1910 *
1911 * Local variables:
1912 * c-basic-offset: 2
1913 * tab-width: 8
1914 * indent-tabs-mode: nil
1915 * End:
1916 *
1917 * vi: set shiftwidth=2 tabstop=8 expandtab:
1918 * :indentSize=2:tabSize=8:noTabs=true:
1919 */