Coverage Report

Created: 2026-09-28 07:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata8/rust/src/mqtt/mqtt_message.rs
Line
Count
Source
1
/* Copyright (C) 2020 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17
18
// written by Sascha Steinbiss <sascha@steinbiss.name>
19
20
use crate::mqtt::mqtt_property::*;
21
use crate::mqtt::parser::*;
22
use std::fmt;
23
use suricata_derive::EnumStringU8;
24
25
#[derive(Debug)]
26
pub struct MQTTMessage {
27
    pub header: FixedHeader,
28
    pub op: MQTTOperation,
29
}
30
31
#[derive(Debug)]
32
pub enum MQTTOperation {
33
    UNASSIGNED,
34
    CONNECT(MQTTConnectData),
35
    CONNACK(MQTTConnackData),
36
    PUBLISH(MQTTPublishData),
37
    PUBACK(MQTTMessageIdOnly),
38
    PUBREC(MQTTMessageIdOnly),
39
    PUBREL(MQTTMessageIdOnly),
40
    PUBCOMP(MQTTMessageIdOnly),
41
    SUBSCRIBE(MQTTSubscribeData),
42
    SUBACK(MQTTSubackData),
43
    UNSUBSCRIBE(MQTTUnsubscribeData),
44
    UNSUBACK(MQTTUnsubackData),
45
    AUTH(MQTTAuthData),
46
    PINGREQ,
47
    PINGRESP,
48
    DISCONNECT(MQTTDisconnectData),
49
    // TRUNCATED is special, representing a message that was not parsed
50
    // in its entirety due to size constraints. There is no equivalent in
51
    // the MQTT specification.
52
    TRUNCATED(MQTTTruncatedData),
53
}
54
55
#[repr(u8)]
56
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, FromPrimitive, Debug, EnumStringU8)]
57
pub enum MQTTTypeCode {
58
    UNASSIGNED = 0,
59
    CONNECT = 1,
60
    CONNACK = 2,
61
    PUBLISH = 3,
62
    PUBACK = 4,
63
    PUBREC = 5,
64
    PUBREL = 6,
65
    PUBCOMP = 7,
66
    SUBSCRIBE = 8,
67
    SUBACK = 9,
68
    UNSUBSCRIBE = 10,
69
    UNSUBACK = 11,
70
    PINGREQ = 12,
71
    PINGRESP = 13,
72
    DISCONNECT = 14,
73
    AUTH = 15,
74
}
75
76
impl MQTTTypeCode {
77
0
    pub fn to_lower_str(&self) -> String {
78
0
        self.to_string().to_lowercase()
79
0
    }
80
}
81
82
impl fmt::Display for MQTTTypeCode {
83
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84
0
        write!(f, "{:?}", self)
85
0
    }
86
}
87
88
#[derive(Debug)]
89
pub struct MQTTConnectData {
90
    pub protocol_string: String,
91
    pub protocol_version: u8,
92
    pub rawflags: u8,
93
    pub username_flag: bool,
94
    pub password_flag: bool,
95
    pub will_retain: bool,
96
    pub will_qos: u8,
97
    pub will_flag: bool,
98
    pub clean_session: bool,
99
    pub keepalive: u16,
100
    pub client_id: String,
101
    pub will_topic: Option<String>,
102
    pub will_message: Option<Vec<u8>>,
103
    pub username: Option<String>,
104
    pub password: Option<Vec<u8>>,
105
    pub properties: Option<Vec<MQTTProperty>>, // MQTT 5.0
106
    pub properties_truncated: bool,
107
    pub will_properties: Option<Vec<MQTTProperty>>, // MQTT 5.0
108
}
109
110
#[derive(Debug)]
111
pub struct MQTTConnackData {
112
    pub return_code: u8,
113
    pub session_present: bool,                 // MQTT 3.1.1
114
    pub properties: Option<Vec<MQTTProperty>>, // MQTT 5.0
115
    pub properties_truncated: bool,
116
}
117
118
#[derive(Debug)]
119
pub struct MQTTPublishData {
120
    pub topic: String,
121
    pub message_id: Option<u16>,
122
    pub message: Vec<u8>,
123
    pub properties: Option<Vec<MQTTProperty>>, // MQTT 5.0
124
    pub properties_truncated: bool,
125
}
126
127
#[derive(Debug)]
128
pub struct MQTTMessageIdOnly {
129
    pub message_id: u16,
130
    pub reason_code: Option<u8>,               // MQTT 5.0
131
    pub properties: Option<Vec<MQTTProperty>>, // MQTT 5.0
132
    pub properties_truncated: bool,
133
}
134
135
#[derive(Debug)]
136
pub struct MQTTSubscribeTopicData {
137
    pub topic_name: String,
138
    pub qos: u8,
139
}
140
141
#[derive(Debug)]
142
pub struct MQTTSubscribeData {
143
    pub message_id: u16,
144
    pub topics: Vec<MQTTSubscribeTopicData>,
145
    pub properties: Option<Vec<MQTTProperty>>, // MQTT 5.0
146
    pub properties_truncated: bool,
147
}
148
149
#[derive(Debug)]
150
pub struct MQTTSubackData {
151
    pub message_id: u16,
152
    pub qoss: Vec<u8>,
153
    pub properties: Option<Vec<MQTTProperty>>, // MQTT 5.0
154
    pub properties_truncated: bool,
155
}
156
157
#[derive(Debug)]
158
pub struct MQTTUnsubscribeData {
159
    pub message_id: u16,
160
    pub topics: Vec<String>,
161
    pub properties: Option<Vec<MQTTProperty>>, // MQTT 5.0
162
    pub properties_truncated: bool,
163
}
164
165
#[derive(Debug)]
166
pub struct MQTTUnsubackData {
167
    pub message_id: u16,
168
    pub properties: Option<Vec<MQTTProperty>>, // MQTT 5.0
169
    pub properties_truncated: bool,
170
    pub reason_codes: Option<Vec<u8>>, // MQTT 5.0
171
}
172
173
#[derive(Debug)]
174
pub struct MQTTAuthData {
175
    pub reason_code: u8,                       // MQTT 5.0
176
    pub properties: Option<Vec<MQTTProperty>>, // MQTT 5.0
177
    pub properties_truncated: bool,
178
}
179
180
#[derive(Debug)]
181
pub struct MQTTDisconnectData {
182
    pub reason_code: Option<u8>,               // MQTT 5.0
183
    pub properties: Option<Vec<MQTTProperty>>, // MQTT 5.0
184
    pub properties_truncated: bool,
185
}
186
187
#[derive(Debug)]
188
pub struct MQTTTruncatedData {
189
    pub original_message_type: MQTTTypeCode,
190
    pub skipped_length: usize,
191
}